LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPHBjaS5oPgojaW5jbHVkZSA8c3RkaW9fZGV2Lmg+CiNpbmNsdWRlIDxpODA0Mi5oPgojaW5jbHVkZSA8YXNtL3B0cmFjZS5oPgojaW5jbHVkZSA8YXNtL3JlYWxtb2RlLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9wY2kuaD4KCgovKiBiYXNpYyB0ZXh0bW9kZSBJL08gZnJvbSBsaW51eCBrZXJuZWwgKi8Kc3RhdGljIGNoYXIgKnZpZG1lbSA9IChjaGFyICopMHhiODAwMDsKc3RhdGljIGludCB2aWRwb3J0OwpzdGF0aWMgaW50IGxpbmVzLCBjb2xzOwpzdGF0aWMgaW50IG9yaWdfeCwgb3JpZ195OwoKc3RhdGljIHZvaWQgYmVlcChpbnQgZHVyKQp7CglpbnQgaTsKCglvdXRiX3AoMywgMHg2MSk7Cglmb3IgKGk9MDtpPDEwKmR1cjtpKyspIHsKCQl1ZGVsYXkoMTAwMCk7Cgl9CglvdXRiX3AoMCwgMHg2MSk7Cn0KCnN0YXRpYyB2b2lkIHNjcm9sbCh2b2lkKQp7CglpbnQgaTsKCgltZW1jcHkgKCB2aWRtZW0sIHZpZG1lbSArIGNvbHMgKiAyLCAoIGxpbmVzIC0gMSApICogY29scyAqIDIgKTsKCWZvciAoIGkgPSAoIGxpbmVzIC0gMSApICogY29scyAqIDI7IGkgPCBsaW5lcyAqIGNvbHMgKiAyOyBpICs9IDIgKQoJCXZpZG1lbVtpXSA9ICcgJzsKfQoKc3RhdGljIHZvaWQgX192aWRlb19wdXRjKGNvbnN0IGNoYXIgYywgaW50ICp4LCBpbnQgKnkpCnsKCWlmIChjID09ICdcbicpIHsKCQkoKngpID0gMDsKCQlpZiAoICsrKCp5KSA+PSBsaW5lcyApIHsKCQkJc2Nyb2xsKCk7CgkJCSgqeSktLTsKCQl9Cgl9IGVsc2UgaWYgKGMgPT0gJ1xiJykgewoJCWlmICgoKngpICE9IDApIHsKCQkJLS0oKngpOwoJCQl2aWRtZW0gWyAoICgqeCkgKyBjb2xzICogKCp5KSApICogMiBdID0gJyAnOwoJCX0KCX0gZWxzZSBpZiAoYyA9PSAnXHInKSB7CgkJKCp4KSA9IDA7CgoJfSBlbHNlIGlmIChjID09ICdcYScpIHsKCQliZWVwKDMpOwoKCX0gZWxzZSBpZiAoYyA9PSAnXHQnKSB7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7Cgl9IGVsc2UgaWYgKGMgPT0gJ1x2JykgewoJCXN3aXRjaCAoKCp4KSAlIDgpIHsKCQljYXNlIDA6CgkJCV9fdmlkZW9fcHV0YygnICcsIHgsIHkpOwoJCWNhc2UgNzoKCQkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJY2FzZSA2OgoJCQlfX3ZpZGVvX3B1dGMoJyAnLCB4LCB5KTsKCQljYXNlIDU6CgkJCV9fdmlkZW9fcHV0YygnICcsIHgsIHkpOwoJCWNhc2UgNDoKCQkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJY2FzZSAzOgoJCQlfX3ZpZGVvX3B1dGMoJyAnLCB4LCB5KTsKCQljYXNlIDI6CgkJCV9fdmlkZW9fcHV0YygnICcsIHgsIHkpOwoJCWNhc2UgMToKCQkJX192aWRlb19wdXRjKCcgJywgeCwgeSk7CgkJfQoJfSBlbHNlIGlmIChjID09ICdcZicpIHsKCQlpbnQgaTsKCQlmb3IgKGk9MDtpPGxpbmVzKmNvbHMqMjtpKz0yKSB7CgkJCXZpZG1lbVtpXSA9IDA7CgkJfQoJCSgqeCkgPSAwOwoJCSgqeSkgPSAwOwoJfSBlbHNlIHsKCQl2aWRtZW0gWyAoICgqeCkgKyBjb2xzICogKCp5KSApICogMiBdID0gYzsKCQlpZiAoICsrKCp4KSA+PSBjb2xzICkgewoJCQkoKngpID0gMDsKCQkJaWYgKCArKygqeSkgPj0gbGluZXMgKSB7CgkJCQlzY3JvbGwoKTsKCQkJCSgqeSktLTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIHZvaWQgdmlkZW9fcHV0Yyhjb25zdCBjaGFyIGMpCnsKCWludCB4LHkscG9zOwoKCXggPSBvcmlnX3g7Cgl5ID0gb3JpZ195OwoKCV9fdmlkZW9fcHV0YyhjLCAmeCwgJnkpOwoKCW9yaWdfeCA9IHg7CglvcmlnX3kgPSB5OwoKCXBvcyA9ICh4ICsgY29scyAqIHkpICogMjsJLyogVXBkYXRlIGN1cnNvciBwb3NpdGlvbiAqLwoJb3V0Yl9wKDE0LCB2aWRwb3J0KTsKCW91dGJfcCgweGZmICYgKHBvcyA+PiA5KSwgdmlkcG9ydCsxKTsKCW91dGJfcCgxNSwgdmlkcG9ydCk7CglvdXRiX3AoMHhmZiAmIChwb3MgPj4gMSksIHZpZHBvcnQrMSk7Cn0KCnN0YXRpYyB2b2lkIHZpZGVvX3B1dHMoY29uc3QgY2hhciAqcykKewoJaW50IHgseSxwb3M7CgljaGFyIGM7CgoJeCA9IG9yaWdfeDsKCXkgPSBvcmlnX3k7CgoJd2hpbGUgKCAoIGMgPSAqcysrICkgIT0gJ1wwJyApIHsKCQlfX3ZpZGVvX3B1dGMoYywgJngsICZ5KTsKCX0KCglvcmlnX3ggPSB4OwoJb3JpZ195ID0geTsKCglwb3MgPSAoeCArIGNvbHMgKiB5KSAqIDI7CS8qIFVwZGF0ZSBjdXJzb3IgcG9zaXRpb24gKi8KCW91dGJfcCgxNCwgdmlkcG9ydCk7CglvdXRiX3AoMHhmZiAmIChwb3MgPj4gOSksIHZpZHBvcnQrMSk7CglvdXRiX3AoMTUsIHZpZHBvcnQpOwoJb3V0Yl9wKDB4ZmYgJiAocG9zID4+IDEpLCB2aWRwb3J0KzEpOwp9CgppbnQgdmlkZW9faW5pdCh2b2lkKQp7Cgl1MTYgcG9zOwoKCXN0YXRpYyBzdHJ1Y3Qgc3RkaW9fZGV2IHZnYV9kZXY7CglzdGF0aWMgc3RydWN0IHN0ZGlvX2RldiBrYmRfZGV2OwoKCXZpZG1lbSA9IChjaGFyICopIDB4YjgwMDA7Cgl2aWRwb3J0ID0gMHgzZDQ7CgoJbGluZXMgPSAyNTsKCWNvbHMgPSA4MDsKCglvdXRiX3AoMTQsIHZpZHBvcnQpOwoJcG9zID0gaW5iX3AodmlkcG9ydCsxKTsKCXBvcyA8PD0gODsKCW91dGJfcCgxNSwgdmlkcG9ydCk7Cglwb3MgfD0gaW5iX3AodmlkcG9ydCsxKTsKCglvcmlnX3ggPSBwb3MlY29sczsKCW9yaWdfeSA9IHBvcy9jb2xzOwoKI2lmIDAKCXByaW50ZigicG9zICV4ICVkICVkXG4iLCBwb3MsIG9yaWdfeCwgb3JpZ195KTsKI2VuZGlmCglpZiAob3JpZ195ID4gbGluZXMpIHsKCQlvcmlnX3ggPSBvcmlnX3kgPTA7Cgl9CgoKCW1lbXNldCgmdmdhX2RldiwgMCwgc2l6ZW9mKHZnYV9kZXYpKTsKCXN0cmNweSh2Z2FfZGV2Lm5hbWUsICJ2Z2EiKTsKCXZnYV9kZXYuZXh0ICAgPSAwOwoJdmdhX2Rldi5mbGFncyA9IERFVl9GTEFHU19PVVRQVVQgfCBERVZfRkxBR1NfU1lTVEVNOwoJdmdhX2Rldi5wdXRjICA9IHZpZGVvX3B1dGM7ICAgICAgICAvKiAncHV0YycgZnVuY3Rpb24gKi8KCXZnYV9kZXYucHV0cyAgPSB2aWRlb19wdXRzOyAgICAgICAgLyogJ3B1dHMnIGZ1bmN0aW9uICovCgl2Z2FfZGV2LnRzdGMgID0gTlVMTDsgICAgICAgICAgICAgIC8qICd0c3RjJyBmdW5jdGlvbiAqLwoJdmdhX2Rldi5nZXRjICA9IE5VTEw7ICAgICAgICAgICAgICAvKiAnZ2V0YycgZnVuY3Rpb24gKi8KCglpZiAoc3RkaW9fcmVnaXN0ZXIoJnZnYV9kZXYpID09IDApIHsKCSAgICByZXR1cm4gMTsKCX0KCglpZiAoaTgwNDJfa2JkX2luaXQoKSkgewoJCXJldHVybiAxOwoJfQoKCW1lbXNldCgma2JkX2RldiwgMCwgc2l6ZW9mKGtiZF9kZXYpKTsKCXN0cmNweShrYmRfZGV2Lm5hbWUsICJrYmQiKTsKCWtiZF9kZXYuZXh0ICAgPSAwOwoJa2JkX2Rldi5mbGFncyA9IERFVl9GTEFHU19JTlBVVCB8IERFVl9GTEFHU19TWVNURU07CglrYmRfZGV2LnB1dGMgID0gTlVMTDsgICAgICAgIC8qICdwdXRjJyBmdW5jdGlvbiAqLwoJa2JkX2Rldi5wdXRzICA9IE5VTEw7ICAgICAgICAvKiAncHV0cycgZnVuY3Rpb24gKi8KCWtiZF9kZXYudHN0YyAgPSBpODA0Ml90c3RjOyAgLyogJ3RzdGMnIGZ1bmN0aW9uICovCglrYmRfZGV2LmdldGMgID0gaTgwNDJfZ2V0YzsgIC8qICdnZXRjJyBmdW5jdGlvbiAqLwoKCWlmIChzdGRpb19yZWdpc3Rlcigma2JkX2RldikgPT0gMCkgewoJICAgIHJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCgppbnQgZHJ2X3ZpZGVvX2luaXQodm9pZCkKewoJaWYgKHZpZGVvX2Jpb3NfaW5pdCgpKSB7CgkJcmV0dXJuIDE7Cgl9CgoJcmV0dXJuIHZpZGVvX2luaXQoKTsKfQo=