LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKI2RlZmluZSBQUk9CRV9CVUZGRVJfU0laRSAxMDI0CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGJ1ZmZlcltQUk9CRV9CVUZGRVJfU0laRV07CgoKI2RlZmluZSBTQzUyMF9NQVhfRkxBU0hfQkFOS1MgIDEKI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMF9CQVNFIDB4MzgwMDAwMDAgIC8qIEJPT1RDUyAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTktTSVpFICAgMHg4MDAwMDAwCgojZGVmaW5lIEEyOUxWNjQxREhfU0laRSAgICAgICAgMHg4MDAwMDAKI2RlZmluZSBBMjlMVjY0MURIX1NFQ1RPUlMgICAgIDEyOAoKI2RlZmluZSBBMjlMVjY0MU1IX1NJWkUgICAgICAgIDB4ODAwMDAwCiNkZWZpbmUgQTI5TFY2NDFNSF9TRUNUT1JTICAgICAxMjgKCiNkZWZpbmUgSTI4RjMyMEozQV9TSVpFICAgICAgICAweDQwMDAwMAojZGVmaW5lIEkyOEYzMjBKM0FfU0VDVE9SUyAgICAgMzIKCiNkZWZpbmUgSTI4RjY0MEozQV9TSVpFICAgICAgICAweDgwMDAwMAojZGVmaW5lIEkyOEY2NDBKM0FfU0VDVE9SUyAgICAgNjQKCiNkZWZpbmUgSTI4RjEyOEozQV9TSVpFICAgICAgICAweDEwMDAwMDAKI2RlZmluZSBJMjhGMTI4SjNBX1NFQ1RPUlMgICAgIDEyOAoKZmxhc2hfaW5mb190ICAgIGZsYXNoX2luZm9bU0M1MjBfTUFYX0ZMQVNIX0JBTktTXTsKCiNkZWZpbmUgUkVBRFkgMQojZGVmaW5lIEVSUiAgIDIKI2RlZmluZSBUTU8gICA0CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKCnN0YXRpYyB1MzIgX3Byb2JlX2ZsYXNoKHUzMiBhZGRyLCB1MzIgYncsIGludCBpbCkKewoJdTMyIHJlc3VsdD0wOwoKCS8qIEZpcnN0IGRvIGFuIHVubG9jayBjeWNsZSBmb3IgdGhlIGJlbmVmaXQgb2YKCSAqIGRldmljZXMgdGhhdCBuZWVkIGl0ICovCgoJc3dpdGNoIChidykgewoKCWNhc2UgMToKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpID0gMHhhYTsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDJhYWEpID0gMHg1NTsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpID0gMHg5MDsKCgkJLyogUmVhZCB2ZW5kb3IgKi8KCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHU4KilhZGRyOwoJCXJlc3VsdCA8PD0gMTY7CgoJCS8qIFJlYWQgZGV2aWNlICovCgkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTgqKShhZGRyKzIpOwoKCQkvKiBSZXR1cm4gZGV2aWNlIHRvIGRhdGEgbW9kZSAqLwoJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NSksIDB4ZjA7CgkJYnJlYWs7CgoJY2FzZSAyOgoJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHhhYWFhOwoJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweDU1NTQpID0gMHg1NTU1OwoKCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJaWYgKGlsID09IDIpIHsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKzB4YWFhYSkgPSAweDkwOTA7CgoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHU4KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTgqKShhZGRyKzIpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MTYqKWFkZHIgPSAgMHhmZmZmOwoJCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSwgMHhmMGYwOwoKCQl9IGVsc2UgewoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpID0gMHg5MDsKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzIpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1OCopYWRkciA9IDB4ZmY7CgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4YWFhYSksIDB4ZjA7CgkJfQoKCQlicmVhazsKCgkgY2FzZSA0OgoJCSoodm9sYXRpbGUgdTMyKikoYWRkcisweDU1NTQpID0gMHhhYWFhYWFhYTsKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHhhYWE4KSA9IDB4NTU1NTU1NTU7CgoJCXN3aXRjaCAoaWwpIHsKCQljYXNlIDE6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU0KSA9IDB4OTA7CgoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHUxNiopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHUxNiopKGFkZHIrNCk7CgoJCQkvKiBSZXR1cm4gZGV2aWNlIHRvIGRhdGEgbW9kZSAqLwoJCQkqKHZvbGF0aWxlIHU4KilhZGRyID0gIDB4ZmY7CgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NCksIDB4ZjA7CgkJCWJyZWFrOwoKCQljYXNlIDI6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHg1NTU0KSA9IDB4MDA5MDAwOTA7CgoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHUxNiopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHUxNiopKGFkZHIrNCk7CgoJCQkvKiBSZXR1cm4gZGV2aWNlIHRvIGRhdGEgbW9kZSAqLwoJCQkqKHZvbGF0aWxlIHUzMiopYWRkciA9ICAweDAwZmYwMGZmOwoJCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSwgMHgwMGYwMDBmMDsKCQkJYnJlYWs7CgoJCWNhc2UgNDoKCQkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4OTA5MDkwOTA7CgoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHU4KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTgqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHhmZmZmZmZmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4ZjBmMGYwZjA7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCX0KCgoJcmV0dXJuIHJlc3VsdDsKfQoKZXh0ZXJuIGludCBfcHJvYmVfZmxhc2hfZW5kOwphc20gKCJfcHJvYmVfZmxhc2hfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCnN0YXRpYyBpbnQgaWRlbnRpZnlfZmxhc2godW5zaWduZWQgYWRkcmVzcywgaW50IHdpZHRoKQp7CglpbnQgaXM7CglpbnQgZGV2aWNlOwoJaW50IHZlbmRvcjsKCWludCBzaXplOwoJdW5zaWduZWQgcmVzOwoKCXUzMiAoKl9wcm9iZV9mbGFzaF9wdHIpKHUzMiBhLCB1MzIgYncsIGludCBpbCk7CgoJc2l6ZSA9ICh1bnNpZ25lZCkmX3Byb2JlX2ZsYXNoX2VuZCAtICh1bnNpZ25lZClfcHJvYmVfZmxhc2g7CgoJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCXByaW50ZigiX3Byb2JlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCSAgICAgICBzaXplLCAmX3Byb2JlX2ZsYXNoX2VuZCwgX3Byb2JlX2ZsYXNoKTsKCQlyZXR1cm4gMDsKCX0KCgltZW1jcHkoYnVmZmVyLCBfcHJvYmVfZmxhc2gsIHNpemUpOwoJX3Byb2JlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7CgoJaXMgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCXJlcyA9IF9wcm9iZV9mbGFzaF9wdHIoYWRkcmVzcywgd2lkdGgsIDEpOwoJaWYgKGlzKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCgoJdmVuZG9yID0gcmVzID4+IDE2OwoJZGV2aWNlID0gcmVzICYgMHhmZmZmOwoKCglyZXR1cm4gcmVzOwp9Cgp1bG9uZyBmbGFzaF9pbml0KHZvaWQpCnsKCWludCBpLCBqOwoJdWxvbmcgc2l6ZSA9IDA7CgoJZm9yIChpID0gMDsgaSA8IFNDNTIwX01BWF9GTEFTSF9CQU5LUzsgaSsrKSB7CgkJdW5zaWduZWQgaWQ7CgkJdWxvbmcgZmxhc2hiYXNlID0gMDsKCQlpbnQgc2VjdHNpemUgPSAwOwoKCQltZW1zZXQoZmxhc2hfaW5mb1tpXS5wcm90ZWN0LCAwLCBDRkdfTUFYX0ZMQVNIX1NFQ1QpOwoJCXN3aXRjaCAoaSkgewoJCWNhc2UgMDoKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzBfQkFTRTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcGFuaWMoImNvbmZpZ3VyZWQgdG9vIG1hbnkgZmxhc2ggYmFua3MhXG4iKTsKCQl9CgoJCWlkID0gaWRlbnRpZnlfZmxhc2goZmxhc2hiYXNlLCAyKTsKCQlzd2l0Y2ggKGlkKSB7CgkJY2FzZSAweDAwMDEyMmQ3OgoJCQkvKiAyOUxWNjQxREggKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFY2NDBVICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQTI5TFY2NDFESF9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEEyOUxWNjQxREhfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBBMjlMVjY0MURIX1NJWkUvQTI5TFY2NDFESF9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEFNRCAyOUxWNjQxREhcbiIsIGkpOwoJCQlicmVhazsKCgkJY2FzZSAweDAwMDEyMjdFOgoJCQkvKiAyOUxWNjQxTUggKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfREw2NDAgJiBGTEFTSF9UWVBFTUFTSyk7CgoJCQlmbGFzaF9pbmZvW2ldLnNpemUgPSBBMjlMVjY0MU1IX1NJWkU7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQTI5TFY2NDFNSF9TRUNUT1JTOwoJCQlzZWN0c2l6ZSA9IEEyOUxWNjQxTUhfU0laRS9BMjlMVjY0MU1IX1NFQ1RPUlM7CgkJCXByaW50ZigiQmFuayAlZDogQU1EIDI5TFY2NDFNSFxuIiwgaSk7CgkJCWJyZWFrOwoKCQljYXNlIDB4MDA4OTAwMTY6CgkJCS8qIDI4RjMyMEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGMzIwSjNBICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjMyMEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEYzMjBKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGMzIwSjNBX1NJWkUvSTI4RjMyMEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjMyMEozQVxuIiwgaSk7CgkJCWJyZWFrOwoKCQljYXNlIDB4MDA4OTAwMTc6CgkJCS8qIDI4RjY0MEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGNjQwSjNBICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjY0MEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEY2NDBKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGNjQwSjNBX1NJWkUvSTI4RjY0MEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjY0MEozQVxuIiwgaSk7CgkJCWJyZWFrOwoKCQljYXNlIDB4MDA4OTAwMTg6CgkJCS8qIDI4RjEyOEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGMTI4SjNBICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjEyOEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEYxMjhKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGMTI4SjNBX1NJWkUvSTI4RjEyOEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjEyOEozQVxuIiwgaSk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlwcmludGYoIkJhbmsgJWQgaGF2ZSB1bmtub3duIGZsYXNoICUwOHhcbiIsIGksIGlkKTsKCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9IEZMQVNIX1VOS05PV047CgkJCWNvbnRpbnVlOwoJCX0KCgkJZm9yIChqID0gMDsgaiA8IGZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50OyBqKyspIHsKCQkJZmxhc2hfaW5mb1tpXS5zdGFydFtqXSA9IGZsYXNoYmFzZSArIGogKiBzZWN0c2l6ZTsKCQl9CgkJc2l6ZSArPSBmbGFzaF9pbmZvW2ldLnNpemU7CgoJCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX0NMRUFSLAoJCQkgICAgICBmbGFzaF9pbmZvW2ldLnN0YXJ0WzBdLAoJCQkgICAgICAgZmxhc2hfaW5mb1tpXS5zdGFydFswXSArIGZsYXNoX2luZm9baV0uc2l6ZSAtIDEsCgkJCSAgICAgICZmbGFzaF9pbmZvW2ldKTsKCX0KCgkvKgoJICogUHJvdGVjdCBtb25pdG9yIGFuZCBlbnZpcm9ubWVudCBzZWN0b3JzCgkgKi8KCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBpMzg2Ym9vdF9zdGFydCwKCQkgICAgICBpMzg2Ym9vdF9lbmQsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojaWZkZWYgQ0ZHX0VOVl9BRERSCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgQ0ZHX0VOVl9BRERSLAoJCSAgICAgIENGR19FTlZfQUREUiArIENGR19FTlZfU0laRSAtIDEsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojZW5kaWYKCXJldHVybiBzaXplOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGZsYXNoX3ByaW50X2luZm8oZmxhc2hfaW5mb190ICppbmZvKQp7CglpbnQgaTsKCglzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spIHsKCWNhc2UgKElOVEVMX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spOgoJCXByaW50ZigiSU5URUw6ICIpOwoJCXN3aXRjaCAoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9UWVBFTUFTSykgewoJCWNhc2UgKElOVEVMX0lEXzI4RjMyMEozQSAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCIxeCBJMjhGMzIwSjNBICgzMk1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAoSU5URUxfSURfMjhGNjQwSjNBICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjF4IEkyOEY2NDBKM0EgKDY0TWJpdClcbiIpOwoJCQlicmVhazsKCQljYXNlIChJTlRFTF9JRF8yOEYxMjhKM0EgJiBGTEFTSF9UWVBFTUFTSyk6CgkJCXByaW50ZigiMXggSTI4RjEyOEozQSAoMTI4TWJpdClcbiIpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwcmludGYoIlVua25vd24gQ2hpcCBUeXBlXG4iKTsKCQkJZ290byBkb25lOwoJCQlicmVhazsKCQl9CgoJCWJyZWFrOwoKCWNhc2UgKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKToKCQlwcmludGYoIkFNRDogICAiKTsKCQlzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVFlQRU1BU0spIHsKCQljYXNlIChBTURfSURfTFY2NDBVICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjF4IEFNRDI5TFY2NDFESCAoNjRNYml0KVxuIik7CgkJCWJyZWFrOwoJCWNhc2UgKEFNRF9JRF9ETDY0MCAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCIxeCBBTUQyOUxWNjQxTUggKDY0TWJpdClcbiIpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwcmludGYoIlVua25vd24gQ2hpcCBUeXBlXG4iKTsKCQkJZ290byBkb25lOwoJCQlicmVhazsKCQl9CgoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYoIlVua25vd24gVmVuZG9yICIpOwoJCWJyZWFrOwoJfQoKCglwcmludGYoIiAgU2l6ZTogJWxkIE1CIGluICVkIFNlY3RvcnNcbiIsCgkgICAgICAgaW5mby0+c2l6ZSA+PiAyMCwgaW5mby0+c2VjdG9yX2NvdW50KTsKCglwcmludGYoIiAgU2VjdG9yIFN0YXJ0IEFkZHJlc3NlczoiKTsKCWZvciAoaSA9IDA7IGkgPCBpbmZvLT5zZWN0b3JfY291bnQ7IGkrKykgewoJCWlmICgoaSAlIDUpID09IDApIHsKCQkJcHJpbnRmICgiXG4gICAiKTsKCQl9CgkJcHJpbnRmICgiICUwOGxYJXMiLCBpbmZvLT5zdGFydFtpXSwKCQkJaW5mby0+cHJvdGVjdFtpXSA/ICIgKFJPKSIgOiAiICAgICAiKTsKCX0KCXByaW50ZiAoIlxuIik7CgoJZG9uZToKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgpzdGF0aWMgdTMyIF9hbWRfZXJhc2VfZmxhc2godTMyIGFkZHIsIHUzMiBzZWN0b3IpCnsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogSXNzdWUgZXJhc2UgKi8KCSoodm9sYXRpbGUgdTE2KikoYWRkciArIDB4YWFhYSkgPSAweDAwQUE7CgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyAweDU1NTQpID0gMHgwMDU1OwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHhhYWFhKSA9IDB4MDA4MDsKCS8qIEFuZCBvbmUgdW5sb2NrICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyAweGFhYWEpID0gMHgwMEFBOwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHg1NTU0KSA9IDB4MDA1NTsKCS8qIFNlY3RvciBlcmFzZSBjb21tYW5kIGNvbWVzIGxhc3QgKi8KCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwMzA7CgoJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJZWxhcHNlZCA9IDA7Cgl3aGlsZSAoKCgqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpKSAmIDB4MDA4MCkgIT0gMHgwMDgwKSB7CgoJCWVsYXBzZWQgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOwoJCWlmIChlbGFwc2VkID4gKChDRkdfRkxBU0hfRVJBU0VfVE9VVC9DRkdfSFopICogMTAwMCkpIHsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKSA9IDB4MDBmMDsKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCSoodm9sYXRpbGUgdTE2KikoYWRkcikgPSAweDAwZjA7CgoJcmV0dXJuIDA7Cn0KCmV4dGVybiBpbnQgX2FtZF9lcmFzZV9mbGFzaF9lbmQ7CmFzbSAoIl9hbWRfZXJhc2VfZmxhc2hfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCi8qIHRoaXMgbmVlZHMgdG8gYmUgaW5saW5lZCwgdGhlIFNXVE1STU1JTExJIHJlZ2lzdGVyIGlzIHJlc2V0IGJ5IGVhY2ggcmVhZCAqLwojZGVmaW5lIF9fdWRlbGF5KGRlbGF5KSBcCnsJXAoJdW5zaWduZWQgbWljcm87IFwKCXVuc2lnbmVkIG1pbGxpPTA7IFwKCVwKCW1pY3JvID0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOyBcCgkgXAoJZm9yICg7OykgeyBcCgkJXAoJCW1pbGxpICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgXAoJCW1pY3JvID0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlDUk8pOyBcCgkJXAoJCWlmICgoZGVsYXkpIDw9IChtaWNybyArIChtaWxsaSAqIDEwMDApKSkgeyBcCgkJCWJyZWFrOyBcCgkJfSBcCgl9IFwKfSB3aGlsZSAoMCkKCnN0YXRpYyB1MzIgX2ludGVsX2VyYXNlX2ZsYXNoKHUzMiBhZGRyLCB1MzIgc2VjdG9yKQp7Cgl1bnNpZ25lZCBlbGFwc2VkOwoKCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwNTA7ICAgLyogY2xlYXIgc3RhdHVzIHJlZ2lzdGVyICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMDIwOyAgIC8qIGVyYXNlIHNldHVwICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMEQwOyAgIC8qIGVyYXNlIGNvbmZpcm0gKi8KCgoJLyogV2FpdCBhdCBsZWFzdCA4MHVzIC0gbGV0J3Mgd2FpdCAxIG1zICovCglfX3VkZWxheSgxMDAwKTsKCgllbGFwc2VkID0gMDsKCXdoaWxlICgoKCoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikpICYgMHgwMDgwKSAhPSAweDAwODApIHsKCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQlpZiAoZWxhcHNlZCA+ICgoQ0ZHX0ZMQVNIX0VSQVNFX1RPVVQvQ0ZHX0haKSAqIDEwMDApKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwQjA7ICAvKiBzdXNwZW5kIGVyYXNlICAgICAgKi8KCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBGRjsgIC8qIHJlc2V0IHRvIHJlYWQgbW9kZSAqLwoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBGRjsgIC8qIHJlc2V0IHRvIHJlYWQgbW9kZSAqLwoKCXJldHVybiAwOwp9CgoKZXh0ZXJuIGludCBfaW50ZWxfZXJhc2VfZmxhc2hfZW5kOwphc20gKCJfaW50ZWxfZXJhc2VfZmxhc2hfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCmludCBmbGFzaF9lcmFzZShmbGFzaF9pbmZvX3QgKmluZm8sIGludCBzX2ZpcnN0LCBpbnQgc19sYXN0KQp7Cgl1MzIgKCpfZXJhc2VfZmxhc2hfcHRyKSh1MzIgYSwgdTMyIHNvKTsKCWludCBwcm90OwoJaW50IHNlY3Q7Cgl1bnNpZ25lZCBzaXplOwoKCWlmICgoc19maXJzdCA8IDApIHx8IChzX2ZpcnN0ID4gc19sYXN0KSkgewoJCWlmIChpbmZvLT5mbGFzaF9pZCA9PSBGTEFTSF9VTktOT1dOKSB7CgkJCXByaW50ZigiLSBtaXNzaW5nXG4iKTsKCQl9IGVsc2UgewoJCQlwcmludGYoIi0gbm8gc2VjdG9ycyB0byBlcmFzZVxuIik7CgkJfQoJCXJldHVybiAxOwoJfQoKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfZXJhc2VfZmxhc2hfZW5kIC0gKHVuc2lnbmVkKV9hbWRfZXJhc2VfZmxhc2g7CgoJCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQkJcHJpbnRmKCJfYW1kX2VyYXNlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfZXJhc2VfZmxhc2hfZW5kLCBfYW1kX2VyYXNlX2ZsYXNoKTsKCQkJcmV0dXJuIDA7CgkJfQoKCQltZW1jcHkoYnVmZmVyLCBfYW1kX2VyYXNlX2ZsYXNoLCBzaXplKTsKCQlfZXJhc2VfZmxhc2hfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCgl9IGVsc2UgaWYgKChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSA9PSAoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfaW50ZWxfZXJhc2VfZmxhc2hfZW5kIC0gKHVuc2lnbmVkKV9pbnRlbF9lcmFzZV9mbGFzaDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9pbnRlbF9lcmFzZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfaW50ZWxfZXJhc2VfZmxhc2hfZW5kLCBfaW50ZWxfZXJhc2VfZmxhc2gpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9pbnRlbF9lcmFzZV9mbGFzaCwgc2l6ZSk7CgkJX2VyYXNlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7Cgl9IGVsc2UgewoJCXByaW50ZiAoIkNhbid0IGVyYXNlIHVua25vd24gZmxhc2ggdHlwZSAtIGFib3J0ZWRcbiIpOwoJCXJldHVybiAxOwoJfQoKCXByb3QgPSAwOwoJZm9yIChzZWN0PXNfZmlyc3Q7IHNlY3Q8PXNfbGFzdDsgKytzZWN0KSB7CgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0pIHsKCQkJcHJvdCsrOwoJCX0KCX0KCglpZiAocHJvdCkgewoJCXByaW50ZiAoIi0gV2FybmluZzogJWQgcHJvdGVjdGVkIHNlY3RvcnMgd2lsbCBub3QgYmUgZXJhc2VkIVxuIiwgcHJvdCk7Cgl9IGVsc2UgewoJCXByaW50ZiAoIlxuIik7Cgl9CgoKCS8qIFN0YXJ0IGVyYXNlIG9uIHVucHJvdGVjdGVkIHNlY3RvcnMgKi8KCWZvciAoc2VjdCA9IHNfZmlyc3Q7IHNlY3Q8PXNfbGFzdDsgc2VjdCsrKSB7CgoJCWlmIChpbmZvLT5wcm90ZWN0W3NlY3RdID09IDApIHsgLyogbm90IHByb3RlY3RlZCAqLwoJCQlpbnQgcmVzOwoJCQlpbnQgZmxhZzsKCgkJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJCQlyZXMgPSBfZXJhc2VfZmxhc2hfcHRyKGluZm8tPnN0YXJ0WzBdLCBpbmZvLT5zdGFydFtzZWN0XS1pbmZvLT5zdGFydFswXSk7CgoJCQkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCQkJaWYgKGZsYWcpIHsKCQkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJCX0KCgoJCQlpZiAocmVzKSB7CgkJCQlwcmludGYoIkVyYXNlIHRpbWVkIG91dCwgc2VjdG9yICVkXG4iLCBzZWN0KTsKCQkJCXJldHVybiByZXM7CgkJCX0KCgkJCXB1dGMoJy4nKTsKCQl9Cgl9CgoKCXJldHVybiAwOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFdyaXRlIGEgd29yZCB0byBGbGFzaCwgcmV0dXJuczoKICogMCAtIE9LCiAqIDEgLSB3cml0ZSB0aW1lb3V0CiAqIDIgLSBGbGFzaCBub3QgZXJhc2VkCiAqLwpzdGF0aWMgaW50IF9hbWRfd3JpdGVfd29yZCh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSkKewoJdm9sYXRpbGUgdTE2ICphZGRyMiA9ICh1MTYqKXN0YXJ0OwoJdm9sYXRpbGUgdTE2ICpkZXN0MiA9ICh1MTYqKWRlc3Q7Cgl2b2xhdGlsZSB1MTYgKmRhdGEyID0gKHUxNiopJmRhdGE7CglpbnQgaTsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogQ2hlY2sgaWYgRmxhc2ggaXMgKHN1ZmZpY2llbnRseSkgZXJhc2VkICovCglpZiAoKCooKHZvbGF0aWxlIHUxNiopZGVzdCkgJiAodTE2KWRhdGEpICE9ICh1MTYpZGF0YSkgewoJCXJldHVybiAyOwoJfQoKCWZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKCgoJCWFkZHIyWzB4NTU1NV0gPSAweDAwQUE7CgkJYWRkcjJbMHgyYWFhXSA9IDB4MDA1NTsKCQlhZGRyMlsweDU1NTVdID0gMHgwMEEwOwoKCQlkZXN0MltpXSA9IChkYXRhID4+IChpKjE2KSkgJiAweGZmZmY7CgoJCWVsYXBzZWQgPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IC8qIGR1bW15IHJlYWQgKi8KCQllbGFwc2VkID0gMDsKCgkJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJCXdoaWxlICgoZGVzdDJbaV0gJiAweDAwODApICE9IChkYXRhMltpXSAmIDB4MDA4MCkpIHsKCQkJZWxhcHNlZCArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7CgkJCWlmIChlbGFwc2VkID4gKChDRkdfRkxBU0hfV1JJVEVfVE9VVC9DRkdfSFopICogMTAwMCkpIHsKCQkJCWFkZHIyW2ldID0gMHgwMGYwOwoJCQkJcmV0dXJuIDE7CgkJCX0KCQl9Cgl9CgoJYWRkcjJbaV0gPSAweDAwZjA7CgoJcmV0dXJuIDA7Cn0KCmV4dGVybiBpbnQgX2FtZF93cml0ZV93b3JkX2VuZDsKYXNtICgiX2FtZF93cml0ZV93b3JkX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgoKc3RhdGljIGludCBfaW50ZWxfd3JpdGVfd29yZCh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSkKewoJaW50IGk7Cgl1bnNpZ25lZCBlbGFwc2VkOwoKCS8qIENoZWNrIGlmIEZsYXNoIGlzIChzdWZmaWNpZW50bHkpIGVyYXNlZCAqLwoJaWYgKCgqKCh2b2xhdGlsZSB1MTYqKWRlc3QpICYgKHUxNilkYXRhKSAhPSAodTE2KWRhdGEpIHsKCQlyZXR1cm4gMjsKCX0KCglmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CgoJCSoodm9sYXRpbGUgdTE2KikoZGVzdCsyKmkpID0gMHgwMDQwOyAvKiB3cml0ZSBzZXR1cCAqLwoJCSoodm9sYXRpbGUgdTE2KikoZGVzdCsyKmkpID0gKGRhdGEgPj4gKGkqMTYpKSAmIDB4ZmZmZjsKCgkJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJCWVsYXBzZWQgPSAwOwoKCQkvKiBkYXRhIHBvbGxpbmcgZm9yIEQ3ICovCgkJd2hpbGUgKCgqKHZvbGF0aWxlIHUxNiopZGVzdCAmIDB4MDA4MCkgIT0gMHgwMDgwKSB7CgkJCWVsYXBzZWQgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOwoJCQlpZiAoZWxhcHNlZCA+ICgoQ0ZHX0ZMQVNIX1dSSVRFX1RPVVQvQ0ZHX0haKSAqIDEwMDApKSB7CgkJCQkqKHZvbGF0aWxlIHUxNiopZGVzdCA9IDB4MDBmZjsKCQkJCXJldHVybiAxOwoJCQl9CgkJfQoJfQoKCSoodm9sYXRpbGUgdTE2KilkZXN0ID0gMHgwMGZmOwoKCglyZXR1cm4gMDsKCn0KCmV4dGVybiBpbnQgX2ludGVsX3dyaXRlX3dvcmRfZW5kOwphc20gKCJfaW50ZWxfd3JpdGVfd29yZF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2gsIHJldHVybnM6CiAqIDAgLSBPSwogKiAxIC0gd3JpdGUgdGltZW91dAogKiAyIC0gRmxhc2ggbm90IGVyYXNlZAogKiAzIC0gVW5zdXBwb3J0ZWQgZmxhc2ggdHlwZQogKi8KCmludCB3cml0ZV9idWZmKGZsYXNoX2luZm9fdCAqaW5mbywgdWNoYXIgKnNyYywgdWxvbmcgYWRkciwgdWxvbmcgY250KQp7Cgl1bG9uZyBjcCwgd3AsIGRhdGE7CglpbnQgaSwgbCwgcmM7CglpbnQgZmxhZzsKCXUzMiAoKl93cml0ZV93b3JkX3B0cikodW5zaWduZWQgc3RhcnQsIHVuc2lnbmVkIGRlc3QsIHVuc2lnbmVkIGRhdGEpOwoJdW5zaWduZWQgc2l6ZTsKCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfYW1kX3dyaXRlX3dvcmRfZW5kIC0gKHVuc2lnbmVkKV9hbWRfd3JpdGVfd29yZDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9hbWRfd3JpdGVfd29yZCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfYW1kX3dyaXRlX3dvcmRfZW5kLCBfYW1kX3dyaXRlX3dvcmQpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9hbWRfd3JpdGVfd29yZCwgc2l6ZSk7CgkJX3dyaXRlX3dvcmRfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCgl9IGVsc2UgaWYgKChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSA9PSAoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfaW50ZWxfd3JpdGVfd29yZF9lbmQgLSAodW5zaWduZWQpX2ludGVsX3dyaXRlX3dvcmQ7CgoJCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQkJcHJpbnRmKCJfaW50ZWxfd3JpdGVfd29yZCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfaW50ZWxfd3JpdGVfd29yZF9lbmQsIF9pbnRlbF93cml0ZV93b3JkKTsKCQkJcmV0dXJuIDA7CgkJfQoKCQltZW1jcHkoYnVmZmVyLCBfaW50ZWxfd3JpdGVfd29yZCwgc2l6ZSk7CgkJX3dyaXRlX3dvcmRfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCX0gZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgcHJvZ3JhbSB1bmtub3duIGZsYXNoIHR5cGUgLSBhYm9ydGVkXG4iKTsKCQlyZXR1cm4gMzsKCX0KCgoJd3AgPSAoYWRkciAmIH4zKTsJLyogZ2V0IGxvd2VyIHdvcmQgYWxpZ25lZCBhZGRyZXNzICovCgoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHN0YXJ0IGJ5dGVzCgkgKi8KCWlmICgobCA9IGFkZHIgLSB3cCkgIT0gMCkgewoJCWRhdGEgPSAwOwoJCWZvciAoaT0wLCBjcD13cDsgaTxsOyArK2ksICsrY3ApIHsKCQkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSA8PCAoOCppKTsKCQl9CgkJZm9yICg7IGk8NCAmJiBjbnQ+MDsgKytpKSB7CgkJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCQktLWNudDsKCQkJKytjcDsKCQl9CgkJZm9yICg7IGNudD09MCAmJiBpPDQ7ICsraSwgKytjcCkgewoJCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApICA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCArPSA0OwoJfQoKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9IDA7CgoJCWZvciAoaT0wOyBpPDQ7ICsraSkgewoJCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCAgKz0gNDsKCQljbnQgLT0gNDsKCX0KCglpZiAoY250ID09IDApIHsKCQlyZXR1cm4gMDsKCX0KCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCB0YWlsIGJ5dGVzCgkgKi8KCWRhdGEgPSAwOwoJZm9yIChpPTAsIGNwPXdwOyBpPDQgJiYgY250PjA7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCS0tY250OwoJfQoKCWZvciAoOyBpPDQ7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgPDwgKDgqaSk7Cgl9CgoJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dCBoZXJlICovCglmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCWlmIChmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cgp9Cg==