LyogY3Vyc29yLmMgLSB0aGUgY3Vyc29yIHR5cGUKICoKICogQ29weXJpZ2h0IChDKSAyMDA0LTIwMDYgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBweXNxbGl0ZS4KICoKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgImN1cnNvci5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJzcWxpdGVjb21wYXQuaCIKCi8qIHVzZWQgdG8gZGVjaWRlIHdldGhlciB0byBjYWxsIFB5SW50X0Zyb21Mb25nIG9yIFB5TG9uZ19Gcm9tTG9uZ0xvbmcgKi8KI2lmbmRlZiBJTlQzMl9NSU4KI2RlZmluZSBJTlQzMl9NSU4gKC0yMTQ3NDgzNjQ3IC0gMSkKI2VuZGlmCiNpZm5kZWYgSU5UMzJfTUFYCiNkZWZpbmUgSU5UMzJfTUFYIDIxNDc0ODM2NDcKI2VuZGlmCgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2l0ZXJuZXh0KHB5c3FsaXRlX0N1cnNvciogc2VsZik7CgpzdGF0aWMgcHlzcWxpdGVfU3RhdGVtZW50S2luZCBkZXRlY3Rfc3RhdGVtZW50X3R5cGUoY2hhciogc3RhdGVtZW50KQp7CiAgICBjaGFyIGJ1ZlsyMF07CiAgICBjaGFyKiBzcmM7CiAgICBjaGFyKiBkc3Q7CgogICAgc3JjID0gc3RhdGVtZW50OwogICAgLyogc2tpcCBvdmVyIHdoaXRlcGFjZSAqLwogICAgd2hpbGUgKCpzcmMgPT0gJ1xyJyB8fCAqc3JjID09ICdcbicgfHwgKnNyYyA9PSAnICcgfHwgKnNyYyA9PSAnXHQnKSB7CiAgICAgICAgc3JjKys7CiAgICB9CgogICAgaWYgKCpzcmMgPT0gMCkKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX0lOVkFMSUQ7CgogICAgZHN0ID0gYnVmOwogICAgKmRzdCA9IDA7CiAgICB3aGlsZSAoaXNhbHBoYSgqc3JjKSAmJiBkc3QgLSBidWYgPCBzaXplb2YoYnVmKSAtIDIpIHsKICAgICAgICAqZHN0KysgPSB0b2xvd2VyKCpzcmMrKyk7CiAgICB9CgogICAgKmRzdCA9IDA7CgogICAgaWYgKCFzdHJjbXAoYnVmLCAic2VsZWN0IikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX1NFTEVDVDsKICAgIH0gZWxzZSBpZiAoIXN0cmNtcChidWYsICJpbnNlcnQiKSkgewogICAgICAgIHJldHVybiBTVEFURU1FTlRfSU5TRVJUOwogICAgfSBlbHNlIGlmICghc3RyY21wKGJ1ZiwgInVwZGF0ZSIpKSB7CiAgICAgICAgcmV0dXJuIFNUQVRFTUVOVF9VUERBVEU7CiAgICB9IGVsc2UgaWYgKCFzdHJjbXAoYnVmLCAiZGVsZXRlIikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX0RFTEVURTsKICAgIH0gZWxzZSBpZiAoIXN0cmNtcChidWYsICJyZXBsYWNlIikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX1JFUExBQ0U7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBTVEFURU1FTlRfT1RIRVI7CiAgICB9Cn0KCmludCBweXNxbGl0ZV9jdXJzb3JfaW5pdChweXNxbGl0ZV9DdXJzb3IqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBweXNxbGl0ZV9Db25uZWN0aW9uKiBjb25uZWN0aW9uOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyEiLCAmcHlzcWxpdGVfQ29ubmVjdGlvblR5cGUsICZjb25uZWN0aW9uKSkKICAgIHsKICAgICAgICByZXR1cm4gLTE7IAogICAgfQoKICAgIFB5X0lOQ1JFRihjb25uZWN0aW9uKTsKICAgIHNlbGYtPmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uOwogICAgc2VsZi0+c3RhdGVtZW50ID0gTlVMTDsKICAgIHNlbGYtPm5leHRfcm93ID0gTlVMTDsKCiAgICBzZWxmLT5yb3dfY2FzdF9tYXAgPSBQeUxpc3RfTmV3KDApOwogICAgaWYgKCFzZWxmLT5yb3dfY2FzdF9tYXApIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgc2VsZi0+ZGVzY3JpcHRpb24gPSBQeV9Ob25lOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHNlbGYtPmxhc3Ryb3dpZD0gUHlfTm9uZTsKCiAgICBzZWxmLT5hcnJheXNpemUgPSAxOwoKICAgIHNlbGYtPnJvd2NvdW50ID0gUHlJbnRfRnJvbUxvbmcoLTFMKTsKICAgIGlmICghc2VsZi0+cm93Y291bnQpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgc2VsZi0+cm93X2ZhY3RvcnkgPSBQeV9Ob25lOwoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHJldHVybiAwOwp9Cgp2b2lkIHB5c3FsaXRlX2N1cnNvcl9kZWFsbG9jKHB5c3FsaXRlX0N1cnNvciogc2VsZikKewogICAgaW50IHJjOwoKICAgIC8qIFJlc2V0IHRoZSBzdGF0ZW1lbnQgaWYgdGhlIHVzZXIgaGFzIG5vdCBjbG9zZWQgdGhlIGN1cnNvciAqLwogICAgaWYgKHNlbGYtPnN0YXRlbWVudCkgewogICAgICAgIHJjID0gcHlzcWxpdGVfc3RhdGVtZW50X3Jlc2V0KHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudCk7CiAgICB9CgogICAgUHlfWERFQ1JFRihzZWxmLT5jb25uZWN0aW9uKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+cm93X2Nhc3RfbWFwKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+ZGVzY3JpcHRpb24pOwogICAgUHlfWERFQ1JFRihzZWxmLT5sYXN0cm93aWQpOwogICAgUHlfWERFQ1JFRihzZWxmLT5yb3djb3VudCk7CiAgICBQeV9YREVDUkVGKHNlbGYtPnJvd19mYWN0b3J5KTsKICAgIFB5X1hERUNSRUYoc2VsZi0+bmV4dF9yb3cpOwoKICAgIFB5X1R5cGUoc2VsZiktPnRwX2ZyZWUoKFB5T2JqZWN0KilzZWxmKTsKfQoKUHlPYmplY3QqIF9weXNxbGl0ZV9nZXRfY29udmVydGVyKFB5T2JqZWN0KiBrZXkpCnsKICAgIFB5T2JqZWN0KiB1cGNhc2Vfa2V5OwogICAgUHlPYmplY3QqIHJldHZhbDsKCiAgICB1cGNhc2Vfa2V5ID0gUHlPYmplY3RfQ2FsbE1ldGhvZChrZXksICJ1cHBlciIsICIiKTsKICAgIGlmICghdXBjYXNlX2tleSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHZhbCA9IFB5RGljdF9HZXRJdGVtKGNvbnZlcnRlcnMsIHVwY2FzZV9rZXkpOwogICAgUHlfREVDUkVGKHVwY2FzZV9rZXkpOwoKICAgIHJldHVybiByZXR2YWw7Cn0KCmludCBweXNxbGl0ZV9idWlsZF9yb3dfY2FzdF9tYXAocHlzcWxpdGVfQ3Vyc29yKiBzZWxmKQp7CiAgICBpbnQgaTsKICAgIGNvbnN0IGNoYXIqIHR5cGVfc3RhcnQgPSAoY29uc3QgY2hhciopLTE7CiAgICBjb25zdCBjaGFyKiBwb3M7CgogICAgY29uc3QgY2hhciogY29sbmFtZTsKICAgIGNvbnN0IGNoYXIqIGRlY2x0eXBlOwogICAgUHlPYmplY3QqIHB5X2RlY2x0eXBlOwogICAgUHlPYmplY3QqIGNvbnZlcnRlcjsKICAgIFB5T2JqZWN0KiBrZXk7CgogICAgaWYgKCFzZWxmLT5jb25uZWN0aW9uLT5kZXRlY3RfdHlwZXMpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBQeV9YREVDUkVGKHNlbGYtPnJvd19jYXN0X21hcCk7CiAgICBzZWxmLT5yb3dfY2FzdF9tYXAgPSBQeUxpc3RfTmV3KDApOwoKICAgIGZvciAoaSA9IDA7IGkgPCBzcWxpdGUzX2NvbHVtbl9jb3VudChzZWxmLT5zdGF0ZW1lbnQtPnN0KTsgaSsrKSB7CiAgICAgICAgY29udmVydGVyID0gTlVMTDsKCiAgICAgICAgaWYgKHNlbGYtPmNvbm5lY3Rpb24tPmRldGVjdF90eXBlcyAmIFBBUlNFX0NPTE5BTUVTKSB7CiAgICAgICAgICAgIGNvbG5hbWUgPSBzcWxpdGUzX2NvbHVtbl9uYW1lKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICBpZiAoY29sbmFtZSkgewogICAgICAgICAgICAgICAgZm9yIChwb3MgPSBjb2xuYW1lOyAqcG9zICE9IDA7IHBvcysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCpwb3MgPT0gJ1snKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfc3RhcnQgPSBwb3MgKyAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKnBvcyA9PSAnXScgJiYgdHlwZV9zdGFydCAhPSAoY29uc3QgY2hhciopLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUodHlwZV9zdGFydCwgcG9zIC0gdHlwZV9zdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgha2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjcmVhdGluZyBhIHN0cmluZyBmYWlsZWQsIGJ1dCBpdCBpcyB0b28gY29tcGxpY2F0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRvIHByb3BhZ2F0ZSB0aGUgZXJyb3IgaGVyZSwgd2UganVzdCBhc3N1bWUgdGhlcmUgaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIG5vIGNvbnZlcnRlciBhbmQgcHJvY2VlZCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlciA9IF9weXNxbGl0ZV9nZXRfY29udmVydGVyKGtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghY29udmVydGVyICYmIHNlbGYtPmNvbm5lY3Rpb24tPmRldGVjdF90eXBlcyAmIFBBUlNFX0RFQ0xUWVBFUykgewogICAgICAgICAgICBkZWNsdHlwZSA9IHNxbGl0ZTNfY29sdW1uX2RlY2x0eXBlKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICBpZiAoZGVjbHR5cGUpIHsKICAgICAgICAgICAgICAgIGZvciAocG9zID0gZGVjbHR5cGU7O3BvcysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCpwb3MgPT0gJyAnIHx8ICpwb3MgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBweV9kZWNsdHlwZSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKGRlY2x0eXBlLCBwb3MgLSBkZWNsdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHlfZGVjbHR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY29udmVydGVyID0gX3B5c3FsaXRlX2dldF9jb252ZXJ0ZXIocHlfZGVjbHR5cGUpOwogICAgICAgICAgICAgICAgUHlfREVDUkVGKHB5X2RlY2x0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFjb252ZXJ0ZXIpIHsKICAgICAgICAgICAgY29udmVydGVyID0gUHlfTm9uZTsKICAgICAgICB9CgogICAgICAgIGlmIChQeUxpc3RfQXBwZW5kKHNlbGYtPnJvd19jYXN0X21hcCwgY29udmVydGVyKSAhPSAwKSB7CiAgICAgICAgICAgIGlmIChjb252ZXJ0ZXIgIT0gUHlfTm9uZSkgewogICAgICAgICAgICAgICAgUHlfREVDUkVGKGNvbnZlcnRlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUHlfWERFQ1JFRihzZWxmLT5yb3dfY2FzdF9tYXApOwogICAgICAgICAgICBzZWxmLT5yb3dfY2FzdF9tYXAgPSBOVUxMOwoKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoKUHlPYmplY3QqIF9weXNxbGl0ZV9idWlsZF9jb2x1bW5fbmFtZShjb25zdCBjaGFyKiBjb2xuYW1lKQp7CiAgICBjb25zdCBjaGFyKiBwb3M7CgogICAgaWYgKCFjb2xuYW1lKSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQoKICAgIGZvciAocG9zID0gY29sbmFtZTs7IHBvcysrKSB7CiAgICAgICAgaWYgKCpwb3MgPT0gMCB8fCAqcG9zID09ICdbJykgewogICAgICAgICAgICBpZiAoKCpwb3MgPT0gJ1snKSAmJiAocG9zID4gY29sbmFtZSkgJiYgKCoocG9zLTEpID09ICcgJykpIHsKICAgICAgICAgICAgICAgIHBvcy0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShjb2xuYW1lLCBwb3MgLSBjb2xuYW1lKTsKICAgICAgICB9CiAgICB9Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV91bmljb2RlX2Zyb21fc3RyaW5nKGNvbnN0IGNoYXIqIHZhbF9zdHIsIGludCBvcHRpbWl6ZSkKewogICAgY29uc3QgY2hhciogY2hlY2s7CiAgICBpbnQgaXNfYXNjaWkgPSAwOwoKICAgIGlmIChvcHRpbWl6ZSkgewogICAgICAgIGlzX2FzY2lpID0gMTsKCiAgICAgICAgY2hlY2sgPSB2YWxfc3RyOwogICAgICAgIHdoaWxlICgqY2hlY2spIHsKICAgICAgICAgICAgaWYgKCpjaGVjayAmIDB4ODApIHsKICAgICAgICAgICAgICAgIGlzX2FzY2lpID0gMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjaGVjaysrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaXNfYXNjaWkpIHsKICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyh2YWxfc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9EZWNvZGVVVEY4KHZhbF9zdHIsIHN0cmxlbih2YWxfc3RyKSwgTlVMTCk7CiAgICB9Cn0KCi8qCiAqIFJldHVybnMgYSByb3cgZnJvbSB0aGUgY3VycmVudGx5IGFjdGl2ZSBTUUxpdGUgc3RhdGVtZW50CiAqCiAqIFByZWNvbmRpZGl0aW9uOgogKiAtIHNxbGl0ZTNfc3RlcCgpIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUgYW5kIGl0IHJldHVybmVkIFNRTElURV9ST1cuCiAqLwpQeU9iamVjdCogX3B5c3FsaXRlX2ZldGNoX29uZV9yb3cocHlzcWxpdGVfQ3Vyc29yKiBzZWxmKQp7CiAgICBpbnQgaSwgbnVtY29sczsKICAgIFB5T2JqZWN0KiByb3c7CiAgICBQeU9iamVjdCogaXRlbSA9IE5VTEw7CiAgICBpbnQgY29sdHlwZTsKICAgIFBZX0xPTkdfTE9ORyBpbnR2YWw7CiAgICBQeU9iamVjdCogY29udmVydGVyOwogICAgUHlPYmplY3QqIGNvbnZlcnRlZDsKICAgIFB5X3NzaXplX3QgbmJ5dGVzOwogICAgUHlPYmplY3QqIGJ1ZmZlcjsKICAgIHZvaWQqIHJhd19idWZmZXI7CiAgICBjb25zdCBjaGFyKiB2YWxfc3RyOwogICAgY2hhciBidWZbMjAwXTsKICAgIGNvbnN0IGNoYXIqIGNvbG5hbWU7CgogICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgbnVtY29scyA9IHNxbGl0ZTNfZGF0YV9jb3VudChzZWxmLT5zdGF0ZW1lbnQtPnN0KTsKICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgcm93ID0gUHlUdXBsZV9OZXcobnVtY29scyk7CiAgICBpZiAoIXJvdykgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBudW1jb2xzOyBpKyspIHsKICAgICAgICBpZiAoc2VsZi0+Y29ubmVjdGlvbi0+ZGV0ZWN0X3R5cGVzKSB7CiAgICAgICAgICAgIGNvbnZlcnRlciA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnJvd19jYXN0X21hcCwgaSk7CiAgICAgICAgICAgIGlmICghY29udmVydGVyKSB7CiAgICAgICAgICAgICAgICBjb252ZXJ0ZXIgPSBQeV9Ob25lOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29udmVydGVyID0gUHlfTm9uZTsKICAgICAgICB9CgogICAgICAgIGlmIChjb252ZXJ0ZXIgIT0gUHlfTm9uZSkgewogICAgICAgICAgICBuYnl0ZXMgPSBzcWxpdGUzX2NvbHVtbl9ieXRlcyhzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKTsKICAgICAgICAgICAgdmFsX3N0ciA9IChjb25zdCBjaGFyKilzcWxpdGUzX2NvbHVtbl9ibG9iKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICBpZiAoIXZhbF9zdHIpIHsKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IFB5X05vbmU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpdGVtID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUodmFsX3N0ciwgbmJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmICghaXRlbSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKGNvbnZlcnRlciwgIk8iLCBpdGVtKTsKICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdGVtKTsKICAgICAgICAgICAgICAgIGlmICghY29udmVydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgICAgIGNvbHR5cGUgPSBzcWxpdGUzX2NvbHVtbl90eXBlKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBpZiAoY29sdHlwZSA9PSBTUUxJVEVfTlVMTCkgewogICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlfTm9uZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjb2x0eXBlID09IFNRTElURV9JTlRFR0VSKSB7CiAgICAgICAgICAgICAgICBpbnR2YWwgPSBzcWxpdGUzX2NvbHVtbl9pbnQ2NChzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKTsKICAgICAgICAgICAgICAgIGlmIChpbnR2YWwgPCBJTlQzMl9NSU4gfHwgaW50dmFsID4gSU5UMzJfTUFYKSB7CiAgICAgICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlMb25nX0Zyb21Mb25nTG9uZyhpbnR2YWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBQeUludF9Gcm9tTG9uZygobG9uZylpbnR2YWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGNvbHR5cGUgPT0gU1FMSVRFX0ZMT0FUKSB7CiAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBQeUZsb2F0X0Zyb21Eb3VibGUoc3FsaXRlM19jb2x1bW5fZG91YmxlKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjb2x0eXBlID09IFNRTElURV9URVhUKSB7CiAgICAgICAgICAgICAgICB2YWxfc3RyID0gKGNvbnN0IGNoYXIqKXNxbGl0ZTNfY29sdW1uX3RleHQoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgICAgICBpZiAoKHNlbGYtPmNvbm5lY3Rpb24tPnRleHRfZmFjdG9yeSA9PSAoUHlPYmplY3QqKSZQeVVuaWNvZGVfVHlwZSkKICAgICAgICAgICAgICAgICAgICB8fCAoc2VsZi0+Y29ubmVjdGlvbi0+dGV4dF9mYWN0b3J5ID09IHB5c3FsaXRlX09wdGltaXplZFVuaWNvZGUpKSB7CgogICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IHB5c3FsaXRlX3VuaWNvZGVfZnJvbV9zdHJpbmcodmFsX3N0ciwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+Y29ubmVjdGlvbi0+dGV4dF9mYWN0b3J5ID09IHB5c3FsaXRlX09wdGltaXplZFVuaWNvZGUgPyAxIDogMCk7CgogICAgICAgICAgICAgICAgICAgIGlmICghY29udmVydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWUgPSBzcWxpdGUzX2NvbHVtbl9uYW1lKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWUgPSAiPHVua25vd24gY29sdW1uIG5hbWU+IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZikgLSAxLCAiQ291bGQgbm90IGRlY29kZSB0byBVVEYtOCBjb2x1bW4gJyVzJyB3aXRoIHRleHQgJyVzJyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xuYW1lICwgdmFsX3N0cik7CiAgICAgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhweXNxbGl0ZV9PcGVyYXRpb25hbEVycm9yLCBidWYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VsZi0+Y29ubmVjdGlvbi0+dGV4dF9mYWN0b3J5ID09IChQeU9iamVjdCopJlB5U3RyaW5nX1R5cGUpIHsKICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKHZhbF9zdHIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oc2VsZi0+Y29ubmVjdGlvbi0+dGV4dF9mYWN0b3J5LCAicyIsIHZhbF9zdHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogY29sdHlwZSA9PSBTUUxJVEVfQkxPQiAqLwogICAgICAgICAgICAgICAgbmJ5dGVzID0gc3FsaXRlM19jb2x1bW5fYnl0ZXMoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgICAgICBidWZmZXIgPSBQeUJ1ZmZlcl9OZXcobmJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmICghYnVmZmVyKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoUHlPYmplY3RfQXNXcml0ZUJ1ZmZlcihidWZmZXIsICZyYXdfYnVmZmVyLCAmbmJ5dGVzKSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWVtY3B5KHJhd19idWZmZXIsIHNxbGl0ZTNfY29sdW1uX2Jsb2Ioc2VsZi0+c3RhdGVtZW50LT5zdCwgaSksIG5ieXRlcyk7CiAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBidWZmZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChjb252ZXJ0ZWQpIHsKICAgICAgICAgICAgUHlUdXBsZV9TZXRJdGVtKHJvdywgaSwgY29udmVydGVkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgICAgIFB5VHVwbGVfU2V0SXRlbShyb3csIGksIFB5X05vbmUpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIFB5X0RFQ1JFRihyb3cpOwogICAgICAgIHJvdyA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJvdzsKfQoKUHlPYmplY3QqIF9weXNxbGl0ZV9xdWVyeV9leGVjdXRlKHB5c3FsaXRlX0N1cnNvciogc2VsZiwgaW50IG11bHRpcGxlLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIG9wZXJhdGlvbjsKICAgIFB5T2JqZWN0KiBvcGVyYXRpb25fYnl0ZXN0ciA9IE5VTEw7CiAgICBjaGFyKiBvcGVyYXRpb25fY3N0cjsKICAgIFB5T2JqZWN0KiBwYXJhbWV0ZXJzX2xpc3QgPSBOVUxMOwogICAgUHlPYmplY3QqIHBhcmFtZXRlcnNfaXRlciA9IE5VTEw7CiAgICBQeU9iamVjdCogcGFyYW1ldGVycyA9IE5VTEw7CiAgICBpbnQgaTsKICAgIGludCByYzsKICAgIFB5T2JqZWN0KiBmdW5jX2FyZ3M7CiAgICBQeU9iamVjdCogcmVzdWx0OwogICAgaW50IG51bWNvbHM7CiAgICBQWV9MT05HX0xPTkcgbGFzdHJvd2lkOwogICAgaW50IHN0YXRlbWVudF90eXBlOwogICAgUHlPYmplY3QqIGRlc2NyaXB0b3I7CiAgICBQeU9iamVjdCogc2Vjb25kX2FyZ3VtZW50ID0gTlVMTDsKICAgIGxvbmcgcm93Y291bnQgPSAwOwoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pIHx8ICFweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgUHlfWERFQ1JFRihzZWxmLT5uZXh0X3Jvdyk7CiAgICBzZWxmLT5uZXh0X3JvdyA9IE5VTEw7CgogICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgLyogZXhlY3V0ZW1hbnkoKSAqLwogICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT08iLCAmb3BlcmF0aW9uLCAmc2Vjb25kX2FyZ3VtZW50KSkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsgCiAgICAgICAgfQoKICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG9wZXJhdGlvbikgJiYgIVB5VW5pY29kZV9DaGVjayhvcGVyYXRpb24pKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAib3BlcmF0aW9uIHBhcmFtZXRlciBtdXN0IGJlIHN0ciBvciB1bmljb2RlIik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKFB5SXRlcl9DaGVjayhzZWNvbmRfYXJndW1lbnQpKSB7CiAgICAgICAgICAgIC8qIGl0ZXJhdG9yICovCiAgICAgICAgICAgIFB5X0lOQ1JFRihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBwYXJhbWV0ZXJzX2l0ZXIgPSBzZWNvbmRfYXJndW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogc2VxdWVuY2UgKi8KICAgICAgICAgICAgcGFyYW1ldGVyc19pdGVyID0gUHlPYmplY3RfR2V0SXRlcihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBpZiAoIXBhcmFtZXRlcnNfaXRlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIGV4ZWN1dGUoKSAqLwogICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT3xPIiwgJm9wZXJhdGlvbiwgJnNlY29uZF9hcmd1bWVudCkpIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgICAgIH0KCiAgICAgICAgaWYgKCFQeVN0cmluZ19DaGVjayhvcGVyYXRpb24pICYmICFQeVVuaWNvZGVfQ2hlY2sob3BlcmF0aW9uKSkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm9wZXJhdGlvbiBwYXJhbWV0ZXIgbXVzdCBiZSBzdHIgb3IgdW5pY29kZSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIHBhcmFtZXRlcnNfbGlzdCA9IFB5TGlzdF9OZXcoMCk7CiAgICAgICAgaWYgKCFwYXJhbWV0ZXJzX2xpc3QpIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2Vjb25kX2FyZ3VtZW50ID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vjb25kX2FyZ3VtZW50ID0gUHlUdXBsZV9OZXcoMCk7CiAgICAgICAgICAgIGlmICghc2Vjb25kX2FyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlfSU5DUkVGKHNlY29uZF9hcmd1bWVudCk7CiAgICAgICAgfQogICAgICAgIGlmIChQeUxpc3RfQXBwZW5kKHBhcmFtZXRlcnNfbGlzdCwgc2Vjb25kX2FyZ3VtZW50KSAhPSAwKSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYoc2Vjb25kX2FyZ3VtZW50KTsKCiAgICAgICAgcGFyYW1ldGVyc19pdGVyID0gUHlPYmplY3RfR2V0SXRlcihwYXJhbWV0ZXJzX2xpc3QpOwogICAgICAgIGlmICghcGFyYW1ldGVyc19pdGVyKSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzZWxmLT5zdGF0ZW1lbnQgIT0gTlVMTCkgewogICAgICAgIC8qIFRoZXJlIGlzIGFuIGFjdGl2ZSBzdGF0ZW1lbnQgKi8KICAgICAgICByYyA9IHB5c3FsaXRlX3N0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgfQoKICAgIGlmIChQeVN0cmluZ19DaGVjayhvcGVyYXRpb24pKSB7CiAgICAgICAgb3BlcmF0aW9uX2NzdHIgPSBQeVN0cmluZ19Bc1N0cmluZyhvcGVyYXRpb24pOwogICAgfSBlbHNlIHsKICAgICAgICBvcGVyYXRpb25fYnl0ZXN0ciA9IFB5VW5pY29kZV9Bc1VURjhTdHJpbmcob3BlcmF0aW9uKTsKICAgICAgICBpZiAoIW9wZXJhdGlvbl9ieXRlc3RyKSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBvcGVyYXRpb25fY3N0ciA9IFB5U3RyaW5nX0FzU3RyaW5nKG9wZXJhdGlvbl9ieXRlc3RyKTsKICAgIH0KCiAgICAvKiByZXNldCBkZXNjcmlwdGlvbiBhbmQgcm93Y291bnQgKi8KICAgIFB5X0RFQ1JFRihzZWxmLT5kZXNjcmlwdGlvbik7CiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICBzZWxmLT5kZXNjcmlwdGlvbiA9IFB5X05vbmU7CgogICAgUHlfREVDUkVGKHNlbGYtPnJvd2NvdW50KTsKICAgIHNlbGYtPnJvd2NvdW50ID0gUHlJbnRfRnJvbUxvbmcoLTFMKTsKICAgIGlmICghc2VsZi0+cm93Y291bnQpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHN0YXRlbWVudF90eXBlID0gZGV0ZWN0X3N0YXRlbWVudF90eXBlKG9wZXJhdGlvbl9jc3RyKTsKICAgIGlmIChzZWxmLT5jb25uZWN0aW9uLT5iZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICBzd2l0Y2ggKHN0YXRlbWVudF90eXBlKSB7CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX1VQREFURToKICAgICAgICAgICAgY2FzZSBTVEFURU1FTlRfREVMRVRFOgogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9JTlNFUlQ6CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX1JFUExBQ0U6CiAgICAgICAgICAgICAgICBpZiAoIXNlbGYtPmNvbm5lY3Rpb24tPmluVHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBfcHlzcWxpdGVfY29ubmVjdGlvbl9iZWdpbihzZWxmLT5jb25uZWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9PVEhFUjoKICAgICAgICAgICAgICAgIC8qIGl0J3MgYSBEREwgc3RhdGVtZW50IG9yIHNvbWV0aGluZyBzaW1pbGFyCiAgICAgICAgICAgICAgICAgICAtIHdlIGJldHRlciBDT01NSVQgZmlyc3Qgc28gaXQgd29ya3MgZm9yIGFsbCBjYXNlcyAqLwogICAgICAgICAgICAgICAgaWYgKHNlbGYtPmNvbm5lY3Rpb24tPmluVHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBweXNxbGl0ZV9jb25uZWN0aW9uX2NvbW1pdChzZWxmLT5jb25uZWN0aW9uLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9TRUxFQ1Q6CiAgICAgICAgICAgICAgICBpZiAobXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfUHJvZ3JhbW1pbmdFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWW91IGNhbm5vdCBleGVjdXRlIFNFTEVDVCBzdGF0ZW1lbnRzIGluIGV4ZWN1dGVtYW55KCkuIik7CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jX2FyZ3MgPSBQeVR1cGxlX05ldygxKTsKICAgIGlmICghZnVuY19hcmdzKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5X0lOQ1JFRihvcGVyYXRpb24pOwogICAgaWYgKFB5VHVwbGVfU2V0SXRlbShmdW5jX2FyZ3MsIDAsIG9wZXJhdGlvbikgIT0gMCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHNlbGYtPnN0YXRlbWVudCkgewogICAgICAgICh2b2lkKXB5c3FsaXRlX3N0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnQpOwogICAgfQoKICAgIHNlbGYtPnN0YXRlbWVudCA9IChweXNxbGl0ZV9TdGF0ZW1lbnQqKXB5c3FsaXRlX2NhY2hlX2dldChzZWxmLT5jb25uZWN0aW9uLT5zdGF0ZW1lbnRfY2FjaGUsIGZ1bmNfYXJncyk7CiAgICBQeV9ERUNSRUYoZnVuY19hcmdzKTsKCiAgICBpZiAoIXNlbGYtPnN0YXRlbWVudCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHNlbGYtPnN0YXRlbWVudC0+aW5fdXNlKSB7CiAgICAgICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgc2VsZi0+c3RhdGVtZW50ID0gUHlPYmplY3RfTmV3KHB5c3FsaXRlX1N0YXRlbWVudCwgJnB5c3FsaXRlX1N0YXRlbWVudFR5cGUpOwogICAgICAgIGlmICghc2VsZi0+c3RhdGVtZW50KSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJjID0gcHlzcWxpdGVfc3RhdGVtZW50X2NyZWF0ZShzZWxmLT5zdGF0ZW1lbnQsIHNlbGYtPmNvbm5lY3Rpb24sIG9wZXJhdGlvbik7CiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBzZWxmLT5zdGF0ZW1lbnQgPSAwOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgIH0KCiAgICBweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQoc2VsZi0+c3RhdGVtZW50KTsKICAgIHB5c3FsaXRlX3N0YXRlbWVudF9tYXJrX2RpcnR5KHNlbGYtPnN0YXRlbWVudCk7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBwYXJhbWV0ZXJzID0gUHlJdGVyX05leHQocGFyYW1ldGVyc19pdGVyKTsKICAgICAgICBpZiAoIXBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBweXNxbGl0ZV9zdGF0ZW1lbnRfbWFya19kaXJ0eShzZWxmLT5zdGF0ZW1lbnQpOwoKICAgICAgICBweXNxbGl0ZV9zdGF0ZW1lbnRfYmluZF9wYXJhbWV0ZXJzKHNlbGYtPnN0YXRlbWVudCwgcGFyYW1ldGVycyk7CiAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIGlmIChweXNxbGl0ZV9idWlsZF9yb3dfY2FzdF9tYXAoc2VsZikgIT0gMCkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcocHlzcWxpdGVfT3BlcmF0aW9uYWxFcnJvciwgIkVycm9yIHdoaWxlIGJ1aWxkaW5nIHJvd19jYXN0X21hcCIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgLyogS2VlcCB0cnlpbmcgdGhlIFNRTCBzdGF0ZW1lbnQgdW50aWwgdGhlIHNjaGVtYSBzdG9wcyBjaGFuZ2luZy4gKi8KICAgICAgICB3aGlsZSAoMSkgewogICAgICAgICAgICAvKiBBY3R1YWxseSBleGVjdXRlIHRoZSBTUUwgc3RhdGVtZW50LiAqLwogICAgICAgICAgICByYyA9IF9zcWxpdGVfc3RlcF93aXRoX2J1c3loYW5kbGVyKHNlbGYtPnN0YXRlbWVudC0+c3QsIHNlbGYtPmNvbm5lY3Rpb24pOwogICAgICAgICAgICBpZiAocmMgPT0gU1FMSVRFX0RPTkUgfHwgIHJjID09IFNRTElURV9ST1cpIHsKICAgICAgICAgICAgICAgIC8qIElmIGl0IHdvcmtlZCwgbGV0J3MgZ2V0IG91dCBvZiB0aGUgbG9vcCAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogU29tZXRoaW5nIHdlbnQgd3JvbmcuICBSZS1zZXQgdGhlIHN0YXRlbWVudCBhbmQgdHJ5IGFnYWluLiAqLwogICAgICAgICAgICByYyA9IHB5c3FsaXRlX3N0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBpZiAocmMgPT0gU1FMSVRFX1NDSEVNQSkgewogICAgICAgICAgICAgICAgLyogSWYgdGhpcyB3YXMgYSByZXN1bHQgb2YgdGhlIHNjaGVtYSBjaGFuZ2luZywgbGV0J3MgdHJ5CiAgICAgICAgICAgICAgICAgICBhZ2Fpbi4gKi8KICAgICAgICAgICAgICAgIHJjID0gcHlzcWxpdGVfc3RhdGVtZW50X3JlY29tcGlsZShzZWxmLT5zdGF0ZW1lbnQsIHBhcmFtZXRlcnMpOwogICAgICAgICAgICAgICAgaWYgKHJjID09IFNRTElURV9PSykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGUgZGF0YWJhc2UgZ2F2ZSB1cyBhbiBlcnJvciwgcHJvbW90ZSBpdCB0byBQeXRob24uICovCiAgICAgICAgICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAvKiB0aGVyZSB3YXMgYW4gZXJyb3IgdGhhdCBvY2N1cnJlZCBpbiBhIHVzZXItZGVmaW5lZCBjYWxsYmFjayAqLwogICAgICAgICAgICAgICAgICAgIGlmIChfZW5hYmxlX2NhbGxiYWNrX3RyYWNlYmFja3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfUHJpbnQoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF9weXNxbGl0ZV9zZXRlcnJvcihzZWxmLT5jb25uZWN0aW9uLT5kYik7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmMgPT0gU1FMSVRFX1JPVyB8fCAocmMgPT0gU1FMSVRFX0RPTkUgJiYgc3RhdGVtZW50X3R5cGUgPT0gU1RBVEVNRU5UX1NFTEVDVCkpIHsKICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBudW1jb2xzID0gc3FsaXRlM19jb2x1bW5fY291bnQoc2VsZi0+c3RhdGVtZW50LT5zdCk7CiAgICAgICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgICAgICAgICBpZiAoc2VsZi0+ZGVzY3JpcHRpb24gPT0gUHlfTm9uZSkgewogICAgICAgICAgICAgICAgUHlfREVDUkVGKHNlbGYtPmRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgIHNlbGYtPmRlc2NyaXB0aW9uID0gUHlUdXBsZV9OZXcobnVtY29scyk7CiAgICAgICAgICAgICAgICBpZiAoIXNlbGYtPmRlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1jb2xzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yID0gUHlUdXBsZV9OZXcoNyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXNjcmlwdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFB5VHVwbGVfU2V0SXRlbShkZXNjcmlwdG9yLCAwLCBfcHlzcWxpdGVfYnVpbGRfY29sdW1uX25hbWUoc3FsaXRlM19jb2x1bW5fbmFtZShzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKSkpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDEsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDIsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDMsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDQsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDUsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDYsIFB5X05vbmUpOwogICAgICAgICAgICAgICAgICAgIFB5VHVwbGVfU2V0SXRlbShzZWxmLT5kZXNjcmlwdGlvbiwgaSwgZGVzY3JpcHRvcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyYyA9PSBTUUxJVEVfUk9XKSB7CiAgICAgICAgICAgIGlmIChtdWx0aXBsZSkgewogICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKHB5c3FsaXRlX1Byb2dyYW1taW5nRXJyb3IsICJleGVjdXRlbWFueSgpIGNhbiBvbmx5IGV4ZWN1dGUgRE1MIHN0YXRlbWVudHMuIik7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzZWxmLT5uZXh0X3JvdyA9IF9weXNxbGl0ZV9mZXRjaF9vbmVfcm93KHNlbGYpOwogICAgICAgIH0gZWxzZSBpZiAocmMgPT0gU1FMSVRFX0RPTkUgJiYgIW11bHRpcGxlKSB7CiAgICAgICAgICAgIHB5c3FsaXRlX3N0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50KTsKICAgICAgICAgICAgc2VsZi0+c3RhdGVtZW50ID0gMDsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoc3RhdGVtZW50X3R5cGUpIHsKICAgICAgICAgICAgY2FzZSBTVEFURU1FTlRfVVBEQVRFOgogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9ERUxFVEU6CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX0lOU0VSVDoKICAgICAgICAgICAgY2FzZSBTVEFURU1FTlRfUkVQTEFDRToKICAgICAgICAgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKICAgICAgICAgICAgICAgIHJvd2NvdW50ICs9IChsb25nKXNxbGl0ZTNfY2hhbmdlcyhzZWxmLT5jb25uZWN0aW9uLT5kYik7CiAgICAgICAgICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgICAgICAgICAgUHlfREVDUkVGKHNlbGYtPnJvd2NvdW50KTsKICAgICAgICAgICAgICAgIHNlbGYtPnJvd2NvdW50ID0gUHlJbnRfRnJvbUxvbmcocm93Y291bnQpOwogICAgICAgIH0KCiAgICAgICAgUHlfREVDUkVGKHNlbGYtPmxhc3Ryb3dpZCk7CiAgICAgICAgaWYgKHN0YXRlbWVudF90eXBlID09IFNUQVRFTUVOVF9JTlNFUlQpIHsKICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBsYXN0cm93aWQgPSBzcWxpdGUzX2xhc3RfaW5zZXJ0X3Jvd2lkKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICAgICAgc2VsZi0+bGFzdHJvd2lkID0gUHlJbnRfRnJvbUxvbmcoKGxvbmcpbGFzdHJvd2lkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgICAgIHNlbGYtPmxhc3Ryb3dpZCA9IFB5X05vbmU7CiAgICAgICAgfQoKICAgICAgICBpZiAobXVsdGlwbGUpIHsKICAgICAgICAgICAgcmMgPSBweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQoc2VsZi0+c3RhdGVtZW50KTsKICAgICAgICB9CiAgICAgICAgUHlfWERFQ1JFRihwYXJhbWV0ZXJzKTsKICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihvcGVyYXRpb25fYnl0ZXN0cik7CiAgICBQeV9YREVDUkVGKHBhcmFtZXRlcnMpOwogICAgUHlfWERFQ1JFRihwYXJhbWV0ZXJzX2l0ZXIpOwogICAgUHlfWERFQ1JFRihwYXJhbWV0ZXJzX2xpc3QpOwoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKICAgICAgICByZXR1cm4gKFB5T2JqZWN0KilzZWxmOwogICAgfQp9CgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2V4ZWN1dGUocHlzcWxpdGVfQ3Vyc29yKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgcmV0dXJuIF9weXNxbGl0ZV9xdWVyeV9leGVjdXRlKHNlbGYsIDAsIGFyZ3MpOwp9CgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2V4ZWN1dGVtYW55KHB5c3FsaXRlX0N1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIHJldHVybiBfcHlzcWxpdGVfcXVlcnlfZXhlY3V0ZShzZWxmLCAxLCBhcmdzKTsKfQoKUHlPYmplY3QqIHB5c3FsaXRlX2N1cnNvcl9leGVjdXRlc2NyaXB0KHB5c3FsaXRlX0N1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIFB5T2JqZWN0KiBzY3JpcHRfb2JqOwogICAgUHlPYmplY3QqIHNjcmlwdF9zdHIgPSBOVUxMOwogICAgY29uc3QgY2hhciogc2NyaXB0X2NzdHI7CiAgICBzcWxpdGUzX3N0bXQqIHN0YXRlbWVudDsKICAgIGludCByYzsKICAgIFB5T2JqZWN0KiByZXN1bHQ7CiAgICBpbnQgc3RhdGVtZW50X2NvbXBsZXRlZCA9IDA7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIiwgJnNjcmlwdF9vYmopKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgfQoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pIHx8ICFweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKFB5U3RyaW5nX0NoZWNrKHNjcmlwdF9vYmopKSB7CiAgICAgICAgc2NyaXB0X2NzdHIgPSBQeVN0cmluZ19Bc1N0cmluZyhzY3JpcHRfb2JqKTsKICAgIH0gZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHNjcmlwdF9vYmopKSB7CiAgICAgICAgc2NyaXB0X3N0ciA9IFB5VW5pY29kZV9Bc1VURjhTdHJpbmcoc2NyaXB0X29iaik7CiAgICAgICAgaWYgKCFzY3JpcHRfc3RyKSB7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgc2NyaXB0X2NzdHIgPSBQeVN0cmluZ19Bc1N0cmluZyhzY3JpcHRfc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJzY3JpcHQgYXJndW1lbnQgbXVzdCBiZSB1bmljb2RlIG9yIHN0cmluZy4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBjb21taXQgZmlyc3QgKi8KICAgIHJlc3VsdCA9IHB5c3FsaXRlX2Nvbm5lY3Rpb25fY29tbWl0KHNlbGYtPmNvbm5lY3Rpb24sIE5VTEwpOwogICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgUHlfREVDUkVGKHJlc3VsdCk7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBpZiAoIXNxbGl0ZTNfY29tcGxldGUoc2NyaXB0X2NzdHIpKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBzdGF0ZW1lbnRfY29tcGxldGVkID0gMTsKCiAgICAgICAgcmMgPSBzcWxpdGUzX3ByZXBhcmUoc2VsZi0+Y29ubmVjdGlvbi0+ZGIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0X2NzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXRlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2NyaXB0X2NzdHIpOwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIC8qIGV4ZWN1dGUgc3RhdGVtZW50LCBhbmQgaWdub3JlIHJlc3VsdHMgb2YgU0VMRUNUIHN0YXRlbWVudHMgKi8KICAgICAgICByYyA9IFNRTElURV9ST1c7CiAgICAgICAgd2hpbGUgKHJjID09IFNRTElURV9ST1cpIHsKICAgICAgICAgICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzdGF0ZW1lbnQsIHNlbGYtPmNvbm5lY3Rpb24pOwogICAgICAgIH0KCiAgICAgICAgaWYgKHJjICE9IFNRTElURV9ET05FKSB7CiAgICAgICAgICAgICh2b2lkKXNxbGl0ZTNfZmluYWxpemUoc3RhdGVtZW50KTsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHJjID0gc3FsaXRlM19maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgICAgIGlmIChyYyAhPSBTUUxJVEVfT0spIHsKICAgICAgICAgICAgX3B5c3FsaXRlX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICB9CgplcnJvcjoKICAgIFB5X1hERUNSRUYoc2NyaXB0X3N0cik7CgogICAgaWYgKCFzdGF0ZW1lbnRfY29tcGxldGVkKSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKHB5c3FsaXRlX1Byb2dyYW1taW5nRXJyb3IsICJ5b3UgZGlkIG5vdCBwcm92aWRlIGEgY29tcGxldGUgU1FMIHN0YXRlbWVudCIpOwogICAgfQoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKICAgICAgICByZXR1cm4gKFB5T2JqZWN0KilzZWxmOwogICAgfQp9CgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2dldGl0ZXIocHlzcWxpdGVfQ3Vyc29yICpzZWxmKQp7CiAgICBQeV9JTkNSRUYoc2VsZik7CiAgICByZXR1cm4gKFB5T2JqZWN0KilzZWxmOwp9CgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2l0ZXJuZXh0KHB5c3FsaXRlX0N1cnNvciAqc2VsZikKewogICAgUHlPYmplY3QqIG5leHRfcm93X3R1cGxlOwogICAgUHlPYmplY3QqIG5leHRfcm93OwogICAgaW50IHJjOwoKICAgIGlmICghcHlzcWxpdGVfY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pIHx8ICFweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFzZWxmLT5uZXh0X3JvdykgewogICAgICAgICBpZiAoc2VsZi0+c3RhdGVtZW50KSB7CiAgICAgICAgICAgICh2b2lkKXB5c3FsaXRlX3N0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50KTsKICAgICAgICAgICAgc2VsZi0+c3RhdGVtZW50ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgbmV4dF9yb3dfdHVwbGUgPSBzZWxmLT5uZXh0X3JvdzsKICAgIHNlbGYtPm5leHRfcm93ID0gTlVMTDsKCiAgICBpZiAoc2VsZi0+cm93X2ZhY3RvcnkgIT0gUHlfTm9uZSkgewogICAgICAgIG5leHRfcm93ID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKHNlbGYtPnJvd19mYWN0b3J5LCAiT08iLCBzZWxmLCBuZXh0X3Jvd190dXBsZSk7CiAgICAgICAgUHlfREVDUkVGKG5leHRfcm93X3R1cGxlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgbmV4dF9yb3cgPSBuZXh0X3Jvd190dXBsZTsKICAgIH0KCiAgICBpZiAoc2VsZi0+c3RhdGVtZW50KSB7CiAgICAgICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzZWxmLT5zdGF0ZW1lbnQtPnN0LCBzZWxmLT5jb25uZWN0aW9uKTsKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX0RPTkUgJiYgcmMgIT0gU1FMSVRFX1JPVykgewogICAgICAgICAgICBQeV9ERUNSRUYobmV4dF9yb3cpOwogICAgICAgICAgICBfcHlzcWxpdGVfc2V0ZXJyb3Ioc2VsZi0+Y29ubmVjdGlvbi0+ZGIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIGlmIChyYyA9PSBTUUxJVEVfUk9XKSB7CiAgICAgICAgICAgIHNlbGYtPm5leHRfcm93ID0gX3B5c3FsaXRlX2ZldGNoX29uZV9yb3coc2VsZik7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBuZXh0X3JvdzsKfQoKUHlPYmplY3QqIHB5c3FsaXRlX2N1cnNvcl9mZXRjaG9uZShweXNxbGl0ZV9DdXJzb3IqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBQeU9iamVjdCogcm93OwoKICAgIHJvdyA9IHB5c3FsaXRlX2N1cnNvcl9pdGVybmV4dChzZWxmKTsKICAgIGlmICghcm93ICYmICFQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgIHJldHVybiBQeV9Ob25lOwogICAgfQoKICAgIHJldHVybiByb3c7Cn0KClB5T2JqZWN0KiBweXNxbGl0ZV9jdXJzb3JfZmV0Y2htYW55KHB5c3FsaXRlX0N1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIFB5T2JqZWN0KiByb3c7CiAgICBQeU9iamVjdCogbGlzdDsKICAgIGludCBtYXhyb3dzID0gc2VsZi0+YXJyYXlzaXplOwogICAgaW50IGNvdW50ZXIgPSAwOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAifGkiLCAmbWF4cm93cykpIHsKICAgICAgICByZXR1cm4gTlVMTDsgCiAgICB9CgogICAgbGlzdCA9IFB5TGlzdF9OZXcoMCk7CiAgICBpZiAoIWxpc3QpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBqdXN0IG1ha2Ugc3VyZSB3ZSBlbnRlciB0aGUgbG9vcCAqLwogICAgcm93ID0gUHlfTm9uZTsKCiAgICB3aGlsZSAocm93KSB7CiAgICAgICAgcm93ID0gcHlzcWxpdGVfY3Vyc29yX2l0ZXJuZXh0KHNlbGYpOwogICAgICAgIGlmIChyb3cpIHsKICAgICAgICAgICAgUHlMaXN0X0FwcGVuZChsaXN0LCByb3cpOwogICAgICAgICAgICBQeV9ERUNSRUYocm93KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICgrK2NvdW50ZXIgPT0gbWF4cm93cykgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICBQeV9ERUNSRUYobGlzdCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBsaXN0OwogICAgfQp9CgpQeU9iamVjdCogcHlzcWxpdGVfY3Vyc29yX2ZldGNoYWxsKHB5c3FsaXRlX0N1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIFB5T2JqZWN0KiByb3c7CiAgICBQeU9iamVjdCogbGlzdDsKCiAgICBsaXN0ID0gUHlMaXN0X05ldygwKTsKICAgIGlmICghbGlzdCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIGp1c3QgbWFrZSBzdXJlIHdlIGVudGVyIHRoZSBsb29wICovCiAgICByb3cgPSAoUHlPYmplY3QqKVB5X05vbmU7CgogICAgd2hpbGUgKHJvdykgewogICAgICAgIHJvdyA9IHB5c3FsaXRlX2N1cnNvcl9pdGVybmV4dChzZWxmKTsKICAgICAgICBpZiAocm93KSB7CiAgICAgICAgICAgIFB5TGlzdF9BcHBlbmQobGlzdCwgcm93KTsKICAgICAgICAgICAgUHlfREVDUkVGKHJvdyk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CiAgICAgICAgUHlfREVDUkVGKGxpc3QpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbGlzdDsKICAgIH0KfQoKUHlPYmplY3QqIHB5c3FsaXRlX25vb3AocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIC8qIGRvbid0IGNhcmUsIHJldHVybiBOb25lICovCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKUHlPYmplY3QqIHB5c3FsaXRlX2N1cnNvcl9jbG9zZShweXNxbGl0ZV9DdXJzb3IqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICBpZiAoIXB5c3FsaXRlX2NoZWNrX3RocmVhZChzZWxmLT5jb25uZWN0aW9uKSB8fCAhcHlzcWxpdGVfY2hlY2tfY29ubmVjdGlvbihzZWxmLT5jb25uZWN0aW9uKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChzZWxmLT5zdGF0ZW1lbnQpIHsKICAgICAgICAodm9pZClweXNxbGl0ZV9zdGF0ZW1lbnRfcmVzZXQoc2VsZi0+c3RhdGVtZW50KTsKICAgICAgICBQeV9ERUNSRUYoc2VsZi0+c3RhdGVtZW50KTsKICAgICAgICBzZWxmLT5zdGF0ZW1lbnQgPSAwOwogICAgfQoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlNZXRob2REZWYgY3Vyc29yX21ldGhvZHNbXSA9IHsKICAgIHsiZXhlY3V0ZSIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9jdXJzb3JfZXhlY3V0ZSwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiRXhlY3V0ZXMgYSBTUUwgc3RhdGVtZW50LiIpfSwKICAgIHsiZXhlY3V0ZW1hbnkiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY3Vyc29yX2V4ZWN1dGVtYW55LCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJSZXBlYXRlZGx5IGV4ZWN1dGVzIGEgU1FMIHN0YXRlbWVudC4iKX0sCiAgICB7ImV4ZWN1dGVzY3JpcHQiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY3Vyc29yX2V4ZWN1dGVzY3JpcHQsIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIkV4ZWN1dGVzIGEgbXVsdGlwbGUgU1FMIHN0YXRlbWVudHMgYXQgb25jZS4gTm9uLXN0YW5kYXJkLiIpfSwKICAgIHsiZmV0Y2hvbmUiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY3Vyc29yX2ZldGNob25lLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkZldGNoZXMgc2V2ZXJhbCByb3dzIGZyb20gdGhlIHJlc3VsdHNldC4iKX0sCiAgICB7ImZldGNobWFueSIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9jdXJzb3JfZmV0Y2htYW55LCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJGZXRjaGVzIGFsbCByb3dzIGZyb20gdGhlIHJlc3VsdHNldC4iKX0sCiAgICB7ImZldGNoYWxsIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX2N1cnNvcl9mZXRjaGFsbCwgTUVUSF9OT0FSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJGZXRjaGVzIG9uZSByb3cgZnJvbSB0aGUgcmVzdWx0c2V0LiIpfSwKICAgIHsiY2xvc2UiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfY3Vyc29yX2Nsb3NlLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkNsb3NlcyB0aGUgY3Vyc29yLiIpfSwKICAgIHsic2V0aW5wdXRzaXplcyIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9ub29wLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJSZXF1aXJlZCBieSBEQi1BUEkuIERvZXMgbm90aGluZyBpbiBweXNxbGl0ZS4iKX0sCiAgICB7InNldG91dHB1dHNpemUiLCAoUHlDRnVuY3Rpb24pcHlzcWxpdGVfbm9vcCwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiUmVxdWlyZWQgYnkgREItQVBJLiBEb2VzIG5vdGhpbmcgaW4gcHlzcWxpdGUuIil9LAogICAge05VTEwsIE5VTEx9Cn07CgpzdGF0aWMgc3RydWN0IFB5TWVtYmVyRGVmIGN1cnNvcl9tZW1iZXJzW10gPQp7CiAgICB7ImNvbm5lY3Rpb24iLCBUX09CSkVDVCwgb2Zmc2V0b2YocHlzcWxpdGVfQ3Vyc29yLCBjb25uZWN0aW9uKSwgUk99LAogICAgeyJkZXNjcmlwdGlvbiIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9DdXJzb3IsIGRlc2NyaXB0aW9uKSwgUk99LAogICAgeyJhcnJheXNpemUiLCBUX0lOVCwgb2Zmc2V0b2YocHlzcWxpdGVfQ3Vyc29yLCBhcnJheXNpemUpLCAwfSwKICAgIHsibGFzdHJvd2lkIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHB5c3FsaXRlX0N1cnNvciwgbGFzdHJvd2lkKSwgUk99LAogICAgeyJyb3djb3VudCIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9DdXJzb3IsIHJvd2NvdW50KSwgUk99LAogICAgeyJyb3dfZmFjdG9yeSIsIFRfT0JKRUNULCBvZmZzZXRvZihweXNxbGl0ZV9DdXJzb3IsIHJvd19mYWN0b3J5KSwgMH0sCiAgICB7TlVMTH0KfTsKCnN0YXRpYyBjaGFyIGN1cnNvcl9kb2NbXSA9ClB5RG9jX1NUUigiU1FMaXRlIGRhdGFiYXNlIGN1cnNvciBjbGFzcy4iKTsKClB5VHlwZU9iamVjdCBweXNxbGl0ZV9DdXJzb3JUeXBlID0gewogICAgICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVChOVUxMLCAwKQogICAgICAgIE1PRFVMRV9OQU1FICIuQ3Vyc29yIiwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KICAgICAgICBzaXplb2YocHlzcWxpdGVfQ3Vyc29yKSwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLwogICAgICAgIChkZXN0cnVjdG9yKXB5c3FsaXRlX2N1cnNvcl9kZWFsbG9jLCAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFR8UHlfVFBGTEFHU19IQVZFX0lURVJ8UHlfVFBGTEFHU19CQVNFVFlQRSwgLyogdHBfZmxhZ3MgKi8KICAgICAgICBjdXJzb3JfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLwogICAgICAgIChnZXRpdGVyZnVuYylweXNxbGl0ZV9jdXJzb3JfZ2V0aXRlciwgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KICAgICAgICAoaXRlcm5leHRmdW5jKXB5c3FsaXRlX2N1cnNvcl9pdGVybmV4dCwgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLwogICAgICAgIGN1cnNvcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KICAgICAgICBjdXJzb3JfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCiAgICAgICAgKGluaXRwcm9jKXB5c3FsaXRlX2N1cnNvcl9pbml0LCAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCiAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLwp9OwoKZXh0ZXJuIGludCBweXNxbGl0ZV9jdXJzb3Jfc2V0dXBfdHlwZXModm9pZCkKewogICAgcHlzcWxpdGVfQ3Vyc29yVHlwZS50cF9uZXcgPSBQeVR5cGVfR2VuZXJpY05ldzsKICAgIHJldHVybiBQeVR5cGVfUmVhZHkoJnB5c3FsaXRlX0N1cnNvclR5cGUpOwp9Cg==