LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL2ZjLWNhY2hlL2ZjLWNhY2hlLmMsdiAxLjIgMjAwMi8wMi8xNSAwNzozNjoxNCBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGZvbnRjb25maWcvZm9udGNvbmZpZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaWZkZWYgSEFWRV9DT05GSUdfSAojaW5jbHVkZSA8Y29uZmlnLmg+CiNlbHNlCiNpZmRlZiBsaW51eAojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMQojZW5kaWYKI2RlZmluZSBIQVZFX0dFVE9QVCAxCiNlbmRpZgoKI2lmbmRlZiBIQVZFX0dFVE9QVAojZGVmaW5lIEhBVkVfR0VUT1BUIDAKI2VuZGlmCiNpZm5kZWYgSEFWRV9HRVRPUFRfTE9ORwojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMAojZW5kaWYKCiNpZiBIQVZFX0dFVE9QVF9MT05HCiN1bmRlZiAgX0dOVV9TT1VSQ0UKI2RlZmluZSBfR05VX1NPVVJDRQojaW5jbHVkZSA8Z2V0b3B0Lmg+CmNvbnN0IHN0cnVjdCBvcHRpb24gbG9uZ29wdHNbXSA9IHsKICAgIHsiZm9yY2UiLCAwLCAwLCAnZid9LAogICAgeyJ2ZXJzaW9uIiwgMCwgMCwgJ1YnfSwKICAgIHsidmVyYm9zZSIsIDAsIDAsICd2J30sCiAgICB7ImhlbHAiLCAwLCAwLCAnPyd9LAogICAge05VTEwsMCwwLDB9LAp9OwojZWxzZQojaWYgSEFWRV9HRVRPUFQKZXh0ZXJuIGNoYXIgKm9wdGFyZzsKZXh0ZXJuIGludCBvcHRpbmQsIG9wdGVyciwgb3B0b3B0OwojZW5kaWYKI2VuZGlmCgpzdGF0aWMgdm9pZAp1c2FnZSAoY2hhciAqcHJvZ3JhbSkKewogICAgZnByaW50ZiAoc3RkZXJyLCAidXNhZ2U6ICVzIFstZnZWP10gWy0tZm9yY2VdIFstLXZlcmJvc2VdIFstLXZlcnNpb25dIFstLWhlbHBdIFtkaXJzXVxuIiwKCSAgICAgcHJvZ3JhbSk7CiAgICBmcHJpbnRmIChzdGRlcnIsICJCdWlsZCBmb250IGluZm9ybWF0aW9uIGNhY2hlcyBpbiBbZGlyc11cbiIKCSAgICAgIihhbGwgZGlyZWN0b3JpZXMgaW4gZm9udCBjb25maWd1cmF0aW9uIGJ5IGRlZmF1bHQpLlxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICJcbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiICAtdiwgLS1mb3JjZSAgICAgICAgICBzY2FuIGRpcmVjdG9yaWVzIHdpdGggYXBwYXJlbnRseSB2YWxpZCBjYWNoZXNcbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiICAtdiwgLS12ZXJib3NlICAgICAgICBkaXNwbGF5IHN0YXR1cyBpbmZvcm1hdGlvbiB3aGlsZSBidXN5XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLVYsIC0tdmVyc2lvbiAgICAgICAgZGlzcGxheSBmb250IGNvbmZpZyB2ZXJzaW9uIGFuZCBleGl0XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLT8sIC0taGVscCAgICAgICAgICAgZGlzcGxheSB0aGlzIGhlbHAgYW5kIGV4aXRcbiIpOwogICAgZXhpdCAoMSk7Cn0KCnN0YXRpYyBpbnQKbnN1YmRpcnMgKEZjU3RyU2V0ICpzZXQpCnsKICAgIEZjU3RyTGlzdAkqbGlzdDsKICAgIGludAkJbiA9IDA7CgogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc2V0KTsKICAgIGlmICghbGlzdCkKCXJldHVybiAwOwogICAgd2hpbGUgKEZjU3RyTGlzdE5leHQgKGxpc3QpKQoJbisrOwogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICByZXR1cm4gbjsKfQoKc3RhdGljIGludApzY2FuRGlycyAoRmNTdHJMaXN0ICpsaXN0LCBjaGFyICpwcm9ncmFtLCBGY0Jvb2wgZm9yY2UsIEZjQm9vbCB2ZXJib3NlKQp7CiAgICBpbnQJCXJldCA9IDA7CiAgICBGY0NoYXI4CSpkaXI7CiAgICBGY0ZvbnRTZXQJKnNldDsKICAgIEZjU3RyU2V0CSpzdWJkaXJzOwogICAgRmNTdHJMaXN0CSpzdWJsaXN0OwogICAgCiAgICAvKgogICAgICogTm93IHNjYW4gYWxsIG9mIHRoZSBkaXJlY3RvcmllcyBpbnRvIHNlcGFyYXRlIGRhdGFiYXNlcwogICAgICogYW5kIHdyaXRlIG91dCB0aGUgcmVzdWx0cwogICAgICovCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWlmICh2ZXJib3NlKQoJewoJICAgIHByaW50ZiAoIiVzOiBcIiVzXCI6ICIsIHByb2dyYW0sIGRpcik7CgkgICAgZmZsdXNoIChzdGRvdXQpOwoJfQoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiQ2FuJ3QgY3JlYXRlIGZvbnQgc2V0XG4iKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCXN1YmRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghc3ViZGlycykKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBjcmVhdGUgZGlyZWN0b3J5IHNldFxuIik7CgkgICAgcmV0Kys7CgkgICAgY29udGludWU7Cgl9CglpZiAoIUZjRGlyU2NhbiAoc2V0LCBzdWJkaXJzLCAwLCBGY0NvbmZpZ0dldEJsYW5rcyAoMCksIGRpciwgZm9yY2UpKQoJewoJICAgIGZwcmludGYgKHN0ZGVyciwgIkNhbid0IHNjYW4gXCIlc1wiXG4iLCBkaXIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKCFmb3JjZSAmJiBGY0RpckNhY2hlVmFsaWQgKGRpcikpCgl7CgkgICAgaWYgKHZlcmJvc2UpCgkJcHJpbnRmICgic2tpcHBpbmcsICVkIGZvbnRzLCAlZCBkaXJzXG4iLAoJCQlzZXQtPm5mb250LCBuc3ViZGlycyhzdWJkaXJzKSk7Cgl9CgllbHNlCgl7CgkgICAgaWYgKHZlcmJvc2UpCgkJcHJpbnRmICgiY2FjaGluZywgJWQgZm9udHMsICVkIGRpcnNcbiIsIAoJCQlzZXQtPm5mb250LCBuc3ViZGlycyAoc3ViZGlycykpOwoJICAgIGlmICghRmNEaXJTYXZlIChzZXQsIHN1YmRpcnMsIGRpcikpCgkgICAgewoJCWZwcmludGYgKHN0ZGVyciwgIkNhbid0IHNhdmUgY2FjaGUgaW4gXCIlc1wiXG4iLCBkaXIpOwoJCXJldCsrOwoJICAgIH0KCX0KCUZjRm9udFNldERlc3Ryb3kgKHNldCk7CglzdWJsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzdWJkaXJzKTsKCWlmICghc3VibGlzdCkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBjcmVhdGUgc3ViZGlyIGxpc3QgaW4gXCIlc1wiXG4iLCBkaXIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJcmV0ICs9IHNjYW5EaXJzIChzdWJsaXN0LCBwcm9ncmFtLCBmb3JjZSwgdmVyYm9zZSk7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwogICAgfQogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICByZXR1cm4gcmV0Owp9CgppbnQKbWFpbiAoaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CiAgICBGY1N0clNldAkqZGlyczsKICAgIEZjU3RyTGlzdAkqbGlzdDsKICAgIEZjQm9vbCAgICAJdmVyYm9zZSA9IEZjRmFsc2U7CiAgICBGY0Jvb2wJZm9yY2UgPSBGY0ZhbHNlOwogICAgRmNDb25maWcJKmNvbmZpZzsKICAgIGludAkJaTsKICAgIGludAkJcmV0OwojaWYgSEFWRV9HRVRPUFRfTE9ORyB8fCBIQVZFX0dFVE9QVAogICAgaW50CQljOwoKI2lmIEhBVkVfR0VUT1BUX0xPTkcKICAgIHdoaWxlICgoYyA9IGdldG9wdF9sb25nIChhcmdjLCBhcmd2LCAiZlZ2PyIsIGxvbmdvcHRzLCBOVUxMKSkgIT0gLTEpCiNlbHNlCiAgICB3aGlsZSAoKGMgPSBnZXRvcHQgKGFyZ2MsIGFyZ3YsICJmVnY/IikpICE9IC0xKQojZW5kaWYKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnZic6CgkgICAgZm9yY2UgPSBGY1RydWU7CgkgICAgYnJlYWs7CgljYXNlICdWJzoKCSAgICBmcHJpbnRmIChzdGRlcnIsICJmb250Y29uZmlnIHZlcnNpb24gJWQuJWQuJWRcbiIsIAoJCSAgICAgRkNfTUFKT1IsIEZDX01JTk9SLCBGQ19SRVZJU0lPTik7CgkgICAgZXhpdCAoMCk7CgljYXNlICd2JzoKCSAgICB2ZXJib3NlID0gRmNUcnVlOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB1c2FnZSAoYXJndlswXSk7Cgl9CiAgICB9CiAgICBpID0gb3B0aW5kOwojZWxzZQogICAgaSA9IDE7CiNlbmRpZgoKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWcgKCk7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWZwcmludGYgKHN0ZGVyciwgIiVzOiBDYW4ndCBpbml0IGZvbnQgY29uZmlnIGxpYnJhcnlcbiIsIGFyZ3ZbMF0pOwoJcmV0dXJuIDE7CiAgICB9CiAgICBpZiAoYXJndltpXSkKICAgIHsKCWRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghZGlycykKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgY3JlYXRlIGxpc3Qgb2YgZGlyZWN0b3JpZXNcbiIsCgkJICAgICBhcmd2WzBdKTsKCSAgICByZXR1cm4gMTsKCX0KCXdoaWxlIChhcmd2W2ldKQoJewoJICAgIGlmICghRmNTdHJTZXRBZGQgKGRpcnMsIChGY0NoYXI4ICopIGFyZ3ZbaV0pKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgYWRkIGRpcmVjdG9yeVxuIiwgYXJndlswXSk7CgkJcmV0dXJuIDE7CgkgICAgfQoJICAgIGkrKzsKCX0KCWxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGRpcnMpOwoJRmNTdHJTZXREZXN0cm95IChkaXJzKTsKICAgIH0KICAgIGVsc2UKCWxpc3QgPSBGY0NvbmZpZ0dldENvbmZpZ0RpcnMgKGNvbmZpZyk7CiAgICByZXQgPSBzY2FuRGlycyAobGlzdCwgYXJndlswXSwgZm9yY2UsIHZlcmJvc2UpOwogICAgaWYgKHZlcmJvc2UpCglwcmludGYgKCIlczogJXNcbiIsIGFyZ3ZbMF0sIHJldCA/ICJmYWlsZWQiIDogInN1Y2NlZWRlZCIpOwogICAgcmV0dXJuIHJldDsKfQo=