LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfU1lTX1NUQVRfSAojIGluY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgQk9PTCBET1NWTV9pc2Rvc2V4ZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgIERPU1ZNX0lzV2luMTYKICogCiAqIFJldHVybiBUUlVFIGlmIHdlIGFyZSBpbiBXaW5kb3dzIHByb2Nlc3MuCiAqLwpCT09MIERPU1ZNX0lzV2luMTYodm9pZCkKewogIHJldHVybiBET1NWTV9pc2Rvc2V4ZSA/IEZBTFNFIDogVFJVRTsKfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmU7CiAgRFdPUkQgZmNiMTsKICBEV09SRCBmY2IyOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnBpZF90IGRvc3ZtX3BpZDsKCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBIQU5ETEUgZG9zdm1fdGhyZWFkLCBsb29wX3RocmVhZDsKc3RhdGljIERXT1JEIGRvc3ZtX3RpZCwgbG9vcF90aWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICAgIFBEQjE2ICpwc3AgPSBscFBTUDsKCiAgICBpZihsZW5ndGggPiAxMjcpIAogICAgewogICAgICAgIFdBUk4oICJDb21tYW5kIHRhaWwgdHJ1bmNhdGVkISAobGVuZ3RoICVkKVxuIiwgbGVuZ3RoICk7CiAgICAgICAgbGVuZ3RoID0gMTI2OwogICAgfQoKICAgIHBzcC0+Y21kTGluZVswXSA9IGxlbmd0aDsKCiAgICAvKgogICAgICogTGVuZ3RoIG9mIGV4YWN0bHkgMTI3IGJ5dGVzIG1lYW5zIHRoYXQgZnVsbCBjb21tYW5kIGxpbmUgaXMgCiAgICAgKiBzdG9yZWQgaW4gZW52aXJvbm1lbnQgdmFyaWFibGUgQ01ETElORSBhbmQgUFNQIGNvbnRhaW5zIAogICAgICogY29tbWFuZCB0YWlsIHRydW5jYXRlZCB0byAxMjYgYnl0ZXMuCiAgICAgKi8KICAgIGlmKGxlbmd0aCA9PSAxMjcpCiAgICAgICAgbGVuZ3RoID0gMTI2OwoKICAgIGlmKGxlbmd0aCA+IDApCiAgICAgICAgbWVtbW92ZShwc3AtPmNtZExpbmUrMSwgY21kdGFpbCwgbGVuZ3RoKTsKCiAgICBwc3AtPmNtZExpbmVbbGVuZ3RoKzFdID0gJ1xyJzsKCiAgICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiB1bnNpZ25lZCBpPTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fQWxsb2NCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdXBwZXJjYXNlICovCiB3aGlsZSAoZW52YmxrW2ldKXsKICB3aGlsZSAoZW52YmxrW2ldICE9ICc9Jyl7CiAgIGlmIChlbnZibGtbaV0+PSdhJyAmJiBlbnZibGtbaV0gPD0gJ3onKXsKICAgIGVudmJsa1tpXSAtPSAzMjsKICAgfQogICBpKys7CiAgfQogIGkgKz0gc3RybGVuKGVudmJsaytpKSArIDE7CiB9CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9NYXBEb3NMYXlvdXQoKTsKICAgIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcygpOwogICAgTVNDREVYX0luc3RhbGxDRFJPTSgpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsaywgV09SRCBwYXJfZW52X3NlZyApCnsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogIExQU1RSIG9sZGVudiA9IDA7CiAgaW50IHgsIG9sZF9jb209MCwgYWxsb2M7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZywgbG9hZF9zZWcsIHJlbF9zZWcsIG9sZHBzcF9zZWc7CiAgRFdPUkQgbGVuOwoKICBpZiAoRE9TVk1fcHNwKSB7CiAgICAvKiBET1MgcHJvY2VzcyBhbHJlYWR5IHJ1bm5pbmcsIGluaGVyaXQgZnJvbSBpdCAqLwogICAgUERCMTYqIHBhcl9wc3A7CiAgICBhbGxvYz0wOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICAgIGlmKCAhcGFyX2Vudl9zZWcpIHsgIAogICAgICAgIHBhcl9wc3AgPSAoUERCMTYqKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICAgIG9sZGVudiA9IChMUFNUUikoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBuZXcgRE9TIHByb2Nlc3MsIGluaGVyaXRpbmcgZnJvbSBXaW5lIGVudmlyb25tZW50ICovCiAgICBhbGxvYz0xOwogICAgb2xkcHNwX3NlZyA9IDA7CiAgICBpZiggIXBhcl9lbnZfc2VnKQogICAgICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgY2hhciAqcCA9IHN0cnJjaHIoIGZpbGVuYW1lLCAnLicgKTsKICBpZiAoIXAgfHwgc3RyY2FzZWNtcCggcCwgIi5jb20iICkpICAvKiBjaGVjayBmb3IgLkNPTSBleHRlbnNpb24gKi8KICB7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogIH0KICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIC8qIEZyb20gUmFsZiBCcm93biBJbnRlcnJ1cHQgTGlzdDogSWYgdGhlIHdvcmQgYXQgb2Zmc2V0IDAyaCBpcyA0LCBpdCBzaG91bGQKICAgKiBiZSB0cmVhdGVkIGFzIDAwaCwgc2luY2UgcHJlLTEuMTAgdmVyc2lvbnMgb2YgdGhlIE1TIGxpbmtlciBzZXQgaXQgdGhhdAogICAqIHdheS4gKi8KICBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogIG1pbl9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9taW5hbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKICBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiB9CgogIGlmIChhbGxvYykgTVpfSW5pdE1lbW9yeSgpOwoKICBpZiAob2JsaykgewogICAgLyogbG9hZCBvdmVybGF5IGludG8gcHJlYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgbG9hZF9zZWc9b2Jsay0+bG9hZF9zZWc7CiAgICByZWxfc2VnPW9ibGstPnJlbF9zZWc7CiAgICBsb2FkX3N0YXJ0PShMUEJZVEUpKChEV09SRClsb2FkX3NlZzw8NCk7CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiAgICBpZiggcGFyX2Vudl9zZWcpCiAgICAgICAgZW52X3NlZyA9IHBhcl9lbnZfc2VnOwogICAgZWxzZQogICAgICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwogICAgaWYgKGFsbG9jKQogICAgICAgIEZyZWVFbnZpcm9ubWVudFN0cmluZ3NBKCBvbGRlbnYpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lZCwgbWF4PSVkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiAgICBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKCk7CiAgICBpZiAoYXZhaWw8bWluX3NpemUpIHsKICAgICAgRVJSKCJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiAgICBwc3Bfc3RhcnQ9RE9TTUVNX0FsbG9jQmxvY2soYXZhaWwsJkRPU1ZNX3BzcCk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPURPU1ZNX3BzcCsob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDh4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIC8qIGNoZWNrIGlmIHRoaXMgaXMgZHVlIHRvIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgcHJlLTEuMTAgTVMgbGlua2VyIGFuZCB3ZQogICAgIHJlYWxseSBoYWQgb25seSA0IGJ5dGVzIG9uIHRoZSBsYXN0IHBhZ2UgKi8KICBpZiAobXpfaGVhZGVyLmVfY2JscCAhPSA0IHx8IGltYWdlX3NpemUgLSBsZW4gIT0gNTEyIC0gNCkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogIH0KIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIFNldEZpbGVQb2ludGVyKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxOVUxMLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoIVJlYWRGaWxlKGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpLCZsZW4sTlVMTCkgfHwgbGVuICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1yZWxfc2VnOwogIH0KIH0KCiAgaWYgKCFvYmxrKSB7CiAgICBpbml0X2NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiAgICBpbml0X2lwID0gbXpfaGVhZGVyLmVfaXA7CiAgICBpbml0X3NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiAgICBpbml0X3NwID0gbXpfaGVhZGVyLmVfc3A7CiAgICBpZiAob2xkX2NvbSl7CiAgICAgIC8qIC5DT00gZmlsZXMgZXhpdCB3aXRoIHJldC4gTWFrZSBzdXJlIHRoZXkganVtcCB0byBwc3Agc3RhcnQgKD1pbnQgMjApICovCiAgICAgIFdPUkQqIHN0YWNrID0gUFRSX1JFQUxfVE9fTElOKGluaXRfc3MsIGluaXRfc3ApOwogICAgICAqc3RhY2sgPSAwOwogICAgfQoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgRE9TVk1fcHNwID0gb2xkcHNwX3NlZzsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXdpbmVfbG9hZF9kb3NfZXhlIChXSU5FRE9TLkApCiAqCiAqIENhbGxlZCBmcm9tIFdpbmVWRE0gd2hlbiBhIG5ldyByZWFsLW1vZGUgRE9TIHByb2Nlc3MgaXMgc3RhcnRlZC4KICogTG9hZHMgRE9TIHByb2dyYW0gaW50byBtZW1vcnkgYW5kIGV4ZWN1dGVzIHRoZSBwcm9ncmFtLgogKi8Kdm9pZCBXSU5BUEkgd2luZV9sb2FkX2Rvc19leGUoIExQQ1NUUiBmaWxlbmFtZSwgTFBDU1RSIGNtZGxpbmUgKQp7CiAgICBjaGFyIGRvc19jbWR0YWlsWzEyNl07CiAgICBpbnQgIGRvc19sZW5ndGggPSAwOwoKICAgIEhBTkRMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgIGlmIChoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuOwogICAgRE9TVk1faXNkb3NleGUgPSBUUlVFOwoKICAgIGlmKGNtZGxpbmUgJiYgKmNtZGxpbmUpCiAgICB7CiAgICAgICAgZG9zX2xlbmd0aCA9IHN0cmxlbihjbWRsaW5lKTsKICAgICAgICBtZW1tb3ZlKCBkb3NfY21kdGFpbCArIDEsIGNtZGxpbmUsIAogICAgICAgICAgICAgICAgIChkb3NfbGVuZ3RoIDwgMTI1KSA/IGRvc19sZW5ndGggOiAxMjUgKTsKCiAgICAgICAgLyogTm9uLWVtcHR5IGNvbW1hbmQgdGFpbCBhbHdheXMgc3RhcnRzIHdpdGggYXQgbGVhc3Qgb25lIHNwYWNlLiAqLwogICAgICAgIGRvc19jbWR0YWlsWzBdID0gJyAnOwogICAgICAgIGRvc19sZW5ndGgrKzsKCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBjb21tYW5kIHRhaWwgaXMgbG9uZ2VyIHRoYW4gMTI2IGNoYXJhY3RlcnMsCiAgICAgICAgICogc2V0IHRhaWwgbGVuZ3RoIHRvIDEyNyBhbmQgZmlsbCBDTURMSU5FIGVudmlyb25tZW50IHZhcmlhYmxlIAogICAgICAgICAqIHdpdGggZnVsbCBjb21tYW5kIGxpbmUgKHRoaXMgaW5jbHVkZXMgZmlsZW5hbWUpLgogICAgICAgICAqLwogICAgICAgIGlmIChkb3NfbGVuZ3RoID4gMTI2KQogICAgICAgIHsKICAgICAgICAgICAgY2hhciAqY21kID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3NfbGVuZ3RoICsgc3RybGVuKGZpbGVuYW1lKSArIDQgKTsKICAgICAgICAgICAgY2hhciAqcHRyID0gY21kOwoKICAgICAgICAgICAgaWYgKCFjbWQpCiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBBcHBlbmQgZmlsZW5hbWUuIElmIHBhdGggaW5jbHVkZXMgc3BhY2VzLCBxdW90ZSB0aGUgcGF0aC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzdHJjaHIoZmlsZW5hbWUsICcgJykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpwdHIrKyA9ICdcIic7CiAgICAgICAgICAgICAgICBzdHJjcHkoIHB0ciwgZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgIHB0ciArPSBzdHJsZW4oZmlsZW5hbWUpOyAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICpwdHIrKyA9ICdcIic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHkoIHB0ciwgZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgIHB0ciArPSBzdHJsZW4oZmlsZW5hbWUpOyAgCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBjb21tYW5kIHRhaWwuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY21kbGluZVswXSAhPSAnICcpCiAgICAgICAgICAgICAgICAqcHRyKysgPSAnICc7CiAgICAgICAgICAgIHN0cmNweSggcHRyLCBjbWRsaW5lICk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTZXQgZW52aXJvbm1lbnQgdmFyaWFibGUuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8KICAgICAgICAgICAgICogbmV3IERPUyBwcm9jZXNzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFTZXRFbnZpcm9ubWVudFZhcmlhYmxlQSggIkNNRExJTkUiLCBjbWQgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNtZCApOwogICAgICAgICAgICBkb3NfbGVuZ3RoID0gMTI3OwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCwgMCApKSAKICAgICAgICBNWl9MYXVuY2goIGRvc19jbWR0YWlsLCBkb3NfbGVuZ3RoICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKgogKiB0aGlzIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIGV4aXN0aW5nIERPUyBwcm9jZXNzZXMKICovCkJPT0wgV0lOQVBJIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICBEV09SRCBiaW5UeXBlOwogIFNUQVJUVVBJTkZPQSBzdDsKICBQUk9DRVNTX0lORk9STUFUSU9OIHBlOwogIEhBTkRMRSBoRmlsZTsKCiAgQk9PTCByZXQgPSBGQUxTRTsKCiAgaWYoIUdldEJpbmFyeVR5cGVBKGZpbGVuYW1lLCAmYmluVHlwZSkpICAgLyogZGV0ZXJtaW5lIHdoYXQga2luZCBvZiBiaW5hcnkgdGhpcyBpcyAqLwogIHsKICAgIHJldHVybiBGQUxTRTsgLyogYmluYXJ5IGlzIG5vdCBhbiBleGVjdXRhYmxlICovCiAgfQoKICAvKiBoYW5kbGUgbm9uLWRvcyBleGVjdXRhYmxlcyAqLwogIGlmKGJpblR5cGUgIT0gU0NTX0RPU19CSU5BUlkpCiAgewogICAgaWYoZnVuYyA9PSAwKSAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgICB7CiAgICAgIExQU1RSIGZ1bGxDbWRMaW5lOwogICAgICBXT1JEIGZ1bGxDbWRMZW5ndGg7CiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihibGstPmNtZGxpbmUpLE9GRlNFVE9GKGJsay0+Y21kbGluZSkpOwogICAgICBMUEJZVEUgZW52YmxvY2sgPSBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwgMCk7CiAgICAgIGludCAgICBjbWRMZW5ndGggPSBjbWRsaW5lWzBdOwoKICAgICAgLyoKICAgICAgICogSWYgY21kTGVuZ3RoIGlzIDEyNywgY29tbWFuZCB0YWlsIGlzIHRydW5jYXRlZCBhbmQgZW52aXJvbm1lbnQgCiAgICAgICAqIHZhcmlhYmxlIENNRExJTkUgc2hvdWxkIGNvbnRhaW4gZnVsbCBjb21tYW5kIGxpbmUgCiAgICAgICAqICh0aGlzIGluY2x1ZGVzIGZpbGVuYW1lKS4KICAgICAgICovCiAgICAgIGlmIChjbWRMZW5ndGggPT0gMTI3KQogICAgICB7CiAgICAgICAgICBGSVhNRSggIkNNRExJTkUgYXJndW1lbnQgcGFzc2luZyBpcyB1bmltcGxlbWVudGVkLlxuIiApOwogICAgICAgICAgY21kTGVuZ3RoID0gMTI2OyAvKiBGSVhNRSAqLwogICAgICB9CgogICAgICBmdWxsQ21kTGVuZ3RoID0gKHN0cmxlbihmaWxlbmFtZSkgKyAxKSArIGNtZExlbmd0aCArIDE7IC8qIGZpbGVuYW1lICsgc3BhY2UgKyBjbWRsaW5lICsgdGVybWluYXRpbmcgbnVsbCBjaGFyYWN0ZXIgKi8KCiAgICAgIGZ1bGxDbWRMaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMZW5ndGgpOwogICAgICBpZighZnVsbENtZExpbmUpIHJldHVybiBGQUxTRTsgLyogcmV0dXJuIGZhbHNlIG9uIG1lbW9yeSBhbGxvYyBmYWlsdXJlICovCgogICAgICAvKiBidWlsZCB0aGUgZnVsbCBjb21tYW5kIGxpbmUgZnJvbSB0aGUgZXhlY3V0YWJsZSBmaWxlIGFuZCB0aGUgY29tbWFuZCBsaW5lIGJlaW5nIHBhc3NlZCBpbiAqLwogICAgICBzbnByaW50ZihmdWxsQ21kTGluZSwgZnVsbENtZExlbmd0aCwgIiVzICIsIGZpbGVuYW1lKTsgLyogc3RhcnQgb2ZmIHdpdGggdGhlIGV4ZWN1dGFibGUgZmlsZW5hbWUgYW5kIGEgc3BhY2UgKi8KICAgICAgbWVtY3B5KGZ1bGxDbWRMaW5lICsgc3RybGVuKGZ1bGxDbWRMaW5lKSwgY21kbGluZSArIDEsIGNtZExlbmd0aCk7IC8qIGFwcGVuZCBjbWRsaW5lIG9udG8gdGhlIGVuZCAqLwogICAgICBmdWxsQ21kTGluZVtmdWxsQ21kTGVuZ3RoIC0gMV0gPSAwOyAvKiBudWxsIHRlcm1pbmF0ZSBzdHJpbmcgKi8KCiAgICAgIFplcm9NZW1vcnkgKCZzdCwgc2l6ZW9mKFNUQVJUVVBJTkZPQSkpOwogICAgICBzdC5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwogICAgICByZXQgPSBDcmVhdGVQcm9jZXNzQSAoTlVMTCwgZnVsbENtZExpbmUsIE5VTEwsIE5VTEwsIFRSVUUsIDAsIGVudmJsb2NrLCBOVUxMLCAmc3QsICZwZSk7CgogICAgICAvKiB3YWl0IGZvciB0aGUgYXBwIHRvIGZpbmlzaCBhbmQgY2xlYW4gdXAgUFJPQ0VTU19JTkZPUk1BVElPTiBoYW5kbGVzICovCiAgICAgIGlmKHJldCkKICAgICAgewogICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGUuaFByb2Nlc3MsIElORklOSVRFKTsgIC8qIHdhaXQgaGVyZSB1bnRpbCB0aGUgY2hpbGQgcHJvY2VzcyBpcyBjb21wbGV0ZSAqLwogICAgICAgIENsb3NlSGFuZGxlKHBlLmhQcm9jZXNzKTsKICAgICAgICBDbG9zZUhhbmRsZShwZS5oVGhyZWFkKTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnVsbENtZExpbmUpOyAgLyogZnJlZSB0aGUgbWVtb3J5IHdlIGFsbG9jYXRlZCAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICBGSVhNRSgiRVhFQyB0eXBlIG9mICVkIG5vdCBpbXBsZW1lbnRlZCBmb3Igbm9uLWRvcyBleGVjdXRhYmxlc1xuIiwgZnVuYyk7CiAgICAgIHJldCA9IEZBTFNFOwogICAgfQoKICAgIHJldHVybiByZXQ7CiAgfSAvKiBpZihiaW5UeXBlICE9IFNDU19ET1NfQklOQVJZKSAqLwoKCiAgLyogaGFuZGxlIGRvcyBleGVjdXRhYmxlcyAqLwoKICBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CgogIHN3aXRjaCAoZnVuYykgewogIGNhc2UgMDogLyogbG9hZCBhbmQgZXhlY3V0ZSAqLwogIGNhc2UgMTogLyogbG9hZCBidXQgZG9uJ3QgZXhlY3V0ZSAqLwogICAgewogICAgICAvKiBzYXZlIGN1cnJlbnQgcHJvY2VzcydzIHJldHVybiBTUzpTUCBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIHBzcC0+c2F2ZVN0YWNrID0gKERXT1JEKU1BS0VTRUdQVFIoY29udGV4dC0+U2VnU3MsIExPV09SRChjb250ZXh0LT5Fc3ApKTsKICAgIH0KICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwsICgoRXhlY0Jsb2NrICopcGFyYW1ibGspLT5lbnZfc2VnICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBpdCwKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CgogICAgICAvKiBGaXJzdCBjaGFyYWN0ZXIgY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tbWFuZCBsaW5lLiAqLwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgKExQU1RSKWNtZGxpbmUgKyAxLCBjbWRsaW5lWzBdKTsKCiAgICAgIC8qIHRoZSBsYW1lIE1TLURPUyBlbmdpbmVlcnMgZGVjaWRlZCB0aGF0IHRoZSByZXR1cm4gYWRkcmVzcyBzaG91bGQgYmUgaW4gaW50MjIgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIChGQVJQUk9DMTYpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdDcywgTE9XT1JEKGNvbnRleHQtPkVpcCkpKTsKICAgICAgaWYgKGZ1bmMpIHsKCS8qIGRvbid0IGV4ZWN1dGUsIGp1c3QgcmV0dXJuIHN0YXJ0dXAgc3RhdGUgKi8KICAgICAgICAvKgogICAgICAgICAqIEZyb20gUmFscGggQnJvd246CiAgICAgICAgICogIEZvciBmdW5jdGlvbiAwMWgsIHRoZSBBWCB2YWx1ZSB0byBiZSBwYXNzZWQgdG8gdGhlIGNoaWxkIHByb2dyYW0gCiAgICAgICAgICogIGlzIHB1dCBvbiB0b3Agb2YgdGhlIGNoaWxkJ3Mgc3RhY2sKICAgICAgICAgKi8KICAgICAgICBMUEJZVEUgc3RhY2s7CiAgICAgICAgaW5pdF9zcCAtPSAyOwogICAgICAgIHN0YWNrID0gKExQQllURSkgQ1RYX1NFR19PRkZfVE9fTElOKGNvbnRleHQsIGluaXRfc3MsIGluaXRfc3ApOwogICAgICAgIC8qIEZJWE1FOiBwdXNoIEFYIGNvcnJlY3RseSAqLwogICAgICAgIHN0YWNrWzBdID0gMHgwMDsgICAgLyogcHVzaCBBTCAqLwogICAgICAgIHN0YWNrWzFdID0gMHgwMDsgICAgLyogcHVzaCBBSCAqLwoJCglibGstPmluaXRfY3MgPSBpbml0X2NzOwoJYmxrLT5pbml0X2lwID0gaW5pdF9pcDsKCWJsay0+aW5pdF9zcyA9IGluaXRfc3M7CglibGstPmluaXRfc3AgPSBpbml0X3NwOwogICAgICB9IGVsc2UgewoJLyogZXhlY3V0ZSBieSBtYWtpbmcgdXMgcmV0dXJuIHRvIG5ldyBwcm9jZXNzICovCgljb250ZXh0LT5TZWdDcyA9IGluaXRfY3M7Cgljb250ZXh0LT5FaXAgICA9IGluaXRfaXA7Cgljb250ZXh0LT5TZWdTcyA9IGluaXRfc3M7Cgljb250ZXh0LT5Fc3AgICA9IGluaXRfc3A7Cgljb250ZXh0LT5TZWdEcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPlNlZ0VzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+RWF4ICAgPSAwOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIDM6IC8qIGxvYWQgb3ZlcmxheSAqLwogICAgewogICAgICBPdmVybGF5QmxvY2sgKmJsayA9IChPdmVybGF5QmxvY2sgKilwYXJhbWJsazsKICAgICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgYmxrLCAwKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBGSVhNRSgiRVhFQyBsb2FkIHR5cGUgJWQgbm90IGltcGxlbWVudGVkXG4iLCBmdW5jKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZVTkNUSU9OKTsKICAgIGJyZWFrOwogIH0KICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogIE1aX0luaXRNZW1vcnkoKTsKICBNWl9Jbml0VGFzaygpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICBpZiAobG9vcF90aHJlYWQpIHsKICAgIERPU19TUEMgc3BjOwogICAgSEFORExFIGV2ZW50OwoKICAgIHNwYy5wcm9jID0gcHJvYzsKICAgIHNwYy5hcmcgPSBhcmc7CiAgICBldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICBQb3N0VGhyZWFkTWVzc2FnZUEobG9vcF90aWQsIFdNX1VTRVIsIChXUEFSQU0pZXZlbnQsIChMUEFSQU0pJnNwYyk7CiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGV2ZW50LCBJTkZJTklURSk7CiAgICBDbG9zZUhhbmRsZShldmVudCk7CiAgfSBlbHNlCiAgICBwcm9jKGFyZyk7Cn0KCnN0YXRpYyBEV09SRCBXSU5BUEkgTVpfRE9TVk0oIExQVk9JRCBscEV4dHJhICkKewogIENPTlRFWFQgY29udGV4dDsKICBEV09SRCByZXQ7CgogIGRvc3ZtX3BpZCA9IGdldHBpZCgpOwoKICBtZW1zZXQoICZjb250ZXh0LCAwLCBzaXplb2YoY29udGV4dCkgKTsKICBjb250ZXh0LlNlZ0NzICA9IGluaXRfY3M7CiAgY29udGV4dC5FaXAgICAgPSBpbml0X2lwOwogIGNvbnRleHQuU2VnU3MgID0gaW5pdF9zczsKICBjb250ZXh0LkVzcCAgICA9IGluaXRfc3A7CiAgY29udGV4dC5TZWdEcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5TZWdFcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5FRmxhZ3MgPSBWODZfRkxBRyB8IFZJRl9NQVNLOwogIERPU1ZNX1NldFRpbWVyKDB4MTAwMDApOwogIHJldCA9IERPU1ZNX0VudGVyKCAmY29udGV4dCApOwoKICBkb3N2bV9waWQgPSAwOwogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpCnsKICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShHZXRDdXJyZW50UHJvY2VzcygpLCBHZXRDdXJyZW50VGhyZWFkKCksCiAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3MoKSwgJmxvb3BfdGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgIDAsIEZBTFNFLCBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpKQogICAgcmV0dXJuIEZBTFNFOwogIGRvc3ZtX3RocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBNWl9ET1NWTSwgTlVMTCwgQ1JFQVRFX1NVU1BFTkRFRCwgJmRvc3ZtX3RpZCk7CiAgaWYgKCFkb3N2bV90aHJlYWQpIHsKICAgIENsb3NlSGFuZGxlKGxvb3BfdGhyZWFkKTsKICAgIGxvb3BfdGhyZWFkID0gMDsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgbG9vcF90aWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICBUREIgKnBUYXNrID0gR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBET1NWTV9wc3AsIDAgKTsKICBEV09SRCBydjsKICBTWVNMRVZFTCAqbG9jazsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIGNtZHRhaWwsIGxlbmd0aCk7CiAgcFRhc2stPmZsYWdzIHw9IFREQkZfV0lOT0xEQVA7CgogIC8qIERUQSBpcyBzZXQgdG8gUFNQOjAwODBoIHdoZW4gYSBwcm9ncmFtIGlzIHN0YXJ0ZWQuICovCiAgcFRhc2stPmR0YSA9IE1BS0VTRUdQVFIoIERPU1ZNX3BzcCwgMHg4MCApOwoKICBHZXRwV2luMTZMb2NrKCAmbG9jayApOwogIF9MZWF2ZVN5c0xldmVsKCBsb2NrICk7CgogIFJlc3VtZVRocmVhZChkb3N2bV90aHJlYWQpOwogIHJ2ID0gRE9TVk1fTG9vcChkb3N2bV90aHJlYWQpOwoKICBDbG9zZUhhbmRsZShkb3N2bV90aHJlYWQpOwogIGRvc3ZtX3RocmVhZCA9IDA7IGRvc3ZtX3RpZCA9IDA7CiAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogIGxvb3BfdGhyZWFkID0gMDsgbG9vcF90aWQgPSAwOwoKICBWR0FfQ2xlYW4oKTsKICBFeGl0UHJvY2Vzcyhydik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgaWYgKERPU1ZNX3BzcCkgewogICAgV09SRCBwc3Bfc2VnID0gY3NfcHNwID8gY29udGV4dC0+U2VnQ3MgOiBET1NWTV9wc3A7CiAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBzcF9zZWcgPDwgNCk7CiAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgV09SRCBwYXJwc3AgPSBwc3AtPnBhcmVudFBTUDsgLyogY2hlY2sgZm9yIHBhcmVudCBET1MgcHJvY2VzcyAqLwogICAgaWYgKHBhcnBzcCkgewogICAgICAvKiByZXRyaWV2ZSBwYXJlbnQncyByZXR1cm4gYWRkcmVzcyAqLwogICAgICBGQVJQUk9DMTYgcmV0YWRkciA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMywgcHNwLT5zYXZlZGludDIzKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwwKSApOwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4oRE9TVk1fcHNwLDApICk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgRE9TVk1fcHNwID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIERPU1ZNX3JldHZhbCA9IHJldHZhbDsKICAgICAgY29udGV4dC0+U2VnQ3MgPSBTRUxFQ1RPUk9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5FaXAgICA9IE9GRlNFVE9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5TZWdTcyA9IFNFTEVDVE9ST0YocHNwLT5zYXZlU3RhY2spOwogICAgICBjb250ZXh0LT5Fc3AgICA9IE9GRlNFVE9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlCiAgICAgIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIChkb3N2bV9waWQgIT0gMCk7IC8qIEZJWE1FOiBkbyBhIGJldHRlciBjaGVjayAqLwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXdpbmVfbG9hZF9kb3NfZXhlIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICAgIEZJWE1FKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXG4iKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRklYTUUoIkFjdHVhbCByZWFsLW1vZGUgY2FsbHMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogICAgcHJvYyhhcmcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4aXQKICovCnZvaWQgV0lOQVBJIE1aX0V4aXQoIENPTlRFWFQ4NiAqY29udGV4dCwgQk9PTCBjc19wc3AsIFdPUkQgcmV0dmFsICkKewogIEV4aXRUaHJlYWQoIHJldHZhbCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgICByZXR1cm4gRkFMU0U7Cn0KCiNlbmRpZiAvKiAhTVpfU1VQUE9SVEVEICovCg==