LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5kb3dzeC5oIgoKI2luY2x1ZGUgIm9sZTIuaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInZmdy5oIgojaW5jbHVkZSAibXNhY20uaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBmb3IgQVZJQnVpbGRGaWx0ZXJXIC0tIHVzZXMgZml4ZWQgc2l6ZSB0YWJsZQogKi8KI2RlZmluZSBNQVhfRklMVEVSUyAzMCAvKiAzMCA9PiA3a0IgKi8KCnR5cGVkZWYgc3RydWN0IF9BVklGaWx0ZXIgewogIFdDSEFSIHN6Q2xzaWRbNDBdOwogIFdDSEFSIHN6RXh0ZW5zaW9uc1tNQVhfRklMVEVSUyAqIDddOwp9IEFWSUZpbHRlcjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBmb3IgQVZJU2F2ZU9wdGlvbnMKICovCnN0YXRpYyBzdHJ1Y3QgewogIFVJTlQgICAgICAgICAgICAgICAgICB1RmxhZ3M7CiAgSU5UICAgICAgICAgICAgICAgICAgIG5TdHJlYW1zOwogIFBBVklTVFJFQU0gICAgICAgICAgICpwcGF2aXM7CiAgTFBBVklDT01QUkVTU09QVElPTlMgKnBwT3B0aW9uczsKICBJTlQgICAgICAgICAgICAgICAgICAgbkN1cnJlbnQ7Cn0gU2F2ZU9wdHM7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogY29waWVkIGZyb20gZGxscy9vbGUzMi9jb21wb2JqLmMKICovCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKExQQ1NUUiBpZHN0ciwgTFBDTFNJRCBpZCkKewogIEJZVEUgY29uc3QgKnM7CiAgQllURSAqcDsKICBJTlQgICBpOwogIEJZVEUgdGFibGVbMjU2XTsKCiAgaWYgKCFpZHN0cikgewogICAgbWVtc2V0KGlkLCAwLCBzaXplb2YoQ0xTSUQpKTsKICAgIHJldHVybiBTX09LOwogIH0KCiAgLyogdmFsaWRhdGUgdGhlIENMU0lEIHN0cmluZyAqLwogIGlmIChsc3RybGVuQShpZHN0cikgIT0gMzgpCiAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgcyA9IChCWVRFIGNvbnN0KilpZHN0cjsKICBpZiAoKHNbMF0hPSd7JykgfHwgKHNbOV0hPSctJykgfHwgKHNbMTRdIT0nLScpIHx8IChzWzE5XSE9Jy0nKSB8fAogICAgICAoc1syNF0hPSctJykgfHwgKHNbMzddIT0nfScpKQogICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CgogIGZvciAoaSA9IDE7IGkgPCAzNzsgaSsrKSB7CiAgICBpZiAoKGkgPT0gOSkgfHwgKGkgPT0gMTQpIHx8IChpID09IDE5KSB8fCAoaSA9PSAyNCkpCiAgICAgIGNvbnRpbnVlOwogICAgaWYgKCEoKChzW2ldID49ICcwJykgJiYgKHNbaV0gPD0gJzknKSkgIHx8CiAgICAgICAgKChzW2ldID49ICdhJykgJiYgKHNbaV0gPD0gJ2YnKSkgIHx8CiAgICAgICAgKChzW2ldID49ICdBJykgJiYgKHNbaV0gPD0gJ0YnKSkpCiAgICAgICApCiAgICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwogIH0KCiAgVFJBQ0UoIiVzIC0+ICVwXG4iLCBzLCBpZCk7CgogIC8qIHF1aWNrIGxvb2t1cCB0YWJsZSAqLwogIG1lbXNldCh0YWJsZSwgMCwgMjU2KTsKCiAgZm9yIChpID0gMDsgaSA8IDEwOyBpKyspCiAgICB0YWJsZVsnMCcgKyBpXSA9IGk7CgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgIHRhYmxlWydBJyArIGldID0gaSsxMDsKICAgIHRhYmxlWydhJyArIGldID0gaSsxMDsKICB9CgogIC8qIGluIGZvcm0ge1hYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWH0gKi8KICBwID0gKEJZVEUgKikgaWQ7CgogIHMrKzsJLyogc2tpcCBsZWFkaW5nIGJyYWNlICAqLwogIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgIHBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSA0OwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICBwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDI7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CiAgICAqcCsrID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CgogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgQk9PTCBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oTFBDV1NUUiBzekZpbGUsIExQQ0xTSUQgbHBjbHNpZCkKewogIENIQVIgICBzelJlZ0tleVsyNV07CiAgQ0hBUiAgIHN6VmFsdWVbMTAwXTsKICBMUFdTVFIgc3pFeHQgPSBzdHJyY2hyVyhzekZpbGUsICcuJyk7CiAgTE9ORyAgIGxlbiA9IHNpemVvZihzelZhbHVlKSAvIHNpemVvZihzelZhbHVlWzBdKTsKCiAgaWYgKHN6RXh0ID09IE5VTEwpCiAgICByZXR1cm4gRkFMU0U7CgogIHN6RXh0Kys7CgogIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXEV4dGVuc2lvbnNcXCUuM2xzIiwgc3pFeHQpOwogIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZsZW4pICE9IEVSUk9SX1NVQ0NFU1MpCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgbHBjbHNpZCkgPT0gU19PSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluaXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluaXQJCShBVklGSUxFLjEwMCkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVJbml0KHZvaWQpIHsKICBPbGVJbml0aWFsaXplKE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFeGl0CQkoQVZJRklMRS4xMDEpCiAqLwp2b2lkIFdJTkFQSSBBVklGaWxlRXhpdCh2b2lkKSB7CiAgLyogbmVlZCB0byBmcmVlIG9sZTMyLmRsbCBpZiB3ZSBhcmUgdGhlIGxhc3QgZXhpdCBjYWxsICovCiAgLyogT2xlVW5pdGlhbGl6ZSgpICovCiAgRklYTUUoIigpOiBzdHViIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZU9wZW4JCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZU9wZW5BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVPcGVuCQkoQVZJRklMRS4xMDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlbkEoUEFWSUZJTEUgKnBwZmlsZSwgTFBDU1RSIHN6RmlsZSwgVUlOVCB1TW9kZSwKCQkJICAgIExQQ0xTSUQgbHBIYW5kbGVyKQp7CiAgTFBXU1RSICB3c3pGaWxlID0gTlVMTDsKICBIUkVTVUxUIGhyOwogIGludCAgICAgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4WCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfYShzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBjb252ZXJ0IEFTQ0lJIHN0cmluZyB0byBVbmljb2RlIGFuZCBjYWxsIHVuaWNvZGUgZnVuY3Rpb24gKi8KICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgTlVMTCwgMCk7CiAgaWYgKGxlbiA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgd3N6RmlsZSA9IChMUFdTVFIpTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4pOwoKICBociA9IEFWSUZpbGVPcGVuVyhwcGZpbGUsIHdzekZpbGUsIHVNb2RlLCBscEhhbmRsZXIpOwoKICBMb2NhbEZyZWUoKEhMT0NBTCl3c3pGaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlblcoUEFWSUZJTEUgKnBwZmlsZSwgTFBDV1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIElQZXJzaXN0RmlsZSAqcHBlcnNpc3QgPSBOVUxMOwogIENMU0lEICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXMsMHglWCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfdyhzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciB0aGVuIHRyeSBndWVzc2luZyBpdCBieSBleHRlbnNpb24gKi8KICBpZiAobHBIYW5kbGVyID09IE5VTEwpIHsKICAgIGlmICghIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihzekZpbGUsICZjbHNpZEhhbmRsZXIpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZQogICAgbWVtY3B5KCZjbHNpZEhhbmRsZXIsIGxwSGFuZGxlciwgc2l6ZW9mKGNsc2lkSGFuZGxlcikpOwoKICAvKiBjcmVhdGUgaW5zdGFuY2Ugb2YgaGFuZGxlciAqLwogIGhyID0gQ29DcmVhdGVJbnN0YW5jZSgmY2xzaWRIYW5kbGVyLCBOVUxMLCBDTFNDVFhfSU5QUk9DLCAmSUlEX0lBVklGaWxlLCAoTFBWT0lEKilwcGZpbGUpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgLyogYXNrIGZvciBJUGVyc2lzdEZpbGUgaW50ZXJmYWNlIGZvciBsb2FkaW5nL2NyZWF0aW5nIHRoZSBmaWxlICovCiAgaHIgPSBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgqcHBmaWxlLCAmSUlEX0lQZXJzaXN0RmlsZSwgKExQVk9JRCopJnBwZXJzaXN0KTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwcGVyc2lzdCA9PSBOVUxMKSB7CiAgICBJQVZJRmlsZV9SZWxlYXNlKCpwcGZpbGUpOwogICAgKnBwZmlsZSA9IE5VTEw7CiAgICByZXR1cm4gaHI7CiAgfQoKICBociA9IElQZXJzaXN0RmlsZV9Mb2FkKHBwZXJzaXN0LCBzekZpbGUsIHVNb2RlKTsKICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwcGVyc2lzdCk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklGaWxlX1JlbGVhc2UoKnBwZmlsZSk7CiAgICAqcHBmaWxlID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQWRkUmVmCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVBZGRSZWYJCShBVklGSUxFLjE0MCkKICovClVMT05HIFdJTkFQSSBBVklGaWxlQWRkUmVmKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTEUuMTQxKQogKi8KVUxPTkcgV0lOQVBJIEFWSUZpbGVSZWxlYXNlKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluZm8JCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluZm9BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbmZvCQkoQVZJRklMRS4xNDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb0EoUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9BIGFmaSwgTE9ORyBzaXplKQp7CiAgQVZJRklMRUlORk9XIGFmaXc7CiAgSFJFU1VMVCAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaSwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKEFWSUZJTEVJTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJRmlsZV9JbmZvKHBmaWxlLCAmYWZpdywgc2l6ZW9mKGFmaXcpKTsKCiAgbWVtY3B5KGFmaSwgJmFmaXcsIHNpemVvZigqYWZpKSAtIHNpemVvZihhZmktPnN6RmlsZVR5cGUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYWZpdy5zekZpbGVUeXBlLCAtMSwgYWZpLT5zekZpbGVUeXBlLAoJCSAgICAgIHNpemVvZihhZmktPnN6RmlsZVR5cGUpLCBOVUxMLCBOVUxMKTsKICBhZmktPnN6RmlsZVR5cGVbc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb1coUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9XIGFmaXcsIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaXcsIHNpemUpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfSW5mbyhwZmlsZSwgYWZpdywgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVHZXRTdHJlYW0JKEFWSUZJTEUuMTQzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUdldFN0cmVhbShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCURXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgVFJBQ0UoIiglcCwlcCwnJTQuNHMnLCVsZClcbiIsIHBmaWxlLCBhdmlzLCAoY2hhciopJmZjY1R5cGUsIGxQYXJhbSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVDcmVhdGVTdHJlYW1BCShBVklGSUwzMi5AKQogKiAgICAgICAgICAgICAgQVZJRmlsZUNyZWF0ZVN0cmVhbQkoQVZJRklMRS4xNDQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlQ3JlYXRlU3RyZWFtQShQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqcHBhdmksCgkJCQkgICAgTFBBVklTVFJFQU1JTkZPQSBwc2kpCnsKICBBVklTVFJFQU1JTkZPVwlwc2l3OwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcGZpbGUsIHBwYXZpLCBwc2kpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICAvKiBPbmx5IHRoZSBzek5hbWUgYXQgdGhlIGVuZCBpcyBkaWZmZXJlbnQgKi8KICBtZW1jcHkoJnBzaXcsIHBzaSwgc2l6ZW9mKCpwc2kpIC0gc2l6ZW9mKHBzaS0+c3pOYW1lKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHBzaS0+c3pOYW1lLCAtMSwgcHNpdy5zek5hbWUsCgkJICAgICAgc2l6ZW9mKHBzaXcuc3pOYW1lKSAvIHNpemVvZihwc2l3LnN6TmFtZVswXSkpOwoKICByZXR1cm4gSUFWSUZpbGVfQ3JlYXRlU3RyZWFtKHBmaWxlLCBwcGF2aSwgJnBzaXcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVDcmVhdGVTdHJlYW1XCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUNyZWF0ZVN0cmVhbVcoUEFWSUZJTEUgcGZpbGUsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkgICAgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcGZpbGUsIGF2aXMsIGFzaSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9DcmVhdGVTdHJlYW0ocGZpbGUsIGF2aXMsIGFzaSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVdyaXRlRGF0YQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVXcml0ZURhdGEJKEFWSUZJTEUuMTQ2KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZVdyaXRlRGF0YShQQVZJRklMRSBwZmlsZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlbGQpXG4iLCBwZmlsZSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX1dyaXRlRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVJlYWREYXRhCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVSZWFkRGF0YQkJKEFWSUZJTEUuMTQ3KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZVJlYWREYXRhKFBBVklGSUxFIHBmaWxlLERXT1JEIGZjYyxMUFZPSUQgbHAsTFBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJXApXG4iLCBwZmlsZSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX1JlYWREYXRhKHBmaWxlLCBmY2MsIGxwLCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlRW5kUmVjb3JkCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUVuZFJlY29yZAkoQVZJRklMRS4xNDgpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlRW5kUmVjb3JkKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0VuZFJlY29yZChwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQWRkUmVmCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUFkZFJlZgkJKEFWSUZJTEUuMTYwKQogKi8KVUxPTkcgV0lOQVBJIEFWSVN0cmVhbUFkZFJlZihQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSVN0cmVhbV9BZGRSZWYocHN0cmVhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVsZWFzZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlbGVhc2UJKEFWSUZJTEUuMTYxKQogKi8KVUxPTkcgV0lOQVBJIEFWSVN0cmVhbVJlbGVhc2UoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklTdHJlYW1fUmVsZWFzZShwc3RyZWFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1DcmVhdGUJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtQ3JlYXRlCQkoQVZJRklMRS4xMDQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1DcmVhdGUoUEFWSVNUUkVBTSAqcHBhdmksIExPTkcgbFBhcmFtMSwgTE9ORyBsUGFyYW0yLAoJCQkgICAgICAgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgsJXMpXG4iLCBwcGF2aSwgbFBhcmFtMSwgbFBhcmFtMiwKCWRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CiAgaWYgKHBjbHNpZEhhbmRsZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIGhyID0gQ29DcmVhdGVJbnN0YW5jZShwY2xzaWRIYW5kbGVyLCBOVUxMLCBDTFNDVFhfSU5QUk9DLCAmSUlEX0lBVklTdHJlYW0sIChMUFZPSUQqKXBwYXZpKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJU3RyZWFtX0NyZWF0ZSgqcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIpOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoKnBwYXZpKTsKICAgICpwcGF2aSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtSW5mbwkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1JbmZvQQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1JbmZvCQkoQVZJRklMRS4xNjIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIEhSRVNVTFQJIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CgogIG1lbWNweShhc2ksICZhc2l3LCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYXNpdy5zek5hbWUsIC0xLCBhc2ktPnN6TmFtZSwKCQkgICAgICBzaXplb2YoYXNpLT5zek5hbWUpLCBOVUxMLCBOVUxMKTsKICBhc2ktPnN6TmFtZVtzaXplb2YoYXNpLT5zek5hbWUpIC0gMV0gPSAwOwoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT1cgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCBhc2ksIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1GaW5kU2FtcGxlCShBVklGSUxFLjE2MykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUZpbmRTYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywgRFdPUkQgZmxhZ3MpCnsKICBUUkFDRSgiKCVwLCVsZCwweCVsWClcbiIsIHBzdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKHBzdHJlYW0sIHBvcywgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWFkRm9ybWF0CShBVklGSUxFLjE2NCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWRGb3JtYXQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywKCQkJCSAgIExQVk9JRCBmb3JtYXQsIExQTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZEZvcm1hdChwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2V0Rm9ybWF0CShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtU2V0Rm9ybWF0CShBVklGSUxFLjE2OSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVNldEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWQJCShBVklGSUxFLjE2NykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgTFBWT0lEIGJ1ZmZlciwgTE9ORyBidWZmZXJzaXplLAoJCQkgICAgIExQTE9ORyBieXRlc3JlYWQsIExQTE9ORyBzYW1wbGVzcmVhZCkKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUxFLjE2OCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVdyaXRlKFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBzdGFydCwgTE9ORyBzYW1wbGVzLAoJCQkgICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkgICAgICBMUExPTkcgc2FtcHdyaXR0ZW4sIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JWxYLCVwLCVwKVxuIiwgcHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZShwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkRGF0YQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWREYXRhCShBVklGSUxFLjE2NSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWREYXRhKFBBVklTVFJFQU0gcHN0cmVhbSwgRFdPUkQgZmNjLCBMUFZPSUQgbHAsCgkJCQkgTFBMT05HIGxwcmVhZCkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlcClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRGF0YShwc3RyZWFtLCBmY2MsIGxwLCBscHJlYWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVdyaXRlRGF0YQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVdyaXRlRGF0YQkoQVZJRklMRS4xNjYpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1Xcml0ZURhdGEoUEFWSVNUUkVBTSBwc3RyZWFtLCBEV09SRCBmY2MsIExQVk9JRCBscCwKCQkJCSAgTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVsZClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKHBzdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMRS4xMTIpCiAqLwpQR0VURlJBTUUgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lT3BlbihQQVZJU1RSRUFNIHBzdHJlYW0sCgkJCQkgICAgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlXYW50ZWQpCnsKICBQR0VURlJBTUUgcGcgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcHN0cmVhbSwgbHBiaVdhbnRlZCk7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lHZXRGcmFtZSwgKExQVk9JRCopJnBnKSkgfHwKICAgICAgcGcgPT0gTlVMTCkgewogICAgcGcgPSBBVklGSUxFX0NyZWF0ZUdldEZyYW1lKHBzdHJlYW0pOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogIH0KCiAgaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KHBnLCBscGJpV2FudGVkLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkgewogICAgSUdldEZyYW1lX1JlbGVhc2UocGcpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcGc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZQkoQVZJRklMRS4xMTApCiAqLwpMUFZPSUQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lKFBHRVRGUkFNRSBwZywgTE9ORyBwb3MpCnsKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBnLCBwb3MpOwoKICBpZiAocGcgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICByZXR1cm4gSUdldEZyYW1lX0dldEZyYW1lKHBnLCBwb3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZUNsb3NlCShBVklGSUxFLjExMSkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lQ2xvc2UoUEdFVEZSQU1FIHBnKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBnKTsKCiAgaWYgKHBnICE9IE5VTEwpCiAgICByZXR1cm4gSUdldEZyYW1lX1JlbGVhc2UocGcpOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSU1ha2VDb21wcmVzc2VkU3RyZWFtCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0oUEFWSVNUUkVBTSAqcHBzQ29tcHJlc3NlZCwKCQkJCSAgICAgICBQQVZJU1RSRUFNIHBzU291cmNlLAoJCQkJICAgICAgIExQQVZJQ09NUFJFU1NPUFRJT05TIGFjbywKCQkJCSAgICAgICBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIENIQVIgICAgICAgICAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgICAgICAgICBzelZhbHVlWzEwMF07CiAgQ0xTSUQgICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgIGhyOwogIExPTkcgICAgICAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSk7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXMpXG4iLCBwcHNDb21wcmVzc2VkLCBwc1NvdXJjZSwgYWNvLAoJZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcHNDb21wcmVzc2VkID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChwc1NvdXJjZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogICpwcHNDb21wcmVzc2VkID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciBnaXZlbiBnZXQgZGVmYXVsdCBvbmVzIGJhc2VkIG9uIHN0cmVhbXR5cGUgKi8KICBpZiAocGNsc2lkSGFuZGxlciA9PSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1fSW5mbyhwc1NvdXJjZSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIHdzcHJpbnRmQShzelJlZ0tleSwgIkFWSUZpbGVcXENvbXByZXNzb3JzXFwlNC40cyIsIChjaGFyKikmYXNpdy5mY2NUeXBlKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlQShIS0VZX0NMQVNTRVNfUk9PVCwgc3pSZWdLZXksIHN6VmFsdWUsICZzaXplKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogICAgaWYgKEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKHN6VmFsdWUsICZjbHNpZEhhbmRsZXIpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfSBlbHNlCiAgICBtZW1jcHkoJmNsc2lkSGFuZGxlciwgcGNsc2lkSGFuZGxlciwgc2l6ZW9mKGNsc2lkSGFuZGxlcikpOwoKICBociA9IENvQ3JlYXRlSW5zdGFuY2UoJmNsc2lkSGFuZGxlciwgTlVMTCwgQ0xTQ1RYX0lOUFJPQywgJklJRF9JQVZJU3RyZWFtLCAoTFBWT0lEKilwcHNDb21wcmVzc2VkKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBzQ29tcHJlc3NlZCA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcHNDb21wcmVzc2VkLCAoTFBBUkFNKXBzU291cmNlLCAoTFBBUkFNKWFjbyk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBzQ29tcHJlc3NlZCk7CiAgICAqcHBzQ29tcHJlc3NlZCA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJTWFrZUZpbGVGcm9tU3RyZWFtcwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSU1ha2VGaWxlRnJvbVN0cmVhbXMoUEFWSUZJTEUgKnBwZmlsZSwgaW50IG5TdHJlYW1zLAoJCQkJICAgICAgUEFWSVNUUkVBTSAqcHBTdHJlYW1zKQp7CiAgVFJBQ0UoIiglcCwlZCwlcClcbiIsIHBwZmlsZSwgblN0cmVhbXMsIHBwU3RyZWFtcyk7CgogIGlmIChuU3RyZWFtcyA8IDAgfHwgcHBmaWxlID09IE5VTEwgfHwgcHBTdHJlYW1zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBmaWxlID0gQVZJRklMRV9DcmVhdGVBVklUZW1wRmlsZShuU3RyZWFtcywgcHBTdHJlYW1zKTsKICBpZiAoKnBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlQQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZSAgIChBVklGSUxFLjEwMykKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbU9wZW5Gcm9tRmlsZUEoUEFWSVNUUkVBTSAqcHBhdmksIExQQ1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfYShzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5BKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVXCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlVyhQQVZJU1RSRUFNICpwcGF2aSwgTFBDV1NUUiBzekZpbGUsCgkJCQkgICAgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSwKCQkJCSAgICAgIFVJTlQgbW9kZSwgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgUEFWSUZJTEUgcGZpbGUgPSBOVUxMOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVzLCclNC40cycsJWxkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfdyhzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1CZWdpblN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUJlZ2luU3RyZWFtaW5nKFBBVklTVFJFQU0gcGF2aSwgTE9ORyBsU3RhcnQsIExPTkcgbEVuZCwgTE9ORyBsUmF0ZSkKewogIElBVklTdHJlYW1pbmcqIHBzdHJlYW0gPSBOVUxMOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlbGQpXG4iLCBwYXZpLCBsU3RhcnQsIGxFbmQsIGxSYXRlKTsKCiAgaWYgKHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocGF2aSwgJklJRF9JQVZJU3RyZWFtaW5nLCAoTFBWT0lEKikmcHN0cmVhbSk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcHN0cmVhbSAhPSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1pbmdfQmVnaW4ocHN0cmVhbSwgbFN0YXJ0LCBsRW5kLCBsUmF0ZSk7CiAgICBJQVZJU3RyZWFtaW5nX1JlbGVhc2UocHN0cmVhbSk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUVuZFN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUVuZFN0cmVhbWluZyhQQVZJU1RSRUFNIHBhdmkpCnsKICBJQVZJU3RyZWFtaW5nKiBwc3RyZWFtID0gTlVMTDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwKVxuIiwgcGF2aSk7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwYXZpLCAmSUlEX0lBVklTdHJlYW1pbmcsIChMUFZPSUQqKSZwc3RyZWFtKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwc3RyZWFtICE9IE5VTEwpIHsKICAgIElBVklTdHJlYW1pbmdfRW5kKHBzdHJlYW0pOwogICAgSUFWSVN0cmVhbWluZ19SZWxlYXNlKHBzdHJlYW0pOwogIH0KCiByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVN0YXJ0CQkoQVZJRklMRS4xMzApCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TdGFydChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3U3RhcnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMRS4xMzEpCiAqCQlBVklTdHJlYW1MZW5ndGgJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtTGVuZ3RoKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGFzaXcuZHdMZW5ndGg7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2FtcGxlVG9UaW1lCShBVklGSUxFLjEzMykKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVNhbXBsZVRvVGltZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFNhbXBsZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgTE9ORyB0aW1lOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBzdHJlYW0sIGxTYW1wbGUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdSYXRlID09IDApCiAgICByZXR1cm4gLTE7CgogIC8qIGxpbWl0IHRvIHN0cmVhbSBib3VuZHMgKi8KICBpZiAobFNhbXBsZSA8IGFzaXcuZHdTdGFydCkKICAgIGxTYW1wbGUgPSBhc2l3LmR3U3RhcnQ7CiAgaWYgKGxTYW1wbGUgPiBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoKQogICAgbFNhbXBsZSA9IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGg7CgogIGlmIChhc2l3LmR3UmF0ZSAvIGFzaXcuZHdTY2FsZSA8IDEwMDApCiAgICB0aW1lID0gKExPTkcpKCgoZmxvYXQpbFNhbXBsZSAqIGFzaXcuZHdTY2FsZSAqIDEwMDApIC8gYXNpdy5kd1JhdGUpOwogIGVsc2UKICAgIHRpbWUgPSAoTE9ORykoKChmbG9hdClsU2FtcGxlICogYXNpdy5kd1NjYWxlICogMTAwMCArIChhc2l3LmR3UmF0ZSAtIDEpKSAvIGFzaXcuZHdSYXRlKTsKCiAgVFJBQ0UoIiAtPiAlbGRcbiIsdGltZSk7CiAgcmV0dXJuIHRpbWU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtVGltZVRvU2FtcGxlCShBVklGSUxFLjEzMikKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVRpbWVUb1NhbXBsZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFRpbWUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIFVMT05HIHNhbXBsZTsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBwc3RyZWFtLCBsVGltZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwgfHwgbFRpbWUgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdTY2FsZSA9PSAwKQogICAgcmV0dXJuIC0xOwoKICBpZiAoYXNpdy5kd1JhdGUgLyBhc2l3LmR3U2NhbGUgPCAxMDAwKQogICAgc2FtcGxlID0gKExPTkcpKCgoKGZsb2F0KWFzaXcuZHdSYXRlICogbFRpbWUpIC8gKGFzaXcuZHdTY2FsZSAqIDEwMDApKSk7CiAgZWxzZQogICAgc2FtcGxlID0gKExPTkcpKCgoZmxvYXQpYXNpdy5kd1JhdGUgKiBsVGltZSArIChhc2l3LmR3U2NhbGUgKiAxMDAwIC0gMSkpIC8gKGFzaXcuZHdTY2FsZSAqIDEwMDApKTsKCiAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kcyAqLwogIGlmIChzYW1wbGUgPCBhc2l3LmR3U3RhcnQpCiAgICBzYW1wbGUgPSBhc2l3LmR3U3RhcnQ7CiAgaWYgKHNhbXBsZSA+IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGgpCiAgICBzYW1wbGUgPSBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoOwoKICBUUkFDRSgiIC0+ICVsZFxuIiwgc2FtcGxlKTsKICByZXR1cm4gc2FtcGxlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUJ1aWxkRmlsdGVyCQkoQVZJRklMMzIuQCkKICoJCUFWSUJ1aWxkRmlsdGVyQQkJKEFWSUZJTDMyLkApCiAqCQlBVklCdWlsZEZpbHRlcgkJKEFWSUZJTEUuMTIzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQnVpbGRGaWx0ZXJBKExQU1RSIHN6RmlsdGVyLCBMT05HIGNiRmlsdGVyLCBCT09MIGZTYXZpbmcpCnsKICBMUFdTVFIgIHdzekZpbHRlcjsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlZClcbiIsIHN6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKGNiRmlsdGVyIDwgMikKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgc3pGaWx0ZXJbMF0gPSAwOwogIHN6RmlsdGVyWzFdID0gMDsKCiAgd3N6RmlsdGVyID0gKExQV1NUUilHbG9iYWxBbGxvY1B0cihHSE5ELCBjYkZpbHRlciAqIHNpemVvZihXQ0hBUikpOwogIGlmICh3c3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IEFWSUJ1aWxkRmlsdGVyVyh3c3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHdzekZpbHRlciwgY2JGaWx0ZXIsCgkJCXN6RmlsdGVyLCBjYkZpbHRlciwgTlVMTCwgTlVMTCk7CiAgfQoKICBHbG9iYWxGcmVlUHRyKHdzekZpbHRlcik7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklCdWlsZEZpbHRlclcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQnVpbGRGaWx0ZXJXKExQV1NUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xzaWRbXSA9IHsnQycsJ0wnLCdTJywnSScsJ0QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekV4dGVuc2lvbkZtdFtdID0geyc7JywnKicsJy4nLCclJywncycsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QVZJRmlsZUV4dGVuc2lvbnNbXSA9CiAgICB7J0EnLCdWJywnSScsJ0YnLCdpJywnbCcsJ2UnLCdcXCcsJ0UnLCd4JywndCcsJ2UnLCduJywncycsJ2knLCdvJywnbicsJ3MnLDB9OwoKICBBVklGaWx0ZXIgKmxwOwogIFdDSEFSICAgICAgc3pBbGxGaWxlc1s0MF07CiAgV0NIQVIgICAgICBzekZpbGVFeHRbMTBdOwogIFdDSEFSICAgICAgc3pWYWx1ZVsxMjhdOwogIEhLRVkgICAgICAgaEtleTsKICBEV09SRCAgICAgIG4sIGk7CiAgTE9ORyAgICAgICBzaXplOwogIERXT1JEICAgICAgY291bnQgPSAwOwoKICBUUkFDRSgiKCVwLCVsZCwlZClcbiIsIHN6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKGNiRmlsdGVyIDwgMikKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbHAgPSAoQVZJRmlsdGVyKilHbG9iYWxBbGxvY1B0cihHSE5ELCBNQVhfRklMVEVSUyAqIHNpemVvZihBVklGaWx0ZXIpKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKgogICAqIDEuIGl0ZXJhdGUgb3ZlciBIS0VZX0NMQVNTRVNfUk9PVFxcQVZJRmlsZVxcRXh0ZW5zaW9ucyBhbmQgY29sbGVjdAogICAqICAgIGV4dGVuc2lvbnMgYW5kIENMU0lEJ3MKICAgKiAyLiBpdGVyYXRlIG92ZXIgY29sbGVjdGVkIENMU0lEJ3MgYW5kIGNvcHkgaXRzIGRlc2NyaXB0aW9uIGFuZCBpdHMKICAgKiAgICBleHRlbnNpb25zIHRvIHN6RmlsdGVyIGlmIGl0IGZpdHMKICAgKgogICAqIEZpcnN0IGZpbHRlciBpcyBuYW1lZCAiQWxsIG11bHRpbWVkaWEgZmlsZXMiIGFuZCBpdHMgZmlsdGVyIGlzIGEKICAgKiBjb2xsZWN0aW9uIG9mIGFsbCBwb3NzaWJsZSBleHRlbnNpb25zIGV4Y2VwdCAiKi4qIi4KICAgKi8KICBpZiAoUmVnT3BlbktleVcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6QVZJRmlsZUV4dGVuc2lvbnMsICZoS2V5KSAhPSBTX09LKSB7CiAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7UmVnRW51bUtleVcoaEtleSwgbiwgc3pGaWxlRXh0LCBzaXplb2Yoc3pGaWxlRXh0KSkgPT0gU19PSztuKyspIHsKICAgIC8qIGdldCBDTFNJRCB0byBleHRlbnNpb24gKi8KICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKHN6VmFsdWVbMF0pOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIHN6RmlsZUV4dCwgc3pWYWx1ZSwgJnNpemUpICE9IFNfT0spCiAgICAgIGJyZWFrOwoKICAgIC8qIHNlYXJjaCBpZiB0aGUgQ0xTSUQgaXMgYWxyZWFkeSBrbm93biAqLwogICAgZm9yIChpID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7CiAgICAgIGlmIChsc3RyY21wVyhscFtpXS5zekNsc2lkLCBzelZhbHVlKSA9PSAwKQoJYnJlYWs7IC8qIGEgbmV3IG9uZSAqLwogICAgfQoKICAgIGlmIChjb3VudCAtIGkgPT0gLTFVKSB7CiAgICAgIC8qIGl0J3MgYSBuZXcgQ0xTSUQgKi8KCiAgICAgIC8qIEZJWE1FOiBIb3cgZG8gd2UgZ2V0IGluZm8ncyBhYm91dCByZWFkL3dyaXRlIGNhcGFiaWxpdGllcz8gKi8KCiAgICAgIGlmIChjb3VudCA+PSBNQVhfRklMVEVSUykgewoJLyogdHJ5IHRvIGluZm9ybSB1c2VyIG9mIG91ciBmdWxsIGZpeGVkIHNpemUgdGFibGUgKi8KCUVSUigiOiBNb3JlIHRoYW4gJWQgZmlsdGVycyBmb3VuZCEgQWRqdXN0IE1BWF9GSUxURVJTIGluIGRsbHMvYXZpZmlsMzIvYXBpLmNcbiIsIE1BWF9GSUxURVJTKTsKCWJyZWFrOwogICAgICB9CgogICAgICBsc3RyY3B5VyhscFtpXS5zekNsc2lkLCBzelZhbHVlKTsKCiAgICAgIGNvdW50Kys7CiAgICB9CgogICAgLyogYXBwZW5kIGV4dGVuc2lvbiB0byB0aGUgZmlsdGVyICovCiAgICB3c3ByaW50Zlcoc3pWYWx1ZSwgc3pFeHRlbnNpb25GbXQsIHN6RmlsZUV4dCk7CiAgICBpZiAobHBbaV0uc3pFeHRlbnNpb25zWzBdID09IDApCiAgICAgIGxzdHJjYXRXKGxwW2ldLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSArIDEpOwogICAgZWxzZQogICAgICBsc3RyY2F0VyhscFtpXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUpOwoKICAgIC8qIGFsc28gYXBwZW5kIHRvIHRoZSAiYWxsIG11bHRpbWVkaWEiLWZpbHRlciAqLwogICAgaWYgKGxwWzBdLnN6RXh0ZW5zaW9uc1swXSA9PSAwKQogICAgICBsc3RyY2F0VyhscFswXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUgKyAxKTsKICAgIGVsc2UKICAgICAgbHN0cmNhdFcobHBbMF0uc3pFeHRlbnNpb25zLCBzelZhbHVlKTsKICB9CiAgUmVnQ2xvc2VLZXkoaEtleSk7CgogIC8qIDIuIGdldCBkZXNjcmlwdGlvbnMgZm9yIHRoZSBDTFNJRHMgYW5kIGZpbGwgb3V0IHN6RmlsdGVyICovCiAgaWYgKFJlZ09wZW5LZXlXKEhLRVlfQ0xBU1NFU19ST09ULCBzekNsc2lkLCAmaEtleSkgIT0gU19PSykgewogICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwogIH0KICBmb3IgKG4gPSAwOyBuIDw9IGNvdW50OyBuKyspIHsKICAgIC8qIGZpcnN0IHRoZSBkZXNjcmlwdGlvbiAqLwogICAgaWYgKG4gIT0gMCkgewogICAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpL3NpemVvZihzelZhbHVlWzBdKTsKICAgICAgaWYgKFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIGxwW25dLnN6Q2xzaWQsIHN6VmFsdWUsICZzaXplKSA9PSBTX09LKSB7CglzaXplID0gbHN0cmxlblcoc3pWYWx1ZSk7Cglsc3RyY3B5blcoc3pGaWx0ZXIsIHN6VmFsdWUsIGNiRmlsdGVyKTsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIHNpemUgPSBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsSURTX0FMTE1VTFRJTUVESUEsc3pGaWx0ZXIsY2JGaWx0ZXIpOwoKICAgIC8qIGNoZWNrIGZvciBlbm91Z2ggc3BhY2UgKi8KICAgIHNpemUrKzsKICAgIGlmIChjYkZpbHRlciA8IHNpemUgKyBsc3RybGVuVyhscFtuXS5zekV4dGVuc2lvbnMpICsgMikgewogICAgICBzekZpbHRlclswXSA9IDA7CiAgICAgIHN6RmlsdGVyWzFdID0gMDsKICAgICAgR2xvYmFsRnJlZVB0cihscCk7CiAgICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgfQogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CgogICAgLyogYW5kIHRoZW4gdGhlIGZpbHRlciAqLwogICAgbHN0cmNweW5XKHN6RmlsdGVyLCBscFtuXS5zekV4dGVuc2lvbnMsIGNiRmlsdGVyKTsKICAgIHNpemUgPSBsc3RybGVuVyhscFtuXS5zekV4dGVuc2lvbnMpICsgMTsKICAgIGNiRmlsdGVyIC09IHNpemU7CiAgICBzekZpbHRlciArPSBzaXplOwogIH0KCiAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgR2xvYmFsRnJlZVB0cihscCk7CgogIC8qIGFkZCAiQWxsIGZpbGVzIiAiKi4qIiBmaWx0ZXIgaWYgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQUxMRklMRVMsCgkJICAgICBzekFsbEZpbGVzLCBzaXplb2Yoc3pBbGxGaWxlcykpICsgMTsKICBpZiAoY2JGaWx0ZXIgPiBzaXplKSB7CiAgICBpbnQgaTsKCiAgICAvKiByZXBsYWNlICdAJyB3aXRoIFwwMDAgdG8gc2VwYXJhdGUgZGVzY3JpcHRpb24gb2YgZmlsdGVyICovCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZSAmJiBzekFsbEZpbGVzW2ldICE9IDA7IGkrKykgewogICAgICBpZiAoc3pBbGxGaWxlc1tpXSA9PSAnQCcpIHsKCXN6QWxsRmlsZXNbaV0gPSAwOwoJYnJlYWs7CiAgICAgIH0KICAgIH0KICAgICAgCiAgICBtZW1jcHkoc3pGaWx0ZXIsIHN6QWxsRmlsZXMsIHNpemUgKiBzaXplb2Yoc3pBbGxGaWxlc1swXSkpOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKICAgIHN6RmlsdGVyWzBdID0gMDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBzekZpbHRlclswXSA9IDA7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KfQoKc3RhdGljIEJPT0wgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoSFdORCBoV25kKQp7CiAgTFBBVklDT01QUkVTU09QVElPTlMgcE9wdGlvbnMgPSBTYXZlT3B0cy5wcE9wdGlvbnNbU2F2ZU9wdHMubkN1cnJlbnRdOwogIEFWSVNUUkVBTUlORk9XICAgICAgIHNJbmZvOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIGlmIChwT3B0aW9ucyA9PSBOVUxMIHx8IFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBzdGF0ZSFcbiIpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgICAgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpIHsKICAgIEVSUigiOiBBVklTdHJlYW1JbmZvVyBmYWlsZWQhXG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgQ09NUFZBUlMgY3Y7CiAgICBCT09MICAgICByZXQ7CgogICAgbWVtc2V0KCZjdiwgMCwgc2l6ZW9mKGN2KSk7CgogICAgaWYgKChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkgPT0gMCkgewogICAgICBtZW1zZXQocE9wdGlvbnMsIDAsIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgcE9wdGlvbnMtPmZjY1R5cGUgICAgPSBzdHJlYW10eXBlVklERU87CiAgICAgIHBPcHRpb25zLT5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgID0gKERXT1JEKUlDUVVBTElUWV9ERUZBVUxUOwogICAgfQoKICAgIGN2LmNiU2l6ZSAgICAgPSBzaXplb2YoY3YpOwogICAgY3YuZHdGbGFncyAgICA9IElDTUZfQ09NUFZBUlNfVkFMSUQ7CiAgICAvKmN2LmZjY1R5cGUgICAgPSBwT3B0aW9ucy0+ZmNjVHlwZTsgKi8KICAgIGN2LmZjY0hhbmRsZXIgPSBwT3B0aW9ucy0+ZmNjSGFuZGxlcjsKICAgIGN2LmxRICAgICAgICAgPSBwT3B0aW9ucy0+ZHdRdWFsaXR5OwogICAgY3YubHBTdGF0ZSAgICA9IHBPcHRpb25zLT5scFBhcm1zOwogICAgY3YuY2JTdGF0ZSAgICA9IHBPcHRpb25zLT5jYlBhcm1zOwogICAgaWYgKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0tFWUZSQU1FUykKICAgICAgY3YubEtleSA9IHBPcHRpb25zLT5kd0tleUZyYW1lRXZlcnk7CiAgICBlbHNlCiAgICAgIGN2LmxLZXkgPSAwOwogICAgaWYgKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0RBVEFSQVRFKQogICAgICBjdi5sRGF0YVJhdGUgPSBwT3B0aW9ucy0+ZHdCeXRlc1BlclNlY29uZCAvIDEwMjQ7IC8qIG5lZWQga0J5dGVzICovCiAgICBlbHNlCiAgICAgIGN2LmxEYXRhUmF0ZSA9IDA7CgogICAgcmV0ID0gSUNDb21wcmVzc29yQ2hvb3NlKGhXbmQsIFNhdmVPcHRzLnVGbGFncywgTlVMTCwKCQkJICAgICBTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLCAmY3YsIE5VTEwpOwoKICAgIGlmIChyZXQpIHsKICAgICAgcE9wdGlvbnMtPmZjY0hhbmRsZXIgPSBjdi5mY2NIYW5kbGVyOwogICAgICBwT3B0aW9ucy0+bHBQYXJtcyAgID0gY3YubHBTdGF0ZTsKICAgICAgcE9wdGlvbnMtPmNiUGFybXMgICA9IGN2LmNiU3RhdGU7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgPSBjdi5sUTsKICAgICAgaWYgKGN2LmxLZXkgIT0gMCkgewoJcE9wdGlvbnMtPmR3S2V5RnJhbWVFdmVyeSA9IGN2LmxLZXk7CglwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICBpZiAoY3YubERhdGFSYXRlICE9IDApIHsKCXBPcHRpb25zLT5kd0J5dGVzUGVyU2Vjb25kID0gY3YubERhdGFSYXRlICogMTAyNDsgLyogbmVlZCBieXRlcyAqLwoJcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0RBVEFSQVRFOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfREFUQVJBVEU7CiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzICB8PSBBVklDT01QUkVTU0ZfVkFMSUQ7CiAgICB9CiAgICBJQ0NvbXByZXNzb3JGcmVlKCZjdik7CgogICAgcmV0dXJuIHJldDsKICB9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICBBQ01GT1JNQVRDSE9PU0VXIGFmbXRjOwogICAgTU1SRVNVTFQgICAgICAgICByZXQ7CiAgICBMT05HICAgICAgICAgICAgIHNpemU7CgogICAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uIC0tIFdoaWNoIHZlcnNpb24gaXMgbmVlZGVkPyAqLwoKICAgIG1lbXNldCgmYWZtdGMsIDAsIHNpemVvZihhZm10YykpOwogICAgYWZtdGMuY2JTdHJ1Y3QgID0gc2l6ZW9mKGFmbXRjKTsKICAgIGFmbXRjLmZkd1N0eWxlICA9IDA7CiAgICBhZm10Yy5od25kT3duZXIgPSBoV25kOwoKICAgIGFjbU1ldHJpY3MoTlVMTCwgQUNNX01FVFJJQ19NQVhfU0laRV9GT1JNQVQsICZzaXplKTsKICAgIGlmICgocE9wdGlvbnMtPmNiRm9ybWF0ID09IDAgfHwgcE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpICYmIHNpemUgIT0gMCkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBzaXplKTsKICAgICAgcE9wdGlvbnMtPmNiRm9ybWF0ID0gc2l6ZTsKICAgIH0gZWxzZSBpZiAocE9wdGlvbnMtPmNiRm9ybWF0IDwgKERXT1JEKXNpemUpIHsKICAgICAgcE9wdGlvbnMtPmxwRm9ybWF0ID0gR2xvYmFsUmVBbGxvY1B0cihwT3B0aW9ucy0+bHBGb3JtYXQsIHNpemUsIEdNRU1fTU9WRUFCTEUpOwogICAgICBwT3B0aW9ucy0+Y2JGb3JtYXQgPSBzaXplOwogICAgfQogICAgaWYgKHBPcHRpb25zLT5scEZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gRkFMU0U7CiAgICBhZm10Yy5wd2Z4ICA9IHBPcHRpb25zLT5scEZvcm1hdDsKICAgIGFmbXRjLmNid2Z4ID0gcE9wdGlvbnMtPmNiRm9ybWF0OwoKICAgIHNpemUgPSAwOwogICAgQVZJU3RyZWFtRm9ybWF0U2l6ZShTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQlzSW5mby5kd1N0YXJ0LCAmc2l6ZSk7CiAgICBpZiAoc2l6ZSA8IChMT05HKXNpemVvZihQQ01XQVZFRk9STUFUKSkKICAgICAgc2l6ZSA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKICAgIGFmbXRjLnB3ZnhFbnVtID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgc2l6ZSk7CiAgICBpZiAoYWZtdGMucHdmeEVudW0gIT0gTlVMTCkgewogICAgICBBVklTdHJlYW1SZWFkRm9ybWF0KFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCSAgc0luZm8uZHdTdGFydCwgYWZtdGMucHdmeEVudW0sICZzaXplKTsKICAgICAgYWZtdGMuZmR3RW51bSA9IEFDTV9GT1JNQVRFTlVNRl9DT05WRVJUOwogICAgfQoKICAgIHJldCA9IGFjbUZvcm1hdENob29zZVcoJmFmbXRjKTsKICAgIGlmIChyZXQgPT0gU19PSykKICAgICAgcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX1ZBTElEOwoKICAgIGlmIChhZm10Yy5wd2Z4RW51bSAhPSBOVUxMKQogICAgICBHbG9iYWxGcmVlUHRyKGFmbXRjLnB3ZnhFbnVtKTsKCiAgICByZXR1cm4gKHJldCA9PSBTX09LID8gVFJVRSA6IEZBTFNFKTsKICB9IGVsc2UgewogICAgRVJSKCI6IHVua25vd24gc3RyZWFtdHlwZSAweCUwOGxYXG4iLCBzSW5mby5mY2NUeXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9Cn0KCnN0YXRpYyB2b2lkIEFWSVNhdmVPcHRpb25zVXBkYXRlKEhXTkQgaFduZCkKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelZpZGVvRm10W109eyclJywnbCcsJ2QnLCd4JywnJScsJ2wnLCdkJywneCcsJyUnLCdkJywwfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pBdWRpb0ZtdFtdPXsnJScsJ3MnLCcgJywnJScsJ3MnLDB9OwoKICBXQ0hBUiAgICAgICAgICBzekZvcm1hdFsxMjhdOwogIEFWSVNUUkVBTUlORk9XIHNJbmZvOwogIExQVk9JRCAgICAgICAgIGxwRm9ybWF0OwogIExPTkcgICAgICAgICAgIHNpemU7CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgU2F2ZU9wdHMubkN1cnJlbnQgPSBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsSURDX1NUUkVBTSxDQl9HRVRDVVJTRUwsMCwwKTsKICBpZiAoU2F2ZU9wdHMubkN1cnJlbnQgPCAwKQogICAgcmV0dXJuOwoKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUluZm9XKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSkpKQogICAgcmV0dXJuOwoKICBBVklTdHJlYW1Gb3JtYXRTaXplKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sc0luZm8uZHdTdGFydCwmc2l6ZSk7CiAgaWYgKHNpemUgPiAwKSB7CiAgICBzekZvcm1hdFswXSA9IDA7CgogICAgLyogcmVhZCBmb3JtYXQgdG8gYnVpbGQgZm9ybWF0IGRlc2NyaXB0aW9uIHN0cmluZyAqLwogICAgbHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBzaXplKTsKICAgIGlmIChscEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIGlmIChTVUNDRUVERUQoQVZJU3RyZWFtUmVhZEZvcm1hdChTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLHNJbmZvLmR3U3RhcnQsbHBGb3JtYXQsICZzaXplKSkpIHsKCWlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewoJICBMUEJJVE1BUElORk9IRUFERVIgbHBiaSA9IGxwRm9ybWF0OwoJICBJQ0lORk8gaWNpbmZvOwoKCSAgd3NwcmludGZXKHN6Rm9ybWF0LCBzelZpZGVvRm10LCBscGJpLT5iaVdpZHRoLAoJCSAgICBscGJpLT5iaUhlaWdodCwgbHBiaS0+YmlCaXRDb3VudCk7CgoJICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IpIHsKCSAgICBISUMgICAgaGljOwoKCSAgICBoaWMgPSBJQ0xvY2F0ZShJQ1RZUEVfVklERU8sIHNJbmZvLmZjY0hhbmRsZXIsIGxwRm9ybWF0LAoJCQkgICBOVUxMLCBJQ01PREVfREVDT01QUkVTUyk7CgkgICAgaWYgKGhpYyAhPSBOVUxMKSB7CgkgICAgICBpZiAoSUNHZXRJbmZvKGhpYywgJmljaW5mbywgc2l6ZW9mKGljaW5mbykpID09IFNfT0spCgkJbHN0cmNhdFcoc3pGb3JtYXQsIGljaW5mby5zekRlc2NyaXB0aW9uKTsKCSAgICAgIElDQ2xvc2UoaGljKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfVU5DT01QUkVTU0VELAoJCQlpY2luZm8uc3pEZXNjcmlwdGlvbiwgc2l6ZW9mKGljaW5mby5zekRlc2NyaXB0aW9uKSk7CgkgICAgbHN0cmNhdFcoc3pGb3JtYXQsIGljaW5mby5zekRlc2NyaXB0aW9uKTsKCSAgfQoJfSBlbHNlIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewoJICBBQ01GT1JNQVRUQUdERVRBSUxTVyBhZnRkOwoJICBBQ01GT1JNQVRERVRBSUxTVyAgICBhZmQ7CgoJICBtZW1zZXQoJmFmdGQsIDAsIHNpemVvZihhZnRkKSk7CgkgIG1lbXNldCgmYWZkLCAwLCBzaXplb2YoYWZkKSk7CgoJICBhZnRkLmNiU3RydWN0ICAgICA9IHNpemVvZihhZnRkKTsKCSAgYWZ0ZC5kd0Zvcm1hdFRhZyAgPSBhZmQuZHdGb3JtYXRUYWcgPQoJICAgICgoUFdBVkVGT1JNQVRFWClscEZvcm1hdCktPndGb3JtYXRUYWc7CgkgIGFmdGQuY2JGb3JtYXRTaXplID0gYWZkLmNid2Z4ID0gc2l6ZTsKCgkgIGFmZC5jYlN0cnVjdCAgICAgID0gc2l6ZW9mKGFmZCk7CgkgIGFmZC5wd2Z4ICAgICAgICAgID0gbHBGb3JtYXQ7CgoJICBpZiAoYWNtRm9ybWF0VGFnRGV0YWlsc1coTlVMTCwgJmFmdGQsCgkJCQkgICBBQ01fRk9STUFUVEFHREVUQUlMU0ZfRk9STUFUVEFHKSA9PSBTX09LKSB7CgkgICAgaWYgKGFjbUZvcm1hdERldGFpbHNXKE5VTEwsJmFmZCxBQ01fRk9STUFUREVUQUlMU0ZfRk9STUFUKSA9PSBTX09LKQoJICAgICAgd3NwcmludGZXKHN6Rm9ybWF0LCBzekF1ZGlvRm10LCBhZmQuc3pGb3JtYXQsIGFmdGQuc3pGb3JtYXRUYWcpOwoJICB9Cgl9CiAgICAgIH0KICAgICAgR2xvYmFsRnJlZVB0cihscEZvcm1hdCk7CiAgICB9CgogICAgLyogc2V0IHRleHQgZm9yIGZvcm1hdCBkZXNjcmlwdGlvbiAqLwogICAgU2V0RGxnSXRlbVRleHRXKGhXbmQsIElEQ19GT1JNQVRURVhULCBzekZvcm1hdCk7CgogICAgLyogRGlzYWJsZSBvcHRpb24gYnV0dG9uIGZvciB1bnN1cHBvcnRlZCBzdHJlYW10eXBlcyAqLwogICAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPIHx8CglzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBUUlVFKTsKICAgIGVsc2UKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBGQUxTRSk7CiAgfQoKfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgQVZJU2F2ZU9wdGlvbnNEbGdQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogIERXT1JEIGR3SW50ZXJsZWF2ZTsKICBCT09MICBiSXNJbnRlcmxlYXZlZDsKICBJTlQgICBuOwoKICAvKlRSQUNFKCIoJXAsJXUsMHglMDRYLDB4JTA4bFgpXG4iLCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Ki8KCiAgc3dpdGNoICh1TXNnKSB7CiAgY2FzZSBXTV9JTklURElBTE9HOgogICAgU2F2ZU9wdHMubkN1cnJlbnQgPSAwOwogICAgaWYgKFNhdmVPcHRzLm5TdHJlYW1zID09IDEpIHsKICAgICAgRW5kRGlhbG9nKGhXbmQsIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKGhXbmQpKTsKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLyogYWRkIHN0cmVhbXMgKi8KICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CiAgICAgIEFWSVNUUkVBTUlORk9XIHNJbmZvOwoKICAgICAgQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW25dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsIElEQ19TVFJFQU0sIENCX0FERFNUUklORywKCQkJICAwTCwgKExQQVJBTSlzSW5mby5zek5hbWUpOwogICAgfQoKICAgIC8qIHNlbGVjdCBmaXJzdCBzdHJlYW0gKi8KICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfU0VUQ1VSU0VMLCAwLCAwKTsKICAgIFNlbmRNZXNzYWdlVyhoV25kLCBXTV9DT01NQU5ELAoJCSBHRVRfV01fQ09NTUFORF9NUFMoSURDX1NUUkVBTSwgaFduZCwgQ0JOX1NFTENIQU5HRSkpOwoKICAgIC8qIGluaXRpYWxpemUgaW50ZXJsZWF2ZSAqLwogICAgaWYgKFNhdmVPcHRzLnBwT3B0aW9uc1swXSAhPSBOVUxMICYmCgkoU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX1ZBTElEKSkgewogICAgICBiSXNJbnRlcmxlYXZlZCA9IChTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfSU5URVJMRUFWRSk7CiAgICAgIGR3SW50ZXJsZWF2ZSA9IFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdJbnRlcmxlYXZlRXZlcnk7CiAgICB9IGVsc2UgewogICAgICBiSXNJbnRlcmxlYXZlZCA9IFRSVUU7CiAgICAgIGR3SW50ZXJsZWF2ZSAgID0gMDsKICAgIH0KICAgIENoZWNrRGxnQnV0dG9uKGhXbmQsIElEQ19JTlRFUkxFQVZFLCBiSXNJbnRlcmxlYXZlZCk7CiAgICBTZXREbGdJdGVtSW50KGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlksIGR3SW50ZXJsZWF2ZSwgRkFMU0UpOwogICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSksIGJJc0ludGVybGVhdmVkKTsKICAgIGJyZWFrOwogIGNhc2UgV01fQ09NTUFORDoKICAgIHN3aXRjaCAoR0VUX1dNX0NPTU1BTkRfSUQod1BhcmFtLCBsUGFyYW0pKSB7CiAgICBjYXNlIElET0s6CiAgICAgIC8qIGdldCBkYXRhIGZyb20gY29udHJvbHMgYW5kIHNhdmUgdGhlbSAqLwogICAgICBkd0ludGVybGVhdmUgICA9IEdldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgTlVMTCwgMCk7CiAgICAgIGJJc0ludGVybGVhdmVkID0gSXNEbGdCdXR0b25DaGVja2VkKGhXbmQsIElEQ19JTlRFUkxFQVZFKTsKICAgICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKCWlmIChTYXZlT3B0cy5wcE9wdGlvbnNbbl0gIT0gTlVMTCkgewoJICBpZiAoYklzSW50ZXJsZWF2ZWQpIHsKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ludGVybGVhdmVFdmVyeSA9IGR3SW50ZXJsZWF2ZTsKCSAgfSBlbHNlCgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfSU5URVJMRUFWRTsKCX0KICAgICAgfQogICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgSURDQU5DRUw6CiAgICAgIEVuZERpYWxvZyhoV25kLCBHRVRfV01fQ09NTUFORF9JRCh3UGFyYW0sIGxQYXJhbSkgPT0gSURPSyk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBJRENfSU5URVJMRUFWRToKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSksCgkJICAgSXNEbGdCdXR0b25DaGVja2VkKGhXbmQsIElEQ19JTlRFUkxFQVZFKSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBJRENfU1RSRUFNOgogICAgICBpZiAoR0VUX1dNX0NPTU1BTkRfQ01EKHdQYXJhbSwgbFBhcmFtKSA9PSBDQk5fU0VMQ0hBTkdFKSB7CgkvKiB1cGRhdGUgY29udHJvbCBlbGVtZW50cyAqLwoJQVZJU2F2ZU9wdGlvbnNVcGRhdGUoaFduZCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19PUFRJT05TOgogICAgICBBVklTYXZlT3B0aW9uc0ZtdENob29zZShoV25kKTsKICAgICAgYnJlYWs7CiAgICB9OwogICAgcmV0dXJuIFRSVUU7CiAgfTsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zCQkoQVZJRklMMzIuQCkKICovCkJPT0wgV0lOQVBJIEFWSVNhdmVPcHRpb25zKEhXTkQgaFduZCwgVUlOVCB1RmxhZ3MsIElOVCBuU3RyZWFtcywKCQkJICAgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnMpCnsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBwU2F2ZWRPcHRpb25zID0gTlVMTDsKICBJTlQgcmV0LCBuOwoKICBUUkFDRSgiKCVwLDB4JVgsJWQsJXAsJXApXG4iLCBoV25kLCB1RmxhZ3MsIG5TdHJlYW1zLAoJcHBhdmksIHBwT3B0aW9ucyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoblN0cmVhbXMgPD0gMCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2F2ZSBvcHRpb25zIGluIGNhc2UgdGhlIHVzZXIgcHJlc3NlcyBjYW5jZWwgKi8KICBpZiAocHBPcHRpb25zICE9IE5VTEwgJiYgblN0cmVhbXMgPiAxKSB7CiAgICBwU2F2ZWRPcHRpb25zID0gR2xvYmFsQWxsb2NQdHIoR0hORCxuU3RyZWFtcyAqIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgIGlmIChwU2F2ZWRPcHRpb25zID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgICBpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgltZW1jcHkocFNhdmVkT3B0aW9ucyArIG4sIHBwT3B0aW9uc1tuXSwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgfQogIH0KCiAgU2F2ZU9wdHMudUZsYWdzICAgID0gdUZsYWdzOwogIFNhdmVPcHRzLm5TdHJlYW1zICA9IG5TdHJlYW1zOwogIFNhdmVPcHRzLnBwYXZpcyAgICA9IHBwYXZpOwogIFNhdmVPcHRzLnBwT3B0aW9ucyA9IHBwT3B0aW9uczsKCiAgcmV0ID0gRGlhbG9nQm94VyhBVklGSUxFX2hNb2R1bGUsIE1BS0VJTlRSRVNPVVJDRVcoSUREX1NBVkVPUFRJT05TKSwKCQkgICBoV25kLCBBVklTYXZlT3B0aW9uc0RsZ1Byb2MpOwoKICBpZiAocmV0ID09IC0xKQogICAgcmV0ID0gRkFMU0U7CgogIC8qIHJlc3RvcmUgb3B0aW9ucyB3aGVuIHVzZXIgcHJlc3NlZCBjYW5jZWwgKi8KICBpZiAocFNhdmVkT3B0aW9ucyAhPSBOVUxMKSB7CiAgICBpZiAocmV0ID09IEZBTFNFKSB7CiAgICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CglpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgkgIG1lbWNweShwcE9wdGlvbnNbbl0sIHBTYXZlZE9wdGlvbnMgKyBuLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICAgIH0KICAgIH0KICAgIEdsb2JhbEZyZWVQdHIocFNhdmVkT3B0aW9ucyk7CiAgfQoKICByZXR1cm4gKEJPT0wpcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMMzIuQCkKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMRS4xMjQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlT3B0aW9uc0ZyZWUoSU5UIG5TdHJlYW1zLExQQVZJQ09NUFJFU1NPUFRJT05TKnBwT3B0aW9ucykKewogIFRSQUNFKCIoJWQsJXApXG4iLCBuU3RyZWFtcywgcHBPcHRpb25zKTsKCiAgaWYgKG5TdHJlYW1zIDwgMCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBuU3RyZWFtcyA+IDA7IG5TdHJlYW1zLS0pIHsKICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdICE9IE5VTEwpIHsKICAgICAgcHBPcHRpb25zW25TdHJlYW1zXS0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX1ZBTElEOwoKICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgIT0gTlVMTCkgewoJR2xvYmFsRnJlZVB0cihwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zKTsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgPSBOVUxMOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+Y2JQYXJtcyA9IDA7CiAgICAgIH0KICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0ICE9IE5VTEwpIHsKCUdsb2JhbEZyZWVQdHIocHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQpOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+bHBGb3JtYXQgPSBOVUxMOwoJcHBPcHRpb25zW25TdHJlYW1zXS0+Y2JGb3JtYXQgPSAwOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVWQQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlVkEoTFBDU1RSIHN6RmlsZSwgQ0xTSUQgKnBjbHNpZEhhbmRsZXIsCgkJCSBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLCBpbnQgblN0cmVhbSwKCQkJIFBBVklTVFJFQU0gKnBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcGxwT3B0aW9ucykKewogIExQV1NUUiAgd3N6RmlsZSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKICBpbnQgICAgIGxlbjsKCiAgVFJBQ0UoIiVzLCVwLCVwLCVkLCVwLCVwKVxuIiwgZGVidWdzdHJfYShzekZpbGUpLCBwY2xzaWRIYW5kbGVyLAoJbHBmbkNhbGxiYWNrLCBuU3RyZWFtLCBwcGF2aSwgcGxwT3B0aW9ucyk7CgogIGlmIChzekZpbGUgPT0gTlVMTCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBscE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIGNvbnZlcnQgQVNDSUkgc3RyaW5nIHRvIFVuaWNvZGUgYW5kIGNhbGwgVW5pY29kZSBmdW5jdGlvbiAqLwogIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCBOVUxMLCAwKTsKICBpZiAobGVuIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICB3c3pGaWxlID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAod3N6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzekZpbGUsIC0xLCB3c3pGaWxlLCBsZW4pOwoKICBociA9IEFWSVNhdmVWVyh3c3pGaWxlLCBwY2xzaWRIYW5kbGVyLCBscGZuQ2FsbGJhY2ssCgkJIG5TdHJlYW0sIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgTG9jYWxGcmVlKChITE9DQUwpd3N6RmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGSUxFX0FWSVNhdmVEZWZhdWx0Q2FsbGJhY2sJKGludGVybmFsKQogKi8Kc3RhdGljIEJPT0wgV0lOQVBJIEFWSUZJTEVfQVZJU2F2ZURlZmF1bHRDYWxsYmFjayhJTlQgcHJvZ3Jlc3MpCnsKICBUUkFDRSgiKCVkKVxuIiwgcHJvZ3Jlc3MpOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZVZXCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVWVyhMUENXU1RSIHN6RmlsZSwgQ0xTSUQgKnBjbHNpZEhhbmRsZXIsCgkJCSBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLCBpbnQgblN0cmVhbXMsCgkJCSBQQVZJU1RSRUFNICpwcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgKnBscE9wdGlvbnMpCnsKICBMT05HICAgICAgICAgICBsU3RhcnRbTUFYX0FWSVNUUkVBTVNdOwogIFBBVklTVFJFQU0gICAgIHBPdXRTdHJlYW1zW01BWF9BVklTVFJFQU1TXTsKICBQQVZJU1RSRUFNICAgICBwSW5TdHJlYW1zW01BWF9BVklTVFJFQU1TXTsKICBBVklGSUxFSU5GT1cgICBmSW5mbzsKICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKCiAgUEFWSUZJTEUgICAgICAgcGZpbGUgPSBOVUxMOyAvKiB0aGUgb3V0cHV0IEFWSSBmaWxlICovCiAgTE9ORyAgICAgICAgICAgbEZpcnN0VmlkZW8gPSAtMTsKICBpbnQgICAgICAgICAgICBjdXJTdHJlYW07CgogIC8qIGZvciBpbnRlcmxlYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgZHdJbnRlcmxlYXZlID0gMDsgLyogaW50ZXJsZWF2ZSByYXRlICovCiAgRFdPUkQgICAgICAgICAgZHdGaWxlSW5pdGlhbEZyYW1lczsKICBMT05HICAgICAgICAgICBsRmlsZUxlbmd0aDsKICBMT05HICAgICAgICAgICBsU2FtcGxlSW5jOwoKICAvKiBmb3IgcmVhZGluZy93cml0aW5nIHRoZSBkYXRhIC4uLiAqLwogIExQVk9JRCAgICAgICAgIGxwQnVmZmVyID0gTlVMTDsKICBMT05HICAgICAgICAgICBjYkJ1ZmZlcjsgICAgICAgIC8qIHJlYWwgc2l6ZSBvZiBscEJ1ZmZlciAqLwogIExPTkcgICAgICAgICAgIGxCdWZmZXJTaXplOyAgICAgLyogbmVlZGVkIGJ5dGVzIGZvciBmb3JtYXQocyksIGV0Yy4gKi8KICBMT05HICAgICAgICAgICBsUmVhZEJ5dGVzOwogIExPTkcgICAgICAgICAgIGxSZWFkU2FtcGxlczsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVkLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhzekZpbGUpLCBwY2xzaWRIYW5kbGVyLAoJbHBmbkNhbGxiYWNrLCBuU3RyZWFtcywgcHBhdmksIHBscE9wdGlvbnMpOwoKICBpZiAoc3pGaWxlID09IE5VTEwgfHwgcHBhdmkgPT0gTlVMTCB8fCBwbHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChuU3RyZWFtcyA+PSBNQVhfQVZJU1RSRUFNUykgewogICAgV0FSTigiQ2FuJ3Qgd3JpdGUgQVZJIHdpdGggJWQgc3RyZWFtcyBvbmx5IHN1cHBvcnRzICVkIC0tIGNoYW5nZSBNQVhfQVZJU1RSRUFNUyFcbiIsIG5TdHJlYW1zLCBNQVhfQVZJU1RSRUFNUyk7CiAgICByZXR1cm4gQVZJRVJSX0lOVEVSTkFMOwogIH0KCiAgaWYgKGxwZm5DYWxsYmFjayA9PSBOVUxMKQogICAgbHBmbkNhbGxiYWNrID0gQVZJRklMRV9BVklTYXZlRGVmYXVsdENhbGxiYWNrOwoKICAvKiBjbGVhciBsb2NhbCB2YXJpYWJsZShzKSAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBwSW5TdHJlYW1zW2N1clN0cmVhbV0gID0gTlVMTDsKICAgIHBPdXRTdHJlYW1zW2N1clN0cmVhbV0gPSBOVUxMOwogIH0KCiAgLyogb3BlbiBvdXRwdXQgQVZJIGZpbGUgKGNyZWF0ZSBpdCBpZiBpdCBkb2Vzbid0IGV4aXN0KSAqLwogIGhyZXMgPSBBVklGaWxlT3BlblcoJnBmaWxlLCBzekZpbGUsIE9GX0NSRUFURXxPRl9TSEFSRV9FWENMVVNJVkV8T0ZfV1JJVEUsCgkJICAgICAgcGNsc2lkSGFuZGxlcik7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwogIEFWSUZpbGVJbmZvVyhwZmlsZSwgJmZJbmZvLCBzaXplb2YoZkluZm8pKTsgLyogZm9yIGR3Q2FwcyAqLwoKICAvKiBpbml0aWFsaXplIG91ciBkYXRhIHN0cnVjdHVyZXMgcGFydCAxICovCiAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgIFBBVklTVFJFQU0gcEN1clN0cmVhbSA9IHBwYXZpW2N1clN0cmVhbV07CgogICAgaHJlcyA9IEFWSVN0cmVhbUluZm9XKHBDdXJTdHJlYW0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICBnb3RvIGVycm9yOwoKICAgIC8qIHNlYXJjaCBmaXJzdCB2aWRlbyBzdHJlYW0gYW5kIGNoZWNrIGZvciBpbnRlcmxlYXZpbmcgKi8KICAgIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICAvKiByZW1lbWJlciBmaXJzdCB2aWRlbyBzdHJlYW0gLS0gbmVlZGVkIGZvciBpbnRlcmxlYXZpbmcgKi8KICAgICAgaWYgKGxGaXJzdFZpZGVvIDwgMCkKCWxGaXJzdFZpZGVvID0gY3VyU3RyZWFtOwogICAgfSBlbHNlIGlmICghZHdJbnRlcmxlYXZlICYmIHBscE9wdGlvbnMgIT0gTlVMTCkgewogICAgICAvKiBjaGVjayBpZiBhbnkgbm9uLXZpZGVvIHN0cmVhbSB3YW50cyB0byBiZSBpbnRlcmxlYXZlZCAqLwogICAgICBXQVJOKCJvcHRpb25zLmZsYWdzPTB4JWxYIG9wdGlvbnMuZHdJbnRlcmxlYXZlPSVsdVxuIixwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3RmxhZ3MscGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ludGVybGVhdmVFdmVyeSk7CiAgICAgIGlmIChwbHBPcHRpb25zW2N1clN0cmVhbV0gIT0gTlVMTCAmJgoJICBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfSU5URVJMRUFWRSkKCWR3SW50ZXJsZWF2ZSA9IHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdJbnRlcmxlYXZlRXZlcnk7CiAgICB9CgogICAgLyogY3JlYXRlIGRlLS9jb21wcmVzc2VkIHN0cmVhbSBpbnRlcmZhY2UgaWYgbmVlZGVkICovCiAgICBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPSBOVUxMOwogICAgaWYgKHBscE9wdGlvbnMgIT0gTlVMTCAmJiBwbHBPcHRpb25zW2N1clN0cmVhbV0gIT0gTlVMTCkgewogICAgICBpZiAocGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5mY2NIYW5kbGVyIHx8CgkgIHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+bHBGb3JtYXQgIT0gTlVMTCkgewoJRFdPUkQgZHdLZXlTYXZlID0gcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0tleUZyYW1lRXZlcnk7CgoJaWYgKGZJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0FMTEtFWUZSQU1FUykKCSAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0tleUZyYW1lRXZlcnkgPSAxOwoKCWhyZXMgPSBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbSgmcEluU3RyZWFtc1tjdXJTdHJlYW1dLCBwQ3VyU3RyZWFtLAoJCQkJICAgICAgIHBscE9wdGlvbnNbY3VyU3RyZWFtXSwgTlVMTCk7CglwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3S2V5RnJhbWVFdmVyeSA9IGR3S2V5U2F2ZTsKCWlmIChGQUlMRUQoaHJlcykgfHwgcEluU3RyZWFtc1tjdXJTdHJlYW1dID09IE5VTEwpIHsKCSAgcEluU3RyZWFtc1tjdXJTdHJlYW1dID0gTlVMTDsKCSAgZ290byBlcnJvcjsKCX0KCgkvKiB0ZXN0IHN0cmVhbSBpbnRlcmZhY2UgYW5kIHVwZGF0ZSBzdHJlYW0taW5mbyAqLwoJaHJlcyA9IEFWSVN0cmVhbUluZm9XKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGdvdG8gZXJyb3I7CiAgICAgIH0KICAgIH0KCiAgICAvKiBub3cgaGFuZGxlIHN0cmVhbXMgd2hpY2ggd2lsbCBvbmx5IGJlIGNvcGllZCAqLwogICAgaWYgKHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9PSBOVUxMKSB7CiAgICAgIHBDdXJTdHJlYW0gPSBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPSBwcGF2aVtjdXJTdHJlYW1dOwogICAgICBBVklTdHJlYW1BZGRSZWYocEN1clN0cmVhbSk7CiAgICB9IGVsc2UKICAgICAgcEN1clN0cmVhbSA9IHBJblN0cmVhbXNbY3VyU3RyZWFtXTsKCiAgICBsU3RhcnRbY3VyU3RyZWFtXSA9IHNJbmZvLmR3U3RhcnQ7CiAgfSAvKiBmb3IgYWxsIHN0cmVhbXMgKi8KCiAgLyogY2hlY2sgdGhhdCBmaXJzdCB2aWRlbyBzdHJlYW0gaXMgdGhlIGZpcnN0IHN0cmVhbSAqLwogIGlmIChsRmlyc3RWaWRlbyA+IDApIHsKICAgIFBBVklTVFJFQU0gcFRtcCA9IHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dOwogICAgTE9ORyBsVG1wID0gbFN0YXJ0W2xGaXJzdFZpZGVvXTsKCiAgICBwSW5TdHJlYW1zW2xGaXJzdFZpZGVvXSA9IHBJblN0cmVhbXNbMF07CiAgICBwSW5TdHJlYW1zWzBdID0gcFRtcDsKICAgIGxTdGFydFtsRmlyc3RWaWRlb10gPSBsU3RhcnRbMF07CiAgICBsU3RhcnRbMF0gPSBsVG1wOwogICAgbEZpcnN0VmlkZW8gPSAwOwogIH0KCiAgLyogYWxsb2NhdGUgYnVmZmVyIGZvciBmb3JtYXRzLCBkYXRhLCBldGMuIG9mIGFuIGluaXRpYWwgc2l6ZSBvZiA2NCBrQnl0ZXMqLwogIGxwQnVmZmVyID0gR2xvYmFsQWxsb2NQdHIoR1BUUiwgY2JCdWZmZXIgPSAweDAwMDEwMDAwKTsKICBpZiAobHBCdWZmZXIgPT0gTlVMTCkgewogICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CiAgICBnb3RvIGVycm9yOwogIH0KCiAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1swXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICBsRmlsZUxlbmd0aCA9IHNJbmZvLmR3TGVuZ3RoOwogIGR3RmlsZUluaXRpYWxGcmFtZXMgPSAwOwogIGlmIChsRmlyc3RWaWRlbyA+PSAwKSB7CiAgICAvKiBjaGVjayBmb3IgY29ycmVjdCB2ZXJzaW9uIG9mIHRoZSBmb3JtYXQKICAgICAqICAtLSBuZWVkIGF0IGxlYXN0IEJJVE1BUElORk9IRUFERVIgb3IgbmV3ZXIKICAgICAqLwogICAgbFNhbXBsZUluYyA9IDE7CiAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tsRmlyc3RWaWRlb10sIEFWSVN0cmVhbVN0YXJ0KHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dKSwgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CiAgICBpZiAobEJ1ZmZlclNpemUgPCAoTE9ORylzaXplb2YoQklUTUFQSU5GT0hFQURFUikpCiAgICAgIGhyZXMgPSBBVklFUlJfSU5URVJOQUw7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICBnb3RvIGVycm9yOwogIH0gZWxzZSAvKiB1c2Ugb25lIHNlY29uZCBibG9ja3MgZm9yIGludGVybGVhdmluZyBpZiBubyB2aWRlbyBwcmVzZW50ICovCiAgICBsU2FtcGxlSW5jID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKHBJblN0cmVhbXNbMF0sIDEwMDAwMDApOwoKICAvKiBjcmVhdGUgb3V0cHV0IHN0cmVhbXMgKi8KICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoKICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyA9IDA7CiAgICBpZiAoZHdJbnRlcmxlYXZlICE9IDAgJiYgY3VyU3RyZWFtID4gMCAmJiBzSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVWSURFTykgewogICAgICAvKiA3NTAgbXMgaW5pdGlhbCBmcmFtZXMgZm9yIG5vbi12aWRlbyBzdHJlYW1zICovCiAgICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyA9IEFWSVN0cmVhbVRpbWVUb1NhbXBsZShwSW5TdHJlYW1zWzBdLCA3NTApOwogICAgfQoKICAgIGhyZXMgPSBBVklGaWxlQ3JlYXRlU3RyZWFtVyhwZmlsZSwgJnBPdXRTdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbyk7CiAgICBpZiAocE91dFN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMICYmIFNVQ0NFRURFRChocmVzKSkgewogICAgICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IGZvciB0aGlzIHN0cmVhbSAqLwogICAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCQkgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHJlcykpCglnb3RvIGVycm9yOwogICAgICBocmVzID0gQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIDAsIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHJlcykpCglnb3RvIGVycm9yOwoKICAgICAgLyogdHJ5IHRvIGNvcHkgc3RyZWFtIGhhbmRsZXIgZGF0YSAqLwogICAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgICBocmVzID0gQVZJU3RyZWFtUmVhZERhdGEocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBja2lkU1RSRUFNSEFORExFUkRBVEEsCgkJCSAgICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgICAgaWYgKFNVQ0NFRURFRChocmVzKSAmJiBsQnVmZmVyU2l6ZSA+IDApIHsKCWhyZXMgPSBBVklTdHJlYW1Xcml0ZURhdGEocE91dFN0cmVhbXNbY3VyU3RyZWFtXSxja2lkU1RSRUFNSEFORExFUkRBVEEsCgkJCQkgIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBnb3RvIGVycm9yOwogICAgICB9CgogICAgICBpZiAoZHdGaWxlSW5pdGlhbEZyYW1lcyA8IHNJbmZvLmR3SW5pdGlhbEZyYW1lcykKCWR3RmlsZUluaXRpYWxGcmFtZXMgPSBzSW5mby5kd0luaXRpYWxGcmFtZXM7CiAgICAgIGxSZWFkQnl0ZXMgPQoJQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUocE91dFN0cmVhbXNbMF0sIHBJblN0cmVhbXNbY3VyU3RyZWFtXSwKCQkJCXNJbmZvLmR3TGVuZ3RoKTsKICAgICAgaWYgKGxGaWxlTGVuZ3RoIDwgbFJlYWRCeXRlcykKCWxGaWxlTGVuZ3RoID0gbFJlYWRCeXRlczsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNyZWF0aW9uIG9mIGRlLS9jb21wcmVzc2lvbiBzdHJlYW0gaW50ZXJmYWNlIGZhaWxlZCAqLwogICAgICBXQVJOKCJjcmVhdGlvbiBvZiAoZGUtKWNvbXByZXNzaW9uIHN0cmVhbSBmYWlsZWQgZm9yIHN0cmVhbSAlZFxuIixjdXJTdHJlYW0pOwogICAgICBBVklTdHJlYW1SZWxlYXNlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CiAgICAgIGlmIChjdXJTdHJlYW0gKyAxID49IG5TdHJlYW1zKSB7CgkvKiBtb3ZlIHRoZSBvdGhlcnMgb25lIHVwICovCglQQVZJU1RSRUFNICpwcGFzID0gJnBJblN0cmVhbXNbY3VyU3RyZWFtXTsKCWludCAgICAgICAgICAgIG4gPSBuU3RyZWFtcyAtIChjdXJTdHJlYW0gKyAxKTsKCglkbyB7CgkgICpwcGFzID0gcEluU3RyZWFtc1tjdXJTdHJlYW0gKyAxXTsKCX0gd2hpbGUgKC0tbik7CiAgICAgIH0KICAgICAgblN0cmVhbXMtLTsKICAgICAgY3VyU3RyZWFtLS07CiAgICB9CiAgfSAvKiBjcmVhdGUgb3V0cHV0IHN0cmVhbXMgZm9yIGFsbCBpbnB1dCBzdHJlYW1zICovCgogIC8qIGhhdmUgd2Ugc3RpbGwgc29tZXRoaW5nIHRvIHdyaXRlLCBvciBsb3N0IGV2ZXJ5dGhpbmc/ICovCiAgaWYgKG5TdHJlYW1zIDw9IDApCiAgICBnb3RvIGVycm9yOwoKICBpZiAoZHdJbnRlcmxlYXZlKSB7CiAgICBMT05HIGxDdXJGcmFtZSA9IC1kd0ZpbGVJbml0aWFsRnJhbWVzOwoKICAgIC8qIGludGVybGVhdmVkIGZpbGUgKi8KICAgIGlmIChkd0ludGVybGVhdmUgPT0gMSkKICAgICAgQVZJRmlsZUVuZFJlY29yZChwZmlsZSk7CgogICAgZm9yICg7IGxDdXJGcmFtZSA8IGxGaWxlTGVuZ3RoOyBsQ3VyRnJhbWUgKz0gbFNhbXBsZUluYykgewogICAgICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewoJTE9ORyBsTGFzdFNhbXBsZTsKCglocmVzID0gQVZJU3RyZWFtSW5mb1cocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGdvdG8gZXJyb3I7CgoJLyogaW5pdGlhbCBmcmFtZXMgcGhhc2UgYXQgdGhlIGVuZCBmb3IgdGhpcyBzdHJlYW0/ICovCglpZiAoLShMT05HKXNJbmZvLmR3SW5pdGlhbEZyYW1lcyA+IGxDdXJGcmFtZSkKCSAgY29udGludWU7CgoJaWYgKChsRmlsZUxlbmd0aCAtIGxTYW1wbGVJbmMpIDw9IGxDdXJGcmFtZSkgewoJICBsTGFzdFNhbXBsZSA9IEFWSVN0cmVhbUxlbmd0aChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJICBsRmlyc3RWaWRlbyA9IGxMYXN0U2FtcGxlICsgQVZJU3RyZWFtU3RhcnQocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKCX0gZWxzZSB7CgkgIGlmIChjdXJTdHJlYW0gIT0gMCkgewoJICAgIGxGaXJzdFZpZGVvID0KCSAgICAgIEFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgcEluU3RyZWFtc1swXSwKCQkJCSAgICAgIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTyA/IAoJCQkJICAgICAgIChMT05HKWR3SW50ZXJsZWF2ZSA6IGxTYW1wbGVJbmMpICsKCQkJCSAgICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSk7CgkgIH0gZWxzZQoJICAgIGxGaXJzdFZpZGVvID0gbFNhbXBsZUluYyArIChzSW5mby5kd0luaXRpYWxGcmFtZXMgKyBsQ3VyRnJhbWUpOwoKCSAgbExhc3RTYW1wbGUgPSBBVklTdHJlYW1FbmQocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKCSAgaWYgKGxMYXN0U2FtcGxlIDw9IGxGaXJzdFZpZGVvKQoJICAgIGxGaXJzdFZpZGVvID0gbExhc3RTYW1wbGU7Cgl9CgoJLyogY29weSBuZWVkZWQgc2FtcGxlcyBub3cgKi8KCVdBUk4oImNvcHkgZnJvbSBzdHJlYW0gJWQgc2FtcGxlcyAlbGQgdG8gJWxkLi4uXG4iLGN1clN0cmVhbSwKCSAgICAgIGxTdGFydFtjdXJTdHJlYW1dLGxGaXJzdFZpZGVvKTsKCXdoaWxlIChsRmlyc3RWaWRlbyA+IGxTdGFydFtjdXJTdHJlYW1dKSB7CgkgIERXT1JEIGZsYWdzID0gMDsKCgkgIC8qIGNvcHkgZm9ybWF0IGluIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIGxTdGFydFtjdXJTdHJlYW1dLAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgbFN0YXJ0W2N1clN0cmVhbV0sCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIHRyeSB0byByZWFkIGRhdGEgdW50aWwgd2UgZ290IGl0LCBvciBlcnJvciAqLwoJICBkbyB7CgkgICAgaHJlcyA9IEFWSVN0cmVhbVJlYWQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBsU3RhcnRbY3VyU3RyZWFtXSwKCQkJCSBsRmlyc3RWaWRlbyAtIGxTdGFydFtjdXJTdHJlYW1dLCBscEJ1ZmZlciwKCQkJCSBjYkJ1ZmZlciwgJmxSZWFkQnl0ZXMsICZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gR2xvYmFsUmVBbGxvY1B0cihscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMiwgR1BUUikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoKCSAgaWYgKEFWSVN0cmVhbUlzS2V5RnJhbWUocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAoTE9ORylzSW5mby5kd1N0YXJ0KSkKCSAgICBmbGFncyA9IEFWSUlGX0tFWUZSQU1FOwoJICBocmVzID0gQVZJU3RyZWFtV3JpdGUocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgLTEsIGxSZWFkU2FtcGxlcywKCQkJCWxwQnVmZmVyLCBsUmVhZEJ5dGVzLCBmbGFncywgTlVMTCwgTlVMTCk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCgkgIGxTdGFydFtjdXJTdHJlYW1dICs9IGxSZWFkU2FtcGxlczsKCX0KCWxTdGFydFtjdXJTdHJlYW1dID0gbEZpcnN0VmlkZW87CiAgICAgIH0gLyogc3RyZWFtIGJ5IHN0cmVhbSAqLwoKICAgICAgLyogbmVlZCB0byBjbG9zZSB0aGlzIGJsb2NrPyAqLwogICAgICBpZiAoZHdJbnRlcmxlYXZlID09IDEpIHsKCWhyZXMgPSBBVklGaWxlRW5kUmVjb3JkKHBmaWxlKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGJyZWFrOwogICAgICB9CgogICAgICAvKiBzaG93IHByb2dyZXNzICovCiAgICAgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KGR3RmlsZUluaXRpYWxGcmFtZXMgKyBsQ3VyRnJhbWUsIDEwMCwKCQkJICAgICAgZHdGaWxlSW5pdGlhbEZyYW1lcyArIGxGaWxlTGVuZ3RoKSkpIHsKCWhyZXMgPSBBVklFUlJfVVNFUkFCT1JUOwoJYnJlYWs7CiAgICAgIH0KICAgIH0gLyogY29weSBmcmFtZSBieSBmcmFtZSAqLwogIH0gZWxzZSB7CiAgICAvKiBub24taW50ZXJsZWF2ZWQgZmlsZSAqLwoKICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KICAgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoY3VyU3RyZWFtLCAxMDAsIG5TdHJlYW1zKSkpIHsKCWhyZXMgPSBBVklFUlJfVVNFUkFCT1JUOwoJZ290byBlcnJvcjsKICAgICAgfQoKICAgICAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoKICAgICAgaWYgKHNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CgkvKiBzYW1wbGUtYmFzZWQgZGF0YSBsaWtlIGF1ZGlvICovCgl3aGlsZSAoc0luZm8uZHdTdGFydCA8IHNJbmZvLmR3TGVuZ3RoKSB7CgkgIExPTkcgbFNhbXBsZXMgPSBjYkJ1ZmZlciAvIHNJbmZvLmR3U2FtcGxlU2l6ZTsKCgkgIC8qIGNvcHkgZm9ybWF0IGluIGNhc2UgaXQgY2FuIGNoYW5nZSAqLwoJICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwoJICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCQkgICAgIGxwQnVmZmVyLCAmbEJ1ZmZlclNpemUpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIHJldHVybiBocmVzOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kYXJpZXMgKi8KCSAgaWYgKGxTYW1wbGVzICE9IChMT05HKShzSW5mby5kd0xlbmd0aCAtIHNJbmZvLmR3U3RhcnQpKQoJICAgIGxTYW1wbGVzID0gc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0OwoKCSAgLyogbm93IHRyeSB0byByZWFkIHVudGlsIHdlIGdldCBpdCwgb3IgYW4gZXJyb3Igb2NjdXJzICovCgkgIGRvIHsKCSAgICBsUmVhZEJ5dGVzICAgPSBjYkJ1ZmZlcjsKCSAgICBsUmVhZFNhbXBsZXMgPSAwOwoJICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkKHBJblN0cmVhbXNbY3VyU3RyZWFtXSxzSW5mby5kd1N0YXJ0LGxTYW1wbGVzLAoJCQkJIGxwQnVmZmVyLGNiQnVmZmVyLCZsUmVhZEJ5dGVzLCZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gR2xvYmFsUmVBbGxvY1B0cihscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMiwgR1BUUikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBpZiAobFJlYWRTYW1wbGVzICE9IDApIHsKCSAgICBzSW5mby5kd1N0YXJ0ICs9IGxSZWFkU2FtcGxlczsKCSAgICBocmVzID0gQVZJU3RyZWFtV3JpdGUocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgLTEsIGxSZWFkU2FtcGxlcywKCQkJCSAgbHBCdWZmZXIsIGxSZWFkQnl0ZXMsIDAsIE5VTEwgLCBOVUxMKTsKCSAgICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgICAgZ290byBlcnJvcjsKCgkgICAgLyogc2hvdyBwcm9ncmVzcyAqLwoJICAgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KHNJbmZvLmR3U3RhcnQsMTAwLG5TdHJlYW1zKnNJbmZvLmR3TGVuZ3RoKSsKCQkJICAgICBNdWxEaXYoY3VyU3RyZWFtLCAxMDAsIG5TdHJlYW1zKSkpIHsKCSAgICAgIGhyZXMgPSBBVklFUlJfVVNFUkFCT1JUOwoJICAgICAgZ290byBlcnJvcjsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgaWYgKChzSW5mby5kd0xlbmd0aCAtIHNJbmZvLmR3U3RhcnQpICE9IDEpIHsKCSAgICAgIGhyZXMgPSBBVklFUlJfRklMRVJFQUQ7CgkgICAgICBnb3RvIGVycm9yOwoJICAgIH0KCSAgfQoJfQogICAgICB9IGVsc2UgewoJLyogYmxvY2stYmFzZWQgZGF0YSBsaWtlIHZpZGVvICovCglmb3IgKDsgc0luZm8uZHdTdGFydCA8IHNJbmZvLmR3TGVuZ3RoOyBzSW5mby5kd1N0YXJ0KyspIHsKCSAgRFdPUkQgZmxhZ3MgPSAwOwoKCSAgLyogY29weSBmb3JtYXQgaW4gY2FzZSBpdCBjYW4gY2hhbmdlICovCgkgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CgkgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJCSAgICAgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIHRyeSB0byByZWFkIGJsb2NrIGFuZCByZXNpemUgYnVmZmVyIGlmIG5lY2Vzc2FyeSAqLwoJICBkbyB7CgkgICAgbFJlYWRTYW1wbGVzID0gMDsKCSAgICBsUmVhZEJ5dGVzICAgPSBjYkJ1ZmZlcjsKCSAgICBocmVzID0gQVZJU3RyZWFtUmVhZChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsIDEsCgkJCQkgbHBCdWZmZXIsIGNiQnVmZmVyLCZsUmVhZEJ5dGVzLCZsUmVhZFNhbXBsZXMpOwoJICB9IHdoaWxlICgoaHJlcyA9PSBBVklFUlJfQlVGRkVSVE9PU01BTEwpICYmCgkJICAgKGxwQnVmZmVyID0gR2xvYmFsUmVBbGxvY1B0cihscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMiwgR1BUUikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBpZiAobFJlYWRTYW1wbGVzICE9IDEpIHsKCSAgICBocmVzID0gQVZJRVJSX0ZJTEVSRUFEOwoJICAgIGdvdG8gZXJyb3I7CgkgIH0KCgkgIGlmIChBVklTdHJlYW1Jc0tleUZyYW1lKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgKExPTkcpc0luZm8uZHdTdGFydCkpCgkgICAgZmxhZ3MgPSBBVklJRl9LRVlGUkFNRTsKCSAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQlscEJ1ZmZlciwgbFJlYWRCeXRlcywgZmxhZ3MsIE5VTEwsIE5VTEwpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICAvKiBzaG93IHByb2dyZXNzICovCgkgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KHNJbmZvLmR3U3RhcnQsMTAwLG5TdHJlYW1zKnNJbmZvLmR3TGVuZ3RoKSsKCQkJICAgTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CgkgICAgaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CgkgICAgZ290byBlcnJvcjsKCSAgfQoJfSAvKiBjb3B5IGFsbCBibG9ja3MgKi8KICAgICAgfQogICAgfSAvKiBjb3B5IGRhdGEgc3RyZWFtIGJ5IHN0cmVhbSAqLwogIH0KCiBlcnJvcjoKICBpZiAobHBCdWZmZXIgIT0gTlVMTCkKICAgIEdsb2JhbEZyZWVQdHIobHBCdWZmZXIpOwogIGlmIChwZmlsZSAhPSBOVUxMKSB7CiAgICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgICBpZiAocE91dFN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMKQoJQVZJU3RyZWFtUmVsZWFzZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dKTsKICAgICAgaWYgKHBJblN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMKQoJQVZJU3RyZWFtUmVsZWFzZShwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwogICAgfQoKICAgIEFWSUZpbGVSZWxlYXNlKHBmaWxlKTsKICB9CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUNyZWF0ZUVkaXRhYmxlU3RyZWFtCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQ3JlYXRlRWRpdGFibGVTdHJlYW0oUEFWSVNUUkVBTSAqcHBFZGl0YWJsZSwgUEFWSVNUUkVBTSBwU291cmNlKQp7CiAgSUFWSUVkaXRTdHJlYW0gKnBFZGl0ID0gTlVMTDsKICBIUkVTVUxUCSAgaHI7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBwcEVkaXRhYmxlLCBwU291cmNlKTsKCiAgaWYgKHBwRWRpdGFibGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcEVkaXRhYmxlID0gTlVMTDsKCiAgaWYgKHBTb3VyY2UgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTb3VyY2UsICZJSURfSUFWSUVkaXRTdHJlYW0sCgkJCQkgICAoTFBWT0lEKikmcEVkaXQpOwogICAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgICBociA9IElBVklFZGl0U3RyZWFtX0Nsb25lKHBFZGl0LCBwcEVkaXRhYmxlKTsKICAgICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CgogICAgICByZXR1cm4gaHI7CiAgICB9CiAgfQoKICAvKiBuZWVkIG93biBpbXBsZW1lbnRhdGlvbiBvZiBJQVZJRWRpdFN0cmVhbSAqLwogIHBFZGl0ID0gQVZJRklMRV9DcmVhdGVFZGl0U3RyZWFtKHBTb3VyY2UpOwogIGlmIChwRWRpdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGhyID0gSUFWSUVkaXRTdHJlYW1fUXVlcnlJbnRlcmZhY2UocEVkaXQsICZJSURfSUFWSVN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQqKXBwRWRpdGFibGUpOwogIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUNsb25lCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1DbG9uZShQQVZJU1RSRUFNIHBTdHJlYW0sIFBBVklTVFJFQU0gKnBwUmVzdWx0KQp7CiAgUEFWSUVESVRTVFJFQU0gcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcFN0cmVhbSwgcHBSZXN1bHQpOwoKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ2xvbmUocEVkaXQsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUNvcHkJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbUNvcHkoUEFWSVNUUkVBTSBwU3RyZWFtLCBMT05HICpwbFN0YXJ0LAoJCQkgICAgICBMT05HICpwbExlbmd0aCwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLCBwU3RyZWFtLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMIHx8IHBwUmVzdWx0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBSZXN1bHQgPSBOVUxMOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ29weShwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbUN1dAkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtQ3V0KFBBVklTVFJFQU0gcFN0cmVhbSwgTE9ORyAqcGxTdGFydCwKCQkJICAgICBMT05HICpwbExlbmd0aCwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLCBwU3RyZWFtLCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICBpZiAocHBSZXN1bHQgIT0gTlVMTCkKICAgICpwcFJlc3VsdCA9IE5VTEw7CiAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9DdXQocEVkaXQsIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1QYXN0ZQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtUGFzdGUoUEFWSVNUUkVBTSBwRGVzdCwgTE9ORyAqcGxTdGFydCwgTE9ORyAqcGxMZW5ndGgsCgkJCSAgICAgICBQQVZJU1RSRUFNIHBTb3VyY2UsIExPTkcgbFN0YXJ0LCBMT05HIGxFbmQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJWxkLCVsZClcbiIsIHBEZXN0LCBwbFN0YXJ0LCBwbExlbmd0aCwKCXBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogIGlmIChwRGVzdCA9PSBOVUxMIHx8IHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBEZXN0LCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9QYXN0ZShwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXRJbmZvQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXRJbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkJICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIHBzdHJlYW0sIGFzaSwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoQVZJU1RSRUFNSU5GT0EpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkoJmFzaXcsIGFzaSwgc2l6ZW9mKGFzaXcpIC0gc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIGFzaS0+c3pOYW1lLCAtMSwKCQkgICAgICBhc2l3LnN6TmFtZSwgc2l6ZW9mKGFzaXcuc3pOYW1lKSk7CgogIHJldHVybiBFZGl0U3RyZWFtU2V0SW5mb1cocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldEluZm9XCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldEluZm9XKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPVyBhc2ksCgkJCQkgIExPTkcgc2l6ZSkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBhc2ksIHNpemUpOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocHN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fU2V0SW5mbyhwRWRpdCwgYXNpLCBzaXplKTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldE5hbWVBCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldE5hbWVBKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBDU1RSIHN6TmFtZSkKewogIEFWSVNUUkVBTUlORk9BIGFzaWE7CiAgSFJFU1VMVCAgICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIHBzdHJlYW0sIGRlYnVnc3RyX2Eoc3pOYW1lKSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoc3pOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBocmVzID0gQVZJU3RyZWFtSW5mb0EocHN0cmVhbSwgJmFzaWEsIHNpemVvZihhc2lhKSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpYS5zek5hbWUsIDAsIHNpemVvZihhc2lhLnN6TmFtZSkpOwogIGxzdHJjcHluQShhc2lhLnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpYS5zek5hbWUpL3NpemVvZihhc2lhLnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9BKHBzdHJlYW0sICZhc2lhLCBzaXplb2YoYXNpYSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXROYW1lVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXROYW1lVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQ1dTVFIgc3pOYW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgcHN0cmVhbSwgZGVidWdzdHJfdyhzek5hbWUpKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzek5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpdy5zek5hbWUsIDAsIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIGxzdHJjcHluVyhhc2l3LnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpdy5zek5hbWUpL3NpemVvZihhc2l3LnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9XKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUNsZWFyQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQ2xlYXJDbGlwYm9hcmQodm9pZCkKewogIFRSQUNFKCIoKVxuIik7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIE9sZVNldENsaXBib2FyZChOVUxMKTsgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklHZXRGcm9tQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJR2V0RnJvbUNsaXBib2FyZChQQVZJRklMRSAqcHBmaWxlKQp7CiAgRklYTUUoIiglcCksIHN0dWIhXG4iLCBwcGZpbGUpOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQVZJTWFrZVN0cmVhbUZyb21DbGlwYm9hcmQgKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlU3RyZWFtRnJvbUNsaXBib2FyZChVSU5UIGNmRm9ybWF0LCBIQU5ETEUgaEdsb2JhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSAqIHBwc3RyZWFtKQp7CiAgRklYTUUoIigweCUwOHgsJXAsJXApLCBzdHViIVxuIiwgY2ZGb3JtYXQsIGhHbG9iYWwsIHBwc3RyZWFtKTsKCiAgaWYgKHBwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklQdXRGaWxlT25DbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklQdXRGaWxlT25DbGlwYm9hcmQoUEFWSUZJTEUgcGZpbGUpCnsKICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKSFJFU1VMVCBDREVDTCBBVklTYXZlQShMUENTVFIgc3pGaWxlLCBDTFNJRCAqIHBjbHNpZEhhbmRsZXIsIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuU3RyZWFtcywgUEFWSVNUUkVBTSBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyBscE9wdGlvbnMsIC4uLikKewogICAgRklYTUUoIiglcywlcCwlcCwweCUwOHgsJXAsJXApLCBzdHViIVxuIiwgZGVidWdzdHJfYShzekZpbGUpLCBwY2xzaWRIYW5kbGVyLCBscGZuQ2FsbGJhY2ssCiAgICAgICAgICBuU3RyZWFtcywgcGF2aSwgbHBPcHRpb25zKTsKCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpIUkVTVUxUIENERUNMIEFWSVNhdmVXKExQQ1dTVFIgc3pGaWxlLCBDTFNJRCAqIHBjbHNpZEhhbmRsZXIsIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuU3RyZWFtcywgUEFWSVNUUkVBTSBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyBscE9wdGlvbnMsIC4uLikKewogICAgRklYTUUoIiglcywlcCwlcCwweCUwOHgsJXAsJXApLCBzdHViIVxuIiwgZGVidWdzdHJfdyhzekZpbGUpLCBwY2xzaWRIYW5kbGVyLCBscGZuQ2FsbGJhY2ssCiAgICAgICAgICBuU3RyZWFtcywgcGF2aSwgbHBPcHRpb25zKTsKCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9Cg==