LyogQ29weXJpZ2h0IChDKSAyMDExLTIwMTIgSHVtYXggQ28uLCBMdGQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIEh1bWF4IENvLiwgTHRkLiAoIkh1bWF4IikgaGVyZWJ5IHByb3ZpZGVzIHBlcm1pc3Npb24sIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkKICogcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YgdGhpcyBzb3VyY2UgY29kZSwgdG8gdXNlIGFuZCByZWRpc3RyaWJ1dGUgdGhpcwogKiBzb3VyY2UgY29kZSB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2YgdGhpcyBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqIG5vdGljZSwgcGVybWlzc2lvbiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nCiAqIGRpc2NsYWltZXIuCiAqCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwKICogcGVybWlzc2lvbiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KICogdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgSFVNQVggIkFTIElTIiBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAogKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQUNDVVJBQ1ksIENPTVBMRVRFTkVTUywKICogQ1VSUkVOQ1ksIEFWQUlMQUJJTElUWSwgVElUTEUgT1IgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgSFVNQVggT1IKICogQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsCiAqIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywKICogUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7CiAqIE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLAogKiBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUgogKiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSElTCiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKgogKiBUaGUgdmlld3MgYW5kIGNvbmNsdXNpb24gY29udGFpbmVkIGluIHRoZSBzb2Z0d2FyZSBhbmQgZG9jdW1lbnRhdGlvbiBhcmUKICogdGhvc2Ugb2YgdGhlIGF1dGhvcnMgYW5kIHNob3VsZCBub3QgYmUgaW50ZXJwcmV0ZWQgYXMgcmVwcmVzZW50aW5nIG9mZmljaWFsCiAqIHBvbGljaWVzLCBlaXRoZXIgZXhwcmVzc2VkIG9yIGltcGxpZWQsIG9mIEh1bWF4LgogKgogKiBOb3R3aXRoc3RhbmRpbmcgdGhlIGFib3ZlLCB1bmRlciBubyBjaXJjdW1zdGFuY2VzIG1heSB5b3UgY29tYmluZSB0aGlzCiAqIHNvZnR3YXJlIGluIGFueSB3YXkgd2l0aCBhbnkgb3RoZXIgSHVtYXi/cyBzb2Z0d2FyZSBwcm92aWRlZCB1bmRlciBhIGxpY2Vuc2UKICogb3RoZXIgdGhhbiB0aGUgYWJvdmUgbGljZW5zZSwgd2l0aG91dCBIdW1heCdzIGV4cHJlc3MgcHJpb3Igd3JpdHRlbiBjb25zZW50LgogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqIEZpbGUgRGVzY3JpcHRpb24gKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogRmlsZSBOYW1lOiAgICAgICAgICAgJFdvcmtmaWxlOiAgIGhteF91cHJhZGVfZmxhc2guYyAgJAogKiBWZXJzaW9uOiAgICAgICAgICAgICAkUmV2aXNpb246ICAgMS4wICAkCiAqIE9yaWdpbmFsIEF1dGhvcjogICAgIFlhbmcgSHl1biBVayAkCiAqIEN1cnJlbnQgQXV0aG9yOiAgICAgICRBdXRob3I6IGh1eWFuZ0BodW1heGRpZ2l0YWwuY29tICQKICogRGF0ZTogICAgICAgICAgICAgICAgJERhdGU6IDIwMTEuMDkuMzAKICogRmlsZSBEZXNjcmlwdGlvbjogICAgSHVtYXggVXBncmFkZSBBUElzCiAqIE1vZHVsZToKICogUmVtYXJrczoKICovCgovKioKICogQGRlZmdyb3VwIFVQR1JBREVfRkxBU0ggRmxhc2hpbmcgQVBJcyBmb3IgVXBncmFkZSBNb2R1bGUKICogQGluZ3JvdXAgVVBHUkFERQogKgogKi8KCi8qKgogKiBAYXV0aG9yIEh5dW51ayBZYW5nKGh1eWFuZ0BodW1heGRpZ2l0YWwuY29tKQogKiBAZGF0ZSAzMCBTZXB0IDIwMTEKICovCgogLypAeyovCgovKioKICogQGZpbGUgaG14X3VwZ3JhZGVfZmxhc2guYwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBIZWFkZXIgRmlsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IEluY2x1ZGluZyBIZWFkZXIgRmlsZXMgKi8KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDxzeXMvbW91bnQuaD4KI2luY2x1ZGUgPG10ZC9tdGQtdXNlci5oPgovKiBFbmQgSW5jbHVkaW5nIEhlYWRlcnMgKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBkZWZpbmUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiBTdGFydCAjZGVmaW5lICovCi8qIHRoaXMgaXMgZm9yIHRlc3QgKi8KI2RlZmluZSBUQVJHRVRfTlZSQU1fTVREICAgICAgICAiL2Rldi9tdGQvaG52cmFtIgovKiBFbmQgI2RlZmluZSAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogdHlwZWRlZiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogU3RhcnQgdHlwZWRlZiAqLwovKiBFbmQgdHlwZWRlZiAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqIGdsb2JhbCB2YXJpYWJsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IGdsb2JhbCB2YXJpYWJsZSAqLwppbnQgbGlidXBncmFkZV92ZXJib3NlID0gMTsKLyogRW5kIGdsb2JhbCB2YXJpYWJsZSAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqIHN0YXRpYyB2YXJpYWJsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFN0YXJ0IHN0YXRpYyB2YXJpYWJsZSAqLwppbnQgZmRfbnZyYW0gPSAtMTsKCi8qIEVuZCBzdGF0aWMgdmFyaWFibGUgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqIHN0YXRpYyBmdW50aW9ucyAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmludCBITVhfVVBHUkFERV9OVlJBTV9Xcml0ZSh1bnNpZ25lZCBsb25nIG9mZnNldCwgdW5zaWduZWQgY2hhciAqIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgc2l6ZSApCnsKICBpbnQgcmV0OwoKICBpZiAobGlidXBncmFkZV92ZXJib3NlKSBwcmludGYoIlslc10gb2Zmc2V0ICUwOHgsIHNpemUgJWQsIGRhdGEgPSAlMDJ4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0ZVTkNUSU9OX18sIG9mZnNldCwgc2l6ZSwgZGF0YVswXSApOwoKICBpZiAoIGZkX252cmFtIDwgMCApIHsKICAgIGZkX252cmFtID0gb3BlbihUQVJHRVRfTlZSQU1fTVRELCAoT19SRFdSIHwgT19TWU5DKSApOwogICAgaWYoIGZkX252cmFtIDwgMCApIHsKICAgICAgcGVycm9yKFRBUkdFVF9OVlJBTV9NVEQpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgfQoKICByZXQgPSBsc2VlayhmZF9udnJhbSwgb2Zmc2V0LCBTRUVLX1NFVCk7CiAgaWYocmV0IDwgMCkgewogICAgcGVycm9yKCJsc2VlayIpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgcmV0ID0gd3JpdGUoZmRfbnZyYW0sIGRhdGEsIHNpemUpOwogIGlmKHJldCA8IDApIHsKICAgIHBlcnJvcigid3JpdGUiKTsKICAgIHJldHVybiAtMTsKICB9CgogIC8qIFdyaXRlcyB0byAvZGV2L210ZGJsb2NrWCBhcmUgY2FjaGVkIGluZGVmaW5pdGVseSB1bnRpbCB0aGUgbGFzdCBmaWxlCiAgICogZGVzY3JpcHRvciBpcyBjbG9zZWQuIEZsdXNoIHRoaXMgY2FjaGUgYWZ0ZXIgd3JpdGluZy4gVGhlIHVzZXIgZGVwZW5kcyBvbgogICAqIGRhdGEgYmVpbmcgcGh5c2ljYWxseSB3cml0dGVuIHRvIGZsYXNoIHdoZW4gdGhpcyBmdW5jdGlvbiByZXR1cm5zLgogICAqIFJlcXVpcmVzIENBUF9TWVNfQURNSU4uICovCiAgcmV0ID0gaW9jdGwoZmRfbnZyYW0sIEJMS0ZMU0JVRiwgMCk7CiAgaWYocmV0IDwgMCkgewogICAgcGVycm9yKCJpb2N0bChobnZyYW0sIEJMS0ZMU0JVRiwgMCkiKTsKICAgIHJldHVybiAtMTsKICB9CgogIHJldHVybiAwOwp9CgppbnQgSE1YX1VQR1JBREVfTlZSQU1fUmVhZCh1bnNpZ25lZCBsb25nIG9mZnNldCwgdW5zaWduZWQgY2hhciAqIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBzaXplICkKewogIGludCByZXQ7CgogIGlmIChsaWJ1cGdyYWRlX3ZlcmJvc2UpIHByaW50ZigiWyVzXSBvZmZzZXQgJTA4eCwgc2l6ZSAlZCwgZGF0YSA9ICUwMnhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fRlVOQ1RJT05fXywgb2Zmc2V0LCBzaXplLCBkYXRhWzBdICk7CgogIC8qICovCiAgaWYgKCBmZF9udnJhbSA8IDAgKSB7CiAgICBmZF9udnJhbSA9IG9wZW4oVEFSR0VUX05WUkFNX01URCwgKE9fUkRXUiB8IE9fU1lOQykgKTsKICAgIGlmKCBmZF9udnJhbSA8IDAgKSB7CiAgICAgIHBlcnJvcihUQVJHRVRfTlZSQU1fTVREKTsKICAgICAgcmV0dXJuIC0xOwogICAgfQogIH0KCgogIHJldCA9IGxzZWVrKGZkX252cmFtLCBvZmZzZXQsIFNFRUtfU0VUKTsKICBpZihyZXQgPCAwKSB7CiAgICBwZXJyb3IoImxzZWVrIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICByZXQgPSByZWFkKGZkX252cmFtLCBkYXRhLCBzaXplKTsKICBpZihyZXQgPCAwKSB7CiAgICBwZXJyb3IoInJlYWQiKTsKICAgIHJldHVybiByZXQ7CiAgfQoKICByZXR1cm4gMDsKfQoKCi8qQH0qLwo=