LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZG93c3guaCIKCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSUJ1aWxkRmlsdGVyVyAtLSB1c2VzIGZpeGVkIHNpemUgdGFibGUKICovCiNkZWZpbmUgTUFYX0ZJTFRFUlMgMzAgLyogMzAgPT4gN2tCICovCgp0eXBlZGVmIHN0cnVjdCBfQVZJRmlsdGVyIHsKICBXQ0hBUiBzekNsc2lkWzQwXTsKICBXQ0hBUiBzekV4dGVuc2lvbnNbTUFYX0ZJTFRFUlMgKiA3XTsKfSBBVklGaWx0ZXI7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZm9yIEFWSVNhdmVPcHRpb25zCiAqLwpzdGF0aWMgc3RydWN0IHsKICBVSU5UICAgICAgICAgICAgICAgICAgdUZsYWdzOwogIElOVCAgICAgICAgICAgICAgICAgICBuU3RyZWFtczsKICBQQVZJU1RSRUFNICAgICAgICAgICAqcHBhdmlzOwogIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnM7CiAgSU5UICAgICAgICAgICAgICAgICAgIG5DdXJyZW50Owp9IFNhdmVPcHRzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNvcGllZCBmcm9tIGRsbHMvb2xlMzIvY29tcG9iai5jCiAqLwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0NMU0lERnJvbVN0cmluZyhMUENTVFIgaWRzdHIsIExQQ0xTSUQgaWQpCnsKICBCWVRFIGNvbnN0ICpzID0gKEJZVEUgY29uc3QqKWlkc3RyOwogIEJZVEUgKnA7CiAgSU5UICAgaTsKICBCWVRFIHRhYmxlWzI1Nl07CgogIGlmICghcykgewogICAgbWVtc2V0KGlkLCAwLCBzaXplb2YoQ0xTSUQpKTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCiAgICBpZiAobHN0cmxlbkEocykgIT0gMzgpCiAgICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwoKICAgIGlmICgoc1swXSE9J3snKSB8fCAoc1s5XSE9Jy0nKSB8fCAoc1sxNF0hPSctJykgfHwgKHNbMTldIT0nLScpIHx8Cgkoc1syNF0hPSctJykgfHwgKHNbMzddIT0nfScpKQogICAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgICBmb3IgKGkgPSAxOyBpIDwgMzc7IGkrKykgewogICAgICBpZiAoKGkgPT0gOSkgfHwgKGkgPT0gMTQpIHx8IChpID09IDE5KSB8fCAoaSA9PSAyNCkpCgljb250aW51ZTsKICAgICAgaWYgKCEoKChzW2ldID49ICcwJykgJiYgKHNbaV0gPD0gJzknKSkgIHx8CgkgICAgKChzW2ldID49ICdhJykgJiYgKHNbaV0gPD0gJ2YnKSkgIHx8CgkgICAgKChzW2ldID49ICdBJykgJiYgKHNbaV0gPD0gJ0YnKSkpCgkgICkKCXJldHVybiBDT19FX0NMQVNTU1RSSU5HOwogICAgfQogIH0KCiAgVFJBQ0UoIiVzIC0+ICVwXG4iLCBzLCBpZCk7CgogIC8qIHF1aWNrIGxvb2t1cCB0YWJsZSAqLwogIG1lbXNldCh0YWJsZSwgMCwgMjU2KTsKCiAgZm9yIChpID0gMDsgaSA8IDEwOyBpKyspCiAgICB0YWJsZVsnMCcgKyBpXSA9IGk7CgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgIHRhYmxlWydBJyArIGldID0gaSsxMDsKICAgIHRhYmxlWydhJyArIGldID0gaSsxMDsKICB9CgogIC8qIGluIGZvcm0ge1hYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWH0gKi8KICBwID0gKEJZVEUgKikgaWQ7CgogIHMrKzsJLyogc2tpcCBsZWFkaW5nIGJyYWNlICAqLwogIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgIHBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSA0OwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICBwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDI7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CiAgICAqcCsrID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CgogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgQk9PTCBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oTFBDV1NUUiBzekZpbGUsIExQQ0xTSUQgbHBjbHNpZCkKewogIENIQVIgICBzelJlZ0tleVsyNV07CiAgQ0hBUiAgIHN6VmFsdWVbMTAwXTsKICBMUFdTVFIgc3pFeHQgPSBzdHJyY2hyVyhzekZpbGUsICcuJyk7CiAgTE9ORyAgIGxlbiA9IHNpemVvZihzelZhbHVlKSAvIHNpemVvZihzelZhbHVlWzBdKTsKCiAgaWYgKHN6RXh0ID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIHN6RXh0Kys7CgogIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXEV4dGVuc2lvbnNcXCUuM2xzIiwgc3pFeHQpOwogIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgbHBjbHNpZCkgPT0gU19PSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluaXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluaXQJCShBVklGSUxFLjEwMCkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVJbml0KHZvaWQpIHsKICAvKiBuZWVkIHRvIGxvYWQgb2xlMzIuZGxsIGlmIG5vdCBhbHJlYWR5IGRvbmUgYW5kIGdldCBzb21lIGZ1bmN0aW9ucyAqLwogIEZJWE1FKCIoKTogc3R1YiFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMRS4xMDEpCiAqLwp2b2lkIFdJTkFQSSBBVklGaWxlRXhpdCh2b2lkKSB7CiAgLyogbmVlZCB0byBmcmVlIG9sZTMyLmRsbCBpZiB3ZSBhcmUgdGhlIGxhc3QgZXhpdCBjYWxsICovCiAgRklYTUUoIigpOiBzdHViIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZU9wZW5BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVPcGVuCQkoQVZJRklMRS4xMDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlbkEoUEFWSUZJTEUgKnBwZmlsZSwgTFBDU1RSIHN6RmlsZSwgVUlOVCB1TW9kZSwKCQkJICAgIExQQ0xTSUQgbHBIYW5kbGVyKQp7CiAgTFBXU1RSICB3c3pGaWxlID0gTlVMTDsKICBIUkVTVUxUIGhyOwogIGludCAgICAgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4WCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfYShzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjb252ZXJ0IEFTQ0lJIHN0cmluZyB0byBVbmljb2RlIGFuZCBjYWxsIHVuaWNvZGUgZnVuY3Rpb24gKi8KICBsZW4gPSBsc3RybGVuQShzekZpbGUpOwogIGlmIChsZW4gPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHdzekZpbGUgPSAoTFBXU1RSKUxvY2FsQWxsb2MoTFBUUiwgKGxlbiArIDEpICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgd3N6RmlsZSwgbGVuICsgMSk7CiAgd3N6RmlsZVtsZW4gKyAxXSA9IDA7CgogIGhyID0gQVZJRmlsZU9wZW5XKHBwZmlsZSwgd3N6RmlsZSwgdU1vZGUsIGxwSGFuZGxlcik7CgogIExvY2FsRnJlZSgoSExPQ0FMKXdzekZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZU9wZW5XCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVPcGVuVyhQQVZJRklMRSAqcHBmaWxlLCBMUENXU1RSIHN6RmlsZSwgVUlOVCB1TW9kZSwKCQkJICAgIExQQ0xTSUQgbHBIYW5kbGVyKQp7CiAgSVBlcnNpc3RGaWxlICpwcGVyc2lzdCA9IE5VTEw7CiAgQ0xTSUQgICAgICAgICBjbHNpZEhhbmRsZXI7CiAgSFJFU1VMVCAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcywweCVYLCVzKVxuIiwgcHBmaWxlLCBkZWJ1Z3N0cl93KHN6RmlsZSksIHVNb2RlLAoJZGVidWdzdHJfZ3VpZChscEhhbmRsZXIpKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChwcGZpbGUgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGZpbGUgPSBOVUxMOwoKICAvKiBpZiBubyBoYW5kbGVyIHRoZW4gdHJ5IGd1ZXNzaW5nIGl0IGJ5IGV4dGVuc2lvbiAqLwogIGlmIChscEhhbmRsZXIgPT0gTlVMTCkgewogICAgaWYgKCEgQVZJRklMRV9HZXRGaWxlSGFuZGxlckJ5RXh0ZW5zaW9uKHN6RmlsZSwgJmNsc2lkSGFuZGxlcikpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfSBlbHNlCiAgICBtZW1jcHkoJmNsc2lkSGFuZGxlciwgbHBIYW5kbGVyLCBzaXplb2YoY2xzaWRIYW5kbGVyKSk7CgogIC8qIGNyZXRlIGluc3RhbmNlIG9mIGhhbmRsZXIgKi8KICBociA9IFNIQ29DcmVhdGVJbnN0YW5jZShOVUxMLCAmY2xzaWRIYW5kbGVyLCBOVUxMLAoJCQkgICZJSURfSUFWSUZpbGUsIChMUFZPSUQqKXBwZmlsZSk7CiAgaWYgKEZBSUxFRChocikgfHwgKnBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICAvKiBhc2sgZm9yIElQZXJzaXN0RmlsZSBpbnRlcmZhY2UgZm9yIGxvYWRpbmcvY3JlYXRpbmcgdGhlIGZpbGUgKi8KICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKCpwcGZpbGUsICZJSURfSVBlcnNpc3RGaWxlLCAoTFBWT0lEKikmcHBlcnNpc3QpOwogIGlmIChGQUlMRUQoaHIpIHx8IHBwZXJzaXN0ID09IE5VTEwpIHsKICAgIElBVklGaWxlX1JlbGVhc2UoKnBwZmlsZSk7CiAgICAqcHBmaWxlID0gTlVMTDsKICAgIHJldHVybiBocjsKICB9CgogIGhyID0gSVBlcnNpc3RGaWxlX0xvYWQocHBlcnNpc3QsIHN6RmlsZSwgdU1vZGUpOwogIElQZXJzaXN0RmlsZV9SZWxlYXNlKHBwZXJzaXN0KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSUFWSUZpbGVfUmVsZWFzZSgqcHBmaWxlKTsKICAgICpwcGZpbGUgPSBOVUxMOwogIH0KCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVBZGRSZWYJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUFkZFJlZgkJKEFWSUZJTEUuMTQwKQogKi8KVUxPTkcgV0lOQVBJIEFWSUZpbGVBZGRSZWYoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVSZWxlYXNlCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVSZWxlYXNlCQkoQVZJRklMRS4xNDEpCiAqLwpVTE9ORyBXSU5BUEkgQVZJRmlsZVJlbGVhc2UoUEFWSUZJTEUgcGZpbGUpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5mbwkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5mb0EJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluZm8JCShBVklGSUxFLjE0MikKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVJbmZvQShQQVZJRklMRSBwZmlsZSwgTFBBVklGSUxFSU5GT0EgYWZpLCBMT05HIHNpemUpCnsKICBBVklGSUxFSU5GT1cgYWZpdzsKICBIUkVTVUxUICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwZmlsZSwgYWZpLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoQVZJRklMRUlORk9BKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaHJlcyA9IElBVklGaWxlX0luZm8ocGZpbGUsICZhZml3LCBzaXplb2YoYWZpdykpOwoKICBtZW1jcHkoYWZpLCAmYWZpdywgc2l6ZW9mKCphZmkpIC0gc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkpOwogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBhZml3LnN6RmlsZVR5cGUsIC0xLCBhZmktPnN6RmlsZVR5cGUsCgkJICAgICAgc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSksIE5VTEwsIE5VTEwpOwogIGFmaS0+c3pGaWxlVHlwZVtzaXplb2YoYWZpLT5zekZpbGVUeXBlKSAtIDFdID0gMDsKCiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluZm9XCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVJbmZvVyhQQVZJRklMRSBwZmlsZSwgTFBBVklGSUxFSU5GT1cgYWZpdywgTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwZmlsZSwgYWZpdywgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9JbmZvKHBmaWxlLCBhZml3LCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlR2V0U3RyZWFtCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMRS4xNDMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlR2V0U3RyZWFtKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBUUkFDRSgiKCVwLCVwLCclNC40cycsJWxkKVxuIiwgcGZpbGUsIGF2aXMsIChjaGFyKikmZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtQQkoQVZJRklMMzIuQCkKICogICAgICAgICAgICAgIEFWSUZpbGVDcmVhdGVTdHJlYW0JKEFWSUZJTEUuMTQ0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUNyZWF0ZVN0cmVhbUEoUEFWSUZJTEUgcGZpbGUsIFBBVklTVFJFQU0gKnBwYXZpLAoJCQkJICAgIExQQVZJU1RSRUFNSU5GT0EgcHNpKQp7CiAgQVZJU1RSRUFNSU5GT1cJcHNpdzsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBmaWxlLCBwcGF2aSwgcHNpKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgLyogT25seSB0aGUgc3pOYW1lIGF0IHRoZSBlbmQgaXMgZGlmZmVyZW50ICovCiAgbWVtY3B5KCZwc2l3LCBwc2ksIHNpemVvZigqcHNpKSAtIHNpemVvZihwc2ktPnN6TmFtZSkpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwc2ktPnN6TmFtZSwgLTEsIHBzaXcuc3pOYW1lLAoJCSAgICAgIHNpemVvZihwc2l3LnN6TmFtZSkgLyBzaXplb2YocHNpdy5zek5hbWVbMF0pKTsKCiAgcmV0dXJuIElBVklGaWxlX0NyZWF0ZVN0cmVhbShwZmlsZSwgcHBhdmksICZwc2l3KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVDcmVhdGVTdHJlYW1XKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBmaWxlLCBhdmlzLCBhc2kpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfQ3JlYXRlU3RyZWFtKHBmaWxlLCBhdmlzLCBhc2kpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVXcml0ZURhdGEJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlV3JpdGVEYXRhCShBVklGSUxFLjE0NikKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVXcml0ZURhdGEoUEFWSUZJTEUgcGZpbGUsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWxkKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9Xcml0ZURhdGEocGZpbGUsIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVSZWFkRGF0YQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlUmVhZERhdGEJCShBVklGSUxFLjE0NykKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVSZWFkRGF0YShQQVZJRklMRSBwZmlsZSxEV09SRCBmY2MsTFBWT0lEIGxwLExQTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUVuZFJlY29yZAkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFbmRSZWNvcmQJKEFWSUZJTEUuMTQ4KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUVuZFJlY29yZChQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9FbmRSZWNvcmQocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUFkZFJlZgkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1BZGRSZWYJCShBVklGSUxFLjE2MCkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1BZGRSZWYoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklTdHJlYW1fQWRkUmVmKHBzdHJlYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlbGVhc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWxlYXNlCShBVklGSUxFLjE2MSkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1SZWxlYXNlKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJU3RyZWFtX1JlbGVhc2UocHN0cmVhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQ3JlYXRlCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUNyZWF0ZQkJKEFWSUZJTEUuMTA0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtQ3JlYXRlKFBBVklTVFJFQU0gKnBwYXZpLCBMT05HIGxQYXJhbTEsIExPTkcgbFBhcmFtMiwKCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLCVzKVxuIiwgcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIsCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICBociA9IFNIQ29DcmVhdGVJbnN0YW5jZShOVUxMLCBwY2xzaWRIYW5kbGVyLCBOVUxMLAoJCQkgICZJSURfSUFWSVN0cmVhbSwgKExQVk9JRCopcHBhdmkpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcGF2aSwgbFBhcmFtMSwgbFBhcmFtMik7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBhdmkpOwogICAgKnBwYXZpID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUluZm9BCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUluZm8JCShBVklGSUxFLjE2MikKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUluZm9BKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPQSBhc2ksCgkJCSAgICAgIExPTkcgc2l6ZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgSFJFU1VMVAkgaHJlczsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBhc2ksIHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKEFWSVNUUkVBTUlORk9BKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaHJlcyA9IElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKCiAgbWVtY3B5KGFzaSwgJmFzaXcsIHNpemVvZihhc2l3KSAtIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBhc2l3LnN6TmFtZSwgLTEsIGFzaS0+c3pOYW1lLAoJCSAgICAgIHNpemVvZihhc2ktPnN6TmFtZSksIE5VTEwsIE5VTEwpOwogIGFzaS0+c3pOYW1lW3NpemVvZihhc2ktPnN6TmFtZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUluZm9XCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUluZm9XKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPVyBhc2ksCgkJCSAgICAgIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sIGFzaSwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtRmluZFNhbXBsZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTEUuMTYzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtRmluZFNhbXBsZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLCBEV09SRCBmbGFncykKewogIFRSQUNFKCIoJXAsJWxkLDB4JWxYKVxuIiwgcHN0cmVhbSwgcG9zLCBmbGFncyk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIHJldHVybiBJQVZJU3RyZWFtX0ZpbmRTYW1wbGUocHN0cmVhbSwgcG9zLCBmbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVhZEZvcm1hdAkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTEUuMTY0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICAgTFBWT0lEIGZvcm1hdCwgTFBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1TZXRGb3JtYXQJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1TZXRGb3JtYXQJKEFWSUZJTEUuMTY5KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtU2V0Rm9ybWF0KFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MsCgkJCQkgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsIHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9TZXRGb3JtYXQocHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWQJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVhZAkJKEFWSUZJTEUuMTY3KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgc3RhcnQsIExPTkcgc2FtcGxlcywKCQkJICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsCgkJCSAgICAgTFBMT05HIGJ5dGVzcmVhZCwgTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcClcbiIsIHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkKHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1Xcml0ZQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1Xcml0ZQkJKEFWSUZJTEUuMTY4KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtV3JpdGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgIExQVk9JRCBidWZmZXIsIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCSAgICAgIExQTE9ORyBzYW1wd3JpdHRlbiwgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglbFgsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWREYXRhCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVhZERhdGEJKEFWSUZJTEUuMTY1KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZERhdGEoUEFWSVNUUkVBTSBwc3RyZWFtLCBEV09SRCBmY2MsIExQVk9JRCBscCwKCQkJCSBMUExPTkcgbHByZWFkKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcHN0cmVhbSwgKGNoYXIqKSZmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKHBzdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtV3JpdGVEYXRhCShBVklGSUxFLjE2NikKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlRGF0YShQQVZJU1RSRUFNIHBzdHJlYW0sIERXT1JEIGZjYywgTFBWT0lEIGxwLAoJCQkJICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWxkKVxuIiwgcHN0cmVhbSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZURhdGEocHN0cmVhbSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWVPcGVuCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtR2V0RnJhbWVPcGVuCShBVklGSUxFLjExMikKICovClBHRVRGUkFNRSBXSU5BUEkgQVZJU3RyZWFtR2V0RnJhbWVPcGVuKFBBVklTVFJFQU0gcHN0cmVhbSwKCQkJCSAgICAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaVdhbnRlZCkKewogIFBHRVRGUkFNRSBwZyA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBwc3RyZWFtLCBscGJpV2FudGVkKTsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBzdHJlYW0sICZJSURfSUdldEZyYW1lLCAoTFBWT0lEKikmcGcpKSB8fAogICAgICBwZyA9PSBOVUxMKSB7CiAgICBwZyA9IEFWSUZJTEVfQ3JlYXRlR2V0RnJhbWUocHN0cmVhbSk7CiAgICBpZiAocGcgPT0gTlVMTCkKICAgICAgcmV0dXJuIE5VTEw7CiAgfQoKICBpZiAoRkFJTEVEKElHZXRGcmFtZV9TZXRGb3JtYXQocGcsIGxwYmlXYW50ZWQsIE5VTEwsIDAsIDAsIC0xLCAtMSkpKSB7CiAgICBJR2V0RnJhbWVfUmVsZWFzZShwZyk7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIHJldHVybiBwZzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1HZXRGcmFtZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lCShBVklGSUxFLjExMCkKICovCkxQVk9JRCBXSU5BUEkgQVZJU3RyZWFtR2V0RnJhbWUoUEdFVEZSQU1FIHBnLCBMT05HIHBvcykKewogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcGcsIHBvcyk7CgogIGlmIChwZyA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiBJR2V0RnJhbWVfR2V0RnJhbWUocGcsIHBvcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWVDbG9zZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UJKEFWSUZJTEUuMTExKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShQR0VURlJBTUUgcGcpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGcpOwoKICBpZiAocGcgIT0gTlVMTCkKICAgIHJldHVybiBJR2V0RnJhbWVfUmVsZWFzZShwZyk7CiAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0JKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbShQQVZJU1RSRUFNICpwcHNDb21wcmVzc2VkLAoJCQkJICAgICAgIFBBVklTVFJFQU0gcHNTb3VyY2UsCgkJCQkgICAgICAgTFBBVklDT01QUkVTU09QVElPTlMgYWNvLAoJCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgQ0hBUiAgICAgICAgICAgc3pSZWdLZXlbMjVdOwogIENIQVIgICAgICAgICAgIHN6VmFsdWVbMTAwXTsKICBDTFNJRCAgICAgICAgICBjbHNpZEhhbmRsZXI7CiAgSFJFU1VMVCAgICAgICAgaHI7CiAgTE9ORyAgICAgICAgICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKTsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcylcbiIsIHBwc0NvbXByZXNzZWQsIHBzU291cmNlLCBhY28sCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwc0NvbXByZXNzZWQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHBzU291cmNlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgKnBwc0NvbXByZXNzZWQgPSBOVUxMOwoKICAvKiBpZiBubyBoYW5kbGVyIGdpdmVuIGdldCBkZWZhdWx0IG9uZXMgYmFzZWQgb24gc3RyZWFtdHlwZSAqLwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpIHsKICAgIGhyID0gSUFWSVN0cmVhbV9JbmZvKHBzU291cmNlLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CgogICAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcQ29tcHJlc3NvcnNcXCU0LjRzIiwgKGNoYXIqKSZhc2l3LmZjY1R5cGUpOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJnNpemUpICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgICBpZiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgJmNsc2lkSGFuZGxlcikgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIG1lbWNweSgmY2xzaWRIYW5kbGVyLCBwY2xzaWRIYW5kbGVyLCBzaXplb2YoY2xzaWRIYW5kbGVyKSk7CgogIGhyID0gU0hDb0NyZWF0ZUluc3RhbmNlKE5VTEwsICZjbHNpZEhhbmRsZXIsIE5VTEwsCgkJCSAgJklJRF9JQVZJU3RyZWFtLCAoTFBWT0lEKilwcHNDb21wcmVzc2VkKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBzQ29tcHJlc3NlZCA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcHNDb21wcmVzc2VkLCAoTFBBUkFNKXBzU291cmNlLCAoTFBBUkFNKWFjbyk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBzQ29tcHJlc3NlZCk7CiAgICAqcHBzQ29tcHJlc3NlZCA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJTWFrZUZpbGVGcm9tU3RyZWFtcwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSU1ha2VGaWxlRnJvbVN0cmVhbXMoUEFWSUZJTEUgKnBwZmlsZSwgaW50IG5TdHJlYW1zLAoJCQkJICAgICAgUEFWSVNUUkVBTSAqcHBTdHJlYW1zKQp7CiAgVFJBQ0UoIiglcCwlZCwlcClcbiIsIHBwZmlsZSwgblN0cmVhbXMsIHBwU3RyZWFtcyk7CgogIGlmIChuU3RyZWFtcyA8IDAgfHwgcHBmaWxlID09IE5VTEwgfHwgcHBTdHJlYW1zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBmaWxlID0gQVZJRklMRV9DcmVhdGVBVklUZW1wRmlsZShuU3RyZWFtcywgcHBTdHJlYW1zKTsKICBpZiAoKnBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlICAgKEFWSUZJTEUuMTAzKQogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbU9wZW5Gcm9tRmlsZUEoUEFWSVNUUkVBTSAqcHBhdmksIExQQ1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfYShzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5BKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlVyhQQVZJU1RSRUFNICpwcGF2aSwgTFBDV1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfdyhzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1CZWdpblN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUJlZ2luU3RyZWFtaW5nKFBBVklTVFJFQU0gcGF2aSwgTE9ORyBsU3RhcnQsIExPTkcgbEVuZCwgTE9ORyBsUmF0ZSkKewogIElBVklTdHJlYW1pbmcqIHBzdHJlYW0gPSBOVUxMOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlbGQpXG4iLCBwYXZpLCBsU3RhcnQsIGxFbmQsIGxSYXRlKTsKCiAgaWYgKHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocGF2aSwgJklJRF9JQVZJU3RyZWFtaW5nLCAoTFBWT0lEKikmcHN0cmVhbSk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcHN0cmVhbSAhPSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1pbmdfQmVnaW4ocHN0cmVhbSwgbFN0YXJ0LCBsRW5kLCBsUmF0ZSk7CiAgICBJQVZJU3RyZWFtaW5nX1JlbGVhc2UocHN0cmVhbSk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUVuZFN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUVuZFN0cmVhbWluZyhQQVZJU1RSRUFNIHBhdmkpCnsKICBJQVZJU3RyZWFtaW5nKiBwc3RyZWFtID0gTlVMTDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwKVxuIiwgcGF2aSk7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwYXZpLCAmSUlEX0lBVklTdHJlYW1pbmcsIChMUFZPSUQqKSZwc3RyZWFtKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwc3RyZWFtICE9IE5VTEwpIHsKICAgIElBVklTdHJlYW1pbmdfRW5kKHBzdHJlYW0pOwogICAgSUFWSVN0cmVhbWluZ19SZWxlYXNlKHBzdHJlYW0pOwogIH0KCiByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVN0YXJ0CQkoQVZJRklMRS4xMzApCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TdGFydChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3U3RhcnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMRS4xMzEpCiAqCQlBVklTdHJlYW1MZW5ndGgJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtTGVuZ3RoKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGFzaXcuZHdMZW5ndGg7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2FtcGxlVG9UaW1lCShBVklGSUxFLjEzMykKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVNhbXBsZVRvVGltZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFNhbXBsZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgTE9ORyB0aW1lOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBzdHJlYW0sIGxTYW1wbGUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdSYXRlID09IDApCiAgICByZXR1cm4gLTE7CgogIC8qIGxpbWl0IHRvIHN0cmVhbSBib3VuZHMgKi8KICBpZiAobFNhbXBsZSA8IGFzaXcuZHdTdGFydCkKICAgIGxTYW1wbGUgPSBhc2l3LmR3U3RhcnQ7CiAgaWYgKGxTYW1wbGUgPiBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoKQogICAgbFNhbXBsZSA9IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGg7CgogIGlmIChhc2l3LmR3UmF0ZSAvIGFzaXcuZHdTY2FsZSA8IDEwMDApCiAgICB0aW1lID0gKExPTkcpKCgoZmxvYXQpbFNhbXBsZSAqIGFzaXcuZHdTY2FsZSAqIDEwMDApIC8gYXNpdy5kd1JhdGUpOwogIGVsc2UKICAgIHRpbWUgPSAoTE9ORykoKChmbG9hdClsU2FtcGxlICogYXNpdy5kd1NjYWxlICogMTAwMCArIChhc2l3LmR3UmF0ZSAtIDEpKSAvIGFzaXcuZHdSYXRlKTsKCiAgVFJBQ0UoIiAtPiAlbGRcbiIsdGltZSk7CiAgcmV0dXJuIHRpbWU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtVGltZVRvU2FtcGxlCShBVklGSUxFLjEzMikKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVRpbWVUb1NhbXBsZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFRpbWUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIExPTkcgc2FtcGxlOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBzdHJlYW0sIGxUaW1lKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCB8fCBsVGltZSA8IDApCiAgICByZXR1cm4gLTE7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAtMTsKICBpZiAoYXNpdy5kd1NjYWxlID09IDApCiAgICByZXR1cm4gLTE7CgogIGlmIChhc2l3LmR3UmF0ZSAvIGFzaXcuZHdTY2FsZSA8IDEwMDApCiAgICBzYW1wbGUgPSAoTE9ORykoKCgoZmxvYXQpYXNpdy5kd1JhdGUgKiBsVGltZSkgLyAoYXNpdy5kd1NjYWxlICogMTAwMCkpKTsKICBlbHNlCiAgICBzYW1wbGUgPSAoTE9ORykoKChmbG9hdClhc2l3LmR3UmF0ZSAqIGxUaW1lICsgKGFzaXcuZHdTY2FsZSAqIDEwMDAgLSAxKSkgLyAoYXNpdy5kd1NjYWxlICogMTAwMCkpOwoKICAvKiBsaW1pdCB0byBzdHJlYW0gYm91bmRzICovCiAgaWYgKHNhbXBsZSA8IGFzaXcuZHdTdGFydCkKICAgIHNhbXBsZSA9IGFzaXcuZHdTdGFydDsKICBpZiAoc2FtcGxlID4gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aCkKICAgIHNhbXBsZSA9IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGg7CgogIFRSQUNFKCIgLT4gJWxkXG4iLCBzYW1wbGUpOwogIHJldHVybiBzYW1wbGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXJBCQkoQVZJRklMMzIuQCkKICoJCUFWSUJ1aWxkRmlsdGVyCQkoQVZJRklMRS4xMjMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklCdWlsZEZpbHRlckEoTFBTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIExQV1NUUiAgd3N6RmlsdGVyOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVkKVxuIiwgc3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoY2JGaWx0ZXIgPCAyKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBzekZpbHRlclswXSA9IDA7CiAgc3pGaWx0ZXJbMV0gPSAwOwoKICB3c3pGaWx0ZXIgPSAoTFBXU1RSKUdsb2JhbEFsbG9jUHRyKEdITkQsIGNiRmlsdGVyICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gQVZJQnVpbGRGaWx0ZXJXKHdzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgd3N6RmlsdGVyLCBjYkZpbHRlciwKCQkJc3pGaWx0ZXIsIGNiRmlsdGVyLCBOVUxMLCBOVUxMKTsKICB9CgogIEdsb2JhbEZyZWVQdHIod3N6RmlsdGVyKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUJ1aWxkRmlsdGVyVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklCdWlsZEZpbHRlclcoTFBXU1RSIHN6RmlsdGVyLCBMT05HIGNiRmlsdGVyLCBCT09MIGZTYXZpbmcpCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDbHNpZFtdID0geydDJywnTCcsJ1MnLCdJJywnRCcsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6RXh0ZW5zaW9uRm10W10gPSB7JzsnLCcqJywnLicsJyUnLCdzJywwfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pBVklGaWxlRXh0ZW5zaW9uc1tdID0KICAgIHsnQScsJ1YnLCdJJywnRicsJ2knLCdsJywnZScsJ1xcJywnRScsJ3gnLCd0JywnZScsJ24nLCdzJywnaScsJ28nLCduJywncycsMH07CgogIEFWSUZpbHRlciAqbHA7CiAgV0NIQVIgICAgICBzekFsbEZpbGVzWzQwXTsKICBXQ0hBUiAgICAgIHN6RmlsZUV4dFsxMF07CiAgV0NIQVIgICAgICBzelZhbHVlWzEyOF07CiAgSEtFWSAgICAgICBoS2V5OwogIERXT1JEICAgICAgbiwgaTsKICBMT05HICAgICAgIHNpemU7CiAgRFdPUkQgICAgICBjb3VudCA9IDA7CgogIFRSQUNFKCIoJXAsJWxkLCVkKVxuIiwgc3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzekZpbHRlciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoY2JGaWx0ZXIgPCAyKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBscCA9IChBVklGaWx0ZXIqKUdsb2JhbEFsbG9jUHRyKEdITkQsIE1BWF9GSUxURVJTICogc2l6ZW9mKEFWSUZpbHRlcikpOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qCiAgICogMS4gaXRlcmF0ZSBvdmVyIEhLRVlfQ0xBU1NFU19ST09UXFxBVklGaWxlXFxFeHRlbnNpb25zIGFuZCBjb2xsZWN0CiAgICogICAgZXh0ZW5zaW9ucyBhbmQgQ0xTSUQncwogICAqIDIuIGl0ZXJhdGUgb3ZlciBjb2xsZWN0ZWQgQ0xTSUQncyBhbmQgY29weSBpdCdzIGRlc2NyaXB0aW9uIGFuZCBpdCdzCiAgICogICAgZXh0ZW5zaW9ucyB0byBzekZpbHRlciBpZiBpdCBmaXRzCiAgICoKICAgKiBGaXJzdCBmaWx0ZXIgaXMgbmFtZWQgIkFsbCBtdWx0aW1lZGlhIGZpbGVzIiBhbmQgaXQncyBmaWx0ZXIgaXMgYQogICAqIGNvbGxlY3Rpb24gb2YgYWxsIHBvc3NpYmxlIGV4dGVuc2lvbnMgZXhjZXB0ICIqLioiLgogICAqLwogIGlmIChSZWdPcGVuS2V5VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pBVklGaWxlRXh0ZW5zaW9ucywgJmhLZXkpICE9IFNfT0spIHsKICAgIEdsb2JhbEZyZWVQdHIobHApOwogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICB9CiAgZm9yIChuID0gMDtSZWdFbnVtS2V5VyhoS2V5LCBuLCBzekZpbGVFeHQsIHNpemVvZihzekZpbGVFeHQpKSA9PSBTX09LO24rKykgewogICAgLyogZ2V0IENMU0lEIHRvIGV4dGVuc2lvbiAqLwogICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKS9zaXplb2Yoc3pWYWx1ZVswXSk7CiAgICBpZiAoUmVnUXVlcnlWYWx1ZVcoaEtleSwgc3pGaWxlRXh0LCBzelZhbHVlLCAmc2l6ZSkgIT0gU19PSykKICAgICAgYnJlYWs7CgogICAgLyogc2VhcmNoIGlmIHRoZSBDTFNJRCBpcyBhbHJlYWR5IGtub3duICovCiAgICBmb3IgKGkgPSAxOyBpIDw9IGNvdW50OyBpKyspIHsKICAgICAgaWYgKGxzdHJjbXBXKGxwW2ldLnN6Q2xzaWQsIHN6VmFsdWUpID09IDApCglicmVhazsgLyogYSBuZXcgb25lICovCiAgICB9CgogICAgaWYgKGNvdW50IC0gaSA9PSAtMVUpIHsKICAgICAgLyogaXQncyBhIG5ldyBDTFNJRCAqLwoKICAgICAgLyogRklYTUU6IEhvdyBkbyB3ZSBnZXQgaW5mbydzIGFib3V0IHJlYWQvd3JpdGUgY2FwYWJpbGl0aWVzPyAqLwoKICAgICAgaWYgKGNvdW50ID49IE1BWF9GSUxURVJTKSB7CgkvKiB0cnkgdG8gaW5mb3JtIHVzZXIgb2Ygb3VyIGZ1bGwgZml4ZWQgc2l6ZSB0YWJsZSAqLwoJRVJSKCI6IE1vcmUgdGhhbiAlZCBmaWx0ZXJzIGZvdW5kISBBZGp1c3QgTUFYX0ZJTFRFUlMgaW4gZGxscy9hdmlmaWwzMi9hcGkuY1xuIiwgTUFYX0ZJTFRFUlMpOwoJYnJlYWs7CiAgICAgIH0KCiAgICAgIGxzdHJjcHlXKGxwW2ldLnN6Q2xzaWQsIHN6VmFsdWUpOwoKICAgICAgY291bnQrKzsKICAgIH0KCiAgICAvKiBhcHBlbmQgZXh0ZW5zaW9uIHRvIHRoZSBmaWx0ZXIgKi8KICAgIHdzcHJpbnRmVyhzelZhbHVlLCBzekV4dGVuc2lvbkZtdCwgc3pGaWxlRXh0KTsKICAgIGlmIChscFtpXS5zekV4dGVuc2lvbnNbMF0gPT0gMCkKICAgICAgbHN0cmNhdFcobHBbaV0uc3pFeHRlbnNpb25zLCBzelZhbHVlICsgMSk7CiAgICBlbHNlCiAgICAgIGxzdHJjYXRXKGxwW2ldLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSk7CgogICAgLyogYWxzbyBhcHBlbmQgdG8gdGhlICJhbGwgbXVsdGltZWRpYSItZmlsdGVyICovCiAgICBpZiAobHBbMF0uc3pFeHRlbnNpb25zWzBdID09IDApCiAgICAgIGxzdHJjYXRXKGxwWzBdLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSArIDEpOwogICAgZWxzZQogICAgICBsc3RyY2F0VyhscFswXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUpOwogIH0KICBSZWdDbG9zZUtleShoS2V5KTsKCiAgLyogMi4gZ2V0IGRlc2NyaXB0aW9ucyBmb3IgdGhlIENMU0lEcyBhbmQgZmlsbCBvdXQgc3pGaWx0ZXIgKi8KICBpZiAoUmVnT3BlbktleVcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6Q2xzaWQsICZoS2V5KSAhPSBTX09LKSB7CiAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7IG4gPD0gY291bnQ7IG4rKykgewogICAgLyogZmlyc3QgdGhlIGRlc2NyaXB0aW9uICovCiAgICBpZiAobiAhPSAwKSB7CiAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKHN6VmFsdWVbMF0pOwogICAgICBpZiAoUmVnUXVlcnlWYWx1ZVcoaEtleSwgbHBbbl0uc3pDbHNpZCwgc3pWYWx1ZSwgJnNpemUpID09IFNfT0spIHsKCXNpemUgPSBsc3RybGVuVyhzelZhbHVlKTsKCWxzdHJjcHluVyhzekZpbHRlciwgc3pWYWx1ZSwgY2JGaWx0ZXIpOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgc2l6ZSA9IExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSxJRFNfQUxMTVVMVElNRURJQSxzekZpbHRlcixjYkZpbHRlcik7CgogICAgLyogY2hlY2sgZm9yIGVub3VnaCBzcGFjZSAqLwogICAgc2l6ZSsrOwogICAgaWYgKGNiRmlsdGVyIDwgc2l6ZSArIGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAyKSB7CiAgICAgIHN6RmlsdGVyWzBdID0gMDsKICAgICAgc3pGaWx0ZXJbMV0gPSAwOwogICAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICB9CiAgICBjYkZpbHRlciAtPSBzaXplOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKCiAgICAvKiBhbmQgdGhlbiB0aGUgZmlsdGVyICovCiAgICBsc3RyY3B5blcoc3pGaWx0ZXIsIGxwW25dLnN6RXh0ZW5zaW9ucywgY2JGaWx0ZXIpOwogICAgc2l6ZSA9IGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAxOwogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgfQoKICBSZWdDbG9zZUtleShoS2V5KTsKICBHbG9iYWxGcmVlUHRyKGxwKTsKCiAgLyogYWRkICJBbGwgZmlsZXMiICIqLioiIGZpbHRlciBpZiBlbm91Z2ggc3BhY2UgbGVmdCAqLwogIHNpemUgPSBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BTExGSUxFUywKCQkgICAgIHN6QWxsRmlsZXMsIHNpemVvZihzekFsbEZpbGVzKSkgKyAxOwogIGlmIChjYkZpbHRlciA+IHNpemUpIHsKICAgIGludCBpOwoKICAgIC8qIHJlcGxhY2UgJ0AnIHdpdGggXDAwMCB0byBzZXBhcmF0ZSBkZXNjcmlwdGlvbiBvZiBmaWx0ZXIgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBzaXplICYmIHN6QWxsRmlsZXNbaV0gIT0gMDsgaSsrKSB7CiAgICAgIGlmIChzekFsbEZpbGVzW2ldID09ICdAJykgewoJc3pBbGxGaWxlc1tpXSA9IDA7CglicmVhazsKICAgICAgfQogICAgfQogICAgICAKICAgIG1lbWNweShzekZpbHRlciwgc3pBbGxGaWxlcywgc2l6ZSAqIHNpemVvZihzekFsbEZpbGVzWzBdKSk7CiAgICBzekZpbHRlciArPSBzaXplOwogICAgc3pGaWx0ZXJbMF0gPSAwOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIHN6RmlsdGVyWzBdID0gMDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQp9CgpzdGF0aWMgQk9PTCBBVklTYXZlT3B0aW9uc0ZtdENob29zZShIV05EIGhXbmQpCnsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBwT3B0aW9ucyA9IFNhdmVPcHRzLnBwT3B0aW9uc1tTYXZlT3B0cy5uQ3VycmVudF07CiAgQVZJU1RSRUFNSU5GT1cgICAgICAgc0luZm87CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaWYgKHBPcHRpb25zID09IE5VTEwgfHwgU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIHN0YXRlIVxuIik7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUluZm9XKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCSAgICAmc0luZm8sIHNpemVvZihzSW5mbykpKSkgewogICAgRVJSKCI6IEFWSVN0cmVhbUluZm9XIGZhaWxlZCFcbiIpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBDT01QVkFSUyBjdjsKICAgIEJPT0wgICAgIHJldDsKCiAgICBtZW1zZXQoJmN2LCAwLCBzaXplb2YoY3YpKTsKCiAgICBpZiAoKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX1ZBTElEKSA9PSAwKSB7CiAgICAgIG1lbXNldChwT3B0aW9ucywgMCwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgICBwT3B0aW9ucy0+ZmNjVHlwZSAgICA9IHN0cmVhbXR5cGVWSURFTzsKICAgICAgcE9wdGlvbnMtPmZjY0hhbmRsZXIgPSBjb21wdHlwZURJQjsKICAgICAgcE9wdGlvbnMtPmR3UXVhbGl0eSAgPSAoRFdPUkQpSUNRVUFMSVRZX0RFRkFVTFQ7CiAgICB9CgogICAgY3YuY2JTaXplICAgICA9IHNpemVvZihjdik7CiAgICBjdi5kd0ZsYWdzICAgID0gSUNNRl9DT01QVkFSU19WQUxJRDsKICAgIC8qY3YuZmNjVHlwZSAgICA9IHBPcHRpb25zLT5mY2NUeXBlOyAqLwogICAgY3YuZmNjSGFuZGxlciA9IHBPcHRpb25zLT5mY2NIYW5kbGVyOwogICAgY3YubFEgICAgICAgICA9IHBPcHRpb25zLT5kd1F1YWxpdHk7CiAgICBjdi5scFN0YXRlICAgID0gcE9wdGlvbnMtPmxwUGFybXM7CiAgICBjdi5jYlN0YXRlICAgID0gcE9wdGlvbnMtPmNiUGFybXM7CiAgICBpZiAocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfS0VZRlJBTUVTKQogICAgICBjdi5sS2V5ID0gcE9wdGlvbnMtPmR3S2V5RnJhbWVFdmVyeTsKICAgIGVsc2UKICAgICAgY3YubEtleSA9IDA7CiAgICBpZiAocE9wdGlvbnMtPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfREFUQVJBVEUpCiAgICAgIGN2LmxEYXRhUmF0ZSA9IHBPcHRpb25zLT5kd0J5dGVzUGVyU2Vjb25kIC8gMTAyNDsgLyogbmVlZCBrQnl0ZXMgKi8KICAgIGVsc2UKICAgICAgY3YubERhdGFSYXRlID0gMDsKCiAgICByZXQgPSBJQ0NvbXByZXNzb3JDaG9vc2UoaFduZCwgU2F2ZU9wdHMudUZsYWdzLCBOVUxMLAoJCQkgICAgIFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sICZjdiwgTlVMTCk7CgogICAgaWYgKHJldCkgewogICAgICBwT3B0aW9ucy0+ZmNjSGFuZGxlciA9IGN2LmZjY0hhbmRsZXI7CiAgICAgIHBPcHRpb25zLT5scFBhcm1zICAgPSBjdi5scFN0YXRlOwogICAgICBwT3B0aW9ucy0+Y2JQYXJtcyAgID0gY3YuY2JTdGF0ZTsKICAgICAgcE9wdGlvbnMtPmR3UXVhbGl0eSA9IGN2LmxROwogICAgICBpZiAoY3YubEtleSAhPSAwKSB7CglwT3B0aW9ucy0+ZHdLZXlGcmFtZUV2ZXJ5ID0gY3YubEtleTsKCXBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9LRVlGUkFNRVM7CiAgICAgIH0gZWxzZQoJcE9wdGlvbnMtPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9LRVlGUkFNRVM7CiAgICAgIGlmIChjdi5sRGF0YVJhdGUgIT0gMCkgewoJcE9wdGlvbnMtPmR3Qnl0ZXNQZXJTZWNvbmQgPSBjdi5sRGF0YVJhdGUgKiAxMDI0OyAvKiBuZWVkIGJ5dGVzICovCglwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfREFUQVJBVEU7CiAgICAgIH0gZWxzZQoJcE9wdGlvbnMtPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9EQVRBUkFURTsKICAgICAgcE9wdGlvbnMtPmR3RmxhZ3MgIHw9IEFWSUNPTVBSRVNTRl9WQUxJRDsKICAgIH0KICAgIElDQ29tcHJlc3NvckZyZWUoJmN2KTsKCiAgICByZXR1cm4gcmV0OwogIH0gZWxzZSBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIEFDTUZPUk1BVENIT09TRVcgYWZtdGM7CiAgICBNTVJFU1VMVCAgICAgICAgIHJldDsKICAgIExPTkcgICAgICAgICAgICAgc2l6ZTsKCiAgICAvKiBGSVhNRTogY2hlY2sgQUNNIHZlcnNpb24gLS0gV2hpY2ggdmVyc2lvbiBpcyBuZWVkZWQ/ICovCgogICAgbWVtc2V0KCZhZm10YywgMCwgc2l6ZW9mKGFmbXRjKSk7CiAgICBhZm10Yy5jYlN0cnVjdCAgPSBzaXplb2YoYWZtdGMpOwogICAgYWZtdGMuZmR3U3R5bGUgID0gMDsKICAgIGFmbXRjLmh3bmRPd25lciA9IGhXbmQ7CgogICAgYWNtTWV0cmljcyhOVUxMLCBBQ01fTUVUUklDX01BWF9TSVpFX0ZPUk1BVCwgJnNpemUpOwogICAgaWYgKChwT3B0aW9ucy0+Y2JGb3JtYXQgPT0gMCB8fCBwT3B0aW9ucy0+bHBGb3JtYXQgPT0gTlVMTCkgJiYgc2l6ZSAhPSAwKSB7CiAgICAgIHBPcHRpb25zLT5scEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIHNpemUpOwogICAgICBwT3B0aW9ucy0+Y2JGb3JtYXQgPSBzaXplOwogICAgfSBlbHNlIGlmIChwT3B0aW9ucy0+Y2JGb3JtYXQgPCAoRFdPUkQpc2l6ZSkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBHbG9iYWxSZUFsbG9jUHRyKHBPcHRpb25zLT5scEZvcm1hdCwgc2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICAgIHBPcHRpb25zLT5jYkZvcm1hdCA9IHNpemU7CiAgICB9CiAgICBpZiAocE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKICAgIGFmbXRjLnB3ZnggID0gcE9wdGlvbnMtPmxwRm9ybWF0OwogICAgYWZtdGMuY2J3ZnggPSBwT3B0aW9ucy0+Y2JGb3JtYXQ7CgogICAgc2l6ZSA9IDA7CiAgICBBVklTdHJlYW1Gb3JtYXRTaXplKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCXNJbmZvLmR3U3RhcnQsICZzaXplKTsKICAgIGlmIChzaXplIDwgKExPTkcpc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgICBzaXplID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwogICAgYWZtdGMucHdmeEVudW0gPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplKTsKICAgIGlmIChhZm10Yy5wd2Z4RW51bSAhPSBOVUxMKSB7CiAgICAgIEFWSVN0cmVhbVJlYWRGb3JtYXQoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJICBzSW5mby5kd1N0YXJ0LCBhZm10Yy5wd2Z4RW51bSwgJnNpemUpOwogICAgICBhZm10Yy5mZHdFbnVtID0gQUNNX0ZPUk1BVEVOVU1GX0NPTlZFUlQ7CiAgICB9CgogICAgcmV0ID0gYWNtRm9ybWF0Q2hvb3NlVygmYWZtdGMpOwogICAgaWYgKHJldCA9PSBTX09LKQogICAgICBwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfVkFMSUQ7CgogICAgaWYgKGFmbXRjLnB3ZnhFbnVtICE9IE5VTEwpCiAgICAgIEdsb2JhbEZyZWVQdHIoYWZtdGMucHdmeEVudW0pOwoKICAgIHJldHVybiAocmV0ID09IFNfT0sgPyBUUlVFIDogRkFMU0UpOwogIH0gZWxzZSB7CiAgICBFUlIoIjogdW5rbm93biBzdHJlYW10eXBlIDB4JTA4bFhcbiIsIHNJbmZvLmZjY1R5cGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KfQoKc3RhdGljIHZvaWQgQVZJU2F2ZU9wdGlvbnNVcGRhdGUoSFdORCBoV25kKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmlkZW9GbXRbXT17JyUnLCdsJywnZCcsJ3gnLCclJywnbCcsJ2QnLCd4JywnJScsJ2QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekF1ZGlvRm10W109eyclJywncycsJyAnLCclJywncycsMH07CgogIFdDSEFSICAgICAgICAgIHN6Rm9ybWF0WzEyOF07CiAgQVZJU1RSRUFNSU5GT1cgc0luZm87CiAgTFBWT0lEICAgICAgICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgc2l6ZTsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBTYXZlT3B0cy5uQ3VycmVudCA9IFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCxJRENfU1RSRUFNLENCX0dFVENVUlNFTCwwLDApOwogIGlmIChTYXZlT3B0cy5uQ3VycmVudCA8IDApCiAgICByZXR1cm47CgogIGlmIChGQUlMRUQoQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpCiAgICByZXR1cm47CgogIEFWSVN0cmVhbUZvcm1hdFNpemUoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSxzSW5mby5kd1N0YXJ0LCZzaXplKTsKICBpZiAoc2l6ZSA+IDApIHsKICAgIHN6Rm9ybWF0WzBdID0gMDsKCiAgICAvKiByZWFkIGZvcm1hdCB0byBidWlsZCBmb3JtYXQgZGVzY3Jpb3Rpb24gc3RyaW5nICovCiAgICBscEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUpOwogICAgaWYgKGxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sc0luZm8uZHdTdGFydCxscEZvcm1hdCwgJnNpemUpKSkgewoJaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CgkgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gbHBGb3JtYXQ7CgkgIElDSU5GTyBpY2luZm87CgoJICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6VmlkZW9GbXQsIGxwYmktPmJpV2lkdGgsCgkJICAgIGxwYmktPmJpSGVpZ2h0LCBscGJpLT5iaUJpdENvdW50KTsKCgkgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQikgewoJICAgIEhJQyAgICBoaWM7CgoJICAgIGhpYyA9IElDTG9jYXRlKElDVFlQRV9WSURFTywgc0luZm8uZmNjSGFuZGxlciwgbHBGb3JtYXQsCgkJCSAgIE5VTEwsIElDTU9ERV9ERUNPTVBSRVNTKTsKCSAgICBpZiAoaGljICE9IE5VTEwpIHsKCSAgICAgIGlmIChJQ0dldEluZm8oaGljLCAmaWNpbmZvLCBzaXplb2YoaWNpbmZvKSkgPT0gU19PSykKCQlsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICAgICAgSUNDbG9zZShoaWMpOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19VTkNPTVBSRVNTRUQsCgkJCWljaW5mby5zekRlc2NyaXB0aW9uLCBzaXplb2YoaWNpbmZvLnN6RGVzY3JpcHRpb24pKTsKCSAgICBsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICB9Cgl9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CgkgIEFDTUZPUk1BVFRBR0RFVEFJTFNXIGFmdGQ7CgkgIEFDTUZPUk1BVERFVEFJTFNXICAgIGFmZDsKCgkgIG1lbXNldCgmYWZ0ZCwgMCwgc2l6ZW9mKGFmdGQpKTsKCSAgbWVtc2V0KCZhZmQsIDAsIHNpemVvZihhZmQpKTsKCgkgIGFmdGQuY2JTdHJ1Y3QgICAgID0gc2l6ZW9mKGFmdGQpOwoJICBhZnRkLmR3Rm9ybWF0VGFnICA9IGFmZC5kd0Zvcm1hdFRhZyA9CgkgICAgKChQV0FWRUZPUk1BVEVYKWxwRm9ybWF0KS0+d0Zvcm1hdFRhZzsKCSAgYWZ0ZC5jYkZvcm1hdFNpemUgPSBhZmQuY2J3ZnggPSBzaXplOwoKCSAgYWZkLmNiU3RydWN0ICAgICAgPSBzaXplb2YoYWZkKTsKCSAgYWZkLnB3ZnggICAgICAgICAgPSBscEZvcm1hdDsKCgkgIGlmIChhY21Gb3JtYXRUYWdEZXRhaWxzVyhOVUxMLCAmYWZ0ZCwKCQkJCSAgIEFDTV9GT1JNQVRUQUdERVRBSUxTRl9GT1JNQVRUQUcpID09IFNfT0spIHsKCSAgICBpZiAoYWNtRm9ybWF0RGV0YWlsc1coTlVMTCwmYWZkLEFDTV9GT1JNQVRERVRBSUxTRl9GT1JNQVQpID09IFNfT0spCgkgICAgICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6QXVkaW9GbXQsIGFmZC5zekZvcm1hdCwgYWZ0ZC5zekZvcm1hdFRhZyk7CgkgIH0KCX0KICAgICAgfQogICAgICBHbG9iYWxGcmVlUHRyKGxwRm9ybWF0KTsKICAgIH0KCiAgICAvKiBzZXQgdGV4dCBmb3IgZm9ybWF0IGRlc2NyaXB0aW9uICovCiAgICBTZXREbGdJdGVtVGV4dFcoaFduZCwgSURDX0ZPUk1BVFRFWFQsIHN6Rm9ybWF0KTsKCiAgICAvKiBEaXNhYmxlIG9wdGlvbiBidXR0b24gZm9yIHVuc3VwcG9ydGVkIHN0cmVhbXR5cGVzICovCiAgICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8gfHwKCXNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfT1BUSU9OUyksIFRSVUUpOwogICAgZWxzZQogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfT1BUSU9OUyksIEZBTFNFKTsKICB9Cgp9CgpJTlRfUFRSIENBTExCQUNLIEFWSVNhdmVPcHRpb25zRGxnUHJvYyhIV05EIGhXbmQsIFVJTlQgdU1zZywKCQkJCSAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgRFdPUkQgZHdJbnRlcmxlYXZlOwogIEJPT0wgIGJJc0ludGVybGVhdmVkOwogIElOVCAgIG47CgogIC8qVFJBQ0UoIiglcCwldSwweCUwNFgsMHglMDhsWClcbiIsIGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsqLwoKICBzd2l0Y2ggKHVNc2cpIHsKICBjYXNlIFdNX0lOSVRESUFMT0c6CiAgICBTYXZlT3B0cy5uQ3VycmVudCA9IDA7CiAgICBpZiAoU2F2ZU9wdHMublN0cmVhbXMgPT0gMSkgewogICAgICBFbmREaWFsb2coaFduZCwgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoaFduZCkpOwogICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICAvKiBhZGQgc3RyZWFtcyAqLwogICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKICAgICAgQVZJU1RSRUFNSU5GT1cgc0luZm87CgogICAgICBBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbbl0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CiAgICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfQUREU1RSSU5HLAoJCQkgIDBMLCAoTFBBUkFNKXNJbmZvLnN6TmFtZSk7CiAgICB9CgogICAgLyogc2VsZWN0IGZpcnN0IHN0cmVhbSAqLwogICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLCBJRENfU1RSRUFNLCBDQl9TRVRDVVJTRUwsIDAsIDApOwogICAgU2VuZE1lc3NhZ2VXKGhXbmQsIFdNX0NPTU1BTkQsCgkJIEdFVF9XTV9DT01NQU5EX01QUyhJRENfU1RSRUFNLCBoV25kLCBDQk5fU0VMQ0hBTkdFKSk7CgogICAgLyogaW5pdGlhbGl6ZSBpbnRlcmxlYXZlICovCiAgICBpZiAoU2F2ZU9wdHMucHBPcHRpb25zWzBdICE9IE5VTEwgJiYKCShTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfVkFMSUQpKSB7CiAgICAgIGJJc0ludGVybGVhdmVkID0gKFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFKTsKICAgICAgZHdJbnRlcmxlYXZlID0gU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ludGVybGVhdmVFdmVyeTsKICAgIH0gZWxzZSB7CiAgICAgIGJJc0ludGVybGVhdmVkID0gVFJVRTsKICAgICAgZHdJbnRlcmxlYXZlICAgPSAwOwogICAgfQogICAgQ2hlY2tEbGdCdXR0b24oaFduZCwgSURDX0lOVEVSTEVBVkUsIGJJc0ludGVybGVhdmVkKTsKICAgIFNldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgZHdJbnRlcmxlYXZlLCBGQUxTRSk7CiAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwgYklzSW50ZXJsZWF2ZWQpOwogICAgYnJlYWs7CiAgY2FzZSBXTV9DT01NQU5EOgogICAgc3dpdGNoIChHRVRfV01fQ09NTUFORF9JRCh3UGFyYW0sIGxQYXJhbSkpIHsKICAgIGNhc2UgSURPSzoKICAgICAgLyogZ2V0IGRhdGEgZnJvbSBjb250cm9scyBhbmQgc2F2ZSB0aGVtICovCiAgICAgIGR3SW50ZXJsZWF2ZSAgID0gR2V0RGxnSXRlbUludChoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZLCBOVUxMLCAwKTsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSBJc0RsZ0J1dHRvbkNoZWNrZWQoaFduZCwgSURDX0lOVEVSTEVBVkUpOwogICAgICBmb3IgKG4gPSAwOyBuIDwgU2F2ZU9wdHMublN0cmVhbXM7IG4rKykgewoJaWYgKFNhdmVPcHRzLnBwT3B0aW9uc1tuXSAhPSBOVUxMKSB7CgkgIGlmIChiSXNJbnRlcmxlYXZlZCkgewoJICAgIFNhdmVPcHRzLnBwT3B0aW9uc1tuXS0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfSU5URVJMRUFWRTsKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3SW50ZXJsZWF2ZUV2ZXJ5ID0gZHdJbnRlcmxlYXZlOwoJICB9IGVsc2UKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFOwoJfQogICAgICB9CiAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBJRENBTkNFTDoKICAgICAgRW5kRGlhbG9nKGhXbmQsIEdFVF9XTV9DT01NQU5EX0lEKHdQYXJhbSwgbFBhcmFtKSA9PSBJRE9LKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19JTlRFUkxFQVZFOgogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwKCQkgICBJc0RsZ0J1dHRvbkNoZWNrZWQoaFduZCwgSURDX0lOVEVSTEVBVkUpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19TVFJFQU06CiAgICAgIGlmIChHRVRfV01fQ09NTUFORF9DTUQod1BhcmFtLCBsUGFyYW0pID09IENCTl9TRUxDSEFOR0UpIHsKCS8qIHVwZGF0ZSBjb250cm9sIGVsZW1lbnRzICovCglBVklTYXZlT3B0aW9uc1VwZGF0ZShoV25kKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgSURDX09QVElPTlM6CiAgICAgIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKGhXbmQpOwogICAgICBicmVhazsKICAgIH07CiAgICByZXR1cm4gVFJVRTsKICB9OwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZU9wdGlvbnMJCShBVklGSUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgQVZJU2F2ZU9wdGlvbnMoSFdORCBoV25kLCBVSU5UIHVGbGFncywgSU5UIG5TdHJlYW1zLAoJCQkgICBQQVZJU1RSRUFNICpwcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgKnBwT3B0aW9ucykKewogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBTYXZlZE9wdGlvbnMgPSBOVUxMOwogIElOVCByZXQsIG47CgogIFRSQUNFKCIoJXAsMHglWCwlZCwlcCwlcClcbiIsIGhXbmQsIHVGbGFncywgblN0cmVhbXMsCglwcGF2aSwgcHBPcHRpb25zKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChuU3RyZWFtcyA8PSAwIHx8IHBwYXZpID09IE5VTEwgfHwgcHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBzYXZlIG9wdGlvbnMgZm9yIGNhc2UgdXNlciBwcmVzcyBjYW5jZWwgKi8KICBpZiAocHBPcHRpb25zICE9IE5VTEwgJiYgblN0cmVhbXMgPiAxKSB7CiAgICBwU2F2ZWRPcHRpb25zID0gR2xvYmFsQWxsb2NQdHIoR0hORCxuU3RyZWFtcyAqIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgIGlmIChwU2F2ZWRPcHRpb25zID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgICBpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgltZW1jcHkocFNhdmVkT3B0aW9ucyArIG4sIHBwT3B0aW9uc1tuXSwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgfQogIH0KCiAgU2F2ZU9wdHMudUZsYWdzICAgID0gdUZsYWdzOwogIFNhdmVPcHRzLm5TdHJlYW1zICA9IG5TdHJlYW1zOwogIFNhdmVPcHRzLnBwYXZpcyAgICA9IHBwYXZpOwogIFNhdmVPcHRzLnBwT3B0aW9ucyA9IHBwT3B0aW9uczsKCiAgcmV0ID0gRGlhbG9nQm94VyhBVklGSUxFX2hNb2R1bGUsIE1BS0VJTlRSRVNPVVJDRVcoSUREX1NBVkVPUFRJT05TKSwKCQkgICBoV25kLCBBVklTYXZlT3B0aW9uc0RsZ1Byb2MpOwoKICBpZiAocmV0ID09IC0xKQogICAgcmV0ID0gRkFMU0U7CgogIC8qIHJlc3RvcmUgb3B0aW9ucyB3aGVuIHVzZXIgcHJlc3NlZCBjYW5jZWwgKi8KICBpZiAocFNhdmVkT3B0aW9ucyAhPSBOVUxMKSB7CiAgICBpZiAocmV0ID09IEZBTFNFKSB7CiAgICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CglpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgkgIG1lbWNweShwcE9wdGlvbnNbbl0sIHBTYXZlZE9wdGlvbnMgKyBuLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICAgIH0KICAgIH0KICAgIEdsb2JhbEZyZWVQdHIocFNhdmVkT3B0aW9ucyk7CiAgfQoKICByZXR1cm4gKEJPT0wpcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMMzIuQCkKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMRS4xMjQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlT3B0aW9uc0ZyZWUoSU5UIG5TdHJlYW1zLExQQVZJQ09NUFJFU1NPUFRJT05TKnBwT3B0aW9ucykKewogIFRSQUNFKCIoJWQsJXApXG4iLCBuU3RyZWFtcywgcHBPcHRpb25zKTsKCiAgaWYgKG5TdHJlYW1zIDwgMCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBuU3RyZWFtcyA+IDA7IG5TdHJlYW1zLS0pIHsKICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdICE9IE5VTEwpIHsKICAgICAgcHBPcHRpb25zW25TdHJlYW1zXS0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX1ZBTElEOwoKICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgIT0gTlVMTCkgewoJR2xvYmFsRnJlZVB0cihwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zKTsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgPSBOVUxMOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+Y2JQYXJtcyA9IDA7CiAgICAgIH0KICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0ICE9IE5VTEwpIHsKCUdsb2JhbEZyZWVQdHIocHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQpOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQgPSBOVUxMOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+Y2JGb3JtYXQgPSAwOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVWQQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlVkEoTFBDU1RSIHN6RmlsZSwgQ0xTSUQgKnBjbHNpZEhhbmRsZXIsCgkJCSBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLCBpbnQgblN0cmVhbSwKCQkJIFBBVklTVFJFQU0gKnBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcGxwT3B0aW9ucykKewogIExQV1NUUiAgd3N6RmlsZSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKICBpbnQgICAgIGxlbjsKCiAgVFJBQ0UoIiVzLCVwLCVwLCVkLCVwLCVwKVxuIiwgZGVidWdzdHJfYShzekZpbGUpLCBwY2xzaWRIYW5kbGVyLAoJbHBmbkNhbGxiYWNrLCBuU3RyZWFtLCBwcGF2aSwgcGxwT3B0aW9ucyk7CgogIGlmIChzekZpbGUgPT0gTlVMTCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBscE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIGNvbnZlcnQgQVNDSUkgc3RyaW5nIHRvIFVuaWNvZGUgYW5kIGNhbGwgVW5pY29kZSBmdW5jdGlvbiAqLwogIGxlbiA9IGxzdHJsZW5BKHN6RmlsZSk7CiAgaWYgKGxlbiA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgd3N6RmlsZSA9IChMUFdTVFIpTG9jYWxBbGxvYyhMUFRSLCAobGVuICsgMSkgKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4gKyAxKTsKICB3c3pGaWxlW2xlbiArIDFdID0gMDsKCiAgaHIgPSBBVklTYXZlVlcod3N6RmlsZSwgcGNsc2lkSGFuZGxlciwgbHBmbkNhbGxiYWNrLAoJCSBuU3RyZWFtLCBwcGF2aSwgcGxwT3B0aW9ucyk7CgogIExvY2FsRnJlZSgoSExPQ0FMKXdzekZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRklMRV9BVklTYXZlRGVmYXVsdENhbGxiYWNrCShpbnRlcm5hbCkKICovCnN0YXRpYyBCT09MIFdJTkFQSSBBVklGSUxFX0FWSVNhdmVEZWZhdWx0Q2FsbGJhY2soSU5UIHByb2dyZXNzKQp7CiAgVFJBQ0UoIiglZClcbiIsIHByb2dyZXNzKTsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVWVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlVlcoTFBDV1NUUiBzekZpbGUsIENMU0lEICpwY2xzaWRIYW5kbGVyLAoJCQkgQVZJU0FWRUNBTExCQUNLIGxwZm5DYWxsYmFjaywgaW50IG5TdHJlYW1zLAoJCQkgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwbHBPcHRpb25zKQp7CiAgTE9ORyAgICAgICAgICAgbFN0YXJ0W01BWF9BVklTVFJFQU1TXTsKICBQQVZJU1RSRUFNICAgICBwT3V0U3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CiAgUEFWSVNUUkVBTSAgICAgcEluU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CiAgQVZJRklMRUlORk9XICAgZkluZm87CiAgQVZJU1RSRUFNSU5GT1cgc0luZm87CgogIFBBVklGSUxFICAgICAgIHBmaWxlID0gTlVMTDsgLyogdGhlIG91dHB1dCBBVkkgZmlsZSAqLwogIExPTkcgICAgICAgICAgIGxGaXJzdFZpZGVvID0gLTE7CiAgaW50ICAgICAgICAgICAgY3VyU3RyZWFtOwoKICAvKiBmb3IgaW50ZXJsZWF2aW5nIC4uLiAqLwogIERXT1JEICAgICAgICAgIGR3SW50ZXJsZWF2ZSA9IDA7IC8qIGludGVybGVhdmUgcmF0ZSAqLwogIERXT1JEICAgICAgICAgIGR3RmlsZUluaXRpYWxGcmFtZXM7CiAgTE9ORyAgICAgICAgICAgbEZpbGVMZW5ndGg7CiAgTE9ORyAgICAgICAgICAgbFNhbXBsZUluYzsKCiAgLyogZm9yIHJlYWRpbmcvd3JpdGluZyB0aGUgZGF0YSAuLi4gKi8KICBMUFZPSUQgICAgICAgICBscEJ1ZmZlciA9IE5VTEw7CiAgTE9ORyAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgICAvKiByZWFsIHNpemUgb2YgbHBCdWZmZXIgKi8KICBMT05HICAgICAgICAgICBsQnVmZmVyU2l6ZTsgICAgIC8qIG5lZWRlZCBieXRlcyBmb3IgZm9ybWF0KHMpLCBldGMuICovCiAgTE9ORyAgICAgICAgICAgbFJlYWRCeXRlczsKICBMT05HICAgICAgICAgICBsUmVhZFNhbXBsZXM7CiAgSFJFU1VMVCAgICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcywlcCwlcCwlZCwlcCwlcClcbiIsIGRlYnVnc3RyX3coc3pGaWxlKSwgcGNsc2lkSGFuZGxlciwKCWxwZm5DYWxsYmFjaywgblN0cmVhbXMsIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgaWYgKHN6RmlsZSA9PSBOVUxMIHx8IHBwYXZpID09IE5VTEwgfHwgcGxwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoblN0cmVhbXMgPj0gTUFYX0FWSVNUUkVBTVMpIHsKICAgIFdBUk4oIkNhbid0IHdyaXRlIEFWSSB3aXRoICVkIHN0cmVhbXMgb25seSBzdXBwb3J0cyAlZCAtLSBjaGFuZ2UgTUFYX0FWSVNUUkVBTVMhXG4iLCBuU3RyZWFtcywgTUFYX0FWSVNUUkVBTVMpOwogICAgcmV0dXJuIEFWSUVSUl9JTlRFUk5BTDsKICB9CgogIGlmIChscGZuQ2FsbGJhY2sgPT0gTlVMTCkKICAgIGxwZm5DYWxsYmFjayA9IEFWSUZJTEVfQVZJU2F2ZURlZmF1bHRDYWxsYmFjazsKCiAgLyogY2xlYXIgbG9jYWwgdmFyaWFibGUocykgKi8KICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgcEluU3RyZWFtc1tjdXJTdHJlYW1dICA9IE5VTEw7CiAgICBwT3V0U3RyZWFtc1tjdXJTdHJlYW1dID0gTlVMTDsKICB9CgogIC8qIG9wZW4gb3V0cHV0IEFWSSBmaWxlIChjcmVhdGUgaXQgaWYgaXQgZG9lc24ndCBleGlzdCkgKi8KICBocmVzID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBPRl9DUkVBVEV8T0ZfU0hBUkVfRVhDTFVTSVZFfE9GX1dSSVRFLAoJCSAgICAgIHBjbHNpZEhhbmRsZXIpOwogIGlmIChGQUlMRUQoaHJlcykpCiAgICByZXR1cm4gaHJlczsKICBBVklGaWxlSW5mb1cocGZpbGUsICZmSW5mbywgc2l6ZW9mKGZJbmZvKSk7IC8qIGZvciBkd0NhcHMgKi8KCiAgLyogaW5pdGlhbGl6ZSBvdXIgZGF0YSBzdHJ1Y3R1cmVzIHBhcnQgMSAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBQQVZJU1RSRUFNIHBDdXJTdHJlYW0gPSBwcGF2aVtjdXJTdHJlYW1dOwoKICAgIGhyZXMgPSBBVklTdHJlYW1JbmZvVyhwQ3VyU3RyZWFtLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgaWYgKEZBSUxFRChocmVzKSkKICAgICAgZ290byBlcnJvcjsKCiAgICAvKiBzZWFyY2ggZmlyc3QgdmlkZW8gc3RyZWFtIGFuZCBjaGVjayBmb3IgaW50ZXJsZWF2aW5nICovCiAgICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgLyogcmVtZW1iZXIgZmlyc3QgdmlkZW8gc3RyZWFtIC0tIG5lZWRlZCBmb3IgaW50ZXJsZWF2aW5nICovCiAgICAgIGlmIChsRmlyc3RWaWRlbyA8IDApCglsRmlyc3RWaWRlbyA9IGN1clN0cmVhbTsKICAgIH0gZWxzZSBpZiAoIWR3SW50ZXJsZWF2ZSAmJiBwbHBPcHRpb25zICE9IE5VTEwpIHsKICAgICAgLyogY2hlY2sgaWYgYW55IG5vbi12aWRlbyBzdHJlYW0gd2FudHMgdG8gYmUgaW50ZXJsZWF2ZWQgKi8KICAgICAgV0FSTigib3B0aW9ucy5mbGFncz0weCVsWCBvcHRpb25zLmR3SW50ZXJsZWF2ZT0lbHVcbiIscGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ZsYWdzLHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdJbnRlcmxlYXZlRXZlcnkpOwogICAgICBpZiAocGxwT3B0aW9uc1tjdXJTdHJlYW1dICE9IE5VTEwgJiYKCSAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkUpCglkd0ludGVybGVhdmUgPSBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3SW50ZXJsZWF2ZUV2ZXJ5OwogICAgfQoKICAgIC8qIGNyZWF0ZSBkZS0vY29tcHJlc3NlZCBzdHJlYW0gaW50ZXJmYWNlIGlmIG5lZWRlZCAqLwogICAgcEluU3RyZWFtc1tjdXJTdHJlYW1dID0gTlVMTDsKICAgIGlmIChwbHBPcHRpb25zICE9IE5VTEwgJiYgcGxwT3B0aW9uc1tjdXJTdHJlYW1dICE9IE5VTEwpIHsKICAgICAgaWYgKHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZmNjSGFuZGxlciB8fAoJICBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmxwRm9ybWF0ICE9IE5VTEwpIHsKCURXT1JEIGR3S2V5U2F2ZSA9IHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5OwoKCWlmIChmSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19BTExLRVlGUkFNRVMpCgkgIHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5ID0gMTsKCglocmVzID0gQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0oJnBJblN0cmVhbXNbY3VyU3RyZWFtXSwgcEN1clN0cmVhbSwKCQkJCSAgICAgICBwbHBPcHRpb25zW2N1clN0cmVhbV0sIE5VTEwpOwoJcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0tleUZyYW1lRXZlcnkgPSBkd0tleVNhdmU7CglpZiAoRkFJTEVEKGhyZXMpIHx8IHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9PSBOVUxMKSB7CgkgIHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IE5VTEw7CgkgIGdvdG8gZXJyb3I7Cgl9CgoJLyogdGVzdCBzdHJlYW0gaW50ZXJmYWNlIGFuZCB1cGRhdGUgc3RyZWFtLWluZm8gKi8KCWhyZXMgPSBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBnb3RvIGVycm9yOwogICAgICB9CiAgICB9CgogICAgLyogbm93IGhhbmRsZSBzdHJlYW1zIHdoaWNoIHdpbGwgb25seSBiZSBjb3BpZWQgKi8KICAgIGlmIChwSW5TdHJlYW1zW2N1clN0cmVhbV0gPT0gTlVMTCkgewogICAgICBwQ3VyU3RyZWFtID0gcEluU3RyZWFtc1tjdXJTdHJlYW1dID0gcHBhdmlbY3VyU3RyZWFtXTsKICAgICAgQVZJU3RyZWFtQWRkUmVmKHBDdXJTdHJlYW0pOwogICAgfSBlbHNlCiAgICAgIHBDdXJTdHJlYW0gPSBwSW5TdHJlYW1zW2N1clN0cmVhbV07CgogICAgbFN0YXJ0W2N1clN0cmVhbV0gPSBzSW5mby5kd1N0YXJ0OwogIH0gLyogZm9yIGFsbCBzdHJlYW1zICovCgogIC8qIGNoZWNrIHRoYXQgZmlyc3QgdmlkZW8gc3RyZWFtIGlzIHRoZSBmaXJzdCBzdHJlYW0gKi8KICBpZiAobEZpcnN0VmlkZW8gPiAwKSB7CiAgICBQQVZJU1RSRUFNIHBUbXAgPSBwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXTsKICAgIExPTkcgbFRtcCA9IGxTdGFydFtsRmlyc3RWaWRlb107CgogICAgcEluU3RyZWFtc1tsRmlyc3RWaWRlb10gPSBwSW5TdHJlYW1zWzBdOwogICAgcEluU3RyZWFtc1swXSA9IHBUbXA7CiAgICBsU3RhcnRbbEZpcnN0VmlkZW9dID0gbFN0YXJ0WzBdOwogICAgbFN0YXJ0WzBdID0gbFRtcDsKICAgIGxGaXJzdFZpZGVvID0gMDsKICB9CgogIC8qIGFsbG9jYXRlIGJ1ZmZlciBmb3IgZm9ybWF0cywgZGF0YSwgZXRjLiBvZiBhbiBpbml0aWFsZSBzaXplIG9mIDY0IGtCeXRlICovCiAgbHBCdWZmZXIgPSBHbG9iYWxBbGxvY1B0cihHUFRSLCBjYkJ1ZmZlciA9IDB4MDAwMTAwMDApOwogIGlmIChscEJ1ZmZlciA9PSBOVUxMKSB7CiAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKICAgIGdvdG8gZXJyb3I7CiAgfQoKICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zWzBdLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogIGxGaWxlTGVuZ3RoID0gc0luZm8uZHdMZW5ndGg7CiAgZHdGaWxlSW5pdGlhbEZyYW1lcyA9IDA7CiAgaWYgKGxGaXJzdFZpZGVvID49IDApIHsKICAgIC8qIGNoZWNrIGZvciBjb3JyZWN0IHZlcnNpb24gb2YgdGhlIGZvcm1hdAogICAgICogIC0tIG5lZWQgYXRsZWFzdCBCSVRNQVBJTkZPSEVBREVSIG9yIG5ld2VyCiAgICAgKi8KICAgIGxTYW1wbGVJbmMgPSAxOwogICAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dLCBBVklTdHJlYW1TdGFydChwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXSksIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwogICAgaWYgKGxCdWZmZXJTaXplIDwgKExPTkcpc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKQogICAgICBocmVzID0gQVZJRVJSX0lOVEVSTkFMOwogICAgaWYgKEZBSUxFRChocmVzKSkKICAgICAgZ290byBlcnJvcjsKICB9IGVsc2UgLyogdXNlIG9uZSBzZWNvbmQgYmxvY2tzIGZvciBpbnRlcmxlYXZpbmcgaWYgbm8gdmlkZW8gcHJlc2VudCAqLwogICAgbFNhbXBsZUluYyA9IEFWSVN0cmVhbVRpbWVUb1NhbXBsZShwSW5TdHJlYW1zWzBdLCAxMDAwMDAwKTsKCiAgLyogY3JlYXRlIG91dHB1dCBzdHJlYW1zICovCiAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgIEFWSVN0cmVhbUluZm9XKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCiAgICBzSW5mby5kd0luaXRpYWxGcmFtZXMgPSAwOwogICAgaWYgKGR3SW50ZXJsZWF2ZSAhPSAwICYmIGN1clN0cmVhbSA+IDAgJiYgc0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgLyogNzUwIG1zIGluaXRpYWwgZnJhbWVzIGZvciBub24tdmlkZW8gc3RyZWFtcyAqLwogICAgICBzSW5mby5kd0luaXRpYWxGcmFtZXMgPSBBVklTdHJlYW1UaW1lVG9TYW1wbGUocEluU3RyZWFtc1swXSwgNzUwKTsKICAgIH0KCiAgICBocmVzID0gQVZJRmlsZUNyZWF0ZVN0cmVhbVcocGZpbGUsICZwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8pOwogICAgaWYgKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0gIT0gTlVMTCAmJiBTVUNDRUVERUQoaHJlcykpIHsKICAgICAgLyogY29weSBpbml0aWFsIGZvcm1hdCBmb3IgdGhpcyBzdHJlYW0gKi8KICAgICAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKICAgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkJIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwogICAgICBpZiAoRkFJTEVEKGhyZXMpKQoJZ290byBlcnJvcjsKICAgICAgaHJlcyA9IEFWSVN0cmVhbVNldEZvcm1hdChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAwLCBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwogICAgICBpZiAoRkFJTEVEKGhyZXMpKQoJZ290byBlcnJvcjsKCiAgICAgIC8qIHRyeSB0byBjb3B5IHN0cmVhbSBoYW5kbGVyIGRhdGEgKi8KICAgICAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKICAgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWREYXRhKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgY2tpZFNUUkVBTUhBTkRMRVJEQVRBLAoJCQkgICAgICAgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CiAgICAgIGlmIChTVUNDRUVERUQoaHJlcykgJiYgbEJ1ZmZlclNpemUgPiAwKSB7CglocmVzID0gQVZJU3RyZWFtV3JpdGVEYXRhKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sY2tpZFNUUkVBTUhBTkRMRVJEQVRBLAoJCQkJICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgZ290byBlcnJvcjsKICAgICAgfQoKICAgICAgaWYgKGR3RmlsZUluaXRpYWxGcmFtZXMgPCBzSW5mby5kd0luaXRpYWxGcmFtZXMpCglkd0ZpbGVJbml0aWFsRnJhbWVzID0gc0luZm8uZHdJbml0aWFsRnJhbWVzOwogICAgICBsUmVhZEJ5dGVzID0KCUFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKHBPdXRTdHJlYW1zWzBdLCBwSW5TdHJlYW1zW2N1clN0cmVhbV0sCgkJCQlzSW5mby5kd0xlbmd0aCk7CiAgICAgIGlmIChsRmlsZUxlbmd0aCA8IGxSZWFkQnl0ZXMpCglsRmlsZUxlbmd0aCA9IGxSZWFkQnl0ZXM7CiAgICB9IGVsc2UgewogICAgICAvKiBjcmVhdGlvbiBvZiBkZS0vY29tcHJlc3Npb24gc3RyZWFtIGludGVyZmFjZSBmYWlsZWQgKi8KICAgICAgV0FSTigiY3JlYXRpb24gb2YgKGRlLSljb21wcmVzc2lvbiBzdHJlYW0gZmFpbGVkIGZvciBzdHJlYW0gJWRcbiIsY3VyU3RyZWFtKTsKICAgICAgQVZJU3RyZWFtUmVsZWFzZShwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwogICAgICBpZiAoY3VyU3RyZWFtICsgMSA+PSBuU3RyZWFtcykgewoJLyogbW92ZSB0aGUgb3RoZXJzIG9uZSB1cCAqLwoJUEFWSVNUUkVBTSAqcHBhcyA9ICZwSW5TdHJlYW1zW2N1clN0cmVhbV07CglpbnQgICAgICAgICAgICBuID0gblN0cmVhbXMgLSAoY3VyU3RyZWFtICsgMSk7CgoJZG8gewoJICAqcHBhcyA9IHBJblN0cmVhbXNbY3VyU3RyZWFtICsgMV07Cgl9IHdoaWxlICgtLW4pOwogICAgICB9CiAgICAgIG5TdHJlYW1zLS07CiAgICAgIGN1clN0cmVhbS0tOwogICAgfQogIH0gLyogY3JlYXRlIG91dHB1dCBzdHJlYW1zIGZvciBhbGwgaW5wdXQgc3RyZWFtcyAqLwoKICAvKiBoYXZlIHdlIHN0aWxsIHNvbWV0aGluZyB0byB3cml0ZSwgb3IgbG9zdCBldmVyeXRoaW5nPyAqLwogIGlmIChuU3RyZWFtcyA8PSAwKQogICAgZ290byBlcnJvcjsKCiAgaWYgKGR3SW50ZXJsZWF2ZSkgewogICAgTE9ORyBsQ3VyRnJhbWUgPSAtZHdGaWxlSW5pdGlhbEZyYW1lczsKCiAgICAvKiBpbnRlcmxlYXZlZCBmaWxlICovCiAgICBpZiAoZHdJbnRlcmxlYXZlID09IDEpCiAgICAgIEFWSUZpbGVFbmRSZWNvcmQocGZpbGUpOwoKICAgIGZvciAoOyBsQ3VyRnJhbWUgPCBsRmlsZUxlbmd0aDsgbEN1ckZyYW1lICs9IGxTYW1wbGVJbmMpIHsKICAgICAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKCUxPTkcgbExhc3RTYW1wbGU7CgoJaHJlcyA9IEFWSVN0cmVhbUluZm9XKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBnb3RvIGVycm9yOwoKCS8qIGluaXRpYWwgZnJhbWVzIHBoYXNlIGF0IHRoZSBlbmQgZm9yIHRoaXMgc3RyZWFtPyAqLwoJaWYgKC0oTE9ORylzSW5mby5kd0luaXRpYWxGcmFtZXMgPiBsQ3VyRnJhbWUpCgkgIGNvbnRpbnVlOwoKCWlmICgobEZpbGVMZW5ndGggLSBsU2FtcGxlSW5jKSA8PSBsQ3VyRnJhbWUpIHsKCSAgbExhc3RTYW1wbGUgPSBBVklTdHJlYW1MZW5ndGgocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKCSAgbEZpcnN0VmlkZW8gPSBsTGFzdFNhbXBsZSArIEFWSVN0cmVhbVN0YXJ0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7Cgl9IGVsc2UgewoJICBpZiAoY3VyU3RyZWFtICE9IDApIHsKCSAgICBsRmlyc3RWaWRlbyA9CgkgICAgICBBVklTdHJlYW1TYW1wbGVUb1NhbXBsZShwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHBJblN0cmVhbXNbMF0sCgkJCQkgICAgICAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8gPyAKCQkJCSAgICAgICAoTE9ORylkd0ludGVybGVhdmUgOiBsU2FtcGxlSW5jKSArCgkJCQkgICAgICBzSW5mby5kd0luaXRpYWxGcmFtZXMgKyBsQ3VyRnJhbWUpOwoJICB9IGVsc2UKCSAgICBsRmlyc3RWaWRlbyA9IGxTYW1wbGVJbmMgKyAoc0luZm8uZHdJbml0aWFsRnJhbWVzICsgbEN1ckZyYW1lKTsKCgkgIGxMYXN0U2FtcGxlID0gQVZJU3RyZWFtRW5kKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CgkgIGlmIChsTGFzdFNhbXBsZSA8PSBsRmlyc3RWaWRlbykKCSAgICBsRmlyc3RWaWRlbyA9IGxMYXN0U2FtcGxlOwoJfQoKCS8qIGNvcHkgbmVlZGVkIHNhbXBsZXMgbm93ICovCglXQVJOKCJjb3B5IGZyb20gc3RyZWFtICVkIHNhbXBsZXMgJWxkIHRvICVsZC4uLlxuIixjdXJTdHJlYW0sCgkgICAgICBsU3RhcnRbY3VyU3RyZWFtXSxsRmlyc3RWaWRlbyk7Cgl3aGlsZSAobEZpcnN0VmlkZW8gPiBsU3RhcnRbY3VyU3RyZWFtXSkgewoJICBEV09SRCBmbGFncyA9IDA7CgoJICAvKiBjb3B5IGZvcm1hdCBmb3IgY2FzZSBpdCBjYW4gY2hhbmdlICovCgkgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CgkgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgbFN0YXJ0W2N1clN0cmVhbV0sCgkJCQkgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIEFWSVN0cmVhbVNldEZvcm1hdChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCBsU3RhcnRbY3VyU3RyZWFtXSwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogdHJ5IHRvIHJlYWQgZGF0YSB1bnRpbCB3ZSBnb3QgaXQsIG9yIGVycm9yICovCgkgIGRvIHsKCSAgICBocmVzID0gQVZJU3RyZWFtUmVhZChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGxTdGFydFtjdXJTdHJlYW1dLAoJCQkJIGxGaXJzdFZpZGVvIC0gbFN0YXJ0W2N1clN0cmVhbV0sIGxwQnVmZmVyLAoJCQkJIGNiQnVmZmVyLCAmbFJlYWRCeXRlcywgJmxSZWFkU2FtcGxlcyk7CgkgIH0gd2hpbGUgKChocmVzID09IEFWSUVSUl9CVUZGRVJUT09TTUFMTCkgJiYKCQkgICAobHBCdWZmZXIgPSBHbG9iYWxSZUFsbG9jUHRyKGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyLCBHUFRSKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICBpZiAoQVZJU3RyZWFtSXNLZXlGcmFtZShwSW5TdHJlYW1zW2N1clN0cmVhbV0sIChMT05HKXNJbmZvLmR3U3RhcnQpKQoJICAgIGZsYWdzID0gQVZJSUZfS0VZRlJBTUU7CgkgIGhyZXMgPSBBVklTdHJlYW1Xcml0ZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAtMSwgbFJlYWRTYW1wbGVzLAoJCQkJbHBCdWZmZXIsIGxSZWFkQnl0ZXMsIGZsYWdzLCBOVUxMLCBOVUxMKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoKCSAgbFN0YXJ0W2N1clN0cmVhbV0gKz0gbFJlYWRTYW1wbGVzOwoJfQoJbFN0YXJ0W2N1clN0cmVhbV0gPSBsRmlyc3RWaWRlbzsKICAgICAgfSAvKiBzdHJlYW0gYnkgc3RyZWFtICovCgogICAgICAvKiBuZWVkIHRvIGNsb3NlIHRoaXMgYmxvY2s/ICovCiAgICAgIGlmIChkd0ludGVybGVhdmUgPT0gMSkgewoJaHJlcyA9IEFWSUZpbGVFbmRSZWNvcmQocGZpbGUpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgYnJlYWs7CiAgICAgIH0KCiAgICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KICAgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoZHdGaWxlSW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSwgMTAwLAoJCQkgICAgICBkd0ZpbGVJbml0aWFsRnJhbWVzICsgbEZpbGVMZW5ndGgpKSkgewoJaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CglicmVhazsKICAgICAgfQogICAgfSAvKiBjb3B5IGZyYW1lIGJ5IGZyYW1lICovCiAgfSBlbHNlIHsKICAgIC8qIG5vbi1pbnRlcmxlYXZlZCBmaWxlICovCgogICAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgICAgLyogc2hvdyBwcm9ncmVzcyAqLwogICAgICBpZiAobHBmbkNhbGxiYWNrKE11bERpdihjdXJTdHJlYW0sIDEwMCwgblN0cmVhbXMpKSkgewoJaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7Cglnb3RvIGVycm9yOwogICAgICB9CgogICAgICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CgogICAgICBpZiAoc0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKCS8qIHNhbXBsZS1iYXNlZCBkYXRhIGxpa2UgYXVkaW8gKi8KCXdoaWxlIChzSW5mby5kd1N0YXJ0IDwgc0luZm8uZHdMZW5ndGgpIHsKCSAgTE9ORyBsU2FtcGxlcyA9IGNiQnVmZmVyIC8gc0luZm8uZHdTYW1wbGVTaXplOwoKCSAgLyogY29weSBmb3JtYXQgZm9yIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCQkgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIHJldHVybiBocmVzOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kYXJpZXMgKi8KCSAgaWYgKGxTYW1wbGVzICE9IChMT05HKShzSW5mby5kd0xlbmd0aCAtIHNJbmZvLmR3U3RhcnQpKQoJICAgIGxTYW1wbGVzID0gc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0OwoKCSAgLyogbm93IHRyeSB0byByZWFkIHVudGlsIHdlIGdvdCBpdCwgb3IgZXJyb3Igb2NjdXJlcyAqLwoJICBkbyB7CgkgICAgbFJlYWRCeXRlcyAgID0gY2JCdWZmZXI7CgkgICAgbFJlYWRTYW1wbGVzID0gMDsKCSAgICBocmVzID0gQVZJU3RyZWFtUmVhZChwSW5TdHJlYW1zW2N1clN0cmVhbV0sc0luZm8uZHdTdGFydCxsU2FtcGxlcywKCQkJCSBscEJ1ZmZlcixjYkJ1ZmZlciwmbFJlYWRCeXRlcywmbFJlYWRTYW1wbGVzKTsKCSAgfSB3aGlsZSAoKGhyZXMgPT0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMKSAmJgoJCSAgIChscEJ1ZmZlciA9IEdsb2JhbFJlQWxsb2NQdHIobHBCdWZmZXIsIGNiQnVmZmVyICo9IDIsIEdQVFIpKSAhPSBOVUxMKTsKCSAgaWYgKGxwQnVmZmVyID09IE5VTEwpCgkgICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgaWYgKGxSZWFkU2FtcGxlcyAhPSAwKSB7CgkgICAgc0luZm8uZHdTdGFydCArPSBsUmVhZFNhbXBsZXM7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQkgIGxwQnVmZmVyLCBsUmVhZEJ5dGVzLCAwLCBOVUxMICwgTlVMTCk7CgkgICAgaWYgKEZBSUxFRChocmVzKSkKCSAgICAgIGdvdG8gZXJyb3I7CgoJICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KCSAgICBpZiAobHBmbkNhbGxiYWNrKE11bERpdihzSW5mby5kd1N0YXJ0LDEwMCxuU3RyZWFtcypzSW5mby5kd0xlbmd0aCkrCgkJCSAgICAgTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CgkgICAgICBocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCSAgICAgIGdvdG8gZXJyb3I7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIGlmICgoc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0KSAhPSAxKSB7CgkgICAgICBocmVzID0gQVZJRVJSX0ZJTEVSRUFEOwoJICAgICAgZ290byBlcnJvcjsKCSAgICB9CgkgIH0KCX0KICAgICAgfSBlbHNlIHsKCS8qIGJsb2NrLWJhc2VkIGRhdGEgbGlrZSB2aWRlbyAqLwoJZm9yICg7IHNJbmZvLmR3U3RhcnQgPCBzSW5mby5kd0xlbmd0aDsgc0luZm8uZHdTdGFydCsrKSB7CgkgIERXT1JEIGZsYWdzID0gMDsKCgkgIC8qIGNvcHkgZm9ybWF0IGZvciBjYXNlIGl0IGNhbiBjaGFuZ2UgKi8KCSAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKCSAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogdHJ5IHRvIHJlYWQgYmxvY2sgYW5kIHJlc2l6ZSBidWZmZXIgaWYgbmVjZXNzYXJ5ICovCgkgIGRvIHsKCSAgICBsUmVhZFNhbXBsZXMgPSAwOwoJICAgIGxSZWFkQnl0ZXMgICA9IGNiQnVmZmVyOwoJICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwgMSwKCQkJCSBscEJ1ZmZlciwgY2JCdWZmZXIsJmxSZWFkQnl0ZXMsJmxSZWFkU2FtcGxlcyk7CgkgIH0gd2hpbGUgKChocmVzID09IEFWSUVSUl9CVUZGRVJUT09TTUFMTCkgJiYKCQkgICAobHBCdWZmZXIgPSBHbG9iYWxSZUFsbG9jUHRyKGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyLCBHUFRSKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIGlmIChsUmVhZFNhbXBsZXMgIT0gMSkgewoJICAgIGhyZXMgPSBBVklFUlJfRklMRVJFQUQ7CgkgICAgZ290byBlcnJvcjsKCSAgfQoKCSAgaWYgKEFWSVN0cmVhbUlzS2V5RnJhbWUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAoTE9ORylzSW5mby5kd1N0YXJ0KSkKCSAgICBmbGFncyA9IEFWSUlGX0tFWUZSQU1FOwoJICBocmVzID0gQVZJU3RyZWFtV3JpdGUocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgLTEsIGxSZWFkU2FtcGxlcywKCQkJCWxwQnVmZmVyLCBsUmVhZEJ5dGVzLCBmbGFncywgTlVMTCwgTlVMTCk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCgkgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KCSAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoc0luZm8uZHdTdGFydCwxMDAsblN0cmVhbXMqc0luZm8uZHdMZW5ndGgpKwoJCQkgICBNdWxEaXYoY3VyU3RyZWFtLCAxMDAsIG5TdHJlYW1zKSkpIHsKCSAgICBocmVzID0gQVZJRVJSX1VTRVJBQk9SVDsKCSAgICBnb3RvIGVycm9yOwoJICB9Cgl9IC8qIGNvcHkgYWxsIGJsb2NrcyAqLwogICAgICB9CiAgICB9IC8qIGNvcHkgZGF0YSBzdHJlYW0gYnkgc3RyZWFtICovCiAgfQoKIGVycm9yOgogIGlmIChscEJ1ZmZlciAhPSBOVUxMKQogICAgR2xvYmFsRnJlZVB0cihscEJ1ZmZlcik7CiAgaWYgKHBmaWxlICE9IE5VTEwpIHsKICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICAgIGlmIChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwpCglBVklTdHJlYW1SZWxlYXNlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0pOwogICAgICBpZiAocEluU3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwpCglBVklTdHJlYW1SZWxlYXNlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CiAgICB9CgogICAgQVZJRmlsZVJlbGVhc2UocGZpbGUpOwogIH0KCiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQ3JlYXRlRWRpdGFibGVTdHJlYW0JKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBDcmVhdGVFZGl0YWJsZVN0cmVhbShQQVZJU1RSRUFNICpwcEVkaXRhYmxlLCBQQVZJU1RSRUFNIHBTb3VyY2UpCnsKICBJQVZJRWRpdFN0cmVhbSAqcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQJICBocjsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBwRWRpdGFibGUsIHBTb3VyY2UpOwoKICBpZiAocHBFZGl0YWJsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwRWRpdGFibGUgPSBOVUxMOwoKICBpZiAocFNvdXJjZSAhPSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JQVZJRWRpdFN0cmVhbSwKCQkJCSAgIChMUFZPSUQqKSZwRWRpdCk7CiAgICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ2xvbmUocEVkaXQsIHBwRWRpdGFibGUpOwogICAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKCiAgICAgIHJldHVybiBocjsKICAgIH0KICB9CgogIC8qIG5lZWQgb3duIGltcGxlbWVudGF0aW9uIG9mIElBVklFZGl0U3RyZWFtICovCiAgcEVkaXQgPSBBVklGSUxFX0NyZWF0ZUVkaXRTdHJlYW0ocFNvdXJjZSk7CiAgaWYgKHBFZGl0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaHIgPSBJQVZJRWRpdFN0cmVhbV9RdWVyeUludGVyZmFjZShwRWRpdCwgJklJRF9JQVZJU3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopcHBFZGl0YWJsZSk7CiAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ2xvbmUJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbUNsb25lKFBBVklTVFJFQU0gcFN0cmVhbSwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBwU3RyZWFtLCBwcFJlc3VsdCk7CgogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcFJlc3VsdCA9IE5VTEw7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9DbG9uZShwRWRpdCwgcHBSZXN1bHQpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ29weQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtQ29weShQQVZJU1RSRUFNIHBTdHJlYW0sIExPTkcgKnBsU3RhcnQsCgkJCSAgICAgIExPTkcgKnBsTGVuZ3RoLCBQQVZJU1RSRUFNICpwcFJlc3VsdCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsIHBTdHJlYW0sIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgcHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcFJlc3VsdCA9IE5VTEw7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KHBFZGl0LCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ3V0CQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1DdXQoUEFWSVNUUkVBTSBwU3RyZWFtLCBMT05HICpwbFN0YXJ0LAoJCQkgICAgIExPTkcgKnBsTGVuZ3RoLCBQQVZJU1RSRUFNICpwcFJlc3VsdCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsIHBTdHJlYW0sIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCAhPSBOVUxMKQogICAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTdHJlYW0sICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX0N1dChwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVBhc3RlCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1QYXN0ZShQQVZJU1RSRUFNIHBEZXN0LCBMT05HICpwbFN0YXJ0LCBMT05HICpwbExlbmd0aCwKCQkJICAgICAgIFBBVklTVFJFQU0gcFNvdXJjZSwgTE9ORyBsU3RhcnQsIExPTkcgbEVuZCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcCwlbGQsJWxkKVxuIiwgcERlc3QsIHBsU3RhcnQsIHBsTGVuZ3RoLAoJcFNvdXJjZSwgbFN0YXJ0LCBsRW5kKTsKCiAgaWYgKHBEZXN0ID09IE5VTEwgfHwgcFNvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8IGxTdGFydCA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocERlc3QsICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX1Bhc3RlKHBFZGl0LCBwbFN0YXJ0LCBwbExlbmd0aCwgcFNvdXJjZSwgbFN0YXJ0LCBsRW5kKTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldEluZm9BCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldEluZm9BKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPQSBhc2ksCgkJCQkgIExPTkcgc2l6ZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweSgmYXNpdywgYXNpLCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgYXNpLT5zek5hbWUsIC0xLAoJCSAgICAgIGFzaXcuc3pOYW1lLCBzaXplb2YoYXNpdy5zek5hbWUpKTsKCiAgcmV0dXJuIEVkaXRTdHJlYW1TZXRJbmZvVyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtU2V0SW5mb1cJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtU2V0SW5mb1coUEFWSVNUUkVBTSBwc3RyZWFtLCBMUEFWSVNUUkVBTUlORk9XIGFzaSwKCQkJCSAgTE9ORyBzaXplKQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9TZXRJbmZvKHBFZGl0LCBhc2ksIHNpemUpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtU2V0TmFtZUEJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtU2V0TmFtZUEoUEFWSVNUUkVBTSBwc3RyZWFtLCBMUENTVFIgc3pOYW1lKQp7CiAgQVZJU1RSRUFNSU5GT0EgYXNpYTsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgcHN0cmVhbSwgZGVidWdzdHJfYShzek5hbWUpKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzek5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyZXMgPSBBVklTdHJlYW1JbmZvQShwc3RyZWFtLCAmYXNpYSwgc2l6ZW9mKGFzaWEpKTsKICBpZiAoRkFJTEVEKGhyZXMpKQogICAgcmV0dXJuIGhyZXM7CgogIG1lbXNldChhc2lhLnN6TmFtZSwgMCwgc2l6ZW9mKGFzaWEuc3pOYW1lKSk7CiAgbHN0cmNweW5BKGFzaWEuc3pOYW1lLCBzek5hbWUsIHNpemVvZihhc2lhLnN6TmFtZSkvc2l6ZW9mKGFzaWEuc3pOYW1lWzBdKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb0EocHN0cmVhbSwgJmFzaWEsIHNpemVvZihhc2lhKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldE5hbWVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldE5hbWVXKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBDV1NUUiBzek5hbWUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIEhSRVNVTFQgICAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXAsJXMpXG4iLCBwc3RyZWFtLCBkZWJ1Z3N0cl93KHN6TmFtZSkpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHN6TmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHJlcyA9IElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKICBpZiAoRkFJTEVEKGhyZXMpKQogICAgcmV0dXJuIGhyZXM7CgogIG1lbXNldChhc2l3LnN6TmFtZSwgMCwgc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CiAgbHN0cmNweW5XKGFzaXcuc3pOYW1lLCBzek5hbWUsIHNpemVvZihhc2l3LnN6TmFtZSkvc2l6ZW9mKGFzaXcuc3pOYW1lWzBdKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb1cocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQ2xlYXJDbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklDbGVhckNsaXBib2FyZCh2b2lkKQp7CiAgVFJBQ0UoIigpXG4iKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogT2xlU2V0Q2xpcGJvYXJkKE5VTEwpOyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUdldEZyb21DbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklHZXRGcm9tQ2xpcGJvYXJkKFBBVklGSUxFICpwcGZpbGUpCnsKICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIsIHBwZmlsZSk7CgogICpwcGZpbGUgPSBOVUxMOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVB1dEZpbGVPbkNsaXBib2FyZAkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVB1dEZpbGVPbkNsaXBib2FyZChQQVZJRklMRSBwZmlsZSkKewogIEZJWE1FKCIoJXApLCBzdHViIVxuIiwgcGZpbGUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9Cg==