LyoNCiAgICBGcmVlUlRPUyBWNy41LjEgLSBDb3B5cmlnaHQgKEMpIDIwMTMgUmVhbCBUaW1lIEVuZ2luZWVycyBMdGQuDQoNCiAgICBWSVNJVCBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZyBUTyBFTlNVUkUgWU9VIEFSRSBVU0lORyBUSEUgTEFURVNUIFZFUlNJT04uDQoNCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKg0KICAgICAqICAgIEZyZWVSVE9TIHByb3ZpZGVzIGNvbXBsZXRlbHkgZnJlZSB5ZXQgcHJvZmVzc2lvbmFsbHkgZGV2ZWxvcGVkLCAgICAqDQogICAgICogICAgcm9idXN0LCBzdHJpY3RseSBxdWFsaXR5IGNvbnRyb2xsZWQsIHN1cHBvcnRlZCwgYW5kIGNyb3NzICAgICAgICAgICoNCiAgICAgKiAgICBwbGF0Zm9ybSBzb2Z0d2FyZSB0aGF0IGhhcyBiZWNvbWUgYSBkZSBmYWN0byBzdGFuZGFyZC4gICAgICAgICAgICAgKg0KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQogICAgICogICAgSGVscCB5b3Vyc2VsZiBnZXQgc3RhcnRlZCBxdWlja2x5IGFuZCBzdXBwb3J0IHRoZSBGcmVlUlRPUyAgICAgICAgICoNCiAgICAgKiAgICBwcm9qZWN0IGJ5IHB1cmNoYXNpbmcgYSBGcmVlUlRPUyB0dXRvcmlhbCBib29rLCByZWZlcmVuY2UgICAgICAgICAgKg0KICAgICAqICAgIG1hbnVhbCwgb3IgYm90aCBmcm9tOiBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZy9Eb2N1bWVudGF0aW9uICAgICAgICAqDQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAgKiAgICBUaGFuayB5b3UhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKg0KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoNCiAgICBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgRnJlZVJUT1MgZGlzdHJpYnV0aW9uLg0KDQogICAgRnJlZVJUT1MgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdCB1bmRlcg0KICAgIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKHZlcnNpb24gMikgYXMgcHVibGlzaGVkIGJ5IHRoZQ0KICAgIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiA+PiFBTkQgTU9ESUZJRUQgQlkhPDwgdGhlIEZyZWVSVE9TIGV4Y2VwdGlvbi4NCg0KICAgID4+ISBOT1RFOiBUaGUgbW9kaWZpY2F0aW9uIHRvIHRoZSBHUEwgaXMgaW5jbHVkZWQgdG8gYWxsb3cgeW91IHRvIGRpc3RyaWJ1dGUNCiAgICA+PiEgYSBjb21iaW5lZCB3b3JrIHRoYXQgaW5jbHVkZXMgRnJlZVJUT1Mgd2l0aG91dCBiZWluZyBvYmxpZ2VkIHRvIHByb3ZpZGUNCiAgICA+PiEgdGhlIHNvdXJjZSBjb2RlIGZvciBwcm9wcmlldGFyeSBjb21wb25lbnRzIG91dHNpZGUgb2YgdGhlIEZyZWVSVE9TDQogICAgPj4hIGtlcm5lbC4NCg0KICAgIEZyZWVSVE9TIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQ0KICAgIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MNCiAgICBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBGdWxsIGxpY2Vuc2UgdGV4dCBpcyBhdmFpbGFibGUgZnJvbSB0aGUgZm9sbG93aW5nDQogICAgbGluazogaHR0cDovL3d3dy5mcmVlcnRvcy5vcmcvYTAwMTE0Lmh0bWwNCg0KICAgIDEgdGFiID09IDQgc3BhY2VzIQ0KDQogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAgKiAgICBIYXZpbmcgYSBwcm9ibGVtPyAgU3RhcnQgYnkgcmVhZGluZyB0aGUgRkFRICJNeSBhcHBsaWNhdGlvbiBkb2VzICAgKg0KICAgICAqICAgIG5vdCBydW4sIHdoYXQgY291bGQgYmUgd3Jvbmc/IiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAgKiAgICBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZy9GQVFIZWxwLmh0bWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKg0KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoNCiAgICBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZyAtIERvY3VtZW50YXRpb24sIGJvb2tzLCB0cmFpbmluZywgbGF0ZXN0IHZlcnNpb25zLA0KICAgIGxpY2Vuc2UgYW5kIFJlYWwgVGltZSBFbmdpbmVlcnMgTHRkLiBjb250YWN0IGRldGFpbHMuDQoNCiAgICBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZy9wbHVzIC0gQSBzZWxlY3Rpb24gb2YgRnJlZVJUT1MgZWNvc3lzdGVtIHByb2R1Y3RzLA0KICAgIGluY2x1ZGluZyBGcmVlUlRPUytUcmFjZSAtIGFuIGluZGlzcGVuc2FibGUgcHJvZHVjdGl2aXR5IHRvb2wsIGEgRE9TDQogICAgY29tcGF0aWJsZSBGQVQgZmlsZSBzeXN0ZW0sIGFuZCBvdXIgdGlueSB0aHJlYWQgYXdhcmUgVURQL0lQIHN0YWNrLg0KDQogICAgaHR0cDovL3d3dy5PcGVuUlRPUy5jb20gLSBSZWFsIFRpbWUgRW5naW5lZXJzIGx0ZCBsaWNlbnNlIEZyZWVSVE9TIHRvIEhpZ2gNCiAgICBJbnRlZ3JpdHkgU3lzdGVtcyB0byBzZWxsIHVuZGVyIHRoZSBPcGVuUlRPUyBicmFuZC4gIExvdyBjb3N0IE9wZW5SVE9TDQogICAgbGljZW5zZXMgb2ZmZXIgdGlja2V0ZWQgc3VwcG9ydCwgaW5kZW1uaWZpY2F0aW9uIGFuZCBtaWRkbGV3YXJlLg0KDQogICAgaHR0cDovL3d3dy5TYWZlUlRPUy5jb20gLSBIaWdoIEludGVncml0eSBTeXN0ZW1zIGFsc28gcHJvdmlkZSBhIHNhZmV0eQ0KICAgIGVuZ2luZWVyZWQgYW5kIGluZGVwZW5kZW50bHkgU0lMMyBjZXJ0aWZpZWQgdmVyc2lvbiBmb3IgdXNlIGluIHNhZmV0eSBhbmQNCiAgICBtaXNzaW9uIGNyaXRpY2FsIGFwcGxpY2F0aW9ucyB0aGF0IHJlcXVpcmUgcHJvdmFibGUgZGVwZW5kYWJpbGl0eS4NCg0KICAgIDEgdGFiID09IDQgc3BhY2VzIQ0KKi8NCg0KLyogU3RhbmRhcmQgaW5jbHVkZXMuICovDQojaW5jbHVkZSA8c3RyaW5nLmg+DQoNCi8qIFNjaGVkdWxlciBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJGcmVlUlRPUy5oIg0KI2luY2x1ZGUgInNlbXBoci5oIg0KI2luY2x1ZGUgInRhc2suaCINCg0KLyogRGVtbyBhcHBsaWNhdGlvbiBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJTQU03X0VNQUMuaCINCg0KLyogdUlQIGluY2x1ZGVzLiAqLw0KI2luY2x1ZGUgInVpcC5oIg0KDQovKiBIYXJkd2FyZSBzcGVjaWZpYyBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJFbWFjLmgiDQojaW5jbHVkZSAibWlpLmgiDQojaW5jbHVkZSAiQVQ5MVNBTTdYMjU2LmgiDQoNCg0KLyogVVNFX1JNSUlfSU5URVJGQUNFIG11c3QgYmUgZGVmaW5lZCBhcyAxIHRvIHVzZSBhbiBSTUlJIGludGVyZmFjZSwgb3IgMA0KdG8gdXNlIGFuIE1JSSBpbnRlcmZhY2UuICovDQojZGVmaW5lIFVTRV9STUlJX0lOVEVSRkFDRSAwDQoNCi8qIFRoZSBidWZmZXIgYWRkcmVzc2VzIHdyaXR0ZW4gaW50byB0aGUgZGVzY3JpcHRvcnMgbXVzdCBiZSBhbGlnbmVkIHNvIHRoZQ0KbGFzdCBmZXcgYml0cyBhcmUgemVyby4gIFRoZXNlIGJpdHMgaGF2ZSBzcGVjaWFsIG1lYW5pbmcgZm9yIHRoZSBFTUFDDQpwZXJpcGhlcmFsIGFuZCBjYW5ub3QgYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBhZGRyZXNzLiAqLw0KI2RlZmluZSBlbWFjQUREUkVTU19NQVNLCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSAweEZGRkZGRkZDICkNCg0KLyogQml0IHVzZWQgd2l0aGluIHRoZSBhZGRyZXNzIHN0b3JlZCBpbiB0aGUgZGVzY3JpcHRvciB0byBtYXJrIHRoZSBsYXN0DQpkZXNjcmlwdG9yIGluIHRoZSBhcnJheS4gKi8NCiNkZWZpbmUgZW1hY1JYX1dSQVBfQklUCQkJCSggKCB1bnNpZ25lZCBsb25nICkgMHgwMiApDQoNCi8qIEJpdCB1c2VkIHdpdGhpbiB0aGUgVHggZGVzY3JpcHRvciBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUNCmRlc2NyaXB0b3IgaXMgdW5kZXIgdGhlIGNvbnRyb2wgb2YgdGhlIEVNQUMgb3IgdGhlIHNvZnR3YXJlLiAqLw0KI2RlZmluZSBlbWFjVFhfQlVGX1VTRUQJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSAweDgwMDAwMDAwICkNCg0KLyogQSBzaG9ydCBkZWxheSBpcyB1c2VkIHRvIHdhaXQgZm9yIGEgYnVmZmVyIHRvIGJlY29tZSBhdmFpbGFibGUsIHNob3VsZA0Kb25lIG5vdCBiZSBpbW1lZGlhdGVseSBhdmFpbGFibGUgd2hlbiB0cnlpbmcgdG8gdHJhbnNtaXQgYSBmcmFtZS4gKi8NCiNkZWZpbmUgZW1hY0JVRkZFUl9XQUlUX0RFTEFZCQkoIDIgKQ0KI2RlZmluZSBlbWFjTUFYX1dBSVRfQ1lDTEVTCQkJKCBjb25maWdUSUNLX1JBVEVfSFogLyA0MCApDQoNCi8qIE1pc2MgZGVmaW5lcy4gKi8NCiNkZWZpbmUgZW1hY0lOVEVSUlVQVF9MRVZFTAkJCSggNSApDQojZGVmaW5lIGVtYWNOT19ERUxBWQkJCQkoIDAgKQ0KI2RlZmluZSBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUJKCA1NCApDQojZGVmaW5lIGVtYWNQSFlfSU5JVF9ERUxBWQkJCSggNTAwMCAvIHBvcnRUSUNLX1JBVEVfTVMgKQ0KI2RlZmluZSBlbWFjUkVTRVRfS0VZCQkJCSggKCB1bnNpZ25lZCBsb25nICkgMHhBNTAwMDAwMCApDQojZGVmaW5lIGVtYWNSRVNFVF9MRU5HVEgJCQkoICggdW5zaWduZWQgbG9uZyApICggMHgwMSA8PCA4ICkgKQ0KDQovKiBUaGUgQXRtZWwgaGVhZGVyIGZpbGUgb25seSBkZWZpbmVzIHRoZSBUWCBmcmFtZSBsZW5ndGggbWFzay4gKi8NCiNkZWZpbmUgZW1hY1JYX0xFTkdUSF9GUkFNRQkJCSggMHhmZmYgKQ0KDQovKiBQZXJpcGhlcmFsIHNldHVwIGZvciB0aGUgRU1BQy4gKi8NCiNkZWZpbmUgZW1hY1BFUklQSEVSQUxfQV9TRVRVUCAJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIyX0VUWDAJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjEyX0VUWEVSCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjE2X0VDT0wJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjExX0VUWDMJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjZfRVJYMQkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCMTVfRVJYRFYJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCMTNfRVJYMgkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCM19FVFgxCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEI4X0VNREMJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjVfRVJYMAkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCMTRfRVJYMwkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCNF9FQ1JTX0VDUlNEVgkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjFfRVRYRU4JCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjEwX0VUWDIJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjBfRVRYQ0tfRVJFRkNLCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCOV9FTURJTwkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCN19FUlhFUgkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCMTdfRVJYQ0sJCSk7DQoNCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQovKg0KICogUHJvdG90eXBlIGZvciB0aGUgRU1BQyBpbnRlcnJ1cHQgZnVuY3Rpb24gLSBjYWxsZWQgYnkgdGhlIGFzbSB3cmFwcGVyLg0KICovDQpleHRlcm4gdm9pZCB2RU1BQ0lTUl9XcmFwcGVyKCB2b2lkICkgX19hdHRyaWJ1dGVfXygobmFrZWQpKTsNCg0KLyoNCiAqIEluaXRpYWxpc2UgYm90aCB0aGUgVHggYW5kIFJ4IGRlc2NyaXB0b3JzIHVzZWQgYnkgdGhlIEVNQUMuDQogKi8NCnN0YXRpYyB2b2lkIHBydlNldHVwRGVzY3JpcHRvcnModm9pZCk7DQoNCi8qDQogKiBXcml0ZSBvdXIgTUFDIGFkZHJlc3MgaW50byB0aGUgRU1BQy4gIFRoZSBNQUMgYWRkcmVzcyBpcyBzZXQgYXMgb25lIG9mIHRoZQ0KICogdWlwIG9wdGlvbnMuDQogKi8NCnN0YXRpYyB2b2lkIHBydlNldHVwTUFDQWRkcmVzcyggdm9pZCApOw0KDQovKg0KICogQ29uZmlndXJlIHRoZSBFTUFDIGFuZCBBSUMgZm9yIEVNQUMgaW50ZXJydXB0cy4NCiAqLw0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBFTUFDSW50ZXJydXB0KCB2b2lkICk7DQoNCi8qDQogKiBTb21lIGluaXRpYWxpc2F0aW9uIGZ1bmN0aW9ucyB0YWtlbiBmcm9tIHRoZSBBdG1lbCBFTUFDIHNhbXBsZSBjb2RlLg0KICovDQpzdGF0aWMgdm9pZCB2UmVhZFBIWSggdW5zaWduZWQgY2hhciB1Y1BIWUFkZHJlc3MsIHVuc2lnbmVkIGNoYXIgdWNBZGRyZXNzLCB1bnNpZ25lZCBsb25nICpwdWxWYWx1ZSApOw0KI2lmIFVTRV9STUlJX0lOVEVSRkFDRSAhPSAxDQoJc3RhdGljIHZvaWQgdldyaXRlUEhZKCB1bnNpZ25lZCBjaGFyIHVjUEhZQWRkcmVzcywgdW5zaWduZWQgY2hhciB1Y0FkZHJlc3MsIHVuc2lnbmVkIGxvbmcgdWxWYWx1ZSk7DQojZW5kaWYNCnN0YXRpYyBwb3J0QkFTRV9UWVBFIHhHZXRMaW5rU3BlZWQoIHZvaWQgKTsNCnN0YXRpYyBwb3J0QkFTRV9UWVBFIHBydlByb2JlUEhZKCB2b2lkICk7DQoNCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQovKiBCdWZmZXIgd3JpdHRlbiB0byBieSB0aGUgRU1BQyBETUEuICBNdXN0IGJlIGFsaWduZWQgYXMgZGVzY3JpYmVkIGJ5IHRoZQ0KY29tbWVudCBhYm92ZSB0aGUgZW1hY0FERFJFU1NfTUFTSyBkZWZpbml0aW9uLiAqLw0KI3ByYWdtYSBkYXRhX2FsaWdubWVudD04DQpzdGF0aWMgdm9sYXRpbGUgY2hhciBwY1J4QnVmZmVyWyBOQl9SWF9CVUZGRVJTICogRVRIX1JYX0JVRkZFUl9TSVpFIF07DQoNCi8qIEJ1ZmZlciByZWFkIGJ5IHRoZSBFTUFDIERNQS4gIE11c3QgYmUgYWxpZ25lZCBhcyBkZXNjcmliZWQgYnkgaGUgY29tbWVudA0KYWJvdmUgdGhlIGVtYWNBRERSRVNTX01BU0sgZGVmaW5pdGlvbi4gKi8NCiNwcmFnbWEgZGF0YV9hbGlnbm1lbnQ9OA0Kc3RhdGljIGNoYXIgcGNUeEJ1ZmZlclsgTkJfVFhfQlVGRkVSUyAqIEVUSF9UWF9CVUZGRVJfU0laRSBdOw0KDQovKiBEZXNjcmlwdG9ycyB1c2VkIHRvIGNvbW11bmljYXRlIGJldHdlZW4gdGhlIHByb2dyYW0gYW5kIHRoZSBFTUFDIHBlcmlwaGVyYWwuDQpUaGVzZSBkZXNjcmlwdG9ycyBob2xkIHRoZSBsb2NhdGlvbnMgYW5kIHN0YXRlIG9mIHRoZSBSeCBhbmQgVHggYnVmZmVycy4gKi8NCnN0YXRpYyB2b2xhdGlsZSBBVDkxU19UeFRkRGVzY3JpcHRvciB4VHhEZXNjcmlwdG9yc1sgTkJfVFhfQlVGRkVSUyBdOw0Kc3RhdGljIHZvbGF0aWxlIEFUOTFTX1J4VGREZXNjcmlwdG9yIHhSeERlc2NyaXB0b3JzWyBOQl9SWF9CVUZGRVJTIF07DQoNCi8qIFRoZSBJUCBhbmQgRXRoZXJuZXQgYWRkcmVzc2VzIGFyZSByZWFkIGZyb20gdGhlIHVJUCBzZXR1cC4gKi8NCmNvbnN0IGNoYXIgY01BQ0FkZHJlc3NbIDYgXSA9IHsgdWlwTUFDX0FERFIwLCB1aXBNQUNfQUREUjEsIHVpcE1BQ19BRERSMiwgdWlwTUFDX0FERFIzLCB1aXBNQUNfQUREUjQsIHVpcE1BQ19BRERSNSB9Ow0KY29uc3QgdW5zaWduZWQgY2hhciB1Y0lQQWRkcmVzc1sgNCBdICA9IHsgdWlwSVBfQUREUjAsIHVpcElQX0FERFIxLCB1aXBJUF9BRERSMiwgdWlwSVBfQUREUjMgfTsNCg0KLyogVGhlIHNlbWFwaG9yZSB1c2VkIGJ5IHRoZSBFTUFDIElTUiB0byB3YWtlIHRoZSBFTUFDIHRhc2suICovDQpzdGF0aWMgeFNlbWFwaG9yZUhhbmRsZSB4U2VtYXBob3JlID0gTlVMTDsNCg0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnhTZW1hcGhvcmVIYW5kbGUgeEVNQUNJbml0KCB2b2lkICkNCnsNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJLyogRGlzYWJsZSBwdWxsIHVwIG9uIFJYRFYgPT4gUEhZIG5vcm1hbCBtb2RlIChub3QgaW4gdGVzdCBtb2RlKSwNCglQSFkgaGFzIGludGVybmFsIHB1bGwgZG93bi4gKi8NCglBVDkxQ19CQVNFX1BJT0ItPlBJT19QUFVEUiA9IDEgPDwgMTU7DQoNCgkjaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCgkgIAkvKiBQSFkgaGFzIGludGVybmFsIHB1bGwgZG93biA6IHNldCBNSUkgbW9kZS4gKi8NCgkgIAlBVDkxQ19CQVNFX1BJT0ItPlBJT19QUFVEUiA9IDEgPDwgMTY7DQoJI2VuZGlmDQoNCgkvKiBDbGVhciBQQjE4IDw9PiBQSFkgcG93ZXJkb3duLiAqLw0KICAgCUFUOTFDX0JBU0VfUElPQi0+UElPX1BFUiA9IDEgPDwgMTg7DQoJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fT0VSID0gMSA8PCAxODsNCglBVDkxQ19CQVNFX1BJT0ItPlBJT19DT0RSID0gMSA8PCAxODsNCg0KCS8qIEFmdGVyIFBIWSBwb3dlciB1cCwgaGFyZHdhcmUgcmVzZXQuICovDQoJQVQ5MUNfQkFTRV9SU1RDLT5SU1RDX1JNUiA9IGVtYWNSRVNFVF9LRVkgfCBlbWFjUkVTRVRfTEVOR1RIOw0KCUFUOTFDX0JBU0VfUlNUQy0+UlNUQ19SQ1IgPSBlbWFjUkVTRVRfS0VZIHwgQVQ5MUNfUlNUQ19FWFRSU1Q7DQoNCgkvKiBXYWl0IGZvciBoYXJkd2FyZSByZXNldCBlbmQuICovDQoJd2hpbGUoICEoIEFUOTFDX0JBU0VfUlNUQy0+UlNUQ19SU1IgJiBBVDkxQ19SU1RDX05SU1RMICkgKQ0KCXsNCgkJX19hc20gdm9sYXRpbGUgKCAiTk9QIiApOw0KCX0NCiAgICBfX2FzbSB2b2xhdGlsZSAoICJOT1AiICk7DQoNCgkvKiBTZXR1cCB0aGUgcGlucy4gKi8NCglBVDkxQ19CQVNFX1BJT0ItPlBJT19BU1IgPSBlbWFjUEVSSVBIRVJBTF9BX1NFVFVQOw0KCUFUOTFDX0JBU0VfUElPQi0+UElPX1BEUiA9IGVtYWNQRVJJUEhFUkFMX0FfU0VUVVA7DQoNCgkvKiBFbmFibGUgY29tIGJldHdlZW4gRU1BQyBQSFkuDQoNCglFbmFibGUgbWFuYWdlbWVudCBwb3J0LiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ1IgfD0gQVQ5MUNfRU1BQ19NUEU7CQ0KDQoJLyogTURDID0gTUNLLzMyLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiB8PSAoIDIgKSA8PCAxMDsJDQoNCgkvKiBXYWl0IGZvciBQSFkgYXV0byBpbml0IGVuZCAocmF0aGVyIGNydWRlIGRlbGF5ISkuICovDQoJdlRhc2tEZWxheSggZW1hY1BIWV9JTklUX0RFTEFZICk7DQoNCgkvKiBQSFkgY29uZmlndXJhdGlvbi4gKi8NCgkjaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCgl7DQoJCXVuc2lnbmVkIGxvbmcgdWxDb250cm9sOw0KDQoJCS8qIFBIWSBoYXMgaW50ZXJuYWwgcHVsbCBkb3duIDogZGlzYWJsZSBNSUkgaXNvbGF0ZS4gKi8NCgkJdlJlYWRQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfQk1DUiwgJnVsQ29udHJvbCApOw0KCQl2UmVhZFBIWSggQVQ5MUNfUEhZX0FERFIsIE1JSV9CTUNSLCAmdWxDb250cm9sICk7DQoJCXVsQ29udHJvbCAmPSB+Qk1DUl9JU09MQVRFOw0KCQl2V3JpdGVQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfQk1DUiwgdWxDb250cm9sICk7DQoJfQ0KCSNlbmRpZg0KDQoJLyogRGlzYWJsZSBtYW5hZ2VtZW50IHBvcnQgYWdhaW4uICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiAmPSB+QVQ5MUNfRU1BQ19NUEU7DQoNCgkjaWYgVVNFX1JNSUlfSU5URVJGQUNFICE9IDENCgkJLyogRW5hYmxlIEVNQUMgaW4gTUlJIG1vZGUsIGVuYWJsZSBjbG9jayBFUlhDSyBhbmQgRVRYQ0suICovDQoJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19VU1JJTyA9IEFUOTFDX0VNQUNfQ0xLRU4gOw0KCSNlbHNlDQoJCS8qIEVuYWJsZSBFTUFDIGluIFJNSUkgbW9kZSwgZW5hYmxlIFJNSUkgY2xvY2sgKDUwTUh6IGZyb20gb3NjaWxsYXRvcg0KCQlvbiBFUkZDSykuICovDQoJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19VU1JJTyA9IEFUOTFDX0VNQUNfUk1JSSB8IEFUOTFDX0VNQUNfQ0xLRU4gOw0KCSNlbmRpZg0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCS8qIFNldHVwIHRoZSBidWZmZXJzIGFuZCBkZXNjcmlwdG9ycy4gKi8NCglwcnZTZXR1cERlc2NyaXB0b3JzKCk7DQoJDQoJLyogTG9hZCBvdXIgTUFDIGFkZHJlc3MgaW50byB0aGUgRU1BQy4gKi8NCglwcnZTZXR1cE1BQ0FkZHJlc3MoKTsNCg0KCS8qIEFyZSB3ZSBjb25uZWN0ZWQ/ICovDQoJaWYoIHBydlByb2JlUEhZKCkgKQ0KCXsNCgkJLyogRW5hYmxlIHRoZSBpbnRlcnJ1cHQhICovDQoJCXBvcnRFTlRFUl9DUklUSUNBTCgpOw0KCQl7DQoJCQlwcnZTZXR1cEVNQUNJbnRlcnJ1cHQoKTsNCgkJCXZQYXNzRU1BQ1NlbWFwaG9yZSggeFNlbWFwaG9yZSApOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KDQoJcmV0dXJuIHhTZW1hcGhvcmU7DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KbG9uZyBsRU1BQ1NlbmQoIHZvaWQgKQ0Kew0Kc3RhdGljIHVuc2lnbmVkIHBvcnRCQVNFX1RZUEUgdXhUeEJ1ZmZlckluZGV4ID0gMDsNCnBvcnRCQVNFX1RZUEUgeFdhaXRDeWNsZXMgPSAwOw0KbG9uZyBsUmV0dXJuID0gcGRQQVNTOw0KY2hhciAqcGNCdWZmZXI7DQoNCgkvKiBJcyBhIGJ1ZmZlciBhdmFpbGFibGU/ICovDQoJd2hpbGUoICEoIHhUeERlc2NyaXB0b3JzWyB1eFR4QnVmZmVySW5kZXggXS5VX1N0YXR1cy5zdGF0dXMgJiBBVDkxQ19UUkFOU01JVF9PSyApICkNCgl7DQoJCS8qIFRoZXJlIGlzIG5vIHJvb20gdG8gd3JpdGUgdGhlIFR4IGRhdGEgdG8gdGhlIFR4IGJ1ZmZlci4gIFdhaXQgYQ0KCQlzaG9ydCB3aGlsZSwgdGhlbiB0cnkgYWdhaW4uICovDQoJCXhXYWl0Q3ljbGVzKys7DQoJCWlmKCB4V2FpdEN5Y2xlcyA+IGVtYWNNQVhfV0FJVF9DWUNMRVMgKQ0KCQl7DQoJCQkvKiBHaXZlIHVwLiAqLw0KCQkJbFJldHVybiA9IHBkRkFJTDsNCgkJCWJyZWFrOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdlRhc2tEZWxheSggZW1hY0JVRkZFUl9XQUlUX0RFTEFZICk7DQoJCX0NCgl9DQoNCgkvKiBsUmV0dXJuIHdpbGwgb25seSBiZSBwZFBBU1MgaWYgYSBidWZmZXIgaXMgYXZhaWxhYmxlLiAqLw0KCWlmKCBsUmV0dXJuID09IHBkUEFTUyApDQoJew0KCQkvKiBDb3B5IHRoZSBoZWFkZXJzIGludG8gdGhlIFR4IGJ1ZmZlci4gIFRoZXNlIHdpbGwgYmUgaW4gdGhlIHVJUCBidWZmZXIuICovDQoJCXBjQnVmZmVyID0gKCBjaGFyICogKSB4VHhEZXNjcmlwdG9yc1sgdXhUeEJ1ZmZlckluZGV4IF0uYWRkcjsNCgkJbWVtY3B5KCAoIHZvaWQgKiApIHBjQnVmZmVyLCAoIHZvaWQgKiApIHVpcF9idWYsIGVtYWNUT1RBTF9GUkFNRV9IRUFERVJfU0laRSApOw0KDQoJCS8qIElmIHRoZXJlIGlzIHJvb20sIGFsc28gY29weSBpbiB0aGUgYXBwbGljYXRpb24gZGF0YSBpZiBhbnkuICovDQoJCWlmKCAoIHVpcF9sZW4gPiBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgKSAmJiAoIHVpcF9sZW4gPD0gKCBFVEhfVFhfQlVGRkVSX1NJWkUgLSBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgKSApICkNCgkJew0KCQkJbWVtY3B5KCAoIHZvaWQgKiApICYoIHBjQnVmZmVyWyBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgXSApLCAoIHZvaWQgKiApIHVpcF9hcHBkYXRhLCAoIHVpcF9sZW4gLSBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgKSApOw0KCQl9DQoNCgkJLyogU2VuZC4gKi8JDQoJCXBvcnRFTlRFUl9DUklUSUNBTCgpOw0KCQl7DQoJCQlpZiggdXhUeEJ1ZmZlckluZGV4ID49ICggTkJfVFhfQlVGRkVSUyAtIDEgKSApDQoJCQl7DQoJCQkJLyogRmlsbCBvdXQgdGhlIG5lY2Vzc2FyeSBpbiB0aGUgZGVzY3JpcHRvciB0byBnZXQgdGhlIGRhdGEgc2VudC4gKi8NCgkJCQl4VHhEZXNjcmlwdG9yc1sgdXhUeEJ1ZmZlckluZGV4IF0uVV9TdGF0dXMuc3RhdHVzID0gCSggdWlwX2xlbiAmICggdW5zaWduZWQgbG9uZyApIEFUOTFDX0xFTkdUSF9GUkFNRSApDQoJCQkJCQkJCQkJCQkJCQkJCQl8IEFUOTFDX0xBU1RfQlVGRkVSDQoJCQkJCQkJCQkJCQkJCQkJCQl8IEFUOTFDX1RSQU5TTUlUX1dSQVA7DQoJCQkJdXhUeEJ1ZmZlckluZGV4ID0gMDsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkvKiBGaWxsIG91dCB0aGUgbmVjZXNzYXJ5IGluIHRoZSBkZXNjcmlwdG9yIHRvIGdldCB0aGUgZGF0YSBzZW50LiAqLw0KCQkJCXhUeERlc2NyaXB0b3JzWyB1eFR4QnVmZmVySW5kZXggXS5VX1N0YXR1cy5zdGF0dXMgPSAJKCB1aXBfbGVuICYgKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfTEVOR1RIX0ZSQU1FICkNCgkJCQkJCQkJCQkJCQkJCQkJCXwgQVQ5MUNfTEFTVF9CVUZGRVI7DQoJCQkJdXhUeEJ1ZmZlckluZGV4Kys7DQoJCQl9DQoJDQoJCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNSIHw9IEFUOTFDX0VNQUNfVFNUQVJUOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KDQoJcmV0dXJuIGxSZXR1cm47DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KdW5zaWduZWQgbG9uZyB1bEVNQUNQb2xsKCB2b2lkICkNCnsNCnN0YXRpYyB1bnNpZ25lZCBwb3J0QkFTRV9UWVBFIHVsTmV4dFJ4QnVmZmVyID0gMDsNCnVuc2lnbmVkIGxvbmcgdWxTZWN0aW9uTGVuZ3RoID0gMCwgdWxMZW5ndGhTb0ZhciA9IDAsIHVsRU9GID0gcGRGQUxTRTsNCmNoYXIgKnBjU291cmNlOw0KDQoJLyogU2tpcCBhbnkgZnJhZ21lbnRzLiAqLw0KCXdoaWxlKCAoIHhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLmFkZHIgJiBBVDkxQ19PV05FUlNISVBfQklUICkgJiYgISggeFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uVV9TdGF0dXMuc3RhdHVzICYgQVQ5MUNfU09GICkgKQ0KCXsNCgkJLyogTWFyayB0aGUgYnVmZmVyIGFzIGZyZWUgYWdhaW4uICovDQoJCXhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLmFkZHIgJj0gfiggQVQ5MUNfT1dORVJTSElQX0JJVCApOwkJDQoJCXVsTmV4dFJ4QnVmZmVyKys7DQoJCWlmKCB1bE5leHRSeEJ1ZmZlciA+PSBOQl9SWF9CVUZGRVJTICkNCgkJew0KCQkJdWxOZXh0UnhCdWZmZXIgPSAwOw0KCQl9DQoJfQ0KDQoJLyogSXMgdGhlcmUgYSBwYWNrZXQgcmVhZHk/ICovDQoNCgl3aGlsZSggKCB4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICYgQVQ5MUNfT1dORVJTSElQX0JJVCApICYmICF1bFNlY3Rpb25MZW5ndGggKQ0KCXsNCgkJcGNTb3VyY2UgPSAoIGNoYXIgKiApKCB4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICYgZW1hY0FERFJFU1NfTUFTSyApOw0KCQl1bFNlY3Rpb25MZW5ndGggPSB4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5VX1N0YXR1cy5zdGF0dXMgJiBlbWFjUlhfTEVOR1RIX0ZSQU1FOw0KDQoJCWlmKCB1bFNlY3Rpb25MZW5ndGggPT0gMCApDQoJCXsNCgkJCS8qIFRoZSBmcmFtZSBpcyBsb25nZXIgdGhhbiB0aGUgYnVmZmVyIHBvaW50ZWQgdG8gYnkgdGhpcw0KCQkJZGVzY3JpcHRvciBzbyBjb3B5IHRoZSBlbnRpcmUgYnVmZmVyIHRvIHVJUCAtIHRoZW4gbW92ZSBvbnRvDQoJCQl0aGUgbmV4dCBkZXNjcmlwdG9yIHRvIGdldCB0aGUgcmVzdCBvZiB0aGUgZnJhbWUuICovDQoJCQlpZiggKCB1bExlbmd0aFNvRmFyICsgRVRIX1JYX0JVRkZFUl9TSVpFICkgPD0gVUlQX0JVRlNJWkUgKQ0KCQkJew0KCQkJCW1lbWNweSggJiggdWlwX2J1ZlsgdWxMZW5ndGhTb0ZhciBdICksIHBjU291cmNlLCBFVEhfUlhfQlVGRkVSX1NJWkUgKTsNCgkJCQl1bExlbmd0aFNvRmFyICs9IEVUSF9SWF9CVUZGRVJfU0laRTsNCgkJCX0JCQkNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8qIFRoaXMgaXMgdGhlIGxhc3Qgc2VjdGlvbiBvZiB0aGUgZnJhbWUuICBDb3B5IHRoZSBzZWN0aW9uIHRvDQoJCQl1SVAuICovDQoJCQlpZiggdWxTZWN0aW9uTGVuZ3RoIDwgVUlQX0JVRlNJWkUgKQ0KCQkJew0KCQkJCS8qIFRoZSBzZWN0aW9uIGxlbmd0aCBob2xkcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbnRpcmUgZnJhbWUuDQoJCQkJdWxMZW5ndGhTb0ZhciBob2xkcyB0aGUgbGVuZ3RoIG9mIHRoZSBmcmFtZSBzZWN0aW9ucyBhbHJlYWR5DQoJCQkJY29waWVkIHRvIHVJUCwgc28gdGhlIGxlbmd0aCBvZiB0aGUgZmluYWwgc2VjdGlvbiBpcw0KCQkJCXVsU2VjdGlvbkxlbmd0aCAtIHVsTGVuZ3RoU29GYXI7ICovDQoJCQkJaWYoIHVsU2VjdGlvbkxlbmd0aCA+IHVsTGVuZ3RoU29GYXIgKQ0KCQkJCXsNCgkJCQkJbWVtY3B5KCAmKCB1aXBfYnVmWyB1bExlbmd0aFNvRmFyIF0gKSwgcGNTb3VyY2UsICggdWxTZWN0aW9uTGVuZ3RoIC0gdWxMZW5ndGhTb0ZhciApICk7DQoJCQkJfQ0KCQkJfQkJCQ0KDQoJCQkvKiBJcyB0aGlzIHRoZSBsYXN0IGJ1ZmZlciBmb3IgdGhlIGZyYW1lPyAgSWYgbm90IHdoeT8gKi8NCgkJCXVsRU9GID0geFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uVV9TdGF0dXMuc3RhdHVzICYgQVQ5MUNfRU9GOw0KCQl9DQoNCgkJLyogTWFyayB0aGUgYnVmZmVyIGFzIGZyZWUgYWdhaW4uICovDQoJCXhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLmFkZHIgJj0gfiggQVQ5MUNfT1dORVJTSElQX0JJVCApOw0KDQoJCS8qIEluY3JlbWVudCB0byB0aGUgbmV4dCBidWZmZXIsIHdyYXBwaW5nIGlmIG5lY2Vzc2FyeS4gKi8NCgkJdWxOZXh0UnhCdWZmZXIrKzsNCgkJaWYoIHVsTmV4dFJ4QnVmZmVyID49IE5CX1JYX0JVRkZFUlMgKQ0KCQl7DQoJCQl1bE5leHRSeEJ1ZmZlciA9IDA7DQoJCX0NCgl9DQoNCgkvKiBJZiB3ZSBvYnRhaW5lZCBkYXRhIGJ1dCBmb3Igc29tZSByZWFzb24gZGlkIG5vdCBmaW5kIHRoZSBlbmQgb2YgdGhlDQoJZnJhbWUgdGhlbiBkaXNjYXJkIHRoZSBkYXRhIGFzIGl0IG11c3QgY29udGFpbiBhbiBlcnJvci4gKi8NCglpZiggIXVsRU9GICkNCgl7DQoJCXVsU2VjdGlvbkxlbmd0aCA9IDA7DQoJfQ0KDQoJcmV0dXJuIHVsU2VjdGlvbkxlbmd0aDsNCn0NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQpzdGF0aWMgdm9pZCBwcnZTZXR1cERlc2NyaXB0b3JzKHZvaWQpDQp7DQp1bnNpZ25lZCBwb3J0QkFTRV9UWVBFIHhJbmRleDsNCnVuc2lnbmVkIGxvbmcgdWxBZGRyZXNzOw0KDQoJLyogSW5pdGlhbGlzZSB4UnhEZXNjcmlwdG9ycyBkZXNjcmlwdG9yLiAqLw0KCWZvciggeEluZGV4ID0gMDsgeEluZGV4IDwgTkJfUlhfQlVGRkVSUzsgKyt4SW5kZXggKQ0KCXsNCgkJLyogQ2FsY3VsYXRlIHRoZSBhZGRyZXNzIG9mIHRoZSBudGggYnVmZmVyIHdpdGhpbiB0aGUgYXJyYXkuICovDQoJCXVsQWRkcmVzcyA9ICggdW5zaWduZWQgbG9uZyApKCBwY1J4QnVmZmVyICsgKCB4SW5kZXggKiBFVEhfUlhfQlVGRkVSX1NJWkUgKSApOw0KDQoJCS8qIFdyaXRlIHRoZSBidWZmZXIgYWRkcmVzcyBpbnRvIHRoZSBkZXNjcmlwdG9yLiAgVGhlIERNQSB3aWxsIHBsYWNlDQoJCXRoZSBkYXRhIGF0IHRoaXMgYWRkcmVzcyB3aGVuIHRoaXMgZGVzY3JpcHRvciBpcyBiZWluZyB1c2VkLiAgTWFzayBvZmYNCgkJdGhlIGJvdHRvbSBiaXRzIG9mIHRoZSBhZGRyZXNzIGFzIHRoZXNlIGhhdmUgc3BlY2lhbCBtZWFuaW5nLiAqLw0KCQl4UnhEZXNjcmlwdG9yc1sgeEluZGV4IF0uYWRkciA9IHVsQWRkcmVzcyAmIGVtYWNBRERSRVNTX01BU0s7DQoJfQkNCg0KCS8qIFRoZSBsYXN0IGJ1ZmZlciBoYXMgdGhlIHdyYXAgYml0IHNldCBzbyB0aGUgRU1BQyBrbm93cyB0byB3cmFwIGJhY2sNCgl0byB0aGUgZmlyc3QgYnVmZmVyLiAqLw0KCXhSeERlc2NyaXB0b3JzWyBOQl9SWF9CVUZGRVJTIC0gMSBdLmFkZHIgfD0gZW1hY1JYX1dSQVBfQklUOw0KDQoJLyogSW5pdGlhbGlzZSB4VHhEZXNjcmlwdG9ycy4gKi8NCglmb3IoIHhJbmRleCA9IDA7IHhJbmRleCA8IE5CX1RYX0JVRkZFUlM7ICsreEluZGV4ICkNCgl7DQoJCS8qIENhbGN1bGF0ZSB0aGUgYWRkcmVzcyBvZiB0aGUgbnRoIGJ1ZmZlciB3aXRoaW4gdGhlIGFycmF5LiAqLw0KCQl1bEFkZHJlc3MgPSAoIHVuc2lnbmVkIGxvbmcgKSggcGNUeEJ1ZmZlciArICggeEluZGV4ICogRVRIX1RYX0JVRkZFUl9TSVpFICkgKTsNCg0KCQkvKiBXcml0ZSB0aGUgYnVmZmVyIGFkZHJlc3MgaW50byB0aGUgZGVzY3JpcHRvci4gIFRoZSBETUEgd2lsbCByZWFkDQoJCWRhdGEgZnJvbSBoZXJlIHdoZW4gdGhlIGRlc2NyaXB0b3IgaXMgYmVpbmcgdXNlZC4gKi8NCgkJeFR4RGVzY3JpcHRvcnNbIHhJbmRleCBdLmFkZHIgPSB1bEFkZHJlc3MgJiBlbWFjQUREUkVTU19NQVNLOw0KCQl4VHhEZXNjcmlwdG9yc1sgeEluZGV4IF0uVV9TdGF0dXMuc3RhdHVzID0gQVQ5MUNfVFJBTlNNSVRfT0s7DQoJfQkNCg0KCS8qIFRoZSBsYXN0IGJ1ZmZlciBoYXMgdGhlIHdyYXAgYml0IHNldCBzbyB0aGUgRU1BQyBrbm93cyB0byB3cmFwIGJhY2sNCgl0byB0aGUgZmlyc3QgYnVmZmVyLiAqLw0KCXhUeERlc2NyaXB0b3JzWyBOQl9UWF9CVUZGRVJTIC0gMSBdLlVfU3RhdHVzLnN0YXR1cyA9IEFUOTFDX1RSQU5TTUlUX1dSQVAgfCBBVDkxQ19UUkFOU01JVF9PSzsNCg0KCS8qIFRlbGwgdGhlIEVNQUMgd2hlcmUgdG8gZmluZCB0aGUgZGVzY3JpcHRvcnMuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1JCUVAgPSAoIHVuc2lnbmVkIGxvbmcgKSB4UnhEZXNjcmlwdG9yczsNCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfVEJRUCA9ICggdW5zaWduZWQgbG9uZyApIHhUeERlc2NyaXB0b3JzOw0KCQ0KCS8qIENsZWFyIGFsbCB0aGUgYml0cyBpbiB0aGUgcmVjZWl2ZSBzdGF0dXMgcmVnaXN0ZXIuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1JTUiA9ICggQVQ5MUNfRU1BQ19PVlIgfCBBVDkxQ19FTUFDX1JFQyB8IEFUOTFDX0VNQUNfQk5BICk7DQoNCgkvKiBFbmFibGUgdGhlIGNvcHkgb2YgZGF0YSBpbnRvIHRoZSBidWZmZXJzLCBpZ25vcmUgYnJvYWRjYXN0cywNCglhbmQgZG9uJ3QgY29weSBGQ1MuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSIHw9ICggQVQ5MUNfRU1BQ19DQUYgfCBBVDkxQ19FTUFDX05CQyB8IEFUOTFDX0VNQUNfRFJGQ1MpOw0KDQoJLyogRW5hYmxlIFJ4IGFuZCBUeCwgcGx1cyB0aGUgc3RhdHMgcmVnaXN0ZXIuICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiB8PSAoIEFUOTFDX0VNQUNfVEUgfCBBVDkxQ19FTUFDX1JFIHwgQVQ5MUNfRU1BQ19XRVNUQVQgKTsNCn0JDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBNQUNBZGRyZXNzKCB2b2lkICkNCnsNCgkvKiBNdXN0IGJlIHdyaXR0ZW4gU0ExTCB0aGVuIFNBMUguICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1NBMUwgPQkoICggdW5zaWduZWQgbG9uZyApIGNNQUNBZGRyZXNzWyAzIF0gPDwgMjQgKSB8DQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIGNNQUNBZGRyZXNzWyAyIF0gPDwgMTYgKSB8DQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIGNNQUNBZGRyZXNzWyAxIF0gPDwgOCAgKSB8DQoJCQkJCQkJCQljTUFDQWRkcmVzc1sgMCBdOw0KDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1NBMUggPQkoICggdW5zaWduZWQgbG9uZyApIGNNQUNBZGRyZXNzWyA1IF0gPDwgOCApIHwNCgkJCQkJCQkJCWNNQUNBZGRyZXNzWyA0IF07DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBFTUFDSW50ZXJydXB0KCB2b2lkICkNCnsNCgkvKiBDcmVhdGUgdGhlIHNlbWFwaG9yZSB1c2VkIHRvIHRyaWdnZXIgdGhlIEVNQUMgdGFzay4gKi8NCgl2U2VtYXBob3JlQ3JlYXRlQmluYXJ5KCB4U2VtYXBob3JlICk7DQoJaWYoIHhTZW1hcGhvcmUgKQ0KCXsNCgkJLyogV2Ugc3RhcnQgYnkgJ3Rha2luZycgdGhlIHNlbWFwaG9yZSBzbyB0aGUgSVNSIGNhbiAnZ2l2ZScgaXQgd2hlbiB0aGUNCgkJZmlyc3QgaW50ZXJydXB0IG9jY3Vycy4gKi8NCgkJeFNlbWFwaG9yZVRha2UoIHhTZW1hcGhvcmUsIGVtYWNOT19ERUxBWSApOw0KCQlwb3J0RU5URVJfQ1JJVElDQUwoKTsNCgkJew0KCQkJLyogV2Ugd2FudCB0byBpbnRlcnJ1cHQgb24gUnggZXZlbnRzLiAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX0lFUiA9IEFUOTFDX0VNQUNfUkNPTVA7DQoNCgkJCS8qIEVuYWJsZSB0aGUgaW50ZXJydXB0cyBpbiB0aGUgQUlDLiAqLw0KCQkJQVQ5MUZfQUlDX0NvbmZpZ3VyZUl0KCBBVDkxQ19JRF9FTUFDLCBlbWFjSU5URVJSVVBUX0xFVkVMLCBBVDkxQ19BSUNfU1JDVFlQRV9JTlRfSElHSF9MRVZFTCwgKCB2b2lkICgqKSggdm9pZCApICkgdkVNQUNJU1JfV3JhcHBlciApOw0KCQkJQVQ5MUNfQkFTRV9BSUMtPkFJQ19JRUNSID0gMHgxIDw8IEFUOTFDX0lEX0VNQUM7DQoJCX0NCgkJcG9ydEVYSVRfQ1JJVElDQUwoKTsNCgl9DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KDQoNCg0KLyoNCiAqIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbml0aWFsaXNhdGlvbiBmdW5jdGlvbnMgdGFrZW4gZnJvbSB0aGUgQXRtZWwNCiAqIEVNQUMgc2FtcGxlIGNvZGUuDQogKi8NCg0Kc3RhdGljIHBvcnRCQVNFX1RZUEUgcHJ2UHJvYmVQSFkoIHZvaWQgKQ0Kew0KdW5zaWduZWQgbG9uZyB1bFBIWUlkMSwgdWxQSFlJZDIsIHVsU3RhdHVzOw0KcG9ydEJBU0VfVFlQRSB4UmV0dXJuID0gcGRQQVNTOw0KCQ0KCS8qIENvZGUgc3VwcGxpZWQgYnkgQXRtZWwgKHJlZm9ybWF0dGVkKSAtLS0tLS0tLS0tLS0tLS0tLSovDQoNCgkvKiBFbmFibGUgbWFuYWdlbWVudCBwb3J0ICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiB8PSBBVDkxQ19FTUFDX01QRTsJDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSIHw9ICggMiApIDw8IDEwOw0KDQoJLyogUmVhZCB0aGUgUEhZIElELiAqLw0KCXZSZWFkUEhZKCBBVDkxQ19QSFlfQUREUiwgTUlJX1BIWVNJRDEsICZ1bFBIWUlkMSApOw0KCXZSZWFkUEhZKCBBVDkxQ19QSFlfQUREUiwgTUlJX1BIWVNJRDIsICZ1bFBIWUlkMiApOw0KDQoJLyogQU1EIEFNNzlDODc1Og0KCQkJUEhZX0lEMSA9IDB4MDAyMg0KCQkJUEhZX0lEMiA9IDB4NTU0MQ0KCQkJQml0cyAzOjAgUmV2aXNpb24gTnVtYmVyIEZvdXIgYml0IG1hbnVmYWN0dXJlcpJzIHJldmlzaW9uIG51bWJlci4NCgkJCQkwMDAxIHN0YW5kcyBmb3IgUmV2LiBBLCBldGMuDQoJKi8NCglpZiggKCAoIHVsUEhZSWQxIDw8IDE2ICkgfCAoIHVsUEhZSWQyICYgMHhmZmYwICkgKSAhPSBNSUlfRE05MTYxX0lEICkNCgl7DQoJCS8qIERpZCBub3QgZXhwZWN0IHRoaXMgSUQuICovDQoJCXhSZXR1cm4gPSBwZEZBSUw7DQoJfQ0KCWVsc2UNCgl7DQoJCXVsU3RhdHVzID0geEdldExpbmtTcGVlZCgpOw0KDQoJCWlmKCB1bFN0YXR1cyAhPSBwZFBBU1MgKQ0KCQl7DQoJCQl4UmV0dXJuID0gcGRGQUlMOw0KCQl9DQoJfQ0KDQoJLyogRGlzYWJsZSBtYW5hZ2VtZW50IHBvcnQgKi8NCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNSICY9IH5BVDkxQ19FTUFDX01QRTsJDQoNCgkvKiBFbmQgb2YgY29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJcmV0dXJuIHhSZXR1cm47DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgdlJlYWRQSFkoIHVuc2lnbmVkIGNoYXIgdWNQSFlBZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHVjQWRkcmVzcywgdW5zaWduZWQgbG9uZyAqcHVsVmFsdWUgKQ0Kew0KCS8qIENvZGUgc3VwcGxpZWQgYnkgQXRtZWwgKHJlZm9ybWF0dGVkKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19NQU4gPSAJKEFUOTFDX0VNQUNfU09GICYgKDB4MDE8PDMwKSkNCgkJCQkJCQkJCXwgKDIgPDwgMTYpIHwgKDIgPDwgMjgpDQoJCQkJCQkJCQl8ICgodWNQSFlBZGRyZXNzICYgMHgxZikgPDwgMjMpDQoJCQkJCQkJCQl8ICh1Y0FkZHJlc3MgPDwgMTgpOw0KDQoJLyogV2FpdCB1bnRpbCBJRExFIGJpdCBpbiBOZXR3b3JrIFN0YXR1cyByZWdpc3RlciBpcyBjbGVhcmVkLiAqLw0KCXdoaWxlKCAhKCBBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTlNSICYgQVQ5MUNfRU1BQ19JRExFICkgKQ0KCXsNCgkJX19hc20oICJOT1AiICk7DQoJfQ0KDQoJKnB1bFZhbHVlID0gKCBBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTUFOICYgMHgwMDAwZmZmZiApOwkNCg0KCS8qIEVuZCBvZiBjb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KI2lmIFVTRV9STUlJX0lOVEVSRkFDRSAhPSAxDQpzdGF0aWMgdm9pZCB2V3JpdGVQSFkoIHVuc2lnbmVkIGNoYXIgdWNQSFlBZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHVjQWRkcmVzcywgdW5zaWduZWQgbG9uZyB1bFZhbHVlICkNCnsNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIChyZWZvcm1hdHRlZCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTUFOID0gKCggQVQ5MUNfRU1BQ19TT0YgJiAoMHgwMTw8MzApKQ0KCQkJCQkJCQl8ICgyIDw8IDE2KSB8ICgxIDw8IDI4KQ0KCQkJCQkJCQl8ICgodWNQSFlBZGRyZXNzICYgMHgxZikgPDwgMjMpDQoJCQkJCQkJCXwgKHVjQWRkcmVzcyA8PCAxOCkpDQoJCQkJCQkJCXwgKHVsVmFsdWUgJiAweGZmZmYpOw0KDQoJLyogV2FpdCB1bnRpbCBJRExFIGJpdCBpbiBOZXR3b3JrIFN0YXR1cyByZWdpc3RlciBpcyBjbGVhcmVkICovDQoJd2hpbGUoICEoIEFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OU1IgJiBBVDkxQ19FTUFDX0lETEUgKSApDQoJew0KCQlfX2FzbSggIk5PUCIgKTsNCgl9Ow0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCn0NCiNlbmRpZg0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnN0YXRpYyBwb3J0QkFTRV9UWVBFIHhHZXRMaW5rU3BlZWQoIHZvaWQgKQ0Kew0KCXVuc2lnbmVkIGxvbmcgdWxCTVNSLCB1bEJNQ1IsIHVsTFBBLCB1bE1BQ0NmZywgdWxTcGVlZCwgdWxEdXBsZXg7DQoNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIChyZWZvcm1hdHRlZCkgLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJLyogTGluayBzdGF0dXMgaXMgbGF0Y2hlZCwgc28gcmVhZCB0d2ljZSB0byBnZXQgY3VycmVudCB2YWx1ZSAqLw0KCXZSZWFkUEhZKEFUOTFDX1BIWV9BRERSLCBNSUlfQk1TUiwgJnVsQk1TUik7DQoJdlJlYWRQSFkoQVQ5MUNfUEhZX0FERFIsIE1JSV9CTVNSLCAmdWxCTVNSKTsNCg0KCWlmKCAhKCB1bEJNU1IgJiBCTVNSX0xTVEFUVVMgKSApDQoJewkNCgkJLyogTm8gTGluay4gKi8NCgkJcmV0dXJuIHBkRkFJTDsNCgl9DQoNCgl2UmVhZFBIWShBVDkxQ19QSFlfQUREUiwgTUlJX0JNQ1IsICZ1bEJNQ1IpOw0KCWlmICh1bEJNQ1IgJiBCTUNSX0FORU5BQkxFKQ0KCXsJCQkJDQoJCS8qIEF1dG9OZWdvdGlhdGlvbiBpcyBlbmFibGVkLiAqLw0KCQlpZiAoISh1bEJNU1IgJiBCTVNSX0FORUdDT01QTEVURSkpDQoJCXsNCgkJCS8qIEF1dG8tbmVnb3RpYXRpb24gaW4gcHJvZ3Jlc3MuICovDQoJCQlyZXR1cm4gcGRGQUlMOwkJCQkNCgkJfQkJDQoNCgkJdlJlYWRQSFkoQVQ5MUNfUEhZX0FERFIsIE1JSV9MUEEsICZ1bExQQSk7DQoJCWlmKCAoIHVsTFBBICYgTFBBXzEwMEZVTEwgKSB8fCAoIHVsTFBBICYgTFBBXzEwMEhBTEYgKSApDQoJCXsNCgkJCXVsU3BlZWQgPSBTUEVFRF8xMDA7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl1bFNwZWVkID0gU1BFRURfMTA7DQoJCX0NCg0KCQlpZiggKCB1bExQQSAmIExQQV8xMDBGVUxMICkgfHwgKCB1bExQQSAmIExQQV8xMEZVTEwgKSApDQoJCXsNCgkJCXVsRHVwbGV4ID0gRFVQTEVYX0ZVTEw7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl1bER1cGxleCA9IERVUExFWF9IQUxGOw0KCQl9DQoJfQ0KCWVsc2UNCgl7DQoJCXVsU3BlZWQgPSAoIHVsQk1DUiAmIEJNQ1JfU1BFRUQxMDAgKSA/IFNQRUVEXzEwMCA6IFNQRUVEXzEwOw0KCQl1bER1cGxleCA9ICggdWxCTUNSICYgQk1DUl9GVUxMRFBMWCApID8gRFVQTEVYX0ZVTEwgOiBEVVBMRVhfSEFMRjsNCgl9DQoNCgkvKiBVcGRhdGUgdGhlIE1BQyAqLw0KCXVsTUFDQ2ZnID0gQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSICYgfiggQVQ5MUNfRU1BQ19TUEQgfCBBVDkxQ19FTUFDX0ZEICk7DQoJaWYoIHVsU3BlZWQgPT0gU1BFRURfMTAwICkNCgl7DQoJCWlmKCB1bER1cGxleCA9PSBEVVBMRVhfRlVMTCApDQoJCXsNCgkJCS8qIDEwMCBGdWxsIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmcgfCBBVDkxQ19FTUFDX1NQRCB8IEFUOTFDX0VNQUNfRkQ7DQoJCX0NCgkJZWxzZQ0KCQl7CQkJCQkNCgkJCS8qIDEwMCBIYWxmIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmcgfCBBVDkxQ19FTUFDX1NQRDsNCgkJfQ0KCX0NCgllbHNlDQoJew0KCQlpZiAodWxEdXBsZXggPT0gRFVQTEVYX0ZVTEwpDQoJCXsNCgkJCS8qIDEwIEZ1bGwgRHVwbGV4ICovDQoJCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNGR1IgPSB1bE1BQ0NmZyB8IEFUOTFDX0VNQUNfRkQ7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKiAxMCBIYWxmIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmc7DQoJCX0NCgl9DQoNCgkvKiBFbmQgb2YgY29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJcmV0dXJuIHBkUEFTUzsNCn0NCg==