LyogZG1lc2cuYyAtLSBQcmludCBvdXQgdGhlIGNvbnRlbnRzIG9mIHRoZSBrZXJuZWwgcmluZyBidWZmZXIKICogQ3JlYXRlZDogU2F0IE9jdCAgOSAxNjoxOTo0NyAxOTkzCiAqIFJldmlzZWQ6IFRodSBPY3QgMjggMjE6NTI6MTcgMTk5MyBieSBmYWl0aEBjcy51bmMuZWR1CiAqIENvcHlyaWdodCAxOTkzIFRoZW9kb3JlIFRzJ28gKHR5dHNvQGF0aGVuYS5taXQuZWR1KQogKiBUaGlzIHByb2dyYW0gY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLgogKiBNb2RpZmljYXRpb25zIGJ5IFJpY2sgU2xhZGtleSAoanJzQHdvcmxkLnN0ZC5jb20pCiAqIExhcmdlciBidWZmZXJzaXplIDMgSnVuZSAxOTk4IGJ5IE5pY29sYWkgTGFuZ2ZlbGR0LCBiYXNlZCBvbiBhIHBhdGNoCiAqIGJ5IFBlZXRlciBKb290LiAgVGhpcyB3YXMgYWxzbyBzdWdnZXN0ZWQgYnkgSm9obiBIdWRzb24uCiAqIDE5OTktMDItMjIgQXJrYWRpdXN6IE1ptmtpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAqCiAqLwoKLyoKICogQ29tbWFuZHMgdG8gc3lzX3N5c2xvZzoKICoKICogICAgICAwIC0tIENsb3NlIHRoZSBsb2cuICBDdXJyZW50bHkgYSBOT1AuCiAqICAgICAgMSAtLSBPcGVuIHRoZSBsb2cuIEN1cnJlbnRseSBhIE5PUC4KICogICAgICAyIC0tIFJlYWQgZnJvbSB0aGUgbG9nLgogKiAgICAgIDMgLS0gUmVhZCBhbGwgbWVzc2FnZXMgcmVtYWluaW5nIGluIHRoZSByaW5nIGJ1ZmZlci4KICogICAgICA0IC0tIFJlYWQgYW5kIGNsZWFyIGFsbCBtZXNzYWdlcyByZW1haW5pbmcgaW4gdGhlIHJpbmcgYnVmZmVyCiAqICAgICAgNSAtLSBDbGVhciByaW5nIGJ1ZmZlci4KICogICAgICA2IC0tIERpc2FibGUgcHJpbnRrJ3MgdG8gY29uc29sZQogKiAgICAgIDcgLS0gRW5hYmxlIHByaW50aydzIHRvIGNvbnNvbGUKICogICAgICA4IC0tIFNldCBsZXZlbCBvZiBtZXNzYWdlcyBwcmludGVkIHRvIGNvbnNvbGUKICogICAgICA5IC0tIFJldHVybiBudW1iZXIgb2YgdW5yZWFkIGNoYXJhY3RlcnMgaW4gdGhlIGxvZyBidWZmZXIKICogICAgICAgICAgIFtzdXBwb3J0ZWQgc2luY2UgMi40LjEwXQogKgogKiBPbmx5IGZ1bmN0aW9uIDMgaXMgYWxsb3dlZCB0byBub24tcm9vdCBwcm9jZXNzZXMuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3VuaXN0ZC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiMgaW5jbHVkZSA8c3lzL2tsb2cuaD4KCiNpbmNsdWRlICJubHMuaCIKCnN0YXRpYyBjaGFyICpwcm9nbmFtZTsKCnN0YXRpYyB2b2lkCnVzYWdlKHZvaWQpIHsKCWZwcmludGYoc3RkZXJyLAoJCV8oIlVzYWdlOiAlcyBbLWNdIFstbiBsZXZlbF0gWy1yXSBbLXMgYnVmc2l6ZV1cbiIpLCBwcm9nbmFtZSk7Cn0KCmludAptYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsKCWNoYXIgKmJ1ZjsKCWludCAgc3o7CglpbnQgIGJ1ZnNpemUgPSAwOwoJaW50ICBpOwoJaW50ICBuOwoJaW50ICBjOwoJaW50ICBsZXZlbCA9IDA7CglpbnQgIGxhc3RjOwoJaW50ICBjbWQgPSAzOwkJLyogUmVhZCBhbGwgbWVzc2FnZXMgaW4gdGhlIHJpbmcgYnVmZmVyICovCglpbnQgIHJhdyA9IDA7CgoJc2V0bG9jYWxlKExDX0FMTCwgIiIpOwoJYmluZHRleHRkb21haW4oUEFDS0FHRSwgTE9DQUxFRElSKTsKCXRleHRkb21haW4oUEFDS0FHRSk7CgoJcHJvZ25hbWUgPSBhcmd2WzBdOwoJd2hpbGUgKChjID0gZ2V0b3B0KGFyZ2MsIGFyZ3YsICJjcm46czoiKSkgIT0gLTEpIHsKCQlzd2l0Y2ggKGMpIHsKCQljYXNlICdjJzoKCQkJY21kID0gNDsJLyogUmVhZCBhbmQgY2xlYXIgYWxsIG1lc3NhZ2VzICovCgkJCWJyZWFrOwoJCWNhc2UgJ24nOgoJCQljbWQgPSA4OwkvKiBTZXQgbGV2ZWwgb2YgbWVzc2FnZXMgKi8KCQkJbGV2ZWwgPSBhdG9pKG9wdGFyZyk7CgkJCWJyZWFrOwoJCWNhc2UgJ3InOgoJCQlyYXcgPSAxOwoJCQlicmVhazsKCQljYXNlICdzJzoKCQkJYnVmc2l6ZSA9IGF0b2kob3B0YXJnKTsKCQkJaWYgKGJ1ZnNpemUgPCA0MDk2KQoJCQkJYnVmc2l6ZSA9IDQwOTY7CgkJCWJyZWFrOwoJCWNhc2UgJz8nOgoJCWRlZmF1bHQ6CgkJCXVzYWdlKCk7CgkJCWV4aXQoMSk7CgkJfQoJfQoJYXJnYyAtPSBvcHRpbmQ7Cglhcmd2ICs9IG9wdGluZDsKCglpZiAoYXJnYyA+IDEpIHsKCQl1c2FnZSgpOwoJCWV4aXQoMSk7Cgl9CgoJaWYgKGNtZCA9PSA4KSB7CgkJbiA9IGtsb2djdGwoY21kLCBOVUxMLCBsZXZlbCk7CgkJaWYgKG4gPCAwKSB7CgkJCXBlcnJvcigia2xvZ2N0bCIpOwoJCQlleGl0KDEpOwoJCX0KCQlleGl0KDApOwoJfQoKCWlmICghYnVmc2l6ZSkgewoJCW4gPSBrbG9nY3RsKDEwLCBOVUxMLCAwKTsJLyogcmVhZCByaW5nYnVmZmVyIHNpemUgKi8KCQlpZiAobiA+IDApCgkJCWJ1ZnNpemUgPSBuOwoJfQoKCWlmIChidWZzaXplKSB7CgkJc3ogPSBidWZzaXplICsgODsKCQlidWYgPSAoY2hhciAqKSBtYWxsb2Moc3opOwoJCW4gPSBrbG9nY3RsKGNtZCwgYnVmLCBzeik7Cgl9IGVsc2UgewoJCXN6ID0gMTYzOTI7CgkJd2hpbGUgKDEpIHsKCQkJYnVmID0gKGNoYXIgKikgbWFsbG9jKHN6KTsKCQkJbiA9IGtsb2djdGwoMywgYnVmLCBzeik7CS8qIHJlYWQgb25seSAqLwoJCQlpZiAobiAhPSBzeiB8fCBzeiA+ICgxPDwyOCkpCgkJCQlicmVhazsKCQkJZnJlZShidWYpOwoJCQlzeiAqPSA0OwoJCX0KCgkJaWYgKG4gPiAwICYmIGNtZCA9PSA0KQoJCQluID0ga2xvZ2N0bChjbWQsIGJ1Ziwgc3opOwkvKiByZWFkIGFuZCBjbGVhciAqLwoJfQoKCWlmIChuIDwgMCkgewoJCXBlcnJvcigia2xvZ2N0bCIpOwoJCWV4aXQoMSk7Cgl9CgoJbGFzdGMgPSAnXG4nOwoJZm9yIChpID0gMDsgaSA8IG47IGkrKykgewoJCWlmICghcmF3ICYmIChpID09IDAgfHwgYnVmW2kgLSAxXSA9PSAnXG4nKSAmJiBidWZbaV0gPT0gJzwnKSB7CgkJCWkrKzsKCQkJd2hpbGUgKGJ1ZltpXSA+PSAnMCcgJiYgYnVmW2ldIDw9ICc5JykKCQkJCWkrKzsKCQkJaWYgKGJ1ZltpXSA9PSAnPicpCgkJCQlpKys7CgkJfQoJCWxhc3RjID0gYnVmW2ldOwoJCXB1dGNoYXIobGFzdGMpOwoJfQoJaWYgKGxhc3RjICE9ICdcbicpCgkJcHV0Y2hhcignXG4nKTsKCXJldHVybiAwOwp9Cg==