LyoKICogTkRSIGNsaWVudCBzdHVmZgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogVE9ETzoKICogIC0gRXhjZXB0aW9uIGhhbmRsaW5nCiAqICAtIENvbnRleHQgc3R1ZmYKICogIC0gV2hvIGtub3dzCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJuZHJfbWlzYy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCkxPTkdfUFRSIC8qIENMSUVOVF9DQUxMX1JFVFVSTiAqLyBSUENSVDRfTmRyQ2xpZW50Q2FsbDIoUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzYywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgdmFfbGlzdCBhcmdzKQp7CgogIFJQQ19DTElFTlRfSU5URVJGQUNFICpycGNfY2xpX2lmID0gKFJQQ19DTElFTlRfSU5URVJGQUNFICopKHBTdHViRGVzYy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24pOwogIExPTkdfUFRSIHJldCA9IDA7Ci8qCiAgUlBDX0JJTkRJTkdfSEFORExFIGhhbmRsZSA9IDA7CiAgUlBDX01FU1NBR0UgcnBjbXNnOwogIE1JRExfU1RVQl9NRVNTQUdFIHN0dWJtc2c7CiovCgogIEZJWE1FKCIocFN0dWJEZWMgPT0gXiVwLHBGb3JtYXQgPSBeJXAsLi4uKTogc2VtaS1zdHViXG4iLCBwU3R1YkRlc2MsIHBGb3JtYXQpOwogIGlmIChycGNfY2xpX2lmKSAvKiBOVUxMIGZvciBvYmplY3RzICovIHsKICAgIFRSQUNFKCIgICpycGNfY2xpX2lmICg9PSBeJXApID09IChSUENfQ0xJRU5UX0lOVEVSRkFDRSk6XG4iLCBwU3R1YkRlc2MpOwogICAgVFJBQ0UoIiAgICBMZW5ndGggPT0gJWRcbiIsIHJwY19jbGlfaWYtPkxlbmd0aCk7CiAgICBUUkFDRSgiICAgIEludGVyZmFjZUlEID09ICVzICglZC4lZClcbiIsIGRlYnVnc3RyX2d1aWQoJnJwY19jbGlfaWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLCAKICAgICAgcnBjX2NsaV9pZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24sIHJwY19jbGlfaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICAgIFRSQUNFKCIgICAgVHJhbnNmZXJTeW50YXggPT0gJXMgKCVkLiVkKVxuIiwgZGVidWdzdHJfZ3VpZCgmcnBjX2NsaV9pZi0+VHJhbnNmZXJTeW50YXguU3ludGF4R1VJRCksCiAgICAgIHJwY19jbGlfaWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLCBycGNfY2xpX2lmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgICBUUkFDRSgiICAgIERpc3BhdGNoVGFibGUgPT0gXiVwXG4iLCBycGNfY2xpX2lmLT5EaXNwYXRjaFRhYmxlKTsKICAgIFRSQUNFKCIgICAgUnBjUHJvdHNlcUVuZHBvaW50Q291bnQgPT0gXiVkXG4iLCBycGNfY2xpX2lmLT5ScGNQcm90c2VxRW5kcG9pbnRDb3VudCk7CiAgICBUUkFDRSgiICAgIFJwY1Byb3RzZXFFbmRwb2ludCA9PSBeJXBcbiIsIHJwY19jbGlfaWYtPlJwY1Byb3RzZXFFbmRwb2ludCk7CiAgICBUUkFDRSgiICAgIEZsYWdzID09IF4lZFxuIiwgcnBjX2NsaV9pZi0+RmxhZ3MpOwogIH0KCiAgLyogZm9yIG5vdywgd2hpbGUgdGhlc2UgZnVuY3RvbnMgYXJlIHVuZGVyIGRldmVsb3BtZW50LCB0aGlzIGlzIHRvbyBza2V0Y2h5LiAgY29tbWVudGVkIG91dC4gKi8KICAvKgogIE5kckNsaWVudEluaXRpYWxpemVOZXcoICZycGNtc2csICZzdHVibXNnLCBwU3R1YkRlc2MsIDAgKTsKICAgICAgICAKICBoYW5kbGUgPSAoUlBDX0JJTkRJTkdfSEFORExFKTB4ZGVhZGJlZWY7ICovIC8qIEZJWE1FICovCgogIC8qIHN0dWJtc2cuQnVmZmVyTGVuZ3RoID0gMDsqLyAvKiBGSVhNRSAqLwogIC8qCiAgTmRyR2V0QnVmZmVyKCAmc3R1Ym1zZywgc3R1Ym1zZy5CdWZmZXJMZW5ndGgsIGhhbmRsZSApOwogIE5kclNlbmRSZWNlaXZlKCAmc3R1Ym1zZywgc3R1Ym1zZy5CdWZmZXIgICk7CiAgTmRyRnJlZUJ1ZmZlciggJnN0dWJtc2cgKTsKICAqLwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyQ2xpZW50Q2FsbDIgW1JQQ1JUNC5AXQogKi8KTE9OR19QVFIgLyogQ0xJRU5UX0NBTExfUkVUVVJOICovIFdJTkFQSVYgTmRyQ2xpZW50Q2FsbDIoUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzYywKICBQRk9STUFUX1NUUklORyBwRm9ybWF0LCAuLi4pCnsKICAgIExPTkdfUFRSIHJldDsKICAgIHZhX2xpc3QgYXJnczsKCiAgICBUUkFDRSgiKCVwLCVwLC4uLilcbiIsIHBTdHViRGVzYywgcEZvcm1hdCk7CgogICAgdmFfc3RhcnQoYXJncywgcEZvcm1hdCk7CiAgICByZXQgPSBSUENSVDRfTmRyQ2xpZW50Q2FsbDIocFN0dWJEZXNjLCBwRm9ybWF0LCBhcmdzKTsKICAgIHZhX2VuZChhcmdzKTsKICAgIHJldHVybiByZXQ7Cn0K