Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gVGFubmVyIEhlbGxhbmQgKHRhbm5lcmhlbGxhbmRAdXNlcnMuc2YubmV0KQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgc21hcnQgY29udmVydCBYIHRvIFJHQkFGCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0VG9SR0JBRihGSUJJVE1BUCAqZGliKSB7CglGSUJJVE1BUCAqc3JjID0gTlVMTDsKCUZJQklUTUFQICpkc3QgPSBOVUxMOwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikpIHJldHVybiBOVUxMOwoKCWNvbnN0IEZSRUVfSU1BR0VfVFlQRSBzcmNfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCgkvLyBjaGVjayBmb3IgYWxsb3dlZCBjb252ZXJzaW9ucyAKCXN3aXRjaChzcmNfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQl7CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSAzMi1iaXQKCQkJY29uc3QgRlJFRV9JTUFHRV9DT0xPUl9UWVBFIGNvbG9yX3R5cGUgPSBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRpYik7CgkJCWlmKGNvbG9yX3R5cGUgIT0gRklDX1JHQkFMUEhBKSB7CgkJCQlzcmMgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKGRpYik7CgkJCQlpZighc3JjKSByZXR1cm4gTlVMTDsKCQkJfSBlbHNlIHsKCQkJCXNyYyA9IGRpYjsKCQkJfQoJCQlicmVhazsKCQl9CgkJY2FzZSBGSVRfVUlOVDE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gMTYtYml0CgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCMTY6CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSA0OC1iaXQgUkdCCgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCQTE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gNjQtYml0IFJHQkEKCQkJc3JjID0gZGliOwoJCQlicmVhazsKCQljYXNlIEZJVF9GTE9BVDoKCQkJLy8gYWxsb3cgY29udmVyc2lvbiBmcm9tIDMyLWJpdCBmbG9hdAoJCQlzcmMgPSBkaWI7CgkJCWJyZWFrOwoJCWNhc2UgRklUX1JHQkY6CgkJCS8vIGFsbG93IGNvbnZlcnNpb24gZnJvbSA5Ni1iaXQgUkdCRgoJCQlzcmMgPSBkaWI7CgkJCWJyZWFrOwoJCWNhc2UgRklUX1JHQkFGOgoJCQkvLyBSR0JBRiB0eXBlIDogY2xvbmUgdGhlIHNyYwoJCQlyZXR1cm4gRnJlZUltYWdlX0Nsb25lKGRpYik7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXJldHVybiBOVUxMOwoJfQoKCS8vIGFsbG9jYXRlIGRzdCBpbWFnZQoKCWNvbnN0IHVuc2lnbmVkIHdpZHRoID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CgoJZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChGSVRfUkdCQUYsIHdpZHRoLCBoZWlnaHQpOwoJaWYoIWRzdCkgewoJCWlmKHNyYyAhPSBkaWIpIHsKCQkJRnJlZUltYWdlX1VubG9hZChzcmMpOwoJCX0KCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEoZHN0LCBzcmMpOwoKCS8vIGNvbnZlcnQgZnJvbSBzcmMgdHlwZSB0byBSR0JBRgoKCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRzdCk7CgoJc3dpdGNoKHNyY190eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCXsKCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGVyIHBpeGVsICg0IGZvciAzMi1iaXQpCgkJCWNvbnN0IHVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgoJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpOwoJCQlCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEJZVEUgKnNyY19waXhlbCA9IChCWVRFKilzcmNfYml0czsKCQkJCUZJUkdCQUYgKmRzdF9waXhlbCA9IChGSVJHQkFGKilkc3RfYml0czsKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBzY2FsZSB0byB0aGUgcmFuZ2UgWzAuLjFdCgkJCQkJZHN0X3BpeGVsLT5yZWQgICA9IChmbG9hdCkoc3JjX3BpeGVsW0ZJX1JHQkFfUkVEXSkgICAvIDI1NS4wRjsKCQkJCQlkc3RfcGl4ZWwtPmdyZWVuID0gKGZsb2F0KShzcmNfcGl4ZWxbRklfUkdCQV9HUkVFTl0pIC8gMjU1LjBGOwoJCQkJCWRzdF9waXhlbC0+Ymx1ZSAgPSAoZmxvYXQpKHNyY19waXhlbFtGSV9SR0JBX0JMVUVdKSAgLyAyNTUuMEY7CgkJCQkJZHN0X3BpeGVsLT5hbHBoYSA9IChmbG9hdCkoc3JjX3BpeGVsW0ZJX1JHQkFfQUxQSEFdKSAvIDI1NS4wRjsKCgkJCQkJc3JjX3BpeGVsICs9IGJ5dGVzcHA7CgkJCQkJZHN0X3BpeGVsKys7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1VJTlQxNjoKCQl7CgkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CgkJCUJZVEUgKmRzdF9iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgV09SRCAqc3JjX3BpeGVsID0gKFdPUkQqKXNyY19iaXRzOwoJCQkJRklSR0JBRiAqZHN0X3BpeGVsID0gKEZJUkdCQUYqKWRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBzY2FsZSB0byB0aGUgcmFuZ2UgWzAuLjFdCgkJCQkJY29uc3QgZmxvYXQgZHN0X3ZhbHVlID0gKGZsb2F0KXNyY19waXhlbFt4XSAvIDY1NTM1LjBGOwoJCQkJCWRzdF9waXhlbFt4XS5yZWQgICA9IGRzdF92YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSBkc3RfdmFsdWU7CgkJCQkJZHN0X3BpeGVsW3hdLmJsdWUgID0gZHN0X3ZhbHVlOwoJCQkJCWRzdF9waXhlbFt4XS5hbHBoYSA9IDEuMEY7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX1JHQjE2OgoJCXsKCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCQkJQllURSAqZHN0X2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBGSVJHQjE2ICpzcmNfcGl4ZWwgPSAoRklSR0IxNiopc3JjX2JpdHM7CgkJCQlGSVJHQkFGICpkc3RfcGl4ZWwgPSAoRklSR0JBRiopZHN0X2JpdHM7CgoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCS8vIGNvbnZlcnQgYW5kIHNjYWxlIHRvIHRoZSByYW5nZSBbMC4uMV0KCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSAoZmxvYXQpKHNyY19waXhlbFt4XS5yZWQpICAgLyA2NTUzNS4wRjsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSAoZmxvYXQpKHNyY19waXhlbFt4XS5ncmVlbikgLyA2NTUzNS4wRjsKCQkJCQlkc3RfcGl4ZWxbeF0uYmx1ZSAgPSAoZmxvYXQpKHNyY19waXhlbFt4XS5ibHVlKSAgLyA2NTUzNS4wRjsKCQkJCQlkc3RfcGl4ZWxbeF0uYWxwaGEgPSAxLjBGOwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JBMTY6CgkJewoJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpOwoJCQlCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEZJUkdCQTE2ICpzcmNfcGl4ZWwgPSAoRklSR0JBMTYqKXNyY19iaXRzOwoJCQkJRklSR0JBRiAqZHN0X3BpeGVsID0gKEZJUkdCQUYqKWRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IGFuZCBzY2FsZSB0byB0aGUgcmFuZ2UgWzAuLjFdCgkJCQkJZHN0X3BpeGVsW3hdLnJlZCAgID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0ucmVkKSAgIC8gNjU1MzUuMEY7CgkJCQkJZHN0X3BpeGVsW3hdLmdyZWVuID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0uZ3JlZW4pIC8gNjU1MzUuMEY7CgkJCQkJZHN0X3BpeGVsW3hdLmJsdWUgID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0uYmx1ZSkgIC8gNjU1MzUuMEY7CgkJCQkJZHN0X3BpeGVsW3hdLmFscGhhID0gKGZsb2F0KShzcmNfcGl4ZWxbeF0uYWxwaGEpIC8gNjU1MzUuMEY7CgkJCQl9CgkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCX0KCQl9CgkJYnJlYWs7CgoJCWNhc2UgRklUX0ZMT0FUOgoJCXsKCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCQkJQllURSAqZHN0X2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBmbG9hdCAqc3JjX3BpeGVsID0gKGZsb2F0KilzcmNfYml0czsKCQkJCUZJUkdCQUYgKmRzdF9waXhlbCA9IChGSVJHQkFGKilkc3RfYml0czsKCgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBieSBjb3B5aW5nIGdyZXlzY2FsZSBjaGFubmVsIHRvIGVhY2ggUiwgRywgQiBjaGFubmVscwoJCQkJCS8vIGFzc3VtZSBmbG9hdCB2YWx1ZXMgYXJlIGluIFswLi4xXQoJCQkJCWNvbnN0IGZsb2F0IHZhbHVlID0gQ0xBTVAoc3JjX3BpeGVsW3hdLCAwLjBGLCAxLjBGKTsKCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSB2YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSB2YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uYmx1ZSAgPSB2YWx1ZTsKCQkJCQlkc3RfcGl4ZWxbeF0uYWxwaGEgPSAxLjBGOwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JGOgoJCXsKCQkJY29uc3QgQllURSAqc3JjX2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCQkJQllURSAqZHN0X2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQljb25zdCBGSVJHQkYgKnNyY19waXhlbCA9IChGSVJHQkYqKXNyY19iaXRzOwoJCQkJRklSR0JBRiAqZHN0X3BpeGVsID0gKEZJUkdCQUYqKWRzdF9iaXRzOwoKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkvLyBjb252ZXJ0IHBpeGVscyBkaXJlY3RseSwgd2hpbGUgYWRkaW5nIGEgImR1bW15IiBhbHBoYSBvZiAxLjAKCQkJCQlkc3RfcGl4ZWxbeF0ucmVkICAgPSBDTEFNUChzcmNfcGl4ZWxbeF0ucmVkLCAwLjBGLCAxLjBGKTsKCQkJCQlkc3RfcGl4ZWxbeF0uZ3JlZW4gPSBDTEFNUChzcmNfcGl4ZWxbeF0uZ3JlZW4sIDAuMEYsIDEuMEYpOwoJCQkJCWRzdF9waXhlbFt4XS5ibHVlICA9IENMQU1QKHNyY19waXhlbFt4XS5ibHVlLCAwLjBGLCAxLjBGKTsKCQkJCQlkc3RfcGl4ZWxbeF0uYWxwaGEgPSAxLjBGOwoJCQkJfQoJCQkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCQl9CgkJfQoJCWJyZWFrOwoJfQoKCWlmKHNyYyAhPSBkaWIpIHsKCQlGcmVlSW1hZ2VfVW5sb2FkKHNyYyk7Cgl9CgoJcmV0dXJuIGRzdDsKfQoK