LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCnN0YXRpYyBGY0NvbmZpZyAgICAqZmNDb25maWc7CgpGY0NvbmZpZyAqCkZjQ29uZmlnQ3JlYXRlICh2b2lkKQp7CiAgICBGY1NldE5hbWUJc2V0OwogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBjb25maWcgPSBtYWxsb2MgKHNpemVvZiAoRmNDb25maWcpKTsKICAgIGlmICghY29uZmlnKQoJZ290byBiYWlsMDsKICAgIAogICAgY29uZmlnLT5kaXJzID0gbWFsbG9jIChzaXplb2YgKGNoYXIgKikpOwogICAgaWYgKCFjb25maWctPmRpcnMpCglnb3RvIGJhaWwxOwogICAgY29uZmlnLT5kaXJzWzBdID0gMDsKICAgIAogICAgY29uZmlnLT5jb25maWdGaWxlcyA9IG1hbGxvYyAoc2l6ZW9mIChjaGFyICopKTsKICAgIGlmICghY29uZmlnLT5jb25maWdGaWxlcykKCWdvdG8gYmFpbDI7CiAgICBjb25maWctPmNvbmZpZ0ZpbGVzWzBdID0gMDsKICAgIAogICAgY29uZmlnLT5jYWNoZSA9IDA7CiAgICBpZiAoIUZjQ29uZmlnU2V0Q2FjaGUgKGNvbmZpZywgIn4vIiBGQ19VU0VSX0NBQ0hFX0ZJTEUpKQoJZ290byBiYWlsMzsKCiAgICBjb25maWctPmJsYW5rcyA9IDA7CgogICAgY29uZmlnLT5zdWJzdFBhdHRlcm4gPSAwOwogICAgY29uZmlnLT5zdWJzdEZvbnQgPSAwOwogICAgY29uZmlnLT5tYXhPYmplY3RzID0gMDsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWNvbmZpZy0+Zm9udHNbc2V0XSA9IDA7CiAgICAKICAgIHJldHVybiBjb25maWc7CgpiYWlsMzoKICAgIGZyZWUgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwpiYWlsMjoKICAgIGZyZWUgKGNvbmZpZy0+ZGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNTdWJzdERlc3Ryb3kgKEZjU3Vic3QgKnMpCnsKICAgIEZjU3Vic3QgKm47CiAgICAKICAgIHdoaWxlIChzKQogICAgewoJbiA9IHMtPm5leHQ7CglGY1Rlc3REZXN0cm95IChzLT50ZXN0KTsKCUZjRWRpdERlc3Ryb3kgKHMtPmVkaXQpOwoJcyA9IG47CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnRGVzdHJveVN0cmluZ3MgKGNoYXIgKipzdHJpbmdzKQp7CiAgICBjaGFyICAgICoqczsKCiAgICBmb3IgKHMgPSBzdHJpbmdzOyBzICYmICpzOyBzKyspCglmcmVlICgqcyk7CiAgICBpZiAoc3RyaW5ncykKCWZyZWUgKHN0cmluZ3MpOwp9CiAgICAKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZFN0cmluZyAoY2hhciAqKipzdHJpbmdzLCBjaGFyICpzdHJpbmcpCnsKICAgIGludAkgICAgbjsKICAgIGNoYXIgICAgKipzOwogICAgCiAgICBuID0gMDsKICAgIGZvciAocyA9ICpzdHJpbmdzOyBzICYmICpzOyBzKyspCgluKys7CiAgICBzID0gbWFsbG9jICgobiArIDIpICogc2l6ZW9mIChjaGFyICopKTsKICAgIGlmICghcykKCXJldHVybiBGY0ZhbHNlOwogICAgc1tuXSA9IHN0cmluZzsKICAgIHNbbisxXSA9IDA7CiAgICBtZW1jcHkgKHMsICpzdHJpbmdzLCBuICogc2l6ZW9mIChjaGFyICopKTsKICAgIGZyZWUgKCpzdHJpbmdzKTsKICAgICpzdHJpbmdzID0gczsKICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNDb25maWdEZXN0cm95IChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY1NldE5hbWUJc2V0OwogICAgRmNDb25maWdEZXN0cm95U3RyaW5ncyAoY29uZmlnLT5kaXJzKTsKICAgIEZjQ29uZmlnRGVzdHJveVN0cmluZ3MgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwoKICAgIGZyZWUgKGNvbmZpZy0+Y2FjaGUpOwoKICAgIEZjU3Vic3REZXN0cm95IChjb25maWctPnN1YnN0UGF0dGVybik7CiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdEZvbnQpOwogICAgZm9yIChzZXQgPSBGY1NldFN5c3RlbTsgc2V0IDw9IEZjU2V0QXBwbGljYXRpb247IHNldCsrKQoJaWYgKGNvbmZpZy0+Zm9udHNbc2V0XSkKCSAgICBGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwp9CgovKgogKiBTY2FuIHRoZSBjdXJyZW50IGxpc3Qgb2YgZGlyZWN0b3JpZXMgaW4gdGhlIGNvbmZpZ3VyYXRpb24KICogYW5kIGJ1aWxkIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGZvbnRzLiBVcGRhdGUgdGhlCiAqIHBlci11c2VyIGNhY2hlIGZpbGUgdG8gcmVmbGVjdCB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KICovCgpGY0Jvb2wKRmNDb25maWdCdWlsZEZvbnRzIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZvbnRTZXQgICAqZm9udHM7CiAgICBGY0ZpbGVDYWNoZSAqY2FjaGU7CiAgICBjaGFyCSoqZDsKCiAgICBmb250cyA9IEZjRm9udFNldENyZWF0ZSAoKTsKICAgIGlmICghZm9udHMpCglnb3RvIGJhaWwwOwogICAgCiAgICBjYWNoZSA9IEZjRmlsZUNhY2hlQ3JlYXRlICgpOwogICAgaWYgKCFjYWNoZSkKCWdvdG8gYmFpbDE7CgogICAgRmNGaWxlQ2FjaGVMb2FkIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CgogICAgZm9yIChkID0gY29uZmlnLT5kaXJzOyBkICYmICpkOyBkKyspCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJICAgIHByaW50ZiAoInNjYW4gZGlyICVzXG4iLCAqZCk7CglGY0RpclNjYW4gKGZvbnRzLCBjYWNoZSwgY29uZmlnLT5ibGFua3MsICpkLCBGY0ZhbHNlKTsKICAgIH0KICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCUZjRm9udFNldFByaW50IChmb250cyk7CgogICAgRmNGaWxlQ2FjaGVTYXZlIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CiAgICBGY0ZpbGVDYWNoZURlc3Ryb3kgKGNhY2hlKTsKCiAgICBGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIGZvbnRzLCBGY1NldFN5c3RlbSk7CiAgICAKICAgIHJldHVybiBGY1RydWU7CmJhaWwxOgogICAgRmNGb250U2V0RGVzdHJveSAoZm9udHMpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNDb25maWdTZXRDdXJyZW50IChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZy0+Zm9udHMpCglpZiAoIUZjQ29uZmlnQnVpbGRGb250cyAoY29uZmlnKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKCiAgICBpZiAoZmNDb25maWcpCglGY0NvbmZpZ0Rlc3Ryb3kgKGZjQ29uZmlnKTsKICAgIGZjQ29uZmlnID0gY29uZmlnOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDb25maWcgKgpGY0NvbmZpZ0dldEN1cnJlbnQgKHZvaWQpCnsKICAgIHJldHVybiBmY0NvbmZpZzsKfQoKRmNCb29sCkZjQ29uZmlnQWRkRGlyIChGY0NvbmZpZyAgICAqY29uZmlnLAoJCWNvbnN0IGNoYXIgICpkKQp7CiAgICBjaGFyICAgICpkaXI7CiAgICBjaGFyICAgICpoOwoKICAgIGlmICgqZCA9PSAnficpCiAgICB7CgloID0gZ2V0ZW52ICgiSE9NRSIpOwoJaWYgKCFoKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJZGlyID0gKGNoYXIgKikgbWFsbG9jIChzdHJsZW4gKGgpICsgc3RybGVuIChkKSk7CglpZiAoIWRpcikKCSAgICByZXR1cm4gRmNGYWxzZTsKCXN0cmNweSAoZGlyLCBoKTsKCXN0cmNhdCAoZGlyLCBkKzEpOwogICAgfQogICAgZWxzZQogICAgewoJZGlyID0gKGNoYXIgKikgbWFsbG9jIChzdHJsZW4gKGQpICsgMSk7CglpZiAoIWRpcikKCSAgICByZXR1cm4gRmNGYWxzZTsKCXN0cmNweSAoZGlyLCBkKTsKICAgIH0KICAgIGlmICghRmNDb25maWdBZGRTdHJpbmcgKCZjb25maWctPmRpcnMsIGRpcikpCiAgICB7CglmcmVlIChkaXIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpjaGFyICoqCkZjQ29uZmlnR2V0RGlycyAoRmNDb25maWcgICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+ZGlyczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRmlsZSAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgIGNvbnN0IGNoYXIgICAqZikKewogICAgY2hhciAgICAqZmlsZTsKICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVuYW1lIChmKTsKICAgIGlmICghZmlsZSkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFGY0NvbmZpZ0FkZFN0cmluZyAoJmNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGUpKQogICAgewoJZnJlZSAoZmlsZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCmNoYXIgKioKRmNDb25maWdHZXRDb25maWdGaWxlcyAoRmNDb25maWcgICAgKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmNvbmZpZ0ZpbGVzOwp9CgpGY0Jvb2wKRmNDb25maWdTZXRDYWNoZSAoRmNDb25maWcJKmNvbmZpZywKCQkgIGNvbnN0IGNoYXIJKmMpCnsKICAgIGNoYXIgICAgKm5ldzsKICAgIGNoYXIgICAgKmg7CgogICAgaWYgKCpjID09ICd+JykKICAgIHsKCWggPSBnZXRlbnYgKCJIT01FIik7CglpZiAoIWgpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgluZXcgPSAoY2hhciAqKSBtYWxsb2MgKHN0cmxlbiAoaCkgKyBzdHJsZW4gKGMpKTsKCWlmICghbmV3KQoJICAgIHJldHVybiBGY0ZhbHNlOwoJc3RyY3B5IChuZXcsIGgpOwoJc3RyY2F0IChuZXcsIGMrMSk7CiAgICB9CiAgICBlbHNlCiAgICB7CgluZXcgPSBGY1N0ckNvcHkgKGMpOwogICAgfQogICAgaWYgKGNvbmZpZy0+Y2FjaGUpCglmcmVlIChjb25maWctPmNhY2hlKTsKICAgIGNvbmZpZy0+Y2FjaGUgPSBuZXc7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpjaGFyICoKRmNDb25maWdHZXRDYWNoZSAoRmNDb25maWcgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnLT5jYWNoZTsKfQoKRmNGb250U2V0ICoKRmNDb25maWdHZXRGb250cyAoRmNDb25maWcJKmNvbmZpZywKCQkgIEZjU2V0TmFtZQlzZXQpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnLT5mb250c1tzZXRdOwp9Cgp2b2lkCkZjQ29uZmlnU2V0Rm9udHMgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0ZvbnRTZXQJKmZvbnRzLAoJCSAgRmNTZXROYW1lCXNldCkKewogICAgaWYgKGNvbmZpZy0+Zm9udHNbc2V0XSkKCUZjRm9udFNldERlc3Ryb3kgKGNvbmZpZy0+Zm9udHNbc2V0XSk7CiAgICBjb25maWctPmZvbnRzW3NldF0gPSBmb250czsKfQoKRmNCbGFua3MgKgpGY0NvbmZpZ0dldEJsYW5rcyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmJsYW5rczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQmxhbmsgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0NoYXIzMiAgICAJYmxhbmspCnsKICAgIEZjQmxhbmtzCSpiOwogICAgCiAgICBiID0gY29uZmlnLT5ibGFua3M7CiAgICBpZiAoIWIpCiAgICB7CgliID0gRmNCbGFua3NDcmVhdGUgKCk7CglpZiAoIWIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIUZjQmxhbmtzQWRkIChiLCBibGFuaykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGNvbmZpZy0+YmxhbmtzID0gYjsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZEVkaXQgKEZjQ29uZmlnCSpjb25maWcsCgkJIEZjVGVzdAkJKnRlc3QsCgkJIEZjRWRpdAkJKmVkaXQsCgkJIEZjTWF0Y2hLaW5kCWtpbmQpCnsKICAgIEZjU3Vic3QJKnN1YnN0LCAqKnByZXY7CiAgICBGY1Rlc3QJKnQ7CiAgICBpbnQJCW51bTsKCiAgICBzdWJzdCA9IChGY1N1YnN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY1N1YnN0KSk7CiAgICBpZiAoIXN1YnN0KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoa2luZCA9PSBGY01hdGNoUGF0dGVybikKCXByZXYgPSAmY29uZmlnLT5zdWJzdFBhdHRlcm47CiAgICBlbHNlCglwcmV2ID0gJmNvbmZpZy0+c3Vic3RGb250OwogICAgZm9yICg7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpOwogICAgKnByZXYgPSBzdWJzdDsKICAgIHN1YnN0LT5uZXh0ID0gMDsKICAgIHN1YnN0LT50ZXN0ID0gdGVzdDsKICAgIHN1YnN0LT5lZGl0ID0gZWRpdDsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJBZGQgU3Vic3QgIik7CglGY1N1YnN0UHJpbnQgKHN1YnN0KTsKICAgIH0KICAgIG51bSA9IDA7CiAgICBmb3IgKHQgPSB0ZXN0OyB0OyB0ID0gdC0+bmV4dCkKCW51bSsrOwogICAgaWYgKGNvbmZpZy0+bWF4T2JqZWN0cyA8IG51bSkKCWNvbmZpZy0+bWF4T2JqZWN0cyA9IG51bTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnR5cGVkZWYgc3RydWN0IF9GY1N1YlN0YXRlIHsKICAgIEZjUGF0dGVybkVsdCAgICplbHQ7CiAgICBGY1ZhbHVlTGlzdCAgICAqdmFsdWU7Cn0gRmNTdWJTdGF0ZTsKCnN0YXRpYyBjb25zdCBGY01hdHJpeCAgICBGY0lkZW50aXR5TWF0cml4ID0geyAxLCAwLCAwLCAxIH07CgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ1Byb21vdGUgKEZjVmFsdWUgdiwgRmNWYWx1ZSB1KQp7CiAgICBpZiAodi50eXBlID09IEZjVHlwZUludGVnZXIpCiAgICB7Cgl2LnR5cGUgPSBGY1R5cGVEb3VibGU7Cgl2LnUuZCA9IChkb3VibGUpIHYudS5pOwogICAgfQogICAgZWxzZSBpZiAodi50eXBlID09IEZjVHlwZVZvaWQgJiYgdS50eXBlID09IEZjVHlwZU1hdHJpeCkKICAgIHsKCXYudS5tID0gKEZjTWF0cml4ICopICZGY0lkZW50aXR5TWF0cml4OwoJdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgfQogICAgcmV0dXJuIHY7Cn0KCkZjQm9vbApGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAoRmNWYWx1ZQltLAoJCSAgICAgIEZjT3AJb3AsCgkJICAgICAgRmNWYWx1ZQl2KQp7CiAgICBGY0Jvb2wgICAgcmV0ID0gRmNGYWxzZTsKICAgIAogICAgbSA9IEZjQ29uZmlnUHJvbW90ZSAobSwgdik7CiAgICB2ID0gRmNDb25maWdQcm9tb3RlICh2LCBtKTsKICAgIGlmIChtLnR5cGUgPT0gdi50eXBlKSAKICAgIHsKCXJldCA9IEZjRmFsc2U7Cglzd2l0Y2ggKG0udHlwZSkgewoJY2FzZSBGY1R5cGVJbnRlZ2VyOgoJICAgIGJyZWFrOwkvKiBGY0NvbmZpZ1Byb21vdGUgcHJldmVudHMgdGhpcyBmcm9tIGhhcHBlbmluZyAqLwoJY2FzZSBGY1R5cGVEb3VibGU6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IG0udS5kID09IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOiAgICAKCQlyZXQgPSBtLnUuZCAhPSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BMZXNzOiAgICAKCQlyZXQgPSBtLnUuZCA8IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3NFcXVhbDogICAgCgkJcmV0ID0gbS51LmQgPD0gdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTW9yZTogICAgCgkJcmV0ID0gbS51LmQgPiB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCXJldCA9IG0udS5kID49IHYudS5kOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDogICAgCgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmIgPT0gdi51LmI7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6ICAgIAoJCXJldCA9IG0udS5iICE9IHYudS5iOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVTdHJpbmc6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOiAgICAKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY1N0ckNtcElnbm9yZUNhc2UgKG0udS5zLCB2LnUucykgPT0gMDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDogICAgCgkJcmV0ID0gRmNTdHJDbXBJZ25vcmVDYXNlIChtLnUucywgdi51LnMpICE9IDA7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZU1hdHJpeDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gRmNNYXRyaXhFcXVhbCAobS51Lm0sIHYudS5tKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCQlyZXQgPSAhRmNNYXRyaXhFcXVhbCAobS51Lm0sIHYudS5tKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlQ2hhclNldDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJLyogbSBjb250YWlucyB2IGlmIHYgLSBtIGlzIGVtcHR5ICovCgkJcmV0ID0gRmNDaGFyU2V0U3VidHJhY3RDb3VudCAodi51LmMsIG0udS5jKSA9PSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjQ2hhclNldEVxdWFsIChtLnUuYywgdi51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJCXJldCA9ICFGY0NoYXJTZXRFcXVhbCAobS51LmMsIHYudS5jKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlVm9pZDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gRmNUcnVlOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJfQogICAgfQogICAgZWxzZQogICAgewoJaWYgKG9wID09IEZjT3BOb3RFcXVhbCkKCSAgICByZXQgPSBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKc3RhdGljIEZjVmFsdWUKRmNDb25maWdFdmFsdWF0ZSAoRmNQYXR0ZXJuICpwLCBGY0V4cHIgKmUpCnsKICAgIEZjVmFsdWUJdiwgdmwsIHZyOwogICAgRmNSZXN1bHQJcjsKICAgIEZjTWF0cml4CSptOwogICAgRmNDaGFyOAkqczsKICAgIAogICAgc3dpdGNoIChlLT5vcCkgewogICAgY2FzZSBGY09wSW50ZWdlcjoKCXYudHlwZSA9IEZjVHlwZUludGVnZXI7Cgl2LnUuaSA9IGUtPnUuaXZhbDsKCWJyZWFrOwogICAgY2FzZSBGY09wRG91YmxlOgoJdi50eXBlID0gRmNUeXBlRG91YmxlOwoJdi51LmQgPSBlLT51LmR2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcFN0cmluZzoKCXYudHlwZSA9IEZjVHlwZVN0cmluZzsKCXYudS5zID0gZS0+dS5zdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wTWF0cml4OgoJdi50eXBlID0gRmNUeXBlTWF0cml4OwoJdi51Lm0gPSBlLT51Lm12YWw7Cgl2ID0gRmNWYWx1ZVNhdmUgKHYpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDaGFyU2V0OgoJdi50eXBlID0gRmNUeXBlQ2hhclNldDsKCXYudS5jID0gZS0+dS5jdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQm9vbDoKCXYudHlwZSA9IEZjVHlwZUJvb2w7Cgl2LnUuYiA9IGUtPnUuYnZhbDsKCWJyZWFrOwogICAgY2FzZSBGY09wRmllbGQ6CglyID0gRmNQYXR0ZXJuR2V0IChwLCBlLT51LmZpZWxkLCAwLCAmdik7CglpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcENvbnN0OgoJaWYgKEZjTmFtZUNvbnN0YW50IChlLT51LmNvbnN0YW50LCAmdi51LmkpKQoJICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CgllbHNlCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgY2FzZSBGY09wUXVlc3Q6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCWlmICh2bC50eXBlID09IEZjVHlwZUJvb2wpCgl7CgkgICAgaWYgKHZsLnUuYikKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUubGVmdCk7CgkgICAgZWxzZQoJCXYgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUucmlnaHQtPnUudHJlZS5yaWdodCk7Cgl9CgllbHNlCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGNhc2UgRmNPcE9yOgogICAgY2FzZSBGY09wQW5kOgogICAgY2FzZSBGY09wRXF1YWw6CiAgICBjYXNlIEZjT3BDb250YWluczoKICAgIGNhc2UgRmNPcE5vdEVxdWFsOgogICAgY2FzZSBGY09wTGVzczoKICAgIGNhc2UgRmNPcExlc3NFcXVhbDoKICAgIGNhc2UgRmNPcE1vcmU6CiAgICBjYXNlIEZjT3BNb3JlRXF1YWw6CiAgICBjYXNlIEZjT3BQbHVzOgogICAgY2FzZSBGY09wTWludXM6CiAgICBjYXNlIEZjT3BUaW1lczoKICAgIGNhc2UgRmNPcERpdmlkZToKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJdnIgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUucmlnaHQpOwoJdmwgPSBGY0NvbmZpZ1Byb21vdGUgKHZsLCB2cik7Cgl2ciA9IEZjQ29uZmlnUHJvbW90ZSAodnIsIHZsKTsKCWlmICh2bC50eXBlID09IHZyLnR5cGUpCgl7CgkgICAgc3dpdGNoICh2bC50eXBlKSB7CgkgICAgY2FzZSBGY1R5cGVEb3VibGU6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcFBsdXM6CSAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kICsgdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTWludXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgLSB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BUaW1lczoKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCAqIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcERpdmlkZToKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCAvIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcEVxdWFsOgoJCWNhc2UgRmNPcENvbnRhaW5zOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPT0gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BOb3RFcXVhbDogICAgCgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7IAoJCSAgICB2LnUuYiA9IHZsLnUuZCAhPSB2ci51LmQ7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcExlc3M6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPCB2ci51LmQ7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcExlc3NFcXVhbDogICAgCgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7IAoJCSAgICB2LnUuYiA9IHZsLnUuZCA8PSB2ci51LmQ7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1vcmU6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPiB2ci51LmQ7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1vcmVFcXVhbDogICAgCgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7IAoJCSAgICB2LnUuYiA9IHZsLnUuZCA+PSB2ci51LmQ7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7IAoJCSAgICBicmVhazsKCQl9CgkJaWYgKHYudHlwZSA9PSBGY1R5cGVEb3VibGUgJiYKCQkgICAgdi51LmQgPT0gKGRvdWJsZSkgKGludCkgdi51LmQpCgkJewoJCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJCSAgICB2LnUuaSA9IChpbnQpIHYudS5kOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjVHlwZUJvb2w6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcE9yOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJCSAgICB2LnUuYiA9IHZsLnUuYiB8fCB2ci51LmI7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcEFuZDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgJiYgdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BFcXVhbDoKCQljYXNlIEZjT3BDb250YWluczoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgPT0gdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BOb3RFcXVhbDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgIT0gdnIudS5iOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOyAKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BFcXVhbDoKCQljYXNlIEZjT3BDb250YWluczoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSBGY1N0ckNtcElnbm9yZUNhc2UgKHZsLnUucywgdnIudS5zKSA9PSAwOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BOb3RFcXVhbDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSBGY1N0ckNtcElnbm9yZUNhc2UgKHZsLnUucywgdnIudS5zKSAhPSAwOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BQbHVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVTdHJpbmc7CgkJICAgIHYudS5zID0gRmNTdHJQbHVzICh2bC51LnMsIHZyLnUucyk7CgkJICAgIGlmICghdi51LnMpCgkJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIGJyZWFrOwoJCX0KCSAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wRXF1YWw6CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNNYXRyaXhFcXVhbCAodmwudS5tLCB2ci51Lm0pOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BOb3RFcXVhbDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSBGY01hdHJpeEVxdWFsICh2bC51Lm0sIHZyLnUubSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcFRpbWVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CgkJICAgIG0gPSBtYWxsb2MgKHNpemVvZiAoRmNNYXRyaXgpKTsKCQkgICAgaWYgKG0pCgkJICAgIHsKCQkJRmNNZW1BbGxvYyAoRkNfTUVNX01BVFJJWCwgc2l6ZW9mIChGY01hdHJpeCkpOwoJCQlGY01hdHJpeE11bHRpcGx5IChtLCB2bC51Lm0sIHZyLnUubSk7CgkJCXYudS5tID0gbTsKCQkgICAgfQoJCSAgICBlbHNlCgkJICAgIHsKCQkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgfQoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BDb250YWluczoKCQkgICAgLyogdmwgY29udGFpbnMgdnIgaWYgdnIgLSB2bCBpcyBlbXB0eSAqLwoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJCSAgICB2LnUuYiA9IEZjQ2hhclNldFN1YnRyYWN0Q291bnQgKHZyLnUuYywgdmwudS5jKSA9PSAwOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BFcXVhbDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSBGY0NoYXJTZXRFcXVhbCAodmwudS5jLCB2ci51LmMpOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BOb3RFcXVhbDoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSAhRmNDaGFyU2V0RXF1YWwgKHZsLnUuYywgdnIudS5jKTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQlicmVhazsKCSAgICB9Cgl9CgllbHNlCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCUZjVmFsdWVEZXN0cm95ICh2bCk7CglGY1ZhbHVlRGVzdHJveSAodnIpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BOb3Q6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXN3aXRjaCAodmwudHlwZSkgewoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkgICAgdi51LmIgPSAhdmwudS5iOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIH0KICAgIHJldHVybiB2Owp9CgpzdGF0aWMgRmNWYWx1ZUxpc3QgKgpGY0NvbmZpZ01hdGNoVmFsdWVMaXN0IChGY1BhdHRlcm4JKnAsCgkJCUZjVGVzdAkJKnQsCgkJCUZjVmFsdWVMaXN0CSp2KQp7CiAgICBGY1ZhbHVlTGlzdCAgICAqcmV0ID0gMDsKICAgIEZjVmFsdWUJICAgIHZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgdC0+ZXhwcik7CiAgICAKICAgIGZvciAoOyB2OyB2ID0gdi0+bmV4dCkKICAgIHsKCWlmIChGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAodi0+dmFsdWUsIHQtPm9wLCB2YWx1ZSkpCgl7CgkgICAgaWYgKCFyZXQpCgkJcmV0ID0gdjsKCX0KCWVsc2UKCXsKCSAgICBpZiAodC0+cXVhbCA9PSBGY1F1YWxBbGwpCgkgICAgewoJCXJldCA9IDA7CgkJYnJlYWs7CgkgICAgfQoJfQogICAgfQogICAgRmNWYWx1ZURlc3Ryb3kgKHZhbHVlKTsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBGY1ZhbHVlTGlzdCAqCkZjQ29uZmlnVmFsdWVzIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZUxpc3QJKmw7CiAgICAKICAgIGlmICghZSkKCXJldHVybiAwOwogICAgbCA9IChGY1ZhbHVlTGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmICghbCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmIChlLT5vcCA9PSBGY09wQ29tbWEpCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCWwtPm5leHQgID0gRmNDb25maWdWYWx1ZXMgKHAsIGUtPnUudHJlZS5yaWdodCk7CiAgICB9CiAgICBlbHNlCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUpOwoJbC0+bmV4dCAgPSAwOwogICAgfQogICAgd2hpbGUgKGwtPnZhbHVlLnR5cGUgPT0gRmNUeXBlVm9pZCkKICAgIHsKCUZjVmFsdWVMaXN0CSpuZXh0ID0gbC0+bmV4dDsKCQoJRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwoJZnJlZSAobCk7CglsID0gbmV4dDsKICAgIH0KICAgIHJldHVybiBsOwp9CgpzdGF0aWMgRmNCb29sCkZjQ29uZmlnQWRkIChGY1ZhbHVlTGlzdCAgICAqKmhlYWQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpwb3NpdGlvbiwKCSAgICAgRmNCb29sCSAgICBhcHBlbmQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpuZXcpCnsKICAgIEZjVmFsdWVMaXN0ICAgICoqcHJldiwgKmxhc3Q7CiAgICAKICAgIGlmIChhcHBlbmQpCiAgICB7CglpZiAocG9zaXRpb24pCgkgICAgcHJldiA9ICZwb3NpdGlvbi0+bmV4dDsKCWVsc2UKCSAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQoJCTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChwb3NpdGlvbikKCXsKCSAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQoJICAgIHsKCQlpZiAoKnByZXYgPT0gcG9zaXRpb24pCgkJICAgIGJyZWFrOwoJICAgIH0KCX0KCWVsc2UKCSAgICBwcmV2ID0gaGVhZDsKCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIGlmICghKnByZXYpCgkJcHJpbnRmICgicG9zaXRpb24gbm90IG9uIGxpc3RcbiIpOwoJfQogICAgfQoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCIlcyBsaXN0IGJlZm9yZSAiLCBhcHBlbmQgPyAiQXBwZW5kIiA6ICJQcmVwZW5kIik7CglGY1ZhbHVlTGlzdFByaW50ICgqaGVhZCk7CglwcmludGYgKCJcbiIpOwogICAgfQogICAgCiAgICBpZiAobmV3KQogICAgewoJbGFzdCA9IG5ldzsKCXdoaWxlIChsYXN0LT5uZXh0KQoJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwogICAgCglsYXN0LT5uZXh0ID0gKnByZXY7CgkqcHJldiA9IG5ldzsKICAgIH0KICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIiVzIGxpc3QgYWZ0ZXIgIiwgYXBwZW5kID8gIkFwcGVuZCIgOiAiUHJlcGVuZCIpOwoJRmNWYWx1ZUxpc3RQcmludCAoKmhlYWQpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIAogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdEZWwgKEZjVmFsdWVMaXN0ICAgICoqaGVhZCwKCSAgICAgRmNWYWx1ZUxpc3QgICAgKnBvc2l0aW9uKQp7CiAgICBGY1ZhbHVlTGlzdCAgICAqKnByZXY7CgogICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmICgqcHJldiA9PSBwb3NpdGlvbikKCXsKCSAgICAqcHJldiA9IHBvc2l0aW9uLT5uZXh0OwoJICAgIHBvc2l0aW9uLT5uZXh0ID0gMDsKCSAgICBGY1ZhbHVlTGlzdERlc3Ryb3kgKHBvc2l0aW9uKTsKCSAgICBicmVhazsKCX0KICAgIH0KfQoKc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuQWRkIChGY1BhdHRlcm4JKnAsCgkJICAgIGNvbnN0IGNoYXIJKm9iamVjdCwKCQkgICAgRmNWYWx1ZUxpc3QJKmxpc3QsCgkJICAgIEZjQm9vbAlhcHBlbmQpCnsKICAgIGlmIChsaXN0KQogICAgewoJRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuRmluZCAocCwgb2JqZWN0LCBGY1RydWUpOwogICAgCglpZiAoIWUpCgkgICAgcmV0dXJuOwoJRmNDb25maWdBZGQgKCZlLT52YWx1ZXMsIDAsIGFwcGVuZCwgbGlzdCk7CiAgICB9Cn0KCi8qCiAqIERlbGV0ZSBhbGwgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBhIGZpZWxkCiAqLwpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5EZWwgKEZjUGF0dGVybgkqcCwKCQkgICAgY29uc3QgY2hhcgkqb2JqZWN0KQp7CiAgICBGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5GaW5kIChwLCBvYmplY3QsIEZjRmFsc2UpOwogICAgaWYgKCFlKQoJcmV0dXJuOwogICAgd2hpbGUgKGUtPnZhbHVlcykKCUZjQ29uZmlnRGVsICgmZS0+dmFsdWVzLCBlLT52YWx1ZXMpOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5DYW5vbiAoRmNQYXR0ZXJuCSAgICAqcCwKCQkgICAgICBjb25zdCBjaGFyICAgICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkZpbmQgKHAsIG9iamVjdCwgRmNGYWxzZSk7CiAgICBpZiAoIWUpCglyZXR1cm47CiAgICBpZiAoIWUtPnZhbHVlcykKCUZjUGF0dGVybkRlbCAocCwgb2JqZWN0KTsKfQoKRmNCb29sCkZjQ29uZmlnU3Vic3RpdHV0ZSAoRmNDb25maWcJKmNvbmZpZywKCQkgICAgRmNQYXR0ZXJuCSpwLAoJCSAgICBGY01hdGNoS2luZAlraW5kKQp7CiAgICBGY1N1YnN0CSAgICAqczsKICAgIEZjU3ViU3RhdGUJICAgICpzdDsKICAgIGludAkJICAgIGk7CiAgICBGY1Rlc3QJICAgICp0OwogICAgRmNFZGl0CSAgICAqZTsKICAgIEZjVmFsdWVMaXN0CSAgICAqbDsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHN0ID0gKEZjU3ViU3RhdGUgKikgbWFsbG9jIChjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKICAgIGlmICghc3QgJiYgY29uZmlnLT5tYXhPYmplY3RzKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1VCU1RBVEUsIGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgIik7CglGY1BhdHRlcm5QcmludCAocCk7CiAgICB9CiAgICBpZiAoa2luZCA9PSBGY01hdGNoUGF0dGVybikKCXMgPSBjb25maWctPnN1YnN0UGF0dGVybjsKICAgIGVsc2UKCXMgPSBjb25maWctPnN1YnN0Rm9udDsKICAgIGZvciAoOyBzOyBzID0gcy0+bmV4dCkKICAgIHsKCS8qCgkgKiBDaGVjayB0aGUgdGVzdHMgdG8gc2VlIGlmCgkgKiB0aGV5IGFsbCBtYXRjaCB0aGUgcGF0dGVybgoJICovCglmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJICAgIHsKCQlwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgdGVzdCAiKTsKCQlGY1Rlc3RQcmludCAodCk7CgkgICAgfQoJICAgIHN0W2ldLmVsdCA9IEZjUGF0dGVybkZpbmQgKHAsIHQtPmZpZWxkLCBGY0ZhbHNlKTsKCSAgICAvKgoJICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBmaWVsZCBpbiB0aGUgZm9udCwKCSAgICAgKiB0aGVuIEZjUXVhbEFsbCBtYXRjaGVzIHdoaWxlIEZjUXVhbEFueSBkb2VzIG5vdAoJICAgICAqLwoJICAgIGlmICghc3RbaV0uZWx0KQoJICAgIHsKCQlpZiAodC0+cXVhbCA9PSBGY1F1YWxBbGwpCgkJewoJCSAgICBzdFtpXS52YWx1ZSA9IDA7CgkJICAgIGNvbnRpbnVlOwoJCX0KCQllbHNlCgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICAvKgoJICAgICAqIENoZWNrIHRvIHNlZSBpZiB0aGVyZSBpcyBhIG1hdGNoLCBtYXJrIHRoZSBsb2NhdGlvbgoJICAgICAqIHRvIGFwcGx5IG1hdGNoLXJlbGF0aXZlIGVkaXRzCgkgICAgICovCgkgICAgc3RbaV0udmFsdWUgPSBGY0NvbmZpZ01hdGNoVmFsdWVMaXN0IChwLCB0LCBzdFtpXS5lbHQtPnZhbHVlcyk7CgkgICAgaWYgKCFzdFtpXS52YWx1ZSkKCQlicmVhazsKCX0KCWlmICh0KQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgkJcHJpbnRmICgiTm8gbWF0Y2hcbiIpOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBwcmludGYgKCJTdWJzdGl0dXRlICIpOwoJICAgIEZjU3Vic3RQcmludCAocyk7Cgl9Cglmb3IgKGUgPSBzLT5lZGl0OyBlOyBlID0gZS0+bmV4dCkKCXsKCSAgICAvKgoJICAgICAqIEV2YWx1YXRlIHRoZSBsaXN0IG9mIGV4cHJlc3Npb25zCgkgICAgICovCgkgICAgbCA9IEZjQ29uZmlnVmFsdWVzIChwLCBlLT5leHByKTsKCSAgICAvKgoJICAgICAqIExvY2F0ZSBhbnkgdGVzdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBmaWVsZAoJICAgICAqLwoJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCWlmICghRmNTdHJDbXBJZ25vcmVDYXNlICh0LT5maWVsZCwgZS0+ZmllbGQpKQoJCSAgICBicmVhazsKCSAgICBzd2l0Y2ggKGUtPm9wKSB7CgkgICAgY2FzZSBGY09wQXNzaWduOgoJCS8qCgkJICogSWYgdGhlcmUgd2FzIGEgdGVzdCwgdGhlbiByZXBsYWNlIHRoZSBtYXRjaGVkCgkJICogdmFsdWUgd2l0aCB0aGUgbmV3IGxpc3Qgb2YgdmFsdWVzCgkJICovCgkJaWYgKHQpCgkJewoJCSAgICBGY1ZhbHVlTGlzdAkqdGhpc1ZhbHVlID0gc3RbaV0udmFsdWU7CgkJICAgIEZjVmFsdWVMaXN0CSpuZXh0VmFsdWUgPSB0aGlzVmFsdWUgPyB0aGlzVmFsdWUtPm5leHQgOiAwOwoJCSAgICAKCQkgICAgLyoKCQkgICAgICogQXBwZW5kIHRoZSBuZXcgbGlzdCBvZiB2YWx1ZXMgYWZ0ZXIgdGhlIGN1cnJlbnQgdmFsdWUKCQkgICAgICovCgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHRoaXNWYWx1ZSwgRmNUcnVlLCBsKTsKCQkgICAgLyoKCQkgICAgICogQWRqdXN0IGFueSBwb2ludGVycyBpbnRvIHRoZSB2YWx1ZSBsaXN0IHRvIGVuc3VyZQoJCSAgICAgKiBmdXR1cmUgZWRpdHMgb2NjdXIgYXQgdGhlIHNhbWUgcGxhY2UKCQkgICAgICovCgkJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCSAgICB7CgkJCWlmIChzdFtpXS52YWx1ZSA9PSB0aGlzVmFsdWUpCgkJCSAgICBzdFtpXS52YWx1ZSA9IG5leHRWYWx1ZTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAgKiBEZWxldGUgdGhlIG1hcmtlZCB2YWx1ZQoJCSAgICAgKi8KCQkgICAgRmNDb25maWdEZWwgKCZzdFtpXS5lbHQtPnZhbHVlcywgdGhpc1ZhbHVlKTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BBc3NpZ25SZXBsYWNlOgoJCS8qCgkJICogRGVsZXRlIGFsbCBvZiB0aGUgdmFsdWVzIGFuZCBpbnNlcnQKCQkgKiB0aGUgbmV3IHNldAoJCSAqLwoJCUZjQ29uZmlnUGF0dGVybkRlbCAocCwgZS0+ZmllbGQpOwoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjVHJ1ZSk7CgkJLyoKCQkgKiBBZGp1c3QgYW55IHBvaW50ZXJzIGludG8gdGhlIHZhbHVlIGxpc3QgYXMgdGhleSBubwoJCSAqIGxvbmdlciBwb2ludCB0byBhbnl0aGluZyB2YWxpZAoJCSAqLwoJCWlmICh0KQoJCXsKCQkgICAgRmNQYXR0ZXJuRWx0ICAgICp0aGlzRWx0ID0gc3RbaV0uZWx0OwoJCSAgICBmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCQkgICAgewoJCQlpZiAoc3RbaV0uZWx0ID09IHRoaXNFbHQpCgkJCSAgICBzdFtpXS52YWx1ZSA9IDA7CgkJICAgIH0KCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wUHJlcGVuZDoKCQlpZiAodCkKCQl7CgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHN0W2ldLnZhbHVlLCBGY0ZhbHNlLCBsKTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BQcmVwZW5kRmlyc3Q6CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNGYWxzZSk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wQXBwZW5kOgoJCWlmICh0KQoJCXsKCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgc3RbaV0udmFsdWUsIEZjVHJ1ZSwgbCk7CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wQXBwZW5kTGFzdDoKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY1RydWUpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJfQoJLyoKCSAqIE5vdyBnbyB0aHJvdWdoIHRoZSBwYXR0ZXJuIGFuZCBlbGltaW5hdGUKCSAqIGFueSBwcm9wZXJ0aWVzIHdpdGhvdXQgZGF0YQoJICovCglmb3IgKGUgPSBzLT5lZGl0OyBlOyBlID0gZS0+bmV4dCkKCSAgICBGY0NvbmZpZ1BhdHRlcm5DYW5vbiAocCwgZS0+ZmllbGQpOwoKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIGVkaXQiKTsKCSAgICBGY1BhdHRlcm5QcmludCAocCk7Cgl9CiAgICB9CiAgICBGY01lbUZyZWUgKEZDX01FTV9TVUJTVEFURSwgY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CiAgICBmcmVlIChzdCk7CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIGRvbmUiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCiNpZm5kZWYgRk9OVENPTkZJR19QQVRICiNkZWZpbmUgRk9OVENPTkZJR19QQVRICSIvZXRjL2ZvbnRzIgojZW5kaWYKCiNpZm5kZWYgRk9OVENPTkZJR19GSUxFCiNkZWZpbmUgRk9OVENPTkZJR19GSUxFCSJmb250cy5jb25mIgojZW5kaWYKCnN0YXRpYyBjaGFyICoKRmNDb25maWdGaWxlRXhpc3RzIChjb25zdCBjaGFyICpkaXIsIGNvbnN0IGNoYXIgKmZpbGUpCnsKICAgIGNoYXIgICAgKnBhdGg7CgogICAgaWYgKCFkaXIpCglkaXIgPSAiIjsKICAgIHBhdGggPSBtYWxsb2MgKHN0cmxlbiAoZGlyKSArIDEgKyBzdHJsZW4gKGZpbGUpICsgMSk7CiAgICBpZiAoIXBhdGgpCglyZXR1cm4gMDsKCiAgICBzdHJjcHkgKHBhdGgsIGRpcik7CiAgICAvKiBtYWtlIHN1cmUgdGhlcmUncyBhIHNpbmdsZSBzZXBhcmF0aW5nIC8gKi8KICAgIGlmICgoIXBhdGhbMF0gfHwgcGF0aFtzdHJsZW4ocGF0aCktMV0gIT0gJy8nKSAmJiBmaWxlWzBdICE9ICcvJykKCXN0cmNhdCAocGF0aCwgIi8iKTsKICAgIHN0cmNhdCAocGF0aCwgZmlsZSk7CgogICAgaWYgKGFjY2VzcyAocGF0aCwgUl9PSykgPT0gMCkKCXJldHVybiBwYXRoOwogICAgCiAgICBmcmVlIChwYXRoKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgY2hhciAqKgpGY0NvbmZpZ0dldFBhdGggKHZvaWQpCnsKICAgIGNoYXIgICAgKipwYXRoOwogICAgY2hhciAgICAqZW52LCAqZSwgKmNvbG9uOwogICAgY2hhciAgICAqZGlyOwogICAgaW50CSAgICBucGF0aDsKICAgIGludAkgICAgaTsKCiAgICBucGF0aCA9IDI7CS8qIGRlZmF1bHQgZGlyICsgbnVsbCAqLwogICAgZW52ID0gZ2V0ZW52ICgiRk9OVENPTkZJR19QQVRIIik7CiAgICBpZiAoZW52KQogICAgewoJZSA9IGVudjsKCW5wYXRoKys7Cgl3aGlsZSAoKmUpCgkgICAgaWYgKCplKysgPT0gJzonKQoJCW5wYXRoKys7CiAgICB9CiAgICBwYXRoID0gY2FsbG9jIChucGF0aCwgc2l6ZW9mIChjaGFyICopKTsKICAgIGlmICghcGF0aCkKCWdvdG8gYmFpbDA7CiAgICBpID0gMDsKCiAgICBpZiAoZW52KQogICAgewoJZSA9IGVudjsKCXdoaWxlICgqZSkgCgl7CgkgICAgY29sb24gPSBzdHJjaHIgKGUsICc6Jyk7CgkgICAgaWYgKCFjb2xvbikKCQljb2xvbiA9IGUgKyBzdHJsZW4gKGUpOwoJICAgIHBhdGhbaV0gPSBtYWxsb2MgKGNvbG9uIC0gZSArIDEpOwoJICAgIGlmICghcGF0aFtpXSkKCQlnb3RvIGJhaWwxOwoJICAgIHN0cm5jcHkgKHBhdGhbaV0sIGUsIGNvbG9uIC0gZSk7CgkgICAgcGF0aFtpXVtjb2xvbiAtIGVdID0gJ1wwJzsKCSAgICBpZiAoKmNvbG9uKQoJCWUgPSBjb2xvbiArIDE7CgkgICAgZWxzZQoJCWUgPSBjb2xvbjsKCSAgICBpKys7Cgl9CiAgICB9CiAgICAKICAgIGRpciA9IEZPTlRDT05GSUdfUEFUSDsKICAgIHBhdGhbaV0gPSBtYWxsb2MgKHN0cmxlbiAoZGlyKSArIDEpOwogICAgaWYgKCFwYXRoW2ldKQoJZ290byBiYWlsMTsKICAgIHN0cmNweSAocGF0aFtpXSwgZGlyKTsKICAgIHJldHVybiBwYXRoOwoKYmFpbDE6CiAgICBmb3IgKGkgPSAwOyBwYXRoW2ldOyBpKyspCglmcmVlIChwYXRoW2ldKTsKICAgIGZyZWUgKHBhdGgpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ0ZyZWVQYXRoIChjaGFyICoqcGF0aCkKewogICAgY2hhciAgICAqKnA7CgogICAgZm9yIChwID0gcGF0aDsgKnA7IHArKykKCWZyZWUgKCpwKTsKICAgIGZyZWUgKHBhdGgpOwp9CgpjaGFyICoKRmNDb25maWdGaWxlbmFtZSAoY29uc3QgY2hhciAqdXJsKQp7CiAgICBjaGFyICAgICpmaWxlLCAqZGlyLCAqKnBhdGgsICoqcDsKICAgIAogICAgaWYgKCF1cmwgfHwgISp1cmwpCiAgICB7Cgl1cmwgPSBnZXRlbnYgKCJGT05UQ09ORklHX0ZJTEUiKTsKCWlmICghdXJsKQoJICAgIHVybCA9IEZPTlRDT05GSUdfRklMRTsKICAgIH0KICAgIHN3aXRjaCAoKnVybCkgewogICAgY2FzZSAnfic6CglkaXIgPSBnZXRlbnYgKCJIT01FIik7CglpZiAoZGlyKQoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKGRpciwgdXJsICsgMSk7CgllbHNlCgkgICAgZmlsZSA9IDA7CglicmVhazsKICAgIGNhc2UgJy8nOgoJZmlsZSA9IEZjQ29uZmlnRmlsZUV4aXN0cyAoMCwgdXJsKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXBhdGggPSBGY0NvbmZpZ0dldFBhdGggKCk7CglpZiAoIXBhdGgpCgkgICAgcmV0dXJuIDA7Cglmb3IgKHAgPSBwYXRoOyAqcDsgcCsrKQoJewoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKCpwLCB1cmwpOwoJICAgIGlmIChmaWxlKQoJCWJyZWFrOwoJfQoJRmNDb25maWdGcmVlUGF0aCAocGF0aCk7CglicmVhazsKICAgIH0KICAgIHJldHVybiBmaWxlOwp9CgovKgogKiBNYW5hZ2UgdGhlIGFwcGxpY2F0aW9uLXNwZWNpZmljIGZvbnRzCiAqLwoKRmNCb29sCkZjQ29uZmlnQXBwRm9udEFkZEZpbGUgKEZjQ29uZmlnICAgICpjb25maWcsCgkJCWNvbnN0IGNoYXIgICpmaWxlKQp7CiAgICBGY0ZvbnRTZXQJKnNldDsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHNldCA9IEZjQ29uZmlnR2V0Rm9udHMgKGNvbmZpZywgRmNTZXRBcHBsaWNhdGlvbik7CiAgICBpZiAoIXNldCkKICAgIHsKCXNldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKCWlmICghc2V0KQoJICAgIHJldHVybiBGY0ZhbHNlOwoJRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBzZXQsIEZjU2V0QXBwbGljYXRpb24pOwogICAgfQogICAgcmV0dXJuIEZjRmlsZVNjYW4gKHNldCwgMCwgY29uZmlnLT5ibGFua3MsIGZpbGUsIEZjRmFsc2UpOwp9CgpGY0Jvb2wKRmNDb25maWdBcHBGb250QWRkRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgY2hhciAgICpkaXIpCnsKICAgIEZjRm9udFNldAkqc2V0OwogICAgCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgc2V0ID0gRmNDb25maWdHZXRGb250cyAoY29uZmlnLCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIGlmICghc2V0KQogICAgewoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIHNldCwgRmNTZXRBcHBsaWNhdGlvbik7CiAgICB9CiAgICByZXR1cm4gRmNEaXJTY2FuIChzZXQsIDAsIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UpOwp9Cgp2b2lkCkZjQ29uZmlnQXBwRm9udENsZWFyIChGY0NvbmZpZwkgICAgKmNvbmZpZykKewogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCAwLCBGY1NldEFwcGxpY2F0aW9uKTsKfQo=