LyoKICogQ29weXJpZ2h0IChjKSAxOTgwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICovCgovKgogKiBtb2RpZmllZCBieSBLYXJzIGRlIEpvbmcgPGpvbmdrQGNzLnV0d2VudGUubmw+CiAqCXRvIHVzZSB0ZXJtaW5mbyBpbnN0ZWFkIG9mIHRlcm1jYXAuCiAqIDE5OTktMDItMjIgQXJrYWRpdXN6IE1ptmtpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAJYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogMTk5OS0wOS0xOSBCcnVubyBIYWlibGUgPGhhaWJsZUBjbGlzcC5jb25zLm9yZz4KICogCW1vZGlmaWVkIHRvIHdvcmsgY29ycmVjdGx5IGluIG11bHRpLWJ5dGUgbG9jYWxlcwogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CQkvKiBmb3IgZ2V0b3B0KCksIGlzYXR0eSgpICovCiNpbmNsdWRlIDxzdHJpbmcuaD4JCS8qIGZvciBiemVybygpLCBzdHJjcHkoKSAqLwojaW5jbHVkZSA8dGVybS5oPgkJLyogZm9yIHNldHVwdGVybSgpICovCiNpbmNsdWRlIDxzdGRsaWIuaD4JCS8qIGZvciBnZXRlbnYoKSAqLwojaW5jbHVkZSA8bGltaXRzLmg+CQkvKiBmb3IgSU5UX01BWCAqLwojaW5jbHVkZSAibmxzLmgiCgojaW5jbHVkZSAid2lkZWNoYXIuaCIKCiNpZmRlZiBIQVZFX1dJREVDSEFSCnN0YXRpYyBpbnQgcHV0MXdjKGludCBjKSAvKiBPdXRwdXQgYW4gQVNDSUkgY2hhcmFjdGVyIGFzIGEgd2lkZSBjaGFyYWN0ZXIgKi8KewogIGlmIChwdXR3Y2hhcihjKSA9PSBXRU9GKQogICAgcmV0dXJuIEVPRjsKICBlbHNlCiAgICByZXR1cm4gYzsKfQojZGVmaW5lIHB1dHdwKHMpIHRwdXRzKHMsMSxwdXQxd2MpCiNlbHNlCiNkZWZpbmUgcHV0d3AocykgcHV0cChzKQojZW5kaWYKCnZvaWQgZmlsdGVyKEZJTEUgKmYpOwp2b2lkIGZsdXNobG4odm9pZCk7CnZvaWQgb3ZlcnN0cmlrZSh2b2lkKTsKdm9pZCBpYXR0cih2b2lkKTsKdm9pZCBpbml0YnVmKHZvaWQpOwp2b2lkIGZ3ZCh2b2lkKTsKdm9pZCByZXZlcnNlKHZvaWQpOwp2b2lkIGluaXRpbmZvKHZvaWQpOwp2b2lkIG91dGMod2ludF90IGMsIGludCB3aWR0aCk7CnZvaWQgc2V0bW9kZShpbnQgbmV3bW9kZSk7CnN0YXRpYyB2b2lkIHNldGNvbChpbnQgbmV3Y29sKTsKc3RhdGljIHZvaWQgbmVlZGNvbChpbnQgY29sKTsKCiNkZWZpbmUJSUVTQwknXDAzMycKI2RlZmluZQlTTwknXDAxNicKI2RlZmluZQlTSQknXDAxNycKI2RlZmluZQlIRldECSc5JwojZGVmaW5lCUhSRVYJJzgnCiNkZWZpbmUJRlJFVgknNycKCiNkZWZpbmUJTk9STUFMCTAwMAojZGVmaW5lCUFMVFNFVAkwMDEJLyogUmV2ZXJzZSAqLwojZGVmaW5lCVNVUEVSU0MJMDAyCS8qIERpbSAqLwojZGVmaW5lCVNVQlNDCTAwNAkvKiBEaW0gfCBVbCAqLwojZGVmaW5lCVVOREVSTAkwMTAJLyogVWwgKi8KI2RlZmluZQlCT0xECTAyMAkvKiBCb2xkICovCiNkZWZpbmUJSU5JVEJVRgk1MTIKCmludAltdXN0X3VzZV91YywgbXVzdF9vdmVyc3RyaWtlOwpjaGFyCSpDVVJTX1VQLCAqQ1VSU19SSUdIVCwgKkNVUlNfTEVGVCwKCSpFTlRFUl9TVEFORE9VVCwgKkVYSVRfU1RBTkRPVVQsICpFTlRFUl9VTkRFUkxJTkUsICpFWElUX1VOREVSTElORSwKCSpFTlRFUl9ESU0sICpFTlRFUl9CT0xELCAqRU5URVJfUkVWRVJTRSwgKlVOREVSX0NIQVIsICpFWElUX0FUVFJJQlVURVM7CgpzdHJ1Y3QJQ0hBUgl7CgljaGFyCWNfbW9kZTsKCXdjaGFyX3QJY19jaGFyOwoJaW50CWNfd2lkdGg7Cn0gOwoKc3RydWN0CUNIQVIJKm9idWY7CmludAlvYnVmbGVuOwkJLyogVHJhY2tzIG51bWJlciBvZiBlbGVtZW50cyBpbiBvYnVmLiAqLwppbnQJY29sLCBtYXhjb2w7CmludAltb2RlOwppbnQJaGFsZnBvczsKaW50CXVwbG47CmludAlpZmxhZzsKCiNkZWZpbmUJUFJJTlQocykJaWYgKHMgPT0gTlVMTCkgLyogdm9pZCAqLzsgZWxzZSBwdXR3cChzKQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CglpbnQgYywgcmV0OwoJY2hhciAqdGVybXR5cGU7CglGSUxFICpmOwoKCXNldGxvY2FsZShMQ19BTEwsICIiKTsKCWJpbmR0ZXh0ZG9tYWluKFBBQ0tBR0UsIExPQ0FMRURJUik7Cgl0ZXh0ZG9tYWluKFBBQ0tBR0UpOwoKCXRlcm10eXBlID0gZ2V0ZW52KCJURVJNIik7CglpZiAodGVybXR5cGUgPT0gTlVMTCB8fCAoYXJndlswXVswXSA9PSAnYycgJiYgIWlzYXR0eSgxKSkpCgkJdGVybXR5cGUgPSAibHByIjsKCXdoaWxlICgoYyA9IGdldG9wdChhcmdjLCBhcmd2LCAiaXQ6VDoiKSkgIT0gLTEpCgkJc3dpdGNoKGMpIHsKCgkJY2FzZSAndCc6CgkJY2FzZSAnVCc6IC8qIGZvciBucm9mZiBjb21wYXRpYmlsaXR5ICovCgkJCQl0ZXJtdHlwZSA9IG9wdGFyZzsKCQkJYnJlYWs7CgkJY2FzZSAnaSc6CgkJCWlmbGFnID0gMTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWZwcmludGYoc3RkZXJyLAoJCQkJXygidXNhZ2U6ICVzIFsgLWkgXSBbIC10VGVybSBdIGZpbGUuLi5cbiIpLAoJCQkJYXJndlswXSk7CgkJCWV4aXQoMSk7CgkJfQoJc2V0dXB0ZXJtKHRlcm10eXBlLCAxLCAmcmV0KTsKCXN3aXRjaChyZXQpIHsKCgljYXNlIDE6CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlmcHJpbnRmKHN0ZGVycixfKCJ0cm91YmxlIHJlYWRpbmcgdGVybWluZm8iKSk7CgkJLyogZmFsbCB0aHJvdWdoIHRvIC4uLiAqLwoKCWNhc2UgMDoKCQkvKiBObyBzdWNoIHRlcm1pbmFsIHR5cGUgLSBhc3N1bWUgZHVtYiAqLwoJICAgICAgICBzZXR1cHRlcm0oImR1bWIiLCAxLCAoaW50ICopMCk7CgkJYnJlYWs7Cgl9Cglpbml0aW5mbygpOwoJaWYgKCAgICAodGlnZXRmbGFnKCJvcyIpICYmIEVOVEVSX0JPTEQ9PU5VTEwgKSB8fAoJCSh0aWdldGZsYWcoInVsIikgJiYgRU5URVJfVU5ERVJMSU5FPT1OVUxMICYmIFVOREVSX0NIQVI9PU5VTEwpKQoJCQltdXN0X292ZXJzdHJpa2UgPSAxOwoJaW5pdGJ1ZigpOwoJaWYgKG9wdGluZCA9PSBhcmdjKQoJCWZpbHRlcihzdGRpbik7CgllbHNlIGZvciAoOyBvcHRpbmQ8YXJnYzsgb3B0aW5kKyspIHsKCQlmID0gZm9wZW4oYXJndltvcHRpbmRdLCJyIik7CgkJaWYgKGYgPT0gTlVMTCkgewoJCQlwZXJyb3IoYXJndltvcHRpbmRdKTsKCQkJZXhpdCgxKTsKCQl9IGVsc2UKCQkJZmlsdGVyKGYpOwoJfQoJaWYgKGZlcnJvcihzdGRvdXQpIHx8IGZjbG9zZShzdGRvdXQpKQoJCXJldHVybiAxOwoJcmV0dXJuIDA7Cn0KCnZvaWQgZmlsdGVyKEZJTEUgKmYpCnsKCXdpbnRfdCBjOwoJaW50IGksIHc7CgoJd2hpbGUgKChjID0gZ2V0d2MoZikpICE9IFdFT0YpIHN3aXRjaChjKSB7CgoJY2FzZSAnXGInOgoJCXNldGNvbChjb2wgLSAxKTsKCQljb250aW51ZTsKCgljYXNlICdcdCc6CgkJc2V0Y29sKChjb2wrOCkgJiB+MDcpOwoJCWNvbnRpbnVlOwoKCWNhc2UgJ1xyJzoKCQlzZXRjb2woMCk7CgkJY29udGludWU7CgoJY2FzZSBTTzoKCQltb2RlIHw9IEFMVFNFVDsKCQljb250aW51ZTsKCgljYXNlIFNJOgoJCW1vZGUgJj0gfkFMVFNFVDsKCQljb250aW51ZTsKCgljYXNlIElFU0M6CgkJc3dpdGNoIChjID0gZ2V0d2MoZikpIHsKCgkJY2FzZSBIUkVWOgoJCQlpZiAoaGFsZnBvcyA9PSAwKSB7CgkJCQltb2RlIHw9IFNVUEVSU0M7CgkJCQloYWxmcG9zLS07CgkJCX0gZWxzZSBpZiAoaGFsZnBvcyA+IDApIHsKCQkJCW1vZGUgJj0gflNVQlNDOwoJCQkJaGFsZnBvcy0tOwoJCQl9IGVsc2UgewoJCQkJaGFsZnBvcyA9IDA7CgkJCQlyZXZlcnNlKCk7CgkJCX0KCQkJY29udGludWU7CgoJCWNhc2UgSEZXRDoKCQkJaWYgKGhhbGZwb3MgPT0gMCkgewoJCQkJbW9kZSB8PSBTVUJTQzsKCQkJCWhhbGZwb3MrKzsKCQkJfSBlbHNlIGlmIChoYWxmcG9zIDwgMCkgewoJCQkJbW9kZSAmPSB+U1VQRVJTQzsKCQkJCWhhbGZwb3MrKzsKCQkJfSBlbHNlIHsKCQkJCWhhbGZwb3MgPSAwOwoJCQkJZndkKCk7CgkJCX0KCQkJY29udGludWU7CgoJCWNhc2UgRlJFVjoKCQkJcmV2ZXJzZSgpOwoJCQljb250aW51ZTsKCgkJZGVmYXVsdDoKCQkJZnByaW50ZihzdGRlcnIsCgkJCQlfKCJVbmtub3duIGVzY2FwZSBzZXF1ZW5jZSBpbiBpbnB1dDogJW8sICVvXG4iKSwKCQkJCUlFU0MsIGMpOwoJCQlleGl0KDEpOwoJCX0KCQljb250aW51ZTsKCgljYXNlICdfJzoKCQlpZiAob2J1Zltjb2xdLmNfY2hhciB8fCBvYnVmW2NvbF0uY193aWR0aCA8IDApIHsKCQkJd2hpbGUoY29sID4gMCAmJiBvYnVmW2NvbF0uY193aWR0aCA8IDApCgkJCQljb2wtLTsKCQkJdyA9IG9idWZbY29sXS5jX3dpZHRoOwoJCQlmb3IgKGkgPSAwOyBpIDwgdzsgaSsrKQoJCQkJb2J1Zltjb2wrK10uY19tb2RlIHw9IFVOREVSTCB8IG1vZGU7CgkJCXNldGNvbChjb2wpOwoJCQljb250aW51ZTsKCQl9CgkJb2J1Zltjb2xdLmNfY2hhciA9ICdfJzsKCQlvYnVmW2NvbF0uY193aWR0aCA9IDE7CgkJLyogZmFsbCB0aHJvdWdoICovCgljYXNlICcgJzoKCQlzZXRjb2woY29sICsgMSk7CgkJY29udGludWU7CgoJY2FzZSAnXG4nOgoJCWZsdXNobG4oKTsKCQljb250aW51ZTsKCgljYXNlICdcZic6CgkJZmx1c2hsbigpOwoJCXB1dHdjaGFyKCdcZicpOwoJCWNvbnRpbnVlOwoKCWRlZmF1bHQ6CgkJaWYgKCFpc3dwcmludChjKSkJLyogbm9uIHByaW50aW5nICovCgkJCWNvbnRpbnVlOwoJCXcgPSB3Y3dpZHRoKGMpOwoJCW5lZWRjb2woY29sICsgdyk7CgkJaWYgKG9idWZbY29sXS5jX2NoYXIgPT0gJ1wwJykgewoJCQlvYnVmW2NvbF0uY19jaGFyID0gYzsKCQkJZm9yIChpID0gMDsgaSA8IHc7IGkrKykKCQkJCW9idWZbY29sK2ldLmNfbW9kZSA9IG1vZGU7CgkJCW9idWZbY29sXS5jX3dpZHRoID0gdzsKCQkJZm9yIChpID0gMTsgaSA8IHc7IGkrKykKCQkJCW9idWZbY29sK2ldLmNfd2lkdGggPSAtMTsKCQl9IGVsc2UgaWYgKG9idWZbY29sXS5jX2NoYXIgPT0gJ18nKSB7CgkJCW9idWZbY29sXS5jX2NoYXIgPSBjOwoJCQlmb3IgKGkgPSAwOyBpIDwgdzsgaSsrKQoJCQkJb2J1Zltjb2wraV0uY19tb2RlIHw9IFVOREVSTHxtb2RlOwoJCQlvYnVmW2NvbF0uY193aWR0aCA9IHc7CgkJCWZvciAoaSA9IDE7IGkgPCB3OyBpKyspCgkJCQlvYnVmW2NvbCtpXS5jX3dpZHRoID0gLTE7CgkJfSBlbHNlIGlmIChvYnVmW2NvbF0uY19jaGFyID09IGMpIHsKCQkJZm9yIChpID0gMDsgaSA8IHc7IGkrKykKCQkJCW9idWZbY29sK2ldLmNfbW9kZSB8PSBCT0xEfG1vZGU7CgkJfSBlbHNlIHsKCQkJdyA9IG9idWZbY29sXS5jX3dpZHRoOwoJCQlmb3IgKGkgPSAwOyBpIDwgdzsgaSsrKQoJCQkJb2J1Zltjb2wraV0uY19tb2RlID0gbW9kZTsKCQl9CgkJc2V0Y29sKGNvbCArIHcpOwoJCWNvbnRpbnVlOwoJfQoJaWYgKG1heGNvbCkKCQlmbHVzaGxuKCk7Cn0KCnZvaWQgZmx1c2hsbih2b2lkKQp7CglpbnQgbGFzdG1vZGU7CglpbnQgaTsKCWludCBoYWRtb2RlcyA9IDA7CgoJbGFzdG1vZGUgPSBOT1JNQUw7Cglmb3IgKGk9MDsgaTxtYXhjb2w7IGkrKykgewoJCWlmIChvYnVmW2ldLmNfbW9kZSAhPSBsYXN0bW9kZSkgewoJCQloYWRtb2RlcysrOwoJCQlzZXRtb2RlKG9idWZbaV0uY19tb2RlKTsKCQkJbGFzdG1vZGUgPSBvYnVmW2ldLmNfbW9kZTsKCQl9CgkJaWYgKG9idWZbaV0uY19jaGFyID09ICdcMCcpIHsKCQkJaWYgKHVwbG4pIHsKCQkJCVBSSU5UKENVUlNfUklHSFQpOwoJCQl9IGVsc2UKCQkJCW91dGMoJyAnLCAxKTsKCQl9IGVsc2UKCQkJb3V0YyhvYnVmW2ldLmNfY2hhciwgb2J1ZltpXS5jX3dpZHRoKTsKCQlpZiAob2J1ZltpXS5jX3dpZHRoID4gMSkKCQkJaSArPSBvYnVmW2ldLmNfd2lkdGggLTE7Cgl9CglpZiAobGFzdG1vZGUgIT0gTk9STUFMKSB7CgkJc2V0bW9kZSgwKTsKCX0KCWlmIChtdXN0X292ZXJzdHJpa2UgJiYgaGFkbW9kZXMpCgkJb3ZlcnN0cmlrZSgpOwoJcHV0d2NoYXIoJ1xuJyk7CglpZiAoaWZsYWcgJiYgaGFkbW9kZXMpCgkJaWF0dHIoKTsKCSh2b2lkKWZmbHVzaChzdGRvdXQpOwoJaWYgKHVwbG4pCgkJdXBsbi0tOwoJaW5pdGJ1ZigpOwp9CgovKgogKiBGb3IgdGVybWluYWxzIHRoYXQgY2FuIG92ZXJzdHJpa2UsIG92ZXJzdHJpa2UgdW5kZXJsaW5lcyBhbmQgYm9sZHMuCiAqIFdlIGRvbid0IGRvIGFueXRoaW5nIHdpdGggaGFsZmxpbmUgdXBzIGFuZCBkb3ducywgb3IgR3JlZWsuCiAqLwp2b2lkIG92ZXJzdHJpa2Uodm9pZCkKewoJcmVnaXN0ZXIgaW50IGk7CiNpZmRlZiBfX0dOVUNfXwoJcmVnaXN0ZXIgd2NoYXJfdCAqbGJ1ZiA9IF9fYnVpbHRpbl9hbGxvY2EoKG1heGNvbCsxKSpzaXplb2Yod2NoYXJfdCkpOwojZWxzZQoJd2NoYXJfdCBsYnVmWzI1Nl07CiNlbmRpZgoJcmVnaXN0ZXIgd2NoYXJfdCAqY3AgPSBsYnVmOwoJaW50IGhhZGJvbGQ9MDsKCgkvKiBTZXQgdXAgb3ZlcnN0cmlrZSBidWZmZXIgKi8KCWZvciAoaT0wOyBpPG1heGNvbDsgaSsrKQoJCXN3aXRjaCAob2J1ZltpXS5jX21vZGUpIHsKCQljYXNlIE5PUk1BTDoKCQlkZWZhdWx0OgoJCQkqY3ArKyA9ICcgJzsKCQkJYnJlYWs7CgkJY2FzZSBVTkRFUkw6CgkJCSpjcCsrID0gJ18nOwoJCQlicmVhazsKCQljYXNlIEJPTEQ6CgkJCSpjcCsrID0gb2J1ZltpXS5jX2NoYXI7CgkJCWlmIChvYnVmW2ldLmNfd2lkdGggPiAxKQoJCQkJaSArPSBvYnVmW2ldLmNfd2lkdGggLSAxOwoJCQloYWRib2xkPTE7CgkJCWJyZWFrOwoJCX0KCXB1dHdjaGFyKCdccicpOwoJZm9yICgqY3A9JyAnOyAqY3A9PScgJzsgY3AtLSkKCQkqY3AgPSAwOwoJZm9yIChjcD1sYnVmOyAqY3A7IGNwKyspCgkJcHV0d2NoYXIoKmNwKTsKCWlmIChoYWRib2xkKSB7CgkJcHV0d2NoYXIoJ1xyJyk7CgkJZm9yIChjcD1sYnVmOyAqY3A7IGNwKyspCgkJCXB1dHdjaGFyKCpjcD09J18nID8gJyAnIDogKmNwKTsKCQlwdXR3Y2hhcignXHInKTsKCQlmb3IgKGNwPWxidWY7ICpjcDsgY3ArKykKCQkJcHV0d2NoYXIoKmNwPT0nXycgPyAnICcgOiAqY3ApOwoJfQp9Cgp2b2lkIGlhdHRyKHZvaWQpCnsKCXJlZ2lzdGVyIGludCBpOwojaWZkZWYgX19HTlVDX18KCXJlZ2lzdGVyIGNoYXIgKmxidWYgPSBfX2J1aWx0aW5fYWxsb2NhKChtYXhjb2wrMSkqc2l6ZW9mKGNoYXIpKTsKI2Vsc2UKCWNoYXIgbGJ1ZlsyNTZdOwojZW5kaWYKCXJlZ2lzdGVyIGNoYXIgKmNwID0gbGJ1ZjsKCglmb3IgKGk9MDsgaTxtYXhjb2w7IGkrKykKCQlzd2l0Y2ggKG9idWZbaV0uY19tb2RlKSB7CgkJY2FzZSBOT1JNQUw6CSpjcCsrID0gJyAnOyBicmVhazsKCQljYXNlIEFMVFNFVDoJKmNwKysgPSAnZyc7IGJyZWFrOwoJCWNhc2UgU1VQRVJTQzoJKmNwKysgPSAnXic7IGJyZWFrOwoJCWNhc2UgU1VCU0M6CSpjcCsrID0gJ3YnOyBicmVhazsKCQljYXNlIFVOREVSTDoJKmNwKysgPSAnXyc7IGJyZWFrOwoJCWNhc2UgQk9MRDoJKmNwKysgPSAnISc7IGJyZWFrOwoJCWRlZmF1bHQ6CSpjcCsrID0gJ1gnOyBicmVhazsKCQl9Cglmb3IgKCpjcD0nICc7ICpjcD09JyAnOyBjcC0tKQoJCSpjcCA9IDA7Cglmb3IgKGNwPWxidWY7ICpjcDsgY3ArKykKCQlwdXR3Y2hhcigqY3ApOwoJcHV0d2NoYXIoJ1xuJyk7Cn0KCnZvaWQgaW5pdGJ1Zih2b2lkKQp7CglpZiAob2J1ZiA9PSBOVUxMKSB7CS8qIEZpcnN0IHRpbWUuICovCgkJb2J1ZmxlbiA9IElOSVRCVUY7CgkJb2J1ZiA9IG1hbGxvYyhzaXplb2Yoc3RydWN0IENIQVIpICogb2J1Zmxlbik7CgkJaWYgKG9idWYgPT0gTlVMTCkgewoJCQlmcHJpbnRmKHN0ZGVyciwgXygiVW5hYmxlIHRvIGFsbG9jYXRlIGJ1ZmZlci5cbiIpKTsKCQkJZXhpdCgxKTsKCQl9Cgl9CgoJLyogYXNzdW1lcyBOT1JNQUwgPT0gMCAqLwoJbWVtc2V0KG9idWYsIDAsIHNpemVvZihzdHJ1Y3QgQ0hBUikgKiBvYnVmbGVuKTsKCXNldGNvbCgwKTsKCW1heGNvbCA9IDA7Cgltb2RlICY9IEFMVFNFVDsKfQoKdm9pZCBmd2Qodm9pZCkKewoJaW50IG9sZGNvbCwgb2xkbWF4OwoKCW9sZGNvbCA9IGNvbDsKCW9sZG1heCA9IG1heGNvbDsKCWZsdXNobG4oKTsKCXNldGNvbChvbGRjb2wpOwoJbWF4Y29sID0gb2xkbWF4Owp9Cgp2b2lkIHJldmVyc2Uodm9pZCkKewoJdXBsbisrOwoJZndkKCk7CglQUklOVChDVVJTX1VQKTsKCVBSSU5UKENVUlNfVVApOwoJdXBsbisrOwp9Cgp2b2lkIGluaXRpbmZvKHZvaWQpCnsKCUNVUlNfVVAgPQkJdGlnZXRzdHIoImN1dTEiKTsKCUNVUlNfUklHSFQgPQkJdGlnZXRzdHIoImN1ZjEiKTsKCUNVUlNfTEVGVCA9CQl0aWdldHN0cigiY3ViMSIpOwoJaWYgKENVUlNfTEVGVCA9PSBOVUxMKQoJCUNVUlNfTEVGVCA9CSJcYiI7CgoJRU5URVJfU1RBTkRPVVQgPQl0aWdldHN0cigic21zbyIpOwoJRVhJVF9TVEFORE9VVCA9CQl0aWdldHN0cigicm1zbyIpOwoJRU5URVJfVU5ERVJMSU5FID0JdGlnZXRzdHIoInNtdWwiKTsKCUVYSVRfVU5ERVJMSU5FID0JdGlnZXRzdHIoInJtdWwiKTsKCUVOVEVSX0RJTSA9CQl0aWdldHN0cigiZGltIik7CglFTlRFUl9CT0xEID0JCXRpZ2V0c3RyKCJib2xkIik7CglFTlRFUl9SRVZFUlNFID0JCXRpZ2V0c3RyKCJyZXYiKTsKCUVYSVRfQVRUUklCVVRFUyA9CXRpZ2V0c3RyKCJzZ3IwIik7CgoJaWYgKCFFTlRFUl9CT0xEICYmIEVOVEVSX1JFVkVSU0UpCgkJRU5URVJfQk9MRCA9IEVOVEVSX1JFVkVSU0U7CglpZiAoIUVOVEVSX0JPTEQgJiYgRU5URVJfU1RBTkRPVVQpCgkJRU5URVJfQk9MRCA9IEVOVEVSX1NUQU5ET1VUOwoJaWYgKCFFTlRFUl9VTkRFUkxJTkUgJiYgRU5URVJfU1RBTkRPVVQpIHsKCQlFTlRFUl9VTkRFUkxJTkUgPSBFTlRFUl9TVEFORE9VVDsKCQlFWElUX1VOREVSTElORSA9IEVYSVRfU1RBTkRPVVQ7Cgl9CglpZiAoIUVOVEVSX0RJTSAmJiBFTlRFUl9TVEFORE9VVCkKCQlFTlRFUl9ESU0gPSBFTlRFUl9TVEFORE9VVDsKCWlmICghRU5URVJfUkVWRVJTRSAmJiBFTlRFUl9TVEFORE9VVCkKCQlFTlRFUl9SRVZFUlNFID0gRU5URVJfU1RBTkRPVVQ7CglpZiAoIUVYSVRfQVRUUklCVVRFUyAmJiBFWElUX1NUQU5ET1VUKQoJCUVYSVRfQVRUUklCVVRFUyA9IEVYSVRfU1RBTkRPVVQ7CgkKCS8qCgkgKiBOb3RlIHRoYXQgd2UgdXNlIFJFVkVSU0UgZm9yIHRoZSBhbHRlcm5hdGUgY2hhcmFjdGVyIHNldCwKCSAqIG5vdCB0aGUgYXMvYWUgY2FwYWJpbGl0aWVzLiAgVGhpcyBpcyBiZWNhdXNlIHdlIGFyZSBtb2RlbGxpbmcKCSAqIHRoZSBtb2RlbCAzNyB0ZWxldHlwZSAoc2luY2UgdGhhdCdzIHdoYXQgbnJvZmYgb3V0cHV0cykgYW5kCgkgKiB0aGUgdHlwaWNhbCBhcy9hZSBpcyBtb3JlIG9mIGEgZ3JhcGhpY3Mgc2V0LCBub3QgdGhlIGdyZWVrCgkgKiBsZXR0ZXJzIHRoZSAzNyBoYXMuCgkgKi8KCglVTkRFUl9DSEFSID0JCXRpZ2V0c3RyKCJ1YyIpOwoJbXVzdF91c2VfdWMgPSAoVU5ERVJfQ0hBUiAmJiAhRU5URVJfVU5ERVJMSU5FKTsKfQoKc3RhdGljIGludCBjdXJtb2RlID0gMDsKCnZvaWQKb3V0Yyh3aW50X3QgYywgaW50IHdpZHRoKSB7CglpbnQgaTsKCglwdXR3Y2hhcihjKTsKCWlmIChtdXN0X3VzZV91YyAmJiAoY3VybW9kZSZVTkRFUkwpKSB7CgkJZm9yIChpPTA7IGk8d2lkdGg7IGkrKykKCQkJUFJJTlQoQ1VSU19MRUZUKTsKCQlmb3IgKGk9MDsgaTx3aWR0aDsgaSsrKQoJCQlQUklOVChVTkRFUl9DSEFSKTsKCX0KfQoKdm9pZCBzZXRtb2RlKGludCBuZXdtb2RlKQp7CglpZiAoIWlmbGFnKSB7CgkJaWYgKGN1cm1vZGUgIT0gTk9STUFMICYmIG5ld21vZGUgIT0gTk9STUFMKQoJCQlzZXRtb2RlKE5PUk1BTCk7CgkJc3dpdGNoIChuZXdtb2RlKSB7CgkJY2FzZSBOT1JNQUw6CgkJCXN3aXRjaChjdXJtb2RlKSB7CgkJCWNhc2UgTk9STUFMOgoJCQkJYnJlYWs7CgkJCWNhc2UgVU5ERVJMOgoJCQkJUFJJTlQoRVhJVF9VTkRFUkxJTkUpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQkvKiBUaGlzIGluY2x1ZGVzIHN0YW5kb3V0ICovCgkJCQlQUklOVChFWElUX0FUVFJJQlVURVMpOwoJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBBTFRTRVQ6CgkJCVBSSU5UKEVOVEVSX1JFVkVSU0UpOwoJCQlicmVhazsKCQljYXNlIFNVUEVSU0M6CgkJCS8qCgkJCSAqIFRoaXMgb25seSB3b3JrcyBvbiBhIGZldyB0ZXJtaW5hbHMuCgkJCSAqIEl0IHNob3VsZCBiZSBmaXhlZC4KCQkJICovCgkJCVBSSU5UKEVOVEVSX1VOREVSTElORSk7CgkJCVBSSU5UKEVOVEVSX0RJTSk7CgkJCWJyZWFrOwoJCWNhc2UgU1VCU0M6CgkJCVBSSU5UKEVOVEVSX0RJTSk7CgkJCWJyZWFrOwoJCWNhc2UgVU5ERVJMOgoJCQlQUklOVChFTlRFUl9VTkRFUkxJTkUpOwoJCQlicmVhazsKCQljYXNlIEJPTEQ6CgkJCVBSSU5UKEVOVEVSX0JPTEQpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQkvKgoJCQkgKiBXZSBzaG91bGQgaGF2ZSBzb21lIHByb3Zpc2lvbiBoZXJlIGZvciBtdWx0aXBsZSBtb2RlcwoJCQkgKiBvbiBhdCBvbmNlLiAgVGhpcyB3aWxsIGhhdmUgdG8gY29tZSBsYXRlci4KCQkJICovCgkJCVBSSU5UKEVOVEVSX1NUQU5ET1VUKTsKCQkJYnJlYWs7CgkJfQoJfQoJY3VybW9kZSA9IG5ld21vZGU7Cn0KCnN0YXRpYyB2b2lkCnNldGNvbChpbnQgbmV3Y29sKSB7Cgljb2wgPSBuZXdjb2w7CgoJaWYgKGNvbCA8IDApCgkJY29sID0gMDsKCWVsc2UgaWYgKGNvbCA+IG1heGNvbCkKCQluZWVkY29sKGNvbCk7Cn0KCnN0YXRpYyB2b2lkCm5lZWRjb2woaW50IGNvbCkgewoJbWF4Y29sID0gY29sOwoKCS8qIElmIGNvbCA+PSBvYnVmbGVuLCBleHBhbmQgb2J1ZiB1bnRpbCBvYnVmbGVuID4gY29sLiAqLwoJd2hpbGUgKGNvbCA+PSBvYnVmbGVuKSB7CgkJLyogUGFyYW5vaWQgY2hlY2sgZm9yIG9idWZsZW4gPT0gSU5UX01BWC4gKi8KCQlpZiAob2J1ZmxlbiA9PSBJTlRfTUFYKSB7CgkJCWZwcmludGYoc3RkZXJyLAoJCQkJXygiSW5wdXQgbGluZSB0b28gbG9uZy5cbiIpKTsKCQkJZXhpdCgxKTsKCQl9CgoJCS8qIFNpbWlsYXIgcGFyYW5vaWE6IGRvdWJsZSBvbmx5IHVwIHRvIElOVF9NQVguICovCgkJb2J1ZmxlbiA9ICgoSU5UX01BWCAvIDIpIDwgb2J1ZmxlbikKCQkJPyBJTlRfTUFYCgkJCTogb2J1ZmxlbiAqIDI7CgoJCS8qIE5vdyB3ZSBjYW4gdHJ5IHRvIGV4cGFuZCBvYnVmLiAqLwoJCW9idWYgPSByZWFsbG9jKG9idWYsIHNpemVvZihzdHJ1Y3QgQ0hBUikgKiBvYnVmbGVuKTsKCQlpZiAob2J1ZiA9PSBOVUxMKSB7CgkJCWZwcmludGYoc3RkZXJyLAoJCQkJXygiT3V0IG9mIG1lbW9yeSB3aGVuIGdyb3dpbmcgYnVmZmVyLlxuIikpOwoJCQlleGl0KDEpOwoJCX0KCX0KfQo=