LyoKICogIGxpbnV4L2FyY2gvbTY4ay90b29scy9hbWlnYS9kbWVzZy5jIC0tIFJldHJpZXZlIHRoZSBrZXJuZWwgbWVzc2FnZXMgc3RvcmVkCiAqCQkJCQkgICBpbiBDaGlwIFJBTSB3aXRoIHRoZSBrZXJuZWwgY29tbWFuZAogKgkJCQkJICAgbGluZSBvcHRpb24gYGRlYnVnPW1lbScuCiAqCiAqICCpIENvcHlyaWdodCAxOTk2IGJ5IEdlZXJ0IFV5dHRlcmhvZXZlbiA8Z2VlcnRAbGludXgtbTY4ay5vcmc+CiAqCiAqCiAqICBVc2FnZToKICoKICoJZG1lc2cKICoJZG1lc2cgPENISVBNRU1fRU5EPgogKgogKgogKiAgVGhpcyBmaWxlIGlzIHN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKICogIExpY2Vuc2UuICBTZWUgdGhlIGZpbGUgQ09QWUlORyBpbiB0aGUgbWFpbiBkaXJlY3Rvcnkgb2YgdGhlIExpbnV4CiAqICBkaXN0cmlidXRpb24gZm9yIG1vcmUgZGV0YWlscy4KICovCgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgoKCiNkZWZpbmUgQ0hJUE1FTV9TVEFSVAkweDAwMDAwMDAwCiNkZWZpbmUgQ0hJUE1FTV9FTkQJMHgwMDIwMDAwMAkvKiBvdmVycmlkZGVuIGJ5IGFyZ3ZbMV0gKi8KCiNkZWZpbmUgU0FWRUtNU0dfTUFHSUMxCTB4NTM0MTU2NDUJLyogJ1NBVkUnICovCiNkZWZpbmUgU0FWRUtNU0dfTUFHSUMyCTB4NEI0RDUzNDcJLyogJ0tNU0cnICovCgpzdHJ1Y3Qgc2F2ZWttc2cgewogICAgdV9sb25nIG1hZ2ljMTsJLyogU0FWRUtNU0dfTUFHSUMxICovCiAgICB1X2xvbmcgbWFnaWMyOwkvKiBTQVZFS01TR19NQUdJQzIgKi8KICAgIHVfbG9uZyBtYWdpY3B0cjsJLyogYWRkcmVzcyBvZiBtYWdpYzEgKi8KICAgIHVfbG9uZyBzaXplOwogICAgY2hhciBkYXRhWzBdOwp9OwoKCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pCnsKICAgIHVfbG9uZyBzdGFydCA9IENISVBNRU1fU1RBUlQsIGVuZCA9IENISVBNRU1fRU5ELCBwOwogICAgaW50IGZvdW5kID0gMDsKICAgIHN0cnVjdCBzYXZla21zZyAqbSA9IE5VTEw7CgogICAgaWYgKGFyZ2MgPj0gMikKCWVuZCA9IHN0cnRvdWwoYXJndlsxXSwgTlVMTCwgMCk7CiAgICBwcmludGYoIlNlYXJjaGluZyBmb3IgU0FWRUtNU0cgbWFnaWMuLi5cbiIpOwogICAgZm9yIChwID0gc3RhcnQ7IHAgPD0gZW5kLXNpemVvZihzdHJ1Y3Qgc2F2ZWttc2cpOyBwICs9IDQpIHsKCW0gPSAoc3RydWN0IHNhdmVrbXNnICopcDsKCWlmICgobS0+bWFnaWMxID09IFNBVkVLTVNHX01BR0lDMSkgJiYgKG0tPm1hZ2ljMiA9PSBTQVZFS01TR19NQUdJQzIpICYmCgkgICAgKG0tPm1hZ2ljcHRyID09IHApKSB7CgkgICAgZm91bmQgPSAxOwoJICAgIGJyZWFrOwoJfQogICAgfQogICAgaWYgKCFmb3VuZCkKCXByaW50ZigiTm90IGZvdW5kXG4iKTsKICAgIGVsc2UgewoJcHJpbnRmKCJGb3VuZCAlbGQgYnl0ZXMgYXQgMHglMDhseFxuIiwgbS0+c2l6ZSwgKHVfbG9uZykmbS0+ZGF0YSk7CglwdXRzKCI+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+PiIpOwoJZmZsdXNoKHN0ZG91dCk7Cgl3cml0ZSgxLCAmbS0+ZGF0YSwgbS0+c2l6ZSk7CglmZmx1c2goc3Rkb3V0KTsKCXB1dHMoIjw8PDw8PDw8PDw8PDw8PDw8PDw8Iik7CiAgICB9CiAgICByZXR1cm4oMCk7Cn0K