LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY3BhdC5jLHYgMS4xMCAyMDAyLzA2LzI5IDIwOjMxOjAyIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgImZjaW50LmgiCgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5DcmVhdGUgKHZvaWQpCnsKICAgIEZjUGF0dGVybgkqcDsKCiAgICBwID0gKEZjUGF0dGVybiAqKSBtYWxsb2MgKHNpemVvZiAoRmNQYXR0ZXJuKSk7CiAgICBpZiAoIXApCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRURVJOLCBzaXplb2YgKEZjUGF0dGVybikpOwogICAgcC0+bnVtID0gMDsKICAgIHAtPnNpemUgPSAwOwogICAgcC0+ZWx0cyA9IDA7CiAgICBwLT5yZWYgPSAxOwogICAgcmV0dXJuIHA7Cn0KCnZvaWQKRmNWYWx1ZURlc3Ryb3kgKEZjVmFsdWUgdikKewogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSB2LnUucyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJRmNNYXRyaXhGcmVlICgoRmNNYXRyaXggKikgdi51Lm0pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQp9CgpGY1ZhbHVlCkZjVmFsdWVTYXZlIChGY1ZhbHVlIHYpCnsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXYudS5zID0gRmNTdHJDb3B5ICh2LnUucyk7CglpZiAoIXYudS5zKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJdi51Lm0gPSBGY01hdHJpeENvcHkgKHYudS5tKTsKCWlmICghdi51Lm0pCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJdi51LmMgPSBGY0NoYXJTZXRDb3B5ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWlmICghdi51LmMpCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnZvaWQKRmNWYWx1ZUxpc3REZXN0cm95IChGY1ZhbHVlTGlzdCAqbCkKewogICAgRmNWYWx1ZUxpc3QgICAgKm5leHQ7CiAgICBmb3IgKDsgbDsgbCA9IG5leHQpCiAgICB7Cglzd2l0Y2ggKGwtPnZhbHVlLnR5cGUpIHsKCWNhc2UgRmNUeXBlU3RyaW5nOgoJICAgIEZjU3RyRnJlZSAoKEZjQ2hhcjggKikgbC0+dmFsdWUudS5zKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTWF0cml4OgoJICAgIEZjTWF0cml4RnJlZSAoKEZjTWF0cml4ICopIGwtPnZhbHVlLnUubSk7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUNoYXJTZXQ6CgkgICAgRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSBsLT52YWx1ZS51LmMpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KCW5leHQgPSBsLT5uZXh0OwoJRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwoJZnJlZSAobCk7CiAgICB9Cn0KCkZjQm9vbApGY1ZhbHVlRXF1YWwgKEZjVmFsdWUgdmEsIEZjVmFsdWUgdmIpCnsKICAgIGlmICh2YS50eXBlICE9IHZiLnR5cGUpCiAgICB7CglpZiAodmEudHlwZSA9PSBGY1R5cGVJbnRlZ2VyKQoJewoJICAgIHZhLnR5cGUgPSBGY1R5cGVEb3VibGU7CgkgICAgdmEudS5kID0gdmEudS5pOwoJfQoJaWYgKHZiLnR5cGUgPT0gRmNUeXBlSW50ZWdlcikKCXsKCSAgICB2Yi50eXBlID0gRmNUeXBlRG91YmxlOwoJICAgIHZiLnUuZCA9IHZiLnUuaTsKCX0KCWlmICh2YS50eXBlICE9IHZiLnR5cGUpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBzd2l0Y2ggKHZhLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlVm9pZDoKCXJldHVybiBGY1RydWU7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglyZXR1cm4gdmEudS5pID09IHZiLnUuaTsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJcmV0dXJuIHZhLnUuZCA9PSB2Yi51LmQ7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXJldHVybiBGY1N0ckNtcElnbm9yZUNhc2UgKHZhLnUucywgdmIudS5zKSA9PSAwOwogICAgY2FzZSBGY1R5cGVCb29sOgoJcmV0dXJuIHZhLnUuYiA9PSB2Yi51LmI7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXJldHVybiBGY01hdHJpeEVxdWFsICh2YS51Lm0sIHZiLnUubSk7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglyZXR1cm4gRmNDaGFyU2V0RXF1YWwgKHZhLnUuYywgdmIudS5jKTsKICAgIGNhc2UgRmNUeXBlRlRGYWNlOgoJcmV0dXJuIHZhLnUuZiA9PSB2Yi51LmY7CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjRG91YmxlSGFzaCAoZG91YmxlIGQpCnsKICAgIGlmIChkIDwgMCkKCWQgPSAtZDsKICAgIGlmIChkID4gMHhmZmZmZmZmZikKCWQgPSAweGZmZmZmZmZmOwogICAgcmV0dXJuIChGY0NoYXIzMikgZDsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjU3RyaW5nSGFzaCAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOAljOwogICAgRmNDaGFyMzIJaCA9IDA7CiAgICAKICAgIGlmIChzKQoJd2hpbGUgKChjID0gKnMrKykpCgkgICAgaCA9ICgoaCA8PCAxKSB8IChoID4+IDMxKSkgXiBjOwogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY1ZhbHVlSGFzaCAoRmNWYWx1ZSB2KQp7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVWb2lkOgoJcmV0dXJuIDA7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglyZXR1cm4gKEZjQ2hhcjMyKSB2LnUuaTsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJcmV0dXJuIEZjRG91YmxlSGFzaCAodi51LmQpOwogICAgY2FzZSBGY1R5cGVTdHJpbmc6CglyZXR1cm4gRmNTdHJpbmdIYXNoICh2LnUucyk7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglyZXR1cm4gKEZjQ2hhcjMyKSB2LnUuYjsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJcmV0dXJuIChGY0RvdWJsZUhhc2ggKHYudS5tLT54eCkgXiAKCQlGY0RvdWJsZUhhc2ggKHYudS5tLT54eSkgXiAKCQlGY0RvdWJsZUhhc2ggKHYudS5tLT55eCkgXiAKCQlGY0RvdWJsZUhhc2ggKHYudS5tLT55eSkpOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJcmV0dXJuIChGY0NoYXIzMikgdi51LmMtPm51bTsKICAgIGNhc2UgRmNUeXBlRlRGYWNlOgoJcmV0dXJuIEZjU3RyaW5nSGFzaCAoKGNvbnN0IEZjQ2hhcjggKikgKChGVF9GYWNlKSB2LnUuZiktPmZhbWlseV9uYW1lKSBeCgkgICAgICAgRmNTdHJpbmdIYXNoICgoY29uc3QgRmNDaGFyOCAqKSAoKEZUX0ZhY2UpIHYudS5mKS0+c3R5bGVfbmFtZSk7CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjQm9vbApGY1ZhbHVlTGlzdEVxdWFsIChGY1ZhbHVlTGlzdCAqbGEsIEZjVmFsdWVMaXN0ICpsYikKewogICAgd2hpbGUgKGxhICYmIGxiKQogICAgewoJaWYgKCFGY1ZhbHVlRXF1YWwgKGxhLT52YWx1ZSwgbGItPnZhbHVlKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKCWxhID0gbGEtPm5leHQ7CglsYiA9IGxiLT5uZXh0OwogICAgfQogICAgaWYgKGxhIHx8IGxiKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNWYWx1ZUxpc3RIYXNoIChGY1ZhbHVlTGlzdCAqbCkKewogICAgRmNDaGFyMzIJaGFzaCA9IDA7CiAgICAKICAgIHdoaWxlIChsKQogICAgewoJaGFzaCA9ICgoaGFzaCA8PCAxKSB8IChoYXNoID4+IDMxKSkgXiBGY1ZhbHVlSGFzaCAobC0+dmFsdWUpOwoJbCA9IGwtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gaGFzaDsKfQoKdm9pZApGY1BhdHRlcm5EZXN0cm95IChGY1BhdHRlcm4gKnApCnsKICAgIGludAkJICAgIGk7CiAgICAKICAgIGlmICgtLXAtPnJlZiA+IDApCglyZXR1cm47CgogICAgZm9yIChpID0gMDsgaSA8IHAtPm51bTsgaSsrKQoJRmNWYWx1ZUxpc3REZXN0cm95IChwLT5lbHRzW2ldLnZhbHVlcyk7CgogICAgcC0+bnVtID0gMDsKICAgIGlmIChwLT5lbHRzKQogICAgewoJRmNNZW1GcmVlIChGQ19NRU1fUEFURUxULCBwLT5zaXplICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCWZyZWUgKHAtPmVsdHMpOwoJcC0+ZWx0cyA9IDA7CiAgICB9CiAgICBwLT5zaXplID0gMDsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1BBVFRFUk4sIHNpemVvZiAoRmNQYXR0ZXJuKSk7CiAgICBmcmVlIChwKTsKfQoKc3RhdGljIGludApGY1BhdHRlcm5Qb3NpdGlvbiAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIGludAkgICAgbG93LCBoaWdoLCBtaWQsIGM7CgogICAgbG93ID0gMDsKICAgIGhpZ2ggPSBwLT5udW0gLSAxOwogICAgYyA9IDE7CiAgICBtaWQgPSAwOwogICAgd2hpbGUgKGxvdyA8PSBoaWdoKQogICAgewoJbWlkID0gKGxvdyArIGhpZ2gpID4+IDE7CgljID0gc3RyY21wIChwLT5lbHRzW21pZF0ub2JqZWN0LCBvYmplY3QpOwoJaWYgKGMgPT0gMCkKCSAgICByZXR1cm4gbWlkOwoJaWYgKGMgPCAwKQoJICAgIGxvdyA9IG1pZCArIDE7CgllbHNlCgkgICAgaGlnaCA9IG1pZCAtIDE7CiAgICB9CiAgICBpZiAoYyA8IDApCgltaWQrKzsKICAgIHJldHVybiAtKG1pZCArIDEpOwp9CgpGY1BhdHRlcm5FbHQgKgpGY1BhdHRlcm5GaW5kRWx0IChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CSAgICBpID0gRmNQYXR0ZXJuUG9zaXRpb24gKHAsIG9iamVjdCk7CiAgICBpZiAoaSA8IDApCglyZXR1cm4gMDsKICAgIHJldHVybiAmcC0+ZWx0c1tpXTsKfQoKRmNQYXR0ZXJuRWx0ICoKRmNQYXR0ZXJuSW5zZXJ0RWx0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQkgICAgaTsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgCiAgICBpID0gRmNQYXR0ZXJuUG9zaXRpb24gKHAsIG9iamVjdCk7CiAgICBpZiAoaSA8IDApCiAgICB7CglpID0gLWkgLSAxOwogICAgCgkvKiBncm93IGFycmF5ICovCglpZiAocC0+bnVtICsgMSA+PSBwLT5zaXplKQoJewoJICAgIGludCBzID0gcC0+c2l6ZSArIDE2OwoJICAgIGlmIChwLT5lbHRzKQoJCWUgPSAoRmNQYXR0ZXJuRWx0ICopIHJlYWxsb2MgKHAtPmVsdHMsIHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIGVsc2UKCQllID0gKEZjUGF0dGVybkVsdCAqKSBtYWxsb2MgKHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIGlmICghZSkKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBwLT5lbHRzID0gZTsKCSAgICBpZiAocC0+c2l6ZSkKCQlGY01lbUZyZWUgKEZDX01FTV9QQVRFTFQsIHAtPnNpemUgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRFTFQsIHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIHdoaWxlIChwLT5zaXplIDwgcykKCSAgICB7CgkJcC0+ZWx0c1twLT5zaXplXS5vYmplY3QgPSAwOwoJCXAtPmVsdHNbcC0+c2l6ZV0udmFsdWVzID0gMDsKCQlwLT5zaXplKys7CgkgICAgfQoJfQoJCgkvKiBtb3ZlIGVsdHMgdXAgKi8KCW1lbW1vdmUgKHAtPmVsdHMgKyBpICsgMSwKCQkgcC0+ZWx0cyArIGksCgkJIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSAqCgkJIChwLT5udW0gLSBpKSk7CgkJIAoJLyogYnVtcCBjb3VudCAqLwoJcC0+bnVtKys7CgkKCXAtPmVsdHNbaV0ub2JqZWN0ID0gb2JqZWN0OwoJcC0+ZWx0c1tpXS52YWx1ZXMgPSAwOwogICAgfQogICAgCiAgICByZXR1cm4gJnAtPmVsdHNbaV07Cn0KCkZjQm9vbApGY1BhdHRlcm5FcXVhbCAoY29uc3QgRmNQYXR0ZXJuICpwYSwgY29uc3QgRmNQYXR0ZXJuICpwYikKewogICAgaW50CWk7CgogICAgaWYgKHBhLT5udW0gIT0gcGItPm51bSkKCXJldHVybiBGY0ZhbHNlOwogICAgZm9yIChpID0gMDsgaSA8IHBhLT5udW07IGkrKykKICAgIHsKCWlmIChzdHJjbXAgKHBhLT5lbHRzW2ldLm9iamVjdCwgcGItPmVsdHNbaV0ub2JqZWN0KSAhPSAwKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY1ZhbHVlTGlzdEVxdWFsIChwYS0+ZWx0c1tpXS52YWx1ZXMsIHBiLT5lbHRzW2ldLnZhbHVlcykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0NoYXIzMgpGY1BhdHRlcm5IYXNoIChjb25zdCBGY1BhdHRlcm4gKnApCnsKICAgIGludAkJaTsKICAgIEZjQ2hhcjMyCWggPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBwLT5udW07IGkrKykKICAgIHsKCWggPSAoKChoIDw8IDEpIHwgKGggPj4gMzEpKSBeIAoJICAgICBGY1N0cmluZ0hhc2ggKChjb25zdCBGY0NoYXI4ICopIHAtPmVsdHNbaV0ub2JqZWN0KSBeCgkgICAgIEZjVmFsdWVMaXN0SGFzaCAocC0+ZWx0c1tpXS52YWx1ZXMpKTsKICAgIH0KICAgIHJldHVybiBoOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuRXF1YWxTdWJzZXQgKGNvbnN0IEZjUGF0dGVybiAqcGEsIGNvbnN0IEZjUGF0dGVybiAqcGIsIGNvbnN0IEZjT2JqZWN0U2V0ICpvcykKewogICAgRmNQYXR0ZXJuRWx0ICAgICplYSwgKmViOwogICAgaW50CQkgICAgaTsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IG9zLT5ub2JqZWN0OyBpKyspCiAgICB7CgllYSA9IEZjUGF0dGVybkZpbmRFbHQgKHBhLCBvcy0+b2JqZWN0c1tpXSk7CgllYiA9IEZjUGF0dGVybkZpbmRFbHQgKHBiLCBvcy0+b2JqZWN0c1tpXSk7CglpZiAoZWEpCgl7CgkgICAgaWYgKCFlYikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBpZiAoIUZjVmFsdWVMaXN0RXF1YWwgKGVhLT52YWx1ZXMsIGViLT52YWx1ZXMpKQoJCXJldHVybiBGY0ZhbHNlOwoJfQoJZWxzZQoJewoJICAgIGlmIChlYikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRXaXRoQmluZGluZyAgKEZjUGF0dGVybgkgICAgKnAsCgkJCSAgY29uc3QgY2hhcgkgICAgKm9iamVjdCwKCQkJICBGY1ZhbHVlCSAgICB2YWx1ZSwKCQkJICBGY1ZhbHVlQmluZGluZyAgICBiaW5kaW5nLAoJCQkgIEZjQm9vbAkgICAgYXBwZW5kKQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpuZXcsICoqcHJldjsKCiAgICBuZXcgPSAoRmNWYWx1ZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIC8qIGR1cCBzdHJpbmcgKi8KICAgIHZhbHVlID0gRmNWYWx1ZVNhdmUgKHZhbHVlKTsKICAgIGlmICh2YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCglnb3RvIGJhaWwxOwoKICAgIG5ldy0+dmFsdWUgPSB2YWx1ZTsKICAgIG5ldy0+YmluZGluZyA9IGJpbmRpbmc7CiAgICBuZXctPm5leHQgPSAwOwogICAgCiAgICBlID0gRmNQYXR0ZXJuSW5zZXJ0RWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJZ290byBiYWlsMjsKICAgIAogICAgaWYgKGFwcGVuZCkKICAgIHsKCWZvciAocHJldiA9ICZlLT52YWx1ZXM7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpOwoJKnByZXYgPSBuZXc7CiAgICB9CiAgICBlbHNlCiAgICB7CgluZXctPm5leHQgPSBlLT52YWx1ZXM7CgllLT52YWx1ZXMgPSBuZXc7CiAgICB9CiAgICAKICAgIHJldHVybiBGY1RydWU7CgpiYWlsMjogICAgCiAgICBzd2l0Y2ggKHZhbHVlLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSB2YWx1ZS51LnMpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCUZjTWF0cml4RnJlZSAoKEZjTWF0cml4ICopIHZhbHVlLnUubSk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCUZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgdmFsdWUudS5jKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQpiYWlsMToKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGZyZWUgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nU3Ryb25nLCBhcHBlbmQpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkV2VhayAgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nV2VhaywgYXBwZW5kKTsKfQoKRmNCb29sCkZjUGF0dGVybkRlbCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgaW50CQkgICAgaTsKCiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybiBGY0ZhbHNlOwoKICAgIGkgPSBlIC0gcC0+ZWx0czsKICAgIAogICAgLyogZGVzdHJveSB2YWx1ZSAqLwogICAgRmNWYWx1ZUxpc3REZXN0cm95IChlLT52YWx1ZXMpOwogICAgCiAgICAvKiBzaHVmZmxlIGV4aXN0aW5nIG9uZXMgZG93biAqLwogICAgbWVtbW92ZSAoZSwgZSsxLCAocC0+ZWx0cyArIHAtPm51bSAtIChlICsgMSkpICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKICAgIHAtPm51bS0tOwogICAgcC0+ZWx0c1twLT5udW1dLm9iamVjdCA9IDA7CiAgICBwLT5lbHRzW3AtPm51bV0udmFsdWVzID0gMDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRJbnRlZ2VyIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGkpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwogICAgdi51LmkgPSBpOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkRG91YmxlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgZG91YmxlIGQpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CiAgICB2LnUuZCA9IGQ7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCgpGY0Jvb2wKRmNQYXR0ZXJuQWRkU3RyaW5nIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZVN0cmluZzsKICAgIHYudS5zID0gczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZE1hdHJpeCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjTWF0cml4ICpzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgdi51Lm0gPSAoRmNNYXRyaXggKikgczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKCkZjQm9vbApGY1BhdHRlcm5BZGRCb29sIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgRmNCb29sIGIpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwogICAgdi51LmIgPSBiOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkQ2hhclNldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjQ2hhclNldCAqYykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7CiAgICB2LnUuYyA9IChGY0NoYXJTZXQgKikgYzsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZEZURmFjZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZUX0ZhY2UgZikKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUZURmFjZTsKICAgIHYudS5mID0gKHZvaWQgKikgZjsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY1ZhbHVlICp2KQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpsOwoKICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJcmV0dXJuIEZjUmVzdWx0Tm9NYXRjaDsKICAgIGZvciAobCA9IGUtPnZhbHVlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7CglpZiAoIWlkKQoJewoJICAgICp2ID0gbC0+dmFsdWU7CgkgICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cgl9CglpZC0tOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0Tm9JZDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0SW50ZWdlciAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgaW50ICppKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSppID0gKGludCkgdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSppID0gdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldERvdWJsZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgZG91YmxlICpkKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSpkID0gdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSpkID0gKGRvdWJsZSkgdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldFN0cmluZyAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNDaGFyOCAqKiBzKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlU3RyaW5nKQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpzID0gKEZjQ2hhcjggKikgdi51LnM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0TWF0cml4IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY01hdHJpeCAqKm0pCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVNYXRyaXgpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKm0gPSAoRmNNYXRyaXggKikgdi51Lm07CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKCkZjUmVzdWx0CkZjUGF0dGVybkdldEJvb2wgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjQm9vbCAqYikKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUJvb2wpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKmIgPSB2LnUuYjsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRDaGFyU2V0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0NoYXJTZXQgKipjKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlQ2hhclNldCkKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqYyA9IChGY0NoYXJTZXQgKikgdi51LmM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0RlRGYWNlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGVF9GYWNlICpmKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlRlRGYWNlKQoJcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKmYgPSAoRlRfRmFjZSkgdi51LmY7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuRHVwbGljYXRlIChGY1BhdHRlcm4gKm9yaWcpCnsKICAgIEZjUGF0dGVybgkgICAgKm5ldzsKICAgIGludAkJICAgIGk7CiAgICBGY1ZhbHVlTGlzdCAgICAqbDsKCiAgICBuZXcgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgZm9yIChpID0gMDsgaSA8IG9yaWctPm51bTsgaSsrKQogICAgewoJZm9yIChsID0gb3JpZy0+ZWx0c1tpXS52YWx1ZXM7IGw7IGwgPSBsLT5uZXh0KQoJICAgIGlmICghRmNQYXR0ZXJuQWRkIChuZXcsIG9yaWctPmVsdHNbaV0ub2JqZWN0LCBsLT52YWx1ZSwgRmNUcnVlKSkKCQlnb3RvIGJhaWwxOwogICAgfQoKICAgIHJldHVybiBuZXc7CgpiYWlsMToKICAgIEZjUGF0dGVybkRlc3Ryb3kgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCnZvaWQKRmNQYXR0ZXJuUmVmZXJlbmNlIChGY1BhdHRlcm4gKnApCnsKICAgIHAtPnJlZisrOwp9CgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5WYUJ1aWxkIChGY1BhdHRlcm4gKm9yaWcsIHZhX2xpc3QgdmEpCnsKICAgIEZjUGF0dGVybgkqcmV0OwogICAgCiAgICBGY1BhdHRlcm5WYXBCdWlsZCAocmV0LCBvcmlnLCB2YSk7CiAgICByZXR1cm4gcmV0Owp9CgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5CdWlsZCAoRmNQYXR0ZXJuICpvcmlnLCAuLi4pCnsKICAgIHZhX2xpc3QJdmE7CiAgICAKICAgIHZhX3N0YXJ0ICh2YSwgb3JpZyk7CiAgICBGY1BhdHRlcm5WYXBCdWlsZCAob3JpZywgb3JpZywgdmEpOwogICAgdmFfZW5kICh2YSk7CiAgICByZXR1cm4gb3JpZzsKfQo=