LyoKICogQ29weXJpZ2h0IChjKSAxOTk4LTIwMDQgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAoYykgMjAwMi0yMDA1IENocmlzdGlhbiBDb3N0YQogKiBDb3B5cmlnaHQgKGMpIDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBJRGlyZWN0M0REZXZpY2UgaW1wbGVtZW50YXRpb24sIHZlcnNpb24gMSwgMiwgMyBhbmQgNy4gUmVuZGVyaW5nIGlzIHJlbGF5ZWQKICogdG8gV2luZUQzRCwgc29tZSBtaW5pbWFsIERpcmVjdERyYXcgc3BlY2lmaWMgbWFuYWdlbWVudCBpcyBoYW5kbGVkIGhlcmUuCiAqIFRoZSBEaXJlY3QzRERldmljZSBpcyBOT1QgdGhlIHBhcmVudCBvZiB0aGUgV2luZUQzRERldmljZSwgYmVjYXVzZSBkM2QKICogaXMgaW5pdGlhbGl6ZWQgd2hlbiBEaXJlY3REcmF3IGNyZWF0ZXMgdGhlIHByaW1hcnkgc3VyZmFjZS4KICogU29tZSB0eXBlIG1hbmFnZW1lbnQgaXMgbmVjZXNzYXJ5LCBiZWNhdXNlIHNvbWUgRDNEIHR5cGVzIGNoYW5nZWQgYmV0d2VlbgogKiBEM0Q3IGFuZCBEM0Q5LgogKgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Q3KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGRyYXdfdGh1bmspOwoKLyogVGhlIGRldmljZSBJRCAqLwpjb25zdCBHVUlEIElJRF9EM0RERVZJQ0VfV2luZUQzRCA9IHsKICAweGFlZjcyZDQzLAogIDB4YjA5YSwKICAweDRiN2IsCiAgeyAweGI3LDB4OTgsMHhjNiwweDhhLDB4NzcsMHgyZCwweDcyLDB4MmEgfQp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElVbmtub3duIE1ldGhvZHMuIENvbW1vbiBmb3IgVmVyc2lvbiAxLCAyLCAzIGFuZCA3IAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6UXVlcnlJbnRlcmZhY2UKICoKICogVXNlZCB0byBxdWVyeSBvdGhlciBpbnRlcmZhY2VzIGZyb20gYSBEaXJlY3QzRERldmljZSBpbnRlcmZhY2UuCiAqIEl0IGNhbiByZXR1cm4gaW50ZXJmYWNlIHBvaW50ZXJzIHRvIGFsbCBEaXJlY3QzRERldmljZSB2ZXJzaW9ucyBhcyB3ZWxsCiAqIGFzIElEaXJlY3REcmF3IGFuZCBJRGlyZWN0M0QuIEZvciBhIGxpbmsgdG8gUXVlcnlJbnRlcmZhY2UKICogcnVsZXMgc2VlIGRkcmF3LmMsIElEaXJlY3REcmF3Nzo6UXVlcnlJbnRlcmZhY2UKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICByZWZpaWQ6IEludGVyZmFjZSBJRCBxdWVyaWVkIGZvcgogKiAgb2JqOiBVc2VkIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvciBFX05PSU5URVJGQUNFCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19RdWVyeUludGVyZmFjZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByZWZpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICAgIC8qIEFjY29yZGluZyB0byBDT00gZG9jcywgaWYgdGhlIFF1ZXJ5SW50ZXJmYWNlIGZhaWxzLCBvYmogc2hvdWxkIGJlIHNldCB0byBOVUxMICovCiAgICAqb2JqID0gTlVMTDsKCiAgICBpZighcmVmaWlkKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSVVua25vd24sIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyk7CiAgICB9CgogICAgLyogQ2hlY2sgRGlyZWN0RHJhdyBJbnRlcmZhYwFzICovCiAgICBlbHNlIGlmKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzcsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3Nyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3NCwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXc0KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXc0IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXcyLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdzIpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzIgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CgogICAgLyogRGlyZWN0M0QgKi8KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QgICwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdDNEKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNEIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMiAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3QzRDIpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0QyIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMyAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3QzRDMpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0QzIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNENyAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3QzRDcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0Q3IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CgogICAgLyogRGlyZWN0M0REZXZpY2UgKi8KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0REZXZpY2UgICwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0REZXZpY2UgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0REZXZpY2UyICAsIHJlZmlpZCApICkgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UyKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNERGV2aWNlMiBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRERldmljZTMgICwgcmVmaWlkICkgKSB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNERGV2aWNlNyAgLCByZWZpaWQgKSApIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KCiAgICAvKiBVbmtub3duIGludGVyZmFjZSAqLwogICAgZWxzZQogICAgewogICAgICAgIEVSUigiKCVwKS0+KCVzLCAlcCk6IE5vIGludGVyZmFjZSBmb3VuZFxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwogICAgICAgIHJldHVybiBFX05PSU5URVJGQUNFOwogICAgfQoKICAgIC8qIEFkZFJlZiB0aGUgcmV0dXJuZWQgaW50ZXJmYWNlICovCiAgICBJVW5rbm93bl9BZGRSZWYoIChJVW5rbm93biAqKSAqb2JqKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfUXVlcnlJbnRlcmZhY2UoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcywlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfUXVlcnlJbnRlcmZhY2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9RdWVyeUludGVyZmFjZShJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVzLCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIG9iaik7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19RdWVyeUludGVyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmopOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYnApCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVzLCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIG9icCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19RdWVyeUludGVyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6QWRkUmVmCiAqCiAqIEluY3JlYXNlcyB0aGUgcmVmY291bnQuLi4uCiAqIFRoZSBtb3N0IGV4Y2l0aW5nIE1ldGhvZCwgZGVmaW5pdGVseQogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCAzIGFuZCA3CiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQWRkUmVmKElEaXJlY3QzRERldmljZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IGluY3JlbWVudGluZyBmcm9tICV1LlxuIiwgVGhpcywgcmVmIC0xKTsKCiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19BZGRSZWYoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9BZGRSZWYoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9BZGRSZWYoSURpcmVjdDNERGV2aWNlICppZmFjZSkKewogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19BZGRSZWYoQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlJlbGVhc2UKICoKICogRGVjcmVhc2VzIHRoZSByZWZjb3VudCBvZiB0aGUgaW50ZXJmYWNlCiAqIFdoZW4gdGhlIHJlZmNvdW50IGlzIHJlZHVjZWQgdG8gMCwgdGhlIG9iamVjdCBpcyBkZXN0cm95ZWQuCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDMgYW5kIDcKICoKICogUmV0dXJuczpkCiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfUmVsZWFzZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBmcm9tICV1LlxuIiwgVGhpcywgcmVmICsxKTsKCiAgICAvKiBUaGlzIG1ldGhvZCBkb2Vzbid0IGRlc3Ryb3kgdGhlIFdpbmVEM0REZXZpY2UsIGJlY2F1c2UgaXQncyBzdGlsbCBpbiB1c2UgZm9yCiAgICAgKiAyRCByZW5kZXJpbmcuIElEaXJlY3REcmF3U3VyZmFjZTc6OlJlbGVhc2Ugd2lsbCBkZXN0cm95IHRoZSBXaW5lRDNERGV2aWNlCiAgICAgKiB3aGVuIHRoZSByZW5kZXIgdGFyZ2V0IGlzIHJlbGVhc2VkCiAgICAgKi8KICAgIGlmIChyZWYgPT0gMCkKICAgIHsKICAgICAgICBJUGFyZW50ICpJbmRleEJ1ZmZlclBhcmVudDsKICAgICAgICBEV09SRCBpOwoKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIC8qIEZyZWUgdGhlIGluZGV4IGJ1ZmZlci4gKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRJbmRpY2VzKFRoaXMtPndpbmVEM0REZXZpY2UsIE5VTEwpOwogICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfR2V0UGFyZW50KFRoaXMtPmluZGV4YnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJkluZGV4QnVmZmVyUGFyZW50KTsKICAgICAgICBJUGFyZW50X1JlbGVhc2UoSW5kZXhCdWZmZXJQYXJlbnQpOyAvKiBPbmNlIGZvciB0aGUgZ2V0UGFyZW50ICovCiAgICAgICAgaWYoIElQYXJlbnRfUmVsZWFzZShJbmRleEJ1ZmZlclBhcmVudCkgIT0gMCkgIC8qIEFuZCBub3cgdG8gZGVzdHJveSBpdCAqLwogICAgICAgIHsKICAgICAgICAgICAgRVJSKCIgKCVwKSBTb21ldGhpbmcgaXMgc3RpbGwgaG9sZGluZyB0aGUgaW5kZXggYnVmZmVyIHBhcmVudCAlcFxuIiwgVGhpcywgSW5kZXhCdWZmZXJQYXJlbnQpOwogICAgICAgIH0KCiAgICAgICAgLyogVGhlcmUgaXMgbm8gbmVlZCB0byB1bnNldCB0aGUgdmVydGV4IGJ1ZmZlciBoZXJlLCBJV2luZUQzRERldmljZV9VbmluaXQzRCB3aWxsIGRvIHRoYXQgd2hlbgogICAgICAgICAqIGRlc3Ryb3lpbmcgdGhlIHByaW1hcnkgc3RhdGVibG9jay4gSWYgYSB2ZXJ0ZXggYnVmZmVyIGlzIGRlc3Ryb3llZCB3aGlsZSBpdCBpcyBib3VuZAogICAgICAgICAqIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjo6UmVsZWFzZSB3aWxsIHVuc2V0IGl0LgogICAgICAgICAqLwoKICAgICAgICAvKiBSZXN0b3JlIHRoZSByZW5kZXIgdGFyZ2V0cyAqLwogICAgICAgIGlmKFRoaXMtPk9mZlNjcmVlblRhcmdldCkKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKCiAgICAgICAgICAgIHZwLlggPSAwOwogICAgICAgICAgICB2cC5ZID0gMDsKICAgICAgICAgICAgdnAuV2lkdGggPSBUaGlzLT5kZHJhdy0+ZDNkX3RhcmdldC0+c3VyZmFjZV9kZXNjLmR3V2lkdGg7CiAgICAgICAgICAgIHZwLkhlaWdodCA9IFRoaXMtPmRkcmF3LT5kM2RfdGFyZ2V0LT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQ7CiAgICAgICAgICAgIHZwLk1pblogPSAwLjA7CiAgICAgICAgICAgIHZwLk1heFogPSAxLjA7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFZpZXdwb3J0KFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2cCk7CgogICAgICAgICAgICAvKiBTZXQgdGhlIGRldmljZSB1cCB0byByZW5kZXIgdG8gdGhlIGZyb250IGJ1ZmZlciBzaW5jZSB0aGUgYmFjayBidWZmZXIgd2lsbAogICAgICAgICAgICAgKiB2YW5pc2ggc29vbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFJlbmRlclRhcmdldChUaGlzLT53aW5lRDNERGV2aWNlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQtPldpbmVEM0RTdXJmYWNlKTsKICAgICAgICAgICAgLyogVGhpcy0+dGFyZ2V0IGlzIHRoZSBvZmZzY3JlZW4gdGFyZ2V0LgogICAgICAgICAgICAgKiBUaGlzLT5kZHJhdy0+ZDNkX3RhcmdldCBpcyB0aGUgdGFyZ2V0IHVzZWQgYnkgRERyYXcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIFJlbGVhc2U6IFVzaW5nICVwIGFzIGZyb250IGJ1ZmZlciwgJXAgYXMgYmFjayBidWZmZXJcbiIsIFRoaXMsIFRoaXMtPmRkcmF3LT5kM2RfdGFyZ2V0LCBOVUxMKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnJvbnRCYWNrQnVmZmVycyhUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmRkcmF3LT5kM2RfdGFyZ2V0LT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICB9CgogICAgICAgIC8qIFJlbGVhc2UgdGhlIFdpbmVEM0REZXZpY2UuIFRoaXMgd29uJ3QgZGVzdHJveSBpdCAqLwogICAgICAgIGlmKElXaW5lRDNERGV2aWNlX1JlbGVhc2UoVGhpcy0+d2luZUQzRERldmljZSkgPD0gMCkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiICglcCkgVGhlIHdpbmVEM0QgZGV2aWNlICVwIHdhcyBkZXN0cm95ZWQgdW5leHBlY3RhZGVseS4gUHJlcGFyZSBmb3IgdHJvdWJsZVxuIiwgVGhpcywgVGhpcy0+d2luZUQzRERldmljZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBUaGUgdGV4dHVyZSBoYW5kbGVzIHNob3VsZCBiZSB1bnNldCBieSBub3csIGJ1dCB0aGVyZSBtaWdodCBiZSBzb21lIGJpdHMKICAgICAgICAgKiBtaXNzaW5nIGluIG91ciByZWZlcmVuY2UgY291bnRpbmcobmVlZHMgdGVzdCkuIERvIGEgc2FuaXR5IGNoZWNrCiAgICAgICAgICovCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bnVtSGFuZGxlczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaWYoVGhpcy0+SGFuZGxlc1tpXS5wdHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaChUaGlzLT5IYW5kbGVzW2ldLnR5cGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBERHJhd0hhbmRsZV9UZXh0dXJlOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICopIFRoaXMtPkhhbmRsZXNbaV0ucHRyOwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVGV4dHVyZSBIYW5kbGUgJWQgbm90IHVuc2V0IHByb3Blcmx5XG4iLCBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1cmYtPkhhbmRsZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX01hdGVyaWFsOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNETWF0ZXJpYWxJbXBsICptYXQgPSAoSURpcmVjdDNETWF0ZXJpYWxJbXBsICopIFRoaXMtPkhhbmRsZXNbaV0ucHRyOwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiTWF0ZXJpYWwgaGFuZGxlICVkIG5vdCB1bnNldCBwcm9wZXJseVxuIiwgaSArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBtYXQtPkhhbmRsZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX01hdHJpeDoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vIGZpeG1lIGhlcmUgYmVjYXVzZSB0aGlzIG1pZ2h0IGhhcHBlbiBiZWNhdXNlIG9mIHNsb3BweSBhcHBzICovCiAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIkxlZnRvdmVyIG1hdHJpeCBoYW5kbGUgJWQsIGRlbGV0aW5nXG4iLCBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZV9EZWxldGVNYXRyaXgoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEREcmF3SGFuZGxlX1N0YXRlQmxvY2s6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBObyBmaXhtZSBoZXJlIGJlY2F1c2UgdGhpcyBtaWdodCBoYXBwZW4gYmVjYXVzZSBvZiBzbG9wcHkgYXBwcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJMZWZ0b3ZlciBzdGF0ZWJsb2NrIGhhbmRsZSAlZCwgZGVsZXRpbmdcbiIsIGkgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNERGV2aWNlN19EZWxldGVTdGF0ZUJsb2NrKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArIDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVua25vd24gaGFuZGxlICVkIG5vdCB1bnNldCBwcm9wZXJseVxuIiwgaSArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5IYW5kbGVzKTsKCiAgICAgICAgVFJBQ0UoIlJlbGVhc2luZyB0YXJnZXQgJXAgJXBcbiIsIFRoaXMtPnRhcmdldCwgVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQpOwogICAgICAgIC8qIFJlbGVhc2UgdGhlIHJlbmRlciB0YXJnZXQgYW5kIHRoZSBXaW5lRDNEIHJlbmRlciB0YXJnZXQKICAgICAgICAgKiAoU2VlIElEaXJlY3QzRDc6OkNyZWF0ZURldmljZSBmb3IgbW9yZSBjb21tZW50cyBvbiB0aGlzKQogICAgICAgICAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShUaGlzLT50YXJnZXQsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXctPmQzZF90YXJnZXQsSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgIFRSQUNFKCJUYXJnZXQgcmVsZWFzZSBkb25lXG4iKTsKCiAgICAgICAgVGhpcy0+ZGRyYXctPmQzZGRldmljZSA9IE5VTEw7CgogICAgICAgIC8qIE5vdyBmcmVlIHRoZSBzdHJ1Y3R1cmUgKi8KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgfQoKICAgIFRSQUNFKCJEb25lXG4iKTsKICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1JlbGVhc2UoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfUmVsZWFzZShJRGlyZWN0M0REZXZpY2UyICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9SZWxlYXNlKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlIE1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6SW5pdGlhbGl6ZQogKgogKiBJbml0aWFsaXplcyBhIERpcmVjdDNERGV2aWNlLiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGEgbm8tb3AsIGFzIGFsbAogKiBpbml0aWFsaXphdGlvbiBpcyBkb25lIGF0IGNyZWF0ZSB0aW1lLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBObyBpZGVhIHdoYXQgdGhleSBtZWFuLCBhcyB0aGUgTVNETiBwYWdlIGlzIGdvbmUKICoKICogUmV0dXJuczogRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0luaXRpYWxpemUoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEICpEaXJlY3QzRCwgR1VJRCAqZ3VpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CgogICAgLyogSXQgc2hvdWxkbid0IGJlIGNydWNpYWwsIGJ1dCBwcmludCBhIEZJWE1FLCBJJ20gaW50ZXJlc3RlZCBpZgogICAgICogYW55IGdhbWUgY2FsbHMgaXQgYW5kIHdoZW4KICAgICAqLwogICAgRklYTUUoIiglcCktPiglcCwlcCwlcCk6IE5vLW9wIVxuIiwgVGhpcywgRGlyZWN0M0QsIGd1aWQsIERlc2MpOwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRDYXBzCiAqCiAqIFJldHJpZXZlcyB0aGUgZGV2aWNlJ3MgY2FwYWJpbGl0aWVzCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgdXNlZCBmb3IgVmVyc2lvbiA3IG9ubHksIHRoZSBvbGRlciB2ZXJzaW9ucyBoYXZlCiAqIHRoZWlyIG93biBpbXBsZW1lbnRhdGlvbi4KICoKICogUGFyYW1ldGVyczoKICogIERlc2M6IFBvaW50ZXIgdG8gYSBEM0RERVZJQ0VERVNDNyBzdHJ1Y3R1cmUgdG8gZmlsbAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEQzREVSUl8qIGlmIGEgcHJvYmxlbSBvY2N1cnMuIFNlZSBXaW5lRDNECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRDYXBzKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RERVZJQ0VERVNDNyAqRGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgRDNEREVWSUNFREVTQyBPbGREZXNjOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIERlc2MpOwoKICAgIC8qIENhbGwgdGhlIHNhbWUgZnVuY3Rpb24gdXNlZCBieSBJRGlyZWN0M0QsIHRoaXMgc2F2ZXMgY29kZSAqLwogICAgcmV0dXJuIElEaXJlY3QzREltcGxfR2V0Q2FwcyhUaGlzLT5kZHJhdy0+d2luZUQzRCwgJk9sZERlc2MsIERlc2MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6R2V0Q2FwcwogKgogKiBSZXRyaWV2ZXMgdGhlIGNhcGFiaWxpdGllcyBvZiB0aGUgaGFyZHdhcmUgZGV2aWNlIGFuZCB0aGUgZW11bGF0aW9uCiAqIGRldmljZS4gRm9yIFdpbmUsIGhhcmR3YXJlIGFuZCBlbXVsYXRpb24gYXJlIHRoZSBzYW1lIChpdCdzIGFsbCBIVykuCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgdXNlZCBmb3IgVmVyc2lvbiAxLCAyLCBhbmQgMy4gVmVyc2lvbiA3IGhhcyBpdHMgb3duCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBIV0Rlc2M6IFN0cnVjdHVyZSB0byBmaWxsIHdpdGggdGhlIEhXIGNhcHMKICogIEhlbERlc2M6IFN0cnVjdHVyZSB0byBmaWxsIHdpdGggdGhlIGhhcmRhcmUgZW11bGF0aW9uIGNhcHMKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfKiBpZiBhIHByb2JsZW0gb2NjdXJzLiBTZWUgV2luZUQzRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q2FwcyhJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqSFdEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RERVZJQ0VERVNDICpIZWxEZXNjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBEM0RERVZJQ0VERVNDNyBuZXdEZXNjOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBpZmFjZSwgSFdEZXNjLCBIZWxEZXNjKTsKCiAgICBociA9IElEaXJlY3QzREltcGxfR2V0Q2FwcyhUaGlzLT5kZHJhdy0+d2luZUQzRCwgSFdEZXNjLCAmbmV3RGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKCiAgICAqSGVsRGVzYyA9ICpIV0Rlc2M7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldENhcHMoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERFVklDRURFU0MgKkQzREhXRGV2RGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRDNESEVMRGV2RGVzYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwLCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIEQzREhXRGV2RGVzYywgRDNESEVMRGV2RGVzYyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRDYXBzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RIV0RldkRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzREhFTERldkRlc2MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0dldENhcHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEREVWSUNFREVTQyAqRDNESFdEZXZEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RERVZJQ0VERVNDICpEM0RIRUxEZXZEZXNjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEM0RIV0RldkRlc2MsIEQzREhFTERldkRlc2MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfR2V0Q2FwcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNESFdEZXZEZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RIRUxEZXZEZXNjKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTI6OlN3YXBUZXh0dXJlSGFuZGxlcwogKgogKiBTd2FwcyB0aGUgdGV4dHVyZSBoYW5kbGVzIG9mIDIgVGV4dHVyZSBpbnRlcmZhY2VzLiBWZXJzaW9uIDEgYW5kIDIKICoKICogUGFyYW1ldGVyczoKICogIFRleDEsIFRleDI6IFRoZSAyIFRleHR1cmVzIHRvIHN3YXAKICoKICogUmV0dXJuczoKICogIEQzRF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzJfU3dhcFRleHR1cmVIYW5kbGVzKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICpUZXgxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICpUZXgyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBEV09SRCBzd2FwOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjEgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlMiwgVGV4MSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmMiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBUZXgyKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBzdXJmMSwgc3VyZjIpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBUaGlzLT5IYW5kbGVzW3N1cmYxLT5IYW5kbGUgLSAxXS5wdHIgPSBzdXJmMjsKICAgIFRoaXMtPkhhbmRsZXNbc3VyZjItPkhhbmRsZSAtIDFdLnB0ciA9IHN1cmYxOwoKICAgIHN3YXAgPSBzdXJmMi0+SGFuZGxlOwogICAgc3VyZjItPkhhbmRsZSA9IHN1cmYxLT5IYW5kbGU7CiAgICBzdXJmMS0+SGFuZGxlID0gc3dhcDsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9Td2FwVGV4dHVyZUhhbmRsZXMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RUZXh0dXJlICpEM0RUZXgxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUgKkQzRFRleDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjEgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlLCBEM0RUZXgxKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYyID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgRDNEVGV4Mik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTIgaW50ZXJmYWNlLlxuIiwgVGhpcywgc3VyZjEsIHN1cmYyKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UyX1N3YXBUZXh0dXJlSGFuZGxlcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRShzdXJmMSwgSURpcmVjdDNEVGV4dHVyZTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHN1cmYyLCBJRGlyZWN0M0RUZXh0dXJlMikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6R2V0U3RhdHMKICoKICogVGhpcyBtZXRob2Qgc2VlbXMgdG8gcmV0cmlldmUgc29tZSBzdGF0cyBmcm9tIHRoZSBkZXZpY2UuCiAqIFRoZSBNU0ROIGRvY3VtZW50YXRpb24gZG9lc24ndCBleGlzdCBhbnkgbW9yZSwgYnV0IHRoZSBEM0RTVEFUUwogKiBzdHJ1Y3R1cmUgc3VnZ2VzdHMgdGhhdCB0aGUgYW1vdXQgb2YgZHJhd24gcHJpbWl0aXZlcyBhbmQgcHJvY2Vzc2VkCiAqIHZlcnRpY2VzIGlzIHJldHVybmVkLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyIGFuZCAzCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBTdGF0czogUG9pbnRlciB0byBhIEQzRFNUQVRTIHN0cnVjdHVyZSB0byBiZSBmaWxsZWQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFN0YXRzID09IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFN0YXRzKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEU1RBVFMgKlN0YXRzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwKTogU3R1YiFcbiIsIFRoaXMsIFN0YXRzKTsKCiAgICBpZighU3RhdHMpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogRmlsbCB0aGUgU3RhdHMgd2l0aCAwICovCiAgICBTdGF0cy0+ZHdUcmlhbmdsZXNEcmF3biA9IDA7CiAgICBTdGF0cy0+ZHdMaW5lc0RyYXduID0gMDsKICAgIFN0YXRzLT5kd1BvaW50c0RyYXduID0gMDsKICAgIFN0YXRzLT5kd1NwYW5zRHJhd24gPSAwOwogICAgU3RhdHMtPmR3VmVydGljZXNQcm9jZXNzZWQgPSAwOwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0U3RhdHMoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RTVEFUUyAqU3RhdHMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBTdGF0cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRTdGF0cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9HZXRTdGF0cyhJRGlyZWN0M0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEU1RBVFMgKlN0YXRzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBTdGF0cyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRTdGF0cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6Q3JlYXRlRXhlY3V0ZUJ1ZmZlcgogKgogKiBDcmVhdGVzIGFuIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIsIHVzZWQgZm9yIHJlbmRlcmluZyB3aXRoIGEKICogRGlyZWN0M0REZXZpY2UuCiAqCiAqIFZlcnNpb24gMSBvbmx5LgogKgogKiBQYXJhbXM6CiAqICBEZXNjOiBCdWZmZXIgZGVzY3JpcHRpb24KICogIEV4ZWN1dGVCdWZmZXI6IEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBJbnRlcmZhY2UgcG9pbnRlciBhdAogKiAgVW5rT3V0ZXI6IE11c3QgYmUgTlVMTC4gQmFzaWNhbGx5IGZvciBhZ2dyZWdhdGlvbiwgd2hpY2ggZGRyYXcgZG9lc24ndAogKiAgICAgICAgICAgIHN1cHBvcnQKICoKICogUmV0dXJuczoKICogIENMQVNTX0VfTk9BR0dSRUdBVElPTiBpZiBVbmtPdXRlciAhPSBOVUxMCiAqICBEREVSUl9PVVRPRk1FTU9SWSBpZiB3ZSByYW4gb3V0IG9mIG1lbW9yeQogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0NyZWF0ZUV4ZWN1dGVCdWZmZXIoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERVhFQ1VURUJVRkZFUkRFU0MgKkRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIgKipFeGVjdXRlQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwqIG9iamVjdDsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXApIVxuIiwgVGhpcywgRGVzYywgRXhlY3V0ZUJ1ZmZlciwgVW5rT3V0ZXIpOwoKICAgIGlmKFVua091dGVyKQogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgLyogQWxsb2NhdGUgdGhlIG5ldyBFeGVjdXRlIEJ1ZmZlciAqLwogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCkpOwogICAgaWYoIW9iamVjdCkKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIGEgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwgc3RydWN0dXJlXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIsIElEaXJlY3QzREV4ZWN1dGVCdWZmZXJfVnRibCk7CgogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT5kM2RkZXYgPSBUaGlzOwoKICAgIC8qIEluaXRpYWxpemVzIG1lbW9yeSAqLwogICAgbWVtY3B5KCZvYmplY3QtPmRlc2MsIERlc2MsIERlc2MtPmR3U2l6ZSk7CgogICAgLyogTm8gYnVmZmVyIGdpdmVuICovCiAgICBpZiAoKG9iamVjdC0+ZGVzYy5kd0ZsYWdzICYgRDNEREVCX0xQREFUQSkgPT0gMCkKICAgICAgICBvYmplY3QtPmRlc2MubHBEYXRhID0gTlVMTDsKCiAgICAvKiBObyBidWZmZXIgc2l6ZSBnaXZlbiAqLwogICAgaWYgKChvYmplY3QtPmRlc2MuZHdGbGFncyAmIEQzRERFQl9CVUZTSVpFKSA9PSAwKQogICAgICAgIG9iamVjdC0+ZGVzYy5kd0J1ZmZlclNpemUgPSAwOwoKICAgIC8qIENyZWF0ZSBidWZmZXIgaWYgYXNrZWQgKi8KICAgIGlmICgob2JqZWN0LT5kZXNjLmxwRGF0YSA9PSBOVUxMKSAmJiAob2JqZWN0LT5kZXNjLmR3QnVmZmVyU2l6ZSA+IDApKQogICAgewogICAgICAgIG9iamVjdC0+bmVlZF9mcmVlID0gVFJVRTsKICAgICAgICBvYmplY3QtPmRlc2MubHBEYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxvYmplY3QtPmRlc2MuZHdCdWZmZXJTaXplKTsKICAgICAgICBpZighb2JqZWN0LT5kZXNjLmxwRGF0YSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgdGhlIGV4ZWN1dGUgYnVmZmVyIGRhdGFcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG9iamVjdC0+bmVlZF9mcmVlID0gRkFMU0U7CiAgICB9CgogICAgLyogTm8gdmVydGljZXMgZm9yIHRoZSBtb21lbnQgKi8KICAgIG9iamVjdC0+dmVydGV4X2RhdGEgPSBOVUxMOwoKICAgIG9iamVjdC0+ZGVzYy5kd0ZsYWdzIHw9IEQzRERFQl9MUERBVEE7CgogICAgb2JqZWN0LT5pbmRpY2VzID0gTlVMTDsKICAgIG9iamVjdC0+bmJfaW5kaWNlcyA9IDA7CgogICAgKkV4ZWN1dGVCdWZmZXIgPSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIpOwoKICAgIFRSQUNFKCIgUmV0dXJuaW5nIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIgYXQgJXAsIGltcGxlbWVudGF0aW9uIGlzIGF0ICVwXG4iLCAqRXhlY3V0ZUJ1ZmZlciwgb2JqZWN0KTsKCiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlOjpFeGVjdXRlCiAqCiAqIEV4ZWN1dGVzIGFsbCB0aGUgc3R1ZmYgaW4gYW4gZXhlY3V0ZSBidWZmZXIuCiAqCiAqIFBhcmFtczoKICogIEV4ZWN1dGVCdWZmZXI6IFRoZSBidWZmZXIgdG8gZXhlY3V0ZQogKiAgVmlld3BvcnQ6IFRoZSB2aWV3cG9ydCB1c2VkIGZvciByZW5kZXJpbmcKICogIEZsYWdzOiBTb21lIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEV4ZWN1dGVCdWZmZXIgPT0gTlVMTAogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0V4ZWN1dGUoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlciAqRXhlY3V0ZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQgKlZpZXdwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCAqRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsLCBJRGlyZWN0M0RFeGVjdXRlQnVmZmVyLCBFeGVjdXRlQnVmZmVyKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqRGlyZWN0M0RWaWV3cG9ydEltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgVmlld3BvcnQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJTA4eClcbiIsIFRoaXMsIERpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwsIERpcmVjdDNEVmlld3BvcnRJbXBsLCBGbGFncyk7CgogICAgaWYoIURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogRXhlY3V0ZS4uLiAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIElEaXJlY3QzREV4ZWN1dGVCdWZmZXJJbXBsX0V4ZWN1dGUoRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCwgVGhpcywgRGlyZWN0M0RWaWV3cG9ydEltcGwpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6QWRkVmlld3BvcnQKICoKICogQWRkIGEgRGlyZWN0M0RWaWV3cG9ydCB0byB0aGUgZGV2aWNlJ3Mgdmlld3BvcnQgbGlzdC4gVGhlc2Ugdmlld3BvcnRzCiAqIGFyZSB3cmFwcGVkIHRvIElEaXJlY3QzRERldmljZTcgdmlld3BvcnRzIGluIHZpZXdwb3J0LmMKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiBhbmQgMy4gTm90ZSB0aGF0IElEaXJlY3QzRFZpZXdwb3J0IDEsIDIgYW5kIDMKICogYXJlIHRoZSBzYW1lIGludGVyZmFjZXMuCiAqCiAqIFBhcmFtczoKICogIFZpZXdwb3J0OiBUaGUgdmlld3BvcnQgdG8gYWRkCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZpZXdwb3J0ID09IE5VTEwKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19BZGRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqVmlld3BvcnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgVmlld3BvcnQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCB2cCk7CgogICAgLyogU2FuaXR5IGNoZWNrICovCiAgICBpZighdnApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHZwLT5uZXh0ID0gVGhpcy0+dmlld3BvcnRfbGlzdDsKICAgIFRoaXMtPnZpZXdwb3J0X2xpc3QgPSB2cDsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9BZGRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqRGlyZWN0M0RWaWV3cG9ydDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0FkZFZpZXdwb3J0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodnAsIElEaXJlY3QzRFZpZXdwb3J0MykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0FkZFZpZXdwb3J0KElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydCAqRGlyZWN0M0RWaWV3cG9ydCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIERpcmVjdDNEVmlld3BvcnQpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0FkZFZpZXdwb3J0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodnAsIElEaXJlY3QzRFZpZXdwb3J0MykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6RGVsZXRlVmlld3BvcnQKICoKICogRGVsZXRlcyBhIERpcmVjdDNEVmlld3BvcnQgZnJvbSB0aGUgZGV2aWNlJ3Mgdmlld3BvcnQgbGlzdC4KICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiBhbmQgMy4gTm90ZSB0aGF0IGFsbCBWaWV3cG9ydCBpbnRlcmZhY2UgdmVyc2lvbnMKICogYXJlIGVxdWFsLgogKgogKiBQYXJhbXM6CiAqICBWaWV3cG9ydDogVGhlIHZpZXdwb3J0IHRvIGRlbGV0ZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIHZpZXdwb3J0IHdhc24ndCBmb3VuZCBpbiB0aGUgbGlzdAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfRGVsZXRlVmlld3BvcnQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKlZpZXdwb3J0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gKElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqKSBWaWV3cG9ydDsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqY3VyX3ZpZXdwb3J0LCAqcHJldl92aWV3cG9ydCA9IE5VTEw7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHZwKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgY3VyX3ZpZXdwb3J0ID0gVGhpcy0+dmlld3BvcnRfbGlzdDsKICAgIHdoaWxlIChjdXJfdmlld3BvcnQgIT0gTlVMTCkKICAgIHsKICAgICAgICBpZiAoY3VyX3ZpZXdwb3J0ID09IHZwKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHByZXZfdmlld3BvcnQgPT0gTlVMTCkgVGhpcy0+dmlld3BvcnRfbGlzdCA9IGN1cl92aWV3cG9ydC0+bmV4dDsKICAgICAgICAgICAgZWxzZSBwcmV2X3ZpZXdwb3J0LT5uZXh0ID0gY3VyX3ZpZXdwb3J0LT5uZXh0OwogICAgICAgICAgICAvKiBUT0RPIDogYWRkIGRlc2FjdGl2YXRlIG9mIHRoZSB2aWV3cG9ydCBhbmQgYWxsIGFzc29jaWF0ZWQgbGlnaHRzLi4uICovCiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEM0RfT0s7CiAgICAgICAgfQogICAgICAgIHByZXZfdmlld3BvcnQgPSBjdXJfdmlld3BvcnQ7CiAgICAgICAgY3VyX3ZpZXdwb3J0ID0gY3VyX3ZpZXdwb3J0LT5uZXh0OwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EZWxldGVWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqRGlyZWN0M0RWaWV3cG9ydDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0RlbGV0ZVZpZXdwb3J0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodnAsIElEaXJlY3QzRFZpZXdwb3J0MykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0RlbGV0ZVZpZXdwb3J0KElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydCAqRGlyZWN0M0RWaWV3cG9ydCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIERpcmVjdDNEVmlld3BvcnQpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0RlbGV0ZVZpZXdwb3J0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodnAsIElEaXJlY3QzRFZpZXdwb3J0MykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6TmV4dFZpZXdwb3J0CiAqCiAqIFJldHVybnMgYSB2aWV3cG9ydCBmcm9tIHRoZSB2aWV3cG9ydCBsaXN0LCBkZXBlbmRpbmcgb24gdGhlCiAqIHBhc3NlZCB2aWV3cG9ydCBhbmQgdGhlIGZsYWdzLgogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyIGFuZCAzLiBOb3RlIHRoYXQgYWxsIFZpZXdwb3J0IGludGVyZmFjZSB2ZXJzaW9ucwogKiBhcmUgZXF1YWwuCiAqCiAqIFBhcmFtczoKICogIFZpZXdwb3J0OiBWaWV3cG9ydCB0byB1c2UgZm9yIGJlZ2lubmluZyB0aGUgc2VhcmNoCiAqICBGbGFnczogRDNETkVYVF9ORVhULCBEM0RORVhUX0hFQUQgb3IgRDNETkVYVF9UQUlMCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgZmxhZ3Mgd2VyZSB3cm9uZywgb3IgVmlld3BvcnQgd2FzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX05leHRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKlZpZXdwb3J0MywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKipscGxwRGlyZWN0M0RWaWV3cG9ydDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgVmlld3BvcnQzKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqcmVzID0gTlVMTDsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCUwOHgpXG4iLCBUaGlzLCB2cCwgbHBscERpcmVjdDNEVmlld3BvcnQzLCBGbGFncyk7CgogICAgaWYoIXZwKQogICAgewogICAgICAgICpscGxwRGlyZWN0M0RWaWV3cG9ydDMgPSBOVUxMOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoIChGbGFncykKICAgIHsKICAgICAgICBjYXNlIEQzRE5FWFRfTkVYVDoKICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IHZwLT5uZXh0OwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRE5FWFRfSEVBRDoKICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IFRoaXMtPnZpZXdwb3J0X2xpc3Q7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNETkVYVF9UQUlMOgogICAgICAgIHsKICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICpjdXJfdmlld3BvcnQgPSBUaGlzLT52aWV3cG9ydF9saXN0OwogICAgICAgICAgICBpZiAoY3VyX3ZpZXdwb3J0ICE9IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdoaWxlIChjdXJfdmlld3BvcnQtPm5leHQgIT0gTlVMTCkgY3VyX3ZpZXdwb3J0ID0gY3VyX3ZpZXdwb3J0LT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcyA9IGN1cl92aWV3cG9ydDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgKmxwbHBEaXJlY3QzRFZpZXdwb3J0MyA9IE5VTEw7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgICpscGxwRGlyZWN0M0RWaWV3cG9ydDMgPSBJQ09NX0lOVEVSRkFDRShyZXMsIElEaXJlY3QzRFZpZXdwb3J0Myk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9OZXh0Vmlld3BvcnQoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQyICpWaWV3cG9ydDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQyICoqbHBscERpcmVjdDNEVmlld3BvcnQyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIFZpZXdwb3J0Mik7CiAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKnJlczsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXAsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCB2cCwgbHBscERpcmVjdDNEVmlld3BvcnQyLCBGbGFncyk7CiAgICBociA9IElEaXJlY3QzRERldmljZTNfTmV4dFZpZXdwb3J0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwogICAgKmxwbHBEaXJlY3QzRFZpZXdwb3J0MiA9IChJRGlyZWN0M0RWaWV3cG9ydDIgKikgQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBJRGlyZWN0M0RWaWV3cG9ydDMsIHJlcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfTmV4dFZpZXdwb3J0KElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVmlld3BvcnQgKlZpZXdwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0ICoqbHBscERpcmVjdDNEVmlld3BvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdDNEVmlld3BvcnRJbXBsICp2cCA9IElDT01fT0JKRUNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBWaWV3cG9ydCk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKnJlczsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXAsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCB2cCwgbHBscERpcmVjdDNEVmlld3BvcnQsIEZsYWdzKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlM19OZXh0Vmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHZwLCBJRGlyZWN0M0RWaWV3cG9ydDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICAqbHBscERpcmVjdDNEVmlld3BvcnQgPSAoSURpcmVjdDNEVmlld3BvcnQgKikgQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3QzRFZpZXdwb3J0SW1wbCwgSURpcmVjdDNEVmlld3BvcnQzLCBJRGlyZWN0M0RWaWV3cG9ydDMsIHJlcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OlBpY2sKICoKICogRXhlY3V0ZXMgYW4gZXhlY3V0ZSBidWZmZXIgd2l0aG91dCBwZXJmb3JtaW5nIHJlbmRlcmluZy4gSW5zdGVhZCwgYQogKiBsaXN0IG9mIHByaW1pdGl2ZXMgdGhhdCBpbnRlcnNlY3Qgd2l0aCAoeDEseTEpIG9mIHRoZSBwYXNzZWQgcmVjdGFuZ2xlCiAqIGlzIGNyZWF0ZWQuIElEaXJlY3QzRERldmljZTo6R2V0UGlja1JlY29yZHMgY2FuIGJlIHVzZWQgdG8gcmV0cmlldmUKICogdGhpcyBsaXN0LgogKgogKiBWZXJzaW9uIDEgb25seQogKgogKiBQYXJhbXM6CiAqICBFeGVjdXRlQnVmZmVyOiBCdWZmZXIgdG8gZXhlY3V0ZQogKiAgVmlld3BvcnQ6IFZpZXdwb3J0IHRvIHVzZSBmb3IgZXhlY3V0aW9uCiAqICBGbGFnczogTm9uZSBhcmUgZGVmaW5lZCwgYWNjb3JkaW5nIHRvIHRoZSBTREsKICogIFJlY3Q6IFNwZWNpZmllcyB0aGUgY29vcmRpbmF0ZXMgdG8gYmUgcGlja2VkLiBPbmx5IHgxIGFuZCB5MiBhcmUgdXNlZCwKICogICAgICAgIHgyIGFuZCB5MiBhcmUgaWdub3JlZC4KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9QaWNrKElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzREV4ZWN1dGVCdWZmZXIgKkV4ZWN1dGVCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0ICpWaWV3cG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFQ1QgKlJlY3QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlckltcGwgKmV4ZWNidWYgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RFeGVjdXRlQnVmZmVySW1wbCwgSURpcmVjdDNERXhlY3V0ZUJ1ZmZlciwgRXhlY3V0ZUJ1ZmZlcik7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIFZpZXdwb3J0KTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJXAsJTA4eCwlcCk6IHN0dWIhXG4iLCBUaGlzLCBleGVjYnVmLCB2cCwgRmxhZ3MsIFJlY3QpOwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OkdldFBpY2tSZWNvcmRzCiAqCiAqIFJldHJpZXZlcyB0aGUgcGljayByZWNvcmRzIGdlbmVyYXRlZCBieSBJRGlyZWN0M0REZXZpY2U6OkdldFBpY2tSZWNvcmRzCiAqCiAqIFZlcnNpb24gMSBvbmx5CiAqCiAqIFBhcmFtczoKICogIENvdW50OiBQb2ludGVyIHRvIGEgRFdPUkQgY29udGFpbmluZyB0aGUgbnVtYmVycyBvZiBwaWNrIHJlY29yZHMgdG8KICogICAgICAgICByZXRyaWV2ZQogKiAgRDNEUGlja1JlYzogQWRkcmVzcyB0byBzdG9yZSB0aGUgcmVzdWx0aW5nIEQzRFBJQ0tSRUNPUkQgYXJyeS4KICoKICogUmV0dXJuczoKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0UGlja1JlY29yZHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBJQ0tSRUNPUkQgKkQzRFBpY2tSZWMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCwlcCk6IHN0dWIhXG4iLCBUaGlzLCBDb3VudCwgRDNEUGlja1JlYyk7CgogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkVudW1UZXh0dXJlZm9ybWF0cwogKgogKiBFbnVtZXJhdGVzIHRoZSBzdXBwb3J0ZWQgdGV4dHVyZSBmb3JtYXRzLiBJdCBoYXMgYSBsaXN0IG9mIGFsbCBwb3NzaWJsZQogKiBmb3JtYXRzIGFuZCBjYWxscyBJV2luZUQzRDo6Q2hlY2tEZXZpY2VGb3JtYXQgZm9yIGVhY2ggZm9ybWF0IHRvIHNlZSBpZgogKiBXaW5lRDNEIHN1cHBvcnRzIGl0LiBJZiBzbywgdGhlbiBpdCBpcyBwYXNzZWQgdG8gdGhlIGFwcC4KICoKICogVGhpcyBpcyBmb3IgVmVyc2lvbiA3IGFuZCAzLCBvbGRlciB2ZXJzaW9ucyBoYXZlIGEgZGlmZmVyZW50CiAqIGNhbGxiYWNrIGZ1bmN0aW9uIGFuZCB0aGVpciBvd24gaW1wbGVtZW50YXRpb24KICoKICogUGFyYW1zOgogKiAgQ2FsbGJhY2s6IENhbGxiYWNrIHRvIGNhbGwgZm9yIGVhY2ggZW51bWVyYXRlZCBmb3JtYXQKICogIEFyZzogQXJndW1lbnQgdG8gcGFzcyB0byB0aGUgY2FsbGJhY2sKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhbGxiYWNrID09IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0VudW1UZXh0dXJlRm9ybWF0cyhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEQzREVOVU1QSVhFTEZPUk1BVFNDQUxMQkFDSyBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpBcmcpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBpbnQgaTsKCiAgICBXSU5FRDNERk9STUFUIEZvcm1hdExpc3RbXSA9IHsKICAgICAgICAvKiAzMiBiaXQgKi8KICAgICAgICBXSU5FRDNERk1UX0E4UjhHOEI4LAogICAgICAgIFdJTkVEM0RGTVRfWDhSOEc4QjgsCiAgICAgICAgLyogMjQgYml0ICovCiAgICAgICAgV0lORUQzREZNVF9SOEc4QjgsCiAgICAgICAgLyogMTYgQml0ICovCiAgICAgICAgV0lORUQzREZNVF9BMVI1RzVCNSwKICAgICAgICBXSU5FRDNERk1UX0E0UjRHNEI0LAogICAgICAgIFdJTkVEM0RGTVRfUjVHNkI1LAogICAgICAgIFdJTkVEM0RGTVRfWDFSNUc1QjUsCiAgICAgICAgLyogOCBCaXQgKi8KICAgICAgICBXSU5FRDNERk1UX1IzRzNCMiwKICAgICAgICBXSU5FRDNERk1UX1A4LAogICAgICAgIC8qIEZPVVJDQyBjb2RlcyAqLwogICAgICAgIFdJTkVEM0RGTVRfRFhUMSwKICAgICAgICBXSU5FRDNERk1UX0RYVDMsCiAgICAgICAgV0lORUQzREZNVF9EWFQ1LAogICAgfTsKCiAgICBXSU5FRDNERk9STUFUIEJ1bXBGb3JtYXRMaXN0W10gPSB7CiAgICAgICAgV0lORUQzREZNVF9WOFU4LAogICAgICAgIFdJTkVEM0RGTVRfTDZWNVU1LAogICAgICAgIFdJTkVEM0RGTVRfWDhMOFY4VTgsCiAgICAgICAgV0lORUQzREZNVF9ROFc4VjhVOCwKICAgICAgICBXSU5FRDNERk1UX1YxNlUxNiwKICAgICAgICBXSU5FRDNERk1UX1cxMVYxMVUxMCwKICAgICAgICBXSU5FRDNERk1UX0EyVzEwVjEwVTEwCiAgICB9OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApOiBSZWxheVxuIiwgVGhpcywgQ2FsbGJhY2ssIEFyZyk7CgogICAgaWYoIUNhbGxiYWNrKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBmb3IoaSA9IDA7IGkgPCBzaXplb2YoRm9ybWF0TGlzdCkgLyBzaXplb2YoV0lORUQzREZPUk1BVCk7IGkrKykKICAgIHsKICAgICAgICBociA9IElXaW5lRDNEX0NoZWNrRGV2aWNlRm9ybWF0KFRoaXMtPmRkcmF3LT53aW5lRDNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBEZXZpY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyRm9ybWF0ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBVc2FnZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogUmVzb3VyY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0TGlzdFtpXSk7CiAgICAgICAgaWYoaHIgPT0gRDNEX09LKQogICAgICAgIHsKICAgICAgICAgICAgRERQSVhFTEZPUk1BVCBwZm9ybWF0OwoKICAgICAgICAgICAgbWVtc2V0KCZwZm9ybWF0LCAwLCBzaXplb2YocGZvcm1hdCkpOwogICAgICAgICAgICBwZm9ybWF0LmR3U2l6ZSA9IHNpemVvZihwZm9ybWF0KTsKICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJnBmb3JtYXQsIEZvcm1hdExpc3RbaV0pOwoKICAgICAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nIFdpbmVEM0RGb3JtYXQgJWRcbiIsIEZvcm1hdExpc3RbaV0pOwogICAgICAgICAgICBociA9IENhbGxiYWNrKCZwZm9ybWF0LCBBcmcpOwogICAgICAgICAgICBpZihociAhPSBEREVOVU1SRVRfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJGb3JtYXQgZW51bWVyYXRpb24gY2FuY2VsbGVkIGJ5IGFwcGxpY2F0aW9uXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRDNEX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZvcihpID0gMDsgaSA8IHNpemVvZihCdW1wRm9ybWF0TGlzdCkgLyBzaXplb2YoV0lORUQzREZPUk1BVCk7IGkrKykKICAgIHsKICAgICAgICBociA9IElXaW5lRDNEX0NoZWNrRGV2aWNlRm9ybWF0KFRoaXMtPmRkcmF3LT53aW5lRDNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBEZXZpY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyRm9ybWF0ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFVTQUdFX1FVRVJZX0xFR0FDWUJVTVBNQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFJlc291cmNlVHlwZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1bXBGb3JtYXRMaXN0W2ldKTsKICAgICAgICBpZihociA9PSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBERFBJWEVMRk9STUFUIHBmb3JtYXQ7CgogICAgICAgICAgICBtZW1zZXQoJnBmb3JtYXQsIDAsIHNpemVvZihwZm9ybWF0KSk7CiAgICAgICAgICAgIHBmb3JtYXQuZHdTaXplID0gc2l6ZW9mKHBmb3JtYXQpOwogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmcGZvcm1hdCwgQnVtcEZvcm1hdExpc3RbaV0pOwoKICAgICAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nIFdpbmVEM0RGb3JtYXQgJWRcbiIsIEJ1bXBGb3JtYXRMaXN0W2ldKTsKICAgICAgICAgICAgaHIgPSBDYWxsYmFjaygmcGZvcm1hdCwgQXJnKTsKICAgICAgICAgICAgaWYoaHIgIT0gRERFTlVNUkVUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiRm9ybWF0IGVudW1lcmF0aW9uIGNhbmNlbGxlZCBieSBhcHBsaWNhdGlvblxuIik7CiAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIEQzRF9PSzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIFRSQUNFKCJFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRW51bVRleHR1cmVGb3JtYXRzKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNERU5VTVBJWEVMRk9STUFUU0NBTExCQUNLIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkFyZykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwLCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENhbGxiYWNrLCBBcmcpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRW51bVRleHR1cmVGb3JtYXRzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UyOjpFbnVtVGV4dHVyZWZvcm1hdHMKICoKICogRW51bVRleHR1cmVGb3JtYXRzIGZvciBWZXJzaW9uIDEgYW5kIDIsIHNlZQogKiBJRGlyZWN0M0REZXZpY2U3OjpFbnVtVGV4dXJlRm9ybWF0cyBmb3IgYSBtb3JlIGRldGFpbGVkIGRlc2NyaXB0aW9uLgogKgogKiBUaGlzIHZlcnNpb24gaGFzIGEgZGlmZmVyZW50IGNhbGxiYWNrIGFuZCBkb2VzIG5vdCBlbnVtZXJhdGUgRm91ckNDCiAqIGZvcm1hdHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8yX0VudW1UZXh0dXJlRm9ybWF0cyhJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEQzREVOVU1URVhUVVJFRk9STUFUU0NBTExCQUNLIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkFyZykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIGludCBpOwoKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0TGlzdFtdID0gewogICAgICAgIC8qIDMyIGJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfQThSOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9YOFI4RzhCOCwKICAgICAgICAvKiAyNCBiaXQgKi8KICAgICAgICBXSU5FRDNERk1UX1I4RzhCOCwKICAgICAgICAvKiAxNiBCaXQgKi8KICAgICAgICBXSU5FRDNERk1UX0ExUjVHNUI1LAogICAgICAgIFdJTkVEM0RGTVRfQTRSNEc0QjQsCiAgICAgICAgV0lORUQzREZNVF9SNUc2QjUsCiAgICAgICAgV0lORUQzREZNVF9YMVI1RzVCNSwKICAgICAgICAvKiA4IEJpdCAqLwogICAgICAgIFdJTkVEM0RGTVRfUjNHM0IyLAogICAgICAgIFdJTkVEM0RGTVRfUDgsCiAgICAgICAgLyogRk9VUkNDIGNvZGVzIC0gTm90IGluIHRoaXMgdmVyc2lvbiovCiAgICB9OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApOiBSZWxheVxuIiwgVGhpcywgQ2FsbGJhY2ssIEFyZyk7CgogICAgaWYoIUNhbGxiYWNrKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBmb3IoaSA9IDA7IGkgPCBzaXplb2YoRm9ybWF0TGlzdCkgLyBzaXplb2YoV0lORUQzREZPUk1BVCk7IGkrKykKICAgIHsKICAgICAgICBociA9IElXaW5lRDNEX0NoZWNrRGV2aWNlRm9ybWF0KFRoaXMtPmRkcmF3LT53aW5lRDNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBEZXZpY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBBZGFwdGVyRm9ybWF0ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBVc2FnZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogUmVzb3VyY2VUeXBlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0TGlzdFtpXSk7CiAgICAgICAgaWYoaHIgPT0gRDNEX09LKQogICAgICAgIHsKICAgICAgICAgICAgRERTVVJGQUNFREVTQyBzZGVzYzsKCiAgICAgICAgICAgIG1lbXNldCgmc2Rlc2MsIDAsIHNpemVvZihzZGVzYykpOwogICAgICAgICAgICBzZGVzYy5kd1NpemUgPSBzaXplb2Yoc2Rlc2MpOwogICAgICAgICAgICBzZGVzYy5kd0ZsYWdzID0gRERTRF9QSVhFTEZPUk1BVCB8IEREU0RfQ0FQUzsKICAgICAgICAgICAgc2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX1RFWFRVUkU7CiAgICAgICAgICAgIHNkZXNjLmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2Yoc2Rlc2MuZGRwZlBpeGVsRm9ybWF0KTsKICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJnNkZXNjLmRkcGZQaXhlbEZvcm1hdCwgRm9ybWF0TGlzdFtpXSk7CgogICAgICAgICAgICBUUkFDRSgiRW51bWVyYXRpbmcgV2luZUQzREZvcm1hdCAlZFxuIiwgRm9ybWF0TGlzdFtpXSk7CiAgICAgICAgICAgIGhyID0gQ2FsbGJhY2soJnNkZXNjLCBBcmcpOwogICAgICAgICAgICBpZihociAhPSBEREVOVU1SRVRfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJGb3JtYXQgZW51bWVyYXRpb24gY2FuY2VsbGVkIGJ5IGFwcGxpY2F0aW9uXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRDNEX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9FbnVtVGV4dHVyZUZvcm1hdHMoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEQzREVOVU1URVhUVVJFRk9STUFUU0NBTExCQUNLIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkFyZykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTIgaW50ZXJmYWNlLlxuIiwgVGhpcywgQ2FsbGJhY2ssIEFyZyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlMl9FbnVtVGV4dHVyZUZvcm1hdHMoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6Q3JlYXRlTWF0cml4CiAqCiAqIENyZWF0ZXMgYSBtYXRyaXggaGFuZGxlLiBBIGhhbmRsZSBpcyBjcmVhdGVkIGFuZCBtZW1vcnkgZm9yIGEgRDNETUFUUklYIGlzCiAqIGFsbG9jYXRlZCBmb3IgdGhlIGhhbmRsZS4KICoKICogVmVyc2lvbiAxIG9ubHkKICoKICogUGFyYW1zCiAqICBEM0RNYXRIYW5kbGU6IEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBoYW5kbGUgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRE1hdEhhbmRsZSA9IE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8xX0NyZWF0ZU1hdHJpeChJRGlyZWN0M0REZXZpY2UgKmlmYWNlLCBEM0RNQVRSSVhIQU5ETEUgKkQzRE1hdEhhbmRsZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBEM0RNQVRSSVggKk1hdHJpeDsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBEM0RNYXRIYW5kbGUpOwoKICAgIGlmKCFEM0RNYXRIYW5kbGUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgTWF0cml4ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihEM0RNQVRSSVgpKTsKICAgIGlmKCFNYXRyaXgpCiAgICB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBhIEQzRE1BVFJJWFxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX09VVE9GTUVNT1JZOwogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAqRDNETWF0SGFuZGxlID0gSURpcmVjdDNERGV2aWNlSW1wbF9DcmVhdGVIYW5kbGUoVGhpcyk7CiAgICBpZighKCpEM0RNYXRIYW5kbGUpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIG1hdHJpeCBoYW5kbGVcbiIpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIE1hdHJpeCk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUaGlzLT5IYW5kbGVzWypEM0RNYXRIYW5kbGUgLSAxXS5wdHIgPSBNYXRyaXg7CiAgICBUaGlzLT5IYW5kbGVzWypEM0RNYXRIYW5kbGUgLSAxXS50eXBlID0gRERyYXdIYW5kbGVfTWF0cml4OwogICAgVFJBQ0UoIiByZXR1cm5pbmcgbWF0cml4IGhhbmRsZSAlZFxuIiwgKkQzRE1hdEhhbmRsZSk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OlNldE1hdHJpeAogKgogKiBTZXRzIGEgbWF0cml4IGZvciBhIG1hdHJpeCBoYW5kbGUuIFRoZSBtYXRyaXggaXMgY29waWVkIGludG8gdGhlIG1lbW9yeQogKiBhbGxvY2F0ZWQgZm9yIHRoZSBoYW5kbGUKICoKICogVmVyc2lvbiAxIG9ubHkKICoKICogUGFyYW1zOgogKiAgRDNETWF0SGFuZGxlOiBIYW5kbGUgdG8gc2V0IHRoZSBtYXRyaXggdG8KICogIEQzRE1hdHJpeDogTWF0cml4IHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIGhhbmRsZSBvZiB0aGUgbWF0cml4IGlzIGludmFsaWQgb3IgdGhlIG1hdHJpeAogKiAgIHRvIHNldCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9TZXRNYXRyaXgoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVhIQU5ETEUgRDNETWF0SGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEQzRE1hdEhhbmRsZSwgRDNETWF0cml4KTsKCiAgICBpZiggKCFEM0RNYXRIYW5kbGUpIHx8ICghRDNETWF0cml4KSApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKEQzRE1hdEhhbmRsZSA+IFRoaXMtPm51bUhhbmRsZXMpCiAgICB7CiAgICAgICAgRVJSKCJIYW5kbGUgJWQgb3V0IG9mIHJhbmdlXG4iLCBEM0RNYXRIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CiAgICBlbHNlIGlmKFRoaXMtPkhhbmRsZXNbRDNETWF0SGFuZGxlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9NYXRyaXgpCiAgICB7CiAgICAgICAgRVJSKCJIYW5kbGUgJWQgaXMgbm90IGEgbWF0cml4IGhhbmRsZVxuIiwgRDNETWF0SGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmIChUUkFDRV9PTihkM2Q3KSkKICAgICAgICBkdW1wX0QzRE1BVFJJWChEM0RNYXRyaXgpOwoKICAgICooKEQzRE1BVFJJWCAqKSBUaGlzLT5IYW5kbGVzW0QzRE1hdEhhbmRsZSAtIDFdLnB0cikgPSAqRDNETWF0cml4OwoKICAgIGlmKFRoaXMtPndvcmxkID09IEQzRE1hdEhhbmRsZSkKICAgIHsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1dPUkxETUFUUklYKDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRE1BVFJJWCAqKSBEM0RNYXRyaXgpOwogICAgfQogICAgaWYoVGhpcy0+dmlldyA9PSBEM0RNYXRIYW5kbGUpCiAgICB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VHJhbnNmb3JtKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19WSUVXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRE1BVFJJWCAqKSBEM0RNYXRyaXgpOwogICAgfQogICAgaWYoVGhpcy0+cHJvaiA9PSBEM0RNYXRIYW5kbGUpCiAgICB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VHJhbnNmb3JtKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19QUk9KRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRE1BVFJJWCAqKSBEM0RNYXRyaXgpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlOjpTZXRNYXRyaXgKICoKICogUmV0dXJucyB0aGUgY29udGVudCBvZiBhIEQzRE1BVFJJWCBoYW5kbGUKICoKICogVmVyc2lvbiAxIG9ubHkKICoKICogUGFyYW1zOgogKiAgRDNETWF0SGFuZGxlOiBNYXRyaXggaGFuZGxlIHRvIHJlYWQgdGhlIGNvbnRlbnQgZnJvbQogKiAgRDNETWF0cml4OiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBjb250ZW50IGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBEM0RNYXRIYW5kbGUgaXMgaW52YWxpZCBvciBEM0RNYXRyaXggaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0TWF0cml4KElEaXJlY3QzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYSEFORExFIEQzRE1hdEhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLCBEM0RNYXRIYW5kbGUsIEQzRE1hdHJpeCk7CgogICAgaWYoIUQzRE1hdHJpeCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIGlmKCFEM0RNYXRIYW5kbGUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKEQzRE1hdEhhbmRsZSA+IFRoaXMtPm51bUhhbmRsZXMpCiAgICB7CiAgICAgICAgRVJSKCJIYW5kbGUgJWQgb3V0IG9mIHJhbmdlXG4iLCBEM0RNYXRIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CiAgICBlbHNlIGlmKFRoaXMtPkhhbmRsZXNbRDNETWF0SGFuZGxlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9NYXRyaXgpCiAgICB7CiAgICAgICAgRVJSKCJIYW5kbGUgJWQgaXMgbm90IGEgbWF0cml4IGhhbmRsZVxuIiwgRDNETWF0SGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFRoZSBoYW5kbGUgaXMgc2ltcGx5IGEgcG9pbnRlciB0byBhIEQzRE1BVFJJWCBzdHJ1Y3R1cmUgKi8KICAgICpEM0RNYXRyaXggPSAqKChEM0RNQVRSSVggKikgVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS5wdHIpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlOjpEZWxldGVNYXRyaXgKICoKICogRGVzdHJveXMgYSBNYXRyaXggaGFuZGxlLiBGcmVlcyB0aGUgbWVtb3J5IGFuZCB1bnNldHMgdGhlIGhhbmRsZSBkYXRhCiAqCiAqIFZlcnNpb24gMSBvbmx5CiAqCiAqIFBhcmFtczoKICogIEQzRE1hdEhhbmRsZTogSGFuZGxlIHRvIGRlc3Ryb3kKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRE1hdEhhbmRsZSBpcyBpbnZhbGlkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfMV9EZWxldGVNYXRyaXgoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVhIQU5ETEUgRDNETWF0SGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsIFRoaXMsIEQzRE1hdEhhbmRsZSk7CgogICAgaWYoIUQzRE1hdEhhbmRsZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoRDNETWF0SGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBvdXQgb2YgcmFuZ2VcbiIsIEQzRE1hdEhhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KICAgIGVsc2UgaWYoVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX01hdHJpeCkKICAgIHsKICAgICAgICBFUlIoIkhhbmRsZSAlZCBpcyBub3QgYSBtYXRyaXggaGFuZGxlXG4iLCBEM0RNYXRIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS5wdHIpOwogICAgVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS5wdHIgPSBOVUxMOwogICAgVGhpcy0+SGFuZGxlc1tEM0RNYXRIYW5kbGUgLSAxXS50eXBlID0gRERyYXdIYW5kbGVfVW5rbm93bjsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkJlZ2luU2NlbmUKICoKICogVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIGFueSByZW5kZXJpbmcgaXMgcGVyZm9ybWVkLgogKiBJRGlyZWN0M0REZXZpY2U6OkVuZFNjZW5lIGhhcyB0byBiZSBjYWxsZWQgYWZ0ZXIgdGhlIHNjZW5lIGlzIGNvbXBsZXRlCiAqCiAqIFZlcnNpb24gMSwgMiwgMyBhbmQgNwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MsIGZvciBkZXRhaWxzIHNlZSBJV2luZUQzRERldmljZTo6QmVnaW5TY2VuZQogKiAgRDNERVJSX1NDRU5FX0lOX1NDRU5FIGlmIFdpbmVEM0QgcmV0dXJucyBhbiBlcnJvcihPbmx5IGluIGNhc2Ugb2YgYW4gYWxyZWFkeQogKiAgc3RhcnRlZCBzY2VuZSkuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19CZWdpblNjZW5lKElEaXJlY3QzRERldmljZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCk6IFJlbGF5XG4iLCBUaGlzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9CZWdpblNjZW5lKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spIHJldHVybiBEM0RfT0s7CiAgICBlbHNlIHJldHVybiBEM0RFUlJfU0NFTkVfSU5fU0NFTkU7IC8qIFRPRE86IE90aGVyIHBvc3NpYmxlIGNhdXNlcyBvZiBmYWlsdXJlICovCn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW5TY2VuZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0JlZ2luU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0JlZ2luU2NlbmUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19CZWdpblNjZW5lKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9CZWdpblNjZW5lKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0JlZ2luU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RW5kU2NlbmUKICoKICogRW5kcyBhIHNjZW5lIHRoYXQgaGFzIGJlZW4gYmVndW4gd2l0aCBJRGlyZWN0M0REZXZpY2U3OjpCZWdpblNjZW5lLgogKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBhZnRlciByZW5kZXJpbmcgaXMgZmluaXNoZWQuCiAqCiAqIFZlcnNpb24gMSwgMiwgMyBhbmQgNwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MsIGZvciBkZXRhaWxzIHNlZSBJV2luZUQzRERldmljZTo6RW5kU2NlbmUKICogIEQzREVSUl9TQ0VORV9OT1RfSU5fU0NFTkUgaXMgcmV0dXJuZWQgaWYgV2luZUQzRCByZXR1cm5zIGFuIGVycm9yLiBJdCBkb2VzCiAqICB0aGF0IG9ubHkgaWYgdGhlIHNjZW5lIHdhcyBhbHJlYWR5IGVuZGVkLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKTogUmVsYXlcbiIsIFRoaXMpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0VuZFNjZW5lKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spIHJldHVybiBEM0RfT0s7CiAgICBlbHNlIHJldHVybiBEM0RFUlJfU0NFTkVfTk9UX0lOX1NDRU5FOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0VuZFNjZW5lKElEaXJlY3QzRERldmljZTMgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0VuZFNjZW5lKElEaXJlY3QzRERldmljZTIgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRW5kU2NlbmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNykpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0VuZFNjZW5lKElEaXJlY3QzRERldmljZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0VuZFNjZW5lKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldERpcmVjdDNECiAqCiAqIFJldHVybnMgdGhlIElEaXJlY3QzRCg9IGludGVyZmFjZSB0byB0aGUgRGlyZWN0RHJhdyBvYmplY3QpIHVzZWQgdG8gY3JlYXRlCiAqIHRoaXMgZGV2aWNlLgogKgogKiBQYXJhbXM6CiAqICBEaXJlY3QzRDc6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBEaXJlY3QzRDcgPT0gTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0RGlyZWN0M0QoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0Q3ICoqRGlyZWN0M0Q3KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRGlyZWN0M0Q3KTsKCiAgICBpZighRGlyZWN0M0Q3KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgICpEaXJlY3QzRDcgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdDNENyk7CiAgICBJRGlyZWN0M0Q3X0FkZFJlZigqRGlyZWN0M0Q3KTsKCiAgICBUUkFDRSgiIHJldHVybmluZyBpbnRlcmZhY2UgJXBcbiIsICpEaXJlY3QzRDcpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXREaXJlY3QzRChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRDMgKipEaXJlY3QzRDMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIEhSRVNVTFQgcmV0OwogICAgSURpcmVjdDNENyAqcmV0X3B0cjsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgRGlyZWN0M0QzKTsKICAgIHJldCA9IElEaXJlY3QzRERldmljZTdfR2V0RGlyZWN0M0QoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXRfcHRyKTsKICAgIGlmKHJldCAhPSBEM0RfT0spCiAgICAgICAgcmV0dXJuIHJldDsKICAgICpEaXJlY3QzRDMgPSBDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0M0Q3LCBJRGlyZWN0M0QzLCByZXRfcHRyKTsKICAgIFRSQUNFKCIgcmV0dXJuaW5nIGludGVyZmFjZSAlcFxuIiwgKkRpcmVjdDNEMyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldERpcmVjdDNEKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEMiAqKkRpcmVjdDNEMikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgSFJFU1VMVCByZXQ7CiAgICBJRGlyZWN0M0Q3ICpyZXRfcHRyOwoKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBEaXJlY3QzRDIpOwogICAgcmV0ID0gSURpcmVjdDNERGV2aWNlN19HZXREaXJlY3QzRChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJldF9wdHIpOwogICAgaWYocmV0ICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gcmV0OwogICAgKkRpcmVjdDNEMiA9IENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3QzRDcsIElEaXJlY3QzRDIsIHJldF9wdHIpOwogICAgVFJBQ0UoIiByZXR1cm5pbmcgaW50ZXJmYWNlICVwXG4iLCAqRGlyZWN0M0QyKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0RGlyZWN0M0QoSURpcmVjdDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRCAqKkRpcmVjdDNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UsIGlmYWNlKTsKICAgIEhSRVNVTFQgcmV0OwogICAgSURpcmVjdDNENyAqcmV0X3B0cjsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgRGlyZWN0M0QpOwogICAgcmV0ID0gSURpcmVjdDNERGV2aWNlN19HZXREaXJlY3QzRChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJldF9wdHIpOwogICAgaWYocmV0ICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gcmV0OwogICAgKkRpcmVjdDNEID0gQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdDNENywgSURpcmVjdDNELCByZXRfcHRyKTsKICAgIFRSQUNFKCIgcmV0dXJuaW5nIGludGVyZmFjZSAlcFxuIiwgKkRpcmVjdDNEKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpTZXRDdXJyZW50Vmlld3BvcnQKICoKICogU2V0cyBhIERpcmVjdDNEVmlld3BvcnQgYXMgdGhlIGN1cnJlbnQgdmlld3BvcnQuCiAqIEZvciB0aGUgdGh1bmtzIG5vdGUgdGhhdCBhbGwgdmlld3BvcnQgaW50ZXJmYWNlIHZlcnNpb25zIGFyZSBlcXVhbAogKgogKiBQYXJhbXM6CiAqICBEaXJlY3QzRFZpZXdwb3J0MzogVGhlIHZpZXdwb3J0IHRvIHNldAogKgogKiBWZXJzaW9uIDIgYW5kIDMKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICAoSXMgYSBOVUxMIHZpZXdwb3J0IHZhbGlkPykKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldEN1cnJlbnRWaWV3cG9ydChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWaWV3cG9ydDMgKkRpcmVjdDNEVmlld3BvcnQzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBJRGlyZWN0M0RWaWV3cG9ydEltcGwgKnZwID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmlld3BvcnRJbXBsLCBJRGlyZWN0M0RWaWV3cG9ydDMsIERpcmVjdDNEVmlld3BvcnQzKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBEaXJlY3QzRFZpZXdwb3J0Myk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIERvIG5vdGhpbmcgaWYgdGhlIHNwZWNpZmllZCB2aWV3cG9ydCBpcyB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCBvbmUgKi8KICAgIGlmIChUaGlzLT5jdXJyZW50X3ZpZXdwb3J0ID09IHZwICkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RfT0s7CiAgICB9CgogICAgLyogU2hvdWxkIGNoZWNrIGlmIHRoZSB2aWV3cG9ydCB3YXMgYWRkZWQgb3Igbm90ICovCgogICAgLyogUmVsZWFzZSBwcmV2aW91cyB2aWV3cG9ydCBhbmQgQWRkUmVmIHRoZSBuZXcgb25lICovCiAgICBpZiAoVGhpcy0+Y3VycmVudF92aWV3cG9ydCkKICAgIHsKICAgICAgICBUUkFDRSgiVmlld3BvcnRJbXBsIGlzIGF0ICVwLCBpbnRlcmZhY2UgaXMgYXQgJXBcbiIsIFRoaXMtPmN1cnJlbnRfdmlld3BvcnQsIElDT01fSU5URVJGQUNFKFRoaXMtPmN1cnJlbnRfdmlld3BvcnQsIElEaXJlY3QzRFZpZXdwb3J0MykpOwogICAgICAgIElEaXJlY3QzRFZpZXdwb3J0M19SZWxlYXNlKCBJQ09NX0lOVEVSRkFDRShUaGlzLT5jdXJyZW50X3ZpZXdwb3J0LCBJRGlyZWN0M0RWaWV3cG9ydDMpICk7CiAgICB9CiAgICBJRGlyZWN0M0RWaWV3cG9ydDNfQWRkUmVmKERpcmVjdDNEVmlld3BvcnQzKTsKCiAgICAvKiBTZXQgdGhpcyB2aWV3cG9ydCBhcyB0aGUgY3VycmVudCB2aWV3cG9ydCAqLwogICAgVGhpcy0+Y3VycmVudF92aWV3cG9ydCA9IHZwOwoKICAgIC8qIEFjdGl2YXRlIHRoaXMgdmlld3BvcnQgKi8KICAgIFRoaXMtPmN1cnJlbnRfdmlld3BvcnQtPmFjdGl2ZV9kZXZpY2UgPSBUaGlzOwogICAgVGhpcy0+Y3VycmVudF92aWV3cG9ydC0+YWN0aXZhdGUoVGhpcy0+Y3VycmVudF92aWV3cG9ydCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqRGlyZWN0M0RWaWV3cG9ydDIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZpZXdwb3J0SW1wbCAqdnAgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIHZwKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX1NldEN1cnJlbnRWaWV3cG9ydChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRSh2cCwgSURpcmVjdDNEVmlld3BvcnQzKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpHZXRDdXJyZW50Vmlld3BvcnQKICoKICogUmV0dXJucyB0aGUgY3VycmVudGx5IGFjdGl2ZSB2aWV3cG9ydC4KICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIERpcmVjdDNEVmlld3BvcnQzOiBBZGRyZXNzIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERpcmVjdDNEVmlld3BvcnQgPT0gTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MyAqKkRpcmVjdDNEVmlld3BvcnQzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgRGlyZWN0M0RWaWV3cG9ydDMpOwoKICAgIGlmKCFEaXJlY3QzRFZpZXdwb3J0MykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgKkRpcmVjdDNEVmlld3BvcnQzID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+Y3VycmVudF92aWV3cG9ydCwgSURpcmVjdDNEVmlld3BvcnQzKTsKCiAgICAvKiBBZGRSZWYgdGhlIHJldHVybmVkIHZpZXdwb3J0ICovCiAgICBpZigqRGlyZWN0M0RWaWV3cG9ydDMpIElEaXJlY3QzRFZpZXdwb3J0M19BZGRSZWYoKkRpcmVjdDNEVmlld3BvcnQzKTsKCiAgICBUUkFDRSgiIHJldHVybmluZyBpbnRlcmZhY2UgJXBcbiIsICpEaXJlY3QzRFZpZXdwb3J0Myk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q3VycmVudFZpZXdwb3J0KElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZpZXdwb3J0MiAqKkRpcmVjdDNEVmlld3BvcnQyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIERpcmVjdDNEVmlld3BvcnQyKTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlM19HZXRDdXJyZW50Vmlld3BvcnQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElEaXJlY3QzRFZpZXdwb3J0MyAqKikgRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgaWYoaHIgIT0gRDNEX09LKSByZXR1cm4gaHI7CiAgICAqRGlyZWN0M0RWaWV3cG9ydDIgPSAoSURpcmVjdDNEVmlld3BvcnQyICopIENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0M0RWaWV3cG9ydEltcGwsIElEaXJlY3QzRFZpZXdwb3J0MywgSURpcmVjdDNEVmlld3BvcnQzLCAqRGlyZWN0M0RWaWV3cG9ydDIpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldFJlbmRlclRhcmdldAogKgogKiBTZXRzIHRoZSByZW5kZXIgdGFyZ2V0IGZvciB0aGUgRGlyZWN0M0REZXZpY2UuCiAqIEZvciB0aGUgdGh1bmtzIG5vdGUgdGhhdCBJRGlyZWN0RHJhd1N1cmZhY2U3ID09IElEaXJlY3REcmF3U3VyZmFjZTQgYW5kCiAqIElEaXJlY3REcmF3U3VyZmFjZTMgPT0gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBOZXdUYXJnZXQ6IFBvaW50ZXIgdG8gYW4gSURpcmVjdERyYXdTdXJmYWNlNyBpbnRlcmZhY2UgdG8gc2V0IGFzIHRoZSBuZXcKICogICAgICAgICAgICAgcmVuZGVyIHRhcmdldAogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzLCBmb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFJlbmRlclRhcmdldAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyVGFyZ2V0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKk5ld1RhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqVGFyZ2V0ID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgTmV3VGFyZ2V0KTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCUwOHgpOiBSZWxheVxuIiwgVGhpcywgTmV3VGFyZ2V0LCBGbGFncyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIEZsYWdzOiBOb3QgdXNlZCAqLwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0UmVuZGVyVGFyZ2V0KFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGFyZ2V0ID8gVGFyZ2V0LT5XaW5lRDNEU3VyZmFjZSA6IE5VTEwpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoTmV3VGFyZ2V0KTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShUaGlzLT50YXJnZXQsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgIFRoaXMtPnRhcmdldCA9IFRhcmdldDsKICAgIElEaXJlY3QzRERldmljZUltcGxfVXBkYXRlRGVwdGhTdGVuY2lsKFRoaXMpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0UmVuZGVyVGFyZ2V0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTQgKk5ld1JlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqVGFyZ2V0ID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgTmV3UmVuZGVyVGFyZ2V0KTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRhcmdldCwgRmxhZ3MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyVGFyZ2V0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKFRhcmdldCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldFJlbmRlclRhcmdldChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2UgKk5ld1JlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqVGFyZ2V0ID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlMywgTmV3UmVuZGVyVGFyZ2V0KTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRhcmdldCwgRmxhZ3MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyVGFyZ2V0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKFRhcmdldCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0UmVuZGVyVGFyZ2V0CiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgcmVuZGVyIHRhcmdldC4KICogVGhpcyBpcyBoYW5kbGVkIGxvY2FsbHksIGJlY2F1c2UgdGhlIFdpbmVEM0QgcmVuZGVyIHRhcmdldCdzIHBhcmVudAogKiBpcyBhbiBJUGFyZW50CiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBSZW5kZXJUYXJnZXQ6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIHN1cmZhY2UgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFJlbmRlclRhcmdldCA9PSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRSZW5kZXJUYXJnZXQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKlJlbmRlclRhcmdldCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBSZW5kZXJUYXJnZXQpOwoKICAgIGlmKCFSZW5kZXJUYXJnZXQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpSZW5kZXJUYXJnZXQgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT50YXJnZXQsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoKlJlbmRlclRhcmdldCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0UmVuZGVyVGFyZ2V0KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTQgKipSZW5kZXJUYXJnZXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUmVuZGVyVGFyZ2V0KTsKICAgIGhyID0gSURpcmVjdDNERGV2aWNlN19HZXRSZW5kZXJUYXJnZXQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJRGlyZWN0RHJhd1N1cmZhY2U3ICoqKSBSZW5kZXJUYXJnZXQpOwogICAgaWYoaHIgIT0gRDNEX09LKSByZXR1cm4gaHI7CiAgICAqUmVuZGVyVGFyZ2V0ID0gKElEaXJlY3REcmF3U3VyZmFjZTQgKikgQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3REcmF3U3VyZmFjZTcsICpSZW5kZXJUYXJnZXQpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRSZW5kZXJUYXJnZXQoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlICoqUmVuZGVyVGFyZ2V0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFJlbmRlclRhcmdldCk7CiAgICBociA9IElEaXJlY3QzRERldmljZTdfR2V0UmVuZGVyVGFyZ2V0KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSURpcmVjdERyYXdTdXJmYWNlNyAqKikgUmVuZGVyVGFyZ2V0KTsKICAgIGlmKGhyICE9IEQzRF9PSykgcmV0dXJuIGhyOwogICAgKlJlbmRlclRhcmdldCA9IChJRGlyZWN0RHJhd1N1cmZhY2UgKikgQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3REcmF3U3VyZmFjZTMsICpSZW5kZXJUYXJnZXQpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkJlZ2luCiAqCiAqIEJlZ2lucyBhIGRlc2NyaXB0aW9uIGJsb2NrIG9mIHZlcnRpY2VzLiBUaGlzIGlzIHNpbWlsYXIgdG8gZ2xCZWdpbigpCiAqIGFuZCBnbEVuZCgpLiBBZnRlciBhIGNhbGwgdG8gSURpcmVjdDNERGV2aWNlMzo6RW5kLCB0aGUgdmVydGljZXMKICogZGVzY3JpYmVkIHdpdGggSURpcmVjdDNERGV2aWNlOjpWZXJ0ZXggYXJlIGRyYXduLgogKgogKiBWZXJzaW9uIDIgYW5kIDMKICoKICogUGFyYW1zOgogKiAgUHJpbWl0aXZlVHlwZTogVGhlIHR5cGUgb2YgcHJpbWl0aXZlcyB0byBkcmF3CiAqICBWZXJ0ZXhUeXBlRGVzYzogQSBmbGV4aWJsZSB2ZXJ0ZXggZm9ybWF0IGRlc2NyaXB0aW9uIG9mIHRoZSB2ZXJ0aWNlcwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MuLgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX0JlZ2luKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZURlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlMDh4KVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZURlc2MsIEZsYWdzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgVGhpcy0+cHJpbWl0aXZlX3R5cGUgPSBQcmltaXRpdmVUeXBlOwogICAgVGhpcy0+dmVydGV4X3R5cGUgPSBWZXJ0ZXhUeXBlRGVzYzsKICAgIFRoaXMtPnJlbmRlcl9mbGFncyA9IEZsYWdzOwogICAgVGhpcy0+dmVydGV4X3NpemUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoVGhpcy0+dmVydGV4X3R5cGUpOwogICAgVGhpcy0+bmJfdmVydGljZXMgPSAwOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0JlZ2luKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBkM2RwdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWFRZUEUgZHdWZXJ0ZXhUeXBlRGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3RmxhZ3MpCnsKICAgIERXT1JEIEZWRjsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcC8lcCktPiglMDh4LCUwOHgsJTA4eCk6IFRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTNcbiIsIFRoaXMsIGlmYWNlLCBkM2RwdCwgZHdWZXJ0ZXhUeXBlRGVzYywgZHdGbGFncyk7CgogICAgc3dpdGNoKGR3VmVydGV4VHlwZURlc2MpCiAgICB7CiAgICAgICAgY2FzZSBEM0RWVF9WRVJURVg6IEZWRiA9IEQzREZWRl9WRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfTFZFUlRFWDogRlZGID0gRDNERlZGX0xWRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfVExWRVJURVg6IEZWRiA9IEQzREZWRl9UTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCB0eXBlICVkXG4iLCBkd1ZlcnRleFR5cGVEZXNjKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7ICAvKiBTaG91bGQgbmV2ZXIgaGFwcGVuICovCiAgICB9OwoKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0JlZ2luKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZDNkcHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVkYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkJlZ2luSW5kZXhlZAogKgogKiBEcmF3cyBwcmltaXRpdmVzIGJhc2VkIG9uIHZlcnRpY2VzIGluIGEgdmVydGV4IGFycmF5IHdoaWNoIGFyZSBzcGVjaWZpZWQKICogYnkgaW5kaWNlcy4KICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFByaW1pdGl2ZSB0eXBlIHRvIGRyYXcKICogIFZlcnRleFR5cGU6IEEgRlZGIGRlc2NyaXB0aW9uIG9mIHRoZSB2ZXJ0ZXggZm9ybWF0CiAqICBWZXJ0aWNlczogcG9pbnRlciB0byBhbiBhcnJheSBjb250YWluaW5nIHRoZSB2ZXJ0aWNlcwogKiAgTnVtVmVydGljZXM6IFRoZSBudW1iZXIgb2YgdmVydGljZXMgaW4gdGhlIHZlcnRleCBhcnJheQogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MgLi4uCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF8zX0JlZ2luSW5kZXhlZChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KTogc3R1YiFcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBOdW1WZXJ0aWNlcywgRmxhZ3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQmVnaW5JbmRleGVkKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgZDNkcHRQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWFRZUEUgZDNkdnRWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmxwdlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3TnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncykKewogICAgRFdPUkQgRlZGOwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwLyVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpOiBUaHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzXG4iLCBUaGlzLCBpZmFjZSwgZDNkcHRQcmltaXRpdmVUeXBlLCBkM2R2dFZlcnRleFR5cGUsIGxwdlZlcnRpY2VzLCBkd051bVZlcnRpY2VzLCBkd0ZsYWdzKTsKCiAgICBzd2l0Y2goZDNkdnRWZXJ0ZXhUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEVlRfVkVSVEVYOiBGVkYgPSBEM0RGVkZfVkVSVEVYOyBicmVhazsKICAgICAgICBjYXNlIEQzRFZUX0xWRVJURVg6IEZWRiA9IEQzREZWRl9MVkVSVEVYOyBicmVhazsKICAgICAgICBjYXNlIEQzRFZUX1RMVkVSVEVYOiBGVkYgPSBEM0RGVkZfVExWRVJURVg7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB2ZXJ0ZXggdHlwZSAlZFxuIiwgZDNkdnRWZXJ0ZXhUeXBlKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7ICAvKiBTaG91bGQgbmV2ZXIgaGFwcGVuICovCiAgICB9OwoKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2UzX0JlZ2luSW5kZXhlZChJQ09NX0lOVEVSRkFDRShUaGlzLElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQzZHB0UHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGVkYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHB2VmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OlZlcnRleAogKgogKiBEcmF3cyBhIHZlcnRleCBhcyBkZXNjcmliZWQgYnkgSURpcmVjdDNERGV2aWNlMzo6QmVnaW4uIEl0IHBsYWNlcyBhbGwKICogZHJhd24gdmVydGljZXMgaW4gYSB2ZXJ0ZXggYnVmZmVyLiBJZiB0aGUgYnVmZmVyIGlzIHRvbyBzbWFsbCwgaXRzCiAqIHNpemUgaXMgaW5jcmVhc2VkLgogKgogKiBWZXJzaW9uIDIgYW5kIDMKICoKICogUGFyYW1zOgogKiAgVmVydGV4OiBQb2ludGVyIHRvIHRoZSB2ZXJ0ZXgKICoKICogUmV0dXJuczoKICogIEQzRF9PSywgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBWZXJ0ZXggaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfVmVydGV4KElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRleCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFZlcnRleCk7CgogICAgaWYoIVZlcnRleCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKChUaGlzLT5uYl92ZXJ0aWNlcysxKSpUaGlzLT52ZXJ0ZXhfc2l6ZSA+IFRoaXMtPmJ1ZmZlcl9zaXplKQogICAgewogICAgICAgIEJZVEUgKm9sZF9idWZmZXI7CiAgICAgICAgVGhpcy0+YnVmZmVyX3NpemUgPSBUaGlzLT5idWZmZXJfc2l6ZSA/IFRoaXMtPmJ1ZmZlcl9zaXplICogMiA6IFRoaXMtPnZlcnRleF9zaXplICogMzsKICAgICAgICBvbGRfYnVmZmVyID0gVGhpcy0+dmVydGV4X2J1ZmZlcjsKICAgICAgICBUaGlzLT52ZXJ0ZXhfYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmJ1ZmZlcl9zaXplKTsKICAgICAgICBpZiAob2xkX2J1ZmZlcikKICAgICAgICB7CiAgICAgICAgICAgIENvcHlNZW1vcnkoVGhpcy0+dmVydGV4X2J1ZmZlciwgb2xkX2J1ZmZlciwgVGhpcy0+bmJfdmVydGljZXMgKiBUaGlzLT52ZXJ0ZXhfc2l6ZSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZF9idWZmZXIpOwogICAgICAgIH0KICAgIH0KCiAgICBDb3B5TWVtb3J5KFRoaXMtPnZlcnRleF9idWZmZXIgKyBUaGlzLT5uYl92ZXJ0aWNlcysrICogVGhpcy0+dmVydGV4X3NpemUsIFZlcnRleCwgVGhpcy0+dmVydGV4X3NpemUpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1ZlcnRleChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpscFZlcnRleFR5cGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBscFZlcnRleFR5cGUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfVmVydGV4KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwVmVydGV4VHlwZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2UzOjpJbmRleAogKgogKiBTcGVjaWZpZXMgYW4gaW5kZXggdG8gYSB2ZXJ0ZXggdG8gYmUgZHJhd24uIFRoZSB2ZXJ0ZXggYXJyYXkgaGFzIHRvCiAqIGJlIHNwZWNpZmllZCB3aXRoIEJlZ2luSW5kZXhlZCBmaXJzdC4KICoKICogUGFyYW1ldGVyczoKICogIFZlcnRleEluZGV4OiBUaGUgaW5kZXggb2YgdGhlIHZlcnRleCB0byBkcmF3CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfSW5kZXgoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEIFZlcnRleEluZGV4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCUwNHgpOiBzdHViIVxuIiwgVGhpcywgVmVydGV4SW5kZXgpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9JbmRleChJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgd1ZlcnRleEluZGV4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA0eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCB3VmVydGV4SW5kZXgpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfSW5kZXgoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3VmVydGV4SW5kZXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlMzo6RW5kCiAqCiAqIEVuZHMgYSBkcmF3IGJlZ3VuIHdpdGggSURpcmVjdDNERGV2aWNlMzo6QmVnaW4gb3IKICogSURpcmVjdDNERGV2aWNlOjpCZWdpbkluZGV4ZWQuIFRoZSB2ZXJ0aWNlcyBzcGVjaWZpZWQgd2l0aAogKiBJRGlyZWN0M0REZXZpY2U6OlZlcnRleCBvciBJRGlyZWN0M0REZXZpY2U6OkluZGV4IGFyZSBkcmF3biB1c2luZwogKiB0aGUgSURpcmVjdDNERGV2aWNlNzo6RHJhd1ByaW1pdGl2ZSBtZXRob2QuIFNvIGZhciBvbmx5CiAqIG5vbi1pbmRleGVkIG1vZGUgaXMgc3VwcG9ydGVkCiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBQYXJhbXM6CiAqICBGbGFnczogU29tZSBmbGFncywgYXMgdXN1YWwuIERvbid0IGtub3cgd2hpY2ggYXJlIGRlZmluZWQKICoKICogUmV0dXJuczoKICogIFRoZSByZXR1cm4gdmFsdWUgb2YgSURpcmVjdDNERGV2aWNlNzo6RHJhd1ByaW1pdGl2ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfRW5kKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgpXG4iLCBUaGlzLCBGbGFncyk7CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cHJpbWl0aXZlX3R5cGUsIFRoaXMtPnZlcnRleF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT52ZXJ0ZXhfYnVmZmVyLCBUaGlzLT5uYl92ZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVuZGVyX2ZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9FbmQoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTMgaW50ZXJmYWNlLlxuIiwgVGhpcywgZHdGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19FbmQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRSZW5kZXJTdGF0ZQogKgogKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHJlbmRlciBzdGF0ZS4gVGhlIHBvc3NpYmxlIHJlbmRlciBzdGF0ZXMgYXJlCiAqIGRlZmluZWQgaW4gaW5jbHVkZS9kM2R0eXBlcy5oCiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBSZW5kZXJTdGF0ZVR5cGU6IFJlbmRlciBzdGF0ZSB0byByZXR1cm4gdGhlIGN1cnJlbnQgc2V0dGluZyBvZgogKiAgVmFsdWU6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIHZhbHVlIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcywgZm9yIGRldGFpbHMgc2VlIElXaW5lRDNERGV2aWNlOjpHZXRSZW5kZXJTdGF0ZQogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBWYWx1ZSA9PSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRSZW5kZXJTdGF0ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFTkRFUlNUQVRFVFlQRSBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqVmFsdWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheVxuIiwgVGhpcywgUmVuZGVyU3RhdGVUeXBlLCBWYWx1ZSk7CgogICAgaWYoIVZhbHVlKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goUmVuZGVyU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUhBTkRMRToKICAgICAgICB7CiAgICAgICAgICAgIC8qIFRoaXMgc3RhdGUgaXMgd3JhcHBlZCB0byBTZXRUZXh0dXJlIGluIFNldFJlbmRlclN0YXRlLCBzbwogICAgICAgICAgICAgKiBpdCBoYXMgdG8gYmUgd3JhcHBlZCB0byBHZXRUZXh0dXJlIGhlcmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKnRleCA9IE5VTEw7CiAgICAgICAgICAgICpWYWx1ZSA9IDA7CgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGV4KTsKCiAgICAgICAgICAgIGlmKGhyID09IFdJTkVEM0RfT0sgJiYgdGV4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpwYXJlbnQgPSBOVUxMOwogICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFBhcmVudCh0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJnBhcmVudCk7CiAgICAgICAgICAgICAgICBpZihwYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhlIHBhcmVudCBvZiB0aGUgdGV4dHVyZSBpcyB0aGUgSURpcmVjdERyYXdTdXJmYWNlNyBpbnRlcmZhY2UKICAgICAgICAgICAgICAgICAgICAgKiBvZiB0aGUgZGRyYXcgc3VyZmFjZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnRleEltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQpOwogICAgICAgICAgICAgICAgICAgICpWYWx1ZSA9IHRleEltcGwtPkhhbmRsZTsKICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UocGFyZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSh0ZXgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RSRU5ERVJTVEFURV9URVhUVVJFTUFHOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHRleF9tYWc7CgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9NQUdGSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0ZXhfbWFnKTsKCiAgICAgICAgICAgIHN3aXRjaCAodGV4X21hZykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9QT0lOVDoKICAgICAgICAgICAgICAgICAgICAqVmFsdWUgPSBEM0RGSUxURVJfTkVBUkVTVDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfTElORUFSOgogICAgICAgICAgICAgICAgICAgICpWYWx1ZSA9IEQzREZJTFRFUl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5oYW5kbGVkIHRleHR1cmUgbWFnICVkICFcbiIsdGV4X21hZyk7CiAgICAgICAgICAgICAgICAgICAgKlZhbHVlID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1JTjoKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSB0ZXhfbWluOwoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfTUlORklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGV4X21pbik7CgogICAgICAgICAgICBzd2l0Y2ggKHRleF9taW4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfUE9JTlQ6CiAgICAgICAgICAgICAgICAgICAgKlZhbHVlID0gRDNERklMVEVSX05FQVJFU1Q7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0xJTkVBUjoKICAgICAgICAgICAgICAgICAgICAqVmFsdWUgPSBEM0RGSUxURVJfTElORUFSOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBFUlIoIlVuaGFuZGxlZCB0ZXh0dXJlIG1hZyAlZCAhXG4iLHRleF9taW4pOwogICAgICAgICAgICAgICAgICAgICpWYWx1ZSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVBRERSRVNTOgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1NVOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTVSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVBRERSRVNTVjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIEZJWE1FOiBVbmhhbmRsZWQ6IEQzRFJFTkRFUlNUQVRFX1NUSVBQTEVQQVRURVJOMDAgLSAzMSAqLwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFJlbmRlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0UmVuZGVyU3RhdGUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRU5ERVJTVEFURVRZUEUgZHdSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqbHBkd1JlbmRlclN0YXRlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBkd1JlbmRlclN0YXRlVHlwZSwgbHBkd1JlbmRlclN0YXRlKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0dldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscGR3UmVuZGVyU3RhdGUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFJlbmRlclN0YXRlKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIGR3UmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKmxwZHdSZW5kZXJTdGF0ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgZHdSZW5kZXJTdGF0ZVR5cGUsIGxwZHdSZW5kZXJTdGF0ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19HZXRSZW5kZXJTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3UmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBkd1JlbmRlclN0YXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldFJlbmRlclN0YXRlCiAqCiAqIFNldHMgYSByZW5kZXIgc3RhdGUuIFRoZSBwb3NzaWJsZSByZW5kZXIgc3RhdGVzIGFyZSBkZWZpbmVkIGluCiAqIGluY2x1ZGUvZDNkdHlwZXMuaAogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgUmVuZGVyU3RhdGVUeXBlOiBTdGF0ZSB0byBzZXQKICogIFZhbHVlOiBWYWx1ZSB0byBhc3NpZ24gdG8gdGhhdCBzdGF0ZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MsCiAqICBmb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFJlbmRlclN0YXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRSZW5kZXJTdGF0ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFJFTkRFUlNUQVRFVFlQRSBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlZCk6IFJlbGF5XG4iLCBUaGlzLCBSZW5kZXJTdGF0ZVR5cGUsIFZhbHVlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogU29tZSByZW5kZXIgc3RhdGVzIG5lZWQgc3BlY2lhbCBjYXJlICovCiAgICBzd2l0Y2goUmVuZGVyU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUhBTkRMRToKICAgICAgICB7CiAgICAgICAgICAgIGlmKFZhbHVlID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoVmFsdWUgPiBUaGlzLT5udW1IYW5kbGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBGSVhNRSgiU3BlY2lmaWVkIGhhbmRsZSAlZCBvdXQgb2YgcmFuZ2VcbiIsIFZhbHVlKTsKICAgICAgICAgICAgICAgIGhyID0gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKFRoaXMtPkhhbmRsZXNbVmFsdWUgLSAxXS50eXBlICE9IEREcmF3SGFuZGxlX1RleHR1cmUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJIYW5kbGUgJWQgaXNuJ3QgYSB0ZXh0dXJlIGhhbmRsZVxuIiwgVmFsdWUpOwogICAgICAgICAgICAgICAgaHIgPSBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmID0gKElEaXJlY3REcmF3U3VyZmFjZUltcGwgKikgVGhpcy0+SGFuZGxlc1tWYWx1ZSAtIDFdLnB0cjsKICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyZi0+d2luZUQzRFRleHR1cmUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BRzoKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSB0ZXhfbWFnID0gV0lORUQzRFRFWEZfTk9ORTsKCiAgICAgICAgICAgIHN3aXRjaCAoKEQzRFRFWFRVUkVGSUxURVIpIFZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9ORUFSRVNUOgogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTElORUFSTUlQTkVBUkVTVDoKICAgICAgICAgICAgICAgICAgICB0ZXhfbWFnID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVI6CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVJNSVBMSU5FQVI6CiAgICAgICAgICAgICAgICAgICAgdGV4X21hZyA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmhhbmRsZWQgdGV4dHVyZSBtYWcgJWQgIVxuIixWYWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFdJTkVEM0RTQU1QX01BR0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4X21hZyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RSRU5ERVJTVEFURV9URVhUVVJFTUlOOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHRleF9taW4gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgdGV4X21pcCA9IFdJTkVEM0RURVhGX05PTkU7CgogICAgICAgICAgICBzd2l0Y2ggKChEM0RURVhUVVJFRklMVEVSKSBWYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTkVBUkVTVDoKICAgICAgICAgICAgICAgICAgICB0ZXhfbWluID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVI6CiAgICAgICAgICAgICAgICAgICAgdGV4X21pbiA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNERklMVEVSX01JUE5FQVJFU1Q6CiAgICAgICAgICAgICAgICAgICAgdGV4X21pbiA9IFdJTkVEM0RURVhGX05PTkU7CiAgICAgICAgICAgICAgICAgICAgdGV4X21pcCA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTUlQTElORUFSOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICAgICAgICAgIHRleF9taXAgPSBXSU5FRDNEVEVYRl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzREZJTFRFUl9MSU5FQVJNSVBORUFSRVNUOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgICAgICAgICB0ZXhfbWlwID0gV0lORUQzRFRFWEZfTElORUFSOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RGSUxURVJfTElORUFSTUlQTElORUFSOgogICAgICAgICAgICAgICAgICAgIHRleF9taW4gPSBXSU5FRDNEVEVYRl9MSU5FQVI7CiAgICAgICAgICAgICAgICAgICAgdGV4X21pcCA9IFdJTkVEM0RURVhGX0xJTkVBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5oYW5kbGVkIHRleHR1cmUgbWluICVkICFcbiIsVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfTUlQRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9taXApOwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9NSU5GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF9taW4pOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1M6CiAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTViwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSk7CiAgICAgICAgICAgIC8qIERyb3AgdGhyb3VnaCAqLwogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRUFERFJFU1NVOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBXSU5FRDNEU0FNUF9BRERSRVNTVSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEQzRFJFTkRFUlNUQVRFX1RFWFRVUkVBRERSRVNTVjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUkVOREVSU1RBVEVfVEVYVFVSRU1BUEJMRU5EOgogICAgICAgIHsKICAgICAgICAgICAgLyogT2xkIHRleHR1cmUgY29tYmluZSBzZXR1cCBzdHlsZSwgc3VwZXJzZWRlZCBieSB0ZXh0dXJlIHN0YWdlIHN0YXRlcwogICAgICAgICAgICAgKiBpbiBEM0Q3LiBJdCBpcyBzYWZlIGZvciB1cyB0byB3cmFwIGl0IHRvIHRleHR1cmUgc3RhZ2Ugc3RhdGVzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3dpdGNoICggKEQzRFRFWFRVUkVCTEVORCkgVmFsdWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEJMRU5EX01PRFVMQVRFOgogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcxLCBXSU5FRDNEVEFfVEVYVFVSRSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9SQVJHMiwgV0lORUQzRFRBX0NVUlJFTlQpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JPUCwgV0lORUQzRFRPUF9NT0RVTEFURSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQU9QLCBXSU5FRDNEVE9QX1NFTEVDVEFSRzEpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEJMRU5EX01PRFVMQVRFQUxQSEE6CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUkFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0FMUEhBQVJHMSwgV0lORUQzRFRBX1RFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JBUkcyLCBXSU5FRDNEVEFfQ1VSUkVOVCk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzIsIFdJTkVEM0RUQV9DVVJSRU5UKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9ST1AsIFdJTkVEM0RUT1BfTU9EVUxBVEUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFPUCwgV0lORUQzRFRPUF9NT0RVTEFURSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBEM0RUQkxFTkRfREVDQUw6CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19DT0xPUkFSRzEsIFdJTkVEM0RUQV9URVhUVVJFKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0FMUEhBQVJHMSwgV0lORUQzRFRBX1RFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQ09MT1JPUCwgV0lORUQzRFRPUF9TRUxFQ1RBUkcxKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0FMUEhBT1AsIFdJTkVEM0RUT1BfU0VMRUNUQVJHMSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBEM0RUQkxFTkRfREVDQUxBTFBIQToKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9SQVJHMSwgV0lORUQzRFRBX1RFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsIDAsIFdJTkVEM0RUU1NfQUxQSEFBUkcxLCBXSU5FRDNEVEFfVEVYVFVSRSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQUFSRzIsIFdJTkVEM0RUQV9DVVJSRU5UKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLCAwLCBXSU5FRDNEVFNTX0NPTE9ST1AsIFdJTkVEM0RUT1BfU0VMRUNUQVJHMSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZVN0YWdlU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwgMCwgV0lORUQzRFRTU19BTFBIQU9QLCBXSU5FRDNEVE9QX01PRFVMQVRFKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5oYW5kbGVkIHRleHR1cmUgZW52aXJvbm1lbnQgJWQgIVxuIixWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBociA9IEQzRF9PSzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBkZWZhdWx0OgoKICAgICAgICAgICAgLyogRklYTUU6IFVuaGFuZGxlZDogRDNEUkVOREVSU1RBVEVfU1RJUFBMRVBBVFRFUk4wMCAtIDMxICovCgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFJlbmRlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFJlbmRlclN0YXRlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIFJlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFJlbmRlclN0YXRlVHlwZSwgVmFsdWUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfU2V0UmVuZGVyU3RhdGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW5kZXJTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0UmVuZGVyU3RhdGUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRU5ERVJTVEFURVRZUEUgUmVuZGVyU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmFsdWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUmVuZGVyU3RhdGVUeXBlLCBWYWx1ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRSZW5kZXJTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbmRlclN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdDNERGV2aWNlMzo6U2V0TGlnaHRTdGF0ZQogKgogKiBTZXRzIGEgbGlnaHQgc3RhdGUgZm9yIERpcmVjdDNERGV2aWNlMyBhbmQgRGlyZWN0M0REZXZpY2UyLiBUaGUKICogbGlnaHQgc3RhdGVzIGFyZSBmb3J3YXJkZWQgdG8gRGlyZWN0M0REZXZpY2U3IHJlbmRlciBzdGF0ZXMKICoKICogVmVyc2lvbiAyIGFuZCAzCiAqCiAqIFBhcmFtczoKICogIExpZ2h0U3RhdGVUeXBlOiBUaGUgbGlnaHQgc3RhdGUgdG8gY2hhbmdlCiAqICBWYWx1ZTogVGhlIHZhbHVlIHRvIGFzc2lnbiB0byB0aGF0IGxpZ2h0IHN0YXRlCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgcGFyYW1ldGVycyB3ZXJlIGluY29ycmVjdAogKiAgQWxzbyBjaGVjayBJRGlyZWN0M0REZXZpY2U3OjpTZXRSZW5kZXJTdGF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0TGlnaHRTdGF0ZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETElHSFRTVEFURVRZUEUgTGlnaHRTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4KVxuIiwgVGhpcywgTGlnaHRTdGF0ZVR5cGUsIFZhbHVlKTsKCiAgICBpZiAoIUxpZ2h0U3RhdGVUeXBlICYmIChMaWdodFN0YXRlVHlwZSA+IEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVgpKQogICAgewogICAgICAgIFRSQUNFKCJVbmV4cGVjdGVkIExpZ2h0IFN0YXRlIFR5cGVcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoTGlnaHRTdGF0ZVR5cGUgPT0gRDNETElHSFRTVEFURV9NQVRFUklBTCAvKiAxICovKQogICAgewogICAgICAgIElEaXJlY3QzRE1hdGVyaWFsSW1wbCAqbWF0OwoKICAgICAgICBpZihWYWx1ZSA9PSAwKSBtYXQgPSBOVUxMOwogICAgICAgIGVsc2UgaWYoVmFsdWUgPiBUaGlzLT5udW1IYW5kbGVzKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJNYXRlcmlhbCBoYW5kbGUgb3V0IG9mIHJhbmdlKCVkKVxuIiwgVmFsdWUpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5IYW5kbGVzW1ZhbHVlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9NYXRlcmlhbCkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSW52YWxpZCBoYW5kbGUgJWRcbiIsIFZhbHVlKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG1hdCA9IChJRGlyZWN0M0RNYXRlcmlhbEltcGwgKikgVGhpcy0+SGFuZGxlc1tWYWx1ZSAtIDFdLnB0cjsKICAgICAgICB9CgogICAgICAgIGlmIChtYXQgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIgYWN0aXZhdGluZyBtYXRlcmlhbCAlcC5cbiIsIG1hdCk7CiAgICAgICAgICAgIG1hdC0+YWN0aXZhdGUobWF0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIiBEM0RMSUdIVFNUQVRFX01BVEVSSUFMIGNhbGxlZCB3aXRoIE5VTEwgbWF0ZXJpYWwgISEhXG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+bWF0ZXJpYWwgPSBWYWx1ZTsKICAgIH0KICAgIGVsc2UgaWYgKExpZ2h0U3RhdGVUeXBlID09IEQzRExJR0hUU1RBVEVfQ09MT1JNT0RFTCAvKiAzICovKQogICAgewogICAgICAgIHN3aXRjaCAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRENPTE9SX01PTk86CiAgICAgICAgICAgICAgICBFUlIoIkREQ09MT1JfTU9OTyBzaG91bGQgbm90IGhhcHBlbiFcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRDNEQ09MT1JfUkdCOgogICAgICAgICAgICAgICAgLyogV2UgYXJlIGFscmVhZHkgaW4gdGhpcyBtb2RlICovCiAgICAgICAgICAgICAgICBUUkFDRSgiU2V0dGluZyBjb2xvciBtb2RlbCB0byBSR0IgKG5vLW9wKS5cbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBFUlIoIlVua25vd24gY29sb3IgbW9kZWwhXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIHJzOwogICAgICAgIHN3aXRjaCAoTGlnaHRTdGF0ZVR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQU1CSUVOVDogICAgICAgLyogMiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9BTUJJRU5UOwogICAgICAgICAgICAgICAgYnJlYWs7CQkKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR01PREU6ICAgICAgIC8qIDQgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HVkVSVEVYTU9ERTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HU1RBUlQ6ICAgICAgLyogNSAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dTVEFSVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HRU5EOiAgICAgICAgLyogNiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dFTkQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR0RFTlNJVFk6ICAgIC8qIDcgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HREVOU0lUWTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVg6ICAgLyogOCAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9DT0xPUlZFUlRFWDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIEQzRExJR0hUU1RBVEVUWVBFICVkLlxuIiwgTGlnaHRTdGF0ZVR5cGUpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X1NldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldExpZ2h0U3RhdGUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUU1RBVEVUWVBFIExpZ2h0U3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlMyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBMaWdodFN0YXRlVHlwZSwgVmFsdWUpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTNfU2V0TGlnaHRTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2UzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlnaHRTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTM6OkdldExpZ2h0U3RhdGUKICoKICogUmV0dXJucyB0aGUgY3VycmVudCBzZXR0aW5nIG9mIGEgbGlnaHQgc3RhdGUuIFRoZSBzdGF0ZSBpcyByZWFkIGZyb20KICogdGhlIERpcmVjdDNERGV2aWNlNyByZW5kZXIgc3RhdGUuCiAqCiAqIFZlcnNpb24gMiBhbmQgMwogKgogKiBQYXJhbXM6CiAqICBMaWdodFN0YXRlVHlwZTogVGhlIGxpZ2h0IHN0YXRlIHRvIHJldHVybgogKiAgVmFsdWU6IFRoZSBhZGRyZXNzIHRvIHN0b3JlIHRoZSBsaWdodCBzdGF0ZSBzZXR0aW5nIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIHBhcmFtZXRlcnMgd2VyZSBpbmNvcnJlY3QKICogIEFsc28gc2VlIElEaXJlY3QzRERldmljZTc6OkdldFJlbmRlclN0YXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfM19HZXRMaWdodFN0YXRlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RMSUdIVFNUQVRFVFlQRSBMaWdodFN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIExpZ2h0U3RhdGVUeXBlLCBWYWx1ZSk7CgogICAgaWYgKCFMaWdodFN0YXRlVHlwZSAmJiAoTGlnaHRTdGF0ZVR5cGUgPiBEM0RMSUdIVFNUQVRFX0NPTE9SVkVSVEVYKSkKICAgIHsKICAgICAgICBUUkFDRSgiVW5leHBlY3RlZCBMaWdodCBTdGF0ZSBUeXBlXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZighVmFsdWUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmIChMaWdodFN0YXRlVHlwZSA9PSBEM0RMSUdIVFNUQVRFX01BVEVSSUFMIC8qIDEgKi8pCiAgICB7CiAgICAgICAgKlZhbHVlID0gVGhpcy0+bWF0ZXJpYWw7CiAgICB9CiAgICBlbHNlIGlmIChMaWdodFN0YXRlVHlwZSA9PSBEM0RMSUdIVFNUQVRFX0NPTE9STU9ERUwgLyogMyAqLykKICAgIHsKICAgICAgICAqVmFsdWUgPSBEM0RDT0xPUl9SR0I7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRDNEUkVOREVSU1RBVEVUWVBFIHJzOwogICAgICAgIHN3aXRjaCAoTGlnaHRTdGF0ZVR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQU1CSUVOVDogICAgICAgLyogMiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9BTUJJRU5UOwogICAgICAgICAgICAgICAgYnJlYWs7CQkKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR01PREU6ICAgICAgIC8qIDQgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HVkVSVEVYTU9ERTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HU1RBUlQ6ICAgICAgLyogNSAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dTVEFSVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfRk9HRU5EOiAgICAgICAgLyogNiAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9GT0dFTkQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RMSUdIVFNUQVRFX0ZPR0RFTlNJVFk6ICAgIC8qIDcgKi8KICAgICAgICAgICAgICAgIHJzID0gRDNEUkVOREVSU1RBVEVfRk9HREVOU0lUWTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEQzRExJR0hUU1RBVEVfQ09MT1JWRVJURVg6ICAgLyogOCAqLwogICAgICAgICAgICAgICAgcnMgPSBEM0RSRU5ERVJTVEFURV9DT0xPUlZFUlRFWDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIEQzRExJR0hUU1RBVEVUWVBFICVkLlxuIiwgTGlnaHRTdGF0ZVR5cGUpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgaHIgPSBJRGlyZWN0M0REZXZpY2U3X0dldFJlbmRlclN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldExpZ2h0U3RhdGUoSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUU1RBVEVUWVBFIExpZ2h0U3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqVmFsdWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2UzIGludGVyZmFjZS5cbiIsIFRoaXMsIExpZ2h0U3RhdGVUeXBlLCBWYWx1ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlM19HZXRMaWdodFN0YXRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaWdodFN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0VHJhbnNmb3JtCiAqCiAqIEFzc2lnbnMgYSBEM0RNQVRSSVggdG8gYSB0cmFuc2Zvcm0gdHlwZS4gVGhlIHRyYW5zZm9ybSB0eXBlcyBhcmUgZGVmaW5lZAogKiBpbiBpbmNsdWRlL2QzZHR5cGVzLmguCiAqIFRoZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRCAoPTEpIGlzIHRyYW5zbGF0ZWQgdG8gRDNEVFNfV09STERNQVRSSVgoMCkKICogKD0yNTUpIGZvciB3aW5lZDNkLCBiZWNhdXNlIHRoZSAxIHRyYW5zZm9ybSBzdGF0ZSB3YXMgcmVtb3ZlZCBpbiBkM2Q4CiAqIGFuZCBXaW5lRDNEIGFscmVhZHkgdW5kZXJzdGFuZHMgdGhlIHJlcGxhY2VtZW50IEQzRFRTX1dPUkxETUFUUklYKDApCiAqCiAqIFZlcnNpb24gMiwgMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBUcmFuc2Zvcm1TdGF0ZVR5cGU6IHRyYW5zZm9ybSBzdGF0ZSB0byBzZXQKICogIE1hdHJpeDogTWF0cml4IHRvIGFzc2lnbiB0byB0aGUgc3RhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIE1hdHJpeCA9PSBOVUxMCiAqICBGb3IgZGV0YWlscyBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFRyYW5zZm9ybQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSB0eXBlID0gVHJhbnNmb3JtU3RhdGVUeXBlOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIE1hdHJpeCk7CgogICAgc3dpdGNoKFRyYW5zZm9ybVN0YXRlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEIDogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMCk7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQxOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgxKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDI6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDIpOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMzogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMyk7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IFRyYW5zZm9ybVN0YXRlVHlwZTsKICAgIH0KCiAgICBpZighTWF0cml4KQogICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogTm90ZTogRDNETUFUUklYIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETUFUUklYICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRE1BVFJJWCopIE1hdHJpeCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFRyYW5zZm9ybShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RUUkFOU0ZPUk1TVEFURVRZUEUgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIEQzRE1hdHJpeCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRUcmFuc2Zvcm0oSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1hdHJpeCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTIsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X1NldFRyYW5zZm9ybShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETWF0cml4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldFRyYW5zZm9ybQogKgogKiBSZXR1cm5zIHRoZSBtYXRyaXggYXNzaWduZWQgdG8gYSB0cmFuc2Zvcm0gc3RhdGUKICogRDNEVFJBTlNGT1JNU1RBVEVfV09STEQgaXMgdHJhbnNsYXRlZCB0byBEM0RUU19XT1JMRE1BVFJJWCgwKSwgc2VlCiAqIFNldFRyYW5zZm9ybQogKgogKiBQYXJhbXM6CiAqICBUcmFuc2Zvcm1TdGF0ZVR5cGU6IFN0YXRlIHRvIHJlYWQgdGhlIG1hdHJpeCBmcm9tCiAqICBNYXRyaXg6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIG1hdHJpeCBhdAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgTWF0cml4ID09IE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldFRyYW5zZm9ybQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSB0eXBlID0gVHJhbnNmb3JtU3RhdGVUeXBlOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIE1hdHJpeCk7CgogICAgc3dpdGNoKFRyYW5zZm9ybVN0YXRlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEIDogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMCk7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQxOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgxKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDI6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDIpOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMzogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMyk7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IFRyYW5zZm9ybVN0YXRlVHlwZTsKICAgIH0KCiAgICBpZighTWF0cml4KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIE5vdGU6IEQzRE1BVFJJWCBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRE1BVFJJWCAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0VHJhbnNmb3JtKFRoaXMtPndpbmVEM0REZXZpY2UsIHR5cGUsIChXSU5FRDNETUFUUklYKikgTWF0cml4KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETUFUUklYICpEM0RNYXRyaXgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0dldFRyYW5zZm9ybShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNETWF0cml4KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRUcmFuc2Zvcm0oSURpcmVjdDNERGV2aWNlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfR2V0VHJhbnNmb3JtKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNYXRyaXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6TXVsdGlwbHlUcmFuc2Zvcm0KICoKICogTXVsdGlwbGllcyB0aGUgYWxyZWFkeS1zZXQgdHJhbnNmb3JtIG1hdHJpeCBvZiBhIHRyYW5zZm9ybSBzdGF0ZQogKiB3aXRoIGFub3RoZXIgbWF0cml4LiBGb3IgdGhlIHdvcmxkIG1hdHJpeCwgc2VlIFNldFRyYW5zZm9ybQogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgVHJhbnNmb3JtU3RhdGVUeXBlOiBUcmFuc2Zvcm0gc3RhdGUgdG8gbXVsdGlwbHkKICogIEQzRE1hdHJpeCBNYXRyaXggdG8gbXVsdGlwbHkgd2l0aC4KICoKICogUmV0dXJucwogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNETWF0cml4IGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6Ok11bHRpcGx5VHJhbnNmb3JtCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19NdWx0aXBseVRyYW5zZm9ybShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSB0eXBlOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXlcbiIsIFRoaXMsIFRyYW5zZm9ybVN0YXRlVHlwZSwgRDNETWF0cml4KTsKCiAgICBzd2l0Y2goVHJhbnNmb3JtU3RhdGVUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQgOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgwKTsgYnJlYWs7CiAgICAgICAgY2FzZSBEM0RUUkFOU0ZPUk1TVEFURV9XT1JMRDE6ICB0eXBlID0gV0lORUQzRFRTX1dPUkxETUFUUklYKDEpOyBicmVhazsKICAgICAgICBjYXNlIEQzRFRSQU5TRk9STVNUQVRFX1dPUkxEMjogIHR5cGUgPSBXSU5FRDNEVFNfV09STERNQVRSSVgoMik7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFJBTlNGT1JNU1RBVEVfV09STEQzOiAgdHlwZSA9IFdJTkVEM0RUU19XT1JMRE1BVFJJWCgzKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gVHJhbnNmb3JtU3RhdGVUeXBlOwogICAgfQoKICAgIC8qIE5vdGU6IEQzRE1BVFJJWCBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRE1BVFJJWCAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfTXVsdGlwbHlUcmFuc2Zvcm0oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RNQVRSSVgqKSBEM0RNYXRyaXgpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19NdWx0aXBseVRyYW5zZm9ybShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRSQU5TRk9STVNUQVRFVFlQRSBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNQVRSSVggKkQzRE1hdHJpeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgVHJhbnNmb3JtU3RhdGVUeXBlLCBEM0RNYXRyaXgpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfTXVsdGlwbHlUcmFuc2Zvcm0oSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1TdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RNYXRyaXgpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX011bHRpcGx5VHJhbnNmb3JtKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVFJJWCAqRDNETWF0cml4KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCBUcmFuc2Zvcm1TdGF0ZVR5cGUsIEQzRE1hdHJpeCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19NdWx0aXBseVRyYW5zZm9ybShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1hdHJpeCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpEcmF3UHJpbWl0aXZlCiAqCiAqIERyYXdzIHByaW1pdGl2ZXMgYmFzZWQgb24gdmVydGljZXMgaW4gYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgcG9pbnRlcgogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcuIFRoZSBJRGlyZWN0M0REZXZpY2UyIHRodW5rIGNvbnZlcnRzIHRoZSBmaXhlZCB2ZXJ0ZXggdHlwZSBpbnRvCiAqIGFuIEZWRiBmb3JtYXQgZm9yIEQzRDcKICoKICogUGFyYW1zOgogKiAgUHJpbWl0aXZlVHlwZTogVGhlIHR5cGUgb2YgdGhlIHByaW1pdGl2ZXMgdG8gZHJhdwogKiAgVmVydGV4IHR5cGU6IEZsZXhpYmxlIHZlcnRleCBmb3JtYXQgdmVydGV4IGRlc2NyaXB0aW9uCiAqICBWZXJ0aWNlczogUG9pbnRlciB0byB0aGUgdmVydGV4IGFycmF5CiAqICBWZXJ0ZXhDb3VudDogVGhlIG51bWJlciBvZiB2ZXJ0aWNlcyB0byBkcmF3CiAqICBGbGFnczogQXMgdXN1YWwgYSBmZXcgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZlcnRpY2VzIGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkRyYXdQcmltaXRpdmVVUAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBzdHJpZGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KTogUmVsYXkhXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBWZXJ0aWNlcywgVmVydGV4Q291bnQsIEZsYWdzKTsKCiAgICBpZighVmVydGljZXMpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogR2V0IHRoZSB2ZXJ0ZXggY291bnQgKi8KICAgIHN3aXRjaChQcmltaXRpdmVUeXBlKQogICAgewogICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDogCiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLyAyOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBEM0RQVF9MSU5FU1RSSVA6CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAtIDE7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFTElTVDoKICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC8gMzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC0gMjsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVGQU46CiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAtIDI7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEdldCB0aGUgc3RyaWRlICovCiAgICBzdHJpZGUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoVmVydGV4VHlwZSk7CgogICAgLyogU2V0IHRoZSBGVkYgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9GaW5kRGVjbChUaGlzLT5kZHJhdywgVmVydGV4VHlwZSkpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIFRoaXMgbWV0aG9kIHRyYW5zbGF0ZXMgdG8gdGhlIHVzZXIgcG9pbnRlciBkcmF3IG9mIFdpbmVEM0QgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd1ByaW1pdGl2ZVVQKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3UHJpbWl0aXZlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EcmF3UHJpbWl0aXZlKElEaXJlY3QzRERldmljZTIgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWFRZUEUgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgRFdPUkQgRlZGOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgVmVydGljZXMsIFZlcnRleENvdW50LCBGbGFncyk7CgogICAgc3dpdGNoKFZlcnRleFR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RWVF9WRVJURVg6IEZWRiA9IEQzREZWRl9WRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfTFZFUlRFWDogRlZGID0gRDNERlZGX0xWRVJURVg7IGJyZWFrOwogICAgICAgIGNhc2UgRDNEVlRfVExWRVJURVg6IEZWRiA9IEQzREZWRl9UTFZFUlRFWDsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCB0eXBlICVkXG4iLCBWZXJ0ZXhUeXBlKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7ICAvKiBTaG91bGQgbmV2ZXIgaGFwcGVuICovCiAgICB9CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlZGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkRyYXdJbmRleGVkUHJpbWl0aXZlCiAqCiAqIERyYXdzIHZlcnRpY2VzIGZyb20gYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgcG9pbnRlciwgYmFzZWQgb24gdGhlIGluZGV4CiAqIG51bWJlcnMgaW4gYSBXT1JEIGFycmF5LgogKgogKiBWZXJzaW9uIDIsIDMgYW5kIDcuIFRoZSB2ZXJzaW9uIDcgdGh1bmsgdHJhbnNsYXRlcyB0aGUgdmVydGV4IHR5cGUgaW50bwogKiBhbiBGVkYgZm9ybWF0IGZvciBEM0Q3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFRoZSBwcmltaXRpdmUgdHlwZSB0byBkcmF3CiAqICBWZXJ0ZXhUeXBlOiBUaGUgRlZGIHZlcnRleCBkZXNjcmlwdGlvbgogKiAgVmVydGljZXM6IFBvaW50ZXIgdG8gdGhlIHZlcnRleCBhcnJheQogKiAgVmVydGV4Q291bnQ6ID8KICogIEluZGljZXM6IFBvaW50ZXIgdG8gdGhlIGluZGV4IGFycmF5CiAqICBJbmRleENvdW50OiBOdW1iZXIgb2YgaW5kaWNlcyA9IE51bWJlciBvZiB2ZXJ0aWNlcyB0byBkcmF3CiAqICBGbGFnczogQXMgdXN1YWwsIHNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFZlcnRpY2VzIG9yIEluZGljZXMgaXMgTlVMTAogKiAgRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6RHJhd0luZGV4ZWRQcmltaXRpdmVVUAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgKkluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFVJTlQgUHJpbWl0aXZlQ291bnQgPSAwOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJXAsJTA4eCwlMDh4KTogUmVsYXkhXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBWZXJ0aWNlcywgVmVydGV4Q291bnQsIEluZGljZXMsIEluZGV4Q291bnQsIEZsYWdzKTsKCiAgICAvKiBHZXQgdGhlIHByaW1pdGl2ZSBudW1iZXIgKi8KICAgIHN3aXRjaChQcmltaXRpdmVUeXBlKQogICAgewogICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDogCiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50OwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBEM0RQVF9MSU5FTElTVDogCiAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC8gMjsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgRDNEUFRfTElORVNUUklQOgogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDE7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFTElTVDoKICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLyAzOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRVNUUklQOgogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFRkFOOgogICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFNldCB0aGUgRDNERGV2aWNlJ3MgRlZGICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRWZXJ0ZXhEZWNsYXJhdGlvbihUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfRmluZERlY2woVGhpcy0+ZGRyYXcsIFZlcnRleFR5cGUpKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIgKCVwKSBTZXR0aW5nIHRoZSBGVkYgZmFpbGVkLCBociA9ICV4IVxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd0luZGV4ZWRQcmltaXRpdmVVUChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBNaW5WZXJ0ZXhJbmRleCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCAvKiBVSU5UIE51bVZlcnRleEluZGV4ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZNVF9JTkRFWDE2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShWZXJ0ZXhUeXBlKSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdJbmRleGVkUHJpbWl0aXZlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EcmF3SW5kZXhlZFByaW1pdGl2ZShJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZFUlRFWFRZUEUgVmVydGV4VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXT1JEICpJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBEV09SRCBGVkY7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIFZlcnRpY2VzLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwoKICAgIHN3aXRjaChWZXJ0ZXhUeXBlKQogICAgewogICAgICAgIGNhc2UgRDNEVlRfVkVSVEVYOiBGVkYgPSBEM0RGVkZfVkVSVEVYOyBicmVhazsKICAgICAgICBjYXNlIEQzRFZUX0xWRVJURVg6IEZWRiA9IEQzREZWRl9MVkVSVEVYOyBicmVhazsKICAgICAgICBjYXNlIEQzRFZUX1RMVkVSVEVYOiBGVkYgPSBEM0RGVkZfVExWRVJURVg7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB2ZXJ0ZXggdHlwZSAlZFxuIiwgVmVydGV4VHlwZSk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOyAgLyogU2hvdWxkIG5ldmVyIGhhcHBlbiAqLwogICAgfQoKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0RyYXdJbmRleGVkUHJpbWl0aXZlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZWRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldENsaXBTdGF0dXMKICoKICogU2V0cyB0aGUgY2xpcCBzdGF0dXMuIFRoaXMgZGVmaW5lcyB0aGluZ3MgYXMgY2xpcHBpbmcgY29uZGl0aW9ucyBhbmQKICogdGhlIGV4dGVudHMgb2YgdGhlIGNsaXBwaW5nIHJlZ2lvbi4KICoKICogVmVyc2lvbiAyLCAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIENsaXBTdGF0dXM6CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKiAgKERERVJSX0lOVkFMSURQQVJBTVMgaWYgQ2xpcFN0YXR1cyA9PSBOVUxMKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCk6IFN0dWIhXG4iLCBUaGlzLCBDbGlwU3RhdHVzKTsKCiAgICAvKiBEM0RDTElQU1RBVFVTIGFuZCBXSU5FRDNEQ0xJUFNUQVRVUyBhcmUgZGlmZmVyZW50LiBJIGRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgdGhlbQogICAgICogUGVyaGFwcyB0aGlzIG5lZWRzIGEgbmV3IGRhdGEgdHlwZSBhbmQgYW4gYWRkaXRpb25hbCBJV2luZUQzRERldmljZSBtZXRob2QKICAgICAqLwogICAgLyogcmV0dXJuIElXaW5lRDNERGV2aWNlX1NldENsaXBTdGF0dXMoVGhpcy0+d2luZUQzRERldmljZSwgQ2xpcFN0YXR1cyk7Ki8KICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENsaXBTdGF0dXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfU2V0Q2xpcFN0YXR1cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpcFN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENsaXBTdGF0dXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfU2V0Q2xpcFN0YXR1cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpcFN0YXR1cyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRDbGlwU3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIGNsaXAgc3RhdHVzCiAqCiAqIFBhcmFtczoKICogIENsaXBTdGF0dXM6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGNsaXAgc3RhdHVzIHRvCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCk6IFN0dWIhXG4iLCBUaGlzLCBDbGlwU3RhdHVzKTsKCiAgICAvKiBEM0RDTElQU1RBVFVTIGFuZCBXSU5FRDNEQ0xJUFNUQVRVUyBhcmUgZGlmZmVyZW50LiBJIGRvbid0IGtub3cgaG93IHRvIGNvbnZlcnQgdGhlbSAqLwogICAgLyogcmV0dXJuIElXaW5lRDNERGV2aWNlX0dldENsaXBTdGF0dXMoVGhpcy0+d2luZUQzRERldmljZSwgQ2xpcFN0YXR1cyk7Ki8KICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENsaXBTdGF0dXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfR2V0Q2xpcFN0YXR1cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpcFN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q2xpcFN0YXR1cyhJRGlyZWN0M0REZXZpY2UyICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xJUFNUQVRVUyAqQ2xpcFN0YXR1cykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMiwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENsaXBTdGF0dXMpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfR2V0Q2xpcFN0YXR1cyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpcFN0YXR1cyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U6OkRyYXdQcmltaXRpdmVTdHJpZGVkCiAqCiAqIERyYXdzIHZlcnRpY2VzIGRlc2NyaWJlZCBieSBhIEQzRERSQVdQUklNSVRJVkVTVFJJREVEREFUQSBzdHJ1Y3R1cmUuCiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBQcmltaXRpdmVUeXBlOiBUaGUgcHJpbWl0aXZlIHR5cGUgdG8gZHJhdwogKiAgVmVydGV4VHlwZTogVGhlIEZWRiBkZXNjcmlwdGlvbiBvZiB0aGUgdmVydGljZXMgdG8gZHJhdyAoZm9yIHRoZSBzdHJpZGU/PykKICogIEQzRERyYXdQcmltU3RyaWRlRGF0YTogQSBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgc3RydWN0dXJlIGRlc2NyaWJpbmcKICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHZlcnRleCBkYXRhIGxvY2F0aW9ucwogKiAgVmVydGV4Q291bnQ6IFRoZSBudW1iZXIgb2YgdmVydGljZXMgdG8gZHJhdwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKiAgKERERVJSX0lOVkFMSURQQVJBTVMgaWYgRDNERHJhd1ByaW1TdHJpZGVEYXRhIGlzIE5VTEwpCiAqICAoRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6RHJhd1ByaW1pdGl2ZVN0cmlkZWQpCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlU3RyaWRlZChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKkQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFdpbmVEaXJlY3QzRFZlcnRleFN0cmlkZWREYXRhIFdpbmVEM0RTdHJpZGVkOwogICAgaW50IGk7CiAgICBVSU5UIFByaW1pdGl2ZUNvdW50OwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgpOiBzdHViIVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgRDNERHJhd1ByaW1TdHJpZGVEYXRhLCBWZXJ0ZXhDb3VudCwgRmxhZ3MpOwoKICAgIG1lbXNldCgmV2luZUQzRFN0cmlkZWQsIDAsIHNpemVvZihXaW5lRDNEU3RyaWRlZCkpOwogICAgLyogR2V0IHRoZSBzdHJpZGVkIGRhdGEgcmlnaHQuIHRoZSB3aW5lZDNkIHN0cnVjdHVyZSBpcyBhIGJpdCBiaWdnZXIKICAgICAqIFdhdGNoIG91dDogVGhlIGNvbnRlbnRzIG9mIHRoZSBzdHJpZGVkIGRhdGEgYXJlIGRldGVybWluZWQgYnkgdGhlIGZ2ZiwKICAgICAqIG5vdCBieSB0aGUgbWVtYmVycyBzZXQgaW4gRDNERHJhd1ByaW1TdHJpZGVEYXRhLiBTbyBpdCdzIHZhbGlkCiAgICAgKiB0byBoYXZlIGRpZmZ1c2UubHB2RGF0YSBzZXQgdG8gMHhkZWFkYmVlZiBpZiB0aGUgZGlmZnVzZSBmbGFnIGlzCiAgICAgKiBub3Qgc2V0IGluIHRoZSBmdmYuCiAgICAgKi8KICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfUE9TSVRJT05fTUFTSykKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb24ubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5wb3NpdGlvbi5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbi5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+cG9zaXRpb24uZHdTdHJpZGU7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICAgICAgaWYgKFZlcnRleFR5cGUgJiBEM0RGVkZfWFlaUkhXKQogICAgICAgIHsKICAgICAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7CiAgICAgICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IFRSVUU7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IEZBTFNFOwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfTk9STUFMKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5ub3JtYWwubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5ub3JtYWwubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMubm9ybWFsLmR3U3RyaWRlID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5ub3JtYWwuZHdTdHJpZGU7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLm5vcm1hbC5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfRElGRlVTRSkKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5scERhdGEgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPmRpZmZ1c2UubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+ZGlmZnVzZS5kd1N0cmlkZTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfU0hPUlQ0OwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfU1BFQ1VMQVIpCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnNwZWN1bGFyLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+c3BlY3VsYXIubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuc3BlY3VsYXIuZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnNwZWN1bGFyLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5zcGVjdWxhci5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfU0hPUlQ0OwogICAgfQoKICAgIGZvciggaSA9IDA7IGkgPCBHRVRfVEVYQ09VTlRfRlJPTV9GVkYoVmVydGV4VHlwZSk7IGkrKykKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+dGV4dHVyZUNvb3Jkc1tpXS5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnRleHR1cmVDb29yZHNbaV0uZHdTdHJpZGU7CiAgICAgICAgc3dpdGNoKEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKFZlcnRleFR5cGUsIGkpKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAxOiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6IFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzogV2luZUQzRFN0cmlkZWQudS5zLnRleENvb3Jkc1tpXS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOyBicmVhazsKICAgICAgICAgICAgY2FzZSA0OiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiBFUlIoIlVuZXhwZWN0ZWQgdGV4dHVyZSBjb29yZGluYXRlIHNpemUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfVEVYQ09PUkRfU0laRV9GUk9NX0ZWRihWZXJ0ZXhUeXBlLCBpKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCB0aGUgcHJpbWl0aXZlIGNvdW50ICovCiAgICBzd2l0Y2goUHJpbWl0aXZlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDogCiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50OwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBWZXJ0ZXhDb3VudCAvIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9MSU5FU1RSSVA6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC0gMTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFTElTVDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLyAzOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gVmVydGV4Q291bnQgLSAyOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVGQU46CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IFZlcnRleENvdW50IC0gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OiByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBXaW5lRDNEIGRvZXNuJ3QgbmVlZCB0aGUgRlZGIGhlcmUgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0RyYXdQcmltaXRpdmVTdHJpZGVkKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmV2luZUQzRFN0cmlkZWQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3UHJpbWl0aXZlU3RyaWRlZChJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REUkFXUFJJTUlUSVZFU1RSSURFRERBVEEgKkQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZlcnRleFR5cGUsIEQzRERyYXdQcmltU3RyaWRlRGF0YSwgVmVydGV4Q291bnQsIEZsYWdzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0RyYXdQcmltaXRpdmVTdHJpZGVkKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkRyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZAogKgogKiBEcmF3cyBwcmltaXRpdmVzIHNwZWNpZmllZCBieSBzdHJpZGVkIGRhdGEgbG9jYXRpb25zIGJhc2VkIG9uIGluZGljZXMKICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICogIChEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRERyYXdQcmltU3RyaWRlRGF0YSBpcyBOVUxMKQogKiAgKERERVJSX0lOVkFMSURQQVJBTVMgaWYgSW5kaWNlcyBpcyBOVUxMKQogKiAgKEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6RHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERSQVdQUklNSVRJVkVTVFJJREVEREFUQSAqRDNERHJhd1ByaW1TdHJpZGVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdPUkQgKkluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgV2luZUQzRFN0cmlkZWQ7CiAgICBpbnQgaTsKICAgIFVJTlQgUHJpbWl0aXZlQ291bnQ7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJXAsJTA4eCwlMDh4KVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgVmVydGV4VHlwZSwgRDNERHJhd1ByaW1TdHJpZGVEYXRhLCBWZXJ0ZXhDb3VudCwgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwoKICAgIG1lbXNldCgmV2luZUQzRFN0cmlkZWQsIDAsIHNpemVvZihXaW5lRDNEU3RyaWRlZCkpOwogICAgLyogR2V0IHRoZSBzdHJpZGVkIGRhdGEgcmlnaHQuIHRoZSB3aW5lZDNkIHN0cnVjdHVyZSBpcyBhIGJpdCBiaWdnZXIKICAgICAqIFdhdGNoIG91dDogVGhlIGNvbnRlbnRzIG9mIHRoZSBzdHJpZGVkIGRhdGEgYXJlIGRldGVybWluZWQgYnkgdGhlIGZ2ZiwKICAgICAqIG5vdCBieSB0aGUgbWVtYmVycyBzZXQgaW4gRDNERHJhd1ByaW1TdHJpZGVEYXRhLiBTbyBpdCdzIHZhbGlkCiAgICAgKiB0byBoYXZlIGRpZmZ1c2UubHB2RGF0YSBzZXQgdG8gMHhkZWFkYmVlZiBpZiB0aGUgZGlmZnVzZSBmbGFnIGlzCiAgICAgKiBub3Qgc2V0IGluIHRoZSBmdmYuCiAgICAgKi8KICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfUE9TSVRJT05fTUFTSykKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMucG9zaXRpb24ubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5wb3NpdGlvbi5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbi5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+cG9zaXRpb24uZHdTdHJpZGU7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICAgICAgaWYgKFZlcnRleFR5cGUgJiBEM0RGVkZfWFlaUkhXKQogICAgICAgIHsKICAgICAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnBvc2l0aW9uLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7CiAgICAgICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IFRSVUU7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IEZBTFNFOwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfTk9STUFMKQogICAgewogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5ub3JtYWwubHBEYXRhID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5ub3JtYWwubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMubm9ybWFsLmR3U3RyaWRlID0gRDNERHJhd1ByaW1TdHJpZGVEYXRhLT5ub3JtYWwuZHdTdHJpZGU7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLm5vcm1hbC5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfRElGRlVTRSkKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5scERhdGEgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPmRpZmZ1c2UubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5kd1N0cmlkZSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+ZGlmZnVzZS5kd1N0cmlkZTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuZGlmZnVzZS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfU0hPUlQ0OwogICAgfQoKICAgIGlmKFZlcnRleFR5cGUgJiBEM0RGVkZfU1BFQ1VMQVIpCiAgICB7CiAgICAgICAgV2luZUQzRFN0cmlkZWQudS5zLnNwZWN1bGFyLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+c3BlY3VsYXIubHB2RGF0YTsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMuc3BlY3VsYXIuZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnNwZWN1bGFyLmR3U3RyaWRlOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy5zcGVjdWxhci5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfU0hPUlQ0OwogICAgfQoKICAgIGZvciggaSA9IDA7IGkgPCBHRVRfVEVYQ09VTlRfRlJPTV9GVkYoVmVydGV4VHlwZSk7IGkrKykKICAgIHsKICAgICAgICBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmxwRGF0YSA9IEQzRERyYXdQcmltU3RyaWRlRGF0YS0+dGV4dHVyZUNvb3Jkc1tpXS5scHZEYXRhOwogICAgICAgIFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdTdHJpZGUgPSBEM0REcmF3UHJpbVN0cmlkZURhdGEtPnRleHR1cmVDb29yZHNbaV0uZHdTdHJpZGU7CiAgICAgICAgc3dpdGNoKEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKFZlcnRleFR5cGUsIGkpKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAxOiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7IGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6IFdpbmVEM0RTdHJpZGVkLnUucy50ZXhDb29yZHNbaV0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzogV2luZUQzRFN0cmlkZWQudS5zLnRleENvb3Jkc1tpXS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOyBicmVhazsKICAgICAgICAgICAgY2FzZSA0OiBXaW5lRDNEU3RyaWRlZC51LnMudGV4Q29vcmRzW2ldLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiBFUlIoIlVuZXhwZWN0ZWQgdGV4dHVyZSBjb29yZGluYXRlIHNpemUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfVEVYQ09PUkRfU0laRV9GUk9NX0ZWRihWZXJ0ZXhUeXBlLCBpKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCB0aGUgcHJpbWl0aXZlIGNvdW50ICovCiAgICBzd2l0Y2goUHJpbWl0aXZlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDoKICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50OwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9MSU5FTElTVDoKICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC8gMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORVNUUklQOgogICAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLSAxOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAvIDM7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFU1RSSVA6CiAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFRkFOOgogICAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLSAyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFdpbmVEM0QgZG9lc24ndCBuZWVkIHRoZSBGVkYgaGVyZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmV2luZUQzRFN0cmlkZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk1UX0lOREVYMTYpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFZlcnRleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNERFJBV1BSSU1JVElWRVNUUklERUREQVRBICpEM0REcmF3UHJpbVN0cmlkZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVmVydGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCVwLCUwOHgsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIGlmYWNlLCBQcmltaXRpdmVUeXBlLCBWZXJ0ZXhUeXBlLCBEM0REcmF3UHJpbVN0cmlkZURhdGEsIFZlcnRleENvdW50LCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNERGV2aWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRERyYXdQcmltU3RyaWRlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Q291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6RHJhd1ByaW1pdGl2ZVZCCiAqCiAqIERyYXdzIHByaW1pdGl2ZXMgZnJvbSBhIHZlcnRleCBidWZmZXIgdG8gdGhlIHNjcmVlbi4KICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFByaW1pdGl2ZVR5cGU6IFR5cGUgb2YgcHJpbWl0aXZlIHRvIGJlIHJlbmRlcmVkLgogKiAgRDNEVmVydGV4QnVmOiBTb3VyY2UgVmVydGV4IEJ1ZmZlcgogKiAgU3RhcnRWZXJ0ZXg6IEluZGV4IG9mIHRoZSBmaXJzdCB2ZXJ0ZXggZnJvbSB0aGUgYnVmZmVyIHRvIGJlIHJlbmRlcmVkCiAqICBOdW1WZXJ0aWNlczogTnVtYmVyIG9mIHZlcnRpY2VzIHRvIGJlIHJlbmRlcmVkCiAqICBGbGFnczogQ2FuIGJlIEQzRERQX1dBSVQgdG8gd2FpdCB1bnRpbCByZW5kZXJpbmcgaGFzIGZpbmlzaGVkCiAqCiAqIFJldHVybiB2YWx1ZXMKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEQzRFZlcnRleEJ1ZiBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19EcmF3UHJpbWl0aXZlVkIoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcgKkQzRFZlcnRleEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCAqdmIgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3LCBEM0RWZXJ0ZXhCdWYpOwogICAgVUlOVCBQcmltaXRpdmVDb3VudDsKICAgIEhSRVNVTFQgaHI7CiAgICBEV09SRCBzdHJpZGU7CiAgICBXSU5FRDNEVkVSVEVYQlVGRkVSX0RFU0MgRGVzYzsKCiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXAsJTA4eCwlMDh4LCUwOHgpXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLCBEM0RWZXJ0ZXhCdWYsIFN0YXJ0VmVydGV4LCBOdW1WZXJ0aWNlcywgRmxhZ3MpOwoKICAgIC8qIFNhbml0eSBjaGVja3MgKi8KICAgIGlmKCF2YikKICAgIHsKICAgICAgICBFUlIoIiglcCkgTm8gVmVydGV4IGJ1ZmZlciBzcGVjaWZpZWRcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEdldCB0aGUgcHJpbWl0aXZlIGNvdW50ICovCiAgICBzd2l0Y2goUHJpbWl0aXZlVHlwZSkKICAgIHsKICAgICAgICBjYXNlIEQzRFBUX1BPSU5UTElTVDogCiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IE51bVZlcnRpY2VzOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBOdW1WZXJ0aWNlcyAvIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9MSU5FU1RSSVA6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IE51bVZlcnRpY2VzIC0gMTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX1RSSUFOR0xFTElTVDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gTnVtVmVydGljZXMgLyAzOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gTnVtVmVydGljZXMgLSAyOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVGQU46CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IE51bVZlcnRpY2VzIC0gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogR2V0IHRoZSBGVkYgb2YgdGhlIHZlcnRleCBidWZmZXIsIGFuZCBpdHMgc3RyaWRlICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9HZXREZXNjKHZiLT53aW5lRDNEVmVydGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RWZXJ0ZXhCdWZmZXI6OkdldERlc2MgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICBzdHJpZGUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzYy5GVkYpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0VmVydGV4RGVjbGFyYXRpb24oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPndpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbik7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiICglcCkgU2V0dGluZyB0aGUgRlZGIGZhaWxlZCwgaHIgPSAleCFcbiIsIFRoaXMsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIHZlcnRleCBzdHJlYW0gc291cmNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFN0cmVhbVNvdXJjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTdHJlYW1OdW1iZXIgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+d2luZUQzRFZlcnRleEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RhcnRWZXJ0ZXggLSB3ZSBwYXNzIHRoaXMgdG8gRHJhd1ByaW1pdGl2ZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZSk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElEaXJlY3QzRERldmljZTo6U2V0U3RyZWFtU291cmNlIGZhaWxlZCB3aXRoIGhyID0gJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIE5vdyBkcmF3IHRoZSBwcmltaXRpdmVzICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0RyYXdQcmltaXRpdmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd1ByaW1pdGl2ZVZCKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKkQzRFZlcnRleEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCAqdmIgPSBJQ09NX09CSkVDVChJRGlyZWN0M0RWZXJ0ZXhCdWZmZXJJbXBsLCBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIsIEQzRFZlcnRleEJ1Zik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlcCwlMDh4LCUwOHgsJTA4eCkgdGh1bmtpbmcgdG8gSURpcmVjdDNERGV2aWNlNyBpbnRlcmZhY2UuXG4iLCBUaGlzLCAgUHJpbWl0aXZlVHlwZSwgdmIsIFN0YXJ0VmVydGV4LCBOdW1WZXJ0aWNlcywgRmxhZ3MpOwogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd1ByaW1pdGl2ZVZCKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodmIsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpEcmF3SW5kZXhlZFByaW1pdGl2ZVZCCiAqCiAqIERyYXdzIHByaW1pdGl2ZXMgZnJvbSBhIHZlcnRleCBidWZmZXIgdG8gdGhlIHNjcmVlbgogKgogKiBQYXJhbXM6CiAqICBQcmltaXRpdmVUeXBlOiBUeXBlIG9mIHByaW1pdGl2ZSB0byBiZSByZW5kZXJlZC4KICogIEQzRFZlcnRleEJ1ZjogU291cmNlIFZlcnRleCBCdWZmZXIKICogIFN0YXJ0VmVydGV4OiBJbmRleCBvZiB0aGUgZmlyc3QgdmVydGV4IGZyb20gdGhlIGJ1ZmZlciB0byBiZSByZW5kZXJlZAogKiAgTnVtVmVydGljZXM6IE51bWJlciBvZiB2ZXJ0aWNlcyB0byBiZSByZW5kZXJlZAogKiAgSW5kaWNlczogQXJyYXkgb2YgRFdPUkRzIHVzZWQgdG8gaW5kZXggaW50byB0aGUgVmVydGljZXMKICogIEluZGV4Q291bnQ6IE51bWJlciBvZiBpbmRpY2VzIGluIEluZGljZXMKICogIEZsYWdzOiBDYW4gYmUgRDNERFBfV0FJVCB0byB3YWl0IHVudGlsIHJlbmRlcmluZyBoYXMgZmluaXNoZWQKICoKICogUmV0dXJuIHZhbHVlcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQihJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3ICpEM0RWZXJ0ZXhCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwgKnZiID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyNywgRDNEVmVydGV4QnVmKTsKICAgIERXT1JEIHN0cmlkZTsKICAgIFVJTlQgUHJpbWl0aXZlQ291bnQ7CiAgICBXT1JEICpMb2NrZWRJbmRpY2VzOwogICAgSFJFU1VMVCBocjsKICAgIFdJTkVEM0RWRVJURVhCVUZGRVJfREVTQyBEZXNjOwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlZCwlZCwlcCwlZCwlMDh4KVxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwgdmIsIFN0YXJ0VmVydGV4LCBOdW1WZXJ0aWNlcywgSW5kaWNlcywgSW5kZXhDb3VudCwgRmxhZ3MpOwoKICAgIC8qIFN0ZXBzOgogICAgICogMSkgQ2FsY3VsYXRlIHNvbWUgdGhpbmdzOiBWZXJ0ZXggY291bnQgLT4gUHJpbWl0aXZlIGNvdW50LCBzdHJpZGUsIC4uLgogICAgICogMikgVXBsb2FkIHRoZSBJbmRpY2VzIHRvIHRoZSBpbmRleCBidWZmZXIKICAgICAqIDMpIFNldCB0aGUgaW5kZXggc291cmNlCiAgICAgKiA0KSBTZXQgdGhlIFZlcnRleCBCdWZmZXIgYXMgdGhlIFN0cmVhbSBzb3VyY2UKICAgICAqIDUpIENhbGwgSVdpbmVEM0REZXZpY2U6OkRyYXdJbmRleGVkUHJpbWl0aXZlCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHByaW1pdGl2ZSBjb3VudCAqLwogICAgc3dpdGNoKFByaW1pdGl2ZVR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBEM0RQVF9QT0lOVExJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50OwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfTElORUxJU1Q6IAogICAgICAgICAgUHJpbWl0aXZlQ291bnQgPSBJbmRleENvdW50IC8gMjsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFBUX0xJTkVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDE7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgICBQcmltaXRpdmVDb3VudCA9IEluZGV4Q291bnQgLyAzOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBEM0RQVF9UUklBTkdMRUZBTjoKICAgICAgICAgIFByaW1pdGl2ZUNvdW50ID0gSW5kZXhDb3VudCAtIDI7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDogcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIEdldCB0aGUgRlZGIG9mIHRoZSB2ZXJ0ZXggYnVmZmVyLCBhbmQgaXRzIHN0cmlkZSAqLwogICAgaHIgPSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9HZXREZXNjKHZiLT53aW5lRDNEVmVydGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RWZXJ0ZXhCdWZmZXI6OkdldERlc2MgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICBzdHJpZGUgPSBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzYy5GVkYpOwogICAgVFJBQ0UoIlZlcnRleCBidWZmZXIgRlZGID0gJTA4eCwgc3RyaWRlPSVkXG4iLCBEZXNjLkZWRiwgc3RyaWRlKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFZlcnRleERlY2xhcmF0aW9uKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT53aW5lRDNEVmVydGV4RGVjbGFyYXRpb24pOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIFNldHRpbmcgdGhlIEZWRiBmYWlsZWQsIGhyID0gJXghXG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogY29weSB0aGUgaW5kZXggc3RyZWFtIGludG8gdGhlIGluZGV4IGJ1ZmZlci4KICAgICAqIEEgbmV3IElXaW5lRDNERGV2aWNlIG1ldGhvZCBjb3VsZCBiZSBjcmVhdGVkCiAgICAgKiB3aGljaCB0YWtlcyBhbiB1c2VyIHBvaW50ZXIgY29udGFpbmluZyB0aGUgaW5kaWNlcwogICAgICogb3IgYSBTZXREYXRhLU1ldGhvZCBmb3IgdGhlIGluZGV4IGJ1ZmZlciwgd2hpY2gKICAgICAqIG92ZXJyaWRlcyB0aGUgaW5kZXggYnVmZmVyIGRhdGEgd2l0aCBvdXIgcG9pbnRlci4KICAgICAqLwogICAgaHIgPSBJV2luZUQzREluZGV4QnVmZmVyX0xvY2soVGhpcy0+aW5kZXhidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIE9mZlNldFRvTG9jayAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Q291bnQgKiBzaXplb2YoV09SRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSAqKikgJkxvY2tlZEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEZsYWdzICovKTsKICAgIGFzc2VydChJbmRleENvdW50IDwgMHgxMDAwMDApOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiKCVwKSBJV2luZUQzREluZGV4QnVmZmVyOjpMb2NrIGZhaWxlZCB3aXRoIGhyID0gJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgbWVtY3B5KExvY2tlZEluZGljZXMsIEluZGljZXMsIEluZGV4Q291bnQgKiBzaXplb2YoV09SRCkpOwogICAgaHIgPSBJV2luZUQzREluZGV4QnVmZmVyX1VubG9jayhUaGlzLT5pbmRleGJ1ZmZlcik7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNESW5kZXhCdWZmZXI6OlVubG9jayBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIGluZGV4IHN0cmVhbSAqLwogICAgSVdpbmVEM0REZXZpY2VfU2V0QmFzZVZlcnRleEluZGV4KFRoaXMtPndpbmVEM0REZXZpY2UsIFN0YXJ0VmVydGV4KTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0SW5kaWNlcyhUaGlzLT53aW5lRDNERGV2aWNlLCBUaGlzLT5pbmRleGJ1ZmZlcik7CgogICAgLyogU2V0IHRoZSB2ZXJ0ZXggc3RyZWFtIHNvdXJjZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTdHJlYW1Tb3VyY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RyZWFtTnVtYmVyICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPndpbmVEM0RWZXJ0ZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIG9mZnNldCwgd2UgcGFzcyB0aGlzIHRvIERyYXdJbmRleGVkUHJpbWl0aXZlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaWRlKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIiglcCkgSURpcmVjdDNERGV2aWNlOjpTZXRTdHJlYW1Tb3VyY2UgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfRHJhd0luZGV4ZWRQcmltaXRpdmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBtaW5JbmRleCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RhcnRJbmRleCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlQ291bnQpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd0luZGV4ZWRQcmltaXRpdmVWQihJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXIgKkQzRFZlcnRleEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV09SRCAqSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXhDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3QzRFZlcnRleEJ1ZmZlckltcGwgKlZCID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNEVmVydGV4QnVmZmVySW1wbCwgSURpcmVjdDNEVmVydGV4QnVmZmVyLCBEM0RWZXJ0ZXhCdWYpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCUwOHgsJXAsJXAsJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsIFZCLCBJbmRpY2VzLCBJbmRleENvdW50LCBGbGFncyk7CgogICAgcmV0dXJuIElEaXJlY3QzRERldmljZTdfRHJhd0luZGV4ZWRQcmltaXRpdmVWQihJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UoVkIsIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpDb21wdXRlU3BoZXJlVmlzaWJpbGl0eQogKgogKiBDYWxjdWxhdGVzIHRoZSB2aXNpYmlsaXR5IG9mIHNwaGVyZXMgaW4gdGhlIGN1cnJlbnQgdmlld3BvcnQuIFRoZSBzcGhlcmVzCiAqIGFyZSBwYXNzZWQgaW4gdGhlIENlbnRlcnMgYW5kIFJhZGlpIGFycmF5cywgdGhlIHJlc3VsdHMgYXJlIHBhc3NlZCBiYWNrCiAqIGluIHRoZSBSZXR1cm5WYWx1ZXMgYXJyYXkuIFJldHVybiB2YWx1ZXMgYXJlIGVpdGhlciBjb21wbGV0ZWx5IHZpc2libGUsCiAqIHBhcnRpYWxseSB2aXNpYmxlIG9yIGNvbXBsZXRlbHkgaW52aXNpYmxlLgogKiBUaGUgcmV0dXJuIHZhbHVlIGNvbnNpc3Qgb2YgYSBjb21iaW5hdGlvbiBvZiBEM0RDTElQXyogZmxhZ3MsIG9yIGl0J3MKICogMCBpZiB0aGUgc3BoZXJlIGlzIGNvbXBsZXRlbHkgdmlzaWJsZShhY2NvcmRpbmcgdG8gdGhlIFNESywgbm90IGNoZWNrZWQpCiAqCiAqIFNvdW5kcyBsaWtlIGFuIG92ZXJkb3NlIG9mIG1hdGggOykKICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIENlbnRlcnM6IEFycmF5IGNvbnRhaW5pbmcgdGhlIHNwaGVyZSBjZW50ZXJzCiAqICBSYWRpaTogQXJyYXkgY29udGFpbmluZyB0aGUgc3BoZXJlIHJhZGlpCiAqICBOdW1TcGhlcmVzOiBUaGUgbnVtYmVyIG9mIGNlbnRlcnMgYW5kIHJhZGlpIGluIHRoZSBhcnJheXMKICogIEZsYWdzOiBTb21lIGZsYWdzCiAqICBSZXR1cm5WYWx1ZXM6IEFycmF5IHRvIHdyaXRlIHRoZSByZXN1bHRzIHRvCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKiAgKERERVJSX0lOVkFMSURQQVJBTVMgaWYgQ2VudGVycywgUmFkaWkgb3IgUmV0dXJuVmFsdWVzIGFyZSBOVUxMKQogKiAgKEQzREVSUl9JTlZBTElETUFUUklYIGlmIHRoZSBjb21iaW5lZCB3b3JsZCwgdmlldyBhbmQgcHJvaiBtYXRyaXgKICogIGlzIHNpbmd1bGFyKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ29tcHV0ZVNwaGVyZVZpc2liaWxpdHkoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWRUNUT1IgKkNlbnRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSAqUmFkaWksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1TcGhlcmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqUmV0dXJuVmFsdWVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwLCUwOHgsJTA4eCwlcCk6IHN0dWIhXG4iLCBUaGlzLCBDZW50ZXJzLCBSYWRpaSwgTnVtU3BoZXJlcywgRmxhZ3MsIFJldHVyblZhbHVlcyk7CgogICAgLyogdGhlIERpcmVjdFggNyBzZGsgc2F5cyB0aGF0IHRoZSB2aXNpYmlsaXR5IGlzIGNvbXB1dGVkIGJ5CiAgICAgKiBiYWNrLXRyYW5zZm9ybWluZyB0aGUgdmlld2luZyBmcnVzdHVtIHRvIG1vZGVsIHNwYWNlCiAgICAgKiB1c2luZyB0aGUgaW52ZXJzZSBvZiB0aGUgY29tYmluZWQgd29ybGQsIHZpZXcgYW5kIHByb2plY3Rpb24KICAgICAqIG1hdHJpeC4gSWYgdGhlIG1hdHJpeCBjYW4ndCBiZSByZXZlcnNlZCwgRDNERVJSX0lOVkFMSURNQVRSSVgKICAgICAqIGlzIHJldHVybmVkLgogICAgICoKICAgICAqIEJhc2ljIGltcGxlbWVudGF0aW9uIGlkZWE6CiAgICAgKiAxKSBDaGVjayBpZiB0aGUgY2VudGVyIGlzIGluIHRoZSB2aWV3aW5nIGZydXN0dW0KICAgICAqIDIpIEN1dCB0aGUgc3BoZXJlIHdpdGggdGhlIHBsYW5lcyBvZiB0aGUgdmlld2luZwogICAgICogICAgZnJ1c3R1bQogICAgICoKICAgICAqIC0+Q2VudGVyIGluc2lkZSB0aGUgZnJ1c3R1bSwgbm8gaW50ZXJzZWN0aW9uczoKICAgICAqICAgIEZ1bGx5IHZpc2libGUKICAgICAqIC0+Q2VudGVyIG91dHNpZGUgdGhlIGZydXN0dW0sIG5vIGludGVyc2VjdGlvbnM6CiAgICAgKiAgICBOb3QgdmlzaWJsZQogICAgICogLT5Tb21lIGludGVyc2VjdGlvbnM6IFBhcnRpYWxseSB2aXNpYmxlCiAgICAgKgogICAgICogSW1wbGVtZW50IHRoaXMgY2FsbCBpbiBXaW5lRDNELiBFaXRoZXIgaW1wbGVtZW50IHRoZQogICAgICogbWF0cml4IGFuZCB2ZWN0b3Igc3R1ZmYgaW4gV2luZUQzRCwgb3IgdXNlIHNvbWUgZXh0ZXJuYWwKICAgICAqIG1hdGggbGlicmFyeS4KICAgICAqLwoKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfQ29tcHV0ZVNwaGVyZVZpc2liaWxpdHkoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWRUNUT1IgKkNlbnRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSAqUmFkaWksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1TcGhlcmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqUmV0dXJuVmFsdWVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXAsJXAsJTA4eCwlMDh4LCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIENlbnRlcnMsIFJhZGlpLCBOdW1TcGhlcmVzLCBGbGFncywgUmV0dXJuVmFsdWVzKTsKICAgIHJldHVybiBJRGlyZWN0M0REZXZpY2U3X0NvbXB1dGVTcGhlcmVWaXNpYmlsaXR5KElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VudGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhZGlpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtU3BoZXJlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV0dXJuVmFsdWVzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldFRleHR1cmUKICoKICogUmV0dXJucyB0aGUgdGV4dHVyZSBpbnRlcmZhY2UgaGFuZGxlIGFzc2lnbmVkIHRvIGEgdGV4dHVyZSBzdGFnZS4KICogVGhlIHJldHVybmVkIHRleHR1cmUgaXMgQWRkUmVmZWQuIFRoaXMgaXMgdGFrZW4gZnJvbSBvbGQgZGRyYXcsCiAqIG5vdCBjaGVja2VkIGluIFdpbmRvd3MuCiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBTdGFnZTogVGV4dHVyZSBzdGFnZSB0byByZWFkIHRoZSB0ZXh0dXJlIGZyb20KICogIFRleHR1cmU6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBUZXh0dXJlIGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldFRleHR1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqVGV4dHVyZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqU3VyZjsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVkLCVwKTogUmVsYXlcbiIsIFRoaXMsIFN0YWdlLCBUZXh0dXJlKTsKCiAgICBpZighVGV4dHVyZSkKICAgIHsKICAgICAgICBUUkFDRSgiVGV4dHVyZSA9PSBOVUxMLCBmYWlsaW5nIHdpdGggRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0VGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLCBTdGFnZSwgJlN1cmYpOwogICAgaWYoIChociAhPSBEM0RfT0spIHx8ICghU3VyZikgKSAKICAgIHsKICAgICAgICAqVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogR2V0UGFyZW50IEFkZFJlZigpcywgd2hpY2ggaXMgcGVyZmVjdGx5IE9LLgogICAgICogV2UgaGF2ZSBwYXNzZWQgdGhlIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlIHRvIFdpbmVEM0QsIHNvIHRoYXQncyBPSyB0b28uCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRQYXJlbnQoU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICoqKSBUZXh0dXJlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0VGV4dHVyZShJRGlyZWN0M0REZXZpY2UzICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRFRleHR1cmUyICoqVGV4dHVyZTIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIEhSRVNVTFQgcmV0OwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqcmV0X3ZhbDsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJWQsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhZ2UsIFRleHR1cmUyKTsKICAgIHJldCA9IElEaXJlY3QzRERldmljZTdfR2V0VGV4dHVyZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV0X3ZhbCk7CgogICAgKlRleHR1cmUyID0gQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3QzRFRleHR1cmUyLCByZXRfdmFsKTsKCiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIgcmV0dXJuaW5nIGludGVyZmFjZSAlcC5cbiIsICpUZXh0dXJlMik7CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldFRleHR1cmUKICoKICogQXNzaWducyBhIHRleHR1cmUgdG8gYSB0ZXh0dXJlIHN0YWdlLiBJcyB0aGUgdGV4dHVyZSBBZGRSZWYtZWQ/CiAqCiAqIFZlcnNpb24gMyBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBTdGFnZTogVGhlIHN0YWdlIHRvIGFzc2lnbiB0aGUgdGV4dHVyZSB0bwogKiAgVGV4dHVyZTogSW50ZXJmYWNlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgc3VyZmFjZQogKgogKiBSZXR1cm5zCiAqIEQzRF9PSyBvbiBzdWNjZXNzCiAqIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OlNldFRleHR1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpUZXh0dXJlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgVGV4dHVyZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXkhXG4iLCBUaGlzLCBTdGFnZSwgc3VyZik7CgogICAgLyogVGV4dHVyZSBtYXkgYmUgTlVMTCBoZXJlICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyZiA/IHN1cmYtPndpbmVEM0RUZXh0dXJlIDogTlVMTCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFRleHR1cmUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RUZXh0dXJlMiAqVGV4dHVyZTIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnRleCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBUZXh0dXJlMik7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJWQsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhZ2UsIHRleCk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRERldmljZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNPTV9JTlRFUkZBQ0UodGV4LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRUZXh0dXJlU3RhZ2VTdGF0ZQogKgogKiBSZXRyaWV2ZXMgYSBzdGF0ZSBmcm9tIGEgdGV4dHVyZSBzdGFnZS4KICoKICogVmVyc2lvbiAzIGFuZCA3CiAqCiAqIFBhcmFtczoKICogIFN0YWdlOiBUaGUgc3RhZ2UgdG8gcmV0cmlldmUgdGhlIHN0YXRlIGZyb20KICogIFRleFN0YWdlU3RhdGVUeXBlOiBUaGUgc3RhdGUgdHlwZSB0byByZXRyaWV2ZQogKiAgU3RhdGU6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIHN0YXRlJ3MgdmFsdWUgYXQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFN0YXRlIGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldFRleHR1cmVTdGFnZVN0YXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlN0YXRlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwoKICAgIGlmKCFTdGF0ZSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKFRleFN0YWdlU3RhdGVUeXBlKQogICAgewogICAgICAgIC8qIE1pcGZpbHRlciBpcyBhIHNhbXBsZXIgc3RhdGUgd2l0aCBkaWZmZXJlbnQgdmFsdWVzICovCiAgICAgICAgY2FzZSBEM0RUU1NfTUlQRklMVEVSOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHZhbHVlOwoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX01JUEZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZhbHVlKTsKICAgICAgICAgICAgc3dpdGNoKHZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX05PTkU6ICpTdGF0ZSA9IEQzRFRGUF9OT05FOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfUE9JTlQ6ICpTdGF0ZSA9IEQzRFRGUF9QT0lOVDsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0xJTkVBUjogKlN0YXRlID0gRDNEVEZQX0xJTkVBUjsgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBtaXBmaWx0ZXIgdmFsdWUgJWRcbiIsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAqU3RhdGUgPSBEM0RURlBfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8qIE1pbmZpbHRlciBpcyBhIHNhbXBsZXIgc3RhdGUgdG9vLCBlcXVhbCB2YWx1ZXMgKi8KICAgICAgICBjYXNlIEQzRFRTU19NSU5GSUxURVI6CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEU0FNUF9NSU5GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIC8qIE1hZ2ZpbHRlciBoYXMgc2xpZ2h0bHkgZGlmZmVyZW50IHZhbHVlcyAqLwogICAgICAgIGNhc2UgRDNEVFNTX01BR0ZJTFRFUjoKICAgICAgICB7CiAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSB3aW5lZDNkZmlsdGVyOwogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUFHRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZWQzZGZpbHRlcik7CiAgICAgICAgICAgIHN3aXRjaCh3aW5lZDNkZmlsdGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX1BPSU5UOiAgICAgICAgICAgICAqU3RhdGUgPSBEM0RURkdfUE9JTlQ7ICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9MSU5FQVI6ICAgICAgICAgICAgKlN0YXRlID0gRDNEVEZHX0xJTkVBUjsgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRFWEZfQU5JU09UUk9QSUM6ICAgICAgICpTdGF0ZSA9IEQzRFRGR19BTklTT1RST1BJQzsgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0ZMQVRDVUJJQzogICAgICAgICAqU3RhdGUgPSBEM0RURkdfRkxBVENVQklDOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9HQVVTU0lBTkNVQklDOiAgICAgKlN0YXRlID0gRDNEVEZHX0dBVVNTSUFOQ1VCSUM7ICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHdpbmVkM2QgbWFnIGZpbHRlciB2YWx1ZSAlZFxuIiwgd2luZWQzZGZpbHRlcik7CiAgICAgICAgICAgICAgICAgICAgKlN0YXRlID0gRDNEVEZHX1BPSU5UOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBEM0RUU1NfQUREUkVTUzoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVToKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDNEVFNTX0FERFJFU1NWOgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRUZXh0dXJlU3RhZ2VTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRleFN0YWdlU3RhdGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFRleHR1cmVTdGFnZVN0YXRlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqU3RhdGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTMsIGlmYWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglMDh4LCUwOHgsJXApIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhZ2UsIFRleFN0YWdlU3RhdGVUeXBlLCBTdGF0ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpTZXRUZXh0dXJlU3RhZ2VTdGF0ZQogKgogKiBTZXRzIGEgdGV4dHVyZSBzdGFnZSBzdGF0ZS4gU29tZSBzdGFnZSB0eXBlcyBuZWVkIHRvIGJlIGhhbmRsZWQgc3BlY2lhbGx5LAogKiBiZWNhdXNlIHRoZXkgZG8gbm90IGV4aXN0IGluIFdpbmVEM0QgYW5kIHdlcmUgbW92ZWQgdG8gYW5vdGhlciBwbGFjZQogKgogKiBWZXJzaW9uIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgU3RhZ2U6IFRoZSBzdGFnZSB0byBtb2RpZnkKICogIFRleFN0YWdlU3RhdGVUeXBlOiBUaGUgc3RhdGUgdG8gY2hhbmdlCiAqICBTdGF0ZTogVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHN0YXRlCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6U2V0VGV4dHVyZVN0YWdlU3RhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFRleHR1cmVTdGFnZVN0YXRlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGF0ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4LCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIFN0YWdlLCBUZXhTdGFnZVN0YXRlVHlwZSwgU3RhdGUpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goVGV4U3RhZ2VTdGF0ZVR5cGUpCiAgICB7CiAgICAgICAgLyogTWlwZmlsdGVyIGlzIGEgc2FtcGxlciBzdGF0ZSB3aXRoIGRpZmZlcmVudCB2YWx1ZXMgKi8KICAgICAgICBjYXNlIEQzRFRTU19NSVBGSUxURVI6CiAgICAgICAgewogICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgdmFsdWU7CiAgICAgICAgICAgIHN3aXRjaChTdGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBEM0RURlBfTk9ORTogdmFsdWUgPSBXSU5FRDNEVEVYRl9OT05FOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZQX1BPSU5UOiB2YWx1ZSA9IFdJTkVEM0RURVhGX1BPSU5UOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMDogLyogVW5jaGVja2VkICovCiAgICAgICAgICAgICAgICBjYXNlIEQzRFRGUF9MSU5FQVI6IHZhbHVlID0gV0lORUQzRFRFWEZfTElORUFSOyBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmV4cGVjdGVkIG1pcGZpbHRlciB2YWx1ZSAlZFxuIiwgU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gV0lORUQzRFRFWEZfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUlQRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyogTWluZmlsdGVyIGlzIGEgc2FtcGxlciBzdGF0ZSB0b28sIGVxdWFsIHZhbHVlcyAqLwogICAgICAgIGNhc2UgRDNEVFNTX01JTkZJTFRFUjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX01JTkZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLyogTWFnZmlsdGVyIGhhcyBzbGlnaHRseSBkaWZmZXJlbnQgdmFsdWVzICovCiAgICAgICAgY2FzZSBEM0RUU1NfTUFHRklMVEVSOgogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIHdpbmVkM2RmaWx0ZXI7CiAgICAgICAgICAgIHN3aXRjaCgoRDNEVEVYVFVSRU1BR0ZJTFRFUikgU3RhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZHX1BPSU5UOiAgICAgICAgICB3aW5lZDNkZmlsdGVyID0gV0lORUQzRFRFWEZfUE9JTlQ7ICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RURkdfTElORUFSOiAgICAgICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9MSU5FQVI7ICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEQzRFRGR19GTEFUQ1VCSUM6ICAgICAgd2luZWQzZGZpbHRlciA9IFdJTkVEM0RURVhGX0ZMQVRDVUJJQzsgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRDNEVEZHX0dBVVNTSUFOQ1VCSUM6ICB3aW5lZDNkZmlsdGVyID0gV0lORUQzRFRFWEZfR0FVU1NJQU5DVUJJQzsgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBEM0RURkdfQU5JU09UUk9QSUM6ICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9BTklTT1RST1BJQzsgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBkM2Q3IG1hZyBmaWx0ZXIgdHlwZSAlZFxuIiwgU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHdpbmVkM2RmaWx0ZXIgPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgfQogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFNhbXBsZXJTdGF0ZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfTUFHRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5lZDNkZmlsdGVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTOgogICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0U2FtcGxlclN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNBTVBfQUREUkVTU1YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICAvKiBEcm9wIHRocm91Z2ggKi8KICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVToKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEQzRFRTU19BRERSRVNTVjoKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRTYW1wbGVyU3RhdGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQU1QX0FERFJFU1NWLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1NldFRleHR1cmVTdGFnZVN0YXRlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0VGV4dHVyZVN0YWdlU3RhdGUoSURpcmVjdDNERGV2aWNlMyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFRFWFRVUkVTVEFHRVNUQVRFVFlQRSBUZXhTdGFnZVN0YXRlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFN0YXRlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UzLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJTA4eCwlMDh4LCUwOHgpIHRodW5raW5nIHRvIElEaXJlY3QzRERldmljZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgU3RhZ2UsIFRleFN0YWdlU3RhdGVUeXBlLCBTdGF0ZSk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGV4U3RhZ2VTdGF0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpWYWxpZGF0ZURldmljZQogKgogKiBTREs6ICJSZXBvcnRzIHRoZSBkZXZpY2UncyBhYmlsaXR5IHRvIHJlbmRlciB0aGUgY3VycmVudGx5IHNldAogKiB0ZXh0dXJlLWJsZW5kaW5nIG9wZXJhdGlvbnMgaW4gYSBzaW5nbGUgcGFzcyIuIFdoYXRldmVyIHRoYXQgbWVhbnMKICogZXhhY3RseS4uLgogKgogKiBWZXJzaW9uIDMgYW5kIDcKICoKICogUGFyYW1zOgogKiAgTnVtUGFzc2VzOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBudW1iZXIgb2YgbmVjZXNzYXJ5IHBhc3NlcyBmb3IgdGhlCiAqICAgICAgICAgICAgIGRlc2lyZWQgZWZmZWN0IHRvLgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIFNlZSBJV2luZUQzRERldmljZTo6VmFsaWRhdGVEZXZpY2UgZm9yIG1vcmUgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfVmFsaWRhdGVEZXZpY2UoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqTnVtUGFzc2VzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBOdW1QYXNzZXMpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1ZhbGlkYXRlRGV2aWNlKFRoaXMtPndpbmVEM0REZXZpY2UsIE51bVBhc3Nlcyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1ZhbGlkYXRlRGV2aWNlKElEaXJlY3QzRERldmljZTMgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlBhc3NlcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlMywgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0REZXZpY2U3IGludGVyZmFjZS5cbiIsIFRoaXMsIFBhc3Nlcyk7CiAgICByZXR1cm4gSURpcmVjdDNERGV2aWNlN19WYWxpZGF0ZURldmljZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0REZXZpY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3Nlcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpDbGVhcgogKgogKiBGaWxscyB0aGUgcmVuZGVyIHRhcmdldCwgdGhlIHogYnVmZmVyIGFuZCB0aGUgc3RlbmNpbCBidWZmZXIgd2l0aCBhCiAqIGNsZWFyIGNvbG9yIC8gdmFsdWUKICoKICogVmVyc2lvbiA3IG9ubHkKICoKICogUGFyYW1zOgogKiAgQ291bnQ6IE51bWJlciBvZiByZWN0YW5nbGVzIGluIFJlY3RzIG11c3QgYmUgMCBpZiBSZWN0cyBpcyBOVUxMCiAqICBSZWN0czogUmVjdGFuZ2xlcyB0byBjbGVhci4gSWYgTlVMTCwgdGhlIHdob2xlIHN1cmZhY2UgaXMgY2xlYXJlZAogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MsIGFzIHVzdWFsCiAqICBDb2xvcjogQ2xlYXIgY29sb3IgZm9yIHRoZSByZW5kZXIgdGFyZ2V0CiAqICBaOiBDbGVhciB2YWx1ZSBmb3IgdGhlIFogYnVmZmVyCiAqICBTdGVuY2lsOiBDbGVhciB2YWx1ZSB0byBzdG9yZSBpbiBlYWNoIHN0ZW5jaWwgYnVmZmVyIGVudHJ5CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6Q2xlYXIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0NsZWFyKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RSRUNUICpSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1IgQ29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWQUxVRSBaLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RlbmNpbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlMDh4LCUwOHgsJWYsJTA4eCk6IFJlbGF5XG4iLCBUaGlzLCBDb3VudCwgUmVjdHMsIEZsYWdzLCBDb2xvciwgWiwgU3RlbmNpbCk7CgogICAgLyogTm90ZTsgRDNEUkVDVCBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRFJFQ1QgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0NsZWFyKFRoaXMtPndpbmVEM0REZXZpY2UsIENvdW50LCAoV0lORUQzRFJFQ1QqKSBSZWN0cywgRmxhZ3MsIENvbG9yLCBaLCBTdGVuY2lsKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpTZXRWaWV3cG9ydAogKgogKiBTZXRzIHRoZSBjdXJyZW50IHZpZXdwb3J0LgogKgogKiBWZXJzaW9uIDcgb25seSwgYnV0IElEaXJlY3QzRFZpZXdwb3J0IHVzZXMgdGhpcyBjYWxsIGZvciBvbGRlcgogKiB2ZXJzaW9ucwogKgogKiBQYXJhbXM6CiAqICBEYXRhOiBUaGUgbmV3IHZpZXdwb3J0IHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRGF0YSBpcyBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVERERldmljZTo6U2V0Vmlld3BvcnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFZpZXdwb3J0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVklFV1BPUlQ3ICpEYXRhKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCkgUmVsYXkhXG4iLCBUaGlzLCBEYXRhKTsKCiAgICBpZighRGF0YSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBOb3RlOiBEM0RWSUVXUE9SVDcgaXMgY29tcGF0aWJsZSB3aXRoIFdJTkVEM0RWSUVXUE9SVCAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RWSUVXUE9SVCopIERhdGEpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTo6R2V0Vmlld3BvcnQKICoKICogUmV0dXJucyB0aGUgY3VycmVudCB2aWV3cG9ydAogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgRGF0YTogRDNEN1ZpZXdwb3J0IHN0cnVjdHVyZSB0byB3cml0ZSB0aGUgdmlld3BvcnQgaW5mb3JtYXRpb24gdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpHZXRWaWV3cG9ydAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Vmlld3BvcnQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RWSUVXUE9SVDcgKkRhdGEpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKSBSZWxheSFcbiIsIFRoaXMsIERhdGEpOwoKICAgIGlmKCFEYXRhKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIE5vdGU6IEQzRFZJRVdQT1JUNyBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRFZJRVdQT1JUICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRWaWV3cG9ydChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRFZJRVdQT1JUKikgRGF0YSk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0TWF0ZXJpYWwKICoKICogU2V0cyB0aGUgTWF0ZXJpYWwKICoKICogVmVyc2lvbiA3CiAqCiAqIFBhcmFtczoKICogIE1hdDogVGhlIG1hdGVyaWFsIHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgTWF0IGlzIE5VTEwuCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OlNldE1hdGVyaWFsCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRNYXRlcmlhbChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVEVSSUFMNyAqTWF0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5IVxuIiwgVGhpcywgTWF0KTsKCiAgICAvKiBOb3RlOiBEM0RNQVRFUklBTDcgaXMgY29tcGF0aWJsZSB3aXRoIFdJTkVEM0RNQVRFUklBTCAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0TWF0ZXJpYWwoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RNQVRFUklBTCopIE1hdCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRNYXRlcmlhbAogKgogKiBSZXR1cm5zIHRoZSBjdXJyZW50IG1hdGVyaWFsCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBNYXQ6IEQzRE1BVEVSSUFMNyBzdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIG1hdGVyaWFsIHBhcmFtZXRlcnMgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIE1hdCBpcyBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldE1hdGVyaWFsCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRNYXRlcmlhbChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRE1BVEVSSUFMNyAqTWF0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5IVxuIiwgVGhpcywgTWF0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogTm90ZTogRDNETUFURVJJQUw3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETUFURVJJQUwgKi8gCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldE1hdGVyaWFsKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETUFURVJJQUwqKSBNYXQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6U2V0TGlnaHQKICoKICogQXNzaWducyBhIGxpZ2h0IHRvIGEgbGlnaHQgaW5kZXgsIGJ1dCBkb2Vzbid0IGFjdGl2YXRlIGl0IHlldC4KICoKICogVmVyc2lvbiA3LCBJRGlyZWN0M0RMaWdodCB1c2VzIHRoaXMgbWV0aG9kIGZvciBvbGRlciB2ZXJzaW9ucwogKgogKiBQYXJhbXM6CiAqICBMaWdodEluZGV4OiBUaGUgaW5kZXggb2YgdGhlIG5ldyBsaWdodAogKiAgTGlnaHQ6IEEgRDNETElHSFQ3IHN0cnVjdHVyZSBkZXNjcmliaW5nIHRoZSBsaWdodAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6U2V0TGlnaHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0KElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRExJR0hUNyAqTGlnaHQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIExpZ2h0SW5kZXgsIExpZ2h0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogTm90ZTogRDNETElHSFQ3IGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNETElHSFQgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfU2V0TGlnaHQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RMSUdIVCopIExpZ2h0KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldExpZ2h0CiAqCiAqIFJldHVybnMgdGhlIGxpZ2h0IGFzc2lnbmVkIHRvIGEgbGlnaHQgaW5kZXgKICoKICogUGFyYW1zOgogKiAgTGlnaHQ6IFN0cnVjdHVyZSB0byB3cml0ZSB0aGUgbGlnaHQgaW5mb3JtYXRpb24gdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIExpZ2h0IGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0REZXZpY2U6OkdldExpZ2h0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRMaWdodChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIExpZ2h0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RMSUdIVDcgKkxpZ2h0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIHJjOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKTogUmVsYXkhXG4iLCBUaGlzLCBMaWdodEluZGV4LCBMaWdodCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIE5vdGU6IEQzRExJR0hUNyBpcyBjb21wYXRpYmxlIHdpdGggV0lORUQzRExJR0hUICovCiAgICByYyA9ICBJV2luZUQzRERldmljZV9HZXRMaWdodChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNETElHSFQqKSBMaWdodCk7CgogICAgLyogVHJhbnNsYXRlIHRoZSByZXN1bHQuIFdpbmVEM0QgcmV0dXJucyBvdGhlciB2YWx1ZXMgdGhhbiBEM0Q3ICovCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChyYyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpCZWdpblN0YXRlQmxvY2sKICoKICogQmVnaW5zIHJlY29yZGluZyB0byBhIHN0YXRlYmxvY2sKICoKICogVmVyc2lvbiA3CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIGRldGFpbHMgc2VlIElXaW5lRDNERGV2aWNlOjpCZWdpblN0YXRlQmxvY2sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9jayhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oKTogUmVsYXkhXG4iLCBUaGlzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9CZWdpblN0YXRlQmxvY2soVGhpcy0+d2luZUQzRERldmljZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpFbmRTdGF0ZUJsb2NrCiAqCiAqIFN0b3BzIHJlY29yZGluZyB0byBhIHN0YXRlIGJsb2NrIGFuZCByZXR1cm5zIHRoZSBjcmVhdGVkIHN0YXRlYmxvY2sKICogaGFuZGxlLgogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgQmxvY2tIYW5kbGU6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIHN0YXRlYmxvY2sncyBoYW5kbGUgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEJsb2NrSGFuZGxlIGlzIE5VTEwKICogIFNlZSBJV2luZUQzRERldmljZTo6RW5kU3RhdGVCbG9jayBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19FbmRTdGF0ZUJsb2NrKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXkhXG4iLCBUaGlzLCBCbG9ja0hhbmRsZSk7CgogICAgaWYoIUJsb2NrSGFuZGxlKQogICAgewogICAgICAgIFdBUk4oIkJsb2NrSGFuZGxlID09IE5VTEwsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgKkJsb2NrSGFuZGxlID0gSURpcmVjdDNERGV2aWNlSW1wbF9DcmVhdGVIYW5kbGUoVGhpcyk7CiAgICBpZighKkJsb2NrSGFuZGxlKQogICAgewogICAgICAgIEVSUigiQ2Fubm90IGdldCBhIGhhbmRsZSBudW1iZXIgZm9yIHRoZSBzdGF0ZWJsb2NrXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRk1FTU9SWTsKICAgIH0KICAgIFRoaXMtPkhhbmRsZXNbKkJsb2NrSGFuZGxlIC0gMV0udHlwZSA9IEREcmF3SGFuZGxlX1N0YXRlQmxvY2s7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0VuZFN0YXRlQmxvY2soVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdGF0ZUJsb2NrICoqKSAmVGhpcy0+SGFuZGxlc1sqQmxvY2tIYW5kbGUgLSAxXS5wdHIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6UHJlTG9hZAogKgogKiBBbGxvd3MgdGhlIGFwcCB0byBzaWduYWwgdGhhdCBhIHRleHR1cmUgd2lsbCBiZSB1c2VkIHNvb24sIHRvIGFsbG93CiAqIHRoZSBEaXJlY3QzRERldmljZSB0byBsb2FkIGl0IHRvIHRoZSB2aWRlbyBjYXJkIGluIHRoZSBtZWFudGltZS4KICoKICogVmVyc2lvbiA3CiAqCiAqIFBhcmFtczoKICogIFRleHR1cmU6IFRoZSB0ZXh0dXJlIHRvIHByZWxvYWQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFRleHR1cmUgaXMgTlVMTAogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6UHJlTG9hZCBmb3IgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfUHJlTG9hZChJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqVGV4dHVyZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheSFcbiIsIFRoaXMsIHN1cmYpOwoKICAgIGlmKCFUZXh0dXJlKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChzdXJmLT5XaW5lRDNEU3VyZmFjZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkFwcGx5U3RhdGVCbG9jawogKgogKiBBY3RpdmF0ZXMgdGhlIHN0YXRlIHN0b3JlZCBpbiBhIHN0YXRlIGJsb2NrIGhhbmRsZS4KICoKICogUGFyYW1zOgogKiAgQmxvY2tIYW5kbGU6IFRoZSBzdGF0ZWJsb2NrIGhhbmRsZSB0byBhY3RpdmF0ZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSyBpZiBCbG9ja0hhbmRsZSBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2soSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgpOiBSZWxheSFcbiIsIFRoaXMsIEJsb2NrSGFuZGxlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoIUJsb2NrSGFuZGxlIHx8IEJsb2NrSGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBXQVJOKCJPdXQgb2YgcmFuZ2UgaGFuZGxlICVkLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURTVEFURUJMT0NLXG4iLCBCbG9ja0hhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRDNERVJSX0lOVkFMSURTVEFURUJMT0NLOwogICAgfQogICAgaWYoVGhpcy0+SGFuZGxlc1tCbG9ja0hhbmRsZSAtIDFdLnR5cGUgIT0gRERyYXdIYW5kbGVfU3RhdGVCbG9jaykKICAgIHsKICAgICAgICBXQVJOKCJIYW5kbGUgJWQgaXMgbm90IGEgc3RhdGVibG9jaywgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DS1xuIiwgQmxvY2tIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSzsKICAgIH0KCiAgICBociA9IElXaW5lRDNEU3RhdGVCbG9ja19BcHBseSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocl9kZHJhd19mcm9tX3dpbmVkM2QoaHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6Q2FwdHVyZVN0YXRlQmxvY2sKICoKICogVXBkYXRlcyBhIHN0YXRlYmxvY2sncyB2YWx1ZXMgdG8gdGhlIHZhbHVlcyBjdXJyZW50bHkgc2V0IGZvciB0aGUgZGV2aWNlCiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBCbG9ja0hhbmRsZTogU3RhdGVibG9jayB0byB1cGRhdGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0sgaWYgQmxvY2tIYW5kbGUgaXMgTlVMTAogKiAgU2VlIElXaW5lRDNERGV2aWNlOjpDYXB0dXJlU3RhdGVCbG9jayBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19DYXB0dXJlU3RhdGVCbG9jayhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJsb2NrSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4KTogUmVsYXkhXG4iLCBUaGlzLCBCbG9ja0hhbmRsZSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKEJsb2NrSGFuZGxlID09IDAgfHwgQmxvY2tIYW5kbGUgPiBUaGlzLT5udW1IYW5kbGVzKQogICAgewogICAgICAgIFdBUk4oIk91dCBvZiByYW5nZSBoYW5kbGUgJWQsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0tcbiIsIEJsb2NrSGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0s7CiAgICB9CiAgICBpZihUaGlzLT5IYW5kbGVzW0Jsb2NrSGFuZGxlIC0gMV0udHlwZSAhPSBERHJhd0hhbmRsZV9TdGF0ZUJsb2NrKQogICAgewogICAgICAgIFdBUk4oIkhhbmRsZSAlZCBpcyBub3QgYSBzdGF0ZWJsb2NrLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURTVEFURUJMT0NLXG4iLCBCbG9ja0hhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRDNERVJSX0lOVkFMSURTVEFURUJMT0NLOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RTdGF0ZUJsb2NrX0NhcHR1cmUoKElXaW5lRDNEU3RhdGVCbG9jayAqKSBUaGlzLT5IYW5kbGVzW0Jsb2NrSGFuZGxlIC0gMV0ucHRyKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkRlbGV0ZVN0YXRlQmxvY2sKICoKICogRGVsZXRlcyBhIHN0YXRlYmxvY2sgaGFuZGxlLiBUaGlzIG1lYW5zIHJlbGVhc2luZyB0aGUgV2luZUQzRFN0YXRlQmxvY2sKICoKICogVmVyc2lvbiA3CiAqCiAqIFBhcmFtczoKICogIEJsb2NrSGFuZGxlOiBTdGF0ZWJsb2NrIGhhbmRsZSB0byBkZWxldGUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfSU5WQUxJRFNUQVRFQkxPQ0sgaWYgQmxvY2tIYW5kbGUgaXMgMAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfRGVsZXRlU3RhdGVCbG9jayhJRGlyZWN0M0REZXZpY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCk6IFJlbGF5IVxuIiwgVGhpcywgQmxvY2tIYW5kbGUpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihCbG9ja0hhbmRsZSA9PSAwIHx8IEJsb2NrSGFuZGxlID4gVGhpcy0+bnVtSGFuZGxlcykKICAgIHsKICAgICAgICBXQVJOKCJPdXQgb2YgcmFuZ2UgaGFuZGxlICVkLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURTVEFURUJMT0NLXG4iLCBCbG9ja0hhbmRsZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRDNERVJSX0lOVkFMSURTVEFURUJMT0NLOwogICAgfQogICAgaWYoVGhpcy0+SGFuZGxlc1tCbG9ja0hhbmRsZSAtIDFdLnR5cGUgIT0gRERyYXdIYW5kbGVfU3RhdGVCbG9jaykKICAgIHsKICAgICAgICBXQVJOKCJIYW5kbGUgJWQgaXMgbm90IGEgc3RhdGVibG9jaywgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DS1xuIiwgQmxvY2tIYW5kbGUpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEU1RBVEVCTE9DSzsKICAgIH0KCiAgICByZWYgPSBJV2luZUQzRFN0YXRlQmxvY2tfUmVsZWFzZSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIpOwogICAgaWYocmVmKQogICAgewogICAgICAgIEVSUigiU29tZXRoaW5nIGlzIHN0aWxsIGhvbGRpbmcgdGhlIHN0YXRlYmxvY2sgJXAoSGFuZGxlICVkKS4gUmVmID0gJWRcbiIsIFRoaXMtPkhhbmRsZXNbQmxvY2tIYW5kbGUgLSAxXS5wdHIsIEJsb2NrSGFuZGxlLCByZWYpOwogICAgfQogICAgVGhpcy0+SGFuZGxlc1tCbG9ja0hhbmRsZSAtIDFdLnB0ciA9IE5VTEw7CiAgICBUaGlzLT5IYW5kbGVzW0Jsb2NrSGFuZGxlIC0gMV0udHlwZSA9IEREcmF3SGFuZGxlX1Vua25vd247CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpDcmVhdGVTdGF0ZUJsb2NrCiAqCiAqIENyZWF0ZXMgYSBuZXcgc3RhdGUgYmxvY2sgaGFuZGxlLgogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgVHlwZTogVGhlIHN0YXRlIGJsb2NrIHR5cGUKICogIEJsb2NrSGFuZGxlOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBjcmVhdGVkIGhhbmRsZSB0bwogKgogKiBSZXR1cm5zOgogKiAgIEQzRF9PSyBvbiBzdWNjZXNzCiAqICAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBCbG9ja0hhbmRsZSBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19DcmVhdGVTdGF0ZUJsb2NrKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RTVEFURUJMT0NLVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQmxvY2tIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApIVxuIiwgVGhpcywgVHlwZSwgQmxvY2tIYW5kbGUpOwoKICAgIGlmKCFCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBXQVJOKCJCbG9ja0hhbmRsZSA9PSBOVUxMLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CiAgICBpZihUeXBlICE9IEQzRFNCVF9BTEwgICAgICAgICAmJiBUeXBlICE9IEQzRFNCVF9QSVhFTFNUQVRFICYmCiAgICAgICBUeXBlICE9IEQzRFNCVF9WRVJURVhTVEFURSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgewogICAgICAgIFdBUk4oIlVuZXhwZWN0ZWQgc3RhdGVibG9jayB0eXBlLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpCbG9ja0hhbmRsZSA9IElEaXJlY3QzRERldmljZUltcGxfQ3JlYXRlSGFuZGxlKFRoaXMpOwogICAgaWYoISpCbG9ja0hhbmRsZSkKICAgIHsKICAgICAgICBFUlIoIkNhbm5vdCBnZXQgYSBoYW5kbGUgbnVtYmVyIGZvciB0aGUgc3RhdGVibG9ja1xuIik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUaGlzLT5IYW5kbGVzWypCbG9ja0hhbmRsZSAtIDFdLnR5cGUgPSBERHJhd0hhbmRsZV9TdGF0ZUJsb2NrOwoKICAgIC8qIFRoZSBEM0RTVEFURUJMT0NLVFlQRSBlbnVtIGlzIGZpbmUgaGVyZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVTdGF0ZUJsb2NrKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdGF0ZUJsb2NrICoqKSAmVGhpcy0+SGFuZGxlc1sqQmxvY2tIYW5kbGUgLSAxXS5wdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBQYXJlbnQsIGhvcGUgdGhhdCB3b3JrcyAqLyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpMb2FkCiAqCiAqIExvYWRzIGEgcmVjdGFuZ3VsYXIgYXJlYSBmcm9tIHRoZSBzb3VyY2UgaW50byB0aGUgZGVzdGluYXRpb24gdGV4dHVyZS4KICogSXQgY2FuIGFsc28gY29weSB0aGUgc291cmNlIHRvIHRoZSBmYWNlcyBvZiBhIGN1YmljIGVudmlyb25tZW50IG1hcAogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgRGVzdFRleDogRGVzdGluYXRpb24gdGV4dHVyZQogKiAgRGVzdFBvaW50OiBQb2ludCBpbiB0aGUgZGVzdGluYXRpb24gd2hlcmUgdGhlIHNvdXJjZSBpbWFnZSBzaG91bGQgYmUKICogICAgICAgICAgICAgd3JpdHRlbiB0bwogKiAgU3JjVGV4OiBTb3VyY2UgdGV4dHVyZQogKiAgU3JjUmVjdDogU291cmNlIHJlY3RhbmdsZQogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERlc3RUZXggb3IgU3JjVGV4IGFyZSBOVUxMCiAqICBTZWUgSURpcmVjdDNEVGV4dHVyZTI6OkxvYWQgZm9yIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0xvYWQoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RUZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFBPSU5UICpEZXN0UG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlNyY1RleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3QgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBEZXN0VGV4KTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyY1RleCk7CiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwLCVwLCVwLCUwOHgpOiBQYXJ0aWFsbHkgSW1wbGVtZW50ZWQhXG4iLCBUaGlzLCBkZXN0LCBEZXN0UG9pbnQsIHNyYywgU3JjUmVjdCwgRmxhZ3MpOwoKICAgIGlmKCAoIXNyYykgfHwgKCFkZXN0KSApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgSURpcmVjdDNEVGV4dHVyZTJfTG9hZChJQ09NX0lOVEVSRkFDRShkZXN0LCBJRGlyZWN0M0RUZXh0dXJlMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKHNyYywgSURpcmVjdDNEVGV4dHVyZTIpKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpMaWdodEVuYWJsZQogKgogKiBFbmFibGVzIG9yIGRpc2FibGVzIGEgbGlnaHQKICoKICogVmVyc2lvbiA3LCBJRGlyZWN0M0RMaWdodCB1c2VzIHRoaXMgbWV0aG9kIHRvby4KICoKICogUGFyYW1zOgogKiAgTGlnaHRJbmRleDogVGhlIGluZGV4IG9mIHRoZSBsaWdodCB0byBlbmFibGUgLyBkaXNhYmxlCiAqICBFbmFibGU6IEVuYWJsZSBvciBkaXNhYmxlIHRoZSBsaWdodAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRERldmljZTo6U2V0TGlnaHRFbmFibGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0xpZ2h0RW5hYmxlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgRW5hYmxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVkKTogUmVsYXkhXG4iLCBUaGlzLCBMaWdodEluZGV4LCBFbmFibGUpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldExpZ2h0RW5hYmxlKFRoaXMtPndpbmVEM0REZXZpY2UsIExpZ2h0SW5kZXgsIEVuYWJsZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyX2RkcmF3X2Zyb21fd2luZWQzZChocik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2U3OjpHZXRMaWdodEVuYWJsZQogKgogKiBSZXRyaWV2ZXMgaWYgdGhlIGxpZ2h0IHdpdGggdGhlIGdpdmVuIGluZGV4IGlzIGVuYWJsZWQgb3Igbm90CiAqCiAqIFZlcnNpb24gNwogKgogKiBQYXJhbXM6CiAqICBMaWdodEluZGV4OiBJbmRleCBvZiBkZXNpcmVkIGxpZ2h0CiAqICBFbmFibGU6IFBvaW50ZXIgdG8gYSBCT09MIHdoaWNoIGNvbnRhaW5zIHRoZSByZXN1bHQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEVuYWJsZSBpcyBOVUxMCiAqICBTZWUgSVdpbmVEM0REZXZpY2U6OkdldExpZ2h0RW5hYmxlIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0RW5hYmxlKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTGlnaHRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wqIEVuYWJsZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBMaWdodEluZGV4LCBFbmFibGUpOwoKICAgIGlmKCFFbmFibGUpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0TGlnaHRFbmFibGUoVGhpcy0+d2luZUQzRERldmljZSwgTGlnaHRJbmRleCwgRW5hYmxlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHJfZGRyYXdfZnJvbV93aW5lZDNkKGhyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OlNldENsaXBQbGFuZQogKgogKiBTZXRzIGN1c3RvbSBjbGlwcGluZyBwbGFuZQogKgogKiBWZXJzaW9uIDcKICoKICogUGFyYW1zOgogKiAgSW5kZXg6IFRoZSBpbmRleCBvZiB0aGUgY2xpcHBpbmcgcGxhbmUKICogIFBsYW5lRXF1YXRpb246IEFuIGVxdWF0aW9uIGRlZmluaW5nIHRoZSBjbGlwcGluZyBwbGFuZQogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgUGxhbmVFcXVhdGlvbiBpcyBOVUxMCiAqICBTZWUgSVdpbmVEM0REZXZpY2U6OlNldENsaXBQbGFuZSBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19TZXRDbGlwUGxhbmUoSURpcmVjdDNERGV2aWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVkFMVUUqIFBsYW5lRXF1YXRpb24pCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApOiBSZWxheSFcbiIsIFRoaXMsIEluZGV4LCBQbGFuZUVxdWF0aW9uKTsKCiAgICBpZighUGxhbmVFcXVhdGlvbikKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXRDbGlwUGxhbmUoVGhpcy0+d2luZUQzRERldmljZSwgSW5kZXgsIFBsYW5lRXF1YXRpb24pOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRERldmljZTc6OkdldENsaXBQbGFuZQogKgogKiBSZXR1cm5zIHRoZSBjbGlwcGluZyBwbGFuZSB3aXRoIGEgc3BlY2lmaWMgaW5kZXgKICoKICogUGFyYW1zOgogKiAgSW5kZXg6IFRoZSBpbmRleCBvZiB0aGUgZGVzaXJlZCBwbGFuZQogKiAgUGxhbmVFcXVhdGlvbjogQWRkcmVzcyB0byBzdG9yZSB0aGUgcGxhbmUgZXF1YXRpb24gdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFBsYW5lRXF1YXRpb24gaXMgTlVMTAogKiAgU2VlIElXaW5lRDNERGV2aWNlOjpHZXRDbGlwUGxhbmUgZm9yIG1vcmUgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0Q2xpcFBsYW5lKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRFZBTFVFKiBQbGFuZUVxdWF0aW9uKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlcCk6IFJlbGF5IVxuIiwgVGhpcywgSW5kZXgsIFBsYW5lRXF1YXRpb24pOwoKICAgIGlmKCFQbGFuZUVxdWF0aW9uKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldENsaXBQbGFuZShUaGlzLT53aW5lRDNERGV2aWNlLCBJbmRleCwgUGxhbmVFcXVhdGlvbik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNERGV2aWNlNzo6R2V0SW5mbwogKgogKiBSZXRyaWV2ZXMgc29tZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZGV2aWNlLiBUaGUgRGlyZWN0WCBzZGsgc2F5cyB0aGF0CiAqIHRoaXMgdmVyc2lvbiByZXR1cm5zIFNfRkFMU0UgZm9yIGFsbCByZXRhaWwgYnVpbGRzIG9mIERpcmVjdFgsIHRoYXQncyB3aGF0CiAqIHRoaXMgaW1wbGVtZW50YXRpb24gZG9lcy4KICoKICogUGFyYW1zOgogKiAgRGV2SW5mb0lEOiBJbmZvcm1hdGlvbiB0eXBlIHJlcXVlc3RlZAogKiAgRGV2SW5mb1N0cnVjdDogUG9pbnRlciB0byBhIHN0cnVjdHVyZSB0byBzdG9yZSB0aGUgaW5mbyB0bwogKiAgU2l6ZTogU2l6ZSBvZiB0aGUgc3RydWN0dXJlCiAqCiAqIFJldHVybnM6CiAqICBTX0ZBTFNFLCBiZWNhdXNlIGl0J3MgYSBub24tZGVidWcgZHJpdmVyCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRERldmljZUltcGxfN19HZXRJbmZvKElEaXJlY3QzRERldmljZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBEZXZJbmZvSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkRldkluZm9TdHJ1Y3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFNpemUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcCwlMDh4KVxuIiwgVGhpcywgRGV2SW5mb0lELCBEZXZJbmZvU3RydWN0LCBTaXplKTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkNykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiBpbmZvIHJlcXVlc3RlZCA6ICIpOwogICAgICAgIHN3aXRjaCAoRGV2SW5mb0lEKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfVEVYVFVSRU1BTkFHRVI6IFRSQUNFKCJEM0RERVZJTkZPSURfVEVYVFVSRU1BTkFHRVJcbiIpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfRDNEVEVYVFVSRU1BTkFHRVI6IFRSQUNFKCJEM0RERVZJTkZPSURfRDNEVEVYVFVSRU1BTkFHRVJcbiIpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBEM0RERVZJTkZPSURfVEVYVFVSSU5HOiBUUkFDRSgiRDNEREVWSU5GT0lEX1RFWFRVUklOR1xuIik7IGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OiBFUlIoIiBpbnZhbGlkIGZsYWcgISEhXG4iKTsgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBTX0ZBTFNFOyAvKiBBY2NvcmRpbmcgdG8gTVNETiwgdGhpcyBpcyB2YWxpZCBmb3IgYSBub24tZGVidWcgZHJpdmVyICovCn0KCmNvbnN0IElEaXJlY3QzRERldmljZTdWdGJsIElEaXJlY3QzRERldmljZTdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gTWV0aG9kcyAqKiovCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQWRkUmVmLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3QzRERldmljZTcgKioqLwogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENhcHMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW51bVRleHR1cmVGb3JtYXRzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU2NlbmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRW5kU2NlbmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0RGlyZWN0M0QsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0UmVuZGVyVGFyZ2V0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclRhcmdldCwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19DbGVhciwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRUcmFuc2Zvcm0sCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0VHJhbnNmb3JtLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X011bHRpcGx5VHJhbnNmb3JtLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldE1hdGVyaWFsLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldE1hdGVyaWFsLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldExpZ2h0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldExpZ2h0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1NldFJlbmRlclN0YXRlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFJlbmRlclN0YXRlLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0JlZ2luU3RhdGVCbG9jaywKICAgIElEaXJlY3QzRERldmljZUltcGxfN19FbmRTdGF0ZUJsb2NrLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X1ByZUxvYWQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRDbGlwU3RhdHVzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENsaXBTdGF0dXMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd1ByaW1pdGl2ZVN0cmlkZWQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0RyYXdQcmltaXRpdmVWQiwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0NvbXB1dGVTcGhlcmVWaXNpYmlsaXR5LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldFRleHR1cmUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0VGV4dHVyZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19WYWxpZGF0ZURldmljZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19BcHBseVN0YXRlQmxvY2ssCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfQ2FwdHVyZVN0YXRlQmxvY2ssCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfRGVsZXRlU3RhdGVCbG9jaywKICAgIElEaXJlY3QzRERldmljZUltcGxfN19DcmVhdGVTdGF0ZUJsb2NrLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0xvYWQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfTGlnaHRFbmFibGUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfR2V0TGlnaHRFbmFibGUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzdfU2V0Q2xpcFBsYW5lLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF83X0dldENsaXBQbGFuZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfN19HZXRJbmZvCn07Cgpjb25zdCBJRGlyZWN0M0REZXZpY2UzVnRibCBJRGlyZWN0M0REZXZpY2UzX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duIE1ldGhvZHMgKioqLwogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1F1ZXJ5SW50ZXJmYWNlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0FkZFJlZiwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0M0REZXZpY2UzICoqKi8KICAgIElEaXJlY3QzRERldmljZUltcGxfM19HZXRDYXBzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFN0YXRzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0FkZFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX0RlbGV0ZVZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX05leHRWaWV3cG9ydCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19FbnVtVGV4dHVyZUZvcm1hdHMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW5TY2VuZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19FbmRTY2VuZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXREaXJlY3QzRCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19TZXRDdXJyZW50Vmlld3BvcnQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0Q3VycmVudFZpZXdwb3J0LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFJlbmRlclRhcmdldCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRSZW5kZXJUYXJnZXQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW4sCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfQmVnaW5JbmRleGVkLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8zX1ZlcnRleCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19JbmRleCwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19FbmQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0UmVuZGVyU3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0UmVuZGVyU3RhdGUsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzNfR2V0TGlnaHRTdGF0ZSwKICAgIElEaXJlY3QzRERldmljZUltcGxfM19TZXRMaWdodFN0YXRlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX1NldFRyYW5zZm9ybSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRUcmFuc2Zvcm0sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfTXVsdGlwbHlUcmFuc2Zvcm0sCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd1ByaW1pdGl2ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3SW5kZXhlZFByaW1pdGl2ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRDbGlwU3RhdHVzLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldENsaXBTdGF0dXMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd1ByaW1pdGl2ZVN0cmlkZWQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0RyYXdQcmltaXRpdmVWQiwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19EcmF3SW5kZXhlZFByaW1pdGl2ZVZCLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0NvbXB1dGVTcGhlcmVWaXNpYmlsaXR5LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8zX0dldFRleHR1cmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzNfU2V0VGV4dHVyZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfM19WYWxpZGF0ZURldmljZQp9OwoKY29uc3QgSURpcmVjdDNERGV2aWNlMlZ0YmwgSURpcmVjdDNERGV2aWNlMl9WdGJsID0KewogICAgLyoqKiBJVW5rbm93biBNZXRob2RzICoqKi8KICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9RdWVyeUludGVyZmFjZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9BZGRSZWYsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfUmVsZWFzZSwKICAgIC8qKiogSURpcmVjdDNERGV2aWNlMiAqKiovCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q2FwcywKICAgIElEaXJlY3QzRERldmljZUltcGxfMl9Td2FwVGV4dHVyZUhhbmRsZXMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0U3RhdHMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfQWRkVmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfRGVsZXRlVmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfTmV4dFZpZXdwb3J0LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8yX0VudW1UZXh0dXJlRm9ybWF0cywKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9CZWdpblNjZW5lLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0VuZFNjZW5lLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldERpcmVjdDNELAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldEN1cnJlbnRWaWV3cG9ydCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRDdXJyZW50Vmlld3BvcnQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0UmVuZGVyVGFyZ2V0LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFJlbmRlclRhcmdldCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9CZWdpbiwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9CZWdpbkluZGV4ZWQsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfVmVydGV4LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0luZGV4LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0VuZCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRSZW5kZXJTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9TZXRSZW5kZXJTdGF0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9HZXRMaWdodFN0YXRlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldExpZ2h0U3RhdGUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfU2V0VHJhbnNmb3JtLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0dldFRyYW5zZm9ybSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9NdWx0aXBseVRyYW5zZm9ybSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMl9EcmF3UHJpbWl0aXZlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX0RyYXdJbmRleGVkUHJpbWl0aXZlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8yX1NldENsaXBTdGF0dXMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzJfR2V0Q2xpcFN0YXR1cwp9OwoKY29uc3QgSURpcmVjdDNERGV2aWNlVnRibCBJRGlyZWN0M0REZXZpY2UxX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duIE1ldGhvZHMgKioqLwogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX1F1ZXJ5SW50ZXJmYWNlLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0FkZFJlZiwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0M0REZXZpY2UxICoqKi8KICAgIElEaXJlY3QzRERldmljZUltcGxfMV9Jbml0aWFsaXplLAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0dldENhcHMsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfU3dhcFRleHR1cmVIYW5kbGVzLAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX0NyZWF0ZUV4ZWN1dGVCdWZmZXIsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0U3RhdHMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfRXhlY3V0ZSwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9BZGRWaWV3cG9ydCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9EZWxldGVWaWV3cG9ydCwKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9OZXh0Vmlld3BvcnQsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfUGljaywKICAgIElEaXJlY3QzRERldmljZUltcGxfMV9HZXRQaWNrUmVjb3JkcywKICAgIFRodW5rX0lEaXJlY3QzRERldmljZUltcGxfMV9FbnVtVGV4dHVyZUZvcm1hdHMsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfQ3JlYXRlTWF0cml4LAogICAgSURpcmVjdDNERGV2aWNlSW1wbF8xX1NldE1hdHJpeCwKICAgIElEaXJlY3QzRERldmljZUltcGxfMV9HZXRNYXRyaXgsCiAgICBJRGlyZWN0M0REZXZpY2VJbXBsXzFfRGVsZXRlTWF0cml4LAogICAgVGh1bmtfSURpcmVjdDNERGV2aWNlSW1wbF8xX0JlZ2luU2NlbmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfRW5kU2NlbmUsCiAgICBUaHVua19JRGlyZWN0M0REZXZpY2VJbXBsXzFfR2V0RGlyZWN0M0QKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2VJbXBsX0NyZWF0ZUhhbmRsZQogKgogKiBOb3QgY2FsbGVkIGZyb20gdGhlIFZUYWJsZQogKgogKiBTb21lIG9sZGVyIGludGVyZmFjZSB2ZXJzaW9ucyBvcGVyYXRlIHdpdGggaGFuZGxlcywgd2hpY2ggYXJlIGJhc2ljYWxseQogKiBEV09SRHMgd2hpY2ggaWRlbnRpZnkgYW4gaW50ZXJmYWNlLCBmb3IgZXhhbXBsZQogKiBJRGlyZWN0M0REZXZpY2U6OlNldFJlbmRlclN0YXRlIHdpdGggRElSRUNUM0RSRU5ERVJTVEFURV9URVhUVVJFSEFORExFCiAqCiAqIFRob3NlIGhhbmRsZSBjb3VsZCBiZSBqdXN0IGNhc3RzIHRvIHRoZSBpbnRlcmZhY2UgcG9pbnRlcnMgb3IgdmljZSB2ZXJzYSwKICogYnV0IHRoYXQgaXMgbm90IDY0IGJpdCBzYWZlIGFuZCB3b3VsZCBtZWFuIGJsaW5kbHkgZGVyZWZlcmluZyBhIERXT1JECiAqIHBhc3NlZCBieSB0aGUgYXBwLiBJbnN0ZWFkIHRoZXJlIGlzIGEgZHluYW1pYyBhcnJheSBpbiB0aGUgZGV2aWNlIHdoaWNoCiAqIGtlZXBzIGEgRFdPUkQgdG8gcG9pbnRlciBpbmZvcm1hdGlvbiBhbmQgYSB0eXBlIGZvciB0aGUgaGFuZGxlLgogKgogKiBCYXNpY2FsbHkgdGhpcyBhcnJheSBvbmx5IGdyb3dzLCB3aGVuIGEgaGFuZGxlIGlzIGZyZWVkIGl0cyBwb2ludGVyIGlzCiAqIGp1c3Qgc2V0IHRvIE5VTEwuIFRoZXJlIHdpbGwgYmUgbXVjaCBtb3JlIHJlYWRzIGZyb20gdGhlIGFycmF5IHRoYW4KICogaW5zZXJ0aW9uIG9wZXJhdGlvbnMsIHNvIGEgZHluYW1pYyBhcnJheSBpcyBmaW5lLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEM0REZXZpY2UgaW1wbGVtZW50YXRpb24gZm9yIHdoaWNoIHRoaXMgaGFuZGxlIHNob3VsZCBiZSBjcmVhdGVkCiAqCiAqIFJldHVybnM6CiAqICBBIGZyZWUgaGFuZGxlIG9uIHN1Y2Nlc3MKICogIDAgb24gZmFpbHVyZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkRXT1JECklEaXJlY3QzRERldmljZUltcGxfQ3JlYXRlSGFuZGxlKElEaXJlY3QzRERldmljZUltcGwgKlRoaXMpCnsKICAgIERXT1JEIGk7CiAgICBzdHJ1Y3QgSGFuZGxlRW50cnkgKm9sZEhhbmRsZXMgPSBUaGlzLT5IYW5kbGVzOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1IYW5kbGVzOyBpKyspCiAgICB7CiAgICAgICAgaWYoVGhpcy0+SGFuZGxlc1tpXS5wdHIgPT0gTlVMTCAmJgogICAgICAgICAgIFRoaXMtPkhhbmRsZXNbaV0udHlwZSA9PSBERHJhd0hhbmRsZV9Vbmtub3duKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlJldXNpbmcgZnJlZWQgaGFuZGxlICVkXG4iLCBpICsgMSk7CiAgICAgICAgICAgIHJldHVybiBpICsgMTsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIkdyb3dpbmcgdGhlIGhhbmRsZSBhcnJheVxuIik7CgogICAgVGhpcy0+bnVtSGFuZGxlcysrOwogICAgVGhpcy0+SGFuZGxlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2Yoc3RydWN0IEhhbmRsZUVudHJ5KSAqIFRoaXMtPm51bUhhbmRsZXMpOwogICAgaWYoIVRoaXMtPkhhbmRsZXMpCiAgICB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICBUaGlzLT5IYW5kbGVzID0gb2xkSGFuZGxlczsKICAgICAgICBUaGlzLT5udW1IYW5kbGVzLS07CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZihvbGRIYW5kbGVzKQogICAgewogICAgICAgIG1lbWNweShUaGlzLT5IYW5kbGVzLCBvbGRIYW5kbGVzLCAoVGhpcy0+bnVtSGFuZGxlcyAtIDEpICogc2l6ZW9mKHN0cnVjdCBIYW5kbGVFbnRyeSkpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEhhbmRsZXMpOwogICAgfQoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJWRcbiIsIFRoaXMtPm51bUhhbmRsZXMpOwogICAgcmV0dXJuIFRoaXMtPm51bUhhbmRsZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0REZXZpY2VJbXBsX1VwZGF0ZURlcHRoU3RlbmNpbAogKgogKiBDaGVja3MgdGhlIGN1cnJlbnQgcmVuZGVyIHRhcmdldCBmb3IgYXR0YWNoZWQgZGVwdGggc3RlbmNpbHMgYW5kIHNldHMgdGhlCiAqIFdpbmVEM0QgZGVwdGggc3RlbmNpbCBhY2NvcmRpbmdseS4KICoKICogUmV0dXJuczoKICogIFRoZSBkZXB0aCBzdGVuY2lsIHN0YXRlIHRvIHNldCBpZiBjcmVhdGluZyB0aGUgZGV2aWNlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KV0lORUQzRFpCVUZGRVJUWVBFCklEaXJlY3QzRERldmljZUltcGxfVXBkYXRlRGVwdGhTdGVuY2lsKElEaXJlY3QzRERldmljZUltcGwgKlRoaXMpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRlcHRoU3RlbmNpbCA9IE5VTEw7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpkc2k7CiAgICBzdGF0aWMgRERTQ0FQUzIgZGVwdGhjYXBzID0geyBERFNDQVBTX1pCVUZGRVIsIDAsIDAsIDAgfTsKCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLT50YXJnZXQsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlcHRoY2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXB0aFN0ZW5jaWwpOwogICAgaWYoIWRlcHRoU3RlbmNpbCkKICAgIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyB3aW5lZDNkIGRlcHRoIHN0ZW5jaWwgdG8gTlVMTFxuIik7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RaQl9GQUxTRTsKICAgIH0KCiAgICBkc2kgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBkZXB0aFN0ZW5jaWwpOwogICAgVFJBQ0UoIlNldHRpbmcgd2luZWQzZCBkZXB0aCBzdGVuY2lsIHRvICVwICh3aW5lZDNkICVwKVxuIiwgZHNpLCBkc2ktPldpbmVEM0RTdXJmYWNlKTsKICAgIElXaW5lRDNERGV2aWNlX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHNpLT5XaW5lRDNEU3VyZmFjZSk7CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGRlcHRoU3RlbmNpbCk7CiAgICByZXR1cm4gV0lORUQzRFpCX1RSVUU7Cn0K