LyoKICogR0xTTCBwaXhlbCBhbmQgdmVydGV4IHNoYWRlciBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwNiBKYXNvbiBHcmVlbiAKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBIZW5yaSBWZXJiZWV0CiAqIENvcHlyaWdodCAyMDA3LTIwMDggU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKgogKiBEM0Qgc2hhZGVyIGFzbSBoYXMgc3dpenpsZXMgb24gc291cmNlIHBhcmFtZXRlcnMsIGFuZCB3cml0ZSBtYXNrcyBmb3IKICogZGVzdGluYXRpb24gcGFyYW1ldGVycy4gR0xTTCB1c2VzIHN3aXp6bGVzIGZvciBib3RoLiBUaGUgcmVzdWx0IG9mIHRoaXMgaXMKICogdGhhdCBmb3IgZXhhbXBsZSAibW92IGRzdC54dywgc3JjLnp5eHciIGJlY29tZXMgImRzdC54dyA9IHNyYy56dyIgaW4gR0xTTC4KICogSWUsIHRvIGdlbmVyYXRlIGEgcHJvcGVyIEdMU0wgc291cmNlIHN3aXp6bGUsIHdlIG5lZWQgdG8gdGFrZSB0aGUgRDNEIHdyaXRlCiAqIG1hc2sgZm9yIHRoZSBkZXN0aW5hdGlvbiBwYXJhbWV0ZXIgaW50byBhY2NvdW50LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zaGFkZXIpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChkM2RfY29uc3RhbnRzKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZDNkX2NhcHMpOwoKI2RlZmluZSBHTElORk9fTE9DQVRJT04gICAgICAoKmdsX2luZm8pCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjaGFyIHJlZ19uYW1lWzE1MF07CiAgICBjaGFyIG1hc2tfc3RyWzZdOwp9IGdsc2xfZHN0X3BhcmFtX3Q7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjaGFyIHJlZ19uYW1lWzE1MF07CiAgICBjaGFyIHBhcmFtX3N0clsxMDBdOwp9IGdsc2xfc3JjX3BhcmFtX3Q7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjb25zdCBjaGFyICpuYW1lOwogICAgRFdPUkQgY29vcmRfbWFzazsKfSBnbHNsX3NhbXBsZV9mdW5jdGlvbl90OwoKLyoqIFByaW50cyB0aGUgR0xTTCBpbmZvIGxvZyB3aGljaCB3aWxsIGNvbnRhaW4gZXJyb3IgbWVzc2FnZXMgaWYgdGhleSBleGlzdCAqLwp2b2lkIHByaW50X2dsc2xfaW5mb19sb2coV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBHTGhhbmRsZUFSQiBvYmopIHsKICAgIAogICAgaW50IGluZm9sb2dMZW5ndGggPSAwOwogICAgY2hhciAqaW5mb0xvZzsKICAgIGludCBpOwogICAgQk9PTCBpc19zcGFtOwoKICAgIGNvbnN0IGNoYXIgKnNwYW1bXSA9IHsKICAgICAgICAiVmVydGV4IHNoYWRlciB3YXMgc3VjY2Vzc2Z1bGx5IGNvbXBpbGVkIHRvIHJ1biBvbiBoYXJkd2FyZS5cbiIsICAgIC8qIGZnbHJ4ICAgICAgICAgICovCiAgICAgICAgIkZyYWdtZW50IHNoYWRlciB3YXMgc3VjY2Vzc2Z1bGx5IGNvbXBpbGVkIHRvIHJ1biBvbiBoYXJkd2FyZS5cbiIsICAvKiBmZ2xyeCAgICAgICAgICAqLwogICAgICAgICJGcmFnbWVudCBzaGFkZXIocykgbGlua2VkLCB2ZXJ0ZXggc2hhZGVyKHMpIGxpbmtlZC4gXG4gIiwgICAgICAgICAgLyogZmdscngsIHdpdGggXG4gKi8KICAgICAgICAiRnJhZ21lbnQgc2hhZGVyKHMpIGxpbmtlZCwgdmVydGV4IHNoYWRlcihzKSBsaW5rZWQuIiwgICAgICAgICAgICAgIC8qIGZnbHJ4LCBubyBcbiAgICovCiAgICAgICAgIlZlcnRleCBzaGFkZXIocykgbGlua2VkLCBubyBmcmFnbWVudCBzaGFkZXIocykgZGVmaW5lZC4gXG4gIiwgICAgICAvKiBmZ2xyeCwgd2l0aCBcbiAqLwogICAgICAgICJWZXJ0ZXggc2hhZGVyKHMpIGxpbmtlZCwgbm8gZnJhZ21lbnQgc2hhZGVyKHMpIGRlZmluZWQuIiwgICAgICAgICAgLyogZmdscngsIG5vIFxuICAgKi8KICAgICAgICAiRnJhZ21lbnQgc2hhZGVyIHdhcyBzdWNjZXNzZnVsbHkgY29tcGlsZWQgdG8gcnVuIG9uIGhhcmR3YXJlLlxuV0FSTklORzogMDoxOiBleHRlbnNpb24gJ0dMX0FSQl9kcmF3X2J1ZmZlcnMnIGlzIG5vdCBzdXBwb3J0ZWQiLAogICAgICAgICJGcmFnbWVudCBzaGFkZXIocykgbGlua2VkLCBubyB2ZXJ0ZXggc2hhZGVyKHMpIGRlZmluZWQuIiwgICAgICAgICAgLyogZmdscngsIG5vIFxuICAgKi8KICAgICAgICAiRnJhZ21lbnQgc2hhZGVyKHMpIGxpbmtlZCwgbm8gdmVydGV4IHNoYWRlcihzKSBkZWZpbmVkLiBcbiAiLCAgICAgIC8qIGZnbHJ4LCB3aXRoIFxuICovCiAgICAgICAgIldBUk5JTkc6IDA6MjogZXh0ZW5zaW9uICdHTF9BUkJfZHJhd19idWZmZXJzJyBpcyBub3Qgc3VwcG9ydGVkXG4iICAvKiBNYWNPUyBhdGkgICAgICAqLwogICAgfTsKCiAgICBHTF9FWFRDQUxMKGdsR2V0T2JqZWN0UGFyYW1ldGVyaXZBUkIob2JqLAogICAgICAgICAgICAgICBHTF9PQkpFQ1RfSU5GT19MT0dfTEVOR1RIX0FSQiwKICAgICAgICAgICAgICAgJmluZm9sb2dMZW5ndGgpKTsKCiAgICAvKiBBIHNpemUgb2YgMSBpcyBqdXN0IGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZywgc28gdGhlIGxvZyBzaG91bGQgYmUgYmlnZ2VyIHRoYW4KICAgICAqIHRoYXQgaWYgdGhlcmUgYXJlIGVycm9ycy4gKi8KICAgIGlmIChpbmZvbG9nTGVuZ3RoID4gMSkKICAgIHsKICAgICAgICAvKiBGZ2xyeCBkb2Vzbid0IHRlcm1pbmF0ZSB0aGUgc3RyaW5nIHByb3Blcmx5LCBidXQgaXQgdGVsbHMgdXMgdGhlIHByb3BlciBsZW5ndGguCiAgICAgICAgICogU28gdXNlIEhFQVBfWkVST19NRU1PUlkgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBieXRlcwogICAgICAgICAqLwogICAgICAgIGluZm9Mb2cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgaW5mb2xvZ0xlbmd0aCk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEdldEluZm9Mb2dBUkIob2JqLCBpbmZvbG9nTGVuZ3RoLCBOVUxMLCBpbmZvTG9nKSk7CiAgICAgICAgaXNfc3BhbSA9IEZBTFNFOwoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBzaXplb2Yoc3BhbSkgLyBzaXplb2Yoc3BhbVswXSk7IGkrKykgewogICAgICAgICAgICBpZihzdHJjbXAoaW5mb0xvZywgc3BhbVtpXSkgPT0gMCkgewogICAgICAgICAgICAgICAgaXNfc3BhbSA9IFRSVUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihpc19zcGFtKSB7CiAgICAgICAgICAgIFRSQUNFKCJTcGFtIHJlY2VpdmVkIGZyb20gR0xTTCBzaGFkZXIgIyV1OiAlc1xuIiwgb2JqLCBkZWJ1Z3N0cl9hKGluZm9Mb2cpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiRXJyb3IgcmVjZWl2ZWQgZnJvbSBHTFNMIHNoYWRlciAjJXU6ICVzXG4iLCBvYmosIGRlYnVnc3RyX2EoaW5mb0xvZykpOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvTG9nKTsKICAgIH0KfQoKLyoqCiAqIExvYWRzIChwaXhlbCBzaGFkZXIpIHNhbXBsZXJzCiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX3BzYW1wbGVycygKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgIElXaW5lRDNEU3RhdGVCbG9jayogaWZhY2UsCiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtSWQpIHsKCiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsKiBzdGF0ZUJsb2NrID0gKElXaW5lRDNEU3RhdGVCbG9ja0ltcGwqKSBpZmFjZTsKICAgIEdMaGFuZGxlQVJCIG5hbWVfbG9jOwogICAgaW50IGk7CiAgICBjaGFyIHNhbXBsZXJfbmFtZVsyMF07CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9GUkFHTUVOVF9TQU1QTEVSUzsgKytpKSB7CiAgICAgICAgc25wcmludGYoc2FtcGxlcl9uYW1lLCBzaXplb2Yoc2FtcGxlcl9uYW1lKSwgIlBzYW1wbGVyJWQiLCBpKTsKICAgICAgICBuYW1lX2xvYyA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBzYW1wbGVyX25hbWUpKTsKICAgICAgICBpZiAobmFtZV9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgaW50IG1hcHBlZF91bml0ID0gc3RhdGVCbG9jay0+d2luZUQzRERldmljZS0+dGV4VW5pdE1hcFtpXTsKICAgICAgICAgICAgaWYgKG1hcHBlZF91bml0ICE9IC0xICYmIG1hcHBlZF91bml0IDwgR0xfTElNSVRTKGZyYWdtZW50X3NhbXBsZXJzKSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIkxvYWRpbmcgJXMgZm9yIHRleHR1cmUgJWRcbiIsIHNhbXBsZXJfbmFtZSwgbWFwcGVkX3VuaXQpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xaUFSQihuYW1lX2xvYywgbWFwcGVkX3VuaXQpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaUFSQiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJUcnlpbmcgdG8gbG9hZCBzYW1wbGVyICVzIG9uIHVuc3VwcG9ydGVkIHVuaXQgJWRcbiIsIHNhbXBsZXJfbmFtZSwgbWFwcGVkX3VuaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX3ZzYW1wbGVycyhXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8sIElXaW5lRDNEU3RhdGVCbG9jayogaWZhY2UsIEdMaGFuZGxlQVJCIHByb2dyYW1JZCkgewogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCogc3RhdGVCbG9jayA9IChJV2luZUQzRFN0YXRlQmxvY2tJbXBsKikgaWZhY2U7CiAgICBHTGhhbmRsZUFSQiBuYW1lX2xvYzsKICAgIGNoYXIgc2FtcGxlcl9uYW1lWzIwXTsKICAgIGludCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfVkVSVEVYX1NBTVBMRVJTOyArK2kpIHsKICAgICAgICBzbnByaW50ZihzYW1wbGVyX25hbWUsIHNpemVvZihzYW1wbGVyX25hbWUpLCAiVnNhbXBsZXIlZCIsIGkpOwogICAgICAgIG5hbWVfbG9jID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIHNhbXBsZXJfbmFtZSkpOwogICAgICAgIGlmIChuYW1lX2xvYyAhPSAtMSkgewogICAgICAgICAgICBpbnQgbWFwcGVkX3VuaXQgPSBzdGF0ZUJsb2NrLT53aW5lRDNERGV2aWNlLT50ZXhVbml0TWFwW01BWF9GUkFHTUVOVF9TQU1QTEVSUyArIGldOwogICAgICAgICAgICBpZiAobWFwcGVkX3VuaXQgIT0gLTEgJiYgbWFwcGVkX3VuaXQgPCBHTF9MSU1JVFMoY29tYmluZWRfc2FtcGxlcnMpKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTG9hZGluZyAlcyBmb3IgdGV4dHVyZSAlZFxuIiwgc2FtcGxlcl9uYW1lLCBtYXBwZWRfdW5pdCk7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTFpQVJCKG5hbWVfbG9jLCBtYXBwZWRfdW5pdCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTFpQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBFUlIoIlRyeWluZyB0byBsb2FkIHNhbXBsZXIgJXMgb24gdW5zdXBwb3J0ZWQgdW5pdCAlZFxuIiwgc2FtcGxlcl9uYW1lLCBtYXBwZWRfdW5pdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKiAKICogTG9hZHMgZmxvYXRpbmcgcG9pbnQgY29uc3RhbnRzIChha2EgdW5pZm9ybXMpIGludG8gdGhlIGN1cnJlbnRseSBzZXQgR0xTTCBwcm9ncmFtLgogKiBXaGVuIGNvbnN0YW50X2xpc3QgPT0gTlVMTCwgaXQgd2lsbCBsb2FkIGFsbCB0aGUgY29uc3RhbnRzLgogKi8Kc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNGKElXaW5lRDNEQmFzZVNoYWRlckltcGwqIFRoaXMsIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgICAgICB1bnNpZ25lZCBpbnQgbWF4X2NvbnN0YW50cywgZmxvYXQqIGNvbnN0YW50cywgR0xoYW5kbGVBUkIgKmNvbnN0YW50X2xvY2F0aW9ucywKICAgICAgICBzdHJ1Y3QgbGlzdCAqY29uc3RhbnRfbGlzdCkgewogICAgY29uc3RhbnRzX2VudHJ5ICpjb25zdGFudDsKICAgIGxvY2FsX2NvbnN0YW50KiBsY29uc3Q7CiAgICBHTGhhbmRsZUFSQiB0bXBfbG9jOwogICAgRFdPUkQgaSwgaiwgazsKICAgIERXT1JEICppZHg7CgogICAgaWYgKFRSQUNFX09OKGQzZF9zaGFkZXIpKSB7CiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShjb25zdGFudCwgY29uc3RhbnRfbGlzdCwgY29uc3RhbnRzX2VudHJ5LCBlbnRyeSkgewogICAgICAgICAgICBpZHggPSBjb25zdGFudC0+aWR4OwogICAgICAgICAgICBqID0gY29uc3RhbnQtPmNvdW50OwogICAgICAgICAgICB3aGlsZSAoai0tKSB7CiAgICAgICAgICAgICAgICBpID0gKmlkeCsrOwogICAgICAgICAgICAgICAgdG1wX2xvYyA9IGNvbnN0YW50X2xvY2F0aW9uc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNbaSAqIDQgKyAwXSwgY29uc3RhbnRzW2kgKiA0ICsgMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNbaSAqIDQgKyAyXSwgY29uc3RhbnRzW2kgKiA0ICsgM10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIDEuWCBwc2hhZGVycyBoYXZlIHRoZSBjb25zdGFudHMgY2xhbXBlZCB0byBbLTE7MV0gaW1wbGljaXRseS4gKi8KICAgIGlmKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA9PSAxICYmCiAgICAgICBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pKSB7CiAgICAgICAgZmxvYXQgbGNsX2NvbnN0WzRdOwoKICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGNvbnN0YW50LCBjb25zdGFudF9saXN0LCBjb25zdGFudHNfZW50cnksIGVudHJ5KSB7CiAgICAgICAgICAgIGlkeCA9IGNvbnN0YW50LT5pZHg7CiAgICAgICAgICAgIGogPSBjb25zdGFudC0+Y291bnQ7CiAgICAgICAgICAgIHdoaWxlIChqLS0pIHsKICAgICAgICAgICAgICAgIGkgPSAqaWR4Kys7CiAgICAgICAgICAgICAgICB0bXBfbG9jID0gY29uc3RhbnRfbG9jYXRpb25zW2ldOwogICAgICAgICAgICAgICAgaWYgKHRtcF9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAvKiBXZSBmb3VuZCB0aGlzIHVuaWZvcm0gbmFtZSBpbiB0aGUgcHJvZ3JhbSAtIGdvIGFoZWFkIGFuZCBzZW5kIHRoZSBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgayA9IGkgKiA0OwogICAgICAgICAgICAgICAgICAgIGlmKGNvbnN0YW50c1trICsgMF0gPCAtMS4wKSBsY2xfY29uc3RbMF0gPSAtMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2sgKyAwXSA+IDEuMCkgbGNsX2NvbnN0WzBdID0gMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzBdID0gY29uc3RhbnRzW2sgKyAwXTsKICAgICAgICAgICAgICAgICAgICBpZihjb25zdGFudHNbayArIDFdIDwgLTEuMCkgbGNsX2NvbnN0WzFdID0gLTEuMDsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGNvbnN0YW50c1trICsgMV0gPiAxLjApIGxjbF9jb25zdFsxXSA9IDEuMDsKICAgICAgICAgICAgICAgICAgICBlbHNlIGxjbF9jb25zdFsxXSA9IGNvbnN0YW50c1trICsgMV07CiAgICAgICAgICAgICAgICAgICAgaWYoY29uc3RhbnRzW2sgKyAyXSA8IC0xLjApIGxjbF9jb25zdFsyXSA9IC0xLjA7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihjb25zdGFudHNbayArIDJdID4gMS4wKSBsY2xfY29uc3RbMl0gPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBsY2xfY29uc3RbMl0gPSBjb25zdGFudHNbayArIDJdOwogICAgICAgICAgICAgICAgICAgIGlmKGNvbnN0YW50c1trICsgM10gPCAtMS4wKSBsY2xfY29uc3RbM10gPSAtMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2sgKyAzXSA+IDEuMCkgbGNsX2NvbnN0WzNdID0gMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzNdID0gY29uc3RhbnRzW2sgKyAzXTsKCiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIodG1wX2xvYywgMSwgbGNsX2NvbnN0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoY29uc3RhbnQsIGNvbnN0YW50X2xpc3QsIGNvbnN0YW50c19lbnRyeSwgZW50cnkpIHsKICAgICAgICAgICAgaWR4ID0gY29uc3RhbnQtPmlkeDsKICAgICAgICAgICAgaiA9IGNvbnN0YW50LT5jb3VudDsKICAgICAgICAgICAgd2hpbGUgKGotLSkgewogICAgICAgICAgICAgICAgaSA9ICppZHgrKzsKICAgICAgICAgICAgICAgIHRtcF9sb2MgPSBjb25zdGFudF9sb2NhdGlvbnNbaV07CiAgICAgICAgICAgICAgICBpZiAodG1wX2xvYyAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTRmdkFSQih0bXBfbG9jLCAxLCBjb25zdGFudHMgKyAoaSAqIDQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGZ2QVJCKCkiKTsKCiAgICBpZighVGhpcy0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YpIHsKICAgICAgICBUUkFDRSgiTm8gbmVlZCB0byBsb2FkIGxvY2FsIGZsb2F0IGNvbnN0YW50cyBmb3IgdGhpcyBzaGFkZXJcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIGlmIChUUkFDRV9PTihkM2Rfc2hhZGVyKSkgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgdG1wX2xvYyA9IGNvbnN0YW50X2xvY2F0aW9uc1tsY29uc3QtPmlkeF07CiAgICAgICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgICAgICBHTGZsb2F0KiB2YWx1ZXMgPSAoR0xmbG9hdCopbGNvbnN0LT52YWx1ZTsKICAgICAgICAgICAgICAgIFRSQUNFXyhkM2RfY29uc3RhbnRzKSgiTG9hZGluZyBsb2NhbCBjb25zdGFudHMgJWk6ICVmLCAlZiwgJWYsICVmXG4iLCBsY29uc3QtPmlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sIHZhbHVlc1syXSwgdmFsdWVzWzNdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8qIEltbWVkaWF0ZSBjb25zdGFudHMgYXJlIGNsYW1wZWQgdG8gWy0xOzFdIGF0IHNoYWRlciBjcmVhdGlvbiB0aW1lIGlmIG5lZWRlZCAqLwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShsY29uc3QsICZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0YsIGxvY2FsX2NvbnN0YW50LCBlbnRyeSkgewogICAgICAgIHRtcF9sb2MgPSBjb25zdGFudF9sb2NhdGlvbnNbbGNvbnN0LT5pZHhdOwogICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIodG1wX2xvYywgMSwgKEdMZmxvYXQqKWxjb25zdC0+dmFsdWUpKTsKICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGZ2QVJCKCkiKTsKfQoKLyoqIAogKiBMb2FkcyBpbnRlZ2VyIGNvbnN0YW50cyAoYWthIHVuaWZvcm1zKSBpbnRvIHRoZSBjdXJyZW50bHkgc2V0IEdMU0wgcHJvZ3JhbS4KICogV2hlbiBAY29uc3RhbnRzX3NldCA9PSBOVUxMLCBpdCB3aWxsIGxvYWQgYWxsIHRoZSBjb25zdGFudHMuCiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0koCiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBUaGlzLAogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLAogICAgR0xoYW5kbGVBUkIgcHJvZ3JhbUlkLAogICAgR0xoYW5kbGVBUkIgbG9jYXRpb25zW01BWF9DT05TVF9JXSwKICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHMsCiAgICBpbnQqIGNvbnN0YW50cywKICAgIEJPT0wqIGNvbnN0YW50c19zZXQpIHsKICAgIAogICAgaW50IGk7CiAgICBzdHJ1Y3QgbGlzdCogcHRyOwoKICAgIGZvciAoaT0wOyBpPG1heF9jb25zdGFudHM7ICsraSkgewogICAgICAgIGlmIChOVUxMID09IGNvbnN0YW50c19zZXQgfHwgY29uc3RhbnRzX3NldFtpXSkgewoKICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWksICVpLCAlaSwgJWlcbiIsCiAgICAgICAgICAgICAgICAgIGksIGNvbnN0YW50c1tpKjRdLCBjb25zdGFudHNbaSo0KzFdLCBjb25zdGFudHNbaSo0KzJdLCBjb25zdGFudHNbaSo0KzNdKTsKCiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00aXZBUkIobG9jYXRpb25zW2ldLCAxLCAmY29uc3RhbnRzW2kqNF0pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTRpdkFSQiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIHB0ciA9IGxpc3RfaGVhZCgmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNJKTsKICAgIHdoaWxlIChwdHIpIHsKICAgICAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0ID0gTElTVF9FTlRSWShwdHIsIHN0cnVjdCBsb2NhbF9jb25zdGFudCwgZW50cnkpOwogICAgICAgIHVuc2lnbmVkIGludCBpZHggPSBsY29uc3QtPmlkeDsKICAgICAgICBHTGludCogdmFsdWVzID0gKEdMaW50KikgbGNvbnN0LT52YWx1ZTsKCiAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWksICVpLCAlaSwgJWlcbiIsIGlkeCwKICAgICAgICAgICAgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sIHZhbHVlc1syXSwgdmFsdWVzWzNdKTsKCiAgICAgICAgLyogV2UgZm91bmQgdGhpcyB1bmlmb3JtIG5hbWUgaW4gdGhlIHByb2dyYW0gLSBnbyBhaGVhZCBhbmQgc2VuZCB0aGUgZGF0YSAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtNGl2QVJCKGxvY2F0aW9uc1tpZHhdLCAxLCB2YWx1ZXMpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGl2QVJCIik7CiAgICAgICAgcHRyID0gbGlzdF9uZXh0KCZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0ksIHB0cik7CiAgICB9Cn0KCi8qKiAKICogTG9hZHMgYm9vbGVhbiBjb25zdGFudHMgKGFrYSB1bmlmb3JtcykgaW50byB0aGUgY3VycmVudGx5IHNldCBHTFNMIHByb2dyYW0uCiAqIFdoZW4gQGNvbnN0YW50c19zZXQgPT0gTlVMTCwgaXQgd2lsbCBsb2FkIGFsbCB0aGUgY29uc3RhbnRzLgogKi8Kc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNCKAogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcywKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgIEdMaGFuZGxlQVJCIHByb2dyYW1JZCwKICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHMsCiAgICBCT09MKiBjb25zdGFudHMsCiAgICBCT09MKiBjb25zdGFudHNfc2V0KSB7CiAgICAKICAgIEdMaGFuZGxlQVJCIHRtcF9sb2M7CiAgICBpbnQgaTsKICAgIGNoYXIgdG1wX25hbWVbOF07CiAgICBjaGFyIGlzX3BzaGFkZXIgPSBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwogICAgY29uc3QgY2hhciogcHJlZml4ID0gaXNfcHNoYWRlcj8gIlBCIjoiVkIiOwogICAgc3RydWN0IGxpc3QqIHB0cjsKCiAgICBmb3IgKGk9MDsgaTxtYXhfY29uc3RhbnRzOyArK2kpIHsKICAgICAgICBpZiAoTlVMTCA9PSBjb25zdGFudHNfc2V0IHx8IGNvbnN0YW50c19zZXRbaV0pIHsKCiAgICAgICAgICAgIFRSQUNFXyhkM2RfY29uc3RhbnRzKSgiTG9hZGluZyBjb25zdGFudHMgJWk6ICVpO1xuIiwgaSwgY29uc3RhbnRzW2ldKTsKCiAgICAgICAgICAgIC8qIFRPRE86IEJlbmNobWFyayBhbmQgc2VlIGlmIGl0IHdvdWxkIGJlIGJlbmVmaWNpYWwgdG8gc3RvcmUgdGhlIAogICAgICAgICAgICAgKiBsb2NhdGlvbnMgb2YgdGhlIGNvbnN0YW50cyB0byBhdm9pZCBsb29raW5nIHVwIGVhY2ggdGltZSAqLwogICAgICAgICAgICBzbnByaW50Zih0bXBfbmFtZSwgc2l6ZW9mKHRtcF9uYW1lKSwgIiVzWyVpXSIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgIHRtcF9sb2MgPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgdG1wX25hbWUpKTsKICAgICAgICAgICAgaWYgKHRtcF9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtMWl2QVJCKHRtcF9sb2MsIDEsICZjb25zdGFudHNbaV0pKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaXZBUkIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIHB0ciA9IGxpc3RfaGVhZCgmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNCKTsKICAgIHdoaWxlIChwdHIpIHsKICAgICAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0ID0gTElTVF9FTlRSWShwdHIsIHN0cnVjdCBsb2NhbF9jb25zdGFudCwgZW50cnkpOwogICAgICAgIHVuc2lnbmVkIGludCBpZHggPSBsY29uc3QtPmlkeDsKICAgICAgICBHTGludCogdmFsdWVzID0gKEdMaW50KikgbGNvbnN0LT52YWx1ZTsKCiAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWlcbiIsIGlkeCwgdmFsdWVzWzBdKTsKCiAgICAgICAgc25wcmludGYodG1wX25hbWUsIHNpemVvZih0bXBfbmFtZSksICIlc1slaV0iLCBwcmVmaXgsIGlkeCk7CiAgICAgICAgdG1wX2xvYyA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCB0bXBfbmFtZSkpOwogICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xaXZBUkIodG1wX2xvYywgMSwgdmFsdWVzKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaXZBUkIiKTsKICAgICAgICB9CiAgICAgICAgcHRyID0gbGlzdF9uZXh0KCZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0IsIHB0cik7CiAgICB9Cn0KCgoKLyoqCiAqIExvYWRzIHRoZSBhcHAtc3VwcGxpZWQgY29uc3RhbnRzIGludG8gdGhlIGN1cnJlbnRseSBzZXQgR0xTTCBwcm9ncmFtLgogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50cygKICAgIElXaW5lRDNERGV2aWNlKiBkZXZpY2UsCiAgICBjaGFyIHVzZVBpeGVsU2hhZGVyLAogICAgY2hhciB1c2VWZXJ0ZXhTaGFkZXIpIHsKICAgCiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgZGV2aWNlOwogICAgc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKilkZXZpY2VJbXBsLT5zaGFkZXJfcHJpdjsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwqIHN0YXRlQmxvY2sgPSBkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJmRldmljZUltcGwtPmFkYXB0ZXItPmdsX2luZm87CgogICAgR0xoYW5kbGVBUkIgKmNvbnN0YW50X2xvY2F0aW9uczsKICAgIHN0cnVjdCBsaXN0ICpjb25zdGFudF9saXN0OwogICAgR0xoYW5kbGVBUkIgcHJvZ3JhbUlkOwogICAgc3RydWN0IGdsc2xfc2hhZGVyX3Byb2dfbGluayAqcHJvZyA9IHByaXYtPmdsc2xfcHJvZ3JhbTsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmICghcHJvZykgewogICAgICAgIC8qIE5vIEdMU0wgcHJvZ3JhbSBzZXQgLSBub3RoaW5nIHRvIGRvLiAqLwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHByb2dyYW1JZCA9IHByb2ctPnByb2dyYW1JZDsKCiAgICBpZiAodXNlVmVydGV4U2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogdnNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgc3RhdGVCbG9jay0+dmVydGV4U2hhZGVyOwoKICAgICAgICBjb25zdGFudF9sb2NhdGlvbnMgPSBwcm9nLT52dW5pZm9ybUZfbG9jYXRpb25zOwogICAgICAgIGNvbnN0YW50X2xpc3QgPSAmc3RhdGVCbG9jay0+c2V0X3Zjb25zdGFudHNGOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBmbG9hdCBjb25zdGFudHMvdW5pZm9ybXMgZm9yIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0YodnNoYWRlciwgZ2xfaW5mbywgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRiksCiAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEYsIGNvbnN0YW50X2xvY2F0aW9ucywgY29uc3RhbnRfbGlzdCk7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGludGVnZXIgY29uc3RhbnRzL3VuaWZvcm1zIGZvciB2ZXJ0ZXggc2hhZGVyICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNJKHZzaGFkZXIsIGdsX2luZm8sIHByb2dyYW1JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZy0+dnVuaWZvcm1JX2xvY2F0aW9ucywgTUFYX0NPTlNUX0ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJKTsKCiAgICAgICAgLyogTG9hZCBEaXJlY3RYIDkgYm9vbGVhbiBjb25zdGFudHMvdW5pZm9ybXMgZm9yIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0IodnNoYWRlciwgZ2xfaW5mbywgcHJvZ3JhbUlkLCBNQVhfQ09OU1RfQiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0IpOwoKICAgICAgICAvKiBVcGxvYWQgdGhlIHBvc2l0aW9uIGZpeHVwIHBhcmFtcyAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtNGZ2QVJCKHByb2ctPnBvc0ZpeHVwX2xvY2F0aW9uLCAxLCAmZGV2aWNlSW1wbC0+cG9zRml4dXBbMF0pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGZ2QVJCIik7CiAgICB9CgogICAgaWYgKHVzZVBpeGVsU2hhZGVyKSB7CgogICAgICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHBzaGFkZXIgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIHN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwoKICAgICAgICBjb25zdGFudF9sb2NhdGlvbnMgPSBwcm9nLT5wdW5pZm9ybUZfbG9jYXRpb25zOwogICAgICAgIGNvbnN0YW50X2xpc3QgPSAmc3RhdGVCbG9jay0+c2V0X3Bjb25zdGFudHNGOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBmbG9hdCBjb25zdGFudHMvdW5pZm9ybXMgZm9yIHBpeGVsIHNoYWRlciAqLwogICAgICAgIHNoYWRlcl9nbHNsX2xvYWRfY29uc3RhbnRzRihwc2hhZGVyLCBnbF9pbmZvLCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSwKICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGLCBjb25zdGFudF9sb2NhdGlvbnMsIGNvbnN0YW50X2xpc3QpOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBpbnRlZ2VyIGNvbnN0YW50cy91bmlmb3JtcyBmb3IgcGl4ZWwgc2hhZGVyICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNJKHBzaGFkZXIsIGdsX2luZm8sIHByb2dyYW1JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZy0+cHVuaWZvcm1JX2xvY2F0aW9ucywgTUFYX0NPTlNUX0ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRJLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0kpOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBib29sZWFuIGNvbnN0YW50cy91bmlmb3JtcyBmb3IgcGl4ZWwgc2hhZGVyICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNCKHBzaGFkZXIsIGdsX2luZm8sIHByb2dyYW1JZCwgTUFYX0NPTlNUX0IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRCLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0IpOwoKICAgICAgICAvKiBVcGxvYWQgdGhlIGVudmlyb25tZW50IGJ1bXAgbWFwIG1hdHJpeCBpZiBuZWVkZWQuIFRoZSBuZWVkc2J1bXBtYXQgbWVtYmVyIHNwZWNpZmllcyB0aGUgdGV4dHVyZSBzdGFnZSB0byBsb2FkIHRoZSBtYXRyaXggZnJvbS4KICAgICAgICAgKiBJdCBjYW4ndCBiZSAwIGZvciBhIHZhbGlkIHRleGJlbSBpbnN0cnVjdGlvbi4KICAgICAgICAgKi8KICAgICAgICBmb3IoaSA9IDA7IGkgPCAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXIpLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXI7CiAgICAgICAgICAgIGludCBzdGFnZSA9IHBzLT5sdW1pbmFuY2Vjb25zdFtpXS50ZXh1bml0OwoKICAgICAgICAgICAgZmxvYXQgKmRhdGEgPSAoZmxvYXQgKikgJnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVsoaW50KSBwcy0+YnVtcGVudm1hdGNvbnN0W2ldLnRleHVuaXRdW1dJTkVEM0RUU1NfQlVNUEVOVk1BVDAwXTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm1NYXRyaXgyZnZBUkIocHJvZy0+YnVtcGVudm1hdF9sb2NhdGlvbltpXSwgMSwgMCwgZGF0YSkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtTWF0cml4MmZ2QVJCIik7CgogICAgICAgICAgICAvKiB0ZXhiZW1sIG5lZWRzIHRoZSBsdW1pbmFuY2Ugc2NhbGUgYW5kIG9mZnNldCB0b28uIElmIHRleGJlbWwgaXMgdXNlZCwgbmVlZHNidW1wbWF0CiAgICAgICAgICAgICAqIGlzIHNldCB0b28sIHNvIHdlIGNhbiBjaGVjayB0aGF0IGluIHRoZSBuZWVkc2J1bXBtYXQgY2hlY2sKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKHBzLT5iYXNlU2hhZGVyLnJlZ19tYXBzLmx1bWluYW5jZXBhcmFtc1tzdGFnZV0pIHsKICAgICAgICAgICAgICAgIEdMZmxvYXQgKnNjYWxlID0gKEdMZmxvYXQgKikgJnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtzdGFnZV1bV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFXTsKICAgICAgICAgICAgICAgIEdMZmxvYXQgKm9mZnNldCA9IChHTGZsb2F0ICopICZzdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbc3RhZ2VdW1dJTkVEM0RUU1NfQlVNUEVOVkxPRkZTRVRdOwoKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtMWZ2QVJCKHByb2ctPmx1bWluYW5jZXNjYWxlX2xvY2F0aW9uW2ldLCAxLCBzY2FsZSkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTFmdkFSQiIpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xZnZBUkIocHJvZy0+bHVtaW5hbmNlb2Zmc2V0X2xvY2F0aW9uW2ldLCAxLCBvZmZzZXQpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xZnZBUkIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBwc2hhZGVyKS0+c3JnYl9lbmFibGVkICYmCiAgICAgICAgICAgICAgICAgICEoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXIpLT5zcmdiX21vZGVfaGFyZGNvZGVkKSB7CiAgICAgICAgICAgIGZsb2F0IGNvbXBhcmlzb25bNF07CiAgICAgICAgICAgIGZsb2F0IG11bF9sb3dbNF07CgogICAgICAgICAgICBpZihzdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1JHQldSSVRFRU5BQkxFXSkgewogICAgICAgICAgICAgICAgY29tcGFyaXNvblswXSA9IHNyZ2JfY21wOyBjb21wYXJpc29uWzFdID0gc3JnYl9jbXA7CiAgICAgICAgICAgICAgICBjb21wYXJpc29uWzJdID0gc3JnYl9jbXA7IGNvbXBhcmlzb25bM10gPSBzcmdiX2NtcDsKCiAgICAgICAgICAgICAgICBtdWxfbG93WzBdID0gc3JnYl9tdWxfbG93OyBtdWxfbG93WzFdID0gc3JnYl9tdWxfbG93OwogICAgICAgICAgICAgICAgbXVsX2xvd1syXSA9IHNyZ2JfbXVsX2xvdzsgbXVsX2xvd1szXSA9IHNyZ2JfbXVsX2xvdzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMF0gPSAxLjAgLyAwLjA7IGNvbXBhcmlzb25bMV0gPSAxLjAgLyAwLjA7CiAgICAgICAgICAgICAgICBjb21wYXJpc29uWzJdID0gMS4wIC8gMC4wOyBjb21wYXJpc29uWzNdID0gMS4wIC8gMC4wOwoKICAgICAgICAgICAgICAgIG11bF9sb3dbMF0gPSAxLjA7IG11bF9sb3dbMV0gPSAxLjA7CiAgICAgICAgICAgICAgICBtdWxfbG93WzJdID0gMS4wOyBtdWxfbG93WzNdID0gMS4wOwogICAgICAgICAgICB9CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTRmdkFSQihwcm9nLT5zcmdiX2NvbXBhcmlzb25fbG9jYXRpb24sIDEsIGNvbXBhcmlzb24pKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIocHJvZy0+c3JnYl9tdWxfbG93X2xvY2F0aW9uLCAxLCBtdWxfbG93KSk7CiAgICAgICAgfQogICAgICAgIGlmKCgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcHNoYWRlciktPnZwb3NfdW5pZm9ybSkgewogICAgICAgICAgICBmbG9hdCBjb3JyZWN0aW9uX3BhcmFtc1s0XTsKICAgICAgICAgICAgaWYoZGV2aWNlSW1wbC0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgICAgICAgICAgY29ycmVjdGlvbl9wYXJhbXNbMF0gPSAwLjA7CiAgICAgICAgICAgICAgICBjb3JyZWN0aW9uX3BhcmFtc1sxXSA9IDEuMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIHBvc2l0aW9uIGlzIHdpbmRvdyByZWxhdGl2ZSwgbm90IHZpZXdwb3J0IHJlbGF0aXZlICovCiAgICAgICAgICAgICAgICBjb3JyZWN0aW9uX3BhcmFtc1swXSA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXZpY2VJbXBsLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIGNvcnJlY3Rpb25fcGFyYW1zWzFdID0gLTEuMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTRmdkFSQihwcm9nLT55Y29ycmVjdGlvbl9sb2NhdGlvbiwgMSwgY29ycmVjdGlvbl9wYXJhbXMpKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKiBHZW5lcmF0ZSB0aGUgdmFyaWFibGUgJiByZWdpc3RlciBkZWNsYXJhdGlvbnMgZm9yIHRoZSBHTFNMIG91dHB1dCB0YXJnZXQgKi8Kdm9pZCBzaGFkZXJfZ2VuZXJhdGVfZ2xzbF9kZWNsYXJhdGlvbnMoCiAgICBJV2luZUQzREJhc2VTaGFkZXIgKmlmYWNlLAogICAgc2hhZGVyX3JlZ19tYXBzKiByZWdfbWFwcywKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciwKICAgIFdpbmVEM0RfR0xfSW5mbyogZ2xfaW5mbykgewoKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgaW50IGk7CiAgICB1bnNpZ25lZCBpbnQgZXh0cmFfY29uc3RhbnRzX25lZWRlZCA9IDA7CiAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0OwoKICAgIC8qIFRoZXJlIGFyZSBzb21lIG1pbm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gcGl4ZWwgYW5kIHZlcnRleCBzaGFkZXJzICovCiAgICBjaGFyIHBzaGFkZXIgPSBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwogICAgY2hhciBwcmVmaXggPSBwc2hhZGVyID8gJ1AnIDogJ1YnOwoKICAgIC8qIFByb3RvdHlwZSB0aGUgc3Vicm91dGluZXMgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5sYWJlbDsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT5sYWJlbHNbaV0pCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZvaWQgc3Vicm91dGluZSV1KCk7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBEZWNsYXJlIHRoZSBjb25zdGFudHMgKGFrYSB1bmlmb3JtcykgKi8KICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCA+IDApIHsKICAgICAgICB1bnNpZ25lZCBtYXhfY29uc3RhbnRzRiA9IG1pbihUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCwgCiAgICAgICAgICAgICAgICAocHNoYWRlciA/IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpIDogR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikpKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHZlYzQgJWNDWyV1XTtcbiIsIHByZWZpeCwgbWF4X2NvbnN0YW50c0YpOwogICAgfQoKICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9pbnQgPiAwKQogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gaXZlYzQgJWNJWyV1XTtcbiIsIHByZWZpeCwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuY29uc3RhbnRfaW50KTsKCiAgICBpZiAoVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuY29uc3RhbnRfYm9vbCA+IDApCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBib29sICVjQlsldV07XG4iLCBwcmVmaXgsIFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Jvb2wpOwoKICAgIGlmKCFwc2hhZGVyKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSB2ZWM0IHBvc0ZpeHVwO1xuIik7CiAgICAgICAgLyogUHJlZGVjbGFyYXRpb247IFRoaXMgZnVuY3Rpb24gaXMgYWRkZWQgYXQgbGluayB0aW1lIGJhc2VkIG9uIHRoZSBwaXhlbCBzaGFkZXIuCiAgICAgICAgICogVlMgMy4wIHNoYWRlcnMgaGF2ZSBhbiBhcnJheSBPVVRbXSB0aGUgc2hhZGVyIHdyaXRlcyB0bywgZWFybGllciB2ZXJzaW9ucyBkb24ndCBoYXZlCiAgICAgICAgICogdGhhdC4gV2Uga25vdyB0aGUgaW5wdXQgdG8gdGhlIHJlb3JkZXIgZnVuY3Rpb24gYXQgdmVydGV4IHNoYWRlciBjb21waWxlIHRpbWUsIHNvCiAgICAgICAgICogd2UgY2FuIGRlYWwgd2l0aCB0aGF0LiBUaGUgcmVvcmRlciBmdW5jdGlvbiBmb3IgYSAxLnggYW5kIDIueCB2ZXJ0ZXggc2hhZGVyIGNhbiBqdXN0CiAgICAgICAgICogcmVhZCBnbF9Gcm9udENvbG9yLiBUaGUgb3V0cHV0IGRlcGVuZHMgb24gdGhlIHBpeGVsIHNoYWRlci4gVGhlIHJlb3JkZXIgZnVuY3Rpb24gZm9yIGEKICAgICAgICAgKiAxLnggYW5kIDIueCBwc2hhZGVyIG9yIGZvciBmaXhlZCBmdW5jdGlvbiB3aWxsIHdyaXRlIGdsX0Zyb250Q29sb3IsIGFuZCBmb3IgYSAzLjAgc2hhZGVyCiAgICAgICAgICogaXQgd2lsbCB3cml0ZSB0byB0aGUgdmFyeWluZyBhcnJheS4gSGVyZSB3ZSBkZXBlbmQgb24gdGhlIHNoYWRlciBvcHRpbWl6ZXIgb24gc29ydGluZyB0aGF0CiAgICAgICAgICogb3V0LiBUaGUgbnZpZGlhIGRyaXZlciBvbmx5IGRvZXMgdGhhdCBpZiB0aGUgcGFyYW1ldGVyIGlzIGlub3V0IGluc3RlYWQgb2Ygb3V0LCBoZW5jZSB0aGUKICAgICAgICAgKiBpbm91dC4KICAgICAgICAgKi8KICAgICAgICBpZihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uID49IFdJTkVEM0RWU19WRVJTSU9OKDMsIDApKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZvaWQgb3JkZXJfcHNfaW5wdXQoaW4gdmVjNFsldV0pO1xuIiwgTUFYX1JFR19PVVRQVVQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZvaWQgb3JkZXJfcHNfaW5wdXQoKTtcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzX2ltcGwgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgVGhpczsKCiAgICAgICAgcHNfaW1wbC0+bnVtYnVtcGVudm1hdGNvbnN0cyA9IDA7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgKHNpemVvZihyZWdfbWFwcy0+YnVtcG1hdCkgLyBzaXplb2YocmVnX21hcHMtPmJ1bXBtYXRbMF0pKTsgaSsrKSB7CiAgICAgICAgICAgIGlmKCFyZWdfbWFwcy0+YnVtcG1hdFtpXSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBzX2ltcGwtPmJ1bXBlbnZtYXRjb25zdFsoaW50KSBwc19pbXBsLT5udW1idW1wZW52bWF0Y29uc3RzXS50ZXh1bml0ID0gaTsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBtYXQyIGJ1bXBlbnZtYXQlZDtcbiIsIGkpOwoKICAgICAgICAgICAgaWYocmVnX21hcHMtPmx1bWluYW5jZXBhcmFtcykgewogICAgICAgICAgICAgICAgcHNfaW1wbC0+bHVtaW5hbmNlY29uc3RbKGludCkgcHNfaW1wbC0+bnVtYnVtcGVudm1hdGNvbnN0c10udGV4dW5pdCA9IGk7CiAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIGZsb2F0IGx1bWluYW5jZXNjYWxlJWQ7XG4iLCBpKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gZmxvYXQgbHVtaW5hbmNlb2Zmc2V0JWQ7XG4iLCBpKTsKICAgICAgICAgICAgICAgIGV4dHJhX2NvbnN0YW50c19uZWVkZWQrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBzX2ltcGwtPmx1bWluYW5jZWNvbnN0WyhpbnQpIHBzX2ltcGwtPm51bWJ1bXBlbnZtYXRjb25zdHNdLnRleHVuaXQgPSAtMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZXh0cmFfY29uc3RhbnRzX25lZWRlZCsrOwogICAgICAgICAgICBwc19pbXBsLT5udW1idW1wZW52bWF0Y29uc3RzKys7CiAgICAgICAgfQoKICAgICAgICBpZihkZXZpY2UtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TUkdCV1JJVEVFTkFCTEVdKSB7CiAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfZW5hYmxlZCA9IDE7CiAgICAgICAgICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0ICsgZXh0cmFfY29uc3RhbnRzX25lZWRlZCArIDEgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSB2ZWM0IHNyZ2JfbXVsX2xvdztcbiIpOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSB2ZWM0IHNyZ2JfY29tcGFyaXNvbjtcbiIpOwogICAgICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9tb2RlX2hhcmRjb2RlZCA9IDA7CiAgICAgICAgICAgICAgICBleHRyYV9jb25zdGFudHNfbmVlZGVkKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwc19pbXBsLT5zcmdiX21vZGVfaGFyZGNvZGVkID0gMTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImNvbnN0IHZlYzQgc3JnYl9tdWxfbG93ID0gdmVjNCglZiwgJWYsICVmLCAlZik7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9tdWxfbG93LCBzcmdiX211bF9sb3csIHNyZ2JfbXVsX2xvdywgc3JnYl9tdWxfbG93KTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImNvbnN0IHZlYzQgc3JnYl9jb21wYXJpc29uID0gdmVjNCglZiwgJWYsICVmLCAlZik7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9jbXAsIHNyZ2JfY21wLCBzcmdiX2NtcCwgc3JnYl9jbXApOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzX2ltcGwgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgVGhpczsKCiAgICAgICAgICAgIC8qIERvIG5vdCB3cml0ZSBhbnkgc3JnYiBmaXh1cCBpbnRvIHRoZSBzaGFkZXIgdG8gc2F2ZSBzaGFkZXIgc2l6ZSBhbmQgcHJvY2Vzc2luZyB0aW1lLgogICAgICAgICAgICAgKiBBcyBhIGNvbnNlcXVlbmNlLCB3ZSBjYW4ndCB0b2dnbGUgc3JnYiB3cml0ZSBvbiB3aXRob3V0IHJlY29tcGlsYXRpb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfZW5hYmxlZCA9IDA7CiAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfbW9kZV9oYXJkY29kZWQgPSAxOwogICAgICAgIH0KICAgICAgICBpZihyZWdfbWFwcy0+dnBvcyB8fCByZWdfbWFwcy0+dXNlc2RzeSkgewogICAgICAgICAgICBpZihUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCArIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgKyAxIDwgR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikpIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gdmVjNCB5Y29ycmVjdGlvbjtcbiIpOwogICAgICAgICAgICAgICAgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzKS0+dnBvc191bmlmb3JtID0gMTsKICAgICAgICAgICAgICAgIGV4dHJhX2NvbnN0YW50c19uZWVkZWQrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFRoaXMgaGFwcGVucyBiZWNhdXNlIHdlIGRvIG5vdCBoYXZlIHByb3BlciB0cmFja2luZyBvZiB0aGUgY29uc3RhbnQgcmVnaXN0ZXJzIHRoYXQgYXJlCiAgICAgICAgICAgICAgICAgKiBhY3R1YWxseSB1c2VkLCBvbmx5IHRoZSBtYXggbGltaXQgb2YgdGhlIHNoYWRlciB2ZXJzaW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCJDYW5ub3QgZmluZCBhIGZyZWUgdW5pZm9ybSBmb3IgdnBvcyBjb3JyZWN0aW9uIHBhcmFtc1xuIik7CiAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJjb25zdCB2ZWM0IHljb3JyZWN0aW9uID0gdmVjNCglZiwgJWYsIDAuMCwgMC4wKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnJlbmRlcl9vZmZzY3JlZW4gPyAwLjAgOiAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZS0+cmVuZGVyX29mZnNjcmVlbiA/IDEuMCA6IC0xLjApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYzQgdnBvcztcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBEZWNsYXJlIHRleHR1cmUgc2FtcGxlcnMgKi8gCiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuc2FtcGxlcjsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT5zYW1wbGVyc1tpXSkgewoKICAgICAgICAgICAgRFdPUkQgc3R5cGUgPSByZWdfbWFwcy0+c2FtcGxlcnNbaV0gJiBXSU5FRDNEU1BfVEVYVFVSRVRZUEVfTUFTSzsKICAgICAgICAgICAgc3dpdGNoIChzdHlwZSkgewoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFNUVF8xRDoKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHNhbXBsZXIxRCAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RTVFRfMkQ6CiAgICAgICAgICAgICAgICAgICAgaWYoZGV2aWNlLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tpXSAmJgogICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfR2V0VGV4dHVyZURpbWVuc2lvbnMoZGV2aWNlLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tpXSkgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gc2FtcGxlcjJEUmVjdCAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBzYW1wbGVyMkQgJWNzYW1wbGVyJXU7XG4iLCBwcmVmaXgsIGkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFNUVF9DVUJFOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gc2FtcGxlckN1YmUgJWNzYW1wbGVyJXU7XG4iLCBwcmVmaXgsIGkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEU1RUX1ZPTFVNRToKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHNhbXBsZXIzRCAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gdW5zdXBwb3J0ZWRfc2FtcGxlciAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBzYW1wbGVyIHR5cGU6ICUjeFxuIiwgc3R5cGUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKiBEZWNsYXJlIGFkZHJlc3MgdmFyaWFibGVzICovCiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuYWRkcmVzczsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT5hZGRyZXNzW2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpdmVjNCBBJWQ7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBEZWNsYXJlIHRleHR1cmUgY29vcmRpbmF0ZSB0ZW1wb3JhcmllcyBhbmQgaW5pdGlhbGl6ZSB0aGVtICovCiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMudGV4Y29vcmQ7IGkrKykgewogICAgICAgIGlmIChyZWdfbWFwcy0+dGV4Y29vcmRbaV0pIAogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IFQldSA9IGdsX1RleENvb3JkWyV1XTtcbiIsIGksIGkpOwogICAgfQoKICAgIC8qIERlY2xhcmUgaW5wdXQgcmVnaXN0ZXIgdmFyeWluZ3MuIE9ubHkgcGl4ZWwgc2hhZGVyLCB2ZXJ0ZXggc2hhZGVycyBoYXZlIHRoYXQgZGVjbGFyZWQgaW4gdGhlCiAgICAgKiBoZWxwZXIgZnVuY3Rpb24gc2hhZGVyIHRoYXQgaXMgbGlua2VkIGluIGF0IGxpbmsgdGltZQogICAgICovCiAgICBpZihwc2hhZGVyICYmIFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPj0gV0lORUQzRFBTX1ZFUlNJT04oMywgMCkpIHsKICAgICAgICBpZih1c2VfdnMoZGV2aWNlKSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2YXJ5aW5nIHZlYzQgSU5bJXVdO1xuIiwgR0xfTElNSVRTKGdsc2xfdmFyeWluZ3MpIC8gNCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogVE9ETzogV3JpdGUgYSByZXBsYWNlbWVudCBzaGFkZXIgZm9yIHRoZSBmaXhlZCBmdW5jdGlvbiB2ZXJ0ZXggcGlwZWxpbmUsIHNvIHRoaXMgaXNuJ3QgbmVlZGVkLgogICAgICAgICAgICAgKiBGb3IgZml4ZWQgZnVuY3Rpb24gdmVydGV4IHByb2Nlc3NpbmcgKyAzLjAgcGl4ZWwgc2hhZGVyIHdlIG5lZWQgYSBzZXBhcmF0ZSBmdW5jdGlvbiBpbiB0aGUKICAgICAgICAgICAgICogcGl4ZWwgc2hhZGVyIHRoYXQgcmVhZHMgdGhlIGZpeGVkIGZ1bmN0aW9uIGNvbG9yIGludG8gdGhlIHBhY2tlZCBpbnB1dCByZWdpc3RlcnMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IElOWyV1XTtcbiIsIEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBEZWNsYXJlIG91dHB1dCByZWdpc3RlciB0ZW1wb3JhcmllcyAqLwogICAgaWYoVGhpcy0+YmFzZVNoYWRlci5saW1pdHMucGFja2VkX291dHB1dCkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYzQgT1VUWyV1XTtcbiIsIFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLnBhY2tlZF9vdXRwdXQpOwogICAgfQoKICAgIC8qIERlY2xhcmUgdGVtcG9yYXJ5IHZhcmlhYmxlcyAqLwogICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMudGVtcG9yYXJ5OyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPnRlbXBvcmFyeVtpXSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjNCBSJXU7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBEZWNsYXJlIGF0dHJpYnV0ZXMgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5hdHRyaWJ1dGVzOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPmF0dHJpYnV0ZXNbaV0pCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImF0dHJpYnV0ZSB2ZWM0IGF0dHJpYiVpO1xuIiwgaSk7CiAgICB9CgogICAgLyogRGVjbGFyZSBsb29wIHJlZ2lzdGVycyBhTHggKi8KICAgIGZvciAoaSA9IDA7IGkgPCByZWdfbWFwcy0+bG9vcF9kZXB0aDsgaSsrKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiaW50IGFMJXU7XG4iLCBpKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpbnQgdG1wSW50JXU7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBUZW1wb3JhcnkgdmFyaWFibGVzIGZvciBtYXRyaXggb3BlcmF0aW9ucyAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjNCB0bXAwO1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IHRtcDE7XG4iKTsKCiAgICAvKiBMb2NhbCBjb25zdGFudHMgdXNlIGEgZGlmZmVyZW50IG5hbWUgc28gdGhleSBjYW4gYmUgbG9hZGVkIG9uY2UgYXQgc2hhZGVyIGxpbmsgdGltZQogICAgICogVGhleSBjYW4ndCBiZSBoYXJkY29kZWQgaW50byB0aGUgc2hhZGVyIHRleHQgdmlhIExDID0ge3gsIHksIHosIHd9OyBiZWNhdXNlIHRoZQogICAgICogZmxvYXQgLT4gc3RyaW5nIGNvbnZlcnNpb24gY2FuIGNhdXNlIHByZWNpc2lvbiBsb3NzLgogICAgICovCiAgICBpZighVGhpcy0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YpIHsKICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGxjb25zdCwgJlRoaXMtPmJhc2VTaGFkZXIuY29uc3RhbnRzRiwgbG9jYWxfY29uc3RhbnQsIGVudHJ5KSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gdmVjNCAlY0xDJXU7XG4iLCBwcmVmaXgsIGxjb25zdC0+aWR4KTsKICAgICAgICB9CiAgICB9CgogICAgLyogU3RhcnQgdGhlIG1haW4gcHJvZ3JhbSAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidm9pZCBtYWluKCkge1xuIik7CiAgICBpZihwc2hhZGVyICYmIHJlZ19tYXBzLT52cG9zKSB7CiAgICAgICAgLyogRGlyZWN0WCBhcHBzIGV4cGVjdCBpbnRlZ2VyIHZhbHVlcywgd2hpbGUgT3BlbkdMIGRyaXZlcnMgYWRkIGFwcHJveGltYXRlbHkgMC41LiBUaGlzIGNhdXNlcwogICAgICAgICAqIG9mZi1ieS1vbmUgcHJvYmxlbXMgYXMgc3BvdHRlZCBieSB0aGUgdlBvcyBkM2Q5IHZpc3VhbCB0ZXN0LiBVbmZvcnR1bmF0ZWx5IHRoZSBBVEkgY2FyZHMgZG8KICAgICAgICAgKiBub3QgYWRkIGV4YWN0bHkgMC41LCBidXQgcmF0aGVyIHNvbWV0aGluZyBsaWtlIDAuNDk5OTk5OTkgb3IgMC41MDAwMDAwMSwgd2hpY2ggc3RpbGwgY2F1c2VzCiAgICAgICAgICogcHJlY2lzaW9uIHRyb3VibGVzIHdoZW4gd2UganVzdCBzdWJzdHJhY3QgMC41LgogICAgICAgICAqCiAgICAgICAgICogVG8gZGVhbCB3aXRoIHRoYXQganVzdCBmbG9vcigpIHRoZSBwb3NpdGlvbi4gVGhpcyB3aWxsIGVsaW1pbmF0ZSB0aGUgZnJhY3Rpb24gb24gYWxsIGNhcmRzLgogICAgICAgICAqCiAgICAgICAgICogVE9ETzogVGVzdCBob3cgdGhhdCBiZWhhdmVzIHdpdGggbXVsdGlzYW1wbGluZyBvbmNlIHdlIGNhbiBlbmFibGUgbXVsdGlzYW1wbGluZyBpbiB3aW5leDExLgogICAgICAgICAqCiAgICAgICAgICogQW4gYWR2YW50YWdlIG9mIGZsb29yIGlzIHRoYXQgaXQgd29ya3MgZXZlbiBpZiB0aGUgZHJpdmVyIGRvZXNuJ3QgYWRkIDEvMi4gSXQgaXMgc29tZXdoYXQKICAgICAgICAgKiBxdWVzdGlvbmFibGUgaWYgMS41LCAyLjUsIC4uLiBhcmUgdGhlIHByb3BlciB2YWx1ZXMgdG8gcmV0dXJuIGluIGdsX0ZyYWdDb29yZCwgZXZlbiB0aG91Z2gKICAgICAgICAgKiBjb29yZGluYXRlcyBzcGVjaWZ5IHRoZSBwaXhlbCBjZW50ZXJzIGluc3RlYWQgb2YgdGhlIHBpeGVsIGNvcm5lcnMuIFRoaXMgY29kZSB3aWxsIGJlaGF2ZQogICAgICAgICAqIGNvcnJlY3RseSBvbiBkcml2ZXJzIHRoYXQgcmV0dXJucyBpbnRlZ2VyIHZhbHVlcy4KICAgICAgICAgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2cG9zID0gZmxvb3IodmVjNCgwLCB5Y29ycmVjdGlvblswXSwgMCwgMCkgKyBnbF9GcmFnQ29vcmQgKiB2ZWM0KDEsIHljb3JyZWN0aW9uWzFdLCAxLCAxKSk7XG4iKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZ1bmN0aW9ucyB0byBnZW5lcmF0ZSBHTFNMIHN0cmluZ3MgZnJvbSBEaXJlY3RYIFNoYWRlciBieXRlY29kZSBiZWdpbiBoZXJlLgogKgogKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIGh0dHA6Ly93aWtpLndpbmVocS5vcmcvRGlyZWN0WC1TaGFkZXJzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogUHJvdG90eXBlcyAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKFNIQURFUl9PUENPREVfQVJHKiBhcmcsIGNvbnN0IERXT1JEIHBhcmFtLAogICAgICAgIGNvbnN0IERXT1JEIGFkZHJfdG9rZW4sIERXT1JEIG1hc2ssIGdsc2xfc3JjX3BhcmFtX3QgKnNyY19wYXJhbSk7CgovKiogVXNlZCBmb3Igb3Bjb2RlIG1vZGlmaWVycyAtIFRoZXkgbXVsdGlwbHkgdGhlIHJlc3VsdCBieSB0aGUgc3BlY2lmaWVkIGFtb3VudCAqLwpzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IHNoaWZ0X2dsc2xfdGFiW10gPSB7CiAgICAiIiwgICAgICAgICAgIC8qICAwIChub25lKSAqLyAKICAgICIyLjAgKiAiLCAgICAgLyogIDEgKHgyKSAgICovIAogICAgIjQuMCAqICIsICAgICAvKiAgMiAoeDQpICAgKi8gCiAgICAiOC4wICogIiwgICAgIC8qICAzICh4OCkgICAqLyAKICAgICIxNi4wICogIiwgICAgLyogIDQgKHgxNikgICovIAogICAgIjMyLjAgKiAiLCAgICAvKiAgNSAoeDMyKSAgKi8gCiAgICAiIiwgICAgICAgICAgIC8qICA2ICh4NjQpICAqLyAKICAgICIiLCAgICAgICAgICAgLyogIDcgKHgxMjgpICovIAogICAgIiIsICAgICAgICAgICAvKiAgOCAoZDI1NikgKi8gCiAgICAiIiwgICAgICAgICAgIC8qICA5IChkMTI4KSAqLyAKICAgICIiLCAgICAgICAgICAgLyogMTAgKGQ2NCkgICovIAogICAgIiIsICAgICAgICAgICAvKiAxMSAoZDMyKSAgKi8gCiAgICAiMC4wNjI1ICogIiwgIC8qIDEyIChkMTYpICAqLyAKICAgICIwLjEyNSAqICIsICAgLyogMTMgKGQ4KSAgICovIAogICAgIjAuMjUgKiAiLCAgICAvKiAxNCAoZDQpICAgKi8gCiAgICAiMC41ICogIiAgICAgIC8qIDE1IChkMikgICAqLyAKfTsKCi8qIEdlbmVyYXRlIGEgR0xTTCBwYXJhbWV0ZXIgdGhhdCBkb2VzIHRoZSBpbnB1dCBtb2RpZmllciBjb21wdXRhdGlvbiBhbmQgcmV0dXJuIHRoZSBpbnB1dCByZWdpc3Rlci9tYXNrIHRvIHVzZSAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9nZW5fbW9kaWZpZXIgKAogICAgY29uc3QgRFdPUkQgaW5zdHIsCiAgICBjb25zdCBjaGFyICppbl9yZWcsCiAgICBjb25zdCBjaGFyICppbl9yZWdzd2l6emxlLAogICAgY2hhciAqb3V0X3N0cikgewoKICAgIG91dF9zdHJbMF0gPSAwOwogICAgCiAgICBpZiAoaW5zdHIgPT0gV0lORUQzRFNJT19URVhLSUxMKQogICAgICAgIHJldHVybjsKCiAgICBzd2l0Y2ggKGluc3RyICYgV0lORUQzRFNQX1NSQ01PRF9NQVNLKSB7CiAgICBjYXNlIFdJTkVEM0RTUFNNX0RaOiAvKiBOZWVkIHRvIGhhbmRsZSB0aGlzIGluIHRoZSBpbnN0cnVjdGlvbnMgaXRzZWxmICh0ZXhsZCAmIHRleGNyZCkuICovCiAgICBjYXNlIFdJTkVEM0RTUFNNX0RXOgogICAgY2FzZSBXSU5FRDNEU1BTTV9OT05FOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIiVzJXMiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9ORUc6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiLSVzJXMiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9OT1Q6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiISVzJXMiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9CSUFTOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIiglcyVzIC0gdmVjNCgwLjUpJXMpIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlLCBpbl9yZWdzd2l6emxlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fQklBU05FRzoKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICItKCVzJXMgLSB2ZWM0KDAuNSklcykiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9TSUdOOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIigyLjAgKiAoJXMlcyAtIDAuNSkpIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fU0lHTk5FRzoKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICItKDIuMCAqICglcyVzIC0gMC41KSkiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9DT01QOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIigxLjAgLSAlcyVzKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX1gyOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIigyLjAgKiAlcyVzKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX1gyTkVHOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIi0oMi4wICogJXMlcykiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9BQlM6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiYWJzKCVzJXMpIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fQUJTTkVHOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIi1hYnMoJXMlcykiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIG1vZGlmaWVyICV1XG4iLCAoaW5zdHIgJiBXSU5FRDNEU1BfU1JDTU9EX01BU0spKTsKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICIlcyVzIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlKTsKICAgIH0KfQoKLyoqIFdyaXRlcyB0aGUgR0xTTCB2YXJpYWJsZSBuYW1lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHJlZ2lzdGVyIHRoYXQgdGhlCiAqIERYIG9wY29kZSBwYXJhbWV0ZXIgaXMgdHJ5aW5nIHRvIGFjY2VzcyAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9nZXRfcmVnaXN0ZXJfbmFtZSgKICAgIGNvbnN0IERXT1JEIHBhcmFtLAogICAgY29uc3QgRFdPUkQgYWRkcl90b2tlbiwKICAgIGNoYXIqIHJlZ3N0ciwKICAgIEJPT0wqIGlzX2NvbG9yLAogICAgU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIC8qIG9Qb3MsIG9Gb2cgYW5kIG9QdHMgaW4gRDNEICovCiAgICBzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0IGh3cmFzdG91dF9yZWdfbmFtZXNbXSA9IHsgImdsX1Bvc2l0aW9uIiwgImdsX0ZvZ0ZyYWdDb29yZCIsICJnbF9Qb2ludFNpemUiIH07CgogICAgRFdPUkQgcmVnID0gcGFyYW0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBEV09SRCByZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKHBhcmFtKTsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgV2luZUQzRF9HTF9JbmZvKiBnbF9pbmZvID0gJmRldmljZUltcGwtPmFkYXB0ZXItPmdsX2luZm87CgogICAgY2hhciBwc2hhZGVyID0gc2hhZGVyX2lzX3BzaGFkZXJfdmVyc2lvbihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKTsKICAgIGNoYXIgdG1wU3RyWzE1MF07CgogICAgKmlzX2NvbG9yID0gRkFMU0U7ICAgCiAKICAgIHN3aXRjaCAocmVndHlwZSkgewogICAgY2FzZSBXSU5FRDNEU1BSX1RFTVA6CiAgICAgICAgc3ByaW50Zih0bXBTdHIsICJSJXUiLCByZWcpOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfSU5QVVQ6CiAgICAgICAgaWYgKHBzaGFkZXIpIHsKICAgICAgICAgICAgLyogUGl4ZWwgc2hhZGVycyA+PSAzLjAgKi8KICAgICAgICAgICAgaWYgKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA+PSAzKSB7CiAgICAgICAgICAgICAgICBEV09SRCBpbl9jb3VudCA9IEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQ7CgogICAgICAgICAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNIQURFUl9BRERSTU9ERV9SRUxBVElWRSkgewogICAgICAgICAgICAgICAgICAgIGdsc2xfc3JjX3BhcmFtX3QgcmVsX3BhcmFtOwogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhZGRyX3Rva2VuLCAwLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZyZWxfcGFyYW0pOwoKICAgICAgICAgICAgICAgICAgICAvKiBSZW1vdmluZyBhICsgMCB3b3VsZCBiZSBhbiBvYnZpb3VzIG9wdGltaXphdGlvbiwgYnV0IG1hY29zIGRvZXNuJ3Qgc2VlIHRoZSBOT1AKICAgICAgICAgICAgICAgICAgICAgKiBvcGVyYXRpb24gdGhlcmUKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZigoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXMpLT5pbnB1dF9yZWdfbWFwW3JlZ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKilUaGlzKS0+ZGVjbGFyZWRfaW5fY291bnQgPiBpbl9jb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIoKCVzICsgJXUpID4gJWQgPyAoJXMgKyAldSkgPiAlZCA/IGdsX1NlY29uZGFyeUNvbG9yIDogZ2xfQ29sb3IgOiBJTlslcyArICV1XSkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxfcGFyYW0ucGFyYW1fc3RyLCAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcyktPmlucHV0X3JlZ19tYXBbcmVnXSwgaW5fY291bnQgLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxfcGFyYW0ucGFyYW1fc3RyLCAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcyktPmlucHV0X3JlZ19tYXBbcmVnXSwgaW5fY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9wYXJhbS5wYXJhbV9zdHIsICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKilUaGlzKS0+aW5wdXRfcmVnX21hcFtyZWddKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiSU5bJXMgKyAldV0iLCByZWxfcGFyYW0ucGFyYW1fc3RyLCAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcyktPmlucHV0X3JlZ19tYXBbcmVnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKVRoaXMpLT5kZWNsYXJlZF9pbl9jb3VudCA+IGluX2NvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIigoJXMpID4gJWQgPyAoJXMpID4gJWQgPyBnbF9TZWNvbmRhcnlDb2xvciA6IGdsX0NvbG9yIDogSU5bJXNdKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9wYXJhbS5wYXJhbV9zdHIsIGluX2NvdW50IC0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsX3BhcmFtLnBhcmFtX3N0ciwgaW5fY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJJTlslc10iLCByZWxfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgRFdPUkQgaWR4ID0gKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzKS0+aW5wdXRfcmVnX21hcFtyZWddOwogICAgICAgICAgICAgICAgICAgIGlmIChpZHggPT0gaW5fY291bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJnbF9Db2xvciIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWR4ID09IGluX2NvdW50ICsgMSkgewogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImdsX1NlY29uZGFyeUNvbG9yIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJJTlsldV0iLCBpZHgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChyZWc9PTApCiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHRtcFN0ciwgImdsX0NvbG9yIik7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHRtcFN0ciwgImdsX1NlY29uZGFyeUNvbG9yIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAodnNoYWRlcl9pbnB1dF9pc19jb2xvcigoSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqKSBUaGlzLCByZWcpKQogICAgICAgICAgICAgICAqaXNfY29sb3IgPSBUUlVFOwogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImF0dHJpYiV1IiwgcmVnKTsKICAgICAgICB9IAogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0NPTlNUOgogICAgewogICAgICAgIGNvbnN0IGNoYXIgcHJlZml4ID0gcHNoYWRlcj8gJ1AnOidWJzsKCiAgICAgICAgLyogUmVsYXRpdmUgYWRkcmVzc2luZyAqLwogICAgICAgIGlmIChwYXJhbSAmIFdJTkVEM0RTSEFERVJfQUREUk1PREVfUkVMQVRJVkUpIHsKCiAgICAgICAgICAgLyogUmVsYXRpdmUgYWRkcmVzc2luZyBvbiBzaGFkZXJzIDIuMCsgaGF2ZSBhIHJlbGF0aXZlIGFkZHJlc3MgdG9rZW4sIAogICAgICAgICAgICAqIHByaW9yIHRvIHRoYXQsIGl0IHdhcyBoYXJkLWNvZGVkIGFzICJBMC54IiBiZWNhdXNlIHRoZXJlJ3Mgb25seSAxIHJlZ2lzdGVyICovCiAgICAgICAgICAgaWYgKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA+PSAyKSAgewogICAgICAgICAgICAgICBnbHNsX3NyY19wYXJhbV90IHJlbF9wYXJhbTsKICAgICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFkZHJfdG9rZW4sIDAsIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnJlbF9wYXJhbSk7CiAgICAgICAgICAgICAgIGlmKHJlZykgewogICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlY0NbJXMgKyAldV0iLCBwcmVmaXgsIHJlbF9wYXJhbS5wYXJhbV9zdHIsIHJlZyk7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIiVjQ1slc10iLCBwcmVmaXgsIHJlbF9wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgaWYocmVnKSB7CiAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIiVjQ1tBMC54ICsgJXVdIiwgcHJlZml4LCByZWcpOwogICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlY0NbQTAueF0iLCBwcmVmaXgpOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgfQoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZihzaGFkZXJfY29uc3RhbnRfaXNfbG9jYWwoVGhpcywgcmVnKSkgewogICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlY0xDJXUiLCBwcmVmaXgsIHJlZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIiVjQ1sldV0iLCBwcmVmaXgsIHJlZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEU1BSX0NPTlNUSU5UOgogICAgICAgIGlmIChwc2hhZGVyKQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlBJWyV1XSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZJWyV1XSIsIHJlZyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfQ09OU1RCT09MOgogICAgICAgIGlmIChwc2hhZGVyKQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlBCWyV1XSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZCWyV1XSIsIHJlZyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfVEVYVFVSRTogLyogY2FzZSBXSU5FRDNEU1BSX0FERFI6ICovCiAgICAgICAgaWYgKHBzaGFkZXIpIHsKICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJUJXUiLCByZWcpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiQSV1IiwgcmVnKTsKICAgICAgICB9CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9MT09QOgogICAgICAgIHNwcmludGYodG1wU3RyLCAiYUwldSIsIFRoaXMtPmJhc2VTaGFkZXIuY3VyX2xvb3BfcmVnbm8gLSAxKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX1NBTVBMRVI6CiAgICAgICAgaWYgKHBzaGFkZXIpCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiUHNhbXBsZXIldSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZzYW1wbGVyJXUiLCByZWcpOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfQ09MT1JPVVQ6CiAgICAgICAgaWYgKHJlZyA+PSBHTF9MSU1JVFMoYnVmZmVycykpIHsKICAgICAgICAgICAgV0FSTigiV3JpdGUgdG8gcmVuZGVyIHRhcmdldCAldSwgb25seSAlZCBzdXBwb3J0ZWRcbiIsIHJlZywgNCk7CiAgICAgICAgfQogICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0RhdGFbJXVdIiwgcmVnKTsKICAgICAgICB9IGVsc2UgeyAvKiBPbiBvbGRlciBjYXJkcyB3aXRoIEdMU0wgc3VwcG9ydCBsaWtlIHRoZSBHZWZvcmNlRlggdGhlcmUncyBvbmx5IG9uZSBidWZmZXIuICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0NvbG9yIik7CiAgICAgICAgfQogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfUkFTVE9VVDoKICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIiVzIiwgaHdyYXN0b3V0X3JlZ19uYW1lc1tyZWddKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0RFUFRIT1VUOgogICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0RlcHRoIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9BVFRST1VUOgogICAgICAgIGlmIChyZWcgPT0gMCkgewogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImdsX0Zyb250Q29sb3IiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImdsX0Zyb250U2Vjb25kYXJ5Q29sb3IiKTsKICAgICAgICB9CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9URVhDUkRPVVQ6CiAgICAgICAgLyogVmVydGV4IHNoYWRlcnMgPj0gMy4wOiBXSU5FRDNEU1BSX09VVFBVVCAqLwogICAgICAgIGlmIChXSU5FRDNEU0hBREVSX1ZFUlNJT05fTUFKT1IoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbikgPj0gMykKICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJPVVRbJXVdIiwgcmVnKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfVGV4Q29vcmRbJXVdIiwgcmVnKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX01JU0NUWVBFOgogICAgICAgIGlmIChyZWcgPT0gMCkgewogICAgICAgICAgICAvKiB2UG9zICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAidnBvcyIpOwogICAgICAgIH0gZWxzZSBpZiAocmVnID09IDEpewogICAgICAgICAgICAvKiBOb3RlIHRoYXQgZ2xfRnJvbnRGYWNpbmcgaXMgYSBib29sLCB3aGlsZSB2RmFjZSBpcwogICAgICAgICAgICAgKiBhIGZsb2F0IGZvciB3aGljaCB0aGUgc2lnbiBkZXRlcm1pbmVzIGZyb250L2JhY2sKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiKGdsX0Zyb250RmFjaW5nID8gMS4wIDogLTEuMCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIG1pc2N0eXBlIHJlZ2lzdGVyICVkXG4iLCByZWcpOwogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgInVucmVjb2duaXplZF9yZWdpc3RlciIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCByZWdpc3RlciBuYW1lIFR5cGUoJWQpXG4iLCByZWd0eXBlKTsKICAgICAgICBzcHJpbnRmKHRtcFN0ciwgInVucmVjb2duaXplZF9yZWdpc3RlciIpOwogICAgYnJlYWs7CiAgICB9CgogICAgc3RyY2F0KHJlZ3N0ciwgdG1wU3RyKTsKfQoKLyogR2V0IHRoZSBHTFNMIHdyaXRlIG1hc2sgZm9yIHRoZSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwpzdGF0aWMgRFdPUkQgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soY29uc3QgRFdPUkQgcGFyYW0sIGNoYXIgKndyaXRlX21hc2spIHsKICAgIGNoYXIgKnB0ciA9IHdyaXRlX21hc2s7CiAgICBEV09SRCBtYXNrID0gcGFyYW0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTDsKCiAgICBpZiAoc2hhZGVyX2lzX3NjYWxhcihwYXJhbSkpIHsKICAgICAgICBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wOwogICAgfSBlbHNlIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18wKSAqcHRyKysgPSAneCc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSAneSc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18yKSAqcHRyKysgPSAneic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSAqcHRyKysgPSAndyc7CiAgICB9CgogICAgKnB0ciA9ICdcMCc7CgogICAgcmV0dXJuIG1hc2s7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShEV09SRCB3cml0ZV9tYXNrKSB7CiAgICB1bnNpZ25lZCBpbnQgc2l6ZSA9IDA7CgogICAgaWYgKHdyaXRlX21hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzApICsrc2l6ZTsKICAgIGlmICh3cml0ZV9tYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSArK3NpemU7CiAgICBpZiAod3JpdGVfbWFzayAmIFdJTkVEM0RTUF9XUklURU1BU0tfMikgKytzaXplOwogICAgaWYgKHdyaXRlX21hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzMpICsrc2l6ZTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfZ2V0X3N3aXp6bGUoY29uc3QgRFdPUkQgcGFyYW0sIEJPT0wgZml4dXAsIERXT1JEIG1hc2ssIGNoYXIgKnN3aXp6bGVfc3RyKSB7CiAgICAvKiBGb3IgcmVnaXN0ZXJzIG9mIHR5cGUgV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SLCBkYXRhIGlzIHN0b3JlZCBhcyAiYmdyYSIsCiAgICAgKiBidXQgYWRkcmVzc2VkIGFzICJyZ2JhIi4gVG8gZml4IHRoaXMgd2UgbmVlZCB0byBzd2FwIHRoZSByZWdpc3RlcidzIHgKICAgICAqIGFuZCB6IGNvbXBvbmVudHMuICovCiAgICBEV09SRCBzd2l6emxlID0gKHBhcmFtICYgV0lORUQzRFNQX1NXSVpaTEVfTUFTSykgPj4gV0lORUQzRFNQX1NXSVpaTEVfU0hJRlQ7CiAgICBjb25zdCBjaGFyICpzd2l6emxlX2NoYXJzID0gZml4dXAgPyAienl4dyIgOiAieHl6dyI7CiAgICBjaGFyICpwdHIgPSBzd2l6emxlX3N0cjsKCiAgICBpZiAoIXNoYWRlcl9pc19zY2FsYXIocGFyYW0pKSB7CiAgICAgICAgKnB0cisrID0gJy4nOwogICAgICAgIC8qIHN3aXp6bGUgYml0cyBmaWVsZHM6IHd3enp5eXh4ICovCiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzApICpwdHIrKyA9IHN3aXp6bGVfY2hhcnNbc3dpenpsZSAmIDB4MDNdOwogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSBzd2l6emxlX2NoYXJzWyhzd2l6emxlID4+IDIpICYgMHgwM107CiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzIpICpwdHIrKyA9IHN3aXp6bGVfY2hhcnNbKHN3aXp6bGUgPj4gNCkgJiAweDAzXTsKICAgICAgICBpZiAobWFzayAmIFdJTkVEM0RTUF9XUklURU1BU0tfMykgKnB0cisrID0gc3dpenpsZV9jaGFyc1soc3dpenpsZSA+PiA2KSAmIDB4MDNdOwogICAgfQoKICAgICpwdHIgPSAnXDAnOwp9CgovKiBGcm9tIGEgZ2l2ZW4gcGFyYW1ldGVyIHRva2VuLCBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBHTFNMIHN0cmluZy4KICogQWxzbywgcmV0dXJuIHRoZSBhY3R1YWwgcmVnaXN0ZXIgbmFtZSBhbmQgc3dpenpsZSBpbiBjYXNlIHRoZQogKiBjYWxsZXIgbmVlZHMgdGhpcyBpbmZvcm1hdGlvbiBhcyB3ZWxsLiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKFNIQURFUl9PUENPREVfQVJHKiBhcmcsIGNvbnN0IERXT1JEIHBhcmFtLAogICAgICAgIGNvbnN0IERXT1JEIGFkZHJfdG9rZW4sIERXT1JEIG1hc2ssIGdsc2xfc3JjX3BhcmFtX3QgKnNyY19wYXJhbSkgewogICAgQk9PTCBpc19jb2xvciA9IEZBTFNFOwogICAgY2hhciBzd2l6emxlX3N0cls2XTsKCiAgICBzcmNfcGFyYW0tPnJlZ19uYW1lWzBdID0gJ1wwJzsKICAgIHNyY19wYXJhbS0+cGFyYW1fc3RyWzBdID0gJ1wwJzsKICAgIHN3aXp6bGVfc3RyWzBdID0gJ1wwJzsKCiAgICBzaGFkZXJfZ2xzbF9nZXRfcmVnaXN0ZXJfbmFtZShwYXJhbSwgYWRkcl90b2tlbiwgc3JjX3BhcmFtLT5yZWdfbmFtZSwgJmlzX2NvbG9yLCBhcmcpOwoKICAgIHNoYWRlcl9nbHNsX2dldF9zd2l6emxlKHBhcmFtLCBpc19jb2xvciwgbWFzaywgc3dpenpsZV9zdHIpOwogICAgc2hhZGVyX2dsc2xfZ2VuX21vZGlmaWVyKHBhcmFtLCBzcmNfcGFyYW0tPnJlZ19uYW1lLCBzd2l6emxlX3N0ciwgc3JjX3BhcmFtLT5wYXJhbV9zdHIpOwp9CgovKiBGcm9tIGEgZ2l2ZW4gcGFyYW1ldGVyIHRva2VuLCBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBHTFNMIHN0cmluZy4KICogQWxzbywgcmV0dXJuIHRoZSBhY3R1YWwgcmVnaXN0ZXIgbmFtZSBhbmQgc3dpenpsZSBpbiBjYXNlIHRoZQogKiBjYWxsZXIgbmVlZHMgdGhpcyBpbmZvcm1hdGlvbiBhcyB3ZWxsLiAqLwpzdGF0aWMgRFdPUkQgc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShTSEFERVJfT1BDT0RFX0FSRyogYXJnLCBjb25zdCBEV09SRCBwYXJhbSwKICAgICAgICBjb25zdCBEV09SRCBhZGRyX3Rva2VuLCBnbHNsX2RzdF9wYXJhbV90ICpkc3RfcGFyYW0pIHsKICAgIEJPT0wgaXNfY29sb3IgPSBGQUxTRTsKCiAgICBkc3RfcGFyYW0tPm1hc2tfc3RyWzBdID0gJ1wwJzsKICAgIGRzdF9wYXJhbS0+cmVnX25hbWVbMF0gPSAnXDAnOwoKICAgIHNoYWRlcl9nbHNsX2dldF9yZWdpc3Rlcl9uYW1lKHBhcmFtLCBhZGRyX3Rva2VuLCBkc3RfcGFyYW0tPnJlZ19uYW1lLCAmaXNfY29sb3IsIGFyZyk7CiAgICByZXR1cm4gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2socGFyYW0sIGRzdF9wYXJhbS0+bWFza19zdHIpOwp9CgovKiBBcHBlbmQgdGhlIGRlc3RpbmF0aW9uIHBhcnQgb2YgdGhlIGluc3RydWN0aW9uIHRvIHRoZSBidWZmZXIsIHJldHVybiB0aGUgZWZmZWN0aXZlIHdyaXRlIG1hc2sgKi8Kc3RhdGljIERXT1JEIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KFNIQURFUl9CVUZGRVIgKmJ1ZmZlciwgU0hBREVSX09QQ09ERV9BUkcgKmFyZywgY29uc3QgRFdPUkQgcGFyYW0pIHsKICAgIGdsc2xfZHN0X3BhcmFtX3QgZHN0X3BhcmFtOwogICAgRFdPUkQgbWFzazsKICAgIGludCBzaGlmdDsKCiAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIHBhcmFtLCBhcmctPmRzdF9hZGRyLCAmZHN0X3BhcmFtKTsKCiAgICBpZihtYXNrKSB7CiAgICAgICAgc2hpZnQgPSAocGFyYW0gJiBXSU5FRDNEU1BfRFNUU0hJRlRfTUFTSykgPj4gV0lORUQzRFNQX0RTVFNISUZUX1NISUZUOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSAlcygiLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0ciwgc2hpZnRfZ2xzbF90YWJbc2hpZnRdKTsKICAgIH0KCiAgICByZXR1cm4gbWFzazsKfQoKLyogQXBwZW5kIHRoZSBkZXN0aW5hdGlvbiBwYXJ0IG9mIHRoZSBpbnN0cnVjdGlvbiB0byB0aGUgYnVmZmVyLCByZXR1cm4gdGhlIGVmZmVjdGl2ZSB3cml0ZSBtYXNrICovCnN0YXRpYyBEV09SRCBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KFNIQURFUl9CVUZGRVIgKmJ1ZmZlciwgU0hBREVSX09QQ09ERV9BUkcgKmFyZykgewogICAgcmV0dXJuIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KGJ1ZmZlciwgYXJnLCBhcmctPmRzdCk7Cn0KCi8qKiBQcm9jZXNzIEdMU0wgaW5zdHJ1Y3Rpb24gbW9kaWZpZXJzICovCnZvaWQgc2hhZGVyX2dsc2xfYWRkX2luc3RydWN0aW9uX21vZGlmaWVycyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICAKICAgIERXT1JEIG1hc2sgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9EU1RNT0RfTUFTSzsKIAogICAgaWYgKGFyZy0+b3Bjb2RlLT5kc3RfdG9rZW4gJiYgbWFzayAhPSAwKSB7CiAgICAgICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CgogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgMCwgJmRzdF9wYXJhbSk7CgogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQRE1fU0FUVVJBVEUpIHsKICAgICAgICAgICAgLyogX1NBVCBtZWFucyB0byBjbGFtcCB0aGUgdmFsdWUgb2YgdGhlIHJlZ2lzdGVyIHRvIGJldHdlZW4gMCBhbmQgMSAqLwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzJXMgPSBjbGFtcCglcyVzLCAwLjAsIDEuMCk7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLm1hc2tfc3RyLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0cik7CiAgICAgICAgfQogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQRE1fTVNBTVBDRU5UUk9JRCkgewogICAgICAgICAgICBGSVhNRSgiX2NlbnRyb2lkIG1vZGlmaWVyIG5vdCBoYW5kbGVkXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BETV9QQVJUSUFMUFJFQ0lTSU9OKSB7CiAgICAgICAgICAgIC8qIE1TRE4gc2F5cyB0aGlzIG1vZGlmaWVyIGNhbiBiZSBzYWZlbHkgaWdub3JlZCwgc28gdGhhdCdzIHdoYXQgd2UnbGwgZG8uICovCiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgaW5saW5lIGNvbnN0IGNoYXIqIHNoYWRlcl9nZXRfY29tcF9vcCgKICAgIGNvbnN0IERXT1JEIG9wY29kZSkgewoKICAgIERXT1JEIG9wID0gKG9wY29kZSAmIElOU1RfQ09OVFJPTFNfTUFTSykgPj4gSU5TVF9DT05UUk9MU19TSElGVDsKICAgIHN3aXRjaCAob3ApIHsKICAgICAgICBjYXNlIENPTVBBUklTT05fR1Q6IHJldHVybiAiPiI7CiAgICAgICAgY2FzZSBDT01QQVJJU09OX0VROiByZXR1cm4gIj09IjsKICAgICAgICBjYXNlIENPTVBBUklTT05fR0U6IHJldHVybiAiPj0iOwogICAgICAgIGNhc2UgQ09NUEFSSVNPTl9MVDogcmV0dXJuICI8IjsKICAgICAgICBjYXNlIENPTVBBUklTT05fTkU6IHJldHVybiAiIT0iOwogICAgICAgIGNhc2UgQ09NUEFSSVNPTl9MRTogcmV0dXJuICI8PSI7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBjb21wYXJpc29uIHZhbHVlOiAldVxuIiwgb3ApOwogICAgICAgICAgICByZXR1cm4gIihcP1w/KSI7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oRFdPUkQgc2FtcGxlcl90eXBlLCBCT09MIHByb2plY3RlZCwgQk9PTCB0ZXhyZWN0LCBnbHNsX3NhbXBsZV9mdW5jdGlvbl90ICpzYW1wbGVfZnVuY3Rpb24pIHsKICAgIC8qIE5vdGUgdGhhdCB0aGVyZSdzIG5vIHN1Y2ggdGhpbmcgYXMgYSBwcm9qZWN0ZWQgY3ViZSB0ZXh0dXJlLiAqLwogICAgc3dpdGNoKHNhbXBsZXJfdHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFNUVF8xRDoKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gcHJvamVjdGVkID8gInRleHR1cmUxRFByb2oiIDogInRleHR1cmUxRCI7CiAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi0+Y29vcmRfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU1RUXzJEOgogICAgICAgICAgICBpZih0ZXhyZWN0KSB7CiAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSBwcm9qZWN0ZWQgPyAidGV4dHVyZTJEUmVjdFByb2oiIDogInRleHR1cmUyRFJlY3QiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gcHJvamVjdGVkID8gInRleHR1cmUyRFByb2oiIDogInRleHR1cmUyRCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTVFRfQ1VCRToKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gInRleHR1cmVDdWJlIjsKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTVFRfVk9MVU1FOgogICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSBwcm9qZWN0ZWQgPyAidGV4dHVyZTNEUHJvaiIgOiAidGV4dHVyZTNEIjsKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSAiIjsKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBzYW1wbGVyIHR5cGU6ICUjeDtcbiIsIHNhbXBsZXJfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9jb2xvcl9jb3JyZWN0aW9uKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgc2hhZGVyLT5iYXNlU2hhZGVyLmRldmljZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZkZXZpY2VJbXBsLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CiAgICBnbHNsX2RzdF9wYXJhbV90IGRzdF9wYXJhbTI7CiAgICBXSU5FRDNERk9STUFUIGZtdDsKICAgIFdJTkVEM0RGT1JNQVQgY29udmVyc2lvbl9ncm91cDsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlOwogICAgRFdPUkQgbWFzaywgbWFza19zaXplOwogICAgVUlOVCBpOwogICAgQk9PTCByZWNvcmRlZCA9IEZBTFNFOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IHNoYWRlci0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbjsKCiAgICBzd2l0Y2goYXJnLT5vcGNvZGUtPm9wY29kZSkgewogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVg6CiAgICAgICAgICAgIGlmIChoZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICAgICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzYW1wbGVyX2lkeCA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTERMOgogICAgICAgICAgICBGSVhNRSgiQWRkIGNvbG9yIGZpeHVwIGZvciB2ZXJ0ZXggdGV4dHVyZSBXSU5FRDNEU0lPX1RFWExETFxuIik7CiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWERQM1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1NQRUM6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWE0zeDNWU1BFQzoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYQkVNOgogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVhSRUcyQVI6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWFJFRzJHQjoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYUkVHMlJHQjoKICAgICAgICAgICAgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIE5vdCBhIHRleHR1cmUgc2FtcGxpbmcgaW5zdHJ1Y3Rpb24sIG5vdGhpbmcgdG8gZG8gKi8KICAgICAgICAgICAgcmV0dXJuOwogICAgfTsKCiAgICB0ZXh0dXJlID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XTsKICAgIGlmKHRleHR1cmUpIHsKICAgICAgICBmbXQgPSB0ZXh0dXJlLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IHRleHR1cmUtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwOwogICAgfSBlbHNlIHsKICAgICAgICBmbXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIH0KCiAgICAvKiBiZWZvcmUgZG9pbmcgYW55dGhpbmcsIHJlY29yZCB0aGUgc2FtcGxlciB3aXRoIHRoZSBmb3JtYXQgaW4gdGhlIGZvcm1hdCBjb252ZXJzaW9uIGxpc3QsCiAgICAgKiBidXQgY2hlY2sgaWYgaXQncyBub3QgdGhlcmUgYWxyZWFkeQogICAgICovCiAgICBmb3IoaSA9IDA7IGkgPCBzaGFkZXItPmJhc2VTaGFkZXIubnVtX3NhbXBsZWRfc2FtcGxlcnM7IGkrKykgewogICAgICAgIGlmKHNoYWRlci0+YmFzZVNoYWRlci5zYW1wbGVkX3NhbXBsZXJzW2ldID09IHNhbXBsZXJfaWR4KSB7CiAgICAgICAgICAgIHJlY29yZGVkID0gVFJVRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgaWYoIXJlY29yZGVkKSB7CiAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLnNhbXBsZWRfc2FtcGxlcnNbc2hhZGVyLT5iYXNlU2hhZGVyLm51bV9zYW1wbGVkX3NhbXBsZXJzXSA9IHNhbXBsZXJfaWR4OwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5udW1fc2FtcGxlZF9zYW1wbGVycysrOwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5zYW1wbGVkX2Zvcm1hdFtzYW1wbGVyX2lkeF0gPSBjb252ZXJzaW9uX2dyb3VwOwogICAgfQoKICAgIHN3aXRjaChmbXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjhVODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjE2VTE2OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSB8fAogICAgICAgICAgICAgIChHTF9TVVBQT1JUKEFUSV9FTlZNQVBfQlVNUE1BUCkgJiYgZm10ID09IFdJTkVEM0RGTVRfVjhVOCkpIHsKICAgICAgICAgICAgICAgIC8qIFRoZSAzcmQgY2hhbm5lbCByZXR1cm5zIDEuMCBpbiBkM2QsIGJ1dCAwLjAgaW4gZ2wuIEZpeCB0aGlzIHdoaWxlIHdlJ3JlIGF0IGl0IDotKSAqLwogICAgICAgICAgICAgICAgbWFzayA9IHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUobWFzayk7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMykgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMgPSAxLjA7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clszXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBDb3JyZWN0IHRoZSBzaWduLCBidXQgbGVhdmUgdGhlIGJsdWUgYXMgaXQgaXMgLSBpdCB3YXMgbG9hZGVkIGNvcnJlY3RseSBhbHJlYWR5ICovCiAgICAgICAgICAgICAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkc3RfcGFyYW0pOwogICAgICAgICAgICAgICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShtYXNrKTsKICAgICAgICAgICAgICAgIGlmKG1hc2tfc2l6ZSA+PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyVjID0gJXMuJWMlYyAqIDIuMCAtIDEuMDtcbiIsCiAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clsyXSwKICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsxXSwgZHN0X3BhcmFtLm1hc2tfc3RyWzJdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZihtYXNrX3NpemUgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMgPSAlcy4lYyAqIDIuMCAtIDEuMDtcbiIsIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4TDhWOFU4OgogICAgICAgICAgICBpZighR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikpIHsKICAgICAgICAgICAgICAgIC8qIFJlZCBhbmQgYmx1ZSBhcmUgdGhlIHNpZ25lZCBjaGFubmVscywgZml4IHRoZW0gdXA7IEJsdWUoPUwpIGlzIGNvcnJlY3QgYWxyZWFkeSwKICAgICAgICAgICAgICAgICAqIGFuZCBhKFgpIGlzIGFsd2F5cyAxLjAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbWFzayA9IHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xLCAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUobWFzayk7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMikgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMlYyA9ICVzLiVjJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLCBkc3RfcGFyYW0ubWFza19zdHJbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clsyXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYobWFza19zaXplID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzLiVjID0gJXMuJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0w2VjVVNToKICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZkc3RfcGFyYW0pOwogICAgICAgICAgICAgICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShtYXNrKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmZHN0X3BhcmFtMik7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMykgewogICAgICAgICAgICAgICAgICAgIC8qIFN3YXAgeSBhbmQgeiAoVSBhbmQgTCksIGFuZCBkbyBhIHNpZ24gY29udmVyc2lvbiBvbiB4IGFuZCB0aGUgbmV3IHkoViBhbmQgVSkgKi8KICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAuZyA9ICVzLiVjO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsyXSk7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyVjID0gJXMuJWMlYyAqIDIuMCAtIDEuMDtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMl0sIGRzdF9wYXJhbS5tYXNrX3N0clsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0yLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clszXSk7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyA9IHRtcDAuZztcbiIsIGRzdF9wYXJhbS5yZWdfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ubWFza19zdHJbM10pOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmKG1hc2tfc2l6ZSA9PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBpcyBiYWQ6IFdlIGhhdmUgVkwsIGJ1dCB3ZSBuZWVkIFZVICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIjIgY29tcG9uZW50cyBzYW1wbGVkIGZyb20gYSBjb252ZXJ0ZWQgTDZWNVU1IHRleHR1cmVcbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzLiVjID0gJXMuJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbTIucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsxXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9ROFc4VjhVODoKICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICAvKiBDb3JyZWN0IHRoZSBzaWduIGluIGFsbCBjaGFubmVscy4gVGhlIHdyaXRlbWFzayBqdXN0IGFwcGxpZXMgYXMtaXMsIG5vCiAgICAgICAgICAgICAgICAgKiBuZWVkIGZvciBjaGVja2luZyB0aGUgbWFzayBzaXplCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNQX1dSSVRFTUFTS18yIHwgV0lORUQzRFNQX1dSSVRFTUFTS18zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMlcyA9ICVzJXMgKiAyLjAgLSAxLjA7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0FUSTJOOgogICAgICAgICAgICAvKiBHTF9BVElfdGV4dHVyZV9jb21wcmVzc2lvbl8zZGMgcmV0dXJucyB0aGUgdHdvIGNoYW5uZWxzIGFzIGx1bWluYW5jZS1hbHBoYSwKICAgICAgICAgICAgICogd2hpY2ggbWVhbnMgdGhlIGZpcnN0IG9uZSBpcyByZXBsaWNhdGVkIGFjcm9zcyAucmdiLCBhbmQgdGhlIDJuZCBvbmUgaXMgaW4KICAgICAgICAgICAgICogLmEuIFdlIG5lZWQgdGhlIDJuZCBpbiAuZwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBHTF9FWFRfdGV4dHVyZV9jb21wcmVzc2lvbl9yZ3RjIHJldHVybnMgdGhlIHZhbHVlcyBpbiAucmcsIGhvd2V2ZXIsIHRoZXkKICAgICAgICAgICAgICogYXJlIHN3YXBwZWQgY29tcGFyZWQgdG8gZDNkLiBTbyBzd2FwIHJlZCBhbmQgZ3JlZW4uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZkc3RfcGFyYW0pOwogICAgICAgICAgICBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKG1hc2spOwogICAgICAgICAgICBpZihHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0NPTVBSRVNTSU9OX1JHVEMpKSB7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMikgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMlYyA9ICVzLiVjJWM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLm1hc2tfc3RyWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLm1hc2tfc3RyWzFdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiV1IGNvbXBvbmVudHMgc2FtcGxlZCBmcm9tIGEgY29udmVydGVkIEFUSTJOIHRleHR1cmVcbiIsIG1hc2tfc2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPT0gNCkgewogICAgICAgICAgICAgICAgICAgIC8qIFN3YXAgeSBhbmQgeiAoVSBhbmQgTCksIGFuZCBkbyBhIHNpZ24gY29udmVyc2lvbiBvbiB4IGFuZCB0aGUgbmV3IHkoViBhbmQgVSkgKi8KICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzLiVjID0gJXMuJWM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzRdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZihtYXNrX3NpemUgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIC8qIE5vdGhpbmcgdG8gZG8gKi8KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiV1IGNvbXBvbmVudHMgc2FtcGxlZCBmcm9tIGEgY29udmVydGVkIEFUSTJOIHRleHR1cmVcbiIsIG1hc2tfc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBpcyBiYWQ6IFdlIGhhdmUgLnJbZ2JdLCBidXQgd2UgbmVlZCAucmEgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIC8qIHN0dXBpZCBjb21waWxlciAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCiAqIEJlZ2luIHByb2Nlc3NpbmcgaW5kaXZpZHVhbCBpbnN0cnVjdGlvbiBvcGNvZGVzCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIEdlbmVyYXRlIEdMU0wgYXJpdGhtZXRpYyBmdW5jdGlvbnMgKGRzdCA9IHNyYzEgKyBzcmMyKSAqLwp2b2lkIHNoYWRlcl9nbHNsX2FyaXRoKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgY2hhciBvcDsKCiAgICAvKiBEZXRlcm1pbmUgdGhlIEdMU0wgb3BlcmF0b3IgdG8gdXNlIGJhc2VkIG9uIHRoZSBvcGNvZGUgKi8KICAgIHN3aXRjaCAoY3VyT3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTVVMOiBvcCA9ICcqJzsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0FERDogb3AgPSAnKyc7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19TVUI6IG9wID0gJy0nOyBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBvcCA9ICcgJzsKICAgICAgICAgICAgRklYTUUoIk9wY29kZSAlcyBub3QgeWV0IGhhbmRsZWQgaW4gR0xTTFxuIiwgY3VyT3Bjb2RlLT5uYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCB3cml0ZV9tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHdyaXRlX21hc2ssICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzICVjICVzKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBvcCwgc3JjMV9wYXJhbS5wYXJhbV9zdHIpOwp9CgovKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX01PViBvcGNvZGUgdXNpbmcgR0xTTCAoZHN0ID0gc3JjKSAqLwp2b2lkIHNoYWRlcl9nbHNsX21vdihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgd3JpdGVfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIC8qIEluIHZzXzFfMSBXSU5FRDNEU0lPX01PViBjYW4gd3JpdGUgdG8gdGhlIGFkZHJlc3MgcmVnaXN0ZXIuIEluIGxhdGVyCiAgICAgKiBzaGFkZXIgdmVyc2lvbnMgV0lORUQzRFNJT19NT1ZBIGlzIHVzZWQgZm9yIHRoaXMuICovCiAgICBpZiAoKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihzaGFkZXItPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pID09IDEgJiYKICAgICAgICAgICAgIXNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oc2hhZGVyLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSAmJgogICAgICAgICAgICBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5kc3QpID09IFdJTkVEM0RTUFJfQUREUikpIHsKICAgICAgICAvKiBUaGlzIGlzIGEgc2ltcGxlIGZsb29yKCkgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpdmVjJWQoZmxvb3IoJXMpKSk7XG4iLCBtYXNrX3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpbnQoZmxvb3IoJXMpKSk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfSBlbHNlIGlmKGFyZy0+b3Bjb2RlLT5vcGNvZGUgPT0gV0lORUQzRFNJT19NT1ZBKSB7CiAgICAgICAgLyogV2UgbmVlZCB0byAqcm91bmQqIHRvIHRoZSBuZWFyZXN0IGludCBoZXJlLiAqLwogICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgIGlmIChtYXNrX3NpemUgPiAxKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIml2ZWMlZChmbG9vcihhYnMoJXMpICsgdmVjJWQoMC41KSkgKiBzaWduKCVzKSkpO1xuIiwgbWFza19zaXplLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgbWFza19zaXplLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiaW50KGZsb29yKGFicyglcykgKyAwLjUpICogc2lnbiglcykpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIFByb2Nlc3MgdGhlIGRvdCBwcm9kdWN0IG9wZXJhdG9ycyBEUDMgYW5kIERQNCBpbiBHTFNMIChkc3QgPSBkb3Qoc3JjMCwgc3JjMSkpICovCnZvaWQgc2hhZGVyX2dsc2xfZG90KFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCBkc3Rfd3JpdGVfbWFzaywgc3JjX3dyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgZHN0X3NpemUgPSAwOwoKICAgIGRzdF93cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBkc3Rfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUoZHN0X3dyaXRlX21hc2spOwoKICAgIC8qIGRwMyB3b3JrcyBvbiB2ZWMzLCBkcDQgb24gdmVjNCAqLwogICAgaWYgKGN1ck9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fRFA0KSB7CiAgICAgICAgc3JjX3dyaXRlX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3JjX3dyaXRlX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICB9CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfd3JpdGVfbWFzaywgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBzcmNfd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwoKICAgIGlmIChkc3Rfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWMlZChkb3QoJXMsICVzKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImRvdCglcywgJXMpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIE5vdGUgdGhhdCB0aGlzIGluc3RydWN0aW9uIGhhcyBzb21lIHJlc3RyaWN0aW9ucy4gVGhlIGRlc3RpbmF0aW9uIHdyaXRlIG1hc2sKICogY2FuJ3QgY29udGFpbiB0aGUgdyBjb21wb25lbnQsIGFuZCB0aGUgc291cmNlIHN3aXp6bGVzIGhhdmUgdG8gYmUgLnh5encgKi8Kdm9pZCBzaGFkZXJfZ2xzbF9jcm9zcyhTSEFERVJfT1BDT0RFX0FSRyAqYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGNoYXIgZHN0X21hc2tbNl07CgogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHNyY19tYXNrLCAmc3JjMV9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImNyb3NzKCVzLCAlcyklcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKfQoKLyogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19QT1cgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gfHNyYzB8XnNyYzEpCiAqIFNyYzAgYW5kIHNyYzEgYXJlIHNjYWxhcnMuIE5vdGUgdGhhdCBEM0QgdXNlcyB0aGUgYWJzb2x1dGUgb2Ygc3JjMCwgd2hpbGUKICogR0xTTCB1c2VzIHRoZSB2YWx1ZSBhcy1pcy4gKi8Kdm9pZCBzaGFkZXJfZ2xzbF9wb3coU0hBREVSX09QQ09ERV9BUkcgKmFyZykgewogICAgU0hBREVSX0JVRkZFUiAqYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCBkc3Rfd3JpdGVfbWFzazsKICAgIHVuc2lnbmVkIGludCBkc3Rfc2l6ZTsKCiAgICBkc3Rfd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYnVmZmVyLCBhcmcpOwogICAgZHN0X3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKGRzdF93cml0ZV9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMxX3BhcmFtKTsKCiAgICBpZiAoZHN0X3NpemUgPiAxKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjJWQocG93KGFicyglcyksICVzKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInBvdyhhYnMoJXMpLCAlcykpO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKLyogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19MT0cgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gbG9nMih8c3JjMHwpKQogKiBTcmMwIGlzIGEgc2NhbGFyLiBOb3RlIHRoYXQgRDNEIHVzZXMgdGhlIGFic29sdXRlIG9mIHNyYzAsIHdoaWxlCiAqIEdMU0wgdXNlcyB0aGUgdmFsdWUgYXMtaXMuICovCnZvaWQgc2hhZGVyX2dsc2xfbG9nKFNIQURFUl9PUENPREVfQVJHICphcmcpIHsKICAgIFNIQURFUl9CVUZGRVIgKmJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgRFdPUkQgZHN0X3dyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgZHN0X3NpemU7CgogICAgZHN0X3dyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIGRzdF9zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShkc3Rfd3JpdGVfbWFzayk7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKCiAgICBpZiAoZHN0X3NpemUgPiAxKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjJWQobG9nMihhYnMoJXMpKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAibG9nMihhYnMoJXMpKSk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIE1hcCB0aGUgb3Bjb2RlIDEtdG8tMSB0byB0aGUgR0wgY29kZSAoYXJnLT5kc3QgPSBpbnN0cnVjdGlvbihzcmMwLCBzcmMxLCAuLi4pICovCnZvaWQgc2hhZGVyX2dsc2xfbWFwMmdsKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKICAgIGNvbnN0IGNoYXIgKmluc3RydWN0aW9uOwogICAgY2hhciBhcmd1bWVudHNbMjU2XTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpOwoKICAgIC8qIERldGVybWluZSB0aGUgR0xTTCBmdW5jdGlvbiB0byB1c2UgYmFzZWQgb24gdGhlIG9wY29kZSAqLwogICAgLyogVE9ETzogUG9zc2libHkgbWFrZSB0aGlzIGEgdGFibGUgZm9yIGZhc3RlciBsb29rdXBzICovCiAgICBzd2l0Y2ggKGN1ck9wY29kZS0+b3Bjb2RlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX01JTjogaW5zdHJ1Y3Rpb24gPSAibWluIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX01BWDogaW5zdHJ1Y3Rpb24gPSAibWF4IjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0FCUzogaW5zdHJ1Y3Rpb24gPSAiYWJzIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0ZSQzogaW5zdHJ1Y3Rpb24gPSAiZnJhY3QiOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTlJNOiBpbnN0cnVjdGlvbiA9ICJub3JtYWxpemUiOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTE9HUDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTE9HOiBpbnN0cnVjdGlvbiA9ICJsb2cyIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0VYUDogaW5zdHJ1Y3Rpb24gPSAiZXhwMiI7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19TR046IGluc3RydWN0aW9uID0gInNpZ24iOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fRFNYOiBpbnN0cnVjdGlvbiA9ICJkRmR4IjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0RTWTogaW5zdHJ1Y3Rpb24gPSAieWNvcnJlY3Rpb24ueSAqIGRGZHkiOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBpbnN0cnVjdGlvbiA9ICIiOwogICAgICAgICAgICBGSVhNRSgiT3Bjb2RlICVzIG5vdCB5ZXQgaGFuZGxlZCBpbiBHTFNMXG4iLCBjdXJPcGNvZGUtPm5hbWUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CgogICAgYXJndW1lbnRzWzBdID0gJ1wwJzsKICAgIGlmIChjdXJPcGNvZGUtPm51bV9wYXJhbXMgPiAwKSB7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCB3cml0ZV9tYXNrLCAmc3JjX3BhcmFtKTsKICAgICAgICBzdHJjYXQoYXJndW1lbnRzLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICBmb3IgKGkgPSAyOyBpIDwgY3VyT3Bjb2RlLT5udW1fcGFyYW1zOyArK2kpIHsKICAgICAgICAgICAgc3RyY2F0KGFyZ3VtZW50cywgIiwgIik7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1tpLTFdLCBhcmctPnNyY19hZGRyW2ktMV0sIHdyaXRlX21hc2ssICZzcmNfcGFyYW0pOwogICAgICAgICAgICBzdHJjYXQoYXJndW1lbnRzLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9CiAgICB9CgogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMoJXMpKTtcbiIsIGluc3RydWN0aW9uLCBhcmd1bWVudHMpOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19FWFBQIGluc3RydWN0aW9uIGluIEdMU0w6CiAqIEZvciBzaGFkZXIgbW9kZWwgMS54LCBkbyB0aGUgZm9sbG93aW5nIChhbmQgaG9ub3IgdGhlIHdyaXRlbWFzaywgc28gdXNlIGEgdGVtcG9yYXJ5IHZhcmlhYmxlKToKICogICBkc3QueCA9IDJeKGZsb29yKHNyYykpCiAqICAgZHN0LnkgPSBzcmMgLSBmbG9vcihzcmMpCiAqICAgZHN0LnogPSAyXnNyYyAgIChwYXJ0aWFsIHByZWNpc2lvbiBpcyBhbGxvd2VkLCBidXQgb3B0aW9uYWwpCiAqICAgZHN0LncgPSAxLjA7CiAqIEZvciAyLjAgc2hhZGVycywganVzdCBkbyB0aGlzIChob25vcmluZyB3cml0ZW1hc2sgYW5kIHN3aXp6bGUpOgogKiAgIGRzdCA9IDJec3JjOyAgICAocGFydGlhbCBwcmVjaXNpb24gaXMgYWxsb3dlZCwgYnV0IG9wdGlvbmFsKQogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9leHBwKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKnNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsICopYXJnLT5zaGFkZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyY19wYXJhbSk7CgogICAgaWYgKHNoYWRlci0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICBjaGFyIGRzdF9tYXNrWzZdOwoKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueCA9IGV4cDIoZmxvb3IoJXMpKTtcbiIsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMC55ID0gJXMgLSBmbG9vciglcyk7XG4iLCBzcmNfcGFyYW0ucGFyYW1fc3RyLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueiA9IGV4cDIoJXMpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwLncgPSAxLjA7XG4iKTsKCiAgICAgICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMCVzKTtcbiIsIGRzdF9tYXNrKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRFdPUkQgd3JpdGVfbWFzazsKICAgICAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwoKICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGV4cDIoJXMpKSk7XG4iLCBtYXNrX3NpemUsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZXhwMiglcykpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfQp9CgovKiogUHJvY2VzcyB0aGUgUkNQIChyZWNpcHJvY2FsIG9yIGludmVyc2UpIG9wY29kZSBpbiBHTFNMIChkc3QgPSAxIC8gc3JjKSAqLwp2b2lkIHNoYWRlcl9nbHNsX3JjcChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjX3BhcmFtKTsKCiAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjJWQoMS4wIC8gJXMpKTtcbiIsIG1hc2tfc2l6ZSwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiMS4wIC8gJXMpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCnZvaWQgc2hhZGVyX2dsc2xfcnNxKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmNfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgdW5zaWduZWQgaW50IG1hc2tfc2l6ZTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjX3BhcmFtKTsKCiAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYyVkKGludmVyc2VzcXJ0KCVzKSkpO1xuIiwgbWFza19zaXplLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiaW52ZXJzZXNxcnQoJXMpKTtcbiIsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgfQp9CgovKiogUHJvY2VzcyBzaWduZWQgY29tcGFyaXNvbiBvcGNvZGVzIGluIEdMU0wuICovCnZvaWQgc2hhZGVyX2dsc2xfY29tcGFyZShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgdW5zaWduZWQgaW50IG1hc2tfc2l6ZTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUod3JpdGVfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwoKICAgIGlmIChtYXNrX3NpemUgPiAxKSB7CiAgICAgICAgY29uc3QgY2hhciAqY29tcGFyZTsKCiAgICAgICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1NMVDogY29tcGFyZSA9ICJsZXNzVGhhbiI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RTSU9fU0dFOiBjb21wYXJlID0gImdyZWF0ZXJUaGFuRXF1YWwiOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogY29tcGFyZSA9ICIiOwogICAgICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBvcGNvZGUgJXNcbiIsIGFyZy0+b3Bjb2RlLT5uYW1lKTsKICAgICAgICB9CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjJWQoJXMoJXMsICVzKSkpO1xuIiwgbWFza19zaXplLCBjb21wYXJlLAogICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1NMVDoKICAgICAgICAgICAgICAgIC8qIFN0ZXAoc3JjMCwgc3JjMSkgaXMgbm90IHN1aXRhYmxlIGhlcmUgYmVjYXVzZSBpZiBzcmMwID09IHNyYzEgU0xUIGlzIHN1cHBvc2VkLAogICAgICAgICAgICAgICAgICogdG8gcmV0dXJuIDAuMCBidXQgc3RlcCByZXR1cm5zIDEuMCBiZWNhdXNlIHN0ZXAgaXMgbm90IDwgeAogICAgICAgICAgICAgICAgICogQW4gYWx0ZXJuYXRpdmUgaXMgYSBidmVjIGNvbXBhcmUgcGFkZGVkIHdpdGggYW4gdW51c2VkIHNlY29uZCBjb21wb25lbnQuCiAgICAgICAgICAgICAgICAgKiBzdGVwKHNyYzEgKiAtMS4wLCBzcmMwICogLTEuMCkgaXMgbm90IGFuIG9wdGlvbiBiZWNhdXNlIGl0IHN1ZmZlcnMgZnJvbSB0aGUgc2FtZQogICAgICAgICAgICAgICAgICogaXNzdWUuIFBsYXlpbmcgd2l0aCBub3QoKSBpcyBub3QgcG9zc2libGUgZWl0aGVyIGJlY2F1c2Ugbm90KCkgZG9lcyBub3QgYWNjZXB0CiAgICAgICAgICAgICAgICAgKiBhIHNjYWxhci4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIoJXMgPCAlcykgPyAxLjAgOiAwLjApO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RTSU9fU0dFOgogICAgICAgICAgICAgICAgLyogSGVyZSB3ZSBjYW4gdXNlIHRoZSBzdGVwKCkgZnVuY3Rpb24gYW5kIHNhZmUgYSBjb25kaXRpb25hbCAqLwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJzdGVwKCVzLCAlcykpO1xuIiwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBvcGNvZGUgJXNcbiIsIGFyZy0+b3Bjb2RlLT5uYW1lKTsKICAgICAgICB9CgogICAgfQp9CgovKiogUHJvY2VzcyBDTVAgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gc3JjMCA+PSAwLjAgPyBzcmMxIDogc3JjMiksIHBlciBjaGFubmVsICovCnZvaWQgc2hhZGVyX2dsc2xfY21wKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2ssIGNtcF9jaGFubmVsID0gMDsKICAgIHVuc2lnbmVkIGludCBpLCBqOwogICAgY2hhciBtYXNrX2NoYXJbNl07CiAgICBCT09MIHRlbXBfZGVzdGluYXRpb24gPSBGQUxTRTsKCiAgICBpZihzaGFkZXJfaXNfc2NhbGFyKGFyZy0+c3JjWzBdKSkgewogICAgICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwoKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfQUxMLCAmc3JjMF9wYXJhbSk7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCB3cml0ZV9tYXNrLCAmc3JjMV9wYXJhbSk7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMgPj0gMC4wID8gJXMgOiAlcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0ciwgc3JjMl9wYXJhbS5wYXJhbV9zdHIpOwogICAgfSBlbHNlIHsKICAgICAgICBEV09SRCBzcmMwcmVnID0gYXJnLT5zcmNbMF0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgRFdPUkQgc3JjMXJlZyA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIERXT1JEIHNyYzJyZWcgPSBhcmctPnNyY1syXSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICBEV09SRCBzcmMwcmVndHlwZSA9IHNoYWRlcl9nZXRfcmVndHlwZShhcmctPnNyY1swXSk7CiAgICAgICAgRFdPUkQgc3JjMXJlZ3R5cGUgPSBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5zcmNbMV0pOwogICAgICAgIERXT1JEIHNyYzJyZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKGFyZy0+c3JjWzJdKTsKICAgICAgICBEV09SRCBkc3RyZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICBEV09SRCBkc3RyZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKGFyZy0+ZHN0KTsKCiAgICAgICAgLyogQ3ljbGUgdGhyb3VnaCBhbGwgc291cmNlMCBjaGFubmVscyAqLwogICAgICAgIGZvciAoaT0wOyBpPDQ7IGkrKykgewogICAgICAgICAgICB3cml0ZV9tYXNrID0gMDsKICAgICAgICAgICAgLyogRmluZCB0aGUgZGVzdGluYXRpb24gY2hhbm5lbHMgd2hpY2ggdXNlIHRoZSBjdXJyZW50IHNvdXJjZTAgY2hhbm5lbCAqLwogICAgICAgICAgICBmb3IgKGo9MDsgajw0OyBqKyspIHsKICAgICAgICAgICAgICAgIGlmICggKChhcmctPnNyY1swXSA+PiAoV0lORUQzRFNQX1NXSVpaTEVfU0hJRlQgKyAyKmopKSAmIDB4MykgPT0gaSApIHsKICAgICAgICAgICAgICAgICAgICB3cml0ZV9tYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMCA8PCBqOwogICAgICAgICAgICAgICAgICAgIGNtcF9jaGFubmVsID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIDw8IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFNwbGl0dGluZyB0aGUgY21wIGluc3RydWN0aW9uIHVwIGluIG11bHRpcGxlIGxpbmVzIGltcG9zZXMgYSBwcm9ibGVtOgogICAgICAgICAgICAqIFRoZSBmaXJzdCBsaW5lcyBtYXkgb3ZlcndyaXRlIHNvdXJjZSBwYXJhbWV0ZXJzIG9mIHRoZSBmb2xsb3dpbmcgbGluZXMuCiAgICAgICAgICAgICogRGVhbCB3aXRoIHRoYXQgYnkgdXNpbmcgYSB0ZW1wb3JhcnkgZGVzdGluYXRpb24gcmVnaXN0ZXIgaWYgbmVlZGVkCiAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKChzcmMwcmVnID09IGRzdHJlZyAmJiBzcmMwcmVndHlwZSA9PSBkc3RyZWd0eXBlKSB8fAogICAgICAgICAgICAoc3JjMXJlZyA9PSBkc3RyZWcgJiYgc3JjMXJlZ3R5cGUgPT0gZHN0cmVndHlwZSkgfHwKICAgICAgICAgICAgKHNyYzJyZWcgPT0gZHN0cmVnICYmIHNyYzJyZWd0eXBlID09IGRzdHJlZ3R5cGUpKSB7CgogICAgICAgICAgICAgICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0ICYgKH5XSU5FRDNEU1BfU1dJWlpMRV9NQVNLIHwgd3JpdGVfbWFzayksIG1hc2tfY2hhcik7CiAgICAgICAgICAgICAgICBpZiAoIXdyaXRlX21hc2spIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwJXMgPSAoIiwgbWFza19jaGFyKTsKICAgICAgICAgICAgICAgIHRlbXBfZGVzdGluYXRpb24gPSBUUlVFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KGFyZy0+YnVmZmVyLCBhcmcsIGFyZy0+ZHN0ICYgKH5XSU5FRDNEU1BfU1dJWlpMRV9NQVNLIHwgd3JpdGVfbWFzaykpOwogICAgICAgICAgICAgICAgaWYgKCF3cml0ZV9tYXNrKSBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBjbXBfY2hhbm5lbCwgJnNyYzBfcGFyYW0pOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHdyaXRlX21hc2ssICZzcmMxX3BhcmFtKTsKICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzID49IDAuMCA/ICVzIDogJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQoKICAgICAgICBpZih0ZW1wX2Rlc3RpbmF0aW9uKSB7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBtYXNrX2NoYXIpOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0X2V4dChhcmctPmJ1ZmZlciwgYXJnLCBhcmctPmRzdCk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMCVzKTtcbiIsIG1hc2tfY2hhcik7CiAgICAgICAgfQogICAgfQoKfQoKLyoqIFByb2Nlc3MgdGhlIENORCBvcGNvZGUgaW4gR0xTTCAoZHN0ID0gKHNyYzAgPiAwLjUpID8gc3JjMSA6IHNyYzIpICovCi8qIEZvciBwcyAxLjEtMS4zLCBvbmx5IGEgc2luZ2xlIGNvbXBvbmVudCBvZiBzcmMwIGlzIHVzZWQuIEZvciBwcyAxLjQKICogdGhlIGNvbXBhcmUgaXMgZG9uZSBwZXIgY29tcG9uZW50IG9mIHNyYzAuICovCnZvaWQgc2hhZGVyX2dsc2xfY25kKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzJfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrLCBjbXBfY2hhbm5lbCA9IDA7CiAgICB1bnNpZ25lZCBpbnQgaSwgajsKCiAgICBpZiAoc2hhZGVyLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMSwgNCkpIHsKICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgd3JpdGVfbWFzaywgJnNyYzJfcGFyYW0pOwoKICAgICAgICAvKiBGdW46IFRoZSBEM0RTSV9DT0lTU1VFIGZsYWcgY2hhbmdlcyB0aGUgc2VtYW50aWMgb2YgdGhlIGNuZCBpbnN0cnVjdGlvbiBmb3IgPCAxLjQgc2hhZGVycyAqLwogICAgICAgIGlmKGFyZy0+b3Bjb2RlX3Rva2VuICYgV0lORUQzRFNJX0NPSVNTVUUpIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyAvKiBDT0lTU1VFISAqLyk7XG4iLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyA+IDAuNSA/ICVzIDogJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzJfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgLyogQ3ljbGUgdGhyb3VnaCBhbGwgc291cmNlMCBjaGFubmVscyAqLwogICAgZm9yIChpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgd3JpdGVfbWFzayA9IDA7CiAgICAgICAgLyogRmluZCB0aGUgZGVzdGluYXRpb24gY2hhbm5lbHMgd2hpY2ggdXNlIHRoZSBjdXJyZW50IHNvdXJjZTAgY2hhbm5lbCAqLwogICAgICAgIGZvciAoaj0wOyBqPDQ7IGorKykgewogICAgICAgICAgICBpZiAoICgoYXJnLT5zcmNbMF0gPj4gKFdJTkVEM0RTUF9TV0laWkxFX1NISUZUICsgMipqKSkgJiAweDMpID09IGkgKSB7CiAgICAgICAgICAgICAgICB3cml0ZV9tYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMCA8PCBqOwogICAgICAgICAgICAgICAgY21wX2NoYW5uZWwgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgPDwgajsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdF9leHQoYXJnLT5idWZmZXIsIGFyZywgYXJnLT5kc3QgJiAofldJTkVEM0RTUF9TV0laWkxFX01BU0sgfCB3cml0ZV9tYXNrKSk7CiAgICAgICAgaWYgKCF3cml0ZV9tYXNrKSBjb250aW51ZTsKCiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBjbXBfY2hhbm5lbCwgJnNyYzBfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgd3JpdGVfbWFzaywgJnNyYzJfcGFyYW0pOwoKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzID4gMC41ID8gJXMgOiAlcyk7XG4iLAogICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qKiBHTFNMIGNvZGUgZ2VuZXJhdGlvbiBmb3IgV0lORUQzRFNJT19NQUQ6IE11bHRpcGx5IHRoZSBmaXJzdCAyIG9wY29kZXMsIHRoZW4gYWRkIHRoZSBsYXN0ICovCnZvaWQgc2hhZGVyX2dsc2xfbWFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CgogICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiglcyAqICVzKSArICVzKTtcbiIsCiAgICAgICAgICAgIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0ciwgc3JjMl9wYXJhbS5wYXJhbV9zdHIpOwp9CgovKiogSGFuZGxlcyB0cmFuc2Zvcm1pbmcgYWxsIFdJTkVEM0RTSU9fTT94PyBvcGNvZGVzIGZvciAKICAgIFZlcnRleCBzaGFkZXJzIHRvIEdMU0wgY29kZXMgKi8Kdm9pZCBzaGFkZXJfZ2xzbF9tbnhuKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGludCBpOwogICAgaW50IG5Db21wb25lbnRzID0gMDsKICAgIFNIQURFUl9PUENPREVfQVJHIHRtcEFyZzsKICAgCiAgICBtZW1zZXQoJnRtcEFyZywgMCwgc2l6ZW9mKFNIQURFUl9PUENPREVfQVJHKSk7CgogICAgLyogU2V0IGNvbnN0YW50cyBmb3IgdGhlIHRlbXBvcmFyeSBhcmd1bWVudCAqLwogICAgdG1wQXJnLnNoYWRlciAgICAgID0gYXJnLT5zaGFkZXI7CiAgICB0bXBBcmcuYnVmZmVyICAgICAgPSBhcmctPmJ1ZmZlcjsKICAgIHRtcEFyZy5zcmNbMF0gICAgICA9IGFyZy0+c3JjWzBdOwogICAgdG1wQXJnLnNyY19hZGRyWzBdID0gYXJnLT5zcmNfYWRkclswXTsKICAgIHRtcEFyZy5zcmNfYWRkclsxXSA9IGFyZy0+c3JjX2FkZHJbMV07CiAgICB0bXBBcmcucmVnX21hcHMgPSBhcmctPnJlZ19tYXBzOyAKICAgIAogICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTTR4NDoKICAgICAgICAgICAgbkNvbXBvbmVudHMgPSA0OwogICAgICAgICAgICB0bXBBcmcub3Bjb2RlID0gc2hhZGVyX2dldF9vcGNvZGUoYXJnLT5zaGFkZXIsIFdJTkVEM0RTSU9fRFA0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX000eDM6CiAgICAgICAgICAgIG5Db21wb25lbnRzID0gMzsKICAgICAgICAgICAgdG1wQXJnLm9wY29kZSA9IHNoYWRlcl9nZXRfb3Bjb2RlKGFyZy0+c2hhZGVyLCBXSU5FRDNEU0lPX0RQNCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19NM3g0OgogICAgICAgICAgICBuQ29tcG9uZW50cyA9IDQ7CiAgICAgICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTTN4MzoKICAgICAgICAgICAgbkNvbXBvbmVudHMgPSAzOwogICAgICAgICAgICB0bXBBcmcub3Bjb2RlID0gc2hhZGVyX2dldF9vcGNvZGUoYXJnLT5zaGFkZXIsIFdJTkVEM0RTSU9fRFAzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX00zeDI6CiAgICAgICAgICAgIG5Db21wb25lbnRzID0gMjsKICAgICAgICAgICAgdG1wQXJnLm9wY29kZSA9IHNoYWRlcl9nZXRfb3Bjb2RlKGFyZy0+c2hhZGVyLCBXSU5FRDNEU0lPX0RQMyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBuQ29tcG9uZW50czsgaSsrKSB7CiAgICAgICAgdG1wQXJnLmRzdCA9ICgoYXJnLT5kc3QpICYgfldJTkVEM0RTUF9XUklURU1BU0tfQUxMKXwoV0lORUQzRFNQX1dSSVRFTUFTS18wPDxpKTsKICAgICAgICB0bXBBcmcuc3JjWzFdICAgICAgPSBhcmctPnNyY1sxXStpOwogICAgICAgIHNoYWRlcl9nbHNsX2RvdCgmdG1wQXJnKTsKICAgIH0KfQoKLyoqCiAgICBUaGUgTFJQIGluc3RydWN0aW9uIHBlcmZvcm1zIGEgY29tcG9uZW50LXdpc2UgbGluZWFyIGludGVycG9sYXRpb24gCiAgICBiZXR3ZWVuIHRoZSBzZWNvbmQgYW5kIHRoaXJkIG9wZXJhbmRzIHVzaW5nIHRoZSBmaXJzdCBvcGVyYW5kIGFzIHRoZQogICAgYmxlbmQgZmFjdG9yLiAgRXF1YXRpb246ICAoZHN0ID0gc3JjMiArIHNyYzAgKiAoc3JjMSAtIHNyYzIpKQogICAgVGhpcyBpcyBlcXVpdmFsZW50IHRvIG1peChzcmMyLCBzcmMxLCBzcmMwKTsKKi8Kdm9pZCBzaGFkZXJfZ2xzbF9scnAoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMyX3BhcmFtOwogICAgRFdPUkQgd3JpdGVfbWFzazsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJtaXgoJXMsICVzLCAlcykpO1xuIiwKICAgICAgICAgICAgc3JjMl9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX0xJVCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBkc3QueCA9IGRzdC53ID0gMS4wCiAqIGRzdC55ID0gKHNyYzAueCA+IDApID8gc3JjMC54CiAqIGRzdC56ID0gKHNyYzAueCA+IDApID8gKChzcmMwLnkgPiAwKSA/IHBvdyhzcmMwLnksIHNyYy53KSA6IDApIDogMAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVyZSBzcmMudyBpcyBjbGFtcGVkIGF0ICstIDEyOAogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9saXQoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMzX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjM19wYXJhbSk7CgogICAgLyogVGhlIHNkayBzcGVjaWZpZXMgdGhlIGluc3RydWN0aW9uIGxpa2UgdGhpcwogICAgICogZHN0LnggPSAxLjA7CiAgICAgKiBpZihzcmMueCA+IDAuMCkgZHN0LnkgPSBzcmMueAogICAgICogZWxzZSBkc3QueSA9IDAuMC4KICAgICAqIGlmKHNyYy54ID4gMC4wICYmIHNyYy55ID4gMC4wKSBkc3QueiA9IHBvdyhzcmMueSwgcG93ZXIpOwogICAgICogZWxzZSBkc3QueiA9IDAuMDsKICAgICAqIGRzdC53ID0gMS4wOwogICAgICoKICAgICAqIE9idmlvdXNseSB0aGF0IGhhcyBxdWl0ZSBhIGZldyBjb25kaXRpb25hbHMgaW4gaXQgd2hpY2ggd2UgZG9uJ3QgbGlrZS4gU28gdGhlIGZpcnN0IHN0ZXAgaXMgdGhpczoKICAgICAqIGRzdC54ID0gMS4wICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLiBObyBmdXJ0aGVyIGV4cGxhbmF0aW9uIG5lZWRlZAogICAgICogZHN0LnkgPSBtYXgoc3JjLnksIDAuMCk7ICAgICAgICAgICAgICAgICAgICAgLi4uIElmIHggPCAwLjAsIHVzZSAwLjAsIG90aGVyd2lzZSB4LiBTYW1lIGFzIHRoZSBjb25kaXRpb25hbAogICAgICogZHN0LnogPSB4ID4gMC4wID8gcG93KG1heCh5LCAwLjApLCBwKSA6IDA7ICAgLi4uIDAgXiBwb3dlciBpcyAwLCBhbmQgb3RoZXJ3aXNlIHdlIHVzZSB5IGFueXdheQogICAgICogZHN0LncgPSAxLjAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uIE5vdGhpbmcgZmFuY3kuCiAgICAgKgogICAgICogU28gd2Ugc3RpbGwgaGF2ZSBvbmUgY29uZGl0aW9uYWwgaW4gdGhlcmUuIFNvIGRvIHRoaXM6CiAgICAgKiBkc3QueiA9IHBvdyhtYXgoMC4wLCBzcmMueSkgKiBzdGVwKDAuMCwgc3JjLngpLCBwb3dlcik7CiAgICAgKgogICAgICogc3RlcCgwLjAsIHgpIHdpbGwgcmV0dXJuIDEgaWYgc3JjLnggPiAwLjAsIGFuZCAwIG90aGVyd2lzZS4gU28gaWYgeSBpcyAwIHdlIGdldCBwb3coMC4wICogMS4wLCBwb3dlciksCiAgICAgKiB3aGljaCBzZXRzIGRzdC56IHRvIDAuIElmIHkgPiAwLCBidXQgeCA9IDAuMCwgd2UgZ2V0IHBvdyh5ICogMC4wLCBwb3dlciksIHdoaWNoIHJlc3VsdHMgaW4gMCB0b28uCiAgICAgKiBpZiBib3RoIHggYW5kIHkgYXJlID4gMCwgd2UgZ2V0IHBvdyh5ICogMS4wLCBwb3dlciksIGFzIGl0IGlzIHN1cHBvc2VkIHRvCiAgICAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjNCgxLjAsIG1heCglcywgMC4wKSwgcG93KG1heCgwLjAsICVzKSAqIHN0ZXAoMC4wLCAlcyksIGNsYW1wKCVzLCAtMTI4LjAsIDEyOC4wKSksIDEuMCklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjM19wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fRFNUIGluc3RydWN0aW9uIGluIEdMU0w6CiAqIGRzdC54ID0gMS4wCiAqIGRzdC55ID0gc3JjMC54ICogc3JjMC55CiAqIGRzdC56ID0gc3JjMC56CiAqIGRzdC53ID0gc3JjMS53CiAqLwp2b2lkIHNoYWRlcl9nbHNsX2RzdChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzB5X3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwel9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMXlfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzF3X3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzB5X3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmc3JjMHpfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxeV9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJnNyYzF3X3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYzQoMS4wLCAlcyAqICVzLCAlcywgJXMpKSVzO1xuIiwKICAgICAgICAgICAgc3JjMHlfcGFyYW0ucGFyYW1fc3RyLCBzcmMxeV9wYXJhbS5wYXJhbV9zdHIsIHNyYzB6X3BhcmFtLnBhcmFtX3N0ciwgc3JjMXdfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1NJTkNPUyBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBWUyAyLjAgcmVxdWlyZXMgdGhhdCBzcGVjaWZpYyBjb3NpbmUgYW5kIHNpbmUgY29uc3RhbnRzIGJlIHBhc3NlZCB0byB0aGlzIGluc3RydWN0aW9uIHNvIHRoZSBoYXJkd2FyZQogKiBjYW4gaGFuZGxlIGl0LiAgQnV0LCB0aGVzZSBmdW5jdGlvbnMgYXJlIGJ1aWx0LWluIGZvciBHTFNMLCBzbyB3ZSBjYW4ganVzdCBpZ25vcmUgdGhlIGxhc3QgMiBwYXJhbXMuCiAqIAogKiBkc3QueCA9IGNvcyhzcmMwLj8pCiAqIGRzdC55ID0gc2luKHNyYzAuPykKICogZHN0LnogPSBkc3QuegogKiBkc3QudyA9IGRzdC53CiAqLwp2b2lkIHNoYWRlcl9nbHNsX3NpbmNvcyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKCiAgICBzd2l0Y2ggKHdyaXRlX21hc2spIHsKICAgICAgICBjYXNlIFdJTkVEM0RTUF9XUklURU1BU0tfMDoKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJjb3MoJXMpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzRFNQX1dSSVRFTUFTS18xOgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInNpbiglcykpO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAoV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xKToKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2ZWMyKGNvcyglcyksIHNpbiglcykpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIldyaXRlIG1hc2sgc2hvdWxkIGJlIC54LCAueSBvciAueHlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fTE9PUCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBTdGFydCBhIGZvcigpIGxvb3Agd2hlcmUgc3JjMS55IGlzIHRoZSBpbml0aWFsIHZhbHVlIG9mIGFMLAogKiAgaW5jcmVtZW50IGFMIGJ5IHNyYzEueiBmb3IgYSB0b3RhbCBvZiBzcmMxLnggaXRlcmF0aW9ucy4KICogIE5lZWQgdG8gdXNlIGEgdGVtcG9yYXJ5IHZhcmlhYmxlIGZvciB0aGlzIG9wZXJhdGlvbi4KICovCi8qIEZJWE1FOiBJIGRvbid0IHRoaW5rIG5lc3RlZCBsb29wcyB3aWxsIHdvcmsgY29ycmVjdGx5IHRoaXMgd2F5LiAqLwp2b2lkIHNoYWRlcl9nbHNsX2xvb3AoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIERXT1JEIHJlZ3R5cGUgPSBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5zcmNbMV0pOwogICAgRFdPUkQgcmVnID0gYXJnLT5zcmNbMV0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBjb25zdCBEV09SRCAqY29udHJvbF92YWx1ZXMgPSBOVUxMOwogICAgbG9jYWxfY29uc3RhbnQgKmNvbnN0YW50OwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgV0lORUQzRFNQX1dSSVRFTUFTS19BTEwsICZzcmMxX3BhcmFtKTsKCiAgICAvKiBUcnkgdG8gaGFyZGNvZGUgdGhlIGxvb3AgY29udHJvbCBwYXJhbWV0ZXJzIGlmIHBvc3NpYmxlLiBEaXJlY3QzRCA5IGNsYXNzIGhhcmR3YXJlIGRvZXNuJ3Qgc3VwcG9ydCByZWFsCiAgICAgKiB2YXJ5aW5nIGluZGV4aW5nLCBidXQgTWljcm9zb2Z0IGRlc2lnbmVkIHRoaXMgZmVhdHVyZSBmb3IgU2hhZGVyIG1vZGVsIDIueCsuIElmIHRoZSBsb29wIGNvbnRyb2wgaXMKICAgICAqIGtub3duIGF0IGNvbXBpbGUgdGltZSwgdGhlIEdMU0wgY29tcGlsZXIgY2FuIHVucm9sbCB0aGUgbG9vcCwgYW5kIHJlcGxhY2UgaW5kaXJlY3QgYWRkcmVzc2luZyB3aXRoIGRpcmVjdAogICAgICogYWRkcmVzc2luZy4KICAgICAqLwogICAgaWYocmVndHlwZSA9PSBXSU5FRDNEU1BSX0NPTlNUSU5UKSB7CiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShjb25zdGFudCwgJnNoYWRlci0+YmFzZVNoYWRlci5jb25zdGFudHNJLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgaWYoY29uc3RhbnQtPmlkeCA9PSByZWcpIHsKICAgICAgICAgICAgICAgIGNvbnRyb2xfdmFsdWVzID0gY29uc3RhbnQtPnZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYoY29udHJvbF92YWx1ZXMpIHsKICAgICAgICBpZihjb250cm9sX3ZhbHVlc1syXSA+IDApIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJmb3IgKGFMJXUgPSAlZDsgYUwldSA8ICglZCAqICVkICsgJWQpOyBhTCV1ICs9ICVkKSB7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzBdLCBjb250cm9sX3ZhbHVlc1syXSwgY29udHJvbF92YWx1ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCwgY29udHJvbF92YWx1ZXNbMl0pOwogICAgICAgIH0gZWxzZSBpZihjb250cm9sX3ZhbHVlc1syXSA9PSAwKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yIChhTCV1ID0gJWQsIHRtcEludCV1ID0gMDsgdG1wSW50JXUgPCAlZDsgdG1wSW50JXUrKykge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1sxXSwgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yIChhTCV1ID0gJWQ7IGFMJXUgPiAoJWQgKiAlZCArICVkKTsgYUwldSArPSAlZCkge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1swXSwgY29udHJvbF92YWx1ZXNbMl0sIGNvbnRyb2xfdmFsdWVzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzJdKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yICh0bXBJbnQldSA9IDAsIGFMJXUgPSAlcy55OyB0bXBJbnQldSA8ICVzLng7IHRtcEludCV1KyssIGFMJXUgKz0gJXMueikge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9yZWdubywKICAgICAgICAgICAgICAgICAgICAgICBzcmMxX3BhcmFtLnJlZ19uYW1lLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIHNyYzFfcGFyYW0ucmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfcmVnbm8sIHNyYzFfcGFyYW0ucmVnX25hbWUpOwogICAgfQoKICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCsrOwogICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX3JlZ25vKys7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfZW5kKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ9XG4iKTsKCiAgICBpZihhcmctPm9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fRU5ETE9PUCkgewogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aC0tOwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9yZWduby0tOwogICAgfQogICAgaWYoYXJnLT5vcGNvZGUtPm9wY29kZSA9PSBXSU5FRDNEU0lPX0VORFJFUCkgewogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aC0tOwogICAgfQp9Cgp2b2lkIHNoYWRlcl9nbHNsX3JlcChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImZvciAodG1wSW50JWQgPSAwOyB0bXBJbnQlZCA8ICVzOyB0bXBJbnQlZCsrKSB7XG4iLAogICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsCiAgICAgICAgICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoKTsKICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCsrOwp9Cgp2b2lkIHNoYWRlcl9nbHNsX2lmKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoJXMpIHtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9pZmMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzFfcGFyYW0pOwoKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiaWYgKCVzICVzICVzKSB7XG4iLAogICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc2hhZGVyX2dldF9jb21wX29wKGFyZy0+b3Bjb2RlX3Rva2VuKSwgc3JjMV9wYXJhbS5wYXJhbV9zdHIpOwp9Cgp2b2lkIHNoYWRlcl9nbHNsX2Vsc2UoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ9IGVsc2Uge1xuIik7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfYnJlYWsoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJicmVhaztcbiIpOwp9CgovKiBGSVhNRTogQWNjb3JkaW5nIHRvIE1TRE4gdGhlIGNvbXBhcmUgaXMgZG9uZSBwZXIgY29tcG9uZW50LiAqLwp2b2lkIHNoYWRlcl9nbHNsX2JyZWFrYyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMV9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoJXMgJXMgJXMpIGJyZWFrO1xuIiwKICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNoYWRlcl9nZXRfY29tcF9vcChhcmctPm9wY29kZV90b2tlbiksIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9sYWJlbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgRFdPUkQgc251bSA9IChhcmctPnNyY1swXSkgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIn1cbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2b2lkIHN1YnJvdXRpbmUldSAoKSB7XG4iLCAgc251bSk7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfY2FsbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzbnVtID0gKGFyZy0+c3JjWzBdKSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAic3Vicm91dGluZSV1KCk7XG4iLCBzbnVtKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9jYWxsbnooU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwoKICAgIERXT1JEIHNudW0gPSAoYXJnLT5zcmNbMF0pICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiaWYgKCVzKSBzdWJyb3V0aW5lJXUoKTtcbiIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzbnVtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQaXhlbCBTaGFkZXIgU3BlY2lmaWMgQ29kZSBiZWdpbnMgaGVyZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgcHNoYWRlcl9nbHNsX3RleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgRFdPUkQgaGV4X3ZlcnNpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uOwogICAgY2hhciBkc3Rfc3dpenpsZVs2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgRFdPUkQgc2FtcGxlcl90eXBlOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBCT09MIHByb2plY3RlZCwgdGV4cmVjdCA9IEZBTFNFOwogICAgRFdPUkQgbWFzayA9IDA7CgogICAgLyogQWxsIHZlcnNpb25zIGhhdmUgYSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKCiAgICAvKiAxLjAtMS40OiBVc2UgZGVzdGluYXRpb24gcmVnaXN0ZXIgYXMgc2FtcGxlciBzb3VyY2UuCiAgICAgKiAyLjArOiBVc2UgcHJvdmlkZWQgc2FtcGxlciBzb3VyY2UuICovCiAgICBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigxLDQpKSB7CiAgICAgICAgRFdPUkQgZmxhZ3M7CgogICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgZmxhZ3MgPSBkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbc2FtcGxlcl9pZHhdW1dJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTXTsKCiAgICAgICAgaWYgKGZsYWdzICYgV0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIHN3aXRjaCAoZmxhZ3MgJiB+V0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMTogRklYTUUoIldJTkVEM0RUVEZGX1BST0pFQ1RFRCB3aXRoIFdJTkVEM0RUVEZGX0NPVU5UMT9cbiIpOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQyOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18xOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQzOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18yOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQ0OgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9ESVNBQkxFOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18zOyBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IEZBTFNFOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigyLDApKSB7CiAgICAgICAgRFdPUkQgc3JjX21vZCA9IGFyZy0+c3JjWzBdICYgV0lORUQzRFNQX1NSQ01PRF9NQVNLOwogICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CgogICAgICAgIGlmIChzcmNfbW9kID09IFdJTkVEM0RTUFNNX0RaKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIG1hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICAgICAgfSBlbHNlIGlmIChzcmNfbW9kID09IFdJTkVEM0RTUFNNX0RXKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIG1hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJvamVjdGVkID0gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzYW1wbGVyX2lkeCA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIGlmKGFyZy0+b3Bjb2RlX3Rva2VuICYgV0lORUQzRFNJX1RFWExEX1BST0pFQ1QpIHsKICAgICAgICAgICAgICAgIC8qIHBzIDIuMCB0ZXhsZHAgaW5zdHJ1Y3Rpb24gYWx3YXlzIGRpdmlkZXMgYnkgdGhlIGZvdXJ0aCBjb21wb25lbnQuICovCiAgICAgICAgICAgICAgICBwcm9qZWN0ZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcm9qZWN0ZWQgPSBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgaWYoZGV2aWNlSW1wbC0+c3RhdGVCbG9jay0+dGV4dHVyZXNbc2FtcGxlcl9pZHhdICYmCiAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XSkgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgdGV4cmVjdCA9IFRSVUU7CiAgICB9CgogICAgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBzaGFkZXJfZ2xzbF9nZXRfc2FtcGxlX2Z1bmN0aW9uKHNhbXBsZXJfdHlwZSwgcHJvamVjdGVkLCB0ZXhyZWN0LCAmc2FtcGxlX2Z1bmN0aW9uKTsKICAgIG1hc2sgfD0gc2FtcGxlX2Z1bmN0aW9uLmNvb3JkX21hc2s7CgogICAgaWYgKGhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9nbHNsX2dldF9zd2l6emxlKGFyZy0+c3JjWzFdLCBGQUxTRSwgYXJnLT5kc3QsIGRzdF9zd2l6emxlKTsKICAgIH0KCiAgICAvKiAxLjAtMS4zOiBVc2UgZGVzdGluYXRpb24gcmVnaXN0ZXIgYXMgY29vcmRpbmF0ZSBzb3VyY2UuCiAgICAgICAxLjQrOiBVc2UgcHJvdmlkZWQgY29vcmRpbmF0ZSBzb3VyY2UgcmVnaXN0ZXIuICovCiAgICBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigxLDQpKSB7CiAgICAgICAgY2hhciBjb29yZF9tYXNrWzZdOwogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKG1hc2ssIGNvb3JkX21hc2spOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgVCV1JXMpJXMpO1xuIiwKICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIGNvb3JkX21hc2ssIGRzdF9zd2l6emxlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBjb29yZF9wYXJhbTsKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIG1hc2ssICZjb29yZF9wYXJhbSk7CiAgICAgICAgaWYoYXJnLT5vcGNvZGVfdG9rZW4gJiBXSU5FRDNEU0lfVEVYTERfQklBUykgewogICAgICAgICAgICBnbHNsX3NyY19wYXJhbV90IGJpYXM7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmYmlhcyk7CgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzKFBzYW1wbGVyJXUsICVzLCAlcyklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLAogICAgICAgICAgICAgICAgICAgIGJpYXMucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCAlcyklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIHNoYWRlcl9nbHNsX3RleGxkbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKWFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CiAgICBnbHNsX3NyY19wYXJhbV90IGNvb3JkX3BhcmFtLCBsb2RfcGFyYW07CiAgICBjaGFyIGRzdF9zd2l6emxlWzZdOwogICAgRFdPUkQgc2FtcGxlcl90eXBlOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBCT09MIHRleHJlY3QgPSBGQUxTRTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3N3aXp6bGUoYXJnLT5zcmNbMV0sIEZBTFNFLCBhcmctPmRzdCwgZHN0X3N3aXp6bGUpOwoKICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5zcmNbMV0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBzYW1wbGVyX3R5cGUgPSBhcmctPnJlZ19tYXBzLT5zYW1wbGVyc1tzYW1wbGVyX2lkeF0gJiBXSU5FRDNEU1BfVEVYVFVSRVRZUEVfTUFTSzsKICAgIGlmKGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XSAmJgogICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tzYW1wbGVyX2lkeF0pID09IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikgewogICAgICAgIHRleHJlY3QgPSBUUlVFOwogICAgfQogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCB0ZXhyZWN0LCAmc2FtcGxlX2Z1bmN0aW9uKTsgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzYW1wbGVfZnVuY3Rpb24uY29vcmRfbWFzaywgJmNvb3JkX3BhcmFtKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJmxvZF9wYXJhbSk7CgogICAgaWYgKHNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbikpIHsKICAgICAgICAvKiBUaGUgR0xTTCBzcGVjIGNsYWltcyB0aGUgTG9kIHNhbXBsaW5nIGZ1bmN0aW9ucyBhcmUgb25seSBzdXBwb3J0ZWQgaW4gdmVydGV4IHNoYWRlcnMuCiAgICAgICAgICogSG93ZXZlciwgdGhleSBzZWVtIHRvIHdvcmsganVzdCBmaW5lIGluIGZyYWdtZW50IHNoYWRlcnMgYXMgd2VsbC4gKi8KICAgICAgICBXQVJOKCJVc2luZyAlc0xvZCBpbiBmcmFnbWVudCBzaGFkZXIuXG4iLCBzYW1wbGVfZnVuY3Rpb24ubmFtZSk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlc0xvZChQc2FtcGxlciV1LCAlcywgJXMpJXMpO1xuIiwKICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBsb2RfcGFyYW0ucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXNMb2QoVnNhbXBsZXIldSwgJXMsICVzKSVzKTtcbiIsCiAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIGNvb3JkX3BhcmFtLnBhcmFtX3N0ciwgbG9kX3BhcmFtLnBhcmFtX3N0ciwgZHN0X3N3aXp6bGUpOwogICAgfQp9Cgp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhjb29yZChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgLyogRklYTUU6IE1ha2UgdGhpcyB3b3JrIGZvciBtb3JlIHRoYW4ganVzdCAyRCB0ZXh0dXJlcyAqLwogICAgCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb247CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKHdyaXRlX21hc2ssIGRzdF9tYXNrKTsKCiAgICBpZiAoaGV4X3ZlcnNpb24gIT0gV0lORUQzRFBTX1ZFUlNJT04oMSw0KSkgewogICAgICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImNsYW1wKGdsX1RleENvb3JkWyV1XSwgMC4wLCAxLjApJXMpO1xuIiwgcmVnLCBkc3RfbWFzayk7CiAgICB9IGVsc2UgewogICAgICAgIERXT1JEIHJlZyA9IGFyZy0+c3JjWzBdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIERXT1JEIHNyY19tb2QgPSBhcmctPnNyY1swXSAmIFdJTkVEM0RTUF9TUkNNT0RfTUFTSzsKICAgICAgICBjaGFyIGRzdF9zd2l6emxlWzZdOwoKICAgICAgICBzaGFkZXJfZ2xzbF9nZXRfc3dpenpsZShhcmctPnNyY1swXSwgRkFMU0UsIHdyaXRlX21hc2ssIGRzdF9zd2l6emxlKTsKCiAgICAgICAgaWYgKHNyY19tb2QgPT0gV0lORUQzRFNQU01fRFopIHsKICAgICAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBkaXZfcGFyYW07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMiwgJmRpdl9wYXJhbSk7CgogICAgICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfVGV4Q29vcmRbJXVdJXMgLyB2ZWMlZCglcykpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgbWFza19zaXplLCBkaXZfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1RleENvb3JkWyV1XSVzIC8gJXMpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgZGl2X3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHNyY19tb2QgPT0gV0lORUQzRFNQU01fRFcpIHsKICAgICAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBkaXZfcGFyYW07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJmRpdl9wYXJhbSk7CgogICAgICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfVGV4Q29vcmRbJXVdJXMgLyB2ZWMlZCglcykpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgbWFza19zaXplLCBkaXZfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1RleENvb3JkWyV1XSVzIC8gJXMpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgZGl2X3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9UZXhDb29yZFsldV0lcyk7XG4iLCByZWcsIGRzdF9zd2l6emxlKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWERQM1RFWCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBUYWtlIGEgMy1jb21wb25lbnQgZG90IHByb2R1Y3Qgb2YgdGhlIFRleENvb3JkW2RzdHJlZ10gYW5kIHNyYywKICogdGhlbiBwZXJmb3JtIGEgMUQgdGV4dHVyZSBsb29rdXAgZnJvbSBzdGFnZSBkc3RyZWdudW0sIHBsYWNlIGludG8gZHN0LiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhkcDN0ZXgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgRFdPUkQgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwoKICAgIC8qIERvIEkgaGF2ZSB0byB0YWtlIGNhcmUgYWJvdXQgdGhlIHByb2plY3RlZCBiaXQ/IEkgZG9uJ3QgdGhpbmsgc28sIHNpbmNlIHRoZSBkcDMgcmV0dXJucyBvbmx5IG9uZQogICAgICogc2NhbGFyLCBhbmQgcHJvamVjdGVkIHNhbXBsaW5nIHdvdWxkIHJlcXVpcmUgNC4KICAgICAqCiAgICAgKiBJdCBpcyBhIGRlcGVuZGVudCByZWFkIC0gbm90IHZhbGlkIHdpdGggY29uZGl0aW9uYWwgTlAyIHRleHR1cmVzCiAgICAgKi8KICAgIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oc2FtcGxlcl90eXBlLCBGQUxTRSwgRkFMU0UsICZzYW1wbGVfZnVuY3Rpb24pOwoKICAgIHN3aXRjaChjb3VudF9iaXRzKHNhbXBsZV9mdW5jdGlvbi5jb29yZF9tYXNrKSkgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCBkb3QoZ2xfVGV4Q29vcmRbJXVdLnh5eiwgJXMpKSVzKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgdmVjMihkb3QoZ2xfVGV4Q29vcmRbJXVdLnh5eiwgJXMpLCAwLjApKSVzKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHNhbXBsZXJfaWR4LCBzYW1wbGVyX2lkeCwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCB2ZWMzKGRvdChnbF9UZXhDb29yZFsldV0ueHl6LCAlcyksIDAuMCwgMC4wKSklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgZHN0X21hc2spOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5leHBlY3RlZCBtYXNrIGJpdGNvdW50ICVkXG4iLCBjb3VudF9iaXRzKHNhbXBsZV9mdW5jdGlvbi5jb29yZF9tYXNrKSk7CiAgICB9Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWERQMyBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBUYWtlIGEgMy1jb21wb25lbnQgZG90IHByb2R1Y3Qgb2YgdGhlIFRleENvb3JkW2RzdHJlZ10gYW5kIHNyYy4gKi8Kdm9pZCBwc2hhZGVyX2dsc2xfdGV4ZHAzKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIERXT1JEIGRzdHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgRFdPUkQgc3JjX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICBEV09SRCBkc3RfbWFzazsKICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemU7CgogICAgZHN0X21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShkc3RfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CgogICAgaWYgKG1hc2tfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGRvdChUJXUueHl6LCAlcykpKTtcbiIsIG1hc2tfc2l6ZSwgZHN0cmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZG90KFQldS54eXosICVzKSk7XG4iLCBkc3RyZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYREVQVEggaW5zdHJ1Y3Rpb24gaW4gR0xTTDoKICogQ2FsY3VsYXRlIHRoZSBkZXB0aCBhcyBkc3QueCAvIGRzdC55ICAgKi8Kdm9pZCBwc2hhZGVyX2dsc2xfdGV4ZGVwdGgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CgogICAgc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LCAwLCAmZHN0X3BhcmFtKTsKCiAgICAvKiBUZXN0cyBzaG93IHRoYXQgdGV4ZGVwdGggbmV2ZXIgcmV0dXJucyBhbnl0aGluZyBiZWxvdyAwLjAsIGFuZCB0aGF0IHI1LnkgaXMgY2xhbXBlZCB0byAxLjAuCiAgICAgKiBOZWdhdGl2ZSBpbnB1dCBpcyBhY2NlcHRlZCwgLTAuMjUgLyAtMC41IHJldHVybnMgMC41LiBHTCBzaG91bGQgY2xhbXAgZ2xfRnJhZ0RlcHRoIHRvIFswOzFdLCBidXQKICAgICAqIHRoaXMgZG9lc24ndCBhbHdheXMgd29yaywgc28gY2xhbXAgdGhlIHJlc3VsdHMgbWFudWFsbHkuIFdoZXRoZXIgb3Igbm90IHRoZSB4IHZhbHVlIGlzIGNsYW1wZWQgYXQgMQogICAgICogdG9vIGlzIGlycmVsZXZhbnQsIHNpbmNlIGlmIHggPSAwLCBhbnkgeSB2YWx1ZSA8IDEuMCAoYW5kID4gMS4wIGlzIG5vdCBhbGxvd2VkKSByZXN1bHRzIGluIGEgcmVzdWx0CiAgICAgKiA+PSAxLjAgb3IgPCAwLjAKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJnbF9GcmFnRGVwdGggPSBjbGFtcCgoJXMueCAvIG1pbiglcy55LCAxLjApKSwgMC4wLCAxLjApO1xuIiwgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ucmVnX25hbWUpOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gyREVQVEggaW5zdHJ1Y3Rpb24gaW4gR0xTTDoKICogTGFzdCByb3cgb2YgYSAzeDIgbWF0cml4IG11bHRpcGx5LCB1c2UgdGhlIHJlc3VsdCB0byBjYWxjdWxhdGUgdGhlIGRlcHRoOgogKiBDYWxjdWxhdGUgdG1wMC55ID0gVGV4Q29vcmRbZHN0cmVnXSAuIHNyYy54eXo7ICAodG1wMC54IGhhcyBhbHJlYWR5IGJlZW4gY2FsY3VsYXRlZCkKICogZGVwdGggPSAodG1wMC55ID09IDAuMCkgPyAxLjAgOiB0bXAwLnggLyB0bXAwLnkKICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleG0zeDJkZXB0aChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIGRzdHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueSA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCBkc3RyZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZ2xfRnJhZ0RlcHRoID0gKHRtcDAueSA9PSAwLjApID8gMS4wIDogY2xhbXAodG1wMC54IC8gdG1wMC55LCAwLjAsIDEuMCk7XG4iKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYMlBBRCBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIENhbGN1bGF0ZSB0aGUgMXN0IG9mIGEgMi1yb3cgbWF0cml4IG11bHRpcGxpY2F0aW9uLiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gycGFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0bXAwLnggPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWE0zWDNQQUQgaW5zdHJ1Y3Rpb24gaW4gR0xTTAogKiBDYWxjdWxhdGUgdGhlIDFzdCBvciAybmQgcm93IG9mIGEgMy1yb3cgbWF0cml4IG11bHRpcGxpY2F0aW9uLiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzcGFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAuJWMgPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgJ3gnICsgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3csIHJlZywgc3JjMF9wYXJhbS5wYXJhbV9zdHIpOwogICAgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1tjdXJyZW50X3N0YXRlLT5jdXJyZW50X3JvdysrXSA9IHJlZzsKfQoKdm9pZCBwc2hhZGVyX2dsc2xfdGV4bTN4MnRleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueSA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CgogICAgLyogU2FtcGxlIHRoZSB0ZXh0dXJlIHVzaW5nIHRoZSBjYWxjdWxhdGVkIGNvb3JkaW5hdGVzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0ZXh0dXJlMkQoUHNhbXBsZXIldSwgdG1wMC54eSklcyk7XG4iLCByZWcsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYM1RFWCBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFBlcmZvcm0gdGhlIDNyZCByb3cgb2YgYSAzeDMgbWF0cml4IG11bHRpcGx5LCB0aGVuIHNhbXBsZSB0aGUgdGV4dHVyZSB1c2luZyB0aGUgY2FsY3VsYXRlZCBjb29yZGluYXRlcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzdGV4KFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIFNIQURFUl9QQVJTRV9TVEFURSogY3VycmVudF9zdGF0ZSA9ICZUaGlzLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbcmVnXSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwLnogPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CiAgICAvKiBEZXBlbmRlbnQgcmVhZCwgbm90IHZhbGlkIHdpdGggY29uZGl0aW9uYWwgTlAyICovCiAgICBzaGFkZXJfZ2xzbF9nZXRfc2FtcGxlX2Z1bmN0aW9uKHNhbXBsZXJfdHlwZSwgRkFMU0UsIEZBTFNFLCAmc2FtcGxlX2Z1bmN0aW9uKTsKCiAgICAvKiBTYW1wbGUgdGhlIHRleHR1cmUgdXNpbmcgdGhlIGNhbGN1bGF0ZWQgY29vcmRpbmF0ZXMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgdG1wMC54eXopJXMpO1xuIiwgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHJlZywgZHN0X21hc2spOwoKICAgIGN1cnJlbnRfc3RhdGUtPmN1cnJlbnRfcm93ID0gMDsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYMyBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFBlcmZvcm0gdGhlIDNyZCByb3cgb2YgYSAzeDMgbWF0cml4IG11bHRpcGx5ICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleG0zeDMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgRFdPUkQgc3JjX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX1BBUlNFX1NUQVRFKiBjdXJyZW50X3N0YXRlID0gJlRoaXMtPmJhc2VTaGFkZXIucGFyc2Vfc3RhdGU7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2ZWM0KHRtcDAueHksIGRvdChUJXUueHl6LCAlcyksIDEuMCklcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7CgogICAgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3cgPSAwOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gzU1BFQyBpbnN0cnVjdGlvbiBpbiBHTFNMIAogKiBQZWZvcm0gdGhlIGZpbmFsIHRleHR1cmUgbG9va3VwIGJhc2VkIG9uIHRoZSBwcmV2aW91cyAyIDN4MyBtYXRyaXggbXVsdGlwbGllcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzc3BlYyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgRFdPUkQgc3R5cGUgPSBhcmctPnJlZ19tYXBzLT5zYW1wbGVyc1tyZWddICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgc3JjX21hc2ssICZzcmMxX3BhcmFtKTsKCiAgICAvKiBQZXJmb3JtIHRoZSBsYXN0IG1hdHJpeCBtdWx0aXBseSBvcGVyYXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueiA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIC8qIFJlZmxlY3Rpb24gY2FsY3VsYXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueHl6ID0gLXJlZmxlY3QoKCVzKSwgbm9ybWFsaXplKHRtcDAueHl6KSk7XG4iLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzdHlwZSwgRkFMU0UsIEZBTFNFLCAmc2FtcGxlX2Z1bmN0aW9uKTsKCiAgICAvKiBTYW1wbGUgdGhlIHRleHR1cmUgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzKFBzYW1wbGVyJXUsIHRtcDAueHl6KSVzKTtcbiIsIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCByZWcsIGRzdF9tYXNrKTsKCiAgICBjdXJyZW50X3N0YXRlLT5jdXJyZW50X3JvdyA9IDA7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWE0zWDNWU1BFQyBpbnN0cnVjdGlvbiBpbiBHTFNMIAogKiBQZWZvcm0gdGhlIGZpbmFsIHRleHR1cmUgbG9va3VwIGJhc2VkIG9uIHRoZSBwcmV2aW91cyAyIDN4MyBtYXRyaXggbXVsdGlwbGllcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzdnNwZWMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbcmVnXSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIC8qIFBlcmZvcm0gdGhlIGxhc3QgbWF0cml4IG11bHRpcGx5IG9wZXJhdGlvbiAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidG1wMC56ID0gZG90KHZlYzMoVCV1KSwgdmVjMyglcykpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CgogICAgLyogQ29uc3RydWN0IHRoZSBleWUtcmF5IHZlY3RvciBmcm9tIHcgY29vcmRpbmF0ZXMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDEueHl6ID0gbm9ybWFsaXplKHZlYzMoZ2xfVGV4Q29vcmRbJXVdLncsIGdsX1RleENvb3JkWyV1XS53LCBnbF9UZXhDb29yZFsldV0udykpO1xuIiwKICAgICAgICAgICAgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1swXSwgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1sxXSwgcmVnKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueHl6ID0gLXJlZmxlY3QodG1wMS54eXosIG5vcm1hbGl6ZSh0bXAwLnh5eikpO1xuIik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCBGQUxTRSwgJnNhbXBsZV9mdW5jdGlvbik7CgogICAgLyogU2FtcGxlIHRoZSB0ZXh0dXJlIHVzaW5nIHRoZSBjYWxjdWxhdGVkIGNvb3JkaW5hdGVzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyhQc2FtcGxlciV1LCB0bXAwLnh5eiklcyk7XG4iLCBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgcmVnLCBkc3RfbWFzayk7CgogICAgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3cgPSAwOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhCRU0gaW5zdHJ1Y3Rpb24gaW4gR0xTTC4KICogQXBwbHkgYSBmYWtlIGJ1bXAgbWFwIHRyYW5zZm9ybS4KICogdGV4YmVtIGlzIHBzaGFkZXIgPD0gMS4zIG9ubHksIHRoaXMgc2F2ZXMgYSBmZXcgdmVyc2lvbiBjaGVja3MKICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleGJlbShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgY2hhciBkc3Rfc3dpenpsZVs2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBjb29yZF9wYXJhbTsKICAgIERXT1JEIHNhbXBsZXJfdHlwZTsKICAgIERXT1JEIHNhbXBsZXJfaWR4OwogICAgRFdPUkQgbWFzazsKICAgIERXT1JEIGZsYWdzOwogICAgY2hhciBjb29yZF9tYXNrWzZdOwoKICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBmbGFncyA9IGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtzYW1wbGVyX2lkeF1bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdOwoKICAgIHNhbXBsZXJfdHlwZSA9IGFyZy0+cmVnX21hcHMtPnNhbXBsZXJzW3NhbXBsZXJfaWR4XSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCBGQUxTRSwgJnNhbXBsZV9mdW5jdGlvbik7CiAgICBtYXNrID0gc2FtcGxlX2Z1bmN0aW9uLmNvb3JkX21hc2s7CgogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9zd2l6emxlKTsKCiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhtYXNrLCBjb29yZF9tYXNrKTsKCiAgICAvKiB3aXRoIHByb2plY3RpdmUgdGV4dHVyZXMsIHRleGJlbSBvbmx5IGRpdmlkZXMgdGhlIHN0YXRpYyB0ZXh0dXJlIGNvb3JkLCBub3QgdGhlIGRpc3BsYWNlbWVudCwKICAgICAgICAgKiBzbyB3ZSBjYW4ndCBsZXQgdGhlIEdMIGhhbmRsZSB0aGlzLgogICAgICAgICAqLwogICAgaWYgKGZsYWdzICYgV0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgRFdPUkQgZGl2X21hc2s9MDsKICAgICAgICBjaGFyIGNvb3JkX2Rpdl9tYXNrWzNdOwogICAgICAgIHN3aXRjaCAoZmxhZ3MgJiB+V0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQxOiBGSVhNRSgiV0lORUQzRFRURkZfUFJPSkVDVEVEIHdpdGggV0lORUQzRFRURkZfQ09VTlQxP1xuIik7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMjogZGl2X21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzE7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMzogZGl2X21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9ESVNBQkxFOiBkaXZfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGRpdl9tYXNrLCBjb29yZF9kaXZfbWFzayk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJUJXUlcyAvPSBUJXUlcztcbiIsIHNhbXBsZXJfaWR4LCBjb29yZF9tYXNrLCBzYW1wbGVyX2lkeCwgY29vcmRfZGl2X21hc2spOwogICAgfQoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMHxXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZjb29yZF9wYXJhbSk7CiAgICBpZihhcmctPm9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fVEVYQkVNTCkgewogICAgICAgIGdsc2xfc3JjX3BhcmFtX3QgbHVtaW5hbmNlX3BhcmFtOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmbHVtaW5hbmNlX3BhcmFtKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiglcyhQc2FtcGxlciV1LCBUJXUlcyArIHZlYzQoYnVtcGVudm1hdCVkICogJXMsIDAuMCwgMC4wKSVzICkqKCVzICogbHVtaW5hbmNlc2NhbGUlZCArIGx1bWluYW5jZW9mZnNldCVkKSklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIGNvb3JkX21hc2ssIHNhbXBsZXJfaWR4LCBjb29yZF9wYXJhbS5wYXJhbV9zdHIsIGNvb3JkX21hc2ssCiAgICAgICAgICAgICAgICAgICAgICAgbHVtaW5hbmNlX3BhcmFtLnBhcmFtX3N0ciwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgVCV1JXMgKyB2ZWM0KGJ1bXBlbnZtYXQlZCAqICVzLCAwLjAsIDAuMCklcyApJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBjb29yZF9tYXNrLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBjb29yZF9tYXNrLCBkc3Rfc3dpenpsZSk7CiAgICB9Cn0KCnZvaWQgcHNoYWRlcl9nbHNsX2JlbShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW0sIHNyYzFfcGFyYW07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wfFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzB8V0lORUQzRFNQX1dSSVRFTUFTS18xLCAmc3JjMV9wYXJhbSk7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMgKyBidW1wZW52bWF0JWQgKiAlcyk7XG4iLAogICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNhbXBsZXJfaWR4LCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWFJFRzJBUiBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFNhbXBsZSAyRCB0ZXh0dXJlIGF0IGRzdCB1c2luZyB0aGUgYWxwaGEgJiByZWQgKHd4KSBjb21wb25lbnRzIG9mIHNyYyBhcyB0ZXh0dXJlIGNvb3JkaW5hdGVzICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleHJlZzJhcihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgRFdPUkQgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIGNoYXIgZHN0X21hc2tbNl07CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfQUxMLCAmc3JjMF9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0ZXh0dXJlMkQoUHNhbXBsZXIldSwgJXMud3gpJXMpO1xuIiwgc2FtcGxlcl9pZHgsIHNyYzBfcGFyYW0ucmVnX25hbWUsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYUkVHMkdCIGluc3RydWN0aW9uIGluIEdMU0wKICogU2FtcGxlIDJEIHRleHR1cmUgYXQgZHN0IHVzaW5nIHRoZSBncmVlbiAmIGJsdWUgKHl6KSBjb21wb25lbnRzIG9mIHNyYyBhcyB0ZXh0dXJlIGNvb3JkaW5hdGVzICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleHJlZzJnYihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS19BTEwsICZzcmMwX3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRleHR1cmUyRChQc2FtcGxlciV1LCAlcy55eiklcyk7XG4iLCBzYW1wbGVyX2lkeCwgc3JjMF9wYXJhbS5yZWdfbmFtZSwgZHN0X21hc2spOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhSRUcyUkdCIGluc3RydWN0aW9uIGluIEdMU0wKICogU2FtcGxlIHRleHR1cmUgYXQgZHN0IHVzaW5nIHRoZSByZ2IgKHh5eikgY29tcG9uZW50cyBvZiBzcmMgYXMgdGV4dHVyZSBjb29yZGluYXRlcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhyZWcycmdiKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGNoYXIgZHN0X21hc2tbNl07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBnbHNsX3NhbXBsZV9mdW5jdGlvbl90IHNhbXBsZV9mdW5jdGlvbjsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIC8qIERlcGVuZGVudCByZWFkLCBub3QgdmFsaWQgd2l0aCBjb25kaXRpb25hbCBOUDIgKi8KICAgIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oc2FtcGxlcl90eXBlLCBGQUxTRSwgRkFMU0UsICZzYW1wbGVfZnVuY3Rpb24pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzYW1wbGVfZnVuY3Rpb24uY29vcmRfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgJXMpJXMpO1xuIiwgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHNhbXBsZXJfaWR4LCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgZHN0X21hc2spOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhLSUxMIGluc3RydWN0aW9uIGluIEdMU0wuCiAqIElmIGFueSBvZiB0aGUgZmlyc3QgMyBjb21wb25lbnRzIGFyZSA8IDAsIGRpc2NhcmQgdGhpcyBwaXhlbCAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhraWxsKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb247CiAgICBnbHNsX2RzdF9wYXJhbV90IGRzdF9wYXJhbTsKCiAgICAvKiBUaGUgYXJndW1lbnQgaXMgYSBkZXN0aW5hdGlvbiBwYXJhbWV0ZXIsIGFuZCBubyB3cml0ZW1hc2tzIGFyZSBhbGxvd2VkICovCiAgICBzaGFkZXJfZ2xzbF9hZGRfZHN0X3BhcmFtKGFyZywgYXJnLT5kc3QsIDAsICZkc3RfcGFyYW0pOwogICAgaWYoKGhleF92ZXJzaW9uID49IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpKSB7CiAgICAgICAgLyogMi4wIHNoYWRlcnMgY29tcGFyZSBhbGwgNCBjb21wb25lbnRzIGluIHRleGtpbGwgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImlmIChhbnkobGVzc1RoYW4oJXMueHl6dywgdmVjNCgwLjApKSkpIGRpc2NhcmQ7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiAxLlggc2hhZGVycyBvbmx5IGNvbXBhcmUgdGhlIGZpcnN0IDMgY29tcG9uZW50cywgcHJvYmFibHkgZHVlIHRvIHRoZSBuYXR1cmUgb2YgdGhlIHRleGtpbGwKICAgICAgICAgKiBpbnN0cnVjdGlvbiBhcyBhIHRleCogaW5zdHJ1Y3Rpb24sIGFuZCBwaGFzZSwgd2hpY2gga2lsbHMgYWxsIGEgLyB3IGNvbXBvbmVudHMuIEV2ZW4gaWYgYWxsCiAgICAgICAgICogNCBjb21wb25lbnRzIGFyZSBkZWZpbmVkLCBvbmx5IHRoZSBmaXJzdCAzIGFyZSB1c2VkCiAgICAgICAgICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoYW55KGxlc3NUaGFuKCVzLnh5eiwgdmVjMygwLjApKSkpIGRpc2NhcmQ7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUpOwogICAgfQp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19EUDJBREQgaW5zdHJ1Y3Rpb24gaW4gR0xTTC4KICogZHN0ID0gZG90MihzcmMwLCBzcmMxKSArIHNyYzIgKi8Kdm9pZCBwc2hhZGVyX2dsc2xfZHAyYWRkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMl9wYXJhbSk7CgogICAgaWYgKG1hc2tfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGRvdCglcywgJXMpICsgJXMpKTtcbiIsIG1hc2tfc2l6ZSwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZG90KCVzLCAlcykgKyAlcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzJfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKdm9pZCBwc2hhZGVyX2dsc2xfaW5wdXRfcGFjaygKICAgU0hBREVSX0JVRkZFUiogYnVmZmVyLAogICBzZW1hbnRpYyogc2VtYW50aWNzX2luLAogICBJV2luZUQzRFBpeGVsU2hhZGVyICppZmFjZSkgewoKICAgdW5zaWduZWQgaW50IGk7CiAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIGlmYWNlOwoKICAgZm9yIChpID0gMDsgaSA8IE1BWF9SRUdfSU5QVVQ7IGkrKykgewoKICAgICAgIERXT1JEIHVzYWdlX3Rva2VuID0gc2VtYW50aWNzX2luW2ldLnVzYWdlOwogICAgICAgRFdPUkQgcmVnaXN0ZXJfdG9rZW4gPSBzZW1hbnRpY3NfaW5baV0ucmVnOwogICAgICAgRFdPUkQgdXNhZ2UsIHVzYWdlX2lkeDsKICAgICAgIGNoYXIgcmVnX21hc2tbNl07CgogICAgICAgLyogVW5pbml0aWFsaXplZCAqLwogICAgICAgaWYgKCF1c2FnZV90b2tlbikgY29udGludWU7CiAgICAgICB1c2FnZSA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRV9TSElGVDsKICAgICAgIHVzYWdlX2lkeCA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfU0hJRlQ7CiAgICAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgIHN3aXRjaCh1c2FnZSkgewoKICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ6CiAgICAgICAgICAgICAgIGlmKHVzYWdlX2lkeCA8IDggJiYgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9PSBwcmV0cmFuc2Zvcm1lZCkgewogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSBnbF9UZXhDb29yZFsldV0lcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5pbnB1dF9yZWdfbWFwW2ldLCByZWdfbWFzaywgdXNhZ2VfaWR4LCByZWdfbWFzayk7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0lcyA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmlucHV0X3JlZ19tYXBbaV0sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9DT0xPUjoKICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA9PSAwKQogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSB2ZWM0KGdsX0NvbG9yKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5pbnB1dF9yZWdfbWFwW2ldLCByZWdfbWFzaywgcmVnX21hc2spOwogICAgICAgICAgICAgICBlbHNlIGlmICh1c2FnZV9pZHggPT0gMSkKICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNChnbF9TZWNvbmRhcnlDb2xvciklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVmVydGV4IFNoYWRlciBTcGVjaWZpYyBDb2RlIGJlZ2lucyBoZXJlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIGFkZF9nbHNsX3Byb2dyYW1fZW50cnkoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYsIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmVudHJ5KSB7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmtleTsKCiAgICBrZXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKGdsc2xfcHJvZ3JhbV9rZXlfdCkpOwogICAga2V5LT52c2hhZGVyID0gZW50cnktPnZzaGFkZXI7CiAgICBrZXktPnBzaGFkZXIgPSBlbnRyeS0+cHNoYWRlcjsKCiAgICBoYXNoX3RhYmxlX3B1dChwcml2LT5nbHNsX3Byb2dyYW1fbG9va3VwLCBrZXksIGVudHJ5KTsKfQoKc3RhdGljIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmdldF9nbHNsX3Byb2dyYW1fZW50cnkoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYsCiAgICAgICAgR0xoYW5kbGVBUkIgdnNoYWRlciwgR0xoYW5kbGVBUkIgcHNoYWRlcikgewogICAgZ2xzbF9wcm9ncmFtX2tleV90IGtleTsKCiAgICBrZXkudnNoYWRlciA9IHZzaGFkZXI7CiAgICBrZXkucHNoYWRlciA9IHBzaGFkZXI7CgogICAgcmV0dXJuIChzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rICopaGFzaF90YWJsZV9nZXQocHJpdi0+Z2xzbF9wcm9ncmFtX2xvb2t1cCwgJmtleSk7Cn0KCnZvaWQgZGVsZXRlX2dsc2xfcHJvZ3JhbV9lbnRyeShzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqcHJpdiwgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rICplbnRyeSkgewogICAgZ2xzbF9wcm9ncmFtX2tleV90ICprZXk7CgogICAga2V5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihnbHNsX3Byb2dyYW1fa2V5X3QpKTsKICAgIGtleS0+dnNoYWRlciA9IGVudHJ5LT52c2hhZGVyOwogICAga2V5LT5wc2hhZGVyID0gZW50cnktPnBzaGFkZXI7CiAgICBoYXNoX3RhYmxlX3JlbW92ZShwcml2LT5nbHNsX3Byb2dyYW1fbG9va3VwLCBrZXkpOwoKICAgIEdMX0VYVENBTEwoZ2xEZWxldGVPYmplY3RBUkIoZW50cnktPnByb2dyYW1JZCkpOwogICAgaWYgKGVudHJ5LT52c2hhZGVyKSBsaXN0X3JlbW92ZSgmZW50cnktPnZzaGFkZXJfZW50cnkpOwogICAgaWYgKGVudHJ5LT5wc2hhZGVyKSBsaXN0X3JlbW92ZSgmZW50cnktPnBzaGFkZXJfZW50cnkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW50cnktPnZ1bmlmb3JtRl9sb2NhdGlvbnMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW50cnktPnB1bmlmb3JtRl9sb2NhdGlvbnMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW50cnkpOwp9CgpzdGF0aWMgdm9pZCBoYW5kbGVfcHMzX2lucHV0KFNIQURFUl9CVUZGRVIgKmJ1ZmZlciwgc2VtYW50aWMgKnNlbWFudGljc19pbiwgc2VtYW50aWMgKnNlbWFudGljc19vdXQsIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywgRFdPUkQgKm1hcCkgewogICAgdW5zaWduZWQgaW50IGksIGo7CiAgICBEV09SRCB1c2FnZV90b2tlbiwgdXNhZ2VfdG9rZW5fb3V0OwogICAgRFdPUkQgcmVnaXN0ZXJfdG9rZW4sIHJlZ2lzdGVyX3Rva2VuX291dDsKICAgIERXT1JEIHVzYWdlLCB1c2FnZV9pZHgsIHVzYWdlX291dCwgdXNhZ2VfaWR4X291dDsKICAgIERXT1JEICpzZXQ7CiAgICBEV09SRCBpbl9pZHg7CiAgICBEV09SRCBpbl9jb3VudCA9IEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQ7CiAgICBjaGFyIHJlZ19tYXNrWzZdLCByZWdfbWFza19vdXRbNl07CiAgICBjaGFyIGRlc3RpbmF0aW9uWzUwXTsKCiAgICBzZXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpzZXQpICogKGluX2NvdW50ICsgMikpOwoKICAgIGlmICghc2VtYW50aWNzX291dCkgewogICAgICAgIC8qIFNhdmUgZ2xfRnJvbnRDb2xvciAmIGdsX0Zyb250U2Vjb25kYXJ5Q29sb3IgYmVmb3JlIG92ZXJ3cml0aW5nIHRoZW0uICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjNCBmcm9udF9jb2xvciA9IGdsX0Zyb250Q29sb3I7XG4iKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IGZyb250X3NlY29uZGFyeV9jb2xvciA9IGdsX0Zyb250U2Vjb25kYXJ5Q29sb3I7XG4iKTsKICAgIH0KCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfUkVHX0lOUFVUOyBpKyspIHsKICAgICAgICB1c2FnZV90b2tlbiA9IHNlbWFudGljc19pbltpXS51c2FnZTsKICAgICAgICBpZiAoIXVzYWdlX3Rva2VuKSBjb250aW51ZTsKCiAgICAgICAgaW5faWR4ID0gbWFwW2ldOwogICAgICAgIGlmIChpbl9pZHggPj0gKGluX2NvdW50ICsgMikpIHsKICAgICAgICAgICAgRklYTUUoIk1vcmUgaW5wdXQgdmFyeWluZ3MgZGVjbGFyZWQgdGhhbiBzdXBwb3J0ZWQsIGV4cGVjdCBpc3N1ZXNcbiIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9IGVsc2UgaWYobWFwW2ldID09IC0xKSB7CiAgICAgICAgICAgIC8qIERlY2xhcmVkLCBidXQgbm90IHJlYWQgcmVnaXN0ZXIgKi8KICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaW5faWR4ID09IGluX2NvdW50KSB7CiAgICAgICAgICAgIHNwcmludGYoZGVzdGluYXRpb24sICJnbF9Gcm9udENvbG9yIik7CiAgICAgICAgfSBlbHNlIGlmIChpbl9pZHggPT0gaW5fY291bnQgKyAxKSB7CiAgICAgICAgICAgIHNwcmludGYoZGVzdGluYXRpb24sICJnbF9Gcm9udFNlY29uZGFyeUNvbG9yIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ByaW50ZihkZXN0aW5hdGlvbiwgIklOWyV1XSIsIGluX2lkeCk7CiAgICAgICAgfQoKICAgICAgICByZWdpc3Rlcl90b2tlbiA9IHNlbWFudGljc19pbltpXS5yZWc7CgogICAgICAgIHVzYWdlID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRV9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFX1NISUZUOwogICAgICAgIHVzYWdlX2lkeCA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfU0hJRlQ7CiAgICAgICAgc2V0W21hcFtpXV0gPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgICBpZighc2VtYW50aWNzX291dCkgewogICAgICAgICAgICBzd2l0Y2godXNhZ2UpIHsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9DT0xPUjoKICAgICAgICAgICAgICAgICAgICBpZiAodXNhZ2VfaWR4ID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSBmcm9udF9jb2xvciVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodXNhZ2VfaWR4ID09IDEpCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSBmcm9udF9zZWNvbmRhcnlfY29sb3IlcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLCByZWdfbWFzaywgcmVnX21hc2spOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMlcyA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1RFWENPT1JEOgogICAgICAgICAgICAgICAgICAgIGlmICh1c2FnZV9pZHggPCA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSBnbF9UZXhDb29yZFsldV0lcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLCByZWdfbWFzaywgdXNhZ2VfaWR4LCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMlcyA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9GT0c6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMlcyA9IHZlYzQoZ2xfRm9nRnJhZ0Nvb3JkLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbiwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBCT09MIGZvdW5kID0gRkFMU0U7CiAgICAgICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9SRUdfT1VUUFVUOyBqKyspIHsKICAgICAgICAgICAgICAgIHVzYWdlX3Rva2VuX291dCA9IHNlbWFudGljc19vdXRbal0udXNhZ2U7CiAgICAgICAgICAgICAgICBpZiAoIXVzYWdlX3Rva2VuX291dCkgY29udGludWU7CiAgICAgICAgICAgICAgICByZWdpc3Rlcl90b2tlbl9vdXQgPSBzZW1hbnRpY3Nfb3V0W2pdLnJlZzsKCiAgICAgICAgICAgICAgICB1c2FnZV9vdXQgPSAodXNhZ2VfdG9rZW5fb3V0ICYgV0lORUQzRFNQX0RDTF9VU0FHRV9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFX1NISUZUOwogICAgICAgICAgICAgICAgdXNhZ2VfaWR4X291dCA9ICh1c2FnZV90b2tlbl9vdXQgJiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRUlOREVYX1NISUZUOwogICAgICAgICAgICAgICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2socmVnaXN0ZXJfdG9rZW5fb3V0LCByZWdfbWFza19vdXQpOwoKICAgICAgICAgICAgICAgIGlmKHVzYWdlID09IHVzYWdlX291dCAmJgogICAgICAgICAgICAgICAgICAgdXNhZ2VfaWR4ID09IHVzYWdlX2lkeF9vdXQpIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyVzID0gT1VUWyV1XSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbiwgcmVnX21hc2ssIGosIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIWZvdW5kKSB7CiAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyVzID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogVGhpcyBpcyBzb2xlbHkgdG8gbWFrZSB0aGUgY29tcGlsZXIgLyBsaW5rZXIgaGFwcHkgYW5kIGF2b2lkIHdhcm5pbmcgYWJvdXQgdW5kZWZpbmVkCiAgICAgKiB2YXJ5aW5ncy4gSXQgc2hvdWxkbid0IHJlc3VsdCBpbiBhbnkgcmVhbCBjb2RlIGV4ZWN1dGVkIG9uIHRoZSBHUFUsIHNpbmNlIGFsbCByZWFkCiAgICAgKiBpbnB1dCB2YXJ5aW5ncyBhcmUgYXNzaWduZWQgYWJvdmUsIGlmIHRoZSBvcHRpbWl6ZXIgd29ya3MgcHJvcGVybHkuCiAgICAgKi8KICAgIGZvcihpID0gMDsgaSA8IGluX2NvdW50ICsgMjsgaSsrKSB7CiAgICAgICAgaWYoc2V0W2ldICE9IFdJTkVEM0RTUF9XUklURU1BU0tfQUxMKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBzaXplID0gMDsKICAgICAgICAgICAgbWVtc2V0KHJlZ19tYXNrLCAwLCBzaXplb2YocmVnX21hc2spKTsKICAgICAgICAgICAgaWYoIShzZXRbaV0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzApKSB7CiAgICAgICAgICAgICAgICByZWdfbWFza1tzaXplXSA9ICd4JzsKICAgICAgICAgICAgICAgIHNpemUrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighKHNldFtpXSAmIFdJTkVEM0RTUF9XUklURU1BU0tfMSkpIHsKICAgICAgICAgICAgICAgIHJlZ19tYXNrW3NpemVdID0gJ3knOwogICAgICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCEoc2V0W2ldICYgV0lORUQzRFNQX1dSSVRFTUFTS18yKSkgewogICAgICAgICAgICAgICAgcmVnX21hc2tbc2l6ZV0gPSAneic7CiAgICAgICAgICAgICAgICBzaXplKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIShzZXRbaV0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzMpKSB7CiAgICAgICAgICAgICAgICByZWdfbWFza1tzaXplXSA9ICd3JzsKICAgICAgICAgICAgICAgIHNpemUrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPT0gaW5fY291bnQpIHsKICAgICAgICAgICAgICAgIHNwcmludGYoZGVzdGluYXRpb24sICJnbF9Gcm9udENvbG9yIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA9PSBpbl9jb3VudCArIDEpIHsKICAgICAgICAgICAgICAgIHNwcmludGYoZGVzdGluYXRpb24sICJnbF9Gcm9udFNlY29uZGFyeUNvbG9yIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKGRlc3RpbmF0aW9uLCAiSU5bJXVdIiwgaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzaXplID09IDEpIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLiVzID0gMC4wO1xuIiwgZGVzdGluYXRpb24sIHJlZ19tYXNrKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLiVzID0gdmVjJXUoMC4wKTtcbiIsIGRlc3RpbmF0aW9uLCByZWdfbWFzaywgc2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2V0KTsKfQoKc3RhdGljIEdMaGFuZGxlQVJCIGdlbmVyYXRlX3BhcmFtX3Jlb3JkZXJfZnVuY3Rpb24oSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKnZlcnRleHNoYWRlciwKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyICpwaXhlbHNoYWRlciwKICAgICAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8pIHsKICAgIEdMaGFuZGxlQVJCIHJldCA9IDA7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKnZzID0gKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqKSB2ZXJ0ZXhzaGFkZXI7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcGl4ZWxzaGFkZXI7CiAgICBEV09SRCB2c19tYWpvciA9IHZzID8gV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKHZzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA6IDA7CiAgICBEV09SRCBwc19tYWpvciA9IHBzID8gV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKHBzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA6IDA7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIFNIQURFUl9CVUZGRVIgYnVmZmVyOwogICAgRFdPUkQgdXNhZ2VfdG9rZW47CiAgICBEV09SRCByZWdpc3Rlcl90b2tlbjsKICAgIERXT1JEIHVzYWdlLCB1c2FnZV9pZHgsIHdyaXRlbWFzazsKICAgIGNoYXIgcmVnX21hc2tbNl07CiAgICBzZW1hbnRpYyAqc2VtYW50aWNzX291dCwgKnNlbWFudGljc19pbjsKCiAgICBidWZmZXIuYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFNIQURFUl9QR01TSVpFKTsKICAgIGJ1ZmZlci5ic2l6ZSA9IDA7CiAgICBidWZmZXIubGluZU5vID0gMDsKICAgIGJ1ZmZlci5uZXdsaW5lID0gVFJVRTsKCiAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAiI3ZlcnNpb24gMTIwXG4iKTsKCiAgICBpZih2c19tYWpvciA8IDMgJiYgcHNfbWFqb3IgPCAzKSB7CiAgICAgICAgLyogVGhhdCBvbmUgaXMgZWFzeTogVGhlIHZlcnRleCBzaGFkZXIgd3JpdGVzIHRvIHRoZSBidWlsdGluIHZhcnlpbmdzLCB0aGUgcGl4ZWwgc2hhZGVyIHJlYWRzIGZyb20gdGhlbS4KICAgICAgICAgKiBUYWtlIGNhcmUgYWJvdXQgdGhlIHRleGNvb3JkIC53IGZpeHVwIHRob3VnaCBpZiB3ZSdyZSB1c2luZyB0aGUgZml4ZWQgZnVuY3Rpb24gZnJhZ21lbnQgcGlwZWxpbmUKICAgICAgICAgKi8KICAgICAgICBpZigoR0xJTkZPX0xPQ0FUSU9OKS5zZXRfdGV4Y29vcmRfdyAmJiBwc19tYWpvciA9PSAwICYmIHZzX21ham9yID4gMCkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHtcbiIpOwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBtaW4oOCwgTUFYX1JFR19URVhDUkQpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKHZzLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnRleGNvb3JkX21hc2tbaV0gIT0gMCAmJgogICAgICAgICAgICAgICAgICAgdnMtPmJhc2VTaGFkZXIucmVnX21hcHMudGV4Y29vcmRfbWFza1tpXSAhPSBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9UZXhDb29yZFsldV0udyA9IDEuMDtcbiIsIGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ9XG4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHsgLyogZG8gbm90aGluZyAqLyB9XG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYocHNfbWFqb3IgPCAzICYmIHZzX21ham9yID49IDMpIHsKICAgICAgICAvKiBUaGUgdmVydGV4IHNoYWRlciB3cml0ZXMgdG8gaXRzIG93biB2YXJ5aW5ncywgdGhlIHBpeGVsIHNoYWRlciBuZWVkcyB0aGVtIGluIHRoZSBidWlsdGluIG9uZXMgKi8KICAgICAgICBzZW1hbnRpY3Nfb3V0ID0gdnMtPnNlbWFudGljc19vdXQ7CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ2b2lkIG9yZGVyX3BzX2lucHV0KGluIHZlYzQgT1VUWyV1XSkge1xuIiwgTUFYX1JFR19PVVRQVVQpOwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9SRUdfT1VUUFVUOyBpKyspIHsKICAgICAgICAgICAgdXNhZ2VfdG9rZW4gPSBzZW1hbnRpY3Nfb3V0W2ldLnVzYWdlOwogICAgICAgICAgICBpZiAoIXVzYWdlX3Rva2VuKSBjb250aW51ZTsKICAgICAgICAgICAgcmVnaXN0ZXJfdG9rZW4gPSBzZW1hbnRpY3Nfb3V0W2ldLnJlZzsKCiAgICAgICAgICAgIHVzYWdlID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRV9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFX1NISUZUOwogICAgICAgICAgICB1c2FnZV9pZHggPSAodXNhZ2VfdG9rZW4gJiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRUlOREVYX1NISUZUOwogICAgICAgICAgICB3cml0ZW1hc2sgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgICAgICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfQ09MT1I6CiAgICAgICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAiZ2xfRnJvbnRDb2xvciVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh1c2FnZV9pZHggPT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX0Zyb250U2Vjb25kYXJ5Q29sb3IlcyA9IE9VVFsldV0lcztcbiIsIHJlZ19tYXNrLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9Qb3NpdGlvbiVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA8IDgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIShHTElORk9fTE9DQVRJT04pLnNldF90ZXhjb29yZF93IHx8IHBzX21ham9yID4gMCkgd3JpdGVtYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9UZXhDb29yZFsldV0lcyA9IE9VVFsldV0lcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2FnZV9pZHgsIHJlZ19tYXNrLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCEod3JpdGVtYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1RleENvb3JkWyV1XS53ID0gMS4wO1xuIiwgdXNhZ2VfaWR4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfUFNJWkU6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1BvaW50U2l6ZSA9IE9VVFsldV0ueDtcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9GT0c6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX0ZvZ0ZyYWdDb29yZCA9IE9VVFsldV0uJWM7XG4iLCBpLCByZWdfbWFza1sxXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAifVxuIik7CgogICAgfSBlbHNlIGlmKHBzX21ham9yID49IDMgJiYgdnNfbWFqb3IgPj0gMykgewogICAgICAgIHNlbWFudGljc19vdXQgPSB2cy0+c2VtYW50aWNzX291dDsKICAgICAgICBzZW1hbnRpY3NfaW4gPSBwcy0+c2VtYW50aWNzX2luOwoKICAgICAgICAvKiBUaGlzIG9uZSBpcyB0cmlja3k6IGEgMy4wIHBpeGVsIHNoYWRlciByZWFkcyBmcm9tIGEgMy4wIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidmFyeWluZyB2ZWM0IElOWyV1XTtcbiIsIEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ2b2lkIG9yZGVyX3BzX2lucHV0KGluIHZlYzQgT1VUWyV1XSkge1xuIiwgTUFYX1JFR19PVVRQVVQpOwoKICAgICAgICAvKiBGaXJzdCwgc29ydCBvdXQgcG9zaXRpb24gYW5kIHBvaW50IHNpemUuIFRob3NlIGFyZSBub3QgcGFzc2VkIHRvIHRoZSBwaXhlbCBzaGFkZXIgKi8KICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfUkVHX09VVFBVVDsgaSsrKSB7CiAgICAgICAgICAgIHVzYWdlX3Rva2VuID0gc2VtYW50aWNzX291dFtpXS51c2FnZTsKICAgICAgICAgICAgaWYgKCF1c2FnZV90b2tlbikgY29udGludWU7CiAgICAgICAgICAgIHJlZ2lzdGVyX3Rva2VuID0gc2VtYW50aWNzX291dFtpXS5yZWc7CgogICAgICAgICAgICB1c2FnZSA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRV9TSElGVDsKICAgICAgICAgICAgdXNhZ2VfaWR4ID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRUlOREVYX01BU0spID4+IFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9TSElGVDsKICAgICAgICAgICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2socmVnaXN0ZXJfdG9rZW4sIHJlZ19tYXNrKTsKCiAgICAgICAgICAgIHN3aXRjaCh1c2FnZSkgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9Qb3NpdGlvbiVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfUFNJWkU6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1BvaW50U2l6ZSA9IE9VVFsldV0ueDtcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIFRoZW4sIGZpeCB0aGUgcGl4ZWwgc2hhZGVyIGlucHV0ICovCiAgICAgICAgaGFuZGxlX3BzM19pbnB1dCgmYnVmZmVyLCBzZW1hbnRpY3NfaW4sIHNlbWFudGljc19vdXQsIGdsX2luZm8sIHBzLT5pbnB1dF9yZWdfbWFwKTsKCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgIn1cbiIpOwogICAgfSBlbHNlIGlmKHBzX21ham9yID49IDMgJiYgdnNfbWFqb3IgPCAzKSB7CiAgICAgICAgc2VtYW50aWNzX2luID0gcHMtPnNlbWFudGljc19pbjsKCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgInZhcnlpbmcgdmVjNCBJTlsldV07XG4iLCBHTF9MSU1JVFMoZ2xzbF92YXJ5aW5ncykgLyA0KTsKICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHtcbiIpOwogICAgICAgIC8qIFRoZSB2ZXJ0ZXggc2hhZGVyIHdyb3RlIHRvIHRoZSBidWlsdGluIHZhcnlpbmdzLiBUaGVyZSBpcyBubyBuZWVkIHRvIGZpZ3VyZSBvdXQgcG9zaXRpb24gYW5kCiAgICAgICAgICogcG9pbnQgc2l6ZSwgYnV0IHdlIGRlcGVuZCBvbiB0aGUgb3B0aW1pemVycyBraW5kbmVzcyB0byBmaW5kIG91dCB0aGF0IHRoZSBwaXhlbCBzaGFkZXIgZG9lc24ndAogICAgICAgICAqIHJlYWQgZ2xfVGV4Q29vcmQgYW5kIGdsX0NvbG9yWCwgb3RoZXJ3aXNlIHdlJ2xsIHJ1biBvdXQgb2YgdmFyeWluZ3MKICAgICAgICAgKi8KICAgICAgICBoYW5kbGVfcHMzX2lucHV0KCZidWZmZXIsIHNlbWFudGljc19pbiwgTlVMTCwgZ2xfaW5mbywgcHMtPmlucHV0X3JlZ19tYXApOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ9XG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCBhbmQgcGl4ZWwgc2hhZGVyIHZlcnNpb24gY29uZGl0aW9uOiB2czogJWQsIHBzOiAlZFxuIiwgdnNfbWFqb3IsIHBzX21ham9yKTsKICAgIH0KCiAgICByZXQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlU2hhZGVyT2JqZWN0QVJCKEdMX1ZFUlRFWF9TSEFERVJfQVJCKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xDcmVhdGVTaGFkZXJPYmplY3RBUkIoR0xfVkVSVEVYX1NIQURFUl9BUkIpIik7CiAgICBHTF9FWFRDQUxMKGdsU2hhZGVyU291cmNlQVJCKHJldCwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLmJ1ZmZlciwgTlVMTCkpOwogICAgY2hlY2tHTGNhbGwoImdsU2hhZGVyU291cmNlQVJCKHJldCwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLmJ1ZmZlciwgTlVMTCkiKTsKICAgIEdMX0VYVENBTEwoZ2xDb21waWxlU2hhZGVyQVJCKHJldCkpOwogICAgY2hlY2tHTGNhbGwoImdsQ29tcGlsZVNoYWRlckFSQihyZXQpIik7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyLmJ1ZmZlcik7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBoYXJkY29kZV9sb2NhbF9jb25zdGFudHMoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqc2hhZGVyLCBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8sIEdMaGFuZGxlQVJCIHByb2dyYW1JZCwgY2hhciBwcmVmaXgpIHsKICAgIGxvY2FsX2NvbnN0YW50KiBsY29uc3Q7CiAgICBHTHVpbnQgdG1wX2xvYzsKICAgIGZsb2F0ICp2YWx1ZTsKICAgIGNoYXIgZ2xzbF9uYW1lWzhdOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmc2hhZGVyLT5iYXNlU2hhZGVyLmNvbnN0YW50c0YsIGxvY2FsX2NvbnN0YW50LCBlbnRyeSkgewogICAgICAgIHZhbHVlID0gKGZsb2F0ICopIGxjb25zdC0+dmFsdWU7CiAgICAgICAgc25wcmludGYoZ2xzbF9uYW1lLCBzaXplb2YoZ2xzbF9uYW1lKSwgIiVjTEMldSIsIHByZWZpeCwgbGNvbnN0LT5pZHgpOwogICAgICAgIHRtcF9sb2MgPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgZ2xzbF9uYW1lKSk7CiAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIodG1wX2xvYywgMSwgdmFsdWUpKTsKICAgIH0KICAgIGNoZWNrR0xjYWxsKCJIYXJkY29kaW5nIGxvY2FsIGNvbnN0YW50c1xuIik7Cn0KCi8qKiBTZXRzIHRoZSBHTFNMIHByb2dyYW0gSUQgZm9yIHRoZSBnaXZlbiBwaXhlbCBhbmQgdmVydGV4IHNoYWRlciBjb21iaW5hdGlvbi4KICogSXQgc2V0cyB0aGUgcHJvZ3JhbUlkIG9uIHRoZSBjdXJyZW50IFN0YXRlQmxvY2sgKGJlY2F1c2UgaXQgc2hvdWxkIGJlIGNhbGxlZAogKiBpbnNpZGUgb2YgdGhlIERyYXdQcmltaXRpdmUoKSBwYXJ0IG9mIHRoZSByZW5kZXIgbG9vcCkuCiAqCiAqIElmIGEgcHJvZ3JhbSBmb3IgdGhlIGdpdmVuIGNvbWJpbmF0aW9uIGRvZXMgbm90IGV4aXN0LCBjcmVhdGUgb25lLCBhbmQgc3RvcmUKICogdGhlIHByb2dyYW0gaW4gdGhlIGhhc2ggdGFibGUuICBJZiBpdCBjcmVhdGVzIGEgcHJvZ3JhbSwgaXQgd2lsbCBsaW5rIHRoZQogKiBnaXZlbiBvYmplY3RzLCB0b28uCiAqLwpzdGF0aWMgdm9pZCBzZXRfZ2xzbF9zaGFkZXJfcHJvZ3JhbShJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgdXNlX3BzLCBCT09MIHVzZV92cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzICAgICAgICAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqcHJpdiAgICAgICAgICA9IChzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqKVRoaXMtPnNoYWRlcl9wcml2OwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvICAgICAgICAgICAgICAgPSAmVGhpcy0+YWRhcHRlci0+Z2xfaW5mbzsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXIgICpwc2hhZGVyICAgICAgICAgID0gVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlciAqdnNoYWRlciAgICAgICAgICA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKICAgIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmVudHJ5ICAgID0gTlVMTDsKICAgIEdMaGFuZGxlQVJCIHByb2dyYW1JZCAgICAgICAgICAgICAgICAgID0gMDsKICAgIEdMaGFuZGxlQVJCIHJlb3JkZXJfc2hhZGVyX2lkICAgICAgICAgID0gMDsKICAgIGludCBpOwogICAgY2hhciBnbHNsX25hbWVbOF07CgogICAgR0xoYW5kbGVBUkIgdnNoYWRlcl9pZCA9IHVzZV92cyA/ICgoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopdnNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQgOiAwOwogICAgR0xoYW5kbGVBUkIgcHNoYWRlcl9pZCA9IHVzZV9wcyA/ICgoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopcHNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQgOiAwOwogICAgZW50cnkgPSBnZXRfZ2xzbF9wcm9ncmFtX2VudHJ5KHByaXYsIHZzaGFkZXJfaWQsIHBzaGFkZXJfaWQpOwogICAgaWYgKGVudHJ5KSB7CiAgICAgICAgcHJpdi0+Z2xzbF9wcm9ncmFtID0gZW50cnk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIElmIHdlIGdldCB0byB0aGlzIHBvaW50LCB0aGVuIG5vIG1hdGNoaW5nIHByb2dyYW0gZXhpc3RzLCBzbyB3ZSBjcmVhdGUgb25lICovCiAgICBwcm9ncmFtSWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlUHJvZ3JhbU9iamVjdEFSQigpKTsKICAgIFRSQUNFKCJDcmVhdGVkIG5ldyBHTFNMIHNoYWRlciBwcm9ncmFtICV1XG4iLCBwcm9ncmFtSWQpOwoKICAgIC8qIENyZWF0ZSB0aGUgZW50cnkgKi8KICAgIGVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rKSk7CiAgICBlbnRyeS0+cHJvZ3JhbUlkID0gcHJvZ3JhbUlkOwogICAgZW50cnktPnZzaGFkZXIgPSB2c2hhZGVyX2lkOwogICAgZW50cnktPnBzaGFkZXIgPSBwc2hhZGVyX2lkOwogICAgLyogQWRkIHRoZSBoYXNoIHRhYmxlIGVudHJ5ICovCiAgICBhZGRfZ2xzbF9wcm9ncmFtX2VudHJ5KHByaXYsIGVudHJ5KTsKCiAgICAvKiBTZXQgdGhlIGN1cnJlbnQgcHJvZ3JhbSAqLwogICAgcHJpdi0+Z2xzbF9wcm9ncmFtID0gZW50cnk7CgogICAgLyogQXR0YWNoIEdMU0wgdnNoYWRlciAqLwogICAgaWYgKHZzaGFkZXJfaWQpIHsKICAgICAgICBpbnQgbWF4X2F0dHJpYnMgPSAxNjsgICAvKiBUT0RPOiBXaWxsIHRoaXMgYWx3YXlzIGJlIHRoZSBjYXNlPyBJdCBpcyBhdCB0aGUgbW9tZW50Li4uICovCiAgICAgICAgY2hhciB0bXBfbmFtZVsxMF07CgogICAgICAgIHJlb3JkZXJfc2hhZGVyX2lkID0gZ2VuZXJhdGVfcGFyYW1fcmVvcmRlcl9mdW5jdGlvbih2c2hhZGVyLCBwc2hhZGVyLCBnbF9pbmZvKTsKICAgICAgICBUUkFDRSgiQXR0YWNoaW5nIEdMU0wgc2hhZGVyIG9iamVjdCAldSB0byBwcm9ncmFtICV1XG4iLCByZW9yZGVyX3NoYWRlcl9pZCwgcHJvZ3JhbUlkKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQXR0YWNoT2JqZWN0QVJCKHByb2dyYW1JZCwgcmVvcmRlcl9zaGFkZXJfaWQpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xBdHRhY2hPYmplY3RBUkIiKTsKICAgICAgICAvKiBGbGFnIHRoZSByZW9yZGVyIGZ1bmN0aW9uIGZvciBkZWxldGlvbiwgdGhlbiBpdCB3aWxsIGJlIGZyZWVkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgcHJvZ3JhbQogICAgICAgICAqIGlzIGRlc3Ryb3llZAogICAgICAgICAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVPYmplY3RBUkIocmVvcmRlcl9zaGFkZXJfaWQpKTsKCiAgICAgICAgVFJBQ0UoIkF0dGFjaGluZyBHTFNMIHNoYWRlciBvYmplY3QgJXUgdG8gcHJvZ3JhbSAldVxuIiwgdnNoYWRlcl9pZCwgcHJvZ3JhbUlkKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQXR0YWNoT2JqZWN0QVJCKHByb2dyYW1JZCwgdnNoYWRlcl9pZCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEF0dGFjaE9iamVjdEFSQiIpOwoKICAgICAgICAvKiBCaW5kIHZlcnRleCBhdHRyaWJ1dGVzIHRvIGEgY29ycmVzcG9uZGluZyBpbmRleCBudW1iZXIgdG8gbWF0Y2gKICAgICAgICAgKiB0aGUgc2FtZSBpbmRleCBudW1iZXJzIGFzIEFSQl92ZXJ0ZXhfcHJvZ3JhbXMgKG1ha2VzIGxvYWRpbmcKICAgICAgICAgKiB2ZXJ0ZXggYXR0cmlidXRlcyBzaW1wbGVyKS4gIFdpdGggdGhpcyBtZXRob2QsIHdlIGNhbiB1c2UgdGhlCiAgICAgICAgICogZXhhY3Qgc2FtZSBjb2RlIHRvIGxvYWQgdGhlIGF0dHJpYnV0ZXMgbGF0ZXIgZm9yIGJvdGggQVJCIGFuZAogICAgICAgICAqIEdMU0wgc2hhZGVycy4KICAgICAgICAgKgogICAgICAgICAqIFdlIGhhdmUgdG8gZG8gdGhpcyBoZXJlIGJlY2F1c2Ugd2UgbmVlZCB0byBrbm93IHRoZSBQcm9ncmFtIElECiAgICAgICAgICogaW4gb3JkZXIgdG8gbWFrZSB0aGUgYmluZGluZ3Mgd29yaywgYW5kIGl0IGhhcyB0byBiZSBkb25lIHByaW9yCiAgICAgICAgICogdG8gbGlua2luZyB0aGUgR0xTTCBwcm9ncmFtLiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBtYXhfYXR0cmliczsgKytpKSB7CiAgICAgICAgICAgIGlmICgoKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKXZzaGFkZXIpLT5iYXNlU2hhZGVyLnJlZ19tYXBzLmF0dHJpYnV0ZXNbaV0pIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKHRtcF9uYW1lLCBzaXplb2YodG1wX25hbWUpLCAiYXR0cmliJWkiLCBpKTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQXR0cmliTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBpLCB0bXBfbmFtZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRBdHRyaWJMb2NhdGlvbkFSQiIpOwoKICAgICAgICBsaXN0X2FkZF9oZWFkKCYoKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKil2c2hhZGVyKS0+YmFzZVNoYWRlci5saW5rZWRfcHJvZ3JhbXMsICZlbnRyeS0+dnNoYWRlcl9lbnRyeSk7CiAgICB9CgogICAgLyogQXR0YWNoIEdMU0wgcHNoYWRlciAqLwogICAgaWYgKHBzaGFkZXJfaWQpIHsKICAgICAgICBUUkFDRSgiQXR0YWNoaW5nIEdMU0wgc2hhZGVyIG9iamVjdCAldSB0byBwcm9ncmFtICV1XG4iLCBwc2hhZGVyX2lkLCBwcm9ncmFtSWQpOwogICAgICAgIEdMX0VYVENBTEwoZ2xBdHRhY2hPYmplY3RBUkIocHJvZ3JhbUlkLCBwc2hhZGVyX2lkKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQXR0YWNoT2JqZWN0QVJCIik7CgogICAgICAgIGxpc3RfYWRkX2hlYWQoJigoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKXBzaGFkZXIpLT5iYXNlU2hhZGVyLmxpbmtlZF9wcm9ncmFtcywgJmVudHJ5LT5wc2hhZGVyX2VudHJ5KTsKICAgIH0KCiAgICAvKiBMaW5rIHRoZSBwcm9ncmFtICovCiAgICBUUkFDRSgiTGlua2luZyBHTFNMIHNoYWRlciBwcm9ncmFtICV1XG4iLCBwcm9ncmFtSWQpOwogICAgR0xfRVhUQ0FMTChnbExpbmtQcm9ncmFtQVJCKHByb2dyYW1JZCkpOwogICAgcHJpbnRfZ2xzbF9pbmZvX2xvZygmR0xJTkZPX0xPQ0FUSU9OLCBwcm9ncmFtSWQpOwoKICAgIGVudHJ5LT52dW5pZm9ybUZfbG9jYXRpb25zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihHTGhhbmRsZUFSQikgKiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7ICsraSkgewogICAgICAgIHNucHJpbnRmKGdsc2xfbmFtZSwgc2l6ZW9mKGdsc2xfbmFtZSksICJWQ1slaV0iLCBpKTsKICAgICAgICBlbnRyeS0+dnVuaWZvcm1GX2xvY2F0aW9uc1tpXSA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBnbHNsX25hbWUpKTsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgKytpKSB7CiAgICAgICAgc25wcmludGYoZ2xzbF9uYW1lLCBzaXplb2YoZ2xzbF9uYW1lKSwgIlZJWyVpXSIsIGkpOwogICAgICAgIGVudHJ5LT52dW5pZm9ybUlfbG9jYXRpb25zW2ldID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIGdsc2xfbmFtZSkpOwogICAgfQogICAgZW50cnktPnB1bmlmb3JtRl9sb2NhdGlvbnMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKEdMaGFuZGxlQVJCKSAqIEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKTsKICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKTsgKytpKSB7CiAgICAgICAgc25wcmludGYoZ2xzbF9uYW1lLCBzaXplb2YoZ2xzbF9uYW1lKSwgIlBDWyVpXSIsIGkpOwogICAgICAgIGVudHJ5LT5wdW5pZm9ybUZfbG9jYXRpb25zW2ldID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIGdsc2xfbmFtZSkpOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpIHsKICAgICAgICBzbnByaW50ZihnbHNsX25hbWUsIHNpemVvZihnbHNsX25hbWUpLCAiUElbJWldIiwgaSk7CiAgICAgICAgZW50cnktPnB1bmlmb3JtSV9sb2NhdGlvbnNbaV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgZ2xzbF9uYW1lKSk7CiAgICB9CgogICAgaWYocHNoYWRlcikgewogICAgICAgIGZvcihpID0gMDsgaSA8ICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKXBzaGFkZXIpLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICAgICAgY2hhciBuYW1lWzMyXTsKICAgICAgICAgICAgc3ByaW50ZihuYW1lLCAiYnVtcGVudm1hdCVkIiwgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopcHNoYWRlciktPmJ1bXBlbnZtYXRjb25zdFtpXS50ZXh1bml0KTsKICAgICAgICAgICAgZW50cnktPmJ1bXBlbnZtYXRfbG9jYXRpb25baV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgbmFtZSkpOwogICAgICAgICAgICBzcHJpbnRmKG5hbWUsICJsdW1pbmFuY2VzY2FsZSVkIiwgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopcHNoYWRlciktPmx1bWluYW5jZWNvbnN0W2ldLnRleHVuaXQpOwogICAgICAgICAgICBlbnRyeS0+bHVtaW5hbmNlc2NhbGVfbG9jYXRpb25baV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgbmFtZSkpOwogICAgICAgICAgICBzcHJpbnRmKG5hbWUsICJsdW1pbmFuY2VvZmZzZXQlZCIsICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKXBzaGFkZXIpLT5sdW1pbmFuY2Vjb25zdFtpXS50ZXh1bml0KTsKICAgICAgICAgICAgZW50cnktPmx1bWluYW5jZW9mZnNldF9sb2NhdGlvbltpXSA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBuYW1lKSk7CiAgICAgICAgfQogICAgfQoKCiAgICBlbnRyeS0+cG9zRml4dXBfbG9jYXRpb24gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgInBvc0ZpeHVwIikpOwogICAgZW50cnktPnNyZ2JfY29tcGFyaXNvbl9sb2NhdGlvbiA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCAic3JnYl9jb21wYXJpc29uIikpOwogICAgZW50cnktPnNyZ2JfbXVsX2xvd19sb2NhdGlvbiA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCAic3JnYl9tdWxfbG93IikpOwogICAgZW50cnktPnljb3JyZWN0aW9uX2xvY2F0aW9uID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsICJ5Y29ycmVjdGlvbiIpKTsKICAgIGNoZWNrR0xjYWxsKCJGaW5kIGdsc2wgcHJvZ3JhbSB1bmlmb3JtIGxvY2F0aW9ucyIpOwoKICAgIGlmIChwc2hhZGVyICYmIFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUigoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopcHNoYWRlciktPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pID49IDMKICAgICAgICAgICAgJiYgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKXBzaGFkZXIpLT5kZWNsYXJlZF9pbl9jb3VudCA+IEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpIHsKICAgICAgICBUUkFDRSgiU2hhZGVyICVkIG5lZWRzIHZlcnRleCBjb2xvciBjbGFtcGluZyBkaXNhYmxlZFxuIiwgcHJvZ3JhbUlkKTsKICAgICAgICBlbnRyeS0+dmVydGV4X2NvbG9yX2NsYW1wID0gR0xfRkFMU0U7CiAgICB9IGVsc2UgewogICAgICAgIGVudHJ5LT52ZXJ0ZXhfY29sb3JfY2xhbXAgPSBHTF9GSVhFRF9PTkxZX0FSQjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIHNoYWRlciB0byBhbGxvdyB1bmlmb3JtIGxvYWRpbmcgb24gaXQgKi8KICAgIEdMX0VYVENBTEwoZ2xVc2VQcm9ncmFtT2JqZWN0QVJCKHByb2dyYW1JZCkpOwogICAgY2hlY2tHTGNhbGwoImdsVXNlUHJvZ3JhbU9iamVjdEFSQihwcm9ncmFtSWQpIik7CgogICAgLyogTG9hZCB0aGUgdmVydGV4IGFuZCBwaXhlbCBzYW1wbGVycyBub3cuIFRoZSBmdW5jdGlvbiB0aGF0IGZpbmRzIHRoZSBtYXBwaW5ncyBtYWtlcyBzdXJlCiAgICAgKiB0aGF0IGl0IHN0YXlzIHRoZSBzYW1lIGZvciBlYWNoIHZlcnRleHNoYWRlci1waXhlbHNoYWRlciBwYWlyKD1saW5rZWQgZ2xzbCBwcm9ncmFtKS4gSWYKICAgICAqIGEgcHNoYWRlciB3aXRoIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lIGlzIHVzZWQgdGhlcmUgYXJlIG5vIHZlcnRleCBzYW1wbGVycywgYW5kIGlmIGEKICAgICAqIHZlcnRleCBzaGFkZXIgd2l0aCBmaXhlZCBmdW5jdGlvbiBwaXhlbCBwcm9jZXNzaW5nIGlzIHVzZWQgd2UgbWFrZSBzdXJlIHRoYXQgdGhlIGNhcmQKICAgICAqIHN1cHBvcnRzIGVub3VnaCBzYW1wbGVycyB0byBhbGxvdyB0aGUgbWF4IG51bWJlciBvZiB2ZXJ0ZXggc2FtcGxlcnMgd2l0aCBhbGwgcG9zc2libGUKICAgICAqIGZpeGVkIGZ1bmN0aW9uIGZyYWdtZW50IHByb2Nlc3Npbmcgc2V0dXBzLiBTbyBvbmNlIHRoZSBwcm9ncmFtIGlzIGxpbmtlZCB0aGVzZSBzYW1wbGVycwogICAgICogd29uJ3QgY2hhbmdlLgogICAgICovCiAgICBpZih2c2hhZGVyX2lkKSB7CiAgICAgICAgLyogTG9hZCB2ZXJ0ZXggc2hhZGVyIHNhbXBsZXJzICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF92c2FtcGxlcnMoZ2xfaW5mbywgKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+c3RhdGVCbG9jaywgcHJvZ3JhbUlkKTsKICAgIH0KICAgIGlmKHBzaGFkZXJfaWQpIHsKICAgICAgICAvKiBMb2FkIHBpeGVsIHNoYWRlciBzYW1wbGVycyAqLwogICAgICAgIHNoYWRlcl9nbHNsX2xvYWRfcHNhbXBsZXJzKGdsX2luZm8sIChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnN0YXRlQmxvY2ssIHByb2dyYW1JZCk7CiAgICB9CgogICAgLyogSWYgdGhlIGxvY2FsIGNvbnN0YW50cyBkbyBub3QgaGF2ZSB0byBiZSBsb2FkZWQgd2l0aCB0aGUgZW52aXJvbm1lbnQgY29uc3RhbnRzLAogICAgICogbG9hZCB0aGVtIG5vdyB0byBoYXZlIHRoZW0gaGFyZGNvZGVkIGluIHRoZSBHTFNMIHByb2dyYW0uIFRoaXMgc2F2ZXMgc29tZSBDUFUgY3ljbGVzCiAgICAgKiBsYXRlcgogICAgICovCiAgICBpZihwc2hhZGVyICYmICEoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKilwc2hhZGVyKS0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YpIHsKICAgICAgICBoYXJkY29kZV9sb2NhbF9jb25zdGFudHMoKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKikgcHNoYWRlciwgZ2xfaW5mbywgcHJvZ3JhbUlkLCAnUCcpOwogICAgfQogICAgaWYodnNoYWRlciAmJiAhKChJV2luZUQzRFZlcnRleFNoYWRlckltcGwqKXZzaGFkZXIpLT5iYXNlU2hhZGVyLmxvYWRfbG9jYWxfY29uc3RzRikgewogICAgICAgIGhhcmRjb2RlX2xvY2FsX2NvbnN0YW50cygoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKSB2c2hhZGVyLCBnbF9pbmZvLCBwcm9ncmFtSWQsICdWJyk7CiAgICB9Cn0KCnN0YXRpYyBHTGhhbmRsZUFSQiBjcmVhdGVfZ2xzbF9ibHRfc2hhZGVyKFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbykgewogICAgR0xoYW5kbGVBUkIgcHJvZ3JhbV9pZDsKICAgIEdMaGFuZGxlQVJCIHZzaGFkZXJfaWQsIHBzaGFkZXJfaWQ7CiAgICBjb25zdCBjaGFyICpibHRfdnNoYWRlcltdID0gewogICAgICAgICIjdmVyc2lvbiAxMjBcbiIKICAgICAgICAidm9pZCBtYWluKHZvaWQpXG4iCiAgICAgICAgIntcbiIKICAgICAgICAiICAgIGdsX1Bvc2l0aW9uID0gZ2xfVmVydGV4O1xuIgogICAgICAgICIgICAgZ2xfRnJvbnRDb2xvciA9IHZlYzQoMS4wKTtcbiIKICAgICAgICAiICAgIGdsX1RleENvb3JkWzBdLnggPSAoZ2xfVmVydGV4LnggKiAwLjUpICsgMC41O1xuIgogICAgICAgICIgICAgZ2xfVGV4Q29vcmRbMF0ueSA9ICgtZ2xfVmVydGV4LnkgKiAwLjUpICsgMC41O1xuIgogICAgICAgICJ9XG4iCiAgICB9OwoKICAgIGNvbnN0IGNoYXIgKmJsdF9wc2hhZGVyW10gPSB7CiAgICAgICAgIiN2ZXJzaW9uIDEyMFxuIgogICAgICAgICJ1bmlmb3JtIHNhbXBsZXIyRCBzYW1wbGVyO1xuIgogICAgICAgICJ2b2lkIG1haW4odm9pZClcbiIKICAgICAgICAie1xuIgogICAgICAgICIgICAgZ2xfRnJhZ0RlcHRoID0gdGV4dHVyZTJEKHNhbXBsZXIsIGdsX1RleENvb3JkWzBdLnh5KS54O1xuIgogICAgICAgICJ9XG4iCiAgICB9OwoKICAgIHZzaGFkZXJfaWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlU2hhZGVyT2JqZWN0QVJCKEdMX1ZFUlRFWF9TSEFERVJfQVJCKSk7CiAgICBHTF9FWFRDQUxMKGdsU2hhZGVyU291cmNlQVJCKHZzaGFkZXJfaWQsIDEsIGJsdF92c2hhZGVyLCBOVUxMKSk7CiAgICBHTF9FWFRDQUxMKGdsQ29tcGlsZVNoYWRlckFSQih2c2hhZGVyX2lkKSk7CgogICAgcHNoYWRlcl9pZCA9IEdMX0VYVENBTEwoZ2xDcmVhdGVTaGFkZXJPYmplY3RBUkIoR0xfRlJBR01FTlRfU0hBREVSX0FSQikpOwogICAgR0xfRVhUQ0FMTChnbFNoYWRlclNvdXJjZUFSQihwc2hhZGVyX2lkLCAxLCBibHRfcHNoYWRlciwgTlVMTCkpOwogICAgR0xfRVhUQ0FMTChnbENvbXBpbGVTaGFkZXJBUkIocHNoYWRlcl9pZCkpOwoKICAgIHByb2dyYW1faWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlUHJvZ3JhbU9iamVjdEFSQigpKTsKICAgIEdMX0VYVENBTEwoZ2xBdHRhY2hPYmplY3RBUkIocHJvZ3JhbV9pZCwgdnNoYWRlcl9pZCkpOwogICAgR0xfRVhUQ0FMTChnbEF0dGFjaE9iamVjdEFSQihwcm9ncmFtX2lkLCBwc2hhZGVyX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsTGlua1Byb2dyYW1BUkIocHJvZ3JhbV9pZCkpOwoKICAgIHByaW50X2dsc2xfaW5mb19sb2coJkdMSU5GT19MT0NBVElPTiwgcHJvZ3JhbV9pZCk7CgogICAgLyogT25jZSBsaW5rZWQgd2UgY2FuIG1hcmsgdGhlIHNoYWRlcnMgZm9yIGRlbGV0aW9uLiBUaGV5IHdpbGwgYmUgZGVsZXRlZCBvbmNlIHRoZSBwcm9ncmFtCiAgICAgKiBpcyBkZXN0cm95ZWQKICAgICAqLwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZU9iamVjdEFSQih2c2hhZGVyX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlT2JqZWN0QVJCKHBzaGFkZXJfaWQpKTsKICAgIHJldHVybiBwcm9ncmFtX2lkOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9zZWxlY3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIHVzZVBTLCBCT09MIHVzZVZTKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqcHJpdiA9IChzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqKVRoaXMtPnNoYWRlcl9wcml2OwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtX2lkID0gMDsKICAgIEdMZW51bSBvbGRfdmVydGV4X2NvbG9yX2NsYW1wLCBjdXJyZW50X3ZlcnRleF9jb2xvcl9jbGFtcDsKCiAgICBvbGRfdmVydGV4X2NvbG9yX2NsYW1wID0gcHJpdi0+Z2xzbF9wcm9ncmFtID8gcHJpdi0+Z2xzbF9wcm9ncmFtLT52ZXJ0ZXhfY29sb3JfY2xhbXAgOiBHTF9GSVhFRF9PTkxZX0FSQjsKCiAgICBpZiAodXNlVlMgfHwgdXNlUFMpIHNldF9nbHNsX3NoYWRlcl9wcm9ncmFtKGlmYWNlLCB1c2VQUywgdXNlVlMpOwogICAgZWxzZSBwcml2LT5nbHNsX3Byb2dyYW0gPSBOVUxMOwoKICAgIGN1cnJlbnRfdmVydGV4X2NvbG9yX2NsYW1wID0gcHJpdi0+Z2xzbF9wcm9ncmFtID8gcHJpdi0+Z2xzbF9wcm9ncmFtLT52ZXJ0ZXhfY29sb3JfY2xhbXAgOiBHTF9GSVhFRF9PTkxZX0FSQjsKCiAgICBpZiAob2xkX3ZlcnRleF9jb2xvcl9jbGFtcCAhPSBjdXJyZW50X3ZlcnRleF9jb2xvcl9jbGFtcCkgewogICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9DT0xPUl9CVUZGRVJfRkxPQVQpKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDbGFtcENvbG9yQVJCKEdMX0NMQU1QX1ZFUlRFWF9DT0xPUl9BUkIsIGN1cnJlbnRfdmVydGV4X2NvbG9yX2NsYW1wKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENsYW1wQ29sb3JBUkIiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgidmVydGV4IGNvbG9yIGNsYW1wIG5lZWRzIHRvIGJlIGNoYW5nZWQsIGJ1dCBleHRlbnNpb24gbm90IHN1cHBvcnRlZC5cbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm9ncmFtX2lkID0gcHJpdi0+Z2xzbF9wcm9ncmFtID8gcHJpdi0+Z2xzbF9wcm9ncmFtLT5wcm9ncmFtSWQgOiAwOwogICAgaWYgKHByb2dyYW1faWQpIFRSQUNFKCJVc2luZyBHTFNMIHByb2dyYW0gJXVcbiIsIHByb2dyYW1faWQpOwogICAgR0xfRVhUQ0FMTChnbFVzZVByb2dyYW1PYmplY3RBUkIocHJvZ3JhbV9pZCkpOwogICAgY2hlY2tHTGNhbGwoImdsVXNlUHJvZ3JhbU9iamVjdEFSQiIpOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9zZWxlY3RfZGVwdGhfYmx0KElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqcHJpdiA9IChzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqKSBUaGlzLT5zaGFkZXJfcHJpdjsKICAgIHN0YXRpYyBHTGhhbmRsZUFSQiBsb2MgPSAtMTsKCiAgICBpZiAoIXByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQpIHsKICAgICAgICBwcml2LT5kZXB0aF9ibHRfZ2xzbF9wcm9ncmFtX2lkID0gY3JlYXRlX2dsc2xfYmx0X3NoYWRlcihnbF9pbmZvKTsKICAgICAgICBsb2MgPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQsICJzYW1wbGVyIikpOwogICAgfQoKICAgIEdMX0VYVENBTEwoZ2xVc2VQcm9ncmFtT2JqZWN0QVJCKHByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQpKTsKICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtMWlBUkIobG9jLCAwKSk7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2Rlc2VsZWN0X2RlcHRoX2JsdChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKikgVGhpcy0+c2hhZGVyX3ByaXY7CiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtX2lkOwoKICAgIHByb2dyYW1faWQgPSBwcml2LT5nbHNsX3Byb2dyYW0gPyBwcml2LT5nbHNsX3Byb2dyYW0tPnByb2dyYW1JZCA6IDA7CiAgICBpZiAocHJvZ3JhbV9pZCkgVFJBQ0UoIlVzaW5nIEdMU0wgcHJvZ3JhbSAldVxuIiwgcHJvZ3JhbV9pZCk7CgogICAgR0xfRVhUQ0FMTChnbFVzZVByb2dyYW1PYmplY3RBUkIocHJvZ3JhbV9pZCkpOwogICAgY2hlY2tHTGNhbGwoImdsVXNlUHJvZ3JhbU9iamVjdEFSQiIpOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9jbGVhbnVwKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBHTF9FWFRDQUxMKGdsVXNlUHJvZ3JhbU9iamVjdEFSQigwKSk7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2Rlc3Ryb3koSVdpbmVEM0RCYXNlU2hhZGVyICppZmFjZSkgewogICAgc3RydWN0IGxpc3QgKmxpbmtlZF9wcm9ncmFtczsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKVRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKilkZXZpY2UtPnNoYWRlcl9wcml2OwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJmRldmljZS0+YWRhcHRlci0+Z2xfaW5mbzsKCiAgICAvKiBOb3RlOiBEbyBub3QgdXNlIFF1ZXJ5SW50ZXJmYWNlIGhlcmUgdG8gZmluZCBvdXQgd2hpY2ggc2hhZGVyIHR5cGUgdGhpcyBpcyBiZWNhdXNlIHRoaXMgY29kZQogICAgICogY2FuIGJlIGNhbGxlZCBmcm9tIElXaW5lRDNEQmFzZVNoYWRlcjo6UmVsZWFzZQogICAgICovCiAgICBjaGFyIHBzaGFkZXIgPSBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwoKICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPT0gMCkgcmV0dXJuOwogICAgbGlua2VkX3Byb2dyYW1zID0gJlRoaXMtPmJhc2VTaGFkZXIubGlua2VkX3Byb2dyYW1zOwoKICAgIFRSQUNFKCJEZWxldGluZyBsaW5rZWQgcHJvZ3JhbXNcbiIpOwogICAgaWYgKGxpbmtlZF9wcm9ncmFtcy0+bmV4dCkgewogICAgICAgIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmVudHJ5LCAqZW50cnkyOwoKICAgICAgICBpZihwc2hhZGVyKSB7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUllfU0FGRShlbnRyeSwgZW50cnkyLCBsaW5rZWRfcHJvZ3JhbXMsIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmssIHBzaGFkZXJfZW50cnkpIHsKICAgICAgICAgICAgICAgIGRlbGV0ZV9nbHNsX3Byb2dyYW1fZW50cnkocHJpdiwgZ2xfaW5mbywgZW50cnkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWV9TQUZFKGVudHJ5LCBlbnRyeTIsIGxpbmtlZF9wcm9ncmFtcywgc3RydWN0IGdsc2xfc2hhZGVyX3Byb2dfbGluaywgdnNoYWRlcl9lbnRyeSkgewogICAgICAgICAgICAgICAgZGVsZXRlX2dsc2xfcHJvZ3JhbV9lbnRyeShwcml2LCBnbF9pbmZvLCBlbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIkRlbGV0aW5nIHNoYWRlciBvYmplY3QgJXVcbiIsIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQpOwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZU9iamVjdEFSQihUaGlzLT5iYXNlU2hhZGVyLnByZ0lkKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVPYmplY3RBUkIiKTsKICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAwOwogICAgVGhpcy0+YmFzZVNoYWRlci5pc19jb21waWxlZCA9IEZBTFNFOwp9CgpzdGF0aWMgdW5zaWduZWQgaW50IGdsc2xfcHJvZ3JhbV9rZXlfaGFzaCh2b2lkICprZXkpIHsKICAgIGdsc2xfcHJvZ3JhbV9rZXlfdCAqayA9IChnbHNsX3Byb2dyYW1fa2V5X3QgKilrZXk7CgogICAgdW5zaWduZWQgaW50IGhhc2ggPSBrLT52c2hhZGVyIHwgay0+cHNoYWRlciA8PCAxNjsKICAgIGhhc2ggKz0gfihoYXNoIDw8IDE1KTsKICAgIGhhc2ggXj0gIChoYXNoID4+IDEwKTsKICAgIGhhc2ggKz0gIChoYXNoIDw8IDMpOwogICAgaGFzaCBePSAgKGhhc2ggPj4gNik7CiAgICBoYXNoICs9IH4oaGFzaCA8PCAxMSk7CiAgICBoYXNoIF49ICAoaGFzaCA+PiAxNik7CgogICAgcmV0dXJuIGhhc2g7Cn0KCnN0YXRpYyBCT09MIGdsc2xfcHJvZ3JhbV9rZXlfY29tcGFyZSh2b2lkICprZXlhLCB2b2lkICprZXliKSB7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmthID0gKGdsc2xfcHJvZ3JhbV9rZXlfdCAqKWtleWE7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmtiID0gKGdsc2xfcHJvZ3JhbV9rZXlfdCAqKWtleWI7CgogICAgcmV0dXJuIGthLT52c2hhZGVyID09IGtiLT52c2hhZGVyICYmIGthLT5wc2hhZGVyID09IGtiLT5wc2hhZGVyOwp9CgpzdGF0aWMgSFJFU1VMVCBzaGFkZXJfZ2xzbF9hbGxvYyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0cnVjdCBzaGFkZXJfZ2xzbF9wcml2ICpwcml2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdikpOwogICAgcHJpdi0+Z2xzbF9wcm9ncmFtX2xvb2t1cCA9IGhhc2hfdGFibGVfY3JlYXRlKGdsc2xfcHJvZ3JhbV9rZXlfaGFzaCwgZ2xzbF9wcm9ncmFtX2tleV9jb21wYXJlKTsKICAgIFRoaXMtPnNoYWRlcl9wcml2ID0gcHJpdjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9mcmVlKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqcHJpdiA9IChzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdiAqKVRoaXMtPnNoYWRlcl9wcml2OwoKICAgIGlmKHByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlT2JqZWN0QVJCKHByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQpKTsKICAgIH0KCiAgICBoYXNoX3RhYmxlX2Rlc3Ryb3kocHJpdi0+Z2xzbF9wcm9ncmFtX2xvb2t1cCwgTlVMTCwgTlVMTCk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c2hhZGVyX3ByaXYpOwogICAgVGhpcy0+c2hhZGVyX3ByaXYgPSBOVUxMOwp9CgpzdGF0aWMgQk9PTCBzaGFkZXJfZ2xzbF9kaXJ0eV9jb25zdChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIC8qIFRPRE86IEdMX0VYVF9iaW5kYWJsZV91bmlmb3JtIGNhbiBiZSB1c2VkIHRvIHNoYXJlIGNvbnN0YW50cyBhY3Jvc3Mgc2hhZGVycyAqLwogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9nZW5lcmF0ZV9wc2hhZGVyKElXaW5lRDNEUGl4ZWxTaGFkZXIgKmlmYWNlLCBTSEFERVJfQlVGRkVSICpidWZmZXIpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgY29uc3QgY2hhciAqZnJhZ2NvbG9yOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIC8qIENyZWF0ZSB0aGUgaHcgR0xTTCBzaGFkZXIgb2JqZWN0IGFuZCBhc3NpZ24gaXQgYXMgdGhlIGJhc2VTaGFkZXIucHJnSWQgKi8KICAgIEdMaGFuZGxlQVJCIHNoYWRlcl9vYmogPSBHTF9FWFRDQUxMKGdsQ3JlYXRlU2hhZGVyT2JqZWN0QVJCKEdMX0ZSQUdNRU5UX1NIQURFUl9BUkIpKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIjdmVyc2lvbiAxMjBcbiIpOwoKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiI2V4dGVuc2lvbiBHTF9BUkJfZHJhd19idWZmZXJzIDogZW5hYmxlXG4iKTsKICAgIH0KICAgIGlmIChHTF9TVVBQT1JUKEFSQl9URVhUVVJFX1JFQ1RBTkdMRSkpIHsKICAgICAgICAvKiBUaGUgc3BlYyBzYXlzIHRoYXQgaXQgZG9lc24ndCBoYXZlIHRvIGJlIGV4cGxpY2l0bHkgZW5hYmxlZCwgYnV0IHRoZSBudmlkaWEKICAgICAgICAgKiBkcml2ZXJzIHdyaXRlIGEgd2FybmluZyBpZiB3ZSBkb24ndCBkbyBzbwogICAgICAgICAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiNleHRlbnNpb24gR0xfQVJCX3RleHR1cmVfcmVjdGFuZ2xlIDogZW5hYmxlXG4iKTsKICAgIH0KCiAgICAvKiBCYXNlIERlY2xhcmF0aW9ucyAqLwogICAgc2hhZGVyX2dlbmVyYXRlX2dsc2xfZGVjbGFyYXRpb25zKCAoSVdpbmVEM0RCYXNlU2hhZGVyKikgVGhpcywgcmVnX21hcHMsIGJ1ZmZlciwgJkdMSU5GT19MT0NBVElPTik7CgogICAgLyogUGFjayAzLjAgaW5wdXRzICovCiAgICBpZiAoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA+PSBXSU5FRDNEUFNfVkVSU0lPTigzLDApKSB7CgogICAgICAgIGlmKCgoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlKS0+c3RyaWRlZF9zdHJlYW1zLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCkgewogICAgICAgICAgICBUaGlzLT52ZXJ0ZXhwcm9jZXNzaW5nID0gcHJldHJhbnNmb3JtZWQ7CiAgICAgICAgICAgIHBzaGFkZXJfZ2xzbF9pbnB1dF9wYWNrKGJ1ZmZlciwgVGhpcy0+c2VtYW50aWNzX2luLCBpZmFjZSk7CiAgICAgICAgfSBlbHNlIGlmKCF1c2VfdnMoKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZSkpIHsKICAgICAgICAgICAgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9IGZpeGVkZnVuY3Rpb247CiAgICAgICAgICAgIHBzaGFkZXJfZ2xzbF9pbnB1dF9wYWNrKGJ1ZmZlciwgVGhpcy0+c2VtYW50aWNzX2luLCBpZmFjZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9IHZlcnRleHNoYWRlcjsKICAgICAgICB9CiAgICB9CgogICAgLyogQmFzZSBTaGFkZXIgQm9keSAqLwogICAgc2hhZGVyX2dlbmVyYXRlX21haW4oIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCBidWZmZXIsIHJlZ19tYXBzLCBmdW5jdGlvbik7CgogICAgLyogUGl4ZWwgc2hhZGVycyA8IDIuMCBwbGFjZSB0aGUgcmVzdWx0aW5nIGNvbG9yIGluIFIwIGltcGxpY2l0bHkgKi8KICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIC8qIFNvbWUgb2xkZXIgY2FyZHMgbGlrZSBHZWZvcmNlRlggb25lcyBkb24ndCBzdXBwb3J0IG11bHRpcGxlIGJ1ZmZlcnMsIHNvIGFsc28gbm90IGdsX0ZyYWdEYXRhICovCiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfRFJBV19CVUZGRVJTKSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfRnJhZ0RhdGFbMF0gPSBSMDtcbiIpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfRnJhZ0NvbG9yID0gUjA7XG4iKTsKICAgIH0KCiAgICBpZihHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgZnJhZ2NvbG9yID0gImdsX0ZyYWdEYXRhWzBdIjsKICAgIH0gZWxzZSB7CiAgICAgICAgZnJhZ2NvbG9yID0gImdsX0ZyYWdDb2xvciI7CiAgICB9CiAgICBpZihUaGlzLT5zcmdiX2VuYWJsZWQpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0bXAwLnh5eiA9IHBvdyglcy54eXosIHZlYzMoJWYsICVmLCAlZikpICogdmVjMyglZiwgJWYsICVmKSAtIHZlYzMoJWYsICVmLCAlZik7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICBmcmFnY29sb3IsIHNyZ2JfcG93LCBzcmdiX3Bvdywgc3JnYl9wb3csIHNyZ2JfbXVsX2hpZ2gsIHNyZ2JfbXVsX2hpZ2gsIHNyZ2JfbXVsX2hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDEueHl6ID0gJXMueHl6ICogc3JnYl9tdWxfbG93Lnh5ejtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMueCA9ICVzLnggPCBzcmdiX2NvbXBhcmlzb24ueCA/IHRtcDEueCA6IHRtcDAueDtcbiIsIGZyYWdjb2xvciwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcy55ID0gJXMueSA8IHNyZ2JfY29tcGFyaXNvbi55ID8gdG1wMS55IDogdG1wMC55O1xuIiwgZnJhZ2NvbG9yLCBmcmFnY29sb3IpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLnogPSAlcy56IDwgc3JnYl9jb21wYXJpc29uLnogPyB0bXAxLnogOiB0bXAwLno7XG4iLCBmcmFnY29sb3IsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMgPSBjbGFtcCglcywgMC4wLCAxLjApO1xuIiwgZnJhZ2NvbG9yLCBmcmFnY29sb3IpOwogICAgfQogICAgLyogUGl4ZWwgc2hhZGVyIDwgMy4wIGRvIG5vdCByZXBsYWNlIHRoZSBmb2cgc3RhZ2UuCiAgICAgKiBUaGlzIGltcGxlbWVudHMgbGluZWFyIGZvZyBjb21wdXRhdGlvbiBhbmQgYmxlbmRpbmcuCiAgICAgKiBUT0RPOiBub24gbGluZWFyIGZvZwogICAgICogTk9URTogZ2xfRm9nLnN0YXJ0IGFuZCBnbF9Gb2cuZW5kIGRvbid0IGhvbGQgZm9nIHN0YXJ0IHMgYW5kIGVuZCBlIGJ1dAogICAgICogLTEvKGUtcykgYW5kIGUvKGUtcykgcmVzcGVjdGl2ZWx5LgogICAgICovCiAgICBpZihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMywwKSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImZsb2F0IEZvZyA9IGNsYW1wKGdsX0ZvZ0ZyYWdDb29yZCAqIGdsX0ZvZy5zdGFydCArIGdsX0ZvZy5lbmQsIDAuMCwgMS4wKTtcbiIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLnh5eiA9IG1peChnbF9Gb2cuY29sb3IueHl6LCAlcy54eXosIEZvZyk7XG4iLCBmcmFnY29sb3IsIGZyYWdjb2xvcik7CiAgICB9CgogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAifVxuIik7CgogICAgVFJBQ0UoIkNvbXBpbGluZyBzaGFkZXIgb2JqZWN0ICV1XG4iLCBzaGFkZXJfb2JqKTsKICAgIEdMX0VYVENBTEwoZ2xTaGFkZXJTb3VyY2VBUkIoc2hhZGVyX29iaiwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLT5idWZmZXIsIE5VTEwpKTsKICAgIEdMX0VYVENBTEwoZ2xDb21waWxlU2hhZGVyQVJCKHNoYWRlcl9vYmopKTsKICAgIHByaW50X2dsc2xfaW5mb19sb2coJkdMSU5GT19MT0NBVElPTiwgc2hhZGVyX29iaik7CgogICAgLyogU3RvcmUgdGhlIHNoYWRlciBvYmplY3QgKi8KICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSBzaGFkZXJfb2JqOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9nZW5lcmF0ZV92c2hhZGVyKElXaW5lRDNEVmVydGV4U2hhZGVyICppZmFjZSwgU0hBREVSX0JVRkZFUiAqYnVmZmVyKSB7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIC8qIENyZWF0ZSB0aGUgaHcgR0xTTCBzaGFkZXIgcHJvZ3JhbSBhbmQgYXNzaWduIGl0IGFzIHRoZSBiYXNlU2hhZGVyLnByZ0lkICovCiAgICBHTGhhbmRsZUFSQiBzaGFkZXJfb2JqID0gR0xfRVhUQ0FMTChnbENyZWF0ZVNoYWRlck9iamVjdEFSQihHTF9WRVJURVhfU0hBREVSX0FSQikpOwoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiN2ZXJzaW9uIDEyMFxuIik7CgogICAgLyogQmFzZSBEZWNsYXJhdGlvbnMgKi8KICAgIHNoYWRlcl9nZW5lcmF0ZV9nbHNsX2RlY2xhcmF0aW9ucyggKElXaW5lRDNEQmFzZVNoYWRlciopIFRoaXMsIHJlZ19tYXBzLCBidWZmZXIsICZHTElORk9fTE9DQVRJT04pOwoKICAgIC8qIEJhc2UgU2hhZGVyIEJvZHkgKi8KICAgIHNoYWRlcl9nZW5lcmF0ZV9tYWluKCAoSVdpbmVEM0RCYXNlU2hhZGVyKikgVGhpcywgYnVmZmVyLCByZWdfbWFwcywgZnVuY3Rpb24pOwoKICAgIC8qIFVucGFjayAzLjAgb3V0cHV0cyAqLwogICAgaWYgKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPj0gV0lORUQzRFZTX1ZFUlNJT04oMywwKSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIm9yZGVyX3BzX2lucHV0KE9VVCk7XG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAib3JkZXJfcHNfaW5wdXQoKTtcbiIpOwogICAgfQoKICAgIC8qIElmIHRoaXMgc2hhZGVyIGRvZXNuJ3QgdXNlIGZvZyBjb3B5IHRoZSB6IGNvb3JkIHRvIHRoZSBmb2cgY29vcmQgc28gdGhhdCB3ZSBjYW4gdXNlIHRhYmxlIGZvZyAqLwogICAgaWYgKCFyZWdfbWFwcy0+Zm9nKQogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX0ZvZ0ZyYWdDb29yZCA9IGdsX1Bvc2l0aW9uLno7XG4iKTsKCiAgICAvKiBXcml0ZSB0aGUgZmluYWwgcG9zaXRpb24uCiAgICAgKgogICAgICogT3BlbkdMIGNvb3JkaW5hdGVzIHNwZWNpZnkgdGhlIGNlbnRlciBvZiB0aGUgcGl4ZWwgd2hpbGUgZDNkIGNvb3JkcyBzcGVjaWZ5CiAgICAgKiB0aGUgY29ybmVyLiBUaGUgb2Zmc2V0cyBhcmUgc3RvcmVkIGluIHogYW5kIHcgaW4gcG9zRml4dXAuIHBvc0ZpeHVwLnkgY29udGFpbnMKICAgICAqIDEuMCBvciAtMS4wIHRvIHR1cm4gdGhlIHJlbmRlcmluZyB1cHNpZGUgZG93biBmb3Igb2Zmc2NyZWVuIHJlbmRlcmluZy4gUG9zRml4dXAueAogICAgICogY29udGFpbnMgMS4wIHRvIGFsbG93IGEgbWFkLgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9Qb3NpdGlvbi55ID0gZ2xfUG9zaXRpb24ueSAqIHBvc0ZpeHVwLnk7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1Bvc2l0aW9uLnh5ICs9IHBvc0ZpeHVwLnp3ICogZ2xfUG9zaXRpb24ud3c7XG4iKTsKCiAgICAvKiBaIGNvb3JkIFswOzFdLT5bLTE7MV0gbWFwcGluZywgc2VlIGNvbW1lbnQgaW4gdHJhbnNmb3JtX3Byb2plY3Rpb24gaW4gc3RhdGUuYwogICAgICoKICAgICAqIEJhc2ljYWxseSB3ZSB3YW50IChpbiBob21vZ2VuZW91cyBjb29yZGluYXRlcykgeiA9IHogKiAyIC0gMS4gSG93ZXZlciwgc2hhZGVycyBhcmUgcnVuCiAgICAgKiBiZWZvcmUgdGhlIGhvbW9nZW5lb3VzIGRpdmlkZSwgc28gd2UgaGF2ZSB0byB0YWtlIHRoZSB3IGludG8gYWNjb3VudDogeiA9ICgoeiAvIHcpICogMiAtIDEpICogdywKICAgICAqIHdoaWNoIGlzIHRoZSBzYW1lIGFzIHogPSB6IC8gMiAtIHcuCiAgICAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1Bvc2l0aW9uLnogPSBnbF9Qb3NpdGlvbi56ICogMi4wIC0gZ2xfUG9zaXRpb24udztcbiIpOwoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIn1cbiIpOwoKICAgIFRSQUNFKCJDb21waWxpbmcgc2hhZGVyIG9iamVjdCAldVxuIiwgc2hhZGVyX29iaik7CiAgICBHTF9FWFRDQUxMKGdsU2hhZGVyU291cmNlQVJCKHNoYWRlcl9vYmosIDEsIChjb25zdCBjaGFyKiopJmJ1ZmZlci0+YnVmZmVyLCBOVUxMKSk7CiAgICBHTF9FWFRDQUxMKGdsQ29tcGlsZVNoYWRlckFSQihzaGFkZXJfb2JqKSk7CiAgICBwcmludF9nbHNsX2luZm9fbG9nKCZHTElORk9fTE9DQVRJT04sIHNoYWRlcl9vYmopOwoKICAgIC8qIFN0b3JlIHRoZSBzaGFkZXIgb2JqZWN0ICovCiAgICBUaGlzLT5iYXNlU2hhZGVyLnByZ0lkID0gc2hhZGVyX29iajsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfZ2V0X2NhcHMoV0lORUQzRERFVlRZUEUgZGV2dHlwZSwgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBzdHJ1Y3Qgc2hhZGVyX2NhcHMgKnBDYXBzKSB7CiAgICAvKiBOdmlkaWEgR2Vmb3JjZTYvNyBvciBBdGkgUjR4eC9SNXh4IGNhcmRzIHdpdGggR0xTTCBzdXBwb3J0LCBzdXBwb3J0IFZTIDMuMCBidXQgb2xkZXIgTnZpZGlhL0F0aQogICAgICogbW9kZWxzIHdpdGggR0xTTCBzdXBwb3J0IG9ubHkgc3VwcG9ydCAyLjAuIEluIGNhc2Ugb2YgbnZpZGlhIHdlIGNhbiBkZXRlY3QgVlMgMi4wIHN1cHBvcnQgdXNpbmcKICAgICAqIHZzX252X3ZlcnNpb24gd2hpY2ggaXMgYmFzZWQgb24gTlZfdmVydGV4X3Byb2dyYW0uCiAgICAgKiBGb3IgQXRpIGNhcmRzIHRoZXJlJ3Mgbm8gd2F5IHVzaW5nIGdsc2wgKGl0IGFic3RyYWN0cyB0aGUgbG93bGV2ZWwgaW5mbyBhd2F5KSBhbmQgYWxzbyBub3QKICAgICAqIHVzaW5nIEFSQl92ZXJ0ZXhfcHJvZ3JhbS4gSXQgaXMgc2FmZSB0byBhc3N1bWUgdGhhdCB3aGVuIGEgY2FyZCBzdXBwb3J0cyBwaXhlbCBzaGFkZXIgMi4wIGl0CiAgICAgKiBzdXBwb3J0cyB2ZXJ0ZXggc2hhZGVyIDIuMCB0b28gYW5kIHRoZSB3YXkgYXJvdW5kLiBXZSBjYW4gZGV0ZWN0IHBzMi4wIHVzaW5nIHRoZSBtYXhpbXVtIG51bWJlcgogICAgICogb2YgbmF0aXZlIGluc3RydWN0aW9ucywgc28gdXNlIHRoYXQgaGVyZS4gRm9yIG1vcmUgaW5mbyBzZWUgdGhlIHBpeGVsIHNoYWRlciB2ZXJzaW9uaW5nIGNvZGUgYmVsb3cuCiAgICAgKi8KICAgIGlmKChHTElORk9fTE9DQVRJT04udnNfbnZfdmVyc2lvbiA9PSBWU19WRVJTSU9OXzIwKSB8fCAoR0xJTkZPX0xPQ0FUSU9OLnBzX2FyYl9tYXhfaW5zdHJ1Y3Rpb25zIDw9IDUxMikpCiAgICAgICAgcENhcHMtPlZlcnRleFNoYWRlclZlcnNpb24gPSBXSU5FRDNEVlNfVkVSU0lPTigyLDApOwogICAgZWxzZQogICAgICAgIHBDYXBzLT5WZXJ0ZXhTaGFkZXJWZXJzaW9uID0gV0lORUQzRFZTX1ZFUlNJT04oMywwKTsKICAgIFRSQUNFXyhkM2RfY2FwcykoIkhhcmR3YXJlIHZlcnRleCBzaGFkZXIgdmVyc2lvbiAlZC4lZCBlbmFibGVkIChHTFNMKVxuIiwgKHBDYXBzLT5WZXJ0ZXhTaGFkZXJWZXJzaW9uID4+IDgpICYgMHhmZiwgcENhcHMtPlZlcnRleFNoYWRlclZlcnNpb24gJiAweGZmKTsKICAgIHBDYXBzLT5NYXhWZXJ0ZXhTaGFkZXJDb25zdCA9IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOwoKICAgIC8qIE9sZGVyIERYOS1jbGFzcyB2aWRlb2NhcmRzIChHZWZvcmNlRlggLyBSYWRlb24gPjk1MDAvWCowMCkgb25seSBzdXBwb3J0IHBpeGVsIHNoYWRlciAyLjAvMi4wYS8yLjBiLgogICAgICogSW4gT3BlbkdMIHRoZSBleHRlbnNpb25zIHJlbGF0ZWQgdG8gR0xTTCBhYnN0cmFjdCBsb3dsZXZlbCBHTCBpbmZvIGF3YXkgd2hpY2ggaXMgbmVlZGVkCiAgICAgKiB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIDIuMCBhbmQgMy4wIChhbmQgMi4wYS8yLjBiKS4gSW4gY2FzZSBvZiBOdmlkaWEgd2UgdXNlIHRoZWlyIGZyYWdtZW50CiAgICAgKiBwcm9ncmFtIGV4dGVuc2lvbnMuIE9uIG90aGVyIGhhcmR3YXJlIGluY2x1ZGluZyBBVEkgR0xfQVJCX2ZyYWdtZW50X3Byb2dyYW0gb2ZmZXJzIHRoZSBpbmZvCiAgICAgKiBpbiBtYXggbmF0aXZlIGluc3RydWN0aW9ucy4gSW50ZWwgYW5kIG90aGVycyBhbHNvIG9mZmVyIHRoZSBpbmZvIGluIHRoaXMgZXh0ZW5zaW9uIGJ1dCB0aGV5CiAgICAgKiBkb24ndCBzdXBwb3J0IEdMU0wgKGF0IGxlYXN0IG9uIFdpbmRvd3MpLgogICAgICoKICAgICAqIFBTMi4wIHJlcXVpcmVzIGF0IGxlYXN0IDk2IGluc3RydWN0aW9ucywgMi4wYS8yLjBiIGdvIHVwIHRvIDUxMi4gQXNzdW1lIHRoYXQgaWYgdGhlIG51bWJlcgogICAgICogb2YgaW5zdHJ1Y3Rpb25zIGlzIDUxMiBvciBsZXNzIHdlIGhhdmUgdG8gZG8gd2l0aCBwczIuMCBoYXJkd2FyZS4KICAgICAqIE5PVEU6IHBzMy4wIGhhcmR3YXJlIHJlcXVpcmVzIDUxMiBvciBtb3JlIGluc3RydWN0aW9ucyBidXQgYXRpIGFuZCBudmlkaWEgb2ZmZXIgJ2Vub3VnaCcgKDEwMjQgdnMgNDA5Nikgb24gdGhlaXIgbW9zdCBiYXNpYyBwczMuMCBoYXJkd2FyZS4KICAgICAqLwogICAgaWYoKEdMSU5GT19MT0NBVElPTi5wc19udl92ZXJzaW9uID09IFBTX1ZFUlNJT05fMjApIHx8IChHTElORk9fTE9DQVRJT04ucHNfYXJiX21heF9pbnN0cnVjdGlvbnMgPD0gNTEyKSkKICAgICAgICBwQ2Fwcy0+UGl4ZWxTaGFkZXJWZXJzaW9uID0gV0lORUQzRFBTX1ZFUlNJT04oMiwwKTsKICAgIGVsc2UKICAgICAgICBwQ2Fwcy0+UGl4ZWxTaGFkZXJWZXJzaW9uID0gV0lORUQzRFBTX1ZFUlNJT04oMywwKTsKCiAgICAvKiBGSVhNRTogVGhlIGZvbGxvd2luZyBsaW5lIGlzIGNhcmQgZGVwZW5kZW50LiAtOC4wIHRvIDguMCBpcyB0aGUKICAgICAqIERpcmVjdDNEIG1pbmltdW0gcmVxdWlyZW1lbnQuCiAgICAgKgogICAgICogQm90aCBHTF9BUkJfZnJhZ21lbnRfcHJvZ3JhbSBhbmQgR0xTTCByZXF1aXJlIGEgIm1heGltdW0gcmVwcmVzZW50YWJsZSBtYWduaXR1ZGUiCiAgICAgKiBvZiBjb2xvcnMgdG8gYmUgMl4xMCwgYW5kIDJeMzIgZm9yIG90aGVyIGZsb2F0cy4gU2hvdWxkIHdlIHVzZSAxMDI0IGhlcmU/CiAgICAgKgogICAgICogVGhlIHByb2JsZW0gaXMgdGhhdCB0aGUgcmVmcmFzdCBjbGFtcHMgdGVtcG9yYXJ5IHJlc3VsdHMgaW4gdGhlIHNoYWRlciB0bwogICAgICogWy1NYXhWYWx1ZTsrTWF4VmFsdWVdLiBJZiB0aGUgY2FyZCdzIG1heCB2YWx1ZSBpcyBiaWdnZXIgdGhhbiB0aGUgb25lIHdlIGFkdmVydGl6ZSBoZXJlLAogICAgICogdGhlbiBhcHBsaWNhdGlvbnMgbWF5IG1pc3MgdGhlIGNsYW1waW5nIGJlaGF2aW9yLiBPbiB0aGUgb3RoZXIgaGFuZCwgaWYgaXQgaXMgc21hbGxlciwKICAgICAqIHRoZSBzaGFkZXIgd2lsbCBnZW5lcmF0ZSBpbmNvcnJlY3QgcmVzdWx0cyB0b28uIFVuZm9ydHVuYXRlbHksIEdMIGRlbGliZXJhdGVseSBkb2Vzbid0CiAgICAgKiBvZmZlciBhIHdheSB0byBxdWVyeSB0aGlzLgogICAgICovCiAgICBwQ2Fwcy0+UGl4ZWxTaGFkZXIxeE1heFZhbHVlID0gOC4wOwogICAgVFJBQ0VfKGQzZF9jYXBzKSgiSGFyZHdhcmUgcGl4ZWwgc2hhZGVyIHZlcnNpb24gJWQuJWQgZW5hYmxlZCAoR0xTTClcbiIsIChwQ2Fwcy0+UGl4ZWxTaGFkZXJWZXJzaW9uID4+IDgpICYgMHhmZiwgcENhcHMtPlBpeGVsU2hhZGVyVmVyc2lvbiAmIDB4ZmYpOwp9CgpzdGF0aWMgQk9PTCBzaGFkZXJfZ2xzbF9jb252X3N1cHBvcnRlZChXSU5FRDNERk9STUFUIGZtdCkgewogICAgVFJBQ0UoIkNoZWNraW5nIHNoYWRlciBmb3JtYXQgc3VwcG9ydCBmb3IgZm9ybWF0ICVzOiIsIGRlYnVnX2QzZGZvcm1hdChmbXQpKTsKICAgIHN3aXRjaChmbXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjhVODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjE2VTE2OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOEw4VjhVODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfTDZWNVU1OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9ROFc4VjhVODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQVRJMk46CiAgICAgICAgICAgIFRSQUNFKCJbT0tdXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVFJBQ0UoIltGQUlMRURcbiIpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9Cn0KCmNvbnN0IHNoYWRlcl9iYWNrZW5kX3QgZ2xzbF9zaGFkZXJfYmFja2VuZCA9IHsKICAgIHNoYWRlcl9nbHNsX3NlbGVjdCwKICAgIHNoYWRlcl9nbHNsX3NlbGVjdF9kZXB0aF9ibHQsCiAgICBzaGFkZXJfZ2xzbF9kZXNlbGVjdF9kZXB0aF9ibHQsCiAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50cywKICAgIHNoYWRlcl9nbHNsX2NsZWFudXAsCiAgICBzaGFkZXJfZ2xzbF9jb2xvcl9jb3JyZWN0aW9uLAogICAgc2hhZGVyX2dsc2xfZGVzdHJveSwKICAgIHNoYWRlcl9nbHNsX2FsbG9jLAogICAgc2hhZGVyX2dsc2xfZnJlZSwKICAgIHNoYWRlcl9nbHNsX2RpcnR5X2NvbnN0LAogICAgc2hhZGVyX2dsc2xfZ2VuZXJhdGVfcHNoYWRlciwKICAgIHNoYWRlcl9nbHNsX2dlbmVyYXRlX3ZzaGFkZXIsCiAgICBzaGFkZXJfZ2xzbF9nZXRfY2FwcywKICAgIHNoYWRlcl9nbHNsX2NvbnZfc3VwcG9ydGVkLAp9Owo=