LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid293bnQzMi5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgoKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3N2bS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZXhjcHQuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGludCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CiNpZmRlZiBNWl9TVVBQT1JURUQKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwojZW5kaWYKCldPUkQgRE9TVk1fcHNwID0gMDsKV09SRCBET1NWTV9yZXR2YWwgPSAwOwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKCnR5cGVkZWYgc3RydWN0IF9ET1NFVkVOVCB7CiAgaW50IGlycSxwcmlvcml0eTsKICBET1NSRUxBWSByZWxheTsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBfRE9TRVZFTlQgKm5leHQ7Cn0gRE9TRVZFTlQsICpMUERPU0VWRU5UOwoKc3RhdGljIHN0cnVjdCBfRE9TRVZFTlQgKnBlbmRpbmdfZXZlbnQsICpjdXJyZW50X2V2ZW50OwpzdGF0aWMgSEFORExFIGV2ZW50X25vdGlmaWVyOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQ7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJnFjcml0LAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBxY3JpdCIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQgPSB7ICZjcml0c2VjdF9kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMKICoKICogUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIHBlbmRpbmcgZXZlbnRzIHRoYXQgYXJlIG5vdAogKiBibG9ja2VkIGJ5IGN1cnJlbnRseSBhY3RpdmUgZXZlbnQuCiAqLwpzdGF0aWMgQk9PTCBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCB2b2lkICkKeyAgIAogICAgaWYgKCFwZW5kaW5nX2V2ZW50KQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIWN1cnJlbnRfZXZlbnQpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaWYgKHBlbmRpbmdfZXZlbnQtPnByaW9yaXR5IDwgY3VycmVudF9ldmVudC0+cHJpb3JpdHkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQKICoKICogUHJvY2VzcyBzaW5nbGUgcGVuZGluZyBldmVudC4KICoKICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdpdGggcXVldWUgY3JpdGljYWwgc2VjdGlvbiBsb2NrZWQuIAogKiBUaGUgZnVuY3Rpb24gdGVtcG9yYXJpbHkgcmVsZWFzZXMgdGhlIGNyaXRpY2FsIHNlY3Rpb24gaWYgaXQgaXMgCiAqIHBvc3NpYmxlIHRoYXQgaW50ZXJuYWwgaW50ZXJydXB0IGhhbmRsZXIgb3IgdXNlciBwcm9jZWR1cmUgd2lsbCAKICogYmUgY2FsbGVkLiBUaGlzIGlzIGJlY2F1c2Ugd2UgbWF5IG90aGVyd2lzZSBnZXQgYSBkZWFkbG9jayBpZgogKiBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIGZvciB0aGUgc2FtZSBjcml0aWNhbCBzZWN0aW9uLgogKi8Kc3RhdGljIHZvaWQgRE9TVk1fU2VuZE9uZUV2ZW50KCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBMUERPU0VWRU5UIGV2ZW50ID0gcGVuZGluZ19ldmVudDsKCiAgICAvKiBSZW1vdmUgZnJvbSBwZW5kaW5nIGV2ZW50cyBsaXN0LiAqLwogICAgcGVuZGluZ19ldmVudCA9IGV2ZW50LT5uZXh0OwoKICAgIC8qIFByb2Nlc3MgYWN0aXZlIGV2ZW50LiAqLwogICAgaWYgKGV2ZW50LT5pcnEgPj0gMCkgCiAgICB7CiAgICAgICAgQllURSBpbnRudW0gPSAoZXZlbnQtPmlycSA8IDgpID8KICAgICAgICAgICAgKGV2ZW50LT5pcnEgKyA4KSA6IChldmVudC0+aXJxIC0gOCArIDB4NzApOwogICAgICAgICAgICAKICAgICAgICAvKiBFdmVudCBpcyBhbiBJUlEsIG1vdmUgaXQgdG8gY3VycmVudCBldmVudHMgbGlzdC4gKi8KICAgICAgICBldmVudC0+bmV4dCA9IGN1cnJlbnRfZXZlbnQ7CiAgICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50OwoKICAgICAgICBUUkFDRSggIkRpc3BhdGNoaW5nIElSUSAlZC5cbiIsIGV2ZW50LT5pcnEgKTsKCiAgICAgICAgaWYgKElTVjg2KGNvbnRleHQpKQogICAgICAgIHsKICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCBpZiBET1NWTV9IYXJkd2FyZUludGVycnVwdFJNIGNhbGxzIGFuIGludGVybmFsIAogICAgICAgICAgICAgKiBpbnRlcnJ1cHQgZGlyZWN0bHksIGN1cnJlbnRfZXZlbnQgbWlnaHQgYmUgY2xlYXJlZCAKICAgICAgICAgICAgICogKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyBjYWxsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgRE9TVk1fSGFyZHdhcmVJbnRlcnJ1cHRSTSggY29udGV4dCwgaW50bnVtICk7CiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgcm91dGluZSBvbmx5IG1vZGlmaWVzIGN1cnJlbnQgY29udGV4dCBzbyBpdCBpcwogICAgICAgICAgICAgKiBub3QgbmVjZXNzYXJ5IHRvIHJlbGVhc2UgY3JpdGljYWwgc2VjdGlvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0hhcmR3YXJlSW50ZXJydXB0UE0oIGNvbnRleHQsIGludG51bSApOwogICAgICAgIH0KICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIC8qIENhbGxiYWNrIGV2ZW50LiAqLwogICAgICAgIFRSQUNFKCAiRGlzcGF0Y2hpbmcgY2FsbGJhY2sgZXZlbnQuXG4iICk7CgogICAgICAgIGlmIChJU1Y4Nihjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIENhbGwgcmVsYXkgaW1tZWRpYXRlbHkgaW4gcmVhbCBtb2RlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgKCpldmVudC0+cmVsYXkpKCBjb250ZXh0LCBldmVudC0+ZGF0YSApOwogICAgICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3JjZSByZXR1cm4gdG8gcmVsYXkgY29kZS4gV2UgZG8gbm90IHdhbnQgdG8KICAgICAgICAgICAgICogY2FsbCByZWxheSBkaXJlY3RseSBiZWNhdXNlIHdlIG1heSBiZSBpbnNpZGUgYSBzaWduYWwgaGFuZGxlci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0J1aWxkQ2FsbEZyYW1lKCBjb250ZXh0LCBldmVudC0+cmVsYXksIGV2ZW50LT5kYXRhICk7CiAgICAgICAgfQoKICAgICAgICBmcmVlKGV2ZW50KTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cwogKgogKiBBcyBsb25nIGFzIGNvbnRleHQgaW5zdHJ1Y3Rpb24gcG9pbnRlciBzdGF5cyB1bm1vZGlmaWVkLAogKiBwcm9jZXNzIGFsbCBwZW5kaW5nIGV2ZW50cyB0aGF0IGFyZSBub3QgYmxvY2tlZCBieSBjdXJyZW50bHkKICogYWN0aXZlIGV2ZW50LgogKgogKiBUaGlzIHJvdXRpbmUgYXNzdW1lcyB0aGF0IGNhbGxlciBoYXMgYWxyZWFkeSBjbGVhcmVkIFRFQi52bTg2X3BlbmRpbmcgCiAqIGFuZCBjaGVja2VkIHRoYXQgaW50ZXJydXB0cyBhcmUgZW5hYmxlZC4KICovCnZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyggQ09OVEVYVDg2ICpjb250ZXh0ICkKeyAgIAogICAgRFdPUkQgb2xkX2NzID0gY29udGV4dC0+U2VnQ3M7CiAgICBEV09SRCBvbGRfaXAgPSBjb250ZXh0LT5FaXA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICBUUkFDRSggIkNhbGxlZCBpbiAlcyBtb2RlICVzIGV2ZW50cyBwZW5kaW5nICh0aW1lPSVkKVxuIiwKICAgICAgICAgICBJU1Y4Nihjb250ZXh0KSA/ICJyZWFsIiA6ICJwcm90ZWN0ZWQiLAogICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSA/ICJ3aXRoIiA6ICJ3aXRob3V0IiwKICAgICAgICAgICBHZXRUaWNrQ291bnQoKSApOwogICAgVFJBQ0UoICJjczppcD0lMDR4OiUwOHgsIHNzOnNwPSUwNHg6JTA4eFxuIiwKICAgICAgICAgICBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwKTsKCiAgICB3aGlsZSAoY29udGV4dC0+U2VnQ3MgPT0gb2xkX2NzICYmCiAgICAgICAgICAgY29udGV4dC0+RWlwID09IG9sZF9pcCAmJgogICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkKICAgIHsKICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQoY29udGV4dCk7CgogICAgICAgIC8qCiAgICAgICAgICogRXZlbnQgaGFuZGxpbmcgbWF5IGhhdmUgdHVybmVkIHBlbmRpbmcgZXZlbnRzIGZsYWcgb24uCiAgICAgICAgICogV2UgZGlzYWJsZSBpdCBoZXJlIGJlY2F1c2UgdGhpcyBwcmV2ZW50cyBzb21lCiAgICAgICAgICogdW5uZWNlc3NhcnkgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbi4KICAgICAgICAgKi8KICAgICAgICBOdEN1cnJlbnRUZWIoKS0+dm04Nl9wZW5kaW5nID0gMDsKICAgIH0KCiNpZmRlZiBNWl9TVVBQT1JURUQKCiAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogSW50ZXJydXB0cyBkaXNhYmxlZCwgYnV0IHRoZXJlIGFyZSBzdGlsbAogICAgICAgICAqIHBlbmRpbmcgZXZlbnRzLCBtYWtlIHN1cmUgdGhhdCBwZW5kaW5nIGZsYWcgaXMgdHVybmVkIG9uLgogICAgICAgICAqLwogICAgICAgIFRSQUNFKCAiQW5vdGhlciBldmVudCBpcyBwZW5kaW5nLCBzZXR0aW5nIFZJUCBmbGFnLlxuIiApOwogICAgICAgIE50Q3VycmVudFRlYigpLT52bTg2X3BlbmRpbmcgfD0gVklQX01BU0s7CiAgICB9CgojZWxzZQoKICAgIEZJWE1FKCJObyBET1MgLmV4ZSBmaWxlIHN1cHBvcnQgb24gdGhpcyBwbGF0Zm9ybSAoeWV0KVxuIik7CgojZW5kaWYgLyogTVpfU1VQUE9SVEVEICovCgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKfQoKCiNpZmRlZiBNWl9TVVBQT1JURUQKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlRdWV1ZUV2ZW50IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9RdWV1ZUV2ZW50KCBJTlQgaXJxLCBJTlQgcHJpb3JpdHksIERPU1JFTEFZIHJlbGF5LCBMUFZPSUQgZGF0YSkKewogIExQRE9TRVZFTlQgZXZlbnQsIGN1ciwgcHJldjsKICBCT09MICAgICAgIG9sZF9wZW5kaW5nOwoKICBpZiAoTVpfQ3VycmVudCgpKSB7CiAgICBldmVudCA9IG1hbGxvYyhzaXplb2YoRE9TRVZFTlQpKTsKICAgIGlmICghZXZlbnQpIHsKICAgICAgRVJSKCJvdXQgb2YgbWVtb3J5IGFsbG9jYXRpbmcgZXZlbnQgZW50cnlcbiIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBldmVudC0+aXJxID0gaXJxOyBldmVudC0+cHJpb3JpdHkgPSBwcmlvcml0eTsKICAgIGV2ZW50LT5yZWxheSA9IHJlbGF5OyBldmVudC0+ZGF0YSA9IGRhdGE7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIG9sZF9wZW5kaW5nID0gRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpOwoKICAgIC8qIGluc2VydCBldmVudCBpbnRvIGxpbmtlZCBsaXN0LCBpbiBvcmRlciAqYWZ0ZXIqCiAgICAgKiBhbGwgZWFybGllciBldmVudHMgb2YgaGlnaGVyIG9yIGVxdWFsIHByaW9yaXR5ICovCiAgICBjdXIgPSBwZW5kaW5nX2V2ZW50OyBwcmV2ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgJiYgY3VyLT5wcmlvcml0eTw9cHJpb3JpdHkpIHsKICAgICAgcHJldiA9IGN1cjsKICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgZXZlbnQtPm5leHQgPSBjdXI7CiAgICBpZiAocHJldikgcHJldi0+bmV4dCA9IGV2ZW50OwogICAgZWxzZSBwZW5kaW5nX2V2ZW50ID0gZXZlbnQ7CgogICAgaWYgKCFvbGRfcGVuZGluZyAmJiBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQsIHNpZ25hbGxpbmcgKHRpbWU9JWQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICAgIAogICAgICAvKiBBbGVydCBWTTg2IHRocmVhZCBhYm91dCB0aGUgbmV3IGV2ZW50LiAqLwogICAgICBraWxsKGRvc3ZtX3BpZCxTSUdVU1IyKTsKCiAgICAgIC8qIFdha2UgdXAgRE9TVk1fV2FpdCBzbyB0aGF0IGl0IGNhbiBzZXJ2ZSBwZW5kaW5nIGV2ZW50cy4gKi8KICAgICAgU2V0RXZlbnQoZXZlbnRfbm90aWZpZXIpOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQgKHRpbWU9JWQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICB9IGVsc2UgewogICAgLyogRE9TIHN1YnN5c3RlbSBub3QgcnVubmluZyAqLwogICAgLyogKHRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB3ZSdyZSBydW5uaW5nIGEgd2luMTYgYXBwCiAgICAgKiAgd2hpY2ggdXNlcyBEUE1JIHRvIHRodW5rIGRvd24gdG8gRE9TIHNlcnZpY2VzKSAqLwogICAgaWYgKGlycTwwKSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgICBDT05URVhUODYgY29udGV4dDsKICAgICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzQ29uc29sZSh2b2lkKQp7CiAgSU5QVVRfUkVDT1JEIG1zZzsKICBEV09SRCByZXM7CiAgQllURSBzY2FuLCBhc2NpaTsKCiAgaWYgKFJlYWRDb25zb2xlSW5wdXRBKEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKSwmbXNnLDEsJnJlcykpIHsKICAgIHN3aXRjaCAobXNnLkV2ZW50VHlwZSkgewogICAgY2FzZSBLRVlfRVZFTlQ6CiAgICAgIHNjYW4gPSBtc2cuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZTsKICAgICAgYXNjaWkgPSBtc2cuRXZlbnQuS2V5RXZlbnQudUNoYXIuQXNjaWlDaGFyOwogICAgICBUUkFDRSgic2NhbiAlMDJ4LCBhc2NpaSAlMDJ4XG4iLCBzY2FuLCBhc2NpaSk7CgogICAgICAvKiBzZXQgdGhlICJicmVhayIgKHJlbGVhc2UpIGZsYWcgaWYga2V5IHJlbGVhc2VkICovCiAgICAgIGlmICghbXNnLkV2ZW50LktleUV2ZW50LmJLZXlEb3duKSBzY2FuIHw9IDB4ODA7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkgewogICAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oMHhFMCwwKTsKICAgICAgfQogICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKHNjYW4sIGFzY2lpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1PVVNFX0VWRU5UOgogICAgICBET1NWTV9JbnQzM0NvbnNvbGUoJm1zZy5FdmVudC5Nb3VzZUV2ZW50KTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkRPV19CVUZGRVJfU0laRV9FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1FTlVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgTUVOVV9FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGNhc2UgRk9DVVNfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgRk9DVVNfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5rbm93biBjb25zb2xlIGV2ZW50OiAlZFxuIiwgbXNnLkV2ZW50VHlwZSk7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzTWVzc2FnZShNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIFRSQUNFKCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4eCwgbHBhcmFtPSUwOGx4XG4iLG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgaWYgKChtc2ctPm1lc3NhZ2U+PVdNX01PVVNFRklSU1QpJiYKICAgICAgKG1zZy0+bWVzc2FnZTw9V01fTU9VU0VMQVNUKSkgewogICAgRE9TVk1fSW50MzNNZXNzYWdlKG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgfSBlbHNlIHsKICAgIHN3aXRjaCAobXNnLT5tZXNzYWdlKSB7CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICBzY2FuID0gMHg4MDsKICAgIGNhc2UgV01fS0VZRE9XTjoKICAgICAgc2NhbiB8PSAobXNnLT5sUGFyYW0gPj4gMTYpICYgMHg3ZjsKCiAgICAgIC8qIGNoZWNrIHdoZXRoZXIgZXh0ZW5kZWQgYml0IGlzIHNldCwKICAgICAgICogYW5kIGlmIHNvLCBxdWV1ZSB0aGUgZXh0ZW5zaW9uIHByZWZpeCAqLwogICAgICBpZiAobXNnLT5sUGFyYW0gJiAweDEwMDAwMDApIHsKCS8qIEZJWE1FOiBzb21lIGtleXMgKGZ1bmN0aW9uIGtleXMpIGhhdmUKCSAqIGV4dGVuZGVkIGJpdCBzZXQgZXZlbiB3aGVuIHRoZXkgc2hvdWxkbid0LAoJICogc2hvdWxkIGNoZWNrIGZvciB0aGVtICovCglET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLDApOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURPU1ZNX1dhaXQKICoKICogV2FpdCBmb3IgYXN5bmNocm9ub3VzIGV2ZW50cy4gVGhpcyByb3V0aW5lIHRlbXBvcmFyaWx5IGVuYWJsZXMKICogaW50ZXJydXB0cyBhbmQgd2FpdHMgdW50aWwgc29tZSBhc3luY2hyb25vdXMgZXZlbnQgaGFzIGJlZW4gCiAqIHByb2Nlc3NlZC4KICovCnZvaWQgV0lOQVBJIERPU1ZNX1dhaXQoIENPTlRFWFQ4NiAqd2FpdGN0eCApCnsKICAgIGlmIChET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpCiAgICB7CiAgICAgICAgQ09OVEVYVDg2IGNvbnRleHQgPSAqd2FpdGN0eDsKICAgICAgICAKICAgICAgICAvKgogICAgICAgICAqIElmIERPU1ZNX1dhaXQgaXMgY2FsbGVkIGZyb20gcHJvdGVjdGVkIG1vZGUgd2UgZW11bGF0ZQogICAgICAgICAqIGludGVycnVwdCByZWZsZWN0aW9uIGFuZCBjb252ZXJ0IGNvbnRleHQgaW50byByZWFsIG1vZGUgY29udGV4dC4KICAgICAgICAgKiBUaGlzIGlzIGFjdHVhbGx5IHRoZSBjb3JyZWN0IHRoaW5nIHRvIGRvIGFzIGxvbmcgYXMgRE9TVk1fV2FpdAogICAgICAgICAqIGlzIG9ubHkgY2FsbGVkIGZyb20gdGhvc2UgaW50ZXJydXB0IGZ1bmN0aW9ucyB0aGF0IERQTUkgcmVmbGVjdHMKICAgICAgICAgKiB0byByZWFsIG1vZGUuCiAgICAgICAgICoKICAgICAgICAgKiBGSVhNRTogTmVlZCB0byB0aGluayBhYm91dCB3aGVyZSB0byBwbGFjZSByZWFsIG1vZGUgc3RhY2suCiAgICAgICAgICogRklYTUU6IElmIERPU1ZNX1dhaXQgY2FsbHMgYXJlIG5lc3RlZCBzdGFjayBnZXRzIGNvcnJ1cHRlZC4KICAgICAgICAgKiAgICAgICAgQ2FuIHRoaXMgcmVhbGx5IGhhcHBlbj8KICAgICAgICAgKi8KICAgICAgICBpZiAoIUlTVjg2KCZjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnRleHQuRUZsYWdzIHw9IFY4Nl9GTEFHOwogICAgICAgICAgICBjb250ZXh0LlNlZ1NzID0gMHhmZmZmOwogICAgICAgICAgICBjb250ZXh0LkVzcCA9IDA7CiAgICAgICAgfQoKICAgICAgICBjb250ZXh0LkVGbGFncyB8PSBWSUZfTUFTSzsKICAgICAgICBjb250ZXh0LlNlZ0NzID0gMDsKICAgICAgICBjb250ZXh0LkVpcCA9IDA7CgogICAgICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQpOwoKICAgICAgICBpZihjb250ZXh0LlNlZ0NzIHx8IGNvbnRleHQuRWlwKQogICAgICAgICAgICBEUE1JX0NhbGxSTVByb2MoICZjb250ZXh0LCBOVUxMLCAwLCBUUlVFICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgSEFORExFIG9ianNbMl07CiAgICAgICAgaW50ICAgIG9iamMgPSBET1NWTV9Jc1dpbjE2KCkgPyAyIDogMTsKICAgICAgICBEV09SRCAgd2FpdHJldDsKCiAgICAgICAgb2Jqc1swXSA9IGV2ZW50X25vdGlmaWVyOwogICAgICAgIG9ianNbMV0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CgogICAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKCBvYmpjLCBvYmpzLCBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElORklOSVRFLCBRU19BTExJTlBVVCApOwogICAgICAgIAogICAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOZXcgcGVuZGluZyBldmVudCBoYXMgYmVlbiBxdWV1ZWQsIHdlIGlnbm9yZSBpdAogICAgICAgICAgICAgKiBoZXJlIGJlY2F1c2UgaXQgd2lsbCBiZSBwcm9jZXNzZWQgb24gbmV4dCBjYWxsIHRvCiAgICAgICAgICAgICAqIERPU1ZNX1dhaXQuCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChvYmpjID09IDIgJiYgd2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkKICAgICAgICB7CiAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIG9iamMpCiAgICAgICAgewogICAgICAgICAgICBNU0cgbXNnOwogICAgICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogZ290IGEgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgICAgICAvKiB3ZSBkb24ndCBuZWVkIGEgVHJhbnNsYXRlTWVzc2FnZSBoZXJlICovCiAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIEVSUl8obW9kdWxlKSggImRvc3ZtIHdhaXQgZXJyb3I9JWRcbiIsIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgfQogICAgfQp9CgoKRFdPUkQgV0lOQVBJIERPU1ZNX0xvb3AoIEhBTkRMRSBoVGhyZWFkICkKewogIEhBTkRMRSBvYmpzWzJdOwogIE1TRyBtc2c7CiAgRFdPUkQgd2FpdHJldDsKCiAgb2Jqc1swXSA9IEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKTsKICBvYmpzWzFdID0gaFRocmVhZDsKCiAgZm9yKDs7KSB7CiAgICAgIFRSQUNFXyhpbnQpKCJ3YWl0aW5nIGZvciBhY3Rpb25cbiIpOwogICAgICB3YWl0cmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cygyLCBvYmpzLCBGQUxTRSwgSU5GSU5JVEUsIFFTX0FMTElOUFVUKTsKICAgICAgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCkgewogICAgICAgICAgRE9TVk1fUHJvY2Vzc0NvbnNvbGUoKTsKICAgICAgfQogICAgICBlbHNlIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzAgKyAxKSB7CiAgICAgICAgIERXT1JEIHJ2OwogICAgICAgICBpZighR2V0RXhpdENvZGVUaHJlYWQoaFRocmVhZCwgJnJ2KSkgewogICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gZ2V0IHRocmVhZCBleGl0IGNvZGUhXG4iKTsKICAgICAgICAgICAgIHJ2ID0gMDsKICAgICAgICAgfQogICAgICAgICByZXR1cm4gcnY7CiAgICAgIH0KICAgICAgZWxzZSBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMikgewogICAgICAgICAgd2hpbGUgKFBlZWtNZXNzYWdlQSgmbXNnLDAsMCwwLFBNX1JFTU9WRSkpIHsKICAgICAgICAgICAgICBpZiAobXNnLmh3bmQpIHsKICAgICAgICAgICAgICAgICAgLyogaXQncyBhIHdpbmRvdyBtZXNzYWdlICovCiAgICAgICAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NNZXNzYWdlKCZtc2cpOwogICAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIC8qIGl0J3MgYSB0aHJlYWQgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICBzd2l0Y2ggKG1zZy5tZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgV01fUVVJVDoKICAgICAgICAgICAgICAgICAgICAgIC8qIHN0b3AgdGhpcyBtYWRuZXNzISEgKi8KICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICBjYXNlIFdNX1VTRVI6CiAgICAgICAgICAgICAgICAgICAgICAvKiBydW4gcGFzc2VkIHByb2NlZHVyZSBpbiB0aGlzIHRocmVhZCAqLwogICAgICAgICAgICAgICAgICAgICAgLyogKHNvcnQgb2YgbGlrZSBBUEMsIGJ1dCB3ZSBzaWduYWwgdGhlIGNvbXBsZXRpb24pICovCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgRE9TX1NQQyAqc3BjID0gKERPU19TUEMgKiltc2cubFBhcmFtOwogICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFXyhpbnQpKCJjYWxsaW5nICVwIHdpdGggYXJnICUwOGx4XG4iLCBzcGMtPnByb2MsIHNwYy0+YXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAoc3BjLT5wcm9jKShzcGMtPmFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGludCkoImRvbmUsIHNpZ25hbGxpbmcgZXZlbnQgJXhcbiIsIG1zZy53UGFyYW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgIFNldEV2ZW50KCAoSEFORExFKW1zZy53UGFyYW0gKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgIEVSUl8oaW50KSgiTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cyByZXR1cm5lZCB1bmV4cGVjdGVkIHZhbHVlLlxuIik7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgfQogIH0KfQoKc3RhdGljIFdJTkVfRVhDRVBUSU9OX0ZJTFRFUihleGNlcHRpb25faGFuZGxlcikKewogIEVYQ0VQVElPTl9SRUNPUkQgKnJlYyA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkV4Y2VwdGlvblJlY29yZDsKICBDT05URVhUICpjb250ZXh0ID0gR2V0RXhjZXB0aW9uSW5mb3JtYXRpb24oKS0+Q29udGV4dFJlY29yZDsKICBpbnQgYXJnID0gcmVjLT5FeGNlcHRpb25JbmZvcm1hdGlvblswXTsKICBCT09MIHJldDsKCiAgc3dpdGNoKHJlYy0+RXhjZXB0aW9uQ29kZSkgewogIGNhc2UgRVhDRVBUSU9OX1ZNODZfSU5UeDoKICAgIFRSQUNFXyhyZWxheSkoIkNhbGwgRE9TIGludCAweCUwMnggcmV0PSUwNHg6JTA0eFxuIgogICAgICAgICAgICAgICAgICAiIGVheD0lMDh4IGVieD0lMDh4IGVjeD0lMDh4IGVkeD0lMDh4IGVzaT0lMDh4IGVkaT0lMDh4XG4iCiAgICAgICAgICAgICAgICAgICIgZWJwPSUwOHggZXNwPSUwOHggZHM9JTA0eCBlcz0lMDR4IGZzPSUwNHggZ3M9JTA0eCBmbGFncz0lMDh4XG4iLAogICAgICAgICAgICAgICAgICBhcmcsIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAsCiAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwgY29udGV4dC0+RXNpLCBjb250ZXh0LT5FZGksCiAgICAgICAgICAgICAgICAgIGNvbnRleHQtPkVicCwgY29udGV4dC0+RXNwLCBjb250ZXh0LT5TZWdEcywgY29udGV4dC0+U2VnRXMsIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RUZsYWdzICk7CiAgICByZXQgPSBET1NWTV9FbXVsYXRlSW50ZXJydXB0Uk0oIGNvbnRleHQsIGFyZyApOwogICAgVFJBQ0VfKHJlbGF5KSgiUmV0ICBET1MgaW50IDB4JTAyeCByZXQ9JTA0eDolMDR4XG4iCiAgICAgICAgICAgICAgICAgICIgZWF4PSUwOHggZWJ4PSUwOHggZWN4PSUwOHggZWR4PSUwOHggZXNpPSUwOHggZWRpPSUwOHhcbiIKICAgICAgICAgICAgICAgICAgIiBlYnA9JTA4eCBlc3A9JTA4eCBkcz0lMDR4IGVzPSUwNHggZnM9JTA0eCBncz0lMDR4IGZsYWdzPSUwOHhcbiIsCiAgICAgICAgICAgICAgICAgIGFyZywgY29udGV4dC0+U2VnQ3MsIGNvbnRleHQtPkVpcCwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LCBjb250ZXh0LT5Fc2ksIGNvbnRleHQtPkVkaSwKICAgICAgICAgICAgICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKICAgICAgICAgICAgICAgICAgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLCBjb250ZXh0LT5FRmxhZ3MgKTsKICAgIHJldHVybiByZXQgPyBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OIDogRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKCiAgY2FzZSBFWENFUFRJT05fVk04Nl9TVEk6CiAgLyogY2FzZSBFWENFUFRJT05fVk04Nl9QSUNSRVRVUk46ICovCiAgICBpZiAoIUlTVjg2KGNvbnRleHQpKQogICAgICBFUlIoICJQcm90ZWN0ZWQgbW9kZSBTVEkgY2F1Z2h0IGJ5IHJlYWwgbW9kZSBoYW5kbGVyIVxuIiApOwogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhjb250ZXh0KTsKICAgIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OOwogIAogIGNhc2UgRVhDRVBUSU9OX1NJTkdMRV9TVEVQOgogICAgcmV0ID0gRE9TVk1fRW11bGF0ZUludGVycnVwdFJNKCBjb250ZXh0LCAxICk7CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTiA6IEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7CiAgCiAgY2FzZSBFWENFUFRJT05fQlJFQUtQT0lOVDoKICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgMyApOwogICAgcmV0dXJuIHJldCA/IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT04gOiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwogIAogIH0KICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX1NFQVJDSDsKfQoKaW50IFdJTkFQSSBET1NWTV9FbnRlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogIGlmICghSVNWODYoY29udGV4dCkpCiAgICAgIEVSUiggIkNhbGxlZCB3aXRoIHByb3RlY3RlZCBtb2RlIGNvbnRleHQhXG4iICk7CgogIF9fVFJZCiAgewogICAgICBXT1dDYWxsYmFjazE2RXgoIDAsIFdDQjE2X1JFR1MsIDAsIE5VTEwsIChEV09SRCAqKWNvbnRleHQgKTsKICAgICAgVFJBQ0VfKG1vZHVsZSkoICJ2bTg2IHJldHVybmVkOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pICk7CiAgfQogIF9fRVhDRVBUKGV4Y2VwdGlvbl9oYW5kbGVyKQogIHsKICAgIFRSQUNFXyhtb2R1bGUpKCAibGVhdmluZyB2bTg2IG1vZGVcbiIgKTsKICB9CiAgX19FTkRUUlkKCiAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJT3V0UElDIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9QSUNfaW9wb3J0X291dCggV09SRCBwb3J0LCBCWVRFIHZhbCkKewogICAgaWYgKHBvcnQgIT0gMHgyMCkKICAgIHsKICAgICAgICBGSVhNRSggIlVuc3VwcG9ydGVkIFBJQyBwb3J0ICUwNHhcbiIsIHBvcnQgKTsKICAgIH0KICAgIGVsc2UgaWYgKHZhbCA9PSAweDIwIHx8ICh2YWwgPj0gMHg2MCAmJiB2YWwgPD0gMHg2NykpIAogICAgewogICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CgogICAgICAgIGlmICghY3VycmVudF9ldmVudCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oICIlcyB3aXRob3V0IGFjdGl2ZSBJUlFcbiIsCiAgICAgICAgICAgICAgICAgIHZhbCA9PSAweDIwID8gIkVPSSIgOiAiU3BlY2lmaWMgRU9JIiApOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICh2YWwgIT0gMHgyMCAmJiB2YWwgLSAweDYwICE9IGN1cnJlbnRfZXZlbnQtPmlycSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oICJTcGVjaWZpYyBFT0kgYnV0IGN1cnJlbnQgSVJRICVkIGlzIG5vdCAlZFxuIiwgCiAgICAgICAgICAgICAgICAgIGN1cnJlbnRfZXZlbnQtPmlycSwgdmFsIC0gMHg2MCApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBMUERPU0VWRU5UIGV2ZW50ID0gY3VycmVudF9ldmVudDsKCiAgICAgICAgICAgIFRSQUNFKCAiUmVjZWl2ZWQgJXMgZm9yIGN1cnJlbnQgSVJRICVkLCBjbGVhcmluZyBldmVudFxuIiwKICAgICAgICAgICAgICAgICAgIHZhbCA9PSAweDIwID8gIkVPSSIgOiAiU3BlY2lmaWMgRU9JIiwgZXZlbnQtPmlycSApOwoKICAgICAgICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50LT5uZXh0OwogICAgICAgICAgICBpZiAoZXZlbnQtPnJlbGF5KQogICAgICAgICAgICAgICAgKCpldmVudC0+cmVsYXkpKE5VTEwsZXZlbnQtPmRhdGEpOwogICAgICAgICAgICBmcmVlKGV2ZW50KTsKCiAgICAgICAgICAgIGlmIChET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpIAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSggIkFub3RoZXIgZXZlbnQgcGVuZGluZywgc2V0dGluZyBwZW5kaW5nIGZsYWdcbiIgKTsKICAgICAgICAgICAgICAgIE50Q3VycmVudFRlYigpLT52bTg2X3BlbmRpbmcgfD0gVklQX01BU0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICB9IAogICAgZWxzZSAKICAgIHsKICAgICAgICBGSVhNRSggIlVucmVjb2duaXplZCBQSUMgY29tbWFuZCAlMDJ4XG4iLCB2YWwgKTsKICAgIH0KfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFbnRlciAoV0lORURPUy5AKQogKi8KSU5UIFdJTkFQSSBET1NWTV9FbnRlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogRVJSXyhtb2R1bGUpKCJET1MgcmVhbG1vZGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZSFcbiIpOwogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdhaXQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1dhaXQoIENPTlRFWFQ4NiAqd2FpdGN0eCApIHsgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlPdXRQSUMgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKSB7fQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlRdWV1ZUV2ZW50IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9RdWV1ZUV2ZW50KCBJTlQgaXJxLCBJTlQgcHJpb3JpdHksIERPU1JFTEFZIHJlbGF5LCBMUFZPSUQgZGF0YSkKewogIGlmIChpcnE8MCkgewogICAgLyogY2FsbGJhY2sgZXZlbnQsIHBlcmZvcm0gaXQgd2l0aCBkdW1teSBjb250ZXh0ICovCiAgICBDT05URVhUODYgY29udGV4dDsKICAgIG1lbXNldCgmY29udGV4dCwwLHNpemVvZihjb250ZXh0KSk7CiAgICAoKnJlbGF5KSgmY29udGV4dCxkYXRhKTsKICB9IGVsc2UgewogICAgRVJSKCJJUlEgd2l0aG91dCBET1MgdGFzazogc2hvdWxkIG5vdCBoYXBwZW5cbiIpOwogIH0KfQoKI2VuZGlmIC8qIE1aX1NVUFBPUlRFRCAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgRE9TVk1fQWNrbm93bGVkZ2VJUlEKICoKICogVGhpcyByb3V0aW5lIHNob3VsZCBiZSBjYWxsZWQgYnkgYWxsIGludGVybmFsIElSUSBoYW5kbGVycy4KICovCnZvaWQgV0lOQVBJIERPU1ZNX0Fja25vd2xlZGdlSVJRKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICAvKgogICAgICogU2VuZCBFT0kgdG8gUElDLgogICAgICovCiAgICBET1NWTV9QSUNfaW9wb3J0X291dCggMHgyMCwgMHgyMCApOwoKICAgIC8qCiAgICAgKiBQcm90ZWN0ZWQgbW9kZSBJUlEgaGFuZGxlcnMgYXJlIHN1cHBvc2VkCiAgICAgKiB0byB0dXJuIFZJRiBmbGFnIG9uIGJlZm9yZSB0aGV5IHJldHVybi4KICAgICAqLwogICAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+ZHBtaV92aWYgPSAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERsbE1haW4gIChET1NWTS4wKQogKi8KQk9PTCBXSU5BUEkgRGxsTWFpbiggSElOU1RBTkNFIGhpbnN0RExMLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCApCnsKICAgIFRSQUNFXyhtb2R1bGUpKCIoJXAsJWQsJXApXG4iLCBoaW5zdERMTCwgZmR3UmVhc29uLCBscHZSZXNlcnZlZCk7CgogICAgaWYgKGZkd1JlYXNvbiA9PSBETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoaW5zdERMTCk7CiAgICAgICAgaWYgKCFET1NNRU1fSW5pdERvc01lbW9yeSgpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgRE9TVk1fSW5pdFNlZ21lbnRzKCk7CgogICAgICAgIGV2ZW50X25vdGlmaWVyID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgaWYoIWV2ZW50X25vdGlmaWVyKQogICAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGV2ZW50IG9iamVjdCFcbiIpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0K