LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5udC5oIgojaW5jbHVkZSAid2luY29uLmgiCgojaW5jbHVkZSAibXNkb3MuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zdm0uaCIKI2luY2x1ZGUgInN0YWNrZnJhbWUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIm1zdmNydC9leGNwdC5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoaW50KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwoKV09SRCBET1NWTV9wc3AgPSAwOwpXT1JEIERPU1ZNX3JldHZhbCA9IDA7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfVk04Nl9ICiMgaW5jbHVkZSA8c3lzL3ZtODYuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCiNkZWZpbmUgSUZfQ0xSKGN0eCkgICAgICgoY3R4KS0+RUZsYWdzICY9IH5WSUZfTUFTSykKI2RlZmluZSBJRl9TRVQoY3R4KSAgICAgKChjdHgpLT5FRmxhZ3MgfD0gVklGX01BU0spCiNkZWZpbmUgSUZfRU5BQkxFRChjdHgpICgoY3R4KS0+RUZsYWdzICYgVklGX01BU0spCiNkZWZpbmUgU0VUX1BFTkQoY3R4KSAgICgoY3R4KS0+RUZsYWdzIHw9IFZJUF9NQVNLKQojZGVmaW5lIENMUl9QRU5EKGN0eCkgICAoKGN0eCktPkVGbGFncyAmPSB+VklQX01BU0spCiNkZWZpbmUgSVNfUEVORChjdHgpICAgICgoY3R4KS0+RUZsYWdzICYgVklQX01BU0spCgojdW5kZWYgVFJZX1BJQ1JFVFVSTgoKdHlwZWRlZiBzdHJ1Y3QgX0RPU0VWRU5UIHsKICBpbnQgaXJxLHByaW9yaXR5OwogIERPU1JFTEFZIHJlbGF5OwogIHZvaWQgKmRhdGE7CiAgc3RydWN0IF9ET1NFVkVOVCAqbmV4dDsKfSBET1NFVkVOVCwgKkxQRE9TRVZFTlQ7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBxY3JpdCA9IENSSVRJQ0FMX1NFQ1RJT05fSU5JVCgiRE9TVk0iKTsKc3RhdGljIHN0cnVjdCBfRE9TRVZFTlQgKnBlbmRpbmdfZXZlbnQsICpjdXJyZW50X2V2ZW50OwpzdGF0aWMgaW50IHNpZ19zZW50OwpzdGF0aWMgSEFORExFIGV2ZW50X25vdGlmaWVyOwpzdGF0aWMgQ09OVEVYVDg2ICpjdXJyZW50X2NvbnRleHQ7CgpzdGF0aWMgaW50IERPU1ZNX1NpbXVsYXRlSW50KCBpbnQgdmVjdCwgQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGlud2luZSApCnsKICBGQVJQUk9DMTYgaGFuZGxlcj1ET1NWTV9HZXRSTUhhbmRsZXIodmVjdCk7CgogIC8qIGNoZWNrIGZvciBvdXIgcmVhbC1tb2RlIGhvb2tzICovCiAgaWYgKHZlY3Q9PTB4MzEpIHsKICAgIGlmIChjb250ZXh0LT5TZWdDcz09RE9TTUVNX3dyYXBfc2VnKSB7CiAgICAgIC8qIGV4aXQgZnJvbSByZWFsLW1vZGUgd3JhcHBlciAqLwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICAvKiB3ZSBjb3VsZCBwcm9iYWJseSBtb3ZlIHNvbWUgb3RoZXIgZG9kZ3kgc3R1ZmYgaGVyZSB0b28gZnJvbSBkcG1pLmMgKi8KICB9CiAgLyogY2hlY2sgaWYgdGhlIGNhbGwgaXMgZnJvbSBvdXIgZmFrZSBCSU9TIGludGVycnVwdCBzdHVicyAqLwogIGlmICgoY29udGV4dC0+U2VnQ3M9PTB4ZjAwMCkgJiYgIWlud2luZSkgewogICAgaWYgKHZlY3QgIT0gKGNvbnRleHQtPkVpcC80KSkgewogICAgICBUUkFDRSgic29tZXRoaW5nIGZpc2h5IGdvaW5nIG9uIGhlcmUgKGludGVycnVwdCBzdHViIGlzICUwMmx4KVxuIiwgY29udGV4dC0+RWlwLzQpOwogICAgfQogICAgVFJBQ0UoImJ1aWx0aW4gaW50ZXJydXB0ICUwMnggaGFzIGJlZW4gYnJhbmNoZWQgdG9cbiIsIHZlY3QpOwogICAgRE9TVk1fUmVhbE1vZGVJbnRlcnJ1cHQodmVjdCwgY29udGV4dCk7CiAgfQogIC8qIGNoZWNrIGlmIHRoZSBjYWxsIGdvZXMgdG8gYW4gdW5ob29rZWQgaW50ZXJydXB0ICovCiAgZWxzZSBpZiAoU0VMRUNUT1JPRihoYW5kbGVyKT09MHhmMDAwKSB7CiAgICAvKiBpZiBzbywgY2FsbCBpdCBkaXJlY3RseSAqLwogICAgVFJBQ0UoImJ1aWx0aW4gaW50ZXJydXB0ICUwMnggaGFzIGJlZW4gaW52b2tlZCAodGhyb3VnaCB2ZWN0b3IgJTAyeClcbiIsIE9GRlNFVE9GKGhhbmRsZXIpLzQsIHZlY3QpOwogICAgRE9TVk1fUmVhbE1vZGVJbnRlcnJ1cHQoT0ZGU0VUT0YoaGFuZGxlcikvNCwgY29udGV4dCk7CiAgfQogIC8qIHRoZSBpbnRlcnJ1cHQgaXMgaG9va2VkLCBzaW11bGF0ZSBpbnRlcnJ1cHQgaW4gRE9TIHNwYWNlICovCiAgZWxzZSB7CiAgICBXT1JEKnN0YWNrPSBQVFJfUkVBTF9UT19MSU4oIGNvbnRleHQtPlNlZ1NzLCBjb250ZXh0LT5Fc3AgKTsKICAgIFdPUkQgZmxhZz1MT1dPUkQoY29udGV4dC0+RUZsYWdzKTsKCiAgICBUUkFDRV8oaW50KSgiaW52b2tpbmcgaG9va2VkIGludGVycnVwdCAlMDJ4IGF0ICUwNHg6JTA0eFxuIiwgdmVjdCwKCQlTRUxFQ1RPUk9GKGhhbmRsZXIpLCBPRkZTRVRPRihoYW5kbGVyKSk7CiAgICBpZiAoSUZfRU5BQkxFRChjb250ZXh0KSkgZmxhZ3w9SUZfTUFTSzsKICAgIGVsc2UgZmxhZyY9fklGX01BU0s7CgogICAgKigtLXN0YWNrKT1mbGFnOwogICAgKigtLXN0YWNrKT1jb250ZXh0LT5TZWdDczsKICAgICooLS1zdGFjayk9TE9XT1JEKGNvbnRleHQtPkVpcCk7CiAgICBjb250ZXh0LT5Fc3AtPTY7CiAgICBjb250ZXh0LT5TZWdDcz1TRUxFQ1RPUk9GKGhhbmRsZXIpOwogICAgY29udGV4dC0+RWlwPU9GRlNFVE9GKGhhbmRsZXIpOwogICAgSUZfQ0xSKGNvbnRleHQpOwogIH0KICByZXR1cm4gMDsKfQoKI2RlZmluZSBTSE9VTERfUEVORCh4KSBcCiAgKHggJiYgKCghY3VycmVudF9ldmVudCkgfHwgKHgtPnByaW9yaXR5IDwgY3VycmVudF9ldmVudC0+cHJpb3JpdHkpKSkKCnN0YXRpYyB2b2lkIERPU1ZNX1NlbmRRdWV1ZWRFdmVudChDT05URVhUODYgKmNvbnRleHQpCnsKICBMUERPU0VWRU5UIGV2ZW50ID0gcGVuZGluZ19ldmVudDsKCiAgaWYgKFNIT1VMRF9QRU5EKGV2ZW50KSkgewogICAgLyogcmVtb3ZlIGZyb20gInBlbmRpbmciIGxpc3QgKi8KICAgIHBlbmRpbmdfZXZlbnQgPSBldmVudC0+bmV4dDsKICAgIC8qIHByb2Nlc3MgZXZlbnQgKi8KICAgIGlmIChldmVudC0+aXJxPj0wKSB7CiAgICAgIC8qIGl0J3MgYW4gSVJRLCBtb3ZlIGl0IHRvICJjdXJyZW50IiBsaXN0ICovCiAgICAgIGV2ZW50LT5uZXh0ID0gY3VycmVudF9ldmVudDsKICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50OwogICAgICBUUkFDRSgiZGlzcGF0Y2hpbmcgSVJRICVkXG4iLGV2ZW50LT5pcnEpOwogICAgICAvKiBub3RlIHRoYXQgaWYgRE9TVk1fU2ltdWxhdGVJbnQgY2FsbHMgYW4gaW50ZXJuYWwgaW50ZXJydXB0IGRpcmVjdGx5LAogICAgICAgKiBjdXJyZW50X2V2ZW50IG1pZ2h0IGJlIGNsZWFyZWQgKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyB2ZXJ5IGNhbGwhICovCiAgICAgIERPU1ZNX1NpbXVsYXRlSW50KChldmVudC0+aXJxPDgpPyhldmVudC0+aXJxKzgpOihldmVudC0+aXJxLTgrMHg3MCksY29udGV4dCxUUlVFKTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50ICovCiAgICAgIFRSQUNFKCJkaXNwYXRjaGluZyBjYWxsYmFjayBldmVudFxuIik7CiAgICAgICgqZXZlbnQtPnJlbGF5KShjb250ZXh0LGV2ZW50LT5kYXRhKTsKICAgICAgZnJlZShldmVudCk7CiAgICB9CiAgfQogIGlmICghU0hPVUxEX1BFTkQocGVuZGluZ19ldmVudCkpIHsKICAgIFRSQUNFKCJjbGVhcmluZyBQZW5kaW5nIGZsYWdcbiIpOwogICAgQ0xSX1BFTkQoY29udGV4dCk7CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9TZW5kUXVldWVkRXZlbnRzKENPTlRFWFQ4NiAqY29udGV4dCkKewogIC8qIHdlIHdpbGwgc2VuZCBhbGwgcXVldWVkIGV2ZW50cyBhcyBsb25nIGFzIGludGVycnVwdHMgYXJlIGVuYWJsZWQsCiAgICogYnV0IElSUSBldmVudHMgd2lsbCBkaXNhYmxlIGludGVycnVwdHMgYWdhaW4gKi8KICB3aGlsZSAoSVNfUEVORChjb250ZXh0KSAmJiBJRl9FTkFCTEVEKGNvbnRleHQpKQogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50KGNvbnRleHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVF1ZXVlRXZlbnQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1F1ZXVlRXZlbnQoIElOVCBpcnEsIElOVCBwcmlvcml0eSwgRE9TUkVMQVkgcmVsYXksIExQVk9JRCBkYXRhKQp7CiAgTFBET1NFVkVOVCBldmVudCwgY3VyLCBwcmV2OwoKICBpZiAoY3VycmVudF9jb250ZXh0KSB7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgZXZlbnQgPSBtYWxsb2Moc2l6ZW9mKERPU0VWRU5UKSk7CiAgICBpZiAoIWV2ZW50KSB7CiAgICAgIEVSUigib3V0IG9mIG1lbW9yeSBhbGxvY2F0aW5nIGV2ZW50IGVudHJ5XG4iKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgZXZlbnQtPmlycSA9IGlycTsgZXZlbnQtPnByaW9yaXR5ID0gcHJpb3JpdHk7CiAgICBldmVudC0+cmVsYXkgPSByZWxheTsgZXZlbnQtPmRhdGEgPSBkYXRhOwoKICAgIC8qIGluc2VydCBldmVudCBpbnRvIGxpbmtlZCBsaXN0LCBpbiBvcmRlciAqYWZ0ZXIqCiAgICAgKiBhbGwgZWFybGllciBldmVudHMgb2YgaGlnaGVyIG9yIGVxdWFsIHByaW9yaXR5ICovCiAgICBjdXIgPSBwZW5kaW5nX2V2ZW50OyBwcmV2ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgJiYgY3VyLT5wcmlvcml0eTw9cHJpb3JpdHkpIHsKICAgICAgcHJldiA9IGN1cjsKICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgZXZlbnQtPm5leHQgPSBjdXI7CiAgICBpZiAocHJldikgcHJldi0+bmV4dCA9IGV2ZW50OwogICAgZWxzZSBwZW5kaW5nX2V2ZW50ID0gZXZlbnQ7CgogICAgLyogYWxlcnQgdGhlIHZtODYgYWJvdXQgdGhlIG5ldyBldmVudCAqLwogICAgaWYgKCFzaWdfc2VudCkgewogICAgICBUUkFDRSgibmV3IGV2ZW50IHF1ZXVlZCwgc2lnbmFsbGluZyAodGltZT0lbGQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICAgIGtpbGwoZG9zdm1fcGlkLFNJR1VTUjIpOwogICAgICBzaWdfc2VudCsrOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQgKHRpbWU9JWxkKVxuIiwgR2V0VGlja0NvdW50KCkpOwogICAgfQogICAgCiAgICAvKiBXYWtlIHVwIERPU1ZNX1dhaXQgc28gdGhhdCBpdCBjYW4gc2VydmUgcGVuZGluZyBldmVudHMuICovCiAgICBTZXRFdmVudChldmVudF9ub3RpZmllcik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICB9IGVsc2UgewogICAgLyogRE9TIHN1YnN5c3RlbSBub3QgcnVubmluZyAqLwogICAgLyogKHRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB3ZSdyZSBydW5uaW5nIGEgd2luMTYgYXBwCiAgICAgKiAgd2hpY2ggdXNlcyBEUE1JIHRvIHRodW5rIGRvd24gdG8gRE9TIHNlcnZpY2VzKSAqLwogICAgaWYgKGlycTwwKSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgICBDT05URVhUODYgY29udGV4dDsKICAgICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlbiIpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc0NvbnNvbGUodm9pZCkKewogIElOUFVUX1JFQ09SRCBtc2c7CiAgRFdPUkQgcmVzOwogIEJZVEUgc2NhbjsKCiAgaWYgKFJlYWRDb25zb2xlSW5wdXRBKEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKSwmbXNnLDEsJnJlcykpIHsKICAgIHN3aXRjaCAobXNnLkV2ZW50VHlwZSkgewogICAgY2FzZSBLRVlfRVZFTlQ6CiAgICAgIHNjYW4gPSBtc2cuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZTsKICAgICAgaWYgKCFtc2cuRXZlbnQuS2V5RXZlbnQuYktleURvd24pIHNjYW4gfD0gMHg4MDsKCiAgICAgIC8qIGNoZWNrIHdoZXRoZXIgZXh0ZW5kZWQgYml0IGlzIHNldCwKICAgICAgICogYW5kIGlmIHNvLCBxdWV1ZSB0aGUgZXh0ZW5zaW9uIHByZWZpeCAqLwogICAgICBpZiAobXNnLkV2ZW50LktleUV2ZW50LmR3Q29udHJvbEtleVN0YXRlICYgRU5IQU5DRURfS0VZKSB7CiAgICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbigweEUwLDApOwogICAgICB9CiAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oc2Nhbixtc2cuRXZlbnQuS2V5RXZlbnQudUNoYXIuQXNjaWlDaGFyKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1PVVNFX0VWRU5UOgogICAgICBET1NWTV9JbnQzM0NvbnNvbGUoJm1zZy5FdmVudC5Nb3VzZUV2ZW50KTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkRPV19CVUZGRVJfU0laRV9FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1FTlVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgTUVOVV9FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGNhc2UgRk9DVVNfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgRk9DVVNfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5rbm93biBjb25zb2xlIGV2ZW50OiAlZFxuIiwgbXNnLkV2ZW50VHlwZSk7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzTWVzc2FnZShNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIFRSQUNFKCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4eCwgbHBhcmFtPSUwOGx4XG4iLG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgaWYgKChtc2ctPm1lc3NhZ2U+PVdNX01PVVNFRklSU1QpJiYKICAgICAgKG1zZy0+bWVzc2FnZTw9V01fTU9VU0VMQVNUKSkgewogICAgRE9TVk1fSW50MzNNZXNzYWdlKG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgfSBlbHNlIHsKICAgIHN3aXRjaCAobXNnLT5tZXNzYWdlKSB7CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICBzY2FuID0gMHg4MDsKICAgIGNhc2UgV01fS0VZRE9XTjoKICAgICAgc2NhbiB8PSAobXNnLT5sUGFyYW0gPj4gMTYpICYgMHg3ZjsKCiAgICAgIC8qIGNoZWNrIHdoZXRoZXIgZXh0ZW5kZWQgYml0IGlzIHNldCwKICAgICAgICogYW5kIGlmIHNvLCBxdWV1ZSB0aGUgZXh0ZW5zaW9uIHByZWZpeCAqLwogICAgICBpZiAobXNnLT5sUGFyYW0gJiAweDEwMDAwMDApIHsKCS8qIEZJWE1FOiBzb21lIGtleXMgKGZ1bmN0aW9uIGtleXMpIGhhdmUKCSAqIGV4dGVuZGVkIGJpdCBzZXQgZXZlbiB3aGVuIHRoZXkgc2hvdWxkbid0LAoJICogc2hvdWxkIGNoZWNrIGZvciB0aGVtICovCglET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLDApOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggSU5UIHJlYWRfcGlwZSwgSEFORExFIGhPYmplY3QgKQp7CiAgTVNHIG1zZzsKICBEV09SRCB3YWl0cmV0OwogIEhBTkRMRSBvYmpzWzNdOwogIGludCBvYmpjOwogIEJPT0wgZ290X21zZyA9IEZBTFNFOwoKICBvYmpzWzBdPUdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKTsKICBvYmpzWzFdPWV2ZW50X25vdGlmaWVyOwogIG9ianNbMl09aE9iamVjdDsKICBvYmpjPWhPYmplY3Q/MzoyOwogIGRvIHsKICAgIC8qIGNoZWNrIGZvciBtZXNzYWdlcyAod2FzdGUgdGltZSBiZWZvcmUgdGhlIHJlc3BvbnNlIGNoZWNrIGJlbG93KSAqLwogICAgaWYgKFBlZWtNZXNzYWdlQSkKICAgIHsKICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSB7CiAgICAgICAgICAgIC8qIGdvdCBhIG1lc3NhZ2UgKi8KICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgIC8qIHdlIGRvbid0IG5lZWQgYSBUcmFuc2xhdGVNZXNzYWdlIGhlcmUgKi8KICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgZ290X21zZyA9IFRSVUU7CiAgICAgICAgfQogICAgfQpjaGtfY29uc29sZV9pbnB1dDoKICAgIGlmICghZ290X21zZykgewogICAgICAvKiBjaGVjayBmb3IgY29uc29sZSBpbnB1dCAqLwogICAgICBJTlBVVF9SRUNPUkQgbXNnOwogICAgICBEV09SRCBudW07CiAgICAgIGlmIChQZWVrQ29uc29sZUlucHV0QShvYmpzWzBdLCZtc2csMSwmbnVtKSAmJiBudW0pIHsKICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICAgIGdvdF9tc2cgPSBUUlVFOwogICAgICB9CiAgICB9CiAgICBpZiAocmVhZF9waXBlID09IC0xKSB7CiAgICAgIC8qIGRpc3BhdGNoIHBlbmRpbmcgZXZlbnRzICovCiAgICAgIGlmIChTSE9VTERfUEVORChwZW5kaW5nX2V2ZW50KSkgewogICAgICAgIENPTlRFWFQ4NiBjb250ZXh0ID0gKmN1cnJlbnRfY29udGV4dDsKICAgICAgICBJRl9TRVQoJmNvbnRleHQpOwogICAgICAgIFNFVF9QRU5EKCZjb250ZXh0KTsKICAgICAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCZjb250ZXh0KTsKICAgICAgICBnb3RfbXNnID0gVFJVRTsKICAgICAgfQogICAgICBpZiAoZ290X21zZykgYnJlYWs7CiAgICB9IGVsc2UgewogICAgICBmZF9zZXQgcmVhZGZkczsKICAgICAgc3RydWN0IHRpbWV2YWwgdGltZW91dD17MCwwfTsKICAgICAgLyogcXVpY2sgY2hlY2sgZm9yIHJlc3BvbnNlIGZyb20gZG9zbW9kCiAgICAgICAqIChmYXN0ZXIgdGhhbiBkb2luZyB0aGUgZnVsbCBibG9ja2luZyB3YWl0LCBpZiBkYXRhIGFscmVhZHkgYXZhaWxhYmxlKSAqLwogICAgICBGRF9aRVJPKCZyZWFkZmRzKTsgRkRfU0VUKHJlYWRfcGlwZSwmcmVhZGZkcyk7CiAgICAgIGlmIChzZWxlY3QocmVhZF9waXBlKzEsJnJlYWRmZHMsTlVMTCxOVUxMLCZ0aW1lb3V0KT4wKQoJYnJlYWs7CiAgICB9CiAgICAvKiBub3RoaW5nIHlldCwgYmxvY2sgd2hpbGUgd2FpdGluZyBmb3Igc29tZXRoaW5nIHRvIGRvICovCiAgICBpZiAoTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cykKICAgICAgICB3YWl0cmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cyhvYmpjLG9ianMsRkFMU0UsSU5GSU5JVEUsUVNfQUxMSU5QVVQpOwogICAgZWxzZQogICAgICAgIHdhaXRyZXQgPSBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKG9iamMsb2JqcyxGQUxTRSxJTkZJTklURSk7CgogICAgaWYgKHdhaXRyZXQ9PShEV09SRCktMSkgewogICAgICBFUlJfKG1vZHVsZSkoImRvc3ZtIHdhaXQgZXJyb3I9JWxkXG4iLEdldExhc3RFcnJvcigpKTsKICAgIH0KICAgIGlmICgocmVhZF9waXBlICE9IC0xKSAmJiBoT2JqZWN0KSB7CiAgICAgIGlmICh3YWl0cmV0PT0oV0FJVF9PQkpFQ1RfMCsyKSkgYnJlYWs7CiAgICB9CiAgICBpZiAod2FpdHJldD09V0FJVF9PQkpFQ1RfMCkKICAgICAgZ290byBjaGtfY29uc29sZV9pbnB1dDsKICB9IHdoaWxlIChUUlVFKTsKfQoKRFdPUkQgV0lOQVBJIERPU1ZNX0xvb3AoIExQVk9JRCBscEV4dHJhICkKewogIEhBTkRMRSBvYmogPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgTVNHIG1zZzsKICBEV09SRCB3YWl0cmV0OwoKICBmb3IoOzspIHsKICAgICAgVFJBQ0VfKGludCkoIndhaXRpbmcgZm9yIGFjdGlvblxuIik7CiAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsICZvYmosIEZBTFNFLCBJTkZJTklURSwgUVNfQUxMSU5QVVQpOwogICAgICBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgICAgICBET1NWTV9Qcm9jZXNzQ29uc29sZSgpOwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpIHsKICAgICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkUpKSB7CiAgICAgICAgICAgICAgaWYgKG1zZy5od25kKSB7CiAgICAgICAgICAgICAgICAgIC8qIGl0J3MgYSB3aW5kb3cgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgdGhyZWFkIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgc3dpdGNoIChtc2cubWVzc2FnZSkgewogICAgICAgICAgICAgICAgICBjYXNlIFdNX1FVSVQ6CiAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9wIHRoaXMgbWFkbmVzcyEhICovCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9VU0VSOgogICAgICAgICAgICAgICAgICAgICAgLyogcnVuIHBhc3NlZCBwcm9jZWR1cmUgaW4gdGhpcyB0aHJlYWQgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIChzb3J0IG9mIGxpa2UgQVBDLCBidXQgd2Ugc2lnbmFsIHRoZSBjb21wbGV0aW9uKSAqLwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIERPU19TUEMgKnNwYyA9IChET1NfU1BDICopbXNnLmxQYXJhbTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiY2FsbGluZyAlcCB3aXRoIGFyZyAlMDh4XG4iLCBzcGMtPnByb2MsIHNwYy0+YXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAoc3BjLT5wcm9jKShzcGMtPmFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGludCkoImRvbmUsIHNpZ25hbGxpbmcgZXZlbnQgJWRcbiIsIG1zZy53UGFyYW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgIFNldEV2ZW50KG1zZy53UGFyYW0pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgICBFUlJfKGludCkoIk1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMgcmV0dXJuZWQgdW5leHBlY3RlZCB2YWx1ZS5cbiIpOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICB9Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIoZXhjZXB0aW9uX2hhbmRsZXIpCnsKICBFWENFUFRJT05fUkVDT1JEICpyZWMgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5FeGNlcHRpb25SZWNvcmQ7CiAgQ09OVEVYVCAqY29udGV4dCA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkNvbnRleHRSZWNvcmQ7CiAgaW50IHJldCwgYXJnID0gcmVjLT5FeGNlcHRpb25JbmZvcm1hdGlvblswXTsKCiAgc3dpdGNoKHJlYy0+RXhjZXB0aW9uQ29kZSkgewogIGNhc2UgRVhDRVBUSU9OX1ZNODZfSU5UeDoKICAgIGlmIChUUkFDRV9PTihyZWxheSkpIHsKICAgICAgRFBSSU5URigiQ2FsbCBET1MgaW50IDB4JTAyeCByZXQ9JTA0bHg6JTA0bHhcbiIsCgkgICAgICBhcmcsIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAgKTsKICAgICAgRFBSSU5URigiIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseCBlc2k9JTA4bHggZWRpPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LAoJICAgICAgY29udGV4dC0+RXNpLCBjb250ZXh0LT5FZGkgKTsKICAgICAgRFBSSU5URigiIGVicD0lMDhseCBlc3A9JTA4bHggZHM9JTA0bHggZXM9JTA0bHggZnM9JTA0bHggZ3M9JTA0bHggZmxhZ3M9JTA4bHhcbiIsCgkgICAgICBjb250ZXh0LT5FYnAsIGNvbnRleHQtPkVzcCwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzLAoJICAgICAgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLCBjb250ZXh0LT5FRmxhZ3MgKTsKICAgICAgfQogICAgcmV0ID0gRE9TVk1fU2ltdWxhdGVJbnQoYXJnLCBjb250ZXh0LCBGQUxTRSk7CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICB9CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUiA6IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CgogIGNhc2UgRVhDRVBUSU9OX1ZNODZfU1RJOgogIC8qIGNhc2UgRVhDRVBUSU9OX1ZNODZfUElDUkVUVVJOOiAqLwogICAgSUZfU0VUKGNvbnRleHQpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIHNpZ19zZW50Kys7CiAgICB3aGlsZSAoTnRDdXJyZW50VGViKCktPmFsYXJtcykgewogICAgICBET1NWTV9RdWV1ZUV2ZW50KDAsRE9TX1BSSU9SSVRZX1JFQUxUSU1FLE5VTEwsTlVMTCk7CiAgICAgIC8qIGhtbSwgaW5zdGVhZCBvZiByZWx5aW5nIG9uIHRoaXMgc2lnbmFsIGNvdW50ZXIsIHdlIHNob3VsZAogICAgICAgKiBwcm9iYWJseSBjaGVjayBob3cgbWFueSB0aWNrcyBoYXZlICpyZWFsbHkqIHBhc3NlZCwgcHJvYmFibHkgdXNpbmcKICAgICAgICogUXVlcnlQZXJmb3JtYW5jZUNvdW50ZXIoKSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCYoTnRDdXJyZW50VGViKCktPmFsYXJtcykpOwogICAgfQogICAgVFJBQ0VfKGludCkoImNvbnRleHQ9JXAsIGN1cnJlbnQ9JXBcbiIsIGNvbnRleHQsIGN1cnJlbnRfY29udGV4dCk7CiAgICBUUkFDRV8oaW50KSgiY3M6aXA9JTA0bHg6JTA0bHgsIHNzOnNwPSUwNGx4OiUwNGx4XG4iLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwKTsKICAgIGlmICghSVNWODYoY29udGV4dCkpIHsKICAgICAgRVJSXyhpbnQpKCJAIyYqJSUsIHdpbmVkb3Mgc2lnbmFsIGhhbmRsaW5nIGlzICpzdGlsbCogbWVzc2VkIHVwXG4iKTsKICAgIH0KICAgIFRSQUNFXyhpbnQpKCJET1MgdGFzayBlbmFibGVkIGludGVycnVwdHMgJXMgZXZlbnRzIHBlbmRpbmcsIHNlbmRpbmcgZXZlbnRzICh0aW1lPSVsZClcbiIsIElTX1BFTkQoY29udGV4dCk/IndpdGgiOiJ3aXRob3V0IiwgR2V0VGlja0NvdW50KCkpOwogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhjb250ZXh0KTsKICAgIHNpZ19zZW50PTA7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CiAgfQogIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfU0VBUkNIOwp9CgppbnQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgQ09OVEVYVDg2ICpvbGRfY29udGV4dCA9IGN1cnJlbnRfY29udGV4dDsKCiAgY3VycmVudF9jb250ZXh0ID0gY29udGV4dDsKICBfX1RSWQogIHsKICAgIF9fd2luZV9lbnRlcl92bTg2KCBjb250ZXh0ICk7CiAgICBUUkFDRV8obW9kdWxlKSggInZtODYgcmV0dXJuZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykgKTsKICB9CiAgX19FWENFUFQoZXhjZXB0aW9uX2hhbmRsZXIpCiAgewogICAgVFJBQ0VfKG1vZHVsZSkoICJsZWF2aW5nIHZtODYgbW9kZVxuIiApOwogIH0KICBfX0VORFRSWQogIGN1cnJlbnRfY29udGV4dCA9IG9sZF9jb250ZXh0OwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICAgIExQRE9TRVZFTlQgZXZlbnQ7CgogICAgaWYgKChwb3J0PT0weDIwKSAmJiAodmFsPT0weDIwKSkgewogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICBpZiAoY3VycmVudF9ldmVudCkgewoJLyogRU9JIChFbmQgT2YgSW50ZXJydXB0KSAqLwoJVFJBQ0UoInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gY3VycmVudF9ldmVudDsKCWN1cnJlbnRfZXZlbnQgPSBldmVudC0+bmV4dDsKCWlmIChldmVudC0+cmVsYXkpCgkoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CglmcmVlKGV2ZW50KTsKCglpZiAocGVuZGluZ19ldmVudCkgewoJICAvKiBhbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHdoaWNoIHdlIHNob3VsZCBwcm9iYWJseQoJICAgKiBiZSBhYmxlIHRvIHByb2Nlc3Mgbm93ICovCgkgIFRSQUNFKCJhbm90aGVyIGV2ZW50IHBlbmRpbmcsIHNldHRpbmcgZmxhZ1xuIik7CgkgIGN1cnJlbnRfY29udGV4dC0+RUZsYWdzIHw9IFZJUF9NQVNLOwoJfQogICAgICB9IGVsc2UgewoJV0FSTigiRU9JIHdpdGhvdXQgYWN0aXZlIElSUVxuIik7CiAgICAgIH0KICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIH0gZWxzZSB7CiAgICAgIEZJWE1FKCJ1bnJlY29nbml6ZWQgUElDIGNvbW1hbmQgJTAyeFxuIix2YWwpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApCnsKICBzdHJ1Y3QgaXRpbWVydmFsIHRpbTsKCiAgaWYgKGRvc3ZtX3BpZCkgewogICAgLyogdGhlIFBDIGNsb2NrcyB0aWNrcyBhdCAxMTkzMTgwIEh6ICovCiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfc2VjPTA7CiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYz1NdWxEaXYodGlja3MsMTAwMDAwMCwxMTkzMTgwKTsKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKCF0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYykgdGltLml0X2ludGVydmFsLnR2X3VzZWM9MTsKICAgIC8qIGZpcnN0IHRpY2sgdmFsdWUgKi8KICAgIHRpbS5pdF92YWx1ZSA9IHRpbS5pdF9pbnRlcnZhbDsKICAgIFRSQUNFXyhpbnQpKCJzZXR0aW5nIHRpbWVyIHRpY2sgZGVsYXkgdG8gJWxkIHVzXG4iLCB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYyk7CiAgICBzZXRpdGltZXIoSVRJTUVSX1JFQUwsICZ0aW0sIE5VTEwpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRUaW1lciAoV0lORURPUy5AKQogKi8KVUlOVCBXSU5BUEkgRE9TVk1fR2V0VGltZXIoIHZvaWQgKQp7CiAgc3RydWN0IGl0aW1lcnZhbCB0aW07CgogIGlmIChkb3N2bV9waWQpIHsKICAgIGdldGl0aW1lcihJVElNRVJfUkVBTCwgJnRpbSk7CiAgICByZXR1cm4gTXVsRGl2KHRpbS5pdF92YWx1ZS50dl91c2VjLDExOTMxODAsMTAwMDAwMCk7CiAgfQogIHJldHVybiAwOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVudGVyIChXSU5FRE9TLkApCiAqLwpJTlQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiBFUlJfKG1vZHVsZSkoIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggSU5UIHJlYWRfcGlwZSwgSEFORExFIGhPYmplY3QpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFRpbWVyIChXSU5FRE9TLkApCiAqLwpVSU5UIFdJTkFQSSBET1NWTV9HZXRUaW1lciggdm9pZCApIHsgcmV0dXJuIDA7IH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBpZiAoaXJxPDApIHsKICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICBtZW1zZXQoJmNvbnRleHQsMCxzaXplb2YoY29udGV4dCkpOwogICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgfSBlbHNlIHsKICAgIEVSUigiSVJRIHdpdGhvdXQgRE9TIHRhc2s6IHNob3VsZCBub3QgaGFwcGVuIik7CiAgfQp9CgojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9HZXRSTUhhbmRsZXIKICoKICogUmV0dXJuIHRoZSByZWFsIG1vZGUgaW50ZXJydXB0IHZlY3RvciBmb3IgYSBnaXZlbiBpbnRlcnJ1cHQuCiAqLwpGQVJQUk9DMTYgRE9TVk1fR2V0Uk1IYW5kbGVyKCBCWVRFIGludG51bSApCnsKICAgIHJldHVybiAoKEZBUlBST0MxNiopRE9TTUVNX1N5c3RlbUJhc2UoKSlbaW50bnVtXTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9TZXRSTUhhbmRsZXIKICoKICogU2V0IHRoZSByZWFsIG1vZGUgaW50ZXJydXB0IGhhbmRsZXIgZm9yIGEgZ2l2ZW4gaW50ZXJydXB0LgogKi8Kdm9pZCBET1NWTV9TZXRSTUhhbmRsZXIoIEJZVEUgaW50bnVtLCBGQVJQUk9DMTYgaGFuZGxlciApCnsKICAgIFRSQUNFKCJTZXQgcmVhbCBtb2RlIGludGVycnVwdCB2ZWN0b3IgJTAyeCA8LSAlMDR4OiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgaW50bnVtLCBISVdPUkQoaGFuZGxlciksIExPV09SRChoYW5kbGVyKSApOwogICAgKChGQVJQUk9DMTYqKURPU01FTV9TeXN0ZW1CYXNlKCkpW2ludG51bV0gPSBoYW5kbGVyOwp9CgoKc3RhdGljIGNvbnN0IElOVFBST0MgcmVhbF9tb2RlX2hhbmRsZXJzW10gPQp7CiAgICAvKiAwMCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMDggKi8gMCwgRE9TVk1fSW50MDlIYW5kbGVyLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMTAgKi8gRE9TVk1fSW50MTBIYW5kbGVyLCBJTlRfSW50MTFIYW5kbGVyLCBJTlRfSW50MTJIYW5kbGVyLCBJTlRfSW50MTNIYW5kbGVyLAogICAgICAgICAgICAgMCwgSU5UX0ludDE1SGFuZGxlciwgRE9TVk1fSW50MTZIYW5kbGVyLCBET1NWTV9JbnQxN0hhbmRsZXIsCiAgICAvKiAxOCAqLyAwLCAwLCBJTlRfSW50MWFIYW5kbGVyLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMjAgKi8gRE9TVk1fSW50MjBIYW5kbGVyLCBET1NWTV9JbnQyMUhhbmRsZXIsIDAsIDAsIDAsIElOVF9JbnQyNUhhbmRsZXIsIDAsIDAsCiAgICAvKiAyOCAqLyAwLCBET1NWTV9JbnQyOUhhbmRsZXIsIElOVF9JbnQyYUhhbmRsZXIsIDAsIDAsIDAsIDAsIElOVF9JbnQyZkhhbmRsZXIsCiAgICAvKiAzMCAqLyAwLCBET1NWTV9JbnQzMUhhbmRsZXIsIDAsIERPU1ZNX0ludDMzSGFuZGxlciwgMCwgMCwgMCwgMCwKICAgIC8qIDM4ICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiA0MCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogNDggKi8gMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCiAgICAvKiA1MCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogNTggKi8gMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKICAgIC8qIDYwICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIERPU1ZNX0ludDY3SGFuZGxlcgp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9SZWFsTW9kZUludGVycnVwdAogKgogKiBIYW5kbGUgcmVhbCBtb2RlIGludGVycnVwdHMKICovCnZvaWQgRE9TVk1fUmVhbE1vZGVJbnRlcnJ1cHQoIEJZVEUgaW50bnVtLCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBpZiAoaW50bnVtIDwgc2l6ZW9mKHJlYWxfbW9kZV9oYW5kbGVycykvc2l6ZW9mKElOVFBST0MpICYmIHJlYWxfbW9kZV9oYW5kbGVyc1tpbnRudW1dKQogICAgICAgICgqcmVhbF9tb2RlX2hhbmRsZXJzW2ludG51bV0pKGNvbnRleHQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJVbmtub3duIEludGVycnVwdCBpbiBET1MgbW9kZTogMHgleFxuIiwgaW50bnVtKTsKICAgICAgICBGSVhNRSgiICAgIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseFxuIiwKICAgICAgICAgICAgICBjb250ZXh0LT5FYXgsIGNvbnRleHQtPkVieCwgY29udGV4dC0+RWN4LCBjb250ZXh0LT5FZHgpOwogICAgICAgIEZJWE1FKCIgICAgZXNpPSUwOGx4IGVkaT0lMDhseCBkcz0lMDRseCBlcz0lMDRseFxuIiwKICAgICAgICAgICAgICBjb250ZXh0LT5Fc2ksIGNvbnRleHQtPkVkaSwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRE9TVk1fSW5pdAogKi8KQk9PTCBXSU5BUEkgRE9TVk1fSW5pdCggSElOU1RBTkNFIGhpbnN0RExMLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCApCnsKICAgIFRSQUNFXyhtb2R1bGUpKCIoMHglMDh4LCVsZCwlcClcbiIsIGhpbnN0RExMLCBmZHdSZWFzb24sIGxwdlJlc2VydmVkKTsKCiAgICBpZiAoZmR3UmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgICAgICBUUkFDRSgiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiAgICAgICAgRE9TTUVNX0luaXQoIFRSVUUgKTsKICAgICAgICBET1NERVZfSW5zdGFsbERPU0RldmljZXMoKTsKCiNpZmRlZiBNWl9TVVBQT1JURUQKICAgICAgICBldmVudF9ub3RpZmllciA9IENyZWF0ZUV2ZW50QShOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmKCFldmVudF9ub3RpZmllcikKICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBldmVudCBvYmplY3QhXG4iKTsKI2VuZGlmCgogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0K