LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAicnBjX3NlcnZlci5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCiNpbmNsdWRlICJuY2FzdGF0dXMuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHJwYyk7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjUGFja2V0CnsKICBzdHJ1Y3QgX1JwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUnBjUGt0SGRyKiBoZHI7CiAgUlBDX01FU1NBR0UqIG1zZzsKfSBScGNQYWNrZXQ7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjT2JqVHlwZU1hcAp7CiAgLyogRklYTUU6IGEgaGFzaCB0YWJsZSB3b3VsZCBiZSBiZXR0ZXIuICovCiAgc3RydWN0IF9ScGNPYmpUeXBlTWFwICpuZXh0OwogIFVVSUQgT2JqZWN0OwogIFVVSUQgVHlwZTsKfSBScGNPYmpUeXBlTWFwOwoKc3RhdGljIFJwY09ialR5cGVNYXAgKlJwY09ialR5cGVNYXBzOwoKLyogbGlzdCBvZiB0eXBlIFJwY1NlcnZlclByb3RzZXEgKi8Kc3RhdGljIHN0cnVjdCBsaXN0IHByb3RzZXFzID0gTElTVF9JTklUKHByb3RzZXFzKTsKc3RhdGljIHN0cnVjdCBsaXN0IHNlcnZlcl9pbnRlcmZhY2VzID0gTElTVF9JTklUKHNlcnZlcl9pbnRlcmZhY2VzKTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgc2VydmVyX2NzX2RlYnVnID0KewogICAgMCwgMCwgJnNlcnZlcl9jcywKICAgIHsgJnNlcnZlcl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmc2VydmVyX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBzZXJ2ZXJfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jcyA9IHsgJnNlcnZlcl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgbGlzdGVuX2NzX2RlYnVnID0KewogICAgMCwgMCwgJmxpc3Rlbl9jcywKICAgIHsgJmxpc3Rlbl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmbGlzdGVuX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBsaXN0ZW5fY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jcyA9IHsgJmxpc3Rlbl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCi8qIHdoZXRoZXIgdGhlIHNlcnZlciBpcyBjdXJyZW50bHkgbGlzdGVuaW5nICovCnN0YXRpYyBCT09MIHN0ZF9saXN0ZW47Ci8qIG51bWJlciBvZiBtYW51YWwgbGlzdGVuZXJzIChjYWxscyB0byBScGNTZXJ2ZXJMaXN0ZW4pICovCnN0YXRpYyBMT05HIG1hbnVhbF9saXN0ZW5fY291bnQ7Ci8qIHRvdGFsIGxpc3RlbmVycyBpbmNsdWRpbmcgYXV0byBsaXN0ZW5lcnMgKi8Kc3RhdGljIExPTkcgbGlzdGVuX2NvdW50OwoKc3RhdGljIFVVSUQgdXVpZF9uaWw7CgpzdGF0aWMgaW5saW5lIFJwY09ialR5cGVNYXAgKkxvb2t1cE9ialR5cGVNYXAoVVVJRCAqT2JqVXVpZCkKewogIFJwY09ialR5cGVNYXAgKnJzbHQgPSBScGNPYmpUeXBlTWFwczsKICBSUENfU1RBVFVTIGR1bW15OwoKICB3aGlsZSAocnNsdCkgewogICAgaWYgKCEgVXVpZENvbXBhcmUoT2JqVXVpZCwgJnJzbHQtPk9iamVjdCwgJmR1bW15KSkgYnJlYWs7CiAgICByc2x0ID0gcnNsdC0+bmV4dDsKICB9CgogIHJldHVybiByc2x0Owp9CgpzdGF0aWMgaW5saW5lIFVVSUQgKkxvb2t1cE9ialR5cGUoVVVJRCAqT2JqVXVpZCkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IExvb2t1cE9ialR5cGVNYXAoT2JqVXVpZCk7CiAgaWYgKG1hcCkKICAgIHJldHVybiAmbWFwLT5UeXBlOwogIGVsc2UKICAgIHJldHVybiAmdXVpZF9uaWw7Cn0KCnN0YXRpYyBScGNTZXJ2ZXJJbnRlcmZhY2UqIFJQQ1JUNF9maW5kX2ludGVyZmFjZShVVUlEKiBvYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIqIGlmX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBjaGVja19vYmplY3QpCnsKICBVVUlEKiBNZ3JUeXBlID0gTlVMTDsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIGNpZjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgaWYgKGNoZWNrX29iamVjdCkKICAgIE1nclR5cGUgPSBMb29rdXBPYmpUeXBlKG9iamVjdCk7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgTElTVF9GT1JfRUFDSF9FTlRSWShjaWYsICZzZXJ2ZXJfaW50ZXJmYWNlcywgUnBjU2VydmVySW50ZXJmYWNlLCBlbnRyeSkgewogICAgaWYgKCFtZW1jbXAoaWZfaWQsICZjaWYtPklmLT5JbnRlcmZhY2VJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpICYmCiAgICAgICAgKGNoZWNrX29iamVjdCA9PSBGQUxTRSB8fCBVdWlkRXF1YWwoTWdyVHlwZSwgJmNpZi0+TWdyVHlwZVV1aWQsICZzdGF0dXMpKSAmJgogICAgICAgIHN0ZF9saXN0ZW4pIHsKICAgICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJmNpZi0+Q3VycmVudENhbGxzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIGlmICgmY2lmLT5lbnRyeSA9PSAmc2VydmVyX2ludGVyZmFjZXMpIGNpZiA9IE5VTEw7CiAgVFJBQ0UoInJldHVybmluZyAlcCBmb3IgJXNcbiIsIGNpZiwgZGVidWdzdHJfZ3VpZChvYmplY3QpKTsKICByZXR1cm4gY2lmOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfcmVsZWFzZV9zZXJ2ZXJfaW50ZXJmYWNlKFJwY1NlcnZlckludGVyZmFjZSAqc2lmKQp7CiAgaWYgKCFJbnRlcmxvY2tlZERlY3JlbWVudCgmc2lmLT5DdXJyZW50Q2FsbHMpICYmCiAgICAgIHNpZi0+Q2FsbHNDb21wbGV0ZWRFdmVudCkgewogICAgLyogc2lmIG11c3QgaGF2ZSBiZWVuIHJlbW92ZWQgZnJvbSBzZXJ2ZXJfaW50ZXJmYWNlcyBiZWZvcmUKICAgICAqIENhbGxzQ29tcGxldGVkRXZlbnQgaXMgc2V0ICovCiAgICBTZXRFdmVudChzaWYtPkNhbGxzQ29tcGxldGVkRXZlbnQpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2lmKTsKICB9Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIocnBjX2ZpbHRlcikKewogIFdBUk4oImV4Y2VwdGlvbiBjYXVnaHQgd2l0aCBjb2RlIDB4JTA4eCA9ICVkXG4iLCBHZXRFeGNlcHRpb25Db2RlKCksIEdldEV4Y2VwdGlvbkNvZGUoKSk7CiAgVFJBQ0UoInJldHVybmluZyBmYWlsdXJlIHBhY2tldFxuIik7CiAgLyogY2F0Y2ggZXZlcnkgZXhjZXB0aW9uICovCiAgcmV0dXJuIEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChScGNDb25uZWN0aW9uKiBjb25uLCBScGNQa3RIZHIqIGhkciwgUlBDX01FU1NBR0UqIG1zZykKewogIFJwY1NlcnZlckludGVyZmFjZSogc2lmOwogIFJQQ19ESVNQQVRDSF9GVU5DVElPTiBmdW5jOwogIFVVSUQgKm9iamVjdF91dWlkOwogIFJwY1BrdEhkciAqcmVzcG9uc2UgPSBOVUxMOwogIHZvaWQgKmJ1ZiA9IG1zZy0+QnVmZmVyOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIEJPT0wgZXhjZXB0aW9uOwoKICBzd2l0Y2ggKGhkci0+Y29tbW9uLnB0eXBlKSB7CiAgICBjYXNlIFBLVF9CSU5EOgogICAgICBUUkFDRSgiZ290IGJpbmQgcGFja2V0XG4iKTsKCiAgICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcyEgKi8KICAgICAgaWYgKGhkci0+YmluZC5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFIHx8CiAgICAgICAgICAhVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICBUUkFDRSgicGFja2V0IHNpemUgbGVzcyB0aGFuIG1pbiBzaXplLCBvciBhY3RpdmUgaW50ZXJmYWNlIHN5bnRheCBndWlkIG5vbi1udWxsXG4iKTsKICAgICAgICBzaWYgPSBOVUxMOwogICAgICB9IGVsc2UgewogICAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShOVUxMLCAmaGRyLT5iaW5kLmFic3RyYWN0LCBGQUxTRSk7CiAgICAgIH0KICAgICAgaWYgKHNpZiA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoInJlamVjdGluZyBiaW5kIHJlcXVlc3Qgb24gY29ubmVjdGlvbiAlcFxuIiwgY29ubik7CiAgICAgICAgLyogUmVwb3J0IGZhaWx1cmUgdG8gY2xpZW50LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZE5hY2tIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfVkVSX01BSk9SLCBSUENfVkVSX01JTk9SKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiYWNjZXB0aW5nIGJpbmQgcmVxdWVzdCBvbiBjb25uZWN0aW9uICVwIGZvciAlc1xuIiwgY29ubiwKICAgICAgICAgICAgICBkZWJ1Z3N0cl9ndWlkKCZoZHItPmJpbmQuYWJzdHJhY3QuU3ludGF4R1VJRCkpOwoKICAgICAgICAvKiBhY2NlcHQuICovCiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRCaW5kQWNrSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5FbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVTVUxUX0FDQ0VQVCwgUkVBU09OX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzaWYtPklmLT5UcmFuc2ZlclN5bnRheCk7CgogICAgICAgIC8qIHNhdmUgdGhlIGludGVyZmFjZSBmb3IgbGF0ZXIgdXNlICovCiAgICAgICAgY29ubi0+QWN0aXZlSW50ZXJmYWNlID0gaGRyLT5iaW5kLmFic3RyYWN0OwogICAgICAgIGNvbm4tPk1heFRyYW5zbWlzc2lvblNpemUgPSBoZHItPmJpbmQubWF4X3RzaXplOwoKICAgICAgICBSUENSVDRfcmVsZWFzZV9zZXJ2ZXJfaW50ZXJmYWNlKHNpZik7CiAgICAgIH0KCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKTsKICAgICAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2UpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIGdvdG8gZmFpbDsKCiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUEtUX1JFUVVFU1Q6CiAgICAgIFRSQUNFKCJnb3QgcmVxdWVzdCBwYWNrZXRcbiIpOwoKICAgICAgLyogZmFpbCBpZiB0aGUgY29ubmVjdGlvbiBpc24ndCBib3VuZCB3aXRoIGFuIGludGVyZmFjZSAqLwogICAgICBpZiAoVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICAvKiBGSVhNRTogc2hvdWxkIHNlbmQgQmluZE5hY2sgaW5zdGVhZCAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwoKICAgICAgICBSUENSVDRfU2VuZChjb25uLCByZXNwb25zZSwgTlVMTCwgMCk7CiAgICAgICAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2UpOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICBpZiAoaGRyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX09CSkVDVF9VVUlEKSB7CiAgICAgICAgb2JqZWN0X3V1aWQgPSAoVVVJRCopKCZoZHItPnJlcXVlc3QgKyAxKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvYmplY3RfdXVpZCA9IE5VTEw7CiAgICAgIH0KCiAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShvYmplY3RfdXVpZCwgJmNvbm4tPkFjdGl2ZUludGVyZmFjZSwgVFJVRSk7CiAgICAgIGlmICghc2lmKSB7CiAgICAgICAgV0FSTigiaW50ZXJmYWNlICVzIG5vIGxvbmdlciByZWdpc3RlcmVkLCByZXR1cm5pbmcgZmF1bHQgcGFja2V0XG4iLCBkZWJ1Z3N0cl9ndWlkKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCkpOwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQ0FfU19VTktfSUYpOwoKICAgICAgICBSUENSVDRfU2VuZChjb25uLCByZXNwb25zZSwgTlVMTCwgMCk7CiAgICAgICAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2UpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24gPSBzaWYtPklmOwogICAgICAvKiBjb3B5IHRoZSBlbmRwb2ludCB2ZWN0b3IgZnJvbSBzaWYgdG8gbXNnIHNvIHRoYXQgbWlkbC1nZW5lcmF0ZWQgY29kZSB3aWxsIHVzZSBpdCAqLwogICAgICBtc2ctPk1hbmFnZXJFcHYgPSBzaWYtPk1nckVwdjsKICAgICAgaWYgKG9iamVjdF91dWlkICE9IE5VTEwpIHsKICAgICAgICBSUENSVDRfU2V0QmluZGluZ09iamVjdChtc2ctPkhhbmRsZSwgb2JqZWN0X3V1aWQpOwogICAgICB9CgogICAgICAvKiBmaW5kIGRpc3BhdGNoIGZ1bmN0aW9uICovCiAgICAgIG1zZy0+UHJvY051bSA9IGhkci0+cmVxdWVzdC5vcG51bTsKICAgICAgaWYgKHNpZi0+RmxhZ3MgJiBSUENfSUZfT0xFKSB7CiAgICAgICAgLyogbmF0aXZlIG9sZTMyIGFsd2F5cyBnaXZlcyB1cyBhIGRpc3BhdGNoIHRhYmxlIHdpdGggYSBzaW5nbGUgZW50cnkKICAgICAgICAgKiAoSSBhc3N1bWUgdGhhdCdzIGEgd3JhcHBlciBmb3IgSVJwY1N0dWJCdWZmZXI6Okludm9rZSkgKi8KICAgICAgICBmdW5jID0gKnNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG1zZy0+UHJvY051bSA+PSBzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlQ291bnQpIHsKICAgICAgICAgIFdBUk4oImludmFsaWQgcHJvY251bSAoJWQvJWQpXG4iLCBtc2ctPlByb2NOdW0sIHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCk7CiAgICAgICAgICByZXNwb25zZSA9IFJQQ1JUNF9CdWlsZEZhdWx0SGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQ0FfU19PUF9STkdfRVJST1IpOwoKICAgICAgICAgIFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKTsKICAgICAgICAgIFJQQ1JUNF9GcmVlSGVhZGVyKHJlc3BvbnNlKTsKICAgICAgICB9CiAgICAgICAgZnVuYyA9IHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbbXNnLT5Qcm9jTnVtXTsKICAgICAgfQoKICAgICAgLyogcHV0IGluIHRoZSBkcmVwLiBGSVhNRTogaXMgdGhpcyBtb3JlIHVuaXZlcnNhbGx5IGFwcGxpY2FibGU/CiAgICAgICAgIHBlcmhhcHMgd2Ugc2hvdWxkIG1vdmUgdGhpcyBvdXR3YXJkLi4uICovCiAgICAgIG1zZy0+RGF0YVJlcHJlc2VudGF0aW9uID0gCiAgICAgICAgTUFLRUxPTkcoIE1BS0VXT1JEKGhkci0+Y29tbW9uLmRyZXBbMF0sIGhkci0+Y29tbW9uLmRyZXBbMV0pLAogICAgICAgICAgICAgICAgICBNQUtFV09SRChoZHItPmNvbW1vbi5kcmVwWzJdLCBoZHItPmNvbW1vbi5kcmVwWzNdKSk7CgogICAgICBleGNlcHRpb24gPSBGQUxTRTsKCiAgICAgIC8qIGRpc3BhdGNoICovCiAgICAgIF9fVFJZIHsKICAgICAgICBpZiAoZnVuYykgZnVuYyhtc2cpOwogICAgICB9IF9fRVhDRVBUKHJwY19maWx0ZXIpIHsKICAgICAgICBleGNlcHRpb24gPSBUUlVFOwogICAgICAgIGlmIChHZXRFeGNlcHRpb25Db2RlKCkgPT0gU1RBVFVTX0FDQ0VTU19WSU9MQVRJT04pCiAgICAgICAgICAgIHN0YXR1cyA9IEVSUk9SX05PQUNDRVNTOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc3RhdHVzID0gR2V0RXhjZXB0aW9uQ29kZSgpOwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIobXNnLT5EYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUEMyTkNBX1NUQVRVUyhzdGF0dXMpKTsKICAgICAgfSBfX0VORFRSWQoKICAgICAgaWYgKCFleGNlcHRpb24pCiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRSZXNwb25zZUhlYWRlcihtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoKTsKCiAgICAgIC8qIHNlbmQgcmVzcG9uc2UgcGFja2V0ICovCiAgICAgIGlmIChyZXNwb25zZSkgewogICAgICAgIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBleGNlcHRpb24gPyBOVUxMIDogbXNnLT5CdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uID8gMCA6IG1zZy0+QnVmZmVyTGVuZ3RoKTsKICAgICAgICBSUENSVDRfRnJlZUhlYWRlcihyZXNwb25zZSk7CiAgICAgIH0gZWxzZQogICAgICAgIEVSUigib3V0IG9mIG1lbW9yeVxuIik7CgogICAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKICAgICAgUlBDUlQ0X3JlbGVhc2Vfc2VydmVyX2ludGVyZmFjZShzaWYpOwoKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBwYWNrZXQgdHlwZSAldVxuIiwgaGRyLT5jb21tb24ucHR5cGUpOwogICAgICBicmVhazsKICB9CgpmYWlsOgogIC8qIGNsZWFuIHVwICovCiAgaWYgKG1zZy0+QnVmZmVyID09IGJ1ZikgbXNnLT5CdWZmZXIgPSBOVUxMOwogIFRSQUNFKCJmcmVlaW5nIEJ1ZmZlcj0lcFxuIiwgYnVmKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYpOwogIFJQQ1JUNF9EZXN0cm95QmluZGluZyhtc2ctPkhhbmRsZSk7CiAgbXNnLT5IYW5kbGUgPSAwOwogIElfUnBjRnJlZUJ1ZmZlcihtc2cpOwogIG1zZy0+QnVmZmVyID0gTlVMTDsKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZyk7Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfd29ya2VyX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIFJwY1BhY2tldCAqcGt0ID0gdGhlX2FyZzsKICBSUENSVDRfcHJvY2Vzc19wYWNrZXQocGt0LT5jb25uLCBwa3QtPmhkciwgcGt0LT5tc2cpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBrdCk7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfaW9fdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgUnBjQ29ubmVjdGlvbiogY29ubiA9IChScGNDb25uZWN0aW9uKil0aGVfYXJnOwogIFJwY1BrdEhkciAqaGRyOwogIFJwY0JpbmRpbmcgKnBiaW5kOwogIFJQQ19NRVNTQUdFICptc2c7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGFja2V0ICpwYWNrZXQ7CgogIFRSQUNFKCIoJXApXG4iLCBjb25uKTsKCiAgZm9yICg7OykgewogICAgbXNnID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihSUENfTUVTU0FHRSkpOwoKICAgIC8qIGNyZWF0ZSB0ZW1wb3JhcnkgYmluZGluZyBmb3IgZGlzcGF0Y2gsIGl0IHdpbGwgYmUgZnJlZWQgaW4KICAgICAqIFJQQ1JUNF9wcm9jZXNzX3BhY2tldCAqLwogICAgUlBDUlQ0X01ha2VCaW5kaW5nKCZwYmluZCwgY29ubik7CiAgICBtc2ctPkhhbmRsZSA9IChSUENfQklORElOR19IQU5ETEUpcGJpbmQ7CgogICAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJmhkciwgbXNnKTsKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgICAgV0FSTigicmVjZWl2ZSBmYWlsZWQgd2l0aCBlcnJvciAlbHhcbiIsIHN0YXR1cyk7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZyk7CiAgICAgIGJyZWFrOwogICAgfQoKI2lmIDAKICAgIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChjb25uLCBoZHIsIG1zZyk7CiNlbHNlCiAgICBwYWNrZXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY1BhY2tldCkpOwogICAgcGFja2V0LT5jb25uID0gY29ubjsKICAgIHBhY2tldC0+aGRyID0gaGRyOwogICAgcGFja2V0LT5tc2cgPSBtc2c7CiAgICBRdWV1ZVVzZXJXb3JrSXRlbShSUENSVDRfd29ya2VyX3RocmVhZCwgcGFja2V0LCBXVF9FWEVDVVRFTE9OR0ZVTkNUSU9OKTsKI2VuZGlmCiAgICBtc2cgPSBOVUxMOwogIH0KICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oY29ubik7CiAgcmV0dXJuIDA7Cn0KCnZvaWQgUlBDUlQ0X25ld19jbGllbnQoUnBjQ29ubmVjdGlvbiogY29ubikKewogIEhBTkRMRSB0aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X2lvX3RocmVhZCwgY29ubiwgMCwgTlVMTCk7CiAgaWYgKCF0aHJlYWQpIHsKICAgIERXT1JEIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgRVJSKCJmYWlsZWQgdG8gY3JlYXRlIHRocmVhZCwgZXJyb3I9JTA4eFxuIiwgZXJyKTsKICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICB9CiAgLyogd2UgY291bGQgc2V0IGNvbm4tPnRocmVhZCwgYnV0IHRoZW4gd2UnZCBoYXZlIHRvIG1ha2UgdGhlIGlvX3RocmVhZCB3YWl0CiAgICogZm9yIHRoYXQsIG90aGVyd2lzZSB0aGUgdGhyZWFkIG1pZ2h0IGZpbmlzaCwgZGVzdHJveSB0aGUgY29ubmVjdGlvbiwgYW5kCiAgICogZnJlZSB0aGUgbWVtb3J5IHdlJ2Qgd3JpdGUgdG8gYmVmb3JlIHdlIGRpZCwgY2F1c2luZyBjcmFzaGVzIGFuZCBzdHVmZiAtCiAgICogc28gbGV0J3MgaW1wbGVtZW50IHRoYXQgbGF0ZXIsIHdoZW4gd2UgcmVhbGx5IG5lZWQgY29ubi0+dGhyZWFkICovCgogIENsb3NlSGFuZGxlKCB0aHJlYWQgKTsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF9zZXJ2ZXJfdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgaW50IHJlczsKICB1bnNpZ25lZCBpbnQgY291bnQ7CiAgdm9pZCAqb2JqcyA9IE5VTEw7CiAgUnBjU2VydmVyUHJvdHNlcSogY3BzID0gdGhlX2FyZzsKICBScGNDb25uZWN0aW9uKiBjb25uOwogIEJPT0wgc2V0X3JlYWR5X2V2ZW50ID0gRkFMU0U7CgogIFRSQUNFKCIodGhlX2FyZyA9PSBeJXApXG4iLCB0aGVfYXJnKTsKCiAgZm9yICg7OykgewogICAgb2JqcyA9IGNwcy0+b3BzLT5nZXRfd2FpdF9hcnJheShjcHMsIG9ianMsICZjb3VudCk7CgogICAgaWYgKHNldF9yZWFkeV9ldmVudCkKICAgIHsKICAgICAgICAvKiBzaWduYWwgdG8gZnVuY3Rpb24gdGhhdCBjaGFuZ2VkIHN0YXRlIHRoYXQgd2UgYXJlIG5vdyBzeW5jJ2VkICovCiAgICAgICAgU2V0RXZlbnQoY3BzLT5zZXJ2ZXJfcmVhZHlfZXZlbnQpOwogICAgICAgIHNldF9yZWFkeV9ldmVudCA9IEZBTFNFOwogICAgfQoKICAgIC8qIHN0YXJ0IHdhaXRpbmcgKi8KICAgIHJlcyA9IGNwcy0+b3BzLT53YWl0X2Zvcl9uZXdfY29ubmVjdGlvbihjcHMsIGNvdW50LCBvYmpzKTsKICAgIGlmIChyZXMgPT0gLTEpCiAgICAgIGJyZWFrOwogICAgZWxzZSBpZiAocmVzID09IDApCiAgICB7CiAgICAgIGlmICghc3RkX2xpc3RlbikKICAgICAgewogICAgICAgIFNldEV2ZW50KGNwcy0+c2VydmVyX3JlYWR5X2V2ZW50KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBzZXRfcmVhZHlfZXZlbnQgPSBUUlVFOwogICAgfQogIH0KICBjcHMtPm9wcy0+ZnJlZV93YWl0X2FycmF5KGNwcywgb2Jqcyk7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNwcy0+Y3MpOwogIC8qIGNsb3NlIGNvbm5lY3Rpb25zICovCiAgY29ubiA9IGNwcy0+Y29ubjsKICB3aGlsZSAoY29ubikgewogICAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihjb25uKTsKICAgIGNvbm4gPSBjb25uLT5OZXh0OwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3BzLT5jcyk7CiAgcmV0dXJuIDA7Cn0KCi8qIHRlbGxzIHRoZSBzZXJ2ZXIgdGhyZWFkIHRoYXQgdGhlIHN0YXRlIGhhcyBjaGFuZ2VkIGFuZCB3YWl0cyBmb3IgaXQgdG8KICogbWFrZSB0aGUgY2hhbmdlcyAqLwpzdGF0aWMgdm9pZCBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoUnBjU2VydmVyUHJvdHNlcSAqcHMpCnsKICAvKiBtYWtlIHN1cmUgd2UgYXJlIHRoZSBvbmx5IHRocmVhZCBzeW5jJ2luZyB0aGUgc2VydmVyIHN0YXRlLCBvdGhlcndpc2UKICAgKiB0aGVyZSBpcyBhIHJhY2Ugd2l0aCB0aGUgc2VydmVyIHRocmVhZCBzZXR0aW5nIGFuIG9sZGVyIHN0YXRlIGFuZCBzZXR0aW5nCiAgICogdGhlIHNlcnZlcl9yZWFkeV9ldmVudCB3aGVuIHRoZSBuZXcgc3RhdGUgaGFzbid0IHlldCBiZWVuIGFwcGxpZWQgKi8KICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHBzLT5tZ3JfbXV0ZXgsIElORklOSVRFKTsKCiAgcHMtPm9wcy0+c2lnbmFsX3N0YXRlX2NoYW5nZWQocHMpOwoKICAvKiB3YWl0IGZvciBzZXJ2ZXIgdGhyZWFkIHRvIG1ha2UgdGhlIHJlcXVlc3RlZCBjaGFuZ2VzIGJlZm9yZSByZXR1cm5pbmcgKi8KICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHBzLT5zZXJ2ZXJfcmVhZHlfZXZlbnQsIElORklOSVRFKTsKCiAgUmVsZWFzZU11dGV4KHBzLT5tZ3JfbXV0ZXgpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfc3RhcnRfbGlzdGVuX3Byb3RzZXEoUnBjU2VydmVyUHJvdHNlcSAqcHMsIEJPT0wgYXV0b19saXN0ZW4pCnsKICBSUENfU1RBVFVTIHN0YXR1cyA9IFJQQ19TX09LOwogIEhBTkRMRSBzZXJ2ZXJfdGhyZWFkOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICBpZiAocHMtPmlzX2xpc3RlbmluZykgZ290byBkb25lOwoKICBpZiAoIXBzLT5tZ3JfbXV0ZXgpIHBzLT5tZ3JfbXV0ZXggPSBDcmVhdGVNdXRleFcoTlVMTCwgRkFMU0UsIE5VTEwpOwogIGlmICghcHMtPnNlcnZlcl9yZWFkeV9ldmVudCkgcHMtPnNlcnZlcl9yZWFkeV9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogIHNlcnZlcl90aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X3NlcnZlcl90aHJlYWQsIHBzLCAwLCBOVUxMKTsKICBpZiAoIXNlcnZlcl90aHJlYWQpCiAgewogICAgc3RhdHVzID0gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKICAgIGdvdG8gZG9uZTsKICB9CiAgcHMtPmlzX2xpc3RlbmluZyA9IFRSVUU7CiAgQ2xvc2VIYW5kbGUoc2VydmVyX3RocmVhZCk7Cgpkb25lOgogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIHJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9zdGFydF9saXN0ZW4oQk9PTCBhdXRvX2xpc3RlbikKewogIFJQQ19TVEFUVVMgc3RhdHVzID0gUlBDX1NfQUxSRUFEWV9MSVNURU5JTkc7CiAgUnBjU2VydmVyUHJvdHNlcSAqY3BzOwoKICBUUkFDRSgiXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgaWYgKGF1dG9fbGlzdGVuIHx8IChtYW51YWxfbGlzdGVuX2NvdW50KysgPT0gMCkpCiAgewogICAgc3RhdHVzID0gUlBDX1NfT0s7CiAgICBpZiAoKytsaXN0ZW5fY291bnQgPT0gMSkKICAgICAgc3RkX2xpc3RlbiA9IFRSVUU7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICBpZiAoc3RkX2xpc3RlbikKICB7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoY3BzLCAmcHJvdHNlcXMsIFJwY1NlcnZlclByb3RzZXEsIGVudHJ5KQogICAgewogICAgICBzdGF0dXMgPSBSUENSVDRfc3RhcnRfbGlzdGVuX3Byb3RzZXEoY3BzLCBUUlVFKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICBicmVhazsKICAgICAgCiAgICAgIC8qIG1ha2Ugc3VyZSBzZXJ2ZXIgaXMgYWN0dWFsbHkgbGlzdGVuaW5nIG9uIHRoZSBpbnRlcmZhY2UgYmVmb3JlCiAgICAgICAqIHJldHVybmluZyAqLwogICAgICBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoY3BzKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIH0KCiAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3N0b3BfbGlzdGVuKEJPT0wgYXV0b19saXN0ZW4pCnsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICBpZiAoYXV0b19saXN0ZW4gfHwgKC0tbWFudWFsX2xpc3Rlbl9jb3VudCA9PSAwKSkKICB7CiAgICBpZiAobGlzdGVuX2NvdW50ICE9IDAgJiYgLS1saXN0ZW5fY291bnQgPT0gMCkgewogICAgICBScGNTZXJ2ZXJQcm90c2VxICpjcHM7CgogICAgICBzdGRfbGlzdGVuID0gRkFMU0U7CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShjcHMsICZwcm90c2VxcywgUnBjU2VydmVyUHJvdHNlcSwgZW50cnkpCiAgICAgICAgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKGNwcyk7CgogICAgICByZXR1cm47CiAgICB9CiAgICBhc3NlcnQobGlzdGVuX2NvdW50ID49IDApOwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X3VzZV9wcm90c2VxKFJwY1NlcnZlclByb3RzZXEqIHBzLCBMUFNUUiBlbmRwb2ludCkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBzdGF0dXMgPSBwcy0+b3BzLT5vcGVuX2VuZHBvaW50KHBzLCBlbmRwb2ludCk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHJldHVybiBzdGF0dXM7CgogIGlmIChzdGRfbGlzdGVuKQogIHsKICAgIHN0YXR1cyA9IFJQQ1JUNF9zdGFydF9saXN0ZW5fcHJvdHNlcShwcywgRkFMU0UpOwogICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgICAgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKHBzKTsKICB9CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJJbnFCaW5kaW5ncyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJJbnFCaW5kaW5ncyggUlBDX0JJTkRJTkdfVkVDVE9SKiogQmluZGluZ1ZlY3RvciApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBEV09SRCBjb3VudDsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKICBScGNDb25uZWN0aW9uKiBjb25uOwoKICBpZiAoQmluZGluZ1ZlY3RvcikKICAgIFRSQUNFKCIoKkJpbmRpbmdWZWN0b3IgPT0gXiVwKVxuIiwgKkJpbmRpbmdWZWN0b3IpOwogIGVsc2UKICAgIEVSUigiKEJpbmRpbmdWZWN0b3IgPT0gTlVMTCEhPylcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAvKiBjb3VudCBjb25uZWN0aW9ucyAqLwogIGNvdW50ID0gMDsKICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHBzLCAmcHJvdHNlcXMsIFJwY1NlcnZlclByb3RzZXEsIGVudHJ5KSB7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcHMtPmNzKTsKICAgIGNvbm4gPSBwcy0+Y29ubjsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgIGNvdW50Kys7CiAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnBzLT5jcyk7CiAgfQogIGlmIChjb3VudCkgewogICAgLyogZXhwb3J0IGJpbmRpbmdzICovCiAgICAqQmluZGluZ1ZlY3RvciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoUlBDX0JJTkRJTkdfVkVDVE9SKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19IQU5ETEUpKihjb3VudC0xKSk7CiAgICAoKkJpbmRpbmdWZWN0b3IpLT5Db3VudCA9IGNvdW50OwogICAgY291bnQgPSAwOwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShwcywgJnByb3RzZXFzLCBScGNTZXJ2ZXJQcm90c2VxLCBlbnRyeSkgewogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcHMtPmNzKTsKICAgICAgY29ubiA9IHBzLT5jb25uOwogICAgICB3aGlsZSAoY29ubikgewogICAgICAgUlBDUlQ0X01ha2VCaW5kaW5nKChScGNCaW5kaW5nKiopJigqQmluZGluZ1ZlY3RvciktPkJpbmRpbmdIW2NvdW50XSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uKTsKICAgICAgIGNvdW50Kys7CiAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgfQogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHMtPmNzKTsKICAgIH0KICAgIHN0YXR1cyA9IFJQQ19TX09LOwogIH0gZWxzZSB7CiAgICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgICBzdGF0dXMgPSBSUENfU19OT19CSU5ESU5HUzsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwQSggUlBDX0NTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgUlBDX0NTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBQcm90c2VxLCBNYXhDYWxscywgRW5kcG9pbnQsIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwVyggUlBDX1dTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgUlBDX1dTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksIE1heENhbGxzLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IgKTsKICAKICAvKiBUaGlzIHNob3VsZCBwcm92aWRlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciAqLwogIHBvbGljeS5MZW5ndGggICAgICAgID0gc2l6ZW9mKCBwb2xpY3kgKTsKICBwb2xpY3kuRW5kcG9pbnRGbGFncyA9IDA7CiAgcG9saWN5Lk5JQ0ZsYWdzICAgICAgPSAwOwogIAogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcoIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yLCAmcG9saWN5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBhbGxvY19zZXJ2ZXJwcm90b3NlcSAoaW50ZXJuYWwpCiAqCiAqIE11c3QgYmUgY2FsbGVkIHdpdGggc2VydmVyX2NzIGhlbGQuCiAqLwpzdGF0aWMgUlBDX1NUQVRVUyBhbGxvY19zZXJ2ZXJwcm90b3NlcShVSU5UIE1heENhbGxzLCBjaGFyICpQcm90c2VxLCBScGNTZXJ2ZXJQcm90c2VxICoqcHMpCnsKICBjb25zdCBzdHJ1Y3QgcHJvdHNlcV9vcHMgKm9wcyA9IHJwY3J0NF9nZXRfcHJvdHNlcV9vcHMoUHJvdHNlcSk7CgogIGlmICghb3BzKQogIHsKICAgIEZJWE1FKCJwcm90c2VxICVzIG5vdCBzdXBwb3J0ZWRcbiIsIGRlYnVnc3RyX2EoUHJvdHNlcSkpOwogICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICB9CgogICpwcyA9IG9wcy0+YWxsb2MoKTsKICBpZiAoISpwcykKICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogICgqcHMpLT5NYXhDYWxscyA9IE1heENhbGxzOwogICgqcHMpLT5Qcm90c2VxID0gUHJvdHNlcTsKICAoKnBzKS0+b3BzID0gb3BzOwogICgqcHMpLT5NYXhDYWxscyA9IDA7CiAgKCpwcyktPmNvbm4gPSBOVUxMOwogIEluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigqcHMpLT5jcyk7CiAgKCpwcyktPmlzX2xpc3RlbmluZyA9IEZBTFNFOwogICgqcHMpLT5tZ3JfbXV0ZXggPSBOVUxMOwogICgqcHMpLT5zZXJ2ZXJfcmVhZHlfZXZlbnQgPSBOVUxMOwoKICBsaXN0X2FkZF9oZWFkKCZwcm90c2VxcywgJigqcHMpLT5lbnRyeSk7CgogIFRSQUNFKCJuZXcgcHJvdHNlcSAlcCBjcmVhdGVkIGZvciAlc1xuIiwgKnBzLCBQcm90c2VxKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKiBGaW5kcyBhIGdpdmVuIHByb3RzZXEgb3IgY3JlYXRlcyBhIG5ldyBvbmUgaWYgb25lIGRvZXNuJ3QgYWxyZWFkeSBleGlzdCAqLwpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfZ2V0X29yX2NyZWF0ZV9zZXJ2ZXJwcm90c2VxKFVJTlQgTWF4Q2FsbHMsIGNoYXIgKlByb3RzZXEsIFJwY1NlcnZlclByb3RzZXEgKipwcykKewogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBScGNTZXJ2ZXJQcm90c2VxICpjcHM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShjcHMsICZwcm90c2VxcywgUnBjU2VydmVyUHJvdHNlcSwgZW50cnkpCiAgICAgICAgaWYgKCFzdHJjbXAoY3BzLT5Qcm90c2VxLCBQcm90c2VxKSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJmb3VuZCBleGlzdGluZyBwcm90c2VxIG9iamVjdCBmb3IgJXNcbiIsIFByb3RzZXEpOwogICAgICAgICAgICAqcHMgPSBjcHM7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgICAgICAgICByZXR1cm4gU19PSzsKICAgICAgICB9CgogICAgc3RhdHVzID0gYWxsb2Nfc2VydmVycHJvdG9zZXEoTWF4Q2FsbHMsIFByb3RzZXEsIHBzKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSggUlBDX0NTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgUlBDX0NTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19QT0xJQ1kgbHBQb2xpY3kgKQp7CiAgY2hhciAqc3pwcyA9IChjaGFyKilQcm90c2VxLCAqc3plcCA9IChjaGFyKilFbmRwb2ludDsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIiglcywldSwlcywlcCx7JXUsJWx1LCVsdX0pXG4iLCBkZWJ1Z3N0cl9hKHN6cHMpLCBNYXhDYWxscywKICAgICAgIGRlYnVnc3RyX2Eoc3plcCksIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgIGxwUG9saWN5LT5MZW5ndGgsIGxwUG9saWN5LT5FbmRwb2ludEZsYWdzLCBscFBvbGljeS0+TklDRmxhZ3MgKTsKCiAgc3RhdHVzID0gUlBDUlQ0X2dldF9vcl9jcmVhdGVfc2VydmVycHJvdHNlcShNYXhDYWxscywgUlBDUlQ0X3N0cmR1cEEoc3pwcyksICZwcyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHJldHVybiBzdGF0dXM7CgogIHJldHVybiBSUENSVDRfdXNlX3Byb3RzZXEocHMsIHN6ZXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyggUlBDX1dTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgUlBDX1dTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19QT0xJQ1kgbHBQb2xpY3kgKQp7CiAgUnBjU2VydmVyUHJvdHNlcSogcHM7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgTFBTVFIgRW5kcG9pbnRBOwoKICBUUkFDRSgiKCVzLCV1LCVzLCVwLHsldSwlbHUsJWx1fSlcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsCiAgICAgICBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICBscFBvbGljeS0+TGVuZ3RoLCBscFBvbGljeS0+RW5kcG9pbnRGbGFncywgbHBQb2xpY3ktPk5JQ0ZsYWdzICk7CgogIHN0YXR1cyA9IFJQQ1JUNF9nZXRfb3JfY3JlYXRlX3NlcnZlcnByb3RzZXEoTWF4Q2FsbHMsIFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpLCAmcHMpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICByZXR1cm4gc3RhdHVzOwoKICBFbmRwb2ludEEgPSBSUENSVDRfc3RyZHVwV3RvQShFbmRwb2ludCk7CiAgc3RhdHVzID0gUlBDUlQ0X3VzZV9wcm90c2VxKHBzLCBFbmRwb2ludEEpOwogIFJQQ1JUNF9zdHJmcmVlKEVuZHBvaW50QSk7CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFBKFJQQ19DU1RSIFByb3RzZXEsIHVuc2lnbmVkIGludCBNYXhDYWxscywgdm9pZCAqU2VjdXJpdHlEZXNjcmlwdG9yKQp7CiAgVFJBQ0UoIihQcm90c2VxID09ICVzLCBNYXhDYWxscyA9PSAlZCwgU2VjdXJpdHlEZXNjcmlwdG9yID09IF4lcClcbiIsIGRlYnVnc3RyX2EoKGNoYXIqKVByb3RzZXEpLCBNYXhDYWxscywgU2VjdXJpdHlEZXNjcmlwdG9yKTsKICByZXR1cm4gUnBjU2VydmVyVXNlUHJvdHNlcUVwQShQcm90c2VxLCBNYXhDYWxscywgTlVMTCwgU2VjdXJpdHlEZXNjcmlwdG9yKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFXKFJQQ19XU1RSIFByb3RzZXEsIHVuc2lnbmVkIGludCBNYXhDYWxscywgdm9pZCAqU2VjdXJpdHlEZXNjcmlwdG9yKQp7CiAgVFJBQ0UoIlByb3RzZXEgPT0gJXMsIE1heENhbGxzID09ICVkLCBTZWN1cml0eURlc2NyaXB0b3IgPT0gXiVwKVxuIiwgZGVidWdzdHJfdyhQcm90c2VxKSwgTWF4Q2FsbHMsIFNlY3VyaXR5RGVzY3JpcHRvcik7CiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcFcoUHJvdHNlcSwgTWF4Q2FsbHMsIE5VTEwsIFNlY3VyaXR5RGVzY3JpcHRvcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWYoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgUlBDX01HUl9FUFYqIE1nckVwdiApCnsKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2KTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgMCwgUlBDX0NfTElTVEVOX01BWF9DQUxMU19ERUZBVUxULCAoVUlOVCktMSwgTlVMTCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJJZkV4IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgIFVJTlQgRmxhZ3MsIFVJTlQgTWF4Q2FsbHMsIFJQQ19JRl9DQUxMQkFDS19GTiogSWZDYWxsYmFja0ZuICkKewogIFRSQUNFKCIoJXAsJXMsJXAsJXUsJXUsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYsIEZsYWdzLCBNYXhDYWxscywgSWZDYWxsYmFja0ZuKTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLCAoVUlOVCktMSwgSWZDYWxsYmFja0ZuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmMiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlcklmMiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgVUlOVCBGbGFncywgVUlOVCBNYXhDYWxscywgVUlOVCBNYXhScGNTaXplLCBSUENfSUZfQ0FMTEJBQ0tfRk4qIElmQ2FsbGJhY2tGbiApCnsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICB1bnNpZ25lZCBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcywlcCwldSwldSwldSwlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLAogICAgICAgICBNYXhScGNTaXplLCBJZkNhbGxiYWNrRm4pOwogIFRSQUNFKCIgaW50ZXJmYWNlIGlkOiAlcyAlZC4lZFxuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICBUUkFDRSgiIHRyYW5zZmVyIHN5bnRheDogJXMgJWQuJWRcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhHVUlEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgVFJBQ0UoIiBkaXNwYXRjaCB0YWJsZTogJXBcbiIsIElmLT5EaXNwYXRjaFRhYmxlKTsKICBpZiAoSWYtPkRpc3BhdGNoVGFibGUpIHsKICAgIFRSQUNFKCIgIGRpc3BhdGNoIHRhYmxlIGNvdW50OiAlZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCk7CiAgICBmb3IgKGk9MDsgaTxJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50OyBpKyspIHsKICAgICAgVFJBQ0UoIiAgIGVudHJ5ICVkOiAlcFxuIiwgaSwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbaV0pOwogICAgfQogICAgVFJBQ0UoIiAgcmVzZXJ2ZWQ6ICVsZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPlJlc2VydmVkKTsKICB9CiAgVFJBQ0UoIiBwcm90c2VxIGVuZHBvaW50IGNvdW50OiAlZFxuIiwgSWYtPlJwY1Byb3RzZXFFbmRwb2ludENvdW50KTsKICBUUkFDRSgiIGRlZmF1bHQgbWFuYWdlciBlcHY6ICVwXG4iLCBJZi0+RGVmYXVsdE1hbmFnZXJFcHYpOwogIFRSQUNFKCIgaW50ZXJwcmV0ZXIgaW5mbzogJXBcbiIsIElmLT5JbnRlcnByZXRlckluZm8pOwoKICBzaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY1NlcnZlckludGVyZmFjZSkpOwogIHNpZi0+SWYgICAgICAgICAgID0gSWY7CiAgaWYgKE1nclR5cGVVdWlkKSB7CiAgICBtZW1jcHkoJnNpZi0+TWdyVHlwZVV1aWQsIE1nclR5cGVVdWlkLCBzaXplb2YoVVVJRCkpOwogICAgc2lmLT5NZ3JFcHYgICAgICAgPSBNZ3JFcHY7CiAgfSBlbHNlIHsKICAgIG1lbXNldCgmc2lmLT5NZ3JUeXBlVXVpZCwgMCwgc2l6ZW9mKFVVSUQpKTsKICAgIHNpZi0+TWdyRXB2ICAgICAgID0gSWYtPkRlZmF1bHRNYW5hZ2VyRXB2OwogIH0KICBzaWYtPkZsYWdzICAgICAgICA9IEZsYWdzOwogIHNpZi0+TWF4Q2FsbHMgICAgID0gTWF4Q2FsbHM7CiAgc2lmLT5NYXhScGNTaXplICAgPSBNYXhScGNTaXplOwogIHNpZi0+SWZDYWxsYmFja0ZuID0gSWZDYWxsYmFja0ZuOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBsaXN0X2FkZF9oZWFkKCZzZXJ2ZXJfaW50ZXJmYWNlcywgJnNpZi0+ZW50cnkpOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICBpZiAoc2lmLT5GbGFncyAmIFJQQ19JRl9BVVRPTElTVEVOKQogICAgICBSUENSVDRfc3RhcnRfbGlzdGVuKFRSVUUpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVW5yZWdpc3RlcklmKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFVJTlQgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSApCnsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICBIQU5ETEUgZXZlbnQgPSBOVUxMOwogIEJPT0wgZm91bmQgPSBGQUxTRTsKICBCT09MIGNvbXBsZXRlZCA9IFRSVUU7CiAgUnBjU2VydmVySW50ZXJmYWNlICpjaWY7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoSWZTcGVjID09IChSUENfSUZfSEFORExFKV4lcCAoJXMpLCBNZ3JUeXBlVXVpZCA9PSAlcywgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSA9PSAldSlcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoJklmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEKSwgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIFdhaXRGb3JDYWxsc1RvQ29tcGxldGUpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGNpZiwgJnNlcnZlcl9pbnRlcmZhY2VzLCBScGNTZXJ2ZXJJbnRlcmZhY2UsIGVudHJ5KSB7CiAgICBpZiAoKCFJZlNwZWMgfHwgIW1lbWNtcCgmSWYtPkludGVyZmFjZUlkLCAmY2lmLT5JZi0+SW50ZXJmYWNlSWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSkgJiYKICAgICAgICBVdWlkRXF1YWwoTWdyVHlwZVV1aWQsICZjaWYtPk1nclR5cGVVdWlkLCAmc3RhdHVzKSkgewogICAgICBsaXN0X3JlbW92ZSgmY2lmLT5lbnRyeSk7CiAgICAgIGlmIChjaWYtPkN1cnJlbnRDYWxscykgewogICAgICAgIGNvbXBsZXRlZCA9IEZBTFNFOwogICAgICAgIGlmIChXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlKQogICAgICAgICAgY2lmLT5DYWxsc0NvbXBsZXRlZEV2ZW50ID0gZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgICAgfQogICAgICBmb3VuZCA9IFRSVUU7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgaWYgKCFmb3VuZCkgewogICAgRVJSKCJub3QgZm91bmQgZm9yIG9iamVjdCAlc1xuIiwgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCkpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fSUY7CiAgfQoKICBpZiAoY29tcGxldGVkKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2lmKTsKICBlbHNlIGlmIChldmVudCkgewogICAgLyogc2lmIHdpbGwgYmUgZnJlZWQgd2hlbiB0aGUgbGFzdCBjYWxsIGlzIGNvbXBsZXRlZCwgc28gYmUgY2FyZWZ1bCBub3QgdG8KICAgICAqIHRvdWNoIHRoYXQgbWVtb3J5IGhlcmUgYXMgdGhhdCBjb3VsZCBoYXBwZW4gYmVmb3JlIHdlIGdldCBoZXJlICovCiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGV2ZW50LCBJTkZJTklURSk7CiAgICBDbG9zZUhhbmRsZShldmVudCk7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBpbnQgUnVuZG93bkNvbnRleHRIYW5kbGVzICkKewogIEZJWE1FKCIoSWZTcGVjID09IChSUENfSUZfSEFORExFKV4lcCwgTWdyVHlwZVV1aWQgPT0gJXMsIFJ1bmRvd25Db250ZXh0SGFuZGxlcyA9PSAlZCk6IHN0dWJcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBSdW5kb3duQ29udGV4dEhhbmRsZXMpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNPYmplY3RTZXRUeXBlIChSUENSVDQuQCkKICoKICogUEFSQU1TCiAqICAgT2JqVXVpZCAgW0ldICJPYmplY3QiIFVVSUQKICogICBUeXBlVXVpZCBbSV0gIlR5cGUiIFVVSUQKICoKICogUkVUVVJOUwogKiAgIFJQQ19TX09LICAgICAgICAgICAgICAgICBUaGUgY2FsbCBzdWNjZWVkZWQKICogICBSUENfU19JTlZBTElEX09CSkVDVCAgICAgVGhlIHByb3ZpZGVkIG9iamVjdCAobmlsKSBpcyBub3QgdmFsaWQKICogICBSUENfU19BTFJFQURZX1JFR0lTVEVSRUQgVGhlIHByb3ZpZGVkIG9iamVjdCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQKICoKICogTWFwcyAiT2JqZWN0IiBVVUlEcyB0byAiVHlwZSIgVVVJRCdzLiAgUGFzc2luZyB0aGUgbmlsIFVVSUQgYXMgdGhlIHR5cGUKICogcmVzZXRzIHRoZSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBVVUlEIHRvIG5pbCAodGhlIGRlZmF1bHQpLgogKiBUaGUgbmlsIG9iamVjdCBpcyBhbHdheXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBuaWwgdHlwZSBhbmQgY2Fubm90IGJlCiAqIHJlYXNzaWduZWQuICBTZXJ2ZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlIGltcGxlbWVudGF0aW9ucyBvbiB0aGUgc2FtZQogKiBpbnRlcmZhY2UgYnkgcmVnaXN0ZXJpbmcgZGlmZmVyZW50IGVuZC1wb2ludCB2ZWN0b3JzIGZvciB0aGUgZGlmZmVyZW50CiAqIHR5cGVzLiAgVGhlcmUncyBubyBuZWVkIHRvIGNhbGwgdGhpcyBpZiBhIHNlcnZlciBvbmx5IHN1cHBvcnRzIHRoZSBuaWwKICogdHlwZSwgYXMgaXMgdHlwaWNhbC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY09iamVjdFNldFR5cGUoIFVVSUQqIE9ialV1aWQsIFVVSUQqIFR5cGVVdWlkICkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IFJwY09ialR5cGVNYXBzLCAqcHJldiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgVFJBQ0UoIihPYmpVVUlEID09ICVzLCBUeXBlVXVpZCA9PSAlcykuXG4iLCBkZWJ1Z3N0cl9ndWlkKE9ialV1aWQpLCBkZWJ1Z3N0cl9ndWlkKFR5cGVVdWlkKSk7CiAgaWYgKCghIE9ialV1aWQpIHx8IFV1aWRJc05pbChPYmpVdWlkLCAmZHVtbXkpKSB7CiAgICAvKiBuaWwgdXVpZCBjYW5ub3QgYmUgcmVtYXBwZWQgKi8KICAgIHJldHVybiBSUENfU19JTlZBTElEX09CSkVDVDsKICB9CgogIC8qIGZpbmQgdGhlIG1hcHBpbmcgZm9yIHRoaXMgb2JqZWN0IGlmIHRoZXJlIGlzIG9uZSAuLi4gKi8KICB3aGlsZSAobWFwKSB7CiAgICBpZiAoISBVdWlkQ29tcGFyZShPYmpVdWlkLCAmbWFwLT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcHJldiA9IG1hcDsKICAgIG1hcCA9IG1hcC0+bmV4dDsKICB9CiAgaWYgKCghIFR5cGVVdWlkKSB8fCBVdWlkSXNOaWwoVHlwZVV1aWQsICZkdW1teSkpIHsKICAgIC8qIC4uLiBhbmQgZHJvcCBpdCBmcm9tIHRoZSBsaXN0ICovCiAgICBpZiAobWFwKSB7CiAgICAgIGlmIChwcmV2KSAKICAgICAgICBwcmV2LT5uZXh0ID0gbWFwLT5uZXh0OwogICAgICBlbHNlCiAgICAgICAgUnBjT2JqVHlwZU1hcHMgPSBtYXAtPm5leHQ7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1hcCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIC4uLiAsIGZhaWwgaWYgd2UgZm91bmQgaXQgLi4uICovCiAgICBpZiAobWFwKQogICAgICByZXR1cm4gUlBDX1NfQUxSRUFEWV9SRUdJU1RFUkVEOwogICAgLyogLi4uIG90aGVyd2lzZSBjcmVhdGUgYSBuZXcgb25lIGFuZCBhZGQgaXQgaW4uICovCiAgICBtYXAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY09ialR5cGVNYXApKTsKICAgIG1lbWNweSgmbWFwLT5PYmplY3QsIE9ialV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtZW1jcHkoJm1hcC0+VHlwZSwgVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtYXAtPm5leHQgPSBOVUxMOwogICAgaWYgKHByZXYpCiAgICAgIHByZXYtPm5leHQgPSBtYXA7IC8qIHByZXYgaXMgdGhlIGxhc3QgbWFwIGluIHRoZSBsaW5rbGlzdCAqLwogICAgZWxzZQogICAgICBScGNPYmpUeXBlTWFwcyA9IG1hcDsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BKCBSUENfQ1NUUiBTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9LRVlfUkVUUklFVkFMX0ZOIEdldEtleUZuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIEFyZyApCnsKICBGSVhNRSggIiglcywldSwlcCwlcCk6IHN0dWJcbiIsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5TdmMsIEdldEtleUZuLCBBcmcgKTsKICAKICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOyAvKiBXZSBkb24ndCBrbm93IGFueSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlcyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1coIFJQQ19XU1RSIFNlcnZlclByaW5jTmFtZSwgVUxPTkcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCV1LCVwLCVwKTogc3R1YlxuIiwgZGVidWdzdHJfdyggU2VydmVyUHJpbmNOYW1lICksIEF1dGhuU3ZjLCBHZXRLZXlGbiwgQXJnICk7CiAgCiAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsgLyogV2UgZG9uJ3Qga25vdyBhbnkgYXV0aGVudGljYXRpb24gc2VydmljZXMgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlckxpc3RlbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJMaXN0ZW4oIFVJTlQgTWluaW11bUNhbGxUaHJlYWRzLCBVSU5UIE1heENhbGxzLCBVSU5UIERvbnRXYWl0ICkKewogIFJQQ19TVEFUVVMgc3RhdHVzID0gUlBDX1NfT0s7CgogIFRSQUNFKCIoJXUsJXUsJXUpXG4iLCBNaW5pbXVtQ2FsbFRocmVhZHMsIE1heENhbGxzLCBEb250V2FpdCk7CgogIGlmIChsaXN0X2VtcHR5KCZwcm90c2VxcykpCiAgICByZXR1cm4gUlBDX1NfTk9fUFJPVFNFUVNfUkVHSVNURVJFRDsKCiAgc3RhdHVzID0gUlBDUlQ0X3N0YXJ0X2xpc3RlbihGQUxTRSk7CgogIGlmIChEb250V2FpdCB8fCAoc3RhdHVzICE9IFJQQ19TX09LKSkgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJwY01nbXRXYWl0U2VydmVyTGlzdGVuKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U2VydmVyV2FpdExpc3RlbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210V2FpdFNlcnZlckxpc3Rlbiggdm9pZCApCnsKICBUUkFDRSgiKClcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKCiAgaWYgKCFzdGRfbGlzdGVuKSB7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgIHJldHVybiBSUENfU19OT1RfTElTVEVOSU5HOwogIH0KICAKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKCiAgRklYTUUoIm5vdCB3YWl0aW5nIGZvciBzZXJ2ZXIgY2FsbHMgdG8gZmluaXNoXG4iKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdFN0b3BTZXJ2ZXJMaXN0ZW5pbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTWdtdFN0b3BTZXJ2ZXJMaXN0ZW5pbmcgKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZyApCnsKICBUUkFDRSgiKEJpbmRpbmcgPT0gKFJQQ19CSU5ESU5HX0hBTkRMRSleJXApXG4iLCBCaW5kaW5nKTsKCiAgaWYgKEJpbmRpbmcpIHsKICAgIEZJWE1FKCJjbGllbnQtc2lkZSBpbnZvY2F0aW9uIG5vdCBpbXBsZW1lbnRlZC5cbiIpOwogICAgcmV0dXJuIFJQQ19TX1dST05HX0tJTkRfT0ZfQklORElORzsKICB9CiAgCiAgUlBDUlQ0X3N0b3BfbGlzdGVuKEZBTFNFKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdEVuYWJsZUlkbGVDbGVhbnVwIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRFbmFibGVJZGxlQ2xlYW51cCh2b2lkKQp7CiAgICBGSVhNRSgiKCk6IHN0dWJcbiIpOwogICAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNTZXJ2ZXJTdGFydExpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlcnZlclN0YXJ0TGlzdGVuaW5nKCBIV05EIGhXbmQgKQp7CiAgRklYTUUoICIoJXApOiBzdHViXG4iLCBoV25kICk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjU2VydmVyU3RvcExpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlcnZlclN0b3BMaXN0ZW5pbmcoIHZvaWQgKQp7CiAgRklYTUUoICIoKTogc3R1YlxuIiApOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1dpbmRvd1Byb2MgKFJQQ1JUNC5AKQogKi8KVUlOVCBXSU5BUEkgSV9ScGNXaW5kb3dQcm9jKCB2b2lkICpoV25kLCBVSU5UIE1lc3NhZ2UsIFVJTlQgd1BhcmFtLCBVTE9ORyBsUGFyYW0gKQp7CiAgRklYTUUoICIoJXAsJTA4eCwlMDh4LCUwOHgpOiBzdHViXG4iLCBoV25kLCBNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSApOwoKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRJbnFJZklkcyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210SW5xSWZJZHMoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19JRl9JRF9WRUNUT1IgKipJZklkVmVjdG9yKQp7CiAgRklYTUUoIiglcCwlcCk6IHN0dWJcbiIsIEJpbmRpbmcsIElmSWRWZWN0b3IpOwogIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210RXBFbHRJbnFCZWdpbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210RXBFbHRJbnFCZWdpbihSUENfQklORElOR19IQU5ETEUgQmluZGluZywgVUxPTkcgSW5xdWlyeVR5cGUsCiAgICBSUENfSUZfSUQgKklmSWQsIFVMT05HIFZlcnNPcHRpb24sIFVVSUQgKk9iamVjdFV1aWQsIFJQQ19FUF9JTlFfSEFORExFKiBJbnF1aXJ5Q29udGV4dCkKewogIEZJWE1FKCIoJXAsJXUsJXAsJXUsJXAsJXApOiBzdHViXG4iLAogICAgICAgIEJpbmRpbmcsIElucXVpcnlUeXBlLCBJZklkLCBWZXJzT3B0aW9uLCBPYmplY3RVdWlkLCBJbnF1aXJ5Q29udGV4dCk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRJc1NlcnZlckxpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210SXNTZXJ2ZXJMaXN0ZW5pbmcoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcpCnsKICBGSVhNRSgiKCVwKTogc3R1YlxuIiwgQmluZGluZyk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXRTZXJ2ZXJTdGFja1NpemUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTWdtdFNldFNlcnZlclN0YWNrU2l6ZShVTE9ORyBUaHJlYWRTdGFja1NpemUpCnsKICBGSVhNRSgiKDB4JXgpOiBzdHViXG4iLCBUaHJlYWRTdGFja1NpemUpOwogIHJldHVybiBSUENfU19PSzsKfQo=