Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDb3B5IC8gcGFzdGUgcm91dGluZXMKLy8KLy8gLSBGbG9yaXMgdmFuIGRlbiBCZXJnIChmbHZkYmVyZ0B3eHMubmwpCi8vIC0gQWxleGFuZGVyIER5bWVyZXRzIChzYXNoYWRAdGUubmV0LnVhKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gTWFuZnJlZCBUYXVzY2ggKG1hbmZyZWQudGF1c2NoQHQtb25saW5lLmRlKQovLyAtIFJpbGV5IE1jTmlmZiAocm1jbmlmZkBtYXJleGdyb3VwLmNvbSkKLy8gLSBDYXJzdGVuIEtsZWluIChja2xlaW4wNUB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgSGVscGVycwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIEFscGhhIGJsZW5kaW5nIC8gY29tYmluZSBmdW5jdGlvbnMKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8vIDEtYml0CnN0YXRpYyBCT09MIENvbWJpbmUxKEZJQklUTUFQICpkc3RfZGliLCBGSUJJVE1BUCAqc3JjX2RpYiwgdW5zaWduZWQgeCwgdW5zaWduZWQgeSwgdW5zaWduZWQgYWxwaGEpOwovLy8gNC1iaXQKc3RhdGljIEJPT0wgQ29tYmluZTQoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSk7Ci8vLyA4LWJpdApzdGF0aWMgQk9PTCBDb21iaW5lOChGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKTsKLy8vIDE2LWJpdCA1NTUKc3RhdGljIEJPT0wgQ29tYmluZTE2XzU1NShGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKTsKLy8vIDE2LWJpdCA1NjUKc3RhdGljIEJPT0wgQ29tYmluZTE2XzU2NShGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKTsKLy8vIDI0LWJpdApzdGF0aWMgQk9PTCBDb21iaW5lMjQoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSk7Ci8vLyAzMi0gYml0CnN0YXRpYyBCT09MIENvbWJpbmUzMihGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKTsKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIDEtYml0Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnN0YXRpYyBCT09MIApDb21iaW5lMShGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKSB7CglCT09MIHZhbHVlOwoKCS8vIGNoZWNrIHRoZSBiaXQgZGVwdGggb2Ygc3JjIGFuZCBkc3QgaW1hZ2VzCglpZigoRnJlZUltYWdlX0dldEJQUChkc3RfZGliKSAhPSAxKSB8fCAoRnJlZUltYWdlX0dldEJQUChzcmNfZGliKSAhPSAxKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCgkvLyBjaGVjayB0aGUgc2l6ZSBvZiBzcmMgaW1hZ2UKCWlmKCh4ICsgRnJlZUltYWdlX0dldFdpZHRoKHNyY19kaWIpID4gRnJlZUltYWdlX0dldFdpZHRoKGRzdF9kaWIpKSB8fCAoeSArIEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYikgPiBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdF9kaWIpKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCglCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdF9kaWIpICsgKChGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdF9kaWIpIC0gRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKSAtIHkpICogRnJlZUltYWdlX0dldFBpdGNoKGRzdF9kaWIpKTsKCUJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoc3JjX2RpYik7CQoKCS8vIGNvbWJpbmUgaW1hZ2VzCglmb3IodW5zaWduZWQgcm93cyA9IDA7IHJvd3MgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpOyByb3dzKyspIHsKCQlmb3IodW5zaWduZWQgY29scyA9IDA7IGNvbHMgPCBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjX2RpYik7IGNvbHMrKykgewoJCQkvLyBnZXQgYml0IGF0IChyb3dzLCBjb2xzKSBpbiBzcmMgaW1hZ2UKCQkJdmFsdWUgPSAoc3JjX2JpdHNbY29scyA+PiAzXSAmICgweDgwID4+IChjb2xzICYgMHgwNykpKSAhPSAwOwoJCQkvLyBzZXQgYml0IGF0IChyb3dzLCB4K2NvbHMpIGluIGRzdCBpbWFnZQkKCQkJdmFsdWUgPyBkc3RfYml0c1soeCArIGNvbHMpID4+IDNdIHw9ICgweDgwID4+ICgoeCArIGNvbHMpICYgMHg3KSkgOiBkc3RfYml0c1soeCArIGNvbHMpID4+IDNdICY9ICgweEZGN0YgPj4gKCh4ICsgY29scykgJiAweDcpKTsKCQl9CgoJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQlzcmNfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjX2RpYik7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICA0LWJpdAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCAKQ29tYmluZTQoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSkgewoJaW50IHN3YXBUYWJsZVsxNl07CglCT09MIGJPZGRTdGFydCwgYk9kZEVuZDsKCgkvLyBjaGVjayB0aGUgYml0IGRlcHRoIG9mIHNyYyBhbmQgZHN0IGltYWdlcwoJaWYoKEZyZWVJbWFnZV9HZXRCUFAoZHN0X2RpYikgIT0gNCkgfHwgKEZyZWVJbWFnZV9HZXRCUFAoc3JjX2RpYikgIT0gNCkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJLy8gY2hlY2sgdGhlIHNpemUgb2Ygc3JjIGltYWdlCglpZigoeCArIEZyZWVJbWFnZV9HZXRXaWR0aChzcmNfZGliKSA+IEZyZWVJbWFnZV9HZXRXaWR0aChkc3RfZGliKSkgfHwgKHkgKyBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpID4gRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKSkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJLy8gZ2V0IHNyYyBhbmQgZHN0IHBhbGV0dGVzCglSR0JRVUFEICpzcmNfcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoc3JjX2RpYik7CglSR0JRVUFEICpkc3RfcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZHN0X2RpYik7CglpZiAoc3JjX3BhbCA9PSBOVUxMIHx8IGRzdF9wYWwgPT0gTlVMTCkgewoJCXJldHVybiBGQUxTRTsKCX0KCgkvLyBidWlsZCBhIHN3YXAgdGFibGUgZm9yIHRoZSBjbG9zZXN0IGNvbG9yIG1hdGNoIGZyb20gdGhlIHNvdXJjZSBwYWxldHRlIHRvIHRoZSBkZXN0aW5hdGlvbiBwYWxldHRlCgoJZm9yIChpbnQgaSA9IDA7IGkgPCAxNjsgaSsrKQl7CgkJV09SRCBtaW5fZGlmZiA9IChXT1JEKS0xOwoKCQlmb3IgKGludCBqID0gMDsgaiA8IDE2OyBqKyspCXsKCQkJLy8gY2FsY3VsYXRlcyB0aGUgY29sb3IgZGlmZmVyZW5jZSB1c2luZyBhIE1hbmhhdHRhbiBkaXN0YW5jZQoJCQlXT1JEIGFic19kaWZmID0gKFdPUkQpKAoJCQkJYWJzKHNyY19wYWxbaV0ucmdiQmx1ZSAtIGRzdF9wYWxbal0ucmdiQmx1ZSkKCQkJCSsgYWJzKHNyY19wYWxbaV0ucmdiR3JlZW4gLSBkc3RfcGFsW2pdLnJnYkdyZWVuKQoJCQkJKyBhYnMoc3JjX3BhbFtpXS5yZ2JSZWQgLSBkc3RfcGFsW2pdLnJnYlJlZCkKCQkJCSk7CgoJCQlpZiAoYWJzX2RpZmYgPCBtaW5fZGlmZikJewoJCQkJc3dhcFRhYmxlW2ldID0gajsKCQkJCW1pbl9kaWZmID0gYWJzX2RpZmY7CgkJCQlpZiAoYWJzX2RpZmYgPT0gMCkgewoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJfQoKCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZHN0X2RpYikgKyAoKEZyZWVJbWFnZV9HZXRIZWlnaHQoZHN0X2RpYikgLSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpIC0geSkgKglGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYikpICsgKHggPj4gMSk7CglCWVRFICpzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyY19kaWIpOyAgICAKCgkvLyBjb21iaW5lIGltYWdlcwoKCS8vIGFsbG9jYXRlIHNwYWNlIGZvciBvdXIgdGVtcG9yYXJ5IHJvdwoJdW5zaWduZWQgc3JjX2xpbmUgICA9IEZyZWVJbWFnZV9HZXRMaW5lKHNyY19kaWIpOwoJdW5zaWduZWQgc3JjX3dpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmNfZGliKTsKCXVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpOwoKCUJZVEUgKmJ1ZmZlciA9IChCWVRFICopbWFsbG9jKHNyY19saW5lICogc2l6ZW9mKEJZVEUpKTsKCWlmIChidWZmZXIgPT0gTlVMTCkgewoJCXJldHVybiBGQUxTRTsKCX0KCgliT2RkU3RhcnQgPSAoeCAmIDB4MDEpID8gVFJVRSA6IEZBTFNFOwoKCWlmICgoYk9kZFN0YXJ0ICYmICEoc3JjX3dpZHRoICYgMHgwMSkpIHx8ICghYk9kZFN0YXJ0ICYmIChzcmNfd2lkdGggJiAweDAxKSkpCXsKCQliT2RkRW5kID0gVFJVRTsKCX0KCWVsc2UgewoJCWJPZGRFbmQgPSBGQUxTRTsKCX0KCglmb3IodW5zaWduZWQgcm93cyA9IDA7IHJvd3MgPCBzcmNfaGVpZ2h0OyByb3dzKyspIHsKCQltZW1jcHkoYnVmZmVyLCBzcmNfYml0cywgc3JjX2xpbmUpOwoJCQoJCS8vIGNoYW5nZSB0aGUgdmFsdWVzIGluIHRoZSB0ZW1wIHJvdyB0byBiZSB0aG9zZSBmcm9tIHRoZSBzd2FwIHRhYmxlCgkJCgkJZm9yICh1bnNpZ25lZCBjb2xzID0gMDsgY29scyA8IHNyY19saW5lOyBjb2xzKyspIHsKCQkJYnVmZmVyW2NvbHNdID0gKEJZVEUpKChzd2FwVGFibGVbSElOSUJCTEUoYnVmZmVyW2NvbHNdKSA+PiA0XSA8PCA0KSArIHN3YXBUYWJsZVtMT1dOSUJCTEUoYnVmZmVyW2NvbHNdKV0pOwoJCX0KCgkJaWYgKGJPZGRTdGFydCkgewkKCQkJYnVmZmVyWzBdID0gSElOSUJCTEUoZHN0X2JpdHNbMF0pICsgTE9XTklCQkxFKGJ1ZmZlclswXSk7CgkJfQoJCQoJCWlmIChiT2RkRW5kKQl7CgkJCWJ1ZmZlcltzcmNfbGluZSAtIDFdID0gSElOSUJCTEUoYnVmZmVyW3NyY19saW5lIC0gMV0pICsgTE9XTklCQkxFKGRzdF9iaXRzW3NyY19saW5lIC0gMV0pOwoJCX0KCgkJbWVtY3B5KGRzdF9iaXRzLCBidWZmZXIsIHNyY19saW5lKTsKCQkKCQlkc3RfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYik7CgkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJfQoKCWZyZWUoYnVmZmVyKTsKCglyZXR1cm4gVFJVRTsKCn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICA4LWJpdAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCAKQ29tYmluZTgoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSkgewoJLy8gY2hlY2sgdGhlIGJpdCBkZXB0aCBvZiBzcmMgYW5kIGRzdCBpbWFnZXMKCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRzdF9kaWIpICE9IDgpIHx8IChGcmVlSW1hZ2VfR2V0QlBQKHNyY19kaWIpICE9IDgpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHNyYyBpbWFnZQoJaWYoKHggKyBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjX2RpYikgPiBGcmVlSW1hZ2VfR2V0V2lkdGgoZHN0X2RpYikpIHx8ICh5ICsgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKSA+IEZyZWVJbWFnZV9HZXRIZWlnaHQoZHN0X2RpYikpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZHN0X2RpYikgKyAoKEZyZWVJbWFnZV9HZXRIZWlnaHQoZHN0X2RpYikgLSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpIC0geSkgKiBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYikpICsgKHgpOwoJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0Qml0cyhzcmNfZGliKTsJCgoJaWYoYWxwaGEgPiAyNTUpIHsKCQkvLyBjb21iaW5lIGltYWdlcwoJCWZvcih1bnNpZ25lZCByb3dzID0gMDsgcm93cyA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYik7IHJvd3MrKykgewoJCQltZW1jcHkoZHN0X2JpdHMsIHNyY19iaXRzLCBGcmVlSW1hZ2VfR2V0TGluZShzcmNfZGliKSk7CgoJCQlkc3RfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYik7CgkJCXNyY19iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmNfZGliKTsKCQl9Cgl9IGVsc2UgewoJCS8vIGFscGhhIGJsZW5kIGltYWdlcwoJCWZvcih1bnNpZ25lZCByb3dzID0gMDsgcm93cyA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYik7IHJvd3MrKykgewoJCQlmb3IgKHVuc2lnbmVkIGNvbHMgPSAwOyBjb2xzIDwgRnJlZUltYWdlX0dldExpbmUoc3JjX2RpYik7IGNvbHMrKykgewkJCQkJCQkKCQkJCWRzdF9iaXRzW2NvbHNdID0gKEJZVEUpKCgoc3JjX2JpdHNbY29sc10gLSBkc3RfYml0c1tjb2xzXSkgKiBhbHBoYSArIChkc3RfYml0c1tjb2xzXSA8PCA4KSkgPj4gOCk7CgkJCX0KCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0KCglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIDE2LWJpdAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCAKQ29tYmluZTE2XzU1NShGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIHVuc2lnbmVkIGFscGhhKSB7CgkvLyBjaGVjayB0aGUgYml0IGRlcHRoIG9mIHNyYyBhbmQgZHN0IGltYWdlcwoJaWYoKEZyZWVJbWFnZV9HZXRCUFAoZHN0X2RpYikgIT0gMTYpIHx8IChGcmVlSW1hZ2VfR2V0QlBQKHNyY19kaWIpICE9IDE2KSkgewoJCXJldHVybiBGQUxTRTsKCX0KCgkvLyBjaGVjayB0aGUgc2l6ZSBvZiBzcmMgaW1hZ2UKCWlmKCh4ICsgRnJlZUltYWdlX0dldFdpZHRoKHNyY19kaWIpID4gRnJlZUltYWdlX0dldFdpZHRoKGRzdF9kaWIpKSB8fCAoeSArIEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYikgPiBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdF9kaWIpKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCglCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdF9kaWIpICsgKChGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdF9kaWIpIC0gRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKSAtIHkpICogRnJlZUltYWdlX0dldFBpdGNoKGRzdF9kaWIpKSArICh4ICogMik7CglCWVRFICpzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyY19kaWIpOwkKCglpZiAoYWxwaGEgPiAyNTUpIHsKCQlmb3IodW5zaWduZWQgcm93cyA9IDA7IHJvd3MgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpOyByb3dzKyspIHsKCQkJbWVtY3B5KGRzdF9iaXRzLCBzcmNfYml0cywgRnJlZUltYWdlX0dldExpbmUoc3JjX2RpYikpOwoKCQkJZHN0X2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKGRzdF9kaWIpOwoJCQlzcmNfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjX2RpYik7CgkJfQoJfSBlbHNlIHsKCQlmb3IodW5zaWduZWQgcm93cyA9IDA7IHJvd3MgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpOyByb3dzKyspIHsKCQkJZm9yKHVuc2lnbmVkIGNvbHMgPSAwOyBjb2xzIDwgRnJlZUltYWdlX0dldExpbmUoc3JjX2RpYik7IGNvbHMgKz0gMikgewoJCQkJUkdCVFJJUExFIGNvbG9yX3M7CgkJCQlSR0JUUklQTEUgY29sb3JfdDsKCQkJCQoJCQkJV09SRCAqdG1wMSA9IChXT1JEICopJmRzdF9iaXRzW2NvbHNdOwoJCQkJV09SRCAqdG1wMiA9IChXT1JEICopJnNyY19iaXRzW2NvbHNdOwoKCQkJCS8vIGNvbnZlcnQgMTYtYml0IGNvbG9ycyB0byAyNC1iaXQKCgkJCQljb2xvcl9zLnJnYnRSZWQgPSAoQllURSkoKCgqdG1wMSAmIEZJMTZfNTU1X1JFRF9NQVNLKSA+PiBGSTE2XzU1NV9SRURfU0hJRlQpIDw8IDMpOwoJCQkJY29sb3Jfcy5yZ2J0R3JlZW4gPSAoQllURSkoKCgqdG1wMSAmIEZJMTZfNTU1X0dSRUVOX01BU0spID4+IEZJMTZfNTU1X0dSRUVOX1NISUZUKSA8PCAzKTsKCQkJCWNvbG9yX3MucmdidEJsdWUgPSAoQllURSkoKCgqdG1wMSAmIEZJMTZfNTU1X0JMVUVfTUFTSykgPj4gRkkxNl81NTVfQkxVRV9TSElGVCkgPDwgMyk7CgoJCQkJY29sb3JfdC5yZ2J0UmVkID0gKEJZVEUpKCgoKnRtcDIgJiBGSTE2XzU1NV9SRURfTUFTSykgPj4gRkkxNl81NTVfUkVEX1NISUZUKSA8PCAzKTsKCQkJCWNvbG9yX3QucmdidEdyZWVuID0gKEJZVEUpKCgoKnRtcDIgJiBGSTE2XzU1NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU1NV9HUkVFTl9TSElGVCkgPDwgMyk7CgkJCQljb2xvcl90LnJnYnRCbHVlID0gKEJZVEUpKCgoKnRtcDIgJiBGSTE2XzU1NV9CTFVFX01BU0spID4+IEZJMTZfNTU1X0JMVUVfU0hJRlQpIDw8IDMpOwoKCQkJCS8vIGFscGhhIGJsZW5kCgoJCQkJY29sb3Jfcy5yZ2J0UmVkID0gKEJZVEUpKCgoY29sb3JfdC5yZ2J0UmVkIC0gY29sb3Jfcy5yZ2J0UmVkKSAqIGFscGhhICsgKGNvbG9yX3MucmdidFJlZCA8PCA4KSkgPj4gOCk7CgkJCQljb2xvcl9zLnJnYnRHcmVlbiA9IChCWVRFKSgoKGNvbG9yX3QucmdidEdyZWVuIC0gY29sb3Jfcy5yZ2J0R3JlZW4pICogYWxwaGEgKyAoY29sb3Jfcy5yZ2J0R3JlZW4gPDwgOCkpID4+IDgpOwoJCQkJY29sb3Jfcy5yZ2J0Qmx1ZSA9IChCWVRFKSgoKGNvbG9yX3QucmdidEJsdWUgLSBjb2xvcl9zLnJnYnRCbHVlKSAqIGFscGhhICsgKGNvbG9yX3MucmdidEJsdWUgPDwgOCkpID4+IDgpOwoKCQkJCS8vIGNvbnZlcnQgMjQtYml0IGNvbG9yIGJhY2sgdG8gMTYtYml0CgoJCQkJKnRtcDEgPSBSR0I1NTUoY29sb3Jfcy5yZ2J0UmVkLCBjb2xvcl9zLnJnYnRHcmVlbiwgY29sb3Jfcy5yZ2J0Qmx1ZSk7CgkJCX0KCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0KCglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgCkNvbWJpbmUxNl81NjUoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSkgewoJLy8gY2hlY2sgdGhlIGJpdCBkZXB0aCBvZiBzcmMgYW5kIGRzdCBpbWFnZXMKCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRzdF9kaWIpICE9IDE2KSB8fCAoRnJlZUltYWdlX0dldEJQUChzcmNfZGliKSAhPSAxNikpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJLy8gY2hlY2sgdGhlIHNpemUgb2Ygc3JjIGltYWdlCglpZigoeCArIEZyZWVJbWFnZV9HZXRXaWR0aChzcmNfZGliKSA+IEZyZWVJbWFnZV9HZXRXaWR0aChkc3RfZGliKSkgfHwgKHkgKyBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpID4gRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKSkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0Qml0cyhkc3RfZGliKSArICgoRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKSAtIEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYikgLSB5KSAqIEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKSkgKyAoeCAqIDIpOwoJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0Qml0cyhzcmNfZGliKTsJCgoJaWYgKGFscGhhID4gMjU1KSB7CgkJZm9yKHVuc2lnbmVkIHJvd3MgPSAwOyByb3dzIDwgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKTsgcm93cysrKSB7CgkJCW1lbWNweShkc3RfYml0cywgc3JjX2JpdHMsIEZyZWVJbWFnZV9HZXRMaW5lKHNyY19kaWIpKTsKCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0gZWxzZSB7CgkJZm9yKHVuc2lnbmVkIHJvd3MgPSAwOyByb3dzIDwgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKTsgcm93cysrKSB7CgkJCWZvcih1bnNpZ25lZCBjb2xzID0gMDsgY29scyA8IEZyZWVJbWFnZV9HZXRMaW5lKHNyY19kaWIpOyBjb2xzICs9IDIpIHsKCQkJCVJHQlRSSVBMRSBjb2xvcl9zOwoJCQkJUkdCVFJJUExFIGNvbG9yX3Q7CgkJCQkKCQkJCVdPUkQgKnRtcDEgPSAoV09SRCAqKSZkc3RfYml0c1tjb2xzXTsKCQkJCVdPUkQgKnRtcDIgPSAoV09SRCAqKSZzcmNfYml0c1tjb2xzXTsKCgkJCQkvLyBjb252ZXJ0IDE2LWJpdCBjb2xvcnMgdG8gMjQtYml0CgoJCQkJY29sb3Jfcy5yZ2J0UmVkID0gKEJZVEUpKCgoKnRtcDEgJiBGSTE2XzU2NV9SRURfTUFTSykgPj4gRkkxNl81NjVfUkVEX1NISUZUKSA8PCAzKTsKCQkJCWNvbG9yX3MucmdidEdyZWVuID0gKEJZVEUpKCgoKnRtcDEgJiBGSTE2XzU2NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU2NV9HUkVFTl9TSElGVCkgPDwgMik7CgkJCQljb2xvcl9zLnJnYnRCbHVlID0gKEJZVEUpKCgoKnRtcDEgJiBGSTE2XzU2NV9CTFVFX01BU0spID4+IEZJMTZfNTY1X0JMVUVfU0hJRlQpIDw8IDMpOwoKCQkJCWNvbG9yX3QucmdidFJlZCA9IChCWVRFKSgoKCp0bXAyICYgRkkxNl81NjVfUkVEX01BU0spID4+IEZJMTZfNTY1X1JFRF9TSElGVCkgPDwgMyk7CgkJCQljb2xvcl90LnJnYnRHcmVlbiA9IChCWVRFKSgoKCp0bXAyICYgRkkxNl81NjVfR1JFRU5fTUFTSykgPj4gRkkxNl81NjVfR1JFRU5fU0hJRlQpIDw8IDIpOwoJCQkJY29sb3JfdC5yZ2J0Qmx1ZSA9IChCWVRFKSgoKCp0bXAyICYgRkkxNl81NjVfQkxVRV9NQVNLKSA+PiBGSTE2XzU2NV9CTFVFX1NISUZUKSA8PCAzKTsKCgkJCQkvLyBhbHBoYSBibGVuZAoKCQkJCWNvbG9yX3MucmdidFJlZCA9IChCWVRFKSgoKGNvbG9yX3QucmdidFJlZCAtIGNvbG9yX3MucmdidFJlZCkgKiBhbHBoYSArIChjb2xvcl9zLnJnYnRSZWQgPDwgOCkpID4+IDgpOwoJCQkJY29sb3Jfcy5yZ2J0R3JlZW4gPSAoQllURSkoKChjb2xvcl90LnJnYnRHcmVlbiAtIGNvbG9yX3MucmdidEdyZWVuKSAqIGFscGhhICsgKGNvbG9yX3MucmdidEdyZWVuIDw8IDgpKSA+PiA4KTsKCQkJCWNvbG9yX3MucmdidEJsdWUgPSAoQllURSkoKChjb2xvcl90LnJnYnRCbHVlIC0gY29sb3Jfcy5yZ2J0Qmx1ZSkgKiBhbHBoYSArIChjb2xvcl9zLnJnYnRCbHVlIDw8IDgpKSA+PiA4KTsKCgkJCQkvLyBjb252ZXJ0IDI0LWJpdCBjb2xvciBiYWNrIHRvIDE2LWJpdAoKCQkJCSp0bXAxID0gUkdCNTY1KGNvbG9yX3MucmdidFJlZCwgY29sb3Jfcy5yZ2J0R3JlZW4sIGNvbG9yX3MucmdidEJsdWUpOwoJCQl9CgoJCQlkc3RfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYik7CgkJCXNyY19iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmNfZGliKTsKCQl9Cgl9CgkKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgMjQtYml0Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnN0YXRpYyBCT09MIApDb21iaW5lMjQoRklCSVRNQVAgKmRzdF9kaWIsIEZJQklUTUFQICpzcmNfZGliLCB1bnNpZ25lZCB4LCB1bnNpZ25lZCB5LCB1bnNpZ25lZCBhbHBoYSkgewoJLy8gY2hlY2sgdGhlIGJpdCBkZXB0aCBvZiBzcmMgYW5kIGRzdCBpbWFnZXMKCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRzdF9kaWIpICE9IDI0KSB8fCAoRnJlZUltYWdlX0dldEJQUChzcmNfZGliKSAhPSAyNCkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJLy8gY2hlY2sgdGhlIHNpemUgb2Ygc3JjIGltYWdlCglpZigoeCArIEZyZWVJbWFnZV9HZXRXaWR0aChzcmNfZGliKSA+IEZyZWVJbWFnZV9HZXRXaWR0aChkc3RfZGliKSkgfHwgKHkgKyBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpID4gRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKSkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0Qml0cyhkc3RfZGliKSArICgoRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKSAtIEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYikgLSB5KSAqIEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKSkgKyAoeCAqIDMpOwoJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0Qml0cyhzcmNfZGliKTsJCgoJaWYoYWxwaGEgPiAyNTUpIHsKCQkvLyBjb21iaW5lIGltYWdlcwoJCWZvcih1bnNpZ25lZCByb3dzID0gMDsgcm93cyA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYik7IHJvd3MrKykgewoJCQltZW1jcHkoZHN0X2JpdHMsIHNyY19iaXRzLCBGcmVlSW1hZ2VfR2V0TGluZShzcmNfZGliKSk7CgoJCQlkc3RfYml0cyArPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYik7CgkJCXNyY19iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmNfZGliKTsKCQl9Cgl9IGVsc2UgewoJCS8vIGFscGhhIGJsZW5kIGltYWdlcwoJCWZvcih1bnNpZ25lZCByb3dzID0gMDsgcm93cyA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjX2RpYik7IHJvd3MrKykgewoJCQlmb3IgKHVuc2lnbmVkIGNvbHMgPSAwOyBjb2xzIDwgRnJlZUltYWdlX0dldExpbmUoc3JjX2RpYik7IGNvbHMrKykgewkJCQkJCQkKCQkJCWRzdF9iaXRzW2NvbHNdID0gKEJZVEUpKCgoc3JjX2JpdHNbY29sc10gLSBkc3RfYml0c1tjb2xzXSkgKiBhbHBoYSArIChkc3RfYml0c1tjb2xzXSA8PCA4KSkgPj4gOCk7CgkJCX0KCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0KCglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIDMyLWJpdAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgQk9PTCAKQ29tYmluZTMyKEZJQklUTUFQICpkc3RfZGliLCBGSUJJVE1BUCAqc3JjX2RpYiwgdW5zaWduZWQgeCwgdW5zaWduZWQgeSwgdW5zaWduZWQgYWxwaGEpIHsKCS8vIGNoZWNrIHRoZSBiaXQgZGVwdGggb2Ygc3JjIGFuZCBkc3QgaW1hZ2VzCglpZigoRnJlZUltYWdlX0dldEJQUChkc3RfZGliKSAhPSAzMikgfHwgKEZyZWVJbWFnZV9HZXRCUFAoc3JjX2RpYikgIT0gMzIpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHNyYyBpbWFnZQoJaWYoKHggKyBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjX2RpYikgPiBGcmVlSW1hZ2VfR2V0V2lkdGgoZHN0X2RpYikpIHx8ICh5ICsgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKSA+IEZyZWVJbWFnZV9HZXRIZWlnaHQoZHN0X2RpYikpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZHN0X2RpYikgKyAoKEZyZWVJbWFnZV9HZXRIZWlnaHQoZHN0X2RpYikgLSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpIC0geSkgKiBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYikpICsgKHggKiA0KTsKCUJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoc3JjX2RpYik7CQoKCWlmIChhbHBoYSA+IDI1NSkgewoJCS8vIGNvbWJpbmUgaW1hZ2VzCgkJZm9yKHVuc2lnbmVkIHJvd3MgPSAwOyByb3dzIDwgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKTsgcm93cysrKSB7CgkJCW1lbWNweShkc3RfYml0cywgc3JjX2JpdHMsIEZyZWVJbWFnZV9HZXRMaW5lKHNyY19kaWIpKTsKCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0gZWxzZSB7CgkJLy8gYWxwaGEgYmxlbmQgaW1hZ2VzCgkJZm9yKHVuc2lnbmVkIHJvd3MgPSAwOyByb3dzIDwgRnJlZUltYWdlX0dldEhlaWdodChzcmNfZGliKTsgcm93cysrKSB7CgkJCWZvcih1bnNpZ25lZCBjb2xzID0gMDsgY29scyA8IEZyZWVJbWFnZV9HZXRMaW5lKHNyY19kaWIpOyBjb2xzKyspIHsKCQkJCWRzdF9iaXRzW2NvbHNdID0gKEJZVEUpKCgoc3JjX2JpdHNbY29sc10gLSBkc3RfYml0c1tjb2xzXSkgKiBhbHBoYSArIChkc3RfYml0c1tjb2xzXSA8PCA4KSkgPj4gOCk7CgkJCX0KCgkJCWRzdF9iaXRzICs9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3RfZGliKTsKCQkJc3JjX2JpdHMgKz0gRnJlZUltYWdlX0dldFBpdGNoKHNyY19kaWIpOwoJCX0KCX0KCglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIEFueSB0eXBlIG90aGVyIHRoYW4gRklCSVRNQVAKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIEJPT0wgCkNvbWJpbmVTYW1lVHlwZShGSUJJVE1BUCAqZHN0X2RpYiwgRklCSVRNQVAgKnNyY19kaWIsIHVuc2lnbmVkIHgsIHVuc2lnbmVkIHkpIHsKCS8vIGNoZWNrIHRoZSBiaXQgZGVwdGggb2Ygc3JjIGFuZCBkc3QgaW1hZ2VzCglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRzdF9kaWIpICE9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjX2RpYikpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJdW5zaWduZWQgc3JjX3dpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmNfZGliKTsKCXVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyY19kaWIpOwoJdW5zaWduZWQgc3JjX3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmNfZGliKTsKCXVuc2lnbmVkIHNyY19saW5lICAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmNfZGliKTsKCXVuc2lnbmVkIGRzdF93aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZHN0X2RpYik7Cgl1bnNpZ25lZCBkc3RfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkc3RfZGliKTsKCXVuc2lnbmVkIGRzdF9waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0X2RpYik7CgkKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHNyYyBpbWFnZQoJaWYoKHggKyBzcmNfd2lkdGggPiBkc3Rfd2lkdGgpIHx8ICh5ICsgc3JjX2hlaWdodCA+IGRzdF9oZWlnaHQpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQkKCglCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdF9kaWIpICsgKChkc3RfaGVpZ2h0IC0gc3JjX2hlaWdodCAtIHkpICogZHN0X3BpdGNoKSArICh4ICogKHNyY19saW5lIC8gc3JjX3dpZHRoKSk7CglCWVRFICpzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyY19kaWIpOwkKCgkvLyBjb21iaW5lIGltYWdlcwkKCWZvcih1bnNpZ25lZCByb3dzID0gMDsgcm93cyA8IHNyY19oZWlnaHQ7IHJvd3MrKykgewoJCW1lbWNweShkc3RfYml0cywgc3JjX2JpdHMsIHNyY19saW5lKTsKCgkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIEZyZWVJbWFnZSBpbnRlcmZhY2UKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCkNvcHkgYSBzdWIgcGFydCBvZiB0aGUgY3VycmVudCBpbWFnZSBhbmQgcmV0dXJucyBpdCBhcyBhIEZJQklUTUFQKi4KV29ya3Mgd2l0aCBhbnkgYml0bWFwIHR5cGUuCkBwYXJhbSBsZWZ0IFNwZWNpZmllcyB0aGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgY3JvcHBlZCByZWN0YW5nbGUuIApAcGFyYW0gdG9wIFNwZWNpZmllcyB0aGUgdG9wIHBvc2l0aW9uIG9mIHRoZSBjcm9wcGVkIHJlY3RhbmdsZS4gCkBwYXJhbSByaWdodCBTcGVjaWZpZXMgdGhlIHJpZ2h0IHBvc2l0aW9uIG9mIHRoZSBjcm9wcGVkIHJlY3RhbmdsZS4gCkBwYXJhbSBib3R0b20gU3BlY2lmaWVzIHRoZSBib3R0b20gcG9zaXRpb24gb2YgdGhlIGNyb3BwZWQgcmVjdGFuZ2xlLiAKQHJldHVybiBSZXR1cm5zIHRoZSBzdWJpbWFnZSBpZiBzdWNjZXNzZnVsLCBOVUxMIG90aGVyd2lzZS4KKi8KRklCSVRNQVAgKiBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9Db3B5KEZJQklUTUFQICpzcmMsIGludCBsZWZ0LCBpbnQgdG9wLCBpbnQgcmlnaHQsIGludCBib3R0b20pIHsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpKSAKCQlyZXR1cm4gTlVMTDsKCgkvLyBub3JtYWxpemUgdGhlIHJlY3RhbmdsZQoJaWYocmlnaHQgPCBsZWZ0KSB7CgkJSU5QTEFDRVNXQVAobGVmdCwgcmlnaHQpOwoJfQoJaWYoYm90dG9tIDwgdG9wKSB7CgkJSU5QTEFDRVNXQVAodG9wLCBib3R0b20pOwoJfQoJLy8gY2hlY2sgdGhlIHNpemUgb2YgdGhlIHN1YiBpbWFnZQoJaW50IHNyY193aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWludCBzcmNfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoJaWYoKGxlZnQgPCAwKSB8fCAocmlnaHQgPiBzcmNfd2lkdGgpIHx8ICh0b3AgPCAwKSB8fCAoYm90dG9tID4gc3JjX2hlaWdodCkpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBhbGxvY2F0ZSB0aGUgc3ViIGltYWdlCgl1bnNpZ25lZCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKHNyYyk7CglpbnQgZHN0X3dpZHRoID0gKHJpZ2h0IC0gbGVmdCk7CglpbnQgZHN0X2hlaWdodCA9IChib3R0b20gLSB0b3ApOwoKCUZJQklUTUFQICpkc3QgPSAKCQlGcmVlSW1hZ2VfQWxsb2NhdGVUKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKSwgCgkJCQkJCQlkc3Rfd2lkdGgsIAoJCQkJCQkJZHN0X2hlaWdodCwgCgkJCQkJCQlicHAsIAoJCQkJCQkJRnJlZUltYWdlX0dldFJlZE1hc2soc3JjKSwgRnJlZUltYWdlX0dldEdyZWVuTWFzayhzcmMpLCBGcmVlSW1hZ2VfR2V0Qmx1ZU1hc2soc3JjKSk7CgoJaWYoTlVMTCA9PSBkc3QpIHJldHVybiBOVUxMOwoKCS8vIGdldCB0aGUgZGltZW5zaW9ucwoJaW50IGRzdF9saW5lID0gRnJlZUltYWdlX0dldExpbmUoZHN0KTsKCWludCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KTsKCWludCBzcmNfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCgkvLyBnZXQgdGhlIHBvaW50ZXJzIHRvIHRoZSBiaXRzIGFuZCBzdWNoCgoJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCBzcmNfaGVpZ2h0IC0gdG9wIC0gZHN0X2hlaWdodCk7Cglzd2l0Y2goYnBwKSB7CgkJY2FzZSAxOgoJCQkvLyBwb2ludCB0byB4ID0gMAoJCQlicmVhazsKCgkJY2FzZSA0OgoJCQkvLyBwb2ludCB0byB4ID0gMAoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQl7CgkJCS8vIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBlciBwaXhlbAoJCQl1bnNpZ25lZCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJCQkvLyBwb2ludCB0byB4ID0gbGVmdAoJCQlzcmNfYml0cyArPSBsZWZ0ICogYnl0ZXNwcDsKCQl9CgkJYnJlYWs7Cgl9CgoJLy8gcG9pbnQgdG8geCA9IDAKCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCgkvLyBjb3B5IHRoZSBwYWxldHRlCgoJbWVtY3B5KEZyZWVJbWFnZV9HZXRQYWxldHRlKGRzdCksIEZyZWVJbWFnZV9HZXRQYWxldHRlKHNyYyksIEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKHNyYykgKiBzaXplb2YoUkdCUVVBRCkpOwoKCS8vIGNvcHkgdGhlIGJpdHMKCWlmKGJwcCA9PSAxKSB7CgkJQk9PTCB2YWx1ZTsKCQl1bnNpZ25lZCB5X3NyYywgeV9kc3Q7CgoJCWZvcihpbnQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJeV9zcmMgPSB5ICogc3JjX3BpdGNoOwoJCQl5X2RzdCA9IHkgKiBkc3RfcGl0Y2g7CgkJCWZvcihpbnQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJLy8gZ2V0IGJpdCBhdCAoeSwgeCkgaW4gc3JjIGltYWdlCgkJCQl2YWx1ZSA9IChzcmNfYml0c1t5X3NyYyArICgobGVmdCt4KSA+PiAzKV0gJiAoMHg4MCA+PiAoKGxlZnQreCkgJiAweDA3KSkpICE9IDA7CgkJCQkvLyBzZXQgYml0IGF0ICh5LCB4KSBpbiBkc3QgaW1hZ2UKCQkJCXZhbHVlID8gZHN0X2JpdHNbeV9kc3QgKyAoeCA+PiAzKV0gfD0gKDB4ODAgPj4gKHggJiAweDcpKSA6IGRzdF9iaXRzW3lfZHN0ICsgKHggPj4gMyldICY9ICgweGZmN2YgPj4gKHggJiAweDcpKTsKCQkJfQoJCX0KCX0KCgllbHNlIGlmKGJwcCA9PSA0KSB7CgkJQllURSBzaGlmdCwgdmFsdWU7CgkJdW5zaWduZWQgeV9zcmMsIHlfZHN0OwoKCQlmb3IoaW50IHkgPSAwOyB5IDwgZHN0X2hlaWdodDsgeSsrKSB7CgkJCXlfc3JjID0geSAqIHNyY19waXRjaDsKCQkJeV9kc3QgPSB5ICogZHN0X3BpdGNoOwoJCQlmb3IoaW50IHggPSAwOyB4IDwgZHN0X3dpZHRoOyB4KyspIHsKCQkJCS8vIGdldCBuaWJibGUgYXQgKHksIHgpIGluIHNyYyBpbWFnZQoJCQkJc2hpZnQgPSAoQllURSkoKDEgLSAobGVmdCt4KSAlIDIpIDw8IDIpOwoJCQkJdmFsdWUgPSAoc3JjX2JpdHNbeV9zcmMgKyAoKGxlZnQreCkgPj4gMSldICYgKDB4MEYgPDwgc2hpZnQpKSA+PiBzaGlmdDsKCQkJCS8vIHNldCBuaWJibGUgYXQgKHksIHgpIGluIGRzdCBpbWFnZQoJCQkJc2hpZnQgPSAoQllURSkoKDEgLSB4ICUgMikgPDwgMik7CgkJCQlkc3RfYml0c1t5X2RzdCArICh4ID4+IDEpXSAmPSB+KDB4MEYgPDwgc2hpZnQpOwoJCQkJZHN0X2JpdHNbeV9kc3QgKyAoeCA+PiAxKV0gfD0gKCh2YWx1ZSAmIDB4MEYpIDw8IHNoaWZ0KTsKCQkJfQoJCX0KCX0KCgllbHNlIGlmKGJwcCA+PSA4KSB7CgkJZm9yKGludCB5ID0gMDsgeSA8IGRzdF9oZWlnaHQ7IHkrKykgewoJCQltZW1jcHkoZHN0X2JpdHMgKyAoeSAqIGRzdF9waXRjaCksIHNyY19iaXRzICsgKHkgKiBzcmNfcGl0Y2gpLCBkc3RfbGluZSk7CgkJfQoJfQoKCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CglGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShkc3QsIHNyYyk7CgkKCS8vIGNvcHkgdHJhbnNwYXJlbmN5IHRhYmxlIAoJRnJlZUltYWdlX1NldFRyYW5zcGFyZW5jeVRhYmxlKGRzdCwgRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeVRhYmxlKHNyYyksIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lDb3VudChzcmMpKTsKCQoJLy8gY29weSBiYWNrZ3JvdW5kIGNvbG9yIAoJUkdCUVVBRCBia2NvbG9yOyAKCWlmKCBGcmVlSW1hZ2VfR2V0QmFja2dyb3VuZENvbG9yKHNyYywgJmJrY29sb3IpICkgewoJCUZyZWVJbWFnZV9TZXRCYWNrZ3JvdW5kQ29sb3IoZHN0LCAmYmtjb2xvcik7IAoJfQoJCgkvLyBjbG9uZSByZXNvbHV0aW9uIAoJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclgoZHN0LCBGcmVlSW1hZ2VfR2V0RG90c1Blck1ldGVyWChzcmMpKTsgCglGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWShkc3QsIEZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJZKHNyYykpOyAKCQoJLy8gY2xvbmUgSUNDIHByb2ZpbGUgCglGSUlDQ1BST0ZJTEUgKnNyY19wcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoc3JjKTsgCglGSUlDQ1BST0ZJTEUgKmRzdF9wcm9maWxlID0gRnJlZUltYWdlX0NyZWF0ZUlDQ1Byb2ZpbGUoZHN0LCBzcmNfcHJvZmlsZS0+ZGF0YSwgc3JjX3Byb2ZpbGUtPnNpemUpOyAKCWRzdF9wcm9maWxlLT5mbGFncyA9IHNyY19wcm9maWxlLT5mbGFnczsgCgkKCXJldHVybiBkc3Q7Cn0KCi8qKgpBbHBoYSBibGVuZCBvciBjb21iaW5lIGEgc3ViIHBhcnQgaW1hZ2Ugd2l0aCB0aGUgY3VycmVudCBpbWFnZS4KVGhlIGJpdCBkZXB0aCBvZiBkc3QgYml0bWFwIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBiaXQgZGVwdGggb2Ygc3JjLiAKVXBwZXIgcHJvbW90aW9uIG9mIHNyYyBpcyBkb25lIGludGVybmFsbHkuIFN1cHBvcnRlZCBiaXQgZGVwdGggZXF1YWxzIHRvIDEsIDQsIDgsIDE2LCAyNCBvciAzMi4KQHBhcmFtIHNyYyBTb3VyY2Ugc3ViaW1hZ2UKQHBhcmFtIGxlZnQgU3BlY2lmaWVzIHRoZSBsZWZ0IHBvc2l0aW9uIG9mIHRoZSBzdWIgaW1hZ2UuIApAcGFyYW0gdG9wIFNwZWNpZmllcyB0aGUgdG9wIHBvc2l0aW9uIG9mIHRoZSBzdWIgaW1hZ2UuIApAcGFyYW0gYWxwaGEgQWxwaGEgYmxlbmQgZmFjdG9yLiBUaGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBpbWFnZXMgYXJlIGFscGhhIGJsZW5kZWQgaWYgCmFscGhhID0gMC4uMjU1LiBJZiBhbHBoYSA+IDI1NSwgdGhlbiB0aGUgc291cmNlIGltYWdlIGlzIGNvbWJpbmVkIHRvIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoqLwpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX1Bhc3RlKEZJQklUTUFQICpkc3QsIEZJQklUTUFQICpzcmMsIGludCBsZWZ0LCBpbnQgdG9wLCBpbnQgYWxwaGEpIHsKCUJPT0wgYlJlc3VsdCA9IEZBTFNFOwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKHNyYykgfHwgIUZyZWVJbWFnZV9IYXNQaXhlbHMoZHN0KSkgcmV0dXJuIEZBTFNFOwoKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHNyYyBpbWFnZQoJaWYoKGxlZnQgPCAwKSB8fCAodG9wIDwgMCkpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CglpZigobGVmdCArIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpID4gRnJlZUltYWdlX0dldFdpZHRoKGRzdCkpIHx8ICh0b3AgKyBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYykgPiBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRzdCkpKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vIGNoZWNrIGRhdGEgdHlwZQoJY29uc3QgRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRzdCk7CglpZihpbWFnZV90eXBlICE9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKSkgewoJCS8vIG5vIGNvbnZlcnNpb24gYmV0d2VlbiBkYXRhIHR5cGUgaXMgZG9uZQoJCXJldHVybiBGQUxTRTsKCX0KCglpZihpbWFnZV90eXBlID09IEZJVF9CSVRNQVApIHsKCQlGSUJJVE1BUCAqY2xvbmUgPSBOVUxMOwoKCQkvLyBjaGVjayB0aGUgYml0IGRlcHRoIG9mIHNyYyBhbmQgZHN0IGltYWdlcwoJCXVuc2lnbmVkIGJwcF9zcmMgPSBGcmVlSW1hZ2VfR2V0QlBQKHNyYyk7CgkJdW5zaWduZWQgYnBwX2RzdCA9IEZyZWVJbWFnZV9HZXRCUFAoZHN0KTsKCQlCT09MIGlzUkdCNTY1ID0gRkFMU0U7CgoJCWlmICgoRnJlZUltYWdlX0dldFJlZE1hc2soZHN0KSA9PSBGSTE2XzU2NV9SRURfTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRHcmVlbk1hc2soZHN0KSA9PSBGSTE2XzU2NV9HUkVFTl9NQVNLKSAmJiAoRnJlZUltYWdlX0dldEJsdWVNYXNrKGRzdCkgPT0gRkkxNl81NjVfQkxVRV9NQVNLKSkgewoJCQlpc1JHQjU2NSA9IFRSVUU7CgkJfSBlbHNlIHsKCQkJLy8gaW5jbHVkZXMgY2FzZSB3aGVyZSBhbGwgdGhlIG1hc2tzIGFyZSAwCgkJCWlzUkdCNTY1ID0gRkFMU0U7CgkJfQoKCQkvLyBwZXJmb3JtIHByb21vdGlvbiBpZiBuZWVkZWQKCQlpZihicHBfZHN0ID09IGJwcF9zcmMpIHsKCQkJY2xvbmUgPSBzcmM7CgkJfSBlbHNlIGlmKGJwcF9kc3QgPiBicHBfc3JjKSB7CgkJCS8vIHBlcmZvcm0gcHJvbW90aW9uCgkJCXN3aXRjaChicHBfZHN0KSB7CgkJCQljYXNlIDQ6CgkJCQkJY2xvbmUgPSBGcmVlSW1hZ2VfQ29udmVydFRvNEJpdHMoc3JjKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgODoKCQkJCQljbG9uZSA9IEZyZWVJbWFnZV9Db252ZXJ0VG84Qml0cyhzcmMpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAxNjoKCQkJCQlpZiAoaXNSR0I1NjUpIHsKCQkJCQkJY2xvbmUgPSBGcmVlSW1hZ2VfQ29udmVydFRvMTZCaXRzNTY1KHNyYyk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJLy8gaW5jbHVkZXMgY2FzZSB3aGVyZSBhbGwgdGhlIG1hc2tzIGFyZSAwCgkJCQkJCWNsb25lID0gRnJlZUltYWdlX0NvbnZlcnRUbzE2Qml0czU1NShzcmMpOwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgMjQ6CgkJCQkJY2xvbmUgPSBGcmVlSW1hZ2VfQ29udmVydFRvMjRCaXRzKHNyYyk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIDMyOgoJCQkJCWNsb25lID0gRnJlZUltYWdlX0NvbnZlcnRUbzMyQml0cyhzcmMpOwoJCQkJCWJyZWFrOwoJCQkJZGVmYXVsdDoKCQkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9IGVsc2UgewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQlpZighY2xvbmUpIHJldHVybiBGQUxTRTsKCgkJLy8gcGFzdGUgc3JjIHRvIGRzdAoJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRzdCkpIHsKCQkJY2FzZSAxOgoJCQkJYlJlc3VsdCA9IENvbWJpbmUxKGRzdCwgY2xvbmUsICh1bnNpZ25lZClsZWZ0LCAodW5zaWduZWQpdG9wLCAodW5zaWduZWQpYWxwaGEpOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDoKCQkJCWJSZXN1bHQgPSBDb21iaW5lNChkc3QsIGNsb25lLCAodW5zaWduZWQpbGVmdCwgKHVuc2lnbmVkKXRvcCwgKHVuc2lnbmVkKWFscGhhKTsKCQkJCWJyZWFrOwoJCQljYXNlIDg6CgkJCQliUmVzdWx0ID0gQ29tYmluZTgoZHN0LCBjbG9uZSwgKHVuc2lnbmVkKWxlZnQsICh1bnNpZ25lZCl0b3AsICh1bnNpZ25lZClhbHBoYSk7CgkJCQlicmVhazsKCQkJY2FzZSAxNjoKCQkJCWlmIChpc1JHQjU2NSkgewoJCQkJCWJSZXN1bHQgPSBDb21iaW5lMTZfNTY1KGRzdCwgY2xvbmUsICh1bnNpZ25lZClsZWZ0LCAodW5zaWduZWQpdG9wLCAodW5zaWduZWQpYWxwaGEpOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyBpbmNsdWRlcyBjYXNlIHdoZXJlIGFsbCB0aGUgbWFza3MgYXJlIDAKCQkJCQliUmVzdWx0ID0gQ29tYmluZTE2XzU1NShkc3QsIGNsb25lLCAodW5zaWduZWQpbGVmdCwgKHVuc2lnbmVkKXRvcCwgKHVuc2lnbmVkKWFscGhhKTsKCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlIDI0OgoJCQkJYlJlc3VsdCA9IENvbWJpbmUyNChkc3QsIGNsb25lLCAodW5zaWduZWQpbGVmdCwgKHVuc2lnbmVkKXRvcCwgKHVuc2lnbmVkKWFscGhhKTsKCQkJCWJyZWFrOwoJCQljYXNlIDMyOgoJCQkJYlJlc3VsdCA9IENvbWJpbmUzMihkc3QsIGNsb25lLCAodW5zaWduZWQpbGVmdCwgKHVuc2lnbmVkKXRvcCwgKHVuc2lnbmVkKWFscGhhKTsKCQkJCWJyZWFrOwoJCX0KCgkJaWYoY2xvbmUgIT0gc3JjKQoJCQlGcmVlSW1hZ2VfVW5sb2FkKGNsb25lKTsKCgkJfQoJZWxzZSB7CS8vIGFueSB0eXBlIG90aGVyIHRoYW4gRklUQklUTUFQCgkJYlJlc3VsdCA9IENvbWJpbmVTYW1lVHlwZShkc3QsIHNyYywgKHVuc2lnbmVkKWxlZnQsICh1bnNpZ25lZCl0b3ApOwoJfQoKCXJldHVybiBiUmVzdWx0Owp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKiogQGJyaWVmIENyZWF0ZXMgYSBkeW5hbWljIHJlYWQvd3JpdGUgdmlldyBpbnRvIGEgRnJlZUltYWdlIGJpdG1hcC4KCiBBIGR5bmFtaWMgdmlldyBpcyBhIEZyZWVJbWFnZSBiaXRtYXAgd2l0aCBpdHMgb3duIHdpZHRoIGFuZCBoZWlnaHQsIHRoYXQsCiBob3dldmVyLCBzaGFyZXMgaXRzIGJpdHMgd2l0aCBhbm90aGVyIEZyZWVJbWFnZSBiaXRtYXAuIFR5cGljYWxseSwgdmlld3MKIGFyZSB1c2VkIHRvIGRlZmluZSBvbmUgb3IgbW9yZSByZWN0YW5ndWxhciBzdWItaW1hZ2VzIG9mIGFuIGV4aXN0aW5nCiBiaXRtYXAuIEFsbCBGcmVlSW1hZ2Ugb3BlcmF0aW9ucywgbGlrZSBzYXZpbmcsIGRpc3BsYXlpbmcgYW5kIGFsbCB0aGUKIHRvb2xraXQgZnVuY3Rpb25zLCB3aGVuIGFwcGxpZWQgdG8gdGhlIHZpZXcsIG9ubHkgYWZmZWN0IHRoZSB2aWV3J3MKIHJlY3Rhbmd1bGFyIGFyZWEuCgogQWx0aG91Z2ggdGhlIHZpZXcncyBiYWNraW5nIGltYWdlJ3MgYml0cyBub3QgbmVlZCB0byBiZSBjb3BpZWQgYXJvdW5kLAogd2hpY2ggbWFrZXMgdGhlIHZpZXcgbXVjaCBmYXN0ZXIgdGhhbiBzaW1pbGFyIHNvbHV0aW9ucyB1c2luZwogRnJlZUltYWdlX0NvcHksIGEgdmlldyB1c2VzIHNvbWUgcHJpdmF0ZSBtZW1vcnkgdGhhdCBuZWVkcyB0byBiZSBmcmVlZCBieQogY2FsbGluZyBGcmVlSW1hZ2VfVW5sb2FkIG9uIHRoZSB2aWV3J3MgaGFuZGxlIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzLgoKIE9ubHkgdGhlIGJhY2tpbmcgaW1hZ2UncyBwaXhlbHMgYXJlIHNoYXJlZCBieSB0aGUgdmlldy4gRm9yIGFsbCBvdGhlciBpbWFnZQogZGF0YSwgbm90YWJseSBmb3IgdGhlIHJlc29sdXRpb24sIGJhY2tncm91bmQgY29sb3IsIGNvbG9yIHBhbGV0dGUsCiB0cmFuc3BhcmVuY3kgdGFibGUgYW5kIGZvciB0aGUgSUNDIHByb2ZpbGUsIHRoZSB2aWV3IGdldHMgYSBwcml2YXRlIGNvcHkKIG9mIHRoZSBkYXRhLiBCeSBkZWZhdWx0LCB0aGUgYmFja2luZyBpbWFnZSdzIG1ldGFkYXRhIGlzIE5PVCBjb3BpZWQgdG8KIHRoZSB2aWV3LgoKIEFzIHdpdGggYWxsIEZyZWVJbWFnZSBmdW5jdGlvbnMgdGhhdCB0YWtlIGEgcmVjdGFuZ2xlIHJlZ2lvbiwgdG9wIGFuZCBsZWZ0CiBwb3NpdGlvbnMgYXJlIGluY2x1ZGVkLCB3aGVyZWFzIHJpZ2h0IGFuZCBib3R0b20gcG9zaXRpb25zIGFyZSBleGNsdWRlZAogZnJvbSB0aGUgcmVjdGFuZ2xlIGFyZWEuCgogU2luY2UgdGhlIG1lbW9yeSBibG9jayBzaGFyZWQgYnkgdGhlIGJhY2tpbmcgaW1hZ2UgYW5kIHRoZSB2aWV3IG11c3Qgc3RhcnQKIGF0IGEgYnl0ZSBib3VuZGFyeSwgdGhlIHZhbHVlIG9mIHBhcmFtZXRlciBsZWZ0IG11c3QgYmUgYSBtdWx0aXBsZSBvZiA4CiBmb3IgMS1iaXQgaW1hZ2VzIGFuZCBhIG11bHRpcGxlIG9mIDIgZm9yIDQtYml0IGltYWdlcy4KCiBAcGFyYW0gZGliIFRoZSBGcmVlSW1hZ2UgYml0bWFwIG9uIHdoaWNoIHRvIGNyZWF0ZSB0aGUgdmlldy4KIEBwYXJhbSBsZWZ0IFRoZSBsZWZ0IHBvc2l0aW9uIG9mIHRoZSB2aWV3J3MgYXJlYS4KIEBwYXJhbSB0b3AgVGhlIHRvcCBwb3NpdGlvbiBvZiB0aGUgdmlldydzIGFyZWEuCiBAcGFyYW0gcmlnaHQgVGhlIHJpZ2h0IHBvc2l0aW9uIG9mIHRoZSB2aWV3J3MgYXJlYS4KIEBwYXJhbSBib3R0b20gVGhlIGJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgdmlldydzIGFyZWEuCiBAcmV0dXJuIFJldHVybnMgYSBoYW5kbGUgdG8gdGhlIG5ld2x5IGNyZWF0ZWQgdmlldyBvciBOVUxMIGlmIHRoZSB2aWV3CiB3YXMgbm90IGNyZWF0ZWQuCiAqLwpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ3JlYXRlVmlldyhGSUJJVE1BUCAqZGliLCB1bnNpZ25lZCBsZWZ0LCB1bnNpZ25lZCB0b3AsIHVuc2lnbmVkIHJpZ2h0LCB1bnNpZ25lZCBib3R0b20pIHsKCWlmICghRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gbm9ybWFsaXplIHRoZSByZWN0YW5nbGUKCWlmIChyaWdodCA8IGxlZnQpIHsKCQlJTlBMQUNFU1dBUChsZWZ0LCByaWdodCk7Cgl9CglpZiAoYm90dG9tIDwgdG9wKSB7CgkJSU5QTEFDRVNXQVAodG9wLCBib3R0b20pOwoJfQoKCS8vIGNoZWNrIHRoZSBzaXplIG9mIHRoZSBzdWIgaW1hZ2UKCXVuc2lnbmVkIHdpZHRoID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CglpZiAobGVmdCA8IDAgfHwgcmlnaHQgPiB3aWR0aCB8fCB0b3AgPCAwIHx8IGJvdHRvbSA+IGhlaWdodCkgewoJCXJldHVybiBOVUxMOwoJfQoKCXVuc2lnbmVkIGJwcCA9IEZyZWVJbWFnZV9HZXRCUFAoZGliKTsKCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSBib3R0b20pOwoJc3dpdGNoIChicHApIHsKCQljYXNlIDE6CgkJCWlmIChsZWZ0ICUgOCAhPSAwKSB7CgkJCQkvLyB2aWV3IGNhbiBvbmx5IHN0YXJ0IGF0IGEgYnl0ZSBib3VuZGFyeQoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQkJYml0cyArPSAobGVmdCAvIDgpOwoJCQlicmVhazsKCQljYXNlIDQ6CgkJCWlmIChsZWZ0ICUgMiAhPSAwKSB7CgkJCQkvLyB2aWV3IGNhbiBvbmx5IHN0YXJ0IGF0IGEgYnl0ZSBib3VuZGFyeQoJCQkJcmV0dXJuIE5VTEw7CgkJCQl9CgkJCWJpdHMgKz0gKGxlZnQgLyAyKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJYml0cyArPSBsZWZ0ICogKGJwcCAvIDgpOwoJCQlicmVhazsKCX0KCglGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyRm9yQml0cyhiaXRzLCBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKSwgRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpLCAKCQlyaWdodCAtIGxlZnQsIGJvdHRvbSAtIHRvcCwgCgkJYnBwLCAKCQlGcmVlSW1hZ2VfR2V0UmVkTWFzayhkaWIpLCBGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKGRpYiksIEZyZWVJbWFnZV9HZXRCbHVlTWFzayhkaWIpKTsKCglpZiAoZHN0ID09IE5VTEwpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBjb3B5IHNvbWUgYmFzaWMgaW1hZ2UgcHJvcGVydGllcyBuZWVkZWQgZm9yIGRpc3BsYXlpbmcgYW5kIHNhdmluZwoKCS8vIHJlc29sdXRpb24KCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJYKGRzdCwgRnJlZUltYWdlX0dldERvdHNQZXJNZXRlclgoZGliKSk7CglGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWShkc3QsIEZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJZKGRpYikpOwoKCS8vIGJhY2tncm91bmQgY29sb3IKCVJHQlFVQUQgYmtjb2xvcjsKCWlmIChGcmVlSW1hZ2VfR2V0QmFja2dyb3VuZENvbG9yKGRpYiwgJmJrY29sb3IpKSB7CgkJRnJlZUltYWdlX1NldEJhY2tncm91bmRDb2xvcihkc3QsICZia2NvbG9yKTsKCX0KCgkvLyBwYWxldHRlCgltZW1jcHkoRnJlZUltYWdlX0dldFBhbGV0dGUoZHN0KSwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSwgRnJlZUltYWdlX0dldENvbG9yc1VzZWQoZGliKSAqIHNpemVvZihSR0JRVUFEKSk7CgoJLy8gdHJhbnNwYXJlbmN5IHRhYmxlCglGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbmN5VGFibGUoZHN0LCBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZGliKSwgRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeUNvdW50KGRpYikpOwoKCS8vIElDQyBwcm9maWxlCglGSUlDQ1BST0ZJTEUgKnNyY19wcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoZGliKTsKCUZJSUNDUFJPRklMRSAqZHN0X3Byb2ZpbGUgPSBGcmVlSW1hZ2VfQ3JlYXRlSUNDUHJvZmlsZShkc3QsIHNyY19wcm9maWxlLT5kYXRhLCBzcmNfcHJvZmlsZS0+c2l6ZSk7Cglkc3RfcHJvZmlsZS0+ZmxhZ3MgPSBzcmNfcHJvZmlsZS0+ZmxhZ3M7CgoJcmV0dXJuIGRzdDsKfQo=