LyoKICogRERFTUwgbGlicmFyeQogKgogKiBDb3B5cmlnaHQgMTk5NyBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTcgTGVuIFdoaXRlCiAqIENvcHlyaWdodCAxOTk5IEtlaXRoIE1hdHRoZXdzCiAqLwoKLyogT25seSBlbXB0eSBzdHVicyBmb3Igbm93ICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgImRkZW1sLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAidGNoYXIuaCIKI2luY2x1ZGUgIndpbm50LmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoZGRlbWwpCgovKiBIYXMgZGVmaW5lZCBpbiBhdG9tLmMgZmlsZS4KICovCiNkZWZpbmUgTUFYX0FUT01fTEVOICAgICAgICAgICAgICAyNTUKCi8qIE1heGltdW0gYnVmZmVyIHNpemUgKCBpbmNsdWRpbmcgdGhlICdcMCcgKS4KICovCiNkZWZpbmUgTUFYX0JVRkZFUl9MRU4gICAgICAgICAgICAoTUFYX0FUT01fTEVOICsgMSkKCi8qICB0eXBlZGVmIHN0cnVjdCB7CglEV09SRAkJbkxlbmd0aDsKCUxQVk9JRAkJbHBTZWN1cml0eURlc2NyaXB0b3I7CglCT09MCQliSW5oZXJpdEhhbmRsZTsKfQlTRUNVUklUWV9BVFRSSUJVVEVTOyAqLwoKLyogVGhpcyBpcyBhIHNpbXBsZSBsaXN0IHRvIGtlZXAgdHJhY2sgb2YgdGhlIHN0cmluZ3MgY3JlYXRlZAogKiBieSBEZGVDcmVhdGVTdHJpbmdIYW5kbGUuICBUaGUgbGlzdCBpcyB1c2VkIHRvIGZyZWUKICogdGhlIHN0cmluZ3Mgd2hlbmV2ZXIgRGRlVW5pbml0aWFsaXplIGlzIGNhbGxlZC4KICogVGhpcyBtZWNoYW5pc20gaXMgbm90IGNvbXBsZXRlIGFuZCBkb2VzIG5vdCBoYW5kbGUgbXVsdGlwbGUgaW5zdGFuY2VzLgogKiBNb3N0IG9mIHRoZSBEREUgQVBJIHVzZSBhIERXT1JEIHBhcmFtZXRlciBpbmRpY2F0aW5nIHdoaWNoIGluc3RhbmNlCiAqIG9mIGEgZ2l2ZW4gcHJvZ3JhbSBpcyBjYWxsaW5nIHRoZW0uICBUaGUgQVBJIGFyZSBzdXBwb3NlZCB0bwogKiBhc3NvY2lhdGUgdGhlIGRhdGEgdG8gdGhlIGluc3RhbmNlIHRoYXQgY3JlYXRlZCBpdC4KICovCnR5cGVkZWYgc3RydWN0IHRhZ0hTWk5vZGUgSFNaTm9kZTsKc3RydWN0IHRhZ0hTWk5vZGUKewogICAgSFNaTm9kZSogbmV4dDsKICAgIEhTWiBoc3o7Cn07CgoKdHlwZWRlZiBzdHJ1Y3QgdGFnU2VydmljZU5vZGUgU2VydmljZU5vZGU7CnN0cnVjdCB0YWdTZXJ2aWNlTm9kZQp7CiAgICBTZXJ2aWNlTm9kZSogbmV4dDsKICAgIEhTWiBoc3o7CiAgICBCT09MMTYJCUZpbHRlck9uOwp9Owp0eXBlZGVmIHN0cnVjdCBEREVfSEFORExFX0VOVFJZIHsKICAgIEJPT0wxNiAgICAgICAgICAgICAgTW9uaXRvcjsgICAgICAgIC8qIGhhdmUgdGhlc2UgdHdvIGFzIGZ1bGwgQm9vbGVhbnMgY29zIHRoZXknbGwgYmUgdGVzdGVkIGZyZXF1ZW50bHkgKi8KICAgIEJPT0wxNiAgICAgICAgICAgICAgQ2xpZW50X29ubHk7ICAgIC8qIGJpdCB3YXN0ZWZ1bCBvZiBzcGFjZSBidXQgaXQgd2lsbCBiZSBmYXN0ZXIgKi8KICAgIEJPT0wxNiAgICAgICAgICAgICAgVW5pY29kZTsgICAgICAgIC8qIEZsYWcgdG8gaW5kaWNhdGUgV2luMzIgQVBJIHVzZWQgdG8gaW5pdGlhbGlzZSAqLwogICAgQk9PTDE2ICAgICAgICAgICAgICBXaW4xNjsgICAgICAgICAgLyogZmxhZyB0byBpbmRpY2F0ZSBXaW4xNiBBUEkgdXNlZCB0byBpbml0aWFsaXplICovCiAgICBEV09SRCAgICAgICAgICAgICAgIEluc3RhbmNlX2lkOyAgLyogbmVlZGVkIHRvIHRyYWNrIG1vbml0b3IgdXNhZ2UgKi8KICAgIHN0cnVjdCBEREVfSEFORExFX0VOVFJZICAgICpOZXh0X0VudHJ5OwogICAgSFNaTm9kZQkqTm9kZV9saXN0OwogICAgUEZOQ0FMTEJBQ0sgICAgICAgICBDYWxsQmFjazsKICAgIERXT1JEICAgICAgICAgICAgICAgQ0JGX0ZsYWdzOwogICAgRFdPUkQgICAgICAgICAgICAgICBNb25pdG9yX2ZsYWdzOwogICAgVUlOVCAgICAgICAgICAgICAgVHhuX2NvdW50OyAgICAgIC8qIGNvdW50IHRyYW5zYWN0aW9ucyBvcGVuIHRvIHNpbXBsaWZ5IGNsb3N1cmUgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgTGFzdF9FcnJvcjsgCiAgICBTZXJ2aWNlTm9kZSoJCVNlcnZpY2VOYW1lczsKfSBEREVfSEFORExFX0VOVFJZOwoKc3RhdGljIERERV9IQU5ETEVfRU5UUlkJKkRERV9IYW5kbGVfVGFibGVfQmFzZSA9IE5VTEw7CnN0YXRpYyBEV09SRCAJCURERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPSAwOyAgLyogT0sgZm9yIHByZXNlbnQsIG1heSBoYXZlIHRvIHdvcnJ5IGFib3V0IHdyYXAtYXJvdW5kIGxhdGVyICovCnN0YXRpYyBjb25zdCBjaGFyCSpEREVJbnN0YW5jZUFjY2VzcyA9ICJEREVNYXhJbnN0YW5jZSI7CnN0YXRpYyBjb25zdCBjaGFyCSpEREVIYW5kbGVBY2Nlc3MgPSAiRERFSGFuZGxlQWNjZXNzIjsKc3RhdGljIEhBTkRMRQkJaW5zdF9jb3VudF9tdXRleCA9IDA7CnN0YXRpYyBIQU5ETEUJCWhhbmRsZV9tdXRleCA9IDA7CgojZGVmaW5lIFRSVUUJMQojZGVmaW5lIEZBTFNFCTAKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgUmVtb3ZlSFNaTm9kZXMgICAgKElOVEVSTkFMKQogKgogKiBSZW1vdmUgYSBub2RlIGZyb20gdGhlIGxpc3Qgb2YgSFNaIG5vZGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIERlYyAxOTk4ICBDb3JlbC9NYWNhZGFtaWFuICAgIEluaXRpYWwgdmVyc2lvbgogKiAgMS4xICAgICAgTWFyIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgbXVsdGlwbGUgaW5zdGFuY2UgaGFuZGxpbmcKICoKICovCnN0YXRpYyB2b2lkIFJlbW92ZUhTWk5vZGUoIEhTWiBoc3osIERERV9IQU5ETEVfRU5UUlkgKiByZWZlcmVuY2VfaW5zdCApCnsKICAgIEhTWk5vZGUqIHBQcmV2ID0gTlVMTDsKICAgIEhTWk5vZGUqIHBDdXJyZW50ID0gTlVMTDsKCiAgICAvKiBTZXQgdGhlIGN1cnJlbnQgbm9kZSBhdCB0aGUgc3RhcnQgb2YgdGhlIGxpc3QuCiAgICAgKi8KICAgIHBDdXJyZW50ID0gcmVmZXJlbmNlX2luc3QtPk5vZGVfbGlzdDsKICAgIC8qIFdoaWxlIHdlIGhhdmUgbW9yZSBub2Rlcy4KICAgICAqLwogICAgd2hpbGUoIHBDdXJyZW50ICE9IE5VTEwgKQogICAgewogICAgICAgIC8qIElmIHdlIGZvdW5kIHRoZSBub2RlIHdlIHdlcmUgbG9va2luZyBmb3IuCiAgICAgICAgICovCiAgICAgICAgaWYoIHBDdXJyZW50LT5oc3ogPT0gaHN6ICkKICAgICAgICB7CiAgICAgICAgICAgIC8qIFJlbW92ZSB0aGUgbm9kZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8qIElmIHRoZSBmaXJzdCBub2RlIGluIHRoZSBsaXN0IGlzIHRvIHRvIGJlIHJlbW92ZWQuCiAgICAgICAgICAgICAqIFNldCB0aGUgZ2xvYmFsIGxpc3QgcG9pbnRlciB0byB0aGUgbmV4dCBub2RlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoIHBDdXJyZW50ID09IHJlZmVyZW5jZV9pbnN0LT5Ob2RlX2xpc3QgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZWZlcmVuY2VfaW5zdC0+Tm9kZV9saXN0ID0gcEN1cnJlbnQtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogSnVzdCBmaXggdGhlIHBvaW50ZXJzIGhhcyB0byBza2lwIHRoZSBjdXJyZW50CiAgICAgICAgICAgICAqIG5vZGUgc28gd2UgY2FuIGRlbGV0ZSBpdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcFByZXYtPm5leHQgPSBwQ3VycmVudC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBEZXN0cm95IHRoaXMgbm9kZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZyZWUoIHBDdXJyZW50ICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvKiBTYXZlIHRoZSBwcmV2aW91cyBub2RlIHBvaW50ZXIuCiAgICAgICAgICovCiAgICAgICAgcFByZXYgPSBwQ3VycmVudDsKICAgICAgICAvKiBNb3ZlIG9uIHRvIHRoZSBuZXh0IG5vZGUuCiAgICAgICAgICovCiAgICAgICAgcEN1cnJlbnQgPSBwQ3VycmVudC0+bmV4dDsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIEZyZWVBbmRSZW1vdmVIU1pOb2RlcyAgICAoSU5URVJOQUwpCiAqCiAqIEZyZWVzIHVwIGFsbCB0aGUgc3RyaW5ncyBzdGlsbCBhbGxvY2F0ZWQgaW4gdGhlIGxpc3QgYW5kCiAqIHJlbW92ZSBhbGwgdGhlIG5vZGVzIGZyb20gdGhlIGxpc3Qgb2YgSFNaIG5vZGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIERlYyAxOTk4ICBDb3JlbC9NYWNhZGFtaWFuICAgIEluaXRpYWwgdmVyc2lvbgogKiAgMS4xICAgICAgTWFyIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgbXVsdGlwbGUgaW5zdGFuY2UgaGFuZGxpbmcKICoKICovCnN0YXRpYyB2b2lkIEZyZWVBbmRSZW1vdmVIU1pOb2RlcyggRFdPUkQgaWRJbnN0LCBEREVfSEFORExFX0VOVFJZICogcmVmZXJlbmNlX2luc3QgKQp7CiAgICAvKiBGcmVlIGFueSBzdHJpbmdzIGNyZWF0ZWQgaW4gdGhpcyBpbnN0YW5jZS4KICAgICAqLwogICAgd2hpbGUoIHJlZmVyZW5jZV9pbnN0LT5Ob2RlX2xpc3QgIT0gTlVMTCApCiAgICB7CiAgICAgICAgRGRlRnJlZVN0cmluZ0hhbmRsZSggaWRJbnN0LCByZWZlcmVuY2VfaW5zdC0+Tm9kZV9saXN0LT5oc3ogKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIEluc2VydEhTWk5vZGUgICAgKElOVEVSTkFMKQogKgogKiBJbnNlcnQgYSBub2RlIHRvIHRoZSBoZWFkIG9mIHRoZSBsaXN0LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIERlYyAxOTk4ICBDb3JlbC9NYWNhZGFtaWFuICAgIEluaXRpYWwgdmVyc2lvbgogKiAgMS4xCSAgICAgTWFyIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgaW5zdGFuY2UgaGFuZGxpbmcKICogIDEuMgkgICAgIEp1biAxOTk5ICBLZWl0aCBNYXR0aGV3cwkgICBBZGRlZCBVc2FnZSBjb3VudCBoYW5kbGluZwogKgogKi8Kc3RhdGljIHZvaWQgSW5zZXJ0SFNaTm9kZSggSFNaIGhzeiwgRERFX0hBTkRMRV9FTlRSWSAqIHJlZmVyZW5jZV9pbnN0ICkKewogICAgaWYoIGhzeiAhPSAwICkKICAgIHsKICAgICAgICBIU1pOb2RlKiBwTmV3ID0gTlVMTDsKICAgICAgICAvKiBDcmVhdGUgYSBuZXcgbm9kZSBmb3IgdGhpcyBIU1ouCiAgICAgICAgICovCiAgICAgICAgcE5ldyA9IChIU1pOb2RlKikgbWFsbG9jKCBzaXplb2YoIEhTWk5vZGUgKSApOwogICAgICAgIGlmKCBwTmV3ICE9IE5VTEwgKQogICAgICAgIHsKICAgICAgICAgICAgLyogU2V0IHRoZSBoYW5kbGUgdmFsdWUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwTmV3LT5oc3ogPSBoc3o7CiAgICAgICAgICAgIC8qIEF0dGFjaCB0aGUgbm9kZSB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdC4gaS5lIG1vc3QgcmVjZW50bHkgYWRkZWQgaXMgZmlyc3QKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBOZXctPm5leHQgPSByZWZlcmVuY2VfaW5zdC0+Tm9kZV9saXN0OwoKICAgICAgICAgICAgLyogVGhlIG5ldyBub2RlIGlzIG5vdyBhdCB0aGUgaGVhZCBvZiB0aGUgbGlzdAogICAgICAgICAgICAgKiBzbyBzZXQgdGhlIGdsb2JhbCBsaXN0IHBvaW50ZXIgdG8gaXQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZWZlcmVuY2VfaW5zdC0+Tm9kZV9saXN0ID0gcE5ldzsKCSAgICBUUkFDRSgiSFNaIG5vZGUgbGlzdCBlbnRyeSBhZGRlZFxuIik7CiAgICAgICAgfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRmluZF9JbnN0YW5jZV9FbnRyeQogKgogKglnZW5lcmljIHJvdXRpbmUgdG8gcmV0dXJuIGEgcG9pbnRlciB0byB0aGUgcmVsZXZhbnQgRERFX0hBTkRMRV9FTlRSWQogKglmb3IgYW4gaW5zdGFuY2UgSWQsIG9yIE5VTEwgaWYgdGhlIGVudHJ5IGRvZXMgbm90IGV4aXN0CiAqCiAqCUFTU1VNRVMgdGhlIG11dGV4IHByb3RlY3RpbmcgdGhlIGhhbmRsZSBlbnRyeSBsaXN0IGlzIHJlc2VydmVkIGJlZm9yZSBjYWxsaW5nCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yCQkgICAgICAgIENvbW1lbnQKICoKICogIDEuMCAgICAgIE1hcmNoIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgMXN0IGltcGxlbWVudGF0aW9uCiAgICAgICAgICAgICAqLwogRERFX0hBTkRMRV9FTlRSWSAqRmluZF9JbnN0YW5jZV9FbnRyeSAoRFdPUkQgSW5zdElkKQp7CglEREVfSEFORExFX0VOVFJZICogcmVmZXJlbmNlX2luc3Q7CglyZWZlcmVuY2VfaW5zdCA9ICBEREVfSGFuZGxlX1RhYmxlX0Jhc2U7Cgl3aGlsZSAoIHJlZmVyZW5jZV9pbnN0ICE9IE5VTEwgKQoJewoJCWlmICggcmVmZXJlbmNlX2luc3QtPkluc3RhbmNlX2lkID09IEluc3RJZCApCgkJewoJCQlUUkFDRSgiSW5zdGFuY2UgZW50cnkgZm91bmRcbiIpOwoJCQlyZXR1cm4gcmVmZXJlbmNlX2luc3Q7CiAgICAgICAgfQoJCXJlZmVyZW5jZV9pbnN0ID0gcmVmZXJlbmNlX2luc3QtPk5leHRfRW50cnk7CiAgICB9CglUUkFDRSgiSW5zdGFuY2UgZW50cnkgbWlzc2luZ1xuIik7CglyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCUZpbmRfU2VydmljZV9OYW1lCiAqCiAqCWdlbmVyaWMgcm91dGluZSB0byByZXR1cm4gYSBwb2ludGVyIHRvIHRoZSByZWxldmFudCBTZXJ2aWNlTm9kZQogKglmb3IgYSBnaXZlbiBzZXJ2aWNlIG5hbWUsIG9yIE5VTEwgaWYgdGhlIGVudHJ5IGRvZXMgbm90IGV4aXN0CiAqCiAqCUFTU1VNRVMgdGhlIG11dGV4IHByb3RlY3RpbmcgdGhlIGhhbmRsZSBlbnRyeSBsaXN0IGlzIHJlc2VydmVkIGJlZm9yZSBjYWxsaW5nCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yCQkgICAgICAgIENvbW1lbnQKICoKICogIDEuMCAgICAgIE1heSAxOTk5ICBLZWl0aCBNYXR0aGV3cyAgICAgIDFzdCBpbXBsZW1lbnRhdGlvbgogICAgICAgICAgICAgKi8KIFNlcnZpY2VOb2RlICpGaW5kX1NlcnZpY2VfTmFtZSAoSFNaIFNlcnZpY2VfTmFtZSwgRERFX0hBTkRMRV9FTlRSWSogdGhpc19pbnN0YW5jZSkKewoJU2VydmljZU5vZGUgKiByZWZlcmVuY2VfbmFtZT0gIHRoaXNfaW5zdGFuY2UtPlNlcnZpY2VOYW1lczsKCXdoaWxlICggcmVmZXJlbmNlX25hbWUgIT0gTlVMTCApCgl7CgkJaWYgKCByZWZlcmVuY2VfbmFtZS0+aHN6ID09IFNlcnZpY2VfTmFtZSApCgkJewoJCQlUUkFDRSgiU2VydmljZSBOYW1lIGZvdW5kXG4iKTsKCQkJcmV0dXJuIHJlZmVyZW5jZV9uYW1lOwogICAgICAgIH0KCQlyZWZlcmVuY2VfbmFtZSA9IHJlZmVyZW5jZV9uYW1lLT5uZXh0OwogICAgfQoJVFJBQ0UoIlNlcnZpY2UgbmFtZSBtaXNzaW5nXG4iKTsKCXJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglSZWxlYXNlX3Jlc2VydmVkX211dGV4CiAqCiAqCWdlbmVyaWMgcm91dGluZSB0byByZWxlYXNlIGEgcmVzZXJ2ZWQgbXV0ZXgKICoKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKglDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAJQXV0aG9yICAgICAgICAgCQlDb21tZW50CiAqCiAqICAxLjAgICAgICBKYW4gMTk5OSAgS2VpdGggTWF0dGhld3MgICAgICAgIEluaXRpYWwgdmVyc2lvbgogKiAgMS4xCSAgICAgTWFyIDE5OTkgIEtlaXRoIE1hdHRoZXdzCSAgICAgQ29ycmVjdGVkIEhlYXAgaGFuZGxpbmcuIENvcnJlY3RlZCByZS1pbml0aWFsaXNhdGlvbiBoYW5kbGluZwogKiAgMS4yCSAgICAgQXVnIDE5OTkgIEr8cmdlbiBTY2htaWVkCSAgICAgQ29ycmVjdGVkIGVycm9yIGhhbmRsaW5nCiAqCiAqLwpzdGF0aWMgRFdPUkQgUmVsZWFzZV9yZXNlcnZlZF9tdXRleCAoSEFORExFIG11dGV4LCBMUFNUUiBtdXRleF9uYW1lLCBCT09MIHJlbGVhc2VfaGFuZGxlX20sIEJPT0wgcmVsZWFzZV90aGlzX2kgLCAKICAgIERERV9IQU5ETEVfRU5UUlkgKnRoaXNfaW5zdGFuY2UpCnsKCWlmICghUmVsZWFzZU11dGV4KG11dGV4KSkKICAgICAgICB7CgkJRVJSKCJSZWxlYXNlTXV0ZXggZmFpbGVkIC0gJXMgbXV0ZXggJWxpXG4iLG11dGV4X25hbWUsR2V0TGFzdEVycm9yKCkpOwoJCUhlYXBGcmVlKFN5c3RlbUhlYXAsIDAsIHRoaXNfaW5zdGFuY2UpOwoJCWlmICggcmVsZWFzZV9oYW5kbGVfbSApCgkJewoJCQlSZWxlYXNlTXV0ZXgoaGFuZGxlX211dGV4KTsKCQl9CiAgICAgICAgICAgICAgICByZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKICAgICAgICAgfQoJaWYgKCByZWxlYXNlX3RoaXNfaSApCgl7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShTeXN0ZW1IZWFwLCAwLCB0aGlzX2luc3RhbmNlKTsKCX0KCXJldHVybiBETUxFUlJfTk9fRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJV2FpdEZvck11dGV4CiAqCiAqCWdlbmVyaWMgcm91dGluZSB0byB3YWl0IGZvciB0aGUgbXV0ZXgKICoKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKglDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAJQXV0aG9yICAgICAgICAgCQlDb21tZW50CiAqCiAqICAxLjAgICAgICBBdWcgMTk5OSAgSnVlcmdlbiBTY2htaWVkICAgICAgIEluaXRpYWwgdmVyc2lvbgogKgogKi8Kc3RhdGljIEJPT0wgV2FpdEZvck11dGV4IChIQU5ETEUgbXV0ZXgpCnsKCURXT1JEIHJlc3VsdDsKCglyZXN1bHQgPSBXYWl0Rm9yU2luZ2xlT2JqZWN0KG11dGV4LDEwMDApOwoKCS8qIGJvdGggZXJyb3JzIHNob3VsZCBuZXZlciBvY2N1ciAqLwoJaWYgKFdBSVRfVElNRU9VVCA9PSByZXN1bHQpCgl7CgkJRVJSKCJXYWl0Rm9yU2luZ2xlT2JqZWN0IHRpbWVkIG91dFxuIik7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWlmIChXQUlUX0ZBSUxFRCA9PSByZXN1bHQpCgl7CgkJRVJSKCJXYWl0Rm9yU2luZ2xlT2JqZWN0IGZhaWxlZCAtIGVycm9yICVsaVxuIiwgR2V0TGFzdEVycm9yKCkpOwoJCXJldHVybiBGQUxTRTsKCX0KCXJldHVybiBUUlVFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUluY3JlbWVudEluc3RhbmNlSWQKICoKICoJZ2VuZXJpYyByb3V0aW5lIHRvIGluY3JlbWVudCB0aGUgbWF4IGluc3RhbmNlIElkIGFuZCBhbGxvY2F0ZSBhIG5ldyBhcHBsaWNhdGlvbiBpbnN0YW5jZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIEphbiAxOTk5ICBLZWl0aCBNYXR0aGV3cyAgICAgICAgSW5pdGlhbCB2ZXJzaW9uCiAqCiAqLwpEV09SRCBJbmNyZW1lbnRJbnN0YW5jZUlkKCBEREVfSEFORExFX0VOVFJZICp0aGlzX2luc3RhbmNlKQp7CglTRUNVUklUWV9BVFRSSUJVVEVTIHNfYXR0cmliOwoKCS8qICBOZWVkIHRvIHNldCB1cCBNdXRleCBpbiBjYXNlIGl0IGlzIG5vdCBhbHJlYWR5IHByZXNlbnQgKi8KCS8qIGluY3JlbWVudCBoYW5kbGUgY291bnQgJiBnZXQgdmFsdWUgKi8KCWlmICggIWluc3RfY291bnRfbXV0ZXggKQoJewoJCXNfYXR0cmliLmJJbmhlcml0SGFuZGxlID0gVFJVRTsKCQlzX2F0dHJpYi5scFNlY3VyaXR5RGVzY3JpcHRvciA9IE5VTEw7CgkJc19hdHRyaWIubkxlbmd0aCA9IHNpemVvZihzX2F0dHJpYik7CgkJaW5zdF9jb3VudF9tdXRleCA9IENyZWF0ZU11dGV4QSgmc19hdHRyaWIsMSxEREVJbnN0YW5jZUFjY2Vzcyk7IC8qIDFzdCB0aW1lIHRocm91Z2ggKi8KCQlpbnN0X2NvdW50X211dGV4ID0gQ29udmVydFRvR2xvYmFsSGFuZGxlKGluc3RfY291bnRfbXV0ZXgpOyAvKiBmaXhtZSB3aGVuIGhhdmluZyBzZXBlcmF0ZSBhZHJlc3NwYWNlcyovCgl9IGVsc2UgewogICAgICAgIAlpZiAoICFXYWl0Rm9yTXV0ZXgoaW5zdF9jb3VudF9tdXRleCkgKQogICAgICAgIAl7CiAgICAgICAgICAgICAgICAJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7CiAgICAgICAgCX0KCX0KCWlmICggIWluc3RfY291bnRfbXV0ZXggKQoJewoJCUVSUigiQ3JlYXRlTXV0ZXggZmFpbGVkIC0gaW5zdF9jb3VudCAlbGlcbiIsR2V0TGFzdEVycm9yKCkpOwoJCVJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXggKGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSk7CgkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7Cgl9CglEREVfTWF4X0Fzc2lnbmVkX0luc3RhbmNlKys7Cgl0aGlzX2luc3RhbmNlLT5JbnN0YW5jZV9pZCA9IERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2U7CiAgICAgICAgVFJBQ0UoIk5ldyBpbnN0YW5jZSBpZCAlbGQgYWxsb2NhdGVkXG4iLERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UpOwoJaWYgKFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaW5zdF9jb3VudF9tdXRleCwiaW5zdGFuY2VfY291bnQiLDEsMCx0aGlzX2luc3RhbmNlKSkgcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7CglyZXR1cm4gRE1MRVJSX05PX0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlGaW5kTm90aWZ5TW9uaXRvckNhbGxiYWNrcwogKgogKglSb3V0aW5lIHRvIGZpbmQgaW5zdGFuY2VzIHRoYXQgbmVlZCB0byBiZSBub3RpZmllZCB2aWEgdGhlaXIgY2FsbGJhY2sKICoJb2Ygc29tZSBldmVudCB0aGV5IGFyZSBtb25pdG9yaW5nCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuCSAgICAgRGF0ZQlBdXRob3IJCQlDb21tZW50CiAqCiAqICAxLjAJICAgTWF5IDE5OTkgICAgS2VpdGggTWF0dGhld3MgICAgICAgSW5pdGlhbCBWZXJzaW9uCiAqCiAqLwoKdm9pZCBGaW5kTm90aWZ5TW9uaXRvckNhbGxiYWNrcyhEV09SRCBUaGlzSW5zdGFuY2UsIERXT1JEIERkZUV2ZW50ICkKewoJRERFX0hBTkRMRV9FTlRSWSAqSW5zdGFuY2VIYW5kbGU7CglJbnN0YW5jZUhhbmRsZSA9IERERV9IYW5kbGVfVGFibGVfQmFzZTsKCXdoaWxlICggSW5zdGFuY2VIYW5kbGUgIT0gTlVMTCApCgl7CgkJaWYgKCAgKEluc3RhbmNlSGFuZGxlLT5Nb25pdG9yICkgJiYgSW5zdGFuY2VIYW5kbGUtPkluc3RhbmNlX2lkID09IFRoaXNJbnN0YW5jZSApCgkJewoJCQkvKiAgIEZvdW5kIGFuIGluc3RhbmNlIHJlZ2lzdGVyZWQgYXMgbW9uaXRvciBhbmQgaXMgbm90IG91cnNlbHZlcwoJCQkgKgl1c2UgY2FsbGJhY2sgdG8gbm90aWZ5IHdoZXJlIGFwcHJvcHJpYXRlCgkJCSAqLwoJCX0KCQlJbnN0YW5jZUhhbmRsZSA9IEluc3RhbmNlSGFuZGxlLT5OZXh0X0VudHJ5OwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBEZGVSZXNlcnZlQXRvbQogKgogKiAgICAgIFJvdXRpbmUgdG8gbWFrZSBhbiBleHRyYSBBZGQgb24gYW4gYXRvbSB0byByZXNlcnZlIGl0IGEgYml0IGxvbmdlcgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgIEp1biAxOTk5ICAgIEtlaXRoIE1hdHRoZXdzICAgICAgIEluaXRpYWwgVmVyc2lvbgogKgogKi8KCnZvaWQgRGRlUmVzZXJ2ZUF0b20oIERERV9IQU5ETEVfRU5UUlkgKiByZWZlcmVuY2VfaW5zdCxIU1ogaHN6KQp7CiAgQ0hBUiBTTmFtZUJ1ZmZlcltNQVhfQlVGRkVSX0xFTl07CiAgVUlOVCByY29kZTsKICBpZiAoIHJlZmVyZW5jZV9pbnN0LT5Vbmljb2RlKQogIHsKICAgICAgICByY29kZT1HbG9iYWxHZXRBdG9tTmFtZVcoaHN6LChMUFdTVFIpJlNOYW1lQnVmZmVyLE1BWF9BVE9NX0xFTik7CiAgICAgICAgR2xvYmFsQWRkQXRvbVcoKExQV1NUUilTTmFtZUJ1ZmZlcik7CiAgfSBlbHNlIHsKICAgICAgICByY29kZT1HbG9iYWxHZXRBdG9tTmFtZUEoaHN6LFNOYW1lQnVmZmVyLE1BWF9BVE9NX0xFTik7CiAgICAgICAgR2xvYmFsQWRkQXRvbUEoU05hbWVCdWZmZXIpOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERkZVJlbGVhc2VBdG9tCiAqCiAqICAgICAgUm91dGluZSB0byBtYWtlIGEgZGVsZXRlIG9uIGFuIGF0b20gdG8gcmVsZWFzZSBpdCBhIGJpdCBzb29uZXIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgICAgIENoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgICAgIEF1dGhvciAgICAgICAgICAgICAgICAgIENvbW1lbnQKICoKICogIDEuMCAgICBKdW4gMTk5OSAgICBLZWl0aCBNYXR0aGV3cyAgICAgICBJbml0aWFsIFZlcnNpb24KICoKICovCgp2b2lkIERkZVJlbGVhc2VBdG9tKCBEREVfSEFORExFX0VOVFJZICogcmVmZXJlbmNlX2luc3QsSFNaIGhzeikKewogIENIQVIgU05hbWVCdWZmZXJbTUFYX0JVRkZFUl9MRU5dOwogIFVJTlQgcmNvZGU7CiAgaWYgKCByZWZlcmVuY2VfaW5zdC0+VW5pY29kZSkKICB7CiAgICAgICAgcmNvZGU9R2xvYmFsR2V0QXRvbU5hbWVXKGhzeiwoTFBXU1RSKSZTTmFtZUJ1ZmZlcixNQVhfQVRPTV9MRU4pOwogICAgICAgIEdsb2JhbEFkZEF0b21XKChMUFdTVFIpU05hbWVCdWZmZXIpOwogIH0gZWxzZSB7CiAgICAgICAgcmNvZGU9R2xvYmFsR2V0QXRvbU5hbWVBKGhzeixTTmFtZUJ1ZmZlcixNQVhfQVRPTV9MRU4pOwogICAgICAgIEdsb2JhbEFkZEF0b21BKFNOYW1lQnVmZmVyKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVJbml0aWFsaXplMTYgICAoRERFTUwuMikKICovClVJTlQxNiBXSU5BUEkgRGRlSW5pdGlhbGl6ZTE2KCBMUERXT1JEIHBpZEluc3QsIFBGTkNBTExCQUNLMTYgcGZuQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBhZkNtZCwgRFdPUkQgdWxSZXMpCnsKICAgIFRSQUNFKCJEZGVJbml0aWFsaXplMTYgY2FsbGVkIC0gY2FsbGluZyBEZGVJbml0aWFsaXplQVxuIik7CiAgICByZXR1cm4gKFVJTlQxNilEZGVJbml0aWFsaXplQShwaWRJbnN0LChQRk5DQUxMQkFDSylwZm5DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZDbWQsIHVsUmVzKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVJbml0aWFsaXplQSAgIChVU0VSMzIuMTA2KQogKi8KVUlOVCBXSU5BUEkgRGRlSW5pdGlhbGl6ZUEoIExQRFdPUkQgcGlkSW5zdCwgUEZOQ0FMTEJBQ0sgcGZuQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgYWZDbWQsIERXT1JEIHVsUmVzICkKewogICAgVFJBQ0UoIkRkZUluaXRpYWxpemVBIGNhbGxlZCAtIGNhbGxpbmcgRGRlSW5pdGlhbGl6ZVdcbiIpOwogICAgcmV0dXJuIERkZUluaXRpYWxpemVXKHBpZEluc3QscGZuQ2FsbGJhY2ssYWZDbWQsdWxSZXMpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVJbml0aWFsaXplVyBbVVNFUjMyLjEwN10KICogUmVnaXN0ZXJzIGFuIGFwcGxpY2F0aW9uIHdpdGggdGhlIERERU1MCiAqCiAqIFBBUkFNUwogKiAgICBwaWRJbnN0ICAgICBbSV0gUG9pbnRlciB0byBpbnN0YW5jZSBpZGVudGlmaWVyCiAqICAgIHBmbkNhbGxiYWNrIFtJXSBQb2ludGVyIHRvIGNhbGxiYWNrIGZ1bmN0aW9uCiAqICAgIGFmQ21kICAgICAgIFtJXSBTZXQgb2YgY29tbWFuZCBhbmQgZmlsdGVyIGZsYWdzCiAqICAgIHVsUmVzICAgICAgIFtJXSBSZXNlcnZlZAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERNTEVSUl9OT19FUlJPUgogKiAgICBGYWlsdXJlOiBETUxFUlJfRExMX1VTQUdFLCBETUxFUlJfSU5WQUxJRFBBUkFNRVRFUiwgRE1MRVJSX1NZU19FUlJPUgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIFByZSAxOTk4ICBBbGV4YW5kcmUvTGVuCSAgICAgSW5pdGlhbCBTdHViCiAqICAxLjEgICAgICBKYW4gMTk5OSAgS2VpdGggTWF0dGhld3MgICAgICAgIEluaXRpYWwgKG5lYXItKWNvbXBsZXRlIHZlcnNpb24KICogIDEuMgkgICAgIE1hciAxOTk5ICBLZWl0aCBNYXR0aGV3cwkgICAgIENvcnJlY3RlZCBIZWFwIGhhbmRsaW5nLCBDcmVhdGVNdXRleCBmYWlsdXJlIGhhbmRsaW5nCiAqCiAqLwpVSU5UIFdJTkFQSSBEZGVJbml0aWFsaXplVyggTFBEV09SRCBwaWRJbnN0LCBQRk5DQUxMQkFDSyBwZm5DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBhZkNtZCwgRFdPUkQgdWxSZXMgKQp7CgovKiAgcHJvYmFibHkgbm90IHJlYWxseSBjYXBhYmxlIG9mIGhhbmRsaW5nIG11dGxpcGxlIHByb2Nlc3NlcywgYnV0IHNob3VsZCBoYW5kbGUKICoJbXVsdGlwbGUgaW5zdGFuY2VzIHdpdGhpbiBvbmUgcHJvY2VzcyAqLwoKICAgIFNFQ1VSSVRZX0FUVFJJQlVURVMgKnNfYXR0PSBOVUxMOwogICAgU0VDVVJJVFlfQVRUUklCVVRFUyBzX2F0dHJpYjsKICAgIERXT1JEIAkgICAgIAllcnJfbm8gPSAwOwogICAgRERFX0hBTkRMRV9FTlRSWSAqdGhpc19pbnN0YW5jZTsKICAgIERERV9IQU5ETEVfRU5UUlkgKnJlZmVyZW5jZV9pbnN0OwogICAgc19hdHQgPSAmc19hdHRyaWI7CgogICAgaWYoIHVsUmVzICkKICAgIHsKICAgICAgICBFUlIoIlJlc2VydmVkIHZhbHVlIG5vdCB6ZXJvPyAgV2hhdCBkb2VzIHRoaXMgbWVhbj9cbiIpOwogICAgICAgIEZJWE1FKCIoJXAsJXAsMHglbHgsJWxkKTogc3R1YlxuIiwgcGlkSW5zdCwgcGZuQ2FsbGJhY2ssCgkgICAgICBhZkNtZCx1bFJlcyk7CiAgICAgICAgLyogdHJhcCB0aGlzIGFuZCBubyBtb3JlIHVudGlsIHdlIGtub3cgbW9yZSAqLwogICAgICAgIHJldHVybiBETUxFUlJfTk9fRVJST1I7CiAgICB9CiAgICBpZiAoIXBmbkNhbGxiYWNrICkgCiAgICB7CgkvKiAgdGhpcyBvbmUgbWF5IGJlIHdyb25nIC0gTVMgZGxsIHNlZW1zIHRvIGFjY2VwdCB0aGUgY29uZGl0aW9uLCAKCSAgICBsZWF2ZSB0aGlzIHVudGlsIHdlIGZpbmQgb3V0IG1vcmUgISEgKi8KCgogICAgICAgIC8qIGNhbid0IHNldCB1cCB0aGUgaW5zdGFuY2Ugd2l0aCBub3RoaW5nIHRvIGFjdCBhcyBhIGNhbGxiYWNrICovCiAgICAgICAgVFJBQ0UoIk5vIGNhbGxiYWNrIHByb3ZpZGVkXG4iKTsKICAgICAgICByZXR1cm4gRE1MRVJSX0lOVkFMSURQQVJBTUVURVI7IC8qIG1pZ2h0IGJlIERNTEVSUl9ETExfVVNBR0UgKi8KICAgICB9CgogICAgIC8qIGdyYWIgZW5vdWdoIGhlYXAgZm9yIG9uZSBjb250cm9sIHN0cnVjdCAtIG5vdCByZWFsbHkgbmVjZXNzYXJ5IGZvciByZS1pbml0aWFsaXNlCiAgICAgICoJYnV0IGFsbG93cyB1cyB0byB1c2Ugc2FtZSB2YWxpZGF0aW9uIHJvdXRpbmVzICovCiAgICAgdGhpc19pbnN0YW5jZT0gKERERV9IQU5ETEVfRU5UUlkqKUhlYXBBbGxvYyggU3lzdGVtSGVhcCwgMCwgc2l6ZW9mKERERV9IQU5ETEVfRU5UUlkpICk7CiAgICAgaWYgKCB0aGlzX2luc3RhbmNlID09IE5VTEwgKQogICAgIHsKCS8qIGNhdGFzdHJvcGhlICEhIHdhcm4gdXNlciAmIGFib3J0ICovCglFUlIoIkluc3RhbmNlIGNyZWF0ZSBmYWlsZWQgLSBvdXQgb2YgbWVtb3J5XG4iKTsKCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwogICAgIH0KICAgICB0aGlzX2luc3RhbmNlLT5OZXh0X0VudHJ5ID0gTlVMTDsKICAgICB0aGlzX2luc3RhbmNlLT5Nb25pdG9yPShhZkNtZHxBUFBDTEFTU19NT05JVE9SKTsKCiAgICAgLyogbWVzc3kgYml0LCBzcGVjIGltcGxpZXMgdGhhdCAnQ2xpZW50IE9ubHknIGNhbiBiZSBzZXQgaW4gMiBkaWZmZXJlbnQgd2F5cywgY2F0Y2ggMSBoZXJlICovCgogICAgIHRoaXNfaW5zdGFuY2UtPkNsaWVudF9vbmx5PWFmQ21kJkFQUENNRF9DTElFTlRPTkxZOwogICAgIHRoaXNfaW5zdGFuY2UtPkluc3RhbmNlX2lkID0gKnBpZEluc3Q7IC8qIE1heSBuZWVkIHRvIGFkZCBjYWxsaW5nIHByb2MgSWQgKi8KICAgICB0aGlzX2luc3RhbmNlLT5DYWxsQmFjaz0qcGZuQ2FsbGJhY2s7CiAgICAgdGhpc19pbnN0YW5jZS0+VHhuX2NvdW50PTA7CiAgICAgdGhpc19pbnN0YW5jZS0+VW5pY29kZSA9IFRSVUU7CiAgICAgdGhpc19pbnN0YW5jZS0+V2luMTYgPSBGQUxTRTsKICAgICB0aGlzX2luc3RhbmNlLT5Ob2RlX2xpc3QgPSBOVUxMOyAvKiBub2RlIHdpbGwgYmUgYWRkZWQgbGF0ZXIgKi8KICAgICB0aGlzX2luc3RhbmNlLT5Nb25pdG9yX2ZsYWdzID0gYWZDbWQgJiBNRl9NQVNLOwogICAgIHRoaXNfaW5zdGFuY2UtPlNlcnZpY2VOYW1lcyA9IE5VTEw7CgogICAgIC8qIGlzb2xhdGUgQ0JGIGZsYWdzIGluIG9uZSBnbywgZXhwZWN0IHRoaXMgd2lsbCBnbyB0aGUgd2F5IG9mIGFsbCBhdHRlbXB0cyB0byBiZSBjbGV2ZXIgISEgKi8KCiAgICAgdGhpc19pbnN0YW5jZS0+Q0JGX0ZsYWdzPWFmQ21kXigoYWZDbWQmTUZfTUFTSyl8KChhZkNtZCZBUFBDTURfTUFTSyl8KGFmQ21kJkFQUENMQVNTX01BU0spKSk7CgogICAgIGlmICggISB0aGlzX2luc3RhbmNlLT5DbGllbnRfb25seSApCiAgICAgewoKCS8qIENoZWNrIGZvciBvdGhlciB3YXkgb2Ygc2V0dGluZyBDbGllbnQtb25seSAhISAqLwoKCXRoaXNfaW5zdGFuY2UtPkNsaWVudF9vbmx5PSh0aGlzX2luc3RhbmNlLT5DQkZfRmxhZ3MmQ0JGX0ZBSUxfQUxMU1ZSWEFDVElPTlMpCgkJCT09Q0JGX0ZBSUxfQUxMU1ZSWEFDVElPTlM7CiAgICAgfQoKICAgICBUUkFDRSgiaW5zdGFuY2UgY3JlYXRlZCAtIGNoZWNraW5nIHZhbGlkaXR5IFxuIik7CgogICAgaWYoICpwaWRJbnN0ID09IDAgKSB7CiAgICAgICAgLyogIEluaXRpYWxpc2F0aW9uIG9mIG5ldyBJbnN0YW5jZSBJZGVudGlmaWVyICovCiAgICAgICAgVFJBQ0UoIm5ldyBpbnN0YW5jZSwgY2FsbGJhY2sgJXAgZmxhZ3MgJWxYXG4iLHBmbkNhbGxiYWNrLGFmQ21kKTsKICAgICAgICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCiAgICAgICAgewogICAgICAgICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhIGNhbiByZXR1cm4gVFJVRSBzaW5jZSBlZmZlY3QgaXMgdGhlIHNhbWUgKi8KCS8qICBOZWVkIHRvIHNldCB1cCBNdXRleCBpbiBjYXNlIGl0IGlzIG5vdCBhbHJlYWR5IHByZXNlbnQgKi8KCXNfYXR0LT5iSW5oZXJpdEhhbmRsZSA9IFRSVUU7CglzX2F0dC0+bHBTZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwoJc19hdHQtPm5MZW5ndGggPSBzaXplb2Yoc19hdHQpOwoJaGFuZGxlX211dGV4ID0gQ3JlYXRlTXV0ZXhBKHNfYXR0LDEsRERFSGFuZGxlQWNjZXNzKTsKCWhhbmRsZV9tdXRleCA9IENvbnZlcnRUb0dsb2JhbEhhbmRsZShoYW5kbGVfbXV0ZXgpOyAvKiBmaXhtZSB3aGVuIGhhdmluZyBzZXBlcmF0ZSBhZHJlc3NwYWNlcyovCglpZiAoICFoYW5kbGVfbXV0ZXggKSB7CgkJRVJSKCJDcmVhdGVNdXRleCBmYWlsZWQgLSBoYW5kbGUgbGlzdCAgJWxpXG4iLEdldExhc3RFcnJvcigpKTsKCQlIZWFwRnJlZShTeXN0ZW1IZWFwLCAwLCB0aGlzX2luc3RhbmNlKTsKCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKCX0KICAgIH0gZWxzZSB7CglpZiAoICFXYWl0Rm9yTXV0ZXgoaGFuZGxlX211dGV4KSApCgl7CgkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7Cgl9CiAgICB9CgoJVFJBQ0UoIkhhbmRsZSBNdXRleCBjcmVhdGVkL3Jlc2VydmVkXG4iKTsKICAgICAgICBpZiAoRERFX0hhbmRsZV9UYWJsZV9CYXNlID09IE5VTEwgKSAKCXsKICAgICAgICAgICAgICAgIC8qIGNhbid0IGJlIGFub3RoZXIgaW5zdGFuY2UgaW4gdGhpcyBjYXNlLCBhc3NpZ24gdG8gdGhlIGJhc2UgcG9pbnRlciAqLwogICAgICAgICAgICAgICAgRERFX0hhbmRsZV9UYWJsZV9CYXNlPSB0aGlzX2luc3RhbmNlOwoKCQkvKiBzaW5jZSBmaXJzdCBtdXN0IGZvcmNlIGZpbHRlciBvZiBYVFlQX0NPTk5FQ1QgYW5kIFhUWVBfV0lMRENPTk5FQ1QgZm9yCgkJICoJCXByZXNlbnQgCgkJICoJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgIE5PVEUgTk9URSBOT1RFICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkgCSAqCQkKCSAJICoJdGhlIG1hbnVhbCBpcyBub3QgY2xlYXIgaWYgdGhpcyBjb25kaXRpb24KCSAJICoJYXBwbGllcyB0byB0aGUgZmlyc3QgY2FsbCB0byBEZGVJbml0aWFsaXplIGZyb20gYW4gYXBwbGljYXRpb24sIG9yIHRoZSAKCSAJICoJZmlyc3QgY2FsbCBmb3IgYSBnaXZlbiBjYWxsYmFjayAhISEKCQkqLwoKCQl0aGlzX2luc3RhbmNlLT5DQkZfRmxhZ3M9dGhpc19pbnN0YW5jZS0+Q0JGX0ZsYWdzfEFQUENNRF9GSUxURVJJTklUUzsKIAkJVFJBQ0UoIkZpcnN0IGFwcGxpY2F0aW9uIGluc3RhbmNlIGRldGVjdGVkIE9LXG4iKTsKCQkvKglhbGxvY2F0ZSBuZXcgaW5zdGFuY2UgSUQgKi8KCQlpZiAoKGVycl9ubyA9IEluY3JlbWVudEluc3RhbmNlSWQoIHRoaXNfaW5zdGFuY2UpKSApIHJldHVybiBlcnJfbm87CgogICAJfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIHJlYWxseSBuZWVkIHRvIGNoYWluIHRoZSBuZXcgb25lIGluIHRvIHRoZSBsYXRlc3QgaGVyZSwgYnV0IGFmdGVyIGNoZWNraW5nIGNvbmRpdGlvbnMKICAgICAgICAgICAgICAgICAqCXN1Y2ggYXMgdHJ5aW5nIHRvIHN0YXJ0IGEgY29udmVyc2F0aW9uIGZyb20gYW4gYXBwbGljYXRpb24gdHJ5aW5nIHRvIG1vbml0b3IgKi8KICAgICAgICAgICAgICAgIHJlZmVyZW5jZV9pbnN0ID0gIERERV9IYW5kbGVfVGFibGVfQmFzZTsKCQlUUkFDRSgiU3Vic2VxdWVudCBhcHBsaWNhdGlvbiBpbnN0YW5jZSAtIHN0YXJ0aW5nIGNoZWNrc1xuIik7CiAgICAgICAgICAgICAgICB3aGlsZSAoIHJlZmVyZW5jZV9pbnN0LT5OZXh0X0VudHJ5ICE9IE5VTEwgKSAKCQl7CgkJCS8qCgkJCSoJVGhpcyBzZXQgb2YgdGVzdHMgd2lsbCB3b3JrIGlmIGFwcGxpY2F0aW9uIHVzZXMgc2FtZSBpbnN0YW5jZSBJZAoJCQkqCWF0IGFwcGxpY2F0aW9uIGxldmVsIG9uY2UgYWxsb2NhdGVkIC0gd2hpY2ggaXMgd2hhdCBtYW51YWwgaW1wbGllcwoJCQkqCXNob3VsZCBoYXBwZW4uIElmIHNvbWVvbmUgdHJpZXMgdG8gYmUgCgkJCSoJY2xldmVyIChsYXp5ID8pIGl0IHdpbGwgZmFpbCB0byBwaWNrIHVwIHRoYXQgbGF0ZXIgY2FsbHMgYXJlIGZvcgoJCQkqCXRoZSBzYW1lIGFwcGxpY2F0aW9uIC0gc2hvdWxkIHdlIHRydXN0IHRoZW0gPwoJCQkqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXNfaW5zdGFuY2UtPkluc3RhbmNlX2lkID09IHJlZmVyZW5jZV9pbnN0LT5JbnN0YW5jZV9pZCkgCgkJCXsKCQkJCS8qIENoZWNrIDEgLSBtdXN0IGJlIHNhbWUgQ2xpZW50LW9ubHkgc3RhdGUgKi8KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB0aGlzX2luc3RhbmNlLT5DbGllbnRfb25seSAhPSByZWZlcmVuY2VfaW5zdC0+Q2xpZW50X29ubHkpCgkJCQl7CgkJCQkJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSkpCgkJCQkJCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERNTEVSUl9ETExfVVNBR0U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKCQkJCS8qIENoZWNrIDIgLSBjYW5ub3QgdXNlICdNb25pdG9yJyB3aXRoIGFueSBub24tbW9uaXRvciBtb2RlcyAqLwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXNfaW5zdGFuY2UtPk1vbml0b3IgIT0gcmVmZXJlbmNlX2luc3QtPk1vbml0b3IpIAoJCQkJewoJCQkJCWlmICggUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsMCwxLHRoaXNfaW5zdGFuY2UpKQoJCQkJCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBETUxFUlJfSU5WQUxJRFBBUkFNRVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgoJCQkJLyogQ2hlY2sgMyAtIG11c3Qgc3VwcGx5IGRpZmZlcmVudCBjYWxsYmFjayBhZGRyZXNzICovCgoJCQkJaWYgKCB0aGlzX2luc3RhbmNlLT5DYWxsQmFjayA9PSByZWZlcmVuY2VfaW5zdC0+Q2FsbEJhY2spCgkJCQl7CgkJCQkJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSkpCgkJCQkJCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERNTEVSUl9ETExfVVNBR0U7CgkJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlX2luc3QgPSByZWZlcmVuY2VfaW5zdC0+TmV4dF9FbnRyeTsKICAgICAgICAgICAgICAgIH0KCQkvKiAgQWxsIGNsZWFyZWQsIGFkZCB0byBjaGFpbiAqLwoKCQlUUkFDRSgiQXBwbGljYXRpb24gSW5zdGFuY2UgY2hlY2tzIGZpbmlzaGVkXG4iKTsKCQlpZiAoKGVycl9ubyA9IEluY3JlbWVudEluc3RhbmNlSWQoIHRoaXNfaW5zdGFuY2UpKSApIHJldHVybiBlcnJfbm87CgkJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDAsdGhpc19pbnN0YW5jZSkpIHJldHVybiBETUxFUlJfU1lTX0VSUk9SOwoJCXJlZmVyZW5jZV9pbnN0LT5OZXh0X0VudHJ5ID0gdGhpc19pbnN0YW5jZTsKICAgICAgICB9CgkqcGlkSW5zdCA9IHRoaXNfaW5zdGFuY2UtPkluc3RhbmNlX2lkOwoJVFJBQ0UoIk5ldyBhcHBsaWNhdGlvbiBpbnN0YW5jZSBwcm9jZXNzaW5nIGZpbmlzaGVkIE9LXG4iKTsKICAgICB9IGVsc2UgewogICAgICAgIC8qIFJlaW5pdGlhbGlzYXRpb24gc2l0dWF0aW9uICAgLS0tIEZJWCAgKi8KICAgICAgICBUUkFDRSgicmVpbml0aWFsaXNhdGlvbiBvZiAoJXAsJXAsMHglbHgsJWxkKTogc3R1YlxuIixwaWRJbnN0LHBmbkNhbGxiYWNrLGFmQ21kLHVsUmVzKTsKCglpZiAoICFXYWl0Rm9yTXV0ZXgoaGFuZGxlX211dGV4KSAgKQoJewoJCUhlYXBGcmVlKFN5c3RlbUhlYXAsIDAsIHRoaXNfaW5zdGFuY2UpOwoJCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgaWYgKERERV9IYW5kbGVfVGFibGVfQmFzZSA9PSBOVUxMICkgCgl7CgkJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSkpIHJldHVybiBETUxFUlJfU1lTX0VSUk9SOwogICAgICAgIAlyZXR1cm4gRE1MRVJSX0RMTF9VU0FHRTsKIAl9CiAgICAgICAgSGVhcEZyZWUoU3lzdGVtSGVhcCwgMCwgdGhpc19pbnN0YW5jZSk7IC8qIGZpbmlzaGVkIC0gcmVsZWFzZSBoZWFwIHNwYWNlIHVzZWQgYXMgd29yayBzdG9yZSAqLwogICAgICAgIC8qIGNhbid0IHJlaW5pdGlhbGlzZSBpZiB3ZSBoYXZlIGluaXRpYWxpc2VkIG5vdGhpbmcgISEgKi8KICAgICAgICByZWZlcmVuY2VfaW5zdCA9ICBEREVfSGFuZGxlX1RhYmxlX0Jhc2U7CiAgICAgICAgLyogbXVzdCBmaXJzdCBjaGVjayBpZiB3ZSBoYXZlIGJlZW4gZ2l2ZW4gYSB2YWxpZCBpbnN0YW5jZSB0byByZS1pbml0aWFsaXNlICEhICBob3cgZG8gd2UgZG8gdGhhdCA/ICovCgkvKgoJKglNUyBhbGxvd3MgaW5pdGlhbGlzYXRpb24gd2l0aG91dCBzcGVjaWZ5aW5nIGEgY2FsbGJhY2ssIHNob3VsZCB3ZSBhbGxvdyBhZGRpdGlvbiBvZiB0aGUKCSoJY2FsbGJhY2sgYnkgYSBsYXRlciBjYWxsIHRvIGluaXRpYWxpc2UgPyAtIGlmIHNvIHRoaXMgbG90IHdpbGwgaGF2ZSB0byBjaGFuZ2UKCSovCgl3aGlsZSAoIHJlZmVyZW5jZV9pbnN0LT5OZXh0X0VudHJ5ICE9IE5VTEwgKQoJewoJCWlmICggKnBpZEluc3QgPT0gcmVmZXJlbmNlX2luc3QtPkluc3RhbmNlX2lkICYmIHBmbkNhbGxiYWNrID09IHJlZmVyZW5jZV9pbnN0LT5DYWxsQmFjayApCgkJewoJCQkvKiBDaGVjayAxIC0gY2Fubm90IGNoYW5nZSBjbGllbnQtb25seSBtb2RlIGlmIHNldCB2aWEgQVBQQ01EX0NMSUVOVE9OTFkgKi8KCgkJCWlmICggIHJlZmVyZW5jZV9pbnN0LT5DbGllbnRfb25seSApCgkJCXsKCQkJICAgaWYgICgocmVmZXJlbmNlX2luc3QtPkNCRl9GbGFncyAmIENCRl9GQUlMX0FMTFNWUlhBQ1RJT05TKSAhPSBDQkZfRkFJTF9BTExTVlJYQUNUSU9OUykgCgkJCSAgIHsKCQkJCS8qIGkuZS4gV2FzIHNldCB0byBDbGllbnQtb25seSBhbmQgdGhyb3VnaCBBUFBDTURfQ0xJRU5UT05MWSAqLwoKCQkJCWlmICggISAoIGFmQ21kICYgQVBQQ01EX0NMSUVOVE9OTFkpKQoJCQkJewoJCQkJCWlmICggUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsMCwxLHRoaXNfaW5zdGFuY2UpKQoJCQkJCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJcmV0dXJuIERNTEVSUl9ETExfVVNBR0U7CgkJCQl9CgkJCSAgIH0KCQkJfQoJCQkvKiBDaGVjayAyIC0gY2Fubm90IGNoYW5nZSBtb25pdG9yIG1vZGVzICovCgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXNfaW5zdGFuY2UtPk1vbml0b3IgIT0gcmVmZXJlbmNlX2luc3QtPk1vbml0b3IpIAoJCQl7CgkJCQlpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLDAsMSx0aGlzX2luc3RhbmNlKSkKCQkJCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRE1MRVJSX0RMTF9VU0FHRTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKCQkJLyogQ2hlY2sgMyAtIHRyeWluZyB0byBzZXQgQ2xpZW50LW9ubHkgdmlhIEFQUENNRCB3aGVuIG5vdCBzZXQgc28gcHJldmlvdXNseSAqLwoKCQkJaWYgKCggYWZDbWQmQVBQQ01EX0NMSUVOVE9OTFkpICYmICEgcmVmZXJlbmNlX2luc3QtPkNsaWVudF9vbmx5ICkKCQkJewoJCQkJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSkpCgkJCQkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERNTEVSUl9ETExfVVNBR0U7CgkJCX0KCQkJYnJlYWs7CgkJfQogICAgICAgICAgICAgICAgcmVmZXJlbmNlX2luc3QgPSByZWZlcmVuY2VfaW5zdC0+TmV4dF9FbnRyeTsKCX0KCWlmICggcmVmZXJlbmNlX2luc3QtPk5leHRfRW50cnkgPT0gTlVMTCApCgl7CgkJLyogQ3Jhenkgc2l0dWF0aW9uIC0gdHJ5aW5nIHRvIHJlLWluaXRpYWxpemUgc29tZXRoaW5nIHRoYXQgaGFzIG5vdCBiZWVlbiBpbml0aWFsaXplZCAhISAKCQkqCQoJCSoJTWFudWFsIGRvZXMgbm90IHNheSB3aGF0IHdlIGRvLCBjYW5ub3QgcmV0dXJuIERNTEVSUl9OT1RfSU5JVElBTElaRUQgc28gd2hhdCA/CgkJKi8KCQlpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLDAsMSx0aGlzX2luc3RhbmNlKSkKCQkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7CgkJcmV0dXJuIERNTEVSUl9JTlZBTElEUEFSQU1FVEVSOwoJfQoJLyoJCUFsbCBjaGVja2VkIC0gY2hhbmdlIHJlbGV2YW50IGZsYWdzICovCgoJcmVmZXJlbmNlX2luc3QtPkNCRl9GbGFncyA9IHRoaXNfaW5zdGFuY2UtPkNCRl9GbGFnczsKCXJlZmVyZW5jZV9pbnN0LT5DbGllbnRfb25seSA9IHRoaXNfaW5zdGFuY2UtPkNsaWVudF9vbmx5OwoJcmVmZXJlbmNlX2luc3QtPk1vbml0b3JfZmxhZ3MgPSB0aGlzX2luc3RhbmNlLT5Nb25pdG9yX2ZsYWdzOwoJaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IiwwLDEsdGhpc19pbnN0YW5jZSkpCgkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7CiAgICAgfQoKICAgIHJldHVybiBETUxFUlJfTk9fRVJST1I7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVVbmluaXRpYWxpemUxNiAgIChEREVNTC4zKQogKi8KQk9PTDE2IFdJTkFQSSBEZGVVbmluaXRpYWxpemUxNiggRFdPUkQgaWRJbnN0ICkKewogICAgRklYTUUoIiBzdHViIGNhbGxpbmcgRGRlVW5pbml0aWFsaXplXG4iKTsKICAgIHJldHVybiAoQk9PTDE2KURkZVVuaW5pdGlhbGl6ZSggaWRJbnN0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGRlVW5pbml0aWFsaXplIFtVU0VSMzIuMTE5XSAgRnJlZXMgRERFTUwgcmVzb3VyY2VzCiAqCiAqIFBBUkFNUwogKiAgICBpZEluc3QgW0ldIEluc3RhbmNlIGlkZW50aWZpZXIKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBUUlVFCiAqICAgIEZhaWx1cmU6IEZBTFNFCiAqLwoKQk9PTCBXSU5BUEkgRGRlVW5pbml0aWFsaXplKCBEV09SRCBpZEluc3QgKQp7CgkvKiAgU3RhZ2Ugb25lIC0gY2hlY2sgaWYgd2UgaGF2ZSBhIGhhbmRsZSBmb3IgdGhpcyBpbnN0YW5jZQoJCQkJCQkJCQkqLwogICAgICAgIFNFQ1VSSVRZX0FUVFJJQlVURVMgKnNfYXR0PSBOVUxMOwogIAlTRUNVUklUWV9BVFRSSUJVVEVTIHNfYXR0cmliOwogICAgICAgIERERV9IQU5ETEVfRU5UUlkgKnRoaXNfaW5zdGFuY2U7CiAgICAgICAgRERFX0hBTkRMRV9FTlRSWSAqcmVmZXJlbmNlX2luc3Q7CiAgCXNfYXR0ID0gJnNfYXR0cmliOwoKCWlmICggRERFX01heF9Bc3NpZ25lZF9JbnN0YW5jZSA9PSAwICkKCXsKCQkvKiAgTm90aGluZyBoYXMgYmVlbiBpbml0aWFsaXNlZCAtIGV4aXQgbm93ICEgY2FuIHJldHVybiBUUlVFIHNpbmNlIGVmZmVjdCBpcyB0aGUgc2FtZSAqLwoJCXJldHVybiBUUlVFOwoJfQoKCWlmICggIVdhaXRGb3JNdXRleChoYW5kbGVfbXV0ZXgpICkKCXsKCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKCX0KICAJVFJBQ0UoIkhhbmRsZSBNdXRleCBjcmVhdGVkL3Jlc2VydmVkXG4iKTsKICAJLyogIEZpcnN0IGNoZWNrIGluc3RhbmNlIAogIAkqLwogIAl0aGlzX2luc3RhbmNlID0gRmluZF9JbnN0YW5jZV9FbnRyeShpZEluc3QpOwogIAlpZiAoIHRoaXNfaW5zdGFuY2UgPT0gTlVMTCApCiAgCXsKCQlpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHRoaXNfaW5zdGFuY2UpKSByZXR1cm4gRkFMU0U7CgkJLyoKCQkgICoJTmVlZHMgc29tZXRoaW5nIGhlcmUgdG8gcmVjb3JkIE5PVF9JTklUSUFMSVpFRCByZWFkeSBmb3IgRGRlR2V0TGFzdEVycm9yCgkJKi8KCQlyZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgCUZJWE1FKCIoJWxkKTogcGFydGlhbCBzdHViXG4iLCBpZEluc3QpOwoKCS8qICAgRklYTUUJKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCgkgKglOZWVkcyB0byBkZS1yZWdpc3RlciBhbGwgc2VydmljZSBuYW1lcwoJICoJCgkgKi8KICAgIC8qIEZyZWUgdGhlIG5vZGVzIHRoYXQgd2VyZSBub3QgZnJlZWQgYnkgdGhpcyBpbnN0YW5jZQogICAgICogYW5kIHJlbW92ZSB0aGUgbm9kZXMgZnJvbSB0aGUgbGlzdCBvZiBIU1ogbm9kZXMuCiAgICAgKi8KICAgICAgICBGcmVlQW5kUmVtb3ZlSFNaTm9kZXMoIGlkSW5zdCwgdGhpc19pbnN0YW5jZSApOwogICAgCgkvKiBPSyBub3cgZGVsZXRlIHRoZSBpbnN0YW5jZSBoYW5kbGUgaXRzZWxmICovCgoJaWYgKCBEREVfSGFuZGxlX1RhYmxlX0Jhc2UgPT0gdGhpc19pbnN0YW5jZSApCgl7CgkJLyogc3BlY2lhbCBjYXNlIC0gdGhlIGZpcnN0L29ubHkgZW50cnkKCQkqLwoJCURERV9IYW5kbGVfVGFibGVfQmFzZSA9IHRoaXNfaW5zdGFuY2UtPk5leHRfRW50cnk7Cgl9IGVsc2UKCXsKCQkvKiBnZW5lcmFsIGNhc2UKCQkqLwoJCXJlZmVyZW5jZV9pbnN0ID0gRERFX0hhbmRsZV9UYWJsZV9CYXNlOwoJCXdoaWxlICggcmVmZXJlbmNlX2luc3QtPk5leHRfRW50cnkgIT0gdGhpc19pbnN0YW5jZSApCgkJewoJCQlyZWZlcmVuY2VfaW5zdCA9IHRoaXNfaW5zdGFuY2UtPk5leHRfRW50cnk7CgkJfQoJCXJlZmVyZW5jZV9pbnN0LT5OZXh0X0VudHJ5ID0gdGhpc19pbnN0YW5jZS0+TmV4dF9FbnRyeTsKICAgIAl9CgkvKiByZWxlYXNlIHRoZSBtdXRleCBhbmQgdGhlIGhlYXAgZW50cnkKCSovCiAgICAgIAlpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLFRSVUUsdGhpc19pbnN0YW5jZSkpIAoJewoJCS8qIHNob3VsZCByZWNvcmQgc29tZXRoaW5nIGhlcmUsIGJ1dCBub3RoaW5nIGxlZnQgdG8gaGFuZyBpdCBmcm9tICEhCgkJKi8KCQlyZXR1cm4gRkFMU0U7Cgl9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVDb25uZWN0TGlzdDE2IFtEREVNTC40XQogKi8KCkhDT05WTElTVCBXSU5BUEkgRGRlQ29ubmVjdExpc3QxNiggRFdPUkQgaWRJbnN0LCBIU1ogaHN6U2VydmljZSwgSFNaIGhzelRvcGljLAogICAgICAgICAgICAgICAgIEhDT05WTElTVCBoQ29udkxpc3QsIExQQ09OVkNPTlRFWFQxNiBwQ0MgKQp7CiAgICByZXR1cm4gRGRlQ29ubmVjdExpc3QoaWRJbnN0LCBoc3pTZXJ2aWNlLCBoc3pUb3BpYywgaENvbnZMaXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENPTlZDT05URVhUKXBDQyk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZUNvbm5lY3RMaXN0IFtVU0VSMzIuOTNdICBFc3RhYmxpc2hlcyBjb252ZXJzYXRpb24gd2l0aCBEREUgc2VydmVycwogKgogKiBQQVJBTVMKICogICAgaWRJbnN0ICAgICBbSV0gSW5zdGFuY2UgaWRlbnRpZmllcgogKiAgICBoc3pTZXJ2aWNlIFtJXSBIYW5kbGUgdG8gc2VydmljZSBuYW1lIHN0cmluZwogKiAgICBoc3pUb3BpYyAgIFtJXSBIYW5kbGUgdG8gdG9waWMgbmFtZSBzdHJpbmcKICogICAgaENvbnZMaXN0ICBbSV0gSGFuZGxlIHRvIGNvbnZlcnNhdGlvbiBsaXN0CiAqICAgIHBDQyAgICAgICAgW0ldIFBvaW50ZXIgdG8gc3RydWN0dXJlIHdpdGggY29udGV4dCBkYXRhCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogSGFuZGxlIHRvIG5ldyBjb252ZXJzYXRpb24gbGlzdAogKiAgICBGYWlsdXJlOiAwCiAqLwpIQ09OVkxJU1QgV0lOQVBJIERkZUNvbm5lY3RMaXN0KCBEV09SRCBpZEluc3QsIEhTWiBoc3pTZXJ2aWNlLCBIU1ogaHN6VG9waWMsCiAgICAgICAgICAgICAgICAgSENPTlZMSVNUIGhDb252TGlzdCwgTFBDT05WQ09OVEVYVCBwQ0MgKQp7CiAgICBGSVhNRSgiKCVsZCwlbGQsJWxkLCVsZCwlcCk6IHN0dWJcbiIsIGlkSW5zdCwgaHN6U2VydmljZSwgaHN6VG9waWMsCiAgICAgICAgICBoQ29udkxpc3QscENDKTsKICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZVF1ZXJ5TmV4dFNlcnZlcjE2IFtEREVNTC41XQogKi8KSENPTlYgV0lOQVBJIERkZVF1ZXJ5TmV4dFNlcnZlcjE2KCBIQ09OVkxJU1QgaENvbnZMaXN0LCBIQ09OViBoQ29udlByZXYgKQp7CiAgICByZXR1cm4gRGRlUXVlcnlOZXh0U2VydmVyKGhDb252TGlzdCwgaENvbnZQcmV2KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVRdWVyeU5leHRTZXJ2ZXIgW1VTRVIzMi4xMTJdCiAqLwpIQ09OViBXSU5BUEkgRGRlUXVlcnlOZXh0U2VydmVyKCBIQ09OVkxJU1QgaENvbnZMaXN0LCBIQ09OViBoQ29udlByZXYgKQp7CiAgICBGSVhNRSgiKCVsZCwlbGQpOiBzdHViXG4iLGhDb252TGlzdCxoQ29udlByZXYpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVRdWVyeVN0cmluZ0EgW1VTRVIzMi4xMTNdCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKglDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAJQXV0aG9yICAgICAgICAgCQlDb21tZW50CiAqCiAqICAxLjAgICAgICBEZWMgMTk5OCAgQ29yZWwvTWFjYWRhbWlhbiAgICBJbml0aWFsIHZlcnNpb24KICogIDEuMSAgICAgIE1hciAxOTk5ICBLZWl0aCBNYXR0aGV3cyAgICAgIEFkZGVkIGxpbmtzIHRvIGluc3RhbmNlIHRhYmxlIGFuZCByZWxhdGVkIHByb2Nlc3NpbmcKICoKICovCkRXT1JEIFdJTkFQSSBEZGVRdWVyeVN0cmluZ0EoRFdPUkQgaWRJbnN0LCBIU1ogaHN6LCBMUFNUUiBwc3osIERXT1JEIGNjaE1heCwgSU5UIGlDb2RlUGFnZSkKewogICAgRFdPUkQgcmV0ID0gMDsKICAgIENIQVIgcFN0cmluZ1tNQVhfQlVGRkVSX0xFTl07CiAgICBEREVfSEFORExFX0VOVFJZICpyZWZlcmVuY2VfaW5zdDsKCiAgICBGSVhNRSgKICAgICAgICAgIiglbGQsIDB4JWx4LCAlcCwgJWxkLCAlZCk6IHBhcnRpYWwgc3R1YlxuIiwKICAgICAgICAgaWRJbnN0LAogICAgICAgICBoc3osCiAgICAgICAgIHBzeiwgCiAgICAgICAgIGNjaE1heCwKICAgICAgICAgaUNvZGVQYWdlKTsKICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCiAgewogICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhICovCgkgIC8qICBuZWVkcyBzb21ldGhpbmcgZm9yIERkZUdldExBc3RFcnJvciBldmVuIGlmIHRoZSBtYW51YWwgZG9lc24ndCBzYXkgc28gKi8KICAgICAgICAgIHJldHVybiBGQUxTRTsKICB9CiAgCglpZiAoICFXYWl0Rm9yTXV0ZXgoaGFuZGxlX211dGV4KSApCgl7CgkJcmV0dXJuIEZBTFNFOwoJfQoKICBUUkFDRSgiSGFuZGxlIE11dGV4IGNyZWF0ZWQvcmVzZXJ2ZWRcbiIpOwoKICAvKiAgRmlyc3QgY2hlY2sgaW5zdGFuY2UgCiAgKi8KICByZWZlcmVuY2VfaW5zdCA9IEZpbmRfSW5zdGFuY2VfRW50cnkoaWRJbnN0KTsKICBpZiAoIHJlZmVyZW5jZV9pbnN0ID09IE5VTEwgKQogIHsKICAgICAgICBpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHJlZmVyZW5jZV9pbnN0KSkgcmV0dXJuIEZBTFNFOwogICAgICAgIC8qCiAgICAgICAgTmVlZHMgc29tZXRoaW5nIGhlcmUgdG8gcmVjb3JkIE5PVF9JTklUSUFMSVpFRCByZWFkeSBmb3IgRGRlR2V0TGFzdEVycm9yCiAgICAgICAgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgfQoKICAgIGlmKCBpQ29kZVBhZ2UgPT0gQ1BfV0lOQU5TSSApCiAgICB7CiAgICAgICAgLyogSWYgcHN6IGlzIG51bGwsIHdlIGhhdmUgdG8gcmV0dXJuIG9ubHkgdGhlIGxlbmd0aAogICAgICAgICAqIG9mIHRoZSBzdHJpbmcuCiAgICAgICAgICovCiAgICAgICAgaWYoIHBzeiA9PSBOVUxMICkKICAgICAgICB7CiAgICAgICAgICAgIHBzeiA9IHBTdHJpbmc7CiAgICAgICAgICAgIGNjaE1heCA9IE1BWF9CVUZGRVJfTEVOOwp9CgogICAgICAgIHJldCA9IEdsb2JhbEdldEF0b21OYW1lQSggaHN6LCAoTFBTVFIpcHN6LCBjY2hNYXggKTsKICB9IGVsc2UgewogIAlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCk7CiAgICB9CiAgIFRSQUNFKCJyZXR1cm5pbmcgcG9pbnRlclxuIik7IAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZVF1ZXJ5U3RyaW5nVyBbVVNFUjMyLjExNF0KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIERlYyAxOTk4ICBDb3JlbC9NYWNhZGFtaWFuICAgIEluaXRpYWwgdmVyc2lvbgogKgogKi8KCkRXT1JEIFdJTkFQSSBEZGVRdWVyeVN0cmluZ1coRFdPUkQgaWRJbnN0LCBIU1ogaHN6LCBMUFdTVFIgcHN6LCBEV09SRCBjY2hNYXgsIElOVCBpQ29kZVBhZ2UpCnsKICAgIERXT1JEIHJldCA9IDA7CiAgICBXQ0hBUiBwU3RyaW5nW01BWF9CVUZGRVJfTEVOXTsKICAgIGludCBmYWN0b3IgPSAxOwoKICAgIEZJWE1FKAogICAgICAgICAiKCVsZCwgMHglbHgsICVwLCAlbGQsICVkKTogc3R1YlxuIiwKICAgICAgICAgaWRJbnN0LAogICAgICAgICBoc3osCiAgICAgICAgIHBzeiwgCiAgICAgICAgIGNjaE1heCwKICAgICAgICAgaUNvZGVQYWdlKTsKCiAgICBpZiggaUNvZGVQYWdlID09IENQX1dJTlVOSUNPREUgKQogICAgewogICAgICAgIC8qIElmIHBzeiBpcyBudWxsLCB3ZSBoYXZlIHRvIHJldHVybiBvbmx5IHRoZSBsZW5ndGgKICAgICAgICAgKiBvZiB0aGUgc3RyaW5nLgogICAgICAgICAqLwogICAgICAgIGlmKCBwc3ogPT0gTlVMTCApCiAgICAgICAgewogICAgICAgICAgICBwc3ogPSBwU3RyaW5nOwogICAgICAgICAgICBjY2hNYXggPSBNQVhfQlVGRkVSX0xFTjsKICAgICAgICAgICAgLyogTm90ZTogQWNjb3JkaW5nIHRvIGRvY3VtZW50YXRpb24gaWYgdGhlIHBzeiBwYXJhbWV0ZXIKICAgICAgICAgICAgICogd2FzIE5VTEwgdGhpcyBBUEkgbXVzdCByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGluIGJ5dGVzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZmFjdG9yID0gKGludCkgc2l6ZW9mKFdDSEFSKS9zaXplb2YoQllURSk7CiAgICAgICAgfQogICAgICAgIHJldCA9IEdsb2JhbEdldEF0b21OYW1lVyggaHN6LCAoTFBXU1RSKXBzeiwgY2NoTWF4ICkgKiBmYWN0b3I7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqCQlEZGVRdWVyeVN0cmluZzE2IChEREVNTC4yMykKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgCUF1dGhvciAgICAgICAgIAkJQ29tbWVudAogKgogKiAgMS4wICAgICAgTWFyY2ggMTk5OSBLIE1hdHRoZXdzCQlzdHViIG9ubHkKICovCgpEV09SRCBXSU5BUEkgRGRlUXVlcnlTdHJpbmcxNihEV09SRCBpZEluc3QsIEhTWiBoc3osIExQU1RSIGxwc3osIERXT1JEIGNjaE1heCwgaW50IGNvZGVwYWdlKQp7CglGSVhNRSgiKCVsZCwgMHglbHgsICVwLCAlbGQsICVkKTogc3R1YiBcbiIsIAogICAgICAgICBpZEluc3QsCiAgICAgICAgIGhzeiwKICAgICAgICAgbHBzeiwgCiAgICAgICAgIGNjaE1heCwKICAgICAgICAgY29kZXBhZ2UpOwoJcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVEaXNjb25uZWN0TGlzdCAoRERFTUwuNikKICovCkJPT0wxNiBXSU5BUEkgRGRlRGlzY29ubmVjdExpc3QxNiggSENPTlZMSVNUIGhDb252TGlzdCApCnsKICAgIHJldHVybiAoQk9PTDE2KURkZURpc2Nvbm5lY3RMaXN0KGhDb252TGlzdCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZURpc2Nvbm5lY3RMaXN0IFtVU0VSMzIuOThdICBEZXN0cm95cyBsaXN0IGFuZCB0ZXJtaW5hdGVzIGNvbnZlcnNhdGlvbnMKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBUUlVFCiAqICAgIEZhaWx1cmU6IEZBTFNFCiAqLwpCT09MIFdJTkFQSSBEZGVEaXNjb25uZWN0TGlzdCgKICAgIEhDT05WTElTVCBoQ29udkxpc3QpIC8qIFtpbl0gSGFuZGxlIHRvIGNvbnZlcnNhdGlvbiBsaXN0ICovCnsKICAgIEZJWE1FKCIoJWxkKTogc3R1YlxuIiwgaENvbnZMaXN0KTsKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlQ29ubmVjdDE2ICAgKERERU1MLjcpCiAqLwpIQ09OViBXSU5BUEkgRGRlQ29ubmVjdDE2KCBEV09SRCBpZEluc3QsIEhTWiBoc3pTZXJ2aWNlLCBIU1ogaHN6VG9waWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ09OVkNPTlRFWFQxNiBwQ0MgKQp7CiAgICBGSVhNRSgiZW1wdHkgc3R1YlxuIiApOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVDb25uZWN0ICAgKFVTRVIzMi45MikKICovCkhDT05WIFdJTkFQSSBEZGVDb25uZWN0KCBEV09SRCBpZEluc3QsIEhTWiBoc3pTZXJ2aWNlLCBIU1ogaHN6VG9waWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ09OVkNPTlRFWFQgcENDICkKewogICAgRklYTUUoIigweCVseCwlbGQsJWxkLCVwKTogc3R1YlxuIixpZEluc3QsaHN6U2VydmljZSxoc3pUb3BpYywKICAgICAgICAgIHBDQyk7CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZURpc2Nvbm5lY3QxNiAgIChEREVNTC44KQogKi8KQk9PTDE2IFdJTkFQSSBEZGVEaXNjb25uZWN0MTYoIEhDT05WIGhDb252ICkKewogICAgcmV0dXJuIChCT09MMTYpRGRlRGlzY29ubmVjdCggaENvbnYgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlU2V0VXNlckhhbmRsZTE2IChEREVNTC4xMCkKICovCkJPT0wxNiBXSU5BUEkgRGRlU2V0VXNlckhhbmRsZTE2KCBIQ09OViBoQ29udiwgRFdPUkQgaWQsIERXT1JEIGhVc2VyICkKewogICAgRklYTUUoIiglbGQsJWxkLCVsZCk6IHN0dWJcbiIsaENvbnYsaWQsIGhVc2VyICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlQ3JlYXRlRGF0YUhhbmRsZTE2IChEREVNTC4xNCkKICovCkhEREVEQVRBIFdJTkFQSSBEZGVDcmVhdGVEYXRhSGFuZGxlMTYoIERXT1JEIGlkSW5zdCwgTFBCWVRFIHBTcmMsIERXT1JEIGNiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNiT2ZmLCBIU1ogaHN6SXRlbSwgVUlOVDE2IHdGbXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVDE2IGFmQ21kICkKewogICAgcmV0dXJuIERkZUNyZWF0ZURhdGFIYW5kbGUoaWRJbnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JPZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHN6SXRlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3Rm10LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFmQ21kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlQ3JlYXRlRGF0YUhhbmRsZSAoVVNFUjMyLjk0KQogKi8KSERERURBVEEgV0lOQVBJIERkZUNyZWF0ZURhdGFIYW5kbGUoIERXT1JEIGlkSW5zdCwgTFBCWVRFIHBTcmMsIERXT1JEIGNiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY2JPZmYsIEhTWiBoc3pJdGVtLCBVSU5UIHdGbXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGFmQ21kICkKewogICAgRklYTUUoCiAgICAgICAgICAiKCVsZCwlcCwlbGQsJWxkLDB4JWx4LCVkLCVkKTogc3R1YlxuIiwKICAgICAgICAgIGlkSW5zdCwKICAgICAgICAgIHBTcmMsCiAgICAgICAgICBjYiwKICAgICAgICAgIGNiT2ZmLAogICAgICAgICAgIGhzekl0ZW0sCiAgICAgICAgICB3Rm10LCAKICAgICAgICAgIGFmQ21kICk7CgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZURpc2Nvbm5lY3QgICAoVVNFUjMyLjk3KQogKi8KQk9PTCBXSU5BUEkgRGRlRGlzY29ubmVjdCggSENPTlYgaENvbnYgKQp7CiAgICBGSVhNRSgiZW1wdHkgc3R1YlxuIiApOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVSZWNvbm5lY3QgICAoRERFTUwuMzcpIChVU0VSMzIuMTE1KQogKi8KSENPTlYgV0lOQVBJIERkZVJlY29ubmVjdCggSENPTlYgaENvbnYgKQp7CiAgICBGSVhNRSgiZW1wdHkgc3R1YlxuIiApOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVDcmVhdGVTdHJpbmdIYW5kbGUxNiAgIChEREVNTC4yMSkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgICAgPwkJPwkJCWJhc2ljIHN0dWIKICogIDEuMSAgICAgIEp1bmUgMTk5OSAgS2VpdGggTWF0dGhld3MJCWFtZW5kZWQgb253YXJkIGNhbGwgdG8gc3VwcGx5IGRlZmF1bHQKICoJCQkJCQljb2RlIHBhZ2UgaWYgbm9uZSBzdXBwbGllZCBieSBjYWxsZXIKICovCkhTWiBXSU5BUEkgRGRlQ3JlYXRlU3RyaW5nSGFuZGxlMTYoIERXT1JEIGlkSW5zdCwgTFBDU1RSIHN0ciwgSU5UMTYgY29kZXBhZ2UgKQp7CiAgICBpZiAgKCBjb2RlcGFnZSApCiAgICB7CiAgICByZXR1cm4gRGRlQ3JlYXRlU3RyaW5nSGFuZGxlQSggaWRJbnN0LCBzdHIsIGNvZGVwYWdlICk7CiAgICAgfSBlbHNlIHsKICAJVFJBQ0UoIkRlZmF1bHQgY29kZXBhZ2Ugc3VwcGxpZWRcbiIpOwoJIHJldHVybiBEZGVDcmVhdGVTdHJpbmdIYW5kbGVBKCBpZEluc3QsIHN0ciwgQ1BfV0lOQU5TSSk7CiAgICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZUNyZWF0ZVN0cmluZ0hhbmRsZUEgW1VTRVIzMi45NV0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTdHJpbmcgaGFuZGxlCiAqICAgIEZhaWx1cmU6IDAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgICAgRGVjIDE5OTggIENvcmVsL01hY2FkYW1pYW4gICAgSW5pdGlhbCB2ZXJzaW9uCiAqICAxLjEgICAgICBNYXIgMTk5OSAgS2VpdGggTWF0dGhld3MgICAgICBBZGRlZCBsaW5rcyB0byBpbnN0YW5jZSB0YWJsZSBhbmQgcmVsYXRlZCBwcm9jZXNzaW5nCiAqCiAqLwpIU1ogV0lOQVBJIERkZUNyZWF0ZVN0cmluZ0hhbmRsZUEoIERXT1JEIGlkSW5zdCwgTFBDU1RSIHBzeiwgSU5UIGNvZGVwYWdlICkKewogIEhTWiBoc3ogPSAwOwogIERERV9IQU5ETEVfRU5UUlkgKnJlZmVyZW5jZV9pbnN0OwogIFRSQUNFKCIoJWxkLCVzLCVkKTogcGFydGlhbCBzdHViXG4iLGlkSW5zdCxkZWJ1Z3N0cl9hKHBzeiksY29kZXBhZ2UpOwogIAoKICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCiAgewogICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhIGNhbiByZXR1cm4gRkFMU0Ugc2luY2UgZWZmZWN0IGlzIHRoZSBzYW1lICovCiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgfQogIAoJaWYgKCAhV2FpdEZvck11dGV4KGhhbmRsZV9tdXRleCkgKQoJewoJCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwoJfQoKICBUUkFDRSgiSGFuZGxlIE11dGV4IGNyZWF0ZWQvcmVzZXJ2ZWRcbiIpOwoKICAvKiAgRmlyc3QgY2hlY2sgaW5zdGFuY2UgCiAgKi8KICByZWZlcmVuY2VfaW5zdCA9IEZpbmRfSW5zdGFuY2VfRW50cnkoaWRJbnN0KTsKICBpZiAoIHJlZmVyZW5jZV9pbnN0ID09IE5VTEwgKQogIHsKCWlmICggUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UscmVmZXJlbmNlX2luc3QpKSByZXR1cm4gMDsKCS8qCglOZWVkcyBzb21ldGhpbmcgaGVyZSB0byByZWNvcmQgTk9UX0lOSVRJQUxJWkVEIHJlYWR5IGZvciBEZGVHZXRMYXN0RXJyb3IKCSovCglyZXR1cm4gMDsKICB9CiAgCiAgaWYgKGNvZGVwYWdlPT1DUF9XSU5BTlNJKQogIHsKICAgICAgaHN6ID0gR2xvYmFsQWRkQXRvbUEgKHBzeik7CiAgICAgIC8qIFNhdmUgdGhlIGhhbmRsZSBzbyB3ZSBrbm93IHRvIGNsZWFuIGl0IHdoZW4KICAgICAgICogdW5pbml0aWFsaXplIGlzIGNhbGxlZC4KICAgICAgICovCiAgICAgIFRSQUNFKCJhZGRlZCBhdG9tICVzIHdpdGggSFNaIDB4JWx4LCBcbiIsZGVidWdzdHJfYShwc3opLGhzeik7CiAgICAgIEluc2VydEhTWk5vZGUoIGhzeiwgcmVmZXJlbmNlX2luc3QgKTsKICAgICAgaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCkpIAoJewoJCXJlZmVyZW5jZV9pbnN0LT5MYXN0X0Vycm9yID0gRE1MRVJSX1NZU19FUlJPUjsKCQlyZXR1cm4gMDsKCX0KICAgICAgVFJBQ0UoIlJldHVybmluZyBwb2ludGVyXG4iKTsKICAgICAgcmV0dXJuIGhzejsKICB9IGVsc2UgewogIAlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCk7CiAgfQogICAgVFJBQ0UoIlJldHVybmluZyBlcnJvclxuIik7CiAgICByZXR1cm4gMDsgIAp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVDcmVhdGVTdHJpbmdIYW5kbGVXIFtVU0VSMzIuOTZdICBDcmVhdGVzIGhhbmRsZSB0byBpZGVudGlmeSBzdHJpbmcKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTdHJpbmcgaGFuZGxlCiAqICAgIEZhaWx1cmU6IDAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIERlYyAxOTk4ICBDb3JlbC9NYWNhZGFtaWFuICAgIEluaXRpYWwgdmVyc2lvbgogKiAgMS4xCSAgICAgTWFyIDE5OTkgIEtlaXRoIE1hdHRoZXdzCSAgIEFkZGVkIGxpbmtzIHRvIGluc3RhbmNlIHRhYmxlIGFuZCByZWxhdGVkIHByb2Nlc3NpbmcKICoKICovCkhTWiBXSU5BUEkgRGRlQ3JlYXRlU3RyaW5nSGFuZGxlVygKICAgIERXT1JEIGlkSW5zdCwgICAvKiBbaW5dIEluc3RhbmNlIGlkZW50aWZpZXIgKi8KICAgIExQQ1dTVFIgcHN6LCAgICAvKiBbaW5dIFBvaW50ZXIgdG8gc3RyaW5nICovCiAgICBJTlQgY29kZXBhZ2UpIC8qIFtpbl0gQ29kZSBwYWdlIGlkZW50aWZpZXIgKi8KewogICBEREVfSEFORExFX0VOVFJZICpyZWZlcmVuY2VfaW5zdDsKICAgSFNaIGhzeiA9IDA7CgogICBUUkFDRSgiKCVsZCwlcywlZCk6IHBhcnRpYWwgc3R1YlxuIixpZEluc3QsZGVidWdzdHJfdyhwc3opLGNvZGVwYWdlKTsKICAKCiAgaWYgKCBEREVfTWF4X0Fzc2lnbmVkX0luc3RhbmNlID09IDAgKQogIHsKICAgICAgICAgIC8qICBOb3RoaW5nIGhhcyBiZWVuIGluaXRpYWxpc2VkIC0gZXhpdCBub3cgISBjYW4gcmV0dXJuIEZBTFNFIHNpbmNlIGVmZmVjdCBpcyB0aGUgc2FtZSAqLwogICAgICAgICAgcmV0dXJuIEZBTFNFOwogIH0KICAKCWlmICggIVdhaXRGb3JNdXRleChoYW5kbGVfbXV0ZXgpICkKCXsKCQlyZXR1cm4gRE1MRVJSX1NZU19FUlJPUjsKCX0KCiAgVFJBQ0UoIkNyZWF0ZVN0cmluZyAtIEhhbmRsZSBNdXRleCBjcmVhdGVkL3Jlc2VydmVkXG4iKTsKICAKICAvKiAgRmlyc3QgY2hlY2sgaW5zdGFuY2UgCiAgKi8KICByZWZlcmVuY2VfaW5zdCA9IEZpbmRfSW5zdGFuY2VfRW50cnkoaWRJbnN0KTsKICBpZiAoIHJlZmVyZW5jZV9pbnN0ID09IE5VTEwgKQogIHsKCWlmICggUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UscmVmZXJlbmNlX2luc3QpKSByZXR1cm4gMDsKCS8qCglOZWVkcyBzb21ldGhpbmcgaGVyZSB0byByZWNvcmQgTk9UX0lOSVRJQUxJWkVEIHJlYWR5IGZvciBEZGVHZXRMYXN0RXJyb3IKCSovCglyZXR1cm4gMDsKICB9CgogICAgRklYTUUoIiglbGQsJXMsJWQpOiBwYXJ0aWFsIHN0dWJcbiIsaWRJbnN0LGRlYnVnc3RyX3cocHN6KSxjb2RlcGFnZSk7CgogIGlmIChjb2RlcGFnZT09Q1BfV0lOVU5JQ09ERSkKICAvKgogIFNob3VsZCB3ZSBiZSBjaGVja2luZyB0aGlzIGFnYWluc3QgdGhlIHVuaWNvZGUvYXNjaWkgbmF0dXJlIG9mIHRoZSBjYWxsIHRvIERkZUluaXRpYWxpemUgPwogICovCiAgewogICAgICBoc3ogPSBHbG9iYWxBZGRBdG9tVyAocHN6KTsKICAgICAgLyogU2F2ZSB0aGUgaGFuZGxlIHNvIHdlIGtub3cgdG8gY2xlYW4gaXQgd2hlbgogICAgICAgKiB1bmluaXRpYWxpemUgaXMgY2FsbGVkLgogICAgICAgKi8KICAgICAgSW5zZXJ0SFNaTm9kZSggaHN6LCByZWZlcmVuY2VfaW5zdCApOwogICAgICBpZiAoIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHJlZmVyZW5jZV9pbnN0KSkgCgl7CgkJcmVmZXJlbmNlX2luc3QtPkxhc3RfRXJyb3IgPSBETUxFUlJfU1lTX0VSUk9SOwoJCXJldHVybiAwOwoJfQogICAgICBUUkFDRSgiUmV0dXJuaW5nIHBvaW50ZXJcbiIpOwogICAgICByZXR1cm4gaHN6OwogICB9IGVsc2UgewogIAlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCk7Cn0KICAgIFRSQUNFKCJSZXR1cm5pbmcgZXJyb3JcbiIpOwogIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlRnJlZVN0cmluZ0hhbmRsZTE2ICAgKERERU1MLjIyKQogKi8KQk9PTDE2IFdJTkFQSSBEZGVGcmVlU3RyaW5nSGFuZGxlMTYoIERXT1JEIGlkSW5zdCwgSFNaIGhzeiApCnsKCUZJWE1FKCJpZEluc3QgJWxkIGhzeiAweCVseFxuIixpZEluc3QsaHN6KTsKICAgIHJldHVybiAoQk9PTClEZGVGcmVlU3RyaW5nSGFuZGxlKCBpZEluc3QsIGhzeiApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlRnJlZVN0cmluZ0hhbmRsZSAgIChVU0VSMzIuMTAxKQogKiBSRVRVUk5TOiBzdWNjZXNzOiBub256ZXJvCiAqICAgICAgICAgIGZhaWw6ICAgIHplcm8KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgICAgRGVjIDE5OTggIENvcmVsL01hY2FkYW1pYW4gICAgSW5pdGlhbCB2ZXJzaW9uCiAqICAxLjEgICAgICBBcHIgMTk5OSAgS2VpdGggTWF0dGhld3MgICAgICBBZGRlZCBsaW5rcyB0byBpbnN0YW5jZSB0YWJsZSBhbmQgcmVsYXRlZCBwcm9jZXNzaW5nCiAqCiAqLwpCT09MIFdJTkFQSSBEZGVGcmVlU3RyaW5nSGFuZGxlKCBEV09SRCBpZEluc3QsIEhTWiBoc3ogKQp7CiAgICBEREVfSEFORExFX0VOVFJZICpyZWZlcmVuY2VfaW5zdDsKICAgIFRSQUNFKCIoJWxkLCVsZCk6IFxuIixpZEluc3QsaHN6KTsKICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCnsKICAgICAgICAgIC8qICBOb3RoaW5nIGhhcyBiZWVuIGluaXRpYWxpc2VkIC0gZXhpdCBub3cgISBjYW4gcmV0dXJuIFRSVUUgc2luY2UgZWZmZWN0IGlzIHRoZSBzYW1lICovCiAgICAgICAgICByZXR1cm4gVFJVRTsKICB9CgoJaWYgKCAhV2FpdEZvck11dGV4KGhhbmRsZV9tdXRleCkgKQoJewoJCXJldHVybiBETUxFUlJfU1lTX0VSUk9SOwoJfQoKICBUUkFDRSgiSGFuZGxlIE11dGV4IGNyZWF0ZWQvcmVzZXJ2ZWRcbiIpOwoKICAvKiAgRmlyc3QgY2hlY2sgaW5zdGFuY2UgCiAgKi8KICByZWZlcmVuY2VfaW5zdCA9IEZpbmRfSW5zdGFuY2VfRW50cnkoaWRJbnN0KTsKICBpZiAoIChyZWZlcmVuY2VfaW5zdCA9PSBOVUxMKSB8fCAocmVmZXJlbmNlX2luc3QtPk5vZGVfbGlzdCA9PSBOVUxMKSkKICB7CiAgICAgICAgaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCkpIHJldHVybiBUUlVFOwogICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhIGNhbiByZXR1cm4gVFJVRSBzaW5jZSBlZmZlY3QgaXMgdGhlIHNhbWUgKi8KICAgICAgICAgIHJldHVybiBUUlVFOwoKICB9CgogICAgLyogUmVtb3ZlIHRoZSBub2RlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEhTWi4KICAgICAqLwogICAgUmVtb3ZlSFNaTm9kZSggaHN6ICwgcmVmZXJlbmNlX2luc3QpOwogICAgLyogRnJlZSB0aGUgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEhTWi4KICAgICAqLwogIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHJlZmVyZW5jZV9pbnN0KTsKICAgIHJldHVybiBHbG9iYWxEZWxldGVBdG9tIChoc3opID8gMCA6IGhzejsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZUZyZWVEYXRhSGFuZGxlMTYgICAoRERFTUwuMTkpCiAqLwpCT09MMTYgV0lOQVBJIERkZUZyZWVEYXRhSGFuZGxlMTYoIEhEREVEQVRBIGhEYXRhICkKewogICAgcmV0dXJuIChCT09MKURkZUZyZWVEYXRhSGFuZGxlKCBoRGF0YSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlRnJlZURhdGFIYW5kbGUgICAoVVNFUjMyLjEwMCkKICovCkJPT0wgV0lOQVBJIERkZUZyZWVEYXRhSGFuZGxlKCBIRERFREFUQSBoRGF0YSApCnsKICAgIEZJWE1FKCJlbXB0eSBzdHViXG4iICk7CiAgICByZXR1cm4gVFJVRTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlS2VlcFN0cmluZ0hhbmRsZTE2ICAgKERERU1MLjI0KQogKi8KQk9PTDE2IFdJTkFQSSBEZGVLZWVwU3RyaW5nSGFuZGxlMTYoIERXT1JEIGlkSW5zdCwgSFNaIGhzeiApCnsKICAgIHJldHVybiAoQk9PTClEZGVLZWVwU3RyaW5nSGFuZGxlKCBpZEluc3QsIGhzeiApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlS2VlcFN0cmluZ0hhbmRsZSAgKFVTRVIzMi4xMDgpCiAqCiAqIFJFVFVSTlM6IHN1Y2Nlc3M6IG5vbnplcm8KICogICAgICAgICAgZmFpbDogICAgemVybwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICAgICBDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAgICBBdXRob3IgICAgICAgICAgICAgICAgICBDb21tZW50CiAqCiAqICAxLjAgICAgICA/CQkgPwkJICAgU3R1YiBvbmx5CiAqICAxLjEgICAgICBKdW4gMTk5OSAgS2VpdGggTWF0dGhld3MgICAgICBGaXJzdCBjdXQgaW1wbGVtZW50YXRpb24KICoKICovCkJPT0wgV0lOQVBJIERkZUtlZXBTdHJpbmdIYW5kbGUoIERXT1JEIGlkSW5zdCwgSFNaIGhzeiApCnsKCiAgRERFX0hBTkRMRV9FTlRSWSAqcmVmZXJlbmNlX2luc3Q7CiAgVFJBQ0UoIiglbGQsJWxkKTogXG4iLGlkSW5zdCxoc3opOwogIGlmICggRERFX01heF9Bc3NpZ25lZF9JbnN0YW5jZSA9PSAwICkKICB7CiAgICAgICAgICAvKiAgTm90aGluZyBoYXMgYmVlbiBpbml0aWFsaXNlZCAtIGV4aXQgbm93ICEgY2FuIHJldHVybiBGQUxTRSBzaW5jZSBlZmZlY3QgaXMgdGhlIHNhbWUgKi8KICAgICAgICAgIHJldHVybiBGQUxTRTsKICB9CgoKCWlmICggIVdhaXRGb3JNdXRleChoYW5kbGVfbXV0ZXgpICkKCXsKCQlyZXR1cm4gRkFMU0U7Cgl9CgogIFRSQUNFKCJIYW5kbGUgTXV0ZXggY3JlYXRlZC9yZXNlcnZlZFxuIik7CgogIC8qICBGaXJzdCBjaGVjayBpbnN0YW5jZQogICovCiAgcmVmZXJlbmNlX2luc3QgPSBGaW5kX0luc3RhbmNlX0VudHJ5KGlkSW5zdCk7CiAgaWYgKCAocmVmZXJlbmNlX2luc3QgPT0gTlVMTCkgfHwgKHJlZmVyZW5jZV9pbnN0LT5Ob2RlX2xpc3QgPT0gTlVMTCkpCiAgewogICAgICAgIGlmICggUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UscmVmZXJlbmNlX2luc3QpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAvKiAgTm90aGluZyBoYXMgYmVlbiBpbml0aWFsaXNlZCAtIGV4aXQgbm93ICEgY2FuIHJldHVybiBGQUxTRSBzaW5jZSBlZmZlY3QgaXMgdGhlIHNhbWUgKi8KICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBGQUxTRTsKICAgfQogIERkZVJlc2VydmVBdG9tKHJlZmVyZW5jZV9pbnN0LGhzeik7CiAgUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UscmVmZXJlbmNlX2luc3QpOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVDbGllbnRUcmFuc2FjdGlvbjE2ICAoRERFTUwuMTEpCiAqLwpIRERFREFUQSBXSU5BUEkgRGRlQ2xpZW50VHJhbnNhY3Rpb24xNiggTFBWT0lEIHBEYXRhLCBEV09SRCBjYkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQ09OViBoQ29udiwgSFNaIGhzekl0ZW0sIFVJTlQxNiB3Rm10LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVDE2IHdUeXBlLCBEV09SRCBkd1RpbWVvdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERXT1JEIHBkd1Jlc3VsdCApCnsKICAgIHJldHVybiBEZGVDbGllbnRUcmFuc2FjdGlvbiggKExQQllURSlwRGF0YSwgY2JEYXRhLCBoQ29udiwgaHN6SXRlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3Rm10LCB3VHlwZSwgZHdUaW1lb3V0LCBwZHdSZXN1bHQgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZUNsaWVudFRyYW5zYWN0aW9uICAoVVNFUjMyLjkwKQogKi8KSERERURBVEEgV0lOQVBJIERkZUNsaWVudFRyYW5zYWN0aW9uKCBMUEJZVEUgcERhdGEsIERXT1JEIGNiRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhDT05WIGhDb252LCBIU1ogaHN6SXRlbSwgVUlOVCB3Rm10LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCB3VHlwZSwgRFdPUkQgZHdUaW1lb3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEV09SRCBwZHdSZXN1bHQgKQp7CiAgICBGSVhNRSgiZW1wdHkgc3R1YlxuIiApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgICAgICAgICAgIERkZUFiYW5kb25UcmFuc2FjdGlvbjE2IChEREVNTC4xMikKICoKICovCkJPT0wxNiBXSU5BUEkgRGRlQWJhbmRvblRyYW5zYWN0aW9uMTYoIERXT1JEIGlkSW5zdCwgSENPTlYgaENvbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgaWRUcmFuc2FjdGlvbiApCnsKICAgIEZJWE1FKCJlbXB0eSBzdHViXG4iICk7CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgICAgICAgICAgIERkZUFiYW5kb25UcmFuc2FjdGlvbiAoVVNFUjMyLjg3KQogKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgCUF1dGhvciAgICAgICAgIAkJQ29tbWVudAogKgogKiAgMS4wICAgICAgTWFyY2ggMTk5OSBLIE1hdHRoZXdzCQlzdHViIG9ubHkKICovCkJPT0wgV0lOQVBJIERkZUFiYW5kb25UcmFuc2FjdGlvbiggRFdPUkQgaWRJbnN0LCBIQ09OViBoQ29udiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBpZFRyYW5zYWN0aW9uICkKewogICAgRklYTUUoImVtcHR5IHN0dWJcbiIgKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGRlUG9zdEFkdmlzZTE2IFtEREVNTC4xM10KICovCkJPT0wxNiBXSU5BUEkgRGRlUG9zdEFkdmlzZTE2KCBEV09SRCBpZEluc3QsIEhTWiBoc3pUb3BpYywgSFNaIGhzekl0ZW0gKQp7CiAgICByZXR1cm4gKEJPT0wxNilEZGVQb3N0QWR2aXNlKGlkSW5zdCwgaHN6VG9waWMsIGhzekl0ZW0pOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZGVQb3N0QWR2aXNlIFtVU0VSMzIuMTEwXSAgU2VuZCB0cmFuc2FjdGlvbiB0byBEREUgY2FsbGJhY2sgZnVuY3Rpb24uCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogVFJVRQogKiAgICBGYWlsdXJlOiBGQUxTRQogKi8KQk9PTCBXSU5BUEkgRGRlUG9zdEFkdmlzZSgKICAgIERXT1JEIGlkSW5zdCwgLyogW2luXSBJbnN0YW5jZSBpZGVudGlmaWVyICovCiAgICBIU1ogaHN6VG9waWMsIC8qIFtpbl0gSGFuZGxlIHRvIHRvcGljIG5hbWUgc3RyaW5nICovCiAgICBIU1ogaHN6SXRlbSkgIC8qIFtpbl0gSGFuZGxlIHRvIGl0ZW0gbmFtZSBzdHJpbmcgKi8KewogICAgRklYTUUoIiglbGQsJWxkLCVsZCk6IHN0dWJcbiIsaWRJbnN0LGhzelRvcGljLGhzekl0ZW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVBZGREYXRhMTYgKERERU1MLjE1KQogKi8KSERERURBVEEgV0lOQVBJIERkZUFkZERhdGExNiggSERERURBVEEgaERhdGEsIExQQllURSBwU3JjLCBEV09SRCBjYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNiT2ZmICkKewogICAgRklYTUUoImVtcHR5IHN0dWJcbiIgKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICAgICAgICAgICBEZGVBZGREYXRhIChVU0VSMzIuODkpCiAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKglDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAJQXV0aG9yICAgICAgICAgCQlDb21tZW50CiAqCiAqICAxLjAgICAgICBNYXJjaCAxOTk5IEsgTWF0dGhld3MJCXN0dWIgb25seQogKi8KSERERURBVEEgV0lOQVBJIERkZUFkZERhdGEoIEhEREVEQVRBIGhEYXRhLCBMUEJZVEUgcFNyYywgRFdPUkQgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjYk9mZiApCnsKICAgIEZJWE1FKCJlbXB0eSBzdHViXG4iICk7CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgICAgICAgICAgIERkZUltcGVyc29uYXRlQ2xpZW50IChVU0VSMzIuMTA1KQogKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICoJQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgCUF1dGhvciAgICAgICAgIAkJQ29tbWVudAogKgogKiAgMS4wICAgICAgTWFyY2ggMTk5OSBLIE1hdHRoZXdzCQlzdHViIG9ubHkKICovCgpCT09MIFdJTkFQSSBEZGVJbXBlcnNvbmF0ZUNsaWVudCggSENPTlYgaENvbnYpCnsKICAgIEZJWE1FKCJlbXB0eSBzdHViXG4iICk7CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgICAgICAgICAgIERkZVNldFF1YWxpdHlPZlNlcnZpY2UgKFVTRVIzMi4xMTYpCiAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKglDaGFuZ2UgSGlzdG9yeQogKgogKiAgVm4gICAgICAgRGF0ZSAgICAJQXV0aG9yICAgICAgICAgCQlDb21tZW50CiAqCiAqICAxLjAgICAgICBNYXJjaCAxOTk5IEsgTWF0dGhld3MJCXN0dWIgb25seQogKi8KCkJPT0wgV0lOQVBJIERkZVNldFF1YWxpdHlPZlNlcnZpY2UoIEhXTkQgaHduZENsaWVudCwgQ09OU1QgU0VDVVJJVFlfUVVBTElUWV9PRl9TRVJWSUNFICpwcW9zTmV3LAoJCQkJCVBTRUNVUklUWV9RVUFMSVRZX09GX1NFUlZJQ0UgcHFvc1ByZXYpCnsKICAgIEZJWE1FKCJlbXB0eSBzdHViXG4iICk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgICAgICAgRGRlU2V0VXNlckhhbmRsZSAoVVNFUjMyLjExNykKICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqCUNoYW5nZSBIaXN0b3J5CiAqCiAqICBWbiAgICAgICBEYXRlICAgIAlBdXRob3IgICAgICAgICAJCUNvbW1lbnQKICoKICogIDEuMCAgICAgIE1hcmNoIDE5OTkgSyBNYXR0aGV3cwkJc3R1YiBvbmx5CiAqLwoKQk9PTCBXSU5BUEkgRGRlU2V0VXNlckhhbmRsZSggSENPTlYgaENvbnYsIERXT1JEIGlkLCBEV09SRCBoVXNlcikKewogICAgRklYTUUoImVtcHR5IHN0dWJcbiIgKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZUdldERhdGEgW1VTRVIzMi4xMDJdICBDb3BpZXMgZGF0YSBmcm9tIERERSBvYmplY3Qgb3QgbG9jYWwgYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogICAgU2l6ZSBvZiBtZW1vcnkgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCBoYW5kbGUKICovCkRXT1JEIFdJTkFQSSBEZGVHZXREYXRhKAogICAgSERERURBVEEgaERhdGEsIC8qIFtpbl0gSGFuZGxlIHRvIERERSBvYmplY3QgKi8KICAgIExQQllURSBwRHN0LCAgICAvKiBbaW5dIFBvaW50ZXIgdG8gZGVzdGluYXRpb24gYnVmZmVyICovCiAgICBEV09SRCBjYk1heCwgICAgLyogW2luXSBBbW91bnQgb2YgZGF0YSB0byBjb3B5ICovCiAgICBEV09SRCBjYk9mZikgICAgLyogW2luXSBPZmZzZXQgdG8gYmVnaW5uaW5nIG9mIGRhdGEgKi8KewogICAgRklYTUUoIiglbGQsJXAsJWxkLCVsZCk6IHN0dWJcbiIsaERhdGEscERzdCxjYk1heCxjYk9mZik7CiAgICByZXR1cm4gY2JNYXg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGRlR2V0RGF0YTE2IFtEREVNTC4xNl0KICovCkRXT1JEIFdJTkFQSSBEZGVHZXREYXRhMTYoCiAgICBIRERFREFUQSBoRGF0YSwKICAgIExQQllURSBwRHN0LAogICAgRFdPUkQgY2JNYXgsIAogICAgRFdPUkQgY2JPZmYpCnsKICAgIHJldHVybiBEZGVHZXREYXRhKGhEYXRhLCBwRHN0LCBjYk1heCwgY2JPZmYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlQWNjZXNzRGF0YTE2IChEREVNTC4xNykKICovCkxQQllURSBXSU5BUEkgRGRlQWNjZXNzRGF0YTE2KCBIRERFREFUQSBoRGF0YSwgTFBEV09SRCBwY2JEYXRhU2l6ZSApCnsKICAgICByZXR1cm4gRGRlQWNjZXNzRGF0YShoRGF0YSwgcGNiRGF0YVNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVBY2Nlc3NEYXRhIChVU0VSMzIuODgpCiAqLwpMUEJZVEUgV0lOQVBJIERkZUFjY2Vzc0RhdGEoIEhEREVEQVRBIGhEYXRhLCBMUERXT1JEIHBjYkRhdGFTaXplICkKewogICAgIEZJWE1FKCIoJWxkLCVwKTogc3R1YlxuIiwgaERhdGEsIHBjYkRhdGFTaXplKTsKICAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlVW5hY2Nlc3NEYXRhMTYgKERERU1MLjE4KQogKi8KQk9PTDE2IFdJTkFQSSBEZGVVbmFjY2Vzc0RhdGExNiggSERERURBVEEgaERhdGEgKQp7CiAgICAgcmV0dXJuIERkZVVuYWNjZXNzRGF0YShoRGF0YSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZVVuYWNjZXNzRGF0YSAoVVNFUjMyLjExOCkKICovCkJPT0wgV0lOQVBJIERkZVVuYWNjZXNzRGF0YSggSERERURBVEEgaERhdGEgKQp7CiAgICAgRklYTUUoIigweCVseCk6IHN0dWJcbiIsIGhEYXRhKTsKCiAgICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZUVuYWJsZUNhbGxiYWNrMTYgKERERU1MLjI2KQogKi8KQk9PTDE2IFdJTkFQSSBEZGVFbmFibGVDYWxsYmFjazE2KCBEV09SRCBpZEluc3QsIEhDT05WIGhDb252LCBVSU5UMTYgd0NtZCApCnsKICAgICByZXR1cm4gRGRlRW5hYmxlQ2FsbGJhY2soaWRJbnN0LCBoQ29udiwgd0NtZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgIERkZUVuYWJsZUNhbGxiYWNrIChVU0VSMzIuOTkpCiAqLwpCT09MIFdJTkFQSSBEZGVFbmFibGVDYWxsYmFjayggRFdPUkQgaWRJbnN0LCBIQ09OViBoQ29udiwgVUlOVCB3Q21kICkKewogICAgIEZJWE1FKCIoJWxkLCAweCVseCwgJWQpIHN0dWJcbiIsIGlkSW5zdCwgaENvbnYsIHdDbWQpOwoKICAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlTmFtZVNlcnZpY2UxNiAgKERERU1MLjI3KQogKi8KSERERURBVEEgV0lOQVBJIERkZU5hbWVTZXJ2aWNlMTYoIERXT1JEIGlkSW5zdCwgSFNaIGhzejEsIEhTWiBoc3oyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVDE2IGFmQ21kICkKewogICAgcmV0dXJuIERkZU5hbWVTZXJ2aWNlKCBpZEluc3QsIGhzejEsIGhzejIsIGFmQ21kICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERkZU5hbWVTZXJ2aWNlIFtVU0VSMzIuMTA5XSAge1VufXJlZ2lzdGVycyBzZXJ2aWNlIG5hbWUgb2YgRERFIHNlcnZlcgogKgogKiBQQVJBTVMKICogICAgaWRJbnN0IFtJXSBJbnN0YW5jZSBpZGVudGlmaWVyCiAqICAgIGhzejEgICBbSV0gSGFuZGxlIHRvIHNlcnZpY2UgbmFtZSBzdHJpbmcKICogICAgaHN6MiAgIFtJXSBSZXNlcnZlZAogKiAgICBhZkNtZCAgW0ldIFNlcnZpY2UgbmFtZSBmbGFncwogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IE5vbi16ZXJvCiAqICAgIEZhaWx1cmU6IDAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgICAgPwkgCSAgPwkJICAgU3R1YgogKiAgMS4xICAgICAgQXByIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgdHJhcCBmb3Igbm9uLWV4aXN0ZW50IGluc3RhbmNlICh1bmluaXRpYWxpc2VkIGluc3RhbmNlIDAKICoJCQkJCQl1c2VkIGJ5IHNvbWUgTVMgcHJvZ3JhbXMgZm9yIHVuZmF0aG9tYWJsZSByZWFzb25zKQogKiAgMS4yCSAgICAgTWF5IDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgcGFyYW1ldGVyIHZhbGlkYXRpb24gYW5kIGJhc2ljIHNlcnZpY2UgbmFtZSBoYW5kbGluZy4KICoJCQkJCSAgIFN0aWxsIG5lZWRzIGNhbGxiYWNrIHBhcnRzCiAqCiAqLwpIRERFREFUQSBXSU5BUEkgRGRlTmFtZVNlcnZpY2UoIERXT1JEIGlkSW5zdCwgSFNaIGhzejEsIEhTWiBoc3oyLAogICAgICAgICAgICAgICAgVUlOVCBhZkNtZCApCnsKICBVSU5UCUNtZF9mbGFncyA9IGFmQ21kOwogIFNlcnZpY2VOb2RlKiB0aGlzX3NlcnZpY2UsICpyZWZlcmVuY2Vfc2VydmljZSA7CiAgQ0hBUiBTTmFtZUJ1ZmZlcltNQVhfQlVGRkVSX0xFTl07CiAgVUlOVCByY29kZTsKICBEREVfSEFORExFX0VOVFJZICp0aGlzX2luc3RhbmNlOwogIERERV9IQU5ETEVfRU5UUlkgKnJlZmVyZW5jZV9pbnN0OwogIHRoaXNfc2VydmljZSA9IE5VTEw7CgogIEZJWE1FKCIoJWxkLCVsZCwlbGQsJWQpOiBzdHViXG4iLGlkSW5zdCxoc3oxLGhzejIsYWZDbWQpOwoKICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCiAgewogICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhIAoJICAgKgluZWVkcyBzb21ldGhpbmcgZm9yIERkZUdldExhc3RFcnJvciAqLwogICAgICAgICAgcmV0dXJuIDBMOwogIH0KCglpZiAoICFXYWl0Rm9yTXV0ZXgoaGFuZGxlX211dGV4KSApCgl7CgkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7Cgl9CgogICBUUkFDRSgiSGFuZGxlIE11dGV4IGNyZWF0ZWQvcmVzZXJ2ZWRcbiIpOwoKICAgLyogIEZpcnN0IGNoZWNrIGluc3RhbmNlCiAgICovCiAgIHJlZmVyZW5jZV9pbnN0ID0gRmluZF9JbnN0YW5jZV9FbnRyeShpZEluc3QpOwogICB0aGlzX2luc3RhbmNlID0gcmVmZXJlbmNlX2luc3Q7CiAgIGlmICAocmVmZXJlbmNlX2luc3QgPT0gTlVMTCkKICAgewoJVFJBQ0UoIkluc3RhbmNlIG5vdCBmb3VuZCBhcyBpbml0aWFsaXNlZFxuIik7CiAgICAgICAgaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSx0aGlzX2luc3RhbmNlKSkgcmV0dXJuIFRSVUU7CiAgICAgICAgICAvKiAgTm90aGluZyBoYXMgYmVlbiBpbml0aWFsaXNlZCAtIGV4aXQgbm93ICEgY2FuIHJldHVybiBUUlVFIHNpbmNlIGVmZmVjdCBpcyB0aGUgc2FtZSAqLwogICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgfQoKICBpZiAoIGhzejIgIT0gMEwgKQogIHsKCS8qCUlsbGVnYWwsIHJlc2VydmVkIHBhcmFtZXRlcgoJICovCglyZWZlcmVuY2VfaW5zdC0+TGFzdF9FcnJvciA9IERNTEVSUl9JTlZBTElEUEFSQU1FVEVSOwogIAlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSx0aGlzX2luc3RhbmNlKTsKCUZJWE1FKCJSZXNlcnZlZCBwYXJhbWV0ZXIgbm8temVybyAhIVxuIik7CglyZXR1cm4gRkFMU0U7CiAgfQogIGlmICggaHN6MSA9PSAwTCApCiAgewoJLyoKCSAqCUdlbmVyYWwgdW5yZWdpc3RlciBzaXR1YXRpb24KCSAqLwogICAgICAgIGlmICggYWZDbWQgIT0gRE5TX1VOUkVHSVNURVIgKQoJewoJCS8qCWRvbid0IGtub3cgaWYgd2Ugc2hvdWxkIGNoZWNrIHRoaXMgYnV0IGl0IG1ha2VzIHNlbnNlCgkJICoJd2h5IHN1cHBseSBSRUdJU1RFUiBvciBmaWx0ZXIgZmxhZ3MgaWYgZGUtcmVnaXN0ZXJpbmcgYWxsCgkJICovCiAgIAkJVFJBQ0UoIkdlbmVyYWwgdW5yZWdpc3RlciB1bmV4cGVjdGVkIGZsYWdzXG4iKTsKCQlyZWZlcmVuY2VfaW5zdC0+TGFzdF9FcnJvciA9IERNTEVSUl9ETExfVVNBR0U7CiAgCQlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSx0aGlzX2luc3RhbmNlKTsKCQlyZXR1cm4gRkFMU0U7Cgl9CgkvKglMb29wIHRvIGZpbmQgYWxsIHJlZ2lzdGVyZWQgc2VydmljZSBhbmQgZGUtcmVnaXN0ZXIgdGhlbQoJICovCglpZiAoIHJlZmVyZW5jZV9pbnN0LT5TZXJ2aWNlTmFtZXMgPT0gTlVMTCApCgl7CgkJLyogIE5vbmUgdG8gdW5yZWdpc3RlciAhISAgCgkJICovCgkJVFJBQ0UoIkdlbmVyYWwgZGUtcmVnaXN0ZXIgLSBub3RoaW5nIHJlZ2lzdGVyZWRcbiIpOwoJCXJlZmVyZW5jZV9pbnN0LT5MYXN0X0Vycm9yID0gRE1MRVJSX0RMTF9VU0FHRTsKICAJCVJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHRoaXNfaW5zdGFuY2UpOwoJCXJldHVybiBGQUxTRTsKCX0gIGVsc2UKCXsKCQl0aGlzX3NlcnZpY2UgPSByZWZlcmVuY2VfaW5zdC0+U2VydmljZU5hbWVzOwoJCXdoaWxlICggdGhpc19zZXJ2aWNlLT5uZXh0ICE9IE5VTEwpCgkJewoJCQlUUkFDRSgiZ2VuZXJhbCBkZXJlZ2lzdGVyIC0gaXRlcmF0aW9uXG4iKTsKCQkJcmVmZXJlbmNlX3NlcnZpY2UgPSB0aGlzX3NlcnZpY2U7CgkJCXRoaXNfc2VydmljZSA9IHRoaXNfc2VydmljZS0+bmV4dDsKCQkJRGRlUmVsZWFzZUF0b20ocmVmZXJlbmNlX2luc3QscmVmZXJlbmNlX3NlcnZpY2UtPmhzeik7CiAgICAgICAgCQlIZWFwRnJlZShTeXN0ZW1IZWFwLCAwLCByZWZlcmVuY2Vfc2VydmljZSk7IC8qIGZpbmlzaGVkIC0gcmVsZWFzZSBoZWFwIHNwYWNlIHVzZWQgYXMgd29yayBzdG9yZSAqLwoJCX0KCQlEZGVSZWxlYXNlQXRvbShyZWZlcmVuY2VfaW5zdCx0aGlzX3NlcnZpY2UtPmhzeik7CiAgICAgICAgCUhlYXBGcmVlKFN5c3RlbUhlYXAsIDAsIHRoaXNfc2VydmljZSk7IC8qIGZpbmlzaGVkIC0gcmVsZWFzZSBoZWFwIHNwYWNlIHVzZWQgYXMgd29yayBzdG9yZSAqLwoJCXJlZmVyZW5jZV9pbnN0LT5TZXJ2aWNlTmFtZXMgPSBOVUxMOwoJCVRSQUNFKCJHZW5lcmFsIGRlLXJlZ2lzdGVyIC0gZmluaXNoZWRcbiIpOwoJfQogIAlSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSx0aGlzX2luc3RhbmNlKTsKICAJcmV0dXJuIFRSVUU7CiAgfQogIFRSQUNFKCJTcGVjaWZpYyBuYW1lIGFjdGlvbiBkZXRlY3RlZFxuIik7CiAgcmVmZXJlbmNlX3NlcnZpY2UgPSBGaW5kX1NlcnZpY2VfTmFtZShoc3oxLHJlZmVyZW5jZV9pbnN0KTsKICBpZiAoKCBDbWRfZmxhZ3MgJiYgRE5TX1JFR0lTVEVSICkgPT0gRE5TX1JFR0lTVEVSICkKICB7CgkvKglSZWdpc3RlciBuZXcgc2VydmljZSBuYW1lCgkgKi8KCglyY29kZT1HbG9iYWxHZXRBdG9tTmFtZUEoaHN6MSxTTmFtZUJ1ZmZlcixNQVhfQVRPTV9MRU4pOwoJQ21kX2ZsYWdzID0gQ21kX2ZsYWdzIF4gRE5TX1JFR0lTVEVSOwogIAl0aGlzX3NlcnZpY2U9IChTZXJ2aWNlTm9kZSopSGVhcEFsbG9jKCBTeXN0ZW1IZWFwLCAwLCBzaXplb2YoU2VydmljZU5vZGUpICk7CiAgCXRoaXNfc2VydmljZS0+bmV4dCA9IE5VTEw7CiAgCXRoaXNfc2VydmljZS0+aHN6ID0gaHN6MTsKICAJdGhpc19zZXJ2aWNlLT5GaWx0ZXJPbiA9IFRSVUU7CglpZiAoIHJlZmVyZW5jZV9pbnN0LT5TZXJ2aWNlTmFtZXMgPT0gTlVMTCApCgl7CgkJLyoJZWFzeSBvbmUgLSBub3RoaW5nIGVsc2UgdGhlcmUKCQkgKi8KICAJCVRSQUNFKCJBZGRpbmcgMXN0IHNlcnZpY2UgbmFtZVxuIik7CgkJcmVmZXJlbmNlX2luc3QtPlNlcnZpY2VOYW1lcyA9IHRoaXNfc2VydmljZTsKCQlHbG9iYWxBZGRBdG9tQShTTmFtZUJ1ZmZlcik7Cgl9IGVsc2UKCXsKCQkvKgltb3JlIGRpZmZpY3VsdCAtIG1heSBoYXZlIGFsc28gYmVlbiByZWdpc3RlcmVkCgkJICovCgkJaWYgKHJlZmVyZW5jZV9zZXJ2aWNlICE9IE5VTEwgKQoJCXsKCQkJLyoJU2VydmljZSBuYW1lIGFscmVhZHkgcmVnaXN0ZXJlZCAhIQoJCQkgKgkgd2hhdCBkbyB3ZSBkbyA/IAoJCQkgKi8KICAgICAgICAJCUhlYXBGcmVlKFN5c3RlbUhlYXAsIDAsIHRoaXNfc2VydmljZSk7IC8qIGZpbmlzaGVkIC0gcmVsZWFzZSBoZWFwIHNwYWNlIHVzZWQgYXMgd29yayBzdG9yZSAqLwogICAgICAgIAkJRklYTUUoIlRyeWluZyB0byByZWdpc3RlciBhbHJlYWR5IHJlZ2lzdGVyZWQgc2VydmljZSAgISFcbiIpOwoJCX0gZWxzZQoJCXsKCQkJLyoJQWRkIHRoaXMgb25lIGludG8gdGhlIGNoYWluCgkJCSAqLwogIAkJCVRSQUNFKCJBZGRpbmcgc3Vic2VxdWVudCBzZXJ2aWNlIG5hbWVcbiIpOwoJCQl0aGlzX3NlcnZpY2UtPm5leHQgPSByZWZlcmVuY2VfaW5zdC0+U2VydmljZU5hbWVzOwoJCQlyZWZlcmVuY2VfaW5zdC0+U2VydmljZU5hbWVzID0gdGhpc19zZXJ2aWNlOwoJCQlHbG9iYWxBZGRBdG9tQShTTmFtZUJ1ZmZlcik7CgkJfQoJfQogIH0KICBpZiAoIChDbWRfZmxhZ3MgJiYgRE5TX1VOUkVHSVNURVIgKSA9PSBETlNfVU5SRUdJU1RFUiApCiAgewoJLyoJRGUtcmVnaXN0ZXIgc2VydmljZSBuYW1lCgkgKi8KICAgICAgICBDbWRfZmxhZ3MgPSBDbWRfZmxhZ3MgXiBETlNfVU5SRUdJU1RFUjsKICAgICAgICBpZiAoIHJlZmVyZW5jZV9pbnN0LT5TZXJ2aWNlTmFtZXMgPT0gTlVMTCApCiAgICAgICAgeyAKICAgICAgICAgICAgICAgIC8qICAgICAgZWFzeSBvbmUgLSBhbHJlYWR5IGRvbmUKICAgICAgICAgICAgICAgICAqLwogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgICAgIC8qICAgICAgbW9yZSBkaWZmaWN1bHQgLSBtdXN0IGhvb2sgb3V0IG9mIHNlcXVlbmNlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHRoaXNfaW5zdGFuY2UgPSByZWZlcmVuY2VfaW5zdDsKICAgICAgICAgICAgICAgIGlmICh0aGlzX3NlcnZpY2UgPT0gTlVMTCApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qICAgICAgU2VydmljZSBuYW1lIG5vdCAgcmVnaXN0ZXJlZCAhIQogICAgICAgICAgICAgICAgICAgICAgICAgKiAgICAgICB3aGF0IGRvIHdlIGRvID8KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gZGUtcmVnaXN0ZXIgdW5yZWdpc3RlcmVkIHNlcnZpY2UgICEhXG4iKTsKICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiAgICAgIERlbGV0ZSB0aGlzIG9uZSBmcm9tIHRoZSBjaGFpbgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAJCWlmICggcmVmZXJlbmNlX2luc3QtPlNlcnZpY2VOYW1lcyA9PSB0aGlzX3NlcnZpY2UgKQogICAgICAgIAkJewogICAgICAgICAgICAgICAgCQkvKiBzcGVjaWFsIGNhc2UgLSB0aGUgZmlyc3Qvb25seSBlbnRyeQogICAgICAgICAgICAgICAgCQkqLwogICAgICAgICAgICAgICAgCQlyZWZlcmVuY2VfaW5zdC0+U2VydmljZU5hbWVzID0gdGhpc19zZXJ2aWNlLT5uZXh0OwogICAgICAgIAkJfSBlbHNlCiAgICAgICAgCQl7CiAgICAgICAgICAgICAgICAJCS8qIGdlbmVyYWwgY2FzZQogICAgICAgICAgICAgICAgCQkqLwogICAgICAgICAgICAgICAgCQlyZWZlcmVuY2Vfc2VydmljZS0+bmV4dD0gcmVmZXJlbmNlX2luc3QtPlNlcnZpY2VOYW1lczsKICAgICAgICAgICAgICAgIAkJd2hpbGUgKCByZWZlcmVuY2Vfc2VydmljZS0+bmV4dCE9IHRoaXNfc2VydmljZSApCiAgICAgICAgICAgICAgICAJCXsKICAgICAgICAgICAgICAgICAgICAgICAgCQlyZWZlcmVuY2Vfc2VydmljZSA9IHJlZmVyZW5jZV9zZXJ2aWNlLT5uZXh0OwogICAgICAgICAgICAgICAgCQl9CiAgICAgICAgICAgICAgICAJCXJlZmVyZW5jZV9zZXJ2aWNlLT5uZXh0PSB0aGlzX3NlcnZpY2UtPm5leHQ7CgkJCX0KCQkJRGRlUmVsZWFzZUF0b20ocmVmZXJlbmNlX2luc3QsdGhpc19zZXJ2aWNlLT5oc3opOwogICAgICAgIAkJSGVhcEZyZWUoU3lzdGVtSGVhcCwgMCwgdGhpc19zZXJ2aWNlKTsgLyogZmluaXNoZWQgLSByZWxlYXNlIGhlYXAgc3BhY2UgKi8KICAgICAgICAJfQogCX0KICB9CiAgaWYgKCAoIENtZF9mbGFncyAmJiBETlNfRklMVEVST0ZGICkgIT0gRE5TX0ZJTFRFUk9GRiApCiAgewoJLyoJU2V0IGZpbHRlciBmbGFncyBvbiB0byBob2xkIG5vdGlmaWNhdGlvbnMgb2YgY29ubmVjdGlvbgoJICoKCSAqCXRlc3QgY29kZWQgdGhpcyB3YXkgYXMgdGhpcyBpcyB0aGUgZGVmYXVsdCBzZXR0aW5nCgkgKi8KCUNtZF9mbGFncyA9IENtZF9mbGFncyBeIEROU19GSUxURVJPTjsKCWlmICggKCByZWZlcmVuY2VfaW5zdC0+U2VydmljZU5hbWVzID09IE5VTEwgKSB8fCAoIHRoaXNfc2VydmljZSA9PSBOVUxMKSApCgl7CgkJLyogIHRyeWluZyB0byBmaWx0ZXIgd2hlcmUgbm8gc2VydmljZSBuYW1lcyAhIQoJCSAqLwoJCXJlZmVyZW5jZV9pbnN0LT5MYXN0X0Vycm9yID0gRE1MRVJSX0RMTF9VU0FHRTsKICAJCVJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHRoaXNfaW5zdGFuY2UpOwoJCXJldHVybiBGQUxTRTsKCX0gZWxzZSAKCXsKCQl0aGlzX3NlcnZpY2UtPkZpbHRlck9uID0gVFJVRTsKCX0KICB9CiAgaWYgKCAoIENtZF9mbGFncyAmJiBETlNfRklMVEVST0ZGICkgPT0gRE5TX0ZJTFRFUk9GRiApCiAgewoJLyoJU2V0IGZpbHRlciBmbGFncyBvbiB0byBob2xkIG5vdGlmaWNhdGlvbnMgb2YgY29ubmVjdGlvbgoJICovCglDbWRfZmxhZ3MgPSBDbWRfZmxhZ3MgXiBETlNfRklMVEVST0ZGOwoJaWYgKCAoIHJlZmVyZW5jZV9pbnN0LT5TZXJ2aWNlTmFtZXMgPT0gTlVMTCApIHx8ICggdGhpc19zZXJ2aWNlID09IE5VTEwpICkKCXsKCQkvKiAgdHJ5aW5nIHRvIGZpbHRlciB3aGVyZSBubyBzZXJ2aWNlIG5hbWVzICEhCgkJICovCgkJcmVmZXJlbmNlX2luc3QtPkxhc3RfRXJyb3IgPSBETUxFUlJfRExMX1VTQUdFOwogIAkJUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UsdGhpc19pbnN0YW5jZSk7CgkJcmV0dXJuIEZBTFNFOwoJfSBlbHNlIAoJewoJCXRoaXNfc2VydmljZS0+RmlsdGVyT24gPSBGQUxTRTsKCX0KICB9CiAgUmVsZWFzZV9yZXNlcnZlZF9tdXRleChoYW5kbGVfbXV0ZXgsImhhbmRsZV9tdXRleCIsRkFMU0UsRkFMU0UsdGhpc19pbnN0YW5jZSk7CiAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVHZXRMYXN0RXJyb3IxNiAgKERERU1MLjIwKQogKi8KVUlOVDE2IFdJTkFQSSBEZGVHZXRMYXN0RXJyb3IxNiggRFdPUkQgaWRJbnN0ICkKewogICAgcmV0dXJuIChVSU5UMTYpRGRlR2V0TGFzdEVycm9yKCBpZEluc3QgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGRlR2V0TGFzdEVycm9yIFtVU0VSMzIuMTAzXSAgR2V0cyBtb3N0IHJlY2VudCBlcnJvciBjb2RlCiAqCiAqIFBBUkFNUwogKiAgICBpZEluc3QgW0ldIEluc3RhbmNlIGlkZW50aWZpZXIKICoKICogUkVUVVJOUwogKiAgICBMYXN0IGVycm9yIGNvZGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICAgQ2hhbmdlIEhpc3RvcnkKICoKICogIFZuICAgICAgIERhdGUgICAgICAgQXV0aG9yICAgICAgICAgICAgICAgICAgQ29tbWVudAogKgogKiAgMS4wICAgICAgPyAgICAgICAgICAgID8gICAgICAgICAgICAgICAgU3R1YgogKiAgMS4xICAgICAgQXByIDE5OTkgIEtlaXRoIE1hdHRoZXdzICAgICAgQWRkZWQgcmVzcG9uc2UgZm9yIG5vbi1leGlzdGVudCBpbnN0YW5jZSAodW5pbml0aWFsaXNlZCBpbnN0YW5jZSAwCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgYnkgc29tZSBNUyBwcm9ncmFtcyBmb3IgdW5mYXRob21hYmxlIHJlYXNvbnMpCiAqICAxLjIJICAgICBNYXkgMTk5OSAgS2VpdGggTWF0dGhld3MJICAgQWRkZWQgaW50ZXJyb2dhdGlvbiBvZiBMYXN0X0Vycm9yIGZvciBpbnN0YW5jZSBoYW5kbGUgd2hlcmUgZm91bmQuCiAqCiAqLwpVSU5UIFdJTkFQSSBEZGVHZXRMYXN0RXJyb3IoIERXT1JEIGlkSW5zdCApCnsKICAgIERXT1JECWVycm9yX2NvZGU7CiAgICBEREVfSEFORExFX0VOVFJZICpyZWZlcmVuY2VfaW5zdDsKCiAgICBGSVhNRSgiKCVsZCk6IHN0dWJcbiIsaWRJbnN0KTsKCiAgICBpZiAoIERERV9NYXhfQXNzaWduZWRfSW5zdGFuY2UgPT0gMCApCiAgICB7CiAgICAgICAgICAvKiAgTm90aGluZyBoYXMgYmVlbiBpbml0aWFsaXNlZCAtIGV4aXQgbm93ICEgKi8KICAgICAgICAgIHJldHVybiBETUxFUlJfRExMX05PVF9JTklUSUFMSVpFRDsKICAgIH0KCglpZiAoICFXYWl0Rm9yTXV0ZXgoaGFuZGxlX211dGV4KSApCgl7CgkJcmV0dXJuIERNTEVSUl9TWVNfRVJST1I7Cgl9CgogICBUUkFDRSgiSGFuZGxlIE11dGV4IGNyZWF0ZWQvcmVzZXJ2ZWRcbiIpOwoKICAgLyogIEZpcnN0IGNoZWNrIGluc3RhbmNlCiAgICovCiAgIHJlZmVyZW5jZV9pbnN0ID0gRmluZF9JbnN0YW5jZV9FbnRyeShpZEluc3QpOwogICBpZiAgKHJlZmVyZW5jZV9pbnN0ID09IE5VTEwpIAogICB7CiAgICAgICAgaWYgKCBSZWxlYXNlX3Jlc2VydmVkX211dGV4KGhhbmRsZV9tdXRleCwiaGFuZGxlX211dGV4IixGQUxTRSxGQUxTRSxyZWZlcmVuY2VfaW5zdCkpIHJldHVybiBUUlVFOwogICAgICAgICAgLyogIE5vdGhpbmcgaGFzIGJlZW4gaW5pdGlhbGlzZWQgLSBleGl0IG5vdyAhIGNhbiByZXR1cm4gVFJVRSBzaW5jZSBlZmZlY3QgaXMgdGhlIHNhbWUgKi8KICAgICAgICAgIHJldHVybiBETUxFUlJfRExMX05PVF9JTklUSUFMSVpFRDsKCiAgIH0KICAgIGVycm9yX2NvZGUgPSByZWZlcmVuY2VfaW5zdC0+TGFzdF9FcnJvcjsKICAgIHJlZmVyZW5jZV9pbnN0LT5MYXN0X0Vycm9yID0gMDsKICAgIFJlbGVhc2VfcmVzZXJ2ZWRfbXV0ZXgoaGFuZGxlX211dGV4LCJoYW5kbGVfbXV0ZXgiLEZBTFNFLEZBTFNFLHJlZmVyZW5jZV9pbnN0KTsKICAgcmV0dXJuIGVycm9yX2NvZGU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBEZGVDbXBTdHJpbmdIYW5kbGVzMTYgKERERU1MLjM2KQogKi8KaW50IFdJTkFQSSBEZGVDbXBTdHJpbmdIYW5kbGVzMTYoIEhTWiBoc3oxLCBIU1ogaHN6MiApCnsKICAgICByZXR1cm4gRGRlQ21wU3RyaW5nSGFuZGxlcyhoc3oxLCBoc3oyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRGRlQ21wU3RyaW5nSGFuZGxlcyAoVVNFUjMyLjkxKQogKgogKiBDb21wYXJlcyB0aGUgdmFsdWUgb2YgdHdvIHN0cmluZyBoYW5kbGVzLiAgVGhpcyBjb21wYXJpc29uIGlzCiAqIG5vdCBjYXNlIHNlbnNpdGl2ZS4KICoKICogUmV0dXJuczoKICogLTEgVGhlIHZhbHVlIG9mIGhzejEgaXMgemVybyBvciBsZXNzIHRoYW4gaHN6MgogKiAwICBUaGUgdmFsdWVzIG9mIGhzeiAxIGFuZCAyIGFyZSB0aGUgc2FtZSBvciBib3RoIHplcm8uCiAqIDEgIFRoZSB2YWx1ZSBvZiBoc3oyIGlzIHplcm8gb2YgbGVzcyB0aGFuIGhzejEKICovCmludCBXSU5BUEkgRGRlQ21wU3RyaW5nSGFuZGxlcyggSFNaIGhzejEsIEhTWiBoc3oyICkKewogICAgQ0hBUiBwc3oxW01BWF9CVUZGRVJfTEVOXTsKICAgIENIQVIgcHN6MltNQVhfQlVGRkVSX0xFTl07CiAgICBpbnQgcmV0ID0gMDsKICAgIGludCByZXQxLCByZXQyOwoKICAgIFRSQUNFKCJoYW5kbGUgMSwgaGFuZGxlIDJcbiIgKTsKCiAgICByZXQxID0gR2xvYmFsR2V0QXRvbU5hbWVBKCBoc3oxLCBwc3oxLCBNQVhfQlVGRkVSX0xFTiApOwogICAgcmV0MiA9IEdsb2JhbEdldEF0b21OYW1lQSggaHN6MiwgcHN6MiwgTUFYX0JVRkZFUl9MRU4gKTsKICAgIC8qIE1ha2Ugc3VyZSB3ZSBmb3VuZCBib3RoIHN0cmluZ3MuCiAgICAgKi8KICAgIGlmKCByZXQxID09IDAgJiYgcmV0MiA9PSAwICkKICAgIHsKICAgICAgICAvKiBJZiBib3RoIGFyZSBub3QgZm91bmQsIHJldHVybiBib3RoICAiemVybyBzdHJpbmdzIi4KICAgICAgICAgKi8KICAgICAgICByZXQgPSAwOwogICAgfQogICAgZWxzZSBpZiggcmV0MSA9PSAwICkKICAgIHsKICAgICAgICAvKiBJZiBoc3oxIGlzIGEgbm90IGZvdW5kLCByZXR1cm4gaHN6MSBpcyAiemVybyBzdHJpbmciLgogICAgICAgICAqLwogICAgICAgIHJldCA9IC0xOwogICAgfQogICAgZWxzZSBpZiggcmV0MiA9PSAwICkKICAgIHsKICAgICAgICAvKiBJZiBoc3oyIGlzIGEgbm90IGZvdW5kLCByZXR1cm4gaHN6MiBpcyAiemVybyBzdHJpbmciLgogICAgICAgICAqLwogICAgICAgIHJldCA9IDE7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogQ29tcGFyZSB0aGUgdHdvIHN0cmluZ3Mgd2UgZ290ICggY2FzZSBpbnNlbnNpdGl2ZSApLgogICAgICAgICAqLwogICAgICAgIHJldCA9IHN0cmNhc2VjbXAoIHBzejEsIHBzejIgKTsKICAgICAgICAvKiBTaW5jZSBzdHJjbXAgcmV0dXJucyBhbnkgbnVtYmVyIHNtYWxsZXIgdGhhbgogICAgICAgICAqIDAgd2hlbiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGZvdW5kIHRvIGJlIGxlc3MgdGhhbgogICAgICAgICAqIHRoZSBzZWNvbmQgb25lIHdlIG11c3QgbWFrZSBzdXJlIHdlIGFyZSByZXR1cm5pbmcKICAgICAgICAgKiB0aGUgcHJvcGVyIHZhbHVlcy4KICAgICAgICAgKi8KICAgICAgICBpZiggcmV0IDwgMCApCiAgICAgICAgewogICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggcmV0ID4gMCApCiAgICAgICAgewogICAgICAgICAgICByZXQgPSAxOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBQYWNrRERFbFBhcmFtIChVU0VSMzIuNDE0KQogKgogKiBSRVRVUk5TCiAqICAgc3VjY2Vzczogbm9uemVybwogKiAgIGZhaWx1cmU6IHplcm8KICovClVJTlQgV0lOQVBJIFBhY2tEREVsUGFyYW0oVUlOVCBtc2csIFVJTlQgdWlMbywgVUlOVCB1aUhpKQp7CiAgICBGSVhNRSgic3R1Yi5cbiIpOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBVbnBhY2tEREVsUGFyYW0gKFVTRVIzMi41NjIpCiAqCiAqIFJFVFVSTlMKICogICBzdWNjZXNzOiBub256ZXJvCiAqICAgZmFpbHVyZTogemVybwogKi8KVUlOVCBXSU5BUEkgVW5wYWNrRERFbFBhcmFtKFVJTlQgbXNnLCBVSU5UIGxQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAqdWlMbywgVUlOVCAqdWlIaSkKewogICAgRklYTUUoInN0dWIuXG4iKTsKICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgRnJlZURERWxQYXJhbSAoVVNFUjMyLjIwNCkKICoKICogUkVUVVJOUwogKiAgIHN1Y2Nlc3M6IG5vbnplcm8KICogICBmYWlsdXJlOiB6ZXJvCiAqLwpVSU5UIFdJTkFQSSBGcmVlRERFbFBhcmFtKFVJTlQgbXNnLCBVSU5UIGxQYXJhbSkKewogICAgRklYTUUoInN0dWIuXG4iKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICBSZXVzZURERWxQYXJhbSAoVVNFUjMyLjQ0NikKICoKICovClVJTlQgV0lOQVBJIFJldXNlRERFbFBhcmFtKFVJTlQgbFBhcmFtLCBVSU5UIG1zZ0luLCBVSU5UIG1zZ091dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHVpTGksIFVJTlQgdWlIaSkKewogICAgRklYTUUoInN0dWIuXG4iKTsKICAgIHJldHVybiAwOwp9IAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGRlUXVlcnlDb252SW5mbzE2IChEREVNTC45KQogKgogKi8KVUlOVDE2IFdJTkFQSSBEZGVRdWVyeUNvbnZJbmZvMTYoIEhDT05WIGhjb252LCBEV09SRCBpZFRyYW5zYWN0aW9uICwgTFBDT05WSU5GTzE2IGxwQ29udkluZm8pCnsKCUZJWE1FKCJzdHViLlxuIik7CglyZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURkZVF1ZXJ5Q29udkluZm8gKFVTRVIzMi4xMTEpCiAqCiAqLwpVSU5UIFdJTkFQSSBEZGVRdWVyeUNvbnZJbmZvKCBIQ09OViBoY29udiwgRFdPUkQgaWRUcmFuc2FjdGlvbiAsIExQQ09OVklORk8gbHBDb252SW5mbykKewoJRklYTUUoInN0dWIuXG4iKTsKCXJldHVybiAwOwp9Cg==