LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgImZjaW50LmgiCgpzdGF0aWMgc3RydWN0IHsKICAgIGNoYXIJKmZpZWxkOwogICAgRmNCb29sCXZhbHVlOwp9IEZjQm9vbERlZmF1bHRzW10gPSB7CiAgICB7IEZDX0hJTlRJTkcsCSAgICBGY1RydWUJfSwgIC8qICFGVF9MT0FEX05PX0hJTlRJTkcgKi8KICAgIHsgRkNfVkVSVElDQUxfTEFZT1VULCAgIEZjRmFsc2UJfSwgIC8qIEZDX0xPQURfVkVSVElDQUxfTEFZT1VUICovCiAgICB7IEZDX0FVVE9ISU5ULAkgICAgRmNGYWxzZQl9LCAgLyogRkNfTE9BRF9GT1JDRV9BVVRPSElOVCAqLwogICAgeyBGQ19HTE9CQUxfQURWQU5DRSwgICAgRmNUcnVlCX0sICAvKiAhRkNfTE9BRF9JR05PUkVfR0xPQkFMX0FEVkFOQ0VfV0lEVEggKi8KfTsKCiNkZWZpbmUgTlVNX0ZDX0JPT0xfREVGQVVMVFMJKHNpemVvZiBGY0Jvb2xEZWZhdWx0cyAvIHNpemVvZiBGY0Jvb2xEZWZhdWx0c1swXSkKCnZvaWQKRmNEZWZhdWx0U3Vic3RpdHV0ZSAoRmNQYXR0ZXJuICpwYXR0ZXJuKQp7CiAgICBGY1ZhbHVlIHY7CiAgICBpbnQJICAgIGk7CgogICAgaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfU1RZTEUsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCiAgICB7CglpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19XRUlHSFQsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2ggKQoJewoJICAgIEZjUGF0dGVybkFkZEludGVnZXIgKHBhdHRlcm4sIEZDX1dFSUdIVCwgRkNfV0VJR0hUX01FRElVTSk7Cgl9CglpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19TTEFOVCwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKCXsKCSAgICBGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXR0ZXJuLCBGQ19TTEFOVCwgRkNfU0xBTlRfUk9NQU4pOwoJfQogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fRkNfQk9PTF9ERUZBVUxUUzsgaSsrKQoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRmNCb29sRGVmYXVsdHNbaV0uZmllbGQsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCgkgICAgRmNQYXR0ZXJuQWRkQm9vbCAocGF0dGVybiwgRmNCb29sRGVmYXVsdHNbaV0uZmllbGQsIEZjQm9vbERlZmF1bHRzW2ldLnZhbHVlKTsKICAgIAogICAgaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfUElYRUxfU0laRSwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKICAgIHsKCWRvdWJsZQlkcGksIHNpemUsIHNjYWxlOwoKCWlmIChGY1BhdHRlcm5HZXREb3VibGUgKHBhdHRlcm4sIEZDX1NJWkUsIDAsICZzaXplKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIHNpemUgPSAxMi4wOwoJICAgICh2b2lkKSBGY1BhdHRlcm5EZWwgKHBhdHRlcm4sIEZDX1NJWkUpOwoJICAgIEZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfU0laRSwgc2l6ZSk7Cgl9CglpZiAoRmNQYXR0ZXJuR2V0RG91YmxlIChwYXR0ZXJuLCBGQ19TQ0FMRSwgMCwgJnNjYWxlKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIHNjYWxlID0gMS4wOwoJICAgICh2b2lkKSBGY1BhdHRlcm5EZWwgKHBhdHRlcm4sIEZDX1NDQUxFKTsKCSAgICBGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX1NDQUxFLCBzY2FsZSk7Cgl9CglzaXplICo9IHNjYWxlOwoJaWYgKEZjUGF0dGVybkdldERvdWJsZSAocGF0dGVybiwgRkNfRFBJLCAwLCAmZHBpKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIGRwaSA9IDc1LjA7CgkgICAgKHZvaWQpIEZjUGF0dGVybkRlbCAocGF0dGVybiwgRkNfRFBJKTsKCSAgICBGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX0RQSSwgZHBpKTsKCX0KCXNpemUgKj0gZHBpIC8gNzIuMDsKCUZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfUElYRUxfU0laRSwgc2l6ZSk7CiAgICB9Cn0K