Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDIwMDMgR2x5cGggJiBDb2csIExMQwovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gTW9kaWZpZWQgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCAtIGh0dHA6Ly9wb3BwbGVyLmZyZWVkZXNrdG9wLm9yZwovLwovLyBBbGwgY2hhbmdlcyBtYWRlIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgdG8gdGhpcyBmaWxlIGFyZSBsaWNlbnNlZAovLyB1bmRlciBHUEwgdmVyc2lvbiAyIG9yIGxhdGVyCi8vCi8vIENvcHlyaWdodCAoQykgMjAwNSBUYWthc2hpIEl3YWkgPHRpd2FpQHN1c2UuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAwOS0yMDEyIFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgQ2FybG9zIEdhcmNpYSBDYW1wb3MgPGNhcmxvc2djQGdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExIEFuZHJlYXMgSGFydG1ldHogPGFoYXJ0bWV0ekBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMSBBbmRyZWEgQ2FuY2lhbmkgPHJhbm1hNDJAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTEgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLwovLyBUbyBzZWUgYSBkZXNjcmlwdGlvbiBvZiB0aGUgY2hhbmdlcyBwbGVhc2Ugc2VlIHRoZSBDaGFuZ2Vsb2cgZmlsZSB0aGF0Ci8vIGNhbWUgd2l0aCB5b3VyIHRhcmJhbGwgb3IgdHlwZSBtYWtlIENoYW5nZUxvZyBpZiB5b3UgYXJlIGJ1aWxkaW5nIGZyb20gZ2l0Ci8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZuZGVmIFNQTEFTSE9VVFBVVERFVl9ICiNkZWZpbmUgU1BMQVNIT1VUUFVUREVWX0gKCiNpZmRlZiBVU0VfR0NDX1BSQUdNQVMKI3ByYWdtYSBpbnRlcmZhY2UKI2VuZGlmCgojaW5jbHVkZSAiZ29vL2d0eXBlcy5oIgojaW5jbHVkZSAic3BsYXNoL1NwbGFzaFR5cGVzLmgiCiNpbmNsdWRlICJzcGxhc2gvU3BsYXNoUGF0dGVybi5oIgojaW5jbHVkZSAicG9wcGxlci1jb25maWcuaCIKI2luY2x1ZGUgIk91dHB1dERldi5oIgojaW5jbHVkZSAiR2Z4U3RhdGUuaCIKCmNsYXNzIFBERkRvYzsKY2xhc3MgR2Z4OEJpdEZvbnQ7CmNsYXNzIFNwbGFzaEJpdG1hcDsKY2xhc3MgU3BsYXNoOwpjbGFzcyBTcGxhc2hQYXRoOwpjbGFzcyBTcGxhc2hGb250RW5naW5lOwpjbGFzcyBTcGxhc2hGb250OwpjbGFzcyBUM0ZvbnRDYWNoZTsKc3RydWN0IFQzRm9udENhY2hlVGFnOwpzdHJ1Y3QgVDNHbHlwaFN0YWNrOwpzdHJ1Y3QgU3BsYXNoVHJhbnNwYXJlbmN5R3JvdXA7CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTcGxhc2ggZHluYW1pYyBwYXR0ZXJuCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybjogcHVibGljIFNwbGFzaFBhdHRlcm4gewpwdWJsaWM6CgogIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4VW5pdmFyaWF0ZVNoYWRpbmcgKnNoYWRpbmcpOwoKICB2aXJ0dWFsIH5TcGxhc2hVbml2YXJpYXRlUGF0dGVybigpOwoKICB2aXJ0dWFsIEdCb29sIGdldENvbG9yKGludCB4LCBpbnQgeSwgU3BsYXNoQ29sb3JQdHIgYyk7CgogIHZpcnR1YWwgR0Jvb2wgdGVzdFBvc2l0aW9uKGludCB4LCBpbnQgeSk7CgogIHZpcnR1YWwgR0Jvb2wgaXNTdGF0aWMoKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCBnZXRQYXJhbWV0ZXIoZG91YmxlIHhzLCBkb3VibGUgeXMsIGRvdWJsZSAqdCkgPSAwOwoKICB2aXJ0dWFsIEdmeFVuaXZhcmlhdGVTaGFkaW5nICpnZXRTaGFkaW5nKCkgeyByZXR1cm4gc2hhZGluZzsgfQoKcHJvdGVjdGVkOgogIE1hdHJpeCBpY3RtOwogIGRvdWJsZSB0MCwgdDEsIGR0OwogIEdmeFVuaXZhcmlhdGVTaGFkaW5nICpzaGFkaW5nOwogIEdmeFN0YXRlICpzdGF0ZTsKICBTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlOwp9OwoKY2xhc3MgU3BsYXNoQXhpYWxQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4gewpwdWJsaWM6CgogIFNwbGFzaEF4aWFsUGF0dGVybihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlLCBHZnhTdGF0ZSAqc3RhdGUsIEdmeEF4aWFsU2hhZGluZyAqc2hhZGluZyk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hBeGlhbFBhdHRlcm4oY29sb3JNb2RlLCBzdGF0ZSwgKEdmeEF4aWFsU2hhZGluZyAqKSBzaGFkaW5nKTsgfQoKICB2aXJ0dWFsIH5TcGxhc2hBeGlhbFBhdHRlcm4oKTsKCiAgdmlydHVhbCBHQm9vbCBnZXRQYXJhbWV0ZXIoZG91YmxlIHhzLCBkb3VibGUgeXMsIGRvdWJsZSAqdCk7Cgpwcml2YXRlOgogIGRvdWJsZSB4MCwgeTAsIHgxLCB5MTsKICBkb3VibGUgZHgsIGR5LCBtdWw7Cn07CgovLyBzZWUgR2Z4U3RhdGUuaCwgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZwpjbGFzcyBTcGxhc2hHb3VyYXVkUGF0dGVybjogcHVibGljIFNwbGFzaEdvdXJhdWRDb2xvciB7CnB1YmxpYzoKCiAgU3BsYXNoR291cmF1ZFBhdHRlcm4oR0Jvb2wgYkRpcmVjdENvbG9yVHJhbnNsYXRpb24sIEdmeFN0YXRlICpzdGF0ZSwgR2Z4R291cmF1ZFRyaWFuZ2xlU2hhZGluZyAqc2hhZGluZywgU3BsYXNoQ29sb3JNb2RlIG1vZGUpOwoKICB2aXJ0dWFsIFNwbGFzaFBhdHRlcm4gKmNvcHkoKSB7IHJldHVybiBuZXcgU3BsYXNoR291cmF1ZFBhdHRlcm4oYkRpcmVjdENvbG9yVHJhbnNsYXRpb24sIHN0YXRlLCBzaGFkaW5nLCBtb2RlKTsgfQoKICB2aXJ0dWFsIH5TcGxhc2hHb3VyYXVkUGF0dGVybigpOwoKICB2aXJ0dWFsIEdCb29sIGdldENvbG9yKGludCB4LCBpbnQgeSwgU3BsYXNoQ29sb3JQdHIgYykgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIHZpcnR1YWwgR0Jvb2wgdGVzdFBvc2l0aW9uKGludCB4LCBpbnQgeSkgeyByZXR1cm4gZ0ZhbHNlOyB9CgogIHZpcnR1YWwgR0Jvb2wgaXNTdGF0aWMoKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCBpc1BhcmFtZXRlcml6ZWQoKSB7IHJldHVybiBzaGFkaW5nLT5pc1BhcmFtZXRlcml6ZWQoKTsgfQogIHZpcnR1YWwgaW50IGdldE5UcmlhbmdsZXMoKSB7IHJldHVybiBzaGFkaW5nLT5nZXROVHJpYW5nbGVzKCk7IH0KICB2aXJ0dWFsICB2b2lkIGdldFRyaWFuZ2xlKGludCBpLCBkb3VibGUgKngwLCBkb3VibGUgKnkwLCBkb3VibGUgKmNvbG9yMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSAqeDEsIGRvdWJsZSAqeTEsIGRvdWJsZSAqY29sb3IxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlICp4MiwgZG91YmxlICp5MiwgZG91YmxlICpjb2xvcjIpCiAgeyByZXR1cm4gc2hhZGluZy0+Z2V0VHJpYW5nbGUoaSwgeDAsIHkwLCBjb2xvcjAsIHgxLCB5MSwgY29sb3IxLCB4MiwgeTIsIGNvbG9yMik7IH0KCiAgdmlydHVhbCB2b2lkIGdldFBhcmFtZXRlcml6ZWRDb2xvcihkb3VibGUgdCwgU3BsYXNoQ29sb3JNb2RlIG1vZGUsIFNwbGFzaENvbG9yUHRyIGMpOwoKcHJpdmF0ZToKICBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nOwogIEdmeFN0YXRlICpzdGF0ZTsKICBHQm9vbCBiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbjsKICBTcGxhc2hDb2xvck1vZGUgbW9kZTsKfTsKCi8vIHNlZSBHZnhTdGF0ZS5oLCBHZnhSYWRpYWxTaGFkaW5nCmNsYXNzIFNwbGFzaFJhZGlhbFBhdHRlcm46IHB1YmxpYyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoUmFkaWFsUGF0dGVybihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlLCBHZnhTdGF0ZSAqc3RhdGUsIEdmeFJhZGlhbFNoYWRpbmcgKnNoYWRpbmcpOwoKICB2aXJ0dWFsIFNwbGFzaFBhdHRlcm4gKmNvcHkoKSB7IHJldHVybiBuZXcgU3BsYXNoUmFkaWFsUGF0dGVybihjb2xvck1vZGUsIHN0YXRlLCAoR2Z4UmFkaWFsU2hhZGluZyAqKSBzaGFkaW5nKTsgfQoKICB2aXJ0dWFsIH5TcGxhc2hSYWRpYWxQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0UGFyYW1ldGVyKGRvdWJsZSB4cywgZG91YmxlIHlzLCBkb3VibGUgKnQpOwoKcHJpdmF0ZToKICBkb3VibGUgeDAsIHkwLCByMCwgZHgsIGR5LCBkcjsKICBkb3VibGUgYSwgaW52YTsKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBudW1iZXIgb2YgVHlwZSAzIGZvbnRzIHRvIGNhY2hlCiNkZWZpbmUgc3BsYXNoT3V0VDNGb250Q2FjaGVTaXplIDgKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaE91dHB1dERldgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgU3BsYXNoT3V0cHV0RGV2OiBwdWJsaWMgT3V0cHV0RGV2IHsKcHVibGljOgoKICAvLyBDb25zdHJ1Y3Rvci4KICBTcGxhc2hPdXRwdXREZXYoU3BsYXNoQ29sb3JNb2RlIGNvbG9yTW9kZUEsIGludCBiaXRtYXBSb3dQYWRBLAoJCSAgR0Jvb2wgcmV2ZXJzZVZpZGVvQSwgU3BsYXNoQ29sb3JQdHIgcGFwZXJDb2xvckEsCgkJICBHQm9vbCBiaXRtYXBUb3BEb3duQSA9IGdUcnVlLAoJCSAgR0Jvb2wgYWxsb3dBbnRpYWxpYXNBID0gZ1RydWUpOwoKICAvLyBEZXN0cnVjdG9yLgogIHZpcnR1YWwgflNwbGFzaE91dHB1dERldigpOwoKICAvLy0tLS0tIGdldCBpbmZvIGFib3V0IG91dHB1dCBkZXZpY2UKCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgdGlsaW5nUGF0dGVybkZpbGwoKT8gIElmIHRoaXMgcmV0dXJucyBmYWxzZSwKICAvLyB0aWxpbmcgcGF0dGVybiBmaWxscyB3aWxsIGJlIHJlZHVjZWQgdG8gYSBzZXJpZXMgb2Ygb3RoZXIgZHJhd2luZwogIC8vIG9wZXJhdGlvbnMuCiAgdmlydHVhbCBHQm9vbCB1c2VUaWxpbmdQYXR0ZXJuRmlsbCgpIHsgcmV0dXJuIGdUcnVlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGZ1bmN0aW9uU2hhZGVkRmlsbCgpLCBheGlhbFNoYWRlZEZpbGwoKSwgYW5kCiAgLy8gcmFkaWFsU2hhZGVkRmlsbCgpPyAgSWYgdGhpcyByZXR1cm5zIGZhbHNlLCB0aGVzZSBzaGFkZWQgZmlsbHMKICAvLyB3aWxsIGJlIHJlZHVjZWQgdG8gYSBzZXJpZXMgb2Ygb3RoZXIgZHJhd2luZyBvcGVyYXRpb25zLgogIHZpcnR1YWwgR0Jvb2wgdXNlU2hhZGVkRmlsbHMoaW50IHR5cGUpCiAgeyByZXR1cm4gKHR5cGUgPj0gMiAmJiB0eXBlIDw9IDUpID8gZ1RydWUgOiBnRmFsc2U7IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgdXBzaWRlLWRvd24gY29vcmRpbmF0ZXM/CiAgLy8gKFVwc2lkZS1kb3duIG1lYW5zICgwLDApIGlzIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIHBhZ2UuKQogIHZpcnR1YWwgR0Jvb2wgdXBzaWRlRG93bigpIHsgcmV0dXJuIGJpdG1hcFRvcERvd24gXiBiaXRtYXBVcHNpZGVEb3duOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGRyYXdDaGFyKCkgb3IgZHJhd1N0cmluZygpPwogIHZpcnR1YWwgR0Jvb2wgdXNlRHJhd0NoYXIoKSB7IHJldHVybiBnVHJ1ZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSBiZWdpblR5cGUzQ2hhci9lbmRUeXBlM0NoYXI/ICBPdGhlcndpc2UsCiAgLy8gdGV4dCBpbiBUeXBlIDMgZm9udHMgd2lsbCBiZSBkcmF3biB3aXRoIGRyYXdDaGFyL2RyYXdTdHJpbmcuCiAgdmlydHVhbCBHQm9vbCBpbnRlcnByZXRUeXBlM0NoYXJzKCkgeyByZXR1cm4gZ1RydWU7IH0KCiAgLy8tLS0tLSBpbml0aWFsaXphdGlvbiBhbmQgY29udHJvbAoKICAvLyBTdGFydCBhIHBhZ2UuCiAgdmlydHVhbCB2b2lkIHN0YXJ0UGFnZShpbnQgcGFnZU51bSwgR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8gRW5kIGEgcGFnZS4KICB2aXJ0dWFsIHZvaWQgZW5kUGFnZSgpOwoKICAvLy0tLS0tIHNhdmUvcmVzdG9yZSBncmFwaGljcyBzdGF0ZQogIHZpcnR1YWwgdm9pZCBzYXZlU3RhdGUoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgcmVzdG9yZVN0YXRlKEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gdXBkYXRlIGdyYXBoaWNzIHN0YXRlCiAgdmlydHVhbCB2b2lkIHVwZGF0ZUFsbChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVDVE0oR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgbTExLCBkb3VibGUgbTEyLAoJCQkgZG91YmxlIG0yMSwgZG91YmxlIG0yMiwgZG91YmxlIG0zMSwgZG91YmxlIG0zMik7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVEYXNoKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZsYXRuZXNzKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVKb2luKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVDYXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTWl0ZXJMaW1pdChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVMaW5lV2lkdGgoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlQWRqdXN0KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxDb2xvcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VDb2xvcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVCbGVuZE1vZGUoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbE9wYWNpdHkoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlT3BhY2l0eShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsT3ZlcnByaW50KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZU92ZXJwcmludChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVPdmVycHJpbnRNb2RlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVRyYW5zZmVyKEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gdXBkYXRlIHRleHQgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRm9udChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHBhdGggcGFpbnRpbmcKICB2aXJ0dWFsIHZvaWQgc3Ryb2tlKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGZpbGwoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZW9GaWxsKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCBHQm9vbCB0aWxpbmdQYXR0ZXJuRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeCAqZ2Z4LCBDYXRhbG9nICpjYXRhbG9nLCBPYmplY3QgKnN0ciwKCQkJCSAgZG91YmxlICpwbWF0LCBpbnQgcGFpbnRUeXBlLCBpbnQgdGlsaW5nVHlwZSwgRGljdCAqcmVzRGljdCwKCQkJCSAgZG91YmxlICptYXQsIGRvdWJsZSAqYmJveCwKCQkJCSAgaW50IHgwLCBpbnQgeTAsIGludCB4MSwgaW50IHkxLAoJCQkJICBkb3VibGUgeFN0ZXAsIGRvdWJsZSB5U3RlcCk7CiAgdmlydHVhbCBHQm9vbCBheGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhBeGlhbFNoYWRpbmcgKnNoYWRpbmcsIGRvdWJsZSB0TWluLCBkb3VibGUgdE1heCk7CiAgdmlydHVhbCBHQm9vbCByYWRpYWxTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4UmFkaWFsU2hhZGluZyAqc2hhZGluZywgZG91YmxlIHRNaW4sIGRvdWJsZSB0TWF4KTsKICB2aXJ0dWFsIEdCb29sIGdvdXJhdWRUcmlhbmdsZVNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nKTsKCiAgLy8tLS0tLSBwYXRoIGNsaXBwaW5nCiAgdmlydHVhbCB2b2lkIGNsaXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZW9DbGlwKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGNsaXBUb1N0cm9rZVBhdGgoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB0ZXh0IGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgZHJhd0NoYXIoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgeCwgZG91YmxlIHksCgkJCWRvdWJsZSBkeCwgZG91YmxlIGR5LAoJCQlkb3VibGUgb3JpZ2luWCwgZG91YmxlIG9yaWdpblksCgkJCUNoYXJDb2RlIGNvZGUsIGludCBuQnl0ZXMsIFVuaWNvZGUgKnUsIGludCB1TGVuKTsKICB2aXJ0dWFsIEdCb29sIGJlZ2luVHlwZTNDaGFyKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHgsIGRvdWJsZSB5LAoJCQkgICAgICAgZG91YmxlIGR4LCBkb3VibGUgZHksCgkJCSAgICAgICBDaGFyQ29kZSBjb2RlLCBVbmljb2RlICp1LCBpbnQgdUxlbik7CiAgdmlydHVhbCB2b2lkIGVuZFR5cGUzQ2hhcihHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBiZWdpblRleHRPYmplY3QoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIEdCb29sIGRldmljZUhhc1RleHRDbGlwKEdmeFN0YXRlICpzdGF0ZSkgeyByZXR1cm4gdGV4dENsaXBQYXRoOyB9CiAgdmlydHVhbCB2b2lkIGVuZFRleHRPYmplY3QoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSBpbWFnZSBkcmF3aW5nCiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZU1hc2soR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHQm9vbCBpbnZlcnQsCgkJCSAgICAgR0Jvb2wgaW50ZXJwb2xhdGUsIEdCb29sIGlubGluZUltZyk7CiAgdmlydHVhbCB2b2lkIHNldFNvZnRNYXNrRnJvbUltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsCgkJCQkJT2JqZWN0ICpyZWYsIFN0cmVhbSAqc3RyLAoJCQkJCWludCB3aWR0aCwgaW50IGhlaWdodCwgR0Jvb2wgaW52ZXJ0LAoJCQkJCUdCb29sIGlubGluZUltZyk7CiAgdmlydHVhbCB2b2lkIHVuc2V0U29mdE1hc2tGcm9tSW1hZ2VNYXNrKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJIGludCB3aWR0aCwgaW50IGhlaWdodCwgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsCgkJCSBHQm9vbCBpbnRlcnBvbGF0ZSwgaW50ICptYXNrQ29sb3JzLCBHQm9vbCBpbmxpbmVJbWcpOwogIHZpcnR1YWwgdm9pZCBkcmF3TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCSAgICAgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJICAgICAgIEdCb29sIGludGVycG9sYXRlLAoJCQkgICAgICAgU3RyZWFtICptYXNrU3RyLCBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJICAgICAgIEdCb29sIG1hc2tJbnZlcnQsIEdCb29sIG1hc2tJbnRlcnBvbGF0ZSk7CiAgdmlydHVhbCB2b2lkIGRyYXdTb2Z0TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJCSAgIEdCb29sIGludGVycG9sYXRlLAoJCQkJICAgU3RyZWFtICptYXNrU3RyLAoJCQkJICAgaW50IG1hc2tXaWR0aCwgaW50IG1hc2tIZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICptYXNrQ29sb3JNYXAsCgkJCQkgICBHQm9vbCBtYXNrSW50ZXJwb2xhdGUpOwoKICAvLy0tLS0tIFR5cGUgMyBmb250IG9wZXJhdG9ycwogIHZpcnR1YWwgdm9pZCB0eXBlM0QwKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3kpOwogIHZpcnR1YWwgdm9pZCB0eXBlM0QxKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3ksCgkJICAgICAgIGRvdWJsZSBsbHgsIGRvdWJsZSBsbHksIGRvdWJsZSB1cngsIGRvdWJsZSB1cnkpOwoKICAvLy0tLS0tIHRyYW5zcGFyZW5jeSBncm91cHMgYW5kIHNvZnQgbWFza3MKICB2aXJ0dWFsIHZvaWQgYmVnaW5UcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmJveCwKCQkJCSAgICAgIEdmeENvbG9yU3BhY2UgKmJsZW5kaW5nQ29sb3JTcGFjZSwKCQkJCSAgICAgIEdCb29sIGlzb2xhdGVkLCBHQm9vbCBrbm9ja291dCwKCQkJCSAgICAgIEdCb29sIGZvclNvZnRNYXNrKTsKICB2aXJ0dWFsIHZvaWQgZW5kVHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgcGFpbnRUcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmJveCk7CiAgdmlydHVhbCB2b2lkIHNldFNvZnRNYXNrKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlICpiYm94LCBHQm9vbCBhbHBoYSwKCQkJICAgRnVuY3Rpb24gKnRyYW5zZmVyRnVuYywgR2Z4Q29sb3IgKmJhY2tkcm9wQ29sb3IpOwogIHZpcnR1YWwgdm9pZCBjbGVhclNvZnRNYXNrKEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gc3BlY2lhbCBhY2Nlc3MKCiAgLy8gQ2FsbGVkIHRvIGluZGljYXRlIHRoYXQgYSBuZXcgUERGIGRvY3VtZW50IGhhcyBiZWVuIGxvYWRlZC4KICB2b2lkIHN0YXJ0RG9jKFBERkRvYyAqZG9jQSk7CiAKICB2b2lkIHNldFBhcGVyQ29sb3IoU3BsYXNoQ29sb3JQdHIgcGFwZXJDb2xvckEpOwoKICBHQm9vbCBpc1JldmVyc2VWaWRlbygpIHsgcmV0dXJuIHJldmVyc2VWaWRlbzsgfQogIHZvaWQgc2V0UmV2ZXJzZVZpZGVvKEdCb29sIHJldmVyc2VWaWRlb0EpIHsgcmV2ZXJzZVZpZGVvID0gcmV2ZXJzZVZpZGVvQTsgfQoKICAvLyBHZXQgdGhlIGJpdG1hcCBhbmQgaXRzIHNpemUuCiAgU3BsYXNoQml0bWFwICpnZXRCaXRtYXAoKSB7IHJldHVybiBiaXRtYXA7IH0KICBpbnQgZ2V0Qml0bWFwV2lkdGgoKTsKICBpbnQgZ2V0Qml0bWFwSGVpZ2h0KCk7CgogIC8vIFJldHVybnMgdGhlIGxhc3QgcmFzdGVyaXplZCBiaXRtYXAsIHRyYW5zZmVycmluZyBvd25lcnNoaXAgdG8gdGhlCiAgLy8gY2FsbGVyLgogIFNwbGFzaEJpdG1hcCAqdGFrZUJpdG1hcCgpOwoKICAvLyBTZXQgdGhpcyBmbGFnIHRvIHRydWUgdG8gZ2VuZXJhdGUgYW4gdXBzaWRlLWRvd24gYml0bWFwICh1c2VmdWwKICAvLyBmb3IgV2luZG93cyBCTVAgZmlsZXMpLgogIHZvaWQgc2V0Qml0bWFwVXBzaWRlRG93bihHQm9vbCBmKSB7IGJpdG1hcFVwc2lkZURvd24gPSBmOyB9CgogIC8vIEdldCB0aGUgU3BsYXNoIG9iamVjdC4KICBTcGxhc2ggKmdldFNwbGFzaCgpIHsgcmV0dXJuIHNwbGFzaDsgfQoKICAvLyBHZXQgdGhlIG1vZGlmaWVkIHJlZ2lvbi4KICB2b2lkIGdldE1vZFJlZ2lvbihpbnQgKnhNaW4sIGludCAqeU1pbiwgaW50ICp4TWF4LCBpbnQgKnlNYXgpOwoKICAvLyBDbGVhciB0aGUgbW9kaWZpZWQgcmVnaW9uLgogIHZvaWQgY2xlYXJNb2RSZWdpb24oKTsKCiAgU3BsYXNoRm9udCAqZ2V0Q3VycmVudEZvbnQoKSB7IHJldHVybiBmb250OyB9CgogIC8vIElmIDxza2lwVGV4dEE+IGlzIHRydWUsIGRvbid0IGRyYXcgaG9yaXpvbnRhbCB0ZXh0LgogIC8vIElmIDxza2lwUm90YXRlZFRleHRBPiBpcyB0cnVlLCBkb24ndCBkcmF3IHJvdGF0ZWQgKG5vbi1ob3Jpem9udGFsKSB0ZXh0LgogIHZvaWQgc2V0U2tpcFRleHQoR0Jvb2wgc2tpcEhvcml6VGV4dEEsIEdCb29sIHNraXBSb3RhdGVkVGV4dEEpCiAgICB7IHNraXBIb3JpelRleHQgPSBza2lwSG9yaXpUZXh0QTsgc2tpcFJvdGF0ZWRUZXh0ID0gc2tpcFJvdGF0ZWRUZXh0QTsgfQoKICBpbnQgZ2V0TmVzdENvdW50KCkgeyByZXR1cm4gbmVzdENvdW50OyB9CgojaWYgMSAvL350bXA6IHR1cm4gb2ZmIGFudGktYWxpYXNpbmcgdGVtcG9yYXJpbHkKICB2aXJ0dWFsIEdCb29sIGdldFZlY3RvckFudGlhbGlhcygpOwogIHZpcnR1YWwgdm9pZCBzZXRWZWN0b3JBbnRpYWxpYXMoR0Jvb2wgdmFhKTsKI2VuZGlmCgogIHZvaWQgc2V0RnJlZVR5cGVIaW50aW5nKEdCb29sIGVuYWJsZSwgR0Jvb2wgZW5hYmxlU2xpZ2h0SGludGluZyk7Cgpwcml2YXRlOgogIEdCb29sIHVuaXZhcmlhdGVTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4gKnBhdHRlcm4sIGRvdWJsZSB0TWluLCBkb3VibGUgdE1heCk7CgogIHZvaWQgc2V0dXBTY3JlZW5QYXJhbXMoZG91YmxlIGhEUEksIGRvdWJsZSB2RFBJKTsKICBTcGxhc2hQYXR0ZXJuICpnZXRDb2xvcihHZnhHcmF5IGdyYXkpOwogIFNwbGFzaFBhdHRlcm4gKmdldENvbG9yKEdmeFJHQiAqcmdiKTsKI2lmIFNQTEFTSF9DTVlLCiAgU3BsYXNoUGF0dGVybiAqZ2V0Q29sb3IoR2Z4Q01ZSyAqY215ayk7CiNlbmRpZgogIHZvaWQgc2V0T3ZlcnByaW50TWFzayhHZnhDb2xvclNwYWNlICpjb2xvclNwYWNlLCBHQm9vbCBvdmVycHJpbnRGbGFnLAoJCQlpbnQgb3ZlcnByaW50TW9kZSwgR2Z4Q29sb3IgKnNpbmdsZUNvbG9yLCBHQm9vbCBncmF5SW5kZXhlZCA9IGdGYWxzZSk7CiAgU3BsYXNoUGF0aCAqY29udmVydFBhdGgoR2Z4U3RhdGUgKnN0YXRlLCBHZnhQYXRoICpwYXRoLAoJCQkgIEdCb29sIGRyb3BFbXB0eVN1YnBhdGhzKTsKICB2b2lkIGRvVXBkYXRlRm9udChHZnhTdGF0ZSAqc3RhdGUpOwogIHZvaWQgZHJhd1R5cGUzR2x5cGgoR2Z4U3RhdGUgKnN0YXRlLCBUM0ZvbnRDYWNoZSAqdDNGb250LAoJCSAgICAgIFQzRm9udENhY2hlVGFnICp0YWcsIEd1Y2hhciAqZGF0YSk7CiAgc3RhdGljIEdCb29sIGltYWdlTWFza1NyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBsaW5lKTsKICBzdGF0aWMgR0Jvb2wgaW1hZ2VTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgY29sb3JMaW5lLAoJCQlHdWNoYXIgKmFscGhhTGluZSk7CiAgc3RhdGljIEdCb29sIGFscGhhSW1hZ2VTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSwKCQkJICAgICBHdWNoYXIgKmFscGhhTGluZSk7CiAgc3RhdGljIEdCb29sIG1hc2tlZEltYWdlU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGxpbmUsCgkJCSAgICAgIEd1Y2hhciAqYWxwaGFMaW5lKTsKICBzdGF0aWMgR0Jvb2wgdGlsaW5nQml0bWFwU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGxpbmUsCgkJCSAgICAgR3VjaGFyICphbHBoYUxpbmUpOwoKICBHQm9vbCBrZWVwQWxwaGFDaGFubmVsOwkvLyBkb24ndCBmaWxsIHdpdGggcGFwZXIgY29sb3IsIGtlZXAgYWxwaGEgY2hhbm5lbAoKICBTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlOwogIGludCBiaXRtYXBSb3dQYWQ7CiAgR0Jvb2wgYml0bWFwVG9wRG93bjsKICBHQm9vbCBiaXRtYXBVcHNpZGVEb3duOwogIEdCb29sIGFsbG93QW50aWFsaWFzOwogIEdCb29sIHZlY3RvckFudGlhbGlhczsKICBHQm9vbCBlbmFibGVGcmVlVHlwZUhpbnRpbmc7CiAgR0Jvb2wgZW5hYmxlU2xpZ2h0SGludGluZzsKICBHQm9vbCByZXZlcnNlVmlkZW87CQkvLyByZXZlcnNlIHZpZGVvIG1vZGUKICBTcGxhc2hDb2xvciBwYXBlckNvbG9yOwkvLyBwYXBlciBjb2xvcgogIFNwbGFzaFNjcmVlblBhcmFtcyBzY3JlZW5QYXJhbXM7CiAgR0Jvb2wgc2tpcEhvcml6VGV4dDsKICBHQm9vbCBza2lwUm90YXRlZFRleHQ7CgogIFBERkRvYyAqZG9jOwkJCS8vIHRoZSBjdXJyZW50IGRvY3VtZW50CgogIFNwbGFzaEJpdG1hcCAqYml0bWFwOwogIFNwbGFzaCAqc3BsYXNoOwogIFNwbGFzaEZvbnRFbmdpbmUgKmZvbnRFbmdpbmU7CgogIFQzRm9udENhY2hlICoJCQkvLyBUeXBlIDMgZm9udCBjYWNoZQogICAgdDNGb250Q2FjaGVbc3BsYXNoT3V0VDNGb250Q2FjaGVTaXplXTsKICBpbnQgblQzRm9udHM7CQkJLy8gbnVtYmVyIG9mIHZhbGlkIGVudHJpZXMgaW4gdDNGb250Q2FjaGUKICBUM0dseXBoU3RhY2sgKnQzR2x5cGhTdGFjazsJLy8gVHlwZSAzIGdseXBoIGNvbnRleHQgc3RhY2sKICBHQm9vbCBoYXZlVDNEeDsJCS8vIHNldCBhZnRlciBzZWVpbmcgYSBkMC9kMSBvcGVyYXRvcgoKICBTcGxhc2hGb250ICpmb250OwkJLy8gY3VycmVudCBmb250CiAgR0Jvb2wgbmVlZEZvbnRVcGRhdGU7CQkvLyBzZXQgd2hlbiB0aGUgZm9udCBuZWVkcyB0byBiZSB1cGRhdGVkCiAgU3BsYXNoUGF0aCAqdGV4dENsaXBQYXRoOwkvLyBjbGlwcGluZyBwYXRoIGJ1aWx0IHdpdGggdGV4dCBvYmplY3QKCiAgU3BsYXNoVHJhbnNwYXJlbmN5R3JvdXAgKgkvLyB0cmFuc3BhcmVuY3kgZ3JvdXAgc3RhY2sKICAgIHRyYW5zcEdyb3VwU3RhY2s7CiAgU3BsYXNoQml0bWFwICptYXNrQml0bWFwOyAvLyBmb3IgaW1hZ2UgbWFza3MgaW4gcGF0dGVybiBjb2xvcnNwYWNlCiAgaW50IG5lc3RDb3VudDsKfTsKCiNlbmRpZgo=