LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNsaXN0LmMsdiAxLjExdHNpIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZAogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjT2JqZWN0U2V0ICoKRmNPYmplY3RTZXRDcmVhdGUgKHZvaWQpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICBvcyA9IChGY09iamVjdFNldCAqKSBtYWxsb2MgKHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIGlmICghb3MpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RTRVQsIHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIG9zLT5ub2JqZWN0ID0gMDsKICAgIG9zLT5zb2JqZWN0ID0gMDsKICAgIG9zLT5vYmplY3RzID0gMDsKICAgIHJldHVybiBvczsKfQoKRmNCb29sCkZjT2JqZWN0U2V0QWRkIChGY09iamVjdFNldCAqb3MsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQlzOwogICAgY29uc3QgY2hhcgkqKm9iamVjdHM7CiAgICBpbnQJCWhpZ2gsIGxvdywgbWlkLCBjOwogICAgCiAgICBpZiAob3MtPm5vYmplY3QgPT0gb3MtPnNvYmplY3QpCiAgICB7CglzID0gb3MtPnNvYmplY3QgKyA0OwoJaWYgKG9zLT5vYmplY3RzKQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgcmVhbGxvYyAoKHZvaWQgKikgb3MtPm9iamVjdHMsCgkJCQkJICAgICAgIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJZWxzZQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgbWFsbG9jIChzICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWlmICghb2JqZWN0cykKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmIChvcy0+c29iamVjdCkKCSAgICBGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCUZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RQVFIsIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJb3MtPm9iamVjdHMgPSBvYmplY3RzOwoJb3MtPnNvYmplY3QgPSBzOwogICAgfQogICAgaGlnaCA9IG9zLT5ub2JqZWN0IC0gMTsKICAgIGxvdyA9IDA7CiAgICBtaWQgPSAwOwogICAgYyA9IDE7CiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAobG93ICsgaGlnaCkgPj4gMTsKCWMgPSBzdHJjbXAgKG9zLT5vYmplY3RzW21pZF0sIG9iamVjdCk7CglpZiAoYyA9PSAwKQoJICAgIHJldHVybiBGY1RydWU7CglpZiAoYyA8IDApCgkgICAgbG93ID0gbWlkICsgMTsKCWVsc2UKCSAgICBoaWdoID0gbWlkIC0gMTsKICAgIH0KICAgIGlmIChjIDwgMCkKCW1pZCsrOwogICAgbWVtbW92ZSAob3MtPm9iamVjdHMgKyBtaWQgKyAxLCBvcy0+b2JqZWN0cyArIG1pZCwgCgkgICAgIChvcy0+bm9iamVjdCAtIG1pZCkgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwogICAgb3MtPm9iamVjdHNbbWlkXSA9IG9iamVjdDsKICAgIG9zLT5ub2JqZWN0Kys7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjT2JqZWN0U2V0RGVzdHJveSAoRmNPYmplY3RTZXQgKm9zKQp7CiAgICBpZiAob3MtPm9iamVjdHMpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWZyZWUgKCh2b2lkICopIG9zLT5vYmplY3RzKTsKICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX09CSkVDVFNFVCwgc2l6ZW9mIChGY09iamVjdFNldCkpOwogICAgZnJlZSAob3MpOwp9CgpGY09iamVjdFNldCAqCkZjT2JqZWN0U2V0VmFCdWlsZCAoY29uc3QgY2hhciAqZmlyc3QsIHZhX2xpc3QgdmEpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpyZXQ7CgogICAgRmNPYmplY3RTZXRWYXBCdWlsZCAocmV0LCBmaXJzdCwgdmEpOwogICAgcmV0dXJuIHJldDsKfQoKRmNPYmplY3RTZXQgKgpGY09iamVjdFNldEJ1aWxkIChjb25zdCBjaGFyICpmaXJzdCwgLi4uKQp7CiAgICB2YV9saXN0CSAgICB2YTsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICB2YV9zdGFydCAodmEsIGZpcnN0KTsKICAgIEZjT2JqZWN0U2V0VmFwQnVpbGQgKG9zLCBmaXJzdCwgdmEpOwogICAgdmFfZW5kICh2YSk7CiAgICByZXR1cm4gb3M7Cn0KCi8qCiAqIEZvbnQgbXVzdCBoYXZlIGEgY29udGFpbmluZyB2YWx1ZSBmb3IgZXZlcnkgdmFsdWUgaW4gdGhlIHBhdHRlcm4KICovCnN0YXRpYyBGY0Jvb2wKRmNMaXN0VmFsdWVMaXN0TWF0Y2hBbnkgKEZjVmFsdWVMaXN0ICpwYXRPcmlnLAkgICAgLyogcGF0dGVybiAqLwoJCQkgRmNWYWx1ZUxpc3QgKmZudE9yaWcpCSAgICAvKiBmb250ICovCnsKICAgIEZjVmFsdWVMaXN0CSAgICAqcGF0LCAqZm50OwoKICAgIGZvciAocGF0ID0gcGF0T3JpZzsgcGF0OyBwYXQgPSBwYXQtPm5leHQpCiAgICB7Cglmb3IgKGZudCA9IGZudE9yaWc7IGZudDsgZm50ID0gZm50LT5uZXh0KQoJewoJICAgIC8qCgkgICAgICogbWFrZSBzdXJlIHRoZSBmb250ICdjb250YWlucycgdGhlIHBhdHRlcm4uCgkgICAgICogKE9wTGlzdGluZyBpcyBPcENvbnRhaW5zIGV4Y2VwdCBmb3Igc3RyaW5ncwoJICAgICAqICB3aGVyZSBpdCByZXF1aXJlcyBhbiBleGFjdCBtYXRjaCkKCSAgICAgKi8KCSAgICBpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKGZudC0+dmFsdWUsCgkJCQkgICAgICBGY09wTGlzdGluZywgCgkJCQkgICAgICBwYXQtPnZhbHVlKSkgCgkJYnJlYWs7Cgl9CglpZiAoIWZudCkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNMaXN0VmFsdWVMaXN0RXF1YWwgKEZjVmFsdWVMaXN0ICAgKnYxb3JpZywKCQkgICAgICBGY1ZhbHVlTGlzdCAgICp2Mm9yaWcpCnsKICAgIEZjVmFsdWVMaXN0CSAgICAqdjEsICp2MjsKCiAgICBmb3IgKHYxID0gdjFvcmlnOyB2MTsgdjEgPSB2MS0+bmV4dCkKICAgIHsKCWZvciAodjIgPSB2Mm9yaWc7IHYyOyB2MiA9IHYyLT5uZXh0KQoJICAgIGlmIChGY1ZhbHVlRXF1YWwgKHYxLT52YWx1ZSwgdjItPnZhbHVlKSkKCQlicmVhazsKCWlmICghdjIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBmb3IgKHYyID0gdjJvcmlnOyB2MjsgdjIgPSB2Mi0+bmV4dCkKICAgIHsKCWZvciAodjEgPSB2MW9yaWc7IHYxOyB2MSA9IHYxLT5uZXh0KQoJICAgIGlmIChGY1ZhbHVlRXF1YWwgKHYxLT52YWx1ZSwgdjItPnZhbHVlKSkKCQlicmVhazsKCWlmICghdjEpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjTGlzdFBhdHRlcm5FcXVhbCAoRmNQYXR0ZXJuCSpwMSwKCQkgICAgRmNQYXR0ZXJuCSpwMiwKCQkgICAgRmNPYmplY3RTZXQJKm9zKQp7CiAgICBpbnQJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0ICAgICplMSwgKmUyOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvcy0+bm9iamVjdDsgaSsrKQogICAgewoJZTEgPSBGY1BhdHRlcm5GaW5kRWx0IChwMSwgb3MtPm9iamVjdHNbaV0pOwoJZTIgPSBGY1BhdHRlcm5GaW5kRWx0IChwMiwgb3MtPm9iamVjdHNbaV0pOwoJaWYgKCFlMSAmJiAhZTIpCgkgICAgY29udGludWU7CglpZiAoIWUxIHx8ICFlMikKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmICghRmNMaXN0VmFsdWVMaXN0RXF1YWwgKGUxLT52YWx1ZXMsIGUyLT52YWx1ZXMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKLyoKICogRmNUcnVlIGlmZiBhbGwgb2JqZWN0cyBpbiAicCIgbWF0Y2ggImZvbnQiCiAqLwoKc3RhdGljIEZjQm9vbApGY0xpc3RQYXR0ZXJuTWF0Y2hBbnkgKEZjUGF0dGVybiAqcCwKCQkgICAgICAgRmNQYXR0ZXJuICpmb250KQp7CiAgICBpbnQJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0ICAgKmU7CgogICAgZm9yIChpID0gMDsgaSA8IHAtPm51bTsgaSsrKQogICAgewoJZSA9IEZjUGF0dGVybkZpbmRFbHQgKGZvbnQsIHAtPmVsdHNbaV0ub2JqZWN0KTsKCWlmICghZSkKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmICghRmNMaXN0VmFsdWVMaXN0TWF0Y2hBbnkgKHAtPmVsdHNbaV0udmFsdWVzLCAgICAvKiBwYXQgZWx0cyAqLwoJCQkJICAgICAgZS0+dmFsdWVzKSkJICAgIC8qIGZvbnQgZWx0cyAqLwoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjTGlzdFN0cmluZ0hhc2ggKGNvbnN0IEZjQ2hhcjgJKnMpCnsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgRmNDaGFyOAljOwoKICAgIHdoaWxlICgoYyA9ICpzKyspKQogICAgewoJYyA9IEZjVG9Mb3dlciAoYyk7CgloID0gKChoIDw8IDMpIF4gKGggPj4gMykpIF4gYzsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0TWF0cml4SGFzaCAoY29uc3QgRmNNYXRyaXggKm0pCnsKICAgIGludAkgICAgeHggPSAoaW50KSAobS0+eHggKiAxMDApLCAKCSAgICB4eSA9IChpbnQpIChtLT54eSAqIDEwMCksIAoJICAgIHl4ID0gKGludCkgKG0tPnl4ICogMTAwKSwKCSAgICB5eSA9IChpbnQpIChtLT55eSAqIDEwMCk7CgogICAgcmV0dXJuICgoRmNDaGFyMzIpIHh4KSBeICgoRmNDaGFyMzIpIHh5KSBeICgoRmNDaGFyMzIpIHl4KSBeICgoRmNDaGFyMzIpIHl5KTsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjTGlzdFZhbHVlSGFzaCAoRmNWYWx1ZSAgICB2KQp7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVWb2lkOgoJcmV0dXJuIDA7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglyZXR1cm4gKEZjQ2hhcjMyKSB2LnUuaTsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJcmV0dXJuIChGY0NoYXIzMikgKGludCkgdi51LmQ7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXJldHVybiBGY0xpc3RTdHJpbmdIYXNoICh2LnUucyk7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglyZXR1cm4gKEZjQ2hhcjMyKSB2LnUuYjsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJcmV0dXJuIEZjTGlzdE1hdHJpeEhhc2ggKHYudS5tKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiBGY0NoYXJTZXRDb3VudCAodi51LmMpOwogICAgY2FzZSBGY1R5cGVGVEZhY2U6CglyZXR1cm4gKGxvbmcpIHYudS5mOwogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJcmV0dXJuIEZjTGFuZ1NldEhhc2ggKHYudS5sKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0VmFsdWVMaXN0SGFzaCAoRmNWYWx1ZUxpc3QgICAgKmxpc3QpCnsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgCiAgICB3aGlsZSAobGlzdCkKICAgIHsKCWggPSBoIF4gRmNMaXN0VmFsdWVIYXNoIChsaXN0LT52YWx1ZSk7CglsaXN0ID0gbGlzdC0+bmV4dDsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0UGF0dGVybkhhc2ggKEZjUGF0dGVybgkqZm9udCwKCQkgICBGY09iamVjdFNldAkqb3MpCnsKICAgIGludAkJICAgIG47CiAgICBGY1BhdHRlcm5FbHQgICAgKmU7CiAgICBGY0NoYXIzMgkgICAgaCA9IDA7CgogICAgZm9yIChuID0gMDsgbiA8IG9zLT5ub2JqZWN0OyBuKyspCiAgICB7CgllID0gRmNQYXR0ZXJuRmluZEVsdCAoZm9udCwgb3MtPm9iamVjdHNbbl0pOwoJaWYgKGUpCgkgICAgaCA9IGggXiBGY0xpc3RWYWx1ZUxpc3RIYXNoIChlLT52YWx1ZXMpOwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnR5cGVkZWYgc3RydWN0IF9GY0xpc3RCdWNrZXQgewogICAgc3RydWN0IF9GY0xpc3RCdWNrZXQgICAgKm5leHQ7CiAgICBGY0NoYXIzMgkJICAgIGhhc2g7CiAgICBGY1BhdHRlcm4JCSAgICAqcGF0dGVybjsKfSBGY0xpc3RCdWNrZXQ7CgojZGVmaW5lIEZDX0xJU1RfSEFTSF9TSVpFICAgNDA5OQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjTGlzdEhhc2hUYWJsZSB7CiAgICBpbnQJCSAgICBlbnRyaWVzOwogICAgRmNMaXN0QnVja2V0ICAgICpidWNrZXRzW0ZDX0xJU1RfSEFTSF9TSVpFXTsKfSBGY0xpc3RIYXNoVGFibGU7CiAgICAKc3RhdGljIHZvaWQKRmNMaXN0SGFzaFRhYmxlSW5pdCAoRmNMaXN0SGFzaFRhYmxlICp0YWJsZSkKewogICAgdGFibGUtPmVudHJpZXMgPSAwOwogICAgbWVtc2V0ICh0YWJsZS0+YnVja2V0cywgJ1wwJywgc2l6ZW9mICh0YWJsZS0+YnVja2V0cykpOwp9CgpzdGF0aWMgdm9pZApGY0xpc3RIYXNoVGFibGVDbGVhbnVwIChGY0xpc3RIYXNoVGFibGUgKnRhYmxlKQp7CiAgICBpbnQJaTsKICAgIEZjTGlzdEJ1Y2tldCAgICAqYnVja2V0LCAqbmV4dDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgRkNfTElTVF9IQVNIX1NJWkU7IGkrKykKICAgIHsKCWZvciAoYnVja2V0ID0gdGFibGUtPmJ1Y2tldHNbaV07IGJ1Y2tldDsgYnVja2V0ID0gbmV4dCkKCXsKCSAgICBuZXh0ID0gYnVja2V0LT5uZXh0OwoJICAgIEZjUGF0dGVybkRlc3Ryb3kgKGJ1Y2tldC0+cGF0dGVybik7CgkgICAgRmNNZW1GcmVlIChGQ19NRU1fTElTVEJVQ0ssIHNpemVvZiAoRmNMaXN0QnVja2V0KSk7CgkgICAgZnJlZSAoYnVja2V0KTsKCX0KCXRhYmxlLT5idWNrZXRzW2ldID0gMDsKICAgIH0KICAgIHRhYmxlLT5lbnRyaWVzID0gMDsKfQoKc3RhdGljIEZjQm9vbApGY0xpc3RBcHBlbmQgKEZjTGlzdEhhc2hUYWJsZQkqdGFibGUsCgkgICAgICBGY1BhdHRlcm4JCSpmb250LAoJICAgICAgRmNPYmplY3RTZXQJKm9zKQp7CiAgICBpbnQJCSAgICBvOwogICAgRmNQYXR0ZXJuRWx0ICAgICplOwogICAgRmNWYWx1ZUxpc3QJICAgICp2OwogICAgRmNDaGFyMzIJICAgIGhhc2g7CiAgICBGY0xpc3RCdWNrZXQgICAgKipwcmV2LCAqYnVja2V0OwoKICAgIGhhc2ggPSBGY0xpc3RQYXR0ZXJuSGFzaCAoZm9udCwgb3MpOwogICAgZm9yIChwcmV2ID0gJnRhYmxlLT5idWNrZXRzW2hhc2ggJSBGQ19MSVNUX0hBU0hfU0laRV07CgkgKGJ1Y2tldCA9ICpwcmV2KTsgcHJldiA9ICYoYnVja2V0LT5uZXh0KSkKICAgIHsKCWlmIChidWNrZXQtPmhhc2ggPT0gaGFzaCAmJiAKCSAgICBGY0xpc3RQYXR0ZXJuRXF1YWwgKGJ1Y2tldC0+cGF0dGVybiwgZm9udCwgb3MpKQoJICAgIHJldHVybiBGY1RydWU7CiAgICB9CiAgICBidWNrZXQgPSAoRmNMaXN0QnVja2V0ICopIG1hbGxvYyAoc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKICAgIGlmICghYnVja2V0KQoJZ290byBiYWlsMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9MSVNUQlVDSywgc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKICAgIGJ1Y2tldC0+bmV4dCA9IDA7CiAgICBidWNrZXQtPmhhc2ggPSBoYXNoOwogICAgYnVja2V0LT5wYXR0ZXJuID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFidWNrZXQtPnBhdHRlcm4pCglnb3RvIGJhaWwxOwogICAgCiAgICBmb3IgKG8gPSAwOyBvIDwgb3MtPm5vYmplY3Q7IG8rKykKICAgIHsKCWUgPSBGY1BhdHRlcm5GaW5kRWx0IChmb250LCBvcy0+b2JqZWN0c1tvXSk7CglpZiAoZSkKCXsKCSAgICBmb3IgKHYgPSBlLT52YWx1ZXM7IHY7IHYgPSB2LT5uZXh0KQoJICAgIHsKCQlpZiAoIUZjUGF0dGVybkFkZCAoYnVja2V0LT5wYXR0ZXJuLCAKCQkJCSAgIG9zLT5vYmplY3RzW29dLCAKCQkJCSAgIHYtPnZhbHVlLCBGY1RydWUpKQoJCSAgICBnb3RvIGJhaWwyOwoJICAgIH0KCX0KICAgIH0KICAgICpwcmV2ID0gYnVja2V0OwogICAgKyt0YWJsZS0+ZW50cmllczsKCiAgICByZXR1cm4gRmNUcnVlOwogICAgCmJhaWwyOgogICAgRmNQYXR0ZXJuRGVzdHJveSAoYnVja2V0LT5wYXR0ZXJuKTsKYmFpbDE6CiAgICBGY01lbUZyZWUgKEZDX01FTV9MSVNUQlVDSywgc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKICAgIGZyZWUgKGJ1Y2tldCk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjRm9udFNldCAqCkZjRm9udFNldExpc3QgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJICAgICAgIEZjRm9udFNldCAgICAqKnNldHMsCgkgICAgICAgaW50CSAgICBuc2V0cywKCSAgICAgICBGY1BhdHRlcm4gICAgKnAsCgkgICAgICAgRmNPYmplY3RTZXQgICpvcykKewogICAgRmNGb250U2V0CSAgICAqcmV0OwogICAgRmNGb250U2V0CSAgICAqczsKICAgIGludAkJICAgIGY7CiAgICBpbnQJCSAgICBzZXQ7CiAgICBGY0xpc3RIYXNoVGFibGUgdGFibGU7CiAgICBpbnQJCSAgICBpOwogICAgRmNMaXN0QnVja2V0ICAgICpidWNrZXQ7CgogICAgaWYgKCFjb25maWcpCiAgICB7CglpZiAoIUZjSW5pdEJyaW5nVXB0b0RhdGUgKCkpCgkgICAgZ290byBiYWlsMDsKCgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICBnb3RvIGJhaWwwOwogICAgfQogICAgRmNMaXN0SGFzaFRhYmxlSW5pdCAoJnRhYmxlKTsKICAgIC8qCiAgICAgKiBXYWxrIGFsbCBhdmFpbGFibGUgZm9udHMgYWRkaW5nIHRob3NlIHRoYXQKICAgICAqIG1hdGNoIHRvIHRoZSBoYXNoIHRhYmxlCiAgICAgKi8KICAgIGZvciAoc2V0ID0gMDsgc2V0IDwgbnNldHM7IHNldCsrKQogICAgewoJcyA9IHNldHNbc2V0XTsKCWlmICghcykKCSAgICBjb250aW51ZTsKCWZvciAoZiA9IDA7IGYgPCBzLT5uZm9udDsgZisrKQoJICAgIGlmIChGY0xpc3RQYXR0ZXJuTWF0Y2hBbnkgKHAsCQkvKiBwYXR0ZXJuICovCgkJCQkgICAgICAgcy0+Zm9udHNbZl0pKQkvKiBmb250ICovCgkJaWYgKCFGY0xpc3RBcHBlbmQgKCZ0YWJsZSwgcy0+Zm9udHNbZl0sIG9zKSkKCQkgICAgZ290byBiYWlsMTsKICAgIH0KI2lmIDAKICAgIHsKCWludAltYXggPSAwOwoJaW50CWZ1bGwgPSAwOwoJaW50CWVudHMgPSAwOwoJaW50CWxlbjsKCWZvciAoaSA9IDA7IGkgPCBGQ19MSVNUX0hBU0hfU0laRTsgaSsrKQoJewoJICAgIGlmICgoYnVja2V0ID0gdGFibGUuYnVja2V0c1tpXSkpCgkgICAgewoJCWxlbiA9IDA7CgkJZm9yICg7IGJ1Y2tldDsgYnVja2V0ID0gYnVja2V0LT5uZXh0KQoJCXsKCQkgICAgZW50cysrOwoJCSAgICBsZW4rKzsKCQl9CgkJaWYgKGxlbiA+IG1heCkKCQkgICAgbWF4ID0gbGVuOwoJCWZ1bGwrKzsKCSAgICB9Cgl9CglwcmludGYgKCJ1c2VkOiAlZCBtYXg6ICVkIGF2ZzogJWdcbiIsIGZ1bGwsIG1heCwgCgkJKGRvdWJsZSkgZW50cyAvIEZDX0xJU1RfSEFTSF9TSVpFKTsKICAgIH0KI2VuZGlmCiAgICAvKgogICAgICogV2FsayB0aGUgaGFzaCB0YWJsZSBhbmQgYnVpbGQKICAgICAqIGEgZm9udCBzZXQKICAgICAqLwogICAgcmV0ID0gRmNGb250U2V0Q3JlYXRlICgpOwogICAgaWYgKCFyZXQpCglnb3RvIGJhaWwwOwogICAgZm9yIChpID0gMDsgaSA8IEZDX0xJU1RfSEFTSF9TSVpFOyBpKyspCgl3aGlsZSAoKGJ1Y2tldCA9IHRhYmxlLmJ1Y2tldHNbaV0pKQoJewoJICAgIGlmICghRmNGb250U2V0QWRkIChyZXQsIGJ1Y2tldC0+cGF0dGVybikpCgkJZ290byBiYWlsMjsKCSAgICB0YWJsZS5idWNrZXRzW2ldID0gYnVja2V0LT5uZXh0OwoJICAgIEZjTWVtRnJlZSAoRkNfTUVNX0xJU1RCVUNLLCBzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwoJICAgIGZyZWUgKGJ1Y2tldCk7Cgl9CiAgICAKICAgIHJldHVybiByZXQ7CgpiYWlsMjoKICAgIEZjRm9udFNldERlc3Ryb3kgKHJldCk7CmJhaWwxOgogICAgRmNMaXN0SGFzaFRhYmxlQ2xlYW51cCAoJnRhYmxlKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKRmNGb250U2V0ICoKRmNGb250TGlzdCAoRmNDb25maWcJKmNvbmZpZywKCSAgICBGY1BhdHRlcm4JKnAsCgkgICAgRmNPYmplY3RTZXQgKm9zKQp7CiAgICBGY0ZvbnRTZXQJKnNldHNbMl07CiAgICBpbnQJCW5zZXRzOwoKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICBuc2V0cyA9IDA7CiAgICBpZiAoY29uZmlnLT5mb250c1tGY1NldFN5c3RlbV0pCglzZXRzW25zZXRzKytdID0gY29uZmlnLT5mb250c1tGY1NldFN5c3RlbV07CiAgICBpZiAoY29uZmlnLT5mb250c1tGY1NldEFwcGxpY2F0aW9uXSkKCXNldHNbbnNldHMrK10gPSBjb25maWctPmZvbnRzW0ZjU2V0QXBwbGljYXRpb25dOwogICAgcmV0dXJuIEZjRm9udFNldExpc3QgKGNvbmZpZywgc2V0cywgbnNldHMsIHAsIG9zKTsKfQo=