LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNkZWZhdWx0LmMsdiAxLjIgMjAwMi8wNy8wOSAyMjowODoxNCBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKI2luY2x1ZGUgPGxvY2FsZS5oPgoKc3RhdGljIHN0cnVjdCB7CiAgICBjaGFyCSpmaWVsZDsKICAgIEZjQm9vbAl2YWx1ZTsKfSBGY0Jvb2xEZWZhdWx0c1tdID0gewogICAgeyBGQ19ISU5USU5HLAkgICAgRmNUcnVlCX0sICAvKiAhRlRfTE9BRF9OT19ISU5USU5HICovCiAgICB7IEZDX1ZFUlRJQ0FMX0xBWU9VVCwgICBGY0ZhbHNlCX0sICAvKiBGQ19MT0FEX1ZFUlRJQ0FMX0xBWU9VVCAqLwogICAgeyBGQ19BVVRPSElOVCwJICAgIEZjRmFsc2UJfSwgIC8qIEZDX0xPQURfRk9SQ0VfQVVUT0hJTlQgKi8KICAgIHsgRkNfR0xPQkFMX0FEVkFOQ0UsICAgIEZjVHJ1ZQl9LCAgLyogIUZDX0xPQURfSUdOT1JFX0dMT0JBTF9BRFZBTkNFX1dJRFRIICovCn07CgojZGVmaW5lIE5VTV9GQ19CT09MX0RFRkFVTFRTCShzaXplb2YgRmNCb29sRGVmYXVsdHMgLyBzaXplb2YgRmNCb29sRGVmYXVsdHNbMF0pCgp2b2lkCkZjRGVmYXVsdFN1YnN0aXR1dGUgKEZjUGF0dGVybiAqcGF0dGVybikKewogICAgRmNWYWx1ZSB2OwogICAgaW50CSAgICBpOwoKICAgIGlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX1NUWUxFLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQogICAgewoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfV0VJR0hULCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoICkKCXsKCSAgICBGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXR0ZXJuLCBGQ19XRUlHSFQsIEZDX1dFSUdIVF9NRURJVU0pOwoJfQoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfU0xBTlQsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCgl7CgkgICAgRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0dGVybiwgRkNfU0xBTlQsIEZDX1NMQU5UX1JPTUFOKTsKCX0KICAgIH0KCiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19XSURUSCwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKCUZjUGF0dGVybkFkZEludGVnZXIgKHBhdHRlcm4sIEZDX1dJRFRILCBGQ19XSURUSF9OT1JNQUwpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fRkNfQk9PTF9ERUZBVUxUUzsgaSsrKQoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRmNCb29sRGVmYXVsdHNbaV0uZmllbGQsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCgkgICAgRmNQYXR0ZXJuQWRkQm9vbCAocGF0dGVybiwgRmNCb29sRGVmYXVsdHNbaV0uZmllbGQsIEZjQm9vbERlZmF1bHRzW2ldLnZhbHVlKTsKICAgIAogICAgaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfUElYRUxfU0laRSwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKICAgIHsKCWRvdWJsZQlkcGksIHNpemUsIHNjYWxlOwoKCWlmIChGY1BhdHRlcm5HZXREb3VibGUgKHBhdHRlcm4sIEZDX1NJWkUsIDAsICZzaXplKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIHNpemUgPSAxMi4wOwoJICAgICh2b2lkKSBGY1BhdHRlcm5EZWwgKHBhdHRlcm4sIEZDX1NJWkUpOwoJICAgIEZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfU0laRSwgc2l6ZSk7Cgl9CglpZiAoRmNQYXR0ZXJuR2V0RG91YmxlIChwYXR0ZXJuLCBGQ19TQ0FMRSwgMCwgJnNjYWxlKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIHNjYWxlID0gMS4wOwoJICAgICh2b2lkKSBGY1BhdHRlcm5EZWwgKHBhdHRlcm4sIEZDX1NDQUxFKTsKCSAgICBGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX1NDQUxFLCBzY2FsZSk7Cgl9CglzaXplICo9IHNjYWxlOwoJaWYgKEZjUGF0dGVybkdldERvdWJsZSAocGF0dGVybiwgRkNfRFBJLCAwLCAmZHBpKSAhPSBGY1Jlc3VsdE1hdGNoKQoJewoJICAgIGRwaSA9IDc1LjA7CgkgICAgKHZvaWQpIEZjUGF0dGVybkRlbCAocGF0dGVybiwgRkNfRFBJKTsKCSAgICBGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX0RQSSwgZHBpKTsKCX0KCXNpemUgKj0gZHBpIC8gNzIuMDsKCUZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfUElYRUxfU0laRSwgc2l6ZSk7CiAgICB9CgogICAgaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfTEFORywgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKICAgIHsKCWNoYXIJKmxhbmc7CgljaGFyCSp0ZXJyaXRvcnk7CgljaGFyCSphZnRlcjsKCWludAlsYW5nX2xlbiwgdGVycml0b3J5X2xlbjsKCWNoYXIJbGFuZ19sb2NhbFsxMjhdOwoJY2hhcgkqY3R5cGUgPSBzZXRsb2NhbGUgKExDX0NUWVBFLCBOVUxMKTsKCgkvKgoJICogQ2hlY2sgaWYgc2V0bG9jYWxlIChMQ19BTEwsICIiKSBoYXMgYmVlbiBjYWxsZWQKCSAqLwoJaWYgKCFjdHlwZSB8fCAhc3RyY21wIChjdHlwZSwgIkMiKSkKCXsKCSAgICBjdHlwZSA9IGdldGVudiAoIkxDX0FMTCIpOwoJICAgIGlmICghY3R5cGUpCgkgICAgewoJCWN0eXBlID0gZ2V0ZW52ICgiTENfQ1RZUEUiKTsKCQlpZiAoIWN0eXBlKQoJCSAgICBjdHlwZSA9IGdldGVudiAoIkxBTkciKTsKCSAgICB9Cgl9CglpZiAoY3R5cGUpCgl7CgkgICAgbGFuZyA9IGN0eXBlOwoJICAgIHRlcnJpdG9yeSA9IHN0cmNociAoY3R5cGUsICdfJyk7CgkgICAgaWYgKHRlcnJpdG9yeSkKCSAgICB7CgkJbGFuZ19sZW4gPSB0ZXJyaXRvcnkgLSBsYW5nOwoJCXRlcnJpdG9yeSA9IHRlcnJpdG9yeSArIDE7CgkJYWZ0ZXIgPSBzdHJjaHIgKHRlcnJpdG9yeSwgJy4nKTsKCQlpZiAoIWFmdGVyKQoJCXsKCQkgICAgYWZ0ZXIgPSBzdHJjaHIgKHRlcnJpdG9yeSwgJ0AnKTsKCQkgICAgaWYgKCFhZnRlcikKCQkJYWZ0ZXIgPSB0ZXJyaXRvcnkgKyBzdHJsZW4gKHRlcnJpdG9yeSk7CgkJfQoJCXRlcnJpdG9yeV9sZW4gPSBhZnRlciAtIHRlcnJpdG9yeTsKCQlpZiAobGFuZ19sZW4gKyAxICsgdGVycml0b3J5X2xlbiArIDEgPD0gc2l6ZW9mIChsYW5nX2xvY2FsKSkKCQl7CgkJICAgIHN0cm5jcHkgKGxhbmdfbG9jYWwsIGxhbmcsIGxhbmdfbGVuKTsKCQkgICAgbGFuZ19sb2NhbFtsYW5nX2xlbl0gPSAnLSc7CgkJICAgIHN0cm5jcHkgKGxhbmdfbG9jYWwgKyBsYW5nX2xlbiArIDEsIHRlcnJpdG9yeSwgdGVycml0b3J5X2xlbik7CgkJICAgIGxhbmdfbG9jYWxbbGFuZ19sZW4gKyAxICsgdGVycml0b3J5X2xlbl0gPSAnXDAnOwoJCSAgICBGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdHRlcm4sIEZDX0xBTkcsIChGY0NoYXI4ICopIGxhbmdfbG9jYWwpOwoJCX0KCSAgICB9CgkgICAgZWxzZQoJCUZjUGF0dGVybkFkZFN0cmluZyAocGF0dGVybiwgRkNfTEFORywgKEZjQ2hhcjggKikgbGFuZyk7Cgl9CiAgICB9CiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19GT05UVkVSU0lPTiwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKICAgIHsKCUZjUGF0dGVybkFkZEludGVnZXIgKHBhdHRlcm4sIEZDX0ZPTlRWRVJTSU9OLCAweDdmZmZmZmZmKTsKICAgIH0KCiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19ISU5UX1NUWUxFLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQogICAgewoJRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0dGVybiwgRkNfSElOVF9TVFlMRSwgRkNfSElOVF9GVUxMKTsKICAgIH0KfQo=