LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZG93c3guaCIKCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSUJ1aWxkRmlsdGVyVyAtLSB1c2VzIGZpeGVkIHNpemUgdGFibGUKICovCiNkZWZpbmUgTUFYX0ZJTFRFUlMgMzAgLyogMzAgPT4gN2tCICovCgp0eXBlZGVmIHN0cnVjdCBfQVZJRmlsdGVyIHsKICBXQ0hBUiBzekNsc2lkWzQwXTsKICBXQ0hBUiBzekV4dGVuc2lvbnNbTUFYX0ZJTFRFUlMgKiA3XTsKfSBBVklGaWx0ZXI7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSVNhdmVPcHRpb25zCiAqLwpzdGF0aWMgc3RydWN0IHsKICBVSU5UICAgICAgICAgICAgICAgICAgdUZsYWdzOwogIElOVCAgICAgICAgICAgICAgICAgICBuU3RyZWFtczsKICBQQVZJU1RSRUFNICAgICAgICAgICAqcHBhdmlzOwogIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnM7CiAgSU5UICAgICAgICAgICAgICAgICAgIG5DdXJyZW50Owp9IFNhdmVPcHRzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNvcGllZCBmcm9tIGRsbHMvb2xlMzIvY29tcG9iai5jCiAqLwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0NMU0lERnJvbVN0cmluZyhMUENTVFIgaWRzdHIsIExQQ0xTSUQgaWQpCnsKICBCWVRFIGNvbnN0ICpzID0gKEJZVEUgY29uc3QqKWlkc3RyOwogIEJZVEUgKnA7CiAgSU5UICAgaTsKICBCWVRFIHRhYmxlWzI1Nl07CgogIGlmICghcykgewogICAgbWVtc2V0KGlkLCAwLCBzaXplb2YoQ0xTSUQpKTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCiAgICBpZiAobHN0cmxlbkEocykgIT0gMzgpCiAgICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwoKICAgIGlmICgoc1swXSE9J3snKSB8fCAoc1s5XSE9Jy0nKSB8fCAoc1sxNF0hPSctJykgfHwgKHNbMTldIT0nLScpIHx8Cgkoc1syNF0hPSctJykgfHwgKHNbMzddIT0nfScpKQogICAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgICBmb3IgKGkgPSAxOyBpIDwgMzc7IGkrKykgewogICAgICBpZiAoKGkgPT0gOSkgfHwgKGkgPT0gMTQpIHx8IChpID09IDE5KSB8fCAoaSA9PSAyNCkpCgljb250aW51ZTsKICAgICAgaWYgKCEoKChzW2ldID49ICcwJykgJiYgKHNbaV0gPD0gJzknKSkgIHx8CgkgICAgKChzW2ldID49ICdhJykgJiYgKHNbaV0gPD0gJ2YnKSkgIHx8CgkgICAgKChzW2ldID49ICdBJykgJiYgKHNbaV0gPD0gJ0YnKSkpCgkgICkKCXJldHVybiBDT19FX0NMQVNTU1RSSU5HOwogICAgfQogIH0KCiAgVFJBQ0UoIiVzIC0+ICVwXG4iLCBzLCBpZCk7CgogIC8qIHF1aWNrIGxvb2t1cCB0YWJsZSAqLwogIG1lbXNldCh0YWJsZSwgMCwgMjU2KTsKCiAgZm9yIChpID0gMDsgaSA8IDEwOyBpKyspCiAgICB0YWJsZVsnMCcgKyBpXSA9IGk7CgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgIHRhYmxlWydBJyArIGldID0gaSsxMDsKICAgIHRhYmxlWydhJyArIGldID0gaSsxMDsKICB9CgogIC8qIGluIGZvcm0ge1hYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWH0gKi8KICBwID0gKEJZVEUgKikgaWQ7CgogIHMrKzsJLyogc2tpcCBsZWFkaW5nIGJyYWNlICAqLwogIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgIHBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSA0OwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICBwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDI7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CiAgICAqcCsrID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CgogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgQk9PTCBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oTFBDV1NUUiBzekZpbGUsIExQQ0xTSUQgbHBjbHNpZCkKewogIENIQVIgICBzelJlZ0tleVsyNV07CiAgQ0hBUiAgIHN6VmFsdWVbMTAwXTsKICBMUFdTVFIgc3pFeHQgPSBzdHJyY2hyVyhzekZpbGUsICcuJyk7CiAgTE9ORyAgIGxlbiA9IHNpemVvZihzelZhbHVlKSAvIHNpemVvZihzelZhbHVlWzBdKTsKCiAgaWYgKHN6RXh0ID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIHN6RXh0Kys7CgogIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXEV4dGVuc2lvbnNcXCUuM2xzIiwgc3pFeHQpOwogIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgbHBjbHNpZCkgPT0gU19PSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluaXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluaXQJCShBVklGSUxFLjEwMCkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVJbml0KHZvaWQpIHsKICAvKiBuZWVkIHRvIGxvYWQgb2xlMzIuZGxsIGlmIG5vdCBhbHJlYWR5IGRvbmUgYW5kIGdldCBzb21lIGZ1bmN0aW9ucyAqLwogIEZJWE1FKCIoKTogc3R1YiFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMRS4xMDEpCiAqLwp2b2lkIFdJTkFQSSBBVklGaWxlRXhpdCh2b2lkKSB7CiAgLyogbmVlZCB0byBmcmVlIG9sZTMyLmRsbCBpZiB3ZSBhcmUgdGhlIGxhc3QgZXhpdCBjYWxsICovCiAgRklYTUUoIigpOiBzdHViIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZU9wZW5BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVPcGVuCQkoQVZJRklMRS4xMDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlbkEoUEFWSUZJTEUgKnBwZmlsZSwgTFBDU1RSIHN6RmlsZSwgVUlOVCB1TW9kZSwKCQkJICAgIExQQ0xTSUQgbHBIYW5kbGVyKQp7CiAgTFBXU1RSICB3c3pGaWxlID0gTlVMTDsKICBIUkVTVUxUIGhyOwogIGludCAgICAgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4WCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfYShzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjb252ZXJ0IEFTQ0lJIHN0cmluZyB0byBVbmljb2RlIGFuZCBjYWxsIHVuaWNvZGUgZnVuY3Rpb24gKi8KICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgTlVMTCwgMCk7CiAgaWYgKGxlbiA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgd3N6RmlsZSA9IChMUFdTVFIpTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4pOwoKICBociA9IEFWSUZpbGVPcGVuVyhwcGZpbGUsIHdzekZpbGUsIHVNb2RlLCBscEhhbmRsZXIpOwoKICBMb2NhbEZyZWUoKEhMT0NBTCl3c3pGaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlblcoUEFWSUZJTEUgKnBwZmlsZSwgTFBDV1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIElQZXJzaXN0RmlsZSAqcHBlcnNpc3QgPSBOVUxMOwogIENMU0lEICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXMsMHglWCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfdyhzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciB0aGVuIHRyeSBndWVzc2luZyBpdCBieSBleHRlbnNpb24gKi8KICBpZiAobHBIYW5kbGVyID09IE5VTEwpIHsKICAgIGlmICghIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihzekZpbGUsICZjbHNpZEhhbmRsZXIpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZQogICAgbWVtY3B5KCZjbHNpZEhhbmRsZXIsIGxwSGFuZGxlciwgc2l6ZW9mKGNsc2lkSGFuZGxlcikpOwoKICAvKiBjcmV0ZSBpbnN0YW5jZSBvZiBoYW5kbGVyICovCiAgaHIgPSBTSENvQ3JlYXRlSW5zdGFuY2UoTlVMTCwgJmNsc2lkSGFuZGxlciwgTlVMTCwKCQkJICAmSUlEX0lBVklGaWxlLCAoTFBWT0lEKilwcGZpbGUpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgLyogYXNrIGZvciBJUGVyc2lzdEZpbGUgaW50ZXJmYWNlIGZvciBsb2FkaW5nL2NyZWF0aW5nIHRoZSBmaWxlICovCiAgaHIgPSBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgqcHBmaWxlLCAmSUlEX0lQZXJzaXN0RmlsZSwgKExQVk9JRCopJnBwZXJzaXN0KTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwcGVyc2lzdCA9PSBOVUxMKSB7CiAgICBJQVZJRmlsZV9SZWxlYXNlKCpwcGZpbGUpOwogICAgKnBwZmlsZSA9IE5VTEw7CiAgICByZXR1cm4gaHI7CiAgfQoKICBociA9IElQZXJzaXN0RmlsZV9Mb2FkKHBwZXJzaXN0LCBzekZpbGUsIHVNb2RlKTsKICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwcGVyc2lzdCk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklGaWxlX1JlbGVhc2UoKnBwZmlsZSk7CiAgICAqcHBmaWxlID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQWRkUmVmCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVBZGRSZWYJCShBVklGSUxFLjE0MCkKICovClVMT05HIFdJTkFQSSBBVklGaWxlQWRkUmVmKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTEUuMTQxKQogKi8KVUxPTkcgV0lOQVBJIEFWSUZpbGVSZWxlYXNlKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluZm8JCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluZm9BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbmZvCQkoQVZJRklMRS4xNDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb0EoUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9BIGFmaSwgTE9ORyBzaXplKQp7CiAgQVZJRklMRUlORk9XIGFmaXc7CiAgSFJFU1VMVCAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaSwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKEFWSUZJTEVJTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJRmlsZV9JbmZvKHBmaWxlLCAmYWZpdywgc2l6ZW9mKGFmaXcpKTsKCiAgbWVtY3B5KGFmaSwgJmFmaXcsIHNpemVvZigqYWZpKSAtIHNpemVvZihhZmktPnN6RmlsZVR5cGUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYWZpdy5zekZpbGVUeXBlLCAtMSwgYWZpLT5zekZpbGVUeXBlLAoJCSAgICAgIHNpemVvZihhZmktPnN6RmlsZVR5cGUpLCBOVUxMLCBOVUxMKTsKICBhZmktPnN6RmlsZVR5cGVbc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb1coUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9XIGFmaXcsIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaXcsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfSW5mbyhwZmlsZSwgYWZpdywgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVHZXRTdHJlYW0JKEFWSUZJTEUuMTQzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUdldFN0cmVhbShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCURXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgVFJBQ0UoIiglcCwlcCwnJTQuNHMnLCVsZClcbiIsIHBmaWxlLCBhdmlzLCAoY2hhciopJmZjY1R5cGUsIGxQYXJhbSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbUEJKEFWSUZJTDMyLkApCiAqICAgICAgICAgICAgICBBVklGaWxlQ3JlYXRlU3RyZWFtCShBVklGSUxFLjE0NCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVDcmVhdGVTdHJlYW1BKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICpwcGF2aSwKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9BIHBzaSkKewogIEFWSVNUUkVBTUlORk9XCXBzaXc7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgcHBhdmksIHBzaSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIC8qIE9ubHkgdGhlIHN6TmFtZSBhdCB0aGUgZW5kIGlzIGRpZmZlcmVudCAqLwogIG1lbWNweSgmcHNpdywgcHNpLCBzaXplb2YoKnBzaSkgLSBzaXplb2YocHNpLT5zek5hbWUpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgcHNpLT5zek5hbWUsIC0xLCBwc2l3LnN6TmFtZSwKCQkgICAgICBzaXplb2YocHNpdy5zek5hbWUpIC8gc2l6ZW9mKHBzaXcuc3pOYW1lWzBdKSk7CgogIHJldHVybiBJQVZJRmlsZV9DcmVhdGVTdHJlYW0ocGZpbGUsIHBwYXZpLCAmcHNpdyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbVcJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlQ3JlYXRlU3RyZWFtVyhQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgYXZpcywgYXNpKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0NyZWF0ZVN0cmVhbShwZmlsZSwgYXZpcywgYXNpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZVdyaXRlRGF0YQkoQVZJRklMRS4xNDYpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlV3JpdGVEYXRhKFBBVklGSUxFIHBmaWxlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVsZClcbiIsIHBmaWxlLCAoY2hhciopJmZjYywgbHAsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfV3JpdGVEYXRhKHBmaWxlLCBmY2MsIGxwLCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlUmVhZERhdGEJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZVJlYWREYXRhCQkoQVZJRklMRS4xNDcpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlUmVhZERhdGEoUEFWSUZJTEUgcGZpbGUsRFdPUkQgZmNjLExQVk9JRCBscCxMUExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlcClcbiIsIHBmaWxlLCAoY2hhciopJmZjYywgbHAsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfUmVhZERhdGEocGZpbGUsIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVFbmRSZWNvcmQJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlRW5kUmVjb3JkCShBVklGSUxFLjE0OCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVFbmRSZWNvcmQoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfRW5kUmVjb3JkKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1BZGRSZWYJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtQWRkUmVmCQkoQVZJRklMRS4xNjApCiAqLwpVTE9ORyBXSU5BUEkgQVZJU3RyZWFtQWRkUmVmKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJU3RyZWFtX0FkZFJlZihwc3RyZWFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWxlYXNlCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVsZWFzZQkoQVZJRklMRS4xNjEpCiAqLwpVTE9ORyBXSU5BUEkgQVZJU3RyZWFtUmVsZWFzZShQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWxlYXNlKHBzdHJlYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUNyZWF0ZQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1DcmVhdGUJCShBVklGSUxFLjEwNCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUNyZWF0ZShQQVZJU1RSRUFNICpwcGF2aSwgTE9ORyBsUGFyYW0xLCBMT05HIGxQYXJhbTIsCgkJCSAgICAgICBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWCwlcylcbiIsIHBwYXZpLCBsUGFyYW0xLCBsUGFyYW0yLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgaHIgPSBTSENvQ3JlYXRlSW5zdGFuY2UoTlVMTCwgcGNsc2lkSGFuZGxlciwgTlVMTCwKCQkJICAmSUlEX0lBVklTdHJlYW0sIChMUFZPSUQqKXBwYXZpKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJU3RyZWFtX0NyZWF0ZSgqcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIpOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoKnBwYXZpKTsKICAgICpwcGF2aSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtSW5mbwkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1JbmZvQQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1JbmZvCQkoQVZJRklMRS4xNjIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIEhSRVNVTFQJIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CgogIG1lbWNweShhc2ksICZhc2l3LCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYXNpdy5zek5hbWUsIC0xLCBhc2ktPnN6TmFtZSwKCQkgICAgICBzaXplb2YoYXNpLT5zek5hbWUpLCBOVUxMLCBOVUxMKTsKICBhc2ktPnN6TmFtZVtzaXplb2YoYXNpLT5zek5hbWUpIC0gMV0gPSAwOwoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT1cgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCBhc2ksIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1GaW5kU2FtcGxlCShBVklGSUxFLjE2MykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUZpbmRTYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywgRFdPUkQgZmxhZ3MpCnsKICBUUkFDRSgiKCVwLCVsZCwweCVsWClcbiIsIHBzdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKHBzdHJlYW0sIHBvcywgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWFkRm9ybWF0CShBVklGSUxFLjE2NCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWRGb3JtYXQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywKCQkJCSAgIExQVk9JRCBmb3JtYXQsIExQTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZEZvcm1hdChwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2V0Rm9ybWF0CShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtU2V0Rm9ybWF0CShBVklGSUxFLjE2OSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVNldEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWQJCShBVklGSUxFLjE2NykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgTFBWT0lEIGJ1ZmZlciwgTE9ORyBidWZmZXJzaXplLAoJCQkgICAgIExQTE9ORyBieXRlc3JlYWQsIExQTE9ORyBzYW1wbGVzcmVhZCkKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUxFLjE2OCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBzdGFydCwgTE9ORyBzYW1wbGVzLAoJCQkgICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkgICAgICBMUExPTkcgc2FtcHdyaXR0ZW4sIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JWxYLCVwLCVwKVxuIiwgcHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZShwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkRGF0YQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWREYXRhCShBVklGSUxFLjE2NSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWREYXRhKFBBVklTVFJFQU0gcHN0cmVhbSwgRFdPUkQgZmNjLCBMUFZPSUQgbHAsCgkJCQkgTFBMT05HIGxwcmVhZCkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlcClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRGF0YShwc3RyZWFtLCBmY2MsIGxwLCBscHJlYWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVdyaXRlRGF0YQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVdyaXRlRGF0YQkoQVZJRklMRS4xNjYpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1Xcml0ZURhdGEoUEFWSVNUUkVBTSBwc3RyZWFtLCBEV09SRCBmY2MsIExQVk9JRCBscCwKCQkJCSAgTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVsZClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKHBzdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMRS4xMTIpCiAqLwpQR0VURlJBTUUgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lT3BlbihQQVZJU1RSRUFNIHBzdHJlYW0sCgkJCQkgICAgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlXYW50ZWQpCnsKICBQR0VURlJBTUUgcGcgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcHN0cmVhbSwgbHBiaVdhbnRlZCk7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lHZXRGcmFtZSwgKExQVk9JRCopJnBnKSkgfHwKICAgICAgcGcgPT0gTlVMTCkgewogICAgcGcgPSBBVklGSUxFX0NyZWF0ZUdldEZyYW1lKHBzdHJlYW0pOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogIH0KCiAgaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KHBnLCBscGJpV2FudGVkLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkgewogICAgSUdldEZyYW1lX1JlbGVhc2UocGcpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcGc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZQkoQVZJRklMRS4xMTApCiAqLwpMUFZPSUQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lKFBHRVRGUkFNRSBwZywgTE9ORyBwb3MpCnsKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBnLCBwb3MpOwoKICBpZiAocGcgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICByZXR1cm4gSUdldEZyYW1lX0dldEZyYW1lKHBnLCBwb3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZUNsb3NlCShBVklGSUxFLjExMSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoUEdFVEZSQU1FIHBnKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBnKTsKCiAgaWYgKHBnICE9IE5VTEwpCiAgICByZXR1cm4gSUdldEZyYW1lX1JlbGVhc2UocGcpOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSU1ha2VDb21wcmVzc2VkU3RyZWFtCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0oUEFWSVNUUkVBTSAqcHBzQ29tcHJlc3NlZCwKCQkJCSAgICAgICBQQVZJU1RSRUFNIHBzU291cmNlLAoJCQkJICAgICAgIExQQVZJQ09NUFJFU1NPUFRJT05TIGFjbywKCQkJCSAgICAgICBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIENIQVIgICAgICAgICAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgICAgICAgICBzelZhbHVlWzEwMF07CiAgQ0xTSUQgICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgIGhyOwogIExPTkcgICAgICAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSk7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXMpXG4iLCBwcHNDb21wcmVzc2VkLCBwc1NvdXJjZSwgYWNvLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcHNDb21wcmVzc2VkID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChwc1NvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogICpwcHNDb21wcmVzc2VkID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciBnaXZlbiBnZXQgZGVmYXVsdCBvbmVzIGJhc2VkIG9uIHN0cmVhbXR5cGUgKi8KICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1fSW5mbyhwc1NvdXJjZSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXENvbXByZXNzb3JzXFwlNC40cyIsIChjaGFyKikmYXNpdy5mY2NUeXBlKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZzaXplKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogICAgaWYgKEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKHN6VmFsdWUsICZjbHNpZEhhbmRsZXIpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfSBlbHNlCiAgICBtZW1jcHkoJmNsc2lkSGFuZGxlciwgcGNsc2lkSGFuZGxlciwgc2l6ZW9mKGNsc2lkSGFuZGxlcikpOwoKICBociA9IFNIQ29DcmVhdGVJbnN0YW5jZShOVUxMLCAmY2xzaWRIYW5kbGVyLCBOVUxMLAoJCQkgICZJSURfSUFWSVN0cmVhbSwgKExQVk9JRCopcHBzQ29tcHJlc3NlZCk7CiAgaWYgKEZBSUxFRChocikgfHwgKnBwc0NvbXByZXNzZWQgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJU3RyZWFtX0NyZWF0ZSgqcHBzQ29tcHJlc3NlZCwgKExQQVJBTSlwc1NvdXJjZSwgKExQQVJBTSlhY28pOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoKnBwc0NvbXByZXNzZWQpOwogICAgKnBwc0NvbXByZXNzZWQgPSBOVUxMOwogIH0KCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSU1ha2VGaWxlRnJvbVN0cmVhbXMJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlRmlsZUZyb21TdHJlYW1zKFBBVklGSUxFICpwcGZpbGUsIGludCBuU3RyZWFtcywKCQkJCSAgICAgIFBBVklTVFJFQU0gKnBwU3RyZWFtcykKewogIFRSQUNFKCIoJXAsJWQsJXApXG4iLCBwcGZpbGUsIG5TdHJlYW1zLCBwcFN0cmVhbXMpOwoKICBpZiAoblN0cmVhbXMgPCAwIHx8IHBwZmlsZSA9PSBOVUxMIHx8IHBwU3RyZWFtcyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwZmlsZSA9IEFWSUZJTEVfQ3JlYXRlQVZJVGVtcEZpbGUoblN0cmVhbXMsIHBwU3RyZWFtcyk7CiAgaWYgKCpwcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZSAgIChBVklGSUxFLjEwMykKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZUEJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1PcGVuRnJvbUZpbGVBKFBBVklTVFJFQU0gKnBwYXZpLCBMUENTVFIgc3pGaWxlLAoJCQkJICAgICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0sCgkJCQkgICAgICBVSU5UIG1vZGUsIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIFBBVklGSUxFIHBmaWxlID0gTlVMTDsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlcywnJTQuNHMnLCVsZCwweCVYLCVzKVxuIiwgcHBhdmksIGRlYnVnc3RyX2Eoc3pGaWxlKSwKCShjaGFyKikmZmNjVHlwZSwgbFBhcmFtLCBtb2RlLCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwoKICBociA9IEFWSUZpbGVPcGVuQSgmcGZpbGUsIHN6RmlsZSwgbW9kZSwgcGNsc2lkSGFuZGxlcik7CiAgaWYgKEZBSUxFRChocikgfHwgcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIHBwYXZpLCBmY2NUeXBlLCBsUGFyYW0pOwogIElBVklGaWxlX1JlbGVhc2UocGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbU9wZW5Gcm9tRmlsZVcoUEFWSVNUUkVBTSAqcHBhdmksIExQQ1dTVFIgc3pGaWxlLAoJCQkJICAgICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0sCgkJCQkgICAgICBVSU5UIG1vZGUsIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIFBBVklGSUxFIHBmaWxlID0gTlVMTDsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlcywnJTQuNHMnLCVsZCwweCVYLCVzKVxuIiwgcHBhdmksIGRlYnVnc3RyX3coc3pGaWxlKSwKCShjaGFyKikmZmNjVHlwZSwgbFBhcmFtLCBtb2RlLCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwoKICBociA9IEFWSUZpbGVPcGVuVygmcGZpbGUsIHN6RmlsZSwgbW9kZSwgcGNsc2lkSGFuZGxlcik7CiAgaWYgKEZBSUxFRChocikgfHwgcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIHBwYXZpLCBmY2NUeXBlLCBsUGFyYW0pOwogIElBVklGaWxlX1JlbGVhc2UocGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQmVnaW5TdHJlYW1pbmcJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1CZWdpblN0cmVhbWluZyhQQVZJU1RSRUFNIHBhdmksIExPTkcgbFN0YXJ0LCBMT05HIGxFbmQsIExPTkcgbFJhdGUpCnsKICBJQVZJU3RyZWFtaW5nKiBwc3RyZWFtID0gTlVMTDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJWxkKVxuIiwgcGF2aSwgbFN0YXJ0LCBsRW5kLCBsUmF0ZSk7CgogIGlmIChwYXZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBhdmksICZJSURfSUFWSVN0cmVhbWluZywgKExQVk9JRCopJnBzdHJlYW0pOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBzdHJlYW0gIT0gTlVMTCkgewogICAgaHIgPSBJQVZJU3RyZWFtaW5nX0JlZ2luKHBzdHJlYW0sIGxTdGFydCwgbEVuZCwgbFJhdGUpOwogICAgSUFWSVN0cmVhbWluZ19SZWxlYXNlKHBzdHJlYW0pOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfT0s7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1FbmRTdHJlYW1pbmcJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1FbmRTdHJlYW1pbmcoUEFWSVNUUkVBTSBwYXZpKQp7CiAgSUFWSVN0cmVhbWluZyogcHN0cmVhbSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcClcbiIsIHBhdmkpOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocGF2aSwgJklJRF9JQVZJU3RyZWFtaW5nLCAoTFBWT0lEKikmcHN0cmVhbSk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcHN0cmVhbSAhPSBOVUxMKSB7CiAgICBJQVZJU3RyZWFtaW5nX0VuZChwc3RyZWFtKTsKICAgIElBVklTdHJlYW1pbmdfUmVsZWFzZShwc3RyZWFtKTsKICB9CgogcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTEUuMTMwKQogKgkJQVZJU3RyZWFtU3RhcnQJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtU3RhcnQoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKCiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIDA7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAwOwoKICByZXR1cm4gYXNpdy5kd1N0YXJ0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUxlbmd0aAkJKEFWSUZJTEUuMTMxKQogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUxlbmd0aChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3TGVuZ3RoOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMRS4xMzMpCiAqCQlBVklTdHJlYW1TYW1wbGVUb1RpbWUJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TYW1wbGVUb1RpbWUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIGxTYW1wbGUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIExPTkcgdGltZTsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBwc3RyZWFtLCBsU2FtcGxlKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIC0xOwogIGlmIChhc2l3LmR3UmF0ZSA9PSAwKQogICAgcmV0dXJuIC0xOwoKICAvKiBsaW1pdCB0byBzdHJlYW0gYm91bmRzICovCiAgaWYgKGxTYW1wbGUgPCBhc2l3LmR3U3RhcnQpCiAgICBsU2FtcGxlID0gYXNpdy5kd1N0YXJ0OwogIGlmIChsU2FtcGxlID4gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aCkKICAgIGxTYW1wbGUgPSBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoOwoKICBpZiAoYXNpdy5kd1JhdGUgLyBhc2l3LmR3U2NhbGUgPCAxMDAwKQogICAgdGltZSA9IChMT05HKSgoKGZsb2F0KWxTYW1wbGUgKiBhc2l3LmR3U2NhbGUgKiAxMDAwKSAvIGFzaXcuZHdSYXRlKTsKICBlbHNlCiAgICB0aW1lID0gKExPTkcpKCgoZmxvYXQpbFNhbXBsZSAqIGFzaXcuZHdTY2FsZSAqIDEwMDAgKyAoYXNpdy5kd1JhdGUgLSAxKSkgLyBhc2l3LmR3UmF0ZSk7CgogIFRSQUNFKCIgLT4gJWxkXG4iLHRpbWUpOwogIHJldHVybiB0aW1lOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMRS4xMzIpCiAqCQlBVklTdHJlYW1UaW1lVG9TYW1wbGUJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1UaW1lVG9TYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIGxUaW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBVTE9ORyBzYW1wbGU7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcHN0cmVhbSwgbFRpbWUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMIHx8IGxUaW1lIDwgMCkKICAgIHJldHVybiAtMTsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIC0xOwogIGlmIChhc2l3LmR3U2NhbGUgPT0gMCkKICAgIHJldHVybiAtMTsKCiAgaWYgKGFzaXcuZHdSYXRlIC8gYXNpdy5kd1NjYWxlIDwgMTAwMCkKICAgIHNhbXBsZSA9IChMT05HKSgoKChmbG9hdClhc2l3LmR3UmF0ZSAqIGxUaW1lKSAvIChhc2l3LmR3U2NhbGUgKiAxMDAwKSkpOwogIGVsc2UKICAgIHNhbXBsZSA9IChMT05HKSgoKGZsb2F0KWFzaXcuZHdSYXRlICogbFRpbWUgKyAoYXNpdy5kd1NjYWxlICogMTAwMCAtIDEpKSAvIChhc2l3LmR3U2NhbGUgKiAxMDAwKSk7CgogIC8qIGxpbWl0IHRvIHN0cmVhbSBib3VuZHMgKi8KICBpZiAoc2FtcGxlIDwgYXNpdy5kd1N0YXJ0KQogICAgc2FtcGxlID0gYXNpdy5kd1N0YXJ0OwogIGlmIChzYW1wbGUgPiBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoKQogICAgc2FtcGxlID0gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aDsKCiAgVFJBQ0UoIiAtPiAlbGRcbiIsIHNhbXBsZSk7CiAgcmV0dXJuIHNhbXBsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklCdWlsZEZpbHRlckEJCShBVklGSUwzMi5AKQogKgkJQVZJQnVpbGRGaWx0ZXIJCShBVklGSUxFLjEyMykKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyQShMUFNUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgTFBXU1RSICB3c3pGaWx0ZXI7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWQpXG4iLCBzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChjYkZpbHRlciA8IDIpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIHN6RmlsdGVyWzBdID0gMDsKICBzekZpbHRlclsxXSA9IDA7CgogIHdzekZpbHRlciA9IChMUFdTVFIpR2xvYmFsQWxsb2NQdHIoR0hORCwgY2JGaWx0ZXIgKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaHIgPSBBVklCdWlsZEZpbHRlclcod3N6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCB3c3pGaWx0ZXIsIGNiRmlsdGVyLAoJCQlzekZpbHRlciwgY2JGaWx0ZXIsIE5VTEwsIE5VTEwpOwogIH0KCiAgR2xvYmFsRnJlZVB0cih3c3pGaWx0ZXIpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXJXCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyVyhMUFdTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsc2lkW10gPSB7J0MnLCdMJywnUycsJ0knLCdEJywwfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pFeHRlbnNpb25GbXRbXSA9IHsnOycsJyonLCcuJywnJScsJ3MnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFWSUZpbGVFeHRlbnNpb25zW10gPQogICAgeydBJywnVicsJ0knLCdGJywnaScsJ2wnLCdlJywnXFwnLCdFJywneCcsJ3QnLCdlJywnbicsJ3MnLCdpJywnbycsJ24nLCdzJywwfTsKCiAgQVZJRmlsdGVyICpscDsKICBXQ0hBUiAgICAgIHN6QWxsRmlsZXNbNDBdOwogIFdDSEFSICAgICAgc3pGaWxlRXh0WzEwXTsKICBXQ0hBUiAgICAgIHN6VmFsdWVbMTI4XTsKICBIS0VZICAgICAgIGhLZXk7CiAgRFdPUkQgICAgICBuLCBpOwogIExPTkcgICAgICAgc2l6ZTsKICBEV09SRCAgICAgIGNvdW50ID0gMDsKCiAgVFJBQ0UoIiglcCwlbGQsJWQpXG4iLCBzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChjYkZpbHRlciA8IDIpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGxwID0gKEFWSUZpbHRlciopR2xvYmFsQWxsb2NQdHIoR0hORCwgTUFYX0ZJTFRFUlMgKiBzaXplb2YoQVZJRmlsdGVyKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyoKICAgKiAxLiBpdGVyYXRlIG92ZXIgSEtFWV9DTEFTU0VTX1JPT1RcXEFWSUZpbGVcXEV4dGVuc2lvbnMgYW5kIGNvbGxlY3QKICAgKiAgICBleHRlbnNpb25zIGFuZCBDTFNJRCdzCiAgICogMi4gaXRlcmF0ZSBvdmVyIGNvbGxlY3RlZCBDTFNJRCdzIGFuZCBjb3B5IGl0J3MgZGVzY3JpcHRpb24gYW5kIGl0J3MKICAgKiAgICBleHRlbnNpb25zIHRvIHN6RmlsdGVyIGlmIGl0IGZpdHMKICAgKgogICAqIEZpcnN0IGZpbHRlciBpcyBuYW1lZCAiQWxsIG11bHRpbWVkaWEgZmlsZXMiIGFuZCBpdCdzIGZpbHRlciBpcyBhCiAgICogY29sbGVjdGlvbiBvZiBhbGwgcG9zc2libGUgZXh0ZW5zaW9ucyBleGNlcHQgIiouKiIuCiAgICovCiAgaWYgKFJlZ09wZW5LZXlXKEhLRVlfQ0xBU1NFU19ST09ULCBzekFWSUZpbGVFeHRlbnNpb25zLCAmaEtleSkgIT0gU19PSykgewogICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIH0KICBmb3IgKG4gPSAwO1JlZ0VudW1LZXlXKGhLZXksIG4sIHN6RmlsZUV4dCwgc2l6ZW9mKHN6RmlsZUV4dCkpID09IFNfT0s7bisrKSB7CiAgICAvKiBnZXQgQ0xTSUQgdG8gZXh0ZW5zaW9uICovCiAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpL3NpemVvZihzelZhbHVlWzBdKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBzekZpbGVFeHQsIHN6VmFsdWUsICZzaXplKSAhPSBTX09LKQogICAgICBicmVhazsKCiAgICAvKiBzZWFyY2ggaWYgdGhlIENMU0lEIGlzIGFscmVhZHkga25vd24gKi8KICAgIGZvciAoaSA9IDE7IGkgPD0gY291bnQ7IGkrKykgewogICAgICBpZiAobHN0cmNtcFcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSkgPT0gMCkKCWJyZWFrOyAvKiBhIG5ldyBvbmUgKi8KICAgIH0KCiAgICBpZiAoY291bnQgLSBpID09IC0xVSkgewogICAgICAvKiBpdCdzIGEgbmV3IENMU0lEICovCgogICAgICAvKiBGSVhNRTogSG93IGRvIHdlIGdldCBpbmZvJ3MgYWJvdXQgcmVhZC93cml0ZSBjYXBhYmlsaXRpZXM/ICovCgogICAgICBpZiAoY291bnQgPj0gTUFYX0ZJTFRFUlMpIHsKCS8qIHRyeSB0byBpbmZvcm0gdXNlciBvZiBvdXIgZnVsbCBmaXhlZCBzaXplIHRhYmxlICovCglFUlIoIjogTW9yZSB0aGFuICVkIGZpbHRlcnMgZm91bmQhIEFkanVzdCBNQVhfRklMVEVSUyBpbiBkbGxzL2F2aWZpbDMyL2FwaS5jXG4iLCBNQVhfRklMVEVSUyk7CglicmVhazsKICAgICAgfQoKICAgICAgbHN0cmNweVcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSk7CgogICAgICBjb3VudCsrOwogICAgfQoKICAgIC8qIGFwcGVuZCBleHRlbnNpb24gdG8gdGhlIGZpbHRlciAqLwogICAgd3NwcmludGZXKHN6VmFsdWUsIHN6RXh0ZW5zaW9uRm10LCBzekZpbGVFeHQpOwogICAgaWYgKGxwW2ldLnN6RXh0ZW5zaW9uc1swXSA9PSAwKQogICAgICBsc3RyY2F0VyhscFtpXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUgKyAxKTsKICAgIGVsc2UKICAgICAgbHN0cmNhdFcobHBbaV0uc3pFeHRlbnNpb25zLCBzelZhbHVlKTsKCiAgICAvKiBhbHNvIGFwcGVuZCB0byB0aGUgImFsbCBtdWx0aW1lZGlhIi1maWx0ZXIgKi8KICAgIGlmIChscFswXS5zekV4dGVuc2lvbnNbMF0gPT0gMCkKICAgICAgbHN0cmNhdFcobHBbMF0uc3pFeHRlbnNpb25zLCBzelZhbHVlICsgMSk7CiAgICBlbHNlCiAgICAgIGxzdHJjYXRXKGxwWzBdLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSk7CiAgfQogIFJlZ0Nsb3NlS2V5KGhLZXkpOwoKICAvKiAyLiBnZXQgZGVzY3JpcHRpb25zIGZvciB0aGUgQ0xTSURzIGFuZCBmaWxsIG91dCBzekZpbHRlciAqLwogIGlmIChSZWdPcGVuS2V5VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pDbHNpZCwgJmhLZXkpICE9IFNfT0spIHsKICAgIEdsb2JhbEZyZWVQdHIobHApOwogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICB9CiAgZm9yIChuID0gMDsgbiA8PSBjb3VudDsgbisrKSB7CiAgICAvKiBmaXJzdCB0aGUgZGVzY3JpcHRpb24gKi8KICAgIGlmIChuICE9IDApIHsKICAgICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKS9zaXplb2Yoc3pWYWx1ZVswXSk7CiAgICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBscFtuXS5zekNsc2lkLCBzelZhbHVlLCAmc2l6ZSkgPT0gU19PSykgewoJc2l6ZSA9IGxzdHJsZW5XKHN6VmFsdWUpOwoJbHN0cmNweW5XKHN6RmlsdGVyLCBzelZhbHVlLCBjYkZpbHRlcik7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLElEU19BTExNVUxUSU1FRElBLHN6RmlsdGVyLGNiRmlsdGVyKTsKCiAgICAvKiBjaGVjayBmb3IgZW5vdWdoIHNwYWNlICovCiAgICBzaXplKys7CiAgICBpZiAoY2JGaWx0ZXIgPCBzaXplICsgbHN0cmxlblcobHBbbl0uc3pFeHRlbnNpb25zKSArIDIpIHsKICAgICAgc3pGaWx0ZXJbMF0gPSAwOwogICAgICBzekZpbHRlclsxXSA9IDA7CiAgICAgIEdsb2JhbEZyZWVQdHIobHApOwogICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgIH0KICAgIGNiRmlsdGVyIC09IHNpemU7CiAgICBzekZpbHRlciArPSBzaXplOwoKICAgIC8qIGFuZCB0aGVuIHRoZSBmaWx0ZXIgKi8KICAgIGxzdHJjcHluVyhzekZpbHRlciwgbHBbbl0uc3pFeHRlbnNpb25zLCBjYkZpbHRlcik7CiAgICBzaXplID0gbHN0cmxlblcobHBbbl0uc3pFeHRlbnNpb25zKSArIDE7CiAgICBjYkZpbHRlciAtPSBzaXplOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKICB9CgogIFJlZ0Nsb3NlS2V5KGhLZXkpOwogIEdsb2JhbEZyZWVQdHIobHApOwoKICAvKiBhZGQgIkFsbCBmaWxlcyIgIiouKiIgZmlsdGVyIGlmIGVub3VnaCBzcGFjZSBsZWZ0ICovCiAgc2l6ZSA9IExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FMTEZJTEVTLAoJCSAgICAgc3pBbGxGaWxlcywgc2l6ZW9mKHN6QWxsRmlsZXMpKSArIDE7CiAgaWYgKGNiRmlsdGVyID4gc2l6ZSkgewogICAgaW50IGk7CgogICAgLyogcmVwbGFjZSAnQCcgd2l0aCBcMDAwIHRvIHNlcGFyYXRlIGRlc2NyaXB0aW9uIG9mIGZpbHRlciAqLwogICAgZm9yIChpID0gMDsgaSA8IHNpemUgJiYgc3pBbGxGaWxlc1tpXSAhPSAwOyBpKyspIHsKICAgICAgaWYgKHN6QWxsRmlsZXNbaV0gPT0gJ0AnKSB7CglzekFsbEZpbGVzW2ldID0gMDsKCWJyZWFrOwogICAgICB9CiAgICB9CiAgICAgIAogICAgbWVtY3B5KHN6RmlsdGVyLCBzekFsbEZpbGVzLCBzaXplICogc2l6ZW9mKHN6QWxsRmlsZXNbMF0pKTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgICBzekZpbHRlclswXSA9IDA7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgc3pGaWx0ZXJbMF0gPSAwOwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9Cn0KCnN0YXRpYyBCT09MIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKEhXTkQgaFduZCkKewogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBPcHRpb25zID0gU2F2ZU9wdHMucHBPcHRpb25zW1NhdmVPcHRzLm5DdXJyZW50XTsKICBBVklTVFJFQU1JTkZPVyAgICAgICBzSW5mbzsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBpZiAocE9wdGlvbnMgPT0gTlVMTCB8fCBTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgc3RhdGUhXG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmIChGQUlMRUQoQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJICAgICZzSW5mbywgc2l6ZW9mKHNJbmZvKSkpKSB7CiAgICBFUlIoIjogQVZJU3RyZWFtSW5mb1cgZmFpbGVkIVxuIik7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgIENPTVBWQVJTIGN2OwogICAgQk9PTCAgICAgcmV0OwoKICAgIG1lbXNldCgmY3YsIDAsIHNpemVvZihjdikpOwoKICAgIGlmICgocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfVkFMSUQpID09IDApIHsKICAgICAgbWVtc2V0KHBPcHRpb25zLCAwLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICAgIHBPcHRpb25zLT5mY2NUeXBlICAgID0gc3RyZWFtdHlwZVZJREVPOwogICAgICBwT3B0aW9ucy0+ZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwogICAgICBwT3B0aW9ucy0+ZHdRdWFsaXR5ICA9IChEV09SRClJQ1FVQUxJVFlfREVGQVVMVDsKICAgIH0KCiAgICBjdi5jYlNpemUgICAgID0gc2l6ZW9mKGN2KTsKICAgIGN2LmR3RmxhZ3MgICAgPSBJQ01GX0NPTVBWQVJTX1ZBTElEOwogICAgLypjdi5mY2NUeXBlICAgID0gcE9wdGlvbnMtPmZjY1R5cGU7ICovCiAgICBjdi5mY2NIYW5kbGVyID0gcE9wdGlvbnMtPmZjY0hhbmRsZXI7CiAgICBjdi5sUSAgICAgICAgID0gcE9wdGlvbnMtPmR3UXVhbGl0eTsKICAgIGN2LmxwU3RhdGUgICAgPSBwT3B0aW9ucy0+bHBQYXJtczsKICAgIGN2LmNiU3RhdGUgICAgPSBwT3B0aW9ucy0+Y2JQYXJtczsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9LRVlGUkFNRVMpCiAgICAgIGN2LmxLZXkgPSBwT3B0aW9ucy0+ZHdLZXlGcmFtZUV2ZXJ5OwogICAgZWxzZQogICAgICBjdi5sS2V5ID0gMDsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9EQVRBUkFURSkKICAgICAgY3YubERhdGFSYXRlID0gcE9wdGlvbnMtPmR3Qnl0ZXNQZXJTZWNvbmQgLyAxMDI0OyAvKiBuZWVkIGtCeXRlcyAqLwogICAgZWxzZQogICAgICBjdi5sRGF0YVJhdGUgPSAwOwoKICAgIHJldCA9IElDQ29tcHJlc3NvckNob29zZShoV25kLCBTYXZlT3B0cy51RmxhZ3MsIE5VTEwsCgkJCSAgICAgU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJmN2LCBOVUxMKTsKCiAgICBpZiAocmV0KSB7CiAgICAgIHBPcHRpb25zLT5mY2NIYW5kbGVyID0gY3YuZmNjSGFuZGxlcjsKICAgICAgcE9wdGlvbnMtPmxwUGFybXMgICA9IGN2LmxwU3RhdGU7CiAgICAgIHBPcHRpb25zLT5jYlBhcm1zICAgPSBjdi5jYlN0YXRlOwogICAgICBwT3B0aW9ucy0+ZHdRdWFsaXR5ID0gY3YubFE7CiAgICAgIGlmIChjdi5sS2V5ICE9IDApIHsKCXBPcHRpb25zLT5kd0tleUZyYW1lRXZlcnkgPSBjdi5sS2V5OwoJcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0tFWUZSQU1FUzsKICAgICAgfSBlbHNlCglwT3B0aW9ucy0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0tFWUZSQU1FUzsKICAgICAgaWYgKGN2LmxEYXRhUmF0ZSAhPSAwKSB7CglwT3B0aW9ucy0+ZHdCeXRlc1BlclNlY29uZCA9IGN2LmxEYXRhUmF0ZSAqIDEwMjQ7IC8qIG5lZWQgYnl0ZXMgKi8KCXBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9EQVRBUkFURTsKICAgICAgfSBlbHNlCglwT3B0aW9ucy0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0RBVEFSQVRFOwogICAgICBwT3B0aW9ucy0+ZHdGbGFncyAgfD0gQVZJQ09NUFJFU1NGX1ZBTElEOwogICAgfQogICAgSUNDb21wcmVzc29yRnJlZSgmY3YpOwoKICAgIHJldHVybiByZXQ7CiAgfSBlbHNlIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewogICAgQUNNRk9STUFUQ0hPT1NFVyBhZm10YzsKICAgIE1NUkVTVUxUICAgICAgICAgcmV0OwogICAgTE9ORyAgICAgICAgICAgICBzaXplOwoKICAgIC8qIEZJWE1FOiBjaGVjayBBQ00gdmVyc2lvbiAtLSBXaGljaCB2ZXJzaW9uIGlzIG5lZWRlZD8gKi8KCiAgICBtZW1zZXQoJmFmbXRjLCAwLCBzaXplb2YoYWZtdGMpKTsKICAgIGFmbXRjLmNiU3RydWN0ICA9IHNpemVvZihhZm10Yyk7CiAgICBhZm10Yy5mZHdTdHlsZSAgPSAwOwogICAgYWZtdGMuaHduZE93bmVyID0gaFduZDsKCiAgICBhY21NZXRyaWNzKE5VTEwsIEFDTV9NRVRSSUNfTUFYX1NJWkVfRk9STUFULCAmc2l6ZSk7CiAgICBpZiAoKHBPcHRpb25zLT5jYkZvcm1hdCA9PSAwIHx8IHBPcHRpb25zLT5scEZvcm1hdCA9PSBOVUxMKSAmJiBzaXplICE9IDApIHsKICAgICAgcE9wdGlvbnMtPmxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgc2l6ZSk7CiAgICAgIHBPcHRpb25zLT5jYkZvcm1hdCA9IHNpemU7CiAgICB9IGVsc2UgaWYgKHBPcHRpb25zLT5jYkZvcm1hdCA8IChEV09SRClzaXplKSB7CiAgICAgIHBPcHRpb25zLT5scEZvcm1hdCA9IEdsb2JhbFJlQWxsb2NQdHIocE9wdGlvbnMtPmxwRm9ybWF0LCBzaXplLCBHTUVNX01PVkVBQkxFKTsKICAgICAgcE9wdGlvbnMtPmNiRm9ybWF0ID0gc2l6ZTsKICAgIH0KICAgIGlmIChwT3B0aW9ucy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwogICAgYWZtdGMucHdmeCAgPSBwT3B0aW9ucy0+bHBGb3JtYXQ7CiAgICBhZm10Yy5jYndmeCA9IHBPcHRpb25zLT5jYkZvcm1hdDsKCiAgICBzaXplID0gMDsKICAgIEFWSVN0cmVhbUZvcm1hdFNpemUoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJc0luZm8uZHdTdGFydCwgJnNpemUpOwogICAgaWYgKHNpemUgPCAoTE9ORylzaXplb2YoUENNV0FWRUZPUk1BVCkpCiAgICAgIHNpemUgPSBzaXplb2YoUENNV0FWRUZPUk1BVCk7CiAgICBhZm10Yy5wd2Z4RW51bSA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUpOwogICAgaWYgKGFmbXRjLnB3ZnhFbnVtICE9IE5VTEwpIHsKICAgICAgQVZJU3RyZWFtUmVhZEZvcm1hdChTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgIHNJbmZvLmR3U3RhcnQsIGFmbXRjLnB3ZnhFbnVtLCAmc2l6ZSk7CiAgICAgIGFmbXRjLmZkd0VudW0gPSBBQ01fRk9STUFURU5VTUZfQ09OVkVSVDsKICAgIH0KCiAgICByZXQgPSBhY21Gb3JtYXRDaG9vc2VXKCZhZm10Yyk7CiAgICBpZiAocmV0ID09IFNfT0spCiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9WQUxJRDsKCiAgICBpZiAoYWZtdGMucHdmeEVudW0gIT0gTlVMTCkKICAgICAgR2xvYmFsRnJlZVB0cihhZm10Yy5wd2Z4RW51bSk7CgogICAgcmV0dXJuIChyZXQgPT0gU19PSyA/IFRSVUUgOiBGQUxTRSk7CiAgfSBlbHNlIHsKICAgIEVSUigiOiB1bmtub3duIHN0cmVhbXR5cGUgMHglMDhsWFxuIiwgc0luZm8uZmNjVHlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQp9CgpzdGF0aWMgdm9pZCBBVklTYXZlT3B0aW9uc1VwZGF0ZShIV05EIGhXbmQpCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pWaWRlb0ZtdFtdPXsnJScsJ2wnLCdkJywneCcsJyUnLCdsJywnZCcsJ3gnLCclJywnZCcsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QXVkaW9GbXRbXT17JyUnLCdzJywnICcsJyUnLCdzJywwfTsKCiAgV0NIQVIgICAgICAgICAgc3pGb3JtYXRbMTI4XTsKICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKICBMUFZPSUQgICAgICAgICBscEZvcm1hdDsKICBMT05HICAgICAgICAgICBzaXplOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIFNhdmVPcHRzLm5DdXJyZW50ID0gU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLElEQ19TVFJFQU0sQ0JfR0VUQ1VSU0VMLDAsMCk7CiAgaWYgKFNhdmVPcHRzLm5DdXJyZW50IDwgMCkKICAgIHJldHVybjsKCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLCAmc0luZm8sIHNpemVvZihzSW5mbykpKSkKICAgIHJldHVybjsKCiAgQVZJU3RyZWFtRm9ybWF0U2l6ZShTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLHNJbmZvLmR3U3RhcnQsJnNpemUpOwogIGlmIChzaXplID4gMCkgewogICAgc3pGb3JtYXRbMF0gPSAwOwoKICAgIC8qIHJlYWQgZm9ybWF0IHRvIGJ1aWxkIGZvcm1hdCBkZXNjcmlvdGlvbiBzdHJpbmcgKi8KICAgIGxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgc2l6ZSk7CiAgICBpZiAobHBGb3JtYXQgIT0gTlVMTCkgewogICAgICBpZiAoU1VDQ0VFREVEKEFWSVN0cmVhbVJlYWRGb3JtYXQoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSxzSW5mby5kd1N0YXJ0LGxwRm9ybWF0LCAmc2l6ZSkpKSB7CglpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKCSAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSBscEZvcm1hdDsKCSAgSUNJTkZPIGljaW5mbzsKCgkgIHdzcHJpbnRmVyhzekZvcm1hdCwgc3pWaWRlb0ZtdCwgbHBiaS0+YmlXaWR0aCwKCQkgICAgbHBiaS0+YmlIZWlnaHQsIGxwYmktPmJpQml0Q291bnQpOwoKCSAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCKSB7CgkgICAgSElDICAgIGhpYzsKCgkgICAgaGljID0gSUNMb2NhdGUoSUNUWVBFX1ZJREVPLCBzSW5mby5mY2NIYW5kbGVyLCBscEZvcm1hdCwKCQkJICAgTlVMTCwgSUNNT0RFX0RFQ09NUFJFU1MpOwoJICAgIGlmIChoaWMgIT0gTlVMTCkgewoJICAgICAgaWYgKElDR2V0SW5mbyhoaWMsICZpY2luZm8sIHNpemVvZihpY2luZm8pKSA9PSBTX09LKQoJCWxzdHJjYXRXKHN6Rm9ybWF0LCBpY2luZm8uc3pEZXNjcmlwdGlvbik7CgkgICAgICBJQ0Nsb3NlKGhpYyk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1VOQ09NUFJFU1NFRCwKCQkJaWNpbmZvLnN6RGVzY3JpcHRpb24sIHNpemVvZihpY2luZm8uc3pEZXNjcmlwdGlvbikpOwoJICAgIGxzdHJjYXRXKHN6Rm9ybWF0LCBpY2luZm8uc3pEZXNjcmlwdGlvbik7CgkgIH0KCX0gZWxzZSBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKCSAgQUNNRk9STUFUVEFHREVUQUlMU1cgYWZ0ZDsKCSAgQUNNRk9STUFUREVUQUlMU1cgICAgYWZkOwoKCSAgbWVtc2V0KCZhZnRkLCAwLCBzaXplb2YoYWZ0ZCkpOwoJICBtZW1zZXQoJmFmZCwgMCwgc2l6ZW9mKGFmZCkpOwoKCSAgYWZ0ZC5jYlN0cnVjdCAgICAgPSBzaXplb2YoYWZ0ZCk7CgkgIGFmdGQuZHdGb3JtYXRUYWcgID0gYWZkLmR3Rm9ybWF0VGFnID0KCSAgICAoKFBXQVZFRk9STUFURVgpbHBGb3JtYXQpLT53Rm9ybWF0VGFnOwoJICBhZnRkLmNiRm9ybWF0U2l6ZSA9IGFmZC5jYndmeCA9IHNpemU7CgoJICBhZmQuY2JTdHJ1Y3QgICAgICA9IHNpemVvZihhZmQpOwoJICBhZmQucHdmeCAgICAgICAgICA9IGxwRm9ybWF0OwoKCSAgaWYgKGFjbUZvcm1hdFRhZ0RldGFpbHNXKE5VTEwsICZhZnRkLAoJCQkJICAgQUNNX0ZPUk1BVFRBR0RFVEFJTFNGX0ZPUk1BVFRBRykgPT0gU19PSykgewoJICAgIGlmIChhY21Gb3JtYXREZXRhaWxzVyhOVUxMLCZhZmQsQUNNX0ZPUk1BVERFVEFJTFNGX0ZPUk1BVCkgPT0gU19PSykKCSAgICAgIHdzcHJpbnRmVyhzekZvcm1hdCwgc3pBdWRpb0ZtdCwgYWZkLnN6Rm9ybWF0LCBhZnRkLnN6Rm9ybWF0VGFnKTsKCSAgfQoJfQogICAgICB9CiAgICAgIEdsb2JhbEZyZWVQdHIobHBGb3JtYXQpOwogICAgfQoKICAgIC8qIHNldCB0ZXh0IGZvciBmb3JtYXQgZGVzY3JpcHRpb24gKi8KICAgIFNldERsZ0l0ZW1UZXh0VyhoV25kLCBJRENfRk9STUFUVEVYVCwgc3pGb3JtYXQpOwoKICAgIC8qIERpc2FibGUgb3B0aW9uIGJ1dHRvbiBmb3IgdW5zdXBwb3J0ZWQgc3RyZWFtdHlwZXMgKi8KICAgIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTyB8fAoJc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19PUFRJT05TKSwgVFJVRSk7CiAgICBlbHNlCiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19PUFRJT05TKSwgRkFMU0UpOwogIH0KCn0KCklOVF9QVFIgQ0FMTEJBQ0sgQVZJU2F2ZU9wdGlvbnNEbGdQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLAoJCQkJICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICBEV09SRCBkd0ludGVybGVhdmU7CiAgQk9PTCAgYklzSW50ZXJsZWF2ZWQ7CiAgSU5UICAgbjsKCiAgLypUUkFDRSgiKCVwLCV1LDB4JTA0WCwweCUwOGxYKVxuIiwgaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOyovCgogIHN3aXRjaCAodU1zZykgewogIGNhc2UgV01fSU5JVERJQUxPRzoKICAgIFNhdmVPcHRzLm5DdXJyZW50ID0gMDsKICAgIGlmIChTYXZlT3B0cy5uU3RyZWFtcyA9PSAxKSB7CiAgICAgIEVuZERpYWxvZyhoV25kLCBBVklTYXZlT3B0aW9uc0ZtdENob29zZShoV25kKSk7CiAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIC8qIGFkZCBzdHJlYW1zICovCiAgICBmb3IgKG4gPSAwOyBuIDwgU2F2ZU9wdHMublN0cmVhbXM7IG4rKykgewogICAgICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKCiAgICAgIEFWSVN0cmVhbUluZm9XKFNhdmVPcHRzLnBwYXZpc1tuXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICAgICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLCBJRENfU1RSRUFNLCBDQl9BRERTVFJJTkcsCgkJCSAgMEwsIChMUEFSQU0pc0luZm8uc3pOYW1lKTsKICAgIH0KCiAgICAvKiBzZWxlY3QgZmlyc3Qgc3RyZWFtICovCiAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsIElEQ19TVFJFQU0sIENCX1NFVENVUlNFTCwgMCwgMCk7CiAgICBTZW5kTWVzc2FnZVcoaFduZCwgV01fQ09NTUFORCwKCQkgR0VUX1dNX0NPTU1BTkRfTVBTKElEQ19TVFJFQU0sIGhXbmQsIENCTl9TRUxDSEFOR0UpKTsKCiAgICAvKiBpbml0aWFsaXplIGludGVybGVhdmUgKi8KICAgIGlmIChTYXZlT3B0cy5wcE9wdGlvbnNbMF0gIT0gTlVMTCAmJgoJKFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkpIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSAoU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkUpOwogICAgICBkd0ludGVybGVhdmUgPSBTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3SW50ZXJsZWF2ZUV2ZXJ5OwogICAgfSBlbHNlIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSBUUlVFOwogICAgICBkd0ludGVybGVhdmUgICA9IDA7CiAgICB9CiAgICBDaGVja0RsZ0J1dHRvbihoV25kLCBJRENfSU5URVJMRUFWRSwgYklzSW50ZXJsZWF2ZWQpOwogICAgU2V0RGxnSXRlbUludChoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZLCBkd0ludGVybGVhdmUsIEZBTFNFKTsKICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlkpLCBiSXNJbnRlcmxlYXZlZCk7CiAgICBicmVhazsKICBjYXNlIFdNX0NPTU1BTkQ6CiAgICBzd2l0Y2ggKEdFVF9XTV9DT01NQU5EX0lEKHdQYXJhbSwgbFBhcmFtKSkgewogICAgY2FzZSBJRE9LOgogICAgICAvKiBnZXQgZGF0YSBmcm9tIGNvbnRyb2xzIGFuZCBzYXZlIHRoZW0gKi8KICAgICAgZHdJbnRlcmxlYXZlICAgPSBHZXREbGdJdGVtSW50KGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlksIE5VTEwsIDApOwogICAgICBiSXNJbnRlcmxlYXZlZCA9IElzRGxnQnV0dG9uQ2hlY2tlZChoV25kLCBJRENfSU5URVJMRUFWRSk7CiAgICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CglpZiAoU2F2ZU9wdHMucHBPcHRpb25zW25dICE9IE5VTEwpIHsKCSAgaWYgKGJJc0ludGVybGVhdmVkKSB7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFOwoJICAgIFNhdmVPcHRzLnBwT3B0aW9uc1tuXS0+ZHdJbnRlcmxlYXZlRXZlcnkgPSBkd0ludGVybGVhdmU7CgkgIH0gZWxzZQoJICAgIFNhdmVPcHRzLnBwT3B0aW9uc1tuXS0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7Cgl9CiAgICAgIH0KICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIElEQ0FOQ0VMOgogICAgICBFbmREaWFsb2coaFduZCwgR0VUX1dNX0NPTU1BTkRfSUQod1BhcmFtLCBsUGFyYW0pID09IElET0spOwogICAgICBicmVhazsKICAgIGNhc2UgSURDX0lOVEVSTEVBVkU6CiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlkpLAoJCSAgIElzRGxnQnV0dG9uQ2hlY2tlZChoV25kLCBJRENfSU5URVJMRUFWRSkpOwogICAgICBicmVhazsKICAgIGNhc2UgSURDX1NUUkVBTToKICAgICAgaWYgKEdFVF9XTV9DT01NQU5EX0NNRCh3UGFyYW0sIGxQYXJhbSkgPT0gQ0JOX1NFTENIQU5HRSkgewoJLyogdXBkYXRlIGNvbnRyb2wgZWxlbWVudHMgKi8KCUFWSVNhdmVPcHRpb25zVXBkYXRlKGhXbmQpOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBJRENfT1BUSU9OUzoKICAgICAgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoaFduZCk7CiAgICAgIGJyZWFrOwogICAgfTsKICAgIHJldHVybiBUUlVFOwogIH07CgogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTYXZlT3B0aW9ucwkJKEFWSUZJTDMyLkApCiAqLwpCT09MIFdJTkFQSSBBVklTYXZlT3B0aW9ucyhIV05EIGhXbmQsIFVJTlQgdUZsYWdzLCBJTlQgblN0cmVhbXMsCgkJCSAgIFBBVklTVFJFQU0gKnBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcHBPcHRpb25zKQp7CiAgTFBBVklDT01QUkVTU09QVElPTlMgcFNhdmVkT3B0aW9ucyA9IE5VTEw7CiAgSU5UIHJldCwgbjsKCiAgVFJBQ0UoIiglcCwweCVYLCVkLCVwLCVwKVxuIiwgaFduZCwgdUZsYWdzLCBuU3RyZWFtcywKCXBwYXZpLCBwcE9wdGlvbnMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKG5TdHJlYW1zIDw9IDAgfHwgcHBhdmkgPT0gTlVMTCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIHNhdmUgb3B0aW9ucyBmb3IgY2FzZSB1c2VyIHByZXNzIGNhbmNlbCAqLwogIGlmIChwcE9wdGlvbnMgIT0gTlVMTCAmJiBuU3RyZWFtcyA+IDEpIHsKICAgIHBTYXZlZE9wdGlvbnMgPSBHbG9iYWxBbGxvY1B0cihHSE5ELG5TdHJlYW1zICogc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgaWYgKHBTYXZlZE9wdGlvbnMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CiAgICAgIGlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCW1lbWNweShwU2F2ZWRPcHRpb25zICsgbiwgcHBPcHRpb25zW25dLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICB9CiAgfQoKICBTYXZlT3B0cy51RmxhZ3MgICAgPSB1RmxhZ3M7CiAgU2F2ZU9wdHMublN0cmVhbXMgID0gblN0cmVhbXM7CiAgU2F2ZU9wdHMucHBhdmlzICAgID0gcHBhdmk7CiAgU2F2ZU9wdHMucHBPcHRpb25zID0gcHBPcHRpb25zOwoKICByZXQgPSBEaWFsb2dCb3hXKEFWSUZJTEVfaE1vZHVsZSwgTUFLRUlOVFJFU09VUkNFVyhJRERfU0FWRU9QVElPTlMpLAoJCSAgIGhXbmQsIEFWSVNhdmVPcHRpb25zRGxnUHJvYyk7CgogIGlmIChyZXQgPT0gLTEpCiAgICByZXQgPSBGQUxTRTsKCiAgLyogcmVzdG9yZSBvcHRpb25zIHdoZW4gdXNlciBwcmVzc2VkIGNhbmNlbCAqLwogIGlmIChwU2F2ZWRPcHRpb25zICE9IE5VTEwpIHsKICAgIGlmIChyZXQgPT0gRkFMU0UpIHsKICAgICAgZm9yIChuID0gMDsgbiA8IG5TdHJlYW1zOyBuKyspIHsKCWlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCSAgbWVtY3B5KHBwT3B0aW9uc1tuXSwgcFNhdmVkT3B0aW9ucyArIG4sIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgfQogICAgfQogICAgR2xvYmFsRnJlZVB0cihwU2F2ZWRPcHRpb25zKTsKICB9CgogIHJldHVybiAoQk9PTClyZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZU9wdGlvbnNGcmVlCShBVklGSUwzMi5AKQogKgkJQVZJU2F2ZU9wdGlvbnNGcmVlCShBVklGSUxFLjEyNCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVPcHRpb25zRnJlZShJTlQgblN0cmVhbXMsTFBBVklDT01QUkVTU09QVElPTlMqcHBPcHRpb25zKQp7CiAgVFJBQ0UoIiglZCwlcClcbiIsIG5TdHJlYW1zLCBwcE9wdGlvbnMpOwoKICBpZiAoblN0cmVhbXMgPCAwIHx8IHBwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgZm9yICg7IG5TdHJlYW1zID4gMDsgblN0cmVhbXMtLSkgewogICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10gIT0gTlVMTCkgewogICAgICBwcE9wdGlvbnNbblN0cmVhbXNdLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfVkFMSUQ7CgogICAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyAhPSBOVUxMKSB7CglHbG9iYWxGcmVlUHRyKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMpOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyA9IE5VTEw7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5jYlBhcm1zID0gMDsKICAgICAgfQogICAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQgIT0gTlVMTCkgewoJR2xvYmFsRnJlZVB0cihwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCk7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCA9IE5VTEw7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5jYkZvcm1hdCA9IDA7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZVZBCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVWQShMUENTVFIgc3pGaWxlLCBDTFNJRCAqcGNsc2lkSGFuZGxlciwKCQkJIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssIGludCBuU3RyZWFtLAoJCQkgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwbHBPcHRpb25zKQp7CiAgTFBXU1RSICB3c3pGaWxlID0gTlVMTDsKICBIUkVTVUxUIGhyOwogIGludCAgICAgbGVuOwoKICBUUkFDRSgiJXMsJXAsJXAsJWQsJXAsJXApXG4iLCBkZWJ1Z3N0cl9hKHN6RmlsZSksIHBjbHNpZEhhbmRsZXIsCglscGZuQ2FsbGJhY2ssIG5TdHJlYW0sIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgaWYgKHN6RmlsZSA9PSBOVUxMIHx8IHBwYXZpID09IE5VTEwgfHwgcGxwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY29udmVydCBBU0NJSSBzdHJpbmcgdG8gVW5pY29kZSBhbmQgY2FsbCBVbmljb2RlIGZ1bmN0aW9uICovCiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIE5VTEwsIDApOwogIGlmIChsZW4gPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHdzekZpbGUgPSBMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogIGlmICh3c3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIHdzekZpbGUsIGxlbik7CgogIGhyID0gQVZJU2F2ZVZXKHdzekZpbGUsIHBjbHNpZEhhbmRsZXIsIGxwZm5DYWxsYmFjaywKCQkgblN0cmVhbSwgcHBhdmksIHBscE9wdGlvbnMpOwoKICBMb2NhbEZyZWUoKEhMT0NBTCl3c3pGaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZJTEVfQVZJU2F2ZURlZmF1bHRDYWxsYmFjawkoaW50ZXJuYWwpCiAqLwpzdGF0aWMgQk9PTCBXSU5BUEkgQVZJRklMRV9BVklTYXZlRGVmYXVsdENhbGxiYWNrKElOVCBwcm9ncmVzcykKewogIFRSQUNFKCIoJWQpXG4iLCBwcm9ncmVzcyk7CgogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTYXZlVlcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU2F2ZVZXKExQQ1dTVFIgc3pGaWxlLCBDTFNJRCAqcGNsc2lkSGFuZGxlciwKCQkJIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssIGludCBuU3RyZWFtcywKCQkJIFBBVklTVFJFQU0gKnBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcGxwT3B0aW9ucykKewogIExPTkcgICAgICAgICAgIGxTdGFydFtNQVhfQVZJU1RSRUFNU107CiAgUEFWSVNUUkVBTSAgICAgcE91dFN0cmVhbXNbTUFYX0FWSVNUUkVBTVNdOwogIFBBVklTVFJFQU0gICAgIHBJblN0cmVhbXNbTUFYX0FWSVNUUkVBTVNdOwogIEFWSUZJTEVJTkZPVyAgIGZJbmZvOwogIEFWSVNUUkVBTUlORk9XIHNJbmZvOwoKICBQQVZJRklMRSAgICAgICBwZmlsZSA9IE5VTEw7IC8qIHRoZSBvdXRwdXQgQVZJIGZpbGUgKi8KICBMT05HICAgICAgICAgICBsRmlyc3RWaWRlbyA9IC0xOwogIGludCAgICAgICAgICAgIGN1clN0cmVhbTsKCiAgLyogZm9yIGludGVybGVhdmluZyAuLi4gKi8KICBEV09SRCAgICAgICAgICBkd0ludGVybGVhdmUgPSAwOyAvKiBpbnRlcmxlYXZlIHJhdGUgKi8KICBEV09SRCAgICAgICAgICBkd0ZpbGVJbml0aWFsRnJhbWVzOwogIExPTkcgICAgICAgICAgIGxGaWxlTGVuZ3RoOwogIExPTkcgICAgICAgICAgIGxTYW1wbGVJbmM7CgogIC8qIGZvciByZWFkaW5nL3dyaXRpbmcgdGhlIGRhdGEgLi4uICovCiAgTFBWT0lEICAgICAgICAgbHBCdWZmZXIgPSBOVUxMOwogIExPTkcgICAgICAgICAgIGNiQnVmZmVyOyAgICAgICAgLyogcmVhbCBzaXplIG9mIGxwQnVmZmVyICovCiAgTE9ORyAgICAgICAgICAgbEJ1ZmZlclNpemU7ICAgICAvKiBuZWVkZWQgYnl0ZXMgZm9yIGZvcm1hdChzKSwgZXRjLiAqLwogIExPTkcgICAgICAgICAgIGxSZWFkQnl0ZXM7CiAgTE9ORyAgICAgICAgICAgbFJlYWRTYW1wbGVzOwogIEhSRVNVTFQgICAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXMsJXAsJXAsJWQsJXAsJXApXG4iLCBkZWJ1Z3N0cl93KHN6RmlsZSksIHBjbHNpZEhhbmRsZXIsCglscGZuQ2FsbGJhY2ssIG5TdHJlYW1zLCBwcGF2aSwgcGxwT3B0aW9ucyk7CgogIGlmIChzekZpbGUgPT0gTlVMTCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBscE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKG5TdHJlYW1zID49IE1BWF9BVklTVFJFQU1TKSB7CiAgICBXQVJOKCJDYW4ndCB3cml0ZSBBVkkgd2l0aCAlZCBzdHJlYW1zIG9ubHkgc3VwcG9ydHMgJWQgLS0gY2hhbmdlIE1BWF9BVklTVFJFQU1TIVxuIiwgblN0cmVhbXMsIE1BWF9BVklTVFJFQU1TKTsKICAgIHJldHVybiBBVklFUlJfSU5URVJOQUw7CiAgfQoKICBpZiAobHBmbkNhbGxiYWNrID09IE5VTEwpCiAgICBscGZuQ2FsbGJhY2sgPSBBVklGSUxFX0FWSVNhdmVEZWZhdWx0Q2FsbGJhY2s7CgogIC8qIGNsZWFyIGxvY2FsIHZhcmlhYmxlKHMpICovCiAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgIHBJblN0cmVhbXNbY3VyU3RyZWFtXSAgPSBOVUxMOwogICAgcE91dFN0cmVhbXNbY3VyU3RyZWFtXSA9IE5VTEw7CiAgfQoKICAvKiBvcGVuIG91dHB1dCBBVkkgZmlsZSAoY3JlYXRlIGl0IGlmIGl0IGRvZXNuJ3QgZXhpc3QpICovCiAgaHJlcyA9IEFWSUZpbGVPcGVuVygmcGZpbGUsIHN6RmlsZSwgT0ZfQ1JFQVRFfE9GX1NIQVJFX0VYQ0xVU0lWRXxPRl9XUklURSwKCQkgICAgICBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyZXMpKQogICAgcmV0dXJuIGhyZXM7CiAgQVZJRmlsZUluZm9XKHBmaWxlLCAmZkluZm8sIHNpemVvZihmSW5mbykpOyAvKiBmb3IgZHdDYXBzICovCgogIC8qIGluaXRpYWxpemUgb3VyIGRhdGEgc3RydWN0dXJlcyBwYXJ0IDEgKi8KICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgUEFWSVNUUkVBTSBwQ3VyU3RyZWFtID0gcHBhdmlbY3VyU3RyZWFtXTsKCiAgICBocmVzID0gQVZJU3RyZWFtSW5mb1cocEN1clN0cmVhbSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICAgIGlmIChGQUlMRUQoaHJlcykpCiAgICAgIGdvdG8gZXJyb3I7CgogICAgLyogc2VhcmNoIGZpcnN0IHZpZGVvIHN0cmVhbSBhbmQgY2hlY2sgZm9yIGludGVybGVhdmluZyAqLwogICAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIC8qIHJlbWVtYmVyIGZpcnN0IHZpZGVvIHN0cmVhbSAtLSBuZWVkZWQgZm9yIGludGVybGVhdmluZyAqLwogICAgICBpZiAobEZpcnN0VmlkZW8gPCAwKQoJbEZpcnN0VmlkZW8gPSBjdXJTdHJlYW07CiAgICB9IGVsc2UgaWYgKCFkd0ludGVybGVhdmUgJiYgcGxwT3B0aW9ucyAhPSBOVUxMKSB7CiAgICAgIC8qIGNoZWNrIGlmIGFueSBub24tdmlkZW8gc3RyZWFtIHdhbnRzIHRvIGJlIGludGVybGVhdmVkICovCiAgICAgIFdBUk4oIm9wdGlvbnMuZmxhZ3M9MHglbFggb3B0aW9ucy5kd0ludGVybGVhdmU9JWx1XG4iLHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdGbGFncyxwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3SW50ZXJsZWF2ZUV2ZXJ5KTsKICAgICAgaWYgKHBscE9wdGlvbnNbY3VyU3RyZWFtXSAhPSBOVUxMICYmCgkgIHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFKQoJZHdJbnRlcmxlYXZlID0gcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ludGVybGVhdmVFdmVyeTsKICAgIH0KCiAgICAvKiBjcmVhdGUgZGUtL2NvbXByZXNzZWQgc3RyZWFtIGludGVyZmFjZSBpZiBuZWVkZWQgKi8KICAgIHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IE5VTEw7CiAgICBpZiAocGxwT3B0aW9ucyAhPSBOVUxMICYmIHBscE9wdGlvbnNbY3VyU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAgIGlmIChwbHBPcHRpb25zW2N1clN0cmVhbV0tPmZjY0hhbmRsZXIgfHwKCSAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5scEZvcm1hdCAhPSBOVUxMKSB7CglEV09SRCBkd0tleVNhdmUgPSBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3S2V5RnJhbWVFdmVyeTsKCglpZiAoZkluZm8uZHdDYXBzICYgQVZJRklMRUNBUFNfQUxMS0VZRlJBTUVTKQoJICBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3S2V5RnJhbWVFdmVyeSA9IDE7CgoJaHJlcyA9IEFWSU1ha2VDb21wcmVzc2VkU3RyZWFtKCZwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHBDdXJTdHJlYW0sCgkJCQkgICAgICAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLCBOVUxMKTsKCXBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5ID0gZHdLZXlTYXZlOwoJaWYgKEZBSUxFRChocmVzKSB8fCBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPT0gTlVMTCkgewoJICBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPSBOVUxMOwoJICBnb3RvIGVycm9yOwoJfQoKCS8qIHRlc3Qgc3RyZWFtIGludGVyZmFjZSBhbmQgdXBkYXRlIHN0cmVhbS1pbmZvICovCglocmVzID0gQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgZ290byBlcnJvcjsKICAgICAgfQogICAgfQoKICAgIC8qIG5vdyBoYW5kbGUgc3RyZWFtcyB3aGljaCB3aWxsIG9ubHkgYmUgY29waWVkICovCiAgICBpZiAocEluU3RyZWFtc1tjdXJTdHJlYW1dID09IE5VTEwpIHsKICAgICAgcEN1clN0cmVhbSA9IHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IHBwYXZpW2N1clN0cmVhbV07CiAgICAgIEFWSVN0cmVhbUFkZFJlZihwQ3VyU3RyZWFtKTsKICAgIH0gZWxzZQogICAgICBwQ3VyU3RyZWFtID0gcEluU3RyZWFtc1tjdXJTdHJlYW1dOwoKICAgIGxTdGFydFtjdXJTdHJlYW1dID0gc0luZm8uZHdTdGFydDsKICB9IC8qIGZvciBhbGwgc3RyZWFtcyAqLwoKICAvKiBjaGVjayB0aGF0IGZpcnN0IHZpZGVvIHN0cmVhbSBpcyB0aGUgZmlyc3Qgc3RyZWFtICovCiAgaWYgKGxGaXJzdFZpZGVvID4gMCkgewogICAgUEFWSVNUUkVBTSBwVG1wID0gcEluU3RyZWFtc1tsRmlyc3RWaWRlb107CiAgICBMT05HIGxUbXAgPSBsU3RhcnRbbEZpcnN0VmlkZW9dOwoKICAgIHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dID0gcEluU3RyZWFtc1swXTsKICAgIHBJblN0cmVhbXNbMF0gPSBwVG1wOwogICAgbFN0YXJ0W2xGaXJzdFZpZGVvXSA9IGxTdGFydFswXTsKICAgIGxTdGFydFswXSA9IGxUbXA7CiAgICBsRmlyc3RWaWRlbyA9IDA7CiAgfQoKICAvKiBhbGxvY2F0ZSBidWZmZXIgZm9yIGZvcm1hdHMsIGRhdGEsIGV0Yy4gb2YgYW4gaW5pdGlhbGUgc2l6ZSBvZiA2NCBrQnl0ZSAqLwogIGxwQnVmZmVyID0gR2xvYmFsQWxsb2NQdHIoR1BUUiwgY2JCdWZmZXIgPSAweDAwMDEwMDAwKTsKICBpZiAobHBCdWZmZXIgPT0gTlVMTCkgewogICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CiAgICBnb3RvIGVycm9yOwogIH0KCiAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1swXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICBsRmlsZUxlbmd0aCA9IHNJbmZvLmR3TGVuZ3RoOwogIGR3RmlsZUluaXRpYWxGcmFtZXMgPSAwOwogIGlmIChsRmlyc3RWaWRlbyA+PSAwKSB7CiAgICAvKiBjaGVjayBmb3IgY29ycmVjdCB2ZXJzaW9uIG9mIHRoZSBmb3JtYXQKICAgICAqICAtLSBuZWVkIGF0bGVhc3QgQklUTUFQSU5GT0hFQURFUiBvciBuZXdlcgogICAgICovCiAgICBsU2FtcGxlSW5jID0gMTsKICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXSwgQVZJU3RyZWFtU3RhcnQocEluU3RyZWFtc1tsRmlyc3RWaWRlb10pLCBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgIGlmIChsQnVmZmVyU2l6ZSA8IChMT05HKXNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkKICAgICAgaHJlcyA9IEFWSUVSUl9JTlRFUk5BTDsKICAgIGlmIChGQUlMRUQoaHJlcykpCiAgICAgIGdvdG8gZXJyb3I7CiAgfSBlbHNlIC8qIHVzZSBvbmUgc2Vjb25kIGJsb2NrcyBmb3IgaW50ZXJsZWF2aW5nIGlmIG5vIHZpZGVvIHByZXNlbnQgKi8KICAgIGxTYW1wbGVJbmMgPSBBVklTdHJlYW1UaW1lVG9TYW1wbGUocEluU3RyZWFtc1swXSwgMTAwMDAwMCk7CgogIC8qIGNyZWF0ZSBvdXRwdXQgc3RyZWFtcyAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CgogICAgc0luZm8uZHdJbml0aWFsRnJhbWVzID0gMDsKICAgIGlmIChkd0ludGVybGVhdmUgIT0gMCAmJiBjdXJTdHJlYW0gPiAwICYmIHNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIC8qIDc1MCBtcyBpbml0aWFsIGZyYW1lcyBmb3Igbm9uLXZpZGVvIHN0cmVhbXMgKi8KICAgICAgc0luZm8uZHdJbml0aWFsRnJhbWVzID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKHBJblN0cmVhbXNbMF0sIDc1MCk7CiAgICB9CgogICAgaHJlcyA9IEFWSUZpbGVDcmVhdGVTdHJlYW1XKHBmaWxlLCAmcE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvKTsKICAgIGlmIChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwgJiYgU1VDQ0VFREVEKGhyZXMpKSB7CiAgICAgIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgZm9yIHRoaXMgc3RyZWFtICovCiAgICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJCSBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgICAgaWYgKEZBSUxFRChocmVzKSkKCWdvdG8gZXJyb3I7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgMCwgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKICAgICAgaWYgKEZBSUxFRChocmVzKSkKCWdvdG8gZXJyb3I7CgogICAgICAvKiB0cnkgdG8gY29weSBzdHJlYW0gaGFuZGxlciBkYXRhICovCiAgICAgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CiAgICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkRGF0YShwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGNraWRTVFJFQU1IQU5ETEVSREFUQSwKCQkJICAgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwogICAgICBpZiAoU1VDQ0VFREVEKGhyZXMpICYmIGxCdWZmZXJTaXplID4gMCkgewoJaHJlcyA9IEFWSVN0cmVhbVdyaXRlRGF0YShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLGNraWRTVFJFQU1IQU5ETEVSREFUQSwKCQkJCSAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGdvdG8gZXJyb3I7CiAgICAgIH0KCiAgICAgIGlmIChkd0ZpbGVJbml0aWFsRnJhbWVzIDwgc0luZm8uZHdJbml0aWFsRnJhbWVzKQoJZHdGaWxlSW5pdGlhbEZyYW1lcyA9IHNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgICAgbFJlYWRCeXRlcyA9CglBVklTdHJlYW1TYW1wbGVUb1NhbXBsZShwT3V0U3RyZWFtc1swXSwgcEluU3RyZWFtc1tjdXJTdHJlYW1dLAoJCQkJc0luZm8uZHdMZW5ndGgpOwogICAgICBpZiAobEZpbGVMZW5ndGggPCBsUmVhZEJ5dGVzKQoJbEZpbGVMZW5ndGggPSBsUmVhZEJ5dGVzOwogICAgfSBlbHNlIHsKICAgICAgLyogY3JlYXRpb24gb2YgZGUtL2NvbXByZXNzaW9uIHN0cmVhbSBpbnRlcmZhY2UgZmFpbGVkICovCiAgICAgIFdBUk4oImNyZWF0aW9uIG9mIChkZS0pY29tcHJlc3Npb24gc3RyZWFtIGZhaWxlZCBmb3Igc3RyZWFtICVkXG4iLGN1clN0cmVhbSk7CiAgICAgIEFWSVN0cmVhbVJlbGVhc2UocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKICAgICAgaWYgKGN1clN0cmVhbSArIDEgPj0gblN0cmVhbXMpIHsKCS8qIG1vdmUgdGhlIG90aGVycyBvbmUgdXAgKi8KCVBBVklTVFJFQU0gKnBwYXMgPSAmcEluU3RyZWFtc1tjdXJTdHJlYW1dOwoJaW50ICAgICAgICAgICAgbiA9IG5TdHJlYW1zIC0gKGN1clN0cmVhbSArIDEpOwoKCWRvIHsKCSAgKnBwYXMgPSBwSW5TdHJlYW1zW2N1clN0cmVhbSArIDFdOwoJfSB3aGlsZSAoLS1uKTsKICAgICAgfQogICAgICBuU3RyZWFtcy0tOwogICAgICBjdXJTdHJlYW0tLTsKICAgIH0KICB9IC8qIGNyZWF0ZSBvdXRwdXQgc3RyZWFtcyBmb3IgYWxsIGlucHV0IHN0cmVhbXMgKi8KCiAgLyogaGF2ZSB3ZSBzdGlsbCBzb21ldGhpbmcgdG8gd3JpdGUsIG9yIGxvc3QgZXZlcnl0aGluZz8gKi8KICBpZiAoblN0cmVhbXMgPD0gMCkKICAgIGdvdG8gZXJyb3I7CgogIGlmIChkd0ludGVybGVhdmUpIHsKICAgIExPTkcgbEN1ckZyYW1lID0gLWR3RmlsZUluaXRpYWxGcmFtZXM7CgogICAgLyogaW50ZXJsZWF2ZWQgZmlsZSAqLwogICAgaWYgKGR3SW50ZXJsZWF2ZSA9PSAxKQogICAgICBBVklGaWxlRW5kUmVjb3JkKHBmaWxlKTsKCiAgICBmb3IgKDsgbEN1ckZyYW1lIDwgbEZpbGVMZW5ndGg7IGxDdXJGcmFtZSArPSBsU2FtcGxlSW5jKSB7CiAgICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CglMT05HIGxMYXN0U2FtcGxlOwoKCWhyZXMgPSBBVklTdHJlYW1JbmZvVyhwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgZ290byBlcnJvcjsKCgkvKiBpbml0aWFsIGZyYW1lcyBwaGFzZSBhdCB0aGUgZW5kIGZvciB0aGlzIHN0cmVhbT8gKi8KCWlmICgtKExPTkcpc0luZm8uZHdJbml0aWFsRnJhbWVzID4gbEN1ckZyYW1lKQoJICBjb250aW51ZTsKCglpZiAoKGxGaWxlTGVuZ3RoIC0gbFNhbXBsZUluYykgPD0gbEN1ckZyYW1lKSB7CgkgIGxMYXN0U2FtcGxlID0gQVZJU3RyZWFtTGVuZ3RoKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CgkgIGxGaXJzdFZpZGVvID0gbExhc3RTYW1wbGUgKyBBVklTdHJlYW1TdGFydChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJfSBlbHNlIHsKCSAgaWYgKGN1clN0cmVhbSAhPSAwKSB7CgkgICAgbEZpcnN0VmlkZW8gPQoJICAgICAgQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBwSW5TdHJlYW1zWzBdLAoJCQkJICAgICAgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPID8gCgkJCQkgICAgICAgKExPTkcpZHdJbnRlcmxlYXZlIDogbFNhbXBsZUluYykgKwoJCQkJICAgICAgc0luZm8uZHdJbml0aWFsRnJhbWVzICsgbEN1ckZyYW1lKTsKCSAgfSBlbHNlCgkgICAgbEZpcnN0VmlkZW8gPSBsU2FtcGxlSW5jICsgKHNJbmZvLmR3SW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSk7CgoJICBsTGFzdFNhbXBsZSA9IEFWSVN0cmVhbUVuZChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJICBpZiAobExhc3RTYW1wbGUgPD0gbEZpcnN0VmlkZW8pCgkgICAgbEZpcnN0VmlkZW8gPSBsTGFzdFNhbXBsZTsKCX0KCgkvKiBjb3B5IG5lZWRlZCBzYW1wbGVzIG5vdyAqLwoJV0FSTigiY29weSBmcm9tIHN0cmVhbSAlZCBzYW1wbGVzICVsZCB0byAlbGQuLi5cbiIsY3VyU3RyZWFtLAoJICAgICAgbFN0YXJ0W2N1clN0cmVhbV0sbEZpcnN0VmlkZW8pOwoJd2hpbGUgKGxGaXJzdFZpZGVvID4gbFN0YXJ0W2N1clN0cmVhbV0pIHsKCSAgRFdPUkQgZmxhZ3MgPSAwOwoKCSAgLyogY29weSBmb3JtYXQgZm9yIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGxTdGFydFtjdXJTdHJlYW1dLAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgbFN0YXJ0W2N1clN0cmVhbV0sCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIHRyeSB0byByZWFkIGRhdGEgdW50aWwgd2UgZ290IGl0LCBvciBlcnJvciAqLwoJICBkbyB7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBsU3RhcnRbY3VyU3RyZWFtXSwKCQkJCSBsRmlyc3RWaWRlbyAtIGxTdGFydFtjdXJTdHJlYW1dLCBscEJ1ZmZlciwKCQkJCSBjYkJ1ZmZlciwgJmxSZWFkQnl0ZXMsICZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gR2xvYmFsUmVBbGxvY1B0cihscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMiwgR1BUUikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoKCSAgaWYgKEFWSVN0cmVhbUlzS2V5RnJhbWUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAoTE9ORylzSW5mby5kd1N0YXJ0KSkKCSAgICBmbGFncyA9IEFWSUlGX0tFWUZSQU1FOwoJICBocmVzID0gQVZJU3RyZWFtV3JpdGUocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgLTEsIGxSZWFkU2FtcGxlcywKCQkJCWxwQnVmZmVyLCBsUmVhZEJ5dGVzLCBmbGFncywgTlVMTCwgTlVMTCk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCgkgIGxTdGFydFtjdXJTdHJlYW1dICs9IGxSZWFkU2FtcGxlczsKCX0KCWxTdGFydFtjdXJTdHJlYW1dID0gbEZpcnN0VmlkZW87CiAgICAgIH0gLyogc3RyZWFtIGJ5IHN0cmVhbSAqLwoKICAgICAgLyogbmVlZCB0byBjbG9zZSB0aGlzIGJsb2NrPyAqLwogICAgICBpZiAoZHdJbnRlcmxlYXZlID09IDEpIHsKCWhyZXMgPSBBVklGaWxlRW5kUmVjb3JkKHBmaWxlKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGJyZWFrOwogICAgICB9CgogICAgICAvKiBzaG93IHByb2dyZXNzICovCiAgICAgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KGR3RmlsZUluaXRpYWxGcmFtZXMgKyBsQ3VyRnJhbWUsIDEwMCwKCQkJICAgICAgZHdGaWxlSW5pdGlhbEZyYW1lcyArIGxGaWxlTGVuZ3RoKSkpIHsKCWhyZXMgPSBBVklFUlJfVVNFUkFCT1JUOwoJYnJlYWs7CiAgICAgIH0KICAgIH0gLyogY29weSBmcmFtZSBieSBmcmFtZSAqLwogIH0gZWxzZSB7CiAgICAvKiBub24taW50ZXJsZWF2ZWQgZmlsZSAqLwoKICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KICAgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoY3VyU3RyZWFtLCAxMDAsIG5TdHJlYW1zKSkpIHsKCWhyZXMgPSBBVklFUlJfVVNFUkFCT1JUOwoJZ290byBlcnJvcjsKICAgICAgfQoKICAgICAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoKICAgICAgaWYgKHNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CgkvKiBzYW1wbGUtYmFzZWQgZGF0YSBsaWtlIGF1ZGlvICovCgl3aGlsZSAoc0luZm8uZHdTdGFydCA8IHNJbmZvLmR3TGVuZ3RoKSB7CgkgIExPTkcgbFNhbXBsZXMgPSBjYkJ1ZmZlciAvIHNJbmZvLmR3U2FtcGxlU2l6ZTsKCgkgIC8qIGNvcHkgZm9ybWF0IGZvciBjYXNlIGl0IGNhbiBjaGFuZ2UgKi8KCSAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKCSAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICByZXR1cm4gaHJlczsKCSAgQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIGxpbWl0IHRvIHN0cmVhbSBib3VuZGFyaWVzICovCgkgIGlmIChsU2FtcGxlcyAhPSAoTE9ORykoc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0KSkKCSAgICBsU2FtcGxlcyA9IHNJbmZvLmR3TGVuZ3RoIC0gc0luZm8uZHdTdGFydDsKCgkgIC8qIG5vdyB0cnkgdG8gcmVhZCB1bnRpbCB3ZSBnb3QgaXQsIG9yIGVycm9yIG9jY3VyZXMgKi8KCSAgZG8gewoJICAgIGxSZWFkQnl0ZXMgICA9IGNiQnVmZmVyOwoJICAgIGxSZWFkU2FtcGxlcyA9IDA7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWQocEluU3RyZWFtc1tjdXJTdHJlYW1dLHNJbmZvLmR3U3RhcnQsbFNhbXBsZXMsCgkJCQkgbHBCdWZmZXIsY2JCdWZmZXIsJmxSZWFkQnl0ZXMsJmxSZWFkU2FtcGxlcyk7CgkgIH0gd2hpbGUgKChocmVzID09IEFWSUVSUl9CVUZGRVJUT09TTUFMTCkgJiYKCQkgICAobHBCdWZmZXIgPSBHbG9iYWxSZUFsbG9jUHRyKGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyLCBHUFRSKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIGlmIChsUmVhZFNhbXBsZXMgIT0gMCkgewoJICAgIHNJbmZvLmR3U3RhcnQgKz0gbFJlYWRTYW1wbGVzOwoJICAgIGhyZXMgPSBBVklTdHJlYW1Xcml0ZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAtMSwgbFJlYWRTYW1wbGVzLAoJCQkJICBscEJ1ZmZlciwgbFJlYWRCeXRlcywgMCwgTlVMTCAsIE5VTEwpOwoJICAgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgICBnb3RvIGVycm9yOwoKCSAgICAvKiBzaG93IHByb2dyZXNzICovCgkgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoc0luZm8uZHdTdGFydCwxMDAsblN0cmVhbXMqc0luZm8uZHdMZW5ndGgpKwoJCQkgICAgIE11bERpdihjdXJTdHJlYW0sIDEwMCwgblN0cmVhbXMpKSkgewoJICAgICAgaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CgkgICAgICBnb3RvIGVycm9yOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBpZiAoKHNJbmZvLmR3TGVuZ3RoIC0gc0luZm8uZHdTdGFydCkgIT0gMSkgewoJICAgICAgaHJlcyA9IEFWSUVSUl9GSUxFUkVBRDsKCSAgICAgIGdvdG8gZXJyb3I7CgkgICAgfQoJICB9Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiBibG9jay1iYXNlZCBkYXRhIGxpa2UgdmlkZW8gKi8KCWZvciAoOyBzSW5mby5kd1N0YXJ0IDwgc0luZm8uZHdMZW5ndGg7IHNJbmZvLmR3U3RhcnQrKykgewoJICBEV09SRCBmbGFncyA9IDA7CgoJICAvKiBjb3B5IGZvcm1hdCBmb3IgY2FzZSBpdCBjYW4gY2hhbmdlICovCgkgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CgkgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJCSAgICAgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIHRyeSB0byByZWFkIGJsb2NrIGFuZCByZXNpemUgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJICBkbyB7CgkgICAgbFJlYWRTYW1wbGVzID0gMDsKCSAgICBsUmVhZEJ5dGVzICAgPSBjYkJ1ZmZlcjsKCSAgICBocmVzID0gQVZJU3RyZWFtUmVhZChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsIDEsCgkJCQkgbHBCdWZmZXIsIGNiQnVmZmVyLCZsUmVhZEJ5dGVzLCZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gR2xvYmFsUmVBbGxvY1B0cihscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMiwgR1BUUikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBpZiAobFJlYWRTYW1wbGVzICE9IDEpIHsKCSAgICBocmVzID0gQVZJRVJSX0ZJTEVSRUFEOwoJICAgIGdvdG8gZXJyb3I7CgkgIH0KCgkgIGlmIChBVklTdHJlYW1Jc0tleUZyYW1lKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgKExPTkcpc0luZm8uZHdTdGFydCkpCgkgICAgZmxhZ3MgPSBBVklJRl9LRVlGUkFNRTsKCSAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQlscEJ1ZmZlciwgbFJlYWRCeXRlcywgZmxhZ3MsIE5VTEwsIE5VTEwpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICAvKiBzaG93IHByb2dyZXNzICovCgkgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KHNJbmZvLmR3U3RhcnQsMTAwLG5TdHJlYW1zKnNJbmZvLmR3TGVuZ3RoKSsKCQkJICAgTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CgkgICAgaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CgkgICAgZ290byBlcnJvcjsKCSAgfQoJfSAvKiBjb3B5IGFsbCBibG9ja3MgKi8KICAgICAgfQogICAgfSAvKiBjb3B5IGRhdGEgc3RyZWFtIGJ5IHN0cmVhbSAqLwogIH0KCiBlcnJvcjoKICBpZiAobHBCdWZmZXIgIT0gTlVMTCkKICAgIEdsb2JhbEZyZWVQdHIobHBCdWZmZXIpOwogIGlmIChwZmlsZSAhPSBOVUxMKSB7CiAgICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgICBpZiAocE91dFN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMKQoJQVZJU3RyZWFtUmVsZWFzZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dKTsKICAgICAgaWYgKHBJblN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMKQoJQVZJU3RyZWFtUmVsZWFzZShwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwogICAgfQoKICAgIEFWSUZpbGVSZWxlYXNlKHBmaWxlKTsKICB9CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUNyZWF0ZUVkaXRhYmxlU3RyZWFtCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQ3JlYXRlRWRpdGFibGVTdHJlYW0oUEFWSVNUUkVBTSAqcHBFZGl0YWJsZSwgUEFWSVNUUkVBTSBwU291cmNlKQp7CiAgSUFWSUVkaXRTdHJlYW0gKnBFZGl0ID0gTlVMTDsKICBIUkVTVUxUCSAgaHI7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBwcEVkaXRhYmxlLCBwU291cmNlKTsKCiAgaWYgKHBwRWRpdGFibGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcEVkaXRhYmxlID0gTlVMTDsKCiAgaWYgKHBTb3VyY2UgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTb3VyY2UsICZJSURfSUFWSUVkaXRTdHJlYW0sCgkJCQkgICAoTFBWT0lEKikmcEVkaXQpOwogICAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgICBociA9IElBVklFZGl0U3RyZWFtX0Nsb25lKHBFZGl0LCBwcEVkaXRhYmxlKTsKICAgICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CgogICAgICByZXR1cm4gaHI7CiAgICB9CiAgfQoKICAvKiBuZWVkIG93biBpbXBsZW1lbnRhdGlvbiBvZiBJQVZJRWRpdFN0cmVhbSAqLwogIHBFZGl0ID0gQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKHBTb3VyY2UpOwogIGlmIChwRWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UocEVkaXQsICZJSURfSUFWSVN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQqKXBwRWRpdGFibGUpOwogIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUNsb25lCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1DbG9uZShQQVZJU1RSRUFNIHBTdHJlYW0sIFBBVklTVFJFQU0gKnBwUmVzdWx0KQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcFN0cmVhbSwgcHBSZXN1bHQpOwoKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ2xvbmUocEVkaXQsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUNvcHkJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbUNvcHkoUEFWSVNUUkVBTSBwU3RyZWFtLCBMT05HICpwbFN0YXJ0LAoJCQkgICAgICBMT05HICpwbExlbmd0aCwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLCBwU3RyZWFtLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8IHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ29weShwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUN1dAkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtQ3V0KFBBVklTVFJFQU0gcFN0cmVhbSwgTE9ORyAqcGxTdGFydCwKCQkJICAgICBMT05HICpwbExlbmd0aCwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLCBwU3RyZWFtLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgIT0gTlVMTCkKICAgICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9DdXQocEVkaXQsIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1QYXN0ZQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtUGFzdGUoUEFWSVNUUkVBTSBwRGVzdCwgTE9ORyAqcGxTdGFydCwgTE9ORyAqcGxMZW5ndGgsCgkJCSAgICAgICBQQVZJU1RSRUFNIHBTb3VyY2UsIExPTkcgbFN0YXJ0LCBMT05HIGxFbmQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJWxkLCVsZClcbiIsIHBEZXN0LCBwbFN0YXJ0LCBwbExlbmd0aCwKCXBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogIGlmIChwRGVzdCA9PSBOVUxMIHx8IHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBEZXN0LCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9QYXN0ZShwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXRJbmZvQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXRJbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkJICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoQVZJU1RSRUFNSU5GT0EpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkoJmFzaXcsIGFzaSwgc2l6ZW9mKGFzaXcpIC0gc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIGFzaS0+c3pOYW1lLCAtMSwKCQkgICAgICBhc2l3LnN6TmFtZSwgc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb1cocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldEluZm9XCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldEluZm9XKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPVyBhc2ksCgkJCQkgIExPTkcgc2l6ZSkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBhc2ksIHNpemUpOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocHN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fU2V0SW5mbyhwRWRpdCwgYXNpLCBzaXplKTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldE5hbWVBCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldE5hbWVBKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBDU1RSIHN6TmFtZSkKewogIEFWSVNUUkVBTUlORk9BIGFzaWE7CiAgSFJFU1VMVCAgICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIHBzdHJlYW0sIGRlYnVnc3RyX2Eoc3pOYW1lKSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoc3pOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBocmVzID0gQVZJU3RyZWFtSW5mb0EocHN0cmVhbSwgJmFzaWEsIHNpemVvZihhc2lhKSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpYS5zek5hbWUsIDAsIHNpemVvZihhc2lhLnN6TmFtZSkpOwogIGxzdHJjcHluQShhc2lhLnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpYS5zek5hbWUpL3NpemVvZihhc2lhLnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9BKHBzdHJlYW0sICZhc2lhLCBzaXplb2YoYXNpYSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXROYW1lVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXROYW1lVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQ1dTVFIgc3pOYW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgcHN0cmVhbSwgZGVidWdzdHJfdyhzek5hbWUpKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzek5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpdy5zek5hbWUsIDAsIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIGxzdHJjcHluVyhhc2l3LnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpdy5zek5hbWUpL3NpemVvZihhc2l3LnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9XKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUNsZWFyQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQ2xlYXJDbGlwYm9hcmQodm9pZCkKewogIFRSQUNFKCIoKVxuIik7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIE9sZVNldENsaXBib2FyZChOVUxMKTsgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklHZXRGcm9tQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJR2V0RnJvbUNsaXBib2FyZChQQVZJRklMRSAqcHBmaWxlKQp7CiAgRklYTUUoIiglcCksIHN0dWIhXG4iLCBwcGZpbGUpOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklQdXRGaWxlT25DbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklQdXRGaWxlT25DbGlwYm9hcmQoUEFWSUZJTEUgcGZpbGUpCnsKICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQo=