LyogCiAqIEltcGxlbWVudGF0aW9uIG9mIFZFUi5ETEwKICogCiAqIENvcHlyaWdodCAxOTk2IE1hcmN1cyBNZWlzc25lcgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJ2ZXIuaCIKI2luY2x1ZGUgImx6ZXhwYW5kLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2RlZmluZSBMWlJFQUQod2hhdCkgXAogIGlmIChzaXplb2YoKndoYXQpIT1MWlJlYWQzMihsemZkLHdoYXQsc2l6ZW9mKCp3aGF0KSkpIHJldHVybiAwOwojZGVmaW5lIExaVEVMTChsemZkKSBMWlNlZWsobHpmZCwgMCwgU0VFS19DVVIpOwoKaW50CnJlYWRfbmVfaGVhZGVyKEhGSUxFIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkKSB7CglzdHJ1Y3QJbXpfaGVhZGVyX3MJbXpoOwoKCUxaU2VlayhsemZkLDAsU0VFS19TRVQpOwoJaWYgKHNpemVvZihtemgpIT1MWlJlYWQzMihsemZkLCZtemgsc2l6ZW9mKG16aCkpKQoJCXJldHVybiAwOwoJaWYgKG16aC5tel9tYWdpYyE9TVpfU0lHTkFUVVJFKQoJCXJldHVybiAwOwoJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CglMWlJFQUQobmVoZCk7CglpZiAobmVoZC0+bmVfbWFnaWMgPT0gTkVfU0lHTkFUVVJFKSB7CgkJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CgkJcmV0dXJuIDE7Cgl9CgkvKiBtdXN0IGhhbmRsZSBQRSBmaWxlcyB0b28uIExhdGVyLiAqLwoJcmV0dXJuIDA7Cn0KCgppbnQKZmluZF9uZV9yZXNvdXJjZSgKCUhGSUxFIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkLFNFR1BUUiB0eXBlaWQsU0VHUFRSIHJlc2lkLAoJQllURSAqKnJlc2RhdGEsaW50ICpyZXNsZW4sRFdPUkQgKm9mZgopIHsKCU5FX1RZUEVJTkZPCXRpOwoJTkVfTkFNRUlORk8Jbmk7CglpbnQJCWk7CglXT1JECQlzaGlmdGNvdW50OwoJRFdPUkQJCW5laGRvZmZzZXQ7CgoJbmVoZG9mZnNldCA9IExaVEVMTChsemZkKTsKCUxaU2VlayhsemZkLG5laGQtPnJlc291cmNlX3RhYl9vZmZzZXQsU0VFS19DVVIpOwoJTFpSRUFEKCZzaGlmdGNvdW50KTsKCWRwcmludGZfdmVyKHN0ZGRlYiwic2hpZnRjb3VudCBpcyAlZFxuIixzaGlmdGNvdW50KTsKCWRwcmludGZfdmVyKHN0ZGRlYiwicmVhZGluZyByZXNvdXJjZSB0eXBlaW5mbyBkaXIuXG4iKTsKCglpZiAoIUhJV09SRCh0eXBlaWQpKSB0eXBlaWQgPSAoU0VHUFRSKShMT1dPUkQodHlwZWlkKSB8IDB4ODAwMCk7CglpZiAoIUhJV09SRChyZXNpZCkpICByZXNpZCAgPSAoU0VHUFRSKShMT1dPUkQocmVzaWQpIHwgMHg4MDAwKTsKCXdoaWxlICgxKSB7CgkJaW50CXNraXBmbGFnOwoKCQlMWlJFQUQoJnRpKTsKCQlpZiAoIXRpLnR5cGVfaWQpCgkJCXJldHVybiAwOwoJCWRwcmludGZfdmVyKHN0ZGRlYiwiICAgIHRpLnR5cGVpZCA9JTA0eCxjb3VudD0lZFxuIix0aS50eXBlX2lkLHRpLmNvdW50KTsKCQlza2lwZmxhZz0wOwoJCWlmICghSElXT1JEKHR5cGVpZCkpIHsKCQkJaWYgKCh0aS50eXBlX2lkJjB4ODAwMCkmJih0eXBlaWQhPXRpLnR5cGVfaWQpKQoJCQkJc2tpcGZsYWc9MTsKCQl9IGVsc2UgewoJCQlpZiAodGkudHlwZV9pZCAmIDB4ODAwMCkgewoJCQkJc2tpcGZsYWc9MTsgCgkJCX0gZWxzZSB7CgkJCQlCWVRFCWxlbjsKCQkJCWNoYXIJKnN0cjsKCQkJCURXT1JECXdoZXJlbGVmdDsKCgkJCQl3aGVyZWxlZnQgPSBMWlRFTEwobHpmZCk7CgkJCQlMWlNlZWsoCgkJCQkJbHpmZCwKCQkJCQluZWhkb2Zmc2V0K25laGQtPnJlc291cmNlX3RhYl9vZmZzZXQrdGkudHlwZV9pZCwKCQkJCQlTRUVLX1NFVAoJCQkJKTsKCQkJCUxaUkVBRCgmbGVuKTsKCQkJCXN0cj14bWFsbG9jKGxlbik7CgkJCQlpZiAobGVuIT1MWlJlYWQzMihsemZkLHN0cixsZW4pKQoJCQkJCXJldHVybiAwOwoJCQkJZHByaW50Zl92ZXIoc3RkZGViLCJyZWFkICVzIHRvIGNvbXBhcmUgaXQgd2l0aCAlc1xuIiwKCQkJCQlzdHIsKGNoYXIqKVBUUl9TRUdfVE9fTElOKHR5cGVpZCkKCQkJCSk7CgkJCQlpZiAobHN0cmNtcGkzMkEoc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpKSkKCQkJCQlza2lwZmxhZz0xOwoJCQkJZnJlZShzdHIpOwoJCQkJTFpTZWVrKGx6ZmQsd2hlcmVsZWZ0LFNFRUtfU0VUKTsKCQkJfQoJCX0KCQlpZiAoc2tpcGZsYWcpIHsKCQkJTFpTZWVrKGx6ZmQsdGkuY291bnQqc2l6ZW9mKG5pKSxTRUVLX0NVUik7CgkJCWNvbnRpbnVlOwoJCX0KCQlmb3IgKGk9MDtpPHRpLmNvdW50O2krKykgewoJCQlXT1JECSpyZGF0YTsKCQkJaW50CWxlbjsKCgkJCUxaUkVBRCgmbmkpOwoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIgluaS5pZD0lNHgsb2Zmc2V0PSVkLGxlbmd0aD0lZFxuIiwKCQkJCW5pLmlkLG5pLm9mZnNldCxuaS5sZW5ndGgKCQkJKTsKCQkJc2tpcGZsYWc9MTsKCQkJaWYgKCFISVdPUkQocmVzaWQpKSB7CgkJCQlpZiAobmkuaWQgPT0gcmVzaWQpCgkJCQkJc2tpcGZsYWc9MDsKCQkJfSBlbHNlIHsKCQkJCWlmICghKG5pLmlkICYgMHg4MDAwKSkgewoJCQkJCUJZVEUJbGVuOwoJCQkJCWNoYXIJKnN0cjsKCQkJCQlEV09SRAl3aGVyZWxlZnQ7CgoJCQkJCXdoZXJlbGVmdCA9IExaVEVMTChsemZkKTsKCQkJCQkgIExaU2VlaygKCQkJCQkJbHpmZCwKCQkJCQkJbmVoZG9mZnNldCtuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0K25pLmlkLAoJCQkJCQlTRUVLX1NFVAoJCQkJCSk7CgkJCQkJTFpSRUFEKCZsZW4pOwoJCQkJCXN0cj14bWFsbG9jKGxlbik7CgkJCQkJaWYgKGxlbiE9TFpSZWFkMzIobHpmZCxzdHIsbGVuKSkKCQkJCQkJcmV0dXJuIDA7CgkJCQkJZHByaW50Zl92ZXIoc3RkZGViLCJyZWFkICVzIHRvIGNvbXBhcmUgaXQgd2l0aCAlc1xuIiwKCQkJCQkJc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpCgkJCQkJKTsKCQkJCQlpZiAoIWxzdHJjbXBpMzJBKHN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKSkpCgkJCQkJCXNraXBmbGFnPTA7CgkJCQkJZnJlZShzdHIpOwoJCQkJCUxaU2VlayhsemZkLHdoZXJlbGVmdCxTRUVLX1NFVCk7CgkJCQl9CgkJCX0KCQkJaWYgKHNraXBmbGFnKQoJCQkJY29udGludWU7CgkJCUxaU2VlayhsemZkLCgoaW50KW5pLm9mZnNldDw8c2hpZnRjb3VudCksU0VFS19TRVQpOwoJCQkqb2ZmCT0gKGludCluaS5vZmZzZXQ8PHNoaWZ0Y291bnQ7CgkJCWxlbgk9IG5pLmxlbmd0aDw8c2hpZnRjb3VudDsKCQkJcmRhdGE9KFdPUkQqKXhtYWxsb2MobGVuKTsKCQkJaWYgKGxlbiE9TFpSZWFkMzIobHpmZCxyZGF0YSxsZW4pKSB7CgkJCQlmcmVlKHJkYXRhKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwicmVzb3VyY2UgZm91bmQuXG4iKTsKCQkJKnJlc2RhdGE9IChCWVRFKilyZGF0YTsKCQkJKnJlc2xlbgk9IGxlbjsKCQkJcmV0dXJuIDE7CgkJfQoJfQp9CgovKiBHZXRGaWxlUmVzb3VyY2VTaXplCQkJCVtWRVIuMl0gKi8KRFdPUkQKR2V0RmlsZVJlc291cmNlU2l6ZShMUENTVFIgZmlsZW5hbWUsU0VHUFRSIHJlc3R5cGUsU0VHUFRSIHJlc2lkLExQRFdPUkQgb2ZmKSB7CglIRklMRQlsemZkOwoJT0ZTVFJVQ1QJb2ZzOwoJQllURQkqcmVzZGF0YTsKCWludAlyZXNsZW47CglzdHJ1Y3QJbmVfaGVhZGVyX3MJbmVoZDsKCglkcHJpbnRmX3ZlcihzdGRkZWIsIkdldEZpbGVSZXNvdXJjZVNpemUoJXMsJWx4LCVseCwlcClcbiIsCgkJZmlsZW5hbWUsKExPTkcpcmVzdHlwZSwoTE9ORylyZXNpZCxvZmYKCSk7CglsemZkPUxaT3BlbkZpbGUxNihmaWxlbmFtZSwmb2ZzLE9GX1JFQUQpOwoJaWYgKGx6ZmQ9PTApCgkJcmV0dXJuIDA7CglpZiAoIXJlYWRfbmVfaGVhZGVyKGx6ZmQsJm5laGQpKSB7CgkJTFpDbG9zZShsemZkKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghZmluZF9uZV9yZXNvdXJjZShsemZkLCZuZWhkLHJlc3R5cGUscmVzaWQsJnJlc2RhdGEsJnJlc2xlbixvZmYpKSB7CgkJTFpDbG9zZShsemZkKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUocmVzZGF0YSk7CglMWkNsb3NlKGx6ZmQpOwoJcmV0dXJuIHJlc2xlbjsKfQoKLyogR2V0RmlsZVJlc291cmNlCQkJCVtWRVIuM10gKi8KRFdPUkQKR2V0RmlsZVJlc291cmNlKExQQ1NUUiBmaWxlbmFtZSxTRUdQVFIgcmVzdHlwZSxTRUdQVFIgcmVzaWQsCgkJRFdPUkQgb2ZmLERXT1JEIGRhdGFsZW4sTFBWT0lEIGRhdGEKKSB7CglIRklMRQlsemZkOwoJT0ZTVFJVQ1QJb2ZzOwoJQllURQkqcmVzZGF0YTsKCWludAlyZXNsZW49ZGF0YWxlbjsKCXN0cnVjdAluZV9oZWFkZXJfcwluZWhkOwoJZHByaW50Zl92ZXIoc3RkZGViLCJHZXRGaWxlUmVzb3VyY2UoJXMsJWx4LCVseCwlbGQsJWxkLCVwKVxuIiwKCQlmaWxlbmFtZSwoTE9ORylyZXN0eXBlLChMT05HKXJlc2lkLG9mZixkYXRhbGVuLGRhdGEKCSk7CgoJbHpmZD1MWk9wZW5GaWxlMTYoZmlsZW5hbWUsJm9mcyxPRl9SRUFEKTsKCWlmIChsemZkPT0wKQoJCXJldHVybiAwOwoJaWYgKCFvZmYpIHsKCQlpZiAoIXJlYWRfbmVfaGVhZGVyKGx6ZmQsJm5laGQpKSB7CgkJCUxaQ2xvc2UobHpmZCk7CgkJCXJldHVybiAwOwoJCX0KCQlpZiAoIWZpbmRfbmVfcmVzb3VyY2UobHpmZCwmbmVoZCxyZXN0eXBlLHJlc2lkLCZyZXNkYXRhLCZyZXNsZW4sJm9mZikpIHsKCQkJTFpDbG9zZShsemZkKTsKCQkJcmV0dXJuIDA7CgkJfQoJCWZyZWUocmVzZGF0YSk7Cgl9CglMWlNlZWsobHpmZCxvZmYsU0VFS19TRVQpOwoJaWYgKHJlc2xlbj5kYXRhbGVuKQoJCXJlc2xlbj1kYXRhbGVuOwoJTFpSZWFkMzIobHpmZCxkYXRhLHJlc2xlbik7CglMWkNsb3NlKGx6ZmQpOwoJcmV0dXJuIHJlc2xlbjsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvU2l6ZQkJCVtWRVIuNl0gKi8KRFdPUkQKR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KExQQ1NUUiBmaWxlbmFtZSxMUERXT1JEIGhhbmRsZSkgewoJRFdPUkQJbGVuLHJldDsKCUJZVEUJYnVmWzcyXTsKCVZTX0ZJWEVERklMRUlORk8gKnZmZmk7CgoJZHByaW50Zl92ZXIoc3RkZGViLCJHZXRGaWxlVmVyc2lvbkluZm9TaXplMTYoJXMsJXApXG4iLGZpbGVuYW1lLGhhbmRsZSk7CglsZW49R2V0RmlsZVJlc291cmNlU2l6ZShmaWxlbmFtZSxWU19GSUxFX0lORk8sVlNfVkVSU0lPTl9JTkZPLGhhbmRsZSk7CglpZiAoIWxlbikKCQlyZXR1cm4gMDsKCXJldD1HZXRGaWxlUmVzb3VyY2UoCgkJZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTywqaGFuZGxlLHNpemVvZihidWYpLGJ1ZgoJKTsKCWlmICghcmV0KQoJCXJldHVybiAwOwoKCXZmZmk9KFZTX0ZJWEVERklMRUlORk8qKShidWYrMHgxNCk7CglpZiAodmZmaS0+ZHdTaWduYXR1cmUgIT0gVlNfRkZJX1NJR05BVFVSRSkKCQlyZXR1cm4gMDsKCWlmICgqKFdPUkQqKWJ1ZiA8IGxlbikKCQlsZW4gPSAqKFdPUkQqKWJ1ZjsKCWRwcmludGZfdmVyKHN0ZGRlYiwiLT5zdHJ1Y3Zlcj0lbGQuJWxkLGZpbGV2ZXI9JWxkLiVsZCxwcm9kdWN0dmVyPSVsZC4lbGQsZmxhZ21hc2s9JWx4LGZsYWdzPSVseCxPUz0iLAoJCSh2ZmZpLT5kd1N0cnVjVmVyc2lvbj4+MTYpLHZmZmktPmR3U3RydWNWZXJzaW9uJjB4RkZGRiwKCQl2ZmZpLT5kd0ZpbGVWZXJzaW9uTVMsdmZmaS0+ZHdGaWxlVmVyc2lvbkxTLAoJCXZmZmktPmR3UHJvZHVjdFZlcnNpb25NUyx2ZmZpLT5kd1Byb2R1Y3RWZXJzaW9uTFMsCgkJdmZmaS0+ZHdGaWxlRmxhZ3NNYXNrLHZmZmktPmR3RmlsZUZsYWdzCgkpOwoJc3dpdGNoICh2ZmZpLT5kd0ZpbGVPUyYweEZGRkYwMDAwKSB7CgljYXNlIFZPU19ET1M6ZHByaW50Zl92ZXIoc3RkZGViLCJET1MsIik7YnJlYWs7CgljYXNlIFZPU19PUzIxNjpkcHJpbnRmX3ZlcihzdGRkZWIsIk9TLzItMTYsIik7YnJlYWs7CgljYXNlIFZPU19PUzIzMjpkcHJpbnRmX3ZlcihzdGRkZWIsIk9TLzItMzIsIik7YnJlYWs7CgljYXNlIFZPU19OVDpkcHJpbnRmX3ZlcihzdGRkZWIsIk5ULCIpO2JyZWFrOwoJY2FzZSBWT1NfVU5LTk9XTjoKCWRlZmF1bHQ6CgkJZHByaW50Zl92ZXIoc3RkZGViLCJVTktOT1dOKCVsZCksIix2ZmZpLT5kd0ZpbGVPUyYweEZGRkYwMDAwKTticmVhazsKCX0KCXN3aXRjaCAodmZmaS0+ZHdGaWxlT1MgJiAweEZGRkYpIHsKCWNhc2UgVk9TX19CQVNFOmRwcmludGZfdmVyKHN0ZGRlYiwiQkFTRSIpO2JyZWFrOwoJY2FzZSBWT1NfX1dJTkRPV1MxNjpkcHJpbnRmX3ZlcihzdGRkZWIsIldJTjE2Iik7YnJlYWs7CgljYXNlIFZPU19fV0lORE9XUzMyOmRwcmludGZfdmVyKHN0ZGRlYiwiV0lOMzIiKTticmVhazsKCWNhc2UgVk9TX19QTTE2OmRwcmludGZfdmVyKHN0ZGRlYiwiUE0xNiIpO2JyZWFrOwoJY2FzZSBWT1NfX1BNMzI6ZHByaW50Zl92ZXIoc3RkZGViLCJQTTMyIik7YnJlYWs7CglkZWZhdWx0OmRwcmludGZfdmVyKHN0ZGRlYiwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVPUyYweEZGRkYpO2JyZWFrOwoJfQoJc3dpdGNoICh2ZmZpLT5kd0ZpbGVUeXBlKSB7CglkZWZhdWx0OgoJY2FzZSBWRlRfVU5LTk9XTjoKCQlkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPVVua25vd24oJWxkKSIsdmZmaS0+ZHdGaWxlVHlwZSk7CgkJYnJlYWs7CgljYXNlIFZGVF9BUFA6ZHByaW50Zl92ZXIoc3RkZGViLCJmaWxldHlwZT1BUFAiKTticmVhazsKCWNhc2UgVkZUX0RMTDpkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPURMTCIpO2JyZWFrOwoJY2FzZSBWRlRfRFJWOgoJCWRwcmludGZfdmVyKHN0ZGRlYiwiZmlsZXR5cGU9RFJWLCIpOwoJCXN3aXRjaCh2ZmZpLT5kd0ZpbGVTdWJ0eXBlKSB7CgkJZGVmYXVsdDoKCQljYXNlIFZGVDJfVU5LTk9XTjoKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJVTktOT1dOKCVsZCkiLHZmZmktPmR3RmlsZVN1YnR5cGUpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1BSSU5URVI6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiUFJJTlRFUiIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0tFWUJPQVJEOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIktFWUJPQVJEIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfTEFOR1VBR0U6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiTEFOR1VBR0UiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9ESVNQTEFZOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIkRJU1BMQVkiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9NT1VTRToKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJNT1VTRSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX05FVFdPUks6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiTkVUV09SSyIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1NZU1RFTToKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJTWVNURU0iKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9JTlNUQUxMQUJMRToKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJJTlNUQUxMQUJMRSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1NPVU5EOgoJCQlkcHJpbnRmX3ZlcihzdGRkZWIsIlNPVU5EIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfQ09NTToKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJDT01NIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfSU5QVVRNRVRIT0Q6CgkJCWRwcmludGZfdmVyKHN0ZGRlYiwiSU5QVVRNRVRIT0QiKTsKCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSBWRlRfRk9OVDoKCQlkcHJpbnRmX3ZlcihzdGRkZWIsImZpbGV0eXBlPUZPTlQuIik7CgkJc3dpdGNoICh2ZmZpLT5kd0ZpbGVTdWJ0eXBlKSB7CgkJZGVmYXVsdDoKCQkJZHByaW50Zl92ZXIoc3RkZGViLCJVTktOT1dOKCVsZCkiLHZmZmktPmR3RmlsZVN1YnR5cGUpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRk9OVF9SQVNURVI6ZHByaW50Zl92ZXIoc3RkZGViLCJSQVNURVIiKTticmVhazsKCQljYXNlIFZGVDJfRk9OVF9WRUNUT1I6ZHByaW50Zl92ZXIoc3RkZGViLCJWRUNUT1IiKTticmVhazsKCQljYXNlIFZGVDJfRk9OVF9UUlVFVFlQRTpkcHJpbnRmX3ZlcihzdGRkZWIsIlRSVUVUWVBFIik7YnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSBWRlRfVlhEOmRwcmludGZfdmVyKHN0ZGRlYiwiZmlsZXR5cGU9VlhEIik7YnJlYWs7CgljYXNlIFZGVF9TVEFUSUNfTElCOmRwcmludGZfdmVyKHN0ZGRlYiwiZmlsZXR5cGU9U1RBVElDX0xJQiIpO2JyZWFrOwoJfQoJZHByaW50Zl92ZXIoc3RkZGViLCJmaWxlZGF0YT0lbHguJWx4XG4iLHZmZmktPmR3RmlsZURhdGVNUyx2ZmZpLT5kd0ZpbGVEYXRlTFMpOwoJcmV0dXJuIGxlbjsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTMyQQkJCVtWRVJTSU9OLjFdICovCkRXT1JECkdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEoTFBDU1RSIGZpbGVuYW1lLExQRFdPUkQgaGFuZGxlKSB7CglkcHJpbnRmX3ZlcihzdGRkZWIsIkdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEoJXMsJXApXG4iLGZpbGVuYW1lLGhhbmRsZSk7CglyZXR1cm4gR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KGZpbGVuYW1lLGhhbmRsZSk7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUzMlcJCQlbVkVSU0lPTi4yXSAqLwpEV09SRCBHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJXKCBMUENXU1RSIGZpbGVuYW1lLCBMUERXT1JEIGhhbmRsZSApCnsKICAgIExQU1RSIHhmbiA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZmlsZW5hbWUgKTsKICAgIERXT1JEIHJldCA9IEdldEZpbGVWZXJzaW9uSW5mb1NpemUxNiggeGZuLCBoYW5kbGUgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB4Zm4gKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mbwkJCQlbVkVSLjddICovCkRXT1JEIApHZXRGaWxlVmVyc2lvbkluZm8xNihMUENTVFIgZmlsZW5hbWUsRFdPUkQgaGFuZGxlLERXT1JEIGRhdGFzaXplLExQVk9JRCBkYXRhKSB7CglkcHJpbnRmX3ZlcihzdGRkZWIsIkdldEZpbGVWZXJzaW9uSW5mbzE2KCVzLCVsZCwlbGQsJXApXG4tPiIsCgkJZmlsZW5hbWUsaGFuZGxlLGRhdGFzaXplLGRhdGEKCSk7CglyZXR1cm4gR2V0RmlsZVJlc291cmNlKAoJCWZpbGVuYW1lLFZTX0ZJTEVfSU5GTyxWU19WRVJTSU9OX0lORk8saGFuZGxlLGRhdGFzaXplLGRhdGEKCSk7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb0EJCQkJW1ZFUlNJT04uMF0gKi8KRFdPUkQgCkdldEZpbGVWZXJzaW9uSW5mbzMyQShMUENTVFIgZmlsZW5hbWUsRFdPUkQgaGFuZGxlLERXT1JEIGRhdGFzaXplLExQVk9JRCBkYXRhKSB7CglyZXR1cm4gR2V0RmlsZVZlcnNpb25JbmZvMTYoZmlsZW5hbWUsaGFuZGxlLGRhdGFzaXplLGRhdGEpOwp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm9XCQkJCVtWRVJTSU9OLjNdICovCkRXT1JEIEdldEZpbGVWZXJzaW9uSW5mbzMyVyggTFBDV1NUUiBmaWxlbmFtZSwgRFdPUkQgaGFuZGxlLCBEV09SRCBkYXRhc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgZGF0YSkKewogICAgTFBTVFIgZm4gPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIGZpbGVuYW1lICk7CiAgICBEV09SRCByZXQgPSBHZXRGaWxlVmVyc2lvbkluZm8xNiggZm4sIGhhbmRsZSwgZGF0YXNpemUsIGRhdGEgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBmbiApOwogICAgcmV0dXJuIHJldDsKfQoKLyogVmVyRmluZEZpbGUJCQkJW1ZFUi44XSAqLwpEV09SRApWZXJGaW5kRmlsZTE2KAoJVUlOVDE2IGZsYWdzLExQQ1NUUiBmaWxlbmFtZSxMUENTVFIgd2luZGlyLExQQ1NUUiBhcHBkaXIsCglMUFNUUiBjdXJkaXIsVUlOVDE2ICpjdXJkaXJsZW4sTFBTVFIgZGVzdGRpcixVSU5UMTYgKmRlc3RkaXJsZW4KKSB7CglkcHJpbnRmX3ZlcihzdGRkZWIsIlZlckZpbmRGaWxlKCV4LCVzLCVzLCVzLCVwLCVkLCVwLCVkKVxuIiwKCQlmbGFncyxmaWxlbmFtZSx3aW5kaXIsYXBwZGlyLGN1cmRpciwqY3VyZGlybGVuLGRlc3RkaXIsKmRlc3RkaXJsZW4KCSk7CglzdHJjcHkoY3VyZGlyLCJaOlxcUk9PVFxcLldJTkVcXCIpOy8qRklYTUUqLwoJKmN1cmRpcmxlbj1zdHJsZW4oY3VyZGlyKTsKCXN0cmNweShkZXN0ZGlyLCJaOlxcUk9PVFxcLldJTkVcXCIpOy8qRklYTUUqLwoJKmRlc3RkaXJsZW49c3RybGVuKGRlc3RkaXIpOwoJcmV0dXJuIDA7Cn0KCi8qIFZlckZpbmRGaWxlQQkJCQkJCVtWRVJTSU9OLjVdICovCkRXT1JEClZlckZpbmRGaWxlMzJBKAoJVUlOVDMyIGZsYWdzLExQQ1NUUiBmaWxlbmFtZSxMUENTVFIgd2luZGlyLExQQ1NUUiBhcHBkaXIsCglMUFNUUiBjdXJkaXIsVUlOVDMyICpwY3VyZGlybGVuLExQU1RSIGRlc3RkaXIsVUlOVDMyICpwZGVzdGRpcmxlbiApCnsKICAgIFVJTlQxNiBjdXJkaXJsZW4sIGRlc3RkaXJsZW47CiAgICBEV09SRCByZXQgPSBWZXJGaW5kRmlsZTE2KGZsYWdzLGZpbGVuYW1lLHdpbmRpcixhcHBkaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cmRpciwmY3VyZGlybGVuLGRlc3RkaXIsJmRlc3RkaXJsZW4pOwogICAgKnBjdXJkaXJsZW4gPSBjdXJkaXJsZW47CiAgICAqcGRlc3RkaXJsZW4gPSBkZXN0ZGlybGVuOwogICAgcmV0dXJuIHJldDsKfQoKLyogVmVyRmluZEZpbGVXCQkJCQkJW1ZFUlNJT04uNl0gKi8KRFdPUkQKVmVyRmluZEZpbGUzMlcoCglVSU5UMzIgZmxhZ3MsTFBDV1NUUiBmaWxlbmFtZSxMUENXU1RSIHdpbmRpcixMUENXU1RSIGFwcGRpciwKCUxQV1NUUiBjdXJkaXIsVUlOVDMyICpwY3VyZGlybGVuLExQV1NUUiBkZXN0ZGlyLFVJTlQzMiAqcGRlc3RkaXJsZW4gKQp7CiAgICBVSU5UMTYgY3VyZGlybGVuLCBkZXN0ZGlybGVuOwogICAgTFBTVFIgd2ZuLHd3ZCx3YWQsd2RkLHdjZDsKICAgIERXT1JEIHJldDsKCiAgICB3Zm4gPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIGZpbGVuYW1lICk7CiAgICB3d2QgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdpbmRpciApOwogICAgd2FkID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcHBkaXIgKTsKICAgIHdjZCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKnBjdXJkaXJsZW4gKTsKICAgIHdkZCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKnBkZXN0ZGlybGVuICk7CiAgICByZXQgPSBWZXJGaW5kRmlsZTE2KGZsYWdzLHdmbix3d2Qsd2FkLHdjZCwmY3VyZGlybGVuLHdkZCwmZGVzdGRpcmxlbik7CiAgICBsc3RyY3B5bkF0b1coY3VyZGlyLHdjZCwqcGN1cmRpcmxlbik7CiAgICBsc3RyY3B5bkF0b1coZGVzdGRpcix3ZGQsKnBkZXN0ZGlybGVuKTsKICAgICpwY3VyZGlybGVuID0gc3RybGVuKHdjZCk7CiAgICAqcGRlc3RkaXJsZW4gPSBzdHJsZW4od2RkKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3Zm4gKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3d2QgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3YWQgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3Y2QgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3ZGQgKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIFZlckluc3RhbGxGaWxlCQkJCQlbVkVSLjldICovCkRXT1JEClZlckluc3RhbGxGaWxlMTYoCglVSU5UMTYgZmxhZ3MsTFBDU1RSIHNyY2ZpbGVuYW1lLExQQ1NUUiBkZXN0ZmlsZW5hbWUsTFBDU1RSIHNyY2RpciwKCUxQQ1NUUiBkZXN0ZGlyLExQU1RSIHRtcGZpbGUsVUlOVDE2ICp0bXBmaWxlbGVuCikgewoJZHByaW50Zl92ZXIoc3RkZGViLCJWZXJJbnN0YWxsRmlsZSgleCwlcywlcywlcywlcywlcCwlZClcbiIsCgkJZmxhZ3Msc3JjZmlsZW5hbWUsZGVzdGZpbGVuYW1lLHNyY2RpcixkZXN0ZGlyLHRtcGZpbGUsKnRtcGZpbGVsZW4KCSk7CgoJLyogRklYTUU6IEltcGxlbWVudGF0aW9uIHN0aWxsIG1pc3NpbmcgLi4uLiAqLwoKCXJldHVybiBWSUZfU1JDT0xEOwp9CgovKiBWZXJGaW5kRmlsZUEJCQkJCVtWRVJTSU9OLjVdICovCkRXT1JEClZlckluc3RhbGxGaWxlMzJBKAoJVUlOVDMyIGZsYWdzLExQQ1NUUiBzcmNmaWxlbmFtZSxMUENTVFIgZGVzdGZpbGVuYW1lLExQQ1NUUiBzcmNkaXIsCglMUENTVFIgZGVzdGRpcixMUFNUUiB0bXBmaWxlLFVJTlQzMiAqdG1wZmlsZWxlbiApCnsKICAgIFVJTlQxNiBmaWxlbGVuOwogICAgRFdPUkQgcmV0PSBWZXJJbnN0YWxsRmlsZTE2KGZsYWdzLHNyY2ZpbGVuYW1lLGRlc3RmaWxlbmFtZSxzcmNkaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGRpcix0bXBmaWxlLCZmaWxlbGVuKTsKICAgICp0bXBmaWxlbGVuID0gZmlsZWxlbjsKICAgIHJldHVybiByZXQ7Cn0KCi8qIFZlckZpbmRGaWxlVwkJCQkJW1ZFUlNJT04uNl0gKi8KRFdPUkQKVmVySW5zdGFsbEZpbGUzMlcoCglVSU5UMzIgZmxhZ3MsTFBDV1NUUiBzcmNmaWxlbmFtZSxMUENXU1RSIGRlc3RmaWxlbmFtZSxMUENXU1RSIHNyY2RpciwKCUxQQ1dTVFIgZGVzdGRpcixMUFdTVFIgdG1wZmlsZSxVSU5UMzIgKnRtcGZpbGVsZW4gKQp7CiAgICBMUFNUUiB3c3JjZix3c3JjZCx3ZGVzdGYsd2Rlc3RkLHd0bXBmOwogICAgRFdPUkQgcmV0OwoKICAgIHdzcmNmICA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjZmlsZW5hbWUgKTsKICAgIHdzcmNkICA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjZGlyICk7CiAgICB3ZGVzdGYgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIGRlc3RmaWxlbmFtZSApOwogICAgd2Rlc3RkID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0ZGlyICk7CiAgICB3dG1wZiAgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHRtcGZpbGUgKTsKICAgIHJldCA9IFZlckluc3RhbGxGaWxlMzJBKGZsYWdzLHdzcmNmLHdkZXN0Zix3c3JjZCx3ZGVzdGQsd3RtcGYsdG1wZmlsZWxlbik7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd3NyY2YgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3c3JjZCApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdkZXN0ZiApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdkZXN0ZCApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHd0bXBmICk7CiAgICByZXR1cm4gcmV0Owp9CgovKiBGSVhNRTogVGhpcyB0YWJsZSBzaG91bGQsIG9mIGNvdXJzZSwgYmUgbGFuZ3VhZ2UgZGVwZW5kZW5kICovCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbWFwX2lkMnN0ciB7CglVSU5UCWxhbmdpZDsKCWNvbnN0IGNoYXIgKmxhbmduYW1lOwp9IGxhbmd1YWdlc1tdPXsKCXsweDA0MDEsIkFyYWJpc2NoIn0sCgl7MHgwNDAyLCJCdWxnYXJpc2NoIn0sCgl7MHgwNDAzLCJLYXRhbGFuaXNjaCJ9LAoJezB4MDQwNCwiVHJhZGl0aW9uYWxlcyBDaGluZXNpc2NoIn0sCgl7MHgwNDA1LCJUc2NoZWNpc2NoIn0sCgl7MHgwNDA2LCJE5G5pc2NoIn0sCgl7MHgwNDA3LCJEZXV0c2NoIn0sCgl7MHgwNDA4LCJHcmllY2hpc2NoIn0sCgl7MHgwNDA5LCJBbWVyaWthbmlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDQwQSwiS2FzdGlsaXNjaGVzIFNwYW5pc2NoIn0sCgl7MHgwNDBCLCJGaW5uaXNjaCJ9LAoJezB4MDQwQywiRnJhbnr2c2lzY2gifSwKCXsweDA0MEQsIkhlYnLkaXNjaCJ9LAoJezB4MDQwRSwiVW5nYXJpc2NoIn0sCgl7MHgwNDBGLCJJc2zkbmRpc2NoIn0sCgl7MHgwNDEwLCJJdGFsaWVuaXNjaCJ9LAoJezB4MDQxMSwiSmFwYW5pc2NoIn0sCgl7MHgwNDEyLCJLb3JlYW5pc2NoIn0sCgl7MHgwNDEzLCJOaWVkZXJs5G5kaXNjaCJ9LAoJezB4MDQxNCwiTm9yd2VnaXNjaC1Cb2ttYWwifSwKCXsweDA0MTUsIlBvbG5pc2NoIn0sCgl7MHgwNDE2LCJCcmFzaWxpYW5pc2NoZXMgUG9ydHVnaWVzaXNjaCJ9LAoJezB4MDQxNywiUuR0b3JvbWFuaXNjaCJ9LAoJezB4MDQxOCwiUnVt5G5pc2NoIn0sCgl7MHgwNDE5LCJSdXNzaXNjaCJ9LAoJezB4MDQxQSwiS3JvYXRvc2VyYmlzY2ggKGxhdGVpbmlzY2gpIn0sCgl7MHgwNDFCLCJTbG93ZW5pc2NoIn0sCgl7MHgwNDFDLCJBbGJhbmlzY2gifSwKCXsweDA0MUQsIlNjaHdlZGlzY2gifSwKCXsweDA0MUUsIlRoYWkifSwKCXsweDA0MUYsIlT8cmtpc2NoIn0sCgl7MHgwNDIwLCJVcmR1In0sCgl7MHgwNDIxLCJCYWhhc2EifSwKCXsweDA4MDQsIlZlcmVpbmZhY2h0ZXMgQ2hpbmVzaXNjaCJ9LAoJezB4MDgwNywiU2Nod2VpemVyZGV1dHNjaCJ9LAoJezB4MDgwOSwiQnJpdGlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDgwQSwiTWV4aWthbmlzY2hlcyBTcGFuaXNjaCJ9LAoJezB4MDgwQywiQmVsZ2lzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDgxMCwiU2Nod2VpemVyaXNjaGVzIEl0YWxpZW5pc2NoIn0sCgl7MHgwODEzLCJCZWxnaXNjaGVzIE5pZWRlcmzkbmRpc2NoIn0sCgl7MHgwODE0LCJOb3Jnd2VnaXNjaC1OeW5vcnNrIn0sCgl7MHgwODE2LCJQb3J0dWdpZXNpc2NoIn0sCgl7MHgwODFBLCJTZXJib2tyYXRpc2NoIChreXJpbGxpc2NoKSJ9LAoJezB4MEMxQywiS2FuYWRpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDEwMEMsIlNjaHdlaXplcmlzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDAwMCwiVW5iZWthbm50In0sCn07CgovKiBWZXJMYW5ndWFnZU5hbWUJCQkJW1ZFUi4xMF0gKi8KRFdPUkQKVmVyTGFuZ3VhZ2VOYW1lMTYoVUlOVDE2IGxhbmdpZCxMUFNUUiBsYW5nbmFtZSxVSU5UMTYgbGFuZ25hbWVsZW4pIHsKCWludAlpOwoJY2hhcgkqYnVmOwoKCWRwcmludGZfdmVyKHN0ZGRlYiwiVmVyTGFuZ3VhZ2VOYW1lKCVkLCVwLCVkKVxuIixsYW5naWQsbGFuZ25hbWUsbGFuZ25hbWVsZW4pOwoJLyogRmlyc3QsIGNoZWNrIFxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXRcY29udHJvbFxObHNcTG9jYWxlXDxsYW5naWQ+CgkgKiBmcm9tIHRoZSByZWdpc3RyeS4gCgkgKi8KCWJ1Zj0oY2hhciopbWFsbG9jKHN0cmxlbigiXFxTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxjb250cm9sXFxObHNcXExvY2FsZVxcIikrOSk7CglzcHJpbnRmKGJ1ZiwiXFxTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxjb250cm9sXFxObHNcXExvY2FsZVxcJTA4eCIsbGFuZ2lkKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdRdWVyeVZhbHVlMTYoSEtFWV9MT0NBTF9NQUNISU5FLGJ1ZixsYW5nbmFtZSwoTFBEV09SRCkmbGFuZ25hbWVsZW4pKSB7CgkJbGFuZ25hbWVbbGFuZ25hbWVsZW4tMV09J1wwJzsKCQlyZXR1cm4gbGFuZ25hbWVsZW47Cgl9CgkvKiBpZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGludGVyYWwgdGFibGUgKi8KCWZvciAoaT0wO2xhbmd1YWdlc1tpXS5sYW5naWQhPTA7aSsrKQoJCWlmIChsYW5naWQ9PWxhbmd1YWdlc1tpXS5sYW5naWQpCgkJCWJyZWFrOwoJc3RybmNweShsYW5nbmFtZSxsYW5ndWFnZXNbaV0ubGFuZ25hbWUsbGFuZ25hbWVsZW4pOwoJbGFuZ25hbWVbbGFuZ25hbWVsZW4tMV09J1wwJzsKCXJldHVybiBzdHJsZW4obGFuZ3VhZ2VzW2ldLmxhbmduYW1lKTsKfQoKLyogVmVyTGFuZ3VhZ2VOYW1lQQkJCQlbVkVSU0lPTi45XSAqLwpEV09SRApWZXJMYW5ndWFnZU5hbWUzMkEoVUlOVDMyIGxhbmdpZCxMUFNUUiBsYW5nbmFtZSxVSU5UMzIgbGFuZ25hbWVsZW4pIHsKCXJldHVybiBWZXJMYW5ndWFnZU5hbWUxNihsYW5naWQsbGFuZ25hbWUsbGFuZ25hbWVsZW4pOwp9CgovKiBWZXJMYW5ndWFnZU5hbWVXCQkJCVtWRVJTSU9OLjEwXSAqLwpEV09SRApWZXJMYW5ndWFnZU5hbWUzMlcoVUlOVDMyIGxhbmdpZCxMUFdTVFIgbGFuZ25hbWUsVUlOVDMyIGxhbmduYW1lbGVuKSB7CglpbnQJaTsKCWNoYXIJYnVmZmVyWzgwXTsKCUxQV1NUUglrZXluYW1lOwoKCS8qIEZpcnN0LCBjaGVjayBcU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0XGNvbnRyb2xcTmxzXExvY2FsZVw8bGFuZ2lkPgoJICogZnJvbSB0aGUgcmVnaXN0cnkuIAoJICovCglzcHJpbnRmKGJ1ZmZlciwiXFxTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxjb250cm9sXFxObHNcXExvY2FsZVxcJTA4eCIsbGFuZ2lkKTsKCWtleW5hbWUgPSBIRUFQX3N0cmR1cEF0b1coIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlciApOwoJaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ1F1ZXJ5VmFsdWUzMlcoSEtFWV9MT0NBTF9NQUNISU5FLGtleW5hbWUsbGFuZ25hbWUsKExQRFdPUkQpJmxhbmduYW1lbGVuKSkgewoJCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBrZXluYW1lICk7CgkJcmV0dXJuIGxhbmduYW1lbGVuOwoJfQogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBrZXluYW1lICk7CgkvKiBpZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGludGVyYWwgdGFibGUgKi8KCWZvciAoaT0wO2xhbmd1YWdlc1tpXS5sYW5naWQhPTA7aSsrKQoJCWlmIChsYW5naWQ9PWxhbmd1YWdlc1tpXS5sYW5naWQpCgkJCWJyZWFrOwogICAgICAgIGxzdHJjcHlBdG9XKCBsYW5nbmFtZSwgbGFuZ3VhZ2VzW2ldLmxhbmduYW1lICk7CglyZXR1cm4gc3RybGVuKGxhbmd1YWdlc1tpXS5sYW5nbmFtZSk7IC8qIHNhbWUgYXMgc3RybGVuVyhsYW5nbmFtZSk7ICovCn0KCi8qIEZJWE1FOiBVTklDT0RFPyAqLwpzdHJ1Y3QgZGIgewoJV09SRAluZXh0b2ZmOwoJV09SRAlkYXRhbGVuOwovKiBpbiBtZW1vcnkgc3RydWN0dXJlLi4uICovCgljaGFyCW5hbWVbMV07IAkvKiBwYWRkZWQgdG8gZHdvcmQgYWxpZ25tZW50ICovCi8qIC4uLi4gCgljaGFyCWRhdGFbZGF0YWxlbl07ICAgICBwYWRkZWQgdG8gZHdvcmQgYWxpZ25lbW50CglCWVRFCXN1YmRpcmRhdGFbXTsgICAgICB1bnRpbCBuZXh0b2ZmCiAqLwp9OwoKc3RhdGljIEJZVEUqCl9maW5kX2RhdGEoQllURSAqYmxvY2ssTFBDU1RSIHN0cikgewoJY2hhcgkqbmV4dHNsYXNoOwoJaW50CXN1YnN0cmxlbjsKCXN0cnVjdAlkYgkqZGI7CgoJd2hpbGUgKCpzdHIgJiYgKnN0cj09J1xcJykKCQlzdHIrKzsKCWlmIChOVUxMIT0obmV4dHNsYXNoPXN0cmNocihzdHIsJ1xcJykpKQoJCXN1YnN0cmxlbj1uZXh0c2xhc2gtc3RyOwoJZWxzZQoJCXN1YnN0cmxlbj1zdHJsZW4oc3RyKTsKCWlmIChuZXh0c2xhc2ghPU5VTEwpIHsKCQl3aGlsZSAoKm5leHRzbGFzaCAmJiAqbmV4dHNsYXNoPT0nXFwnKQoJCQluZXh0c2xhc2grKzsKCQlpZiAoISpuZXh0c2xhc2gpCgkJCW5leHRzbGFzaD1OVUxMOwoJfQoKCgl3aGlsZSAoMSkgewoJCWRiPShzdHJ1Y3QgZGIqKWJsb2NrOwoJCWRwcmludGZfdmVyKHN0ZGRlYiwiZGI9JXAsZGItPm5leHRvZmY9JWQsZGItPmRhdGFsZW49JWQsZGItPm5hbWU9JXMsZGItPmRhdGE9JXNcbiIsCgkJCWRiLGRiLT5uZXh0b2ZmLGRiLT5kYXRhbGVuLGRiLT5uYW1lLChjaGFyKikoKGNoYXIqKWRiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKSkKCQkpOwoJCWlmICghZGItPm5leHRvZmYpCgkJCXJldHVybiBOVUxMOwoKCQlkcHJpbnRmX3ZlcihzdGRkZWIsImNvbXBhcmluZyB3aXRoICVzXG4iLGRiLT5uYW1lKTsKCQlpZiAoIXN0cm5jbXAoZGItPm5hbWUsc3RyLHN1YnN0cmxlbikpIHsKCQkJaWYgKG5leHRzbGFzaCkKCQkJCXJldHVybiBfZmluZF9kYXRhKAoJCQkJCWJsb2NrKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKSsoKGRiLT5kYXRhbGVuKzMpJn4zKQoJCQkJCSxuZXh0c2xhc2gKCQkJCSk7CgkJCWVsc2UKCQkJCXJldHVybiBibG9jazsKCQl9CgkJYmxvY2s9YmxvY2srKChkYi0+bmV4dG9mZiszKSZ+Myk7Cgl9Cn0KCi8qIFZlclF1ZXJ5VmFsdWUgCQkJW1ZFUi4xMV0gKi8KLyogdGFrZSBjYXJlLCAnYnVmZmVyJyBpcyBOT1QgYSBTRUdQVFIsIGl0IGp1c3QgcG9pbnRzIHRvIG9uZSAqLwpEV09SRApWZXJRdWVyeVZhbHVlMTYoU0VHUFRSIHNlZ2Jsb2NrLExQQ1NUUiBzdWJibG9jayxTRUdQVFIgKmJ1ZmZlcixVSU5UMTYgKmJ1ZmxlbikKewoJQllURQkqYmxvY2s9UFRSX1NFR19UT19MSU4oc2VnYmxvY2spLCpiOwoJc3RydWN0CWRiCSpkYjsKCWNoYXIJKnM7CgoJZHByaW50Zl92ZXIoc3RkZGViLCJWZXJRdWVyeVZhbHVlMTYoJXAsJXMsJXAsJWQpXG4iLAoJCWJsb2NrLHN1YmJsb2NrLGJ1ZmZlciwqYnVmbGVuCgkpOwoJcz0oY2hhciopeG1hbGxvYyhzdHJsZW4oIlZTX1ZFUlNJT05fSU5GT1xcIikrc3RybGVuKHN1YmJsb2NrKSsxKTsKCXN0cmNweShzLCJWU19WRVJTSU9OX0lORk9cXCIpO3N0cmNhdChzLHN1YmJsb2NrKTsKCWI9X2ZpbmRfZGF0YShibG9jayxzKTsKCWlmIChiPT1OVUxMKSB7CgkJKmJ1Zmxlbj0wOwoJCXJldHVybiAwOwoJfQoJZGI9KHN0cnVjdCBkYiopYjsKCSpidWZsZW4JPSBkYi0+ZGF0YWxlbjsKCS8qIGxldCBiIHBvaW50IHRvIGRhdGEgYXJlYSAqLwoJYgk9IGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmfjMpOwoJLyogbm93IGxvb2sgdXAgd2hhdCB0aGUgcmVzcC4gU0VHUFRSIHdvdWxkIGJlIC4uLiAqLwoJKmJ1ZmZlcgk9IChiLWJsb2NrKStzZWdibG9jazsKCWRwcmludGZfdmVyKHN0ZGRlYiwiCS0+ICVzPSVzXG4iLHN1YmJsb2NrLGIpOwoJcmV0dXJuIDE7Cn0KCkRXT1JEClZlclF1ZXJ5VmFsdWUzMkEoTFBWT0lEIHZibG9jayxMUENTVFIgc3ViYmxvY2ssTFBWT0lEICp2YnVmZmVyLFVJTlQzMiAqYnVmbGVuKQp7CglCWVRFCSpiLCpibG9jaz0oTFBCWVRFKXZibG9jaywqKmJ1ZmZlcj0oTFBCWVRFKil2YnVmZmVyOwoJc3RydWN0CWRiCSpkYjsKCWNoYXIJKnM7CgoJZHByaW50Zl92ZXIoc3RkZGViLCJWZXJRdWVyeVZhbHVlMzJBKCVwLCVzLCVwLCVkKVxuIiwKCQlibG9jayxzdWJibG9jayxidWZmZXIsKmJ1ZmxlbgoJKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk9cXCIpK3N0cmxlbihzdWJibG9jaykrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPXFwiKTtzdHJjYXQocyxzdWJibG9jayk7CgliPV9maW5kX2RhdGEoYmxvY2sscyk7CglpZiAoYj09TlVMTCkgewoJCSpidWZsZW49MDsKCQlyZXR1cm4gMDsKCX0KCWRiPShzdHJ1Y3QgZGIqKWI7CgkqYnVmbGVuCT0gZGItPmRhdGFsZW47CgkvKiBsZXQgYiBwb2ludCB0byBkYXRhIGFyZWEgKi8KCWIJPSBiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKTsKCSpidWZmZXIJPSBiOwoJZHByaW50Zl92ZXIoc3RkZGViLCIJLT4gJXM9JXNcbiIsc3ViYmxvY2ssYik7CglyZXR1cm4gMTsKfQoKRFdPUkQKVmVyUXVlcnlWYWx1ZTMyVyhMUFZPSUQgdmJsb2NrLExQQ1dTVFIgc3ViYmxvY2ssTFBWT0lEICp2YnVmZmVyLFVJTlQzMiAqYnVmbGVuKQp7CgkvKiBGSVhNRTogaG1tLCB3ZSBub3Qgb25seSBuZWVkIHRvIGNvbnZlcnQgc3ViYmxvY2ssIGJ1dCBhbHNvIAoJICogICAgICAgIHRoZSBjb250ZW50Li4ub3I/CgkgKiBBbmQgd2hhdCBhYm91dCBVTklDT0RFIHZlcnNpb24gaW5mbz8KCSAqIEFuZCB0aGUgTkFNRVMgb2YgdGhlIHZhbHVlcz8KCSAqLwoJQllURQkJKmIsKipidWZmZXI9KExQQllURSopdmJ1ZmZlciwqYmxvY2s9KExQQllURSl2YmxvY2s7CglzdHJ1Y3QJZGIJKmRiOwoJY2hhcgkJKnMsKnNiOwoKCXNiID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdWJibG9jayApOwoJcz0oY2hhciopeG1hbGxvYyhzdHJsZW4oIlZTX1ZFUlNJT05fSU5GT1xcIikrc3RybGVuKHNiKSsxKTsKCXN0cmNweShzLCJWU19WRVJTSU9OX0lORk9cXCIpO3N0cmNhdChzLHNiKTsKCWI9X2ZpbmRfZGF0YShibG9jayxzKTsKCWlmIChiPT1OVUxMKSB7CgkJKmJ1Zmxlbj0wOwoJCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzYiApOwoJCXJldHVybiAwOwoJfQoJZGI9KHN0cnVjdCBkYiopYjsKCSpidWZsZW4JPSBkYi0+ZGF0YWxlbjsKCS8qIGxldCBiIHBvaW50IHRvIGRhdGEgYXJlYSAqLwoJYgk9IGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmfjMpOwoJKmJ1ZmZlcgk9IGI7CglkcHJpbnRmX3ZlcihzdGRkZWIsIgktPiAlcz0lc1xuIixzYixiKTsKICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2IgKTsKCXJldHVybiAxOwp9Ci8qIDIwIEdFVEZJTEVWRVJTSU9OSU5GT1JBVyAqLwo=