Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGbGlwcGluZyByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gSmltIEtlaXIgKGppbWtlaXJAdXNlcnMuc291cmNlZm9yZ2UubmV0KQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLyoqCkZsaXAgdGhlIGltYWdlIGhvcml6b250YWxseSBhbG9uZyB0aGUgdmVydGljYWwgYXhpcy4KQHBhcmFtIHNyYyBJbnB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KKi8KQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9GbGlwSG9yaXpvbnRhbChGSUJJVE1BUCAqc3JjKSB7CglpZiAoIUZyZWVJbWFnZV9IYXNQaXhlbHMoc3JjKSkgcmV0dXJuIEZBTFNFOwoKCXVuc2lnbmVkIGxpbmUgICA9IEZyZWVJbWFnZV9HZXRMaW5lKHNyYyk7Cgl1bnNpZ25lZCB3aWR0aAk9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCXVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgoJLy8gY29weSBiZXR3ZWVuIGFsaWduZWQgbWVtb3JpZXMKCUJZVEUgKm5ld19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9BbGlnbmVkX01hbGxvYyhsaW5lICogc2l6ZW9mKEJZVEUpLCBGSUJJVE1BUF9BTElHTk1FTlQpOwoJaWYgKCFuZXdfYml0cykgcmV0dXJuIEZBTFNFOwoKCS8vIG1pcnJvciB0aGUgYnVmZmVyCgoJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCW1lbWNweShuZXdfYml0cywgYml0cywgbGluZSk7CgoJCXN3aXRjaCAoRnJlZUltYWdlX0dldEJQUChzcmMpKSB7CgkJCWNhc2UgMSA6CgkJCXsJCQkJCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gZ2V0IHBpeGVsIGF0ICh4LCB5KQoJCQkJCUJPT0wgdmFsdWUgPSAobmV3X2JpdHNbeCA+PiAzXSAmICgweDgwID4+ICh4ICYgMHgwNykpKSAhPSAwOwoJCQkJCS8vIHNldCBwaXhlbCBhdCAobmV3X3gsIHkpCgkJCQkJdW5zaWduZWQgbmV3X3ggPSB3aWR0aCAtIDEgLSB4OwoJCQkJCXZhbHVlID8gYml0c1tuZXdfeCA+PiAzXSB8PSAoMHg4MCA+PiAobmV3X3ggJiAweDcpKSA6IGJpdHNbbmV3X3ggPj4gM10gJj0gKDB4ZmY3ZiA+PiAobmV3X3ggJiAweDcpKTsKCQkJCX0KCQkJfQoJCQlicmVhazsKCgkJCWNhc2UgNCA6CgkJCXsKCQkJCWZvcih1bnNpZ25lZCBjID0gMDsgYyA8IGxpbmU7IGMrKykgewoJCQkJCWJpdHNbY10gPSBuZXdfYml0c1tsaW5lIC0gYyAtIDFdOwoKCQkJCQlCWVRFIG5pYmJsZSA9IChiaXRzW2NdICYgMHhGMCkgPj4gNDsKCgkJCQkJYml0c1tjXSA9IGJpdHNbY10gPDwgNDsKCQkJCQliaXRzW2NdIHw9IG5pYmJsZTsKCQkJCX0KCQkJfQoJCQlicmVhazsKCgkJCWNhc2UgODoKCQkJewkJCQkKCQkJCUJZVEUgKmRzdF9kYXRhID0gKEJZVEUqKSBiaXRzOyAJCQkJCgkJCQlCWVRFICpzcmNfZGF0YSA9IChCWVRFKikgKG5ld19iaXRzICsgbGluZSAtIGJ5dGVzcHApOyAJCQkJCgkJCQlmb3IodW5zaWduZWQgYyA9IDA7IGMgPCB3aWR0aDsgYysrKSB7IAkJCQoJCQkJCSpkc3RfZGF0YSsrID0gKnNyY19kYXRhLS07ICAKCQkJCX0gCgkJCX0KCQkJYnJlYWs7CgoJCQljYXNlIDE2OgoJCQl7CQkJCQoJCQkJV09SRCAqZHN0X2RhdGEgPSAoV09SRCopIGJpdHM7IAkJCQkKCQkJCVdPUkQgKnNyY19kYXRhID0gKFdPUkQqKSAobmV3X2JpdHMgKyBsaW5lIC0gYnl0ZXNwcCk7IAkJCQkKCQkJCWZvcih1bnNpZ25lZCBjID0gMDsgYyA8IHdpZHRoOyBjKyspIHsgCQkJCgkJCQkJKmRzdF9kYXRhKysgPSAqc3JjX2RhdGEtLTsgIAoJCQkJfSAKCQkJfQoJCQlicmVhazsKCgkJCWNhc2UgMjQgOgoJCQljYXNlIDMyIDoKCQkJY2FzZSA0ODoKCQkJY2FzZSA2NDoKCQkJY2FzZSA5NjoKCQkJY2FzZSAxMjg6CgkJCXsJCQkJCgkJCQlCWVRFICpkc3RfZGF0YSA9IChCWVRFKikgYml0czsgCQkJCQoJCQkJQllURSAqc3JjX2RhdGEgPSAoQllURSopIChuZXdfYml0cyArIGxpbmUgLSBieXRlc3BwKTsgCQkJCQoJCQkJZm9yKHVuc2lnbmVkIGMgPSAwOyBjIDwgd2lkdGg7IGMrKykgeyAJCQoJCQkJCWZvcih1bnNpZ25lZCBrID0gMDsgayA8IGJ5dGVzcHA7IGsrKykgewoJCQkJCQkqZHN0X2RhdGErKyA9IHNyY19kYXRhW2tdOyAgCgkJCQkJfQoJCQkJCXNyY19kYXRhIC09IGJ5dGVzcHA7CgkJCQl9IAoJCQl9CgkJCWJyZWFrOwoKCQl9Cgl9CgoJRnJlZUltYWdlX0FsaWduZWRfRnJlZShuZXdfYml0cyk7CgoJcmV0dXJuIFRSVUU7Cn0KCgovKioKRmxpcCB0aGUgaW1hZ2UgdmVydGljYWxseSBhbG9uZyB0aGUgaG9yaXpvbnRhbCBheGlzLgpAcGFyYW0gc3JjIElucHV0IGltYWdlIHRvIGJlIHByb2Nlc3NlZC4KQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoqLwoKQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9GbGlwVmVydGljYWwoRklCSVRNQVAgKnNyYykgewoJQllURSAqRnJvbSwgKk1pZDsKCglpZiAoIUZyZWVJbWFnZV9IYXNQaXhlbHMoc3JjKSkgcmV0dXJuIEZBTFNFOwoKCS8vIHN3YXAgdGhlIGJ1ZmZlcgoKCXVuc2lnbmVkIHBpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCS8vIGNvcHkgYmV0d2VlbiBhbGlnbmVkIG1lbW9yaWVzCglNaWQgPSAoQllURSopRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jKHBpdGNoICogc2l6ZW9mKEJZVEUpLCBGSUJJVE1BUF9BTElHTk1FTlQpOwoJaWYgKCFNaWQpIHJldHVybiBGQUxTRTsKCglGcm9tID0gRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCQoJdW5zaWduZWQgbGluZV9zID0gMDsKCXVuc2lnbmVkIGxpbmVfdCA9IChoZWlnaHQtMSkgKiBwaXRjaDsKCglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQvMjsgeSsrKSB7CgoJCW1lbWNweShNaWQsIEZyb20gKyBsaW5lX3MsIHBpdGNoKTsKCQltZW1jcHkoRnJvbSArIGxpbmVfcywgRnJvbSArIGxpbmVfdCwgcGl0Y2gpOwoJCW1lbWNweShGcm9tICsgbGluZV90LCBNaWQsIHBpdGNoKTsKCgkJbGluZV9zICs9IHBpdGNoOwoJCWxpbmVfdCAtPSBwaXRjaDsKCgl9CgoJRnJlZUltYWdlX0FsaWduZWRfRnJlZShNaWQpOwoKCXJldHVybiBUUlVFOwp9Cgo=