LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZvciBBVklCdWlsZEZpbHRlclcgLS0gdXNlcyBmaXhlZCBzaXplIHRhYmxlCiAqLwojZGVmaW5lIE1BWF9GSUxURVJTIDMwIC8qIDMwID0+IDdrQiAqLwoKdHlwZWRlZiBzdHJ1Y3QgX0FWSUZpbHRlciB7CiAgV0NIQVIgc3pDbHNpZFs0MF07CiAgV0NIQVIgc3pFeHRlbnNpb25zW01BWF9GSUxURVJTICogN107Cn0gQVZJRmlsdGVyOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZvciBBVklTYXZlT3B0aW9ucwogKi8Kc3RhdGljIHN0cnVjdCB7CiAgVUlOVCAgICAgICAgICAgICAgICAgIHVGbGFnczsKICBJTlQgICAgICAgICAgICAgICAgICAgblN0cmVhbXM7CiAgUEFWSVNUUkVBTSAgICAgICAgICAgKnBwYXZpczsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcHBPcHRpb25zOwogIElOVCAgICAgICAgICAgICAgICAgICBuQ3VycmVudDsKfSBTYXZlT3B0czsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBjb3BpZWQgZnJvbSBkbGxzL29sZTMyL2NvbXBvYmouYwogKi8Kc3RhdGljIEhSRVNVTFQgQVZJRklMRV9DTFNJREZyb21TdHJpbmcoTFBDU1RSIGlkc3RyLCBMUENMU0lEIGlkKQp7CiAgQllURSBjb25zdCAqczsKICBCWVRFICpwOwogIElOVCAgIGk7CiAgQllURSB0YWJsZVsyNTZdOwoKICBpZiAoIWlkc3RyKSB7CiAgICBtZW1zZXQoaWQsIDAsIHNpemVvZihDTFNJRCkpOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCiAgaWYgKGxzdHJsZW5BKGlkc3RyKSAhPSAzOCkKICAgIHJldHVybiBDT19FX0NMQVNTU1RSSU5HOwoKICBzID0gKEJZVEUgY29uc3QqKWlkc3RyOwogIGlmICgoc1swXSE9J3snKSB8fCAoc1s5XSE9Jy0nKSB8fCAoc1sxNF0hPSctJykgfHwgKHNbMTldIT0nLScpIHx8CiAgICAgIChzWzI0XSE9Jy0nKSB8fCAoc1szN10hPSd9JykpCiAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgZm9yIChpID0gMTsgaSA8IDM3OyBpKyspIHsKICAgIGlmICgoaSA9PSA5KSB8fCAoaSA9PSAxNCkgfHwgKGkgPT0gMTkpIHx8IChpID09IDI0KSkKICAgICAgY29udGludWU7CiAgICBpZiAoISgoKHNbaV0gPj0gJzAnKSAmJiAoc1tpXSA8PSAnOScpKSAgfHwKICAgICAgICAoKHNbaV0gPj0gJ2EnKSAmJiAoc1tpXSA8PSAnZicpKSAgfHwKICAgICAgICAoKHNbaV0gPj0gJ0EnKSAmJiAoc1tpXSA8PSAnRicpKSkKICAgICAgICkKICAgICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CiAgfQoKICBUUkFDRSgiJXMgLT4gJXBcbiIsIHMsIGlkKTsKCiAgLyogcXVpY2sgbG9va3VwIHRhYmxlICovCiAgbWVtc2V0KHRhYmxlLCAwLCAyNTYpOwoKICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykKICAgIHRhYmxlWycwJyArIGldID0gaTsKCiAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykgewogICAgdGFibGVbJ0EnICsgaV0gPSBpKzEwOwogICAgdGFibGVbJ2EnICsgaV0gPSBpKzEwOwogIH0KCiAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwogIHAgPSAoQllURSAqKSBpZDsKCiAgcysrOwkvKiBza2lwIGxlYWRpbmcgYnJhY2UgICovCiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewogICAgcFszIC0gaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDQ7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSAyOwogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgIHBbMS1pXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gMjsKICBzKys7CS8qIHNraXAgLSAqLwoKICAvKiB0aGVzZSBhcmUganVzdCBzZXF1ZW50aWFsIGJ5dGVzICovCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHMrKzsJLyogc2tpcCAtICovCgogIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKICAgICpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KCiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBCT09MIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihMUENXU1RSIHN6RmlsZSwgTFBDTFNJRCBscGNsc2lkKQp7CiAgQ0hBUiAgIHN6UmVnS2V5WzI1XTsKICBDSEFSICAgc3pWYWx1ZVsxMDBdOwogIExQV1NUUiBzekV4dCA9IHN0cnJjaHJXKHN6RmlsZSwgJy4nKTsKICBMT05HICAgbGVuID0gc2l6ZW9mKHN6VmFsdWUpIC8gc2l6ZW9mKHN6VmFsdWVbMF0pOwoKICBpZiAoc3pFeHQgPT0gTlVMTCkKICAgIHJldHVybiBGQUxTRTsKCiAgc3pFeHQrKzsKCiAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcRXh0ZW5zaW9uc1xcJS4zbHMiLCBzekV4dCk7CiAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJmxlbikgIT0gRVJST1JfU1VDQ0VTUykKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIChBVklGSUxFX0NMU0lERnJvbVN0cmluZyhzelZhbHVlLCBscGNsc2lkKSA9PSBTX09LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5pdAkJKEFWSUZJTEUuMTAwKQogKi8Kdm9pZCBXSU5BUEkgQVZJRmlsZUluaXQodm9pZCkgewogIE9sZUluaXRpYWxpemUoTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUV4aXQJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUV4aXQJCShBVklGSUxFLjEwMSkKICovCnZvaWQgV0lOQVBJIEFWSUZpbGVFeGl0KHZvaWQpIHsKICAvKiBuZWVkIHRvIGZyZWUgb2xlMzIuZGxsIGlmIHdlIGFyZSB0aGUgbGFzdCBleGl0IGNhbGwgKi8KICAvKiBPbGVVbmluaXRpYWxpemUoKSAqLwogIEZJWE1FKCIoKTogc3R1YiFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVPcGVuQQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlT3BlbgkJKEFWSUZJTEUuMTAyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5BKFBBVklGSUxFICpwcGZpbGUsIExQQ1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIExQV1NUUiAgd3N6RmlsZSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKICBpbnQgICAgIGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOFgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX2Eoc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY29udmVydCBBU0NJSSBzdHJpbmcgdG8gVW5pY29kZSBhbmQgY2FsbCB1bmljb2RlIGZ1bmN0aW9uICovCiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIE5VTEwsIDApOwogIGlmIChsZW4gPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHdzekZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgd3N6RmlsZSwgbGVuKTsKCiAgaHIgPSBBVklGaWxlT3BlblcocHBmaWxlLCB3c3pGaWxlLCB1TW9kZSwgbHBIYW5kbGVyKTsKCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3N6RmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlT3BlblcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5XKFBBVklGSUxFICpwcGZpbGUsIExQQ1dTVFIgc3pGaWxlLCBVSU5UIHVNb2RlLAoJCQkgICAgTFBDTFNJRCBscEhhbmRsZXIpCnsKICBJUGVyc2lzdEZpbGUgKnBwZXJzaXN0ID0gTlVMTDsKICBDTFNJRCAgICAgICAgIGNsc2lkSGFuZGxlcjsKICBIUkVTVUxUICAgICAgIGhyOwoKICBUUkFDRSgiKCVwLCVzLDB4JVgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX3coc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwZmlsZSA9IE5VTEw7CgogIC8qIGlmIG5vIGhhbmRsZXIgdGhlbiB0cnkgZ3Vlc3NpbmcgaXQgYnkgZXh0ZW5zaW9uICovCiAgaWYgKGxwSGFuZGxlciA9PSBOVUxMKSB7CiAgICBpZiAoISBBVklGSUxFX0dldEZpbGVIYW5kbGVyQnlFeHRlbnNpb24oc3pGaWxlLCAmY2xzaWRIYW5kbGVyKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIG1lbWNweSgmY2xzaWRIYW5kbGVyLCBscEhhbmRsZXIsIHNpemVvZihjbHNpZEhhbmRsZXIpKTsKCiAgLyogY3JlYXRlIGluc3RhbmNlIG9mIGhhbmRsZXIgKi8KICBociA9IENvQ3JlYXRlSW5zdGFuY2UoJmNsc2lkSGFuZGxlciwgTlVMTCwgQ0xTQ1RYX0lOUFJPQywgJklJRF9JQVZJRmlsZSwgKExQVk9JRCopcHBmaWxlKTsKICBpZiAoRkFJTEVEKGhyKSB8fCAqcHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIC8qIGFzayBmb3IgSVBlcnNpc3RGaWxlIGludGVyZmFjZSBmb3IgbG9hZGluZy9jcmVhdGluZyB0aGUgZmlsZSAqLwogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKnBwZmlsZSwgJklJRF9JUGVyc2lzdEZpbGUsIChMUFZPSUQqKSZwcGVyc2lzdCk7CiAgaWYgKEZBSUxFRChocikgfHwgcHBlcnNpc3QgPT0gTlVMTCkgewogICAgSUFWSUZpbGVfUmVsZWFzZSgqcHBmaWxlKTsKICAgICpwcGZpbGUgPSBOVUxMOwogICAgcmV0dXJuIGhyOwogIH0KCiAgaHIgPSBJUGVyc2lzdEZpbGVfTG9hZChwcGVyc2lzdCwgc3pGaWxlLCB1TW9kZSk7CiAgSVBlcnNpc3RGaWxlX1JlbGVhc2UocHBlcnNpc3QpOwogIGlmIChGQUlMRUQoaHIpKSB7CiAgICBJQVZJRmlsZV9SZWxlYXNlKCpwcGZpbGUpOwogICAgKnBwZmlsZSA9IE5VTEw7CiAgfQoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUFkZFJlZgkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlQWRkUmVmCQkoQVZJRklMRS4xNDApCiAqLwpVTE9ORyBXSU5BUEkgQVZJRmlsZUFkZFJlZihQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZihwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVJlbGVhc2UJCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZVJlbGVhc2UJCShBVklGSUxFLjE0MSkKICovClVMT05HIFdJTkFQSSBBVklGaWxlUmVsZWFzZShQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbmZvQQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlSW5mbwkJKEFWSUZJTEUuMTQyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUluZm9BKFBBVklGSUxFIHBmaWxlLCBMUEFWSUZJTEVJTkZPQSBhZmksIExPTkcgc2l6ZSkKewogIEFWSUZJTEVJTkZPVyBhZml3OwogIEhSRVNVTFQgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgcGZpbGUsIGFmaSwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKEFWSUZJTEVJTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJRmlsZV9JbmZvKHBmaWxlLCAmYWZpdywgc2l6ZW9mKGFmaXcpKTsKCiAgbWVtY3B5KGFmaSwgJmFmaXcsIHNpemVvZigqYWZpKSAtIHNpemVvZihhZmktPnN6RmlsZVR5cGUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYWZpdy5zekZpbGVUeXBlLCAtMSwgYWZpLT5zekZpbGVUeXBlLAoJCSAgICAgIHNpemVvZihhZmktPnN6RmlsZVR5cGUpLCBOVUxMLCBOVUxMKTsKICBhZmktPnN6RmlsZVR5cGVbc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb1coUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9XIGFmaXcsIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBwZmlsZSwgYWZpdywgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9JbmZvKHBmaWxlLCBhZml3LCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlR2V0U3RyZWFtCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMRS4xNDMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlR2V0U3RyZWFtKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBUUkFDRSgiKCVwLCVwLCclNC40cycsJWQpXG4iLCBwZmlsZSwgYXZpcywgKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0pOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfR2V0U3RyZWFtKHBmaWxlLCBhdmlzLCBmY2NUeXBlLCBsUGFyYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVDcmVhdGVTdHJlYW0JKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtQQkoQVZJRklMMzIuQCkKICogICAgICAgICAgICAgIEFWSUZpbGVDcmVhdGVTdHJlYW0JKEFWSUZJTEUuMTQ0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUNyZWF0ZVN0cmVhbUEoUEFWSUZJTEUgcGZpbGUsIFBBVklTVFJFQU0gKnBwYXZpLAoJCQkJICAgIExQQVZJU1RSRUFNSU5GT0EgcHNpKQp7CiAgQVZJU1RSRUFNSU5GT1cJcHNpdzsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBmaWxlLCBwcGF2aSwgcHNpKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgLyogT25seSB0aGUgc3pOYW1lIGF0IHRoZSBlbmQgaXMgZGlmZmVyZW50ICovCiAgbWVtY3B5KCZwc2l3LCBwc2ksIHNpemVvZigqcHNpKSAtIHNpemVvZihwc2ktPnN6TmFtZSkpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBwc2ktPnN6TmFtZSwgLTEsIHBzaXcuc3pOYW1lLAoJCSAgICAgIHNpemVvZihwc2l3LnN6TmFtZSkgLyBzaXplb2YocHNpdy5zek5hbWVbMF0pKTsKCiAgcmV0dXJuIElBVklGaWxlX0NyZWF0ZVN0cmVhbShwZmlsZSwgcHBhdmksICZwc2l3KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVDcmVhdGVTdHJlYW1XKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBmaWxlLCBhdmlzLCBhc2kpOwoKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSUZpbGVfQ3JlYXRlU3RyZWFtKHBmaWxlLCBhdmlzLCBhc2kpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVXcml0ZURhdGEJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlV3JpdGVEYXRhCShBVklGSUxFLjE0NikKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVXcml0ZURhdGEoUEFWSUZJTEUgcGZpbGUsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJWQpXG4iLCBwZmlsZSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX1dyaXRlRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVJlYWREYXRhCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVSZWFkRGF0YQkJKEFWSUZJTEUuMTQ3KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZVJlYWREYXRhKFBBVklGSUxFIHBmaWxlLERXT1JEIGZjYyxMUFZPSUQgbHAsTFBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJXApXG4iLCBwZmlsZSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX1JlYWREYXRhKHBmaWxlLCBmY2MsIGxwLCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlRW5kUmVjb3JkCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUVuZFJlY29yZAkoQVZJRklMRS4xNDgpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlRW5kUmVjb3JkKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0VuZFJlY29yZChwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQWRkUmVmCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUFkZFJlZgkJKEFWSUZJTEUuMTYwKQogKi8KVUxPTkcgV0lOQVBJIEFWSVN0cmVhbUFkZFJlZihQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSVN0cmVhbV9BZGRSZWYocHN0cmVhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVsZWFzZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlbGVhc2UJKEFWSUZJTEUuMTYxKQogKi8KVUxPTkcgV0lOQVBJIEFWSVN0cmVhbVJlbGVhc2UoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklTdHJlYW1fUmVsZWFzZShwc3RyZWFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1DcmVhdGUJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtQ3JlYXRlCQkoQVZJRklMRS4xMDQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1DcmVhdGUoUEFWSVNUUkVBTSAqcHBhdmksIExPTkcgbFBhcmFtMSwgTE9ORyBsUGFyYW0yLAoJCQkgICAgICAgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwweCUwOFgsMHglMDhYLCVzKVxuIiwgcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIsCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICBociA9IENvQ3JlYXRlSW5zdGFuY2UocGNsc2lkSGFuZGxlciwgTlVMTCwgQ0xTQ1RYX0lOUFJPQywgJklJRF9JQVZJU3RyZWFtLCAoTFBWT0lEKilwcGF2aSk7CiAgaWYgKEZBSUxFRChocikgfHwgKnBwYXZpID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSVN0cmVhbV9DcmVhdGUoKnBwYXZpLCBsUGFyYW0xLCBsUGFyYW0yKTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSUFWSVN0cmVhbV9SZWxlYXNlKCpwcGF2aSk7CiAgICAqcHBhdmkgPSBOVUxMOwogIH0KCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUluZm8JCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtSW5mb0EJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtSW5mbwkJKEFWSUZJTEUuMTYyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtSW5mb0EoUEFWSVNUUkVBTSBwc3RyZWFtLCBMUEFWSVNUUkVBTUlORk9BIGFzaSwKCQkJICAgICAgTE9ORyBzaXplKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBIUkVTVUxUCSBocmVzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CgogIG1lbWNweShhc2ksICZhc2l3LCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYXNpdy5zek5hbWUsIC0xLCBhc2ktPnN6TmFtZSwKCQkgICAgICBzaXplb2YoYXNpLT5zek5hbWUpLCBOVUxMLCBOVUxMKTsKICBhc2ktPnN6TmFtZVtzaXplb2YoYXNpLT5zek5hbWUpIC0gMV0gPSAwOwoKICByZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT1cgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sIGFzaSwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtRmluZFNhbXBsZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUZpbmRTYW1wbGUJKEFWSUZJTEUuMTYzKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtRmluZFNhbXBsZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLCBMT05HIGZsYWdzKQp7CiAgVFJBQ0UoIiglcCwlZCwweCVYKVxuIiwgcHN0cmVhbSwgcG9zLCBmbGFncyk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIHJldHVybiBJQVZJU3RyZWFtX0ZpbmRTYW1wbGUocHN0cmVhbSwgcG9zLCBmbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVhZEZvcm1hdAkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTEUuMTY0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICAgTFBWT0lEIGZvcm1hdCwgTFBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVkLCVwLCVwKVxuIiwgcHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWRGb3JtYXQocHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVNldEZvcm1hdAkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbVNldEZvcm1hdAkoQVZJRklMRS4xNjkpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1TZXRGb3JtYXQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywKCQkJCSAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgVFJBQ0UoIiglcCwlZCwlcCwlZClcbiIsIHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9TZXRGb3JtYXQocHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWQJCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtUmVhZAkJKEFWSUZJTEUuMTY3KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgc3RhcnQsIExPTkcgc2FtcGxlcywKCQkJICAgICBMUFZPSUQgYnVmZmVyLCBMT05HIGJ1ZmZlcnNpemUsCgkJCSAgICAgTFBMT05HIGJ5dGVzcmVhZCwgTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwlcCwlcClcbiIsIHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkKHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1Xcml0ZQkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1Xcml0ZQkJKEFWSUZJTEUuMTY4KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtV3JpdGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgIExQVk9JRCBidWZmZXIsIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCSAgICAgIExQTE9ORyBzYW1wd3JpdHRlbiwgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsMHglWCwlcCwlcClcbiIsIHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUocHN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwgYnVmZmVyc2l6ZSwKCQkJICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtUmVhZERhdGEJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWFkRGF0YQkoQVZJRklMRS4xNjUpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1SZWFkRGF0YShQQVZJU1RSRUFNIHBzdHJlYW0sIERXT1JEIGZjYywgTFBWT0lEIGxwLAoJCQkJIExQTE9ORyBscHJlYWQpCnsKICBUUkFDRSgiKCVwLCclNC40cycsJXAsJXApXG4iLCBwc3RyZWFtLCAoY2hhciopJmZjYywgbHAsIGxwcmVhZCk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZERhdGEocHN0cmVhbSwgZmNjLCBscCwgbHByZWFkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1Xcml0ZURhdGEJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1Xcml0ZURhdGEJKEFWSUZJTEUuMTY2KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtV3JpdGVEYXRhKFBBVklTVFJFQU0gcHN0cmVhbSwgRFdPUkQgZmNjLCBMUFZPSUQgbHAsCgkJCQkgIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlZClcbiIsIHBzdHJlYW0sIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKHBzdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lT3BlbgkoQVZJRklMRS4xMTIpCiAqLwpQR0VURlJBTUUgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lT3BlbihQQVZJU1RSRUFNIHBzdHJlYW0sCgkJCQkgICAgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlXYW50ZWQpCnsKICBQR0VURlJBTUUgcGcgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcHN0cmVhbSwgbHBiaVdhbnRlZCk7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lHZXRGcmFtZSwgKExQVk9JRCopJnBnKSkgfHwKICAgICAgcGcgPT0gTlVMTCkgewogICAgcGcgPSBBVklGSUxFX0NyZWF0ZUdldEZyYW1lKHBzdHJlYW0pOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogIH0KCiAgaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KHBnLCBscGJpV2FudGVkLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkgewogICAgSUdldEZyYW1lX1JlbGVhc2UocGcpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcGc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1HZXRGcmFtZQkoQVZJRklMRS4xMTApCiAqLwpMUFZPSUQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lKFBHRVRGUkFNRSBwZywgTE9ORyBwb3MpCnsKICBUUkFDRSgiKCVwLCVkKVxuIiwgcGcsIHBvcyk7CgogIGlmIChwZyA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiBJR2V0RnJhbWVfR2V0RnJhbWUocGcsIHBvcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWVDbG9zZQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UJKEFWSUZJTEUuMTExKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtR2V0RnJhbWVDbG9zZShQR0VURlJBTUUgcGcpCnsKICBUUkFDRSgiKCVwKVxuIiwgcGcpOwoKICBpZiAocGcgIT0gTlVMTCkKICAgIHJldHVybiBJR2V0RnJhbWVfUmVsZWFzZShwZyk7CiAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0JKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbShQQVZJU1RSRUFNICpwcHNDb21wcmVzc2VkLAoJCQkJICAgICAgIFBBVklTVFJFQU0gcHNTb3VyY2UsCgkJCQkgICAgICAgTFBBVklDT01QUkVTU09QVElPTlMgYWNvLAoJCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgQ0hBUiAgICAgICAgICAgc3pSZWdLZXlbMjVdOwogIENIQVIgICAgICAgICAgIHN6VmFsdWVbMTAwXTsKICBDTFNJRCAgICAgICAgICBjbHNpZEhhbmRsZXI7CiAgSFJFU1VMVCAgICAgICAgaHI7CiAgTE9ORyAgICAgICAgICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKTsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcylcbiIsIHBwc0NvbXByZXNzZWQsIHBzU291cmNlLCBhY28sCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwc0NvbXByZXNzZWQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHBzU291cmNlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgKnBwc0NvbXByZXNzZWQgPSBOVUxMOwoKICAvKiBpZiBubyBoYW5kbGVyIGdpdmVuIGdldCBkZWZhdWx0IG9uZXMgYmFzZWQgb24gc3RyZWFtdHlwZSAqLwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpIHsKICAgIGhyID0gSUFWSVN0cmVhbV9JbmZvKHBzU291cmNlLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CgogICAgd3NwcmludGZBKHN6UmVnS2V5LCAiQVZJRmlsZVxcQ29tcHJlc3NvcnNcXCU0LjRzIiwgKGNoYXIqKSZhc2l3LmZjY1R5cGUpOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVBKEhLRVlfQ0xBU1NFU19ST09ULCBzelJlZ0tleSwgc3pWYWx1ZSwgJnNpemUpICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgICBpZiAoQVZJRklMRV9DTFNJREZyb21TdHJpbmcoc3pWYWx1ZSwgJmNsc2lkSGFuZGxlcikgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9IGVsc2UKICAgIG1lbWNweSgmY2xzaWRIYW5kbGVyLCBwY2xzaWRIYW5kbGVyLCBzaXplb2YoY2xzaWRIYW5kbGVyKSk7CgogIGhyID0gQ29DcmVhdGVJbnN0YW5jZSgmY2xzaWRIYW5kbGVyLCBOVUxMLCBDTFNDVFhfSU5QUk9DLCAmSUlEX0lBVklTdHJlYW0sIChMUFZPSUQqKXBwc0NvbXByZXNzZWQpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcHNDb21wcmVzc2VkID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSVN0cmVhbV9DcmVhdGUoKnBwc0NvbXByZXNzZWQsIChMUEFSQU0pcHNTb3VyY2UsIChMUEFSQU0pYWNvKTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSUFWSVN0cmVhbV9SZWxlYXNlKCpwcHNDb21wcmVzc2VkKTsKICAgICpwcHNDb21wcmVzc2VkID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklNYWtlRmlsZUZyb21TdHJlYW1zCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJTWFrZUZpbGVGcm9tU3RyZWFtcyhQQVZJRklMRSAqcHBmaWxlLCBpbnQgblN0cmVhbXMsCgkJCQkgICAgICBQQVZJU1RSRUFNICpwcFN0cmVhbXMpCnsKICBUUkFDRSgiKCVwLCVkLCVwKVxuIiwgcHBmaWxlLCBuU3RyZWFtcywgcHBTdHJlYW1zKTsKCiAgaWYgKG5TdHJlYW1zIDwgMCB8fCBwcGZpbGUgPT0gTlVMTCB8fCBwcFN0cmVhbXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGZpbGUgPSBBVklGSUxFX0NyZWF0ZUFWSVRlbXBGaWxlKG5TdHJlYW1zLCBwcFN0cmVhbXMpOwogIGlmICgqcHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGUJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVBCShBVklGSUwzMi5AKQogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlICAgKEFWSUZJTEUuMTAzKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlQShQQVZJU1RSRUFNICpwcGF2aSwgTFBDU1RSIHN6RmlsZSwKCQkJCSAgICAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtLAoJCQkJICAgICAgVUlOVCBtb2RlLCBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBQQVZJRklMRSBwZmlsZSA9IE5VTEw7CiAgSFJFU1VMVCAgaHI7CgogIFRSQUNFKCIoJXAsJXMsJyU0LjRzJywlZCwweCVYLCVzKVxuIiwgcHBhdmksIGRlYnVnc3RyX2Eoc3pGaWxlKSwKCShjaGFyKikmZmNjVHlwZSwgbFBhcmFtLCBtb2RlLCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwoKICBociA9IEFWSUZpbGVPcGVuQSgmcGZpbGUsIHN6RmlsZSwgbW9kZSwgcGNsc2lkSGFuZGxlcik7CiAgaWYgKEZBSUxFRChocikgfHwgcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgaHIgPSBJQVZJRmlsZV9HZXRTdHJlYW0ocGZpbGUsIHBwYXZpLCBmY2NUeXBlLCBsUGFyYW0pOwogIElBVklGaWxlX1JlbGVhc2UocGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtT3BlbkZyb21GaWxlVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbU9wZW5Gcm9tRmlsZVcoUEFWSVNUUkVBTSAqcHBhdmksIExQQ1dTVFIgc3pGaWxlLAoJCQkJICAgICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0sCgkJCQkgICAgICBVSU5UIG1vZGUsIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIFBBVklGSUxFIHBmaWxlID0gTlVMTDsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlcywnJTQuNHMnLCVkLDB4JVgsJXMpXG4iLCBwcGF2aSwgZGVidWdzdHJfdyhzekZpbGUpLAoJKGNoYXIqKSZmY2NUeXBlLCBsUGFyYW0sIG1vZGUsIGRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBhdmkgPT0gTlVMTCB8fCBzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcGF2aSA9IE5VTEw7CgogIGhyID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBtb2RlLCBwY2xzaWRIYW5kbGVyKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgcHBhdmksIGZjY1R5cGUsIGxQYXJhbSk7CiAgSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1CZWdpblN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUJlZ2luU3RyZWFtaW5nKFBBVklTVFJFQU0gcGF2aSwgTE9ORyBsU3RhcnQsIExPTkcgbEVuZCwgTE9ORyBsUmF0ZSkKewogIElBVklTdHJlYW1pbmcqIHBzdHJlYW0gPSBOVUxMOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWQsJWQsJWQpXG4iLCBwYXZpLCBsU3RhcnQsIGxFbmQsIGxSYXRlKTsKCiAgaWYgKHBhdmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocGF2aSwgJklJRF9JQVZJU3RyZWFtaW5nLCAoTFBWT0lEKikmcHN0cmVhbSk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcHN0cmVhbSAhPSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1pbmdfQmVnaW4ocHN0cmVhbSwgbFN0YXJ0LCBsRW5kLCBsUmF0ZSk7CiAgICBJQVZJU3RyZWFtaW5nX1JlbGVhc2UocHN0cmVhbSk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUVuZFN0cmVhbWluZwkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbUVuZFN0cmVhbWluZyhQQVZJU1RSRUFNIHBhdmkpCnsKICBJQVZJU3RyZWFtaW5nKiBwc3RyZWFtID0gTlVMTDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwKVxuIiwgcGF2aSk7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwYXZpLCAmSUlEX0lBVklTdHJlYW1pbmcsIChMUFZPSUQqKSZwc3RyZWFtKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwc3RyZWFtICE9IE5VTEwpIHsKICAgIElBVklTdHJlYW1pbmdfRW5kKHBzdHJlYW0pOwogICAgSUFWSVN0cmVhbWluZ19SZWxlYXNlKHBzdHJlYW0pOwogIH0KCiByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVN0YXJ0CQkoQVZJRklMRS4xMzApCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TdGFydChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3U3RhcnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMRS4xMzEpCiAqCQlBVklTdHJlYW1MZW5ndGgJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtTGVuZ3RoKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGFzaXcuZHdMZW5ndGg7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2FtcGxlVG9UaW1lCShBVklGSUxFLjEzMykKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVNhbXBsZVRvVGltZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFNhbXBsZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CiAgTE9ORyB0aW1lOwoKICBUUkFDRSgiKCVwLCVkKVxuIiwgcHN0cmVhbSwgbFNhbXBsZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAtMTsKICBpZiAoYXNpdy5kd1JhdGUgPT0gMCkKICAgIHJldHVybiAtMTsKCiAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kcyAqLwogIGlmIChsU2FtcGxlIDwgYXNpdy5kd1N0YXJ0KQogICAgbFNhbXBsZSA9IGFzaXcuZHdTdGFydDsKICBpZiAobFNhbXBsZSA+IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGgpCiAgICBsU2FtcGxlID0gYXNpdy5kd1N0YXJ0ICsgYXNpdy5kd0xlbmd0aDsKCiAgaWYgKGFzaXcuZHdSYXRlIC8gYXNpdy5kd1NjYWxlIDwgMTAwMCkKICAgIHRpbWUgPSAoTE9ORykoKChmbG9hdClsU2FtcGxlICogYXNpdy5kd1NjYWxlICogMTAwMCkgLyBhc2l3LmR3UmF0ZSk7CiAgZWxzZQogICAgdGltZSA9IChMT05HKSgoKGZsb2F0KWxTYW1wbGUgKiBhc2l3LmR3U2NhbGUgKiAxMDAwICsgKGFzaXcuZHdSYXRlIC0gMSkpIC8gYXNpdy5kd1JhdGUpOwoKICBUUkFDRSgiIC0+ICVkXG4iLHRpbWUpOwogIHJldHVybiB0aW1lOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMRS4xMzIpCiAqCQlBVklTdHJlYW1UaW1lVG9TYW1wbGUJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1UaW1lVG9TYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIGxUaW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBVTE9ORyBzYW1wbGU7CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBwc3RyZWFtLCBsVGltZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwgfHwgbFRpbWUgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gLTE7CiAgaWYgKGFzaXcuZHdTY2FsZSA9PSAwKQogICAgcmV0dXJuIC0xOwoKICBpZiAoYXNpdy5kd1JhdGUgLyBhc2l3LmR3U2NhbGUgPCAxMDAwKQogICAgc2FtcGxlID0gKExPTkcpKCgoKGZsb2F0KWFzaXcuZHdSYXRlICogbFRpbWUpIC8gKGFzaXcuZHdTY2FsZSAqIDEwMDApKSk7CiAgZWxzZQogICAgc2FtcGxlID0gKExPTkcpKCgoZmxvYXQpYXNpdy5kd1JhdGUgKiBsVGltZSArIChhc2l3LmR3U2NhbGUgKiAxMDAwIC0gMSkpIC8gKGFzaXcuZHdTY2FsZSAqIDEwMDApKTsKCiAgLyogbGltaXQgdG8gc3RyZWFtIGJvdW5kcyAqLwogIGlmIChzYW1wbGUgPCBhc2l3LmR3U3RhcnQpCiAgICBzYW1wbGUgPSBhc2l3LmR3U3RhcnQ7CiAgaWYgKHNhbXBsZSA+IGFzaXcuZHdTdGFydCArIGFzaXcuZHdMZW5ndGgpCiAgICBzYW1wbGUgPSBhc2l3LmR3U3RhcnQgKyBhc2l3LmR3TGVuZ3RoOwoKICBUUkFDRSgiIC0+ICVkXG4iLCBzYW1wbGUpOwogIHJldHVybiBzYW1wbGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXIJCShBVklGSUwzMi5AKQogKgkJQVZJQnVpbGRGaWx0ZXJBCQkoQVZJRklMMzIuQCkKICoJCUFWSUJ1aWxkRmlsdGVyCQkoQVZJRklMRS4xMjMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklCdWlsZEZpbHRlckEoTFBTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIExQV1NUUiAgd3N6RmlsdGVyOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWQsJWQpXG4iLCBzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChjYkZpbHRlciA8IDIpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIHN6RmlsdGVyWzBdID0gMDsKICBzekZpbHRlclsxXSA9IDA7CgogIHdzekZpbHRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjYkZpbHRlciAqIHNpemVvZihXQ0hBUikpOwogIGlmICh3c3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IEFWSUJ1aWxkRmlsdGVyVyh3c3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHdzekZpbHRlciwgY2JGaWx0ZXIsCgkJCXN6RmlsdGVyLCBjYkZpbHRlciwgTlVMTCwgTlVMTCk7CiAgfQoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB3c3pGaWx0ZXIpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXJXCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyVyhMUFdTVFIgc3pGaWx0ZXIsIExPTkcgY2JGaWx0ZXIsIEJPT0wgZlNhdmluZykKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsc2lkW10gPSB7J0MnLCdMJywnUycsJ0knLCdEJywwfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pFeHRlbnNpb25GbXRbXSA9IHsnOycsJyonLCcuJywnJScsJ3MnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFWSUZpbGVFeHRlbnNpb25zW10gPQogICAgeydBJywnVicsJ0knLCdGJywnaScsJ2wnLCdlJywnXFwnLCdFJywneCcsJ3QnLCdlJywnbicsJ3MnLCdpJywnbycsJ24nLCdzJywwfTsKCiAgQVZJRmlsdGVyICpscDsKICBXQ0hBUiAgICAgIHN6QWxsRmlsZXNbNDBdOwogIFdDSEFSICAgICAgc3pGaWxlRXh0WzEwXTsKICBXQ0hBUiAgICAgIHN6VmFsdWVbMTI4XTsKICBIS0VZICAgICAgIGhLZXk7CiAgRFdPUkQgICAgICBuLCBpOwogIExPTkcgICAgICAgc2l6ZTsKICBEV09SRCAgICAgIGNvdW50ID0gMDsKCiAgVFJBQ0UoIiglcCwlZCwlZClcbiIsIHN6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKGNiRmlsdGVyIDwgMikKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbHAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgTUFYX0ZJTFRFUlMgKiBzaXplb2YoQVZJRmlsdGVyKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyoKICAgKiAxLiBpdGVyYXRlIG92ZXIgSEtFWV9DTEFTU0VTX1JPT1RcXEFWSUZpbGVcXEV4dGVuc2lvbnMgYW5kIGNvbGxlY3QKICAgKiAgICBleHRlbnNpb25zIGFuZCBDTFNJRCdzCiAgICogMi4gaXRlcmF0ZSBvdmVyIGNvbGxlY3RlZCBDTFNJRCdzIGFuZCBjb3B5IGl0cyBkZXNjcmlwdGlvbiBhbmQgaXRzCiAgICogICAgZXh0ZW5zaW9ucyB0byBzekZpbHRlciBpZiBpdCBmaXRzCiAgICoKICAgKiBGaXJzdCBmaWx0ZXIgaXMgbmFtZWQgIkFsbCBtdWx0aW1lZGlhIGZpbGVzIiBhbmQgaXRzIGZpbHRlciBpcyBhCiAgICogY29sbGVjdGlvbiBvZiBhbGwgcG9zc2libGUgZXh0ZW5zaW9ucyBleGNlcHQgIiouKiIuCiAgICovCiAgaWYgKFJlZ09wZW5LZXlXKEhLRVlfQ0xBU1NFU19ST09ULCBzekFWSUZpbGVFeHRlbnNpb25zLCAmaEtleSkgIT0gU19PSykgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHApOwogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKICB9CiAgZm9yIChuID0gMDtSZWdFbnVtS2V5VyhoS2V5LCBuLCBzekZpbGVFeHQsIHNpemVvZihzekZpbGVFeHQpL3NpemVvZihzekZpbGVFeHRbMF0pKSA9PSBTX09LO24rKykgewogICAgLyogZ2V0IENMU0lEIHRvIGV4dGVuc2lvbiAqLwogICAgc2l6ZSA9IHNpemVvZihzelZhbHVlKTsKICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBzekZpbGVFeHQsIHN6VmFsdWUsICZzaXplKSAhPSBTX09LKQogICAgICBicmVhazsKCiAgICAvKiBzZWFyY2ggaWYgdGhlIENMU0lEIGlzIGFscmVhZHkga25vd24gKi8KICAgIGZvciAoaSA9IDE7IGkgPD0gY291bnQ7IGkrKykgewogICAgICBpZiAobHN0cmNtcFcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSkgPT0gMCkKCWJyZWFrOyAvKiBhIG5ldyBvbmUgKi8KICAgIH0KCiAgICBpZiAoY291bnQgLSBpID09IC0xVSkgewogICAgICAvKiBpdCdzIGEgbmV3IENMU0lEICovCgogICAgICAvKiBGSVhNRTogSG93IGRvIHdlIGdldCBpbmZvJ3MgYWJvdXQgcmVhZC93cml0ZSBjYXBhYmlsaXRpZXM/ICovCgogICAgICBpZiAoY291bnQgPj0gTUFYX0ZJTFRFUlMpIHsKCS8qIHRyeSB0byBpbmZvcm0gdXNlciBvZiBvdXIgZnVsbCBmaXhlZCBzaXplIHRhYmxlICovCglFUlIoIjogTW9yZSB0aGFuICVkIGZpbHRlcnMgZm91bmQhIEFkanVzdCBNQVhfRklMVEVSUyBpbiBkbGxzL2F2aWZpbDMyL2FwaS5jXG4iLCBNQVhfRklMVEVSUyk7CglicmVhazsKICAgICAgfQoKICAgICAgbHN0cmNweVcobHBbaV0uc3pDbHNpZCwgc3pWYWx1ZSk7CgogICAgICBjb3VudCsrOwogICAgfQoKICAgIC8qIGFwcGVuZCBleHRlbnNpb24gdG8gdGhlIGZpbHRlciAqLwogICAgd3NwcmludGZXKHN6VmFsdWUsIHN6RXh0ZW5zaW9uRm10LCBzekZpbGVFeHQpOwogICAgaWYgKGxwW2ldLnN6RXh0ZW5zaW9uc1swXSA9PSAwKQogICAgICBsc3RyY2F0VyhscFtpXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUgKyAxKTsKICAgIGVsc2UKICAgICAgbHN0cmNhdFcobHBbaV0uc3pFeHRlbnNpb25zLCBzelZhbHVlKTsKCiAgICAvKiBhbHNvIGFwcGVuZCB0byB0aGUgImFsbCBtdWx0aW1lZGlhIi1maWx0ZXIgKi8KICAgIGlmIChscFswXS5zekV4dGVuc2lvbnNbMF0gPT0gMCkKICAgICAgbHN0cmNhdFcobHBbMF0uc3pFeHRlbnNpb25zLCBzelZhbHVlICsgMSk7CiAgICBlbHNlCiAgICAgIGxzdHJjYXRXKGxwWzBdLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSk7CiAgfQogIFJlZ0Nsb3NlS2V5KGhLZXkpOwoKICAvKiAyLiBnZXQgZGVzY3JpcHRpb25zIGZvciB0aGUgQ0xTSURzIGFuZCBmaWxsIG91dCBzekZpbHRlciAqLwogIGlmIChSZWdPcGVuS2V5VyhIS0VZX0NMQVNTRVNfUk9PVCwgc3pDbHNpZCwgJmhLZXkpICE9IFNfT0spIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7IG4gPD0gY291bnQ7IG4rKykgewogICAgLyogZmlyc3QgdGhlIGRlc2NyaXB0aW9uICovCiAgICBpZiAobiAhPSAwKSB7CiAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSk7CiAgICAgIGlmIChSZWdRdWVyeVZhbHVlVyhoS2V5LCBscFtuXS5zekNsc2lkLCBzelZhbHVlLCAmc2l6ZSkgPT0gU19PSykgewoJc2l6ZSA9IGxzdHJsZW5XKHN6VmFsdWUpOwoJbHN0cmNweW5XKHN6RmlsdGVyLCBzelZhbHVlLCBjYkZpbHRlcik7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLElEU19BTExNVUxUSU1FRElBLHN6RmlsdGVyLGNiRmlsdGVyKTsKCiAgICAvKiBjaGVjayBmb3IgZW5vdWdoIHNwYWNlICovCiAgICBzaXplKys7CiAgICBpZiAoY2JGaWx0ZXIgPCBzaXplICsgbHN0cmxlblcobHBbbl0uc3pFeHRlbnNpb25zKSArIDIpIHsKICAgICAgc3pGaWx0ZXJbMF0gPSAwOwogICAgICBzekZpbHRlclsxXSA9IDA7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICB9CiAgICBjYkZpbHRlciAtPSBzaXplOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKCiAgICAvKiBhbmQgdGhlbiB0aGUgZmlsdGVyICovCiAgICBsc3RyY3B5blcoc3pGaWx0ZXIsIGxwW25dLnN6RXh0ZW5zaW9ucywgY2JGaWx0ZXIpOwogICAgc2l6ZSA9IGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAxOwogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgfQoKICBSZWdDbG9zZUtleShoS2V5KTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscCk7CgogIC8qIGFkZCAiQWxsIGZpbGVzIiAiKi4qIiBmaWx0ZXIgaWYgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICBzaXplID0gTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQUxMRklMRVMsCgkJICAgICBzekFsbEZpbGVzLCBzaXplb2Yoc3pBbGxGaWxlcykpICsgMTsKICBpZiAoY2JGaWx0ZXIgPiBzaXplKSB7CiAgICBpbnQgaTsKCiAgICAvKiByZXBsYWNlICdAJyB3aXRoIFwwMDAgdG8gc2VwYXJhdGUgZGVzY3JpcHRpb24gb2YgZmlsdGVyICovCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZSAmJiBzekFsbEZpbGVzW2ldICE9IDA7IGkrKykgewogICAgICBpZiAoc3pBbGxGaWxlc1tpXSA9PSAnQCcpIHsKCXN6QWxsRmlsZXNbaV0gPSAwOwoJYnJlYWs7CiAgICAgIH0KICAgIH0KICAgICAgCiAgICBtZW1jcHkoc3pGaWx0ZXIsIHN6QWxsRmlsZXMsIHNpemUgKiBzaXplb2Yoc3pBbGxGaWxlc1swXSkpOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKICAgIHN6RmlsdGVyWzBdID0gMDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBzekZpbHRlclswXSA9IDA7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KfQoKc3RhdGljIEJPT0wgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoSFdORCBoV25kKQp7CiAgTFBBVklDT01QUkVTU09QVElPTlMgcE9wdGlvbnMgPSBTYXZlT3B0cy5wcE9wdGlvbnNbU2F2ZU9wdHMubkN1cnJlbnRdOwogIEFWSVNUUkVBTUlORk9XICAgICAgIHNJbmZvOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIGlmIChwT3B0aW9ucyA9PSBOVUxMIHx8IFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBzdGF0ZSFcbiIpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgICAgJnNJbmZvLCBzaXplb2Yoc0luZm8pKSkpIHsKICAgIEVSUigiOiBBVklTdHJlYW1JbmZvVyBmYWlsZWQhXG4iKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgQ09NUFZBUlMgY3Y7CiAgICBCT09MICAgICByZXQ7CgogICAgbWVtc2V0KCZjdiwgMCwgc2l6ZW9mKGN2KSk7CgogICAgaWYgKChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkgPT0gMCkgewogICAgICBtZW1zZXQocE9wdGlvbnMsIDAsIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgcE9wdGlvbnMtPmZjY1R5cGUgICAgPSBzdHJlYW10eXBlVklERU87CiAgICAgIHBPcHRpb25zLT5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgID0gKERXT1JEKUlDUVVBTElUWV9ERUZBVUxUOwogICAgfQoKICAgIGN2LmNiU2l6ZSAgICAgPSBzaXplb2YoY3YpOwogICAgY3YuZHdGbGFncyAgICA9IElDTUZfQ09NUFZBUlNfVkFMSUQ7CiAgICAvKmN2LmZjY1R5cGUgICAgPSBwT3B0aW9ucy0+ZmNjVHlwZTsgKi8KICAgIGN2LmZjY0hhbmRsZXIgPSBwT3B0aW9ucy0+ZmNjSGFuZGxlcjsKICAgIGN2LmxRICAgICAgICAgPSBwT3B0aW9ucy0+ZHdRdWFsaXR5OwogICAgY3YubHBTdGF0ZSAgICA9IHBPcHRpb25zLT5scFBhcm1zOwogICAgY3YuY2JTdGF0ZSAgICA9IHBPcHRpb25zLT5jYlBhcm1zOwogICAgaWYgKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0tFWUZSQU1FUykKICAgICAgY3YubEtleSA9IHBPcHRpb25zLT5kd0tleUZyYW1lRXZlcnk7CiAgICBlbHNlCiAgICAgIGN2LmxLZXkgPSAwOwogICAgaWYgKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0RBVEFSQVRFKQogICAgICBjdi5sRGF0YVJhdGUgPSBwT3B0aW9ucy0+ZHdCeXRlc1BlclNlY29uZCAvIDEwMjQ7IC8qIG5lZWQga0J5dGVzICovCiAgICBlbHNlCiAgICAgIGN2LmxEYXRhUmF0ZSA9IDA7CgogICAgcmV0ID0gSUNDb21wcmVzc29yQ2hvb3NlKGhXbmQsIFNhdmVPcHRzLnVGbGFncywgTlVMTCwKCQkJICAgICBTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLCAmY3YsIE5VTEwpOwoKICAgIGlmIChyZXQpIHsKICAgICAgcE9wdGlvbnMtPmZjY0hhbmRsZXIgPSBjdi5mY2NIYW5kbGVyOwogICAgICBwT3B0aW9ucy0+bHBQYXJtcyAgID0gY3YubHBTdGF0ZTsKICAgICAgcE9wdGlvbnMtPmNiUGFybXMgICA9IGN2LmNiU3RhdGU7CiAgICAgIHBPcHRpb25zLT5kd1F1YWxpdHkgPSBjdi5sUTsKICAgICAgaWYgKGN2LmxLZXkgIT0gMCkgewoJcE9wdGlvbnMtPmR3S2V5RnJhbWVFdmVyeSA9IGN2LmxLZXk7CglwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfS0VZRlJBTUVTOwogICAgICBpZiAoY3YubERhdGFSYXRlICE9IDApIHsKCXBPcHRpb25zLT5kd0J5dGVzUGVyU2Vjb25kID0gY3YubERhdGFSYXRlICogMTAyNDsgLyogbmVlZCBieXRlcyAqLwoJcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0RBVEFSQVRFOwogICAgICB9IGVsc2UKCXBPcHRpb25zLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfREFUQVJBVEU7CiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzICB8PSBBVklDT01QUkVTU0ZfVkFMSUQ7CiAgICB9CiAgICBJQ0NvbXByZXNzb3JGcmVlKCZjdik7CgogICAgcmV0dXJuIHJldDsKICB9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICBBQ01GT1JNQVRDSE9PU0VXIGFmbXRjOwogICAgTU1SRVNVTFQgICAgICAgICByZXQ7CiAgICBMT05HICAgICAgICAgICAgIHNpemU7CgogICAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uIC0tIFdoaWNoIHZlcnNpb24gaXMgbmVlZGVkPyAqLwoKICAgIG1lbXNldCgmYWZtdGMsIDAsIHNpemVvZihhZm10YykpOwogICAgYWZtdGMuY2JTdHJ1Y3QgID0gc2l6ZW9mKGFmbXRjKTsKICAgIGFmbXRjLmZkd1N0eWxlICA9IDA7CiAgICBhZm10Yy5od25kT3duZXIgPSBoV25kOwoKICAgIGFjbU1ldHJpY3MoTlVMTCwgQUNNX01FVFJJQ19NQVhfU0laRV9GT1JNQVQsICZzaXplKTsKICAgIGlmICgocE9wdGlvbnMtPmNiRm9ybWF0ID09IDAgfHwgcE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpICYmIHNpemUgIT0gMCkgewogICAgICBwT3B0aW9ucy0+bHBGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICAgIHBPcHRpb25zLT5jYkZvcm1hdCA9IHNpemU7CiAgICB9IGVsc2UgaWYgKHBPcHRpb25zLT5jYkZvcm1hdCA8IChEV09SRClzaXplKSB7CiAgICAgIHBPcHRpb25zLT5scEZvcm1hdCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBPcHRpb25zLT5scEZvcm1hdCwgc2l6ZSk7CiAgICAgIHBPcHRpb25zLT5jYkZvcm1hdCA9IHNpemU7CiAgICB9CiAgICBpZiAocE9wdGlvbnMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBGQUxTRTsKICAgIGFmbXRjLnB3ZnggID0gcE9wdGlvbnMtPmxwRm9ybWF0OwogICAgYWZtdGMuY2J3ZnggPSBwT3B0aW9ucy0+Y2JGb3JtYXQ7CgogICAgc2l6ZSA9IDA7CiAgICBBVklTdHJlYW1Gb3JtYXRTaXplKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCXNJbmZvLmR3U3RhcnQsICZzaXplKTsKICAgIGlmIChzaXplIDwgKExPTkcpc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgICBzaXplID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwogICAgYWZtdGMucHdmeEVudW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICBpZiAoYWZtdGMucHdmeEVudW0gIT0gTlVMTCkgewogICAgICBBVklTdHJlYW1SZWFkRm9ybWF0KFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCSAgc0luZm8uZHdTdGFydCwgYWZtdGMucHdmeEVudW0sICZzaXplKTsKICAgICAgYWZtdGMuZmR3RW51bSA9IEFDTV9GT1JNQVRFTlVNRl9DT05WRVJUOwogICAgfQoKICAgIHJldCA9IGFjbUZvcm1hdENob29zZVcoJmFmbXRjKTsKICAgIGlmIChyZXQgPT0gU19PSykKICAgICAgcE9wdGlvbnMtPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX1ZBTElEOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFmbXRjLnB3ZnhFbnVtKTsKICAgIHJldHVybiAocmV0ID09IFNfT0sgPyBUUlVFIDogRkFMU0UpOwogIH0gZWxzZSB7CiAgICBFUlIoIjogdW5rbm93biBzdHJlYW10eXBlIDB4JTA4WFxuIiwgc0luZm8uZmNjVHlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQp9CgpzdGF0aWMgdm9pZCBBVklTYXZlT3B0aW9uc1VwZGF0ZShIV05EIGhXbmQpCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pWaWRlb0ZtdFtdPXsnJScsJ2wnLCdkJywneCcsJyUnLCdsJywnZCcsJ3gnLCclJywnZCcsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QXVkaW9GbXRbXT17JyUnLCdzJywnICcsJyUnLCdzJywwfTsKCiAgV0NIQVIgICAgICAgICAgc3pGb3JtYXRbMTI4XTsKICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKICBMUFZPSUQgICAgICAgICBscEZvcm1hdDsKICBMT05HICAgICAgICAgICBzaXplOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIFNhdmVPcHRzLm5DdXJyZW50ID0gU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLElEQ19TVFJFQU0sQ0JfR0VUQ1VSU0VMLDAsMCk7CiAgaWYgKFNhdmVPcHRzLm5DdXJyZW50IDwgMCkKICAgIHJldHVybjsKCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLCAmc0luZm8sIHNpemVvZihzSW5mbykpKSkKICAgIHJldHVybjsKCiAgQVZJU3RyZWFtRm9ybWF0U2l6ZShTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLHNJbmZvLmR3U3RhcnQsJnNpemUpOwogIGlmIChzaXplID4gMCkgewogICAgc3pGb3JtYXRbMF0gPSAwOwoKICAgIC8qIHJlYWQgZm9ybWF0IHRvIGJ1aWxkIGZvcm1hdCBkZXNjcmlwdGlvbiBzdHJpbmcgKi8KICAgIGxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgaWYgKGxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgaWYgKFNVQ0NFRURFRChBVklTdHJlYW1SZWFkRm9ybWF0KFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sc0luZm8uZHdTdGFydCxscEZvcm1hdCwgJnNpemUpKSkgewoJaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CgkgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gbHBGb3JtYXQ7CgkgIElDSU5GTyBpY2luZm87CgoJICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6VmlkZW9GbXQsIGxwYmktPmJpV2lkdGgsCgkJICAgIGxwYmktPmJpSGVpZ2h0LCBscGJpLT5iaUJpdENvdW50KTsKCgkgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQikgewoJICAgIEhJQyAgICBoaWM7CgoJICAgIGhpYyA9IElDTG9jYXRlKElDVFlQRV9WSURFTywgc0luZm8uZmNjSGFuZGxlciwgbHBGb3JtYXQsCgkJCSAgIE5VTEwsIElDTU9ERV9ERUNPTVBSRVNTKTsKCSAgICBpZiAoaGljICE9IE5VTEwpIHsKCSAgICAgIGlmIChJQ0dldEluZm8oaGljLCAmaWNpbmZvLCBzaXplb2YoaWNpbmZvKSkgPT0gU19PSykKCQlsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICAgICAgSUNDbG9zZShoaWMpOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19VTkNPTVBSRVNTRUQsCgkJCWljaW5mby5zekRlc2NyaXB0aW9uLCBzaXplb2YoaWNpbmZvLnN6RGVzY3JpcHRpb24pKTsKCSAgICBsc3RyY2F0VyhzekZvcm1hdCwgaWNpbmZvLnN6RGVzY3JpcHRpb24pOwoJICB9Cgl9IGVsc2UgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CgkgIEFDTUZPUk1BVFRBR0RFVEFJTFNXIGFmdGQ7CgkgIEFDTUZPUk1BVERFVEFJTFNXICAgIGFmZDsKCgkgIG1lbXNldCgmYWZ0ZCwgMCwgc2l6ZW9mKGFmdGQpKTsKCSAgbWVtc2V0KCZhZmQsIDAsIHNpemVvZihhZmQpKTsKCgkgIGFmdGQuY2JTdHJ1Y3QgICAgID0gc2l6ZW9mKGFmdGQpOwoJICBhZnRkLmR3Rm9ybWF0VGFnICA9IGFmZC5kd0Zvcm1hdFRhZyA9CgkgICAgKChQV0FWRUZPUk1BVEVYKWxwRm9ybWF0KS0+d0Zvcm1hdFRhZzsKCSAgYWZ0ZC5jYkZvcm1hdFNpemUgPSBhZmQuY2J3ZnggPSBzaXplOwoKCSAgYWZkLmNiU3RydWN0ICAgICAgPSBzaXplb2YoYWZkKTsKCSAgYWZkLnB3ZnggICAgICAgICAgPSBscEZvcm1hdDsKCgkgIGlmIChhY21Gb3JtYXRUYWdEZXRhaWxzVyhOVUxMLCAmYWZ0ZCwKCQkJCSAgIEFDTV9GT1JNQVRUQUdERVRBSUxTRl9GT1JNQVRUQUcpID09IFNfT0spIHsKCSAgICBpZiAoYWNtRm9ybWF0RGV0YWlsc1coTlVMTCwmYWZkLEFDTV9GT1JNQVRERVRBSUxTRl9GT1JNQVQpID09IFNfT0spCgkgICAgICB3c3ByaW50Zlcoc3pGb3JtYXQsIHN6QXVkaW9GbXQsIGFmZC5zekZvcm1hdCwgYWZ0ZC5zekZvcm1hdFRhZyk7CgkgIH0KCX0KICAgICAgfQogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEZvcm1hdCk7CiAgICB9CgogICAgLyogc2V0IHRleHQgZm9yIGZvcm1hdCBkZXNjcmlwdGlvbiAqLwogICAgU2V0RGxnSXRlbVRleHRXKGhXbmQsIElEQ19GT1JNQVRURVhULCBzekZvcm1hdCk7CgogICAgLyogRGlzYWJsZSBvcHRpb24gYnV0dG9uIGZvciB1bnN1cHBvcnRlZCBzdHJlYW10eXBlcyAqLwogICAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPIHx8CglzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBUUlVFKTsKICAgIGVsc2UKICAgICAgRW5hYmxlV2luZG93KEdldERsZ0l0ZW0oaFduZCwgSURDX09QVElPTlMpLCBGQUxTRSk7CiAgfQoKfQoKc3RhdGljIElOVF9QVFIgQ0FMTEJBQ0sgQVZJU2F2ZU9wdGlvbnNEbGdQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogIERXT1JEIGR3SW50ZXJsZWF2ZTsKICBCT09MICBiSXNJbnRlcmxlYXZlZDsKICBJTlQgICBuOwoKICAvKlRSQUNFKCIoJXAsJXUsMHglMDRYLDB4JTA4bFgpXG4iLCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7Ki8KCiAgc3dpdGNoICh1TXNnKSB7CiAgY2FzZSBXTV9JTklURElBTE9HOgogICAgU2F2ZU9wdHMubkN1cnJlbnQgPSAwOwogICAgaWYgKFNhdmVPcHRzLm5TdHJlYW1zID09IDEpIHsKICAgICAgRW5kRGlhbG9nKGhXbmQsIEFWSVNhdmVPcHRpb25zRm10Q2hvb3NlKGhXbmQpKTsKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLyogYWRkIHN0cmVhbXMgKi8KICAgIGZvciAobiA9IDA7IG4gPCBTYXZlT3B0cy5uU3RyZWFtczsgbisrKSB7CiAgICAgIEFWSVNUUkVBTUlORk9XIHNJbmZvOwoKICAgICAgQVZJU3RyZWFtSW5mb1coU2F2ZU9wdHMucHBhdmlzW25dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgICBTZW5kRGxnSXRlbU1lc3NhZ2VXKGhXbmQsIElEQ19TVFJFQU0sIENCX0FERFNUUklORywKCQkJICAwTCwgKExQQVJBTSlzSW5mby5zek5hbWUpOwogICAgfQoKICAgIC8qIHNlbGVjdCBmaXJzdCBzdHJlYW0gKi8KICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfU0VUQ1VSU0VMLCAwLCAwKTsKICAgIFNlbmRNZXNzYWdlVyhoV25kLCBXTV9DT01NQU5ELCBNQUtFTE9ORyhJRENfU1RSRUFNLCBDQk5fU0VMQ0hBTkdFKSwgKExQQVJBTSloV25kKTsKCiAgICAvKiBpbml0aWFsaXplIGludGVybGVhdmUgKi8KICAgIGlmIChTYXZlT3B0cy5wcE9wdGlvbnNbMF0gIT0gTlVMTCAmJgoJKFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9WQUxJRCkpIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSAoU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkUpOwogICAgICBkd0ludGVybGVhdmUgPSBTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3SW50ZXJsZWF2ZUV2ZXJ5OwogICAgfSBlbHNlIHsKICAgICAgYklzSW50ZXJsZWF2ZWQgPSBUUlVFOwogICAgICBkd0ludGVybGVhdmUgICA9IDA7CiAgICB9CiAgICBDaGVja0RsZ0J1dHRvbihoV25kLCBJRENfSU5URVJMRUFWRSwgYklzSW50ZXJsZWF2ZWQpOwogICAgU2V0RGxnSXRlbUludChoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZLCBkd0ludGVybGVhdmUsIEZBTFNFKTsKICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlkpLCBiSXNJbnRlcmxlYXZlZCk7CiAgICBicmVhazsKICBjYXNlIFdNX0NPTU1BTkQ6CiAgICBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKSB7CiAgICBjYXNlIElET0s6CiAgICAgIC8qIGdldCBkYXRhIGZyb20gY29udHJvbHMgYW5kIHNhdmUgdGhlbSAqLwogICAgICBkd0ludGVybGVhdmUgICA9IEdldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgTlVMTCwgMCk7CiAgICAgIGJJc0ludGVybGVhdmVkID0gSXNEbGdCdXR0b25DaGVja2VkKGhXbmQsIElEQ19JTlRFUkxFQVZFKTsKICAgICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKCWlmIChTYXZlT3B0cy5wcE9wdGlvbnNbbl0gIT0gTlVMTCkgewoJICBpZiAoYklzSW50ZXJsZWF2ZWQpIHsKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ludGVybGVhdmVFdmVyeSA9IGR3SW50ZXJsZWF2ZTsKCSAgfSBlbHNlCgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfSU5URVJMRUFWRTsKCX0KICAgICAgfQogICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgSURDQU5DRUw6CiAgICAgIEVuZERpYWxvZyhoV25kLCBMT1dPUkQod1BhcmFtKSA9PSBJRE9LKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19JTlRFUkxFQVZFOgogICAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwKCQkgICBJc0RsZ0J1dHRvbkNoZWNrZWQoaFduZCwgSURDX0lOVEVSTEVBVkUpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19TVFJFQU06CiAgICAgIGlmIChISVdPUkQod1BhcmFtKSA9PSBDQk5fU0VMQ0hBTkdFKSB7CgkvKiB1cGRhdGUgY29udHJvbCBlbGVtZW50cyAqLwoJQVZJU2F2ZU9wdGlvbnNVcGRhdGUoaFduZCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIElEQ19PUFRJT05TOgogICAgICBBVklTYXZlT3B0aW9uc0ZtdENob29zZShoV25kKTsKICAgICAgYnJlYWs7CiAgICB9OwogICAgcmV0dXJuIFRSVUU7CiAgfTsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zCQkoQVZJRklMMzIuQCkKICovCkJPT0wgV0lOQVBJIEFWSVNhdmVPcHRpb25zKEhXTkQgaFduZCwgVUlOVCB1RmxhZ3MsIElOVCBuU3RyZWFtcywKCQkJICAgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwcE9wdGlvbnMpCnsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBwU2F2ZWRPcHRpb25zID0gTlVMTDsKICBJTlQgcmV0LCBuOwoKICBUUkFDRSgiKCVwLDB4JVgsJWQsJXAsJXApXG4iLCBoV25kLCB1RmxhZ3MsIG5TdHJlYW1zLAoJcHBhdmksIHBwT3B0aW9ucyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoblN0cmVhbXMgPD0gMCB8fCBwcGF2aSA9PSBOVUxMIHx8IHBwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogc2F2ZSBvcHRpb25zIGluIGNhc2UgdGhlIHVzZXIgcHJlc3NlcyBjYW5jZWwgKi8KICBpZiAocHBPcHRpb25zICE9IE5VTEwgJiYgblN0cmVhbXMgPiAxKSB7CiAgICBwU2F2ZWRPcHRpb25zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG5TdHJlYW1zICogc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgaWYgKHBTYXZlZE9wdGlvbnMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CiAgICAgIGlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCW1lbWNweShwU2F2ZWRPcHRpb25zICsgbiwgcHBPcHRpb25zW25dLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICB9CiAgfQoKICBTYXZlT3B0cy51RmxhZ3MgICAgPSB1RmxhZ3M7CiAgU2F2ZU9wdHMublN0cmVhbXMgID0gblN0cmVhbXM7CiAgU2F2ZU9wdHMucHBhdmlzICAgID0gcHBhdmk7CiAgU2F2ZU9wdHMucHBPcHRpb25zID0gcHBPcHRpb25zOwoKICByZXQgPSBEaWFsb2dCb3hXKEFWSUZJTEVfaE1vZHVsZSwgTUFLRUlOVFJFU09VUkNFVyhJRERfU0FWRU9QVElPTlMpLAoJCSAgIGhXbmQsIEFWSVNhdmVPcHRpb25zRGxnUHJvYyk7CgogIGlmIChyZXQgPT0gLTEpCiAgICByZXQgPSBGQUxTRTsKCiAgLyogcmVzdG9yZSBvcHRpb25zIHdoZW4gdXNlciBwcmVzc2VkIGNhbmNlbCAqLwogIGlmIChwU2F2ZWRPcHRpb25zICE9IE5VTEwpIHsKICAgIGlmIChyZXQgPT0gRkFMU0UpIHsKICAgICAgZm9yIChuID0gMDsgbiA8IG5TdHJlYW1zOyBuKyspIHsKCWlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCSAgbWVtY3B5KHBwT3B0aW9uc1tuXSwgcFNhdmVkT3B0aW9ucyArIG4sIHNpemVvZihBVklDT01QUkVTU09QVElPTlMpKTsKICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcFNhdmVkT3B0aW9ucyk7CiAgfQoKICByZXR1cm4gKEJPT0wpcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMMzIuQCkKICoJCUFWSVNhdmVPcHRpb25zRnJlZQkoQVZJRklMRS4xMjQpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlT3B0aW9uc0ZyZWUoSU5UIG5TdHJlYW1zLExQQVZJQ09NUFJFU1NPUFRJT05TKnBwT3B0aW9ucykKewogIFRSQUNFKCIoJWQsJXApXG4iLCBuU3RyZWFtcywgcHBPcHRpb25zKTsKCiAgaWYgKG5TdHJlYW1zIDwgMCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBuU3RyZWFtcyA+IDA7IG5TdHJlYW1zLS0pIHsKICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdICE9IE5VTEwpIHsKICAgICAgcHBPcHRpb25zW25TdHJlYW1zXS0+ZHdGbGFncyAmPSB+QVZJQ09NUFJFU1NGX1ZBTElEOwoKICAgICAgaWYgKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwUGFybXMgIT0gTlVMTCkgewoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyk7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zID0gTlVMTDsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmNiUGFybXMgPSAwOwogICAgICB9CiAgICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCAhPSBOVUxMKSB7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCk7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCA9IE5VTEw7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5jYkZvcm1hdCA9IDA7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZVZBCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVNhdmVWQShMUENTVFIgc3pGaWxlLCBDTFNJRCAqcGNsc2lkSGFuZGxlciwKCQkJIEFWSVNBVkVDQUxMQkFDSyBscGZuQ2FsbGJhY2ssIGludCBuU3RyZWFtLAoJCQkgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwbHBPcHRpb25zKQp7CiAgTFBXU1RSICB3c3pGaWxlID0gTlVMTDsKICBIUkVTVUxUIGhyOwogIGludCAgICAgbGVuOwoKICBUUkFDRSgiJXMsJXAsJXAsJWQsJXAsJXApXG4iLCBkZWJ1Z3N0cl9hKHN6RmlsZSksIHBjbHNpZEhhbmRsZXIsCglscGZuQ2FsbGJhY2ssIG5TdHJlYW0sIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgaWYgKHN6RmlsZSA9PSBOVUxMIHx8IHBwYXZpID09IE5VTEwgfHwgcGxwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY29udmVydCBBU0NJSSBzdHJpbmcgdG8gVW5pY29kZSBhbmQgY2FsbCBVbmljb2RlIGZ1bmN0aW9uICovCiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIE5VTEwsIDApOwogIGlmIChsZW4gPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIHdzekZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKHdzekZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3pGaWxlLCAtMSwgd3N6RmlsZSwgbGVuKTsKCiAgaHIgPSBBVklTYXZlVlcod3N6RmlsZSwgcGNsc2lkSGFuZGxlciwgbHBmbkNhbGxiYWNrLAoJCSBuU3RyZWFtLCBwcGF2aSwgcGxwT3B0aW9ucyk7CgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdzekZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRklMRV9BVklTYXZlRGVmYXVsdENhbGxiYWNrCShpbnRlcm5hbCkKICovCnN0YXRpYyBCT09MIFdJTkFQSSBBVklGSUxFX0FWSVNhdmVEZWZhdWx0Q2FsbGJhY2soSU5UIHByb2dyZXNzKQp7CiAgVFJBQ0UoIiglZClcbiIsIHByb2dyZXNzKTsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVNhdmVWVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTYXZlVlcoTFBDV1NUUiBzekZpbGUsIENMU0lEICpwY2xzaWRIYW5kbGVyLAoJCQkgQVZJU0FWRUNBTExCQUNLIGxwZm5DYWxsYmFjaywgaW50IG5TdHJlYW1zLAoJCQkgUEFWSVNUUkVBTSAqcHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TICpwbHBPcHRpb25zKQp7CiAgTE9ORyAgICAgICAgICAgbFN0YXJ0W01BWF9BVklTVFJFQU1TXTsKICBQQVZJU1RSRUFNICAgICBwT3V0U3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CiAgUEFWSVNUUkVBTSAgICAgcEluU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CiAgQVZJRklMRUlORk9XICAgZkluZm87CiAgQVZJU1RSRUFNSU5GT1cgc0luZm87CgogIFBBVklGSUxFICAgICAgIHBmaWxlID0gTlVMTDsgLyogdGhlIG91dHB1dCBBVkkgZmlsZSAqLwogIExPTkcgICAgICAgICAgIGxGaXJzdFZpZGVvID0gLTE7CiAgaW50ICAgICAgICAgICAgY3VyU3RyZWFtOwoKICAvKiBmb3IgaW50ZXJsZWF2aW5nIC4uLiAqLwogIERXT1JEICAgICAgICAgIGR3SW50ZXJsZWF2ZSA9IDA7IC8qIGludGVybGVhdmUgcmF0ZSAqLwogIERXT1JEICAgICAgICAgIGR3RmlsZUluaXRpYWxGcmFtZXM7CiAgTE9ORyAgICAgICAgICAgbEZpbGVMZW5ndGg7CiAgTE9ORyAgICAgICAgICAgbFNhbXBsZUluYzsKCiAgLyogZm9yIHJlYWRpbmcvd3JpdGluZyB0aGUgZGF0YSAuLi4gKi8KICBMUFZPSUQgICAgICAgICBscEJ1ZmZlciA9IE5VTEw7CiAgTE9ORyAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgICAvKiByZWFsIHNpemUgb2YgbHBCdWZmZXIgKi8KICBMT05HICAgICAgICAgICBsQnVmZmVyU2l6ZTsgICAgIC8qIG5lZWRlZCBieXRlcyBmb3IgZm9ybWF0KHMpLCBldGMuICovCiAgTE9ORyAgICAgICAgICAgbFJlYWRCeXRlczsKICBMT05HICAgICAgICAgICBsUmVhZFNhbXBsZXM7CiAgSFJFU1VMVCAgICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcywlcCwlcCwlZCwlcCwlcClcbiIsIGRlYnVnc3RyX3coc3pGaWxlKSwgcGNsc2lkSGFuZGxlciwKCWxwZm5DYWxsYmFjaywgblN0cmVhbXMsIHBwYXZpLCBwbHBPcHRpb25zKTsKCiAgaWYgKHN6RmlsZSA9PSBOVUxMIHx8IHBwYXZpID09IE5VTEwgfHwgcGxwT3B0aW9ucyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoblN0cmVhbXMgPj0gTUFYX0FWSVNUUkVBTVMpIHsKICAgIFdBUk4oIkNhbid0IHdyaXRlIEFWSSB3aXRoICVkIHN0cmVhbXMgb25seSBzdXBwb3J0cyAlZCAtLSBjaGFuZ2UgTUFYX0FWSVNUUkVBTVMhXG4iLCBuU3RyZWFtcywgTUFYX0FWSVNUUkVBTVMpOwogICAgcmV0dXJuIEFWSUVSUl9JTlRFUk5BTDsKICB9CgogIGlmIChscGZuQ2FsbGJhY2sgPT0gTlVMTCkKICAgIGxwZm5DYWxsYmFjayA9IEFWSUZJTEVfQVZJU2F2ZURlZmF1bHRDYWxsYmFjazsKCiAgLyogY2xlYXIgbG9jYWwgdmFyaWFibGUocykgKi8KICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgcEluU3RyZWFtc1tjdXJTdHJlYW1dICA9IE5VTEw7CiAgICBwT3V0U3RyZWFtc1tjdXJTdHJlYW1dID0gTlVMTDsKICB9CgogIC8qIG9wZW4gb3V0cHV0IEFWSSBmaWxlIChjcmVhdGUgaXQgaWYgaXQgZG9lc24ndCBleGlzdCkgKi8KICBocmVzID0gQVZJRmlsZU9wZW5XKCZwZmlsZSwgc3pGaWxlLCBPRl9DUkVBVEV8T0ZfU0hBUkVfRVhDTFVTSVZFfE9GX1dSSVRFLAoJCSAgICAgIHBjbHNpZEhhbmRsZXIpOwogIGlmIChGQUlMRUQoaHJlcykpCiAgICByZXR1cm4gaHJlczsKICBBVklGaWxlSW5mb1cocGZpbGUsICZmSW5mbywgc2l6ZW9mKGZJbmZvKSk7IC8qIGZvciBkd0NhcHMgKi8KCiAgLyogaW5pdGlhbGl6ZSBvdXIgZGF0YSBzdHJ1Y3R1cmVzIHBhcnQgMSAqLwogIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICBQQVZJU1RSRUFNIHBDdXJTdHJlYW0gPSBwcGF2aVtjdXJTdHJlYW1dOwoKICAgIGhyZXMgPSBBVklTdHJlYW1JbmZvVyhwQ3VyU3RyZWFtLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgaWYgKEZBSUxFRChocmVzKSkKICAgICAgZ290byBlcnJvcjsKCiAgICAvKiBzZWFyY2ggZmlyc3QgdmlkZW8gc3RyZWFtIGFuZCBjaGVjayBmb3IgaW50ZXJsZWF2aW5nICovCiAgICBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgLyogcmVtZW1iZXIgZmlyc3QgdmlkZW8gc3RyZWFtIC0tIG5lZWRlZCBmb3IgaW50ZXJsZWF2aW5nICovCiAgICAgIGlmIChsRmlyc3RWaWRlbyA8IDApCglsRmlyc3RWaWRlbyA9IGN1clN0cmVhbTsKICAgIH0gZWxzZSBpZiAoIWR3SW50ZXJsZWF2ZSAmJiBwbHBPcHRpb25zICE9IE5VTEwpIHsKICAgICAgLyogY2hlY2sgaWYgYW55IG5vbi12aWRlbyBzdHJlYW0gd2FudHMgdG8gYmUgaW50ZXJsZWF2ZWQgKi8KICAgICAgV0FSTigib3B0aW9ucy5mbGFncz0weCVYIG9wdGlvbnMuZHdJbnRlcmxlYXZlPSV1XG4iLHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdGbGFncyxwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3SW50ZXJsZWF2ZUV2ZXJ5KTsKICAgICAgaWYgKHBscE9wdGlvbnNbY3VyU3RyZWFtXSAhPSBOVUxMICYmCgkgIHBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFKQoJZHdJbnRlcmxlYXZlID0gcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5kd0ludGVybGVhdmVFdmVyeTsKICAgIH0KCiAgICAvKiBjcmVhdGUgZGUtL2NvbXByZXNzZWQgc3RyZWFtIGludGVyZmFjZSBpZiBuZWVkZWQgKi8KICAgIHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IE5VTEw7CiAgICBpZiAocGxwT3B0aW9ucyAhPSBOVUxMICYmIHBscE9wdGlvbnNbY3VyU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAgIGlmIChwbHBPcHRpb25zW2N1clN0cmVhbV0tPmZjY0hhbmRsZXIgfHwKCSAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLT5scEZvcm1hdCAhPSBOVUxMKSB7CglEV09SRCBkd0tleVNhdmUgPSBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3S2V5RnJhbWVFdmVyeTsKCglpZiAoZkluZm8uZHdDYXBzICYgQVZJRklMRUNBUFNfQUxMS0VZRlJBTUVTKQoJICBwbHBPcHRpb25zW2N1clN0cmVhbV0tPmR3S2V5RnJhbWVFdmVyeSA9IDE7CgoJaHJlcyA9IEFWSU1ha2VDb21wcmVzc2VkU3RyZWFtKCZwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHBDdXJTdHJlYW0sCgkJCQkgICAgICAgcGxwT3B0aW9uc1tjdXJTdHJlYW1dLCBOVUxMKTsKCXBscE9wdGlvbnNbY3VyU3RyZWFtXS0+ZHdLZXlGcmFtZUV2ZXJ5ID0gZHdLZXlTYXZlOwoJaWYgKEZBSUxFRChocmVzKSB8fCBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPT0gTlVMTCkgewoJICBwSW5TdHJlYW1zW2N1clN0cmVhbV0gPSBOVUxMOwoJICBnb3RvIGVycm9yOwoJfQoKCS8qIHRlc3Qgc3RyZWFtIGludGVyZmFjZSBhbmQgdXBkYXRlIHN0cmVhbS1pbmZvICovCglocmVzID0gQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgZ290byBlcnJvcjsKICAgICAgfQogICAgfQoKICAgIC8qIG5vdyBoYW5kbGUgc3RyZWFtcyB3aGljaCB3aWxsIG9ubHkgYmUgY29waWVkICovCiAgICBpZiAocEluU3RyZWFtc1tjdXJTdHJlYW1dID09IE5VTEwpIHsKICAgICAgcEN1clN0cmVhbSA9IHBJblN0cmVhbXNbY3VyU3RyZWFtXSA9IHBwYXZpW2N1clN0cmVhbV07CiAgICAgIEFWSVN0cmVhbUFkZFJlZihwQ3VyU3RyZWFtKTsKICAgIH0gZWxzZQogICAgICBwQ3VyU3RyZWFtID0gcEluU3RyZWFtc1tjdXJTdHJlYW1dOwoKICAgIGxTdGFydFtjdXJTdHJlYW1dID0gc0luZm8uZHdTdGFydDsKICB9IC8qIGZvciBhbGwgc3RyZWFtcyAqLwoKICAvKiBjaGVjayB0aGF0IGZpcnN0IHZpZGVvIHN0cmVhbSBpcyB0aGUgZmlyc3Qgc3RyZWFtICovCiAgaWYgKGxGaXJzdFZpZGVvID4gMCkgewogICAgUEFWSVNUUkVBTSBwVG1wID0gcEluU3RyZWFtc1tsRmlyc3RWaWRlb107CiAgICBMT05HIGxUbXAgPSBsU3RhcnRbbEZpcnN0VmlkZW9dOwoKICAgIHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dID0gcEluU3RyZWFtc1swXTsKICAgIHBJblN0cmVhbXNbMF0gPSBwVG1wOwogICAgbFN0YXJ0W2xGaXJzdFZpZGVvXSA9IGxTdGFydFswXTsKICAgIGxTdGFydFswXSA9IGxUbXA7CiAgICBsRmlyc3RWaWRlbyA9IDA7CiAgfQoKICAvKiBhbGxvY2F0ZSBidWZmZXIgZm9yIGZvcm1hdHMsIGRhdGEsIGV0Yy4gb2YgYW4gaW5pdGlhbCBzaXplIG9mIDY0IGtCeXRlcyovCiAgY2JCdWZmZXIgPSAweDAwMDEwMDAwOwogIGxwQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNiQnVmZmVyKTsKICBpZiAobHBCdWZmZXIgPT0gTlVMTCkgewogICAgaHJlcyA9IEFWSUVSUl9NRU1PUlk7CiAgICBnb3RvIGVycm9yOwogIH0KCiAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1swXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKICBsRmlsZUxlbmd0aCA9IHNJbmZvLmR3TGVuZ3RoOwogIGR3RmlsZUluaXRpYWxGcmFtZXMgPSAwOwogIGlmIChsRmlyc3RWaWRlbyA+PSAwKSB7CiAgICAvKiBjaGVjayBmb3IgY29ycmVjdCB2ZXJzaW9uIG9mIHRoZSBmb3JtYXQKICAgICAqICAtLSBuZWVkIGF0IGxlYXN0IEJJVE1BUElORk9IRUFERVIgb3IgbmV3ZXIKICAgICAqLwogICAgbFNhbXBsZUluYyA9IDE7CiAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tsRmlyc3RWaWRlb10sIEFWSVN0cmVhbVN0YXJ0KHBJblN0cmVhbXNbbEZpcnN0VmlkZW9dKSwgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CiAgICBpZiAobEJ1ZmZlclNpemUgPCAoTE9ORylzaXplb2YoQklUTUFQSU5GT0hFQURFUikpCiAgICAgIGhyZXMgPSBBVklFUlJfSU5URVJOQUw7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICBnb3RvIGVycm9yOwogIH0gZWxzZSAvKiB1c2Ugb25lIHNlY29uZCBibG9ja3MgZm9yIGludGVybGVhdmluZyBpZiBubyB2aWRlbyBwcmVzZW50ICovCiAgICBsU2FtcGxlSW5jID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKHBJblN0cmVhbXNbMF0sIDEwMDAwMDApOwoKICAvKiBjcmVhdGUgb3V0cHV0IHN0cmVhbXMgKi8KICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewogICAgQVZJU3RyZWFtSW5mb1cocEluU3RyZWFtc1tjdXJTdHJlYW1dLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwoKICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyA9IDA7CiAgICBpZiAoZHdJbnRlcmxlYXZlICE9IDAgJiYgY3VyU3RyZWFtID4gMCAmJiBzSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVWSURFTykgewogICAgICAvKiA3NTAgbXMgaW5pdGlhbCBmcmFtZXMgZm9yIG5vbi12aWRlbyBzdHJlYW1zICovCiAgICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyA9IEFWSVN0cmVhbVRpbWVUb1NhbXBsZShwSW5TdHJlYW1zWzBdLCA3NTApOwogICAgfQoKICAgIGhyZXMgPSBBVklGaWxlQ3JlYXRlU3RyZWFtVyhwZmlsZSwgJnBPdXRTdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbyk7CiAgICBpZiAocE91dFN0cmVhbXNbY3VyU3RyZWFtXSAhPSBOVUxMICYmIFNVQ0NFRURFRChocmVzKSkgewogICAgICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IGZvciB0aGlzIHN0cmVhbSAqLwogICAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgICBocmVzID0gQVZJU3RyZWFtUmVhZEZvcm1hdChwSW5TdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCQkgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHJlcykpCglnb3RvIGVycm9yOwogICAgICBocmVzID0gQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIDAsIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHJlcykpCglnb3RvIGVycm9yOwoKICAgICAgLyogdHJ5IHRvIGNvcHkgc3RyZWFtIGhhbmRsZXIgZGF0YSAqLwogICAgICBsQnVmZmVyU2l6ZSA9IGNiQnVmZmVyOwogICAgICBocmVzID0gQVZJU3RyZWFtUmVhZERhdGEocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBja2lkU1RSRUFNSEFORExFUkRBVEEsCgkJCSAgICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKICAgICAgaWYgKFNVQ0NFRURFRChocmVzKSAmJiBsQnVmZmVyU2l6ZSA+IDApIHsKCWhyZXMgPSBBVklTdHJlYW1Xcml0ZURhdGEocE91dFN0cmVhbXNbY3VyU3RyZWFtXSxja2lkU1RSRUFNSEFORExFUkRBVEEsCgkJCQkgIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CglpZiAoRkFJTEVEKGhyZXMpKQoJICBnb3RvIGVycm9yOwogICAgICB9CgogICAgICBpZiAoZHdGaWxlSW5pdGlhbEZyYW1lcyA8IHNJbmZvLmR3SW5pdGlhbEZyYW1lcykKCWR3RmlsZUluaXRpYWxGcmFtZXMgPSBzSW5mby5kd0luaXRpYWxGcmFtZXM7CiAgICAgIGxSZWFkQnl0ZXMgPQoJQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUocE91dFN0cmVhbXNbMF0sIHBJblN0cmVhbXNbY3VyU3RyZWFtXSwKCQkJCXNJbmZvLmR3TGVuZ3RoKTsKICAgICAgaWYgKGxGaWxlTGVuZ3RoIDwgbFJlYWRCeXRlcykKCWxGaWxlTGVuZ3RoID0gbFJlYWRCeXRlczsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNyZWF0aW9uIG9mIGRlLS9jb21wcmVzc2lvbiBzdHJlYW0gaW50ZXJmYWNlIGZhaWxlZCAqLwogICAgICBXQVJOKCJjcmVhdGlvbiBvZiAoZGUtKWNvbXByZXNzaW9uIHN0cmVhbSBmYWlsZWQgZm9yIHN0cmVhbSAlZFxuIixjdXJTdHJlYW0pOwogICAgICBBVklTdHJlYW1SZWxlYXNlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CiAgICAgIGlmIChjdXJTdHJlYW0gKyAxID49IG5TdHJlYW1zKSB7CgkvKiBtb3ZlIHRoZSBvdGhlcnMgb25lIHVwICovCglQQVZJU1RSRUFNICpwcGFzID0gJnBJblN0cmVhbXNbY3VyU3RyZWFtXTsKCWludCAgICAgICAgICAgIG4gPSBuU3RyZWFtcyAtIChjdXJTdHJlYW0gKyAxKTsKCglkbyB7CgkgICpwcGFzID0gcEluU3RyZWFtc1tjdXJTdHJlYW0gKyAxXTsKCX0gd2hpbGUgKC0tbik7CiAgICAgIH0KICAgICAgblN0cmVhbXMtLTsKICAgICAgY3VyU3RyZWFtLS07CiAgICB9CiAgfSAvKiBjcmVhdGUgb3V0cHV0IHN0cmVhbXMgZm9yIGFsbCBpbnB1dCBzdHJlYW1zICovCgogIC8qIGhhdmUgd2Ugc3RpbGwgc29tZXRoaW5nIHRvIHdyaXRlLCBvciBsb3N0IGV2ZXJ5dGhpbmc/ICovCiAgaWYgKG5TdHJlYW1zIDw9IDApCiAgICBnb3RvIGVycm9yOwoKICBpZiAoZHdJbnRlcmxlYXZlKSB7CiAgICBMT05HIGxDdXJGcmFtZSA9IC1kd0ZpbGVJbml0aWFsRnJhbWVzOwoKICAgIC8qIGludGVybGVhdmVkIGZpbGUgKi8KICAgIGlmIChkd0ludGVybGVhdmUgPT0gMSkKICAgICAgQVZJRmlsZUVuZFJlY29yZChwZmlsZSk7CgogICAgZm9yICg7IGxDdXJGcmFtZSA8IGxGaWxlTGVuZ3RoOyBsQ3VyRnJhbWUgKz0gbFNhbXBsZUluYykgewogICAgICBmb3IgKGN1clN0cmVhbSA9IDA7IGN1clN0cmVhbSA8IG5TdHJlYW1zOyBjdXJTdHJlYW0rKykgewoJTE9ORyBsTGFzdFNhbXBsZTsKCglocmVzID0gQVZJU3RyZWFtSW5mb1cocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCWlmIChGQUlMRUQoaHJlcykpCgkgIGdvdG8gZXJyb3I7CgoJLyogaW5pdGlhbCBmcmFtZXMgcGhhc2UgYXQgdGhlIGVuZCBmb3IgdGhpcyBzdHJlYW0/ICovCglpZiAoLShMT05HKXNJbmZvLmR3SW5pdGlhbEZyYW1lcyA+IGxDdXJGcmFtZSkKCSAgY29udGludWU7CgoJaWYgKChsRmlsZUxlbmd0aCAtIGxTYW1wbGVJbmMpIDw9IGxDdXJGcmFtZSkgewoJICBsTGFzdFNhbXBsZSA9IEFWSVN0cmVhbUxlbmd0aChwSW5TdHJlYW1zW2N1clN0cmVhbV0pOwoJICBsRmlyc3RWaWRlbyA9IGxMYXN0U2FtcGxlICsgQVZJU3RyZWFtU3RhcnQocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKCX0gZWxzZSB7CgkgIGlmIChjdXJTdHJlYW0gIT0gMCkgewoJICAgIGxGaXJzdFZpZGVvID0KCSAgICAgIEFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgcEluU3RyZWFtc1swXSwKCQkJCSAgICAgIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTyA/IAoJCQkJICAgICAgIChMT05HKWR3SW50ZXJsZWF2ZSA6IGxTYW1wbGVJbmMpICsKCQkJCSAgICAgIHNJbmZvLmR3SW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSk7CgkgIH0gZWxzZQoJICAgIGxGaXJzdFZpZGVvID0gbFNhbXBsZUluYyArIChzSW5mby5kd0luaXRpYWxGcmFtZXMgKyBsQ3VyRnJhbWUpOwoKCSAgbExhc3RTYW1wbGUgPSBBVklTdHJlYW1FbmQocEluU3RyZWFtc1tjdXJTdHJlYW1dKTsKCSAgaWYgKGxMYXN0U2FtcGxlIDw9IGxGaXJzdFZpZGVvKQoJICAgIGxGaXJzdFZpZGVvID0gbExhc3RTYW1wbGU7Cgl9CgoJLyogY29weSBuZWVkZWQgc2FtcGxlcyBub3cgKi8KCVdBUk4oImNvcHkgZnJvbSBzdHJlYW0gJWQgc2FtcGxlcyAlZCB0byAlZC4uLlxuIixjdXJTdHJlYW0sCgkgICAgICBsU3RhcnRbY3VyU3RyZWFtXSxsRmlyc3RWaWRlbyk7Cgl3aGlsZSAobEZpcnN0VmlkZW8gPiBsU3RhcnRbY3VyU3RyZWFtXSkgewoJICBEV09SRCBmbGFncyA9IDA7CgoJICAvKiBjb3B5IGZvcm1hdCBpbiBjYXNlIGl0IGNhbiBjaGFuZ2UgKi8KCSAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKCSAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBsU3RhcnRbY3VyU3RyZWFtXSwKCQkJCSAgICAgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIGxTdGFydFtjdXJTdHJlYW1dLAoJCQkgICAgIGxwQnVmZmVyLCBsQnVmZmVyU2l6ZSk7CgoJICAvKiB0cnkgdG8gcmVhZCBkYXRhIHVudGlsIHdlIGdvdCBpdCwgb3IgZXJyb3IgKi8KCSAgZG8gewoJICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgbFN0YXJ0W2N1clN0cmVhbV0sCgkJCQkgbEZpcnN0VmlkZW8gLSBsU3RhcnRbY3VyU3RyZWFtXSwgbHBCdWZmZXIsCgkJCQkgY2JCdWZmZXIsICZsUmVhZEJ5dGVzLCAmbFJlYWRTYW1wbGVzKTsKCSAgfSB3aGlsZSAoKGhyZXMgPT0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMKSAmJgoJCSAgIChscEJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICBpZiAoQVZJU3RyZWFtSXNLZXlGcmFtZShwSW5TdHJlYW1zW2N1clN0cmVhbV0sIChMT05HKXNJbmZvLmR3U3RhcnQpKQoJICAgIGZsYWdzID0gQVZJSUZfS0VZRlJBTUU7CgkgIGhyZXMgPSBBVklTdHJlYW1Xcml0ZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAtMSwgbFJlYWRTYW1wbGVzLAoJCQkJbHBCdWZmZXIsIGxSZWFkQnl0ZXMsIGZsYWdzLCBOVUxMLCBOVUxMKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoKCSAgbFN0YXJ0W2N1clN0cmVhbV0gKz0gbFJlYWRTYW1wbGVzOwoJfQoJbFN0YXJ0W2N1clN0cmVhbV0gPSBsRmlyc3RWaWRlbzsKICAgICAgfSAvKiBzdHJlYW0gYnkgc3RyZWFtICovCgogICAgICAvKiBuZWVkIHRvIGNsb3NlIHRoaXMgYmxvY2s/ICovCiAgICAgIGlmIChkd0ludGVybGVhdmUgPT0gMSkgewoJaHJlcyA9IEFWSUZpbGVFbmRSZWNvcmQocGZpbGUpOwoJaWYgKEZBSUxFRChocmVzKSkKCSAgYnJlYWs7CiAgICAgIH0KCiAgICAgIC8qIHNob3cgcHJvZ3Jlc3MgKi8KICAgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoZHdGaWxlSW5pdGlhbEZyYW1lcyArIGxDdXJGcmFtZSwgMTAwLAoJCQkgICAgICBkd0ZpbGVJbml0aWFsRnJhbWVzICsgbEZpbGVMZW5ndGgpKSkgewoJaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CglicmVhazsKICAgICAgfQogICAgfSAvKiBjb3B5IGZyYW1lIGJ5IGZyYW1lICovCiAgfSBlbHNlIHsKICAgIC8qIG5vbi1pbnRlcmxlYXZlZCBmaWxlICovCgogICAgZm9yIChjdXJTdHJlYW0gPSAwOyBjdXJTdHJlYW0gPCBuU3RyZWFtczsgY3VyU3RyZWFtKyspIHsKICAgICAgLyogc2hvdyBwcm9ncmVzcyAqLwogICAgICBpZiAobHBmbkNhbGxiYWNrKE11bERpdihjdXJTdHJlYW0sIDEwMCwgblN0cmVhbXMpKSkgewoJaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7Cglnb3RvIGVycm9yOwogICAgICB9CgogICAgICBBVklTdHJlYW1JbmZvVyhwSW5TdHJlYW1zW2N1clN0cmVhbV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CgogICAgICBpZiAoc0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKCS8qIHNhbXBsZS1iYXNlZCBkYXRhIGxpa2UgYXVkaW8gKi8KCXdoaWxlIChzSW5mby5kd1N0YXJ0IDwgc0luZm8uZHdMZW5ndGgpIHsKCSAgTE9ORyBsU2FtcGxlcyA9IGNiQnVmZmVyIC8gc0luZm8uZHdTYW1wbGVTaXplOwoKCSAgLyogY29weSBmb3JtYXQgaW4gY2FzZSBpdCBjYW4gY2hhbmdlICovCgkgIGxCdWZmZXJTaXplID0gY2JCdWZmZXI7CgkgIGhyZXMgPSBBVklTdHJlYW1SZWFkRm9ybWF0KHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJCSAgICAgbHBCdWZmZXIsICZsQnVmZmVyU2l6ZSk7CgkgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgZ290byBlcnJvcjsKCSAgQVZJU3RyZWFtU2V0Rm9ybWF0KHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIHNJbmZvLmR3U3RhcnQsCgkJCSAgICAgbHBCdWZmZXIsIGxCdWZmZXJTaXplKTsKCgkgIC8qIGxpbWl0IHRvIHN0cmVhbSBib3VuZGFyaWVzICovCgkgIGlmIChsU2FtcGxlcyAhPSAoTE9ORykoc0luZm8uZHdMZW5ndGggLSBzSW5mby5kd1N0YXJ0KSkKCSAgICBsU2FtcGxlcyA9IHNJbmZvLmR3TGVuZ3RoIC0gc0luZm8uZHdTdGFydDsKCgkgIC8qIG5vdyB0cnkgdG8gcmVhZCB1bnRpbCB3ZSBnZXQgaXQsIG9yIGFuIGVycm9yIG9jY3VycyAqLwoJICBkbyB7CgkgICAgbFJlYWRCeXRlcyAgID0gY2JCdWZmZXI7CgkgICAgbFJlYWRTYW1wbGVzID0gMDsKCSAgICBocmVzID0gQVZJU3RyZWFtUmVhZChwSW5TdHJlYW1zW2N1clN0cmVhbV0sc0luZm8uZHdTdGFydCxsU2FtcGxlcywKCQkJCSBscEJ1ZmZlcixjYkJ1ZmZlciwmbFJlYWRCeXRlcywmbFJlYWRTYW1wbGVzKTsKCSAgfSB3aGlsZSAoKGhyZXMgPT0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMKSAmJgoJCSAgIChscEJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwQnVmZmVyLCBjYkJ1ZmZlciAqPSAyKSkgIT0gTlVMTCk7CgkgIGlmIChscEJ1ZmZlciA9PSBOVUxMKQoJICAgIGhyZXMgPSBBVklFUlJfTUVNT1JZOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgkgIGlmIChsUmVhZFNhbXBsZXMgIT0gMCkgewoJICAgIHNJbmZvLmR3U3RhcnQgKz0gbFJlYWRTYW1wbGVzOwoJICAgIGhyZXMgPSBBVklTdHJlYW1Xcml0ZShwT3V0U3RyZWFtc1tjdXJTdHJlYW1dLCAtMSwgbFJlYWRTYW1wbGVzLAoJCQkJICBscEJ1ZmZlciwgbFJlYWRCeXRlcywgMCwgTlVMTCAsIE5VTEwpOwoJICAgIGlmIChGQUlMRUQoaHJlcykpCgkgICAgICBnb3RvIGVycm9yOwoKCSAgICAvKiBzaG93IHByb2dyZXNzICovCgkgICAgaWYgKGxwZm5DYWxsYmFjayhNdWxEaXYoc0luZm8uZHdTdGFydCwxMDAsblN0cmVhbXMqc0luZm8uZHdMZW5ndGgpKwoJCQkgICAgIE11bERpdihjdXJTdHJlYW0sIDEwMCwgblN0cmVhbXMpKSkgewoJICAgICAgaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CgkgICAgICBnb3RvIGVycm9yOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBpZiAoKHNJbmZvLmR3TGVuZ3RoIC0gc0luZm8uZHdTdGFydCkgIT0gMSkgewoJICAgICAgaHJlcyA9IEFWSUVSUl9GSUxFUkVBRDsKCSAgICAgIGdvdG8gZXJyb3I7CgkgICAgfQoJICB9Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiBibG9jay1iYXNlZCBkYXRhIGxpa2UgdmlkZW8gKi8KCWZvciAoOyBzSW5mby5kd1N0YXJ0IDwgc0luZm8uZHdMZW5ndGg7IHNJbmZvLmR3U3RhcnQrKykgewoJICBEV09SRCBmbGFncyA9IDA7CgoJICAvKiBjb3B5IGZvcm1hdCBpbiBjYXNlIGl0IGNhbiBjaGFuZ2UgKi8KCSAgbEJ1ZmZlclNpemUgPSBjYkJ1ZmZlcjsKCSAgaHJlcyA9IEFWSVN0cmVhbVJlYWRGb3JtYXQocEluU3RyZWFtc1tjdXJTdHJlYW1dLCBzSW5mby5kd1N0YXJ0LAoJCQkJICAgICBscEJ1ZmZlciwgJmxCdWZmZXJTaXplKTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBBVklTdHJlYW1TZXRGb3JtYXQocE91dFN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwKCQkJICAgICBscEJ1ZmZlciwgbEJ1ZmZlclNpemUpOwoKCSAgLyogdHJ5IHRvIHJlYWQgYmxvY2sgYW5kIHJlc2l6ZSBidWZmZXIgaWYgbmVjZXNzYXJ5ICovCgkgIGRvIHsKCSAgICBsUmVhZFNhbXBsZXMgPSAwOwoJICAgIGxSZWFkQnl0ZXMgICA9IGNiQnVmZmVyOwoJICAgIGhyZXMgPSBBVklTdHJlYW1SZWFkKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgc0luZm8uZHdTdGFydCwgMSwKCQkJCSBscEJ1ZmZlciwgY2JCdWZmZXIsJmxSZWFkQnl0ZXMsJmxSZWFkU2FtcGxlcyk7CgkgIH0gd2hpbGUgKChocmVzID09IEFWSUVSUl9CVUZGRVJUT09TTUFMTCkgJiYKCQkgICAobHBCdWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEJ1ZmZlciwgY2JCdWZmZXIgKj0gMikpICE9IE5VTEwpOwoJICBpZiAobHBCdWZmZXIgPT0gTlVMTCkKCSAgICBocmVzID0gQVZJRVJSX01FTU9SWTsKCSAgaWYgKEZBSUxFRChocmVzKSkKCSAgICBnb3RvIGVycm9yOwoJICBpZiAobFJlYWRTYW1wbGVzICE9IDEpIHsKCSAgICBocmVzID0gQVZJRVJSX0ZJTEVSRUFEOwoJICAgIGdvdG8gZXJyb3I7CgkgIH0KCgkgIGlmIChBVklTdHJlYW1Jc0tleUZyYW1lKHBJblN0cmVhbXNbY3VyU3RyZWFtXSwgKExPTkcpc0luZm8uZHdTdGFydCkpCgkgICAgZmxhZ3MgPSBBVklJRl9LRVlGUkFNRTsKCSAgaHJlcyA9IEFWSVN0cmVhbVdyaXRlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0sIC0xLCBsUmVhZFNhbXBsZXMsCgkJCQlscEJ1ZmZlciwgbFJlYWRCeXRlcywgZmxhZ3MsIE5VTEwsIE5VTEwpOwoJICBpZiAoRkFJTEVEKGhyZXMpKQoJICAgIGdvdG8gZXJyb3I7CgoJICAvKiBzaG93IHByb2dyZXNzICovCgkgIGlmIChscGZuQ2FsbGJhY2soTXVsRGl2KHNJbmZvLmR3U3RhcnQsMTAwLG5TdHJlYW1zKnNJbmZvLmR3TGVuZ3RoKSsKCQkJICAgTXVsRGl2KGN1clN0cmVhbSwgMTAwLCBuU3RyZWFtcykpKSB7CgkgICAgaHJlcyA9IEFWSUVSUl9VU0VSQUJPUlQ7CgkgICAgZ290byBlcnJvcjsKCSAgfQoJfSAvKiBjb3B5IGFsbCBibG9ja3MgKi8KICAgICAgfQogICAgfSAvKiBjb3B5IGRhdGEgc3RyZWFtIGJ5IHN0cmVhbSAqLwogIH0KCiBlcnJvcjoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscEJ1ZmZlcik7CiAgaWYgKHBmaWxlICE9IE5VTEwpIHsKICAgIGZvciAoY3VyU3RyZWFtID0gMDsgY3VyU3RyZWFtIDwgblN0cmVhbXM7IGN1clN0cmVhbSsrKSB7CiAgICAgIGlmIChwT3V0U3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwpCglBVklTdHJlYW1SZWxlYXNlKHBPdXRTdHJlYW1zW2N1clN0cmVhbV0pOwogICAgICBpZiAocEluU3RyZWFtc1tjdXJTdHJlYW1dICE9IE5VTEwpCglBVklTdHJlYW1SZWxlYXNlKHBJblN0cmVhbXNbY3VyU3RyZWFtXSk7CiAgICB9CgogICAgQVZJRmlsZVJlbGVhc2UocGZpbGUpOwogIH0KCiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQ3JlYXRlRWRpdGFibGVTdHJlYW0JKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBDcmVhdGVFZGl0YWJsZVN0cmVhbShQQVZJU1RSRUFNICpwcEVkaXRhYmxlLCBQQVZJU1RSRUFNIHBTb3VyY2UpCnsKICBJQVZJRWRpdFN0cmVhbSAqcEVkaXQgPSBOVUxMOwogIEhSRVNVTFQJICBocjsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIHBwRWRpdGFibGUsIHBTb3VyY2UpOwoKICBpZiAocHBFZGl0YWJsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwRWRpdGFibGUgPSBOVUxMOwoKICBpZiAocFNvdXJjZSAhPSBOVUxMKSB7CiAgICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocFNvdXJjZSwgJklJRF9JQVZJRWRpdFN0cmVhbSwKCQkJCSAgIChMUFZPSUQqKSZwRWRpdCk7CiAgICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fQ2xvbmUocEVkaXQsIHBwRWRpdGFibGUpOwogICAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKCiAgICAgIHJldHVybiBocjsKICAgIH0KICB9CgogIC8qIG5lZWQgb3duIGltcGxlbWVudGF0aW9uIG9mIElBVklFZGl0U3RyZWFtICovCiAgcEVkaXQgPSBBVklGSUxFX0NyZWF0ZUVkaXRTdHJlYW0ocFNvdXJjZSk7CiAgaWYgKHBFZGl0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaHIgPSBJQVZJRWRpdFN0cmVhbV9RdWVyeUludGVyZmFjZShwRWRpdCwgJklJRF9JQVZJU3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopcHBFZGl0YWJsZSk7CiAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ2xvbmUJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbUNsb25lKFBBVklTVFJFQU0gcFN0cmVhbSwgUEFWSVNUUkVBTSAqcHBSZXN1bHQpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBwU3RyZWFtLCBwcFJlc3VsdCk7CgogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcFJlc3VsdCA9IE5VTEw7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9DbG9uZShwRWRpdCwgcHBSZXN1bHQpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ29weQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBFZGl0U3RyZWFtQ29weShQQVZJU1RSRUFNIHBTdHJlYW0sIExPTkcgKnBsU3RhcnQsCgkJCSAgICAgIExPTkcgKnBsTGVuZ3RoLCBQQVZJU1RSRUFNICpwcFJlc3VsdCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsIHBTdHJlYW0sIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAocGxTdGFydCA9PSBOVUxMIHx8IHBsTGVuZ3RoID09IE5VTEwgfHwgcHBSZXN1bHQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcFJlc3VsdCA9IE5VTEw7CgogIGhyID0gSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwU3RyZWFtLCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9Db3B5KHBFZGl0LCBwbFN0YXJ0LCBwbExlbmd0aCwgcHBSZXN1bHQpOwoKICAgIElBVklFZGl0U3RyZWFtX1JlbGVhc2UocEVkaXQpOwogIH0gZWxzZQogICAgaHIgPSBBVklFUlJfVU5TVVBQT1JURUQ7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFZGl0U3RyZWFtQ3V0CQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1DdXQoUEFWSVNUUkVBTSBwU3RyZWFtLCBMT05HICpwbFN0YXJ0LAoJCQkgICAgIExPTkcgKnBsTGVuZ3RoLCBQQVZJU1RSRUFNICpwcFJlc3VsdCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsIHBTdHJlYW0sIHBsU3RhcnQsIHBsTGVuZ3RoLCBwcFJlc3VsdCk7CgogIGlmIChwcFJlc3VsdCAhPSBOVUxMKQogICAgKnBwUmVzdWx0ID0gTlVMTDsKICBpZiAocFN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHBsU3RhcnQgPT0gTlVMTCB8fCBwbExlbmd0aCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBTdHJlYW0sICZJSURfSUFWSUVkaXRTdHJlYW0sKExQVk9JRCopJnBFZGl0KTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBwRWRpdCAhPSBOVUxMKSB7CiAgICBociA9IElBVklFZGl0U3RyZWFtX0N1dChwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBwUmVzdWx0KTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVBhc3RlCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1QYXN0ZShQQVZJU1RSRUFNIHBEZXN0LCBMT05HICpwbFN0YXJ0LCBMT05HICpwbExlbmd0aCwKCQkJICAgICAgIFBBVklTVFJFQU0gcFNvdXJjZSwgTE9ORyBsU3RhcnQsIExPTkcgbEVuZCkKewogIFBBVklFRElUU1RSRUFNIHBFZGl0ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlcCwlZCwlZClcbiIsIHBEZXN0LCBwbFN0YXJ0LCBwbExlbmd0aCwKCXBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogIGlmIChwRGVzdCA9PSBOVUxMIHx8IHBTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChwbFN0YXJ0ID09IE5VTEwgfHwgcGxMZW5ndGggPT0gTlVMTCB8fCBsU3RhcnQgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKHBEZXN0LCAmSUlEX0lBVklFZGl0U3RyZWFtLChMUFZPSUQqKSZwRWRpdCk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgcEVkaXQgIT0gTlVMTCkgewogICAgaHIgPSBJQVZJRWRpdFN0cmVhbV9QYXN0ZShwRWRpdCwgcGxTdGFydCwgcGxMZW5ndGgsIHBTb3VyY2UsIGxTdGFydCwgbEVuZCk7CgogICAgSUFWSUVkaXRTdHJlYW1fUmVsZWFzZShwRWRpdCk7CiAgfSBlbHNlCiAgICBociA9IEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXRJbmZvQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXRJbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkJICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihBVklTVFJFQU1JTkZPQSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweSgmYXNpdywgYXNpLCBzaXplb2YoYXNpdykgLSBzaXplb2YoYXNpdy5zek5hbWUpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgYXNpLT5zek5hbWUsIC0xLAoJCSAgICAgIGFzaXcuc3pOYW1lLCBzaXplb2YoYXNpdy5zek5hbWUpL3NpemVvZihXQ0hBUikpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9XKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXRJbmZvVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXRJbmZvVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT1cgYXNpLAoJCQkJICBMT05HIHNpemUpCnsKICBQQVZJRURJVFNUUkVBTSBwRWRpdCA9IE5VTEw7CiAgSFJFU1VMVCAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBwc3RyZWFtLCBhc2ksIHNpemUpOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UocHN0cmVhbSwgJklJRF9JQVZJRWRpdFN0cmVhbSwoTFBWT0lEKikmcEVkaXQpOwogIGlmIChTVUNDRUVERUQoaHIpICYmIHBFZGl0ICE9IE5VTEwpIHsKICAgIGhyID0gSUFWSUVkaXRTdHJlYW1fU2V0SW5mbyhwRWRpdCwgYXNpLCBzaXplKTsKCiAgICBJQVZJRWRpdFN0cmVhbV9SZWxlYXNlKHBFZGl0KTsKICB9IGVsc2UKICAgIGhyID0gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRWRpdFN0cmVhbVNldE5hbWVBCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRWRpdFN0cmVhbVNldE5hbWVBKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBDU1RSIHN6TmFtZSkKewogIEFWSVNUUkVBTUlORk9BIGFzaWE7CiAgSFJFU1VMVCAgICAgICAgaHJlczsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIHBzdHJlYW0sIGRlYnVnc3RyX2Eoc3pOYW1lKSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKICBpZiAoc3pOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBocmVzID0gQVZJU3RyZWFtSW5mb0EocHN0cmVhbSwgJmFzaWEsIHNpemVvZihhc2lhKSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpYS5zek5hbWUsIDAsIHNpemVvZihhc2lhLnN6TmFtZSkpOwogIGxzdHJjcHluQShhc2lhLnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpYS5zek5hbWUpL3NpemVvZihhc2lhLnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9BKHBzdHJlYW0sICZhc2lhLCBzaXplb2YoYXNpYSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVkaXRTdHJlYW1TZXROYW1lVwkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEVkaXRTdHJlYW1TZXROYW1lVyhQQVZJU1RSRUFNIHBzdHJlYW0sIExQQ1dTVFIgc3pOYW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBIUkVTVUxUICAgICAgICBocmVzOwoKICBUUkFDRSgiKCVwLCVzKVxuIiwgcHN0cmVhbSwgZGVidWdzdHJfdyhzek5hbWUpKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzek5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGhyZXMgPSBJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSk7CiAgaWYgKEZBSUxFRChocmVzKSkKICAgIHJldHVybiBocmVzOwoKICBtZW1zZXQoYXNpdy5zek5hbWUsIDAsIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIGxzdHJjcHluVyhhc2l3LnN6TmFtZSwgc3pOYW1lLCBzaXplb2YoYXNpdy5zek5hbWUpL3NpemVvZihhc2l3LnN6TmFtZVswXSkpOwoKICByZXR1cm4gRWRpdFN0cmVhbVNldEluZm9XKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUNsZWFyQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQ2xlYXJDbGlwYm9hcmQodm9pZCkKewogIFRSQUNFKCIoKVxuIik7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIE9sZVNldENsaXBib2FyZChOVUxMKTsgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklHZXRGcm9tQ2xpcGJvYXJkCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJR2V0RnJvbUNsaXBib2FyZChQQVZJRklMRSAqcHBmaWxlKQp7CiAgRklYTUUoIiglcCksIHN0dWIhXG4iLCBwcGZpbGUpOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQVZJTWFrZVN0cmVhbUZyb21DbGlwYm9hcmQgKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklNYWtlU3RyZWFtRnJvbUNsaXBib2FyZChVSU5UIGNmRm9ybWF0LCBIQU5ETEUgaEdsb2JhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFWSVNUUkVBTSAqIHBwc3RyZWFtKQp7CiAgRklYTUUoIigweCUwOHgsJXAsJXApLCBzdHViIVxuIiwgY2ZGb3JtYXQsIGhHbG9iYWwsIHBwc3RyZWFtKTsKCiAgaWYgKHBwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklQdXRGaWxlT25DbGlwYm9hcmQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklQdXRGaWxlT25DbGlwYm9hcmQoUEFWSUZJTEUgcGZpbGUpCnsKICBGSVhNRSgiKCVwKSwgc3R1YiFcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKSFJFU1VMVCBXSU5BUElWIEFWSVNhdmVBKExQQ1NUUiBzekZpbGUsIENMU0lEICogcGNsc2lkSGFuZGxlciwgQVZJU0FWRUNBTExCQUNLIGxwZm5DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5TdHJlYW1zLCBQQVZJU1RSRUFNIHBhdmksIExQQVZJQ09NUFJFU1NPUFRJT05TIGxwT3B0aW9ucywgLi4uKQp7CiAgICBGSVhNRSgiKCVzLCVwLCVwLDB4JTA4eCwlcCwlcCksIHN0dWIhXG4iLCBkZWJ1Z3N0cl9hKHN6RmlsZSksIHBjbHNpZEhhbmRsZXIsIGxwZm5DYWxsYmFjaywKICAgICAgICAgIG5TdHJlYW1zLCBwYXZpLCBscE9wdGlvbnMpOwoKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCkhSRVNVTFQgV0lOQVBJViBBVklTYXZlVyhMUENXU1RSIHN6RmlsZSwgQ0xTSUQgKiBwY2xzaWRIYW5kbGVyLCBBVklTQVZFQ0FMTEJBQ0sgbHBmbkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgblN0cmVhbXMsIFBBVklTVFJFQU0gcGF2aSwgTFBBVklDT01QUkVTU09QVElPTlMgbHBPcHRpb25zLCAuLi4pCnsKICAgIEZJWE1FKCIoJXMsJXAsJXAsMHglMDh4LCVwLCVwKSwgc3R1YiFcbiIsIGRlYnVnc3RyX3coc3pGaWxlKSwgcGNsc2lkSGFuZGxlciwgbHBmbkNhbGxiYWNrLAogICAgICAgICAgblN0cmVhbXMsIHBhdmksIGxwT3B0aW9ucyk7CgogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQo=