LyoKICogWE1TIHYyKyBlbXVsYXRpb24KICoKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBOb3RlOiBUaGlzIFhNUyBlbXVsYXRpb24gaXMgaG9va2VkIHRocm91Z2ggdGhlIERQTUkgaW50ZXJydXB0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGludDMxKTsKCnR5cGVkZWYgc3RydWN0IHsKIFdPUkQgSGFuZGxlOwogRFdPUkQgT2Zmc2V0Owp9IFdJTkVfUEFDS0VEIE1PVkVPRlM7Cgp0eXBlZGVmIHN0cnVjdCB7CiBEV09SRCBMZW5ndGg7CiBNT1ZFT0ZTIFNvdXJjZTsKIE1PVkVPRlMgRGVzdDsKfSBXSU5FX1BBQ0tFRCBNT1ZFU1RSVUNUOwoKc3RhdGljIEJZVEUgKiBYTVNfT2Zmc2V0KCBNT1ZFT0ZTICpvZnMgKQp7CiAgICBpZiAob2ZzLT5IYW5kbGUpIHJldHVybiAoQllURSopR2xvYmFsTG9jazE2KG9mcy0+SGFuZGxlKStvZnMtPk9mZnNldDsKICAgIGVsc2UgcmV0dXJuIChCWVRFKilQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihvZnMtPk9mZnNldCksT0ZGU0VUT0Yob2ZzLT5PZmZzZXQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIFhNU19IYW5kbGVyCiAqLwoKdm9pZCBXSU5BUEkgWE1TX0hhbmRsZXIoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKICAgIHN3aXRjaChBSF9yZWcoY29udGV4dCkpCiAgICB7CiAgICBjYXNlIDB4MDA6ICAgLyogR2V0IFhNUyB2ZXJzaW9uIG51bWJlciAqLwogICAgICAgIFRSQUNFKCJnZXQgWE1TIHZlcnNpb24gbnVtYmVyXG4iKTsKICAgICAgICBTRVRfQVgoIGNvbnRleHQsIDB4MDIwMCApOyAvKiAyLjAgKi8KICAgICAgICBTRVRfQlgoIGNvbnRleHQsIDB4MDAwMCApOyAvKiBpbnRlcm5hbCByZXZpc2lvbiAqLwogICAgICAgIFNFVF9EWCggY29udGV4dCwgMHgwMDAxICk7IC8qIEhNQSBleGlzdHMgKi8KICAgICAgICBicmVhazsKICAgIGNhc2UgMHgwODogICAvKiBRdWVyeSBGcmVlIEV4dGVuZGVkIE1lbW9yeSAqLwogICAgewogICAgICAgIE1FTU9SWVNUQVRVUyBzdGF0dXM7CgogICAgICAgIFRSQUNFKCJxdWVyeSBmcmVlIGV4dGVuZGVkIG1lbW9yeVxuIik7CiAgICAgICAgR2xvYmFsTWVtb3J5U3RhdHVzKCAmc3RhdHVzICk7CiAgICAgICAgU0VUX0RYKCBjb250ZXh0LCBzdGF0dXMuZHdBdmFpbFZpcnR1YWwgPj4gMTAgKTsKICAgICAgICBTRVRfQVgoIGNvbnRleHQsIHN0YXR1cy5kd0F2YWlsVmlydHVhbCA+PiAxMCApOwogICAgICAgIFRSQUNFKCJyZXR1cm5pbmcgbGFyZ2VzdCAlZEssIHRvdGFsICVkS1xuIiwgQVhfcmVnKGNvbnRleHQpLCBEWF9yZWcoY29udGV4dCkpOwogICAgfQogICAgYnJlYWs7CiAgICBjYXNlIDB4MDk6ICAgLyogQWxsb2NhdGUgRXh0ZW5kZWQgTWVtb3J5IEJsb2NrICovCiAgICAgICAgVFJBQ0UoImFsbG9jYXRlIGV4dGVuZGVkIG1lbW9yeSBibG9jayAoJWRLKVxuIiwKICAgICAgICAgICAgRFhfcmVnKGNvbnRleHQpKTsKCVNFVF9EWCggY29udGV4dCwgR2xvYmFsQWxsb2MxNihHTUVNX01PVkVBQkxFLCAoRFdPUkQpRFhfcmVnKGNvbnRleHQpPDwxMCkgKTsKCVNFVF9BWCggY29udGV4dCwgRFhfcmVnKGNvbnRleHQpID8gMSA6IDAgKTsKCWlmICghRFhfcmVnKGNvbnRleHQpKSBTRVRfQkwoIGNvbnRleHQsIDB4QTAgKTsgLyogb3V0IG9mIG1lbW9yeSAqLwoJYnJlYWs7CiAgICBjYXNlIDB4MGE6ICAgLyogRnJlZSBFeHRlbmRlZCBNZW1vcnkgQmxvY2sgKi8KCVRSQUNFKCJmcmVlIGV4dGVuZGVkIG1lbW9yeSBibG9jayAlMDR4XG4iLERYX3JlZyhjb250ZXh0KSk7CiAgICAgICBpZighRFhfcmVnKGNvbnRleHQpIHx8IEdsb2JhbEZyZWUxNihEWF9yZWcoY29udGV4dCkpKSB7CiAgICAgICAgIFNFVF9BWCggY29udGV4dCwgMCApOyAgICAvKiBmYWlsdXJlICovCiAgICAgICAgIFNFVF9CTCggY29udGV4dCwgMHhhMiApOyAvKiBpbnZhbGlkIGhhbmRsZSAqLwogICAgICAgfSBlbHNlCiAgICAgICAgIFNFVF9BWCggY29udGV4dCwgMSApOyAgICAvKiBzdWNjZXNzICovCglicmVhazsKICAgIGNhc2UgMHgwYjogICAvKiBNb3ZlIEV4dGVuZGVkIE1lbW9yeSBCbG9jayAqLwogICAgewoJTU9WRVNUUlVDVCptb3ZlPUNUWF9TRUdfT0ZGX1RPX0xJTihjb250ZXh0LAoJICAgIGNvbnRleHQtPlNlZ0RzLGNvbnRleHQtPkVzaSk7CiAgICAgICAgQllURSpzcmMsKmRzdDsKICAgICAgICBUUkFDRSgibW92ZSBleHRlbmRlZCBtZW1vcnkgYmxvY2tcbiIpOwogICAgICAgIHNyYz1YTVNfT2Zmc2V0KCZtb3ZlLT5Tb3VyY2UpOwogICAgICAgIGRzdD1YTVNfT2Zmc2V0KCZtb3ZlLT5EZXN0KTsKCW1lbWNweShkc3Qsc3JjLG1vdmUtPkxlbmd0aCk7CglpZiAobW92ZS0+U291cmNlLkhhbmRsZSkgR2xvYmFsVW5sb2NrMTYobW92ZS0+U291cmNlLkhhbmRsZSk7CglpZiAobW92ZS0+RGVzdC5IYW5kbGUpIEdsb2JhbFVubG9jazE2KG1vdmUtPkRlc3QuSGFuZGxlKTsKCWJyZWFrOwogICAgfQogICAgY2FzZSAweDg4OiAgIC8qIFF1ZXJ5IEFueSBGcmVlIEV4dGVuZGVkIE1lbW9yeSAqLwogICAgewogICAgICAgIE1FTU9SWVNUQVRVUyBzdGF0dXM7CiAgICAgICAgU1lTVEVNX0lORk8gIGluZm87CgogICAgICAgIFRSQUNFKCJxdWVyeSBhbnkgZnJlZSBleHRlbmRlZCBtZW1vcnlcbiIpOwoKICAgICAgICBHbG9iYWxNZW1vcnlTdGF0dXMoICZzdGF0dXMgKTsKICAgICAgICBHZXRTeXN0ZW1JbmZvKCAmaW5mbyApOwogICAgICAgIGNvbnRleHQtPkVheCA9IHN0YXR1cy5kd0F2YWlsVmlydHVhbCA+PiAxMDsKICAgICAgICBjb250ZXh0LT5FZHggPSBzdGF0dXMuZHdBdmFpbFZpcnR1YWwgPj4gMTA7CiAgICAgICAgY29udGV4dC0+RWN4ID0gKERXT1JEKWluZm8ubHBNYXhpbXVtQXBwbGljYXRpb25BZGRyZXNzOwogICAgICAgIFNFVF9CTCggY29udGV4dCwgMCApOyAvKiBObyBlcnJvcnMuICovCgogICAgICAgIFRSQUNFKCJyZXR1cm5pbmcgbGFyZ2VzdCAlbGRLLCB0b3RhbCAlbGRLLCBoaWdoZXN0IDB4JWx4XG4iLCAKICAgICAgICAgICAgICBjb250ZXh0LT5FYXgsIGNvbnRleHQtPkVkeCwgY29udGV4dC0+RWN4KTsKICAgIH0KICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBJTlRfQkFSRiggY29udGV4dCwgMHgzMSApOwogICAgICAgIFNFVF9BWCggY29udGV4dCwgMHgwMDAwICk7IC8qIGZhaWx1cmUgKi8KICAgICAgICBTRVRfQkwoIGNvbnRleHQsIDB4ODAgKTsgICAvKiBmdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQgKi8KICAgICAgICBicmVhazsKICAgIH0KfQo=