LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyIE1pY2hhZWwgR/xubmV3aWcKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZG93c3guaCIKCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogY29waWVkIGZyb20gZGxscy9zaGVsbDMyL3VuZG9jc2hlbGwuaAogKi8KSFJFU1VMVCBXSU5BUEkgU0hDb0NyZWF0ZUluc3RhbmNlKExQQ1NUUiBscHN6Q2xzaWQsUkVGQ0xTSUQgckNsc2lkLAoJCQkJICBMUFVOS05PV04gcFVua091dGVyLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBmb3IgQVZJQnVpbGRGaWx0ZXJXIC0tIHVzZXMgZml4ZWQgc2l6ZSB0YWJsZQogKi8KI2RlZmluZSBNQVhfRklMVEVSUyAzMCAvKiAzMCA9PiA3a0IgKi8KCnR5cGVkZWYgc3RydWN0IF9BVklGaWx0ZXIgewogIFdDSEFSIHN6Q2xzaWRbNDBdOwogIFdDSEFSIHN6RXh0ZW5zaW9uc1tNQVhfRklMVEVSUyAqIDddOwp9IEFWSUZpbHRlcjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBmb3IgQVZJU2F2ZU9wdGlvbnMKICovCnN0YXRpYyBzdHJ1Y3QgewogIFVJTlQgICAgICAgICAgICAgICAgICB1RmxhZ3M7CiAgSU5UICAgICAgICAgICAgICAgICAgIG5TdHJlYW1zOwogIFBBVklTVFJFQU0gICAgICAgICAgICpwcGF2aXM7CiAgTFBBVklDT01QUkVTU09QVElPTlMgKnBwT3B0aW9uczsKICBJTlQgICAgICAgICAgICAgICAgICAgbkN1cnJlbnQ7Cn0gU2F2ZU9wdHM7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogY29waWVkIGZyb20gZGxscy9vbGUzMi9jb21wb2JqLmMKICovCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKExQQ1NUUiBpZHN0ciwgTFBDTFNJRCBpZCkKewogIEJZVEUgKnMgPSAoQllURSopaWRzdHI7CiAgQllURSAqcDsKICBJTlQgICBpOwogIEJZVEUgdGFibGVbMjU2XTsKCiAgaWYgKCFzKSB7CiAgICBtZW1zZXQocywgMCwgc2l6ZW9mKENMU0lEKSk7CiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgeyAgLyogdmFsaWRhdGUgdGhlIENMU0lEIHN0cmluZyAqLwogICAgaWYgKGxzdHJsZW5BKHMpICE9IDM4KQogICAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKCiAgICBpZiAoKHNbMF0hPSd7JykgfHwgKHNbOV0hPSctJykgfHwgKHNbMTRdIT0nLScpIHx8IChzWzE5XSE9Jy0nKSB8fAoJKHNbMjRdIT0nLScpIHx8IChzWzM3XSE9J30nKSkKICAgICAgcmV0dXJuIENPX0VfQ0xBU1NTVFJJTkc7CgogICAgZm9yIChpID0gMTsgaSA8IDM3OyBpKyspIHsKICAgICAgaWYgKChpID09IDkpIHx8IChpID09IDE0KSB8fCAoaSA9PSAxOSkgfHwgKGkgPT0gMjQpKQoJY29udGludWU7CiAgICAgIGlmICghKCgoc1tpXSA+PSAnMCcpICYmIChzW2ldIDw9ICc5JykpICB8fAoJICAgICgoc1tpXSA+PSAnYScpICYmIChzW2ldIDw9ICdmJykpICB8fAoJICAgICgoc1tpXSA+PSAnQScpICYmIChzW2ldIDw9ICdGJykpKQoJICApCglyZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKICAgIH0KICB9CgogIFRSQUNFKCIlcyAtPiAlcFxuIiwgcywgaWQpOwoKICAvKiBxdWljayBsb29rdXAgdGFibGUgKi8KICBtZW1zZXQodGFibGUsIDAsIDI1Nik7CgogIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKQogICAgdGFibGVbJzAnICsgaV0gPSBpOwoKICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CiAgICB0YWJsZVsnQScgKyBpXSA9IGkrMTA7CiAgICB0YWJsZVsnYScgKyBpXSA9IGkrMTA7CiAgfQoKICAvKiBpbiBmb3JtIHtYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFh9ICovCiAgcCA9IChCWVRFICopIGlkOwoKICBzKys7CS8qIHNraXAgbGVhZGluZyBicmFjZSAgKi8KICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICBwWzMgLSBpXSA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQogIHAgKz0gNDsKICBzKys7CS8qIHNraXAgLSAqLwoKICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICBwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwogICAgcyArPSAyOwogIH0KICBwICs9IDI7CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewogICAgcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcCArPSAyOwogIHMrKzsJLyogc2tpcCAtICovCgogIC8qIHRoZXNlIGFyZSBqdXN0IHNlcXVlbnRpYWwgYnl0ZXMgKi8KICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CiAgICAqcCsrID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKICAgIHMgKz0gMjsKICB9CiAgcysrOwkvKiBza2lwIC0gKi8KCiAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykgewogICAgKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CiAgICBzICs9IDI7CiAgfQoKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEJPT0wgQVZJRklMRV9HZXRGaWxlSGFuZGxlckJ5RXh0ZW5zaW9uKExQQ1dTVFIgc3pGaWxlLCBMUENMU0lEIGxwY2xzaWQpCnsKICBDSEFSICAgc3pSZWdLZXlbMjVdOwogIENIQVIgICBzelZhbHVlWzEwMF07CiAgTFBXU1RSIHN6RXh0ID0gc3RycmNoclcoc3pGaWxlLCAnLicpOwogIExPTkcgICBsZW4gPSBzaXplb2Yoc3pWYWx1ZSkgLyBzaXplb2Yoc3pWYWx1ZVswXSk7CgogIGlmIChzekV4dCA9PSBOVUxMKQogICAgcmV0dXJuIEZBTFNFOwoKICBzekV4dCsrOwoKICB3c3ByaW50ZkEoc3pSZWdLZXksICJBVklGaWxlXFxFeHRlbnNpb25zXFwlLjNscyIsIHN6RXh0KTsKICBpZiAoUmVnUXVlcnlWYWx1ZUEoSEtFWV9DTEFTU0VTX1JPT1QsIHN6UmVnS2V5LCBzelZhbHVlLCAmbGVuKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gKEFWSUZJTEVfQ0xTSURGcm9tU3RyaW5nKHN6VmFsdWUsIGxwY2xzaWQpID09IFNfT0spOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVJbml0CQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbml0CQkoQVZJRklMRS4xMDApCiAqLwp2b2lkIFdJTkFQSSBBVklGaWxlSW5pdCh2b2lkKSB7CiAgLyogbmVlZCB0byBsb2FkIG9sZTMyLmRsbCBpZiBub3QgYWxyZWFkeSBkb25lIGFuZCBnZXQgc29tZSBmdW5jdGlvbnMgKi8KICBGSVhNRSgiKCk6IHN0dWIhXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlRXhpdAkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlRXhpdAkJKEFWSUZJTEUuMTAxKQogKi8Kdm9pZCBXSU5BUEkgQVZJRmlsZUV4aXQodm9pZCkgewogIC8qIG5lZWQgdG8gZnJlZSBvbGUzMi5kbGwgaWYgd2UgYXJlIHRoZSBsYXN0IGV4aXQgY2FsbCAqLwogIEZJWE1FKCIoKTogc3R1YiFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuQQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlT3BlbgkJKEFWSUZJTEUuMTAyKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZU9wZW5BKFBBVklGSUxFICpwcGZpbGUsIExQQ1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIExQV1NUUiAgd3N6RmlsZSA9IE5VTEw7CiAgSFJFU1VMVCBocjsKICBpbnQgICAgIGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOFgsJXMpXG4iLCBwcGZpbGUsIGRlYnVnc3RyX2Eoc3pGaWxlKSwgdU1vZGUsCglkZWJ1Z3N0cl9ndWlkKGxwSGFuZGxlcikpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBwZmlsZSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogY29udmVydCBBU0NJSSBzdHJpbmcgdG8gVW5pY29kZSBhbmQgY2FsbCB1bmljb2RlIGZ1bmN0aW9uICovCiAgbGVuID0gbHN0cmxlbkEoc3pGaWxlKTsKICBpZiAobGVuIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICB3c3pGaWxlID0gKExQV1NUUilMb2NhbEFsbG9jKExQVFIsIChsZW4gKyAxKSAqIHNpemVvZihXQ0hBUikpOwogIGlmICh3c3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6RmlsZSwgLTEsIHdzekZpbGUsIGxlbiArIDEpOwogIHdzekZpbGVbbGVuICsgMV0gPSAwOwoKICBociA9IEFWSUZpbGVPcGVuVyhwcGZpbGUsIHdzekZpbGUsIHVNb2RlLCBscEhhbmRsZXIpOwoKICBMb2NhbEZyZWUoKEhMT0NBTCl3c3pGaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSUZpbGVPcGVuVwkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlT3BlblcoUEFWSUZJTEUgKnBwZmlsZSwgTFBDV1NUUiBzekZpbGUsIFVJTlQgdU1vZGUsCgkJCSAgICBMUENMU0lEIGxwSGFuZGxlcikKewogIElQZXJzaXN0RmlsZSAqcHBlcnNpc3QgPSBOVUxMOwogIENMU0lEICAgICAgICAgY2xzaWRIYW5kbGVyOwogIEhSRVNVTFQgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJXMsMHglWCwlcylcbiIsIHBwZmlsZSwgZGVidWdzdHJfdyhzekZpbGUpLCB1TW9kZSwKCWRlYnVnc3RyX2d1aWQobHBIYW5kbGVyKSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocHBmaWxlID09IE5VTEwgfHwgc3pGaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBmaWxlID0gTlVMTDsKCiAgLyogaWYgbm8gaGFuZGxlciB0aGVuIHRyeSBndWVzc2luZyBpdCBieSBleHRlbnNpb24gKi8KICBpZiAobHBIYW5kbGVyID09IE5VTEwpIHsKICAgIGlmICghIEFWSUZJTEVfR2V0RmlsZUhhbmRsZXJCeUV4dGVuc2lvbihzekZpbGUsICZjbHNpZEhhbmRsZXIpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZQogICAgbWVtY3B5KCZjbHNpZEhhbmRsZXIsIGxwSGFuZGxlciwgc2l6ZW9mKGNsc2lkSGFuZGxlcikpOwoKICAvKiBjcmV0ZSBpbnN0YW5jZSBvZiBoYW5kbGVyICovCiAgaHIgPSBTSENvQ3JlYXRlSW5zdGFuY2UoTlVMTCwgJmNsc2lkSGFuZGxlciwgTlVMTCwKCQkJICAmSUlEX0lBVklGaWxlLCAoTFBWT0lEKilwcGZpbGUpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBocjsKCiAgLyogYXNrIGZvciBJUGVyc2lzdEZpbGUgaW50ZXJmYWNlIGZvciBsb2FkaW5nL2NyZWF0aW5nIHRoZSBmaWxlICovCiAgaHIgPSBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgqcHBmaWxlLCAmSUlEX0lQZXJzaXN0RmlsZSwgKExQVk9JRCopJnBwZXJzaXN0KTsKICBpZiAoRkFJTEVEKGhyKSB8fCBwcGVyc2lzdCA9PSBOVUxMKSB7CiAgICBJQVZJRmlsZV9SZWxlYXNlKCpwcGZpbGUpOwogICAgKnBwZmlsZSA9IE5VTEw7CiAgICByZXR1cm4gaHI7CiAgfQoKICBociA9IElQZXJzaXN0RmlsZV9Mb2FkKHBwZXJzaXN0LCBzekZpbGUsIHVNb2RlKTsKICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwcGVyc2lzdCk7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklGaWxlX1JlbGVhc2UoKnBwZmlsZSk7CiAgICAqcHBmaWxlID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQWRkUmVmCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVBZGRSZWYJCShBVklGSUxFLjE0MCkKICovClVMT05HIFdJTkFQSSBBVklGaWxlQWRkUmVmKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKHBmaWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTDMyLkApCiAqCQlBVklGaWxlUmVsZWFzZQkJKEFWSUZJTEUuMTQxKQogKi8KVUxPTkcgV0lOQVBJIEFWSUZpbGVSZWxlYXNlKFBBVklGSUxFIHBmaWxlKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBmaWxlKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpIHsKICAgIEVSUigiOiBiYWQgaGFuZGxlIHBhc3NlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZShwZmlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluZm8JCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUluZm9BCQkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVJbmZvCQkoQVZJRklMRS4xNDIpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlSW5mb0EoUEFWSUZJTEUgcGZpbGUsIExQQVZJRklMRUlORk9BIGFmaSwgTE9ORyBzaXplKQp7CiAgQVZJRklMRUlORk9XIGFmaXc7CiAgSFJFU1VMVCAgICAgIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcGZpbGUsIGFmaSwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CiAgaWYgKHNpemUgPCBzaXplb2YoQVZJRklMRUlORk9BKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaHJlcyA9IElBVklGaWxlX0luZm8ocGZpbGUsICZhZml3LCBzaXplb2YoYWZpdykpOwoKICBtZW1jcHkoYWZpLCAmYWZpdywgc2l6ZW9mKCphZmkpIC0gc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSkpOwogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBhZml3LnN6RmlsZVR5cGUsIC0xLCBhZmktPnN6RmlsZVR5cGUsCgkJICAgICAgc2l6ZW9mKGFmaS0+c3pGaWxlVHlwZSksIE5VTEwsIE5VTEwpOwogIGFmaS0+c3pGaWxlVHlwZVtzaXplb2YoYWZpLT5zekZpbGVUeXBlKSAtIDFdID0gMDsKCiAgcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUluZm9XCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVJbmZvVyhQQVZJRklMRSBwZmlsZSwgTFBBVklGSUxFSU5GT1cgYWZpdywgTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBwZmlsZSwgYWZpdywgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9JbmZvKHBmaWxlLCBhZml3LCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlR2V0U3RyZWFtCShBVklGSUwzMi5AKQogKgkJQVZJRmlsZUdldFN0cmVhbQkoQVZJRklMRS4xNDMpCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlR2V0U3RyZWFtKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBUUkFDRSgiKCVwLCVwLCclNC40cycsJWxkKVxuIiwgcGZpbGUsIGF2aXMsIChjaGFyKikmZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX0dldFN0cmVhbShwZmlsZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlQ3JlYXRlU3RyZWFtQQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVDcmVhdGVTdHJlYW1BKFBBVklGSUxFIHBmaWxlLCBQQVZJU1RSRUFNICpwcGF2aSwKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9BIHBzaSkKewogIEFWSVNUUkVBTUlORk9XCXBzaXc7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgcHBhdmksIHBzaSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIC8qIE9ubHkgdGhlIHN6TmFtZSBhdCB0aGUgZW5kIGlzIGRpZmZlcmVudCAqLwogIG1lbWNweSgmcHNpdywgcHNpLCBzaXplb2YoKnBzaSkgLSBzaXplb2YocHNpLT5zek5hbWUpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgcHNpLT5zek5hbWUsIC0xLCBwc2l3LnN6TmFtZSwKCQkgICAgICBzaXplb2YocHNpdy5zek5hbWUpIC8gc2l6ZW9mKHBzaXcuc3pOYW1lWzBdKSk7CgogIHJldHVybiBJQVZJRmlsZV9DcmVhdGVTdHJlYW0ocGZpbGUsIHBwYXZpLCAmcHNpdyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUNyZWF0ZVN0cmVhbVcJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklGaWxlQ3JlYXRlU3RyZWFtVyhQQVZJRklMRSBwZmlsZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCSAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwZmlsZSwgYXZpcywgYXNpKTsKCiAgcmV0dXJuIElBVklGaWxlX0NyZWF0ZVN0cmVhbShwZmlsZSwgYXZpcywgYXNpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklGaWxlV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZVdyaXRlRGF0YShQQVZJRklMRSBwZmlsZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlbGQpXG4iLCBwZmlsZSwgKGNoYXIqKSZmY2MsIGxwLCBzaXplKTsKCiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklGaWxlX1dyaXRlRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZVJlYWREYXRhCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUZpbGVSZWFkRGF0YShQQVZJRklMRSBwZmlsZSxEV09SRCBmY2MsTFBWT0lEIGxwLExQTE9ORyBzaXplKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcGZpbGUsIChjaGFyKikmZmNjLCBscCwgc2l6ZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YShwZmlsZSwgZmNjLCBscCwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJRmlsZUVuZFJlY29yZAkoQVZJRklMMzIuQCkKICoJCUFWSUZpbGVFbmRSZWNvcmQJKEFWSUZJTEUuMTQ4KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRmlsZUVuZFJlY29yZChQQVZJRklMRSBwZmlsZSkKewogIFRSQUNFKCIoJXApXG4iLCBwZmlsZSk7CgogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJRmlsZV9FbmRSZWNvcmQocGZpbGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUFkZFJlZgkJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1BZGRSZWYJCShBVklGSUxFLjE2MCkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1BZGRSZWYoUEFWSVNUUkVBTSBwc3RyZWFtKQp7CiAgVFJBQ0UoIiglcClcbiIsIHBzdHJlYW0pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIGhhbmRsZSBwYXNzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIElBVklTdHJlYW1fQWRkUmVmKHBzdHJlYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlbGVhc2UJKEFWSUZJTDMyLkApCiAqCQlBVklTdHJlYW1SZWxlYXNlCShBVklGSUxFLjE2MSkKICovClVMT05HIFdJTkFQSSBBVklTdHJlYW1SZWxlYXNlKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkgewogICAgRVJSKCI6IGJhZCBoYW5kbGUgcGFzc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiBJQVZJU3RyZWFtX1JlbGVhc2UocHN0cmVhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtQ3JlYXRlCQkoQVZJRklMMzIuQCkKICoJCUFWSVN0cmVhbUNyZWF0ZQkJKEFWSUZJTEUuMTA0KQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtQ3JlYXRlKFBBVklTVFJFQU0gKnBwYXZpLCBMT05HIGxQYXJhbTEsIExPTkcgbFBhcmFtMiwKCQkJICAgICAgIExQQ0xTSUQgcGNsc2lkSGFuZGxlcikKewogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLCVzKVxuIiwgcHBhdmksIGxQYXJhbTEsIGxQYXJhbTIsCglkZWJ1Z3N0cl9ndWlkKHBjbHNpZEhhbmRsZXIpKTsKCiAgaWYgKHBwYXZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBhdmkgPSBOVUxMOwogIGlmIChwY2xzaWRIYW5kbGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICBociA9IFNIQ29DcmVhdGVJbnN0YW5jZShOVUxMLCBwY2xzaWRIYW5kbGVyLCBOVUxMLAoJCQkgICZJSURfSUFWSVN0cmVhbSwgKExQVk9JRCopcHBhdmkpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcGF2aSA9PSBOVUxMKQogICAgcmV0dXJuIGhyOwoKICBociA9IElBVklTdHJlYW1fQ3JlYXRlKCpwcGF2aSwgbFBhcmFtMSwgbFBhcmFtMik7CiAgaWYgKEZBSUxFRChocikpIHsKICAgIElBVklTdHJlYW1fUmVsZWFzZSgqcHBhdmkpOwogICAgKnBwYXZpID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1JbmZvQQkJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1JbmZvQShQQVZJU1RSRUFNIHBzdHJlYW0sIExQQVZJU1RSRUFNSU5GT0EgYXNpLAoJCQkgICAgICBMT05HIHNpemUpCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwogIEhSRVNVTFQJIGhyZXM7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwogIGlmIChzaXplIDwgc2l6ZW9mKEFWSVNUUkVBTUlORk9BKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgaHJlcyA9IElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKTsKCiAgbWVtY3B5KGFzaSwgJmFzaXcsIHNpemVvZihhc2l3KSAtIHNpemVvZihhc2l3LnN6TmFtZSkpOwogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBhc2l3LnN6TmFtZSwgLTEsIGFzaS0+c3pOYW1lLAoJCSAgICAgIHNpemVvZihhc2ktPnN6TmFtZSksIE5VTEwsIE5VTEwpOwogIGFzaS0+c3pOYW1lW3NpemVvZihhc2ktPnN6TmFtZSkgLSAxXSA9IDA7CgogIHJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUluZm9XCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUluZm9XKFBBVklTVFJFQU0gcHN0cmVhbSwgTFBBVklTVFJFQU1JTkZPVyBhc2ksCgkJCSAgICAgIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgcHN0cmVhbSwgYXNpLCBzaXplKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICByZXR1cm4gSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sIGFzaSwgc2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtRmluZFNhbXBsZQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbUZpbmRTYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHBvcywgRFdPUkQgZmxhZ3MpCnsKICBUUkFDRSgiKCVwLCVsZCwweCVsWClcbiIsIHBzdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKHBzdHJlYW0sIHBvcywgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWRGb3JtYXQJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1SZWFkRm9ybWF0KFBBVklTVFJFQU0gcHN0cmVhbSwgTE9ORyBwb3MsCgkJCQkgICBMUFZPSUQgZm9ybWF0LCBMUExPTkcgZm9ybWF0c2l6ZSkKewogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgcHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWRGb3JtYXQocHN0cmVhbSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVNldEZvcm1hdAkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVNldEZvcm1hdChQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgcG9zLAoJCQkJICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBwc3RyZWFtLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KHBzdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1SZWFkCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSVN0cmVhbVJlYWQoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgTFBWT0lEIGJ1ZmZlciwgTE9ORyBidWZmZXJzaXplLAoJCQkgICAgIExQTE9ORyBieXRlc3JlYWQsIExQTE9ORyBzYW1wbGVzcmVhZCkKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBREhBTkRMRTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGUJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtV3JpdGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIHN0YXJ0LCBMT05HIHNhbXBsZXMsCgkJCSAgICAgIExQVk9JRCBidWZmZXIsIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCSAgICAgIExQTE9ORyBzYW1wd3JpdHRlbiwgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglbFgsJXAsJXApXG4iLCBwc3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAoJYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKHBzdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVJlYWREYXRhCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtUmVhZERhdGEoUEFWSVNUUkVBTSBwc3RyZWFtLCBEV09SRCBmY2MsIExQVk9JRCBscCwKCQkJCSBMUExPTkcgbHByZWFkKQp7CiAgVFJBQ0UoIiglcCwnJTQuNHMnLCVwLCVwKVxuIiwgcHN0cmVhbSwgKGNoYXIqKSZmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKHBzdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtV3JpdGVEYXRhCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtV3JpdGVEYXRhKFBBVklTVFJFQU0gcHN0cmVhbSwgRFdPUkQgZmNjLCBMUFZPSUQgbHAsCgkJCQkgIExPTkcgc2l6ZSkKewogIFRSQUNFKCIoJXAsJyU0LjRzJywlcCwlbGQpXG4iLCBwc3RyZWFtLCAoY2hhciopJmZjYywgbHAsIHNpemUpOwoKICBpZiAocHN0cmVhbSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURIQU5ETEU7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShwc3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1HZXRGcmFtZU9wZW4JKEFWSUZJTDMyLkApCiAqLwpQR0VURlJBTUUgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lT3BlbihQQVZJU1RSRUFNIHBzdHJlYW0sCgkJCQkgICAgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlXYW50ZWQpCnsKICBQR0VURlJBTUUgcGcgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcHN0cmVhbSwgbHBiaVdhbnRlZCk7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9RdWVyeUludGVyZmFjZShwc3RyZWFtLCAmSUlEX0lHZXRGcmFtZSwgKExQVk9JRCopJnBnKSkgfHwKICAgICAgcGcgPT0gTlVMTCkgewogICAgcGcgPSBBVklGSUxFX0NyZWF0ZUdldEZyYW1lKHBzdHJlYW0pOwogICAgaWYgKHBnID09IE5VTEwpCiAgICAgIHJldHVybiBOVUxMOwogIH0KCiAgaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KHBnLCBscGJpV2FudGVkLCBOVUxMLCAwLCAwLCAtMSwgLTEpKSkgewogICAgSUdldEZyYW1lX1JlbGVhc2UocGcpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICByZXR1cm4gcGc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtR2V0RnJhbWUJKEFWSUZJTDMyLkApCiAqLwpMUFZPSUQgV0lOQVBJIEFWSVN0cmVhbUdldEZyYW1lKFBHRVRGUkFNRSBwZywgTE9ORyBwb3MpCnsKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBnLCBwb3MpOwoKICBpZiAocGcgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICByZXR1cm4gSUdldEZyYW1lX0dldEZyYW1lKHBnLCBwb3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbUdldEZyYW1lQ2xvc2UgKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFBHRVRGUkFNRSBwZykKewogIFRSQUNFKCIoJXApXG4iLCBwZyk7CgogIGlmIChwZyAhPSBOVUxMKQogICAgcmV0dXJuIElHZXRGcmFtZV9SZWxlYXNlKHBnKTsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklNYWtlQ29tcHJlc3NlZFN0cmVhbQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSU1ha2VDb21wcmVzc2VkU3RyZWFtKFBBVklTVFJFQU0gKnBwc0NvbXByZXNzZWQsCgkJCQkgICAgICAgUEFWSVNUUkVBTSBwc1NvdXJjZSwKCQkJCSAgICAgICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBhY28sCgkJCQkgICAgICAgTFBDTFNJRCBwY2xzaWRIYW5kbGVyKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKICBDSEFSICAgICAgICAgICBzelJlZ0tleVsyNV07CiAgQ0hBUiAgICAgICAgICAgc3pWYWx1ZVsxMDBdOwogIENMU0lEICAgICAgICAgIGNsc2lkSGFuZGxlcjsKICBIUkVTVUxUICAgICAgICBocjsKICBMT05HICAgICAgICAgICBzaXplID0gc2l6ZW9mKHN6VmFsdWUpOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVzKVxuIiwgcHBzQ29tcHJlc3NlZCwgcHNTb3VyY2UsIGFjbywKCWRlYnVnc3RyX2d1aWQocGNsc2lkSGFuZGxlcikpOwoKICBpZiAocHBzQ29tcHJlc3NlZCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAocHNTb3VyY2UgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFESEFORExFOwoKICAqcHBzQ29tcHJlc3NlZCA9IE5VTEw7CgogIC8qIGlmIG5vIGhhbmRsZXIgZ2l2ZW4gZ2V0IGRlZmF1bHQgb25lcyBiYXNlZCBvbiBzdHJlYW10eXBlICovCiAgaWYgKHBjbHNpZEhhbmRsZXIgPT0gTlVMTCkgewogICAgaHIgPSBJQVZJU3RyZWFtX0luZm8ocHNTb3VyY2UsICZhc2l3LCBzaXplb2YoYXNpdykpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKCiAgICB3c3ByaW50ZkEoc3pSZWdLZXksICJBVklGaWxlXFxDb21wcmVzc29yc1xcJTQuNHMiLCAoY2hhciopJmFzaXcuZmNjVHlwZSk7CiAgICBpZiAoUmVnUXVlcnlWYWx1ZUEoSEtFWV9DTEFTU0VTX1JPT1QsIHN6UmVnS2V5LCBzelZhbHVlLCAmc2l6ZSkgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICAgIGlmIChBVklGSUxFX0NMU0lERnJvbVN0cmluZyhzelZhbHVlLCAmY2xzaWRIYW5kbGVyKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0gZWxzZQogICAgbWVtY3B5KCZjbHNpZEhhbmRsZXIsIHBjbHNpZEhhbmRsZXIsIHNpemVvZihjbHNpZEhhbmRsZXIpKTsKCiAgaHIgPSBTSENvQ3JlYXRlSW5zdGFuY2UoTlVMTCwgJmNsc2lkSGFuZGxlciwgTlVMTCwKCQkJICAmSUlEX0lBVklTdHJlYW0sIChMUFZPSUQqKXBwc0NvbXByZXNzZWQpOwogIGlmIChGQUlMRUQoaHIpIHx8ICpwcHNDb21wcmVzc2VkID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSVN0cmVhbV9DcmVhdGUoKnBwc0NvbXByZXNzZWQsIChMUEFSQU0pcHNTb3VyY2UsIChMUEFSQU0pYWNvKTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgSUFWSVN0cmVhbV9SZWxlYXNlKCpwcHNDb21wcmVzc2VkKTsKICAgICpwcHNDb21wcmVzc2VkID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGUgICAoQVZJRklMRS4xMDMpCiAqCQlBVklTdHJlYW1PcGVuRnJvbUZpbGVBCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU3RyZWFtT3BlbkZyb21GaWxlQShQQVZJU1RSRUFNICpwcGF2aSwgTFBDU1RSIHN6RmlsZSwKCQkJCSAgICAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtLAoJCQkJICAgICAgVUlOVCBtb2RlLCBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBQQVZJRklMRSBwZmlsZSA9IE5VTEw7CiAgSFJFU1VMVCAgaHI7CgogIFRSQUNFKCIoJXAsJXMsJyU0LjRzJywlbGQsMHglWCwlcylcbiIsIHBwYXZpLCBkZWJ1Z3N0cl9hKHN6RmlsZSksCgkoY2hhciopJmZjY1R5cGUsIGxQYXJhbSwgbW9kZSwgZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKCiAgaHIgPSBBVklGaWxlT3BlbkEoJnBmaWxlLCBzekZpbGUsIG1vZGUsIHBjbHNpZEhhbmRsZXIpOwogIGlmIChGQUlMRUQoaHIpIHx8IHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSUZpbGVfR2V0U3RyZWFtKHBmaWxlLCBwcGF2aSwgZmNjVHlwZSwgbFBhcmFtKTsKICBJQVZJRmlsZV9SZWxlYXNlKHBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbU9wZW5Gcm9tRmlsZVcJKEFWSUZJTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBBVklTdHJlYW1PcGVuRnJvbUZpbGVXKFBBVklTVFJFQU0gKnBwYXZpLCBMUENXU1RSIHN6RmlsZSwKCQkJCSAgICAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtLAoJCQkJICAgICAgVUlOVCBtb2RlLCBMUENMU0lEIHBjbHNpZEhhbmRsZXIpCnsKICBQQVZJRklMRSBwZmlsZSA9IE5VTEw7CiAgSFJFU1VMVCAgaHI7CgogIFRSQUNFKCIoJXAsJXMsJyU0LjRzJywlbGQsMHglWCwlcylcbiIsIHBwYXZpLCBkZWJ1Z3N0cl93KHN6RmlsZSksCgkoY2hhciopJmZjY1R5cGUsIGxQYXJhbSwgbW9kZSwgZGVidWdzdHJfZ3VpZChwY2xzaWRIYW5kbGVyKSk7CgogIGlmIChwcGF2aSA9PSBOVUxMIHx8IHN6RmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwYXZpID0gTlVMTDsKCiAgaHIgPSBBVklGaWxlT3BlblcoJnBmaWxlLCBzekZpbGUsIG1vZGUsIHBjbHNpZEhhbmRsZXIpOwogIGlmIChGQUlMRUQoaHIpIHx8IHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gaHI7CgogIGhyID0gSUFWSUZpbGVfR2V0U3RyZWFtKHBmaWxlLCBwcGF2aSwgZmNjVHlwZSwgbFBhcmFtKTsKICBJQVZJRmlsZV9SZWxlYXNlKHBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVN0YXJ0CQkoQVZJRklMRS4xMzApCiAqCQlBVklTdHJlYW1TdGFydAkJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1TdGFydChQQVZJU1RSRUFNIHBzdHJlYW0pCnsKICBBVklTVFJFQU1JTkZPVyBhc2l3OwoKICBUUkFDRSgiKCVwKVxuIiwgcHN0cmVhbSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gMDsKCiAgaWYgKEZBSUxFRChJQVZJU3RyZWFtX0luZm8ocHN0cmVhbSwgJmFzaXcsIHNpemVvZihhc2l3KSkpKQogICAgcmV0dXJuIDA7CgogIHJldHVybiBhc2l3LmR3U3RhcnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtTGVuZ3RoCQkoQVZJRklMRS4xMzEpCiAqCQlBVklTdHJlYW1MZW5ndGgJCShBVklGSUwzMi5AKQogKi8KTE9ORyBXSU5BUEkgQVZJU3RyZWFtTGVuZ3RoKFBBVklTVFJFQU0gcHN0cmVhbSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXApXG4iLCBwc3RyZWFtKTsKCiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoRkFJTEVEKElBVklTdHJlYW1fSW5mbyhwc3RyZWFtLCAmYXNpdywgc2l6ZW9mKGFzaXcpKSkpCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGFzaXcuZHdMZW5ndGg7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU3RyZWFtU2FtcGxlVG9UaW1lCShBVklGSUxFLjEzMykKICoJCUFWSVN0cmVhbVNhbXBsZVRvVGltZQkoQVZJRklMMzIuQCkKICovCkxPTkcgV0lOQVBJIEFWSVN0cmVhbVNhbXBsZVRvVGltZShQQVZJU1RSRUFNIHBzdHJlYW0sIExPTkcgbFNhbXBsZSkKewogIEFWSVNUUkVBTUlORk9XIGFzaXc7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcHN0cmVhbSwgbFNhbXBsZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAtMTsKICBpZiAoYXNpdy5kd1JhdGUgPT0gMCkKICAgIHJldHVybiAtMTsKCiAgcmV0dXJuIChMT05HKSgoKGZsb2F0KWxTYW1wbGUgKiBhc2l3LmR3U2NhbGUgKiAxMDAwLjApIC8gYXNpdy5kd1JhdGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFWSVN0cmVhbVRpbWVUb1NhbXBsZQkoQVZJRklMRS4xMzIpCiAqCQlBVklTdHJlYW1UaW1lVG9TYW1wbGUJKEFWSUZJTDMyLkApCiAqLwpMT05HIFdJTkFQSSBBVklTdHJlYW1UaW1lVG9TYW1wbGUoUEFWSVNUUkVBTSBwc3RyZWFtLCBMT05HIGxUaW1lKQp7CiAgQVZJU1RSRUFNSU5GT1cgYXNpdzsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBwc3RyZWFtLCBsVGltZSk7CgogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gLTE7CgogIGlmIChGQUlMRUQoSUFWSVN0cmVhbV9JbmZvKHBzdHJlYW0sICZhc2l3LCBzaXplb2YoYXNpdykpKSkKICAgIHJldHVybiAtMTsKICBpZiAoYXNpdy5kd1NjYWxlID09IDApCiAgICByZXR1cm4gLTE7CgogIHJldHVybiAoTE9ORykoKChmbG9hdClsVGltZSAqIGFzaXcuZHdSYXRlKSAvIGFzaXcuZHdTY2FsZSAvIDEwMDAuMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJQnVpbGRGaWx0ZXJBCQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIEFWSUJ1aWxkRmlsdGVyQShMUFNUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgTFBXU1RSICB3c3pGaWx0ZXI7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWQpXG4iLCBzekZpbHRlciwgY2JGaWx0ZXIsIGZTYXZpbmcpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN6RmlsdGVyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChjYkZpbHRlciA8IDIpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIHN6RmlsdGVyWzBdID0gMDsKICBzekZpbHRlclsxXSA9IDA7CgogIHdzekZpbHRlciA9IChMUFdTVFIpR2xvYmFsQWxsb2NQdHIoR0hORCwgY2JGaWx0ZXIpOwogIGlmICh3c3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBociA9IEFWSUJ1aWxkRmlsdGVyVyh3c3pGaWx0ZXIsIGNiRmlsdGVyLCBmU2F2aW5nKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHdzekZpbHRlciwgY2JGaWx0ZXIsCgkJCXN6RmlsdGVyLCBjYkZpbHRlciwgTlVMTCwgTlVMTCk7CiAgfQoKICBHbG9iYWxGcmVlUHRyKHdzekZpbHRlcik7CgogIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklCdWlsZEZpbHRlclcJCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJQnVpbGRGaWx0ZXJXKExQV1NUUiBzekZpbHRlciwgTE9ORyBjYkZpbHRlciwgQk9PTCBmU2F2aW5nKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xzaWRbXSA9IHsnQycsJ0wnLCdTJywnSScsJ0QnLDB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekV4dGVuc2lvbkZtdFtdID0geyc7JywnKicsJy4nLCclJywncycsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QVZJRmlsZUV4dGVuc2lvbnNbXSA9CiAgICB7J0EnLCdWJywnSScsJ0YnLCdpJywnbCcsJ2UnLCdcXCcsJ0UnLCd4JywndCcsJ2UnLCduJywncycsJ2knLCdvJywnbicsJ3MnLDB9OwoKICBBVklGaWx0ZXIgKmxwOwogIFdDSEFSICAgICAgc3pBbGxGaWxlc1s0MF07CiAgV0NIQVIgICAgICBzekZpbGVFeHRbMTBdOwogIFdDSEFSICAgICAgc3pWYWx1ZVsxMjhdOwogIEhLRVkgICAgICAgaEtleTsKICBMT05HICAgICAgIG4sIGk7CiAgTE9ORyAgICAgICBzaXplOwogIExPTkcgICAgICAgY291bnQgPSAwOwoKICBUUkFDRSgiKCVwLCVsZCwlZClcbiIsIHN6RmlsdGVyLCBjYkZpbHRlciwgZlNhdmluZyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3pGaWx0ZXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKGNiRmlsdGVyIDwgMikKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbHAgPSAoQVZJRmlsdGVyKilHbG9iYWxBbGxvY1B0cihHSE5ELCBNQVhfRklMVEVSUyAqIHNpemVvZihBVklGaWx0ZXIpKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKgogICAqIDEuIGl0ZXJhdGUgb3ZlciBIS0VZX0NMQVNTRVNfUk9PVFxcQVZJRmlsZVxcRXh0ZW5zaW9ucyBhbmQgY29sbGVjdAogICAqICAgIGV4dGVuc2lvbnMgYW5kIENMU0lEJ3MKICAgKiAyLiBpdGVyYXRlIG92ZXIgY29sbGVjdGVkIENMU0lEJ3MgYW5kIGNvcHkgaXQncyBkZXNjcmlwdGlvbiBhbmQgaXQncwogICAqICAgIGV4dGVuc2lvbnMgdG8gc3pGaWx0ZXIgaWYgaXQgZml0cwogICAqCiAgICogRmlyc3QgZmlsdGVyIGlzIG5hbWVkICJBbGwgbXVsdGltZWRpYSBmaWxlcyIgYW5kIGl0J3MgZmlsdGVyIGlzIGEKICAgKiBjb2xsZWN0aW9uIG9mIGFsbCBwb3NzaWJsZSBleHRlbnNpb25zIGV4Y2VwdCAiKi4qIi4KICAgKi8KICBpZiAoUmVnT3BlbktleVcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6QVZJRmlsZUV4dGVuc2lvbnMsICZoS2V5KSAhPSBTX09LKSB7CiAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7UmVnRW51bUtleVcoaEtleSwgbiwgc3pGaWxlRXh0LCBzaXplb2Yoc3pGaWxlRXh0KSkgPT0gU19PSztuKyspIHsKICAgIC8qIGdldCBDTFNJRCB0byBleHRlbnNpb24gKi8KICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKHN6VmFsdWVbMF0pOwogICAgaWYgKFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIHN6RmlsZUV4dCwgc3pWYWx1ZSwgJnNpemUpICE9IFNfT0spCiAgICAgIGJyZWFrOwoKICAgIC8qIHNlYXJjaCBpZiB0aGUgQ0xTSUQgaXMgYWxyZWFkeSBrbm93biAqLwogICAgZm9yIChpID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7CiAgICAgIGlmIChsc3RyY21wVyhscFtpXS5zekNsc2lkLCBzelZhbHVlKSA9PSAwKQoJYnJlYWs7IC8qIGEgbmV3IG9uZSAqLwogICAgfQoKICAgIGlmIChjb3VudCAtIGkgPT0gLTEpIHsKICAgICAgLyogaXQncyBhIG5ldyBDTFNJRCAqLwoKICAgICAgLyogRklYTUU6IEhvdyBkbyB3ZSBnZXQgaW5mbydzIGFib3V0IHJlYWQvd3JpdGUgY2FwYWJpbGl0aWVzPyAqLwoKICAgICAgaWYgKGNvdW50ID49IE1BWF9GSUxURVJTKSB7CgkvKiB0cnkgdG8gaW5mb3JtIHVzZXIgb2Ygb3VyIGZ1bGwgZml4ZWQgc2l6ZSB0YWJsZSAqLwoJRVJSKCI6IE1vcmUgdGhhbiAlZCBmaWx0ZXJzIGZvdW5kISBBZGp1c3QgTUFYX0ZJTFRFUlMgaW4gZGxscy9hdmlmaWwzMi9hcGkuY1xuIiwgTUFYX0ZJTFRFUlMpOwoJYnJlYWs7CiAgICAgIH0KCiAgICAgIGxzdHJjcHlXKGxwW2ldLnN6Q2xzaWQsIHN6VmFsdWUpOwoKICAgICAgY291bnQrKzsKICAgIH0KCiAgICAvKiBhcHBlbmQgZXh0ZW5zaW9uIHRvIHRoZSBmaWx0ZXIgKi8KICAgIHdzcHJpbnRmVyhzelZhbHVlLCBzekV4dGVuc2lvbkZtdCwgc3pGaWxlRXh0KTsKICAgIGlmIChscFtpXS5zekV4dGVuc2lvbnNbMF0gPT0gMCkKICAgICAgbHN0cmNhdFcobHBbaV0uc3pFeHRlbnNpb25zLCBzelZhbHVlICsgMSk7CiAgICBlbHNlCiAgICAgIGxzdHJjYXRXKGxwW2ldLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSk7CgogICAgLyogYWxzbyBhcHBlbmQgdG8gdGhlICJhbGwgbXVsdGltZWRpYSItZmlsdGVyICovCiAgICBpZiAobHBbMF0uc3pFeHRlbnNpb25zWzBdID09IDApCiAgICAgIGxzdHJjYXRXKGxwWzBdLnN6RXh0ZW5zaW9ucywgc3pWYWx1ZSArIDEpOwogICAgZWxzZQogICAgICBsc3RyY2F0VyhscFswXS5zekV4dGVuc2lvbnMsIHN6VmFsdWUpOwogIH0KICBSZWdDbG9zZUtleShoS2V5KTsKCiAgLyogMi4gZ2V0IGRlc2NyaXB0aW9ucyBmb3IgdGhlIENMU0lEcyBhbmQgZmlsbCBvdXQgc3pGaWx0ZXIgKi8KICBpZiAoUmVnT3BlbktleVcoSEtFWV9DTEFTU0VTX1JPT1QsIHN6Q2xzaWQsICZoS2V5KSAhPSBTX09LKSB7CiAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgIHJldHVybiBBVklFUlJfRVJST1I7CiAgfQogIGZvciAobiA9IDA7IG4gPD0gY291bnQ7IG4rKykgewogICAgLyogZmlyc3QgdGhlIGRlc2NyaXB0aW9uICovCiAgICBpZiAobiAhPSAwKSB7CiAgICAgIHNpemUgPSBzaXplb2Yoc3pWYWx1ZSkvc2l6ZW9mKHN6VmFsdWVbMF0pOwogICAgICBpZiAoUmVnUXVlcnlWYWx1ZVcoaEtleSwgbHBbbl0uc3pDbHNpZCwgc3pWYWx1ZSwgJnNpemUpID09IFNfT0spIHsKCXNpemUgPSBsc3RybGVuVyhzelZhbHVlKTsKCWxzdHJjcHluVyhzekZpbHRlciwgc3pWYWx1ZSwgY2JGaWx0ZXIpOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgc2l6ZSA9IExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSxJRFNfQUxMTVVMVElNRURJQSxzekZpbHRlcixjYkZpbHRlcik7CgogICAgLyogY2hlY2sgZm9yIGVub3VnaCBzcGFjZSAqLwogICAgc2l6ZSsrOwogICAgaWYgKGNiRmlsdGVyIDwgc2l6ZSArIGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAyKSB7CiAgICAgIHN6RmlsdGVyWzBdID0gMDsKICAgICAgc3pGaWx0ZXJbMV0gPSAwOwogICAgICBHbG9iYWxGcmVlUHRyKGxwKTsKICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICB9CiAgICBjYkZpbHRlciAtPSBzaXplOwogICAgc3pGaWx0ZXIgKz0gc2l6ZTsKCiAgICAvKiBhbmQgdGhlbiB0aGUgZmlsdGVyICovCiAgICBsc3RyY3B5blcoc3pGaWx0ZXIsIGxwW25dLnN6RXh0ZW5zaW9ucywgY2JGaWx0ZXIpOwogICAgc2l6ZSA9IGxzdHJsZW5XKGxwW25dLnN6RXh0ZW5zaW9ucykgKyAxOwogICAgY2JGaWx0ZXIgLT0gc2l6ZTsKICAgIHN6RmlsdGVyICs9IHNpemU7CiAgfQoKICBSZWdDbG9zZUtleShoS2V5KTsKICBHbG9iYWxGcmVlUHRyKGxwKTsKCiAgLyogYWRkICJBbGwgZmlsZXMiICIqLioiIGZpbHRlciBpZiBlbm91Z2ggc3BhY2UgbGVmdCAqLwogIHNpemUgPSBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BTExGSUxFUywKCQkgICAgIHN6QWxsRmlsZXMsIHNpemVvZihzekFsbEZpbGVzKSkgKyAxOwogIGlmIChjYkZpbHRlciA+IHNpemUpIHsKICAgIGludCBpOwoKICAgIC8qIHJlcGxhY2UgJ0AnIHdpdGggXDAwMCB0byBzZXBlcmF0ZSBkZXNjcmlwdGlvbiBvZiBmaWx0ZXIgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBzaXplICYmIHN6QWxsRmlsZXNbaV0gIT0gMDsgaSsrKSB7CiAgICAgIGlmIChzekFsbEZpbGVzW2ldID09ICdAJykgewoJc3pBbGxGaWxlc1tpXSA9IDA7CglicmVhazsKICAgICAgfQogICAgfQogICAgICAKICAgIG1lbWNweShzekZpbHRlciwgc3pBbGxGaWxlcywgc2l6ZSAqIHNpemVvZihzekFsbEZpbGVzWzBdKSk7CiAgICBzekZpbHRlciArPSBzaXplOwogICAgc3pGaWx0ZXJbMF0gPSAwOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIHN6RmlsdGVyWzBdID0gMDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQp9CgpzdGF0aWMgQk9PTCBBVklTYXZlT3B0aW9uc0ZtdENob29zZShIV05EIGhXbmQpCnsKICBMUEFWSUNPTVBSRVNTT1BUSU9OUyBwT3B0aW9ucyA9IFNhdmVPcHRzLnBwT3B0aW9uc1tTYXZlT3B0cy5uQ3VycmVudF07CiAgQVZJU1RSRUFNSU5GT1cgICAgICAgc0luZm87CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaWYgKHBPcHRpb25zID09IE5VTEwgfHwgU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSA9PSBOVUxMKSB7CiAgICBFUlIoIjogYmFkIHN0YXRlIVxuIik7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICBpZiAoRkFJTEVEKEFWSVN0cmVhbUluZm9XKFNhdmVPcHRzLnBwYXZpc1tTYXZlT3B0cy5uQ3VycmVudF0sCgkJCSAgICAmc0luZm8sIHNpemVvZihzSW5mbykpKSkgewogICAgRVJSKCI6IEFWSVN0cmVhbUluZm9XIGZhaWxlZCFcbiIpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgaWYgKHNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICBDT01QVkFSUyBjdjsKICAgIEJPT0wgICAgIHJldDsKCiAgICBtZW1zZXQoJmN2LCAwLCBzaXplb2YoY3YpKTsKCiAgICBpZiAoKHBPcHRpb25zLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX1ZBTElEKSA9PSAwKSB7CiAgICAgIG1lbXNldChwT3B0aW9ucywgMCwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgICBwT3B0aW9ucy0+ZmNjVHlwZSAgICA9IHN0cmVhbXR5cGVWSURFTzsKICAgICAgcE9wdGlvbnMtPmZjY0hhbmRsZXIgPSBjb21wdHlwZURJQjsKICAgICAgcE9wdGlvbnMtPmR3UXVhbGl0eSAgPSBJQ1FVQUxJVFlfREVGQVVMVDsKICAgIH0KCiAgICBjdi5jYlNpemUgICAgID0gc2l6ZW9mKGN2KTsKICAgIGN2LmR3RmxhZ3MgICAgPSBJQ01GX0NPTVBWQVJTX1ZBTElEOwogICAgLypjdi5mY2NUeXBlICAgID0gcE9wdGlvbnMtPmZjY1R5cGU7ICovCiAgICBjdi5mY2NIYW5kbGVyID0gcE9wdGlvbnMtPmZjY0hhbmRsZXI7CiAgICBjdi5sUSAgICAgICAgID0gcE9wdGlvbnMtPmR3UXVhbGl0eTsKICAgIGN2LmxwU3RhdGUgICAgPSBwT3B0aW9ucy0+bHBQYXJtczsKICAgIGN2LmNiU3RhdGUgICAgPSBwT3B0aW9ucy0+Y2JQYXJtczsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9LRVlGUkFNRVMpCiAgICAgIGN2LmxLZXkgPSBwT3B0aW9ucy0+ZHdLZXlGcmFtZUV2ZXJ5OwogICAgZWxzZQogICAgICBjdi5sS2V5ID0gMDsKICAgIGlmIChwT3B0aW9ucy0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9EQVRBUkFURSkKICAgICAgY3YubERhdGFSYXRlID0gcE9wdGlvbnMtPmR3Qnl0ZXNQZXJTZWNvbmQgLyAxMDI0OyAvKiBuZWVkIGtCeXRlcyAqLwogICAgZWxzZQogICAgICBjdi5sRGF0YVJhdGUgPSAwOwoKICAgIHJldCA9IElDQ29tcHJlc3NvckNob29zZShoV25kLCBTYXZlT3B0cy51RmxhZ3MsIE5VTEwsCgkJCSAgICAgU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwgJmN2LCBOVUxMKTsKCiAgICBpZiAocmV0KSB7CiAgICAgIHBPcHRpb25zLT5scFBhcm1zICAgPSBjdi5scFN0YXRlOwogICAgICBwT3B0aW9ucy0+Y2JQYXJtcyAgID0gY3YuY2JTdGF0ZTsKICAgICAgcE9wdGlvbnMtPmR3UXVhbGl0eSA9IGN2LmxROwogICAgICBpZiAoY3YubEtleSAhPSAwKSB7CglwT3B0aW9ucy0+ZHdLZXlGcmFtZUV2ZXJ5ID0gY3YubEtleTsKCXBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9LRVlGUkFNRVM7CiAgICAgIH0gZWxzZQoJcE9wdGlvbnMtPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9LRVlGUkFNRVM7CiAgICAgIGlmIChjdi5sRGF0YVJhdGUgIT0gMCkgewoJcE9wdGlvbnMtPmR3Qnl0ZXNQZXJTZWNvbmQgPSBjdi5sRGF0YVJhdGUgKiAxMDI0OyAvKiBuZWVkIGJ5dGVzICovCglwT3B0aW9ucy0+ZHdGbGFncyB8PSBBVklDT01QUkVTU0ZfREFUQVJBVEU7CiAgICAgIH0gZWxzZQoJcE9wdGlvbnMtPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9EQVRBUkFURTsKICAgICAgcE9wdGlvbnMtPmR3RmxhZ3MgIHw9IEFWSUNPTVBSRVNTRl9WQUxJRDsKICAgIH0KICAgIElDQ29tcHJlc3NvckZyZWUoJmN2KTsKCiAgICByZXR1cm4gcmV0OwogIH0gZWxzZSBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIEFDTUZPUk1BVENIT09TRVcgYWZtdGM7CiAgICBNTVJFU1VMVCAgICAgICAgIHJldDsKICAgIExPTkcgICAgICAgICAgICAgc2l6ZTsKCiAgICAvKiBGSVhNRTogY2hlY2sgQUNNIHZlcnNpb24gLS0gV2hpY2ggdmVyc2lvbiBpcyBuZWVkZWQ/ICovCgogICAgbWVtc2V0KCZhZm10YywgMCwgc2l6ZW9mKGFmbXRjKSk7CiAgICBhZm10Yy5jYlN0cnVjdCAgPSBzaXplb2YoYWZtdGMpOwogICAgYWZtdGMuZmR3U3R5bGUgID0gMDsKICAgIGFmbXRjLmh3bmRPd25lciA9IGhXbmQ7CgogICAgYWNtTWV0cmljcyhOVUxMLCBBQ01fTUVUUklDX01BWF9TSVpFX0ZPUk1BVCwgJnNpemUpOwogICAgaWYgKChwT3B0aW9ucy0+Y2JGb3JtYXQgPT0gMCB8fCBwT3B0aW9ucy0+bHBGb3JtYXQgPT0gTlVMTCkgJiYgc2l6ZSAhPSAwKSB7CiAgICAgIHBPcHRpb25zLT5scEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIHNpemUpOwogICAgICBwT3B0aW9ucy0+Y2JGb3JtYXQgPSBzaXplOwogICAgfSBlbHNlIGlmIChwT3B0aW9ucy0+Y2JGb3JtYXQgPCBzaXplKSB7CiAgICAgIHBPcHRpb25zLT5scEZvcm1hdCA9IEdsb2JhbFJlQWxsb2NQdHIocE9wdGlvbnMtPmxwRm9ybWF0LCBzaXplLCBHTUVNX01PVkVBQkxFKTsKICAgICAgcE9wdGlvbnMtPmNiRm9ybWF0ID0gc2l6ZTsKICAgIH0KICAgIGlmIChwT3B0aW9ucy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwogICAgYWZtdGMucHdmeCAgPSBwT3B0aW9ucy0+bHBGb3JtYXQ7CiAgICBhZm10Yy5jYndmeCA9IHBPcHRpb25zLT5jYkZvcm1hdDsKCiAgICBzaXplID0gMDsKICAgIEFWSVN0cmVhbUZvcm1hdFNpemUoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSwKCQkJc0luZm8uZHdTdGFydCwgJnNpemUpOwogICAgaWYgKHNpemUgPCBzaXplb2YoUENNV0FWRUZPUk1BVCkpCiAgICAgIHNpemUgPSBzaXplb2YoUENNV0FWRUZPUk1BVCk7CiAgICBhZm10Yy5wd2Z4RW51bSA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUpOwogICAgaWYgKGFmbXRjLnB3ZnhFbnVtICE9IE5VTEwpIHsKICAgICAgQVZJU3RyZWFtUmVhZEZvcm1hdChTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLAoJCQkgIHNJbmZvLmR3U3RhcnQsIGFmbXRjLnB3ZnhFbnVtLCAmc2l6ZSk7CiAgICAgIGFmbXRjLmZkd0VudW0gPSBBQ01fRk9STUFURU5VTUZfQ09OVkVSVDsKICAgIH0KCiAgICByZXQgPSBhY21Gb3JtYXRDaG9vc2VXKCZhZm10Yyk7CiAgICBpZiAocmV0ID09IFNfT0spCiAgICAgIHBPcHRpb25zLT5kd0ZsYWdzIHw9IEFWSUNPTVBSRVNTRl9WQUxJRDsKCiAgICBpZiAoYWZtdGMucHdmeEVudW0gIT0gTlVMTCkKICAgICAgR2xvYmFsRnJlZVB0cihhZm10Yy5wd2Z4RW51bSk7CgogICAgcmV0dXJuIChyZXQgPT0gU19PSyA/IFRSVUUgOiBGQUxTRSk7CiAgfSBlbHNlIHsKICAgIEVSUigiOiB1bmtub3duIHN0cmVhbXR5cGUgMHglMDhsWFxuIiwgc0luZm8uZmNjVHlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQp9CgpzdGF0aWMgdm9pZCBBVklTYXZlT3B0aW9uc1VwZGF0ZShIV05EIGhXbmQpCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pWaWRlb0ZtdFtdPXsnJScsJ2wnLCdkJywneCcsJyUnLCdsJywnZCcsJ3gnLCclJywnZCcsMH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QXVkaW9GbXRbXT17JyUnLCdzJywnICcsJyUnLCdzJywwfTsKCiAgV0NIQVIgICAgICAgICAgc3pGb3JtYXRbMTI4XTsKICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKICBMUFZPSUQgICAgICAgICBscEZvcm1hdDsKICBMT05HICAgICAgICAgICBzaXplOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIFNhdmVPcHRzLm5DdXJyZW50ID0gU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLElEQ19TVFJFQU0sQ0JfR0VUQ1VSU0VMLDAsMCk7CiAgaWYgKFNhdmVPcHRzLm5DdXJyZW50IDwgMCkKICAgIHJldHVybjsKCiAgaWYgKEZBSUxFRChBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLCAmc0luZm8sIHNpemVvZihzSW5mbykpKSkKICAgIHJldHVybjsKCiAgQVZJU3RyZWFtRm9ybWF0U2l6ZShTYXZlT3B0cy5wcGF2aXNbU2F2ZU9wdHMubkN1cnJlbnRdLHNJbmZvLmR3U3RhcnQsJnNpemUpOwogIGlmIChzaXplID4gMCkgewogICAgc3pGb3JtYXRbMF0gPSAwOwoKICAgIC8qIHJlYWQgZm9ybWF0IHRvIGJ1aWxkIGZvcm1hdCBkZXNjcmlvdGlvbiBzdHJpbmcgKi8KICAgIGxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgc2l6ZSk7CiAgICBpZiAobHBGb3JtYXQgIT0gTlVMTCkgewogICAgICBpZiAoU1VDQ0VFREVEKEFWSVN0cmVhbVJlYWRGb3JtYXQoU2F2ZU9wdHMucHBhdmlzW1NhdmVPcHRzLm5DdXJyZW50XSxzSW5mby5kd1N0YXJ0LGxwRm9ybWF0LCAmc2l6ZSkpKSB7CglpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKCSAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSBscEZvcm1hdDsKCSAgSUNJTkZPIGljaW5mbzsKCgkgIHdzcHJpbnRmVyhzekZvcm1hdCwgc3pWaWRlb0ZtdCwgbHBiaS0+YmlXaWR0aCwKCQkgICAgbHBiaS0+YmlIZWlnaHQsIGxwYmktPmJpQml0Q291bnQpOwoKCSAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCKSB7CgkgICAgSElDICAgIGhpYzsKCgkgICAgaGljID0gSUNMb2NhdGUoSUNUWVBFX1ZJREVPLCBzSW5mby5mY2NIYW5kbGVyLCBscEZvcm1hdCwKCQkJICAgTlVMTCwgSUNNT0RFX0RFQ09NUFJFU1MpOwoJICAgIGlmIChoaWMgIT0gTlVMTCkgewoJICAgICAgaWYgKElDR2V0SW5mbyhoaWMsICZpY2luZm8sIHNpemVvZihpY2luZm8pKSA9PSBTX09LKQoJCWxzdHJjYXRXKHN6Rm9ybWF0LCBpY2luZm8uc3pEZXNjcmlwdGlvbik7CgkgICAgICBJQ0Nsb3NlKGhpYyk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1VOQ09NUFJFU1NFRCwKCQkJaWNpbmZvLnN6RGVzY3JpcHRpb24sIHNpemVvZihpY2luZm8uc3pEZXNjcmlwdGlvbikpOwoJICAgIGxzdHJjYXRXKHN6Rm9ybWF0LCBpY2luZm8uc3pEZXNjcmlwdGlvbik7CgkgIH0KCX0gZWxzZSBpZiAoc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKCSAgQUNNRk9STUFUVEFHREVUQUlMU1cgYWZ0ZDsKCSAgQUNNRk9STUFUREVUQUlMU1cgICAgYWZkOwoKCSAgbWVtc2V0KCZhZnRkLCAwLCBzaXplb2YoYWZ0ZCkpOwoJICBtZW1zZXQoJmFmZCwgMCwgc2l6ZW9mKGFmZCkpOwoKCSAgYWZ0ZC5jYlN0cnVjdCAgICAgPSBzaXplb2YoYWZ0ZCk7CgkgIGFmdGQuZHdGb3JtYXRUYWcgID0gYWZkLmR3Rm9ybWF0VGFnID0KCSAgICAoKFBXQVZFRk9STUFURVgpbHBGb3JtYXQpLT53Rm9ybWF0VGFnOwoJICBhZnRkLmNiRm9ybWF0U2l6ZSA9IGFmZC5jYndmeCA9IHNpemU7CgoJICBhZmQuY2JTdHJ1Y3QgICAgICA9IHNpemVvZihhZmQpOwoJICBhZmQucHdmeCAgICAgICAgICA9IGxwRm9ybWF0OwoKCSAgaWYgKGFjbUZvcm1hdFRhZ0RldGFpbHNXKE5VTEwsICZhZnRkLAoJCQkJICAgQUNNX0ZPUk1BVFRBR0RFVEFJTFNGX0ZPUk1BVFRBRykgPT0gU19PSykgewoJICAgIGlmIChhY21Gb3JtYXREZXRhaWxzVyhOVUxMLCZhZmQsQUNNX0ZPUk1BVERFVEFJTFNGX0ZPUk1BVCkgPT0gU19PSykKCSAgICAgIHdzcHJpbnRmVyhzekZvcm1hdCwgc3pBdWRpb0ZtdCwgYWZkLnN6Rm9ybWF0LCBhZnRkLnN6Rm9ybWF0VGFnKTsKCSAgfQoJfQogICAgICB9CiAgICAgIEdsb2JhbEZyZWVQdHIobHBGb3JtYXQpOwogICAgfQoKICAgIC8qIHNldCB0ZXh0IGZvciBmb3JtYXQgZGVzY3JpcHRpb24gKi8KICAgIFNldERsZ0l0ZW1UZXh0VyhoV25kLCBJRENfRk9STUFUVEVYVCwgc3pGb3JtYXQpOwoKICAgIC8qIERpc2FibGUgb3B0aW9uIGJ1dHRvbiBmb3IgdW5zdXBwb3J0ZWQgc3RyZWFtdHlwZXMgKi8KICAgIGlmIChzSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTyB8fAoJc0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19PUFRJT05TKSwgVFJVRSk7CiAgICBlbHNlCiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19PUFRJT05TKSwgRkFMU0UpOwogIH0KCn0KCklOVF9QVFIgQ0FMTEJBQ0sgQVZJU2F2ZU9wdGlvbnNEbGdQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLAoJCQkJICAgIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICBEV09SRCBkd0ludGVybGVhdmU7CiAgQk9PTCAgYklzSW50ZXJsZWF2ZWQ7CiAgSU5UICAgbjsKCiAgLypUUkFDRSgiKCVwLCV1LDB4JTA0WCwweCUwOGxYKVxuIiwgaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOyovCgogIHN3aXRjaCAodU1zZykgewogIGNhc2UgV01fSU5JVERJQUxPRzoKICAgIFNhdmVPcHRzLm5DdXJyZW50ID0gMDsKICAgIGlmIChTYXZlT3B0cy5uU3RyZWFtcyA9PSAxKSB7CiAgICAgIEVuZERpYWxvZyhoV25kLCBBVklTYXZlT3B0aW9uc0ZtdENob29zZShoV25kKSk7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBhZGQgc3RyZWFtcyAqLwogICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKICAgICAgQVZJU1RSRUFNSU5GT1cgc0luZm87CgogICAgICBBVklTdHJlYW1JbmZvVyhTYXZlT3B0cy5wcGF2aXNbbl0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CiAgICAgIFNlbmREbGdJdGVtTWVzc2FnZVcoaFduZCwgSURDX1NUUkVBTSwgQ0JfQUREU1RSSU5HLAoJCQkgIDBMLCAoTFBBUkFNKXNJbmZvLnN6TmFtZSk7CiAgICB9CgogICAgLyogc2VsZWN0IGZpcnN0IHN0cmVhbSAqLwogICAgU2VuZERsZ0l0ZW1NZXNzYWdlVyhoV25kLCBJRENfU1RSRUFNLCBDQl9TRVRDVVJTRUwsIDAsIDApOwogICAgU2VuZE1lc3NhZ2VXKGhXbmQsIFdNX0NPTU1BTkQsCgkJIEdFVF9XTV9DT01NQU5EX01QUyhJRENfU1RSRUFNLCBoV25kLCBDQk5fU0VMQ0hBTkdFKSk7CgogICAgLyogaW5pdGlhbGl6ZSBpbnRlcmxlYXZlICovCiAgICBpZiAoU2F2ZU9wdHMucHBPcHRpb25zWzBdICE9IE5VTEwgJiYKCShTYXZlT3B0cy5wcE9wdGlvbnNbMF0tPmR3RmxhZ3MgJiBBVklDT01QUkVTU0ZfVkFMSUQpKSB7CiAgICAgIGJJc0ludGVybGVhdmVkID0gKFNhdmVPcHRzLnBwT3B0aW9uc1swXS0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9JTlRFUkxFQVZFKTsKICAgICAgZHdJbnRlcmxlYXZlID0gU2F2ZU9wdHMucHBPcHRpb25zWzBdLT5kd0ludGVybGVhdmVFdmVyeTsKICAgIH0gZWxzZSB7CiAgICAgIGJJc0ludGVybGVhdmVkID0gVFJVRTsKICAgICAgZHdJbnRlcmxlYXZlICAgPSAwOwogICAgfQogICAgQ2hlY2tEbGdCdXR0b24oaFduZCwgSURDX0lOVEVSTEVBVkUsIGJJc0ludGVybGVhdmVkKTsKICAgIFNldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgZHdJbnRlcmxlYXZlLCBGQUxTRSk7CiAgICBFbmFibGVXaW5kb3coR2V0RGxnSXRlbShoV25kLCBJRENfSU5URVJMRUFWRUVWRVJZKSwgYklzSW50ZXJsZWF2ZWQpOwogICAgYnJlYWs7CiAgY2FzZSBXTV9DT01NQU5EOgogICAgc3dpdGNoIChHRVRfV01fQ09NTUFORF9DTUQod1BhcmFtLCBsUGFyYW0pKSB7CiAgICBjYXNlIElET0s6CiAgICAgIC8qIGdldCBkYXRhIGZyb20gY29udHJvbHMgYW5kIHNhdmUgdGhlbSAqLwogICAgICBkd0ludGVybGVhdmUgICA9IEdldERsZ0l0ZW1JbnQoaFduZCwgSURDX0lOVEVSTEVBVkVFVkVSWSwgTlVMTCwgMCk7CiAgICAgIGJJc0ludGVybGVhdmVkID0gSXNEbGdCdXR0b25DaGVja2VkKGhXbmQsIElEQ19JTlRFUkxFQVZFKTsKICAgICAgZm9yIChuID0gMDsgbiA8IFNhdmVPcHRzLm5TdHJlYW1zOyBuKyspIHsKCWlmIChTYXZlT3B0cy5wcE9wdGlvbnNbbl0gIT0gTlVMTCkgewoJICBpZiAoYklzSW50ZXJsZWF2ZWQpIHsKCSAgICBTYXZlT3B0cy5wcE9wdGlvbnNbbl0tPmR3RmxhZ3MgfD0gQVZJQ09NUFJFU1NGX0lOVEVSTEVBVkU7CgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ludGVybGVhdmVFdmVyeSA9IGR3SW50ZXJsZWF2ZTsKCSAgfSBlbHNlCgkgICAgU2F2ZU9wdHMucHBPcHRpb25zW25dLT5kd0ZsYWdzICY9IH5BVklDT01QUkVTU0ZfSU5URVJMRUFWRTsKCX0KICAgICAgfQogICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgSURDQU5DRUw6CiAgICAgIEVuZERpYWxvZyhoV25kLCBHRVRfV01fQ09NTUFORF9DTUQod1BhcmFtLCBsUGFyYW0pID09IElET0spOwogICAgICBicmVhazsKICAgIGNhc2UgSURDX0lOVEVSTEVBVkU6CiAgICAgIEVuYWJsZVdpbmRvdyhHZXREbGdJdGVtKGhXbmQsIElEQ19JTlRFUkxFQVZFRVZFUlkpLAoJCSAgIElzRGxnQnV0dG9uQ2hlY2tlZChoV25kLCBJRENfSU5URVJMRUFWRSkpOwogICAgICBicmVhazsKICAgIGNhc2UgSURDX1NUUkVBTToKICAgICAgaWYgKEdFVF9XTV9DT01NQU5EX0NNRCh3UGFyYW0sIGxQYXJhbSkgPT0gQ0JOX1NFTENIQU5HRSkgewoJLyogdXBkYXRlIGNvbnRyb2wgZWxlbWVudHMgKi8KCUFWSVNhdmVPcHRpb25zVXBkYXRlKGhXbmQpOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBJRENfT1BUSU9OUzoKICAgICAgQVZJU2F2ZU9wdGlvbnNGbXRDaG9vc2UoaFduZCk7CiAgICAgIGJyZWFrOwogICAgfTsKICAgIHJldHVybiBGQUxTRTsKICB9OwoKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBVklTYXZlT3B0aW9ucwkJKEFWSUZJTDMyLkApCiAqLwpCT09MIFdJTkFQSSBBVklTYXZlT3B0aW9ucyhIV05EIGhXbmQsIFVJTlQgdUZsYWdzLCBJTlQgblN0cmVhbXMsCgkJCSAgIFBBVklTVFJFQU0gKnBwYXZpLCBMUEFWSUNPTVBSRVNTT1BUSU9OUyAqcHBPcHRpb25zKQp7CiAgTFBBVklDT01QUkVTU09QVElPTlMgcFNhdmVkT3B0aW9ucyA9IE5VTEw7CiAgSU5UIHJldCwgbjsKCiAgVFJBQ0UoIiglcCwweCVYLCVkLCVwLCVwKVxuIiwgaFduZCwgdUZsYWdzLCBuU3RyZWFtcywKCXBwYXZpLCBwcE9wdGlvbnMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKG5TdHJlYW1zIDw9IDAgfHwgcHBhdmkgPT0gTlVMTCB8fCBwcE9wdGlvbnMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIHNhdmUgb3B0aW9ucyBmb3IgY2FzZSB1c2VyIHByZXNzIGNhbmNlbCAqLwogIGlmIChwcE9wdGlvbnMgIT0gTlVMTCAmJiBuU3RyZWFtcyA+IDEpIHsKICAgIHBTYXZlZE9wdGlvbnMgPSBHbG9iYWxBbGxvY1B0cihHSE5ELG5TdHJlYW1zICogc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgaWYgKHBTYXZlZE9wdGlvbnMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAobiA9IDA7IG4gPCBuU3RyZWFtczsgbisrKSB7CiAgICAgIGlmIChwcE9wdGlvbnNbbl0gIT0gTlVMTCkKCW1lbWNweShwU2F2ZWRPcHRpb25zICsgbiwgcHBPcHRpb25zW25dLCBzaXplb2YoQVZJQ09NUFJFU1NPUFRJT05TKSk7CiAgICB9CiAgfQoKICBTYXZlT3B0cy51RmxhZ3MgICAgPSB1RmxhZ3M7CiAgU2F2ZU9wdHMublN0cmVhbXMgID0gblN0cmVhbXM7CiAgU2F2ZU9wdHMucHBhdmlzICAgID0gcHBhdmk7CiAgU2F2ZU9wdHMucHBPcHRpb25zID0gcHBPcHRpb25zOwoKICByZXQgPSBEaWFsb2dCb3hXKEFWSUZJTEVfaE1vZHVsZSwgTUFLRUlOVFJFU09VUkNFVyhJRERfU0FWRU9QVElPTlMpLAoJCSAgIGhXbmQsIEFWSVNhdmVPcHRpb25zRGxnUHJvYyk7CgogIGlmIChyZXQgPT0gLTEpCiAgICByZXQgPSBGQUxTRTsKCiAgLyogcmVzdG9yZSBvcHRpb25zIHdoZW4gdXNlciBwcmVzc2VkIGNhbmNlbCAqLwogIGlmIChwU2F2ZWRPcHRpb25zICE9IE5VTEwgJiYgcmV0ID09IEZBTFNFKSB7CiAgICBmb3IgKG4gPSAwOyBuIDwgblN0cmVhbXM7IG4rKykgewogICAgICBpZiAocHBPcHRpb25zW25dICE9IE5VTEwpCgltZW1jcHkocHBPcHRpb25zW25dLCBwU2F2ZWRPcHRpb25zICsgbiwgc2l6ZW9mKEFWSUNPTVBSRVNTT1BUSU9OUykpOwogICAgfQogICAgR2xvYmFsRnJlZVB0cihwU2F2ZWRPcHRpb25zKTsKICB9CgogIHJldHVybiAoQk9PTClyZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQVZJU2F2ZU9wdGlvbnNGcmVlCShBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJU2F2ZU9wdGlvbnNGcmVlKElOVCBuU3RyZWFtcyxMUEFWSUNPTVBSRVNTT1BUSU9OUypwcE9wdGlvbnMpCnsKICBUUkFDRSgiKCVkLCVwKVxuIiwgblN0cmVhbXMsIHBwT3B0aW9ucyk7CgogIGlmIChuU3RyZWFtcyA8IDAgfHwgcHBPcHRpb25zID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBmb3IgKDsgblN0cmVhbXMgPiAwOyBuU3RyZWFtcy0tKSB7CiAgICBpZiAocHBPcHRpb25zW25TdHJlYW1zXSAhPSBOVUxMKSB7CiAgICAgIHBwT3B0aW9uc1tuU3RyZWFtc10tPmR3RmxhZ3MgJj0gfkFWSUNPTVBSRVNTRl9WQUxJRDsKCiAgICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zICE9IE5VTEwpIHsKCUdsb2JhbEZyZWVQdHIocHBPcHRpb25zW25TdHJlYW1zXS0+bHBQYXJtcyk7CglwcE9wdGlvbnNbblN0cmVhbXNdLT5scFBhcm1zID0gTlVMTDsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmNiUGFybXMgPSAwOwogICAgICB9CiAgICAgIGlmIChwcE9wdGlvbnNbblN0cmVhbXNdLT5scEZvcm1hdCAhPSBOVUxMKSB7CglHbG9iYWxGcmVlUHRyKHBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0KTsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmxwRm9ybWF0ID0gTlVMTDsKCXBwT3B0aW9uc1tuU3RyZWFtc10tPmNiRm9ybWF0ID0gMDsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQo=