LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAiZmNpbnQuaCIKI2luY2x1ZGUgPGZyZWV0eXBlL2ZyZWV0eXBlLmg+CiNpbmNsdWRlIDxmcmVldHlwZS9pbnRlcm5hbC9mdG9ianMuaD4KI2luY2x1ZGUgPGZyZWV0eXBlL3R0dGFibGVzLmg+CiNpbmNsdWRlIDxmb250Y29uZmlnL2ZjZnJlZXR5cGUuaD4KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgewogICAgaW50CSAgICBiaXQ7CiAgICBGY0NoYXI4ICpuYW1lOwp9IEZjQ29kZVBhZ2VSYW5nZVtdID0gewogICAgeyAwLAkoRmNDaGFyOCAqKSBGQ19MQU5HX0xBVElOXzEgfSwKICAgIHsgMSwJKEZjQ2hhcjggKikgRkNfTEFOR19MQVRJTl8yX0VBU1RFUk5fRVVST1BFIH0sCiAgICB7IDIsCShGY0NoYXI4ICopIEZDX0xBTkdfQ1lSSUxMSUMgfSwKICAgIHsgMywJKEZjQ2hhcjggKikgRkNfTEFOR19HUkVFSyB9LAogICAgeyA0LAkoRmNDaGFyOCAqKSBGQ19MQU5HX1RVUktJU0ggfSwKICAgIHsgNSwJKEZjQ2hhcjggKikgRkNfTEFOR19IRUJSRVcgfSwKICAgIHsgNiwJKEZjQ2hhcjggKikgRkNfTEFOR19BUkFCSUMgfSwKICAgIHsgNywJKEZjQ2hhcjggKikgRkNfTEFOR19XSU5ET1dTX0JBTFRJQyB9LAogICAgeyA4LAkoRmNDaGFyOCAqKSBGQ19MQU5HX1ZJRVROQU1FU0UgfSwKLyogOS0xNSByZXNlcnZlZCBmb3IgQWx0ZXJuYXRlIEFOU0kgKi8KICAgIHsgMTYsCShGY0NoYXI4ICopIEZDX0xBTkdfVEhBSSB9LAogICAgeyAxNywJKEZjQ2hhcjggKikgRkNfTEFOR19KQVBBTkVTRSB9LAogICAgeyAxOCwJKEZjQ2hhcjggKikgRkNfTEFOR19TSU1QTElGSUVEX0NISU5FU0UgfSwKICAgIHsgMTksCShGY0NoYXI4ICopIEZDX0xBTkdfS09SRUFOX1dBTlNVTkcgfSwKICAgIHsgMjAsCShGY0NoYXI4ICopIEZDX0xBTkdfVFJBRElUSU9OQUxfQ0hJTkVTRSB9LAogICAgeyAyMSwJKEZjQ2hhcjggKikgRkNfTEFOR19LT1JFQU5fSk9IQUIgfSwKLyogMjItMjggcmVzZXJ2ZWQgZm9yIEFsdGVybmF0ZSBBTlNJICYgT0VNICovCiAgICB7IDI5LAkoRmNDaGFyOCAqKSBGQ19MQU5HX01BQ0lOVE9TSCB9LAogICAgeyAzMCwJKEZjQ2hhcjggKikgRkNfTEFOR19PRU0gfSwKICAgIHsgMzEsCShGY0NoYXI4ICopIEZDX0xBTkdfU1lNQk9MIH0sCi8qIDMyLTQ3IHJlc2VydmVkIGZvciBPRU0gKi8KICAgIHsgNDgsCShGY0NoYXI4ICopIEZDX0xBTkdfSUJNX0dSRUVLIH0sCiAgICB7IDQ5LAkoRmNDaGFyOCAqKSBGQ19MQU5HX01TRE9TX1JVU1NJQU4gfSwKICAgIHsgNTAsCShGY0NoYXI4ICopIEZDX0xBTkdfTVNET1NfTk9SRElDIH0sCiAgICB7IDUxLAkoRmNDaGFyOCAqKSBGQ19MQU5HX0FSQUJJQ184NjQgfSwKICAgIHsgNTIsCShGY0NoYXI4ICopIEZDX0xBTkdfTVNET1NfQ0FOQURJQU5fRlJFTkNIIH0sCiAgICB7IDUzLAkoRmNDaGFyOCAqKSBGQ19MQU5HX0hFQlJFV184NjIgfSwKICAgIHsgNTQsCShGY0NoYXI4ICopIEZDX0xBTkdfTVNET1NfSUNFTEFORElDIH0sCiAgICB7IDU1LAkoRmNDaGFyOCAqKSBGQ19MQU5HX01TRE9TX1BPUlRVR1VFU0UgfSwKICAgIHsgNTYsCShGY0NoYXI4ICopIEZDX0xBTkdfSUJNX1RVUktJU0ggfSwKICAgIHsgNTcsCShGY0NoYXI4ICopIEZDX0xBTkdfSUJNX0NZUklMTElDIH0sCiAgICB7IDU4LAkoRmNDaGFyOCAqKSBGQ19MQU5HX0xBVElOXzIgfSwKICAgIHsgNTksCShGY0NoYXI4ICopIEZDX0xBTkdfTVNET1NfQkFMVElDIH0sCiAgICB7IDYwLAkoRmNDaGFyOCAqKSBGQ19MQU5HX0dSRUVLXzQzN19HIH0sCiAgICB7IDYxLAkoRmNDaGFyOCAqKSBGQ19MQU5HX0FSQUJJQ19BU01PXzcwOCB9LAogICAgeyA2MiwJKEZjQ2hhcjggKikgRkNfTEFOR19XRV9MQVRJTl8xIH0sCiAgICB7IDYzLAkoRmNDaGFyOCAqKSBGQ19MQU5HX1VTIH0sCn07CgojZGVmaW5lIE5VTV9DT0RFX1BBR0VfUkFOR0UgKHNpemVvZiBGY0NvZGVQYWdlUmFuZ2UgLyBzaXplb2YgRmNDb2RlUGFnZVJhbmdlWzBdKQoKRmNQYXR0ZXJuICoKRmNGcmVlVHlwZVF1ZXJ5IChjb25zdCBGY0NoYXI4CSpmaWxlLAoJCSBpbnQJCWlkLAoJCSBGY0JsYW5rcwkqYmxhbmtzLAoJCSBpbnQJCSpjb3VudCkKewogICAgRlRfRmFjZQkgICAgZmFjZTsKICAgIEZjUGF0dGVybgkgICAgKnBhdDsKICAgIGludAkJICAgIHNsYW50OwogICAgaW50CQkgICAgd2VpZ2h0OwogICAgaW50CQkgICAgaTsKICAgIEZjQ2hhclNldAkgICAgKmNzOwogICAgRlRfTGlicmFyeQkgICAgZnRMaWJyYXJ5OwogICAgY29uc3QgRmNDaGFyOCAgICpmYW1pbHk7CiAgICBUVF9PUzIJICAgICpvczI7CgogICAgaWYgKEZUX0luaXRfRnJlZVR5cGUgKCZmdExpYnJhcnkpKQoJcmV0dXJuIDA7CiAgICAKICAgIGlmIChGVF9OZXdfRmFjZSAoZnRMaWJyYXJ5LCAoY2hhciAqKSBmaWxlLCBpZCwgJmZhY2UpKQoJZ290byBiYWlsOwoKICAgICpjb3VudCA9IGZhY2UtPm51bV9mYWNlczsKCiAgICBwYXQgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIXBhdCkKCWdvdG8gYmFpbDA7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX09VVExJTkUsCgkJCSAgIChmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX1NDQUxBQkxFKSAhPSAwKSkKCWdvdG8gYmFpbDE7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX1NDQUxBQkxFLAoJCQkgICAoZmFjZS0+ZmFjZV9mbGFncyAmIEZUX0ZBQ0VfRkxBR19TQ0FMQUJMRSkgIT0gMCkpCglnb3RvIGJhaWwxOwoKCiAgICBzbGFudCA9IEZDX1NMQU5UX1JPTUFOOwogICAgaWYgKGZhY2UtPnN0eWxlX2ZsYWdzICYgRlRfU1RZTEVfRkxBR19JVEFMSUMpCglzbGFudCA9IEZDX1NMQU5UX0lUQUxJQzsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgRkNfU0xBTlQsIHNsYW50KSkKCWdvdG8gYmFpbDE7CgogICAgd2VpZ2h0ID0gRkNfV0VJR0hUX01FRElVTTsKICAgIGlmIChmYWNlLT5zdHlsZV9mbGFncyAmIEZUX1NUWUxFX0ZMQUdfQk9MRCkKCXdlaWdodCA9IEZDX1dFSUdIVF9CT0xEOwoKICAgIGlmICghRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0LCBGQ19XRUlHSFQsIHdlaWdodCkpCglnb3RvIGJhaWwxOwoKICAgIGZhbWlseSA9IChGY0NoYXI4ICopIGZhY2UtPmZhbWlseV9uYW1lOwogICAgaWYgKCFmYW1pbHkpCiAgICB7CglmYW1pbHkgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBmaWxlLCAnLycpOwoJaWYgKGZhbWlseSkKCSAgICBmYW1pbHkrKzsKCWVsc2UKCSAgICBmYW1pbHkgPSBmaWxlOwogICAgfQogICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfRkFNSUxZLCBmYW1pbHkpKQoJZ290byBiYWlsMTsKCiAgICBpZiAoZmFjZS0+c3R5bGVfbmFtZSkKICAgIHsKCWlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX1NUWUxFLCAoRmNDaGFyOCAqKSBmYWNlLT5zdHlsZV9uYW1lKSkKCSAgICBnb3RvIGJhaWwxOwogICAgfQoKICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX0ZJTEUsIGZpbGUpKQoJZ290byBiYWlsMTsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgRkNfSU5ERVgsIGlkKSkKCWdvdG8gYmFpbDE7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfU09VUkNFLCAoRmNDaGFyOCAqKSAiRnJlZVR5cGUiKSkKCWdvdG8gYmFpbDE7CgojaWYgMQogICAgaWYgKChmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX0ZJWEVEX1dJRFRIKSAhPSAwKQoJaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX1NQQUNJTkcsIEZDX01PTk8pKQoJICAgIGdvdG8gYmFpbDE7CiNlbmRpZgoKICAgIGNzID0gRmNGcmVlVHlwZUNoYXJTZXQgKGZhY2UsIGJsYW5rcyk7CiAgICBpZiAoIWNzKQoJZ290byBiYWlsMTsKCiAgICAvKgogICAgICogU2tpcCBvdmVyIFBDRiBmb250cyB0aGF0IGhhdmUgbm8gZW5jb2RlZCBjaGFyYWN0ZXJzOyB0aGV5J3JlCiAgICAgKiB1c3VhbGx5IGp1c3QgVW5pY29kZSBmb250cyB0cmFuc2NvZGVkIHRvIHNvbWUgbGVnYWN5IGVuY29kaW5nCiAgICAgKi8KICAgIGlmIChGY0NoYXJTZXRDb3VudCAoY3MpID09IDApCiAgICB7CglpZiAoIXN0cmNtcChGVF9NT0RVTEVfQ0xBU1MoJmZhY2UtPmRyaXZlci0+cm9vdCktPm1vZHVsZV9uYW1lLCAicGNmIikpCgkgICAgZ290byBiYWlsMjsKICAgIH0KCiAgICBpZiAoIUZjUGF0dGVybkFkZENoYXJTZXQgKHBhdCwgRkNfQ0hBUlNFVCwgY3MpKQoJZ290byBiYWlsMjsKICAgIC8qCiAgICAgKiBEcm9wIG91ciByZWZlcmVuY2UgdG8gdGhlIGNoYXJzZXQKICAgICAqLwogICAgRmNDaGFyU2V0RGVzdHJveSAoY3MpOwogICAgCiAgICBpZiAoIShmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX1NDQUxBQkxFKSkKICAgIHsKCWZvciAoaSA9IDA7IGkgPCBmYWNlLT5udW1fZml4ZWRfc2l6ZXM7IGkrKykKCSAgICBpZiAoIUZjUGF0dGVybkFkZERvdWJsZSAocGF0LCBGQ19QSVhFTF9TSVpFLAoJCQkJICAgICAoZG91YmxlKSBmYWNlLT5hdmFpbGFibGVfc2l6ZXNbaV0uaGVpZ2h0KSkKCQlnb3RvIGJhaWwxOwoJaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX0FOVElBTElBUywgRmNGYWxzZSkpCgkgICAgZ290byBiYWlsMTsKICAgIH0KCiAgICAvKgogICAgICogR2V0IHRoZSBPUy8yIHRhYmxlIGFuZCBwb2tlIGFib3V0CiAgICAgKi8KICAgIG9zMiA9IChUVF9PUzIgKikgRlRfR2V0X1NmbnRfVGFibGUgKGZhY2UsIGZ0X3NmbnRfb3MyKTsKICAgIGlmIChvczIgJiYgb3MyLT52ZXJzaW9uID49IDB4MDAwMSAmJiBvczItPnZlcnNpb24gIT0gMHhmZmZmKQogICAgewoJZm9yIChpID0gMDsgaSA8IE5VTV9DT0RFX1BBR0VfUkFOR0U7IGkrKykKCXsKCSAgICBGVF9VTG9uZwliaXRzOwoJICAgIGludAkJYml0OwoJICAgIGlmIChGY0NvZGVQYWdlUmFuZ2VbaV0uYml0IDwgMzIpCgkgICAgewoJCWJpdHMgPSBvczItPnVsQ29kZVBhZ2VSYW5nZTE7CgkJYml0ID0gRmNDb2RlUGFnZVJhbmdlW2ldLmJpdDsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQliaXRzID0gb3MyLT51bENvZGVQYWdlUmFuZ2UyOwoJCWJpdCA9IEZjQ29kZVBhZ2VSYW5nZVtpXS5iaXQgLSAzMjsKCSAgICB9CgkgICAgaWYgKGJpdHMgJiAoMSA8PCBiaXQpKQoJICAgIHsKCQlpZiAoIUZjUGF0dGVybkFkZFN0cmluZyAocGF0LCBGQ19MQU5HLAoJCQkJCSBGY0NvZGVQYWdlUmFuZ2VbaV0ubmFtZSkpCgkJICAgIGdvdG8gYmFpbDE7CgkgICAgfQoJfQogICAgfQoKICAgIEZUX0RvbmVfRmFjZSAoZmFjZSk7CiAgICBGVF9Eb25lX0ZyZWVUeXBlIChmdExpYnJhcnkpOwogICAgcmV0dXJuIHBhdDsKCmJhaWwyOgogICAgRmNDaGFyU2V0RGVzdHJveSAoY3MpOwpiYWlsMToKICAgIEZjUGF0dGVybkRlc3Ryb3kgKHBhdCk7CmJhaWwwOgogICAgRlRfRG9uZV9GYWNlIChmYWNlKTsKYmFpbDoKICAgIEZUX0RvbmVfRnJlZVR5cGUgKGZ0TGlicmFyeSk7CiAgICByZXR1cm4gMDsKfQo=