LyogbWVtLmMgLS0tIG1lbW9yeSBmb3IgTTMyQyBzaW11bGF0b3IuCgpDb3B5cmlnaHQgKEMpIDIwMDUtMjAxNiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KQ29udHJpYnV0ZWQgYnkgUmVkIEhhdCwgSW5jLgoKVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEdOVSBzaW11bGF0b3JzLgoKVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KClRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLApidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCkdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgpZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQphbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICovCgoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpZmRlZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfVEVSTUlPU19ICiNpbmNsdWRlIDx0ZXJtaW9zLmg+CiNlbmRpZgoKI2luY2x1ZGUgIm1lbS5oIgojaW5jbHVkZSAiY3B1LmgiCiNpbmNsdWRlICJzeXNjYWxscy5oIgojaW5jbHVkZSAibWlzYy5oIgojaWZkZWYgVElNRVJfQQojaW5jbHVkZSAiaW50LmgiCiNpbmNsdWRlICJ0aW1lcl9hLmgiCiNlbmRpZgoKI2RlZmluZSBMMV9CSVRTICAoMTApCiNkZWZpbmUgTDJfQklUUyAgKDEwKQojZGVmaW5lIE9GRl9CSVRTICgxMikKCiNkZWZpbmUgTDFfTEVOICAoMSA8PCBMMV9CSVRTKQojZGVmaW5lIEwyX0xFTiAgKDEgPDwgTDJfQklUUykKI2RlZmluZSBPRkZfTEVOICgxIDw8IE9GRl9CSVRTKQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKipwdFtMMV9MRU5dOwoKI2lmZGVmIEhBVkVfVEVSTUlPU19ICmludCBtMzJjX2NvbnNvbGVfaWZkID0gMDsKI2VuZGlmCmludCBtMzJjX2NvbnNvbGVfb2ZkID0gMTsKI2lmZGVmIEhBVkVfVEVSTUlPU19ICmludCBtMzJjX3VzZV9yYXdfY29uc29sZSA9IDA7CiNlbmRpZgoKI2lmZGVmIFRJTUVSX0EKVGltZXJfQSB0aW1lcl9hOwojZW5kaWYKCi8qIFsgZ2V0PTAvcHV0PTEgXVsgYnl0ZSBzaXplIF0gKi8Kc3RhdGljIHVuc2lnbmVkIGludCBtZW1fY291bnRlcnNbMl1bNV07CgojZGVmaW5lIENPVU5UKGlzcHV0LGJ5dGVzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogIGlmICh2ZXJib3NlICYmIGVuYWJsZV9jb3VudGluZykgbWVtX2NvdW50ZXJzW2lzcHV0XVtieXRlc10rKwoKdm9pZAppbml0X21lbSAodm9pZCkKewogIGludCBpLCBqOwoKICBmb3IgKGkgPSAwOyBpIDwgTDFfTEVOOyBpKyspCiAgICBpZiAocHRbaV0pCiAgICAgIHsKCWZvciAoaiA9IDA7IGogPCBMMl9MRU47IGorKykKCSAgaWYgKHB0W2ldW2pdKQoJICAgIGZyZWUgKHB0W2ldW2pdKTsKCWZyZWUgKHB0W2ldKTsKICAgICAgfQogIG1lbXNldCAocHQsIDAsIHNpemVvZiAocHQpKTsKICBtZW1zZXQgKG1lbV9jb3VudGVycywgMCwgc2l6ZW9mIChtZW1fY291bnRlcnMpKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKgptZW1fcHRyIChpbnQgYWRkcmVzcykKewogIHN0YXRpYyBpbnQgcmVjdXJzaW5nID0gMDsKICBpbnQgcHQxID0gKGFkZHJlc3MgPj4gKEwyX0JJVFMgKyBPRkZfQklUUykpICYgKCgxIDw8IEwxX0JJVFMpIC0gMSk7CiAgaW50IHB0MiA9IChhZGRyZXNzID4+IE9GRl9CSVRTKSAmICgoMSA8PCBMMl9CSVRTKSAtIDEpOwogIGludCBwdG8gPSBhZGRyZXNzICYgKCgxIDw8IE9GRl9CSVRTKSAtIDEpOwoKICBpZiAoYWRkcmVzcyA9PSAwICYmICFyZWN1cnNpbmcpCiAgICB7CiAgICAgIHJlY3Vyc2luZyA9IDE7CiAgICAgIHB1dF9yZWcgKHBjLCBtMzJjX29wY29kZV9wYyk7CiAgICAgIHByaW50ZiAoIk5VTEwgcG9pbnRlciBkZXJlZmVyZW5jZSBhdCBwYz0weCV4XG4iLCBnZXRfcmVnIChwYykpOwogICAgICBzdGVwX3Jlc3VsdCA9IE0zMkNfTUFLRV9ISVRfQlJFQUsgKCk7CiNpZiAwCiAgICAgIC8qIFRoaXMgY29kZSBjYW4gYmUgcmUtZW5hYmxlZCB0byBoZWxwIGRpYWdub3NlIE5VTEwgcG9pbnRlcgogICAgICAgICBidWdzIHRoYXQgYXJlbid0IGRlYnVnZ2FibGUgaW4gR0RCLiAgKi8KICAgICAgbTMyY19kdW1wX2FsbF9yZWdpc3RlcnMgKCk7CiAgICAgIGV4aXQgKDEpOwojZW5kaWYKICAgIH0KCiAgaWYgKHB0W3B0MV0gPT0gMCkKICAgIHB0W3B0MV0gPSAodW5zaWduZWQgY2hhciAqKikgY2FsbG9jIChMMl9MRU4sIHNpemVvZiAoY2hhciAqKikpOwogIGlmIChwdFtwdDFdW3B0Ml0gPT0gMCkKICAgIHsKICAgICAgcHRbcHQxXVtwdDJdID0gKHVuc2lnbmVkIGNoYXIgKikgbWFsbG9jIChPRkZfTEVOKTsKICAgICAgbWVtc2V0IChwdFtwdDFdW3B0Ml0sIDAsIE9GRl9MRU4pOwogICAgfQoKICByZXR1cm4gcHRbcHQxXVtwdDJdICsgcHRvOwp9CgpzdGF0aWMgdm9pZAp1c2VkIChpbnQgcnN0YXJ0LCBpbnQgaSwgaW50IGopCnsKICBpbnQgcmVuZCA9IGkgPDwgKEwyX0JJVFMgKyBPRkZfQklUUyk7CiAgcmVuZCArPSBqIDw8IE9GRl9CSVRTOwogIGlmIChyc3RhcnQgPT0gMHhlMDAwMCAmJiByZW5kID09IDB4ZTEwMDApCiAgICByZXR1cm47CiAgcHJpbnRmICgibWVtOiAgICUwOHggLSAlMDh4ICglZGsgYnl0ZXMpXG4iLCByc3RhcnQsIHJlbmQgLSAxLAoJICAocmVuZCAtIHJzdGFydCkgLyAxMDI0KTsKfQoKc3RhdGljIGNoYXIgKgptY3MgKGludCBpc3B1dCwgaW50IGJ5dGVzKQp7CiAgcmV0dXJuIGNvbW1hIChtZW1fY291bnRlcnNbaXNwdXRdW2J5dGVzXSk7Cn0KCnZvaWQKbWVtX3VzYWdlX3N0YXRzICh2b2lkKQp7CiAgaW50IGksIGo7CiAgaW50IHJzdGFydCA9IDA7CiAgaW50IHBlbmRpbmcgPSAwOwoKICBmb3IgKGkgPSAwOyBpIDwgTDFfTEVOOyBpKyspCiAgICBpZiAocHRbaV0pCiAgICAgIHsKCWZvciAoaiA9IDA7IGogPCBMMl9MRU47IGorKykKCSAgaWYgKHB0W2ldW2pdKQoJICAgIHsKCSAgICAgIGlmICghcGVuZGluZykKCQl7CgkJICBwZW5kaW5nID0gMTsKCQkgIHJzdGFydCA9IChpIDw8IChMMl9CSVRTICsgT0ZGX0JJVFMpKSArIChqIDw8IE9GRl9CSVRTKTsKCQl9CgkgICAgfQoJICBlbHNlIGlmIChwZW5kaW5nKQoJICAgIHsKCSAgICAgIHBlbmRpbmcgPSAwOwoJICAgICAgdXNlZCAocnN0YXJ0LCBpLCBqKTsKCSAgICB9CiAgICAgIH0KICAgIGVsc2UKICAgICAgewoJaWYgKHBlbmRpbmcpCgkgIHsKCSAgICBwZW5kaW5nID0gMDsKCSAgICB1c2VkIChyc3RhcnQsIGksIDApOwoJICB9CiAgICAgIH0KICAvKiAgICAgICBtZW0gZm9vOiAxMjM0NTY3ODkwMTIgMTIzNDU2Nzg5MDEyIDEyMzQ1Njc4OTAxMiAxMjM0NTY3ODkwMTIKICAgICAgICAgICAgMTIzNDU2Nzg5MDEyICovCiAgcHJpbnRmICgiICAgICAgICAgICAgICAgICBieXRlICAgICAgICBzaG9ydCAgICAgIHBvaW50ZXIgICAgICAgICBsb25nIgoJICAiICAgICAgICBmZXRjaFxuIik7CiAgcHJpbnRmICgibWVtIGdldDogJTEycyAlMTJzICUxMnMgJTEycyAlMTJzXG4iLCBtY3MgKDAsIDEpLCBtY3MgKDAsIDIpLAoJICBtY3MgKDAsIDMpLCBtY3MgKDAsIDQpLCBtY3MgKDAsIDApKTsKICBwcmludGYgKCJtZW0gcHV0OiAlMTJzICUxMnMgJTEycyAlMTJzXG4iLCBtY3MgKDEsIDEpLCBtY3MgKDEsIDIpLAoJICBtY3MgKDEsIDMpLCBtY3MgKDEsIDQpKTsKfQoKc3RhdGljIGludCB0cHIgPSAwOwpzdGF0aWMgdm9pZApzIChpbnQgYWRkcmVzcywgY2hhciAqZGlyKQp7CiAgaWYgKHRwciA9PSAwKQogICAgcHJpbnRmICgiTUVNWyUwKnhdICVzIiwgbWVtYnVzX21hc2sgPT0gMHhmZmZmZiA/IDUgOiA2LCBhZGRyZXNzLCBkaXIpOwogIHRwcisrOwp9CgojZGVmaW5lIFMoZCkgaWYgKHRyYWNlKSBzKGFkZHJlc3MsIGQpCnN0YXRpYyB2b2lkCmUgKHZvaWQpCnsKICBpZiAoIXRyYWNlKQogICAgcmV0dXJuOwogIHRwci0tOwogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIlxuIik7Cn0KCiNkZWZpbmUgRSgpIGlmICh0cmFjZSkgZSgpCgpleHRlcm4gaW50IG0zMmNfZGlzYXNzZW1ibGU7CgpzdGF0aWMgdm9pZAptZW1fcHV0X2J5dGUgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CiAgdW5zaWduZWQgY2hhciAqbTsKICBhZGRyZXNzICY9IG1lbWJ1c19tYXNrOwogIG0gPSBtZW1fcHRyIChhZGRyZXNzKTsKICBpZiAodHJhY2UpCiAgICBwcmludGYgKCIgJTAyeCIsIHZhbHVlKTsKICAqbSA9IHZhbHVlOwogIHN3aXRjaCAoYWRkcmVzcykKICAgIHsKICAgIGNhc2UgMHgwMGUxOgogICAgICB7CglzdGF0aWMgaW50IG9sZF9sZWQgPSAtMTsKCXN0YXRpYyBjaGFyICpsZWRfb25bXSA9CgkgIHsgIlwwMzNbMzFtIE8gIiwgIlwwMzNbMzJtIE8gIiwgIlwwMzNbMzRtIE8gIiB9OwoJc3RhdGljIGNoYXIgKmxlZF9vZmZbXSA9IHsgIlwwMzNbMG0gtyAiLCAiXDAzM1swbSC3ICIsICJcMDMzWzBtILcgIiB9OwoJaW50IGk7CglpZiAob2xkX2xlZCAhPSB2YWx1ZSkKCSAgewoJICAgIGZwdXRzICgiICAiLCBzdGRvdXQpOwoJICAgIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkgICAgICBpZiAodmFsdWUgJiAoMSA8PCBpKSkKCQlmcHV0cyAobGVkX29mZltpXSwgc3Rkb3V0KTsKCSAgICAgIGVsc2UKCQlmcHV0cyAobGVkX29uW2ldLCBzdGRvdXQpOwoJICAgIGZwdXRzICgiXDAzM1swbVxyIiwgc3Rkb3V0KTsKCSAgICBmZmx1c2ggKHN0ZG91dCk7CgkgICAgb2xkX2xlZCA9IHZhbHVlOwoJICB9CiAgICAgIH0KICAgICAgYnJlYWs7CiNpZmRlZiBUSU1FUl9BCiAgICAgIC8qIE0zMkMgVGltZXIgQSAqLwogICAgY2FzZSAweDM0NjoJCS8qIFRBMGxvdyAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gKHRpbWVyX2EuY291bnQgJiAweGZmMDApIHwgdmFsdWU7CiAgICAgIHRpbWVyX2EucmVsb2FkID0gdGltZXJfYS5jb3VudDsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MzQ3OgkJLyogVEEwaGlnaCAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gKHRpbWVyX2EuY291bnQgJiAweDAwZmYpIHwgKHZhbHVlIDw8IDgpOwogICAgICB0aW1lcl9hLnJlbG9hZCA9IHRpbWVyX2EuY291bnQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM0MDoJCS8qIFRBQlNSICovCiAgICAgIHRpbWVyX2EuYnNyID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM1NjoJCS8qIFRBME1SICovCiAgICAgIHRpbWVyX2EubW9kZSA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgzNWY6CQkvKiBUQ1NQUiAqLwogICAgICB0aW1lcl9hLnRjc3ByID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDAwNmM6CQkvKiBUQTBJQyAqLwogICAgICB0aW1lcl9hLmljID0gdmFsdWU7CiAgICAgIGJyZWFrOwoKICAgICAgLyogUjhDIFRpbWVyIFJBICovCiAgICBjYXNlIDB4MTAwOgkJLyogVFJBQ1IgKi8KICAgICAgdGltZXJfYS5ic3IgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MTAyOgkJLyogVFJBTVIgKi8KICAgICAgdGltZXJfYS5tb2RlID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDEwNDoJCS8qIFRSQSAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gdmFsdWU7CiAgICAgIHRpbWVyX2EucmVsb2FkID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDEwMzoJCS8qIFRSQVBSRSAqLwogICAgICB0aW1lcl9hLnRjc3ByID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDAwNTY6CQkvKiBUQTBJQyAqLwogICAgICB0aW1lcl9hLmljID0gdmFsdWU7CiAgICAgIGJyZWFrOwojZW5kaWYKCiAgICBjYXNlIDB4MmVhOgkJLyogbTMyYyB1YXJ0MXR4ICovCiAgICBjYXNlIDB4M2FhOgkJLyogbTE2YyB1YXJ0MXR4ICovCiAgICAgIHsKCXN0YXRpYyBpbnQgcGVuZGluZ19leGl0ID0gMDsKCWlmICh2YWx1ZSA9PSAwKQoJICB7CgkgICAgaWYgKHBlbmRpbmdfZXhpdCkKCSAgICAgIHsKCQlzdGVwX3Jlc3VsdCA9IE0zMkNfTUFLRV9FWElURUQgKHZhbHVlKTsKCQlyZXR1cm47CgkgICAgICB9CgkgICAgcGVuZGluZ19leGl0ID0gMTsKCSAgfQoJZWxzZQoJICB7CgkgICAgd3JpdGUgKG0zMmNfY29uc29sZV9vZmQsICZ2YWx1ZSwgMSk7CgkgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAwOgogICAgICBtMzJjX3N5c2NhbGwgKHZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAweDQwMToKICAgICAgcHV0Y2hhciAodmFsdWUpOwogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAyOgogICAgICBwcmludGYgKCJTaW1UcmFjZTogJTA2bHggJTAyeFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDM6CiAgICAgIHByaW50ZiAoIlNpbVRyYXA6ICUwNmx4ICUwMnhcbiIsIHJlZ3Mucl9wYywgdmFsdWUpOwogICAgICBhYm9ydCAoKTsKICAgIH0KfQoKdm9pZAptZW1fcHV0X3FpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgY2hhciB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBFICgpOwogIENPVU5UICgxLCAxKTsKfQoKdm9pZAptZW1fcHV0X2hpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgc2hvcnQgdmFsdWUpCnsKICBpZiAoYWRkcmVzcyA9PSAweDQwMikKICAgIHsKICAgICAgcHJpbnRmICgiU2ltVHJhY2U6ICUwNmx4ICUwNHhcbiIsIHJlZ3Mucl9wYywgdmFsdWUpOwogICAgICByZXR1cm47CiAgICB9CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDEsIHZhbHVlID4+IDgpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDIpOwp9Cgp2b2lkCm1lbV9wdXRfcHNpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgbG9uZyB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAxLCAodmFsdWUgPj4gOCkgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAyLCB2YWx1ZSA+PiAxNik7CiAgRSAoKTsKICBDT1VOVCAoMSwgMyk7Cn0KCnZvaWQKbWVtX3B1dF9zaSAoaW50IGFkZHJlc3MsIHVuc2lnbmVkIGxvbmcgdmFsdWUpCnsKICBTICgiPD0iKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MsIHZhbHVlICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMSwgKHZhbHVlID4+IDgpICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMiwgKHZhbHVlID4+IDE2KSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDMsICh2YWx1ZSA+PiAyNCkgJiAweGZmKTsKICBFICgpOwogIENPVU5UICgxLCA0KTsKfQoKdm9pZAptZW1fcHV0X2JsayAoaW50IGFkZHJlc3MsIGNvbnN0IHZvaWQgKmJ1ZnB0ciwgaW50IG5ieXRlcykKewogIFMgKCI8PSIpOwogIGlmIChlbmFibGVfY291bnRpbmcpCiAgICBtZW1fY291bnRlcnNbMV1bMV0gKz0gbmJ5dGVzOwogIHdoaWxlIChuYnl0ZXMtLSkKICAgIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcysrLCAqKGNvbnN0IHVuc2lnbmVkIGNoYXIgKikgYnVmcHRyKyspOwogIEUgKCk7Cn0KCnVuc2lnbmVkIGNoYXIKbWVtX2dldF9wYyAodm9pZCkKewogIHVuc2lnbmVkIGNoYXIgKm0gPSBtZW1fcHRyIChyZWdzLnJfcGMgJiBtZW1idXNfbWFzayk7CiAgQ09VTlQgKDAsIDApOwogIHJldHVybiAqbTsKfQoKI2lmZGVmIEhBVkVfVEVSTUlPU19ICnN0YXRpYyBpbnQgY29uc29sZV9yYXcgPSAwOwpzdGF0aWMgc3RydWN0IHRlcm1pb3Mgb2F0dHI7CgpzdGF0aWMgaW50CnN0ZGluX3JlYWR5ICh2b2lkKQp7CiAgZmRfc2V0IGlmZDsKICBpbnQgbjsKICBzdHJ1Y3QgdGltZXZhbCB0OwoKICB0LnR2X3NlYyA9IDA7CiAgdC50dl91c2VjID0gMDsKICBGRF9aRVJPICgmaWZkKTsKICBGRF9TRVQgKG0zMmNfY29uc29sZV9pZmQsICZpZmQpOwogIG4gPSBzZWxlY3QgKDEsICZpZmQsIDAsIDAsICZ0KTsKICByZXR1cm4gbiA+IDA7Cn0KCnZvaWQKbTMyY19zaW1fcmVzdG9yZV9jb25zb2xlICh2b2lkKQp7CiAgaWYgKGNvbnNvbGVfcmF3KQogICAgdGNzZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCBUQ1NBTk9XLCAmb2F0dHIpOwogIGNvbnNvbGVfcmF3ID0gMDsKfQojZW5kaWYKCnN0YXRpYyB1bnNpZ25lZCBjaGFyCm1lbV9nZXRfYnl0ZSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBjaGFyICptOwogIGFkZHJlc3MgJj0gbWVtYnVzX21hc2s7CiAgbSA9IG1lbV9wdHIgKGFkZHJlc3MpOwogIHN3aXRjaCAoYWRkcmVzcykKICAgIHsKI2lmZGVmIEhBVkVfVEVSTUlPU19ICiAgICBjYXNlIDB4MmVkOgkJLyogbTMyYyB1YXJ0MWMxICovCiAgICBjYXNlIDB4M2FkOgkJLyogbTE2YyB1YXJ0MWMxICovCgogICAgICBpZiAoIWNvbnNvbGVfcmF3ICYmIG0zMmNfdXNlX3Jhd19jb25zb2xlKQoJewoJICBzdHJ1Y3QgdGVybWlvcyBhdHRyOwoJICB0Y2dldGF0dHIgKG0zMmNfY29uc29sZV9pZmQsICZhdHRyKTsKCSAgdGNnZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCAmb2F0dHIpOwoJICAvKiBXZSB3YW50IGVhY2gga2V5IHRvIGJlIHNlbnQgYXMgdGhlIHVzZXIgcHJlc3NlcyB0aGVtLiAgKi8KCSAgYXR0ci5jX2xmbGFnICY9IH4oSUNBTk9OIHwgRUNITyB8IEVDSE9FKTsKCSAgdGNzZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCBUQ1NBTk9XLCAmYXR0cik7CgkgIGNvbnNvbGVfcmF3ID0gMTsKCSAgYXRleGl0IChtMzJjX3NpbV9yZXN0b3JlX2NvbnNvbGUpOwoJfQoKICAgICAgaWYgKHN0ZGluX3JlYWR5ICgpKQoJcmV0dXJuIDB4MDI7CQkvKiB0eCBlbXB0eSBhbmQgcnggZnVsbCAqLwogICAgICBlbHNlCglyZXR1cm4gMHgwYTsJCS8qIHRyYW5zbWl0dGVyIGVtcHR5ICovCgogICAgY2FzZSAweDJlZToJCS8qIG0zMmMgdWFydDEgcnggKi8KICAgICAgewoJY2hhciBjOwoJcmVhZCAobTMyY19jb25zb2xlX2lmZCwgJmMsIDEpOwoJaWYgKG0zMmNfY29uc29sZV9pZmQgPT0gMCAmJiBjID09IDMpCS8qIEN0cmwtQyAqLwoJICB7CgkgICAgcHJpbnRmICgiQ3RybC1DIVxuIik7CgkgICAgZXhpdCAoMCk7CgkgIH0KCglpZiAobTMyY19jb25zb2xlX2lmZCAhPSAxKQoJICB7CgkgICAgaWYgKGlzZ3JhcGggKGMpKQoJICAgICAgcHJpbnRmICgiXDAzM1szMW0lY1wwMzNbMG0iLCBjKTsKCSAgICBlbHNlCgkgICAgICBwcmludGYgKCJcMDMzWzMxbSUwMnhcMDMzWzBtIiwgYyk7CgkgIH0KCXJldHVybiBjOwogICAgICB9CiNlbmRpZgoKI2lmZGVmIFRJTUVSX0EKICAgIGNhc2UgMHgzNDY6CQkvKiBUQTBsb3cgKi8KICAgICAgcmV0dXJuIHRpbWVyX2EuY291bnQgJiAweGZmOwogICAgY2FzZSAweDM0NzoJCS8qIFRBMGhpZ2ggKi8KICAgICAgcmV0dXJuICh0aW1lcl9hLmNvdW50ID4+IDgpICYgMHhmZjsKICAgIGNhc2UgMHgxMDQ6CQkvKiBUUkEgKi8KICAgICAgcmV0dXJuIHRpbWVyX2EuY291bnQ7CiNlbmRpZgoKICAgIGRlZmF1bHQ6CiAgICAgIC8qIEluIGNhc2UgYm90aCBjYXNlcyBhYm92ZSBhcmUgbm90IGluY2x1ZGVkLiAgKi8KICAgICAgOwogICAgfQoKICBTICgiPT4iKTsKICBpZiAodHJhY2UpCiAgICBwcmludGYgKCIgJTAyeCIsICptKTsKICBFICgpOwogIHJldHVybiAqbTsKfQoKdW5zaWduZWQgY2hhcgptZW1fZ2V0X3FpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIGNoYXIgcnY7CiAgUyAoIj0+Iik7CiAgcnYgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MpOwogIENPVU5UICgwLCAxKTsKICBFICgpOwogIHJldHVybiBydjsKfQoKdW5zaWduZWQgc2hvcnQKbWVtX2dldF9oaSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBzaG9ydCBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgKiAyNTY7CiAgQ09VTlQgKDAsIDIpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBsb25nCm1lbV9nZXRfcHNpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIGxvbmcgcnY7CiAgUyAoIj0+Iik7CiAgcnYgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MpOwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDEpICogMjU2OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDIpICogNjU1MzY7CiAgQ09VTlQgKDAsIDMpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBsb25nCm1lbV9nZXRfc2kgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgbG9uZyBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgPDwgODsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAyKSA8PCAxNjsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAzKSA8PCAyNDsKICBDT1VOVCAoMCwgNCk7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnZvaWQKbWVtX2dldF9ibGsgKGludCBhZGRyZXNzLCB2b2lkICpidWZwdHIsIGludCBuYnl0ZXMpCnsKICBTICgiPT4iKTsKICBpZiAoZW5hYmxlX2NvdW50aW5nKQogICAgbWVtX2NvdW50ZXJzWzBdWzFdICs9IG5ieXRlczsKICB3aGlsZSAobmJ5dGVzLS0pCiAgICAqKGNoYXIgKikgYnVmcHRyKysgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MrKyk7CiAgRSAoKTsKfQoKaW50CnNpZ25fZXh0IChpbnQgdiwgaW50IGJpdHMpCnsKICBpZiAoYml0cyA8IDMyKQogICAgewogICAgICB2ICY9ICgxIDw8IGJpdHMpIC0gMTsKICAgICAgaWYgKHYgJiAoMSA8PCAoYml0cyAtIDEpKSkKCXYgLT0gKDEgPDwgYml0cyk7CiAgICB9CiAgcmV0dXJuIHY7Cn0KCiNpZiBUSU1FUl9BCnZvaWQKdXBkYXRlX3RpbWVyX2EgKHZvaWQpCnsKICBpZiAodGltZXJfYS5ic3IgJiAxKQogICAgewogICAgICB0aW1lcl9hLnByZXNjYWxlLS07CiAgICAgIGlmICh0aW1lcl9hLnByZXNjYWxlIDwgMCkKCXsKCSAgaWYgKEEyNCkKCSAgICB7CgkgICAgICBzd2l0Y2ggKHRpbWVyX2EubW9kZSAmIDB4YzApCgkJewoJCWNhc2UgMHgwMDoKCQkgIHRpbWVyX2EucHJlc2NhbGUgPSAwOwoJCSAgYnJlYWs7CgkJY2FzZSAweDQwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IDg7CgkJICBicmVhazsKCQljYXNlIDB4ODA6CgkJICB0aW1lcl9hLnByZXNjYWxlID0gdGltZXJfYS50Y3NwciAmIDB4MGY7CgkJICBicmVhazsKCQljYXNlIDB4YzA6CgkJICB0aW1lcl9hLnByZXNjYWxlID0gMzI7CgkJICBicmVhazsKCQl9CgkgICAgfQoJICBlbHNlCgkgICAgewoJICAgICAgdGltZXJfYS5wcmVzY2FsZSA9IHRpbWVyX2EudGNzcHI7CgkgICAgfQoJICB0aW1lcl9hLmNvdW50LS07CgkgIGlmICh0aW1lcl9hLmNvdW50IDwgMCkKCSAgICB7CgkgICAgICB0aW1lcl9hLmNvdW50ID0gdGltZXJfYS5yZWxvYWQ7CgkgICAgICBpZiAodGltZXJfYS5pYyAmIDcpCgkJewoJCSAgaWYgKEEyNCkKCQkgICAgbWVtX3B1dF9xaSAoMHg2YywgdGltZXJfYS5pYyB8IDB4MDgpOwoJCSAgZWxzZQoJCSAgICBtZW1fcHV0X3FpICgweDU2LCB0aW1lcl9hLmljIHwgMHgwOCk7CgkJfQoJICAgIH0KCX0KICAgIH0KCiAgaWYgKHJlZ3Mucl9mbGFncyAmIEZMQUdCSVRfSQkvKiBpbnRlcnJ1cHRzIGVuYWJsZWQgKi8KICAgICAgJiYgdGltZXJfYS5pYyAmIDB4MDgJLyogdGltZXIgQSBpbnRlcnJ1cHQgdHJpZ2dlcmVkICovCiAgICAgICYmICh0aW1lcl9hLmljICYgMHgwNykgPiAoKHJlZ3Mucl9mbGFncyA+PiAxMikgJiAweDA3KSkKICAgIHsKICAgICAgaWYgKEEyNCkKCXRyaWdnZXJfcGVyaXBoZXJhbF9pbnRlcnJ1cHQgKDEyLCAweDA2Yyk7CiAgICAgIGVsc2UKCXRyaWdnZXJfcGVyaXBoZXJhbF9pbnRlcnJ1cHQgKDIyLCAweDA1Nik7CiAgICB9Cn0KI2VuZGlmCg==