CgovLyAgYmFzZTY0LmhwcCAKLy8gIEF1dG9yIEtvbnN0YW50aW4gUGlsaXBjaHVrCi8vICBtYWlsdG86bG9zdGRAdWtyLm5ldAovLwovLwoKI2lmICFkZWZpbmVkKF9fQkFTRTY0X0hfSU5DTFVERURfXykKI2RlZmluZSBfX0JBU0U2NF9IX0lOQ0xVREVEX18gMQoKI2lmbmRlZiBNQUtFREVQRU5ECiMgaW5jbHVkZSA8aW9zdHJlYW0+CiMgaW5jbHVkZSA8aXRlcmF0b3I+CiNlbmRpZgoKc3RhdGljCmludCBfYmFzZTY0Q2hhcnNbXT0geydBJywnQicsJ0MnLCdEJywnRScsJ0YnLCdHJywnSCcsJ0knLCdKJywnSycsJ0wnLCdNJywnTicsJ08nLCdQJywnUScsJ1InLCdTJywnVCcsJ1UnLCdWJywnVycsJ1gnLCdZJywnWicsCgkJCQkgICAgICdhJywnYicsJ2MnLCdkJywnZScsJ2YnLCdnJywnaCcsJ2knLCdqJywnaycsJ2wnLCdtJywnbicsJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywndycsJ3gnLCd5JywneicsCgkJCSAgICAgICAgICcwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JywKCQkJICAgICAgICAgJysnLCcvJyB9OwoKCiNkZWZpbmUgXzAwMDBfMDAxMSAweDAzCiNkZWZpbmUgXzExMTFfMTEwMCAweEZDCiNkZWZpbmUgXzExMTFfMDAwMCAweEYwCiNkZWZpbmUgXzAwMTFfMDAwMCAweDMwCiNkZWZpbmUgXzAwMTFfMTEwMCAweDNDCiNkZWZpbmUgXzAwMDBfMTExMSAweDBGCiNkZWZpbmUgXzExMDBfMDAwMCAweEMwCiNkZWZpbmUgXzAwMTFfMTExMSAweDNGCgojZGVmaW5lIF9FUVVBTF9DSEFSICAgKC0xKQojZGVmaW5lIF9VTktOT1dOX0NIQVIgKC0yKQoKI2RlZmluZSBfSU9TX0ZBSUxCSVQgICBzdGQ6Omlvc19iYXNlOjpmYWlsYml0CiNkZWZpbmUgX0lPU19FT0ZCSVQgICAgc3RkOjppb3NfYmFzZTo6ZW9mYml0CiNkZWZpbmUgX0lPU19CQURCSVQgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0CiNkZWZpbmUgX0lPU19HT09EQklUICAgc3RkOjppb3NfYmFzZTo6Z29vZGJpdAoKLy8gVEVNUExBVEUgQ0xBU1MgYmFzZTY0X3B1dAp0ZW1wbGF0ZTxjbGFzcyBfRSA9IGNoYXIsIGNsYXNzIF9UciA9IHN0ZDo6Y2hhcl90cmFpdHM8X0U+ID4KY2xhc3MgYmFzZTY0CnsKcHVibGljOgoKCXR5cGVkZWYgdW5zaWduZWQgY2hhciBieXRlX3Q7Cgl0eXBlZGVmIF9FICAgICAgICAgICAgY2hhcl90eXBlOwoJdHlwZWRlZiBfVHIgICAgICAgICAgIHRyYWl0c190eXBlOyAKCgkvLyBiYXNlNjQgcmVxdWlyZXMgbWF4IGxpbmUgbGVuZ3RoIDw9IDcyIGNoYXJhY3RlcnMKCS8vIHlvdSBjYW4gZmlsbCBlbmQgb2YgbGluZQoJLy8gaXQgbWF5IGJlIGNybGYsIGNybGZzcCwgbm9saW5lIG9yIG90aGVyIGNsYXNzIGxpa2UgaXQKCgoJc3RydWN0IGNybGYKCXsKCQl0ZW1wbGF0ZTxjbGFzcyBfT0k+CgkJCV9PSSBvcGVyYXRvcigpKF9PSSBfVG8pIGNvbnN0ewoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJ1xyJyk7ICsrX1RvOwoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJ1xuJyk7ICsrX1RvOwoKCQkJcmV0dXJuIChfVG8pOwoJCX0KCX07CgoKCXN0cnVjdCBjcmxmc3AKCXsKCQl0ZW1wbGF0ZTxjbGFzcyBfT0k+CgkJCV9PSSBvcGVyYXRvcigpKF9PSSBfVG8pIGNvbnN0ewoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJ1xyJyk7ICsrX1RvOwoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJ1xuJyk7ICsrX1RvOwoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJyAnKTsgKytfVG87CgoJCQlyZXR1cm4gKF9Ubyk7CgkJfQoJfTsKCglzdHJ1Y3Qgbm9saW5lCgl7CgkJdGVtcGxhdGU8Y2xhc3MgX09JPgoJCQlfT0kgb3BlcmF0b3IoKShfT0kgX1RvKSBjb25zdHsKCQkJcmV0dXJuIChfVG8pOwoJCX0KCX07CgoJc3RydWN0IHRocmVlMmZvdXIKCXsKCQl2b2lkIHplcm8oKQoJCXsKCQkJX2RhdGFbMF0gPSAwOwoJCQlfZGF0YVsxXSA9IDA7CgkJCV9kYXRhWzJdID0gMDsKCQl9CgoJCWJ5dGVfdCBnZXRfMCgpCWNvbnN0CgkJewoJCQlyZXR1cm4gX2RhdGFbMF07CgkJfQoJCWJ5dGVfdCBnZXRfMSgpCWNvbnN0CgkJewoJCQlyZXR1cm4gX2RhdGFbMV07CgkJfQoJCWJ5dGVfdCBnZXRfMigpCWNvbnN0CgkJewoJCQlyZXR1cm4gX2RhdGFbMl07CgkJfQoKCQl2b2lkIHNldF8wKGJ5dGVfdCBfY2gpCgkJewoJCQlfZGF0YVswXSA9IF9jaDsKCQl9CgoJCXZvaWQgc2V0XzEoYnl0ZV90IF9jaCkKCQl7CgkJCV9kYXRhWzFdID0gX2NoOwoJCX0KCgkJdm9pZCBzZXRfMihieXRlX3QgX2NoKQoJCXsKCQkJX2RhdGFbMl0gPSBfY2g7CgkJfQoKCQkvLyAwMDAwIDAwMDAgIDExMTEgMTExMSAgMjIyMiAyMjIyCgkJLy8geHh4eCB4eHh4ICB4eHh4IHh4eHggIHh4eHggeHh4eAoJCS8vIDAwMDAgMDAxMSAgMTExMSAyMjIyICAyMjMzIDMzMzMKCgkJaW50IGI2NF8wKCkJY29uc3QJe3JldHVybiAoX2RhdGFbMF0gJiBfMTExMV8xMTAwKSA+PiAyO30KCQlpbnQgYjY0XzEoKQljb25zdAl7cmV0dXJuICgoX2RhdGFbMF0gJiBfMDAwMF8wMDExKSA8PCA0KSArICgoX2RhdGFbMV0gJiBfMTExMV8wMDAwKT4+NCk7fQoJCWludCBiNjRfMigpCWNvbnN0CXtyZXR1cm4gKChfZGF0YVsxXSAmIF8wMDAwXzExMTEpIDw8IDIpICsgKChfZGF0YVsyXSAmIF8xMTAwXzAwMDApPj42KTt9CgkJaW50IGI2NF8zKCkJY29uc3QJe3JldHVybiAoX2RhdGFbMl0gJiBfMDAxMV8xMTExKTt9CgoJCXZvaWQgYjY0XzAoaW50IF9jaCkJe19kYXRhWzBdID0gKChfY2ggJiBfMDAxMV8xMTExKSA8PCAyKSB8IChfMDAwMF8wMDExICYgX2RhdGFbMF0pO30KCgkJdm9pZCBiNjRfMShpbnQgX2NoKQl7CgkJCV9kYXRhWzBdID0gKChfY2ggJiBfMDAxMV8wMDAwKSA+PiA0KSB8IChfMTExMV8xMTAwICYgX2RhdGFbMF0pOwoJCQlfZGF0YVsxXSA9ICgoX2NoICYgXzAwMDBfMTExMSkgPDwgNCkgfCAoXzAwMDBfMTExMSAmIF9kYXRhWzFdKTsJfQoKCQl2b2lkIGI2NF8yKGludCBfY2gpCXsKCQkJX2RhdGFbMV0gPSAoKF9jaCAmIF8wMDExXzExMDApID4+IDIpIHwgKF8xMTExXzAwMDAgJiBfZGF0YVsxXSk7CgkJCV9kYXRhWzJdID0gKChfY2ggJiBfMDAwMF8wMDExKSA8PCA2KSB8IChfMDAxMV8xMTExICYgX2RhdGFbMl0pOwl9CgoJCXZvaWQgYjY0XzMoaW50IF9jaCl7CgkJCV9kYXRhWzJdID0gKF9jaCAmIF8wMDExXzExMTEpIHwgKF8xMTAwXzAwMDAgJiBfZGF0YVsyXSk7fQoKCXByaXZhdGU6CgkJYnl0ZV90IF9kYXRhWzNdOwoKCX07CgoKCgoJdGVtcGxhdGU8Y2xhc3MgX0lJLCBjbGFzcyBfT0ksIGNsYXNzIF9TdGF0ZSwgY2xhc3MgX0VuZGxpbmU+CgkJX0lJIHB1dChfSUkgX0ZpcnN0LCBfSUkgX0xhc3QsIF9PSSBfVG8sIF9TdGF0ZSYgLyogX1N0ICovLCBfRW5kbGluZSAvKiBfRW5kbCAqLykgIGNvbnN0Cgl7CgkJdGhyZWUyZm91ciBfM3RvNDsKCQlpbnQgbGluZV9vY3RldHMgPSAwOwoKCQl3aGlsZShfRmlyc3QgIT0gX0xhc3QpCgkJewoJCQlfM3RvNC56ZXJvKCk7CgoJCQkvLyDh5fC47CDv7iAzIPHo7OLu6+AKCQkJXzN0bzQuc2V0XzAoKl9GaXJzdCk7CgkJCV9GaXJzdCsrOwoKCQkJaWYoX0ZpcnN0ID09IF9MYXN0KQoJCQl7CgkJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoX2Jhc2U2NENoYXJzW18zdG80LmI2NF8wKCldKTsgKytfVG87CgkJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoX2Jhc2U2NENoYXJzW18zdG80LmI2NF8xKCldKTsgKytfVG87CgkJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJz0nKTsgKytfVG87CgkJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoJz0nKTsgKytfVG87CgkJCQlnb3RvIF9fZW5kOwoJCQl9CgoJCQlfM3RvNC5zZXRfMSgqX0ZpcnN0KTsKCQkJX0ZpcnN0Kys7CgoJCQlpZihfRmlyc3QgPT0gX0xhc3QpCgkJCXsKCQkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZShfYmFzZTY0Q2hhcnNbXzN0bzQuYjY0XzAoKV0pOyArK19UbzsKCQkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZShfYmFzZTY0Q2hhcnNbXzN0bzQuYjY0XzEoKV0pOyArK19UbzsKCQkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZShfYmFzZTY0Q2hhcnNbXzN0bzQuYjY0XzIoKV0pOyArK19UbzsKCQkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZSgnPScpOyArK19UbzsKCQkJCWdvdG8gX19lbmQ7CgkJCX0KCgkJCV8zdG80LnNldF8yKCpfRmlyc3QpOwoJCQlfRmlyc3QrKzsKCgkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZShfYmFzZTY0Q2hhcnNbXzN0bzQuYjY0XzAoKV0pOyArK19UbzsKCQkJKl9UbyA9IF9Ucjo6dG9fY2hhcl90eXBlKF9iYXNlNjRDaGFyc1tfM3RvNC5iNjRfMSgpXSk7ICsrX1RvOwoJCQkqX1RvID0gX1RyOjp0b19jaGFyX3R5cGUoX2Jhc2U2NENoYXJzW18zdG80LmI2NF8yKCldKTsgKytfVG87CgkJCSpfVG8gPSBfVHI6OnRvX2NoYXJfdHlwZShfYmFzZTY0Q2hhcnNbXzN0bzQuYjY0XzMoKV0pOyArK19UbzsKCgkJCWlmKGxpbmVfb2N0ZXRzID09IDE3KSAvLyBiYXNlNjQg7+7n4u7r/+XyIOTr6O3zIPHy8O7q6CDt5SDh7uvl5SA3MiDx6Ozi7uvu4goJCQl7CgkJCQkvL19UbyA9IF9FbmRsKF9Ubyk7CiAgICAgICAgKl9UbyA9ICdcbic7ICsrX1RvOwoJCQkJbGluZV9vY3RldHMgPSAwOwoJCQl9CgkJCWVsc2UKCQkJCSsrbGluZV9vY3RldHM7CgkJfQoKCQlfX2VuZDogOwoKCQlyZXR1cm4gKF9GaXJzdCk7CgoJfQoKCgl0ZW1wbGF0ZTxjbGFzcyBfSUksIGNsYXNzIF9PSSwgY2xhc3MgX1N0YXRlPgoJCV9JSSBnZXQoX0lJIF9GaXJzdCwgX0lJIF9MYXN0LCBfT0kgX1RvLCBfU3RhdGUmIF9TdCkgY29uc3QKCXsKCQl0aHJlZTJmb3VyIF8zdG80OwoJCWludCBfQ2hhcjsKCgkJd2hpbGUoX0ZpcnN0ICE9IF9MYXN0KQoJCXsKCgkJCS8vIFRha2Ugb2N0ZXQKCQkJXzN0bzQuemVybygpOwoKCQkJLy8gLS0gMCAtLQoJCQkvLyBTZWFyY2ggbmV4dCB2YWxpZCBjaGFyLi4uIAoJCQl3aGlsZSgoX0NoYXIgPSAgX2dldENoYXJUeXBlKCpfRmlyc3QpKSA8IDAgJiYgX0NoYXIgPT0gX1VOS05PV05fQ0hBUikKCQkJewoJCQkJaWYoKytfRmlyc3QgPT0gX0xhc3QpCgkJCQl7CgkJCQkJX1N0IHw9IF9JT1NfRkFJTEJJVHxfSU9TX0VPRkJJVDsgcmV0dXJuIF9GaXJzdDsgLy8gdW5leHBlY3RlZCBFT0YKCQkJCX0KCQkJfQoKCQkJaWYoX0NoYXIgPT0gX0VRVUFMX0NIQVIpewoJCQkJLy8gRXJyb3IhIEZpcnN0IGNoYXJhY3RlciBpbiBvY3RldCBjYW4ndCBiZSAnPScKCQkJCV9TdCB8PSBfSU9TX0ZBSUxCSVQ7IAoJCQkJcmV0dXJuIF9GaXJzdDsgCgkJCX0KCQkJZWxzZQoJCQkJXzN0bzQuYjY0XzAoX0NoYXIpOwoKCgkJCS8vIC0tIDEgLS0KCQkJLy8gU2VhcmNoIG5leHQgdmFsaWQgY2hhci4uLiAKCQkJd2hpbGUoKytfRmlyc3QgIT0gX0xhc3QpCgkJCQlpZigoX0NoYXIgPSBfZ2V0Q2hhclR5cGUoKl9GaXJzdCkpICE9IF9VTktOT1dOX0NIQVIpCgkJCQkJYnJlYWs7CgoJCQlpZihfRmlyc3QgPT0gX0xhc3QpCXsKCQkJCV9TdCB8PSBfSU9TX0ZBSUxCSVR8X0lPU19FT0ZCSVQ7IC8vIHVuZXhwZWN0ZWQgRU9GIAoJCQkJcmV0dXJuIF9GaXJzdDsKCQkJfQoKCQkJaWYoX0NoYXIgPT0gX0VRVUFMX0NIQVIpewoJCQkJLy8gRXJyb3IhIFNlY29uZCBjaGFyYWN0ZXIgaW4gb2N0ZXQgY2FuJ3QgYmUgJz0nCgkJCQlfU3QgfD0gX0lPU19GQUlMQklUOyAKCQkJCXJldHVybiBfRmlyc3Q7IAoJCQl9CgkJCWVsc2UKCQkJCV8zdG80LmI2NF8xKF9DaGFyKTsKCgoJCQkvLyAtLSAyIC0tCgkJCS8vIFNlYXJjaCBuZXh0IHZhbGlkIGNoYXIuLi4gCgkJCXdoaWxlKCsrX0ZpcnN0ICE9IF9MYXN0KQoJCQkJaWYoKF9DaGFyID0gX2dldENoYXJUeXBlKCpfRmlyc3QpKSAhPSBfVU5LTk9XTl9DSEFSKQoJCQkJCWJyZWFrOwoKCQkJaWYoX0ZpcnN0ID09IF9MYXN0KQl7CgkJCQkvLyBFcnJvciEgVW5leHBlY3RlZCBFT0YuIE11c3QgYmUgJz0nIG9yIGJhc2U2NCBjaGFyYWN0ZXIKCQkJCV9TdCB8PSBfSU9TX0ZBSUxCSVR8X0lPU19FT0ZCSVQ7IAoJCQkJcmV0dXJuIF9GaXJzdDsgCgkJCX0KCgkJCWlmKF9DaGFyID09IF9FUVVBTF9DSEFSKXsKCQkJCS8vIE9LIQoJCQkJXzN0bzQuYjY0XzIoMCk7IAoJCQkJXzN0bzQuYjY0XzMoMCk7IAoKCQkJCS8vIGNoZWsgZm9yIEVPRgoJCQkJaWYoKytfRmlyc3QgPT0gX0xhc3QpCgkJCQl7CgkJCQkJLy8gRXJyb3IhIFVuZXhwZWN0ZWQgRU9GLiBNdXN0IGJlICc9Jy4gSWdub3JlIGl0LgoJCQkJCS8vX1N0IHw9IF9JT1NfQkFEQklUfF9JT1NfRU9GQklUOwoJCQkJCV9TdCB8PSBfSU9TX0VPRkJJVDsKCQkJCX0KCQkJCWVsc2UgCgkJCQkJaWYoX2dldENoYXJUeXBlKCpfRmlyc3QpICE9IF9FUVVBTF9DSEFSKQoJCQkJCXsKCQkJCQkJLy8gRXJyb3IhIE11c3QgYmUgJz0nLiBJZ25vcmUgaXQuCgkJCQkJCS8vX1N0IHw9IF9JT1NfQkFEQklUOwoJCQkJCX0KCQkJCWVsc2UKCQkJCQkrK19GaXJzdDsgLy8gU2tpcCAnPScKCgkJCQkvLyB3cml0ZSAxIGJ5dGUgdG8gb3V0cHV0CgkJCQkqX1RvID0gKGJ5dGVfdCkgXzN0bzQuZ2V0XzAoKTsKCQkJCXJldHVybiBfRmlyc3Q7CgkJCX0KCQkJZWxzZQoJCQkJXzN0bzQuYjY0XzIoX0NoYXIpOwoKCgkJCS8vIC0tIDMgLS0KCQkJLy8gU2VhcmNoIG5leHQgdmFsaWQgY2hhci4uLiAKCQkJd2hpbGUoKytfRmlyc3QgIT0gX0xhc3QpCgkJCQlpZigoX0NoYXIgPSBfZ2V0Q2hhclR5cGUoKl9GaXJzdCkpICE9IF9VTktOT1dOX0NIQVIpCgkJCQkJYnJlYWs7CgoJCQlpZihfRmlyc3QgPT0gX0xhc3QpCXsKCQkJCS8vIFVuZXhwZWN0ZWQgRU9GLiBJdCdzIGVycm9yLiBCdXQgaWdub3JlIGl0LgoJCQkJLy9fU3QgfD0gX0lPU19GQUlMQklUfF9JT1NfRU9GQklUOyAKCQkJCQlfU3QgfD0gX0lPU19FT0ZCSVQ7IAoJCQkJCgkJCQlyZXR1cm4gX0ZpcnN0OyAKCQkJfQoKCQkJaWYoX0NoYXIgPT0gX0VRVUFMX0NIQVIpCgkJCXsKCQkJCS8vIE9LIQoJCQkJXzN0bzQuYjY0XzMoMCk7IAoKCQkJCS8vIHdyaXRlIHRvIG91dHB1dCAyIGJ5dGVzCgkJCQkqX1RvID0gKGJ5dGVfdCkgXzN0bzQuZ2V0XzAoKTsKCQkJCSpfVG8gPSAoYnl0ZV90KSBfM3RvNC5nZXRfMSgpOwoKCQkJCSsrX0ZpcnN0OyAvLyBzZXQgcG9zaXRpb24gdG8gbmV4dCBjaGFyYWN0ZXIKCgkJCQlyZXR1cm4gX0ZpcnN0OwoJCQl9CgkJCWVsc2UKCQkJCV8zdG80LmI2NF8zKF9DaGFyKTsKCgoJCQkvLyB3cml0ZSB0byBvdXRwdXQgMyBieXRlcwoJCQkqX1RvID0gKGJ5dGVfdCkgXzN0bzQuZ2V0XzAoKTsKCQkJKl9UbyA9IChieXRlX3QpIF8zdG80LmdldF8xKCk7CgkJCSpfVG8gPSAoYnl0ZV90KSBfM3RvNC5nZXRfMigpOwoKCQkJKytfRmlyc3Q7CgkJCQoKCQl9IC8vIHdoaWxlKF9GaXJzdCAhPSBfTGFzdCkKCgkJcmV0dXJuIChfRmlyc3QpOwoJfQoKcHJvdGVjdGVkOgoJCglpbnQgX2dldENoYXJUeXBlKGludCBfQ2gpIGNvbnN0Cgl7CgkJaWYoX2Jhc2U2NENoYXJzWzYyXSA9PSBfQ2gpCgkJCXJldHVybiA2MjsKCgkJaWYoX2Jhc2U2NENoYXJzWzYzXSA9PSBfQ2gpCgkJCXJldHVybiA2MzsKCgkJaWYoKF9iYXNlNjRDaGFyc1swXSA8PSBfQ2gpICYmIChfYmFzZTY0Q2hhcnNbMjVdID49IF9DaCkpCgkJCXJldHVybiBfQ2ggLSBfYmFzZTY0Q2hhcnNbMF07CgoJCWlmKChfYmFzZTY0Q2hhcnNbMjZdIDw9IF9DaCkgJiYgKF9iYXNlNjRDaGFyc1s1MV0gPj0gX0NoKSkKCQkJcmV0dXJuIF9DaCAtIF9iYXNlNjRDaGFyc1syNl0gKyAyNjsKCgkJaWYoKF9iYXNlNjRDaGFyc1s1Ml0gPD0gX0NoKSAmJiAoX2Jhc2U2NENoYXJzWzYxXSA+PSBfQ2gpKQoJCQlyZXR1cm4gX0NoIC0gX2Jhc2U2NENoYXJzWzUyXSArIDUyOwoKCQlpZihfQ2ggPT0gX1RyOjp0b19pbnRfdHlwZSgnPScpKQoJCQlyZXR1cm4gX0VRVUFMX0NIQVI7CgoJCXJldHVybiBfVU5LTk9XTl9DSEFSOwoJfQoKCn07CgoKI2VuZGlmCg==