LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnZlci5oIgojaW5jbHVkZSAid2lubmV0d2suaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgImNvbW1kbGcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKTsKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBEV09SRCBTSExXQVBJX1RocmVhZFJlZl9pbmRleDsKCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZShJVW5rbm93biosUkVGR1VJRCxSRUZJSUQsTFBWT0lEKik7CkhSRVNVTFQgV0lOQVBJIFNISW52b2tlQ29tbWFuZChIV05ELElTaGVsbEZvbGRlciosTFBDSVRFTUlETElTVCxCT09MKTsKQk9PTCAgICBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUixEV09SRCk7CgovKgogTk9URVM6IE1vc3QgZnVuY3Rpb25zIGV4cG9ydGVkIGJ5IG9yZGluYWwgc2VlbSB0byBiZSBzdXBlcmZsb3VzLgogVGhlIHJlYXNvbiBmb3IgdGhlc2UgZnVuY3Rpb25zIHRvIGJlIHRoZXJlIGlzIHRvIHByb3ZpZGUgYSB3cmFwcGVyCiBmb3IgdW5pY29kZSBmdW5jdGlvbnMgdG8gcHJvdmlkZSB0aGVzZSBmdW5jdGlvbnMgb24gc3lzdGVtcyB3aXRob3V0CiB1bmljb2RlIGZ1bmN0aW9ucyBlZy4gd2luOTUvd2luOTguIFNpbmNlIHdlIGhhdmUgc3VjaCBmdW5jdGlvbnMgd2UganVzdAogY2FsbCB0aGVzZS4gSWYgcnVubmluZyBXaW5lIHdpdGggbmF0aXZlIERMTHMsIHNvbWUgbGF0ZSBib3VuZCBjYWxscyBtYXkKIGZhaWwuIEhvd2V2ZXIsIGl0IGlzIGJldHRlciB0byBpbXBsZW1lbnQgdGhlIGZ1bmN0aW9ucyBpbiB0aGUgZm9yd2FyZCBETEwKIGFuZCByZWNvbW1lbmQgdGhlIGJ1aWx0aW4gcmF0aGVyIHRoYW4gcmVpbXBsZW1lbnRpbmcgdGhlIGNhbGxzIGhlcmUhCiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZQogKgogKiBJbnRlcm5hbCBpbXBsZW1ldGF0aW9uIG9mIFNITFdBUElfMTEuCiAqLwpzdGF0aWMKSEFORExFIFdJTkFQSSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3JjUHJvY0lkLCBEV09SRCBkd0FjY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhEc3QsIGhTcmM7CiAgRFdPUkQgZHdNeVByb2NJZCA9IEdldEN1cnJlbnRQcm9jZXNzSWQoKTsKICBIQU5ETEUgaFJldCA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJWQsJWQsJTA4eCwlMDh4KVxuIiwgaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwoKICAvKiBHZXQgZGVzdCBwcm9jZXNzIGhhbmRsZSAqLwogIGlmIChkd0RzdFByb2NJZCA9PSBkd015UHJvY0lkKQogICAgaERzdCA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgZWxzZQogICAgaERzdCA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdEc3RQcm9jSWQpOwoKICBpZiAoaERzdCkKICB7CiAgICAvKiBHZXQgc3JjIHByb2Nlc3MgaGFuZGxlICovCiAgICBpZiAoZHdTcmNQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgICAgaFNyYyA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgICBlbHNlCiAgICAgIGhTcmMgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3U3JjUHJvY0lkKTsKCiAgICBpZiAoaFNyYykKICAgIHsKICAgICAgLyogTWFrZSBoYW5kbGUgYXZhaWxhYmxlIHRvIGRlc3QgcHJvY2VzcyAqLwogICAgICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShoRHN0LCBoU2hhcmVkLCBoU3JjLCAmaFJldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdBY2Nlc3MsIDAsIGR3T3B0aW9ucyB8IERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICAgICAgaFJldCA9IE5VTEw7CgogICAgICBpZiAoZHdTcmNQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgICBDbG9zZUhhbmRsZShoU3JjKTsKICAgIH0KCiAgICBpZiAoZHdEc3RQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgQ2xvc2VIYW5kbGUoaERzdCk7CiAgfQoKICBUUkFDRSgiUmV0dXJuaW5nIGhhbmRsZSAlcFxuIiwgaFJldCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjddCiAqCiAqIENyZWF0ZSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeSBhbmQgaW5pdGlhbGlzZSBpdCB3aXRoIGRhdGEuCiAqCiAqIFBBUkFNUwogKiBscHZEYXRhICBbSV0gUG9pbnRlciB0byBkYXRhIHRvIHdyaXRlCiAqIGR3U2l6ZSAgIFtJXSBTaXplIG9mIGRhdGEKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGRhdGEKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogT3JkaW5hbHMgNy0xMSBwcm92aWRlIGEgc2V0IG9mIGNhbGxzIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IGJldHdlZW4gYQogKiBncm91cCBvZiBwcm9jZXNzZXMuIFRoZSBzaGFyZWQgbWVtb3J5IGlzIHRyZWF0ZWQgb3BhcXVlbHkgaW4gdGhhdCBpdHMgc2l6ZQogKiBpcyBub3QgZXhwb3NlZCB0byBjbGllbnRzIHdobyBtYXAgaXQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHN0b3JpbmcKICogdGhlIHNpemUgb2YgdGhlIG1hcCBhcyB0aGUgZmlyc3QgRFdPUkQgb2YgbWFwcGVkIGRhdGEsIGFuZCB0aGVuIG9mZnNldHRpbmcKICogdGhlIHZpZXcgcG9pbnRlciByZXR1cm5lZCBieSB0aGlzIHNpemUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNIQWxsb2NTaGFyZWQoTFBDVk9JRCBscHZEYXRhLCBEV09SRCBkd1NpemUsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhNYXA7CiAgTFBWT0lEIHBNYXBwZWQ7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgbHB2RGF0YSwgZHdTaXplLCBkd1Byb2NJZCk7CgogIC8qIENyZWF0ZSBmaWxlIG1hcHBpbmcgb2YgdGhlIGNvcnJlY3QgbGVuZ3RoICovCiAgaE1hcCA9IENyZWF0ZUZpbGVNYXBwaW5nQShJTlZBTElEX0hBTkRMRV9WQUxVRSwgTlVMTCwgRklMRV9NQVBfUkVBRCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3U2l6ZSArIHNpemVvZihkd1NpemUpLCBOVUxMKTsKICBpZiAoIWhNYXApCiAgICByZXR1cm4gaFJldDsKCiAgLyogR2V0IGEgdmlldyBpbiBvdXIgcHJvY2VzcyBhZGRyZXNzIHNwYWNlICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoaE1hcCwgRklMRV9NQVBfUkVBRCB8IEZJTEVfTUFQX1dSSVRFLCAwLCAwLCAwKTsKCiAgaWYgKHBNYXBwZWQpCiAgewogICAgLyogV3JpdGUgc2l6ZSBvZiBkYXRhLCBmb2xsb3dlZCBieSB0aGUgZGF0YSwgdG8gdGhlIHZpZXcgKi8KICAgICooKERXT1JEKilwTWFwcGVkKSA9IGR3U2l6ZTsKICAgIGlmIChscHZEYXRhKQogICAgICBtZW1jcHkoKGNoYXIgKikgcE1hcHBlZCArIHNpemVvZihkd1NpemUpLCBscHZEYXRhLCBkd1NpemUpOwoKICAgIC8qIFJlbGVhc2Ugdmlldy4gQWxsIGZ1cnRoZXIgdmlld3MgbWFwcGVkIHdpbGwgYmUgb3BhcXVlICovCiAgICBVbm1hcFZpZXdPZkZpbGUocE1hcHBlZCk7CiAgICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaE1hcCwgZHdQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3NJZCgpLCBGSUxFX01BUF9BTExfQUNDRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERVUExJQ0FURV9TQU1FX0FDQ0VTUyk7CiAgfQoKICBDbG9zZUhhbmRsZShoTWFwKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS44XQogKgogKiBHZXQgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2Ygc2hhcmVkIG1lbW9yeSBmcm9tIGEgc2hhcmVkIG1lbW9yeSBoYW5kbGUuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHBvaW50ZXIgdG8gdGhlIHNoYXJlZCBtZW1vcnkKICogRmFpbHVyZTogTlVMTAogKgogKi8KUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICBIQU5ETEUgaER1cDsKICBMUFZPSUQgcE1hcHBlZDsKCiAgVFJBQ0UoIiglcCAlZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGhhbmRsZSB0byBzaGFyZWQgbWVtb3J5IGZvciBjdXJyZW50IHByb2Nlc3MgKi8KICBoRHVwID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUywgMCk7CiAgLyogR2V0IFZpZXcgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoRHVwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwogIENsb3NlSGFuZGxlKGhEdXApOwoKICBpZiAocE1hcHBlZCkKICAgIHJldHVybiAoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKERXT1JEKTsgLyogSGlkZSBzaXplICovCiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOV0KICoKICogUmVsZWFzZSBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5LgogKgogKiBQQVJBTVMKICogbHBWaWV3IFtJXSBTaGFyZWQgbWVtb3J5IHBvaW50ZXIKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChMUFZPSUQgbHBWaWV3KQp7CiAgVFJBQ0UoIiglcClcbiIsIGxwVmlldyk7CiAgcmV0dXJuIFVubWFwVmlld09mRmlsZSgoY2hhciAqKSBscFZpZXcgLSBzaXplb2YoRFdPUkQpKTsgLyogSW5jbHVkZSBzaXplICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuMTBdCiAqCiAqIERlc3Ryb3kgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhDbG9zZTsKCiAgVFJBQ0UoIiglcCAlZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGEgY29weSBvZiB0aGUgaGFuZGxlIGZvciBvdXIgcHJvY2VzcywgY2xvc2luZyB0aGUgc291cmNlIGhhbmRsZSAqLwogIGhDbG9zZSA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUyxEVVBMSUNBVEVfQ0xPU0VfU09VUkNFKTsKICAvKiBDbG9zZSBsb2NhbCBjb3B5ICovCiAgcmV0dXJuIENsb3NlSGFuZGxlKGhDbG9zZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICBbU0hMV0FQSS4xMV0KICoKICogQ29weSBhIHNoYXJhYmxlIG1lbW9yeSBoYW5kbGUgZnJvbSBvbmUgcHJvY2VzcyB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgICAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlIHRvIGR1cGxpY2F0ZQogKiBkd0RzdFByb2NJZCBbSV0gSUQgb2YgdGhlIHByb2Nlc3Mgd2FudGluZyB0aGUgZHVwbGljYXRlZCBoYW5kbGUKICogZHdTcmNQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqIGR3QWNjZXNzICAgIFtJXSBEZXNpcmVkIER1cGxpY2F0ZUhhbmRsZSgpIGFjY2VzcwogKiBkd09wdGlvbnMgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBvcHRpb25zCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBoYW5kbGUgc3VpdGFibGUgZm9yIHVzZSBieSB0aGUgZHdEc3RQcm9jSWQgcHJvY2Vzcy4KICogRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICoKICovCkhBTkRMRSBXSU5BUEkgU0hNYXBIYW5kbGUoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3RHN0UHJvY0lkLCBEV09SRCBkd1NyY1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0FjY2VzcywgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhSZXQ7CgogIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd0RzdFByb2NJZCwgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTNdCiAqCiAqIENyZWF0ZSBhbmQgcmVnaXN0ZXIgYSBjbGlwYm9hcmQgZW51bWVyYXRvciBmb3IgYSB3ZWIgYnJvd3Nlci4KICoKICogUEFSQU1TCiAqICBscEJDICAgICAgW0ldIEJpbmRpbmcgY29udGV4dAogKiAgbHBVbmtub3duIFtJXSBBbiBvYmplY3QgZXhwb3NpbmcgdGhlIElXZWJCcm93c2VyQXBwIGludGVyZmFjZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgVGhlIGVudW1lcmF0b3IgaXMgc3RvcmVkIGFzIGEgcHJvcGVydHkgb2YgdGhlIHdlYiBicm93c2VyLiBJZiBpdCBkb2VzIG5vdAogKiAgeWV0IGV4aXN0LCBpdCBpcyBjcmVhdGVkIGFuZCBzZXQgYmVmb3JlIGJlaW5nIHJlZ2lzdGVyZWQuCiAqLwpIUkVTVUxUIFdJTkFQSSBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzKExQQkMgbHBCQywgSVVua25vd24gKmxwVW5rbm93bikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb3BlcnR5W10gPSB7ICd7JywnRCcsJzAnLCdGJywnQycsJ0EnLCc0JywnMicsJzAnLAogICAgICAnLScsJ0QnLCczJywnRicsJzUnLCctJywnMScsJzEnLCdDJywnRicsICctJywnQicsJzInLCcxJywnMScsJy0nLCcwJywKICAgICAgJzAnLCdBJywnQScsJzAnLCcwJywnNCcsJ0EnLCdFJywnOCcsJzMnLCc3JywnfScsJ1wwJyB9OwogIEJTVFIgcHJvcGVydHk7CiAgSUVudW1GT1JNQVRFVEMqIHBJRW51bUZvcm1hdEV0YyA9IE5VTEw7CiAgVkFSSUFOVEFSRyB2YXI7CiAgSFJFU1VMVCBoUmV0OwogIElXZWJCcm93c2VyQXBwKiBwQnJvd3NlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwKVxuIiwgbHBCQywgbHBVbmtub3duKTsKCiAgLyogR2V0IEFuIElXZWJCcm93c2VyQXBwIGludGVyZmFjZSBmcm9tICBscFVua25vd24gKi8KICBoUmV0ID0gSVVua25vd25fUXVlcnlTZXJ2aWNlKGxwVW5rbm93biwgJklJRF9JV2ViQnJvd3NlckFwcCwgJklJRF9JV2ViQnJvd3NlckFwcCwgKFBWT0lEKSZwQnJvd3Nlcik7CiAgaWYgKEZBSUxFRChoUmV0KSB8fCAhcEJyb3dzZXIpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgVl9WVCgmdmFyKSA9IFZUX0VNUFRZOwoKICAvKiBUaGUgcHJvcGVydHkgd2UgZ2V0IGlzIHRoZSBicm93c2VycyBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogIHByb3BlcnR5ID0gU3lzQWxsb2NTdHJpbmcoc3pQcm9wZXJ0eSk7CiAgaFJldCA9IElXZWJCcm93c2VyQXBwX0dldFByb3BlcnR5KHBCcm93c2VyLCBwcm9wZXJ0eSwgJnZhcik7CiAgU3lzRnJlZVN0cmluZyhwcm9wZXJ0eSk7CiAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHJldHVybiBoUmV0OwoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9FTVBUWSkKICB7CiAgICAvKiBJdGVyYXRlIHRocm91Z2ggYWNjZXB0ZWQgZG9jdW1lbnRzIGFuZCBSZWdpc3RlckNsaXBCb2FyZEZvcm1hdEEoKSB0aGVtICovCiAgICBjaGFyIHN6S2V5QnVmZlsxMjhdLCBzelZhbHVlQnVmZlsxMjhdOwogICAgRFdPUkQgZHdLZXlTaXplLCBkd1ZhbHVlU2l6ZSwgZHdSZXQgPSAwLCBkd0NvdW50ID0gMCwgZHdOdW1WYWx1ZXMsIGR3VHlwZTsKICAgIEZPUk1BVEVUQyogZm9ybWF0TGlzdCwgKmZvcm1hdDsKICAgIEhLRVkgaERvY3M7CgogICAgVFJBQ0UoIlJlZ2lzdGVyaW5nIGZvcm1hdHMgYW5kIGNyZWF0aW5nIElFbnVtRk9STUFURVRDIGluc3RhbmNlXG4iKTsKCiAgICBpZiAoIVJlZ09wZW5LZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnQiCiAgICAgICAgICAgICAgICAgICAgICJWZXJzaW9uXFxJbnRlcm5ldCBTZXR0aW5nc1xcQWNjZXB0ZWQgRG9jdW1lbnRzIiwgJmhEb2NzKSkKICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAvKiBHZXQgY291bnQgb2YgdmFsdWVzIGluIGtleSAqLwogICAgd2hpbGUgKCFkd1JldCkKICAgIHsKICAgICAgZHdLZXlTaXplID0gc2l6ZW9mKHN6S2V5QnVmZik7CiAgICAgIGR3UmV0ID0gUmVnRW51bVZhbHVlQShoRG9jcyxkd0NvdW50LHN6S2V5QnVmZiwmZHdLZXlTaXplLDAsJmR3VHlwZSwwLDApOwogICAgICBkd0NvdW50Kys7CiAgICB9CgogICAgZHdOdW1WYWx1ZXMgPSBkd0NvdW50OwoKICAgIC8qIE5vdGU6IGR3Q291bnQgPSBudW1iZXIgb2YgaXRlbXMgKyAxOyBUaGUgZXh0cmEgaXRlbSBpcyB0aGUgZW5kIG5vZGUgKi8KICAgIGZvcm1hdCA9IGZvcm1hdExpc3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHdDb3VudCAqIHNpemVvZihGT1JNQVRFVEMpKTsKICAgIGlmICghZm9ybWF0TGlzdCkKICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgaWYgKGR3TnVtVmFsdWVzID4gMSkKICAgIHsKICAgICAgZHdSZXQgPSAwOwogICAgICBkd0NvdW50ID0gMDsKCiAgICAgIGR3TnVtVmFsdWVzLS07CgogICAgICAvKiBSZWdpc3RlciBjbGlwYm9hcmQgZm9ybWF0cyBmb3IgdGhlIHZhbHVlcyBhbmQgcG9wdWxhdGUgZm9ybWF0IGxpc3QgKi8KICAgICAgd2hpbGUoIWR3UmV0ICYmIGR3Q291bnQgPCBkd051bVZhbHVlcykKICAgICAgewogICAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICAgIGR3VmFsdWVTaXplID0gc2l6ZW9mKHN6VmFsdWVCdWZmKTsKICAgICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsIGR3Q291bnQsIHN6S2V5QnVmZiwgJmR3S2V5U2l6ZSwgMCwgJmR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBCWVRFKXN6VmFsdWVCdWZmLCAmZHdWYWx1ZVNpemUpOwogICAgICAgIGlmICghZHdSZXQpCiAgICAgICAgICByZXR1cm4gRV9GQUlMOwoKICAgICAgICBmb3JtYXQtPmNmRm9ybWF0ID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXRBKHN6VmFsdWVCdWZmKTsKICAgICAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICAgICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICAgICAgZm9ybWF0LT5saW5kZXggPSA0OwogICAgICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAgICAgZm9ybWF0Kys7CiAgICAgICAgZHdDb3VudCsrOwogICAgICB9CiAgICB9CgogICAgLyogVGVybWluYXRlIHRoZSAobWF5YmUgZW1wdHkpIGxpc3QsIGxhc3QgZW50cnkgaGFzIGEgY2ZGb3JtYXQgb2YgMCAqLwogICAgZm9ybWF0LT5jZkZvcm1hdCA9IDA7CiAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICBmb3JtYXQtPmR3QXNwZWN0ID0gMTsKICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAvKiBDcmVhdGUgYSBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogICAgaFJldCA9IENyZWF0ZUZvcm1hdEVudW1lcmF0b3IoZHdOdW1WYWx1ZXMsIGZvcm1hdExpc3QsICZwSUVudW1Gb3JtYXRFdGMpOwoKICAgIGlmIChGQUlMRUQoaFJldCkgfHwgIXBJRW51bUZvcm1hdEV0YykKICAgICAgcmV0dXJuIGhSZXQ7CgogICAgLyogU2V0IG91ciBlbnVtZXJhdG9yIGFzIHRoZSBicm93c2VycyBwcm9wZXJ0eSAqLwogICAgVl9WVCgmdmFyKSA9IFZUX1VOS05PV047CiAgICBWX1VOS05PV04oJnZhcikgPSAoSVVua25vd24qKXBJRW51bUZvcm1hdEV0YzsKCiAgICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfUHV0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksIHZhcik7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSUVudW1Gb3JtYXRFdGMpOwogICAgICAgZ290byBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ7CiAgICB9CiAgfQoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9VTktOT1dOKQogIHsKICAgIC8qIE91ciB2YXJpYW50IGlzIGhvbGRpbmcgdGhlIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBJVW5rbm93biogcElVbmtub3duID0gVl9VTktOT1dOKCZ2YXIpOwogICAgSUVudW1GT1JNQVRFVEMqIHBDbG9uZSA9IE5VTEw7CgogICAgVFJBQ0UoIlJldHJpZXZlZCBJRW51bUZPUk1BVEVUQyBwcm9wZXJ0eVxuIik7CgogICAgLyogR2V0IGFuIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSBmcm9tIHRoZSB2YXJpYW50cyB2YWx1ZSAqLwogICAgcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSVVua25vd24sICZJSURfSUVudW1GT1JNQVRFVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBWT0lEKSZwSUVudW1Gb3JtYXRFdGMpOwogICAgaWYgKCFoUmV0ICYmIHBJRW51bUZvcm1hdEV0YykKICAgIHsKICAgICAgLyogQ2xvbmUgYW5kIHJlZ2lzdGVyIHRoZSBlbnVtZXJhdG9yICovCiAgICAgIGhSZXQgPSBJRW51bUZPUk1BVEVUQ19DbG9uZShwSUVudW1Gb3JtYXRFdGMsICZwQ2xvbmUpOwogICAgICBpZiAoIWhSZXQgJiYgcENsb25lKQogICAgICB7CiAgICAgICAgUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yKGxwQkMsIHBDbG9uZSwgMCk7CgogICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocENsb25lKTsKICAgICAgfQoKICAgICAgLyogUmVsZWFzZSB0aGUgSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlICovCiAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElVbmtub3duKTsKICAgIH0KICAgIElVbmtub3duX1JlbGVhc2UoVl9VTktOT1dOKCZ2YXIpKTsKICB9CgpSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ6CiAgSVdlYkJyb3dzZXJBcHBfUmVsZWFzZShwQnJvd3Nlcik7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNV0KICoKICogR2V0IEV4cGxvcmVycyAiQWNjZXB0TGFuZ3VhZ2UiIHNldHRpbmcuCiAqCiAqIFBBUkFNUwogKiAgbGFuZ2J1ZiBbT10gRGVzdGluYXRpb24gZm9yIGxhbmd1YWdlIHN0cmluZwogKiAgYnVmbGVuICBbSV0gTGVuZ3RoIG9mIGxhbmdidWYKICogICAgICAgICAgWzBdIFN1Y2Nlc3M6IHVzZWQgbGVuZ3RoIG9mIGxhbmdidWYKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gICBsYW5nYnVmIGlzIHNldCB0byB0aGUgbGFuZ3VhZ2Ugc3RyaW5nIGZvdW5kLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBhbnkgYXJndW1lbnRzIGFyZSBpbnZhbGlkLCBlcnJvciBvY2N1cnJlZCwgb3IgRXhwbG9yZXIKICogICAgICAgICAgIGRvZXMgbm90IGNvbnRhaW4gdGhlIHNldHRpbmcuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIHRoZSBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2gKICovCkhSRVNVTFQgV0lOQVBJIEdldEFjY2VwdExhbmd1YWdlc1coIExQV1NUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6a2V5V1tdID0gewoJJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAoJJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB2YWx1ZVdbXSA9IHsKCSdBJywnYycsJ2MnLCdlJywncCcsJ3QnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW51c1dbXSA9IHsnZScsJ24nLCctJywndScsJ3MnLDB9OwogICAgRFdPUkQgbXlzdHJsZW4sIG15dHlwZTsKICAgIEhLRVkgbXlrZXk7CiAgICBIUkVTVUxUIHJldHZhbDsKICAgIExDSUQgbXlsY2lkOwogICAgV0NIQVIgKm15c3RyOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pCglyZXR1cm4gRV9GQUlMOwoKICAgIG15c3RybGVuID0gKCpidWZsZW4gPiAyMCkgPyAqYnVmbGVuIDogMjAgOwogICAgbXlzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIG15c3RybGVuKTsKICAgIFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBzemtleVcsICZteWtleSk7CiAgICBpZihSZWdRdWVyeVZhbHVlRXhXKG15a2V5LCB2YWx1ZVcsIDAsICZteXR5cGUsIChQQllURSlteXN0ciwgJm15c3RybGVuKSkgewogICAgICAgIC8qIERpZCBub3QgZmluZCB2YWx1ZSAqLwogICAgICAgIG15bGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIC8qIHNvbWVob3cgdGhlIG15bGNpZCB0cmFuc2xhdGVzIGludG8gImVuLXVzIgogICAgICAgICAqICB0aGlzIGlzIHNpbWlsYXIgdG8gIkxPQ0FMRV9TQUJCUkVWTEFOR05BTUUiCiAgICAgICAgICogIHdoaWNoIGNvdWxkIGJlIGdvdHRlbiB2aWEgR2V0TG9jYWxlSW5mby4KICAgICAgICAgKiAgVGhlIG9ubHkgcHJvYmxlbSBpcyBMT0NBTEVfU0FCQlJFVkxBTkdVQUdFIiBpcwogICAgICAgICAqICBhIDMgY2hhciBzdHJpbmcgKGZpcnN0IDIgYXJlIGNvdW50cnkgY29kZSBhbmQgdGhpcmQgaXMKICAgICAgICAgKiAgbGV0dGVyIGZvciAic3VibGFuZ3VhZ2UiLCB3aGljaCBkb2VzIG5vdCBjb21lIGNsb3NlIHRvCiAgICAgICAgICogICJlbi11cyIKICAgICAgICAgKi8KICAgICAgICBsc3RyY3B5VyhteXN0ciwgZW51c1cpOwogICAgICAgIG15c3RybGVuID0gbHN0cmxlblcobXlzdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBoYW5kbGUgcmV0dXJuZWQgc3RyaW5nICovCiAgICAgICAgRklYTUUoIm1pc3NpbmcgY29kZVxuIik7CiAgICB9CiAgICBtZW1jcHkoIGxhbmdidWYsIG15c3RyLCBtaW4oKmJ1ZmxlbixzdHJsZW5XKG15c3RyKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYoKmJ1ZmxlbiA+IHN0cmxlblcobXlzdHIpKSB7CgkqYnVmbGVuID0gc3RybGVuVyhteXN0cik7CglyZXR2YWwgPSBTX09LOwogICAgfSBlbHNlIHsKCSpidWZsZW4gPSAwOwoJcmV0dmFsID0gRV9JTlZBTElEQVJHOwoJU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgfQogICAgUmVnQ2xvc2VLZXkobXlrZXkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXlzdHIpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE0XQogKgogKiBBc2NpaSB2ZXJzaW9uIG9mIEdldEFjY2VwdExhbmd1YWdlc1cuCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNBKCBMUFNUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgV0NIQVIgKmxhbmdidWZXOwogICAgRFdPUkQgYnVmbGVuVywgY29udmxlbjsKICAgIEhSRVNVTFQgcmV0dmFsOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pIHJldHVybiBFX0ZBSUw7CgogICAgYnVmbGVuVyA9ICpidWZsZW47CiAgICBsYW5nYnVmVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpICogYnVmbGVuVyk7CiAgICByZXR2YWwgPSBHZXRBY2NlcHRMYW5ndWFnZXNXKGxhbmdidWZXLCAmYnVmbGVuVyk7CgogICAgLyogRklYTUU6IHRoaXMgaXMgd3JvbmcsIHRoZSBzdHJpbmcgbWF5IG5vdCBiZSBudWxsLXRlcm1pbmF0ZWQgKi8KICAgIGNvbnZsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgbGFuZ2J1ZlcsIC0xLCBsYW5nYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1ZmxlbiwgTlVMTCwgTlVMTCk7CiAgICAqYnVmbGVuID0gYnVmbGVuVyA/IGNvbnZsZW4gOiAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxhbmdidWZXKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yM10KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCAgICAgW0ldIEdVSUQgdG8gY29udmVydAogKiAgbHBzekRlc3QgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNjaE1heCAgIFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJREEoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4WC0lMDRYLSUwNFgtJTAyWCUwMlgtJTAyWCUwMlglMDJYJTAyWCUwMlglMDJYfSIsCiAgICAgICAgICBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW4oeGd1aWQpICsgMTsKCiAgaWYgKGlMZW4gPiBjY2hNYXgpCiAgICByZXR1cm4gMDsKICBtZW1jcHkobHBzekRlc3QsIHhndWlkLCBpTGVuKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0XQogKgogKiBDb252ZXJ0IGEgR1VJRCB0byBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBndWlkIFtJXSBHVUlEIHRvIGNvbnZlcnQKICogIHN0ciAgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNtYXggW0ldIExlbmd0aCBvZiBvdXRwdXQgYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBjcmVhdGVkLgogKi8KSU5UIFdJTkFQSSBTSFN0cmluZ0Zyb21HVUlEVyhSRUZHVUlEIGd1aWQsIExQV1NUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIFdDSEFSIHhndWlkWzQwXTsKICBJTlQgaUxlbjsKICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6Rm9ybWF0W10gPSB7J3snLCclJywnMCcsJzgnLCdsJywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywKICAgICAgJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnLScsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsCiAgICAgICdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCd9JywwfTsKCiAgVFJBQ0UoIiglcywlcCwlZClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIGxwc3pEZXN0LCBjY2hNYXgpOwoKICBzcHJpbnRmVyh4Z3VpZCwgd3N6Rm9ybWF0LCBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW5XKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbipzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIHNwYWNlLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgc3BhY2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJTcGFjZVcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1NQQUNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMwXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGJsYW5rLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgYmxhbmssCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJCbGFua1coV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0JMQU5LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBwdW5jdHVhdGlvbi4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBwdW5jdHVhdGlvbiwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclB1bmN0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfUFVOQ1QpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzJdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBjb250cm9sIGNoYXJhY3RlciwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckNudHJsVyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfQ05UUkwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzNdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckRpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfRElHSVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzRdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgaGV4IGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgaGV4IGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyWERpZ2l0VyhXQ0hBUiB3YykKewogICAgV09SRCBDaGFyVHlwZTsKCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoQ1RfQ1RZUEUxLCAmd2MsIDEsICZDaGFyVHlwZSkgJiYgKENoYXJUeXBlICYgQzFfWERJR0lUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1XQogKgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZTNFeFcoTFBXU1RSIGxwc3pTdHIsIERXT1JEIGR3TGVuLCBMUFZPSUQgcDMpCnsKICAgIEZJWE1FKCIoJXMsMHglMDh4LCVwKTogc3R1YlxuIiwgZGVidWdzdHJfdyhscHN6U3RyKSwgZHdMZW4sIHAzKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzZdCiAqCiAqIEluc2VydCBhIGJpdG1hcCBtZW51IGl0ZW0gYXQgdGhlIGJvdHRvbSBvZiBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gaW5zZXJ0IGludG8KICogIGZsYWdzIFtJXSBGbGFncyBmb3IgaW5zZXJ0aW9uCiAqICBpZCAgICBbSV0gTWVudSBJRCBvZiB0aGUgaXRlbQogKiAgc3RyICAgW0ldIE1lbnUgdGV4dCBmb3IgdGhlIGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRSwgIHRoZSBpdGVtIGlzIGluc2VydGVkIGludG8gdGhlIG1lbnUKICogIEZhaWx1cmU6IEZBTFNFLCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQKICovCkJPT0wgV0lOQVBJIEFwcGVuZE1lbnVXcmFwVyhITUVOVSBoTWVudSwgVUlOVCBmbGFncywgVUlOVCBpZCwgTFBDV1NUUiBzdHIpCnsKICAgIFRSQUNFKCIoJXAsMHglMDh4LDB4JTA4eCwlcylcbiIsaE1lbnUsIGZsYWdzLCBpZCwgZGVidWdzdHJfdyhzdHIpKTsKICAgIHJldHVybiBJbnNlcnRNZW51VyhoTWVudSwgLTEsIGZsYWdzIHwgTUZfQklUTUFQLCBpZCwgc3RyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgW1NITFdBUEkuMTM4XQogKgogKiBTZXQgdGhlIHRleHQgb2YgYSBnaXZlbiBkaWFsb2cgaXRlbS4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gSGFuZGxlIG9mIGRpYWxvZwogKiAgaUl0ZW0gICAgW0ldIEluZGV4IG9mIGl0ZW0KICogIGxwc3pUZXh0IFtPXSBUZXh0IHRvIHNldAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiAgVGhlIHRleHQgb2YgdGhlIGRpYWxvZyBpcyBzZXQgdG8gbHBzelRleHQuCiAqICBGYWlsdXJlOiBGQUxTRSwgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU2V0RGxnSXRlbVRleHRXcmFwVyhIV05EIGhXbmQsIElOVCBpSXRlbSwgTFBDV1NUUiBscHN6VGV4dCkKewogICAgSFdORCBoV25kSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgaUl0ZW0pOwogICAgaWYgKGhXbmRJdGVtKQogICAgICAgIHJldHVybiBTZXRXaW5kb3dUZXh0VyhoV25kSXRlbSwgbHBzelRleHQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUxXQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzIHVwIHRvIGEgZ2l2ZW4gbGVuZ3RoLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICogIGxlbiAgICAgW0ldIE1heGltdW0gbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBJTlQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUyXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTkNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTNdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGgsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY2FzZWNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU0XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTklDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21waVcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NV0KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTZdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcFcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTddCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNhc2VjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNThdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBJQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21waVcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjBdCiAqCiAqIEdldCBhbiBpZGVudGlmaWNhdGlvbiBzdHJpbmcgZm9yIHRoZSBPUyBhbmQgZXhwbG9yZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBzekRlc3QgIFtPXSBEZXN0aW5hdGlvbiBmb3IgSWQgc3RyaW5nCiAqICBkd0Rlc3RMZW4gW0ldIExlbmd0aCBvZiBscHN6RGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCAgSWYgdGhlIHN0cmluZyB3YXMgY3JlYXRlZCBzdWNjZXNzZnVsbHkKICogIEZBTFNFLCBPdGhlcndpc2UKICovCkJPT0wgV0lOQVBJIFNIQWJvdXRJbmZvQShMUFNUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgV0NIQVIgYnVmZlsyMDg0XTsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAobHBzekRlc3QgJiYgU0hBYm91dEluZm9XKGJ1ZmYsIGR3RGVzdExlbikpCiAgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGJ1ZmYsIC0xLCBscHN6RGVzdCwgZHdEZXN0TGVuLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjFdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSEFib3V0SW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pJRUtleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6V2luTnRLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJyAnLAogICAgJ04nLCdUJywnXFwnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbktleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UmVnS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywKICAgICcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCiAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmVyc2lvbltdID0geyAnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekN1c3RvbWl6ZWRbXSA9IHsgJ0MnLCd1JywncycsJ3QnLCdvJywnbScsJ2knLCd6JywnZScsJ2QnLAogICAgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPd25lcltdID0geyAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywnZScsJ3InLCdlJywnZCcsCiAgICAnTycsJ3cnLCduJywnZScsJ3InLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPcmdbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCdyJywnZycsJ2EnLCduJywnaScsJ3onLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb2R1Y3RbXSA9IHsgJ1AnLCdyJywnbycsJ2QnLCd1JywnYycsJ3QnLCdJJywnZCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelVwZGF0ZVtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnVScsJ3AnLCdkJywnYScsJ3QnLCdlJywnVScsJ3InLCdsJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SGVscFtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnSCcsJ2UnLCdsJywncCcsJ1MnLCd0JywncicsJ2knLCduJywnZycsJ1wwJyB9OwogIFdDSEFSIGJ1ZmZbMjA4NF07CiAgSEtFWSBoUmVnOwogIERXT1JEIGR3VHlwZSwgZHdMZW47CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKCFscHN6RGVzdCkKICAgIHJldHVybiBGQUxTRTsKCiAgKmxwc3pEZXN0ID0gJ1wwJzsKCiAgLyogVHJ5IHRoZSBOVCBrZXkgZmlyc3QsIGZvbGxvd2VkIGJ5IDk1Lzk4IGtleSAqLwogIGlmIChSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5OdEtleSwgMCwgS0VZX1JFQUQsICZoUmVnKSAmJgogICAgICBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5LZXksIDAsIEtFWV9SRUFELCAmaFJlZykpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIE9TIFZlcnNpb24gKi8KICBidWZmWzBdID0gJ1wwJzsKICBkd0xlbiA9IDMwOwogIGlmICghU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LCBzelZlcnNpb24sICZkd1R5cGUsIGJ1ZmYsICZkd0xlbikpCiAgewogICAgRFdPUkQgZHdTdHJMZW4gPSBzdHJsZW5XKGJ1ZmYpOwogICAgZHdMZW4gPSAzMCAtIGR3U3RyTGVuOwogICAgU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LAogICAgICAgICAgICAgICAgc3pDdXN0b21pemVkLCAmZHdUeXBlLCBidWZmK2R3U3RyTGVuLCAmZHdMZW4pOwogIH0KICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3duZXIgKi8KICBidWZmWzBdID0gJ34nOwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek93bmVyLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3JnYW5pemF0aW9uICovCiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKGhSZWcsIHN6T3JnLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogRklYTUU6IE5vdCBzdXJlIHdoZXJlIHRoaXMgbnVtYmVyIGNvbWVzIGZyb20gICovCiAgYnVmZlswXSA9ICd+JzsKICBidWZmWzFdID0gJzAnOwogIGJ1ZmZbMl0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UHJvZHVjdCBJZCAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6UmVnS2V5LCBzelByb2R1Y3QsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgVXBkYXRlIFVybCAqLwogIGR3TGVuID0gMjA0ODsKICBpZihTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCBzelVwZGF0ZSwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5JRSBIZWxwIFN0cmluZyAqLwogIGR3TGVuID0gMjU2OwogIGlmKFNIR2V0VmFsdWVXKGhSZWcsIHN6SGVscCwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIFJlZ0Nsb3NlS2V5KGhSZWcpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYzXQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqICBjQ21kcyAgICAgICAgIFtJXQogKiAgcHJnQ21kcyAgICAgICBbT10gQ29tbWFuZHMKICogIHBDbWRUZXh0ICAgICAgW09dIENvbW1hbmQgdGV4dAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBscFVua25vd24gaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElPbGVDb21tYW5kVGFyZ2V0LgogKiAgICAgICAgICAgT3RoZXJ3aXNlLCBhbiBlcnJvciBjb2RlIGZyb20gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U3RhdHVzKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJWQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMsIHBDbWRUZXh0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscE9sZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZ0NtZHMsIHBDbWRUZXh0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJCVtTSExXQVBJLjE2NF0KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSU9sZUNvbW1hbmRUYXJnZXQuCiAqICAgICAgICAgICBPdGhlcndpc2UsIGFuIGVycm9yIGNvZGUgZnJvbSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FeGVjKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlZCwlZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBPbGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY1XQogKgogKiBSZXRyaWV2ZSwgbW9kaWZ5LCBhbmQgcmUtc2V0IGEgdmFsdWUgZnJvbSBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgW0ldIFdpbmRvdyB0byBnZXQgdmFsdWUgZnJvbQogKiAgb2Zmc2V0IFtJXSBPZmZzZXQgb2YgdmFsdWUKICogIHdNYXNrICBbSV0gTWFzayBmb3IgdWlGbGFncwogKiAgd0ZsYWdzIFtJXSBCaXRzIHRvIHNldCBpbiB3aW5kb3cgdmFsdWUKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyB2YWx1ZSBhcyBpdCB3YXMgc2V0LCBvciAwIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZC4KICoKICogTk9URVMKICogIEFueSBiaXRzIHNldCBpbiB1aU1hc2sgYXJlIGNsZWFyZWQgZnJvbSB0aGUgdmFsdWUsIHRoZW4gYW55IGJpdHMgc2V0IGluCiAqICB1aUZsYWdzIGFyZSBzZXQgaW4gdGhlIHZhbHVlLgogKi8KTE9ORyBXSU5BUEkgU0hTZXRXaW5kb3dCaXRzKEhXTkQgaHduZCwgSU5UIG9mZnNldCwgVUlOVCB3TWFzaywgVUlOVCB3RmxhZ3MpCnsKICBMT05HIHJldCA9IEdldFdpbmRvd0xvbmdBKGh3bmQsIG9mZnNldCk7CiAgTE9ORyBuZXdGbGFncyA9ICh3RmxhZ3MgJiB3TWFzaykgfCAocmV0ICYgfndGbGFncyk7CgogIGlmIChuZXdGbGFncyAhPSByZXQpCiAgICByZXQgPSBTZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQsIG5ld0ZsYWdzKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY3XQogKgogKiBDaGFuZ2UgYSB3aW5kb3cncyBwYXJlbnQuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICBbSV0gV2luZG93IHRvIGNoYW5nZSBwYXJlbnQgb2YKICogIGhXbmRQYXJlbnQgW0ldIE5ldyBwYXJlbnQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogIFRoZSBvbGQgcGFyZW50IG9mIGhXbmQuCiAqCiAqIE5PVEVTCiAqICBJZiBoV25kUGFyZW50IGlzIE5VTEwgKGRlc2t0b3ApLCB0aGUgd2luZG93IHN0eWxlIGlzIGNoYW5nZWQgdG8gV1NfUE9QVVAuCiAqICBJZiBoV25kUGFyZW50IGlzIE5PVCBOVUxMIHRoZW4gd2Ugc2V0IHRoZSBXU19DSElMRCBzdHlsZS4KICovCkhXTkQgV0lOQVBJIFNIU2V0UGFyZW50SHduZChIV05EIGhXbmQsIEhXTkQgaFduZFBhcmVudCkKewogIFRSQUNFKCIlcCwgJXBcbiIsIGhXbmQsIGhXbmRQYXJlbnQpOwoKICBpZihHZXRQYXJlbnQoaFduZCkgPT0gaFduZFBhcmVudCkKICAgIHJldHVybiAwOwoKICBpZihoV25kUGFyZW50KQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfQ0hJTEQsIFdTX0NISUxEKTsKICBlbHNlCiAgICBTSFNldFdpbmRvd0JpdHMoaFduZCwgR1dMX1NUWUxFLCBXU19QT1BVUCwgV1NfUE9QVVApOwoKICByZXR1cm4gU2V0UGFyZW50KGhXbmQsIGhXbmRQYXJlbnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTY4XQogKgogKiBMb2NhdGUgYW5kIGFkdmlzZSBhIGNvbm5lY3Rpb24gcG9pbnQgaW4gYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtTaW5rICAgW0ldIFNpbmsgZm9yIHRoZSBjb25uZWN0aW9uIHBvaW50IGFkdmlzZSBjYWxsCiAqICByaWlkICAgICAgICBbSV0gUkVGSUlEIG9mIGNvbm5lY3Rpb24gcG9pbnQgdG8gYWR2aXNlCiAqICBiQWR2aXNlT25seSBbSV0gVFJVRSA9IEFkdmlzZSBvbmx5LCBGQUxTRSA9IFVuYWR2aXNlIGZpcnN0CiAqICBscFVua25vd24gICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlCiAqICBscENvb2tpZSAgICBbT10gUG9pbnRlciB0byBjb25uZWN0aW9uIHBvaW50IGNvb2tpZQogKiAgbHBwQ1AgICAgICAgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgSUNvbm5lY3Rpb25Qb2ludCBmb3VuZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBscHBDUCBpcyBub24tTlVMTCwgaXQgaXMgZmlsbGVkIHdpdGggdGhlIElDb25uZWN0aW9uUG9pbnQKICogICAgICAgICAgIHRoYXQgd2FzIGFkdmlzZWQuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHJlbGVhc2luZyBpdC4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgYW55IGFyZ3VtZW50cyBhcmUgaW52YWxpZC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBpc24ndCBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlIGlmIGFueSBjYWxsIGZhaWxzLgogKi8KSFJFU1VMVCBXSU5BUEkgQ29ubmVjdFRvQ29ubmVjdGlvblBvaW50KElVbmtub3duKiBscFVua1NpbmssIFJFRklJRCByaWlkLCBCT09MIGJBZHZpc2VPbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biogbHBVbmtub3duLCBMUERXT1JEIGxwQ29va2llLAogICAgICAgICAgICAgICAgICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50ICoqbHBwQ1ApCnsKICBIUkVTVUxUIGhSZXQ7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDb250YWluZXI7CiAgSUNvbm5lY3Rpb25Qb2ludCAqbHBDUDsKCiAgaWYoIWxwVW5rbm93biB8fCAoYkFkdmlzZU9ubHkgJiYgIWxwVW5rU2luaykpCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZihscHBDUCkKICAgICpscHBDUCA9IE5VTEw7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDb250YWluZXIpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENvbnRhaW5lciwgcmlpZCwgJmxwQ1ApOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICB7CiAgICAgIGlmKCFiQWR2aXNlT25seSkKICAgICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9VbmFkdmlzZShscENQLCAqbHBDb29raWUpOwogICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9BZHZpc2UobHBDUCwgbHBVbmtTaW5rLCBscENvb2tpZSk7CgogICAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICAgICpscENvb2tpZSA9IDA7CgogICAgICBpZiAobHBwQ1AgJiYgU1VDQ0VFREVEKGhSZXQpKQogICAgICAgICpscHBDUCA9IGxwQ1A7IC8qIENhbGxlciBrZWVwcyB0aGUgaW50ZXJmYWNlICovCiAgICAgIGVsc2UKICAgICAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7IC8qIFJlbGVhc2UgaXQgKi8KICAgIH0KCiAgICBJVW5rbm93bl9SZWxlYXNlKGxwQ29udGFpbmVyKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCUAJW1NITFdBUEkuMTY5XQogKgogKiBSZWxlYXNlIGFuIGludGVyZmFjZS4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byByZWxlYXNlCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fQXRvbWljUmVsZWFzZShJVW5rbm93biAqKiBscFVua25vd24pCnsKICAgIElVbmtub3duICp0ZW1wOwoKICAgIFRSQUNFKCIoJXApXG4iLGxwVW5rbm93bik7CgogICAgaWYoIWxwVW5rbm93biB8fCAhKigoTFBEV09SRClscFVua25vd24pKSByZXR1cm4gMDsKICAgIHRlbXAgPSAqbHBVbmtub3duOwogICAgKmxwVW5rbm93biA9IE5VTEw7CgogICAgVFJBQ0UoImRvaW5nIFJlbGVhc2VcbiIpOwoKICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKHRlbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcwXQogKgogKiBTa2lwICcvLycgaWYgcHJlc2VudCBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTdHJpbmcgdG8gY2hlY2sgZm9yICcvLycKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIG5leHQgY2hhcmFjdGVyIGFmdGVyIHRoZSAnLy8nIG9yIHRoZSBzdHJpbmcgaWYgbm90IHByZXNlbnQKICogIEZhaWx1cmU6IE5VTEwsIGlmIGxwc3pTdHIgaXMgTlVMTC4KICovCkxQQ1NUUiBXSU5BUEkgUGF0aFNraXBMZWFkaW5nU2xhc2hlc0EoTFBDU1RSIGxwc3pTcmMpCnsKICBpZiAobHBzelNyYyAmJiBscHN6U3JjWzBdID09ICcvJyAmJiBscHN6U3JjWzFdID09ICcvJykKICAgIGxwc3pTcmMgKz0gMjsKICByZXR1cm4gbHBzelNyYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNzFdCiAqCiAqIENoZWNrIGlmIHR3byBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgIGxwSW50MSBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQyLgogKiAgIGxwSW50MiBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQxLgogKgogKiBSRVRVUk5TCiAqICAgVFJVRSwgSWYgdGhlIGludGVyZmFjZXMgY29tZSBmcm9tIHRoZSBzYW1lIG9iamVjdC4KICogICBGQUxTRSBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzU2FtZU9iamVjdChJVW5rbm93biogbHBJbnQxLCBJVW5rbm93biogbHBJbnQyKQp7CiAgTFBWT0lEIGxwVW5rbm93bjEsIGxwVW5rbm93bjI7CgogIFRSQUNFKCIlcCAlcFxuIiwgbHBJbnQxLCBscEludDIpOwoKICBpZiAoIWxwSW50MSB8fCAhbHBJbnQyKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBJbnQxID09IGxwSW50MikKICAgIHJldHVybiBUUlVFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDEsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMSkpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDIsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMikpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBVbmtub3duMSA9PSBscFVua25vd24yKQogICAgcmV0dXJuIFRSVUU7CgogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3Ml0KICoKICogR2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBnZXQgdGhlIHdpbmRvdyBoYW5kbGUgb2YKICogIGxwaFduZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHdpbmRvdyBoYW5kbGUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBoV25kIGNvbnRhaW5zIHRoZSBvYmplY3RzIHdpbmRvdyBoYW5kbGUuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCBvbmUgb2YgdGhlIGZvbGxvd2luZyBpbnRlcmZhY2VzOgogKiAgSU9sZVdpbmRvdygpLCBJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUoKSwgb3IgSVNoZWxsVmlldygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0V2luZG93KElVbmtub3duICpscFVua25vd24sIEhXTkQgKmxwaFduZCkKewogIC8qIEZJWE1FOiBXaW5lIGhhcyBubyBoZWFkZXIgZm9yIHRoaXMgb2JqZWN0ICovCiAgc3RhdGljIGNvbnN0IEdVSUQgSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSA9IHsgMHg3OWVhYzllZCwKICAgIDB4YmFmOSwgMHgxMWNlLCB7IDB4OGMsIDB4ODIsIDB4MDAsIDB4YWEsIDB4MDAsIDB4NGIsIDB4YTksIDB4MGIgfX07CiAgSVVua25vd24gKmxwT2xlOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBoV25kKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gaFJldDsKCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlV2luZG93LCAodm9pZCoqKSZscE9sZSk7CgogIGlmIChGQUlMRUQoaFJldCkpCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwmSUlEX0lTaGVsbFZpZXcsICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICB9CiAgfQoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIC8qIExhenluZXNzIGhlcmUgLSBTaW5jZSBHZXRXaW5kb3coKSBpcyB0aGUgZmlyc3QgbWV0aG9kIGZvciB0aGUgYWJvdmUgMwogICAgICogaW50ZXJmYWNlcywgd2UgdXNlIHRoZSBzYW1lIGNhbGwgZm9yIHRoZW0gYWxsLgogICAgICovCiAgICBoUmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cqKWxwT2xlLCBscGhXbmQpOwogICAgSVVua25vd25fUmVsZWFzZShscE9sZSk7CiAgICBpZiAobHBoV25kKQogICAgICBUUkFDRSgiUmV0dXJuaW5nIEhXTkQ9JXBcbiIsICpscGhXbmQpOwogIH0KCiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzNdCiAqCiAqIENhbGwgYSBtZXRob2Qgb24gYXMgYXMgeWV0IHVuaWRlbnRpZmllZCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgcFVuayBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIHVuaWRlbnRpZmllZCBpbnRlcmZhY2UsCiAqICBhcmcgIFtJXSBBcmd1bWVudCBmb3IgdGhlIGNhbGwgb24gdGhlIG9iamVjdC4KICoKICogUkVUVVJOUwogKiAgU19PSy4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1NldE93bmVyKElVbmtub3duICpwVW5rLCBVTE9ORyBhcmcpCnsKICBzdGF0aWMgY29uc3QgR1VJRCBndWlkXzE3MyA9IHsKICAgIDB4NTgzNmZiMDAsIDB4ODE4NywgMHgxMWNmLCB7IDB4YTEsMHgyYiwweDAwLDB4YWEsMHgwMCwweDRhLDB4ZTgsMHgzNyB9CiAgfTsKICBJTWFsbG9jICpwVW5rMjsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIHBVbmssIGFyZyk7CgogIC8qIE5vdGU6IGFyZyBtYXkgbm90IGJlIGEgVUxPTkcgYW5kIHBVbmsyIGlzIGZvciBzdXJlIG5vdCBhbiBJTWFsbG9jIC0KICAgKiAgICAgICBXZSB1c2UgdGhpcyBpbnRlcmZhY2UgYXMgaXRzIHZ0YWJsZSBlbnRyeSBpcyBjb21wYXRpYmxlIHdpdGggdGhlCiAgICogICAgICAgb2JqZWN0IGluIHF1ZXN0aW9uLgogICAqIEZJWE1FOiBGaW5kIG91dCB3aGF0IHRoaXMgb2JqZWN0IGlzIGFuZCB3aGVyZSBpdCBzaG91bGQgYmUgZGVmaW5lZC4KICAgKi8KICBpZiAocFVuayAmJgogICAgICBTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocFVuaywgJmd1aWRfMTczLCAodm9pZCoqKSZwVW5rMikpKQogIHsKICAgIElNYWxsb2NfQWxsb2MocFVuazIsIGFyZyk7IC8qIEZha2VkIGNhbGwhISAqLwogICAgSU1hbGxvY19SZWxlYXNlKHBVbmsyKTsKICB9CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzRdCiAqCiAqIENhbGwgZWl0aGVyIElPYmplY3RXaXRoU2l0ZV9TZXRTaXRlKCkgb3IgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZSgpIG9uCiAqIGFuIG9iamVjdC4KICoKICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1NldFNpdGUoCiAgICAgICAgSVVua25vd24gKm9iaiwgICAgICAgIC8qIFtpbl0gICBPTEUgb2JqZWN0ICAgICAqLwogICAgICAgIElVbmtub3duICpzaXRlKSAgICAgICAvKiBbaW5dICAgU2l0ZSBpbnRlcmZhY2UgKi8KewogICAgSFJFU1VMVCBocjsKICAgIElPYmplY3RXaXRoU2l0ZSAqaW9iandpdGhzaXRlOwogICAgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyICppc2VjbWdyOwoKICAgIGlmICghb2JqKSByZXR1cm4gRV9GQUlMOwoKICAgIGhyID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2Uob2JqLCAmSUlEX0lPYmplY3RXaXRoU2l0ZSwgKExQVk9JRCAqKSZpb2Jqd2l0aHNpdGUpOwogICAgVFJBQ0UoIklJRF9JT2JqZWN0V2l0aFNpdGUgUUkgcmV0PSUwOHgsICVwXG4iLCBociwgaW9iandpdGhzaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgewoJaHIgPSBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZShpb2Jqd2l0aHNpdGUsIHNpdGUpOwoJVFJBQ0UoImRvbmUgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUgcmV0PSUwOHhcbiIsIGhyKTsKCUlVbmtub3duX1JlbGVhc2UoaW9iandpdGhzaXRlKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWhyID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2Uob2JqLCAmSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWFuYWdlciwgKExQVk9JRCAqKSZpc2VjbWdyKTsKCVRSQUNFKCJJSURfSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyIFFJIHJldD0lMDh4LCAlcFxuIiwgaHIsIGlzZWNtZ3IpOwoJaWYgKEZBSUxFRChocikpIHJldHVybiBocjsKCglociA9IElJbnRlcm5ldFNlY3VyaXR5TWFuYWdlcl9TZXRTZWN1cml0eVNpdGUoaXNlY21nciwgKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSAqKXNpdGUpOwoJVFJBQ0UoImRvbmUgSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZSByZXQ9JTA4eFxuIiwgaHIpOwoJSVVua25vd25fUmVsZWFzZShpc2VjbWdyKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NV0KICoKICogQ2FsbCBJUGVyc2lzdF9HZXRDbGFzc0lEKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0IGludGVyZmFjZQogKiAgbHBDbGFzc0lkIFtPXSBEZXN0aW5hdGlvbiBmb3IgQ2xhc3MgSWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBDbGFzc0lkIGNvbnRhaW5zIHRoZSBDbGFzcyBJZCByZXF1ZXN0ZWQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGxwVW5rbm93biBpcyBOVUxMLAogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSBJZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJUGVyc2lzdCwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldENsYXNzSUQoSVVua25vd24gKmxwVW5rbm93biwgQ0xTSUQqIGxwQ2xhc3NJZCkKewogIElQZXJzaXN0KiBscFBlcnNpc3Q7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGxwQ2xhc3NJZCkpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JUGVyc2lzdCwodm9pZCoqKSZscFBlcnNpc3QpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgSVBlcnNpc3RfR2V0Q2xhc3NJRChscFBlcnNpc3QsIGxwQ2xhc3NJZCk7CiAgICAgIElQZXJzaXN0X1JlbGVhc2UobHBQZXJzaXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzZdCiAqCiAqIFJldHJpZXZlIGEgU2VydmljZSBJbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20KICogIHNpZCAgICAgICBbSV0gU2VydmljZSBJRCBmb3IgSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UoKSBjYWxsCiAqICByaWlkICAgICAgW0ldIEZ1bmN0aW9uIHJlcXVlc3RlZCBmb3IgUXVlcnlTZXJ2aWNlIGNhbGwKICogIGxwcE91dCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBzZXJ2aWNlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwcE91dCBjb250YWlucyBhbiBvYmplY3QgcHJvdmlkaW5nIHRoZSByZXF1ZXN0ZWQgc2VydmljZQogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBzaWQsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKmxwcE91dCkKewogIElTZXJ2aWNlUHJvdmlkZXIqIHBTZXJ2aWNlID0gTlVMTDsKICBIUkVTVUxUIGhSZXQ7CgogIGlmICghbHBwT3V0KQogICAgcmV0dXJuIEVfRkFJTDsKCiAgKmxwcE91dCA9IE5VTEw7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgLyogR2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVNlcnZpY2VQcm92aWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopJnBTZXJ2aWNlKTsKCiAgaWYgKCFoUmV0ICYmIHBTZXJ2aWNlKQogIHsKICAgIFRSQUNFKCJRdWVyeUludGVyZmFjZSByZXR1cm5lZCAoSVNlcnZpY2VQcm92aWRlciopJXBcbiIsIHBTZXJ2aWNlKTsKCiAgICAvKiBHZXQgYSBTZXJ2aWNlIGludGVyZmFjZSBmcm9tIHRoZSBvYmplY3QgKi8KICAgIGhSZXQgPSBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZShwU2VydmljZSwgc2lkLCByaWlkLCBscHBPdXQpOwoKICAgIFRSQUNFKCIoSVNlcnZpY2VQcm92aWRlciopJXAgcmV0dXJuZWQgKElVbmtub3duKiklcFxuIiwgcFNlcnZpY2UsICpscHBPdXQpOwoKICAgIC8qIFJlbGVhc2UgdGhlIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlICovCiAgICBJVW5rbm93bl9SZWxlYXNlKHBTZXJ2aWNlKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzddCiAqCiAqIExvYWRzIGEgcG9wdXAgbWVudS4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgW0ldIEluc3RhbmNlIGhhbmRsZQogKiAgc3pOYW1lIFtJXSBNZW51IG5hbWUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgU0hMb2FkTWVudVBvcHVwKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiBzek5hbWUpCnsKICBITUVOVSBoTWVudSwgaFN1Yk1lbnU7CgogIGlmICgoaE1lbnUgPSBMb2FkTWVudVcoaEluc3QsIHN6TmFtZSkpKQogIHsKICAgIGlmICgoaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCAwKSkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0IF9lbnVtV25kRGF0YQp7CiAgVUlOVCAgIHVpTXNnSWQ7CiAgV1BBUkFNIHdQYXJhbTsKICBMUEFSQU0gbFBhcmFtOwogIExSRVNVTFQgKFdJTkFQSSAqcGZuUG9zdCkoSFdORCxVSU5ULFdQQVJBTSxMUEFSQU0pOwp9IGVudW1XbmREYXRhOwoKLyogQ2FsbGJhY2sgZm9yIFNITFdBUElfMTc4ICovCnN0YXRpYyBCT09MIENBTExCQUNLIFNITFdBUElfRW51bUNoaWxkUHJvYyhIV05EIGhXbmQsIExQQVJBTSBsUGFyYW0pCnsKICBlbnVtV25kRGF0YSAqZGF0YSA9IChlbnVtV25kRGF0YSAqKWxQYXJhbTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGhXbmQsIGRhdGEpOwogIGRhdGEtPnBmblBvc3QoaFduZCwgZGF0YS0+dWlNc2dJZCwgZGF0YS0+d1BhcmFtLCBkYXRhLT5sUGFyYW0pOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xNzhdCiAqCiAqIFNlbmQgb3IgcG9zdCBhIG1lc3NhZ2UgdG8gZXZlcnkgY2hpbGQgb2YgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICBbSV0gV2luZG93IHdob3NlIGNoaWxkcmVuIHdpbGwgZ2V0IHRoZSBtZXNzYWdlcwogKiAgdWlNc2dJZCBbSV0gTWVzc2FnZSBJZAogKiAgd1BhcmFtICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqICBiU2VuZCAgIFtJXSBUUlVFID0gVXNlIFNlbmRNZXNzYWdlQSgpLCBGQUxTRSA9IFVzZSBQb3N0TWVzc2FnZUEoKQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKgogKiBOT1RFUwogKiAgVGhlIGFwcHJvcHJpYXRlIEFTQ0lJIG9yIFVuaWNvZGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciB0aGUgd2luZG93LgogKi8Kdm9pZCBXSU5BUEkgU0hQcm9wYWdhdGVNZXNzYWdlKEhXTkQgaFduZCwgVUlOVCB1aU1zZ0lkLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtLCBCT09MIGJTZW5kKQp7CiAgZW51bVduZERhdGEgZGF0YTsKCiAgVFJBQ0UoIiglcCwldSwlZCwlbGQsJWQpXG4iLCBoV25kLCB1aU1zZ0lkLCB3UGFyYW0sIGxQYXJhbSwgYlNlbmQpOwoKICBpZihoV25kKQogIHsKICAgIGRhdGEudWlNc2dJZCA9IHVpTXNnSWQ7CiAgICBkYXRhLndQYXJhbSAgPSB3UGFyYW07CiAgICBkYXRhLmxQYXJhbSAgPSBsUGFyYW07CgogICAgaWYgKGJTZW5kKQogICAgICBkYXRhLnBmblBvc3QgPSBJc1dpbmRvd1VuaWNvZGUoaFduZCkgPyAodm9pZCopU2VuZE1lc3NhZ2VXIDogKHZvaWQqKVNlbmRNZXNzYWdlQTsKICAgIGVsc2UKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVBvc3RNZXNzYWdlVyA6ICh2b2lkKilQb3N0TWVzc2FnZUE7CgogICAgRW51bUNoaWxkV2luZG93cyhoV25kLCBTSExXQVBJX0VudW1DaGlsZFByb2MsIChMUEFSQU0pJmRhdGEpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MF0KICoKICogUmVtb3ZlIGFsbCBzdWItbWVudXMgZnJvbSBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gcmVtb3ZlIHN1Yi1tZW51cyBmcm9tCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IDAuICBBbGwgc3ViLW1lbnVzIHVuZGVyIGhNZW51IGFyZSByZW1vdmVkCiAqICBGYWlsdXJlOiAtMSwgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkCiAqLwpEV09SRCBXSU5BUEkgU0hSZW1vdmVBbGxTdWJNZW51cyhITUVOVSBoTWVudSkKewogIGludCBpSXRlbUNvdW50ID0gR2V0TWVudUl0ZW1Db3VudChoTWVudSkgLSAxOwogIHdoaWxlIChpSXRlbUNvdW50ID49IDApCiAgewogICAgSE1FTlUgaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCBpSXRlbUNvdW50KTsKICAgIGlmIChoU3ViTWVudSkKICAgICAgUmVtb3ZlTWVudShoTWVudSwgaUl0ZW1Db3VudCwgTUZfQllQT1NJVElPTik7CiAgICBpSXRlbUNvdW50LS07CiAgfQogIHJldHVybiBpSXRlbUNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgxXQogKgogKiBFbmFibGUgb3IgZGlzYWJsZSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSAgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gZW5hYmxlL2Rpc2FibGUKICogIGJFbmFibGUgW0ldIFdoZXRoZXIgdG8gZW5hYmxlIChUUlVFKSBvciBkaXNhYmxlIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIEVuYWJsZU1lbnVJdGVtLgogKi8KVUlOVCBXSU5BUEkgU0hFbmFibGVNZW51SXRlbShITUVOVSBoTWVudSwgVUlOVCB3SXRlbUlELCBCT09MIGJFbmFibGUpCnsKICByZXR1cm4gRW5hYmxlTWVudUl0ZW0oaE1lbnUsIHdJdGVtSUQsIGJFbmFibGUgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4xODJdCiAqCiAqIENoZWNrIG9yIHVuY2hlY2sgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBjaGVjay91bmNoZWNrCiAqICBiQ2hlY2sgW0ldIFdoZXRoZXIgdG8gY2hlY2sgKFRSVUUpIG9yIHVuY2hlY2sgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gQ2hlY2tNZW51SXRlbS4KICovCkRXT1JEIFdJTkFQSSBTSENoZWNrTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgdUlELCBCT09MIGJDaGVjaykKewogIHJldHVybiBDaGVja01lbnVJdGVtKGhNZW51LCB1SUQsIGJDaGVjayA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgzXQogKgogKiBSZWdpc3RlciBhIHdpbmRvdyBjbGFzcyBpZiBpdCBpc24ndCBhbHJlYWR5LgogKgogKiBQQVJBTVMKICogIGxwV25kQ2xhc3MgW0ldIFdpbmRvdyBjbGFzcyB0byByZWdpc3RlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIHRoZSBSZWdpc3RlckNsYXNzQSBjYWxsLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJDbGFzc0EoV05EQ0xBU1NBICp3bmRjbGFzcykKewogIFdORENMQVNTQSB3Y2E7CiAgaWYgKEdldENsYXNzSW5mb0Eod25kY2xhc3MtPmhJbnN0YW5jZSwgd25kY2xhc3MtPmxwc3pDbGFzc05hbWUsICZ3Y2EpKQogICAgcmV0dXJuIFRSVUU7CiAgcmV0dXJuIChEV09SRClSZWdpc3RlckNsYXNzQSh3bmRjbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODZdCiAqLwpCT09MIFdJTkFQSSBTSFNpbXVsYXRlRHJvcChJRHJvcFRhcmdldCAqcERyb3AsIElEYXRhT2JqZWN0ICpwRGF0YU9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZ3JmS2V5U3RhdGUsIFBQT0lOVEwgbHBQdCwgRFdPUkQqIHBkd0VmZmVjdCkKewogIERXT1JEIGR3RWZmZWN0ID0gRFJPUEVGRkVDVF9MSU5LIHwgRFJPUEVGRkVDVF9NT1ZFIHwgRFJPUEVGRkVDVF9DT1BZOwogIFBPSU5UTCBwdCA9IHsgMCwgMCB9OwoKICBpZiAoIWxwUHQpCiAgICBscFB0ID0gJnB0OwoKICBpZiAoIXBkd0VmZmVjdCkKICAgIHBkd0VmZmVjdCA9ICZkd0VmZmVjdDsKCiAgSURyb3BUYXJnZXRfRHJhZ0VudGVyKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBpZiAoKnBkd0VmZmVjdCkKICAgIHJldHVybiBJRHJvcFRhcmdldF9Ecm9wKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBJRHJvcFRhcmdldF9EcmFnTGVhdmUocERyb3ApOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg3XQogKgogKiBDYWxsIElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJUGVyc2lzdFByb3BlcnR5QmFnIGludGVyZmFjZQogKiAgbHBQcm9wQmFnIFtPXSBEZXN0aW5hdGlvbiBmb3IgbG9hZGVkIElQcm9wZXJ0eUJhZwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgU0hMb2FkRnJvbVByb3BlcnR5QmFnKElVbmtub3duICpscFVua25vd24sIElQcm9wZXJ0eUJhZyogbHBQcm9wQmFnKQp7CiAgSVBlcnNpc3RQcm9wZXJ0eUJhZyogbHBQUEJhZzsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwUHJvcEJhZyk7CgogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JUGVyc2lzdFByb3BlcnR5QmFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwUFBCYWcpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFBQQmFnKQogICAgewogICAgICBoUmV0ID0gSVBlcnNpc3RQcm9wZXJ0eUJhZ19Mb2FkKGxwUFBCYWcsIGxwUHJvcEJhZywgTlVMTCk7CiAgICAgIElQZXJzaXN0UHJvcGVydHlCYWdfUmVsZWFzZShscFBQQmFnKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE4OF0KICoKICogQ2FsbCBJT2xlQ29udHJvbFNpdGVfVHJhbnNsYXRlQWNjZWxlcmF0b3IoKSAgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZS4KICogIGxwTXNnICAgICAgIFtJXSBLZXkgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQuCiAqICBkd01vZGlmaWVycyBbSV0gRmxhZ3MgY29udGFpbmluZyB0aGUgc3RhdGUgb2YgdGhlIG1vZGlmaWVyIGtleXMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfSU5WQUxJREFSRyBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1RyYW5zbGF0ZUFjY2VsZXJhdG9yT0NTKElVbmtub3duICpscFVua25vd24sIExQTVNHIGxwTXNnLCBEV09SRCBkd01vZGlmaWVycykKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4eClcbiIsIGxwVW5rbm93biwgbHBNc2csIGR3TW9kaWZpZXJzKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbnRyb2xTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ1NpdGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscENTaXRlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbnRyb2xTaXRlX1RyYW5zbGF0ZUFjY2VsZXJhdG9yKGxwQ1NpdGUsIGxwTXNnLCBkd01vZGlmaWVycyk7CiAgICAgIElPbGVDb250cm9sU2l0ZV9SZWxlYXNlKGxwQ1NpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE4OV0KICoKICogQ2FsbCBJT2xlQ29udHJvbFNpdGVfR2V0RXh0ZW5kZWRDb250cm9sKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb250cm9sU2l0ZSBpbnRlcmZhY2UuCiAqICBscHBEaXNwICAgW09dIERlc3RpbmF0aW9uIGZvciByZXN1bHRpbmcgSURpc3BhdGNoLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fT25Gb2N1c09DUyhJVW5rbm93biAqbHBVbmtub3duLCBJRGlzcGF0Y2gqKiBscHBEaXNwKQp7CiAgSU9sZUNvbnRyb2xTaXRlKiBscENTaXRlID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwcERpc3ApOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29udHJvbFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDU2l0ZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwQ1NpdGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29udHJvbFNpdGVfR2V0RXh0ZW5kZWRDb250cm9sKGxwQ1NpdGUsIGxwcERpc3ApOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgW1NITFdBUEkuMTkwXQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fSGFuZGxlSVJlc3RyaWN0KExQVU5LTk9XTiBscFVua25vd24sIFBWT0lEIGxwQXJnMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBWT0lEIGxwQXJnMiwgUFZPSUQgbHBBcmczLCBQVk9JRCBscEFyZzQpCnsKICAvKiBGSVhNRToge0QxMkYyNkIyLUQ5MEEtMTFEMC04MzBELTAwQUEwMDVCNDM4M30gLSBXaGF0IG9iamVjdCBkb2VzIHRoaXMgcmVwcmVzZW50PyAqLwogIHN0YXRpYyBjb25zdCBEV09SRCBzZXJ2aWNlX2lkW10gPSB7IDB4ZDEyZjI2YjIsIDB4MTFkMGQ5MGEsIDB4YWEwMDBkODMsIDB4ODM0MzViMDAgfTsKICAvKiBGSVhNRToge0QxMkYyNkIxLUQ5MEEtMTFEMC04MzBELTAwQUEwMDVCNDM4M30gLSBBbHNvIFVua25vd24vdW5kb2N1bWVudGVkICovCiAgc3RhdGljIGNvbnN0IERXT1JEIGZ1bmN0aW9uX2lkW10gPSB7IDB4ZDEyZjI2YjEsIDB4MTFkMGQ5MGEsIDB4YWEwMDBkODMsIDB4ODM0MzViMDAgfTsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CiAgTFBVTktOT1dOIGxwVW5rSW5uZXIgPSBOVUxMOyAvKiBGSVhNRTogUmVhbCB0eXBlIGlzIHVua25vd24gKi8KCiAgVFJBQ0UoIiglcCwlcCwlcCwlcCwlcClcbiIsIGxwVW5rbm93biwgbHBBcmcxLCBscEFyZzIsIGxwQXJnMywgbHBBcmc0KTsKCiAgaWYgKGxwVW5rbm93biAmJiBscEFyZzQpCiAgewogICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeVNlcnZpY2UobHBVbmtub3duLCAoUkVGR1VJRClzZXJ2aWNlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFJFRkdVSUQpZnVuY3Rpb25faWQsICh2b2lkKiopJmxwVW5rSW5uZXIpOwoKICAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwVW5rSW5uZXIpCiAgICAgewogICAgICAgLyogRklYTUU6IFRoZSB0eXBlIG9mIHNlcnZpY2Ugb2JqZWN0IHJlcXVlc3RlZCBpcyB1bmtub3duLCBob3dldmVyCgkqIHRlc3Rpbmcgc2hvd3MgdGhhdCBpdHMgZmlyc3QgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIDQgcGFyYW1ldGVycy4KCSogRmFrZSB0aGlzIGJ5IHVzaW5nIElQYXJzZURpc3BsYXlOYW1lX1BhcnNlRGlzcGxheU5hbWUgc2luY2UgdGhlCgkqIHNpZ25hdHVyZSBhbmQgcG9zaXRpb24gaW4gdGhlIHZ0YWJsZSBtYXRjaGVzIG91ciB1bmtub3duIG9iamVjdCB0eXBlLgoJKi8KICAgICAgIGhSZXQgPSBJUGFyc2VEaXNwbGF5TmFtZV9QYXJzZURpc3BsYXlOYW1lKChMUFBBUlNFRElTUExBWU5BTUUpbHBVbmtJbm5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwQXJnMSwgbHBBcmcyLCBscEFyZzMsIGxwQXJnNCk7CiAgICAgICBJVW5rbm93bl9SZWxlYXNlKGxwVW5rSW5uZXIpOwogICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgW1NITFdBUEkuMTkyXQogKgogKiBHZXQgYSBzdWItbWVudSBmcm9tIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIGdldCBzdWItbWVudSBmcm9tCiAqICB1SUQgICBbSV0gSUQgb2YgbWVudSBpdGVtIGNvbnRhaW5pbmcgc3ViLW1lbnUKICoKICogUkVUVVJOUwogKiAgVGhlIHN1Yi1tZW51IG9mIHRoZSBpdGVtLCBvciBhIE5VTEwgaGFuZGxlIGlmIGFueSBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkLgogKi8KSE1FTlUgV0lOQVBJIFNIR2V0TWVudUZyb21JRChITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICBNRU5VSVRFTUlORk9XIG1pOwoKICBUUkFDRSgiKCVwLCV1KVxuIiwgaE1lbnUsIHVJRCk7CgogIG1pLmNiU2l6ZSA9IHNpemVvZihtaSk7CiAgbWkuZk1hc2sgPSBNSUlNX1NVQk1FTlU7CgogIGlmICghR2V0TWVudUl0ZW1JbmZvVyhoTWVudSwgdUlELCBGQUxTRSwgJm1pKSkKICAgIHJldHVybiBOVUxMOwoKICByZXR1cm4gbWkuaFN1Yk1lbnU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTNdCiAqCiAqIEdldCB0aGUgY29sb3IgZGVwdGggb2YgdGhlIHByaW1hcnkgZGlzcGxheS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgY29sb3IgZGVwdGggb2YgdGhlIHByaW1hcnkgZGlzcGxheS4KICovCkRXT1JEIFdJTkFQSSBTSEdldEN1ckNvbG9yUmVzKHZvaWQpCnsKICAgIEhEQyBoZGM7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0UoIigpXG4iKTsKCiAgICBoZGMgPSBHZXREQygwKTsKICAgIHJldCA9IEdldERldmljZUNhcHMoaGRjLCBCSVRTUElYRUwpICogR2V0RGV2aWNlQ2FwcyhoZGMsIFBMQU5FUyk7CiAgICBSZWxlYXNlREMoMCwgaGRjKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTRdCiAqCiAqIFdhaXQgZm9yIGEgbWVzc2FnZSB0byBhcnJpdmUsIHdpdGggYSB0aW1lb3V0LgogKgogKiBQQVJBTVMKICogIGhhbmQgICAgICBbSV0gSGFuZGxlIHRvIHF1ZXJ5CiAqICBkd1RpbWVvdXQgW0ldIFRpbWVvdXQgaW4gdGlja3Mgb3IgSU5GSU5JVEUgdG8gbmV2ZXIgdGltZW91dAogKgogKiBSRVRVUk5TCiAqICBTVEFUVVNfVElNRU9VVCBpZiBubyBtZXNzYWdlIGlzIHJlY2VpdmVkIGJlZm9yZSBkd1RpbWVvdXQgdGlja3MgcGFzc2VzLgogKiAgT3RoZXJ3aXNlIHJldHVybnMgdGhlIHZhbHVlIGZyb20gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0c0V4IHdoZW4gYQogKiAgbWVzc2FnZSBpcyBhdmFpbGFibGUuCiAqLwpEV09SRCBXSU5BUEkgU0hXYWl0Rm9yU2VuZE1lc3NhZ2VUaHJlYWQoSEFORExFIGhhbmQsIERXT1JEIGR3VGltZW91dCkKewogIERXT1JEIGR3RW5kVGlja3MgPSBHZXRUaWNrQ291bnQoKSArIGR3VGltZW91dDsKICBEV09SRCBkd1JldDsKCiAgd2hpbGUgKChkd1JldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCgxLCAmaGFuZCwgZHdUaW1lb3V0LCBRU19TRU5ETUVTU0FHRSwgMCkpID09IDEpCiAgewogICAgTVNHIG1zZzsKCiAgICBQZWVrTWVzc2FnZVcoJm1zZywgTlVMTCwgMCwgMCwgUE1fTk9SRU1PVkUpOwoKICAgIGlmIChkd1RpbWVvdXQgIT0gSU5GSU5JVEUpCiAgICB7CiAgICAgICAgaWYgKChpbnQpKGR3VGltZW91dCA9IGR3RW5kVGlja3MgLSBHZXRUaWNrQ291bnQoKSkgPD0gMCkKICAgICAgICAgICAgcmV0dXJuIFdBSVRfVElNRU9VVDsKICAgIH0KICB9CgogIHJldHVybiBkd1JldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5NV0KICoKICogRGV0ZXJtaW5lIGlmIGEgc2hlbGwgZm9sZGVyIGNhbiBiZSBleHBhbmRlZC4KICoKICogUEFSQU1TCiAqICBscEZvbGRlciBbSV0gUGFyZW50IGZvbGRlciBjb250YWluaW5nIHRoZSBvYmplY3QgdG8gdGVzdC4KICogIHBpZGwgICAgIFtJXSBJZCBvZiB0aGUgb2JqZWN0IHRvIHRlc3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0ssIGlmIHRoZSBvYmplY3QgaXMgZXhwYW5kYWJsZSwgU19GQUxTRSBvdGhlcndpc2UuCiAqICBGYWlsdXJlOiBFX0lOVkFMSURBUkcsIGlmIGFueSBhcmd1bWVudCBpcyBpbnZhbGlkLgogKgogKiBOT1RFUwogKiAgSWYgdGhlIG9iamVjdCB0byBiZSB0ZXN0ZWQgZG9lcyBub3QgZXhwb3NlIHRoZSBJUXVlcnlJbmZvKCkgaW50ZXJmYWNlIGl0CiAqICB3aWxsIG5vdCBiZSBpZGVudGlmaWVkIGFzIGFuIGV4cGFuZGFibGUgZm9sZGVyLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJc0V4cGFuZGFibGVGb2xkZXIoTFBTSEVMTEZPTERFUiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIElRdWVyeUluZm8gKmxwSW5mbzsKCiAgaWYgKGxwRm9sZGVyICYmIHBpZGwpCiAgewogICAgaFJldCA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKGxwRm9sZGVyLCBOVUxMLCAxLCAmcGlkbCwgJklJRF9JUXVlcnlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICh2b2lkKiopJmxwSW5mbyk7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICBoUmV0ID0gU19GQUxTRTsgLyogRG9lc24ndCBleHBvc2UgSVF1ZXJ5SW5mbyAqLwogICAgZWxzZQogICAgewogICAgICBEV09SRCBkd0ZsYWdzID0gMDsKCiAgICAgIC8qIE1TRE4gc3RhdGVzIG9mIElRdWVyeUluZm9fR2V0SW5mb0ZsYWdzKCkgdGhhdCAiVGhpcyBtZXRob2QgaXMgbm90CiAgICAgICAqIGN1cnJlbnRseSB1c2VkIi4gUmVhbGx5PyBZb3Ugd291bGRuJ3QgYmUgaG9sZGluZyBvdXQgb24gbWUgd291bGQgeW91PwogICAgICAgKi8KICAgICAgaFJldCA9IElRdWVyeUluZm9fR2V0SW5mb0ZsYWdzKGxwSW5mbywgJmR3RmxhZ3MpOwoKICAgICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgICAgewogICAgICAgIC8qIDB4MiBpcyBhbiB1bmRvY3VtZW50ZWQgZmxhZyBhcHBhcmVudGx5IGluZGljYXRpbmcgZXhwYW5kYWJpbGl0eSAqLwogICAgICAgIGhSZXQgPSBkd0ZsYWdzICYgMHgyID8gU19PSyA6IFNfRkFMU0U7CiAgICAgIH0KCiAgICAgIElRdWVyeUluZm9fUmVsZWFzZShscEluZm8pOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5N10KICoKICogQmxhbmsgb3V0IGEgcmVnaW9uIG9mIHRleHQgYnkgZHJhd2luZyB0aGUgYmFja2dyb3VuZCBvbmx5LgogKgogKiBQQVJBTVMKICogIGhEQyAgIFtJXSBEZXZpY2UgY29udGV4dCB0byBkcmF3IGluCiAqICBwUmVjdCBbSV0gQXJlYSB0byBkcmF3IGluCiAqICBjUmVmICBbSV0gQ29sb3IgdG8gZHJhdyBpbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIFNIRmlsbFJlY3RDbHIoSERDIGhEQywgTFBDUkVDVCBwUmVjdCwgQ09MT1JSRUYgY1JlZikKewogICAgQ09MT1JSRUYgY09sZENvbG9yID0gU2V0QmtDb2xvcihoREMsIGNSZWYpOwogICAgRXh0VGV4dE91dEEoaERDLCAwLCAwLCBFVE9fT1BBUVVFLCBwUmVjdCwgMCwgMCwgMCk7CiAgICBTZXRCa0NvbG9yKGhEQywgY09sZENvbG9yKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk4XQogKgogKiBSZXR1cm4gdGhlIHZhbHVlIGFzb2NpYXRlZCB3aXRoIGEga2V5IGluIGEgbWFwLgogKgogKiBQQVJBTVMKICogIGxwS2V5cyAgIFtJXSBBIGxpc3Qgb2Yga2V5cyBvZiBsZW5ndGggaUxlbgogKiAgbHBWYWx1ZXMgW0ldIEEgbGlzdCBvZiB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxwS2V5cywgb2YgbGVuZ3RoIGlMZW4KICogIGlMZW4gICAgIFtJXSBMZW5ndGggb2YgYm90aCBscEtleXMgYW5kIGxwVmFsdWVzCiAqICBpS2V5ICAgICBbSV0gVGhlIGtleSB2YWx1ZSB0byBsb29rIHVwIGluIGxwS2V5cwogKgogKiBSRVRVUk5TCiAqICBUaGUgdmFsdWUgaW4gbHBWYWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGlLZXksIG9yIC0xIGlmIGlLZXkgaXMgbm90CiAqICBmb3VuZCBpbiBscEtleXMuCiAqCiAqIE5PVEVTCiAqICAtIElmIHR3byBlbGVtZW50cyBpbiB0aGUgbWFwIHNoYXJlIHRoZSBzYW1lIGtleSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zCiAqICAgIHRoZSB2YWx1ZSBjbG9zZXN0IHRvIHRoZSBzdGFydCBvZiB0aGUgbWFwCiAqICAtIFRoZSBuYXRpdmUgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIGNyYXNoZXMgaWYgbHBLZXlzIG9yIGxwVmFsdWVzIGlzIE5VTEwuCiAqLwppbnQgV0lOQVBJIFNIU2VhcmNoTWFwSW50KGNvbnN0IGludCAqbHBLZXlzLCBjb25zdCBpbnQgKmxwVmFsdWVzLCBpbnQgaUxlbiwgaW50IGlLZXkpCnsKICBpZiAobHBLZXlzICYmIGxwVmFsdWVzKQogIHsKICAgIGludCBpID0gMDsKCiAgICB3aGlsZSAoaSA8IGlMZW4pCiAgICB7CiAgICAgIGlmIChscEtleXNbaV0gPT0gaUtleSkKICAgICAgICByZXR1cm4gbHBWYWx1ZXNbaV07IC8qIEZvdW5kICovCiAgICAgIGkrKzsKICAgIH0KICB9CiAgcmV0dXJuIC0xOyAvKiBOb3QgZm91bmQgKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTldCiAqCiAqIENvcHkgYW4gaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUEFSQU1TCiAqICAgbHBwRGVzdCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29weQogKiAgIGxwVW5rbm93biBbSV0gU291cmNlIGZvciBjb3B5CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBJVW5rbm93bl9TZXQoSVVua25vd24gKipscHBEZXN0LCBJVW5rbm93biAqbHBVbmtub3duKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwcERlc3QsIGxwVW5rbm93bik7CgogIGlmIChscHBEZXN0KQogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBEZXN0KTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICAvKiBDb3B5ICovCiAgICBJVW5rbm93bl9BZGRSZWYobHBVbmtub3duKTsKICAgICpscHBEZXN0ID0gbHBVbmtub3duOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMF0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heVFTRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBQVk9JRCBscFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGR1VJRCByaWlkQ21kR3JwLCBVTE9ORyBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBGSVhNRSgiKCVwLCVwLCVwLCVkLCVwLCVwKSAtIHN0dWJcbiIsCiAgICAgICAgbHBVbmtub3duLCBscFJlc2VydmVkLCByaWlkQ21kR3JwLCBjQ21kcywgcHJnQ21kcywgcENtZFRleHQpOwoKICAvKiBGSVhNRTogQ2FsbHMgSXNRU0ZvcndhcmQgJiBJVW5rbm93bl9RdWVyeVN0YXR1cyAqLwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBNYXlFeGVjRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBJTlQgaVVuaywgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBuQ21kSUQsIERXT1JEIG5DbWRleGVjb3B0LCBWQVJJQU5UKiBwdmFJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFOVCogcHZhT3V0KQp7CiAgRklYTUUoIiglcCwlZCwlcCwlZCwlZCwlcCwlcCkgLSBzdHViIVxuIiwgbHBVbmtub3duLCBpVW5rLCBwZ3VpZENtZEdyb3VwLAogICAgICAgIG5DbWRJRCwgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBJc1FTRm9yd2FyZChSRUZHVUlEIHBndWlkQ21kR3JvdXAsVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcykKewogIEZJWE1FKCIoJXAsJWQsJXApIC0gc3R1YiFcbiIsIHBndWlkQ21kR3JvdXAsIGNDbWRzLCBwcmdDbWRzKTsKICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBACVtTSExXQVBJLjIwNF0KICoKICogRGV0ZXJtaW5lIGlmIGEgd2luZG93IGlzIG5vdCBhIGNoaWxkIG9mIGFub3RoZXIgd2luZG93LgogKgogKiBQQVJBTVMKICogaFBhcmVudCBbSV0gU3VzcGVjdGVkIHBhcmVudCB3aW5kb3cKICogaENoaWxkICBbSV0gU3VzcGVjdGVkIGNoaWxkIHdpbmRvdwogKgogKiBSRVRVUk5TCiAqIFRSVUU6ICBJZiBoQ2hpbGQgaXMgYSBjaGlsZCB3aW5kb3cgb2YgaFBhcmVudAogKiBGQUxTRTogSWYgaENoaWxkIGlzIG5vdCBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50LCBvciB0aGV5IGFyZSBlcXVhbAogKi8KQk9PTCBXSU5BUEkgU0hJc0NoaWxkT3JTZWxmKEhXTkQgaFBhcmVudCwgSFdORCBoQ2hpbGQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFBhcmVudCwgaENoaWxkKTsKCiAgaWYgKCFoUGFyZW50IHx8ICFoQ2hpbGQpCiAgICByZXR1cm4gVFJVRTsKICBlbHNlIGlmKGhQYXJlbnQgPT0gaENoaWxkKQogICAgcmV0dXJuIEZBTFNFOwogIHJldHVybiAhSXNDaGlsZChoUGFyZW50LCBoQ2hpbGQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICBGRFNBIGZ1bmN0aW9ucy4gIE1hbmFnZSBhIGR5bmFtaWMgYXJyYXkgb2YgZml4ZWQgc2l6ZSBtZW1vcnkgYmxvY2tzLgogKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIERXT1JEIG51bV9pdGVtczsgICAgICAgLyogTnVtYmVyIG9mIGVsZW1lbnRzIGluc2VydGVkICovCiAgICB2b2lkICptZW07ICAgICAgICAgICAgIC8qIFB0ciB0byBhcnJheSAqLwogICAgRFdPUkQgYmxvY2tzX2FsbG9jZWQ7ICAvKiBOdW1iZXIgb2YgZWxlbWVudHMgYWxsb2NhdGVkICovCiAgICBCWVRFIGluYzsgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBlbGVtZW50cyB0byBncm93IGJ5IHdoZW4gd2UgbmVlZCB0byBleHBhbmQgKi8KICAgIEJZVEUgYmxvY2tfc2l6ZTsgICAgICAgLyogU2l6ZSBpbiBieXRlcyBvZiBhbiBlbGVtZW50ICovCiAgICBCWVRFIGZsYWdzOyAgICAgICAgICAgIC8qIEZsYWdzICovCn0gRkRTQV9pbmZvOwoKI2RlZmluZSBGRFNBX0ZMQUdfSU5URVJOQUxfQUxMT0MgMHgwMSAvKiBXaGVuIHNldCB3ZSBoYXZlIGFsbG9jYXRlZCBtZW0gaW50ZXJuYWxseSAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwOF0KICoKICogSW5pdGlhbGl6ZSBhbiBGRFNBIGFycmFyeS4gCiAqLwpCT09MIFdJTkFQSSBGRFNBX0luaXRpYWxpemUoRFdPUkQgYmxvY2tfc2l6ZSwgRFdPUkQgaW5jLCBGRFNBX2luZm8gKmluZm8sIHZvaWQgKm1lbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGluaXRfYmxvY2tzKQp7CiAgICBUUkFDRSgiKDB4JTA4eCAweCUwOHggJXAgJXAgMHglMDh4KVxuIiwgYmxvY2tfc2l6ZSwgaW5jLCBpbmZvLCBtZW0sIGluaXRfYmxvY2tzKTsKCiAgICBpZihpbmMgPT0gMCkKICAgICAgICBpbmMgPSAxOwoKICAgIGlmKG1lbSkKICAgICAgICBtZW1zZXQobWVtLCAwLCBibG9ja19zaXplICogaW5pdF9ibG9ja3MpOwogICAgCiAgICBpbmZvLT5udW1faXRlbXMgPSAwOwogICAgaW5mby0+aW5jID0gaW5jOwogICAgaW5mby0+bWVtID0gbWVtOwogICAgaW5mby0+YmxvY2tzX2FsbG9jZWQgPSBpbml0X2Jsb2NrczsKICAgIGluZm8tPmJsb2NrX3NpemUgPSBibG9ja19zaXplOwogICAgaW5mby0+ZmxhZ3MgPSAwOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA5XQogKgogKiBEZXN0cm95IGFuIEZEU0EgYXJyYXkKICovCkJPT0wgV0lOQVBJIEZEU0FfRGVzdHJveShGRFNBX2luZm8gKmluZm8pCnsKICAgIFRSQUNFKCIoJXApXG4iLCBpbmZvKTsKCiAgICBpZihpbmZvLT5mbGFncyAmIEZEU0FfRkxBR19JTlRFUk5BTF9BTExPQykKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvLT5tZW0pOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxMF0KICoKICogSW5zZXJ0IGVsZW1lbnQgaW50byBhbiBGRFNBIGFycmF5CiAqLwpEV09SRCBXSU5BUEkgRkRTQV9JbnNlcnRJdGVtKEZEU0FfaW5mbyAqaW5mbywgRFdPUkQgd2hlcmUsIGNvbnN0IHZvaWQgKmJsb2NrKQp7CiAgICBUUkFDRSgiKCVwIDB4JTA4eCAlcClcbiIsIGluZm8sIHdoZXJlLCBibG9jayk7CiAgICBpZih3aGVyZSA+IGluZm8tPm51bV9pdGVtcykKICAgICAgICB3aGVyZSA9IGluZm8tPm51bV9pdGVtczsKCiAgICBpZihpbmZvLT5udW1faXRlbXMgPj0gaW5mby0+YmxvY2tzX2FsbG9jZWQpCiAgICB7CiAgICAgICAgRFdPUkQgc2l6ZSA9IChpbmZvLT5ibG9ja3NfYWxsb2NlZCArIGluZm8tPmluYykgKiBpbmZvLT5ibG9ja19zaXplOwogICAgICAgIGlmKGluZm8tPmZsYWdzICYgMHgxKQogICAgICAgICAgICBpbmZvLT5tZW0gPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBpbmZvLT5tZW0sIHNpemUpOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHZvaWQgKm9sZF9tZW0gPSBpbmZvLT5tZW07CiAgICAgICAgICAgIGluZm8tPm1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplKTsKICAgICAgICAgICAgbWVtY3B5KGluZm8tPm1lbSwgb2xkX21lbSwgaW5mby0+YmxvY2tzX2FsbG9jZWQgKiBpbmZvLT5ibG9ja19zaXplKTsKICAgICAgICB9CiAgICAgICAgaW5mby0+YmxvY2tzX2FsbG9jZWQgKz0gaW5mby0+aW5jOwogICAgICAgIGluZm8tPmZsYWdzIHw9IDB4MTsKICAgIH0KCiAgICBpZih3aGVyZSA8IGluZm8tPm51bV9pdGVtcykKICAgIHsKICAgICAgICBtZW1tb3ZlKChjaGFyKilpbmZvLT5tZW0gKyAod2hlcmUgKyAxKSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoY2hhciopaW5mby0+bWVtICsgd2hlcmUgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGluZm8tPm51bV9pdGVtcyAtIHdoZXJlKSAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgfQogICAgbWVtY3B5KChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsIGJsb2NrLCBpbmZvLT5ibG9ja19zaXplKTsKCiAgICBpbmZvLT5udW1faXRlbXMrKzsKICAgIHJldHVybiB3aGVyZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxMV0KICoKICogRGVsZXRlIGFuIGVsZW1lbnQgZnJvbSBhbiBGRFNBIGFycmF5LgogKi8KQk9PTCBXSU5BUEkgRkRTQV9EZWxldGVJdGVtKEZEU0FfaW5mbyAqaW5mbywgRFdPUkQgd2hlcmUpCnsKICAgIFRSQUNFKCIoJXAgMHglMDh4KVxuIiwgaW5mbywgd2hlcmUpOwoKICAgIGlmKHdoZXJlID49IGluZm8tPm51bV9pdGVtcykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYod2hlcmUgPCBpbmZvLT5udW1faXRlbXMgLSAxKQogICAgewogICAgICAgIG1lbW1vdmUoKGNoYXIqKWluZm8tPm1lbSArIHdoZXJlICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChjaGFyKilpbmZvLT5tZW0gKyAod2hlcmUgKyAxKSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoaW5mby0+bnVtX2l0ZW1zIC0gd2hlcmUgLSAxKSAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgfQogICAgbWVtc2V0KChjaGFyKilpbmZvLT5tZW0gKyAoaW5mby0+bnVtX2l0ZW1zIC0gMSkgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgIDAsIGluZm8tPmJsb2NrX3NpemUpOwogICAgaW5mby0+bnVtX2l0ZW1zLS07CiAgICByZXR1cm4gVFJVRTsKfQoKCnR5cGVkZWYgc3RydWN0IHsKICAgIFJFRklJRCAgIHJlZmlkOwogICAgRFdPUkQgICAgaW5keDsKfSBJRkFDRV9JTkRFWF9UQkw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjE5XQogKgogKiBDYWxsIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKCkgb24gYSB0YWJsZSBvZiBvYmplY3RzLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSIG9yIEVfTk9JTlRFUkZBQ0UuCiAqLwpIUkVTVUxUIFdJTkFQSSBRSVNlYXJjaCgKCUxQVk9JRCB3LCAgICAgICAgICAgLyogW2luXSAgIFRhYmxlIG9mIGludGVyZmFjZXMgKi8KCUlGQUNFX0lOREVYX1RCTCAqeCwgLyogW2luXSAgIEFycmF5IG9mIFJFRklJRHMgYW5kIGluZGV4ZXMgaW50byB0aGUgdGFibGUgKi8KCVJFRklJRCByaWlkLCAgICAgICAgLyogW2luXSAgIFJFRklJRCB0byBnZXQgaW50ZXJmYWNlIGZvciAqLwoJTFBWT0lEICpwcHYpICAgICAgICAgIC8qIFtvdXRdICBEZXN0aW5hdGlvbiBmb3IgaW50ZXJmYWNlIHBvaW50ZXIgKi8KewoJSFJFU1VMVCByZXQ7CglJVW5rbm93biAqYV92dGJsOwoJSUZBQ0VfSU5ERVhfVEJMICp4bW92ZTsKCglUUkFDRSgiKCVwICVwICVzICVwKVxuIiwgdyx4LGRlYnVnc3RyX2d1aWQocmlpZCkscHB2KTsKCWlmIChwcHYpIHsKCSAgICB4bW92ZSA9IHg7CgkgICAgd2hpbGUgKHhtb3ZlLT5yZWZpZCkgewoJCVRSQUNFKCJ0cnlpbmcgKGluZHggJWQpICVzXG4iLCB4bW92ZS0+aW5keCwgZGVidWdzdHJfZ3VpZCh4bW92ZS0+cmVmaWQpKTsKCQlpZiAoSXNFcXVhbElJRChyaWlkLCB4bW92ZS0+cmVmaWQpKSB7CgkJICAgIGFfdnRibCA9IChJVW5rbm93biopKHhtb3ZlLT5pbmR4ICsgKExQQllURSl3KTsKCQkgICAgVFJBQ0UoIm1hdGNoZWQsIHJldHVybmluZyAoJXApXG4iLCBhX3Z0YmwpOwoJCSAgICAqcHB2ID0gKExQVk9JRClhX3Z0Ymw7CgkJICAgIElVbmtub3duX0FkZFJlZihhX3Z0YmwpOwoJCSAgICByZXR1cm4gU19PSzsKCQl9CgkJeG1vdmUrKzsKCSAgICB9CgoJICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSB7CgkJYV92dGJsID0gKElVbmtub3duKikoeC0+aW5keCArIChMUEJZVEUpdyk7CgkJVFJBQ0UoInJldHVybmluZyBmaXJzdCBmb3IgSVVua25vd24gKCVwKVxuIiwgYV92dGJsKTsKCQkqcHB2ID0gKExQVk9JRClhX3Z0Ymw7CgkJSVVua25vd25fQWRkUmVmKGFfdnRibCk7CgkJcmV0dXJuIFNfT0s7CgkgICAgfQoJICAgICpwcHYgPSAwOwoJICAgIHJldCA9IEVfTk9JTlRFUkZBQ0U7Cgl9IGVsc2UKCSAgICByZXQgPSBFX1BPSU5URVI7CgoJVFJBQ0UoIi0tIDB4JTA4eFxuIiwgcmV0KTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMjFdCiAqCiAqIFJlbW92ZSB0aGUgIlByb3BEbGdGb250IiBwcm9wZXJ0eSBmcm9tIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgW0ldIFdpbmRvdyB0byByZW1vdmUgdGhlIHByb3BlcnR5IGZyb20KICoKICogUkVUVVJOUwogKiAgQSBoYW5kbGUgdG8gdGhlIHJlbW92ZWQgcHJvcGVydHksIG9yIE5VTEwgaWYgaXQgZGlkIG5vdCBleGlzdC4KICovCkhBTkRMRSBXSU5BUEkgU0hSZW1vdmVEZWZhdWx0RGlhbG9nRm9udChIV05EIGhXbmQpCnsKICBIQU5ETEUgaFByb3A7CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaFByb3AgPSBHZXRQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKCiAgaWYoaFByb3ApCiAgewogICAgRGVsZXRlT2JqZWN0KGhQcm9wKTsKICAgIGhQcm9wID0gUmVtb3ZlUHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CiAgfQogIHJldHVybiBoUHJvcDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzNl0KICoKICogTG9hZCB0aGUgaW4tcHJvY2VzcyBzZXJ2ZXIgb2YgYSBnaXZlbiBHVUlELgogKgogKiBQQVJBTVMKICogIHJlZmlpZCBbSV0gR1VJRCBvZiB0aGUgc2VydmVyIHRvIGxvYWQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgc2VydmVyIGRsbC4KICogIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqLwpITU9EVUxFIFdJTkFQSSBTSFBpbkRsbE9mQ0xTSUQoUkVGSUlEIHJlZmlpZCkKewogICAgSEtFWSBuZXdrZXk7CiAgICBEV09SRCB0eXBlLCBjb3VudDsKICAgIENIQVIgdmFsdWVbTUFYX1BBVEhdLCBzdHJpbmdbTUFYX1BBVEhdOwoKICAgIHN0cmNweShzdHJpbmcsICJDTFNJRFxcIik7CiAgICBTSFN0cmluZ0Zyb21HVUlEQShyZWZpaWQsIHN0cmluZyArIDYsIHNpemVvZihzdHJpbmcpL3NpemVvZihjaGFyKSAtIDYpOwogICAgc3RyY2F0KHN0cmluZywgIlxcSW5Qcm9jU2VydmVyMzIiKTsKCiAgICBjb3VudCA9IE1BWF9QQVRIOwogICAgUmVnT3BlbktleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwgc3RyaW5nLCAwLCAxLCAmbmV3a2V5KTsKICAgIFJlZ1F1ZXJ5VmFsdWVFeEEobmV3a2V5LCAwLCAwLCAmdHlwZSwgKFBCWVRFKXZhbHVlLCAmY291bnQpOwogICAgUmVnQ2xvc2VLZXkobmV3a2V5KTsKICAgIHJldHVybiBMb2FkTGlicmFyeUV4QSh2YWx1ZSwgMCwgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzddCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE4My4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NXKFdORENMQVNTVyAqIGxwV25kQ2xhc3MpCnsKCVdORENMQVNTVyBXbmRDbGFzczsKCglUUkFDRSgiKCVwICVzKVxuIixscFduZENsYXNzLT5oSW5zdGFuY2UsIGRlYnVnc3RyX3cobHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSkpOwoKCWlmIChHZXRDbGFzc0luZm9XKGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgbHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSwgJlduZENsYXNzKSkKCQlyZXR1cm4gVFJVRTsKCXJldHVybiBSZWdpc3RlckNsYXNzVyhscFduZENsYXNzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOF0KICoKICogVW5yZWdpc3RlciBhIGxpc3Qgb2YgY2xhc3Nlcy4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgICAgIFtJXSBBcHBsaWNhdGlvbiBpbnN0YW5jZSB0aGF0IHJlZ2lzdGVyZWQgdGhlIGNsYXNzZXMKICogIGxwcENsYXNzZXMgW0ldIExpc3Qgb2YgY2xhc3MgbmFtZXMKICogIGlDb3VudCAgICAgW0ldIE51bWJlciBvZiBuYW1lcyBpbiBscHBDbGFzc2VzCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwp2b2lkIFdJTkFQSSBTSFVucmVnaXN0ZXJDbGFzc2VzQShISU5TVEFOQ0UgaEluc3QsIExQQ1NUUiAqbHBwQ2xhc3NlcywgSU5UIGlDb3VudCkKewogIFdORENMQVNTQSBXbmRDbGFzczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGhJbnN0LCBscHBDbGFzc2VzLCBpQ291bnQpOwoKICB3aGlsZSAoaUNvdW50ID4gMCkKICB7CiAgICBpZiAoR2V0Q2xhc3NJbmZvQShoSW5zdCwgKmxwcENsYXNzZXMsICZXbmRDbGFzcykpCiAgICAgIFVucmVnaXN0ZXJDbGFzc0EoKmxwcENsYXNzZXMsIGhJbnN0KTsKICAgIGxwcENsYXNzZXMrKzsKICAgIGlDb3VudC0tOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOV0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIVW5yZWdpc3RlckNsYXNzZXNBLgogKi8Kdm9pZCBXSU5BUEkgU0hVbnJlZ2lzdGVyQ2xhc3Nlc1coSElOU1RBTkNFIGhJbnN0LCBMUENXU1RSICpscHBDbGFzc2VzLCBJTlQgaUNvdW50KQp7CiAgV05EQ0xBU1NXIFduZENsYXNzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaEluc3QsIGxwcENsYXNzZXMsIGlDb3VudCk7CgogIHdoaWxlIChpQ291bnQgPiAwKQogIHsKICAgIGlmIChHZXRDbGFzc0luZm9XKGhJbnN0LCAqbHBwQ2xhc3NlcywgJlduZENsYXNzKSkKICAgICAgVW5yZWdpc3RlckNsYXNzVygqbHBwQ2xhc3NlcywgaEluc3QpOwogICAgbHBwQ2xhc3NlcysrOwogICAgaUNvdW50LS07CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjQwXQogKgogKiBDYWxsIFRoZSBjb3JyZWN0IChBc2NpaS9Vbmljb2RlKSBkZWZhdWx0IHdpbmRvdyBwcm9jZWR1cmUgZm9yIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBXaW5kb3cgdG8gY2FsbCB0aGUgZGVmYXVsdCBwcm9jZWR1cmUgZm9yCiAqICB1TWVzc2FnZSBbSV0gTWVzc2FnZSBJRAogKiAgd1BhcmFtICAgW0ldIFdQQVJBTSBvZiBtZXNzYWdlCiAqICBsUGFyYW0gICBbSV0gTFBBUkFNIG9mIG1lc3NhZ2UKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiBjYWxsaW5nIERlZldpbmRvd1Byb2NBKCkgb3IgRGVmV2luZG93UHJvY1coKS4KICovCkxSRVNVTFQgQ0FMTEJBQ0sgU0hEZWZXaW5kb3dQcm9jKEhXTkQgaFduZCwgVUlOVCB1TWVzc2FnZSwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewoJaWYgKElzV2luZG93VW5pY29kZShoV25kKSkKCQlyZXR1cm4gRGVmV2luZG93UHJvY1coaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMjU2XQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0U2l0ZShMUFVOS05PV04gbHBVbmtub3duLCBSRUZJSUQgaWlkLCBQVk9JRCAqbHBwU2l0ZSkKewogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKICBMUE9CSkVDVFdJVEhTSVRFIGxwU2l0ZSA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBscFVua25vd24sIGRlYnVnc3RyX2d1aWQoaWlkKSwgbHBwU2l0ZSk7CgogIGlmIChscFVua25vd24gJiYgaWlkICYmIGxwcFNpdGUpCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2JqZWN0V2l0aFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBTaXRlKQogICAgewogICAgICBoUmV0ID0gSU9iamVjdFdpdGhTaXRlX0dldFNpdGUobHBTaXRlLCBpaWQsIGxwcFNpdGUpOwogICAgICBJT2JqZWN0V2l0aFNpdGVfUmVsZWFzZShscFNpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI1N10KICoKICogQ3JlYXRlIGEgd29ya2VyIHdpbmRvdyB1c2luZyBDcmVhdGVXaW5kb3dFeEEoKS4KICoKICogUEFSQU1TCiAqICB3bmRQcm9jICAgIFtJXSBXaW5kb3cgcHJvY2VkdXJlCiAqICBoV25kUGFyZW50IFtJXSBQYXJlbnQgd2luZG93CiAqICBkd0V4U3R5bGUgIFtJXSBFeHRyYSBzdHlsZSBmbGFncwogKiAgZHdTdHlsZSAgICBbSV0gU3R5bGUgZmxhZ3MKICogIGhNZW51ICAgICAgW0ldIFdpbmRvdyBtZW51CiAqICB6ICAgICAgICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSB3aW5kb3cgaGFuZGxlIG9mIHRoZSBuZXdseSBjcmVhdGVkIHdpbmRvdy4KICogIEZhaWx1cmU6IDAuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd0EoTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBjaGFyIHN6Q2xhc3NbXSA9ICJXb3JrZXJBIjsKICBXTkRDTEFTU0Egd2M7CiAgSFdORCBoV25kOwoKICBUUkFDRSgiKDB4JTA4eCwlcCwweCUwOHgsMHglMDh4LCVwLDB4JTA4eClcbiIsCiAgICAgICAgIHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NBOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gTlVMTDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoTlVMTCwgKExQU1RSKUlEQ19BUlJPVyk7CiAgd2MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpKENPTE9SX0JUTkZBQ0UgKyAxKTsKICB3Yy5scHN6TWVudU5hbWUgID0gTlVMTDsKICB3Yy5scHN6Q2xhc3NOYW1lID0gc3pDbGFzczsKCiAgU0hSZWdpc3RlckNsYXNzQSgmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeEEoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nUHRyVyhoV25kLCBEV0xQX01TR1JFU1VMVCwgeik7CgogICAgaWYgKHduZFByb2MpCiAgICAgIFNldFdpbmRvd0xvbmdQdHJBKGhXbmQsIEdXTFBfV05EUFJPQywgd25kUHJvYyk7CiAgfQogIHJldHVybiBoV25kOwp9Cgp0eXBlZGVmIHN0cnVjdCB0YWdQT0xJQ1lEQVRBCnsKICBEV09SRCBwb2xpY3k7ICAgICAgICAvKiBmbGFncyB2YWx1ZSBwYXNzZWQgdG8gU0hSZXN0cmljdGVkICovCiAgTFBDV1NUUiBhcHBzdHI7ICAgICAgLyogYXBwbGljYXRpb24gc3RyIHN1Y2ggYXMgIkV4cGxvcmVyIiAqLwogIExQQ1dTVFIga2V5c3RyOyAgICAgIC8qIG5hbWUgb2YgdGhlIGFjdHVhbCByZWdpc3RyeSBrZXkgLyBwb2xpY3kgKi8KfSBQT0xJQ1lEQVRBLCAqTFBQT0xJQ1lEQVRBOwoKI2RlZmluZSBTSEVMTF9OT19QT0xJQ1kgMHhmZmZmZmZmZgoKLyogZGVmYXVsdCBzaGVsbCBwb2xpY3kgcmVnaXN0cnkga2V5ICovCnN0YXRpYyBjb25zdCBXQ0hBUiBzdHJSZWdpc3RyeVBvbGljeVdbXSA9IHsnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsJ00nLCdpJywnYycsJ3InLCdvJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcXCcsJ1AnLCdvJywnbCcsJ2knLCdjJywnaScsJ2UnLCdzJywwfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgICAgICAgICAgICAgICAgICAgICAgIFtTSExXQVBJLjI3MV0KICoKICogUmV0cmlldmUgYSBwb2xpY3kgdmFsdWUgZnJvbSB0aGUgcmVnaXN0cnkuCiAqCiAqIFBBUkFNUwogKiAgbHBTdWJLZXkgICBbSV0gICByZWdpc3RyeSBrZXkgbmFtZQogKiAgbHBTdWJOYW1lICBbSV0gICBzdWJuYW1lIG9mIHJlZ2lzdHJ5IGtleQogKiAgbHBWYWx1ZSAgICBbSV0gICB2YWx1ZSBuYW1lIG9mIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIFJFVFVSTlMKICogIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5IGtleSBvciAwIGlmIG5vdCBmb3VuZAogKi8KRFdPUkQgV0lOQVBJIFNIR2V0UmVzdHJpY3Rpb24oTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscFN1Yk5hbWUsIExQQ1dTVFIgbHBWYWx1ZSkKewoJRFdPUkQgcmV0dmFsLCBkYXRzaXplID0gc2l6ZW9mKHJldHZhbCk7CglIS0VZIGhLZXk7CgoJaWYgKCFscFN1YktleSkKCSAgbHBTdWJLZXkgPSBzdHJSZWdpc3RyeVBvbGljeVc7CgoJcmV0dmFsID0gUmVnT3BlbktleVcoSEtFWV9MT0NBTF9NQUNISU5FLCBscFN1YktleSwgJmhLZXkpOwogICAgaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0NVUlJFTlRfVVNFUiwgbHBTdWJLZXksICZoS2V5KTsKCWlmIChyZXR2YWwgIT0gRVJST1JfU1VDQ0VTUykKCSAgcmV0dXJuIDA7CgoJU0hHZXRWYWx1ZVcoaEtleSwgbHBTdWJOYW1lLCBscFZhbHVlLCBOVUxMLCAoTFBCWVRFKSZyZXR2YWwsICZkYXRzaXplKTsKCVJlZ0Nsb3NlS2V5KGhLZXkpOwoJcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICAgICAgICAgICAgICAgICAgICAgICBbU0hMV0FQSS4yNjZdCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0byByZXRyaWV2ZSB0aGUgcG9zc2libHkgY2FjaGVkIHZhbHVlIGZvciBhIHNwZWNpZmljIHBvbGljeQogKgogKiBQQVJBTVMKICogIHBvbGljeSAgICAgW0ldICAgVGhlIHBvbGljeSB0byBsb29rIGZvcgogKiAgaW5pdGlhbCAgICBbSV0gICBNYWluIHJlZ2lzdHJ5IGtleSB0byBvcGVuLCBpZiBOVUxMIHVzZSBkZWZhdWx0CiAqICBwb2xUYWJsZSAgIFtJXSAgIFRhYmxlIG9mIGtub3duIHBvbGljaWVzLCAwIHRlcm1pbmF0ZWQKICogIHBvbEFyciAgICAgW0ldICAgQ2FjaGUgYXJyYXkgb2YgcG9saWN5IHZhbHVlcwogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0cmlldmVkIHBvbGljeSB2YWx1ZSBvciAwIGlmIG5vdCBzdWNjZXNzZnVsCiAqCiAqIE5PVEVTCiAqICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYnkgdGhlIG5hdGl2ZSBTSFJlc3RyaWN0ZWQgZnVuY3Rpb24gdG8gc2VhcmNoIGZvciB0aGUKICogIHBvbGljeSBhbmQgY2FjaGUgaXQgb25jZSByZXRyaWV2ZWQuIFRoZSBjdXJyZW50IFdpbmUgaW1wbGVtZW50YXRpb24gdXNlcyBhCiAqICBkaWZmZXJlbnQgUE9MSUNZREFUQSBzdHJ1Y3R1cmUgYW5kIGltcGxlbWVudHMgYSBzaW1pbGFyIGFsZ29yaXRobWUgYWRhcHRlZCB0bwogKiAgdGhhdCBzdHJ1Y3R1cmUuCiAqLwpEV09SRCBXSU5BUEkgU0hSZXN0cmljdGlvbkxvb2t1cCgKCURXT1JEIHBvbGljeSwKCUxQQ1dTVFIgaW5pdGlhbCwKCUxQUE9MSUNZREFUQSBwb2xUYWJsZSwKCUxQRFdPUkQgcG9sQXJyKQp7CglUUkFDRSgiKDB4JTA4eCAlcyAlcCAlcClcbiIsIHBvbGljeSwgZGVidWdzdHJfdyhpbml0aWFsKSwgcG9sVGFibGUsIHBvbEFycik7CgoJaWYgKCFwb2xUYWJsZSB8fCAhcG9sQXJyKQoJICByZXR1cm4gMDsKCglmb3IgKDtwb2xUYWJsZS0+cG9saWN5OyBwb2xUYWJsZSsrLCBwb2xBcnIrKykKCXsKCSAgaWYgKHBvbGljeSA9PSBwb2xUYWJsZS0+cG9saWN5KQoJICB7CgkgICAgLyogd2UgaGF2ZSBhIGtub3duIHBvbGljeSAqLwoKCSAgICAvKiBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQgKi8KCQlpZiAoKnBvbEFyciA9PSBTSEVMTF9OT19QT0xJQ1kpCgkgICAgICAqcG9sQXJyID0gU0hHZXRSZXN0cmljdGlvbihpbml0aWFsLCBwb2xUYWJsZS0+YXBwc3RyLCBwb2xUYWJsZS0+a2V5c3RyKTsKCSAgICByZXR1cm4gKnBvbEFycjsKCSAgfQoJfQoJLyogd2UgZG9uJ3Qga25vdyB0aGlzIHBvbGljeSwgcmV0dXJuIDAgKi8KCVRSQUNFKCJ1bmtub3duIHBvbGljeTogKCUwOHgpXG4iLCBwb2xpY3kpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjddCiAqCiAqIEdldCBhbiBpbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIHBwdiBjb250YWlucyB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogICBUaGlzIFF1ZXJ5SW50ZXJmYWNlIGFza3MgdGhlIGlubmVyIG9iamVjdCBmb3IgYW4gaW50ZXJmYWNlLiBJbiBjYXNlCiAqICAgb2YgYWdncmVnYXRpb24gdGhpcyByZXF1ZXN0IHdvdWxkIGJlIGZvcndhcmRlZCBieSB0aGUgaW5uZXIgdG8gdGhlCiAqICAgb3V0ZXIgb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIGFza3MgdGhlIGlubmVyIG9iamVjdCBkaXJlY3RseSBmb3IgdGhlCiAqICAgaW50ZXJmYWNlIGNpcmN1bXZlbnRpbmcgdGhlIGZvcndhcmRpbmcgdG8gdGhlIG91dGVyIG9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIFNIV2Vha1F1ZXJ5SW50ZXJmYWNlKAoJSVVua25vd24gKiBwVW5rLCAgIC8qIFtpbl0gT3V0ZXIgb2JqZWN0ICovCglJVW5rbm93biAqIHBJbm5lciwgLyogW2luXSBJbm5lciBvYmplY3QgKi8KCUlJRCAqIHJpaWQsIC8qIFtpbl0gSW50ZXJmYWNlIEdVSUQgdG8gcXVlcnkgZm9yICovCglMUFZPSUQqIHBwdikgLyogW291dF0gRGVzdGluYXRpb24gZm9yIHF1ZXJpZWQgaW50ZXJmYWNlICovCnsKCUhSRVNVTFQgaHJldCA9IEVfTk9JTlRFUkZBQ0U7CglUUkFDRSgiKHBVbms9JXAgcElubmVyPSVwXG5cdElJRDogICVzICVwKVxuIixwVW5rLHBJbm5lcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKCSpwcHYgPSBOVUxMOwoJaWYocFVuayAmJiBwSW5uZXIpIHsKCSAgICBocmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElubmVyLCByaWlkLCAoTFBWT0lEKilwcHYpOwoJICAgIGlmIChTVUNDRUVERUQoaHJldCkpIElVbmtub3duX1JlbGVhc2UocFVuayk7Cgl9CglUUkFDRSgiLS0gMHglMDh4XG4iLCBocmV0KTsKCXJldHVybiBocmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY4XQogKgogKiBNb3ZlIGEgcmVmZXJlbmNlIGZyb20gb25lIGludGVyZmFjZSB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogICBscERlc3QgICAgIFtPXSBEZXN0aW5hdGlvbiB0byByZWNlaXZlIHRoZSByZWZlcmVuY2UKICogICBscHBVbmtub3duIFtPXSBTb3VyY2UgdG8gZ2l2ZSB1cCB0aGUgcmVmZXJlbmNlIHRvIGxwRGVzdAogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgU0hXZWFrUmVsZWFzZUludGVyZmFjZShJVW5rbm93biAqbHBEZXN0LCBJVW5rbm93biAqKmxwcFVua25vd24pCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBEZXN0LCBscHBVbmtub3duKTsKCiAgaWYgKCpscHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgUmVmZXJlbmNlKi8KICAgIElVbmtub3duX0FkZFJlZihscERlc3QpOwogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBVbmtub3duKTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjldCiAqCiAqIENvbnZlcnQgYW4gQVNDSUkgc3RyaW5nIG9mIGEgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyIFtJXSBTdHJpbmcgcmVwcmVzZW50aW5nIGEgQ0xTSUQgaW4gcmVnaXN0cnkgZm9ybWF0CiAqICBpZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjb252ZXJ0ZWQgQ0xTSUQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gaWQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCBDTFNJRC4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdBKExQQ1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgV0NIQVIgd0Nsc2lkWzQwXTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgaWRzdHIsIC0xLCB3Q2xzaWQsIHNpemVvZih3Q2xzaWQpL3NpemVvZihXQ0hBUikpOwogIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nKHdDbHNpZCwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3MF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIEdVSURGcm9tU3RyaW5nQS4KICovCkJPT0wgV0lOQVBJIEdVSURGcm9tU3RyaW5nVyhMUENXU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICAgIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nKChMUE9MRVNUUilpZHN0ciwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3Nl0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQgaW50byB0aGUgc2hlbGwsIGFuZCBzZXQgYSByZWdpc3RyeQogKiBrZXkgYWNjb3JkaW5nbHkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgMSwgSWYgdGhlIGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQuCiAqICAyLCBJZiB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkLgogKgogKiBOT1RFUwogKiAgVGhlIGtleSAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZWdyYXRlZEJyb3dzZXIiIGlzCiAqICBlaXRoZXIgc2V0IHRvIFRSVUUsIG9yIHJlbW92ZWQgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgZGVlbWVkCiAqICB0byBiZSBpbnRlZ3JhdGVkLgogKi8KRFdPUkQgV0lOQVBJIFdoaWNoUGxhdGZvcm0odm9pZCkKewogIHN0YXRpYyBjb25zdCBjaGFyIHN6SW50ZWdyYXRlZEJyb3dzZXJbXSA9ICJJbnRlZ3JhdGVkQnJvd3NlciI7CiAgc3RhdGljIERXT1JEIGR3U3RhdGUgPSAwOwogIEhLRVkgaEtleTsKICBEV09SRCBkd1JldCwgZHdEYXRhLCBkd1NpemU7CiAgSE1PRFVMRSBoc2hlbGwzMjsKCiAgaWYgKGR3U3RhdGUpCiAgICByZXR1cm4gZHdTdGF0ZTsKCiAgLyogSWYgc2hlbGwzMiBleHBvcnRzIERsbEdldFZlcnNpb24oKSwgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCAqLwogIGR3U3RhdGUgPSAxOwogIGhzaGVsbDMyID0gTG9hZExpYnJhcnlBKCJzaGVsbDMyLmRsbCIpOwogIGlmIChoc2hlbGwzMikKICB7CiAgICBGQVJQUk9DIHBEbGxHZXRWZXJzaW9uOwogICAgcERsbEdldFZlcnNpb24gPSBHZXRQcm9jQWRkcmVzcyhoc2hlbGwzMiwgIkRsbEdldFZlcnNpb24iKTsKICAgIGR3U3RhdGUgPSBwRGxsR2V0VmVyc2lvbiA/IDIgOiAxOwogICAgRnJlZUxpYnJhcnkoaHNoZWxsMzIpOwogIH0KCiAgLyogU2V0IG9yIGRlbGV0ZSB0aGUga2V5IGFjY29yZGluZ2x5ICovCiAgZHdSZXQgPSBSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwKICAgICAgICAgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXEludGVybmV0IEV4cGxvcmVyIiwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9BTExfQUNDRVNTLCAmaEtleSk7CiAgaWYgKCFkd1JldCkKICB7CiAgICBkd1JldCA9IFJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsICZkd1NpemUpOwoKICAgIGlmICghZHdSZXQgJiYgZHdTdGF0ZSA9PSAxKQogICAgewogICAgICAvKiBWYWx1ZSBleGlzdHMgYnV0IGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQgKi8KICAgICAgUmVnRGVsZXRlVmFsdWVBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIpOwogICAgfQogICAgZWxzZSBpZiAoZHdSZXQgJiYgZHdTdGF0ZSA9PSAyKQogICAgewogICAgICAvKiBCcm93c2VyIGlzIGludGVncmF0ZWQgYnV0IHZhbHVlIGRvZXMgbm90IGV4aXN0ICovCiAgICAgIGR3RGF0YSA9IFRSVUU7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgKExQQllURSkmZHdEYXRhLCBzaXplb2YoZHdEYXRhKSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoS2V5KTsKICB9CiAgcmV0dXJuIGR3U3RhdGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzhdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSENyZWF0ZVdvcmtlcldpbmRvd0EuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd1coTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsYXNzW10gPSB7ICdXJywgJ28nLCAncicsICdrJywgJ2UnLCAncicsICdXJywgJ1wwJyB9OwogIFdORENMQVNTVyB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDh4LCVwLDB4JTA4eCwweCUwOHgsJXAsMHglMDh4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIElmIG91ciBPUyBpcyBuYXRpdmVseSBBU0NJSSwgdXNlIHRoZSBBU0NJSSB2ZXJzaW9uICovCiAgaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpICAvKiBOVCAqLwogICAgcmV0dXJuIFNIQ3JlYXRlV29ya2VyV2luZG93QSh3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogQ3JlYXRlIFdpbmRvdyBjbGFzcyAqLwogIHdjLnN0eWxlICAgICAgICAgPSAwOwogIHdjLmxwZm5XbmRQcm9jICAgPSBEZWZXaW5kb3dQcm9jVzsKICB3Yy5jYkNsc0V4dHJhICAgID0gMDsKICB3Yy5jYlduZEV4dHJhICAgID0gNDsKICB3Yy5oSW5zdGFuY2UgICAgID0gc2hsd2FwaV9oSW5zdGFuY2U7CiAgd2MuaEljb24gICAgICAgICA9IE5VTEw7CiAgd2MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JXKE5VTEwsIChMUFdTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NXKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4Vyhkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIERXTFBfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzldCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VEZWZhdWx0Q29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCkKewogIHJldHVybiBTSEludm9rZUNvbW1hbmQoaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4MV0KICoKICogX1NIUGFja0Rpc3BQYXJhbXNWCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zVihMUFZPSUQgdywgTFBWT0lEIHgsIExQVk9JRCB5LCBMUFZPSUQgeikKewoJRklYTUUoIiVwICVwICVwICVwXG4iLHcseCx5LHopOwoJcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjI4Ml0KICoKICogVGhpcyBmdW5jdGlvbiBzZWVtcyB0byBiZSBhIGZvcndhcmQgdG8gU0hQYWNrRGlzcFBhcmFtc1YgKHdoYXRldmVyIFRIQVQKICogZnVuY3Rpb24gZG9lcy4uLikuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zKExQVk9JRCB3LCBMUFZPSUQgeCwgTFBWT0lEIHksIExQVk9JRCB6KQp7CiAgRklYTUUoIiVwICVwICVwICVwXG4iLCB3LCB4LCB5LCB6KTsKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNITFdBUElfSW52b2tlQnlJSUQKICoKICogICBUaGlzIGhlbHBlciBmdW5jdGlvbiBjYWxscyBJRGlzcGF0Y2g6Okludm9rZSBmb3IgZWFjaCBzaW5rCiAqIHdoaWNoIGltcGxlbWVudHMgZ2l2ZW4gaWlkIG9yIElEaXNwYXRjaC4KICoKICovCnN0YXRpYyBIUkVTVUxUIFNITFdBUElfSW52b2tlQnlJSUQoCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCogaUNQLAogICAgICAgIFJFRklJRCBpaWQsCiAgICAgICAgRElTUElEIGRpc3BJZCwKICAgICAgICBESVNQUEFSQU1TKiBkaXNwUGFyYW1zKQp7CiAgSUVudW1Db25uZWN0aW9ucyAqZW51bWVyYXRvcjsKICBDT05ORUNUREFUQSByZ2NkOwoKICBIUkVTVUxUIHJlc3VsdCA9IElDb25uZWN0aW9uUG9pbnRfRW51bUNvbm5lY3Rpb25zKGlDUCwgJmVudW1lcmF0b3IpOwogIGlmIChGQUlMRUQocmVzdWx0KSkKICAgIHJldHVybiByZXN1bHQ7CgogIHdoaWxlKElFbnVtQ29ubmVjdGlvbnNfTmV4dChlbnVtZXJhdG9yLCAxLCAmcmdjZCwgTlVMTCk9PVNfT0spCiAgewogICAgSURpc3BhdGNoICpkaXNwSWZhY2U7CiAgICBpZiAoU1VDQ0VFREVEKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHJnY2QucFVuaywgaWlkLCAoTFBWT0lEKikmZGlzcElmYWNlKSkgfHwKICAgICAgICBTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocmdjZC5wVW5rLCAmSUlEX0lEaXNwYXRjaCwgKExQVk9JRCopJmRpc3BJZmFjZSkpKQogICAgewogICAgICBJRGlzcGF0Y2hfSW52b2tlKGRpc3BJZmFjZSwgZGlzcElkLCAmSUlEX05VTEwsIDAsIERJU1BBVENIX01FVEhPRCwgZGlzcFBhcmFtcywgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgIElEaXNwYXRjaF9SZWxlYXNlKGRpc3BJZmFjZSk7CiAgICB9CiAgfQoKICBJRW51bUNvbm5lY3Rpb25zX1JlbGVhc2UoZW51bWVyYXRvcik7CgogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg0XQogKgogKiAgSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UKICovCkhSRVNVTFQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfU2ltcGxlSW52b2tlKAogICAgICAgIElDb25uZWN0aW9uUG9pbnQqIGlDUCwKICAgICAgICBESVNQSUQgZGlzcElkLAogICAgICAgIERJU1BQQVJBTVMqIGRpc3BQYXJhbXMpCnsKICBJSUQgaWlkOwogIEhSRVNVTFQgcmVzdWx0OwoKICBUUkFDRSgiKCVwKS0+KDB4JXggJXApXG4iLGlDUCxkaXNwSWQsZGlzcFBhcmFtcyk7CgogIHJlc3VsdCA9IElDb25uZWN0aW9uUG9pbnRfR2V0Q29ubmVjdGlvbkludGVyZmFjZShpQ1AsICZpaWQpOwogIGlmIChTVUNDRUVERUQocmVzdWx0KSkKICAgIHJlc3VsdCA9IFNITFdBUElfSW52b2tlQnlJSUQoaUNQLCAmaWlkLCBkaXNwSWQsIGRpc3BQYXJhbXMpOwoKICByZXR1cm4gcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg1XQogKgogKiBOb3RpZnkgYW4gSUNvbm5lY3Rpb25Qb2ludCBvYmplY3Qgb2YgY2hhbmdlcy4KICoKICogUEFSQU1TCiAqICBscENQICAgW0ldIE9iamVjdCB0byBub3RpZnkKICogIGRpc3BJRCBbSV0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UsIGlmIGxwQ1AgaXMgTlVMTCBvciBkb2VzIG5vdCBzdXBwb3J0IHRoZQogKiAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJQ29ubmVjdGlvblBvaW50X09uQ2hhbmdlZChJQ29ubmVjdGlvblBvaW50KiBscENQLCBESVNQSUQgZGlzcElEKQp7CiAgSUVudW1Db25uZWN0aW9ucyAqbHBFbnVtOwogIEhSRVNVTFQgaFJldCA9IEVfTk9JTlRFUkZBQ0U7CgogIFRSQUNFKCIoJXAsMHglOFgpXG4iLCBscENQLCBkaXNwSUQpOwoKICAvKiBHZXQgYW4gZW51bWVyYXRvciBmb3IgdGhlIGNvbm5lY3Rpb25zICovCiAgaWYgKGxwQ1ApCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9FbnVtQ29ubmVjdGlvbnMobHBDUCwgJmxwRW51bSk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSVByb3BlcnR5Tm90aWZ5U2luayAqbHBTaW5rOwogICAgQ09OTkVDVERBVEEgY29ubkRhdGE7CiAgICBVTE9ORyB1bEZldGNoZWQ7CgogICAgLyogQ2FsbCBPbkNoYW5nZWQoKSBmb3IgZXZlcnkgbm90aWZ5IHNpbmsgaW4gdGhlIGNvbm5lY3Rpb24gcG9pbnQgKi8KICAgIHdoaWxlIChJRW51bUNvbm5lY3Rpb25zX05leHQobHBFbnVtLCAxLCAmY29ubkRhdGEsICZ1bEZldGNoZWQpID09IFNfT0spCiAgICB7CiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoY29ubkRhdGEucFVuaywgJklJRF9JUHJvcGVydHlOb3RpZnlTaW5rLCAodm9pZCoqKSZscFNpbmspKSAmJgogICAgICAgICAgbHBTaW5rKQogICAgICB7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19PbkNoYW5nZWQobHBTaW5rLCBkaXNwSUQpOwogICAgICAgIElQcm9wZXJ0eU5vdGlmeVNpbmtfUmVsZWFzZShscFNpbmspOwogICAgICB9CiAgICAgIElVbmtub3duX1JlbGVhc2UoY29ubkRhdGEucFVuayk7CiAgICB9CgogICAgSUVudW1Db25uZWN0aW9uc19SZWxlYXNlKGxwRW51bSk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg2XQogKgogKiAgSVVua25vd25fQ1BDb250YWluZXJJbnZva2VQYXJhbQogKi8KSFJFU1VMVCBXSU5BUElWIElVbmtub3duX0NQQ29udGFpbmVySW52b2tlUGFyYW0oCiAgICAgICAgSVVua25vd24gKmNvbnRhaW5lciwKICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICBESVNQSUQgZGlzcElkLAogICAgICAgIFZBUklBTlRBUkcqIGJ1ZmZlciwKICAgICAgICBEV09SRCBjUGFyYW1zLCAuLi4pCnsKICBIUkVTVUxUIHJlc3VsdDsKICBJQ29ubmVjdGlvblBvaW50ICppQ1A7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciAqaUNQQzsKCiAgaWYgKCFjb250YWluZXIpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgcmVzdWx0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoY29udGFpbmVyLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsKExQVk9JRCopICZpQ1BDKTsKICBpZiAoU1VDQ0VFREVEKHJlc3VsdCkpCiAgewogICAgcmVzdWx0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGlDUEMsIHJpaWQsICZpQ1ApOwogICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9SZWxlYXNlKGlDUEMpOwogIH0KCiAgaWYgKFNVQ0NFRURFRChyZXN1bHQpKQogIHsKICAgIFVMT05HIGNudDsKICAgIFZBUklBTlRBUkcgKmN1cnZhciA9IGJ1ZmZlcitjUGFyYW1zLTE7CiAgICBESVNQUEFSQU1TIGRpc3BQYXJhbXMgPSB7YnVmZmVyLCBOVUxMLCBjUGFyYW1zLCAwfTsKICAgIHZhX2xpc3QgdmFsaXN0OwoKICAgIHZhX3N0YXJ0KHZhbGlzdCwgY1BhcmFtcyk7CiAgICBmb3IoY250PWNQYXJhbXM7Y250PjA7Y250LS0sY3VydmFyLS0pIC8qIGJhY2t3YXJkcyBmb3Igc29tZSByZWFzb24gKi8KICAgIHsKICAgICAgZW51bSBWQVJFTlVNIHZ0ID0gdmFfYXJnKHZhbGlzdCwgZW51bSBWQVJFTlVNKTsKICAgICAgbWVtc2V0KGN1cnZhciwgMCwgc2l6ZW9mKCpjdXJ2YXIpKTsKICAgICAgaWYgKHZ0ICYgVlRfQllSRUYpCiAgICAgIHsKICAgICAgICBWX1ZUKGN1cnZhcikgPSB2dDsKICAgICAgICBWX0JZUkVGKGN1cnZhcikgPSB2YV9hcmcodmFsaXN0LCBMUFZPSUQpOwogICAgICB9IGVsc2UKICAgICAgICBzd2l0Y2godnQpCiAgICAgICAgewogICAgICAgIGNhc2UgVlRfQlNUUjoKICAgICAgICAgIFZfVlQoY3VydmFyKSA9IHZ0OwogICAgICAgICAgVl9CU1RSKGN1cnZhcikgPSB2YV9hcmcodmFsaXN0LCBCU1RSKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVlRfRElTUEFUQ0g6CiAgICAgICAgICBWX1ZUKGN1cnZhcikgPSB2dDsKICAgICAgICAgIFZfRElTUEFUQ0goY3VydmFyKSA9IHZhX2FyZyh2YWxpc3QsIElEaXNwYXRjaCopOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBWVF9CT09MOgogICAgICAgICAgVl9WVChjdXJ2YXIpID0gdnQ7CiAgICAgICAgICBWX0JPT0woY3VydmFyKSA9IHZhX2FyZyh2YWxpc3QsIGludCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZUX1VOS05PV046CiAgICAgICAgICBWX1ZUKGN1cnZhcikgPSB2dDsKICAgICAgICAgIFZfVU5LTk9XTihjdXJ2YXIpID0gdmFfYXJnKHZhbGlzdCwgSVVua25vd24qKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVlRfSTQ6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIFZfVlQoY3VydmFyKSA9IFZUX0k0OwogICAgICAgICAgVl9JNChjdXJ2YXIpID0gdmFfYXJnKHZhbGlzdCwgTE9ORyk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICB2YV9lbmQodmFsaXN0KTsKCiAgICByZXN1bHQgPSBTSExXQVBJX0ludm9rZUJ5SUlEKGlDUCwgcmlpZCwgZGlzcElkLCAmZGlzcFBhcmFtcyk7CiAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UoaUNQKTsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODddCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEICAgIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGlzIE5VTEwgb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUKICogICAgICAgICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fQ1BDb250YWluZXJPbkNoYW5nZWQoSVVua25vd24gKmxwVW5rbm93biwgRElTUElEIGRpc3BJRCkKewogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ1BDID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX05PSU5URVJGQUNFOwoKICBUUkFDRSgiKCVwLDB4JThYKVxuIiwgbHBVbmtub3duLCBkaXNwSUQpOwoKICBpZiAobHBVbmtub3duKQogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLCAodm9pZCoqKSZscENQQyk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSUNvbm5lY3Rpb25Qb2ludCogbHBDUDsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGxwQ1BDLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICZscENQKTsKICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfUmVsZWFzZShscENQQyk7CgogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKGxwQ1AsIGRpc3BJRCk7CiAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg5XQogKgogKiBTZWUgUGxheVNvdW5kVy4KICovCkJPT0wgV0lOQVBJIFBsYXlTb3VuZFdyYXBXKExQQ1dTVFIgcHN6U291bmQsIEhNT0RVTEUgaG1vZCwgRFdPUkQgZmR3U291bmQpCnsKICAgIHJldHVybiBQbGF5U291bmRXKHBzelNvdW5kLCBobW9kLCBmZHdTb3VuZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTRdCiAqLwpCT09MIFdJTkFQSSBTSEdldEluaVN0cmluZ1coTFBTVFIgc3RyMSwgTFBTVFIgc3RyMiwgTFBTVFIgcFN0ciwgRFdPUkQgc29tZV9sZW4sICBMUENTVFIgbHBTdHIyKQp7CiAgICAvKgogICAgICogc3RyMToJCSJJIgkiSSIJcHVzaGwgZXNwKzB4MjAKICAgICAqIHN0cjI6CQkiVSIJIkkiCXB1c2hsIDB4NzdjOTM4MTAKICAgICAqIChpcyAiSSIgYW5kICJVIiAiaW50ZWdlciIgYW5kICJ1bnNpZ25lZCIgPz8pCiAgICAgKgogICAgICogcFN0cjoJCSIiCSIiCXB1c2hsIGVheAogICAgICogc29tZV9sZW46CTB4ODI0CTB4MTA0CXB1c2hsIDB4ODI0CiAgICAgKiBscFN0cjI6CQkiJWwiCSIlbCIJcHVzaGwgZXNwKzB4YwogICAgICoKICAgICAqIHNobHdhcGkuIFN0ckNweU5XKGxwU3RyMiwgaXJyZWxldmFudF92YXIsIDB4MTA0KTsKICAgICAqIExvY2FsQWxsb2MoMHgwMCwgc29tZV9sZW4pIC0+IGlycmVsZXZhbnRfdmFyCiAgICAgKiBMb2NhbEFsbG9jKDB4NDAsIGlycmVsZXZhbnRfbGVuKSAtPiBwU3RyCiAgICAgKiBzaGx3YXBpLjI5NChzdHIxLCBzdHIyLCBwU3RyLCBzb21lX2xlbiwgbHBTdHIyKTsKICAgICAqIHNobHdhcGkuUGF0aFJlbW92ZUJsYW5rc1cocFN0cik7CiAgICAgKi8KICAgIEZJWE1FKCIoJyVzJywgJyVzJywgJyVzJywgJTA4eCwgJyVzJyk6IHN0dWIhXG4iLCBzdHIxLCBzdHIyLCBwU3RyLCBzb21lX2xlbiwgbHBTdHIyKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjk1XQogKgogKiBDYWxsZWQgYnkgSUNRMjAwMGIgaW5zdGFsbCB2aWEgU0hET0NWVzoKICogc3RyMTogIkludGVybmV0U2hvcnRjdXQiCiAqIHg6IHNvbWUgdW5rbm93biBwb2ludGVyCiAqIHN0cjI6ICJodHRwOi8vZnJlZS5hb2wuY29tL3RyeWFvbGZyZWUvaW5kZXguYWRwPzEzOTI2OSIKICogc3RyMzogIkM6XFxXSU5ET1dTXFxEZXNrdG9wLm5ldzJcXEZyZWUgQU9MICYgVW5saW1pdGVkIEludGVybmV0LnVybCIKICoKICogSW4gc2hvcnQ6IHRoaXMgb25lIG1heWJlIGNyZWF0ZXMgYSBkZXNrdG9wIGxpbmsgOi0pCiAqLwpCT09MIFdJTkFQSSBTSFNldEluaVN0cmluZ1coTFBXU1RSIHN0cjEsIExQVk9JRCB4LCBMUFdTVFIgc3RyMiwgTFBXU1RSIHN0cjMpCnsKICAgIEZJWE1FKCIoJXMsICVwLCAlcywgJXMpLCBzdHViLlxuIiwgZGVidWdzdHJfdyhzdHIxKSwgeCwgZGVidWdzdHJfdyhzdHIyKSwgZGVidWdzdHJfdyhzdHIzKSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxM10KICoKICogU2VlIFNIR2V0RmlsZUluZm9XLgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0RmlsZUluZm9XcmFwVyhMUENXU1RSIHBhdGgsIERXT1JEIGR3RmlsZUF0dHJpYnV0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICBTSEZJTEVJTkZPVyAqcHNmaSwgVUlOVCBzaXplb2Zwc2ZpLCBVSU5UIGZsYWdzKQp7CiAgICByZXR1cm4gU0hHZXRGaWxlSW5mb1cocGF0aCwgZHdGaWxlQXR0cmlidXRlcywgcHNmaSwgc2l6ZW9mcHNmaSwgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzE4XQogKgogKiBTZWUgRHJhZ1F1ZXJ5RmlsZVcuCiAqLwpVSU5UIFdJTkFQSSBEcmFnUXVlcnlGaWxlV3JhcFcoSERST1AgaERyb3AsIFVJTlQgbEZpbGUsIExQV1NUUiBscHN6RmlsZSwgVUlOVCBsTGVuZ3RoKQp7CiAgICByZXR1cm4gRHJhZ1F1ZXJ5RmlsZVcoaERyb3AsIGxGaWxlLCBscHN6RmlsZSwgbExlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzNdCiAqCiAqIFNlZSBTSEJyb3dzZUZvckZvbGRlclcuCiAqLwpMUElURU1JRExJU1QgV0lOQVBJIFNIQnJvd3NlRm9yRm9sZGVyV3JhcFcoTFBCUk9XU0VJTkZPVyBscEJpKQp7CiAgICByZXR1cm4gU0hCcm93c2VGb3JGb2xkZXJXKGxwQmkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM0XQogKgogKiBTZWUgU0hHZXRQYXRoRnJvbUlETGlzdFcuCiAqLwpCT09MIFdJTkFQSSBTSEdldFBhdGhGcm9tSURMaXN0V3JhcFcoTFBDSVRFTUlETElTVCBwaWRsLExQV1NUUiBwc3pQYXRoKQp7CiAgICByZXR1cm4gU0hHZXRQYXRoRnJvbUlETGlzdFcocGlkbCwgcHN6UGF0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzVdCiAqCiAqIFNlZSBTaGVsbEV4ZWN1dGVFeFcuCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeFdyYXBXKExQU0hFTExFWEVDVVRFSU5GT1cgbHBFeGVjSW5mbykKewogICAgcmV0dXJuIFNoZWxsRXhlY3V0ZUV4VyhscEV4ZWNJbmZvKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNl0KICoKICogU2VlIFNIRmlsZU9wZXJhdGlvblcuCiAqLwpJTlQgV0lOQVBJIFNIRmlsZU9wZXJhdGlvbldyYXBXKExQU0hGSUxFT1BTVFJVQ1RXIGxwRmlsZU9wKQp7CiAgICByZXR1cm4gU0hGaWxlT3BlcmF0aW9uVyhscEZpbGVPcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNDJdCiAqCiAqLwpQVk9JRCBXSU5BUEkgU0hJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSggUFZPSUQgKmRlc3QsIFBWT0lEIHhjaGcsIFBWT0lEIGNvbXBhcmUgKQp7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2VQb2ludGVyKCBkZXN0LCB4Y2hnLCBjb21wYXJlICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTBdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9TaXplVy4KICovCkRXT1JEIFdJTkFQSSBHZXRGaWxlVmVyc2lvbkluZm9TaXplV3JhcFcoIExQQ1dTVFIgZmlsZW5hbWUsIExQRFdPUkQgaGFuZGxlICkKewogICAgcmV0dXJuIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXKCBmaWxlbmFtZSwgaGFuZGxlICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTFdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9XLgogKi8KQk9PTCAgV0lOQVBJIEdldEZpbGVWZXJzaW9uSW5mb1dyYXBXKCBMUENXU1RSIGZpbGVuYW1lLCBEV09SRCBoYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZGF0YXNpemUsIExQVk9JRCBkYXRhICkKewogICAgcmV0dXJuIEdldEZpbGVWZXJzaW9uSW5mb1coIGZpbGVuYW1lLCBoYW5kbGUsIGRhdGFzaXplLCBkYXRhICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTJdCiAqCiAqIFNlZSBWZXJRdWVyeVZhbHVlVy4KICovCldPUkQgV0lOQVBJIFZlclF1ZXJ5VmFsdWVXcmFwVyggTFBWT0lEIHBCbG9jaywgTFBDV1NUUiBscFN1YkJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqbHBscEJ1ZmZlciwgVUlOVCAqcHVMZW4gKQp7CiAgICByZXR1cm4gVmVyUXVlcnlWYWx1ZVcoIHBCbG9jaywgbHBTdWJCbG9jaywgbHBscEJ1ZmZlciwgcHVMZW4gKTsKfQoKI2RlZmluZSBJc0lmYWNlKHR5cGUpIFNVQ0NFRURFRCgoaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF8jI3R5cGUsICh2b2lkKiopJmxwT2JqKSkpCiNkZWZpbmUgSVNoZWxsQnJvd3Nlcl9FbmFibGVNb2RlbGVzcyBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzU0IKI2RlZmluZSBFbmFibGVNb2RlbGVzcyh0eXBlKSB0eXBlIyNfRW5hYmxlTW9kZWxlc3MoKHR5cGUqKWxwT2JqLCBiTW9kZWxlc3MpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU1XQogKgogKiBDaGFuZ2UgdGhlIG1vZGFsaXR5IG9mIGEgc2hlbGwgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG1ha2UgbW9kZWxlc3MKICogIGJNb2RlbGVzcyBbSV0gVFJVRT1NYWtlIG1vZGVsZXNzLCBGQUxTRT1NYWtlIG1vZGFsCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIFRoZSBtb2RhbGl0eSBscFVua25vd24gaXMgY2hhbmdlZC4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICoKICogTk9URVMKICogIGxwVW5rbm93biBtdXN0IHN1cHBvcnQgdGhlIElPbGVJblBsYWNlRnJhbWUgaW50ZXJmYWNlLCB0aGUKICogIElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSBpbnRlcmZhY2UsIHRoZSBJU2hlbGxCcm93c2VyIGludGVyZmFjZQogKiAgdGhlIElEb2NIb3N0VUlIYW5kbGVyIGludGVyZmFjZSwgb3IgdGhlIElPbGVJblBsYWNlQWN0aXZlT2JqZWN0IGludGVyZmFjZSwKICogIG9yIHRoaXMgY2FsbCB3aWxsIGZhaWwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FbmFibGVNb2RlbGVzcyhJVW5rbm93biAqbHBVbmtub3duLCBCT09MIGJNb2RlbGVzcykKewogIElVbmtub3duICpscE9iajsKICBIUkVTVUxUIGhSZXQ7CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscFVua25vd24sIGJNb2RlbGVzcyk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYgKElzSWZhY2UoSU9sZUluUGxhY2VBY3RpdmVPYmplY3QpKQogICAgRW5hYmxlTW9kZWxlc3MoSU9sZUluUGxhY2VBY3RpdmVPYmplY3QpOwogIGVsc2UgaWYgKElzSWZhY2UoSU9sZUluUGxhY2VGcmFtZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJT2xlSW5QbGFjZUZyYW1lKTsKICBlbHNlIGlmIChJc0lmYWNlKElTaGVsbEJyb3dzZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSVNoZWxsQnJvd3Nlcik7CiNpZiAwCiAgLyogRklYTUU6IFdpbmUgaGFzIG5vIGhlYWRlcnMgZm9yIHRoZXNlIG9iamVjdHMgeWV0ICovCiAgZWxzZSBpZiAoSXNJZmFjZShJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpKQogICAgRW5hYmxlTW9kZWxlc3MoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKTsKICBlbHNlIGlmIChJc0lmYWNlKElEb2NIb3N0VUlIYW5kbGVyKSkKICAgIEVuYWJsZU1vZGVsZXNzKElEb2NIb3N0VUlIYW5kbGVyKTsKI2VuZGlmCiAgZWxzZQogICAgcmV0dXJuIGhSZXQ7CgogIElVbmtub3duX1JlbGVhc2UobHBPYmopOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU3XQogKgogKiBTZWUgU0hHZXROZXdMaW5rSW5mb1cuCiAqLwpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvV3JhcFcoTFBDV1NUUiBwc3pMaW5rVG8sIExQQ1dTVFIgcHN6RGlyLCBMUFdTVFIgcHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqcGZNdXN0Q29weSwgVUlOVCB1RmxhZ3MpCnsKICAgIHJldHVybiBTSEdldE5ld0xpbmtJbmZvVyhwc3pMaW5rVG8sIHBzekRpciwgcHN6TmFtZSwgcGZNdXN0Q29weSwgdUZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1OF0KICoKICogU2VlIFNIRGVmRXh0cmFjdEljb25XLgogKi8KVUlOVCBXSU5BUEkgU0hEZWZFeHRyYWN0SWNvbldyYXBXKExQQ1dTVFIgcHN6SWNvbkZpbGUsIGludCBpSW5kZXgsIFVJTlQgdUZsYWdzLCBISUNPTiogcGhpY29uTGFyZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBISUNPTiogcGhpY29uU21hbGwsIFVJTlQgbkljb25TaXplKQp7CiAgICByZXR1cm4gU0hEZWZFeHRyYWN0SWNvblcocHN6SWNvbkZpbGUsIGlJbmRleCwgdUZsYWdzLCBwaGljb25MYXJnZSwgcGhpY29uU21hbGwsIG5JY29uU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNjNdCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKiAgYkludm9rZURlZmF1bHQgW0ldIFdoZXRoZXIgdG8gaW52b2tlIHRoZSBkZWZhdWx0IG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBiSW52b2tlRGVmYXVsdCBpcyBUUlVFLCB0aGUgZGVmYXVsdCBtZW51IGFjdGlvbiB3YXMKICogICAgICAgICAgIGV4ZWN1dGVkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VDb21tYW5kKEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsLCBCT09MIGJJbnZva2VEZWZhdWx0KQp7CiAgSUNvbnRleHRNZW51ICppQ29udGV4dDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBoV25kLCBscEZvbGRlciwgbHBBcGlkbCwgYkludm9rZURlZmF1bHQpOwoKICBpZiAoIWxwRm9sZGVyKQogICAgcmV0dXJuIGhSZXQ7CgogIC8qIEdldCB0aGUgY29udGV4dCBtZW51IGZyb20gdGhlIHNoZWxsIGZvbGRlciAqLwogIGhSZXQgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihscEZvbGRlciwgaFduZCwgMSwgJmxwQXBpZGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZJSURfSUNvbnRleHRNZW51LCAwLCAodm9pZCoqKSZpQ29udGV4dCk7CiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBITUVOVSBoTWVudTsKICAgIGlmICgoaE1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKSkpCiAgICB7CiAgICAgIEhSRVNVTFQgaFF1ZXJ5OwogICAgICBEV09SRCBkd0RlZmF1bHRJZCA9IDA7CgogICAgICAvKiBBZGQgdGhlIGNvbnRleHQgbWVudSBlbnRyaWVzIHRvIHRoZSBwb3B1cCAqLwogICAgICBoUXVlcnkgPSBJQ29udGV4dE1lbnVfUXVlcnlDb250ZXh0TWVudShpQ29udGV4dCwgaE1lbnUsIDAsIDEsIDB4N0ZGRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkludm9rZURlZmF1bHQgPyBDTUZfTk9STUFMIDogQ01GX0RFRkFVTFRPTkxZKTsKCiAgICAgIGlmIChTVUNDRUVERUQoaFF1ZXJ5KSkKICAgICAgewogICAgICAgIGlmIChiSW52b2tlRGVmYXVsdCAmJgogICAgICAgICAgICAoZHdEZWZhdWx0SWQgPSBHZXRNZW51RGVmYXVsdEl0ZW0oaE1lbnUsIDAsIDApKSAhPSAweEZGRkZGRkZGKQogICAgICAgIHsKICAgICAgICAgIENNSU5WT0tFQ09NTUFORElORk8gY21JY2k7CiAgICAgICAgICAvKiBJbnZva2UgdGhlIGRlZmF1bHQgaXRlbSAqLwogICAgICAgICAgbWVtc2V0KCZjbUljaSwwLHNpemVvZihjbUljaSkpOwogICAgICAgICAgY21JY2kuY2JTaXplID0gc2l6ZW9mKGNtSWNpKTsKICAgICAgICAgIGNtSWNpLmZNYXNrID0gQ01JQ19NQVNLX0FTWU5DT0s7CiAgICAgICAgICBjbUljaS5od25kID0gaFduZDsKICAgICAgICAgIGNtSWNpLmxwVmVyYiA9IE1BS0VJTlRSRVNPVVJDRUEoZHdEZWZhdWx0SWQpOwogICAgICAgICAgY21JY2kublNob3cgPSBTV19TQ1JPTExDSElMRFJFTjsKCiAgICAgICAgICBoUmV0ID0gSUNvbnRleHRNZW51X0ludm9rZUNvbW1hbmQoaUNvbnRleHQsICZjbUljaSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIH0KICAgIElDb250ZXh0TWVudV9SZWxlYXNlKGlDb250ZXh0KTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzBdCiAqCiAqIFNlZSBFeHRyYWN0SWNvblcuCiAqLwpISUNPTiBXSU5BUEkgRXh0cmFjdEljb25XcmFwVyhISU5TVEFOQ0UgaEluc3RhbmNlLCBMUENXU1RSIGxwc3pFeGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbkljb25JbmRleCkKewogICAgcmV0dXJuIEV4dHJhY3RJY29uVyhoSW5zdGFuY2UsIGxwc3pFeGVGaWxlTmFtZSwgbkljb25JbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzddCiAqCiAqIExvYWQgYSBsaWJyYXJ5IGZyb20gdGhlIGRpcmVjdG9yeSBvZiBhIHBhcnRpY3VsYXIgcHJvY2Vzcy4KICoKICogUEFSQU1TCiAqICBuZXdfbW9kICAgICAgICBbSV0gTGlicmFyeSBuYW1lCiAqICBpbnN0X2h3bmQgICAgICBbSV0gTW9kdWxlIHdob3NlIGRpcmVjdG9yeSBpcyB0byBiZSB1c2VkCiAqICBkd0Nyb3NzQ29kZVBhZ2UgW0ldIFNob3VsZCBiZSBGQUxTRSAoY3VycmVudGx5IGlnbm9yZWQpCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgbW9kdWxlCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeUEoTFBDU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0Nyb3NzQ29kZVBhZ2UpCnsKICAvKiBGSVhNRTogTmF0aXZlIGFwcGVhcnMgdG8gZG8gRFBBX0NyZWF0ZSBhbmQgYSBEUEFfSW5zZXJ0UHRyIGZvcgogICAqICAgICAgICBlYWNoIGNhbGwgaGVyZS4KICAgKiBGSVhNRTogTmF0aXZlIHNob3dzIGNhbGxzIHRvOgogICAqICBTSFJlZ0dldFVTVmFsdWUgZm9yICJTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZXJuYXRpb25hbCIKICAgKiAgICAgICAgICAgICAgICAgICAgICBDaGVja1ZlcnNpb24KICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyIgogICAqICBSZWdRdWVyeVZhbHVlRXhBIGZvciAiTFBLSW5zdGFsbGVkIgogICAqICBSZWdDbG9zZUtleQogICAqICBSZWdPcGVuS2V5RXhBIGZvciAiSEtDVVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZXJuYXRpb25hbCIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIlJlc291cmNlTG9jYWxlIgogICAqICBSZWdDbG9zZUtleQogICAqICBSZWdPcGVuS2V5RXhBIGZvciAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcQWN0aXZlIFNldHVwXEluc3RhbGxlZCBDb21wb25lbnRzXHtndWlkfSIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgYW5kIHRoZW4gdGVzdHMgdGhlIExvY2FsZSAoImVuIiBmb3IgbWUpLgogICAqICAgICBjb2RlIGJlbG93CiAgICogIGFmdGVyIHRoZSBjb2RlIHRoZW4gYSBEUEFfQ3JlYXRlIChmaXJzdCB0aW1lKSBhbmQgRFBBX0luc2VydFB0ciBhcmUgZG9uZS4KICAgKi8KICAgIENIQVIgbW9kX3BhdGhbMipNQVhfUEFUSF07CiAgICBMUFNUUiBwdHI7CiAgICBEV09SRCBsZW47CgogICAgRklYTUUoIiglcywlcCwlZCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfYShuZXdfbW9kKSwgaW5zdF9od25kLCBkd0Nyb3NzQ29kZVBhZ2UpOwogICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKGluc3RfaHduZCwgbW9kX3BhdGgsIHNpemVvZihtb2RfcGF0aCkpOwogICAgaWYgKCFsZW4gfHwgbGVuID49IHNpemVvZihtb2RfcGF0aCkpIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IHN0cnJjaHIobW9kX3BhdGgsICdcXCcpOwogICAgaWYgKHB0cikgewoJc3RyY3B5KHB0cisxLCBuZXdfbW9kKTsKCVRSQUNFKCJsb2FkaW5nICVzXG4iLCBkZWJ1Z3N0cl9hKG1vZF9wYXRoKSk7CglyZXR1cm4gTG9hZExpYnJhcnlBKG1vZF9wYXRoKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc4XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgTUxMb2FkTGlicmFyeUEuCiAqLwpITU9EVUxFIFdJTkFQSSBNTExvYWRMaWJyYXJ5VyhMUENXU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0Nyb3NzQ29kZVBhZ2UpCnsKICAgIFdDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBXU1RSIHB0cjsKICAgIERXT1JEIGxlbjsKCiAgICBGSVhNRSgiKCVzLCVwLCVkKSBzZW1pLXN0dWIhXG4iLCBkZWJ1Z3N0cl93KG5ld19tb2QpLCBpbnN0X2h3bmQsIGR3Q3Jvc3NDb2RlUGFnZSk7CiAgICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZVcoaW5zdF9od25kLCBtb2RfcGF0aCwgc2l6ZW9mKG1vZF9wYXRoKSAvIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCFsZW4gfHwgbGVuID49IHNpemVvZihtb2RfcGF0aCkgLyBzaXplb2YoV0NIQVIpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyVyhtb2RfcGF0aCwgJ1xcJyk7CiAgICBpZiAocHRyKSB7CglzdHJjcHlXKHB0cisxLCBuZXdfbW9kKTsKCVRSQUNFKCJsb2FkaW5nICVzXG4iLCBkZWJ1Z3N0cl93KG1vZF9wYXRoKSk7CglyZXR1cm4gTG9hZExpYnJhcnlXKG1vZF9wYXRoKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb2xvckFkanVzdEx1bWEgICAgICBbU0hMV0FQSS5AXQogKgogKiBBZGp1c3QgdGhlIGx1bWlub3NpdHkgb2YgYSBjb2xvcgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gUkdCIHZhbHVlIHRvIGNvbnZlcnQKICogIGR3THVtYSAgICAgICBbSV0gTHVtYSBhZGp1c3RtZW50CiAqICBiVW5rbm93biAgICAgW0ldIFVua25vd24KICoKICogUkVUVVJOUwogKiAgVGhlIGFkanVzdGVkIFJHQiBjb2xvci4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckFkanVzdEx1bWEoQ09MT1JSRUYgY1JHQiwgaW50IGR3THVtYSwgQk9PTCBiVW5rbm93bikKewogIFRSQUNFKCIoMHglOHgsJWQsJWQpXG4iLCBjUkdCLCBkd0x1bWEsIGJVbmtub3duKTsKCiAgaWYgKGR3THVtYSkKICB7CiAgICBXT1JEIHdILCB3TCwgd1M7CgogICAgQ29sb3JSR0JUb0hMUyhjUkdCLCAmd0gsICZ3TCwgJndTKTsKCiAgICBGSVhNRSgiSWdub3JpbmcgbHVtYSBhZGp1c3RtZW50XG4iKTsKCiAgICAvKiBGSVhNRTogVGhlIGFqZHVzdG1lbnQgaXMgbm90IGxpbmVhciAqLwoKICAgIGNSR0IgPSBDb2xvckhMU1RvUkdCKHdILCB3TCwgd1MpOwogIH0KICByZXR1cm4gY1JHQjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM4OV0KICoKICogU2VlIEdldFNhdmVGaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVXcmFwVyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgICByZXR1cm4gR2V0U2F2ZUZpbGVOYW1lVyhvZm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzkwXQogKgogKiBTZWUgV05ldFJlc3RvcmVDb25uZWN0aW9uVy4KICovCkRXT1JEIFdJTkFQSSBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XcmFwVyhIV05EIGh3bmRPd25lciwgTFBXU1RSIGxwc3pEZXZpY2UpCnsKICAgIHJldHVybiBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XKGh3bmRPd25lciwgbHBzekRldmljZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zOTFdCiAqCiAqIFNlZSBXTmV0R2V0TGFzdEVycm9yVy4KICovCkRXT1JEIFdJTkFQSSBXTmV0R2V0TGFzdEVycm9yV3JhcFcoTFBEV09SRCBscEVycm9yLCBMUFdTVFIgbHBFcnJvckJ1ZiwgRFdPUkQgbkVycm9yQnVmU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBscE5hbWVCdWYsIERXT1JEIG5OYW1lQnVmU2l6ZSkKewogICAgcmV0dXJuIFdOZXRHZXRMYXN0RXJyb3JXKGxwRXJyb3IsIGxwRXJyb3JCdWYsIG5FcnJvckJ1ZlNpemUsIGxwTmFtZUJ1Ziwgbk5hbWVCdWZTaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwMV0KICoKICogU2VlIFBhZ2VTZXR1cERsZ1cuCiAqLwpCT09MIFdJTkFQSSBQYWdlU2V0dXBEbGdXcmFwVyhMUFBBR0VTRVRVUERMR1cgcGFnZWRsZykKewogICAgcmV0dXJuIFBhZ2VTZXR1cERsZ1cocGFnZWRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDJdCiAqCiAqIFNlZSBQcmludERsZ1cuCiAqLwpCT09MIFdJTkFQSSBQcmludERsZ1dyYXBXKExQUFJJTlRETEdXIHByaW50ZGxnKQp7CiAgICByZXR1cm4gUHJpbnREbGdXKHByaW50ZGxnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwM10KICoKICogU2VlIEdldE9wZW5GaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBHZXRPcGVuRmlsZU5hbWVXcmFwVyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgICByZXR1cm4gR2V0T3BlbkZpbGVOYW1lVyhvZm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDA0XQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRW51bU9iamVjdHMoTFBTSEVMTEZPTERFUiBscEZvbGRlciwgSFdORCBod25kLCBTSENPTlRGIGZsYWdzLCBJRW51bUlETGlzdCAqKnBwZW51bSkKewogICAgSVBlcnNpc3QgKnBlcnNpc3Q7CiAgICBIUkVTVUxUIGhyOwoKICAgIGhyID0gSVNoZWxsRm9sZGVyX1F1ZXJ5SW50ZXJmYWNlKGxwRm9sZGVyLCAmSUlEX0lQZXJzaXN0LCAoTFBWT0lEKSZwZXJzaXN0KTsKICAgIGlmKFNVQ0NFRURFRChocikpCiAgICB7CiAgICAgICAgQ0xTSUQgY2xzaWQ7CiAgICAgICAgaHIgPSBJUGVyc2lzdF9HZXRDbGFzc0lEKHBlcnNpc3QsICZjbHNpZCk7CiAgICAgICAgaWYoU1VDQ0VFREVEKGhyKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKElzRXF1YWxDTFNJRCgmY2xzaWQsICZDTFNJRF9TaGVsbEZTRm9sZGVyKSkKICAgICAgICAgICAgICAgIGhyID0gSVNoZWxsRm9sZGVyX0VudW1PYmplY3RzKGxwRm9sZGVyLCBod25kLCBmbGFncywgcHBlbnVtKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaHIgPSBFX0ZBSUw7CiAgICAgICAgfQogICAgICAgIElQZXJzaXN0X1JlbGVhc2UocGVyc2lzdCk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCi8qIElOVEVSTkFMOiBNYXAgZnJvbSBITFMgY29sb3Igc3BhY2UgdG8gUkdCICovCnN0YXRpYyBXT1JEIFdJTkFQSSBDb252ZXJ0SHVlKGludCB3SHVlLCBXT1JEIHdNaWQxLCBXT1JEIHdNaWQyKQp7CiAgd0h1ZSA9IHdIdWUgPiAyNDAgPyB3SHVlIC0gMjQwIDogd0h1ZSA8IDAgPyB3SHVlICsgMjQwIDogd0h1ZTsKCiAgaWYgKHdIdWUgPiAxNjApCiAgICByZXR1cm4gd01pZDE7CiAgZWxzZSBpZiAod0h1ZSA+IDEyMCkKICAgIHdIdWUgPSAxNjAgLSB3SHVlOwogIGVsc2UgaWYgKHdIdWUgPiA0MCkKICAgIHJldHVybiB3TWlkMjsKCiAgcmV0dXJuICgod0h1ZSAqICh3TWlkMiAtIHdNaWQxKSArIDIwKSAvIDQwKSArIHdNaWQxOwp9CgovKiBDb252ZXJ0IHRvIFJHQiBhbmQgc2NhbGUgaW50byBSR0IgcmFuZ2UgKDAuLjI1NSkgKi8KI2RlZmluZSBHRVRfUkdCKGgpIChDb252ZXJ0SHVlKGgsIHdNaWQxLCB3TWlkMikgKiAyNTUgKyAxMjApIC8gMjQwCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9ySExTVG9SR0IJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBmcm9tIGhscyBjb2xvciBzcGFjZSBpbnRvIGFuIHJnYiBDT0xPUlJFRi4KICoKICogUEFSQU1TCiAqICB3SHVlICAgICAgICBbSV0gSHVlIGFtb3VudAogKiAgd0x1bWlub3NpdHkgW0ldIEx1bWlub3NpdHkgYW1vdW50CiAqICB3U2F0dXJhdGlvbiBbSV0gU2F0dXJhdGlvbiBhbW91bnQKICoKICogUkVUVVJOUwogKiAgQSBDT0xPUlJFRiByZXByZXNlbnRpbmcgdGhlIGNvbnZlcnRlZCBjb2xvci4KICoKICogTk9URVMKICogIElucHV0IGhscyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckhMU1RvUkdCKFdPUkQgd0h1ZSwgV09SRCB3THVtaW5vc2l0eSwgV09SRCB3U2F0dXJhdGlvbikKewogIFdPUkQgd1JlZDsKCiAgaWYgKHdTYXR1cmF0aW9uKQogIHsKICAgIFdPUkQgd0dyZWVuLCB3Qmx1ZSwgd01pZDEsIHdNaWQyOwoKICAgIGlmICh3THVtaW5vc2l0eSA+IDEyMCkKICAgICAgd01pZDIgPSB3U2F0dXJhdGlvbiArIHdMdW1pbm9zaXR5IC0gKHdTYXR1cmF0aW9uICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwogICAgZWxzZQogICAgICB3TWlkMiA9ICgod1NhdHVyYXRpb24gKyAyNDApICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwoKICAgIHdNaWQxID0gd0x1bWlub3NpdHkgKiAyIC0gd01pZDI7CgogICAgd1JlZCAgID0gR0VUX1JHQih3SHVlICsgODApOwogICAgd0dyZWVuID0gR0VUX1JHQih3SHVlKTsKICAgIHdCbHVlICA9IEdFVF9SR0Iod0h1ZSAtIDgwKTsKCiAgICByZXR1cm4gUkdCKHdSZWQsIHdHcmVlbiwgd0JsdWUpOwogIH0KCiAgd1JlZCA9IHdMdW1pbm9zaXR5ICogMjU1IC8gMjQwOwogIHJldHVybiBSR0Iod1JlZCwgd1JlZCwgd1JlZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTNdCiAqCiAqIEdldCB0aGUgY3VycmVudCBkb2NraW5nIHN0YXR1cyBvZiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIERPQ0tJTkZPXyBmbGFncyBmcm9tICJ3aW5iYXNlLmgiLCB1bnVzZWQKICoKICogUkVUVVJOUwogKiAgT25lIG9mIERPQ0tJTkZPX1VORE9DS0VELCBET0NLSU5GT19VTkRPQ0tFRCwgb3IgMCBpZiB0aGUgc3lzdGVtIGlzIG5vdAogKiAgYSBub3RlYm9vay4KICovCkRXT1JEIFdJTkFQSSBTSEdldE1hY2hpbmVJbmZvKERXT1JEIGR3RmxhZ3MpCnsKICBIV19QUk9GSUxFX0lORk9BIGh3SW5mbzsKCiAgVFJBQ0UoIigweCUwOHgpXG4iLCBkd0ZsYWdzKTsKCiAgR2V0Q3VycmVudEh3UHJvZmlsZUEoJmh3SW5mbyk7CiAgc3dpdGNoIChod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpKQogIHsKICBjYXNlIERPQ0tJTkZPX0RPQ0tFRDoKICBjYXNlIERPQ0tJTkZPX1VORE9DS0VEOgogICAgcmV0dXJuIGh3SW5mby5kd0RvY2tJbmZvICYgKERPQ0tJTkZPX0RPQ0tFRHxET0NLSU5GT19VTkRPQ0tFRCk7CiAgZGVmYXVsdDoKICAgIHJldHVybiAwOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQxOF0KICoKICogRnVuY3Rpb24gc2VlbXMgdG8gZG8gRnJlZUxpYnJhcnkgcGx1cyBvdGhlciB0aGluZ3MuCiAqCiAqIEZJWE1FIG5hdGl2ZSBzaG93cyB0aGUgZm9sbG93aW5nIGNhbGxzOgogKiAgIFJ0bEVudGVyQ3JpdGljYWxTZWN0aW9uCiAqICAgTG9jYWxGcmVlCiAqICAgR2V0UHJvY0FkZHJlc3MoQ29tY3RsMzI/PywgMTUwTCkKICogICBEUEFfRGVsZXRlUHRyCiAqICAgUnRsTGVhdmVDcml0aWNhbFNlY3Rpb24KICogIGZvbGxvd2VkIGJ5IHRoZSBGcmVlTGlicmFyeS4KICogIFRoZSBhYm92ZSBjb2RlIG1heSBiZSByZWxhdGVkIHRvIC4zNzcgYWJvdmUuCiAqLwpCT09MIFdJTkFQSSBNTEZyZWVMaWJyYXJ5KEhNT0RVTEUgaE1vZHVsZSkKewoJRklYTUUoIiglcCkgc2VtaS1zdHViXG4iLCBoTW9kdWxlKTsKCXJldHVybiBGcmVlTGlicmFyeShoTW9kdWxlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQxOV0KICovCkJPT0wgV0lOQVBJIFNIRmx1c2hTRkNhY2hlV3JhcCh2b2lkKSB7CiAgRklYTUUoIjogc3R1YlxuIik7CiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MjVdCiAqLwpCT09MIFdJTkFQSSBEZWxldGVNZW51V3JhcChITUVOVSBobWVudSwgVUlOVCBwb3MsIFVJTlQgZmxhZ3MpCnsKICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBkbyBtb3JlIHRoYW4gc2ltcGx5IGNhbGwgRGVsZXRlTWVudSAqLwogICAgRklYTUUoIiVwICUwOHggJTA4eCk6IHNlbWktc3R1YlxuIiwgaG1lbnUsIHBvcywgZmxhZ3MpOwogICAgcmV0dXJuIERlbGV0ZU1lbnUoaG1lbnUsIHBvcywgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICBbU0hMV0FQSS40MjldCiAqIEZJWE1FIEkgaGF2ZSBubyBpZGVhIHdoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIG9yIHdoYXQgaXRzIGFyZ3VtZW50cyBhcmUuCiAqLwpCT09MIFdJTkFQSSBNTElzTUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0KQp7CiAgICAgICBGSVhNRSgiKCVwKSBzdHViXG4iLCBoSW5zdCk7CiAgICAgICByZXR1cm4gRkFMU0U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMwXQogKi8KRFdPUkQgV0lOQVBJIE1MU2V0TUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0LCBIQU5ETEUgaEhlYXApCnsKCUZJWE1FKCIoJXAsJXApIHN0dWJcbiIsIGhJbnN0LCBoSGVhcCk7CglyZXR1cm4gRV9GQUlMOyAgIC8qIFRoaXMgaXMgd2hhdCBpcyB1c2VkIGlmIHNobHdhcGkgbm90IGxvYWRlZCAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMxXQogKi8KRFdPUkQgV0lOQVBJIE1MQ2xlYXJNTEhJbnN0YW5jZShEV09SRCB4KQp7CglGSVhNRSgiKDB4JTA4eClzdHViXG4iLCB4KTsKCXJldHVybiAweGFiYmExMjQ3Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM2XQogKgogKiBDb252ZXJ0IGFuIFVuaWNvZGUgc3RyaW5nIENMU0lEIGludG8gYSBDTFNJRC4KICoKICogUEFSQU1TCiAqICBpZHN0ciAgICAgIFtJXSAgIHN0cmluZyBjb250YWluaW5nIGEgQ0xTSUQgaW4gdGV4dCBmb3JtCiAqICBpZCAgICAgICAgIFtPXSAgIENMU0lEIGV4dHJhY3RlZCBmcm9tIHRoZSBzdHJpbmcKICoKICogUkVUVVJOUwogKiAgU19PSyBvbiBzdWNjZXNzIG9yIEVfSU5WQUxJREFSRyBvbiBmYWlsdXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBDTFNJREZyb21TdHJpbmdXcmFwKExQQ1dTVFIgaWRzdHIsIENMU0lEICppZCkKewogICAgcmV0dXJuIENMU0lERnJvbVN0cmluZygoTFBPTEVTVFIpaWRzdHIsIGlkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzN10KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBPUyBzdXBwb3J0cyBhIGdpdmVuIGZlYXR1cmUuCiAqCiAqIFBBUkFNUwogKiAgZHdGZWF0dXJlIFtJXSBGZWF0dXJlIHJlcXVlc3RlZCAodW5kb2N1bWVudGVkKQogKgogKiBSRVRVUk5TCiAqICBUUlVFICBJZiB0aGUgZmVhdHVyZSBpcyBhdmFpbGFibGUuCiAqICBGQUxTRSBJZiB0aGUgZmVhdHVyZSBpcyBub3QgYXZhaWxhYmxlLgogKi8KQk9PTCBXSU5BUEkgSXNPUyhEV09SRCBmZWF0dXJlKQp7CiAgICBPU1ZFUlNJT05JTkZPQSBvc3ZpOwogICAgRFdPUkQgcGxhdGZvcm0sIG1ham9ydiwgbWlub3J2OwoKICAgIG9zdmkuZHdPU1ZlcnNpb25JbmZvU2l6ZSA9IHNpemVvZihPU1ZFUlNJT05JTkZPQSk7CiAgICBpZighR2V0VmVyc2lvbkV4QSgmb3N2aSkpICB7CiAgICAgICAgRVJSKCJHZXRWZXJzaW9uRXggZmFpbGVkXG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbWFqb3J2ID0gb3N2aS5kd01ham9yVmVyc2lvbjsKICAgIG1pbm9ydiA9IG9zdmkuZHdNaW5vclZlcnNpb247CiAgICBwbGF0Zm9ybSA9IG9zdmkuZHdQbGF0Zm9ybUlkOwoKI2RlZmluZSBJU09TX1JFVFVSTih4KSBcCiAgICBUUkFDRSgiKDB4JXgpIHJldD0lZFxuIixmZWF0dXJlLCh4KSk7IFwKICAgIHJldHVybiAoeCk7CgogICAgc3dpdGNoKGZlYXR1cmUpICB7CiAgICBjYXNlIE9TX1dJTjMyU09SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJzCiAgICAgICAgICAgICAgICAgfHwgcGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV0lOOTVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UNE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDQpCiAgICBjYXNlIE9TX1dJTjIwMDBPUkdSRUFURVJfQUxUOgogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfV0lOOThPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDEwKQogICAgY2FzZSBPU19XSU45OF9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAxMCkKICAgIGNhc2UgT1NfV0lOMjAwMFBSTzoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjIwMDBTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBBRFZTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBEQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwVEVSTUlOQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX0VNQkVEREVEOgogICAgICAgIEZJWE1FKCIoT1NfRU1CRURERUQpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19URVJNSU5BTENMSUVOVDoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMQ0xJRU5UKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxSRU1PVEVBRE1JTjoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMUkVNT1RFQURNSU4pIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XSU45NV9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAwKQogICAgY2FzZSBPU19NRU9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPj0gOTApCiAgICBjYXNlIE9TX1hQT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSAmJiBtaW5vcnYgPj0gMSkKICAgIGNhc2UgT1NfSE9NRToKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX1BST0ZFU1NJT05BTDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX0RBVEFDRU5URVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19BRFZTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19TRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19URVJNSU5BTFNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1BFUlNPTkFMVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1pbm9ydiA+PSAxICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19GQVNUVVNFUlNXSVRDSElORzoKICAgICAgICBGSVhNRSgiKE9TX0ZBU1RVU0VSU1dJVENISU5HKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgY2FzZSBPU19XRUxDT01FTE9HT05VSToKICAgICAgICBGSVhNRSgiKE9TX1dFTENPTUVMT0dPTlVJKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfRE9NQUlOTUVNQkVSOgogICAgICAgIEZJWE1FKCIoT1NfRE9NQUlOTUVNQkVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgY2FzZSBPU19BTllTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19XT1c2NDMyOgogICAgICAgIEZJWE1FKCIoT1NfV09XNjQzMikgU2hvdWxkIHdlIGNoZWNrIHRoaXM/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1dFQlNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1NNQUxMQlVTSU5FU1NTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19UQUJMRVRQQzoKICAgICAgICBGSVhNRSgiKE9TX1RBQkxFUEMpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19TRVJWRVJBRE1JTlVJOgogICAgICAgIEZJWE1FKCIoT1NfU0VSVkVSQURNSU5VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX01FRElBQ0VOVEVSOgogICAgICAgIEZJWE1FKCIoT1NfTUVESUFDRU5URVIpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19BUFBMSUFOQ0U6CiAgICAgICAgRklYTUUoIihPU19BUFBMSUFOQ0UpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKI3VuZGVmIElTT1NfUkVUVVJOCgogICAgV0FSTigiKDB4JXgpIHVua25vd24gcGFyYW1ldGVyXG4iLGZlYXR1cmUpOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuNDM5XQogKi8KSFJFU1VMVCBXSU5BUEkgU0hMb2FkUmVnVUlTdHJpbmdXKEhLRVkgaGtleSwgTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZiwgRFdPUkQgc2l6ZSkKewogICAgRFdPUkQgdHlwZSwgc3ogPSBzaXplOwoKICAgIGlmKFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgdmFsdWUsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWJ1ZiwgJnN6KSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgcmV0dXJuIFNITG9hZEluZGlyZWN0U3RyaW5nKGJ1ZiwgYnVmLCBzaXplLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuNDc4XQogKgogKiBDYWxsIElJbnB1dE9iamVjdF9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElJbnB1dE9iamVjdCBpbnRlcmZhY2UuCiAqICBscE1zZyAgICAgW0ldIEtleSBtZXNzYWdlIHRvIGJlIHByb2Nlc3NlZC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9JTlZBTElEQVJHIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fVHJhbnNsYXRlQWNjZWxlcmF0b3JJTyhJVW5rbm93biAqbHBVbmtub3duLCBMUE1TRyBscE1zZykKewogIElJbnB1dE9iamVjdCogbHBJbnB1dCA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscE1zZyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnB1dE9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscElucHV0KTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBJbnB1dCkKICAgIHsKICAgICAgaFJldCA9IElJbnB1dE9iamVjdF9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKGxwSW5wdXQsIGxwTXNnKTsKICAgICAgSUlucHV0T2JqZWN0X1JlbGVhc2UobHBJbnB1dCk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40ODFdCiAqCiAqIENhbGwgSUlucHV0T2JqZWN0X0hhc0ZvY3VzSU8oKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSUlucHV0T2JqZWN0IGludGVyZmFjZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSywgaWYgbHBVbmtub3duIGlzIGFuIElJbnB1dE9iamVjdCBvYmplY3QgYW5kIGhhcyB0aGUgZm9jdXMsCiAqICAgICAgICAgICBvciBTX0ZBTFNFIG90aGVyd2lzZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9JTlZBTElEQVJHIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fSGFzRm9jdXNJTyhJVW5rbm93biAqbHBVbmtub3duKQp7CiAgSUlucHV0T2JqZWN0KiBscElucHV0ID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CgogIFRSQUNFKCIoJXApXG4iLCBscFVua25vd24pOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW5wdXRPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBJbnB1dCk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwSW5wdXQpCiAgICB7CiAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RfSGFzRm9jdXNJTyhscElucHV0KTsKICAgICAgSUlucHV0T2JqZWN0X1JlbGVhc2UobHBJbnB1dCk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9yUkdCVG9ITFMJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBhbiByZ2IgQ09MT1JSRUYgaW50byB0aGUgaGxzIGNvbG9yIHNwYWNlLgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gU291cmNlIHJnYiB2YWx1ZQogKiAgcHdIdWUgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGh1ZQogKiAgcHdMdW1pbmFuY2UgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGx1bWluYW5jZQogKiAgcHdTYXR1cmF0aW9uIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIHNhdHVyYXRpb24KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4gcHdIdWUsIHB3THVtaW5hbmNlIGFuZCBwd1NhdHVyYXRpb24gYXJlIHNldCB0byB0aGUgY29udmVydGVkCiAqICB2YWx1ZXMuCiAqCiAqIE5PVEVTCiAqICBPdXRwdXQgSExTIHZhbHVlcyBhcmUgY29uc3RyYWluZWQgdG8gdGhlIHJhbmdlICgwLi4yNDApLgogKiAgRm9yIEFjaHJvbWF0aWMgY29udmVyc2lvbnMsIEh1ZSBpcyBzZXQgdG8gMTYwLgogKi8KVk9JRCBXSU5BUEkgQ29sb3JSR0JUb0hMUyhDT0xPUlJFRiBjUkdCLCBMUFdPUkQgcHdIdWUsCgkJCSAgTFBXT1JEIHB3THVtaW5hbmNlLCBMUFdPUkQgcHdTYXR1cmF0aW9uKQp7CiAgaW50IHdSLCB3Rywgd0IsIHdNYXgsIHdNaW4sIHdIdWUsIHdMdW1pbm9zaXR5LCB3U2F0dXJhdGlvbjsKCiAgVFJBQ0UoIiglMDh4LCVwLCVwLCVwKVxuIiwgY1JHQiwgcHdIdWUsIHB3THVtaW5hbmNlLCBwd1NhdHVyYXRpb24pOwoKICB3UiA9IEdldFJWYWx1ZShjUkdCKTsKICB3RyA9IEdldEdWYWx1ZShjUkdCKTsKICB3QiA9IEdldEJWYWx1ZShjUkdCKTsKCiAgd01heCA9IG1heCh3UiwgbWF4KHdHLCB3QikpOwogIHdNaW4gPSBtaW4od1IsIG1pbih3Rywgd0IpKTsKCiAgLyogTHVtaW5vc2l0eSAqLwogIHdMdW1pbm9zaXR5ID0gKCh3TWF4ICsgd01pbikgKiAyNDAgKyAyNTUpIC8gNTEwOwoKICBpZiAod01heCA9PSB3TWluKQogIHsKICAgIC8qIEFjaHJvbWF0aWMgY2FzZSAqLwogICAgd1NhdHVyYXRpb24gPSAwOwogICAgLyogSHVlIGlzIG5vdyB1bnJlcHJlc2VudGFibGUsIGJ1dCB0aGlzIGlzIHdoYXQgbmF0aXZlIHJldHVybnMuLi4gKi8KICAgIHdIdWUgPSAxNjA7CiAgfQogIGVsc2UKICB7CiAgICAvKiBDaHJvbWF0aWMgY2FzZSAqLwogICAgaW50IHdEZWx0YSA9IHdNYXggLSB3TWluLCB3Uk5vcm0sIHdHTm9ybSwgd0JOb3JtOwoKICAgIC8qIFNhdHVyYXRpb24gKi8KICAgIGlmICh3THVtaW5vc2l0eSA8PSAxMjApCiAgICAgIHdTYXR1cmF0aW9uID0gKCh3TWF4ICsgd01pbikvMiArIHdEZWx0YSAqIDI0MCkgLyAod01heCArIHdNaW4pOwogICAgZWxzZQogICAgICB3U2F0dXJhdGlvbiA9ICgoNTEwIC0gd01heCAtIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKDUxMCAtIHdNYXggLSB3TWluKTsKCiAgICAvKiBIdWUgKi8KICAgIHdSTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdSICogNDApIC8gd0RlbHRhOwogICAgd0dOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0cgKiA0MCkgLyB3RGVsdGE7CiAgICB3Qk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3QiAqIDQwKSAvIHdEZWx0YTsKCiAgICBpZiAod1IgPT0gd01heCkKICAgICAgd0h1ZSA9IHdCTm9ybSAtIHdHTm9ybTsKICAgIGVsc2UgaWYgKHdHID09IHdNYXgpCiAgICAgIHdIdWUgPSA4MCArIHdSTm9ybSAtIHdCTm9ybTsKICAgIGVsc2UKICAgICAgd0h1ZSA9IDE2MCArIHdHTm9ybSAtIHdSTm9ybTsKICAgIGlmICh3SHVlIDwgMCkKICAgICAgd0h1ZSArPSAyNDA7CiAgICBlbHNlIGlmICh3SHVlID4gMjQwKQogICAgICB3SHVlIC09IDI0MDsKICB9CiAgaWYgKHB3SHVlKQogICAgKnB3SHVlID0gd0h1ZTsKICBpZiAocHdMdW1pbmFuY2UpCiAgICAqcHdMdW1pbmFuY2UgPSB3THVtaW5vc2l0eTsKICBpZiAocHdTYXR1cmF0aW9uKQogICAgKnB3U2F0dXJhdGlvbiA9IHdTYXR1cmF0aW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQ3JlYXRlU2hlbGxQYWxldHRlCVtTSExXQVBJLkBdCiAqLwpIUEFMRVRURSBXSU5BUEkgU0hDcmVhdGVTaGVsbFBhbGV0dGUoSERDIGhkYykKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIENyZWF0ZUhhbGZ0b25lUGFsZXR0ZShoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTSEdldEludmVyc2VDTUFQIChTSExXQVBJLkApCiAqCiAqIEdldCBhbiBpbnZlcnNlIGNvbG9yIG1hcCB0YWJsZS4KICoKICogUEFSQU1TCiAqICBscENtYXAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29sb3IgbWFwCiAqICBkd1NpemUgIFtJXSBTaXplIG9mIG1lbW9yeSBwb2ludGVkIHRvIGJ5IGxwQ21hcAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSLCAgICBJZiBscENtYXAgaXMgaW52YWxpZC4KICogICAgICAgICAgIEVfSU5WQUxJREFSRywgSWYgZHdGbGFncyBpcyBpbnZhbGlkCiAqICAgICAgICAgICBFX09VVE9GTUVNT1JZLCBJZiB0aGVyZSBpcyBubyBtZW1vcnkgYXZhaWxhYmxlCiAqCiAqIE5PVEVTCiAqICBkd1NpemUgbWF5IG9ubHkgYmUgQ01BUF9QVFJfU0laRSAoNCkgb3IgQ01BUF9TSVpFICg4MTkyKS4KICogIElmIGR3U2l6ZSA9IENNQVBfUFRSX1NJWkUsICpscENtYXAgaXMgc2V0IHRvIHRoZSBhZGRyZXNzIG9mIHRoaXMgRExMJ3MKICogIGludGVybmFsIENNYXAuCiAqICBJZiBkd1NpemUgPSBDTUFQX1NJWkUsIGxwQ21hcCBpcyBmaWxsZWQgd2l0aCBhIGNvcHkgb2YgdGhlIGRhdGEgZnJvbQogKiAgdGhpcyBETEwncyBpbnRlcm5hbCBDTWFwLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnZlcnNlQ01BUChMUERXT1JEIGRlc3QsIERXT1JEIGR3U2l6ZSkKewogICAgaWYgKGR3U2l6ZSA9PSA0KSB7CglGSVhNRSgiIC0gcmV0dXJuaW5nIGJvZ3VzIGFkZHJlc3MgZm9yIFNIR2V0SW52ZXJzZUNNQVBcbiIpOwoJKmRlc3QgPSAoRFdPUkQpMHhhYmJhMTI0OTsKCXJldHVybiAwOwogICAgfQogICAgRklYTUUoIiglcCwgJSN4KSBzdHViXG4iLCBkZXN0LCBkd1NpemUpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hJc0xvd01lbW9yeU1hY2hpbmUJW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBjdXJyZW50IGNvbXB1dGVyIGhhcyBsb3cgbWVtb3J5LgogKgogKiBQQVJBTVMKICogIHggW0ldIEZJWE1FCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgaWYgdGhlIHVzZXJzIG1hY2hpbmUgaGFzIDE2IE1lZ2FieXRlcyBvZiBtZW1vcnkgb3IgbGVzcywKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNISXNMb3dNZW1vcnlNYWNoaW5lIChEV09SRCB4KQp7CiAgRklYTUUoIigweCUwOHgpIHN0dWJcbiIsIHgpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBHZXRNZW51UG9zRnJvbUlECVtTSExXQVBJLkBdCiAqCiAqIFJldHVybiB0aGUgcG9zaXRpb24gb2YgYSBtZW51IGl0ZW0gZnJvbSBpdHMgSWQuCiAqCiAqIFBBUkFNUwogKiAgIGhNZW51IFtJXSBNZW51IGNvbnRhaW5pbmcgdGhlIGl0ZW0KICogICB3SUQgICBbSV0gSWQgb2YgdGhlIG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgaW5kZXggb2YgdGhlIG1lbnUgaXRlbSBpbiBoTWVudS4KICogIEZhaWx1cmU6IC0xLCBJZiB0aGUgaXRlbSBpcyBub3QgZm91bmQuCiAqLwpJTlQgV0lOQVBJIEdldE1lbnVQb3NGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgd0lEKQp7CiBNRU5VSVRFTUlORk9XIG1pOwogSU5UIG5Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpLCBuSXRlciA9IDA7Cgogd2hpbGUgKG5JdGVyIDwgbkNvdW50KQogewogICBtaS5jYlNpemUgPSBzaXplb2YobWkpOwogICBtaS5mTWFzayA9IE1JSU1fSUQ7CiAgIGlmIChHZXRNZW51SXRlbUluZm9XKGhNZW51LCBuSXRlciwgVFJVRSwgJm1pKSAmJiBtaS53SUQgPT0gd0lEKQogICAgIHJldHVybiBuSXRlcjsKICAgbkl0ZXIrKzsKIH0KIHJldHVybiAtMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3OV0KICoKICogU2FtZSBhcyBTSExXQVBJLkdldE1lbnVQb3NGcm9tSUQKICovCkRXT1JEIFdJTkFQSSBTSE1lbnVJbmRleEZyb21JRChITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICAgIHJldHVybiBHZXRNZW51UG9zRnJvbUlEKGhNZW51LCB1SUQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ0OF0KICovClZPSUQgV0lOQVBJIEZpeFNsYXNoZXNBbmRDb2xvblcoTFBXU1RSIGxwd3N0cikKewogICAgd2hpbGUgKCpscHdzdHIpCiAgICB7CiAgICAgICAgaWYgKCpscHdzdHIgPT0gJy8nKQogICAgICAgICAgICAqbHB3c3RyID0gJ1xcJzsKICAgICAgICBscHdzdHIrKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40NjFdCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRBcHBDb21wYXRGbGFncyhEV09SRCBkd1Vua25vd24pCnsKICBGSVhNRSgiKDB4JTA4eCkgc3R1YlxuIiwgZHdVbmtub3duKTsKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS41NDldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2VBQyhSRUZDTFNJRCByY2xzaWQsIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3Q2xzQ29udGV4dCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHJldHVybiBDb0NyZWF0ZUluc3RhbmNlKHJjbHNpZCwgcFVua091dGVyLCBkd0Nsc0NvbnRleHQsIGlpZCwgcHB2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTa2lwSnVuY3Rpb24JW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIGEgYmluZCBjb250ZXh0IGNhbiBiZSBib3VuZCB0byBhbiBvYmplY3QKICoKICogUEFSQU1TCiAqICBwYmMgICAgW0ldIEJpbmQgY29udGV4dCB0byBjaGVjawogKiAgcGNsc2lkIFtJXSBDTFNJRCBvZiBvYmplY3QgdG8gYmUgYm91bmQgdG8KICoKICogUkVUVVJOUwogKiAgVFJVRTogSWYgaXQgaXMgc2FmZSB0byBiaW5kCiAqICBGQUxTRTogSWYgcGJjIGlzIGludmFsaWQgb3IgYmluZGluZyB3b3VsZCBub3QgYmUgc2FmZQogKgogKi8KQk9PTCBXSU5BUEkgU0hTa2lwSnVuY3Rpb24oSUJpbmRDdHggKnBiYywgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIHN0YXRpYyBXQ0hBUiBzelNraXBCaW5kaW5nW10gPSB7ICdTJywnaycsJ2knLCdwJywnICcsCiAgICAnQicsJ2knLCduJywnZCcsJ2knLCduJywnZycsJyAnLCdDJywnTCcsJ1MnLCdJJywnRCcsJ1wwJyB9OwogIEJPT0wgYlJldCA9IEZBTFNFOwoKICBpZiAocGJjKQogIHsKICAgIElVbmtub3duKiBscFVuazsKCiAgICBpZiAoU1VDQ0VFREVEKElCaW5kQ3R4X0dldE9iamVjdFBhcmFtKHBiYywgKExQT0xFU1RSKXN6U2tpcEJpbmRpbmcsICZscFVuaykpKQogICAgewogICAgICBDTFNJRCBjbHNpZDsKCiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fR2V0Q2xhc3NJRChscFVuaywgJmNsc2lkKSkgJiYKICAgICAgICAgIElzRXF1YWxHVUlEKHBjbHNpZCwgJmNsc2lkKSkKICAgICAgICBiUmV0ID0gVFJVRTsKCiAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmspOwogICAgfQogIH0KICByZXR1cm4gYlJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFNoZWxsS2V5IChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRTaGVsbEtleShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAgICBGSVhNRSgiKCV4LCAleCwgJXgpOiBzdHViXG4iLCBhLCBiLCBjKTsKICAgIHJldHVybiAweDUwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIUXVldWVVc2VyV29ya0l0ZW0gKFNITFdBUEkuQCkKICovCkJPT0wgV0lOQVBJIFNIUXVldWVVc2VyV29ya0l0ZW0oTFBUSFJFQURfU1RBUlRfUk9VVElORSBwZm5DYWxsYmFjaywgCiAgICAgICAgTFBWT0lEIHBDb250ZXh0LCBMT05HIGxQcmlvcml0eSwgRFdPUkRfUFRSIGR3VGFnLAogICAgICAgIERXT1JEX1BUUiAqcGR3SWQsIExQQ1NUUiBwc3pNb2R1bGUsIERXT1JEIGR3RmxhZ3MpCnsKICAgIFRSQUNFKCIoJXAsICVwLCAlZCwgJWx4LCAlcCwgJXMsICUwOHgpXG4iLCBwZm5DYWxsYmFjaywgcENvbnRleHQsCiAgICAgICAgICBsUHJpb3JpdHksIGR3VGFnLCBwZHdJZCwgZGVidWdzdHJfYShwc3pNb2R1bGUpLCBkd0ZsYWdzKTsKCiAgICBpZihsUHJpb3JpdHkgfHwgZHdUYWcgfHwgcGR3SWQgfHwgcHN6TW9kdWxlIHx8IGR3RmxhZ3MpCiAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGFyZ3VtZW50c1xuIik7CgogICAgcmV0dXJuIFF1ZXVlVXNlcldvcmtJdGVtKHBmbkNhbGxiYWNrLCBwQ29udGV4dCwgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSVVua25vd25fT25Gb2N1c0NoYW5nZUlTIChTSExXQVBJLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMoTFBVTktOT1dOIGxwVW5rbm93biwgTFBVTktOT1dOIHBGb2N1c09iamVjdCwgQk9PTCBiRm9jdXMpCnsKICAgIElJbnB1dE9iamVjdFNpdGUgKnBJT1MgPSBOVUxMOwogICAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICAgIFRSQUNFKCIoJXAsICVwLCAlcylcbiIsIGxwVW5rbm93biwgcEZvY3VzT2JqZWN0LCBiRm9jdXMgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCiAgICBpZiAobHBVbmtub3duKQogICAgewogICAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0U2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJnBJT1MpOwogICAgICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgcElPUykKICAgICAgICB7CiAgICAgICAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RTaXRlX09uRm9jdXNDaGFuZ2VJUyhwSU9TLCBwRm9jdXNPYmplY3QsIGJGb2N1cyk7CiAgICAgICAgICAgIElJbnB1dE9iamVjdFNpdGVfUmVsZWFzZShwSU9TKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFZhbHVlVyAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgU0tHZXRWYWx1ZVcoRFdPUkQgYSwgTFBXU1RSIGIsIExQV1NUUiBjLCBEV09SRCBkLCBEV09SRCBlLCBEV09SRCBmKQp7CiAgICBGSVhNRSgiKCV4LCAlcywgJXMsICV4LCAleCwgJXgpOiBzdHViXG4iLCBhLCBkZWJ1Z3N0cl93KGIpLCBkZWJ1Z3N0cl93KGMpLCBkLCBlLCBmKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpEbGxHZXRWZXJzaW9uX2Z1bmMpKERMTFZFUlNJT05JTkZPICopOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRVSVZlcnNpb24gKFNITFdBUEkuNDUyKQogKi8KRFdPUkQgV0lOQVBJIEdldFVJVmVyc2lvbih2b2lkKQp7CiAgICBzdGF0aWMgRFdPUkQgdmVyc2lvbjsKCiAgICBpZiAoIXZlcnNpb24pCiAgICB7CiAgICAgICAgRGxsR2V0VmVyc2lvbl9mdW5jIHBEbGxHZXRWZXJzaW9uOwogICAgICAgIEhNT0RVTEUgZGxsID0gTG9hZExpYnJhcnlBKCJzaGVsbDMyLmRsbCIpOwogICAgICAgIGlmICghZGxsKSByZXR1cm4gMDsKCiAgICAgICAgcERsbEdldFZlcnNpb24gPSAoRGxsR2V0VmVyc2lvbl9mdW5jKUdldFByb2NBZGRyZXNzKGRsbCwgIkRsbEdldFZlcnNpb24iKTsKICAgICAgICBpZiAocERsbEdldFZlcnNpb24pCiAgICAgICAgewogICAgICAgICAgICBETExWRVJTSU9OSU5GTyBkdmk7CiAgICAgICAgICAgIGR2aS5jYlNpemUgPSBzaXplb2YoRExMVkVSU0lPTklORk8pOwogICAgICAgICAgICBpZiAocERsbEdldFZlcnNpb24oJmR2aSkgPT0gU19PSykgdmVyc2lvbiA9IGR2aS5kd01ham9yVmVyc2lvbjsKICAgICAgICB9CiAgICAgICAgRnJlZUxpYnJhcnkoIGRsbCApOwogICAgICAgIGlmICghdmVyc2lvbikgdmVyc2lvbiA9IDM7ICAvKiBvbGQgc2hlbGwgZGxscyBkb24ndCBoYXZlIERsbEdldFZlcnNpb24gKi8KICAgIH0KICAgIHJldHVybiB2ZXJzaW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIFNoZWxsTWVzc2FnZUJveFdyYXBXIFtTSExXQVBJLjM4OF0KICoKICogbG9hZHMgYSBzdHJpbmcgcmVzb3VyY2UgZm9yIGEgbW9kdWxlLCBkaXNwbGF5cyB0aGUgc3RyaW5nIGluIGEgCiAqIG1lc3NhZ2UgYm94IGFuZCB3cml0ZXMgaXQgaW50byB0aGUgbG9nZmlsZQogKgogKiBQQVJBTVMKICogIG1vZCAgICAgIFtJXSB0aGUgbW9kdWxlIGNvbnRhaW5pbmcgdGhlIHN0cmluZyByZXNvdXJjZQogKiAgdW5rbm93bjEgW0ldIEZJWE1FCiAqICB1SWQgICAgICBbSV0gdGhlIGlkIG9mIHRoZSBzdHJpbmcgcmVzb3VyY2UKICogIHRpdGxlICAgIFtJXSB0aGUgdGl0bGUgb2YgdGhlIG1lc3NhZ2UgYm94CiAqICB1bmtub3duMiBbSV0gRklYTUUKICogIGZpbGVuYW1lIFtJXSBuYW1lIG9mIHRoZSBsb2dmaWxlCiAqCiAqIFJFVFVSTlMKICogIEZJWE1FCiAqLwpCT09MIFdJTkFQSSBTaGVsbE1lc3NhZ2VCb3hXcmFwVyhITU9EVUxFIG1vZCwgRFdPUkQgdW5rbm93bjEsIFVJTlQgdUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIHRpdGxlLCBEV09SRCB1bmtub3duMiwgTFBDV1NUUiBmaWxlbmFtZSkKewogICAgRklYTUUoIiVwICV4ICVkICVzICV4ICVzXG4iLAogICAgICAgICAgbW9kLCB1bmtub3duMSwgdUlkLCBkZWJ1Z3N0cl93KHRpdGxlKSwgdW5rbm93bjIsIGRlYnVnc3RyX3coZmlsZW5hbWUpKTsKICAgIHJldHVybiBUUlVFOwp9CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2VFeGVjKElVbmtub3duICp1bmssIFJFRklJRCBzZXJ2aWNlLCBSRUZJSUQgY2xzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgeDEsIERXT1JEIHgyLCBEV09SRCB4Mywgdm9pZCAqKnBwdk91dCkKewogICAgRklYTUUoIiVwICVzICVzICUwOHggJTA4eCAlMDh4ICVwXG4iLCB1bmssCiAgICAgICAgICBkZWJ1Z3N0cl9ndWlkKHNlcnZpY2UpLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkKSwgeDEsIHgyLCB4MywgcHB2T3V0KTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0KCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1Byb2ZmZXJTZXJ2aWNlKElVbmtub3duICp1bmssIHZvaWQgKngwLCB2b2lkICp4MSwgdm9pZCAqeDIpCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcFxuIiwgdW5rLCB4MCwgeDEsIHgyKTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgWm9uZUNvbXB1dGVQYW5lU2l6ZSBbU0hMV0FQSS4zODJdCiAqLwpVSU5UIFdJTkFQSSBab25lQ29tcHV0ZVBhbmVTaXplKEhXTkQgaHduZCkKewogICAgRklYTUUoIlxuIik7CiAgICByZXR1cm4gMHg5NTsKfQoKdm9pZCBXSU5BUEkgU0hDaGFuZ2VOb3RpZnkoTE9ORyB3RXZlbnRJZCwgVUlOVCB1RmxhZ3MsIExQQ1ZPSUQgZHdJdGVtMSwgTFBDVk9JRCBkd0l0ZW0yKQp7CiAgICBTSENoYW5nZU5vdGlmeSh3RXZlbnRJZCwgdUZsYWdzLCBkd0l0ZW0xLCBkd0l0ZW0yKTsKfQoKdHlwZWRlZiBzdHJ1Y3QgU0hFTExfVVNFUl9TSUQgeyAgIC8qIGFjY29yZGluZyB0byBNU0ROIHRoaXMgc2hvdWxkIGJlIGluIHNobG9iai5oLi4uICovCiAgICBTSURfSURFTlRJRklFUl9BVVRIT1JJVFkgc2lkQXV0aG9yaXR5OwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgIGR3VXNlckdyb3VwSUQ7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgZHdVc2VySUQ7Cn0gU0hFTExfVVNFUl9TSUQsICpQU0hFTExfVVNFUl9TSUQ7Cgp0eXBlZGVmIHN0cnVjdCBTSEVMTF9VU0VSX1BFUk1JU1NJT04geyAvKiAuLi5hbmQgdGhpcyBzaG91bGQgYmUgaW4gc2hsd2FwaS5oICovCiAgICBTSEVMTF9VU0VSX1NJRCBzdXNJRDsKICAgIERXT1JEICAgICAgICAgIGR3QWNjZXNzVHlwZTsKICAgIEJPT0wgICAgICAgICAgIGZJbmhlcml0OwogICAgRFdPUkQgICAgICAgICAgZHdBY2Nlc3NNYXNrOwogICAgRFdPUkQgICAgICAgICAgZHdJbmhlcml0TWFzazsKICAgIERXT1JEICAgICAgICAgIGR3SW5oZXJpdEFjY2Vzc01hc2s7Cn0gU0hFTExfVVNFUl9QRVJNSVNTSU9OLCAqUFNIRUxMX1VTRVJfUEVSTUlTU0lPTjsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBHZXRTaGVsbFNlY3VyaXR5RGVzY3JpcHRvciBbU0hMV0FQSS40NzVdCiAqCiAqIHByZXBhcmVzIFNFQ1VSSVRZX0RFU0NSSVBUT1IgZnJvbSBhIHNldCBvZiBBQ0VzCiAqCiAqIFBBUkFNUwogKiAgYXBVc2VyUGVybSBbSV0gYXJyYXkgb2YgcG9pbnRlcnMgdG8gU0hFTExfVVNFUl9QRVJNSVNTSU9OIHN0cnVjdHVyZXMsCiAqICAgICAgICAgICAgICAgICBlYWNoIG9mIHdoaWNoIGRlc2NyaWJlcyBwZXJtaXNzaW9ucyB0byBhcHBseQogKiAgY1VzZXJQZXJtICBbSV0gbnVtYmVyIG9mIGVudHJpZXMgaW4gYXBVc2VyUGVybSBhcnJheQogKgogKiBSRVRVUk5TCiAqICBzdWNjZXNzOiBwb2ludGVyIHRvIFNFQ1VSSVRZX0RFU0NSSVBUT1IKICogIGZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogIENhbGwgc2hvdWxkIGZyZWUgcmV0dXJuZWQgZGVzY3JpcHRvciB3aXRoIExvY2FsRnJlZQogKi8KU0VDVVJJVFlfREVTQ1JJUFRPUiAqIFdJTkFQSSBHZXRTaGVsbFNlY3VyaXR5RGVzY3JpcHRvcihQU0hFTExfVVNFUl9QRVJNSVNTSU9OICphcFVzZXJQZXJtLCBpbnQgY1VzZXJQZXJtKQp7CiAgICBQU0lEICpzaWRsaXN0OwogICAgUFNJRCAgY3VyX3VzZXIgPSBOVUxMOwogICAgQllURSAgdHVVc2VyWzIwMDBdOwogICAgRFdPUkQgYWNsX3NpemU7CiAgICBpbnQgICBzaWRfY291bnQsIGk7CiAgICBQU0VDVVJJVFlfREVTQ1JJUFRPUiBwc2QgPSBOVUxMOwoKICAgIFRSQUNFKCIlcCAlZFxuIiwgYXBVc2VyUGVybSwgY1VzZXJQZXJtKTsKCiAgICBpZiAoYXBVc2VyUGVybSA9PSBOVUxMIHx8IGNVc2VyUGVybSA8PSAwKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHNpZGxpc3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY1VzZXJQZXJtICogc2l6ZW9mKFBTSUQpKTsKICAgIGlmICghc2lkbGlzdCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBhY2xfc2l6ZSA9IHNpemVvZihBQ0wpOwoKICAgIGZvcihzaWRfY291bnQgPSAwOyBzaWRfY291bnQgPCBjVXNlclBlcm07IHNpZF9jb3VudCsrKQogICAgewogICAgICAgIHN0YXRpYyBTSEVMTF9VU0VSX1NJRCBudWxsX3NpZCA9IHt7U0VDVVJJVFlfTlVMTF9TSURfQVVUSE9SSVRZfSwgMCwgMH07CiAgICAgICAgUFNIRUxMX1VTRVJfUEVSTUlTU0lPTiBwZXJtID0gYXBVc2VyUGVybVtzaWRfY291bnRdOwogICAgICAgIFBTSEVMTF9VU0VSX1NJRCBzaWQgPSAmcGVybS0+c3VzSUQ7CiAgICAgICAgUFNJRCBwU2lkOwogICAgICAgIEJPT0wgcmV0ID0gVFJVRTsKCiAgICAgICAgaWYgKCFtZW1jbXAoKHZvaWQqKXNpZCwgKHZvaWQqKSZudWxsX3NpZCwgc2l6ZW9mKFNIRUxMX1VTRVJfU0lEKSkpCiAgICAgICAgeyAgLyogY3VycmVudCB1c2VyJ3MgU0lEICovIAogICAgICAgICAgICBpZiAoIWN1cl91c2VyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIQU5ETEUgVG9rZW47CiAgICAgICAgICAgICAgICBEV09SRCBidWZzaXplID0gc2l6ZW9mKHR1VXNlcik7CgogICAgICAgICAgICAgICAgcmV0ID0gT3BlblByb2Nlc3NUb2tlbihHZXRDdXJyZW50UHJvY2VzcygpLCBUT0tFTl9RVUVSWSwgJlRva2VuKTsKICAgICAgICAgICAgICAgIGlmIChyZXQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gR2V0VG9rZW5JbmZvcm1hdGlvbihUb2tlbiwgVG9rZW5Vc2VyLCAodm9pZCopdHVVc2VyLCBidWZzaXplLCAmYnVmc2l6ZSApOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXQpCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cl91c2VyID0gKChQVE9LRU5fVVNFUikmdHVVc2VyKS0+VXNlci5TaWQ7CiAgICAgICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoVG9rZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHBTaWQgPSBjdXJfdXNlcjsKICAgICAgICB9IGVsc2UgaWYgKHNpZC0+ZHdVc2VySUQ9PTApIC8qIG9uZSBzdWItYXV0aG9yaXR5ICovCiAgICAgICAgICAgIHJldCA9IEFsbG9jYXRlQW5kSW5pdGlhbGl6ZVNpZCgmc2lkLT5zaWRBdXRob3JpdHksIDEsIHNpZC0+ZHdVc2VyR3JvdXBJRCwgMCwKICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAmcFNpZCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXQgPSBBbGxvY2F0ZUFuZEluaXRpYWxpemVTaWQoJnNpZC0+c2lkQXV0aG9yaXR5LCAyLCBzaWQtPmR3VXNlckdyb3VwSUQsIHNpZC0+ZHdVc2VySUQsCiAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgJnBTaWQpOwogICAgICAgIGlmICghcmV0KQogICAgICAgICAgICBnb3RvIGZyZWVfc2lkczsKCiAgICAgICAgc2lkbGlzdFtzaWRfY291bnRdID0gcFNpZDsKICAgICAgICAvKiBpbmNyZW1lbnQgYWNsX3NpemUgKDEgQUNFIGZvciBub24taW5oZXJpdGFibGUgYW5kIDIgQUNFcyBmb3IgaW5oZXJpdGFibGUgcmVjb3JkcyAqLwogICAgICAgIGFjbF9zaXplICs9IChzaXplb2YoQUNDRVNTX0FMTE9XRURfQUNFKS1zaXplb2YoRFdPUkQpICsgR2V0TGVuZ3RoU2lkKHBTaWQpKSAqIChwZXJtLT5mSW5oZXJpdCA/IDIgOiAxKTsKICAgIH0KCiAgICBwc2QgPSBMb2NhbEFsbG9jKDAsIHNpemVvZihTRUNVUklUWV9ERVNDUklQVE9SKSArIGFjbF9zaXplKTsKCiAgICBpZiAocHNkICE9IE5VTEwpCiAgICB7CiAgICAgICAgUEFDTCBwQWNsID0gKFBBQ0wpKCgoQllURSopcHNkKStzaXplb2YoU0VDVVJJVFlfREVTQ1JJUFRPUikpOwoKICAgICAgICBpZiAoIUluaXRpYWxpemVTZWN1cml0eURlc2NyaXB0b3IocHNkLCBTRUNVUklUWV9ERVNDUklQVE9SX1JFVklTSU9OKSkKICAgICAgICAgICAgZ290byBlcnJvcjsKCiAgICAgICAgaWYgKCFJbml0aWFsaXplQWNsKHBBY2wsIGFjbF9zaXplLCBBQ0xfUkVWSVNJT04pKQogICAgICAgICAgICBnb3RvIGVycm9yOwoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBzaWRfY291bnQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIFBTSEVMTF9VU0VSX1BFUk1JU1NJT04gc3VwID0gYXBVc2VyUGVybVtpXTsKICAgICAgICAgICAgUFNJRCBzaWQgPSBzaWRsaXN0W2ldOwoKICAgICAgICAgICAgc3dpdGNoKHN1cC0+ZHdBY2Nlc3NUeXBlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIEFDQ0VTU19BTExPV0VEX0FDRV9UWVBFOgogICAgICAgICAgICAgICAgICAgIGlmICghQWRkQWNjZXNzQWxsb3dlZEFjZShwQWNsLCBBQ0xfUkVWSVNJT04sIHN1cC0+ZHdBY2Nlc3NNYXNrLCBzaWQpKQogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIGlmIChzdXAtPmZJbmhlcml0ICYmICFBZGRBY2Nlc3NBbGxvd2VkQWNlRXgocEFjbCwgQUNMX1JFVklTSU9OLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQllURSlzdXAtPmR3SW5oZXJpdE1hc2ssIHN1cC0+ZHdJbmhlcml0QWNjZXNzTWFzaywgc2lkKSkKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQUNDRVNTX0RFTklFRF9BQ0VfVFlQRToKICAgICAgICAgICAgICAgICAgICBpZiAoIUFkZEFjY2Vzc0RlbmllZEFjZShwQWNsLCBBQ0xfUkVWSVNJT04sIHN1cC0+ZHdBY2Nlc3NNYXNrLCBzaWQpKQogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIGlmIChzdXAtPmZJbmhlcml0ICYmICFBZGRBY2Nlc3NEZW5pZWRBY2VFeChwQWNsLCBBQ0xfUkVWSVNJT04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChCWVRFKXN1cC0+ZHdJbmhlcml0TWFzaywgc3VwLT5kd0luaGVyaXRBY2Nlc3NNYXNrLCBzaWQpKQogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIVNldFNlY3VyaXR5RGVzY3JpcHRvckRhY2wocHNkLCBUUlVFLCBwQWNsLCBGQUxTRSkpCiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBnb3RvIGZyZWVfc2lkczsKCmVycm9yOgogICAgTG9jYWxGcmVlKHBzZCk7CiAgICBwc2QgPSBOVUxMOwpmcmVlX3NpZHM6CiAgICBmb3IoaSA9IDA7IGkgPCBzaWRfY291bnQ7IGkrKykKICAgIHsKICAgICAgICBpZiAoIWN1cl91c2VyIHx8IHNpZGxpc3RbaV0gIT0gY3VyX3VzZXIpCiAgICAgICAgICAgIEZyZWVTaWQoc2lkbGlzdFtpXSk7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaWRsaXN0KTsKCiAgICByZXR1cm4gcHNkOwp9Cg==