LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfU1lTX1NUQVRfSAojIGluY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgQk9PTCBET1NWTV9pc2Rvc2V4ZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgIERPU1ZNX0lzV2luMTYKICogCiAqIFJldHVybiBUUlVFIGlmIHdlIGFyZSBpbiBXaW5kb3dzIHByb2Nlc3MuCiAqLwpCT09MIERPU1ZNX0lzV2luMTYodm9pZCkKewogIHJldHVybiBET1NWTV9pc2Rvc2V4ZSA/IEZBTFNFIDogVFJVRTsKfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmU7CiAgRFdPUkQgZmNiMTsKICBEV09SRCBmY2IyOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnBpZF90IGRvc3ZtX3BpZDsKCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBIQU5ETEUgZG9zdm1fdGhyZWFkLCBsb29wX3RocmVhZDsKc3RhdGljIERXT1JEIGRvc3ZtX3RpZCwgbG9vcF90aWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICAgIFBEQjE2ICpwc3AgPSBscFBTUDsKCiAgICBpZihsZW5ndGggPiAxMjcpIAogICAgewogICAgICAgIFdBUk4oICJDb21tYW5kIHRhaWwgdHJ1bmNhdGVkISAobGVuZ3RoICVkKVxuIiwgbGVuZ3RoICk7CiAgICAgICAgbGVuZ3RoID0gMTI2OwogICAgfQoKICAgIHBzcC0+Y21kTGluZVswXSA9IGxlbmd0aDsKCiAgICAvKgogICAgICogTGVuZ3RoIG9mIGV4YWN0bHkgMTI3IGJ5dGVzIG1lYW5zIHRoYXQgZnVsbCBjb21tYW5kIGxpbmUgaXMgCiAgICAgKiBzdG9yZWQgaW4gZW52aXJvbm1lbnQgdmFyaWFibGUgQ01ETElORSBhbmQgUFNQIGNvbnRhaW5zIAogICAgICogY29tbWFuZCB0YWlsIHRydW5jYXRlZCB0byAxMjYgYnl0ZXMuCiAgICAgKi8KICAgIGlmKGxlbmd0aCA9PSAxMjcpCiAgICAgICAgbGVuZ3RoID0gMTI2OwoKICAgIGlmKGxlbmd0aCA+IDApCiAgICAgICAgbWVtbW92ZShwc3AtPmNtZExpbmUrMSwgY21kdGFpbCwgbGVuZ3RoKTsKCiAgICBwc3AtPmNtZExpbmVbbGVuZ3RoKzFdID0gJ1xyJzsKCiAgICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiB1bnNpZ25lZCBpPTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fQWxsb2NCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdXBwZXJjYXNlICovCiB3aGlsZSAoZW52YmxrW2ldKXsKICB3aGlsZSAoZW52YmxrW2ldICE9ICc9Jyl7CiAgIGlmIChlbnZibGtbaV0+PSdhJyAmJiBlbnZibGtbaV0gPD0gJ3onKXsKICAgIGVudmJsa1tpXSAtPSAzMjsKICAgfQogICBpKys7CiAgfQogIGkgKz0gc3RybGVuKGVudmJsaytpKSArIDE7CiB9CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9NYXBEb3NMYXlvdXQoKTsKICAgIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcygpOwogICAgTVNDREVYX0luc3RhbGxDRFJPTSgpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsaywgV09SRCBwYXJfZW52X3NlZyApCnsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogIExQU1RSIG9sZGVudiA9IDA7CiAgaW50IHgsIG9sZF9jb209MCwgYWxsb2M7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZywgbG9hZF9zZWcsIHJlbF9zZWcsIG9sZHBzcF9zZWc7CiAgRFdPUkQgbGVuOwoKICBpZiAoRE9TVk1fcHNwKSB7CiAgICAvKiBET1MgcHJvY2VzcyBhbHJlYWR5IHJ1bm5pbmcsIGluaGVyaXQgZnJvbSBpdCAqLwogICAgUERCMTYqIHBhcl9wc3A7CiAgICBhbGxvYz0wOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICAgIGlmKCAhcGFyX2Vudl9zZWcpIHsgIAogICAgICAgIHBhcl9wc3AgPSAoUERCMTYqKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICAgIG9sZGVudiA9IChMUFNUUikoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBuZXcgRE9TIHByb2Nlc3MsIGluaGVyaXRpbmcgZnJvbSBXaW5lIGVudmlyb25tZW50ICovCiAgICBhbGxvYz0xOwogICAgb2xkcHNwX3NlZyA9IDA7CiAgICBpZiggIXBhcl9lbnZfc2VnKQogICAgICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgY2hhciAqcCA9IHN0cnJjaHIoIGZpbGVuYW1lLCAnLicgKTsKICBpZiAoIXAgfHwgc3RyY2FzZWNtcCggcCwgIi5jb20iICkpICAvKiBjaGVjayBmb3IgLkNPTSBleHRlbnNpb24gKi8KICB7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogIH0KICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoaEZpbGUsTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIC8qIEZyb20gUmFsZiBCcm93biBJbnRlcnJ1cHQgTGlzdDogSWYgdGhlIHdvcmQgYXQgb2Zmc2V0IDAyaCBpcyA0LCBpdCBzaG91bGQKICAgKiBiZSB0cmVhdGVkIGFzIDAwaCwgc2luY2UgcHJlLTEuMTAgdmVyc2lvbnMgb2YgdGhlIE1TIGxpbmtlciBzZXQgaXQgdGhhdAogICAqIHdheS4gKi8KICBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogIG1pbl9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9taW5hbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKICBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiB9CgogIGlmIChhbGxvYykgTVpfSW5pdE1lbW9yeSgpOwoKICBpZiAob2JsaykgewogICAgLyogbG9hZCBvdmVybGF5IGludG8gcHJlYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgbG9hZF9zZWc9b2Jsay0+bG9hZF9zZWc7CiAgICByZWxfc2VnPW9ibGstPnJlbF9zZWc7CiAgICBsb2FkX3N0YXJ0PShMUEJZVEUpKChEV09SRClsb2FkX3NlZzw8NCk7CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiAgICBpZiggcGFyX2Vudl9zZWcpCiAgICAgICAgZW52X3NlZyA9IHBhcl9lbnZfc2VnOwogICAgZWxzZQogICAgICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwogICAgaWYgKGFsbG9jKQogICAgICAgIEZyZWVFbnZpcm9ubWVudFN0cmluZ3NBKCBvbGRlbnYpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lZCwgbWF4PSVkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiAgICBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKCk7CiAgICBpZiAoYXZhaWw8bWluX3NpemUpIHsKICAgICAgRVJSKCJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiAgICBwc3Bfc3RhcnQ9RE9TTUVNX0FsbG9jQmxvY2soYXZhaWwsJkRPU1ZNX3BzcCk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPURPU1ZNX3BzcCsob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDh4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIC8qIGNoZWNrIGlmIHRoaXMgaXMgZHVlIHRvIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgcHJlLTEuMTAgTVMgbGlua2VyIGFuZCB3ZQogICAgIHJlYWx5IGhhZCBvbmx5IDQgYnl0ZXMgb24gdGhlIGxhc3QgcGFnZSAqLwogIGlmIChtel9oZWFkZXIuZV9jYmxwICE9IDQgfHwgaW1hZ2Vfc2l6ZSAtIGxlbiAhPSA1MTIgLSA0KSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPXJlbF9zZWc7CiAgfQogfQoKICBpZiAoIW9ibGspIHsKICAgIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKICAgIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKICAgIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKICAgIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKICAgIGlmIChvbGRfY29tKXsKICAgICAgLyogLkNPTSBmaWxlcyBleGl0IHdpdGggcmV0LiBNYWtlIHN1cmUgdGhleSBqdW1wIHRvIHBzcCBzdGFydCAoPWludCAyMCkgKi8KICAgICAgV09SRCogc3RhY2sgPSBQVFJfUkVBTF9UT19MSU4oaW5pdF9zcywgaW5pdF9zcCk7CiAgICAgICpzdGFjayA9IDA7CiAgICB9CgogICAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsaW5pdF9jcyxpbml0X2lwKTsKICB9CgogIGlmIChhbGxvYyAmJiAhTVpfSW5pdFRhc2soKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBET1NWTV9wc3AgPSBvbGRwc3Bfc2VnOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICoKICogQ2FsbGVkIGZyb20gV2luZVZETSB3aGVuIGEgbmV3IHJlYWwtbW9kZSBET1MgcHJvY2VzcyBpcyBzdGFydGVkLgogKiBMb2FkcyBET1MgcHJvZ3JhbSBpbnRvIG1lbW9yeSBhbmQgZXhlY3V0ZXMgdGhlIHByb2dyYW0uCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICAgIGNoYXIgZG9zX2NtZHRhaWxbMTI2XTsKICAgIGludCAgZG9zX2xlbmd0aCA9IDA7CgogICAgSEFORExFIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm47CiAgICBET1NWTV9pc2Rvc2V4ZSA9IFRSVUU7CgogICAgaWYoY21kbGluZSAmJiAqY21kbGluZSkKICAgIHsKICAgICAgICBkb3NfbGVuZ3RoID0gc3RybGVuKGNtZGxpbmUpOwogICAgICAgIG1lbW1vdmUoIGRvc19jbWR0YWlsICsgMSwgY21kbGluZSwgCiAgICAgICAgICAgICAgICAgKGRvc19sZW5ndGggPCAxMjUpID8gZG9zX2xlbmd0aCA6IDEyNSApOwoKICAgICAgICAvKiBOb24tZW1wdHkgY29tbWFuZCB0YWlsIGFsd2F5cyBzdGFydHMgd2l0aCBhdCBsZWFzdCBvbmUgc3BhY2UuICovCiAgICAgICAgZG9zX2NtZHRhaWxbMF0gPSAnICc7CiAgICAgICAgZG9zX2xlbmd0aCsrOwoKICAgICAgICAvKgogICAgICAgICAqIElmIGNvbW1hbmQgdGFpbCBpcyBsb25nZXIgdGhhbiAxMjYgY2hhcmFjdGVycywKICAgICAgICAgKiBzZXQgdGFpbCBsZW5ndGggdG8gMTI3IGFuZCBmaWxsIENNRExJTkUgZW52aXJvbm1lbnQgdmFyaWFibGUgCiAgICAgICAgICogd2l0aCBmdWxsIGNvbW1hbmQgbGluZSAodGhpcyBpbmNsdWRlcyBmaWxlbmFtZSkuCiAgICAgICAgICovCiAgICAgICAgaWYgKGRvc19sZW5ndGggPiAxMjYpCiAgICAgICAgewogICAgICAgICAgICBjaGFyICpjbWQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvc19sZW5ndGggKyBzdHJsZW4oZmlsZW5hbWUpICsgNCApOwogICAgICAgICAgICBjaGFyICpwdHIgPSBjbWQ7CgogICAgICAgICAgICBpZiAoIWNtZCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBmaWxlbmFtZS4gSWYgcGF0aCBpbmNsdWRlcyBzcGFjZXMsIHF1b3RlIHRoZSBwYXRoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHN0cmNocihmaWxlbmFtZSwgJyAnKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQXBwZW5kIGNvbW1hbmQgdGFpbC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjbWRsaW5lWzBdICE9ICcgJykKICAgICAgICAgICAgICAgICpwdHIrKyA9ICcgJzsKICAgICAgICAgICAgc3RyY3B5KCBwdHIsIGNtZGxpbmUgKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0bwogICAgICAgICAgICAgKiBuZXcgRE9TIHByb2Nlc3MuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIVNldEVudmlyb25tZW50VmFyaWFibGVBKCAiQ01ETElORSIsIGNtZCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjbWQgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgIGRvc19sZW5ndGggPSAxMjc7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMLCAwICkpIAogICAgICAgIE1aX0xhdW5jaCggZG9zX2NtZHRhaWwsIGRvc19sZW5ndGggKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqCiAqIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIERXT1JEIGJpblR5cGU7CiAgU1RBUlRVUElORk9BIHN0OwogIFBST0NFU1NfSU5GT1JNQVRJT04gcGU7CiAgSEFORExFIGhGaWxlOwoKICBCT09MIHJldCA9IEZBTFNFOwoKICBpZighR2V0QmluYXJ5VHlwZUEoZmlsZW5hbWUsICZiaW5UeXBlKSkgICAvKiBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIGJpbmFyeSB0aGlzIGlzICovCiAgewogICAgcmV0dXJuIEZBTFNFOyAvKiBiaW5hcnkgaXMgbm90IGFuIGV4ZWN1dGFibGUgKi8KICB9CgogIC8qIGhhbmRsZSBub24tZG9zIGV4ZWN1dGFibGVzICovCiAgaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkKICB7CiAgICBpZihmdW5jID09IDApIC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICAgIHsKICAgICAgTFBTVFIgZnVsbENtZExpbmU7CiAgICAgIFdPUkQgZnVsbENtZExlbmd0aDsKICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CiAgICAgIExQQllURSBlbnZibG9jayA9IFBUUl9SRUFMX1RPX0xJTihwc3AtPmVudmlyb25tZW50LCAwKTsKICAgICAgaW50ICAgIGNtZExlbmd0aCA9IGNtZGxpbmVbMF07CgogICAgICAvKgogICAgICAgKiBJZiBjbWRMZW5ndGggaXMgMTI3LCBjb21tYW5kIHRhaWwgaXMgdHJ1bmNhdGVkIGFuZCBlbnZpcm9ubWVudCAKICAgICAgICogdmFyaWFibGUgQ01ETElORSBzaG91bGQgY29udGFpbiBmdWxsIGNvbW1hbmQgbGluZSAKICAgICAgICogKHRoaXMgaW5jbHVkZXMgZmlsZW5hbWUpLgogICAgICAgKi8KICAgICAgaWYgKGNtZExlbmd0aCA9PSAxMjcpCiAgICAgIHsKICAgICAgICAgIEZJWE1FKCAiQ01ETElORSBhcmd1bWVudCBwYXNzaW5nIGlzIHVuaW1wbGVtZW50ZWQuXG4iICk7CiAgICAgICAgICBjbWRMZW5ndGggPSAxMjY7IC8qIEZJWE1FICovCiAgICAgIH0KCiAgICAgIGZ1bGxDbWRMZW5ndGggPSAoc3RybGVuKGZpbGVuYW1lKSArIDEpICsgY21kTGVuZ3RoICsgMTsgLyogZmlsZW5hbWUgKyBzcGFjZSArIGNtZGxpbmUgKyB0ZXJtaW5hdGluZyBudWxsIGNoYXJhY3RlciAqLwoKICAgICAgZnVsbENtZExpbmUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnVsbENtZExlbmd0aCk7CiAgICAgIGlmKCFmdWxsQ21kTGluZSkgcmV0dXJuIEZBTFNFOyAvKiByZXR1cm4gZmFsc2Ugb24gbWVtb3J5IGFsbG9jIGZhaWx1cmUgKi8KCiAgICAgIC8qIGJ1aWxkIHRoZSBmdWxsIGNvbW1hbmQgbGluZSBmcm9tIHRoZSBleGVjdXRhYmxlIGZpbGUgYW5kIHRoZSBjb21tYW5kIGxpbmUgYmVpbmcgcGFzc2VkIGluICovCiAgICAgIHNucHJpbnRmKGZ1bGxDbWRMaW5lLCBmdWxsQ21kTGVuZ3RoLCAiJXMgIiwgZmlsZW5hbWUpOyAvKiBzdGFydCBvZmYgd2l0aCB0aGUgZXhlY3V0YWJsZSBmaWxlbmFtZSBhbmQgYSBzcGFjZSAqLwogICAgICBtZW1jcHkoZnVsbENtZExpbmUgKyBzdHJsZW4oZnVsbENtZExpbmUpLCBjbWRsaW5lICsgMSwgY21kTGVuZ3RoKTsgLyogYXBwZW5kIGNtZGxpbmUgb250byB0aGUgZW5kICovCiAgICAgIGZ1bGxDbWRMaW5lW2Z1bGxDbWRMZW5ndGggLSAxXSA9IDA7IC8qIG51bGwgdGVybWluYXRlIHN0cmluZyAqLwoKICAgICAgWmVyb01lbW9yeSAoJnN0LCBzaXplb2YoU1RBUlRVUElORk9BKSk7CiAgICAgIHN0LmNiID0gc2l6ZW9mKFNUQVJUVVBJTkZPQSk7CiAgICAgIHJldCA9IENyZWF0ZVByb2Nlc3NBIChOVUxMLCBmdWxsQ21kTGluZSwgTlVMTCwgTlVMTCwgVFJVRSwgMCwgZW52YmxvY2ssIE5VTEwsICZzdCwgJnBlKTsKCiAgICAgIC8qIHdhaXQgZm9yIHRoZSBhcHAgdG8gZmluaXNoIGFuZCBjbGVhbiB1cCBQUk9DRVNTX0lORk9STUFUSU9OIGhhbmRsZXMgKi8KICAgICAgaWYocmV0KQogICAgICB7CiAgICAgICAgV2FpdEZvclNpbmdsZU9iamVjdChwZS5oUHJvY2VzcywgSU5GSU5JVEUpOyAgLyogd2FpdCBoZXJlIHVudGlsIHRoZSBjaGlsZCBwcm9jZXNzIGlzIGNvbXBsZXRlICovCiAgICAgICAgQ2xvc2VIYW5kbGUocGUuaFByb2Nlc3MpOwogICAgICAgIENsb3NlSGFuZGxlKHBlLmhUaHJlYWQpOwogICAgICB9CgogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBmdWxsQ21kTGluZSk7ICAvKiBmcmVlIHRoZSBtZW1vcnkgd2UgYWxsb2NhdGVkICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIEZJWE1FKCJFWEVDIHR5cGUgb2YgJWQgbm90IGltcGxlbWVudGVkIGZvciBub24tZG9zIGV4ZWN1dGFibGVzXG4iLCBmdW5jKTsKICAgICAgcmV0ID0gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIHJldDsKICB9IC8qIGlmKGJpblR5cGUgIT0gU0NTX0RPU19CSU5BUlkpICovCgoKICAvKiBoYW5kbGUgZG9zIGV4ZWN1dGFibGVzICovCgogIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKCQkJICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICBpZiAoaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHJldHVybiBGQUxTRTsKCiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdTcywgTE9XT1JEKGNvbnRleHQtPkVzcCkpOwogICAgfQogICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCwgKChFeGVjQmxvY2sgKilwYXJhbWJsayktPmVudl9zZWcgKTsKICAgIGlmIChyZXQpIHsKICAgICAgLyogTVpfTG9hZEltYWdlIGNyZWF0ZWQgYSBuZXcgUFNQIGFuZCBsb2FkZWQgbmV3IHZhbHVlcyBpbnRvIGl0LAogICAgICAgKiBsZXQncyB3b3JrIG9uIHRoZSBuZXcgdmFsdWVzIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgRXhlY0Jsb2NrICpibGsgPSAoRXhlY0Jsb2NrICopcGFyYW1ibGs7CiAgICAgIExQQllURSBjbWRsaW5lID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoYmxrLT5jbWRsaW5lKSxPRkZTRVRPRihibGstPmNtZGxpbmUpKTsKCiAgICAgIC8qIEZpcnN0IGNoYXJhY3RlciBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21tYW5kIGxpbmUuICovCiAgICAgIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCAoTFBTVFIpY21kbGluZSArIDEsIGNtZGxpbmVbMF0pOwoKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwogICAgICAgIC8qCiAgICAgICAgICogRnJvbSBSYWxwaCBCcm93bjoKICAgICAgICAgKiAgRm9yIGZ1bmN0aW9uIDAxaCwgdGhlIEFYIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgY2hpbGQgcHJvZ3JhbSAKICAgICAgICAgKiAgaXMgcHV0IG9uIHRvcCBvZiB0aGUgY2hpbGQncyBzdGFjawogICAgICAgICAqLwogICAgICAgIExQQllURSBzdGFjazsKICAgICAgICBpbml0X3NwIC09IDI7CiAgICAgICAgc3RhY2sgPSAoTFBCWVRFKSBDVFhfU0VHX09GRl9UT19MSU4oY29udGV4dCwgaW5pdF9zcywgaW5pdF9zcCk7CiAgICAgICAgLyogRklYTUU6IHB1c2ggQVggY29ycmVjdGx5ICovCiAgICAgICAgc3RhY2tbMF0gPSAweDAwOyAgICAvKiBwdXNoIEFMICovCiAgICAgICAgc3RhY2tbMV0gPSAweDAwOyAgICAvKiBwdXNoIEFIICovCgkKCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+U2VnRXMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBibGssIDApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTVpfSW5pdE1lbW9yeSgpOwogIE1aX0luaXRUYXNrKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogIGlmIChsb29wX3RocmVhZCkgewogICAgRE9TX1NQQyBzcGM7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgc3BjLnByb2MgPSBwcm9jOwogICAgc3BjLmFyZyA9IGFyZzsKICAgIGV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIFBvc3RUaHJlYWRNZXNzYWdlQShsb29wX3RpZCwgV01fVVNFUiwgKFdQQVJBTSlldmVudCwgKExQQVJBTSkmc3BjKTsKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9IGVsc2UKICAgIHByb2MoYXJnKTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBNWl9ET1NWTSggTFBWT0lEIGxwRXh0cmEgKQp7CiAgQ09OVEVYVCBjb250ZXh0OwogIERXT1JEIHJldDsKCiAgZG9zdm1fcGlkID0gZ2V0cGlkKCk7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LlNlZ0VzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LkVGbGFncyA9IFY4Nl9GTEFHIHwgVklGX01BU0s7CiAgRE9TVk1fU2V0VGltZXIoMHgxMDAwMCk7CiAgcmV0ID0gRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7CgogIGRvc3ZtX3BpZCA9IDA7CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGlmICghRHVwbGljYXRlSGFuZGxlKEdldEN1cnJlbnRQcm9jZXNzKCksIEdldEN1cnJlbnRUaHJlYWQoKSwKICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2VzcygpLCAmbG9vcF90aHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgMCwgRkFMU0UsIERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICByZXR1cm4gRkFMU0U7CiAgZG9zdm1fdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIE1aX0RPU1ZNLCBOVUxMLCBDUkVBVEVfU1VTUEVOREVELCAmZG9zdm1fdGlkKTsKICBpZiAoIWRvc3ZtX3RocmVhZCkgewogICAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogICAgbG9vcF90aHJlYWQgPSAwOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICBsb29wX3RpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICkKewogIFREQiAqcFRhc2sgPSBHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIERPU1ZNX3BzcCwgMCApOwogIERXT1JEIHJ2OwogIFNZU0xFVkVMICpsb2NrOwoKICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kdGFpbCwgbGVuZ3RoKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgLyogRFRBIGlzIHNldCB0byBQU1A6MDA4MGggd2hlbiBhIHByb2dyYW0gaXMgc3RhcnRlZC4gKi8KICBwVGFzay0+ZHRhID0gTUFLRVNFR1BUUiggRE9TVk1fcHNwLCAweDgwICk7CgogIEdldHBXaW4xNkxvY2soICZsb2NrICk7CiAgX0xlYXZlU3lzTGV2ZWwoIGxvY2sgKTsKCiAgUmVzdW1lVGhyZWFkKGRvc3ZtX3RocmVhZCk7CiAgcnYgPSBET1NWTV9Mb29wKGRvc3ZtX3RocmVhZCk7CgogIENsb3NlSGFuZGxlKGRvc3ZtX3RocmVhZCk7CiAgZG9zdm1fdGhyZWFkID0gMDsgZG9zdm1fdGlkID0gMDsKICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgbG9vcF90aHJlYWQgPSAwOyBsb29wX3RpZCA9IDA7CgogIFZHQV9DbGVhbigpOwogIEV4aXRQcm9jZXNzKHJ2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBpZiAoRE9TVk1fcHNwKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IERPU1ZNX3BzcDsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIHBzcC0+c2F2ZWRpbnQyMik7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihwc3AtPmVudmlyb25tZW50LDApICk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihET1NWTV9wc3AsMCkgKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBET1NWTV9wc3AgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgRE9TVk1fcmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gKGRvc3ZtX3BpZCAhPSAwKTsgLyogRklYTUU6IGRvIGEgYmV0dGVyIGNoZWNrICovCn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIHdpbmVfbG9hZF9kb3NfZXhlKCBMUENTVFIgZmlsZW5hbWUsIExQQ1NUUiBjbWRsaW5lICkKewogICAgRklYTUUoIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4ZWMKICovCkJPT0wgV0lOQVBJIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiBjYW4ndCBoYXBwZW4gKi8KICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgICBGSVhNRSgiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0hXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9SdW5JblRocmVhZAogKi8Kdm9pZCBXSU5BUEkgTVpfUnVuSW5UaHJlYWQoIFBBUENGVU5DIHByb2MsIFVMT05HX1BUUiBhcmcgKQp7CiAgICBwcm9jKGFyZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICAgIHJldHVybiBGQUxTRTsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8K