LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2luY2x1ZGUgImRvY29iai5oIgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImRkZW1sLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJjb21tZGxnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbmUvb2JqX3dlYmJyb3dzZXIuaCIKI2luY2x1ZGUgIndpbmUvb2JqX3NlcnZpY2Vwcm92aWRlci5oIgojaW5jbHVkZSAid2luZS9vYmpfY29udHJvbC5oIgojaW5jbHVkZSAid2luZS9vYmpfY29ubmVjdGlvbi5oIgojaW5jbHVkZSAid2luZS9vYmpfcHJvcGVydHkuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJzaGx3YXBpLmgiCgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwoKLyogR2V0IGEgZnVuY3Rpb24gcG9pbnRlciBmcm9tIGEgRExMIGhhbmRsZSAqLwojZGVmaW5lIEdFVF9GVU5DKGZ1bmMsIG1vZHVsZSwgbmFtZSwgZmFpbCkgXAogIGRvIHsgXAogICAgaWYgKCFmdW5jKSB7IFwKICAgICAgaWYgKCFTSExXQVBJX2gjI21vZHVsZSAmJiAhKFNITFdBUElfaCMjbW9kdWxlID0gTG9hZExpYnJhcnlBKCNtb2R1bGUgIi5kbGwiKSkpIHJldHVybiBmYWlsOyBcCiAgICAgIGZ1bmMgPSAoZm4jI2Z1bmMpR2V0UHJvY0FkZHJlc3MoU0hMV0FQSV9oIyNtb2R1bGUsIG5hbWUpOyBcCiAgICAgIGlmICghZnVuYykgcmV0dXJuIGZhaWw7IFwKICAgIH0gXAogIH0gd2hpbGUgKDApCgovKiBETEwgaGFuZGxlcyBmb3IgbGF0ZSBib3VuZCBjYWxscyAqLwpleHRlcm4gSElOU1RBTkNFIHNobHdhcGlfaEluc3RhbmNlOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2hzaGVsbDMyOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h3aW5tbTsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9oY29tZGxnMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaGNvbWN0bDMyOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2htcHI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaG1sYW5nOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h1cmxtb247CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHZlcnNpb247CgpleHRlcm4gRFdPUkQgU0hMV0FQSV9UaHJlYWRSZWZfaW5kZXg7Cgp0eXBlZGVmIEhBTkRMRSBIU0hBUkVEOyAvKiBTaGFyZWQgbWVtb3J5ICovCgovKiBmb2xsb3dpbmcgaXMgR1VJRCBmb3IgSU9iamVjdFdpdGhTaXRlOjpTZXRTaXRlICAtLSBzZWUgXzE3NCAgICAgICAgICAgKi8Kc3RhdGljIERXT1JEIGlkMVs0XSA9IHsweGZjNDgwMWEzLCAweDExY2YyYmE5LCAweGFhMDAyOWEyLCAweDUyNzMzZDAwfTsKLyogZm9sbG93aW5nIGlzIEdVSUQgZm9yIElQZXJzaXN0TW9uaWtlcjo6R2V0Q2xhc3NJRCAgLS0gc2VlIF8xNzQgICAgICAgICovCnN0YXRpYyBEV09SRCBpZDJbNF0gPSB7MHg3OWVhYzllZSwgMHgxMWNlYmFmOSwgMHhhYTAwODI4YywgMHgwYmE5NGIwMH07CgovKiBGdW5jdGlvbiBwb2ludGVycyBmb3IgR0VUX0ZVTkMgbWFjcm87IHRoZXNlIG5lZWQgdG8gYmUgZ2xvYmFsIGJlY2F1c2Ugb2YgZ2NjIGJ1ZyAqLwp0eXBlZGVmIExQSVRFTUlETElTVCAoV0lOQVBJICpmbnBTSEJyb3dzZUZvckZvbGRlclcpKExQQlJPV1NFSU5GT1cpOwpzdGF0aWMgIGZucFNIQnJvd3NlRm9yRm9sZGVyVyBwU0hCcm93c2VGb3JGb2xkZXJXOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUpKExQRFdPUkQsRFdPUkQsTFBDV1NUUixMUElOVCxMUFNUUixMUElOVCk7CnN0YXRpYyAgZm5wQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUgcENvbnZlcnRJTmV0VW5pY29kZVRvTXVsdGlCeXRlOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUGxheVNvdW5kVykoTFBDV1NUUiwgSE1PRFVMRSwgRFdPUkQpOwpzdGF0aWMgIGZucFBsYXlTb3VuZFcgcFBsYXlTb3VuZFc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBTSEdldEZpbGVJbmZvVykoTFBDV1NUUixEV09SRCxTSEZJTEVJTkZPVyosVUlOVCxVSU5UKTsKc3RhdGljICBmbnBTSEdldEZpbGVJbmZvVyBwU0hHZXRGaWxlSW5mb1c7CnR5cGVkZWYgVUlOVCAgICAoV0lOQVBJICpmbnBEcmFnUXVlcnlGaWxlVykoSERST1AsIFVJTlQsIExQV1NUUiwgVUlOVCk7CnN0YXRpYyAgZm5wRHJhZ1F1ZXJ5RmlsZVcgcERyYWdRdWVyeUZpbGVXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wU0hHZXRQYXRoRnJvbUlETGlzdFcpKExQQ0lURU1JRExJU1QsIExQV1NUUik7CnN0YXRpYyAgZm5wU0hHZXRQYXRoRnJvbUlETGlzdFcgcFNIR2V0UGF0aEZyb21JRExpc3RXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wU2hlbGxFeGVjdXRlRXhXKShMUFNIRUxMRVhFQ1VURUlORk9XKTsKc3RhdGljICBmbnBTaGVsbEV4ZWN1dGVFeFcgcFNoZWxsRXhlY3V0ZUV4VzsKdHlwZWRlZiBISUNPTiAgIChXSU5BUEkgKmZucFNIRmlsZU9wZXJhdGlvblcpKExQU0hGSUxFT1BTVFJVQ1RXKTsKc3RhdGljICBmbnBTSEZpbGVPcGVyYXRpb25XIHBTSEZpbGVPcGVyYXRpb25XOwp0eXBlZGVmIFVJTlQgICAgKFdJTkFQSSAqZm5wRXh0cmFjdEljb25FeFcpKExQQ1dTVFIsIElOVCxISUNPTiAqLEhJQ09OICosIFVJTlQpOwpzdGF0aWMgIGZucEV4dHJhY3RJY29uRXhXIHBFeHRyYWN0SWNvbkV4VzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNIR2V0TmV3TGlua0luZm9XKShMUENXU1RSLCBMUENXU1RSLCBMUENXU1RSLCBCT09MKiwgVUlOVCk7CnN0YXRpYyAgZm5wU0hHZXROZXdMaW5rSW5mb1cgcFNIR2V0TmV3TGlua0luZm9XOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wU0hEZWZFeHRyYWN0SWNvblcpKExQQ1dTVFIsIGludCwgVUlOVCwgSElDT04qLCBISUNPTiosIFVJTlQpOwpzdGF0aWMgIGZucFNIRGVmRXh0cmFjdEljb25XIHBTSERlZkV4dHJhY3RJY29uVzsKdHlwZWRlZiBISUNPTiAgIChXSU5BUEkgKmZucEV4dHJhY3RJY29uVykoSElOU1RBTkNFLCBMUENXU1RSLCBVSU5UKTsKc3RhdGljICBmbnBFeHRyYWN0SWNvblcgcEV4dHJhY3RJY29uVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucEdldFNhdmVGaWxlTmFtZVcpKExQT1BFTkZJTEVOQU1FVyk7CnN0YXRpYyAgZm5wR2V0U2F2ZUZpbGVOYW1lVyBwR2V0U2F2ZUZpbGVOYW1lVzsKdHlwZWRlZiBEV09SRCAgIChXSU5BUEkgKmZucFdOZXRSZXN0b3JlQ29ubmVjdGlvblcpKEhXTkQsIExQV1NUUik7CnN0YXRpYyAgZm5wV05ldFJlc3RvcmVDb25uZWN0aW9uVyBwV05ldFJlc3RvcmVDb25uZWN0aW9uVzsKdHlwZWRlZiBEV09SRCAgIChXSU5BUEkgKmZucFdOZXRHZXRMYXN0RXJyb3JXKShMUERXT1JELCBMUFdTVFIsIERXT1JELCBMUFdTVFIsIERXT1JEKTsKc3RhdGljICBmbnBXTmV0R2V0TGFzdEVycm9yVyBwV05ldEdldExhc3RFcnJvclc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBQYWdlU2V0dXBEbGdXKShMUFBBR0VTRVRVUERMR1cpOwpzdGF0aWMgIGZucFBhZ2VTZXR1cERsZ1cgcFBhZ2VTZXR1cERsZ1c7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBQcmludERsZ1cpKExQUFJJTlRETEdXKTsKc3RhdGljICBmbnBQcmludERsZ1cgcFByaW50RGxnVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucEdldE9wZW5GaWxlTmFtZVcpKExQT1BFTkZJTEVOQU1FVyk7CnN0YXRpYyAgZm5wR2V0T3BlbkZpbGVOYW1lVyBwR2V0T3BlbkZpbGVOYW1lVzsKdHlwZWRlZiBEV09SRCAgIChXSU5BUEkgKmZucEdldEZpbGVWZXJzaW9uSW5mb1NpemVXKShMUENXU1RSLExQRFdPUkQpOwpzdGF0aWMgIGZucEdldEZpbGVWZXJzaW9uSW5mb1NpemVXIHBHZXRGaWxlVmVyc2lvbkluZm9TaXplVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucEdldEZpbGVWZXJzaW9uSW5mb1cpKExQQ1dTVFIsRFdPUkQsRFdPUkQsTFBWT0lEKTsKc3RhdGljICBmbnBHZXRGaWxlVmVyc2lvbkluZm9XIHBHZXRGaWxlVmVyc2lvbkluZm9XOwp0eXBlZGVmIFdPUkQgICAgKFdJTkFQSSAqZm5wVmVyUXVlcnlWYWx1ZVcpKExQVk9JRCxMUENXU1RSLExQVk9JRCosVUlOVCopOwpzdGF0aWMgIGZucFZlclF1ZXJ5VmFsdWVXIHBWZXJRdWVyeVZhbHVlVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucENPTUNUTDMyXzQxNykoSERDLElOVCxJTlQsVUlOVCxjb25zdCBSRUNUKixMUENXU1RSLFVJTlQsY29uc3QgSU5UKik7CnN0YXRpYyAgZm5wQ09NQ1RMMzJfNDE3IHBDT01DVEwzMl80MTc7CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpmbnBEbGxHZXRWZXJzaW9uKShETExWRVJTSU9OSU5GTyopOwpzdGF0aWMgIGZucERsbEdldFZlcnNpb24gcERsbEdldFZlcnNpb247CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpmbnBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yKShVSU5ULEZPUk1BVEVUQyosSUVudW1GT1JNQVRFVEMqKik7CnN0YXRpYyBmbnBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yIHBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yKShMUEJDLElFbnVtRk9STUFURVRDKixEV09SRCk7CnN0YXRpYyBmbnBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IgcFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcjsKCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMTc2KElVbmtub3duKixSRUZHVUlELFJFRklJRCxMUFZPSUQqKTsKSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8zNjMoSFdORCxJU2hlbGxGb2xkZXIqLExQQ0lURU1JRExJU1QsQk9PTCk7CkhSRVNVTFQgV0lOQVBJIFNITFdBUElfNDM2KExQQ1dTVFIsQ0xTSUQqKTsKQk9PTCAgICBXSU5BUEkgU0hMV0FQSV8xNjEoTFBXU1RSLERXT1JEKTsKCi8qCiBOT1RFUzogTW9zdCBmdW5jdGlvbnMgZXhwb3J0ZWQgYnkgb3JkaW5hbCBzZWVtIHRvIGJlIHN1cGVyZmxvdXMuCiBUaGUgcmVhc29uIGZvciB0aGVzZSBmdW5jdGlvbnMgdG8gYmUgdGhlcmUgaXMgdG8gcHJvdmlkZSBhIHdyYXBwZXIKIGZvciB1bmljb2RlIGZ1bmN0aW9ucyB0byBwcm92aWRlIHRoZXNlIGZ1bmN0aW9ucyBvbiBzeXN0ZW1zIHdpdGhvdXQKIHVuaWNvZGUgZnVuY3Rpb25zIGVnLiB3aW45NS93aW45OC4gU2luY2Ugd2UgaGF2ZSBzdWNoIGZ1bmN0aW9ucyB3ZSBqdXN0CiBjYWxsIHRoZXNlLiBJZiBydW5uaW5nIFdpbmUgd2l0aCBuYXRpdmUgRExMJ3MsIHNvbWUgbGF0ZSBib3VuZCBjYWxscyBtYXkKIGZhaWwuIEhvd2V2ZXIsIGl0cyBiZXR0ZXIgdG8gaW1wbGVtZW50IHRoZSBmdW5jdGlvbnMgaW4gdGhlIGZvcndhcmQgRExMCiBhbmQgcmVjb21tZW5kIHRoZSBidWlsdGluIHJhdGhlciB0aGFuIHJlaW1wbGVtZW50aW5nIHRoZSBjYWxscyBoZXJlIQoqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUKICoKICogSW50ZXJuYWwgaW1wbGVtZXRhdGlvbiBvZiBTSExXQVBJXzExLgogKi8Kc3RhdGljCkhTSEFSRUQgV0lOQVBJIFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKEhTSEFSRUQgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3JjUHJvY0lkLCBEV09SRCBkd0FjY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhEc3QsIGhTcmM7CiAgRFdPUkQgZHdNeVByb2NJZCA9IEdldEN1cnJlbnRQcm9jZXNzSWQoKTsKICBIU0hBUkVEIGhSZXQgPSAoSFNIQVJFRClOVUxMOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJTA4bHgsJTA4bHgpXG4iLCAoUFZPSUQpaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwoKICAvKiBHZXQgZGVzdCBwcm9jZXNzIGhhbmRsZSAqLwogIGlmIChkd0RzdFByb2NJZCA9PSBkd015UHJvY0lkKQogICAgaERzdCA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgZWxzZQogICAgaERzdCA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdEc3RQcm9jSWQpOwoKICBpZiAoaERzdCkKICB7CiAgICAvKiBHZXQgc3JjIHByb2Nlc3MgaGFuZGxlICovCiAgICBpZiAoZHdTcmNQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgICAgaFNyYyA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgICBlbHNlCiAgICAgIGhTcmMgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3U3JjUHJvY0lkKTsKCiAgICBpZiAoaFNyYykKICAgIHsKICAgICAgLyogTWFrZSBoYW5kbGUgYXZhaWxhYmxlIHRvIGRlc3QgcHJvY2VzcyAqLwogICAgICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShoRHN0LCAoSEFORExFKWhTaGFyZWQsIGhTcmMsICZoUmV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBkd0FjY2VzcywgMCwgZHdPcHRpb25zIHwgRFVQTElDQVRFX1NBTUVfQUNDRVNTKSkKICAgICAgICBoUmV0ID0gKEhTSEFSRUQpTlVMTDsKCiAgICAgIGlmIChkd1NyY1Byb2NJZCAhPSBkd015UHJvY0lkKQogICAgICAgIENsb3NlSGFuZGxlKGhTcmMpOwogICAgfQoKICAgIGlmIChkd0RzdFByb2NJZCAhPSBkd015UHJvY0lkKQogICAgICBDbG9zZUhhbmRsZShoRHN0KTsKICB9CgogIFRSQUNFKCJSZXR1cm5pbmcgaGFuZGxlICVwXG4iLCAoUFZPSUQpaFJldCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjddCiAqCiAqIENyZWF0ZSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeSBhbmQgaW5pdGlhbGlzZSBpdCB3aXRoIGRhdGEuCiAqCiAqIFBBUkFNUwogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgZGF0YQogKiBscHZEYXRhICBbSV0gUG9pbnRlciB0byBkYXRhIHRvIHdyaXRlCiAqIGR3U2l6ZSAgIFtJXSBTaXplIG9mIGRhdGEKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogT3JkaW5hbHMgNy0xMSBwcm92aWRlIGEgc2V0IG9mIGNhbGxzIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IGJldHdlZW4gYQogKiBncm91cCBvZiBwcm9jZXNzZXMuIFRoZSBzaGFyZWQgbWVtb3J5IGlzIHRyZWF0ZWQgb3BhcXVlbHkgaW4gdGhhdCBpdHMgc2l6ZQogKiBpcyBub3QgZXhwb3NlZCB0byBjbGllbnRzIHdobyBtYXAgaXQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHN0b3JpbmcKICogdGhlIHNpemUgb2YgdGhlIG1hcCBhcyB0aGUgZmlyc3QgRFdPUkQgb2YgbWFwcGVkIGRhdGEsIGFuZCB0aGVuIG9mZnNldHRpbmcKICogdGhlIHZpZXcgcG9pbnRlciByZXR1cm5lZCBieSB0aGlzIHNpemUuCiAqCiAqIFNITFdBUElfNygpL1NITFdBUElfMTAoKSAtIENyZWF0ZS9EZXN0cm95IHRoZSBzaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBTSExXQVBJXzgoKS9TSExXQVBJXzkoKSAgLSBHZXQvUmVsZWFzZSBhIHBvaW50ZXIgdG8gdGhlIHNoYXJlZCBkYXRhCiAqIFNITFdBUElfMTEoKSAgICAgICAgICAgLSBIZWxwZXIgZnVuY3Rpb247IER1cGxpY2F0ZSBjcm9zcy1wcm9jZXNzIGhhbmRsZXMKICAgKi8KSFNIQVJFRCBXSU5BUEkgU0hMV0FQSV83IChEV09SRCBkd1Byb2NJZCwgRFdPUkQgZHdTaXplLCBMUENWT0lEIGxwdkRhdGEpCnsKICBIQU5ETEUgaE1hcDsKICBMUFZPSUQgcE1hcHBlZDsKICBIU0hBUkVEIGhSZXQgPSAoSFNIQVJFRClOVUxMOwoKICBUUkFDRSgiKCVsZCwlcCwlbGQpXG4iLCBkd1Byb2NJZCwgbHB2RGF0YSwgZHdTaXplKTsKCiAgLyogQ3JlYXRlIGZpbGUgbWFwcGluZyBvZiB0aGUgY29ycmVjdCBsZW5ndGggKi8KICBoTWFwID0gQ3JlYXRlRmlsZU1hcHBpbmdBKElOVkFMSURfSEFORExFX1ZBTFVFLCBOVUxMLCBGSUxFX01BUF9SRUFELCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdTaXplICsgc2l6ZW9mKGR3U2l6ZSksIE5VTEwpOwogIGlmICghaE1hcCkKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgYSB2aWV3IGluIG91ciBwcm9jZXNzIGFkZHJlc3Mgc3BhY2UgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoTWFwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwoKICBpZiAocE1hcHBlZCkKICB7CiAgICAvKiBXcml0ZSBzaXplIG9mIGRhdGEsIGZvbGxvd2VkIGJ5IHRoZSBkYXRhLCB0byB0aGUgdmlldyAqLwogICAgKigoRFdPUkQqKXBNYXBwZWQpID0gZHdTaXplOwogICAgaWYgKGR3U2l6ZSkKICAgICAgbWVtY3B5KChjaGFyICopIHBNYXBwZWQgKyBzaXplb2YoZHdTaXplKSwgbHB2RGF0YSwgZHdTaXplKTsKCiAgICAvKiBSZWxlYXNlIHZpZXcuIEFsbCBmdXJ0aGVyIHZpZXdzIG1hcHBlZCB3aWxsIGJlIG9wYXF1ZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKHBNYXBwZWQpOwogICAgaFJldCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKChIU0hBUkVEKWhNYXAsIGR3UHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwgRklMRV9NQVBfQUxMX0FDQ0VTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpOwogIH0KCiAgQ2xvc2VIYW5kbGUoaE1hcCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOF0KICoKICogR2V0IGEgcG9pbnRlciB0byBhIGJsb2NrIG9mIHNoYXJlZCBtZW1vcnkgZnJvbSBhIHNoYXJlZCBtZW1vcnkgaGFuZGxlLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBwb2ludGVyIHRvIHRoZSBzaGFyZWQgbWVtb3J5CiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogU2VlIFNITFdBUElfNy4KICAgKi8KUFZPSUQgV0lOQVBJIFNITFdBUElfOCAoSFNIQVJFRCBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKICB7CiAgSFNIQVJFRCBoRHVwOwogIExQVk9JRCBwTWFwcGVkOwoKICBUUkFDRSgiKCVwICVsZClcbiIsIChQVk9JRCloU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBoYW5kbGUgdG8gc2hhcmVkIG1lbW9yeSBmb3IgY3VycmVudCBwcm9jZXNzICovCiAgaER1cCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsIDApOwogIC8qIEdldCBWaWV3ICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoKEhBTkRMRSloRHVwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwogIENsb3NlSGFuZGxlKGhEdXApOwoKICBpZiAocE1hcHBlZCkKICAgIHJldHVybiAoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKERXT1JEKTsgLyogSGlkZSBzaXplICovCiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOV0KICoKICogUmVsZWFzZSBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5LgogKgogKiBQQVJBTVMKICogbHBWaWV3IFtJXSBTaGFyZWQgbWVtb3J5IHBvaW50ZXIKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqIE5PVEVTCiAqIFNlZSBTSExXQVBJXzcuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzkgKExQVk9JRCBscFZpZXcpCnsKICBUUkFDRSgiKCVwKVxuIiwgbHBWaWV3KTsKICByZXR1cm4gVW5tYXBWaWV3T2ZGaWxlKChjaGFyICopIGxwVmlldyAtIHNpemVvZihEV09SRCkpOyAvKiBJbmNsdWRlIHNpemUgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS4xMF0KICoKICogRGVzdHJveSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeS4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IFRSVUUKICogRmFpbHVyZTogRkFMU0UKICoKICogTk9URVMKICogU2VlIFNITFdBUElfNy4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMTAgKEhTSEFSRUQgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICBIU0hBUkVEIGhDbG9zZTsKCiAgVFJBQ0UoIiglcCAlbGQpXG4iLCAoUFZPSUQpaFNoYXJlZCwgZHdQcm9jSWQpOwoKICAvKiBHZXQgYSBjb3B5IG9mIHRoZSBoYW5kbGUgZm9yIG91ciBwcm9jZXNzLCBjbG9zaW5nIHRoZSBzb3VyY2UgaGFuZGxlICovCiAgaENsb3NlID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX01BUF9BTExfQUNDRVNTLERVUExJQ0FURV9DTE9TRV9TT1VSQ0UpOwogIC8qIENsb3NlIGxvY2FsIGNvcHkgKi8KICByZXR1cm4gQ2xvc2VIYW5kbGUoKEhBTkRMRSloQ2xvc2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgW1NITFdBUEkuMTFdCiAqCiAqIENvcHkgYSBzaGFyYWJsZSBtZW1vcnkgaGFuZGxlIGZyb20gb25lIHByb2Nlc3MgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgICAgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZSB0byBkdXBsaWNhdGUKICogZHdEc3RQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIHdhbnRpbmcgdGhlIGR1cGxpY2F0ZWQgaGFuZGxlCiAqIGR3U3JjUHJvY0lkIFtJXSBJRCBvZiB0aGUgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKiBkd0FjY2VzcyAgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBhY2Nlc3MKICogZHdPcHRpb25zICAgW0ldIERlc2lyZWQgRHVwbGljYXRlSGFuZGxlKCkgb3B0aW9ucwogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgaGFuZGxlIHN1aXRhYmxlIGZvciB1c2UgYnkgdGhlIGR3RHN0UHJvY0lkIHByb2Nlc3MuCiAqIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqCiAqIE5PVEVTCiAqIFNlZSBTSExXQVBJXzcuCiAqLwpIU0hBUkVEIFdJTkFQSSBTSExXQVBJXzExKEhTSEFSRUQgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsIERXT1JEIGR3U3JjUHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3QWNjZXNzLCBEV09SRCBkd09wdGlvbnMpCnsKICBIU0hBUkVEIGhSZXQ7CgogIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd0RzdFByb2NJZCwgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTNdCiAqCiAqIENyZWF0ZSBhbmQgcmVnaXN0ZXIgYSBjbGlwYm9hcmQgZW51bWVyYXRvciBmb3IgYSB3ZWIgYnJvd3Nlci4KICoKICogUEFSQU1TCiAqICBscEJDICAgICAgW0ldIEJpbmRpbmcgY29udGV4dAogKiAgbHBVbmtub3duIFtJXSBBbiBvYmplY3QgZXhwb3NpbmcgdGhlIElXZWJCcm93c2VyQXBwIGludGVyZmFjZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgVGhlIGVudW1lcmF0b3IgaXMgc3RvcmVkIGFzIGEgcHJvcGVydHkgb2YgdGhlIHdlYiBicm93c2VyLiBJZiBpdCBkb2VzIG5vdAogKiAgeWV0IGV4aXN0LCBpdCBpcyBjcmVhdGVkIGFuZCBzZXQgYmVmb3JlIGJlaW5nIHJlZ2lzdGVyZWQuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzEzKExQQkMgbHBCQywgSVVua25vd24gKmxwVW5rbm93bikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb3BlcnR5W10gPSB7ICd7JywnRCcsJzAnLCdGJywnQycsJ0EnLCc0JywnMicsJzAnLAogICAgICAnLScsJ0QnLCczJywnRicsJzUnLCctJywnMScsJzEnLCdDJywnRicsICctJywnQicsJzInLCcxJywnMScsJy0nLCcwJywKICAgICAgJzAnLCdBJywnQScsJzAnLCcwJywnNCcsJ0EnLCdFJywnOCcsJzMnLCc3JywnfScsJ1wwJyB9OwogIElFbnVtRk9STUFURVRDKiBwSUVudW1Gb3JtYXRFdGMgPSBOVUxMOwogIFZBUklBTlRBUkcgdmFyOwogIEhSRVNVTFQgaFJldDsKICBJV2ViQnJvd3NlckFwcCogcEJyb3dzZXIgPSBOVUxMOwoKICAvKiBHZXQgQW4gSVdlYkJyb3dzZXJBcHAgaW50ZXJmYWNlIGZyb20gIGxwVW5rbm93biAqLwogIGhSZXQgPSBTSExXQVBJXzE3NihscFVua25vd24sICZJSURfSVdlYkJyb3dzZXJBcHAsICZJSURfSVdlYkJyb3dzZXJBcHAsIChQVk9JRCkmcEJyb3dzZXIpOwogIGlmIChGQUlMRUQoaFJldCkgfHwgIXBCcm93c2VyKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CgogIFZfVlQoJnZhcikgPSBWVF9FTVBUWTsKCiAgLyogVGhlIHByb3BlcnR5IHdlIGdldCBpcyB0aGUgYnJvd3NlcnMgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfR2V0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksICZ2YXIpOwogIGlmIChGQUlMRUQoaFJldCkpCiAgICByZXR1cm4gaFJldDsKCiAgaWYgKFZfVlQoJnZhcikgPT0gVlRfRU1QVFkpCiAgewogICAgLyogSXRlcmF0ZSB0aHJvdWdoIGFjY2VwdGVkIGRvY3VtZW50cyBhbmQgUmVnaXN0ZXJDbGlwQm9hcmRGb3JtYXRBKCkgdGhlbSAqLwogICAgY2hhciBzektleUJ1ZmZbMTI4XSwgc3pWYWx1ZUJ1ZmZbMTI4XTsKICAgIERXT1JEIGR3S2V5U2l6ZSwgZHdWYWx1ZVNpemUsIGR3UmV0ID0gMCwgZHdDb3VudCA9IDAsIGR3TnVtVmFsdWVzLCBkd1R5cGU7CiAgICBGT1JNQVRFVEMqIGZvcm1hdExpc3QsICpmb3JtYXQ7CiAgICBIS0VZIGhEb2NzOwoKICAgIFRSQUNFKCJSZWdpc3RlcmluZyBmb3JtYXRzIGFuZCBjcmVhdGluZyBJRW51bUZPUk1BVEVUQyBpbnN0YW5jZVxuIik7CgogICAgaWYgKCFSZWdPcGVuS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50IgogICAgICAgICAgICAgICAgICAgICAiVmVyc2lvblxcSW50ZXJuZXQgU2V0dGluZ3NcXEFjY2VwdGVkIERvY3VtZW50cyIsICZoRG9jcykpCiAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgLyogR2V0IGNvdW50IG9mIHZhbHVlcyBpbiBrZXkgKi8KICAgIHdoaWxlICghZHdSZXQpCiAgICB7CiAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsZHdDb3VudCxzektleUJ1ZmYsJmR3S2V5U2l6ZSwwLCZkd1R5cGUsMCwwKTsKICAgICAgZHdDb3VudCsrOwogICAgfQoKICAgIGR3TnVtVmFsdWVzID0gZHdDb3VudDsKCiAgICAvKiBOb3RlOiBkd0NvdW50ID0gbnVtYmVyIG9mIGl0ZW1zICsgMTsgVGhlIGV4dHJhIGl0ZW0gaXMgdGhlIGVuZCBub2RlICovCiAgICBmb3JtYXQgPSBmb3JtYXRMaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGR3Q291bnQgKiBzaXplb2YoRk9STUFURVRDKSk7CiAgICBpZiAoIWZvcm1hdExpc3QpCiAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGlmIChkd051bVZhbHVlcyA+IDEpCiAgICB7CiAgICAgIGR3UmV0ID0gMDsKICAgICAgZHdDb3VudCA9IDA7CgogICAgICBkd051bVZhbHVlcy0tOwoKICAgICAgLyogUmVnaXN0ZXIgY2xpcGJvYXJkIGZvcm1hdHMgZm9yIHRoZSB2YWx1ZXMgYW5kIHBvcHVsYXRlIGZvcm1hdCBsaXN0ICovCiAgICAgIHdoaWxlKCFkd1JldCAmJiBkd0NvdW50IDwgZHdOdW1WYWx1ZXMpCiAgICAgIHsKICAgICAgICBkd0tleVNpemUgPSBzaXplb2Yoc3pLZXlCdWZmKTsKICAgICAgICBkd1ZhbHVlU2l6ZSA9IHNpemVvZihzelZhbHVlQnVmZik7CiAgICAgICAgZHdSZXQgPSBSZWdFbnVtVmFsdWVBKGhEb2NzLCBkd0NvdW50LCBzektleUJ1ZmYsICZkd0tleVNpemUsIDAsICZkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQQllURSlzelZhbHVlQnVmZiwgJmR3VmFsdWVTaXplKTsKICAgICAgICBpZiAoIWR3UmV0KQogICAgICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAgICAgZm9ybWF0LT5jZkZvcm1hdCA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0QShzelZhbHVlQnVmZik7CiAgICAgICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgICAgIGZvcm1hdC0+ZHdBc3BlY3QgPSAxOwogICAgICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgICAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgICAgIGZvcm1hdCsrOwogICAgICAgIGR3Q291bnQrKzsKICAgICAgfQogICAgfQoKICAgIC8qIFRlcm1pbmF0ZSB0aGUgKG1heWJlIGVtcHR5KSBsaXN0LCBsYXN0IGVudHJ5IGhhcyBhIGNmRm9ybWF0IG9mIDAgKi8KICAgIGZvcm1hdC0+Y2ZGb3JtYXQgPSAwOwogICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICBmb3JtYXQtPmxpbmRleCA9IDQ7CiAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgLyogQ3JlYXRlIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICAgIEdFVF9GVU5DKHBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yLCB1cmxtb24sICJDcmVhdGVGb3JtYXRFbnVtZXJhdG9yIiwgRV9GQUlMKTsKICAgIGhSZXQgPSBwQ3JlYXRlRm9ybWF0RW51bWVyYXRvcihkd051bVZhbHVlcywgZm9ybWF0TGlzdCwgJnBJRW51bUZvcm1hdEV0Yyk7CgogICAgaWYgKEZBSUxFRChoUmV0KSB8fCAhcElFbnVtRm9ybWF0RXRjKQogICAgICByZXR1cm4gaFJldDsKCiAgICAvKiBTZXQgb3VyIGVudW1lcmF0b3IgYXMgdGhlIGJyb3dzZXJzIHByb3BlcnR5ICovCiAgICBWX1ZUKCZ2YXIpID0gVlRfVU5LTk9XTjsKICAgIFZfVU5LTk9XTigmdmFyKSA9IChJVW5rbm93biopcElFbnVtRm9ybWF0RXRjOwoKICAgIGhSZXQgPSBJV2ViQnJvd3NlckFwcF9QdXRQcm9wZXJ0eShwQnJvd3NlciwgKEJTVFIpc3pQcm9wZXJ0eSwgdmFyKTsKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICB7CiAgICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBJRW51bUZvcm1hdEV0Yyk7CiAgICAgICBnb3RvIFNITFdBUElfMTNfRXhpdDsKICAgIH0KICB9CgogIGlmIChWX1ZUKCZ2YXIpID09IFZUX1VOS05PV04pCiAgewogICAgLyogT3VyIHZhcmlhbnQgaXMgaG9sZGluZyB0aGUgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICAgIElVbmtub3duKiBwSVVua25vd24gPSBWX1VOS05PV04oJnZhcik7CiAgICBJRW51bUZPUk1BVEVUQyogcENsb25lID0gTlVMTDsKCiAgICBUUkFDRSgiUmV0cmlldmVkIElFbnVtRk9STUFURVRDIHByb3BlcnR5XG4iKTsKCiAgICAvKiBHZXQgYW4gSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlIGZyb20gdGhlIHZhcmlhbnRzIHZhbHVlICovCiAgICBwSUVudW1Gb3JtYXRFdGMgPSBOVUxMOwogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBJVW5rbm93biwgJklJRF9JRW51bUZPUk1BVEVUQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUFZPSUQpJnBJRW51bUZvcm1hdEV0Yyk7CiAgICBpZiAoIWhSZXQgJiYgcElFbnVtRm9ybWF0RXRjKQogICAgewogICAgICAvKiBDbG9uZSBhbmQgcmVnaXN0ZXIgdGhlIGVudW1lcmF0b3IgKi8KICAgICAgaFJldCA9IElFbnVtRk9STUFURVRDX0Nsb25lKHBJRW51bUZvcm1hdEV0YywgJnBDbG9uZSk7CiAgICAgIGlmICghaFJldCAmJiBwQ2xvbmUpCiAgICAgIHsKICAgICAgICBHRVRfRlVOQyhwUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yLCB1cmxtb24sICJSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IiLCBFX0ZBSUwpOwogICAgICAgIHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IobHBCQywgcENsb25lLCAwKTsKCiAgICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwQ2xvbmUpOwogICAgICB9CgogICAgICAvKiBSZWxlYXNlIHRoZSBJRW51bUZvcm1hdEV0YyBpbnRlcmZhY2UgKi8KICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSVVua25vd24pOwogICAgfQogICAgSVVua25vd25fUmVsZWFzZShWX1VOS05PV04oJnZhcikpOwogIH0KClNITFdBUElfMTNfRXhpdDoKICBJV2ViQnJvd3NlckFwcF9SZWxlYXNlKHBCcm93c2VyKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE0XQogKgogKiBHZXQgRXhwbG9yZXJzICJBY2NlcHRMYW5ndWFnZSIgc2V0dGluZy4KICoKICogUEFSQU1TCiAqICBsYW5nYnVmIFtPXSBEZXN0aW5hdGlvbiBmb3IgbGFuZ3VhZ2Ugc3RyaW5nCiAqICBidWZsZW4gIFtJXSBMZW5ndGggb2YgbGFuZ2J1ZgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiAgIGxhbmdidWYgaXMgc2V0IHRvIHRoZSBsYW5ndWFnZSBzdHJpbmcgZm91bmQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQsIGVycm9yIG9jY3VycmVkLCBvciBFeHBsb3JlcgogKiAgICAgICAgICAgZG9lcyBub3QgY29udGFpbiB0aGUgc2V0dGluZy4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMTQgKAoJTFBTVFIgbGFuZ2J1ZiwKCUxQRFdPUkQgYnVmbGVuKQp7CglDSEFSICpteXN0cjsKCURXT1JEIG15c3RybGVuLCBteXR5cGU7CglIS0VZIG15a2V5OwoJTENJRCBteWxjaWQ7CgoJbXlzdHJsZW4gPSAoKmJ1ZmxlbiA+IDYpID8gKmJ1ZmxlbiA6IDY7CglteXN0ciA9IChDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJCSBIRUFQX1pFUk9fTUVNT1JZLCBteXN0cmxlbik7CglSZWdPcGVuS2V5QShIS0VZX0NVUlJFTlRfVVNFUiwKCQkgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXEludGVybmV0IEV4cGxvcmVyXFxJbnRlcm5hdGlvbmFsIiwKCQkgICAgJm15a2V5KTsKCWlmIChSZWdRdWVyeVZhbHVlRXhBKG15a2V5LCAiQWNjZXB0TGFuZ3VhZ2UiLAoJCQkgICAgICAwLCAmbXl0eXBlLCAoUEJZVEUpbXlzdHIsICZteXN0cmxlbikpIHsKCSAgICAvKiBEaWQgbm90IGZpbmQgdmFsdWUgKi8KCSAgICBteWxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKCSAgICAvKiBzb21laG93IHRoZSBteWxjaWQgdHJhbnNsYXRlcyBpbnRvICJlbi11cyIKCSAgICAgKiAgdGhpcyBpcyBzaW1pbGFyIHRvICJMT0NBTEVfU0FCQlJFVkxBTkdOQU1FIgoJICAgICAqICB3aGljaCBjb3VsZCBiZSBnb3R0ZW4gdmlhIEdldExvY2FsZUluZm8uCgkgICAgICogIFRoZSBvbmx5IHByb2JsZW0gaXMgTE9DQUxFX1NBQkJSRVZMQU5HVUFHRSIgaXMKCSAgICAgKiAgYSAzIGNoYXIgc3RyaW5nIChmaXJzdCAyIGFyZSBjb3VudHJ5IGNvZGUgYW5kIHRoaXJkIGlzCgkgICAgICogIGxldHRlciBmb3IgInN1Ymxhbmd1YWdlIiwgd2hpY2ggZG9lcyBub3QgY29tZSBjbG9zZSB0bwoJICAgICAqICAiZW4tdXMiCgkgICAgICovCgkgICAgbHN0cmNweUEobXlzdHIsICJlbi11cyIpOwoJICAgIG15c3RybGVuID0gbHN0cmxlbkEobXlzdHIpOwoJfQoJZWxzZSB7CgkgICAgLyogaGFuZGxlIHJldHVybmVkIHN0cmluZyAqLwoJICAgIEZJWE1FKCJtaXNzaW5nIGNvZGVcbiIpOwoJfQoJaWYgKG15c3RybGVuID4gKmJ1ZmxlbikKCSAgICBsc3RyY3B5bkEobGFuZ2J1ZiwgbXlzdHIsICpidWZsZW4pOwoJZWxzZSB7CgkgICAgbHN0cmNweUEobGFuZ2J1ZiwgbXlzdHIpOwoJICAgICpidWZsZW4gPSBsc3RybGVuQShsYW5nYnVmKTsKCX0KCVJlZ0Nsb3NlS2V5KG15a2V5KTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG15c3RyKTsKCVRSQUNFKCJsYW5ndWFnZSBpcyAlc1xuIiwgZGVidWdzdHJfYShsYW5nYnVmKSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hMV0FQSV8xNC4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMTUgKAoJTFBXU1RSIGxhbmdidWYsCglMUERXT1JEIGJ1ZmxlbikKewoJQ0hBUiAqbXlzdHI7CglEV09SRCBteXN0cmxlbiwgbXl0eXBlOwoJSEtFWSBteWtleTsKCUxDSUQgbXlsY2lkOwoKCW15c3RybGVuID0gKCpidWZsZW4gPiA2KSA/ICpidWZsZW4gOiA2OwoJbXlzdHIgPSAoQ0hBUiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCgkJCQkgSEVBUF9aRVJPX01FTU9SWSwgbXlzdHJsZW4pOwoJUmVnT3BlbktleUEoSEtFWV9DVVJSRU5UX1VTRVIsCgkJICAgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxJbnRlcm5ldCBFeHBsb3JlclxcSW50ZXJuYXRpb25hbCIsCgkJICAgICZteWtleSk7CglpZiAoUmVnUXVlcnlWYWx1ZUV4QShteWtleSwgIkFjY2VwdExhbmd1YWdlIiwKCQkJICAgICAgMCwgJm15dHlwZSwgKFBCWVRFKW15c3RyLCAmbXlzdHJsZW4pKSB7CgkgICAgLyogRGlkIG5vdCBmaW5kIHZhbHVlICovCgkgICAgbXlsY2lkID0gR2V0VXNlckRlZmF1bHRMQ0lEKCk7CgkgICAgLyogc29tZWhvdyB0aGUgbXlsY2lkIHRyYW5zbGF0ZXMgaW50byAiZW4tdXMiCgkgICAgICogIHRoaXMgaXMgc2ltaWxhciB0byAiTE9DQUxFX1NBQkJSRVZMQU5HTkFNRSIKCSAgICAgKiAgd2hpY2ggY291bGQgYmUgZ290dGVuIHZpYSBHZXRMb2NhbGVJbmZvLgoJICAgICAqICBUaGUgb25seSBwcm9ibGVtIGlzIExPQ0FMRV9TQUJCUkVWTEFOR1VBR0UiIGlzCgkgICAgICogIGEgMyBjaGFyIHN0cmluZyAoZmlyc3QgMiBhcmUgY291bnRyeSBjb2RlIGFuZCB0aGlyZCBpcwoJICAgICAqICBsZXR0ZXIgZm9yICJzdWJsYW5ndWFnZSIsIHdoaWNoIGRvZXMgbm90IGNvbWUgY2xvc2UgdG8KCSAgICAgKiAgImVuLXVzIgoJICAgICAqLwoJICAgIGxzdHJjcHlBKG15c3RyLCAiZW4tdXMiKTsKCSAgICBteXN0cmxlbiA9IGxzdHJsZW5BKG15c3RyKTsKCX0KCWVsc2UgewoJICAgIC8qIGhhbmRsZSByZXR1cm5lZCBzdHJpbmcgKi8KCSAgICBGSVhNRSgibWlzc2luZyBjb2RlXG4iKTsKCX0KCVJlZ0Nsb3NlS2V5KG15a2V5KTsKCSpidWZsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKDAsIDAsIG15c3RyLCAtMSwgbGFuZ2J1ZiwgKCpidWZsZW4pLTEpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXlzdHIpOwoJVFJBQ0UoImxhbmd1YWdlIGlzICVzXG4iLCBkZWJ1Z3N0cl93KGxhbmdidWYpKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjNdCiAqCiAqIENvbnZlcnQgYSBHVUlEIHRvIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGd1aWQgW0ldIEdVSUQgdG8gY29udmVydAogKiAgc3RyICBbT10gRGVzdGluYXRpb24gZm9yIHN0cmluZwogKiAgY21heCBbSV0gTGVuZ3RoIG9mIG91dHB1dCBidWZmZXIKICoKICogUkVUVVJOUwogKiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGNyZWF0ZWQuCiAqLwpJTlQgV0lOQVBJIFNITFdBUElfMjMoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4bFgtJTA0WC0lMDRYLSUwMlglMDJYLSUwMlglMDJYJTAyWCUwMlglMDJYJTAyWH0iLAogICAgICAgICAgZ3VpZC0+RGF0YTEsIGd1aWQtPkRhdGEyLCBndWlkLT5EYXRhMywKICAgICAgICAgIGd1aWQtPkRhdGE0WzBdLCBndWlkLT5EYXRhNFsxXSwgZ3VpZC0+RGF0YTRbMl0sIGd1aWQtPkRhdGE0WzNdLAogICAgICAgICAgZ3VpZC0+RGF0YTRbNF0sIGd1aWQtPkRhdGE0WzVdLCBndWlkLT5EYXRhNFs2XSwgZ3VpZC0+RGF0YTRbN10pOwoKICBpTGVuID0gc3RybGVuKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbik7CiAgcmV0dXJuIGlMZW47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMjMuCiAqLwpJTlQgV0lOQVBJIFNITFdBUElfMjQoUkVGR1VJRCBndWlkLCBMUFdTVFIgbHBzekRlc3QsIElOVCBjY2hNYXgpCnsKICBjaGFyIHhndWlkWzQwXTsKICBJTlQgaUxlbiA9IFNITFdBUElfMjMoZ3VpZCwgeGd1aWQsIGNjaE1heCk7CiAgCiAgaWYgKGlMZW4pCiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgeGd1aWQsIC0xLCBscHN6RGVzdCwgY2NoTWF4KTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI1XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhbHBoYWJldGljLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGFscGhhYmV0aWMsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzI1KFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0FMUEhBKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjZdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIHVwcGVyLWNhc2UuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgdXBwZXItY2FzZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjYoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfVVBQRVIpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yN10KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgbG93ZXItY2FzZS4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBsb3dlci1jYXNlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8yNyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9MT1dFUikgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhbHBoYWJldGljIG9yIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYWxwaGFiZXRpYyBvciBhIGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8yOChXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiAoQzFfQUxQSEF8QzFfRElHSVQpKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjldCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgc3BhY2UuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBzcGFjZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjkoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfU1BBQ0UpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMF0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBibGFuay4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGJsYW5rLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zMChXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9CTEFOSykgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBwdW5jdHVhdGlvbi4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBwdW5jdHVhdGlvbiwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMzEoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfUFVOQ1QpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMl0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3Rlci4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zMihXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9DTlRSTCkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzMzKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0RJR0lUKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzRdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgaGV4IGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgaGV4IGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zNChXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9YRElHSVQpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNV0KICoKICovCkJPT0wgV0lOQVBJIFNITFdBUElfMzUoTFBXU1RSIGxwc3pTdHIsIERXT1JEIGR3TGVuLCBMUFZPSUQgcDMpCnsKICAgIEZJWE1FKCIoJXMsMHglMDhseCwlcCk6IHN0dWJcbiIsIGRlYnVnc3RyX3cobHBzelN0ciksIGR3TGVuLCBwMyk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM2XQogKgogKiBJbnNlcnQgYSBiaXRtYXAgbWVudSBpdGVtIGF0IHRoZSBib3R0b20gb2YgYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIGluc2VydCBpbnRvCiAqICBmbGFncyBbSV0gRmxhZ3MgZm9yIGluc2VydGlvbgogKiAgaWQgICAgW0ldIE1lbnUgSUQgb2YgdGhlIGl0ZW0KICogIHN0ciAgIFtJXSBNZW51IHRleHQgZm9yIHRoZSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUsICB0aGUgaXRlbSBpcyBpbnNlcnRlZCBpbnRvIHRoZSBtZW51CiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzM2KEhNRU5VIGhNZW51LCBVSU5UIGZsYWdzLCBVSU5UIGlkLCBMUENXU1RSIHN0cikKewogICAgVFJBQ0UoIiglcCwweCUwOHgsMHglMDh4LCVzKVxuIixoTWVudSwgZmxhZ3MsIGlkLCBkZWJ1Z3N0cl93KHN0cikpOwogICAgcmV0dXJuIEluc2VydE1lbnVXKGhNZW51LCAtMSwgZmxhZ3MgfCBNRl9CSVRNQVAsIGlkLCBzdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNzRdCiAqCiAqIEdldCB0aGUgdGV4dCBmcm9tIGEgZ2l2ZW4gZGlhbG9nIGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIEhhbmRsZSBvZiBkaWFsb2cKICogIG5JdGVtICAgIFtJXSBJbmRleCBvZiBpdGVtCiAqICBscHNEZXN0ICBbT10gQnVmZmVyIGZvciByZWNlaXZpbmcgd2luZG93IHRleHQKICogIG5EZXN0TGVuIFtJXSBMZW5ndGggb2YgYnVmZmVyLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSByZXR1cm5lZCB0ZXh0LgogKiAgRmFpbHVyZTogMC4KICovCklOVCBXSU5BUEkgU0hMV0FQSV83NChIV05EIGhXbmQsIElOVCBuSXRlbSwgTFBXU1RSIGxwc0Rlc3QsSU5UIG5EZXN0TGVuKQp7CiAgSFdORCBoSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgbkl0ZW0pOwoKICBpZiAoaEl0ZW0pCiAgICByZXR1cm4gR2V0V2luZG93VGV4dFcoaEl0ZW0sIGxwc0Rlc3QsIG5EZXN0TGVuKTsKICBpZiAobkRlc3RMZW4pCiAgICAqbHBzRGVzdCA9IChXQ0hBUiknXDAnOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICBbU0hMV0FQSS4xMzhdCiAqCiAqIFNldCB0aGUgdGV4dCBvZiBhIGdpdmVuIGRpYWxvZyBpdGVtLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBIYW5kbGUgb2YgZGlhbG9nCiAqICBpSXRlbSAgICBbSV0gSW5kZXggb2YgaXRlbQogKiAgbHBzelRleHQgW09dIFRleHQgdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuICBUaGUgdGV4dCBvZiB0aGUgZGlhbG9nIGlzIHNldCB0byBscHN6VGV4dC4KICogIEZhaWx1cmU6IEZBTFNFLCBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzEzOChIV05EIGhXbmQsIElOVCBpSXRlbSwgTFBDV1NUUiBscHN6VGV4dCkKewogICAgSFdORCBoV25kSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgaUl0ZW0pOwogICAgaWYgKGhXbmRJdGVtKQogICAgICAgIHJldHVybiBTZXRXaW5kb3dUZXh0VyhoV25kSXRlbSwgbHBzelRleHQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUxXQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzIHVwIHRvIGEgZ2l2ZW4gbGVuZ3RoLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICogIGxlbiAgICAgW0ldIE1heGltdW0gbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE1MShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIElOVCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21wKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTJdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE1MS4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE1MihMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTNdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGgsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTUzKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCwgRFdPUkQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNhc2VjbXAobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMTUzLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTU0KExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21waVcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NV0KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE1NShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTZdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE1NS4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE1NihMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcFcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTddCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xNTcoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY2FzZWNtcChscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMTU3LgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTU4IChMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcGlXKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNITFdBUElfMTYwCVtTSExXQVBJLjE2MF0KICoKICogR2V0IGFuIGlkZW50aWZpY2F0aW9uIHN0cmluZyBmb3IgdGhlIE9TIGFuZCBleHBsb3Jlci4KICoKICogUEFSQU1TCiAqICBscHN6RGVzdCAgW09dIERlc3RpbmF0aW9uIGZvciBJZCBzdHJpbmcKICogIGR3RGVzdExlbiBbSV0gTGVuZ3RoIG9mIGxwc3pEZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsICBJZiB0aGUgc3RyaW5nIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgRkFMU0UsIE90aGVyd2lzZQogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8xNjAoTFBTVFIgbHBzekRlc3QsIERXT1JEIGR3RGVzdExlbikKewogIFdDSEFSIGJ1ZmZbMjA4NF07CgogIFRSQUNFKCIoJXAsJWxkKSIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAobHBzekRlc3QgJiYgU0hMV0FQSV8xNjEoYnVmZiwgZHdEZXN0TGVuKSkKICB7CiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYnVmZiwgLTEsIGxwc3pEZXN0LCBkd0Rlc3RMZW4sIE5VTEwsIE5VTEwpOwogICAgcmV0dXJuIFRSVUU7CiAgfQogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSExXQVBJXzE2MQlbU0hMV0FQSS4xNjFdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE2MC4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMTYxKExQV1NUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SUVLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLAogICAgJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbk50S2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCcgJywKICAgICdOJywnVCcsJ1xcJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pXaW5LZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelJlZ0tleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAogICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelZlcnNpb25bXSA9IHsgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDdXN0b21pemVkW10gPSB7ICdDJywndScsJ3MnLCd0JywnbycsJ20nLCdpJywneicsJ2UnLCdkJywKICAgICdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3duZXJbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCd3JywnbicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3JnW10gPSB7ICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdlJywncicsJ2UnLCdkJywKICAgICdPJywncicsJ2cnLCdhJywnbicsJ2knLCd6JywnYScsJ3QnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9kdWN0W10gPSB7ICdQJywncicsJ28nLCdkJywndScsJ2MnLCd0JywnSScsJ2QnLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pVcGRhdGVbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ1UnLCdwJywnZCcsJ2EnLCd0JywnZScsJ1UnLCdyJywnbCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekhlbHBbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ0gnLCdlJywnbCcsJ3AnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdcMCcgfTsKICBXQ0hBUiBidWZmWzIwODRdOwogIEhLRVkgaFJlZzsKICBEV09SRCBkd1R5cGUsIGR3TGVuOwoKICBUUkFDRSgiKCVwLCVsZCkiLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKCFscHN6RGVzdCkKICAgIHJldHVybiBGQUxTRTsKCiAgKmxwc3pEZXN0ID0gJ1wwJzsKCiAgLyogVHJ5IHRoZSBOVCBrZXkgZmlyc3QsIGZvbGxvd2VkIGJ5IDk1Lzk4IGtleSAqLwogIGlmIChSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5OdEtleSwgMCwgS0VZX1JFQUQsICZoUmVnKSAmJgogICAgICBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5LZXksIDAsIEtFWV9SRUFELCAmaFJlZykpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIE9TIFZlcnNpb24gKi8KICBidWZmWzBdID0gJ1wwJzsKICBkd0xlbiA9IDMwOwogIGlmICghU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LCBzelZlcnNpb24sICZkd1R5cGUsIGJ1ZmYsICZkd0xlbikpCiAgewogICAgRFdPUkQgZHdTdHJMZW4gPSBzdHJsZW5XKGJ1ZmYpOwogICAgZHdMZW4gPSAzMCAtIGR3U3RyTGVuOwogICAgU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LAogICAgICAgICAgICAgICAgc3pDdXN0b21pemVkLCAmZHdUeXBlLCBidWZmK2R3U3RyTGVuLCAmZHdMZW4pOwogIH0KICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3duZXIgKi8KICBidWZmWzBdID0gJ34nOwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek93bmVyLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3JnYW5pemF0aW9uICovCiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKGhSZWcsIHN6T3JnLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogRklYTUU6IE5vdCBzdXJlIHdoZXJlIHRoaXMgbnVtYmVyIGNvbWVzIGZyb20gICovCiAgYnVmZlswXSA9ICd+JzsKICBidWZmWzFdID0gJzAnOwogIGJ1ZmZbMl0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UHJvZHVjdCBJZCAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6UmVnS2V5LCBzelByb2R1Y3QsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgVXBkYXRlIFVybCAqLwogIGR3TGVuID0gMjA0ODsKICBpZihTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCBzelVwZGF0ZSwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5JRSBIZWxwIFN0cmluZyAqLwogIGR3TGVuID0gMjU2OwogIGlmKFNIR2V0VmFsdWVXKGhSZWcsIHN6SGVscCwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIFJlZ0Nsb3NlS2V5KGhSZWcpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYyXQogKgogKiBSZW1vdmUgYSBoYW5naW5nIGxlYWQgYnl0ZSBmcm9tIHRoZSBlbmQgb2YgYSBzdHJpbmcsIGlmIHByZXNlbnQuCiAqCiAqIFBBUkFNUwogKiAgbHBTdHIgW0ldIFN0cmluZyB0byBjaGVjayBmb3IgYSBoYW5naW5nIGxlYWQgYnl0ZQogKiAgc2l6ZSAgW0ldIExlbmd0aCBvZiBscFN0cgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbmV3IGxlbmd0aCBvZiB0aGUgc3RyaW5nLiBBbnkgaGFuZ2luZyBsZWFkIGJ5dGVzIGFyZSByZW1vdmVkLgogKiAgRmFpbHVyZTogMCwgaWYgYW55IHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xNjIoTFBTVFIgbHBTdHIsIERXT1JEIHNpemUpCnsKICBpZiAobHBTdHIgJiYgc2l6ZSkKICB7CiAgICBMUFNUUiBsYXN0Qnl0ZSA9IGxwU3RyICsgc2l6ZSAtIDE7CgogICAgd2hpbGUobHBTdHIgPCBsYXN0Qnl0ZSkKICAgICAgbHBTdHIgKz0gSXNEQkNTTGVhZEJ5dGUoKmxwU3RyKSA/IDIgOiAxOwoKICAgIGlmKGxwU3RyID09IGxhc3RCeXRlICYmIElzREJDU0xlYWRCeXRlKCpscFN0cikpCiAgICB7CiAgICAgICpscFN0ciA9ICdcMCc7CiAgICAgIHNpemUtLTsKICAgIH0KICAgIHJldHVybiBzaXplOwogIH0KICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2M10KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKiAgY0NtZHMgICAgICAgICBbSV0KICogIHByZ0NtZHMgICAgICAgW09dIENvbW1hbmRzCiAqICBwQ21kVGV4dCAgICAgIFtPXSBDb21tYW5kIHRleHQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzE2MyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMsIE9MRUNNRFRFWFQqIHBDbWRUZXh0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVsZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywgcHJnQ21kcywgcENtZFRleHQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMobHBPbGUsIHBndWlkQ21kR3JvdXAsIGNDbWRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJnQ21kcywgcENtZFRleHQpOwogICAgICBJT2xlQ29tbWFuZFRhcmdldF9SZWxlYXNlKGxwT2xlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTY0XQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duICAgICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb21tYW5kVGFyZ2V0IGludGVyZmFjZQogKiAgcGd1aWRDbWRHcm91cCBbSV0gR1VJRCBmb3IgdGhlIGNvbW1hbmQgZ3JvdXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKS4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMTY0KElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlbGQsJWxkLCVwLCVwKVxuIixscFVua25vd24sIHBndWlkQ21kR3JvdXAsIG5DbWRJRCwKICAgICAgICBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CgogIGlmIChscFVua25vd24pCiAgewogICAgSU9sZUNvbW1hbmRUYXJnZXQqIGxwT2xlOwoKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbW1hbmRUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscE9sZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMobHBPbGUsIHBndWlkQ21kR3JvdXAsIG5DbWRJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogICAgICBJT2xlQ29tbWFuZFRhcmdldF9SZWxlYXNlKGxwT2xlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjVdCiAqCiAqIFJldHJpZXZlLCBtb2RpZnksIGFuZCByZS1zZXQgYSB2YWx1ZSBmcm9tIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICBbSV0gV2luZG93IHRvIGdldCB2YWx1ZSBmcm9tCiAqICBvZmZzZXQgW0ldIE9mZnNldCBvZiB2YWx1ZQogKiAgd01hc2sgIFtJXSBNYXNrIGZvciB1aUZsYWdzCiAqICB3RmxhZ3MgW0ldIEJpdHMgdG8gc2V0IGluIHdpbmRvdyB2YWx1ZQogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHZhbHVlIGFzIGl0IHdhcyBzZXQsIG9yIDAgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkLgogKgogKiBOT1RFUwogKiAgQW55IGJpdHMgc2V0IGluIHVpTWFzayBhcmUgY2xlYXJlZCBmcm9tIHRoZSB2YWx1ZSwgdGhlbiBhbnkgYml0cyBzZXQgaW4KICogIHVpRmxhZ3MgYXJlIHNldCBpbiB0aGUgdmFsdWUuCiAqLwpMT05HIFdJTkFQSSBTSExXQVBJXzE2NShIV05EIGh3bmQsIElOVCBvZmZzZXQsIFVJTlQgd01hc2ssIFVJTlQgd0ZsYWdzKQp7CiAgTE9ORyByZXQgPSBHZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQpOwogIExPTkcgbmV3RmxhZ3MgPSAod0ZsYWdzICYgd01hc2spIHwgKHJldCAmIH53RmxhZ3MpOwoKICBpZiAobmV3RmxhZ3MgIT0gcmV0KQogICAgcmV0ID0gU2V0V2luZG93TG9uZ0EoaHduZCwgb2Zmc2V0LCBuZXdGbGFncyk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2N10KICoKICogQ2hhbmdlIGEgd2luZG93J3MgcGFyZW50LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgW0ldIFdpbmRvdyB0byBjaGFuZ2UgcGFyZW50IG9mCiAqICBoV25kUGFyZW50IFtJXSBOZXcgcGFyZW50IHdpbmRvdwogKgogKiBSRVRVUk5TCiAqICBUaGUgb2xkIHBhcmVudCBvZiBoV25kLgogKgogKiBOT1RFUwogKiAgSWYgaFduZFBhcmVudCBpcyBOVUxMIChkZXNrdG9wKSwgdGhlIHdpbmRvdyBzdHlsZSBpcyBjaGFuZ2VkIHRvIFdTX1BPUFVQLgogKiAgSWYgaFduZFBhcmVudCBpcyBOT1QgTlVMTCB0aGVuIHdlIHNldCB0aGUgV1NfQ0hJTEQgc3R5bGUuCiAqLwpIV05EIFdJTkFQSSBTSExXQVBJXzE2NyhIV05EIGhXbmQsIEhXTkQgaFduZFBhcmVudCkKewogIFRSQUNFKCIlcCwgJXBcbiIsIGhXbmQsIGhXbmRQYXJlbnQpOwoKICBpZihHZXRQYXJlbnQoaFduZCkgPT0gaFduZFBhcmVudCkKICAgIHJldHVybiAwOwoKICBpZihoV25kUGFyZW50KQogICAgU0hMV0FQSV8xNjUoaFduZCwgR1dMX1NUWUxFLCBXU19DSElMRCwgV1NfQ0hJTEQpOwogIGVsc2UKICAgIFNITFdBUElfMTY1KGhXbmQsIEdXTF9TVFlMRSwgV1NfUE9QVVAsIFdTX1BPUFVQKTsKCiAgcmV0dXJuIFNldFBhcmVudChoV25kLCBoV25kUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE2OF0KICoKICogTG9jYXRlIGFuZCBhZHZpc2UgYSBjb25uZWN0aW9uIHBvaW50IGluIGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rU2luayAgIFtJXSBTaW5rIGZvciB0aGUgY29ubmVjdGlvbiBwb2ludCBhZHZpc2UgY2FsbAogKiAgcmlpZCAgICAgICAgW0ldIFJFRklJRCBvZiBjb25uZWN0aW9uIHBvaW50IHRvIGFkdmlzZQogKiAgYkFkdmlzZU9ubHkgW0ldIFRSVUUgPSBBZHZpc2Ugb25seSwgRkFMU0UgPSBVbmFkdmlzZSBmaXJzdAogKiAgbHBVbmtub3duICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZQogKiAgbHBDb29raWUgICAgW09dIFBvaW50ZXIgdG8gY29ubmVjdGlvbiBwb2ludCBjb29raWUKICogIGxwcENQICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIElDb25uZWN0aW9uUG9pbnQgZm91bmQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgbHBwQ1AgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZCB3aXRoIHRoZSBJQ29ubmVjdGlvblBvaW50CiAqICAgICAgICAgICB0aGF0IHdhcyBhZHZpc2VkLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNhYmxlIGZvciByZWxlYXNpbmcgaXQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXNuJ3QgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZSBpZiBhbnkgY2FsbCBmYWlscy4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMTY4KElVbmtub3duKiBscFVua1NpbmssIFJFRklJRCByaWlkLCBCT09MIGJBZHZpc2VPbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biogbHBVbmtub3duLCBMUERXT1JEIGxwQ29va2llLAogICAgICAgICAgICAgICAgICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50ICoqbHBwQ1ApCnsKICBIUkVTVUxUIGhSZXQ7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDb250YWluZXI7CiAgSUNvbm5lY3Rpb25Qb2ludCAqbHBDUDsKCiAgaWYoIWxwVW5rbm93biB8fCAoYkFkdmlzZU9ubHkgJiYgIWxwVW5rU2luaykpCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZihscHBDUCkKICAgICpscHBDUCA9IE5VTEw7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDb250YWluZXIpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENvbnRhaW5lciwgcmlpZCwgJmxwQ1ApOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICB7CiAgICAgIGlmKCFiQWR2aXNlT25seSkKICAgICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9VbmFkdmlzZShscENQLCAqbHBDb29raWUpOwogICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9BZHZpc2UobHBDUCwgbHBVbmtTaW5rLCBscENvb2tpZSk7CgogICAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICAgICpscENvb2tpZSA9IDA7CgogICAgICBpZiAobHBwQ1AgJiYgU1VDQ0VFREVEKGhSZXQpKQogICAgICAgICpscHBDUCA9IGxwQ1A7IC8qIENhbGxlciBrZWVwcyB0aGUgaW50ZXJmYWNlICovCiAgICAgIGVsc2UKICAgICAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7IC8qIFJlbGVhc2UgaXQgKi8KICAgIH0KCiAgICBJVW5rbm93bl9SZWxlYXNlKGxwQ29udGFpbmVyKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCUAJW1NITFdBUEkuMTY5XQogKgogKiBSZWxlYXNlIGFuIGludGVyZmFjZS4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byByZWxlYXNlCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xNjkgKElVbmtub3duICoqIGxwVW5rbm93bikKewogICAgICAgIElVbmtub3duICp0ZW1wOwoKCVRSQUNFKCIoJXApXG4iLGxwVW5rbm93bik7CglpZighbHBVbmtub3duIHx8ICEqKChMUERXT1JEKWxwVW5rbm93bikpIHJldHVybiAwOwoJdGVtcCA9ICpscFVua25vd247CgkqbHBVbmtub3duID0gTlVMTDsKCVRSQUNFKCJkb2luZyBSZWxlYXNlXG4iKTsKCXJldHVybiBJVW5rbm93bl9SZWxlYXNlKHRlbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcwXQogKgogKiBTa2lwICcvLycgaWYgcHJlc2VudCBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTdHJpbmcgdG8gY2hlY2sgZm9yICcvLycKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIG5leHQgY2hhcmFjdGVyIGFmdGVyIHRoZSAnLy8nIG9yIHRoZSBzdHJpbmcgaWYgbm90IHByZXNlbnQKICogIEZhaWx1cmU6IE5VTEwsIGlmIGxwc3pTdHIgaXMgTlVMTC4KICovCkxQQ1NUUiBXSU5BUEkgU0hMV0FQSV8xNzAoTFBDU1RSIGxwc3pTcmMpCnsKICBpZiAobHBzelNyYyAmJiBscHN6U3JjWzBdID09ICcvJyAmJiBscHN6U3JjWzFdID09ICcvJykKICAgIGxwc3pTcmMgKz0gMjsKICByZXR1cm4gbHBzelNyYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNzFdCiAqCiAqIENoZWNrIGlmIHR3byBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgIGxwSW50MSBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQyLgogKiAgIGxwSW50MiBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQxLgogKgogKiBSRVRVUk5TCiAqICAgVFJVRSwgSWYgdGhlIGludGVyZmFjZXMgY29tZSBmcm9tIHRoZSBzYW1lIG9iamVjdC4KICogICBGQUxTRSBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzE3MShJVW5rbm93biogbHBJbnQxLCBJVW5rbm93biogbHBJbnQyKQp7CiAgTFBWT0lEIGxwVW5rbm93bjEsIGxwVW5rbm93bjI7CgogIFRSQUNFKCIlcCAlcFxuIiwgbHBJbnQxLCBscEludDIpOwoKICBpZiAoIWxwSW50MSB8fCAhbHBJbnQyKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBJbnQxID09IGxwSW50MikKICAgIHJldHVybiBUUlVFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDEsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMSkpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDIsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMikpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBVbmtub3duMSA9PSBscFVua25vd24yKQogICAgcmV0dXJuIFRSVUU7CiAgCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcyXQogKgogKiBHZXQgdGhlIHdpbmRvdyBoYW5kbGUgb2YgYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIGdldCB0aGUgd2luZG93IGhhbmRsZSBvZgogKiAgbHBoV25kICAgIFtPXSBEZXN0aW5hdGlvbiBmb3Igd2luZG93IGhhbmRsZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBscGhXbmQgY29udGFpbnMgdGhlIG9iamVjdHMgd2luZG93IGhhbmRsZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIGxwVW5rbm93biBpcyBleHBlY3RlZCB0byBzdXBwb3J0IG9uZSBvZiB0aGUgZm9sbG93aW5nIGludGVyZmFjZXM6CiAqICBJT2xlV2luZG93KCksIElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSgpLCBvciBJU2hlbGxWaWV3KCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzE3MihJVW5rbm93biAqbHBVbmtub3duLCBIV05EICpscGhXbmQpCnsKICAvKiBGSVhNRTogV2luZSBoYXMgbm8gaGVhZGVyIGZvciB0aGlzIG9iamVjdCAqLwogIHN0YXRpYyBjb25zdCBHVUlEIElJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUgPSB7IDB4NzllYWM5ZWQsCiAgICAweGJhZjksIDB4MTFjZSwgeyAweDhjLCAweDgyLCAweDAwLCAweGFhLCAweDAwLCAweDRiLCAweGE5LCAweDBiIH19OwogIElVbmtub3duICpscE9sZTsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwaFduZCk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIGhSZXQ7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZVdpbmRvdywgKHZvaWQqKikmbHBPbGUpOwoKICBpZiAoRkFJTEVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JU2hlbGxWaWV3LCAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHsKICAgICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwogICAgfQogIH0KCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICAvKiBMYXp5bmVzcyBoZXJlIC0gU2luY2UgR2V0V2luZG93KCkgaXMgdGhlIGZpcnN0IG1ldGhvZCBmb3IgdGhlIGFib3ZlIDMKICAgICAqIGludGVyZmFjZXMsIHdlIHVzZSB0aGUgc2FtZSBjYWxsIGZvciB0aGVtIGFsbC4KICAgICAqLwogICAgaFJldCA9IElPbGVXaW5kb3dfR2V0V2luZG93KChJT2xlV2luZG93KilscE9sZSwgbHBoV25kKTsKICAgIElVbmtub3duX1JlbGVhc2UobHBPbGUpOwogICAgaWYgKGxwaFduZCkKICAgICAgVFJBQ0UoIlJldHVybmluZyBIV05EPSVwXG4iLCAqbHBoV25kKTsKICB9CgogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTczXQogKgogKiBDYWxsIGEgbWV0aG9kIG9uIGFzIGFzIHlldCB1bmlkZW50aWZpZWQgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIHBVbmsgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSB1bmlkZW50aWZpZWQgaW50ZXJmYWNlLAogKiAgYXJnICBbSV0gQXJndW1lbnQgZm9yIHRoZSBjYWxsIG9uIHRoZSBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFNfT0suCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzE3MyhJVW5rbm93biAqcFVuaywgVUxPTkcgYXJnKQp7CiAgc3RhdGljIGNvbnN0IEdVSUQgZ3VpZF8xNzMgPSB7CiAgICAweDU4MzZmYjAwLCAweDgxODcsIDB4MTFjZiwgeyAweGExLDB4MmIsMHgwMCwweGFhLDB4MDAsMHg0YSwweGU4LDB4MzcgfQogIH07CiAgSU1hbGxvYyAqcFVuazI7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcFVuaywgYXJnKTsKCiAgLyogTm90ZTogYXJnIG1heSBub3QgYmUgYSBVTE9ORyBhbmQgcFVuazIgaXMgZm9yIHN1cmUgbm90IGFuIElNYWxsb2MgLQogICAqICAgICAgIFdlIHVzZSB0aGlzIGludGVyZmFjZSBhcyBpdHMgdnRhYmxlIGVudHJ5IGlzIGNvbXBhdGFibGUgd2l0aCB0aGUKICAgKiAgICAgICBvYmplY3QgaW4gcXVlc3Rpb24uCiAgICogRklYTUU6IEZpbmQgb3V0IHdoYXQgdGhpcyBvYmplY3QgaXMgYW5kIHdoZXJlIGl0IHNob3VsZCBiZSBkZWZpbmVkLgogICAqLwogIGlmIChwVW5rICYmCiAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rLCAmZ3VpZF8xNzMsICh2b2lkKiopJnBVbmsyKSkpCiAgewogICAgSU1hbGxvY19BbGxvYyhwVW5rMiwgYXJnKTsgLyogRmFrZWQgY2FsbCEhICovCiAgICBJTWFsbG9jX1JlbGVhc2UocFVuazIpOwogIH0KICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NF0KICoKICogQ2FsbCBlaXRoZXIgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUoKSBvciBJUGVyc2lzdE1vbmlrZXJfR2V0Q2xhc3NJRCgpIG9uCiAqIGFuIGludGVyZmFjZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgcDEgaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UgSWYgcDEgZG9lcyBub3Qgc3VwcG9ydCB0aGUgSVBlcnNpc3QgaW50ZXJmYWNlLAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTc0KAogICAgICAgIElVbmtub3duICpwMSwgICAgIC8qIFtpbl0gICBPTEUgb2JqZWN0ICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIExQVk9JRCAqcDIpICAgICAgIC8qIFtvdXRdICBwdHIgZm9yIGNhbGwgcmVzdWx0cyAqLwp7CiAgICBEV09SRCByZXQsIGFhOwoKICAgIGlmICghcDEpIHJldHVybiBFX0ZBSUw7CgogICAgLyogc2VlIGlmIFNldFNpdGUgaW50ZXJmYWNlIGV4aXN0cyBmb3IgSU9iamVjdFdpdGhTaXRlIG9iamVjdCAqLwogICAgcmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKElVbmtub3duICopcDEsIChSRUZJSUQpaWQxLCAoTFBWT0lEICopJnAxKTsKICAgIFRSQUNFKCJmaXJzdCBJVV9RSSByZXQ9JTA4bHgsIHAxPSVwXG4iLCByZXQsIHAxKTsKICAgIGlmIChyZXQpIHsKCgkvKiBzZWUgaWYgR2V0Q2xhc3NJZCBpbnRlcmZhY2UgZXhpc3RzIGZvciBJUGVyc2lzdE1vbmlrZXIgb2JqZWN0ICovCglyZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgoSVVua25vd24gKilwMSwgKFJFRklJRClpZDIsIChMUFZPSUQgKikmYWEpOwoJVFJBQ0UoInNlY29uZCBJVV9RSSByZXQ9JTA4bHgsIGFhPSUwOGx4XG4iLCByZXQsIGFhKTsKCWlmIChyZXQpIHJldHVybiByZXQ7CgoJLyogZmFrZSBhIEdldENsYXNzSWQgY2FsbCAqLwoJcmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cgKilhYSwgKEhXTkQqKXAyKTsKCVRSQUNFKCJzZWNvbmQgSVVfUUkgZG9pbmcgMHgwYyByZXQ9JTA4bHgsICpwMj0lMDhseFxuIiwgcmV0LAoJICAgICAgKihMUERXT1JEKXAyKTsKCUlVbmtub3duX1JlbGVhc2UoKElVbmtub3duICopYWEpOwogICAgfQogICAgZWxzZSB7CgkvKiBmYWtlIGEgU2V0U2l0ZSBjYWxsICovCglyZXQgPSBJT2xlV2luZG93X0dldFdpbmRvdygoSU9sZVdpbmRvdyAqKXAxLCAoSFdORCopcDIpOwoJVFJBQ0UoImZpcnN0IElVX1FJIGRvaW5nIDB4MGMgcmV0PSUwOGx4LCAqcDI9JTA4bHhcbiIsIHJldCwKCSAgICAgICooTFBEV09SRClwMik7CglJVW5rbm93bl9SZWxlYXNlKChJVW5rbm93biAqKXAxKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzVdCiAqCiAqIENhbGwgSVBlcnNpc3RfR2V0Q2xhc3NJRCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJUGVyc2lzdCBpbnRlcmZhY2UKICogIGxwQ2xhc3NJZCBbT10gRGVzdGluYXRpb24gZm9yIENsYXNzIElkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwQ2xhc3NJZCBjb250YWlucyB0aGUgQ2xhc3MgSWQgcmVxdWVzdGVkLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBscFVua25vd24gaXMgTlVMTCwKICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UgSWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSVBlcnNpc3QsCiAqICAgICAgICAgICBPciBhbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzE3NSAoSVVua25vd24gKmxwVW5rbm93biwgQ0xTSUQqIGxwQ2xhc3NJZCkKewogIElQZXJzaXN0KiBscFBlcnNpc3Q7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGxwQ2xhc3NJZCkpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JUGVyc2lzdCwodm9pZCoqKSZscFBlcnNpc3QpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgSVBlcnNpc3RfR2V0Q2xhc3NJRChscFBlcnNpc3QsIGxwQ2xhc3NJZCk7CiAgICAgIElQZXJzaXN0X1JlbGVhc2UobHBQZXJzaXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzZdCiAqCiAqIFJldHJpZXZlIGEgU2VydmljZSBJbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20KICogIHNpZCAgICAgICBbSV0gU2VydmljZSBJRCBmb3IgSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UoKSBjYWxsCiAqICByaWlkICAgICAgW0ldIEZ1bmN0aW9uIHJlcXVlc3RlZCBmb3IgUXVlcnlTZXJ2aWNlIGNhbGwKICogIGxwcE91dCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBzZXJ2aWNlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwcE91dCBjb250YWlucyBhbiBvYmplY3QgcHJvdmlkaW5nIHRoZSByZXF1ZXN0ZWQgc2VydmljZQogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzE3NihJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHNpZCwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqbHBwT3V0KQp7CiAgSVNlcnZpY2VQcm92aWRlciogcFNlcnZpY2UgPSBOVUxMOwogIEhSRVNVTFQgaFJldDsKCiAgaWYgKCFscHBPdXQpCiAgICByZXR1cm4gRV9GQUlMOwoKICAqbHBwT3V0ID0gTlVMTDsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICAvKiBHZXQgYW4gSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgZnJvbSB0aGUgb2JqZWN0ICovCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JU2VydmljZVByb3ZpZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcFNlcnZpY2UpOwoKICBpZiAoIWhSZXQgJiYgcFNlcnZpY2UpCiAgewogICAgVFJBQ0UoIlF1ZXJ5SW50ZXJmYWNlIHJldHVybmVkIChJU2VydmljZVByb3ZpZGVyKiklcFxuIiwgcFNlcnZpY2UpOwoKICAgIC8qIEdldCBhIFNlcnZpY2UgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogICAgaFJldCA9IElTZXJ2aWNlUHJvdmlkZXJfUXVlcnlTZXJ2aWNlKHBTZXJ2aWNlLCBzaWQsIHJpaWQsIGxwcE91dCk7CgogICAgVFJBQ0UoIihJU2VydmljZVByb3ZpZGVyKiklcCByZXR1cm5lZCAoSVVua25vd24qKSVwXG4iLCBwU2VydmljZSwgKmxwcE91dCk7CgogICAgLyogUmVsZWFzZSB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgKi8KICAgIElVbmtub3duX1JlbGVhc2UocFNlcnZpY2UpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3N10KICoKICogRGVzdHJveSBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaEluc3QgIFtJXSBJbnN0YW5jZSBoYW5kbGUKICogIHN6TmFtZSBbSV0gTWVudSBuYW1lCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMTc3KEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiBzek5hbWUpCnsKICBITUVOVSBoTWVudSwgaFN1Yk1lbnU7CgogIGlmICgoaE1lbnUgPSBMb2FkTWVudVcoaEluc3QsIHN6TmFtZSkpKQogIHsKICAgIGlmICgoaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCAwKSkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsgLyogRklYTUU6IFNob3VsZCBiZTogU0hMV0FQSV80MjYoaE1lbnUpOyAqLwogICAgcmV0dXJuIFRSVUU7CiAgfQogIHJldHVybiBGQUxTRTsKfQoKdHlwZWRlZiBzdHJ1Y3QgX2VudW1XbmREYXRhCnsKICBVSU5UICAgdWlNc2dJZDsKICBXUEFSQU0gd1BhcmFtOwogIExQQVJBTSBsUGFyYW07CiAgTFJFU1VMVCAoV0lOQVBJICpwZm5Qb3N0KShIV05ELFVJTlQsV1BBUkFNLExQQVJBTSk7Cn0gZW51bVduZERhdGE7CgovKiBDYWxsYmFjayBmb3IgU0hMV0FQSV8xNzggKi8Kc3RhdGljIEJPT0wgQ0FMTEJBQ0sgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jKEhXTkQgaFduZCwgTFBBUkFNIGxQYXJhbSkKewogIGVudW1XbmREYXRhICpkYXRhID0gKGVudW1XbmREYXRhICopbFBhcmFtOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFduZCwgZGF0YSk7CiAgZGF0YS0+cGZuUG9zdChoV25kLCBkYXRhLT51aU1zZ0lkLCBkYXRhLT53UGFyYW0sIGRhdGEtPmxQYXJhbSk7CiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE3OF0KICoKICogU2VuZCBvciBwb3N0IGEgbWVzc2FnZSB0byBldmVyeSBjaGlsZCBvZiBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgIFtJXSBXaW5kb3cgd2hvc2UgY2hpbGRyZW4gd2lsbCBnZXQgdGhlIG1lc3NhZ2VzCiAqICB1aU1zZ0lkIFtJXSBNZXNzYWdlIElkCiAqICB3UGFyYW0gIFtJXSBXUEFSQU0gb2YgbWVzc2FnZQogKiAgbFBhcmFtICBbSV0gTFBBUkFNIG9mIG1lc3NhZ2UKICogIGJTZW5kICAgW0ldIFRSVUUgPSBVc2UgU2VuZE1lc3NhZ2VBKCksIEZBTFNFID0gVXNlIFBvc3RNZXNzYWdlQSgpCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqCiAqIE5PVEVTCiAqICBUaGUgYXBwcm9wcmlhdGUgQVNDSUkgb3IgVW5pY29kZSBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIHRoZSB3aW5kb3cuCiAqLwp2b2lkIFdJTkFQSSBTSExXQVBJXzE3OChIV05EIGhXbmQsIFVJTlQgdWlNc2dJZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSwgQk9PTCBiU2VuZCkKewogIGVudW1XbmREYXRhIGRhdGE7CgogIFRSQUNFKCIoJXAsJXUsJWQsJWxkLCVkKVxuIiwgaFduZCwgdWlNc2dJZCwgd1BhcmFtLCBsUGFyYW0sIGJTZW5kKTsKCiAgaWYoaFduZCkKICB7CiAgICBkYXRhLnVpTXNnSWQgPSB1aU1zZ0lkOwogICAgZGF0YS53UGFyYW0gID0gd1BhcmFtOwogICAgZGF0YS5sUGFyYW0gID0gbFBhcmFtOwoKICAgIGlmIChiU2VuZCkKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVNlbmRNZXNzYWdlVyA6ICh2b2lkKilTZW5kTWVzc2FnZUE7CiAgICBlbHNlCiAgICAgIGRhdGEucGZuUG9zdCA9IElzV2luZG93VW5pY29kZShoV25kKSA/ICh2b2lkKilQb3N0TWVzc2FnZVcgOiAodm9pZCopUG9zdE1lc3NhZ2VBOwoKICAgIEVudW1DaGlsZFdpbmRvd3MoaFduZCwgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jLCAoTFBBUkFNKSZkYXRhKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODBdCiAqCiAqIFJlbW92ZSBhbGwgc3ViLW1lbnVzIGZyb20gYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIHJlbW92ZSBzdWItbWVudXMgZnJvbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiAwLiAgQWxsIHN1Yi1tZW51cyB1bmRlciBoTWVudSBhcmUgcmVtb3ZlZAogKiAgRmFpbHVyZTogLTEsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTgwKEhNRU5VIGhNZW51KQp7CiAgaW50IGlJdGVtQ291bnQgPSBHZXRNZW51SXRlbUNvdW50KGhNZW51KSAtIDE7CiAgd2hpbGUgKGlJdGVtQ291bnQgPj0gMCkKICB7CiAgICBITUVOVSBoU3ViTWVudSA9IEdldFN1Yk1lbnUoaE1lbnUsIGlJdGVtQ291bnQpOwogICAgaWYgKGhTdWJNZW51KQogICAgICBSZW1vdmVNZW51KGhNZW51LCBpSXRlbUNvdW50LCBNRl9CWVBPU0lUSU9OKTsKICAgIGlJdGVtQ291bnQtLTsKICB9CiAgcmV0dXJuIGlJdGVtQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODFdCiAqCiAqIEVuYWJsZSBvciBkaXNhYmxlIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51ICAgW0ldIE1lbnUgaG9sZGluZyBtZW51IGl0ZW0KICogIHVJRCAgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBlbmFibGUvZGlzYWJsZQogKiAgYkVuYWJsZSBbSV0gV2hldGhlciB0byBlbmFibGUgKFRSVUUpIG9yIGRpc2FibGUgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gRW5hYmxlTWVudUl0ZW0uCiAqLwpVSU5UIFdJTkFQSSBTSExXQVBJXzE4MShITUVOVSBoTWVudSwgVUlOVCB3SXRlbUlELCBCT09MIGJFbmFibGUpCnsKICByZXR1cm4gRW5hYmxlTWVudUl0ZW0oaE1lbnUsIHdJdGVtSUQsIGJFbmFibGUgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4xODJdCiAqCiAqIENoZWNrIG9yIHVuY2hlY2sgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBjaGVjay91bmNoZWNrCiAqICBiQ2hlY2sgW0ldIFdoZXRoZXIgdG8gY2hlY2sgKFRSVUUpIG9yIHVuY2hlY2sgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gQ2hlY2tNZW51SXRlbS4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE4MihITUVOVSBoTWVudSwgVUlOVCB1SUQsIEJPT0wgYkNoZWNrKQp7CiAgcmV0dXJuIENoZWNrTWVudUl0ZW0oaE1lbnUsIHVJRCwgYkNoZWNrID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODNdCiAqCiAqIFJlZ2lzdGVyIGEgd2luZG93IGNsYXNzIGlmIGl0IGlzbid0IGFscmVhZHkuCiAqCiAqIFBBUkFNUwogKiAgbHBXbmRDbGFzcyBbSV0gV2luZG93IGNsYXNzIHRvIHJlZ2lzdGVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXN1bHQgb2YgdGhlIFJlZ2lzdGVyQ2xhc3NBIGNhbGwuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xODMoV05EQ0xBU1NBICp3bmRjbGFzcykKewogIFdORENMQVNTQSB3Y2E7CiAgaWYgKEdldENsYXNzSW5mb0Eod25kY2xhc3MtPmhJbnN0YW5jZSwgd25kY2xhc3MtPmxwc3pDbGFzc05hbWUsICZ3Y2EpKQogICAgcmV0dXJuIFRSVUU7CiAgcmV0dXJuIChEV09SRClSZWdpc3RlckNsYXNzQSh3bmRjbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODddCiAqCiAqIENhbGwgSVBlcnNpc3RQcm9wZXJ0eUJhZ19Mb2FkKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0UHJvcGVydHlCYWcgaW50ZXJmYWNlCiAqICBscFByb3BCYWcgW09dIERlc3RpbmF0aW9uIGZvciBsb2FkZWQgSVByb3BlcnR5QmFnCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfRkFJTCBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzE4NyhJVW5rbm93biAqbHBVbmtub3duLCBJUHJvcGVydHlCYWcqIGxwUHJvcEJhZykKewogIElQZXJzaXN0UHJvcGVydHlCYWcqIGxwUFBCYWc7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscFByb3BCYWcpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVBlcnNpc3RQcm9wZXJ0eUJhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFBQQmFnKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBQUEJhZykKICAgIHsKICAgICAgaFJldCA9IElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZChscFBQQmFnLCBscFByb3BCYWcsIE5VTEwpOwogICAgICBJUGVyc2lzdFByb3BlcnR5QmFnX1JlbGVhc2UobHBQUEJhZyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29udHJvbFNpdGUgaW50ZXJmYWNlCiAqICBscHBEaXNwICAgW09dIERlc3RpbmF0aW9uIGZvciByZXN1bHRpbmcgSURpc3BhdGNoLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xODkoSVVua25vd24gKmxwVW5rbm93biwgSURpc3BhdGNoKiogbHBwRGlzcCkKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZTsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwcERpc3ApOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29udHJvbFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDU2l0ZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwQ1NpdGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29udHJvbFNpdGVfR2V0RXh0ZW5kZWRDb250cm9sKGxwQ1NpdGUsIGxwcERpc3ApOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCnN0YXRpYyBjb25zdCBXQ0hBUiBzekRvbnRTaG93S2V5W10gPSB7ICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1xcJywKICAnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsJ0QnLCdvJywnbicsJ3QnLCdTJywnaCcsJ28nLCd3JywKICAnTScsJ2UnLCdUJywnaCcsJ2knLCdzJywnRCcsJ2knLCdhJywnbCcsJ28nLCdnJywnQScsJ2cnLCdhJywnaScsJ24nLCdcMCcKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgW1NITFdBUEkuMTkxXQogKgogKiBQb3AgdXAgYSAnRG9uJ3Qgc2hvdyB0aGlzIG1lc3NhZ2UgYWdhaW4nIGVycm9yIGRpYWxvZyBib3guCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgIFtJXSBXaW5kb3cgdG8gb3duIHRoZSBkaWFsb2cgYm94CiAqICBhcmcyICAgICAgW0ldIFVua25vd24KICogIGFyZzMgICAgICBbSV0gVW5rbm93bgogKiAgYXJnNCAgICAgIFtJXSBVbmtub3duCiAqICBhcmc1ICAgICAgW0ldIFVua25vd24KICogIGxwc3pWYWx1ZSBbSV0gUmVnaXN0cnkgdmFsdWUgaG9sZGluZyBib29sZWFuIHNob3cvZG9uJ3Qgc2hvdy4KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCnZvaWQgV0lOQVBJIFNITFdBUElfMTkxKEhXTkQgaFduZCwgUFZPSUQgYXJnMiwgUFZPSUQgYXJnMywgUFZPSUQgYXJnNCwgUFZPSUQgYXJnNSwgTFBDV1NUUiBscHN6VmFsdWUpCnsKICBGSVhNRSgiKCVwLCVwLCVwLCVwLCVwLCVzKSAtIHN0dWIhXG4iLCBoV25kLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1LCBkZWJ1Z3N0cl93KGxwc3pWYWx1ZSkpOwoKICBpZiAoU0hSZWdHZXRCb29sVVNWYWx1ZVcoc3pEb250U2hvd0tleSwgbHBzelZhbHVlLCBGQUxTRSwgVFJVRSkpCiAgewogICAgLyogRklYTUU6IFNob3VsZCB1c2UgRGlhbG9nQm94UGFyYW1XIHRvIGxvYWQgYSBkaWFsb2cgYm94OyBpdHMgZGxncHJvYwogICAgICogc2hvdWxkIGFjY2VwdCBjbGlja3Mgb24gJ0Rvbid0IHNob3cnIGFuZCBzZXQgdGhlIHJlZyB2YWx1ZSBhcHByb3ByaWF0ZWx5LgogICAgICovCiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgIFtTSExXQVBJLjE5Ml0KICoKICogR2V0IGEgc3ViLW1lbnUgZnJvbSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byBnZXQgc3ViLW1lbnUgZnJvbQogKiAgdUlEICAgW0ldIElEIG9mIG1lbnUgaXRlbSBjb250YWluaW5nIHN1Yi1tZW51CiAqCiAqIFJFVFVSTlMKICogIFRoZSBzdWItbWVudSBvZiB0aGUgaXRlbSwgb3IgYSBOVUxMIGhhbmRsZSBpZiBhbnkgcGFyYW1ldGVycyBhcmUgaW52YWxpZC4KICovCkhNRU5VIFdJTkFQSSBTSExXQVBJXzE5MihITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICBNRU5VSVRFTUlORk9BIG1pOwoKICBUUkFDRSgiKCVwLCV1bGQpXG4iLCBoTWVudSwgdUlEKTsKCiAgbWkuY2JTaXplID0gc2l6ZW9mKE1FTlVJVEVNSU5GT0EpOwogIG1pLmZNYXNrID0gTUlJTV9TVUJNRU5VOwoKICBpZiAoIUdldE1lbnVJdGVtSW5mb0EoaE1lbnUsIHVJRCwgMCwgJm1pKSkKICAgIHJldHVybiAoSE1FTlUpTlVMTDsKCiAgcmV0dXJuIG1pLmhTdWJNZW51Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTkzXQogKgogKiBHZXQgdGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8xOTMgKCkKewoJSERDIGhkYzsKCURXT1JEIHJldDsKCglUUkFDRSgiKClcbiIpOwoKCWhkYyA9IEdldERDKDApOwoJcmV0ID0gR2V0RGV2aWNlQ2FwcyhoZGMsIEJJVFNQSVhFTCkgKiBHZXREZXZpY2VDYXBzKGhkYywgUExBTkVTKTsKCVJlbGVhc2VEQygwLCBoZGMpOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5N10KICoKICogQmxhbmsgb3V0IGEgcmVnaW9uIG9mIHRleHQgYnkgZHJhd2luZyB0aGUgYmFja2dyb3VuZCBvbmx5LgogKgogKiBQQVJBTVMKICogIGhEQyAgIFtJXSBEZXZpY2UgY29udGV4dCB0byBkcmF3IGluCiAqICBwUmVjdCBbSV0gQXJlYSB0byBkcmF3IGluCiAqICBjUmVmICBbSV0gQ29sb3IgdG8gZHJhdyBpbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMTk3KEhEQyBoREMsIExQQ1JFQ1QgcFJlY3QsIENPTE9SUkVGIGNSZWYpCnsKICAgIENPTE9SUkVGIGNPbGRDb2xvciA9IFNldEJrQ29sb3IoaERDLCBjUmVmKTsKICAgIEV4dFRleHRPdXRBKGhEQywgMCwgMCwgRVRPX09QQVFVRSwgcFJlY3QsIDAsIDAsIDApOwogICAgU2V0QmtDb2xvcihoREMsIGNPbGRDb2xvcik7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5OV0KICoKICogQ29weSBhbiBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBQQVJBTVMKICogICBscHBEZXN0ICAgW09dIERlc3RpbmF0aW9uIGZvciBjb3B5CiAqICAgbHBVbmtub3duIFtJXSBTb3VyY2UgZm9yIGNvcHkKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovClZPSUQgV0lOQVBJIFNITFdBUElfMTk5KElVbmtub3duICoqbHBwRGVzdCwgSVVua25vd24gKmxwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscHBEZXN0LCBscFVua25vd24pOwoKICBpZiAobHBwRGVzdCkKICAgIFNITFdBUElfMTY5KGxwcERlc3QpOyAvKiBSZWxlYXNlIGV4aXN0aW5nIGludGVyZmFjZSAqLwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgKi8KICAgIElVbmtub3duX0FkZFJlZihscFVua25vd24pOwogICAgKmxwcERlc3QgPSBscFVua25vd247CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjAxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8yMDEoSVVua25vd24qIGxwVW5rbm93biwgSU5UIGlVbmssIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEZJWE1FKCIoJXAsJWQsJXAsJWxkLCVsZCwlcCwlcCkgLSBzdHViIVxuIiwgbHBVbmtub3duLCBpVW5rLCBwZ3VpZENtZEdyb3VwLAogICAgICAgIG5DbWRJRCwgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzIwMihSRUZHVUlEIHBndWlkQ21kR3JvdXAsVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcykKewogIEZJWE1FKCIoJXAsJWxkLCVwKSAtIHN0dWIhXG4iLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywgcHJnQ21kcyk7CiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4yMDRdCiAqCiAqIERldGVybWluZSBpZiBhIHdpbmRvdyBpcyBub3QgYSBjaGlsZCBvZiBhbm90aGVyIHdpbmRvdy4KICoKICogUEFSQU1TCiAqIGhQYXJlbnQgW0ldIFN1c3BlY3RlZCBwYXJlbnQgd2luZG93CiAqIGhDaGlsZCAgW0ldIFN1c3BlY3RlZCBjaGlsZCB3aW5kb3cKICoKICogUkVUVVJOUwogKiBUUlVFOiAgSWYgaENoaWxkIGlzIGEgY2hpbGQgd2luZG93IG9mIGhQYXJlbnQKICogRkFMU0U6IElmIGhDaGlsZCBpcyBub3QgYSBjaGlsZCB3aW5kb3cgb2YgaFBhcmVudCwgb3IgdGhleSBhcmUgZXF1YWwKICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjA0KEhXTkQgaFBhcmVudCwgSFdORCBoQ2hpbGQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFBhcmVudCwgaENoaWxkKTsKCiAgaWYgKCFoUGFyZW50IHx8ICFoQ2hpbGQpCiAgICByZXR1cm4gVFJVRTsKICBlbHNlIGlmKGhQYXJlbnQgPT0gaENoaWxkKQogICAgcmV0dXJuIEZBTFNFOwogIHJldHVybiAhSXNDaGlsZChoUGFyZW50LCBoQ2hpbGQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA4XQogKgogKiBTb21lIHNvcnQgb2YgbWVtb3J5IG1hbmFnZW1lbnQgcHJvY2VzcyAtIGFzc29jaWF0ZWQgd2l0aCBfMjEwCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8yMDggKAoJRFdPUkQgICAgYSwKCURXT1JEICAgIGIsCglMUFZPSUQgICBjLAoJTFBWT0lEICAgZCwKCURXT1JEICAgIGUpCnsKICAgIEZJWE1FKCIoMHglMDhseCAweCUwOGx4ICVwICVwIDB4JTA4bHgpIHN0dWJcbiIsCgkgIGEsIGIsIGMsIGQsIGUpOwogICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDldCiAqCiAqIFNvbWUgc29ydCBvZiBtZW1vcnkgbWFuYWdlbWVudCBwcm9jZXNzIC0gYXNzb2NpYXRlZCB3aXRoIF8yMDgKICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzIwOSAoCglMUFZPSUQgICBhKQp7CiAgICBGSVhNRSgiKCVwKSBzdHViXG4iLAoJICBhKTsKICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjEwXQogKgogKiBTb21lIHNvcnQgb2YgbWVtb3J5IG1hbmFnZW1lbnQgcHJvY2VzcyAtIGFzc29jaWF0ZWQgd2l0aCBfMjA4CiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8yMTAgKAoJTFBWT0lEICAgYSwKCURXT1JEICAgIGIsCglMUFZPSUQgICBjKQp7CiAgICBGSVhNRSgiKCVwIDB4JTA4bHggJXApIHN0dWJcbiIsCgkgIGEsIGIsIGMpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTFdCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8yMTEgKAoJTFBWT0lEICAgYSwKCURXT1JEICAgIGIpCnsKICAgIEZJWE1FKCIoJXAgMHglMDhseCkgc3R1YlxuIiwKCSAgYSwgYik7CiAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxNV0KICoKICogTk9URVMKICogIGNoZWNrIG1lIQogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMjE1ICgKCUxQQ1NUUiBscFN0clNyYywKCUxQV1NUUiBscHdTdHJEZXN0LAoJaW50IGxlbikKewoJSU5UIGxlbl9hLCByZXQ7CgoJbGVuX2EgPSBsc3RybGVuQShscFN0clNyYyk7CglyZXQgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKDAsIDAsIGxwU3RyU3JjLCBsZW5fYSwgbHB3U3RyRGVzdCwgbGVuKTsKCVRSQUNFKCIlcyAlcyAlZCwgcmV0PSVkXG4iLAoJICAgICAgZGVidWdzdHJfYShscFN0clNyYyksIGRlYnVnc3RyX3cobHB3U3RyRGVzdCksIGxlbiwgcmV0KTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMThdCiAqCiAqIFdpZGVDaGFyVG9NdWx0aUJ5dGUgd2l0aCBzdXBwb3J0IGZvciBtdWx0aXBsZSBjb2RlcGFnZXMuCiAqCiAqIFBBUkFNUwogKiAgQ29kZVBhZ2UgICAgICAgICAgW0ldIENvZGUgcGFnZSB0byB1c2UgZm9yIHRoZSBjb252ZXJzaW9uCiAqICBscFNyY1N0ciAgICAgICAgICBbSV0gU291cmNlIFVuaWNvZGUgc3RyaW5nIHRvIGNvbnZlcnQKICogIGxwRHN0U3RyICAgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIEFzY2lpIHN0cmluZwogKiAgbHBuTXVsdGlDaGFyQ291bnQgW09dIElucHV0IGxlbmd0aCBvZiBscERzdFN0ci9kZXN0aW5hdGlvbiBmb3IgbGVuZ3RoIG9mIGxwRHN0U3RyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IHJlc3VsdCBmcm9tIHRoZSBjb252ZXJzaW9uLgogKiAgRmFpbHVyZTogMC4KICovCklOVCBXSU5BUEkgU0hMV0FQSV8yMTgoVUlOVCBDb2RlUGFnZSwgTFBDV1NUUiBscFNyY1N0ciwgTFBTVFIgbHBEc3RTdHIsCiAgICAgICAgICAgICAgICAgICAgICAgTFBJTlQgbHBuTXVsdGlDaGFyQ291bnQpCnsKICBXQ0hBUiBlbXB0eVdbXSA9IHsgJ1wwJyB9OwogIGludCBsZW4gLCByZXFMZW47CiAgTFBTVFIgbWVtOwoKICBpZiAoIWxwRHN0U3RyIHx8ICFscG5NdWx0aUNoYXJDb3VudCkKICAgIHJldHVybiAwOwoKICBpZiAoIWxwU3JjU3RyKQogICAgbHBTcmNTdHIgPSBlbXB0eVc7CgogICpscERzdFN0ciA9ICdcMCc7CgogIGxlbiA9IHN0cmxlblcobHBTcmNTdHIpICsgMTsKCiAgc3dpdGNoIChDb2RlUGFnZSkKICB7CiAgY2FzZSBDUF9XSU5VTklDT0RFOgogICAgQ29kZVBhZ2UgPSBDUF9VVEY4OyAvKiBGYWxsIHRocm91Z2guLi4gKi8KICBjYXNlIDB4MDAwMEMzNTA6IC8qIEZJWE1FOiBDUF8gI2RlZmluZSAqLwogIGNhc2UgQ1BfVVRGNzoKICBjYXNlIENQX1VURjg6CiAgICB7CiAgICAgIERXT1JEIGR3TW9kZSA9IDA7CiAgICAgIElOVCBuV2lkZUNoYXJDb3VudCA9IGxlbiAtIDE7CgogICAgICBHRVRfRlVOQyhwQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUsIG1sYW5nLCAiQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUiLCAwKTsKICAgICAgaWYgKCFwQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUoJmR3TW9kZSwgQ29kZVBhZ2UsIGxwU3JjU3RyLCAmbldpZGVDaGFyQ291bnQsIGxwRHN0U3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscG5NdWx0aUNoYXJDb3VudCkpCiAgICAgICAgcmV0dXJuIDA7CgogICAgICBpZiAobldpZGVDaGFyQ291bnQgPCBsZW4gLSAxKQogICAgICB7CiAgICAgICAgbWVtID0gKExQU1RSKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAqbHBuTXVsdGlDaGFyQ291bnQpOwogICAgICAgIGlmICghbWVtKQogICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgICpscG5NdWx0aUNoYXJDb3VudCA9IDA7CgogICAgICAgIGlmIChwQ29udmVydElOZXRVbmljb2RlVG9NdWx0aUJ5dGUoJmR3TW9kZSwgQ29kZVBhZ2UsIGxwU3JjU3RyLCAmbGVuLCBtZW0sIGxwbk11bHRpQ2hhckNvdW50KSkKICAgICAgICB7CiAgICAgICAgICBTSExXQVBJXzE2MiAobWVtLCAqbHBuTXVsdGlDaGFyQ291bnQpOwogICAgICAgICAgbHN0cmNweW5BKGxwRHN0U3RyLCBtZW0sICpscG5NdWx0aUNoYXJDb3VudCArIDEpOwogICAgICAgICAgcmV0dXJuICpscG5NdWx0aUNoYXJDb3VudCArIDE7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgcmV0dXJuICpscG5NdWx0aUNoYXJDb3VudDsKICAgICAgfQogICAgICBscERzdFN0clsqbHBuTXVsdGlDaGFyQ291bnRdID0gJ1wwJzsKICAgICAgcmV0dXJuICpscG5NdWx0aUNoYXJDb3VudDsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBicmVhazsKICB9CgogIHJlcUxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ29kZVBhZ2UsIDAsIGxwU3JjU3RyLCBsZW4sIGxwRHN0U3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmxwbk11bHRpQ2hhckNvdW50LCBOVUxMLCBOVUxMKTsKCiAgaWYgKCFyZXFMZW4gJiYgR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUikKICB7CiAgICByZXFMZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENvZGVQYWdlLCAwLCBscFNyY1N0ciwgbGVuLCBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIGlmIChyZXFMZW4pCiAgICB7CiAgICAgIG1lbSA9IChMUFNUUilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVxTGVuKTsKICAgICAgaWYgKG1lbSkKICAgICAgewogICAgICAgIHJlcUxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ29kZVBhZ2UsIDAsIGxwU3JjU3RyLCBsZW4sIG1lbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcUxlbiwgTlVMTCwgTlVMTCk7CgogICAgICAgIHJlcUxlbiA9IFNITFdBUElfMTYyKG1lbSwgKmxwbk11bHRpQ2hhckNvdW50KTsKICAgICAgICByZXFMZW4rKzsKCiAgICAgICAgbHN0cmNweW5BKGxwRHN0U3RyLCBtZW0sICpscG5NdWx0aUNoYXJDb3VudCk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHJlcUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxN10KICoKICogV2lkZUNoYXJUb011bHRpQnl0ZSB3aXRoIHN1cHBvcnQgZm9yIG11bHRpcGxlIGNvZGVwYWdlcy4KICoKICogUEFSQU1TCiAqICBscFNyY1N0ciAgICAgICAgICBbSV0gU291cmNlIFVuaWNvZGUgc3RyaW5nIHRvIGNvbnZlcnQKICogIGxwRHN0U3RyICAgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIEFzY2lpIHN0cmluZwogKiAgbHBuTXVsdGlDaGFyQ291bnQgW09dIElucHV0IGxlbmd0aCBvZiBscERzdFN0ci9kZXN0aW5hdGlvbiBmb3IgbGVuZ3RoIG9mIGxwRHN0U3RyCiAqCiAqIFJFVFVSTlMKICogIFNlZSBTSExXQVBJXzIxOC4KCiAqIE5PVEVTCiAqICBUaGlzIGZ1bmN0aW9uIHNpbXBseSBjYWxscyBTSExXQVBJXzIxOCgpIHdpdGggQ29kZVBhZ2UgPSBDUF9BQ1AuCiAqLwpJTlQgV0lOQVBJIFNITFdBUElfMjE3KExQQ1dTVFIgbHBTcmNTdHIsIExQU1RSIGxwRHN0U3RyLCBJTlQgTXVsdGlDaGFyQ291bnQpCnsKICAgIElOVCBteWludCA9IE11bHRpQ2hhckNvdW50OwoKICAgIHJldHVybiBTSExXQVBJXzIxOChDUF9BQ1AsIGxwU3JjU3RyLCBscERzdFN0ciwgJm15aW50KTsKfQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgUkVGSUlEICAgcmVmaWQ7CiAgICBEV09SRCAgICBpbmR4Owp9IElGQUNFX0lOREVYX1RCTDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTldCiAqCiAqIENhbGwgSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKSBvbiBhIHRhYmxlIG9mIG9iamVjdHMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX1BPSU5URVIgb3IgRV9OT0lOVEVSRkFDRS4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMjE5ICgKCUxQVk9JRCB3LCAgICAgICAgICAgLyogW2luXSAgIFRhYmxlIG9mIGludGVyZmFjZXMgKi8KCUlGQUNFX0lOREVYX1RCTCAqeCwgLyogW2luXSAgIEFycmF5IG9mIFJFRklJRHMgYW5kIGluZGV4ZXMgaW50byB0aGUgdGFibGUgKi8KCVJFRklJRCByaWlkLCAgICAgICAgLyogW2luXSAgIFJFRklJRCB0byBnZXQgaW50ZXJmYWNlIGZvciAqLwoJTFBWT0lEICpwcHYpICAgICAgICAgIC8qIFtvdXRdICBEZXN0aW5hdGlvbiBmb3IgaW50ZXJmYWNlIHBvaW50ZXIgKi8KewoJSFJFU1VMVCByZXQ7CglJVW5rbm93biAqYV92dGJsOwoJSUZBQ0VfSU5ERVhfVEJMICp4bW92ZTsKCglUUkFDRSgiKCVwICVwICVzICVwKVxuIiwgdyx4LGRlYnVnc3RyX2d1aWQocmlpZCkscHB2KTsKCWlmIChwcHYpIHsKCSAgICB4bW92ZSA9IHg7CgkgICAgd2hpbGUgKHhtb3ZlLT5yZWZpZCkgewoJCVRSQUNFKCJ0cnlpbmcgKGluZHggJWxkKSAlc1xuIiwgeG1vdmUtPmluZHgsIGRlYnVnc3RyX2d1aWQoeG1vdmUtPnJlZmlkKSk7CgkJaWYgKElzRXF1YWxJSUQocmlpZCwgeG1vdmUtPnJlZmlkKSkgewoJCSAgICBhX3Z0YmwgPSAoSVVua25vd24qKSh4bW92ZS0+aW5keCArIChMUEJZVEUpdyk7CgkJICAgIFRSQUNFKCJtYXRjaGVkLCByZXR1cm5pbmcgKCVwKVxuIiwgYV92dGJsKTsKCQkgICAgKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCSAgICBJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQkgICAgcmV0dXJuIFNfT0s7CgkJfQoJCXhtb3ZlKys7CgkgICAgfQoKCSAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgewoJCWFfdnRibCA9IChJVW5rbm93biopKHgtPmluZHggKyAoTFBCWVRFKXcpOwoJCVRSQUNFKCJyZXR1cm5pbmcgZmlyc3QgZm9yIElVbmtub3duICglcClcbiIsIGFfdnRibCk7CgkJKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCUlVbmtub3duX0FkZFJlZihhX3Z0YmwpOwoJCXJldHVybiBTX09LOwoJICAgIH0KCSAgICAqcHB2ID0gMDsKCSAgICByZXQgPSBFX05PSU5URVJGQUNFOwoJfSBlbHNlCgkgICAgcmV0ID0gRV9QT0lOVEVSOwoKCVRSQUNFKCItLSAweCUwOGx4XG4iLCByZXQpOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIyMV0KICoKICogUmVtb3ZlIHRoZSAiUHJvcERsZ0ZvbnQiIHByb3BlcnR5IGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCBbSV0gV2luZG93IHRvIHJlbW92ZSB0aGUgcHJvcGVydHkgZnJvbQogKgogKiBSRVRVUk5TCiAqICBBIGhhbmRsZSB0byB0aGUgcmVtb3ZlZCBwcm9wZXJ0eSwgb3IgTlVMTCBpZiBpdCBkaWQgbm90IGV4aXN0LgogKi8KSEFORExFIFdJTkFQSSBTSExXQVBJXzIyMShIV05EIGhXbmQpCnsKICBIQU5ETEUgaFByb3A7CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaFByb3AgPSBHZXRQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKCiAgaWYoaFByb3ApCiAgewogICAgRGVsZXRlT2JqZWN0KGhQcm9wKTsKICAgIGhQcm9wID0gUmVtb3ZlUHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CiAgfQogIHJldHVybiBoUHJvcDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzNl0KICoKICogTG9hZCB0aGUgaW4tcHJvY2VzcyBzZXJ2ZXIgb2YgYSBnaXZlbiBHVUlELgogKgogKiBQQVJBTVMKICogIHJlZmlpZCBbSV0gR1VJRCBvZiB0aGUgc2VydmVyIHRvIGxvYWQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgc2VydmVyIGRsbC4KICogIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqLwpITU9EVUxFIFdJTkFQSSBTSExXQVBJXzIzNihSRUZJSUQgcmVmaWlkKQp7CiAgICBIS0VZIG5ld2tleTsKICAgIERXT1JEIHR5cGUsIGNvdW50OwogICAgQ0hBUiB2YWx1ZVtNQVhfUEFUSF0sIHN0cmluZ1tNQVhfUEFUSF07CgogICAgc3RyY3B5KHN0cmluZywgIkNMU0lEXFwiKTsKICAgIFNITFdBUElfMjMocmVmaWlkLCBzdHJpbmcgKyA2LCBzaXplb2Yoc3RyaW5nKS9zaXplb2YoY2hhcikgLSA2KTsKICAgIHN0cmNhdChzdHJpbmcsICJcXEluUHJvY1NlcnZlcjMyIik7CgogICAgY291bnQgPSBNQVhfUEFUSDsKICAgIFJlZ09wZW5LZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIHN0cmluZywgMCwgMSwgJm5ld2tleSk7CiAgICBSZWdRdWVyeVZhbHVlRXhBKG5ld2tleSwgMCwgMCwgJnR5cGUsIChQQllURSl2YWx1ZSwgJmNvdW50KTsKICAgIFJlZ0Nsb3NlS2V5KG5ld2tleSk7CiAgICByZXR1cm4gTG9hZExpYnJhcnlFeEEodmFsdWUsIDAsIDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM3XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hMV0FQSV8xODMuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8yMzcgKFdORENMQVNTVyAqIGxwV25kQ2xhc3MpCnsKCVdORENMQVNTVyBXbmRDbGFzczsKCglUUkFDRSgiKCVwICVzKVxuIixscFduZENsYXNzLT5oSW5zdGFuY2UsIGRlYnVnc3RyX3cobHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSkpOwoKCWlmIChHZXRDbGFzc0luZm9XKGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgbHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSwgJlduZENsYXNzKSkKCQlyZXR1cm4gVFJVRTsKCXJldHVybiBSZWdpc3RlckNsYXNzVyhscFduZENsYXNzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSExXQVBJXzIzOAlbU0hMV0FQSS4yMzhdCiAqCiAqIFVucmVnaXN0ZXIgYSBsaXN0IG9mIGNsYXNzZXMuCiAqCiAqIFBBUkFNUwogKiAgaEluc3QgICAgICBbSV0gQXBwbGljYXRpb24gaW5zdGFuY2UgdGhhdCByZWdpc3RlcmVkIHRoZSBjbGFzc2VzCiAqICBscHBDbGFzc2VzIFtJXSBMaXN0IG9mIGNsYXNzIG5hbWVzCiAqICBpQ291bnQgICAgIFtJXSBOdW1iZXIgb2YgbmFtZXMgaW4gbHBwQ2xhc3NlcwogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8Kdm9pZCBXSU5BUEkgU0hMV0FQSV8yMzgoSElOU1RBTkNFIGhJbnN0LCBMUENTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU0EgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb0EoaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NBKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hMV0FQSV8yMzkJW1NITFdBUEkuMjM5XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hMV0FQSV8yMzguCiAqLwp2b2lkIFdJTkFQSSBTSExXQVBJXzIzOShISU5TVEFOQ0UgaEluc3QsIExQQ1dTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU1cgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb1coaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NXKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNDBdCiAqCiAqIENhbGwgVGhlIGNvcnJlY3QgKEFzY2lpL1VuaWNvZGUpIGRlZmF1bHQgd2luZG93IHByb2NlZHVyZSBmb3IgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIFdpbmRvdyB0byBjYWxsIHRoZSBkZWZhdWx0IHByb2NlZHVyZSBmb3IKICogIHVNZXNzYWdlIFtJXSBNZXNzYWdlIElECiAqICB3UGFyYW0gICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgIFtJXSBMUEFSQU0gb2YgbWVzc2FnZQogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIGNhbGxpbmcgRGVmV2luZG93UHJvY0EoKSBvciBEZWZXaW5kb3dQcm9jVygpLgogKi8KTFJFU1VMVCBDQUxMQkFDSyBTSExXQVBJXzI0MChIV05EIGhXbmQsIFVJTlQgdU1lc3NhZ2UsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKCWlmIChJc1dpbmRvd1VuaWNvZGUoaFduZCkpCgkJcmV0dXJuIERlZldpbmRvd1Byb2NXKGhXbmQsIHVNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0MV0KICoKICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzI0MSAoKQp7CglGSVhNRSgiKClzdHViXG4iKTsKCXJldHVybiAvKiAweGFiYmExMjQzICovIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNTddCiAqCiAqIENyZWF0ZSBhIHdvcmtlciB3aW5kb3cgdXNpbmcgQ3JlYXRlV2luZG93RXhBKCkuCiAqCiAqIFBBUkFNUwogKiAgd25kUHJvYyAgICBbSV0gV2luZG93IHByb2NlZHVyZQogKiAgaFduZFBhcmVudCBbSV0gUGFyZW50IHdpbmRvdwogKiAgZHdFeFN0eWxlICBbSV0gRXh0cmEgc3R5bGUgZmxhZ3MKICogIGR3U3R5bGUgICAgW0ldIFN0eWxlIGZsYWdzCiAqICBoTWVudSAgICAgIFtJXSBXaW5kb3cgbWVudQogKiAgeiAgICAgICAgICBbSV0gVW5rbm93bgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgd2luZG93IGhhbmRsZSBvZiB0aGUgbmV3bHkgY3JlYXRlZCB3aW5kb3cuCiAqICBGYWlsdXJlOiAwLgogKi8KSFdORCBXSU5BUEkgU0hMV0FQSV8yNTcoTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBjaGFyKiBzekNsYXNzID0gIldvcmtlckEiOwogIFdORENMQVNTQSB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDhseCwlcCwweCUwOGx4LDB4JTA4bHgsJXAsMHglMDhseClcbiIsCiAgICAgICAgIHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NBOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gKEhJQ09OKTA7CiAgd2MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JBKChISU5TVEFOQ0UpMCwgSURDX0FSUk9XQSk7CiAgd2MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpQ09MT1JfQlROU0hBRE9XOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSExXQVBJXzE4Mygmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeEEoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nQShoV25kLCBEV0xfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1dORFBST0MsIHduZFByb2MpOwogIH0KICByZXR1cm4gaFduZDsKfQoKdHlwZWRlZiBzdHJ1Y3QgdGFnUE9MSUNZREFUQQp7CiAgRFdPUkQgcG9saWN5OyAgICAgICAgLyogZmxhZ3MgdmFsdWUgcGFzc2VkIHRvIFNIUmVzdHJpY3RlZCAqLwogIExQQ1dTVFIgYXBwc3RyOyAgICAgIC8qIGFwcGxpY2F0aW9uIHN0ciBzdWNoIGFzICJFeHBsb3JlciIgKi8KICBMUENXU1RSIGtleXN0cjsgICAgICAvKiBuYW1lIG9mIHRoZSBhY3R1YWwgcmVnaXN0cnkga2V5IC8gcG9saWN5ICovCn0gUE9MSUNZREFUQSwgKkxQUE9MSUNZREFUQTsKCiNkZWZpbmUgU0hFTExfTk9fUE9MSUNZIDB4ZmZmZmZmZmYKCi8qIGRlZmF1bHQgc2hlbGwgcG9saWN5IHJlZ2lzdHJ5IGtleSAqLwpzdGF0aWMgV0NIQVIgc3RyUmVnaXN0cnlQb2xpY3lXW10gPSB7J1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLCdNJywnaScsJ2MnLCdyJywnbycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXFwnLCdQJywnbycsJ2wnLCdpJywnYycsJ2knLCdlJywncycsMH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgICBbU0hMV0FQSS4yNzFdCiAqCiAqIFJldHJpZXZlIGEgcG9saWN5IHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LgogKgogKiBQQVJBTVMKICogIGxwU3ViS2V5ICAgW0ldICAgcmVnaXN0cnkga2V5IG5hbWUKICogIGxwU3ViTmFtZSAgW0ldICAgc3VibmFtZSBvZiByZWdpc3RyeSBrZXkKICogIGxwVmFsdWUgICAgW0ldICAgdmFsdWUgbmFtZSBvZiByZWdpc3RyeSB2YWx1ZQogKgogKiBSRVRVUk5TCiAqICB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeSBrZXkgb3IgMCBpZiBub3QgZm91bmQKICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzI3MShMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwU3ViTmFtZSwgTFBDV1NUUiBscFZhbHVlKQp7CglEV09SRCByZXR2YWwsIGRhdHNpemUgPSA0OwoJSEtFWSBoS2V5OwoKCWlmICghbHBTdWJLZXkpCgkgIGxwU3ViS2V5ID0gKExQQ1dTVFIpc3RyUmVnaXN0cnlQb2xpY3lXOwoJCglyZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGxwU3ViS2V5LCAmaEtleSk7CiAgICBpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBscFN1YktleSwgJmhLZXkpOwoJaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR1cm4gMDsKCglTSEdldFZhbHVlVyhoS2V5LCBscFN1Yk5hbWUsIGxwVmFsdWUsIE5VTEwsIChMUEJZVEUpJnJldHZhbCwgJmRhdHNpemUpOwoJUmVnQ2xvc2VLZXkoaEtleSk7CglyZXR1cm4gcmV0dmFsOyAgCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjY2XQogKgogKiBIZWxwZXIgZnVuY3Rpb24gdG8gcmV0cmlldmUgdGhlIHBvc3NpYmx5IGNhY2hlZCB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBwb2xpY3kKICoKICogUEFSQU1TCiAqICBwb2xpY3kgICAgIFtJXSAgIFRoZSBwb2xpY3kgdG8gbG9vayBmb3IKICogIGluaXRpYWwgICAgW0ldICAgTWFpbiByZWdpc3RyeSBrZXkgdG8gb3BlbiwgaWYgTlVMTCB1c2UgZGVmYXVsdAogKiAgcG9sVGFibGUgICBbSV0gICBUYWJsZSBvZiBrbm93biBwb2xpY2llcywgMCB0ZXJtaW5hdGVkCiAqICBwb2xBcnIgICAgIFtJXSAgIENhY2hlIGFycmF5IG9mIHBvbGljeSB2YWx1ZXMKICoKICogUkVUVVJOUwogKiAgVGhlIHJldHJpZXZlZCBwb2xpY3kgdmFsdWUgb3IgMCBpZiBub3Qgc3VjY2Vzc2Z1bAogKgogKiBOT1RFUwogKiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJ5IHRoZSBuYXRpdmUgU0hSZXN0cmljdGVkIGZ1bmN0aW9uIHRvIHNlYXJjaCBmb3IgdGhlCiAqICBwb2xpY3kgYW5kIGNhY2hlIGl0IG9uY2UgcmV0cmlldmVkLiBUaGUgY3VycmVudCBXaW5lIGltcGxlbWVudGF0aW9uIHVzZXMgYQogKiAgZGlmZmVyZW50IFBPTElDWURBVEEgc3RydWN0dXJlIGFuZCBpbXBsZW1lbnRzIGEgc2ltaWxhciBhbGdvcml0aG1lIGFkYXB0ZWQgdG8KICogIHRoYXQgc3RydWN0dXJlLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMjY2ICgKCURXT1JEIHBvbGljeSwKCUxQQ1dTVFIgaW5pdGlhbCwKCUxQUE9MSUNZREFUQSBwb2xUYWJsZSwKCUxQRFdPUkQgcG9sQXJyKQp7CglUUkFDRSgiKDB4JTA4bHggJXMgJXAgJXApXG4iLCBwb2xpY3ksIGRlYnVnc3RyX3coaW5pdGlhbCksIHBvbFRhYmxlLCBwb2xBcnIpOwoKCWlmICghcG9sVGFibGUgfHwgIXBvbEFycikKCSAgcmV0dXJuIDA7CgoJZm9yICg7cG9sVGFibGUtPnBvbGljeTsgcG9sVGFibGUrKywgcG9sQXJyKyspCgl7CgkgIGlmIChwb2xpY3kgPT0gcG9sVGFibGUtPnBvbGljeSkKCSAgewoJICAgIC8qIHdlIGhhdmUgYSBrbm93biBwb2xpY3kgKi8KCgkgICAgLyogY2hlY2sgaWYgdGhpcyBwb2xpY3kgaGFzIGJlZW4gY2FjaGVkICovCgkJaWYgKCpwb2xBcnIgPT0gU0hFTExfTk9fUE9MSUNZKQoJICAgICAgKnBvbEFyciA9IFNITFdBUElfMjcxKGluaXRpYWwsIHBvbFRhYmxlLT5hcHBzdHIsIHBvbFRhYmxlLT5rZXlzdHIpOwoJICAgIHJldHVybiAqcG9sQXJyOwoJICB9Cgl9CgkvKiB3ZSBkb24ndCBrbm93IHRoaXMgcG9saWN5LCByZXR1cm4gMCAqLwoJVFJBQ0UoInVua25vd24gcG9saWN5OiAoJTA4bHgpXG4iLCBwb2xpY3kpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjddCiAqCiAqIEdldCBhbiBpbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIHBwdiBjb250YWlucyB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogICBUaGlzIFF1ZXJ5SW50ZXJmYWNlIGFza3MgdGhlIGlubmVyIG9iamVjdCBmb3IgYSBpbnRlcmZhY2UuIEluIGNhc2UKICogICBvZiBhZ2dyZWdhdGlvbiB0aGlzIHJlcXVlc3Qgd291bGQgYmUgZm9yd2FyZGVkIGJ5IHRoZSBpbm5lciB0byB0aGUKICogICBvdXRlciBvYmplY3QuIFRoaXMgZnVuY3Rpb24gYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGRpcmVjdGx5IGZvciB0aGUKICogICBpbnRlcmZhY2UgY2lyY3VtdmVudGluZyB0aGUgZm9yd2FyZGluZyB0byB0aGUgb3V0ZXIgb2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8yNjcgKAoJSVVua25vd24gKiBwVW5rLCAgIC8qIFtpbl0gT3V0ZXIgb2JqZWN0ICovCglJVW5rbm93biAqIHBJbm5lciwgLyogW2luXSBJbm5lciBvYmplY3QgKi8KCUlJRCAqIHJpaWQsIC8qIFtpbl0gSW50ZXJmYWNlIEdVSUQgdG8gcXVlcnkgZm9yICovCglMUFZPSUQqIHBwdikgLyogW291dF0gRGVzdGluYXRpb24gZm9yIHF1ZXJpZWQgaW50ZXJmYWNlICovCnsKCUhSRVNVTFQgaHJldCA9IEVfTk9JTlRFUkZBQ0U7CglUUkFDRSgiKHBVbms9JXAgcElubmVyPSVwXG5cdElJRDogICVzICVwKVxuIixwVW5rLHBJbm5lcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKCSpwcHYgPSBOVUxMOwoJaWYocFVuayAmJiBwSW5uZXIpIHsKCSAgICBocmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElubmVyLCByaWlkLCAoTFBWT0lEKilwcHYpOwoJICAgIGlmIChTVUNDRUVERUQoaHJldCkpIElVbmtub3duX1JlbGVhc2UocFVuayk7Cgl9CglUUkFDRSgiLS0gMHglMDhseFxuIiwgaHJldCk7CglyZXR1cm4gaHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2OF0KICoKICogTW92ZSBhIHJlZmVyZW5jZSBmcm9tIG9uZSBpbnRlcmZhY2UgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqICAgbHBEZXN0ICAgICBbT10gRGVzdGluYXRpb24gdG8gcmVjZWl2ZSB0aGUgcmVmZXJlbmNlCiAqICAgbHBwVW5rbm93biBbT10gU291cmNlIHRvIGdpdmUgdXAgdGhlIHJlZmVyZW5jZSB0byBscERlc3QKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovClZPSUQgV0lOQVBJIFNITFdBUElfMjY4KElVbmtub3duICpscERlc3QsIElVbmtub3duICoqbHBwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscERlc3QsIGxwcFVua25vd24pOwoKICBpZiAoKmxwcFVua25vd24pCiAgewogICAgLyogQ29weSBSZWZlcmVuY2UqLwogICAgSVVua25vd25fQWRkUmVmKGxwRGVzdCk7CiAgICBTSExXQVBJXzE2OShscHBVbmtub3duKTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjldCiAqCiAqIENvbnZlcnQgYW4gQVNDSUkgc3RyaW5nIG9mIGEgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyIFtJXSBTdHJpbmcgcmVwcmVzZW50aW5nIGEgQ0xTSUQgaW4gcmVnaXN0cnkgZm9ybWF0CiAqICBpZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjb252ZXJ0ZWQgQ0xTSUQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gaWQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCBDTFNJRC4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8yNjkoTFBDU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICBXQ0hBUiB3Q2xzaWRbNDBdOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBpZHN0ciwgLTEsIHdDbHNpZCwgc2l6ZW9mKHdDbHNpZCkvc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIFNVQ0NFRURFRChTSExXQVBJXzQzNih3Q2xzaWQsIGlkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzBdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzI2OS4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjcwKExQQ1dTVFIgaWRzdHIsIENMU0lEICppZCkKewogIHJldHVybiBTVUNDRUVERUQoU0hMV0FQSV80MzYoaWRzdHIsIGlkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzZdCiAqCiAqIERldGVybWluZSBpZiB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkIGludG8gdGhlIHNoZWxsLCBhbmQgc2V0IGEgcmVnaXN0cnkKICoga2V5IGFjY29yZGluZ2x5LgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIDEsIElmIHRoZSBicm93c2VyIGlzIG5vdCBpbnRlZ3JhdGVkLgogKiAgMiwgSWYgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZC4KICoKICogTk9URVMKICogIFRoZSBrZXkgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVncmF0ZWRCcm93c2VyIiBpcwogKiAgZWl0aGVyIHNldCB0byBUUlVFLCBvciByZW1vdmVkIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBicm93c2VyIGlzIGRlZW1lZAogKiAgdG8gYmUgaW50ZWdyYXRlZC4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzI3NigpCnsKICBzdGF0aWMgTFBDU1RSIHN6SW50ZWdyYXRlZEJyb3dzZXIgPSAiSW50ZWdyYXRlZEJyb3dzZXIiOwogIHN0YXRpYyBEV09SRCBkd1N0YXRlID0gMDsKICBIS0VZIGhLZXk7CiAgRFdPUkQgZHdSZXQsIGR3RGF0YSwgZHdTaXplOwoKICBpZiAoZHdTdGF0ZSkKICAgIHJldHVybiBkd1N0YXRlOwoKICAvKiBJZiBzaGVsbDMyIGV4cG9ydHMgRGxsR2V0VmVyc2lvbigpLCB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkICovCiAgR0VUX0ZVTkMocERsbEdldFZlcnNpb24sIHNoZWxsMzIsICJEbGxHZXRWZXJzaW9uIiwgMSk7CiAgZHdTdGF0ZSA9IHBEbGxHZXRWZXJzaW9uID8gMiA6IDE7CgogIC8qIFNldCBvciBkZWxldGUgdGhlIGtleSBhY2NvcmRpbmx5ICovCiAgZHdSZXQgPSBSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwKICAgICAgICAgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXEludGVybmV0IEV4cGxvcmVyIiwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9BTExfQUNDRVNTLCAmaEtleSk7CiAgaWYgKCFkd1JldCkKICB7CiAgICBkd1JldCA9IFJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsICZkd1NpemUpOwoKICAgIGlmICghZHdSZXQgJiYgZHdTdGF0ZSA9PSAxKQogICAgewogICAgICAvKiBWYWx1ZSBleGlzdHMgYnV0IGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQgKi8KICAgICAgUmVnRGVsZXRlVmFsdWVBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIpOwogICAgfQogICAgZWxzZSBpZiAoZHdSZXQgJiYgZHdTdGF0ZSA9PSAyKQogICAgewogICAgICAvKiBCcm93c2VyIGlzIGludGVncmF0ZWQgYnV0IHZhbHVlIGRvZXMgbm90IGV4aXN0ICovCiAgICAgIGR3RGF0YSA9IFRSVUU7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgKExQQllURSkmZHdEYXRhLCBzaXplb2YoZHdEYXRhKSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoS2V5KTsKICB9CiAgcmV0dXJuIGR3U3RhdGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzhdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzI1Ny4KICovCkhXTkQgV0lOQVBJIFNITFdBUElfMjc4KExPTkcgd25kUHJvYywgSFdORCBoV25kUGFyZW50LCBEV09SRCBkd0V4U3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3R5bGUsIEhNRU5VIGhNZW51LCBMT05HIHopCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDbGFzc1tdID0geyAnVycsICdvJywgJ3InLCAnaycsICdlJywgJ3InLCAnVycsICdcMCcgfTsKICBXTkRDTEFTU1cgd2M7CiAgSFdORCBoV25kOwoKICBUUkFDRSgiKDB4JTA4bHgsJXAsMHglMDhseCwweCUwOGx4LCVwLDB4JTA4bHgpXG4iLAogICAgICAgICB3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogSWYgb3VyIE9TIGlzIG5hdGl2ZWx5IEFTQ0lJLCB1c2UgdGhlIEFTQ0lJIHZlcnNpb24gKi8KICBpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgIC8qIE5UICovCiAgICByZXR1cm4gU0hMV0FQSV8yNTcod25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIENyZWF0ZSBXaW5kb3cgY2xhc3MgKi8KICB3Yy5zdHlsZSAgICAgICAgID0gMDsKICB3Yy5scGZuV25kUHJvYyAgID0gRGVmV2luZG93UHJvY1c7CiAgd2MuY2JDbHNFeHRyYSAgICA9IDA7CiAgd2MuY2JXbmRFeHRyYSAgICA9IDQ7CiAgd2MuaEluc3RhbmNlICAgICA9IHNobHdhcGlfaEluc3RhbmNlOwogIHdjLmhJY29uICAgICAgICAgPSAoSElDT04pMDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoKEhJTlNUQU5DRSkwLCBJRENfQVJST1dBKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSClDT0xPUl9CVE5TSEFET1c7CiAgd2MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgd2MubHBzekNsYXNzTmFtZSA9IHN6Q2xhc3M7CgogIFNITFdBUElfMjM3KCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4Vyhkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIERXTF9NU0dSRVNVTFQsIHopOwoKICAgIGlmICh3bmRQcm9jKQogICAgICBTZXRXaW5kb3dMb25nQShoV25kLCBHV0xfV05EUFJPQywgd25kUHJvYyk7CiAgfQogIHJldHVybiBoV25kOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc5XQogKgogKiBHZXQgYW5kIHNob3cgYSBjb250ZXh0IG1lbnUgZnJvbSBhIHNoZWxsIGZvbGRlci4KICoKICogUEFSQU1TCiAqICBoV25kICAgICAgICAgICBbSV0gV2luZG93IGRpc3BsYXlpbmcgdGhlIHNoZWxsIGZvbGRlcgogKiAgbHBGb2xkZXIgICAgICAgW0ldIElTaGVsbEZvbGRlciBpbnRlcmZhY2UKICogIGxwQXBpZGwgICAgICAgIFtJXSBJZCBmb3IgdGhlIHBhcnRpY3VsYXIgZm9sZGVyIGRlc2lyZWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICovCkhSRVNVTFQgV0lOQVBJIFNITFdBUElfMjc5KEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsKQp7CiAgcmV0dXJuIFNITFdBUElfMzYzKGhXbmQsIGxwRm9sZGVyLCBscEFwaWRsLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODFdCiAqCiAqIF9TSFBhY2tEaXNwUGFyYW1zVgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8yODEoTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKCUZJWE1FKCIlcCAlcCAlcCAlcFxuIix3LHgseSx6KTsKCXJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4yODJdCiAqCiAqIFRoaXMgZnVuY3Rpb24gc2VlbXMgdG8gYmUgYSBmb3J3YXJkIHRvIFNITFdBUEkuMjgxICh3aGF0ZXZlciBUSEFUCiAqIGZ1bmN0aW9uIGRvZXMuLi4pLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8yODIoTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKICBGSVhNRSgiJXAgJXAgJXAgJXBcbiIsIHcsIHgsIHksIHopOwogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODRdCiAqCiAqIF9JQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZQogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMjg0ICgKCUxQVk9JRCB4LAoJTFBWT0lEIHksCglMUFZPSUQgeikKewogICAgICAgIFRSQUNFKCIoJXAgJXAgJXApIHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hMV0FQSV8yODUJW1NITFdBUEkuMjg1XQogKgogKiBOb3RpZnkgYW4gSUNvbm5lY3Rpb25Qb2ludCBvYmplY3Qgb2YgY2hhbmdlcy4KICoKICogUEFSQU1TCiAqICBscENQICAgW0ldIE9iamVjdCB0byBub3RpZnkKICogIGRpc3BJRCBbSV0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UsIGlmIGxwQ1AgaXMgTlVMTCBvciBkb2VzIG5vdCBzdXBwb3J0IHRoZQogKiAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzI4NShJQ29ubmVjdGlvblBvaW50KiBscENQLCBESVNQSUQgZGlzcElEKQp7CiAgSUVudW1Db25uZWN0aW9ucyAqbHBFbnVtOwogIEhSRVNVTFQgaFJldCA9IEVfTk9JTlRFUkZBQ0U7CgogIFRSQUNFKCIoJXAsMHglOGxYKVxuIiwgbHBDUCwgZGlzcElEKTsKCiAgLyogR2V0IGFuIGVudW1lcmF0b3IgZm9yIHRoZSBjb25uZWN0aW9ucyAqLwogIGlmIChscENQKQogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfRW51bUNvbm5lY3Rpb25zKGxwQ1AsICZscEVudW0pOwoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIElQcm9wZXJ0eU5vdGlmeVNpbmsgKmxwU2luazsKICAgIENPTk5FQ1REQVRBIGNvbm5EYXRhOwogICAgVUxPTkcgdWxGZXRjaGVkOwoKICAgIC8qIENhbGwgT25DaGFuZ2VkKCkgZm9yIGV2ZXJ5IG5vdGlmeSBzaW5rIGluIHRoZSBjb25uZWN0aW9uIHBvaW50ICovCiAgICB3aGlsZSAoSUVudW1Db25uZWN0aW9uc19OZXh0KGxwRW51bSwgMSwgJmNvbm5EYXRhLCAmdWxGZXRjaGVkKSA9PSBTX09LKQogICAgewogICAgICBpZiAoU1VDQ0VFREVEKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGNvbm5EYXRhLnBVbmssICZJSURfSVByb3BlcnR5Tm90aWZ5U2luaywgKHZvaWQqKikmbHBTaW5rKSkgJiYKICAgICAgICAgIGxwU2luaykKICAgICAgewogICAgICAgIElQcm9wZXJ0eU5vdGlmeVNpbmtfT25DaGFuZ2VkKGxwU2luaywgZGlzcElEKTsKICAgICAgICBJUHJvcGVydHlOb3RpZnlTaW5rX1JlbGVhc2UobHBTaW5rKTsKICAgICAgfQogICAgICBJVW5rbm93bl9SZWxlYXNlKGNvbm5EYXRhLnBVbmspOwogICAgfQoKICAgIElFbnVtQ29ubmVjdGlvbnNfUmVsZWFzZShscEVudW0pOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSExXQVBJXzI4NwlbU0hMV0FQSS4yODddCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEICAgIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGlzIE5VTEwgb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUKICogICAgICAgICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8yODcoSVVua25vd24gKmxwVW5rbm93biwgRElTUElEIGRpc3BJRCkKewogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ1BDID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX05PSU5URVJGQUNFOwoKICBUUkFDRSgiKCVwLDB4JThsWClcbiIsIGxwVW5rbm93biwgZGlzcElEKTsKCiAgaWYgKGxwVW5rbm93bikKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwgKHZvaWQqKikmbHBDUEMpOwoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIElDb25uZWN0aW9uUG9pbnQqIGxwQ1A7CgogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENQQywgJklJRF9JUHJvcGVydHlOb3RpZnlTaW5rLCAmbHBDUCk7CiAgICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX1JlbGVhc2UobHBDUEMpOwoKICAgIGhSZXQgPSBTSExXQVBJXzI4NShscENQLCBkaXNwSUQpOwogICAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGxwQ1ApOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4OV0KICoKICogU2VlIFBsYXlTb3VuZFcuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzI4OShMUENXU1RSIHBzelNvdW5kLCBITU9EVUxFIGhtb2QsIERXT1JEIGZkd1NvdW5kKQp7CiAgR0VUX0ZVTkMocFBsYXlTb3VuZFcsIHdpbm1tLCAiUGxheVNvdW5kVyIsIEZBTFNFKTsKICByZXR1cm4gcFBsYXlTb3VuZFcocHN6U291bmQsIGhtb2QsIGZkd1NvdW5kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NF0KICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjk0KExQU1RSIHN0cjEsIExQU1RSIHN0cjIsIExQU1RSIHBTdHIsIERXT1JEIHNvbWVfbGVuLCAgTFBDU1RSIGxwU3RyMikKewogICAgLyoKICAgICAqIHN0cjE6CQkiSSIJIkkiCXB1c2hsIGVzcCsweDIwCiAgICAgKiBzdHIyOgkJIlUiCSJJIglwdXNobCAweDc3YzkzODEwCiAgICAgKiAoaXMgIkkiIGFuZCAiVSIgImludGVnZXIiIGFuZCAidW5zaWduZWQiID8/KQogICAgICoKICAgICAqIHBTdHI6CQkiIgkiIglwdXNobCBlYXgKICAgICAqIHNvbWVfbGVuOgkweDgyNAkweDEwNAlwdXNobCAweDgyNAogICAgICogbHBTdHIyOgkJIiVsIgkiJWwiCXB1c2hsIGVzcCsweGMKICAgICAqCiAgICAgKiBzaGx3YXBpLiBTdHJDcHlOVyhscFN0cjIsIGlycmVsZXZhbnRfdmFyLCAweDEwNCk7CiAgICAgKiBMb2NhbEFsbG9jKDB4MDAsIHNvbWVfbGVuKSAtPiBpcnJlbGV2YW50X3ZhcgogICAgICogTG9jYWxBbGxvYygweDQwLCBpcnJlbGV2YW50X2xlbikgLT4gcFN0cgogICAgICogc2hsd2FwaS4yOTQoc3RyMSwgc3RyMiwgcFN0ciwgc29tZV9sZW4sIGxwU3RyMik7CiAgICAgKiBzaGx3YXBpLlBhdGhSZW1vdmVCbGFua3NXKHBTdHIpOwogICAgICovCiAgICBGSVhNRSgiKCclcycsICclcycsICclcycsICUwOGx4LCAnJXMnKTogc3R1YiFcbiIsIHN0cjEsIHN0cjIsIHBTdHIsIHNvbWVfbGVuLCBscFN0cjIpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTVdCiAqCiAqIENhbGxlZCBieSBJQ1EyMDAwYiBpbnN0YWxsIHZpYSBTSERPQ1ZXOgogKiBzdHIxOiAiSW50ZXJuZXRTaG9ydGN1dCIKICogeDogc29tZSB1bmtub3duIHBvaW50ZXIKICogc3RyMjogImh0dHA6Ly9mcmVlLmFvbC5jb20vdHJ5YW9sZnJlZS9pbmRleC5hZHA/MTM5MjY5IgogKiBzdHIzOiAiQzpcXFdJTkRPV1NcXERlc2t0b3AubmV3MlxcRnJlZSBBT0wgJiBVbmxpbWl0ZWQgSW50ZXJuZXQudXJsIgogKgogKiBJbiBzaG9ydDogdGhpcyBvbmUgbWF5YmUgY3JlYXRlcyBhIGRlc2t0b3AgbGluayA6LSkKICovCkJPT0wgV0lOQVBJIFNITFdBUElfMjk1KExQV1NUUiBzdHIxLCBMUFZPSUQgeCwgTFBXU1RSIHN0cjIsIExQV1NUUiBzdHIzKQp7CiAgICBGSVhNRSgiKCclcycsICVwLCAnJXMnLCAnJXMnKSwgc3R1Yi5cbiIsIGRlYnVnc3RyX3coc3RyMSksIHgsIGRlYnVnc3RyX3coc3RyMiksIGRlYnVnc3RyX3coc3RyMykpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTldCiAqCiAqIFNlZSBDT01DVEwzMl80MTcuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzI5OShIREMgaGRjLCBJTlQgeCwgSU5UIHksIFVJTlQgZmxhZ3MsIGNvbnN0IFJFQ1QgKmxwcmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgc3RyLCBVSU5UIGNvdW50LCBjb25zdCBJTlQgKmxwRHgpCnsKICAgIEdFVF9GVU5DKHBDT01DVEwzMl80MTcsIGNvbWN0bDMyLCAoTFBDU1RSKTQxNywgRkFMU0UpOwogICAgcmV0dXJuIHBDT01DVEwzMl80MTcoaGRjLCB4LCB5LCBmbGFncywgbHByZWN0LCBzdHIsIGNvdW50LCBscER4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxM10KICoKICogU2VlIFNIR2V0RmlsZUluZm9XLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMzEzKExQQ1dTVFIgcGF0aCwgRFdPUkQgZHdGaWxlQXR0cmlidXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgIFNIRklMRUlORk9XICpwc2ZpLCBVSU5UIHNpemVvZnBzZmksIFVJTlQgZmxhZ3MpCnsKICBHRVRfRlVOQyhwU0hHZXRGaWxlSW5mb1csIHNoZWxsMzIsICJTSEdldEZpbGVJbmZvVyIsIDApOwogIHJldHVybiBwU0hHZXRGaWxlSW5mb1cocGF0aCwgZHdGaWxlQXR0cmlidXRlcywgcHNmaSwgc2l6ZW9mcHNmaSwgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzE4XQogKgogKiBTZWUgRHJhZ1F1ZXJ5RmlsZVcuCiAqLwpVSU5UIFdJTkFQSSBTSExXQVBJXzMxOChIRFJPUCBoRHJvcCwgVUlOVCBsRmlsZSwgTFBXU1RSIGxwc3pGaWxlLCBVSU5UIGxMZW5ndGgpCnsKICBHRVRfRlVOQyhwRHJhZ1F1ZXJ5RmlsZVcsIHNoZWxsMzIsICJEcmFnUXVlcnlGaWxlVyIsIDApOwogIHJldHVybiBwRHJhZ1F1ZXJ5RmlsZVcoaERyb3AsIGxGaWxlLCBscHN6RmlsZSwgbExlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzNdCiAqCiAqIFNlZSBTSEJyb3dzZUZvckZvbGRlclcuCiAqLwpMUElURU1JRExJU1QgV0lOQVBJIFNITFdBUElfMzMzKExQQlJPV1NFSU5GT1cgbHBCaSkKewogIEdFVF9GVU5DKHBTSEJyb3dzZUZvckZvbGRlclcsIHNoZWxsMzIsICJTSEJyb3dzZUZvckZvbGRlclciLCBOVUxMKTsKICByZXR1cm4gcFNIQnJvd3NlRm9yRm9sZGVyVyhscEJpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNF0KICoKICogU2VlIFNIR2V0UGF0aEZyb21JRExpc3RXLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zMzQoTFBDSVRFTUlETElTVCBwaWRsLExQV1NUUiBwc3pQYXRoKQp7CiAgR0VUX0ZVTkMocFNIR2V0UGF0aEZyb21JRExpc3RXLCBzaGVsbDMyLCAiU0hHZXRQYXRoRnJvbUlETGlzdFciLCAwKTsKICByZXR1cm4gcFNIR2V0UGF0aEZyb21JRExpc3RXKHBpZGwsIHBzelBhdGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM1XQogKgogKiBTZWUgU2hlbGxFeGVjdXRlRXhXLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zMzUoTFBTSEVMTEVYRUNVVEVJTkZPVyBscEV4ZWNJbmZvKQp7CiAgR0VUX0ZVTkMocFNoZWxsRXhlY3V0ZUV4Vywgc2hlbGwzMiwgIlNoZWxsRXhlY3V0ZUV4VyIsIEZBTFNFKTsKICByZXR1cm4gcFNoZWxsRXhlY3V0ZUV4VyhscEV4ZWNJbmZvKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNl0KICoKICogU2VlIFNIRmlsZU9wZXJhdGlvblcuCiAqLwpISUNPTiBXSU5BUEkgU0hMV0FQSV8zMzYoTFBTSEZJTEVPUFNUUlVDVFcgbHBGaWxlT3ApCnsKICBHRVRfRlVOQyhwU0hGaWxlT3BlcmF0aW9uVywgc2hlbGwzMiwgIlNIRmlsZU9wZXJhdGlvblciLCAwKTsKICByZXR1cm4gcFNIRmlsZU9wZXJhdGlvblcobHBGaWxlT3ApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM3XQogKgogKiBTZWUgRXh0cmFjdEljb25FeFcuCiAqLwpVSU5UIFdJTkFQSSBTSExXQVBJXzMzNyhMUENXU1RSIGxwc3pGaWxlLCBJTlQgbkljb25JbmRleCwgSElDT04gKnBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04gKnBoaWNvblNtYWxsLCBVSU5UIG5JY29ucykKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvbkV4Vywgc2hlbGwzMiwgIkV4dHJhY3RJY29uRXhXIiwgMCk7CiAgcmV0dXJuIHBFeHRyYWN0SWNvbkV4VyhscHN6RmlsZSwgbkljb25JbmRleCwgcGhpY29uTGFyZ2UsIHBoaWNvblNtYWxsLCBuSWNvbnMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzQyXQogKgogKi8KTE9ORyBXSU5BUEkgU0hJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSggUExPTkcgZGVzdCwgTE9ORyB4Y2hnLCBMT05HIGNvbXBhcmUpCnsKICAgICAgICByZXR1cm4gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoZGVzdCwgeGNoZywgY29tcGFyZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNDZdCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8zNDYgKAoJTFBDV1NUUiBzcmMsCglMUFdTVFIgZGVzdCwKCWludCBsZW4pCnsKCUZJWE1FKCIoJXMgJXAgMHglMDh4KXN0dWJcbiIsZGVidWdzdHJfdyhzcmMpLGRlc3QsbGVuKTsKCWxzdHJjcHluVyhkZXN0LCBzcmMsIGxlbik7CglyZXR1cm4gbHN0cmxlblcoZGVzdCkrMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MF0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMzUwICgKCUxQV1NUUiB4LAoJTFBWT0lEIHkpCnsKICAgICAgICBEV09SRCByZXQ7CgoJR0VUX0ZVTkMocEdldEZpbGVWZXJzaW9uSW5mb1NpemVXLCB2ZXJzaW9uLCAiR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVciLCAwKTsKCXJldCA9IHBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyh4LCB5KTsKCXJldHVybiAweDIwOCArIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MV0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1cuCiAqLwpCT09MICBXSU5BUEkgU0hMV0FQSV8zNTEgKAoJTFBXU1RSIHcsICAgLyogW2luXSBwYXRoIHRvIGRsbCAqLwoJRFdPUkQgIHgsICAgLyogW2luXSBwYXJtIDIgdG8gR2V0RmlsZVZlcnNpb25JbmZvQSAqLwoJRFdPUkQgIHksICAgLyogW2luXSByZXR1cm4gdmFsdWUgZnJvbSBTSExXQVBJXzM1MCgpIC0gYXNzdW1lIGxlbmd0aCAqLwoJTFBWT0lEIHopICAgLyogW2luL291dF0gYnVmZmVyICgrMHgyMDggc2VudCB0byBHZXRGaWxlVmVyc2lvbkluZm9BKCkpICovCnsKICAgIEdFVF9GVU5DKHBHZXRGaWxlVmVyc2lvbkluZm9XLCB2ZXJzaW9uLCAiR2V0RmlsZVZlcnNpb25JbmZvVyIsIDApOwogICAgcmV0dXJuIHBHZXRGaWxlVmVyc2lvbkluZm9XKHcsIHgsIHktMHgyMDgsIChjaGFyKil6KzB4MjA4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1Ml0KICoKICogU2VlIFZlclF1ZXJ5VmFsdWVXLgogKi8KV09SRCBXSU5BUEkgU0hMV0FQSV8zNTIgKAoJTFBWT0lEIHcsICAgLyogW2luXSBCdWZmZXIgZnJvbSBTSExXQVBJXzM1MSgpICovCglMUFdTVFIgeCwgICAvKiBbaW5dICAgVmFsdWUgdG8gcmV0cmlldmUgLSBjb252ZXJ0ZWQgYW5kIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSgpIGFzICMyICovCglMUFZPSUQgeSwgICAvKiBbb3V0XSAgVmVyIGJ1ZmZlciAtIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSBhcyAjMyAqLwoJVUlOVCogIHopICAgLyogW2luXSAgIFZlciBsZW5ndGggLSBwYXNzZWQgdG8gVmVyUXVlcnlWYWx1ZUEgYXMgIzQgKi8KewogICAgR0VUX0ZVTkMocFZlclF1ZXJ5VmFsdWVXLCB2ZXJzaW9uLCAiVmVyUXVlcnlWYWx1ZVciLCAwKTsKICAgIHJldHVybiBwVmVyUXVlcnlWYWx1ZVcoKGNoYXIqKXcrMHgyMDgsIHgsIHksIHopOwp9CgojZGVmaW5lIElzSWZhY2UodHlwZSkgU1VDQ0VFREVEKChoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEXyMjdHlwZSwgKHZvaWQqKikmbHBPYmopKSkKI2RlZmluZSBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3NTQgojZGVmaW5lIEVuYWJsZU1vZGVsZXNzKHR5cGUpIHR5cGUjI19FbmFibGVNb2RlbGVzcygodHlwZSopbHBPYmosIGJNb2RlbGVzcykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hMV0FQSV8zNTUJW1NITFdBUEkuMzU1XQogKgogKiBDaGFuZ2UgdGhlIG1vZGFsaXR5IG9mIGEgc2hlbGwgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG1ha2UgbW9kZWxlc3MKICogIGJNb2RlbGVzcyBbSV0gVFJVRT1NYWtlIG1vZGVsZXNzLCBGQUxTRT1NYWtlIG1vZGFsCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIFRoZSBtb2RhbGl0eSBscFVua25vd24gaXMgY2hhbmdlZC4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICoKICogTk9URVMKICogIGxwVW5rbm93biBtdXN0IHN1cHBvcnQgdGhlIElPbGVJblBsYWNlRnJhbWUgaW50ZXJmYWNlLCB0aGUKICogIElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSBpbnRlcmZhY2UsIHRoZSBJU2hlbGxCcm93c2VyIGludGVyZmFjZQogKiAgb3IgdGhlIElEb2NIb3N0VUlIYW5kbGVyIGludGVyZmFjZSwgb3IgdGhpcyBjYWxsIGZhaWxzLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV8zNTUoSVVua25vd24gKmxwVW5rbm93biwgQk9PTCBiTW9kZWxlc3MpCnsKICBJVW5rbm93biAqbHBPYmo7CiAgSFJFU1VMVCBoUmV0OwoKICBUUkFDRSgiKCVwLCVkKVxuIiwgbHBVbmtub3duLCBiTW9kZWxlc3MpOwoKICBpZiAoIWxwVW5rbm93bikKICAgIHJldHVybiBFX0ZBSUw7CgogIGlmIChJc0lmYWNlKElPbGVJblBsYWNlRnJhbWUpKQogICAgRW5hYmxlTW9kZWxlc3MoSU9sZUluUGxhY2VGcmFtZSk7CiAgZWxzZSBpZiAoSXNJZmFjZShJU2hlbGxCcm93c2VyKSkKICAgIEVuYWJsZU1vZGVsZXNzKElTaGVsbEJyb3dzZXIpOwojaWYgMAogIC8qIEZJWE1FOiBXaW5lIGhhcyBubyBoZWFkZXJzIGZvciB0aGVzZSBvYmplY3RzIHlldCAqLwogIGVsc2UgaWYgKElzSWZhY2UoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKSkKICAgIEVuYWJsZU1vZGVsZXNzKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSk7CiAgZWxzZSBpZiAoSXNJZmFjZShJRG9jSG9zdFVJSGFuZGxlcikpCiAgICBFbmFibGVNb2RlbGVzcyhJRG9jSG9zdFVJSGFuZGxlcik7CiNlbmRpZgogIGVsc2UKICAgIHJldHVybiBoUmV0OwoKICBJVW5rbm93bl9SZWxlYXNlKGxwT2JqKTsKICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1N10KICoKICogU2VlIFNIR2V0TmV3TGlua0luZm9XLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zNTcoTFBDV1NUUiBwc3pMaW5rVG8sIExQQ1dTVFIgcHN6RGlyLCBMUFdTVFIgcHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqcGZNdXN0Q29weSwgVUlOVCB1RmxhZ3MpCnsKICBHRVRfRlVOQyhwU0hHZXROZXdMaW5rSW5mb1csIHNoZWxsMzIsICJTSEdldE5ld0xpbmtJbmZvVyIsIEZBTFNFKTsKICByZXR1cm4gcFNIR2V0TmV3TGlua0luZm9XKHBzekxpbmtUbywgcHN6RGlyLCBwc3pOYW1lLCBwZk11c3RDb3B5LCB1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU4XQogKgogKiBTZWUgU0hEZWZFeHRyYWN0SWNvblcuCiAqLwpVSU5UIFdJTkFQSSBTSExXQVBJXzM1OChMUENXU1RSIHBzekljb25GaWxlLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgSElDT04qIHBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04qIHBoaWNvblNtYWxsLCBVSU5UIG5JY29uU2l6ZSkKewogIEdFVF9GVU5DKHBTSERlZkV4dHJhY3RJY29uVywgc2hlbGwzMiwgIlNIRGVmRXh0cmFjdEljb25XIiwgMCk7CiAgcmV0dXJuIHBTSERlZkV4dHJhY3RJY29uVyhwc3pJY29uRmlsZSwgaUluZGV4LCB1RmxhZ3MsIHBoaWNvbkxhcmdlLCBwaGljb25TbWFsbCwgbkljb25TaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM2M10KICoKICogR2V0IGFuZCBzaG93IGEgY29udGV4dCBtZW51IGZyb20gYSBzaGVsbCBmb2xkZXIuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICAgICAgW0ldIFdpbmRvdyBkaXNwbGF5aW5nIHRoZSBzaGVsbCBmb2xkZXIKICogIGxwRm9sZGVyICAgICAgIFtJXSBJU2hlbGxGb2xkZXIgaW50ZXJmYWNlCiAqICBscEFwaWRsICAgICAgICBbSV0gSWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZvbGRlciBkZXNpcmVkCiAqICBiSW52b2tlRGVmYXVsdCBbSV0gV2hldGhlciB0byBpbnZva2UgdGhlIGRlZmF1bHQgbWVudSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIElmIGJJbnZva2VEZWZhdWx0IGlzIFRSVUUsIHRoZSBkZWZhdWx0IG1lbnUgYWN0aW9uIHdhcwogKiAgICAgICAgICAgZXhlY3V0ZWQuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExXQVBJXzM2MyhIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCwgQk9PTCBiSW52b2tlRGVmYXVsdCkKewogIElDb250ZXh0TWVudSAqaUNvbnRleHQ7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVkKVxuIiwgaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIGJJbnZva2VEZWZhdWx0KTsKCiAgaWYgKCFscEZvbGRlcikKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgdGhlIGNvbnRleHQgbWVudSBmcm9tIHRoZSBzaGVsbCBmb2xkZXIgKi8KICBoUmV0ID0gSVNoZWxsRm9sZGVyX0dldFVJT2JqZWN0T2YobHBGb2xkZXIsIGhXbmQsIDEsICZscEFwaWRsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmSUlEX0lDb250ZXh0TWVudSwgMCwgKHZvaWQqKikmaUNvbnRleHQpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSE1FTlUgaE1lbnU7CiAgICBpZiAoKGhNZW51ID0gQ3JlYXRlUG9wdXBNZW51KCkpKQogICAgewogICAgICBIUkVTVUxUIGhRdWVyeTsKICAgICAgRFdPUkQgZHdEZWZhdWx0SWQgPSAwOwoKICAgICAgLyogQWRkIHRoZSBjb250ZXh0IG1lbnUgZW50cmllcyB0byB0aGUgcG9wdXAgKi8KICAgICAgaFF1ZXJ5ID0gSUNvbnRleHRNZW51X1F1ZXJ5Q29udGV4dE1lbnUoaUNvbnRleHQsIGhNZW51LCAwLCAxLCAweDdGRkYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJJbnZva2VEZWZhdWx0ID8gQ01GX05PUk1BTCA6IENNRl9ERUZBVUxUT05MWSk7CgogICAgICBpZiAoU1VDQ0VFREVEKGhRdWVyeSkpCiAgICAgIHsKICAgICAgICBpZiAoYkludm9rZURlZmF1bHQgJiYKICAgICAgICAgICAgKGR3RGVmYXVsdElkID0gR2V0TWVudURlZmF1bHRJdGVtKGhNZW51LCAwLCAwKSkgIT0gMHhGRkZGRkZGRikKICAgICAgICB7CiAgICAgICAgICBDTUlOVk9LRUNPTU1BTkRJTkZPIGNtSWNpOwogICAgICAgICAgLyogSW52b2tlIHRoZSBkZWZhdWx0IGl0ZW0gKi8KICAgICAgICAgIG1lbXNldCgmY21JY2ksMCxzaXplb2YoY21JY2kpKTsKICAgICAgICAgIGNtSWNpLmNiU2l6ZSA9IHNpemVvZihjbUljaSk7CiAgICAgICAgICBjbUljaS5mTWFzayA9IENNSUNfTUFTS19BU1lOQ09LOwogICAgICAgICAgY21JY2kuaHduZCA9IGhXbmQ7CiAgICAgICAgICBjbUljaS5scFZlcmIgPSBNQUtFSU5UUkVTT1VSQ0VBKGR3RGVmYXVsdElkKTsKICAgICAgICAgIGNtSWNpLm5TaG93ID0gU1dfU0NST0xMQ0hJTERSRU47CgogICAgICAgICAgaFJldCA9IElDb250ZXh0TWVudV9JbnZva2VDb21tYW5kKGlDb250ZXh0LCAmY21JY2kpOwogICAgICAgIH0KICAgICAgfQogICAgICBEZXN0cm95TWVudShoTWVudSk7CiAgICB9CiAgICBJQ29udGV4dE1lbnVfUmVsZWFzZShpQ29udGV4dCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzY0XQogKgogKiBDb3B5IG9uZSBzdHJpbmcgdG8gYW5vdGhlciwgdXAgdG8gYSBnaXZlbiBsZW5ndGguCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZyB0byBjb3B5CiAqICBscHN6RHN0IFtPXSBEZXN0aW5hdGlvbiBmb3IgY29waWVkIHN0cmluZwogKiAgaUxlbiAgICBbSV0gTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gY29weQogKgogKiBSRVRVUk5TCiAqICBUUlVFLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMzY0KExQQ1NUUiBscHN6U3JjLCBMUFNUUiBscHN6RHN0LCBJTlQgaUxlbikKewogIGxzdHJjcHluQShscHN6RHN0LCBscHN6U3JjLCBpTGVuKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3MF0KICoKICogU2VlIEV4dHJhY3RJY29uVy4KICovCkhJQ09OIFdJTkFQSSBTSExXQVBJXzM3MChISU5TVEFOQ0UgaEluc3RhbmNlLCBMUENXU1RSIGxwc3pFeGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbkljb25JbmRleCkKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvblcsIHNoZWxsMzIsICJFeHRyYWN0SWNvblciLCBOVUxMKTsKICByZXR1cm4gcEV4dHJhY3RJY29uVyhoSW5zdGFuY2UsIGxwc3pFeGVGaWxlTmFtZSwgbkljb25JbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzZdCiAqLwpMQU5HSUQgV0lOQVBJIFNITFdBUElfMzc2ICgpCnsKICAgIEZJWE1FKCIoKSBzdHViXG4iKTsKICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBhIGZvcndhcmQgaW4gdGhlIC5zcGVjIGZpbGUgdG8gdGhlIHdpbjJrIGZ1bmN0aW9uCiAgICAgKiBrZXJuZWwzMi5HZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2UsIGhvd2V2ZXIgdGhhdCBmdW5jdGlvbiBpc24ndCB0aGVyZSB5ZXQuCiAgICAgKi8KICAgIHJldHVybiBHZXRVc2VyRGVmYXVsdExhbmdJRCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgIFtJXSBMaWJyYXJ5IG5hbWUKICogIGluc3RfaHduZCBbSV0gTW9kdWxlIHdob3NlIGRpcmVjdG9yeSBpcyB0byBiZSB1c2VkCiAqICBkd0ZsYWdzICAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBsb2FkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgbW9kdWxlCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgU0hMV0FQSV8zNzcgKExQQ1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdGbGFncykKewogIC8qIEZJWE1FOiBOYXRpdmUgYXBwZWFycyB0byBkbyBEUEFfQ3JlYXRlIGFuZCBhIERQQV9JbnNlcnRQdHIgZm9yCiAgICogICAgICAgIGVhY2ggY2FsbCBoZXJlLgogICAqIEZJWE1FOiBOYXRpdmUgc2hvd3MgY2FsbHMgdG86CiAgICogIFNIUmVnR2V0VVNWYWx1ZSBmb3IgIlNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlclxJbnRlcm5hdGlvbmFsIgogICAqICAgICAgICAgICAgICAgICAgICAgIENoZWNrVmVyc2lvbgogICAqICBSZWdPcGVuS2V5RXhBIGZvciAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXIiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMUEtJbnN0YWxsZWQiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0NVXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlclxJbnRlcm5hdGlvbmFsIgogICAqICBSZWdRdWVyeVZhbHVlRXhBIGZvciAiUmVzb3VyY2VMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxBY3RpdmUgU2V0dXBcSW5zdGFsbGVkIENvbXBvbmVudHNce2d1aWR9IgogICAqICBSZWdRdWVyeVZhbHVlRXhBIGZvciAiTG9jYWxlIgogICAqICBSZWdDbG9zZUtleQogICAqICBhbmQgdGhlbiB0ZXN0cyB0aGUgTG9jYWxlICgiZW4iIGZvciBtZSkuCiAgICogICAgIGNvZGUgYmVsb3cKICAgKiAgYWZ0ZXIgdGhlIGNvZGUgdGhlbiBhIERQQV9DcmVhdGUgKGZpcnN0IHRpbWUpIGFuZCBEUEFfSW5zZXJ0UHRyIGFyZSBkb25lLgogICAqLwogICAgQ0hBUiBtb2RfcGF0aFsyKk1BWF9QQVRIXTsKICAgIExQU1RSIHB0cjsKCiAgICBGSVhNRSgiKCVzLCVwLDB4JTA4bHgpIHNlbWktc3R1YiFcbiIsIGRlYnVnc3RyX2EobmV3X21vZCksIGluc3RfaHduZCwgZHdGbGFncyk7CiAgICBHZXRNb2R1bGVGaWxlTmFtZUEoaW5zdF9od25kLCBtb2RfcGF0aCwgMipNQVhfUEFUSCk7CiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMzc3CiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV8zNzggKExQQ1dTVFIgbmV3X21vZCwgSE1PRFVMRSBpbnN0X2h3bmQsIERXT1JEIGR3RmxhZ3MpCnsKICAgIFdDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBXU1RSIHB0cjsKCiAgICBGSVhNRSgiKCVzLCVwLDB4JTA4bHgpIHNlbWktc3R1YiFcbiIsIGRlYnVnc3RyX3cobmV3X21vZCksIGluc3RfaHduZCwgZHdGbGFncyk7CiAgICBHZXRNb2R1bGVGaWxlTmFtZVcoaW5zdF9od25kLCBtb2RfcGF0aCwgMipNQVhfUEFUSCk7CiAgICBwdHIgPSBzdHJyY2hyVyhtb2RfcGF0aCwgJ1xcJyk7CiAgICBpZiAocHRyKSB7CglzdHJjcHlXKHB0cisxLCBuZXdfbW9kKTsKCVRSQUNFKCJsb2FkaW5nICVzXG4iLCBkZWJ1Z3N0cl93KG1vZF9wYXRoKSk7CglyZXR1cm4gKERXT1JEKUxvYWRMaWJyYXJ5Vyhtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29sb3JBZGp1c3RMdW1hICAgICAgW1NITFdBUEkuMzg3XQogKgogKiBBZGp1c3QgdGhlIGx1bWlub3NpdHkgb2YgYSBjb2xvcgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gUkdCIHZhbHVlIHRvIGNvbnZlcnQKICogIGR3THVtYSAgICAgICBbSV0gTHVtYSBhZGp1c3RtZW50CiAqICBiVW5rbm93biAgICAgW0ldIFVua25vd24KICoKICogUkVUVVJOUwogKiAgVGhlIGFkanVzdGVkIFJHQiBjb2xvci4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckFkanVzdEx1bWEoQ09MT1JSRUYgY1JHQiwgaW50IGR3THVtYSwgQk9PTCBiVW5rbm93bikKewogIFRSQUNFKCIoMHglOGx4LCVkLCVkKVxuIiwgY1JHQiwgZHdMdW1hLCBiVW5rbm93bik7CgogIGlmIChkd0x1bWEpCiAgewogICAgV09SRCB3SCwgd0wsIHdTOwoKICAgIENvbG9yUkdCVG9ITFMoY1JHQiwgJndILCAmd0wsICZ3Uyk7CgogICAgRklYTUUoIklnbm9yaW5nIGx1bWEgYWRqdXN0bWVudFxuIik7CgogICAgLyogRklYTUU6IFRoZSBhamR1c3RtZW50IGlzIG5vdCBsaW5lYXIgKi8KCiAgICBjUkdCID0gQ29sb3JITFNUb1JHQih3SCwgd0wsIHdTKTsKICB9CiAgcmV0dXJuIGNSR0I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zODldCiAqCiAqIFNlZSBHZXRTYXZlRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgU0hMV0FQSV8zODkoTFBPUEVORklMRU5BTUVXIG9mbikKewogIEdFVF9GVU5DKHBHZXRTYXZlRmlsZU5hbWVXLCBjb21kbGczMiwgIkdldFNhdmVGaWxlTmFtZVciLCBGQUxTRSk7CiAgcmV0dXJuIHBHZXRTYXZlRmlsZU5hbWVXKG9mbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zOTBdCiAqCiAqIFNlZSBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XLgogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfMzkwKEhXTkQgaHduZE93bmVyLCBMUFdTVFIgbHBzekRldmljZSkKewogIEdFVF9GVU5DKHBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XLCBtcHIsICJXTmV0UmVzdG9yZUNvbm5lY3Rpb25XIiwgMCk7CiAgcmV0dXJuIHBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XKGh3bmRPd25lciwgbHBzekRldmljZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zOTFdCiAqCiAqIFNlZSBXTmV0R2V0TGFzdEVycm9yVy4KICovCkRXT1JEIFdJTkFQSSBTSExXQVBJXzM5MShMUERXT1JEIGxwRXJyb3IsIExQV1NUUiBscEVycm9yQnVmLCBEV09SRCBuRXJyb3JCdWZTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwTmFtZUJ1ZiwgRFdPUkQgbk5hbWVCdWZTaXplKQp7CiAgR0VUX0ZVTkMocFdOZXRHZXRMYXN0RXJyb3JXLCBtcHIsICJXTmV0R2V0TGFzdEVycm9yVyIsIDApOwogIHJldHVybiBwV05ldEdldExhc3RFcnJvclcobHBFcnJvciwgbHBFcnJvckJ1ZiwgbkVycm9yQnVmU2l6ZSwgbHBOYW1lQnVmLCBuTmFtZUJ1ZlNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAxXQogKgogKiBTZWUgUGFnZVNldHVwRGxnVy4KICovCkJPT0wgV0lOQVBJIFNITFdBUElfNDAxKExQUEFHRVNFVFVQRExHVyBwYWdlZGxnKQp7CiAgR0VUX0ZVTkMocFBhZ2VTZXR1cERsZ1csIGNvbWRsZzMyLCAiUGFnZVNldHVwRGxnVyIsIEZBTFNFKTsKICByZXR1cm4gcFBhZ2VTZXR1cERsZ1cocGFnZWRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDJdCiAqCiAqIFNlZSBQcmludERsZ1cuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzQwMihMUFBSSU5URExHVyBwcmludGRsZykKewogIEdFVF9GVU5DKHBQcmludERsZ1csIGNvbWRsZzMyLCAiUHJpbnREbGdXIiwgRkFMU0UpOwogIHJldHVybiBwUHJpbnREbGdXKHByaW50ZGxnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwM10KICoKICogU2VlIEdldE9wZW5GaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzQwMyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgR0VUX0ZVTkMocEdldE9wZW5GaWxlTmFtZVcsIGNvbWRsZzMyLCAiR2V0T3BlbkZpbGVOYW1lVyIsIEZBTFNFKTsKICByZXR1cm4gcEdldE9wZW5GaWxlTmFtZVcob2ZuKTsKfQoKLyogSU5URVJOQUw6IE1hcCBmcm9tIEhMUyBjb2xvciBzcGFjZSB0byBSR0IgKi8Kc3RhdGljIFdPUkQgV0lOQVBJIENvbnZlcnRIdWUoaW50IHdIdWUsIFdPUkQgd01pZDEsIFdPUkQgd01pZDIpCnsKICB3SHVlID0gd0h1ZSA+IDI0MCA/IHdIdWUgLSAyNDAgOiB3SHVlIDwgMCA/IHdIdWUgKyAyNDAgOiB3SHVlOwoKICBpZiAod0h1ZSA+IDE2MCkKICAgIHJldHVybiB3TWlkMTsKICBlbHNlIGlmICh3SHVlID4gMTIwKQogICAgd0h1ZSA9IDE2MCAtIHdIdWU7CiAgZWxzZSBpZiAod0h1ZSA+IDQwKQogICAgcmV0dXJuIHdNaWQyOwoKICByZXR1cm4gKCh3SHVlICogKHdNaWQyIC0gd01pZDEpICsgMjApIC8gNDApICsgd01pZDE7Cn0KCi8qIENvbnZlcnQgdG8gUkdCIGFuZCBzY2FsZSBpbnRvIFJHQiByYW5nZSAoMC4uMjU1KSAqLwojZGVmaW5lIEdFVF9SR0IoaCkgKENvbnZlcnRIdWUoaCwgd01pZDEsIHdNaWQyKSAqIDI1NSArIDEyMCkgLyAyNDAKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQ29sb3JITFNUb1JHQglbU0hMV0FQSS40MDRdCiAqCiAqIENvbnZlcnQgZnJvbSBobHMgY29sb3Igc3BhY2UgaW50byBhbiByZ2IgQ09MT1JSRUYuCiAqCiAqIFBBUkFNUwogKiAgd0h1ZSAgICAgICAgW0ldIEh1ZSBhbW91bnQKICogIHdMdW1pbm9zaXR5IFtJXSBMdW1pbm9zaXR5IGFtb3VudAogKiAgd1NhdHVyYXRpb24gW0ldIFNhdHVyYXRpb24gYW1vdW50CiAqCiAqIFJFVFVSTlMKICogIEEgQ09MT1JSRUYgcmVwcmVzZW50aW5nIHRoZSBjb252ZXJ0ZWQgY29sb3IuCiAqCiAqIE5PVEVTCiAqICBJbnB1dCBobHMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JITFNUb1JHQihXT1JEIHdIdWUsIFdPUkQgd0x1bWlub3NpdHksIFdPUkQgd1NhdHVyYXRpb24pCnsKICBXT1JEIHdSZWQ7CgogIGlmICh3U2F0dXJhdGlvbikKICB7CiAgICBXT1JEIHdHcmVlbiwgd0JsdWUsIHdNaWQxLCB3TWlkMjsKCiAgICBpZiAod0x1bWlub3NpdHkgPiAxMjApCiAgICAgIHdNaWQyID0gd1NhdHVyYXRpb24gKyB3THVtaW5vc2l0eSAtICh3U2F0dXJhdGlvbiAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKICAgIGVsc2UKICAgICAgd01pZDIgPSAoKHdTYXR1cmF0aW9uICsgMjQwKSAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKCiAgICB3TWlkMSA9IHdMdW1pbm9zaXR5ICogMiAtIHdNaWQyOwoKICAgIHdSZWQgICA9IEdFVF9SR0Iod0h1ZSArIDgwKTsKICAgIHdHcmVlbiA9IEdFVF9SR0Iod0h1ZSk7CiAgICB3Qmx1ZSAgPSBHRVRfUkdCKHdIdWUgLSA4MCk7CgogICAgcmV0dXJuIFJHQih3UmVkLCB3R3JlZW4sIHdCbHVlKTsKICB9CgogIHdSZWQgPSB3THVtaW5vc2l0eSAqIDI1NSAvIDI0MDsKICByZXR1cm4gUkdCKHdSZWQsIHdSZWQsIHdSZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuNDA2XQogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfNDA2KExQVk9JRCB1LCBMUFZPSUQgdiwgTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKICBGSVhNRSgiJXAgJXAgJXAgJXAgJXAgJXBcbiIsIHUsIHYsIHcsIHgsIHksIHopOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDEzXQogKgogKiBHZXQgdGhlIGN1cnJlbnQgZG9ja2luZyBzdGF0dXMgb2YgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBET0NLSU5GT18gZmxhZ3MgZnJvbSAid2luYmFzZS5oIiwgdW51c2VkCiAqCiAqIFJFVFVSTlMKICogIE9uZSBvZiBET0NLSU5GT19VTkRPQ0tFRCwgRE9DS0lORk9fVU5ET0NLRUQsIG9yIDAgaWYgdGhlIHN5c3RlbSBpcyBub3QKICogIGEgbm90ZWJvb2suCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV80MTMoRFdPUkQgZHdGbGFncykKewogIEhXX1BST0ZJTEVfSU5GT0EgaHdJbmZvOwoKICBUUkFDRSgiKDB4JTA4bHgpXG4iLCBkd0ZsYWdzKTsKCiAgR2V0Q3VycmVudEh3UHJvZmlsZUEoJmh3SW5mbyk7CiAgc3dpdGNoIChod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpKQogIHsKICBjYXNlIERPQ0tJTkZPX0RPQ0tFRDoKICBjYXNlIERPQ0tJTkZPX1VORE9DS0VEOgogICAgcmV0dXJuIGh3SW5mby5kd0RvY2tJbmZvICYgKERPQ0tJTkZPX0RPQ0tFRHxET0NLSU5GT19VTkRPQ0tFRCk7CiAgZGVmYXVsdDoKICAgIHJldHVybiAwOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQxOF0KICoKICogRnVuY3Rpb24gc2VlbXMgdG8gZG8gRnJlZUxpYnJhcnkgcGx1cyBvdGhlciB0aGluZ3MuCiAqCiAqIEZJWE1FIG5hdGl2ZSBzaG93cyB0aGUgZm9sbG93aW5nIGNhbGxzOgogKiAgIFJ0bEVudGVyQ3JpdGljYWxTZWN0aW9uCiAqICAgTG9jYWxGcmVlCiAqICAgR2V0UHJvY0FkZHJlc3MoQ29tY3RsMzI/PywgMTUwTCkKICogICBEUEFfRGVsZXRlUHRyCiAqICAgUnRsTGVhdmVDcml0aWNhbFNlY3Rpb24KICogIGZvbGxvd2VkIGJ5IHRoZSBGcmVlTGlicmFyeS4KICogIFRoZSBhYm92ZSBjb2RlIG1heSBiZSByZWxhdGVkIHRvIC4zNzcgYWJvdmUuCiAqLwpCT09MIFdJTkFQSSBTSExXQVBJXzQxOChITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzBdCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV80MzAoSElOU1RBTkNFIGhJbnN0LCBIQU5ETEUgaEhlYXApCnsKCUZJWE1FKCIoJXAsJXApIHN0dWJcbiIsIGhJbnN0LCBoSGVhcCk7CglyZXR1cm4gRV9GQUlMOyAgIC8qIFRoaXMgaXMgd2hhdCBpcyB1c2VkIGlmIHNobHdhcGkgbm90IGxvYWRlZCAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMxXQogKi8KRFdPUkQgV0lOQVBJIFNITFdBUElfNDMxIChEV09SRCB4KQp7CglGSVhNRSgiKDB4JTA4bHgpc3R1YlxuIiwgeCk7CglyZXR1cm4gMHhhYmJhMTI0NzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzNl0KICoKICogQ29udmVydCBhbiBVbmljb2RlIHN0cmluZyBDTFNJRCBpbnRvIGEgQ0xTSUQuCiAqCiAqIFBBUkFNUwogKiAgaWRzdHIgICAgICBbSV0gICBzdHJpbmcgY29udGFpbmluZyBhIENMU0lEIGluIHRleHQgZm9ybQogKiAgaWQgICAgICAgICBbT10gICBDTFNJRCBleHRyYWN0ZWQgZnJvbSB0aGUgc3RyaW5nCiAqCiAqIFJFVFVSTlMKICogIFNfT0sgb24gc3VjY2VzcyBvciBFX0lOVkFMSURBUkcgb24gZmFpbHVyZQogKgogKiBOT1RFUwogKiAgVGhpcyBpcyByZWFsbHkgQ0xTSURGcm9tU3RyaW5nKCkgd2hpY2ggaXMgZXhwb3J0ZWQgYnkgb2xlMzIuZGxsLAogKiAgaG93ZXZlciB0aGUgbmF0aXZlIHNobHdhcGkuZGxsIGRvZXMgKm5vdCogaW1wb3J0IG9sZTMyLiBOb3IgZG9lcwogKiAgb2xlMzIuZGxsIGltcG9ydCB0aGlzIG9yZGluYWwgZnJvbSBzaGx3YXBpLiBUaGVyZWZvcmUgd2UgbXVzdCBjb25jbHVkZQogKiAgdGhhdCBNUyBkdXBsaWNhdGVkIHRoZSBjb2RlIGZvciBDTFNJREZyb21TdHJpbmcoKSwgYW5kIHllcyB0aGV5IGRpZCwgb25seQogKiAgaXQgcmV0dXJucyBhbiBFX0lOVkFMSURBUkcgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKiAgVGhpcyBpcyBhIGR1cGxpY2F0ZSAod2l0aCBjaGFuZ2VzIGZvciBVbmljb2RlKSBvZiBDTFNJREZyb21TdHJpbmcxNigpCiAqICBpbiAiZGxscy9vbGUzMi9jb21wb2JqLmMiLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMV0FQSV80MzYoTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CglMUENXU1RSIHMgPSBpZHN0cjsKCUJZVEUgKnA7CglJTlQgaTsKCVdDSEFSIHRhYmxlWzI1Nl07CgoJaWYgKCFzKSB7CgkgIG1lbXNldChpZCwgMCwgc2l6ZW9mKENMU0lEKSk7CgkgIHJldHVybiBTX09LOwoJfQoJZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCgoJICBpZiAoc3RybGVuVyhzKSAhPSAzOCkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgaWYgKChzWzBdIT1MJ3snKSB8fCAoc1s5XSE9TCctJykgfHwgKHNbMTRdIT1MJy0nKSB8fCAoc1sxOV0hPUwnLScpIHx8IChzWzI0XSE9TCctJykgfHwgKHNbMzddIT1MJ30nKSkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgZm9yIChpPTE7IGk8Mzc7IGkrKykKCSAgewoJICAgIGlmICgoaSA9PSA5KXx8KGkgPT0gMTQpfHwoaSA9PSAxOSl8fChpID09IDI0KSkKCSAgICAgIGNvbnRpbnVlOwoJICAgIGlmICghKCgoc1tpXSA+PSBMJzAnKSAmJiAoc1tpXSA8PSBMJzknKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ2EnKSAmJiAoc1tpXSA8PSBMJ2YnKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ0EnKSAmJiAoc1tpXSA8PSBMJ0YnKSkpCgkgICAgICAgKQoJICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKCSAgfQoJfQoKICAgIFRSQUNFKCIlcyAtPiAlcFxuIiwgZGVidWdzdHJfdyhzKSwgaWQpOwoKICAvKiBxdWljayBsb29rdXAgdGFibGUgKi8KICAgIG1lbXNldCh0YWJsZSwgMCwgMjU2KnNpemVvZihXQ0hBUikpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cgl0YWJsZVsnMCcgKyBpXSA9IGk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7Cgl0YWJsZVsnQScgKyBpXSA9IGkrMTA7Cgl0YWJsZVsnYScgKyBpXSA9IGkrMTA7CiAgICB9CgogICAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwoKICAgIHAgPSAoQllURSAqKSBpZDsKCiAgICBzKys7CS8qIHNraXAgbGVhZGluZyBicmFjZSAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKCXBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gNDsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CglzICs9IDI7CiAgICB9CiAgICBzKys7CS8qIHNraXAgLSAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCSpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM3XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIE9TIHN1cHBvcnRzIGEgZ2l2ZW4gZmVhdHVyZS4KICoKICogUEFSQU1TCiAqICBkd0ZlYXR1cmUgW0ldIEZlYXR1cmUgcmVxdWVzdGVkICh1bmRvY3VtZW50ZWQpCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgIElmIHRoZSBmZWF0dXJlIGlzIGF2YWlsYWJsZS4KICogIEZBTFNFIElmIHRoZSBmZWF0dXJlIGlzIG5vdCBhdmFpbGFibGUuCiAqLwpEV09SRCBXSU5BUEkgU0hMV0FQSV80MzcgKERXT1JEIGZlYXR1cmUpCnsKICBGSVhNRSgiKDB4JTA4bHgpIHN0dWJcbiIsIGZlYXR1cmUpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvclJHQlRvSExTCVtTSExXQVBJLjQ0NV0KICoKICogQ29udmVydCBhbiByZ2IgQ09MT1JSRUYgaW50byB0aGUgaGxzIGNvbG9yIHNwYWNlLgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gU291cmNlIHJnYiB2YWx1ZQogKiAgcHdIdWUgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGh1ZQogKiAgcHdMdW1pbmFuY2UgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGx1bWluYW5jZQogKiAgcHdTYXR1cmF0aW9uIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIHNhdHVyYXRpb24KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4gcHdIdWUsIHB3THVtaW5hbmNlIGFuZCBwd1NhdHVyYXRpb24gYXJlIHNldCB0byB0aGUgY29udmVydGVkCiAqICB2YWx1ZXMuCiAqCiAqIE5PVEVTCiAqICBPdXRwdXQgSExTIHZhbHVlcyBhcmUgY29uc3RyYWluZWQgdG8gdGhlIHJhbmdlICgwLi4yNDApLgogKiAgRm9yIEFjaHJvbWF0aWMgY29udmVyc2lvbnMsIEh1ZSBpcyBzZXQgdG8gMTYwLgogKi8KVk9JRCBXSU5BUEkgQ29sb3JSR0JUb0hMUyhDT0xPUlJFRiBjUkdCLCBMUFdPUkQgcHdIdWUsCgkJCSAgTFBXT1JEIHB3THVtaW5hbmNlLCBMUFdPUkQgcHdTYXR1cmF0aW9uKQp7CiAgaW50IHdSLCB3Rywgd0IsIHdNYXgsIHdNaW4sIHdIdWUsIHdMdW1pbm9zaXR5LCB3U2F0dXJhdGlvbjsKCiAgVFJBQ0UoIiglMDhseCwlcCwlcCwlcClcbiIsIGNSR0IsIHB3SHVlLCBwd0x1bWluYW5jZSwgcHdTYXR1cmF0aW9uKTsKCiAgd1IgPSBHZXRSVmFsdWUoY1JHQik7CiAgd0cgPSBHZXRHVmFsdWUoY1JHQik7CiAgd0IgPSBHZXRCVmFsdWUoY1JHQik7CgogIHdNYXggPSBtYXgod1IsIG1heCh3Rywgd0IpKTsKICB3TWluID0gbWluKHdSLCBtaW4od0csIHdCKSk7CgogIC8qIEx1bWlub3NpdHkgKi8KICB3THVtaW5vc2l0eSA9ICgod01heCArIHdNaW4pICogMjQwICsgMjU1KSAvIDUxMDsKCiAgaWYgKHdNYXggPT0gd01pbikKICB7CiAgICAvKiBBY2hyb21hdGljIGNhc2UgKi8KICAgIHdTYXR1cmF0aW9uID0gMDsKICAgIC8qIEh1ZSBpcyBub3cgdW5yZXByZXNlbnRhYmxlLCBidXQgdGhpcyBpcyB3aGF0IG5hdGl2ZSByZXR1cm5zLi4uICovCiAgICB3SHVlID0gMTYwOwogIH0KICBlbHNlCiAgewogICAgLyogQ2hyb21hdGljIGNhc2UgKi8KICAgIGludCB3RGVsdGEgPSB3TWF4IC0gd01pbiwgd1JOb3JtLCB3R05vcm0sIHdCTm9ybTsKCiAgICAvKiBTYXR1cmF0aW9uICovCiAgICBpZiAod0x1bWlub3NpdHkgPD0gMTIwKQogICAgICB3U2F0dXJhdGlvbiA9ICgod01heCArIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKHdNYXggKyB3TWluKTsKICAgIGVsc2UKICAgICAgd1NhdHVyYXRpb24gPSAoKDUxMCAtIHdNYXggLSB3TWluKS8yICsgd0RlbHRhICogMjQwKSAvICg1MTAgLSB3TWF4IC0gd01pbik7CgogICAgLyogSHVlICovCiAgICB3Uk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3UiAqIDQwKSAvIHdEZWx0YTsKICAgIHdHTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdHICogNDApIC8gd0RlbHRhOwogICAgd0JOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0IgKiA0MCkgLyB3RGVsdGE7CgogICAgaWYgKHdSID09IHdNYXgpCiAgICAgIHdIdWUgPSB3Qk5vcm0gLSB3R05vcm07CiAgICBlbHNlIGlmICh3RyA9PSB3TWF4KQogICAgICB3SHVlID0gODAgKyB3Uk5vcm0gLSB3Qk5vcm07CiAgICBlbHNlCiAgICAgIHdIdWUgPSAxNjAgKyB3R05vcm0gLSB3Uk5vcm07CiAgICBpZiAod0h1ZSA8IDApCiAgICAgIHdIdWUgKz0gMjQwOwogICAgZWxzZSBpZiAod0h1ZSA+IDI0MCkKICAgICAgd0h1ZSAtPSAyNDA7CiAgfQogIGlmIChwd0h1ZSkKICAgICpwd0h1ZSA9IHdIdWU7CiAgaWYgKHB3THVtaW5hbmNlKQogICAgKnB3THVtaW5hbmNlID0gd0x1bWlub3NpdHk7CiAgaWYgKHB3U2F0dXJhdGlvbikKICAgICpwd1NhdHVyYXRpb24gPSB3U2F0dXJhdGlvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSENyZWF0ZVNoZWxsUGFsZXR0ZQlbU0hMV0FQSS5AXQogKi8KSFBBTEVUVEUgV0lOQVBJIFNIQ3JlYXRlU2hlbGxQYWxldHRlKEhEQyBoZGMpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBDcmVhdGVIYWxmdG9uZVBhbGV0dGUoaGRjKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hHZXRJbnZlcnNlQ01BUCAoU0hMV0FQSS5AKQogKgogKiBHZXQgYW4gaW52ZXJzZSBjb2xvciBtYXAgdGFibGUuCiAqCiAqIFBBUkFNUwogKiAgbHBDbWFwICBbT10gRGVzdGluYXRpb24gZm9yIGNvbG9yIG1hcAogKiAgZHdTaXplICBbSV0gU2l6ZSBvZiBtZW1vcnkgcG9pbnRlZCB0byBieSBscENtYXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiwgICAgSWYgbHBDbWFwIGlzIGludmFsaWQuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIGR3RmxhZ3MgaXMgaW52YWxpZAogKiAgICAgICAgICAgRV9PVVRPRk1FTU9SWSwgSWYgdGhlcmUgaXMgbm8gbWVtb3J5IGF2YWlsYWJsZQogKgogKiBOT1RFUwogKiAgZHdTaXplIG1heSBvbmx5IGJlIENNQVBfUFRSX1NJWkUgKDQpIG9yIENNQVBfU0laRSAoODE5MikuCiAqICBJZiBkd1NpemUgPSBDTUFQX1BUUl9TSVpFLCAqbHBDbWFwIGlzIHNldCB0byB0aGUgYWRkcmVzcyBvZiB0aGlzIERMTCdzCiAqICBpbnRlcm5hbCBDTWFwLgogKiAgSWYgZHdTaXplID0gQ01BUF9TSVpFLCBscENtYXAgaXMgZmlsbGVkIHdpdGggYSBjb3B5IG9mIHRoZSBkYXRhIGZyb20KICogIHRoaXMgRExMJ3MgaW50ZXJuYWwgQ01hcC4KICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW52ZXJzZUNNQVAoTFBEV09SRCBkZXN0LCBEV09SRCBkd1NpemUpCnsKICAgIGlmIChkd1NpemUgPT0gNCkgewoJRklYTUUoIiAtIHJldHVybmluZyBib2d1cyBhZGRyZXNzIGZvciBTSEdldEludmVyc2VDTUFQXG4iKTsKCSpkZXN0ID0gKERXT1JEKTB4YWJiYTEyNDk7CglyZXR1cm4gMDsKICAgIH0KICAgIEZJWE1FKCIoJXAsICUjbHgpIHN0dWJcbiIsIGRlc3QsIGR3U2l6ZSk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSElzTG93TWVtb3J5TWFjaGluZQlbU0hMV0FQSS5AXQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIGN1cnJlbnQgY29tcHV0ZXIgaGFzIGxvdyBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiAgeCBbSV0gRklYTUUKICoKICogUkVUVVJOUwogKiAgVFJVRSBpZiB0aGUgdXNlcnMgbWFjaGluZSBoYXMgMTYgTWVnYWJ5dGVzIG9mIG1lbW9yeSBvciBsZXNzLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc0xvd01lbW9yeU1hY2hpbmUgKERXT1JEIHgpCnsKICBGSVhNRSgiKDB4JTA4bHgpIHN0dWJcbiIsIHgpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBHZXRNZW51UG9zRnJvbUlECVtTSExXQVBJLkBdCiAqLwpJTlQgV0lOQVBJIEdldE1lbnVQb3NGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgd0lEKQp7CiBNRU5VSVRFTUlORk9BIG1pOwogSU5UIG5Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpLCBuSXRlciA9IDA7Cgogd2hpbGUgKG5JdGVyIDwgbkNvdW50KQogewogICBtaS53SUQgPSAwOwogICBpZiAoIUdldE1lbnVJdGVtSW5mb0EoaE1lbnUsIG5JdGVyLCBUUlVFLCAmbWkpICYmIG1pLndJRCA9PSB3SUQpCiAgICAgcmV0dXJuIG5JdGVyOwogICBuSXRlcisrOwogfQogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFNraXBKdW5jdGlvbglbU0hMV0FQSS5AXQogKgogKiBEZXRlcm1pbmUgaWYgYSBiaW5kIGNvbnRleHQgY2FuIGJlIGJvdW5kIHRvIGFuIG9iamVjdAogKgogKiBQQVJBTVMKICogIHBiYyAgICBbSV0gQmluZCBjb250ZXh0IHRvIGNoZWNrCiAqICBwY2xzaWQgW0ldIENMU0lEIG9mIG9iamVjdCB0byBiZSBib3VuZCB0bwogKgogKiBSRVRVUk5TCiAqICBUUlVFOiBJZiBpdCBpcyBzYWZlIHRvIGJpbmQKICogIEZBTFNFOiBJZiBwYmMgaXMgaW52YWxpZCBvciBiaW5kaW5nIHdvdWxkIG5vdCBiZSBzYWZlCiAqCiAqLwpCT09MIFdJTkFQSSBTSFNraXBKdW5jdGlvbihJQmluZEN0eCAqcGJjLCBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgc3RhdGljIFdDSEFSIHN6U2tpcEJpbmRpbmdbXSA9IHsgJ1MnLCdrJywnaScsJ3AnLCcgJywKICAgICdCJywnaScsJ24nLCdkJywnaScsJ24nLCdnJywnICcsJ0MnLCdMJywnUycsJ0knLCdEJywnXDAnIH07CiAgQk9PTCBiUmV0ID0gRkFMU0U7CgogIGlmIChwYmMpCiAgewogICAgSVVua25vd24qIGxwVW5rOwoKICAgIGlmIChTVUNDRUVERUQoSUJpbmRDdHhfR2V0T2JqZWN0UGFyYW0ocGJjLCBzelNraXBCaW5kaW5nLCAmbHBVbmspKSkKICAgIHsKICAgICAgQ0xTSUQgY2xzaWQ7CgogICAgICBpZiAoU1VDQ0VFREVEKFNITFdBUElfMTc1KGxwVW5rLCAmY2xzaWQpKSAmJgogICAgICAgICAgSXNFcXVhbEdVSUQocGNsc2lkLCAmY2xzaWQpKQogICAgICAgIGJSZXQgPSBUUlVFOwoKICAgICAgSVVua25vd25fUmVsZWFzZShscFVuayk7CiAgICB9CiAgfQogIHJldHVybiBiUmV0Owp9Cg==