LyoKICogQ29weXJpZ2h0IChjKSAxOTgzLCAxOTg5LCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICovCgogLyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAgKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAgKi8KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDxzeXMvcmVzb3VyY2UuaD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgIm5scy5oIgoKaW50IGRvbmljZShpbnQsaW50LGludCk7Cgp2b2lkIHVzYWdlKGludCByYykKewoJcHJpbnRmKCBfKCJcblVzYWdlOlxuIgoJCSIgcmVuaWNlIFstbl0gcHJpb3JpdHkgWy1wfC0tcGlkXSBwaWQgIFsuLi4gcGlkXVxuIgoJCSIgcmVuaWNlIFstbl0gcHJpb3JpdHkgIC1nfC0tcGdycCBwZ3JwIFsuLi4gcGdycF1cbiIKCQkiIHJlbmljZSBbLW5dIHByaW9yaXR5ICAtdXwtLXVzZXIgdXNlciBbLi4uIHVzZXJdXG4iCgkJIiByZW5pY2UgLWggfCAtLWhlbHBcbiIKCQkiIHJlbmljZSAtdiB8IC0tdmVyc2lvblxuXG4iKSk7CgoJZXhpdChyYyk7Cn0KCi8qCiAqIENoYW5nZSB0aGUgcHJpb3JpdHkgKG5pY2UpIG9mIHByb2Nlc3NlcwogKiBvciBncm91cHMgb2YgcHJvY2Vzc2VzIHdoaWNoIGFyZSBhbHJlYWR5CiAqIHJ1bm5pbmcuCiAqLwppbnQKbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWludCB3aGljaCA9IFBSSU9fUFJPQ0VTUzsKCWludCB3aG8gPSAwLCBwcmlvLCBlcnJzID0gMDsKCWNoYXIgKmVuZHB0ciA9IE5VTEw7CgoJc2V0bG9jYWxlKExDX0FMTCwgIiIpOwoJYmluZHRleHRkb21haW4oUEFDS0FHRSwgTE9DQUxFRElSKTsKCXRleHRkb21haW4oUEFDS0FHRSk7CgoJYXJnYy0tOwoJYXJndisrOwoKCWlmIChhcmdjID09IDEpIHsKCQlpZiAoc3RyY21wKCphcmd2LCAiLWgiKSA9PSAwIHx8CgkJICAgIHN0cmNtcCgqYXJndiwgIi0taGVscCIpID09IDApCgkJCXVzYWdlKEVYSVRfU1VDQ0VTUyk7CgoJCWlmIChzdHJjbXAoKmFyZ3YsICItdiIpID09IDAgfHwKCQkgICAgc3RyY21wKCphcmd2LCAiLS12ZXJzaW9uIikgPT0gMCkgewoJCQlwcmludGYoXygicmVuaWNlIGZyb20gJXNcbiIpLCBQQUNLQUdFX1NUUklORyk7CgkJCWV4aXQoRVhJVF9TVUNDRVNTKTsKCQl9Cgl9CgoJaWYgKGFyZ2MgPCAyKQoJCXVzYWdlKEVYSVRfRkFJTFVSRSk7CgoJaWYgKHN0cmNtcCgqYXJndiwgIi1uIikgPT0gMCB8fCBzdHJjbXAoKmFyZ3YsICItLXByaW9yaXR5IikgPT0gMCkgewoJCWFyZ2MtLTsKCQlhcmd2Kys7Cgl9CgoJcHJpbyA9IHN0cnRvbCgqYXJndiwgJmVuZHB0ciwgMTApOwoJaWYgKCplbmRwdHIpCgkJdXNhZ2UoRVhJVF9GQUlMVVJFKTsKCglhcmdjLS07Cglhcmd2Kys7CgoJZm9yICg7IGFyZ2MgPiAwOyBhcmdjLS0sIGFyZ3YrKykgewoJCWlmIChzdHJjbXAoKmFyZ3YsICItZyIpID09IDAgfHwgc3RyY21wKCphcmd2LCAiLS1wZ3JwIikgPT0gMCkgewoJCQl3aGljaCA9IFBSSU9fUEdSUDsKCQkJY29udGludWU7CgkJfQoJCWlmIChzdHJjbXAoKmFyZ3YsICItdSIpID09IDAgfHwgc3RyY21wKCphcmd2LCAiLS11c2VyIikgPT0gMCkgewoJCQl3aGljaCA9IFBSSU9fVVNFUjsKCQkJY29udGludWU7CgkJfQoJCWlmIChzdHJjbXAoKmFyZ3YsICItcCIpID09IDAgfHwgc3RyY21wKCphcmd2LCAiLS1waWQiKSA9PSAwKSB7CgkJCXdoaWNoID0gUFJJT19QUk9DRVNTOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHdoaWNoID09IFBSSU9fVVNFUikgewoJCQlyZWdpc3RlciBzdHJ1Y3QgcGFzc3dkICpwd2QgPSBnZXRwd25hbSgqYXJndik7CgoJCQlpZiAocHdkID09IE5VTEwpIHsKCQkJCWZwcmludGYoc3RkZXJyLCBfKCJyZW5pY2U6ICVzOiB1bmtub3duIHVzZXJcbiIpLAoJCQkJCSphcmd2KTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCXdobyA9IHB3ZC0+cHdfdWlkOwoJCX0gZWxzZSB7CgkJCXdobyA9IHN0cnRvbCgqYXJndiwgJmVuZHB0ciwgMTApOwoJCQlpZiAod2hvIDwgMCB8fCAqZW5kcHRyKSB7CgkJCQlmcHJpbnRmKHN0ZGVyciwgXygicmVuaWNlOiAlczogYmFkIHZhbHVlXG4iKSwKCQkJCQkqYXJndik7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQllcnJzICs9IGRvbmljZSh3aGljaCwgd2hvLCBwcmlvKTsKCX0KCXJldHVybiBlcnJzICE9IDAgPyBFWElUX0ZBSUxVUkUgOiBFWElUX1NVQ0NFU1M7Cn0KCmludApkb25pY2UoaW50IHdoaWNoLCBpbnQgd2hvLCBpbnQgcHJpbykgewoJaW50IG9sZHByaW8sIG5ld3ByaW87CgoJZXJybm8gPSAwOwoJb2xkcHJpbyA9IGdldHByaW9yaXR5KHdoaWNoLCB3aG8pOwoJaWYgKG9sZHByaW8gPT0gLTEgJiYgZXJybm8pIHsKCQlmcHJpbnRmKHN0ZGVyciwgInJlbmljZTogJWQ6ICIsIHdobyk7CgkJcGVycm9yKF8oImdldHByaW9yaXR5IikpOwoJCXJldHVybiAxOwoJfQoJaWYgKHNldHByaW9yaXR5KHdoaWNoLCB3aG8sIHByaW8pIDwgMCkgewoJCWZwcmludGYoc3RkZXJyLCAicmVuaWNlOiAlZDogIiwgd2hvKTsKCQlwZXJyb3IoXygic2V0cHJpb3JpdHkiKSk7CgkJcmV0dXJuIDE7Cgl9CgllcnJubyA9IDA7CgluZXdwcmlvID0gZ2V0cHJpb3JpdHkod2hpY2gsIHdobyk7CglpZiAobmV3cHJpbyA9PSAtMSAmJiBlcnJubykgewoJCWZwcmludGYoc3RkZXJyLCAicmVuaWNlOiAlZDogIiwgd2hvKTsKCQlwZXJyb3IoXygiZ2V0cHJpb3JpdHkiKSk7CgkJcmV0dXJuIDE7Cgl9CgoJcHJpbnRmKF8oIiVkOiBvbGQgcHJpb3JpdHkgJWQsIG5ldyBwcmlvcml0eSAlZFxuIiksCgkgICAgICAgd2hvLCBvbGRwcmlvLCBuZXdwcmlvKTsKCXJldHVybiAwOwp9Cg==