Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBzbWFydCBjb252ZXJ0IFggdG8gUkdCMTYKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRUb1JHQjE2KEZJQklUTUFQICpkaWIpIHsKCUZJQklUTUFQICpzcmMgPSBOVUxMOwoJRklCSVRNQVAgKmRzdCA9IE5VTEw7CgoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSkgcmV0dXJuIE5VTEw7CgoJY29uc3QgRlJFRV9JTUFHRV9UWVBFIHNyY190eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoKCS8vIGNoZWNrIGZvciBhbGxvd2VkIGNvbnZlcnNpb25zIAoJc3dpdGNoKHNyY190eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCXsKCQkJLy8gY29udmVydCB0byAyNC1iaXQgaWYgbmVlZGVkCgkJCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gMjQpIHx8IChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gMzIpKSB7CgkJCQlzcmMgPSBkaWI7CgkJCX0gZWxzZSB7CgkJCQlzcmMgPSBGcmVlSW1hZ2VfQ29udmVydFRvMjRCaXRzKGRpYik7CgkJCQlpZighc3JjKSByZXR1cm4gTlVMTDsKCQkJfQoJCQlicmVhazsKCQl9CgkJY2FzZSBGSVRfVUlOVDE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gdW5zaWduZWQgMTYtYml0CgkJCXNyYyA9IGRpYjsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCMTY6CgkJCS8vIFJHQjE2IHR5cGUgOiBjbG9uZSB0aGUgc3JjCgkJCXJldHVybiBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCQTE2OgoJCQkvLyBhbGxvdyBjb252ZXJzaW9uIGZyb20gNjQtYml0IFJHQkEgKGlnbm9yZSB0aGUgYWxwaGEgY2hhbm5lbCkKCQkJc3JjID0gZGliOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gTlVMTDsKCX0KCgkvLyBhbGxvY2F0ZSBkc3QgaW1hZ2UKCgljb25zdCB1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCWRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX1JHQjE2LCB3aWR0aCwgaGVpZ2h0KTsKCWlmKCFkc3QpIHsKCQlpZihzcmMgIT0gZGliKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoc3JjKTsKCQl9CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gY29weSBtZXRhZGF0YSBmcm9tIHNyYyB0byBkc3QKCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgc3JjKTsKCgkvLyBjb252ZXJ0IGZyb20gc3JjIHR5cGUgdG8gUkdCMTYKCglzd2l0Y2goc3JjX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJewoJCQkvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwgKDEgZm9yIDgtYml0LCAzIGZvciAyNC1iaXQgb3IgNCBmb3IgMzItYml0KQoJCQljb25zdCB1bnNpZ25lZCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IEJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJRklSR0IxNiAqZHN0X2JpdHMgPSAoRklSR0IxNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJZHN0X2JpdHNbeF0ucmVkICAgPSBzcmNfYml0c1tGSV9SR0JBX1JFRF0gPDwgODsKCQkJCQlkc3RfYml0c1t4XS5ncmVlbiA9IHNyY19iaXRzW0ZJX1JHQkFfR1JFRU5dIDw8IDg7CgkJCQkJZHN0X2JpdHNbeF0uYmx1ZSAgPSBzcmNfYml0c1tGSV9SR0JBX0JMVUVdIDw8IDg7CgkJCQkJc3JjX2JpdHMgKz0gYnl0ZXNwcDsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCgkJY2FzZSBGSVRfVUlOVDE2OgoJCXsKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCWNvbnN0IFdPUkQgKnNyY19iaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJRklSR0IxNiAqZHN0X2JpdHMgPSAoRklSR0IxNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRzdCwgeSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJLy8gY29udmVydCBieSBjb3B5aW5nIGdyZXlzY2FsZSBjaGFubmVsIHRvIGVhY2ggUiwgRywgQiBjaGFubmVscwoJCQkJCWRzdF9iaXRzW3hdLnJlZCAgID0gc3JjX2JpdHNbeF07CgkJCQkJZHN0X2JpdHNbeF0uZ3JlZW4gPSBzcmNfYml0c1t4XTsKCQkJCQlkc3RfYml0c1t4XS5ibHVlICA9IHNyY19iaXRzW3hdOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQljYXNlIEZJVF9SR0JBMTY6CgkJewoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJY29uc3QgRklSR0JBMTYgKnNyY19iaXRzID0gKEZJUkdCQTE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCUZJUkdCMTYgKmRzdF9iaXRzID0gKEZJUkdCMTYqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIHkpOwoJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCS8vIGNvbnZlcnQgYW5kIHNraXAgYWxwaGEgY2hhbm5lbAoJCQkJCWRzdF9iaXRzW3hdLnJlZCAgID0gc3JjX2JpdHNbeF0ucmVkOwoJCQkJCWRzdF9iaXRzW3hdLmdyZWVuID0gc3JjX2JpdHNbeF0uZ3JlZW47CgkJCQkJZHN0X2JpdHNbeF0uYmx1ZSAgPSBzcmNfYml0c1t4XS5ibHVlOwoJCQkJfQoJCQl9CgkJfQoJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlicmVhazsKCX0KCglpZihzcmMgIT0gZGliKSB7CgkJRnJlZUltYWdlX1VubG9hZChzcmMpOwoJfQoKCXJldHVybiBkc3Q7Cn0KCg==