LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2ZyZWV0eXBlLmMsdiAxLjExIDIwMDIvMDgvMzEgMjI6MTc6MzIga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDEgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgImZjaW50LmgiCiNpbmNsdWRlIDxmcmVldHlwZS9mcmVldHlwZS5oPgojaW5jbHVkZSA8ZnJlZXR5cGUvaW50ZXJuYWwvZnRvYmpzLmg+CiNpbmNsdWRlIDxmcmVldHlwZS90dHRhYmxlcy5oPgojaW5jbHVkZSA8ZnJlZXR5cGUvZnRzbmFtZXMuaD4KI2luY2x1ZGUgPGZyZWV0eXBlL3R0bmFtZWlkLmg+CgovKgogKiBLZWVwIEhhbiBsYW5ndWFnZXMgc2VwYXJhdGVkIGJ5IGVsaW1pbmF0aW5nIGxhbmd1YWdlcwogKiB0aGF0IHRoZSBjb2RlUGFnZVJhbmdlIGJpdHMgc2F5cyBhcmVuJ3Qgc3VwcG9ydGVkCiAqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCB7CiAgICBpbnQJCSAgICBiaXQ7CiAgICBjb25zdCBGY0NoYXI4ICAgKmxhbmc7Cn0gRmNDb2RlUGFnZVJhbmdlW10gPSB7CiAgICB7IDE3LAkoY29uc3QgRmNDaGFyOCAqKSAiamEiIH0sCiAgICB7IDE4LAkoY29uc3QgRmNDaGFyOCAqKSAiemgtY24iIH0sCiAgICB7IDE5LAkoY29uc3QgRmNDaGFyOCAqKSAia28iIH0sCiAgICB7IDIwLAkoY29uc3QgRmNDaGFyOCAqKSAiemgtdHciIH0sCn07CgojZGVmaW5lIE5VTV9DT0RFX1BBR0VfUkFOR0UgKHNpemVvZiBGY0NvZGVQYWdlUmFuZ2UgLyBzaXplb2YgRmNDb2RlUGFnZVJhbmdlWzBdKQoKRmNCb29sCkZjRnJlZVR5cGVJc0V4Y2x1c2l2ZUxhbmcgKGNvbnN0IEZjQ2hhcjggICpsYW5nKQp7CiAgICBpbnQJICAgIGk7CgogICAgZm9yIChpID0gMDsgaSA8IE5VTV9DT0RFX1BBR0VfUkFOR0U7IGkrKykKICAgIHsKCWlmIChGY0xhbmdDb21wYXJlIChsYW5nLCBGY0NvZGVQYWdlUmFuZ2VbaV0ubGFuZykgIT0gRmNMYW5nRGlmZmVyZW50TGFuZykKCSAgICByZXR1cm4gRmNUcnVlOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCiNkZWZpbmUgRkNfTkFNRV9QUklPX0xBTkcJICAgIDB4MGYwMAojZGVmaW5lIEZDX05BTUVfUFJJT19MQU5HX0VOR0xJU0ggICAweDAyMDAKI2RlZmluZSBGQ19OQU1FX1BSSU9fTEFOR19MQVRJTgkgICAgMHgwMTAwCiNkZWZpbmUgRkNfTkFNRV9QUklPX0xBTkdfTk9ORQkgICAgMHgwMDAwCgojZGVmaW5lIEZDX05BTUVfUFJJT19FTkMJICAgIDB4MDBmMAojZGVmaW5lIEZDX05BTUVfUFJJT19FTkNfVU5JQ09ERSAgICAweDAwMTAKI2RlZmluZSBGQ19OQU1FX1BSSU9fRU5DX05PTkUJICAgIDB4MDAwMAoKI2RlZmluZSBGQ19OQU1FX1BSSU9fTkFNRQkgICAgMHgwMDBmCiNkZWZpbmUgRkNfTkFNRV9QUklPX05BTUVfRkFNSUxZICAgIDB4MDAwMgojZGVmaW5lIEZDX05BTUVfUFJJT19OQU1FX1BTCSAgICAweDAwMDEKI2RlZmluZSBGQ19OQU1FX1BSSU9fTkFNRV9OT05FCSAgICAweDAwMDAKCnN0YXRpYyBGY0Jvb2wKRmNVY3M0SXNMYXRpbiAoRmNDaGFyMzIgdWNzNCkKewogICAgRmNDaGFyMzIJcGFnZSA9IHVjczQgPj4gODsKICAgIAogICAgaWYgKHBhZ2UgPD0gMikKCXJldHVybiBGY1RydWU7CiAgICBpZiAocGFnZSA9PSAweDFlKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGlmICgweDIwIDw9IHBhZ2UgJiYgcGFnZSA8PSAweDIzKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGlmIChwYWdlID09IDB4ZmIpCglyZXR1cm4gRmNUcnVlOwogICAgaWYgKHBhZ2UgPT0gMHhmZikKCXJldHVybiBGY1RydWU7CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjQm9vbApGY1V0ZjhJc0xhdGluIChGY0NoYXI4ICpzdHIsIGludCBsZW4pCnsKICAgIHdoaWxlIChsZW4pCiAgICB7CglGY0NoYXIzMiAgICB1Y3M0OwoJaW50CSAgICBjbGVuID0gRmNVdGY4VG9VY3M0IChzdHIsICZ1Y3M0LCBsZW4pOwoJaWYgKGNsZW4gPD0gMCkKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmICghRmNVY3M0SXNMYXRpbiAodWNzNCkpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglsZW4gLT0gY2xlbjsKCXN0ciArPSBjbGVuOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNQYXR0ZXJuICoKRmNGcmVlVHlwZVF1ZXJ5IChjb25zdCBGY0NoYXI4CSpmaWxlLAoJCSBpbnQJCWlkLAoJCSBGY0JsYW5rcwkqYmxhbmtzLAoJCSBpbnQJCSpjb3VudCkKewogICAgRlRfRmFjZQkgICAgZmFjZTsKICAgIEZjUGF0dGVybgkgICAgKnBhdDsKICAgIGludAkJICAgIHNsYW50OwogICAgaW50CQkgICAgd2VpZ2h0OwogICAgaW50CQkgICAgaTsKICAgIEZjQ2hhclNldAkgICAgKmNzOwogICAgRmNMYW5nU2V0CSAgICAqbHM7CiAgICBGVF9MaWJyYXJ5CSAgICBmdExpYnJhcnk7CiAgICBGY0NoYXI4CSAgICAqZmFtaWx5OwogICAgRmNDaGFyOAkgICAgKnN0eWxlOwogICAgVFRfT1MyCSAgICAqb3MyOwogICAgVFRfSGVhZGVyCSAgICAqaGVhZDsKICAgIGNvbnN0IEZjQ2hhcjggICAqZXhjbHVzaXZlTGFuZyA9IDA7CiAgICBGVF9TZm50TmFtZQkgICAgc25hbWU7CiAgICBGVF9VSW50ICAgIAkgICAgc25hbWVpLCBzbmFtZWM7CiAgICBGY0Jvb2wJICAgIGZhbWlseV9hbGxvY2F0ZWQgPSBGY0ZhbHNlOwogICAgRmNCb29sCSAgICBzdHlsZV9hbGxvY2F0ZWQgPSBGY0ZhbHNlOwogICAgaW50CQkgICAgZmFtaWx5X3ByaW8gPSAwOwogICAgaW50CQkgICAgc3R5bGVfcHJpbyA9IDA7CgogICAgaWYgKEZUX0luaXRfRnJlZVR5cGUgKCZmdExpYnJhcnkpKQoJcmV0dXJuIDA7CiAgICAKICAgIGlmIChGVF9OZXdfRmFjZSAoZnRMaWJyYXJ5LCAoY2hhciAqKSBmaWxlLCBpZCwgJmZhY2UpKQoJZ290byBiYWlsOwoKICAgICpjb3VudCA9IGZhY2UtPm51bV9mYWNlczsKCiAgICBwYXQgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIXBhdCkKCWdvdG8gYmFpbDA7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX09VVExJTkUsCgkJCSAgIChmYWNlLT5mYWNlX2ZsYWdzICYgRlRfRkFDRV9GTEFHX1NDQUxBQkxFKSAhPSAwKSkKCWdvdG8gYmFpbDE7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRCb29sIChwYXQsIEZDX1NDQUxBQkxFLAoJCQkgICAoZmFjZS0+ZmFjZV9mbGFncyAmIEZUX0ZBQ0VfRkxBR19TQ0FMQUJMRSkgIT0gMCkpCglnb3RvIGJhaWwxOwoKCiAgICBzbGFudCA9IEZDX1NMQU5UX1JPTUFOOwogICAgaWYgKGZhY2UtPnN0eWxlX2ZsYWdzICYgRlRfU1RZTEVfRkxBR19JVEFMSUMpCglzbGFudCA9IEZDX1NMQU5UX0lUQUxJQzsKCiAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgRkNfU0xBTlQsIHNsYW50KSkKCWdvdG8gYmFpbDE7CgogICAgd2VpZ2h0ID0gRkNfV0VJR0hUX01FRElVTTsKICAgIGlmIChmYWNlLT5zdHlsZV9mbGFncyAmIEZUX1NUWUxFX0ZMQUdfQk9MRCkKCXdlaWdodCA9IEZDX1dFSUdIVF9CT0xEOwoKICAgIGlmICghRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0LCBGQ19XRUlHSFQsIHdlaWdodCkpCglnb3RvIGJhaWwxOwoKICAgIC8qCiAgICAgKiBHcnViIHRocm91Z2ggdGhlIG5hbWUgdGFibGUgbG9va2luZyBmb3IgZmFtaWx5CiAgICAgKiBhbmQgc3R5bGUgbmFtZXMuICBGcmVlVHlwZSBtYWtlcyBxdWl0ZSBhIGhhc2gKICAgICAqIG9mIHRoZW0KICAgICAqLwogICAgZmFtaWx5ID0gMDsKICAgIHN0eWxlID0gMDsKICAgIHNuYW1lYyA9IEZUX0dldF9TZm50X05hbWVfQ291bnQgKGZhY2UpOwogICAgZm9yIChzbmFtZWkgPSAwOyBzbmFtZWkgPCBzbmFtZWM7IHNuYW1laSsrKQogICAgewoJRmNDaGFyOAkJKnV0Zjg7CglpbnQJCWxlbjsKCWludAkJd2NoYXI7CglGY0NoYXI4CQkqc3JjOwoJaW50CQlzcmNfbGVuOwoJRmNDaGFyOAkJKnU4OwoJRmNDaGFyMzIJdWNzNDsKCWludAkJaWxlbiwgb2xlbjsKCWludAkJcHJpbyA9IDA7CgkKCWNvbnN0IEZjQ2hhck1hcAkqbWFwOwoJZW51bSB7CgkgICAgRmNOYW1lRW5jb2RpbmdVdGYxNiwgCgkgICAgRmNOYW1lRW5jb2RpbmdBcHBsZVJvbWFuLAoJICAgIEZjTmFtZUVuY29kaW5nTGF0aW4xIAoJfSBlbmNvZGluZzsKCQoJCglpZiAoRlRfR2V0X1NmbnRfTmFtZSAoZmFjZSwgc25hbWVpLCAmc25hbWUpICE9IDApCgkgICAgYnJlYWs7CgkKCS8qCgkgKiBMb29rIGZvciBVbmljb2RlIHN0cmluZ3MKCSAqLwoJc3dpdGNoIChzbmFtZS5wbGF0Zm9ybV9pZCkgewoJY2FzZSBUVF9QTEFURk9STV9BUFBMRV9VTklDT0RFOgoJICAgIC8qCgkgICAgICogQWxsIEFQUExFX1VOSUNPREUgZW5jb2RpbmdzIGFyZSBVdGYxNiBCRQoJICAgICAqCgkgICAgICogQmVjYXVzZSB0aGVyZSdzIG5vIGxhbmd1YWdlIGlkIGZvciBVbmljb2RlLAoJICAgICAqIGFzc3VtZSBpdCdzIEVuZ2xpc2gKCSAgICAgKi8KCSAgICBwcmlvIHw9IEZDX05BTUVfUFJJT19MQU5HX0VOR0xJU0g7CgkgICAgcHJpbyB8PSBGQ19OQU1FX1BSSU9fRU5DX1VOSUNPREU7CgkgICAgZW5jb2RpbmcgPSBGY05hbWVFbmNvZGluZ1V0ZjE2OwoJICAgIGJyZWFrOwoJY2FzZSBUVF9QTEFURk9STV9NQUNJTlRPU0g6CgkgICAgc3dpdGNoIChzbmFtZS5lbmNvZGluZ19pZCkgewoJICAgIGNhc2UgVFRfTUFDX0lEX1JPTUFOOgoJCWVuY29kaW5nID0gRmNOYW1lRW5jb2RpbmdBcHBsZVJvbWFuOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJY29udGludWU7CgkgICAgfQoJICAgIHN3aXRjaCAoc25hbWUubGFuZ3VhZ2VfaWQpIHsKCSAgICBjYXNlIFRUX01BQ19MQU5HSURfRU5HTElTSDoKCQlwcmlvIHw9IEZDX05BTUVfUFJJT19MQU5HX0VOR0xJU0g7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQkvKgoJCSAqIFNvbWV0aW1lcyBNaWNyb3NvZnQgbGFuZ3VhZ2UgaWRzCgkJICogZW5kIHVwIGluIHRoZSBtYWNpbnRvc2ggdGFibGUuICBUaGlzCgkJICogaXMgb2Z0ZW4gYWNjb21wYW5pZWQgYnkgZGF0YSBpbgoJCSAqIHNvbWUgbXlzdGljIGVuY29kaW5nLiAgSWdub3JlIHRoZXNlIG5hbWVzCgkJICovCgkJaWYgKHNuYW1lLmxhbmd1YWdlX2lkID49IDB4MTAwKQoJCSAgICBjb250aW51ZTsKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFRUX1BMQVRGT1JNX01JQ1JPU09GVDoKCSAgICBzd2l0Y2ggKHNuYW1lLmVuY29kaW5nX2lkKSB7CgkgICAgY2FzZSBUVF9NU19JRF9VTklDT0RFX0NTOgoJCWVuY29kaW5nID0gRmNOYW1lRW5jb2RpbmdVdGYxNjsKCQlwcmlvIHw9IEZDX05BTUVfUFJJT19FTkNfVU5JQ09ERTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBzd2l0Y2ggKHNuYW1lLmxhbmd1YWdlX2lkICYgMHhmZikgewoJICAgIGNhc2UgMHgwOToKCQlwcmlvIHw9IEZDX05BTUVfUFJJT19MQU5HX0VOR0xJU0g7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFRUX1BMQVRGT1JNX0lTTzoKCSAgICBzd2l0Y2ggKHNuYW1lLmVuY29kaW5nX2lkKSB7CgkgICAgY2FzZSBUVF9JU09fSURfMTA2NDY6CgkJZW5jb2RpbmcgPSBGY05hbWVFbmNvZGluZ1V0ZjE2OwoJCXByaW8gfD0gRkNfTkFNRV9QUklPX0VOQ19VTklDT0RFOwoJCWJyZWFrOwoJICAgIGNhc2UgVFRfSVNPX0lEXzdCSVRfQVNDSUk6CgkgICAgY2FzZSBUVF9JU09fSURfODg1OV8xOgoJCWVuY29kaW5nID0gRmNOYW1lRW5jb2RpbmdMYXRpbjE7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQljb250aW51ZTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGNvbnRpbnVlOwoJfQoJCgkvKgoJICogTG9vayBmb3IgZmFtaWx5IGFuZCBzdHlsZSBuYW1lcyAKCSAqLwoJc3dpdGNoIChzbmFtZS5uYW1lX2lkKSB7CgljYXNlIFRUX05BTUVfSURfRk9OVF9GQU1JTFk6CgkgICAgcHJpbyB8PSBGQ19OQU1FX1BSSU9fTkFNRV9GQU1JTFk7CgkgICAgYnJlYWs7CgljYXNlIFRUX05BTUVfSURfUFNfTkFNRToKCSAgICBwcmlvIHw9IEZDX05BTUVfUFJJT19OQU1FX1BTOwoJICAgIGJyZWFrOwoJY2FzZSBUVF9OQU1FX0lEX0ZPTlRfU1VCRkFNSUxZOgoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBjb250aW51ZTsKCX0KCSAgICAKICAgICAgICBzcmMgPSAoRmNDaGFyOCAqKSBzbmFtZS5zdHJpbmc7CiAgICAgICAgc3JjX2xlbiA9IHNuYW1lLnN0cmluZ19sZW47CgkKCXN3aXRjaCAoZW5jb2RpbmcpIHsKCWNhc2UgRmNOYW1lRW5jb2RpbmdVdGYxNjoKCSAgICAvKgoJICAgICAqIENvbnZlcnQgVXRmMTYgdG8gVXRmOAoJICAgICAqLwoJICAgIAoJICAgIGlmICghRmNVdGYxNkxlbiAoc3JjLCBGY0VuZGlhbkJpZywgc3JjX2xlbiwgJmxlbiwgJndjaGFyKSkKCQljb250aW51ZTsKICAgIAoJICAgIC8qCgkgICAgICogQWxsb2NhdGUgcGxlbnR5IG9mIHNwYWNlLiAgRnJlZWQgYmVsb3cKCSAgICAgKi8KCSAgICB1dGY4ID0gbWFsbG9jIChsZW4gKiBGQ19VVEY4X01BWF9MRU4gKyAxKTsKCSAgICBpZiAoIXV0ZjgpCgkJY29udGludWU7CgkJCgkgICAgdTggPSB1dGY4OwoJICAgIAoJICAgIHdoaWxlICgoaWxlbiA9IEZjVXRmMTZUb1VjczQgKHNyYywgRmNFbmRpYW5CaWcsICZ1Y3M0LCBzcmNfbGVuKSkgPiAwKQoJICAgIHsKCQlzcmNfbGVuIC09IGlsZW47CgkJc3JjICs9IGlsZW47CgkJb2xlbiA9IEZjVWNzNFRvVXRmOCAodWNzNCwgdTgpOwoJCXU4ICs9IG9sZW47CgkgICAgfQoJICAgICp1OCA9ICdcMCc7CgkgICAgYnJlYWs7CgljYXNlIEZjTmFtZUVuY29kaW5nTGF0aW4xOgoJICAgIC8qCgkgICAgICogQ29udmVydCBMYXRpbjEgdG8gVXRmOC4gRnJlZWQgYmVsb3cKCSAgICAgKi8KCSAgICB1dGY4ID0gbWFsbG9jIChzcmNfbGVuICogMiArIDEpOwoJICAgIGlmICghdXRmOCkKCQljb250aW51ZTsKCgkgICAgdTggPSB1dGY4OwoJICAgIHdoaWxlIChzcmNfbGVuID4gMCkKCSAgICB7CgkJdWNzNCA9ICpzcmMrKzsKCQlzcmNfbGVuLS07CgkJb2xlbiA9IEZjVWNzNFRvVXRmOCAodWNzNCwgdTgpOwoJCXU4ICs9IG9sZW47CgkgICAgfQoJICAgICp1OCA9ICdcMCc7CgkgICAgYnJlYWs7CgljYXNlIEZjTmFtZUVuY29kaW5nQXBwbGVSb21hbjoKCSAgICAvKgoJICAgICAqIENvbnZlcnQgQXBwbGVSb21hbiB0byBVdGY4CgkgICAgICovCgkgICAgbWFwID0gRmNGcmVlVHlwZUdldFByaXZhdGVNYXAgKGZ0X2VuY29kaW5nX2FwcGxlX3JvbWFuKTsKCSAgICBpZiAoIW1hcCkKCQljb250aW51ZTsKCgkgICAgLyogZnJlZWQgYmVsb3cgKi8KCSAgICB1dGY4ID0gbWFsbG9jIChzcmNfbGVuICogMyArIDEpOwoJICAgIGlmICghdXRmOCkKCQljb250aW51ZTsKCgkgICAgdTggPSB1dGY4OwoJICAgIHdoaWxlIChzcmNfbGVuID4gMCkKCSAgICB7CgkJdWNzNCA9IEZjRnJlZVR5cGVQcml2YXRlVG9VY3M0ICgqc3JjKyssIG1hcCk7CgkJc3JjX2xlbi0tOwoJCW9sZW4gPSBGY1VjczRUb1V0ZjggKHVjczQsIHU4KTsKCQl1OCArPSBvbGVuOwoJICAgIH0KCSAgICAqdTggPSAnXDAnOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBjb250aW51ZTsKCX0KCWlmICgocHJpbyAmIEZDX05BTUVfUFJJT19MQU5HKSA9PSBGQ19OQU1FX1BSSU9fTEFOR19OT05FKQoJICAgIGlmIChGY1V0ZjhJc0xhdGluICh1dGY4LCBzdHJsZW4gKChjaGFyICopIHV0ZjgpKSkKCQlwcmlvIHw9IEZDX05BTUVfUFJJT19MQU5HX0xBVElOOwoJCQkgICAgICAgCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOVikKCSAgICBwcmludGYgKCJcbmZvdW5kIG5hbWUgKG5hbWUgJWQgcGxhdGZvcm0gJWQgZW5jb2RpbmcgJWQgbGFuZ3VhZ2UgMHgleCBwcmlvIDB4JXgpICVzXG4iLAoJCSAgICBzbmFtZS5uYW1lX2lkLCBzbmFtZS5wbGF0Zm9ybV9pZCwKCQkgICAgc25hbWUuZW5jb2RpbmdfaWQsIHNuYW1lLmxhbmd1YWdlX2lkLAoJCSAgICBwcmlvLCB1dGY4KTsKICAgIAoJc3dpdGNoIChzbmFtZS5uYW1lX2lkKSB7CgljYXNlIFRUX05BTUVfSURfRk9OVF9GQU1JTFk6CgljYXNlIFRUX05BTUVfSURfUFNfTkFNRToKCSAgICBpZiAoIWZhbWlseSB8fCBwcmlvID4gZmFtaWx5X3ByaW8pCgkgICAgewoJCWlmIChmYW1pbHkpCgkJICAgIGZyZWUgKGZhbWlseSk7CgkJZmFtaWx5ID0gdXRmODsKCQl1dGY4ID0gMDsKCQlmYW1pbHlfYWxsb2NhdGVkID0gRmNUcnVlOwoJCWZhbWlseV9wcmlvID0gcHJpbzsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFRUX05BTUVfSURfRk9OVF9TVUJGQU1JTFk6CgkgICAgaWYgKCFzdHlsZSB8fCBwcmlvID4gc3R5bGVfcHJpbykKCSAgICB7CgkJaWYgKHN0eWxlKQoJCSAgICBmcmVlIChzdHlsZSk7CgkJc3R5bGUgPSB1dGY4OwoJCXV0ZjggPSAwOwoJCXN0eWxlX2FsbG9jYXRlZCA9IEZjVHJ1ZTsKCQlzdHlsZV9wcmlvID0gcHJpbzsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CglpZiAodXRmOCkKCSAgICBmcmVlICh1dGY4KTsKICAgIH0KICAgIAogICAgaWYgKCFmYW1pbHkpCglmYW1pbHkgPSAoRmNDaGFyOCAqKSBmYWNlLT5mYW1pbHlfbmFtZTsKICAgIAogICAgaWYgKCFzdHlsZSkKCXN0eWxlID0gKEZjQ2hhcjggKikgZmFjZS0+c3R5bGVfbmFtZTsKICAgIAogICAgaWYgKCFmYW1pbHkpCiAgICB7CglGY0NoYXI4CSpzdGFydCwgKmVuZDsKCQoJc3RhcnQgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBmaWxlLCAnLycpOwoJaWYgKHN0YXJ0KQoJICAgIHN0YXJ0Kys7CgllbHNlCgkgICAgc3RhcnQgPSAoRmNDaGFyOCAqKSBmaWxlOwoJZW5kID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgc3RhcnQsICcuJyk7CglpZiAoIWVuZCkKCSAgICBlbmQgPSBzdGFydCArIHN0cmxlbiAoKGNoYXIgKikgc3RhcnQpOwoJLyogZnJlZWQgYmVsb3cgKi8KCWZhbWlseSA9IG1hbGxvYyAoZW5kIC0gc3RhcnQgKyAxKTsKCXN0cm5jcHkgKChjaGFyICopIGZhbWlseSwgKGNoYXIgKikgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKCWZhbWlseVtlbmQgLSBzdGFydF0gPSAnXDAnOwoJZmFtaWx5X2FsbG9jYXRlZCA9IEZjVHJ1ZTsKICAgIH0KCiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX1NDQU4pCglwcmludGYgKCJcIiVzXCIgXCIlc1wiICIsIGZhbWlseSwgc3R5bGUgPyBzdHlsZSA6IChGY0NoYXI4ICopICI8bm9uZT4iKTsKCiAgICBpZiAoIUZjUGF0dGVybkFkZFN0cmluZyAocGF0LCBGQ19GQU1JTFksIGZhbWlseSkpCiAgICB7CglpZiAoZmFtaWx5X2FsbG9jYXRlZCkKCSAgICBmcmVlIChmYW1pbHkpOwoJaWYgKHN0eWxlX2FsbG9jYXRlZCkKCSAgICBmcmVlIChzdHlsZSk7Cglnb3RvIGJhaWwxOwogICAgfQoKICAgIGlmIChmYW1pbHlfYWxsb2NhdGVkKQoJZnJlZSAoZmFtaWx5KTsKCiAgICBpZiAoc3R5bGUpCiAgICB7CglpZiAoIUZjUGF0dGVybkFkZFN0cmluZyAocGF0LCBGQ19TVFlMRSwgc3R5bGUpKQoJewoJICAgIGlmIChzdHlsZV9hbGxvY2F0ZWQpCgkJZnJlZSAoc3R5bGUpOwoJICAgIGdvdG8gYmFpbDE7Cgl9CglpZiAoc3R5bGVfYWxsb2NhdGVkKQoJICAgIGZyZWUgKHN0eWxlKTsKICAgIH0KCiAgICBpZiAoIUZjUGF0dGVybkFkZFN0cmluZyAocGF0LCBGQ19GSUxFLCBmaWxlKSkKCWdvdG8gYmFpbDE7CgogICAgaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX0lOREVYLCBpZCkpCglnb3RvIGJhaWwxOwoKICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXQsIEZDX1NPVVJDRSwgKEZjQ2hhcjggKikgIkZyZWVUeXBlIikpCglnb3RvIGJhaWwxOwoKI2lmIDEKICAgIGlmICgoZmFjZS0+ZmFjZV9mbGFncyAmIEZUX0ZBQ0VfRkxBR19GSVhFRF9XSURUSCkgIT0gMCkKCWlmICghRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0LCBGQ19TUEFDSU5HLCBGQ19NT05PKSkKCSAgICBnb3RvIGJhaWwxOwojZW5kaWYKCiAgICAvKgogICAgICogRmluZCB0aGUgZm9udCByZXZpc2lvbiAoaWYgYXZhaWxhYmxlKQogICAgICovCiAgICBoZWFkID0gKFRUX0hlYWRlciAqKSBGVF9HZXRfU2ZudF9UYWJsZSAoZmFjZSwgZnRfc2ZudF9oZWFkKTsKICAgIGlmIChoZWFkKQogICAgewoJaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX0ZPTlRWRVJTSU9OLCBoZWFkLT5Gb250X1JldmlzaW9uKSkKCSAgICBnb3RvIGJhaWwxOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKCFGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXQsIEZDX0ZPTlRWRVJTSU9OLCAwKSkKCSAgICBnb3RvIGJhaWwxOwogICAgfQoKICAgIC8qCiAgICAgKiBHZXQgdGhlIE9TLzIgdGFibGUgYW5kIHBva2UgYWJvdXQKICAgICAqLwogICAgb3MyID0gKFRUX09TMiAqKSBGVF9HZXRfU2ZudF9UYWJsZSAoZmFjZSwgZnRfc2ZudF9vczIpOwogICAgaWYgKG9zMiAmJiBvczItPnZlcnNpb24gPj0gMHgwMDAxICYmIG9zMi0+dmVyc2lvbiAhPSAweGZmZmYpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgTlVNX0NPREVfUEFHRV9SQU5HRTsgaSsrKQoJewoJICAgIEZUX1VMb25nCWJpdHM7CgkgICAgaW50CQliaXQ7CgkgICAgaWYgKEZjQ29kZVBhZ2VSYW5nZVtpXS5iaXQgPCAzMikKCSAgICB7CgkJYml0cyA9IG9zMi0+dWxDb2RlUGFnZVJhbmdlMTsKCQliaXQgPSBGY0NvZGVQYWdlUmFuZ2VbaV0uYml0OwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWJpdHMgPSBvczItPnVsQ29kZVBhZ2VSYW5nZTI7CgkJYml0ID0gRmNDb2RlUGFnZVJhbmdlW2ldLmJpdCAtIDMyOwoJICAgIH0KCSAgICBpZiAoYml0cyAmICgxIDw8IGJpdCkpCgkgICAgewoJCS8qIAoJCSAqIElmIHRoZSBmb250IGFkdmVydGlzZXMgc3VwcG9ydCBmb3IgbXVsdGlwbGUKCQkgKiAiZXhjbHVzaXZlIiBsYW5ndWFnZXMsIHRoZW4gaW5jbHVkZSBzdXBwb3J0CgkJICogZm9yIGFueSBsYW5ndWFnZSBmb3VuZCB0byBoYXZlIGNvdmVyYWdlCgkJICovCgkJaWYgKGV4Y2x1c2l2ZUxhbmcpCgkJewoJCSAgICBleGNsdXNpdmVMYW5nID0gMDsKCQkgICAgYnJlYWs7CgkJfQoJCWV4Y2x1c2l2ZUxhbmcgPSBGY0NvZGVQYWdlUmFuZ2VbaV0ubGFuZzsKCSAgICB9Cgl9CiAgICB9CgogICAgLyoKICAgICAqIENvbXB1dGUgdGhlIHVuaWNvZGUgY292ZXJhZ2UgZm9yIHRoZSBmb250CiAgICAgKi8KICAgIGNzID0gRmNGcmVlVHlwZUNoYXJTZXQgKGZhY2UsIGJsYW5rcyk7CiAgICBpZiAoIWNzKQoJZ290byBiYWlsMTsKCiAgICAvKgogICAgICogU2tpcCBvdmVyIFBDRiBmb250cyB0aGF0IGhhdmUgbm8gZW5jb2RlZCBjaGFyYWN0ZXJzOyB0aGV5J3JlCiAgICAgKiB1c3VhbGx5IGp1c3QgVW5pY29kZSBmb250cyB0cmFuc2NvZGVkIHRvIHNvbWUgbGVnYWN5IGVuY29kaW5nCiAgICAgKi8KICAgIGlmIChGY0NoYXJTZXRDb3VudCAoY3MpID09IDApCiAgICB7CglpZiAoIXN0cmNtcChGVF9NT0RVTEVfQ0xBU1MoJmZhY2UtPmRyaXZlci0+cm9vdCktPm1vZHVsZV9uYW1lLCAicGNmIikpCgkgICAgZ290byBiYWlsMjsKICAgIH0KCiAgICBpZiAoIUZjUGF0dGVybkFkZENoYXJTZXQgKHBhdCwgRkNfQ0hBUlNFVCwgY3MpKQoJZ290byBiYWlsMjsKCiAgICBscyA9IEZjRnJlZVR5cGVMYW5nU2V0IChjcywgZXhjbHVzaXZlTGFuZyk7CiAgICBpZiAoIWxzKQoJZ290byBiYWlsMjsKCiAgICBpZiAoIUZjUGF0dGVybkFkZExhbmdTZXQgKHBhdCwgRkNfTEFORywgbHMpKQoJZ290byBiYWlsMjsKCiAgICAvKgogICAgICogRHJvcCBvdXIgcmVmZXJlbmNlIHRvIHRoZSBjaGFyc2V0CiAgICAgKi8KICAgIEZjQ2hhclNldERlc3Ryb3kgKGNzKTsKICAgIAogICAgaWYgKCEoZmFjZS0+ZmFjZV9mbGFncyAmIEZUX0ZBQ0VfRkxBR19TQ0FMQUJMRSkpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgZmFjZS0+bnVtX2ZpeGVkX3NpemVzOyBpKyspCgkgICAgaWYgKCFGY1BhdHRlcm5BZGREb3VibGUgKHBhdCwgRkNfUElYRUxfU0laRSwKCQkJCSAgICAgKGRvdWJsZSkgZmFjZS0+YXZhaWxhYmxlX3NpemVzW2ldLmhlaWdodCkpCgkJZ290byBiYWlsMTsKCWlmICghRmNQYXR0ZXJuQWRkQm9vbCAocGF0LCBGQ19BTlRJQUxJQVMsIEZjRmFsc2UpKQoJICAgIGdvdG8gYmFpbDE7CiAgICB9CgogICAgRlRfRG9uZV9GYWNlIChmYWNlKTsKICAgIEZUX0RvbmVfRnJlZVR5cGUgKGZ0TGlicmFyeSk7CiAgICByZXR1cm4gcGF0OwoKYmFpbDI6CiAgICBGY0NoYXJTZXREZXN0cm95IChjcyk7CmJhaWwxOgogICAgRmNQYXR0ZXJuRGVzdHJveSAocGF0KTsKYmFpbDA6CiAgICBGVF9Eb25lX0ZhY2UgKGZhY2UpOwpiYWlsOgogICAgRlRfRG9uZV9GcmVlVHlwZSAoZnRMaWJyYXJ5KTsKICAgIHJldHVybiAwOwp9Cg==