LyogbWVtLmMgLS0tIG1lbW9yeSBmb3IgTTMyQyBzaW11bGF0b3IuCgpDb3B5cmlnaHQgKEMpIDIwMDUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCkNvbnRyaWJ1dGVkIGJ5IFJlZCBIYXQsIEluYy4KClRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBHTlUgc2ltdWxhdG9ycy4KClRoZSBHTlUgc2ltdWxhdG9ycyBhcmUgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgdGhlbSBhbmQvb3IKbW9kaWZ5IHRoZW0gdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwpwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUKTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KClRoZSBHTlUgc2ltdWxhdG9ycyBhcmUgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCB0aGV5IHdpbGwgYmUKdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VCkdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCmFsb25nIHdpdGggdGhlIEdOVSBzaW11bGF0b3JzOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCkZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEKMDIxMTAtMTMwMSwgVVNBICAqLwoKCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJtZW0uaCIKI2luY2x1ZGUgImNwdS5oIgojaW5jbHVkZSAic3lzY2FsbHMuaCIKI2luY2x1ZGUgIm1pc2MuaCIKCiNkZWZpbmUgTDFfQklUUyAgKDEwKQojZGVmaW5lIEwyX0JJVFMgICgxMCkKI2RlZmluZSBPRkZfQklUUyAoMTIpCgojZGVmaW5lIEwxX0xFTiAgKDEgPDwgTDFfQklUUykKI2RlZmluZSBMMl9MRU4gICgxIDw8IEwyX0JJVFMpCiNkZWZpbmUgT0ZGX0xFTiAoMSA8PCBPRkZfQklUUykKCnN0YXRpYyB1bnNpZ25lZCBjaGFyICoqcHRbTDFfTEVOXTsKCi8qIFsgZ2V0PTAvcHV0PTEgXVsgYnl0ZSBzaXplIF0gKi8Kc3RhdGljIHVuc2lnbmVkIGludCBtZW1fY291bnRlcnNbMl1bNF07CgojZGVmaW5lIENPVU5UKGlzcHV0LGJ5dGVzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogIGlmICh2ZXJib3NlICYmIGVuYWJsZV9jb3VudGluZykgbWVtX2NvdW50ZXJzW2lzcHV0XVtieXRlc10rKwoKdm9pZAppbml0X21lbSAodm9pZCkKewogIGludCBpLCBqOwoKICBmb3IgKGkgPSAwOyBpIDwgTDFfTEVOOyBpKyspCiAgICBpZiAocHRbaV0pCiAgICAgIHsKCWZvciAoaiA9IDA7IGogPCBMMl9MRU47IGorKykKCSAgaWYgKHB0W2ldW2pdKQoJICAgIGZyZWUgKHB0W2ldW2pdKTsKCWZyZWUgKHB0W2ldKTsKICAgICAgfQogIG1lbXNldCAocHQsIDAsIHNpemVvZiAocHQpKTsKICBtZW1zZXQgKG1lbV9jb3VudGVycywgMCwgc2l6ZW9mIChtZW1fY291bnRlcnMpKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKgptZW1fcHRyIChhZGRyZXNzKQp7CiAgaW50IHB0MSA9IChhZGRyZXNzID4+IChMMl9CSVRTICsgT0ZGX0JJVFMpKSAmICgoMSA8PCBMMV9CSVRTKSAtIDEpOwogIGludCBwdDIgPSAoYWRkcmVzcyA+PiBPRkZfQklUUykgJiAoKDEgPDwgTDJfQklUUykgLSAxKTsKICBpbnQgcHRvID0gYWRkcmVzcyAmICgoMSA8PCBPRkZfQklUUykgLSAxKTsKCiAgaWYgKGFkZHJlc3MgPT0gMCkKICAgIHsKICAgICAgcHJpbnRmICgiTlVMTCBwb2ludGVyIGRlcmVmZXJlbmNlXG4iKTsKICAgICAgZXhpdCAoMSk7CiAgICB9CgogIGlmIChwdFtwdDFdID09IDApCiAgICBwdFtwdDFdID0gKHVuc2lnbmVkIGNoYXIgKiopIGNhbGxvYyAoTDJfTEVOLCBzaXplb2YgKGNoYXIgKiopKTsKICBpZiAocHRbcHQxXVtwdDJdID09IDApCiAgICB7CiAgICAgIHB0W3B0MV1bcHQyXSA9ICh1bnNpZ25lZCBjaGFyICopIG1hbGxvYyAoT0ZGX0xFTik7CiAgICAgIG1lbXNldCAocHRbcHQxXVtwdDJdLCAwLCBPRkZfTEVOKTsKICAgIH0KCiAgcmV0dXJuIHB0W3B0MV1bcHQyXSArIHB0bzsKfQoKc3RhdGljIHZvaWQKdXNlZCAoaW50IHJzdGFydCwgaW50IGksIGludCBqKQp7CiAgaW50IHJlbmQgPSBpIDw8IChMMl9CSVRTICsgT0ZGX0JJVFMpOwogIHJlbmQgKz0gaiA8PCBPRkZfQklUUzsKICBpZiAocnN0YXJ0ID09IDB4ZTAwMDAgJiYgcmVuZCA9PSAweGUxMDAwKQogICAgcmV0dXJuOwogIHByaW50ZiAoIm1lbTogICAlMDh4IC0gJTA4eCAoJWRrIGJ5dGVzKVxuIiwgcnN0YXJ0LCByZW5kIC0gMSwKCSAgKHJlbmQgLSByc3RhcnQpIC8gMTAyNCk7Cn0KCnN0YXRpYyBjaGFyICoKbWNzIChpbnQgaXNwdXQsIGludCBieXRlcykKewogIHJldHVybiBjb21tYSAobWVtX2NvdW50ZXJzW2lzcHV0XVtieXRlc10pOwp9Cgp2b2lkCm1lbV91c2FnZV9zdGF0cyAoKQp7CiAgaW50IGksIGo7CiAgaW50IHJzdGFydCA9IDA7CiAgaW50IHBlbmRpbmcgPSAwOwoKICBmb3IgKGkgPSAwOyBpIDwgTDFfTEVOOyBpKyspCiAgICBpZiAocHRbaV0pCiAgICAgIHsKCWZvciAoaiA9IDA7IGogPCBMMl9MRU47IGorKykKCSAgaWYgKHB0W2ldW2pdKQoJICAgIHsKCSAgICAgIGlmICghcGVuZGluZykKCQl7CgkJICBwZW5kaW5nID0gMTsKCQkgIHJzdGFydCA9IChpIDw8IChMMl9CSVRTICsgT0ZGX0JJVFMpKSArIChqIDw8IE9GRl9CSVRTKTsKCQl9CgkgICAgfQoJICBlbHNlIGlmIChwZW5kaW5nKQoJICAgIHsKCSAgICAgIHBlbmRpbmcgPSAwOwoJICAgICAgdXNlZCAocnN0YXJ0LCBpLCBqKTsKCSAgICB9CiAgICAgIH0KICAgIGVsc2UKICAgICAgewoJaWYgKHBlbmRpbmcpCgkgIHsKCSAgICBwZW5kaW5nID0gMDsKCSAgICB1c2VkIChyc3RhcnQsIGksIDApOwoJICB9CiAgICAgIH0KICAvKiAgICAgICBtZW0gZm9vOiAxMjM0NTY3ODkwMTIgMTIzNDU2Nzg5MDEyIDEyMzQ1Njc4OTAxMiAxMjM0NTY3ODkwMTIKICAgICAgICAgICAgMTIzNDU2Nzg5MDEyICovCiAgcHJpbnRmICgiICAgICAgICAgICAgICAgICBieXRlICAgICAgICBzaG9ydCAgICAgIHBvaW50ZXIgICAgICAgICBsb25nIgogICAgICAgICAgIiAgICAgICAgZmV0Y2hcbiIpOwogIHByaW50ZiAoIm1lbSBnZXQ6ICUxMnMgJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgwLCAxKSwgbWNzICgwLCAyKSwKCSAgbWNzICgwLCAzKSwgbWNzICgwLCA0KSwgbWNzICgwLCAwKSk7CiAgcHJpbnRmICgibWVtIHB1dDogJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgxLCAxKSwgbWNzICgxLCAyKSwKCSAgbWNzICgxLCAzKSwgbWNzICgxLCA0KSk7Cn0KCnN0YXRpYyBpbnQgdHByID0gMDsKc3RhdGljIHZvaWQKcyAoaW50IGFkZHJlc3MsIGNoYXIgKmRpcikKewogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIk1FTVslMCp4XSAlcyIsIG1lbWJ1c19tYXNrID09IDB4ZmZmZmYgPyA1IDogNiwgYWRkcmVzcywgZGlyKTsKICB0cHIrKzsKfQoKI2RlZmluZSBTKGQpIGlmICh0cmFjZSkgcyhhZGRyZXNzLCBkKQpzdGF0aWMgdm9pZAplICgpCnsKICBpZiAoIXRyYWNlKQogICAgcmV0dXJuOwogIHRwci0tOwogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIlxuIik7Cn0KCiNkZWZpbmUgRSgpIGlmICh0cmFjZSkgZSgpCgp2b2lkCm1lbV9wdXRfYnl0ZSAoaW50IGFkZHJlc3MsIHVuc2lnbmVkIGNoYXIgdmFsdWUpCnsKICB1bnNpZ25lZCBjaGFyICptOwogIGFkZHJlc3MgJj0gbWVtYnVzX21hc2s7CiAgbSA9IG1lbV9wdHIgKGFkZHJlc3MpOwogIGlmICh0cmFjZSkKICAgIHByaW50ZiAoIiAlMDJ4IiwgdmFsdWUpOwogICptID0gdmFsdWU7CiAgc3dpdGNoIChhZGRyZXNzKQogICAgewogICAgY2FzZSAweDAwZTE6CiAgICAgIHsKCXN0YXRpYyBpbnQgb2xkX2xlZCA9IC0xOwoJc3RhdGljIGNoYXIgKmxlZF9vbltdID0KCSAgeyAiXDAzM1szMW0gTyAiLCAiXDAzM1szMm0gTyAiLCAiXDAzM1szNG0gTyAiIH07CglzdGF0aWMgY2hhciAqbGVkX29mZltdID0geyAiXDAzM1swbSC3ICIsICJcMDMzWzBtILcgIiwgIlwwMzNbMG0gtyAiIH07CglpbnQgaTsKCWlmIChvbGRfbGVkICE9IHZhbHVlKQoJICB7CgkgICAgZnB1dHMgKCIgICIsIHN0ZG91dCk7CgkgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykKCSAgICAgIGlmICh2YWx1ZSAmICgxIDw8IGkpKQoJCWZwdXRzIChsZWRfb2ZmW2ldLCBzdGRvdXQpOwoJICAgICAgZWxzZQoJCWZwdXRzIChsZWRfb25baV0sIHN0ZG91dCk7CgkgICAgZnB1dHMgKCJcMDMzWzBtXHIiLCBzdGRvdXQpOwoJICAgIGZmbHVzaCAoc3Rkb3V0KTsKCSAgICBvbGRfbGVkID0gdmFsdWU7CgkgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIDB4M2FhOiAvKiB1YXJ0MXR4ICovCiAgICAgIHsKCXN0YXRpYyBpbnQgcGVuZGluZ19leGl0ID0gMDsKCWlmICh2YWx1ZSA9PSAwKQoJICB7CgkgICAgaWYgKHBlbmRpbmdfZXhpdCkKCSAgICAgIHsKCQlzdGVwX3Jlc3VsdCA9IE0zMkNfTUFLRV9FWElURUQodmFsdWUpOwoJCXJldHVybjsKCSAgICAgIH0KCSAgICBwZW5kaW5nX2V4aXQgPSAxOwoJICB9CgllbHNlCgkgIHB1dGNoYXIodmFsdWUpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDA6CiAgICAgIG0zMmNfc3lzY2FsbCAodmFsdWUpOwogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAxOgogICAgICBwdXRjaGFyICh2YWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDI6CiAgICAgIHByaW50ZiAoIlNpbVRyYWNlOiAlMDZseCAlMDJ4XG4iLCByZWdzLnJfcGMsIHZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAweDQwMzoKICAgICAgcHJpbnRmICgiU2ltVHJhcDogJTA2bHggJTAyeFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIGFib3J0ICgpOwogICAgfQp9Cgp2b2lkCm1lbV9wdXRfcWkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDEpOwp9Cgp2b2lkCm1lbV9wdXRfaGkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBzaG9ydCB2YWx1ZSkKewogIGlmIChhZGRyZXNzID09IDB4NDAyKQogICAgewogICAgICBwcmludGYgKCJTaW1UcmFjZTogJTA2bHggJTA0eFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIHJldHVybjsKICAgIH0KICBTICgiPD0iKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MsIHZhbHVlICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMSwgdmFsdWUgPj4gOCk7CiAgRSAoKTsKICBDT1VOVCAoMSwgMik7Cn0KCnZvaWQKbWVtX3B1dF9wc2kgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBsb25nIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDEsICh2YWx1ZSA+PiA4KSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDIsIHZhbHVlID4+IDE2KTsKICBFICgpOwogIENPVU5UICgxLCAzKTsKfQoKdm9pZAptZW1fcHV0X3NpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgbG9uZyB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAxLCAodmFsdWUgPj4gOCkgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAyLCAodmFsdWUgPj4gMTYpICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMywgKHZhbHVlID4+IDI0KSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDQpOwp9Cgp2b2lkCm1lbV9wdXRfYmxrIChpbnQgYWRkcmVzcywgdm9pZCAqYnVmcHRyLCBpbnQgbmJ5dGVzKQp7CiAgUyAoIjw9Iik7CiAgaWYgKGVuYWJsZV9jb3VudGluZykKICAgIG1lbV9jb3VudGVyc1sxXVsxXSArPSBuYnl0ZXM7CiAgd2hpbGUgKG5ieXRlcy0tKQogICAgbWVtX3B1dF9ieXRlIChhZGRyZXNzKyssICoodW5zaWduZWQgY2hhciAqKSBidWZwdHIrKyk7CiAgRSAoKTsKfQoKdW5zaWduZWQgY2hhcgptZW1fZ2V0X3BjICgpCnsKICB1bnNpZ25lZCBjaGFyICptID0gbWVtX3B0ciAocmVncy5yX3BjICYgbWVtYnVzX21hc2spOwogIENPVU5UICgwLCAwKTsKICByZXR1cm4gKm07Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyCm1lbV9nZXRfYnl0ZSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBjaGFyICptOwogIGFkZHJlc3MgJj0gbWVtYnVzX21hc2s7CiAgUyAoIj0+Iik7CiAgbSA9IG1lbV9wdHIgKGFkZHJlc3MpOwogIHN3aXRjaCAoYWRkcmVzcykKICAgIHsKICAgIGNhc2UgMHgzYWQ6IC8qIHVhcnQxYzEgKi8KICAgICAgRSgpOwogICAgICByZXR1cm4gMjsgLyogdHJhbnNtaXR0ZXIgZW1wdHkgKi8KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OiAKICAgICAgaWYgKHRyYWNlKQoJcHJpbnRmICgiICUwMngiLCAqbSk7CiAgICAgIGJyZWFrOwogICAgfQogIEUgKCk7CiAgcmV0dXJuICptOwp9Cgp1bnNpZ25lZCBjaGFyCm1lbV9nZXRfcWkgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgY2hhciBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgQ09VTlQgKDAsIDEpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBzaG9ydAptZW1fZ2V0X2hpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIHNob3J0IHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSAqIDI1NjsKICBDT1VOVCAoMCwgMik7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9wc2kgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgbG9uZyBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgKiAyNTY7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMikgKiA2NTUzNjsKICBDT1VOVCAoMCwgMyk7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9zaSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBsb25nIHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSA8PCA4OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDIpIDw8IDE2OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDMpIDw8IDI0OwogIENPVU5UICgwLCA0KTsKICBFICgpOwogIHJldHVybiBydjsKfQoKdm9pZAptZW1fZ2V0X2JsayAoaW50IGFkZHJlc3MsIHZvaWQgKmJ1ZnB0ciwgaW50IG5ieXRlcykKewogIFMgKCI9PiIpOwogIGlmIChlbmFibGVfY291bnRpbmcpCiAgICBtZW1fY291bnRlcnNbMF1bMV0gKz0gbmJ5dGVzOwogIHdoaWxlIChuYnl0ZXMtLSkKICAgICooY2hhciAqKSBidWZwdHIrKyA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcysrKTsKICBFICgpOwp9CgppbnQKc2lnbl9leHQgKGludCB2LCBpbnQgYml0cykKewogIGlmIChiaXRzIDwgMzIpCiAgICB7CiAgICAgIHYgJj0gKDEgPDwgYml0cykgLSAxOwogICAgICBpZiAodiAmICgxIDw8IChiaXRzIC0gMSkpKQoJdiAtPSAoMSA8PCBiaXRzKTsKICAgIH0KICByZXR1cm4gdjsKfQo=