LyoKICogQ29weXJpZ2h0IChjKSAxOTk4LTIwMDQgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAoYykgMjAwMi0yMDA1IENocmlzdGlhbiBDb3N0YQogKiBDb3B5cmlnaHQgKGMpIDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqIENvcHlyaWdodCAoYykgMjAwOCBBbGV4YW5kZXIgRG9yb2ZleWV2CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBJRGlyZWN0M0REZXZpY2UgaW1wbGVtZW50YXRpb24sIHZlcnNpb24gMSwgMiwgMyBhbmQgNy4gUmVuZGVyaW5nIGlzIHJlbGF5ZWQKICogdG8gV2luZUQzRCwgc29tZSBtaW5pbWFsIERpcmVjdERyYXcgc3BlY2lmaWMgbWFuYWdlbWVudCBpcyBoYW5kbGVkIGhlcmUuCiAqIFRoZSBEaXJlY3QzRERldmljZSBpcyBOT1QgdGhlIHBhcmVudCBvZiB0aGUgV2luZUQzRERldmljZSwgYmVjYXVzZSBkM2QKICogaXMgaW5pdGlhbGl6ZWQgd2hlbiBEaXJlY3REcmF3IGNyZWF0ZXMgdGhlIHByaW1hcnkgc3VyZmFjZS4KICogU29tZSB0eXBlIG1hbmFnZW1lbnQgaXMgbmVjZXNzYXJ5LCBiZWNhdXNlIHNvbWUgRDNEIHR5cGVzIGNoYW5nZWQgYmV0d2VlbgogKiBEM0Q3IGFuZCBEM0Q5LgogKgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Q3KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGRyYXdfdGh1bmspOwoKLyogVGhlIGRldmljZSBJRCAqLwpjb25zdCBHVUlEIElJRF9EM0RERVZJQ0VfV2luZUQzRCA9IHsKICAweGFlZjcyZDQzLAogIDB4YjA5YSwKICAweDRiN2IsCiAgeyAweGI3LDB4OTgsMHhjNiwweDhhLDB4NzcsMHgyZCwweDcyLDB4MmEgfQp9OwoKc3RhdGljIGlubGluZSB2b2lkIHNldF9mcHVfY29udHJvbF93b3JkKFdPUkQgZnB1Y3cpCnsKI2lmIGRlZmluZWQoX19pMzg2X18pICYmIGRlZmluZWQoX19HTlVDX18pCiAgICBfX2FzbV9fIHZvbGF0aWxlICgiZmxkY3cgJTAiIDogOiAibSIgKGZwdWN3KSk7CiNlbGlmIGRlZmluZWQoX19pMzg2X18pICYmIGRlZmluZWQoX01TQ19WRVIpCiAgICBfX2FzbSBmbGRjdyBmcHVjdzsKI2VuZGlmCn0KCnN0YXRpYyBpbmxpbmUgV09SRCBkM2RfZnB1X3NldHVwKHZvaWQpCnsKICAgIFdPUkQgb2xkY3c7CgojaWYgZGVmaW5lZChfX2kzODZfXykgJiYgZGVmaW5lZChfX0dOVUNfXykKICAgIF9fYXNtX18gdm9sYXRpbGUgKCJmbnN0Y3cgJTAiIDogIj1tIiAob2xkY3cpKTsKI2VsaWYgZGVmaW5lZChfX2kzODZfXykgJiYgZGVmaW5lZChfTVNDX1ZFUikKICAgIF9fYXNtIGZuc3RjdyBvbGRjdzsKI2Vsc2UKICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgaWYoIXdhcm5lZCkKICAgIHsKICAgICAgICBGSVhNRSgiRlBVUFJFU0VSVkUgbm90IGltcGxlbWVudGVkIGZvciB0aGlzIHBsYXRmb3JtIC8gY29tcGlsZXJcbiIpOwogICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICB9CiNlbmRpZgoKICAgIHNldF9mcHVfY29udHJvbF93b3JkKDB4MzdmKTsKCiAgICByZXR1cm4gb2xkY3c7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzLiBDb21tb24gZm9yIFZlcnNpb24gMSwgMiwgMyBhbmQgNyAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFVzZWQgdG8gcXVlcnkgb3RoZXIgaW50ZXJmYWNlcyBmcm9tIGEgRGlyZWN0M0REZXZpY2UgaW50ZXJmYWNlLgogKiBJdCBjYW4gcmV0dXJuIGludGVyZmFjZSBwb2ludGVycyB0byBhbGwgRGlyZWN0M0REZXZpY2UgdmVyc2lvbnMgYXMgd2VsbAogKiBhcyBJRGlyZWN0RHJhdyBhbmQgSURpcmVjdDNELiBGb3IgYSBsaW5rIHRvIFF1ZXJ5SW50ZXJmYWNlCiAqIHJ1bGVzIHNlZSBkZHJhdy5jLCBJRGlyZWN0RHJhdzc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgcmVmaWlkOiBJbnRlcmZhY2UgSUQgcXVlcmllZCBmb3IKICogIG9iajogVXNlZCB0byByZXR1cm4gdGhlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb3IgRV9OT0lOVEVSRkFDRQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfUXVlcnlJbnRlcmZhY2UoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgICAvKiBBY2NvcmRpbmcgdG8gQ09NIGRvY3MsIGlmIHRoZSBRdWVyeUludGVyZmFjZSBmYWlscywgb2JqIHNob3VsZCBiZSBzZXQgdG8gTlVMTCAqLwogICAgKm9iaiA9IE5VTEw7CgogICAgaWYoIXJlZmlpZCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lVbmtub3duLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpOwogICAgfQoKICAgIC8qIENoZWNrIERpcmVjdERyYXcgSW50ZXJmYWMBcyAqLwogICAgZWxzZSBpZiggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXc3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdzcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzQsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3NCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NCBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3MiwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXcyKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXcyIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdywgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQoKICAgIC8qIERpcmVjdDNEICovCiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEICAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3QzRCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3QzRCBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDIgLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0M0QyKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNEMiBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDMgLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0M0QzKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNEMyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDcgLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0M0Q3KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNENyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQoKICAgIC8qIERpcmVjdDNERGV2aWNlICovCiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNERGV2aWNlICAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNERGV2aWNlIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNERGV2aWNlMiAgLCByZWZpaWQgKSApIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMik7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3QzRERldmljZTIgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0REZXZpY2UzICAsIHJlZmlpZCApICkgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRERldmljZTcgICwgcmVmaWlkICkgKSB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CgogICAgLyogVW5rbm93biBpbnRlcmZhY2UgKi8KICAgIGVsc2UKICAgIHsKICAgICAgICBFUlIoIiglcCktPiglcywgJXApOiBObyBpbnRlcmZhY2UgZm91bmRcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICAvKiBBZGRSZWYgdGhlIHJldHVybmVkIGludGVyZmFjZSAqLwogICAgSVVua25vd25fQWRkUmVmKCAoSVVua25vd24gKikgKm9iaik7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXMsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1F1ZXJ5SW50ZXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfUXVlcnlJbnRlcmZhY2UoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcywlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfUXVlcnlJbnRlcmZhY2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9RdWVyeUludGVyZmFjZShJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JwKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcywlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYnApOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfUXVlcnlJbnRlcmZhY2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkFkZFJlZgogKgogKiBJbmNyZWFzZXMgdGhlIHJlZmNvdW50Li4uLgogKiBUaGUgbW9zdCBleGNpdGluZyBNZXRob2QsIGRlZmluaXRlbHkKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgMyBhbmQgNwogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0FkZFJlZihJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBpbmNyZW1lbnRpbmcgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiAtMSk7CgogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfQWRkUmVmKElEaXJlY3QzRERldmljZTMgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQWRkUmVmKElEaXJlY3QzRERldmljZTIgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfQWRkUmVmKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgaWZhY2UpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfQWRkUmVmKENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpSZWxlYXNlCiAqCiAqIERlY3JlYXNlcyB0aGUgcmVmY291bnQgb2YgdGhlIGludGVyZmFjZQogKiBXaGVuIHRoZSByZWZjb3VudCBpcyByZWR1Y2VkIHRvIDAsIHRoZSBvYmplY3QgaXMgZGVzdHJveWVkLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCAzIGFuZCA3CiAqCiAqIFJldHVybnM6ZAogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1JlbGVhc2UoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApLT4oKSBkZWNyZW1lbnRpbmcgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiArMSk7CgogICAgLyogVGhpcyBtZXRob2QgZG9lc24ndCBkZXN0cm95IHRoZSBXaW5lRDNERGV2aWNlLCBiZWNhdXNlIGl0J3Mgc3RpbGwgaW4gdXNlIGZvcgogICAgICogMkQgcmVuZGVyaW5nLiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlIHdpbGwgZGVzdHJveSB0aGUgV2luZUQzRERldmljZQogICAgICogd2hlbiB0aGUgcmVuZGVyIHRhcmdldCBpcyByZWxlYXNlZAogICAgICovCiAgICBpZiAocmVmID09IDApCiAgICB7CiAgICAgICAgSVBhcmVudCAqSW5kZXhCdWZmZXJQYXJlbnQ7CiAgICAgICAgRFdPUkQgaTsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAvKiBGcmVlIHRoZSBpbmRleCBidWZmZXIuICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SW5kaWNlcyhUaGlzLT53aW5lRDNERGV2aWNlLCBOVUxMKTsKICAgICAgICBJV2luZUQzREluZGV4QnVmZmVyX0dldFBhcmVudChUaGlzLT5pbmRleGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKiopICZJbmRleEJ1ZmZlclBhcmVudCk7CiAgICAgICAgSVBhcmVudF9SZWxlYXNlKEluZGV4QnVmZmVyUGFyZW50KTsgLyogT25jZSBmb3IgdGhlIGdldFBhcmVudCAqLwogICAgICAgIGlmKCBJUGFyZW50X1JlbGVhc2UoSW5kZXhCdWZmZXJQYXJlbnQpICE9IDApICAvKiBBbmQgbm93IHRvIGRlc3Ryb3kgaXQgKi8KICAgICAgICB7CiAgICAgICAgICAgIEVSUigiICglcCkgU29tZXRoaW5nIGlzIHN0aWxsIGhvbGRpbmcgdGhlIGluZGV4IGJ1ZmZlciBwYXJlbnQgJXBcbiIsIFRoaXMsIEluZGV4QnVmZmVyUGFyZW50KTsKICAgICAgICB9CgogICAgICAgIC8qIFRoZXJlIGlzIG5vIG5lZWQgdG8gdW5zZXQgdGhlIHZlcnRleCBidWZmZXIgaGVyZSwgSVdpbmVEM0REZXZpY2VfVW5pbml0M0Qgd2lsbCBkbyB0aGF0IHdoZW4KICAgICAgICAgKiBkZXN0cm95aW5nIHRoZSBwcmltYXJ5IHN0YXRlYmxvY2suIElmIGEgdmVydGV4IGJ1ZmZlciBpcyBkZXN0cm95ZWQgd2hpbGUgaXQgaXMgYm91bmQKICAgICAgICAgKiBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI6OlJlbGVhc2Ugd2lsbCB1bnNldCBpdC4KICAgICAgICAgKi8KCiAgICAgICAgLyogUmVzdG9yZSB0aGUgcmVuZGVyIHRhcmdldHMgKi8KICAgICAgICBpZihUaGlzLT5PZmZTY3JlZW5UYXJnZXQpCiAgICAgICAgewogICAgICAgICAgICBXSU5FRDNEVklFV1BPUlQgdnA7CgogICAgICAgICAgICB2cC5YID0gMDsKICAgICAgICAgICAgdnAuWSA9IDA7CiAgICAgICAgICAgIHZwLldpZHRoID0gVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQtPnN1cmZhY2VfZGVzYy5kd1dpZHRoOwogICAgICAgICAgICB2cC5IZWlnaHQgPSBUaGlzLT5kZHJhdy0+ZDNkX3RhcmdldC0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0OwogICAgICAgICAgICB2cC5NaW5aID0gMC4wOwogICAgICAgICAgICB2cC5NYXhaID0gMS4wOwogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRWaWV3cG9ydChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdnApOwoKICAgICAgICAgICAgLyogU2V0IHRoZSBkZXZpY2UgdXAgdG8gcmVuZGVyIHRvIHRoZSBmcm9udCBidWZmZXIgc2luY2UgdGhlIGJhY2sgYnVmZmVyIHdpbGwKICAgICAgICAgICAgICogdmFuaXNoIHNvb24uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRSZW5kZXJUYXJnZXQoVGhpcy0+d2luZUQzRERldmljZSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmRkcmF3LT5kM2RfdGFyZ2V0LT5XaW5lRDNEU3VyZmFjZSk7CiAgICAgICAgICAgIC8qIFRoaXMtPnRhcmdldCBpcyB0aGUgb2Zmc2NyZWVuIHRhcmdldC4KICAgICAgICAgICAgICogVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQgaXMgdGhlIHRhcmdldCB1c2VkIGJ5IEREcmF3CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUUkFDRSgiKCVwKSBSZWxlYXNlOiBVc2luZyAlcCBhcyBmcm9udCBidWZmZXIsICVwIGFzIGJhY2sgYnVmZmVyXG4iLCBUaGlzLCBUaGlzLT5kZHJhdy0+ZDNkX3RhcmdldCwgTlVMTCk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZyb250QmFja0J1ZmZlcnMoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5kZHJhdy0+ZDNkX3RhcmdldC0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgfQoKICAgICAgICAvKiBSZWxlYXNlIHRoZSBXaW5lRDNERGV2aWNlLiBUaGlzIHdvbid0IGRlc3Ryb3kgaXQgKi8KICAgICAgICBpZihJV2luZUQzRERldmljZV9SZWxlYXNlKFRoaXMtPndpbmVEM0REZXZpY2UpIDw9IDApCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiAoJXApIFRoZSB3aW5lRDNEIGRldmljZSAlcCB3YXMgZGVzdHJveWVkIHVuZXhwZWN0ZWRseS4gUHJlcGFyZSBmb3IgdHJvdWJsZVxuIiwgVGhpcywgVGhpcy0+d2luZUQzRERldmljZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBUaGUgdGV4dHVyZSBoYW5kbGVzIHNob3VsZCBiZSB1bnNldCBieSBub3csIGJ1dCB0aGVyZSBtaWdodCBiZSBzb21lIGJpdHMKICAgICAgICAgKiBtaXNzaW5nIGluIG91ciByZWZlcmVuY2UgY291bnRpbmcobmVlZHMgdGVzdCkuIERvIGEgc2FuaXR5IGNoZWNrCiAgICAgICAgICovCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bnVtSGFuZGxlczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaWYoVGhpcy0+SGFuZGxlc1tpXS5wdHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaChUaGlzLT5IYW5kbGVzW2ldLnR5cGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBERHJhd0hhbmRsZV9UZXh0dXJlOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICopIFRoaXMtPkhhbmRsZXNbaV0ucHRyOwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVGV4dHVyZSBIYW5kbGUgJWQgbm90IHVuc2V0IHByb3Blcmx5XG4iLCBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1cmYtPkhhbmRsZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX01hdGVyaWFsOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNETWF0ZXJpYWxJbXBsICptYXQgPSAoSURpcmVjdDNETWF0ZXJpYWxJbXBsICopIFRoaXMtPkhhbmRsZXNbaV0ucHRyOwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiTWF0ZXJpYWwgaGFuZGxlICVkIG5vdCB1bnNldCBwcm9wZXJseVxuIiwgaSArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBtYXQtPkhhbmRsZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX01hdHJpeDoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vIGZpeG1lIGhlcmUgYmVjYXVzZSB0aGlzIG1pZ2h0IGhhcHBlbiBiZWNhdXNlIG9mIHNsb3BweSBhcHBzICovCiAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIkxlZnRvdmVyIG1hdHJpeCBoYW5kbGUgJWQsIGRlbGV0aW5nXG4iLCBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZV9EZWxldGVNYXRyaXgoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX1N0YXRlQmxvY2s6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBObyBmaXhtZSBoZXJlIGJlY2F1c2UgdGhpcyBtaWdodCBoYXBwZW4gYmVjYXVzZSBvZiBzbG9wcHkgYXBwcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJMZWZ0b3ZlciBzdGF0ZWJsb2NrIGhhbmRsZSAlZCwgZGVsZXRpbmdcbiIsIGkgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNERGV2aWNlN19EZWxldGVTdGF0ZUJsb2NrKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArIDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVua25vd24gaGFuZGxlICVkIG5vdCB1bnNldCBwcm9wZXJseVxuIiwgaSArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5IYW5kbGVzKTsKCiAgICAgICAgVFJBQ0UoIlJlbGVhc2luZyB0YXJnZXQgJXAgJXBcbiIsIFRoaXMtPnRhcmdldCwgVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQpOwogICAgICAgIC8qIFJlbGVhc2UgdGhlIHJlbmRlciB0YXJnZXQgYW5kIHRoZSBXaW5lRDNEIHJlbmRlciB0YXJnZXQKICAgICAgICAgKiAoU2VlIElEaXJlY3QzRDc6OkNyZWF0ZURldmljZSBmb3IgbW9yZSBjb21tZW50cyBvbiB0aGlzKQogICAgICAgICAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShUaGlzLT50YXJnZXQsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQsSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgIFRSQUNFKCJUYXJnZXQgcmVsZWFzZSBkb25lXG4iKTsKCiAgICAgICAgVGhpcy0+ZGRyYXctPmQzZGRldmljZSA9IE5VTEw7CgogICAgICAgIC8qIE5vdyBmcmVlIHRoZSBzdHJ1Y3R1cmUgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgfQoKICAgIFRSQUNFKCJEb25lXG4iKTsKICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1JlbGVhc2UoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfUmVsZWFzZShJRGlyZWN0M0REZXZpY2UyICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9SZWxlYXNlKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlIE1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6SW5pdGlhbGl6ZQogKgogKiBJbml0aWFsaXplcyBhIERpcmVjdDNERGV2aWNlLiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGEgbm8tb3AsIGFzIGFsbAogKiBpbml0aWFsaXphdGlvbiBpcyBkb25lIGF0IGNyZWF0ZSB0aW1lLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBObyBpZGVhIHdoYXQgdGhleSBtZWFuLCBhcyB0aGUgTVNETiBwYWdlIGlzIGdvbmUKICoKICogUmV0dXJuczogRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0luaXRpYWxpemUoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEICpEaXJlY3QzRCwgR1VJRCAqZ3VpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CgogICAgLyogSXQgc2hvdWxkbid0IGJlIGNydWNpYWwsIGJ1dCBwcmludCBhIEZJWE1FLCBJJ20gaW50ZXJlc3RlZCBpZgogICAgICogYW55IGdhbWUgY2FsbHMgaXQgYW5kIHdoZW4KICAgICAqLwogICAgRklYTUUoIiglcCktPiglcCwlcCwlcCk6IE5vLW9wIVxuIiwgVGhpcywgRGlyZWN0M0QsIGd1aWQsIERlc2MpOwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRDYXBzCiAqCiAqIFJldHJpZXZlcyB0aGUgZGV2aWNlJ3MgY2FwYWJpbGl0aWVzCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgdXNlZCBmb3IgVmVyc2lvbiA3IG9ubHksIHRoZSBvbGRlciB2ZXJzaW9ucyBoYXZlCiAqIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4KICoKICogUGFyYW1ldGVyczoKICogIERlc2M6IFBvaW50ZXIgdG8gYSBEM0RERVZJQ0VERVNDNyBzdHJ1Y3R1cmUgdG8gZmlsbAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEQzREVSUl8qIGlmIGEgcHJvYmxlbSBvY2N1cnMuIFNlZSBXaW5lRDNECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENhcHMoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERFVklDRURFU0M3ICpEZXNjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBEM0RERVZJQ0VERVNDIE9sZERlc2M7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRGVzYyk7CgogICAgLyogQ2FsbCB0aGUgc2FtZSBmdW5jdGlvbiB1c2VkIGJ5IElEaXJlY3QzRCwgdGhpcyBzYXZlcyBjb2RlICovCiAgICByZXR1cm4gSURpcmVjdDNESW1wbF9HZXRDYXBzKFRoaXMtPmRkcmF3LT53aW5lRDNELCAmT2xkRGVzYywgRGVzYyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2Fwc19GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQzcgKkRlc2MpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2FwcyhpZmFjZSwgRGVzYyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2Fwc19GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQzcgKkRlc2MpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19HZXRDYXBzKGlmYWNlLCBEZXNjKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpHZXRDYXBzCiAqCiAqIFJldHJpZXZlcyB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBoYXJkd2FyZSBkZXZpY2UgYW5kIHRoZSBlbXVsYXRpb24KICogZGV2aWNlLiBGb3IgV2luZSwgaGFyZHdhcmUgYW5kIGVtdWxhdGlvbiBhcmUgdGhlIHNhbWUgKGl0J3MgYWxsIEhXKS4KICoKICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkIGZvciBWZXJzaW9uIDEsIDIsIGFuZCAzLiBWZXJzaW9uIDcgaGFzIGl0cyBvd24KICoKICogUGFyYW1ldGVyczoKICogIEhXRGVzYzogU3RydWN0dXJlIHRvIGZpbGwgd2l0aCB0aGUgSFcgY2FwcwogKiAgSGVsRGVzYzogU3RydWN0dXJlIHRvIGZpbGwgd2l0aCB0aGUgaGFyZHdhcmUgZW11bGF0aW9uIGNhcHMKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfKiBpZiBhIHByb2JsZW0gb2NjdXJzLiBTZWUgV2luZUQzRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q2FwcyhJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqSFdEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RERVZJQ0VERVNDICpIZWxEZXNjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBEM0RERVZJQ0VERVNDNyBuZXdEZXNjOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBpZmFjZSwgSFdEZXNjLCBIZWxEZXNjKTsKCiAgICBociA9IElEaXJlY3QzREltcGxfR2V0Q2FwcyhUaGlzLT5kZHJhdy0+d2luZUQzRCwgSFdEZXNjLCAmbmV3RGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKCiAgICAqSGVsRGVzYyA9ICpIV0Rlc2M7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldENhcHMoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERFVklDRURFU0MgKkQzREhXRGV2RGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRDNESEVMRGV2RGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwLCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIEQzREhXRGV2RGVzYywgRDNESEVMRGV2RGVzYyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRDYXBzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RIV0RldkRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzREhFTERldkRlc2MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0dldENhcHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRDNESFdEZXZEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RERVZJQ0VERVNDICpEM0RIRUxEZXZEZXNjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEM0RIV0RldkRlc2MsIEQzREhFTERldkRlc2MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfR2V0Q2FwcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNESFdEZXZEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RIRUxEZXZEZXNjKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTI6OlN3YXBUZXh0dXJlSGFuZGxlcwogKgogKiBTd2FwcyB0aGUgdGV4dHVyZSBoYW5kbGVzIG9mIDIgVGV4dHVyZSBpbnRlcmZhY2VzLiBWZXJzaW9uIDEgYW5kIDIKICoKICogUGFyYW1ldGVyczoKICogIFRleDEsIFRleDI6IFRoZSAyIFRleHR1cmVzIHRvIHN3YXAKICoKICogUmV0dXJuczoKICogIEQzRF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzJfU3dhcFRleHR1cmVIYW5kbGVzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICpUZXgxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICpUZXgyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBEV09SRCBzd2FwOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjEgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlMiwgVGV4MSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmMiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBUZXgyKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBzdXJmMSwgc3VyZjIpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBUaGlzLT5IYW5kbGVzW3N1cmYxLT5IYW5kbGUgLSAxXS5wdHIgPSBzdXJmMjsKICAgIFRoaXMtPkhhbmRsZXNbc3VyZjItPkhhbmRsZSAtIDFdLnB0ciA9IHN1cmYxOwoKICAgIHN3YXAgPSBzdXJmMi0+SGFuZGxlOwogICAgc3VyZjItPkhhbmRsZSA9IHN1cmYxLT5IYW5kbGU7CiAgICBzdXJmMS0+SGFuZGxlID0gc3dhcDsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9Td2FwVGV4dHVyZUhhbmRsZXMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RUZXh0dXJlICpEM0RUZXgxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUgKkQzRFRleDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjEgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlLCBEM0RUZXgxKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYyID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgRDNEVGV4Mik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTIgaW50ZXJmYWNlLlxuIiwgVGhpcywgc3VyZjEsIHN1cmYyKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UyX1N3YXBUZXh0dXJlSGFuZGxlcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRShzdXJmMSwgSURpcmVjdDNEVGV4dHVyZTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHN1cmYyLCBJRGlyZWN0M0RUZXh0dXJlMikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6R2V0U3RhdHMKICoKICogVGhpcyBtZXRob2Qgc2VlbXMgdG8gcmV0cmlldmUgc29tZSBzdGF0cyBmcm9tIHRoZSBkZXZpY2UuCiAqIFRoZSBNU0ROIGRvY3VtZW50YXRpb24gZG9lc24ndCBleGlzdCBhbnkgbW9yZSwgYnV0IHRoZSBEM0RTVEFUUwogKiBzdHJ1Y3R1cmUgc3VnZ2VzdHMgdGhhdCB0aGUgYW1vdW50IG9mIGRyYXduIHByaW1pdGl2ZXMgYW5kIHByb2Nlc3NlZAogKiB2ZXJ0aWNlcyBpcyByZXR1cm5lZC4KICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiBhbmQgMwogKgogKiBQYXJhbWV0ZXJzOgogKiAgU3RhdHM6IFBvaW50ZXIgdG8gYSBEM0RTVEFUUyBzdHJ1Y3R1cmUgdG8gYmUgZmlsbGVkCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBTdGF0cyA9PSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19HZXRTdGF0cyhJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFNUQVRTICpTdGF0cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCk6IFN0dWIhXG4iLCBUaGlzLCBTdGF0cyk7CgogICAgaWYoIVN0YXRzKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIEZpbGwgdGhlIFN0YXRzIHdpdGggMCAqLwogICAgU3RhdHMtPmR3VHJpYW5nbGVzRHJhd24gPSAwOwogICAgU3RhdHMtPmR3TGluZXNEcmF3biA9IDA7CiAgICBTdGF0cy0+ZHdQb2ludHNEcmF3biA9IDA7CiAgICBTdGF0cy0+ZHdTcGFuc0RyYXduID0gMDsKICAgIFN0YXRzLT5kd1ZlcnRpY2VzUHJvY2Vzc2VkID0gMDsKCiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFN0YXRzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEU1RBVFMgKlN0YXRzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhdHMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfR2V0U3RhdHMoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0U3RhdHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFNUQVRTICpTdGF0cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhdHMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfR2V0U3RhdHMoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0cyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OkNyZWF0ZUV4ZWN1dGVCdWZmZXIKICoKICogQ3JlYXRlcyBhbiBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyLCB1c2VkIGZvciByZW5kZXJpbmcgd2l0aCBhCiAqIERpcmVjdDNERGV2aWNlLgogKgogKiBWZXJzaW9uIDEgb25seS4KICoKICogUGFyYW1zOgogKiAgRGVzYzogQnVmZmVyIGRlc2NyaXB0aW9uCiAqICBFeGVjdXRlQnVmZmVyOiBBZGRyZXNzIHRvIHJldHVybiB0aGUgSW50ZXJmYWNlIHBvaW50ZXIgYXQKICogIFVua091dGVyOiBNdXN0IGJlIE5VTEwuIEJhc2ljYWxseSBmb3IgYWdncmVnYXRpb24sIHdoaWNoIGRkcmF3IGRvZXNuJ3QKICogICAgICAgICAgICBzdXBwb3J0CiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRERFUlJfT1VUT0ZNRU1PUlkgaWYgd2UgcmFuIG91dCBvZiBtZW1vcnkKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9DcmVhdGVFeGVjdXRlQnVmZmVyKElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzREVYRUNVVEVCVUZGRVJERVNDICpEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyICoqRXhlY3V0ZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIElEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsKiBvYmplY3Q7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwKSFcbiIsIFRoaXMsIERlc2MsIEV4ZWN1dGVCdWZmZXIsIFVua091dGVyKTsKCiAgICBpZihVbmtPdXRlcikKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBuZXcgRXhlY3V0ZSBCdWZmZXIgKi8KICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwpKTsKICAgIGlmKCFvYmplY3QpCiAgICB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBhIElEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsIHN0cnVjdHVyZVxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX09VVE9GTUVNT1JZOwogICAgfQoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyLCBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyX1Z0YmwpOwoKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+ZDNkZGV2ID0gVGhpczsKCiAgICAvKiBJbml0aWFsaXplcyBtZW1vcnkgKi8KICAgIG1lbWNweSgmb2JqZWN0LT5kZXNjLCBEZXNjLCBEZXNjLT5kd1NpemUpOwoKICAgIC8qIE5vIGJ1ZmZlciBnaXZlbiAqLwogICAgaWYgKChvYmplY3QtPmRlc2MuZHdGbGFncyAmIEQzRERFQl9MUERBVEEpID09IDApCiAgICAgICAgb2JqZWN0LT5kZXNjLmxwRGF0YSA9IE5VTEw7CgogICAgLyogTm8gYnVmZmVyIHNpemUgZ2l2ZW4gKi8KICAgIGlmICgob2JqZWN0LT5kZXNjLmR3RmxhZ3MgJiBEM0RERUJfQlVGU0laRSkgPT0gMCkKICAgICAgICBvYmplY3QtPmRlc2MuZHdCdWZmZXJTaXplID0gMDsKCiAgICAvKiBDcmVhdGUgYnVmZmVyIGlmIGFza2VkICovCiAgICBpZiAoKG9iamVjdC0+ZGVzYy5scERhdGEgPT0gTlVMTCkgJiYgKG9iamVjdC0+ZGVzYy5kd0J1ZmZlclNpemUgPiAwKSkKICAgIHsKICAgICAgICBvYmplY3QtPm5lZWRfZnJlZSA9IFRSVUU7CiAgICAgICAgb2JqZWN0LT5kZXNjLmxwRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksb2JqZWN0LT5kZXNjLmR3QnVmZmVyU2l6ZSk7CiAgICAgICAgaWYoIW9iamVjdC0+ZGVzYy5scERhdGEpCiAgICAgICAgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIHRoZSBleGVjdXRlIGJ1ZmZlciBkYXRhXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBvYmplY3QtPm5lZWRfZnJlZSA9IEZBTFNFOwogICAgfQoKICAgIC8qIE5vIHZlcnRpY2VzIGZvciB0aGUgbW9tZW50ICovCiAgICBvYmplY3QtPnZlcnRleF9kYXRhID0gTlVMTDsKCiAgICBvYmplY3QtPmRlc2MuZHdGbGFncyB8PSBEM0RERUJfTFBEQVRBOwoKICAgIG9iamVjdC0+aW5kaWNlcyA9IE5VTEw7CiAgICBvYmplY3QtPm5iX2luZGljZXMgPSAwOwoKICAgICpFeGVjdXRlQnVmZmVyID0gSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyKTsKCiAgICBUUkFDRSgiIFJldHVybmluZyBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyIGF0ICVwLCBpbXBsZW1lbnRhdGlvbiBpcyBhdCAlcFxuIiwgKkV4ZWN1dGVCdWZmZXIsIG9iamVjdCk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6RXhlY3V0ZQogKgogKiBFeGVjdXRlcyBhbGwgdGhlIHN0dWZmIGluIGFuIGV4ZWN1dGUgYnVmZmVyLgogKgogKiBQYXJhbXM6CiAqICBFeGVjdXRlQnVmZmVyOiBUaGUgYnVmZmVyIHRvIGV4ZWN1dGUKICogIFZpZXdwb3J0OiBUaGUgdmlld3BvcnQgdXNlZCBmb3IgcmVuZGVyaW5nCiAqICBGbGFnczogU29tZSBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBFeGVjdXRlQnVmZmVyID09IE5VTEwKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9FeGVjdXRlKElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIgKkV4ZWN1dGVCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0ICpWaWV3cG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwgKkRpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCwgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlciwgRXhlY3V0ZUJ1ZmZlcik7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKkRpcmVjdDNEVmlld3BvcnRJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIFZpZXdwb3J0KTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCUwOHgpXG4iLCBUaGlzLCBEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsLCBEaXJlY3QzRFZpZXdwb3J0SW1wbCwgRmxhZ3MpOwoKICAgIGlmKCFEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIEV4ZWN1dGUuLi4gKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbF9FeGVjdXRlKERpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwsIFRoaXMsIERpcmVjdDNEVmlld3BvcnRJbXBsKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkFkZFZpZXdwb3J0CiAqCiAqIEFkZCBhIERpcmVjdDNEVmlld3BvcnQgdG8gdGhlIGRldmljZSdzIHZpZXdwb3J0IGxpc3QuIFRoZXNlIHZpZXdwb3J0cwogKiBhcmUgd3JhcHBlZCB0byBJRGlyZWN0M0REZXZpY2U3IHZpZXdwb3J0cyBpbiB2aWV3cG9ydC5jCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIgYW5kIDMuIE5vdGUgdGhhdCBJRGlyZWN0M0RWaWV3cG9ydCAxLCAyIGFuZCAzCiAqIGFyZSB0aGUgc2FtZSBpbnRlcmZhY2VzLgogKgogKiBQYXJhbXM6CiAqICBWaWV3cG9ydDogVGhlIHZpZXdwb3J0IHRvIGFkZAogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBWaWV3cG9ydCA9PSBOVUxMCiAqICBEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfQWRkVmlld3BvcnQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKlZpZXdwb3J0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIFZpZXdwb3J0KTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgdnApOwoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYoIXZwKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICB2cC0+bmV4dCA9IFRoaXMtPnZpZXdwb3J0X2xpc3Q7CiAgICBUaGlzLT52aWV3cG9ydF9saXN0ID0gdnA7CiAgICB2cC0+YWN0aXZlX2RldmljZSA9IFRoaXM7IC8qIFZpZXdwb3J0IG11c3QgYmUgdXNhYmxlIGZvciBDbGVhcigpIGFmdGVyIEFkZFZpZXdwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbyBzZXQgYWN0aXZlX2RldmljZSBoZXJlLiAqLwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0FkZFZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQyICpEaXJlY3QzRFZpZXdwb3J0MikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICp2cCA9IElDT01fT0JKRUNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBEaXJlY3QzRFZpZXdwb3J0Mik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgdnApOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfQWRkVmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfQWRkVmlld3BvcnQoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0ICpEaXJlY3QzRFZpZXdwb3J0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydCk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgdnApOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfQWRkVmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpEZWxldGVWaWV3cG9ydAogKgogKiBEZWxldGVzIGEgRGlyZWN0M0RWaWV3cG9ydCBmcm9tIHRoZSBkZXZpY2UncyB2aWV3cG9ydCBsaXN0LgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyIGFuZCAzLiBOb3RlIHRoYXQgYWxsIFZpZXdwb3J0IGludGVyZmFjZSB2ZXJzaW9ucwogKiBhcmUgZXF1YWwuCiAqCiAqIFBhcmFtczoKICogIFZpZXdwb3J0OiBUaGUgdmlld3BvcnQgdG8gZGVsZXRlCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgdmlld3BvcnQgd2Fzbid0IGZvdW5kIGluIHRoZSBsaXN0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19EZWxldGVWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqVmlld3BvcnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSAoSURpcmVjdDNEVmlld3BvcnRJbXBsICopIFZpZXdwb3J0OwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICpjdXJfdmlld3BvcnQsICpwcmV2X3ZpZXdwb3J0ID0gTlVMTDsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgdnApOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBjdXJfdmlld3BvcnQgPSBUaGlzLT52aWV3cG9ydF9saXN0OwogICAgd2hpbGUgKGN1cl92aWV3cG9ydCAhPSBOVUxMKQogICAgewogICAgICAgIGlmIChjdXJfdmlld3BvcnQgPT0gdnApCiAgICAgICAgewogICAgICAgICAgICBpZiAocHJldl92aWV3cG9ydCA9PSBOVUxMKSBUaGlzLT52aWV3cG9ydF9saXN0ID0gY3VyX3ZpZXdwb3J0LT5uZXh0OwogICAgICAgICAgICBlbHNlIHByZXZfdmlld3BvcnQtPm5leHQgPSBjdXJfdmlld3BvcnQtPm5leHQ7CiAgICAgICAgICAgIC8qIFRPRE8gOiBhZGQgZGVzYWN0aXZhdGUgb2YgdGhlIHZpZXdwb3J0IGFuZCBhbGwgYXNzb2NpYXRlZCBsaWdodHMuLi4gKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIEQzRF9PSzsKICAgICAgICB9CiAgICAgICAgcHJldl92aWV3cG9ydCA9IGN1cl92aWV3cG9ydDsKICAgICAgICBjdXJfdmlld3BvcnQgPSBjdXJfdmlld3BvcnQtPm5leHQ7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0RlbGV0ZVZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQyICpEaXJlY3QzRFZpZXdwb3J0MikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICp2cCA9IElDT01fT0JKRUNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBEaXJlY3QzRFZpZXdwb3J0Mik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgdnApOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfRGVsZXRlVmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfRGVsZXRlVmlld3BvcnQoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0ICpEaXJlY3QzRFZpZXdwb3J0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydCk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgdnApOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfRGVsZXRlVmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpOZXh0Vmlld3BvcnQKICoKICogUmV0dXJucyBhIHZpZXdwb3J0IGZyb20gdGhlIHZpZXdwb3J0IGxpc3QsIGRlcGVuZGluZyBvbiB0aGUKICogcGFzc2VkIHZpZXdwb3J0IGFuZCB0aGUgZmxhZ3MuCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIgYW5kIDMuIE5vdGUgdGhhdCBhbGwgVmlld3BvcnQgaW50ZXJmYWNlIHZlcnNpb25zCiAqIGFyZSBlcXVhbC4KICoKICogUGFyYW1zOgogKiAgVmlld3BvcnQ6IFZpZXdwb3J0IHRvIHVzZSBmb3IgYmVnaW5uaW5nIHRoZSBzZWFyY2gKICogIEZsYWdzOiBEM0RORVhUX05FWFQsIEQzRE5FWFRfSEVBRCBvciBEM0RORVhUX1RBSUwKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBmbGFncyB3ZXJlIHdyb25nLCBvciBWaWV3cG9ydCB3YXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfTmV4dFZpZXdwb3J0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqVmlld3BvcnQzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqKmxwbHBEaXJlY3QzRFZpZXdwb3J0MywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICp2cCA9IElDT01fT0JKRUNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBWaWV3cG9ydDMpOwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICpyZXMgPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJTA4eClcbiIsIFRoaXMsIHZwLCBscGxwRGlyZWN0M0RWaWV3cG9ydDMsIEZsYWdzKTsKCiAgICBpZighdnApCiAgICB7CiAgICAgICAgKmxwbHBEaXJlY3QzRFZpZXdwb3J0MyA9IE5VTEw7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2ggKEZsYWdzKQogICAgewogICAgICAgIGNhc2UgRDNETkVYVF9ORVhUOgogICAgICAgIHsKICAgICAgICAgICAgcmVzID0gdnAtPm5leHQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNETkVYVF9IRUFEOgogICAgICAgIHsKICAgICAgICAgICAgcmVzID0gVGhpcy0+dmlld3BvcnRfbGlzdDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RORVhUX1RBSUw6CiAgICAgICAgewogICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKmN1cl92aWV3cG9ydCA9IFRoaXMtPnZpZXdwb3J0X2xpc3Q7CiAgICAgICAgICAgIGlmIChjdXJfdmlld3BvcnQgIT0gTlVMTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKGN1cl92aWV3cG9ydC0+bmV4dCAhPSBOVUxMKSBjdXJfdmlld3BvcnQgPSBjdXJfdmlld3BvcnQtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzID0gY3VyX3ZpZXdwb3J0OwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAqbHBscERpcmVjdDNEVmlld3BvcnQzID0gTlVMTDsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgKmxwbHBEaXJlY3QzRFZpZXdwb3J0MyA9IElDT01fSU5URVJGQUNFKHJlcywgSURpcmVjdDNEVmlld3BvcnQzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX05leHRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDIgKlZpZXdwb3J0MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDIgKipscGxwRGlyZWN0M0RWaWV3cG9ydDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgVmlld3BvcnQyKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqcmVzOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwLCBscGxwRGlyZWN0M0RWaWV3cG9ydDIsIEZsYWdzKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlM19OZXh0Vmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHZwLCBJRGlyZWN0M0RWaWV3cG9ydDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICAqbHBscERpcmVjdDNEVmlld3BvcnQyID0gKElEaXJlY3QzRFZpZXdwb3J0MiAqKSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIElEaXJlY3QzRFZpZXdwb3J0MywgcmVzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9OZXh0Vmlld3BvcnQoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydCAqVmlld3BvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQgKipscGxwRGlyZWN0M0RWaWV3cG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIFZpZXdwb3J0KTsKICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqcmVzOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwLCBscGxwRGlyZWN0M0RWaWV3cG9ydCwgRmxhZ3MpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2UzX05leHRWaWV3cG9ydChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodnAsIElEaXJlY3QzRFZpZXdwb3J0MyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKICAgICpscGxwRGlyZWN0M0RWaWV3cG9ydCA9IChJRGlyZWN0M0RWaWV3cG9ydCAqKSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIElEaXJlY3QzRFZpZXdwb3J0MywgcmVzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6UGljawogKgogKiBFeGVjdXRlcyBhbiBleGVjdXRlIGJ1ZmZlciB3aXRob3V0IHBlcmZvcm1pbmcgcmVuZGVyaW5nLiBJbnN0ZWFkLCBhCiAqIGxpc3Qgb2YgcHJpbWl0aXZlcyB0aGF0IGludGVyc2VjdCB3aXRoICh4MSx5MSkgb2YgdGhlIHBhc3NlZCByZWN0YW5nbGUKICogaXMgY3JlYXRlZC4gSURpcmVjdDNERGV2aWNlOjpHZXRQaWNrUmVjb3JkcyBjYW4gYmUgdXNlZCB0byByZXRyaWV2ZQogKiB0aGlzIGxpc3QuCiAqCiAqIFZlcnNpb24gMSBvbmx5CiAqCiAqIFBhcmFtczoKICogIEV4ZWN1dGVCdWZmZXI6IEJ1ZmZlciB0byBleGVjdXRlCiAqICBWaWV3cG9ydDogVmlld3BvcnQgdG8gdXNlIGZvciBleGVjdXRpb24KICogIEZsYWdzOiBOb25lIGFyZSBkZWZpbmVkLCBhY2NvcmRpbmcgdG8gdGhlIFNESwogKiAgUmVjdDogU3BlY2lmaWVzIHRoZSBjb29yZGluYXRlcyB0byBiZSBwaWNrZWQuIE9ubHkgeDEgYW5kIHkyIGFyZSB1c2VkLAogKiAgICAgICAgeDIgYW5kIHkyIGFyZSBpZ25vcmVkLgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX1BpY2soSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlciAqRXhlY3V0ZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQgKlZpZXdwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVDVCAqUmVjdCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCAqZXhlY2J1ZiA9IElDT01fT0JKRUNUKElEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsLCBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyLCBFeGVjdXRlQnVmZmVyKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgVmlld3BvcnQpOwogICAgRklYTUUoIiglcCktPiglcCwlcCwlMDh4LCVwKTogc3R1YiFcbiIsIFRoaXMsIGV4ZWNidWYsIHZwLCBGbGFncywgUmVjdCk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6R2V0UGlja1JlY29yZHMKICoKICogUmV0cmlldmVzIHRoZSBwaWNrIHJlY29yZHMgZ2VuZXJhdGVkIGJ5IElEaXJlY3QzRERldmljZTo6R2V0UGlja1JlY29yZHMKICoKICogVmVyc2lvbiAxIG9ubHkKICoKICogUGFyYW1zOgogKiAgQ291bnQ6IFBvaW50ZXIgdG8gYSBEV09SRCBjb250YWluaW5nIHRoZSBudW1iZXJzIG9mIHBpY2sgcmVjb3JkcyB0bwogKiAgICAgICAgIHJldHJpZXZlCiAqICBEM0RQaWNrUmVjOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSByZXN1bHRpbmcgRDNEUElDS1JFQ09SRCBhcnJheS4KICoKICogUmV0dXJuczoKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0UGlja1JlY29yZHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBJQ0tSRUNPUkQgKkQzRFBpY2tSZWMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCwlcCk6IHN0dWIhXG4iLCBUaGlzLCBDb3VudCwgRDNEUGlja1JlYyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkVudW1UZXh0dXJlZm9ybWF0cwogKgogKiBFbnVtZXJhdGVzIHRoZSBzdXBwb3J0ZWQgdGV4dHVyZSBmb3JtYXRzLiBJdCBoYXMgYSBsaXN0IG9mIGFsbCBwb3NzaWJsZQogKiBmb3JtYXRzIGFuZCBjYWxscyBJV2luZUQzRDo6Q2hlY2tEZXZpY2VGb3JtYXQgZm9yIGVhY2ggZm9ybWF0IHRvIHNlZSBpZgogKiBXaW5lRDNEIHN1cHBvcnRzIGl0LiBJZiBzbywgdGhlbiBpdCBpcyBwYXNzZWQgdG8gdGhlIGFwcC4KICoKICogVGhpcyBpcyBmb3IgVmVyc2lvbiA3IGFuZCAzLCBvbGRlciB2ZXJzaW9ucyBoYXZlIGEgZGlmZmVyZW50CiAqIGNhbGxiYWNrIGZ1bmN0aW9uIGFuZCB0aGVpciBvd24gaW1wbGVtZW50YXRpb24KICoKICogUGFyYW1zOgogKiAgQ2FsbGJhY2s6IENhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggZW51bWVyYXRlZCBmb3JtYXQKICogIEFyZzogQXJndW1lbnQgdG8gcGFzcyB0byB0aGUgY2FsbGJhY2sKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhbGxiYWNrID09IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW51bVRleHR1cmVGb3JtYXRzKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNERU5VTVBJWEVMRk9STUFUU0NBTExCQUNLIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkFyZykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIGludCBpOwoKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0TGlzdFtdID0gewogICAgICAgIC8qIDMyIGJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfQThSOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9YOFI4RzhCOCwKICAgICAgICAvKiAyNCBiaXQgKi8KICAgICAgICBXSU5FRDNERk1UX1I4RzhCOCwKICAgICAgICAvKiAxNiBCaXQgKi8KICAgICAgICBXSU5FRDNERk1UX0ExUjVHNUI1LAogICAgICAgIFdJTkVEM0RGTVRfQTRSNEc0QjQsCiAgICAgICAgV0lORUQzREZNVF9SNUc2QjUsCiAgICAgICAgV0lORUQzREZNVF9YMVI1RzVCNSwKICAgICAgICAvKiA4IEJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfUjNHM0IyLAogICAgICAgIFdJTkVEM0RGTVRfUDgsCiAgICAgICAgLyogRk9VUkNDIGNvZGVzICovCiAgICAgICAgV0lORUQzREZNVF9EWFQxLAogICAgICAgIFdJTkVEM0RGTVRfRFhUMywKICAgICAgICBXSU5FRDNERk1UX0RYVDUsCiAgICB9OwoKICAgIFdJTkVEM0RGT1JNQVQgQnVtcEZvcm1hdExpc3RbXSA9IHsKICAgICAgICBXSU5FRDNERk1UX1Y4VTgsCiAgICAgICAgV0lORUQzREZNVF9MNlY1VTUsCiAgICAgICAgV0lORUQzREZNVF9YOEw4VjhVOCwKICAgICAgICBXSU5FRDNERk1UX1E4VzhWOFU4LAogICAgICAgIFdJTkVEM0RGTVRfVjE2VTE2LAogICAgICAgIFdJTkVEM0RGTVRfVzExVjExVTEwLAogICAgICAgIFdJTkVEM0RGTVRfQTJXMTBWMTBVMTAKICAgIH07CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBDYWxsYmFjaywgQXJnKTsKCiAgICBpZighQ2FsbGJhY2spCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGZvcihpID0gMDsgaSA8IHNpemVvZihGb3JtYXRMaXN0KSAvIHNpemVvZihXSU5FRDNERk9STUFUKTsgaSsrKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RfQ2hlY2tEZXZpY2VGb3JtYXQoVGhpcy0+ZGRyYXctPndpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIERldmljZVR5cGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXJGb3JtYXQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFVzYWdlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBSZXNvdXJjZVR5cGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXRMaXN0W2ldKTsKICAgICAgICBpZihociA9PSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBERFBJWEVMRk9STUFUIHBmb3JtYXQ7CgogICAgICAgICAgICBtZW1zZXQoJnBmb3JtYXQsIDAsIHNpemVvZihwZm9ybWF0KSk7CiAgICAgICAgICAgIHBmb3JtYXQuZHdTaXplID0gc2l6ZW9mKHBmb3JtYXQpOwogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmcGZvcm1hdCwgRm9ybWF0TGlzdFtpXSk7CgogICAgICAgICAgICBUUkFDRSgiRW51bWVyYXRpbmcgV2luZUQzREZvcm1hdCAlZFxuIiwgRm9ybWF0TGlzdFtpXSk7CiAgICAgICAgICAgIGhyID0gQ2FsbGJhY2soJnBmb3JtYXQsIEFyZyk7CiAgICAgICAgICAgIGlmKGhyICE9IERERU5VTVJFVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIkZvcm1hdCBlbnVtZXJhdGlvbiBjYW5jZWxsZWQgYnkgYXBwbGljYXRpb25cbiIpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEM0RfT0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgc2l6ZW9mKEJ1bXBGb3JtYXRMaXN0KSAvIHNpemVvZihXSU5FRDNERk9STUFUKTsgaSsrKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RfQ2hlY2tEZXZpY2VGb3JtYXQoVGhpcy0+ZGRyYXctPndpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIERldmljZVR5cGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXJGb3JtYXQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVVNBR0VfUVVFUllfTEVHQUNZQlVNUE1BUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogUmVzb3VyY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnVtcEZvcm1hdExpc3RbaV0pOwogICAgICAgIGlmKGhyID09IEQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEREUElYRUxGT1JNQVQgcGZvcm1hdDsKCiAgICAgICAgICAgIG1lbXNldCgmcGZvcm1hdCwgMCwgc2l6ZW9mKHBmb3JtYXQpKTsKICAgICAgICAgICAgcGZvcm1hdC5kd1NpemUgPSBzaXplb2YocGZvcm1hdCk7CiAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZwZm9ybWF0LCBCdW1wRm9ybWF0TGlzdFtpXSk7CgogICAgICAgICAgICBUUkFDRSgiRW51bWVyYXRpbmcgV2luZUQzREZvcm1hdCAlZFxuIiwgQnVtcEZvcm1hdExpc3RbaV0pOwogICAgICAgICAgICBociA9IENhbGxiYWNrKCZwZm9ybWF0LCBBcmcpOwogICAgICAgICAgICBpZihociAhPSBEREVOVU1SRVRfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJGb3JtYXQgZW51bWVyYXRpb24gY2FuY2VsbGVkIGJ5IGFwcGxpY2F0aW9uXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRDNEX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19FbnVtVGV4dHVyZUZvcm1hdHNfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEM0RFTlVNUElYRUxGT1JNQVRTQ0FMTEJBQ0sgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQXJnKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0VudW1UZXh0dXJlRm9ybWF0cyhpZmFjZSwgQ2FsbGJhY2ssIEFyZyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW51bVRleHR1cmVGb3JtYXRzX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNERU5VTVBJWEVMRk9STUFUU0NBTExCQUNLIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkFyZykKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0VudW1UZXh0dXJlRm9ybWF0cyhpZmFjZSwgQ2FsbGJhY2ssIEFyZyk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19FbnVtVGV4dHVyZUZvcm1hdHMoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEM0RFTlVNUElYRUxGT1JNQVRTQ0FMTEJBQ0sgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQXJnKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2FsbGJhY2ssIEFyZyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19FbnVtVGV4dHVyZUZvcm1hdHMoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTI6OkVudW1UZXh0dXJlZm9ybWF0cwogKgogKiBFbnVtVGV4dHVyZUZvcm1hdHMgZm9yIFZlcnNpb24gMSBhbmQgMiwgc2VlCiAqIElEaXJlY3QzRERldmljZTc6OkVudW1UZXh1cmVGb3JtYXRzIGZvciBhIG1vcmUgZGV0YWlsZWQgZGVzY3JpcHRpb24uCiAqCiAqIFRoaXMgdmVyc2lvbiBoYXMgYSBkaWZmZXJlbnQgY2FsbGJhY2sgYW5kIGRvZXMgbm90IGVudW1lcmF0ZSBGb3VyQ0MKICogZm9ybWF0cwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzJfRW51bVRleHR1cmVGb3JtYXRzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNERU5VTVRFWFRVUkVGT1JNQVRTQ0FMTEJBQ0sgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQXJnKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgaW50IGk7CgogICAgV0lORUQzREZPUk1BVCBGb3JtYXRMaXN0W10gPSB7CiAgICAgICAgLyogMzIgYml0ICovCiAgICAgICAgV0lORUQzREZNVF9BOFI4RzhCOCwKICAgICAgICBXSU5FRDNERk1UX1g4UjhHOEI4LAogICAgICAgIC8qIDI0IGJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfUjhHOEI4LAogICAgICAgIC8qIDE2IEJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfQTFSNUc1QjUsCiAgICAgICAgV0lORUQzREZNVF9BNFI0RzRCNCwKICAgICAgICBXSU5FRDNERk1UX1I1RzZCNSwKICAgICAgICBXSU5FRDNERk1UX1gxUjVHNUI1LAogICAgICAgIC8qIDggQml0ICovCiAgICAgICAgV0lORUQzREZNVF9SM0czQjIsCiAgICAgICAgV0lORUQzREZNVF9QOCwKICAgICAgICAvKiBGT1VSQ0MgY29kZXMgLSBOb3QgaW4gdGhpcyB2ZXJzaW9uKi8KICAgIH07CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBDYWxsYmFjaywgQXJnKTsKCiAgICBpZighQ2FsbGJhY2spCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGZvcihpID0gMDsgaSA8IHNpemVvZihGb3JtYXRMaXN0KSAvIHNpemVvZihXSU5FRDNERk9STUFUKTsgaSsrKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RfQ2hlY2tEZXZpY2VGb3JtYXQoVGhpcy0+ZGRyYXctPndpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIERldmljZVR5cGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEFkYXB0ZXJGb3JtYXQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFVzYWdlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBSZXNvdXJjZVR5cGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXRMaXN0W2ldKTsKICAgICAgICBpZihociA9PSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBERFNVUkZBQ0VERVNDIHNkZXNjOwoKICAgICAgICAgICAgbWVtc2V0KCZzZGVzYywgMCwgc2l6ZW9mKHNkZXNjKSk7CiAgICAgICAgICAgIHNkZXNjLmR3U2l6ZSA9IHNpemVvZihzZGVzYyk7CiAgICAgICAgICAgIHNkZXNjLmR3RmxhZ3MgPSBERFNEX1BJWEVMRk9STUFUIHwgRERTRF9DQVBTOwogICAgICAgICAgICBzZGVzYy5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfVEVYVFVSRTsKICAgICAgICAgICAgc2Rlc2MuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihzZGVzYy5kZHBmUGl4ZWxGb3JtYXQpOwogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmc2Rlc2MuZGRwZlBpeGVsRm9ybWF0LCBGb3JtYXRMaXN0W2ldKTsKCiAgICAgICAgICAgIFRSQUNFKCJFbnVtZXJhdGluZyBXaW5lRDNERm9ybWF0ICVkXG4iLCBGb3JtYXRMaXN0W2ldKTsKICAgICAgICAgICAgaHIgPSBDYWxsYmFjaygmc2Rlc2MsIEFyZyk7CiAgICAgICAgICAgIGlmKGhyICE9IERERU5VTVJFVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIkZvcm1hdCBlbnVtZXJhdGlvbiBjYW5jZWxsZWQgYnkgYXBwbGljYXRpb25cbiIpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEM0RfT0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBUUkFDRSgiRW5kIG9mIGVudW1lcmF0aW9uXG4iKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0VudW1UZXh0dXJlRm9ybWF0cyhJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNERU5VTVRFWFRVUkVGT1JNQVRTQ0FMTEJBQ0sgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQXJnKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMiBpbnRlcmZhY2UuXG4iLCBUaGlzLCBDYWxsYmFjaywgQXJnKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UyX0VudW1UZXh0dXJlRm9ybWF0cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlOjpDcmVhdGVNYXRyaXgKICoKICogQ3JlYXRlcyBhIG1hdHJpeCBoYW5kbGUuIEEgaGFuZGxlIGlzIGNyZWF0ZWQgYW5kIG1lbW9yeSBmb3IgYSBEM0RNQVRSSVggaXMKICogYWxsb2NhdGVkIGZvciB0aGUgaGFuZGxlLgogKgogKiBWZXJzaW9uIDEgb25seQogKgogKiBQYXJhbXMKICogIEQzRE1hdEhhbmRsZTogQWRkcmVzcyB0byByZXR1cm4gdGhlIGhhbmRsZSBhdAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNETWF0SGFuZGxlID0gTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzFfQ3JlYXRlTWF0cml4KElEaXJlY3QzRERldmljZSAqaWZhY2UsIEQzRE1BVFJJWEhBTkRMRSAqRDNETWF0SGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIEQzRE1BVFJJWCAqTWF0cml4OwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEQzRE1hdEhhbmRsZSk7CgogICAgaWYoIUQzRE1hdEhhbmRsZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBNYXRyaXggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEQzRE1BVFJJWCkpOwogICAgaWYoIU1hdHJpeCkKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIGEgRDNETUFUUklYXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpEM0RNYXRIYW5kbGUgPSBJRGlyZWN0M0REZXZpY2VJbXBsX0NyZWF0ZUhhbmRsZShUaGlzKTsKICAgIGlmKCEoKkQzRE1hdEhhbmRsZSkpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgbWF0cml4IGhhbmRsZVxuIik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgTWF0cml4KTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRk1FTU9SWTsKICAgIH0KICAgIFRoaXMtPkhhbmRsZXNbKkQzRE1hdEhhbmRsZSAtIDFdLnB0ciA9IE1hdHJpeDsKICAgIFRoaXMtPkhhbmRsZXNbKkQzRE1hdEhhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9NYXRyaXg7CiAgICBUUkFDRSgiIHJldHVybmluZyBtYXRyaXggaGFuZGxlICVkXG4iLCAqRDNETWF0SGFuZGxlKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6U2V0TWF0cml4CiAqCiAqIFNldHMgYSBtYXRyaXggZm9yIGEgbWF0cml4IGhhbmRsZS4gVGhlIG1hdHJpeCBpcyBjb3BpZWQgaW50byB0aGUgbWVtb3J5CiAqIGFsbG9jYXRlZCBmb3IgdGhlIGhhbmRsZQogKgogKiBWZXJzaW9uIDEgb25seQogKgogKiBQYXJhbXM6CiAqICBEM0RNYXRIYW5kbGU6IEhhbmRsZSB0byBzZXQgdGhlIG1hdHJpeCB0bwogKiAgRDNETWF0cml4OiBNYXRyaXggdG8gc2V0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgaGFuZGxlIG9mIHRoZSBtYXRyaXggaXMgaW52YWxpZCBvciB0aGUgbWF0cml4CiAqICAgdG8gc2V0IGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX1NldE1hdHJpeChJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWEhBTkRMRSBEM0RNYXRIYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcywgRDNETWF0SGFuZGxlLCBEM0RNYXRyaXgpOwoKICAgIGlmKCAoIUQzRE1hdEhhbmRsZSkgfHwgKCFEM0RNYXRyaXgpICkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoRDNETWF0SGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBvdXQgb2YgcmFuZ2VcbiIsIEQzRE1hdEhhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KICAgIGVsc2UgaWYoVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX01hdHJpeCkKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBpcyBub3QgYSBtYXRyaXggaGFuZGxlXG4iLCBEM0RNYXRIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYgKFRSQUNFX09OKGQzZDcpKQogICAgICAgIGR1bXBfRDNETUFUUklYKEQzRE1hdHJpeCk7CgogICAgKigoRDNETUFUUklYICopIFRoaXMtPkhhbmRsZXNbRDNETWF0SGFuZGxlIC0gMV0ucHRyKSA9ICpEM0RNYXRyaXg7CgogICAgaWYoVGhpcy0+d29ybGQgPT0gRDNETWF0SGFuZGxlKQogICAgewogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRyYW5zZm9ybShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVFNfV09STERNQVRSSVgoMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFUUklYICopIEQzRE1hdHJpeCk7CiAgICB9CiAgICBpZihUaGlzLT52aWV3ID09IEQzRE1hdEhhbmRsZSkKICAgIHsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1ZJRVcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFUUklYICopIEQzRE1hdHJpeCk7CiAgICB9CiAgICBpZihUaGlzLT5wcm9qID09IEQzRE1hdEhhbmRsZSkKICAgIHsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1BST0pFQ1RJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFUUklYICopIEQzRE1hdHJpeCk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OlNldE1hdHJpeAogKgogKiBSZXR1cm5zIHRoZSBjb250ZW50IG9mIGEgRDNETUFUUklYIGhhbmRsZQogKgogKiBWZXJzaW9uIDEgb25seQogKgogKiBQYXJhbXM6CiAqICBEM0RNYXRIYW5kbGU6IE1hdHJpeCBoYW5kbGUgdG8gcmVhZCB0aGUgY29udGVudCBmcm9tCiAqICBEM0RNYXRyaXg6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGNvbnRlbnQgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRE1hdEhhbmRsZSBpcyBpbnZhbGlkIG9yIEQzRE1hdHJpeCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9HZXRNYXRyaXgoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVhIQU5ETEUgRDNETWF0SGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEQzRE1hdEhhbmRsZSwgRDNETWF0cml4KTsKCiAgICBpZighRDNETWF0cml4KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgaWYoIUQzRE1hdEhhbmRsZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoRDNETWF0SGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBvdXQgb2YgcmFuZ2VcbiIsIEQzRE1hdEhhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KICAgIGVsc2UgaWYoVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX01hdHJpeCkKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBpcyBub3QgYSBtYXRyaXggaGFuZGxlXG4iLCBEM0RNYXRIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogVGhlIGhhbmRsZSBpcyBzaW1wbHkgYSBwb2ludGVyIHRvIGEgRDNETUFUUklYIHN0cnVjdHVyZSAqLwogICAgKkQzRE1hdHJpeCA9ICooKEQzRE1BVFJJWCAqKSBUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnB0cik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OkRlbGV0ZU1hdHJpeAogKgogKiBEZXN0cm95cyBhIE1hdHJpeCBoYW5kbGUuIEZyZWVzIHRoZSBtZW1vcnkgYW5kIHVuc2V0cyB0aGUgaGFuZGxlIGRhdGEKICoKICogVmVyc2lvbiAxIG9ubHkKICoKICogUGFyYW1zOgogKiAgRDNETWF0SGFuZGxlOiBIYW5kbGUgdG8gZGVzdHJveQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNETWF0SGFuZGxlIGlzIGludmFsaWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0RlbGV0ZU1hdHJpeChJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWEhBTkRMRSBEM0RNYXRIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglMDh4KVxuIiwgVGhpcywgRDNETWF0SGFuZGxlKTsKCiAgICBpZighRDNETWF0SGFuZGxlKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihEM0RNYXRIYW5kbGUgPiBUaGlzLT5udW1IYW5kbGVzKQogICAgewogICAgICAgIEVSUigiSGFuZGxlICVkIG91dCBvZiByYW5nZVxuIiwgRDNETWF0SGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQogICAgZWxzZSBpZihUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnR5cGUgIT0gRERyYXdIYW5kbGVfTWF0cml4KQogICAgewogICAgICAgIEVSUigiSGFuZGxlICVkIGlzIG5vdCBhIG1hdHJpeCBoYW5kbGVcbiIsIEQzRE1hdEhhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnB0cik7CiAgICBUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnB0ciA9IE5VTEw7CiAgICBUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9Vbmtub3duOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6QmVnaW5TY2VuZQogKgogKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYW55IHJlbmRlcmluZyBpcyBwZXJmb3JtZWQuCiAqIElEaXJlY3QzRERldmljZTo6RW5kU2NlbmUgaGFzIHRvIGJlIGNhbGxlZCBhZnRlciB0aGUgc2NlbmUgaXMgY29tcGxldGUKICoKICogVmVyc2lvbiAxLCAyLCAzIGFuZCA3CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcywgZm9yIGRldGFpbHMgc2VlIElXaW5lRDNERGV2aWNlOjpCZWdpblNjZW5lCiAqICBEM0RFUlJfU0NFTkVfSU5fU0NFTkUgaWYgV2luZUQzRCByZXR1cm5zIGFuIGVycm9yKE9ubHkgaW4gY2FzZSBvZiBhbiBhbHJlYWR5CiAqICBzdGFydGVkIHNjZW5lKS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfQmVnaW5TY2VuZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApOiBSZWxheVxuIiwgVGhpcyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQmVnaW5TY2VuZShUaGlzLT53aW5lRDNERGV2aWNlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihociA9PSBXSU5FRDNEX09LKSByZXR1cm4gRDNEX09LOwogICAgZWxzZSByZXR1cm4gRDNERVJSX1NDRU5FX0lOX1NDRU5FOyAvKiBUT0RPOiBPdGhlciBwb3NzaWJsZSBjYXVzZXMgb2YgZmFpbHVyZSAqLwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU2NlbmVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQmVnaW5TY2VuZShpZmFjZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQmVnaW5TY2VuZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU2NlbmUoaWZhY2UpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW5TY2VuZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0JlZ2luU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0JlZ2luU2NlbmUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19CZWdpblNjZW5lKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9CZWdpblNjZW5lKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0JlZ2luU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RW5kU2NlbmUKICoKICogRW5kcyBhIHNjZW5lIHRoYXQgaGFzIGJlZW4gYmVndW4gd2l0aCBJRGlyZWN0M0REZXZpY2U3OjpCZWdpblNjZW5lLgogKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBhZnRlciByZW5kZXJpbmcgaXMgZmluaXNoZWQuCiAqCiAqIFZlcnNpb24gMSwgMiwgMyBhbmQgNwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MsIGZvciBkZXRhaWxzIHNlZSBJV2luZUQzRERldmljZTo6RW5kU2NlbmUKICogIEQzREVSUl9TQ0VORV9OT1RfSU5fU0NFTkUgaXMgcmV0dXJuZWQgaWYgV2luZUQzRCByZXR1cm5zIGFuIGVycm9yLiBJdCBkb2VzCiAqICB0aGF0IG9ubHkgaWYgdGhlIHNjZW5lIHdhcyBhbHJlYWR5IGVuZGVkLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19FbmRTY2VuZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApOiBSZWxheVxuIiwgVGhpcyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRW5kU2NlbmUoVGhpcy0+d2luZUQzRERldmljZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSykgcmV0dXJuIEQzRF9PSzsKICAgIGVsc2UgcmV0dXJuIEQzREVSUl9TQ0VORV9OT1RfSU5fU0NFTkU7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmUoaWZhY2UpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0VuZFNjZW5lX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmUoaWZhY2UpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRW5kU2NlbmUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19FbmRTY2VuZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfRW5kU2NlbmUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19FbmRTY2VuZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfRW5kU2NlbmUoSURpcmVjdDNERGV2aWNlICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0RGlyZWN0M0QKICoKICogUmV0dXJucyB0aGUgSURpcmVjdDNEKD0gaW50ZXJmYWNlIHRvIHRoZSBEaXJlY3REcmF3IG9iamVjdCkgdXNlZCB0byBjcmVhdGUKICogdGhpcyBkZXZpY2UuCiAqCiAqIFBhcmFtczoKICogIERpcmVjdDNENzogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERpcmVjdDNENyA9PSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXREaXJlY3QzRChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRDcgKipEaXJlY3QzRDcpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBEaXJlY3QzRDcpOwoKICAgIGlmKCFEaXJlY3QzRDcpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgKkRpcmVjdDNENyA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0M0Q3KTsKICAgIElEaXJlY3QzRDdfQWRkUmVmKCpEaXJlY3QzRDcpOwoKICAgIFRSQUNFKCIgcmV0dXJuaW5nIGludGVyZmFjZSAlcFxuIiwgKkRpcmVjdDNENyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldERpcmVjdDNEKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEMyAqKkRpcmVjdDNEMykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSFJFU1VMVCByZXQ7CiAgICBJRGlyZWN0M0Q3ICpyZXRfcHRyOwoKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEaXJlY3QzRDMpOwogICAgcmV0ID0gSURpcmVjdDNERGV2aWNlN19HZXREaXJlY3QzRChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJldF9wdHIpOwogICAgaWYocmV0ICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gcmV0OwogICAgKkRpcmVjdDNEMyA9IENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3QzRDcsIElEaXJlY3QzRDMsIHJldF9wdHIpOwogICAgVFJBQ0UoIiByZXR1cm5pbmcgaW50ZXJmYWNlICVwXG4iLCAqRGlyZWN0M0QzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0RGlyZWN0M0QoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0QyICoqRGlyZWN0M0QyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBIUkVTVUxUIHJldDsKICAgIElEaXJlY3QzRDcgKnJldF9wdHI7CgogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIERpcmVjdDNEMik7CiAgICByZXQgPSBJRGlyZWN0M0REZXZpY2U3X0dldERpcmVjdDNEKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV0X3B0cik7CiAgICBpZihyZXQgIT0gRDNEX09LKQogICAgICAgIHJldHVybiByZXQ7CiAgICAqRGlyZWN0M0QyID0gQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdDNENywgSURpcmVjdDNEMiwgcmV0X3B0cik7CiAgICBUUkFDRSgiIHJldHVybmluZyBpbnRlcmZhY2UgJXBcbiIsICpEaXJlY3QzRDIpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9HZXREaXJlY3QzRChJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEICoqRGlyZWN0M0QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSFJFU1VMVCByZXQ7CiAgICBJRGlyZWN0M0Q3ICpyZXRfcHRyOwoKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEaXJlY3QzRCk7CiAgICByZXQgPSBJRGlyZWN0M0REZXZpY2U3X0dldERpcmVjdDNEKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV0X3B0cik7CiAgICBpZihyZXQgIT0gRDNEX09LKQogICAgICAgIHJldHVybiByZXQ7CiAgICAqRGlyZWN0M0QgPSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0M0Q3LCBJRGlyZWN0M0QsIHJldF9wdHIpOwogICAgVFJBQ0UoIiByZXR1cm5pbmcgaW50ZXJmYWNlICVwXG4iLCAqRGlyZWN0M0QpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OlNldEN1cnJlbnRWaWV3cG9ydAogKgogKiBTZXRzIGEgRGlyZWN0M0RWaWV3cG9ydCBhcyB0aGUgY3VycmVudCB2aWV3cG9ydC4KICogRm9yIHRoZSB0aHVua3Mgbm90ZSB0aGF0IGFsbCB2aWV3cG9ydCBpbnRlcmZhY2UgdmVyc2lvbnMgYXJlIGVxdWFsCiAqCiAqIFBhcmFtczoKICogIERpcmVjdDNEVmlld3BvcnQzOiBUaGUgdmlld3BvcnQgdG8gc2V0CiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIChJcyBhIE5VTEwgdmlld3BvcnQgdmFsaWQ/KQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqRGlyZWN0M0RWaWV3cG9ydDMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydDMpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIERpcmVjdDNEVmlld3BvcnQzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogRG8gbm90aGluZyBpZiB0aGUgc3BlY2lmaWVkIHZpZXdwb3J0IGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IG9uZSAqLwogICAgaWYgKFRoaXMtPmN1cnJlbnRfdmlld3BvcnQgPT0gdnAgKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzRF9PSzsKICAgIH0KCiAgICAvKiBTaG91bGQgY2hlY2sgaWYgdGhlIHZpZXdwb3J0IHdhcyBhZGRlZCBvciBub3QgKi8KCiAgICAvKiBSZWxlYXNlIHByZXZpb3VzIHZpZXdwb3J0IGFuZCBBZGRSZWYgdGhlIG5ldyBvbmUgKi8KICAgIGlmIChUaGlzLT5jdXJyZW50X3ZpZXdwb3J0KQogICAgewogICAgICAgIFRSQUNFKCJWaWV3cG9ydEltcGwgaXMgYXQgJXAsIGludGVyZmFjZSBpcyBhdCAlcFxuIiwgVGhpcy0+Y3VycmVudF92aWV3cG9ydCwgSUNPTV9JTlRFUkZBQ0UoVGhpcy0+Y3VycmVudF92aWV3cG9ydCwgSURpcmVjdDNEVmlld3BvcnQzKSk7CiAgICAgICAgSURpcmVjdDNEVmlld3BvcnQzX1JlbGVhc2UoIElDT01fSU5URVJGQUNFKFRoaXMtPmN1cnJlbnRfdmlld3BvcnQsIElEaXJlY3QzRFZpZXdwb3J0MykgKTsKICAgIH0KICAgIElEaXJlY3QzRFZpZXdwb3J0M19BZGRSZWYoRGlyZWN0M0RWaWV3cG9ydDMpOwoKICAgIC8qIFNldCB0aGlzIHZpZXdwb3J0IGFzIHRoZSBjdXJyZW50IHZpZXdwb3J0ICovCiAgICBUaGlzLT5jdXJyZW50X3ZpZXdwb3J0ID0gdnA7CgogICAgLyogQWN0aXZhdGUgdGhpcyB2aWV3cG9ydCAqLwogICAgVGhpcy0+Y3VycmVudF92aWV3cG9ydC0+YWN0aXZlX2RldmljZSA9IFRoaXM7CiAgICBUaGlzLT5jdXJyZW50X3ZpZXdwb3J0LT5hY3RpdmF0ZShUaGlzLT5jdXJyZW50X3ZpZXdwb3J0LCBGQUxTRSk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqRGlyZWN0M0RWaWV3cG9ydDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX1NldEN1cnJlbnRWaWV3cG9ydChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpHZXRDdXJyZW50Vmlld3BvcnQKICoKICogUmV0dXJucyB0aGUgY3VycmVudGx5IGFjdGl2ZSB2aWV3cG9ydC4KICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIERpcmVjdDNEVmlld3BvcnQzOiBBZGRyZXNzIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERpcmVjdDNEVmlld3BvcnQgPT0gTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqKkRpcmVjdDNEVmlld3BvcnQzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRGlyZWN0M0RWaWV3cG9ydDMpOwoKICAgIGlmKCFEaXJlY3QzRFZpZXdwb3J0MykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgKkRpcmVjdDNEVmlld3BvcnQzID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+Y3VycmVudF92aWV3cG9ydCwgSURpcmVjdDNEVmlld3BvcnQzKTsKCiAgICAvKiBBZGRSZWYgdGhlIHJldHVybmVkIHZpZXdwb3J0ICovCiAgICBpZigqRGlyZWN0M0RWaWV3cG9ydDMpIElEaXJlY3QzRFZpZXdwb3J0M19BZGRSZWYoKkRpcmVjdDNEVmlld3BvcnQzKTsKCiAgICBUUkFDRSgiIHJldHVybmluZyBpbnRlcmZhY2UgJXBcbiIsICpEaXJlY3QzRFZpZXdwb3J0Myk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqKkRpcmVjdDNEVmlld3BvcnQyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIERpcmVjdDNEVmlld3BvcnQyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlM19HZXRDdXJyZW50Vmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElEaXJlY3QzRFZpZXdwb3J0MyAqKikgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgaWYoaHIgIT0gRDNEX09LKSByZXR1cm4gaHI7CiAgICAqRGlyZWN0M0RWaWV3cG9ydDIgPSAoSURpcmVjdDNEVmlld3BvcnQyICopIENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgSURpcmVjdDNEVmlld3BvcnQzLCAqRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldFJlbmRlclRhcmdldAogKgogKiBTZXRzIHRoZSByZW5kZXIgdGFyZ2V0IGZvciB0aGUgRGlyZWN0M0REZXZpY2UuCiAqIEZvciB0aGUgdGh1bmtzIG5vdGUgdGhhdCBJRGlyZWN0RHJhd1N1cmZhY2U3ID09IElEaXJlY3REcmF3U3VyZmFjZTQgYW5kCiAqIElEaXJlY3REcmF3U3VyZmFjZTMgPT0gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBOZXdUYXJnZXQ6IFBvaW50ZXIgdG8gYW4gSURpcmVjdERyYXdTdXJmYWNlNyBpbnRlcmZhY2UgdG8gc2V0IGFzIHRoZSBuZXcKICogICAgICAgICAgICAgcmVuZGVyIHRhcmdldAogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzLCBmb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFJlbmRlclRhcmdldAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19TZXRSZW5kZXJUYXJnZXQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqTmV3VGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUYXJnZXQgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBOZXdUYXJnZXQpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJTA4eCk6IFJlbGF5XG4iLCBUaGlzLCBOZXdUYXJnZXQsIEZsYWdzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogRmxhZ3M6IE5vdCB1c2VkICovCgogICAgaWYoVGhpcy0+dGFyZ2V0ID09IFRhcmdldCkKICAgIHsKICAgICAgICBUUkFDRSgiTm8tb3AgU2V0UmVuZGVyVGFyZ2V0IG9wZXJhdGlvbiwgbm90IGRvaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RfT0s7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRSZW5kZXJUYXJnZXQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYXJnZXQgPyBUYXJnZXQtPldpbmVEM0RTdXJmYWNlIDogTlVMTCk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihOZXdUYXJnZXQpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMtPnRhcmdldCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgVGhpcy0+dGFyZ2V0ID0gVGFyZ2V0OwogICAgSURpcmVjdDNERGV2aWNlSW1wbF9VcGRhdGVEZXB0aFN0ZW5jaWwoVGhpcyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRSZW5kZXJUYXJnZXRfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqTmV3VGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclRhcmdldChpZmFjZSwgTmV3VGFyZ2V0LCBGbGFncyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyVGFyZ2V0X0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKk5ld1RhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclRhcmdldChpZmFjZSwgTmV3VGFyZ2V0LCBGbGFncyk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRSZW5kZXJUYXJnZXQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNCAqTmV3UmVuZGVyVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUYXJnZXQgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBOZXdSZW5kZXJUYXJnZXQpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwLCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVGFyZ2V0LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJUYXJnZXQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UoVGFyZ2V0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0UmVuZGVyVGFyZ2V0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZSAqTmV3UmVuZGVyVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUYXJnZXQgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2UzLCBOZXdSZW5kZXJUYXJnZXQpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwLCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVGFyZ2V0LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJUYXJnZXQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UoVGFyZ2V0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRSZW5kZXJUYXJnZXQKICoKICogUmV0dXJucyB0aGUgY3VycmVudCByZW5kZXIgdGFyZ2V0LgogKiBUaGlzIGlzIGhhbmRsZWQgbG9jYWxseSwgYmVjYXVzZSB0aGUgV2luZUQzRCByZW5kZXIgdGFyZ2V0J3MgcGFyZW50CiAqIGlzIGFuIElQYXJlbnQKICoKICogVmVyc2lvbiAyLCAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFJlbmRlclRhcmdldDogQWRkcmVzcyB0byBzdG9yZSB0aGUgc3VyZmFjZSBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgUmVuZGVyVGFyZ2V0ID09IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclRhcmdldChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqUmVuZGVyVGFyZ2V0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIFJlbmRlclRhcmdldCk7CgogICAgaWYoIVJlbmRlclRhcmdldCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgKlJlbmRlclRhcmdldCA9IElDT01fSU5URVJGQUNFKFRoaXMtPnRhcmdldCwgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZigqUmVuZGVyVGFyZ2V0KTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRSZW5kZXJUYXJnZXQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNCAqKlJlbmRlclRhcmdldCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXQpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0dldFJlbmRlclRhcmdldChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElEaXJlY3REcmF3U3VyZmFjZTcgKiopIFJlbmRlclRhcmdldCk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKICAgICpSZW5kZXJUYXJnZXQgPSAoSURpcmVjdERyYXdTdXJmYWNlNCAqKSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgSURpcmVjdERyYXdTdXJmYWNlNywgKlJlbmRlclRhcmdldCk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFJlbmRlclRhcmdldChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2UgKipSZW5kZXJUYXJnZXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUmVuZGVyVGFyZ2V0KTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19HZXRSZW5kZXJUYXJnZXQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJRGlyZWN0RHJhd1N1cmZhY2U3ICoqKSBSZW5kZXJUYXJnZXQpOwogICAgaWYoaHIgIT0gRDNEX09LKSByZXR1cm4gaHI7CiAgICAqUmVuZGVyVGFyZ2V0ID0gKElEaXJlY3REcmF3U3VyZmFjZSAqKSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgSURpcmVjdERyYXdTdXJmYWNlMywgKlJlbmRlclRhcmdldCk7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6QmVnaW4KICoKICogQmVnaW5zIGEgZGVzY3JpcHRpb24gYmxvY2sgb2YgdmVydGljZXMuIFRoaXMgaXMgc2ltaWxhciB0byBnbEJlZ2luKCkKICogYW5kIGdsRW5kKCkuIEFmdGVyIGEgY2FsbCB0byBJRGlyZWN0M0REZXZpY2UzOjpFbmQsIHRoZSB2ZXJ0aWNlcwogKiBkZXNjcmliZWQgd2l0aCBJRGlyZWN0M0REZXZpY2U6OlZlcnRleCBhcmUgZHJhd24uCiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBQYXJhbXM6CiAqICBQcmltaXRpdmVUeXBlOiBUaGUgdHlwZSBvZiBwcmltaXRpdmVzIHRvIGRyYXcKICogIFZlcnRleFR5cGVEZXNjOiBBIGZsZXhpYmxlIHZlcnRleCBmb3JtYXQgZGVzY3JpcHRpb24gb2YgdGhlIHZlcnRpY2VzCiAqICBGbGFnczogU29tZSBmbGFncy4uCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW4oSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlRGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVkLCVkLCUwOHgpXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlRGVzYywgRmxhZ3MpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBUaGlzLT5wcmltaXRpdmVfdHlwZSA9IFByaW1pdGl2ZVR5cGU7CiAgICBUaGlzLT52ZXJ0ZXhfdHlwZSA9IFZlcnRleFR5cGVEZXNjOwogICAgVGhpcy0+cmVuZGVyX2ZsYWdzID0gRmxhZ3M7CiAgICBUaGlzLT52ZXJ0ZXhfc2l6ZSA9IGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShUaGlzLT52ZXJ0ZXhfdHlwZSk7CiAgICBUaGlzLT5uYl92ZXJ0aWNlcyA9IDA7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQmVnaW4oSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIGQzZHB0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkVSVEVYVFlQRSBkd1ZlcnRleFR5cGVEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncykKewogICAgRFdPUkQgRlZGOwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwLyVwKS0+KCUwOHgsJTA4eCwlMDh4KTogVGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlM1xuIiwgVGhpcywgaWZhY2UsIGQzZHB0LCBkd1ZlcnRleFR5cGVEZXNjLCBkd0ZsYWdzKTsKCiAgICBzd2l0Y2goZHdWZXJ0ZXhUeXBlRGVzYykKICAgIHsKICAgICAgICBjYXNlIEQzRFZUX1ZFUlRFWDogRlZGID0gRDNERlZGX1ZFUlRFWDsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RWVF9MVkVSVEVYOiBGVkYgPSBEM0RGVkZfTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RWVF9UTFZFUlRFWDogRlZGID0gRDNERlZGX1RMVkVSVEVYOyBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgdmVydGV4IHR5cGUgJWRcbiIsIGR3VmVydGV4VHlwZURlc2MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsgIC8qIFNob3VsZCBuZXZlciBoYXBwZW4gKi8KICAgIH07CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfQmVnaW4oSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkM2RwdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZWRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6QmVnaW5JbmRleGVkCiAqCiAqIERyYXdzIHByaW1pdGl2ZXMgYmFzZWQgb24gdmVydGljZXMgaW4gYSB2ZXJ0ZXggYXJyYXkgd2hpY2ggYXJlIHNwZWNpZmllZAogKiBieSBpbmRpY2VzLgogKgogKiBWZXJzaW9uIDIgYW5kIDMKICoKICogUGFyYW1zOgogKiAgUHJpbWl0aXZlVHlwZTogUHJpbWl0aXZlIHR5cGUgdG8gZHJhdwogKiAgVmVydGV4VHlwZTogQSBGVkYgZGVzY3JpcHRpb24gb2YgdGhlIHZlcnRleCBmb3JtYXQKICogIFZlcnRpY2VzOiBwb2ludGVyIHRvIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHZlcnRpY2VzCiAqICBOdW1WZXJ0aWNlczogVGhlIG51bWJlciBvZiB2ZXJ0aWNlcyBpbiB0aGUgdmVydGV4IGFycmF5CiAqICBGbGFnczogU29tZSBmbGFncyAuLi4KICoKICogUmV0dXJuczoKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW5JbmRleGVkKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpOiBzdHViIVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIE51bVZlcnRpY2VzLCBGbGFncyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9CZWdpbkluZGV4ZWQoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBkM2RwdFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkVSVEVYVFlQRSBkM2R2dFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqbHB2VmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzKQp7CiAgICBEV09SRCBGVkY7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXAvJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJTA4eCk6IFRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTNcbiIsIFRoaXMsIGlmYWNlLCBkM2RwdFByaW1pdGl2ZVR5cGUsIGQzZHZ0VmVydGV4VHlwZSwgbHB2VmVydGljZXMsIGR3TnVtVmVydGljZXMsIGR3RmxhZ3MpOwoKICAgIHN3aXRjaChkM2R2dFZlcnRleFR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RWVF9WRVJURVg6IEZWRiA9IEQzREZWRl9WRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfTFZFUlRFWDogRlZGID0gRDNERlZGX0xWRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfVExWRVJURVg6IEZWRiA9IEQzREZWRl9UTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCB0eXBlICVkXG4iLCBkM2R2dFZlcnRleFR5cGUpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsgIC8qIFNob3VsZCBuZXZlciBoYXBwZW4gKi8KICAgIH07CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfQmVnaW5JbmRleGVkKElDT01fSU5URVJGQUNFKFRoaXMsSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZDNkcHRQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZWRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscHZWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd051bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6VmVydGV4CiAqCiAqIERyYXdzIGEgdmVydGV4IGFzIGRlc2NyaWJlZCBieSBJRGlyZWN0M0REZXZpY2UzOjpCZWdpbi4gSXQgcGxhY2VzIGFsbAogKiBkcmF3biB2ZXJ0aWNlcyBpbiBhIHZlcnRleCBidWZmZXIuIElmIHRoZSBidWZmZXIgaXMgdG9vIHNtYWxsLCBpdHMKICogc2l6ZSBpcyBpbmNyZWFzZWQuCiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBQYXJhbXM6CiAqICBWZXJ0ZXg6IFBvaW50ZXIgdG8gdGhlIHZlcnRleAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LLCBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZlcnRleCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19WZXJ0ZXgoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGV4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgVmVydGV4KTsKCiAgICBpZighVmVydGV4KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoKFRoaXMtPm5iX3ZlcnRpY2VzKzEpKlRoaXMtPnZlcnRleF9zaXplID4gVGhpcy0+YnVmZmVyX3NpemUpCiAgICB7CiAgICAgICAgQllURSAqb2xkX2J1ZmZlcjsKICAgICAgICBUaGlzLT5idWZmZXJfc2l6ZSA9IFRoaXMtPmJ1ZmZlcl9zaXplID8gVGhpcy0+YnVmZmVyX3NpemUgKiAyIDogVGhpcy0+dmVydGV4X3NpemUgKiAzOwogICAgICAgIG9sZF9idWZmZXIgPSBUaGlzLT52ZXJ0ZXhfYnVmZmVyOwogICAgICAgIFRoaXMtPnZlcnRleF9idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YnVmZmVyX3NpemUpOwogICAgICAgIGlmIChvbGRfYnVmZmVyKQogICAgICAgIHsKICAgICAgICAgICAgQ29weU1lbW9yeShUaGlzLT52ZXJ0ZXhfYnVmZmVyLCBvbGRfYnVmZmVyLCBUaGlzLT5uYl92ZXJ0aWNlcyAqIFRoaXMtPnZlcnRleF9zaXplKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2xkX2J1ZmZlcik7CiAgICAgICAgfQogICAgfQoKICAgIENvcHlNZW1vcnkoVGhpcy0+dmVydGV4X2J1ZmZlciArIFRoaXMtPm5iX3ZlcnRpY2VzKysgKiBUaGlzLT52ZXJ0ZXhfc2l6ZSwgVmVydGV4LCBUaGlzLT52ZXJ0ZXhfc2l6ZSk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfVmVydGV4KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmxwVmVydGV4VHlwZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIGxwVmVydGV4VHlwZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19WZXJ0ZXgoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBWZXJ0ZXhUeXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkluZGV4CiAqCiAqIFNwZWNpZmllcyBhbiBpbmRleCB0byBhIHZlcnRleCB0byBiZSBkcmF3bi4gVGhlIHZlcnRleCBhcnJheSBoYXMgdG8KICogYmUgc3BlY2lmaWVkIHdpdGggQmVnaW5JbmRleGVkIGZpcnN0LgogKgogKiBQYXJhbWV0ZXJzOgogKiAgVmVydGV4SW5kZXg6IFRoZSBpbmRleCBvZiB0aGUgdmVydGV4IHRvIGRyYXcKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19JbmRleChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgVmVydGV4SW5kZXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJTA0eCk6IHN0dWIhXG4iLCBUaGlzLCBWZXJ0ZXhJbmRleCk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0luZGV4KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCB3VmVydGV4SW5kZXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDR4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHdWZXJ0ZXhJbmRleCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19JbmRleChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdWZXJ0ZXhJbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpFbmQKICoKICogRW5kcyBhIGRyYXcgYmVndW4gd2l0aCBJRGlyZWN0M0REZXZpY2UzOjpCZWdpbiBvcgogKiBJRGlyZWN0M0REZXZpY2U6OkJlZ2luSW5kZXhlZC4gVGhlIHZlcnRpY2VzIHNwZWNpZmllZCB3aXRoCiAqIElEaXJlY3QzRERldmljZTo6VmVydGV4IG9yIElEaXJlY3QzRERldmljZTo6SW5kZXggYXJlIGRyYXduIHVzaW5nCiAqIHRoZSBJRGlyZWN0M0REZXZpY2U3OjpEcmF3UHJpbWl0aXZlIG1ldGhvZC4gU28gZmFyIG9ubHkKICogbm9uLWluZGV4ZWQgbW9kZSBpcyBzdXBwb3J0ZWQKICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBTb21lIGZsYWdzLCBhcyB1c3VhbC4gRG9uJ3Qga25vdyB3aGljaCBhcmUgZGVmaW5lZAogKgogKiBSZXR1cm5zOgogKiAgVGhlIHJldHVybiB2YWx1ZSBvZiBJRGlyZWN0M0REZXZpY2U3OjpEcmF3UHJpbWl0aXZlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19FbmQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsIFRoaXMsIEZsYWdzKTsKCiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wcmltaXRpdmVfdHlwZSwgVGhpcy0+dmVydGV4X3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnZlcnRleF9idWZmZXIsIFRoaXMtPm5iX3ZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZW5kZXJfZmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0VuZChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkd0ZsYWdzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0VuZChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldFJlbmRlclN0YXRlCiAqCiAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgcmVuZGVyIHN0YXRlLiBUaGUgcG9zc2libGUgcmVuZGVyIHN0YXRlcyBhcmUKICogZGVmaW5lZCBpbiBpbmNsdWRlL2QzZHR5cGVzLmgKICoKICogVmVyc2lvbiAyLCAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFJlbmRlclN0YXRlVHlwZTogUmVuZGVyIHN0YXRlIHRvIHJldHVybiB0aGUgY3VycmVudCBzZXR0aW5nIG9mCiAqICBWYWx1ZTogQWRkcmVzcyB0byBzdG9yZSB0aGUgdmFsdWUgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzLCBmb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OkdldFJlbmRlclN0YXRlCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZhbHVlID09IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0UmVuZGVyU3RhdGUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRU5ERVJTVEFURVRZUEUgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXlcbiIsIFRoaXMsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwoKICAgIGlmKCFWYWx1ZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKFJlbmRlclN0YXRlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVNQUc6CiAgICAgICAgewogICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgdGV4X21hZzsKCiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFdJTkVEM0RTQU1QX01BR0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRleF9tYWcpOwoKICAgICAgICAgICAgc3dpdGNoICh0ZXhfbWFnKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX1BPSU5UOgogICAgICAgICAgICAgICAgICAgICpWYWx1ZSA9IEQzREZJTFRFUl9ORUFSRVNUOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9MSU5FQVI6CiAgICAgICAgICAgICAgICAgICAgKlZhbHVlID0gRDNERklMVEVSX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmhhbmRsZWQgdGV4dHVyZSBtYWcgJWQgIVxuIix0ZXhfbWFnKTsKICAgICAgICAgICAgICAgICAgICAqVmFsdWUgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RSRU5ERVJTVEFURV9URVhUVVJFTUlOOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHRleF9taW47CgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9NSU5GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0ZXhfbWluKTsKCiAgICAgICAgICAgIHN3aXRjaCAodGV4X21pbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9QT0lOVDoKICAgICAgICAgICAgICAgICAgICAqVmFsdWUgPSBEM0RGSUxURVJfTkVBUkVTVDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfTElORUFSOgogICAgICAgICAgICAgICAgICAgICpWYWx1ZSA9IEQzREZJTFRFUl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5oYW5kbGVkIHRleHR1cmUgbWFnICVkICFcbiIsdGV4X21pbik7CiAgICAgICAgICAgICAgICAgICAgKlZhbHVlID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1M6CiAgICAgICAgY2FzZSBEM0RSRU5ERVJTVEFURV9URVhUVVJFQUREUkVTU1U6CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFdJTkVEM0RTQU1QX0FERFJFU1NVLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1NWOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTViwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogRklYTUU6IFVuaGFuZGxlZDogRDNEUkVOREVSU1RBVEVfU1RJUFBMRVBBVFRFUk4wMCAtIDMxICovCiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0UmVuZGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRSZW5kZXJTdGF0ZV9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFTkRFUlNUQVRFVFlQRSBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqVmFsdWUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0UmVuZGVyU3RhdGUoaWZhY2UsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclN0YXRlX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIFJlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpWYWx1ZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclN0YXRlKGlmYWNlLCBSZW5kZXJTdGF0ZVR5cGUsIFZhbHVlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFJlbmRlclN0YXRlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIGR3UmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKmxwZHdSZW5kZXJTdGF0ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIGR3UmVuZGVyU3RhdGVUeXBlLCBscGR3UmVuZGVyU3RhdGUpOwoKICAgIHN3aXRjaChkd1JlbmRlclN0YXRlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVIQU5ETEU6CiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIHN0YXRlIGlzIHdyYXBwZWQgdG8gU2V0VGV4dHVyZSBpbiBTZXRSZW5kZXJTdGF0ZSwgc28KICAgICAgICAgICAgICogaXQgaGFzIHRvIGJlIHdyYXBwZWQgdG8gR2V0VGV4dHVyZSBoZXJlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlICp0ZXggPSBOVUxMOwogICAgICAgICAgICAqbHBkd1JlbmRlclN0YXRlID0gMDsKCiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGV4KTsKCiAgICAgICAgICAgIGlmKGhyID09IFdJTkVEM0RfT0sgJiYgdGV4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpwYXJlbnQgPSBOVUxMOwogICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFBhcmVudCh0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJnBhcmVudCk7CiAgICAgICAgICAgICAgICBpZihwYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhlIHBhcmVudCBvZiB0aGUgdGV4dHVyZSBpcyB0aGUgSURpcmVjdERyYXdTdXJmYWNlNyBpbnRlcmZhY2UKICAgICAgICAgICAgICAgICAgICAgKiBvZiB0aGUgZGRyYXcgc3VyZmFjZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnRleEltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQpOwogICAgICAgICAgICAgICAgICAgICpscGR3UmVuZGVyU3RhdGUgPSB0ZXhJbXBsLT5IYW5kbGU7CiAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHBhcmVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UodGV4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BUEJMRU5EOgogICAgICAgIHsKICAgICAgICAgICAgLyogRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BUEJMRU5EIGlzIG1hcHBlZCB0byB0ZXh0dXJlIHN0YXRlIHN0YWdlcyBpbiBTZXRSZW5kZXJTdGF0ZTsgcmV2ZXJzZQogICAgICAgICAgICAgICB0aGUgbWFwcGluZyB0byBnZXQgdGhlIHZhbHVlLiAqLwogICAgICAgICAgICBEV09SRCBjb2xvcm9wLCBjb2xvcmFyZzEsIGNvbG9yYXJnMjsKICAgICAgICAgICAgRFdPUkQgYWxwaGFvcCwgYWxwaGFhcmcxLCBhbHBoYWFyZzI7CgogICAgICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgICAgICAgICAgVGhpcy0+bGVnYWN5VGV4dHVyZUJsZW5kaW5nID0gVFJVRTsKCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0dldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JPUCwgJmNvbG9yb3ApOwogICAgICAgICAgICBJV2luZUQzRERldmljZV9HZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9SQVJHMSwgJmNvbG9yYXJnMSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0dldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcyLCAmY29sb3JhcmcyKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQU9QLCAmYWxwaGFvcCk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0dldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFBUkcxLCAmYWxwaGFhcmcxKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzIsICZhbHBoYWFyZzIpOwoKICAgICAgICAgICAgaWYgKGNvbG9yb3AgPT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcxICYmIGNvbG9yYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSAmJgogICAgICAgICAgICAgICAgYWxwaGFvcCA9PSBXSU5FRDNEVE9QX1NFTEVDVEFSRzEgJiYgYWxwaGFhcmcxID09IFdJTkVEM0RUQV9URVhUVVJFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAqbHBkd1JlbmRlclN0YXRlID0gRDNEVEJMRU5EX0RFQ0FMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGNvbG9yb3AgPT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcxICYmIGNvbG9yYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSAmJgogICAgICAgICAgICAgICAgYWxwaGFvcCA9PSBXSU5FRDNEVE9QX01PRFVMQVRFICYmIGFscGhhYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSAmJiBhbHBoYWFyZzIgPT0gV0lORUQzRFRBX0NVUlJFTlQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpscGR3UmVuZGVyU3RhdGUgPSBEM0RUQkxFTkRfREVDQUxBTFBIQTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjb2xvcm9wID09IFdJTkVEM0RUT1BfTU9EVUxBVEUgJiYgY29sb3JhcmcxID09IFdJTkVEM0RUQV9URVhUVVJFICYmIGNvbG9yYXJnMiA9PSBXSU5FRDNEVEFfQ1VSUkVOVCAmJgogICAgICAgICAgICAgICAgYWxwaGFvcCA9PSBXSU5FRDNEVE9QX01PRFVMQVRFICYmIGFscGhhYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSAmJiBhbHBoYWFyZzIgPT0gV0lORUQzRFRBX0NVUlJFTlQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpscGR3UmVuZGVyU3RhdGUgPSBEM0RUQkxFTkRfTU9EVUxBVEVBTFBIQTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhSRVNVTFQgaHI7CiAgICAgICAgICAgICAgICBCT09MIHRleF9hbHBoYSA9IEZBTFNFOwogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqdGV4ID0gTlVMTDsKICAgICAgICAgICAgICAgIFdJTkVEM0RTVVJGQUNFX0RFU0MgZGVzYzsKICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgZm10OwogICAgICAgICAgICAgICAgRERQSVhFTEZPUk1BVCBkZGZtdDsKCiAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0ZXgpOwoKICAgICAgICAgICAgICAgIGlmKGhyID09IFdJTkVEM0RfT0sgJiYgdGV4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1lbXNldCgmZGVzYywgMCwgc2l6ZW9mKGRlc2MpKTsKICAgICAgICAgICAgICAgICAgICBkZXNjLkZvcm1hdCA9ICZmbXQ7CiAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzRFRleHR1cmVfR2V0TGV2ZWxEZXNjKChJV2luZUQzRFRleHR1cmUqKSB0ZXgsIDAsICZkZXNjKTsKICAgICAgICAgICAgICAgICAgICBpZiAoU1VDQ0VFREVEKGhyKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRkZm10LmR3U2l6ZSA9IHNpemVvZihkZGZtdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZGZtdCwgZm10KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRkZm10LnU1LmR3UkdCQWxwaGFCaXRNYXNrKSB0ZXhfYWxwaGEgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHRleCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEoY29sb3JvcCA9PSBXSU5FRDNEVE9QX01PRFVMQVRFICYmIGNvbG9yYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSAmJiBjb2xvcmFyZzIgPT0gV0lORUQzRFRBX0NVUlJFTlQgJiYKICAgICAgICAgICAgICAgICAgICAgIGFscGhhb3AgPT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcxICYmIGFscGhhYXJnMSA9PSAodGV4X2FscGhhID8gV0lORUQzRFRBX1RFWFRVUkUgOiBXSU5FRDNEVEFfQ1VSUkVOVCkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB0ZXh0dXJlIHN0YWdlIHN0YXRlIHNldHVwLCByZXR1cm5pbmcgRDNEVEJMRU5EX01PRFVMQVRFIC0gbGlrZWx5IGVycm9uZW91c1xuIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgKmxwZHdSZW5kZXJTdGF0ZSA9IEQzRFRCTEVORF9NT0RVTEFURTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAgICAgICAgIHJldHVybiBEM0RfT0s7CiAgICAgICAgfQoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19HZXRSZW5kZXJTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3UmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1JlbmRlclN0YXRlKTsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRSZW5kZXJTdGF0ZShJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFTkRFUlNUQVRFVFlQRSBkd1JlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpscGR3UmVuZGVyU3RhdGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIGR3UmVuZGVyU3RhdGVUeXBlLCBscGR3UmVuZGVyU3RhdGUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfR2V0UmVuZGVyU3RhdGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd1JlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwZHdSZW5kZXJTdGF0ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpTZXRSZW5kZXJTdGF0ZQogKgogKiBTZXRzIGEgcmVuZGVyIHN0YXRlLiBUaGUgcG9zc2libGUgcmVuZGVyIHN0YXRlcyBhcmUgZGVmaW5lZCBpbgogKiBpbmNsdWRlL2QzZHR5cGVzLmgKICoKICogVmVyc2lvbiAyLCAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFJlbmRlclN0YXRlVHlwZTogU3RhdGUgdG8gc2V0CiAqICBWYWx1ZTogVmFsdWUgdG8gYXNzaWduIHRvIHRoYXQgc3RhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzLAogKiAgZm9yIGRldGFpbHMgc2VlIElXaW5lRDNERGV2aWNlOjpTZXRSZW5kZXJTdGF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19TZXRSZW5kZXJTdGF0ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFTkRFUlNUQVRFVFlQRSBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlZCk6IFJlbGF5XG4iLCBUaGlzLCBSZW5kZXJTdGF0ZVR5cGUsIFZhbHVlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogU29tZSByZW5kZXIgc3RhdGVzIG5lZWQgc3BlY2lhbCBjYXJlICovCiAgICBzd2l0Y2goUmVuZGVyU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BRzoKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSB0ZXhfbWFnID0gV0lORUQzRFRFWEZfTk9ORTsKCiAgICAgICAgICAgIHN3aXRjaCAoKEQzRFRFWFRVUkVGSUxURVIpIFZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9ORUFSRVNUOgogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTElORUFSTUlQTkVBUkVTVDoKICAgICAgICAgICAgICAgICAgICB0ZXhfbWFnID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVI6CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVJNSVBMSU5FQVI6CiAgICAgICAgICAgICAgICAgICAgdGV4X21hZyA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmhhbmRsZWQgdGV4dHVyZSBtYWcgJWQgIVxuIixWYWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFdJTkVEM0RTQU1QX01BR0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4X21hZyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RSRU5ERVJTVEFURV9URVhUVVJFTUlOOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHRleF9taW4gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgdGV4X21pcCA9IFdJTkVEM0RURVhGX05PTkU7CgogICAgICAgICAgICBzd2l0Y2ggKChEM0RURVhUVVJFRklMVEVSKSBWYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTkVBUkVTVDoKICAgICAgICAgICAgICAgICAgICB0ZXhfbWluID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVI6CiAgICAgICAgICAgICAgICAgICAgdGV4X21pbiA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNERklMVEVSX01JUE5FQVJFU1Q6CiAgICAgICAgICAgICAgICAgICAgdGV4X21pbiA9IFdJTkVEM0RURVhGX05PTkU7CiAgICAgICAgICAgICAgICAgICAgdGV4X21pcCA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTUlQTElORUFSOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICAgICAgICAgIHRleF9taXAgPSBXSU5FRDNEVEVYRl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVJNSVBORUFSRVNUOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgICAgICAgICB0ZXhfbWlwID0gV0lORUQzRFRFWEZfTElORUFSOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTElORUFSTUlQTElORUFSOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgdGV4X21pcCA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5oYW5kbGVkIHRleHR1cmUgbWluICVkICFcbiIsVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfTUlQRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9taXApOwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9NSU5GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9taW4pOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1M6CiAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTViwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSk7CiAgICAgICAgICAgIC8qIERyb3AgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1NVOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTVSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVBRERSRVNTVjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CgogICAgICAgICAgICAvKiBGSVhNRTogVW5oYW5kbGVkOiBEM0RSRU5ERVJTVEFURV9TVElQUExFUEFUVEVSTjAwIC0gMzEgKi8KCiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0UmVuZGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyU3RhdGVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRU5ERVJTVEFURVRZUEUgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmFsdWUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyU3RhdGUoaWZhY2UsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclN0YXRlX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIFJlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZhbHVlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyU3RhdGUoaWZhY2UsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0UmVuZGVyU3RhdGUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRU5ERVJTVEFURVRZUEUgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmFsdWUpCnsKICAgIC8qIE5vdGUgYWJvdXQgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BUEJMRU5EIGltcGxlbWVudGF0aW9uOiBtb3N0IG9mIHZhbHVlcwogICAgZm9yIHRoaXMgc3RhdGUgY2FuIGJlIGRpcmVjdGx5IG1hcHBlZCB0byB0ZXh0dXJlIHN0YWdlIGNvbG9yb3AgYW5kIGFscGhhb3AsIGJ1dAogICAgRDNEVEJMRU5EX01PRFVMQVRFIGlzIHRyaWNreTogaXQgdXNlcyBhbHBoYSBmcm9tIHRleHR1cmUgd2hlbiBhdmFpbGFibGUgYW5kIGFscGhhCiAgICBmcm9tIGRpZmZ1c2Ugb3RoZXJ3aXNlLiBTbyBjaGFuZ2luZyB0aGUgdGV4dHVyZSBtdXN0IGJlIG1vbml0b3JlZCBpbiBTZXRUZXh0dXJlIHRvIG1vZGlmeQogICAgYWxwaGFhcmcgd2hlbiBuZWVkZWQuCgogICAgQWxpZW5zIHZzIFByZWRhdG9yIDEgZGVwZW5kcyBvbiBhY2N1cmF0ZSBEM0RUQkxFTkRfTU9EVUxBVEUgZW11bGF0aW9uCgogICAgTGVnYWN5IHRleHR1cmUgYmxlbmRpbmcgKFRFWFRVUkVNQVBCTEVORCkgYW5kIHRleHR1cmUgc3RhZ2Ugc3RhdGVzOiBkaXJlY3R4NiBkb2NzIHN0YXRlIHRoYXQKICAgIFRFWFRVUkVNQVBCTEVORCBpcyBkZXByZWNhdGVkLCB5ZXQgY2FuIHN0aWxsIGJlIHVzZWQuIEdhbWVzIG11c3Qgbm90IHVzZSBib3RoIG9yIHJlc3VsdHMKICAgIGFyZSB1bmRlZmluZWQuIEQzRFRCTEVORF9NT0RVTEFURSBtb2RlIGluIHBhcnRpY3VsYXIgaXMgZGVwZW5kZW50IG9uIHRleHR1cmUgcGl4ZWwgZm9ybWF0IGFuZAogICAgcmVxdWlyZXMgZml4dXAgb2Ygc3RhZ2UgMCB0ZXh0dXJlIHN0YXRlcyB3aGVuIHRleHR1cmUgY2hhbmdlcywgYnV0IHRoaXMgZml4dXAgY2FuIGludGVyZmVyZQogICAgd2l0aCBnYW1lcyBub3QgdXNpbmcgdGhpcyBkZXByZWNhdGVkIHN0YXRlLiBTbyBhIGZsYWcgJ2xlZ2FjeVRleHR1cmVCbGVuZGluZycgaGFzIHRvIGJlIGtlcHQKICAgIGluIGRldmljZSAtIFRSVUUgaWYgdGhlIGFwcCBpcyB1c2luZyBURVhUVVJFTUFQQkxFTkQuCgogICAgVGVzdHMgc2hvdyB0aGF0IHNldHRpbmcgVEVYVFVSRU1BUEJMRU5EIG9uIG5hdGl2ZSBkb2Vzbid0IHNlZW0gdG8gY2hhbmdlIHZhbHVlcyByZXR1cm5lZCBieQogICAgR2V0VGV4dHVyZVN0YWdlU3RhdGUgYW5kIHZpY2UgdmVyc2EuIE5vdCBzbyBvbiBXaW5lLCBidXQgaXQgaXMgJ3VuZGVmaW5lZCcgYW55d2F5IHNvLCBwcm9iYWJseSwgb2ssCiAgICB1bmxlc3Mgc29tZSBicm9rZW4gZ2FtZSB3aWxsIGJlIGZvdW5kIHRoYXQgY2FyZXMuICovCgogICAgSFJFU1VMVCBocjsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlZClcbiIsIFRoaXMsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgc3dpdGNoKFJlbmRlclN0YXRlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVIQU5ETEU6CiAgICAgICAgewogICAgICAgICAgICBpZihWYWx1ZSA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKFZhbHVlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRklYTUUoIlNwZWNpZmllZCBoYW5kbGUgJWQgb3V0IG9mIHJhbmdlXG4iLCBWYWx1ZSk7CiAgICAgICAgICAgICAgICBociA9IERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihUaGlzLT5IYW5kbGVzW1ZhbHVlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9UZXh0dXJlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBGSVhNRSgiSGFuZGxlICVkIGlzbid0IGEgdGV4dHVyZSBoYW5kbGVcbiIsIFZhbHVlKTsKICAgICAgICAgICAgICAgIGhyID0gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICopIFRoaXMtPkhhbmRsZXNbVmFsdWUgLSAxXS5wdHI7CiAgICAgICAgICAgICAgICBociA9IElEaXJlY3QzRERldmljZTNfU2V0VGV4dHVyZShpZmFjZSwgMCwgSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdDNEVGV4dHVyZTIpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVNQVBCTEVORDoKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmxlZ2FjeVRleHR1cmVCbGVuZGluZyA9IFRSVUU7CgogICAgICAgICAgICBzd2l0Y2ggKCAoRDNEVEVYVFVSRUJMRU5EKSBWYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBEM0RUQkxFTkRfTU9EVUxBVEU6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQk9PTCB0ZXhfYWxwaGEgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlICp0ZXggPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTVVJGQUNFX0RFU0MgZGVzYzsKICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIGZtdDsKICAgICAgICAgICAgICAgICAgICBERFBJWEVMRk9STUFUIGRkZm10OwoKICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRleCk7CgogICAgICAgICAgICAgICAgICAgIGlmKGhyID09IFdJTkVEM0RfT0sgJiYgdGV4KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWVtc2V0KCZkZXNjLCAwLCBzaXplb2YoZGVzYykpOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjLkZvcm1hdCA9ICZmbXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0RUZXh0dXJlX0dldExldmVsRGVzYygoSVdpbmVEM0RUZXh0dXJlKikgdGV4LCAwLCAmZGVzYyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZGZtdC5kd1NpemUgPSBzaXplb2YoZGRmbXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRkZm10LCBmbXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRkZm10LnU1LmR3UkdCQWxwaGFCaXRNYXNrKSB0ZXhfYWxwaGEgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UodGV4KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFPUCwgV0lORUQzRFRPUF9TRUxFQ1RBUkcxKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGV4X2FscGhhKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzEsIFdJTkVEM0RUQV9DVVJSRU5UKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcxLCBXSU5FRDNEVEFfVEVYVFVSRSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUkFSRzIsIFdJTkVEM0RUQV9DVVJSRU5UKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9ST1AsIFdJTkVEM0RUT1BfTU9EVUxBVEUpOwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIEQzRFRCTEVORF9BREQ6CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUk9QLCBXSU5FRDNEVE9QX0FERCk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUkFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9SQVJHMiwgV0lORUQzRFRBX0NVUlJFTlQpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFPUCwgV0lORUQzRFRPUF9TRUxFQ1RBUkcyKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0FMUEhBQVJHMiwgV0lORUQzRFRBX0NVUlJFTlQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEJMRU5EX01PRFVMQVRFQUxQSEE6CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUkFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0FMUEhBQVJHMSwgV0lORUQzRFRBX1RFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcyLCBXSU5FRDNEVEFfQ1VSUkVOVCk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzIsIFdJTkVEM0RUQV9DVVJSRU5UKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9ST1AsIFdJTkVEM0RUT1BfTU9EVUxBVEUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFPUCwgV0lORUQzRFRPUF9NT0RVTEFURSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBEM0RUQkxFTkRfQ09QWToKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEJMRU5EX0RFQ0FMOgogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcxLCBXSU5FRDNEVEFfVEVYVFVSRSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9ST1AsIFdJTkVEM0RUT1BfU0VMRUNUQVJHMSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQU9QLCBXSU5FRDNEVE9QX1NFTEVDVEFSRzEpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEJMRU5EX0RFQ0FMQUxQSEE6CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUk9QLCBXSU5FRDNEVE9QX0JMRU5EVEVYVFVSRUFMUEhBKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9SQVJHMSwgV0lORUQzRFRBX1RFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcyLCBXSU5FRDNEVEFfQ1VSUkVOVCk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQU9QLCBXSU5FRDNEVE9QX1NFTEVDVEFSRzIpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFBUkcyLCBXSU5FRDNEVEFfQ1VSUkVOVCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBFUlIoIlVuaGFuZGxlZCB0ZXh0dXJlIGVudmlyb25tZW50ICVkICFcbiIsVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBociA9IEQzRF9PSzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBociA9IElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldFJlbmRlclN0YXRlKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIFJlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlZCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBSZW5kZXJTdGF0ZVR5cGUsIFZhbHVlKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX1NldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLCBSZW5kZXJTdGF0ZVR5cGUsIFZhbHVlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdDNERGV2aWNlMzo6U2V0TGlnaHRTdGF0ZQogKgogKiBTZXRzIGEgbGlnaHQgc3RhdGUgZm9yIERpcmVjdDNERGV2aWNlMyBhbmQgRGlyZWN0M0REZXZpY2UyLiBUaGUKICogbGlnaHQgc3RhdGVzIGFyZSBmb3J3YXJkZWQgdG8gRGlyZWN0M0REZXZpY2U3IHJlbmRlciBzdGF0ZXMKICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIExpZ2h0U3RhdGVUeXBlOiBUaGUgbGlnaHQgc3RhdGUgdG8gY2hhbmdlCiAqICBWYWx1ZTogVGhlIHZhbHVlIHRvIGFzc2lnbiB0byB0aGF0IGxpZ2h0IHN0YXRlCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgcGFyYW1ldGVycyB3ZXJlIGluY29ycmVjdAogKiAgQWxzbyBjaGVjayBJRGlyZWN0M0REZXZpY2U3OjpTZXRSZW5kZXJTdGF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0TGlnaHRTdGF0ZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETElHSFRTVEFURVRZUEUgTGlnaHRTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4KVxuIiwgVGhpcywgTGlnaHRTdGF0ZVR5cGUsIFZhbHVlKTsKCiAgICBpZiAoIUxpZ2h0U3RhdGVUeXBlICYmIChMaWdodFN0YXRlVHlwZSA+IEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVgpKQogICAgewogICAgICAgIFRSQUNFKCJVbmV4cGVjdGVkIExpZ2h0IFN0YXRlIFR5cGVcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoTGlnaHRTdGF0ZVR5cGUgPT0gRDNETElHSFRTVEFURV9NQVRFUklBTCAvKiAxICovKQogICAgewogICAgICAgIElEaXJlY3QzRE1hdGVyaWFsSW1wbCAqbWF0OwoKICAgICAgICBpZihWYWx1ZSA9PSAwKSBtYXQgPSBOVUxMOwogICAgICAgIGVsc2UgaWYoVmFsdWUgPiBUaGlzLT5udW1IYW5kbGVzKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJNYXRlcmlhbCBoYW5kbGUgb3V0IG9mIHJhbmdlKCVkKVxuIiwgVmFsdWUpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5IYW5kbGVzW1ZhbHVlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9NYXRlcmlhbCkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSW52YWxpZCBoYW5kbGUgJWRcbiIsIFZhbHVlKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG1hdCA9IChJRGlyZWN0M0RNYXRlcmlhbEltcGwgKikgVGhpcy0+SGFuZGxlc1tWYWx1ZSAtIDFdLnB0cjsKICAgICAgICB9CgogICAgICAgIGlmIChtYXQgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIgYWN0aXZhdGluZyBtYXRlcmlhbCAlcC5cbiIsIG1hdCk7CiAgICAgICAgICAgIG1hdC0+YWN0aXZhdGUobWF0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIiBEM0RMSUdIVFNUQVRFX01BVEVSSUFMIGNhbGxlZCB3aXRoIE5VTEwgbWF0ZXJpYWwgISEhXG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+bWF0ZXJpYWwgPSBWYWx1ZTsKICAgIH0KICAgIGVsc2UgaWYgKExpZ2h0U3RhdGVUeXBlID09IEQzRExJR0hUU1RBVEVfQ09MT1JNT0RFTCAvKiAzICovKQogICAgewogICAgICAgIHN3aXRjaCAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRENPTE9SX01PTk86CiAgICAgICAgICAgICAgICBFUlIoIkREQ09MT1JfTU9OTyBzaG91bGQgbm90IGhhcHBlbiFcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ09MT1JfUkdCOgogICAgICAgICAgICAgICAgLyogV2UgYXJlIGFscmVhZHkgaW4gdGhpcyBtb2RlICovCiAgICAgICAgICAgICAgICBUUkFDRSgiU2V0dGluZyBjb2xvciBtb2RlbCB0byBSR0IgKG5vLW9wKS5cbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBFUlIoIlVua25vd24gY29sb3IgbW9kZWwhXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIHJzOwogICAgICAgIHN3aXRjaCAoTGlnaHRTdGF0ZVR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQU1CSUVOVDogICAgICAgLyogMiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9BTUJJRU5UOwogICAgICAgICAgICAgICAgYnJlYWs7CQkKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR01PREU6ICAgICAgIC8qIDQgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HVkVSVEVYTU9ERTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HU1RBUlQ6ICAgICAgLyogNSAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dTVEFSVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HRU5EOiAgICAgICAgLyogNiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dFTkQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR0RFTlNJVFk6ICAgIC8qIDcgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HREVOU0lUWTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVg6ICAgLyogOCAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9DT0xPUlZFUlRFWDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIEQzRExJR0hUU1RBVEVUWVBFICVkLlxuIiwgTGlnaHRTdGF0ZVR5cGUpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldExpZ2h0U3RhdGUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUU1RBVEVUWVBFIExpZ2h0U3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBMaWdodFN0YXRlVHlwZSwgVmFsdWUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfU2V0TGlnaHRTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlnaHRTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkdldExpZ2h0U3RhdGUKICoKICogUmV0dXJucyB0aGUgY3VycmVudCBzZXR0aW5nIG9mIGEgbGlnaHQgc3RhdGUuIFRoZSBzdGF0ZSBpcyByZWFkIGZyb20KICogdGhlIERpcmVjdDNERGV2aWNlNyByZW5kZXIgc3RhdGUuCiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBQYXJhbXM6CiAqICBMaWdodFN0YXRlVHlwZTogVGhlIGxpZ2h0IHN0YXRlIHRvIHJldHVybgogKiAgVmFsdWU6IFRoZSBhZGRyZXNzIHRvIHN0b3JlIHRoZSBsaWdodCBzdGF0ZSBzZXR0aW5nIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIHBhcmFtZXRlcnMgd2VyZSBpbmNvcnJlY3QKICogIEFsc28gc2VlIElEaXJlY3QzRERldmljZTc6OkdldFJlbmRlclN0YXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19HZXRMaWdodFN0YXRlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RMSUdIVFNUQVRFVFlQRSBMaWdodFN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIExpZ2h0U3RhdGVUeXBlLCBWYWx1ZSk7CgogICAgaWYgKCFMaWdodFN0YXRlVHlwZSAmJiAoTGlnaHRTdGF0ZVR5cGUgPiBEM0RMSUdIVFNUQVRFX0NPTE9SVkVSVEVYKSkKICAgIHsKICAgICAgICBUUkFDRSgiVW5leHBlY3RlZCBMaWdodCBTdGF0ZSBUeXBlXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZighVmFsdWUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmIChMaWdodFN0YXRlVHlwZSA9PSBEM0RMSUdIVFNUQVRFX01BVEVSSUFMIC8qIDEgKi8pCiAgICB7CiAgICAgICAgKlZhbHVlID0gVGhpcy0+bWF0ZXJpYWw7CiAgICB9CiAgICBlbHNlIGlmIChMaWdodFN0YXRlVHlwZSA9PSBEM0RMSUdIVFNUQVRFX0NPTE9STU9ERUwgLyogMyAqLykKICAgIHsKICAgICAgICAqVmFsdWUgPSBEM0RDT0xPUl9SR0I7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIHJzOwogICAgICAgIHN3aXRjaCAoTGlnaHRTdGF0ZVR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQU1CSUVOVDogICAgICAgLyogMiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9BTUJJRU5UOwogICAgICAgICAgICAgICAgYnJlYWs7CQkKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR01PREU6ICAgICAgIC8qIDQgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HVkVSVEVYTU9ERTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HU1RBUlQ6ICAgICAgLyogNSAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dTVEFSVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HRU5EOiAgICAgICAgLyogNiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dFTkQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR0RFTlNJVFk6ICAgIC8qIDcgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HREVOU0lUWTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVg6ICAgLyogOCAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9DT0xPUlZFUlRFWDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIEQzRExJR0hUU1RBVEVUWVBFICVkLlxuIiwgTGlnaHRTdGF0ZVR5cGUpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0dldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldExpZ2h0U3RhdGUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUU1RBVEVUWVBFIExpZ2h0U3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqVmFsdWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIExpZ2h0U3RhdGVUeXBlLCBWYWx1ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRMaWdodFN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaWdodFN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0VHJhbnNmb3JtCiAqCiAqIEFzc2lnbnMgYSBEM0RNQVRSSVggdG8gYSB0cmFuc2Zvcm0gdHlwZS4gVGhlIHRyYW5zZm9ybSB0eXBlcyBhcmUgZGVmaW5lZAogKiBpbiBpbmNsdWRlL2QzZHR5cGVzLmguCiAqIFRoZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRCAoPTEpIGlzIHRyYW5zbGF0ZWQgdG8gRDNEVFNfV09STERNQVRSSVgoMCkKICogKD0yNTUpIGZvciB3aW5lZDNkLCBiZWNhdXNlIHRoZSAxIHRyYW5zZm9ybSBzdGF0ZSB3YXMgcmVtb3ZlZCBpbiBkM2Q4CiAqIGFuZCBXaW5lRDNEIGFscmVhZHkgdW5kZXJzdGFuZHMgdGhlIHJlcGxhY2VtZW50IEQzRFRTX1dPUkxETUFUUklYKDApCiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBUcmFuc2Zvcm1TdGF0ZVR5cGU6IHRyYW5zZm9ybSBzdGF0ZSB0byBzZXQKICogIE1hdHJpeDogTWF0cml4IHRvIGFzc2lnbiB0byB0aGUgc3RhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIE1hdHJpeCA9PSBOVUxMCiAqICBGb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFRyYW5zZm9ybQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19TZXRUcmFuc2Zvcm0oSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKk1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIHR5cGUgPSBUcmFuc2Zvcm1TdGF0ZVR5cGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXlcbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgTWF0cml4KTsKCiAgICBzd2l0Y2goVHJhbnNmb3JtU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQgOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgwKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDE6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDEpOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMjogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMik7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQzOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgzKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gVHJhbnNmb3JtU3RhdGVUeXBlOwogICAgfQoKICAgIGlmKCFNYXRyaXgpCiAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBOb3RlOiBEM0RNQVRSSVggaXMgY29tcGF0aWJsZSB3aXRoIFdJTkVEM0RNQVRSSVggKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFRyYW5zZm9ybShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFUUklYKikgTWF0cml4KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VHJhbnNmb3JtX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpNYXRyaXgpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VHJhbnNmb3JtKGlmYWNlLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIE1hdHJpeCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VHJhbnNmb3JtX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpNYXRyaXgpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19TZXRUcmFuc2Zvcm0oaWZhY2UsIFRyYW5zZm9ybVN0YXRlVHlwZSwgTWF0cml4KTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFRyYW5zZm9ybShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RUUkFOU0ZPUk1TVEFURVRZUEUgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIEQzRE1hdHJpeCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRUcmFuc2Zvcm0oSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1hdHJpeCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1NldFRyYW5zZm9ybShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETWF0cml4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldFRyYW5zZm9ybQogKgogKiBSZXR1cm5zIHRoZSBtYXRyaXggYXNzaWduZWQgdG8gYSB0cmFuc2Zvcm0gc3RhdGUKICogRDNEVFJBTlNGT1JNU1RBVEVfV09STEQgaXMgdHJhbnNsYXRlZCB0byBEM0RUU19XT1JMRE1BVFJJWCgwKSwgc2VlCiAqIFNldFRyYW5zZm9ybQogKgogKiBQYXJhbXM6CiAqICBUcmFuc2Zvcm1TdGF0ZVR5cGU6IFN0YXRlIHRvIHJlYWQgdGhlIG1hdHJpeCBmcm9tCiAqICBNYXRyaXg6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIG1hdHJpeCBhdAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgTWF0cml4ID09IE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldFRyYW5zZm9ybQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUcmFuc2Zvcm0oSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKk1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIHR5cGUgPSBUcmFuc2Zvcm1TdGF0ZVR5cGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXlcbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgTWF0cml4KTsKCiAgICBzd2l0Y2goVHJhbnNmb3JtU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQgOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgwKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDE6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDEpOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMjogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMik7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQzOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgzKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gVHJhbnNmb3JtU3RhdGVUeXBlOwogICAgfQoKICAgIGlmKCFNYXRyaXgpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogTm90ZTogRDNETUFUUklYIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETUFUUklYICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwgdHlwZSwgKFdJTkVEM0RNQVRSSVgqKSBNYXRyaXgpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUcmFuc2Zvcm1fRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKk1hdHJpeCkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19HZXRUcmFuc2Zvcm0oaWZhY2UsIFRyYW5zZm9ybVN0YXRlVHlwZSwgTWF0cml4KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUcmFuc2Zvcm1fRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKk1hdHJpeCkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRyYW5zZm9ybShpZmFjZSwgVHJhbnNmb3JtU3RhdGVUeXBlLCBNYXRyaXgpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0dldFRyYW5zZm9ybShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETWF0cml4KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRUcmFuc2Zvcm0oSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfR2V0VHJhbnNmb3JtKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNYXRyaXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6TXVsdGlwbHlUcmFuc2Zvcm0KICoKICogTXVsdGlwbGllcyB0aGUgYWxyZWFkeS1zZXQgdHJhbnNmb3JtIG1hdHJpeCBvZiBhIHRyYW5zZm9ybSBzdGF0ZQogKiB3aXRoIGFub3RoZXIgbWF0cml4LiBGb3IgdGhlIHdvcmxkIG1hdHJpeCwgc2VlIFNldFRyYW5zZm9ybQogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgVHJhbnNmb3JtU3RhdGVUeXBlOiBUcmFuc2Zvcm0gc3RhdGUgdG8gbXVsdGlwbHkKICogIEQzRE1hdHJpeCBNYXRyaXggdG8gbXVsdGlwbHkgd2l0aC4KICoKICogUmV0dXJucwogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNETWF0cml4IGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6Ok11bHRpcGx5VHJhbnNmb3JtCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X011bHRpcGx5VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIHR5cGU7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheVxuIiwgVGhpcywgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwoKICAgIHN3aXRjaChUcmFuc2Zvcm1TdGF0ZVR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRCA6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDApOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMTogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMSk7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQyOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgyKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDM6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDMpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBUcmFuc2Zvcm1TdGF0ZVR5cGU7CiAgICB9CgogICAgLyogTm90ZTogRDNETUFUUklYIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETUFUUklYICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9NdWx0aXBseVRyYW5zZm9ybShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRE1BVFJJWCopIEQzRE1hdHJpeCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X011bHRpcGx5VHJhbnNmb3JtX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X011bHRpcGx5VHJhbnNmb3JtKGlmYWNlLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIEQzRE1hdHJpeCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfTXVsdGlwbHlUcmFuc2Zvcm1fRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RUUkFOU0ZPUk1TVEFURVRZUEUgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19NdWx0aXBseVRyYW5zZm9ybShpZmFjZSwgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfTXVsdGlwbHlUcmFuc2Zvcm0oSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RUUkFOU0ZPUk1TVEFURVRZUEUgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X011bHRpcGx5VHJhbnNmb3JtKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETWF0cml4KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9NdWx0aXBseVRyYW5zZm9ybShJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfTXVsdGlwbHlUcmFuc2Zvcm0oSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNYXRyaXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RHJhd1ByaW1pdGl2ZQogKgogKiBEcmF3cyBwcmltaXRpdmVzIGJhc2VkIG9uIHZlcnRpY2VzIGluIGFuIGFwcGxpY2F0aW9uLXByb3ZpZGVkIHBvaW50ZXIKICoKICogVmVyc2lvbiAyLCAzIGFuZCA3LiBUaGUgSURpcmVjdDNERGV2aWNlMiB0aHVuayBjb252ZXJ0cyB0aGUgZml4ZWQgdmVydGV4IHR5cGUgaW50bwogKiBhbiBGVkYgZm9ybWF0IGZvciBEM0Q3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFRoZSB0eXBlIG9mIHRoZSBwcmltaXRpdmVzIHRvIGRyYXcKICogIFZlcnRleCB0eXBlOiBGbGV4aWJsZSB2ZXJ0ZXggZm9ybWF0IHZlcnRleCBkZXNjcmlwdGlvbgogKiAgVmVydGljZXM6IFBvaW50ZXIgdG8gdGhlIHZlcnRleCBhcnJheQogKiAgVmVydGV4Q291bnQ6IFRoZSBudW1iZXIgb2YgdmVydGljZXMgdG8gZHJhdwogKiAgRmxhZ3M6IEFzIHVzdWFsIGEgZmV3IGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBWZXJ0aWNlcyBpcyBOVUxMCiAqICBGb3IgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpEcmF3UHJpbWl0aXZlVVAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBzdHJpZGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KTogUmVsYXkhXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBWZXJ0aWNlcywgVmVydGV4Q291bnQsIEZsYWdzKTsKCiAgICBpZighVmVydGljZXMpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogR2V0IHRoZSB2ZXJ0ZXggY291bnQgKi8KICAgIHN3aXRjaChQcmltaXRpdmVUeXBlKQogICAgewogICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDogCiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLyAyOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBEM0RQVF9MSU5FU1RSSVA6CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAtIDE7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFTElTVDoKICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC8gMzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC0gMjsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVGQU46CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAtIDI7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEdldCB0aGUgc3RyaWRlICovCiAgICBzdHJpZGUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoVmVydGV4VHlwZSk7CgogICAgLyogU2V0IHRoZSBGVkYgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9GaW5kRGVjbChUaGlzLT5kZHJhdywgVmVydGV4VHlwZSkpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIFRoaXMgbWV0aG9kIHRyYW5zbGF0ZXMgdG8gdGhlIHVzZXIgcG9pbnRlciBkcmF3IG9mIFdpbmVEM0QgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd1ByaW1pdGl2ZVVQKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBWZXJ0aWNlcywgVmVydGV4Q291bnQsIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBWZXJ0aWNlcywgVmVydGV4Q291bnQsIEZsYWdzKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EcmF3UHJpbWl0aXZlKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWFRZUEUgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgRFdPUkQgRlZGOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBGbGFncyk7CgogICAgc3dpdGNoKFZlcnRleFR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RWVF9WRVJURVg6IEZWRiA9IEQzREZWRl9WRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfTFZFUlRFWDogRlZGID0gRDNERlZGX0xWRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfVExWRVJURVg6IEZWRiA9IEQzREZWRl9UTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCB0eXBlICVkXG4iLCBWZXJ0ZXhUeXBlKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7ICAvKiBTaG91bGQgbmV2ZXIgaGFwcGVuICovCiAgICB9CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlZGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkRyYXdJbmRleGVkUHJpbWl0aXZlCiAqCiAqIERyYXdzIHZlcnRpY2VzIGZyb20gYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgcG9pbnRlciwgYmFzZWQgb24gdGhlIGluZGV4CiAqIG51bWJlcnMgaW4gYSBXT1JEIGFycmF5LgogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcuIFRoZSB2ZXJzaW9uIDcgdGh1bmsgdHJhbnNsYXRlcyB0aGUgdmVydGV4IHR5cGUgaW50bwogKiBhbiBGVkYgZm9ybWF0IGZvciBEM0Q3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFRoZSBwcmltaXRpdmUgdHlwZSB0byBkcmF3CiAqICBWZXJ0ZXhUeXBlOiBUaGUgRlZGIHZlcnRleCBkZXNjcmlwdGlvbgogKiAgVmVydGljZXM6IFBvaW50ZXIgdG8gdGhlIHZlcnRleCBhcnJheQogKiAgVmVydGV4Q291bnQ6ID8KICogIEluZGljZXM6IFBvaW50ZXIgdG8gdGhlIGluZGV4IGFycmF5CiAqICBJbmRleENvdW50OiBOdW1iZXIgb2YgaW5kaWNlcyA9IE51bWJlciBvZiB2ZXJ0aWNlcyB0byBkcmF3CiAqICBGbGFnczogQXMgdXN1YWwsIHNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZlcnRpY2VzIG9yIEluZGljZXMgaXMgTlVMTAogKiAgRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6RHJhd0luZGV4ZWRQcmltaXRpdmVVUAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgVUlOVCBQcmltaXRpdmVDb3VudCA9IDA7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4LCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwoKICAgIC8qIEdldCB0aGUgcHJpbWl0aXZlIG51bWJlciAqLwogICAgc3dpdGNoKFByaW1pdGl2ZVR5cGUpCiAgICB7CiAgICAgIGNhc2UgRDNEUFRfUE9JTlRMSVNUOiAKICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQ7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX0xJTkVMSVNUOiAKICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLyAyOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBEM0RQVF9MSU5FU1RSSVA6CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC0gMTsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVMSVNUOgogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAvIDM7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFU1RSSVA6CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC0gMjsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVGQU46CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC0gMjsKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogU2V0IHRoZSBEM0REZXZpY2UncyBGVkYgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9GaW5kRGVjbChUaGlzLT5kZHJhdywgVmVydGV4VHlwZSkpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIFNldHRpbmcgdGhlIEZWRiBmYWlsZWQsIGhyID0gJXghXG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRERldmljZV9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIE1pblZlcnRleEluZGV4ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleENvdW50IC8qIFVJTlQgTnVtVmVydGV4SW5kZXggKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk1UX0lOREVYMTYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKFZlcnRleFR5cGUpKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgKkluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdJbmRleGVkUHJpbWl0aXZlX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd0luZGV4ZWRQcmltaXRpdmUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgKkluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0RyYXdJbmRleGVkUHJpbWl0aXZlKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkVSVEVYVFlQRSBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgKkluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIERXT1JEIEZWRjsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CgogICAgc3dpdGNoKFZlcnRleFR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RWVF9WRVJURVg6IEZWRiA9IEQzREZWRl9WRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfTFZFUlRFWDogRlZGID0gRDNERlZGX0xWRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfVExWRVJURVg6IEZWRiA9IEQzREZWRl9UTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCB0eXBlICVkXG4iLCBWZXJ0ZXhUeXBlKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7ICAvKiBTaG91bGQgbmV2ZXIgaGFwcGVuICovCiAgICB9CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlZGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0Q2xpcFN0YXR1cwogKgogKiBTZXRzIHRoZSBjbGlwIHN0YXR1cy4gVGhpcyBkZWZpbmVzIHRoaW5ncyBhcyBjbGlwcGluZyBjb25kaXRpb25zIGFuZAogKiB0aGUgZXh0ZW50cyBvZiB0aGUgY2xpcHBpbmcgcmVnaW9uLgogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgQ2xpcFN0YXR1czoKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqICAoRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDbGlwU3RhdHVzID09IE5VTEwpCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwKTogU3R1YiFcbiIsIFRoaXMsIENsaXBTdGF0dXMpOwoKICAgIC8qIEQzRENMSVBTVEFUVVMgYW5kIFdJTkVEM0RDTElQU1RBVFVTIGFyZSBkaWZmZXJlbnQuIEkgZG9uJ3Qga25vdyBob3cgdG8gY29udmVydCB0aGVtCiAgICAgKiBQZXJoYXBzIHRoaXMgbmVlZHMgYSBuZXcgZGF0YSB0eXBlIGFuZCBhbiBhZGRpdGlvbmFsIElXaW5lRDNERGV2aWNlIG1ldGhvZAogICAgICovCiAgICAvKiByZXR1cm4gSVdpbmVEM0REZXZpY2VfU2V0Q2xpcFN0YXR1cyhUaGlzLT53aW5lRDNERGV2aWNlLCBDbGlwU3RhdHVzKTsqLwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2xpcFN0YXR1cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRDbGlwU3RhdHVzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGlwU3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9TZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2xpcFN0YXR1cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRDbGlwU3RhdHVzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGlwU3RhdHVzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldENsaXBTdGF0dXMKICoKICogUmV0dXJucyB0aGUgY2xpcCBzdGF0dXMKICoKICogUGFyYW1zOgogKiAgQ2xpcFN0YXR1czogQWRkcmVzcyB0byB3cml0ZSB0aGUgY2xpcCBzdGF0dXMgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwKTogU3R1YiFcbiIsIFRoaXMsIENsaXBTdGF0dXMpOwoKICAgIC8qIEQzRENMSVBTVEFUVVMgYW5kIFdJTkVEM0RDTElQU1RBVFVTIGFyZSBkaWZmZXJlbnQuIEkgZG9uJ3Qga25vdyBob3cgdG8gY29udmVydCB0aGVtICovCiAgICAvKiByZXR1cm4gSVdpbmVEM0REZXZpY2VfR2V0Q2xpcFN0YXR1cyhUaGlzLT53aW5lRDNERGV2aWNlLCBDbGlwU3RhdHVzKTsqLwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2xpcFN0YXR1cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19HZXRDbGlwU3RhdHVzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGlwU3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRDbGlwU3RhdHVzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDTElQU1RBVFVTICpDbGlwU3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2xpcFN0YXR1cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19HZXRDbGlwU3RhdHVzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGlwU3RhdHVzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6RHJhd1ByaW1pdGl2ZVN0cmlkZWQKICoKICogRHJhd3MgdmVydGljZXMgZGVzY3JpYmVkIGJ5IGEgRDNERFJBV1BSSU1JVElWRVNUUklERUREQVRBIHN0cnVjdHVyZS4KICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFRoZSBwcmltaXRpdmUgdHlwZSB0byBkcmF3CiAqICBWZXJ0ZXhUeXBlOiBUaGUgRlZGIGRlc2NyaXB0aW9uIG9mIHRoZSB2ZXJ0aWNlcyB0byBkcmF3IChmb3IgdGhlIHN0cmlkZT8/KQogKiAgRDNERHJhd1ByaW1TdHJpZGVEYXRhOiBBIEQzRERSQVdQUklNSVRJVkVTVFJJREVEREFUQSBzdHJ1Y3R1cmUgZGVzY3JpYmluZwogKiAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgdmVydGV4IGRhdGEgbG9jYXRpb25zCiAqICBWZXJ0ZXhDb3VudDogVGhlIG51bWJlciBvZiB2ZXJ0aWNlcyB0byBkcmF3CiAqICBGbGFnczogU29tZSBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqICAoRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBEM0REcmF3UHJpbVN0cmlkZURhdGEgaXMgTlVMTCkKICogIChGb3IgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpEcmF3UHJpbWl0aXZlU3RyaWRlZCkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZVN0cmlkZWQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERFJBV1BSSU1JVElWRVNUUklERUREQVRBICpEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSBXaW5lRDNEU3RyaWRlZDsKICAgIGludCBpOwogICAgVUlOVCBQcmltaXRpdmVDb3VudDsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KTogc3R1YiFcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIEQzRERyYXdQcmltU3RyaWRlRGF0YSwgVmVydGV4Q291bnQsIEZsYWdzKTsKCiAgICBtZW1zZXQoJldpbmVEM0RTdHJpZGVkLCAwLCBzaXplb2YoV2luZUQzRFN0cmlkZWQpKTsKICAgIC8qIEdldCB0aGUgc3RyaWRlZCBkYXRhIHJpZ2h0LiB0aGUgd2luZWQzZCBzdHJ1Y3R1cmUgaXMgYSBiaXQgYmlnZ2VyCiAgICAgKiBXYXRjaCBvdXQ6IFRoZSBjb250ZW50cyBvZiB0aGUgc3RyaWRlZCBkYXRhIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBmdmYsCiAgICAgKiBub3QgYnkgdGhlIG1lbWJlcnMgc2V0IGluIEQzRERyYXdQcmltU3RyaWRlRGF0YS4gU28gaXQncyB2YWxpZAogICAgICogdG8gaGF2ZSBkaWZmdXNlLmxwdkRhdGEgc2V0IHRvIDB4ZGVhZGJlZWYgaWYgdGhlIGRpZmZ1c2UgZmxhZyBpcwogICAgICogbm90IHNldCBpbiB0aGUgZnZmLgogICAgICovCiAgICBpZihWZXJ0ZXhUeXBlICYgRDNERlZGX1BPU0lUSU9OX01BU0spCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+cG9zaXRpb24ubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb24uZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnBvc2l0aW9uLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbi5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgIGlmIChWZXJ0ZXhUeXBlICYgRDNERlZGX1hZWlJIVykKICAgICAgICB7CiAgICAgICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbi5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb25fdHJhbnNmb3JtZWQgPSBUUlVFOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb25fdHJhbnNmb3JtZWQgPSBGQUxTRTsKICAgIH0KCiAgICBpZihWZXJ0ZXhUeXBlICYgRDNERlZGX05PUk1BTCkKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMubm9ybWFsLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+bm9ybWFsLmxwdkRhdGE7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLm5vcm1hbC5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+bm9ybWFsLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5ub3JtYWwuZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgIH0KCiAgICBpZihWZXJ0ZXhUeXBlICYgRDNERlZGX0RJRkZVU0UpCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLmRpZmZ1c2UubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5kaWZmdXNlLmxwdkRhdGE7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLmRpZmZ1c2UuZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPmRpZmZ1c2UuZHdTdHJpZGU7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLmRpZmZ1c2UuZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfU1BFQ1VMQVIpCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnNwZWN1bGFyLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+c3BlY3VsYXIubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuc3BlY3VsYXIuZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnNwZWN1bGFyLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5zcGVjdWxhci5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRDNEQ09MT1I7CiAgICB9CgogICAgZm9yKCBpID0gMDsgaSA8IEdFVF9URVhDT1VOVF9GUk9NX0ZWRihWZXJ0ZXhUeXBlKTsgaSsrKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0ubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT50ZXh0dXJlQ29vcmRzW2ldLmxwdkRhdGE7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnRleENvb3Jkc1tpXS5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+dGV4dHVyZUNvb3Jkc1tpXS5kd1N0cmlkZTsKICAgICAgICBzd2l0Y2goR0VUX1RFWENPT1JEX1NJWkVfRlJPTV9GVkYoVmVydGV4VHlwZSwgaSkpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIDE6IFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjogV2luZUQzRFN0cmlkZWQudS5zLnRleENvb3Jkc1tpXS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQyOyBicmVhazsKICAgICAgICAgICAgY2FzZSAzOiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDQ6IFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNDsgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6IEVSUigiVW5leHBlY3RlZCB0ZXh0dXJlIGNvb3JkaW5hdGUgc2l6ZSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKFZlcnRleFR5cGUsIGkpKTsKICAgICAgICB9CiAgICB9CgogICAgLyogR2V0IHRoZSBwcmltaXRpdmUgY291bnQgKi8KICAgIHN3aXRjaChQcmltaXRpdmVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEUFRfUE9JTlRMSVNUOiAKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQ7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9MSU5FTElTVDogCiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC8gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX0xJTkVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLSAxOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVMSVNUOgogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAvIDM7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRVNUUklQOgogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUZBTjoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLSAyOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6IHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFdpbmVEM0QgZG9lc24ndCBuZWVkIHRoZSBGVkYgaGVyZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd1ByaW1pdGl2ZVN0cmlkZWQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZXaW5lRDNEU3RyaWRlZCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVTdHJpZGVkX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERSQVdQUklNSVRJVkVTVFJJREVEREFUQSAqRDNERHJhd1ByaW1TdHJpZGVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlU3RyaWRlZChpZmFjZSwgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgRDNERHJhd1ByaW1TdHJpZGVEYXRhLCBWZXJ0ZXhDb3VudCwgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVTdHJpZGVkX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERSQVdQUklNSVRJVkVTVFJJREVEREFUQSAqRDNERHJhd1ByaW1TdHJpZGVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVTdHJpZGVkKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBEM0REcmF3UHJpbVN0cmlkZURhdGEsIFZlcnRleENvdW50LCBGbGFncyk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3UHJpbWl0aXZlU3RyaWRlZChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKkQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIEQzRERyYXdQcmltU3RyaWRlRGF0YSwgVmVydGV4Q291bnQsIEZsYWdzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0RyYXdQcmltaXRpdmVTdHJpZGVkKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkRyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZAogKgogKiBEcmF3cyBwcmltaXRpdmVzIHNwZWNpZmllZCBieSBzdHJpZGVkIGRhdGEgbG9jYXRpb25zIGJhc2VkIG9uIGluZGljZXMKICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICogIChEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRERyYXdQcmltU3RyaWRlRGF0YSBpcyBOVUxMKQogKiAgKERERVJSX0lOVkFMSURQQVJBTVMgaWYgSW5kaWNlcyBpcyBOVUxMKQogKiAgKEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6RHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERFJBV1BSSU1JVElWRVNUUklERUREQVRBICpEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSBXaW5lRDNEU3RyaWRlZDsKICAgIGludCBpOwogICAgVUlOVCBQcmltaXRpdmVDb3VudDsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4LCUwOHgpXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBEM0REcmF3UHJpbVN0cmlkZURhdGEsIFZlcnRleENvdW50LCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CgogICAgbWVtc2V0KCZXaW5lRDNEU3RyaWRlZCwgMCwgc2l6ZW9mKFdpbmVEM0RTdHJpZGVkKSk7CiAgICAvKiBHZXQgdGhlIHN0cmlkZWQgZGF0YSByaWdodC4gdGhlIHdpbmVkM2Qgc3RydWN0dXJlIGlzIGEgYml0IGJpZ2dlcgogICAgICogV2F0Y2ggb3V0OiBUaGUgY29udGVudHMgb2YgdGhlIHN0cmlkZWQgZGF0YSBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZnZmLAogICAgICogbm90IGJ5IHRoZSBtZW1iZXJzIHNldCBpbiBEM0REcmF3UHJpbVN0cmlkZURhdGEuIFNvIGl0J3MgdmFsaWQKICAgICAqIHRvIGhhdmUgZGlmZnVzZS5scHZEYXRhIHNldCB0byAweGRlYWRiZWVmIGlmIHRoZSBkaWZmdXNlIGZsYWcgaXMKICAgICAqIG5vdCBzZXQgaW4gdGhlIGZ2Zi4KICAgICAqLwogICAgaWYoVmVydGV4VHlwZSAmIEQzREZWRl9QT1NJVElPTl9NQVNLKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbi5scERhdGEgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnBvc2l0aW9uLmxwdkRhdGE7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmR3U3RyaWRlID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5wb3NpdGlvbi5kd1N0cmlkZTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb24uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICBpZiAoVmVydGV4VHlwZSAmIEQzREZWRl9YWVpSSFcpCiAgICAgICAgewogICAgICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb24uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNDsKICAgICAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkID0gVFJVRTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkID0gRkFMU0U7CiAgICB9CgogICAgaWYoVmVydGV4VHlwZSAmIEQzREZWRl9OT1JNQUwpCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLm5vcm1hbC5scERhdGEgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPm5vcm1hbC5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5ub3JtYWwuZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPm5vcm1hbC5kd1N0cmlkZTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMubm9ybWFsLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICB9CgogICAgaWYoVmVydGV4VHlwZSAmIEQzREZWRl9ESUZGVVNFKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5kaWZmdXNlLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+ZGlmZnVzZS5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5kaWZmdXNlLmR3U3RyaWRlID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5kaWZmdXNlLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5kaWZmdXNlLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgIH0KCiAgICBpZihWZXJ0ZXhUeXBlICYgRDNERlZGX1NQRUNVTEFSKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5zcGVjdWxhci5scERhdGEgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnNwZWN1bGFyLmxwdkRhdGE7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnNwZWN1bGFyLmR3U3RyaWRlID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5zcGVjdWxhci5kd1N0cmlkZTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuc3BlY3VsYXIuZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgfQoKICAgIGZvciggaSA9IDA7IGkgPCBHRVRfVEVYQ09VTlRfRlJPTV9GVkYoVmVydGV4VHlwZSk7IGkrKykKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+dGV4dHVyZUNvb3Jkc1tpXS5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnRleHR1cmVDb29yZHNbaV0uZHdTdHJpZGU7CiAgICAgICAgc3dpdGNoKEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKFZlcnRleFR5cGUsIGkpKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAxOiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6IFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzogV2luZUQzRFN0cmlkZWQudS5zLnRleENvb3Jkc1tpXS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOyBicmVhazsKICAgICAgICAgICAgY2FzZSA0OiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiBFUlIoIlVuZXhwZWN0ZWQgdGV4dHVyZSBjb29yZGluYXRlIHNpemUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfVEVYQ09PUkRfU0laRV9GUk9NX0ZWRihWZXJ0ZXhUeXBlLCBpKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCB0aGUgcHJpbWl0aXZlIGNvdW50ICovCiAgICBzd2l0Y2goUHJpbWl0aXZlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDoKICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50OwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9MSU5FTElTVDoKICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC8gMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORVNUUklQOgogICAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLSAxOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAvIDM7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFU1RSSVA6CiAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFRkFOOgogICAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLSAyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFdpbmVEM0QgZG9lc24ndCBuZWVkIHRoZSBGVkYgaGVyZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmV2luZUQzRFN0cmlkZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk1UX0lOREVYMTYpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWRfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERFJBV1BSSU1JVElWRVNUUklERUREQVRBICpEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZChpZmFjZSwgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgRDNERHJhd1ByaW1TdHJpZGVEYXRhLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZF9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKkQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIEQzRERyYXdQcmltU3RyaWRlRGF0YSwgVmVydGV4Q291bnQsIEluZGljZXMsIEluZGV4Q291bnQsIEZsYWdzKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKkQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIEQzRERyYXdQcmltU3RyaWRlRGF0YSwgVmVydGV4Q291bnQsIEluZGljZXMsIEluZGV4Q291bnQsIEZsYWdzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERHJhd1ByaW1TdHJpZGVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpEcmF3UHJpbWl0aXZlVkIKICoKICogRHJhd3MgcHJpbWl0aXZlcyBmcm9tIGEgdmVydGV4IGJ1ZmZlciB0byB0aGUgc2NyZWVuLgogKgogKiBWZXJzaW9uIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgUHJpbWl0aXZlVHlwZTogVHlwZSBvZiBwcmltaXRpdmUgdG8gYmUgcmVuZGVyZWQuCiAqICBEM0RWZXJ0ZXhCdWY6IFNvdXJjZSBWZXJ0ZXggQnVmZmVyCiAqICBTdGFydFZlcnRleDogSW5kZXggb2YgdGhlIGZpcnN0IHZlcnRleCBmcm9tIHRoZSBidWZmZXIgdG8gYmUgcmVuZGVyZWQKICogIE51bVZlcnRpY2VzOiBOdW1iZXIgb2YgdmVydGljZXMgdG8gYmUgcmVuZGVyZWQKICogIEZsYWdzOiBDYW4gYmUgRDNERFBfV0FJVCB0byB3YWl0IHVudGlsIHJlbmRlcmluZyBoYXMgZmluaXNoZWQKICoKICogUmV0dXJuIHZhbHVlcwogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNEVmVydGV4QnVmIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZVZCKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICpEM0RWZXJ0ZXhCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhcnRWZXJ0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwgKnZiID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyNywgRDNEVmVydGV4QnVmKTsKICAgIFVJTlQgUHJpbWl0aXZlQ291bnQ7CiAgICBIUkVTVUxUIGhyOwogICAgRFdPUkQgc3RyaWRlOwogICAgV0lORUQzRFZFUlRFWEJVRkZFUl9ERVNDIERlc2M7CgogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwLCUwOHgsJTA4eCwlMDh4KVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgRDNEVmVydGV4QnVmLCBTdGFydFZlcnRleCwgTnVtVmVydGljZXMsIEZsYWdzKTsKCiAgICAvKiBTYW5pdHkgY2hlY2tzICovCiAgICBpZighdmIpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIE5vIFZlcnRleCBidWZmZXIgc3BlY2lmaWVkXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBHZXQgdGhlIHByaW1pdGl2ZSBjb3VudCAqLwogICAgc3dpdGNoKFByaW1pdGl2ZVR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RQVF9QT0lOVExJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBOdW1WZXJ0aWNlczsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX0xJTkVMSVNUOiAKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gTnVtVmVydGljZXMgLyAyOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORVNUUklQOgogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBOdW1WZXJ0aWNlcyAtIDE7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IE51bVZlcnRpY2VzIC8gMzsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFU1RSSVA6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IE51bVZlcnRpY2VzIC0gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFRkFOOgogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBOdW1WZXJ0aWNlcyAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEdldCB0aGUgRlZGIG9mIHRoZSB2ZXJ0ZXggYnVmZmVyLCBhbmQgaXRzIHN0cmlkZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfR2V0RGVzYyh2Yi0+d2luZUQzRFZlcnRleEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNEVmVydGV4QnVmZmVyOjpHZXREZXNjIGZhaWxlZCB3aXRoIGhyID0gJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgc3RyaWRlID0gZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKERlc2MuRlZGKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT53aW5lRDNEVmVydGV4RGVjbGFyYXRpb24pOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIFNldHRpbmcgdGhlIEZWRiBmYWlsZWQsIGhyID0gJXghXG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogU2V0IHRoZSB2ZXJ0ZXggc3RyZWFtIHNvdXJjZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTdHJlYW1Tb3VyY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RyZWFtTnVtYmVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPndpbmVEM0RWZXJ0ZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN0YXJ0VmVydGV4IC0gd2UgcGFzcyB0aGlzIHRvIERyYXdQcmltaXRpdmUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpZGUpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiKCVwKSBJRGlyZWN0M0REZXZpY2U6OlNldFN0cmVhbVNvdXJjZSBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBOb3cgZHJhdyB0aGUgcHJpbWl0aXZlcyAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9EcmF3UHJpbWl0aXZlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVDb3VudCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVWQl9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmVydGV4QnVmZmVyNyAqRDNEVmVydGV4QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVWQihpZmFjZSwgUHJpbWl0aXZlVHlwZSwgRDNEVmVydGV4QnVmLCBTdGFydFZlcnRleCwgTnVtVmVydGljZXMsIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlVkJfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKkQzRFZlcnRleEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVWQihpZmFjZSwgUHJpbWl0aXZlVHlwZSwgRDNEVmVydGV4QnVmLCBTdGFydFZlcnRleCwgTnVtVmVydGljZXMsIEZsYWdzKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmVWQihJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmVydGV4QnVmZmVyICpEM0RWZXJ0ZXhCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhcnRWZXJ0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwgKnZiID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyLCBEM0RWZXJ0ZXhCdWYpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXAsJTA4eCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgIFByaW1pdGl2ZVR5cGUsIHZiLCBTdGFydFZlcnRleCwgTnVtVmVydGljZXMsIEZsYWdzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0RyYXdQcmltaXRpdmVWQihJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHZiLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RHJhd0luZGV4ZWRQcmltaXRpdmVWQgogKgogKiBEcmF3cyBwcmltaXRpdmVzIGZyb20gYSB2ZXJ0ZXggYnVmZmVyIHRvIHRoZSBzY3JlZW4KICoKICogUGFyYW1zOgogKiAgUHJpbWl0aXZlVHlwZTogVHlwZSBvZiBwcmltaXRpdmUgdG8gYmUgcmVuZGVyZWQuCiAqICBEM0RWZXJ0ZXhCdWY6IFNvdXJjZSBWZXJ0ZXggQnVmZmVyCiAqICBTdGFydFZlcnRleDogSW5kZXggb2YgdGhlIGZpcnN0IHZlcnRleCBmcm9tIHRoZSBidWZmZXIgdG8gYmUgcmVuZGVyZWQKICogIE51bVZlcnRpY2VzOiBOdW1iZXIgb2YgdmVydGljZXMgdG8gYmUgcmVuZGVyZWQKICogIEluZGljZXM6IEFycmF5IG9mIERXT1JEcyB1c2VkIHRvIGluZGV4IGludG8gdGhlIFZlcnRpY2VzCiAqICBJbmRleENvdW50OiBOdW1iZXIgb2YgaW5kaWNlcyBpbiBJbmRpY2VzCiAqICBGbGFnczogQ2FuIGJlIEQzRERQX1dBSVQgdG8gd2FpdCB1bnRpbCByZW5kZXJpbmcgaGFzIGZpbmlzaGVkCiAqCiAqIFJldHVybiB2YWx1ZXMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQihJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICpEM0RWZXJ0ZXhCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwgKnZiID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyNywgRDNEVmVydGV4QnVmKTsKICAgIERXT1JEIHN0cmlkZTsKICAgIFVJTlQgUHJpbWl0aXZlQ291bnQ7CiAgICBXT1JEICpMb2NrZWRJbmRpY2VzOwogICAgSFJFU1VMVCBocjsKICAgIFdJTkVEM0RWRVJURVhCVUZGRVJfREVTQyBEZXNjOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlZCwlZCwlcCwlZCwlMDh4KVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgdmIsIFN0YXJ0VmVydGV4LCBOdW1WZXJ0aWNlcywgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwoKICAgIC8qIFN0ZXBzOgogICAgICogMSkgQ2FsY3VsYXRlIHNvbWUgdGhpbmdzOiBWZXJ0ZXggY291bnQgLT4gUHJpbWl0aXZlIGNvdW50LCBzdHJpZGUsIC4uLgogICAgICogMikgVXBsb2FkIHRoZSBJbmRpY2VzIHRvIHRoZSBpbmRleCBidWZmZXIKICAgICAqIDMpIFNldCB0aGUgaW5kZXggc291cmNlCiAgICAgKiA0KSBTZXQgdGhlIFZlcnRleCBCdWZmZXIgYXMgdGhlIFN0cmVhbSBzb3VyY2UKICAgICAqIDUpIENhbGwgSVdpbmVEM0REZXZpY2U6OkRyYXdJbmRleGVkUHJpbWl0aXZlCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHByaW1pdGl2ZSBjb3VudCAqLwogICAgc3dpdGNoKFByaW1pdGl2ZVR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RQVF9QT0lOVExJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50OwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC8gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX0xJTkVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDE7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLyAzOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUZBTjoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDogcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIEdldCB0aGUgRlZGIG9mIHRoZSB2ZXJ0ZXggYnVmZmVyLCBhbmQgaXRzIHN0cmlkZSAqLwogICAgaHIgPSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9HZXREZXNjKHZiLT53aW5lRDNEVmVydGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RWZXJ0ZXhCdWZmZXI6OkdldERlc2MgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICBzdHJpZGUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzYy5GVkYpOwogICAgVFJBQ0UoIlZlcnRleCBidWZmZXIgRlZGID0gJTA4eCwgc3RyaWRlPSVkXG4iLCBEZXNjLkZWRiwgc3RyaWRlKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT53aW5lRDNEVmVydGV4RGVjbGFyYXRpb24pOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIFNldHRpbmcgdGhlIEZWRiBmYWlsZWQsIGhyID0gJXghXG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogY29weSB0aGUgaW5kZXggc3RyZWFtIGludG8gdGhlIGluZGV4IGJ1ZmZlci4KICAgICAqIEEgbmV3IElXaW5lRDNERGV2aWNlIG1ldGhvZCBjb3VsZCBiZSBjcmVhdGVkCiAgICAgKiB3aGljaCB0YWtlcyBhbiB1c2VyIHBvaW50ZXIgY29udGFpbmluZyB0aGUgaW5kaWNlcwogICAgICogb3IgYSBTZXREYXRhLU1ldGhvZCBmb3IgdGhlIGluZGV4IGJ1ZmZlciwgd2hpY2gKICAgICAqIG92ZXJyaWRlcyB0aGUgaW5kZXggYnVmZmVyIGRhdGEgd2l0aCBvdXIgcG9pbnRlci4KICAgICAqLwogICAgaHIgPSBJV2luZUQzREluZGV4QnVmZmVyX0xvY2soVGhpcy0+aW5kZXhidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIE9mZlNldFRvTG9jayAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Q291bnQgKiBzaXplb2YoV09SRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSAqKikgJkxvY2tlZEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEZsYWdzICovKTsKICAgIGFzc2VydChJbmRleENvdW50IDwgMHgxMDAwMDApOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiKCVwKSBJV2luZUQzREluZGV4QnVmZmVyOjpMb2NrIGZhaWxlZCB3aXRoIGhyID0gJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgbWVtY3B5KExvY2tlZEluZGljZXMsIEluZGljZXMsIEluZGV4Q291bnQgKiBzaXplb2YoV09SRCkpOwogICAgaHIgPSBJV2luZUQzREluZGV4QnVmZmVyX1VubG9jayhUaGlzLT5pbmRleGJ1ZmZlcik7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNESW5kZXhCdWZmZXI6OlVubG9jayBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIGluZGV4IHN0cmVhbSAqLwogICAgSVdpbmVEM0REZXZpY2VfU2V0QmFzZVZlcnRleEluZGV4KFRoaXMtPndpbmVEM0REZXZpY2UsIFN0YXJ0VmVydGV4KTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0SW5kaWNlcyhUaGlzLT53aW5lRDNERGV2aWNlLCBUaGlzLT5pbmRleGJ1ZmZlcik7CgogICAgLyogU2V0IHRoZSB2ZXJ0ZXggc3RyZWFtIHNvdXJjZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTdHJlYW1Tb3VyY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RyZWFtTnVtYmVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPndpbmVEM0RWZXJ0ZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIG9mZnNldCwgd2UgcGFzcyB0aGlzIHRvIERyYXdJbmRleGVkUHJpbWl0aXZlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaWRlKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIiglcCkgSURpcmVjdDNERGV2aWNlOjpTZXRTdHJlYW1Tb3VyY2UgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd0luZGV4ZWRQcmltaXRpdmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBtaW5JbmRleCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RhcnRJbmRleCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQl9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICpEM0RWZXJ0ZXhCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQihpZmFjZSwgUHJpbWl0aXZlVHlwZSwgRDNEVmVydGV4QnVmLCBTdGFydFZlcnRleCwgTnVtVmVydGljZXMsIEluZGljZXMsIEluZGV4Q291bnQsIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKkQzRFZlcnRleEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhcnRWZXJ0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdJbmRleGVkUHJpbWl0aXZlVkIoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIEQzRFZlcnRleEJ1ZiwgU3RhcnRWZXJ0ZXgsIE51bVZlcnRpY2VzLCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlciAqRDNEVmVydGV4QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCAqVkIgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIsIEQzRFZlcnRleEJ1Zik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVkIsIEluZGljZXMsIEluZGV4Q291bnQsIEZsYWdzKTsKCiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRShWQiwgSURpcmVjdDNEVmVydGV4QnVmZmVyNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkNvbXB1dGVTcGhlcmVWaXNpYmlsaXR5CiAqCiAqIENhbGN1bGF0ZXMgdGhlIHZpc2liaWxpdHkgb2Ygc3BoZXJlcyBpbiB0aGUgY3VycmVudCB2aWV3cG9ydC4gVGhlIHNwaGVyZXMKICogYXJlIHBhc3NlZCBpbiB0aGUgQ2VudGVycyBhbmQgUmFkaWkgYXJyYXlzLCB0aGUgcmVzdWx0cyBhcmUgcGFzc2VkIGJhY2sKICogaW4gdGhlIFJldHVyblZhbHVlcyBhcnJheS4gUmV0dXJuIHZhbHVlcyBhcmUgZWl0aGVyIGNvbXBsZXRlbHkgdmlzaWJsZSwKICogcGFydGlhbGx5IHZpc2libGUgb3IgY29tcGxldGVseSBpbnZpc2libGUuCiAqIFRoZSByZXR1cm4gdmFsdWUgY29uc2lzdCBvZiBhIGNvbWJpbmF0aW9uIG9mIEQzRENMSVBfKiBmbGFncywgb3IgaXQncwogKiAwIGlmIHRoZSBzcGhlcmUgaXMgY29tcGxldGVseSB2aXNpYmxlKGFjY29yZGluZyB0byB0aGUgU0RLLCBub3QgY2hlY2tlZCkKICoKICogU291bmRzIGxpa2UgYW4gb3ZlcmRvc2Ugb2YgbWF0aCA7KQogKgogKiBWZXJzaW9uIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgQ2VudGVyczogQXJyYXkgY29udGFpbmluZyB0aGUgc3BoZXJlIGNlbnRlcnMKICogIFJhZGlpOiBBcnJheSBjb250YWluaW5nIHRoZSBzcGhlcmUgcmFkaWkKICogIE51bVNwaGVyZXM6IFRoZSBudW1iZXIgb2YgY2VudGVycyBhbmQgcmFkaWkgaW4gdGhlIGFycmF5cwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICogIFJldHVyblZhbHVlczogQXJyYXkgdG8gd3JpdGUgdGhlIHJlc3VsdHMgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqICAoRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDZW50ZXJzLCBSYWRpaSBvciBSZXR1cm5WYWx1ZXMgYXJlIE5VTEwpCiAqICAoRDNERVJSX0lOVkFMSURNQVRSSVggaWYgdGhlIGNvbWJpbmVkIHdvcmxkLCB2aWV3IGFuZCBwcm9qIG1hdHJpeAogKiAgaXMgc2luZ3VsYXIpCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19Db21wdXRlU3BoZXJlVmlzaWJpbGl0eShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFQ1RPUiAqQ2VudGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFICpSYWRpaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bVNwaGVyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpSZXR1cm5WYWx1ZXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJXAsJTA4eCwlMDh4LCVwKTogc3R1YiFcbiIsIFRoaXMsIENlbnRlcnMsIFJhZGlpLCBOdW1TcGhlcmVzLCBGbGFncywgUmV0dXJuVmFsdWVzKTsKCiAgICAvKiB0aGUgRGlyZWN0WCA3IHNkayBzYXlzIHRoYXQgdGhlIHZpc2liaWxpdHkgaXMgY29tcHV0ZWQgYnkKICAgICAqIGJhY2stdHJhbnNmb3JtaW5nIHRoZSB2aWV3aW5nIGZydXN0dW0gdG8gbW9kZWwgc3BhY2UKICAgICAqIHVzaW5nIHRoZSBpbnZlcnNlIG9mIHRoZSBjb21iaW5lZCB3b3JsZCwgdmlldyBhbmQgcHJvamVjdGlvbgogICAgICogbWF0cml4LiBJZiB0aGUgbWF0cml4IGNhbid0IGJlIHJldmVyc2VkLCBEM0RFUlJfSU5WQUxJRE1BVFJJWAogICAgICogaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQmFzaWMgaW1wbGVtZW50YXRpb24gaWRlYToKICAgICAqIDEpIENoZWNrIGlmIHRoZSBjZW50ZXIgaXMgaW4gdGhlIHZpZXdpbmcgZnJ1c3R1bQogICAgICogMikgQ3V0IHRoZSBzcGhlcmUgd2l0aCB0aGUgcGxhbmVzIG9mIHRoZSB2aWV3aW5nCiAgICAgKiAgICBmcnVzdHVtCiAgICAgKgogICAgICogLT5DZW50ZXIgaW5zaWRlIHRoZSBmcnVzdHVtLCBubyBpbnRlcnNlY3Rpb25zOgogICAgICogICAgRnVsbHkgdmlzaWJsZQogICAgICogLT5DZW50ZXIgb3V0c2lkZSB0aGUgZnJ1c3R1bSwgbm8gaW50ZXJzZWN0aW9uczoKICAgICAqICAgIE5vdCB2aXNpYmxlCiAgICAgKiAtPlNvbWUgaW50ZXJzZWN0aW9uczogUGFydGlhbGx5IHZpc2libGUKICAgICAqCiAgICAgKiBJbXBsZW1lbnQgdGhpcyBjYWxsIGluIFdpbmVEM0QuIEVpdGhlciBpbXBsZW1lbnQgdGhlCiAgICAgKiBtYXRyaXggYW5kIHZlY3RvciBzdHVmZiBpbiBXaW5lRDNELCBvciB1c2Ugc29tZSBleHRlcm5hbAogICAgICogbWF0aCBsaWJyYXJ5LgogICAgICovCgogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19Db21wdXRlU3BoZXJlVmlzaWJpbGl0eShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFQ1RPUiAqQ2VudGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFICpSYWRpaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bVNwaGVyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpSZXR1cm5WYWx1ZXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCwlMDh4LCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2VudGVycywgUmFkaWksIE51bVNwaGVyZXMsIEZsYWdzLCBSZXR1cm5WYWx1ZXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfQ29tcHV0ZVNwaGVyZVZpc2liaWxpdHkoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDZW50ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmFkaWksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1TcGhlcmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXR1cm5WYWx1ZXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0VGV4dHVyZQogKgogKiBSZXR1cm5zIHRoZSB0ZXh0dXJlIGludGVyZmFjZSBoYW5kbGUgYXNzaWduZWQgdG8gYSB0ZXh0dXJlIHN0YWdlLgogKiBUaGUgcmV0dXJuZWQgdGV4dHVyZSBpcyBBZGRSZWZlZC4gVGhpcyBpcyB0YWtlbiBmcm9tIG9sZCBkZHJhdywKICogbm90IGNoZWNrZWQgaW4gV2luZG93cy4KICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFN0YWdlOiBUZXh0dXJlIHN0YWdlIHRvIHJlYWQgdGhlIHRleHR1cmUgZnJvbQogKiAgVGV4dHVyZTogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFRleHR1cmUgaXMgTlVMTAogKiAgRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6R2V0VGV4dHVyZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKlRleHR1cmUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKlN1cmY7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBTdGFnZSwgVGV4dHVyZSk7CgogICAgaWYoIVRleHR1cmUpCiAgICB7CiAgICAgICAgVFJBQ0UoIlRleHR1cmUgPT0gTlVMTCwgZmFpbGluZyB3aXRoIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwgU3RhZ2UsICZTdXJmKTsKICAgIGlmKCAoaHIgIT0gRDNEX09LKSB8fCAoIVN1cmYpICkgCiAgICB7CiAgICAgICAgKlRleHR1cmUgPSBOVUxMOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIEdldFBhcmVudCBBZGRSZWYoKXMsIHdoaWNoIGlzIHBlcmZlY3RseSBPSy4KICAgICAqIFdlIGhhdmUgcGFzc2VkIHRoZSBJRGlyZWN0RHJhd1N1cmZhY2U3IGludGVyZmFjZSB0byBXaW5lRDNELCBzbyB0aGF0J3MgT0sgdG9vLgogICAgICovCiAgICBociA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0UGFyZW50KFN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgVGV4dHVyZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqVGV4dHVyZSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlKGlmYWNlLCBTdGFnZSwgVGV4dHVyZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VGV4dHVyZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipUZXh0dXJlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VGV4dHVyZShpZmFjZSwgU3RhZ2UsIFRleHR1cmUpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VGV4dHVyZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICoqVGV4dHVyZTIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIEhSRVNVTFQgcmV0OwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqcmV0X3ZhbDsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJWQsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhZ2UsIFRleHR1cmUyKTsKICAgIHJldCA9IElEaXJlY3QzRERldmljZTdfR2V0VGV4dHVyZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV0X3ZhbCk7CgogICAgKlRleHR1cmUyID0gQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3QzRFRleHR1cmUyLCByZXRfdmFsKTsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIgcmV0dXJuaW5nIGludGVyZmFjZSAlcC5cbiIsICpUZXh0dXJlMik7CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldFRleHR1cmUKICoKICogQXNzaWducyBhIHRleHR1cmUgdG8gYSB0ZXh0dXJlIHN0YWdlLiBJcyB0aGUgdGV4dHVyZSBBZGRSZWYtZWQ/CiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBTdGFnZTogVGhlIHN0YWdlIHRvIGFzc2lnbiB0aGUgdGV4dHVyZSB0bwogKiAgVGV4dHVyZTogSW50ZXJmYWNlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgc3VyZmFjZQogKgogKiBSZXR1cm5zCiAqIEQzRF9PSyBvbiBzdWNjZXNzCiAqIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFRleHR1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlRleHR1cmUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBUZXh0dXJlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIFN0YWdlLCBzdXJmKTsKCiAgICAvKiBUZXh0dXJlIG1heSBiZSBOVUxMIGhlcmUgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmID8gc3VyZi0+d2luZUQzRFRleHR1cmUgOiBOVUxMKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZV9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlRleHR1cmUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZShpZmFjZSwgU3RhZ2UsIFRleHR1cmUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmVfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpUZXh0dXJlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZShpZmFjZSwgU3RhZ2UsIFRleHR1cmUpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0VGV4dHVyZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICpUZXh0dXJlMikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqdGV4ID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZTIsIFRleHR1cmUyKTsKICAgIERXT1JEIHRleG1hcGJsZW5kOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJWQsJXApXG4iLCBUaGlzLCBTdGFnZSwgdGV4KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIGlmIChUaGlzLT5sZWdhY3lUZXh0dXJlQmxlbmRpbmcpCiAgICAgICAgSURpcmVjdDNERGV2aWNlM19HZXRSZW5kZXJTdGF0ZShpZmFjZSwgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BUEJMRU5ELCAmdGV4bWFwYmxlbmQpOwoKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodGV4LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CgogICAgaWYgKFRoaXMtPmxlZ2FjeVRleHR1cmVCbGVuZGluZyAmJiB0ZXhtYXBibGVuZCA9PSBEM0RUQkxFTkRfTU9EVUxBVEUpCiAgICB7CiAgICAgICAgLyogVGhpcyBmaXh1cCBpcyByZXF1aXJlZCBieSB0aGUgd2F5IEQzRFRCTEVORF9NT0RVTEFURSBtYXBzIHRvIHRleHR1cmUgc3RhZ2Ugc3RhdGVzLgogICAgICAgICAgIFNlZSBJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0UmVuZGVyU3RhdGUgZm9yIGRldGFpbHMuICovCiAgICAgICAgQk9PTCB0ZXhfYWxwaGEgPSBGQUxTRTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlICp0ZXggPSBOVUxMOwogICAgICAgIFdJTkVEM0RTVVJGQUNFX0RFU0MgZGVzYzsKICAgICAgICBXSU5FRDNERk9STUFUIGZtdDsKICAgICAgICBERFBJWEVMRk9STUFUIGRkZm10OwogICAgICAgIEhSRVNVTFQgcmVzdWx0OwoKICAgICAgICByZXN1bHQgPSBJV2luZUQzRERldmljZV9HZXRUZXh0dXJlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0ZXgpOwoKICAgICAgICBpZihyZXN1bHQgPT0gV0lORUQzRF9PSyAmJiB0ZXgpCiAgICAgICAgewogICAgICAgICAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICAgICAgICAgIGRlc2MuRm9ybWF0ID0gJmZtdDsKICAgICAgICAgICAgcmVzdWx0ID0gSVdpbmVEM0RUZXh0dXJlX0dldExldmVsRGVzYygoSVdpbmVEM0RUZXh0dXJlKikgdGV4LCAwLCAmZGVzYyk7CiAgICAgICAgICAgIGlmIChTVUNDRUVERUQocmVzdWx0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGRmbXQuZHdTaXplID0gc2l6ZW9mKGRkZm10KTsKICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZGZtdCwgZm10KTsKICAgICAgICAgICAgICAgIGlmIChkZGZtdC51NS5kd1JHQkFscGhhQml0TWFzaykgdGV4X2FscGhhID0gVFJVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHRleCk7CiAgICAgICAgfQoKICAgICAgICAvKiBhbHBoYW9wIGlzIFdJTkVEM0RUT1BfU0VMRUNUQVJHMSBpZiBpdCdzIEQzRFRCTEVORF9NT0RVTEFURSwgc28gb25seSBtb2RpZnkgYWxwaGFhcmcxICovCiAgICAgICAgaWYgKHRleF9hbHBoYSkKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFBUkcxLCBXSU5FRDNEVEFfVEVYVFVSRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFBUkcxLCBXSU5FRDNEVEFfQ1VSUkVOVCk7CiAgICAgICAgfQogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0VGV4dHVyZVN0YWdlU3RhdGUKICoKICogUmV0cmlldmVzIGEgc3RhdGUgZnJvbSBhIHRleHR1cmUgc3RhZ2UuCiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBTdGFnZTogVGhlIHN0YWdlIHRvIHJldHJpZXZlIHRoZSBzdGF0ZSBmcm9tCiAqICBUZXhTdGFnZVN0YXRlVHlwZTogVGhlIHN0YXRlIHR5cGUgdG8gcmV0cmlldmUKICogIFN0YXRlOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBzdGF0ZSdzIHZhbHVlIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBTdGF0ZSBpcyBOVUxMCiAqICBGb3IgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpHZXRUZXh0dXJlU3RhZ2VTdGF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlN0YXRlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwoKICAgIGlmKCFTdGF0ZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKFRleFN0YWdlU3RhdGVUeXBlKQogICAgewogICAgICAgIC8qIE1pcGZpbHRlciBpcyBhIHNhbXBsZXIgc3RhdGUgd2l0aCBkaWZmZXJlbnQgdmFsdWVzICovCiAgICAgICAgY2FzZSBEM0RUU1NfTUlQRklMVEVSOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHZhbHVlOwoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX01JUEZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZhbHVlKTsKICAgICAgICAgICAgc3dpdGNoKHZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX05PTkU6ICpTdGF0ZSA9IEQzRFRGUF9OT05FOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfUE9JTlQ6ICpTdGF0ZSA9IEQzRFRGUF9QT0lOVDsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0xJTkVBUjogKlN0YXRlID0gRDNEVEZQX0xJTkVBUjsgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBtaXBmaWx0ZXIgdmFsdWUgJWRcbiIsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAqU3RhdGUgPSBEM0RURlBfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8qIE1pbmZpbHRlciBpcyBhIHNhbXBsZXIgc3RhdGUgdG9vLCBlcXVhbCB2YWx1ZXMgKi8KICAgICAgICBjYXNlIEQzRFRTU19NSU5GSUxURVI6CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEU0FNUF9NSU5GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIC8qIE1hZ2ZpbHRlciBoYXMgc2xpZ2h0bHkgZGlmZmVyZW50IHZhbHVlcyAqLwogICAgICAgIGNhc2UgRDNEVFNTX01BR0ZJTFRFUjoKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSB3aW5lZDNkZmlsdGVyOwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUFHRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZWQzZGZpbHRlcik7CiAgICAgICAgICAgIHN3aXRjaCh3aW5lZDNkZmlsdGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX1BPSU5UOiAgICAgICAgICAgICAqU3RhdGUgPSBEM0RURkdfUE9JTlQ7ICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9MSU5FQVI6ICAgICAgICAgICAgKlN0YXRlID0gRDNEVEZHX0xJTkVBUjsgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfQU5JU09UUk9QSUM6ICAgICAgICpTdGF0ZSA9IEQzRFRGR19BTklTT1RST1BJQzsgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0ZMQVRDVUJJQzogICAgICAgICAqU3RhdGUgPSBEM0RURkdfRkxBVENVQklDOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9HQVVTU0lBTkNVQklDOiAgICAgKlN0YXRlID0gRDNEVEZHX0dBVVNTSUFOQ1VCSUM7ICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHdpbmVkM2QgbWFnIGZpbHRlciB2YWx1ZSAlZFxuIiwgd2luZWQzZGZpbHRlcik7CiAgICAgICAgICAgICAgICAgICAgKlN0YXRlID0gRDNEVEZHX1BPSU5UOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RUU1NfQUREUkVTUzoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVToKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFNTX0FERFJFU1NWOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmVTdGFnZVN0YXRlX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqU3RhdGUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VGV4dHVyZVN0YWdlU3RhdGUoaWZhY2UsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmVTdGFnZVN0YXRlX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqU3RhdGUpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZShpZmFjZSwgU3RhZ2UsIFRleFN0YWdlU3RhdGVUeXBlLCBTdGF0ZSk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlN0YXRlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfR2V0VGV4dHVyZVN0YWdlU3RhdGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0VGV4dHVyZVN0YWdlU3RhdGUKICoKICogU2V0cyBhIHRleHR1cmUgc3RhZ2Ugc3RhdGUuIFNvbWUgc3RhZ2UgdHlwZXMgbmVlZCB0byBiZSBoYW5kbGVkIHNwZWNpYWxseSwKICogYmVjYXVzZSB0aGV5IGRvIG5vdCBleGlzdCBpbiBXaW5lRDNEIGFuZCB3ZXJlIG1vdmVkIHRvIGFub3RoZXIgcGxhY2UKICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFN0YWdlOiBUaGUgc3RhZ2UgdG8gbW9kaWZ5CiAqICBUZXhTdGFnZVN0YXRlVHlwZTogVGhlIHN0YXRlIHRvIGNoYW5nZQogKiAgU3RhdGU6IFRoZSBuZXcgdmFsdWUgZm9yIHRoZSBzdGF0ZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFRleHR1cmVTdGFnZVN0YXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmVTdGFnZVN0YXRlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGF0ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4LCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goVGV4U3RhZ2VTdGF0ZVR5cGUpCiAgICB7CiAgICAgICAgLyogTWlwZmlsdGVyIGlzIGEgc2FtcGxlciBzdGF0ZSB3aXRoIGRpZmZlcmVudCB2YWx1ZXMgKi8KICAgICAgICBjYXNlIEQzRFRTU19NSVBGSUxURVI6CiAgICAgICAgewogICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgdmFsdWU7CiAgICAgICAgICAgIHN3aXRjaChTdGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBEM0RURlBfTk9ORTogdmFsdWUgPSBXSU5FRDNEVEVYRl9OT05FOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZQX1BPSU5UOiB2YWx1ZSA9IFdJTkVEM0RURVhGX1BPSU5UOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMDogLyogVW5jaGVja2VkICovCiAgICAgICAgICAgICAgICBjYXNlIEQzRFRGUF9MSU5FQVI6IHZhbHVlID0gV0lORUQzRFRFWEZfTElORUFSOyBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIG1pcGZpbHRlciB2YWx1ZSAlZFxuIiwgU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gV0lORUQzRFRFWEZfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUlQRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyogTWluZmlsdGVyIGlzIGEgc2FtcGxlciBzdGF0ZSB0b28sIGVxdWFsIHZhbHVlcyAqLwogICAgICAgIGNhc2UgRDNEVFNTX01JTkZJTFRFUjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX01JTkZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLyogTWFnZmlsdGVyIGhhcyBzbGlnaHRseSBkaWZmZXJlbnQgdmFsdWVzICovCiAgICAgICAgY2FzZSBEM0RUU1NfTUFHRklMVEVSOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHdpbmVkM2RmaWx0ZXI7CiAgICAgICAgICAgIHN3aXRjaCgoRDNEVEVYVFVSRU1BR0ZJTFRFUikgU3RhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZHX1BPSU5UOiAgICAgICAgICB3aW5lZDNkZmlsdGVyID0gV0lORUQzRFRFWEZfUE9JTlQ7ICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RURkdfTElORUFSOiAgICAgICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9MSU5FQVI7ICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzRFRGR19GTEFUQ1VCSUM6ICAgICAgd2luZWQzZGZpbHRlciA9IFdJTkVEM0RURVhGX0ZMQVRDVUJJQzsgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZHX0dBVVNTSUFOQ1VCSUM6ICB3aW5lZDNkZmlsdGVyID0gV0lORUQzRFRFWEZfR0FVU1NJQU5DVUJJQzsgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RURkdfQU5JU09UUk9QSUM6ICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9BTklTT1RST1BJQzsgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBkM2Q3IG1hZyBmaWx0ZXIgdHlwZSAlZFxuIiwgU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgfQogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUFHRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lZDNkZmlsdGVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTOgogICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICAvKiBEcm9wIHRocm91Z2ggKi8KICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVToKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NWLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZVN0YWdlU3RhdGVfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRFWFRVUkVTVEFHRVNUQVRFVFlQRSBUZXhTdGFnZVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXRlKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmVTdGFnZVN0YXRlKGlmYWNlLCBTdGFnZSwgVGV4U3RhZ2VTdGF0ZVR5cGUsIFN0YXRlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhdGUpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShpZmFjZSwgU3RhZ2UsIFRleFN0YWdlU3RhdGVUeXBlLCBTdGF0ZSk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhdGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBTdGFnZSwgVGV4U3RhZ2VTdGF0ZVR5cGUsIFN0YXRlKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1NldFRleHR1cmVTdGFnZVN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXhTdGFnZVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlZhbGlkYXRlRGV2aWNlCiAqCiAqIFNESzogIlJlcG9ydHMgdGhlIGRldmljZSdzIGFiaWxpdHkgdG8gcmVuZGVyIHRoZSBjdXJyZW50bHkgc2V0CiAqIHRleHR1cmUtYmxlbmRpbmcgb3BlcmF0aW9ucyBpbiBhIHNpbmdsZSBwYXNzIi4gV2hhdGV2ZXIgdGhhdCBtZWFucwogKiBleGFjdGx5Li4uCiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBOdW1QYXNzZXM6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIG51bWJlciBvZiBuZWNlc3NhcnkgcGFzc2VzIGZvciB0aGUKICogICAgICAgICAgICAgZGVzaXJlZCBlZmZlY3QgdG8uCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNERGV2aWNlOjpWYWxpZGF0ZURldmljZSBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X1ZhbGlkYXRlRGV2aWNlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKk51bVBhc3NlcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgTnVtUGFzc2VzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9WYWxpZGF0ZURldmljZShUaGlzLT53aW5lRDNERGV2aWNlLCBOdW1QYXNzZXMpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19WYWxpZGF0ZURldmljZV9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpOdW1QYXNzZXMpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfVmFsaWRhdGVEZXZpY2UoaWZhY2UsIE51bVBhc3Nlcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfVmFsaWRhdGVEZXZpY2VfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqTnVtUGFzc2VzKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfVmFsaWRhdGVEZXZpY2UoaWZhY2UsIE51bVBhc3Nlcyk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19WYWxpZGF0ZURldmljZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpQYXNzZXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBQYXNzZXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfVmFsaWRhdGVEZXZpY2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzZXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6Q2xlYXIKICoKICogRmlsbHMgdGhlIHJlbmRlciB0YXJnZXQsIHRoZSB6IGJ1ZmZlciBhbmQgdGhlIHN0ZW5jaWwgYnVmZmVyIHdpdGggYQogKiBjbGVhciBjb2xvciAvIHZhbHVlCiAqCiAqIFZlcnNpb24gNyBvbmx5CiAqCiAqIFBhcmFtczoKICogIENvdW50OiBOdW1iZXIgb2YgcmVjdGFuZ2xlcyBpbiBSZWN0cyBtdXN0IGJlIDAgaWYgUmVjdHMgaXMgTlVMTAogKiAgUmVjdHM6IFJlY3RhbmdsZXMgdG8gY2xlYXIuIElmIE5VTEwsIHRoZSB3aG9sZSBzdXJmYWNlIGlzIGNsZWFyZWQKICogIEZsYWdzOiBTb21lIGZsYWdzLCBhcyB1c3VhbAogKiAgQ29sb3I6IENsZWFyIGNvbG9yIGZvciB0aGUgcmVuZGVyIHRhcmdldAogKiAgWjogQ2xlYXIgdmFsdWUgZm9yIHRoZSBaIGJ1ZmZlcgogKiAgU3RlbmNpbDogQ2xlYXIgdmFsdWUgdG8gc3RvcmUgaW4gZWFjaCBzdGVuY2lsIGJ1ZmZlciBlbnRyeQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkNsZWFyCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0NsZWFyKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRUNUICpSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1IgQ29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSBaLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RlbmNpbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlMDh4LCUwOHgsJWYsJTA4eCk6IFJlbGF5XG4iLCBUaGlzLCBDb3VudCwgUmVjdHMsIEZsYWdzLCBDb2xvciwgWiwgU3RlbmNpbCk7CgogICAgLyogTm90ZTsgRDNEUkVDVCBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRFJFQ1QgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0NsZWFyKFRoaXMtPndpbmVEM0REZXZpY2UsIENvdW50LCAoV0lORUQzRFJFQ1QqKSBSZWN0cywgRmxhZ3MsIENvbG9yLCBaLCBTdGVuY2lsKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2xlYXJfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFQ1QgKlJlY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUiBDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFIFosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGVuY2lsKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0NsZWFyKGlmYWNlLCBDb3VudCwgUmVjdHMsIEZsYWdzLCBDb2xvciwgWiwgU3RlbmNpbCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2xlYXJfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFQ1QgKlJlY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUiBDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFIFosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGVuY2lsKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2xlYXIoaWZhY2UsIENvdW50LCBSZWN0cywgRmxhZ3MsIENvbG9yLCBaLCBTdGVuY2lsKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0Vmlld3BvcnQKICoKICogU2V0cyB0aGUgY3VycmVudCB2aWV3cG9ydC4KICoKICogVmVyc2lvbiA3IG9ubHksIGJ1dCBJRGlyZWN0M0RWaWV3cG9ydCB1c2VzIHRoaXMgY2FsbCBmb3Igb2xkZXIKICogdmVyc2lvbnMKICoKICogUGFyYW1zOgogKiAgRGF0YTogVGhlIG5ldyB2aWV3cG9ydCB0byBzZXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lREREZXZpY2U6OlNldFZpZXdwb3J0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFZpZXdwb3J0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVklFV1BPUlQ3ICpEYXRhKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCkgUmVsYXkhXG4iLCBUaGlzLCBEYXRhKTsKCiAgICBpZighRGF0YSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBOb3RlOiBEM0RWSUVXUE9SVDcgaXMgY29tcGF0aWJsZSB3aXRoIFdJTkVEM0RWSUVXUE9SVCAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RWSUVXUE9SVCopIERhdGEpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRWaWV3cG9ydF9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZJRVdQT1JUNyAqRGF0YSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19TZXRWaWV3cG9ydChpZmFjZSwgRGF0YSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Vmlld3BvcnRfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWSUVXUE9SVDcgKkRhdGEpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19TZXRWaWV3cG9ydChpZmFjZSwgRGF0YSk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6R2V0Vmlld3BvcnQKICoKICogUmV0dXJucyB0aGUgY3VycmVudCB2aWV3cG9ydAogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgRGF0YTogRDNEN1ZpZXdwb3J0IHN0cnVjdHVyZSB0byB3cml0ZSB0aGUgdmlld3BvcnQgaW5mb3JtYXRpb24gdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpHZXRWaWV3cG9ydAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19HZXRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZJRVdQT1JUNyAqRGF0YSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApIFJlbGF5IVxuIiwgVGhpcywgRGF0YSk7CgogICAgaWYoIURhdGEpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogTm90ZTogRDNEVklFV1BPUlQ3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNEVklFV1BPUlQgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFZpZXdwb3J0KFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNEVklFV1BPUlQqKSBEYXRhKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Vmlld3BvcnRfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWSUVXUE9SVDcgKkRhdGEpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Vmlld3BvcnQoaWZhY2UsIERhdGEpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFZpZXdwb3J0X0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVklFV1BPUlQ3ICpEYXRhKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Vmlld3BvcnQoaWZhY2UsIERhdGEpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpTZXRNYXRlcmlhbAogKgogKiBTZXRzIHRoZSBNYXRlcmlhbAogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgTWF0OiBUaGUgbWF0ZXJpYWwgdG8gc2V0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBNYXQgaXMgTlVMTC4KICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6U2V0TWF0ZXJpYWwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0TWF0ZXJpYWwoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRFUklBTDcgKk1hdCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheSFcbiIsIFRoaXMsIE1hdCk7CgogICAgLyogTm90ZTogRDNETUFURVJJQUw3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETUFURVJJQUwgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldE1hdGVyaWFsKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFURVJJQUwqKSBNYXQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldE1hdGVyaWFsX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFURVJJQUw3ICpNYXQpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0TWF0ZXJpYWwoaWZhY2UsIE1hdCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0TWF0ZXJpYWxfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRFUklBTDcgKk1hdCkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldE1hdGVyaWFsKGlmYWNlLCBNYXQpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRNYXRlcmlhbAogKgogKiBSZXR1cm5zIHRoZSBjdXJyZW50IG1hdGVyaWFsCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBNYXQ6IEQzRE1BVEVSSUFMNyBzdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIG1hdGVyaWFsIHBhcmFtZXRlcnMgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIE1hdCBpcyBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldE1hdGVyaWFsCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldE1hdGVyaWFsKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFURVJJQUw3ICpNYXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXkhXG4iLCBUaGlzLCBNYXQpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAvKiBOb3RlOiBEM0RNQVRFUklBTDcgaXMgY29tcGF0aWJsZSB3aXRoIFdJTkVEM0RNQVRFUklBTCAqLyAKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0TWF0ZXJpYWwoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RNQVRFUklBTCopIE1hdCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TWF0ZXJpYWxfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRFUklBTDcgKk1hdCkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19HZXRNYXRlcmlhbChpZmFjZSwgTWF0KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRNYXRlcmlhbF9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVEVSSUFMNyAqTWF0KQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TWF0ZXJpYWwoaWZhY2UsIE1hdCk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldExpZ2h0CiAqCiAqIEFzc2lnbnMgYSBsaWdodCB0byBhIGxpZ2h0IGluZGV4LCBidXQgZG9lc24ndCBhY3RpdmF0ZSBpdCB5ZXQuCiAqCiAqIFZlcnNpb24gNywgSURpcmVjdDNETGlnaHQgdXNlcyB0aGlzIG1ldGhvZCBmb3Igb2xkZXIgdmVyc2lvbnMKICoKICogUGFyYW1zOgogKiAgTGlnaHRJbmRleDogVGhlIGluZGV4IG9mIHRoZSBuZXcgbGlnaHQKICogIExpZ2h0OiBBIEQzRExJR0hUNyBzdHJ1Y3R1cmUgZGVzY3JpYmluZyB0aGUgbGlnaHQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OlNldExpZ2h0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUNyAqTGlnaHQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIExpZ2h0SW5kZXgsIExpZ2h0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogTm90ZTogRDNETElHSFQ3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETElHSFQgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0TGlnaHQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RMSUdIVCopIExpZ2h0KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRMaWdodF9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RMSUdIVDcgKkxpZ2h0KQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0KGlmYWNlLCBMaWdodEluZGV4LCBMaWdodCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0TGlnaHRfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBMaWdodEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETElHSFQ3ICpMaWdodCkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0KGlmYWNlLCBMaWdodEluZGV4LCBMaWdodCk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldExpZ2h0CiAqCiAqIFJldHVybnMgdGhlIGxpZ2h0IGFzc2lnbmVkIHRvIGEgbGlnaHQgaW5kZXgKICoKICogUGFyYW1zOgogKiAgTGlnaHQ6IFN0cnVjdHVyZSB0byB3cml0ZSB0aGUgbGlnaHQgaW5mb3JtYXRpb24gdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIExpZ2h0IGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldExpZ2h0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUNyAqTGlnaHQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgcmM7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIExpZ2h0SW5kZXgsIExpZ2h0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogTm90ZTogRDNETElHSFQ3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETElHSFQgKi8KICAgIHJjID0gIElXaW5lRDNERGV2aWNlX0dldExpZ2h0KFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaWdodEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RMSUdIVCopIExpZ2h0KTsKCiAgICAvKiBUcmFuc2xhdGUgdGhlIHJlc3VsdC4gV2luZUQzRCByZXR1cm5zIG90aGVyIHZhbHVlcyB0aGFuIEQzRDcgKi8KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKHJjKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodF9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RMSUdIVDcgKkxpZ2h0KQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0KGlmYWNlLCBMaWdodEluZGV4LCBMaWdodCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TGlnaHRfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBMaWdodEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETElHSFQ3ICpMaWdodCkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0KGlmYWNlLCBMaWdodEluZGV4LCBMaWdodCk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkJlZ2luU3RhdGVCbG9jawogKgogKiBCZWdpbnMgcmVjb3JkaW5nIHRvIGEgc3RhdGVibG9jawogKgogKiBWZXJzaW9uIDcKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OkJlZ2luU3RhdGVCbG9jawogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19CZWdpblN0YXRlQmxvY2soSURpcmVjdDNERGV2aWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCk6IFJlbGF5IVxuIiwgVGhpcyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQmVnaW5TdGF0ZUJsb2NrKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9ja19GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19CZWdpblN0YXRlQmxvY2soaWZhY2UpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9ja19GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9jayhpZmFjZSk7CiAgICBzZXRfZnB1X2NvbnRyb2xfd29yZChvbGRfZnB1Y3cpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkVuZFN0YXRlQmxvY2sKICoKICogU3RvcHMgcmVjb3JkaW5nIHRvIGEgc3RhdGUgYmxvY2sgYW5kIHJldHVybnMgdGhlIGNyZWF0ZWQgc3RhdGVibG9jawogKiBoYW5kbGUuCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBCbG9ja0hhbmRsZTogQWRkcmVzcyB0byBzdG9yZSB0aGUgc3RhdGVibG9jaydzIGhhbmRsZSB0bwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgQmxvY2tIYW5kbGUgaXMgTlVMTAogKiAgU2VlIElXaW5lRDNERGV2aWNlOjpFbmRTdGF0ZUJsb2NrIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU3RhdGVCbG9jayhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKkJsb2NrSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5IVxuIiwgVGhpcywgQmxvY2tIYW5kbGUpOwoKICAgIGlmKCFCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBXQVJOKCJCbG9ja0hhbmRsZSA9PSBOVUxMLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpCbG9ja0hhbmRsZSA9IElEaXJlY3QzRERldmljZUltcGxfQ3JlYXRlSGFuZGxlKFRoaXMpOwogICAgaWYoISpCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBnZXQgYSBoYW5kbGUgbnVtYmVyIGZvciB0aGUgc3RhdGVibG9ja1xuIik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUaGlzLT5IYW5kbGVzWypCbG9ja0hhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9TdGF0ZUJsb2NrOwogICAgaHIgPSBJV2luZUQzRERldmljZV9FbmRTdGF0ZUJsb2NrKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElXaW5lRDNEU3RhdGVCbG9jayAqKikgJlRoaXMtPkhhbmRsZXNbKkJsb2NrSGFuZGxlIC0gMV0ucHRyKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19FbmRTdGF0ZUJsb2NrX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQmxvY2tIYW5kbGUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU3RhdGVCbG9jayhpZmFjZSwgQmxvY2tIYW5kbGUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0VuZFN0YXRlQmxvY2tfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpCbG9ja0hhbmRsZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0VuZFN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6UHJlTG9hZAogKgogKiBBbGxvd3MgdGhlIGFwcCB0byBzaWduYWwgdGhhdCBhIHRleHR1cmUgd2lsbCBiZSB1c2VkIHNvb24sIHRvIGFsbG93CiAqIHRoZSBEaXJlY3QzRERldmljZSB0byBsb2FkIGl0IHRvIHRoZSB2aWRlbyBjYXJkIGluIHRoZSBtZWFudGltZS4KICoKICogVmVyc2lvbiA3CiAqCiAqIFBhcmFtczoKICogIFRleHR1cmU6IFRoZSB0ZXh0dXJlIHRvIHByZWxvYWQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFRleHR1cmUgaXMgTlVMTAogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6UHJlTG9hZCBmb3IgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19QcmVMb2FkKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpUZXh0dXJlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgVGV4dHVyZSk7CgogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5IVxuIiwgVGhpcywgc3VyZik7CgogICAgaWYoIVRleHR1cmUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHN1cmYtPldpbmVEM0RTdXJmYWNlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1ByZUxvYWRfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlRleHR1cmUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfUHJlTG9hZChpZmFjZSwgVGV4dHVyZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfUHJlTG9hZF9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqVGV4dHVyZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X1ByZUxvYWQoaWZhY2UsIFRleHR1cmUpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpBcHBseVN0YXRlQmxvY2sKICoKICogQWN0aXZhdGVzIHRoZSBzdGF0ZSBzdG9yZWQgaW4gYSBzdGF0ZSBibG9jayBoYW5kbGUuCiAqCiAqIFBhcmFtczoKICogIEJsb2NrSGFuZGxlOiBUaGUgc3RhdGVibG9jayBoYW5kbGUgdG8gYWN0aXZhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0sgaWYgQmxvY2tIYW5kbGUgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2soSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIEJsb2NrSGFuZGxlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoIUJsb2NrSGFuZGxlIHx8IEJsb2NrSGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBXQVJOKCJPdXQgb2YgcmFuZ2UgaGFuZGxlICVkLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURTVEFURUJMT0NLXG4iLCBCbG9ja0hhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRDNERVJSX0lOVkFMSURTVEFURUJMT0NLOwogICAgfQogICAgaWYoVGhpcy0+SGFuZGxlc1tCbG9ja0hhbmRsZSAtIDFdLnR5cGUgIT0gRERyYXdIYW5kbGVfU3RhdGVCbG9jaykKICAgIHsKICAgICAgICBXQVJOKCJIYW5kbGUgJWQgaXMgbm90IGEgc3RhdGVibG9jaywgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DS1xuIiwgQmxvY2tIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSzsKICAgIH0KCiAgICBociA9IElXaW5lRDNEU3RhdGVCbG9ja19BcHBseSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0FwcGx5U3RhdGVCbG9ja19GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBCbG9ja0hhbmRsZSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2tfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6Q2FwdHVyZVN0YXRlQmxvY2sKICoKICogVXBkYXRlcyBhIHN0YXRlYmxvY2sncyB2YWx1ZXMgdG8gdGhlIHZhbHVlcyBjdXJyZW50bHkgc2V0IGZvciB0aGUgZGV2aWNlCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBCbG9ja0hhbmRsZTogU3RhdGVibG9jayB0byB1cGRhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0sgaWYgQmxvY2tIYW5kbGUgaXMgTlVMTAogKiAgU2VlIElXaW5lRDNERGV2aWNlOjpDYXB0dXJlU3RhdGVCbG9jayBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0NhcHR1cmVTdGF0ZUJsb2NrKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIEJsb2NrSGFuZGxlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoQmxvY2tIYW5kbGUgPT0gMCB8fCBCbG9ja0hhbmRsZSA+IFRoaXMtPm51bUhhbmRsZXMpCiAgICB7CiAgICAgICAgV0FSTigiT3V0IG9mIHJhbmdlIGhhbmRsZSAlZCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DS1xuIiwgQmxvY2tIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSzsKICAgIH0KICAgIGlmKFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX1N0YXRlQmxvY2spCiAgICB7CiAgICAgICAgV0FSTigiSGFuZGxlICVkIGlzIG5vdCBhIHN0YXRlYmxvY2ssIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0tcbiIsIEJsb2NrSGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0s7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN0YXRlQmxvY2tfQ2FwdHVyZSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0NhcHR1cmVTdGF0ZUJsb2NrX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2FwdHVyZVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19DYXB0dXJlU3RhdGVCbG9ja19GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJsb2NrSGFuZGxlKQp7CiAgICBIUkVTVUxUIGhyOwogICAgV09SRCBvbGRfZnB1Y3c7CgogICAgb2xkX2ZwdWN3ID0gZDNkX2ZwdV9zZXR1cCgpOwogICAgaHIgPSBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2FwdHVyZVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RGVsZXRlU3RhdGVCbG9jawogKgogKiBEZWxldGVzIGEgc3RhdGVibG9jayBoYW5kbGUuIFRoaXMgbWVhbnMgcmVsZWFzaW5nIHRoZSBXaW5lRDNEU3RhdGVCbG9jawogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgQmxvY2tIYW5kbGU6IFN0YXRlYmxvY2sgaGFuZGxlIHRvIGRlbGV0ZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSyBpZiBCbG9ja0hhbmRsZSBpcyAwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0RlbGV0ZVN0YXRlQmxvY2soSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJsb2NrSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBVTE9ORyByZWY7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIEJsb2NrSGFuZGxlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoQmxvY2tIYW5kbGUgPT0gMCB8fCBCbG9ja0hhbmRsZSA+IFRoaXMtPm51bUhhbmRsZXMpCiAgICB7CiAgICAgICAgV0FSTigiT3V0IG9mIHJhbmdlIGhhbmRsZSAlZCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DS1xuIiwgQmxvY2tIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSzsKICAgIH0KICAgIGlmKFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX1N0YXRlQmxvY2spCiAgICB7CiAgICAgICAgV0FSTigiSGFuZGxlICVkIGlzIG5vdCBhIHN0YXRlYmxvY2ssIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0tcbiIsIEJsb2NrSGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0s7CiAgICB9CgogICAgcmVmID0gSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayAqKSBUaGlzLT5IYW5kbGVzW0Jsb2NrSGFuZGxlIC0gMV0ucHRyKTsKICAgIGlmKHJlZikKICAgIHsKICAgICAgICBFUlIoIlNvbWV0aGluZyBpcyBzdGlsbCBob2xkaW5nIHRoZSBzdGF0ZWJsb2NrICVwKEhhbmRsZSAlZCkuIFJlZiA9ICVkXG4iLCBUaGlzLT5IYW5kbGVzW0Jsb2NrSGFuZGxlIC0gMV0ucHRyLCBCbG9ja0hhbmRsZSwgcmVmKTsKICAgIH0KICAgIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIgPSBOVUxMOwogICAgVGhpcy0+SGFuZGxlc1tCbG9ja0hhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9Vbmtub3duOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0RlbGV0ZVN0YXRlQmxvY2tfRlBVU2V0dXAoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJsb2NrSGFuZGxlKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0RlbGV0ZVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EZWxldGVTdGF0ZUJsb2NrX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBCbG9ja0hhbmRsZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0RlbGV0ZVN0YXRlQmxvY2soaWZhY2UsIEJsb2NrSGFuZGxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6Q3JlYXRlU3RhdGVCbG9jawogKgogKiBDcmVhdGVzIGEgbmV3IHN0YXRlIGJsb2NrIGhhbmRsZS4KICoKICogVmVyc2lvbiA3CiAqCiAqIFBhcmFtczoKICogIFR5cGU6IFRoZSBzdGF0ZSBibG9jayB0eXBlCiAqICBCbG9ja0hhbmRsZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgY3JlYXRlZCBoYW5kbGUgdG8KICoKICogUmV0dXJuczoKICogICBEM0RfT0sgb24gc3VjY2VzcwogKiAgIERERVJSX0lOVkFMSURQQVJBTVMgaWYgQmxvY2tIYW5kbGUgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3QzRERldmljZUltcGxfN19DcmVhdGVTdGF0ZUJsb2NrKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RTVEFURUJMT0NLVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApIVxuIiwgVGhpcywgVHlwZSwgQmxvY2tIYW5kbGUpOwoKICAgIGlmKCFCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBXQVJOKCJCbG9ja0hhbmRsZSA9PSBOVUxMLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CiAgICBpZihUeXBlICE9IEQzRFNCVF9BTEwgICAgICAgICAmJiBUeXBlICE9IEQzRFNCVF9QSVhFTFNUQVRFICYmCiAgICAgICBUeXBlICE9IEQzRFNCVF9WRVJURVhTVEFURSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgewogICAgICAgIFdBUk4oIlVuZXhwZWN0ZWQgc3RhdGVibG9jayB0eXBlLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpCbG9ja0hhbmRsZSA9IElEaXJlY3QzRERldmljZUltcGxfQ3JlYXRlSGFuZGxlKFRoaXMpOwogICAgaWYoISpCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBnZXQgYSBoYW5kbGUgbnVtYmVyIGZvciB0aGUgc3RhdGVibG9ja1xuIik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUaGlzLT5IYW5kbGVzWypCbG9ja0hhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9TdGF0ZUJsb2NrOwoKICAgIC8qIFRoZSBEM0RTVEFURUJMT0NLVFlQRSBlbnVtIGlzIGZpbmUgaGVyZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVTdGF0ZUJsb2NrKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdGF0ZUJsb2NrICoqKSAmVGhpcy0+SGFuZGxlc1sqQmxvY2tIYW5kbGUgLSAxXS5wdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBQYXJlbnQsIGhvcGUgdGhhdCB3b3JrcyAqLyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ3JlYXRlU3RhdGVCbG9ja19GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEU1RBVEVCTE9DS1RZUEUgVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKkJsb2NrSGFuZGxlKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X0NyZWF0ZVN0YXRlQmxvY2soaWZhY2UsIFR5cGUsIEJsb2NrSGFuZGxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19DcmVhdGVTdGF0ZUJsb2NrX0ZQVVByZXNlcnZlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RTVEFURUJMT0NLVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQmxvY2tIYW5kbGUpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9SURpcmVjdDNERGV2aWNlSW1wbF83X0NyZWF0ZVN0YXRlQmxvY2soaWZhY2UsIFR5cGUsIEJsb2NrSGFuZGxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKiBIZWxwZXIgZnVuY3Rpb24gZm9yIElEaXJlY3QzRERldmljZUltcGxfN19Mb2FkLiAqLwpzdGF0aWMgQk9PTCBpc19taXBfbGV2ZWxfc3Vic2V0KElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3JjKQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzcmNfbGV2ZWwsICpkZXN0X2xldmVsOwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqdGVtcDsKICAgIEREU1VSRkFDRURFU0MyIGRkc2Q7CiAgICBCT09MIGxldmVsRm91bmQ7IC8qIGF0IGxlYXN0IG9uZSBzdWl0YWJsZSBzdWJsZXZlbCBpbiBkZXN0IGZvdW5kICovCgogICAgLyogVG8gc2F0aXNmeSAiZGVzdGluYXRpb24gaXMgbWlwIGxldmVsIHN1YnNldCBvZiBzb3VyY2UiIGNyaXRlcmlhIChyZWd1bGFyIHRleHR1cmUgY291bnRzIGFzIDEgbGV2ZWwpLAogICAgICogMSkgdGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgbWlwIGxldmVsIGluIGRlc3RpbmF0aW9uIHRoYXQgbWF0Y2hlZCBkaW1lbnNpb25zIG9mIHNvbWUgbWlwIGxldmVsIGluIHNvdXJjZSBhbmQKICAgICAqIDIpIHRoZXJlIG11c3QgYmUgbm8gZGVzdGluYXRpb24gbGV2ZWxzIHRoYXQgZG9uJ3QgbWF0Y2ggYW55IGxldmVscyBpbiBzb3VyY2UuIE90aGVyd2lzZSBpdCdzIElOVkFMSURQQVJBTVMuCiAgICAgKi8KICAgIGxldmVsRm91bmQgPSBGQUxTRTsKCiAgICBzcmNfbGV2ZWwgPSBzcmM7CiAgICBkZXN0X2xldmVsID0gZGVzdDsKCiAgICBmb3IgKDtzcmNfbGV2ZWwgJiYgZGVzdF9sZXZlbDspCiAgICB7CiAgICAgICAgaWYgKHNyY19sZXZlbC0+c3VyZmFjZV9kZXNjLmR3V2lkdGggPT0gZGVzdF9sZXZlbC0+c3VyZmFjZV9kZXNjLmR3V2lkdGggJiYKICAgICAgICAgICAgc3JjX2xldmVsLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQgPT0gZGVzdF9sZXZlbC0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgbGV2ZWxGb3VuZCA9IFRSVUU7CgogICAgICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19URVhUVVJFOwogICAgICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzMiA9IEREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShkZXN0X2xldmVsLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRkc2QuZGRzQ2FwcywgJnRlbXApOwoKICAgICAgICAgICAgaWYgKGRlc3RfbGV2ZWwgIT0gZGVzdCkgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRlc3RfbGV2ZWwsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKCiAgICAgICAgICAgIGRlc3RfbGV2ZWwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCB0ZW1wKTsKICAgICAgICB9CgogICAgICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX1RFWFRVUkU7CiAgICAgICAgZGRzZC5kZHNDYXBzLmR3Q2FwczIgPSBERFNDQVBTMl9NSVBNQVBTVUJMRVZFTDsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShzcmNfbGV2ZWwsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGRzZC5kZHNDYXBzLCAmdGVtcCk7CgogICAgICAgIGlmIChzcmNfbGV2ZWwgIT0gc3JjKSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0Uoc3JjX2xldmVsLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CgogICAgICAgIHNyY19sZXZlbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHRlbXApOwogICAgfQoKICAgIGlmIChzcmNfbGV2ZWwgJiYgc3JjX2xldmVsICE9IHNyYykgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKHNyY19sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgaWYgKGRlc3RfbGV2ZWwgJiYgZGVzdF9sZXZlbCAhPSBkZXN0KSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGVzdF9sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwoKICAgIHJldHVybiAhZGVzdF9sZXZlbCAmJiBsZXZlbEZvdW5kOwp9CgovKiBIZWxwZXIgZnVuY3Rpb24gZm9yIElEaXJlY3QzRERldmljZUltcGxfN19Mb2FkLiAqLwpzdGF0aWMgdm9pZCBjb3B5X21pcG1hcF9jaGFpbihJRGlyZWN0M0REZXZpY2VJbXBsICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9JTlQgKkRlc3RQb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3JjX2xldmVsLCAqZGVzdF9sZXZlbDsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKnRlbXA7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwogICAgUE9JTlQgcG9pbnQ7CiAgICBSRUNUIHJlY3Q7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdQYWxldHRlICpwYWwgPSBOVUxMLCAqcGFsX3NyYyA9IE5VTEw7CiAgICBEV09SRCBja2V5ZmxhZzsKICAgIEREQ09MT1JLRVkgZGRja2V5OwoKICAgIHNyY19sZXZlbCA9IHNyYzsKICAgIGRlc3RfbGV2ZWwgPSBkZXN0OwoKICAgIHBvaW50ID0gKkRlc3RQb2ludDsKICAgIHJlY3QgPSAqU3JjUmVjdDsKCiAgICBmb3IgKDtzcmNfbGV2ZWwgJiYgZGVzdF9sZXZlbDspCiAgICB7CiAgICAgICAgaWYgKHNyY19sZXZlbC0+c3VyZmFjZV9kZXNjLmR3V2lkdGggPT0gZGVzdF9sZXZlbC0+c3VyZmFjZV9kZXNjLmR3V2lkdGggJiYKICAgICAgICAgICAgc3JjX2xldmVsLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQgPT0gZGVzdF9sZXZlbC0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgLyogVHJ5IFVwZGF0ZVN1cmZhY2UgdGhhdCBtYXkgcGVyZm9ybSBhIG1vcmUgZGlyZWN0IG9wZW5nbCBsb2FkaW5nLiAqLwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoZGV2aWNlLT53aW5lRDNERGV2aWNlLCBzcmNfbGV2ZWwtPldpbmVEM0RTdXJmYWNlLCAmcmVjdCwgZGVzdF9sZXZlbC0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBvaW50KTsKICAgICAgICAgICAgaWYgKEZBSUxFRChocikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFVwZGF0ZVN1cmZhY2UgbWF5IGZhaWwgZS5nLiBpZiBkZXN0IGlzIGluIHN5c3RlbSBtZW1vcnkuIEZhbGwgYmFjayB0byBCbHRGYXN0IHRoYXQgaXMgbGVzcyBzdHJpY3QuICovCiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfQmx0RmFzdChkZXN0X2xldmVsLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50LngsIHBvaW50LnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNfbGV2ZWwtPldpbmVEM0RTdXJmYWNlLCAmcmVjdCwgMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX1RFWFRVUkU7CiAgICAgICAgICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMyID0gRERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKGRlc3RfbGV2ZWwsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGRzZC5kZHNDYXBzLCAmdGVtcCk7CgogICAgICAgICAgICBpZiAoZGVzdF9sZXZlbCAhPSBkZXN0KSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGVzdF9sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwoKICAgICAgICAgICAgZGVzdF9sZXZlbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHRlbXApOwogICAgICAgIH0KCiAgICAgICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfVEVYVFVSRTsKICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzMiA9IEREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKHNyY19sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNyksICZkZHNkLmRkc0NhcHMsICZ0ZW1wKTsKCiAgICAgICAgaWYgKHNyY19sZXZlbCAhPSBzcmMpIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShzcmNfbGV2ZWwsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKCiAgICAgICAgc3JjX2xldmVsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgdGVtcCk7CgogICAgICAgIHBvaW50LnggLz0gMjsKICAgICAgICBwb2ludC55IC89IDI7CgogICAgICAgIHJlY3QudG9wIC89IDI7CiAgICAgICAgcmVjdC5sZWZ0IC89IDI7CiAgICAgICAgcmVjdC5yaWdodCA9IChyZWN0LnJpZ2h0ICsgMSkgLyAyOwogICAgICAgIHJlY3QuYm90dG9tID0gKHJlY3QuYm90dG9tICsgMSkgLyAyOwogICAgfQoKICAgIGlmIChzcmNfbGV2ZWwgJiYgc3JjX2xldmVsICE9IHNyYykgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKHNyY19sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgaWYgKGRlc3RfbGV2ZWwgJiYgZGVzdF9sZXZlbCAhPSBkZXN0KSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGVzdF9sZXZlbCwgSURpcmVjdERyYXdTdXJmYWNlNykpOwoKICAgIC8qIENvcHkgcGFsZXR0ZSwgaWYgcG9zc2libGUuICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldFBhbGV0dGUoSUNPTV9JTlRFUkZBQ0Uoc3JjLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJnBhbF9zcmMpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19HZXRQYWxldHRlKElDT01fSU5URVJGQUNFKGRlc3QsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmcGFsKTsKCiAgICBpZiAocGFsX3NyYyAhPSBOVUxMICYmIHBhbCAhPSBOVUxMKQogICAgewogICAgICAgIFBBTEVUVEVFTlRSWSBwYWxlbnRbMjU2XTsKCiAgICAgICAgSURpcmVjdERyYXdQYWxldHRlX0dldEVudHJpZXMocGFsX3NyYywgMCwgMCwgMjU2LCBwYWxlbnQpOwogICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKHBhbCwgMCwgMCwgMjU2LCBwYWxlbnQpOwogICAgfQoKICAgIGlmIChwYWwpIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKHBhbCk7CiAgICBpZiAocGFsX3NyYykgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2UocGFsX3NyYyk7CgogICAgLyogQ29weSBjb2xvcmtleXMsIGlmIHByZXNlbnQuICovCiAgICBmb3IgKGNrZXlmbGFnID0gRERDS0VZX0RFU1RCTFQ7IGNrZXlmbGFnIDw9IEREQ0tFWV9TUkNPVkVSTEFZOyBja2V5ZmxhZyA8PD0gMSkKICAgIHsKICAgICAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfR2V0Q29sb3JLZXkoSUNPTV9JTlRFUkZBQ0Uoc3JjLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgY2tleWZsYWcsICZkZGNrZXkpOwoKICAgICAgICBpZiAoU1VDQ0VFREVEKGhyKSkKICAgICAgICB7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfU2V0Q29sb3JLZXkoSUNPTV9JTlRFUkZBQ0UoZGVzdCwgSURpcmVjdERyYXdTdXJmYWNlNyksIGNrZXlmbGFnLCAmZGRja2V5KTsKICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpMb2FkCiAqCiAqIExvYWRzIGEgcmVjdGFuZ3VsYXIgYXJlYSBmcm9tIHRoZSBzb3VyY2UgaW50byB0aGUgZGVzdGluYXRpb24gdGV4dHVyZS4KICogSXQgY2FuIGFsc28gY29weSB0aGUgc291cmNlIHRvIHRoZSBmYWNlcyBvZiBhIGN1YmljIGVudmlyb25tZW50IG1hcAogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgRGVzdFRleDogRGVzdGluYXRpb24gdGV4dHVyZQogKiAgRGVzdFBvaW50OiBQb2ludCBpbiB0aGUgZGVzdGluYXRpb24gd2hlcmUgdGhlIHNvdXJjZSBpbWFnZSBzaG91bGQgYmUKICogICAgICAgICAgICAgd3JpdHRlbiB0bwogKiAgU3JjVGV4OiBTb3VyY2UgdGV4dHVyZQogKiAgU3JjUmVjdDogU291cmNlIHJlY3RhbmdsZQogKiAgRmxhZ3M6IEN1YmVtYXAgZmFjZXMgdG8gbG9hZCAoRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUywgRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVgsCiAqICAgICAgICAgIEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVYLCBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWSwgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVksCiAqICAgICAgICAgIEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVaLCBERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWikKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERlc3RUZXggb3IgU3JjVGV4IGFyZSBOVUxMLCBicm9rZW4gY29vcmRpbmF0ZXMgb3IgYW55dGhpbmcgdW5leHBlY3RlZC4KICoKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQKSURpcmVjdDNERGV2aWNlSW1wbF83X0xvYWQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RUZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPSU5UICpEZXN0UG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlNyY1RleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3QgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBEZXN0VGV4KTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyY1RleCk7CiAgICBQT0lOVCBkZXN0cG9pbnQ7CiAgICBSRUNUIHNyY3JlY3Q7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCVwLCUwOHgpXG4iLCBUaGlzLCBkZXN0LCBEZXN0UG9pbnQsIHNyYywgU3JjUmVjdCwgRmxhZ3MpOwoKICAgIGlmKCAoIXNyYykgfHwgKCFkZXN0KSApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICBpZiAoU3JjUmVjdCkgc3JjcmVjdCA9ICpTcmNSZWN0OwogICAgZWxzZQogICAgewogICAgICAgIHNyY3JlY3QubGVmdCA9IHNyY3JlY3QudG9wID0gMDsKICAgICAgICBzcmNyZWN0LnJpZ2h0ID0gc3JjLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aDsKICAgICAgICBzcmNyZWN0LmJvdHRvbSA9IHNyYy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0OwogICAgfQoKICAgIGlmIChEZXN0UG9pbnQpIGRlc3Rwb2ludCA9ICpEZXN0UG9pbnQ7CiAgICBlbHNlCiAgICB7CiAgICAgICAgZGVzdHBvaW50LnggPSBkZXN0cG9pbnQueSA9IDA7CiAgICB9CiAgICAvKiBDaGVjayBiYWQgZGltZW5zaW9ucy4gRGVzdFBvaW50IGlzIHZhbGlkYXRlZCBhZ2FpbnN0IHNyYywgbm90IGRlc3QsIGJlY2F1c2UKICAgICAqIGRlc3RpbmF0aW9uIGNhbiBiZSBhIHN1YnNldCBvZiBtaXAgbGV2ZWxzLCBpbiB3aGljaCBjYXNlIGFjdHVhbCBjb29yZGluYXRlcyB1c2VkCiAgICAgKiBmb3IgaXQgbWF5IGJlIGRpdmlkZWQuIElmIGFueSBkaW1lbnNpb24gb2YgZGVzdCBpcyBsYXJnZXIgdGhhbiBzb3VyY2UsIGl0IGNhbid0IGJlCiAgICAgKiBtaXAgbGV2ZWwgc3Vic2V0LCBzbyBhbiBlcnJvciBjYW4gYmUgcmV0dXJuZWQgZWFybHkuCiAgICAgKi8KICAgIGlmIChzcmNyZWN0LmxlZnQgPj0gc3JjcmVjdC5yaWdodCB8fCBzcmNyZWN0LnRvcCA+PSBzcmNyZWN0LmJvdHRvbSB8fAogICAgICAgIHNyY3JlY3QucmlnaHQgPiBzcmMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoIHx8CiAgICAgICAgc3JjcmVjdC5ib3R0b20gPiBzcmMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCB8fAogICAgICAgIGRlc3Rwb2ludC54ICsgc3JjcmVjdC5yaWdodCAtIHNyY3JlY3QubGVmdCA+IHNyYy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICBkZXN0cG9pbnQueSArIHNyY3JlY3QuYm90dG9tIC0gc3JjcmVjdC50b3AgPiBzcmMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCB8fAogICAgICAgIGRlc3QtPnN1cmZhY2VfZGVzYy5kd1dpZHRoID4gc3JjLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aCB8fAogICAgICAgIGRlc3QtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCA+IHNyYy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogTXVzdCBiZSB0b3AgbGV2ZWwgc3VyZmFjZXMuICovCiAgICBpZiAoc3JjLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfTUlQTUFQU1VCTEVWRUwgfHwKICAgICAgICBkZXN0LT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfTUlQTUFQU1VCTEVWRUwpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZiAoc3JjLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCkKICAgIHsKICAgICAgICBEV09SRCBzcmNfZmFjZV9mbGFnLCBkZXN0X2ZhY2VfZmxhZzsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzcmNfZmFjZSwgKmRlc3RfZmFjZTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICp0ZW1wOwogICAgICAgIEREU1VSRkFDRURFU0MyIGRkc2Q7CiAgICAgICAgaW50IGk7CgogICAgICAgIGlmICghKGRlc3QtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKSkKICAgICAgICB7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgLyogSXRlcmF0ZSB0aHJvdWdoIGN1YmUgZmFjZXMgMiB0aW1lcy4gRmlyc3QgdGltZSBpcyBqdXN0IHRvIGNoZWNrIElOVkFMSURQQVJBTVMgY29uZGl0aW9ucywgc2Vjb25kCiAgICAgICAgICogdGltZSBpdCdzIGFjdHVhbCBzdXJmYWNlIGxvYWRpbmcuICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGRlc3RfZmFjZSA9IGRlc3Q7CiAgICAgICAgICAgIHNyY19mYWNlID0gc3JjOwoKICAgICAgICAgICAgZm9yICg7ZGVzdF9mYWNlICYmIHNyY19mYWNlOykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3JjX2ZhY2VfZmxhZyA9IHNyY19mYWNlLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgICAgICAgICAgICAgIGRlc3RfZmFjZV9mbGFnID0gZGVzdF9mYWNlLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKCiAgICAgICAgICAgICAgICBpZiAoc3JjX2ZhY2VfZmxhZyA9PSBkZXN0X2ZhY2VfZmxhZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogRGVzdGluYXRpb24gbWlwIGxldmVscyBtdXN0IGJlIHN1YnNldCBvZiBzb3VyY2UgbWlwIGxldmVscy4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc19taXBfbGV2ZWxfc3Vic2V0KGRlc3RfZmFjZSwgc3JjX2ZhY2UpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoRmxhZ3MgJiBkZXN0X2ZhY2VfZmxhZykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlfbWlwbWFwX2NoYWluKFRoaXMsIGRlc3RfZmFjZSwgc3JjX2ZhY2UsICZkZXN0cG9pbnQsICZzcmNyZWN0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChzcmNfZmFjZV9mbGFnIDwgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVopCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19URVhUVVJFOwogICAgICAgICAgICAgICAgICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzMiA9IEREU0NBUFMyX0NVQkVNQVAgfCAoc3JjX2ZhY2VfZmxhZyA8PCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoSUNPTV9JTlRFUkZBQ0Uoc3JjLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRkc2QuZGRzQ2FwcywgJnRlbXApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNyY19mYWNlICE9IHNyYykgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKHNyY19mYWNlLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CgogICAgICAgICAgICAgICAgICAgICAgICBzcmNfZmFjZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHRlbXApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3JjX2ZhY2UgIT0gc3JjKSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0Uoc3JjX2ZhY2UsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNyY19mYWNlID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGRlc3RfZmFjZV9mbGFnIDwgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVopCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfVEVYVFVSRTsKICAgICAgICAgICAgICAgICAgICBkZHNkLmRkc0NhcHMuZHdDYXBzMiA9IEREU0NBUFMyX0NVQkVNQVAgfCAoZGVzdF9mYWNlX2ZsYWcgPDwgMSk7CiAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoSUNPTV9JTlRFUkZBQ0UoZGVzdCwgSURpcmVjdERyYXdTdXJmYWNlNyksICZkZHNkLmRkc0NhcHMsICZ0ZW1wKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc3RfZmFjZSAhPSBkZXN0KSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGVzdF9mYWNlLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CgogICAgICAgICAgICAgICAgICAgIGRlc3RfZmFjZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHRlbXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChkZXN0X2ZhY2UgIT0gZGVzdCkgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRlc3RfZmFjZSwgSURpcmVjdERyYXdTdXJmYWNlNykpOwoKICAgICAgICAgICAgICAgICAgICBkZXN0X2ZhY2UgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBOYXRpdmUgcmV0dXJucyBlcnJvciBpZiBzcmMgZmFjZXMgYXJlIG5vdCBzdWJzZXQgb2YgZGVzdCBmYWNlcy4gKi8KICAgICAgICAgICAgICAgIGlmIChzcmNfZmFjZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RfT0s7CiAgICB9CiAgICBlbHNlIGlmIChkZXN0LT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEhhbmRsZSBub24gY3ViZSBtYXAgdGV4dHVyZXMuICovCgogICAgLyogRGVzdGluYXRpb24gbWlwIGxldmVscyBtdXN0IGJlIHN1YnNldCBvZiBzb3VyY2UgbWlwIGxldmVscy4gKi8KICAgIGlmICghaXNfbWlwX2xldmVsX3N1YnNldChkZXN0LCBzcmMpKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgY29weV9taXBtYXBfY2hhaW4oVGhpcywgZGVzdCwgc3JjLCAmZGVzdHBvaW50LCAmc3JjcmVjdCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfTG9hZF9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqRGVzdFRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUE9JTlQgKkRlc3RQb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqU3JjVGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19Mb2FkKGlmYWNlLCBEZXN0VGV4LCBEZXN0UG9pbnQsIFNyY1RleCwgU3JjUmVjdCwgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0xvYWRfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RUZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPSU5UICpEZXN0UG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlNyY1RleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19Mb2FkKGlmYWNlLCBEZXN0VGV4LCBEZXN0UG9pbnQsIFNyY1RleCwgU3JjUmVjdCwgRmxhZ3MpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpMaWdodEVuYWJsZQogKgogKiBFbmFibGVzIG9yIGRpc2FibGVzIGEgbGlnaHQKICoKICogVmVyc2lvbiA3LCBJRGlyZWN0M0RMaWdodCB1c2VzIHRoaXMgbWV0aG9kIHRvby4KICoKICogUGFyYW1zOgogKiAgTGlnaHRJbmRleDogVGhlIGluZGV4IG9mIHRoZSBsaWdodCB0byBlbmFibGUgLyBkaXNhYmxlCiAqICBFbmFibGU6IEVuYWJsZSBvciBkaXNhYmxlIHRoZSBsaWdodAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6U2V0TGlnaHRFbmFibGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfTGlnaHRFbmFibGUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBMaWdodEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBFbmFibGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJWQpOiBSZWxheSFcbiIsIFRoaXMsIExpZ2h0SW5kZXgsIEVuYWJsZSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0TGlnaHRFbmFibGUoVGhpcy0+d2luZUQzRERldmljZSwgTGlnaHRJbmRleCwgRW5hYmxlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19MaWdodEVuYWJsZV9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIEVuYWJsZSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19MaWdodEVuYWJsZShpZmFjZSwgTGlnaHRJbmRleCwgRW5hYmxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19MaWdodEVuYWJsZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIEVuYWJsZSkKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X0xpZ2h0RW5hYmxlKGlmYWNlLCBMaWdodEluZGV4LCBFbmFibGUpOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRMaWdodEVuYWJsZQogKgogKiBSZXRyaWV2ZXMgaWYgdGhlIGxpZ2h0IHdpdGggdGhlIGdpdmVuIGluZGV4IGlzIGVuYWJsZWQgb3Igbm90CiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBMaWdodEluZGV4OiBJbmRleCBvZiBkZXNpcmVkIGxpZ2h0CiAqICBFbmFibGU6IFBvaW50ZXIgdG8gYSBCT09MIHdoaWNoIGNvbnRhaW5zIHRoZSByZXN1bHQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEVuYWJsZSBpcyBOVUxMCiAqICBTZWUgSVdpbmVEM0REZXZpY2U6OkdldExpZ2h0RW5hYmxlIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TGlnaHRFbmFibGUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBMaWdodEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCogRW5hYmxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXlcbiIsIFRoaXMsIExpZ2h0SW5kZXgsIEVuYWJsZSk7CgogICAgaWYoIUVuYWJsZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRMaWdodEVuYWJsZShUaGlzLT53aW5lRDNERGV2aWNlLCBMaWdodEluZGV4LCBFbmFibGUpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0RW5hYmxlX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wqIEVuYWJsZSkKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodEVuYWJsZShpZmFjZSwgTGlnaHRJbmRleCwgRW5hYmxlKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodEVuYWJsZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MKiBFbmFibGUpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodEVuYWJsZShpZmFjZSwgTGlnaHRJbmRleCwgRW5hYmxlKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0Q2xpcFBsYW5lCiAqCiAqIFNldHMgY3VzdG9tIGNsaXBwaW5nIHBsYW5lCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBJbmRleDogVGhlIGluZGV4IG9mIHRoZSBjbGlwcGluZyBwbGFuZQogKiAgUGxhbmVFcXVhdGlvbjogQW4gZXF1YXRpb24gZGVmaW5pbmcgdGhlIGNsaXBwaW5nIHBsYW5lCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQbGFuZUVxdWF0aW9uIGlzIE5VTEwKICogIFNlZSBJV2luZUQzRERldmljZTo6U2V0Q2xpcFBsYW5lIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFBsYW5lKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFKiBQbGFuZUVxdWF0aW9uKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXkhXG4iLCBUaGlzLCBJbmRleCwgUGxhbmVFcXVhdGlvbik7CgogICAgaWYoIVBsYW5lRXF1YXRpb24pCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0Q2xpcFBsYW5lKFRoaXMtPndpbmVEM0REZXZpY2UsIEluZGV4LCBQbGFuZUVxdWF0aW9uKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFBsYW5lX0ZQVVNldHVwKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFKiBQbGFuZUVxdWF0aW9uKQp7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldENsaXBQbGFuZShpZmFjZSwgSW5kZXgsIFBsYW5lRXF1YXRpb24pOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldENsaXBQbGFuZV9GUFVQcmVzZXJ2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSogUGxhbmVFcXVhdGlvbikKewogICAgSFJFU1VMVCBocjsKICAgIFdPUkQgb2xkX2ZwdWN3OwoKICAgIG9sZF9mcHVjdyA9IGQzZF9mcHVfc2V0dXAoKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlSW1wbF83X1NldENsaXBQbGFuZShpZmFjZSwgSW5kZXgsIFBsYW5lRXF1YXRpb24pOwogICAgc2V0X2ZwdV9jb250cm9sX3dvcmQob2xkX2ZwdWN3KTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRDbGlwUGxhbmUKICoKICogUmV0dXJucyB0aGUgY2xpcHBpbmcgcGxhbmUgd2l0aCBhIHNwZWNpZmljIGluZGV4CiAqCiAqIFBhcmFtczoKICogIEluZGV4OiBUaGUgaW5kZXggb2YgdGhlIGRlc2lyZWQgcGxhbmUKICogIFBsYW5lRXF1YXRpb246IEFkZHJlc3MgdG8gc3RvcmUgdGhlIHBsYW5lIGVxdWF0aW9uIHRvCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQbGFuZUVxdWF0aW9uIGlzIE5VTEwKICogIFNlZSBJV2luZUQzRERldmljZTo6R2V0Q2xpcFBsYW5lIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2xpcFBsYW5lKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFKiBQbGFuZUVxdWF0aW9uKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlcCk6IFJlbGF5IVxuIiwgVGhpcywgSW5kZXgsIFBsYW5lRXF1YXRpb24pOwoKICAgIGlmKCFQbGFuZUVxdWF0aW9uKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldENsaXBQbGFuZShUaGlzLT53aW5lRDNERGV2aWNlLCBJbmRleCwgUGxhbmVFcXVhdGlvbik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENsaXBQbGFuZV9GUFVTZXR1cChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSogUGxhbmVFcXVhdGlvbikKewogICAgcmV0dXJuIElEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwUGxhbmUoaWZhY2UsIEluZGV4LCBQbGFuZUVxdWF0aW9uKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwUGxhbmVfRlBVUHJlc2VydmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkFMVUUqIFBsYW5lRXF1YXRpb24pCnsKICAgIEhSRVNVTFQgaHI7CiAgICBXT1JEIG9sZF9mcHVjdzsKCiAgICBvbGRfZnB1Y3cgPSBkM2RfZnB1X3NldHVwKCk7CiAgICBociA9IElEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwUGxhbmUoaWZhY2UsIEluZGV4LCBQbGFuZUVxdWF0aW9uKTsKICAgIHNldF9mcHVfY29udHJvbF93b3JkKG9sZF9mcHVjdyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0SW5mbwogKgogKiBSZXRyaWV2ZXMgc29tZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZGV2aWNlLiBUaGUgRGlyZWN0WCBzZGsgc2F5cyB0aGF0CiAqIHRoaXMgdmVyc2lvbiByZXR1cm5zIFNfRkFMU0UgZm9yIGFsbCByZXRhaWwgYnVpbGRzIG9mIERpcmVjdFgsIHRoYXQncyB3aGF0CiAqIHRoaXMgaW1wbGVtZW50YXRpb24gZG9lcy4KICoKICogUGFyYW1zOgogKiAgRGV2SW5mb0lEOiBJbmZvcm1hdGlvbiB0eXBlIHJlcXVlc3RlZAogKiAgRGV2SW5mb1N0cnVjdDogUG9pbnRlciB0byBhIHN0cnVjdHVyZSB0byBzdG9yZSB0aGUgaW5mbyB0bwogKiAgU2l6ZTogU2l6ZSBvZiB0aGUgc3RydWN0dXJlCiAqCiAqIFJldHVybnM6CiAqICBTX0ZBTFNFLCBiZWNhdXNlIGl0J3MgYSBub24tZGVidWcgZHJpdmVyCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRJbmZvKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBEZXZJbmZvSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkRldkluZm9TdHJ1Y3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFNpemUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlMDh4KVxuIiwgVGhpcywgRGV2SW5mb0lELCBEZXZJbmZvU3RydWN0LCBTaXplKTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkNykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiBpbmZvIHJlcXVlc3RlZCA6ICIpOwogICAgICAgIHN3aXRjaCAoRGV2SW5mb0lEKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfVEVYVFVSRU1BTkFHRVI6IFRSQUNFKCJEM0RERVZJTkZPSURfVEVYVFVSRU1BTkFHRVJcbiIpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfRDNEVEVYVFVSRU1BTkFHRVI6IFRSQUNFKCJEM0RERVZJTkZPSURfRDNEVEVYVFVSRU1BTkFHRVJcbiIpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfVEVYVFVSSU5HOiBUUkFDRSgiRDNEREVWSU5GT0lEX1RFWFRVUklOR1xuIik7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiBFUlIoIiBpbnZhbGlkIGZsYWcgISEhXG4iKTsgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBTX0ZBTFNFOyAvKiBBY2NvcmRpbmcgdG8gTVNETiwgdGhpcyBpcyB2YWxpZCBmb3IgYSBub24tZGVidWcgZHJpdmVyICovCn0KCi8qIEZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24sIGRldmljZXMgY3JlYXRlZCBpbiBGUFVTRVRVUCBhbmQgRlBVUFJFU0VSVkUgbW9kZXMKICogaGF2ZSBzZXBhcmF0ZSB2dGFibGVzLiBTaW1wbGUgZnVuY3Rpb25zIHdoZXJlIHRoaXMgZG9lc24ndCBtYXR0ZXIgbGlrZSBHZXREaXJlY3QzRAogKiBhcmUgbm90IGR1cGxpY2F0ZWQuCgogKiBEZXZpY2UgY3JlYXRlZCB3aXRoIEREU0NMX0ZQVVNFVFVQIChkM2Q3IGRlZmF1bHQpIC0gZGV2aWNlIG1ldGhvZHMgYXNzdW1lIHRoYXQgRlBVCiAqIGhhcyBhbHJlYWR5IGJlZW4gc2V0dXAgZm9yIG9wdGltYWwgZDNkIG9wZXJhdGlvbi4KCiAqIERldmljZSBjcmVhdGVkIHdpdGggRERTQ0xfRlBVUFJFU0VSVkUgLSByZXNldHMgYW5kIHJlc3RvcmVzIEZQVSBtb2RlIHdoZW4gbmVjZXNzYXJ5IGluCiAqIGQzZCBjYWxscyAoRlBVIG1heSBiZSBpbiBhIG1vZGUgbm9uLXN1aXRhYmxlIGZvciBkM2Qgd2hlbiB0aGUgYXBwIGNhbGxzIGQzZCkuIFJlcXVpcmVkCiAqIGJ5IFNhY3JpZmljZSAoZ2FtZSkuICovCmNvbnN0IElEaXJlY3QzRERldmljZTdWdGJsIElEaXJlY3QzRERldmljZTdfRlBVU2V0dXBfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gTWV0aG9kcyAqKiovCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQWRkUmVmLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3QzRERldmljZTcgKioqLwogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENhcHNfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW51bVRleHR1cmVGb3JtYXRzX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU2NlbmVfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmVfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0RGlyZWN0M0QsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyVGFyZ2V0X0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclRhcmdldCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19DbGVhcl9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRUcmFuc2Zvcm1fRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VHJhbnNmb3JtX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFZpZXdwb3J0X0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X011bHRpcGx5VHJhbnNmb3JtX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFZpZXdwb3J0X0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldE1hdGVyaWFsX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldE1hdGVyaWFsX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0X0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0X0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclN0YXRlX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclN0YXRlX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9ja19GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19FbmRTdGF0ZUJsb2NrX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1ByZUxvYWRfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRDbGlwU3RhdHVzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENsaXBTdGF0dXMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZVN0cmlkZWRfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVWQl9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0NvbXB1dGVTcGhlcmVWaXNpYmlsaXR5LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmVfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19WYWxpZGF0ZURldmljZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2tfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2FwdHVyZVN0YXRlQmxvY2tfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRGVsZXRlU3RhdGVCbG9ja19GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19DcmVhdGVTdGF0ZUJsb2NrX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0xvYWRfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfTGlnaHRFbmFibGVfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TGlnaHRFbmFibGVfRlBVU2V0dXAsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFBsYW5lX0ZQVVNldHVwLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENsaXBQbGFuZV9GUFVTZXR1cCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRJbmZvCn07Cgpjb25zdCBJRGlyZWN0M0REZXZpY2U3VnRibCBJRGlyZWN0M0REZXZpY2U3X0ZQVVByZXNlcnZlX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duIE1ldGhvZHMgKioqLwogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0FkZFJlZiwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0M0REZXZpY2U3ICoqKi8KICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRDYXBzX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0VudW1UZXh0dXJlRm9ybWF0c19GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19CZWdpblNjZW5lX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0VuZFNjZW5lX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldERpcmVjdDNELAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclRhcmdldF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRSZW5kZXJUYXJnZXQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2xlYXJfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VHJhbnNmb3JtX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRyYW5zZm9ybV9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRWaWV3cG9ydF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19NdWx0aXBseVRyYW5zZm9ybV9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRWaWV3cG9ydF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRNYXRlcmlhbF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRNYXRlcmlhbF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRMaWdodF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRSZW5kZXJTdGF0ZV9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRSZW5kZXJTdGF0ZV9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19CZWdpblN0YXRlQmxvY2tfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU3RhdGVCbG9ja19GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19QcmVMb2FkX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFN0YXR1cywKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwU3RhdHVzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVTdHJpZGVkX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZF9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlVkJfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQl9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19Db21wdXRlU3BoZXJlVmlzaWJpbGl0eSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VGV4dHVyZVN0YWdlU3RhdGVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZVN0YWdlU3RhdGVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfVmFsaWRhdGVEZXZpY2VfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQXBwbHlTdGF0ZUJsb2NrX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0NhcHR1cmVTdGF0ZUJsb2NrX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RlbGV0ZVN0YXRlQmxvY2tfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ3JlYXRlU3RhdGVCbG9ja19GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19Mb2FkX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0xpZ2h0RW5hYmxlX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0RW5hYmxlX0ZQVVByZXNlcnZlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldENsaXBQbGFuZV9GUFVQcmVzZXJ2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRDbGlwUGxhbmVfRlBVUHJlc2VydmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0SW5mbwp9OwoKY29uc3QgSURpcmVjdDNERGV2aWNlM1Z0YmwgSURpcmVjdDNERGV2aWNlM19WdGJsID0KewogICAgLyoqKiBJVW5rbm93biBNZXRob2RzICoqKi8KICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19RdWVyeUludGVyZmFjZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19BZGRSZWYsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfUmVsZWFzZSwKICAgIC8qKiogSURpcmVjdDNERGV2aWNlMyAqKiovCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q2FwcywKICAgIElEaXJlY3QzRERldmljZUltcGxfM19HZXRTdGF0cywKICAgIElEaXJlY3QzRERldmljZUltcGxfM19BZGRWaWV3cG9ydCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19EZWxldGVWaWV3cG9ydCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19OZXh0Vmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRW51bVRleHR1cmVGb3JtYXRzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0JlZ2luU2NlbmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRW5kU2NlbmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0RGlyZWN0M0QsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0Q3VycmVudFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldEN1cnJlbnRWaWV3cG9ydCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRSZW5kZXJUYXJnZXQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0UmVuZGVyVGFyZ2V0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0JlZ2luLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0JlZ2luSW5kZXhlZCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19WZXJ0ZXgsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfSW5kZXgsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfRW5kLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFJlbmRlclN0YXRlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFJlbmRlclN0YXRlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldExpZ2h0U3RhdGUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0TGlnaHRTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRUcmFuc2Zvcm0sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VHJhbnNmb3JtLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX011bHRpcGx5VHJhbnNmb3JtLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd0luZGV4ZWRQcmltaXRpdmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0Q2xpcFN0YXR1cywKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRDbGlwU3RhdHVzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmVTdHJpZGVkLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3UHJpbWl0aXZlVkIsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd0luZGV4ZWRQcmltaXRpdmVWQiwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19Db21wdXRlU3BoZXJlVmlzaWJpbGl0eSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRUZXh0dXJlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFRleHR1cmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfVmFsaWRhdGVEZXZpY2UKfTsKCmNvbnN0IElEaXJlY3QzRERldmljZTJWdGJsIElEaXJlY3QzRERldmljZTJfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gTWV0aG9kcyAqKiovCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfUXVlcnlJbnRlcmZhY2UsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQWRkUmVmLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3QzRERldmljZTIgKioqLwogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldENhcHMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzJfU3dhcFRleHR1cmVIYW5kbGVzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFN0YXRzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0FkZFZpZXdwb3J0LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0RlbGV0ZVZpZXdwb3J0LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX05leHRWaWV3cG9ydCwKICAgIElEaXJlY3QzRERldmljZUltcGxfMl9FbnVtVGV4dHVyZUZvcm1hdHMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQmVnaW5TY2VuZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9FbmRTY2VuZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXREaXJlY3QzRCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9TZXRDdXJyZW50Vmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q3VycmVudFZpZXdwb3J0LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldFJlbmRlclRhcmdldCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRSZW5kZXJUYXJnZXQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQmVnaW4sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQmVnaW5JbmRleGVkLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1ZlcnRleCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9JbmRleCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9FbmQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0UmVuZGVyU3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0UmVuZGVyU3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0TGlnaHRTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9TZXRMaWdodFN0YXRlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldFRyYW5zZm9ybSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRUcmFuc2Zvcm0sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfTXVsdGlwbHlUcmFuc2Zvcm0sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfRHJhd1ByaW1pdGl2ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EcmF3SW5kZXhlZFByaW1pdGl2ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9TZXRDbGlwU3RhdHVzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldENsaXBTdGF0dXMKfTsKCmNvbnN0IElEaXJlY3QzRERldmljZVZ0YmwgSURpcmVjdDNERGV2aWNlMV9WdGJsID0KewogICAgLyoqKiBJVW5rbm93biBNZXRob2RzICoqKi8KICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9RdWVyeUludGVyZmFjZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9BZGRSZWYsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfUmVsZWFzZSwKICAgIC8qKiogSURpcmVjdDNERGV2aWNlMSAqKiovCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfSW5pdGlhbGl6ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9HZXRDYXBzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX1N3YXBUZXh0dXJlSGFuZGxlcywKICAgIElEaXJlY3QzRERldmljZUltcGxfMV9DcmVhdGVFeGVjdXRlQnVmZmVyLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0dldFN0YXRzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX0V4ZWN1dGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfQWRkVmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfRGVsZXRlVmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfTmV4dFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX1BpY2ssCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0UGlja1JlY29yZHMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfRW51bVRleHR1cmVGb3JtYXRzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX0NyZWF0ZU1hdHJpeCwKICAgIElEaXJlY3QzRERldmljZUltcGxfMV9TZXRNYXRyaXgsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0TWF0cml4LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX0RlbGV0ZU1hdHJpeCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9CZWdpblNjZW5lLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0VuZFNjZW5lLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0dldERpcmVjdDNECn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlSW1wbF9DcmVhdGVIYW5kbGUKICoKICogTm90IGNhbGxlZCBmcm9tIHRoZSBWVGFibGUKICoKICogU29tZSBvbGRlciBpbnRlcmZhY2UgdmVyc2lvbnMgb3BlcmF0ZSB3aXRoIGhhbmRsZXMsIHdoaWNoIGFyZSBiYXNpY2FsbHkKICogRFdPUkRzIHdoaWNoIGlkZW50aWZ5IGFuIGludGVyZmFjZSwgZm9yIGV4YW1wbGUKICogSURpcmVjdDNERGV2aWNlOjpTZXRSZW5kZXJTdGF0ZSB3aXRoIERJUkVDVDNEUkVOREVSU1RBVEVfVEVYVFVSRUhBTkRMRQogKgogKiBUaG9zZSBoYW5kbGUgY291bGQgYmUganVzdCBjYXN0cyB0byB0aGUgaW50ZXJmYWNlIHBvaW50ZXJzIG9yIHZpY2UgdmVyc2EsCiAqIGJ1dCB0aGF0IGlzIG5vdCA2NCBiaXQgc2FmZSBhbmQgd291bGQgbWVhbiBibGluZGx5IGRlcmVmZXJpbmcgYSBEV09SRAogKiBwYXNzZWQgYnkgdGhlIGFwcC4gSW5zdGVhZCB0aGVyZSBpcyBhIGR5bmFtaWMgYXJyYXkgaW4gdGhlIGRldmljZSB3aGljaAogKiBrZWVwcyBhIERXT1JEIHRvIHBvaW50ZXIgaW5mb3JtYXRpb24gYW5kIGEgdHlwZSBmb3IgdGhlIGhhbmRsZS4KICoKICogQmFzaWNhbGx5IHRoaXMgYXJyYXkgb25seSBncm93cywgd2hlbiBhIGhhbmRsZSBpcyBmcmVlZCBpdHMgcG9pbnRlciBpcwogKiBqdXN0IHNldCB0byBOVUxMLiBUaGVyZSB3aWxsIGJlIG11Y2ggbW9yZSByZWFkcyBmcm9tIHRoZSBhcnJheSB0aGFuCiAqIGluc2VydGlvbiBvcGVyYXRpb25zLCBzbyBhIGR5bmFtaWMgYXJyYXkgaXMgZmluZS4KICoKICogUGFyYW1zOgogKiAgVGhpczogRDNERGV2aWNlIGltcGxlbWVudGF0aW9uIGZvciB3aGljaCB0aGlzIGhhbmRsZSBzaG91bGQgYmUgY3JlYXRlZAogKgogKiBSZXR1cm5zOgogKiAgQSBmcmVlIGhhbmRsZSBvbiBzdWNjZXNzCiAqICAwIG9uIGZhaWx1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpEV09SRApJRGlyZWN0M0REZXZpY2VJbXBsX0NyZWF0ZUhhbmRsZShJRGlyZWN0M0REZXZpY2VJbXBsICpUaGlzKQp7CiAgICBEV09SRCBpOwogICAgc3RydWN0IEhhbmRsZUVudHJ5ICpvbGRIYW5kbGVzID0gVGhpcy0+SGFuZGxlczsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bnVtSGFuZGxlczsgaSsrKQogICAgewogICAgICAgIGlmKFRoaXMtPkhhbmRsZXNbaV0ucHRyID09IE5VTEwgJiYKICAgICAgICAgICBUaGlzLT5IYW5kbGVzW2ldLnR5cGUgPT0gRERyYXdIYW5kbGVfVW5rbm93bikKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJSZXVzaW5nIGZyZWVkIGhhbmRsZSAlZFxuIiwgaSArIDEpOwogICAgICAgICAgICByZXR1cm4gaSArIDE7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJHcm93aW5nIHRoZSBoYW5kbGUgYXJyYXlcbiIpOwoKICAgIFRoaXMtPm51bUhhbmRsZXMrKzsKICAgIFRoaXMtPkhhbmRsZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKHN0cnVjdCBIYW5kbGVFbnRyeSkgKiBUaGlzLT5udW1IYW5kbGVzKTsKICAgIGlmKCFUaGlzLT5IYW5kbGVzKQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgVGhpcy0+SGFuZGxlcyA9IG9sZEhhbmRsZXM7CiAgICAgICAgVGhpcy0+bnVtSGFuZGxlcy0tOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYob2xkSGFuZGxlcykKICAgIHsKICAgICAgICBtZW1jcHkoVGhpcy0+SGFuZGxlcywgb2xkSGFuZGxlcywgKFRoaXMtPm51bUhhbmRsZXMgLSAxKSAqIHNpemVvZihzdHJ1Y3QgSGFuZGxlRW50cnkpKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvbGRIYW5kbGVzKTsKICAgIH0KCiAgICBUUkFDRSgiUmV0dXJuaW5nICVkXG4iLCBUaGlzLT5udW1IYW5kbGVzKTsKICAgIHJldHVybiBUaGlzLT5udW1IYW5kbGVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlSW1wbF9VcGRhdGVEZXB0aFN0ZW5jaWwKICoKICogQ2hlY2tzIHRoZSBjdXJyZW50IHJlbmRlciB0YXJnZXQgZm9yIGF0dGFjaGVkIGRlcHRoIHN0ZW5jaWxzIGFuZCBzZXRzIHRoZQogKiBXaW5lRDNEIGRlcHRoIHN0ZW5jaWwgYWNjb3JkaW5nbHkuCiAqCiAqIFJldHVybnM6CiAqICBUaGUgZGVwdGggc3RlbmNpbCBzdGF0ZSB0byBzZXQgaWYgY3JlYXRpbmcgdGhlIGRldmljZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCldJTkVEM0RaQlVGRkVSVFlQRQpJRGlyZWN0M0REZXZpY2VJbXBsX1VwZGF0ZURlcHRoU3RlbmNpbChJRGlyZWN0M0REZXZpY2VJbXBsICpUaGlzKQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpkZXB0aFN0ZW5jaWwgPSBOVUxMOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqZHNpOwogICAgc3RhdGljIEREU0NBUFMyIGRlcHRoY2FwcyA9IHsgRERTQ0FQU19aQlVGRkVSLCAwLCAwLCAwIH07CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoSUNPTV9JTlRFUkZBQ0UoVGhpcy0+dGFyZ2V0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXB0aGNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGVwdGhTdGVuY2lsKTsKICAgIGlmKCFkZXB0aFN0ZW5jaWwpCiAgICB7CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgd2luZWQzZCBkZXB0aCBzdGVuY2lsIHRvIE5VTExcbiIpOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiBXSU5FRDNEWkJfRkFMU0U7CiAgICB9CgogICAgZHNpID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgZGVwdGhTdGVuY2lsKTsKICAgIFRSQUNFKCJTZXR0aW5nIHdpbmVkM2QgZGVwdGggc3RlbmNpbCB0byAlcCAod2luZWQzZCAlcClcbiIsIGRzaSwgZHNpLT5XaW5lRDNEU3VyZmFjZSk7CiAgICBJV2luZUQzRERldmljZV9TZXREZXB0aFN0ZW5jaWxTdXJmYWNlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzaS0+V2luZUQzRFN1cmZhY2UpOwoKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShkZXB0aFN0ZW5jaWwpOwogICAgcmV0dXJuIFdJTkVEM0RaQl9UUlVFOwp9Cg==