LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5udC5oIgojaW5jbHVkZSAid2luY29uLmgiCgojaW5jbHVkZSAibXNkb3MuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zdm0uaCIKI2luY2x1ZGUgInN0YWNrZnJhbWUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIm1zdmNydC9leGNwdC5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoaW50KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwoKV09SRCBET1NWTV9wc3AgPSAwOwpXT1JEIERPU1ZNX3JldHZhbCA9IDA7CmNvbnN0IHN0cnVjdCBEUE1JX3NlZ21lbnRzICpET1NWTV9kcG1pX3NlZ21lbnRzID0gTlVMTDsKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpZmRlZiBIQVZFX1NZU19WTTg2X0gKIyBpbmNsdWRlIDxzeXMvdm04Ni5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2RlZmluZSBJRl9DTFIoY3R4KSAgICAgKChjdHgpLT5FRmxhZ3MgJj0gflZJRl9NQVNLKQojZGVmaW5lIElGX1NFVChjdHgpICAgICAoKGN0eCktPkVGbGFncyB8PSBWSUZfTUFTSykKI2RlZmluZSBJRl9FTkFCTEVEKGN0eCkgKChjdHgpLT5FRmxhZ3MgJiBWSUZfTUFTSykKI2RlZmluZSBTRVRfUEVORChjdHgpICAgKChjdHgpLT5FRmxhZ3MgfD0gVklQX01BU0spCiNkZWZpbmUgQ0xSX1BFTkQoY3R4KSAgICgoY3R4KS0+RUZsYWdzICY9IH5WSVBfTUFTSykKI2RlZmluZSBJU19QRU5EKGN0eCkgICAgKChjdHgpLT5FRmxhZ3MgJiBWSVBfTUFTSykKCiN1bmRlZiBUUllfUElDUkVUVVJOCgp0eXBlZGVmIHN0cnVjdCBfRE9TRVZFTlQgewogIGludCBpcnEscHJpb3JpdHk7CiAgRE9TUkVMQVkgcmVsYXk7CiAgdm9pZCAqZGF0YTsKICBzdHJ1Y3QgX0RPU0VWRU5UICpuZXh0Owp9IERPU0VWRU5ULCAqTFBET1NFVkVOVDsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHFjcml0ID0gQ1JJVElDQUxfU0VDVElPTl9JTklUKCJET1NWTSIpOwpzdGF0aWMgc3RydWN0IF9ET1NFVkVOVCAqcGVuZGluZ19ldmVudCwgKmN1cnJlbnRfZXZlbnQ7CnN0YXRpYyBpbnQgc2lnX3NlbnQ7CnN0YXRpYyBIQU5ETEUgZXZlbnRfbm90aWZpZXI7CnN0YXRpYyBDT05URVhUODYgKmN1cnJlbnRfY29udGV4dDsKCnN0YXRpYyBpbnQgRE9TVk1fU2ltdWxhdGVJbnQoIGludCB2ZWN0LCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgaW53aW5lICkKewogIEZBUlBST0MxNiBoYW5kbGVyPURPU1ZNX0dldFJNSGFuZGxlcih2ZWN0KTsKCiAgLyogY2hlY2sgZm9yIG91ciByZWFsLW1vZGUgaG9va3MgKi8KICBpZiAodmVjdD09MHgzMSkgewogICAgaWYgKGNvbnRleHQtPlNlZ0NzPT1ET1NWTV9kcG1pX3NlZ21lbnRzLT53cmFwX3NlZykgewogICAgICAvKiBleGl0IGZyb20gcmVhbC1tb2RlIHdyYXBwZXIgKi8KICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgLyogd2UgY291bGQgcHJvYmFibHkgbW92ZSBzb21lIG90aGVyIGRvZGd5IHN0dWZmIGhlcmUgdG9vIGZyb20gZHBtaS5jICovCiAgfQogIC8qIGNoZWNrIGlmIHRoZSBjYWxsIGlzIGZyb20gb3VyIGZha2UgQklPUyBpbnRlcnJ1cHQgc3R1YnMgKi8KICBpZiAoKGNvbnRleHQtPlNlZ0NzPT0weGYwMDApICYmICFpbndpbmUpIHsKICAgIGlmICh2ZWN0ICE9IChjb250ZXh0LT5FaXAvNCkpIHsKICAgICAgVFJBQ0UoInNvbWV0aGluZyBmaXNoeSBnb2luZyBvbiBoZXJlIChpbnRlcnJ1cHQgc3R1YiBpcyAlMDJseClcbiIsIGNvbnRleHQtPkVpcC80KTsKICAgIH0KICAgIFRSQUNFKCJidWlsdGluIGludGVycnVwdCAlMDJ4IGhhcyBiZWVuIGJyYW5jaGVkIHRvXG4iLCB2ZWN0KTsKICAgIERPU1ZNX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsIGNvbnRleHQpOwogIH0KICAvKiBjaGVjayBpZiB0aGUgY2FsbCBnb2VzIHRvIGFuIHVuaG9va2VkIGludGVycnVwdCAqLwogIGVsc2UgaWYgKFNFTEVDVE9ST0YoaGFuZGxlcik9PTB4ZjAwMCkgewogICAgLyogaWYgc28sIGNhbGwgaXQgZGlyZWN0bHkgKi8KICAgIFRSQUNFKCJidWlsdGluIGludGVycnVwdCAlMDJ4IGhhcyBiZWVuIGludm9rZWQgKHRocm91Z2ggdmVjdG9yICUwMngpXG4iLCBPRkZTRVRPRihoYW5kbGVyKS80LCB2ZWN0KTsKICAgIERPU1ZNX1JlYWxNb2RlSW50ZXJydXB0KE9GRlNFVE9GKGhhbmRsZXIpLzQsIGNvbnRleHQpOwogIH0KICAvKiB0aGUgaW50ZXJydXB0IGlzIGhvb2tlZCwgc2ltdWxhdGUgaW50ZXJydXB0IGluIERPUyBzcGFjZSAqLwogIGVsc2UgewogICAgV09SRCpzdGFjaz0gUFRSX1JFQUxfVE9fTElOKCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwICk7CiAgICBXT1JEIGZsYWc9TE9XT1JEKGNvbnRleHQtPkVGbGFncyk7CgogICAgVFJBQ0VfKGludCkoImludm9raW5nIGhvb2tlZCBpbnRlcnJ1cHQgJTAyeCBhdCAlMDR4OiUwNHhcbiIsIHZlY3QsCgkJU0VMRUNUT1JPRihoYW5kbGVyKSwgT0ZGU0VUT0YoaGFuZGxlcikpOwogICAgaWYgKElGX0VOQUJMRUQoY29udGV4dCkpIGZsYWd8PUlGX01BU0s7CiAgICBlbHNlIGZsYWcmPX5JRl9NQVNLOwoKICAgICooLS1zdGFjayk9ZmxhZzsKICAgICooLS1zdGFjayk9Y29udGV4dC0+U2VnQ3M7CiAgICAqKC0tc3RhY2spPUxPV09SRChjb250ZXh0LT5FaXApOwogICAgY29udGV4dC0+RXNwLT02OwogICAgY29udGV4dC0+U2VnQ3M9U0VMRUNUT1JPRihoYW5kbGVyKTsKICAgIGNvbnRleHQtPkVpcD1PRkZTRVRPRihoYW5kbGVyKTsKICAgIElGX0NMUihjb250ZXh0KTsKICB9CiAgcmV0dXJuIDA7Cn0KCiNkZWZpbmUgU0hPVUxEX1BFTkQoeCkgXAogICh4ICYmICgoIWN1cnJlbnRfZXZlbnQpIHx8ICh4LT5wcmlvcml0eSA8IGN1cnJlbnRfZXZlbnQtPnByaW9yaXR5KSkpCgpzdGF0aWMgdm9pZCBET1NWTV9TZW5kUXVldWVkRXZlbnQoQ09OVEVYVDg2ICpjb250ZXh0KQp7CiAgTFBET1NFVkVOVCBldmVudCA9IHBlbmRpbmdfZXZlbnQ7CgogIGlmIChTSE9VTERfUEVORChldmVudCkpIHsKICAgIC8qIHJlbW92ZSBmcm9tICJwZW5kaW5nIiBsaXN0ICovCiAgICBwZW5kaW5nX2V2ZW50ID0gZXZlbnQtPm5leHQ7CiAgICAvKiBwcm9jZXNzIGV2ZW50ICovCiAgICBpZiAoZXZlbnQtPmlycT49MCkgewogICAgICAvKiBpdCdzIGFuIElSUSwgbW92ZSBpdCB0byAiY3VycmVudCIgbGlzdCAqLwogICAgICBldmVudC0+bmV4dCA9IGN1cnJlbnRfZXZlbnQ7CiAgICAgIGN1cnJlbnRfZXZlbnQgPSBldmVudDsKICAgICAgVFJBQ0UoImRpc3BhdGNoaW5nIElSUSAlZFxuIixldmVudC0+aXJxKTsKICAgICAgLyogbm90ZSB0aGF0IGlmIERPU1ZNX1NpbXVsYXRlSW50IGNhbGxzIGFuIGludGVybmFsIGludGVycnVwdCBkaXJlY3RseSwKICAgICAgICogY3VycmVudF9ldmVudCBtaWdodCBiZSBjbGVhcmVkIChhbmQgZXZlbnQgZnJlZWQpIGluIHRoaXMgdmVyeSBjYWxsISAqLwogICAgICBET1NWTV9TaW11bGF0ZUludCgoZXZlbnQtPmlycTw4KT8oZXZlbnQtPmlycSs4KTooZXZlbnQtPmlycS04KzB4NzApLGNvbnRleHQsVFJVRSk7CiAgICB9IGVsc2UgewogICAgICAvKiBjYWxsYmFjayBldmVudCAqLwogICAgICBUUkFDRSgiZGlzcGF0Y2hpbmcgY2FsbGJhY2sgZXZlbnRcbiIpOwogICAgICAoKmV2ZW50LT5yZWxheSkoY29udGV4dCxldmVudC0+ZGF0YSk7CiAgICAgIGZyZWUoZXZlbnQpOwogICAgfQogIH0KICBpZiAoIVNIT1VMRF9QRU5EKHBlbmRpbmdfZXZlbnQpKSB7CiAgICBUUkFDRSgiY2xlYXJpbmcgUGVuZGluZyBmbGFnXG4iKTsKICAgIENMUl9QRU5EKGNvbnRleHQpOwogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhDT05URVhUODYgKmNvbnRleHQpCnsKICAvKiB3ZSB3aWxsIHNlbmQgYWxsIHF1ZXVlZCBldmVudHMgYXMgbG9uZyBhcyBpbnRlcnJ1cHRzIGFyZSBlbmFibGVkLAogICAqIGJ1dCBJUlEgZXZlbnRzIHdpbGwgZGlzYWJsZSBpbnRlcnJ1cHRzIGFnYWluICovCiAgd2hpbGUgKElTX1BFTkQoY29udGV4dCkgJiYgSUZfRU5BQkxFRChjb250ZXh0KSkKICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudChjb250ZXh0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlRdWV1ZUV2ZW50IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9RdWV1ZUV2ZW50KCBJTlQgaXJxLCBJTlQgcHJpb3JpdHksIERPU1JFTEFZIHJlbGF5LCBMUFZPSUQgZGF0YSkKewogIExQRE9TRVZFTlQgZXZlbnQsIGN1ciwgcHJldjsKCiAgaWYgKGN1cnJlbnRfY29udGV4dCkgewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIGV2ZW50ID0gbWFsbG9jKHNpemVvZihET1NFVkVOVCkpOwogICAgaWYgKCFldmVudCkgewogICAgICBFUlIoIm91dCBvZiBtZW1vcnkgYWxsb2NhdGluZyBldmVudCBlbnRyeVxuIik7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGV2ZW50LT5pcnEgPSBpcnE7IGV2ZW50LT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgZXZlbnQtPnJlbGF5ID0gcmVsYXk7IGV2ZW50LT5kYXRhID0gZGF0YTsKCiAgICAvKiBpbnNlcnQgZXZlbnQgaW50byBsaW5rZWQgbGlzdCwgaW4gb3JkZXIgKmFmdGVyKgogICAgICogYWxsIGVhcmxpZXIgZXZlbnRzIG9mIGhpZ2hlciBvciBlcXVhbCBwcmlvcml0eSAqLwogICAgY3VyID0gcGVuZGluZ19ldmVudDsgcHJldiA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICYmIGN1ci0+cHJpb3JpdHk8PXByaW9yaXR5KSB7CiAgICAgIHByZXYgPSBjdXI7CiAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIGV2ZW50LT5uZXh0ID0gY3VyOwogICAgaWYgKHByZXYpIHByZXYtPm5leHQgPSBldmVudDsKICAgIGVsc2UgcGVuZGluZ19ldmVudCA9IGV2ZW50OwoKICAgIC8qIGFsZXJ0IHRoZSB2bTg2IGFib3V0IHRoZSBuZXcgZXZlbnQgKi8KICAgIGlmICghc2lnX3NlbnQpIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQsIHNpZ25hbGxpbmcgKHRpbWU9JWxkKVxuIiwgR2V0VGlja0NvdW50KCkpOwogICAgICBraWxsKGRvc3ZtX3BpZCxTSUdVU1IyKTsKICAgICAgc2lnX3NlbnQrKzsKICAgIH0gZWxzZSB7CiAgICAgIFRSQUNFKCJuZXcgZXZlbnQgcXVldWVkICh0aW1lPSVsZClcbiIsIEdldFRpY2tDb3VudCgpKTsKICAgIH0KCiAgICAvKiBXYWtlIHVwIERPU1ZNX1dhaXQgc28gdGhhdCBpdCBjYW4gc2VydmUgcGVuZGluZyBldmVudHMuICovCiAgICBTZXRFdmVudChldmVudF9ub3RpZmllcik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICB9IGVsc2UgewogICAgLyogRE9TIHN1YnN5c3RlbSBub3QgcnVubmluZyAqLwogICAgLyogKHRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB3ZSdyZSBydW5uaW5nIGEgd2luMTYgYXBwCiAgICAgKiAgd2hpY2ggdXNlcyBEUE1JIHRvIHRodW5rIGRvd24gdG8gRE9TIHNlcnZpY2VzKSAqLwogICAgaWYgKGlycTwwKSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgICBDT05URVhUODYgY29udGV4dDsKICAgICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzQ29uc29sZSh2b2lkKQp7CiAgSU5QVVRfUkVDT1JEIG1zZzsKICBEV09SRCByZXM7CiAgQllURSBzY2FuOwoKICBpZiAoUmVhZENvbnNvbGVJbnB1dEEoR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpLCZtc2csMSwmcmVzKSkgewogICAgc3dpdGNoIChtc2cuRXZlbnRUeXBlKSB7CiAgICBjYXNlIEtFWV9FVkVOVDoKICAgICAgc2NhbiA9IG1zZy5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlOwogICAgICBpZiAoIW1zZy5FdmVudC5LZXlFdmVudC5iS2V5RG93bikgc2NhbiB8PSAweDgwOwoKICAgICAgLyogY2hlY2sgd2hldGhlciBleHRlbmRlZCBiaXQgaXMgc2V0LAogICAgICAgKiBhbmQgaWYgc28sIHF1ZXVlIHRoZSBleHRlbnNpb24gcHJlZml4ICovCiAgICAgIGlmIChtc2cuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpIHsKICAgICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLG1zZy5FdmVudC5LZXlFdmVudC51Q2hhci5Bc2NpaUNoYXIpOwogICAgICBicmVhazsKICAgIGNhc2UgTU9VU0VfRVZFTlQ6CiAgICAgIERPU1ZNX0ludDMzQ29uc29sZSgmbXNnLkV2ZW50Lk1vdXNlRXZlbnQpOwogICAgICBicmVhazsKICAgIGNhc2UgV0lORE9XX0JVRkZFUl9TSVpFX0VWRU5UOgogICAgICBGSVhNRSgidW5oYW5kbGVkIFdJTkRPV19CVUZGRVJfU0laRV9FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGNhc2UgTUVOVV9FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBNRU5VX0VWRU5ULlxuIik7CiAgICAgIGJyZWFrOwogICAgY2FzZSBGT0NVU19FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBGT0NVU19FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIEZJWE1FKCJ1bmtub3duIGNvbnNvbGUgZXZlbnQ6ICVkXG4iLCBtc2cuRXZlbnRUeXBlKTsKICAgIH0KICB9Cn0KCnN0YXRpYyB2b2lkIERPU1ZNX1Byb2Nlc3NNZXNzYWdlKE1TRyAqbXNnKQp7CiAgQllURSBzY2FuID0gMDsKCiAgVFJBQ0UoImdvdCBtZXNzYWdlICUwNHgsIHdwYXJhbT0lMDh4LCBscGFyYW09JTA4bHhcbiIsbXNnLT5tZXNzYWdlLG1zZy0+d1BhcmFtLG1zZy0+bFBhcmFtKTsKICBpZiAoKG1zZy0+bWVzc2FnZT49V01fTU9VU0VGSVJTVCkmJgogICAgICAobXNnLT5tZXNzYWdlPD1XTV9NT1VTRUxBU1QpKSB7CiAgICBET1NWTV9JbnQzM01lc3NhZ2UobXNnLT5tZXNzYWdlLG1zZy0+d1BhcmFtLG1zZy0+bFBhcmFtKTsKICB9IGVsc2UgewogICAgc3dpdGNoIChtc2ctPm1lc3NhZ2UpIHsKICAgIGNhc2UgV01fS0VZVVA6CiAgICAgIHNjYW4gPSAweDgwOwogICAgY2FzZSBXTV9LRVlET1dOOgogICAgICBzY2FuIHw9IChtc2ctPmxQYXJhbSA+PiAxNikgJiAweDdmOwoKICAgICAgLyogY2hlY2sgd2hldGhlciBleHRlbmRlZCBiaXQgaXMgc2V0LAogICAgICAgKiBhbmQgaWYgc28sIHF1ZXVlIHRoZSBleHRlbnNpb24gcHJlZml4ICovCiAgICAgIGlmIChtc2ctPmxQYXJhbSAmIDB4MTAwMDAwMCkgewoJLyogRklYTUU6IHNvbWUga2V5cyAoZnVuY3Rpb24ga2V5cykgaGF2ZQoJICogZXh0ZW5kZWQgYml0IHNldCBldmVuIHdoZW4gdGhleSBzaG91bGRuJ3QsCgkgKiBzaG91bGQgY2hlY2sgZm9yIHRoZW0gKi8KCURPU1ZNX0ludDA5U2VuZFNjYW4oMHhFMCwwKTsKICAgICAgfQogICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKHNjYW4sMCk7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXYWl0IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9XYWl0KCBJTlQgcmVhZF9waXBlLCBIQU5ETEUgaE9iamVjdCApCnsKICBNU0cgbXNnOwogIERXT1JEIHdhaXRyZXQ7CiAgSEFORExFIG9ianNbM107CiAgaW50IG9iamM7CiAgQk9PTCBnb3RfbXNnID0gRkFMU0U7CgogIG9ianNbMF09R2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIG9ianNbMV09ZXZlbnRfbm90aWZpZXI7CiAgb2Jqc1syXT1oT2JqZWN0OwogIG9iamM9aE9iamVjdD8zOjI7CiAgZG8gewogICAgLyogY2hlY2sgZm9yIG1lc3NhZ2VzICh3YXN0ZSB0aW1lIGJlZm9yZSB0aGUgcmVzcG9uc2UgY2hlY2sgYmVsb3cpICovCiAgICBpZiAoUGVla01lc3NhZ2VBKQogICAgewogICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkV8UE1fTk9ZSUVMRCkpIHsKICAgICAgICAgICAgLyogZ290IGEgbWVzc2FnZSAqLwogICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCBhIFRyYW5zbGF0ZU1lc3NhZ2UgaGVyZSAqLwogICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICBnb3RfbXNnID0gVFJVRTsKICAgICAgICB9CiAgICB9CmNoa19jb25zb2xlX2lucHV0OgogICAgaWYgKCFnb3RfbXNnKSB7CiAgICAgIC8qIGNoZWNrIGZvciBjb25zb2xlIGlucHV0ICovCiAgICAgIElOUFVUX1JFQ09SRCBtc2c7CiAgICAgIERXT1JEIG51bTsKICAgICAgaWYgKFBlZWtDb25zb2xlSW5wdXRBKG9ianNbMF0sJm1zZywxLCZudW0pICYmIG51bSkgewogICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgICAgZ290X21zZyA9IFRSVUU7CiAgICAgIH0KICAgIH0KICAgIGlmIChyZWFkX3BpcGUgPT0gLTEpIHsKICAgICAgLyogZGlzcGF0Y2ggcGVuZGluZyBldmVudHMgKi8KICAgICAgaWYgKFNIT1VMRF9QRU5EKHBlbmRpbmdfZXZlbnQpKSB7CiAgICAgICAgQ09OVEVYVDg2IGNvbnRleHQgPSAqY3VycmVudF9jb250ZXh0OwogICAgICAgIElGX1NFVCgmY29udGV4dCk7CiAgICAgICAgU0VUX1BFTkQoJmNvbnRleHQpOwogICAgICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQpOwogICAgICAgIGdvdF9tc2cgPSBUUlVFOwogICAgICB9CiAgICAgIGlmIChnb3RfbXNnKSBicmVhazsKICAgIH0gZWxzZSB7CiAgICAgIGZkX3NldCByZWFkZmRzOwogICAgICBzdHJ1Y3QgdGltZXZhbCB0aW1lb3V0PXswLDB9OwogICAgICAvKiBxdWljayBjaGVjayBmb3IgcmVzcG9uc2UgZnJvbSBkb3Ntb2QKICAgICAgICogKGZhc3RlciB0aGFuIGRvaW5nIHRoZSBmdWxsIGJsb2NraW5nIHdhaXQsIGlmIGRhdGEgYWxyZWFkeSBhdmFpbGFibGUpICovCiAgICAgIEZEX1pFUk8oJnJlYWRmZHMpOyBGRF9TRVQocmVhZF9waXBlLCZyZWFkZmRzKTsKICAgICAgaWYgKHNlbGVjdChyZWFkX3BpcGUrMSwmcmVhZGZkcyxOVUxMLE5VTEwsJnRpbWVvdXQpPjApCglicmVhazsKICAgIH0KICAgIC8qIG5vdGhpbmcgeWV0LCBibG9jayB3aGlsZSB3YWl0aW5nIGZvciBzb21ldGhpbmcgdG8gZG8gKi8KICAgIGlmIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKQogICAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKG9iamMsb2JqcyxGQUxTRSxJTkZJTklURSxRU19BTExJTlBVVCk7CiAgICBlbHNlCiAgICAgICAgd2FpdHJldCA9IFdhaXRGb3JNdWx0aXBsZU9iamVjdHMob2JqYyxvYmpzLEZBTFNFLElORklOSVRFKTsKCiAgICBpZiAod2FpdHJldD09KERXT1JEKS0xKSB7CiAgICAgIEVSUl8obW9kdWxlKSgiZG9zdm0gd2FpdCBlcnJvcj0lbGRcbiIsR2V0TGFzdEVycm9yKCkpOwogICAgfQogICAgaWYgKChyZWFkX3BpcGUgIT0gLTEpICYmIGhPYmplY3QpIHsKICAgICAgaWYgKHdhaXRyZXQ9PShXQUlUX09CSkVDVF8wKzIpKSBicmVhazsKICAgIH0KICAgIGlmICh3YWl0cmV0PT1XQUlUX09CSkVDVF8wKQogICAgICBnb3RvIGNoa19jb25zb2xlX2lucHV0OwogIH0gd2hpbGUgKFRSVUUpOwp9CgpEV09SRCBXSU5BUEkgRE9TVk1fTG9vcCggSEFORExFIGhUaHJlYWQgKQp7CiAgSEFORExFIG9ianNbMl07CiAgTVNHIG1zZzsKICBEV09SRCB3YWl0cmV0OwoKICBvYmpzWzBdID0gR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIG9ianNbMV0gPSBoVGhyZWFkOwoKICBmb3IoOzspIHsKICAgICAgVFJBQ0VfKGludCkoIndhaXRpbmcgZm9yIGFjdGlvblxuIik7CiAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDIsIG9ianMsIEZBTFNFLCBJTkZJTklURSwgUVNfQUxMSU5QVVQpOwogICAgICBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpIHsKICAgICAgICAgRFdPUkQgcnY7CiAgICAgICAgIGlmKCFHZXRFeGl0Q29kZVRocmVhZChoVGhyZWFkLCAmcnYpKSB7CiAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBnZXQgdGhyZWFkIGV4aXQgY29kZSFcbiIpOwogICAgICAgICAgICAgcnYgPSAwOwogICAgICAgICB9CiAgICAgICAgIHJldHVybiBydjsKICAgICAgfQogICAgICBlbHNlIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzAgKyAyKSB7CiAgICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFKSkgewogICAgICAgICAgICAgIGlmIChtc2cuaHduZCkgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgd2luZG93IG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgLyogaXQncyBhIHRocmVhZCBtZXNzYWdlICovCiAgICAgICAgICAgICAgICAgIHN3aXRjaCAobXNnLm1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9RVUlUOgogICAgICAgICAgICAgICAgICAgICAgLyogc3RvcCB0aGlzIG1hZG5lc3MhISAqLwogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgIGNhc2UgV01fVVNFUjoKICAgICAgICAgICAgICAgICAgICAgIC8qIHJ1biBwYXNzZWQgcHJvY2VkdXJlIGluIHRoaXMgdGhyZWFkICovCiAgICAgICAgICAgICAgICAgICAgICAvKiAoc29ydCBvZiBsaWtlIEFQQywgYnV0IHdlIHNpZ25hbCB0aGUgY29tcGxldGlvbikgKi8KICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBET1NfU1BDICpzcGMgPSAoRE9TX1NQQyAqKW1zZy5sUGFyYW07CiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGludCkoImNhbGxpbmcgJXAgd2l0aCBhcmcgJTA4bHhcbiIsIHNwYy0+cHJvYywgc3BjLT5hcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgIChzcGMtPnByb2MpKHNwYy0+YXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiZG9uZSwgc2lnbmFsbGluZyBldmVudCAleFxuIiwgbXNnLndQYXJhbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0RXZlbnQoIChIQU5ETEUpbXNnLndQYXJhbSApOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgICBFUlJfKGludCkoIk1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMgcmV0dXJuZWQgdW5leHBlY3RlZCB2YWx1ZS5cbiIpOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICB9Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIoZXhjZXB0aW9uX2hhbmRsZXIpCnsKICBFWENFUFRJT05fUkVDT1JEICpyZWMgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5FeGNlcHRpb25SZWNvcmQ7CiAgQ09OVEVYVCAqY29udGV4dCA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkNvbnRleHRSZWNvcmQ7CiAgaW50IHJldCwgYXJnID0gcmVjLT5FeGNlcHRpb25JbmZvcm1hdGlvblswXTsKCiAgc3dpdGNoKHJlYy0+RXhjZXB0aW9uQ29kZSkgewogIGNhc2UgRVhDRVBUSU9OX1ZNODZfSU5UeDoKICAgIGlmIChUUkFDRV9PTihyZWxheSkpIHsKICAgICAgRFBSSU5URigiQ2FsbCBET1MgaW50IDB4JTAyeCByZXQ9JTA0bHg6JTA0bHhcbiIsCgkgICAgICBhcmcsIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAgKTsKICAgICAgRFBSSU5URigiIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseCBlc2k9JTA4bHggZWRpPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LAoJICAgICAgY29udGV4dC0+RXNpLCBjb250ZXh0LT5FZGkgKTsKICAgICAgRFBSSU5URigiIGVicD0lMDhseCBlc3A9JTA4bHggZHM9JTA0bHggZXM9JTA0bHggZnM9JTA0bHggZ3M9JTA0bHggZmxhZ3M9JTA4bHhcbiIsCgkgICAgICBjb250ZXh0LT5FYnAsIGNvbnRleHQtPkVzcCwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzLAoJICAgICAgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLCBjb250ZXh0LT5FRmxhZ3MgKTsKICAgICAgfQogICAgcmV0ID0gRE9TVk1fU2ltdWxhdGVJbnQoYXJnLCBjb250ZXh0LCBGQUxTRSk7CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICB9CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUiA6IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CgogIGNhc2UgRVhDRVBUSU9OX1ZNODZfU1RJOgogIC8qIGNhc2UgRVhDRVBUSU9OX1ZNODZfUElDUkVUVVJOOiAqLwogICAgSUZfU0VUKGNvbnRleHQpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIHNpZ19zZW50Kys7CiAgICB3aGlsZSAoTnRDdXJyZW50VGViKCktPmFsYXJtcykgewogICAgICBET1NWTV9RdWV1ZUV2ZW50KDAsRE9TX1BSSU9SSVRZX1JFQUxUSU1FLE5VTEwsTlVMTCk7CiAgICAgIC8qIGhtbSwgaW5zdGVhZCBvZiByZWx5aW5nIG9uIHRoaXMgc2lnbmFsIGNvdW50ZXIsIHdlIHNob3VsZAogICAgICAgKiBwcm9iYWJseSBjaGVjayBob3cgbWFueSB0aWNrcyBoYXZlICpyZWFsbHkqIHBhc3NlZCwgcHJvYmFibHkgdXNpbmcKICAgICAgICogUXVlcnlQZXJmb3JtYW5jZUNvdW50ZXIoKSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCYoTnRDdXJyZW50VGViKCktPmFsYXJtcykpOwogICAgfQogICAgVFJBQ0VfKGludCkoImNvbnRleHQ9JXAsIGN1cnJlbnQ9JXBcbiIsIGNvbnRleHQsIGN1cnJlbnRfY29udGV4dCk7CiAgICBUUkFDRV8oaW50KSgiY3M6aXA9JTA0bHg6JTA0bHgsIHNzOnNwPSUwNGx4OiUwNGx4XG4iLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwKTsKICAgIGlmICghSVNWODYoY29udGV4dCkpIHsKICAgICAgRVJSXyhpbnQpKCJAIyYqJSUsIHdpbmVkb3Mgc2lnbmFsIGhhbmRsaW5nIGlzICpzdGlsbCogbWVzc2VkIHVwXG4iKTsKICAgIH0KICAgIFRSQUNFXyhpbnQpKCJET1MgdGFzayBlbmFibGVkIGludGVycnVwdHMgJXMgZXZlbnRzIHBlbmRpbmcsIHNlbmRpbmcgZXZlbnRzICh0aW1lPSVsZClcbiIsIElTX1BFTkQoY29udGV4dCk/IndpdGgiOiJ3aXRob3V0IiwgR2V0VGlja0NvdW50KCkpOwogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhjb250ZXh0KTsKICAgIHNpZ19zZW50PTA7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CiAgfQogIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfU0VBUkNIOwp9CgppbnQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgQ09OVEVYVDg2ICpvbGRfY29udGV4dCA9IGN1cnJlbnRfY29udGV4dDsKCiAgY3VycmVudF9jb250ZXh0ID0gY29udGV4dDsKICBfX1RSWQogIHsKICAgIF9fd2luZV9lbnRlcl92bTg2KCBjb250ZXh0ICk7CiAgICBUUkFDRV8obW9kdWxlKSggInZtODYgcmV0dXJuZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykgKTsKICB9CiAgX19FWENFUFQoZXhjZXB0aW9uX2hhbmRsZXIpCiAgewogICAgVFJBQ0VfKG1vZHVsZSkoICJsZWF2aW5nIHZtODYgbW9kZVxuIiApOwogIH0KICBfX0VORFRSWQogIGN1cnJlbnRfY29udGV4dCA9IG9sZF9jb250ZXh0OwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICAgIExQRE9TRVZFTlQgZXZlbnQ7CgogICAgaWYgKChwb3J0PT0weDIwKSAmJiAodmFsPT0weDIwKSkgewogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICBpZiAoY3VycmVudF9ldmVudCkgewoJLyogRU9JIChFbmQgT2YgSW50ZXJydXB0KSAqLwoJVFJBQ0UoInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gY3VycmVudF9ldmVudDsKCWN1cnJlbnRfZXZlbnQgPSBldmVudC0+bmV4dDsKCWlmIChldmVudC0+cmVsYXkpCgkoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CglmcmVlKGV2ZW50KTsKCglpZiAocGVuZGluZ19ldmVudCkgewoJICAvKiBhbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHdoaWNoIHdlIHNob3VsZCBwcm9iYWJseQoJICAgKiBiZSBhYmxlIHRvIHByb2Nlc3Mgbm93ICovCgkgIFRSQUNFKCJhbm90aGVyIGV2ZW50IHBlbmRpbmcsIHNldHRpbmcgZmxhZ1xuIik7CgkgIGN1cnJlbnRfY29udGV4dC0+RUZsYWdzIHw9IFZJUF9NQVNLOwoJfQogICAgICB9IGVsc2UgewoJV0FSTigiRU9JIHdpdGhvdXQgYWN0aXZlIElSUVxuIik7CiAgICAgIH0KICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIH0gZWxzZSB7CiAgICAgIEZJWE1FKCJ1bnJlY29nbml6ZWQgUElDIGNvbW1hbmQgJTAyeFxuIix2YWwpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApCnsKICBzdHJ1Y3QgaXRpbWVydmFsIHRpbTsKCiAgaWYgKGRvc3ZtX3BpZCkgewogICAgLyogdGhlIFBDIGNsb2NrcyB0aWNrcyBhdCAxMTkzMTgwIEh6ICovCiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfc2VjPTA7CiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYz1NdWxEaXYodGlja3MsMTAwMDAwMCwxMTkzMTgwKTsKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKCF0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYykgdGltLml0X2ludGVydmFsLnR2X3VzZWM9MTsKICAgIC8qIGZpcnN0IHRpY2sgdmFsdWUgKi8KICAgIHRpbS5pdF92YWx1ZSA9IHRpbS5pdF9pbnRlcnZhbDsKICAgIFRSQUNFXyhpbnQpKCJzZXR0aW5nIHRpbWVyIHRpY2sgZGVsYXkgdG8gJWxkIHVzXG4iLCB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYyk7CiAgICBzZXRpdGltZXIoSVRJTUVSX1JFQUwsICZ0aW0sIE5VTEwpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRUaW1lciAoV0lORURPUy5AKQogKi8KVUlOVCBXSU5BUEkgRE9TVk1fR2V0VGltZXIoIHZvaWQgKQp7CiAgc3RydWN0IGl0aW1lcnZhbCB0aW07CgogIGlmIChkb3N2bV9waWQpIHsKICAgIGdldGl0aW1lcihJVElNRVJfUkVBTCwgJnRpbSk7CiAgICByZXR1cm4gTXVsRGl2KHRpbS5pdF92YWx1ZS50dl91c2VjLDExOTMxODAsMTAwMDAwMCk7CiAgfQogIHJldHVybiAwOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVudGVyIChXSU5FRE9TLkApCiAqLwpJTlQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiBFUlJfKG1vZHVsZSkoIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggSU5UIHJlYWRfcGlwZSwgSEFORExFIGhPYmplY3QpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFRpbWVyIChXSU5FRE9TLkApCiAqLwpVSU5UIFdJTkFQSSBET1NWTV9HZXRUaW1lciggdm9pZCApIHsgcmV0dXJuIDA7IH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBpZiAoaXJxPDApIHsKICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICBtZW1zZXQoJmNvbnRleHQsMCxzaXplb2YoY29udGV4dCkpOwogICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgfSBlbHNlIHsKICAgIEVSUigiSVJRIHdpdGhvdXQgRE9TIHRhc2s6IHNob3VsZCBub3QgaGFwcGVuXG4iKTsKICB9Cn0KCiNlbmRpZgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX0dldFJNSGFuZGxlcgogKgogKiBSZXR1cm4gdGhlIHJlYWwgbW9kZSBpbnRlcnJ1cHQgdmVjdG9yIGZvciBhIGdpdmVuIGludGVycnVwdC4KICovCkZBUlBST0MxNiBET1NWTV9HZXRSTUhhbmRsZXIoIEJZVEUgaW50bnVtICkKewogICAgcmV0dXJuICgoRkFSUFJPQzE2KikwKVtpbnRudW1dOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX1NldFJNSGFuZGxlcgogKgogKiBTZXQgdGhlIHJlYWwgbW9kZSBpbnRlcnJ1cHQgaGFuZGxlciBmb3IgYSBnaXZlbiBpbnRlcnJ1cHQuCiAqLwp2b2lkIERPU1ZNX1NldFJNSGFuZGxlciggQllURSBpbnRudW0sIEZBUlBST0MxNiBoYW5kbGVyICkKewogICAgVFJBQ0UoIlNldCByZWFsIG1vZGUgaW50ZXJydXB0IHZlY3RvciAlMDJ4IDwtICUwNHg6JTA0eFxuIiwKICAgICAgICAgICAgICAgICBpbnRudW0sIEhJV09SRChoYW5kbGVyKSwgTE9XT1JEKGhhbmRsZXIpICk7CiAgICAoKEZBUlBST0MxNiopMClbaW50bnVtXSA9IGhhbmRsZXI7Cn0KCgpzdGF0aWMgY29uc3QgSU5UUFJPQyByZWFsX21vZGVfaGFuZGxlcnNbXSA9CnsKICAgIC8qIDAwICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiAwOCAqLyAwLCBET1NWTV9JbnQwOUhhbmRsZXIsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiAxMCAqLyBET1NWTV9JbnQxMEhhbmRsZXIsIElOVF9JbnQxMUhhbmRsZXIsIElOVF9JbnQxMkhhbmRsZXIsIElOVF9JbnQxM0hhbmRsZXIsCiAgICAgICAgICAgICAwLCBJTlRfSW50MTVIYW5kbGVyLCBET1NWTV9JbnQxNkhhbmRsZXIsIERPU1ZNX0ludDE3SGFuZGxlciwKICAgIC8qIDE4ICovIDAsIDAsIElOVF9JbnQxYUhhbmRsZXIsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiAyMCAqLyBET1NWTV9JbnQyMEhhbmRsZXIsIERPU1ZNX0ludDIxSGFuZGxlciwgMCwgMCwgMCwgSU5UX0ludDI1SGFuZGxlciwgMCwgMCwKICAgIC8qIDI4ICovIDAsIERPU1ZNX0ludDI5SGFuZGxlciwgSU5UX0ludDJhSGFuZGxlciwgMCwgMCwgMCwgMCwgSU5UX0ludDJmSGFuZGxlciwKICAgIC8qIDMwICovIDAsIERPU1ZNX0ludDMxSGFuZGxlciwgMCwgRE9TVk1fSW50MzNIYW5kbGVyLCBJTlRfSW50MzRIYW5kbGVyLCBJTlRfSW50MzVIYW5kbGVyLCBJTlRfSW50MzZIYW5kbGVyLCBJTlRfSW50MzdIYW5kbGVyLAogICAgLyogMzggKi8gSU5UX0ludDM4SGFuZGxlciwgSU5UX0ludDM5SGFuZGxlciwgSU5UX0ludDNhSGFuZGxlciwgSU5UX0ludDNiSGFuZGxlciwgSU5UX0ludDNjSGFuZGxlciwgSU5UX0ludDNkSGFuZGxlciwgSU5UX0ludDNlSGFuZGxlciwgMCwKICAgIC8qIDQwICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiA0OCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogNTAgKi8gMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKICAgIC8qIDU4ICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiA2MCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCBET1NWTV9JbnQ2N0hhbmRsZXIKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRE9TVk1fUmVhbE1vZGVJbnRlcnJ1cHQKICoKICogSGFuZGxlIHJlYWwgbW9kZSBpbnRlcnJ1cHRzCiAqLwp2b2lkIERPU1ZNX1JlYWxNb2RlSW50ZXJydXB0KCBCWVRFIGludG51bSwgQ09OVEVYVDg2ICpjb250ZXh0ICkKewogICAgaWYgKGludG51bSA8IHNpemVvZihyZWFsX21vZGVfaGFuZGxlcnMpL3NpemVvZihJTlRQUk9DKSAmJiByZWFsX21vZGVfaGFuZGxlcnNbaW50bnVtXSkKICAgICAgICAoKnJlYWxfbW9kZV9oYW5kbGVyc1tpbnRudW1dKShjb250ZXh0KTsKICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiVW5rbm93biBJbnRlcnJ1cHQgaW4gRE9TIG1vZGU6IDB4JXhcbiIsIGludG51bSk7CiAgICAgICAgRklYTUUoIiAgICBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHhcbiIsCiAgICAgICAgICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4KTsKICAgICAgICBGSVhNRSgiICAgIGVzaT0lMDhseCBlZGk9JTA4bHggZHM9JTA0bHggZXM9JTA0bHhcbiIsCiAgICAgICAgICAgICAgY29udGV4dC0+RXNpLCBjb250ZXh0LT5FZGksIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcyApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX0luaXQKICovCkJPT0wgV0lOQVBJIERPU1ZNX0luaXQoIEhJTlNUQU5DRSBoaW5zdERMTCwgRFdPUkQgZmR3UmVhc29uLCBMUFZPSUQgbHB2UmVzZXJ2ZWQgKQp7CiAgICBUUkFDRV8obW9kdWxlKSgiKCVwLCVsZCwlcClcbiIsIGhpbnN0RExMLCBmZHdSZWFzb24sIGxwdlJlc2VydmVkKTsKCiAgICBpZiAoZmR3UmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgICAgICBUUkFDRSgiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiAgICAgICAgRE9TTUVNX0luaXQoIFRSVUUgKTsKICAgICAgICBET1NERVZfSW5zdGFsbERPU0RldmljZXMoKTsKICAgICAgICBET1NWTV9kcG1pX3NlZ21lbnRzID0gRE9TTUVNX0dldERQTUlTZWdtZW50cygpOwoKI2lmZGVmIE1aX1NVUFBPUlRFRAogICAgICAgIGV2ZW50X25vdGlmaWVyID0gQ3JlYXRlRXZlbnRBKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYoIWV2ZW50X25vdGlmaWVyKQogICAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGV2ZW50IG9iamVjdCFcbiIpOwojZW5kaWYKCiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQo=