LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNsYW5nLmMsdiAxLjcgMjAwMi8wOC8yNiAyMzozNDozMSBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCnR5cGVkZWYgc3RydWN0IHsKICAgIEZjQ2hhcjgJKmxhbmc7CiAgICBGY0NoYXJTZXQJY2hhcnNldDsKfSBGY0xhbmdDaGFyU2V0OwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgaW50IGJlZ2luOwogICAgaW50IGVuZDsKfSBGY0xhbmdDaGFyU2V0UmFuZ2U7CgojaW5jbHVkZSAiLi4vZmMtbGFuZy9mY2xhbmcuaCIKCnN0cnVjdCBfRmNMYW5nU2V0IHsKICAgIEZjQ2hhcjMyCW1hcFtOVU1fTEFOR19TRVRfTUFQXTsKICAgIEZjU3RyU2V0CSpleHRyYTsKfTsKCiNkZWZpbmUgRmNMYW5nU2V0Qml0U2V0KGxzLCBpZCkJKChscyktPm1hcFsoaWQpPj41XSB8PSAoKEZjQ2hhcjMyKSAxIDw8ICgoaWQpICYgMHgxZikpKQojZGVmaW5lIEZjTGFuZ1NldEJpdEdldChscywgaWQpICgoKGxzKS0+bWFwWyhpZCk+PjVdID4+ICgoaWQpICYgMHgxZikpICYgMSkKCkZjTGFuZ1NldCAqCkZjRnJlZVR5cGVMYW5nU2V0IChjb25zdCBGY0NoYXJTZXQgICpjaGFyc2V0LCAKCQkgICBjb25zdCBGY0NoYXI4ICAgICpleGNsdXNpdmVMYW5nKQp7CiAgICBpbnQJCSAgICBpOwogICAgRmNDaGFyMzIJICAgIG1pc3Npbmc7CiAgICBjb25zdCBGY0NoYXJTZXQgKmV4Y2x1c2l2ZUNoYXJzZXQgPSAwOwogICAgRmNMYW5nU2V0CSAgICAqbHM7CiAgICAKCiAgICBpZiAoZXhjbHVzaXZlTGFuZykKCWV4Y2x1c2l2ZUNoYXJzZXQgPSBGY0NoYXJTZXRGb3JMYW5nIChleGNsdXNpdmVMYW5nKTsKICAgIGxzID0gRmNMYW5nU2V0Q3JlYXRlICgpOwogICAgaWYgKCFscykKCXJldHVybiAwOwogICAgZm9yIChpID0gMDsgaSA8IE5VTV9MQU5HX0NIQVJfU0VUOyBpKyspCiAgICB7CgkvKgoJICogQ2hlY2sgZm9yIEhhbiBjaGFyc2V0cyB0byBtYWtlIGZvbnRzCgkgKiB3aGljaCBhZHZlcnRpc2Ugc3VwcG9ydCBmb3IgYSBzaW5nbGUgbGFuZ3VhZ2UKCSAqIG5vdCBzdXBwb3J0IG90aGVyIEhhbiBsYW5ndWFnZXMKCSAqLwoJaWYgKGV4Y2x1c2l2ZUNoYXJzZXQgJiYKCSAgICBGY0ZyZWVUeXBlSXNFeGNsdXNpdmVMYW5nIChmY0xhbmdDaGFyU2V0c1tpXS5sYW5nKSAmJgoJICAgIGZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQubGVhdmVzICE9IGV4Y2x1c2l2ZUNoYXJzZXQtPmxlYXZlcykKCXsKCSAgICBjb250aW51ZTsKCX0KCW1pc3NpbmcgPSBGY0NoYXJTZXRTdWJ0cmFjdENvdW50ICgmZmNMYW5nQ2hhclNldHNbaV0uY2hhcnNldCwgY2hhcnNldCk7CiAgICAgICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19TQ0FOVikKCXsKCSAgICBpZiAobWlzc2luZyAmJiBtaXNzaW5nIDwgMTApCgkgICAgewoJCUZjQ2hhclNldCAgICptaXNzZWQgPSBGY0NoYXJTZXRTdWJ0cmFjdCAoJmZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQsIAoJCQkJCQkJIGNoYXJzZXQpOwoJCUZjQ2hhcjMyICAgIHVjczQ7CgkJRmNDaGFyMzIgICAgbWFwW0ZDX0NIQVJTRVRfTUFQX1NJWkVdOwoJCUZjQ2hhcjMyICAgIG5leHQ7CgoJCXByaW50ZiAoIlxuJXMoJWQpICIsIGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcsIG1pc3NpbmcpOwoJCXByaW50ZiAoInsiKTsKCQlmb3IgKHVjczQgPSBGY0NoYXJTZXRGaXJzdFBhZ2UgKG1pc3NlZCwgbWFwLCAmbmV4dCk7CgkJICAgICB1Y3M0ICE9IEZDX0NIQVJTRVRfRE9ORTsKCQkgICAgIHVjczQgPSBGY0NoYXJTZXROZXh0UGFnZSAobWlzc2VkLCBtYXAsICZuZXh0KSkKCQl7CgkJICAgIGludAkgICAgaSwgajsKCQkgICAgZm9yIChpID0gMDsgaSA8IEZDX0NIQVJTRVRfTUFQX1NJWkU7IGkrKykKCQkJaWYgKG1hcFtpXSkKCQkJewoJCQkgICAgZm9yIChqID0gMDsgaiA8IDMyOyBqKyspCgkJCQlpZiAobWFwW2ldICYgKDEgPDwgaikpCgkJCQkgICAgcHJpbnRmICgiICUwNHgiLCB1Y3M0ICsgaSAqIDMyICsgaik7CgkJCX0KCQl9CgkJcHJpbnRmICgiIH1cblx0Iik7CgkJRmNDaGFyU2V0RGVzdHJveSAobWlzc2VkKTsKCSAgICB9CgkgICAgZWxzZQoJCXByaW50ZiAoIiVzKCVkKSAiLCBmY0xhbmdDaGFyU2V0c1tpXS5sYW5nLCBtaXNzaW5nKTsKCX0KCWlmICghbWlzc2luZykKCSAgICBGY0xhbmdTZXRCaXRTZXQgKGxzLCBpKTsKICAgIH0KCiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX1NDQU5WKQoJcHJpbnRmICgiXG4iKTsKICAgIAogICAgCiAgICByZXR1cm4gbHM7Cn0KCiNkZWZpbmUgRmNMYW5nRW5kKGMpCSgoYykgPT0gJy0nIHx8IChjKSA9PSAnXDAnKQoKRmNMYW5nUmVzdWx0CkZjTGFuZ0NvbXBhcmUgKGNvbnN0IEZjQ2hhcjggKnMxLCBjb25zdCBGY0NoYXI4ICpzMikKewogICAgRmNDaGFyOAkgICAgYzEsIGMyOwogICAgRmNMYW5nUmVzdWx0ICAgIHJlc3VsdCA9IEZjTGFuZ0RpZmZlcmVudExhbmc7CgogICAgZm9yICg7OykKICAgIHsKCWMxID0gKnMxKys7CgljMiA9ICpzMisrOwoJCgljMSA9IEZjVG9Mb3dlciAoYzEpOwoJYzIgPSBGY1RvTG93ZXIgKGMyKTsKCWlmIChjMSAhPSBjMikKCXsKCSAgICBpZiAoRmNMYW5nRW5kIChjMSkgJiYgRmNMYW5nRW5kIChjMikpCgkJcmVzdWx0ID0gRmNMYW5nRGlmZmVyZW50Q291bnRyeTsKCSAgICByZXR1cm4gcmVzdWx0OwoJfQoJZWxzZSBpZiAoIWMxKQoJICAgIHJldHVybiBGY0xhbmdFcXVhbDsKCWVsc2UgaWYgKGMxID09ICctJykKCSAgICByZXN1bHQgPSBGY0xhbmdEaWZmZXJlbnRDb3VudHJ5OwogICAgfQp9CgovKgogKiBSZXR1cm4gRmNUcnVlIHdoZW4gczEgY29udGFpbnMgczIuIAogKgogKiBzMSBjb250YWlucyBzMiBpZiBzMSBlcXVhbHMgczIgb3IgaWYgczEgaXMgYQogKiBsYW5ndWFnZSB3aXRoIGEgY291bnRyeSBhbmQgczIgaXMganVzdCBhIGxhbmd1YWdlCiAqLwoKc3RhdGljIEZjQm9vbApGY0xhbmdDb250YWlucyAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4CSAgICBjMSwgYzI7CgogICAgZm9yICg7OykKICAgIHsKCWMxID0gKnMxKys7CgljMiA9ICpzMisrOwoJCgljMSA9IEZjVG9Mb3dlciAoYzEpOwoJYzIgPSBGY1RvTG93ZXIgKGMyKTsKCWlmIChjMSAhPSBjMikKCXsKCSAgICAvKiBzZWUgaWYgczEgaGFzIGEgY291bnRyeSB3aGlsZSBzMiBpcyBtaXNpbmcgb25lICovCgkgICAgaWYgKGMxID09ICctJyAmJiBjMiA9PSAnXDAnKQoJCXJldHVybiBGY1RydWU7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CgllbHNlIGlmICghYzEpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIH0KfQoKY29uc3QgRmNDaGFyU2V0ICoKRmNDaGFyU2V0Rm9yTGFuZyAoY29uc3QgRmNDaGFyOCAqbGFuZykKewogICAgaW50CQlpOwogICAgaW50CQljb3VudHJ5ID0gLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0xBTkdfQ0hBUl9TRVQ7IGkrKykKICAgIHsKCXN3aXRjaCAoRmNMYW5nQ29tcGFyZSAobGFuZywgZmNMYW5nQ2hhclNldHNbaV0ubGFuZykpIHsKCWNhc2UgRmNMYW5nRXF1YWw6CgkgICAgcmV0dXJuICZmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0OwoJY2FzZSBGY0xhbmdEaWZmZXJlbnRDb3VudHJ5OgoJICAgIGlmIChjb3VudHJ5ID09IC0xKQoJCWNvdW50cnkgPSBpOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChjb3VudHJ5ID09IC0xKQoJcmV0dXJuIDA7CiAgICByZXR1cm4gJmZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQ7Cn0KCkZjTGFuZ1NldCAqCkZjTGFuZ1NldENyZWF0ZSAodm9pZCkKewogICAgRmNMYW5nU2V0CSpsczsKCiAgICBscyA9IG1hbGxvYyAoc2l6ZW9mIChGY0xhbmdTZXQpKTsKICAgIGlmICghbHMpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9MQU5HU0VULCBzaXplb2YgKEZjTGFuZ1NldCkpOwogICAgbWVtc2V0IChscy0+bWFwLCAnXDAnLCBzaXplb2YgKGxzLT5tYXApKTsKICAgIGxzLT5leHRyYSA9IDA7CiAgICByZXR1cm4gbHM7Cn0KCnZvaWQKRmNMYW5nU2V0RGVzdHJveSAoRmNMYW5nU2V0ICpscykKewogICAgaWYgKGxzLT5leHRyYSkKCUZjU3RyU2V0RGVzdHJveSAobHMtPmV4dHJhKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0xBTkdTRVQsIHNpemVvZiAoRmNMYW5nU2V0KSk7CiAgICBmcmVlIChscyk7Cn0KCkZjTGFuZ1NldCAqCkZjTGFuZ1NldENvcHkgKGNvbnN0IEZjTGFuZ1NldCAqbHMpCnsKICAgIEZjTGFuZ1NldAkqbmV3OwoKICAgIG5ldyA9IEZjTGFuZ1NldENyZWF0ZSAoKTsKICAgIGlmICghbmV3KQoJZ290byBiYWlsMDsKICAgIG1lbWNweSAobmV3LT5tYXAsIGxzLT5tYXAsIHNpemVvZiAobmV3LT5tYXApKTsKICAgIGlmIChscy0+ZXh0cmEpCiAgICB7CglGY1N0ckxpc3QJKmxpc3Q7CglGY0NoYXI4CQkqZXh0cmE7CgkKCW5ldy0+ZXh0cmEgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghbmV3LT5leHRyYSkKCSAgICBnb3RvIGJhaWwxOwoKCWxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CQoJaWYgKCFsaXN0KQoJICAgIGdvdG8gYmFpbDE7CgkKCXdoaWxlICgoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKCFGY1N0clNldEFkZCAobmV3LT5leHRyYSwgZXh0cmEpKQoJICAgIHsKCQlGY1N0ckxpc3REb25lIChsaXN0KTsKCQlnb3RvIGJhaWwxOwoJICAgIH0KCUZjU3RyTGlzdERvbmUgKGxpc3QpOwogICAgfQogICAgcmV0dXJuIG5ldzsKYmFpbDE6CiAgICBGY0xhbmdTZXREZXN0cm95IChuZXcpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CkZjTGFuZ1NldEluZGV4IChjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBpbnQJICAgIGxvdywgaGlnaCwgbWlkID0gMDsKICAgIGludAkgICAgY21wID0gMDsKICAgIEZjQ2hhcjggZmlyc3RDaGFyID0gRmNUb0xvd2VyKGxhbmdbMF0pOyAKICAgIEZjQ2hhcjggc2Vjb25kQ2hhciA9IGZpcnN0Q2hhciA/IEZjVG9Mb3dlcihsYW5nWzFdKSA6ICdcMCc7CiAgICAKICAgIGlmIChmaXJzdENoYXIgPCAnYScpCiAgICB7Cglsb3cgPSAwOwoJaGlnaCA9IGZjTGFuZ0NoYXJTZXRSYW5nZXNbMF0uYmVnaW47CiAgICB9CiAgICBlbHNlIGlmKGZpcnN0Q2hhciA+ICd6JykKICAgIHsKCWxvdyA9IGZjTGFuZ0NoYXJTZXRSYW5nZXNbMjVdLmJlZ2luOwoJaGlnaCA9IE5VTV9MQU5HX0NIQVJfU0VUIC0gMTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWxvdyA9IGZjTGFuZ0NoYXJTZXRSYW5nZXNbZmlyc3RDaGFyIC0gJ2EnXS5iZWdpbjsKCWhpZ2ggPSBmY0xhbmdDaGFyU2V0UmFuZ2VzW2ZpcnN0Q2hhciAtICdhJ10uZW5kOwoJLyogbm8gbWF0Y2hlcyAqLwoJaWYgKGxvdyA+IGhpZ2gpCgkgICAgcmV0dXJuIC1sb3c7IC8qIG5leHQgZW50cnkgYWZ0ZXIgd2hlcmUgaXQgd291bGQgYmUgKi8KICAgIH0KCiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAoaGlnaCArIGxvdykgPj4gMTsKCWlmKGZjTGFuZ0NoYXJTZXRzW21pZF0ubGFuZ1swXSAhPSBmaXJzdENoYXIpCgkgICAgY21wID0gRmNTdHJDbXBJZ25vcmVDYXNlKGZjTGFuZ0NoYXJTZXRzW21pZF0ubGFuZywgbGFuZyk7CgllbHNlCgl7ICAgLyogZmFzdCBwYXRoIGZvciByZXNvbHZpbmcgMi1sZXR0ZXIgbGFuZ3VhZ2VzIChieSBmYXIgdGhlIG1vc3QgY29tbW9uKSBhZnRlcgoJICAgICAqIGZpbmRpbmcgdGhlIGZpcnN0IGNoYXIgKHByb2JhYmx5IGFscmVhZHkgdHJ1ZSBiZWNhdXNlIG9mIHRoZSBoYXNoIHRhYmxlKSAqLwoJICAgIGNtcCA9IGZjTGFuZ0NoYXJTZXRzW21pZF0ubGFuZ1sxXSAtIHNlY29uZENoYXI7CgkgICAgaWYgKGNtcCA9PSAwICYmIAoJCShmY0xhbmdDaGFyU2V0c1ttaWRdLmxhbmdbMl0gIT0gJ1wwJyB8fCAKCQkgbGFuZ1syXSAhPSAnXDAnKSkKCSAgICB7CgkJY21wID0gRmNTdHJDbXBJZ25vcmVDYXNlKGZjTGFuZ0NoYXJTZXRzW21pZF0ubGFuZysyLCAKCQkJCQkgbGFuZysyKTsKCSAgICB9Cgl9CglpZiAoY21wID09IDApCgkgICAgcmV0dXJuIG1pZDsKCWlmIChjbXAgPCAwKQoJICAgIGxvdyA9IG1pZCArIDE7CgllbHNlCgkgICAgaGlnaCA9IG1pZCAtIDE7CiAgICB9CiAgICBpZiAoY21wIDwgMCkKCW1pZCsrOwogICAgcmV0dXJuIC0obWlkICsgMSk7Cn0KCkZjQm9vbApGY0xhbmdTZXRBZGQgKEZjTGFuZ1NldCAqbHMsIGNvbnN0IEZjQ2hhcjggKmxhbmcpCnsKICAgIGludAkgICAgaWQ7CgogICAgaWQgPSBGY0xhbmdTZXRJbmRleCAobGFuZyk7CiAgICBpZiAoaWQgPj0gMCkKICAgIHsKCUZjTGFuZ1NldEJpdFNldCAobHMsIGlkKTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICBpZiAoIWxzLT5leHRyYSkKICAgIHsKCWxzLT5leHRyYSA9IEZjU3RyU2V0Q3JlYXRlICgpOwoJaWYgKCFscy0+ZXh0cmEpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNTdHJTZXRBZGQgKGxzLT5leHRyYSwgbGFuZyk7Cn0KCkZjTGFuZ1Jlc3VsdApGY0xhbmdTZXRIYXNMYW5nIChjb25zdCBGY0xhbmdTZXQgKmxzLCBjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBpbnQJCSAgICBpZDsKICAgIEZjTGFuZ1Jlc3VsdCAgICBiZXN0LCByOwogICAgaW50CQkgICAgaTsKCiAgICBpZCA9IEZjTGFuZ1NldEluZGV4IChsYW5nKTsKICAgIGlmIChpZCA8IDApCglpZCA9IC1pZCAtIDE7CiAgICBlbHNlIGlmIChGY0xhbmdTZXRCaXRHZXQgKGxzLCBpZCkpCglyZXR1cm4gRmNMYW5nRXF1YWw7CiAgICBiZXN0ID0gRmNMYW5nRGlmZmVyZW50TGFuZzsKICAgIGZvciAoaSA9IGlkIC0gMTsgaSA+PSAwOyBpLS0pCiAgICB7CglyID0gRmNMYW5nQ29tcGFyZSAobGFuZywgZmNMYW5nQ2hhclNldHNbaV0ubGFuZyk7CglpZiAociA9PSBGY0xhbmdEaWZmZXJlbnRMYW5nKQoJICAgIGJyZWFrOwoJaWYgKEZjTGFuZ1NldEJpdEdldCAobHMsIGkpICYmIHIgPCBiZXN0KQoJICAgIGJlc3QgPSByOwogICAgfQogICAgZm9yIChpID0gaWQ7IGkgPCBOVU1fTEFOR19DSEFSX1NFVDsgaSsrKQogICAgewoJciA9IEZjTGFuZ0NvbXBhcmUgKGxhbmcsIGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcpOwoJaWYgKHIgPT0gRmNMYW5nRGlmZmVyZW50TGFuZykKCSAgICBicmVhazsKCWlmIChGY0xhbmdTZXRCaXRHZXQgKGxzLCBpKSAmJiByIDwgYmVzdCkKCSAgICBiZXN0ID0gcjsKICAgIH0KICAgIGlmIChscy0+ZXh0cmEpCiAgICB7CglGY1N0ckxpc3QJKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CglGY0NoYXI4CQkqZXh0cmE7CglGY0xhbmdSZXN1bHQJcjsKCQoJaWYgKGxpc3QpCgl7CgkgICAgd2hpbGUgKGJlc3QgPiBGY0xhbmdFcXVhbCAmJiAoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgewoJCXIgPSBGY0xhbmdDb21wYXJlIChsYW5nLCBleHRyYSk7CgkJaWYgKHIgPCBiZXN0KQoJCSAgICBiZXN0ID0gcjsKCSAgICB9CgkgICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7Cgl9CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQoKc3RhdGljIEZjTGFuZ1Jlc3VsdApGY0xhbmdTZXRDb21wYXJlU3RyU2V0IChjb25zdCBGY0xhbmdTZXQgKmxzLCBGY1N0clNldCAqc2V0KQp7CiAgICBGY1N0ckxpc3QJICAgICpsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzZXQpOwogICAgRmNMYW5nUmVzdWx0ICAgIHIsIGJlc3QgPSBGY0xhbmdEaWZmZXJlbnRMYW5nOwogICAgRmNDaGFyOAkgICAgKmV4dHJhOwoKICAgIGlmIChsaXN0KQogICAgewoJd2hpbGUgKGJlc3QgPiBGY0xhbmdFcXVhbCAmJiAoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgl7CgkgICAgciA9IEZjTGFuZ1NldEhhc0xhbmcgKGxzLCBleHRyYSk7CgkgICAgaWYgKHIgPCBiZXN0KQoJCWJlc3QgPSByOwoJfQoJRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQoKRmNMYW5nUmVzdWx0CkZjTGFuZ1NldENvbXBhcmUgKGNvbnN0IEZjTGFuZ1NldCAqbHNhLCBjb25zdCBGY0xhbmdTZXQgKmxzYikKewogICAgaW50CQkgICAgaSwgajsKICAgIEZjTGFuZ1Jlc3VsdCAgICBiZXN0LCByOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCglpZiAobHNhLT5tYXBbaV0gJiBsc2ItPm1hcFtpXSkKCSAgICByZXR1cm4gRmNMYW5nRXF1YWw7CiAgICBiZXN0ID0gRmNMYW5nRGlmZmVyZW50TGFuZzsKICAgIGZvciAoaiA9IDA7IGogPCBOVU1fQ09VTlRSWV9TRVQ7IGorKykKCWZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCgkgICAgaWYgKChsc2EtPm1hcFtpXSAmIGZjTGFuZ0NvdW50cnlTZXRzW2pdW2ldKSAmJgoJCShsc2ItPm1hcFtpXSAmIGZjTGFuZ0NvdW50cnlTZXRzW2pdW2ldKSkKCSAgICB7CgkJYmVzdCA9IEZjTGFuZ0RpZmZlcmVudENvdW50cnk7CgkJYnJlYWs7CgkgICAgfQogICAgaWYgKGxzYS0+ZXh0cmEpCiAgICB7CglyID0gRmNMYW5nU2V0Q29tcGFyZVN0clNldCAobHNiLCBsc2EtPmV4dHJhKTsKCWlmIChyIDwgYmVzdCkKCSAgICBiZXN0ID0gcjsKICAgIH0KICAgIGlmIChiZXN0ID4gRmNMYW5nRXF1YWwgJiYgbHNiLT5leHRyYSkKICAgIHsKCXIgPSBGY0xhbmdTZXRDb21wYXJlU3RyU2V0IChsc2EsIGxzYi0+ZXh0cmEpOwoJaWYgKHIgPCBiZXN0KQoJICAgIGJlc3QgPSByOwogICAgfQogICAgcmV0dXJuIGJlc3Q7Cn0KCi8qCiAqIFVzZWQgaW4gY29tcHV0aW5nIHZhbHVlcyAtLSBtdXN0bid0IGFsbG9jYXRlIGFueSBzdG9yYWdlCiAqLwpGY0xhbmdTZXQgKgpGY0xhbmdTZXRQcm9tb3RlIChjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBzdGF0aWMgRmNMYW5nU2V0CWxzOwogICAgc3RhdGljIEZjU3RyU2V0CXN0cnM7CiAgICBzdGF0aWMgRmNDaGFyOAkqc3RyOwogICAgaW50CQkJaWQ7CgogICAgbWVtc2V0IChscy5tYXAsICdcMCcsIHNpemVvZiAobHMubWFwKSk7CiAgICBscy5leHRyYSA9IDA7CiAgICBpZCA9IEZjTGFuZ1NldEluZGV4IChsYW5nKTsKICAgIGlmIChpZCA+IDApCiAgICB7CglGY0xhbmdTZXRCaXRTZXQgKCZscywgaWQpOwogICAgfQogICAgZWxzZQogICAgewoJbHMuZXh0cmEgPSAmc3RyczsKCXN0cnMubnVtID0gMTsKCXN0cnMuc2l6ZSA9IDE7CglzdHJzLnN0cnMgPSAmc3RyOwoJc3Rycy5yZWYgPSAxOwoJc3RyID0gKEZjQ2hhcjggKikgbGFuZzsKICAgIH0KICAgIHJldHVybiAmbHM7Cn0KCkZjQ2hhcjMyCkZjTGFuZ1NldEhhc2ggKGNvbnN0IEZjTGFuZ1NldCAqbHMpCnsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgaW50CQlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCgloIF49IGxzLT5tYXBbaV07CiAgICBpZiAobHMtPmV4dHJhKQoJaCBePSBscy0+ZXh0cmEtPm51bTsKICAgIHJldHVybiBoOwp9CgpGY0xhbmdTZXQgKgpGY05hbWVQYXJzZUxhbmdTZXQgKGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewogICAgRmNDaGFyOAkgICAgbGFuZ1szMl0sYzsKICAgIGludCBpOwogICAgRmNMYW5nU2V0CSAgICAqbHM7CgogICAgbHMgPSBGY0xhbmdTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWxzKQoJZ290byBiYWlsMDsKCiAgICBmb3IoOzspCiAgICB7Cglmb3IoaSA9IDA7IGkgPCAzMTtpKyspCgl7CgkgICAgYyA9ICpzdHJpbmcrKzsKCSAgICBpZihjID09ICdcMCcgfHwgYyA9PSAnfCcpCgkJYnJlYWs7IC8qIGVuZCBvZiB0aGlzIGNvZGUgKi8KCSAgICBsYW5nW2ldID0gYzsKCX0KCWxhbmdbaV0gPSAnXDAnOwoJaWYgKCFGY0xhbmdTZXRBZGQgKGxzLCBsYW5nKSkKCSAgICBnb3RvIGJhaWwxOwoJaWYoYyA9PSAnXDAnKQoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIGxzOwpiYWlsMToKICAgIEZjTGFuZ1NldERlc3Ryb3kgKGxzKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKRmNCb29sCkZjTmFtZVVucGFyc2VMYW5nU2V0IChGY1N0ckJ1ZiAqYnVmLCBjb25zdCBGY0xhbmdTZXQgKmxzKQp7CiAgICBpbnQJCWksIGJpdDsKICAgIEZjQ2hhcjMyCWJpdHM7CiAgICBGY0Jvb2wJZmlyc3QgPSBGY1RydWU7CgogICAgZm9yIChpID0gMDsgaSA8IE5VTV9MQU5HX1NFVF9NQVA7IGkrKykKICAgIHsKCWlmICgoYml0cyA9IGxzLT5tYXBbaV0pKQoJewoJICAgIGZvciAoYml0ID0gMDsgYml0IDw9IDMxOyBiaXQrKykKCQlpZiAoYml0cyAmICgxIDw8IGJpdCkpCgkJewoJCSAgICBpbnQgaWQgPSAoaSA8PCA1KSB8IGJpdDsKCQkgICAgaWYgKCFmaXJzdCkKCQkJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgJ3wnKSkKCQkJICAgIHJldHVybiBGY0ZhbHNlOwoJCSAgICBpZiAoIUZjU3RyQnVmU3RyaW5nIChidWYsIGZjTGFuZ0NoYXJTZXRzW2lkXS5sYW5nKSkKCQkJcmV0dXJuIEZjRmFsc2U7CgkJICAgIGZpcnN0ID0gRmNGYWxzZTsKCQl9Cgl9CiAgICB9CiAgICBpZiAobHMtPmV4dHJhKQogICAgewoJRmNTdHJMaXN0ICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CglGY0NoYXI4CSAgICAqZXh0cmE7CgoJaWYgKCFsaXN0KQoJICAgIHJldHVybiBGY0ZhbHNlOwoJd2hpbGUgKChleHRyYSA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKCXsKCSAgICBpZiAoIWZpcnN0KQoJCWlmICghRmNTdHJCdWZDaGFyIChidWYsICd8JykpCgkJICAgIHJldHVybiBGY0ZhbHNlOwoJICAgIGlmICghRmNTdHJCdWZTdHJpbmcgKGJ1ZiwgZXh0cmEpKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIGZpcnN0ID0gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0xhbmdTZXRFcXVhbCAoY29uc3QgRmNMYW5nU2V0ICpsc2EsIGNvbnN0IEZjTGFuZ1NldCAqbHNiKQp7CiAgICBpbnQJICAgIGk7CgogICAgZm9yIChpID0gMDsgaSA8IE5VTV9MQU5HX1NFVF9NQVA7IGkrKykKICAgIHsKCWlmIChsc2EtPm1hcFtpXSAhPSBsc2ItPm1hcFtpXSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmICghbHNhLT5leHRyYSAmJiAhbHNiLT5leHRyYSkKCXJldHVybiBGY1RydWU7CiAgICBpZiAobHNhLT5leHRyYSAmJiBsc2ItPmV4dHJhKQoJcmV0dXJuIEZjU3RyU2V0RXF1YWwgKGxzYS0+ZXh0cmEsIGxzYi0+ZXh0cmEpOwogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNMYW5nU2V0Q29udGFpbnNMYW5nIChjb25zdCBGY0xhbmdTZXQgKmxzLCBjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBpbnQJCSAgICBpZDsKICAgIGludAkJICAgIGk7CgogICAgaWQgPSBGY0xhbmdTZXRJbmRleCAobGFuZyk7CiAgICBpZiAoaWQgPCAwKQoJaWQgPSAtaWQgLSAxOwogICAgZWxzZSBpZiAoRmNMYW5nU2V0Qml0R2V0IChscywgaWQpKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIC8qCiAgICAgKiBzZWFyY2ggdXAgYW5kIGRvd24gYW1vbmcgZXF1YWwgbGFuZ3VhZ2VzIGZvciBhIG1hdGNoCiAgICAgKi8KICAgIGZvciAoaSA9IGlkIC0gMTsgaSA+PSAwOyBpLS0pCiAgICB7CglpZiAoRmNMYW5nQ29tcGFyZSAoZmNMYW5nQ2hhclNldHNbaV0ubGFuZywgbGFuZykgPT0gRmNMYW5nRGlmZmVyZW50TGFuZykKCSAgICBicmVhazsKCWlmIChGY0xhbmdTZXRCaXRHZXQgKGxzLCBpKSAmJgoJICAgIEZjTGFuZ0NvbnRhaW5zIChmY0xhbmdDaGFyU2V0c1tpXS5sYW5nLCBsYW5nKSkKCSAgICByZXR1cm4gRmNUcnVlOwogICAgfQogICAgZm9yIChpID0gaWQ7IGkgPCBOVU1fTEFOR19DSEFSX1NFVDsgaSsrKQogICAgewoJaWYgKEZjTGFuZ0NvbXBhcmUgKGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcsIGxhbmcpID09IEZjTGFuZ0RpZmZlcmVudExhbmcpCgkgICAgYnJlYWs7CglpZiAoRmNMYW5nU2V0Qml0R2V0IChscywgaSkgJiYKCSAgICBGY0xhbmdDb250YWlucyAoZmNMYW5nQ2hhclNldHNbaV0ubGFuZywgbGFuZykpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChscy0+ZXh0cmEpCiAgICB7CglGY1N0ckxpc3QJKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CglGY0NoYXI4CQkqZXh0cmE7CgkKCWlmIChsaXN0KQoJewoJICAgIHdoaWxlICgoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgewoJCWlmIChGY0xhbmdDb250YWlucyAoZXh0cmEsIGxhbmcpKQoJCSAgICBicmVhazsKCSAgICB9CgkgICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICAJICAgIGlmIChleHRyYSkKCQlyZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCi8qCiAqIHJldHVybiBGY1RydWUgaWYgbHNhIGNvbnRhaW5zIGV2ZXJ5IGxhbmd1YWdlIGluIGxzYgogKi8KRmNCb29sCkZjTGFuZ1NldENvbnRhaW5zIChjb25zdCBGY0xhbmdTZXQgKmxzYSwgY29uc3QgRmNMYW5nU2V0ICpsc2IpCnsKICAgIGludAkJICAgIGksIGo7CiAgICBGY0NoYXIzMgkgICAgbWlzc2luZzsKCiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX01BVENIVikKICAgIHsKCXByaW50ZiAoIkZjTGFuZ1NldCAiKTsgRmNMYW5nU2V0UHJpbnQgKGxzYSk7CglwcmludGYgKCIgY29udGFpbnMgIik7IEZjTGFuZ1NldFByaW50IChsc2IpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIC8qCiAgICAgKiBjaGVjayBiaXRtYXBzIGZvciBtaXNzaW5nIGxhbmd1YWdlIHN1cHBvcnQKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IE5VTV9MQU5HX1NFVF9NQVA7IGkrKykKICAgIHsKCW1pc3NpbmcgPSBsc2ItPm1hcFtpXSAmIH5sc2EtPm1hcFtpXTsKCWlmIChtaXNzaW5nKQoJewoJICAgIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKQoJCWlmIChtaXNzaW5nICYgKDEgPDwgaikpIAoJCXsKCQkgICAgaWYgKCFGY0xhbmdTZXRDb250YWluc0xhbmcgKGxzYSwKCQkJCQkJZmNMYW5nQ2hhclNldHNbaSozMiArIGpdLmxhbmcpKQoJCSAgICB7CgkJCWlmIChGY0RlYnVnKCkgJiBGQ19EQkdfTUFUQ0hWKQoJCQkgICAgcHJpbnRmICgiXHRNaXNzaW5nIGJpdG1hcCAlc1xuIiwgZmNMYW5nQ2hhclNldHNbaSozMitqXS5sYW5nKTsKCQkJcmV0dXJuIEZjRmFsc2U7CgkJICAgIH0KCQl9Cgl9CiAgICB9CiAgICBpZiAobHNiLT5leHRyYSkKICAgIHsKCUZjU3RyTGlzdCAgICpsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChsc2ItPmV4dHJhKTsKCUZjQ2hhcjgJICAgICpleHRyYTsKCglpZiAobGlzdCkKCXsKCSAgICB3aGlsZSAoKGV4dHJhID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQoJICAgIHsKCQlpZiAoIUZjTGFuZ1NldENvbnRhaW5zTGFuZyAobHNhLCBleHRyYSkpCgkJewoJCSAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX01BVENIVikKCQkJcHJpbnRmICgiXHRNaXNzaW5nIHN0cmluZyAlc1xuIiwgZXh0cmEpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwoJICAgIGlmIChleHRyYSkKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0K