Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBUSUZGIExvYWRlciBhbmQgV3JpdGVyCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkgCi8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gTWFya3VzIExvaWJsIChtYXJrdXMubG9pYmxAZXBvc3QuZGUpCi8vIC0gTHVjYSBQaWVyZ2VudGlsaSAobC5waWVyZ2VAdGVycmEuZXMpCi8vIC0gRGV0bGV2IFZlbmR0IChkZXRsZXYudmVuZHRAYnJpbGxpdC5kZSkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZkZWYgX01TQ19WRVIgCiNwcmFnbWEgd2FybmluZyAoZGlzYWJsZSA6IDQ3ODYpIC8vIGlkZW50aWZpZXIgd2FzIHRydW5jYXRlZCB0byAnbnVtYmVyJyBjaGFyYWN0ZXJzCiNlbmRpZgoKI2lmZGVmIHVuaXgKI3VuZGVmIHVuaXgKI2VuZGlmCiNpZmRlZiBfX3VuaXgKI3VuZGVmIF9fdW5peAojZW5kaWYKCiNpbmNsdWRlICIuLi9MaWJUSUZGL3RpZmZpb3AuaCIKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCiNpbmNsdWRlICIuLi9NZXRhZGF0YS9GcmVlSW1hZ2VUYWcuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBnZW90aWZmIGludGVyZmFjZSAoc2VlIFhUSUZGLmNwcCkKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gRXh0ZW5kZWQgVElGRiBEaXJlY3RvcnkgR0VPIFRhZyBTdXBwb3J0CnZvaWQgWFRJRkZJbml0aWFsaXplKCk7CgovLyBHZW9USUZGIHByb2ZpbGUKdm9pZCB0aWZmX3JlYWRfZ2VvdGlmZl9wcm9maWxlKFRJRkYgKnRpZiwgRklCSVRNQVAgKmRpYik7CnZvaWQgdGlmZl93cml0ZV9nZW90aWZmX3Byb2ZpbGUoVElGRiAqdGlmLCBGSUJJVE1BUCAqZGliKTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBleGlmIGludGVyZmFjZSAoc2VlIFhUSUZGLmNwcCkKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gVElGRiBFeGlmIHByb2ZpbGUKQk9PTCB0aWZmX3JlYWRfZXhpZl90YWdzKFRJRkYgKnRpZiwgVGFnTGliOjpNRE1PREVMIG1kX21vZGVsLCBGSUJJVE1BUCAqZGliKTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBMb2dMdXYgY29udmVyc2lvbiBmdW5jdGlvbnMgaW50ZXJmYWNlIChzZWUgVElGRkxvZ0x1di5jcHApCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgdGlmZl9Db252ZXJ0TGluZVhZWlRvUkdCKEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBkb3VibGUgc3Rvbml0cywgaW50IHdpZHRoX2luX3BpeGVscyk7CnZvaWQgdGlmZl9Db252ZXJ0TGluZVJHQlRvWFlaKEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKiBTdXBwb3J0ZWQgbG9hZGluZyBtZXRob2RzICovCnR5cGVkZWYgZW51bSB7CglMb2FkQXNSQkdBCQkJPSAwLCAKCUxvYWRBc0NNWUsJCQk9IDEsIAoJTG9hZEFzOEJpdFRybnMJCT0gMiwgCglMb2FkQXNHZW5lcmljU3RyaXAJPSAzLCAKCUxvYWRBc1RpbGVkCQkJPSA0LAoJTG9hZEFzUkdCRgkJCT0gNQp9IFRJRkZMb2FkTWV0aG9kOwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIGxvY2FsIHByb3RvdHlwZXMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIHRzaXplX3QgX3RpZmZSZWFkUHJvYyh0aGFuZGxlX3QgaGFuZGxlLCB0ZGF0YV90IGJ1ZiwgdHNpemVfdCBzaXplKTsKc3RhdGljIHRzaXplX3QgX3RpZmZXcml0ZVByb2ModGhhbmRsZV90IGhhbmRsZSwgdGRhdGFfdCBidWYsIHRzaXplX3Qgc2l6ZSk7CnN0YXRpYyB0b2ZmX3QgX3RpZmZTZWVrUHJvYyh0aGFuZGxlX3QgaGFuZGxlLCB0b2ZmX3Qgb2ZmLCBpbnQgd2hlbmNlKTsKc3RhdGljIGludCBfdGlmZkNsb3NlUHJvYyh0aGFuZGxlX3QgZmQpOwpzdGF0aWMgaW50IF90aWZmTWFwUHJvYyh0aGFuZGxlX3QgZmQsIHRkYXRhX3QqIHBiYXNlLCB0b2ZmX3QqIHBzaXplKTsKc3RhdGljIHZvaWQgX3RpZmZVbm1hcFByb2ModGhhbmRsZV90IGZkLCB0ZGF0YV90IGJhc2UsIHRvZmZfdCBzaXplKTsKCnN0YXRpYyB1aW50MTYgQ2hlY2tDb2xvcm1hcChpbnQgbiwgdWludDE2KiByLCB1aW50MTYqIGcsIHVpbnQxNiogYik7CnN0YXRpYyB1aW50MTYgR2V0UGhvdG9tZXRyaWMoRklCSVRNQVAgKmRpYik7CgpzdGF0aWMgdm9pZCBSZWFkUmVzb2x1dGlvbihUSUZGICp0aWZmLCBGSUJJVE1BUCAqZGliKTsKc3RhdGljIHZvaWQgV3JpdGVSZXNvbHV0aW9uKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpOwoKc3RhdGljIHZvaWQgUmVhZFBhbGV0dGUoVElGRiAqdGlmZiwgdWludDE2IHBob3RvbWV0cmljLCB1aW50MTYgYml0c3BlcnNhbXBsZSwgRklCSVRNQVAgKmRpYik7CgpzdGF0aWMgRklCSVRNQVAqIENyZWF0ZUltYWdlVHlwZShGUkVFX0lNQUdFX1RZUEUgZml0LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIHVpbnQxNiBiaXRzcGVyc2FtcGxlLCB1aW50MTYgc2FtcGxlc3BlcnBpeGVsKTsKc3RhdGljIEZSRUVfSU1BR0VfVFlQRSBSZWFkSW1hZ2VUeXBlKFRJRkYgKnRpZmYsIHVpbnQxNiBiaXRzcGVyc2FtcGxlLCB1aW50MTYgc2FtcGxlc3BlcnBpeGVsKTsKc3RhdGljIHZvaWQgV3JpdGVJbWFnZVR5cGUoVElGRiAqdGlmZiwgRlJFRV9JTUFHRV9UWVBFIGZpdCk7CgpzdGF0aWMgdm9pZCBXcml0ZUNvbXByZXNzaW9uKFRJRkYgKnRpZmYsIHVpbnQxNiBiaXRzcGVyc2FtcGxlLCB1aW50MTYgc2FtcGxlc3BlcnBpeGVsLCB1aW50MTYgcGhvdG9tZXRyaWMsIGludCBmbGFncyk7CgpzdGF0aWMgQk9PTCB0aWZmX3JlYWRfaXB0Y19wcm9maWxlKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpOwpzdGF0aWMgQk9PTCB0aWZmX3JlYWRfeG1wX3Byb2ZpbGUoVElGRiAqdGlmZiwgRklCSVRNQVAgKmRpYik7CnN0YXRpYyBCT09MIHRpZmZfcmVhZF9leGlmX3Byb2ZpbGUoVElGRiAqdGlmZiwgRklCSVRNQVAgKmRpYik7CnN0YXRpYyB2b2lkIFJlYWRNZXRhZGF0YShUSUZGICp0aWZmLCBGSUJJVE1BUCAqZGliKTsKCnN0YXRpYyBCT09MIHRpZmZfd3JpdGVfaXB0Y19wcm9maWxlKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpOwpzdGF0aWMgQk9PTCB0aWZmX3dyaXRlX3htcF9wcm9maWxlKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpOwpzdGF0aWMgdm9pZCBXcml0ZU1ldGFkYXRhKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpOwoKc3RhdGljIFRJRkZMb2FkTWV0aG9kIEZpbmRMb2FkTWV0aG9kKFRJRkYgKnRpZiwgdWludDE2IHBob3RvbWV0cmljLCB1aW50MTYgYml0c3BlcnNhbXBsZSwgdWludDE2IHNhbXBsZXNwZXJwaXhlbCwgRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUsIGludCBmbGFncyk7CgoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW50ZXJmYWNlCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0YXRpYyBpbnQgc19mb3JtYXRfaWQ7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBGcmVlSW1hZ2VJTyAqaW87CglmaV9oYW5kbGUgaGFuZGxlOwoJVElGRiAqdGlmOwp9IGZpX1RJRkZJTzsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBsaWJ0aWZmIGludGVyZmFjZSAKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIHRzaXplX3QgCl90aWZmUmVhZFByb2ModGhhbmRsZV90IGhhbmRsZSwgdGRhdGFfdCBidWYsIHRzaXplX3Qgc2l6ZSkgewoJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKiloYW5kbGU7CglyZXR1cm4gZmlvLT5pby0+cmVhZF9wcm9jKGJ1Ziwgc2l6ZSwgMSwgZmlvLT5oYW5kbGUpICogc2l6ZTsKfQoKc3RhdGljIHRzaXplX3QKX3RpZmZXcml0ZVByb2ModGhhbmRsZV90IGhhbmRsZSwgdGRhdGFfdCBidWYsIHRzaXplX3Qgc2l6ZSkgewoJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKiloYW5kbGU7CglyZXR1cm4gZmlvLT5pby0+d3JpdGVfcHJvYyhidWYsIHNpemUsIDEsIGZpby0+aGFuZGxlKSAqIHNpemU7Cn0KCnN0YXRpYyB0b2ZmX3QKX3RpZmZTZWVrUHJvYyh0aGFuZGxlX3QgaGFuZGxlLCB0b2ZmX3Qgb2ZmLCBpbnQgd2hlbmNlKSB7CglmaV9USUZGSU8gKmZpbyA9IChmaV9USUZGSU8qKWhhbmRsZTsKCWZpby0+aW8tPnNlZWtfcHJvYyhmaW8tPmhhbmRsZSwgb2ZmLCB3aGVuY2UpOwoJcmV0dXJuIGZpby0+aW8tPnRlbGxfcHJvYyhmaW8tPmhhbmRsZSk7Cn0KCnN0YXRpYyBpbnQKX3RpZmZDbG9zZVByb2ModGhhbmRsZV90IGZkKSB7CglyZXR1cm4gMDsKfQoKI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CgpzdGF0aWMgdG9mZl90Cl90aWZmU2l6ZVByb2ModGhhbmRsZV90IGhhbmRsZSkgewogICAgZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKiloYW5kbGU7CiAgICBsb25nIGN1cnJQb3MgPSBmaW8tPmlvLT50ZWxsX3Byb2MoZmlvLT5oYW5kbGUpOwogICAgZmlvLT5pby0+c2Vla19wcm9jKGZpby0+aGFuZGxlLCAwLCBTRUVLX0VORCk7CiAgICBsb25nIGZpbGVTaXplID0gZmlvLT5pby0+dGVsbF9wcm9jKGZpby0+aGFuZGxlKTsKICAgIGZpby0+aW8tPnNlZWtfcHJvYyhmaW8tPmhhbmRsZSwgY3VyclBvcywgU0VFS19TRVQpOwogICAgcmV0dXJuIGZpbGVTaXplOwp9CgpzdGF0aWMgaW50Cl90aWZmTWFwUHJvYyh0aGFuZGxlX3QgZmQsIHRkYXRhX3QqIHBiYXNlLCB0b2ZmX3QqIHBzaXplKSB7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKX3RpZmZVbm1hcFByb2ModGhhbmRsZV90IGZkLCB0ZGF0YV90IGJhc2UsIHRvZmZfdCBzaXplKSB7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBPcGVuIGEgVElGRiBmaWxlIGRlc2NyaXB0b3IgZm9yIHJlYWQvd3JpdGluZy4KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVElGRiAqClRJRkZGZE9wZW4odGhhbmRsZV90IGhhbmRsZSwgY29uc3QgY2hhciAqbmFtZSwgY29uc3QgY2hhciAqbW9kZSkgewoJVElGRiAqdGlmOwoKICAgIC8vIFNldCB1cCB0aGUgY2FsbGJhY2sgZm9yIGV4dGVuZGVkIFRJRkYgZGlyZWN0b3J5IHRhZyBzdXBwb3J0CgkvLyAoc2VlIFhUSUZGLmNwcCkKICAgIFhUSUZGSW5pdGlhbGl6ZSgpOwkKCQoJLy8gT3BlbiB0aGUgZmlsZTsgdGhlIGNhbGxiYWNrIHdpbGwgc2V0IGV2ZXJ5dGhpbmcgdXAKCXRpZiA9IFRJRkZDbGllbnRPcGVuKG5hbWUsIG1vZGUsIGhhbmRsZSwKCSAgICBfdGlmZlJlYWRQcm9jLCBfdGlmZldyaXRlUHJvYywgX3RpZmZTZWVrUHJvYywgX3RpZmZDbG9zZVByb2MsCgkgICAgX3RpZmZTaXplUHJvYywgX3RpZmZNYXBQcm9jLCBfdGlmZlVubWFwUHJvYyk7CgoJLy8gV2FybmluZzogdGlmX2ZkIGlzIGRlY2xhcmVkIGFzICdpbnQnIGN1cnJlbnRseSAoc2VlIGxpYlRJRkYpLCAKICAgIC8vIG1heSByZXN1bHQgaW4gaW5jb3JyZWN0IGZpbGUgcG9pbnRlcnMgaW5zaWRlIGxpYlRJRkYgb24gCiAgICAvLyA2NGJpdCBtYWNoaW5lcyAoc2l6ZW9mKGludCkgIT0gc2l6ZW9mKGxvbmcpKS4gCiAgICAvLyBOZWVkcyB0byBiZSBmaXhlZCB3aXRoaW4gbGliVElGRi4KICAgIGlmICh0aWYpCgkJdGlmLT50aWZfZmQgPSAobG9uZyloYW5kbGU7CgoJcmV0dXJuIHRpZjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIE9wZW4gYSBUSUZGIGZpbGUgZm9yIHJlYWQvd3JpdGluZy4KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVElGRioKVElGRk9wZW4oY29uc3QgY2hhciogbmFtZSwgY29uc3QgY2hhciogbW9kZSkgewoJcmV0dXJuIDA7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBUSUZGIGxpYnJhcnkgRnJlZUltYWdlLXNwZWNpZmljIHJvdXRpbmVzLgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp0ZGF0YV90Cl9USUZGbWFsbG9jKHRzaXplX3QgcykgewoJcmV0dXJuIG1hbGxvYyhzKTsKfQoKdm9pZApfVElGRmZyZWUodGRhdGFfdCBwKSB7CglmcmVlKHApOwp9Cgp0ZGF0YV90Cl9USUZGcmVhbGxvYyh0ZGF0YV90IHAsIHRzaXplX3QgcykgewoJcmV0dXJuIHJlYWxsb2MocCwgcyk7Cn0KCnZvaWQKX1RJRkZtZW1zZXQodGRhdGFfdCBwLCBpbnQgdiwgdHNpemVfdCBjKSB7CgltZW1zZXQocCwgdiwgKHNpemVfdCkgYyk7Cn0KCnZvaWQKX1RJRkZtZW1jcHkodGRhdGFfdCBkLCBjb25zdCB0ZGF0YV90IHMsIHRzaXplX3QgYykgewoJbWVtY3B5KGQsIHMsIChzaXplX3QpIGMpOwp9CgppbnQKX1RJRkZtZW1jbXAoY29uc3QgdGRhdGFfdCBwMSwgY29uc3QgdGRhdGFfdCBwMiwgdHNpemVfdCBjKSB7CglyZXR1cm4gKG1lbWNtcChwMSwgcDIsIChzaXplX3QpIGMpKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIGluIEZyZWVJbWFnZSB3YXJuaW5ncyBhbmQgZXJyb3JzIGFyZSBkaXNhYmxlZAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgdm9pZAptc2Rvc1dhcm5pbmdIYW5kbGVyKGNvbnN0IGNoYXIqIG1vZHVsZSwgY29uc3QgY2hhciogZm10LCB2YV9saXN0IGFwKSB7Cn0KClRJRkZFcnJvckhhbmRsZXIgX1RJRkZ3YXJuaW5nSGFuZGxlciA9IG1zZG9zV2FybmluZ0hhbmRsZXI7CgpzdGF0aWMgdm9pZAptc2Rvc0Vycm9ySGFuZGxlcihjb25zdCBjaGFyKiBtb2R1bGUsIGNvbnN0IGNoYXIqIGZtdCwgdmFfbGlzdCBhcCkgewoJCgkvLyB1c2UgdGhpcyBmb3IgZGlhZ25vc3RpYyBvbmx5IChkbyBub3QgdXNlIG90aGVyd2lzZSwgZXZlbiBpbiBERUJVRyBtb2RlKQoJLyoKCWlmIChtb2R1bGUgIT0gTlVMTCkgewoJCWNoYXIgbXNnWzEwMjRdOwoJCXZzcHJpbnRmKG1zZywgZm10LCBhcCk7CgkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiJXM6ICVzIiwgbW9kdWxlLCBtc2cpOwoJfQoJKi8KfQoKVElGRkVycm9ySGFuZGxlciBfVElGRmVycm9ySGFuZGxlciA9IG1zZG9zRXJyb3JIYW5kbGVyOwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2RlZmluZSBDVlQoeCkgICAgICAoKCh4KSAqIDI1NUwpIC8gKCgxTDw8MTYpLTEpKQojZGVmaW5lCVNDQUxFKHgpCSgoKHgpKigoMUw8PDE2KS0xKSkvMjU1KQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBJbnRlcm5hbCBmdW5jdGlvbnMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIHVpbnQxNgpDaGVja0NvbG9ybWFwKGludCBuLCB1aW50MTYqIHIsIHVpbnQxNiogZywgdWludDE2KiBiKSB7CiAgICB3aGlsZSAobi0tID4gMCkgewogICAgICAgIGlmICgqcisrID49IDI1NiB8fCAqZysrID49IDI1NiB8fCAqYisrID49IDI1NikgewoJCQlyZXR1cm4gMTY7CgkJfQoJfQoKICAgIHJldHVybiA4Owp9CgovKioKR2V0IHRoZSBUSUZGVEFHX1BIT1RPTUVUUklDIHZhbHVlIGZyb20gdGhlIGRpYgoqLwpzdGF0aWMgdWludDE2CkdldFBob3RvbWV0cmljKEZJQklUTUFQICpkaWIpIHsKCUZSRUVfSU1BR0VfQ09MT1JfVFlQRSBjb2xvcl90eXBlID0gRnJlZUltYWdlX0dldENvbG9yVHlwZShkaWIpOwoJc3dpdGNoKGNvbG9yX3R5cGUpIHsKCQljYXNlIEZJQ19NSU5JU1dISVRFOgkvLyBtaW4gdmFsdWUgaXMgd2hpdGUKCQkJcmV0dXJuIFBIT1RPTUVUUklDX01JTklTV0hJVEU7CgkJY2FzZSBGSUNfTUlOSVNCTEFDSzoJLy8gbWluIHZhbHVlIGlzIGJsYWNrCgkJCXJldHVybiBQSE9UT01FVFJJQ19NSU5JU0JMQUNLOwoJCWNhc2UgRklDX1BBTEVUVEU6CQkvLyBjb2xvciBtYXAgaW5kZXhlZAoJCQlyZXR1cm4gUEhPVE9NRVRSSUNfUEFMRVRURTsKCQljYXNlIEZJQ19SR0I6CQkJLy8gUkdCIGNvbG9yIG1vZGVsCgkJY2FzZSBGSUNfUkdCQUxQSEE6CQkvLyBSR0IgY29sb3IgbW9kZWwgd2l0aCBhbHBoYSBjaGFubmVsCgkJCXJldHVybiBQSE9UT01FVFJJQ19SR0I7CgkJY2FzZSBGSUNfQ01ZSzoJCQkvLyBDTVlLIGNvbG9yIG1vZGVsCgkJCXJldHVybiBQSE9UT01FVFJJQ19SR0I7CS8vIGRlZmF1bHQgdG8gUkdCIHVubGVzcyB0aGUgc2F2ZSBmbGFnIGlzIHNldCB0byBUSUZGX0NNWUsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gUEhPVE9NRVRSSUNfTUlOSVNCTEFDSzsKCX0KfQoKLyoqCkdldCB0aGUgcmVzb2x1dGlvbiBmcm9tIHRoZSBUSUZGIGFuZCBmaWxsIHRoZSBkaWIgd2l0aCB1bml2ZXJzYWwgdW5pdHMKKi8Kc3RhdGljIHZvaWQgClJlYWRSZXNvbHV0aW9uKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpIHsKCWZsb2F0IGZSZXNYID0gMzAwLjA7CglmbG9hdCBmUmVzWSA9IDMwMC4wOwoJdWludDE2IHJlc1VuaXQgPSBSRVNVTklUX0lOQ0g7CgoJVElGRkdldEZpZWxkKHRpZmYsIFRJRkZUQUdfUkVTT0xVVElPTlVOSVQsICZyZXNVbml0KTsKCVRJRkZHZXRGaWVsZCh0aWZmLCBUSUZGVEFHX1hSRVNPTFVUSU9OLCAmZlJlc1gpOwoJVElGRkdldEZpZWxkKHRpZmYsIFRJRkZUQUdfWVJFU09MVVRJT04sICZmUmVzWSk7CgkKCS8vIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCByZXNvbHV0aW9uIHVuaXQgYW5kIHZhbGlkIHJlc29sdXRpb24gaXMgc3BlY2lmaWVkIHRoZW4gYXNzdW1lIGluY2gKCWlmIChyZXNVbml0ID09IFJFU1VOSVRfTk9ORSAmJiBmUmVzWCA+IDAuMCAmJiBmUmVzWSA+IDAuMCkgewoJCXJlc1VuaXQgPSBSRVNVTklUX0lOQ0g7Cgl9CglpZiAocmVzVW5pdCA9PSBSRVNVTklUX0lOQ0gpIHsKCQlGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWChkaWIsICh1bnNpZ25lZCkgKGZSZXNYLzAuMDI1NDAwMCArIDAuNSkpOwoJCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJZKGRpYiwgKHVuc2lnbmVkKSAoZlJlc1kvMC4wMjU0MDAwICsgMC41KSk7Cgl9IGVsc2UgaWYocmVzVW5pdCA9PSBSRVNVTklUX0NFTlRJTUVURVIpIHsKCQlGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWChkaWIsICh1bnNpZ25lZCkgKGZSZXNYKjEwMC4wICsgMC41KSk7CgkJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclkoZGliLCAodW5zaWduZWQpIChmUmVzWSoxMDAuMCArIDAuNSkpOwoJfQp9CgovKioKU2V0IHRoZSByZXNvbHV0aW9uIHRvIHRoZSBUSUZGIHVzaW5nIGVuZ2xpc2ggdW5pdHMKKi8Kc3RhdGljIHZvaWQgCldyaXRlUmVzb2x1dGlvbihUSUZGICp0aWZmLCBGSUJJVE1BUCAqZGliKSB7Cglkb3VibGUgcmVzOwoKCVRJRkZTZXRGaWVsZCh0aWZmLCBUSUZGVEFHX1JFU09MVVRJT05VTklULCBSRVNVTklUX0lOQ0gpOwoKCXJlcyA9ICh1bnNpZ25lZCBsb25nKSAoMC41ICsgMC4wMjU0ICogRnJlZUltYWdlX0dldERvdHNQZXJNZXRlclgoZGliKSk7CglUSUZGU2V0RmllbGQodGlmZiwgVElGRlRBR19YUkVTT0xVVElPTiwgcmVzKTsKCglyZXMgPSAodW5zaWduZWQgbG9uZykgKDAuNSArIDAuMDI1NCAqIEZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJZKGRpYikpOwoJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfWVJFU09MVVRJT04sIHJlcyk7Cn0KCi8qKgpGaWxsIHRoZSBkaWIgcGFsZXR0ZSBhY2NvcmRpbmcgdG8gdGhlIFRJRkYgcGhvdG9tZXRyaWMKKi8Kc3RhdGljIHZvaWQgClJlYWRQYWxldHRlKFRJRkYgKnRpZmYsIHVpbnQxNiBwaG90b21ldHJpYywgdWludDE2IGJpdHNwZXJzYW1wbGUsIEZJQklUTUFQICpkaWIpIHsKCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgoJc3dpdGNoKHBob3RvbWV0cmljKSB7CgkJY2FzZSBQSE9UT01FVFJJQ19NSU5JU0JMQUNLOgkvLyBiaXRtYXAgYW5kIGdyZXlzY2FsZSBpbWFnZSB0eXBlcwoJCWNhc2UgUEhPVE9NRVRSSUNfTUlOSVNXSElURToKCQkJLy8gTW9ub2Nocm9tZSBpbWFnZQoKCQkJaWYgKGJpdHNwZXJzYW1wbGUgPT0gMSkgewoJCQkJaWYgKHBob3RvbWV0cmljID09IFBIT1RPTUVUUklDX01JTklTV0hJVEUpIHsKCQkJCQlwYWxbMF0ucmdiUmVkID0gcGFsWzBdLnJnYkdyZWVuID0gcGFsWzBdLnJnYkJsdWUgPSAyNTU7CgkJCQkJcGFsWzFdLnJnYlJlZCA9IHBhbFsxXS5yZ2JHcmVlbiA9IHBhbFsxXS5yZ2JCbHVlID0gMDsKCQkJCX0gZWxzZSB7CgkJCQkJcGFsWzBdLnJnYlJlZCA9IHBhbFswXS5yZ2JHcmVlbiA9IHBhbFswXS5yZ2JCbHVlID0gMDsKCQkJCQlwYWxbMV0ucmdiUmVkID0gcGFsWzFdLnJnYkdyZWVuID0gcGFsWzFdLnJnYkJsdWUgPSAyNTU7CgkJCQl9CgoJCQl9IGVsc2UgaWYgKChiaXRzcGVyc2FtcGxlID09IDQpIHx8KGJpdHNwZXJzYW1wbGUgPT0gOCkpIHsKCQkJCS8vIG5lZWQgdG8gYnVpbGQgdGhlIHNjYWxlIGZvciBncmV5c2NhbGUgaW1hZ2VzCgkJCQlpbnQgbmNvbG9ycyA9IEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKGRpYik7CgoJCQkJaWYgKHBob3RvbWV0cmljID09IFBIT1RPTUVUUklDX01JTklTQkxBQ0spIHsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IG5jb2xvcnM7IGkrKykgewoJCQkJCQlwYWxbaV0ucmdiUmVkCT0KCQkJCQkJcGFsW2ldLnJnYkdyZWVuID0KCQkJCQkJcGFsW2ldLnJnYkJsdWUJPSAoQllURSkoaSooMjU1LyhuY29sb3JzLTEpKSk7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IG5jb2xvcnM7IGkrKykgewoJCQkJCQlwYWxbaV0ucmdiUmVkCT0KCQkJCQkJcGFsW2ldLnJnYkdyZWVuID0KCQkJCQkJcGFsW2ldLnJnYkJsdWUJPSAoQllURSkoMjU1LWkqKDI1NS8obmNvbG9ycy0xKSkpOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJYnJlYWs7CgoJCWNhc2UgUEhPVE9NRVRSSUNfUEFMRVRURToJLy8gY29sb3IgbWFwIGluZGV4ZWQKCQkJdWludDE2ICpyZWQ7CgkJCXVpbnQxNiAqZ3JlZW47CgkJCXVpbnQxNiAqYmx1ZTsKCQkJCgkJCVRJRkZHZXRGaWVsZCh0aWZmLCBUSUZGVEFHX0NPTE9STUFQLCAmcmVkLCAmZ3JlZW4sICZibHVlKTsgCgoJCQkvLyBsb2FkIHRoZSBwYWxldHRlIGluIHRoZSBESUIKCgkJCWlmIChDaGVja0NvbG9ybWFwKDE8PGJpdHNwZXJzYW1wbGUsIHJlZCwgZ3JlZW4sIGJsdWUpID09IDE2KSB7CgkJCQlmb3IgKGludCBpID0gKDEgPDwgYml0c3BlcnNhbXBsZSkgLSAxOyBpID49IDA7IGktLSkgewoJCQkJCXBhbFtpXS5yZ2JSZWQgPShCWVRFKSBDVlQocmVkW2ldKTsKCQkJCQlwYWxbaV0ucmdiR3JlZW4gPSAoQllURSkgQ1ZUKGdyZWVuW2ldKTsKCQkJCQlwYWxbaV0ucmdiQmx1ZSA9IChCWVRFKSBDVlQoYmx1ZVtpXSk7ICAgICAgICAgICAKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZvciAoaW50IGkgPSAoMSA8PCBiaXRzcGVyc2FtcGxlKSAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJCQkJcGFsW2ldLnJnYlJlZCA9IChCWVRFKSByZWRbaV07CgkJCQkJcGFsW2ldLnJnYkdyZWVuID0gKEJZVEUpIGdyZWVuW2ldOwoJCQkJCXBhbFtpXS5yZ2JCbHVlID0gKEJZVEUpIGJsdWVbaV07ICAgICAgICAKCQkJCX0KCQkJfQoKCQkJYnJlYWs7CQkJCQkJCgl9Cn0KCi8qKiAKQWxsb2NhdGUgYSBGSUJJVE1BUApAcGFyYW0gZml0IEltYWdlIHR5cGUKQHBhcmFtIHdpZHRoIEltYWdlIHdpZHRoIGluIHBpeGVscwpAcGFyYW0gaGVpZ2h0IEltYWdlIGhlaWdodCBpbiBwaXhlbHMKQHBhcmFtIGJpdHNwZXJzYW1wbGUgIyBiaXRzIHBlciBzYW1wbGUKQHBhcmFtIHNhbXBsZXNwZXJwaXhlbCAjIHNhbXBsZXMgcGVyIHBpeGVsCkByZXR1cm4gUmV0dXJucyB0aGUgYWxsb2NhdGVkIGltYWdlIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKKi8Kc3RhdGljIEZJQklUTUFQKiAKQ3JlYXRlSW1hZ2VUeXBlKEZSRUVfSU1BR0VfVFlQRSBmaXQsIGludCB3aWR0aCwgaW50IGhlaWdodCwgdWludDE2IGJpdHNwZXJzYW1wbGUsIHVpbnQxNiBzYW1wbGVzcGVycGl4ZWwpIHsKCUZJQklUTUFQICpkaWIgPSBOVUxMOwoKCXVpbnQxNiBicHAgPSBiaXRzcGVyc2FtcGxlICogc2FtcGxlc3BlcnBpeGVsOwoKCWlmKGZpdCA9PSBGSVRfQklUTUFQKSB7CgkJLy8gc3RhbmRhcmQgYml0bWFwIHR5cGUgCgoJCWlmKGJpdHNwZXJzYW1wbGUgPT0gMTYpIHsKCQkJaWYoc2FtcGxlc3BlcnBpeGVsID09IDEpIHsKCQkJCS8vIDE2LWJpdCBncmV5c2NhbGUgLT4gY29udmVydCB0byA4LWJpdAoJCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlKHdpZHRoLCBoZWlnaHQsIDgpOwoJCQl9CgkJCWVsc2UgaWYoc2FtcGxlc3BlcnBpeGVsID09IDMpIHsKCQkJCS8vIDQ4LWJpdCBSR0IgLT4gY29udmVydCB0byAyNC1iaXQgUkdCCgkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMjQsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCQl9CgkJfQoJCWVsc2UgaWYoYnBwID09IDE2KSB7CgkJCWlmKChzYW1wbGVzcGVycGl4ZWwgPT0gMikgJiYgKGJpdHNwZXJzYW1wbGUgPT0gOCkpIHsKCQkJCS8vIDgtYml0IGluZGV4ZWQgKyA4LWJpdCBhbHBoYSBjaGFubmVsIC0+IGNvbnZlcnQgdG8gOC1iaXQgdHJhbnNwYXJlbnQKCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3aWR0aCwgaGVpZ2h0LCA4KTsKCQkJfSBlbHNlIHsKCQkJCS8vIDE2LWJpdCBSR0IgLT4gZXhwZWN0IGl0IHRvIGJlIDU2NQoJCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlKHdpZHRoLCBoZWlnaHQsIGJwcCwgRkkxNl81NjVfUkVEX01BU0ssIEZJMTZfNTY1X0dSRUVOX01BU0ssIEZJMTZfNTY1X0JMVUVfTUFTSyk7CgkJCX0KCQl9CgkJZWxzZSBpZihicHAgPT0gMjQpIHsKCQkJLy8gQkdSCgkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3aWR0aCwgaGVpZ2h0LCBicHAsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCX0KCQllbHNlIGlmKGJwcCA9PSAzMikgewoJCQkvLyBCR1JBCgkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3aWR0aCwgaGVpZ2h0LCBicHAsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCX0KCQllbHNlIHsKCQkJLy8gYW55dGhpbmcgZWxzZSA8PSA4LWJpdAoJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgYnBwKTsKCQl9Cgl9IGVsc2UgewoJCS8vIG90aGVyIGJpdG1hcCB0eXBlcwoJCQoJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoZml0LCB3aWR0aCwgaGVpZ2h0LCBicHApOwoJfQoKCXJldHVybiBkaWI7Cn0KCi8qKiAKUmVhZCB0aGUgVElGRlRBR19TQU1QTEVGT1JNQVQgdGFnIGFuZCBjb252ZXJ0IHRvIEZSRUVfSU1BR0VfVFlQRQpAcGFyYW0gdGlmZiBMaWJUSUZGIFRJRkYgSGFuZGxlCkBwYXJhbSBiaXRzcGVyc2FtcGxlICMgYml0IHBlciBzYW1wbGUKQHBhcmFtIHNhbXBsZXNwZXJwaXhlbCAjIHNhbXBsZXMgcGVyIHBpeGVsCkByZXR1cm4gUmV0dXJucyB0aGUgaW1hZ2UgdHlwZSBhcyBhIEZSRUVfSU1BR0VfVFlQRSB2YWx1ZQoqLwpzdGF0aWMgRlJFRV9JTUFHRV9UWVBFIApSZWFkSW1hZ2VUeXBlKFRJRkYgKnRpZmYsIHVpbnQxNiBiaXRzcGVyc2FtcGxlLCB1aW50MTYgc2FtcGxlc3BlcnBpeGVsKSB7Cgl1aW50MTYgc2FtcGxlZm9ybWF0ID0gMDsKCUZSRUVfSU1BR0VfVFlQRSBmaXQgPSBGSVRfQklUTUFQOwoKCXVpbnQxNiBicHAgPSBiaXRzcGVyc2FtcGxlICogc2FtcGxlc3BlcnBpeGVsOwoKCS8vIHRyeSB0aGUgc2FtcGxlZm9ybWF0IHRhZwogICAgaWYoVElGRkdldEZpZWxkKHRpZmYsIFRJRkZUQUdfU0FNUExFRk9STUFULCAmc2FtcGxlZm9ybWF0KSkgewoKICAgICAgICBzd2l0Y2ggKHNhbXBsZWZvcm1hdCkgewoJCQljYXNlIFNBTVBMRUZPUk1BVF9VSU5UOgoJCQkJc3dpdGNoIChicHApIHsKCQkJCQljYXNlIDE6CgkJCQkJY2FzZSA0OgoJCQkJCWNhc2UgODoKCQkJCQljYXNlIDI0OgoJCQkJCQlmaXQgPSBGSVRfQklUTUFQOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDE2OgoJCQkJCQkvLyA4LWJpdCArIGFscGhhIG9yIDE2LWJpdCBncmV5c2NhbGUKCQkJCQkJaWYoc2FtcGxlc3BlcnBpeGVsID09IDIpIHsKCQkJCQkJCWZpdCA9IEZJVF9CSVRNQVA7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlmaXQgPSBGSVRfVUlOVDE2OwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgMzI6CgkJCQkJCWlmKHNhbXBsZXNwZXJwaXhlbCA9PSA0KSB7CgkJCQkJCQlmaXQgPSBGSVRfQklUTUFQOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJZml0ID0gRklUX1VJTlQzMjsKCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQljYXNlIDQ4OgoJCQkJCQlpZihzYW1wbGVzcGVycGl4ZWwgPT0gMykgewoJCQkJCQkJZml0ID0gRklUX1JHQjE2OwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgNjQ6CgkJCQkJCWlmKHNhbXBsZXNwZXJwaXhlbCA9PSA0KSB7CgkJCQkJCQlmaXQgPSBGSVRfUkdCQTE2OwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQkJYnJlYWs7CgoJCQljYXNlIFNBTVBMRUZPUk1BVF9JTlQ6CgkJCQlzd2l0Y2ggKGJwcCkgewoJCQkJCWNhc2UgMTY6CgkJCQkJCWlmKHNhbXBsZXNwZXJwaXhlbCA9PSAzKSB7CgkJCQkJCQlmaXQgPSBGSVRfQklUTUFQOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJZml0ID0gRklUX0lOVDE2OwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgMzI6CgkJCQkJCWZpdCA9IEZJVF9JTlQzMjsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCQlicmVhazsKCgkJCWNhc2UgU0FNUExFRk9STUFUX0lFRUVGUDoKCQkJCXN3aXRjaCAoYnBwKSB7CgkJCQkJY2FzZSAzMjoKCQkJCQkJZml0ID0gRklUX0ZMT0FUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDY0OgoJCQkJCQlmaXQgPSBGSVRfRE9VQkxFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDk2OgoJCQkJCQlmaXQgPSBGSVRfUkdCRjsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCQlicmVhazsKCQkJY2FzZSBTQU1QTEVGT1JNQVRfQ09NUExFWElFRUVGUDoKCQkJCXN3aXRjaCAoYnBwKSB7CgkJCQkJY2FzZSA2NDoKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAxMjg6CgkJCQkJCWZpdCA9IEZJVF9DT01QTEVYOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJCWJyZWFrOwoKCQkJfQogICAgfQoJLy8gbm8gc2FtcGxlZm9ybWF0IHRhZyA6IGFzc3VtZSBTQU1QTEVGT1JNQVRfVUlOVAoJZWxzZSB7CgkJaWYoc2FtcGxlc3BlcnBpeGVsID09IDEpIHsKCQkJc3dpdGNoIChicHApIHsKCQkJCWNhc2UgMTY6CgkJCQkJZml0ID0gRklUX1VJTlQxNjsKCQkJCQlicmVhazsKCQkJCQkKCQkJCWNhc2UgMzI6CgkJCQkJZml0ID0gRklUX1VJTlQzMjsKCQkJCQlicmVhazsKCQkJfQoJCX0KCQllbHNlIGlmKHNhbXBsZXNwZXJwaXhlbCA9PSAzKSB7CgkJCWlmKGJwcCA9PSA0OCkgZml0ID0gRklUX1JHQjE2OwoJCX0KCQllbHNlIGlmKHNhbXBsZXNwZXJwaXhlbCA9PSA0KSB7CgkJCWlmKGJwcCA9PSA2NCkgZml0ID0gRklUX1JHQkExNjsKCQl9CgoJfQoKICAgIHJldHVybiBmaXQ7Cn0KCi8qKiAKQ29udmVydCBGUkVFX0lNQUdFX1RZUEUgYW5kIHdyaXRlIFRJRkZUQUdfU0FNUExFRk9STUFUCkBwYXJhbSB0aWZmIExpYlRJRkYgVElGRiBIYW5kbGUKQHBhcmFtIGZpdCBJbWFnZSB0eXBlIGFzIGEgRlJFRV9JTUFHRV9UWVBFIHZhbHVlCiovCnN0YXRpYyB2b2lkIApXcml0ZUltYWdlVHlwZShUSUZGICp0aWZmLCBGUkVFX0lNQUdFX1RZUEUgZml0KSB7Cglzd2l0Y2goZml0KSB7CgkJY2FzZSBGSVRfQklUTUFQOgkvLyBzdGFuZGFyZCBpbWFnZTogMS0sIDQtLCA4LSwgMTYtLCAyNC0sIDMyLWJpdAoJCWNhc2UgRklUX1VJTlQxNjoJLy8gYXJyYXkgb2YgdW5zaWduZWQgc2hvcnQJOiB1bnNpZ25lZCAxNi1iaXQKCQljYXNlIEZJVF9VSU5UMzI6CS8vIGFycmF5IG9mIHVuc2lnbmVkIGxvbmcJOiB1bnNpZ25lZCAzMi1iaXQKCQljYXNlIEZJVF9SR0IxNjoJCS8vIDQ4LWJpdCBSR0IgaW1hZ2UJCQk6IDMgeCAxNi1iaXQKCQljYXNlIEZJVF9SR0JBMTY6CS8vIDY0LWJpdCBSR0JBIGltYWdlCQk6IDQgeCAxNi1iaXQKCQkJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfU0FNUExFRk9STUFULCBTQU1QTEVGT1JNQVRfVUlOVCk7CgkJCWJyZWFrOwoKCQljYXNlIEZJVF9JTlQxNjoJCS8vIGFycmF5IG9mIHNob3J0CTogc2lnbmVkIDE2LWJpdAoJCWNhc2UgRklUX0lOVDMyOgkJLy8gYXJyYXkgb2YgbG9uZwk6IHNpZ25lZCAzMi1iaXQKCQkJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfU0FNUExFRk9STUFULCBTQU1QTEVGT1JNQVRfSU5UKTsKCQkJYnJlYWs7CgoJCWNhc2UgRklUX0ZMT0FUOgkJLy8gYXJyYXkgb2YgZmxvYXQJOiAzMi1iaXQKCQljYXNlIEZJVF9ET1VCTEU6CS8vIGFycmF5IG9mIGRvdWJsZQk6IDY0LWJpdAoJCWNhc2UgRklUX1JHQkY6CQkvLyA5Ni1iaXQgUkdCIGZsb2F0IGltYWdlCTogMyB4IDMyLWJpdCBJRUVFIGZsb2F0aW5nIHBvaW50CgkJY2FzZSBGSVRfUkdCQUY6CQkvLyAxMjgtYml0IFJHQkEgZmxvYXQgaW1hZ2UJOiA0IHggMzItYml0IElFRUUgZmxvYXRpbmcgcG9pbnQKCQkJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfU0FNUExFRk9STUFULCBTQU1QTEVGT1JNQVRfSUVFRUZQKTsKCQkJYnJlYWs7CgoJCWNhc2UgRklUX0NPTVBMRVg6CS8vIGFycmF5IG9mIENPTVBMRVggOiAyIHggNjQtYml0CgkJCVRJRkZTZXRGaWVsZCh0aWZmLCBUSUZGVEFHX1NBTVBMRUZPUk1BVCwgU0FNUExFRk9STUFUX0NPTVBMRVhJRUVFRlApOwoJCQlicmVhazsKCX0KfQoKLyoqClNlbGVjdCB0aGUgY29tcHJlc3Npb24gYWxnb3JpdGhtCkBwYXJhbSB0aWZmIExpYlRJRkYgVElGRiBIYW5kbGUKQHBhcmFtIAoqLwpzdGF0aWMgdm9pZCAKV3JpdGVDb21wcmVzc2lvbihUSUZGICp0aWZmLCB1aW50MTYgYml0c3BlcnNhbXBsZSwgdWludDE2IHNhbXBsZXNwZXJwaXhlbCwgdWludDE2IHBob3RvbWV0cmljLCBpbnQgZmxhZ3MpIHsKCXVpbnQxNiBjb21wcmVzc2lvbjsKCXVpbnQxNiBiaXRzcGVycGl4ZWwgPSBiaXRzcGVyc2FtcGxlICogc2FtcGxlc3BlcnBpeGVsOwoKCWlmKHBob3RvbWV0cmljID09IFBIT1RPTUVUUklDX0xPR0xVVikgewoJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fU0dJTE9HOwoJfSBlbHNlIGlmICgoZmxhZ3MgJiBUSUZGX1BBQ0tCSVRTKSA9PSBUSUZGX1BBQ0tCSVRTKSB7CgkJY29tcHJlc3Npb24gPSBDT01QUkVTU0lPTl9QQUNLQklUUzsKCX0gZWxzZSBpZiAoKGZsYWdzICYgVElGRl9ERUZMQVRFKSA9PSBUSUZGX0RFRkxBVEUpIHsKCQljb21wcmVzc2lvbiA9IENPTVBSRVNTSU9OX0RFRkxBVEU7Cgl9IGVsc2UgaWYgKChmbGFncyAmIFRJRkZfQURPQkVfREVGTEFURSkgPT0gVElGRl9BRE9CRV9ERUZMQVRFKSB7CgkJY29tcHJlc3Npb24gPSBDT01QUkVTU0lPTl9BRE9CRV9ERUZMQVRFOwoJfSBlbHNlIGlmICgoZmxhZ3MgJiBUSUZGX05PTkUpID09IFRJRkZfTk9ORSkgewoJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fTk9ORTsKCX0gZWxzZSBpZiAoKGJpdHNwZXJwaXhlbCA9PSAxKSAmJiAoKGZsYWdzICYgVElGRl9DQ0lUVEZBWDMpID09IFRJRkZfQ0NJVFRGQVgzKSkgewoJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fQ0NJVFRGQVgzOwoJfSBlbHNlIGlmICgoYml0c3BlcnBpeGVsID09IDEpICYmICgoZmxhZ3MgJiBUSUZGX0NDSVRURkFYNCkgPT0gVElGRl9DQ0lUVEZBWDQpKSB7CgkJY29tcHJlc3Npb24gPSBDT01QUkVTU0lPTl9DQ0lUVEZBWDQ7Cgl9IGVsc2UgaWYgKChmbGFncyAmIFRJRkZfTFpXKSA9PSBUSUZGX0xaVykgewoJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fTFpXOwoJfSBlbHNlIGlmICgoZmxhZ3MgJiBUSUZGX0pQRUcpID09IFRJRkZfSlBFRykgewoJCWlmKCgoYml0c3BlcnBpeGVsID09IDgpICYmIChwaG90b21ldHJpYyAhPSBQSE9UT01FVFJJQ19QQUxFVFRFKSkgfHwgKGJpdHNwZXJwaXhlbCA9PSAyNCkpIHsKCQkJY29tcHJlc3Npb24gPSBDT01QUkVTU0lPTl9KUEVHOwoJCQkvLyBSb3dzUGVyU3RyaXAgbXVzdCBiZSBtdWx0aXBsZSBvZiA4IGZvciBKUEVHCgkJCXVpbnQzMiByb3dzcGVyc3RyaXAgPSAodWludDMyKSAtMTsKCQkJcm93c3BlcnN0cmlwID0gVElGRkRlZmF1bHRTdHJpcFNpemUodGlmZiwgcm93c3BlcnN0cmlwKTsKICAgICAgICAgICAgcm93c3BlcnN0cmlwID0gcm93c3BlcnN0cmlwICsgKDggLSAocm93c3BlcnN0cmlwICUgOCkpOwoJCQkvLyBvdmVyd3JpdGUgcHJldmlvdXMgUm93c1BlclN0cmlwCgkJCVRJRkZTZXRGaWVsZCh0aWZmLCBUSUZGVEFHX1JPV1NQRVJTVFJJUCwgcm93c3BlcnN0cmlwKTsKCQl9IGVsc2UgewoJCQkvLyBkZWZhdWx0IHRvIExaVwoJCQljb21wcmVzc2lvbiA9IENPTVBSRVNTSU9OX0xaVzsKCQl9Cgl9CgllbHNlIHsKCQkvLyBkZWZhdWx0IGNvbXByZXNzaW9uIHNjaGVtZQoKCQlzd2l0Y2goYml0c3BlcnBpeGVsKSB7CgkJCWNhc2UgMSA6CgkJCQljb21wcmVzc2lvbiA9IENPTVBSRVNTSU9OX0NDSVRURkFYNDsKCQkJCWJyZWFrOwoKCQkJY2FzZSA0IDoKCQkJY2FzZSA4IDoKCQkJY2FzZSAxNiA6CgkJCWNhc2UgMjQgOgoJCQljYXNlIDMyIDoKCQkJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fTFpXOwoJCQkJYnJlYWs7CgkJCWNhc2UgNDg6CgkJCWNhc2UgNjQgOgoJCQljYXNlIDEyODoKCQkJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fTFpXOwoJCQkJYnJlYWs7CgoJCQlkZWZhdWx0IDoKCQkJCWNvbXByZXNzaW9uID0gQ09NUFJFU1NJT05fTk9ORTsKCQkJCWJyZWFrOwoJCX0KCX0KCglUSUZGU2V0RmllbGQodGlmZiwgVElGRlRBR19DT01QUkVTU0lPTiwgY29tcHJlc3Npb24pOwoKCWlmKGNvbXByZXNzaW9uID09IENPTVBSRVNTSU9OX0xaVykgewoJCS8vIFRoaXMgb3B0aW9uIGlzIG9ubHkgbWVhbmluZ2Z1bCB3aXRoIExaVyBjb21wcmVzc2lvbjogYSBwcmVkaWN0b3IgdmFsdWUgb2YgMiAKCQkvLyBjYXVzZXMgZWFjaCBzY2FubGluZSBvZiB0aGUgb3V0cHV0IGltYWdlIHRvIHVuZGVyZ28gaG9yaXpvbnRhbCBkaWZmZXJlbmNpbmcgCgkJLy8gYmVmb3JlIGl0IGlzIGVuY29kZWQ7IGEgdmFsdWUgb2YgMSBmb3JjZXMgZWFjaCBzY2FubGluZSB0byBiZSBlbmNvZGVkIHdpdGhvdXQgZGlmZmVyZW5jaW5nLgoKCQkvLyBGb3VuZCBvbiBMaWJUSUZGIG1haWxpbmcgbGlzdCA6IAoJCS8vIExaVyB3aXRob3V0IGRpZmZlcmVuY2luZyB3b3JrcyB3ZWxsIGZvciAxLWJpdCBpbWFnZXMsIDQtYml0IGdyYXlzY2FsZSBpbWFnZXMsIAoJCS8vIGFuZCBtYW55IHBhbGV0dGUtY29sb3IgaW1hZ2VzLiBCdXQgbmF0dXJhbCAyNC1iaXQgY29sb3IgaW1hZ2VzIGFuZCBzb21lIDgtYml0IAoJCS8vIGdyYXlzY2FsZSBpbWFnZXMgZG8gbXVjaCBiZXR0ZXIgd2l0aCBkaWZmZXJlbmNpbmcuCgoJCWlmKChiaXRzcGVyc2FtcGxlID09IDgpIHx8IChiaXRzcGVyc2FtcGxlID09IDE2KSkgewoJCQlpZiAoKGJpdHNwZXJwaXhlbCA+PSA4KSAmJiAocGhvdG9tZXRyaWMgIT0gUEhPVE9NRVRSSUNfUEFMRVRURSkpCgkJCQlUSUZGU2V0RmllbGQodGlmZiwgVElGRlRBR19QUkVESUNUT1IsIDIpOwoJCQllbHNlCgkJCQlUSUZGU2V0RmllbGQodGlmZiwgVElGRlRBR19QUkVESUNUT1IsIDEpOwoJCX0gZWxzZSB7CgkJCVRJRkZTZXRGaWVsZCh0aWZmLCBUSUZGVEFHX1BSRURJQ1RPUiwgMSk7CgkJfQoJfQoJZWxzZSBpZihjb21wcmVzc2lvbiA9PSBDT01QUkVTU0lPTl9DQ0lUVEZBWDMpIHsKCQkvLyB0cnkgdG8gYmUgY29tcGxpYW50IHdpdGggdGhlIFRJRkYgQ2xhc3MgRiBzcGVjaWZpY2F0aW9uCgkJLy8gdGhhdCBkb2N1bWVudHMgdGhlIFRJRkYgdGFncyBzcGVjaWZpYyB0byBGQVggYXBwbGljYXRpb25zCgkJLy8gc2VlIGh0dHA6Ly9wYWxpbXBzZXN0LnN0YW5mb3JkLmVkdS9ieXRvcGljL2ltYWdpbmcvc3RkL3RpZmYtZi5odG1sCgkJdWludDMyIGdyb3VwM29wdGlvbnMgPSBHUk9VUDNPUFRfMkRFTkNPRElORyB8IEdST1VQM09QVF9GSUxMQklUUzsJCgkJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfR1JPVVAzT1BUSU9OUywgZ3JvdXAzb3B0aW9ucyk7CS8vIDJkLWVuY29kZWQsIGhhcyBhbGlnbmVkIEVPTAoJCVRJRkZTZXRGaWVsZCh0aWZmLCBUSUZGVEFHX0ZJTExPUkRFUiwgRklMTE9SREVSX0xTQjJNU0IpOwkvLyBsc2ItdG8tbXNiIGZpbGxvcmRlcgoJfQp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFRJRkYgbWV0YWRhdGEgcm91dGluZXMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCglSZWFkIHRoZSBUSUZGVEFHX1JJQ0hUSUZGSVBUQyB0YWcgKElQVEMvTkFBIG9yIEFkb2JlIFBob3Rvc2hvcCBwcm9maWxlKQoqLwpzdGF0aWMgQk9PTCAKdGlmZl9yZWFkX2lwdGNfcHJvZmlsZShUSUZGICp0aWZmLCBGSUJJVE1BUCAqZGliKSB7CglCWVRFICpwcm9maWxlID0gTlVMTDsKCXVpbnQzMiBwcm9maWxlX3NpemUgPSAwOwoKICAgIGlmKFRJRkZHZXRGaWVsZCh0aWZmLFRJRkZUQUdfUklDSFRJRkZJUFRDLCAmcHJvZmlsZV9zaXplLCAmcHJvZmlsZSkgPT0gMSkgewogICAgICAgIGlmIChUSUZGSXNCeXRlU3dhcHBlZCh0aWZmKSAhPSAwKQoJCQlUSUZGU3dhYkFycmF5T2ZMb25nKCh1aW50MzIgKikgcHJvZmlsZSwgKHVuc2lnbmVkIGxvbmcpcHJvZmlsZV9zaXplKTsKCgkJcmV0dXJuIHJlYWRfaXB0Y19wcm9maWxlKGRpYiwgcHJvZmlsZSwgNCAqIHByb2ZpbGVfc2l6ZSk7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKioKCVJlYWQgdGhlIFRJRkZUQUdfWE1MUEFDS0VUIHRhZyAoWE1QIHByb2ZpbGUpCglAcGFyYW0gZGliIElucHV0IEZJQklUTUFQCglAcGFyYW0gdGlmZiBMaWJUSUZGIFRJRkYgaGFuZGxlCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgIAp0aWZmX3JlYWRfeG1wX3Byb2ZpbGUoVElGRiAqdGlmZiwgRklCSVRNQVAgKmRpYikgewoJQllURSAqcHJvZmlsZSA9IE5VTEw7Cgl1aW50MzIgcHJvZmlsZV9zaXplID0gMDsKCglpZiAoVElGRkdldEZpZWxkKHRpZmYsIFRJRkZUQUdfWE1MUEFDS0VULCAmcHJvZmlsZV9zaXplLCAmcHJvZmlsZSkgPT0gMSkgewoJCS8vIGNyZWF0ZSBhIHRhZwoJCUZJVEFHICp0YWcgPSBGcmVlSW1hZ2VfQ3JlYXRlVGFnKCk7CgkJaWYoIXRhZykgcmV0dXJuIEZBTFNFOwoKCQlGcmVlSW1hZ2VfU2V0VGFnSUQodGFnLCBUSUZGVEFHX1hNTFBBQ0tFVCk7CS8vIDcwMAoJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBnX1RhZ0xpYl9YTVBGaWVsZE5hbWUpOwoJCUZyZWVJbWFnZV9TZXRUYWdMZW5ndGgodGFnLCBwcm9maWxlX3NpemUpOwoJCUZyZWVJbWFnZV9TZXRUYWdDb3VudCh0YWcsIHByb2ZpbGVfc2l6ZSk7CgkJRnJlZUltYWdlX1NldFRhZ1R5cGUodGFnLCBGSURUX0FTQ0lJKTsKCQlGcmVlSW1hZ2VfU2V0VGFnVmFsdWUodGFnLCBwcm9maWxlKTsKCgkJLy8gc3RvcmUgdGhlIHRhZwoJCUZyZWVJbWFnZV9TZXRNZXRhZGF0YShGSU1EX1hNUCwgZGliLCBGcmVlSW1hZ2VfR2V0VGFnS2V5KHRhZyksIHRhZyk7CgoJCS8vIGRlc3Ryb3kgdGhlIHRhZwoJCUZyZWVJbWFnZV9EZWxldGVUYWcodGFnKTsKCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKioKCVJlYWQgdGhlIEV4aWYgcHJvZmlsZSBlbWJlZGRlZCBpbiBhIFRJRkYKCUBwYXJhbSBkaWIgSW5wdXQgRklCSVRNQVAKCUBwYXJhbSB0aWZmIExpYlRJRkYgVElGRiBoYW5kbGUKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZQoqLwpzdGF0aWMgQk9PTCAKdGlmZl9yZWFkX2V4aWZfcHJvZmlsZShUSUZGICp0aWZmLCBGSUJJVE1BUCAqZGliKSB7CiAgICB1aW50MzIgZXhpZl9vZmZzZXQgPSAwOwoKCS8vIHJlYWQgRVhJRi1USUZGIHRhZ3MKCXRpZmZfcmVhZF9leGlmX3RhZ3ModGlmZiwgVGFnTGliOjpFWElGX01BSU4sIGRpYik7CgoJLy8gZ2V0IHRoZSBJRkQgb2Zmc2V0CglpZihUSUZGR2V0RmllbGQodGlmZiwgVElGRlRBR19FWElGSUZELCAmZXhpZl9vZmZzZXQpKSB7CgkJLy8gcmVhZCBFWElGIHRhZ3MKCQlpZighVElGRlJlYWRFWElGRGlyZWN0b3J5KHRpZmYsIGV4aWZfb2Zmc2V0KSkKCQkJcmV0dXJuIEZBTFNFOwoKCQlyZXR1cm4gdGlmZl9yZWFkX2V4aWZfdGFncyh0aWZmLCBUYWdMaWI6OkVYSUZfRVhJRiwgZGliKTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8qKgpSZWFkIFRJRkYgc3BlY2lhbCBwcm9maWxlcwoqLwpzdGF0aWMgdm9pZCAKUmVhZE1ldGFkYXRhKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpIHsKCgkvLyBJUFRDL05BQQoJdGlmZl9yZWFkX2lwdGNfcHJvZmlsZSh0aWZmLCBkaWIpOwoKCS8vIEFkb2JlIFhNUAoJdGlmZl9yZWFkX3htcF9wcm9maWxlKHRpZmYsIGRpYik7CgoJLy8gR2VvVElGRgoJdGlmZl9yZWFkX2dlb3RpZmZfcHJvZmlsZSh0aWZmLCBkaWIpOwoKCS8vIEV4aWYtVElGRgoJdGlmZl9yZWFkX2V4aWZfcHJvZmlsZSh0aWZmLCBkaWIpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKCVdyaXRlIHRoZSBUSUZGVEFHX1JJQ0hUSUZGSVBUQyB0YWcgKElQVEMvTkFBIG9yIEFkb2JlIFBob3Rvc2hvcCBwcm9maWxlKQoqLwpzdGF0aWMgQk9PTCAKdGlmZl93cml0ZV9pcHRjX3Byb2ZpbGUoVElGRiAqdGlmZiwgRklCSVRNQVAgKmRpYikgewoJaWYoRnJlZUltYWdlX0dldE1ldGFkYXRhQ291bnQoRklNRF9JUFRDLCBkaWIpKSB7CgkJQllURSAqcHJvZmlsZSA9IE5VTEw7CgkJdWludDMyIHByb2ZpbGVfc2l6ZSA9IDA7CgkJLy8gY3JlYXRlIGEgYmluYXJ5IHByb2ZpbGUKCQlpZih3cml0ZV9pcHRjX3Byb2ZpbGUoZGliLCAmcHJvZmlsZSwgJnByb2ZpbGVfc2l6ZSkpIHsKCQkJdWludDMyIGlwdGNfc2l6ZSA9IHByb2ZpbGVfc2l6ZTsKCQkJaXB0Y19zaXplICs9ICg0LShpcHRjX3NpemUgJiAweDAzKSk7IC8vIFJvdW5kIHVwIGZvciBsb25nIHdvcmQgYWxpZ25tZW50CgkJCUJZVEUgKmlwdGNfcHJvZmlsZSA9IChCWVRFKiltYWxsb2MoaXB0Y19zaXplKTsKCQkJaWYoIWlwdGNfcHJvZmlsZSkgewoJCQkJZnJlZShwcm9maWxlKTsKCQkJCXJldHVybiBGQUxTRTsKCQkJfQoJCQltZW1zZXQoaXB0Y19wcm9maWxlLCAwLCBpcHRjX3NpemUpOwoJCQltZW1jcHkoaXB0Y19wcm9maWxlLCBwcm9maWxlLCBwcm9maWxlX3NpemUpOwoJCQlpZiAoVElGRklzQnl0ZVN3YXBwZWQodGlmZikpCgkJCQlUSUZGU3dhYkFycmF5T2ZMb25nKCh1aW50MzIgKikgaXB0Y19wcm9maWxlLCAodW5zaWduZWQgbG9uZylpcHRjX3NpemUvNCk7CgkJCS8vIFRhZyBpcyB0eXBlIFRJRkZfTE9ORyBzbyBieXRlIGxlbmd0aCBpcyBkaXZpZGVkIGJ5IGZvdXIKCQkJVElGRlNldEZpZWxkKHRpZmYsIFRJRkZUQUdfUklDSFRJRkZJUFRDLCBpcHRjX3NpemUvNCwgaXB0Y19wcm9maWxlKTsKCQkJLy8gcmVsZWFzZSB0aGUgcHJvZmlsZSBkYXRhCgkJCWZyZWUoaXB0Y19wcm9maWxlKTsKCQkJZnJlZShwcm9maWxlKTsKCgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8qKgoJV3JpdGUgdGhlIFRJRkZUQUdfWE1MUEFDS0VUIHRhZyAoWE1QIHByb2ZpbGUpCglAcGFyYW0gZGliIElucHV0IEZJQklUTUFQCglAcGFyYW0gdGlmZiBMaWJUSUZGIFRJRkYgaGFuZGxlCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgIAp0aWZmX3dyaXRlX3htcF9wcm9maWxlKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpIHsKCUZJVEFHICp0YWdfeG1wID0gTlVMTDsKCUZyZWVJbWFnZV9HZXRNZXRhZGF0YShGSU1EX1hNUCwgZGliLCBnX1RhZ0xpYl9YTVBGaWVsZE5hbWUsICZ0YWdfeG1wKTsKCglpZih0YWdfeG1wICYmIChOVUxMICE9IEZyZWVJbWFnZV9HZXRUYWdWYWx1ZSh0YWdfeG1wKSkpIHsKCQkKCQlUSUZGU2V0RmllbGQodGlmZiwgVElGRlRBR19YTUxQQUNLRVQsICh1aW50MzIpRnJlZUltYWdlX0dldFRhZ0xlbmd0aCh0YWdfeG1wKSwgKEJZVEUqKUZyZWVJbWFnZV9HZXRUYWdWYWx1ZSh0YWdfeG1wKSk7CgoJCXJldHVybiBUUlVFOwkJCgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKioKV3JpdGUgVElGRiBzcGVjaWFsIHByb2ZpbGVzCiovCnN0YXRpYyB2b2lkIApXcml0ZU1ldGFkYXRhKFRJRkYgKnRpZmYsIEZJQklUTUFQICpkaWIpIHsKCS8vIElQVEMKCXRpZmZfd3JpdGVfaXB0Y19wcm9maWxlKHRpZmYsIGRpYik7CgoJLy8gQWRvYmUgWE1QCgl0aWZmX3dyaXRlX3htcF9wcm9maWxlKHRpZmYsIGRpYik7CgoJLy8gR2VvVElGRiB0YWdzCgl0aWZmX3dyaXRlX2dlb3RpZmZfcHJvZmlsZSh0aWZmLCBkaWIpOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbXBsZW1lbnRhdGlvbgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpGb3JtYXQoKSB7CglyZXR1cm4gIlRJRkYiOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpEZXNjcmlwdGlvbigpIHsKCXJldHVybiAiVGFnZ2VkIEltYWdlIEZpbGUgRm9ybWF0IjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRXh0ZW5zaW9uKCkgewoJcmV0dXJuICJ0aWYsdGlmZiI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WClJlZ0V4cHIoKSB7CglyZXR1cm4gIl5bTUldW01JXVtcXHgwMSpdW1xceDAxKl0iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2UvdGlmZiI7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpWYWxpZGF0ZShGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUpIHsJCglCWVRFIHRpZmZfaWQxW10gPSB7IDB4NDksIDB4NDksIDB4MkEsIDB4MDAgfTsKCUJZVEUgdGlmZl9pZDJbXSA9IHsgMHg0RCwgMHg0RCwgMHgwMCwgMHgyQSB9OwoJQllURSBzaWduYXR1cmVbNF0gPSB7IDAsIDAsIDAsIDAgfTsKCglpby0+cmVhZF9wcm9jKHNpZ25hdHVyZSwgMSwgNCwgaGFuZGxlKTsKCglpZihtZW1jbXAodGlmZl9pZDEsIHNpZ25hdHVyZSwgNCkgPT0gMCkKCQlyZXR1cm4gVFJVRTsKCglpZihtZW1jbXAodGlmZl9pZDIsIHNpZ25hdHVyZSwgNCkgPT0gMCkKCQlyZXR1cm4gVFJVRTsKCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTdXBwb3J0c0V4cG9ydERlcHRoKGludCBkZXB0aCkgewoJcmV0dXJuICgKCQkJKGRlcHRoID09IDEpICB8fAoJCQkoZGVwdGggPT0gNCkgIHx8CgkJCShkZXB0aCA9PSA4KSAgfHwKCQkJKGRlcHRoID09IDI0KSB8fAoJCQkoZGVwdGggPT0gMzIpCgkJKTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WIApTdXBwb3J0c0V4cG9ydFR5cGUoRlJFRV9JTUFHRV9UWVBFIHR5cGUpIHsKCXJldHVybiAoCgkJKHR5cGUgPT0gRklUX0JJVE1BUCkgIHx8CgkJKHR5cGUgPT0gRklUX1VJTlQxNikgIHx8CgkJKHR5cGUgPT0gRklUX0lOVDE2KSAgIHx8CgkJKHR5cGUgPT0gRklUX1VJTlQzMikgIHx8CgkJKHR5cGUgPT0gRklUX0lOVDMyKSAgIHx8CgkJKHR5cGUgPT0gRklUX0ZMT0FUKSAgIHx8CgkJKHR5cGUgPT0gRklUX0RPVUJMRSkgIHx8CgkJKHR5cGUgPT0gRklUX0NPTVBMRVgpIHx8IAoJCSh0eXBlID09IEZJVF9SR0IxNikgICB8fCAKCQkodHlwZSA9PSBGSVRfUkdCQTE2KSAgfHwgCgkJKHR5cGUgPT0gRklUX1JHQkYpCgkpOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU3VwcG9ydHNJQ0NQcm9maWxlcygpIHsKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgdm9pZCAqIERMTF9DQUxMQ09OVgpPcGVuKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgQk9PTCByZWFkKSB7CgkvLyB3cmFwcGVyIGZvciBUSUZGIEkvTwoJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKiltYWxsb2Moc2l6ZW9mKGZpX1RJRkZJTykpOwoJaWYoIWZpbykgcmV0dXJuIE5VTEw7CglmaW8tPmlvID0gaW87CglmaW8tPmhhbmRsZSA9IGhhbmRsZTsKCglpZiAocmVhZCkgewoJCWZpby0+dGlmID0gVElGRkZkT3BlbigodGhhbmRsZV90KWZpbywgIiIsICJyIik7Cgl9IGVsc2UgewoJCWZpby0+dGlmID0gVElGRkZkT3BlbigodGhhbmRsZV90KWZpbywgIiIsICJ3Iik7Cgl9CglpZihmaW8tPnRpZiA9PSBOVUxMKSB7CgkJZnJlZShmaW8pOwoJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgIkVycm9yIHdoaWxlIG9wZW5pbmcgVElGRjogZGF0YSBpcyBpbnZhbGlkIik7CgkJcmV0dXJuIE5VTEw7Cgl9CglyZXR1cm4gZmlvOwp9CgpzdGF0aWMgdm9pZCBETExfQ0FMTENPTlYKQ2xvc2UoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCB2b2lkICpkYXRhKSB7CglpZihkYXRhKSB7CgkJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKilkYXRhOwoJCVRJRkZDbG9zZShmaW8tPnRpZik7CgkJZnJlZShmaW8pOwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgaW50IERMTF9DQUxMQ09OVgpQYWdlQ291bnQoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCB2b2lkICpkYXRhKSB7CglpZihkYXRhKSB7CgkJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKilkYXRhOwoJCVRJRkYgKnRpZiA9IChUSUZGICopZmlvLT50aWY7CgkJaW50IG5yX2lmZCA9IDA7CgoJCWRvIHsKCQkJbnJfaWZkKys7CgkJfSB3aGlsZSAoVElGRlJlYWREaXJlY3RvcnkodGlmKSk7CgkJCQkKCQlyZXR1cm4gbnJfaWZkOwoJfQoKCXJldHVybiAwOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKY2hlY2sgZm9yIHVuY29tbW9uIGJpdHNwZXJzYW1wbGUgdmFsdWVzIChlLmcuIDEwLCAxMiwgLi4uKQpAcGFyYW0gcGhvdG9tZXRyaWMgVElGRlRBR19QSE9UT01FVFJJQyB0aWZmIHRhZwpAcGFyYW0gYml0c3BlcnNhbXBsZSBUSUZGVEFHX0JJVFNQRVJTQU1QTEUgdGlmZiB0YWcKQHJldHVybiBSZXR1cm5zIEZBTFNFIGlmIGEgdW5jb21tb24gYml0LWRlcHRoIGlzIGVuY291bnRlcmVkLCByZXR1cm5zIFRSVUUgb3RoZXJ3aXNlCiovCnN0YXRpYyBCT09MIElzVmFsaWRCaXRzUGVyU2FtcGxlKHVpbnQxNiBwaG90b21ldHJpYywgdWludDE2IGJpdHNwZXJzYW1wbGUpIHsKCXN3aXRjaChiaXRzcGVyc2FtcGxlKSB7CgkJY2FzZSAxOgoJCWNhc2UgNDoKCQkJaWYoKHBob3RvbWV0cmljID09IFBIT1RPTUVUUklDX01JTklTV0hJVEUpIHx8IChwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19NSU5JU0JMQUNLKSB8fCAocGhvdG9tZXRyaWMgPT0gUEhPVE9NRVRSSUNfUEFMRVRURSkpIHsgCgkJCQlyZXR1cm4gVFJVRTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBGQUxTRTsKCQkJfQoJCQlicmVhazsKCQljYXNlIDg6CgkJCXJldHVybiBUUlVFOwoJCWNhc2UgMTY6CgkJCWlmKHBob3RvbWV0cmljICE9IFBIT1RPTUVUUklDX1BBTEVUVEUpIHsgCgkJCQlyZXR1cm4gVFJVRTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBGQUxTRTsKCQkJfQoJCQlicmVhazsKCQljYXNlIDMyOgoJCQlyZXR1cm4gVFJVRTsKCQljYXNlIDY0OgoJCWNhc2UgMTI4OgoJCQlpZihwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19NSU5JU0JMQUNLKSB7IAoJCQkJcmV0dXJuIFRSVUU7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIEZBTFNFOwoJfQp9CgpzdGF0aWMgVElGRkxvYWRNZXRob2QgIApGaW5kTG9hZE1ldGhvZChUSUZGICp0aWYsIEZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlLCBpbnQgZmxhZ3MpIHsKCXVpbnQxNiBiaXRzcGVyc2FtcGxlOwoJdWludDE2IHNhbXBsZXNwZXJwaXhlbDsKCXVpbnQxNiBwaG90b21ldHJpYzsKCXVpbnQxNiBwbGFuYXJfY29uZmlnOwoKCVRJRkZMb2FkTWV0aG9kIGxvYWRNZXRob2QgPSBMb2FkQXNHZW5lcmljU3RyaXA7CgoJVElGRkdldEZpZWxkKHRpZiwgVElGRlRBR19QSE9UT01FVFJJQywgJnBob3RvbWV0cmljKTsKCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfU0FNUExFU1BFUlBJWEVMLCAmc2FtcGxlc3BlcnBpeGVsKTsKCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfQklUU1BFUlNBTVBMRSwgJmJpdHNwZXJzYW1wbGUpOwoJVElGRkdldEZpZWxkRGVmYXVsdGVkKHRpZiwgVElGRlRBR19QTEFOQVJDT05GSUcsICZwbGFuYXJfY29uZmlnKTsKCglCT09MIGJJc1RpbGVkID0gKFRJRkZJc1RpbGVkKHRpZikgPT0gMCkgPyBGQUxTRTpUUlVFOwoKCXN3aXRjaChwaG90b21ldHJpYykgewoJCS8vIGNvbnZlcnQgdG8gMjQgb3IgMzIgYml0cyBSR0IgaWYgdGhlIGltYWdlIGlzIGZ1bGwgY29sb3IKCQljYXNlIFBIT1RPTUVUUklDX1JHQjoKCQkJaWYoKGltYWdlX3R5cGUgPT0gRklUX1JHQjE2KSB8fCAoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSkgewoJCQkJLy8gbG9hZCA0OC1iaXQgUkdCIGFuZCA2NC1iaXQgUkdCQSB3aXRob3V0IGNvbnZlcnNpb24gCgkJCQlsb2FkTWV0aG9kID0gTG9hZEFzR2VuZXJpY1N0cmlwOwoJCQl9IGVsc2UgaWYoYml0c3BlcnNhbXBsZSA+PSA4KSB7CgkJCQlsb2FkTWV0aG9kID0gTG9hZEFzUkJHQTsKCQkJfSAKCQkJYnJlYWs7CgkJY2FzZSBQSE9UT01FVFJJQ19ZQ0JDUjoKCQljYXNlIFBIT1RPTUVUUklDX0NJRUxBQjoKCQljYXNlIFBIT1RPTUVUUklDX0lDQ0xBQjoKCQljYXNlIFBIT1RPTUVUUklDX0lUVUxBQjoKCQkJbG9hZE1ldGhvZCA9IExvYWRBc1JCR0E7CgkJCWJyZWFrOwoJCWNhc2UgUEhPVE9NRVRSSUNfTE9HTFVWOgoJCQlsb2FkTWV0aG9kID0gTG9hZEFzUkdCRjsKCQkJYnJlYWs7CgkJY2FzZSBQSE9UT01FVFJJQ19TRVBBUkFURUQ6CgkJCWlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX0NPTlRJRykgewoJCQkJLy8gaWYgaW1hZ2UgaXMgUEhPVE9NRVRSSUNfU0VQQVJBVEVEIF9hbmRfIGNvbWVzIHdpdGggYW4gSUNDIHByb2ZpbGUsIAoJCQkJLy8gdGhlbiB0aGUgaW1hZ2Ugc2hvdWxkIHByZXNlcnZlIGl0cyBvcmlnaW5hbCAoQ01ZSykgY29sb3VyIG1vZGVsIGFuZCAKCQkJCS8vIHNob3VsZCBiZSByZWFkIGFzIENNWUsgKHRvIGtlZXAgdGhlIG1hdGNoIG9mIHBpeGVsIGFuZCBwcm9maWxlIGFuZCAKCQkJCS8vIHRvIGF2b2lkIG11bHRpcGxlIGNvbnZlcnNpb25zLiBDb252ZXJzaW9uIGNhbiBiZSBkb25lIGJ5IGNoYW5naW5nIAoJCQkJLy8gdGhlIHByb2ZpbGUgZnJvbSBpdCdzIG9yaWdpbmFsIENNWUsgdG8gYW4gUkdCIHByb2ZpbGUgd2l0aCBhbiAKCQkJCS8vIGFwcm9wcmlhdGUgY29sb3IgbWFuYWdlbWVudCBzeXN0ZW0uIFdvcmtzIHdpdGggbm9uLXRpbGVkIFRJRkZzLgoJCQkJaWYoKCgoZmxhZ3MgJiBUSUZGX0NNWUspID09IFRJRkZfQ01ZSykgfHwgc2FtcGxlc3BlcnBpeGVsID4gNCkgJiYgIWJJc1RpbGVkKSB7CgkJCQkJbG9hZE1ldGhvZCA9IExvYWRBc0NNWUs7CgkJCQl9IGVsc2UgewoJCQkJCWxvYWRNZXRob2QgPSBMb2FkQXNSQkdBOwoJCQkJfQoJCQl9IGVsc2UgaWYocGxhbmFyX2NvbmZpZyA9PSBQTEFOQVJDT05GSUdfU0VQQVJBVEUpIHsKCQkJCS8vIFRJRkZSZWFkUkdCQUltYWdlIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIGNhc2UgLi4uCgkJCQlsb2FkTWV0aG9kID0gTG9hZEFzQ01ZSzsKCQkJfQoJCQlicmVhazsKCQljYXNlIFBIT1RPTUVUUklDX01JTklTV0hJVEU6CgkJY2FzZSBQSE9UT01FVFJJQ19NSU5JU0JMQUNLOgoJCWNhc2UgUEhPVE9NRVRSSUNfUEFMRVRURToKCQkJLy8gV2hlbiBzYW1wbGVzcGVycGl4ZWwgPSAyIGFuZCBiaXRzcGVyc2FtcGxlID0gOCwgc2V0IHRoZSBpbWFnZSBhcyBhCgkJCS8vIDgtYml0IGluZGV4ZWQgaW1hZ2UgKyA4LWJpdCBhbHBoYSBsYXllciBpbWFnZQoJCQkvLyBhbmQgY29udmVydCB0byBhIDgtYml0IGltYWdlIHdpdGggYSB0cmFuc3BhcmVuY3kgdGFibGUKCQkJaWYoKHNhbXBsZXNwZXJwaXhlbCA9PSAyKSAmJiAoYml0c3BlcnNhbXBsZSA9PSA4KSkgewoJCQkJbG9hZE1ldGhvZCA9IExvYWRBczhCaXRUcm5zOwoJCQl9IGVsc2UgewoJCQkJbG9hZE1ldGhvZCA9IExvYWRBc0dlbmVyaWNTdHJpcDsKCQkJfQoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlsb2FkTWV0aG9kID0gTG9hZEFzR2VuZXJpY1N0cmlwOwoJCQlicmVhazsKCX0KCglpZigobG9hZE1ldGhvZCA9PSBMb2FkQXNHZW5lcmljU3RyaXApICYmIGJJc1RpbGVkKSB7CgkJbG9hZE1ldGhvZCA9IExvYWRBc1RpbGVkOwoJfQoKCXJldHVybiBsb2FkTWV0aG9kOwp9CgoKc3RhdGljIEZJQklUTUFQICogRExMX0NBTExDT05WCkxvYWQoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgcGFnZSwgaW50IGZsYWdzLCB2b2lkICpkYXRhKSB7CglpZiAoKGhhbmRsZSAhPSBOVUxMKSAmJiAoZGF0YSAhPSBOVUxMKSkgewoJCVRJRkYgICAqdGlmID0gTlVMTDsKCQl1aW50MzIgaGVpZ2h0ID0gMDsgCgkJdWludDMyIHdpZHRoID0gMDsgCgkJdWludDE2IGJpdHNwZXJzYW1wbGUgPSAxOwoJCXVpbnQxNiBzYW1wbGVzcGVycGl4ZWwgPSAxOwoJCXVpbnQzMiByb3dzcGVyc3RyaXA7ICAKCQl1aW50MTYgcGhvdG9tZXRyaWMgPSBQSE9UT01FVFJJQ19NSU5JU1dISVRFOwoJCXVpbnQxNiBjb21wcmVzc2lvbiA9IENPTVBSRVNTSU9OX05PTkU7CgkJdWludDE2IHBsYW5hcl9jb25maWc7CgoJCUZJQklUTUFQICpkaWIgPSBOVUxMOwoJCXVpbnQzMiBpY2NTaXplID0gMDsJCS8vIElDQyBwcm9maWxlIGxlbmd0aAoJCXZvaWQgKmljY0J1ZiA9IE5VTEw7CS8vIElDQyBwcm9maWxlIGRhdGEJCQoKCQl0cnkgewkKCQkJZmlfVElGRklPICpmaW8gPSAoZmlfVElGRklPKilkYXRhOwoJCQl0aWYgPSBmaW8tPnRpZjsKCgkJCWlmIChwYWdlICE9IC0xKSB7CgkJCQlpZiAoIXRpZiB8fCAhVElGRlNldERpcmVjdG9yeSh0aWYsICh0ZGlyX3QpcGFnZSkpIHsKCQkJCQl0aHJvdyAiRXJyb3IgZW5jb3VudGVyZWQgd2hpbGUgb3BlbmluZyBUSUZGIGZpbGUiOwkJCQoJCQkJfQoJCQl9CgoJCQkvLyBmaXJzdCwgZ2V0IHRoZSBwaG90b21ldHJpYywgdGhlIGNvbXByZXNzaW9uIGFuZCBiYXNpYyBtZXRhZGF0YQoJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfUEhPVE9NRVRSSUMsICZwaG90b21ldHJpYyk7CgkJCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfQ09NUFJFU1NJT04sICZjb21wcmVzc2lvbik7CgoJCQkvLyBjaGVjayBmb3IgSERSIGZvcm1hdHMKCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQlpZihwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19MT0dMVVYpIHsKCQkJCS8vIGNoZWNrIHRoZSBjb21wcmVzc2lvbgoJCQkJaWYoY29tcHJlc3Npb24gIT0gQ09NUFJFU1NJT05fU0dJTE9HICYmIGNvbXByZXNzaW9uICE9IENPTVBSRVNTSU9OX1NHSUxPRzI0KSB7CgkJCQkJdGhyb3cgIk9ubHkgc3VwcG9ydCBTR0lMT0cgY29tcHJlc3NlZCBMb2dMdXYgZGF0YSI7CgkJCQl9CgkJCQkvLyBzZXQgZGVjb2RlciB0byBvdXRwdXQgaW4gSUVFRSAzMi1iaXQgZmxvYXQgWFlaIHZhbHVlcwoJCQkJVElGRlNldEZpZWxkKHRpZiwgVElGRlRBR19TR0lMT0dEQVRBRk1ULCBTR0lMT0dEQVRBRk1UX0ZMT0FUKTsKCQkJfQoKCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQlUSUZGR2V0RmllbGQodGlmLCBUSUZGVEFHX0lNQUdFV0lEVEgsICZ3aWR0aCk7CgkJCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfSU1BR0VMRU5HVEgsICZoZWlnaHQpOwoJCQlUSUZGR2V0RmllbGQodGlmLCBUSUZGVEFHX1NBTVBMRVNQRVJQSVhFTCwgJnNhbXBsZXNwZXJwaXhlbCk7CgkJCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfQklUU1BFUlNBTVBMRSwgJmJpdHNwZXJzYW1wbGUpOwoJCQlUSUZGR2V0RmllbGQodGlmLCBUSUZGVEFHX1JPV1NQRVJTVFJJUCwgJnJvd3NwZXJzdHJpcCk7ICAgCQkJCgkJCVRJRkZHZXRGaWVsZCh0aWYsIFRJRkZUQUdfSUNDUFJPRklMRSwgJmljY1NpemUsICZpY2NCdWYpOwoJCQlUSUZGR2V0RmllbGREZWZhdWx0ZWQodGlmLCBUSUZGVEFHX1BMQU5BUkNPTkZJRywgJnBsYW5hcl9jb25maWcpOwoKCQkJLy8gY2hlY2sgZm9yIHVuc3VwcG9ydGVkIGZvcm1hdHMKCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQlpZiAoY29tcHJlc3Npb24gPT0gQ09NUFJFU1NJT05fT0pQRUcpCgkJCQl0aHJvdyAiNi4wIEpQRUcgZW5jb2RpbmcgaXMgbm90IHN1cHBvcnRlZCI7CgoJCQlpZigocGhvdG9tZXRyaWMgPT0gUEhPVE9NRVRSSUNfU0VQQVJBVEVEKSAmJiAoYml0c3BlcnNhbXBsZSA9PSAxNikpCgkJCQl0aHJvdyAiVW5hYmxlIHRvIGhhbmRsZSAxNi1iaXQgQ01ZSyBUSUZGIjsKCgkJCWlmKElzVmFsaWRCaXRzUGVyU2FtcGxlKHBob3RvbWV0cmljLCBiaXRzcGVyc2FtcGxlKSA9PSBGQUxTRSkgewoJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAKCQkJCQkiVW5hYmxlIHRvIGhhbmRsZSB0aGlzIGZvcm1hdDogYml0c3BlcnNhbXBsZSA9ICVkLCBzYW1wbGVzcGVycGl4ZWwgPSAlZCwgcGhvdG9tZXRyaWMgPSAlZCIsIAoJCQkJCShpbnQpYml0c3BlcnNhbXBsZSwgKGludClzYW1wbGVzcGVycGl4ZWwsIChpbnQpcGhvdG9tZXRyaWMpOwoJCQkJdGhyb3cgKGNoYXIqKU5VTEw7CgkJCX0KCgkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCQkJLy8gZ2V0IGltYWdlIGRhdGEgdHlwZQoKCQkJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBSZWFkSW1hZ2VUeXBlKHRpZiwgYml0c3BlcnNhbXBsZSwgc2FtcGxlc3BlcnBpeGVsKTsKCgkJCS8vIGdldCB0aGUgbW9zdCBhcHByb3ByaWF0ZSBsb2FkaW5nIG1ldGhvZAoKCQkJVElGRkxvYWRNZXRob2QgbG9hZE1ldGhvZCA9IEZpbmRMb2FkTWV0aG9kKHRpZiwgaW1hZ2VfdHlwZSwgZmxhZ3MpOwoKCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQlpZihsb2FkTWV0aG9kID09IExvYWRBc1JCR0EpIHsKCQkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCQkJLy8gUkdCW0FdIGxvYWRpbmcgdXNpbmcgdGhlIFRJRkZSZWFkUkdCQUltYWdlKCkgQVBJCgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJCQlCT09MIGhhc19hbHBoYSA9IEZBTFNFOyAgIAoKCQkJCS8vIFJlYWQgdGhlIHdob2xlIGltYWdlIGludG8gb25lIGJpZyBSR0JBIGJ1ZmZlciBhbmQgdGhlbiAKCQkJCS8vIGNvbnZlcnQgaXQgdG8gYSBESUIuIFRoaXMgaXMgdXNpbmcgdGhlIHRyYWRpdGlvbmFsCgkJCQkvLyBUSUZGUmVhZFJHQkFJbWFnZSgpIEFQSSB0aGF0IHdlIHRydXN0LgoKCQkJCXVpbnQzMiAqcmFzdGVyID0gKHVpbnQzMiopX1RJRkZtYWxsb2Mod2lkdGggKiBoZWlnaHQgKiBzaXplb2YodWludDMyKSk7CgkJCQlpZiAocmFzdGVyID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCS8vIHJlYWQgdGhlIGltYWdlIGluIG9uZSBjaHVuayBpbnRvIGFuIFJHQkEgYXJyYXkKCgkJCQlpZiAoIVRJRkZSZWFkUkdCQUltYWdlKHRpZiwgd2lkdGgsIGhlaWdodCwgcmFzdGVyLCAwKSkgewoJCQkJCV9USUZGZnJlZShyYXN0ZXIpOwoJCQkJCXRocm93IEZJX01TR19FUlJPUl9VTlNVUFBPUlRFRF9GT1JNQVQ7CgkJCQl9CgoJCQkJLy8gVElGRlJlYWRSR0JBSW1hZ2UgYWx3YXlzIGRlbGl2ZXJlcyAzIG9yIDQgc2FtcGxlcyBwZXIgcGl4ZWwgaW1hZ2VzCgkJCQkvLyAoUkdCIG9yIFJHQkEsIHNlZSBiZWxvdykuIEN1dC1vZmYgcG9zc2libHkgcHJlc2VudCBjaGFubmVscyAoYWRkaXRpb25hbCAKCQkJCS8vIGFscGhhIGNoYW5uZWxzKSBmcm9tIGUuZy4gUGhvdG9zaG9wLiBBbnkgQ01ZSyhBLi4pIGlzIG5vdyB0cmVhdGVkIGFzIFJHQiwKCQkJCS8vIGFueSBhZGRpdGlvbmFsIGFscGhhIGNoYW5uZWwgb24gUkdCKEFBLi4pIGlzIGxvc3Qgb24gY29udmVyc2lvbiB0byBSR0IoQSkKCgkJCQlpZihzYW1wbGVzcGVycGl4ZWwgPiA0KSB7CgkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiV2FybmluZzogJWQgYWRkaXRpb25hbCBhbHBoYSBjaGFubmVsKHMpIGlnbm9yZWQiLCBzYW1wbGVzcGVycGl4ZWwtNCk7CgkJCQkJc2FtcGxlc3BlcnBpeGVsID0gNDsKCQkJCX0KCgkJCQkvLyBjcmVhdGUgYSBuZXcgRElCICh0YWtlIGNhcmUgb2YgZGlmZmVyZW50IHNhbXBsZXMtcGVyLXBpeGVsIGluIGNhc2UgCgkJCQkvLyBvZiBjb252ZXJ0ZWQgQ01ZSyBpbWFnZSAoUkdCIGNvbnZlcnNpb24gaXMgb24gc2FtcGxlIHBlciBwaXhlbCBsZXNzKQoKCQkJCWlmIChwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19TRVBBUkFURUQgJiYgc2FtcGxlc3BlcnBpeGVsID09IDQpIHsKCQkJCQlzYW1wbGVzcGVycGl4ZWwgPSAzOwoJCQkJfQoKCQkJCWRpYiA9IENyZWF0ZUltYWdlVHlwZShpbWFnZV90eXBlLCB3aWR0aCwgaGVpZ2h0LCBiaXRzcGVyc2FtcGxlLCBzYW1wbGVzcGVycGl4ZWwpOwoJCQkJaWYgKGRpYiA9PSBOVUxMKSB7CgkJCQkJLy8gZnJlZSB0aGUgcmFzdGVyIHBvaW50ZXIgYW5kIG91dHB1dCBhbiBlcnJvciBpZiBhbGxvY2F0aW9uIGZhaWxlZAoKCQkJCQlfVElGRmZyZWUocmFzdGVyKTsKCgkJCQkJdGhyb3cgRklfTVNHX0VSUk9SX0RJQl9NRU1PUlk7CgkJCQl9CgkJCQkKCQkJCS8vIGZpbGwgaW4gdGhlIHJlc29sdXRpb24gKGVuZ2xpc2ggb3IgdW5pdmVyc2FsKQoKCQkJCVJlYWRSZXNvbHV0aW9uKHRpZiwgZGliKTsKCgkJCQkvLyByZWFkIHRoZSByYXN0ZXIgbGluZXMgYW5kIHNhdmUgdGhlbSBpbiB0aGUgRElCCgkJCQkvLyB3aXRoIFJHQiBtb2RlLCB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgb3JkZXIgb2YgdGhlIDMgc2FtcGxlcyBSR0IKCQkJCS8vIFdlIHVzZSBtYWNyb3MgZm9yIGV4dHJhY3RpbmcgY29tcG9uZW50cyBmcm9tIHRoZSBwYWNrZWQgQUJHUiAKCQkJCS8vIGZvcm0gcmV0dXJuZWQgYnkgVElGRlJlYWRSR0JBSW1hZ2UuCgoJCQkJdWludDMyICpyb3cgPSAmcmFzdGVyWzBdOwoKCQkJCWlmIChzYW1wbGVzcGVycGl4ZWwgPT0gNCkgewoJCQkJCS8vIDMyLWJpdCBSR0JBCgkJCQkJZm9yICh1aW50MzIgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgkJCQkJCWZvciAodWludDMyIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJYml0c1tGSV9SR0JBX0JMVUVdCT0gKEJZVEUpVElGRkdldEIocm93W3hdKTsKCQkJCQkJCWJpdHNbRklfUkdCQV9HUkVFTl0gPSAoQllURSlUSUZGR2V0Ryhyb3dbeF0pOwoJCQkJCQkJYml0c1tGSV9SR0JBX1JFRF0JPSAoQllURSlUSUZGR2V0Uihyb3dbeF0pOwoJCQkJCQkJYml0c1tGSV9SR0JBX0FMUEhBXSA9IChCWVRFKVRJRkZHZXRBKHJvd1t4XSk7CgoJCQkJCQkJaWYgKGJpdHNbRklfUkdCQV9BTFBIQV0gIT0gMCkKCQkJCQkJCQloYXNfYWxwaGEgPSBUUlVFOwkJCQkJCQkJCgoJCQkJCQkJYml0cyArPSA0OwoJCQkJCQl9CgkJCQkJCXJvdyArPSB3aWR0aDsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCS8vIDI0LWJpdCBSR0IKCQkJCQlmb3IgKHVpbnQzMiB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yICh1aW50MzIgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQliaXRzW0ZJX1JHQkFfQkxVRV0JPSAoQllURSlUSUZGR2V0Qihyb3dbeF0pOwoJCQkJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IChCWVRFKVRJRkZHZXRHKHJvd1t4XSk7CgkJCQkJCQliaXRzW0ZJX1JHQkFfUkVEXQk9IChCWVRFKVRJRkZHZXRSKHJvd1t4XSk7CgoJCQkJCQkJYml0cyArPSAzOwoJCQkJCQl9CgkJCQkJCXJvdyArPSB3aWR0aDsKCQkJCQl9CgkJCQl9CgoJCQkJX1RJRkZmcmVlKHJhc3Rlcik7CgoJCQkJRnJlZUltYWdlX1NldFRyYW5zcGFyZW50KGRpYiwgaGFzX2FscGhhKTsKCgkJCX0gZWxzZSBpZihsb2FkTWV0aG9kID09IExvYWRBczhCaXRUcm5zKSB7CgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkJCS8vIDgtYml0ICsgOC1iaXQgYWxwaGEgbGF5ZXIgbG9hZGluZwoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQkJLy8gY3JlYXRlIGEgbmV3IDgtYml0IERJQgoJCQkJZGliID0gQ3JlYXRlSW1hZ2VUeXBlKGltYWdlX3R5cGUsIHdpZHRoLCBoZWlnaHQsIGJpdHNwZXJzYW1wbGUsIHNhbXBsZXNwZXJwaXhlbCk7CgkJCQlpZiAoZGliID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCS8vIGZpbGwgaW4gdGhlIHJlc29sdXRpb24gKGVuZ2xpc2ggb3IgdW5pdmVyc2FsKQoKCQkJCVJlYWRSZXNvbHV0aW9uKHRpZiwgZGliKTsKCgkJCQkvLyBzZXQgdXAgdGhlIGNvbG9ybWFwIGJhc2VkIG9uIHBob3RvbWV0cmljCQoKCQkJCVJlYWRQYWxldHRlKHRpZiwgcGhvdG9tZXRyaWMsIGJpdHNwZXJzYW1wbGUsIGRpYik7CgoJCQkJLy8gY2FsY3VsYXRlIHRoZSBsaW5lICsgcGl0Y2ggKHNlcGFyYXRlIGZvciBzY3IgJiBkZXN0KQoKCQkJCXRzaXplX3Qgc3JjX2xpbmUgPSBUSUZGU2NhbmxpbmVTaXplKHRpZik7CgkJCQkvLyBoZXJlLCB0aGUgcGl0Y2ggaXMgMnggbGVzcyB0aGFuIHRoZSBvcmlnaW5hbCBhcyB3ZSBvbmx5IGtlZXAgdGhlIGZpcnN0IGxheWVyCQkJCQoJCQkJaW50IGRzdF9waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoKCQkJCS8vIHRyYW5zcGFyZW5jeSB0YWJsZSBmb3IgOC1iaXQgKyA4LWJpdCBhbHBoYSBpbWFnZXMKCgkJCQlCWVRFIHRybnNbMjU2XTsgCgkJCQkvLyBjbGVhciB0aGUgdHJhbnNwYXJlbmN5IHRhYmxlCgkJCQltZW1zZXQodHJucywgMHhGRiwgMjU2ICogc2l6ZW9mKEJZVEUpKTsKCgoJCQkJLy8gSW4gdGhlIHRpZmYgZmlsZSB0aGUgbGluZXMgYXJlIHNhdmUgZnJvbSB1cCB0byBkb3duIAoJCQkJLy8gSW4gYSBESUIgdGhlIGxpbmVzIG11c3QgYmUgc2F2ZWQgZnJvbSBkb3duIHRvIHVwCgoJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIDEpOwoKCQkJCS8vIHJlYWQgdGhlIHRpZmYgbGluZXMgYW5kIHNhdmUgdGhlbSBpbiB0aGUgRElCCgoJCQkJaWYocGxhbmFyX2NvbmZpZyA9PSBQTEFOQVJDT05GSUdfQ09OVElHKSB7CgoJCQkJCUJZVEUgKmJ1ZiA9IChCWVRFKiltYWxsb2MoVElGRlN0cmlwU2l6ZSh0aWYpICogc2l6ZW9mKEJZVEUpKTsKCQkJCQlpZihidWYgPT0gTlVMTCkgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCgoJCQkJCWZvciAodWludDMyIHkgPSAwOyB5IDwgaGVpZ2h0OyB5ICs9IHJvd3NwZXJzdHJpcCkgewoJCQkJCQlpbnQzMiBucm93ID0gKHkgKyByb3dzcGVyc3RyaXAgPiBoZWlnaHQgPyBoZWlnaHQgLSB5IDogcm93c3BlcnN0cmlwKTsKCgkJCQkJCWlmIChUSUZGUmVhZEVuY29kZWRTdHJpcCh0aWYsIFRJRkZDb21wdXRlU3RyaXAodGlmLCB5LCAwKSwgYnVmLCBucm93ICogc3JjX2xpbmUpID09IC0xKSB7CgkJCQkJCQlmcmVlKGJ1Zik7CgkJCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfUEFSU0lORzsKCQkJCQkJfQoJCQkJCQlmb3IgKGludCBsID0gMDsgbCA8IG5yb3c7IGwrKykgewoJCQkJCQkJQllURSAqcCA9IGJpdHM7CgkJCQkJCQlCWVRFICpiID0gYnVmICsgbCAqIHNyY19saW5lOwoKCQkJCQkJCWZvcih1aW50MzIgeCA9IDA7IHggPCAodWludDMyKShzcmNfbGluZSAvIHNhbXBsZXNwZXJwaXhlbCk7IHgrKykgewoJCQkJCQkJCS8vIGNvcHkgdGhlIDgtYml0IGxheWVyCgkJCQkJCQkJKnAgPSBiWzBdOwoJCQkJCQkJCS8vIGNvbnZlcnQgdGhlIDgtYml0IGFscGhhIGxheWVyIHRvIGEgdHJucyB0YWJsZQoJCQkJCQkJCXRybnNbIGJbMF0gXSA9IGJbMV07CgoJCQkJCQkJCXArKzsKCQkJCQkJCQliICs9IHNhbXBsZXNwZXJwaXhlbDsKCQkJCQkJCX0KCQkJCQkJCWJpdHMgLT0gZHN0X3BpdGNoOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQlmcmVlKGJ1Zik7CgkJCQl9CgkJCQllbHNlIGlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX1NFUEFSQVRFKSB7CgkJCQkJdHNpemVfdCBzdHJpcHNpemUgPSBUSUZGU3RyaXBTaXplKHRpZikgKiBzaXplb2YoQllURSk7CgkJCQkJQllURSAqYnVmID0gKEJZVEUqKW1hbGxvYygyICogc3RyaXBzaXplKTsKCQkJCQlCWVRFICpncmV5ID0gYnVmOwoJCQkJCUJZVEUgKmFscGhhID0gYnVmICsgc3RyaXBzaXplOwoKCQkJCQlmb3IgKHVpbnQzMiB5ID0gMDsgeSA8IGhlaWdodDsgeSArPSByb3dzcGVyc3RyaXApIHsKCQkJCQkJaW50MzIgbnJvdyA9ICh5ICsgcm93c3BlcnN0cmlwID4gaGVpZ2h0ID8gaGVpZ2h0IC0geSA6IHJvd3NwZXJzdHJpcCk7CgoJCQkJCQlpZiAoVElGRlJlYWRFbmNvZGVkU3RyaXAodGlmLCBUSUZGQ29tcHV0ZVN0cmlwKHRpZiwgeSwgMCksIGdyZXksIG5yb3cgKiBzcmNfbGluZSkgPT0gLTEpIHsKCQkJCQkJCWZyZWUoYnVmKTsKCQkJCQkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCQkJCQl9IAoJCQkJCQlpZiAoVElGRlJlYWRFbmNvZGVkU3RyaXAodGlmLCBUSUZGQ29tcHV0ZVN0cmlwKHRpZiwgeSwgMSksIGFscGhhLCBucm93ICogc3JjX2xpbmUpID09IC0xKSB7CgkJCQkJCQlmcmVlKGJ1Zik7CgkJCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfUEFSU0lORzsKCQkJCQkJfSAKCgkJCQkJCWZvciAoaW50IGwgPSAwOyBsIDwgbnJvdzsgbCsrKSB7CgkJCQkJCQlCWVRFICpwID0gYml0czsKCQkJCQkJCUJZVEUgKmcgPSBncmV5ICsgbCAqIHNyY19saW5lOwoJCQkJCQkJQllURSAqYSA9IGFscGhhICsgbCAqIHNyY19saW5lOwoKCQkJCQkJCWZvcih1aW50MzIgeCA9IDA7IHggPCAodWludDMyKShzcmNfbGluZSk7IHgrKykgewoJCQkJCQkJCS8vIGNvcHkgdGhlIDgtYml0IGxheWVyCgkJCQkJCQkJKnAgPSBnWzBdOwoJCQkJCQkJCS8vIGNvbnZlcnQgdGhlIDgtYml0IGFscGhhIGxheWVyIHRvIGEgdHJucyB0YWJsZQoJCQkJCQkJCXRybnNbIGdbMF0gXSA9IGFbMF07CgoJCQkJCQkJCXArKzsKCQkJCQkJCQlnKys7CgkJCQkJCQkJYSsrOwoJCQkJCQkJfQoJCQkJCQkJYml0cyAtPSBkc3RfcGl0Y2g7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWZyZWUoYnVmKTsKCgkJCQl9CgkJCQkKCQkJCUZyZWVJbWFnZV9TZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIsICZ0cm5zWzBdLCAyNTYpOwoJCQkJRnJlZUltYWdlX1NldFRyYW5zcGFyZW50KGRpYiwgVFJVRSk7CgoJCQl9IGVsc2UgaWYobG9hZE1ldGhvZCA9PSBMb2FkQXNDTVlLKSB7CgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkJCS8vIENNWUsgbG9hZGluZwoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQkJQk9PTCBoYXNfYWxwaGEgPSBGQUxTRTsgICAgCgoJCQkJLy8gQXQgdGhpcyBwbGFjZSwgc2FtcGxlc3BlcnBpeGVsIGNvdWxkIGJlID4gNCwgZXNwLiB3aGVuIGEgQ01ZSyhBKSBmb3JtYXQKCQkJCS8vIGlzIHJlY29nbml6ZWQuIFdoZXJlIGFsbCBvdGhlciBmb3JtYXRzIGFyZSBoYW5kbGVkIHN0cmFpZ2h0LWZvcndhcmQsIHRoaXMKCQkJCS8vIGZvcm1hdCBoYXMgdG8gYmUgaGFuZGxlZCBzcGVjaWFsIAoKCQkJCUJPT0wgaXNDTVlLQSA9IChwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19TRVBBUkFURUQpICYmIChzYW1wbGVzcGVycGl4ZWwgPiA0KTsKCQkJCXVpbnQxNiBzcHAgPSBNSU4oc2FtcGxlc3BlcnBpeGVsLCAodWludDE2KTQpOwoJCQkJaWYoKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX1NFUEFSQVRFKSAmJiAhaXNDTVlLQSAmJiAoKGZsYWdzICYgVElGRl9DTVlLKSAhPSBUSUZGX0NNWUspKSB7CgkJCQkJLy8gQ01ZSyBwaWN0dXJlID0+IGNvbnZlcnQgdG8gUkdCIDI0LWJpdAoJCQkJCXNwcCA9IDM7CgkJCQl9CgoJCQkJLy8gY3JlYXRlIGEgbmV3IERJQgoJCQkJZGliID0gQ3JlYXRlSW1hZ2VUeXBlKGltYWdlX3R5cGUsIHdpZHRoLCBoZWlnaHQsIGJpdHNwZXJzYW1wbGUsIHNwcCk7CgkJCQlpZiAoZGliID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCS8vIGZpbGwgaW4gdGhlIHJlc29sdXRpb24gKGVuZ2xpc2ggb3IgdW5pdmVyc2FsKQoKCQkJCVJlYWRSZXNvbHV0aW9uKHRpZiwgZGliKTsKCgkJCQkvLyBjYWxjdWxhdGUgdGhlIGxpbmUgKyBwaXRjaCAoc2VwYXJhdGUgZm9yIHNjciAmIGRlc3QpCgoJCQkJdHNpemVfdCBzcmNfbGluZSA9IFRJRkZTY2FubGluZVNpemUodGlmKTsKCQkJCWludCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKTsKCgkJCQkvLyBJbiB0aGUgdGlmZiBmaWxlIHRoZSBsaW5lcyBhcmUgc2F2ZSBmcm9tIHVwIHRvIGRvd24gCgkJCQkvLyBJbiBhIERJQiB0aGUgbGluZXMgbXVzdCBiZSBzYXZlZCBmcm9tIGRvd24gdG8gdXAKCgkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSk7CgoJCQkJLy8gcmVhZCB0aGUgdGlmZiBsaW5lcyBhbmQgc2F2ZSB0aGVtIGluIHRoZSBESUIKCgkJCQlpZihwbGFuYXJfY29uZmlnID09IFBMQU5BUkNPTkZJR19DT05USUcpIHsKCQkJCQlCWVRFICpidWYgPSAoQllURSopbWFsbG9jKFRJRkZTdHJpcFNpemUodGlmKSAqIHNpemVvZihCWVRFKSk7CgkJCQkJaWYoYnVmID09IE5VTEwpIHRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgoJCQkJCWZvciAodWludDMyIHkgPSAwOyB5IDwgaGVpZ2h0OyB5ICs9IHJvd3NwZXJzdHJpcCkgewoJCQkJCQlpbnQzMiBucm93ID0gKHkgKyByb3dzcGVyc3RyaXAgPiBoZWlnaHQgPyBoZWlnaHQgLSB5IDogcm93c3BlcnN0cmlwKTsKCgkJCQkJCWlmIChUSUZGUmVhZEVuY29kZWRTdHJpcCh0aWYsIFRJRkZDb21wdXRlU3RyaXAodGlmLCB5LCAwKSwgYnVmLCBucm93ICogc3JjX2xpbmUpID09IC0xKSB7CgkJCQkJCQlmcmVlKGJ1Zik7CgkJCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfUEFSU0lORzsKCQkJCQkJfSAKCQkJCQkJaWYoaXNDTVlLQSkgewoJCQkJCQkJLy8gQ01ZS0EgcGljdHVyZQoJCQkJCQkJZm9yIChpbnQgbCA9IDA7IGwgPCBucm93OyBsKyspIHsKCQkJCQkJCQkvLyBIZXJlIHdlIGtub3c6IHNhbXBsZXMtcGVyLXBpeGVsIHdhcyA+PSA1IG9uIENNWUtBIHBpY3R1cmUKCQkJCQkJCQkvLyBUaGlzIHNob3VsZCBiZSBjb252ZXJ0ZWQgdG8gUkdCQSBvciBDTVlLLCBkZXBlbmRpbmcgb24gCgkJCQkJCQkJLy8gVElGRl9DTVlLIGlzIGdpdmVuLiBUaGUgcmVzdWx0aW5nIGltYWdlIGFsd2F5cyBoYXMgMzJicHAuCgoJCQkJCQkJCUJZVEUgKnAgPSBiaXRzOwoJCQkJCQkJCUJZVEUgKmIgPSBidWYgKyBsICogc3JjX2xpbmU7CgoJCQkJCQkJCWZvciAodWludDMyIHggPSAwOyB4IDwgKHVpbnQzMikoc3JjX2xpbmUgLyBzYW1wbGVzcGVycGl4ZWwpOyB4KyspIHsKCQkJCQkJCQkJaWYgKChmbGFncyAmIFRJRkZfQ01ZSykgPT0gVElGRl9DTVlLKSB7CgkJCQkJCQkJCQltZW1jcHkocCwgYiwgc3BwKTsKCQkJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkJCUJZVEUgayA9IDI1NSAtIGJbM107CgkJCQkJCQkJCQlwW0ZJX1JHQkFfUkVEXQkgPSAoayooMjU1LWJbMF0pKS8yNTU7CgkJCQkJCQkJCQlwW0ZJX1JHQkFfR1JFRU5dID0gKGsqKDI1NS1iWzFdKSkvMjU1OwoJCQkJCQkJCQkJcFtGSV9SR0JBX0JMVUVdCSA9IChrKigyNTUtYlsyXSkpLzI1NTsKCQkJCQkJCQkJCWlmICgocFtGSV9SR0JBX0FMUEhBXSA9IGJbNF0pICE9IDApCgkJCQkJCQkJCQkJaGFzX2FscGhhID0gVFJVRTsJCQkJCQkJCQoJCQkJCQkJCQl9CgkJCQkJCQkJCWIgKz0gc2FtcGxlc3BlcnBpeGVsOwoJCQkJCQkJCQlwICs9IHNwcDsKCQkJCQkJCQl9CgkJCQkJCQkJYml0cyAtPSBkc3RfcGl0Y2g7CgkJCQkJCQl9CQkJCQkJCQkKCQkJCQkJfQoJCQkJCQllbHNlICB7CgkJCQkJCQkvLyBDTVlLIHBpY3R1cmU6IGp1c3QgY29weQoJCQkJCQkJZm9yIChpbnQgbCA9IDA7IGwgPCBucm93OyBsKyspIHsJCQkJCQkJCQoJCQkJCQkJCUJZVEUgKmIgPSBidWYgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJbWVtY3B5KGJpdHMsIGIsIHNyY19saW5lKTsKCQkJCQkJCQliaXRzIC09IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQkJCQkJCQoJCQkJCX0KCgkJCQkJZnJlZShidWYpOwoJCQkJfQoJCQkJZWxzZSBpZihwbGFuYXJfY29uZmlnID09IFBMQU5BUkNPTkZJR19TRVBBUkFURSkgewoJCQkJCXVpbnQxNiBzYW1wbGU7CgkJCQkJQllURSAqY2hhbm5lbDsKCQkJCQl0c2l6ZV90IHN0cmlwc2l6ZSA9IFRJRkZTdHJpcFNpemUodGlmKSAqIHNpemVvZihCWVRFKTsKCQkJCQlCWVRFICpidWYgPSAoQllURSopbWFsbG9jKHNhbXBsZXNwZXJwaXhlbCAqIHN0cmlwc2l6ZSk7CgkJCQkJaWYoYnVmID09IE5VTEwpIHRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgoJCQkJCWZvciAodWludDMyIHkgPSAwOyB5IDwgaGVpZ2h0OyB5ICs9IHJvd3NwZXJzdHJpcCkgewoJCQkJCQlpbnQzMiBucm93ID0gKHkgKyByb3dzcGVyc3RyaXAgPiBoZWlnaHQgPyBoZWlnaHQgLSB5IDogcm93c3BlcnN0cmlwKTsKCgkJCQkJCS8vIHJlYWQgYWxsIHNlcGFyYXRlZCBzdHJpcHMKCQkJCQkJY2hhbm5lbCA9IGJ1ZjsKCQkJCQkJZm9yKHNhbXBsZSA9IDA7IHNhbXBsZSA8IHNhbXBsZXNwZXJwaXhlbDsgc2FtcGxlKyspIHsKCQkJCQkJCWlmIChUSUZGUmVhZEVuY29kZWRTdHJpcCh0aWYsIFRJRkZDb21wdXRlU3RyaXAodGlmLCB5LCBzYW1wbGUpLCBjaGFubmVsLCBucm93ICogc3JjX2xpbmUpID09IC0xKSB7CgkJCQkJCQkJZnJlZShidWYpOwoJCQkJCQkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCQkJCQkJfSAKCQkJCQkJCWNoYW5uZWwgKz0gc3RyaXBzaXplOwoJCQkJCQl9CgkJCQkJCWlmICgoZmxhZ3MgJiBUSUZGX0NNWUspID09IFRJRkZfQ01ZSykgewoJCQkJCQkJLy8gQ01ZSyBvciBDTVlLQSBwaWN0dXJlOiBsb2FkIGFzIDMyLWJpdCBDTVlLLCBza2lwcGluZyBwb3NzaWJseSBwcmVzZW50IGFscGhhIGNoYW5uZWwocykKCQkJCQkJCWZvciAoaW50IGwgPSAwOyBsIDwgbnJvdzsgbCsrKSB7CgkJCQkJCQkJY2hhbm5lbCA9IGJ1ZjsKCQkJCQkJCQlmb3Ioc2FtcGxlID0gMDsgc2FtcGxlIDwgc3BwOyBzYW1wbGUrKykgewoJCQkJCQkJCQlCWVRFICpzcmNfYml0cyA9IGNoYW5uZWwgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gYml0czsKCQkJCQkJCQkJZm9yICh1aW50MzIgeCA9IDA7IHggPCAodWludDMyKShzcmNfbGluZSk7IHgrKykgewoJCQkJCQkJCQkJZHN0X2JpdHNbc2FtcGxlXSA9IHNyY19iaXRzW3hdOwoJCQkJCQkJCQkJZHN0X2JpdHMgKz0gc3BwOwoJCQkJCQkJCQl9CgkJCQkJCQkJCWNoYW5uZWwgKz0gc3RyaXBzaXplOwoJCQkJCQkJCX0KCQkJCQkJCQliaXRzIC09IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQllbHNlIGlmKGlzQ01ZS0EpIHsKCQkJCQkJCS8vIENNWUtBIHBpY3R1cmU6IGNvbnZlcnQgdG8gUkdCQSwgc2tpcHBpbmcgcG9zc2libHkgc29tZSBhbHBoYSBjaGFubmVsKHMpCgkJCQkJCQlmb3IgKGludCBsID0gMDsgbCA8IG5yb3c7IGwrKykgewoJCQkJCQkJCUJZVEUgKmNfY2hhbm5lbCA9IGJ1ZiArIGwgKiBzcmNfbGluZTsKCQkJCQkJCQlCWVRFICptX2NoYW5uZWwgPSBidWYgKyBzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqeV9jaGFubmVsID0gYnVmICsgMipzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqa19jaGFubmVsID0gYnVmICsgMypzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqYV9jaGFubmVsID0gYnVmICsgNCpzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBiaXRzOwoJCQkJCQkJCWZvciAodWludDMyIHggPSAwOyB4IDwgKHVpbnQzMikoc3JjX2xpbmUpOyB4KyspIHsKCQkJCQkJCQkJQllURSBrID0gMjU1IC0ga19jaGFubmVsW3hdOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoayooMjU1LWNfY2hhbm5lbFt4XSkpLzI1NTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0gPSAoayooMjU1LW1fY2hhbm5lbFt4XSkpLzI1NTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChrKigyNTUteV9jaGFubmVsW3hdKSkvMjU1OwoJCQkJCQkJCQlpZiAoKGRzdF9iaXRzW0ZJX1JHQkFfQUxQSEFdID0gYV9jaGFubmVsW3hdKSAhPSAwKQoJCQkJCQkJCQkJaGFzX2FscGhhID0gVFJVRTsKCQkJCQkJCQkJZHN0X2JpdHMgKz0gc3BwOwoJCQkJCQkJCX0KCQkJCQkJCQliaXRzIC09IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQllbHNlICB7CQkJCQkJCQoJCQkJCQkJLy8gQ01ZSyBwaWN0dXJlOiBjb252ZXJ0IHRvIFJHQgoJCQkJCQkJZm9yIChpbnQgbCA9IDA7IGwgPCBucm93OyBsKyspIHsJCQkJCQkJCQoJCQkJCQkJCUJZVEUgKmNfY2hhbm5lbCA9IGJ1ZiArIGwgKiBzcmNfbGluZTsKCQkJCQkJCQlCWVRFICptX2NoYW5uZWwgPSBidWYgKyBzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqeV9jaGFubmVsID0gYnVmICsgMipzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqa19jaGFubmVsID0gYnVmICsgMypzdHJpcHNpemUgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBiaXRzOwoJCQkJCQkJCWZvciAodWludDMyIHggPSAwOyB4IDwgKHVpbnQzMikoc3JjX2xpbmUpOyB4KyspIHsKCQkJCQkJCQkJQllURSBrID0gMjU1IC0ga19jaGFubmVsW3hdOwoJCQkJCQkJCQlkc3RfYml0c1tGSV9SR0JBX1JFRF0JPSAoayooMjU1LWNfY2hhbm5lbFt4XSkpLzI1NTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9HUkVFTl0gPSAoayooMjU1LW1fY2hhbm5lbFt4XSkpLzI1NTsKCQkJCQkJCQkJZHN0X2JpdHNbRklfUkdCQV9CTFVFXQk9IChrKigyNTUteV9jaGFubmVsW3hdKSkvMjU1OwoJCQkJCQkJCQlkc3RfYml0cyArPSBzcHA7CgkJCQkJCQkJfQoJCQkJCQkJCWJpdHMgLT0gZHN0X3BpdGNoOwoJCQkJCQkJfQoJCQkJCQl9CQkJCQkJCgkJCQkJfQoKCQkJCQlmcmVlKGJ1Zik7CgkJCQl9CgoJCQkJRnJlZUltYWdlX1NldFRyYW5zcGFyZW50KGRpYiwgaGFzX2FscGhhKTsKCgkJCX0gZWxzZSBpZihsb2FkTWV0aG9kID09IExvYWRBc0dlbmVyaWNTdHJpcCkgewoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkJCQkvLyBHZW5lcmljIGxvYWRpbmcKCQkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCQkJCS8vIGNyZWF0ZSBhIG5ldyBESUIKCQkJCWRpYiA9IENyZWF0ZUltYWdlVHlwZShpbWFnZV90eXBlLCB3aWR0aCwgaGVpZ2h0LCBiaXRzcGVyc2FtcGxlLCBzYW1wbGVzcGVycGl4ZWwpOwoJCQkJaWYgKGRpYiA9PSBOVUxMKSB7CgkJCQkJdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCQkJCX0KCgkJCQkvLyBmaWxsIGluIHRoZSByZXNvbHV0aW9uIChlbmdsaXNoIG9yIHVuaXZlcnNhbCkKCgkJCQlSZWFkUmVzb2x1dGlvbih0aWYsIGRpYik7CgoJCQkJLy8gc2V0IHVwIHRoZSBjb2xvcm1hcCBiYXNlZCBvbiBwaG90b21ldHJpYwkKCgkJCQlSZWFkUGFsZXR0ZSh0aWYsIHBob3RvbWV0cmljLCBiaXRzcGVyc2FtcGxlLCBkaWIpOwoKCQkJCS8vIGNhbGN1bGF0ZSB0aGUgbGluZSArIHBpdGNoIChzZXBhcmF0ZSBmb3Igc2NyICYgZGVzdCkKCgkJCQl0c2l6ZV90IHNyY19saW5lID0gVElGRlNjYW5saW5lU2l6ZSh0aWYpOwoJCQkJaW50IGRzdF9waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoKCQkJCS8vIEluIHRoZSB0aWZmIGZpbGUgdGhlIGxpbmVzIGFyZSBzYXZlIGZyb20gdXAgdG8gZG93biAKCQkJCS8vIEluIGEgRElCIHRoZSBsaW5lcyBtdXN0IGJlIHNhdmVkIGZyb20gZG93biB0byB1cAoKCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxKTsKCgkJCQkvLyByZWFkIHRoZSB0aWZmIGxpbmVzIGFuZCBzYXZlIHRoZW0gaW4gdGhlIERJQgoKCQkJCWlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX0NPTlRJRykgewoJCQkJCUJPT0wgYlRocm93TWVzc2FnZSA9IEZBTFNFOwoJCQkJCUJZVEUgKmJ1ZiA9IChCWVRFKiltYWxsb2MoVElGRlN0cmlwU2l6ZSh0aWYpICogc2l6ZW9mKEJZVEUpKTsKCQkJCQlpZihidWYgPT0gTlVMTCkgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCgkJCQkJZm9yICh1aW50MzIgeSA9IDA7IHkgPCBoZWlnaHQ7IHkgKz0gcm93c3BlcnN0cmlwKSB7CgkJCQkJCWludDMyIG5yb3cgPSAoeSArIHJvd3NwZXJzdHJpcCA+IGhlaWdodCA/IGhlaWdodCAtIHkgOiByb3dzcGVyc3RyaXApOwoKCQkJCQkJaWYgKFRJRkZSZWFkRW5jb2RlZFN0cmlwKHRpZiwgVElGRkNvbXB1dGVTdHJpcCh0aWYsIHksIDApLCBidWYsIG5yb3cgKiBzcmNfbGluZSkgPT0gLTEpIHsKCQkJCQkJCS8vIGlnbm9yZSBlcnJvcnMgYXMgdGhleSBjYW4gYmUgZnJlcXVlbnQgYW5kIG5vdCByZWFsbHkgdmFsaWQgZXJyb3JzLCBlc3BlY2lhbGx5IHdpdGggZmF4IGltYWdlcwoJCQkJCQkJYlRocm93TWVzc2FnZSA9IFRSVUU7CQkJCQkJCQoJCQkJCQkJLyoKCQkJCQkJCWZyZWUoYnVmKTsKCQkJCQkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCQkJCQkJKi8KCQkJCQkJfSAKCQkJCQkJLy8gY29sb3IvZ3JleXNjYWxlIHBpY3R1cmUgKDEtLCA0LSwgOC1iaXQpIG9yIHNwZWNpYWwgdHlwZSAoaW50LCBsb25nLCBkb3VibGUsIC4uLikKCQkJCQkJLy8gLi4uIGp1c3QgY29weSAKCQkJCQkJZm9yIChpbnQgbCA9IDA7IGwgPCBucm93OyBsKyspIHsJCQkJCQkJCgkJCQkJCQltZW1jcHkoYml0cywgYnVmICsgbCAqIHNyY19saW5lLCBzcmNfbGluZSk7CgkJCQkJCQliaXRzIC09IGRzdF9waXRjaDsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJZnJlZShidWYpOwoKCQkJCQlpZihiVGhyb3dNZXNzYWdlKSB7CgkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgIldhcm5pbmc6IHBhcnNpbmcgZXJyb3IuIEltYWdlIG1heSBiZSBpbmNvbXBsZXRlIG9yIGNvbnRhaW4gaW52YWxpZCBkYXRhICEiKTsKCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX1NFUEFSQVRFKSB7CgkJCQkJQk9PTCBiVGhyb3dNZXNzYWdlID0gRkFMU0U7CgkJCQkJdWludDE2IHNhbXBsZTsKCQkJCQlCWVRFICpjaGFubmVsOwoJCQkJCXRzaXplX3Qgc3RyaXBzaXplID0gVElGRlN0cmlwU2l6ZSh0aWYpICogc2l6ZW9mKEJZVEUpOwoJCQkJCUJZVEUgKmJ1ZiA9IChCWVRFKiltYWxsb2Moc2FtcGxlc3BlcnBpeGVsICogc3RyaXBzaXplKTsKCQkJCQlpZihidWYgPT0gTlVMTCkgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCQkJCQkKCQkJCQlpbnQgYnl0ZXNwZXJzYW1wbGUgPSBiaXRzcGVyc2FtcGxlIC8gODsKCQkJCQlpbnQgYnl0ZXNwZXJwaXhlbCA9IGJ5dGVzcGVyc2FtcGxlICogc2FtcGxlc3BlcnBpeGVsOwoKCQkJCQlmb3IgKHVpbnQzMiB5ID0gMDsgeSA8IGhlaWdodDsgeSArPSByb3dzcGVyc3RyaXApIHsKCQkJCQkJaW50MzIgbnJvdyA9ICh5ICsgcm93c3BlcnN0cmlwID4gaGVpZ2h0ID8gaGVpZ2h0IC0geSA6IHJvd3NwZXJzdHJpcCk7CgoJCQkJCQkvLyByZWFkIGFsbCBzZXBhcmF0ZWQgc3RyaXBzCgkJCQkJCWNoYW5uZWwgPSBidWY7CgkJCQkJCWZvcihzYW1wbGUgPSAwOyBzYW1wbGUgPCBzYW1wbGVzcGVycGl4ZWw7IHNhbXBsZSsrKSB7CgkJCQkJCQlpZiAoVElGRlJlYWRFbmNvZGVkU3RyaXAodGlmLCBUSUZGQ29tcHV0ZVN0cmlwKHRpZiwgeSwgc2FtcGxlKSwgY2hhbm5lbCwgbnJvdyAqIHNyY19saW5lKSA9PSAtMSkgewoJCQkJCQkJCS8vIGlnbm9yZSBlcnJvcnMgYXMgdGhleSBjYW4gYmUgZnJlcXVlbnQgYW5kIG5vdCByZWFsbHkgdmFsaWQgZXJyb3JzLCBlc3BlY2lhbGx5IHdpdGggZmF4IGltYWdlcwoJCQkJCQkJCWJUaHJvd01lc3NhZ2UgPSBUUlVFOwkJCQkJCQkJCgkJCQkJCQkJLyoKCQkJCQkJCQlmcmVlKGJ1Zik7CgkJCQkJCQkJdGhyb3cgRklfTVNHX0VSUk9SX1BBUlNJTkc7CgkJCQkJCQkJKi8KCQkJCQkJCX0gCgkJCQkJCQljaGFubmVsICs9IHN0cmlwc2l6ZTsKCQkJCQkJfQoKCQkJCQkJLy8gcmVjb25zdHJ1Y3QgdGhlIHBpY3R1cmUJCQkJCQkKCQkJCQkJZm9yIChpbnQgbCA9IDA7IGwgPCBucm93OyBsKyspIHsJCQkJCQkJCgkJCQkJCQljaGFubmVsID0gYnVmOwoJCQkJCQkJZm9yKHNhbXBsZSA9IDA7IHNhbXBsZSA8IHNhbXBsZXNwZXJwaXhlbDsgc2FtcGxlKyspIHsKCQkJCQkJCQlCWVRFICpzcmNfYml0cyA9IGNoYW5uZWwgKyBsICogc3JjX2xpbmU7CgkJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBiaXRzICsgc2FtcGxlICogYnl0ZXNwZXJzYW1wbGU7CgkJCQkJCQkJZm9yICh1aW50MzIgeCA9IDA7IHggPCAodWludDMyKShzcmNfbGluZSAvIGJ5dGVzcGVyc2FtcGxlKTsgeCsrKSB7CgkJCQkJCQkJCW1lbWNweShkc3RfYml0cywgc3JjX2JpdHMsIGJ5dGVzcGVyc2FtcGxlKTsKCQkJCQkJCQkJc3JjX2JpdHMgKz0gYnl0ZXNwZXJzYW1wbGU7CgkJCQkJCQkJCWRzdF9iaXRzICs9IGJ5dGVzcGVycGl4ZWw7CgkJCQkJCQkJfQoJCQkJCQkJCWNoYW5uZWwgKz0gc3RyaXBzaXplOwoJCQkJCQkJfQoJCQkJCQkJYml0cyAtPSBkc3RfcGl0Y2g7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWZyZWUoYnVmKTsKCgkJCQkJaWYoYlRocm93TWVzc2FnZSkgewoJCQkJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsICJXYXJuaW5nOiBwYXJzaW5nIGVycm9yLiBJbWFnZSBtYXkgYmUgaW5jb21wbGV0ZSBvciBjb250YWluIGludmFsaWQgZGF0YSAhIik7CgkJCQkJfQoJCQkJfQoKCQkJfSBlbHNlIGlmKGxvYWRNZXRob2QgPT0gTG9hZEFzVGlsZWQpIHsKCQkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCQkJLy8gVGlsZWQgaW1hZ2UgbG9hZGluZwoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQkJdWludDMyIHRpbGVXaWR0aCwgdGlsZUhlaWdodDsKCQkJCXVpbnQzMiBzcmNfbGluZSA9IDA7CgoJCQkJLy8gY3JlYXRlIGEgbmV3IERJQgoJCQkJZGliID0gQ3JlYXRlSW1hZ2VUeXBlKGltYWdlX3R5cGUsIHdpZHRoLCBoZWlnaHQsIGJpdHNwZXJzYW1wbGUsIHNhbXBsZXNwZXJwaXhlbCk7CgkJCQlpZiAoZGliID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCS8vIGZpbGwgaW4gdGhlIHJlc29sdXRpb24gKGVuZ2xpc2ggb3IgdW5pdmVyc2FsKQoKCQkJCVJlYWRSZXNvbHV0aW9uKHRpZiwgZGliKTsKCgkJCQkvLyBzZXQgdXAgdGhlIGNvbG9ybWFwIGJhc2VkIG9uIHBob3RvbWV0cmljCQoKCQkJCVJlYWRQYWxldHRlKHRpZiwgcGhvdG9tZXRyaWMsIGJpdHNwZXJzYW1wbGUsIGRpYik7CgoJCQkJLy8gZ2V0IHRoZSB0aWxlIGdlb21ldHJ5CgkJCQlpZighVElGRkdldEZpZWxkKHRpZiwgVElGRlRBR19USUxFV0lEVEgsICZ0aWxlV2lkdGgpIHx8ICFUSUZGR2V0RmllbGQodGlmLCBUSUZGVEFHX1RJTEVMRU5HVEgsICZ0aWxlSGVpZ2h0KSkgewoJCQkJCXRocm93ICJJbnZhbGlkIHRpbGVkIFRJRkYgaW1hZ2UiOwoJCQkJfQoKCQkJCS8vIGdldCB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gY29udGFpbiBhIHRpbGUKCQkJCXRzaXplX3QgdGlsZVNpemUgPSBUSUZGVGlsZVNpemUodGlmKTsKCgkJCQkvLyBhbGxvY2F0ZSB0aWxlIGJ1ZmZlcgoJCQkJQllURSAqdGlsZUJ1ZmZlciA9IChCWVRFKiltYWxsb2ModGlsZVNpemUgKiBzaXplb2YoQllURSkpOwoJCQkJaWYodGlsZUJ1ZmZlciA9PSBOVUxMKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoKCQkJCS8vIGNhbGN1bGF0ZSBzcmMgbGluZSBhbmQgZHN0IHBpdGNoCgkJCQlpbnQgZHN0X3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkJCQlpbnQgdGlsZVJvd1NpemUgPSBUSUZGVGlsZVJvd1NpemUodGlmKTsKCQkJCWludCBpbWFnZVJvd1NpemUgPSBUSUZGU2NhbmxpbmVTaXplKHRpZik7CgoKCQkJCS8vIEluIHRoZSB0aWZmIGZpbGUgdGhlIGxpbmVzIGFyZSBzYXZlIGZyb20gdXAgdG8gZG93biAKCQkJCS8vIEluIGEgRElCIHRoZSBsaW5lcyBtdXN0IGJlIHNhdmVkIGZyb20gZG93biB0byB1cAoKCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxKTsKCgkJCQkvLyByZWFkIHRoZSB0aWZmIGxpbmVzIGFuZCBzYXZlIHRoZW0gaW4gdGhlIERJQgoKCQkJCWlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX0NPTlRJRykgewoJCQkJCXVpbnQzMiB4LCB5LCByb3dTaXplOwoJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkgKz0gdGlsZUhlaWdodCkgewkJCQkJCQoJCQkJCQlpbnQzMiBucm93cyA9ICh5ICsgdGlsZUhlaWdodCA+IGhlaWdodCA/IGhlaWdodCAtIHkgOiB0aWxlSGVpZ2h0KTsJCQkJCQoKCQkJCQkJZm9yICh4ID0gMCwgcm93U2l6ZSA9IDA7IHggPCB3aWR0aDsgeCArPSB0aWxlV2lkdGgsIHJvd1NpemUgKz0gdGlsZVJvd1NpemUpIHsKCQkJCQkJCW1lbXNldCh0aWxlQnVmZmVyLCAwLCB0aWxlU2l6ZSk7CgoJCQkJCQkJLy8gcmVhZCBvbmUgdGlsZQoJCQkJCQkJaWYgKFRJRkZSZWFkVGlsZSh0aWYsIHRpbGVCdWZmZXIsIHgsIHksIDAsIDApIDwgMCkgewoJCQkJCQkJCWZyZWUodGlsZUJ1ZmZlcik7CgkJCQkJCQkJdGhyb3cgIkNvcnJ1cHRlZCB0aWxlZCBUSUZGIGZpbGUiOwoJCQkJCQkJfQoJCQkJCQkJLy8gY29udmVydCB0byBzdHJpcAoJCQkJCQkJaWYoeCArIHRpbGVXaWR0aCA+IHdpZHRoKSB7CgkJCQkJCQkJc3JjX2xpbmUgPSBpbWFnZVJvd1NpemUgLSByb3dTaXplOwoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQlzcmNfbGluZSA9IHRpbGVSb3dTaXplOwoJCQkJCQkJfQoJCQkJCQkJQllURSAqc3JjX2JpdHMgPSB0aWxlQnVmZmVyOwoJCQkJCQkJQllURSAqZHN0X2JpdHMgPSBiaXRzICsgcm93U2l6ZTsKCQkJCQkJCWZvcihpbnQgayA9IDA7IGsgPCBucm93czsgaysrKSB7CgkJCQkJCQkJbWVtY3B5KGRzdF9iaXRzLCBzcmNfYml0cywgc3JjX2xpbmUpOwoJCQkJCQkJCXNyY19iaXRzICs9IHRpbGVSb3dTaXplOwoJCQkJCQkJCWRzdF9iaXRzIC09IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJYml0cyAtPSBucm93cyAqIGRzdF9waXRjaDsKCQkJCQl9CgoJCQkJfQoJCQkJZWxzZSBpZihwbGFuYXJfY29uZmlnID09IFBMQU5BUkNPTkZJR19TRVBBUkFURSkgewoJCQkJCWZyZWUodGlsZUJ1ZmZlcik7CgkJCQkJdGhyb3cgIlNlcGFyYXRlZCB0aWxlZCBUSUZGIGltYWdlcyBhcmUgbm90IHN1cHBvcnRlZCI7IAoJCQkJfQoKCQkJCWZyZWUodGlsZUJ1ZmZlcik7CgoJCQl9IGVsc2UgaWYobG9hZE1ldGhvZCA9PSBMb2FkQXNSR0JGKSB7CgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkJCS8vIFJHQkYgbG9hZGluZwoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQkJZG91YmxlCXN0b25pdHM7CS8vIGlucHV0IGNvbnZlcnNpb24gdG8gbml0cwoJCQkJaWYgKCFUSUZGR2V0RmllbGQodGlmLCBUSUZGVEFHX1NUT05JVFMsICZzdG9uaXRzKSkgewoJCQkJCXN0b25pdHMgPSAxOwoJCQkJfQoJCQkJCgkJCQkvLyBjcmVhdGUgYSBuZXcgRElCCgkJCQlkaWIgPSBDcmVhdGVJbWFnZVR5cGUoaW1hZ2VfdHlwZSwgd2lkdGgsIGhlaWdodCwgYml0c3BlcnNhbXBsZSwgc2FtcGxlc3BlcnBpeGVsKTsKCQkJCWlmIChkaWIgPT0gTlVMTCkgewoJCQkJCXRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgkJCQl9CgoJCQkJLy8gZmlsbCBpbiB0aGUgcmVzb2x1dGlvbiAoZW5nbGlzaCBvciB1bml2ZXJzYWwpCgoJCQkJUmVhZFJlc29sdXRpb24odGlmLCBkaWIpOwoKCQkJCS8vIGNhbGN1bGF0ZSB0aGUgbGluZSArIHBpdGNoIChzZXBhcmF0ZSBmb3Igc2NyICYgZGVzdCkKCgkJCQl0c2l6ZV90IHNyY19saW5lID0gVElGRlNjYW5saW5lU2l6ZSh0aWYpOwoJCQkJaW50IGRzdF9waXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoKCQkJCS8vIEluIHRoZSB0aWZmIGZpbGUgdGhlIGxpbmVzIGFyZSBzYXZlIGZyb20gdXAgdG8gZG93biAKCQkJCS8vIEluIGEgRElCIHRoZSBsaW5lcyBtdXN0IGJlIHNhdmVkIGZyb20gZG93biB0byB1cAoKCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxKTsKCgkJCQkvLyByZWFkIHRoZSB0aWZmIGxpbmVzIGFuZCBzYXZlIHRoZW0gaW4gdGhlIERJQgoKCQkJCWlmKHBsYW5hcl9jb25maWcgPT0gUExBTkFSQ09ORklHX0NPTlRJRykgewoJCQkJCUJZVEUgKmJ1ZiA9IChCWVRFKiltYWxsb2MoVElGRlN0cmlwU2l6ZSh0aWYpICogc2l6ZW9mKEJZVEUpKTsKCQkJCQlpZihidWYgPT0gTlVMTCkgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCgkJCQkJZm9yICh1aW50MzIgeSA9IDA7IHkgPCBoZWlnaHQ7IHkgKz0gcm93c3BlcnN0cmlwKSB7CgkJCQkJCWludDMyIG5yb3cgPSAoeSArIHJvd3NwZXJzdHJpcCA+IGhlaWdodCA/IGhlaWdodCAtIHkgOiByb3dzcGVyc3RyaXApOwoKCQkJCQkJaWYgKFRJRkZSZWFkRW5jb2RlZFN0cmlwKHRpZiwgVElGRkNvbXB1dGVTdHJpcCh0aWYsIHksIDApLCBidWYsIG5yb3cgKiBzcmNfbGluZSkgPT0gLTEpIHsKCQkJCQkJCWZyZWUoYnVmKTsKCQkJCQkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCQkJCQl9IAoJCQkJCQkvLyBjb252ZXJ0IGZyb20gWFlaIHRvIFJHQgoJCQkJCQlmb3IgKGludCBsID0gMDsgbCA8IG5yb3c7IGwrKykgewkJCQkJCQoJCQkJCQkJdGlmZl9Db252ZXJ0TGluZVhZWlRvUkdCKGJpdHMsIGJ1ZiArIGwgKiBzcmNfbGluZSwgc3Rvbml0cywgd2lkdGgpOwoJCQkJCQkJYml0cyAtPSBkc3RfcGl0Y2g7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCWZyZWUoYnVmKTsKCQkJCX0KCQkJCWVsc2UgaWYocGxhbmFyX2NvbmZpZyA9PSBQTEFOQVJDT05GSUdfU0VQQVJBVEUpIHsKCQkJCQkvLyB0aGlzIGNhbm5vdCBoYXBwZW5kIGFjY29yZGluZyB0byB0aGUgTG9nTHV2IHNwZWNpZmljYXRpb24KCQkJCQl0aHJvdyAiVW5hYmxlIHRvIGhhbmRsZSBQTEFOQVJDT05GSUdfU0VQQVJBVEUgTG9nTHV2IGltYWdlcyI7CgkJCQl9CgoJCQl9IGVsc2UgewoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkJCQkvLyBVbmtub3duIG9yIHVuc3VwcG9ydGVkIGZvcm1hdAoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJCQkJdGhyb3cgRklfTVNHX0VSUk9SX1VOU1VQUE9SVEVEX0ZPUk1BVDsKCQkJfQoKCQkJLy8gY29weSBJQ0MgcHJvZmlsZSBkYXRhIChtdXN0IGJlIGRvbmUgYWZ0ZXIgRnJlZUltYWdlX0FsbG9jYXRlKQoKCQkJRnJlZUltYWdlX0NyZWF0ZUlDQ1Byb2ZpbGUoZGliLCBpY2NCdWYsIGljY1NpemUpOwkJCgkJCWlmIChwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19TRVBBUkFURUQgJiYgKChmbGFncyAmIFRJRkZfQ01ZSykgPT0gVElGRl9DTVlLKSkgewoJCQkJRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoZGliKS0+ZmxhZ3MgfD0gRklJQ0NfQ09MT1JfSVNfQ01ZSzsKCQkJfQkJCQoKCQkJLy8gY29weSBUSUZGIG1ldGFkYXRhIChtdXN0IGJlIGRvbmUgYWZ0ZXIgRnJlZUltYWdlX0FsbG9jYXRlKQoKCQkJUmVhZE1ldGFkYXRhKHRpZiwgZGliKTsKCgkJCXJldHVybiAoRklCSVRNQVAgKilkaWI7CgoJCX0gY2F0Y2ggKGNvbnN0IGNoYXIgKm1lc3NhZ2UpIHsJCQkKCQkJaWYoZGliKQlGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJCWlmKG1lc3NhZ2UpIEZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgbWVzc2FnZSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsJICAgCn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTYXZlKEZyZWVJbWFnZUlPICppbywgRklCSVRNQVAgKmRpYiwgZmlfaGFuZGxlIGhhbmRsZSwgaW50IHBhZ2UsIGludCBmbGFncywgdm9pZCAqZGF0YSkgewoJaWYgKChkaWIgIT0gTlVMTCkgJiYgKGhhbmRsZSAhPSBOVUxMKSAmJiAoZGF0YSAhPSBOVUxMKSkgewoJCWZpX1RJRkZJTyAqZmlvID0gKGZpX1RJRkZJTyopZGF0YTsKCQlUSUZGICpvdXQgPSBmaW8tPnRpZjsKCgkJaW50MzIgaGVpZ2h0OwoJCWludDMyIHdpZHRoOwoJCXVpbnQzMiByb3dzcGVyc3RyaXAgPSAodWludDMyKSAtMTsKCQl1aW50MTYgYml0c3BlcnBpeGVsOwoJCXVpbnQxNiBiaXRzcGVyc2FtcGxlOwoJCXVpbnQxNiBzYW1wbGVzcGVycGl4ZWw7CgkJdWludDE2IHBob3RvbWV0cmljOwoJCXVpbnQxNiBwaXRjaDsKCQlpbnQzMiB4LCB5OwoKCQlGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCgkJd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCQloZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgkJYml0c3BlcnBpeGVsID0gKHVpbnQxNilGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CgoJCUZJSUNDUFJPRklMRSAqaWNjUHJvZmlsZSA9IEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYik7CgoJCWlmKGltYWdlX3R5cGUgPT0gRklUX0JJVE1BUCkgewoJCQkvLyBzdGFuZGFyZCBpbWFnZTogMS0sIDQtLCA4LSwgMTYtLCAyNC0sIDMyLWJpdAoKCQkJc2FtcGxlc3BlcnBpeGVsID0gKChiaXRzcGVycGl4ZWwgPT0gMjQpID8gMyA6ICgoYml0c3BlcnBpeGVsID09IDMyKSA/IDQgOiAxKSk7CgkJCWJpdHNwZXJzYW1wbGUgPSBiaXRzcGVycGl4ZWwgLyBzYW1wbGVzcGVycGl4ZWw7CgkJCXBob3RvbWV0cmljCT0gR2V0UGhvdG9tZXRyaWMoZGliKTsKCgkJCWlmKChiaXRzcGVycGl4ZWwgPT0gOCkgJiYgRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQoZGliKSkgewoJCQkJLy8gOC1iaXQgdHJhbnNwYXJlbnQgcGljdHVyZSA6IGNvbnZlcnQgbGF0ZXIgdG8gOC1iaXQgKyA4LWJpdCBhbHBoYQoJCQkJc2FtcGxlc3BlcnBpeGVsID0gMjsKCQkJCWJpdHNwZXJzYW1wbGUgPSA4OwoJCQl9CgkJCWVsc2UgaWYoYml0c3BlcnBpeGVsID09IDMyKSB7CgkJCQkvLyAzMi1iaXQgaW1hZ2VzIDogY2hlY2sgZm9yIENNWUsgb3IgYWxwaGEgdHJhbnNwYXJlbmN5CgoJCQkJaWYoKCgoaWNjUHJvZmlsZS0+ZmxhZ3MgJiBGSUlDQ19DT0xPUl9JU19DTVlLKSA9PSBGSUlDQ19DT0xPUl9JU19DTVlLKSB8fCAoKGZsYWdzICYgVElGRl9DTVlLKSA9PSBUSUZGX0NNWUspKSkgewoJCQkJCS8vIENNWUsgc3VwcG9ydAoJCQkJCXBob3RvbWV0cmljID0gUEhPVE9NRVRSSUNfU0VQQVJBVEVEOwoJCQkJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfSU5LU0VULCBJTktTRVRfQ01ZSyk7CgkJCQkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19OVU1CRVJPRklOS1MsIDQpOwoJCQkJfQoJCQkJZWxzZSBpZihwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19SR0IpIHsKCQkJCQkvLyB0cmFuc3BhcmVuY3kgbWFzayBzdXBwb3J0CgkJCQkJdWludDE2IHNhbXBsZWluZm9bMV07IAoJCQkJCS8vIHVuYXNzb2NpYXRlZCBhbHBoYSBkYXRhIGlzIHRyYW5zcGFyZW5jeSBpbmZvcm1hdGlvbgoJCQkJCXNhbXBsZWluZm9bMF0gPSBFWFRSQVNBTVBMRV9VTkFTU0FMUEhBOwoJCQkJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfRVhUUkFTQU1QTEVTLCAxLCBzYW1wbGVpbmZvKTsKCQkJCX0KCQkJfQoJCX0gZWxzZSBpZihpbWFnZV90eXBlID09IEZJVF9SR0IxNikgewoJCQkvLyA0OC1iaXQgUkdCCgoJCQlzYW1wbGVzcGVycGl4ZWwgPSAzOwoJCQliaXRzcGVyc2FtcGxlID0gYml0c3BlcnBpeGVsIC8gc2FtcGxlc3BlcnBpeGVsOwoJCQlwaG90b21ldHJpYwk9IFBIT1RPTUVUUklDX1JHQjsKCQl9IGVsc2UgaWYoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSB7CgkJCS8vIDY0LWJpdCBSR0JBCgoJCQlzYW1wbGVzcGVycGl4ZWwgPSA0OwoJCQliaXRzcGVyc2FtcGxlID0gYml0c3BlcnBpeGVsIC8gc2FtcGxlc3BlcnBpeGVsOwoJCQlwaG90b21ldHJpYwk9IFBIT1RPTUVUUklDX1JHQjsKCQkJLy8gdHJhbnNwYXJlbmN5IG1hc2sgc3VwcG9ydAoJCQl1aW50MTYgc2FtcGxlaW5mb1sxXTsgCgkJCS8vIHVuYXNzb2NpYXRlZCBhbHBoYSBkYXRhIGlzIHRyYW5zcGFyZW5jeSBpbmZvcm1hdGlvbgoJCQlzYW1wbGVpbmZvWzBdID0gRVhUUkFTQU1QTEVfVU5BU1NBTFBIQTsKCQkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19FWFRSQVNBTVBMRVMsIDEsIHNhbXBsZWluZm8pOwoJCX0gZWxzZSBpZihpbWFnZV90eXBlID09IEZJVF9SR0JGKSB7CgkJCS8vIDk2LWJpdCBSR0JGID0+IHN0b3JlIHdpdGggYSBMb2dMdXYgZW5jb2RpbmcKCgkJCXNhbXBsZXNwZXJwaXhlbCA9IDM7CgkJCWJpdHNwZXJzYW1wbGUgPSBiaXRzcGVycGl4ZWwgLyBzYW1wbGVzcGVycGl4ZWw7CgkJCXBob3RvbWV0cmljCT0gUEhPVE9NRVRSSUNfTE9HTFVWOwoJCQkvLyB0aGUgbGlicmFyeSBjb252ZXJ0cyB0byBhbmQgZnJvbSBmbG9hdGluZy1wb2ludCBYWVogQ0lFIHZhbHVlcwoJCQlUSUZGU2V0RmllbGQob3V0LCBUSUZGVEFHX1NHSUxPR0RBVEFGTVQsIFNHSUxPR0RBVEFGTVRfRkxPQVQpOwoJCQkvLyBUSUZGU2V0RmllbGQob3V0LCBUSUZGVEFHX1NUT05JVFMsIDEuMCk7ICAgLy8gYXNzdW1lIHVua25vd24gCgkJfSBlbHNlIHsKCQkJLy8gc3BlY2lhbCBpbWFnZSB0eXBlIChpbnQsIGxvbmcsIGRvdWJsZSwgLi4uKQoKCQkJc2FtcGxlc3BlcnBpeGVsID0gMTsKCQkJYml0c3BlcnNhbXBsZSA9IGJpdHNwZXJwaXhlbDsKCQkJcGhvdG9tZXRyaWMJPSBQSE9UT01FVFJJQ19NSU5JU0JMQUNLOwoJCX0KCgkJLy8gc2V0IGltYWdlIGRhdGEgdHlwZQoKCQlXcml0ZUltYWdlVHlwZShvdXQsIGltYWdlX3R5cGUpOwoJCQoJCS8vIHdyaXRlIHBvc3NpYmxlIElDQyBwcm9maWxlCgoJCWlmIChpY2NQcm9maWxlLT5zaXplICYmIGljY1Byb2ZpbGUtPmRhdGEpIHsKCQkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19JQ0NQUk9GSUxFLCBpY2NQcm9maWxlLT5zaXplLCBpY2NQcm9maWxlLT5kYXRhKTsKCQl9CgoJCS8vIGhhbmRsZSBzdGFuZGFyZCB3aWR0aC9oZWlnaHQvYnBwIHN0dWZmCgoJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfSU1BR0VXSURUSCwgd2lkdGgpOwoJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfSU1BR0VMRU5HVEgsIGhlaWdodCk7CgkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19TQU1QTEVTUEVSUElYRUwsIHNhbXBsZXNwZXJwaXhlbCk7CgkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19CSVRTUEVSU0FNUExFLCBiaXRzcGVyc2FtcGxlKTsKCQlUSUZGU2V0RmllbGQob3V0LCBUSUZGVEFHX1BIT1RPTUVUUklDLCBwaG90b21ldHJpYyk7CgkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19QTEFOQVJDT05GSUcsIFBMQU5BUkNPTkZJR19DT05USUcpOwkvLyBzaW5nbGUgaW1hZ2UgcGxhbmUgCgkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19PUklFTlRBVElPTiwgT1JJRU5UQVRJT05fVE9QTEVGVCk7CgkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19ST1dTUEVSU1RSSVAsIFRJRkZEZWZhdWx0U3RyaXBTaXplKG91dCwgcm93c3BlcnN0cmlwKSk7CgoJCS8vIGhhbmRsZSBtZXRyaWNzCgoJCVdyaXRlUmVzb2x1dGlvbihvdXQsIGRpYik7CgoJCS8vIG11bHRpLXBhZ2luZwoKCQlpZiAocGFnZSA+PSAwKSB7CgkJCWNoYXIgcGFnZV9udW1iZXJbMjBdOwoJCQlzcHJpbnRmKHBhZ2VfbnVtYmVyLCAiUGFnZSAlZCIsIHBhZ2UpOwoKCQkJVElGRlNldEZpZWxkKG91dCwgVElGRlRBR19TVUJGSUxFVFlQRSwgRklMRVRZUEVfUEFHRSk7CgkJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfUEFHRU5VTUJFUiwgcGFnZSk7CgkJCVRJRkZTZXRGaWVsZChvdXQsIFRJRkZUQUdfUEFHRU5BTUUsIHBhZ2VfbnVtYmVyKTsKCQl9IGVsc2UgewoJCQlUSUZGU2V0RmllbGQob3V0LCBUSUZGVEFHX1NVQkZJTEVUWVBFLCAwKTsKCQl9CgoJCS8vIHBhbGV0dGVzIChpbWFnZSBjb2xvcm1hcHMgYXJlIGF1dG9tYXRpY2FsbHkgc2NhbGVkIHRvIDE2LWJpdHMpCgoJCWlmIChwaG90b21ldHJpYyA9PSBQSE9UT01FVFJJQ19QQUxFVFRFKSB7CgkJCXVpbnQxNiAqciwgKmcsICpiOwoJCQl1aW50MTYgbkNvbG9ycyA9ICh1aW50MTYpRnJlZUltYWdlX0dldENvbG9yc1VzZWQoZGliKTsKCQkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCgkJCXIgPSAodWludDE2ICopIF9USUZGbWFsbG9jKHNpemVvZih1aW50MTYpICogMyAqIG5Db2xvcnMpOwoJCQlpZihyID09IE5VTEwpIHRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgkJCWcgPSByICsgbkNvbG9yczsKCQkJYiA9IGcgKyBuQ29sb3JzOwoKCQkJZm9yIChpbnQgaSA9IG5Db2xvcnMgLSAxOyBpID49IDA7IGktLSkgewoJCQkJcltpXSA9IFNDQUxFKCh1aW50MTYpcGFsW2ldLnJnYlJlZCk7CgkJCQlnW2ldID0gU0NBTEUoKHVpbnQxNilwYWxbaV0ucmdiR3JlZW4pOwoJCQkJYltpXSA9IFNDQUxFKCh1aW50MTYpcGFsW2ldLnJnYkJsdWUpOwoJCQl9CgoJCQlUSUZGU2V0RmllbGQob3V0LCBUSUZGVEFHX0NPTE9STUFQLCByLCBnLCBiKTsKCgkJCV9USUZGZnJlZShyKTsKCQl9CgoJCS8vIGNvbXByZXNzaW9uCgoJCVdyaXRlQ29tcHJlc3Npb24ob3V0LCBiaXRzcGVyc2FtcGxlLCBzYW1wbGVzcGVycGl4ZWwsIHBob3RvbWV0cmljLCBmbGFncyk7CgoJCS8vIG1ldGFkYXRhCgoJCVdyaXRlTWV0YWRhdGEob3V0LCBkaWIpOwoKCgkJLy8gcmVhZCB0aGUgRElCIGxpbmVzIGZyb20gYm90dG9tIHRvIHRvcAoJCS8vIGFuZCBzYXZlIHRoZW0gaW4gdGhlIFRJRgoJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkKCQlwaXRjaCA9ICh1aW50MTYpRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgoJCWlmKGltYWdlX3R5cGUgPT0gRklUX0JJVE1BUCkgewoJCQkvLyBzdGFuZGFyZCBiaXRtYXAgdHlwZQoJCQoJCQlzd2l0Y2goYml0c3BlcnBpeGVsKSB7CgkJCQljYXNlIDEgOgoJCQkJY2FzZSA0IDoKCQkJCWNhc2UgOCA6CgkJCQl7CgkJCQkJaWYoKGJpdHNwZXJwaXhlbCA9PSA4KSAmJiBGcmVlSW1hZ2VfSXNUcmFuc3BhcmVudChkaWIpKSB7CgkJCQkJCS8vIDgtYml0IHRyYW5zcGFyZW50IHBpY3R1cmUgOiBjb252ZXJ0IHRvIDgtYml0ICsgOC1iaXQgYWxwaGEKCgkJCQkJCS8vIGdldCB0aGUgdHJhbnNwYXJlbmN5IHRhYmxlCgkJCQkJCUJZVEUgKnRybnMgPSBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZGliKTsKCgkJCQkJCUJZVEUgKmJ1ZmZlciA9IChCWVRFICopbWFsbG9jKDIgKiB3aWR0aCAqIHNpemVvZihCWVRFKSk7CgkJCQkJCWlmKGJ1ZmZlciA9PSBOVUxMKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoKCQkJCQkJZm9yICh5ID0gaGVpZ2h0IC0gMTsgeSA+PSAwOyB5LS0pIHsKCQkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCgkJCQkJCQlCWVRFICpwID0gYml0cywgKmIgPSBidWZmZXI7CgoJCQkJCQkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCS8vIGNvcHkgdGhlIDgtYml0IGxheWVyCgkJCQkJCQkJYlswXSA9ICpwOwoJCQkJCQkJCS8vIGNvbnZlcnQgdGhlIHRybnMgdGFibGUgdG8gYSA4LWJpdCBhbHBoYSBsYXllcgoJCQkJCQkJCWJbMV0gPSB0cm5zWyBiWzBdIF07CgoJCQkJCQkJCXArKzsKCQkJCQkJCQliICs9IHNhbXBsZXNwZXJwaXhlbDsKCQkJCQkJCX0KCgkJCQkJCQkvLyB3cml0ZSB0aGUgc2NhbmxpbmUgdG8gZGlzYwoKCQkJCQkJCVRJRkZXcml0ZVNjYW5saW5lKG91dCwgYnVmZmVyLCBoZWlnaHQgLSB5IC0gMSwgMCk7CgkJCQkJCX0KCgkJCQkJCWZyZWUoYnVmZmVyKTsKCQkJCQl9CgkJCQkJZWxzZSB7CgkJCQkJCS8vIG90aGVyIGNhc2VzCgkJCQkJCUJZVEUgKmJ1ZmZlciA9IChCWVRFICopbWFsbG9jKHBpdGNoICogc2l6ZW9mKEJZVEUpKTsKCQkJCQkJaWYoYnVmZmVyID09IE5VTEwpIHRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgkJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJLy8gZ2V0IGEgY29weSBvZiB0aGUgc2NhbmxpbmUKCQkJCQkJCW1lbWNweShidWZmZXIsIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIHkgLSAxKSwgcGl0Y2gpOwoJCQkJCQkJLy8gd3JpdGUgdGhlIHNjYW5saW5lIHRvIGRpc2MKCQkJCQkJCVRJRkZXcml0ZVNjYW5saW5lKG91dCwgYnVmZmVyLCB5LCAwKTsKCQkJCQkJfQoJCQkJCQlmcmVlKGJ1ZmZlcik7CgkJCQkJfQoKCQkJCQlicmVhazsKCQkJCX0JCQkJCgoJCQkJY2FzZSAyNDoKCQkJCWNhc2UgMzI6CgkJCQl7CgkJCQkJQllURSAqYnVmZmVyID0gKEJZVEUgKiltYWxsb2MocGl0Y2ggKiBzaXplb2YoQllURSkpOwoJCQkJCWlmKGJ1ZmZlciA9PSBOVUxMKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoKCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJLy8gZ2V0IGEgY29weSBvZiB0aGUgc2NhbmxpbmUKCgkJCQkJCW1lbWNweShidWZmZXIsIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIHkgLSAxKSwgcGl0Y2gpOwoKI2lmIEZSRUVJTUFHRV9DT0xPUk9SREVSID09IEZSRUVJTUFHRV9DT0xPUk9SREVSX0JHUgoJCQkJCQlpZiAocGhvdG9tZXRyaWMgIT0gUEhPVE9NRVRSSUNfU0VQQVJBVEVEKSB7CgkJCQkJCQkvLyBUSUZGcyBzdG9yZSBjb2xvciBkYXRhIFJHQihBKSBpbnN0ZWFkIG9mIEJHUihBKQoJCQoJCQkJCQkJQllURSAqcEJ1ZiA9IGJ1ZmZlcjsKCQkKCQkJCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJSU5QTEFDRVNXQVAocEJ1ZlswXSwgcEJ1ZlsyXSk7CgkJCQkJCQkJcEJ1ZiArPSBzYW1wbGVzcGVycGl4ZWw7CgkJCQkJCQl9CgkJCQkJCX0KI2VuZGlmCgkJCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZSB0byBkaXNjCgoJCQkJCQlUSUZGV3JpdGVTY2FubGluZShvdXQsIGJ1ZmZlciwgeSwgMCk7CgkJCQkJfQoKCQkJCQlmcmVlKGJ1ZmZlcik7CgoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCX0gZWxzZSBpZihpbWFnZV90eXBlID09IEZJVF9SR0JGKSB7CgkJCS8vIFJHQkYgaW1hZ2UgPT4gc3RvcmUgYXMgWFlaIHVzaW5nIGEgTG9nTHV2IGVuY29kaW5nCgoJCQlCWVRFICpidWZmZXIgPSAoQllURSAqKW1hbGxvYyhwaXRjaCAqIHNpemVvZihCWVRFKSk7CgkJCWlmKGJ1ZmZlciA9PSBOVUxMKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoKCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkvLyBnZXQgYSBjb3B5IG9mIHRoZSBzY2FubGluZSBhbmQgY29udmVydCBmcm9tIFJHQiB0byBYWVoKCQkJCXRpZmZfQ29udmVydExpbmVSR0JUb1hZWihidWZmZXIsIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIHkgLSAxKSwgd2lkdGgpOwoJCQkJLy8gd3JpdGUgdGhlIHNjYW5saW5lIHRvIGRpc2MKCQkJCVRJRkZXcml0ZVNjYW5saW5lKG91dCwgYnVmZmVyLCB5LCAwKTsKCQkJfQoJCQlmcmVlKGJ1ZmZlcik7CgkJfSBlbHNlIHsKCQkJLy8gc3BlY2lhbCBiaXRtYXAgdHlwZSAoaW50LCBsb25nLCBkb3VibGUsIGV0Yy4pCgoJCQlzd2l0Y2goYml0c3BlcnBpeGVsKSB7CgkJCQljYXNlIDE2OgoJCQkJY2FzZSAzMjoKCQkJCWNhc2UgNDg6CgkJCQljYXNlIDY0OgoJCQkJY2FzZSAxMjg6CgkJCQl7CgkJCQkJQllURSAqYnVmZmVyID0gKEJZVEUgKiltYWxsb2MocGl0Y2ggKiBzaXplb2YoQllURSkpOwoJCQkJCWlmKGJ1ZmZlciA9PSBOVUxMKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoKCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJLy8gZ2V0IGEgY29weSBvZiB0aGUgc2NhbmxpbmUKCQkJCQkJbWVtY3B5KGJ1ZmZlciwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0geSAtIDEpLCBwaXRjaCk7CgkJCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZSB0byBkaXNjCgkJCQkJCVRJRkZXcml0ZVNjYW5saW5lKG91dCwgYnVmZmVyLCB5LCAwKTsKCQkJCQl9CgkJCQkJZnJlZShidWZmZXIpOwoJCQkJfQkKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQkvLyB3cml0ZSBvdXQgdGhlIGRpcmVjdG9yeSB0YWcgaWYgd2Ugd3JvdGUgYSBwYWdlIG90aGVyIHRoYW4gLTEKCgkJaWYgKHBhZ2UgPj0gMCkKCQkJVElGRldyaXRlRGlyZWN0b3J5KG91dCk7CQkKCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vICAgSW5pdAovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgp2b2lkIERMTF9DQUxMQ09OVgpJbml0VElGRihQbHVnaW4gKnBsdWdpbiwgaW50IGZvcm1hdF9pZCkgewoJc19mb3JtYXRfaWQgPSBmb3JtYXRfaWQ7CgoJcGx1Z2luLT5mb3JtYXRfcHJvYyA9IEZvcm1hdDsKCXBsdWdpbi0+ZGVzY3JpcHRpb25fcHJvYyA9IERlc2NyaXB0aW9uOwoJcGx1Z2luLT5leHRlbnNpb25fcHJvYyA9IEV4dGVuc2lvbjsKCXBsdWdpbi0+cmVnZXhwcl9wcm9jID0gUmVnRXhwcjsKCXBsdWdpbi0+b3Blbl9wcm9jID0gT3BlbjsKCXBsdWdpbi0+Y2xvc2VfcHJvYyA9IENsb3NlOwoJcGx1Z2luLT5wYWdlY291bnRfcHJvYyA9IFBhZ2VDb3VudDsKCXBsdWdpbi0+cGFnZWNhcGFiaWxpdHlfcHJvYyA9IE5VTEw7CglwbHVnaW4tPmxvYWRfcHJvYyA9IExvYWQ7CglwbHVnaW4tPnNhdmVfcHJvYyA9IFNhdmU7CglwbHVnaW4tPnZhbGlkYXRlX3Byb2MgPSBWYWxpZGF0ZTsKCXBsdWdpbi0+bWltZV9wcm9jID0gTWltZVR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF9icHBfcHJvYyA9IFN1cHBvcnRzRXhwb3J0RGVwdGg7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF90eXBlX3Byb2MgPSBTdXBwb3J0c0V4cG9ydFR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2ljY19wcm9maWxlc19wcm9jID0gU3VwcG9ydHNJQ0NQcm9maWxlczsKfQo=