LyoKICogTkRSIGNsaWVudCBzdHVmZgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogVE9ETzoKICogIC0gRXhjZXB0aW9uIGhhbmRsaW5nCiAqICAtIENvbnRleHQgc3R1ZmYKICogIC0gV2hvIGtub3dzCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgIm5kcl9taXNjLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKTE9OR19QVFIgLyogQ0xJRU5UX0NBTExfUkVUVVJOICovIFJQQ1JUNF9OZHJDbGllbnRDYWxsMihQTUlETF9TVFVCX0RFU0MgcFN0dWJEZXNjLCBQRk9STUFUX1NUUklORyBwRm9ybWF0LCB2YV9saXN0IGFyZ3MpCnsKCiAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UgKnJwY19jbGlfaWYgPSAoUlBDX0NMSUVOVF9JTlRFUkZBQ0UgKikocFN0dWJEZXNjLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbik7CiAgTE9OR19QVFIgcmV0ID0gMDsKLyoKICBSUENfQklORElOR19IQU5ETEUgaGFuZGxlID0gMDsKICBSUENfTUVTU0FHRSBycGNtc2c7CiAgTUlETF9TVFVCX01FU1NBR0Ugc3R1Ym1zZzsKKi8KCiAgRklYTUUoIihwU3R1YkRlYyA9PSBeJXAscEZvcm1hdCA9IF4lcCwuLi4pOiBzdHViXG4iLCBwU3R1YkRlc2MsIHBGb3JtYXQpOwogIGlmIChycGNfY2xpX2lmKSAvKiBOVUxMIGZvciBvYmplY3RzICovIHsKICAgIFRSQUNFKCIgICpycGNfY2xpX2lmICg9PSBeJXApID09IChSUENfQ0xJRU5UX0lOVEVSRkFDRSk6XG4iLCBwU3R1YkRlc2MpOwogICAgVFJBQ0UoIiAgICBMZW5ndGggPT0gJWRcbiIsIHJwY19jbGlfaWYtPkxlbmd0aCk7CiAgICBUUkFDRSgiICAgIEludGVyZmFjZUlEID09ICVzICglZC4lZClcbiIsIGRlYnVnc3RyX2d1aWQoJnJwY19jbGlfaWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLCAKICAgICAgcnBjX2NsaV9pZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24sIHJwY19jbGlfaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICAgIFRSQUNFKCIgICAgVHJhbnNmZXJTeW50YXggPT0gJXMgKCVkLiVkKVxuIiwgZGVidWdzdHJfZ3VpZCgmcnBjX2NsaV9pZi0+VHJhbnNmZXJTeW50YXguU3ludGF4R1VJRCksCiAgICAgIHJwY19jbGlfaWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLCBycGNfY2xpX2lmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgICBUUkFDRSgiICAgIERpc3BhdGNoVGFibGUgPT0gXiVwXG4iLCBycGNfY2xpX2lmLT5EaXNwYXRjaFRhYmxlKTsKICAgIFRSQUNFKCIgICAgUnBjUHJvdHNlcUVuZHBvaW50Q291bnQgPT0gXiVkXG4iLCBycGNfY2xpX2lmLT5ScGNQcm90c2VxRW5kcG9pbnRDb3VudCk7CiAgICBUUkFDRSgiICAgIFJwY1Byb3RzZXFFbmRwb2ludCA9PSBeJXBcbiIsIHJwY19jbGlfaWYtPlJwY1Byb3RzZXFFbmRwb2ludCk7CiAgICBUUkFDRSgiICAgIEZsYWdzID09IF4lZFxuIiwgcnBjX2NsaV9pZi0+RmxhZ3MpOwogIH0KCiAgLyogZm9yIG5vdywgd2hpbGUgdGhlc2UgZnVuY3RvbnMgYXJlIHVuZGVyIGRldmVsb3BtZW50LCB0aGlzIGlzIHRvbyBza2V0Y2h5LiAgY29tbWVudGVkIG91dC4gKi8KICAvKgogIE5kckNsaWVudEluaXRpYWxpemVOZXcoICZycGNtc2csICZzdHVibXNnLCBwU3R1YkRlc2MsIDAgKTsKICAgICAgICAKICBoYW5kbGUgPSAoUlBDX0JJTkRJTkdfSEFORExFKTB4ZGVhZGJlZWY7ICovIC8qIEZJWE1FICovCgogIC8qIHN0dWJtc2cuQnVmZmVyTGVuZ3RoID0gMDsqLyAvKiBGSVhNRSAqLwogIC8qCiAgTmRyR2V0QnVmZmVyKCAmc3R1Ym1zZywgc3R1Ym1zZy5CdWZmZXJMZW5ndGgsIGhhbmRsZSApOwogIE5kclNlbmRSZWNlaXZlKCAmc3R1Ym1zZywgc3R1Ym1zZy5CdWZmZXIgICk7CiAgTmRyRnJlZUJ1ZmZlciggJnN0dWJtc2cgKTsKICAqLwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyQ2xpZW50Q2FsbDIgW1JQQ1JUNC5AXQogKi8KTE9OR19QVFIgLyogQ0xJRU5UX0NBTExfUkVUVVJOICovIFdJTkFQSVYgTmRyQ2xpZW50Q2FsbDIoUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzYywKICBQRk9STUFUX1NUUklORyBwRm9ybWF0LCAuLi4pCnsKICAgIExPTkdfUFRSIHJldDsKICAgIHZhX2xpc3QgYXJnczsKCiAgICBUUkFDRSgiKCVwLCVwLC4uLilcbiIsIHBTdHViRGVzYywgcEZvcm1hdCk7CgogICAgdmFfc3RhcnQoYXJncywgcEZvcm1hdCk7CiAgICByZXQgPSBSUENSVDRfTmRyQ2xpZW50Q2FsbDIocFN0dWJEZXNjLCBwRm9ybWF0LCBhcmdzKTsKICAgIHZhX2VuZChhcmdzKTsKICAgIHJldHVybiByZXQ7Cn0K