Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDIwMDMgR2x5cGggJiBDb2csIExMQwovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gTW9kaWZpZWQgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCAtIGh0dHA6Ly9wb3BwbGVyLmZyZWVkZXNrdG9wLm9yZwovLwovLyBBbGwgY2hhbmdlcyBtYWRlIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgdG8gdGhpcyBmaWxlIGFyZSBsaWNlbnNlZAovLyB1bmRlciBHUEwgdmVyc2lvbiAyIG9yIGxhdGVyCi8vCi8vIENvcHlyaWdodCAoQykgMjAwNSBUYWthc2hpIEl3YWkgPHRpd2FpQHN1c2UuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAwOS0yMDEyIFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgQ2FybG9zIEdhcmNpYSBDYW1wb3MgPGNhcmxvc2djQGdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExIEFuZHJlYXMgSGFydG1ldHogPGFoYXJ0bWV0ekBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMSBBbmRyZWEgQ2FuY2lhbmkgPHJhbm1hNDJAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTEgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vCi8vIFRvIHNlZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHBsZWFzZSBzZWUgdGhlIENoYW5nZWxvZyBmaWxlIHRoYXQKLy8gY2FtZSB3aXRoIHlvdXIgdGFyYmFsbCBvciB0eXBlIG1ha2UgQ2hhbmdlTG9nIGlmIHlvdSBhcmUgYnVpbGRpbmcgZnJvbSBnaXQKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgU1BMQVNIT1VUUFVUREVWX0gKI2RlZmluZSBTUExBU0hPVVRQVVRERVZfSAoKI2lmZGVmIFVTRV9HQ0NfUFJBR01BUwojcHJhZ21hIGludGVyZmFjZQojZW5kaWYKCiNpbmNsdWRlICJnb28vZ3R5cGVzLmgiCiNpbmNsdWRlICJzcGxhc2gvU3BsYXNoVHlwZXMuaCIKI2luY2x1ZGUgInNwbGFzaC9TcGxhc2hQYXR0ZXJuLmgiCiNpbmNsdWRlICJwb3BwbGVyLWNvbmZpZy5oIgojaW5jbHVkZSAiT3V0cHV0RGV2LmgiCiNpbmNsdWRlICJHZnhTdGF0ZS5oIgoKY2xhc3MgUERGRG9jOwpjbGFzcyBHZng4Qml0Rm9udDsKY2xhc3MgU3BsYXNoQml0bWFwOwpjbGFzcyBTcGxhc2g7CmNsYXNzIFNwbGFzaFBhdGg7CmNsYXNzIFNwbGFzaEZvbnRFbmdpbmU7CmNsYXNzIFNwbGFzaEZvbnQ7CmNsYXNzIFQzRm9udENhY2hlOwpzdHJ1Y3QgVDNGb250Q2FjaGVUYWc7CnN0cnVjdCBUM0dseXBoU3RhY2s7CnN0cnVjdCBTcGxhc2hUcmFuc3BhcmVuY3lHcm91cDsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaCBkeW5hbWljIHBhdHRlcm4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4oU3BsYXNoQ29sb3JNb2RlIGNvbG9yTW9kZSwgR2Z4U3RhdGUgKnN0YXRlLCBHZnhVbml2YXJpYXRlU2hhZGluZyAqc2hhZGluZyk7CgogIHZpcnR1YWwgflNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0Q29sb3IoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBjKTsKCiAgdmlydHVhbCBHQm9vbCB0ZXN0UG9zaXRpb24oaW50IHgsIGludCB5KTsKCiAgdmlydHVhbCBHQm9vbCBpc1N0YXRpYygpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICB2aXJ0dWFsIEdCb29sIGdldFBhcmFtZXRlcihkb3VibGUgeHMsIGRvdWJsZSB5cywgZG91YmxlICp0KSA9IDA7CgogIHZpcnR1YWwgR2Z4VW5pdmFyaWF0ZVNoYWRpbmcgKmdldFNoYWRpbmcoKSB7IHJldHVybiBzaGFkaW5nOyB9Cgpwcm90ZWN0ZWQ6CiAgTWF0cml4IGljdG07CiAgZG91YmxlIHQwLCB0MSwgZHQ7CiAgR2Z4VW5pdmFyaWF0ZVNoYWRpbmcgKnNoYWRpbmc7CiAgR2Z4U3RhdGUgKnN0YXRlOwogIFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGU7Cn07CgpjbGFzcyBTcGxhc2hBeGlhbFBhdHRlcm46IHB1YmxpYyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoQXhpYWxQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4QXhpYWxTaGFkaW5nICpzaGFkaW5nKTsKCiAgdmlydHVhbCBTcGxhc2hQYXR0ZXJuICpjb3B5KCkgeyByZXR1cm4gbmV3IFNwbGFzaEF4aWFsUGF0dGVybihjb2xvck1vZGUsIHN0YXRlLCAoR2Z4QXhpYWxTaGFkaW5nICopIHNoYWRpbmcpOyB9CgogIHZpcnR1YWwgflNwbGFzaEF4aWFsUGF0dGVybigpOwoKICB2aXJ0dWFsIEdCb29sIGdldFBhcmFtZXRlcihkb3VibGUgeHMsIGRvdWJsZSB5cywgZG91YmxlICp0KTsKCnByaXZhdGU6CiAgZG91YmxlIHgwLCB5MCwgeDEsIHkxOwogIGRvdWJsZSBkeCwgZHksIG11bDsKfTsKCi8vIHNlZSBHZnhTdGF0ZS5oLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nCmNsYXNzIFNwbGFzaEdvdXJhdWRQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoR291cmF1ZENvbG9yIHsKcHVibGljOgoKICBTcGxhc2hHb3VyYXVkUGF0dGVybihHQm9vbCBiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgR2Z4U3RhdGUgKnN0YXRlLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nLCBTcGxhc2hDb2xvck1vZGUgbW9kZSk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hHb3VyYXVkUGF0dGVybihiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgc3RhdGUsIHNoYWRpbmcsIG1vZGUpOyB9CgogIHZpcnR1YWwgflNwbGFzaEdvdXJhdWRQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0Q29sb3IoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBjKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCB0ZXN0UG9zaXRpb24oaW50IHgsIGludCB5KSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCBpc1N0YXRpYygpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICB2aXJ0dWFsIEdCb29sIGlzUGFyYW1ldGVyaXplZCgpIHsgcmV0dXJuIHNoYWRpbmctPmlzUGFyYW1ldGVyaXplZCgpOyB9CiAgdmlydHVhbCBpbnQgZ2V0TlRyaWFuZ2xlcygpIHsgcmV0dXJuIHNoYWRpbmctPmdldE5UcmlhbmdsZXMoKTsgfQogIHZpcnR1YWwgIHZvaWQgZ2V0VHJpYW5nbGUoaW50IGksIGRvdWJsZSAqeDAsIGRvdWJsZSAqeTAsIGRvdWJsZSAqY29sb3IwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlICp4MSwgZG91YmxlICp5MSwgZG91YmxlICpjb2xvcjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgKngyLCBkb3VibGUgKnkyLCBkb3VibGUgKmNvbG9yMikKICB7IHJldHVybiBzaGFkaW5nLT5nZXRUcmlhbmdsZShpLCB4MCwgeTAsIGNvbG9yMCwgeDEsIHkxLCBjb2xvcjEsIHgyLCB5MiwgY29sb3IyKTsgfQoKICB2aXJ0dWFsIHZvaWQgZ2V0UGFyYW1ldGVyaXplZENvbG9yKGRvdWJsZSB0LCBTcGxhc2hDb2xvck1vZGUgbW9kZSwgU3BsYXNoQ29sb3JQdHIgYyk7Cgpwcml2YXRlOgogIEdmeEdvdXJhdWRUcmlhbmdsZVNoYWRpbmcgKnNoYWRpbmc7CiAgR2Z4U3RhdGUgKnN0YXRlOwogIEdCb29sIGJEaXJlY3RDb2xvclRyYW5zbGF0aW9uOwogIFNwbGFzaENvbG9yTW9kZSBtb2RlOwp9OwoKLy8gc2VlIEdmeFN0YXRlLmgsIEdmeFJhZGlhbFNoYWRpbmcKY2xhc3MgU3BsYXNoUmFkaWFsUGF0dGVybjogcHVibGljIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuIHsKcHVibGljOgoKICBTcGxhc2hSYWRpYWxQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4UmFkaWFsU2hhZGluZyAqc2hhZGluZyk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hSYWRpYWxQYXR0ZXJuKGNvbG9yTW9kZSwgc3RhdGUsIChHZnhSYWRpYWxTaGFkaW5nICopIHNoYWRpbmcpOyB9CgogIHZpcnR1YWwgflNwbGFzaFJhZGlhbFBhdHRlcm4oKTsKCiAgdmlydHVhbCBHQm9vbCBnZXRQYXJhbWV0ZXIoZG91YmxlIHhzLCBkb3VibGUgeXMsIGRvdWJsZSAqdCk7Cgpwcml2YXRlOgogIGRvdWJsZSB4MCwgeTAsIHIwLCBkeCwgZHksIGRyOwogIGRvdWJsZSBhLCBpbnZhOwp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIG51bWJlciBvZiBUeXBlIDMgZm9udHMgdG8gY2FjaGUKI2RlZmluZSBzcGxhc2hPdXRUM0ZvbnRDYWNoZVNpemUgOAoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoT3V0cHV0RGV2Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hPdXRwdXREZXY6IHB1YmxpYyBPdXRwdXREZXYgewpwdWJsaWM6CgogIC8vIENvbnN0cnVjdG9yLgogIFNwbGFzaE91dHB1dERldihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlQSwgaW50IGJpdG1hcFJvd1BhZEEsCgkJICBHQm9vbCByZXZlcnNlVmlkZW9BLCBTcGxhc2hDb2xvclB0ciBwYXBlckNvbG9yQSwKCQkgIEdCb29sIGJpdG1hcFRvcERvd25BID0gZ1RydWUsCgkJICBHQm9vbCBhbGxvd0FudGlhbGlhc0EgPSBnVHJ1ZSk7CgogIC8vIERlc3RydWN0b3IuCiAgdmlydHVhbCB+U3BsYXNoT3V0cHV0RGV2KCk7CgogIC8vLS0tLS0gZ2V0IGluZm8gYWJvdXQgb3V0cHV0IGRldmljZQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB0aWxpbmdQYXR0ZXJuRmlsbCgpPyAgSWYgdGhpcyByZXR1cm5zIGZhbHNlLAogIC8vIHRpbGluZyBwYXR0ZXJuIGZpbGxzIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nCiAgLy8gb3BlcmF0aW9ucy4KICB2aXJ0dWFsIEdCb29sIHVzZVRpbGluZ1BhdHRlcm5GaWxsKCkgeyByZXR1cm4gZ1RydWU7IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgZnVuY3Rpb25TaGFkZWRGaWxsKCksIGF4aWFsU2hhZGVkRmlsbCgpLCBhbmQKICAvLyByYWRpYWxTaGFkZWRGaWxsKCk/ICBJZiB0aGlzIHJldHVybnMgZmFsc2UsIHRoZXNlIHNoYWRlZCBmaWxscwogIC8vIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nIG9wZXJhdGlvbnMuCiAgdmlydHVhbCBHQm9vbCB1c2VTaGFkZWRGaWxscyhpbnQgdHlwZSkKICB7IHJldHVybiAodHlwZSA+PSAyICYmIHR5cGUgPD0gNSkgPyBnVHJ1ZSA6IGdGYWxzZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB1cHNpZGUtZG93biBjb29yZGluYXRlcz8KICAvLyAoVXBzaWRlLWRvd24gbWVhbnMgKDAsMCkgaXMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgcGFnZS4pCiAgdmlydHVhbCBHQm9vbCB1cHNpZGVEb3duKCkgeyByZXR1cm4gYml0bWFwVG9wRG93biBeIGJpdG1hcFVwc2lkZURvd247IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgZHJhd0NoYXIoKSBvciBkcmF3U3RyaW5nKCk/CiAgdmlydHVhbCBHQm9vbCB1c2VEcmF3Q2hhcigpIHsgcmV0dXJuIGdUcnVlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGJlZ2luVHlwZTNDaGFyL2VuZFR5cGUzQ2hhcj8gIE90aGVyd2lzZSwKICAvLyB0ZXh0IGluIFR5cGUgMyBmb250cyB3aWxsIGJlIGRyYXduIHdpdGggZHJhd0NoYXIvZHJhd1N0cmluZy4KICB2aXJ0dWFsIEdCb29sIGludGVycHJldFR5cGUzQ2hhcnMoKSB7IHJldHVybiBnVHJ1ZTsgfQoKICAvLy0tLS0tIGluaXRpYWxpemF0aW9uIGFuZCBjb250cm9sCgogIC8vIFN0YXJ0IGEgcGFnZS4KICB2aXJ0dWFsIHZvaWQgc3RhcnRQYWdlKGludCBwYWdlTnVtLCBHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLyBFbmQgYSBwYWdlLgogIHZpcnR1YWwgdm9pZCBlbmRQYWdlKCk7CgogIC8vLS0tLS0gc2F2ZS9yZXN0b3JlIGdyYXBoaWNzIHN0YXRlCiAgdmlydHVhbCB2b2lkIHNhdmVTdGF0ZShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCByZXN0b3JlU3RhdGUoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB1cGRhdGUgZ3JhcGhpY3Mgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlQWxsKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUNUTShHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSBtMTEsIGRvdWJsZSBtMTIsCgkJCSBkb3VibGUgbTIxLCBkb3VibGUgbTIyLCBkb3VibGUgbTMxLCBkb3VibGUgbTMyKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZURhc2goR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmxhdG5lc3MoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZUpvaW4oR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZUNhcChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVNaXRlckxpbWl0KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVXaWR0aChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VBZGp1c3QoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbENvbG9yKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUNvbG9yKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUJsZW5kTW9kZShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsT3BhY2l0eShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VPcGFjaXR5KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxPdmVycHJpbnQoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlT3ZlcnByaW50KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZU92ZXJwcmludE1vZGUoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlVHJhbnNmZXIoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB1cGRhdGUgdGV4dCBzdGF0ZQogIHZpcnR1YWwgdm9pZCB1cGRhdGVGb250KEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gcGF0aCBwYWludGluZwogIHZpcnR1YWwgdm9pZCBzdHJva2UoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZmlsbChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBlb0ZpbGwoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIEdCb29sIHRpbGluZ1BhdHRlcm5GaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4ICpnZngsIENhdGFsb2cgKmNhdGFsb2csIE9iamVjdCAqc3RyLAoJCQkJICBkb3VibGUgKnBtYXQsIGludCBwYWludFR5cGUsIGludCB0aWxpbmdUeXBlLCBEaWN0ICpyZXNEaWN0LAoJCQkJICBkb3VibGUgKm1hdCwgZG91YmxlICpiYm94LAoJCQkJICBpbnQgeDAsIGludCB5MCwgaW50IHgxLCBpbnQgeTEsCgkJCQkgIGRvdWJsZSB4U3RlcCwgZG91YmxlIHlTdGVwKTsKICB2aXJ0dWFsIEdCb29sIGF4aWFsU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeEF4aWFsU2hhZGluZyAqc2hhZGluZywgZG91YmxlIHRNaW4sIGRvdWJsZSB0TWF4KTsKICB2aXJ0dWFsIEdCb29sIHJhZGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhSYWRpYWxTaGFkaW5nICpzaGFkaW5nLCBkb3VibGUgdE1pbiwgZG91YmxlIHRNYXgpOwogIHZpcnR1YWwgR0Jvb2wgZ291cmF1ZFRyaWFuZ2xlU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeEdvdXJhdWRUcmlhbmdsZVNoYWRpbmcgKnNoYWRpbmcpOwoKICAvLy0tLS0tIHBhdGggY2xpcHBpbmcKICB2aXJ0dWFsIHZvaWQgY2xpcChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBlb0NsaXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgY2xpcFRvU3Ryb2tlUGF0aChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHRleHQgZHJhd2luZwogIHZpcnR1YWwgdm9pZCBkcmF3Q2hhcihHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSB4LCBkb3VibGUgeSwKCQkJZG91YmxlIGR4LCBkb3VibGUgZHksCgkJCWRvdWJsZSBvcmlnaW5YLCBkb3VibGUgb3JpZ2luWSwKCQkJQ2hhckNvZGUgY29kZSwgaW50IG5CeXRlcywgVW5pY29kZSAqdSwgaW50IHVMZW4pOwogIHZpcnR1YWwgR0Jvb2wgYmVnaW5UeXBlM0NoYXIoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgeCwgZG91YmxlIHksCgkJCSAgICAgICBkb3VibGUgZHgsIGRvdWJsZSBkeSwKCQkJICAgICAgIENoYXJDb2RlIGNvZGUsIFVuaWNvZGUgKnUsIGludCB1TGVuKTsKICB2aXJ0dWFsIHZvaWQgZW5kVHlwZTNDaGFyKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGJlZ2luVGV4dE9iamVjdChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgR0Jvb2wgZGV2aWNlSGFzVGV4dENsaXAoR2Z4U3RhdGUgKnN0YXRlKSB7IHJldHVybiB0ZXh0Q2xpcFBhdGg7IH0KICB2aXJ0dWFsIHZvaWQgZW5kVGV4dE9iamVjdChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIGltYWdlIGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgZHJhd0ltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEdCb29sIGludmVydCwKCQkJICAgICBHQm9vbCBpbnRlcnBvbGF0ZSwgR0Jvb2wgaW5saW5lSW1nKTsKICB2aXJ0dWFsIHZvaWQgc2V0U29mdE1hc2tGcm9tSW1hZ2VNYXNrKEdmeFN0YXRlICpzdGF0ZSwKCQkJCQlPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkJaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHQm9vbCBpbnZlcnQsCgkJCQkJR0Jvb2wgaW5saW5lSW1nKTsKICB2aXJ0dWFsIHZvaWQgdW5zZXRTb2Z0TWFza0Zyb21JbWFnZU1hc2soR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZHJhd0ltYWdlKEdmeFN0YXRlICpzdGF0ZSwgT2JqZWN0ICpyZWYsIFN0cmVhbSAqc3RyLAoJCQkgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJIEdCb29sIGludGVycG9sYXRlLCBpbnQgKm1hc2tDb2xvcnMsIEdCb29sIGlubGluZUltZyk7CiAgdmlydHVhbCB2b2lkIGRyYXdNYXNrZWRJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJICAgICAgIEdmeEltYWdlQ29sb3JNYXAgKmNvbG9yTWFwLAoJCQkgICAgICAgR0Jvb2wgaW50ZXJwb2xhdGUsCgkJCSAgICAgICBTdHJlYW0gKm1hc2tTdHIsIGludCBtYXNrV2lkdGgsIGludCBtYXNrSGVpZ2h0LAoJCQkgICAgICAgR0Jvb2wgbWFza0ludmVydCwgR0Jvb2wgbWFza0ludGVycG9sYXRlKTsKICB2aXJ0dWFsIHZvaWQgZHJhd1NvZnRNYXNrZWRJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJCSAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJCSAgIEdmeEltYWdlQ29sb3JNYXAgKmNvbG9yTWFwLAoJCQkJICAgR0Jvb2wgaW50ZXJwb2xhdGUsCgkJCQkgICBTdHJlYW0gKm1hc2tTdHIsCgkJCQkgICBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJCSAgIEdmeEltYWdlQ29sb3JNYXAgKm1hc2tDb2xvck1hcCwKCQkJCSAgIEdCb29sIG1hc2tJbnRlcnBvbGF0ZSk7CgogIC8vLS0tLS0gVHlwZSAzIGZvbnQgb3BlcmF0b3JzCiAgdmlydHVhbCB2b2lkIHR5cGUzRDAoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgd3gsIGRvdWJsZSB3eSk7CiAgdmlydHVhbCB2b2lkIHR5cGUzRDEoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgd3gsIGRvdWJsZSB3eSwKCQkgICAgICAgZG91YmxlIGxseCwgZG91YmxlIGxseSwgZG91YmxlIHVyeCwgZG91YmxlIHVyeSk7CgogIC8vLS0tLS0gdHJhbnNwYXJlbmN5IGdyb3VwcyBhbmQgc29mdCBtYXNrcwogIHZpcnR1YWwgdm9pZCBiZWdpblRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlICpiYm94LAoJCQkJICAgICAgR2Z4Q29sb3JTcGFjZSAqYmxlbmRpbmdDb2xvclNwYWNlLAoJCQkJICAgICAgR0Jvb2wgaXNvbGF0ZWQsIEdCb29sIGtub2Nrb3V0LAoJCQkJICAgICAgR0Jvb2wgZm9yU29mdE1hc2spOwogIHZpcnR1YWwgdm9pZCBlbmRUcmFuc3BhcmVuY3lHcm91cChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBwYWludFRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlICpiYm94KTsKICB2aXJ0dWFsIHZvaWQgc2V0U29mdE1hc2soR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgKmJib3gsIEdCb29sIGFscGhhLAoJCQkgICBGdW5jdGlvbiAqdHJhbnNmZXJGdW5jLCBHZnhDb2xvciAqYmFja2Ryb3BDb2xvcik7CiAgdmlydHVhbCB2b2lkIGNsZWFyU29mdE1hc2soR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSBzcGVjaWFsIGFjY2VzcwoKICAvLyBDYWxsZWQgdG8gaW5kaWNhdGUgdGhhdCBhIG5ldyBQREYgZG9jdW1lbnQgaGFzIGJlZW4gbG9hZGVkLgogIHZvaWQgc3RhcnREb2MoUERGRG9jICpkb2NBKTsKIAogIHZvaWQgc2V0UGFwZXJDb2xvcihTcGxhc2hDb2xvclB0ciBwYXBlckNvbG9yQSk7CgogIEdCb29sIGlzUmV2ZXJzZVZpZGVvKCkgeyByZXR1cm4gcmV2ZXJzZVZpZGVvOyB9CiAgdm9pZCBzZXRSZXZlcnNlVmlkZW8oR0Jvb2wgcmV2ZXJzZVZpZGVvQSkgeyByZXZlcnNlVmlkZW8gPSByZXZlcnNlVmlkZW9BOyB9CgogIC8vIEdldCB0aGUgYml0bWFwIGFuZCBpdHMgc2l6ZS4KICBTcGxhc2hCaXRtYXAgKmdldEJpdG1hcCgpIHsgcmV0dXJuIGJpdG1hcDsgfQogIGludCBnZXRCaXRtYXBXaWR0aCgpOwogIGludCBnZXRCaXRtYXBIZWlnaHQoKTsKCiAgLy8gUmV0dXJucyB0aGUgbGFzdCByYXN0ZXJpemVkIGJpdG1hcCwgdHJhbnNmZXJyaW5nIG93bmVyc2hpcCB0byB0aGUKICAvLyBjYWxsZXIuCiAgU3BsYXNoQml0bWFwICp0YWtlQml0bWFwKCk7CgogIC8vIFNldCB0aGlzIGZsYWcgdG8gdHJ1ZSB0byBnZW5lcmF0ZSBhbiB1cHNpZGUtZG93biBiaXRtYXAgKHVzZWZ1bAogIC8vIGZvciBXaW5kb3dzIEJNUCBmaWxlcykuCiAgdm9pZCBzZXRCaXRtYXBVcHNpZGVEb3duKEdCb29sIGYpIHsgYml0bWFwVXBzaWRlRG93biA9IGY7IH0KCiAgLy8gR2V0IHRoZSBTcGxhc2ggb2JqZWN0LgogIFNwbGFzaCAqZ2V0U3BsYXNoKCkgeyByZXR1cm4gc3BsYXNoOyB9CgogIC8vIEdldCB0aGUgbW9kaWZpZWQgcmVnaW9uLgogIHZvaWQgZ2V0TW9kUmVnaW9uKGludCAqeE1pbiwgaW50ICp5TWluLCBpbnQgKnhNYXgsIGludCAqeU1heCk7CgogIC8vIENsZWFyIHRoZSBtb2RpZmllZCByZWdpb24uCiAgdm9pZCBjbGVhck1vZFJlZ2lvbigpOwoKICBTcGxhc2hGb250ICpnZXRDdXJyZW50Rm9udCgpIHsgcmV0dXJuIGZvbnQ7IH0KCiAgLy8gSWYgPHNraXBUZXh0QT4gaXMgdHJ1ZSwgZG9uJ3QgZHJhdyBob3Jpem9udGFsIHRleHQuCiAgLy8gSWYgPHNraXBSb3RhdGVkVGV4dEE+IGlzIHRydWUsIGRvbid0IGRyYXcgcm90YXRlZCAobm9uLWhvcml6b250YWwpIHRleHQuCiAgdm9pZCBzZXRTa2lwVGV4dChHQm9vbCBza2lwSG9yaXpUZXh0QSwgR0Jvb2wgc2tpcFJvdGF0ZWRUZXh0QSkKICAgIHsgc2tpcEhvcml6VGV4dCA9IHNraXBIb3JpelRleHRBOyBza2lwUm90YXRlZFRleHQgPSBza2lwUm90YXRlZFRleHRBOyB9CgogIGludCBnZXROZXN0Q291bnQoKSB7IHJldHVybiBuZXN0Q291bnQ7IH0KCiNpZiAxIC8vfnRtcDogdHVybiBvZmYgYW50aS1hbGlhc2luZyB0ZW1wb3JhcmlseQogIHZpcnR1YWwgR0Jvb2wgZ2V0VmVjdG9yQW50aWFsaWFzKCk7CiAgdmlydHVhbCB2b2lkIHNldFZlY3RvckFudGlhbGlhcyhHQm9vbCB2YWEpOwojZW5kaWYKCiAgdm9pZCBzZXRGcmVlVHlwZUhpbnRpbmcoR0Jvb2wgZW5hYmxlLCBHQm9vbCBlbmFibGVTbGlnaHRIaW50aW5nKTsKCnByb3RlY3RlZDoKICB2b2lkIGRvVXBkYXRlRm9udChHZnhTdGF0ZSAqc3RhdGUpOwoKcHJpdmF0ZToKICBHQm9vbCB1bml2YXJpYXRlU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuICpwYXR0ZXJuLCBkb3VibGUgdE1pbiwgZG91YmxlIHRNYXgpOwoKICB2b2lkIHNldHVwU2NyZWVuUGFyYW1zKGRvdWJsZSBoRFBJLCBkb3VibGUgdkRQSSk7CiAgU3BsYXNoUGF0dGVybiAqZ2V0Q29sb3IoR2Z4R3JheSBncmF5KTsKICBTcGxhc2hQYXR0ZXJuICpnZXRDb2xvcihHZnhSR0IgKnJnYik7CiNpZiBTUExBU0hfQ01ZSwogIFNwbGFzaFBhdHRlcm4gKmdldENvbG9yKEdmeENNWUsgKmNteWspOwojZW5kaWYKICB2b2lkIHNldE92ZXJwcmludE1hc2soR2Z4Q29sb3JTcGFjZSAqY29sb3JTcGFjZSwgR0Jvb2wgb3ZlcnByaW50RmxhZywKCQkJaW50IG92ZXJwcmludE1vZGUsIEdmeENvbG9yICpzaW5nbGVDb2xvciwgR0Jvb2wgZ3JheUluZGV4ZWQgPSBnRmFsc2UpOwogIFNwbGFzaFBhdGggKmNvbnZlcnRQYXRoKEdmeFN0YXRlICpzdGF0ZSwgR2Z4UGF0aCAqcGF0aCwKCQkJICBHQm9vbCBkcm9wRW1wdHlTdWJwYXRocyk7CiAgdm9pZCBkcmF3VHlwZTNHbHlwaChHZnhTdGF0ZSAqc3RhdGUsIFQzRm9udENhY2hlICp0M0ZvbnQsCgkJICAgICAgVDNGb250Q2FjaGVUYWcgKnRhZywgR3VjaGFyICpkYXRhKTsKICBzdGF0aWMgR0Jvb2wgaW1hZ2VNYXNrU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGxpbmUpOwogIHN0YXRpYyBHQm9vbCBpbWFnZVNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBjb2xvckxpbmUsCgkJCUd1Y2hhciAqYWxwaGFMaW5lKTsKICBzdGF0aWMgR0Jvb2wgYWxwaGFJbWFnZVNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBsaW5lLAoJCQkgICAgIEd1Y2hhciAqYWxwaGFMaW5lKTsKICBzdGF0aWMgR0Jvb2wgbWFza2VkSW1hZ2VTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSwKCQkJICAgICAgR3VjaGFyICphbHBoYUxpbmUpOwogIHN0YXRpYyBHQm9vbCB0aWxpbmdCaXRtYXBTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSwKCQkJICAgICBHdWNoYXIgKmFscGhhTGluZSk7CgogIEdCb29sIGtlZXBBbHBoYUNoYW5uZWw7CS8vIGRvbid0IGZpbGwgd2l0aCBwYXBlciBjb2xvciwga2VlcCBhbHBoYSBjaGFubmVsCgogIFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGU7CiAgaW50IGJpdG1hcFJvd1BhZDsKICBHQm9vbCBiaXRtYXBUb3BEb3duOwogIEdCb29sIGJpdG1hcFVwc2lkZURvd247CiAgR0Jvb2wgYWxsb3dBbnRpYWxpYXM7CiAgR0Jvb2wgdmVjdG9yQW50aWFsaWFzOwogIEdCb29sIGVuYWJsZUZyZWVUeXBlSGludGluZzsKICBHQm9vbCBlbmFibGVTbGlnaHRIaW50aW5nOwogIEdCb29sIHJldmVyc2VWaWRlbzsJCS8vIHJldmVyc2UgdmlkZW8gbW9kZQogIFNwbGFzaENvbG9yIHBhcGVyQ29sb3I7CS8vIHBhcGVyIGNvbG9yCiAgU3BsYXNoU2NyZWVuUGFyYW1zIHNjcmVlblBhcmFtczsKICBHQm9vbCBza2lwSG9yaXpUZXh0OwogIEdCb29sIHNraXBSb3RhdGVkVGV4dDsKCiAgUERGRG9jICpkb2M7CQkJLy8gdGhlIGN1cnJlbnQgZG9jdW1lbnQKCiAgU3BsYXNoQml0bWFwICpiaXRtYXA7CiAgU3BsYXNoICpzcGxhc2g7CiAgU3BsYXNoRm9udEVuZ2luZSAqZm9udEVuZ2luZTsKCiAgVDNGb250Q2FjaGUgKgkJCS8vIFR5cGUgMyBmb250IGNhY2hlCiAgICB0M0ZvbnRDYWNoZVtzcGxhc2hPdXRUM0ZvbnRDYWNoZVNpemVdOwogIGludCBuVDNGb250czsJCQkvLyBudW1iZXIgb2YgdmFsaWQgZW50cmllcyBpbiB0M0ZvbnRDYWNoZQogIFQzR2x5cGhTdGFjayAqdDNHbHlwaFN0YWNrOwkvLyBUeXBlIDMgZ2x5cGggY29udGV4dCBzdGFjawogIEdCb29sIGhhdmVUM0R4OwkJLy8gc2V0IGFmdGVyIHNlZWluZyBhIGQwL2QxIG9wZXJhdG9yCgogIFNwbGFzaEZvbnQgKmZvbnQ7CQkvLyBjdXJyZW50IGZvbnQKICBHQm9vbCBuZWVkRm9udFVwZGF0ZTsJCS8vIHNldCB3aGVuIHRoZSBmb250IG5lZWRzIHRvIGJlIHVwZGF0ZWQKICBTcGxhc2hQYXRoICp0ZXh0Q2xpcFBhdGg7CS8vIGNsaXBwaW5nIHBhdGggYnVpbHQgd2l0aCB0ZXh0IG9iamVjdAoKICBTcGxhc2hUcmFuc3BhcmVuY3lHcm91cCAqCS8vIHRyYW5zcGFyZW5jeSBncm91cCBzdGFjawogICAgdHJhbnNwR3JvdXBTdGFjazsKICBTcGxhc2hCaXRtYXAgKm1hc2tCaXRtYXA7IC8vIGZvciBpbWFnZSBtYXNrcyBpbiBwYXR0ZXJuIGNvbG9yc3BhY2UKICBpbnQgbmVzdENvdW50Owp9OwoKI2VuZGlmCg==