LyogbWVtLmMgLS0tIG1lbW9yeSBmb3IgTTMyQyBzaW11bGF0b3IuCgpDb3B5cmlnaHQgKEMpIDIwMDUsIDIwMDctMjAxMiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KQ29udHJpYnV0ZWQgYnkgUmVkIEhhdCwgSW5jLgoKVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEdOVSBzaW11bGF0b3JzLgoKVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KClRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLApidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCkdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgpZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQphbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICovCgoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpZmRlZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfVEVSTUlPU19ICiNpbmNsdWRlIDx0ZXJtaW9zLmg+CiNlbmRpZgoKI2luY2x1ZGUgIm1lbS5oIgojaW5jbHVkZSAiY3B1LmgiCiNpbmNsdWRlICJzeXNjYWxscy5oIgojaW5jbHVkZSAibWlzYy5oIgojaWZkZWYgVElNRVJfQQojaW5jbHVkZSAiaW50LmgiCiNpbmNsdWRlICJ0aW1lcl9hLmgiCiNlbmRpZgoKI2RlZmluZSBMMV9CSVRTICAoMTApCiNkZWZpbmUgTDJfQklUUyAgKDEwKQojZGVmaW5lIE9GRl9CSVRTICgxMikKCiNkZWZpbmUgTDFfTEVOICAoMSA8PCBMMV9CSVRTKQojZGVmaW5lIEwyX0xFTiAgKDEgPDwgTDJfQklUUykKI2RlZmluZSBPRkZfTEVOICgxIDw8IE9GRl9CSVRTKQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKipwdFtMMV9MRU5dOwoKI2lmZGVmIEhBVkVfVEVSTUlPU19ICmludCBtMzJjX2NvbnNvbGVfaWZkID0gMDsKI2VuZGlmCmludCBtMzJjX2NvbnNvbGVfb2ZkID0gMTsKI2lmZGVmIEhBVkVfVEVSTUlPU19ICmludCBtMzJjX3VzZV9yYXdfY29uc29sZSA9IDA7CiNlbmRpZgoKI2lmZGVmIFRJTUVSX0EKVGltZXJfQSB0aW1lcl9hOwojZW5kaWYKCi8qIFsgZ2V0PTAvcHV0PTEgXVsgYnl0ZSBzaXplIF0gKi8Kc3RhdGljIHVuc2lnbmVkIGludCBtZW1fY291bnRlcnNbMl1bNV07CgojZGVmaW5lIENPVU5UKGlzcHV0LGJ5dGVzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogIGlmICh2ZXJib3NlICYmIGVuYWJsZV9jb3VudGluZykgbWVtX2NvdW50ZXJzW2lzcHV0XVtieXRlc10rKwoKdm9pZAppbml0X21lbSAodm9pZCkKewogIGludCBpLCBqOwoKICBmb3IgKGkgPSAwOyBpIDwgTDFfTEVOOyBpKyspCiAgICBpZiAocHRbaV0pCiAgICAgIHsKCWZvciAoaiA9IDA7IGogPCBMMl9MRU47IGorKykKCSAgaWYgKHB0W2ldW2pdKQoJICAgIGZyZWUgKHB0W2ldW2pdKTsKCWZyZWUgKHB0W2ldKTsKICAgICAgfQogIG1lbXNldCAocHQsIDAsIHNpemVvZiAocHQpKTsKICBtZW1zZXQgKG1lbV9jb3VudGVycywgMCwgc2l6ZW9mIChtZW1fY291bnRlcnMpKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKgptZW1fcHRyIChhZGRyZXNzKQp7CiAgc3RhdGljIGludCByZWN1cnNpbmcgPSAwOwogIGludCBwdDEgPSAoYWRkcmVzcyA+PiAoTDJfQklUUyArIE9GRl9CSVRTKSkgJiAoKDEgPDwgTDFfQklUUykgLSAxKTsKICBpbnQgcHQyID0gKGFkZHJlc3MgPj4gT0ZGX0JJVFMpICYgKCgxIDw8IEwyX0JJVFMpIC0gMSk7CiAgaW50IHB0byA9IGFkZHJlc3MgJiAoKDEgPDwgT0ZGX0JJVFMpIC0gMSk7CgogIGlmIChhZGRyZXNzID09IDAgJiYgIXJlY3Vyc2luZykKICAgIHsKICAgICAgcmVjdXJzaW5nID0gMTsKICAgICAgcHV0X3JlZyAocGMsIG0zMmNfb3Bjb2RlX3BjKTsKICAgICAgcHJpbnRmICgiTlVMTCBwb2ludGVyIGRlcmVmZXJlbmNlIGF0IHBjPTB4JXhcbiIsIGdldF9yZWcgKHBjKSk7CiAgICAgIHN0ZXBfcmVzdWx0ID0gTTMyQ19NQUtFX0hJVF9CUkVBSyAoKTsKI2lmIDAKICAgICAgLyogVGhpcyBjb2RlIGNhbiBiZSByZS1lbmFibGVkIHRvIGhlbHAgZGlhZ25vc2UgTlVMTCBwb2ludGVyCiAgICAgICAgIGJ1Z3MgdGhhdCBhcmVuJ3QgZGVidWdnYWJsZSBpbiBHREIuICAqLwogICAgICBtMzJjX2R1bXBfYWxsX3JlZ2lzdGVycyAoKTsKICAgICAgZXhpdCAoMSk7CiNlbmRpZgogICAgfQoKICBpZiAocHRbcHQxXSA9PSAwKQogICAgcHRbcHQxXSA9ICh1bnNpZ25lZCBjaGFyICoqKSBjYWxsb2MgKEwyX0xFTiwgc2l6ZW9mIChjaGFyICoqKSk7CiAgaWYgKHB0W3B0MV1bcHQyXSA9PSAwKQogICAgewogICAgICBwdFtwdDFdW3B0Ml0gPSAodW5zaWduZWQgY2hhciAqKSBtYWxsb2MgKE9GRl9MRU4pOwogICAgICBtZW1zZXQgKHB0W3B0MV1bcHQyXSwgMCwgT0ZGX0xFTik7CiAgICB9CgogIHJldHVybiBwdFtwdDFdW3B0Ml0gKyBwdG87Cn0KCnN0YXRpYyB2b2lkCnVzZWQgKGludCByc3RhcnQsIGludCBpLCBpbnQgaikKewogIGludCByZW5kID0gaSA8PCAoTDJfQklUUyArIE9GRl9CSVRTKTsKICByZW5kICs9IGogPDwgT0ZGX0JJVFM7CiAgaWYgKHJzdGFydCA9PSAweGUwMDAwICYmIHJlbmQgPT0gMHhlMTAwMCkKICAgIHJldHVybjsKICBwcmludGYgKCJtZW06ICAgJTA4eCAtICUwOHggKCVkayBieXRlcylcbiIsIHJzdGFydCwgcmVuZCAtIDEsCgkgIChyZW5kIC0gcnN0YXJ0KSAvIDEwMjQpOwp9CgpzdGF0aWMgY2hhciAqCm1jcyAoaW50IGlzcHV0LCBpbnQgYnl0ZXMpCnsKICByZXR1cm4gY29tbWEgKG1lbV9jb3VudGVyc1tpc3B1dF1bYnl0ZXNdKTsKfQoKdm9pZAptZW1fdXNhZ2Vfc3RhdHMgKCkKewogIGludCBpLCBqOwogIGludCByc3RhcnQgPSAwOwogIGludCBwZW5kaW5nID0gMDsKCiAgZm9yIChpID0gMDsgaSA8IEwxX0xFTjsgaSsrKQogICAgaWYgKHB0W2ldKQogICAgICB7Cglmb3IgKGogPSAwOyBqIDwgTDJfTEVOOyBqKyspCgkgIGlmIChwdFtpXVtqXSkKCSAgICB7CgkgICAgICBpZiAoIXBlbmRpbmcpCgkJewoJCSAgcGVuZGluZyA9IDE7CgkJICByc3RhcnQgPSAoaSA8PCAoTDJfQklUUyArIE9GRl9CSVRTKSkgKyAoaiA8PCBPRkZfQklUUyk7CgkJfQoJICAgIH0KCSAgZWxzZSBpZiAocGVuZGluZykKCSAgICB7CgkgICAgICBwZW5kaW5nID0gMDsKCSAgICAgIHVzZWQgKHJzdGFydCwgaSwgaik7CgkgICAgfQogICAgICB9CiAgICBlbHNlCiAgICAgIHsKCWlmIChwZW5kaW5nKQoJICB7CgkgICAgcGVuZGluZyA9IDA7CgkgICAgdXNlZCAocnN0YXJ0LCBpLCAwKTsKCSAgfQogICAgICB9CiAgLyogICAgICAgbWVtIGZvbzogMTIzNDU2Nzg5MDEyIDEyMzQ1Njc4OTAxMiAxMjM0NTY3ODkwMTIgMTIzNDU2Nzg5MDEyCiAgICAgICAgICAgIDEyMzQ1Njc4OTAxMiAqLwogIHByaW50ZiAoIiAgICAgICAgICAgICAgICAgYnl0ZSAgICAgICAgc2hvcnQgICAgICBwb2ludGVyICAgICAgICAgbG9uZyIKCSAgIiAgICAgICAgZmV0Y2hcbiIpOwogIHByaW50ZiAoIm1lbSBnZXQ6ICUxMnMgJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgwLCAxKSwgbWNzICgwLCAyKSwKCSAgbWNzICgwLCAzKSwgbWNzICgwLCA0KSwgbWNzICgwLCAwKSk7CiAgcHJpbnRmICgibWVtIHB1dDogJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgxLCAxKSwgbWNzICgxLCAyKSwKCSAgbWNzICgxLCAzKSwgbWNzICgxLCA0KSk7Cn0KCnN0YXRpYyBpbnQgdHByID0gMDsKc3RhdGljIHZvaWQKcyAoaW50IGFkZHJlc3MsIGNoYXIgKmRpcikKewogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIk1FTVslMCp4XSAlcyIsIG1lbWJ1c19tYXNrID09IDB4ZmZmZmYgPyA1IDogNiwgYWRkcmVzcywgZGlyKTsKICB0cHIrKzsKfQoKI2RlZmluZSBTKGQpIGlmICh0cmFjZSkgcyhhZGRyZXNzLCBkKQpzdGF0aWMgdm9pZAplICgpCnsKICBpZiAoIXRyYWNlKQogICAgcmV0dXJuOwogIHRwci0tOwogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIlxuIik7Cn0KCiNkZWZpbmUgRSgpIGlmICh0cmFjZSkgZSgpCgpleHRlcm4gaW50IG0zMmNfZGlzYXNzZW1ibGU7Cgp2b2lkCm1lbV9wdXRfYnl0ZSAoaW50IGFkZHJlc3MsIHVuc2lnbmVkIGNoYXIgdmFsdWUpCnsKICB1bnNpZ25lZCBjaGFyICptOwogIGFkZHJlc3MgJj0gbWVtYnVzX21hc2s7CiAgbSA9IG1lbV9wdHIgKGFkZHJlc3MpOwogIGlmICh0cmFjZSkKICAgIHByaW50ZiAoIiAlMDJ4IiwgdmFsdWUpOwogICptID0gdmFsdWU7CiAgc3dpdGNoIChhZGRyZXNzKQogICAgewogICAgY2FzZSAweDAwZTE6CiAgICAgIHsKCXN0YXRpYyBpbnQgb2xkX2xlZCA9IC0xOwoJc3RhdGljIGNoYXIgKmxlZF9vbltdID0KCSAgeyAiXDAzM1szMW0gTyAiLCAiXDAzM1szMm0gTyAiLCAiXDAzM1szNG0gTyAiIH07CglzdGF0aWMgY2hhciAqbGVkX29mZltdID0geyAiXDAzM1swbSC3ICIsICJcMDMzWzBtILcgIiwgIlwwMzNbMG0gtyAiIH07CglpbnQgaTsKCWlmIChvbGRfbGVkICE9IHZhbHVlKQoJICB7CgkgICAgZnB1dHMgKCIgICIsIHN0ZG91dCk7CgkgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykKCSAgICAgIGlmICh2YWx1ZSAmICgxIDw8IGkpKQoJCWZwdXRzIChsZWRfb2ZmW2ldLCBzdGRvdXQpOwoJICAgICAgZWxzZQoJCWZwdXRzIChsZWRfb25baV0sIHN0ZG91dCk7CgkgICAgZnB1dHMgKCJcMDMzWzBtXHIiLCBzdGRvdXQpOwoJICAgIGZmbHVzaCAoc3Rkb3V0KTsKCSAgICBvbGRfbGVkID0gdmFsdWU7CgkgIH0KICAgICAgfQogICAgICBicmVhazsKI2lmZGVmIFRJTUVSX0EKICAgICAgLyogTTMyQyBUaW1lciBBICovCiAgICBjYXNlIDB4MzQ2OgkJLyogVEEwbG93ICovCiAgICAgIHRpbWVyX2EuY291bnQgPSAodGltZXJfYS5jb3VudCAmIDB4ZmYwMCkgfCB2YWx1ZTsKICAgICAgdGltZXJfYS5yZWxvYWQgPSB0aW1lcl9hLmNvdW50OwogICAgICBicmVhazsKICAgIGNhc2UgMHgzNDc6CQkvKiBUQTBoaWdoICovCiAgICAgIHRpbWVyX2EuY291bnQgPSAodGltZXJfYS5jb3VudCAmIDB4MDBmZikgfCAodmFsdWUgPDwgOCk7CiAgICAgIHRpbWVyX2EucmVsb2FkID0gdGltZXJfYS5jb3VudDsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MzQwOgkJLyogVEFCU1IgKi8KICAgICAgdGltZXJfYS5ic3IgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MzU2OgkJLyogVEEwTVIgKi8KICAgICAgdGltZXJfYS5tb2RlID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM1ZjoJCS8qIFRDU1BSICovCiAgICAgIHRpbWVyX2EudGNzcHIgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MDA2YzoJCS8qIFRBMElDICovCiAgICAgIHRpbWVyX2EuaWMgPSB2YWx1ZTsKICAgICAgYnJlYWs7CgogICAgICAvKiBSOEMgVGltZXIgUkEgKi8KICAgIGNhc2UgMHgxMDA6CQkvKiBUUkFDUiAqLwogICAgICB0aW1lcl9hLmJzciA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgxMDI6CQkvKiBUUkFNUiAqLwogICAgICB0aW1lcl9hLm1vZGUgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MTA0OgkJLyogVFJBICovCiAgICAgIHRpbWVyX2EuY291bnQgPSB2YWx1ZTsKICAgICAgdGltZXJfYS5yZWxvYWQgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MTAzOgkJLyogVFJBUFJFICovCiAgICAgIHRpbWVyX2EudGNzcHIgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MDA1NjoJCS8qIFRBMElDICovCiAgICAgIHRpbWVyX2EuaWMgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiNlbmRpZgoKICAgIGNhc2UgMHgyZWE6CQkvKiBtMzJjIHVhcnQxdHggKi8KICAgIGNhc2UgMHgzYWE6CQkvKiBtMTZjIHVhcnQxdHggKi8KICAgICAgewoJc3RhdGljIGludCBwZW5kaW5nX2V4aXQgPSAwOwoJaWYgKHZhbHVlID09IDApCgkgIHsKCSAgICBpZiAocGVuZGluZ19leGl0KQoJICAgICAgewoJCXN0ZXBfcmVzdWx0ID0gTTMyQ19NQUtFX0VYSVRFRCAodmFsdWUpOwoJCXJldHVybjsKCSAgICAgIH0KCSAgICBwZW5kaW5nX2V4aXQgPSAxOwoJICB9CgllbHNlCgkgIHsKCSAgICB3cml0ZSAobTMyY19jb25zb2xlX29mZCwgJnZhbHVlLCAxKTsKCSAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDA6CiAgICAgIG0zMmNfc3lzY2FsbCAodmFsdWUpOwogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAxOgogICAgICBwdXRjaGFyICh2YWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDI6CiAgICAgIHByaW50ZiAoIlNpbVRyYWNlOiAlMDZseCAlMDJ4XG4iLCByZWdzLnJfcGMsIHZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAweDQwMzoKICAgICAgcHJpbnRmICgiU2ltVHJhcDogJTA2bHggJTAyeFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIGFib3J0ICgpOwogICAgfQp9Cgp2b2lkCm1lbV9wdXRfcWkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDEpOwp9Cgp2b2lkCm1lbV9wdXRfaGkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBzaG9ydCB2YWx1ZSkKewogIGlmIChhZGRyZXNzID09IDB4NDAyKQogICAgewogICAgICBwcmludGYgKCJTaW1UcmFjZTogJTA2bHggJTA0eFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIHJldHVybjsKICAgIH0KICBTICgiPD0iKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MsIHZhbHVlICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMSwgdmFsdWUgPj4gOCk7CiAgRSAoKTsKICBDT1VOVCAoMSwgMik7Cn0KCnZvaWQKbWVtX3B1dF9wc2kgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBsb25nIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDEsICh2YWx1ZSA+PiA4KSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDIsIHZhbHVlID4+IDE2KTsKICBFICgpOwogIENPVU5UICgxLCAzKTsKfQoKdm9pZAptZW1fcHV0X3NpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgbG9uZyB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAxLCAodmFsdWUgPj4gOCkgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAyLCAodmFsdWUgPj4gMTYpICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMywgKHZhbHVlID4+IDI0KSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDQpOwp9Cgp2b2lkCm1lbV9wdXRfYmxrIChpbnQgYWRkcmVzcywgY29uc3Qgdm9pZCAqYnVmcHRyLCBpbnQgbmJ5dGVzKQp7CiAgUyAoIjw9Iik7CiAgaWYgKGVuYWJsZV9jb3VudGluZykKICAgIG1lbV9jb3VudGVyc1sxXVsxXSArPSBuYnl0ZXM7CiAgd2hpbGUgKG5ieXRlcy0tKQogICAgbWVtX3B1dF9ieXRlIChhZGRyZXNzKyssICooY29uc3QgdW5zaWduZWQgY2hhciAqKSBidWZwdHIrKyk7CiAgRSAoKTsKfQoKdW5zaWduZWQgY2hhcgptZW1fZ2V0X3BjICgpCnsKICB1bnNpZ25lZCBjaGFyICptID0gbWVtX3B0ciAocmVncy5yX3BjICYgbWVtYnVzX21hc2spOwogIENPVU5UICgwLCAwKTsKICByZXR1cm4gKm07Cn0KCiNpZmRlZiBIQVZFX1RFUk1JT1NfSApzdGF0aWMgaW50IGNvbnNvbGVfcmF3ID0gMDsKc3RhdGljIHN0cnVjdCB0ZXJtaW9zIG9hdHRyOwoKc3RhdGljIGludApzdGRpbl9yZWFkeSAoKQp7CiAgZmRfc2V0IGlmZDsKICBpbnQgbjsKICBzdHJ1Y3QgdGltZXZhbCB0OwoKICB0LnR2X3NlYyA9IDA7CiAgdC50dl91c2VjID0gMDsKICBGRF9aRVJPICgmaWZkKTsKICBGRF9TRVQgKG0zMmNfY29uc29sZV9pZmQsICZpZmQpOwogIG4gPSBzZWxlY3QgKDEsICZpZmQsIDAsIDAsICZ0KTsKICByZXR1cm4gbiA+IDA7Cn0KCnZvaWQKbTMyY19zaW1fcmVzdG9yZV9jb25zb2xlICgpCnsKICBpZiAoY29uc29sZV9yYXcpCiAgICB0Y3NldGF0dHIgKG0zMmNfY29uc29sZV9pZmQsIFRDU0FOT1csICZvYXR0cik7CiAgY29uc29sZV9yYXcgPSAwOwp9CiNlbmRpZgoKc3RhdGljIHVuc2lnbmVkIGNoYXIKbWVtX2dldF9ieXRlIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIGNoYXIgKm07CiAgYWRkcmVzcyAmPSBtZW1idXNfbWFzazsKICBtID0gbWVtX3B0ciAoYWRkcmVzcyk7CiAgc3dpdGNoIChhZGRyZXNzKQogICAgewojaWZkZWYgSEFWRV9URVJNSU9TX0gKICAgIGNhc2UgMHgyZWQ6CQkvKiBtMzJjIHVhcnQxYzEgKi8KICAgIGNhc2UgMHgzYWQ6CQkvKiBtMTZjIHVhcnQxYzEgKi8KCiAgICAgIGlmICghY29uc29sZV9yYXcgJiYgbTMyY191c2VfcmF3X2NvbnNvbGUpCgl7CgkgIHN0cnVjdCB0ZXJtaW9zIGF0dHI7CgkgIHRjZ2V0YXR0ciAobTMyY19jb25zb2xlX2lmZCwgJmF0dHIpOwoJICB0Y2dldGF0dHIgKG0zMmNfY29uc29sZV9pZmQsICZvYXR0cik7CgkgIC8qIFdlIHdhbnQgZWFjaCBrZXkgdG8gYmUgc2VudCBhcyB0aGUgdXNlciBwcmVzc2VzIHRoZW0uICAqLwoJICBhdHRyLmNfbGZsYWcgJj0gfihJQ0FOT04gfCBFQ0hPIHwgRUNIT0UpOwoJICB0Y3NldGF0dHIgKG0zMmNfY29uc29sZV9pZmQsIFRDU0FOT1csICZhdHRyKTsKCSAgY29uc29sZV9yYXcgPSAxOwoJICBhdGV4aXQgKG0zMmNfc2ltX3Jlc3RvcmVfY29uc29sZSk7Cgl9CgogICAgICBpZiAoc3RkaW5fcmVhZHkgKCkpCglyZXR1cm4gMHgwMjsJCS8qIHR4IGVtcHR5IGFuZCByeCBmdWxsICovCiAgICAgIGVsc2UKCXJldHVybiAweDBhOwkJLyogdHJhbnNtaXR0ZXIgZW1wdHkgKi8KCiAgICBjYXNlIDB4MmVlOgkJLyogbTMyYyB1YXJ0MSByeCAqLwogICAgICB7CgljaGFyIGM7CglyZWFkIChtMzJjX2NvbnNvbGVfaWZkLCAmYywgMSk7CglpZiAobTMyY19jb25zb2xlX2lmZCA9PSAwICYmIGMgPT0gMykJLyogQ3RybC1DICovCgkgIHsKCSAgICBwcmludGYgKCJDdHJsLUMhXG4iKTsKCSAgICBleGl0ICgwKTsKCSAgfQoKCWlmIChtMzJjX2NvbnNvbGVfaWZkICE9IDEpCgkgIHsKCSAgICBpZiAoaXNncmFwaCAoYykpCgkgICAgICBwcmludGYgKCJcMDMzWzMxbSVjXDAzM1swbSIsIGMpOwoJICAgIGVsc2UKCSAgICAgIHByaW50ZiAoIlwwMzNbMzFtJTAyeFwwMzNbMG0iLCBjKTsKCSAgfQoJcmV0dXJuIGM7CiAgICAgIH0KI2VuZGlmCgojaWZkZWYgVElNRVJfQQogICAgY2FzZSAweDM0NjoJCS8qIFRBMGxvdyAqLwogICAgICByZXR1cm4gdGltZXJfYS5jb3VudCAmIDB4ZmY7CiAgICBjYXNlIDB4MzQ3OgkJLyogVEEwaGlnaCAqLwogICAgICByZXR1cm4gKHRpbWVyX2EuY291bnQgPj4gOCkgJiAweGZmOwogICAgY2FzZSAweDEwNDoJCS8qIFRSQSAqLwogICAgICByZXR1cm4gdGltZXJfYS5jb3VudDsKI2VuZGlmCgogICAgZGVmYXVsdDoKICAgICAgLyogSW4gY2FzZSBib3RoIGNhc2VzIGFib3ZlIGFyZSBub3QgaW5jbHVkZWQuICAqLwogICAgICA7CiAgICB9CgogIFMgKCI9PiIpOwogIGlmICh0cmFjZSkKICAgIHByaW50ZiAoIiAlMDJ4IiwgKm0pOwogIEUgKCk7CiAgcmV0dXJuICptOwp9Cgp1bnNpZ25lZCBjaGFyCm1lbV9nZXRfcWkgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgY2hhciBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgQ09VTlQgKDAsIDEpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBzaG9ydAptZW1fZ2V0X2hpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIHNob3J0IHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSAqIDI1NjsKICBDT1VOVCAoMCwgMik7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9wc2kgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgbG9uZyBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgKiAyNTY7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMikgKiA2NTUzNjsKICBDT1VOVCAoMCwgMyk7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9zaSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBsb25nIHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSA8PCA4OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDIpIDw8IDE2OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDMpIDw8IDI0OwogIENPVU5UICgwLCA0KTsKICBFICgpOwogIHJldHVybiBydjsKfQoKdm9pZAptZW1fZ2V0X2JsayAoaW50IGFkZHJlc3MsIHZvaWQgKmJ1ZnB0ciwgaW50IG5ieXRlcykKewogIFMgKCI9PiIpOwogIGlmIChlbmFibGVfY291bnRpbmcpCiAgICBtZW1fY291bnRlcnNbMF1bMV0gKz0gbmJ5dGVzOwogIHdoaWxlIChuYnl0ZXMtLSkKICAgICooY2hhciAqKSBidWZwdHIrKyA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcysrKTsKICBFICgpOwp9CgppbnQKc2lnbl9leHQgKGludCB2LCBpbnQgYml0cykKewogIGlmIChiaXRzIDwgMzIpCiAgICB7CiAgICAgIHYgJj0gKDEgPDwgYml0cykgLSAxOwogICAgICBpZiAodiAmICgxIDw8IChiaXRzIC0gMSkpKQoJdiAtPSAoMSA8PCBiaXRzKTsKICAgIH0KICByZXR1cm4gdjsKfQoKI2lmIFRJTUVSX0EKdm9pZAp1cGRhdGVfdGltZXJfYSAoKQp7CiAgaWYgKHRpbWVyX2EuYnNyICYgMSkKICAgIHsKICAgICAgdGltZXJfYS5wcmVzY2FsZS0tOwogICAgICBpZiAodGltZXJfYS5wcmVzY2FsZSA8IDApCgl7CgkgIGlmIChBMjQpCgkgICAgewoJICAgICAgc3dpdGNoICh0aW1lcl9hLm1vZGUgJiAweGMwKQoJCXsKCQljYXNlIDB4MDA6CgkJICB0aW1lcl9hLnByZXNjYWxlID0gMDsKCQkgIGJyZWFrOwoJCWNhc2UgMHg0MDoKCQkgIHRpbWVyX2EucHJlc2NhbGUgPSA4OwoJCSAgYnJlYWs7CgkJY2FzZSAweDgwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IHRpbWVyX2EudGNzcHIgJiAweDBmOwoJCSAgYnJlYWs7CgkJY2FzZSAweGMwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IDMyOwoJCSAgYnJlYWs7CgkJfQoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIHRpbWVyX2EucHJlc2NhbGUgPSB0aW1lcl9hLnRjc3ByOwoJICAgIH0KCSAgdGltZXJfYS5jb3VudC0tOwoJICBpZiAodGltZXJfYS5jb3VudCA8IDApCgkgICAgewoJICAgICAgdGltZXJfYS5jb3VudCA9IHRpbWVyX2EucmVsb2FkOwoJICAgICAgaWYgKHRpbWVyX2EuaWMgJiA3KQoJCXsKCQkgIGlmIChBMjQpCgkJICAgIG1lbV9wdXRfcWkgKDB4NmMsIHRpbWVyX2EuaWMgfCAweDA4KTsKCQkgIGVsc2UKCQkgICAgbWVtX3B1dF9xaSAoMHg1NiwgdGltZXJfYS5pYyB8IDB4MDgpOwoJCX0KCSAgICB9Cgl9CiAgICB9CgogIGlmIChyZWdzLnJfZmxhZ3MgJiBGTEFHQklUX0kJLyogaW50ZXJydXB0cyBlbmFibGVkICovCiAgICAgICYmIHRpbWVyX2EuaWMgJiAweDA4CS8qIHRpbWVyIEEgaW50ZXJydXB0IHRyaWdnZXJlZCAqLwogICAgICAmJiAodGltZXJfYS5pYyAmIDB4MDcpID4gKChyZWdzLnJfZmxhZ3MgPj4gMTIpICYgMHgwNykpCiAgICB7CiAgICAgIGlmIChBMjQpCgl0cmlnZ2VyX3BlcmlwaGVyYWxfaW50ZXJydXB0ICgxMiwgMHgwNmMpOwogICAgICBlbHNlCgl0cmlnZ2VyX3BlcmlwaGVyYWxfaW50ZXJydXB0ICgyMiwgMHgwNTYpOwogICAgfQp9CiNlbmRpZgo=