LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIiAgLyogZm9yIFJUX1NUUklOR1cgKi8KI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2ludmVyLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgImtlcm5lbF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChubHMpOwoKI2RlZmluZSBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSyAoTE9DQUxFX05PVVNFUk9WRVJSSURFfExPQ0FMRV9VU0VfQ1BfQUNQfExPQ0FMRV9SRVRVUk5fTlVNQkVSKQoKLyogY3VycmVudCBjb2RlIHBhZ2VzICovCnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICphbnNpX2NwdGFibGU7CnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICpvZW1fY3B0YWJsZTsKc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKm1hY19jcHRhYmxlOwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqdW5peF9jcHRhYmxlOyAgLyogTlVMTCBpZiBVVEY4ICovCgpzdGF0aWMgSEtFWSBOTFNfUmVnT3BlbktleShIS0VZIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CnN0YXRpYyBIS0VZIE5MU19SZWdPcGVuU3ViS2V5KEhLRVkgaFJvb3RLZXksIExQQ1dTVFIgc3pLZXlOYW1lKTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzek5sc0tleU5hbWVbXSA9IHsKICAgICdNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCdTJywnZScsJ3QnLCdcXCcsCiAgICAnQycsJ28nLCduJywndCcsJ3InLCdvJywnbCcsJ1xcJywnTicsJ2wnLCdzJywnXDAnCn07CgovKiBDaGFyc2V0IHRvIGNvZGVwYWdlIG1hcCwgc29ydGVkIGJ5IG5hbWUuICovCnN0YXRpYyBjb25zdCBzdHJ1Y3QgY2hhcnNldF9lbnRyeQp7CiAgICBjb25zdCBjaGFyICpjaGFyc2V0X25hbWU7CiAgICBVSU5UICAgICAgICBjb2RlcGFnZTsKfSBjaGFyc2V0X25hbWVzW10gPQp7CiAgICB7ICJCSUc1IiwgOTUwIH0sCiAgICB7ICJDUDEyNTAiLCAxMjUwIH0sCiAgICB7ICJDUDEyNTEiLCAxMjUxIH0sCiAgICB7ICJDUDEyNTIiLCAxMjUyIH0sCiAgICB7ICJDUDEyNTMiLCAxMjUzIH0sCiAgICB7ICJDUDEyNTQiLCAxMjU0IH0sCiAgICB7ICJDUDEyNTUiLCAxMjU1IH0sCiAgICB7ICJDUDEyNTYiLCAxMjU2IH0sCiAgICB7ICJDUDEyNTciLCAxMjU3IH0sCiAgICB7ICJDUDEyNTgiLCAxMjU4IH0sCiAgICB7ICJDUDkzMiIsIDkzMiB9LAogICAgeyAiQ1A5MzYiLCA5MzYgfSwKICAgIHsgIkNQOTQ5IiwgOTQ5IH0sCiAgICB7ICJDUDk1MCIsIDk1MCB9LAogICAgeyAiRVVDSlAiLCAyMDkzMiB9LAogICAgeyAiR0IyMzEyIiwgOTM2IH0sCiAgICB7ICJJQk0wMzciLCAzNyB9LAogICAgeyAiSUJNMTAyNiIsIDEwMjYgfSwKICAgIHsgIklCTTQyNCIsIDQyNCB9LAogICAgeyAiSUJNNDM3IiwgNDM3IH0sCiAgICB7ICJJQk01MDAiLCA1MDAgfSwKICAgIHsgIklCTTg1MCIsIDg1MCB9LAogICAgeyAiSUJNODUyIiwgODUyIH0sCiAgICB7ICJJQk04NTUiLCA4NTUgfSwKICAgIHsgIklCTTg1NyIsIDg1NyB9LAogICAgeyAiSUJNODYwIiwgODYwIH0sCiAgICB7ICJJQk04NjEiLCA4NjEgfSwKICAgIHsgIklCTTg2MiIsIDg2MiB9LAogICAgeyAiSUJNODYzIiwgODYzIH0sCiAgICB7ICJJQk04NjQiLCA4NjQgfSwKICAgIHsgIklCTTg2NSIsIDg2NSB9LAogICAgeyAiSUJNODY2IiwgODY2IH0sCiAgICB7ICJJQk04NjkiLCA4NjkgfSwKICAgIHsgIklCTTg3NCIsIDg3NCB9LAogICAgeyAiSUJNODc1IiwgODc1IH0sCiAgICB7ICJJU084ODU5MSIsIDI4NTkxIH0sCiAgICB7ICJJU084ODU5MTAiLCAyODYwMCB9LAogICAgeyAiSVNPODg1OTEzIiwgMjg2MDMgfSwKICAgIHsgIklTTzg4NTkxNCIsIDI4NjA0IH0sCiAgICB7ICJJU084ODU5MTUiLCAyODYwNSB9LAogICAgeyAiSVNPODg1OTE2IiwgMjg2MDYgfSwKICAgIHsgIklTTzg4NTkyIiwgMjg1OTIgfSwKICAgIHsgIklTTzg4NTkzIiwgMjg1OTMgfSwKICAgIHsgIklTTzg4NTk0IiwgMjg1OTQgfSwKICAgIHsgIklTTzg4NTk1IiwgMjg1OTUgfSwKICAgIHsgIklTTzg4NTk2IiwgMjg1OTYgfSwKICAgIHsgIklTTzg4NTk3IiwgMjg1OTcgfSwKICAgIHsgIklTTzg4NTk4IiwgMjg1OTggfSwKICAgIHsgIklTTzg4NTk5IiwgMjg1OTkgfSwKICAgIHsgIktPSThSIiwgMjA4NjYgfSwKICAgIHsgIktPSThVIiwgMjE4NjYgfSwKICAgIHsgIlVURjgiLCBDUF9VVEY4IH0KfTsKCiNkZWZpbmUgTkxTX01BWF9MQU5HVUFHRVMgMjAKdHlwZWRlZiBzdHJ1Y3QgewogICAgV0NIQVIgbGFuZ1sxMjhdOwogICAgV0NIQVIgY291bnRyeVs0XTsKICAgIExBTkdJRCBmb3VuZF9sYW5nX2lkW05MU19NQVhfTEFOR1VBR0VTXTsKICAgIFdDSEFSIGZvdW5kX2xhbmd1YWdlW05MU19NQVhfTEFOR1VBR0VTXVszXTsKICAgIFdDSEFSIGZvdW5kX2NvdW50cnlbTkxTX01BWF9MQU5HVUFHRVNdWzNdOwogICAgaW50IG5fZm91bmQ7Cn0gTEFOR19GSU5EX0RBVEE7CgoKLyogY29weSBVbmljb2RlIHN0cmluZyB0byBBc2NpaSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5V3RvQSggY2hhciAqZHN0LCBjb25zdCBXQ0hBUiAqc3JjICkKewogICAgd2hpbGUgKCgqZHN0KysgPSAqc3JjKyspKTsKfQoKLyogQ29weSBBc2NpaSBzdHJpbmcgdG8gVW5pY29kZSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5bkF0b1coIFdDSEFSICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IG4gKQp7CiAgICB3aGlsZSAobiA+IDEgJiYgKnNyYykKICAgIHsKICAgICAgICAqZHN0KysgPSAodW5zaWduZWQgY2hhcikqc3JjKys7CiAgICAgICAgbi0tOwogICAgfQogICAgaWYgKG4pICpkc3QgPSAwOwp9CgovKiByZXR1cm4gYSBwcmludGFibGUgc3RyaW5nIGZvciBhIGxhbmd1YWdlIGlkICovCnN0YXRpYyBjb25zdCBjaGFyICpkZWJ1Z3N0cl9sYW5nKCBMQU5HSUQgbGFuZyApCnsKICAgIFdDSEFSIGxhbmdXWzRdLCBjb3VudHJ5V1s0XTsKICAgIGNoYXIgYnVmZmVyWzhdOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoIGxhbmcsIFNPUlRfREVGQVVMVCApOwoKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TSVNPNjM5TEFOR05BTUV8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBsYW5nVywgc2l6ZW9mKGxhbmdXKS9zaXplb2YoV0NIQVIpKTsKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TSVNPMzE2NkNUUllOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwgY291bnRyeVcsIHNpemVvZihjb3VudHJ5Vykvc2l6ZW9mKFdDSEFSKSk7CiAgICBzdHJjcHlXdG9BKCBidWZmZXIsIGxhbmdXICk7CiAgICBzdHJjYXQoIGJ1ZmZlciwgIl8iICk7CiAgICBzdHJjcHlXdG9BKCBidWZmZXIgKyBzdHJsZW4oYnVmZmVyKSwgY291bnRyeVcgKTsKICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCAiJXMiLCBidWZmZXIgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfbGNpZF9jb2RlcGFnZQogKgogKiBSZXRyaWV2ZSB0aGUgQU5TSSBjb2RlcGFnZSBmb3IgYSBnaXZlbiBsb2NhbGUuCiAqLwppbmxpbmUgc3RhdGljIFVJTlQgZ2V0X2xjaWRfY29kZXBhZ2UoIExDSUQgbGNpZCApCnsKICAgIFVJTlQgcmV0OwogICAgaWYgKCFHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX0lERUZBVUxUQU5TSUNPREVQQUdFfExPQ0FMRV9SRVRVUk5fTlVNQkVSLCAoV0NIQVIgKikmcmV0LAogICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHJldCkvc2l6ZW9mKFdDSEFSKSApKSByZXQgPSAwOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2NvZGVwYWdlX3RhYmxlCiAqCiAqIEZpbmQgdGhlIHRhYmxlIGZvciBhIGdpdmVuIGNvZGVwYWdlLCBoYW5kbGluZyBDUF9BQ1AgZXRjLiBwc2V1ZG8tY29kZXBhZ2VzCiAqLwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqZ2V0X2NvZGVwYWdlX3RhYmxlKCB1bnNpZ25lZCBpbnQgY29kZXBhZ2UgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICpyZXQgPSBOVUxMOwoKICAgIGFzc2VydCggYW5zaV9jcHRhYmxlICk7ICAvKiBpbml0IG11c3QgaGF2ZSBiZWVuIGRvbmUgYWxyZWFkeSAqLwoKICAgIHN3aXRjaChjb2RlcGFnZSkKICAgIHsKICAgIGNhc2UgQ1BfQUNQOgogICAgICAgIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICBjYXNlIENQX09FTUNQOgogICAgICAgIHJldHVybiBvZW1fY3B0YWJsZTsKICAgIGNhc2UgQ1BfTUFDQ1A6CiAgICAgICAgcmV0dXJuIG1hY19jcHRhYmxlOwogICAgY2FzZSBDUF9VVEY3OgogICAgY2FzZSBDUF9VVEY4OgogICAgICAgIGJyZWFrOwogICAgY2FzZSBDUF9USFJFQURfQUNQOgogICAgICAgIGlmICghKGNvZGVwYWdlID0gTnRDdXJyZW50VGViKCktPmNvZGVfcGFnZSkpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBkZWZhdWx0OgogICAgICAgIGlmIChjb2RlcGFnZSA9PSBhbnNpX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG9lbV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gb2VtX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG1hY19jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gbWFjX2NwdGFibGU7CiAgICAgICAgcmV0ID0gd2luZV9jcF9nZXRfdGFibGUoIGNvZGVwYWdlICk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWNyZWF0ZV9yZWdpc3RyeV9rZXkKICoKICogQ3JlYXRlIHRoZSBDb250cm9sIFBhbmVsXFxJbnRlcm5hdGlvbmFsIHJlZ2lzdHJ5IGtleS4KICovCmlubGluZSBzdGF0aWMgSEtFWSBjcmVhdGVfcmVnaXN0cnlfa2V5KHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpbnRsV1tdID0geydDJywnbycsJ24nLCd0JywncicsJ28nLCdsJywnICcsJ1AnLCdhJywnbicsJ2UnLCdsJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2EnLCd0JywnaScsJ28nLCduJywnYScsJ2wnLDB9OwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgSEtFWSBoa2V5OwoKICAgIGlmIChSdGxPcGVuQ3VycmVudFVzZXIoIEtFWV9BTExfQUNDRVNTLCAmaGtleSApICE9IFNUQVRVU19TVUNDRVNTKSByZXR1cm4gMDsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXk7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgaW50bFcgKTsKCiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSAhPSBTVEFUVVNfU1VDQ0VTUykgaGtleSA9IDA7CiAgICBOdENsb3NlKCBhdHRyLlJvb3REaXJlY3RvcnkgKTsKICAgIHJldHVybiBoa2V5Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMT0NBTEVfSW5pdFJlZ2lzdHJ5CiAqCiAqIFVwZGF0ZSByZWdpc3RyeSBjb250ZW50cyBvbiBzdGFydHVwIGlmIHRoZSB1c2VyIGxvY2FsZSBoYXMgY2hhbmdlZC4KICogVGhpcyBzaW11bGF0ZXMgdGhlIGFjdGlvbiBvZiB0aGUgV2luZG93cyBjb250cm9sIHBhbmVsLgogKi8Kdm9pZCBMT0NBTEVfSW5pdFJlZ2lzdHJ5KHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBDb2RlcGFnZVdbXSA9IHsnQycsJ28nLCdkJywnZScsJ3AnLCdhJywnZycsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGFjcFdbXSA9IHsnQScsJ0MnLCdQJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBvZW1jcFdbXSA9IHsnTycsJ0UnLCdNJywnQycsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG1hY2NwV1tdID0geydNJywnQScsJ0MnLCdDJywnUCcsMH07CiAgICBzdGF0aWMgY29uc3Qgc3RydWN0CiAgICB7CiAgICAgICAgTFBDV1NUUiBuYW1lOwogICAgICAgIFVTSE9SVCB2YWx1ZTsKICAgIH0gdXBkYXRlX2NwX3ZhbHVlc1tdID0gewogICAgICAgIHsgYWNwVywgTE9DQUxFX0lERUZBVUxUQU5TSUNPREVQQUdFIH0sCiAgICAgICAgeyBvZW1jcFcsIExPQ0FMRV9JREVGQVVMVENPREVQQUdFIH0sCiAgICAgICAgeyBtYWNjcFcsIExPQ0FMRV9JREVGQVVMVE1BQ0NPREVQQUdFIH0KICAgIH07CiAgICBzdGF0aWMgY29uc3QgVVNIT1JUIHVwZGF0ZVZhbHVlc1tdID0gewogICAgICBMT0NBTEVfU0xBTkdVQUdFLAogICAgICBMT0NBTEVfU0NPVU5UUlksIExPQ0FMRV9JQ09VTlRSWSwKICAgICAgTE9DQUxFX1MxMTU5LCBMT0NBTEVfUzIzNTksCiAgICAgIExPQ0FMRV9TVElNRSwgTE9DQUxFX0lUSU1FLAogICAgICBMT0NBTEVfSVRMWkVSTywKICAgICAgTE9DQUxFX1NTSE9SVERBVEUsCiAgICAgIExPQ0FMRV9TTE9OR0RBVEUsCiAgICAgIExPQ0FMRV9TREFURSwKICAgICAgTE9DQUxFX1NDVVJSRU5DWSwgTE9DQUxFX0lDVVJSRU5DWSwKICAgICAgTE9DQUxFX0lORUdDVVJSLAogICAgICBMT0NBTEVfSUNVUlJESUdJVFMsCiAgICAgIExPQ0FMRV9TREVDSU1BTCwKICAgICAgTE9DQUxFX1NMSVNULAogICAgICBMT0NBTEVfU1RIT1VTQU5ELAogICAgICBMT0NBTEVfSURJR0lUUywKICAgICAgTE9DQUxFX0lESUdJVFNVQlNUSVRVVElPTiwKICAgICAgTE9DQUxFX1NOQVRJVkVESUdJVFMsCiAgICAgIExPQ0FMRV9JVElNRU1BUktQT1NOLAogICAgICBMT0NBTEVfSUNBTEVOREFSVFlQRSwKICAgICAgTE9DQUxFX0lMWkVSTywKICAgICAgTE9DQUxFX0lNRUFTVVJFCiAgICB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIExvY2FsZVdbXSA9IHsnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywwfTsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgY2hhciBidWZmZXJbMjBdOwogICAgV0NIQVIgYnVmZmVyV1s4MF07CiAgICBEV09SRCBjb3VudCwgaTsKICAgIEhLRVkgaGtleTsKICAgIExDSUQgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKQogICAgICAgIHJldHVybjsgIC8qIGRvbid0IGRvIGFueXRoaW5nIGlmIHdlIGNhbid0IGNyZWF0ZSB0aGUgcmVnaXN0cnkga2V5ICovCgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTG9jYWxlVyApOwogICAgY291bnQgPSBzaXplb2YoYnVmZmVyVyk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleShoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCAoTFBCWVRFKWJ1ZmZlclcsIGNvdW50LCAmY291bnQpKQogICAgewogICAgICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyVzsKICAgICAgICBMUENXU1RSIHN6VmFsdWVUZXh0ID0gKExQQ1dTVFIpaW5mby0+RGF0YTsKCiAgICAgICAgaWYgKHN0cnRvdWxXKCBzelZhbHVlVGV4dCwgTlVMTCwgMTYgKSA9PSBsY2lkKSAgLyogYWxyZWFkeSBzZXQgY29ycmVjdGx5ICovCiAgICAgICAgewogICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoICJ1cGRhdGluZyByZWdpc3RyeSwgbG9jYWxlIGNoYW5nZWQgJXMgLT4gJTA4bHhcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZVRleHQpLCBsY2lkICk7CiAgICB9CiAgICBlbHNlIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSBjaGFuZ2VkIG5vbmUgLT4gJTA4bHhcbiIsIGxjaWQgKTsKCiAgICBzcHJpbnRmKCBidWZmZXIsICIlMDhseCIsIGxjaWQgKTsKICAgIC8qIE5vdGU6ICc5JyBjb25zdGFudCBiZWxvdyBpcyBzdHJsZW4oYnVmZmVyKSArIDEgKi8KICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKSwgTlVMTCwgYnVmZmVyLCA5ICk7CiAgICBOdFNldFZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgOSAqIHNpemVvZihXQ0hBUikgKTsKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKHVwZGF0ZVZhbHVlcykvc2l6ZW9mKHVwZGF0ZVZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgdXBkYXRlVmFsdWVzW2ldIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmZXJXLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoYnVmZmVyVykvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIFNldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVWYWx1ZXNbaV0sIGJ1ZmZlclcgKTsKICAgIH0KCiAgICBoa2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgQ29kZXBhZ2VXICk7CgogICAgZm9yIChpID0gMDsgaSA8IHNpemVvZih1cGRhdGVfY3BfdmFsdWVzKS9zaXplb2YodXBkYXRlX2NwX3ZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBjb3VudCA9IEdldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVfY3BfdmFsdWVzW2ldLnZhbHVlIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdXBkYXRlX2NwX3ZhbHVlc1tpXS5uYW1lICk7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleSwgJm5hbWVXLCAwLCBSRUdfU1osIGJ1ZmZlclcsIGNvdW50ICogc2l6ZW9mKFdDSEFSKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jCiAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBmaW5kX2xhbmd1YWdlX2lkX3Byb2MoIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMQU5HX0ZJTkRfREFUQSAqbF9kYXRhID0gKExBTkdfRklORF9EQVRBICopbFBhcmFtOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoTGFuZ0lELCBTT1JUX0RFRkFVTFQpOwogICAgV0NIQVIgYnVmX2xhbmd1YWdlWzEyOF07CiAgICBXQ0hBUiBidWZfY291bnRyeVsxMjhdOwogICAgV0NIQVIgYnVmX2VuX2xhbmd1YWdlWzEyOF07CgogICAgaWYoUFJJTUFSWUxBTkdJRChMYW5nSUQpID09IExBTkdfTkVVVFJBTCkKICAgICAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgYnVmX2xhbmd1YWdlWzBdID0gMDsKICAgIGJ1Zl9jb3VudHJ5WzBdID0gMDsKCiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzYzOUxBTkdOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgIGJ1Zl9sYW5ndWFnZSwgc2l6ZW9mKGJ1Zl9sYW5ndWFnZSkvc2l6ZW9mKFdDSEFSKSk7CiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzMxNjZDVFJZTkFNRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICBidWZfY291bnRyeSwgc2l6ZW9mKGJ1Zl9jb3VudHJ5KS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2xhbmd1YWdlKSkKICAgIHsKICAgICAgICBpZihsX2RhdGEtPmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICBpZighc3RyY21waVcobF9kYXRhLT5jb3VudHJ5LCBidWZfY291bnRyeSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxfZGF0YS0+Zm91bmRfbGFuZ19pZFswXSA9IExhbmdJRDsKICAgICAgICAgICAgICAgIGxfZGF0YS0+bl9mb3VuZCA9IDE7CiAgICAgICAgICAgICAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlcyBjb3VudHJ5ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZyksIGRlYnVnc3RyX3cobF9kYXRhLT5jb3VudHJ5KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7IC8qIHN0b3AgZW51bWVyYXRpb24gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGdvdG8gZm91bmQ7IC8qIGxfZGF0YS0+Y291bnRyeSBub3Qgc3BlY2lmaWVkICovCiAgICB9CgogICAgLyogSnVzdCBpbiBjYXNlLCBjaGVjayBMT0NBTEVfU0VOR0xBTkdVQUdFIHRvbywKICAgICAqIGluIGhvcGUgdGhhdCBwb3NzaWJsZSBhbGlhcyBuYW1lIG1pZ2h0IGhhdmUgdGhhdCB2YWx1ZS4KICAgICAqLwogICAgYnVmX2VuX2xhbmd1YWdlWzBdID0gMDsKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TRU5HTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgYnVmX2VuX2xhbmd1YWdlLCBzaXplb2YoYnVmX2VuX2xhbmd1YWdlKS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2VuX2xhbmd1YWdlKSkgZ290byBmb3VuZDsKICAgIHJldHVybiBUUlVFOyAgLyogbm90IGZvdW5kLCBjb250aW51ZSBzZWFyY2ggKi8KCmZvdW5kOgogICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkW2xfZGF0YS0+bl9mb3VuZF0gPSBMYW5nSUQ7CiAgICBzdHJuY3B5VyhsX2RhdGEtPmZvdW5kX2NvdW50cnlbbF9kYXRhLT5uX2ZvdW5kXSwgYnVmX2NvdW50cnksIDMpOwogICAgc3RybmNweVcobF9kYXRhLT5mb3VuZF9sYW5ndWFnZVtsX2RhdGEtPm5fZm91bmRdLCBidWZfbGFuZ3VhZ2UsIDMpOwogICAgbF9kYXRhLT5uX2ZvdW5kKys7CiAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlc1xuIiwgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZykpOwogICAgcmV0dXJuIChsX2RhdGEtPm5fZm91bmQgPCBOTFNfTUFYX0xBTkdVQUdFUyk7IC8qIGNvbnRpbnVlIHNlYXJjaCwgdW5sZXNzIHdlIGhhdmUgZW5vdWdoICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGdldF9sYW5ndWFnZV9pZAogKgogKiBJTlBVVDoKICoJTGFuZzogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoJQ291bnRyeTogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgY291bnRyeQogKglDaGFyc2V0OiBhIHN0cmluZyBkZWZpbmluZyB0aGUgY2hvc2VuIGNoYXJzZXQgZW5jb2RpbmcKICoJRGlhbGVjdDogYSBzdHJpbmcgZGVmaW5pbmcgYSB2YXJpYXRpb24gb2YgdGhlIGxvY2FsZQogKgogKglhbGwgdGhvc2UgdmFsdWVzIGFyZSBmcm9tIHRoZSBzdGFuZGFyZGl6ZWQgZm9ybWF0IG9mIGxvY2FsZQogKgluYW1lIGluIHVuaXggd2hpY2ggaXM6IExhbmdbX0NvdW50cnldWy5DaGFyc2V0XVtARGlhbGVjdF0KICoKICogUkVUVVJOUzoKICoJdGhlIG51bWVyaWMgY29kZSBvZiB0aGUgbGFuZ3VhZ2UgdXNlZCBieSBXaW5kb3dzCiAqCiAqIEZJWE1FOiBDaGFyc2V0IGFuZCBEaWFsZWN0IGFyZSBub3QgaGFuZGxlZAogKi8Kc3RhdGljIExBTkdJRCBnZXRfbGFuZ3VhZ2VfaWQoTFBDU1RSIExhbmcsIExQQ1NUUiBDb3VudHJ5LCBMUENTVFIgQ2hhcnNldCwgTFBDU1RSIERpYWxlY3QpCnsKICAgIExBTkdfRklORF9EQVRBIGxfZGF0YTsKCiAgICBpZighTGFuZykKICAgIHsKICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIGdvdG8gRU5EOwogICAgfQoKICAgIGxfZGF0YS5uX2ZvdW5kID0gMDsKICAgIHN0cmNweW5BdG9XKGxfZGF0YS5sYW5nLCBMYW5nLCBzaXplb2YobF9kYXRhLmxhbmcpKTsKCiAgICBpZiAoQ291bnRyeSkgc3RyY3B5bkF0b1cobF9kYXRhLmNvdW50cnksIENvdW50cnksIHNpemVvZihsX2RhdGEuY291bnRyeSkpOwogICAgZWxzZSBsX2RhdGEuY291bnRyeVswXSA9IDA7CgogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzVyhrZXJuZWwzMl9oYW5kbGUsIChMUENXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTFBBUkFNKSZsX2RhdGEpOwoKICAgIGlmIChsX2RhdGEubl9mb3VuZCA9PSAxKSBnb3RvIEVORDsKCiAgICBpZighbF9kYXRhLm5fZm91bmQpCiAgICB7CiAgICAgICAgaWYobF9kYXRhLmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICAvKiByZXRyeSB3aXRob3V0IGNvdW50cnkgbmFtZSAqLwogICAgICAgICAgICBsX2RhdGEuY291bnRyeVswXSA9IDA7CiAgICAgICAgICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc1coa2VybmVsMzJfaGFuZGxlLCAoTFBDV1NUUilSVF9TVFJJTkcsIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTE9ORykmbF9kYXRhKTsKICAgICAgICAgICAgaWYgKCFsX2RhdGEubl9mb3VuZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzXyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIExhbmcsIENvdW50cnkpOwogICAgICAgICAgICAgICAgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0gPSBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCwgU1VCTEFOR19ERUZBVUxUKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIE1FU1NBR0UoIldhcm5pbmc6IExhbmd1YWdlICclc18lcycgd2FzIG5vdCByZWNvZ25pemVkLCBkZWZhdWx0aW5nIHRvICclcycuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgTGFuZywgQ291bnRyeSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsIExhbmcpOwogICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYgKENvdW50cnkgJiYgQ291bnRyeVswXSkKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclc18lcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcsIENvdW50cnkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcpOwoKICAgICAgICAvKiBwcmludCBhIGxpc3Qgb2YgbGFuZ3VhZ2VzIHdpdGggdGhlaXIgZGVzY3JpcHRpb24gKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbF9kYXRhLm5fZm91bmQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIGJ1ZmZXWzEyOF07CiAgICAgICAgICAgIGNoYXIgYnVmZkFbMTI4XTsKICAgICAgICAgICAgR2V0TG9jYWxlSW5mb1coIE1BS0VMQ0lEKCBsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSwgU09SVF9ERUZBVUxUICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQ0FMRV9TTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmVywgc2l6ZW9mKGJ1ZmZXKS9zaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgc3RyY3B5V3RvQSggYnVmZkEsIGJ1ZmZXICk7CiAgICAgICAgICAgIE1FU1NBR0UoICIgICAlcyAoJTA0WCkgLSAlc1xuIiwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSksCiAgICAgICAgICAgICAgICAgICAgIGxfZGF0YS5mb3VuZF9sYW5nX2lkW2ldLCBidWZmQSApOwogICAgICAgIH0KICAgICAgICBNRVNTQUdFKCJEZWZhdWx0aW5nIHRvICclcycuIFlvdSBzaG91bGQgc3BlY2lmeSB0aGUgZXhhY3QgbGFuZ3VhZ2UgeW91IHdhbnRcbiIKICAgICAgICAgICAgICAgICJieSBkZWZpbmluZyB5b3VyIExBTkcgZW52aXJvbm1lbnQgdmFyaWFibGUgbGlrZSB0aGlzOiBMQU5HPSVzXG4iLAogICAgICAgICAgICAgICAgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSksIGRlYnVnc3RyX2xhbmcobF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pICk7CiAgICB9CkVORDoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA0WCAoJXMpXG4iLCBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkpOwogICAgcmV0dXJuIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBjaGFyc2V0X2NtcCAoaW50ZXJuYWwpCiAqLwpzdGF0aWMgaW50IGNoYXJzZXRfY21wKCBjb25zdCB2b2lkICpuYW1lLCBjb25zdCB2b2lkICplbnRyeSApCnsKICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICpjaGFyc2V0ID0gKGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICopZW50cnk7CiAgICByZXR1cm4gc3RyY2FzZWNtcCggKGNvbnN0IGNoYXIgKiluYW1lLCBjaGFyc2V0LT5jaGFyc2V0X25hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZW52X2xjaWQKICovCnN0YXRpYyBMQ0lEIGdldF9lbnZfbGNpZCggVUlOVCAqdW5peF9jcCwgY29uc3QgY2hhciAqZW52X3N0ciApCnsKICAgIGNoYXIgKmJ1ZiwgKmxhbmcsKmNvdW50cnksKmNoYXJzZXQsKmRpYWxlY3QsKm5leHQ7CiAgICBMQ0lEIHJldCA9IDA7CgogICAgaWYgKChsYW5nID0gZ2V0ZW52KCAiTENfQUxMIiApKSB8fAogICAgICAgIChlbnZfc3RyICYmIChsYW5nID0gZ2V0ZW52KCBlbnZfc3RyICkpKSB8fAogICAgICAgIChsYW5nID0gZ2V0ZW52KCAiTEFORyIgKSkpCiAgICB7CiAgICAgICAgaWYgKCFzdHJjbXAobGFuZywiUE9TSVgiKSB8fCAhc3RyY21wKGxhbmcsIkMiKSkgZ290byBkb25lOwoKICAgICAgICBidWYgPSBSdGxBbGxvY2F0ZUhlYXAoIEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihsYW5nKSArIDEgKTsKICAgICAgICBzdHJjcHkoIGJ1ZiwgbGFuZyApOwogICAgICAgIGxhbmc9YnVmOwoKICAgICAgICBkbyB7CiAgICAgICAgICAgIG5leHQ9c3RyY2hyKGxhbmcsJzonKTsgaWYgKG5leHQpICpuZXh0Kys9J1wwJzsKICAgICAgICAgICAgZGlhbGVjdD1zdHJjaHIobGFuZywnQCcpOyBpZiAoZGlhbGVjdCkgKmRpYWxlY3QrKz0nXDAnOwogICAgICAgICAgICBjaGFyc2V0PXN0cmNocihsYW5nLCcuJyk7IGlmIChjaGFyc2V0KSAqY2hhcnNldCsrPSdcMCc7CiAgICAgICAgICAgIGNvdW50cnk9c3RyY2hyKGxhbmcsJ18nKTsgaWYgKGNvdW50cnkpICpjb3VudHJ5Kys9J1wwJzsKCiAgICAgICAgICAgIHJldCA9IGdldF9sYW5ndWFnZV9pZChsYW5nLCBjb3VudHJ5LCBjaGFyc2V0LCBkaWFsZWN0KTsKICAgICAgICAgICAgaWYgKHJldCAmJiBjaGFyc2V0ICYmIHVuaXhfY3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICplbnRyeTsKICAgICAgICAgICAgICAgIGNoYXIgY2hhcnNldF9uYW1lWzE2XTsKICAgICAgICAgICAgICAgIHNpemVfdCBpLCBqOwoKICAgICAgICAgICAgICAgIC8qIHJlbW92ZSBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZyb20gY2hhcnNldCBuYW1lICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSBqID0gMDsgY2hhcnNldFtpXSAmJiBqIDwgc2l6ZW9mKGNoYXJzZXRfbmFtZSktMTsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChpc2FsbnVtKGNoYXJzZXRbaV0pKSBjaGFyc2V0X25hbWVbaisrXSA9IGNoYXJzZXRbaV07CiAgICAgICAgICAgICAgICBjaGFyc2V0X25hbWVbal0gPSAwOwoKICAgICAgICAgICAgICAgIGVudHJ5ID0gYnNlYXJjaCggY2hhcnNldF9uYW1lLCBjaGFyc2V0X25hbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lcykvc2l6ZW9mKGNoYXJzZXRfbmFtZXNbMF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lc1swXSksIGNoYXJzZXRfY21wICk7CiAgICAgICAgICAgICAgICBpZiAoZW50cnkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKnVuaXhfY3AgPSBlbnRyeS0+Y29kZXBhZ2U7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoImNoYXJzZXQgJXMgd2FzIG1hcHBlZCB0byBjcCAldVxuIiwgY2hhcnNldCwgKnVuaXhfY3ApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJjaGFyc2V0ICVzIHdhcyBub3QgcmVjb2duaXplZFxuIiwgY2hhcnNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxhbmc9bmV4dDsKICAgICAgICB9IHdoaWxlIChsYW5nICYmICFyZXQpOwoKICAgICAgICBpZiAoIXJldCkgTUVTU0FHRSgiV2FybmluZzogbGFuZ3VhZ2UgJyVzJyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoXG4iLCBidWYpOwogICAgICAgIFJ0bEZyZWVIZWFwKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYgKTsKICAgIH0KCiBkb25lOgogICAgaWYgKCFyZXQpIHJldCA9IE1BS0VMQ0lEKCBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCxTVUJMQU5HX0RFRkFVTFQpLCBTT1JUX0RFRkFVTFQpIDsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExhbmdJRCh2b2lkKQp7CiAgICByZXR1cm4gTEFOR0lERlJPTUxDSUQoR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKHZvaWQpCnsKICAgIHJldHVybiBMQU5HSURGUk9NTENJRChHZXRTeXN0ZW1EZWZhdWx0TENJRCgpKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTENJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRMQ0lEKHZvaWQpCnsKICAgIExDSUQgbGNpZDsKICAgIE50UXVlcnlEZWZhdWx0TG9jYWxlKCBUUlVFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgc3lzdGVtLgogKi8KTENJRCBXSU5BUEkgR2V0U3lzdGVtRGVmYXVsdExDSUQodm9pZCkKewogICAgTENJRCBsY2lkOwogICAgTnRRdWVyeURlZmF1bHRMb2NhbGUoIEZBTFNFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0VUlMYW5ndWFnZSAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBkZWZhdWx0IHVzZXIgaW50ZXJmYWNlIGxhbmd1YWdlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExBTkdJRCBvZiB0aGUgZGVmYXVsdCBVSSBsYW5ndWFnZSBmb3IgdGhlIGN1cnJlbnQgdXNlci4KICovCkxBTkdJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRVSUxhbmd1YWdlKHZvaWQpCnsKICAgIExBTkdJRCBsYW5nOwogICAgTnRRdWVyeURlZmF1bHRVSUxhbmd1YWdlKCAmbGFuZyApOwogICAgcmV0dXJuIGxhbmc7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLiBUaGlzIGlzCiAqICB0eXBpY2FsbHkgdGhlIHNhbWUgbGFuZ3VhZ2UgdXNlZCBkdXJpbmcgdGhlIGluc3RhbGxhdGlvbiBwcm9jZXNzLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0VUlMYW5ndWFnZSh2b2lkKQp7CiAgICBMQU5HSUQgbGFuZzsKICAgIE50UXVlcnlJbnN0YWxsVUlMYW5ndWFnZSggJmxhbmcgKTsKICAgIHJldHVybiBsYW5nOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2xvY2FsZV92YWx1ZV9uYW1lCiAqCiAqIEdldHMgdGhlIHJlZ2lzdHJ5IHZhbHVlIG5hbWUgZm9yIGEgZ2l2ZW4gbGN0eXBlLgogKi8Kc3RhdGljIGNvbnN0IFdDSEFSICpnZXRfbG9jYWxlX3ZhbHVlX25hbWUoIERXT1JEIGxjdHlwZSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ2FsZW5kYXJUeXBlV1tdID0geydpJywnQycsJ2EnLCdsJywnZScsJ24nLCdkJywnYScsJ3InLCdUJywneScsJ3AnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ291bnRyeVdbXSA9IHsnaScsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDdXJyRGlnaXRzV1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUN1cnJlbmN5V1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywnYycsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlEYXRlV1tdID0geydpJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaURpZ2l0c1dbXSA9IHsnaScsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUZpcnN0RGF5T2ZXZWVrV1tdID0geydpJywnRicsJ2knLCdyJywncycsJ3QnLCdEJywnYScsJ3knLCdPJywnZicsJ1cnLCdlJywnZScsJ2snLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlGaXJzdFdlZWtPZlllYXJXW10gPSB7J2knLCdGJywnaScsJ3InLCdzJywndCcsJ1cnLCdlJywnZScsJ2snLCdPJywnZicsJ1knLCdlJywnYScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlMRGF0ZVdbXSA9IHsnaScsJ0wnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTFplcm9XW10gPSB7J2knLCdMJywnWicsJ2UnLCdyJywnbycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU1lYXN1cmVXW10gPSB7J2knLCdNJywnZScsJ2EnLCdzJywndScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTmVnQ3VycldbXSA9IHsnaScsJ04nLCdlJywnZycsJ0MnLCd1JywncicsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlOZWdOdW1iZXJXW10gPSB7J2knLCdOJywnZScsJ2cnLCdOJywndScsJ20nLCdiJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlQYXBlclNpemVXW10gPSB7J2knLCdQJywnYScsJ3AnLCdlJywncicsJ1MnLCdpJywneicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUTFplcm9XW10gPSB7J2knLCdUJywnTCcsJ1onLCdlJywncicsJ28nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUaW1lUHJlZml4V1tdID0geydpJywnVCcsJ2knLCdtJywnZScsJ1AnLCdyJywnZScsJ2YnLCdpJywneCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRpbWVXW10gPSB7J2knLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzMTE1OVdbXSA9IHsncycsJzEnLCcxJywnNScsJzknLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMyMzU5V1tdID0geydzJywnMicsJzMnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0NvdW50cnlXW10gPSB7J3MnLCdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ3VycmVuY3lXW10gPSB7J3MnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCdjJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0RhdGVXW10gPSB7J3MnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGVjaW1hbFdbXSA9IHsncycsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNHcm91cGluZ1dbXSA9IHsncycsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGFuZ3VhZ2VXW10gPSB7J3MnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0xpc3RXW10gPSB7J3MnLCdMJywnaScsJ3MnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTG9uZ0RhdGVXW10gPSB7J3MnLCdMJywnbycsJ24nLCdnJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vbkRlY2ltYWxTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdEJywnZScsJ2MnLCdpJywnbScsJ2EnLCdsJywnUycsJ2UnLCdwJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uR3JvdXBpbmdXW10gPSB7J3MnLCdNJywnbycsJ24nLCdHJywncicsJ28nLCd1JywncCcsJ2knLCduJywnZycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vblRob3VzYW5kU2VwV1tdID0geydzJywnTScsJ28nLCduJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOYXRpdmVEaWdpdHNXW10gPSB7J3MnLCdOJywnYScsJ3QnLCdpJywndicsJ2UnLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOZWdhdGl2ZVNpZ25XW10gPSB7J3MnLCdOJywnZScsJ2cnLCdhJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNQb3NpdGl2ZVNpZ25XW10gPSB7J3MnLCdQJywnbycsJ3MnLCdpJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNTaG9ydERhdGVXW10gPSB7J3MnLCdTJywnaCcsJ28nLCdyJywndCcsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaG91c2FuZFdbXSA9IHsncycsJ1QnLCdoJywnbycsJ3UnLCdzJywnYScsJ24nLCdkJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzVGltZUZvcm1hdFdbXSA9IHsncycsJ1QnLCdpJywnbScsJ2UnLCdGJywnbycsJ3InLCdtJywnYScsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lV1tdID0geydzJywnVCcsJ2knLCdtJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1llYXJNb250aFdbXSA9IHsncycsJ1knLCdlJywnYScsJ3InLCdNJywnbycsJ24nLCd0JywnaCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTnVtU2hhcGVXW10gPSB7J04nLCd1JywnbScsJ3MnLCdoJywnYScsJ3AnLCdlJywwfTsKCiAgICBzd2l0Y2ggKGxjdHlwZSkKICAgIHsKICAgIC8qIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBieSBTZXRMb2NhbGVJbmZvIGFuZCBHZXRMb2NhbGVJbmZvLCBhbmQKICAgICAqIHRoZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVnaXN0cnksIGNvbmZpcm1lZCB1bmRlciBXaW5kb3dzLgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOiAgICByZXR1cm4gaUNhbGVuZGFyVHlwZVc7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzogICAgICByZXR1cm4gaUN1cnJEaWdpdHNXOwogICAgY2FzZSBMT0NBTEVfSUNVUlJFTkNZOiAgICAgICAgcmV0dXJuIGlDdXJyZW5jeVc7CiAgICBjYXNlIExPQ0FMRV9JRElHSVRTOiAgICAgICAgICByZXR1cm4gaURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6ICByZXR1cm4gaUZpcnN0RGF5T2ZXZWVrVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVFdFRUtPRllFQVI6IHJldHVybiBpRmlyc3RXZWVrT2ZZZWFyVzsKICAgIGNhc2UgTE9DQUxFX0lMWkVSTzogICAgICAgICAgIHJldHVybiBpTFplcm9XOwogICAgY2FzZSBMT0NBTEVfSU1FQVNVUkU6ICAgICAgICAgcmV0dXJuIGlNZWFzdXJlVzsKICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOiAgICAgICAgIHJldHVybiBpTmVnQ3Vyclc7CiAgICBjYXNlIExPQ0FMRV9JTkVHTlVNQkVSOiAgICAgICByZXR1cm4gaU5lZ051bWJlclc7CiAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOiAgICAgICByZXR1cm4gaVBhcGVyU2l6ZVc7CiAgICBjYXNlIExPQ0FMRV9JVElNRTogICAgICAgICAgICByZXR1cm4gaVRpbWVXOwogICAgY2FzZSBMT0NBTEVfUzExNTk6ICAgICAgICAgICAgcmV0dXJuIHMxMTU5VzsKICAgIGNhc2UgTE9DQUxFX1MyMzU5OiAgICAgICAgICAgIHJldHVybiBzMjM1OVc7CiAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gc0N1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX1NEQVRFOiAgICAgICAgICAgIHJldHVybiBzRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TREVDSU1BTDogICAgICAgICByZXR1cm4gc0RlY2ltYWxXOwogICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOiAgICAgICAgcmV0dXJuIHNHcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTElTVDogICAgICAgICAgICByZXR1cm4gc0xpc3RXOwogICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOiAgICAgICAgcmV0dXJuIHNMb25nRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TTU9OREVDSU1BTFNFUDogICByZXR1cm4gc01vbkRlY2ltYWxTZXBXOwogICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOiAgICAgcmV0dXJuIHNNb25Hcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVA6ICByZXR1cm4gc01vblRob3VzYW5kU2VwVzsKICAgIGNhc2UgTE9DQUxFX1NORUdBVElWRVNJR046ICAgIHJldHVybiBzTmVnYXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NQT1NJVElWRVNJR046ICAgIHJldHVybiBzUG9zaXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NTSE9SVERBVEU6ICAgICAgIHJldHVybiBzU2hvcnREYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NUSE9VU0FORDogICAgICAgIHJldHVybiBzVGhvdXNhbmRXOwogICAgY2FzZSBMT0NBTEVfU1RJTUU6ICAgICAgICAgICAgcmV0dXJuIHNUaW1lVzsKICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOiAgICAgIHJldHVybiBzVGltZUZvcm1hdFc7CiAgICBjYXNlIExPQ0FMRV9TWUVBUk1PTlRIOiAgICAgICByZXR1cm4gc1llYXJNb250aFc7CgogICAgLyogVGhlIGZvbGxvd2luZyBhcmUgbm90IGxpc3RlZCB1bmRlciBNU0ROIGFzIHN1cHBvcnRlZCwKICAgICAqIGJ1dCBzZWVtIHRvIGJlIHVzZWQgYW5kIGFsc28gc3RvcmVkIGluIHRoZSByZWdpc3RyeS4KICAgICAqLwogICAgY2FzZSBMT0NBTEVfSUNPVU5UUlk6ICAgICAgICAgcmV0dXJuIGlDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX0lEQVRFOiAgICAgICAgICAgIHJldHVybiBpRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9JTERBVEU6ICAgICAgICAgICByZXR1cm4gaUxEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lUTFpFUk86ICAgICAgICAgIHJldHVybiBpVExaZXJvVzsKICAgIGNhc2UgTE9DQUxFX1NDT1VOVFJZOiAgICAgICAgIHJldHVybiBzQ291bnRyeVc7CiAgICBjYXNlIExPQ0FMRV9TTEFOR1VBR0U6ICAgICAgICByZXR1cm4gc0xhbmd1YWdlVzsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIGluIFhQIGFuZCBsYXRlciAqLwogICAgY2FzZSBMT0NBTEVfSURJR0lUU1VCU1RJVFVUSU9OOiByZXR1cm4gTnVtU2hhcGVXOwogICAgY2FzZSBMT0NBTEVfU05BVElWRURJR0lUUzogICAgICByZXR1cm4gc05hdGl2ZURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JVElNRU1BUktQT1NOOiAgICAgIHJldHVybiBpVGltZVByZWZpeFc7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbwogKgogKiBSZXRyaWV2ZSB1c2VyLW1vZGlmaWVkIGxvY2FsZSBpbmZvIGZyb20gdGhlIHJlZ2lzdHJ5LgogKiBSZXR1cm4gbGVuZ3RoLCAwIG9uIGVycm9yLCAtMSBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgSU5UIGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIERXT1JEIHNpemU7CiAgICBJTlQgcmV0OwogICAgSEtFWSBoa2V5OwogICAgTlRTVEFUVVMgc3RhdHVzOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbzsKICAgIHN0YXRpYyBjb25zdCBpbnQgaW5mb19zaXplID0gRklFTERfT0ZGU0VUKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OLCBEYXRhKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkgcmV0dXJuIC0xOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHZhbHVlICk7CiAgICBzaXplID0gaW5mb19zaXplICsgbGVuICogc2l6ZW9mKFdDSEFSKTsKCiAgICBpZiAoIShpbmZvID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplICkpKQogICAgewogICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3RhdHVzID0gTnRRdWVyeVZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBpbmZvLCBzaXplLCAmc2l6ZSApOwogICAgaWYgKHN0YXR1cyA9PSBTVEFUVVNfQlVGRkVSX09WRVJGTE9XICYmICFidWZmZXIpIHN0YXR1cyA9IDA7CgogICAgaWYgKCFzdGF0dXMpCiAgICB7CiAgICAgICAgcmV0ID0gKHNpemUgLSBpbmZvX3NpemUpIC8gc2l6ZW9mKFdDSEFSKTsKICAgICAgICAvKiBhcHBlbmQgdGVybWluYXRpbmcgbnVsbCBpZiBuZWVkZWQgKi8KICAgICAgICBpZiAoIXJldCB8fCAoKFdDSEFSICopaW5mby0+RGF0YSlbcmV0LTFdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJldCA8IGxlbiB8fCAhYnVmZmVyKSByZXQrKzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJldCAmJiBidWZmZXIpCiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgaW5mby0+RGF0YSwgKHJldC0xKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgYnVmZmVyW3JldC0xXSA9IDA7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzdGF0dXMgPT0gU1RBVFVTX09CSkVDVF9OQU1FX05PVF9GT1VORCkgcmV0ID0gLTE7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBSdGxOdFN0YXR1c1RvRG9zRXJyb3Ioc3RhdHVzKSApOwogICAgICAgICAgICByZXQgPSAwOwogICAgICAgIH0KICAgIH0KICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0TG9jYWxlSW5mb0EgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGJ1ZmZlciBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBpbmZvcm1hdGlvbgogKiAgbGVuICAgIFtJXSBMZW5ndGggb2YgYnVmZmVyIGluIGNoYXJhY3RlcnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHNpemUgb2YgdGhlIGRhdGEgcmVxdWVzdGVkLiBJZiBidWZmZXIgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgaW5mb3JtYXRpb24uCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gTE9DQUxFX05FVVRSQUwgaXMgZXF1YWwgdG8gTE9DQUxFX1NZU1RFTV9ERUZBVUxUCiAqICAtIFRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgTlVMIHRlcm1pbmF0ZWQsIGV4Y2VwdCBmb3IgTE9DQUxFX0ZPTlRTSUdOQVRVUkUsCiAqICAgIHdoaWNoIGlzIGEgYml0IHN0cmluZy4KICovCklOVCBXSU5BUEkgR2V0TG9jYWxlSW5mb0EoIExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgV0NIQVIgKmJ1ZmZlclc7CiAgICBJTlQgbGVuVywgcmV0OwoKICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKVxuIiwgbGNpZCwgbGN0eXBlLCBidWZmZXIsIGxlbiApOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgaWYgKCEobGVuVyA9IEdldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIE5VTEwsIDAgKSkpIHJldHVybiAwOwoKICAgIGlmICghKGJ1ZmZlclcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlblcgKiBzaXplb2YoV0NIQVIpICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICgocmV0ID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIGxjdHlwZSwgYnVmZmVyVywgbGVuVyApKSkKICAgIHsKICAgICAgICBpZiAoKGxjdHlwZSAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSB8fAogICAgICAgICAgICAoKGxjdHlwZSAmIH5MT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSykgPT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogaXQncyBub3QgYW4gQVNDSUkgc3RyaW5nLCBqdXN0IGJ5dGVzICovCiAgICAgICAgICAgIHJldCAqPSBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBpZiAoYnVmZmVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocmV0IDw9IGxlbikgbWVtY3B5KCBidWZmZXIsIGJ1ZmZlclcsIHJldCApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgICAgICAgICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICAgICAgICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIGNvZGVwYWdlLCAwLCBidWZmZXJXLCByZXQsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlclcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvVyAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldExvY2FsZUluZm9BLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgTEFOR0lEIGxhbmdfaWQ7CiAgICBIUlNSQyBocnNyYzsKICAgIEhHTE9CQUwgaG1lbTsKICAgIElOVCByZXQ7CiAgICBVSU5UIGxjZmxhZ3M7CiAgICBjb25zdCBXQ0hBUiAqcDsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjZmxhZ3MgPSBsY3R5cGUgJiBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSzsKICAgIGxjdHlwZSAmPSAweGZmZmY7CgogICAgVFJBQ0UoICIobGNpZD0weCVseCxsY3R5cGU9MHglbHgsJXAsJWQpXG4iLCBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuICk7CgogICAgLyogZmlyc3QgY2hlY2sgZm9yIG92ZXJyaWRlcyBpbiB0aGUgcmVnaXN0cnkgKi8KCiAgICBpZiAoIShsY2ZsYWdzICYgTE9DQUxFX05PVVNFUk9WRVJSSURFKSAmJiBsY2lkID09IEdldFVzZXJEZWZhdWx0TENJRCgpKQogICAgewogICAgICAgIGNvbnN0IFdDSEFSICp2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZShsY3R5cGUpOwoKICAgICAgICBpZiAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAobGNmbGFncyAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ0hBUiB0bXBbMTZdOwogICAgICAgICAgICAgICAgcmV0ID0gZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCB2YWx1ZSwgdG1wLCBzaXplb2YodG1wKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBpZiAocmV0ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQ0hBUiAqZW5kOwogICAgICAgICAgICAgICAgICAgIFVJTlQgbnVtYmVyID0gc3RydG9sVyggdG1wLCAmZW5kLCAxMCApOwogICAgICAgICAgICAgICAgICAgIGlmICgqZW5kKSAgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gc2l6ZW9mKFVJTlQpL3NpemVvZihXQ0hBUik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFidWZmZXIpIHJldHVybiByZXQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJldCA+IGxlbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsICZudW1iZXIsIHNpemVvZihudW1iZXIpICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSByZXQgPSBnZXRfcmVnaXN0cnlfbG9jYWxlX2luZm8oIHZhbHVlLCBidWZmZXIsIGxlbiApOwoKICAgICAgICAgICAgaWYgKHJldCAhPSAtMSkgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9CgogICAgLyogbm93IGxvYWQgaXQgZnJvbSBrZXJuZWwgcmVzb3VyY2VzICovCgogICAgbGFuZ19pZCA9IExBTkdJREZST01MQ0lEKCBsY2lkICk7CgogICAgLyogcmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgYnkgU1VCTEFOR19ERUZBVUxUICovCiAgICBpZiAoU1VCTEFOR0lEKGxhbmdfaWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nX2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdfaWQpLCBTVUJMQU5HX0RFRkFVTFQpOwoKICAgIGlmICghKGhyc3JjID0gRmluZFJlc291cmNlRXhXKCBrZXJuZWwzMl9oYW5kbGUsIChMUFdTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKSgobGN0eXBlID4+IDQpICsgMSksIGxhbmdfaWQgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7ICAvKiBubyBzdWNoIGxjdHlwZSAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCEoaG1lbSA9IExvYWRSZXNvdXJjZSgga2VybmVsMzJfaGFuZGxlLCBocnNyYyApKSkKICAgICAgICByZXR1cm4gMDsKCiAgICBwID0gTG9ja1Jlc291cmNlKCBobWVtICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKGxjdHlwZSAmIDB4MGYpOyBpKyspIHAgKz0gKnAgKyAxOwoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpIHJldCA9IHNpemVvZihVSU5UKS9zaXplb2YoV0NIQVIpOwogICAgZWxzZSByZXQgPSAobGN0eXBlID09IExPQ0FMRV9GT05UU0lHTkFUVVJFKSA/ICpwIDogKnAgKyAxOwoKICAgIGlmICghYnVmZmVyKSByZXR1cm4gcmV0OwoKICAgIGlmIChyZXQgPiBsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGxjZmxhZ3MgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikKICAgIHsKICAgICAgICBVSU5UIG51bWJlcjsKICAgICAgICBXQ0hBUiAqZW5kLCAqdG1wID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoKnAgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICBpZiAoIXRtcCkgcmV0dXJuIDA7CiAgICAgICAgbWVtY3B5KCB0bXAsIHAgKyAxLCAqcCAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICB0bXBbKnBdID0gMDsKICAgICAgICBudW1iZXIgPSBzdHJ0b2xXKCB0bXAsICZlbmQsIDEwICk7CiAgICAgICAgaWYgKCEqZW5kKQogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgJm51bWJlciwgc2l6ZW9mKG51bWJlcikgKTsKICAgICAgICBlbHNlICAvKiBpbnZhbGlkIG51bWJlciAqLwogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB0bXAgKTsKCiAgICAgICAgVFJBQ0UoICIobGNpZD0weCVseCxsY3R5cGU9MHglbHgsJXAsJWQpIHJldHVybmluZyBudW1iZXIgJWRcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIG51bWJlciApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG1lbWNweSggYnVmZmVyLCBwICsgMSwgKnAgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgaWYgKGxjdHlwZSAhPSBMT0NBTEVfRk9OVFNJR05BVFVSRSkgYnVmZmVyW3JldC0xXSA9IDA7CgogICAgICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKSByZXR1cm5pbmcgJWQgJXNcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIHJldCwgZGVidWdzdHJfdyhidWZmZXIpICk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb0EJW0tFUk5FTDMyLkBdCiAqCiAqIFNldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGRhdGEgICBbSV0gSW5mb3JtYXRpb24gdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIFRoZSBpbmZvcm1hdGlvbiBnaXZlbiB3aWxsIGJlIHJldHVybmVkIGJ5IEdldExvY2FsZUluZm9BKCkKICogICAgICAgICAgIHdoZW5ldmVyIGl0IGlzIGNhbGxlZCB3aXRob3V0IExPQ0FMRV9OT1VTRVJPVkVSUklERS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gVmFsdWVzIGFyZSBvbmx5IGJlIHNldCBmb3IgdGhlIGN1cnJlbnQgdXNlciBsb2NhbGU7IHRoZSBzeXN0ZW0gbG9jYWxlCiAqICBzZXR0aW5ncyBjYW5ub3QgYmUgY2hhbmdlZC4KICogIC0gQW55IHNldHRpbmdzIGNoYW5nZWQgYnkgdGhpcyBjYWxsIGFyZSBsb3N0IHdoZW4gdGhlIGxvY2FsZSBpcyBjaGFuZ2VkIGJ5CiAqICB0aGUgY29udHJvbCBwYW5lbCAoaW4gV2luZSwgdGhpcyBoYXBwZW5zIGV2ZXJ5IHRpbWUgeW91IGNoYW5nZSBMQU5HKS4KICogIC0gVGhlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGNoZWNrIHRoYXQgbGNpZCBtYXRjaGVzCiAqICB0aGUgY3VycmVudCB1c2VyIGxvY2FsZSwgYW5kIHNpbXBseSBzZXRzIHRoZSBuZXcgdmFsdWVzLiBXaW5lIHdhcm5zIHlvdSBpbgogKiAgdGhpcyBjYXNlLCBidXQgYmVoYXZlcyB0aGUgc2FtZS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9BKExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBDU1RSIGRhdGEpCnsKICAgIFVJTlQgY29kZXBhZ2UgPSBDUF9BQ1A7CiAgICBXQ0hBUiAqc3RyVzsKICAgIERXT1JEIGxlbjsKICAgIEJPT0wgcmV0OwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBpZiAoIShsY3R5cGUgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGNvZGVwYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKCiAgICBpZiAoIWRhdGEpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKCEoc3RyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggY29kZXBhZ2UsIDAsIGRhdGEsIC0xLCBzdHJXLCBsZW4gKTsKICAgIHJldCA9IFNldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIHN0clcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb1cJKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBTZXRMb2NhbGVJbmZvQS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9XKCBMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQQ1dTVFIgZGF0YSApCnsKICAgIGNvbnN0IFdDSEFSICp2YWx1ZTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpbnRsV1tdID0geydpJywnbicsJ3QnLCdsJywwIH07CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZVc7CiAgICBOVFNUQVRVUyBzdGF0dXM7CiAgICBIS0VZIGhrZXk7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjdHlwZSAmPSAweGZmZmY7CiAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgaWYgKCFkYXRhIHx8ICF2YWx1ZSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsY3R5cGUgPT0gTE9DQUxFX0lEQVRFIHx8IGxjdHlwZSA9PSBMT0NBTEVfSUxEQVRFKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGNpZCAhPSBHZXRVc2VyRGVmYXVsdExDSUQoKSkKICAgIHsKICAgICAgICAvKiBXaW5kb3dzIGRvZXMgbm90IGNoZWNrIHRoYXQgdGhlIGxjaWQgbWF0Y2hlcyB0aGUgY3VycmVudCBsY2lkICovCiAgICAgICAgV0FSTigibG9jYWxlIDB4JTA4bHggaXNuJ3QgdGhlIGN1cnJlbnQgbG9jYWxlICgweCUwOGx4KSwgc2V0dGluZyBhbnl3YXkhXG4iLAogICAgICAgICAgICAgbGNpZCwgR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwogICAgfQoKICAgIFRSQUNFKCJzZXR0aW5nICVseCAoJXMpIHRvICVzXG4iLCBsY3R5cGUsIGRlYnVnc3RyX3codmFsdWUpLCBkZWJ1Z3N0cl93KGRhdGEpICk7CgogICAgLyogRklYTUU6IHNob3VsZCBjaGVjayB0aGF0IGRhdGEgdG8gc2V0IGlzIHNhbmUgKi8KCiAgICAvKiBGSVhNRTogcHJvZmlsZSBmdW5jdGlvbnMgc2hvdWxkIG1hcCB0byByZWdpc3RyeSAqLwogICAgV3JpdGVQcm9maWxlU3RyaW5nVyggaW50bFcsIHZhbHVlLCBkYXRhICk7CgogICAgaWYgKCEoaGtleSA9IGNyZWF0ZV9yZWdpc3RyeV9rZXkoKSkpIHJldHVybiBGQUxTRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCB2YWx1ZSApOwogICAgc3RhdHVzID0gTnRTZXRWYWx1ZUtleSggaGtleSwgJnZhbHVlVywgMCwgUkVHX1NaLCBkYXRhLCAoc3RybGVuVyhkYXRhKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYgKGxjdHlwZSA9PSBMT0NBTEVfU1NIT1JUREFURSB8fCBsY3R5cGUgPT0gTE9DQUxFX1NMT05HREFURSkKICAgIHsKICAgICAgLyogU2V0IEktdmFsdWUgZnJvbSBTIHZhbHVlICovCiAgICAgIFdDSEFSICpscEQsICpscE0sICpscFk7CiAgICAgIFdDSEFSIHN6QnVmZlsyXTsKCiAgICAgIGxwRCA9IHN0cnJjaHJXKGRhdGEsICdkJyk7CiAgICAgIGxwTSA9IHN0cnJjaHJXKGRhdGEsICdNJyk7CiAgICAgIGxwWSA9IHN0cnJjaHJXKGRhdGEsICd5Jyk7CgogICAgICBpZiAobHBEIDw9IGxwTSkKICAgICAgewogICAgICAgIHN6QnVmZlswXSA9ICcxJzsgLyogRC1NLVkgKi8KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICBpZiAobHBZIDw9IGxwTSkKICAgICAgICAgIHN6QnVmZlswXSA9ICcyJzsgLyogWS1NLUQgKi8KICAgICAgICBlbHNlCiAgICAgICAgICBzekJ1ZmZbMF0gPSAnMCc7IC8qIE0tRC1ZICovCiAgICAgIH0KCiAgICAgIHN6QnVmZlsxXSA9ICdcMCc7CgogICAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TU0hPUlREQVRFKQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JREFURTsKICAgICAgZWxzZQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JTERBVEU7CgogICAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgICBXcml0ZVByb2ZpbGVTdHJpbmdXKCBpbnRsVywgdmFsdWUsIHN6QnVmZiApOwoKICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIHZhbHVlICk7CiAgICAgIHN0YXR1cyA9IE50U2V0VmFsdWVLZXkoIGhrZXksICZ2YWx1ZVcsIDAsIFJFR19TWiwgc3pCdWZmLCBzaXplb2Yoc3pCdWZmKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBpZiAoc3RhdHVzKSBTZXRMYXN0RXJyb3IoIFJ0bE50U3RhdHVzVG9Eb3NFcnJvcihzdGF0dXMpICk7CiAgICByZXR1cm4gIXN0YXR1czsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEdldEFDUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgQW5zaSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgICBUaGUgY3VycmVudCBBbnNpIGNvZGUgcGFnZSBpZGVudGlmaWVyIGZvciB0aGUgc3lzdGVtLgogKi8KVUlOVCBXSU5BUEkgR2V0QUNQKHZvaWQpCnsKICAgIGFzc2VydCggYW5zaV9jcHRhYmxlICk7CiAgICByZXR1cm4gYW5zaV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRPRU1DUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgT0VNIGNvZGUgcGFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAgIFRoZSBjdXJyZW50IE9FTSBjb2RlIHBhZ2UgaWRlbnRpZmllciBmb3IgdGhlIHN5c3RlbS4KICovClVJTlQgV0lOQVBJIEdldE9FTUNQKHZvaWQpCnsKICAgIGFzc2VydCggb2VtX2NwdGFibGUgKTsKICAgIHJldHVybiBvZW1fY3B0YWJsZS0+aW5mby5jb2RlcGFnZTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZENvZGVQYWdlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGdpdmVuIGNvZGUgcGFnZSBpZGVudGlmaWVyIGlzIHZhbGlkLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgSWQgdG8gdmVyaWZ5LgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBJZiBjb2RlcGFnZSBpcyB2YWxpZCBhbmQgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc1ZhbGlkQ29kZVBhZ2UoIFVJTlQgY29kZXBhZ2UgKQp7CiAgICBzd2l0Y2goY29kZXBhZ2UpIHsKICAgIGNhc2UgQ1BfVVRGNzoKICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHdpbmVfY3BfZ2V0X3RhYmxlKCBjb2RlcGFnZSApICE9IE5VTEw7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlRXggICAoS0VSTkVMMzIuQCkKICoKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgbGVhZCBieXRlIGluIGEgZ2l2ZW4gY29kZSBwYWdlLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgZm9yIHRoZSB0ZXN0LgogKiAgdGVzdGNoYXIgW0ldIENoYXJhY3RlciB0byB0ZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHRlc3RjaGFyIGlzIGEgbGVhZCBieXRlIGluIGNvZGVwYWdlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNEQkNTTGVhZEJ5dGVFeCggVUlOVCBjb2RlcGFnZSwgQllURSB0ZXN0Y2hhciApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBjb2RlcGFnZSApOwogICAgcmV0dXJuIHRhYmxlICYmIGlzX2RiY3NfbGVhZGJ5dGUoIHRhYmxlLCB0ZXN0Y2hhciApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc0RCQ1NMZWFkQnl0ZSAgIChLRVJORUwzMi5AKQogKiAgICAgICAgICAgSXNEQkNTTGVhZEJ5dGUgICAoS0VSTkVMLjIwNykKICoKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgbGVhZCBieXRlLgogKgogKiBQQVJBTVMKICogIHRlc3RjaGFyIFtJXSBDaGFyYWN0ZXIgdG8gdGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB0ZXN0Y2hhciBpcyBhIGxlYWQgYnl0ZSBpbiB0aGUgQW5zaWkgY29kZSBwYWdlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNEQkNTTGVhZEJ5dGUoIEJZVEUgdGVzdGNoYXIgKQp7CiAgICBpZiAoIWFuc2lfY3B0YWJsZSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIGlzX2RiY3NfbGVhZGJ5dGUoIGFuc2lfY3B0YWJsZSwgdGVzdGNoYXIgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0Q1BJbmZvICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIG51bWJlcgogKiAgY3BpbmZvICAgW09dIERlc3RpbmF0aW9uIGZvciBjb2RlIHBhZ2UgaW5mb3JtYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY3BpbmZvIGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgY29kZXBhZ2UuCiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgY29kZXBhZ2UgaXMgaW52YWxpZCBvciBjcGluZm8gaXMgTlVMTC4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mbyggVUlOVCBjb2RlcGFnZSwgTFBDUElORk8gY3BpbmZvICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIGNvZGVwYWdlICk7CgogICAgaWYgKCF0YWJsZSkKICAgIHsKICAgICAgICBzd2l0Y2goY29kZXBhZ2UpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIENQX1VURjc6CiAgICAgICAgICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICAgICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMF0gPSAweDNmOwogICAgICAgICAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclsxXSA9IDA7CiAgICAgICAgICAgICAgICBjcGluZm8tPkxlYWRCeXRlWzBdID0gY3BpbmZvLT5MZWFkQnl0ZVsxXSA9IDA7CiAgICAgICAgICAgICAgICBjcGluZm8tPk1heENoYXJTaXplID0gKGNvZGVwYWdlID09IENQX1VURjcpID8gNSA6IDQ7CiAgICAgICAgICAgICAgICByZXR1cm4gVFJVRTsKICAgICAgICB9CgogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAodGFibGUtPmluZm8uZGVmX2NoYXIgJiAweGZmMDApCiAgICB7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclswXSA9IHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHhmZjAwOwogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMV0gPSB0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4MDBmZjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gdGFibGUtPmluZm8uZGVmX2NoYXIgJiAweGZmOwogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMV0gPSAwOwogICAgfQogICAgaWYgKChjcGluZm8tPk1heENoYXJTaXplID0gdGFibGUtPmluZm8uY2hhcl9zaXplKSA9PSAyKQogICAgICAgIG1lbWNweSggY3BpbmZvLT5MZWFkQnl0ZSwgdGFibGUtPmRiY3MubGVhZF9ieXRlcywgc2l6ZW9mKGNwaW5mby0+TGVhZEJ5dGUpICk7CiAgICBlbHNlCiAgICAgICAgY3BpbmZvLT5MZWFkQnl0ZVswXSA9IGNwaW5mby0+TGVhZEJ5dGVbMV0gPSAwOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mb0V4QSAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgZXh0ZW5kZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBjb2RlIHBhZ2UuCiAqCiAqIFBBUkFNUwogKiAgY29kZXBhZ2UgW0ldIENvZGUgcGFnZSBudW1iZXIKICogIGR3RmxhZ3MgIFtJXSBSZXNlcnZlZCwgbXVzdCB0byAwLgogKiAgY3BpbmZvICAgW09dIERlc3RpbmF0aW9uIGZvciBjb2RlIHBhZ2UgaW5mb3JtYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY3BpbmZvIGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgY29kZXBhZ2UuCiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgY29kZXBhZ2UgaXMgaW52YWxpZCBvciBjcGluZm8gaXMgTlVMTC4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mb0V4QSggVUlOVCBjb2RlcGFnZSwgRFdPUkQgZHdGbGFncywgTFBDUElORk9FWEEgY3BpbmZvICkKewogICAgQ1BJTkZPRVhXIGNwaW5mb1c7CgogICAgaWYgKCFHZXRDUEluZm9FeFcoIGNvZGVwYWdlLCBkd0ZsYWdzLCAmY3BpbmZvVyApKQogICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogdGhlIGxheW91dCBpcyB0aGUgc2FtZSBleGNlcHQgZm9yIENvZGVQYWdlTmFtZSAqLwogICAgbWVtY3B5KGNwaW5mbywgJmNwaW5mb1csIHNpemVvZihDUElORk9FWEEpKTsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBjcGluZm9XLkNvZGVQYWdlTmFtZSwgLTEsIGNwaW5mby0+Q29kZVBhZ2VOYW1lLCBzaXplb2YoY3BpbmZvLT5Db2RlUGFnZU5hbWUpLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mb0V4VyAgIChLRVJORUwzMi5AKQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgR2V0Q1BJbmZvRXhBLgogKi8KQk9PTCBXSU5BUEkgR2V0Q1BJbmZvRXhXKCBVSU5UIGNvZGVwYWdlLCBEV09SRCBkd0ZsYWdzLCBMUENQSU5GT0VYVyBjcGluZm8gKQp7CiAgICBpZiAoIUdldENQSW5mbyggY29kZXBhZ2UsIChMUENQSU5GTyljcGluZm8gKSkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIHN3aXRjaChjb2RlcGFnZSkKICAgIHsKICAgICAgICBjYXNlIENQX1VURjc6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgdXRmN1tdID0geydVJywnbicsJ2knLCdjJywnbycsJ2QnLCdlJywnICcsJygnLCdVJywnVCcsJ0YnLCctJywnNycsJyknLDB9OwoKICAgICAgICAgICAgY3BpbmZvLT5Db2RlUGFnZSA9IENQX1VURjc7CiAgICAgICAgICAgIGNwaW5mby0+VW5pY29kZURlZmF1bHRDaGFyID0gMHgzZjsKICAgICAgICAgICAgc3RyY3B5VyhjcGluZm8tPkNvZGVQYWdlTmFtZSwgdXRmNyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDUF9VVEY4OgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHV0ZjhbXSA9IHsnVScsJ24nLCdpJywnYycsJ28nLCdkJywnZScsJyAnLCcoJywnVScsJ1QnLCdGJywnLScsJzgnLCcpJywwfTsKCiAgICAgICAgICAgIGNwaW5mby0+Q29kZVBhZ2UgPSBDUF9VVEY4OwogICAgICAgICAgICBjcGluZm8tPlVuaWNvZGVEZWZhdWx0Q2hhciA9IDB4M2Y7CiAgICAgICAgICAgIHN0cmNweVcoY3BpbmZvLT5Db2RlUGFnZU5hbWUsIHV0ZjgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgewogICAgICAgICAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKTsKCiAgICAgICAgICAgIGNwaW5mby0+Q29kZVBhZ2UgPSB0YWJsZS0+aW5mby5jb2RlcGFnZTsKICAgICAgICAgICAgY3BpbmZvLT5Vbmljb2RlRGVmYXVsdENoYXIgPSB0YWJsZS0+aW5mby5kZWZfdW5pY29kZV9jaGFyOwogICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHRhYmxlLT5pbmZvLm5hbWUsIC0xLCBjcGluZm8tPkNvZGVQYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNwaW5mby0+Q29kZVBhZ2VOYW1lKS9zaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRW51bVN5c3RlbUNvZGVQYWdlc0EgICAoS0VSTkVMMzIuQCkKICoKICogQ2FsbCBhIHVzZXIgZGVmaW5lZCBmdW5jdGlvbiBmb3IgZXZlcnkgY29kZSBwYWdlIGluc3RhbGxlZCBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogICBscGZuQ29kZVBhZ2VFbnVtIFtJXSBVc2VyIENPREVQQUdFX0VOVU1QUk9DIHRvIGNhbGwgd2l0aCBlYWNoIGZvdW5kIGNvZGUgcGFnZQogKiAgIGZsYWdzICAgICAgICAgICAgW0ldIFJlc2VydmVkLCBzZXQgdG8gMC4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgSWYgYWxsIGNvZGUgcGFnZXMgaGF2ZSBiZWVuIGVudW1lcmF0ZWQsIG9yCiAqICBGQUxTRSBpZiBscGZuQ29kZVBhZ2VFbnVtIHJldHVybmVkIEZBTFNFIHRvIHN0b3AgdGhlIGVudW1lcmF0aW9uLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUNvZGVQYWdlc0EoIENPREVQQUdFX0VOVU1QUk9DQSBscGZuQ29kZVBhZ2VFbnVtLCBEV09SRCBmbGFncyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgY2hhciBidWZmZXJbMTBdOwogICAgaW50IGluZGV4ID0gMDsKCiAgICBmb3IgKDs7KQogICAgewogICAgICAgIGlmICghKHRhYmxlID0gd2luZV9jcF9lbnVtX3RhYmxlKCBpbmRleCsrICkpKSBicmVhazsKICAgICAgICBzcHJpbnRmKCBidWZmZXIsICIlZCIsIHRhYmxlLT5pbmZvLmNvZGVwYWdlICk7CiAgICAgICAgaWYgKCFscGZuQ29kZVBhZ2VFbnVtKCBidWZmZXIgKSkgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRW51bVN5c3RlbUNvZGVQYWdlc1cgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1TeXN0ZW1Db2RlUGFnZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUNvZGVQYWdlc1coIENPREVQQUdFX0VOVU1QUk9DVyBscGZuQ29kZVBhZ2VFbnVtLCBEV09SRCBmbGFncyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgV0NIQVIgYnVmZmVyWzEwXSwgKnA7CiAgICBpbnQgcGFnZSwgaW5kZXggPSAwOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgaWYgKCEodGFibGUgPSB3aW5lX2NwX2VudW1fdGFibGUoIGluZGV4KysgKSkpIGJyZWFrOwogICAgICAgIHAgPSBidWZmZXIgKyBzaXplb2YoYnVmZmVyKS9zaXplb2YoV0NIQVIpOwogICAgICAgICotLXAgPSAwOwogICAgICAgIHBhZ2UgPSB0YWJsZS0+aW5mby5jb2RlcGFnZTsKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgKi0tcCA9ICcwJyArIChwYWdlICUgMTApOwogICAgICAgICAgICBwYWdlIC89IDEwOwogICAgICAgIH0gd2hpbGUoIHBhZ2UgKTsKICAgICAgICBpZiAoIWxwZm5Db2RlUGFnZUVudW0oIHAgKSkgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhciAgIChLRVJORUwzMi5AKQogKgogKiBDb252ZXJ0IGEgbXVsdGlieXRlIGNoYXJhY3RlciBzdHJpbmcgaW50byBhIFVuaWNvZGUgc3RyaW5nLgogKgogKiBQQVJBTVMKICogICBwYWdlICAgW0ldIENvZGVwYWdlIGNoYXJhY3RlciBzZXQgdG8gY29udmVydCBmcm9tCiAqICAgZmxhZ3MgIFtJXSBDaGFyYWN0ZXIgbWFwcGluZyBmbGFncwogKiAgIHNyYyAgICBbSV0gU291cmNlIHN0cmluZyBidWZmZXIKICogICBzcmNsZW4gW0ldIExlbmd0aCBvZiBzcmMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgIGRzdCAgICBbT10gRGVzdGluYXRpb24gYnVmZmVyCiAqICAgZHN0bGVuIFtJXSBMZW5ndGggb2YgZHN0LCBvciAwIHRvIGNvbXB1dGUgdGhlIHJlcXVpcmVkIGxlbmd0aAogKgogKiBSRVRVUk5TCiAqICAgU3VjY2VzczogSWYgZHN0bGVuID4gMCwgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdyaXR0ZW4gdG8gZHN0LgogKiAgICAgICAgICAgIElmIGRzdGxlbiA9PSAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgbmVlZGVkIHRvIHBlcmZvcm0gdGhlCiAqICAgICAgICAgICAgY29udmVyc2lvbi4gSW4gYm90aCBjYXNlcyB0aGUgY291bnQgaW5jbHVkZXMgdGhlIHRlcm1pbmF0aW5nIE5VTC4KICogICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4gUG9zc2libGUgZXJyb3JzIGFyZQogKiAgICAgICAgICAgIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIsIGlmIG5vdCBlbm91Z2ggc3BhY2UgaXMgYXZhaWxhYmxlIGluIGRzdAogKiAgICAgICAgICAgIGFuZCBkc3RsZW4gIT0gMDsgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIsICBpZiBhbiBpbnZhbGlkIHBhcmFtZXRlcgogKiAgICAgICAgICAgIGlzIHBhc3NlZCwgYW5kIEVSUk9SX05PX1VOSUNPREVfVFJBTlNMQVRJT04gaWYgbm8gdHJhbnNsYXRpb24gaXMKICogICAgICAgICAgICBwb3NzaWJsZSBmb3Igc3JjLgogKi8KSU5UIFdJTkFQSSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBVSU5UIHBhZ2UsIERXT1JEIGZsYWdzLCBMUENTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBkc3QsIElOVCBkc3RsZW4gKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZTsKICAgIGludCByZXQ7CgogICAgaWYgKCFzcmMgfHwgKCFkc3QgJiYgZHN0bGVuKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlbihzcmMpICsgMTsKCiAgICBpZiAoZmxhZ3MgJiBNQl9VU0VHTFlQSENIQVJTKSBGSVhNRSgiTUJfVVNFR0xZUEhDSEFSUyBub3Qgc3VwcG9ydGVkXG4iKTsKCiAgICBzd2l0Y2gocGFnZSkKICAgIHsKICAgIGNhc2UgQ1BfU1lNQk9MOgogICAgICAgIGlmKCBmbGFncykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3BzeW1ib2xfbWJzdG93Y3MoIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBDUF9VVEY3OgogICAgICAgIEZJWE1FKCJVVEYtNyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICBjYXNlIENQX1VOSVhDUDoKICAgICAgICBpZiAodW5peF9jcHRhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0ID0gd2luZV9jcF9tYnN0b3djcyggdW5peF9jcHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXQgPSB3aW5lX3V0ZjhfbWJzdG93Y3MoIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKCEodGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIHBhZ2UgKSkpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2NwX21ic3Rvd2NzKCB0YWJsZSwgZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChyZXQgPCAwKQogICAgewogICAgICAgIHN3aXRjaChyZXQpCiAgICAgICAgewogICAgICAgIGNhc2UgLTE6IFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOyBicmVhazsKICAgICAgICBjYXNlIC0yOiBTZXRMYXN0RXJyb3IoIEVSUk9SX05PX1VOSUNPREVfVFJBTlNMQVRJT04gKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldCA9IDA7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBVbmljb2RlIGNoYXJhY3RlciBzdHJpbmcgaW50byBhIG11bHRpYnl0ZSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgIHBhZ2UgICAgW0ldIENvZGUgcGFnZSBjaGFyYWN0ZXIgc2V0IHRvIGNvbnZlcnQgdG8KICogICBmbGFncyAgIFtJXSBNYXBwaW5nIEZsYWdzIChNQl8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICAgc3JjICAgICBbSV0gU291cmNlIHN0cmluZyBidWZmZXIKICogICBzcmNsZW4gIFtJXSBMZW5ndGggb2Ygc3JjLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogICBkc3QgICAgIFtPXSBEZXN0aW5hdGlvbiBidWZmZXIKICogICBkc3RsZW4gIFtJXSBMZW5ndGggb2YgZHN0LCBvciAwIHRvIGNvbXB1dGUgdGhlIHJlcXVpcmVkIGxlbmd0aAogKiAgIGRlZmNoYXIgW0ldIERlZmF1bHQgY2hhcmFjdGVyIHRvIHVzZSBmb3IgY29udmVyc2lvbiBpZiBubyBleGFjdAogKgkJICAgIGNvbnZlcnNpb24gY2FuIGJlIG1hZGUKICogICB1c2VkICAgIFtPXSBTZXQgaWYgZGVmYXVsdCBjaGFyYWN0ZXIgd2FzIHVzZWQgaW4gdGhlIGNvbnZlcnNpb24KICoKICogUkVUVVJOUwogKiAgIFN1Y2Nlc3M6IElmIGRzdGxlbiA+IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB3cml0dGVuIHRvIGRzdC4KICogICAgICAgICAgICBJZiBkc3RsZW4gPT0gMCwgbnVtYmVyIG9mIGNoYXJhY3RlcnMgbmVlZGVkIHRvIHBlcmZvcm0gdGhlCiAqICAgICAgICAgICAgY29udmVyc2lvbi4gSW4gYm90aCBjYXNlcyB0aGUgY291bnQgaW5jbHVkZXMgdGhlIHRlcm1pbmF0aW5nIE5VTC4KICogICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4gUG9zc2libGUgZXJyb3JzIGFyZQogKiAgICAgICAgICAgIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIsIGlmIG5vdCBlbm91Z2ggc3BhY2UgaXMgYXZhaWxhYmxlIGluIGRzdAogKiAgICAgICAgICAgIGFuZCBkc3RsZW4gIT0gMCwgYW5kIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSLCBpZiBhbiBpbnZhbGlkCiAqICAgICAgICAgICAgcGFyYW1ldGVyIHdhcyBnaXZlbi4KICovCklOVCBXSU5BUEkgV2lkZUNoYXJUb011bHRpQnl0ZSggVUlOVCBwYWdlLCBEV09SRCBmbGFncywgTFBDV1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuLCBMUENTVFIgZGVmY2hhciwgQk9PTCAqdXNlZCApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgaW50IHJldCwgdXNlZF90bXA7CgogICAgaWYgKCFzcmMgfHwgKCFkc3QgJiYgZHN0bGVuKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKSArIDE7CgogICAgc3dpdGNoKHBhZ2UpCiAgICB7CiAgICBjYXNlIENQX1NZTUJPTDoKICAgICAgICBpZiggZmxhZ3MgfHwgZGVmY2hhciB8fCB1c2VkKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9jcHN5bWJvbF93Y3N0b21icyggc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENQX1VURjc6CiAgICAgICAgRklYTUUoIlVURi03IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQgKTsKICAgICAgICByZXR1cm4gMDsKICAgIGNhc2UgQ1BfVU5JWENQOgogICAgICAgIGlmICh1bml4X2NwdGFibGUpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSB3aW5lX2NwX3djc3RvbWJzKCB1bml4X2NwdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmNoYXIsIHVzZWQgPyAmdXNlZF90bXAgOiBOVUxMICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICBpZiAodXNlZCkgKnVzZWQgPSBGQUxTRTsgIC8qIGFsbCBjaGFycyBhcmUgdmFsaWQgZm9yIFVURi04ICovCiAgICAgICAgcmV0ID0gd2luZV91dGY4X3djc3RvbWJzKCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKCEodGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIHBhZ2UgKSkpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2NwX3djc3RvbWJzKCB0YWJsZSwgZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZjaGFyLCB1c2VkID8gJnVzZWRfdG1wIDogTlVMTCApOwogICAgICAgIGlmICh1c2VkKSAqdXNlZCA9IHVzZWRfdG1wOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChyZXQgPCAwKQogICAgewogICAgICAgIHN3aXRjaChyZXQpCiAgICAgICAgewogICAgICAgIGNhc2UgLTE6IFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOyBicmVhazsKICAgICAgICBjYXNlIC0yOiBTZXRMYXN0RXJyb3IoIEVSUk9SX05PX1VOSUNPREVfVFJBTlNMQVRJT04gKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldCA9IDA7CiAgICB9CiAgICBUUkFDRSgiY3AgJWQgJXMgLT4gJXNcbiIsIHBhZ2UsIGRlYnVnc3RyX3coc3JjKSwgZGVidWdzdHJfYShkc3QpKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBjdXJyZW50IHRocmVhZHMgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBMQ0lEIGN1cnJlbnRseSBhc3NvY2F0ZWQgd2l0aCB0aGUgY2FsbGluZyB0aHJlYWQuCiAqLwpMQ0lEIFdJTkFQSSBHZXRUaHJlYWRMb2NhbGUodm9pZCkKewogICAgTENJRCByZXQgPSBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZTsKICAgIGlmICghcmV0KSBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZSA9IHJldCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICoKICogU2V0IHRoZSBjdXJyZW50IHRocmVhZHMgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIGxjaWQgW0ldIExDSUQgb2YgdGhlIGxvY2FsZSB0byBzZXQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gVGhlIHRocmVhZHMgbG9jYWxlIGlzIHNldCB0byBsY2lkLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgU2V0VGhyZWFkTG9jYWxlKCBMQ0lEIGxjaWQgKQp7CiAgICBUUkFDRSgiKDB4JTA0bFgpXG4iLCBsY2lkKTsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgaWYgKGxjaWQgIT0gR2V0VGhyZWFkTG9jYWxlKCkpCiAgICB7CiAgICAgICAgaWYgKCFJc1ZhbGlkTG9jYWxlKGxjaWQsIExDSURfU1VQUE9SVEVEKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CgogICAgICAgIE50Q3VycmVudFRlYigpLT5DdXJyZW50TG9jYWxlID0gbGNpZDsKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+Y29kZV9wYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDb252ZXJ0RGVmYXVsdExvY2FsZSAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIGRlZmF1bHQgbG9jYWxlIGlkZW50aWZpZXIgaW50byBhIHJlYWwgaWRlbnRpZmllci4KICoKICogUEFSQU1TCiAqICBsY2lkIFtJXSBMQ0lEIGlkZW50aWZpZXIgb2YgdGhlIGxvY2FsZSB0byBjb252ZXJ0CiAqCiAqIFJFVFVSTlMKICogIGxjaWQgdW5jaGFuZ2VkLCBpZiBub3QgYSBkZWZhdWx0IGxvY2FsZSBvciBpdHMgc3VibGFuZ3VhZ2UgaXMKICogICBub3QgU1VCTEFOR19ORVVUUkFMLgogKiAgR2V0U3lzdGVtRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfU1lTVEVNX0RFRkFVTFQuCiAqICBHZXRVc2VyRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfVVNFUl9ERUZBVUxUIG9yIExPQ0FMRV9ORVVUUkFMLgogKiAgT3RoZXJ3aXNlLCBsY2lkIHdpdGggc3VibGFuZ3VhZ2UgY2hhbmdlZCB0byBTVUJMQU5HX0RFRkFVTFQuCiAqLwpMQ0lEIFdJTkFQSSBDb252ZXJ0RGVmYXVsdExvY2FsZSggTENJRCBsY2lkICkKewogICAgTEFOR0lEIGxhbmdpZDsKCiAgICBzd2l0Y2ggKGxjaWQpCiAgICB7CiAgICBjYXNlIExPQ0FMRV9TWVNURU1fREVGQVVMVDoKICAgICAgICBsY2lkID0gR2V0U3lzdGVtRGVmYXVsdExDSUQoKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgTE9DQUxFX1VTRVJfREVGQVVMVDoKICAgIGNhc2UgTE9DQUxFX05FVVRSQUw6CiAgICAgICAgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICAvKiBSZXBsYWNlIFNVQkxBTkdfTkVVVFJBTCB3aXRoIFNVQkxBTkdfREVGQVVMVCAqLwogICAgICAgIGxhbmdpZCA9IExBTkdJREZST01MQ0lEKGxjaWQpOwogICAgICAgIGlmIChTVUJMQU5HSUQobGFuZ2lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgewogICAgICAgICAgbGFuZ2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdpZCksIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgICBsY2lkID0gTUFLRUxDSUQobGFuZ2lkLCBTT1JUSURGUk9NTENJRChsY2lkKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc1ZhbGlkTG9jYWxlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGxvY2FsZSBpcyB2YWxpZC4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBvZiB0aGUgbG9jYWxlIHRvIGNoZWNrCiAqICBmbGFncyBbSV0gTENJRF9TVVBQT1JURUQgPSBWYWxpZCwgTENJRF9JTlNUQUxMRUQgPSBWYWxpZCBhbmQgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOCiAqICBUUlVFLCAgaWYgbGNpZCBpcyB2YWxpZCwKICogIEZBTFNFLCBvdGhlcndpc2UuCiAqCiAqIE5PVEVTCiAqICBXaW5lIGRvZXMgbm90IGN1cnJlbnRseSBtYWtlIHRoZSBkaXN0aW5jdGlvbiBiZXR3ZWVuIHN1cHBvcnRlZCBhbmQgaW5zdGFsbGVkLiBBbGwKICogIGxhbmd1YWdlcyBzdXBwb3J0ZWQgYXJlIGluc3RhbGxlZCBieSBkZWZhdWx0LgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZExvY2FsZSggTENJRCBsY2lkLCBEV09SRCBmbGFncyApCnsKICAgIC8qIGNoZWNrIGlmIGxhbmd1YWdlIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIGtlcm5lbDMyIHJlc291cmNlcyAqLwogICAgcmV0dXJuIEZpbmRSZXNvdXJjZUV4Vygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsIExBTkdJREZST01MQ0lEKGxjaWQpKSAhPSAwOwp9CgoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgZW51bV9sYW5nX3Byb2NfYSggSE1PRFVMRSBoTW9kdWxlLCBMUENTVFIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIG5hbWUsIFdPUkQgTGFuZ0lELCBMT05HIGxQYXJhbSApCnsKICAgIExPQ0FMRV9FTlVNUFJPQ0EgbHBmbkxvY2FsZUVudW0gPSAoTE9DQUxFX0VOVU1QUk9DQSlsUGFyYW07CiAgICBjaGFyIGJ1ZlsyMF07CgogICAgc3ByaW50ZihidWYsICIlMDh4IiwgKFVJTlQpTGFuZ0lEKTsKICAgIHJldHVybiBscGZuTG9jYWxlRW51bSggYnVmICk7Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fbGFuZ19wcm9jX3coIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIG5hbWUsIFdPUkQgTGFuZ0lELCBMT05HIGxQYXJhbSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBmb3JtYXRXW10gPSB7JyUnLCcwJywnOCcsJ3gnLDB9OwogICAgTE9DQUxFX0VOVU1QUk9DVyBscGZuTG9jYWxlRW51bSA9IChMT0NBTEVfRU5VTVBST0NXKWxQYXJhbTsKICAgIFdDSEFSIGJ1ZlsyMF07CiAgICBzcHJpbnRmVyggYnVmLCBmb3JtYXRXLCAoVUlOVClMYW5nSUQgKTsKICAgIHJldHVybiBscGZuTG9jYWxlRW51bSggYnVmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1Mb2NhbGVzQSAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZWFjaCBsb2NhbGUgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgbHBmbkxvY2FsZUVudW0gW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbG9jYWxlCiAqICBkd0ZsYWdzICAgICAgICBbSV0gTE9DQUxFX1NVUFBPUlRFRD1BbGwgc3VwcG9ydGVkLCBMT0NBTEVfSU5TVEFMTEVEPUluc3RhbGxlZCBvbmx5CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtTG9jYWxlc0EoIExPQ0FMRV9FTlVNUFJPQ0EgbHBmbkxvY2FsZUVudW0sIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBUUkFDRSgiKCVwLCUwOGx4KVxuIiwgbHBmbkxvY2FsZUVudW0sIGR3RmxhZ3MpOwogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzQSgga2VybmVsMzJfaGFuZGxlLCAoTFBTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQ1NUUilMT0NBTEVfSUxBTkdVQUdFLCBlbnVtX2xhbmdfcHJvY19hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExPTkcpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTG9jYWxlc1cgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxvY2FsZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxvY2FsZXNXKCBMT0NBTEVfRU5VTVBST0NXIGxwZm5Mb2NhbGVFbnVtLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIiglcCwlMDhseClcbiIsIGxwZm5Mb2NhbGVFbnVtLCBkd0ZsYWdzKTsKICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc1coIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLCBlbnVtX2xhbmdfcHJvY193LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExPTkcpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFZlckxhbmd1YWdlTmFtZUEgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoKICogUEFSQU1TCiAqICB3TGFuZyAgW0ldIExBTkdJRCBvZiB0aGUgbGFuZ3VhZ2UKICogIHN6TGFuZyBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBsYW5ndWFnZSBuYW1lCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBzaXplIG9mIHRoZSBsYW5ndWFnZSBuYW1lLiBJZiBzekxhbmcgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgbmFtZS4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKgogKi8KRFdPUkQgV0lOQVBJIFZlckxhbmd1YWdlTmFtZUEoIFVJTlQgd0xhbmcsIExQU1RSIHN6TGFuZywgVUlOVCBuU2l6ZSApCnsKICAgIHJldHVybiBHZXRMb2NhbGVJbmZvQSggTUFLRUxDSUQod0xhbmcsIFNPUlRfREVGQVVMVCksIExPQ0FMRV9TRU5HTEFOR1VBR0UsIHN6TGFuZywgblNpemUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgVmVyTGFuZ3VhZ2VOYW1lVyAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBWZXJMYW5ndWFnZU5hbWVBLgogKi8KRFdPUkQgV0lOQVBJIFZlckxhbmd1YWdlTmFtZVcoIFVJTlQgd0xhbmcsIExQV1NUUiBzekxhbmcsIFVJTlQgblNpemUgKQp7CiAgICByZXR1cm4gR2V0TG9jYWxlSW5mb1coIE1BS0VMQ0lEKHdMYW5nLCBTT1JUX0RFRkFVTFQpLCBMT0NBTEVfU0VOR0xBTkdVQUdFLCBzekxhbmcsIG5TaXplICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldFN0cmluZ1R5cGVBLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZVcoIERXT1JEIHR5cGUsIExQQ1dTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIGlmIChjb3VudCA9PSAtMSkgY291bnQgPSBzdHJsZW5XKHNyYykgKyAxOwogICAgc3dpdGNoKHR5cGUpCiAgICB7CiAgICBjYXNlIENUX0NUWVBFMToKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgJiAweGZmZjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1RfQ1RZUEUyOgogICAgICAgIHdoaWxlIChjb3VudC0tKSAqY2hhcnR5cGUrKyA9IGdldF9jaGFyX3R5cGVXKCAqc3JjKysgKSA+PiAxMjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1RfQ1RZUEUzOgogICAgewogICAgICAgIFdBUk4oIkNUX0NUWVBFMzogc2VtaS1zdHViLlxuIik7CiAgICAgICAgd2hpbGUgKGNvdW50LS0pCiAgICAgICAgewogICAgICAgICAgICBpbnQgYyA9ICpzcmM7CiAgICAgICAgICAgIFdPUkQgdHlwZTEsIHR5cGUzID0gMDsgLyogQzNfTk9UQVBQTElDQUJMRSAqLwoKICAgICAgICAgICAgdHlwZTEgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgJiAweGZmZjsKICAgICAgICAgICAgLyogdHJ5IHRvIGNvbnN0cnVjdCB0eXBlMyBmcm9tIHR5cGUxICovCiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfU1BBQ0UpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYodHlwZTEgJiBDMV9BTFBIQSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHgzMEEwKSYmKGM8PTB4MzBGRikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4MzA0MCkmJihjPD0weDMwOUYpKSB0eXBlMyB8PSBDM19ISVJBR0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDRFMDApJiYoYzw9MHg5RkFGKSkgdHlwZTMgfD0gQzNfSURFT0dSQVBIOwogICAgICAgICAgICBpZiAoKGM+PTB4MDYwMCkmJihjPD0weDA2RkYpKSB0eXBlMyB8PSBDM19LQVNISURBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzAwMCkmJihjPD0weDMwM0YpKSB0eXBlMyB8PSBDM19TWU1CT0w7CgogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGNjApKSB0eXBlMyB8PSBDM19GVUxMV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjAwKSYmKGM8PTB4RkYyMCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGM0IpJiYoYzw9MHhGRjQwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY1QikmJihjPD0weEZGNjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjIxKSYmKGM8PTB4RkYzQSkpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY0MSkmJihjPD0weEZGNUEpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFMCkmJihjPD0weEZGRTYpKSB0eXBlMyB8PSBDM19TWU1CT0w7CgogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGREMpKSB0eXBlMyB8PSBDM19IQUxGV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjYxKSYmKGM8PTB4RkY2NCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNjUpJiYoYzw9MHhGRjlGKSkgdHlwZTMgfD0gQzNfS0FUQUtBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19IQUxGV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkU4KSYmKGM8PTB4RkZFRSkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgKmNoYXJ0eXBlKysgPSB0eXBlMzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBkZWZhdWx0OgogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFN0cmluZ1R5cGVFeFcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRTdHJpbmdUeXBlRXhBLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4VyggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1dTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIC8qIGxvY2FsZSBpcyBpZ25vcmVkIGZvciBVbmljb2RlICovCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoIHR5cGUsIHNyYywgY291bnQsIGNoYXJ0eXBlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlQSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2hhcmFjdGVycyBtYWtpbmcgdXAgYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbG9jYWxlICAgW0ldIExvY2FsZSBJZCBmb3IgdGhlIHN0cmluZwogKiAgdHlwZSAgICAgW0ldIENUX0NUWVBFMSA9IGNsYXNzaWZpY2F0aW9uLCBDVF9DVFlQRTIgPSBkaXJlY3Rpb25hbGl0eSwgQ1RfQ1RZUEUzID0gdHlwb2dyYXBoaWMgaW5mbwogKiAgc3JjICAgICAgW0ldIFN0cmluZyB0byBhbmFseXNlCiAqICBjb3VudCAgICBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBjaGFydHlwZSBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjYWxjdWxhdGVkIGNoYXJhY3RlcmlzdGljcwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjaGFydHlwZSBpcyBmaWxsZWQgd2l0aCB0aGUgcmVxdWVzdGVkIGNoYXJhY3RlcmlzdGljcyBvZiBlYWNoIGNoYXIKICogICAgICAgICAgIGluIHNyYy4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVBKCBMQ0lEIGxvY2FsZSwgRFdPUkQgdHlwZSwgTFBDU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBVSU5UIGNwOwogICAgSU5UIGNvdW50VzsKICAgIExQV1NUUiBzcmNXOwogICAgQk9PTCByZXQgPSBGQUxTRTsKCiAgICBpZihjb3VudCA9PSAtMSkgY291bnQgPSBzdHJsZW4oc3JjKSArIDE7CgogICAgaWYgKCEoY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbG9jYWxlICkpKQogICAgewogICAgICAgIEZJWE1FKCJGb3IgbG9jYWxlICUwNGx4IHVzaW5nIGN1cnJlbnQgQU5TSSBjb2RlIHBhZ2VcbiIsIGxvY2FsZSk7CiAgICAgICAgY3AgPSBHZXRBQ1AoKTsKICAgIH0KCiAgICBjb3VudFcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBOVUxMLCAwKTsKICAgIGlmKChzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50VyAqIHNpemVvZihXQ0hBUikpKSkKICAgIHsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBzcmNXLCBjb3VudFcpOwogICAgLyoKICAgICAqIE5PVEU6IHRoZSB0YXJnZXQgYnVmZmVyIGhhcyAxIHdvcmQgZm9yIGVhY2ggQ0hBUkFDVEVSIGluIHRoZSBzb3VyY2UKICAgICAqIHN0cmluZywgd2l0aCBtdWx0aWJ5dGUgY2hhcmFjdGVycyB0aGVyZSBtYXliZSBiZSBtb3JlIGJ5dGVzIGluIGNvdW50CiAgICAgKiB0aGFuIGNoYXJhY3RlciBzcGFjZSBpbiB0aGUgYnVmZmVyIQogICAgICovCiAgICAgICAgcmV0ID0gR2V0U3RyaW5nVHlwZVcodHlwZSwgc3JjVywgY291bnRXLCBjaGFydHlwZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhBICAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBjaGFyYWN0ZXJzIG1ha2luZyB1cCBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBsb2NhbGUgICBbSV0gTG9jYWxlIElkIGZvciB0aGUgc3RyaW5nCiAqICB0eXBlICAgICBbSV0gQ1RfQ1RZUEUxID0gY2xhc3NpZmljYXRpb24sIENUX0NUWVBFMiA9IGRpcmVjdGlvbmFsaXR5LCBDVF9DVFlQRTMgPSB0eXBvZ3JhcGhpYyBpbmZvCiAqICBzcmMgICAgICBbSV0gU3RyaW5nIHRvIGFuYWx5c2UKICogIGNvdW50ICAgIFtJXSBMZW5ndGggb2Ygc3JjIGluIGNoYXJzLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogIGNoYXJ0eXBlIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGNhbGN1bGF0ZWQgY2hhcmFjdGVyaXN0aWNzCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNoYXJ0eXBlIGlzIGZpbGxlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgY2hhcmFjdGVyaXN0aWNzIG9mIGVhY2ggY2hhcgogKiAgICAgICAgICAgaW4gc3JjLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4QSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVBKGxvY2FsZSwgdHlwZSwgc3JjLCBjb3VudCwgY2hhcnR5cGUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDTWFwU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIExDTWFwU3RyaW5nQS4KICovCklOVCBXSU5BUEkgTENNYXBTdHJpbmdXKExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBMUFdTVFIgZHN0X3B0cjsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBtdXR1YWxseSBleGNsdXNpdmUgZmxhZ3MgKi8KICAgIGlmICgoZmxhZ3MgJiAoTENNQVBfTE9XRVJDQVNFIHwgTENNQVBfVVBQRVJDQVNFKSkgPT0gKExDTUFQX0xPV0VSQ0FTRSB8IExDTUFQX1VQUEVSQ0FTRSkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfSElSQUdBTkEgfCBMQ01BUF9LQVRBS0FOQSkpID09IChMQ01BUF9ISVJBR0FOQSB8IExDTUFQX0tBVEFLQU5BKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9IQUxGV0lEVEggfCBMQ01BUF9GVUxMV0lEVEgpKSA9PSAoTENNQVBfSEFMRldJRFRIIHwgTENNQVBfRlVMTFdJRFRIKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9UUkFESVRJT05BTF9DSElORVNFIHwgTENNQVBfU0lNUExJRklFRF9DSElORVNFKSkgPT0gKExDTUFQX1RSQURJVElPTkFMX0NISU5FU0UgfCBMQ01BUF9TSU1QTElGSUVEX0NISU5FU0UpKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIWRzdGxlbikgZHN0ID0gTlVMTDsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgaWYgKGZsYWdzICYgTENNQVBfU09SVEtFWSkKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuVyhzcmMpOwoKICAgICAgICBUUkFDRSgiKDB4JTA0bHgsMHglMDhseCwlcywlZCwlcCwlZClcbiIsCiAgICAgICAgICAgICAgbGNpZCwgZmxhZ3MsIGRlYnVnc3RyX3duKHNyYywgc3JjbGVuKSwgc3JjbGVuLCBkc3QsIGRzdGxlbik7CgogICAgICAgIHJldHVybiB3aW5lX2dldF9zb3J0a2V5KGZsYWdzLCBzcmMsIHNyY2xlbiwgKGNoYXIgKilkc3QsIGRzdGxlbik7CiAgICB9CgogICAgLyogU09SVF9TVFJJTkdTT1JUIG11c3QgYmUgdXNlZCBleGNsdXNpdmVseSB3aXRoIExDTUFQX1NPUlRLRVkgKi8KICAgIGlmIChmbGFncyAmIFNPUlRfU1RSSU5HU09SVCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKSArIDE7CgogICAgVFJBQ0UoIigweCUwNGx4LDB4JTA4bHgsJXMsJWQsJXAsJWQpXG4iLAogICAgICAgICAgbGNpZCwgZmxhZ3MsIGRlYnVnc3RyX3duKHNyYywgc3JjbGVuKSwgc3JjbGVuLCBkc3QsIGRzdGxlbik7CgogICAgaWYgKCFkc3QpIC8qIHJldHVybiByZXF1aXJlZCBzdHJpbmcgbGVuZ3RoICovCiAgICB7CiAgICAgICAgSU5UIGxlbjsKCiAgICAgICAgZm9yIChsZW4gPSAwOyBzcmNsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIC8qIHRlc3RzIHNob3cgdGhhdCB3aW4yayBqdXN0IGlnbm9yZXMgTk9STV9JR05PUkVOT05TUEFDRSwKICAgICAgICAgICAgICogYW5kIHNraXBzIHdoaXRlIHNwYWNlIGFuZCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZvcgogICAgICAgICAgICAgKiBOT1JNX0lHTk9SRVNZTUJPTFMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgbGVuKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsZW47CiAgICB9CgogICAgaWYgKGZsYWdzICYgTENNQVBfVVBQRVJDQVNFKQogICAgewogICAgICAgIGZvciAoZHN0X3B0ciA9IGRzdDsgc3JjbGVuICYmIGRzdGxlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICpkc3RfcHRyKysgPSB0b3VwcGVyVyh3Y2gpOwogICAgICAgICAgICBkc3RsZW4tLTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChmbGFncyAmIExDTUFQX0xPV0VSQ0FTRSkKICAgIHsKICAgICAgICBmb3IgKGRzdF9wdHIgPSBkc3Q7IHNyY2xlbiAmJiBkc3RsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAqZHN0X3B0cisrID0gdG9sb3dlclcod2NoKTsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzcmMgPT0gZHN0KQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgZm9yIChkc3RfcHRyID0gZHN0OyBzcmNsZW4gJiYgZHN0bGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgKmRzdF9wdHIrKyA9IHdjaDsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzcmNsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldHVybiBkc3RfcHRyIC0gZHN0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTENNYXBTdHJpbmdBICAgIChLRVJORUwzMi5AKQogKgogKiBNYXAgY2hhcmFjdGVycyBpbiBhIGxvY2FsZSBzZW5zaXRpdmUgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGxjaWQgICBbSV0gTENJRCBmb3IgdGhlIGNvbnZlcnNpb24uCiAqICBmbGFncyAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBtYXBwaW5nIChMQ01BUF8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICBzcmMgICAgW0ldIFN0cmluZyB0byBtYXAKICogIHNyY2xlbiBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBkc3QgICAgW09dIERlc3RpbmF0aW9uIGZvciBtYXBwZWQgc3RyaW5nCiAqICBkc3RsZW4gW0ldIExlbmd0aCBvZiBkc3QgaW4gY2hhcmFjdGVycwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSBtYXBwZWQgc3RyaW5nIGluIGRzdCwgaW5jbHVkaW5nIHRoZSBOVUwgdGVybWluYXRvci4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KSU5UIFdJTkFQSSBMQ01hcFN0cmluZ0EoTENJRCBsY2lkLCBEV09SRCBmbGFncywgTFBDU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBXQ0hBUiAqYnVmVyA9IE50Q3VycmVudFRlYigpLT5TdGF0aWNVbmljb2RlQnVmZmVyOwogICAgTFBXU1RSIHNyY1csIGRzdFc7CiAgICBJTlQgcmV0ID0gMCwgc3JjbGVuVywgZHN0bGVuVzsKICAgIFVJTlQgbG9jYWxlX2NwID0gQ1BfQUNQOwoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICghKGZsYWdzICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbGNpZCApOwoKICAgIHNyY2xlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3JjLCBzcmNsZW4sIGJ1ZlcsIDI2MCk7CiAgICBpZiAoc3JjbGVuVykKICAgICAgICBzcmNXID0gYnVmVzsKICAgIGVsc2UKICAgIHsKICAgICAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBOVUxMLCAwKTsKICAgICAgICBzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2xlblcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXNyY1cpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBzcmNXLCBzcmNsZW5XKTsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBMQ01BUF9TT1JUS0VZKQogICAgewogICAgICAgIGlmIChzcmMgPT0gZHN0KQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9nZXRfc29ydGtleShmbGFncywgc3JjVywgc3JjbGVuVywgZHN0LCBkc3RsZW4pOwogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgfQoKICAgIGlmIChmbGFncyAmIFNPUlRfU1RSSU5HU09SVCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICB9CgogICAgZHN0bGVuVyA9IExDTWFwU3RyaW5nVyhsY2lkLCBmbGFncywgc3JjVywgc3JjbGVuVywgTlVMTCwgMCk7CiAgICBpZiAoIWRzdGxlblcpCiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CgogICAgZHN0VyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3RsZW5XICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoIWRzdFcpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgIH0KCiAgICBMQ01hcFN0cmluZ1cobGNpZCwgZmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdFcsIGRzdGxlblcpOwogICAgcmV0ID0gV2lkZUNoYXJUb011bHRpQnl0ZShsb2NhbGVfY3AsIDAsIGRzdFcsIGRzdGxlblcsIGRzdCwgZHN0bGVuLCBOVUxMLCBOVUxMKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdFcpOwoKbWFwX3N0cmluZ19leGl0OgogICAgaWYgKHNyY1cgIT0gYnVmVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRm9sZFN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIE1hcCBjaGFyYWN0ZXJzIGluIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIGNoYXJzIHRvIG1hcCAoTUFQXyBjb25zdGFudHMgZnJvbSAid2lubmxzLmgiKQogKiAgc3JjICAgICBbSV0gU3RyaW5nIHRvIG1hcAogKiAgc3JjbGVuICBbSV0gTGVuZ3RoIG9mIHNyYywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBkc3QgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgbWFwcGVkIHN0cmluZwogKiAgZHN0bGVuICBbSV0gTGVuZ3RoIG9mIGRzdCwgb3IgMCB0byBmaW5kIHRoZSByZXF1aXJlZCBsZW5ndGggZm9yIHRoZSBtYXBwZWQgc3RyaW5nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB3cml0dGVuIHRvIGRzdCwgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBOVUwuIElmCiAqICAgICAgICAgICBkc3RsZW4gaXMgMCwgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBzYW1lLCBidXQgbm90aGluZyBpcyB3cml0dGVuIHRvIGRzdCwKICogICAgICAgICAgIGFuZCBkc3QgbWF5IGJlIE5VTEwuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgRm9sZFN0cmluZ0EoRFdPUkQgZHdGbGFncywgTFBDU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBkc3QsIElOVCBkc3RsZW4pCnsKICAgIElOVCByZXQgPSAwLCBzcmNsZW5XID0gMDsKICAgIFdDSEFSICpzcmNXID0gTlVMTCwgKmRzdFcgPSBOVUxMOwoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCB8fCAoZHN0bGVuICYmICFkc3QpIHx8IHNyYyA9PSBkc3QpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIGR3RmxhZ3MgJiBNQVBfQ09NUE9TSVRFID8gTUJfQ09NUE9TSVRFIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYywgc3JjbGVuLCBOVUxMLCAwKTsKICAgIHNyY1cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjbGVuVyAqIHNpemVvZihXQ0hBUikpOwoKICAgIGlmICghc3JjVykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgIGdvdG8gRm9sZFN0cmluZ0FfZXhpdDsKICAgIH0KCiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgZHdGbGFncyAmIE1BUF9DT01QT1NJVEUgPyBNQl9DT01QT1NJVEUgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICBzcmMsIHNyY2xlbiwgc3JjVywgc3JjbGVuVyk7CgogICAgZHdGbGFncyA9IChkd0ZsYWdzICYgfk1BUF9QUkVDT01QT1NFRCkgfCBNQVBfRk9MRENaT05FOwoKICAgIHJldCA9IEZvbGRTdHJpbmdXKGR3RmxhZ3MsIHNyY1csIHNyY2xlblcsIE5VTEwsIDApOwogICAgaWYgKHJldCAmJiBkc3RsZW4pCiAgICB7CiAgICAgICAgZHN0VyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCByZXQgKiBzaXplb2YoV0NIQVIpKTsKCiAgICAgICAgaWYgKCFkc3RXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgZ290byBGb2xkU3RyaW5nQV9leGl0OwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gRm9sZFN0cmluZ1coZHdGbGFncywgc3JjVywgc3JjbGVuVywgZHN0VywgcmV0KTsKICAgICAgICBpZiAoIVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBkc3RXLCByZXQsIGRzdCwgZHN0bGVuLCBOVUxMLCBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0Vyk7CgpGb2xkU3RyaW5nQV9leGl0OgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRm9sZFN0cmluZ1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBGb2xkU3RyaW5nQS4KICovCklOVCBXSU5BUEkgRm9sZFN0cmluZ1coRFdPUkQgZHdGbGFncywgTFBDV1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgaW50IHJldDsKCiAgICBzd2l0Y2ggKGR3RmxhZ3MgJiAoTUFQX0NPTVBPU0lURXxNQVBfUFJFQ09NUE9TRUR8TUFQX0VYUEFORF9MSUdBVFVSRVMpKQogICAgewogICAgY2FzZSAwOgogICAgICAgIGlmIChkd0ZsYWdzKQogICAgICAgICAgYnJlYWs7CiAgICAgICAgLyogRmFsbCB0aHJvdWdoIGZvciBkd0ZsYWdzID09IDAgKi8KICAgIGNhc2UgTUFQX1BSRUNPTVBPU0VEfE1BUF9DT01QT1NJVEU6CiAgICBjYXNlIE1BUF9QUkVDT01QT1NFRHxNQVBfRVhQQU5EX0xJR0FUVVJFUzoKICAgIGNhc2UgTUFQX0NPTVBPU0lURXxNQVBfRVhQQU5EX0xJR0FUVVJFUzoKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwIHx8IChkc3RsZW4gJiYgIWRzdCkgfHwgc3JjID09IGRzdCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldCA9IHdpbmVfZm9sZF9zdHJpbmcoZHdGbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuKTsKICAgIGlmICghcmV0KQogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIENvbXBhcmVTdHJpbmdXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgQ29tcGFyZVN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIENvbXBhcmVTdHJpbmdXKExDSUQgbGNpZCwgRFdPUkQgc3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBzdHIxLCBJTlQgbGVuMSwgTFBDV1NUUiBzdHIyLCBJTlQgbGVuMikKewogICAgSU5UIHJldDsKCiAgICBpZiAoIXN0cjEgfHwgIXN0cjIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiggc3R5bGUgJiB+KE5PUk1fSUdOT1JFQ0FTRXxOT1JNX0lHTk9SRU5PTlNQQUNFfE5PUk1fSUdOT1JFU1lNQk9MU3wKICAgICAgICBTT1JUX1NUUklOR1NPUlR8Tk9STV9JR05PUkVLQU5BVFlQRXxOT1JNX0lHTk9SRVdJRFRIfExPQ0FMRV9VU0VfQ1BfQUNQfDB4MTAwMDAwMDApICkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHN0eWxlICYgMHgxMDAwMDAwMCkKICAgICAgICBGSVhNRSgiSWdub3JpbmcgdW5rbm93biBzdHlsZSAweDEwMDAwMDAwXG4iKTsKCiAgICBpZiAobGVuMSA8IDApIGxlbjEgPSBzdHJsZW5XKHN0cjEpOwogICAgaWYgKGxlbjIgPCAwKSBsZW4yID0gc3RybGVuVyhzdHIyKTsKCiAgICByZXQgPSB3aW5lX2NvbXBhcmVfc3RyaW5nKHN0eWxlLCBzdHIxLCBsZW4xLCBzdHIyLCBsZW4yKTsKCiAgICBpZiAocmV0KSAvKiBuZWVkIHRvIHRyYW5zbGF0ZSByZXN1bHQgKi8KICAgICAgICByZXR1cm4gKHJldCA8IDApID8gQ1NUUl9MRVNTX1RIQU4gOiBDU1RSX0dSRUFURVJfVEhBTjsKICAgIHJldHVybiBDU1RSX0VRVUFMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBDb21wYXJlU3RyaW5nQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gbG9jYWxlIHNlbnNpdGl2ZSBzdHJpbmdzLgogKgogKiBQQVJBTVMKICogIGxjaWQgIFtJXSBMQ0lEIGZvciB0aGUgY29tcGFyaXNvbgogKiAgc3R5bGUgW0ldIEZsYWdzIGZvciB0aGUgY29tcGFyaXNvbiAoTk9STV8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICBzdHIxICBbSV0gRmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUKICogIGxlbjEgIFtJXSBMZW5ndGggb2Ygc3RyMSwgb3IgLTEgaWYgc3RyMSBpcyBOVUwgdGVybWluYXRlZAogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKiAgbGVuMiAgW0ldIExlbmd0aCBvZiBzdHIyLCBvciAtMSBpZiBzdHIyIGlzIE5VTCB0ZXJtaW5hdGVkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IENTVFJfTEVTU19USEFOLCBDU1RSX0VRVUFMIG9yIENTVFJfR1JFQVRFUl9USEFOIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KSU5UIFdJTkFQSSBDb21wYXJlU3RyaW5nQShMQ0lEIGxjaWQsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBzdHIxLCBJTlQgbGVuMSwgTFBDU1RSIHN0cjIsIElOVCBsZW4yKQp7CiAgICBXQ0hBUiAqYnVmMVcgPSBOdEN1cnJlbnRUZWIoKS0+U3RhdGljVW5pY29kZUJ1ZmZlcjsKICAgIFdDSEFSICpidWYyVyA9IGJ1ZjFXICsgMTMwOwogICAgTFBXU1RSIHN0cjFXLCBzdHIyVzsKICAgIElOVCBsZW4xVywgbGVuMlcsIHJldDsKICAgIFVJTlQgbG9jYWxlX2NwID0gQ1BfQUNQOwoKICAgIGlmICghc3RyMSB8fCAhc3RyMikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKGxlbjEgPCAwKSBsZW4xID0gc3RybGVuKHN0cjEpOwogICAgaWYgKGxlbjIgPCAwKSBsZW4yID0gc3RybGVuKHN0cjIpOwoKICAgIGlmICghKHN0eWxlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbGNpZCApOwoKICAgIGxlbjFXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjEsIGxlbjEsIGJ1ZjFXLCAxMzApOwogICAgaWYgKGxlbjFXKQogICAgICAgIHN0cjFXID0gYnVmMVc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGVuMVcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMSwgbGVuMSwgTlVMTCwgMCk7CiAgICAgICAgc3RyMVcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuMVcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXN0cjFXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIxLCBsZW4xLCBzdHIxVywgbGVuMVcpOwogICAgfQogICAgbGVuMlcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgYnVmMlcsIDEzMCk7CiAgICBpZiAobGVuMlcpCiAgICAgICAgc3RyMlcgPSBidWYyVzsKICAgIGVsc2UKICAgIHsKICAgICAgICBsZW4yVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIyLCBsZW4yLCBOVUxMLCAwKTsKICAgICAgICBzdHIyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4yVyAqIHNpemVvZihXQ0hBUikpOwogICAgICAgIGlmICghc3RyMlcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc3RyMVcgIT0gYnVmMVcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cjFXKTsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIyLCBsZW4yLCBzdHIyVywgbGVuMlcpOwogICAgfQoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKGxjaWQsIHN0eWxlLCBzdHIxVywgbGVuMVcsIHN0cjJXLCBsZW4yVyk7CgogICAgaWYgKHN0cjFXICE9IGJ1ZjFXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIxVyk7CiAgICBpZiAoc3RyMlcgIT0gYnVmMlcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cjJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21wICAgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIGxzdHJjbXBBICAgIChLRVJORUwzMi5AKQogKgogKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSBjdXJyZW50IHRocmVhZCBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBzdHIyICBbSV0gU2Vjb25kIHN0cmluZyB0byBjb21wYXJlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgbnVtYmVyIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogICAgICAgICAgIHN0cjIgaXMgbGVzcyB0aGFuLCBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gc3RyMSByZXNwZWN0aXZlbHkuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBBKExQQ1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewogICAgaW50IHJldDsKICAgIAogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdBKEdldFRocmVhZExvY2FsZSgpLCBMT0NBTEVfVVNFX0NQX0FDUCwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcGkgICAgIChLRVJORUwzMi5AKQogKiAgICAgICAgICAgbHN0cmNtcGlBICAgIChLRVJORUwzMi5AKQogKgogKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSBjdXJyZW50IHRocmVhZCBsb2NhbGUsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBzdHIyICBbSV0gU2Vjb25kIHN0cmluZyB0byBjb21wYXJlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgbnVtYmVyIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogICAgICAgICAgIHN0cjIgaXMgbGVzcyB0aGFuLCBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gc3RyMSByZXNwZWN0aXZlbHkuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBpQShMUENTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICgoc3RyMSA9PSBOVUxMKSAmJiAoc3RyMiA9PSBOVUxMKSkgcmV0dXJuIDA7CiAgICBpZiAoc3RyMSA9PSBOVUxMKSByZXR1cm4gLTE7CiAgICBpZiAoc3RyMiA9PSBOVUxMKSByZXR1cm4gMTsKCiAgICByZXQgPSBDb21wYXJlU3RyaW5nQShHZXRUaHJlYWRMb2NhbGUoKSwgTk9STV9JR05PUkVDQVNFfExPQ0FMRV9VU0VfQ1BfQUNQLCBzdHIxLCAtMSwgc3RyMiwgLTEpOwogICAgaWYgKHJldCkgcmV0IC09IDI7CiAgICAKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21wVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIGxzdHJjbXBBLgogKi8KaW50IFdJTkFQSSBsc3RyY21wVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMikKewogICAgaW50IHJldDsKCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIDAsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBpVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIGxzdHJjbXBpQS4KICovCmludCBXSU5BUEkgbHN0cmNtcGlXKExQQ1dTVFIgc3RyMSwgTFBDV1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0OwogICAgCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMT0NBTEVfSW5pdAogKi8Kdm9pZCBMT0NBTEVfSW5pdCh2b2lkKQp7CiAgICBleHRlcm4gdm9pZCBfX3dpbmVfaW5pdF9jb2RlcGFnZXMoIGNvbnN0IHVuaW9uIGNwdGFibGUgKmFuc2lfY3AsIGNvbnN0IHVuaW9uIGNwdGFibGUgKm9lbV9jcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdW5peF9jcCApOwoKICAgIFVJTlQgYW5zaV9jcCA9IDEyNTIsIG9lbV9jcCA9IDQzNywgbWFjX2NwID0gMTAwMDAsIHVuaXhfY3AgPSB+MFU7CiAgICBMQ0lEIGxjaWQ7CgogICAgbGNpZCA9IGdldF9lbnZfbGNpZCggTlVMTCwgTlVMTCApOwogICAgTnRTZXREZWZhdWx0TG9jYWxlKCBUUlVFLCBsY2lkICk7CgogICAgbGNpZCA9IGdldF9lbnZfbGNpZCggTlVMTCwgIkxDX01FU1NBR0VTIiApOwogICAgTnRTZXREZWZhdWx0VUlMYW5ndWFnZSggTEFOR0lERlJPTUxDSUQobGNpZCkgKTsKCiAgICBsY2lkID0gZ2V0X2Vudl9sY2lkKCAmdW5peF9jcCwgIkxDX0NUWVBFIiApOwogICAgTnRTZXREZWZhdWx0TG9jYWxlKCBGQUxTRSwgbGNpZCApOwoKICAgIGFuc2lfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZShsY2lkKTsKICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm1hY19jcCwgc2l6ZW9mKG1hY19jcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVENPREVQQUdFIHwgTE9DQUxFX1JFVFVSTl9OVU1CRVIsCiAgICAgICAgICAgICAgICAgICAgKExQV1NUUikmb2VtX2NwLCBzaXplb2Yob2VtX2NwKS9zaXplb2YoV0NIQVIpICk7CiAgICBpZiAodW5peF9jcCA9PSB+MFUpCiAgICAgICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVFVOSVhDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJnVuaXhfY3AsIHNpemVvZih1bml4X2NwKS9zaXplb2YoV0NIQVIpICk7CgogICAgaWYgKCEoYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIGFuc2lfY3AgKSkpCiAgICAgICAgYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIDEyNTIgKTsKICAgIGlmICghKG9lbV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIG9lbV9jcCApKSkKICAgICAgICBvZW1fY3B0YWJsZSAgPSB3aW5lX2NwX2dldF90YWJsZSggNDM3ICk7CiAgICBpZiAoIShtYWNfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBtYWNfY3AgKSkpCiAgICAgICAgbWFjX2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDEwMDAwICk7CiAgICBpZiAodW5peF9jcCAhPSBDUF9VVEY4KQogICAgewogICAgICAgIGlmICghKHVuaXhfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCB1bml4X2NwICkpKQogICAgICAgICAgICB1bml4X2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDI4NTkxICk7CiAgICB9CgogICAgX193aW5lX2luaXRfY29kZXBhZ2VzKCBhbnNpX2NwdGFibGUsIG9lbV9jcHRhYmxlLCB1bml4X2NwdGFibGUgKTsKCiAgICBUUkFDRSggImFuc2k9JTAzZCBvZW09JTAzZCBtYWM9JTAzZCB1bml4PSUwM2RcbiIsCiAgICAgICAgICAgYW5zaV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlLCBvZW1fY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwKICAgICAgICAgICBtYWNfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwgdW5peF9jcCApOwp9CgpzdGF0aWMgSEtFWSBOTFNfUmVnT3BlbktleShIS0VZIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSkKewogICAgVU5JQ09ERV9TVFJJTkcga2V5TmFtZTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBIS0VZIGhrZXk7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZrZXlOYW1lLCBzektleU5hbWUgKTsKICAgIEluaXRpYWxpemVPYmplY3RBdHRyaWJ1dGVzKCZhdHRyLCAma2V5TmFtZSwgMCwgaFJvb3RLZXksIE5VTEwpOwoKICAgIGlmIChOdE9wZW5LZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIgKSAhPSBTVEFUVVNfU1VDQ0VTUykKICAgICAgICBoa2V5ID0gMDsKCiAgICByZXR1cm4gaGtleTsKfQoKc3RhdGljIEhLRVkgTkxTX1JlZ09wZW5TdWJLZXkoSEtFWSBoUm9vdEtleSwgTFBDV1NUUiBzektleU5hbWUpCnsKICAgIEhLRVkgaEtleSA9IE5MU19SZWdPcGVuS2V5KGhSb290S2V5LCBzektleU5hbWUpOwoKICAgIGlmIChoUm9vdEtleSkKICAgICAgICBOdENsb3NlKCBoUm9vdEtleSApOwoKICAgIHJldHVybiBoS2V5Owp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnRW51bVN1YktleShIS0VZIGhLZXksIFVJTlQgdWxJbmRleCwgTFBXU1RSIHN6S2V5TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcga2V5TmFtZVNpemUpCnsKICAgIEJZVEUgYnVmZmVyWzgwXTsKICAgIEtFWV9CQVNJQ19JTkZPUk1BVElPTiAqaW5mbyA9IChLRVlfQkFTSUNfSU5GT1JNQVRJT04gKilidWZmZXI7CiAgICBEV09SRCBkd0xlbjsKCiAgICBpZiAoTnRFbnVtZXJhdGVLZXkoIGhLZXksIHVsSW5kZXgsIEtleUJhc2ljSW5mb3JtYXRpb24sIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGJ1ZmZlciksICZkd0xlbikgIT0gU1RBVFVTX1NVQ0NFU1MgfHwKICAgICAgICBpbmZvLT5OYW1lTGVuZ3RoID4ga2V5TmFtZVNpemUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJpbmZvLT5OYW1lICVzIGluZm8tPk5hbWVMZW5ndGggJWxkXG4iLCBkZWJ1Z3N0cl93KGluZm8tPk5hbWUpLCBpbmZvLT5OYW1lTGVuZ3RoKTsKCiAgICBtZW1jcHkoIHN6S2V5TmFtZSwgaW5mby0+TmFtZSwgaW5mby0+TmFtZUxlbmd0aCk7CiAgICBzektleU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKCiAgICBUUkFDRSgicmV0dXJuaW5nICVzXG4iLCBkZWJ1Z3N0cl93KHN6S2V5TmFtZSkpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE5MU19SZWdFbnVtVmFsdWUoSEtFWSBoS2V5LCBVSU5UIHVsSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIHN6VmFsdWVOYW1lLCBVTE9ORyB2YWx1ZU5hbWVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBzelZhbHVlRGF0YSwgVUxPTkcgdmFsdWVEYXRhU2l6ZSkKewogICAgQllURSBidWZmZXJbODBdOwogICAgS0VZX1ZBTFVFX0ZVTExfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX1ZBTFVFX0ZVTExfSU5GT1JNQVRJT04gKilidWZmZXI7CiAgICBEV09SRCBkd0xlbjsKCiAgICBpZiAoTnRFbnVtZXJhdGVWYWx1ZUtleSggaEtleSwgdWxJbmRleCwgS2V5VmFsdWVGdWxsSW5mb3JtYXRpb24sCiAgICAgICAgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgJmR3TGVuICkgIT0gU1RBVFVTX1NVQ0NFU1MgfHwKICAgICAgICBpbmZvLT5OYW1lTGVuZ3RoID4gdmFsdWVOYW1lU2l6ZSB8fAogICAgICAgIGluZm8tPkRhdGFMZW5ndGggPiB2YWx1ZURhdGFTaXplKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiaW5mby0+TmFtZSAlcyBpbmZvLT5EYXRhTGVuZ3RoICVsZFxuIiwgZGVidWdzdHJfdyhpbmZvLT5OYW1lKSwgaW5mby0+RGF0YUxlbmd0aCk7CgogICAgbWVtY3B5KCBzelZhbHVlTmFtZSwgaW5mby0+TmFtZSwgaW5mby0+TmFtZUxlbmd0aCk7CiAgICBzelZhbHVlTmFtZVtpbmZvLT5OYW1lTGVuZ3RoIC8gc2l6ZW9mKFdDSEFSKV0gPSAnXDAnOwogICAgbWVtY3B5KCBzelZhbHVlRGF0YSwgYnVmZmVyICsgaW5mby0+RGF0YU9mZnNldCwgaW5mby0+RGF0YUxlbmd0aCApOwogICAgc3pWYWx1ZURhdGFbaW5mby0+RGF0YUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKCiAgICBUUkFDRSgicmV0dXJuaW5nICVzICVzXG4iLCBkZWJ1Z3N0cl93KHN6VmFsdWVOYW1lKSwgZGVidWdzdHJfdyhzelZhbHVlRGF0YSkpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE5MU19SZWdHZXREd29yZChIS0VZIGhLZXksIExQQ1dTVFIgc3pWYWx1ZU5hbWUsIERXT1JEICpscFZhbCkKewogICAgQllURSBidWZmZXJbMTI4XTsKICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdTaXplID0gc2l6ZW9mKGJ1ZmZlcik7CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZU5hbWU7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZU5hbWUsIHN6VmFsdWVOYW1lICk7CgogICAgVFJBQ0UoIiVwLCAlc1xuIiwgaEtleSwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSkpOwogICAgaWYgKE50UXVlcnlWYWx1ZUtleSggaEtleSwgJnZhbHVlTmFtZSwgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIGR3U2l6ZSwgJmR3U2l6ZSApID09IFNUQVRVU19TVUNDRVNTICYmCiAgICAgICAgaW5mby0+RGF0YUxlbmd0aCA9PSBzaXplb2YoRFdPUkQpKQogICAgewogICAgICAgIG1lbWNweShscFZhbCwgaW5mby0+RGF0YSwgc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBOTFNfR2V0TGFuZ3VhZ2VHcm91cE5hbWUoTEdSUElEIGxncnBpZCwgTFBXU1RSIHN6TmFtZSwgVUxPTkcgbmFtZVNpemUpCnsKICAgIExBTkdJRCAgbGFuZ0lkOwogICAgTFBDV1NUUiBzelJlc291cmNlTmFtZSA9IChMUENXU1RSKSgoKGxncnBpZCArIDB4MjAwMCkgPj4gNCkgKyAxKTsKICAgIEhSU1JDICAgaFJlc291cmNlOwogICAgQk9PTCAgICBiUmV0ID0gRkFMU0U7CgogICAgLyogRklYTUU6IElzIGl0IGNvcnJlY3QgdG8gdXNlIHRoZSBzeXN0ZW0gZGVmYXVsdCBsYW5naWQ/ICovCiAgICBsYW5nSWQgPSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKCk7CgogICAgaWYgKFNVQkxBTkdJRChsYW5nSWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nSWQgPSBNQUtFTEFOR0lEKCBQUklNQVJZTEFOR0lEKGxhbmdJZCksIFNVQkxBTkdfREVGQVVMVCApOwoKICAgIGhSZXNvdXJjZSA9IEZpbmRSZXNvdXJjZUV4Vygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywgc3pSZXNvdXJjZU5hbWUsIGxhbmdJZCApOwoKICAgIGlmIChoUmVzb3VyY2UpCiAgICB7CiAgICAgICAgSEdMT0JBTCBoUmVzRGlyID0gTG9hZFJlc291cmNlKCBrZXJuZWwzMl9oYW5kbGUsIGhSZXNvdXJjZSApOwoKICAgICAgICBpZiAoaFJlc0RpcikKICAgICAgICB7CiAgICAgICAgICAgIFVMT05HICAgaVJlc291cmNlSW5kZXggPSBsZ3JwaWQgJiAweGY7CiAgICAgICAgICAgIExQQ1dTVFIgbHBSZXNFbnRyeSA9IExvY2tSZXNvdXJjZSggaFJlc0RpciApOwogICAgICAgICAgICBVTE9ORyAgIGk7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaVJlc291cmNlSW5kZXg7IGkrKykKICAgICAgICAgICAgICAgIGxwUmVzRW50cnkgKz0gKmxwUmVzRW50cnkgKyAxOwoKICAgICAgICAgICAgaWYgKCpscFJlc0VudHJ5IDwgbmFtZVNpemUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1lbWNweSggc3pOYW1lLCBscFJlc0VudHJ5ICsgMSwgKmxwUmVzRW50cnkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBzek5hbWVbKmxwUmVzRW50cnldID0gJ1wwJzsKICAgICAgICAgICAgICAgIGJSZXQgPSBUUlVFOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBGcmVlUmVzb3VyY2UoIGhSZXNvdXJjZSApOwogICAgfQogICAgcmV0dXJuIGJSZXQ7Cn0KCi8qIFJlZ2lzdHJ5IGtleXMgZm9yIE5MUyByZWxhdGVkIGluZm9ybWF0aW9uICovCnN0YXRpYyBjb25zdCBXQ0hBUiBzekxhbmdHcm91cHNLZXlOYW1lW10gPSB7CiAgICAnTCcsJ2EnLCduJywnZycsJ3UnLCdhJywnZycsJ2UnLCcgJywnRycsJ3InLCdvJywndScsJ3AnLCdzJywnXDAnCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pDb3VudHJ5TGlzdE5hbWVbXSA9IHsKICAgICdNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgICAnVCcsJ2UnLCdsJywnZScsJ3AnLCdoJywnbycsJ24nLCd5JywnXFwnLAogICAgJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLCcgJywnTCcsJ2knLCdzJywndCcsJ1wwJwp9OwoKCi8qIENhbGxiYWNrIGZ1bmN0aW9uIHB0cnMgZm9yIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EvVyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ0EgcHJvY0E7CiAgTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ1cgcHJvY1c7CiAgRFdPUkQgICAgZHdGbGFnczsKICBMT05HX1BUUiBsUGFyYW07Cn0gRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTOwoKLyogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQS9XICovCnN0YXRpYyBCT09MIE5MU19FbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHMoRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTICpscFByb2NzKQp7CiAgICBXQ0hBUiBzek51bWJlclsxMF0sIHN6VmFsdWVbNF07CiAgICBIS0VZIGhLZXk7CiAgICBCT09MIGJDb250aW51ZSA9IFRSVUU7CiAgICBVTE9ORyB1bEluZGV4ID0gMDsKCiAgICBpZiAoIWxwUHJvY3MpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgc3dpdGNoIChscFByb2NzLT5kd0ZsYWdzKQogICAgewogICAgY2FzZSAwOgogICAgICAgIC8qIERlZmF1bHQgdG8gTEdSUElEX0lOU1RBTExFRCAqLwogICAgICAgIGxwUHJvY3MtPmR3RmxhZ3MgPSBMR1JQSURfSU5TVEFMTEVEOwogICAgICAgIC8qIEZhbGwgdGhyb3VnaC4uLiAqLwogICAgY2FzZSBMR1JQSURfSU5TVEFMTEVEOgogICAgY2FzZSBMR1JQSURfU1VQUE9SVEVEOgogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxhbmdHcm91cHNLZXlOYW1lICk7CgogICAgaWYgKCFoS2V5KQogICAgICAgIEZJWE1FKCJOTFMgcmVnaXN0cnkga2V5IG5vdCBmb3VuZC4gUGxlYXNlIGFwcGx5IHRoZSBkZWZhdWx0IHJlZ2lzdHJ5IGZpbGUgJ3dpbmUuaW5mJ1xuIik7CgogICAgd2hpbGUgKGJDb250aW51ZSkKICAgIHsKICAgICAgICBpZiAoTkxTX1JlZ0VudW1WYWx1ZSggaEtleSwgdWxJbmRleCwgc3pOdW1iZXIsIHNpemVvZihzek51bWJlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN6VmFsdWUsIHNpemVvZihzelZhbHVlKSApKQogICAgICAgIHsKICAgICAgICAgICAgQk9PTCBiSW5zdGFsbGVkID0gc3pWYWx1ZVswXSA9PSAnMScgPyBUUlVFIDogRkFMU0U7CiAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQgPSBzdHJ0b3VsVyggc3pOdW1iZXIsIE5VTEwsIDE2ICk7CgogICAgICAgICAgICBUUkFDRSgiZ3JwaWQgJXMgKCVzaW5zdGFsbGVkKVxuIiwgZGVidWdzdHJfdyhzek51bWJlciksCiAgICAgICAgICAgICAgICAgICBiSW5zdGFsbGVkID8gIiIgOiAibm90ICIpOwoKICAgICAgICAgICAgaWYgKGxwUHJvY3MtPmR3RmxhZ3MgPT0gTEdSUElEX1NVUFBPUlRFRCB8fCBiSW5zdGFsbGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ0hBUiBzekdycE5hbWVbNDhdOwoKICAgICAgICAgICAgICAgIGlmICghTkxTX0dldExhbmd1YWdlR3JvdXBOYW1lKCBsZ3JwaWQsIHN6R3JwTmFtZSwgc2l6ZW9mKHN6R3JwTmFtZSkgLyBzaXplb2YoV0NIQVIpICkpCiAgICAgICAgICAgICAgICAgICAgc3pHcnBOYW1lWzBdID0gJ1wwJzsKCiAgICAgICAgICAgICAgICBpZiAobHBQcm9jcy0+cHJvY1cpCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY1coIGxncnBpZCwgc3pOdW1iZXIsIHN6R3JwTmFtZSwgbHBQcm9jcy0+ZHdGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBQcm9jcy0+bFBhcmFtICk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2hhciBzek51bWJlckFbc2l6ZW9mKHN6TnVtYmVyKS9zaXplb2YoV0NIQVIpXTsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6R3JwTmFtZUFbNDhdOwoKICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogTVNETiBkb2Vzbid0IHNheSB3aGljaCBjb2RlIHBhZ2UgdGhlIFctPkEgdHJhbnNsYXRpb24gdXNlcywKICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgb3Igd2hldGhlciB0aGUgbGFuZ3VhZ2UgbmFtZXMgYXJlIGV2ZXIgbG9jYWxpc2VkLiBBc3N1bWUgQ1BfQUNQLgogICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pOdW1iZXIsIC0xLCBzek51bWJlckEsIHNpemVvZihzek51bWJlckEpLCAwLCAwKTsKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pHcnBOYW1lLCAtMSwgc3pHcnBOYW1lQSwgc2l6ZW9mKHN6R3JwTmFtZUEpLCAwLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY0EoIGxncnBpZCwgc3pOdW1iZXJBLCBzekdycE5hbWVBLCBscFByb2NzLT5kd0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdWxJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhLZXkpCiAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGVhY2ggbGFuZ3VhZ2UgZ3JvdXAgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgcExhbmdHcnBFbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsYW5ndWFnZSBncm91cAogKiAgZHdGbGFncyAgICAgICAgICBbSV0gTEdSUElEX1NVUFBPUlRFRD1BbGwgU3VwcG9ydGVkLCBMR1JQSURfSU5TVEFMTEVEPUluc3RhbGxlZCBvbmx5CiAqICBsUGFyYW0gICAgICAgICAgIFtJXSBVc2VyIHBhcmFtZXRlciB0byBwYXNzIHRvIHBMYW5nR3JwRW51bVByb2MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EoTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ0EgcExhbmdHcnBFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyBwcm9jczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIHBMYW5nR3JwRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgcHJvY3MucHJvY0EgPSBwTGFuZ0dycEVudW1Qcm9jOwogICAgcHJvY3MucHJvY1cgPSBOVUxMOwogICAgcHJvY3MuZHdGbGFncyA9IGR3RmxhZ3M7CiAgICBwcm9jcy5sUGFyYW0gPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHMoIHBMYW5nR3JwRW51bVByb2MgPyAmcHJvY3MgOiBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNXKExBTkdVQUdFR1JPVVBfRU5VTVBST0NXIHBMYW5nR3JwRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUF9DQUxMQkFDS1MgcHJvY3M7CgogICAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycEVudW1Qcm9jLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIHByb2NzLnByb2NBID0gTlVMTDsKICAgIHByb2NzLnByb2NXID0gcExhbmdHcnBFbnVtUHJvYzsKICAgIHByb2NzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgcHJvY3MubFBhcmFtID0gbFBhcmFtOwoKICAgIHJldHVybiBOTFNfRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzKCBwTGFuZ0dycEVudW1Qcm9jID8gJnByb2NzIDogTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzVmFsaWRMYW5ndWFnZUdyb3VwICAgIChLRVJORUwzMi5AKQogKgogKiBEZXRlcm1pbmUgaWYgYSBsYW5ndWFnZSBncm91cCBpcyBzdXBwb3J0ZWQgYW5kL29yIGluc3RhbGxlZC4KICoKICogUEFSQU1TCiAqICBsZ3JwaWQgIFtJXSBMYW5ndWFnZSBHcm91cCBJZCAoTEdSUElEXyB2YWx1ZXMgZnJvbSAid2lubmxzLmgiKQogKiAgZHdGbGFncyBbSV0gTEdSUElEX1NVUFBPUlRFRD1TdXBwb3J0ZWQsIExHUlBJRF9JTlNUQUxMRUQ9SW5zdGFsbGVkCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIGxncnBpZCBpcyBzdXBwb3J0ZWQgYW5kL29yIGluc3RhbGxlZCwgYWNjb3JkaW5nIHRvIGR3RmxhZ3MuCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc1ZhbGlkTGFuZ3VhZ2VHcm91cChMR1JQSUQgbGdycGlkLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pGb3JtYXRbXSA9IHsgJyUnLCd4JywnXDAnIH07CiAgICBXQ0hBUiBzelZhbHVlTmFtZVsxNl0sIHN6VmFsdWVbMl07CiAgICBCT09MIGJTdXBwb3J0ZWQgPSBGQUxTRSwgYkluc3RhbGxlZCA9IEZBTFNFOwogICAgSEtFWSBoS2V5OwoKCiAgICBzd2l0Y2ggKGR3RmxhZ3MpCiAgICB7CiAgICBjYXNlIExHUlBJRF9JTlNUQUxMRUQ6CiAgICBjYXNlIExHUlBJRF9TVVBQT1JURUQ6CgogICAgICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxhbmdHcm91cHNLZXlOYW1lICk7CgogICAgICAgIHNwcmludGZXKCBzelZhbHVlTmFtZSwgc3pGb3JtYXQsIGxncnBpZCApOwoKICAgICAgICBpZiAoTkxTX1JlZ0dldER3b3JkKCBoS2V5LCBzelZhbHVlTmFtZSwgKExQRFdPUkQpJnN6VmFsdWUgKSkKICAgICAgICB7CiAgICAgICAgICAgIGJTdXBwb3J0ZWQgPSBUUlVFOwoKICAgICAgICAgICAgaWYgKHN6VmFsdWVbMF0gPT0gJzEnKQogICAgICAgICAgICAgICAgYkluc3RhbGxlZCA9IFRSVUU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaEtleSkKICAgICAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoKGR3RmxhZ3MgPT0gTEdSUElEX1NVUFBPUlRFRCAmJiBiU3VwcG9ydGVkKSB8fAogICAgICAgIChkd0ZsYWdzID09IExHUlBJRF9JTlNUQUxMRUQgJiYgYkluc3RhbGxlZCkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBDYWxsYmFjayBmdW5jdGlvbiBwdHJzIGZvciBFbnVtTGFuZ3VhZ2VHcm91cGxvY2FsZXNBL1cgKi8KdHlwZWRlZiBzdHJ1Y3QKewogIExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ0EgcHJvY0E7CiAgTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DVyBwcm9jVzsKICBEV09SRCAgICBkd0ZsYWdzOwogIExHUlBJRCAgIGxncnBpZDsKICBMT05HX1BUUiBsUGFyYW07Cn0gRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTOwoKLyogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgRW51bUxhbmd1YWdlR3JvdXBsb2NhbGVzQS9XICovCnN0YXRpYyBCT09MIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTICpscFByb2NzKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pMb2NhbGVLZXlOYW1lW10gPSB7CiAgICAgICdMJywnbycsJ2MnLCdhJywnbCcsJ2UnLCdcMCcKICAgIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pBbHRlcm5hdGVTb3J0c0tleU5hbWVbXSA9IHsKICAgICAgJ0EnLCdsJywndCcsJ2UnLCdyJywnbicsJ2EnLCd0JywnZScsJyAnLCdTJywnbycsJ3InLCd0JywncycsJ1wwJwogICAgfTsKICAgIFdDSEFSIHN6TnVtYmVyWzEwXSwgc3pWYWx1ZVs0XTsKICAgIEhLRVkgaEtleTsKICAgIEJPT0wgYkNvbnRpbnVlID0gVFJVRSwgYkFsdGVybmF0ZSA9IEZBTFNFOwogICAgTEdSUElEIGxncnBpZDsKICAgIFVMT05HIHVsSW5kZXggPSAxOyAgLyogSWdub3JlIGRlZmF1bHQgZW50cnkgb2YgMXN0IGtleSAqLwoKICAgIGlmICghbHBQcm9jcyB8fCAhbHBQcm9jcy0+bGdycGlkIHx8IGxwUHJvY3MtPmxncnBpZCA+IExHUlBJRF9BUk1FTklBTikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobHBQcm9jcy0+ZHdGbGFncykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxvY2FsZUtleU5hbWUgKTsKCiAgICBpZiAoIWhLZXkpCiAgICAgICAgV0FSTigiTkxTIHJlZ2lzdHJ5IGtleSBub3QgZm91bmQuIFBsZWFzZSBhcHBseSB0aGUgZGVmYXVsdCByZWdpc3RyeSBmaWxlICd3aW5lLmluZidcbiIpOwoKICAgIHdoaWxlIChiQ29udGludWUpCiAgICB7CiAgICAgICAgaWYgKE5MU19SZWdFbnVtVmFsdWUoIGhLZXksIHVsSW5kZXgsIHN6TnVtYmVyLCBzaXplb2Yoc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzelZhbHVlLCBzaXplb2Yoc3pWYWx1ZSkgKSkKICAgICAgICB7CiAgICAgICAgICAgIGxncnBpZCA9IHN0cnRvdWxXKCBzelZhbHVlLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgVFJBQ0UoImxjaWQgJXMsIGdycGlkICVsZCAoJXNtYXRjaGVkKVxuIiwgZGVidWdzdHJfdyhzek51bWJlciksCiAgICAgICAgICAgICAgICAgICBsZ3JwaWQsIGxncnBpZCA9PSBscFByb2NzLT5sZ3JwaWQgPyAiIiA6ICJub3QgIik7CgogICAgICAgICAgICBpZiAobGdycGlkID09IGxwUHJvY3MtPmxncnBpZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTENJRCBsY2lkOwoKICAgICAgICAgICAgICAgIGxjaWQgPSBzdHJ0b3VsVyggc3pOdW1iZXIsIE5VTEwsIDE2ICk7CgogICAgICAgICAgICAgICAgLyogRklYTUU6IG5hdGl2ZSByZXR1cm5zIGV4dHJhIHRleHQgZm9yIGEgZmV3ICgxNy8xNTApIGxvY2FsZXMsIGUuZzoKICAgICAgICAgICAgICAgICAqICcwMDAwMDQzNyAgICAgICAgICA7R2VvcmdpYW4nCiAgICAgICAgICAgICAgICAgKiBBdCBwcmVzZW50IHdlIG9ubHkgcGFzcyB0aGUgTENJRCBzdHJpbmcuCiAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICBpZiAobHBQcm9jcy0+cHJvY1cpCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY1coIGxncnBpZCwgbGNpZCwgc3pOdW1iZXIsIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNoYXIgc3pOdW1iZXJBW3NpemVvZihzek51bWJlcikvc2l6ZW9mKFdDSEFSKV07CgogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzek51bWJlciwgLTEsIHN6TnVtYmVyQSwgc2l6ZW9mKHN6TnVtYmVyQSksIDAsIDApOwoKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jQSggbGdycGlkLCBsY2lkLCBzek51bWJlckEsIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB1bEluZGV4Kys7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIEZpbmlzaGVkIGVudW1lcmF0aW5nIHRoaXMga2V5ICovCiAgICAgICAgICAgIGlmICghYkFsdGVybmF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRW51bWVyYXRlIGFsdGVybmF0ZSBzb3J0cyBhbHNvICovCiAgICAgICAgICAgICAgICBoS2V5ID0gTkxTX1JlZ09wZW5LZXkoIGhLZXksIHN6QWx0ZXJuYXRlU29ydHNLZXlOYW1lICk7CiAgICAgICAgICAgICAgICBiQWx0ZXJuYXRlID0gVFJVRTsKICAgICAgICAgICAgICAgIHVsSW5kZXggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOyAvKiBGaW5pc2hlZCBib3RoIGtleXMgKi8KICAgICAgICB9CgogICAgICAgIGlmICghYkNvbnRpbnVlKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZXZlcnkgbG9jYWxlIGluIGEgbGFuZ3VhZ2UgZ3JvdXAgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgcExhbmdHcnBMY0VudW1Qcm9jIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxvY2FsZQogKiAgbGdycGlkICAgICAgICAgICAgIFtJXSBMYW5ndWFnZSBncm91cCAoTEdSUElEXyB2YWx1ZXMgZnJvbSAid2lubmxzLmgiKQogKiAgZHdGbGFncyAgICAgICAgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAKICogIGxQYXJhbSAgICAgICAgICAgICBbSV0gVXNlciBwYXJhbWV0ZXIgdG8gcGFzcyB0byBwTGFuZ0dycExjRW51bVByb2MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc0EoTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DQSBwTGFuZ0dycExjRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1MgY2FsbGJhY2tzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycExjRW51bVByb2MsIGxncnBpZCwgZHdGbGFncywgbFBhcmFtKTsKCiAgICBjYWxsYmFja3MucHJvY0EgICA9IHBMYW5nR3JwTGNFbnVtUHJvYzsKICAgIGNhbGxiYWNrcy5wcm9jVyAgID0gTlVMTDsKICAgIGNhbGxiYWNrcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIGNhbGxiYWNrcy5sZ3JwaWQgID0gbGdycGlkOwogICAgY2FsbGJhY2tzLmxQYXJhbSAgPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoIHBMYW5nR3JwTGNFbnVtUHJvYyA/ICZjYWxsYmFja3MgOiBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzVyhMQU5HR1JPVVBMT0NBTEVfRU5VTVBST0NXIHBMYW5nR3JwTGNFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMR1JQSUQgbGdycGlkLCBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUyBjYWxsYmFja3M7CgogICAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgsMHglMDhsWClcbiIsIHBMYW5nR3JwTGNFbnVtUHJvYywgbGdycGlkLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIGNhbGxiYWNrcy5wcm9jQSAgID0gTlVMTDsKICAgIGNhbGxiYWNrcy5wcm9jVyAgID0gcExhbmdHcnBMY0VudW1Qcm9jOwogICAgY2FsbGJhY2tzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgY2FsbGJhY2tzLmxncnBpZCAgPSBsZ3JwaWQ7CiAgICBjYWxsYmFja3MubFBhcmFtICA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1MYW5ndWFnZUdyb3VwTG9jYWxlcyggcExhbmdHcnBMY0VudW1Qcm9jID8gJmNhbGxiYWNrcyA6IE5VTEwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUdlb0lEICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2F0aW9uIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGdlb2NsYXNzICAgICBbSV0gVHlwZSBvZiBpbmZvcm1hdGlvbiBkZXNpcmVkIChTWVNHRU9UWVBFIGVudW0gZnJvbSAid2lubmxzLmgiKQogKiAgcmVzZXJ2ZWQgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAKICogIHBHZW9FbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhdGlvbgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUdlb0lEKEdFT0NMQVNTIGdlb2NsYXNzLCBHRU9JRCByZXNlcnZlZCwgR0VPX0VOVU1QUk9DIHBHZW9FbnVtUHJvYykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWVbXSA9IHsKICAgICAgJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLCdDJywnbycsJ2QnLCdlJywnXDAnCiAgICB9OwogICAgV0NIQVIgc3pOdW1iZXJbMTBdOwogICAgSEtFWSBoS2V5OwogICAgVUxPTkcgdWxJbmRleCA9IDA7CgogICAgVFJBQ0UoIigweCUwOGxYLDB4JTA4bFgsJXApXG4iLCBnZW9jbGFzcywgcmVzZXJ2ZWQsIHBHZW9FbnVtUHJvYyk7CgogICAgaWYgKGdlb2NsYXNzICE9IEdFT0NMQVNTX05BVElPTiB8fCByZXNlcnZlZCB8fCAhcEdlb0VudW1Qcm9jKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlbktleSggMCwgc3pDb3VudHJ5TGlzdE5hbWUgKTsKCiAgICB3aGlsZSAoTkxTX1JlZ0VudW1TdWJLZXkoIGhLZXksIHVsSW5kZXgsIHN6TnVtYmVyLCBzaXplb2Yoc3pOdW1iZXIpICkpCiAgICB7CiAgICAgICAgQk9PTCBiQ29udGludWUgPSBUUlVFOwogICAgICAgIERXT1JEIGR3R2VvSWQ7CiAgICAgICAgSEtFWSBoU3ViS2V5ID0gTkxTX1JlZ09wZW5LZXkoIGhLZXksIHN6TnVtYmVyICk7CgogICAgICAgIGlmIChoU3ViS2V5KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKE5MU19SZWdHZXREd29yZCggaFN1YktleSwgc3pDb3VudHJ5Q29kZVZhbHVlTmFtZSwgJmR3R2VvSWQgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBnZW9pZCAlbGRcbiIsIGR3R2VvSWQpOwoKICAgICAgICAgICAgICAgIGlmICghcEdlb0VudW1Qcm9jKCBkd0dlb0lkICkpCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gRkFMU0U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE50Q2xvc2UoIGhTdWJLZXkgKTsKICAgICAgICB9CgogICAgICAgIGlmICghYkNvbnRpbnVlKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgdWxJbmRleCsrOwogICAgfQoKICAgIGlmIChoS2V5KQogICAgICAgIE50Q2xvc2UoIGhLZXkgKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSW52YWxpZGF0ZU5MU0NhY2hlICAgICAgICAgICAoS0VSTkVMMzIuQCkKICoKICogSW52YWxpZGF0ZSB0aGUgY2FjaGUgb2YgTkxTIHZhbHVlcy4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuCiAqLwpCT09MIFdJTkFQSSBJbnZhbGlkYXRlTkxTQ2FjaGUodm9pZCkKewogIEZJWE1FKCIoKSBzdHViXG4iKTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFVzZXJHZW9JRCAoS0VSTkVMMzIuQCkKICovCkdFT0lEIFdJTkFQSSBHZXRVc2VyR2VvSUQoIEdFT0NMQVNTIEdlb0NsYXNzICkKewogICAgRklYTUUoIiVsZFxuIixHZW9DbGFzcyk7CiAgICByZXR1cm4gR0VPSURfTk9UX0FWQUlMQUJMRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgU2V0VXNlckdlb0lEIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgU2V0VXNlckdlb0lEKCBHRU9JRCBHZW9JRCApCnsKICAgIEZJWE1FKCIlbGRcbiIsR2VvSUQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtVUlMYW5ndWFnZXNBIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgRW51bVVJTGFuZ3VhZ2VzQShVSUxBTkdVQUdFX0VOVU1QUk9DQSBwVUlMYW5nRW51bVByb2MsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgc3RhdGljIGNoYXIgdmFsdWVbXSA9ICIwNDA5IjsKCiAgICBpZighcFVJTGFuZ0VudW1Qcm9jKSB7CglTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYoZHdGbGFncykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIEZJWE1FKCIlcCwgJWx4LCAlbHggY2FsbGluZyBwVUlMYW5nRW51bVByb2Mgd2l0aCAlc1xuIiwKICAgICAgICAgIHBVSUxhbmdFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtLCBkZWJ1Z3N0cl9hKHZhbHVlKSk7CgogICAgcFVJTGFuZ0VudW1Qcm9jKCB2YWx1ZSwgbFBhcmFtICk7CiAgICByZXR1cm4oVFJVRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1VSUxhbmd1YWdlc1cgKEtFUk5FTDMyLkApCiAqLwpCT09MIFdJTkFQSSBFbnVtVUlMYW5ndWFnZXNXKFVJTEFOR1VBR0VfRU5VTVBST0NXIHBVSUxhbmdFbnVtUHJvYywgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBzdGF0aWMgV0NIQVIgdmFsdWVbXSA9IHsnMCcsJzQnLCcwJywnOScsMH07CgogICAgaWYoIXBVSUxhbmdFbnVtUHJvYykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmKGR3RmxhZ3MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBGSVhNRSgiJXAsICVseCwgJWx4IGNhbGxpbmcgcFVJTGFuZ0VudW1Qcm9jIHdpdGggJXNcbiIsCiAgICAgICAgICBwVUlMYW5nRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSwgZGVidWdzdHJfdyh2YWx1ZSkpOwoKICAgIHBVSUxhbmdFbnVtUHJvYyggdmFsdWUsIGxQYXJhbSApOwogICAgcmV0dXJuKFRSVUUpOwp9Cg==