LyoKICoJT0xFMzIgcHJveHkvc3R1YiBoYW5kbGVyCiAqCiAqICBDb3B5cmlnaHQgMjAwMiAgTWFyY3VzIE1laXNzbmVyCiAqICBDb3B5cmlnaHQgMjAwMSAgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKLyogRG9jdW1lbnRhdGlvbiBvbiBNU0ROOgogKgogKiAoVG9wIGxldmVsIENPTSBkb2N1bWVudGF0aW9uKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RuYW5jaG9yL2h0bWwvY29tcG9uZW50ZGV2ZWxvcG1lbnRhbmsuYXNwCiAqCiAqIChDT00gUHJveHkpCiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvY29tL2h0bS9jb21leHRfMXEwcC5hc3AKICoKICogKENPTSBTdHViKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFsaWEuYXNwCiAqCiAqIChNYXJzaGFsKQogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG0vY29tZXh0XzFnZm4uYXNwCiAqCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3dHlwZXMuaCIKCiNpbmNsdWRlICJjb21wb2JqX3ByaXZhdGUuaCIKI2luY2x1ZGUgIm1vbmlrZXIuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIFVMT05HIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpOwoKLyogRnJvbTogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2VuLXVzL2NvbS9jbWlfbV80bGRhLmFzcAogKgogKiBUaGUgZmlyc3QgdGltZSBhIGNsaWVudCByZXF1ZXN0cyBhIHBvaW50ZXIgdG8gYW4gaW50ZXJmYWNlIG9uIGEKICogcGFydGljdWxhciBvYmplY3QsIENPTSBsb2FkcyBhbiBJQ2xhc3NGYWN0b3J5IHN0dWIgaW4gdGhlIHNlcnZlcgogKiBwcm9jZXNzIGFuZCB1c2VzIGl0IHRvIG1hcnNoYWwgdGhlIGZpcnN0IHBvaW50ZXIgYmFjayB0byB0aGUKICogY2xpZW50LiBJbiB0aGUgY2xpZW50IHByb2Nlc3MsIENPTSBsb2FkcyB0aGUgZ2VuZXJpYyBwcm94eSBmb3IgdGhlCiAqIGNsYXNzIGZhY3Rvcnkgb2JqZWN0IGFuZCBjYWxscyBpdHMgaW1wbGVtZW50YXRpb24gb2YgSU1hcnNoYWwgdG8KICogdW5tYXJzaGFsIHRoYXQgZmlyc3QgcG9pbnRlci4gQ09NIHRoZW4gY3JlYXRlcyB0aGUgZmlyc3QgaW50ZXJmYWNlCiAqIHByb3h5IGFuZCBoYW5kcyBpdCBhIHBvaW50ZXIgdG8gdGhlIFJQQyBjaGFubmVsLiBGaW5hbGx5LCBDT00gcmV0dXJucwogKiB0aGUgSUNsYXNzRmFjdG9yeSBwb2ludGVyIHRvIHRoZSBjbGllbnQsIHdoaWNoIHVzZXMgaXQgdG8gY2FsbAogKiBJQ2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZSwgcGFzc2luZyBpdCBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJmYWNlLgogKgogKiBCYWNrIGluIHRoZSBzZXJ2ZXIgcHJvY2VzcywgQ09NIG5vdyBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZQogKiBvYmplY3QsIGFsb25nIHdpdGggYSBzdHViIGZvciB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBzdHViIG1hcnNoYWxzCiAqIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrIHRvIHRoZSBjbGllbnQgcHJvY2Vzcywgd2hlcmUgYW5vdGhlciBvYmplY3QKICogcHJveHkgaXMgY3JlYXRlZCwgdGhpcyB0aW1lIGZvciB0aGUgb2JqZWN0IGl0c2VsZi4gQWxzbyBjcmVhdGVkIGlzIGEKICogcHJveHkgZm9yIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLCBhIHBvaW50ZXIgdG8gd2hpY2ggaXMgcmV0dXJuZWQgdG8KICogdGhlIGNsaWVudC4gV2l0aCBzdWJzZXF1ZW50IGNhbGxzIHRvIG90aGVyIGludGVyZmFjZXMgb24gdGhlIG9iamVjdCwKICogQ09NIHdpbGwgbG9hZCB0aGUgYXBwcm9wcmlhdGUgaW50ZXJmYWNlIHN0dWJzIGFuZCBwcm94aWVzIGFzIG5lZWRlZC4KICovCnR5cGVkZWYgc3RydWN0IF9DRlN0dWIgewogICAgY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsICAgKmxwdnRibDsKICAgIExPTkcJCQlyZWY7CgogICAgTFBVTktOT1dOCQkJcFVua1NlcnZlcjsKfSBDRlN0dWI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKQ0ZTdHViX1F1ZXJ5SW50ZXJmYWNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLHJpaWQpfHxJc0VxdWFsSUlEKCZJSURfSVJwY1N0dWJCdWZmZXIscmlpZCkpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJSVVua25vd25fQWRkUmVmKGlmYWNlKTsKCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcyksIGludGVyZmFjZSBub3Qgc3VwcG9ydGVkLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkNGU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsIElVbmtub3duICpwVW5rU2VydmVyKSB7CiAgICBDRlN0dWIgKlRoaXMgPSAoQ0ZTdHViICopaWZhY2U7CgogICAgVGhpcy0+cFVua1NlcnZlciA9IHBVbmtTZXJ2ZXI7CiAgICBJVW5rbm93bl9BZGRSZWYocFVua1NlcnZlcik7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJCkNGU3R1Yl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwoKICAgIGlmIChUaGlzLT5wVW5rU2VydmVyKSB7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShUaGlzLT5wVW5rU2VydmVyKTsKICAgICAgICBUaGlzLT5wVW5rU2VydmVyID0gTlVMTDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkNGU3R1Yl9JbnZva2UoCiAgICBMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsUlBDT0xFTUVTU0FHRSogbXNnLElScGNDaGFubmVsQnVmZmVyKiBjaGFuYnVmCikgewogICAgQ0ZTdHViICpUaGlzID0gKENGU3R1YiAqKWlmYWNlOwogICAgSFJFU1VMVCBocmVzOwoKICAgIGlmIChtc2ctPmlNZXRob2QgPT0gMykgeyAvKiBDcmVhdGVJbnN0YW5jZSAqLwoJSUlEIGlpZDsKCUlDbGFzc0ZhY3RvcnkJKmNsYXNzZmFjOwoJSVVua25vd24JKnBwdjsKCUlTdHJlYW0JCSpwU3RtOwoJU1RBVFNURwkJc3RzdGc7CglVTEFSR0VfSU5URUdFUgluZXdwb3M7CglMQVJHRV9JTlRFR0VSCXNlZWt0bzsKCVVMT05HCQlyZXM7CgoJaWYgKG1zZy0+Y2JCdWZmZXIgPCBzaXplb2YoSUlEKSkgewogICAgICAgICAgICBGSVhNRSgiTm90IGVub3VnaCBieXRlcyBpbiBidWZmZXIgKCVkKT9cbiIsbXNnLT5jYkJ1ZmZlcik7CgkgICAgcmV0dXJuIEVfRkFJTDsKCX0KCW1lbWNweSgmaWlkLG1zZy0+QnVmZmVyLHNpemVvZihpaWQpKTsKCVRSQUNFKCItPkNyZWF0ZUluc3RhbmNlKCVzKVxuIixkZWJ1Z3N0cl9ndWlkKCZpaWQpKTsKCWhyZXMgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5wVW5rU2VydmVyLCZJSURfSUNsYXNzRmFjdG9yeSwoTFBWT0lEKikmY2xhc3NmYWMpOwoJaWYgKGhyZXMpIHsKCSAgICBGSVhNRSgiT2xlIHNlcnZlciBkb2VzIG5vdCBwcm92aWRlIGFuIElDbGFzc0ZhY3Rvcnk/XG4iKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJQ2xhc3NGYWN0b3J5X0NyZWF0ZUluc3RhbmNlKGNsYXNzZmFjLE5VTEwsJmlpZCwoTFBWT0lEKikmcHB2KTsKCUlDbGFzc0ZhY3RvcnlfUmVsZWFzZShjbGFzc2ZhYyk7Cgltc2ctPmNiQnVmZmVyID0gMDsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgJXNcbiIsZGVidWdzdHJfZ3VpZCgmaWlkKSk7CgkgICAgZ290byBnZXRidWZmZXI7Cgl9CglocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CglpZiAoaHJlcykgewoJICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN0cmVhbSBvbiBoZ2xvYmFsXG4iKTsKCSAgICBnb3RvIGdldGJ1ZmZlcjsKCX0KCWhyZXMgPSBJU3RyZWFtX1dyaXRlKHBTdG0sICZwcHYsIHNpemVvZihwcHYpLCBOVUxMKTsKCWlmIChocmVzKSB7CgkgICBFUlIoIklTdHJlYW1fV3JpdGUgZmFpbGVkLCAweCUwOHhcbiIsIGhyZXMpOwoJICAgZ290byBnZXRidWZmZXI7Cgl9CglpZiAocHB2KSB7CiAgICAgICAgaHJlcyA9IENvTWFyc2hhbEludGVyZmFjZShwU3RtLCZpaWQscHB2LDAsTlVMTCwwKTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHBwdik7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICV4IVxuIixocmVzKTsKICAgICAgICAgICAgZ290byBnZXRidWZmZXI7CiAgICAgICAgfQogICAgfQoJaHJlcyA9IElTdHJlYW1fU3RhdChwU3RtLCZzdHN0ZywwKTsKCWlmIChocmVzKSB7CgkgICAgRklYTUUoIlN0YXQgZmFpbGVkLlxuIik7CgkgICAgZ290byBnZXRidWZmZXI7Cgl9CgoJbXNnLT5jYkJ1ZmZlciA9IHN0c3RnLmNiU2l6ZS51Lkxvd1BhcnQ7CgpnZXRidWZmZXI6CiAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKGNoYW5idWYsIG1zZywgJklJRF9JQ2xhc3NGYWN0b3J5KTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgoJc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwoJaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKCWlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJJU3RyZWFtX1NlZWsgZmFpbGVkLCAleFxuIixocmVzKTsKCSAgICByZXR1cm4gaHJlczsKCX0KCWhyZXMgPSBJU3RyZWFtX1JlYWQocFN0bSxtc2ctPkJ1ZmZlcixtc2ctPmNiQnVmZmVyLCZyZXMpOwoJaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIlN0cmVhbSBSZWFkIGZhaWxlZCwgJXhcbiIsaHJlcyk7CgkgICAgcmV0dXJuIGhyZXM7Cgl9CglJU3RyZWFtX1JlbGVhc2UocFN0bSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXAsJXApLCBzdHViIVxuIixtc2csY2hhbmJ1Zik7CiAgICBGSVhNRSgiaU1ldGhvZCBpcyAlZFxuIixtc2ctPmlNZXRob2QpOwogICAgRklYTUUoImNiQnVmZmVyIGlzICVkXG4iLG1zZy0+Y2JCdWZmZXIpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIExQUlBDU1RVQkJVRkZFUiBXSU5BUEkKQ0ZTdHViX0lzSUlEU3VwcG9ydGVkKExQUlBDU1RVQkJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCkgewogICAgRklYTUUoIiglcyksIHN0dWIhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKQ0ZTdHViX0NvdW50UmVmcyhMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpIHsKICAgIEZJWE1FKCIoKSwgc3R1YiFcbiIpOwogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlN0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2Usdm9pZCoqIHBwdikgewogICAgRklYTUUoIiglcCksIHN0dWIhXG4iLHBwdik7CiAgICByZXR1cm4gRV9GQUlMOwp9CnN0YXRpYyB2b2lkICAgIFdJTkFQSQpDRlN0dWJfRGVidWdTZXJ2ZXJSZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSx2b2lkICpwdikgewogICAgRklYTUUoIiglcCksIHN0dWIhXG4iLHB2KTsKfQoKc3RhdGljIGNvbnN0IElScGNTdHViQnVmZmVyVnRibCBjZnN0dWJ2dCA9IHsKICAgIENGU3R1Yl9RdWVyeUludGVyZmFjZSwKICAgIENGU3R1Yl9BZGRSZWYsCiAgICBDRlN0dWJfUmVsZWFzZSwKICAgIENGU3R1Yl9Db25uZWN0LAogICAgQ0ZTdHViX0Rpc2Nvbm5lY3QsCiAgICBDRlN0dWJfSW52b2tlLAogICAgQ0ZTdHViX0lzSUlEU3VwcG9ydGVkLAogICAgQ0ZTdHViX0NvdW50UmVmcywKICAgIENGU3R1Yl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogICAgQ0ZTdHViX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKc3RhdGljIEhSRVNVTFQKQ0ZTdHViX0NvbnN0cnVjdChMUFJQQ1NUVUJCVUZGRVIgKnBwdikgewogICAgQ0ZTdHViICpjZnN0dWI7CiAgICBjZnN0dWIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihDRlN0dWIpKTsKICAgIGlmICghY2ZzdHViKQoJcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAqcHB2ID0gKExQUlBDU1RVQkJVRkZFUiljZnN0dWI7CiAgICBjZnN0dWItPmxwdnRibAk9ICZjZnN0dWJ2dDsKICAgIGNmc3R1Yi0+cmVmCQk9IDE7CiAgICByZXR1cm4gU19PSzsKfQoKLyogU2luY2Ugd2UgY3JlYXRlIHByb3h5IGJ1ZmZlcnMgYW5kIGNsYXNzZmFjdG9yeSBpbiBhIHBhaXIsIHRoZXJlIGlzCiAqIG5vIG5lZWQgZm9yIDIgc2VwYXJhdGUgc3RydWN0cy4gSnVzdCBwdXQgdGhlbSBpbiBvbmUsIGJ1dCByZW1lbWJlcgogKiB0aGUgcmVmY291bnQuCiAqLwp0eXBlZGVmIHN0cnVjdCBfQ0ZQcm94eSB7CiAgICBjb25zdCBJQ2xhc3NGYWN0b3J5VnRibAkJKmxwdnRibF9jZjsKICAgIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwJKmxwdnRibF9wcm94eTsKICAgIExPTkcJCQkJcmVmOwoKICAgIElScGNDaGFubmVsQnVmZmVyCQkJKmNoYW5idWY7CiAgICBJVW5rbm93biAqb3V0ZXJfdW5rbm93bjsKfSBDRlByb3h5OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikgewogICAgKnBwdiA9IE5VTEw7CiAgICBpZiAoSXNFcXVhbElJRChyaWlkLCZJSURfSVJwY1Byb3h5QnVmZmVyKXx8SXNFcXVhbElJRChyaWlkLCZJSURfSVVua25vd24pKSB7CglJUnBjUHJveHlCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJcmV0dXJuIFNfT0s7CiAgICB9CiAgICBGSVhNRSgiKCVzKSwgbm8gaW50ZXJmYWNlLlxuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9wcm94eSxpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAoIXJlZikgewogICAgICAgIElScGNQcm94eUJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVJwY1Byb3h5QnVmZmVySW1wbF9Db25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsSVJwY0NoYW5uZWxCdWZmZXIqIHBScGNDaGFubmVsQnVmZmVyKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoQ0ZQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwoKICAgIFRoaXMtPmNoYW5idWYgPSBwUnBjQ2hhbm5lbEJ1ZmZlcjsKICAgIElScGNDaGFubmVsQnVmZmVyX0FkZFJlZihUaGlzLT5jaGFuYnVmKTsKICAgIHJldHVybiBTX09LOwp9CnN0YXRpYyB2b2lkIFdJTkFQSSBJUnBjUHJveHlCdWZmZXJJbXBsX0Rpc2Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIGlmIChUaGlzLT5jaGFuYnVmKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW5idWYpOwoJVGhpcy0+Y2hhbmJ1ZiA9IE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpDRlByb3h5X1F1ZXJ5SW50ZXJmYWNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlLFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKSByZXR1cm4gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoVGhpcy0+b3V0ZXJfdW5rbm93biwgcmlpZCwgcHB2KTsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQoJklJRF9JQ2xhc3NGYWN0b3J5LHJpaWQpIHx8IElzRXF1YWxJSUQoJklJRF9JVW5rbm93bixyaWlkKSkgewoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JTWFyc2hhbCkpIC8qIGp1c3QgdG8gYXZvaWQgZGVidWcgb3V0cHV0ICovCglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIEZJWE1FKCJVbmhhbmRsZWQgaW50ZXJmYWNlOiAlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQ0ZQcm94eV9BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7CiAgICBpZiAoVGhpcy0+b3V0ZXJfdW5rbm93bikgcmV0dXJuIElVbmtub3duX0FkZFJlZihUaGlzLT5vdXRlcl91bmtub3duKTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIENGUHJveHlfUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPm91dGVyX3Vua25vd24pOwogICAgZWxzZQogICAgICAgIHJldHVybiBJUnBjUHJveHlCdWZmZXJJbXBsX1JlbGVhc2UoKElScGNQcm94eUJ1ZmZlciAqKSZUaGlzLT5scHZ0YmxfcHJveHkpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ0ZQcm94eV9DcmVhdGVJbnN0YW5jZSgKICAgIExQQ0xBU1NGQUNUT1JZIGlmYWNlLAogICAgTFBVTktOT1dOIHBVbmtPdXRlciwvKiBbaW5dICovCiAgICBSRUZJSUQgcmlpZCwJLyogW2luXSAqLwogICAgTFBWT0lEICpwcHYJCS8qIFtvdXRdICovCikgewogICAgSUNPTV9USElTX01VTFRJKENGUHJveHksbHB2dGJsX2NmLGlmYWNlKTsKICAgIEhSRVNVTFQJCWhyZXM7CiAgICBMUFNUUkVBTQkJcFN0cmVhbTsKICAgIEhHTE9CQUwJCWhHbG9iYWw7CiAgICBVTE9ORwkJc3JzdGF0dXM7CiAgICBSUENPTEVNRVNTQUdFCW1zZzsKCiAgICBUUkFDRSgiKCVwLCVzLCVwKVxuIixwVW5rT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHYpOwoKICAgIC8qIFNlbmQgQ3JlYXRlSW5zdGFuY2UgdG8gdGhlIHJlbW90ZSBjbGFzc2ZhY3RvcnkuCiAgICAgKgogICAgICogRGF0YTogT25seSB0aGUgJ0lJRCcuCiAgICAgKi8KICAgIG1zZy5pTWV0aG9kICA9IDM7CiAgICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoKnJpaWQpOwogICAgbXNnLkJ1ZmZlcgkgPSBOVUxMOwogICAgaHJlcyA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2csJklJRF9JQ2xhc3NGYWN0b3J5KTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyIGZhaWxlZCB3aXRoICV4P1xuIixocmVzKTsKCXJldHVybiBocmVzOwogICAgfQogICAgbWVtY3B5KG1zZy5CdWZmZXIscmlpZCxzaXplb2YoKnJpaWQpKTsKICAgIGhyZXMgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuYnVmLCZtc2csJnNyc3RhdHVzKTsKICAgIGlmIChocmVzKSB7CglGSVhNRSgiSVJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUgZmFpbGVkIHdpdGggJXg/XG4iLGhyZXMpOwoJSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2cpOwoJcmV0dXJuIGhyZXM7CiAgICB9CgogICAgaWYgKCFtc2cuY2JCdWZmZXIpIHsgLyogaW50ZXJmYWNlIG5vdCBmb3VuZCBvbiByZW1vdGUgKi8KCUlScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbmJ1ZiwmbXNnKTsKCXJldHVybiBzcnN0YXR1czsKICAgIH0KCiAgICAvKiBXZSBnb3QgYmFjazogW01hcnNoYWxsZWQgSW50ZXJmYWNlIGRhdGFdICovCiAgICBUUkFDRSgiZ290ICVkIGJ5dGVzIGRhdGEuXG4iLG1zZy5jYkJ1ZmZlcik7CiAgICBoR2xvYmFsID0gR2xvYmFsQWxsb2MoR01FTV9NT1ZFQUJMRXxHTUVNX05PRElTQ0FSRHxHTUVNX1NIQVJFLG1zZy5jYkJ1ZmZlcik7CiAgICBtZW1jcHkoR2xvYmFsTG9jayhoR2xvYmFsKSxtc2cuQnVmZmVyLG1zZy5jYkJ1ZmZlcik7CiAgICBocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKGhHbG9iYWwsVFJVRSwmcFN0cmVhbSk7CiAgICBpZiAoaHJlcyAhPSBTX09LKSB7CglGSVhNRSgiQ3JlYXRlU3RyZWFtT25IR2xvYmFsIGZhaWxlZCB3aXRoICV4XG4iLGhyZXMpOwoJSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihUaGlzLT5jaGFuYnVmLCZtc2cpOwogICAgICAgIEdsb2JhbEZyZWUoaEdsb2JhbCk7CglyZXR1cm4gaHJlczsKICAgIH0KICAgIGhyZXMgPSBJU3RyZWFtX1JlYWQocFN0cmVhbSwgcHB2LCBzaXplb2YoKnBwdiksIE5VTEwpOwogICAgaWYgKGhyZXMgIT0gU19PSykKICAgICAgICBocmVzID0gRV9GQUlMOwogICAgZWxzZSBpZiAoKnBwdikgewogICAgICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZSgKCSAgICAgICBwU3RyZWFtLAoJICAgICAgIHJpaWQsCgkgICAgICAgcHB2CiAgICAgICAgKTsKICAgIH0KICAgIElTdHJlYW1fUmVsZWFzZShwU3RyZWFtKTsgLyogRG9lcyBHbG9iYWxGcmVlIGhHbG9iYWwgdG9vLiAqLwoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbmJ1ZiwmbXNnKTsKCiAgICBpZiAoaHJlcykgewoJRklYTUUoIkNvTWFyc2hhbEludGVyZmFjZSBmYWlsZWQsICV4XG4iLGhyZXMpOwoJcmV0dXJuIGhyZXM7CiAgICB9CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENGUHJveHlfTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGZMb2NrKSB7CiAgICAvKklDT01fVEhJU19NVUxUSShDRlByb3h5LGxwdnRibF9jZixpZmFjZSk7Ki8KICAgIEZJWE1FKCIoJWQpLCBzdHViIVxuIixmTG9jayk7CiAgICAvKiBiYXNpY2FsbHk6IHdyaXRlIEJPT0wsIHJlYWQgZW1wdHkgKi8KICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibCBwc3BidnRibCA9IHsKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJUnBjUHJveHlCdWZmZXJJbXBsX0FkZFJlZiwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfQ29ubmVjdCwKICAgIElScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdAp9OwpzdGF0aWMgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgY2Zwcm94eXZ0ID0gewogICAgQ0ZQcm94eV9RdWVyeUludGVyZmFjZSwKICAgIENGUHJveHlfQWRkUmVmLAogICAgQ0ZQcm94eV9SZWxlYXNlLAogICAgQ0ZQcm94eV9DcmVhdGVJbnN0YW5jZSwKICAgIENGUHJveHlfTG9ja1NlcnZlcgp9OwoKc3RhdGljIEhSRVNVTFQKQ0ZQcm94eV9Db25zdHJ1Y3QoSVVua25vd24gKnBVbmtPdXRlciwgTFBWT0lEICpwcHYsTFBWT0lEICpwcFByb3h5KSB7CiAgICBDRlByb3h5ICpjZjsKCiAgICBjZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENGUHJveHkpKTsKICAgIGlmICghY2YpCglyZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBjZi0+bHB2dGJsX2NmCT0gJmNmcHJveHl2dDsKICAgIGNmLT5scHZ0YmxfcHJveHkJPSAmcHNwYnZ0Ymw7CiAgICAvKiBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgYnVmZmVyICovCiAgICBjZi0+cmVmCQk9IDE7CiAgICBjZi0+b3V0ZXJfdW5rbm93biA9IHBVbmtPdXRlcjsKICAgICpwcHYJCT0gJihjZi0+bHB2dGJsX2NmKTsKICAgICpwcFByb3h5CQk9ICYoY2YtPmxwdnRibF9wcm94eSk7CiAgICAvKiBhbmQgb25lIHJlZmVyZW5jZSBmb3IgdGhlIG9iamVjdCAqLwogICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biAqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqIElSZW1Vbmtub3duIFByb3h5L1N0dWIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJUnBjU3R1YkJ1ZmZlclZ0YmwgKmxwVnRibDsKICAgIExPTkcgcmVmczsKICAgIElSZW1Vbmtub3duICppZmFjZTsKfSBSZW1VbmtTdHViOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCSAgICAgUkVGSUlEIHJpaWQsCgkJCQkJICAgICBMUFZPSUQgKm9iaikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24scmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JUnBjU3R1YkJ1ZmZlcixyaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICByZXR1cm4gU19PSzsKICB9CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLFRoaXMpOwogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUmVtVW5rU3R1Yl9SZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFVMT05HIHJlZnM7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKICByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZnMpOwogIGlmICghcmVmcykKICB7CiAgICBJUnBjU3R1YkJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogIH0KICByZXR1cm4gcmVmczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJlbVVua1N0dWJfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkgICAgICBMUFVOS05PV04gbHBVbmtTZXJ2ZXIpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+Q29ubmVjdCglcClcbiIsVGhpcyxscFVua1NlcnZlcik7CiAgVGhpcy0+aWZhY2UgPSAoSVJlbVVua25vd24qKWxwVW5rU2VydmVyOwogIElSZW1Vbmtub3duX0FkZFJlZihUaGlzLT5pZmFjZSk7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBSZW1VbmtTdHViX0Rpc2Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkRpc2Nvbm5lY3QoKVxuIixUaGlzKTsKICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPmlmYWNlKTsKICBUaGlzLT5pZmFjZSA9IE5VTEw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtTdHViX0ludm9rZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCgkJCQkgICAgIFBSUENPTEVNRVNTQUdFIHBNc2csCgkJCQkgICAgIExQUlBDQ0hBTk5FTEJVRkZFUiBwQ2hhbm5lbCkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIFVMT05HIGlNZXRob2QgPSBwTXNnLT5pTWV0aG9kOwogIExQQllURSBidWYgPSBwTXNnLT5CdWZmZXI7CiAgSFJFU1VMVCBociA9IFJQQ19FX0lOVkFMSURNRVRIT0Q7CgogIFRSQUNFKCIoJXApLT5JbnZva2UoJXAsJXApIG1ldGhvZCAlZFxuIiwgVGhpcywgcE1zZywgcENoYW5uZWwsIGlNZXRob2QpOwogIHN3aXRjaCAoaU1ldGhvZCkKICB7CiAgY2FzZSAzOiAvKiBSZW1RdWVyeUludGVyZmFjZSAqLwogIHsKICAgIElQSUQgaXBpZDsKICAgIFVMT05HIGNSZWZzOwogICAgVVNIT1JUIGNJaWRzOwogICAgSUlEICppaWRzOwogICAgUkVNUUlSRVNVTFQgKnBRSVJlc3VsdHMgPSBOVUxMOwoKICAgIC8qIGluICovCiAgICBtZW1jcHkoJmlwaWQsIGJ1Ziwgc2l6ZW9mKGlwaWQpKTsKICAgIGJ1ZiArPSBzaXplb2YoaXBpZCk7CiAgICBtZW1jcHkoJmNSZWZzLCBidWYsIHNpemVvZihjUmVmcykpOwogICAgYnVmICs9IHNpemVvZihjUmVmcyk7CiAgICBtZW1jcHkoJmNJaWRzLCBidWYsIHNpemVvZihjSWlkcykpOwogICAgYnVmICs9IHNpemVvZihjSWlkcyk7CiAgICBpaWRzID0gKElJRCAqKWJ1ZjsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbVF1ZXJ5SW50ZXJmYWNlKFRoaXMtPmlmYWNlLCAmaXBpZCwgY1JlZnMsIGNJaWRzLCBpaWRzLCAmcFFJUmVzdWx0cyk7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IGNJaWRzICogc2l6ZW9mKFJFTVFJUkVTVUxUKSArIHNpemVvZihIUkVTVUxUKTsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocENoYW5uZWwsIHBNc2csICZJSURfSVJlbVVua25vd24pOwoKICAgIGJ1ZiA9IHBNc2ctPkJ1ZmZlcjsKICAgICooSFJFU1VMVCAqKWJ1ZiA9IGhyOwogICAgYnVmICs9IHNpemVvZihIUkVTVUxUKTsKICAgIAogICAgaWYgKGhyKSByZXR1cm4gaHI7CiAgICAvKiBGSVhNRTogcFFJUmVzdWx0cyBpcyBhIHVuaXF1ZSBwb2ludGVyIHNvIHBRSVJlc3VsdHMgY2FuIGJlIE5VTEwhICovCiAgICBtZW1jcHkoYnVmLCBwUUlSZXN1bHRzLCBjSWlkcyAqIHNpemVvZihSRU1RSVJFU1VMVCkpOwoKICAgIGJyZWFrOwogIH0KICBjYXNlIDQ6IC8qIFJlbUFkZFJlZiAqLwogIHsKICAgIFVTSE9SVCBjSWlkczsKICAgIFJFTUlOVEVSRkFDRVJFRiAqaXI7CiAgICBIUkVTVUxUICpwUmVzdWx0czsKCiAgICAvKiBpbiAqLwogICAgbWVtY3B5KCZjSWlkcywgYnVmLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBpciA9IChSRU1JTlRFUkZBQ0VSRUYqKWJ1ZjsKICAgIHBSZXN1bHRzID0gQ29UYXNrTWVtQWxsb2MoY0lpZHMgKiBzaXplb2YoSFJFU1VMVCkpOwogICAgaWYgKCFwUmVzdWx0cykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgaHIgPSBJUmVtVW5rbm93bl9SZW1BZGRSZWYoVGhpcy0+aWZhY2UsIGNJaWRzLCBpciwgcFJlc3VsdHMpOwoKICAgIC8qIG91dCAqLwogICAgcE1zZy0+Y2JCdWZmZXIgPSBjSWlkcyAqIHNpemVvZihIUkVTVUxUKTsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocENoYW5uZWwsIHBNc2csICZJSURfSVJlbVVua25vd24pOwogICAgaWYgKCFocikKICAgIHsKICAgICAgICBidWYgPSBwTXNnLT5CdWZmZXI7CiAgICAgICAgbWVtY3B5KGJ1ZiwgcFJlc3VsdHMsIGNJaWRzICogc2l6ZW9mKEhSRVNVTFQpKTsKICAgIH0KCiAgICBDb1Rhc2tNZW1GcmVlKHBSZXN1bHRzKTsKCiAgICBicmVhazsKICB9CiAgY2FzZSA1OiAvKiBSZW1SZWxlYXNlICovCiAgewogICAgVVNIT1JUIGNJaWRzOwogICAgUkVNSU5URVJGQUNFUkVGICppcjsKCiAgICAvKiBpbiAqLwogICAgbWVtY3B5KCZjSWlkcywgYnVmLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBpciA9IChSRU1JTlRFUkZBQ0VSRUYqKWJ1ZjsKCiAgICBociA9IElSZW1Vbmtub3duX1JlbVJlbGVhc2UoVGhpcy0+aWZhY2UsIGNJaWRzLCBpcik7CgogICAgLyogb3V0ICovCiAgICBwTXNnLT5jYkJ1ZmZlciA9IDA7CiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocENoYW5uZWwsIHBNc2csICZJSURfSVJlbVVua25vd24pOwogICAgYnJlYWs7CiAgfQogIH0KICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBMUFJQQ1NUVUJCVUZGRVIgV0lOQVBJIFJlbVVua1N0dWJfSXNJSURTdXBwb3J0ZWQoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCQkgICAgIFJFRklJRCByaWlkKQp7CiAgUmVtVW5rU3R1YiAqVGhpcyA9IChSZW1VbmtTdHViICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPklzSUlEU3VwcG9ydGVkKCVzKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgcmV0dXJuIElzRXF1YWxHVUlEKCZJSURfSVJlbVVua25vd24sIHJpaWQpID8gaWZhY2UgOiBOVUxMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJlbVVua1N0dWJfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5Db3VudFJlZnMoKVxuIiwgVGhpcyk7CiAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtTdHViX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCQkJTFBWT0lEICpwcHYpCnsKICBSZW1VbmtTdHViICpUaGlzID0gKFJlbVVua1N0dWIgKilpZmFjZTsKICBGSVhNRSgiKCVwKS0+RGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSglcClcbiIsVGhpcyxwcHYpOwogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgUmVtVW5rU3R1Yl9EZWJ1Z1NlcnZlclJlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAoJCQkJCSAgICAgIExQVk9JRCBwdikKewogIFJlbVVua1N0dWIgKlRoaXMgPSAoUmVtVW5rU3R1YiAqKWlmYWNlOwogIEZJWE1FKCIoJXApLT5EZWJ1Z1NlcnZlclJlbGVhc2UoJXApXG4iLCBUaGlzLCBwdik7Cn0KCnN0YXRpYyBjb25zdCBJUnBjU3R1YkJ1ZmZlclZ0YmwgUmVtVW5rU3R1Yl9WVGFibGUgPQp7CiAgUmVtVW5rU3R1Yl9RdWVyeUludGVyZmFjZSwKICBSZW1VbmtTdHViX0FkZFJlZiwKICBSZW1VbmtTdHViX1JlbGVhc2UsCiAgUmVtVW5rU3R1Yl9Db25uZWN0LAogIFJlbVVua1N0dWJfRGlzY29ubmVjdCwKICBSZW1VbmtTdHViX0ludm9rZSwKICBSZW1VbmtTdHViX0lzSUlEU3VwcG9ydGVkLAogIFJlbVVua1N0dWJfQ291bnRSZWZzLAogIFJlbVVua1N0dWJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICBSZW1VbmtTdHViX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKc3RhdGljIEhSRVNVTFQgUmVtVW5rU3R1Yl9Db25zdHJ1Y3QoSVJwY1N0dWJCdWZmZXIgKipwcFN0dWIpCnsKICAgIFJlbVVua1N0dWIgKlRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpUaGlzKSk7CiAgICBpZiAoIVRoaXMpIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgVGhpcy0+bHBWdGJsID0gJlJlbVVua1N0dWJfVlRhYmxlOwogICAgVGhpcy0+cmVmcyA9IDE7CiAgICBUaGlzLT5pZmFjZSA9IE5VTEw7CiAgICAqcHBTdHViID0gKElScGNTdHViQnVmZmVyKilUaGlzOwogICAgcmV0dXJuIFNfT0s7Cn0KCgp0eXBlZGVmIHN0cnVjdCBfUmVtVW5rUHJveHkgewogICAgY29uc3QgSVJlbVVua25vd25WdGJsCQkqbHB2dGJsX3JlbXVuazsKICAgIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwJKmxwdnRibF9wcm94eTsKICAgIExPTkcJCQkJcmVmczsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcgkJCSpjaGFuOwogICAgSVVua25vd24gKm91dGVyX3Vua25vd247Cn0gUmVtVW5rUHJveHk7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUXVlcnlJbnRlcmZhY2UoTFBSRU1VTktOT1dOIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCAqKnBwdikKewogICAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICAgIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5vdXRlcl91bmtub3duLCByaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikgfHwKICAgICAgICBJc0VxdWFsSUlEKHJpaWQsICZJSURfSVJlbVVua25vd24pKQogICAgewogICAgICAgIElSZW1Vbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwdiA9IChMUFZPSUQpaWZhY2U7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtQcm94eV9BZGRSZWYoTFBSRU1VTktOT1dOIGlmYWNlKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBVTE9ORyByZWZzOwoKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CgogIGlmIChUaGlzLT5vdXRlcl91bmtub3duKQogICAgICByZWZzID0gSVVua25vd25fQWRkUmVmKFRoaXMtPm91dGVyX3Vua25vd24pOwogIGVsc2UKICAgICAgcmVmcyA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKICByZXR1cm4gcmVmczsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBSZW1VbmtQcm94eV9SZWxlYXNlKExQUkVNVU5LTk9XTiBpZmFjZSkKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CgogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CiAgaWYgKFRoaXMtPm91dGVyX3Vua25vd24pCiAgICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPm91dGVyX3Vua25vd24pOwogIGVsc2UKICAgICAgcmV0dXJuIElScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSgoSVJwY1Byb3h5QnVmZmVyICopJlRoaXMtPmxwdnRibF9wcm94eSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1RdWVyeUludGVyZmFjZShMUFJFTVVOS05PV04gaWZhY2UsCgkJCQkJCSBSRUZJUElEIHJpcGlkLAoJCQkJCQkgVUxPTkcgY1JlZnMsCgkJCQkJCSBVU0hPUlQgY0lpZHMsCgkJCQkJCSBJSUQqIGlpZHMsCgkJCQkJCSBSRU1RSVJFU1VMVCoqIHBwUUlSZXN1bHRzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJXMsJWQsJWQsJXAsJXApXG4iLFRoaXMsCglkZWJ1Z3N0cl9ndWlkKHJpcGlkKSxjUmVmcyxjSWlkcyxpaWRzLHBwUUlSZXN1bHRzKTsKCiAgKnBwUUlSZXN1bHRzID0gTlVMTDsKICBtZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwogIG1zZy5pTWV0aG9kID0gMzsKICBtc2cuY2JCdWZmZXIgPSBzaXplb2YoSVBJRCkgKyBzaXplb2YoVUxPTkcpICsKICAgIHNpemVvZihVU0hPUlQpICsgY0lpZHMqc2l6ZW9mKElJRCk7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIExQQllURSBidWYgPSBtc2cuQnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgcmlwaWQsIHNpemVvZihJUElEKSk7CiAgICBidWYgKz0gc2l6ZW9mKElQSUQpOwogICAgbWVtY3B5KGJ1ZiwgJmNSZWZzLCBzaXplb2YoVUxPTkcpKTsKICAgIGJ1ZiArPSBzaXplb2YoVUxPTkcpOwogICAgbWVtY3B5KGJ1ZiwgJmNJaWRzLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBtZW1jcHkoYnVmLCBpaWRzLCBjSWlkcypzaXplb2YoSUlEKSk7CgogICAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuLCAmbXNnLCAmc3RhdHVzKTsKCiAgICBidWYgPSBtc2cuQnVmZmVyOwoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgICAgaHIgPSAqKEhSRVNVTFQgKilidWY7CiAgICAgICAgYnVmICs9IHNpemVvZihIUkVTVUxUKTsKICAgIH0KCiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICAqcHBRSVJlc3VsdHMgPSBDb1Rhc2tNZW1BbGxvYyhjSWlkcypzaXplb2YoUkVNUUlSRVNVTFQpKTsKICAgICAgbWVtY3B5KCpwcFFJUmVzdWx0cywgYnVmLCBjSWlkcypzaXplb2YoUkVNUUlSRVNVTFQpKTsKICAgIH0KCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW4sICZtc2cpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUmVtVW5rUHJveHlfUmVtQWRkUmVmKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkgVVNIT1JUIGNJbnRlcmZhY2VSZWZzLAoJCQkJCSBSRU1JTlRFUkZBQ0VSRUYqIEludGVyZmFjZVJlZnMsCgkJCQkJIEhSRVNVTFQqIHBSZXN1bHRzKQp7CiAgUmVtVW5rUHJveHkgKlRoaXMgPSAoUmVtVW5rUHJveHkgKilpZmFjZTsKICBSUENPTEVNRVNTQUdFIG1zZzsKICBIUkVTVUxUIGhyID0gU19PSzsKICBVTE9ORyBzdGF0dXM7CgogIFRSQUNFKCIoJXApLT4oJWQsJXAsJXApXG4iLFRoaXMsCgljSW50ZXJmYWNlUmVmcyxJbnRlcmZhY2VSZWZzLHBSZXN1bHRzKTsKCiAgbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKICBtc2cuaU1ldGhvZCA9IDQ7CiAgbXNnLmNiQnVmZmVyID0gc2l6ZW9mKFVTSE9SVCkgKyBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKTsKICBociA9IElScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihUaGlzLT5jaGFuLCAmbXNnLCAmSUlEX0lSZW1Vbmtub3duKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgTFBCWVRFIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICBtZW1jcHkoYnVmLCAmY0ludGVyZmFjZVJlZnMsIHNpemVvZihVU0hPUlQpKTsKICAgIGJ1ZiArPSBzaXplb2YoVVNIT1JUKTsKICAgIG1lbWNweShidWYsIEludGVyZmFjZVJlZnMsIGNJbnRlcmZhY2VSZWZzKnNpemVvZihSRU1JTlRFUkZBQ0VSRUYpKTsKCiAgICBociA9IElScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKFRoaXMtPmNoYW4sICZtc2csICZzdGF0dXMpOwoKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgIGJ1ZiA9IG1zZy5CdWZmZXI7CiAgICAgIG1lbWNweShwUmVzdWx0cywgYnVmLCBjSW50ZXJmYWNlUmVmcypzaXplb2YoSFJFU1VMVCkpOwogICAgfQoKICAgIElScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZyk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSZW1VbmtQcm94eV9SZW1SZWxlYXNlKExQUkVNVU5LTk9XTiBpZmFjZSwKCQkJCQkgIFVTSE9SVCBjSW50ZXJmYWNlUmVmcywKCQkJCQkgIFJFTUlOVEVSRkFDRVJFRiogSW50ZXJmYWNlUmVmcykKewogIFJlbVVua1Byb3h5ICpUaGlzID0gKFJlbVVua1Byb3h5ICopaWZhY2U7CiAgUlBDT0xFTUVTU0FHRSBtc2c7CiAgSFJFU1VMVCBociA9IFNfT0s7CiAgVUxPTkcgc3RhdHVzOwoKICBUUkFDRSgiKCVwKS0+KCVkLCVwKVxuIixUaGlzLAoJY0ludGVyZmFjZVJlZnMsSW50ZXJmYWNlUmVmcyk7CgogIG1lbXNldCgmbXNnLCAwLCBzaXplb2YobXNnKSk7CiAgbXNnLmlNZXRob2QgPSA1OwogIG1zZy5jYkJ1ZmZlciA9IHNpemVvZihVU0hPUlQpICsgY0ludGVyZmFjZVJlZnMqc2l6ZW9mKFJFTUlOVEVSRkFDRVJFRik7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoVGhpcy0+Y2hhbiwgJm1zZywgJklJRF9JUmVtVW5rbm93bik7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIExQQllURSBidWYgPSBtc2cuQnVmZmVyOwogICAgbWVtY3B5KGJ1ZiwgJmNJbnRlcmZhY2VSZWZzLCBzaXplb2YoVVNIT1JUKSk7CiAgICBidWYgKz0gc2l6ZW9mKFVTSE9SVCk7CiAgICBtZW1jcHkoYnVmLCBJbnRlcmZhY2VSZWZzLCBjSW50ZXJmYWNlUmVmcypzaXplb2YoUkVNSU5URVJGQUNFUkVGKSk7CgogICAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShUaGlzLT5jaGFuLCAmbXNnLCAmc3RhdHVzKTsKCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKFRoaXMtPmNoYW4sICZtc2cpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgY29uc3QgSVJlbVVua25vd25WdGJsIFJlbVVua1Byb3h5X1ZUYWJsZSA9CnsKICBSZW1VbmtQcm94eV9RdWVyeUludGVyZmFjZSwKICBSZW1VbmtQcm94eV9BZGRSZWYsCiAgUmVtVW5rUHJveHlfUmVsZWFzZSwKICBSZW1VbmtQcm94eV9SZW1RdWVyeUludGVyZmFjZSwKICBSZW1VbmtQcm94eV9SZW1BZGRSZWYsCiAgUmVtVW5rUHJveHlfUmVtUmVsZWFzZQp9OwoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBSVVJwY1Byb3h5QnVmZmVySW1wbF9RdWVyeUludGVyZmFjZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KSB7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JUnBjUHJveHlCdWZmZXIpfHxJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpIHsKCUlScGNQcm94eUJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJKnBwdiA9IChMUFZPSUQpaWZhY2U7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIEZJWE1FKCIoJXMpLCBubyBpbnRlcmZhY2UuXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwogICAgVFJBQ0UoIiVwLCAlZFxuIiwgaWZhY2UsIFRoaXMtPnJlZnMgKyAxKTsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmcyk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoUmVtVW5rUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWZzKTsKICAgIFRSQUNFKCIlcCwgJWRcbiIsIGlmYWNlLCByZWYpOwogICAgaWYgKCFyZWYpIHsKICAgICAgICBJUnBjUHJveHlCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSxJUnBjQ2hhbm5lbEJ1ZmZlciogcFJwY0NoYW5uZWxCdWZmZXIpIHsKICAgIElDT01fVEhJU19NVUxUSShSZW1VbmtQcm94eSxscHZ0YmxfcHJveHksaWZhY2UpOwoKICAgIFRSQUNFKCIlcCwgJXBcbiIsIGlmYWNlLCBwUnBjQ2hhbm5lbEJ1ZmZlcik7CiAgICBUaGlzLT5jaGFuID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYoVGhpcy0+Y2hhbik7CiAgICByZXR1cm4gU19PSzsKfQpzdGF0aWMgdm9pZCBXSU5BUEkgUlVScGNQcm94eUJ1ZmZlckltcGxfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKSB7CiAgICBJQ09NX1RISVNfTVVMVEkoUmVtVW5rUHJveHksbHB2dGJsX3Byb3h5LGlmYWNlKTsKICAgIFRSQUNFKCIlcCwgJXBcbiIsIGlmYWNlLCBUaGlzLT5jaGFuKTsKICAgIGlmIChUaGlzLT5jaGFuKSB7CglJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmNoYW4pOwoJVGhpcy0+Y2hhbiA9IE5VTEw7CiAgICB9Cn0KCgpzdGF0aWMgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibCBSVVJwY1Byb3h5QnVmZmVyX1ZUYWJsZSA9IHsKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfQWRkUmVmLAogICAgUlVScGNQcm94eUJ1ZmZlckltcGxfUmVsZWFzZSwKICAgIFJVUnBjUHJveHlCdWZmZXJJbXBsX0Nvbm5lY3QsCiAgICBSVVJwY1Byb3h5QnVmZmVySW1wbF9EaXNjb25uZWN0Cn07CgpzdGF0aWMgSFJFU1VMVApSZW1VbmtQcm94eV9Db25zdHJ1Y3QoSVVua25vd24gKnBVbmtPdXRlciwgTFBWT0lEICpwcHYsTFBWT0lEICpwcFByb3h5KSB7CiAgICBSZW1VbmtQcm94eSAqVGhpczsKCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIFRoaXMtPmxwdnRibF9yZW11bmsJPSAmUmVtVW5rUHJveHlfVlRhYmxlOwogICAgVGhpcy0+bHB2dGJsX3Byb3h5CT0gJlJVUnBjUHJveHlCdWZmZXJfVlRhYmxlOwogICAgLyogb25seSBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgYnVmZmVyICovCiAgICBUaGlzLT5yZWZzCQk9IDE7CiAgICBUaGlzLT5vdXRlcl91bmtub3duID0gcFVua091dGVyOwogICAgKnBwdgkJPSAmKFRoaXMtPmxwdnRibF9yZW11bmspOwogICAgKnBwUHJveHkJCT0gJihUaGlzLT5scHZ0YmxfcHJveHkpOwogICAgLyogYW5kIG9uZSByZWZlcmVuY2UgZm9yIHRoZSBvYmplY3QgKi8KICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24gKikqcHB2KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKiBPTEUgUHJveHkvU3R1YiBGYWN0b3J5ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfUXVlcnlJbnRlcmZhY2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KSB7CiAgICBpZiAoSXNFcXVhbElJRChpaWQsJklJRF9JUFNGYWN0b3J5QnVmZmVyKXx8SXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpIHsKCSpwcHYgPSAoTFBWT0lEKWlmYWNlOwoJLyogTm8gcmVmIGNvdW50aW5nLCBzdGF0aWMgY2xhc3MgKi8KCXJldHVybiBTX09LOwogICAgfQogICAgRklYTUUoIiglcykgdW5rbm93biBJSUQ/XG4iLGRlYnVnc3RyX2d1aWQoaWlkKSk7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9BZGRSZWYoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpIHsgcmV0dXJuIDI7IH0Kc3RhdGljIFVMT05HIFdJTkFQSSBQU0ZhY0J1Zl9SZWxlYXNlKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKSB7IHJldHVybiAxOyB9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlUHJveHkoCiAgICBMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwgSVVua25vd24qIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICBJUnBjUHJveHlCdWZmZXIgKipwcFByb3h5LCBMUFZPSUQgKnBwdgopIHsKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSxyaWlkKSkKCXJldHVybiBDRlByb3h5X0NvbnN0cnVjdChwVW5rT3V0ZXIsIHBwdiwoTFBWT0lEKilwcFByb3h5KTsKICAgIGVsc2UgaWYgKElzRXF1YWxJSUQoJklJRF9JUmVtVW5rbm93bixyaWlkKSkKCXJldHVybiBSZW1VbmtQcm94eV9Db25zdHJ1Y3QocFVua091dGVyLCBwcHYsKExQVk9JRCopcHBQcm94eSk7CiAgICBGSVhNRSgicHJveHlpbmcgbm90IGltcGxlbWVudGVkIGZvciAoJXMpIHlldCFcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKUFNGYWNCdWZfQ3JlYXRlU3R1YigKICAgIExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCxJVW5rbm93biAqcFVua1NlcnZlciwKICAgIElScGNTdHViQnVmZmVyKiogcHBTdHViCikgewogICAgSFJFU1VMVCBocmVzOwoKICAgIFRSQUNFKCIoJXMsJXAsJXApXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkscFVua1NlcnZlcixwcFN0dWIpOwoKICAgIGlmIChJc0VxdWFsSUlEKCZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCkgfHwKICAgICAgICBJc0VxdWFsSUlEKCZJSURfSVVua25vd24sIHJpaWQpIC8qIEZJWE1FOiBmaXh1cCBzdHViIG1hbmFnZXIgYW5kIHJlbW92ZSB0aGlzKi8pIHsKCWhyZXMgPSBDRlN0dWJfQ29uc3RydWN0KHBwU3R1Yik7CglpZiAoIWhyZXMpCgkgICAgSVJwY1N0dWJCdWZmZXJfQ29ubmVjdCgoKnBwU3R1YikscFVua1NlcnZlcik7CglyZXR1cm4gaHJlczsKICAgIH0gZWxzZSBpZiAoSXNFcXVhbElJRCgmSUlEX0lSZW1Vbmtub3duLHJpaWQpKSB7CglocmVzID0gUmVtVW5rU3R1Yl9Db25zdHJ1Y3QocHBTdHViKTsKCWlmICghaHJlcykKCSAgICBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KCgqcHBTdHViKSxwVW5rU2VydmVyKTsKCXJldHVybiBocmVzOwogICAgfQogICAgRklYTUUoInN0dWJiaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgKCVzKSB5ZXQhXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIGNvbnN0IElQU0ZhY3RvcnlCdWZmZXJWdGJsIHBzZmFjYnVmdnRibCA9IHsKICAgIFBTRmFjQnVmX1F1ZXJ5SW50ZXJmYWNlLAogICAgUFNGYWNCdWZfQWRkUmVmLAogICAgUFNGYWNCdWZfUmVsZWFzZSwKICAgIFBTRmFjQnVmX0NyZWF0ZVByb3h5LAogICAgUFNGYWNCdWZfQ3JlYXRlU3R1Ygp9OwoKLyogVGhpcyBpcyB0aGUgd2hvbGUgUFNGYWN0b3J5QnVmZmVyIG9iamVjdCwganVzdCB0aGUgdnRhYmxlcHRyICovCnN0YXRpYyBjb25zdCBJUFNGYWN0b3J5QnVmZmVyVnRibCAqbHBwc2ZhYyA9ICZwc2ZhY2J1ZnZ0Ymw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERsbEdldENsYXNzT2JqZWN0IFtPTEUzMi5AXQogKi8KSFJFU1VMVCBXSU5BUEkgRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgaWlkLExQVk9JRCAqcHB2KQp7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJjbHNpZCwgJkNMU0lEX1BTRmFjdG9yeUJ1ZmZlcikpCiAgICAgICAgcmV0dXJuIElQU0ZhY3RvcnlCdWZmZXJfUXVlcnlJbnRlcmZhY2UoKElQU0ZhY3RvcnlCdWZmZXIgKikmbHBwc2ZhYywgaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9EZk1hcnNoYWwpJiYoCgkJSXNFcXVhbElJRChpaWQsJklJRF9JQ2xhc3NGYWN0b3J5KSB8fAoJCUlzRXF1YWxJSUQoaWlkLCZJSURfSVVua25vd24pCgkpCiAgICApCglyZXR1cm4gTUFSU0hBTF9HZXRTdGFuZGFyZE1hcnNoYWxDRihwcHYpOwogICAgaWYgKElzRXF1YWxJSUQocmNsc2lkLCZDTFNJRF9TdGRHbG9iYWxJbnRlcmZhY2VUYWJsZSkgJiYgKElzRXF1YWxJSUQoaWlkLCZJSURfSUNsYXNzRmFjdG9yeSkgfHwgSXNFcXVhbElJRChpaWQsJklJRF9JVW5rbm93bikpKQogICAgICAgIHJldHVybiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZV9HZXRGYWN0b3J5KHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0ZpbGVNb25pa2VyKSkKICAgICAgICByZXR1cm4gRmlsZU1vbmlrZXJDRl9DcmVhdGUoaWlkLCBwcHYpOwogICAgaWYgKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9JdGVtTW9uaWtlcikpCiAgICAgICAgcmV0dXJuIEl0ZW1Nb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQW50aU1vbmlrZXIpKQogICAgICAgIHJldHVybiBBbnRpTW9uaWtlckNGX0NyZWF0ZShpaWQsIHBwdik7CiAgICBpZiAoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX0NvbXBvc2l0ZU1vbmlrZXIpKQogICAgICAgIHJldHVybiBDb21wb3NpdGVNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKICAgIGlmIChJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfQ2xhc3NNb25pa2VyKSkKICAgICAgICByZXR1cm4gQ2xhc3NNb25pa2VyQ0ZfQ3JlYXRlKGlpZCwgcHB2KTsKCiAgICBGSVhNRSgiXG5cdENMU0lEOlx0JXMsXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSxkZWJ1Z3N0cl9ndWlkKGlpZCkpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0K