LyoKICogIFN5c3RlbSBNSUIgZ3JvdXAgaW1wbGVtZW50YXRpb24gLSBzeXN0ZW0uYwogKgogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKCiNpZiBIQVZFX1VUU05BTUVfSAojaW5jbHVkZSA8dXRzbmFtZS5oPgojZWxzZQojaWYgSEFWRV9TWVNfVVRTTkFNRV9ICiNpbmNsdWRlIDxzeXMvdXRzbmFtZS5oPgojZW5kaWYKI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zeXNPUlRhYmxlLmg+CgojaW5jbHVkZSAidXRpbF9mdW5jcy5oIgojaW5jbHVkZSAic3lzdGVtX21pYi5oIgojaW5jbHVkZSAidXBkYXRlcy5oIgoKICAgICAgICAvKioqKioqKioqKioqKioqKioqKioqCgkgKgoJICogIEtlcm5lbCAmIGludGVyZmFjZSBpbmZvcm1hdGlvbiwKCSAqICAgYW5kIGludGVybmFsIGZvcndhcmQgZGVjbGFyYXRpb25zCgkgKgoJICoqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgU1lTX1NUUklOR19MRU4JMjU2CnN0YXRpYyBjaGFyICAgICB2ZXJzaW9uX2Rlc2NyW1NZU19TVFJJTkdfTEVOXSA9IE5FVFNOTVBfVkVSU19ERVNDOwpzdGF0aWMgY2hhciAgICAgc3lzQ29udGFjdFtTWVNfU1RSSU5HX0xFTl0gPSBORVRTTk1QX1NZU19DT05UQUNUOwpzdGF0aWMgY2hhciAgICAgc3lzTmFtZVtTWVNfU1RSSU5HX0xFTl0gPSBORVRTTk1QX1NZU19OQU1FOwpzdGF0aWMgY2hhciAgICAgc3lzTG9jYXRpb25bU1lTX1NUUklOR19MRU5dID0gTkVUU05NUF9TWVNfTE9DOwpzdGF0aWMgb2lkICAgICAgc3lzT2JqZWN0SURbTUFYX09JRF9MRU5dOwpzdGF0aWMgc2l6ZV90IHN5c09iamVjdElEQnl0ZUxlbmd0aDsKCmV4dGVybiBvaWQgICAgICB2ZXJzaW9uX3N5c29pZFtdOwpleHRlcm4gaW50ICAgICAgdmVyc2lvbl9zeXNvaWRfbGVuOwoKc3RhdGljIGludCAgICAgIHN5c1NlcnZpY2VzID0gNzI7CnN0YXRpYyBpbnQgICAgICBzeXNTZXJ2aWNlc0NvbmZpZ2VkID0gMDsKCmV4dGVybiBvaWQgICAgICB2ZXJzaW9uX2lkW107CmV4dGVybiBpbnQgICAgICB2ZXJzaW9uX2lkX2xlbjsKCnN0YXRpYyBpbnQgICAgICBzeXNDb250YWN0U2V0ID0gMCwgc3lzTG9jYXRpb25TZXQgPSAwLCBzeXNOYW1lU2V0ID0gMDsKCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKc3RhdGljIHZvaWQgICAgIHdpbmRvd3NPU1ZlcnNpb25TdHJpbmcoY2hhciBbXSwgc2l6ZV90KTsKI2VuZGlmCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgc25tcGQuY29uZiBjb25maWcgcGFyc2luZwoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2Rlc2NyKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBpZiAoc3RybGVuKGNwdHIpID49IHNpemVvZih2ZXJzaW9uX2Rlc2NyKSkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoInN5c2Rlc2NyIHRva2VuIHRvbyBsb25nIChtdXN0IGJlIDwgJWx1KTpcblx0JXMiLAoJCQkgICAgICh1bnNpZ25lZCBsb25nKXNpemVvZih2ZXJzaW9uX2Rlc2NyKSwgY3B0cik7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChjcHRyLCAiXCJcIiIpID09IDApIHsKICAgICAgICB2ZXJzaW9uX2Rlc2NyWzBdID0gJ1wwJzsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RyY3B5KHZlcnNpb25fZGVzY3IsIGNwdHIpOwogICAgfQp9CgpORVRTTk1QX1NUQVRJQ19JTkxJTkUgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N0cmluZyhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgY2hhciogdmFsdWUsIHNpemVfdCBzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQqIGd1YXJkKQp7CiAgICBpZiAoc3RybGVuKGNwdHIpID49IHNpemUpIHsKCW5ldHNubXBfY29uZmlnX2Vycm9yKCIlcyB0b2tlbiB0b28gbG9uZyAobXVzdCBiZSA8ICVsdSk6XG5cdCVzIiwKCQkJICAgICB0b2tlbiwgKHVuc2lnbmVkIGxvbmcpc2l6ZSwgY3B0cik7CiAgICB9CgogICAgaWYgKCp0b2tlbiA9PSAncCcgJiYgc3RyY2FzZWNtcCh0b2tlbiArIDEsIG5hbWUpID09IDApIHsKICAgICAgICBpZiAoKmd1YXJkIDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHRoZSB2YWx1ZSBpcwogICAgICAgICAgICAgKiBhbHJlYWR5IGNvbmZpZ3VyZWQgcmVhZC1vbmx5LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5ICVzLjBcbiIsIG5hbWUpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgKysoKmd1YXJkKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmICgqZ3VhcmQgPiAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gd2UgYWxyZWFkeSByZWFkIGEKICAgICAgICAgICAgICogcGVyc2lzdGVudCB2YWx1ZSB3aGljaCB3ZSBzaG91bGQgaWdub3JlIGluIGZhdm91ciBvZiB0aGlzIG9uZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAiaWdub3JpbmcgYXR0ZW1wdGVkIG92ZXJyaWRlIG9mIHJlYWQtb25seSAlcy4wXG4iLCBuYW1lKTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRmFsbCB0aHJvdWdoIGFuZCBjb3B5IGluIHRoaXMgdmFsdWUuCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICAqZ3VhcmQgPSAtMTsKICAgIH0KCiAgICBpZiAoc3RyY21wKGNwdHIsICJcIlwiIikgPT0gMCkgewogICAgICAgICp2YWx1ZSA9ICdcMCc7CiAgICB9IGVsc2UgaWYgKHN0cmxlbihjcHRyKSA8IHNpemUpIHsKICAgICAgICBzdHJjcHkodmFsdWUsIGNwdHIpOwogICAgfQp9CgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2xvYyhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zdHJpbmcodG9rZW4sIGNwdHIsICJzeXNMb2NhdGlvbiIsIHN5c0xvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN5c0xvY2F0aW9uKSwgJnN5c0xvY2F0aW9uU2V0KTsKfQoKc3RhdGljIHZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNjb24oY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3RyaW5nKHRva2VuLCBjcHRyLCAic3lzQ29udGFjdCIsIHN5c0NvbnRhY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3lzQ29udGFjdCksICZzeXNDb250YWN0U2V0KTsKfQoKc3RhdGljIHZvaWQKc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNuYW1lKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N0cmluZyh0b2tlbiwgY3B0ciwgInN5c05hbWUiLCBzeXNOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN5c05hbWUpLCAmc3lzTmFtZVNldCk7Cn0KCnN0YXRpYyB2b2lkCnN5c3RlbV9wYXJzZV9jb25maWdfc3lzU2VydmljZXMoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIHN5c1NlcnZpY2VzID0gYXRvaShjcHRyKTsKICAgIHN5c1NlcnZpY2VzQ29uZmlnZWQgPSAxOwp9CgpzdGF0aWMgdm9pZApzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c09iamVjdElEKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBzaXplX3Qgc3lzT2JqZWN0SURMZW5ndGggPSBNQVhfT0lEX0xFTjsKICAgIGlmICghcmVhZF9vYmppZChjcHRyLCBzeXNPYmplY3RJRCwgJnN5c09iamVjdElETGVuZ3RoKSkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoInN5c29iamVjdGlkIHRva2VuIG5vdCBhIHBhcnNhYmxlIE9JRDpcblx0JXMiLAoJCQkgICAgIGNwdHIpOwogICAgICAgIHN5c09iamVjdElEQnl0ZUxlbmd0aCA9IHZlcnNpb25fc3lzb2lkX2xlbiAgKiBzaXplb2Yob2lkKTsKICAgICAgICBtZW1jcHkoc3lzT2JqZWN0SUQsIHZlcnNpb25fc3lzb2lkLCBzeXNPYmplY3RJREJ5dGVMZW5ndGgpOwogICAgfSBlbHNlCiAgICAgICAgc3lzT2JqZWN0SURCeXRlTGVuZ3RoID0gc3lzT2JqZWN0SURMZW5ndGggKiBzaXplb2Yob2lkKTsKfQoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKgoJICoKCSAqICBJbml0aWFsaXNhdGlvbiAmIGNvbW1vbiBpbXBsZW1lbnRhdGlvbiBmdW5jdGlvbnMKCSAqCgkgKioqKioqKioqKioqKioqKioqKioqLwoKb2lkICAgICAgICAgICAgIHN5c3RlbV9tb2R1bGVfb2lkW10gPSB7IFNOTVBfT0lEX1NOTVBNT0RVTEVTLCAxIH07CmludCAgICAgICAgICAgICBzeXN0ZW1fbW9kdWxlX29pZF9sZW4gPSBPSURfTEVOR1RIKHN5c3RlbV9tb2R1bGVfb2lkKTsKaW50ICAgICAgICAgICAgIHN5c3RlbV9tb2R1bGVfY291bnQgPSAwOwoKc3RhdGljIGludApzeXN0ZW1fc3RvcmUoaW50IGEsIGludCBiLCB2b2lkICpjLCB2b2lkICpkKQp7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTTk1QX01BWEJVRl9TTUFMTF07CgogICAgaWYgKHN5c0xvY2F0aW9uU2V0ID4gMCkgewogICAgICAgIHNucHJpbnRmKGxpbmUsIFNOTVBfTUFYQlVGX1NNQUxMLCAicHN5c2xvY2F0aW9uICVzIiwgc3lzTG9jYXRpb24pOwogICAgICAgIHNubXBkX3N0b3JlX2NvbmZpZyhsaW5lKTsKICAgIH0KICAgIGlmIChzeXNDb250YWN0U2V0ID4gMCkgewogICAgICAgIHNucHJpbnRmKGxpbmUsIFNOTVBfTUFYQlVGX1NNQUxMLCAicHN5c2NvbnRhY3QgJXMiLCBzeXNDb250YWN0KTsKICAgICAgICBzbm1wZF9zdG9yZV9jb25maWcobGluZSk7CiAgICB9CiAgICBpZiAoc3lzTmFtZVNldCA+IDApIHsKICAgICAgICBzbnByaW50ZihsaW5lLCBTTk1QX01BWEJVRl9TTUFMTCwgInBzeXNuYW1lICVzIiwgc3lzTmFtZSk7CiAgICAgICAgc25tcGRfc3RvcmVfY29uZmlnKGxpbmUpOwogICAgfQoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CmhhbmRsZV9zeXNTZXJ2aWNlcyhuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiNpZiBORVRTTk1QX05PX0RVTU1ZX1ZBTFVFUwogICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgJiYgIXN5c1NlcnZpY2VzQ29uZmlnZWQpCiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvcihyZXF1ZXN0cywgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiNlbmRpZgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnN0YXRpYyBpbnQKaGFuZGxlX3N5c1VwVGltZShuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBzbm1wX3NldF92YXJfdHlwZWRfaW50ZWdlcihyZXF1ZXN0cy0+cmVxdWVzdHZiLCBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCkpOwogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnZvaWQKaW5pdF9zeXN0ZW1fbWliKHZvaWQpCnsKCiNpZmRlZiBIQVZFX1VOQU1FCiAgICBzdHJ1Y3QgdXRzbmFtZSAgdXRzTmFtZTsKCiAgICB1bmFtZSgmdXRzTmFtZSk7CiAgICBzbnByaW50Zih2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjciksCiAgICAgICAgICAgICIlcyAlcyAlcyAlcyAlcyIsIHV0c05hbWUuc3lzbmFtZSwKICAgICAgICAgICAgdXRzTmFtZS5ub2RlbmFtZSwgdXRzTmFtZS5yZWxlYXNlLCB1dHNOYW1lLnZlcnNpb24sCiAgICAgICAgICAgIHV0c05hbWUubWFjaGluZSk7CiAgICB2ZXJzaW9uX2Rlc2NyWyBzaXplb2YodmVyc2lvbl9kZXNjciktMSBdID0gMDsKI2Vsc2UKI2lmIEhBVkVfRVhFQ1YKICAgIHN0cnVjdCBleHRlbnNpYmxlIGV4dG1wOwoKICAgIC8qCiAgICAgKiBzZXQgZGVmYXVsdCB2YWx1ZXMgb2Ygc3lzdGVtIHN0dWZmIAogICAgICovCiAgICBzcHJpbnRmKGV4dG1wLmNvbW1hbmQsICIlcyAtYSIsIFVOQU1FUFJPRyk7CiAgICAvKgogICAgICogc2V0dXAgZGVmYXVsdHMgCiAgICAgKi8KICAgIGV4dG1wLnR5cGUgPSBFWEVDUFJPQzsKICAgIGV4dG1wLm5leHQgPSBOVUxMOwogICAgZXhlY19jb21tYW5kKCZleHRtcCk7CiAgICBzdHJsY3B5KHZlcnNpb25fZGVzY3IsIGV4dG1wLm91dHB1dCwgc2l6ZW9mKHZlcnNpb25fZGVzY3IpKTsKICAgIGlmIChzdHJsZW4odmVyc2lvbl9kZXNjcikgPj0gMSkKICAgICAgICB2ZXJzaW9uX2Rlc2NyW3N0cmxlbih2ZXJzaW9uX2Rlc2NyKSAtIDFdID0gMDsgLyogY2hvbXAgbmV3IGxpbmUgKi8KI2Vsc2UKI2lmIChkZWZpbmVkIChXSU4zMikgJiYgZGVmaW5lZCAoSEFWRV9XSU4zMl9QTEFURk9STV9TREspKSB8fCBkZWZpbmVkIChtaW5ndzMyKQogICAgd2luZG93c09TVmVyc2lvblN0cmluZyh2ZXJzaW9uX2Rlc2NyLCBzaXplb2YodmVyc2lvbl9kZXNjcikpOwojZWxzZQogICAgc3RyY3B5KHZlcnNpb25fZGVzY3IsICJ1bmtub3duIik7CiNlbmRpZgojZW5kaWYKI2VuZGlmCgojaWZkZWYgSEFWRV9HRVRIT1NUTkFNRQogICAgZ2V0aG9zdG5hbWUoc3lzTmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmZGVmIEhBVkVfVU5BTUUKICAgIHN0cmxjcHkoc3lzTmFtZSwgdXRzTmFtZS5ub2RlbmFtZSwgc2l6ZW9mKHN5c05hbWUpKTsKI2Vsc2UKI2lmIGRlZmluZWQgKEhBVkVfRVhFQ1YpICYmICFkZWZpbmVkIChtaW5ndzMyKQogICAgc3ByaW50ZihleHRtcC5jb21tYW5kLCAiJXMgLW4iLCBVTkFNRVBST0cpOwogICAgLyoKICAgICAqIHNldHVwIGRlZmF1bHRzIAogICAgICovCiAgICBleHRtcC50eXBlID0gRVhFQ1BST0M7CiAgICBleHRtcC5uZXh0ID0gTlVMTDsKICAgIGV4ZWNfY29tbWFuZCgmZXh0bXApOwogICAgc3RybGNweShzeXNOYW1lLCBleHRtcC5vdXRwdXQsIHNpemVvZihzeXNOYW1lKSk7CiAgICBpZiAoc3RybGVuKHN5c05hbWUpID49IDEpCiAgICAgICAgc3lzTmFtZVtzdHJsZW4oc3lzTmFtZSkgLSAxXSA9IDA7IC8qIGNob21wIG5ldyBsaW5lICovCiNlbHNlCiAgICBzdHJjcHkoc3lzTmFtZSwgInVua25vd24iKTsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBIQVZFX0VYRUNWICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSEFWRV9VTkFNRSAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEhBVkVfR0VUSE9TVE5BTUUgKi8KCiNpZiAoZGVmaW5lZCAoV0lOMzIpICYmIGRlZmluZWQgKEhBVkVfV0lOMzJfUExBVEZPUk1fU0RLKSkgfHwgZGVmaW5lZCAobWluZ3czMikKICAgIHsKICAgICAgSEtFWSBoS2V5OwogICAgICAvKiBEZWZhdWx0IHN5c0NvbnRhY3QgaXMgdGhlIHJlZ2lzdGVyZWQgd2luZG93cyB1c2VyICovCiAgICAgIGlmIChSZWdPcGVuS2V5RXgoSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAgICAgICAgICAgICJTT0ZUV0FSRVxcTWljcm9zb2Z0XFxXaW5kb3dzIE5UXFxDdXJyZW50VmVyc2lvbiIsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgS0VZX1FVRVJZX1ZBTFVFLCAmaEtleSkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgY2hhciByZWdpc3RlcmVkT3duZXJbMjU2XSA9ICIiOwogICAgICAgICAgRFdPUkQgcmVnaXN0ZXJlZE93bmVyU3ogPSAyNTY7CiAgICAgICAgICBpZiAoUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJSZWdpc3RlcmVkT3duZXIiLCBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKXJlZ2lzdGVyZWRPd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlZ2lzdGVyZWRPd25lclN6KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgc3RyY3B5KHN5c0NvbnRhY3QsIHJlZ2lzdGVyZWRPd25lcik7CiAgICAgICAgICB9CiAgICAgICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgICAgfQogICAgfQojZW5kaWYKCiAgICAvKiBkZWZhdWx0IHN5c09iamVjdElEICovCiAgICBtZW1jcHkoc3lzT2JqZWN0SUQsIHZlcnNpb25fc3lzb2lkLCB2ZXJzaW9uX3N5c29pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBzeXNPYmplY3RJREJ5dGVMZW5ndGggPSB2ZXJzaW9uX3N5c29pZF9sZW4gKiBzaXplb2Yob2lkKTsKCiAgICB7CiAgICAgICAgY29uc3Qgb2lkIHN5c0Rlc2NyX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCAxIH07CiAgICAgICAgc3RhdGljIG5ldHNubXBfd2F0Y2hlcl9pbmZvIHN5c0Rlc2NyX3dpbmZvOwogICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c0Rlc2NyIiwgTlVMTCwgc3lzRGVzY3Jfb2lkLCBPSURfTEVOR1RIKHN5c0Rlc2NyX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSksCiAgICAgICAgICAgIG5ldHNubXBfaW5pdF93YXRjaGVyX2luZm8oJnN5c0Rlc2NyX3dpbmZvLCB2ZXJzaW9uX2Rlc2NyLCAwLAoJCQkJICAgICAgQVNOX09DVEVUX1NUUiwgV0FUQ0hFUl9TSVpFX1NUUkxFTikpOwogICAgfQogICAgewogICAgICAgIGNvbnN0IG9pZCBzeXNPYmplY3RJRF9vaWRbXSA9IHsgMSwgMywgNiwgMSwgMiwgMSwgMSwgMiB9OwogICAgICAgIHN0YXRpYyBuZXRzbm1wX3dhdGNoZXJfaW5mbyBzeXNPYmplY3RJRF93aW5mbzsKICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfc2NhbGFyKAogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgICAgICAgICJtaWJJSS9zeXNPYmplY3RJRCIsIE5VTEwsCiAgICAgICAgICAgICAgICBzeXNPYmplY3RJRF9vaWQsIE9JRF9MRU5HVEgoc3lzT2JqZWN0SURfb2lkKSwKICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JPTkxZKSwKICAgICAgICAgICAgbmV0c25tcF9pbml0X3dhdGNoZXJfaW5mbzYoCgkJJnN5c09iamVjdElEX3dpbmZvLCBzeXNPYmplY3RJRCwgMCwgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfSVNfUFRSLAogICAgICAgICAgICAgICAgTUFYX09JRF9MRU4sICZzeXNPYmplY3RJREJ5dGVMZW5ndGgpKTsKICAgIH0KICAgIHsKICAgICAgICBjb25zdCBvaWQgc3lzVXBUaW1lX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCAzIH07CiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c1VwVGltZSIsIGhhbmRsZV9zeXNVcFRpbWUsCiAgICAgICAgICAgICAgICBzeXNVcFRpbWVfb2lkLCBPSURfTEVOR1RIKHN5c1VwVGltZV9vaWQpLAogICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUk9OTFkpKTsKICAgIH0KICAgIHsKICAgICAgICBjb25zdCBvaWQgc3lzQ29udGFjdF9vaWRbXSA9IHsgMSwgMywgNiwgMSwgMiwgMSwgMSwgNCB9OwogICAgICAgIHN0YXRpYyBuZXRzbm1wX3dhdGNoZXJfaW5mbyBzeXNDb250YWN0X3dpbmZvOwogICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9zY2FsYXIoCiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3VwZGF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgICAgICAgICJtaWJJSS9zeXNDb250YWN0Iiwgc3lzQ29udGFjdF9vaWQsIE9JRF9MRU5HVEgoc3lzQ29udGFjdF9vaWQpLAogICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUldSSVRFLCAmc3lzQ29udGFjdFNldCksCiAgICAgICAgICAgIG5ldHNubXBfaW5pdF93YXRjaGVyX2luZm8oCgkJJnN5c0NvbnRhY3Rfd2luZm8sIHN5c0NvbnRhY3QsIFNZU19TVFJJTkdfTEVOIC0gMSwKCQlBU05fT0NURVRfU1RSLCBXQVRDSEVSX01BWF9TSVpFIHwgV0FUQ0hFUl9TSVpFX1NUUkxFTikpOwogICAgfQogICAgewogICAgICAgIGNvbnN0IG9pZCBzeXNOYW1lX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCA1IH07CiAgICAgICAgc3RhdGljIG5ldHNubXBfd2F0Y2hlcl9pbmZvIHN5c05hbWVfd2luZm87CiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl93YXRjaGVkX3NjYWxhcigKICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfdXBkYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgIm1pYklJL3N5c05hbWUiLCBzeXNOYW1lX29pZCwgT0lEX0xFTkdUSChzeXNOYW1lX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9SV1JJVEUsICZzeXNOYW1lU2V0KSwKICAgICAgICAgICAgbmV0c25tcF9pbml0X3dhdGNoZXJfaW5mbygKICAgICAgICAgICAgICAgICZzeXNOYW1lX3dpbmZvLCBzeXNOYW1lLCBTWVNfU1RSSU5HX0xFTiAtIDEsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgICAgICAgICBXQVRDSEVSX01BWF9TSVpFIHwgV0FUQ0hFUl9TSVpFX1NUUkxFTikpOwogICAgfQogICAgewogICAgICAgIGNvbnN0IG9pZCBzeXNMb2NhdGlvbl9vaWRbXSA9IHsgMSwgMywgNiwgMSwgMiwgMSwgMSwgNiB9OwogICAgICAgIHN0YXRpYyBuZXRzbm1wX3dhdGNoZXJfaW5mbyBzeXNMb2NhdGlvbl93aW5mbzsKICAgICAgICBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfc2NhbGFyKAogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV91cGRhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAibWliSUkvc3lzTG9jYXRpb24iLCBzeXNMb2NhdGlvbl9vaWQsCiAgICAgICAgICAgICAgICBPSURfTEVOR1RIKHN5c0xvY2F0aW9uX29pZCksCiAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9SV1JJVEUsICZzeXNMb2NhdGlvblNldCksCiAgICAgICAgICAgIG5ldHNubXBfaW5pdF93YXRjaGVyX2luZm8oCgkJJnN5c0xvY2F0aW9uX3dpbmZvLCBzeXNMb2NhdGlvbiwgU1lTX1NUUklOR19MRU4gLSAxLAoJCUFTTl9PQ1RFVF9TVFIsIFdBVENIRVJfTUFYX1NJWkUgfCBXQVRDSEVSX1NJWkVfU1RSTEVOKSk7CiAgICB9CiAgICB7CiAgICAgICAgY29uc3Qgb2lkIHN5c1NlcnZpY2VzX29pZFtdID0geyAxLCAzLCA2LCAxLCAyLCAxLCAxLCA3IH07CiAgICAgICAgbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X3NjYWxhcigKICAgICAgICAgICAgIm1pYklJL3N5c1NlcnZpY2VzIiwgc3lzU2VydmljZXNfb2lkLCBPSURfTEVOR1RIKHN5c1NlcnZpY2VzX29pZCksCiAgICAgICAgICAgICZzeXNTZXJ2aWNlcywgaGFuZGxlX3N5c1NlcnZpY2VzKTsKICAgIH0KICAgIGlmICgrK3N5c3RlbV9tb2R1bGVfY291bnQgPT0gMykKICAgICAgICBSRUdJU1RFUl9TWVNPUl9FTlRSWShzeXN0ZW1fbW9kdWxlX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhlIE1JQiBtb2R1bGUgZm9yIFNOTVB2MiBlbnRpdGllcyIpOwoKICAgIHN5c0NvbnRhY3RTZXQgPSBzeXNMb2NhdGlvblNldCA9IHN5c05hbWVTZXQgPSAwOwoKICAgIC8qCiAgICAgKiByZWdpc3RlciBvdXIgY29uZmlnIGhhbmRsZXJzIAogICAgICovCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzZGVzY3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtX3BhcnNlX2NvbmZpZ19zeXNkZXNjciwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiIpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN5c2xvY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbG9jLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxvY2F0aW9uIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3lzY29udGFjdCIsIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzY29uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgImNvbnRhY3QtbmFtZSIpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN5c25hbWUiLCBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAibm9kZS1uYW1lIik7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigicHN5c2xvY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzbG9jLCBOVUxMLCBOVUxMKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJwc3lzY29udGFjdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c2NvbiwgTlVMTCwgTlVMTCk7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigicHN5c25hbWUiLCBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJzeXNzZXJ2aWNlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1fcGFyc2VfY29uZmlnX3N5c1NlcnZpY2VzLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5VTUJFUiIpOwogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN5c29iamVjdGlkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbV9wYXJzZV9jb25maWdfc3lzT2JqZWN0SUQsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT0lEIik7CiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1fc3RvcmUsIE5VTEwpOwp9CgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioKCSAqCgkgKiAgSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gZnVuY3Rpb25zIC0gTm9uZQoJICoKCSAqKioqKioqKioqKioqKioqKioqKiovCgojaWYgKGRlZmluZWQgKFdJTjMyKSAmJiBkZWZpbmVkIChIQVZFX1dJTjMyX1BMQVRGT1JNX1NESykpIHx8IGRlZmluZWQgKG1pbmd3MzIpCnN0YXRpYyB2b2lkCndpbmRvd3NPU1ZlcnNpb25TdHJpbmcoY2hhciBzdHJpbmdidWZbXSwgc2l6ZV90IHN0cmluZ2J1ZmxlbikKewogICAgLyogY29weSBPUyB2ZXJzaW9uIHRvIHN0cmluZyBidWZmZXIgaW4gJ3VuYW1lIC1hJyBmb3JtYXQgKi8KICAgIE9TVkVSU0lPTklORk9FWCBvc1ZlcnNpb25JbmZvOwogICAgQk9PTCBnb3RPc1ZlcnNpb25JbmZvRXg7CiAgICBjaGFyIHdpbmRvd3NWZXJzaW9uWzI1Nl0gPSAiIjsKICAgIGNoYXIgaG9zdG5hbWVbMjU2XSA9ICIiOwogICAgY2hhciBpZGVudGlmaWVyWzI1Nl0gPSAiIjsKICAgIERXT1JEIGlkZW50aWZpZXJTeiA9IDI1NjsKICAgIEhLRVkgaEtleTsKCiAgICBaZXJvTWVtb3J5KCZvc1ZlcnNpb25JbmZvLCBzaXplb2YoT1NWRVJTSU9OSU5GT0VYKSk7CiAgICBvc1ZlcnNpb25JbmZvLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GT0VYKTsKICAgIGdvdE9zVmVyc2lvbkluZm9FeCA9IEdldFZlcnNpb25FeCgoT1NWRVJTSU9OSU5GTyAqKSZvc1ZlcnNpb25JbmZvKTsKICAgIGlmIChnb3RPc1ZlcnNpb25JbmZvRXggPT0gRkFMU0UpIHsKICAgICAgIEdldFZlcnNpb25FeCgoT1NWRVJTSU9OSU5GTyAqKSZvc1ZlcnNpb25JbmZvKTsKICAgIH0KCiAgICBzd2l0Y2ggKG9zVmVyc2lvbkluZm8uZHdQbGF0Zm9ybUlkKSB7CiAgICAgICBjYXNlIFZFUl9QTEFURk9STV9XSU4zMl9OVDoKICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA1KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAyKSkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiU2VydmVyIDIwMDMiKTsKICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNSkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMSkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIlhQIik7CiAgICAgICAgICB9IGVsc2UgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDApKSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIyMDAwIik7CiAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPD0gNCkgewogICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiTlQiKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChnb3RPc1ZlcnNpb25JbmZvRXggPT0gVFJVRSkgewogICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8ud1Byb2R1Y3RUeXBlID09IFZFUl9OVF9XT1JLU1RBVElPTikgewogICAgICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgewogICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFdvcmtzdGF0aW9uIDQuMCIpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfUEVSU09OQUwpIHsKICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBIb21lIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgUHJvZmVzc2lvbmFsIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1Byb2R1Y3RUeXBlID09IFZFUl9OVF9TRVJWRVIpIHsKICAgICAgICAgICAgICAgIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA1KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAyKSkgewogICAgICAgICAgICAgICAgICAgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9EQVRBQ0VOVEVSKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgRGF0YWNlbnRlciBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayAmIFZFUl9TVUlURV9FTlRFUlBSSVNFKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgRW50ZXJwcmlzZSBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9zVmVyc2lvbkluZm8ud1N1aXRlTWFzayA9PSBWRVJfU1VJVEVfQkxBREUpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBXZWIgRWRpdGlvbiIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTdGFuZGFyZCBFZGl0aW9uIik7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChvc1ZlcnNpb25JbmZvLmR3TWFqb3JWZXJzaW9uID09IDUpICYmIChvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uID09IDApKSB7CiAgICAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0RBVEFDRU5URVIpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBEYXRhY2VudGVyIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvc1ZlcnNpb25JbmZvLndTdWl0ZU1hc2sgJiBWRVJfU1VJVEVfRU5URVJQUklTRSkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIEFkdmFuY2VkIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTZXJ2ZXIiKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby53U3VpdGVNYXNrICYgVkVSX1NVSVRFX0VOVEVSUFJJU0UpIHsKICAgICAgICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBTZXJ2ZXIgNC4wLCBFbnRlcnByaXNlIEVkaXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgU2VydmVyIDQuMCIpOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgIGNoYXIgcHJvZHVjdFR5cGVbODBdOwogICAgICAgICAgICAgRFdPUkQgcHJvZHVjdFR5cGVTeiA9IDgwOwoKICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5RXgoSEtFWV9MT0NBTF9NQUNISU5FLCAiU1lTVEVNXFxDdXJyZW50Q29udHJvbFNldFxcQ29udHJvbFxcUHJvZHVjdE9wdGlvbnMiLCAwLCBLRVlfUVVFUllfVkFMVUUsICZoS2V5KSA9PSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBpZiAoUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJQcm9kdWN0VHlwZSIsIE5VTEwsIE5VTEwsIChMUEJZVEUpIHByb2R1Y3RUeXBlLCAmcHJvZHVjdFR5cGVTeikgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgICAgY2hhciB2ZXJzaW9uU3RyWzEwXTsKICAgICAgICAgICAgICAgICAgIGlmIChzdHJjbXBpKCJXSU5OVCIsIHByb2R1Y3RUeXBlKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgV29ya3N0YXRpb24iKTsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyY21waSgiTEFOTUFOTlQiLCBwcm9kdWN0VHlwZSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHdpbmRvd3NWZXJzaW9uLCAiIFNlcnZlciIpOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJjbXBpKCJTRVJWRVJOVCIsIHByb2R1Y3RUeXBlKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgQWR2YW5jZWQgU2VydmVyIik7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHZlcnNpb25TdHIsICIgJWQuJWQiLCAoaW50KW9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24sIChpbnQpb3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbik7CiAgICAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sIHZlcnNpb25TdHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgIGNhc2UgVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1M6CiAgICAgICAgICBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gOTApKSB7CiAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICJNRSIpOwogICAgICAgICAgfSBlbHNlIGlmICgob3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiA9PSA0KSAmJiAob3NWZXJzaW9uSW5mby5kd01pbm9yVmVyc2lvbiA9PSAxMCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIjk4Iik7CiAgICAgICAgICAgICBpZiAob3NWZXJzaW9uSW5mby5zekNTRFZlcnNpb25bMV0gPT0gJ0EnKSB7CiAgICAgICAgICAgICAgICBzdHJjYXQod2luZG93c1ZlcnNpb24sICIgU0UiKTsKICAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoKG9zVmVyc2lvbkluZm8uZHdNYWpvclZlcnNpb24gPT0gNCkgJiYgKG9zVmVyc2lvbkluZm8uZHdNaW5vclZlcnNpb24gPT0gMCkpIHsKICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIjk1Iik7CiAgICAgICAgICAgICBpZiAoKG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uWzFdID09ICdDJykgfHwgKG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uWzFdID09ICdCJykpIHsKICAgICAgICAgICAgICAgIHN0cmNhdCh3aW5kb3dzVmVyc2lvbiwgIiBPU1IyIik7CiAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBnZXRob3N0bmFtZShob3N0bmFtZSwgc2l6ZW9mKGhvc3RuYW1lKSk7CgogICAgaWYgKFJlZ09wZW5LZXlFeChIS0VZX0xPQ0FMX01BQ0hJTkUsICJIQVJEV0FSRVxcREVTQ1JJUFRJT05cXFN5c3RlbVxcQ2VudHJhbFByb2Nlc3NvclxcMCIsIDAsIEtFWV9BTExfQUNDRVNTLCAmaEtleSkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgUmVnUXVlcnlWYWx1ZUV4KGhLZXksICJJZGVudGlmaWVyIiwgTlVMTCwgTlVMTCwgKExQQllURSkmaWRlbnRpZmllciwgJmlkZW50aWZpZXJTeik7CiAgICAgICBSZWdDbG9zZUtleShoS2V5KTsKICAgIH0KCiAgICAvKiBPdXRwdXQgaXMgbWFkZSB0byBsb29rIGxpa2UgcmVzdWx0cyBmcm9tIHVuYW1lIC1hICovCiAgICBzbnByaW50ZihzdHJpbmdidWYsIHN0cmluZ2J1ZmxlbiwKICAgICAgICAgICAgIldpbmRvd3MgJXMgJWQuJWQuJWQgJXMgJXMgJXMiLCBob3N0bmFtZSwKICAgICAgICAgICAgIChpbnQpb3NWZXJzaW9uSW5mby5kd01ham9yVmVyc2lvbiwgKGludClvc1ZlcnNpb25JbmZvLmR3TWlub3JWZXJzaW9uLAogICAgICAgICAgICAgKGludClvc1ZlcnNpb25JbmZvLmR3QnVpbGROdW1iZXIsIG9zVmVyc2lvbkluZm8uc3pDU0RWZXJzaW9uLAogICAgICAgICAgICAgd2luZG93c1ZlcnNpb24sIGlkZW50aWZpZXIpOwp9CiNlbmRpZiAvKiBXSU4zMiBhbmQgSEFWRV9XSU4zMl9QTEFURk9STV9TREsgb3IgbWluZ3czMiAqLwoK