LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICoKICogQ29weXJpZ2h0IDE5OTcgTWFyY3VzIE1laXNzbmVyCiAqICAgICAgICAgICAxOTk4IEr8cmdlbiBTY2htaWVkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAicGlkbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChwaWRsKTsKCi8qIEZJWE1FOiAhISEgbW92ZSBDUkVBVEVNUlVMSVNUIGFuZCBmbGFncyB0byBoZWFkZXIgZmlsZSAhISEgKi8KLyogICAgICAgICEhISBpdCBpcyBpbiBib3RoIGhlcmUgYW5kIGNvbWN0bDMydW5kb2MuYyAgICAgICEhISAqLwp0eXBlZGVmIHN0cnVjdCB0YWdDUkVBVEVNUlVMSVNUCnsKICAgIERXT1JEICBjYlNpemU7ICAgICAgICAvKiBzaXplIG9mIHN0cnVjdCAqLwogICAgRFdPUkQgIG5NYXhJdGVtczsgICAgIC8qIG1heCBuby4gb2YgaXRlbXMgaW4gbGlzdCAqLwogICAgRFdPUkQgIGR3RmxhZ3M7ICAgICAgIC8qIHNlZSBiZWxvdyAqLwogICAgSEtFWSAgIGhLZXk7ICAgICAgICAgIC8qIHJvb3QgcmVnLiBrZXkgdW5kZXIgd2hpY2ggbGlzdCBpcyBzYXZlZCAqLwogICAgTFBDU1RSIGxwc3pTdWJLZXk7ICAgIC8qIHJlZy4gc3Via2V5ICovCiAgICBQUk9DICAgbHBmbkNvbXBhcmU7ICAgLyogaXRlbSBjb21wYXJlIHByb2MgKi8KfSBDUkVBVEVNUlVMSVNUQSwgKkxQQ1JFQVRFTVJVTElTVEE7CgovKiBkd0ZsYWdzICovCiNkZWZpbmUgTVJVRl9TVFJJTkdfTElTVCAgMCAvKiBsaXN0IHdpbGwgY29udGFpbiBzdHJpbmdzICovCiNkZWZpbmUgTVJVRl9CSU5BUllfTElTVCAgMSAvKiBsaXN0IHdpbGwgY29udGFpbiBiaW5hcnkgZGF0YSAqLwojZGVmaW5lIE1SVUZfREVMQVlFRF9TQVZFIDIgLyogb25seSBzYXZlIGxpc3Qgb3JkZXIgdG8gcmVnLiBpcyBGcmVlTVJVTGlzdCAqLwoKZXh0ZXJuIEhBTkRMRSBXSU5BUEkgQ3JlYXRlTVJVTGlzdEEoTFBDUkVBVEVNUlVMSVNUQSBscGNtbCk7CmV4dGVybiBEV09SRCAgV0lOQVBJIEZyZWVNUlVMaXN0KEhBTkRMRSBoTVJVTGlzdCk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEFkZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhKTsKZXh0ZXJuIElOVCAgICBXSU5BUEkgRmluZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMUElOVCBscFJlZ051bSk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEVudW1NUlVMaXN0QShIQU5ETEUgaExpc3QsIElOVCBuSXRlbVBvcywgTFBWT0lEIGxwQnVmZmVyLCBEV09SRCBuQnVmZmVyU2l6ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkQQkJCQkJW2ludGVybmFsXQogKgogKiBjb3BpZXMgYSBmaWVsZCBmcm9tIGEgJywnIGRlbGltaXRlZCBzdHJpbmcKICoKICogZmlyc3QgZmllbGQgaXMgbkZpZWxkID0gMQogKi8KRFdPUkQgV0lOQVBJIFBhcnNlRmllbGRBKAoJTFBDU1RSIHNyYywKCURXT1JEIG5GaWVsZCwKCUxQU1RSIGRzdCwKCURXT1JEIGxlbikKewoJV0FSTigiKCVzLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLGRlYnVnc3RyX2Eoc3JjKSxuRmllbGQsZHN0LGxlbik7CgoJaWYgKCFzcmMgfHwgIXNyY1swXSB8fCAhZHN0IHx8ICFsZW4pCgkgIHJldHVybiAwOwoKCS8qIHNraXAgbiBmaWVsZHMgZGVsaW1pdGVkIGJ5ICcsJyAqLwoJd2hpbGUgKG5GaWVsZCA+IDEpCgl7CgkgIGlmICgqc3JjPT0nXDAnKSByZXR1cm4gRkFMU0U7CgkgIGlmICgqKHNyYysrKT09JywnKSBuRmllbGQtLTsKCX0KCgkvKiBjb3B5IHBhcnQgdGlsbCB0aGUgbmV4dCAnLCcgdG8gZHN0ICovCgl3aGlsZSAoICpzcmMhPSdcMCcgJiYgKnNyYyE9JywnICYmIChsZW4tLSk+MCApICooZHN0KyspPSooc3JjKyspOwoKCS8qIGZpbmFsaXplIHRoZSBzdHJpbmcgKi8KCSpkc3Q9MHgwOwoKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkVwkJCVtpbnRlcm5hbF0KICoKICogY29waWVzIGEgZmllbGQgZnJvbSBhICcsJyBkZWxpbWl0ZWQgc3RyaW5nCiAqCiAqIGZpcnN0IGZpZWxkIGlzIG5GaWVsZCA9IDEKICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkVyhMUENXU1RSIHNyYywgRFdPUkQgbkZpZWxkLCBMUFdTVFIgZHN0LCBEV09SRCBsZW4pCnsKCVdBUk4oIiglcywweCUwOGx4LCVwLCVsZCkgc2VtaS1zdHViLlxuIiwgZGVidWdzdHJfdyhzcmMpLCBuRmllbGQsIGRzdCwgbGVuKTsKCglpZiAoIXNyYyB8fCAhc3JjWzBdIHx8ICFkc3QgfHwgIWxlbikKCSAgcmV0dXJuIDA7CgoJLyogc2tpcCBuIGZpZWxkcyBkZWxpbWl0ZWQgYnkgJywnICovCgl3aGlsZSAobkZpZWxkID4gMSkKCXsKCSAgaWYgKCpzcmMgPT0gMHgwKSByZXR1cm4gRkFMU0U7CgkgIGlmICgqc3JjKysgPT0gJywnKSBuRmllbGQtLTsKCX0KCgkvKiBjb3B5IHBhcnQgdGlsbCB0aGUgbmV4dCAnLCcgdG8gZHN0ICovCgl3aGlsZSAoICpzcmMgIT0gMHgwICYmICpzcmMgIT0gJywnICYmIChsZW4tLSk+MCApICooZHN0KyspID0gKihzcmMrKyk7CgoJLyogZmluYWxpemUgdGhlIHN0cmluZyAqLwoJKmRzdCA9IDB4MDsKCglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUGFyc2VGaWVsZAkJCVtTSEVMTDMyLjU4XQogKi8KRFdPUkQgV0lOQVBJIFBhcnNlRmllbGRBVyhMUENWT0lEIHNyYywgRFdPUkQgbkZpZWxkLCBMUFZPSUQgZHN0LCBEV09SRCBsZW4pCnsKCWlmIChTSEVMTF9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gUGFyc2VGaWVsZFcoc3JjLCBuRmllbGQsIGRzdCwgbGVuKTsKCXJldHVybiBQYXJzZUZpZWxkQShzcmMsIG5GaWVsZCwgZHN0LCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHZXRGaWxlTmFtZUZyb21Ccm93c2UJCQlbU0hFTEwzMi42M10KICoKICovCkJPT0wgV0lOQVBJIEdldEZpbGVOYW1lRnJvbUJyb3dzZSgKCUhXTkQgaHduZE93bmVyLAoJTFBTVFIgbHBzdHJGaWxlLAoJRFdPUkQgbk1heEZpbGUsCglMUENTVFIgbHBzdHJJbml0aWFsRGlyLAoJTFBDU1RSIGxwc3RyRGVmRXh0LAoJTFBDU1RSIGxwc3RyRmlsdGVyLAoJTFBDU1RSIGxwc3RyVGl0bGUpCnsKICAgIEhNT0RVTEUgaG1vZHVsZTsKICAgIEZBUlBST0MgcEdldE9wZW5GaWxlTmFtZUE7CiAgICBPUEVORklMRU5BTUVBIG9mbjsKICAgIEJPT0wgcmV0OwoKICAgIFRSQUNFKCIlcCwgJXMsICVsZCwgJXMsICVzLCAlcywgJXMpXG4iLAoJICBod25kT3duZXIsIGxwc3RyRmlsZSwgbk1heEZpbGUsIGxwc3RySW5pdGlhbERpciwgbHBzdHJEZWZFeHQsCgkgIGxwc3RyRmlsdGVyLCBscHN0clRpdGxlKTsKCiAgICBobW9kdWxlID0gTG9hZExpYnJhcnlBKCJjb21kbGczMi5kbGwiKTsKICAgIGlmKCFobW9kdWxlKSByZXR1cm4gRkFMU0U7CiAgICBwR2V0T3BlbkZpbGVOYW1lQSA9IEdldFByb2NBZGRyZXNzKGhtb2R1bGUsICJHZXRPcGVuRmlsZU5hbWVBIik7CiAgICBpZighcEdldE9wZW5GaWxlTmFtZUEpCiAgICB7CglGcmVlTGlicmFyeShobW9kdWxlKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtZW1zZXQoJm9mbiwgMCwgc2l6ZW9mKG9mbikpOwoKICAgIG9mbi5sU3RydWN0U2l6ZSA9IHNpemVvZihvZm4pOwogICAgb2ZuLmh3bmRPd25lciA9IGh3bmRPd25lcjsKICAgIG9mbi5scHN0ckZpbHRlciA9IGxwc3RyRmlsdGVyOwogICAgb2ZuLmxwc3RyRmlsZSA9IGxwc3RyRmlsZTsKICAgIG9mbi5uTWF4RmlsZSA9IG5NYXhGaWxlOwogICAgb2ZuLmxwc3RySW5pdGlhbERpciA9IGxwc3RySW5pdGlhbERpcjsKICAgIG9mbi5scHN0clRpdGxlID0gbHBzdHJUaXRsZTsKICAgIG9mbi5scHN0ckRlZkV4dCA9IGxwc3RyRGVmRXh0OwogICAgb2ZuLkZsYWdzID0gT0ZOX0VYUExPUkVSIHwgT0ZOX0hJREVSRUFET05MWSB8IE9GTl9GSUxFTVVTVEVYSVNUOwogICAgcmV0ID0gcEdldE9wZW5GaWxlTmFtZUEoJm9mbik7CgogICAgRnJlZUxpYnJhcnkoaG1vZHVsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldFNldFNldHRpbmdzCQkJCVtTSEVMTDMyLjY4XQogKi8KVk9JRCBXSU5BUEkgU0hHZXRTZXRTZXR0aW5ncyhMUFNIRUxMU1RBVEUgbHBzcywgRFdPUkQgZHdNYXNrLCBCT09MIGJTZXQpCnsKICBpZihiU2V0KQogIHsKICAgIEZJWE1FKCIlcCAweCUwOGx4IFRSVUVcbiIsIGxwc3MsIGR3TWFzayk7CiAgfQogIGVsc2UKICB7CiAgICBTSEdldFNldHRpbmdzKChMUFNIRUxMRkxBR1NUQVRFKWxwc3MsZHdNYXNrKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0U2V0dGluZ3MJCQkJW1NIRUxMMzIuQF0KICoKICogTk9URVMKICogIHRoZSByZWdpc3RyeSBwYXRoIGFyZSBmb3Igd2luOTggKHRlc3RlZCkKICogIGFuZCBwb3NzaWJseSBhcmUgdGhlIHNhbWUgaW4gbnQ0MAogKgogKi8KVk9JRCBXSU5BUEkgU0hHZXRTZXR0aW5ncyhMUFNIRUxMRkxBR1NUQVRFIGxwc2ZzLCBEV09SRCBkd01hc2spCnsKCUhLRVkJaEtleTsKCURXT1JECWR3RGF0YTsKCURXT1JECWR3RGF0YVNpemUgPSBzaXplb2YgKERXT1JEKTsKCglUUkFDRSgiKCVwIDB4JTA4bHgpXG4iLGxwc2ZzLGR3TWFzayk7CgoJaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlclxcQWR2YW5jZWQiLAoJCQkJIDAsIDAsIDAsIEtFWV9BTExfQUNDRVNTLCAwLCAmaEtleSwgMCkpCgkgIHJldHVybjsKCglpZiAoIChTU0ZfU0hPV0VYVEVOU0lPTlMgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRlRmlsZUV4dCIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZlNob3dFeHRlbnNpb25zICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoIChTU0ZfU0hPV0lORk9USVAgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93SW5mb1RpcCIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZlNob3dJbmZvVGlwICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoIChTU0ZfRE9OVFBSRVRUWVBBVEggJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJEb250UHJldHR5UGF0aCIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkRvbnRQcmV0dHlQYXRoICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoIChTU0ZfSElERUlDT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUljb25zIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mSGlkZUljb25zICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoIChTU0ZfTUFQTkVURFJWQlVUVE9OICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiTWFwTmV0RHJ2QnRuIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mTWFwTmV0RHJ2QnRuICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoIChTU0ZfU0hPV0FUVFJJQkNPTCAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIlNob3dBdHRyaWJDb2wiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93QXR0cmliQ29sICA9ICgoZHdEYXRhID09IDApID8gIDAgOiAxKTsKCglpZiAoKChTU0ZfU0hPV0FMTE9CSkVDVFMgfCBTU0ZfU0hPV1NZU0ZJTEVTKSAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGRlbiIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJeyBpZiAoZHdEYXRhID09IDApCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAwOwoJICB9CgkgIGVsc2UgaWYgKGR3RGF0YSA9PSAxKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMTsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMikKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDA7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDE7CgkgIH0KCX0KCVJlZ0Nsb3NlS2V5IChoS2V5KTsKCglUUkFDRSgiLS0gMHglMDR4XG4iLCAqKFdPUkQqKWxwc2ZzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTaGVsbEZvbGRlclZpZXdfTWVzc2FnZQkJCVtTSEVMTDMyLjczXQogKgogKiBTZW5kIGEgbWVzc2FnZSB0byBhbiBleHBsb3JlciBjYWJpbmV0IHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBod25kQ2FiaW5ldCBbSV0gVGhlIHdpbmRvdyBjb250YWluaW5nIHRoZSBzaGVsbHZpZXcgdG8gY29tbXVuaWNhdGUgd2l0aAogKiAgZHdNZXNzYWdlICAgW0ldIFRoZSBTRlZNIG1lc3NhZ2UgdG8gc2VuZAogKiAgZHdQYXJhbSAgICAgW0ldIE1lc3NhZ2UgcGFyYW1ldGVyCiAqCiAqIFJFVFVSTlMKICogIGZpeG1lLgogKgogKiBOT1RFUwogKiAgTWVzc2FnZSBTRlZNX1JFQVJSQU5HRSA9IDEKICoKICogICAgVGhpcyBtZXNzYWdlIGdldHMgc2VudCB3aGVuIGEgY29sdW1uIGdldHMgY2xpY2tlZCB0byBpbnN0cnVjdCB0aGUKICogICAgc2hlbGwgdmlldyB0byByZS1zb3J0IHRoZSBpdGVtIGxpc3QuIGR3UGFyYW0gaWRlbnRpZmllcyB0aGUgY29sdW1uCiAqICAgIHRoYXQgd2FzIGNsaWNrZWQuCiAqLwppbnQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoCglIV05EIGh3bmRDYWJpbmV0LAoJRFdPUkQgZHdNZXNzYWdlLAoJRFdPUkQgZHdQYXJhbSkKewoJRklYTUUoIiVwICUwOGx4ICUwOGx4IHN0dWJcbiIsaHduZENhYmluZXQsIGR3TWVzc2FnZSwgZHdQYXJhbSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnaXN0ZXJTaGVsbEhvb2sJCQkJW1NIRUxMMzIuMTgxXQogKgogKiBSZWdpc3RlciBhIHNoZWxsIGhvb2suCiAqCiAqIFBBUkFNUwogKiAgICAgIGh3bmQgICBbSV0gIFdpbmRvdyBoYW5kbGUKICogICAgICBkd1R5cGUgW0ldICBUeXBlIG9mIGhvb2suCiAqCiAqIE5PVEVTCiAqICAgICBFeHBvcnRlZCBieSBvcmRpbmFsCiAqLwpCT09MIFdJTkFQSSBSZWdpc3RlclNoZWxsSG9vaygKCUhXTkQgaFduZCwKCURXT1JEIGR3VHlwZSkKewoJRklYTUUoIiglcCwweCUwOGx4KTpzdHViLlxuIixoV25kLCBkd1R5cGUpOwoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveFcJCQkJW1NIRUxMMzIuMTgyXQogKgogKiBTZWUgU2hlbGxNZXNzYWdlQm94QS4KICovCmludCBXSU5BUElWIFNoZWxsTWVzc2FnZUJveFcoCglISU5TVEFOQ0UgaEluc3RhbmNlLAoJSFdORCBoV25kLAoJTFBDV1NUUiBscFRleHQsCglMUENXU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUsCgkuLi4pCnsKCVdDSEFSCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXTsKCUxQQ1dTVFIgcHN6VGV4dCA9IHN6VGV4dCwgcHN6VGl0bGUgPSBzelRpdGxlLCBwc3pUZW1wOwoJdmFfbGlzdCBhcmdzOwoJaW50CXJldDsKCgl2YV9zdGFydChhcmdzLCB1VHlwZSk7CgkvKiB3dnNwcmludGZBKGJ1ZixmbXQsIGFyZ3MpOyAqLwoKCVRSQUNFKCIoJTA4bHgsJTA4bHgsJXAsJXAsJTA4eClcbiIsCgkoRFdPUkQpaEluc3RhbmNlLChEV09SRCloV25kLGxwVGV4dCxscENhcHRpb24sdVR5cGUpOwoKCWlmICghSElXT1JEKGxwQ2FwdGlvbikpCgkgIExvYWRTdHJpbmdXKGhJbnN0YW5jZSwgKERXT1JEKWxwQ2FwdGlvbiwgc3pUaXRsZSwgc2l6ZW9mKHN6VGl0bGUpL3NpemVvZihzelRpdGxlWzBdKSk7CgllbHNlCgkgIHBzelRpdGxlID0gbHBDYXB0aW9uOwoKCWlmICghSElXT1JEKGxwVGV4dCkpCgkgIExvYWRTdHJpbmdXKGhJbnN0YW5jZSwgKERXT1JEKWxwVGV4dCwgc3pUZXh0LCBzaXplb2Yoc3pUZXh0KS9zaXplb2Yoc3pUZXh0WzBdKSk7CgllbHNlCgkgIHBzelRleHQgPSBscFRleHQ7CgoJRm9ybWF0TWVzc2FnZVcoRk9STUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSIHwgRk9STUFUX01FU1NBR0VfRlJPTV9TVFJJTkcsCgkJICAgICAgIHBzelRleHQsIDAsIDAsIChMUFdTVFIpJnBzelRlbXAsIDAsICZhcmdzKTsKCgl2YV9lbmQoYXJncyk7CgoJcmV0ID0gTWVzc2FnZUJveFcoaFduZCxwc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKCUxvY2FsRnJlZSgoSExPQ0FMKXBzelRlbXApOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94QQkJCQlbU0hFTEwzMi4xODNdCiAqCiAqIEZvcm1hdCBhbmQgb3V0cHV0IGFuIGVycm9yIG1lc3NhZ2UuCiAqCiAqIFBBUkFNUwogKiAgaEluc3RhbmNlIFtJXSBJbnN0YW5jZSBoYW5kbGUgb2YgbWVzc2FnZSBjcmVhdG9yCiAqICBoV25kICAgICAgW0ldIFdpbmRvdyBoYW5kbGUgb2YgbWVzc2FnZSBjcmVhdG9yCiAqICBscFRleHQgICAgW0ldIFJlc291cmNlIElkIG9mIHRpdGxlIG9yIExQU1RSCiAqICBscENhcHRpb24gW0ldIFJlc291cmNlIElkIG9mIHRpdGxlIG9yIExQU1RSCiAqICB1VHlwZSAgICAgW0ldIFR5cGUgb2YgZXJyb3IgbWVzc2FnZQogKgogKiBSRVRVUk5TCiAqICBBIHJldHVybiB2YWx1ZSBmcm9tIE1lc3NhZ2VCb3hBKCkuCiAqCiAqIE5PVEVTCiAqICAgICBFeHBvcnRlZCBieSBvcmRpbmFsCiAqLwppbnQgV0lOQVBJViBTaGVsbE1lc3NhZ2VCb3hBKAoJSElOU1RBTkNFIGhJbnN0YW5jZSwKCUhXTkQgaFduZCwKCUxQQ1NUUiBscFRleHQsCglMUENTVFIgbHBDYXB0aW9uLAoJVUlOVCB1VHlwZSwKCS4uLikKewoJY2hhcglzelRleHRbMTAwXSxzelRpdGxlWzEwMF07CglMUENTVFIgIHBzelRleHQgPSBzelRleHQsIHBzelRpdGxlID0gc3pUaXRsZSwgcHN6VGVtcDsKCXZhX2xpc3QgYXJnczsKCWludAlyZXQ7CgoJdmFfc3RhcnQoYXJncywgdVR5cGUpOwoJLyogd3ZzcHJpbnRmQShidWYsZm10LCBhcmdzKTsgKi8KCglUUkFDRSgiKCUwOGx4LCUwOGx4LCVwLCVwLCUwOHgpXG4iLAoJKERXT1JEKWhJbnN0YW5jZSwoRFdPUkQpaFduZCxscFRleHQsbHBDYXB0aW9uLHVUeXBlKTsKCglpZiAoIUhJV09SRChscENhcHRpb24pKQoJICBMb2FkU3RyaW5nQShoSW5zdGFuY2UsIChEV09SRClscENhcHRpb24sIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKSk7CgllbHNlCgkgIHBzelRpdGxlID0gbHBDYXB0aW9uOwoKCWlmICghSElXT1JEKGxwVGV4dCkpCgkgIExvYWRTdHJpbmdBKGhJbnN0YW5jZSwgKERXT1JEKWxwVGV4dCwgc3pUZXh0LCBzaXplb2Yoc3pUZXh0KSk7CgllbHNlCgkgIHBzelRleHQgPSBscFRleHQ7CgoJRm9ybWF0TWVzc2FnZUEoRk9STUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSIHwgRk9STUFUX01FU1NBR0VfRlJPTV9TVFJJTkcsCgkJICAgICAgIHBzelRleHQsIDAsIDAsIChMUFNUUikmcHN6VGVtcCwgMCwgJmFyZ3MpOwoKCXZhX2VuZChhcmdzKTsKCglyZXQgPSBNZXNzYWdlQm94QShoV25kLHBzelRlbXAscHN6VGl0bGUsdVR5cGUpOwoJTG9jYWxGcmVlKChITE9DQUwpcHN6VGVtcCk7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ2lzdGVyRHJhZ0Ryb3AJCQkJW1NIRUxMMzIuODZdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJlZ2lzdGVyRHJhZ0Ryb3AoCglIV05EIGhXbmQsCglMUERST1BUQVJHRVQgcERyb3BUYXJnZXQpCnsKCUZJWE1FKCIoJXAsJXApOnN0dWIuXG4iLCBoV25kLCBwRHJvcFRhcmdldCk7CglyZXR1cm4gUmVnaXN0ZXJEcmFnRHJvcChoV25kLCBwRHJvcFRhcmdldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmV2b2tlRHJhZ0Ryb3AJCQkJW1NIRUxMMzIuODddCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJldm9rZURyYWdEcm9wKEhXTkQgaFduZCkKewogICAgRklYTUUoIiglcCk6c3R1Yi5cbiIsaFduZCk7CiAgICByZXR1cm4gUmV2b2tlRHJhZ0Ryb3AoaFduZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRG9EcmFnRHJvcAkJCQkJW1NIRUxMMzIuODhdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpIUkVTVUxUIFdJTkFQSSBTSERvRHJhZ0Ryb3AoCglIV05EIGhXbmQsCglMUERBVEFPQkpFQ1QgbHBEYXRhT2JqZWN0LAoJTFBEUk9QU09VUkNFIGxwRHJvcFNvdXJjZSwKCURXT1JEIGR3T0tFZmZlY3QsCglMUERXT1JEIHBkd0VmZmVjdCkKewogICAgRklYTUUoIiglcCAlcCAlcCAweCUwOGx4ICVwKTpzdHViLlxuIiwKICAgIGhXbmQsIGxwRGF0YU9iamVjdCwgbHBEcm9wU291cmNlLCBkd09LRWZmZWN0LCBwZHdFZmZlY3QpOwoJcmV0dXJuIERvRHJhZ0Ryb3AobHBEYXRhT2JqZWN0LCBscERyb3BTb3VyY2UsIGR3T0tFZmZlY3QsIHBkd0VmZmVjdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFycmFuZ2VXaW5kb3dzCQkJCVtTSEVMTDMyLjE4NF0KICoKICovCldPUkQgV0lOQVBJIEFycmFuZ2VXaW5kb3dzKAoJSFdORCBod25kUGFyZW50LAoJRFdPUkQgZHdSZXNlcnZlZCwKCUxQQ1JFQ1QgbHBSZWN0LAoJV09SRCBjS2lkcywKCUNPTlNUIEhXTkQgKiBscEtpZHMpCnsKICAgIEZJWE1FKCIoJXAgMHglMDhseCAlcCAweCUwNHggJXApOnN0dWIuXG4iLAoJICAgaHduZFBhcmVudCwgZHdSZXNlcnZlZCwgbHBSZWN0LCBjS2lkcywgbHBLaWRzKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaWduYWxGaWxlT3BlbgkJCQlbU0hFTEwzMi4xMDNdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkKU2lnbmFsRmlsZU9wZW4gKERXT1JEIGR3UGFyYW0xKQp7CiAgICBGSVhNRSgiKDB4JTA4bHgpOnN0dWIuXG4iLCBkd1BhcmFtMSk7CgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2dldF9wb2xpY3kgLSBoZWxwZXIgZnVuY3Rpb24gZm9yIFNIQWRkVG9SZWNlbnREb2NzCiAqCiAqIFBBUkFNRVRFUlMKICogICBwb2xpY3kgICAgW0lOXSAgcG9saWN5IG5hbWUgKG51bGwgdGVybWVkIHN0cmluZykgdG8gZmluZAogKiAgIHR5cGUgICAgICBbT1VUXSBwdHIgdG8gRFdPUkQgdG8gcmVjZWl2ZSB0eXBlCiAqICAgYnVmZmVyICAgIFtPVVRdIHB0ciB0byBhcmVhIHRvIGhvbGQgZGF0YSByZXRyaWV2ZWQKICogICBsZW4gICAgICAgW0lOL09VVF0gcHRyIHRvIERXT1JEIGhvbGRpbmcgc2l6ZSBvZiBidWZmZXIgYW5kIGdldHRpbmcKICogICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoIGZpbGxlZAogKgogKiBSRVRVUk5TCiAqICAgcmVzdWx0IG9mIHRoZSBTSFF1ZXJ5VmFsdWVFeCBjYWxsCiAqLwpzdGF0aWMgSU5UIFNIQUREX2dldF9wb2xpY3koTFBTVFIgcG9saWN5LCBMUERXT1JEIHR5cGUsIExQVk9JRCBidWZmZXIsIExQRFdPUkQgbGVuKQp7CiAgICBIS0VZIFBvbGljeV9iYXNla2V5OwogICAgSU5UIHJldDsKCiAgICAvKiBHZXQgdGhlIGtleSBmb3IgdGhlIHBvbGljaWVzIGxvY2F0aW9uIGluIHRoZSByZWdpc3RyeQogICAgICovCiAgICBpZiAoUmVnT3BlbktleUV4QShIS0VZX0xPQ0FMX01BQ0hJTkUsCgkJICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcRXhwbG9yZXIiLAoJCSAgICAgIDAsIEtFWV9SRUFELCAmUG9saWN5X2Jhc2VrZXkpKSB7CgoJaWYgKFJlZ09wZW5LZXlFeEEoSEtFWV9DVVJSRU5UX1VTRVIsCgkJCSAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcRXhwbG9yZXIiLAoJCQkgIDAsIEtFWV9SRUFELCAmUG9saWN5X2Jhc2VrZXkpKSB7CgkgICAgVFJBQ0UoIk5vIEV4cGxvcmVyIFBvbGljaWVzIGxvY2F0aW9uIGV4aXN0cy4gUG9saWN5IHdhbnRlZD0lc1xuIiwKCQkgIHBvbGljeSk7CgkgICAgKmxlbiA9IDA7CgkgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQogICAgfQoKICAgIC8qIFJldHJpZXZlIHRoZSBkYXRhIGlmIGl0IGV4aXN0cwogICAgICovCiAgICByZXQgPSBTSFF1ZXJ5VmFsdWVFeEEoUG9saWN5X2Jhc2VrZXksIHBvbGljeSwgMCwgdHlwZSwgYnVmZmVyLCBsZW4pOwogICAgUmVnQ2xvc2VLZXkoUG9saWN5X2Jhc2VrZXkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2NvbXBhcmVfbXJ1IC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgZGF0YTEgICAgIFtJTl0gZGF0YSBiZWluZyBsb29rZWQgZm9yCiAqICAgZGF0YTIgICAgIFtJTl0gZGF0YSBpbiBNUlUKICogICBjYmRhdGEgICAgW0lOXSBsZW5ndGggZnJvbSBGaW5kTVJVRGF0YSBjYWxsIChub3QgdXNlZCkKICoKICogUkVUVVJOUwogKiAgIHBvc2l0aW9uIHdpdGhpbiBNUlUgbGlzdCB0aGF0IGRhdGEgd2FzIGFkZGVkLgogKi8Kc3RhdGljIElOVCBDQUxMQkFDSyBTSEFERF9jb21wYXJlX21ydShMUENWT0lEIGRhdGExLCBMUENWT0lEIGRhdGEyLCBEV09SRCBjYkRhdGEpCnsKICAgIHJldHVybiBsc3RyY21waUEoZGF0YTEsIGRhdGEyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YSAtIGhlbHBlciBmdW5jdGlvbiBmb3IgU0hBZGRUb1JlY2VudERvY3MKICoKICogUEFSQU1FVEVSUwogKiAgIG1ydWhhbmRsZSAgICBbSU5dIGhhbmRsZSBmb3IgY3JlYXRlZCBNUlUgbGlzdAogKiAgIGRvY19uYW1lICAgICBbSU5dIG51bGwgdGVybWVkIHB1cmUgZG9jIG5hbWUKICogICBuZXdfbG5rX25hbWUgW0lOXSBudWxsIHRlcm1lZCBwYXRoIGFuZCBmaWxlIG5hbWUgZm9yIC5sbmsgZmlsZQogKiAgIGJ1ZmZlciAgICAgICBbSU4vT1VUXSAyMDQ4IGJ5dGUgYXJlYSB0byBjb25zdHVyY3QgTVJVIGRhdGEKICogICBsZW4gICAgICAgICAgW09VVF0gcHRyIHRvIGludCB0byByZWNlaXZlIHNwYWNlIHVzZWQgaW4gYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogICBwb3NpdGlvbiB3aXRoaW4gTVJVIGxpc3QgdGhhdCBkYXRhIHdhcyBhZGRlZC4KICovCnN0YXRpYyBJTlQgU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YShIQU5ETEUgbXJ1aGFuZGxlLCBMUFNUUiBkb2NfbmFtZSwgTFBTVFIgbmV3X2xua19uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgYnVmZmVyLCBJTlQgKmxlbikKewogICAgTFBTVFIgcHRyOwogICAgSU5UIHdsZW47CgogICAgLypGSVhNRTogRG9jdW1lbnQ6CiAgICAgKiAgUmVjZW50RG9jcyBNUlUgZGF0YSBzdHJ1Y3R1cmUgc2VlbXMgdG8gYmU6CiAgICAgKiAgICArMGggICBkb2N1bWVudCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuaCAgIHNob3J0IGludCB3LyBzaXplIG9mIHJlbWFpbmluZwogICAgICogICAgK24rMmggMDJoIDMwaCwgb3IgMDFoIDMwaCwgb3IgMDBoIDMwaCAgLSAgdW5rbm93bgogICAgICogICAgK24rNGggMTAgYnl0ZXMgemVyb3MgIC0gICB1bmtub3duCiAgICAgKiAgICArbitlaCBzaG9ydGN1dCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuK2UrbmggMyB6ZXJvIGJ5dGVzICAtICB1bmtub3duCiAgICAgKi8KCiAgICAvKiBDcmVhdGUgdGhlIE1SVSBkYXRhIHN0cnVjdHVyZSBmb3IgIlJlY2VudERvY3MiCgkgKi8KICAgIHB0ciA9IGJ1ZmZlcjsKICAgIGxzdHJjcHlBKHB0ciwgZG9jX25hbWUpOwogICAgcHRyICs9IChsc3RybGVuQShidWZmZXIpICsgMSk7CiAgICB3bGVuPSBsc3RybGVuQShuZXdfbG5rX25hbWUpICsgMSArIDEyOwogICAgKigoc2hvcnQgaW50KilwdHIpID0gd2xlbjsKICAgIHB0ciArPSAyOyAgIC8qIHN0ZXAgcGFzdCB0aGUgbGVuZ3RoICovCiAgICAqKHB0cisrKSA9IDB4MzA7ICAvKiB1bmtub3duIHJlYXNvbiAqLwogICAgKihwdHIrKykgPSAwOyAgICAgLyogdW5rbm93biwgYnV0IGNhbiBiZSAweDAwLCAweDAxLCAweDAyICovCiAgICBtZW1zZXQocHRyLCAwLCAxMCk7CiAgICBwdHIgKz0gMTA7CiAgICBsc3RyY3B5QShwdHIsIG5ld19sbmtfbmFtZSk7CiAgICBwdHIgKz0gKGxzdHJsZW5BKG5ld19sbmtfbmFtZSkgKyAxKTsKICAgIG1lbXNldChwdHIsIDAsIDMpOwogICAgcHRyICs9IDM7CiAgICAqbGVuID0gcHRyIC0gYnVmZmVyOwoKICAgIC8qIEFkZCB0aGUgbmV3IGVudHJ5IGludG8gdGhlIE1SVSBsaXN0CiAgICAgKi8KICAgIHJldHVybiBBZGRNUlVEYXRhKG1ydWhhbmRsZSwgKExQQ1ZPSUQpYnVmZmVyLCAqbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBZGRUb1JlY2VudERvY3MJCQkJW1NIRUxMMzIuQF0KICoKICogUEFSQU1FVEVSUwogKiAgIHVGbGFncyAgW0lOXSBTSEFSRF9QQVRIIG9yIFNIQVJEX1BJREwKICogICBwdiAgICAgIFtJTl0gc3RyaW5nIG9yIHBpZGwsIE5VTEwgY2xlYXJzIHRoZSBsaXN0CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqLwp2b2lkIFdJTkFQSSBTSEFkZFRvUmVjZW50RG9jcyAoVUlOVCB1RmxhZ3MsTFBDVk9JRCBwdikKewovKiBJZiBsaXN0IGlzIGEgc3RyaW5nIGxpc3QgbHBmbkNvbXBhcmUgaGFzIHRoZSBmb2xsb3dpbmcgcHJvdG90eXBlCiAqIGludCBDQUxMQkFDSyBNUlVDb21wYXJlU3RyaW5nKExQQ1NUUiBzMSwgTFBDU1RSIHMyKQogKiBmb3IgYmluYXJ5IGxpc3RzIHRoZSBwcm90b3R5cGUgaXMKICogaW50IENBTExCQUNLIE1SVUNvbXBhcmVCaW5hcnkoTFBDVk9JRCBkYXRhMSwgTFBDVk9JRCBkYXRhMiwgRFdPUkQgY2JEYXRhKQogKiB3aGVyZSBjYkRhdGEgaXMgdGhlIG5vLiBvZiBieXRlcyB0byBjb21wYXJlLgogKiBOZWVkIHRvIGNoZWNrIHdoYXQgcmV0dXJuIHZhbHVlIG1lYW5zIGlkZW50aWNhbCAtIDA/CiAqLwoKCiAgICBVSU5UIG9sZGVycm9ybW9kZTsKICAgIEhLRVkgSENVYmFzZWtleTsKICAgIENIQVIgZG9jX25hbWVbTUFYX1BBVEhdOwogICAgQ0hBUiBsaW5rX2RpcltNQVhfUEFUSF07CiAgICBDSEFSIG5ld19sbmtfZmlsZXBhdGhbTUFYX1BBVEhdOwogICAgQ0hBUiBuZXdfbG5rX25hbWVbTUFYX1BBVEhdOwogICAgSU1hbGxvYyAqcHBNOwogICAgTFBJVEVNSURMSVNUIHBpZGw7CiAgICBIV05EIGh3bmQgPSAwOyAgICAgICAvKiBGSVhNRTogIGdldCByZWFsIHdpbmRvdyBoYW5kbGUgKi8KICAgIElOVCByZXQ7CiAgICBEV09SRCBkYXRhWzY0XSwgZGF0YWxlbiwgdHlwZTsKCiAgICAvKkZJWE1FOiBEb2N1bWVudDoKICAgICAqICBSZWNlbnREb2NzIE1SVSBkYXRhIHN0cnVjdHVyZSBzZWVtcyB0byBiZToKICAgICAqICAgICswaCAgIGRvY3VtZW50IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK25oICAgc2hvcnQgaW50IHcvIHNpemUgb2YgcmVtYWluaW5nCiAgICAgKiAgICArbisyaCAwMmggMzBoLCBvciAwMWggMzBoLCBvciAwMGggMzBoICAtICB1bmtub3duCiAgICAgKiAgICArbis0aCAxMCBieXRlcyB6ZXJvcyAgLSAgIHVua25vd24KICAgICAqICAgICtuK2VoIHNob3J0Y3V0IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK24rZStuaCAzIHplcm8gYnl0ZXMgIC0gIHVua25vd24KICAgICAqLwoKICAgIC8qIFNlZSBpZiB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nLgogICAgICovCiAgICBkYXRhbGVuID0gNjQ7CiAgICByZXQ9U0hBRERfZ2V0X3BvbGljeSggIk5vUmVjZW50RG9jc0hpc3RvcnkiLCAmdHlwZSwgJmRhdGEsICZkYXRhbGVuKTsKICAgIGlmICgocmV0ID4gMCkgJiYgKHJldCAhPSBFUlJPUl9GSUxFX05PVF9GT1VORCkpIHsKCUVSUigiRXJyb3IgJWQgZ2V0dGluZyBwb2xpY3kgXCJOb1JlY2VudERvY3NIaXN0b3J5XCJcbiIsIHJldCk7CglyZXR1cm47CiAgICB9CiAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MpIHsKCWlmICghKCAodHlwZSA9PSBSRUdfRFdPUkQpIHx8CgkgICAgICAgKCh0eXBlID09IFJFR19CSU5BUlkpICYmIChkYXRhbGVuID09IDQpKSApKSB7CgkgICAgRVJSKCJFcnJvciBwb2xpY3kgZGF0YSBmb3IgXCJOb1JlY2VudERvY3NIaXN0b3J5XCIgbm90IGZvcm1hdGVkIGNvcnJlY3RseSwgdHlwZT0lbGQsIGxlbj0lbGRcbiIsCgkJdHlwZSwgZGF0YWxlbik7CgkgICAgcmV0dXJuOwoJfQoKCVRSQUNFKCJwb2xpY3kgdmFsdWUgZm9yIE5vUmVjZW50RG9jc0hpc3RvcnkgPSAlMDhseFxuIiwgZGF0YVswXSk7CgkvKiBub3cgdGVzdCB0aGUgYWN0dWFsIHBvbGljeSB2YWx1ZSAqLwoJaWYgKCBkYXRhWzBdICE9IDApCgkgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIE9wZW4ga2V5IHRvIHdoZXJlIHRoZSBuZWNlc3NhcnkgaW5mbyBpcwogICAgICovCiAgICAvKiBGSVhNRTogVGhpcyBzaG91bGQgYmUgZG9uZSBkdXJpbmcgRExMIFBST0NFU1NfQVRUQUNIIChvciBUSFJFQURfQVRUQUNIKQogICAgICogICAgICAgIGFuZCB0aGUgY2xvc2Ugc2hvdWxkIGJlIGRvbmUgZHVyaW5nIHRoZSBfREVUQUNILiBUaGUgcmVzdWx0aW5nCiAgICAgKiAgICAgICAga2V5IGlzIHN0b3JlZCBpbiB0aGUgRExMIGdsb2JhbCBkYXRhLgogICAgICovCiAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKEhLRVlfQ1VSUkVOVF9VU0VSLAoJCQkiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyIiwKCQkJMCwgMCwgMCwgS0VZX1JFQUQsIDAsICZIQ1ViYXNla2V5LCAwKSkgewoJRVJSKCJGYWlsZWQgdG8gY3JlYXRlICdTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcRXhwbG9yZXInXG4iKTsKCXJldHVybjsKICAgIH0KCiAgICAvKiBHZXQgcGF0aCB0byB1c2VyJ3MgIlJlY2VudCIgZGlyZWN0b3J5CiAgICAgKi8KICAgIGlmKFNVQ0NFRURFRChTSEdldE1hbGxvYygmcHBNKSkpIHsKCWlmIChTVUNDRUVERUQoU0hHZXRTcGVjaWFsRm9sZGVyTG9jYXRpb24oaHduZCwgQ1NJRExfUkVDRU5ULAoJCQkJCQkgJnBpZGwpKSkgewoJICAgIFNIR2V0UGF0aEZyb21JRExpc3RBKHBpZGwsIGxpbmtfZGlyKTsKCSAgICBJTWFsbG9jX0ZyZWUocHBNLCBwaWRsKTsKCX0KCWVsc2UgewoJICAgIC8qIHNlcmlvdXMgaXNzdWVzICovCgkgICAgbGlua19kaXJbMF0gPSAwOwoJICAgIEVSUigic2VyaW91cyBpc3N1ZXMgMVxuIik7Cgl9CglJTWFsbG9jX1JlbGVhc2UocHBNKTsKICAgIH0KICAgIGVsc2UgewoJLyogc2VyaW91cyBpc3N1ZXMgKi8KCWxpbmtfZGlyWzBdID0gMDsKCUVSUigic2VyaW91cyBpc3N1ZXMgMlxuIik7CiAgICB9CiAgICBUUkFDRSgiVXNlcnMgUmVjZW50IGRpciAlc1xuIiwgbGlua19kaXIpOwoKICAgIC8qIElmIG5vIGlucHV0LCB0aGVuIGdvIGNsZWFyIHRoZSBsaXN0cyAqLwogICAgaWYgKCFwdikgewoJLyogY2xlYXIgdXNlcidzIFJlY2VudCBkaXIKCSAqLwoKCS8qIEZJWE1FOiBkZWxldGUgYWxsIGZpbGVzIGluICJsaW5rX2RpciIKCSAqCgkgKiB3aGlsZSggbW9yZSBmaWxlcyApIHsKCSAqICAgIGxzdHJjcHlBKG9sZF9sbmtfbmFtZSwgbGlua19kaXIpOwoJICogICAgUGF0aEFwcGVuZEEob2xkX2xua19uYW1lLCBmaWxlbmFtKTsKCSAqICAgIERlbGV0ZUZpbGVBKG9sZF9sbmtfbmFtZSk7CgkgKiB9CgkgKi8KCUZJWE1FKCJzaG91bGQgZGVsZXRlIGFsbCBmaWxlcyBpbiAlc1xcIFxuIiwgbGlua19kaXIpOwoKCS8qIGNsZWFyIE1SVSBsaXN0CgkgKi8KCS8qIE1TIEJ1ZyA/PyB2NC43Mi4zNjEyLjE3MDAgb2Ygc2hlbGwzMiBkb2VzIHRoZSBkZWxldGUgYWdhaW5zdAoJICogIEhLRVlfTE9DQUxfTUFDSElORSB2ZXJzaW9uIG9mIC4uLkN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyCgkgKiAgYW5kIG5hdHVyYWxseSBpdCBmYWlscyB3LyByYz0yLiBJdCBzaG91bGQgZG8gaXQgYWdhaW5zdAoJICogIEhLRVlfQ1VSUkVOVF9VU0VSIHdoaWNoIGlzIHdoZXJlIGl0IGlzIHN0b3JlZCwgYW5kIHdoZXJlCgkgKiAgdGhlIE1SVSByb3V0aW5lcyBleHBlY3QgaXQhISEhCgkgKi8KCVJlZ0RlbGV0ZUtleUEoSENVYmFzZWtleSwgIlJlY2VudERvY3MiKTsKCVJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEhhdmUgZGF0YSB0byBhZGQsIHRoZSBqb2JzIHRvIGJlIGRvbmU6CiAgICAgKiAgIDEuIEFkZCBkb2N1bWVudCB0byBNUlUgbGlzdCBpbiByZWdpc3RyeSAiSEtDVVxTb2Z0d2FyZVwKICAgICAqICAgICAgTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXJcUmVjZW50RG9jcyIuCiAgICAgKiAgIDIuIEFkZCBzaG9ydGN1dCB0byBkb2N1bWVudCBpbiB0aGUgdXNlcidzIFJlY2VudCBkaXJlY3RvcnkKICAgICAqICAgICAgKENTSURMX1JFQ0VOVCkuCiAgICAgKiAgIDMuIEFkZCBzaG9ydGN1dCB0byBTdGFydCBtZW51J3MgRG9jdW1lbnRzIHN1Ym1lbnUuCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHB1cmUgZG9jdW1lbnQgbmFtZSBmcm9tIHRoZSBpbnB1dAogICAgICovCiAgICBpZiAodUZsYWdzICYgU0hBUkRfUElETCkgewoJU0hHZXRQYXRoRnJvbUlETGlzdEEoKExQQ0lURU1JRExJU1QpIHB2LCBkb2NfbmFtZSk7CiAgICB9CiAgICBlbHNlIHsKCWxzdHJjcHlBKGRvY19uYW1lLCAoTFBTVFIpIHB2KTsKICAgIH0KICAgIFRSQUNFKCJmdWxsIGRvY3VtZW50IG5hbWUgJXNcbiIsIGRvY19uYW1lKTsKICAgIFBhdGhTdHJpcFBhdGhBKGRvY19uYW1lKTsKICAgIFRSQUNFKCJzdHJpcHBlZCBkb2N1bWVudCBuYW1lICVzXG4iLCBkb2NfbmFtZSk7CgoKICAgIC8qICoqKiAgSk9CIDE6IFVwZGF0ZSByZWdpc3RyeSBmb3IgLi4uXEV4cGxvcmVyXFJlY2VudERvY3MgbGlzdCAgKioqICovCgogICAgeyAgLyogb24gaW5wdXQgbmVlZHM6CgkqICAgICAgZG9jX25hbWUgICAgLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGgKCSogICAgICBsaW5rX2RpciAgICAtICBwYXRoIHRvIHRoZSB1c2VyJ3MgUmVjZW50IGRpcmVjdG9yeQoJKiAgICAgIEhDVWJhc2VrZXkgIC0gIGtleSBvZiAuLi5XaW5kb3dzXEN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyIiBub2RlCgkqIGNyZWF0ZXM6CgkqICAgICAgbmV3X2xua19uYW1lLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGggZm9yIG5ldyAubG5rIGZpbGUKCSogICAgICBuZXdfbG5rX2ZpbGVwYXRoCgkqICAgICAgICAgICAgICAgICAgLSAgcGF0aCBhbmQgZmlsZSBuYW1lIG9mIG5ldyAubG5rIGZpbGUKCSovCglDUkVBVEVNUlVMSVNUQSBteW1ydTsKCUhBTkRMRSBtcnVoYW5kbGU7CglJTlQgbGVuLCBwb3MsIGJ1ZnVzZWQsIGVycjsKCUlOVCBpOwoJRFdPUkQgYXR0cjsKCUNIQVIgYnVmZmVyWzIwNDhdOwoJQ0hBUiAqcHRyOwoJQ0hBUiBvbGRfbG5rX25hbWVbTUFYX1BBVEhdOwoJc2hvcnQgaW50IHNsZW47CgoJbXltcnUuY2JTaXplID0gc2l6ZW9mKENSRUFURU1SVUxJU1RBKTsKCW15bXJ1Lm5NYXhJdGVtcyA9IDE1OwoJbXltcnUuZHdGbGFncyA9IE1SVUZfQklOQVJZX0xJU1QgfCBNUlVGX0RFTEFZRURfU0FWRTsKCW15bXJ1LmhLZXkgPSBIQ1ViYXNla2V5OwoJbXltcnUubHBzelN1YktleSA9ICJSZWNlbnREb2NzIjsKCW15bXJ1LmxwZm5Db21wYXJlID0gJlNIQUREX2NvbXBhcmVfbXJ1OwoJbXJ1aGFuZGxlID0gQ3JlYXRlTVJVTGlzdEEoJm15bXJ1KTsKCWlmICghbXJ1aGFuZGxlKSB7CgkgICAgLyogTVJVIGZhaWxlZCAqLwoJICAgIEVSUigiTVJVIHByb2Nlc3NpbmcgZmFpbGVkLCBoYW5kbGUgemVyb1xuIik7CgkgICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CgkgICAgcmV0dXJuOwoJfQoJbGVuID0gbHN0cmxlbkEoZG9jX25hbWUpOwoJcG9zID0gRmluZE1SVURhdGEobXJ1aGFuZGxlLCBkb2NfbmFtZSwgbGVuLCAwKTsKCgkvKiBOb3cgZ2V0IHRoZSBNUlUgZW50cnkgdGhhdCB3aWxsIGJlIHJlcGxhY2VkCgkgKiBhbmQgZGVsZXRlIHRoZSAubG5rIGZpbGUgZm9yIGl0CgkgKi8KCWlmICgoYnVmdXNlZCA9IEVudW1NUlVMaXN0QShtcnVoYW5kbGUsIChwb3MgPT0gLTEpID8gMTQgOiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgMjA0OCkpICE9IC0xKSB7CgkgICAgcHRyID0gYnVmZmVyOwoJICAgIHB0ciArPSAobHN0cmxlbkEoYnVmZmVyKSArIDEpOwoJICAgIHNsZW4gPSAqKChzaG9ydCBpbnQqKXB0cik7CgkgICAgcHRyICs9IDI7ICAvKiBza2lwIHRoZSBsZW5ndGggYXJlYSAqLwoJICAgIGlmIChidWZ1c2VkID49IHNsZW4gKyAocHRyLWJ1ZmZlcikpIHsKCQkvKiBidWZmZXIgc2l6ZSBsb29rcyBnb29kICovCgkJcHRyICs9IDEyOyAvKiBnZXQgdG8gc3RyaW5nICovCgkJbGVuID0gYnVmdXNlZCAtIChwdHItYnVmZmVyKTsgIC8qIGdldCBsZW5ndGggb2YgYnVmIHJlbWFpbmluZyAqLwoJCWlmICgobHN0cmxlbkEocHRyKSA+IDApICYmIChsc3RybGVuQShwdHIpIDw9IGxlbi0xKSkgewoJCSAgICAvKiBhcHBlYXJzIHRvIGJlIGdvb2Qgc3RyaW5nICovCgkJICAgIGxzdHJjcHlBKG9sZF9sbmtfbmFtZSwgbGlua19kaXIpOwoJCSAgICBQYXRoQXBwZW5kQShvbGRfbG5rX25hbWUsIHB0cik7CgkJICAgIGlmICghRGVsZXRlRmlsZUEob2xkX2xua19uYW1lKSkgewoJCQlpZiAoKGF0dHIgPSBHZXRGaWxlQXR0cmlidXRlc0Eob2xkX2xua19uYW1lKSkgPT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpIHsKCQkJICAgIGlmICgoZXJyID0gR2V0TGFzdEVycm9yKCkpICE9IEVSUk9SX0ZJTEVfTk9UX0ZPVU5EKSB7CgkJCQlFUlIoIkRlbGV0ZSBmb3IgJXMgZmFpbGVkLCBlcnI9JWQsIGF0dHI9JTA4bHhcbiIsCgkJCQkgICAgb2xkX2xua19uYW1lLCBlcnIsIGF0dHIpOwoJCQkgICAgfQoJCQkgICAgZWxzZSB7CgkJCQlUUkFDRSgib2xkIC5sbmsgZmlsZSAlcyBkaWQgbm90IGV4aXN0XG4iLAoJCQkJICAgICAgb2xkX2xua19uYW1lKTsKCQkJICAgIH0KCQkJfQoJCQllbHNlIHsKCQkJICAgIEVSUigiRGVsZXRlIGZvciAlcyBmYWlsZWQsIGF0dHI9JTA4bHhcbiIsCgkJCQlvbGRfbG5rX25hbWUsIGF0dHIpOwoJCQl9CgkJICAgIH0KCQkgICAgZWxzZSB7CgkJCVRSQUNFKCJkZWxldGVkIG9sZCAubG5rIGZpbGUgJXNcbiIsIG9sZF9sbmtfbmFtZSk7CgkJICAgIH0KCQl9CgkgICAgfQoJfQoKCS8qIENyZWF0ZSB1c2FibGUgLmxuayBmaWxlIG5hbWUgZm9yIHRoZSAiUmVjZW50IiBkaXJlY3RvcnkKCSAqLwoJd3NwcmludGZBKG5ld19sbmtfbmFtZSwgIiVzLmxuayIsIGRvY19uYW1lKTsKCWxzdHJjcHlBKG5ld19sbmtfZmlsZXBhdGgsIGxpbmtfZGlyKTsKCVBhdGhBcHBlbmRBKG5ld19sbmtfZmlsZXBhdGgsIG5ld19sbmtfbmFtZSk7CglpID0gMTsKCW9sZGVycm9ybW9kZSA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCXdoaWxlIChHZXRGaWxlQXR0cmlidXRlc0EobmV3X2xua19maWxlcGF0aCkgIT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpIHsKCSAgICBpKys7CgkgICAgd3NwcmludGZBKG5ld19sbmtfbmFtZSwgIiVzICgldSkubG5rIiwgZG9jX25hbWUsIGkpOwoJICAgIGxzdHJjcHlBKG5ld19sbmtfZmlsZXBhdGgsIGxpbmtfZGlyKTsKCSAgICBQYXRoQXBwZW5kQShuZXdfbG5rX2ZpbGVwYXRoLCBuZXdfbG5rX25hbWUpOwoJfQoJU2V0RXJyb3JNb2RlKG9sZGVycm9ybW9kZSk7CglUUkFDRSgibmV3IHNob3J0Y3V0IHdpbGwgYmUgJXNcbiIsIG5ld19sbmtfZmlsZXBhdGgpOwoKCS8qIE5vdyBhZGQgdGhlIG5ldyBNUlUgZW50cnkgYW5kIGRhdGEKCSAqLwoJcG9zID0gU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YShtcnVoYW5kbGUsIGRvY19uYW1lLCBuZXdfbG5rX25hbWUsCgkJCQkJYnVmZmVyLCAmbGVuKTsKCUZyZWVNUlVMaXN0KG1ydWhhbmRsZSk7CglUUkFDRSgiVXBkYXRlZCBNUlUgbGlzdCwgbmV3IGRvYyBpcyBwb3NpdGlvbiAlZFxuIiwgcG9zKTsKICAgIH0KCiAgICAvKiAqKiogIEpPQiAyOiBDcmVhdGUgc2hvcnRjdXQgaW4gdXNlcidzICJSZWNlbnQiIGRpcmVjdG9yeSAgKioqICovCgogICAgeyAgLyogb24gaW5wdXQgbmVlZHM6CgkqICAgICAgZG9jX25hbWUgICAgLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGgKCSogICAgICBuZXdfbG5rX2ZpbGVwYXRoCgkqICAgICAgICAgICAgICAgICAgLSAgcGF0aCBhbmQgZmlsZSBuYW1lIG9mIG5ldyAubG5rIGZpbGUKIAkqICAgICAgdUZsYWdzW2luXSAgLSAgZmxhZ3Mgb24gY2FsbCB0byBTSEFkZFRvUmVjZW50RG9jcwoJKiAgICAgIHB2W2luXSAgICAgIC0gIGRvY3VtZW50IHBhdGgvcGlkbCBvbiBjYWxsIHRvIFNIQWRkVG9SZWNlbnREb2NzCgkqLwoJSVNoZWxsTGlua0EgKnBzbCA9IE5VTEw7CglJUGVyc2lzdEZpbGUgKnBQZiA9IE5VTEw7CglIUkVTVUxUIGhyZXM7CglDSEFSIGRlc2NbTUFYX1BBVEhdOwoJV0NIQVIgd2lkZWxpbmtbTUFYX1BBVEhdOwoKCUNvSW5pdGlhbGl6ZSgwKTsKCglocmVzID0gQ29DcmVhdGVJbnN0YW5jZSggJkNMU0lEX1NoZWxsTGluaywKCQkJCSBOVUxMLAoJCQkJIENMU0NUWF9JTlBST0NfU0VSVkVSLAoJCQkJICZJSURfSVNoZWxsTGlua0EsCgkJCQkgKExQVk9JRCApJnBzbCk7CglpZihTVUNDRUVERUQoaHJlcykpIHsKCgkgICAgaHJlcyA9IElTaGVsbExpbmtBX1F1ZXJ5SW50ZXJmYWNlKHBzbCwgJklJRF9JUGVyc2lzdEZpbGUsCgkJCQkJICAgICAoTFBWT0lEICopJnBQZik7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgUXVlcnlJbnRlcmZhY2UgZm9yIElQZXJzaXN0RmlsZSAlMDhseFxuIiwgaHJlcyk7CgkJZ290byBmYWlsOwoJICAgIH0KCgkgICAgLyogU2V0IHRoZSBkb2N1bWVudCBwYXRoIG9yIHBpZGwgKi8KCSAgICBpZiAodUZsYWdzICYgU0hBUkRfUElETCkgewoJCWhyZXMgPSBJU2hlbGxMaW5rQV9TZXRJRExpc3QocHNsLCAoTFBDSVRFTUlETElTVCkgcHYpOwoJICAgIH0gZWxzZSB7CgkJaHJlcyA9IElTaGVsbExpbmtBX1NldFBhdGgocHNsLCAoTFBDU1RSKSBwdik7CgkgICAgfQoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFNldHtJRExpc3R8UGF0aH0gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIGxzdHJjcHlBKGRlc2MsICJTaG9ydGN1dCB0byAiKTsKCSAgICBsc3RyY2F0QShkZXNjLCBkb2NfbmFtZSk7CgkgICAgaHJlcyA9IElTaGVsbExpbmtBX1NldERlc2NyaXB0aW9uKHBzbCwgZGVzYyk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgU2V0RGVzY3JpcHRpb24gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBuZXdfbG5rX2ZpbGVwYXRoLCAtMSwKCQkJCXdpZGVsaW5rLCBNQVhfUEFUSCk7CgkgICAgLyogY3JlYXRlIHRoZSBzaG9ydCBjdXQgKi8KCSAgICBocmVzID0gSVBlcnNpc3RGaWxlX1NhdmUocFBmLCB3aWRlbGluaywgVFJVRSk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgSVBlcnNpc3RGaWxlOjpTYXZlICUwOGx4XG4iLCBocmVzKTsKCQlJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJCUlTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoJICAgIGhyZXMgPSBJUGVyc2lzdEZpbGVfU2F2ZUNvbXBsZXRlZChwUGYsIHdpZGVsaW5rKTsKCSAgICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJICAgIElTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCSAgICBUUkFDRSgic2hvcnRjdXQgJXMgaGFzIGJlZW4gY3JlYXRlZCwgcmVzdWx0PSUwOGx4XG4iLAoJCSAgbmV3X2xua19maWxlcGF0aCwgaHJlcyk7Cgl9CgllbHNlIHsKCSAgICBFUlIoIkNvQ3JlYXRlSW5zdGFuY2UgZmFpbGVkLCBocmVzPSUwOGx4XG4iLCBocmVzKTsKCX0KICAgIH0KCiBmYWlsOgogICAgQ29VbmluaXRpYWxpemUoKTsKCiAgICAvKiBhbGwgZG9uZSAqLwogICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgJCQlbU0hFTEwzMi4xNzRdCiAqCiAqIE5PVEVTCiAqICBzZWUgSVNoZWxsRm9sZGVyOjpDcmVhdGVWaWV3T2JqZWN0CiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4KAoJTFBDU0hFTExGT0xERVJWSUVXSU5GTyBwc3ZjYmksIC8qIFtpbl0gc2hlbGx0ZW1wbGF0ZSBzdHJ1Y3QgKi8KCUxQU0hFTExWSUVXKiBwcHYpICAgICAgICAgICAgICAvKiBbb3V0XSBJU2hlbGxWaWV3IHBvaW50ZXIgKi8KewoJSVNoZWxsVmlldyAqIHBzZjsKCUhSRVNVTFQgaFJlczsKCglUUkFDRSgic2Y9JXAgcGlkbD0lcCBjYj0lcCBtb2RlPTB4JTA4eCBwYXJtPTB4JTA4bHhcbiIsCgkgIHBzdmNiaS0+cHNoZiwgcHN2Y2JpLT5waWRsRm9sZGVyLCBwc3ZjYmktPmxwZm5DYWxsYmFjaywKCSAgcHN2Y2JpLT51Vmlld01vZGUsIHBzdmNiaS0+ZHdVc2VyKTsKCglwc2YgPSBJU2hlbGxWaWV3X0NvbnN0cnVjdG9yKHBzdmNiaS0+cHNoZik7CgoJaWYgKCFwc2YpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlTaGVsbFZpZXdfQWRkUmVmKHBzZik7CgloUmVzID0gSVNoZWxsVmlld19RdWVyeUludGVyZmFjZShwc2YsICZJSURfSVNoZWxsVmlldywgKExQVk9JRCAqKXBwdik7CglJU2hlbGxWaWV3X1JlbGVhc2UocHNmKTsKCglyZXR1cm4gaFJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix2LHcseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFJ1bkNvbnRyb2xQYW5lbCBbU0hFTEwzMi4xNjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJ1bkNvbnRyb2xQYW5lbCAoRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwoJcmV0dXJuIChIUkVTVUxUKSBscFVua25vd247Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuQF0KICoKICogTk9URVMKICogIGdldHMgdGhlIGludGVyZmFjZSBwb2ludGVyIG9mIHRoZSBleHBsb3JlciBhbmQgYSByZWZlcmVuY2UKICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW5zdGFuY2VFeHBsb3JlciAoTFBVTktOT1dOICogbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCgkqbHBVbmtub3duID0gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U7CgoJaWYgKCFTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSkKCSAgcmV0dXJuIEVfRkFJTDsKCglJVW5rbm93bl9BZGRSZWYoU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpOwoJcmV0dXJuIE5PRVJST1I7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlVW51c2VkTGlicmFyaWVzCQkJW1NIRUxMMzIuMTIzXQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8Kdm9pZCBXSU5BUEkgU0hGcmVlVW51c2VkTGlicmFyaWVzICh2b2lkKQp7CglGSVhNRSgic3R1YlxuIik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0F1dG9TY3JvbGwJCQkJW1NIRUxMMzIuMTI5XQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0F1dG9TY3JvbGwoSFdORCBod25kLCBBVVRPX1NDUk9MTF9EQVRBICpzYW1wbGVzLCBMUFBPSU5UIHB0KQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICVwICVwXG4iLGh3bmQsc2FtcGxlcyxwdCk7CiAgICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0VudGVyCQkJCVtTSEVMTDMyLjEzMF0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnRW50ZXIoSFdORCBod25kKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwXG4iLGh3bmQpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnRW50ZXJFeAkJCQlbU0hFTEwzMi4xMzFdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyRXgoSFdORCBod25kLCBQT0lOVCBwKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICglbGQsJWxkKVxuIixod25kLHAueCxwLnkpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnTW92ZQkJCQlbU0hFTEwzMi4xMzRdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ01vdmUoUE9JTlQgcCkKewogICAgRklYTUUoIiglbGQsJWxkKVxuIixwLngscC55KTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0xlYXZlCQkJCVtTSEVMTDMyLjEzMl0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnTGVhdmUoVk9JRCkKewogICAgRklYTUUoIlxuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1NldERyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzZdCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpCT09MIFdJTkFQSSBEQURfU2V0RHJhZ0ltYWdlKAoJSElNQUdFTElTVCBoaW1sVHJhY2ssCglMUFBPSU5UIGxwcHQpCnsKCUZJWE1FKCIlcCAlcCBzdHViXG4iLGhpbWxUcmFjaywgbHBwdCk7CiAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1Nob3dEcmFnSW1hZ2UJCQkJW1NIRUxMMzIuMTM3XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KQk9PTCBXSU5BUEkgREFEX1Nob3dEcmFnSW1hZ2UoQk9PTCBiU2hvdykKewoJRklYTUUoIjB4JTA4eCBzdHViXG4iLGJTaG93KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgV0NIQVIgc3p3Q2FiTG9jYXRpb25bXSA9IHsKICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKICAnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAogICdDJywnYScsJ2InLCdpJywnbicsJ2UnLCd0JywnUycsJ3QnLCdhJywndCcsJ2UnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzendTZXR0aW5nc1tdID0geyAnUycsJ2UnLCd0JywndCcsJ2knLCduJywnZycsJ3MnLDAgfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRDYWJpbmV0U3RhdGUJCQkJW1NIRUxMMzIuNjUxXSBOVCA0LjAKICoKICovCkJPT0wgV0lOQVBJIFJlYWRDYWJpbmV0U3RhdGUoQ0FCSU5FVFNUQVRFICpjcywgaW50IGxlbmd0aCkKewoJSEtFWSBoa2V5ID0gMDsKCURXT1JEIHR5cGUsIHI7CgoJVFJBQ0UoIiVwICVkIFxuIixjcyxsZW5ndGgpOwoKCWlmKCAoY3MgPT0gTlVMTCkgfHwgKGxlbmd0aCA8IChpbnQpc2l6ZW9mKCpjcykpICApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdPcGVuS2V5VyggSEtFWV9DVVJSRU5UX1VTRVIsIHN6d0NhYkxvY2F0aW9uLCAmaGtleSApOwoJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJdHlwZSA9IFJFR19CSU5BUlk7CgkJciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIHN6d1NldHRpbmdzLCAKCQkJTlVMTCwgJnR5cGUsIChMUEJZVEUpY3MsIChMUERXT1JEKSZsZW5ndGggKTsKCQlSZWdDbG9zZUtleSggaGtleSApOwoJCQkKCX0KCgkvKiBpZiB3ZSBjYW4ndCByZWFkIGZyb20gdGhlIHJlZ2lzdHJ5LCBjcmVhdGUgZGVmYXVsdCB2YWx1ZXMgKi8KCWlmICggKHIgIT0gRVJST1JfU1VDQ0VTUykgfHwgKGNzLT5jTGVuZ3RoIDwgc2l6ZW9mKCpjcykpIHx8CgkJKGNzLT5jTGVuZ3RoICE9IGxlbmd0aCkgKQoJewoJCUVSUigiSW5pdGlhbGl6aW5nIHNoZWxsIGNhYmluZXQgc2V0dGluZ3NcbiIpOwoJCW1lbXNldChjcywgMCwgc2l6ZW9mKCpjcykpOwoJCWNzLT5jTGVuZ3RoICAgICAgICAgID0gc2l6ZW9mKCpjcyk7CgkJY3MtPm5WZXJzaW9uICAgICAgICAgPSAyOwoJCWNzLT5mRnVsbFBhdGhUaXRsZSAgID0gRkFMU0U7CgkJY3MtPmZTYXZlTG9jYWxWaWV3ICAgPSBUUlVFOwoJCWNzLT5mTm90U2hlbGwgICAgICAgID0gRkFMU0U7CgkJY3MtPmZTaW1wbGVEZWZhdWx0ICAgPSBUUlVFOwoJCWNzLT5mRG9udFNob3dEZXNjQmFyID0gRkFMU0U7CgkJY3MtPmZOZXdXaW5kb3dNb2RlICAgPSBGQUxTRTsKCQljcy0+ZlNob3dDb21wQ29sb3IgICA9IEZBTFNFOwoJCWNzLT5mRG9udFByZXR0eU5hbWVzID0gRkFMU0U7CgkJY3MtPmZBZG1pbnNDcmVhdGVDb21tb25Hcm91cHMgPSBUUlVFOwoJCWNzLT5mTWVudUVudW1GaWx0ZXIgID0gOTY7Cgl9CgkKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0ZUNhYmluZXRTdGF0ZQkJCQlbU0hFTEwzMi42NTJdIE5UIDQuMAogKgogKi8KQk9PTCBXSU5BUEkgV3JpdGVDYWJpbmV0U3RhdGUoQ0FCSU5FVFNUQVRFICpjcykKewoJRFdPUkQgcjsKCUhLRVkgaGtleSA9IDA7CgoJVFJBQ0UoIiVwXG4iLGNzKTsKCglpZiggY3MgPT0gTlVMTCApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdDcmVhdGVLZXlFeFcoIEhLRVlfQ1VSUkVOVF9VU0VSLCBzendDYWJMb2NhdGlvbiwgMCwKCQkgTlVMTCwgMCwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsICZoa2V5LCBOVUxMKTsKCWlmKCByID09IEVSUk9SX1NVQ0NFU1MgKQoJewoJCXIgPSBSZWdTZXRWYWx1ZUV4VyggaGtleSwgc3p3U2V0dGluZ3MsIDAsIAoJCQlSRUdfQklOQVJZLCAoTFBCWVRFKSBjcywgY3MtPmNMZW5ndGgpOwoKCQlSZWdDbG9zZUtleSggaGtleSApOwoJfQoKCXJldHVybiAocj09RVJST1JfU1VDQ0VTUyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbGVJY29uSW5pdCAJCQkJW1NIRUxMMzIuNjYwXQogKgogKi8KQk9PTCBXSU5BUEkgRmlsZUljb25Jbml0KEJPT0wgYkZ1bGxJbml0KQp7CUZJWE1FKCIoJXMpXG4iLCBiRnVsbEluaXQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElzVXNlckFkbWluCQkJCQlbU0hFTEwzMi42ODBdIE5UIDQuMAogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNVc2VyQWRtaW4odm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvY1NoYXJlZAkJCQlbU0hFTEwzMi41MjBdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIEhlYXBBbGxvYwogKiAgcGFyYW1ldGVyMiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBhbGxvY2F0ZWQgd2l0aCBIZWFwQWxsb2MKICogIHBhcmFtZXRlcjMgaXMgcmV0dXJuIHZhbHVlIGZyb20gR2V0Q3VycmVudFByb2Nlc3NJZAogKgogKiAgdGhlIHJldHVybiB2YWx1ZSBpcyBwb3N0ZWQgYXMgbFBhcmFtIHdpdGggMHg0MDIgKFdNX1VTRVIrMikgdG8gc29tZXdoZXJlCiAqICBXTV9VU0VSKzIgY291bGQgYmUgdGhlIHVuZG9jdW1lbnRlZCBDV01fU0VUUEFUSAogKiAgdGhlIGFsbG9jYXRlZCBtZW1vcnkgY29udGFpbnMgYSBwaWRsCiAqLwpIR0xPQkFMIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQVk9JRCBwc3JjLCBEV09SRCBzaXplLCBEV09SRCBwcm9jSUQpCnsJSEdMT0JBTCBobWVtOwoJTFBWT0lEIHBtZW07CgoJVFJBQ0UoInB0cj0lcCBzaXplPTB4JTA0bHggcHJvY0lEPTB4JTA0bHhcbiIscHNyYyxzaXplLHByb2NJRCk7CglobWVtID0gR2xvYmFsQWxsb2MoR01FTV9GSVhFRCwgc2l6ZSk7CglpZiAoIWhtZW0pCgkgIHJldHVybiAwOwoKCXBtZW0gPSAgR2xvYmFsTG9jayAoaG1lbSk7CgoJaWYgKCEgcG1lbSkKCSAgcmV0dXJuIDA7CgoJbWVtY3B5IChwbWVtLCBwc3JjLCBzaXplKTsKCUdsb2JhbFVubG9jayhobWVtKTsKCXJldHVybiBobWVtOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9ja1NoYXJlZAkJCQkJW1NIRUxMMzIuNTIxXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSEFsbG9jU2hhcmVkCiAqICBwYXJhbWV0ZXIyIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICogIHRoZSByZWNlaXZlciBvZiAoV01fVVNFUisyKSB0cmllcyB0byBsb2NrIHRoZSBIQU5ETEUgKD8pCiAqICB0aGUgcmV0dXJuIHZhbHVlIHNlZW1zIHRvIGJlIGEgbWVtb3J5IGFkZHJlc3MKICovCkxQVk9JRCBXSU5BUEkgU0hMb2NrU2hhcmVkKEhBTkRMRSBobWVtLCBEV09SRCBwcm9jSUQpCnsJVFJBQ0UoImhhbmRsZT0lcCBwcm9jSUQ9MHglMDRseFxuIixobWVtLHByb2NJRCk7CglyZXR1cm4gR2xvYmFsTG9jayhobWVtKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFVubG9ja1NoYXJlZAkJCQlbU0hFTEwzMi41MjJdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIFNITG9ja1NoYXJlZAogKi8KQk9PTCBXSU5BUEkgU0hVbmxvY2tTaGFyZWQoTFBWT0lEIHB2KQp7CglUUkFDRSgiJXBcbiIscHYpOwoJcmV0dXJuIEdsb2JhbFVubG9jaygoSEFORExFKXB2KTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZyZWVTaGFyZWQJCQkJCVtTSEVMTDMyLjUyM10KICoKICogTk9URVMKICogIHBhcmFtZXRlcjEgaXMgcmV0dXJuIHZhbHVlIGZyb20gU0hBbGxvY1NoYXJlZAogKiAgcGFyYW1ldGVyMiBpcyByZXR1cm4gdmFsdWUgZnJvbSBHZXRDdXJyZW50UHJvY2Vzc0lkCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoCglIQU5ETEUgaE1lbSwKCURXT1JEIHBpZCkKewoJVFJBQ0UoImhhbmRsZT0lcCAweCUwNGx4XG4iLGhNZW0scGlkKTsKCXJldHVybiAoQk9PTClHbG9iYWxGcmVlKGhNZW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXRBcHBTdGFydGluZ0N1cnNvcgkJCQlbU0hFTEwzMi45OV0KICovCkhSRVNVTFQgV0lOQVBJIFNldEFwcFN0YXJ0aW5nQ3Vyc29yKEhXTkQgdSwgRFdPUkQgdikKewlGSVhNRSgiaHduZD0lcCAweCUwNGx4IHN0dWJcbiIsdSx2ICk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExvYWRPTEUJCQkJCVtTSEVMTDMyLjE1MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNITG9hZE9MRShEV09SRCB1KQp7CUZJWE1FKCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gU19PSzsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEcml2ZVR5cGUJCQkJCVtTSEVMTDMyLjY0XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRHJpdmVUeXBlKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWJvcnRJbnZva2VDb21tYW5kCQkJCVtTSEVMTDMyLjE5OF0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIQWJvcnRJbnZva2VDb21tYW5kKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hPdXRPZk1lbW9yeU1lc3NhZ2VCb3gJCQlbU0hFTEwzMi4xMjZdCiAqCiAqLwppbnQgV0lOQVBJIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94KAoJSFdORCBod25kT3duZXIsCglMUENTVFIgbHBDYXB0aW9uLAoJVUlOVCB1VHlwZSkKewoJRklYTUUoIiVwICVzIDB4JTA4eCBzdHViXG4iLGh3bmRPd25lciwgbHBDYXB0aW9uLCB1VHlwZSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZsdXNoQ2xpcGJvYXJkCQkJCVtTSEVMTDMyLjEyMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIRmx1c2hDbGlwYm9hcmQodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hXYWl0Rm9yRmlsZVRvT3BlbgkJCQlbU0hFTEwzMi45N10KICoKICovCkJPT0wgV0lOQVBJIFNIV2FpdEZvckZpbGVUb09wZW4oCglMUENJVEVNSURMSVNUIHBpZGwsCglEV09SRCBkd0ZsYWdzLAoJRFdPUkQgZHdUaW1lb3V0KQp7CglGSVhNRSgiJXAgMHglMDhseCAweCUwOGx4IHN0dWJcbiIsIHBpZGwsIGR3RmxhZ3MsIGR3VGltZW91dCk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglACQkJCVtTSEVMTDMyLjY1NF0KICoKICogTk9URVM6IGZpcnN0IHBhcmFtZXRlciBzZWVtcyB0byBiZSBhIHBvaW50ZXIgKHNhbWUgYXMgcGFzc2VkIHRvIFdyaXRlQ2FiaW5ldFN0YXRlKQogKiBzZWNvbmQgb25lIGNvdWxkIGJlIGEgc2l6ZSAoMHgwYykuIFRoZSBzaXplIGlzIHRoZSBzYW1lIGFzIHRoZSBzdHJ1Y3R1cmUgc2F2ZWQgdG8KICogSENVXFNvZnR3YXJlXE1pY3Jvc29mdFxXaW5kb3dzXEN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyXENhYmluZXRTdGF0ZQogKiBJJ20gKGpzKSBndWVzc2luZzogdGhpcyBvbmUgaXMganVzdCBSZWFkQ2FiaW5ldFN0YXRlIDstKQogKi8KSFJFU1VMVCBXSU5BUEkgc2hlbGwzMl82NTQgKENBQklORVRTVEFURSAqY3MsIGludCBsZW5ndGgpCnsKCVRSQUNFKCIlcCAlZFxuIixjcyxsZW5ndGgpOwoJcmV0dXJuIFJlYWRDYWJpbmV0U3RhdGUoY3MsbGVuZ3RoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglSTEJ1aWxkTGlzdE9mUGF0aHMJCQlbU0hFTEwzMi4xNDZdCiAqCiAqIE5PVEVTCiAqICAgYnVpbGRzIGEgRFBBCiAqLwpEV09SRCBXSU5BUEkgUkxCdWlsZExpc3RPZlBhdGhzICh2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hWYWxpZGF0ZVVOQwkJCQlbU0hFTEwzMi4xNzNdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFZhbGlkYXRlVU5DIChEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CglGSVhNRSgiMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHkseik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3RBCQkJW1NIRUxMMzIuQF0KICoKICovCkhSRVNVTFQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdEEoTFBTVFIgeCwgTFBTVFIgeSkKewoJRklYTUUoIiglcywgJXMpIHN0dWJcbiIsIGRlYnVnc3RyX2EoeCksIGRlYnVnc3RyX2EoeSkpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0VwkJCVtTSEVMTDMyLkBdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RXKExQV1NUUiB4LCBMUFdTVFIgeSkKewoJRklYTUUoIiglcywgJXMpOiBzdHViXG4iLCBkZWJ1Z3N0cl93KHgpLCBkZWJ1Z3N0cl93KHkpKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCURvRW52aXJvbm1lbnRTdWJzdAkJCVtTSEVMTDMyLjUzXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRG9FbnZpcm9ubWVudFN1YnN0QVcoTFBWT0lEIHgsIExQVk9JRCB5KQp7CglpZiAoU0hFTExfT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdFcoeCwgeSk7CglyZXR1cm4gRG9FbnZpcm9ubWVudFN1YnN0QSh4LCB5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbU0hFTEwzMi4yNDNdCiAqCiAqIFdpbjk4KyBieS1vcmRpbmFsIHJvdXRpbmUuICBJbiBXaW45OCB0aGlzIHJvdXRpbmUgcmV0dXJucyB6ZXJvIGFuZAogKiBkb2VzIG5vdGhpbmcgZWxzZS4gIFBvc3NpYmx5IHRoaXMgZG9lcyBzb21ldGhpbmcgaW4gTlQgb3IgU0hFTEwzMiA1LjA/CiAqCiAqLwoKQk9PTCBXSU5BUEkgc2hlbGwzMl8yNDMoRFdPUkQgYSwgRFdPUkQgYikKewogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSEVMTDMyLjcxNF0KICovCkRXT1JEIFdJTkFQSSBTSEVMTDMyXzcxNChMUFZPSUQgeCkKewogCUZJWE1FKCIoJXMpc3R1YlxuIiwgZGVidWdzdHJfdyh4KSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSEFkZEZyb21Qcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjddCiAqLwpEV09SRCBXSU5BUEkgU0hBZGRGcm9tUHJvcFNoZWV0RXh0QXJyYXkoRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYykKewogCUZJWE1FKCIoJTA4bHgsJTA4bHgsJTA4bHgpc3R1YlxuIiwgYSwgYiwgYyk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSENyZWF0ZVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE2OF0KICovCkRXT1JEIFdJTkFQSSBTSENyZWF0ZVByb3BTaGVldEV4dEFycmF5KERXT1JEIGEsIExQQ1NUUiBiLCBEV09SRCBjKQp7CiAJRklYTUUoIiglMDhseCwlcywlMDhseClzdHViXG4iLCBhLCBkZWJ1Z3N0cl9hKGIpLCBjKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIUmVwbGFjZUZyb21Qcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNzBdCiAqLwpEV09SRCBXSU5BUEkgU0hSZXBsYWNlRnJvbVByb3BTaGVldEV4dEFycmF5KERXT1JEIGEsIERXT1JEIGIsIERXT1JEIGMsIERXT1JEIGQpCnsKIAlGSVhNRSgiKCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4KXN0dWJcbiIsIGEsIGIsIGMsIGQpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hEZXN0cm95UHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTY5XQogKi8KRFdPUkQgV0lOQVBJIFNIRGVzdHJveVByb3BTaGVldEV4dEFycmF5KERXT1JEIGEpCnsKIAlGSVhNRSgiKCUwOGx4KXN0dWJcbiIsIGEpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQ0lETERhdGFfQ3JlYXRlRnJvbUlEQXJyYXkJW1NIRUxMMzIuODNdCiAqCiAqICBDcmVhdGUgSURhdGFPYmplY3QgZnJvbSBQSURMcz8/CiAqLwpIUkVTVUxUIFdJTkFQSSBDSURMRGF0YV9DcmVhdGVGcm9tSURBcnJheSgKCUxQQ0lURU1JRExJU1QgcGlkbEZvbGRlciwKCURXT1JEIGNwaWRsRmlsZXMsCglMUENJVEVNSURMSVNUICpscHBpZGxGaWxlcywKCUxQREFUQU9CSkVDVCAqcHBkYXRhT2JqZWN0KQp7CiAgICBVSU5UIGk7CiAgICBIV05EIGh3bmQgPSAwOyAgIC8qRklYTUU6IHdobyBzaG91bGQgYmUgaHduZCBvZiBvd25lcj8gc2V0IHRvIGRlc2t0b3AgKi8KCiAgICBUUkFDRSgiKCVwLCAlbGQsICVwLCAlcClcbiIsIHBpZGxGb2xkZXIsIGNwaWRsRmlsZXMsIGxwcGlkbEZpbGVzLCBwcGRhdGFPYmplY3QpOwogICAgaWYgKFRSQUNFX09OKHBpZGwpKQogICAgewoJcGR1bXAgKHBpZGxGb2xkZXIpOwoJZm9yIChpPTA7IGk8Y3BpZGxGaWxlczsgaSsrKSBwZHVtcCAobHBwaWRsRmlsZXNbaV0pOwogICAgfQogICAgKnBwZGF0YU9iamVjdCA9IElEYXRhT2JqZWN0X0NvbnN0cnVjdG9yKCBod25kLCBwaWRsRm9sZGVyLAoJCQkJCSAgICAgbHBwaWRsRmlsZXMsIGNwaWRsRmlsZXMpOwogICAgaWYgKCpwcGRhdGFPYmplY3QpIHJldHVybiBTX09LOwogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU3RkRW51bUZtdEV0YwkJCVtTSEVMTDMyLjc0XQogKgogKiBOT1RFUwogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVTdGRFbnVtRm10RXRjKAoJRFdPUkQgY0Zvcm1hdHMsCgljb25zdCBGT1JNQVRFVEMgKmxwRm9ybWF0cywKCUxQRU5VTUZPUk1BVEVUQyAqcHBlbnVtRm9ybWF0ZXRjKQp7CglJRW51bUZPUk1BVEVUQyAqcGVmOwoJSFJFU1VMVCBoUmVzOwoJVFJBQ0UoImNmPSVsZCBmZT0lcCBwZWY9JXBcbiIsIGNGb3JtYXRzLCBscEZvcm1hdHMsIHBwZW51bUZvcm1hdGV0Yyk7CgoJcGVmID0gSUVudW1GT1JNQVRFVENfQ29uc3RydWN0b3IoY0Zvcm1hdHMsIGxwRm9ybWF0cyk7CglpZiAoIXBlZikKCSAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgoJSUVudW1GT1JNQVRFVENfQWRkUmVmKHBlZik7CgloUmVzID0gSUVudW1GT1JNQVRFVENfUXVlcnlJbnRlcmZhY2UocGVmLCAmSUlEX0lFbnVtRk9STUFURVRDLCAoTFBWT0lEKilwcGVudW1Gb3JtYXRldGMpOwoJSUVudW1GT1JNQVRFVENfUmVsZWFzZShwZWYpOwoKCXJldHVybiBoUmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIRUxMMzJfMjU2IChTSEVMTDMyLjI1NikKICovCkhSRVNVTFQgV0lOQVBJIFNIRUxMMzJfMjU2KExQRFdPUkQgbHBkdzAsIExQRFdPUkQgbHBkdzEpCnsKICAgIEhSRVNVTFQgcmV0ID0gU19PSzsKCiAgICBGSVhNRSgic3R1YiAlcCAweCUwOGx4ICVwXG4iLCBscGR3MCwgbHBkdzAgPyAqbHBkdzAgOiAwLCBscGR3MSk7CgogICAgaWYgKCFscGR3MCB8fCAqbHBkdzAgIT0gMHgxMCkKICAgICAgICByZXQgPSBFX0lOVkFMSURBUkc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgTFBWT0lEIGxwZGF0YSA9IDA7LypMb2NhbEFsbG9jKEdNRU1fWkVST0lOSVQsIDB4NEU0KTsqLwoKCWlmICghbHBkYXRhKQogICAgICAgICAgICByZXQgPSBFX09VVE9GTUVNT1JZOwoJZWxzZQoJewogICAgICAgICAgICAvKiBJbml0aWFsaXplIGFuZCByZXR1cm4gdW5rbm93biBscGRhdGEgc3RydWN0dXJlICovCgl9CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIRmluZEZpbGVzIChTSEVMTDMyLjkwKQogKi8KQk9PTCBXSU5BUEkgU0hGaW5kRmlsZXMoIExQQ0lURU1JRExJU1QgcGlkbEZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsU2F2ZUZpbGUgKQp7CiAgICBGSVhNRSgiJXAgJXBcbiIsIHBpZGxGb2xkZXIsIHBpZGxTYXZlRmlsZSApOwogICAgcmV0dXJuIEZBTFNFOwp9Cg==