LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY3BhdC5jLHYgMS4xMiAyMDAyLzA4LzA3IDAxOjQ1OjU5IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgImZjaW50LmgiCgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5DcmVhdGUgKHZvaWQpCnsKICAgIEZjUGF0dGVybgkqcDsKCiAgICBwID0gKEZjUGF0dGVybiAqKSBtYWxsb2MgKHNpemVvZiAoRmNQYXR0ZXJuKSk7CiAgICBpZiAoIXApCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRURVJOLCBzaXplb2YgKEZjUGF0dGVybikpOwogICAgcC0+bnVtID0gMDsKICAgIHAtPnNpemUgPSAwOwogICAgcC0+ZWx0cyA9IDA7CiAgICBwLT5yZWYgPSAxOwogICAgcmV0dXJuIHA7Cn0KCnZvaWQKRmNWYWx1ZURlc3Ryb3kgKEZjVmFsdWUgdikKewogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSB2LnUucyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJRmNNYXRyaXhGcmVlICgoRmNNYXRyaXggKikgdi51Lm0pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVQYXR0ZXJuOgoJRmNQYXR0ZXJuRGVzdHJveSAoKEZjUGF0dGVybiAqKSB2LnUucCk7CglicmVhazsKICAgIGRlZmF1bHQ6CglicmVhazsKICAgIH0KfQoKRmNWYWx1ZQpGY1ZhbHVlU2F2ZSAoRmNWYWx1ZSB2KQp7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVTdHJpbmc6Cgl2LnUucyA9IEZjU3RyQ29weSAodi51LnMpOwoJaWYgKCF2LnUucykKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXYudS5tID0gRmNNYXRyaXhDb3B5ICh2LnUubSk7CglpZiAoIXYudS5tKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXYudS5jID0gRmNDaGFyU2V0Q29weSAoKEZjQ2hhclNldCAqKSB2LnUuYyk7CglpZiAoIXYudS5jKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlUGF0dGVybjoKCUZjUGF0dGVyblJlZmVyZW5jZSAoKEZjUGF0dGVybiAqKSB2LnUucCk7CglicmVhazsKICAgIGRlZmF1bHQ6CglicmVhazsKICAgIH0KICAgIHJldHVybiB2Owp9Cgp2b2lkCkZjVmFsdWVMaXN0RGVzdHJveSAoRmNWYWx1ZUxpc3QgKmwpCnsKICAgIEZjVmFsdWVMaXN0ICAgICpuZXh0OwogICAgZm9yICg7IGw7IGwgPSBuZXh0KQogICAgewoJc3dpdGNoIChsLT52YWx1ZS50eXBlKSB7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBGY1N0ckZyZWUgKChGY0NoYXI4ICopIGwtPnZhbHVlLnUucyk7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZU1hdHJpeDoKCSAgICBGY01hdHJpeEZyZWUgKChGY01hdHJpeCAqKSBsLT52YWx1ZS51Lm0pOwoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVDaGFyU2V0OgoJICAgIEZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgbC0+dmFsdWUudS5jKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlUGF0dGVybjoKCSAgICBGY1BhdHRlcm5EZXN0cm95ICgoRmNQYXR0ZXJuICopIGwtPnZhbHVlLnUucCk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGJyZWFrOwoJfQoJbmV4dCA9IGwtPm5leHQ7CglGY01lbUZyZWUgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CglmcmVlIChsKTsKICAgIH0KfQoKRmNCb29sCkZjVmFsdWVFcXVhbCAoRmNWYWx1ZSB2YSwgRmNWYWx1ZSB2YikKewogICAgaWYgKHZhLnR5cGUgIT0gdmIudHlwZSkKICAgIHsKCWlmICh2YS50eXBlID09IEZjVHlwZUludGVnZXIpCgl7CgkgICAgdmEudHlwZSA9IEZjVHlwZURvdWJsZTsKCSAgICB2YS51LmQgPSB2YS51Lmk7Cgl9CglpZiAodmIudHlwZSA9PSBGY1R5cGVJbnRlZ2VyKQoJewoJICAgIHZiLnR5cGUgPSBGY1R5cGVEb3VibGU7CgkgICAgdmIudS5kID0gdmIudS5pOwoJfQoJaWYgKHZhLnR5cGUgIT0gdmIudHlwZSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN3aXRjaCAodmEudHlwZSkgewogICAgY2FzZSBGY1R5cGVWb2lkOgoJcmV0dXJuIEZjVHJ1ZTsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXJldHVybiB2YS51LmkgPT0gdmIudS5pOwogICAgY2FzZSBGY1R5cGVEb3VibGU6CglyZXR1cm4gdmEudS5kID09IHZiLnUuZDsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjU3RyQ21wSWdub3JlQ2FzZSAodmEudS5zLCB2Yi51LnMpID09IDA7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglyZXR1cm4gdmEudS5iID09IHZiLnUuYjsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJcmV0dXJuIEZjTWF0cml4RXF1YWwgKHZhLnUubSwgdmIudS5tKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiBGY0NoYXJTZXRFcXVhbCAodmEudS5jLCB2Yi51LmMpOwogICAgY2FzZSBGY1R5cGVGVEZhY2U6CglyZXR1cm4gdmEudS5mID09IHZiLnUuZjsKICAgIGNhc2UgRmNUeXBlUGF0dGVybjoKCXJldHVybiBGY1BhdHRlcm5FcXVhbCAodmEudS5wLCB2Yi51LnApOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0RvdWJsZUhhc2ggKGRvdWJsZSBkKQp7CiAgICBpZiAoZCA8IDApCglkID0gLWQ7CiAgICBpZiAoZCA+IDB4ZmZmZmZmZmYpCglkID0gMHhmZmZmZmZmZjsKICAgIHJldHVybiAoRmNDaGFyMzIpIGQ7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY1N0cmluZ0hhc2ggKGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjgJYzsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgCiAgICBpZiAocykKCXdoaWxlICgoYyA9ICpzKyspKQoJICAgIGggPSAoKGggPDwgMSkgfCAoaCA+PiAzMSkpIF4gYzsKICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNWYWx1ZUhhc2ggKEZjVmFsdWUgdikKewogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlVm9pZDoKCXJldHVybiAwOwogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJcmV0dXJuIChGY0NoYXIzMikgdi51Lmk7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCXJldHVybiBGY0RvdWJsZUhhc2ggKHYudS5kKTsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjU3RyaW5nSGFzaCAodi51LnMpOwogICAgY2FzZSBGY1R5cGVCb29sOgoJcmV0dXJuIChGY0NoYXIzMikgdi51LmI7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXJldHVybiAoRmNEb3VibGVIYXNoICh2LnUubS0+eHgpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eHkpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eXgpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eXkpKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5jLT5udW07CiAgICBjYXNlIEZjVHlwZUZURmFjZToKCXJldHVybiBGY1N0cmluZ0hhc2ggKChjb25zdCBGY0NoYXI4ICopICgoRlRfRmFjZSkgdi51LmYpLT5mYW1pbHlfbmFtZSkgXgoJICAgICAgIEZjU3RyaW5nSGFzaCAoKGNvbnN0IEZjQ2hhcjggKikgKChGVF9GYWNlKSB2LnUuZiktPnN0eWxlX25hbWUpOwogICAgY2FzZSBGY1R5cGVQYXR0ZXJuOgoJcmV0dXJuIChGY0NoYXIzMikgdi51LnAtPm51bTsKICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjVmFsdWVMaXN0RXF1YWwgKEZjVmFsdWVMaXN0ICpsYSwgRmNWYWx1ZUxpc3QgKmxiKQp7CiAgICB3aGlsZSAobGEgJiYgbGIpCiAgICB7CglpZiAoIUZjVmFsdWVFcXVhbCAobGEtPnZhbHVlLCBsYi0+dmFsdWUpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJbGEgPSBsYS0+bmV4dDsKCWxiID0gbGItPm5leHQ7CiAgICB9CiAgICBpZiAobGEgfHwgbGIpCglyZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY1ZhbHVlTGlzdEhhc2ggKEZjVmFsdWVMaXN0ICpsKQp7CiAgICBGY0NoYXIzMgloYXNoID0gMDsKICAgIAogICAgd2hpbGUgKGwpCiAgICB7CgloYXNoID0gKChoYXNoIDw8IDEpIHwgKGhhc2ggPj4gMzEpKSBeIEZjVmFsdWVIYXNoIChsLT52YWx1ZSk7CglsID0gbC0+bmV4dDsKICAgIH0KICAgIHJldHVybiBoYXNoOwp9Cgp2b2lkCkZjUGF0dGVybkRlc3Ryb3kgKEZjUGF0dGVybiAqcCkKewogICAgaW50CQkgICAgaTsKICAgIAogICAgaWYgKC0tcC0+cmVmID4gMCkKCXJldHVybjsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCglGY1ZhbHVlTGlzdERlc3Ryb3kgKHAtPmVsdHNbaV0udmFsdWVzKTsKCiAgICBwLT5udW0gPSAwOwogICAgaWYgKHAtPmVsdHMpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9QQVRFTFQsIHAtPnNpemUgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJZnJlZSAocC0+ZWx0cyk7CglwLT5lbHRzID0gMDsKICAgIH0KICAgIHAtPnNpemUgPSAwOwogICAgRmNNZW1GcmVlIChGQ19NRU1fUEFUVEVSTiwgc2l6ZW9mIChGY1BhdHRlcm4pKTsKICAgIGZyZWUgKHApOwp9CgpzdGF0aWMgaW50CkZjUGF0dGVyblBvc2l0aW9uIChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CSAgICBsb3csIGhpZ2gsIG1pZCwgYzsKCiAgICBsb3cgPSAwOwogICAgaGlnaCA9IHAtPm51bSAtIDE7CiAgICBjID0gMTsKICAgIG1pZCA9IDA7CiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAobG93ICsgaGlnaCkgPj4gMTsKCWMgPSBzdHJjbXAgKHAtPmVsdHNbbWlkXS5vYmplY3QsIG9iamVjdCk7CglpZiAoYyA9PSAwKQoJICAgIHJldHVybiBtaWQ7CglpZiAoYyA8IDApCgkgICAgbG93ID0gbWlkICsgMTsKCWVsc2UKCSAgICBoaWdoID0gbWlkIC0gMTsKICAgIH0KICAgIGlmIChjIDwgMCkKCW1pZCsrOwogICAgcmV0dXJuIC0obWlkICsgMSk7Cn0KCkZjUGF0dGVybkVsdCAqCkZjUGF0dGVybkZpbmRFbHQgKGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0KQp7CiAgICBpbnQJICAgIGkgPSBGY1BhdHRlcm5Qb3NpdGlvbiAocCwgb2JqZWN0KTsKICAgIGlmIChpIDwgMCkKCXJldHVybiAwOwogICAgcmV0dXJuICZwLT5lbHRzW2ldOwp9CgpGY1BhdHRlcm5FbHQgKgpGY1BhdHRlcm5JbnNlcnRFbHQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0KQp7CiAgICBpbnQJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0ICAgKmU7CiAgICAKICAgIGkgPSBGY1BhdHRlcm5Qb3NpdGlvbiAocCwgb2JqZWN0KTsKICAgIGlmIChpIDwgMCkKICAgIHsKCWkgPSAtaSAtIDE7CiAgICAKCS8qIGdyb3cgYXJyYXkgKi8KCWlmIChwLT5udW0gKyAxID49IHAtPnNpemUpCgl7CgkgICAgaW50IHMgPSBwLT5zaXplICsgMTY7CgkgICAgaWYgKHAtPmVsdHMpCgkJZSA9IChGY1BhdHRlcm5FbHQgKikgcmVhbGxvYyAocC0+ZWx0cywgcyAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CgkgICAgZWxzZQoJCWUgPSAoRmNQYXR0ZXJuRWx0ICopIG1hbGxvYyAocyAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CgkgICAgaWYgKCFlKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIHAtPmVsdHMgPSBlOwoJICAgIGlmIChwLT5zaXplKQoJCUZjTWVtRnJlZSAoRkNfTUVNX1BBVEVMVCwgcC0+c2l6ZSAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CgkgICAgRmNNZW1BbGxvYyAoRkNfTUVNX1BBVEVMVCwgcyAqIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSk7CgkgICAgd2hpbGUgKHAtPnNpemUgPCBzKQoJICAgIHsKCQlwLT5lbHRzW3AtPnNpemVdLm9iamVjdCA9IDA7CgkJcC0+ZWx0c1twLT5zaXplXS52YWx1ZXMgPSAwOwoJCXAtPnNpemUrKzsKCSAgICB9Cgl9CgkKCS8qIG1vdmUgZWx0cyB1cCAqLwoJbWVtbW92ZSAocC0+ZWx0cyArIGkgKyAxLAoJCSBwLT5lbHRzICsgaSwKCQkgc2l6ZW9mIChGY1BhdHRlcm5FbHQpICoKCQkgKHAtPm51bSAtIGkpKTsKCQkgCgkvKiBidW1wIGNvdW50ICovCglwLT5udW0rKzsKCQoJcC0+ZWx0c1tpXS5vYmplY3QgPSBvYmplY3Q7CglwLT5lbHRzW2ldLnZhbHVlcyA9IDA7CiAgICB9CiAgICAKICAgIHJldHVybiAmcC0+ZWx0c1tpXTsKfQoKRmNCb29sCkZjUGF0dGVybkVxdWFsIChjb25zdCBGY1BhdHRlcm4gKnBhLCBjb25zdCBGY1BhdHRlcm4gKnBiKQp7CiAgICBpbnQJaTsKCiAgICBpZiAocGEgPT0gcGIpCglyZXR1cm4gRmNUcnVlOwoKICAgIGlmIChwYS0+bnVtICE9IHBiLT5udW0pCglyZXR1cm4gRmNGYWxzZTsKICAgIGZvciAoaSA9IDA7IGkgPCBwYS0+bnVtOyBpKyspCiAgICB7CglpZiAoc3RyY21wIChwYS0+ZWx0c1tpXS5vYmplY3QsIHBiLT5lbHRzW2ldLm9iamVjdCkgIT0gMCkKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmICghRmNWYWx1ZUxpc3RFcXVhbCAocGEtPmVsdHNbaV0udmFsdWVzLCBwYi0+ZWx0c1tpXS52YWx1ZXMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyMzIKRmNQYXR0ZXJuSGFzaCAoY29uc3QgRmNQYXR0ZXJuICpwKQp7CiAgICBpbnQJCWk7CiAgICBGY0NoYXIzMgloID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCiAgICB7CgloID0gKCgoaCA8PCAxKSB8IChoID4+IDMxKSkgXiAKCSAgICAgRmNTdHJpbmdIYXNoICgoY29uc3QgRmNDaGFyOCAqKSBwLT5lbHRzW2ldLm9iamVjdCkgXgoJICAgICBGY1ZhbHVlTGlzdEhhc2ggKHAtPmVsdHNbaV0udmFsdWVzKSk7CiAgICB9CiAgICByZXR1cm4gaDsKfQoKRmNCb29sCkZjUGF0dGVybkVxdWFsU3Vic2V0IChjb25zdCBGY1BhdHRlcm4gKnBhLCBjb25zdCBGY1BhdHRlcm4gKnBiLCBjb25zdCBGY09iamVjdFNldCAqb3MpCnsKICAgIEZjUGF0dGVybkVsdCAgICAqZWEsICplYjsKICAgIGludAkJICAgIGk7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBvcy0+bm9iamVjdDsgaSsrKQogICAgewoJZWEgPSBGY1BhdHRlcm5GaW5kRWx0IChwYSwgb3MtPm9iamVjdHNbaV0pOwoJZWIgPSBGY1BhdHRlcm5GaW5kRWx0IChwYiwgb3MtPm9iamVjdHNbaV0pOwoJaWYgKGVhKQoJewoJICAgIGlmICghZWIpCgkJcmV0dXJuIEZjRmFsc2U7CgkgICAgaWYgKCFGY1ZhbHVlTGlzdEVxdWFsIChlYS0+dmFsdWVzLCBlYi0+dmFsdWVzKSkKCQlyZXR1cm4gRmNGYWxzZTsKCX0KCWVsc2UKCXsKCSAgICBpZiAoZWIpCgkJcmV0dXJuIEZjRmFsc2U7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgIChGY1BhdHRlcm4JICAgICpwLAoJCQkgIGNvbnN0IGNoYXIJICAgICpvYmplY3QsCgkJCSAgRmNWYWx1ZQkgICAgdmFsdWUsCgkJCSAgRmNWYWx1ZUJpbmRpbmcgICAgYmluZGluZywKCQkJICBGY0Jvb2wJICAgIGFwcGVuZCkKewogICAgRmNQYXR0ZXJuRWx0ICAgKmU7CiAgICBGY1ZhbHVlTGlzdCAgICAqbmV3LCAqKnByZXY7CgogICAgbmV3ID0gKEZjVmFsdWVMaXN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgaWYgKCFuZXcpCglnb3RvIGJhaWwwOwoKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICAvKiBkdXAgc3RyaW5nICovCiAgICB2YWx1ZSA9IEZjVmFsdWVTYXZlICh2YWx1ZSk7CiAgICBpZiAodmFsdWUudHlwZSA9PSBGY1R5cGVWb2lkKQoJZ290byBiYWlsMTsKCiAgICBuZXctPnZhbHVlID0gdmFsdWU7CiAgICBuZXctPmJpbmRpbmcgPSBiaW5kaW5nOwogICAgbmV3LT5uZXh0ID0gMDsKICAgIAogICAgZSA9IEZjUGF0dGVybkluc2VydEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCWdvdG8gYmFpbDI7CiAgICAKICAgIGlmIChhcHBlbmQpCiAgICB7Cglmb3IgKHByZXYgPSAmZS0+dmFsdWVzOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KTsKCSpwcmV2ID0gbmV3OwogICAgfQogICAgZWxzZQogICAgewoJbmV3LT5uZXh0ID0gZS0+dmFsdWVzOwoJZS0+dmFsdWVzID0gbmV3OwogICAgfQogICAgCiAgICByZXR1cm4gRmNUcnVlOwoKYmFpbDI6ICAgIAogICAgc3dpdGNoICh2YWx1ZS50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCUZjU3RyRnJlZSAoKEZjQ2hhcjggKikgdmFsdWUudS5zKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglGY01hdHJpeEZyZWUgKChGY01hdHJpeCAqKSB2YWx1ZS51Lm0pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHZhbHVlLnUuYyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlUGF0dGVybjoKCUZjUGF0dGVybkRlc3Ryb3kgKChGY1BhdHRlcm4gKikgdmFsdWUudS5wKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQpiYWlsMToKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGZyZWUgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nU3Ryb25nLCBhcHBlbmQpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkV2VhayAgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nV2VhaywgYXBwZW5kKTsKfQoKRmNCb29sCkZjUGF0dGVybkRlbCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgaW50CQkgICAgaTsKCiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybiBGY0ZhbHNlOwoKICAgIGkgPSBlIC0gcC0+ZWx0czsKICAgIAogICAgLyogZGVzdHJveSB2YWx1ZSAqLwogICAgRmNWYWx1ZUxpc3REZXN0cm95IChlLT52YWx1ZXMpOwogICAgCiAgICAvKiBzaHVmZmxlIGV4aXN0aW5nIG9uZXMgZG93biAqLwogICAgbWVtbW92ZSAoZSwgZSsxLCAocC0+ZWx0cyArIHAtPm51bSAtIChlICsgMSkpICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKICAgIHAtPm51bS0tOwogICAgcC0+ZWx0c1twLT5udW1dLm9iamVjdCA9IDA7CiAgICBwLT5lbHRzW3AtPm51bV0udmFsdWVzID0gMDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRJbnRlZ2VyIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGkpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwogICAgdi51LmkgPSBpOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkRG91YmxlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgZG91YmxlIGQpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CiAgICB2LnUuZCA9IGQ7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCgpGY0Jvb2wKRmNQYXR0ZXJuQWRkU3RyaW5nIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZVN0cmluZzsKICAgIHYudS5zID0gczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZE1hdHJpeCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjTWF0cml4ICpzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgdi51Lm0gPSAoRmNNYXRyaXggKikgczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKCkZjQm9vbApGY1BhdHRlcm5BZGRCb29sIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgRmNCb29sIGIpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwogICAgdi51LmIgPSBiOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkQ2hhclNldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjQ2hhclNldCAqYykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7CiAgICB2LnUuYyA9IChGY0NoYXJTZXQgKikgYzsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZEZURmFjZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZUX0ZhY2UgZikKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUZURmFjZTsKICAgIHYudS5mID0gKHZvaWQgKikgZjsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZFBhdHRlcm4gKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBjb25zdCBGY1BhdHRlcm4gKnBwKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlUGF0dGVybjsKICAgIHYudS5wID0gcHA7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNWYWx1ZSAqdikKewogICAgRmNQYXR0ZXJuRWx0ICAgKmU7CiAgICBGY1ZhbHVlTGlzdCAgICAqbDsKCiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybiBGY1Jlc3VsdE5vTWF0Y2g7CiAgICBmb3IgKGwgPSBlLT52YWx1ZXM7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJaWYgKCFpZCkKCXsKCSAgICAqdiA9IGwtPnZhbHVlOwoJICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwoJfQoJaWQtLTsKICAgIH0KICAgIHJldHVybiBGY1Jlc3VsdE5vSWQ7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldEludGVnZXIgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIGludCAqaSkKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVEb3VibGU6CgkqaSA9IChpbnQpIHYudS5kOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CgkqaSA9IHYudS5pOwoJYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgIH0KICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXREb3VibGUgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIGRvdWJsZSAqZCkKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVEb3VibGU6CgkqZCA9IHYudS5kOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CgkqZCA9IChkb3VibGUpIHYudS5pOwoJYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgIH0KICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRTdHJpbmcgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjQ2hhcjggKiogcykKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZVN0cmluZykKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqcyA9IChGY0NoYXI4ICopIHYudS5zOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldE1hdHJpeCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNNYXRyaXggKiptKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlTWF0cml4KQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICptID0gKEZjTWF0cml4ICopIHYudS5tOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRCb29sIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0Jvb2wgKmIpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVCb29sKQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpiID0gdi51LmI7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0Q2hhclNldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNDaGFyU2V0ICoqYykKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUNoYXJTZXQpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKmMgPSAoRmNDaGFyU2V0ICopIHYudS5jOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldEZURmFjZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRlRfRmFjZSAqZikKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUZURmFjZSkKCXJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpmID0gKEZUX0ZhY2UpIHYudS5mOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldFBhdHRlcm4gKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjUGF0dGVybiAqKnBwKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlUGF0dGVybikKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqcHAgPSAoRmNQYXR0ZXJuICopIHYudS5wOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVybkR1cGxpY2F0ZSAoRmNQYXR0ZXJuICpvcmlnKQp7CiAgICBGY1BhdHRlcm4JICAgICpuZXc7CiAgICBpbnQJCSAgICBpOwogICAgRmNWYWx1ZUxpc3QgICAgKmw7CgogICAgbmV3ID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFuZXcpCglnb3RvIGJhaWwwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvcmlnLT5udW07IGkrKykKICAgIHsKCWZvciAobCA9IG9yaWctPmVsdHNbaV0udmFsdWVzOyBsOyBsID0gbC0+bmV4dCkKCSAgICBpZiAoIUZjUGF0dGVybkFkZCAobmV3LCBvcmlnLT5lbHRzW2ldLm9iamVjdCwgbC0+dmFsdWUsIEZjVHJ1ZSkpCgkJZ290byBiYWlsMTsKICAgIH0KCiAgICByZXR1cm4gbmV3OwoKYmFpbDE6CiAgICBGY1BhdHRlcm5EZXN0cm95IChuZXcpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp2b2lkCkZjUGF0dGVyblJlZmVyZW5jZSAoRmNQYXR0ZXJuICpwKQp7CiAgICBwLT5yZWYrKzsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuVmFCdWlsZCAoRmNQYXR0ZXJuICpvcmlnLCB2YV9saXN0IHZhKQp7CiAgICBGY1BhdHRlcm4JKnJldDsKICAgIAogICAgRmNQYXR0ZXJuVmFwQnVpbGQgKHJldCwgb3JpZywgdmEpOwogICAgcmV0dXJuIHJldDsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuQnVpbGQgKEZjUGF0dGVybiAqb3JpZywgLi4uKQp7CiAgICB2YV9saXN0CXZhOwogICAgCiAgICB2YV9zdGFydCAodmEsIG9yaWcpOwogICAgRmNQYXR0ZXJuVmFwQnVpbGQgKG9yaWcsIG9yaWcsIHZhKTsKICAgIHZhX2VuZCAodmEpOwogICAgcmV0dXJuIG9yaWc7Cn0K