Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDIwMDMgR2x5cGggJiBDb2csIExMQwovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gTW9kaWZpZWQgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCAtIGh0dHA6Ly9wb3BwbGVyLmZyZWVkZXNrdG9wLm9yZwovLwovLyBBbGwgY2hhbmdlcyBtYWRlIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgdG8gdGhpcyBmaWxlIGFyZSBsaWNlbnNlZAovLyB1bmRlciBHUEwgdmVyc2lvbiAyIG9yIGxhdGVyCi8vCi8vIENvcHlyaWdodCAoQykgMjAwNSBUYWthc2hpIEl3YWkgPHRpd2FpQHN1c2UuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAwOS0yMDE0IFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgQ2FybG9zIEdhcmNpYSBDYW1wb3MgPGNhcmxvc2djQGdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExIEFuZHJlYXMgSGFydG1ldHogPGFoYXJ0bWV0ekBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMSBBbmRyZWEgQ2FuY2lhbmkgPHJhbm1hNDJAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTEgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vCi8vIFRvIHNlZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHBsZWFzZSBzZWUgdGhlIENoYW5nZWxvZyBmaWxlIHRoYXQKLy8gY2FtZSB3aXRoIHlvdXIgdGFyYmFsbCBvciB0eXBlIG1ha2UgQ2hhbmdlTG9nIGlmIHlvdSBhcmUgYnVpbGRpbmcgZnJvbSBnaXQKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgU1BMQVNIT1VUUFVUREVWX0gKI2RlZmluZSBTUExBU0hPVVRQVVRERVZfSAoKI2lmZGVmIFVTRV9HQ0NfUFJBR01BUwojcHJhZ21hIGludGVyZmFjZQojZW5kaWYKCiNpbmNsdWRlICJnb28vZ3R5cGVzLmgiCiNpbmNsdWRlICJzcGxhc2gvU3BsYXNoVHlwZXMuaCIKI2luY2x1ZGUgInNwbGFzaC9TcGxhc2hQYXR0ZXJuLmgiCiNpbmNsdWRlICJwb3BwbGVyLWNvbmZpZy5oIgojaW5jbHVkZSAiT3V0cHV0RGV2LmgiCiNpbmNsdWRlICJHZnhTdGF0ZS5oIgojaW5jbHVkZSAiR2xvYmFsUGFyYW1zLmgiCgpjbGFzcyBQREZEb2M7CmNsYXNzIEdmeDhCaXRGb250OwpjbGFzcyBTcGxhc2hCaXRtYXA7CmNsYXNzIFNwbGFzaDsKY2xhc3MgU3BsYXNoUGF0aDsKY2xhc3MgU3BsYXNoRm9udEVuZ2luZTsKY2xhc3MgU3BsYXNoRm9udDsKY2xhc3MgVDNGb250Q2FjaGU7CnN0cnVjdCBUM0ZvbnRDYWNoZVRhZzsKc3RydWN0IFQzR2x5cGhTdGFjazsKc3RydWN0IFNwbGFzaFRyYW5zcGFyZW5jeUdyb3VwOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoIGR5bmFtaWMgcGF0dGVybgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm46IHB1YmxpYyBTcGxhc2hQYXR0ZXJuIHsKcHVibGljOgoKICBTcGxhc2hVbml2YXJpYXRlUGF0dGVybihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlLCBHZnhTdGF0ZSAqc3RhdGUsIEdmeFVuaXZhcmlhdGVTaGFkaW5nICpzaGFkaW5nKTsKCiAgdmlydHVhbCB+U3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4oKTsKCiAgdmlydHVhbCBHQm9vbCBnZXRDb2xvcihpbnQgeCwgaW50IHksIFNwbGFzaENvbG9yUHRyIGMpOwoKICB2aXJ0dWFsIEdCb29sIHRlc3RQb3NpdGlvbihpbnQgeCwgaW50IHkpOwoKICB2aXJ0dWFsIEdCb29sIGlzU3RhdGljKCkgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIHZpcnR1YWwgR0Jvb2wgZ2V0UGFyYW1ldGVyKGRvdWJsZSB4cywgZG91YmxlIHlzLCBkb3VibGUgKnQpID0gMDsKCiAgdmlydHVhbCBHZnhVbml2YXJpYXRlU2hhZGluZyAqZ2V0U2hhZGluZygpIHsgcmV0dXJuIHNoYWRpbmc7IH0KCiAgdmlydHVhbCBHQm9vbCBpc0NNWUsoKSB7IHJldHVybiBnZnhNb2RlID09IGNzRGV2aWNlQ01ZSzsgfQoKcHJvdGVjdGVkOgogIE1hdHJpeCBpY3RtOwogIGRvdWJsZSB0MCwgdDEsIGR0OwogIEdmeFVuaXZhcmlhdGVTaGFkaW5nICpzaGFkaW5nOwogIEdmeFN0YXRlICpzdGF0ZTsKICBTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlOwogIEdmeENvbG9yU3BhY2VNb2RlIGdmeE1vZGU7Cn07CgpjbGFzcyBTcGxhc2hBeGlhbFBhdHRlcm46IHB1YmxpYyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoQXhpYWxQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4QXhpYWxTaGFkaW5nICpzaGFkaW5nKTsKCiAgdmlydHVhbCBTcGxhc2hQYXR0ZXJuICpjb3B5KCkgeyByZXR1cm4gbmV3IFNwbGFzaEF4aWFsUGF0dGVybihjb2xvck1vZGUsIHN0YXRlLCAoR2Z4QXhpYWxTaGFkaW5nICopIHNoYWRpbmcpOyB9CgogIHZpcnR1YWwgflNwbGFzaEF4aWFsUGF0dGVybigpOwoKICB2aXJ0dWFsIEdCb29sIGdldFBhcmFtZXRlcihkb3VibGUgeHMsIGRvdWJsZSB5cywgZG91YmxlICp0KTsKCnByaXZhdGU6CiAgZG91YmxlIHgwLCB5MCwgeDEsIHkxOwogIGRvdWJsZSBkeCwgZHksIG11bDsKfTsKCi8vIHNlZSBHZnhTdGF0ZS5oLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nCmNsYXNzIFNwbGFzaEdvdXJhdWRQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoR291cmF1ZENvbG9yIHsKcHVibGljOgoKICBTcGxhc2hHb3VyYXVkUGF0dGVybihHQm9vbCBiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgR2Z4U3RhdGUgKnN0YXRlLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nLCBTcGxhc2hDb2xvck1vZGUgbW9kZSk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hHb3VyYXVkUGF0dGVybihiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgc3RhdGUsIHNoYWRpbmcsIG1vZGUpOyB9CgogIHZpcnR1YWwgflNwbGFzaEdvdXJhdWRQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0Q29sb3IoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBjKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCB0ZXN0UG9zaXRpb24oaW50IHgsIGludCB5KSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCBpc1N0YXRpYygpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICB2aXJ0dWFsIEdCb29sIGlzQ01ZSygpIHsgcmV0dXJuIGdmeE1vZGUgPT0gY3NEZXZpY2VDTVlLOyB9CgogIHZpcnR1YWwgR0Jvb2wgaXNQYXJhbWV0ZXJpemVkKCkgeyByZXR1cm4gc2hhZGluZy0+aXNQYXJhbWV0ZXJpemVkKCk7IH0KICB2aXJ0dWFsIGludCBnZXROVHJpYW5nbGVzKCkgeyByZXR1cm4gc2hhZGluZy0+Z2V0TlRyaWFuZ2xlcygpOyB9CiAgdmlydHVhbCAgdm9pZCBnZXRUcmlhbmdsZShpbnQgaSwgZG91YmxlICp4MCwgZG91YmxlICp5MCwgZG91YmxlICpjb2xvcjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgKngxLCBkb3VibGUgKnkxLCBkb3VibGUgKmNvbG9yMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSAqeDIsIGRvdWJsZSAqeTIsIGRvdWJsZSAqY29sb3IyKQogIHsgcmV0dXJuIHNoYWRpbmctPmdldFRyaWFuZ2xlKGksIHgwLCB5MCwgY29sb3IwLCB4MSwgeTEsIGNvbG9yMSwgeDIsIHkyLCBjb2xvcjIpOyB9CgogIHZpcnR1YWwgdm9pZCBnZXRQYXJhbWV0ZXJpemVkQ29sb3IoZG91YmxlIHQsIFNwbGFzaENvbG9yTW9kZSBtb2RlLCBTcGxhc2hDb2xvclB0ciBjKTsKCnByaXZhdGU6CiAgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZyAqc2hhZGluZzsKICBHZnhTdGF0ZSAqc3RhdGU7CiAgR0Jvb2wgYkRpcmVjdENvbG9yVHJhbnNsYXRpb247CiAgU3BsYXNoQ29sb3JNb2RlIG1vZGU7CiAgR2Z4Q29sb3JTcGFjZU1vZGUgZ2Z4TW9kZTsKfTsKCi8vIHNlZSBHZnhTdGF0ZS5oLCBHZnhSYWRpYWxTaGFkaW5nCmNsYXNzIFNwbGFzaFJhZGlhbFBhdHRlcm46IHB1YmxpYyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoUmFkaWFsUGF0dGVybihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlLCBHZnhTdGF0ZSAqc3RhdGUsIEdmeFJhZGlhbFNoYWRpbmcgKnNoYWRpbmcpOwoKICB2aXJ0dWFsIFNwbGFzaFBhdHRlcm4gKmNvcHkoKSB7IHJldHVybiBuZXcgU3BsYXNoUmFkaWFsUGF0dGVybihjb2xvck1vZGUsIHN0YXRlLCAoR2Z4UmFkaWFsU2hhZGluZyAqKSBzaGFkaW5nKTsgfQoKICB2aXJ0dWFsIH5TcGxhc2hSYWRpYWxQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0UGFyYW1ldGVyKGRvdWJsZSB4cywgZG91YmxlIHlzLCBkb3VibGUgKnQpOwoKcHJpdmF0ZToKICBkb3VibGUgeDAsIHkwLCByMCwgZHgsIGR5LCBkcjsKICBkb3VibGUgYSwgaW52YTsKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBudW1iZXIgb2YgVHlwZSAzIGZvbnRzIHRvIGNhY2hlCiNkZWZpbmUgc3BsYXNoT3V0VDNGb250Q2FjaGVTaXplIDgKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaE91dHB1dERldgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgU3BsYXNoT3V0cHV0RGV2OiBwdWJsaWMgT3V0cHV0RGV2IHsKcHVibGljOgoKICAvLyBDb25zdHJ1Y3Rvci4KICBTcGxhc2hPdXRwdXREZXYoU3BsYXNoQ29sb3JNb2RlIGNvbG9yTW9kZUEsIGludCBiaXRtYXBSb3dQYWRBLAoJCSAgR0Jvb2wgcmV2ZXJzZVZpZGVvQSwgU3BsYXNoQ29sb3JQdHIgcGFwZXJDb2xvckEsCgkJICBHQm9vbCBiaXRtYXBUb3BEb3duQSA9IGdUcnVlLAoJCSAgR0Jvb2wgYWxsb3dBbnRpYWxpYXNBID0gZ1RydWUsCgkJICBTcGxhc2hUaGluTGluZU1vZGUgdGhpbkxpbmVNb2RlID0gc3BsYXNoVGhpbkxpbmVEZWZhdWx0LAogICAgICBHQm9vbCBvdmVycHJpbnRQcmV2aWV3QSA9IGdsb2JhbFBhcmFtcy0+Z2V0T3ZlcnByaW50UHJldmlldygpKTsKCiAgLy8gRGVzdHJ1Y3Rvci4KICB2aXJ0dWFsIH5TcGxhc2hPdXRwdXREZXYoKTsKCiAgLy8tLS0tLSBnZXQgaW5mbyBhYm91dCBvdXRwdXQgZGV2aWNlCgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIHRpbGluZ1BhdHRlcm5GaWxsKCk/ICBJZiB0aGlzIHJldHVybnMgZmFsc2UsCiAgLy8gdGlsaW5nIHBhdHRlcm4gZmlsbHMgd2lsbCBiZSByZWR1Y2VkIHRvIGEgc2VyaWVzIG9mIG90aGVyIGRyYXdpbmcKICAvLyBvcGVyYXRpb25zLgogIHZpcnR1YWwgR0Jvb2wgdXNlVGlsaW5nUGF0dGVybkZpbGwoKSB7IHJldHVybiBnVHJ1ZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBmdW5jdGlvblNoYWRlZEZpbGwoKSwgYXhpYWxTaGFkZWRGaWxsKCksIGFuZAogIC8vIHJhZGlhbFNoYWRlZEZpbGwoKT8gIElmIHRoaXMgcmV0dXJucyBmYWxzZSwgdGhlc2Ugc2hhZGVkIGZpbGxzCiAgLy8gd2lsbCBiZSByZWR1Y2VkIHRvIGEgc2VyaWVzIG9mIG90aGVyIGRyYXdpbmcgb3BlcmF0aW9ucy4KICB2aXJ0dWFsIEdCb29sIHVzZVNoYWRlZEZpbGxzKGludCB0eXBlKQogIHsgcmV0dXJuICh0eXBlID49IDIgJiYgdHlwZSA8PSA1KSA/IGdUcnVlIDogZ0ZhbHNlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIHVwc2lkZS1kb3duIGNvb3JkaW5hdGVzPwogIC8vIChVcHNpZGUtZG93biBtZWFucyAoMCwwKSBpcyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBwYWdlLikKICB2aXJ0dWFsIEdCb29sIHVwc2lkZURvd24oKSB7IHJldHVybiBiaXRtYXBUb3BEb3duIF4gYml0bWFwVXBzaWRlRG93bjsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBkcmF3Q2hhcigpIG9yIGRyYXdTdHJpbmcoKT8KICB2aXJ0dWFsIEdCb29sIHVzZURyYXdDaGFyKCkgeyByZXR1cm4gZ1RydWU7IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgYmVnaW5UeXBlM0NoYXIvZW5kVHlwZTNDaGFyPyAgT3RoZXJ3aXNlLAogIC8vIHRleHQgaW4gVHlwZSAzIGZvbnRzIHdpbGwgYmUgZHJhd24gd2l0aCBkcmF3Q2hhci9kcmF3U3RyaW5nLgogIHZpcnR1YWwgR0Jvb2wgaW50ZXJwcmV0VHlwZTNDaGFycygpIHsgcmV0dXJuIGdUcnVlOyB9CgogIC8vLS0tLS0gaW5pdGlhbGl6YXRpb24gYW5kIGNvbnRyb2wKCiAgLy8gU3RhcnQgYSBwYWdlLgogIHZpcnR1YWwgdm9pZCBzdGFydFBhZ2UoaW50IHBhZ2VOdW0sIEdmeFN0YXRlICpzdGF0ZSwgWFJlZiAqeHJlZik7CgogIC8vIEVuZCBhIHBhZ2UuCiAgdmlydHVhbCB2b2lkIGVuZFBhZ2UoKTsKCiAgLy8tLS0tLSBzYXZlL3Jlc3RvcmUgZ3JhcGhpY3Mgc3RhdGUKICB2aXJ0dWFsIHZvaWQgc2F2ZVN0YXRlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHJlc3RvcmVTdGF0ZShHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHVwZGF0ZSBncmFwaGljcyBzdGF0ZQogIHZpcnR1YWwgdm9pZCB1cGRhdGVBbGwoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlQ1RNKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIG0xMSwgZG91YmxlIG0xMiwKCQkJIGRvdWJsZSBtMjEsIGRvdWJsZSBtMjIsIGRvdWJsZSBtMzEsIGRvdWJsZSBtMzIpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lRGFzaChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGbGF0bmVzcyhHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lSm9pbihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lQ2FwKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZU1pdGVyTGltaXQoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZVdpZHRoKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUFkanVzdChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsQ29sb3JTcGFjZShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VDb2xvclNwYWNlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxDb2xvcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VDb2xvcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVCbGVuZE1vZGUoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbE9wYWNpdHkoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlT3BhY2l0eShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsT3ZlcnByaW50KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZU92ZXJwcmludChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVPdmVycHJpbnRNb2RlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVRyYW5zZmVyKEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gdXBkYXRlIHRleHQgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRm9udChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHBhdGggcGFpbnRpbmcKICB2aXJ0dWFsIHZvaWQgc3Ryb2tlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGZpbGwoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZW9GaWxsKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCBHQm9vbCB0aWxpbmdQYXR0ZXJuRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeCAqZ2Z4LCBDYXRhbG9nICpjYXRhbG9nLCBPYmplY3QgKnN0ciwKCQkJCSAgZG91YmxlICpwbWF0LCBpbnQgcGFpbnRUeXBlLCBpbnQgdGlsaW5nVHlwZSwgRGljdCAqcmVzRGljdCwKCQkJCSAgZG91YmxlICptYXQsIGRvdWJsZSAqYmJveCwKCQkJCSAgaW50IHgwLCBpbnQgeTAsIGludCB4MSwgaW50IHkxLAoJCQkJICBkb3VibGUgeFN0ZXAsIGRvdWJsZSB5U3RlcCk7CiAgdmlydHVhbCBHQm9vbCBheGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhBeGlhbFNoYWRpbmcgKnNoYWRpbmcsIGRvdWJsZSB0TWluLCBkb3VibGUgdE1heCk7CiAgdmlydHVhbCBHQm9vbCByYWRpYWxTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4UmFkaWFsU2hhZGluZyAqc2hhZGluZywgZG91YmxlIHRNaW4sIGRvdWJsZSB0TWF4KTsKICB2aXJ0dWFsIEdCb29sIGdvdXJhdWRUcmlhbmdsZVNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nKTsKCiAgLy8tLS0tLSBwYXRoIGNsaXBwaW5nCiAgdmlydHVhbCB2b2lkIGNsaXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZW9DbGlwKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGNsaXBUb1N0cm9rZVBhdGgoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB0ZXh0IGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgZHJhd0NoYXIoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgeCwgZG91YmxlIHksCgkJCWRvdWJsZSBkeCwgZG91YmxlIGR5LAoJCQlkb3VibGUgb3JpZ2luWCwgZG91YmxlIG9yaWdpblksCgkJCUNoYXJDb2RlIGNvZGUsIGludCBuQnl0ZXMsIFVuaWNvZGUgKnUsIGludCB1TGVuKTsKICB2aXJ0dWFsIEdCb29sIGJlZ2luVHlwZTNDaGFyKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHgsIGRvdWJsZSB5LAoJCQkgICAgICAgZG91YmxlIGR4LCBkb3VibGUgZHksCgkJCSAgICAgICBDaGFyQ29kZSBjb2RlLCBVbmljb2RlICp1LCBpbnQgdUxlbik7CiAgdmlydHVhbCB2b2lkIGVuZFR5cGUzQ2hhcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBiZWdpblRleHRPYmplY3QoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZW5kVGV4dE9iamVjdChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIGltYWdlIGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgZHJhd0ltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEdCb29sIGludmVydCwKCQkJICAgICBHQm9vbCBpbnRlcnBvbGF0ZSwgR0Jvb2wgaW5saW5lSW1nKTsKICB2aXJ0dWFsIHZvaWQgc2V0U29mdE1hc2tGcm9tSW1hZ2VNYXNrKEdmeFN0YXRlICpzdGF0ZSwKCQkJCQlPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkJaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHQm9vbCBpbnZlcnQsCgkJCQkJR0Jvb2wgaW5saW5lSW1nLCBkb3VibGUgKmJhc2VNYXRyaXgpOwogIHZpcnR1YWwgdm9pZCB1bnNldFNvZnRNYXNrRnJvbUltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmFzZU1hdHJpeCk7CiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJIGludCB3aWR0aCwgaW50IGhlaWdodCwgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsCgkJCSBHQm9vbCBpbnRlcnBvbGF0ZSwgaW50ICptYXNrQ29sb3JzLCBHQm9vbCBpbmxpbmVJbWcpOwogIHZpcnR1YWwgdm9pZCBkcmF3TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCSAgICAgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJICAgICAgIEdCb29sIGludGVycG9sYXRlLAoJCQkgICAgICAgU3RyZWFtICptYXNrU3RyLCBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJICAgICAgIEdCb29sIG1hc2tJbnZlcnQsIEdCb29sIG1hc2tJbnRlcnBvbGF0ZSk7CiAgdmlydHVhbCB2b2lkIGRyYXdTb2Z0TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJCSAgIEdCb29sIGludGVycG9sYXRlLAoJCQkJICAgU3RyZWFtICptYXNrU3RyLAoJCQkJICAgaW50IG1hc2tXaWR0aCwgaW50IG1hc2tIZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICptYXNrQ29sb3JNYXAsCgkJCQkgICBHQm9vbCBtYXNrSW50ZXJwb2xhdGUpOwoKICAvLy0tLS0tIFR5cGUgMyBmb250IG9wZXJhdG9ycwogIHZpcnR1YWwgdm9pZCB0eXBlM0QwKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3kpOwogIHZpcnR1YWwgdm9pZCB0eXBlM0QxKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3ksCgkJICAgICAgIGRvdWJsZSBsbHgsIGRvdWJsZSBsbHksIGRvdWJsZSB1cngsIGRvdWJsZSB1cnkpOwoKICAvLy0tLS0tIHRyYW5zcGFyZW5jeSBncm91cHMgYW5kIHNvZnQgbWFza3MKICB2aXJ0dWFsIEdCb29sIGNoZWNrVHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBHQm9vbCBrbm9ja291dCk7CiAgdmlydHVhbCB2b2lkIGJlZ2luVHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgKmJib3gsCgkJCQkgICAgICBHZnhDb2xvclNwYWNlICpibGVuZGluZ0NvbG9yU3BhY2UsCgkJCQkgICAgICBHQm9vbCBpc29sYXRlZCwgR0Jvb2wga25vY2tvdXQsCgkJCQkgICAgICBHQm9vbCBmb3JTb2Z0TWFzayk7CiAgdmlydHVhbCB2b2lkIGVuZFRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHBhaW50VHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgKmJib3gpOwogIHZpcnR1YWwgdm9pZCBzZXRTb2Z0TWFzayhHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmJveCwgR0Jvb2wgYWxwaGEsCgkJCSAgIEZ1bmN0aW9uICp0cmFuc2ZlckZ1bmMsIEdmeENvbG9yICpiYWNrZHJvcENvbG9yKTsKICB2aXJ0dWFsIHZvaWQgY2xlYXJTb2Z0TWFzayhHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHNwZWNpYWwgYWNjZXNzCgogIC8vIENhbGxlZCB0byBpbmRpY2F0ZSB0aGF0IGEgbmV3IFBERiBkb2N1bWVudCBoYXMgYmVlbiBsb2FkZWQuCiAgdm9pZCBzdGFydERvYyhQREZEb2MgKmRvY0EpOwogCiAgdm9pZCBzZXRQYXBlckNvbG9yKFNwbGFzaENvbG9yUHRyIHBhcGVyQ29sb3JBKTsKCiAgR0Jvb2wgaXNSZXZlcnNlVmlkZW8oKSB7IHJldHVybiByZXZlcnNlVmlkZW87IH0KICB2b2lkIHNldFJldmVyc2VWaWRlbyhHQm9vbCByZXZlcnNlVmlkZW9BKSB7IHJldmVyc2VWaWRlbyA9IHJldmVyc2VWaWRlb0E7IH0KCiAgLy8gR2V0IHRoZSBiaXRtYXAgYW5kIGl0cyBzaXplLgogIFNwbGFzaEJpdG1hcCAqZ2V0Qml0bWFwKCkgeyByZXR1cm4gYml0bWFwOyB9CiAgaW50IGdldEJpdG1hcFdpZHRoKCk7CiAgaW50IGdldEJpdG1hcEhlaWdodCgpOwoKICAvLyBSZXR1cm5zIHRoZSBsYXN0IHJhc3Rlcml6ZWQgYml0bWFwLCB0cmFuc2ZlcnJpbmcgb3duZXJzaGlwIHRvIHRoZQogIC8vIGNhbGxlci4KICBTcGxhc2hCaXRtYXAgKnRha2VCaXRtYXAoKTsKCiAgLy8gU2V0IHRoaXMgZmxhZyB0byB0cnVlIHRvIGdlbmVyYXRlIGFuIHVwc2lkZS1kb3duIGJpdG1hcCAodXNlZnVsCiAgLy8gZm9yIFdpbmRvd3MgQk1QIGZpbGVzKS4KICB2b2lkIHNldEJpdG1hcFVwc2lkZURvd24oR0Jvb2wgZikgeyBiaXRtYXBVcHNpZGVEb3duID0gZjsgfQoKICAvLyBHZXQgdGhlIFNwbGFzaCBvYmplY3QuCiAgU3BsYXNoICpnZXRTcGxhc2goKSB7IHJldHVybiBzcGxhc2g7IH0KCiAgLy8gR2V0IHRoZSBtb2RpZmllZCByZWdpb24uCiAgdm9pZCBnZXRNb2RSZWdpb24oaW50ICp4TWluLCBpbnQgKnlNaW4sIGludCAqeE1heCwgaW50ICp5TWF4KTsKCiAgLy8gQ2xlYXIgdGhlIG1vZGlmaWVkIHJlZ2lvbi4KICB2b2lkIGNsZWFyTW9kUmVnaW9uKCk7CgogIFNwbGFzaEZvbnQgKmdldEN1cnJlbnRGb250KCkgeyByZXR1cm4gZm9udDsgfQoKICAvLyBJZiA8c2tpcFRleHRBPiBpcyB0cnVlLCBkb24ndCBkcmF3IGhvcml6b250YWwgdGV4dC4KICAvLyBJZiA8c2tpcFJvdGF0ZWRUZXh0QT4gaXMgdHJ1ZSwgZG9uJ3QgZHJhdyByb3RhdGVkIChub24taG9yaXpvbnRhbCkgdGV4dC4KICB2b2lkIHNldFNraXBUZXh0KEdCb29sIHNraXBIb3JpelRleHRBLCBHQm9vbCBza2lwUm90YXRlZFRleHRBKQogICAgeyBza2lwSG9yaXpUZXh0ID0gc2tpcEhvcml6VGV4dEE7IHNraXBSb3RhdGVkVGV4dCA9IHNraXBSb3RhdGVkVGV4dEE7IH0KCiAgaW50IGdldE5lc3RDb3VudCgpIHsgcmV0dXJuIG5lc3RDb3VudDsgfQoKI2lmIDEgLy9+dG1wOiB0dXJuIG9mZiBhbnRpLWFsaWFzaW5nIHRlbXBvcmFyaWx5CiAgdmlydHVhbCBHQm9vbCBnZXRWZWN0b3JBbnRpYWxpYXMoKTsKICB2aXJ0dWFsIHZvaWQgc2V0VmVjdG9yQW50aWFsaWFzKEdCb29sIHZhYSk7CiNlbmRpZgoKICB2b2lkIHNldEZyZWVUeXBlSGludGluZyhHQm9vbCBlbmFibGUsIEdCb29sIGVuYWJsZVNsaWdodEhpbnRpbmcpOwoKcHJvdGVjdGVkOgogIHZvaWQgZG9VcGRhdGVGb250KEdmeFN0YXRlICpzdGF0ZSk7Cgpwcml2YXRlOgogIEdCb29sIHVuaXZhcmlhdGVTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4gKnBhdHRlcm4sIGRvdWJsZSB0TWluLCBkb3VibGUgdE1heCk7CgogIHZvaWQgc2V0dXBTY3JlZW5QYXJhbXMoZG91YmxlIGhEUEksIGRvdWJsZSB2RFBJKTsKICBTcGxhc2hQYXR0ZXJuICpnZXRDb2xvcihHZnhHcmF5IGdyYXkpOwogIFNwbGFzaFBhdHRlcm4gKmdldENvbG9yKEdmeFJHQiAqcmdiKTsKI2lmIFNQTEFTSF9DTVlLCiAgU3BsYXNoUGF0dGVybiAqZ2V0Q29sb3IoR2Z4Q01ZSyAqY215ayk7CiAgU3BsYXNoUGF0dGVybiAqZ2V0Q29sb3IoR2Z4Q29sb3IgKmRldmljZU4pOwojZW5kaWYKICB2b2lkIHNldE92ZXJwcmludE1hc2soR2Z4Q29sb3JTcGFjZSAqY29sb3JTcGFjZSwgR0Jvb2wgb3ZlcnByaW50RmxhZywKCQkJaW50IG92ZXJwcmludE1vZGUsIEdmeENvbG9yICpzaW5nbGVDb2xvciwgR0Jvb2wgZ3JheUluZGV4ZWQgPSBnRmFsc2UpOwogIFNwbGFzaFBhdGggKmNvbnZlcnRQYXRoKEdmeFN0YXRlICpzdGF0ZSwgR2Z4UGF0aCAqcGF0aCwKCQkJICBHQm9vbCBkcm9wRW1wdHlTdWJwYXRocyk7CiAgdm9pZCBkcmF3VHlwZTNHbHlwaChHZnhTdGF0ZSAqc3RhdGUsIFQzRm9udENhY2hlICp0M0ZvbnQsCgkJICAgICAgVDNGb250Q2FjaGVUYWcgKnRhZywgR3VjaGFyICpkYXRhKTsKICBzdGF0aWMgR0Jvb2wgaW1hZ2VNYXNrU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGxpbmUpOwogIHN0YXRpYyBHQm9vbCBpbWFnZVNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBjb2xvckxpbmUsCgkJCUd1Y2hhciAqYWxwaGFMaW5lKTsKICBzdGF0aWMgR0Jvb2wgYWxwaGFJbWFnZVNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBsaW5lLAoJCQkgICAgIEd1Y2hhciAqYWxwaGFMaW5lKTsKICBzdGF0aWMgR0Jvb2wgbWFza2VkSW1hZ2VTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSwKCQkJICAgICAgR3VjaGFyICphbHBoYUxpbmUpOwogIHN0YXRpYyBHQm9vbCB0aWxpbmdCaXRtYXBTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSwKCQkJICAgICBHdWNoYXIgKmFscGhhTGluZSk7CgogIEdCb29sIGtlZXBBbHBoYUNoYW5uZWw7CS8vIGRvbid0IGZpbGwgd2l0aCBwYXBlciBjb2xvciwga2VlcCBhbHBoYSBjaGFubmVsCgogIFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGU7CiAgaW50IGJpdG1hcFJvd1BhZDsKICBHQm9vbCBiaXRtYXBUb3BEb3duOwogIEdCb29sIGJpdG1hcFVwc2lkZURvd247CiAgR0Jvb2wgYWxsb3dBbnRpYWxpYXM7CiAgR0Jvb2wgdmVjdG9yQW50aWFsaWFzOwogIEdCb29sIG92ZXJwcmludFByZXZpZXc7CiAgR0Jvb2wgZW5hYmxlRnJlZVR5cGVIaW50aW5nOwogIEdCb29sIGVuYWJsZVNsaWdodEhpbnRpbmc7CiAgR0Jvb2wgcmV2ZXJzZVZpZGVvOwkJLy8gcmV2ZXJzZSB2aWRlbyBtb2RlCiAgU3BsYXNoQ29sb3IgcGFwZXJDb2xvcjsJLy8gcGFwZXIgY29sb3IKICBTcGxhc2hTY3JlZW5QYXJhbXMgc2NyZWVuUGFyYW1zOwogIEdCb29sIHNraXBIb3JpelRleHQ7CiAgR0Jvb2wgc2tpcFJvdGF0ZWRUZXh0OwoKICBQREZEb2MgKmRvYzsJCQkvLyB0aGUgY3VycmVudCBkb2N1bWVudAogIFhSZWYgKnhyZWY7ICAgICAgIC8vIHRoZSB4cmVmIG9mIHRoZSBjdXJyZW50IGRvY3VtZW50CgogIFNwbGFzaEJpdG1hcCAqYml0bWFwOwogIFNwbGFzaCAqc3BsYXNoOwogIFNwbGFzaEZvbnRFbmdpbmUgKmZvbnRFbmdpbmU7CgogIFQzRm9udENhY2hlICoJCQkvLyBUeXBlIDMgZm9udCBjYWNoZQogICAgdDNGb250Q2FjaGVbc3BsYXNoT3V0VDNGb250Q2FjaGVTaXplXTsKICBpbnQgblQzRm9udHM7CQkJLy8gbnVtYmVyIG9mIHZhbGlkIGVudHJpZXMgaW4gdDNGb250Q2FjaGUKICBUM0dseXBoU3RhY2sgKnQzR2x5cGhTdGFjazsJLy8gVHlwZSAzIGdseXBoIGNvbnRleHQgc3RhY2sKICBHQm9vbCBoYXZlVDNEeDsJCS8vIHNldCBhZnRlciBzZWVpbmcgYSBkMC9kMSBvcGVyYXRvcgoKICBTcGxhc2hGb250ICpmb250OwkJLy8gY3VycmVudCBmb250CiAgR0Jvb2wgbmVlZEZvbnRVcGRhdGU7CQkvLyBzZXQgd2hlbiB0aGUgZm9udCBuZWVkcyB0byBiZSB1cGRhdGVkCiAgU3BsYXNoUGF0aCAqdGV4dENsaXBQYXRoOwkvLyBjbGlwcGluZyBwYXRoIGJ1aWx0IHdpdGggdGV4dCBvYmplY3QKCiAgU3BsYXNoVHJhbnNwYXJlbmN5R3JvdXAgKgkvLyB0cmFuc3BhcmVuY3kgZ3JvdXAgc3RhY2sKICAgIHRyYW5zcEdyb3VwU3RhY2s7CiAgU3BsYXNoQml0bWFwICptYXNrQml0bWFwOyAvLyBmb3IgaW1hZ2UgbWFza3MgaW4gcGF0dGVybiBjb2xvcnNwYWNlCiAgaW50IG5lc3RDb3VudDsKfTsKCiNlbmRpZgo=