LyoKICogTU1JTyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTggQW5kcmV3IFRheWxvcgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICogQ29weXJpZ2h0IDIwMDAsMjAwMiBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKiBTdGlsbCB0byBiZSBkb25lOgogKiAJKyBjb3JyZWN0IGhhbmRsaW5nIG9mIGdsb2JhbC9sb2NhbCBJT1Byb2NzIChhbmQgdGVtcG9yYXJ5IElPUHJvY3MpCiAqCSsgbW9kZSBvZiBtbWlvIG9iamVjdHMgaXMgbm90IHVzZWQgKHJlYWQgdnMgd3JpdGUgdnMgcmVhZHdyaXRlKQogKgkrIHRocmVhZCBzYWZlbmVzcwogKiAgICAgICsgMzIgQSA8PT4gVyBtZXNzYWdlIG1hcHBpbmcKICovCgoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ3aW5lbW0uaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtbWlvKTsKCkxSRVNVTFQgICAgICAgICAoKnBGbk1taW9DYWxsYmFjazE2KShEV09SRCxMUE1NSU9JTkZPLFVJTlQsTFBBUkFNLExQQVJBTSkgLyogPSBOVUxMICovOwoKc3RhdGljIFdJTkVfTU1JTyAqTU1JT0xpc3Q7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAJbW1pb0Rvc0lPUHJvYyAgICAgICAgICAgCQlbaW50ZXJuYWxdCiAqLwpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBtbWlvRG9zSU9Qcm9jKExQTU1JT0lORk8gbHBtbWlvaW5mbywgVUlOVCB1TWVzc2FnZSwKCQkJCSAgICAgIExQQVJBTSBsUGFyYW0xLCBMUEFSQU0gbFBhcmFtMikKewogICAgTFJFU1VMVAlyZXQgPSBNTVNZU0VSUl9OT0VSUk9SOwoKICAgIFRSQUNFKCIoJXAsICVYLCAweCVseCwgMHglbHgpO1xuIiwgbHBtbWlvaW5mbywgdU1lc3NhZ2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAgIHN3aXRjaCAodU1lc3NhZ2UpIHsKICAgIGNhc2UgTU1JT01fT1BFTjoKCXsKCSAgICAvKiBQYXJhbWV0ZXJzOgoJICAgICAqIGxQYXJhbTEgPSBzekZpbGVOYW1lIHBhcmFtZXRlciBmcm9tIG1taW9PcGVuCgkgICAgICogbFBhcmFtMiA9IHJlc2VydmVkCgkgICAgICogUmV0dXJuczogemVybyBvbiBzdWNjZXNzLCBlcnJvciBjb2RlIG9uIGVycm9yCgkgICAgICogTk9URTogbERpc2tPZmZzZXQgYXV0b21hdGljYWxseSBzZXQgdG8gemVybwoJICAgICAqLwoJICAgIExQQ1NUUiAgICAgIHN6RmlsZU5hbWUgPSAoTFBDU1RSKWxQYXJhbTE7CgoJICAgIGlmIChscG1taW9pbmZvLT5kd0ZsYWdzICYgTU1JT19HRVRURU1QKSB7CgkJRklYTUUoIk1NSU9fR0VUVEVNUCBub3QgaW1wbGVtZW50ZWRcbiIpOwoJCXJldHVybiBNTUlPRVJSX0NBTk5PVE9QRU47CgkgICAgfQoKCSAgICAvKiBpZiBmaWxlbmFtZSBOVUxMLCBhc3N1bWUgb3BlbiBmaWxlIGhhbmRsZSBpbiBhZHdJbmZvWzBdICovCgkgICAgaWYgKHN6RmlsZU5hbWUpIHsKICAgICAgICAgICAgICAgIE9GU1RSVUNUICAgIG9mczsKICAgICAgICAgICAgICAgIGxwbW1pb2luZm8tPmFkd0luZm9bMF0gPSAoRFdPUkQpT3BlbkZpbGUoc3pGaWxlTmFtZSwgJm9mcywgbHBtbWlvaW5mby0+ZHdGbGFncyAmIDB4RkZGRik7CiAgICAgICAgICAgIH0KCSAgICBpZiAobHBtbWlvaW5mby0+YWR3SW5mb1swXSA9PSAoRFdPUkQpSEZJTEVfRVJST1IpCgkJcmV0ID0gTU1JT0VSUl9DQU5OT1RPUEVOOwoJfQoJYnJlYWs7CgogICAgY2FzZSBNTUlPTV9DTE9TRToKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gd0ZsYWdzIHBhcmFtZXRlciBmcm9tIG1taW9DbG9zZQoJICogbFBhcmFtMiA9IHVudXNlZAoJICogUmV0dXJuczogemVybyBvbiBzdWNjZXNzLCBlcnJvciBjb2RlIG9uIGVycm9yCgkgKi8KCWlmICghKGxQYXJhbTEgJiBNTUlPX0ZIT1BFTikpCgkgICAgX2xjbG9zZSgoSEZJTEUpbHBtbWlvaW5mby0+YWR3SW5mb1swXSk7CglicmVhazsKCiAgICBjYXNlIE1NSU9NX1JFQUQ6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IGh1Z2UgcG9pbnRlciB0byByZWFkIGJ1ZmZlcgoJICogbFBhcmFtMiA9IG51bWJlciBvZiBieXRlcyB0byByZWFkCgkgKiBSZXR1cm5zOiBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgMCBmb3IgRU9GLCAtMSBmb3IgZXJyb3IgKGVycm9yIGNvZGUKCSAqCSAgIGluIHdFcnJvclJldCkKCSAqLwoJcmV0ID0gX2xyZWFkKChIRklMRSlscG1taW9pbmZvLT5hZHdJbmZvWzBdLCAoSFBTVFIpbFBhcmFtMSwgKExPTkcpbFBhcmFtMik7CglpZiAocmV0ICE9IC0xKQoJICAgIGxwbW1pb2luZm8tPmxEaXNrT2Zmc2V0ICs9IHJldDsKCglicmVhazsKCiAgICBjYXNlIE1NSU9NX1dSSVRFOgogICAgY2FzZSBNTUlPTV9XUklURUZMVVNIOgoJLyogbm8gaW50ZXJuYWwgYnVmZmVyaW5nLCBzbyBXUklURUZMVVNIIGhhbmRsZWQgc2FtZSBhcyBXUklURSAqLwoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gaHVnZSBwb2ludGVyIHRvIHdyaXRlIGJ1ZmZlcgoJICogbFBhcmFtMiA9IG51bWJlciBvZiBieXRlcyB0byB3cml0ZQoJICogUmV0dXJuczogbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4sIC0xIGZvciBlcnJvciAoZXJyb3IgY29kZSBpbgoJICoJCXdFcnJvclJldCkKCSAqLwoJcmV0ID0gX2h3cml0ZSgoSEZJTEUpbHBtbWlvaW5mby0+YWR3SW5mb1swXSwgKEhQU1RSKWxQYXJhbTEsIChMT05HKWxQYXJhbTIpOwoJaWYgKHJldCAhPSAtMSkKCSAgICBscG1taW9pbmZvLT5sRGlza09mZnNldCArPSByZXQ7CglicmVhazsKCiAgICBjYXNlIE1NSU9NX1NFRUs6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IG5ldyBwb3NpdGlvbgoJICogbFBhcmFtMiA9IGZyb20gd2hlbmNlIHRvIHNlZWsgKFNFRUtfU0VULCBTRUVLX0NVUiwgU0VFS19FTkQpCgkgKiBSZXR1cm5zOiBuZXcgZmlsZSBwb3N0aW9uLCAtMSBvbiBlcnJvcgoJICovCglyZXQgPSBfbGxzZWVrKChIRklMRSlscG1taW9pbmZvLT5hZHdJbmZvWzBdLCAoTE9ORylsUGFyYW0xLCAoTE9ORylsUGFyYW0yKTsKCWlmIChyZXQgIT0gLTEpCgkgICAgbHBtbWlvaW5mby0+bERpc2tPZmZzZXQgPSByZXQ7CglyZXR1cm4gcmV0OwoKICAgIGNhc2UgTU1JT01fUkVOQU1FOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBvbGQgbmFtZQoJICogbFBhcmFtMiA9IG5ldyBuYW1lCgkgKiBSZXR1cm5zOiB6ZXJvIG9uIHN1Y2Nlc3MsIG5vbi16ZXJvIG9uIGZhaWx1cmUKCSAqLwogCSBpZiAoIU1vdmVGaWxlQSgoY29uc3QgY2hhciopbFBhcmFtMSwgKGNvbnN0IGNoYXIqKWxQYXJhbTIpKQoJICAgICByZXQgPSBNTUlPRVJSX0ZJTEVOT1RGT1VORDsKCSBicmVhazsKCiAgICBkZWZhdWx0OgoJRklYTUUoInVuZXhwZWN0ZWQgbWVzc2FnZSAldVxuIiwgdU1lc3NhZ2UpOwoJcmV0dXJuIDA7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgCW1taW9NZW1JT1Byb2MgICAgICAgICAgIAkJW2ludGVybmFsXQogKi8Kc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgbW1pb01lbUlPUHJvYyhMUE1NSU9JTkZPIGxwbW1pb2luZm8sIFVJTlQgdU1lc3NhZ2UsCgkJCQkgICAgICBMUEFSQU0gbFBhcmFtMSwgTFBBUkFNIGxQYXJhbTIpCnsKICAgIFRSQUNFKCIoJXAsMHglMDR4LDB4JTA4bHgsMHglMDhseClcbiIsIGxwbW1pb2luZm8sIHVNZXNzYWdlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgICBzd2l0Y2ggKHVNZXNzYWdlKSB7CgogICAgY2FzZSBNTUlPTV9PUEVOOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBmaWxlbmFtZSAobXVzdCBiZSBOVUxMKQoJICogbFBhcmFtMiA9IHJlc2VydmVkCgkgKiBSZXR1cm5zOiB6ZXJvIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKCSAqIE5PVEU6IGxEaXNrT2Zmc2V0IGF1dG9tYXRpY2FsbHkgc2V0IHRvIHplcm8KCSAqLwoJLyogRklYTUU6IGlvIHByb2Mgc2hvdWxkbid0IGNoYW5nZSBpdCAqLwoJaWYgKCEobHBtbWlvaW5mby0+ZHdGbGFncyAmIE1NSU9fQ1JFQVRFKSkKCSAgICBscG1taW9pbmZvLT5wY2hFbmRSZWFkID0gbHBtbWlvaW5mby0+cGNoRW5kV3JpdGU7CiAgICAgICAgbHBtbWlvaW5mby0+YWR3SW5mb1swXSA9IEhGSUxFX0VSUk9SOwoJcmV0dXJuIDA7CgogICAgY2FzZSBNTUlPTV9DTE9TRToKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gd0ZsYWdzIHBhcmFtZXRlciBmcm9tIG1taW9DbG9zZQoJICogbFBhcmFtMiA9IHVudXNlZAoJICogUmV0dXJuczogemVybyBvbiBzdWNjZXNzLCBlcnJvciBjb2RlIG9uIGVycm9yCgkgKi8KCXJldHVybiAwOwoKICAgIGNhc2UgTU1JT01fUkVBRDoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gaHVnZSBwb2ludGVyIHRvIHJlYWQgYnVmZmVyCgkgKiBsUGFyYW0yID0gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQKCSAqIFJldHVybnM6IG51bWJlciBvZiBieXRlcyByZWFkLCAwIGZvciBFT0YsIC0xIGZvciBlcnJvciAoZXJyb3IgY29kZQoJICoJICAgaW4gd0Vycm9yUmV0KQoJICogTk9URTogbERpc2tPZmZzZXQgc2hvdWxkIGJlIHVwZGF0ZWQKCSAqLwoJRklYTUUoIk1NSU9NX1JFQUQgb24gbWVtb3J5IGZpbGVzIHNob3VsZCBub3Qgb2NjdXIsIGJ1ZmZlciBtYXkgYmUgbG9zdCFcbiIpOwoJcmV0dXJuIDA7CgogICAgY2FzZSBNTUlPTV9XUklURToKICAgIGNhc2UgTU1JT01fV1JJVEVGTFVTSDoKCS8qIG5vIGludGVybmFsIGJ1ZmZlcmluZywgc28gV1JJVEVGTFVTSCBoYW5kbGVkIHNhbWUgYXMgV1JJVEUgKi8KCgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IGh1Z2UgcG9pbnRlciB0byB3cml0ZSBidWZmZXIKCSAqIGxQYXJhbTIgPSBudW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKCSAqIFJldHVybnM6IG51bWJlciBvZiBieXRlcyB3cml0dGVuLCAtMSBmb3IgZXJyb3IgKGVycm9yIGNvZGUgaW4KCSAqCQl3RXJyb3JSZXQpCgkgKiBOT1RFOiBsRGlza09mZnNldCBzaG91bGQgYmUgdXBkYXRlZAoJICovCglGSVhNRSgiTU1JT01fV1JJVEUgb24gbWVtb3J5IGZpbGVzIHNob3VsZCBub3Qgb2NjdXIsIGJ1ZmZlciBtYXkgYmUgbG9zdCFcbiIpOwoJcmV0dXJuIDA7CgogICAgY2FzZSBNTUlPTV9TRUVLOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBuZXcgcG9zaXRpb24KCSAqIGxQYXJhbTIgPSBmcm9tIHdoZW5jZSB0byBzZWVrIChTRUVLX1NFVCwgU0VFS19DVVIsIFNFRUtfRU5EKQoJICogUmV0dXJuczogbmV3IGZpbGUgcG9zdGlvbiwgLTEgb24gZXJyb3IKCSAqIE5PVEU6IGxEaXNrT2Zmc2V0IHNob3VsZCBiZSB1cGRhdGVkCgkgKi8KCUZJWE1FKCJNTUlPTV9TRUVLIG9uIG1lbW9yeSBmaWxlcyBzaG91bGQgbm90IG9jY3VyLCBidWZmZXIgbWF5IGJlIGxvc3QhXG4iKTsKCXJldHVybiAtMTsKCiAgICBkZWZhdWx0OgoJRklYTUUoInVuZXhwZWN0ZWQgbWVzc2FnZSAldVxuIiwgdU1lc3NhZ2UpOwoJcmV0dXJuIDA7CiAgICB9Cn0KCi8qIFRoaXMgYXJyYXkgd2lsbCBiZSB0aGUgZW50aXJlIGxpc3QgZm9yIG1vc3QgYXBwcyAKICogTm90ZSB0aGF0IHRlbXBvcmFyeSBpb1Byb2NzIHdpbGwgYmUgc3RvcmVkIHdpdGggYSAwIGZvdXJDQyBjb2RlCiAqLwoKc3RhdGljIHN0cnVjdCBJT1Byb2NMaXN0IGRlZmF1bHRQcm9jc1tdID0gewogICAgeyZkZWZhdWx0UHJvY3NbMV0sIEZPVVJDQ19ET1MsIChMUE1NSU9QUk9DKW1taW9Eb3NJT1Byb2MsIE1NSU9fUFJPQ18zMkEsIDB9LAogICAge05VTEwsICAgICAgICAgICAgIEZPVVJDQ19NRU0sIChMUE1NSU9QUk9DKW1taW9NZW1JT1Byb2MsIE1NSU9fUFJPQ18zMkEsIDB9LAp9OwoKc3RhdGljIHN0cnVjdCBJT1Byb2NMaXN0KglwSU9Qcm9jTGlzdEFuY2hvciA9ICZkZWZhdWx0UHJvY3NbMF07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJTU1JT19GaW5kUHJvY05vZGUgCQkJW0lOVEVSTkFMXQogKgogKiBGaW5kcyB0aGUgUHJvY0xpc3Qgbm9kZSBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBGT1VSQ0MgY29kZS4KICovCnN0YXRpYyBzdHJ1Y3QgSU9Qcm9jTGlzdCoJTU1JT19GaW5kUHJvY05vZGUoRk9VUkNDIGZjY0lPUHJvYykKewogICAgc3RydWN0IElPUHJvY0xpc3QqCXBMaXN0Tm9kZTsKCiAgICBmb3IgKHBMaXN0Tm9kZSA9IHBJT1Byb2NMaXN0QW5jaG9yOyBwTGlzdE5vZGU7IHBMaXN0Tm9kZSA9IHBMaXN0Tm9kZS0+cE5leHQpIHsKCWlmIChwTGlzdE5vZGUtPmZvdXJDQyA9PSBmY2NJT1Byb2MpIHsKCSAgICByZXR1cm4gcExpc3ROb2RlOwoJfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAlNTUlPX0luc3RhbGxJT1Byb2MgCQkJW0lOVEVSTkFMXQogKi8KTFBNTUlPUFJPQyBNTUlPX0luc3RhbGxJT1Byb2MoRk9VUkNDIGZjY0lPUHJvYywgTFBNTUlPUFJPQyBwSU9Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBlbnVtIG1taW9Qcm9jVHlwZSB0eXBlKQp7CiAgICBMUE1NSU9QUk9DCSAgICAgICAgbHBQcm9jID0gTlVMTDsKICAgIHN0cnVjdCBJT1Byb2NMaXN0KiAgcExpc3ROb2RlOwogICAgc3RydWN0IElPUHJvY0xpc3QqKiBwcExpc3ROb2RlOwoKICAgIFRSQUNFKCIoJTA4eCwgJXAsICUwOFgsICVpKVxuIiwgZmNjSU9Qcm9jLCBwSU9Qcm9jLCBkd0ZsYWdzLCB0eXBlKTsKCiAgICBpZiAoZHdGbGFncyAmIE1NSU9fR0xPQkFMUFJPQykKCUZJWE1FKCJHbG9iYWwgcHJvY2VkdXJlcyBub3QgaW1wbGVtZW50ZWRcbiIpOwoKICAgIC8qIGp1c3QgaGFuZGxlIHRoZSBrbm93biBwcm9jZWR1cmVzIGZvciBub3cgKi8KICAgIHN3aXRjaCAoZHdGbGFncyAmIChNTUlPX0lOU1RBTExQUk9DfE1NSU9fUkVNT1ZFUFJPQ3xNTUlPX0ZJTkRQUk9DKSkgewogICAgY2FzZSBNTUlPX0lOU1RBTExQUk9DOgoJLyogQ3JlYXRlIG5ldyBlbnRyeSBmb3IgdGhlIElPUHJvYyBsaXN0ICovCglwTGlzdE5vZGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpwTGlzdE5vZGUpKTsKCWlmIChwTGlzdE5vZGUpIHsKCSAgICAvKiBGaWxsIGluIHRoaXMgbm9kZSAqLwoJICAgIHBMaXN0Tm9kZS0+Zm91ckNDID0gZmNjSU9Qcm9jOwoJICAgIHBMaXN0Tm9kZS0+cElPUHJvYyA9IHBJT1Byb2M7CgkgICAgcExpc3ROb2RlLT50eXBlID0gdHlwZTsKCSAgICBwTGlzdE5vZGUtPmNvdW50ID0gMDsKCgkgICAgLyogU3RpY2sgaXQgb24gdGhlIGVuZCBvZiB0aGUgbGlzdCAqLwoJICAgIHBMaXN0Tm9kZS0+cE5leHQgPSBwSU9Qcm9jTGlzdEFuY2hvcjsKCSAgICBwSU9Qcm9jTGlzdEFuY2hvciA9IHBMaXN0Tm9kZTsKCgkgICAgLyogUmV0dXJuIHRoaXMgSU9Qcm9jIC0gdGhhdCdzIGhvdyB0aGUgY2FsbGVyIGtub3dzIHdlIHN1Y2NlZWRlZCAqLwoJICAgIGxwUHJvYyA9IHBJT1Byb2M7Cgl9CglicmVhazsKCiAgICBjYXNlIE1NSU9fUkVNT1ZFUFJPQzoKCS8qCgkgKiBTZWFyY2ggZm9yIHRoZSBub2RlIHRoYXQgd2UncmUgdHJ5aW5nIHRvIHJlbW92ZQogICAgICAgICAqIFdlIHNlYXJjaCBmb3IgYSBtYXRjaGluZyBmb3VyQ0MgY29kZSBpZiBpdCdzIG5vbiBudWxsLCBvciB0aGUgcHJvYwogICAgICAgICAqIGFkZHJlc3Mgb3RoZXJ3aXNlCiAgICAgICAgICogbm90ZSB0aGF0IHRoaXMgbWV0aG9kIHdvbid0IGZpbmQgdGhlIGZpcnN0IGl0ZW0gb24gdGhlIGxpc3QsIGJ1dAoJICogc2luY2UgdGhlIGZpcnN0IHR3byBpdGVtcyBvbiB0aGlzIGxpc3QgYXJlIG9uZXMgd2Ugd29uJ3QKCSAqIGxldCB0aGUgdXNlciBkZWxldGUgYW55d2F5LCB0aGF0J3Mgb2theQoJICovCglwcExpc3ROb2RlID0gJnBJT1Byb2NMaXN0QW5jaG9yOwoJd2hpbGUgKCgqcHBMaXN0Tm9kZSkgJiYgCiAgICAgICAgICAgICAgICgoZmNjSU9Qcm9jICE9IDApID8gCiAgICAgICAgICAgICAgICAoKnBwTGlzdE5vZGUpLT5mb3VyQ0MgIT0gZmNjSU9Qcm9jIDogCiAgICAgICAgICAgICAgICAoKnBwTGlzdE5vZGUpLT5wSU9Qcm9jICE9IHBJT1Byb2MpKQoJICAgIHBwTGlzdE5vZGUgPSAmKCgqcHBMaXN0Tm9kZSktPnBOZXh0KTsKCglpZiAoKnBwTGlzdE5vZGUpIHsgLyogZm91bmQgaXQgKi8KCSAgICAvKiBGSVhNRTogd2hhdCBzaG91bGQgYmUgZG9uZSBpZiBhbiBvcGVuIG1taW8gb2JqZWN0IHVzZXMgdGhpcyBwcm9jID8KCSAgICAgKiBzaGFsbCB3ZSByZXR1cm4gYW4gZXJyb3IsIG51a2UgdGhlIG1taW8gb2JqZWN0ID8KCSAgICAgKi8KCSAgICBpZiAoKCpwcExpc3ROb2RlKS0+Y291bnQpIHsKCQlFUlIoIkNhbm5vdCByZW1vdmUgYSBtbUlPUHJvYyB3aGlsZSBpbiB1c2VcbiIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICAvKiByZW1vdmUgaXQsIGJ1dCBvbmx5IGlmIGl0IGlzbid0IGJ1aWx0aW4gKi8KCSAgICBpZiAoKCpwcExpc3ROb2RlKSA+PSBkZWZhdWx0UHJvY3MgJiYKCQkoKnBwTGlzdE5vZGUpIDwgZGVmYXVsdFByb2NzICsgc2l6ZW9mKGRlZmF1bHRQcm9jcykpIHsKCQlXQVJOKCJUcmllZCB0byByZW1vdmUgYnVpbHQtaW4gbW1pbyBwcm9jLiBTa2lwcGluZ1xuIik7CgkgICAgfSBlbHNlIHsKCQkvKiBPa2F5LCBudWtlIGl0ICovCgkJc3RydWN0IElPUHJvY0xpc3QqICBwdG1wTm9kZSA9ICpwcExpc3ROb2RlOwoJCWxwUHJvYyA9ICgqcHBMaXN0Tm9kZSktPnBJT1Byb2M7CgkJKnBwTGlzdE5vZGUgPSAoKnBwTGlzdE5vZGUpLT5wTmV4dDsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwdG1wTm9kZSk7CgkgICAgfQoJfQoJYnJlYWs7CgogICAgY2FzZSBNTUlPX0ZJTkRQUk9DOgoJaWYgKChwTGlzdE5vZGUgPSBNTUlPX0ZpbmRQcm9jTm9kZShmY2NJT1Byb2MpKSkgewoJICAgIGxwUHJvYyA9IHBMaXN0Tm9kZS0+cElPUHJvYzsKCX0KCWJyZWFrOwogICAgfQoKICAgIHJldHVybiBscFByb2M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAlzZW5kX21lc3NhZ2UgICAgCQkJW0lOVEVSTkFMXQogKi8Kc3RhdGljIExSRVNVTFQJc2VuZF9tZXNzYWdlKHN0cnVjdCBJT1Byb2NMaXN0KiBpb1Byb2MsIExQTU1JT0lORk8gbW1pb2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgd01zZywgTFBBUkFNIGxQYXJhbTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBUkFNIGxQYXJhbTIsIGVudW0gbW1pb1Byb2NUeXBlIHR5cGUpCnsKICAgIExSRVNVTFQgCQlyZXN1bHQgPSBNTVNZU0VSUl9FUlJPUjsKICAgIExQQVJBTQkJbHAxID0gbFBhcmFtMSwgbHAyID0gbFBhcmFtMjsKCiAgICBpZiAoIWlvUHJvYykgewoJRVJSKCJicnJyXG4iKTsKCXJlc3VsdCA9IE1NU1lTRVJSX0lOVkFMUEFSQU07CiAgICB9CgogICAgc3dpdGNoIChpb1Byb2MtPnR5cGUpIHsKICAgIGNhc2UgTU1JT19QUk9DXzE2OgogICAgICAgIGlmIChwRm5NbWlvQ2FsbGJhY2sxNikKICAgICAgICAgICAgcmVzdWx0ID0gcEZuTW1pb0NhbGxiYWNrMTYoKERXT1JEKWlvUHJvYy0+cElPUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1pb2luZm8sIHdNc2csIGxwMSwgbHAyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgTU1JT19QUk9DXzMyQToKICAgIGNhc2UgTU1JT19QUk9DXzMyVzoKCWlmIChpb1Byb2MtPnR5cGUgIT0gdHlwZSkgewoJICAgIC8qIG1hcCAobFBhcmFtMSwgbFBhcmFtMikgaW50byAobHAxLCBscDIpIDMyIEE8PT5XICovCgkgICAgRklYTUUoIk5JWSAzMiBBPD0+VyBtYXBwaW5nXG4iKTsKCX0KCXJlc3VsdCA9IChpb1Byb2MtPnBJT1Byb2MpKChMUFNUUiltbWlvaW5mbywgd01zZywgbHAxLCBscDIpOwoKI2lmIDAKCWlmIChpb1Byb2MtPnR5cGUgIT0gdHlwZSkgewoJICAgIC8qIHVubWFwIChsUGFyYW0xLCBsUGFyYW0yKSBpbnRvIChscDEsIGxwMikgMzIgQTw9PlcgKi8KCX0KI2VuZGlmCglicmVhazsKICAgIGRlZmF1bHQ6CglGSVhNRSgiSW50ZXJuYWwgZXJyb3JcbiIpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIAkJCU1NSU9fUGFyc2VFeHRBIAkJICAgICAgICBbaW50ZXJuYWxdCiAqCiAqIFBhcnNlcyBhIGZpbGVuYW1lIGZvciB0aGUgZXh0ZW5zaW9uLgogKgogKiBSRVRVUk5TCiAqICBUaGUgRk9VUkNDIGNvZGUgZm9yIHRoZSBleHRlbnNpb24gaWYgZm91bmQsIGVsc2UgMC4KICovCnN0YXRpYyBGT1VSQ0MgTU1JT19QYXJzZUV4dEEoTFBDU1RSIHN6RmlsZU5hbWUpCnsKICAgIC8qIEZpbGVuYW1lcyBhcmUgb2YgdGhlIGZvcm0gZmlsZS5leHR7K0FCQ30KICAgICAgIEZvciBub3csIHdlIHRha2UgdGhlIGxhc3QgJysnIGlmIHByZXNlbnQgKi8KCiAgICBGT1VSQ0MgcmV0ID0gMDsKCiAgICAvKiBOb3RlIHRoYXQgZXh0e1N0YXJ0LEVuZH0gcG9pbnQgdG8gdGhlIC4gYW5kICsgcmVzcGVjdGl2ZWx5ICovCiAgICBMUFNUUiBleHRFbmQ7CiAgICBMUFNUUiBleHRTdGFydDsKCiAgICBUUkFDRSgiKCVzKVxuIiwgZGVidWdzdHJfYShzekZpbGVOYW1lKSk7CgogICAgaWYgKCFzekZpbGVOYW1lKQoJcmV0dXJuIHJldDsKCiAgICAvKiBGaW5kIHRoZSBsYXN0ICcuJyAqLwogICAgZXh0U3RhcnQgPSBzdHJyY2hyKHN6RmlsZU5hbWUsJy4nKTsKCiAgICBpZiAoIWV4dFN0YXJ0KSB7CiAgICAgICAgIEVSUigiTm8gLiBpbiBzekZpbGVOYW1lOiAlc1xuIiwgZGVidWdzdHJfYShzekZpbGVOYW1lKSk7CiAgICB9IGVsc2UgewogICAgICAgIENIQVIgZXh0WzVdOwoKICAgICAgICAvKiBGaW5kIHRoZSAnKycgYWZ0ZXJ3YXJkcyAqLwogICAgICAgIGV4dEVuZCA9IHN0cmNocihleHRTdGFydCwnKycpOwogICAgICAgIGlmIChleHRFbmQpIHsKCiAgICAgICAgICAgIGlmIChleHRFbmQgLSBleHRTdGFydCAtIDEgPiA0KQogICAgICAgICAgICAgICAgV0FSTigiRXh0ZW5zaW9uIGxlbmd0aCA+IDRcbiIpOwogICAgICAgICAgICBsc3RyY3B5bkEoZXh0LCBleHRTdGFydCArIDEsIG1pbihleHRFbmQtZXh0U3RhcnQsNSkpOwoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBObyArIHNvIGp1c3QgYW4gZXh0ZW5zaW9uICovCiAgICAgICAgICAgIGlmIChzdHJsZW4oZXh0U3RhcnQpID4gNCkgewogICAgICAgICAgICAgICAgV0FSTigiRXh0ZW5zaW9uIGxlbmd0aCA+IDRcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxzdHJjcHluQShleHQsIGV4dFN0YXJ0ICsgMSwgNSk7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJHb3QgZXh0ZW5zaW9uOiAlc1xuIiwgZGVidWdzdHJfYShleHQpKTsKCiAgICAgICAgLyogRk9VUkNDIGNvZGVzIGlkZW50aWZ5aW5nIGZpbGUtZXh0ZW5zaW9ucyBtdXN0IGJlIHVwcGVyY2FzZSAqLwogICAgICAgIHJldCA9IG1taW9TdHJpbmdUb0ZPVVJDQ0EoZXh0LCBNTUlPX1RPVVBQRVIpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCU1NSU9fR2V0CQkJW2ludGVybmFsXQogKgogKiBSZXRyaWV2ZXMgdGhlIG1taW8gb2JqZWN0IGZyb20gY3VycmVudCBwcm9jZXNzCiAqLwpMUFdJTkVfTU1JTwlNTUlPX0dldChITU1JTyBoKQp7CiAgICBMUFdJTkVfTU1JTwkJd20gPSBOVUxMOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9jcyk7CiAgICBmb3IgKHdtID0gTU1JT0xpc3Q7IHdtOyB3bSA9IHdtLT5scE5leHQpIHsKCWlmICh3bS0+aW5mby5obW1pbyA9PSBoKQoJICAgIGJyZWFrOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJldJTk1NX2NzKTsKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCU1NSU9fQ3JlYXRlCQkJW2ludGVybmFsXQogKgogKiBDcmVhdGVzIGFuIGludGVybmFsIHJlcHJlc2VudGF0aW9uIGZvciBhIG1taW8gaW5zdGFuY2UKICovCnN0YXRpYwlMUFdJTkVfTU1JTwkJTU1JT19DcmVhdGUodm9pZCkKewogICAgc3RhdGljCVdPUkQJTU1JT19jb3VudGVyID0gMDsKICAgIExQV0lORV9NTUlPCQl3bTsKCiAgICB3bSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV0lORV9NTUlPKSk7CiAgICBpZiAod20pIHsKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9jcyk7CiAgICAgICAgLyogbG9va3VwIG5leHQgdW5hbGxvY2F0ZWQgV09SRCBoYW5kbGUsIHdpdGggYSBub24gTlVMTCB2YWx1ZSAqLwoJd2hpbGUgKCsrTU1JT19jb3VudGVyID09IDAgfHwgTU1JT19HZXQoKEhNTUlPKShVTE9OR19QVFIpTU1JT19jb3VudGVyKSk7Cgl3bS0+aW5mby5obW1pbyA9IChITU1JTykoVUxPTkdfUFRSKU1NSU9fY291bnRlcjsKCXdtLT5scE5leHQgPSBNTUlPTGlzdDsKCU1NSU9MaXN0ID0gd207CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmV0lOTU1fY3MpOwogICAgfQogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJTU1JT19EZXN0cm95CQkJW2ludGVybmFsXQogKi0KICogRGVzdHJveXMgYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gZm9yIGEgbW1pbyBpbnN0YW5jZQogKi8Kc3RhdGljCUJPT0wJCU1NSU9fRGVzdHJveShMUFdJTkVfTU1JTyB3bSkKewogICAgTFBXSU5FX01NSU8qCW07CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJldJTk1NX2NzKTsKICAgIC8qIHNlYXJjaCBmb3IgdGhlIG1hdGNoaW5nIG9uZS4uLiAqLwogICAgbSA9ICZNTUlPTGlzdDsKICAgIHdoaWxlICgqbSAmJiAqbSAhPSB3bSkgbSA9ICYoKm0pLT5scE5leHQ7CiAgICAvKiAuLi5hbmQgZGVzdHJveSAqLwogICAgaWYgKCptKSB7CgkqbSA9ICgqbSktPmxwTmV4dDsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdtKTsKCXdtID0gTlVMTDsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9jcyk7CiAgICByZXR1cm4gd20gPyBGQUxTRSA6IFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAkJTU1JT19GbHVzaCAJCQlbSU5URVJOQUxdCiAqLwpzdGF0aWMJTU1SRVNVTFQgTU1JT19GbHVzaChXSU5FX01NSU8qIHdtLCBVSU5UIHVGbGFncykKewogICAgaWYgKHdtLT5pbmZvLmNjaEJ1ZmZlciAmJiAod20tPmluZm8uZmNjSU9Qcm9jICE9IEZPVVJDQ19NRU0pKSB7CgkvKiBub3QgcXVpdGUgc3VyZSB3aGF0IHRvIGRvIGhlcmUsIGJ1dCBJJ2xsIGd1ZXNzICovCglpZiAod20tPmluZm8uZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgICAgICAgICAgLyogRklYTUU6IGVycm9yIGhhbmRsaW5nICovCgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywgCiAgICAgICAgICAgICAgICAgICAgICAgICB3bS0+aW5mby5sQnVmT2Zmc2V0LCBTRUVLX1NFVCwgTU1JT19QUk9DXzMyQSk7CgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fV1JJVEUsIAogICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSl3bS0+aW5mby5wY2hCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICB3bS0+aW5mby5wY2hOZXh0IC0gd20tPmluZm8ucGNoQnVmZmVyLCBNTUlPX1BST0NfMzJBKTsKCX0KCWlmICh1RmxhZ3MgJiBNTUlPX0VNUFRZQlVGKQoJICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgfQogICAgd20tPmluZm8uZHdGbGFncyAmPSB+TU1JT19ESVJUWTsKCiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJCU1NSU9fR3JhYk5leHRCdWZmZXIJCQlbSU5URVJOQUxdCiAqLwpzdGF0aWMgTE9ORwlNTUlPX0dyYWJOZXh0QnVmZmVyKExQV0lORV9NTUlPIHdtLCBpbnQgZm9yX3JlYWQpCnsKICAgIExPTkcJc2l6ZSA9IHdtLT5pbmZvLmNjaEJ1ZmZlcjsKCiAgICBUUkFDRSgiYm89JXggZG89JXggb2Y9JWx4XG4iLAoJICB3bS0+aW5mby5sQnVmT2Zmc2V0LCB3bS0+aW5mby5sRGlza09mZnNldCwKCSAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywgMCwgU0VFS19DVVIsIE1NSU9fUFJPQ18zMkEpKTsKCiAgICB3bS0+aW5mby5sQnVmT2Zmc2V0ID0gd20tPmluZm8ubERpc2tPZmZzZXQ7CiAgICB3bS0+aW5mby5wY2hOZXh0ID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgd20tPmluZm8ucGNoRW5kUmVhZCA9IHdtLT5pbmZvLnBjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLnBjaEVuZFdyaXRlID0gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyOwoKICAgIHdtLT5iQnVmZmVyTG9hZGVkID0gVFJVRTsKICAgIGlmIChmb3JfcmVhZCkgewoJc2l6ZSA9IHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1JFQUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSl3bS0+aW5mby5wY2hCdWZmZXIsIHNpemUsIE1NSU9fUFJPQ18zMkEpOwoJaWYgKHNpemUgPiAwKQoJICAgIHdtLT5pbmZvLnBjaEVuZFJlYWQgKz0gc2l6ZTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5iQnVmZmVyTG9hZGVkID0gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIHNpemU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgCQlNTUlPX1NldEJ1ZmZlciAJCQkJW0lOVEVSTkFMXQogKi8Kc3RhdGljIE1NUkVTVUxUIE1NSU9fU2V0QnVmZmVyKFdJTkVfTU1JTyogd20sIHZvaWQqIHBjaEJ1ZmZlciwgTE9ORyBjY2hCdWZmZXIsCgkJCSAgICAgICBVSU5UIHVGbGFncykKewogICAgVFJBQ0UoIiglcCAlcCAlZCAldSlcbiIsIHdtLCBwY2hCdWZmZXIsIGNjaEJ1ZmZlciwgdUZsYWdzKTsKCiAgICBpZiAodUZsYWdzKQkJCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwogICAgaWYgKGNjaEJ1ZmZlciA+IDB4RkZGRikKCVdBUk4oIlVudGVzdGVkIGhhbmRsaW5nIG9mIGh1Z2UgbW1pbyBidWZmZXJzICglZCA+PSA2NGspXG4iLCBjY2hCdWZmZXIpOwoKICAgIGlmIChNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SKQoJcmV0dXJuIE1NSU9FUlJfQ0FOTk9UV1JJVEU7CgogICAgLyogZnJlZSBwcmV2aW91cyBidWZmZXIgaWYgYWxsb2NhdGVkICovCiAgICBpZiAod20tPmluZm8uZHdGbGFncyAmIE1NSU9fQUxMT0NCVUYpIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB3bS0+aW5mby5wY2hCdWZmZXIpOwogICAgICAgIHdtLT5pbmZvLnBjaEJ1ZmZlciA9IE5VTEw7Cgl3bS0+aW5mby5kd0ZsYWdzICY9IH5NTUlPX0FMTE9DQlVGOwogICAgfQoKICAgIGlmIChwY2hCdWZmZXIpIHsKICAgICAgICB3bS0+aW5mby5wY2hCdWZmZXIgPSBwY2hCdWZmZXI7CiAgICB9IGVsc2UgaWYgKGNjaEJ1ZmZlcikgewoJaWYgKCEod20tPmluZm8ucGNoQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNjaEJ1ZmZlcikpKQoJICAgIHJldHVybiBNTUlPRVJSX09VVE9GTUVNT1JZOwoJd20tPmluZm8uZHdGbGFncyB8PSBNTUlPX0FMTE9DQlVGOwogICAgfSBlbHNlIHsKCXdtLT5pbmZvLnBjaEJ1ZmZlciA9IE5VTEw7CiAgICB9CgogICAgd20tPmluZm8uY2NoQnVmZmVyID0gY2NoQnVmZmVyOwogICAgd20tPmluZm8ucGNoTmV4dCA9IHdtLT5pbmZvLnBjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLnBjaEVuZFJlYWQgPSB3bS0+aW5mby5wY2hCdWZmZXI7CiAgICB3bS0+aW5mby5wY2hFbmRXcml0ZSA9IHdtLT5pbmZvLnBjaEJ1ZmZlciArIGNjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLmxCdWZPZmZzZXQgPSAwOwogICAgd20tPmJCdWZmZXJMb2FkZWQgPSBGQUxTRTsKCiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCU1NSU9fT3BlbiAgICAgICAJCQlbaW50ZXJuYWxdCiAqLwpITU1JTyBNTUlPX09wZW4oTFBTVFIgc3pGaWxlTmFtZSwgTU1JT0lORk8qIHJlZm1taW5mbywgRFdPUkQgZHdPcGVuRmxhZ3MsIAogICAgICAgICAgICAgICAgZW51bSBtbWlvUHJvY1R5cGUgdHlwZSkKewogICAgTFBXSU5FX01NSU8JCXdtOwogICAgTU1JT0lORk8gICAgCW1taW9pbmZvOwoKICAgIFRSQUNFKCIoJyVzJywgJXAsICUwOFgsICVkKTtcbiIsIHN6RmlsZU5hbWUsIHJlZm1taW5mbywgZHdPcGVuRmxhZ3MsIHR5cGUpOwoKICAgIGlmICghcmVmbW1pbmZvKSB7CiAgICAgICAgcmVmbW1pbmZvID0gJm1taW9pbmZvOwoKCW1taW9pbmZvLmZjY0lPUHJvYyA9IDA7CgltbWlvaW5mby5wSU9Qcm9jID0gTlVMTDsKCW1taW9pbmZvLnBjaEJ1ZmZlciA9IE5VTEw7CgltbWlvaW5mby5jY2hCdWZmZXIgPSAwOwogICAgICAgIHR5cGUgPSBNTUlPX1BST0NfMzJBOwogICAgfQoKICAgIGlmIChkd09wZW5GbGFncyAmIChNTUlPX1BBUlNFfE1NSU9fRVhJU1QpKSB7CgljaGFyCWJ1ZmZlcltNQVhfUEFUSF07CgoJaWYgKEdldEZ1bGxQYXRoTmFtZUEoc3pGaWxlTmFtZSwgc2l6ZW9mKGJ1ZmZlciksIGJ1ZmZlciwgTlVMTCkgPj0gc2l6ZW9mKGJ1ZmZlcikpCgkgICAgcmV0dXJuIChITU1JTylGQUxTRTsKCWlmICgoZHdPcGVuRmxhZ3MgJiBNTUlPX0VYSVNUKSAmJiAoR2V0RmlsZUF0dHJpYnV0ZXNBKGJ1ZmZlcikgPT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpKQoJICAgIHJldHVybiAoSE1NSU8pRkFMU0U7CglzdHJjcHkoc3pGaWxlTmFtZSwgYnVmZmVyKTsKCXJldHVybiAoSE1NSU8pVFJVRTsKICAgIH0KCiAgICBpZiAoKHdtID0gTU1JT19DcmVhdGUoKSkgPT0gTlVMTCkKCXJldHVybiAwOwoKICAgIC8qIElmIGJvdGggcGFyYW1zIGFyZSBOVUxMLCB0aGVuIHBhcnNlIHRoZSBmaWxlIG5hbWUgaWYgYXZhaWxhYmxlICovCiAgICBpZiAocmVmbW1pbmZvLT5mY2NJT1Byb2MgPT0gMCAmJiByZWZtbWluZm8tPnBJT1Byb2MgPT0gTlVMTCkgewoJd20tPmluZm8uZmNjSU9Qcm9jID0gTU1JT19QYXJzZUV4dEEoc3pGaWxlTmFtZSk7CgkvKiBIYW5kbGUgYW55IHVuaGFuZGxlZC9lcnJvciBjYXNlLiBBc3N1bWUgRE9TIGZpbGUgKi8KCWlmICh3bS0+aW5mby5mY2NJT1Byb2MgPT0gMCkKCSAgICB3bS0+aW5mby5mY2NJT1Byb2MgPSBGT1VSQ0NfRE9TOwoJaWYgKCEod20tPmlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKHdtLT5pbmZvLmZjY0lPUHJvYykpKSB7CgkgICAgLyogSWYgbm90IGZvdW5kLCByZXRyeSB3aXRoIEZPVVJDQ19ET1MgKi8KCSAgICB3bS0+aW5mby5mY2NJT1Byb2MgPSBGT1VSQ0NfRE9TOwoJICAgIGlmICghKHdtLT5pb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZSh3bS0+aW5mby5mY2NJT1Byb2MpKSkKCQlnb3RvIGVycm9yMjsKCX0KCXdtLT5iVG1wSU9Qcm9jID0gRkFMU0U7CiAgICB9CiAgICAvKiBpZiBqdXN0IHRoZSBmb3VyIGNoYXJhY3RlciBjb2RlIGlzIHByZXNlbnQsIGxvb2sgdXAgSU8gcHJvYyAqLwogICAgZWxzZSBpZiAocmVmbW1pbmZvLT5wSU9Qcm9jID09IE5VTEwpIHsKCXdtLT5pbmZvLmZjY0lPUHJvYyA9IHJlZm1taW5mby0+ZmNjSU9Qcm9jOwoJaWYgKCEod20tPmlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKHdtLT5pbmZvLmZjY0lPUHJvYykpKSBnb3RvIGVycm9yMjsKCXdtLT5iVG1wSU9Qcm9jID0gRkFMU0U7CiAgICB9CiAgICAvKiBpZiBJTyBwcm9jIHNwZWNpZmllZCwgdXNlIGl0IGFuZCBzcGVjaWZpZWQgZm91ciBjaGFyYWN0ZXIgY29kZSAqLwogICAgZWxzZSB7Cgl3bS0+aW5mby5mY2NJT1Byb2MgPSByZWZtbWluZm8tPmZjY0lPUHJvYzsKCU1NSU9fSW5zdGFsbElPUHJvYyh3bS0+aW5mby5mY2NJT1Byb2MsIHJlZm1taW5mby0+cElPUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgTU1JT19JTlNUQUxMUFJPQywgdHlwZSk7CglpZiAoISh3bS0+aW9Qcm9jID0gTU1JT19GaW5kUHJvY05vZGUod20tPmluZm8uZmNjSU9Qcm9jKSkpIGdvdG8gZXJyb3IyOwoJYXNzZXJ0KHdtLT5pb1Byb2MtPnBJT1Byb2MgPT0gcmVmbW1pbmZvLT5wSU9Qcm9jKTsKCXdtLT5iVG1wSU9Qcm9jID0gVFJVRTsKICAgIH0KCiAgICB3bS0+YkJ1ZmZlckxvYWRlZCA9IEZBTFNFOwogICAgd20tPmlvUHJvYy0+Y291bnQrKzsKCiAgICBpZiAoZHdPcGVuRmxhZ3MgJiBNTUlPX0FMTE9DQlVGKSB7CglpZiAoKHJlZm1taW5mby0+d0Vycm9yUmV0ID0gTU1JT19TZXRCdWZmZXIod20sIE5VTEwsIE1NSU9fREVGQVVMVEJVRkZFUiwgMCkpKQoJICAgIGdvdG8gZXJyb3IxOwogICAgfSBlbHNlIGlmICh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSkgewogICAgICAgIHJlZm1taW5mby0+d0Vycm9yUmV0ID0gTU1JT19TZXRCdWZmZXIod20sIHJlZm1taW5mby0+cGNoQnVmZmVyLCByZWZtbWluZm8tPmNjaEJ1ZmZlciwgMCk7CglpZiAocmVmbW1pbmZvLT53RXJyb3JSZXQgIT0gTU1TWVNFUlJfTk9FUlJPUikKCSAgICBnb3RvIGVycm9yMTsKCXdtLT5iQnVmZmVyTG9hZGVkID0gVFJVRTsKICAgIH0gLyogZWxzZSA9PiB1bmJ1ZmZlcmVkLCB3bS0+aW5mby5wY2hCdWZmZXIgPT0gTlVMTCAqLwoKICAgIC8qIHNlZSBtbWlvRG9zSU9Qcm9jIGZvciB0aGF0IG9uZSAqLwogICAgd20tPmluZm8uYWR3SW5mb1swXSA9IHJlZm1taW5mby0+YWR3SW5mb1swXTsKICAgIHdtLT5pbmZvLmR3RmxhZ3MgPSBkd09wZW5GbGFnczsKCiAgICAvKiBjYWxsIElPIHByb2MgdG8gYWN0dWFsbHkgb3BlbiBmaWxlICovCiAgICByZWZtbWluZm8tPndFcnJvclJldCA9IHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX09QRU4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSlzekZpbGVOYW1lLCAwLCBNTUlPX1BST0NfMzJBKTsKCiAgICAvKiBncmFiIGZpbGUgc2l6ZSwgd2hlbiBwb3NzaWJsZSAqLwogICAgd20tPmR3RmlsZVNpemUgPSBHZXRGaWxlU2l6ZSgoSEFORExFKXdtLT5pbmZvLmFkd0luZm9bMF0sIE5VTEwpOwoKICAgIGlmIChyZWZtbWluZm8tPndFcnJvclJldCA9PSAwKQoJcmV0dXJuIHdtLT5pbmZvLmhtbWlvOwogZXJyb3IxOgogICAgaWYgKHdtLT5pb1Byb2MpIHdtLT5pb1Byb2MtPmNvdW50LS07CiBlcnJvcjI6CiAgICBNTUlPX0Rlc3Ryb3kod20pOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb09wZW5XICAgICAgIAkJW1dJTk1NLkBdCiAqLwpITU1JTyBXSU5BUEkgbW1pb09wZW5XKExQV1NUUiBzekZpbGVOYW1lLCBNTUlPSU5GTyogbHBtbWlvaW5mbywKCQkgICAgICAgRFdPUkQgZHdPcGVuRmxhZ3MpCnsKICAgIEhNTUlPIAlyZXQ7CiAgICBMUFNUUglzekZuID0gTlVMTDsKCiAgICBpZiAoc3pGaWxlTmFtZSkKICAgIHsKICAgICAgICBJTlQgICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pGaWxlTmFtZSwgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwgKTsKICAgICAgICBzekZuID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKTsKICAgICAgICBpZiAoIXN6Rm4pIHJldHVybiBOVUxMOwogICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pGaWxlTmFtZSwgLTEsIHN6Rm4sIGxlbiwgTlVMTCwgTlVMTCApOwogICAgfQoKICAgIHJldCA9IE1NSU9fT3BlbihzekZuLCBscG1taW9pbmZvLCBkd09wZW5GbGFncywgTU1JT19QUk9DXzMyVyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3pGbik7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9PcGVuQSAgICAgICAJCVtXSU5NTS5AXQogKi8KSE1NSU8gV0lOQVBJIG1taW9PcGVuQShMUFNUUiBzekZpbGVOYW1lLCBNTUlPSU5GTyogbHBtbWlvaW5mbywKCQkgICAgICAgRFdPUkQgZHdPcGVuRmxhZ3MpCnsKICAgIHJldHVybiAgTU1JT19PcGVuKHN6RmlsZU5hbWUsIGxwbW1pb2luZm8sIGR3T3BlbkZsYWdzLCBNTUlPX1BST0NfMzJBKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvQ2xvc2UgICAgICAJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9DbG9zZShITU1JTyBobW1pbywgVUlOVCB1RmxhZ3MpCnsKICAgIExQV0lORV9NTUlPCXdtOwogICAgTU1SRVNVTFQgCXJlc3VsdDsKCiAgICBUUkFDRSgiKCVwLCAlMDRYKTtcbiIsIGhtbWlvLCB1RmxhZ3MpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgaWYgKChyZXN1bHQgPSBNTUlPX0ZsdXNoKHdtLCAwKSkgIT0gTU1TWVNFUlJfTk9FUlJPUikKCXJldHVybiByZXN1bHQ7CgogICAgcmVzdWx0ID0gc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fQ0xPU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHVGbGFncywgMCwgTU1JT19QUk9DXzMyQSk7CgogICAgTU1JT19TZXRCdWZmZXIod20sIE5VTEwsIDAsIDApOwoKICAgIHdtLT5pb1Byb2MtPmNvdW50LS07CgogICAgaWYgKHdtLT5iVG1wSU9Qcm9jKQoJTU1JT19JbnN0YWxsSU9Qcm9jKHdtLT5pbmZvLmZjY0lPUHJvYywgd20tPmlvUHJvYy0+cElPUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgTU1JT19SRU1PVkVQUk9DLCB3bS0+aW9Qcm9jLT50eXBlKTsKCiAgICBNTUlPX0Rlc3Ryb3kod20pOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1JlYWQJICAgICAgIAlbV0lOTU0uQF0KICovCkxPTkcgV0lOQVBJIG1taW9SZWFkKEhNTUlPIGhtbWlvLCBIUFNUUiBwY2gsIExPTkcgY2NoKQp7CiAgICBMUFdJTkVfTU1JTwl3bTsKICAgIExPTkcgCWNvdW50OwoKICAgIFRSQUNFKCIoJXAsICVwLCAlZCk7XG4iLCBobW1pbywgcGNoLCBjY2gpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gLTE7CgogICAgLyogdW5idWZmZXJlZCBjYXNlIGZpcnN0ICovCiAgICBpZiAoIXdtLT5pbmZvLnBjaEJ1ZmZlcikKCXJldHVybiBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9SRUFELCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pcGNoLCBjY2gsIE1NSU9fUFJPQ18zMkEpOwoKICAgIC8qIGZpcnN0IHRyeSBmcm9tIGN1cnJlbnQgYnVmZmVyICovCiAgICBpZiAod20tPmluZm8ucGNoTmV4dCAhPSB3bS0+aW5mby5wY2hFbmRSZWFkKSB7Cgljb3VudCA9IHdtLT5pbmZvLnBjaEVuZFJlYWQgLSB3bS0+aW5mby5wY2hOZXh0OwoJaWYgKGNvdW50ID4gY2NoIHx8IGNvdW50IDwgMCkgY291bnQgPSBjY2g7CgltZW1jcHkocGNoLCB3bS0+aW5mby5wY2hOZXh0LCBjb3VudCk7Cgl3bS0+aW5mby5wY2hOZXh0ICs9IGNvdW50OwoJcGNoICs9IGNvdW50OwoJY2NoIC09IGNvdW50OwogICAgfSBlbHNlCgljb3VudCA9IDA7CgogICAgaWYgKGNjaCAmJiAod20tPmluZm8uZmNjSU9Qcm9jICE9IEZPVVJDQ19NRU0pKSB7Cglhc3NlcnQod20tPmluZm8uY2NoQnVmZmVyKTsKCgl3aGlsZSAoY2NoKSB7CgkgICAgTE9ORyBzaXplOwoKCSAgICBzaXplID0gTU1JT19HcmFiTmV4dEJ1ZmZlcih3bSwgVFJVRSk7CgkgICAgaWYgKHNpemUgPD0gMCkgYnJlYWs7CgkgICAgaWYgKHNpemUgPiBjY2gpIHNpemUgPSBjY2g7CgkgICAgbWVtY3B5KHBjaCwgd20tPmluZm8ucGNoQnVmZmVyLCBzaXplKTsKCSAgICB3bS0+aW5mby5wY2hOZXh0ICs9IHNpemU7CgkgICAgcGNoICs9IHNpemU7CgkgICAgY2NoIC09IHNpemU7CgkgICAgY291bnQgKz0gc2l6ZTsKCX0KICAgIH0KCiAgICBUUkFDRSgiY291bnQ9JWRcbiIsIGNvdW50KTsKICAgIHJldHVybiBjb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvV3JpdGUgICAgICAJCVtXSU5NTS5AXQogKi8KTE9ORyBXSU5BUEkgbW1pb1dyaXRlKEhNTUlPIGhtbWlvLCBIUENTVFIgcGNoLCBMT05HIGNjaCkKewogICAgTFBXSU5FX01NSU8Jd207CiAgICBMT05HCWNvdW50OwoKICAgIFRSQUNFKCIoJXAsICVwLCAlZCk7XG4iLCBobW1pbywgcGNoLCBjY2gpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gLTE7CgogICAgaWYgKHdtLT5pbmZvLmNjaEJ1ZmZlcikgewoJTE9ORwlieXRlc1cgPSAwOwoKICAgICAgICBjb3VudCA9IDA7CiAgICAgICAgd2hpbGUgKGNjaCkgewogICAgICAgICAgICBpZiAod20tPmluZm8ucGNoTmV4dCAhPSB3bS0+aW5mby5wY2hFbmRXcml0ZSkgewogICAgICAgICAgICAgICAgY291bnQgPSB3bS0+aW5mby5wY2hFbmRXcml0ZSAtIHdtLT5pbmZvLnBjaE5leHQ7CiAgICAgICAgICAgICAgICBpZiAoY291bnQgPiBjY2ggfHwgY291bnQgPCAwKSBjb3VudCA9IGNjaDsKICAgICAgICAgICAgICAgIG1lbWNweSh3bS0+aW5mby5wY2hOZXh0LCBwY2gsIGNvdW50KTsKICAgICAgICAgICAgICAgIHdtLT5pbmZvLnBjaE5leHQgKz0gY291bnQ7CiAgICAgICAgICAgICAgICBwY2ggKz0gY291bnQ7CiAgICAgICAgICAgICAgICBjY2ggLT0gY291bnQ7CiAgICAgICAgICAgICAgICBieXRlc1cgKz0gY291bnQ7CiAgICAgICAgICAgICAgICB3bS0+aW5mby5kd0ZsYWdzIHw9IE1NSU9fRElSVFk7CgkgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSkgewogICAgICAgICAgICAgICAgICAgIGlmICh3bS0+aW5mby5hZHdJbmZvWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZyb20gd2hlcmUgd291bGQgd2UgZ2V0IHRoZSBtZW1vcnkgaGFuZGxlPyAqLwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgibWVtb3J5IGZpbGUgZXhwYW5zaW9uIG5vdCBpbXBsZW1lbnRlZCFcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkgICAgfSBlbHNlIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAod20tPmluZm8ucGNoTmV4dCA9PSB3bS0+aW5mby5wY2hFbmRXcml0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTU1JT19GbHVzaCh3bSwgTU1JT19FTVBUWUJVRik7CiAgICAgICAgICAgICAgICBNTUlPX0dyYWJOZXh0QnVmZmVyKHdtLCBGQUxTRSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBicmVhazsKICAgICAgICB9Cgljb3VudCA9IGJ5dGVzVzsKICAgIH0gZWxzZSB7Cgljb3VudCA9IHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1dSSVRFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKXBjaCwgY2NoLCBNTUlPX1BST0NfMzJBKTsKCXdtLT5pbmZvLmxCdWZPZmZzZXQgPSB3bS0+aW5mby5sRGlza09mZnNldDsKICAgIH0KCiAgICBUUkFDRSgiYnl0ZXMgd3JpdHRlbj0lZFxuIiwgY291bnQpOwogICAgcmV0dXJuIGNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TZWVrCQlbV0lOTU0uQF0KICovCkxPTkcgV0lOQVBJIG1taW9TZWVrKEhNTUlPIGhtbWlvLCBMT05HIGxPZmZzZXQsIElOVCBpT3JpZ2luKQp7CiAgICBMUFdJTkVfTU1JTwl3bTsKICAgIExPTkcgCW9mZnNldDsKCiAgICBUUkFDRSgiKCVwLCAlMDhYLCAlZCk7XG4iLCBobW1pbywgbE9mZnNldCwgaU9yaWdpbik7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICAvKiBub3QgYnVmZmVyZWQsIGRpcmVjdCBzZWVrIG9uIGZpbGUgKi8KICAgIGlmICghd20tPmluZm8ucGNoQnVmZmVyKQoJcmV0dXJuIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbE9mZnNldCwgaU9yaWdpbiwgTU1JT19QUk9DXzMyQSk7CgogICAgc3dpdGNoIChpT3JpZ2luKSB7CiAgICBjYXNlIFNFRUtfU0VUOgoJb2Zmc2V0ID0gbE9mZnNldDsKCWJyZWFrOwogICAgY2FzZSBTRUVLX0NVUjoKCW9mZnNldCA9IHdtLT5pbmZvLmxCdWZPZmZzZXQgKyAod20tPmluZm8ucGNoTmV4dCAtIHdtLT5pbmZvLnBjaEJ1ZmZlcikgKyBsT2Zmc2V0OwoJYnJlYWs7CiAgICBjYXNlIFNFRUtfRU5EOgoJb2Zmc2V0ID0gKCh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSk/IHdtLT5pbmZvLmNjaEJ1ZmZlciA6IHdtLT5kd0ZpbGVTaXplKSAtIGxPZmZzZXQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKG9mZnNldCAmJiBvZmZzZXQgPj0gd20tPmR3RmlsZVNpemUgJiYgd20tPmluZm8uZmNjSU9Qcm9jICE9IEZPVVJDQ19NRU0pIHsKICAgICAgICAvKiBzaG91bGQgY2hlY2sgdGhhdCB3cml0ZSBtb2RlIGV4aXN0cyAqLwogICAgICAgIGlmIChNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgd20tPmluZm8ubEJ1Zk9mZnNldCA9IG9mZnNldDsKICAgICAgICB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgICAgIHdtLT5pbmZvLnBjaEVuZFdyaXRlID0gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyOwogICAgICAgIGlmICgod20tPmluZm8uZHdGbGFncyAmIE1NSU9fUldNT0RFKSA9PSBNTUlPX1JFQUQpIHsKICAgICAgICAgICAgd20tPmluZm8ubERpc2tPZmZzZXQgPSB3bS0+ZHdGaWxlU2l6ZTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKCh3bS0+aW5mby5jY2hCdWZmZXIgPiAwKSAmJgoJKChvZmZzZXQgPCB3bS0+aW5mby5sQnVmT2Zmc2V0KSB8fAoJIChvZmZzZXQgPj0gd20tPmluZm8ubEJ1Zk9mZnNldCArIHdtLT5pbmZvLmNjaEJ1ZmZlcikgfHwKCSAhd20tPmJCdWZmZXJMb2FkZWQpKSB7CiAgICAgICAgLyogc3RheSBpbiBzYW1lIGJ1ZmZlciA/ICovCiAgICAgICAgLyogc29tZSBtZW1vcnkgbWFwcGVkIGJ1ZmZlcnMgYXJlIGRlZmluZWQgd2l0aCAtMSBhcyBhIHNpemUgKi8KCgkvKiBjb25kaXRpb24gdG8gY2hhbmdlIGJ1ZmZlciAqLwoJaWYgKCh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSkgfHwKCSAgICBNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SIHx8CgkgICAgLyogdGhpcyBhbHNvIHNldHMgdGhlIHdtLT5pbmZvLmxEaXNrT2Zmc2V0IGZpZWxkICovCgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgIChvZmZzZXQgLyB3bS0+aW5mby5jY2hCdWZmZXIpICogd20tPmluZm8uY2NoQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgU0VFS19TRVQsIE1NSU9fUFJPQ18zMkEpID09IC0xKQoJICAgIHJldHVybiAtMTsKCU1NSU9fR3JhYk5leHRCdWZmZXIod20sIFRSVUUpOwogICAgfQoKICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hCdWZmZXIgKyAob2Zmc2V0IC0gd20tPmluZm8ubEJ1Zk9mZnNldCk7CgogICAgVFJBQ0UoIj0+ICVkXG4iLCBvZmZzZXQpOwogICAgcmV0dXJuIG9mZnNldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvR2V0SW5mbwkgICAgICAgCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9HZXRJbmZvKEhNTUlPIGhtbWlvLCBNTUlPSU5GTyogbHBtbWlvaW5mbywgVUlOVCB1RmxhZ3MpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKCiAgICBUUkFDRSgiKCVwLCVwLDB4JTA4eClcbiIsaG1taW8sbHBtbWlvaW5mbyx1RmxhZ3MpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgbWVtY3B5KGxwbW1pb2luZm8sICZ3bS0+aW5mbywgc2l6ZW9mKE1NSU9JTkZPKSk7CiAgICAvKiBkb24ndCBleHBvc2UgMTYgYml0IGlvcHJvYzpzICovCiAgICBpZiAod20tPmlvUHJvYy0+dHlwZSAhPSBNTUlPX1BST0NfMTYpCiAgICAgICAgbHBtbWlvaW5mby0+cElPUHJvYyA9IHdtLT5pb1Byb2MtPnBJT1Byb2M7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1NldEluZm8gICAgCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvU2V0SW5mbyhITU1JTyBobW1pbywgY29uc3QgTU1JT0lORk8qIGxwbW1pb2luZm8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwlcCwweCUwOHgpXG4iLGhtbWlvLGxwbW1pb2luZm8sdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIC8qIGNoZWNrIHBvaW50ZXJzIGNvaGVyZW5jZSAqLwogICAgaWYgKGxwbW1pb2luZm8tPnBjaE5leHQgPCB3bS0+aW5mby5wY2hCdWZmZXIgfHwKCWxwbW1pb2luZm8tPnBjaE5leHQgPiB3bS0+aW5mby5wY2hCdWZmZXIgKyB3bS0+aW5mby5jY2hCdWZmZXIgfHwKCWxwbW1pb2luZm8tPnBjaEVuZFJlYWQgPCB3bS0+aW5mby5wY2hCdWZmZXIgfHwKCWxwbW1pb2luZm8tPnBjaEVuZFJlYWQgPiB3bS0+aW5mby5wY2hCdWZmZXIgKyB3bS0+aW5mby5jY2hCdWZmZXIgfHwKCWxwbW1pb2luZm8tPnBjaEVuZFdyaXRlIDwgd20tPmluZm8ucGNoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRXcml0ZSA+IHdtLT5pbmZvLnBjaEJ1ZmZlciArIHdtLT5pbmZvLmNjaEJ1ZmZlcikKCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIHdtLT5pbmZvLnBjaE5leHQgPSBscG1taW9pbmZvLT5wY2hOZXh0OwogICAgd20tPmluZm8ucGNoRW5kUmVhZCA9IGxwbW1pb2luZm8tPnBjaEVuZFJlYWQ7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIAkJCQltbWlvU2V0QnVmZmVyCQlbV0lOTU0uQF0KKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9TZXRCdWZmZXIoSE1NSU8gaG1taW8sIExQU1RSIHBjaEJ1ZmZlciwgTE9ORyBjY2hCdWZmZXIsIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIihobW1pbz0lcCwgcGNoQnVmPSVwLCBjY2hCdWY9JWQsIHVGbGFncz0lIzA4eClcbiIsCgkgIGhtbWlvLCBwY2hCdWZmZXIsIGNjaEJ1ZmZlciwgdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIHJldHVybiBNTUlPX1NldEJ1ZmZlcih3bSwgcGNoQnVmZmVyLCBjY2hCdWZmZXIsIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0ZsdXNoICAgICAgCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvRmx1c2goSE1NSU8gaG1taW8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwgJTA0WClcbiIsIGhtbWlvLCB1RmxhZ3MpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgcmV0dXJuIE1NSU9fRmx1c2god20sIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0FkdmFuY2UgICAgICAJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb0FkdmFuY2UoSE1NSU8gaG1taW8sIE1NSU9JTkZPKiBscG1taW9pbmZvLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCJobW1pbz0lcCwgbHBtbWlvaW5mbz0lcCwgdUZsYWdzPSUwNFhcbiIsIGhtbWlvLCBscG1taW9pbmZvLCB1RmxhZ3MpOwoKICAgIC8qIE5PVEU6IG1taW9BZHZhbmNlMTYgaGVhdmlseSByZWxpZXMgb24gcGFyYW1ldGVycyBmcm9tIGxwbW1pb2luZm8gd2UncmUgdXNpbmcKICAgICAqIGhlcmUuIGJlIHN1cmUgaWYgeW91IGNoYW5nZSBzb21ldGhpbmcgaGVyZSB0byBjaGVjayBtbWlvQWR2YW5jZTE2IGFzIHdlbGwKICAgICAqLwogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICBpZiAoIXdtLT5pbmZvLmNjaEJ1ZmZlcikKCXJldHVybiBNTUlPRVJSX1VOQlVGRkVSRUQ7CgogICAgaWYgKHVGbGFncyAhPSBNTUlPX1JFQUQgJiYgdUZsYWdzICE9IE1NSU9fV1JJVEUpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxQQVJBTTsKCiAgICBpZiAodUZsYWdzID09IE1NSU9fV1JJVEUgJiYgKGxwbW1pb2luZm8tPmR3RmxhZ3MgJiBNTUlPX0RJUlRZKSkKICAgIHsKICAgICAgICBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9TRUVLLCAKICAgICAgICAgICAgICAgICAgICAgbHBtbWlvaW5mby0+bEJ1Zk9mZnNldCwgU0VFS19TRVQsIE1NSU9fUFJPQ18zMkEpOwogICAgICAgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1dSSVRFLCAKICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSlscG1taW9pbmZvLT5wY2hCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgIGxwbW1pb2luZm8tPnBjaE5leHQgLSBscG1taW9pbmZvLT5wY2hCdWZmZXIsIE1NSU9fUFJPQ18zMkEpOwogICAgICAgIGxwbW1pb2luZm8tPmR3RmxhZ3MgJj0gfk1NSU9fRElSVFk7CiAgICB9CiAgICBpZiAoTU1JT19GbHVzaCh3bSwgMCkgIT0gTU1TWVNFUlJfTk9FUlJPUikKCXJldHVybiBNTUlPRVJSX0NBTk5PVFdSSVRFOwoKICAgIGlmIChscG1taW9pbmZvKSB7Cgl3bS0+ZHdGaWxlU2l6ZSA9IG1heCh3bS0+ZHdGaWxlU2l6ZSwgbHBtbWlvaW5mby0+bEJ1Zk9mZnNldCArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChscG1taW9pbmZvLT5wY2hOZXh0IC0gbHBtbWlvaW5mby0+cGNoQnVmZmVyKSk7CiAgICB9CiAgICBNTUlPX0dyYWJOZXh0QnVmZmVyKHdtLCB1RmxhZ3MgPT0gTU1JT19SRUFEKTsKCiAgICBpZiAobHBtbWlvaW5mbykgewoJbHBtbWlvaW5mby0+cGNoTmV4dCA9IGxwbW1pb2luZm8tPnBjaEJ1ZmZlcjsKCWxwbW1pb2luZm8tPnBjaEVuZFJlYWQgID0gbHBtbWlvaW5mby0+cGNoQnVmZmVyICsKCSAgICAod20tPmluZm8ucGNoRW5kUmVhZCAtIHdtLT5pbmZvLnBjaEJ1ZmZlcik7CglscG1taW9pbmZvLT5wY2hFbmRXcml0ZSA9IGxwbW1pb2luZm8tPnBjaEJ1ZmZlciArCgkgICAgKHdtLT5pbmZvLnBjaEVuZFdyaXRlIC0gd20tPmluZm8ucGNoQnVmZmVyKTsKCWxwbW1pb2luZm8tPmxEaXNrT2Zmc2V0ID0gd20tPmluZm8ubERpc2tPZmZzZXQ7CglscG1taW9pbmZvLT5sQnVmT2Zmc2V0ID0gd20tPmluZm8ubEJ1Zk9mZnNldDsKICAgIH0KICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TdHJpbmdUb0ZPVVJDQ0EJW1dJTk1NLkBdCiAqLwpGT1VSQ0MgV0lOQVBJIG1taW9TdHJpbmdUb0ZPVVJDQ0EoTFBDU1RSIHN6LCBVSU5UIHVGbGFncykKewogICAgQ0hBUiBjY1s0XTsKICAgIGludCBpID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgNCAmJiBzeltpXTsgaSsrKSB7CglpZiAodUZsYWdzICYgTU1JT19UT1VQUEVSKSB7CgkgICAgY2NbaV0gPSB0b3VwcGVyKHN6W2ldKTsKCX0gZWxzZSB7CgkgICAgY2NbaV0gPSBzeltpXTsKCX0KICAgIH0KCiAgICAvKiBQYWQgd2l0aCBzcGFjZXMgKi8KICAgIHdoaWxlIChpIDwgNCkgY2NbaSsrXSA9ICcgJzsKCiAgICBUUkFDRSgiR290ICclLjRzJ1xuIixjYyk7CiAgICByZXR1cm4gbW1pb0ZPVVJDQyhjY1swXSxjY1sxXSxjY1syXSxjY1szXSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1N0cmluZ1RvRk9VUkNDVwlbV0lOTU0uQF0KICovCkZPVVJDQyBXSU5BUEkgbW1pb1N0cmluZ1RvRk9VUkNDVyhMUENXU1RSIHN6LCBVSU5UIHVGbGFncykKewogICAgY2hhcglzekFbNF07CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZSggQ1BfQUNQLCAwLCBzeiwgNCwgc3pBLCBzaXplb2Yoc3pBKSwgTlVMTCwgTlVMTCApOwogICAgcmV0dXJuIG1taW9TdHJpbmdUb0ZPVVJDQ0Eoc3pBLHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0luc3RhbGxJT1Byb2NBCSAgIFtXSU5NTS5AXQogKi8KTFBNTUlPUFJPQyBXSU5BUEkgbW1pb0luc3RhbGxJT1Byb2NBKEZPVVJDQyBmY2NJT1Byb2MsCgkJCQkgICAgIExQTU1JT1BST0MgcElPUHJvYywgRFdPUkQgZHdGbGFncykKewogICAgcmV0dXJuIE1NSU9fSW5zdGFsbElPUHJvYyhmY2NJT1Byb2MsIHBJT1Byb2MsIGR3RmxhZ3MsIE1NSU9fUFJPQ18zMkEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9JbnN0YWxsSU9Qcm9jVwkgICBbV0lOTU0uQF0KICovCkxQTU1JT1BST0MgV0lOQVBJIG1taW9JbnN0YWxsSU9Qcm9jVyhGT1VSQ0MgZmNjSU9Qcm9jLAoJCQkJICAgICBMUE1NSU9QUk9DIHBJT1Byb2MsIERXT1JEIGR3RmxhZ3MpCnsKICAgIHJldHVybiBNTUlPX0luc3RhbGxJT1Byb2MoZmNjSU9Qcm9jLCBwSU9Qcm9jLCBkd0ZsYWdzLCBNTUlPX1BST0NfMzJXKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTU1JT19TZW5kTWVzc2FnZQogKgogKgogKi8KTFJFU1VMVCAgICAgICAgIE1NSU9fU2VuZE1lc3NhZ2UoSE1NSU8gaG1taW8sIFVJTlQgdU1lc3NhZ2UsIExQQVJBTSBsUGFyYW0xLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBBUkFNIGxQYXJhbTIsIGVudW0gbW1pb1Byb2NUeXBlIHR5cGUpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKCiAgICBUUkFDRSgiKCVwLCAldSwgJWxkLCAlbGQsICVkKVxuIiwgaG1taW8sIHVNZXNzYWdlLCBsUGFyYW0xLCBsUGFyYW0yLCB0eXBlKTsKCiAgICBpZiAodU1lc3NhZ2UgPCBNTUlPTV9VU0VSKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMUEFSQU07CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICByZXR1cm4gc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgdU1lc3NhZ2UsIGxQYXJhbTEsIGxQYXJhbTIsIHR5cGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TZW5kTWVzc2FnZQkJW1dJTk1NLkBdCiAqLwpMUkVTVUxUIFdJTkFQSSBtbWlvU2VuZE1lc3NhZ2UoSE1NSU8gaG1taW8sIFVJTlQgdU1lc3NhZ2UsCgkJCSAgICAgICBMUEFSQU0gbFBhcmFtMSwgTFBBUkFNIGxQYXJhbTIpCnsKICAgIHJldHVybiBNTUlPX1NlbmRNZXNzYWdlKGhtbWlvLCB1TWVzc2FnZSwgbFBhcmFtMSwgbFBhcmFtMiwgTU1JT19QUk9DXzMyQSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0Rlc2NlbmQgICAgICAgICAJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb0Rlc2NlbmQoSE1NSU8gaG1taW8sIExQTU1DS0lORk8gbHBjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1NQ0tJTkZPKiBscGNrUGFyZW50LCBVSU5UIHVGbGFncykKewogICAgRFdPUkQJCWR3T2xkUG9zOwogICAgRk9VUkNDCQlzcmNoQ2tJZDsKICAgIEZPVVJDQwkJc3JjaFR5cGU7CgogICAgVFJBQ0UoIiglcCwgJXAsICVwLCAlMDRYKTtcbiIsIGhtbWlvLCBscGNrLCBscGNrUGFyZW50LCB1RmxhZ3MpOwoKICAgIGlmIChscGNrID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxQQVJBTTsKCiAgICBkd09sZFBvcyA9IG1taW9TZWVrKGhtbWlvLCAwLCBTRUVLX0NVUik7CiAgICBUUkFDRSgiZHdPbGRQb3M9JWRcbiIsIGR3T2xkUG9zKTsKCiAgICBpZiAobHBja1BhcmVudCAhPSBOVUxMKSB7CglUUkFDRSgic2VlayBpbnNpZGUgcGFyZW50IGF0ICVkICFcbiIsIGxwY2tQYXJlbnQtPmR3RGF0YU9mZnNldCk7CgkvKiBFUFA6IHdhcyBkd09sZFBvcyA9IG1taW9TZWVrKGhtbWlvLGxwY2tQYXJlbnQtPmR3RGF0YU9mZnNldCxTRUVLX1NFVCk7ICovCglpZiAoZHdPbGRQb3MgPCBscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQgfHwKCSAgICBkd09sZFBvcyA+PSBscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQgKyBscGNrUGFyZW50LT5ja3NpemUpIHsKCSAgICBXQVJOKCJvdXRzaWRlIHBhcmVudCBjaHVua1xuIik7CgkgICAgcmV0dXJuIE1NSU9FUlJfQ0hVTktOT1RGT1VORDsKCX0KICAgIH0KCiAgICAvKiBUaGUgU0RLIGRvY3Ugc2F5cyAnY2tpZCcgaXMgdXNlZCBmb3IgYWxsIGNhc2VzLiBSZWFsIFdvcmxkCiAgICAgKiBleGFtcGxlcyBkaXNhZ3JlZSAtTWFyY3VzLDk5MDIxNi4KICAgICAqLwoKICAgIHNyY2hDa0lkID0gMDsKICAgIHNyY2hUeXBlID0gMDsKCiAgICAvKiBmaW5kX2NodW5rIGxvb2tzIGZvciAnY2tpZCcgKi8KICAgIGlmICh1RmxhZ3MgJiBNTUlPX0ZJTkRDSFVOSykKCXNyY2hDa0lkID0gbHBjay0+Y2tpZDsKCiAgICAvKiBmaW5kX3JpZmYgYW5kIGZpbmRfbGlzdCBsb29rIGZvciAnZmNjVHlwZScgKi8KICAgIGlmICh1RmxhZ3MgJiBNTUlPX0ZJTkRMSVNUKQogICAgewoJc3JjaENrSWQgPSBGT1VSQ0NfTElTVDsKICAgICAgICBzcmNoVHlwZSA9IGxwY2stPmZjY1R5cGU7CiAgICB9CgogICAgaWYgKHVGbGFncyAmIE1NSU9fRklORFJJRkYpCiAgICB7CglzcmNoQ2tJZCA9IEZPVVJDQ19SSUZGOwogICAgICAgIHNyY2hUeXBlID0gbHBjay0+ZmNjVHlwZTsKICAgIH0KCiAgICBUUkFDRSgic2VhcmNoaW5nIGZvciAlNC40cy4lNC40c1xuIiwKICAgICAgICAgIChMUENTVFIpJnNyY2hDa0lkLCBzcmNoVHlwZSA/IChMUENTVFIpJnNyY2hUeXBlIDogImFueSIpOwoKICAgIHdoaWxlIChUUlVFKQogICAgewogICAgICAgIExPTkcgaXg7CgogICAgICAgIGl4ID0gbW1pb1JlYWQoaG1taW8sIChMUFNUUilscGNrLCAzICogc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgaWYgKGl4IDwgMipzaXplb2YoRFdPUkQpKQogICAgICAgIHsKICAgICAgICAgICAgbW1pb1NlZWsoaG1taW8sIGR3T2xkUG9zLCBTRUVLX1NFVCk7CiAgICAgICAgICAgIFdBUk4oInJldHVybiBDaHVua05vdEZvdW5kXG4iKTsKICAgICAgICAgICAgcmV0dXJuIE1NSU9FUlJfQ0hVTktOT1RGT1VORDsKICAgICAgICB9CgogICAgICAgIGxwY2stPmR3RGF0YU9mZnNldCA9IGR3T2xkUG9zICsgMiAqIHNpemVvZihEV09SRCk7CiAgICAgICAgVFJBQ0UoImNraWQ9JTQuNHMgZmNjPSU0LjRzIGNrc2l6ZT0lMDhYICFcbiIsCiAgICAgICAgICAgICAgKExQQ1NUUikmbHBjay0+Y2tpZCwKICAgICAgICAgICAgICBzcmNoVHlwZSA/IChMUENTVFIpJmxwY2stPmZjY1R5cGU6IjxuYT4iLAogICAgICAgICAgICAgIGxwY2stPmNrc2l6ZSk7CiAgICAgICAgaWYgKCAoIXNyY2hDa0lkIHx8IChzcmNoQ2tJZCA9PSBscGNrLT5ja2lkKSkgJiYKICAgICAgICAgICAgICghc3JjaFR5cGUgfHwgKHNyY2hUeXBlID09IGxwY2stPmZjY1R5cGUpKSApCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkd09sZFBvcyA9IGxwY2stPmR3RGF0YU9mZnNldCArICgobHBjay0+Y2tzaXplICsgMSkgJiB+MSk7CiAgICAgICAgbW1pb1NlZWsoaG1taW8sIGR3T2xkUG9zLCBTRUVLX1NFVCk7CiAgICB9CgogICAgbHBjay0+ZHdGbGFncyA9IDA7CiAgICAvKiBJZiB3ZSB3ZXJlIGxvb2tpbmcgZm9yIFJJRkYvTElTVCBjaHVua3MsIHRoZSBmaW5hbCBmaWxlIHBvc2l0aW9uCiAgICAgKiBpcyBhZnRlciB0aGUgY2h1bmtpZC4gSWYgd2Ugd2VyZSBqdXN0IGxvb2tpbmcgZm9yIHRoZSBjaHVuawogICAgICogaXQgaXMgYWZ0ZXIgdGhlIGNrc2l6ZS4gU28gYWRkIDQgaW4gUklGRi9MSVNUIGNhc2UuCiAgICAgKi8KICAgIGlmIChscGNrLT5ja2lkID09IEZPVVJDQ19SSUZGIHx8IGxwY2stPmNraWQgPT0gRk9VUkNDX0xJU1QpCgltbWlvU2VlayhobW1pbywgbHBjay0+ZHdEYXRhT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpOwogICAgZWxzZQoJbW1pb1NlZWsoaG1taW8sIGxwY2stPmR3RGF0YU9mZnNldCwgU0VFS19TRVQpOwogICAgVFJBQ0UoImxwY2s6IGNraWQ9JS40cywgY2tzaXplPSVkLCBkd0RhdGFPZmZzZXQ9JWQgZmNjVHlwZT0lMDhYICglLjRzKSFcbiIsCgkgIChMUFNUUikmbHBjay0+Y2tpZCwgbHBjay0+Y2tzaXplLCBscGNrLT5kd0RhdGFPZmZzZXQsCgkgIGxwY2stPmZjY1R5cGUsIHNyY2hUeXBlPyhMUFNUUikmbHBjay0+ZmNjVHlwZToiIik7CiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvQXNjZW5kICAgICAJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9Bc2NlbmQoSE1NSU8gaG1taW8sIExQTU1DS0lORk8gbHBjaywgVUlOVCB1RmxhZ3MpCnsKICAgIFRSQUNFKCIoJXAsICVwLCAlMDRYKTtcbiIsIGhtbWlvLCBscGNrLCB1RmxhZ3MpOwoKICAgIGlmIChscGNrLT5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewoJRFdPUkQJZHdPbGRQb3MsIGR3TmV3U2l6ZTsKCglUUkFDRSgiQ2h1bmsgaXMgZGlydHksIGNoZWNraW5nIGlmIGNodW5rJ3Mgc2l6ZSBpcyBjb3JyZWN0XG4iKTsKCWR3T2xkUG9zID0gbW1pb1NlZWsoaG1taW8sIDAsIFNFRUtfQ1VSKTsKCVRSQUNFKCJkd09sZFBvcz0lZCBscGNrLT5kd0RhdGFPZmZzZXQgPSAlZFxuIiwgZHdPbGRQb3MsIGxwY2stPmR3RGF0YU9mZnNldCk7Cglkd05ld1NpemUgPSBkd09sZFBvcyAtIGxwY2stPmR3RGF0YU9mZnNldDsKCWlmIChkd05ld1NpemUgIT0gbHBjay0+Y2tzaXplKSB7CgkgICAgVFJBQ0UoIk5vcGU6IGxwY2stPmNrc2l6ZT0lZCBkd05ld1NpemU9JWRcbiIsIGxwY2stPmNrc2l6ZSwgZHdOZXdTaXplKTsKCSAgICBscGNrLT5ja3NpemUgPSBkd05ld1NpemU7CgoJICAgIC8qIHBhZCBvZGQgc2l6ZSB3aXRoIDAgKi8KCSAgICBpZiAoZHdOZXdTaXplICYgMSkgewoJCWNoYXIgY2ggPSAwOwoJCW1taW9Xcml0ZShobW1pbywgJmNoLCAxKTsKCSAgICB9CgkgICAgbW1pb1NlZWsoaG1taW8sIGxwY2stPmR3RGF0YU9mZnNldCAtIHNpemVvZihEV09SRCksIFNFRUtfU0VUKTsKCSAgICBtbWlvV3JpdGUoaG1taW8sIChMUFNUUikmZHdOZXdTaXplLCBzaXplb2YoRFdPUkQpKTsKCX0KCWxwY2stPmR3RmxhZ3MgPSAwOwogICAgfQoKICAgIG1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQgKyAoKGxwY2stPmNrc2l6ZSArIDEpICYgfjEpLCBTRUVLX1NFVCk7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQltbWlvQ3JlYXRlQ2h1bmsJCQkJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb0NyZWF0ZUNodW5rKEhNTUlPIGhtbWlvLCBNTUNLSU5GTyogbHBjaywgVUlOVCB1RmxhZ3MpCnsKICAgIERXT1JECWR3T2xkUG9zOwogICAgTE9ORyAJc2l6ZTsKICAgIExPTkcgCWl4OwoKICAgIFRSQUNFKCIoJXAsICVwLCAlMDRYKTtcbiIsIGhtbWlvLCBscGNrLCB1RmxhZ3MpOwoKICAgIGR3T2xkUG9zID0gbW1pb1NlZWsoaG1taW8sIDAsIFNFRUtfQ1VSKTsKICAgIFRSQUNFKCJkd09sZFBvcz0lZFxuIiwgZHdPbGRQb3MpOwoKICAgIGlmICh1RmxhZ3MgPT0gTU1JT19DUkVBVEVMSVNUKQoJbHBjay0+Y2tpZCA9IEZPVVJDQ19MSVNUOwogICAgZWxzZSBpZiAodUZsYWdzID09IE1NSU9fQ1JFQVRFUklGRikKCWxwY2stPmNraWQgPSBGT1VSQ0NfUklGRjsKCiAgICBUUkFDRSgiY2tpZD0lLjRzXG4iLCAoTFBTVFIpJmxwY2stPmNraWQpOwoKICAgIHNpemUgPSAyICogc2l6ZW9mKERXT1JEKTsKICAgIGxwY2stPmR3RGF0YU9mZnNldCA9IGR3T2xkUG9zICsgc2l6ZTsKCiAgICBpZiAobHBjay0+Y2tpZCA9PSBGT1VSQ0NfUklGRiB8fCBscGNrLT5ja2lkID09IEZPVVJDQ19MSVNUKQoJc2l6ZSArPSBzaXplb2YoRFdPUkQpOwogICAgbHBjay0+ZHdGbGFncyA9IE1NSU9fRElSVFk7CgogICAgaXggPSBtbWlvV3JpdGUoaG1taW8sIChMUFNUUilscGNrLCBzaXplKTsKICAgIFRSQUNFKCJhZnRlciBtbWlvV3JpdGUgaXggPSAlZCByZXEgPSAlZCwgZXJybm8gPSAlZFxuIiwgaXgsIHNpemUsIGVycm5vKTsKICAgIGlmIChpeCA8IHNpemUpIHsKCW1taW9TZWVrKGhtbWlvLCBkd09sZFBvcywgU0VFS19TRVQpOwoJV0FSTigicmV0dXJuIENhbm5vdFdyaXRlXG4iKTsKCXJldHVybiBNTUlPRVJSX0NBTk5PVFdSSVRFOwogICAgfQoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9SZW5hbWVBICAgIAkJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9SZW5hbWVBKExQQ1NUUiBzekZpbGVOYW1lLCBMUENTVFIgc3pOZXdGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1NSU9JTkZPKiBscG1taW9pbmZvLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCogIGlvUHJvYyA9IE5VTEw7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCAgIHRtcDsKICAgIEZPVVJDQyAgICAgICAgICAgICAgZmNjOwoKICAgIFRSQUNFKCIoJyVzJywgJyVzJywgJXAsICUwOFgpO1xuIiwKCSAgZGVidWdzdHJfYShzekZpbGVOYW1lKSwgZGVidWdzdHJfYShzek5ld0ZpbGVOYW1lKSwgbHBtbWlvaW5mbywgZHdGbGFncyk7CgogICAgLyogSWYgYm90aCBwYXJhbXMgYXJlIE5VTEwsIHRoZW4gcGFyc2UgdGhlIGZpbGUgbmFtZSAqLwogICAgaWYgKGxwbW1pb2luZm8gJiYgbHBtbWlvaW5mby0+ZmNjSU9Qcm9jID09IDAgJiYgbHBtbWlvaW5mby0+cElPUHJvYyA9PSBOVUxMKQogICAgewoJZmNjID0gTU1JT19QYXJzZUV4dEEoc3pGaWxlTmFtZSk7CiAgICAgICAgaWYgKGZjYykgaW9Qcm9jID0gTU1JT19GaW5kUHJvY05vZGUoZmNjKTsKICAgIH0KCiAgICAvKiBIYW5kbGUgYW55IHVuaGFuZGxlZC9lcnJvciBjYXNlIGZyb20gYWJvdmUuIEFzc3VtZSBET1MgZmlsZSAqLwogICAgaWYgKCFscG1taW9pbmZvIHx8IChscG1taW9pbmZvLT5mY2NJT1Byb2MgPT0gMCAmJiBscG1taW9pbmZvLT5wSU9Qcm9jID09IE5VTEwgJiYgaW9Qcm9jID09IE5VTEwpKQoJaW9Qcm9jID0gTU1JT19GaW5kUHJvY05vZGUoRk9VUkNDX0RPUyk7CiAgICAvKiBpZiBqdXN0IHRoZSBmb3VyIGNoYXJhY3RlciBjb2RlIGlzIHByZXNlbnQsIGxvb2sgdXAgSU8gcHJvYyAqLwogICAgZWxzZSBpZiAobHBtbWlvaW5mby0+cElPUHJvYyA9PSBOVUxMKQogICAgICAgIGlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKGxwbW1pb2luZm8tPmZjY0lPUHJvYyk7CiAgICBlbHNlIC8qIHVzZSByZWxldmFudCBpb1Byb2MgKi8KICAgIHsKICAgICAgICBpb1Byb2MgPSAmdG1wOwogICAgICAgIHRtcC5mb3VyQ0MgPSBscG1taW9pbmZvLT5mY2NJT1Byb2M7CiAgICAgICAgdG1wLnBJT1Byb2MgPSBscG1taW9pbmZvLT5wSU9Qcm9jOwogICAgICAgIHRtcC50eXBlID0gTU1JT19QUk9DXzMyQTsKICAgICAgICB0bXAuY291bnQgPSAxOwogICAgfQoKICAgIC8qIEZJWE1FOiBzaG91bGQgd2UgYWN0dWFsbHkgcGFzcyBscG1taW9pbmZvIGRvd24gdGhlIGRyYWluID8/PwogICAgICogb3IgbWFrZSBhIGNvcHkgb2YgaXQgYmVjYXVzZSBpdCdzIGNvbnN0ID8/PwogICAgICovCiAgICByZXR1cm4gc2VuZF9tZXNzYWdlKGlvUHJvYywgKE1NSU9JTkZPKilscG1taW9pbmZvLCBNTUlPTV9SRU5BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pc3pGaWxlTmFtZSwgKExQQVJBTSlzek5ld0ZpbGVOYW1lLCBNTUlPX1BST0NfMzJBKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvUmVuYW1lVyAgICAJCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvUmVuYW1lVyhMUENXU1RSIHN6RmlsZU5hbWUsIExQQ1dTVFIgc3pOZXdGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1NSU9JTkZPKiBscG1taW9pbmZvLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBMUFNUUglzekZuID0gTlVMTDsKICAgIExQU1RSCXN6bkZuID0gTlVMTDsKICAgIFVJTlQJcmV0ID0gTU1TWVNFUlJfTk9NRU07CiAgICBJTlQgICAgICAgICBsZW47CgogICAgaWYgKHN6RmlsZU5hbWUpCiAgICB7CiAgICAgICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZSggQ1BfQUNQLCAwLCBzekZpbGVOYW1lLCAtMSwgTlVMTCwgMCwgTlVMTCwgTlVMTCApOwogICAgICAgIHN6Rm4gPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiApOwogICAgICAgIGlmICghc3pGbikgZ290byBkb25lOwogICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pGaWxlTmFtZSwgLTEsIHN6Rm4sIGxlbiwgTlVMTCwgTlVMTCApOwogICAgfQogICAgaWYgKHN6TmV3RmlsZU5hbWUpCiAgICB7CiAgICAgICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZSggQ1BfQUNQLCAwLCBzek5ld0ZpbGVOYW1lLCAtMSwgTlVMTCwgMCwgTlVMTCwgTlVMTCApOwogICAgICAgIHN6bkZuID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKTsKICAgICAgICBpZiAoIXN6bkZuKSBnb3RvIGRvbmU7CiAgICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZSggQ1BfQUNQLCAwLCBzek5ld0ZpbGVOYW1lLCAtMSwgc3puRm4sIGxlbiwgTlVMTCwgTlVMTCApOwogICAgfQoKICAgIHJldCA9IG1taW9SZW5hbWVBKHN6Rm4sIHN6bkZuLCBscG1taW9pbmZvLCBkd0ZsYWdzKTsKCmRvbmU6CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsc3pGbik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsc3puRm4pOwogICAgcmV0dXJuIHJldDsKfQo=