LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2ZyZWV0eXBlLmMsdiAxLjggMjAwMi8wNy8wOSAwMjoyODoyOSBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAiZmNpbnQuaCIKI2luY2x1ZGUgPGZyZWV0eXBlL2ZyZWV0eXBlLmg+CiNpbmNsdWRlIDxmcmVldHlwZS9pbnRlcm5hbC9mdG9ianMuaD4KI2luY2x1ZGUgPGZyZWV0eXBlL3R0dGFibGVzLmg+CiNpbmNsdWRlIDxmcmVldHlwZS9mdHNuYW1lcy5oPgojaW5jbHVkZSA8ZnJlZXR5cGUvdHRuYW1laWQuaD4KCi8qCiAqIEtlZXAgSGFuIGxhbmd1YWdlcyBzZXBhcmF0ZWQgYnkgZWxpbWluYXRpbmcgbGFuZ3VhZ2VzCiAqIHRoYXQgdGhlIGNvZGVQYWdlUmFuZ2UgYml0cyBzYXlzIGFyZW4ndCBzdXBwb3J0ZWQKICovCgpzdGF0aWMgY29uc3Qgc3RydWN0IHsKICAgIGludAkJICAgIGJpdDsKICAgIGNvbnN0IEZjQ2hhcjggICAqbGFuZzsKfSBGY0NvZGVQYWdlUmFuZ2VbXSA9IHsKICAgIHsgMTcsCShjb25zdCBGY0NoYXI4ICopICJqYSIgfSwKICAgIHsgMTgsCShjb25zdCBGY0NoYXI4ICopICJ6aC1jbiIgfSwKICAgIHsgMTksCShjb25zdCBGY0NoYXI4ICopICJrbyIgfSwKICAgIHsgMjAsCShjb25zdCBGY0NoYXI4ICopICJ6aC10dyIgfSwKfTsKCiNkZWZpbmUgTlVNX0NPREVfUEFHRV9SQU5HRSAoc2l6ZW9mIEZjQ29kZVBhZ2VSYW5nZSAvIHNpemVvZiBGY0NvZGVQYWdlUmFuZ2VbMF0pCgpGY0Jvb2wKRmNGcmVlVHlwZUlzRXhjbHVzaXZlTGFuZyAoY29uc3QgRmNDaGFyOCAgKmxhbmcpCnsKICAgIGludAkgICAgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0NPREVfUEFHRV9SQU5HRTsgaSsrKQogICAgewoJaWYgKEZjTGFuZ0NvbXBhcmUgKGxhbmcsIEZjQ29kZVBhZ2VSYW5nZVtpXS5sYW5nKSAhPSBGY0xhbmdEaWZmZXJlbnRMYW5nKQoJICAgIHJldHVybiBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKI2RlZmluZSBGQ19OQU1FX1BSSU9fTEFORwkgICAgMHgwZjAwCiNkZWZpbmUgRkNfTkFNRV9QUklPX0xBTkdfRU5HTElTSCAgIDB4MDIwMAojZGVmaW5lIEZDX05BTUVfUFJJT19MQU5HX0xBVElOCSAgICAweDAxMDAKI2RlZmluZSBGQ19OQU1FX1BSSU9fTEFOR19OT05FCSAgICAweDAwMDAKCiNkZWZpbmUgRkNfTkFNRV9QUklPX0VOQwkgICAgMHgwMGYwCiNkZWZpbmUgRkNfTkFNRV9QUklPX0VOQ19VTklDT0RFICAgIDB4MDAxMAojZGVmaW5lIEZDX05BTUVfUFJJT19FTkNfTk9ORQkgICAgMHgwMDAwCgojZGVmaW5lIEZDX05BTUVfUFJJT19OQU1FCSAgICAweDAwMGYKI2RlZmluZSBGQ19OQU1FX1BSSU9fTkFNRV9GQU1JTFkgICAgMHgwMDAyCiNkZWZpbmUgRkNfTkFNRV9QUklPX05BTUVfUFMJICAgIDB4MDAwMQojZGVmaW5lIEZDX05BTUVfUFJJT19OQU1FX05PTkUJICAgIDB4MDAwMAoKc3RhdGljIEZjQm9vbApGY1VjczRJc0xhdGluIChGY0NoYXIzMiB1Y3M0KQp7CiAgICBGY0NoYXIzMglwYWdlID0gdWNzNCA+PiA4OwogICAgCiAgICBpZiAocGFnZSA8PSAyKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGlmIChwYWdlID09IDB4MWUpCglyZXR1cm4gRmNUcnVlOwogICAgaWYgKDB4MjAgPD0gcGFnZSAmJiBwYWdlIDw9IDB4MjMpCglyZXR1cm4gRmNUcnVlOwogICAgaWYgKHBhZ2UgPT0gMHhmYikKCXJldHVybiBGY1RydWU7CiAgICBpZiAocGFnZSA9PSAweGZmKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjVXRmOElzTGF0aW4gKEZjQ2hhcjggKnN0ciwgaW50IGxlbikKewogICAgd2hpbGUgKGxlbikKICAgIHsKCUZjQ2hhcjMyICAgIHVjczQ7CglpbnQJICAgIGNsZW4gPSBGY1V0ZjhUb1VjczQgKHN0ciwgJnVjczQsIGxlbik7CglpZiAoY2xlbiA8PSAwKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY1VjczRJc0xhdGluICh1Y3M0KSkKCSAgICByZXR1cm4gRmNGYWxzZTsKCWxlbiAtPSBjbGVuOwoJc3RyICs9IGNsZW47CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY1BhdHRlcm4gKgpGY0ZyZWVUeXBlUXVlcnkgKGNvbnN0IEZjQ2hhcjgJKmZpbGUsCgkJIGludAkJaWQsCgkJIEZjQmxhbmtzCSpibGFua3MsCgkJIGludAkJKmNvdW50KQp7CiAgICBGVF9GYWNlCSAgICBmYWNlOwogICAgRmNQYXR0ZXJuCSAgICAqcGF0OwogICAgaW50CQkgICAgc2xhbnQ7CiAgICBpbnQJCSAgICB3ZWlnaHQ7CiAgICBpbnQJCSAgICBpOwogICAgRmNDaGFyU2V0CSAgICAqY3M7CiAgICBGVF9MaWJyYXJ5CSAgICBmdExpYnJhcnk7CiAgICBGY0NoYXI4CSAgICAqZmFtaWx5OwogICAgRmNDaGFyOAkgICAgKnN0eWxlOwogICAgVFRfT1MyCSAgICAqb3MyOwogICAgY29uc3QgRmNDaGFyOCAgICpleGNsdXNpdmVMYW5nID0gMDsKICAgIEZUX1NmbnROYW1lCSAgICBzbmFtZTsKICAgIEZUX1VJbnQgICAgCSAgICBzbmFtZWksIHNuYW1lYzsKICAgIEZjQm9vbAkgICAgZmFtaWx5X2FsbG9jYXRlZCA9IEZjRmFsc2U7CiAgICBGY0Jvb2wJICAgIHN0eWxlX2FsbG9jYXRlZCA9IEZjRmFsc2U7CiAgICBpbnQJCSAgICBmYW1pbHlfcHJpbyA9IDA7CiAgICBpbnQJCSAgICBzdHlsZV9wcmlvID0gMDsKCiAgICBpZiAoRlRfSW5pdF9GcmVlVHlwZSAoJmZ0TGlicmFyeSkpCglyZXR1cm4gMDsKICAgIAogICAgaWYgKEZUX05ld19GYWNlIChmdExpYnJhcnksIChjaGFyICopIGZpbGUsIGlkLCAmZmFjZSkpCglnb3RvIGJhaWw7CgogICAgKmNvdW50ID0gZmFjZS0+bnVtX2ZhY2VzOwoKICAgIHBhdCA9IEZjUGF0dGVybkNyZWF0ZSAoKTsKICAgIGlmICghcGF0KQoJZ290byBiYWlsMDsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEJvb2wgKHBhdCwgRkNfT1VUTElORSwKCQkJICAgKGZhY2UtPmZhY2VfZmxhZ3MgJiBGVF9GQUNFX0ZMQUdfU0NBTEFCTEUpICE9IDApKQoJZ290byBiYWlsMTsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEJvb2wgKHBhdCwgRkNfU0NBTEFCTEUsCgkJCSAgIChmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX1NDQUxBQkxFKSAhPSAwKSkKCWdvdG8gYmFpbDE7CgoKICAgIHNsYW50ID0gRkNfU0xBTlRfUk9NQU47CiAgICBpZiAoZmFjZS0+c3R5bGVfZmxhZ3MgJiBGVF9TVFlMRV9GTEFHX0lUQUxJQykKCXNsYW50ID0gRkNfU0xBTlRfSVRBTElDOwoKICAgIGlmICghRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0LCBGQ19TTEFOVCwgc2xhbnQpKQoJZ290byBiYWlsMTsKCiAgICB3ZWlnaHQgPSBGQ19XRUlHSFRfTUVESVVNOwogICAgaWYgKGZhY2UtPnN0eWxlX2ZsYWdzICYgRlRfU1RZTEVfRkxBR19CT0xEKQoJd2VpZ2h0ID0gRkNfV0VJR0hUX0JPTEQ7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX1dFSUdIVCwgd2VpZ2h0KSkKCWdvdG8gYmFpbDE7CgogICAgLyoKICAgICAqIEdydWIgdGhyb3VnaCB0aGUgbmFtZSB0YWJsZSBsb29raW5nIGZvciBmYW1pbHkKICAgICAqIGFuZCBzdHlsZSBuYW1lcy4gIEZyZWVUeXBlIG1ha2VzIHF1aXRlIGEgaGFzaAogICAgICogb2YgdGhlbQogICAgICovCiAgICBmYW1pbHkgPSAwOwogICAgc3R5bGUgPSAwOwogICAgc25hbWVjID0gRlRfR2V0X1NmbnRfTmFtZV9Db3VudCAoZmFjZSk7CiAgICBmb3IgKHNuYW1laSA9IDA7IHNuYW1laSA8IHNuYW1lYzsgc25hbWVpKyspCiAgICB7CglGY0NoYXI4CQkqdXRmODsKCWludAkJbGVuOwoJaW50CQl3Y2hhcjsKCUZjQ2hhcjgJCSpzcmM7CglpbnQJCXNyY19sZW47CglGY0NoYXI4CQkqdTg7CglGY0NoYXIzMgl1Y3M0OwoJaW50CQlpbGVuLCBvbGVuOwoJaW50CQlwcmlvID0gMDsKCQoJY29uc3QgRmNDaGFyTWFwCSptYXA7CgllbnVtIHsKCSAgICBGY05hbWVFbmNvZGluZ1V0ZjE2LCAKCSAgICBGY05hbWVFbmNvZGluZ0FwcGxlUm9tYW4sCgkgICAgRmNOYW1lRW5jb2RpbmdMYXRpbjEgCgl9IGVuY29kaW5nOwoJCgkKCWlmIChGVF9HZXRfU2ZudF9OYW1lIChmYWNlLCBzbmFtZWksICZzbmFtZSkgIT0gMCkKCSAgICBicmVhazsKCQoJLyoKCSAqIExvb2sgZm9yIFVuaWNvZGUgc3RyaW5ncwoJICovCglzd2l0Y2ggKHNuYW1lLnBsYXRmb3JtX2lkKSB7CgljYXNlIFRUX1BMQVRGT1JNX0FQUExFX1VOSUNPREU6CgkgICAgLyoKCSAgICAgKiBBbGwgQVBQTEVfVU5JQ09ERSBlbmNvZGluZ3MgYXJlIFV0ZjE2IEJFCgkgICAgICoKCSAgICAgKiBCZWNhdXNlIHRoZXJlJ3Mgbm8gbGFuZ3VhZ2UgaWQgZm9yIFVuaWNvZGUsCgkgICAgICogYXNzdW1lIGl0J3MgRW5nbGlzaAoJICAgICAqLwoJICAgIHByaW8gfD0gRkNfTkFNRV9QUklPX0xBTkdfRU5HTElTSDsKCSAgICBwcmlvIHw9IEZDX05BTUVfUFJJT19FTkNfVU5JQ09ERTsKCSAgICBlbmNvZGluZyA9IEZjTmFtZUVuY29kaW5nVXRmMTY7CgkgICAgYnJlYWs7CgljYXNlIFRUX1BMQVRGT1JNX01BQ0lOVE9TSDoKCSAgICBzd2l0Y2ggKHNuYW1lLmVuY29kaW5nX2lkKSB7CgkgICAgY2FzZSBUVF9NQUNfSURfUk9NQU46CgkJZW5jb2RpbmcgPSBGY05hbWVFbmNvZGluZ0FwcGxlUm9tYW47CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQljb250aW51ZTsKCSAgICB9CgkgICAgc3dpdGNoIChzbmFtZS5sYW5ndWFnZV9pZCkgewoJICAgIGNhc2UgVFRfTUFDX0xBTkdJRF9FTkdMSVNIOgoJCXByaW8gfD0gRkNfTkFNRV9QUklPX0xBTkdfRU5HTElTSDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCS8qCgkJICogU29tZXRpbWVzIE1pY3Jvc29mdCBsYW5ndWFnZSBpZHMKCQkgKiBlbmQgdXAgaW4gdGhlIG1hY2ludG9zaCB0YWJsZS4gIFRoaXMKCQkgKiBpcyBvZnRlbiBhY2NvbXBhbmllZCBieSBkYXRhIGluCgkJICogc29tZSBteXN0aWMgZW5jb2RpbmcuICBJZ25vcmUgdGhlc2UgbmFtZXMKCQkgKi8KCQlpZiAoc25hbWUubGFuZ3VhZ2VfaWQgPj0gMHgxMDApCgkJICAgIGNvbnRpbnVlOwoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgVFRfUExBVEZPUk1fTUlDUk9TT0ZUOgoJICAgIHN3aXRjaCAoc25hbWUuZW5jb2RpbmdfaWQpIHsKCSAgICBjYXNlIFRUX01TX0lEX1VOSUNPREVfQ1M6CgkJZW5jb2RpbmcgPSBGY05hbWVFbmNvZGluZ1V0ZjE2OwoJCXByaW8gfD0gRkNfTkFNRV9QUklPX0VOQ19VTklDT0RFOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJY29udGludWU7CgkgICAgfQoJICAgIHN3aXRjaCAoc25hbWUubGFuZ3VhZ2VfaWQgJiAweGZmKSB7CgkgICAgY2FzZSAweDA5OgoJCXByaW8gfD0gRkNfTkFNRV9QUklPX0xBTkdfRU5HTElTSDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgVFRfUExBVEZPUk1fSVNPOgoJICAgIHN3aXRjaCAoc25hbWUuZW5jb2RpbmdfaWQpIHsKCSAgICBjYXNlIFRUX0lTT19JRF8xMDY0NjoKCQllbmNvZGluZyA9IEZjTmFtZUVuY29kaW5nVXRmMTY7CgkJcHJpbyB8PSBGQ19OQU1FX1BSSU9fRU5DX1VOSUNPREU7CgkJYnJlYWs7CgkgICAgY2FzZSBUVF9JU09fSURfN0JJVF9BU0NJSToKCSAgICBjYXNlIFRUX0lTT19JRF84ODU5XzE6CgkJZW5jb2RpbmcgPSBGY05hbWVFbmNvZGluZ0xhdGluMTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgY29udGludWU7Cgl9CgkKCS8qCgkgKiBMb29rIGZvciBmYW1pbHkgYW5kIHN0eWxlIG5hbWVzIAoJICovCglzd2l0Y2ggKHNuYW1lLm5hbWVfaWQpIHsKCWNhc2UgVFRfTkFNRV9JRF9GT05UX0ZBTUlMWToKCSAgICBwcmlvIHw9IEZDX05BTUVfUFJJT19OQU1FX0ZBTUlMWTsKCSAgICBicmVhazsKCWNhc2UgVFRfTkFNRV9JRF9QU19OQU1FOgoJICAgIHByaW8gfD0gRkNfTkFNRV9QUklPX05BTUVfUFM7CgkgICAgYnJlYWs7CgljYXNlIFRUX05BTUVfSURfRk9OVF9TVUJGQU1JTFk6CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGNvbnRpbnVlOwoJfQoJICAgIAogICAgICAgIHNyYyA9IChGY0NoYXI4ICopIHNuYW1lLnN0cmluZzsKICAgICAgICBzcmNfbGVuID0gc25hbWUuc3RyaW5nX2xlbjsKCQoJc3dpdGNoIChlbmNvZGluZykgewoJY2FzZSBGY05hbWVFbmNvZGluZ1V0ZjE2OgoJICAgIC8qCgkgICAgICogQ29udmVydCBVdGYxNiB0byBVdGY4CgkgICAgICovCgkgICAgCgkgICAgaWYgKCFGY1V0ZjE2TGVuIChzcmMsIEZjRW5kaWFuQmlnLCBzcmNfbGVuLCAmbGVuLCAmd2NoYXIpKQoJCWNvbnRpbnVlOwogICAgCgkgICAgLyoKCSAgICAgKiBBbGxvY2F0ZSBwbGVudHkgb2Ygc3BhY2UKCSAgICAgKi8KCSAgICB1dGY4ID0gbWFsbG9jIChsZW4gKiBGQ19VVEY4X01BWF9MRU4gKyAxKTsKCSAgICBpZiAoIXV0ZjgpCgkJY29udGludWU7CgkJCgkgICAgdTggPSB1dGY4OwoJICAgIAoJICAgIHdoaWxlICgoaWxlbiA9IEZjVXRmMTZUb1VjczQgKHNyYywgRmNFbmRpYW5CaWcsICZ1Y3M0LCBzcmNfbGVuKSkgPiAwKQoJICAgIHsKCQlzcmNfbGVuIC09IGlsZW47CgkJc3JjICs9IGlsZW47CgkJb2xlbiA9IEZjVWNzNFRvVXRmOCAodWNzNCwgdTgpOwoJCXU4ICs9IG9sZW47CgkgICAgfQoJICAgICp1OCA9ICdcMCc7CgkgICAgYnJlYWs7CgljYXNlIEZjTmFtZUVuY29kaW5nTGF0aW4xOgoJICAgIC8qCgkgICAgICogQ29udmVydCBMYXRpbjEgdG8gVXRmOAoJICAgICAqLwoJICAgIHV0ZjggPSBtYWxsb2MgKHNyY19sZW4gKiAyICsgMSk7CgkgICAgaWYgKCF1dGY4KQoJCWNvbnRpbnVlOwoKCSAgICB1OCA9IHV0Zjg7CgkgICAgd2hpbGUgKHNyY19sZW4gPiAwKQoJICAgIHsKCQl1Y3M0ID0gKnNyYysrOwoJCXNyY19sZW4tLTsKCQlvbGVuID0gRmNVY3M0VG9VdGY4ICh1Y3M0LCB1OCk7CgkJdTggKz0gb2xlbjsKCSAgICB9CgkgICAgKnU4ID0gJ1wwJzsKCSAgICBicmVhazsKCWNhc2UgRmNOYW1lRW5jb2RpbmdBcHBsZVJvbWFuOgoJICAgIC8qCgkgICAgICogQ29udmVydCBBcHBsZVJvbWFuIHRvIFV0ZjgKCSAgICAgKi8KCSAgICBtYXAgPSBGY0ZyZWVUeXBlR2V0UHJpdmF0ZU1hcCAoZnRfZW5jb2RpbmdfYXBwbGVfcm9tYW4pOwoJICAgIGlmICghbWFwKQoJCWNvbnRpbnVlOwoKCSAgICB1dGY4ID0gbWFsbG9jIChzcmNfbGVuICogMyArIDEpOwoJICAgIGlmICghdXRmOCkKCQljb250aW51ZTsKCgkgICAgdTggPSB1dGY4OwoJICAgIHdoaWxlIChzcmNfbGVuID4gMCkKCSAgICB7CgkJdWNzNCA9IEZjRnJlZVR5cGVQcml2YXRlVG9VY3M0ICgqc3JjKyssIG1hcCk7CgkJc3JjX2xlbi0tOwoJCW9sZW4gPSBGY1VjczRUb1V0ZjggKHVjczQsIHU4KTsKCQl1OCArPSBvbGVuOwoJICAgIH0KCSAgICAqdTggPSAnXDAnOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBjb250aW51ZTsKCX0KCWlmICgocHJpbyAmIEZDX05BTUVfUFJJT19MQU5HKSA9PSBGQ19OQU1FX1BSSU9fTEFOR19OT05FKQoJICAgIGlmIChGY1V0ZjhJc0xhdGluICh1dGY4LCBzdHJsZW4gKChjaGFyICopIHV0ZjgpKSkKCQlwcmlvIHw9IEZDX05BTUVfUFJJT19MQU5HX0xBVElOOwoJCQkgICAgICAgCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOVikKCSAgICBwcmludGYgKCJcbmZvdW5kIG5hbWUgKG5hbWUgJWQgcGxhdGZvcm0gJWQgZW5jb2RpbmcgJWQgbGFuZ3VhZ2UgMHgleCBwcmlvIDB4JXgpICVzXG4iLAoJCSAgICBzbmFtZS5uYW1lX2lkLCBzbmFtZS5wbGF0Zm9ybV9pZCwKCQkgICAgc25hbWUuZW5jb2RpbmdfaWQsIHNuYW1lLmxhbmd1YWdlX2lkLAoJCSAgICBwcmlvLCB1dGY4KTsKICAgIAoJc3dpdGNoIChzbmFtZS5uYW1lX2lkKSB7CgljYXNlIFRUX05BTUVfSURfRk9OVF9GQU1JTFk6CgljYXNlIFRUX05BTUVfSURfUFNfTkFNRToKCSAgICBpZiAoIWZhbWlseSB8fCBwcmlvID4gZmFtaWx5X3ByaW8pCgkgICAgewoJCWlmIChmYW1pbHkpCgkJICAgIGZyZWUgKGZhbWlseSk7CgkJZmFtaWx5ID0gdXRmODsKCQl1dGY4ID0gMDsKCQlmYW1pbHlfYWxsb2NhdGVkID0gRmNUcnVlOwoJCWZhbWlseV9wcmlvID0gcHJpbzsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFRUX05BTUVfSURfRk9OVF9TVUJGQU1JTFk6CgkgICAgaWYgKCFzdHlsZSB8fCBwcmlvID4gc3R5bGVfcHJpbykKCSAgICB7CgkJaWYgKHN0eWxlKQoJCSAgICBmcmVlIChzdHlsZSk7CgkJc3R5bGUgPSB1dGY4OwoJCXV0ZjggPSAwOwoJCXN0eWxlX2FsbG9jYXRlZCA9IEZjVHJ1ZTsKCQlzdHlsZV9wcmlvID0gcHJpbzsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CglpZiAodXRmOCkKCSAgICBmcmVlICh1dGY4KTsKICAgIH0KICAgIAogICAgaWYgKCFmYW1pbHkpCglmYW1pbHkgPSAoRmNDaGFyOCAqKSBmYWNlLT5mYW1pbHlfbmFtZTsKICAgIAogICAgaWYgKCFzdHlsZSkKCXN0eWxlID0gKEZjQ2hhcjggKikgZmFjZS0+c3R5bGVfbmFtZTsKICAgIAogICAgaWYgKCFmYW1pbHkpCiAgICB7CglGY0NoYXI4CSpzdGFydCwgKmVuZDsKCQoJc3RhcnQgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBmaWxlLCAnLycpOwoJaWYgKHN0YXJ0KQoJICAgIHN0YXJ0Kys7CgllbHNlCgkgICAgc3RhcnQgPSAoRmNDaGFyOCAqKSBmaWxlOwoJZW5kID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgc3RhcnQsICcuJyk7CglpZiAoIWVuZCkKCSAgICBlbmQgPSBzdGFydCArIHN0cmxlbiAoKGNoYXIgKikgc3RhcnQpOwoJZmFtaWx5ID0gbWFsbG9jIChlbmQgLSBzdGFydCArIDEpOwoJc3RybmNweSAoKGNoYXIgKikgZmFtaWx5LCAoY2hhciAqKSBzdGFydCwgZW5kIC0gc3RhcnQpOwoJZmFtaWx5W2VuZCAtIHN0YXJ0XSA9ICdcMCc7CglmYW1pbHlfYWxsb2NhdGVkID0gRmNUcnVlOwogICAgfQoKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfU0NBTikKCXByaW50ZiAoIlwiJXNcIiBcIiVzXCIgIiwgZmFtaWx5LCBzdHlsZSA/IHN0eWxlIDogKEZjQ2hhcjggKikgIjxub25lPiIpOwoKICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX0ZBTUlMWSwgZmFtaWx5KSkKICAgIHsKCWlmIChmYW1pbHlfYWxsb2NhdGVkKQoJICAgIGZyZWUgKGZhbWlseSk7CglpZiAoc3R5bGVfYWxsb2NhdGVkKQoJICAgIGZyZWUgKHN0eWxlKTsKCWdvdG8gYmFpbDE7CiAgICB9CgogICAgaWYgKGZhbWlseV9hbGxvY2F0ZWQpCglmcmVlIChmYW1pbHkpOwoKICAgIGlmIChzdHlsZSkKICAgIHsKCWlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX1NUWUxFLCBzdHlsZSkpCgl7CgkgICAgaWYgKHN0eWxlX2FsbG9jYXRlZCkKCQlmcmVlIChzdHlsZSk7CgkgICAgZ290byBiYWlsMTsKCX0KCWlmIChzdHlsZV9hbGxvY2F0ZWQpCgkgICAgZnJlZSAoc3R5bGUpOwogICAgfQoKICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX0ZJTEUsIGZpbGUpKQoJZ290byBiYWlsMTsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgRkNfSU5ERVgsIGlkKSkKCWdvdG8gYmFpbDE7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfU09VUkNFLCAoRmNDaGFyOCAqKSAiRnJlZVR5cGUiKSkKCWdvdG8gYmFpbDE7CgojaWYgMQogICAgaWYgKChmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX0ZJWEVEX1dJRFRIKSAhPSAwKQoJaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX1NQQUNJTkcsIEZDX01PTk8pKQoJICAgIGdvdG8gYmFpbDE7CiNlbmRpZgoKICAgIC8qCiAgICAgKiBHZXQgdGhlIE9TLzIgdGFibGUgYW5kIHBva2UgYWJvdXQKICAgICAqLwogICAgb3MyID0gKFRUX09TMiAqKSBGVF9HZXRfU2ZudF9UYWJsZSAoZmFjZSwgZnRfc2ZudF9vczIpOwogICAgaWYgKG9zMiAmJiBvczItPnZlcnNpb24gPj0gMHgwMDAxICYmIG9zMi0+dmVyc2lvbiAhPSAweGZmZmYpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgTlVNX0NPREVfUEFHRV9SQU5HRTsgaSsrKQoJewoJICAgIEZUX1VMb25nCWJpdHM7CgkgICAgaW50CQliaXQ7CgkgICAgaWYgKEZjQ29kZVBhZ2VSYW5nZVtpXS5iaXQgPCAzMikKCSAgICB7CgkJYml0cyA9IG9zMi0+dWxDb2RlUGFnZVJhbmdlMTsKCQliaXQgPSBGY0NvZGVQYWdlUmFuZ2VbaV0uYml0OwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWJpdHMgPSBvczItPnVsQ29kZVBhZ2VSYW5nZTI7CgkJYml0ID0gRmNDb2RlUGFnZVJhbmdlW2ldLmJpdCAtIDMyOwoJICAgIH0KCSAgICBpZiAoYml0cyAmICgxIDw8IGJpdCkpCgkgICAgewoJCS8qIAoJCSAqIElmIHRoZSBmb250IGFkdmVydGlzZXMgc3VwcG9ydCBmb3IgbXVsdGlwbGUKCQkgKiAiZXhjbHVzaXZlIiBsYW5ndWFnZXMsIHRoZW4gaW5jbHVkZSBzdXBwb3J0CgkJICogZm9yIGFueSBsYW5ndWFnZSBmb3VuZCB0byBoYXZlIGNvdmVyYWdlCgkJICovCgkJaWYgKGV4Y2x1c2l2ZUxhbmcpCgkJewoJCSAgICBleGNsdXNpdmVMYW5nID0gMDsKCQkgICAgYnJlYWs7CgkJfQoJCWV4Y2x1c2l2ZUxhbmcgPSBGY0NvZGVQYWdlUmFuZ2VbaV0ubGFuZzsKCSAgICB9Cgl9CiAgICB9CgogICAgLyoKICAgICAqIENvbXB1dGUgdGhlIHVuaWNvZGUgY292ZXJhZ2UgZm9yIHRoZSBmb250CiAgICAgKi8KICAgIGNzID0gRmNGcmVlVHlwZUNoYXJTZXQgKGZhY2UsIGJsYW5rcyk7CiAgICBpZiAoIWNzKQoJZ290byBiYWlsMTsKCiAgICAvKgogICAgICogU2tpcCBvdmVyIFBDRiBmb250cyB0aGF0IGhhdmUgbm8gZW5jb2RlZCBjaGFyYWN0ZXJzOyB0aGV5J3JlCiAgICAgKiB1c3VhbGx5IGp1c3QgVW5pY29kZSBmb250cyB0cmFuc2NvZGVkIHRvIHNvbWUgbGVnYWN5IGVuY29kaW5nCiAgICAgKi8KICAgIGlmIChGY0NoYXJTZXRDb3VudCAoY3MpID09IDApCiAgICB7CglpZiAoIXN0cmNtcChGVF9NT0RVTEVfQ0xBU1MoJmZhY2UtPmRyaXZlci0+cm9vdCktPm1vZHVsZV9uYW1lLCAicGNmIikpCgkgICAgZ290byBiYWlsMjsKICAgIH0KCiAgICBpZiAoIUZjUGF0dGVybkFkZENoYXJTZXQgKHBhdCwgRkNfQ0hBUlNFVCwgY3MpKQoJZ290byBiYWlsMjsKCiAgICBpZiAoIUZjRnJlZVR5cGVTZXRMYW5nIChwYXQsIGNzLCBleGNsdXNpdmVMYW5nKSkKICAgICAgICBnb3RvIGJhaWwyOwoKICAgIC8qCiAgICAgKiBEcm9wIG91ciByZWZlcmVuY2UgdG8gdGhlIGNoYXJzZXQKICAgICAqLwogICAgRmNDaGFyU2V0RGVzdHJveSAoY3MpOwogICAgCiAgICBpZiAoIShmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX1NDQUxBQkxFKSkKICAgIHsKCWZvciAoaSA9IDA7IGkgPCBmYWNlLT5udW1fZml4ZWRfc2l6ZXM7IGkrKykKCSAgICBpZiAoIUZjUGF0dGVybkFkZERvdWJsZSAocGF0LCBGQ19QSVhFTF9TSVpFLAoJCQkJICAgICAoZG91YmxlKSBmYWNlLT5hdmFpbGFibGVfc2l6ZXNbaV0uaGVpZ2h0KSkKCQlnb3RvIGJhaWwxOwoJaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX0FOVElBTElBUywgRmNGYWxzZSkpCgkgICAgZ290byBiYWlsMTsKICAgIH0KCiAgICBGVF9Eb25lX0ZhY2UgKGZhY2UpOwogICAgRlRfRG9uZV9GcmVlVHlwZSAoZnRMaWJyYXJ5KTsKICAgIHJldHVybiBwYXQ7CgpiYWlsMjoKICAgIEZjQ2hhclNldERlc3Ryb3kgKGNzKTsKYmFpbDE6CiAgICBGY1BhdHRlcm5EZXN0cm95IChwYXQpOwpiYWlsMDoKICAgIEZUX0RvbmVfRmFjZSAoZmFjZSk7CmJhaWw6CiAgICBGVF9Eb25lX0ZyZWVUeXBlIChmdExpYnJhcnkpOwogICAgcmV0dXJuIDA7Cn0K