LyoNCiAgICBGcmVlUlRPUyBWNi4xLjAgLSBDb3B5cmlnaHQgKEMpIDIwMTAgUmVhbCBUaW1lIEVuZ2luZWVycyBMdGQuDQoNCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqIElmIHlvdSBhcmU6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICsgTmV3IHRvIEZyZWVSVE9TLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICsgV2FudGluZyB0byBsZWFybiBGcmVlUlRPUyBvciBtdWx0aXRhc2tpbmcgaW4gZ2VuZXJhbCBxdWlja2x5ICAgICAgICoNCiAgICAqICAgICsgTG9va2luZyBmb3IgYmFzaWMgdHJhaW5pbmcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICsgV2FudGluZyB0byBpbXByb3ZlIHlvdXIgRnJlZVJUT1Mgc2tpbGxzIGFuZCBwcm9kdWN0aXZpdHkgICAgICAgICAgICoNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqIHRoZW4gdGFrZSBhIGxvb2sgYXQgdGhlIEZyZWVSVE9TIGJvb2tzIC0gYXZhaWxhYmxlIGFzIFBERiBvciBwYXBlcmJhY2sgICoNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICAgICAiVXNpbmcgdGhlIEZyZWVSVE9TIFJlYWwgVGltZSBLZXJuZWwgLSBhIFByYWN0aWNhbCBHdWlkZSIgICAgICAgICoNCiAgICAqICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5GcmVlUlRPUy5vcmcvRG9jdW1lbnRhdGlvbiAgICAgICAgICAgICAgICAgICoNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqIEEgcGRmIHJlZmVyZW5jZSBtYW51YWwgaXMgYWxzbyBhdmFpbGFibGUuICBCb3RoIGFyZSB1c3VhbGx5IGRlbGl2ZXJlZCAgICoNCiAgICAqIHRvIHlvdXIgaW5ib3ggd2l0aGluIDIwIG1pbnV0ZXMgdG8gdHdvIGhvdXJzIHdoZW4gcHVyY2hhc2VkIGJldHdlZW4gOGFtICoNCiAgICAqIGFuZCA4cG0gR01UIChhbHRob3VnaCBwbGVhc2UgYWxsb3cgdXAgdG8gMjQgaG91cnMgaW4gY2FzZSBvZiAgICAgICAgICAgICoNCiAgICAqIGV4Y2VwdGlvbmFsIGNpcmN1bXN0YW5jZXMpLiAgVGhhbmsgeW91IGZvciB5b3VyIHN1cHBvcnQhICAgICAgICAgICAgICAgICoNCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCg0KICAgIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBGcmVlUlRPUyBkaXN0cmlidXRpb24uDQoNCiAgICBGcmVlUlRPUyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyDQogICAgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAodmVyc2lvbiAyKSBhcyBwdWJsaXNoZWQgYnkgdGhlDQogICAgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIEFORCBNT0RJRklFRCBCWSB0aGUgRnJlZVJUT1MgZXhjZXB0aW9uLg0KICAgICoqKk5PVEUqKiogVGhlIGV4Y2VwdGlvbiB0byB0aGUgR1BMIGlzIGluY2x1ZGVkIHRvIGFsbG93IHlvdSB0byBkaXN0cmlidXRlDQogICAgYSBjb21iaW5lZCB3b3JrIHRoYXQgaW5jbHVkZXMgRnJlZVJUT1Mgd2l0aG91dCBiZWluZyBvYmxpZ2VkIHRvIHByb3ZpZGUgdGhlDQogICAgc291cmNlIGNvZGUgZm9yIHByb3ByaWV0YXJ5IGNvbXBvbmVudHMgb3V0c2lkZSBvZiB0aGUgRnJlZVJUT1Mga2VybmVsLg0KICAgIEZyZWVSVE9TIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUDQogICAgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yDQogICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvcg0KICAgIG1vcmUgZGV0YWlscy4gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIA0KICAgIExpY2Vuc2UgYW5kIHRoZSBGcmVlUlRPUyBsaWNlbnNlIGV4Y2VwdGlvbiBhbG9uZyB3aXRoIEZyZWVSVE9TOyBpZiBub3QgaXQgDQogICAgY2FuIGJlIHZpZXdlZCBoZXJlOiBodHRwOi8vd3d3LmZyZWVydG9zLm9yZy9hMDAxMTQuaHRtbCBhbmQgYWxzbyBvYnRhaW5lZCANCiAgICBieSB3cml0aW5nIHRvIFJpY2hhcmQgQmFycnksIGNvbnRhY3QgZGV0YWlscyBmb3Igd2hvbSBhcmUgYXZhaWxhYmxlIG9uIHRoZQ0KICAgIEZyZWVSVE9TIFdFQiBzaXRlLg0KDQogICAgMSB0YWIgPT0gNCBzcGFjZXMhDQoNCiAgICBodHRwOi8vd3d3LkZyZWVSVE9TLm9yZyAtIERvY3VtZW50YXRpb24sIGxhdGVzdCBpbmZvcm1hdGlvbiwgbGljZW5zZSBhbmQNCiAgICBjb250YWN0IGRldGFpbHMuDQoNCiAgICBodHRwOi8vd3d3LlNhZmVSVE9TLmNvbSAtIEEgdmVyc2lvbiB0aGF0IGlzIGNlcnRpZmllZCBmb3IgdXNlIGluIHNhZmV0eQ0KICAgIGNyaXRpY2FsIHN5c3RlbXMuDQoNCiAgICBodHRwOi8vd3d3Lk9wZW5SVE9TLmNvbSAtIENvbW1lcmNpYWwgc3VwcG9ydCwgZGV2ZWxvcG1lbnQsIHBvcnRpbmcsDQogICAgbGljZW5zaW5nIGFuZCB0cmFpbmluZyBzZXJ2aWNlcy4NCiovDQoNCi8qIFN0YW5kYXJkIGluY2x1ZGVzLiAqLw0KI2luY2x1ZGUgPHN0cmluZy5oPg0KDQovKiBTY2hlZHVsZXIgaW5jbHVkZXMuICovDQojaW5jbHVkZSAiRnJlZVJUT1MuaCINCiNpbmNsdWRlICJzZW1waHIuaCINCiNpbmNsdWRlICJ0YXNrLmgiDQoNCi8qIERlbW8gYXBwbGljYXRpb24gaW5jbHVkZXMuICovDQojaW5jbHVkZSAiU0FNN19FTUFDLmgiDQoNCi8qIHVJUCBpbmNsdWRlcy4gKi8NCiNpbmNsdWRlICJ1aXAuaCINCg0KLyogSGFyZHdhcmUgc3BlY2lmaWMgaW5jbHVkZXMuICovDQojaW5jbHVkZSAiRW1hYy5oIg0KI2luY2x1ZGUgIm1paS5oIg0KI2luY2x1ZGUgIkFUOTFTQU03WDI1Ni5oIg0KDQoNCi8qIFVTRV9STUlJX0lOVEVSRkFDRSBtdXN0IGJlIGRlZmluZWQgYXMgMSB0byB1c2UgYW4gUk1JSSBpbnRlcmZhY2UsIG9yIDANCnRvIHVzZSBhbiBNSUkgaW50ZXJmYWNlLiAqLw0KI2RlZmluZSBVU0VfUk1JSV9JTlRFUkZBQ0UgMA0KDQovKiBUaGUgYnVmZmVyIGFkZHJlc3NlcyB3cml0dGVuIGludG8gdGhlIGRlc2NyaXB0b3JzIG11c3QgYmUgYWxpZ25lZCBzbyB0aGUNCmxhc3QgZmV3IGJpdHMgYXJlIHplcm8uICBUaGVzZSBiaXRzIGhhdmUgc3BlY2lhbCBtZWFuaW5nIGZvciB0aGUgRU1BQw0KcGVyaXBoZXJhbCBhbmQgY2Fubm90IGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgYWRkcmVzcy4gKi8NCiNkZWZpbmUgZW1hY0FERFJFU1NfTUFTSwkJCSggKCB1bnNpZ25lZCBsb25nICkgMHhGRkZGRkZGQyApDQoNCi8qIEJpdCB1c2VkIHdpdGhpbiB0aGUgYWRkcmVzcyBzdG9yZWQgaW4gdGhlIGRlc2NyaXB0b3IgdG8gbWFyayB0aGUgbGFzdA0KZGVzY3JpcHRvciBpbiB0aGUgYXJyYXkuICovDQojZGVmaW5lIGVtYWNSWF9XUkFQX0JJVAkJCQkoICggdW5zaWduZWQgbG9uZyApIDB4MDIgKQ0KDQovKiBCaXQgdXNlZCB3aXRoaW4gdGhlIFR4IGRlc2NyaXB0b3Igc3RhdHVzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlDQpkZXNjcmlwdG9yIGlzIHVuZGVyIHRoZSBjb250cm9sIG9mIHRoZSBFTUFDIG9yIHRoZSBzb2Z0d2FyZS4gKi8NCiNkZWZpbmUgZW1hY1RYX0JVRl9VU0VECQkJCSggKCB1bnNpZ25lZCBsb25nICkgMHg4MDAwMDAwMCApDQoNCi8qIEEgc2hvcnQgZGVsYXkgaXMgdXNlZCB0byB3YWl0IGZvciBhIGJ1ZmZlciB0byBiZWNvbWUgYXZhaWxhYmxlLCBzaG91bGQNCm9uZSBub3QgYmUgaW1tZWRpYXRlbHkgYXZhaWxhYmxlIHdoZW4gdHJ5aW5nIHRvIHRyYW5zbWl0IGEgZnJhbWUuICovDQojZGVmaW5lIGVtYWNCVUZGRVJfV0FJVF9ERUxBWQkJKCAyICkNCiNkZWZpbmUgZW1hY01BWF9XQUlUX0NZQ0xFUwkJCSggY29uZmlnVElDS19SQVRFX0haIC8gNDAgKQ0KDQovKiBNaXNjIGRlZmluZXMuICovDQojZGVmaW5lIGVtYWNJTlRFUlJVUFRfTEVWRUwJCQkoIDUgKQ0KI2RlZmluZSBlbWFjTk9fREVMQVkJCQkJKCAwICkNCiNkZWZpbmUgZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFCSggNTQgKQ0KI2RlZmluZSBlbWFjUEhZX0lOSVRfREVMQVkJCQkoIDUwMDAgLyBwb3J0VElDS19SQVRFX01TICkNCiNkZWZpbmUgZW1hY1JFU0VUX0tFWQkJCQkoICggdW5zaWduZWQgbG9uZyApIDB4QTUwMDAwMDAgKQ0KI2RlZmluZSBlbWFjUkVTRVRfTEVOR1RICQkJKCAoIHVuc2lnbmVkIGxvbmcgKSAoIDB4MDEgPDwgOCApICkNCg0KLyogVGhlIEF0bWVsIGhlYWRlciBmaWxlIG9ubHkgZGVmaW5lcyB0aGUgVFggZnJhbWUgbGVuZ3RoIG1hc2suICovDQojZGVmaW5lIGVtYWNSWF9MRU5HVEhfRlJBTUUJCQkoIDB4ZmZmICkNCg0KLyogUGVyaXBoZXJhbCBzZXR1cCBmb3IgdGhlIEVNQUMuICovDQojZGVmaW5lIGVtYWNQRVJJUEhFUkFMX0FfU0VUVVAgCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCMl9FVFgwCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIxMl9FVFhFUgkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIxNl9FQ09MCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIxMV9FVFgzCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEI2X0VSWDEJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjE1X0VSWERWCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjEzX0VSWDIJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjNfRVRYMQkJCSkgfCBcDQoJCQkJCQkJCQkoICggdW5zaWduZWQgbG9uZyApIEFUOTFDX1BCOF9FTURDCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEI1X0VSWDAJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjE0X0VSWDMJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjRfRUNSU19FQ1JTRFYJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIxX0VUWEVOCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIxMF9FVFgyCQkJKSB8IFwNCgkJCQkJCQkJCSggKCB1bnNpZ25lZCBsb25nICkgQVQ5MUNfUEIwX0VUWENLX0VSRUZDSwkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjlfRU1ESU8JCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjdfRVJYRVIJCQkpIHwgXA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19QQjE3X0VSWENLCQkpOw0KDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoNCiAqIFByb3RvdHlwZSBmb3IgdGhlIEVNQUMgaW50ZXJydXB0IGZ1bmN0aW9uIC0gY2FsbGVkIGJ5IHRoZSBhc20gd3JhcHBlci4NCiAqLw0KZXh0ZXJuIHZvaWQgdkVNQUNJU1JfV3JhcHBlciggdm9pZCApIF9fYXR0cmlidXRlX18oKG5ha2VkKSk7DQoNCi8qDQogKiBJbml0aWFsaXNlIGJvdGggdGhlIFR4IGFuZCBSeCBkZXNjcmlwdG9ycyB1c2VkIGJ5IHRoZSBFTUFDLg0KICovDQpzdGF0aWMgdm9pZCBwcnZTZXR1cERlc2NyaXB0b3JzKHZvaWQpOw0KDQovKg0KICogV3JpdGUgb3VyIE1BQyBhZGRyZXNzIGludG8gdGhlIEVNQUMuICBUaGUgTUFDIGFkZHJlc3MgaXMgc2V0IGFzIG9uZSBvZiB0aGUNCiAqIHVpcCBvcHRpb25zLg0KICovDQpzdGF0aWMgdm9pZCBwcnZTZXR1cE1BQ0FkZHJlc3MoIHZvaWQgKTsNCg0KLyoNCiAqIENvbmZpZ3VyZSB0aGUgRU1BQyBhbmQgQUlDIGZvciBFTUFDIGludGVycnVwdHMuDQogKi8NCnN0YXRpYyB2b2lkIHBydlNldHVwRU1BQ0ludGVycnVwdCggdm9pZCApOw0KDQovKg0KICogU29tZSBpbml0aWFsaXNhdGlvbiBmdW5jdGlvbnMgdGFrZW4gZnJvbSB0aGUgQXRtZWwgRU1BQyBzYW1wbGUgY29kZS4NCiAqLw0Kc3RhdGljIHZvaWQgdlJlYWRQSFkoIHVuc2lnbmVkIGNoYXIgdWNQSFlBZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHVjQWRkcmVzcywgdW5zaWduZWQgbG9uZyAqcHVsVmFsdWUgKTsNCiNpZiBVU0VfUk1JSV9JTlRFUkZBQ0UgIT0gMQ0KCXN0YXRpYyB2b2lkIHZXcml0ZVBIWSggdW5zaWduZWQgY2hhciB1Y1BIWUFkZHJlc3MsIHVuc2lnbmVkIGNoYXIgdWNBZGRyZXNzLCB1bnNpZ25lZCBsb25nIHVsVmFsdWUpOw0KI2VuZGlmDQpzdGF0aWMgcG9ydEJBU0VfVFlQRSB4R2V0TGlua1NwZWVkKCB2b2lkICk7DQpzdGF0aWMgcG9ydEJBU0VfVFlQRSBwcnZQcm9iZVBIWSggdm9pZCApOw0KDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyogQnVmZmVyIHdyaXR0ZW4gdG8gYnkgdGhlIEVNQUMgRE1BLiAgTXVzdCBiZSBhbGlnbmVkIGFzIGRlc2NyaWJlZCBieSB0aGUNCmNvbW1lbnQgYWJvdmUgdGhlIGVtYWNBRERSRVNTX01BU0sgZGVmaW5pdGlvbi4gKi8NCiNwcmFnbWEgZGF0YV9hbGlnbm1lbnQ9OA0Kc3RhdGljIHZvbGF0aWxlIGNoYXIgcGNSeEJ1ZmZlclsgTkJfUlhfQlVGRkVSUyAqIEVUSF9SWF9CVUZGRVJfU0laRSBdOw0KDQovKiBCdWZmZXIgcmVhZCBieSB0aGUgRU1BQyBETUEuICBNdXN0IGJlIGFsaWduZWQgYXMgZGVzY3JpYmVkIGJ5IGhlIGNvbW1lbnQNCmFib3ZlIHRoZSBlbWFjQUREUkVTU19NQVNLIGRlZmluaXRpb24uICovDQojcHJhZ21hIGRhdGFfYWxpZ25tZW50PTgNCnN0YXRpYyBjaGFyIHBjVHhCdWZmZXJbIE5CX1RYX0JVRkZFUlMgKiBFVEhfVFhfQlVGRkVSX1NJWkUgXTsNCg0KLyogRGVzY3JpcHRvcnMgdXNlZCB0byBjb21tdW5pY2F0ZSBiZXR3ZWVuIHRoZSBwcm9ncmFtIGFuZCB0aGUgRU1BQyBwZXJpcGhlcmFsLg0KVGhlc2UgZGVzY3JpcHRvcnMgaG9sZCB0aGUgbG9jYXRpb25zIGFuZCBzdGF0ZSBvZiB0aGUgUnggYW5kIFR4IGJ1ZmZlcnMuICovDQpzdGF0aWMgdm9sYXRpbGUgQVQ5MVNfVHhUZERlc2NyaXB0b3IgeFR4RGVzY3JpcHRvcnNbIE5CX1RYX0JVRkZFUlMgXTsNCnN0YXRpYyB2b2xhdGlsZSBBVDkxU19SeFRkRGVzY3JpcHRvciB4UnhEZXNjcmlwdG9yc1sgTkJfUlhfQlVGRkVSUyBdOw0KDQovKiBUaGUgSVAgYW5kIEV0aGVybmV0IGFkZHJlc3NlcyBhcmUgcmVhZCBmcm9tIHRoZSB1SVAgc2V0dXAuICovDQpjb25zdCBjaGFyIGNNQUNBZGRyZXNzWyA2IF0gPSB7IHVpcE1BQ19BRERSMCwgdWlwTUFDX0FERFIxLCB1aXBNQUNfQUREUjIsIHVpcE1BQ19BRERSMywgdWlwTUFDX0FERFI0LCB1aXBNQUNfQUREUjUgfTsNCmNvbnN0IHVuc2lnbmVkIGNoYXIgdWNJUEFkZHJlc3NbIDQgXSAgPSB7IHVpcElQX0FERFIwLCB1aXBJUF9BRERSMSwgdWlwSVBfQUREUjIsIHVpcElQX0FERFIzIH07DQoNCi8qIFRoZSBzZW1hcGhvcmUgdXNlZCBieSB0aGUgRU1BQyBJU1IgdG8gd2FrZSB0aGUgRU1BQyB0YXNrLiAqLw0Kc3RhdGljIHhTZW1hcGhvcmVIYW5kbGUgeFNlbWFwaG9yZSA9IE5VTEw7DQoNCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQp4U2VtYXBob3JlSGFuZGxlIHhFTUFDSW5pdCggdm9pZCApDQp7DQoJLyogQ29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCS8qIERpc2FibGUgcHVsbCB1cCBvbiBSWERWID0+IFBIWSBub3JtYWwgbW9kZSAobm90IGluIHRlc3QgbW9kZSksDQoJUEhZIGhhcyBpbnRlcm5hbCBwdWxsIGRvd24uICovDQoJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fUFBVRFIgPSAxIDw8IDE1Ow0KDQoJI2lmIFVTRV9STUlJX0lOVEVSRkFDRSAhPSAxDQoJICAJLyogUEhZIGhhcyBpbnRlcm5hbCBwdWxsIGRvd24gOiBzZXQgTUlJIG1vZGUuICovDQoJICAJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fUFBVRFIgPSAxIDw8IDE2Ow0KCSNlbmRpZg0KDQoJLyogQ2xlYXIgUEIxOCA8PT4gUEhZIHBvd2VyZG93bi4gKi8NCiAgIAlBVDkxQ19CQVNFX1BJT0ItPlBJT19QRVIgPSAxIDw8IDE4Ow0KCUFUOTFDX0JBU0VfUElPQi0+UElPX09FUiA9IDEgPDwgMTg7DQoJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fQ09EUiA9IDEgPDwgMTg7DQoNCgkvKiBBZnRlciBQSFkgcG93ZXIgdXAsIGhhcmR3YXJlIHJlc2V0LiAqLw0KCUFUOTFDX0JBU0VfUlNUQy0+UlNUQ19STVIgPSBlbWFjUkVTRVRfS0VZIHwgZW1hY1JFU0VUX0xFTkdUSDsNCglBVDkxQ19CQVNFX1JTVEMtPlJTVENfUkNSID0gZW1hY1JFU0VUX0tFWSB8IEFUOTFDX1JTVENfRVhUUlNUOw0KDQoJLyogV2FpdCBmb3IgaGFyZHdhcmUgcmVzZXQgZW5kLiAqLw0KCXdoaWxlKCAhKCBBVDkxQ19CQVNFX1JTVEMtPlJTVENfUlNSICYgQVQ5MUNfUlNUQ19OUlNUTCApICkNCgl7DQoJCV9fYXNtIHZvbGF0aWxlICggIk5PUCIgKTsNCgl9DQogICAgX19hc20gdm9sYXRpbGUgKCAiTk9QIiApOw0KDQoJLyogU2V0dXAgdGhlIHBpbnMuICovDQoJQVQ5MUNfQkFTRV9QSU9CLT5QSU9fQVNSID0gZW1hY1BFUklQSEVSQUxfQV9TRVRVUDsNCglBVDkxQ19CQVNFX1BJT0ItPlBJT19QRFIgPSBlbWFjUEVSSVBIRVJBTF9BX1NFVFVQOw0KDQoJLyogRW5hYmxlIGNvbSBiZXR3ZWVuIEVNQUMgUEhZLg0KDQoJRW5hYmxlIG1hbmFnZW1lbnQgcG9ydC4gKi8NCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNSIHw9IEFUOTFDX0VNQUNfTVBFOwkNCg0KCS8qIE1EQyA9IE1DSy8zMi4gKi8NCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTkNGR1IgfD0gKCAyICkgPDwgMTA7CQ0KDQoJLyogV2FpdCBmb3IgUEhZIGF1dG8gaW5pdCBlbmQgKHJhdGhlciBjcnVkZSBkZWxheSEpLiAqLw0KCXZUYXNrRGVsYXkoIGVtYWNQSFlfSU5JVF9ERUxBWSApOw0KDQoJLyogUEhZIGNvbmZpZ3VyYXRpb24uICovDQoJI2lmIFVTRV9STUlJX0lOVEVSRkFDRSAhPSAxDQoJew0KCQl1bnNpZ25lZCBsb25nIHVsQ29udHJvbDsNCg0KCQkvKiBQSFkgaGFzIGludGVybmFsIHB1bGwgZG93biA6IGRpc2FibGUgTUlJIGlzb2xhdGUuICovDQoJCXZSZWFkUEhZKCBBVDkxQ19QSFlfQUREUiwgTUlJX0JNQ1IsICZ1bENvbnRyb2wgKTsNCgkJdlJlYWRQSFkoIEFUOTFDX1BIWV9BRERSLCBNSUlfQk1DUiwgJnVsQ29udHJvbCApOw0KCQl1bENvbnRyb2wgJj0gfkJNQ1JfSVNPTEFURTsNCgkJdldyaXRlUEhZKCBBVDkxQ19QSFlfQUREUiwgTUlJX0JNQ1IsIHVsQ29udHJvbCApOw0KCX0NCgkjZW5kaWYNCg0KCS8qIERpc2FibGUgbWFuYWdlbWVudCBwb3J0IGFnYWluLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ1IgJj0gfkFUOTFDX0VNQUNfTVBFOw0KDQoJI2lmIFVTRV9STUlJX0lOVEVSRkFDRSAhPSAxDQoJCS8qIEVuYWJsZSBFTUFDIGluIE1JSSBtb2RlLCBlbmFibGUgY2xvY2sgRVJYQ0sgYW5kIEVUWENLLiAqLw0KCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfVVNSSU8gPSBBVDkxQ19FTUFDX0NMS0VOIDsNCgkjZWxzZQ0KCQkvKiBFbmFibGUgRU1BQyBpbiBSTUlJIG1vZGUsIGVuYWJsZSBSTUlJIGNsb2NrICg1ME1IeiBmcm9tIG9zY2lsbGF0b3INCgkJb24gRVJGQ0spLiAqLw0KCQlBVDkxQ19CQVNFX0VNQUMtPkVNQUNfVVNSSU8gPSBBVDkxQ19FTUFDX1JNSUkgfCBBVDkxQ19FTUFDX0NMS0VOIDsNCgkjZW5kaWYNCg0KCS8qIEVuZCBvZiBjb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCgkvKiBTZXR1cCB0aGUgYnVmZmVycyBhbmQgZGVzY3JpcHRvcnMuICovDQoJcHJ2U2V0dXBEZXNjcmlwdG9ycygpOw0KCQ0KCS8qIExvYWQgb3VyIE1BQyBhZGRyZXNzIGludG8gdGhlIEVNQUMuICovDQoJcHJ2U2V0dXBNQUNBZGRyZXNzKCk7DQoNCgkvKiBBcmUgd2UgY29ubmVjdGVkPyAqLw0KCWlmKCBwcnZQcm9iZVBIWSgpICkNCgl7DQoJCS8qIEVuYWJsZSB0aGUgaW50ZXJydXB0ISAqLw0KCQlwb3J0RU5URVJfQ1JJVElDQUwoKTsNCgkJew0KCQkJcHJ2U2V0dXBFTUFDSW50ZXJydXB0KCk7DQoJCQl2UGFzc0VNQUNTZW1hcGhvcmUoIHhTZW1hcGhvcmUgKTsNCgkJfQ0KCQlwb3J0RVhJVF9DUklUSUNBTCgpOw0KCX0NCg0KCXJldHVybiB4U2VtYXBob3JlOw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCmxvbmcgbEVNQUNTZW5kKCB2b2lkICkNCnsNCnN0YXRpYyB1bnNpZ25lZCBwb3J0QkFTRV9UWVBFIHV4VHhCdWZmZXJJbmRleCA9IDA7DQpwb3J0QkFTRV9UWVBFIHhXYWl0Q3ljbGVzID0gMDsNCmxvbmcgbFJldHVybiA9IHBkUEFTUzsNCmNoYXIgKnBjQnVmZmVyOw0KDQoJLyogSXMgYSBidWZmZXIgYXZhaWxhYmxlPyAqLw0KCXdoaWxlKCAhKCB4VHhEZXNjcmlwdG9yc1sgdXhUeEJ1ZmZlckluZGV4IF0uVV9TdGF0dXMuc3RhdHVzICYgQVQ5MUNfVFJBTlNNSVRfT0sgKSApDQoJew0KCQkvKiBUaGVyZSBpcyBubyByb29tIHRvIHdyaXRlIHRoZSBUeCBkYXRhIHRvIHRoZSBUeCBidWZmZXIuICBXYWl0IGENCgkJc2hvcnQgd2hpbGUsIHRoZW4gdHJ5IGFnYWluLiAqLw0KCQl4V2FpdEN5Y2xlcysrOw0KCQlpZiggeFdhaXRDeWNsZXMgPiBlbWFjTUFYX1dBSVRfQ1lDTEVTICkNCgkJew0KCQkJLyogR2l2ZSB1cC4gKi8NCgkJCWxSZXR1cm4gPSBwZEZBSUw7DQoJCQlicmVhazsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXZUYXNrRGVsYXkoIGVtYWNCVUZGRVJfV0FJVF9ERUxBWSApOw0KCQl9DQoJfQ0KDQoJLyogbFJldHVybiB3aWxsIG9ubHkgYmUgcGRQQVNTIGlmIGEgYnVmZmVyIGlzIGF2YWlsYWJsZS4gKi8NCglpZiggbFJldHVybiA9PSBwZFBBU1MgKQ0KCXsNCgkJLyogQ29weSB0aGUgaGVhZGVycyBpbnRvIHRoZSBUeCBidWZmZXIuICBUaGVzZSB3aWxsIGJlIGluIHRoZSB1SVAgYnVmZmVyLiAqLw0KCQlwY0J1ZmZlciA9ICggY2hhciAqICkgeFR4RGVzY3JpcHRvcnNbIHV4VHhCdWZmZXJJbmRleCBdLmFkZHI7DQoJCW1lbWNweSggKCB2b2lkICogKSBwY0J1ZmZlciwgKCB2b2lkICogKSB1aXBfYnVmLCBlbWFjVE9UQUxfRlJBTUVfSEVBREVSX1NJWkUgKTsNCg0KCQkvKiBJZiB0aGVyZSBpcyByb29tLCBhbHNvIGNvcHkgaW4gdGhlIGFwcGxpY2F0aW9uIGRhdGEgaWYgYW55LiAqLw0KCQlpZiggKCB1aXBfbGVuID4gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgJiYgKCB1aXBfbGVuIDw9ICggRVRIX1RYX0JVRkZFUl9TSVpFIC0gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgKSApDQoJCXsNCgkJCW1lbWNweSggKCB2b2lkICogKSAmKCBwY0J1ZmZlclsgZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFIF0gKSwgKCB2b2lkICogKSB1aXBfYXBwZGF0YSwgKCB1aXBfbGVuIC0gZW1hY1RPVEFMX0ZSQU1FX0hFQURFUl9TSVpFICkgKTsNCgkJfQ0KDQoJCS8qIFNlbmQuICovCQ0KCQlwb3J0RU5URVJfQ1JJVElDQUwoKTsNCgkJew0KCQkJaWYoIHV4VHhCdWZmZXJJbmRleCA+PSAoIE5CX1RYX0JVRkZFUlMgLSAxICkgKQ0KCQkJew0KCQkJCS8qIEZpbGwgb3V0IHRoZSBuZWNlc3NhcnkgaW4gdGhlIGRlc2NyaXB0b3IgdG8gZ2V0IHRoZSBkYXRhIHNlbnQuICovDQoJCQkJeFR4RGVzY3JpcHRvcnNbIHV4VHhCdWZmZXJJbmRleCBdLlVfU3RhdHVzLnN0YXR1cyA9IAkoIHVpcF9sZW4gJiAoIHVuc2lnbmVkIGxvbmcgKSBBVDkxQ19MRU5HVEhfRlJBTUUgKQ0KCQkJCQkJCQkJCQkJCQkJCQkJfCBBVDkxQ19MQVNUX0JVRkZFUg0KCQkJCQkJCQkJCQkJCQkJCQkJfCBBVDkxQ19UUkFOU01JVF9XUkFQOw0KCQkJCXV4VHhCdWZmZXJJbmRleCA9IDA7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJLyogRmlsbCBvdXQgdGhlIG5lY2Vzc2FyeSBpbiB0aGUgZGVzY3JpcHRvciB0byBnZXQgdGhlIGRhdGEgc2VudC4gKi8NCgkJCQl4VHhEZXNjcmlwdG9yc1sgdXhUeEJ1ZmZlckluZGV4IF0uVV9TdGF0dXMuc3RhdHVzID0gCSggdWlwX2xlbiAmICggdW5zaWduZWQgbG9uZyApIEFUOTFDX0xFTkdUSF9GUkFNRSApDQoJCQkJCQkJCQkJCQkJCQkJCQl8IEFUOTFDX0xBU1RfQlVGRkVSOw0KCQkJCXV4VHhCdWZmZXJJbmRleCsrOw0KCQkJfQ0KCQ0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiB8PSBBVDkxQ19FTUFDX1RTVEFSVDsNCgkJfQ0KCQlwb3J0RVhJVF9DUklUSUNBTCgpOw0KCX0NCg0KCXJldHVybiBsUmV0dXJuOw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnVuc2lnbmVkIGxvbmcgdWxFTUFDUG9sbCggdm9pZCApDQp7DQpzdGF0aWMgdW5zaWduZWQgcG9ydEJBU0VfVFlQRSB1bE5leHRSeEJ1ZmZlciA9IDA7DQp1bnNpZ25lZCBsb25nIHVsU2VjdGlvbkxlbmd0aCA9IDAsIHVsTGVuZ3RoU29GYXIgPSAwLCB1bEVPRiA9IHBkRkFMU0U7DQpjaGFyICpwY1NvdXJjZTsNCg0KCS8qIFNraXAgYW55IGZyYWdtZW50cy4gKi8NCgl3aGlsZSggKCB4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICYgQVQ5MUNfT1dORVJTSElQX0JJVCApICYmICEoIHhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLlVfU3RhdHVzLnN0YXR1cyAmIEFUOTFDX1NPRiApICkNCgl7DQoJCS8qIE1hcmsgdGhlIGJ1ZmZlciBhcyBmcmVlIGFnYWluLiAqLw0KCQl4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICY9IH4oIEFUOTFDX09XTkVSU0hJUF9CSVQgKTsJCQ0KCQl1bE5leHRSeEJ1ZmZlcisrOw0KCQlpZiggdWxOZXh0UnhCdWZmZXIgPj0gTkJfUlhfQlVGRkVSUyApDQoJCXsNCgkJCXVsTmV4dFJ4QnVmZmVyID0gMDsNCgkJfQ0KCX0NCg0KCS8qIElzIHRoZXJlIGEgcGFja2V0IHJlYWR5PyAqLw0KDQoJd2hpbGUoICggeFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uYWRkciAmIEFUOTFDX09XTkVSU0hJUF9CSVQgKSAmJiAhdWxTZWN0aW9uTGVuZ3RoICkNCgl7DQoJCXBjU291cmNlID0gKCBjaGFyICogKSggeFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uYWRkciAmIGVtYWNBRERSRVNTX01BU0sgKTsNCgkJdWxTZWN0aW9uTGVuZ3RoID0geFJ4RGVzY3JpcHRvcnNbIHVsTmV4dFJ4QnVmZmVyIF0uVV9TdGF0dXMuc3RhdHVzICYgZW1hY1JYX0xFTkdUSF9GUkFNRTsNCg0KCQlpZiggdWxTZWN0aW9uTGVuZ3RoID09IDAgKQ0KCQl7DQoJCQkvKiBUaGUgZnJhbWUgaXMgbG9uZ2VyIHRoYW4gdGhlIGJ1ZmZlciBwb2ludGVkIHRvIGJ5IHRoaXMNCgkJCWRlc2NyaXB0b3Igc28gY29weSB0aGUgZW50aXJlIGJ1ZmZlciB0byB1SVAgLSB0aGVuIG1vdmUgb250bw0KCQkJdGhlIG5leHQgZGVzY3JpcHRvciB0byBnZXQgdGhlIHJlc3Qgb2YgdGhlIGZyYW1lLiAqLw0KCQkJaWYoICggdWxMZW5ndGhTb0ZhciArIEVUSF9SWF9CVUZGRVJfU0laRSApIDw9IFVJUF9CVUZTSVpFICkNCgkJCXsNCgkJCQltZW1jcHkoICYoIHVpcF9idWZbIHVsTGVuZ3RoU29GYXIgXSApLCBwY1NvdXJjZSwgRVRIX1JYX0JVRkZFUl9TSVpFICk7DQoJCQkJdWxMZW5ndGhTb0ZhciArPSBFVEhfUlhfQlVGRkVSX1NJWkU7DQoJCQl9CQkJDQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKiBUaGlzIGlzIHRoZSBsYXN0IHNlY3Rpb24gb2YgdGhlIGZyYW1lLiAgQ29weSB0aGUgc2VjdGlvbiB0bw0KCQkJdUlQLiAqLw0KCQkJaWYoIHVsU2VjdGlvbkxlbmd0aCA8IFVJUF9CVUZTSVpFICkNCgkJCXsNCgkJCQkvKiBUaGUgc2VjdGlvbiBsZW5ndGggaG9sZHMgdGhlIGxlbmd0aCBvZiB0aGUgZW50aXJlIGZyYW1lLg0KCQkJCXVsTGVuZ3RoU29GYXIgaG9sZHMgdGhlIGxlbmd0aCBvZiB0aGUgZnJhbWUgc2VjdGlvbnMgYWxyZWFkeQ0KCQkJCWNvcGllZCB0byB1SVAsIHNvIHRoZSBsZW5ndGggb2YgdGhlIGZpbmFsIHNlY3Rpb24gaXMNCgkJCQl1bFNlY3Rpb25MZW5ndGggLSB1bExlbmd0aFNvRmFyOyAqLw0KCQkJCWlmKCB1bFNlY3Rpb25MZW5ndGggPiB1bExlbmd0aFNvRmFyICkNCgkJCQl7DQoJCQkJCW1lbWNweSggJiggdWlwX2J1ZlsgdWxMZW5ndGhTb0ZhciBdICksIHBjU291cmNlLCAoIHVsU2VjdGlvbkxlbmd0aCAtIHVsTGVuZ3RoU29GYXIgKSApOw0KCQkJCX0NCgkJCX0JCQkNCg0KCQkJLyogSXMgdGhpcyB0aGUgbGFzdCBidWZmZXIgZm9yIHRoZSBmcmFtZT8gIElmIG5vdCB3aHk/ICovDQoJCQl1bEVPRiA9IHhSeERlc2NyaXB0b3JzWyB1bE5leHRSeEJ1ZmZlciBdLlVfU3RhdHVzLnN0YXR1cyAmIEFUOTFDX0VPRjsNCgkJfQ0KDQoJCS8qIE1hcmsgdGhlIGJ1ZmZlciBhcyBmcmVlIGFnYWluLiAqLw0KCQl4UnhEZXNjcmlwdG9yc1sgdWxOZXh0UnhCdWZmZXIgXS5hZGRyICY9IH4oIEFUOTFDX09XTkVSU0hJUF9CSVQgKTsNCg0KCQkvKiBJbmNyZW1lbnQgdG8gdGhlIG5leHQgYnVmZmVyLCB3cmFwcGluZyBpZiBuZWNlc3NhcnkuICovDQoJCXVsTmV4dFJ4QnVmZmVyKys7DQoJCWlmKCB1bE5leHRSeEJ1ZmZlciA+PSBOQl9SWF9CVUZGRVJTICkNCgkJew0KCQkJdWxOZXh0UnhCdWZmZXIgPSAwOw0KCQl9DQoJfQ0KDQoJLyogSWYgd2Ugb2J0YWluZWQgZGF0YSBidXQgZm9yIHNvbWUgcmVhc29uIGRpZCBub3QgZmluZCB0aGUgZW5kIG9mIHRoZQ0KCWZyYW1lIHRoZW4gZGlzY2FyZCB0aGUgZGF0YSBhcyBpdCBtdXN0IGNvbnRhaW4gYW4gZXJyb3IuICovDQoJaWYoICF1bEVPRiApDQoJew0KCQl1bFNlY3Rpb25MZW5ndGggPSAwOw0KCX0NCg0KCXJldHVybiB1bFNlY3Rpb25MZW5ndGg7DQp9DQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kc3RhdGljIHZvaWQgcHJ2U2V0dXBEZXNjcmlwdG9ycyh2b2lkKQ0Kew0KdW5zaWduZWQgcG9ydEJBU0VfVFlQRSB4SW5kZXg7DQp1bnNpZ25lZCBsb25nIHVsQWRkcmVzczsNCg0KCS8qIEluaXRpYWxpc2UgeFJ4RGVzY3JpcHRvcnMgZGVzY3JpcHRvci4gKi8NCglmb3IoIHhJbmRleCA9IDA7IHhJbmRleCA8IE5CX1JYX0JVRkZFUlM7ICsreEluZGV4ICkNCgl7DQoJCS8qIENhbGN1bGF0ZSB0aGUgYWRkcmVzcyBvZiB0aGUgbnRoIGJ1ZmZlciB3aXRoaW4gdGhlIGFycmF5LiAqLw0KCQl1bEFkZHJlc3MgPSAoIHVuc2lnbmVkIGxvbmcgKSggcGNSeEJ1ZmZlciArICggeEluZGV4ICogRVRIX1JYX0JVRkZFUl9TSVpFICkgKTsNCg0KCQkvKiBXcml0ZSB0aGUgYnVmZmVyIGFkZHJlc3MgaW50byB0aGUgZGVzY3JpcHRvci4gIFRoZSBETUEgd2lsbCBwbGFjZQ0KCQl0aGUgZGF0YSBhdCB0aGlzIGFkZHJlc3Mgd2hlbiB0aGlzIGRlc2NyaXB0b3IgaXMgYmVpbmcgdXNlZC4gIE1hc2sgb2ZmDQoJCXRoZSBib3R0b20gYml0cyBvZiB0aGUgYWRkcmVzcyBhcyB0aGVzZSBoYXZlIHNwZWNpYWwgbWVhbmluZy4gKi8NCgkJeFJ4RGVzY3JpcHRvcnNbIHhJbmRleCBdLmFkZHIgPSB1bEFkZHJlc3MgJiBlbWFjQUREUkVTU19NQVNLOw0KCX0JDQoNCgkvKiBUaGUgbGFzdCBidWZmZXIgaGFzIHRoZSB3cmFwIGJpdCBzZXQgc28gdGhlIEVNQUMga25vd3MgdG8gd3JhcCBiYWNrDQoJdG8gdGhlIGZpcnN0IGJ1ZmZlci4gKi8NCgl4UnhEZXNjcmlwdG9yc1sgTkJfUlhfQlVGRkVSUyAtIDEgXS5hZGRyIHw9IGVtYWNSWF9XUkFQX0JJVDsNCg0KCS8qIEluaXRpYWxpc2UgeFR4RGVzY3JpcHRvcnMuICovDQoJZm9yKCB4SW5kZXggPSAwOyB4SW5kZXggPCBOQl9UWF9CVUZGRVJTOyArK3hJbmRleCApDQoJew0KCQkvKiBDYWxjdWxhdGUgdGhlIGFkZHJlc3Mgb2YgdGhlIG50aCBidWZmZXIgd2l0aGluIHRoZSBhcnJheS4gKi8NCgkJdWxBZGRyZXNzID0gKCB1bnNpZ25lZCBsb25nICkoIHBjVHhCdWZmZXIgKyAoIHhJbmRleCAqIEVUSF9UWF9CVUZGRVJfU0laRSApICk7DQoNCgkJLyogV3JpdGUgdGhlIGJ1ZmZlciBhZGRyZXNzIGludG8gdGhlIGRlc2NyaXB0b3IuICBUaGUgRE1BIHdpbGwgcmVhZA0KCQlkYXRhIGZyb20gaGVyZSB3aGVuIHRoZSBkZXNjcmlwdG9yIGlzIGJlaW5nIHVzZWQuICovDQoJCXhUeERlc2NyaXB0b3JzWyB4SW5kZXggXS5hZGRyID0gdWxBZGRyZXNzICYgZW1hY0FERFJFU1NfTUFTSzsNCgkJeFR4RGVzY3JpcHRvcnNbIHhJbmRleCBdLlVfU3RhdHVzLnN0YXR1cyA9IEFUOTFDX1RSQU5TTUlUX09LOw0KCX0JDQoNCgkvKiBUaGUgbGFzdCBidWZmZXIgaGFzIHRoZSB3cmFwIGJpdCBzZXQgc28gdGhlIEVNQUMga25vd3MgdG8gd3JhcCBiYWNrDQoJdG8gdGhlIGZpcnN0IGJ1ZmZlci4gKi8NCgl4VHhEZXNjcmlwdG9yc1sgTkJfVFhfQlVGRkVSUyAtIDEgXS5VX1N0YXR1cy5zdGF0dXMgPSBBVDkxQ19UUkFOU01JVF9XUkFQIHwgQVQ5MUNfVFJBTlNNSVRfT0s7DQoNCgkvKiBUZWxsIHRoZSBFTUFDIHdoZXJlIHRvIGZpbmQgdGhlIGRlc2NyaXB0b3JzLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19SQlFQID0gKCB1bnNpZ25lZCBsb25nICkgeFJ4RGVzY3JpcHRvcnM7DQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX1RCUVAgPSAoIHVuc2lnbmVkIGxvbmcgKSB4VHhEZXNjcmlwdG9yczsNCgkNCgkvKiBDbGVhciBhbGwgdGhlIGJpdHMgaW4gdGhlIHJlY2VpdmUgc3RhdHVzIHJlZ2lzdGVyLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19SU1IgPSAoIEFUOTFDX0VNQUNfT1ZSIHwgQVQ5MUNfRU1BQ19SRUMgfCBBVDkxQ19FTUFDX0JOQSApOw0KDQoJLyogRW5hYmxlIHRoZSBjb3B5IG9mIGRhdGEgaW50byB0aGUgYnVmZmVycywgaWdub3JlIGJyb2FkY2FzdHMsDQoJYW5kIGRvbid0IGNvcHkgRkNTLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiB8PSAoIEFUOTFDX0VNQUNfQ0FGIHwgQVQ5MUNfRU1BQ19OQkMgfCBBVDkxQ19FTUFDX0RSRkNTKTsNCg0KCS8qIEVuYWJsZSBSeCBhbmQgVHgsIHBsdXMgdGhlIHN0YXRzIHJlZ2lzdGVyLiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ1IgfD0gKCBBVDkxQ19FTUFDX1RFIHwgQVQ5MUNfRU1BQ19SRSB8IEFUOTFDX0VNQUNfV0VTVEFUICk7DQp9CQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnN0YXRpYyB2b2lkIHBydlNldHVwTUFDQWRkcmVzcyggdm9pZCApDQp7DQoJLyogTXVzdCBiZSB3cml0dGVuIFNBMUwgdGhlbiBTQTFILiAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19TQTFMID0JKCAoIHVuc2lnbmVkIGxvbmcgKSBjTUFDQWRkcmVzc1sgMyBdIDw8IDI0ICkgfA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBjTUFDQWRkcmVzc1sgMiBdIDw8IDE2ICkgfA0KCQkJCQkJCQkJKCAoIHVuc2lnbmVkIGxvbmcgKSBjTUFDQWRkcmVzc1sgMSBdIDw8IDggICkgfA0KCQkJCQkJCQkJY01BQ0FkZHJlc3NbIDAgXTsNCg0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19TQTFIID0JKCAoIHVuc2lnbmVkIGxvbmcgKSBjTUFDQWRkcmVzc1sgNSBdIDw8IDggKSB8DQoJCQkJCQkJCQljTUFDQWRkcmVzc1sgNCBdOw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnN0YXRpYyB2b2lkIHBydlNldHVwRU1BQ0ludGVycnVwdCggdm9pZCApDQp7DQoJLyogQ3JlYXRlIHRoZSBzZW1hcGhvcmUgdXNlZCB0byB0cmlnZ2VyIHRoZSBFTUFDIHRhc2suICovDQoJdlNlbWFwaG9yZUNyZWF0ZUJpbmFyeSggeFNlbWFwaG9yZSApOw0KCWlmKCB4U2VtYXBob3JlICkNCgl7DQoJCS8qIFdlIHN0YXJ0IGJ5ICd0YWtpbmcnIHRoZSBzZW1hcGhvcmUgc28gdGhlIElTUiBjYW4gJ2dpdmUnIGl0IHdoZW4gdGhlDQoJCWZpcnN0IGludGVycnVwdCBvY2N1cnMuICovDQoJCXhTZW1hcGhvcmVUYWtlKCB4U2VtYXBob3JlLCBlbWFjTk9fREVMQVkgKTsNCgkJcG9ydEVOVEVSX0NSSVRJQ0FMKCk7DQoJCXsNCgkJCS8qIFdlIHdhbnQgdG8gaW50ZXJydXB0IG9uIFJ4IGV2ZW50cy4gKi8NCgkJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19JRVIgPSBBVDkxQ19FTUFDX1JDT01QOw0KDQoJCQkvKiBFbmFibGUgdGhlIGludGVycnVwdHMgaW4gdGhlIEFJQy4gKi8NCgkJCUFUOTFGX0FJQ19Db25maWd1cmVJdCggQVQ5MUNfSURfRU1BQywgZW1hY0lOVEVSUlVQVF9MRVZFTCwgQVQ5MUNfQUlDX1NSQ1RZUEVfSU5UX0hJR0hfTEVWRUwsICggdm9pZCAoKikoIHZvaWQgKSApIHZFTUFDSVNSX1dyYXBwZXIgKTsNCgkJCUFUOTFDX0JBU0VfQUlDLT5BSUNfSUVDUiA9IDB4MSA8PCBBVDkxQ19JRF9FTUFDOw0KCQl9DQoJCXBvcnRFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCg0KDQoNCi8qDQogKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBhcmUgaW5pdGlhbGlzYXRpb24gZnVuY3Rpb25zIHRha2VuIGZyb20gdGhlIEF0bWVsDQogKiBFTUFDIHNhbXBsZSBjb2RlLg0KICovDQoNCnN0YXRpYyBwb3J0QkFTRV9UWVBFIHBydlByb2JlUEhZKCB2b2lkICkNCnsNCnVuc2lnbmVkIGxvbmcgdWxQSFlJZDEsIHVsUEhZSWQyLCB1bFN0YXR1czsNCnBvcnRCQVNFX1RZUEUgeFJldHVybiA9IHBkUEFTUzsNCgkNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIChyZWZvcm1hdHRlZCkgLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJLyogRW5hYmxlIG1hbmFnZW1lbnQgcG9ydCAqLw0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ1IgfD0gQVQ5MUNfRU1BQ19NUEU7CQ0KCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiB8PSAoIDIgKSA8PCAxMDsNCg0KCS8qIFJlYWQgdGhlIFBIWSBJRC4gKi8NCgl2UmVhZFBIWSggQVQ5MUNfUEhZX0FERFIsIE1JSV9QSFlTSUQxLCAmdWxQSFlJZDEgKTsNCgl2UmVhZFBIWSggQVQ5MUNfUEhZX0FERFIsIE1JSV9QSFlTSUQyLCAmdWxQSFlJZDIgKTsNCg0KCS8qIEFNRCBBTTc5Qzg3NToNCgkJCVBIWV9JRDEgPSAweDAwMjINCgkJCVBIWV9JRDIgPSAweDU1NDENCgkJCUJpdHMgMzowIFJldmlzaW9uIE51bWJlciBGb3VyIGJpdCBtYW51ZmFjdHVyZXKScyByZXZpc2lvbiBudW1iZXIuDQoJCQkJMDAwMSBzdGFuZHMgZm9yIFJldi4gQSwgZXRjLg0KCSovDQoJaWYoICggKCB1bFBIWUlkMSA8PCAxNiApIHwgKCB1bFBIWUlkMiAmIDB4ZmZmMCApICkgIT0gTUlJX0RNOTE2MV9JRCApDQoJew0KCQkvKiBEaWQgbm90IGV4cGVjdCB0aGlzIElELiAqLw0KCQl4UmV0dXJuID0gcGRGQUlMOw0KCX0NCgllbHNlDQoJew0KCQl1bFN0YXR1cyA9IHhHZXRMaW5rU3BlZWQoKTsNCg0KCQlpZiggdWxTdGF0dXMgIT0gcGRQQVNTICkNCgkJew0KCQkJeFJldHVybiA9IHBkRkFJTDsNCgkJfQ0KCX0NCg0KCS8qIERpc2FibGUgbWFuYWdlbWVudCBwb3J0ICovDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DUiAmPSB+QVQ5MUNfRU1BQ19NUEU7CQ0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCXJldHVybiB4UmV0dXJuOw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCnN0YXRpYyB2b2lkIHZSZWFkUEhZKCB1bnNpZ25lZCBjaGFyIHVjUEhZQWRkcmVzcywgdW5zaWduZWQgY2hhciB1Y0FkZHJlc3MsIHVuc2lnbmVkIGxvbmcgKnB1bFZhbHVlICkNCnsNCgkvKiBDb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIChyZWZvcm1hdHRlZCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCglBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTUFOID0gCShBVDkxQ19FTUFDX1NPRiAmICgweDAxPDwzMCkpDQoJCQkJCQkJCQl8ICgyIDw8IDE2KSB8ICgyIDw8IDI4KQ0KCQkJCQkJCQkJfCAoKHVjUEhZQWRkcmVzcyAmIDB4MWYpIDw8IDIzKQ0KCQkJCQkJCQkJfCAodWNBZGRyZXNzIDw8IDE4KTsNCg0KCS8qIFdhaXQgdW50aWwgSURMRSBiaXQgaW4gTmV0d29yayBTdGF0dXMgcmVnaXN0ZXIgaXMgY2xlYXJlZC4gKi8NCgl3aGlsZSggISggQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05TUiAmIEFUOTFDX0VNQUNfSURMRSApICkNCgl7DQoJCV9fYXNtKCAiTk9QIiApOw0KCX0NCg0KCSpwdWxWYWx1ZSA9ICggQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX01BTiAmIDB4MDAwMGZmZmYgKTsJDQoNCgkvKiBFbmQgb2YgY29kZSBzdXBwbGllZCBieSBBdG1lbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCiNpZiBVU0VfUk1JSV9JTlRFUkZBQ0UgIT0gMQ0Kc3RhdGljIHZvaWQgdldyaXRlUEhZKCB1bnNpZ25lZCBjaGFyIHVjUEhZQWRkcmVzcywgdW5zaWduZWQgY2hhciB1Y0FkZHJlc3MsIHVuc2lnbmVkIGxvbmcgdWxWYWx1ZSApDQp7DQoJLyogQ29kZSBzdXBwbGllZCBieSBBdG1lbCAocmVmb3JtYXR0ZWQpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQoJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX01BTiA9ICgoIEFUOTFDX0VNQUNfU09GICYgKDB4MDE8PDMwKSkNCgkJCQkJCQkJfCAoMiA8PCAxNikgfCAoMSA8PCAyOCkNCgkJCQkJCQkJfCAoKHVjUEhZQWRkcmVzcyAmIDB4MWYpIDw8IDIzKQ0KCQkJCQkJCQl8ICh1Y0FkZHJlc3MgPDwgMTgpKQ0KCQkJCQkJCQl8ICh1bFZhbHVlICYgMHhmZmZmKTsNCg0KCS8qIFdhaXQgdW50aWwgSURMRSBiaXQgaW4gTmV0d29yayBTdGF0dXMgcmVnaXN0ZXIgaXMgY2xlYXJlZCAqLw0KCXdoaWxlKCAhKCBBVDkxQ19CQVNFX0VNQUMtPkVNQUNfTlNSICYgQVQ5MUNfRU1BQ19JRExFICkgKQ0KCXsNCgkJX19hc20oICJOT1AiICk7DQoJfTsNCg0KCS8qIEVuZCBvZiBjb2RlIHN1cHBsaWVkIGJ5IEF0bWVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQp9DQojZW5kaWYNCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQpzdGF0aWMgcG9ydEJBU0VfVFlQRSB4R2V0TGlua1NwZWVkKCB2b2lkICkNCnsNCgl1bnNpZ25lZCBsb25nIHVsQk1TUiwgdWxCTUNSLCB1bExQQSwgdWxNQUNDZmcsIHVsU3BlZWQsIHVsRHVwbGV4Ow0KDQoJLyogQ29kZSBzdXBwbGllZCBieSBBdG1lbCAocmVmb3JtYXR0ZWQpIC0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCS8qIExpbmsgc3RhdHVzIGlzIGxhdGNoZWQsIHNvIHJlYWQgdHdpY2UgdG8gZ2V0IGN1cnJlbnQgdmFsdWUgKi8NCgl2UmVhZFBIWShBVDkxQ19QSFlfQUREUiwgTUlJX0JNU1IsICZ1bEJNU1IpOw0KCXZSZWFkUEhZKEFUOTFDX1BIWV9BRERSLCBNSUlfQk1TUiwgJnVsQk1TUik7DQoNCglpZiggISggdWxCTVNSICYgQk1TUl9MU1RBVFVTICkgKQ0KCXsJDQoJCS8qIE5vIExpbmsuICovDQoJCXJldHVybiBwZEZBSUw7DQoJfQ0KDQoJdlJlYWRQSFkoQVQ5MUNfUEhZX0FERFIsIE1JSV9CTUNSLCAmdWxCTUNSKTsNCglpZiAodWxCTUNSICYgQk1DUl9BTkVOQUJMRSkNCgl7CQkJCQ0KCQkvKiBBdXRvTmVnb3RpYXRpb24gaXMgZW5hYmxlZC4gKi8NCgkJaWYgKCEodWxCTVNSICYgQk1TUl9BTkVHQ09NUExFVEUpKQ0KCQl7DQoJCQkvKiBBdXRvLW5lZ290aWF0aW9uIGluIHByb2dyZXNzLiAqLw0KCQkJcmV0dXJuIHBkRkFJTDsJCQkJDQoJCX0JCQ0KDQoJCXZSZWFkUEhZKEFUOTFDX1BIWV9BRERSLCBNSUlfTFBBLCAmdWxMUEEpOw0KCQlpZiggKCB1bExQQSAmIExQQV8xMDBGVUxMICkgfHwgKCB1bExQQSAmIExQQV8xMDBIQUxGICkgKQ0KCQl7DQoJCQl1bFNwZWVkID0gU1BFRURfMTAwOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdWxTcGVlZCA9IFNQRUVEXzEwOw0KCQl9DQoNCgkJaWYoICggdWxMUEEgJiBMUEFfMTAwRlVMTCApIHx8ICggdWxMUEEgJiBMUEFfMTBGVUxMICkgKQ0KCQl7DQoJCQl1bER1cGxleCA9IERVUExFWF9GVUxMOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdWxEdXBsZXggPSBEVVBMRVhfSEFMRjsNCgkJfQ0KCX0NCgllbHNlDQoJew0KCQl1bFNwZWVkID0gKCB1bEJNQ1IgJiBCTUNSX1NQRUVEMTAwICkgPyBTUEVFRF8xMDAgOiBTUEVFRF8xMDsNCgkJdWxEdXBsZXggPSAoIHVsQk1DUiAmIEJNQ1JfRlVMTERQTFggKSA/IERVUExFWF9GVUxMIDogRFVQTEVYX0hBTEY7DQoJfQ0KDQoJLyogVXBkYXRlIHRoZSBNQUMgKi8NCgl1bE1BQ0NmZyA9IEFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiAmIH4oIEFUOTFDX0VNQUNfU1BEIHwgQVQ5MUNfRU1BQ19GRCApOw0KCWlmKCB1bFNwZWVkID09IFNQRUVEXzEwMCApDQoJew0KCQlpZiggdWxEdXBsZXggPT0gRFVQTEVYX0ZVTEwgKQ0KCQl7DQoJCQkvKiAxMDAgRnVsbCBEdXBsZXggKi8NCgkJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiA9IHVsTUFDQ2ZnIHwgQVQ5MUNfRU1BQ19TUEQgfCBBVDkxQ19FTUFDX0ZEOw0KCQl9DQoJCWVsc2UNCgkJewkJCQkJDQoJCQkvKiAxMDAgSGFsZiBEdXBsZXggKi8NCgkJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiA9IHVsTUFDQ2ZnIHwgQVQ5MUNfRU1BQ19TUEQ7DQoJCX0NCgl9DQoJZWxzZQ0KCXsNCgkJaWYgKHVsRHVwbGV4ID09IERVUExFWF9GVUxMKQ0KCQl7DQoJCQkvKiAxMCBGdWxsIER1cGxleCAqLw0KCQkJQVQ5MUNfQkFTRV9FTUFDLT5FTUFDX05DRkdSID0gdWxNQUNDZmcgfCBBVDkxQ19FTUFDX0ZEOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJLyogMTAgSGFsZiBEdXBsZXggKi8NCgkJCUFUOTFDX0JBU0VfRU1BQy0+RU1BQ19OQ0ZHUiA9IHVsTUFDQ2ZnOw0KCQl9DQoJfQ0KDQoJLyogRW5kIG9mIGNvZGUgc3VwcGxpZWQgYnkgQXRtZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KCXJldHVybiBwZFBBU1M7DQp9DQo=