Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoT3V0cHV0RGV2LmgKLy8KLy8gQ29weXJpZ2h0IDIwMDMgR2x5cGggJiBDb2csIExMQwovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gTW9kaWZpZWQgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCAtIGh0dHA6Ly9wb3BwbGVyLmZyZWVkZXNrdG9wLm9yZwovLwovLyBBbGwgY2hhbmdlcyBtYWRlIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgdG8gdGhpcyBmaWxlIGFyZSBsaWNlbnNlZAovLyB1bmRlciBHUEwgdmVyc2lvbiAyIG9yIGxhdGVyCi8vCi8vIENvcHlyaWdodCAoQykgMjAwNSBUYWthc2hpIEl3YWkgPHRpd2FpQHN1c2UuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAwOS0yMDEyIFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgQ2FybG9zIEdhcmNpYSBDYW1wb3MgPGNhcmxvc2djQGdub21lLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExIEFuZHJlYXMgSGFydG1ldHogPGFoYXJ0bWV0ekBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMSBBbmRyZWEgQ2FuY2lhbmkgPHJhbm1hNDJAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTEgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vCi8vIFRvIHNlZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHBsZWFzZSBzZWUgdGhlIENoYW5nZWxvZyBmaWxlIHRoYXQKLy8gY2FtZSB3aXRoIHlvdXIgdGFyYmFsbCBvciB0eXBlIG1ha2UgQ2hhbmdlTG9nIGlmIHlvdSBhcmUgYnVpbGRpbmcgZnJvbSBnaXQKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgU1BMQVNIT1VUUFVUREVWX0gKI2RlZmluZSBTUExBU0hPVVRQVVRERVZfSAoKI2lmZGVmIFVTRV9HQ0NfUFJBR01BUwojcHJhZ21hIGludGVyZmFjZQojZW5kaWYKCiNpbmNsdWRlICJnb28vZ3R5cGVzLmgiCiNpbmNsdWRlICJzcGxhc2gvU3BsYXNoVHlwZXMuaCIKI2luY2x1ZGUgInNwbGFzaC9TcGxhc2hQYXR0ZXJuLmgiCiNpbmNsdWRlICJwb3BwbGVyLWNvbmZpZy5oIgojaW5jbHVkZSAiT3V0cHV0RGV2LmgiCiNpbmNsdWRlICJHZnhTdGF0ZS5oIgoKY2xhc3MgUERGRG9jOwpjbGFzcyBHZng4Qml0Rm9udDsKY2xhc3MgU3BsYXNoQml0bWFwOwpjbGFzcyBTcGxhc2g7CmNsYXNzIFNwbGFzaFBhdGg7CmNsYXNzIFNwbGFzaEZvbnRFbmdpbmU7CmNsYXNzIFNwbGFzaEZvbnQ7CmNsYXNzIFQzRm9udENhY2hlOwpzdHJ1Y3QgVDNGb250Q2FjaGVUYWc7CnN0cnVjdCBUM0dseXBoU3RhY2s7CnN0cnVjdCBTcGxhc2hUcmFuc3BhcmVuY3lHcm91cDsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaCBkeW5hbWljIHBhdHRlcm4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4oU3BsYXNoQ29sb3JNb2RlIGNvbG9yTW9kZSwgR2Z4U3RhdGUgKnN0YXRlLCBHZnhVbml2YXJpYXRlU2hhZGluZyAqc2hhZGluZyk7CgogIHZpcnR1YWwgflNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0Q29sb3IoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBjKTsKCiAgdmlydHVhbCBHQm9vbCB0ZXN0UG9zaXRpb24oaW50IHgsIGludCB5KTsKCiAgdmlydHVhbCBHQm9vbCBpc1N0YXRpYygpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICB2aXJ0dWFsIEdCb29sIGdldFBhcmFtZXRlcihkb3VibGUgeHMsIGRvdWJsZSB5cywgZG91YmxlICp0KSA9IDA7CgogIHZpcnR1YWwgR2Z4VW5pdmFyaWF0ZVNoYWRpbmcgKmdldFNoYWRpbmcoKSB7IHJldHVybiBzaGFkaW5nOyB9Cgpwcm90ZWN0ZWQ6CiAgTWF0cml4IGljdG07CiAgZG91YmxlIHQwLCB0MSwgZHQ7CiAgR2Z4VW5pdmFyaWF0ZVNoYWRpbmcgKnNoYWRpbmc7CiAgR2Z4U3RhdGUgKnN0YXRlOwogIFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGU7Cn07CgpjbGFzcyBTcGxhc2hBeGlhbFBhdHRlcm46IHB1YmxpYyBTcGxhc2hVbml2YXJpYXRlUGF0dGVybiB7CnB1YmxpYzoKCiAgU3BsYXNoQXhpYWxQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4QXhpYWxTaGFkaW5nICpzaGFkaW5nKTsKCiAgdmlydHVhbCBTcGxhc2hQYXR0ZXJuICpjb3B5KCkgeyByZXR1cm4gbmV3IFNwbGFzaEF4aWFsUGF0dGVybihjb2xvck1vZGUsIHN0YXRlLCAoR2Z4QXhpYWxTaGFkaW5nICopIHNoYWRpbmcpOyB9CgogIHZpcnR1YWwgflNwbGFzaEF4aWFsUGF0dGVybigpOwoKICB2aXJ0dWFsIEdCb29sIGdldFBhcmFtZXRlcihkb3VibGUgeHMsIGRvdWJsZSB5cywgZG91YmxlICp0KTsKCnByaXZhdGU6CiAgZG91YmxlIHgwLCB5MCwgeDEsIHkxOwogIGRvdWJsZSBkeCwgZHksIG11bDsKfTsKCi8vIHNlZSBHZnhTdGF0ZS5oLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nCmNsYXNzIFNwbGFzaEdvdXJhdWRQYXR0ZXJuOiBwdWJsaWMgU3BsYXNoR291cmF1ZENvbG9yIHsKcHVibGljOgoKICBTcGxhc2hHb3VyYXVkUGF0dGVybihHQm9vbCBiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgR2Z4U3RhdGUgKnN0YXRlLCBHZnhHb3VyYXVkVHJpYW5nbGVTaGFkaW5nICpzaGFkaW5nLCBTcGxhc2hDb2xvck1vZGUgbW9kZSk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hHb3VyYXVkUGF0dGVybihiRGlyZWN0Q29sb3JUcmFuc2xhdGlvbiwgc3RhdGUsIHNoYWRpbmcsIG1vZGUpOyB9CgogIHZpcnR1YWwgflNwbGFzaEdvdXJhdWRQYXR0ZXJuKCk7CgogIHZpcnR1YWwgR0Jvb2wgZ2V0Q29sb3IoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBjKSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCB0ZXN0UG9zaXRpb24oaW50IHgsIGludCB5KSB7IHJldHVybiBnRmFsc2U7IH0KCiAgdmlydHVhbCBHQm9vbCBpc1N0YXRpYygpIHsgcmV0dXJuIGdGYWxzZTsgfQoKICB2aXJ0dWFsIEdCb29sIGlzUGFyYW1ldGVyaXplZCgpIHsgcmV0dXJuIHNoYWRpbmctPmlzUGFyYW1ldGVyaXplZCgpOyB9CiAgdmlydHVhbCBpbnQgZ2V0TlRyaWFuZ2xlcygpIHsgcmV0dXJuIHNoYWRpbmctPmdldE5UcmlhbmdsZXMoKTsgfQogIHZpcnR1YWwgIHZvaWQgZ2V0VHJpYW5nbGUoaW50IGksIGRvdWJsZSAqeDAsIGRvdWJsZSAqeTAsIGRvdWJsZSAqY29sb3IwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlICp4MSwgZG91YmxlICp5MSwgZG91YmxlICpjb2xvcjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgKngyLCBkb3VibGUgKnkyLCBkb3VibGUgKmNvbG9yMikKICB7IHJldHVybiBzaGFkaW5nLT5nZXRUcmlhbmdsZShpLCB4MCwgeTAsIGNvbG9yMCwgeDEsIHkxLCBjb2xvcjEsIHgyLCB5MiwgY29sb3IyKTsgfQoKICB2aXJ0dWFsIHZvaWQgZ2V0UGFyYW1ldGVyaXplZENvbG9yKGRvdWJsZSB0LCBTcGxhc2hDb2xvck1vZGUgbW9kZSwgU3BsYXNoQ29sb3JQdHIgYyk7Cgpwcml2YXRlOgogIEdmeEdvdXJhdWRUcmlhbmdsZVNoYWRpbmcgKnNoYWRpbmc7CiAgR2Z4U3RhdGUgKnN0YXRlOwogIEdCb29sIGJEaXJlY3RDb2xvclRyYW5zbGF0aW9uOwogIFNwbGFzaENvbG9yTW9kZSBtb2RlOwp9OwoKLy8gc2VlIEdmeFN0YXRlLmgsIEdmeFJhZGlhbFNoYWRpbmcKY2xhc3MgU3BsYXNoUmFkaWFsUGF0dGVybjogcHVibGljIFNwbGFzaFVuaXZhcmlhdGVQYXR0ZXJuIHsKcHVibGljOgoKICBTcGxhc2hSYWRpYWxQYXR0ZXJuKFNwbGFzaENvbG9yTW9kZSBjb2xvck1vZGUsIEdmeFN0YXRlICpzdGF0ZSwgR2Z4UmFkaWFsU2hhZGluZyAqc2hhZGluZyk7CgogIHZpcnR1YWwgU3BsYXNoUGF0dGVybiAqY29weSgpIHsgcmV0dXJuIG5ldyBTcGxhc2hSYWRpYWxQYXR0ZXJuKGNvbG9yTW9kZSwgc3RhdGUsIChHZnhSYWRpYWxTaGFkaW5nICopIHNoYWRpbmcpOyB9CgogIHZpcnR1YWwgflNwbGFzaFJhZGlhbFBhdHRlcm4oKTsKCiAgdmlydHVhbCBHQm9vbCBnZXRQYXJhbWV0ZXIoZG91YmxlIHhzLCBkb3VibGUgeXMsIGRvdWJsZSAqdCk7Cgpwcml2YXRlOgogIGRvdWJsZSB4MCwgeTAsIHIwLCBkeCwgZHksIGRyOwogIGRvdWJsZSBhLCBpbnZhOwp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIG51bWJlciBvZiBUeXBlIDMgZm9udHMgdG8gY2FjaGUKI2RlZmluZSBzcGxhc2hPdXRUM0ZvbnRDYWNoZVNpemUgOAoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoT3V0cHV0RGV2Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hPdXRwdXREZXY6IHB1YmxpYyBPdXRwdXREZXYgewpwdWJsaWM6CgogIC8vIENvbnN0cnVjdG9yLgogIFNwbGFzaE91dHB1dERldihTcGxhc2hDb2xvck1vZGUgY29sb3JNb2RlQSwgaW50IGJpdG1hcFJvd1BhZEEsCgkJICBHQm9vbCByZXZlcnNlVmlkZW9BLCBTcGxhc2hDb2xvclB0ciBwYXBlckNvbG9yQSwKCQkgIEdCb29sIGJpdG1hcFRvcERvd25BID0gZ1RydWUsCgkJICBHQm9vbCBhbGxvd0FudGlhbGlhc0EgPSBnVHJ1ZSk7CgogIC8vIERlc3RydWN0b3IuCiAgdmlydHVhbCB+U3BsYXNoT3V0cHV0RGV2KCk7CgogIC8vLS0tLS0gZ2V0IGluZm8gYWJvdXQgb3V0cHV0IGRldmljZQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB0aWxpbmdQYXR0ZXJuRmlsbCgpPyAgSWYgdGhpcyByZXR1cm5zIGZhbHNlLAogIC8vIHRpbGluZyBwYXR0ZXJuIGZpbGxzIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nCiAgLy8gb3BlcmF0aW9ucy4KICB2aXJ0dWFsIEdCb29sIHVzZVRpbGluZ1BhdHRlcm5GaWxsKCkgeyByZXR1cm4gZ1RydWU7IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgZnVuY3Rpb25TaGFkZWRGaWxsKCksIGF4aWFsU2hhZGVkRmlsbCgpLCBhbmQKICAvLyByYWRpYWxTaGFkZWRGaWxsKCk/ICBJZiB0aGlzIHJldHVybnMgZmFsc2UsIHRoZXNlIHNoYWRlZCBmaWxscwogIC8vIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNlcmllcyBvZiBvdGhlciBkcmF3aW5nIG9wZXJhdGlvbnMuCiAgdmlydHVhbCBHQm9vbCB1c2VTaGFkZWRGaWxscyhpbnQgdHlwZSkKICB7IHJldHVybiAodHlwZSA+PSAyICYmIHR5cGUgPD0gNSkgPyBnVHJ1ZSA6IGdGYWxzZTsgfQoKICAvLyBEb2VzIHRoaXMgZGV2aWNlIHVzZSB1cHNpZGUtZG93biBjb29yZGluYXRlcz8KICAvLyAoVXBzaWRlLWRvd24gbWVhbnMgKDAsMCkgaXMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgcGFnZS4pCiAgdmlydHVhbCBHQm9vbCB1cHNpZGVEb3duKCkgeyByZXR1cm4gYml0bWFwVG9wRG93biBeIGJpdG1hcFVwc2lkZURvd247IH0KCiAgLy8gRG9lcyB0aGlzIGRldmljZSB1c2UgZHJhd0NoYXIoKSBvciBkcmF3U3RyaW5nKCk/CiAgdmlydHVhbCBHQm9vbCB1c2VEcmF3Q2hhcigpIHsgcmV0dXJuIGdUcnVlOyB9CgogIC8vIERvZXMgdGhpcyBkZXZpY2UgdXNlIGJlZ2luVHlwZTNDaGFyL2VuZFR5cGUzQ2hhcj8gIE90aGVyd2lzZSwKICAvLyB0ZXh0IGluIFR5cGUgMyBmb250cyB3aWxsIGJlIGRyYXduIHdpdGggZHJhd0NoYXIvZHJhd1N0cmluZy4KICB2aXJ0dWFsIEdCb29sIGludGVycHJldFR5cGUzQ2hhcnMoKSB7IHJldHVybiBnVHJ1ZTsgfQoKICAvLy0tLS0tIGluaXRpYWxpemF0aW9uIGFuZCBjb250cm9sCgogIC8vIFN0YXJ0IGEgcGFnZS4KICB2aXJ0dWFsIHZvaWQgc3RhcnRQYWdlKGludCBwYWdlTnVtLCBHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLyBFbmQgYSBwYWdlLgogIHZpcnR1YWwgdm9pZCBlbmRQYWdlKCk7CgogIC8vLS0tLS0gc2F2ZS9yZXN0b3JlIGdyYXBoaWNzIHN0YXRlCiAgdmlydHVhbCB2b2lkIHNhdmVTdGF0ZShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCByZXN0b3JlU3RhdGUoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB1cGRhdGUgZ3JhcGhpY3Mgc3RhdGUKICB2aXJ0dWFsIHZvaWQgdXBkYXRlQWxsKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUNUTShHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSBtMTEsIGRvdWJsZSBtMTIsCgkJCSBkb3VibGUgbTIxLCBkb3VibGUgbTIyLCBkb3VibGUgbTMxLCBkb3VibGUgbTMyKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZURhc2goR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmxhdG5lc3MoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZUpvaW4oR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlTGluZUNhcChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVNaXRlckxpbWl0KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUxpbmVXaWR0aChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VBZGp1c3QoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlRmlsbENvbG9yKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0cm9rZUNvbG9yKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUJsZW5kTW9kZShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVGaWxsT3BhY2l0eShHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCB1cGRhdGVTdHJva2VPcGFjaXR5KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZUZpbGxPdmVycHJpbnQoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3Ryb2tlT3ZlcnByaW50KEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHVwZGF0ZU92ZXJwcmludE1vZGUoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgdXBkYXRlVHJhbnNmZXIoR2Z4U3RhdGUgKnN0YXRlKTsKCiAgLy8tLS0tLSB1cGRhdGUgdGV4dCBzdGF0ZQogIHZpcnR1YWwgdm9pZCB1cGRhdGVGb250KEdmeFN0YXRlICpzdGF0ZSk7CgogIC8vLS0tLS0gcGF0aCBwYWludGluZwogIHZpcnR1YWwgdm9pZCBzdHJva2UoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgZmlsbChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBlb0ZpbGwoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIEdCb29sIHRpbGluZ1BhdHRlcm5GaWxsKEdmeFN0YXRlICpzdGF0ZSwgR2Z4ICpnZngsIENhdGFsb2cgKmNhdGFsb2csIE9iamVjdCAqc3RyLAoJCQkJICBkb3VibGUgKnBtYXQsIGludCBwYWludFR5cGUsIGludCB0aWxpbmdUeXBlLCBEaWN0ICpyZXNEaWN0LAoJCQkJICBkb3VibGUgKm1hdCwgZG91YmxlICpiYm94LAoJCQkJICBpbnQgeDAsIGludCB5MCwgaW50IHgxLCBpbnQgeTEsCgkJCQkgIGRvdWJsZSB4U3RlcCwgZG91YmxlIHlTdGVwKTsKICB2aXJ0dWFsIEdCb29sIGF4aWFsU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeEF4aWFsU2hhZGluZyAqc2hhZGluZywgZG91YmxlIHRNaW4sIGRvdWJsZSB0TWF4KTsKICB2aXJ0dWFsIEdCb29sIHJhZGlhbFNoYWRlZEZpbGwoR2Z4U3RhdGUgKnN0YXRlLCBHZnhSYWRpYWxTaGFkaW5nICpzaGFkaW5nLCBkb3VibGUgdE1pbiwgZG91YmxlIHRNYXgpOwogIHZpcnR1YWwgR0Jvb2wgZ291cmF1ZFRyaWFuZ2xlU2hhZGVkRmlsbChHZnhTdGF0ZSAqc3RhdGUsIEdmeEdvdXJhdWRUcmlhbmdsZVNoYWRpbmcgKnNoYWRpbmcpOwoKICAvLy0tLS0tIHBhdGggY2xpcHBpbmcKICB2aXJ0dWFsIHZvaWQgY2xpcChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgdm9pZCBlb0NsaXAoR2Z4U3RhdGUgKnN0YXRlKTsKICB2aXJ0dWFsIHZvaWQgY2xpcFRvU3Ryb2tlUGF0aChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHRleHQgZHJhd2luZwogIHZpcnR1YWwgdm9pZCBkcmF3Q2hhcihHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSB4LCBkb3VibGUgeSwKCQkJZG91YmxlIGR4LCBkb3VibGUgZHksCgkJCWRvdWJsZSBvcmlnaW5YLCBkb3VibGUgb3JpZ2luWSwKCQkJQ2hhckNvZGUgY29kZSwgaW50IG5CeXRlcywgVW5pY29kZSAqdSwgaW50IHVMZW4pOwogIHZpcnR1YWwgR0Jvb2wgYmVnaW5UeXBlM0NoYXIoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgeCwgZG91YmxlIHksCgkJCSAgICAgICBkb3VibGUgZHgsIGRvdWJsZSBkeSwKCQkJICAgICAgIENoYXJDb2RlIGNvZGUsIFVuaWNvZGUgKnUsIGludCB1TGVuKTsKICB2aXJ0dWFsIHZvaWQgZW5kVHlwZTNDaGFyKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIGJlZ2luVGV4dE9iamVjdChHZnhTdGF0ZSAqc3RhdGUpOwogIHZpcnR1YWwgR0Jvb2wgZGV2aWNlSGFzVGV4dENsaXAoR2Z4U3RhdGUgKnN0YXRlKSB7IHJldHVybiB0ZXh0Q2xpcFBhdGg7IH0KICB2aXJ0dWFsIHZvaWQgZW5kVGV4dE9iamVjdChHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIGltYWdlIGRyYXdpbmcKICB2aXJ0dWFsIHZvaWQgZHJhd0ltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsIEdCb29sIGludmVydCwKCQkJICAgICBHQm9vbCBpbnRlcnBvbGF0ZSwgR0Jvb2wgaW5saW5lSW1nKTsKICB2aXJ0dWFsIHZvaWQgc2V0U29mdE1hc2tGcm9tSW1hZ2VNYXNrKEdmeFN0YXRlICpzdGF0ZSwKCQkJCQlPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkJaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBHQm9vbCBpbnZlcnQsCgkJCQkJR0Jvb2wgaW5saW5lSW1nLCBkb3VibGUgKmJhc2VNYXRyaXgpOwogIHZpcnR1YWwgdm9pZCB1bnNldFNvZnRNYXNrRnJvbUltYWdlTWFzayhHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmFzZU1hdHJpeCk7CiAgdmlydHVhbCB2b2lkIGRyYXdJbWFnZShHZnhTdGF0ZSAqc3RhdGUsIE9iamVjdCAqcmVmLCBTdHJlYW0gKnN0ciwKCQkJIGludCB3aWR0aCwgaW50IGhlaWdodCwgR2Z4SW1hZ2VDb2xvck1hcCAqY29sb3JNYXAsCgkJCSBHQm9vbCBpbnRlcnBvbGF0ZSwgaW50ICptYXNrQ29sb3JzLCBHQm9vbCBpbmxpbmVJbWcpOwogIHZpcnR1YWwgdm9pZCBkcmF3TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCSAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCSAgICAgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJICAgICAgIEdCb29sIGludGVycG9sYXRlLAoJCQkgICAgICAgU3RyZWFtICptYXNrU3RyLCBpbnQgbWFza1dpZHRoLCBpbnQgbWFza0hlaWdodCwKCQkJICAgICAgIEdCb29sIG1hc2tJbnZlcnQsIEdCb29sIG1hc2tJbnRlcnBvbGF0ZSk7CiAgdmlydHVhbCB2b2lkIGRyYXdTb2Z0TWFza2VkSW1hZ2UoR2Z4U3RhdGUgKnN0YXRlLCBPYmplY3QgKnJlZiwgU3RyZWFtICpzdHIsCgkJCQkgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICpjb2xvck1hcCwKCQkJCSAgIEdCb29sIGludGVycG9sYXRlLAoJCQkJICAgU3RyZWFtICptYXNrU3RyLAoJCQkJICAgaW50IG1hc2tXaWR0aCwgaW50IG1hc2tIZWlnaHQsCgkJCQkgICBHZnhJbWFnZUNvbG9yTWFwICptYXNrQ29sb3JNYXAsCgkJCQkgICBHQm9vbCBtYXNrSW50ZXJwb2xhdGUpOwoKICAvLy0tLS0tIFR5cGUgMyBmb250IG9wZXJhdG9ycwogIHZpcnR1YWwgdm9pZCB0eXBlM0QwKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3kpOwogIHZpcnR1YWwgdm9pZCB0eXBlM0QxKEdmeFN0YXRlICpzdGF0ZSwgZG91YmxlIHd4LCBkb3VibGUgd3ksCgkJICAgICAgIGRvdWJsZSBsbHgsIGRvdWJsZSBsbHksIGRvdWJsZSB1cngsIGRvdWJsZSB1cnkpOwoKICAvLy0tLS0tIHRyYW5zcGFyZW5jeSBncm91cHMgYW5kIHNvZnQgbWFza3MKICB2aXJ0dWFsIEdCb29sIGNoZWNrVHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBHQm9vbCBrbm9ja291dCk7CiAgdmlydHVhbCB2b2lkIGJlZ2luVHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgKmJib3gsCgkJCQkgICAgICBHZnhDb2xvclNwYWNlICpibGVuZGluZ0NvbG9yU3BhY2UsCgkJCQkgICAgICBHQm9vbCBpc29sYXRlZCwgR0Jvb2wga25vY2tvdXQsCgkJCQkgICAgICBHQm9vbCBmb3JTb2Z0TWFzayk7CiAgdmlydHVhbCB2b2lkIGVuZFRyYW5zcGFyZW5jeUdyb3VwKEdmeFN0YXRlICpzdGF0ZSk7CiAgdmlydHVhbCB2b2lkIHBhaW50VHJhbnNwYXJlbmN5R3JvdXAoR2Z4U3RhdGUgKnN0YXRlLCBkb3VibGUgKmJib3gpOwogIHZpcnR1YWwgdm9pZCBzZXRTb2Z0TWFzayhHZnhTdGF0ZSAqc3RhdGUsIGRvdWJsZSAqYmJveCwgR0Jvb2wgYWxwaGEsCgkJCSAgIEZ1bmN0aW9uICp0cmFuc2ZlckZ1bmMsIEdmeENvbG9yICpiYWNrZHJvcENvbG9yKTsKICB2aXJ0dWFsIHZvaWQgY2xlYXJTb2Z0TWFzayhHZnhTdGF0ZSAqc3RhdGUpOwoKICAvLy0tLS0tIHNwZWNpYWwgYWNjZXNzCgogIC8vIENhbGxlZCB0byBpbmRpY2F0ZSB0aGF0IGEgbmV3IFBERiBkb2N1bWVudCBoYXMgYmVlbiBsb2FkZWQuCiAgdm9pZCBzdGFydERvYyhQREZEb2MgKmRvY0EpOwogCiAgdm9pZCBzZXRQYXBlckNvbG9yKFNwbGFzaENvbG9yUHRyIHBhcGVyQ29sb3JBKTsKCiAgR0Jvb2wgaXNSZXZlcnNlVmlkZW8oKSB7IHJldHVybiByZXZlcnNlVmlkZW87IH0KICB2b2lkIHNldFJldmVyc2VWaWRlbyhHQm9vbCByZXZlcnNlVmlkZW9BKSB7IHJldmVyc2VWaWRlbyA9IHJldmVyc2VWaWRlb0E7IH0KCiAgLy8gR2V0IHRoZSBiaXRtYXAgYW5kIGl0cyBzaXplLgogIFNwbGFzaEJpdG1hcCAqZ2V0Qml0bWFwKCkgeyByZXR1cm4gYml0bWFwOyB9CiAgaW50IGdldEJpdG1hcFdpZHRoKCk7CiAgaW50IGdldEJpdG1hcEhlaWdodCgpOwoKICAvLyBSZXR1cm5zIHRoZSBsYXN0IHJhc3Rlcml6ZWQgYml0bWFwLCB0cmFuc2ZlcnJpbmcgb3duZXJzaGlwIHRvIHRoZQogIC8vIGNhbGxlci4KICBTcGxhc2hCaXRtYXAgKnRha2VCaXRtYXAoKTsKCiAgLy8gU2V0IHRoaXMgZmxhZyB0byB0cnVlIHRvIGdlbmVyYXRlIGFuIHVwc2lkZS1kb3duIGJpdG1hcCAodXNlZnVsCiAgLy8gZm9yIFdpbmRvd3MgQk1QIGZpbGVzKS4KICB2b2lkIHNldEJpdG1hcFVwc2lkZURvd24oR0Jvb2wgZikgeyBiaXRtYXBVcHNpZGVEb3duID0gZjsgfQoKICAvLyBHZXQgdGhlIFNwbGFzaCBvYmplY3QuCiAgU3BsYXNoICpnZXRTcGxhc2goKSB7IHJldHVybiBzcGxhc2g7IH0KCiAgLy8gR2V0IHRoZSBtb2RpZmllZCByZWdpb24uCiAgdm9pZCBnZXRNb2RSZWdpb24oaW50ICp4TWluLCBpbnQgKnlNaW4sIGludCAqeE1heCwgaW50ICp5TWF4KTsKCiAgLy8gQ2xlYXIgdGhlIG1vZGlmaWVkIHJlZ2lvbi4KICB2b2lkIGNsZWFyTW9kUmVnaW9uKCk7CgogIFNwbGFzaEZvbnQgKmdldEN1cnJlbnRGb250KCkgeyByZXR1cm4gZm9udDsgfQoKICAvLyBJZiA8c2tpcFRleHRBPiBpcyB0cnVlLCBkb24ndCBkcmF3IGhvcml6b250YWwgdGV4dC4KICAvLyBJZiA8c2tpcFJvdGF0ZWRUZXh0QT4gaXMgdHJ1ZSwgZG9uJ3QgZHJhdyByb3RhdGVkIChub24taG9yaXpvbnRhbCkgdGV4dC4KICB2b2lkIHNldFNraXBUZXh0KEdCb29sIHNraXBIb3JpelRleHRBLCBHQm9vbCBza2lwUm90YXRlZFRleHRBKQogICAgeyBza2lwSG9yaXpUZXh0ID0gc2tpcEhvcml6VGV4dEE7IHNraXBSb3RhdGVkVGV4dCA9IHNraXBSb3RhdGVkVGV4dEE7IH0KCiAgaW50IGdldE5lc3RDb3VudCgpIHsgcmV0dXJuIG5lc3RDb3VudDsgfQoKI2lmIDEgLy9+dG1wOiB0dXJuIG9mZiBhbnRpLWFsaWFzaW5nIHRlbXBvcmFyaWx5CiAgdmlydHVhbCBHQm9vbCBnZXRWZWN0b3JBbnRpYWxpYXMoKTsKICB2aXJ0dWFsIHZvaWQgc2V0VmVjdG9yQW50aWFsaWFzKEdCb29sIHZhYSk7CiNlbmRpZgoKICB2b2lkIHNldEZyZWVUeXBlSGludGluZyhHQm9vbCBlbmFibGUsIEdCb29sIGVuYWJsZVNsaWdodEhpbnRpbmcpOwoKcHJvdGVjdGVkOgogIHZvaWQgZG9VcGRhdGVGb250KEdmeFN0YXRlICpzdGF0ZSk7Cgpwcml2YXRlOgogIEdCb29sIHVuaXZhcmlhdGVTaGFkZWRGaWxsKEdmeFN0YXRlICpzdGF0ZSwgU3BsYXNoVW5pdmFyaWF0ZVBhdHRlcm4gKnBhdHRlcm4sIGRvdWJsZSB0TWluLCBkb3VibGUgdE1heCk7CgogIHZvaWQgc2V0dXBTY3JlZW5QYXJhbXMoZG91YmxlIGhEUEksIGRvdWJsZSB2RFBJKTsKICBTcGxhc2hQYXR0ZXJuICpnZXRDb2xvcihHZnhHcmF5IGdyYXkpOwogIFNwbGFzaFBhdHRlcm4gKmdldENvbG9yKEdmeFJHQiAqcmdiKTsKI2lmIFNQTEFTSF9DTVlLCiAgU3BsYXNoUGF0dGVybiAqZ2V0Q29sb3IoR2Z4Q01ZSyAqY215ayk7CiNlbmRpZgogIHZvaWQgc2V0T3ZlcnByaW50TWFzayhHZnhDb2xvclNwYWNlICpjb2xvclNwYWNlLCBHQm9vbCBvdmVycHJpbnRGbGFnLAoJCQlpbnQgb3ZlcnByaW50TW9kZSwgR2Z4Q29sb3IgKnNpbmdsZUNvbG9yLCBHQm9vbCBncmF5SW5kZXhlZCA9IGdGYWxzZSk7CiAgU3BsYXNoUGF0aCAqY29udmVydFBhdGgoR2Z4U3RhdGUgKnN0YXRlLCBHZnhQYXRoICpwYXRoLAoJCQkgIEdCb29sIGRyb3BFbXB0eVN1YnBhdGhzKTsKICB2b2lkIGRyYXdUeXBlM0dseXBoKEdmeFN0YXRlICpzdGF0ZSwgVDNGb250Q2FjaGUgKnQzRm9udCwKCQkgICAgICBUM0ZvbnRDYWNoZVRhZyAqdGFnLCBHdWNoYXIgKmRhdGEpOwogIHN0YXRpYyBHQm9vbCBpbWFnZU1hc2tTcmModm9pZCAqZGF0YSwgU3BsYXNoQ29sb3JQdHIgbGluZSk7CiAgc3RhdGljIEdCb29sIGltYWdlU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGNvbG9yTGluZSwKCQkJR3VjaGFyICphbHBoYUxpbmUpOwogIHN0YXRpYyBHQm9vbCBhbHBoYUltYWdlU3JjKHZvaWQgKmRhdGEsIFNwbGFzaENvbG9yUHRyIGxpbmUsCgkJCSAgICAgR3VjaGFyICphbHBoYUxpbmUpOwogIHN0YXRpYyBHQm9vbCBtYXNrZWRJbWFnZVNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBsaW5lLAoJCQkgICAgICBHdWNoYXIgKmFscGhhTGluZSk7CiAgc3RhdGljIEdCb29sIHRpbGluZ0JpdG1hcFNyYyh2b2lkICpkYXRhLCBTcGxhc2hDb2xvclB0ciBsaW5lLAoJCQkgICAgIEd1Y2hhciAqYWxwaGFMaW5lKTsKCiAgR0Jvb2wga2VlcEFscGhhQ2hhbm5lbDsJLy8gZG9uJ3QgZmlsbCB3aXRoIHBhcGVyIGNvbG9yLCBrZWVwIGFscGhhIGNoYW5uZWwKCiAgU3BsYXNoQ29sb3JNb2RlIGNvbG9yTW9kZTsKICBpbnQgYml0bWFwUm93UGFkOwogIEdCb29sIGJpdG1hcFRvcERvd247CiAgR0Jvb2wgYml0bWFwVXBzaWRlRG93bjsKICBHQm9vbCBhbGxvd0FudGlhbGlhczsKICBHQm9vbCB2ZWN0b3JBbnRpYWxpYXM7CiAgR0Jvb2wgZW5hYmxlRnJlZVR5cGVIaW50aW5nOwogIEdCb29sIGVuYWJsZVNsaWdodEhpbnRpbmc7CiAgR0Jvb2wgcmV2ZXJzZVZpZGVvOwkJLy8gcmV2ZXJzZSB2aWRlbyBtb2RlCiAgU3BsYXNoQ29sb3IgcGFwZXJDb2xvcjsJLy8gcGFwZXIgY29sb3IKICBTcGxhc2hTY3JlZW5QYXJhbXMgc2NyZWVuUGFyYW1zOwogIEdCb29sIHNraXBIb3JpelRleHQ7CiAgR0Jvb2wgc2tpcFJvdGF0ZWRUZXh0OwoKICBQREZEb2MgKmRvYzsJCQkvLyB0aGUgY3VycmVudCBkb2N1bWVudAoKICBTcGxhc2hCaXRtYXAgKmJpdG1hcDsKICBTcGxhc2ggKnNwbGFzaDsKICBTcGxhc2hGb250RW5naW5lICpmb250RW5naW5lOwoKICBUM0ZvbnRDYWNoZSAqCQkJLy8gVHlwZSAzIGZvbnQgY2FjaGUKICAgIHQzRm9udENhY2hlW3NwbGFzaE91dFQzRm9udENhY2hlU2l6ZV07CiAgaW50IG5UM0ZvbnRzOwkJCS8vIG51bWJlciBvZiB2YWxpZCBlbnRyaWVzIGluIHQzRm9udENhY2hlCiAgVDNHbHlwaFN0YWNrICp0M0dseXBoU3RhY2s7CS8vIFR5cGUgMyBnbHlwaCBjb250ZXh0IHN0YWNrCiAgR0Jvb2wgaGF2ZVQzRHg7CQkvLyBzZXQgYWZ0ZXIgc2VlaW5nIGEgZDAvZDEgb3BlcmF0b3IKCiAgU3BsYXNoRm9udCAqZm9udDsJCS8vIGN1cnJlbnQgZm9udAogIEdCb29sIG5lZWRGb250VXBkYXRlOwkJLy8gc2V0IHdoZW4gdGhlIGZvbnQgbmVlZHMgdG8gYmUgdXBkYXRlZAogIFNwbGFzaFBhdGggKnRleHRDbGlwUGF0aDsJLy8gY2xpcHBpbmcgcGF0aCBidWlsdCB3aXRoIHRleHQgb2JqZWN0CgogIFNwbGFzaFRyYW5zcGFyZW5jeUdyb3VwICoJLy8gdHJhbnNwYXJlbmN5IGdyb3VwIHN0YWNrCiAgICB0cmFuc3BHcm91cFN0YWNrOwogIFNwbGFzaEJpdG1hcCAqbWFza0JpdG1hcDsgLy8gZm9yIGltYWdlIG1hc2tzIGluIHBhdHRlcm4gY29sb3JzcGFjZQogIGludCBuZXN0Q291bnQ7Cn07CgojZW5kaWYK