LyoKICogQ09NIHN0dWIgKENTdGRTdHViQnVmZmVyKSBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgoKI2luY2x1ZGUgImNwc2YuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgojZGVmaW5lIFNUVUJfSEVBREVSKFRoaXMpICgoKGNvbnN0IENJbnRlcmZhY2VTdHViSGVhZGVyKikoKFRoaXMpLT5scFZ0YmwpKVstMV0pCgpzdGF0aWMgTE9ORyBXSU5BUEkgc3R1Yl9maWx0ZXIoRVhDRVBUSU9OX1BPSU5URVJTICplcHRyKQp7CiAgICBpZiAoZXB0ci0+RXhjZXB0aW9uUmVjb3JkLT5FeGNlcHRpb25GbGFncyAmIEVYQ0VQVElPTl9OT05DT05USU5VQUJMRSkKICAgICAgICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX1NFQVJDSDsKICAgIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJVW5rbm93blZ0YmwgKmJhc2Vfb2JqOwogICAgSVJwY1N0dWJCdWZmZXIgKmJhc2Vfc3R1YjsKICAgIENTdGRTdHViQnVmZmVyIHN0dWJfYnVmZmVyOwp9IGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdDsKCnN0YXRpYyBpbmxpbmUgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICppbXBsX2Zyb21fZGVsZWdhdGluZyggSVJwY1N0dWJCdWZmZXIgKmlmYWNlICkKewogICAgcmV0dXJuIChjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QqKSgoY2hhciAqKWlmYWNlIC0gRklFTERfT0ZGU0VUKGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCwgc3R1Yl9idWZmZXIpKTsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENTVFVCQlVGRkVSICpwcFN0dWIpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpczsKICBJVW5rbm93biAqcHZTZXJ2ZXI7CiAgSFJFU1VMVCByOwogIFRSQUNFKCIoJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rU2VydmVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFN0dWIsIG5hbWUpOwogIFRSQUNFKCJpaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQodnRibC0+aGVhZGVyLnBpaWQpKTsKICBUUkFDRSgidnRibD0lcFxuIiwgJnZ0YmwtPlZ0YmwpOwoKICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkgewogICAgRVJSKCJJSUQgbWlzbWF0Y2ggZHVyaW5nIHN0dWIgY3JlYXRpb25cbiIpOwogICAgcmV0dXJuIFJQQ19FX1VORVhQRUNURUQ7CiAgfQoKICByID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocFVua1NlcnZlciwgcmlpZCwgKHZvaWQqKikmcHZTZXJ2ZXIpOwogIGlmKEZBSUxFRChyKSkKICAgIHJldHVybiByOwoKICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoQ1N0ZFN0dWJCdWZmZXIpKTsKICBpZiAoIVRoaXMpIHsKICAgIElVbmtub3duX1JlbGVhc2UocHZTZXJ2ZXIpOwogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgfQoKICBUaGlzLT5scFZ0YmwgPSAmdnRibC0+VnRibDsKICBUaGlzLT5SZWZDb3VudCA9IDE7CiAgVGhpcy0+cHZTZXJ2ZXJPYmplY3QgPSBwdlNlcnZlcjsKICBUaGlzLT5wUFNGYWN0b3J5ID0gcFBTRmFjdG9yeTsKICAqcHBTdHViID0gKExQUlBDU1RVQkJVRkZFUilUaGlzOwoKICBJUFNGYWN0b3J5QnVmZmVyX0FkZFJlZihwUFNGYWN0b3J5KTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gZGVsZWdhdGluZ192dGJsX3NlY3Rpb247CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uLAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbiIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gZGVsZWdhdGluZ192dGJsX3NlY3Rpb24gPSB7ICZjcml0c2VjdF9kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIERXT1JEIHJlZjsKICAgIERXT1JEIHNpemU7CiAgICB2b2lkICoqbWV0aG9kczsKICAgIElVbmtub3duVnRibCB2dGJsOwogICAgLyogcmVtYWluaW5nIGVudHJpZXMgaW4gdnRibCAqLwp9IHJlZl9jb3VudGVkX3Z0Ymw7CgpzdGF0aWMgc3RydWN0CnsKICAgIHJlZl9jb3VudGVkX3Z0YmwgKnRhYmxlOwp9IGN1cnJlbnRfdnRibDsKCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgZGVsZWdhdGluZ19RdWVyeUludGVyZmFjZShJVW5rbm93biAqcFVuaywgUkVGSUlEIGlpZCwgdm9pZCAqKnBwdikKewogICAgKnBwdiA9ICh2b2lkICopcFVuazsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIGRlbGVnYXRpbmdfQWRkUmVmKElVbmtub3duICpwVW5rKQp7CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBkZWxlZ2F0aW5nX1JlbGVhc2UoSVVua25vd24gKnBVbmspCnsKICAgIHJldHVybiAxOwp9CgojaWYgZGVmaW5lZChfX2kzODZfXykKCi8qIFRoZSBpZGVhIGhlcmUgaXMgdG8gcmVwbGFjZSB0aGUgZmlyc3QgcGFyYW0gb24gdGhlIHN0YWNrCiAgIGllLiBUaGlzICh3aGljaCB3aWxsIHBvaW50IHRvIGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCkKICAgd2l0aCBUaGlzLT5zdHViX2J1ZmZlci5wdlNlcnZlck9iamVjdCBhbmQgdGhlbiBqdW1wIHRvIHRoZQogICByZWxldmFudCBvZmZzZXQgaW4gVGhpcy0+c3R1Yl9idWZmZXIucHZTZXJ2ZXJPYmplY3QncyB2dGJsLgoqLwojaW5jbHVkZSAicHNocGFjazEuaCIKdHlwZWRlZiBzdHJ1Y3QgewogICAgRFdPUkQgbW92MTsgICAgLyogbW92IDB4NCglZXNwKSwgJWVheCAgICAgIDhiIDQ0IDI0IDA0ICovCiAgICBXT1JEIG1vdjI7ICAgICAvKiBtb3YgMHgxMCglZWF4KSwgJWVheCAgICAgOGIgNDAgKi8KICAgIEJZVEUgc2l4dGVlbjsgIC8qICAgICAgICAgICAgICAgICAgICAgICAgICAxMCAgICovCiAgICBEV09SRCBtb3YzOyAgICAvKiBtb3YgJWVheCwgMHg0KCVlc3ApICAgICAgODkgNDQgMjQgMDQgKi8KICAgIFdPUkQgbW92NDsgICAgIC8qIG1vdiAoJWVheCksICVlYXggICAgICAgICA4YiAwMCAqLwogICAgV09SRCBtb3Y1OyAgICAgLyogbW92IG9mZnNldCglZWF4KSwgJWVheCAgIDhiIDgwICovCiAgICBEV09SRCBvZmZzZXQ7ICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgeHggeHggeHggeHggKi8KICAgIFdPUkQgam1wOyAgICAgIC8qIGptcCAqJWVheCAgICAgICAgICAgICAgICBmZiBlMCAqLwogICAgQllURSBwYWRbM107ICAgLyogbGVhIDB4MCglZXNpKSwgJWVzaSAgICAgIDhkIDc2IDAwICovCn0gdnRibF9tZXRob2RfdDsKI2luY2x1ZGUgInBvcHBhY2suaCIKCnN0YXRpYyB2b2lkIGZpbGxfdGFibGUoSVVua25vd25WdGJsICp2dGJsLCB2b2lkICoqbWV0aG9kcywgRFdPUkQgbnVtKQp7CiAgICB2dGJsX21ldGhvZF90ICptZXRob2Q7CiAgICB2b2lkICoqZW50cnk7CiAgICBEV09SRCBpOwoKICAgIHZ0YmwtPlF1ZXJ5SW50ZXJmYWNlID0gZGVsZWdhdGluZ19RdWVyeUludGVyZmFjZTsKICAgIHZ0YmwtPkFkZFJlZiA9IGRlbGVnYXRpbmdfQWRkUmVmOwogICAgdnRibC0+UmVsZWFzZSA9IGRlbGVnYXRpbmdfUmVsZWFzZTsKCiAgICBtZXRob2QgPSAodnRibF9tZXRob2RfdCopbWV0aG9kczsKICAgIGVudHJ5ID0gKHZvaWQqKikodnRibCArIDEpOwoKICAgIGZvcihpID0gMzsgaSA8IG51bTsgaSsrKQogICAgewogICAgICAgICplbnRyeSA9IG1ldGhvZDsKICAgICAgICBtZXRob2QtPm1vdjEgPSAweDA0MjQ0NDhiOwogICAgICAgIG1ldGhvZC0+bW92MiA9IDB4NDA4YjsKICAgICAgICBtZXRob2QtPnNpeHRlZW4gPSAweDEwOwogICAgICAgIG1ldGhvZC0+bW92MyA9IDB4MDQyNDQ0ODk7CiAgICAgICAgbWV0aG9kLT5tb3Y0ID0gMHgwMDhiOwogICAgICAgIG1ldGhvZC0+bW92NSA9IDB4ODA4YjsKICAgICAgICBtZXRob2QtPm9mZnNldCA9IGkgPDwgMjsKICAgICAgICBtZXRob2QtPmptcCA9IDB4ZTBmZjsKICAgICAgICBtZXRob2QtPnBhZFswXSA9IDB4OGQ7CiAgICAgICAgbWV0aG9kLT5wYWRbMV0gPSAweDc2OwogICAgICAgIG1ldGhvZC0+cGFkWzJdID0gMHgwMDsKCiAgICAgICAgbWV0aG9kKys7CiAgICAgICAgZW50cnkrKzsKICAgIH0KfQoKI2Vsc2UgIC8qIF9faTM4Nl9fICovCgp0eXBlZGVmIHN0cnVjdCB7aW50IGR1bW15O30gdnRibF9tZXRob2RfdDsKc3RhdGljIHZvaWQgZmlsbF90YWJsZShJVW5rbm93blZ0YmwgKnZ0YmwsIHZvaWQgKiptZXRob2RzLCBEV09SRCBudW0pCnsKICAgIEVSUigiZGVsZWdhdGVkIHN0dWJzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKfQoKI2VuZGlmICAvKiBfX2kzODZfXyAqLwoKdm9pZCBjcmVhdGVfZGVsZWdhdGluZ192dGJsKERXT1JEIG51bV9tZXRob2RzKQp7CiAgICBUUkFDRSgiJWRcbiIsIG51bV9tZXRob2RzKTsKICAgIGlmKG51bV9tZXRob2RzIDw9IDMpCiAgICB7CiAgICAgICAgRVJSKCJzaG91bGQgaGF2ZSBtb3JlIHRoYW4gJWQgbWV0aG9kc1xuIiwgbnVtX21ldGhvZHMpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwogICAgaWYoIWN1cnJlbnRfdnRibC50YWJsZSB8fCBudW1fbWV0aG9kcyA+IGN1cnJlbnRfdnRibC50YWJsZS0+c2l6ZSkKICAgIHsKICAgICAgICBEV09SRCBzaXplOwogICAgICAgIERXT1JEIG9sZF9wcm90ZWN0OwogICAgICAgIGlmKGN1cnJlbnRfdnRibC50YWJsZSAmJiBjdXJyZW50X3Z0YmwudGFibGUtPnJlZiA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoImZyZWVpbmcgb2xkIHRhYmxlXG4iKTsKICAgICAgICAgICAgVmlydHVhbEZyZWUoY3VycmVudF92dGJsLnRhYmxlLT5tZXRob2RzLAogICAgICAgICAgICAgICAgICAgICAgICAoY3VycmVudF92dGJsLnRhYmxlLT5zaXplIC0gMykgKiBzaXplb2YodnRibF9tZXRob2RfdCksCiAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRUxFQVNFKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3VycmVudF92dGJsLnRhYmxlKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSA9IChudW1fbWV0aG9kcyAtIDMpICogc2l6ZW9mKHZ0YmxfbWV0aG9kX3QpOwogICAgICAgIGN1cnJlbnRfdnRibC50YWJsZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBGSUVMRF9PRkZTRVQocmVmX2NvdW50ZWRfdnRibCwgdnRibCkgKyBudW1fbWV0aG9kcyAqIHNpemVvZih2b2lkKikpOwogICAgICAgIGN1cnJlbnRfdnRibC50YWJsZS0+cmVmID0gMDsKICAgICAgICBjdXJyZW50X3Z0YmwudGFibGUtPnNpemUgPSBudW1fbWV0aG9kczsKICAgICAgICBjdXJyZW50X3Z0YmwudGFibGUtPm1ldGhvZHMgPSBWaXJ0dWFsQWxsb2MoTlVMTCwgc2l6ZSwgTUVNX0NPTU1JVCB8IE1FTV9SRVNFUlZFLCBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFKTsKICAgICAgICBmaWxsX3RhYmxlKCZjdXJyZW50X3Z0YmwudGFibGUtPnZ0YmwsIGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywgbnVtX21ldGhvZHMpOwogICAgICAgIFZpcnR1YWxQcm90ZWN0KGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywgc2l6ZSwgUEFHRV9FWEVDVVRFX1JFQUQsICZvbGRfcHJvdGVjdCk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwp9CgpzdGF0aWMgSVVua25vd25WdGJsICpnZXRfZGVsZWdhdGluZ192dGJsKHZvaWQpCnsKICAgIElVbmtub3duVnRibCAqcmV0OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7CiAgICBjdXJyZW50X3Z0YmwudGFibGUtPnJlZisrOwogICAgcmV0ID0gJmN1cnJlbnRfdnRibC50YWJsZS0+dnRibDsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCByZWxlYXNlX2RlbGVnYXRpbmdfdnRibChJVW5rbm93blZ0YmwgKnZ0YmwpCnsKICAgIHJlZl9jb3VudGVkX3Z0YmwgKnRhYmxlID0gKHJlZl9jb3VudGVkX3Z0YmwqKSgoRFdPUkQgKil2dGJsIC0gMSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uKTsKICAgIHRhYmxlLT5yZWYtLTsKICAgIFRSQUNFKCJyZWYgbm93ICVkXG4iLCB0YWJsZS0+cmVmKTsKICAgIGlmKHRhYmxlLT5yZWYgPT0gMCAmJiB0YWJsZSAhPSBjdXJyZW50X3Z0YmwudGFibGUpCiAgICB7CiAgICAgICAgVFJBQ0UoIi4uLiBhbmQgd2UncmUgbm90IGN1cnJlbnQgc28gZnJlZSdpbmdcbiIpOwogICAgICAgIFZpcnR1YWxGcmVlKGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywKICAgICAgICAgICAgICAgICAgICAoY3VycmVudF92dGJsLnRhYmxlLT5zaXplIC0gMykgKiBzaXplb2YodnRibF9tZXRob2RfdCksCiAgICAgICAgICAgICAgICAgICAgTUVNX1JFTEVBU0UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHRhYmxlKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIGRlbGVnYXRpbmdfaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGYWN0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ1NUVUJCVUZGRVIgKnBwU3R1YikKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzOwogICAgSVVua25vd24gKnB2U2VydmVyOwogICAgSFJFU1VMVCByOwoKICAgIFRSQUNFKCIoJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rU2VydmVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFN0dWIsIG5hbWUpOwogICAgVFJBQ0UoImlpZD0lcyBkZWxlZ2F0aW5nIHRvICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHZ0YmwtPmhlYWRlci5waWlkKSwgZGVidWdzdHJfZ3VpZChkZWxlZ2F0aW5nX2lpZCkpOwogICAgVFJBQ0UoInZ0Ymw9JXBcbiIsICZ2dGJsLT5WdGJsKTsKCiAgICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkKICAgIHsKICAgICAgICBFUlIoIklJRCBtaXNtYXRjaCBkdXJpbmcgc3R1YiBjcmVhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIFJQQ19FX1VORVhQRUNURUQ7CiAgICB9CgogICAgciA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBVbmtTZXJ2ZXIsIHJpaWQsICh2b2lkKiopJnB2U2VydmVyKTsKICAgIGlmKEZBSUxFRChyKSkgcmV0dXJuIHI7CgogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgIHsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHB2U2VydmVyKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBUaGlzLT5iYXNlX29iaiA9IGdldF9kZWxlZ2F0aW5nX3Z0YmwoKTsKICAgIHIgPSBjcmVhdGVfc3R1YihkZWxlZ2F0aW5nX2lpZCwgKElVbmtub3duKikmVGhpcy0+YmFzZV9vYmosICZUaGlzLT5iYXNlX3N0dWIpOwogICAgaWYoRkFJTEVEKHIpKQogICAgewogICAgICAgIHJlbGVhc2VfZGVsZWdhdGluZ192dGJsKFRoaXMtPmJhc2Vfb2JqKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHB2U2VydmVyKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICBUaGlzLT5zdHViX2J1ZmZlci5scFZ0YmwgPSAmdnRibC0+VnRibDsKICAgIFRoaXMtPnN0dWJfYnVmZmVyLlJlZkNvdW50ID0gMTsKICAgIFRoaXMtPnN0dWJfYnVmZmVyLnB2U2VydmVyT2JqZWN0ID0gcHZTZXJ2ZXI7CiAgICBUaGlzLT5zdHViX2J1ZmZlci5wUFNGYWN0b3J5ID0gcFBTRmFjdG9yeTsKICAgICpwcFN0dWIgPSAoTFBSUENTVFVCQlVGRkVSKSZUaGlzLT5zdHViX2J1ZmZlcjsKCiAgICBJUFNGYWN0b3J5QnVmZmVyX0FkZFJlZihwUFNGYWN0b3J5KTsKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9RdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpvYmopCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CgogIGlmIChJc0VxdWFsSUlEKCZJSURfSVVua25vd24sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxJSUQoJklJRF9JUnBjU3R1YkJ1ZmZlciwgcmlpZCkpCiAgewogICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICpvYmogPSBpZmFjZTsKICAgIHJldHVybiBTX09LOwogIH0KICAqb2JqID0gTlVMTDsKICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKVUxPTkcgV0lOQVBJIENTdGRTdHViQnVmZmVyX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPlJlZkNvdW50KTsKfQoKVUxPTkcgV0lOQVBJIE5kckNTdGRTdHViQnVmZmVyX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFNGQUNUT1JZQlVGRkVSIHBQU0YpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CgogIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+UmVmQ291bnQpOwogIGlmICghcmVmcykKICB7CiAgICAvKiB0ZXN0X1JlbGVhc2Ugc2hvd3MgdGhhdCBuYXRpdmUgZG9lc24ndCBjYWxsIERpc2Nvbm5lY3QgaGVyZS4KICAgICAgIFdlJ2xsIGxlYXZlIGl0IGluIGZvciB0aGUgdGltZSBiZWluZy4gKi8KICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwoKICAgIElQU0ZhY3RvcnlCdWZmZXJfUmVsZWFzZShwUFNGKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICB9CiAgcmV0dXJuIHJlZnM7Cn0KClVMT05HIFdJTkFQSSBOZHJDU3RkU3R1YkJ1ZmZlcjJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyggaWZhY2UgKTsKICAgIFVMT05HIHJlZnM7CgogICAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIiwgVGhpcyk7CgogICAgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5zdHViX2J1ZmZlci5SZWZDb3VudCk7CiAgICBpZiAoIXJlZnMpCiAgICB7CiAgICAgICAgLyogSnVzdCBsaWtlIE5kckNTdGRTdHViQnVmZmVyX1JlbGVhc2UsIHdlIHNob3VsZG4ndCBjYWxsCiAgICAgICAgICAgRGlzY29ubmVjdCBoZXJlICovCiAgICAgICAgSVJwY1N0dWJCdWZmZXJfRGlzY29ubmVjdCgoSVJwY1N0dWJCdWZmZXIgKikmVGhpcy0+c3R1Yl9idWZmZXIpOwoKICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmJhc2Vfc3R1Yik7CiAgICAgICAgcmVsZWFzZV9kZWxlZ2F0aW5nX3Z0YmwoVGhpcy0+YmFzZV9vYmopOwoKICAgICAgICBJUFNGYWN0b3J5QnVmZmVyX1JlbGVhc2UocFBTRik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZnM7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIGxwVW5rU2VydmVyKQp7CiAgICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogICAgSFJFU1VMVCByOwogICAgSVVua25vd24gKm5ldyA9IE5VTEw7CgogICAgVFJBQ0UoIiglcCktPkNvbm5lY3QoJXApXG4iLFRoaXMsbHBVbmtTZXJ2ZXIpOwoKICAgIHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua1NlcnZlciwgU1RVQl9IRUFERVIoVGhpcykucGlpZCwgKHZvaWQqKikmbmV3KTsKICAgIG5ldyA9IEludGVybG9ja2VkRXhjaGFuZ2VQb2ludGVyKCh2b2lkKiopJlRoaXMtPnB2U2VydmVyT2JqZWN0LCBuZXcpOwogICAgaWYobmV3KQogICAgICAgIElVbmtub3duX1JlbGVhc2UobmV3KTsKICAgIHJldHVybiByOwp9Cgp2b2lkIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogICAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICAgIElVbmtub3duICpvbGQ7CiAgICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwoKICAgIG9sZCA9IEludGVybG9ja2VkRXhjaGFuZ2VQb2ludGVyKCh2b2lkKiopJlRoaXMtPnB2U2VydmVyT2JqZWN0LCBOVUxMKTsKCiAgICBpZihvbGQpCiAgICAgICAgSVVua25vd25fUmVsZWFzZShvbGQpOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9JbnZva2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDT0xFTUVTU0FHRSBwTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcENoYW5uZWwpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIERXT1JEIGR3UGhhc2UgPSBTVFVCX1VOTUFSU0hBTDsKICBIUkVTVUxUIGhyID0gU19PSzsKCiAgVFJBQ0UoIiglcCktPkludm9rZSglcCwlcClcbiIsVGhpcyxwTXNnLHBDaGFubmVsKTsKCiAgX19UUlkKICB7CiAgICBpZiAoU1RVQl9IRUFERVIoVGhpcykucERpc3BhdGNoVGFibGUpCiAgICAgIFNUVUJfSEVBREVSKFRoaXMpLnBEaXNwYXRjaFRhYmxlW3BNc2ctPmlNZXRob2RdKGlmYWNlLCBwQ2hhbm5lbCwgKFBSUENfTUVTU0FHRSlwTXNnLCAmZHdQaGFzZSk7CiAgICBlbHNlIC8qIHB1cmUgaW50ZXJwcmV0ZWQgKi8KICAgICAgTmRyU3R1YkNhbGwyKGlmYWNlLCBwQ2hhbm5lbCwgKFBSUENfTUVTU0FHRSlwTXNnLCAmZHdQaGFzZSk7CiAgfQogIF9fRVhDRVBUKHN0dWJfZmlsdGVyKQogIHsKICAgIERXT1JEIGR3RXhjZXB0aW9uQ29kZSA9IEdldEV4Y2VwdGlvbkNvZGUoKTsKICAgIFdBUk4oImEgc3R1YiBjYWxsIGZhaWxlZCB3aXRoIGV4Y2VwdGlvbiAweCUwOHggKCVkKVxuIiwgZHdFeGNlcHRpb25Db2RlLCBkd0V4Y2VwdGlvbkNvZGUpOwogICAgaWYgKEZBSUxFRChkd0V4Y2VwdGlvbkNvZGUpKQogICAgICBociA9IGR3RXhjZXB0aW9uQ29kZTsKICAgIGVsc2UKICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoZHdFeGNlcHRpb25Db2RlKTsKICB9CiAgX19FTkRUUlkKCiAgcmV0dXJuIGhyOwp9CgpMUFJQQ1NUVUJCVUZGRVIgV0lOQVBJIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgcmV0dXJuIElzRXF1YWxHVUlEKFNUVUJfSEVBREVSKFRoaXMpLnBpaWQsIHJpaWQpID8gaWZhY2UgOiBOVUxMOwp9CgpVTE9ORyBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkNvdW50UmVmcygpXG4iLFRoaXMpOwogIHJldHVybiBUaGlzLT5SZWZDb3VudDsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdikKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkRlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoJXApXG4iLFRoaXMscHB2KTsKICByZXR1cm4gU19PSzsKfQoKdm9pZCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJSZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIHB2KQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+RGVidWdTZXJ2ZXJSZWxlYXNlKCVwKVxuIixUaGlzLHB2KTsKfQoKY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIENTdGRTdHViQnVmZmVyX1Z0YmwgPQp7CiAgICBDU3RkU3R1YkJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0FkZFJlZiwKICAgIE5VTEwsCiAgICBDU3RkU3R1YkJ1ZmZlcl9Db25uZWN0LAogICAgQ1N0ZFN0dWJCdWZmZXJfRGlzY29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0ludm9rZSwKICAgIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkLAogICAgQ1N0ZFN0dWJCdWZmZXJfQ291bnRSZWZzLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIGxwVW5rU2VydmVyKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBIUkVTVUxUIHI7CiAgICBUUkFDRSgiKCVwKS0+Q29ubmVjdCglcClcbiIsIFRoaXMsIGxwVW5rU2VydmVyKTsKCiAgICByID0gQ1N0ZFN0dWJCdWZmZXJfQ29ubmVjdChpZmFjZSwgbHBVbmtTZXJ2ZXIpOwogICAgaWYoU1VDQ0VFREVEKHIpKQogICAgICAgIHIgPSBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KFRoaXMtPmJhc2Vfc3R1YiwgKElVbmtub3duKikmVGhpcy0+YmFzZV9vYmopOwoKICAgIHJldHVybiByOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPkRpc2Nvbm5lY3QoKVxuIiwgVGhpcyk7CgogICAgSVJwY1N0dWJCdWZmZXJfRGlzY29ubmVjdChUaGlzLT5iYXNlX3N0dWIpOwogICAgQ1N0ZFN0dWJCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBVTE9ORyByZXQ7CiAgICBUUkFDRSgiKCVwKS0+Q291bnRSZWZzKClcbiIsIFRoaXMpOwoKICAgIHJldCA9IENTdGRTdHViQnVmZmVyX0NvdW50UmVmcyhpZmFjZSk7CiAgICByZXQgKz0gSVJwY1N0dWJCdWZmZXJfQ291bnRSZWZzKFRoaXMtPmJhc2Vfc3R1Yik7CgogICAgcmV0dXJuIHJldDsKfQoKY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfVnRibCA9CnsKICAgIENTdGRTdHViQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgQ1N0ZFN0dWJCdWZmZXJfQWRkUmVmLAogICAgTlVMTCwKICAgIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfRGlzY29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0ludm9rZSwKICAgIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19Db3VudFJlZnMsCiAgICBDU3RkU3R1YkJ1ZmZlcl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07Cgpjb25zdCBNSURMX1NFUlZFUl9JTkZPICpDU3RkU3R1YkJ1ZmZlcl9HZXRTZXJ2ZXJJbmZvKElScGNTdHViQnVmZmVyICppZmFjZSkKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgcmV0dXJuIFNUVUJfSEVBREVSKFRoaXMpLnBTZXJ2ZXJJbmZvOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJTdHViRm9yd2FyZGluZ0Z1bmN0aW9uIFtSUENSVDQuQF0KICovCnZvaWQgX19SUENfU1RVQiBOZHJTdHViRm9yd2FyZGluZ0Z1bmN0aW9uKCBJUnBjU3R1YkJ1ZmZlciAqaWZhY2UsIElScGNDaGFubmVsQnVmZmVyICpwQ2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfTUVTU0FHRSBwTXNnLCBEV09SRCAqcGR3U3R1YlBoYXNlICkKewogICAgLyogTm90ZSBwTXNnIGlzIHBhc3NlZCBpbnRhY3Qgc2luY2UgUlBDT0xFTUVTU0FHRSBpcyBiYXNpY2FsbHkgYSBSUENfTUVTU0FHRS4gKi8KCiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBIUkVTVUxUIHIgPSBJUnBjU3R1YkJ1ZmZlcl9JbnZva2UoVGhpcy0+YmFzZV9zdHViLCAoUlBDT0xFTUVTU0FHRSopcE1zZywgcENoYW5uZWwpOwogICAgaWYoRkFJTEVEKHIpKSBScGNSYWlzZUV4Y2VwdGlvbihyKTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJTdHViSW5pdGlhbGl6ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJTdHViSW5pdGlhbGl6ZShQUlBDX01FU1NBR0UgcFJwY01zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcFJwY0NoYW5uZWxCdWZmZXIpCnsKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIiwgcFJwY01zZywgcFN0dWJNc2csIHBTdHViRGVzY3JpcHRvciwgcFJwY0NoYW5uZWxCdWZmZXIpOwogIE5kclNlcnZlckluaXRpYWxpemVOZXcocFJwY01zZywgcFN0dWJNc2csIHBTdHViRGVzY3JpcHRvcik7CiAgcFN0dWJNc2ctPnBScGNDaGFubmVsQnVmZmVyID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgSVJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChwU3R1Yk1zZy0+cFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJNc2ctPmR3RGVzdENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJNc2ctPnB2RGVzdENvbnRleHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclN0dWJHZXRCdWZmZXIgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRyU3R1YkdldEJ1ZmZlcihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2cpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIFRoaXMsIHBScGNDaGFubmVsQnVmZmVyLCBwU3R1Yk1zZyk7CgogIHBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlckxlbmd0aCA9IHBTdHViTXNnLT5CdWZmZXJMZW5ndGg7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocFJwY0NoYW5uZWxCdWZmZXIsCiAgICAoUlBDT0xFTUVTU0FHRSAqKXBTdHViTXNnLT5ScGNNc2csIFNUVUJfSEVBREVSKFRoaXMpLnBpaWQpOwogIGlmIChGQUlMRUQoaHIpKQogIHsKICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIHJldHVybjsKICB9CgogIHBTdHViTXNnLT5CdWZmZXIgPSBwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXI7Cn0K