LyogY3Vyc29yLmMgLSB0aGUgY3Vyc29yIHR5cGUKICoKICogQ29weXJpZ2h0IChDKSAyMDA0LTIwMDYgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBweXNxbGl0ZS4KICoKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2luY2x1ZGUgImN1cnNvci5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJzcWxpdGVjb21wYXQuaCIKCi8qIHVzZWQgdG8gZGVjaWRlIHdldGhlciB0byBjYWxsIFB5SW50X0Zyb21Mb25nIG9yIFB5TG9uZ19Gcm9tTG9uZ0xvbmcgKi8KI2lmbmRlZiBJTlQzMl9NSU4KI2RlZmluZSBJTlQzMl9NSU4gKC0yMTQ3NDgzNjQ3IC0gMSkKI2VuZGlmCiNpZm5kZWYgSU5UMzJfTUFYCiNkZWZpbmUgSU5UMzJfTUFYIDIxNDc0ODM2NDcKI2VuZGlmCgpQeU9iamVjdCogY3Vyc29yX2l0ZXJuZXh0KEN1cnNvciAqc2VsZik7CgpzdGF0aWMgU3RhdGVtZW50S2luZCBkZXRlY3Rfc3RhdGVtZW50X3R5cGUoY2hhciogc3RhdGVtZW50KQp7CiAgICBjaGFyIGJ1ZlsyMF07CiAgICBjaGFyKiBzcmM7CiAgICBjaGFyKiBkc3Q7CgogICAgc3JjID0gc3RhdGVtZW50OwogICAgLyogc2tpcCBvdmVyIHdoaXRlcGFjZSAqLwogICAgd2hpbGUgKCpzcmMgPT0gJ1xyJyB8fCAqc3JjID09ICdcbicgfHwgKnNyYyA9PSAnICcgfHwgKnNyYyA9PSAnXHQnKSB7CiAgICAgICAgc3JjKys7CiAgICB9CgogICAgaWYgKCpzcmMgPT0gMCkKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX0lOVkFMSUQ7CgogICAgZHN0ID0gYnVmOwogICAgKmRzdCA9IDA7CiAgICB3aGlsZSAoaXNhbHBoYSgqc3JjKSAmJiBkc3QgLSBidWYgPCBzaXplb2YoYnVmKSAtIDIpIHsKICAgICAgICAqZHN0KysgPSB0b2xvd2VyKCpzcmMrKyk7CiAgICB9CgogICAgKmRzdCA9IDA7CgogICAgaWYgKCFzdHJjbXAoYnVmLCAic2VsZWN0IikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX1NFTEVDVDsKICAgIH0gZWxzZSBpZiAoIXN0cmNtcChidWYsICJpbnNlcnQiKSkgewogICAgICAgIHJldHVybiBTVEFURU1FTlRfSU5TRVJUOwogICAgfSBlbHNlIGlmICghc3RyY21wKGJ1ZiwgInVwZGF0ZSIpKSB7CiAgICAgICAgcmV0dXJuIFNUQVRFTUVOVF9VUERBVEU7CiAgICB9IGVsc2UgaWYgKCFzdHJjbXAoYnVmLCAiZGVsZXRlIikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX0RFTEVURTsKICAgIH0gZWxzZSBpZiAoIXN0cmNtcChidWYsICJyZXBsYWNlIikpIHsKICAgICAgICByZXR1cm4gU1RBVEVNRU5UX1JFUExBQ0U7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBTVEFURU1FTlRfT1RIRVI7CiAgICB9Cn0KCmludCBjdXJzb3JfaW5pdChDdXJzb3IqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBDb25uZWN0aW9uKiBjb25uZWN0aW9uOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyEiLCAmQ29ubmVjdGlvblR5cGUsICZjb25uZWN0aW9uKSkKICAgIHsKICAgICAgICByZXR1cm4gLTE7IAogICAgfQoKICAgIFB5X0lOQ1JFRihjb25uZWN0aW9uKTsKICAgIHNlbGYtPmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uOwogICAgc2VsZi0+c3RhdGVtZW50ID0gTlVMTDsKICAgIHNlbGYtPm5leHRfcm93ID0gTlVMTDsKCiAgICBzZWxmLT5yb3dfY2FzdF9tYXAgPSBQeUxpc3RfTmV3KDApOwogICAgaWYgKCFzZWxmLT5yb3dfY2FzdF9tYXApIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgc2VsZi0+ZGVzY3JpcHRpb24gPSBQeV9Ob25lOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHNlbGYtPmxhc3Ryb3dpZD0gUHlfTm9uZTsKCiAgICBzZWxmLT5hcnJheXNpemUgPSAxOwoKICAgIHNlbGYtPnJvd2NvdW50ID0gUHlJbnRfRnJvbUxvbmcoLTFMKTsKICAgIGlmICghc2VsZi0+cm93Y291bnQpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgc2VsZi0+cm93X2ZhY3RvcnkgPSBQeV9Ob25lOwoKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHJldHVybiAwOwp9Cgp2b2lkIGN1cnNvcl9kZWFsbG9jKEN1cnNvciogc2VsZikKewogICAgaW50IHJjOwoKICAgIC8qIFJlc2V0IHRoZSBzdGF0ZW1lbnQgaWYgdGhlIHVzZXIgaGFzIG5vdCBjbG9zZWQgdGhlIGN1cnNvciAqLwogICAgaWYgKHNlbGYtPnN0YXRlbWVudCkgewogICAgICAgIHJjID0gc3RhdGVtZW50X3Jlc2V0KHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudCk7CiAgICB9CgogICAgUHlfWERFQ1JFRihzZWxmLT5jb25uZWN0aW9uKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+cm93X2Nhc3RfbWFwKTsKICAgIFB5X1hERUNSRUYoc2VsZi0+ZGVzY3JpcHRpb24pOwogICAgUHlfWERFQ1JFRihzZWxmLT5sYXN0cm93aWQpOwogICAgUHlfWERFQ1JFRihzZWxmLT5yb3djb3VudCk7CiAgICBQeV9YREVDUkVGKHNlbGYtPnJvd19mYWN0b3J5KTsKICAgIFB5X1hERUNSRUYoc2VsZi0+bmV4dF9yb3cpOwoKICAgIHNlbGYtPm9iX3R5cGUtPnRwX2ZyZWUoKFB5T2JqZWN0KilzZWxmKTsKfQoKaW50IGJ1aWxkX3Jvd19jYXN0X21hcChDdXJzb3IqIHNlbGYpCnsKICAgIGludCBpOwogICAgY29uc3QgY2hhciogdHlwZV9zdGFydCA9IChjb25zdCBjaGFyKiktMTsKICAgIGNvbnN0IGNoYXIqIHBvczsKCiAgICBjb25zdCBjaGFyKiBjb2xuYW1lOwogICAgY29uc3QgY2hhciogZGVjbHR5cGU7CiAgICBQeU9iamVjdCogcHlfZGVjbHR5cGU7CiAgICBQeU9iamVjdCogY29udmVydGVyOwogICAgUHlPYmplY3QqIGtleTsKCiAgICBpZiAoIXNlbGYtPmNvbm5lY3Rpb24tPmRldGVjdF90eXBlcykgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIFB5X1hERUNSRUYoc2VsZi0+cm93X2Nhc3RfbWFwKTsKICAgIHNlbGYtPnJvd19jYXN0X21hcCA9IFB5TGlzdF9OZXcoMCk7CgogICAgZm9yIChpID0gMDsgaSA8IHNxbGl0ZTNfY29sdW1uX2NvdW50KHNlbGYtPnN0YXRlbWVudC0+c3QpOyBpKyspIHsKICAgICAgICBjb252ZXJ0ZXIgPSBOVUxMOwoKICAgICAgICBpZiAoc2VsZi0+Y29ubmVjdGlvbi0+ZGV0ZWN0X3R5cGVzIHwgUEFSU0VfQ09MTkFNRVMpIHsKICAgICAgICAgICAgY29sbmFtZSA9IHNxbGl0ZTNfY29sdW1uX25hbWUoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgIGlmIChjb2xuYW1lKSB7CiAgICAgICAgICAgICAgICBmb3IgKHBvcyA9IGNvbG5hbWU7ICpwb3MgIT0gMDsgcG9zKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKnBvcyA9PSAnWycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9zdGFydCA9IHBvcyArIDE7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgqcG9zID09ICddJyAmJiB0eXBlX3N0YXJ0ICE9IChjb25zdCBjaGFyKiktMSkgewogICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSh0eXBlX3N0YXJ0LCBwb3MgLSB0eXBlX3N0YXJ0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFrZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNyZWF0aW5nIGEgc3RyaW5nIGZhaWxlZCwgYnV0IGl0IGlzIHRvbyBjb21wbGljYXRlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdG8gcHJvcGFnYXRlIHRoZSBlcnJvciBoZXJlLCB3ZSBqdXN0IGFzc3VtZSB0aGVyZSBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogbm8gY29udmVydGVyIGFuZCBwcm9jZWVkICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVyID0gUHlEaWN0X0dldEl0ZW0oY29udmVydGVycywga2V5KTsKICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFjb252ZXJ0ZXIgJiYgc2VsZi0+Y29ubmVjdGlvbi0+ZGV0ZWN0X3R5cGVzIHwgUEFSU0VfREVDTFRZUEVTKSB7CiAgICAgICAgICAgIGRlY2x0eXBlID0gc3FsaXRlM19jb2x1bW5fZGVjbHR5cGUoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgIGlmIChkZWNsdHlwZSkgewogICAgICAgICAgICAgICAgZm9yIChwb3MgPSBkZWNsdHlwZTs7cG9zKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKnBvcyA9PSAnICcgfHwgKnBvcyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHB5X2RlY2x0eXBlID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoZGVjbHR5cGUsIHBvcyAtIGRlY2x0eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFweV9kZWNsdHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjb252ZXJ0ZXIgPSBQeURpY3RfR2V0SXRlbShjb252ZXJ0ZXJzLCBweV9kZWNsdHlwZSk7CiAgICAgICAgICAgICAgICBQeV9ERUNSRUYocHlfZGVjbHR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWNvbnZlcnRlcikgewogICAgICAgICAgICBjb252ZXJ0ZXIgPSBQeV9Ob25lOwogICAgICAgIH0KCiAgICAgICAgaWYgKFB5TGlzdF9BcHBlbmQoc2VsZi0+cm93X2Nhc3RfbWFwLCBjb252ZXJ0ZXIpICE9IDApIHsKICAgICAgICAgICAgaWYgKGNvbnZlcnRlciAhPSBQeV9Ob25lKSB7CiAgICAgICAgICAgICAgICBQeV9ERUNSRUYoY29udmVydGVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBQeV9YREVDUkVGKHNlbGYtPnJvd19jYXN0X21hcCk7CiAgICAgICAgICAgIHNlbGYtPnJvd19jYXN0X21hcCA9IE5VTEw7CgogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAwOwp9CgpQeU9iamVjdCogX2J1aWxkX2NvbHVtbl9uYW1lKGNvbnN0IGNoYXIqIGNvbG5hbWUpCnsKICAgIGNvbnN0IGNoYXIqIHBvczsKCiAgICBpZiAoIWNvbG5hbWUpIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9CgogICAgZm9yIChwb3MgPSBjb2xuYW1lOzsgcG9zKyspIHsKICAgICAgICBpZiAoKnBvcyA9PSAwIHx8ICpwb3MgPT0gJyAnKSB7CiAgICAgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShjb2xuYW1lLCBwb3MgLSBjb2xuYW1lKTsKICAgICAgICB9CiAgICB9Cn0KClB5T2JqZWN0KiB1bmljb2RlX2Zyb21fc3RyaW5nKGNvbnN0IGNoYXIqIHZhbF9zdHIsIGludCBvcHRpbWl6ZSkKewogICAgY29uc3QgY2hhciogY2hlY2s7CiAgICBpbnQgaXNfYXNjaWkgPSAwOwoKICAgIGlmIChvcHRpbWl6ZSkgewogICAgICAgIGlzX2FzY2lpID0gMTsKCiAgICAgICAgY2hlY2sgPSB2YWxfc3RyOwogICAgICAgIHdoaWxlICgqY2hlY2spIHsKICAgICAgICAgICAgaWYgKCpjaGVjayAmIDB4ODApIHsKICAgICAgICAgICAgICAgIGlzX2FzY2lpID0gMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjaGVjaysrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaXNfYXNjaWkpIHsKICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyh2YWxfc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9EZWNvZGVVVEY4KHZhbF9zdHIsIHN0cmxlbih2YWxfc3RyKSwgTlVMTCk7CiAgICB9Cn0KCi8qCiAqIFJldHVybnMgYSByb3cgZnJvbSB0aGUgY3VycmVudGx5IGFjdGl2ZSBTUUxpdGUgc3RhdGVtZW50CiAqCiAqIFByZWNvbmRpZGl0aW9uOgogKiAtIHNxbGl0ZTNfc3RlcCgpIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUgYW5kIGl0IHJldHVybmVkIFNRTElURV9ST1cuCiAqLwpQeU9iamVjdCogX2ZldGNoX29uZV9yb3coQ3Vyc29yKiBzZWxmKQp7CiAgICBpbnQgaSwgbnVtY29sczsKICAgIFB5T2JqZWN0KiByb3c7CiAgICBQeU9iamVjdCogaXRlbSA9IE5VTEw7CiAgICBpbnQgY29sdHlwZTsKICAgIFBZX0xPTkdfTE9ORyBpbnR2YWw7CiAgICBQeU9iamVjdCogY29udmVydGVyOwogICAgUHlPYmplY3QqIGNvbnZlcnRlZDsKICAgIFB5X3NzaXplX3QgbmJ5dGVzOwogICAgUHlPYmplY3QqIGJ1ZmZlcjsKICAgIHZvaWQqIHJhd19idWZmZXI7CiAgICBjb25zdCBjaGFyKiB2YWxfc3RyOwogICAgY2hhciBidWZbMjAwXTsKICAgIGNvbnN0IGNoYXIqIGNvbG5hbWU7CgogICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgbnVtY29scyA9IHNxbGl0ZTNfZGF0YV9jb3VudChzZWxmLT5zdGF0ZW1lbnQtPnN0KTsKICAgIFB5X0VORF9BTExPV19USFJFQURTCgogICAgcm93ID0gUHlUdXBsZV9OZXcobnVtY29scyk7CiAgICBpZiAoIXJvdykgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBudW1jb2xzOyBpKyspIHsKICAgICAgICBpZiAoc2VsZi0+Y29ubmVjdGlvbi0+ZGV0ZWN0X3R5cGVzKSB7CiAgICAgICAgICAgIGNvbnZlcnRlciA9IFB5TGlzdF9HZXRJdGVtKHNlbGYtPnJvd19jYXN0X21hcCwgaSk7CiAgICAgICAgICAgIGlmICghY29udmVydGVyKSB7CiAgICAgICAgICAgICAgICBjb252ZXJ0ZXIgPSBQeV9Ob25lOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29udmVydGVyID0gUHlfTm9uZTsKICAgICAgICB9CgogICAgICAgIGlmIChjb252ZXJ0ZXIgIT0gUHlfTm9uZSkgewogICAgICAgICAgICB2YWxfc3RyID0gKGNvbnN0IGNoYXIqKXNxbGl0ZTNfY29sdW1uX3RleHQoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgIGlmICghdmFsX3N0cikgewogICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlfTm9uZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGl0ZW0gPSBQeVN0cmluZ19Gcm9tU3RyaW5nKHZhbF9zdHIpOwogICAgICAgICAgICAgICAgaWYgKCFpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oY29udmVydGVyLCAiTyIsIGl0ZW0pOwogICAgICAgICAgICAgICAgaWYgKCFjb252ZXJ0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAvKiBUT0RPOiBoYXZlIGEgd2F5IHRvIGxvZyB0aGVzZSBlcnJvcnMgKi8KICAgICAgICAgICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlfTm9uZTsKICAgICAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgUHlfREVDUkVGKGl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBjb2x0eXBlID0gc3FsaXRlM19jb2x1bW5fdHlwZShzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKTsKICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKICAgICAgICAgICAgaWYgKGNvbHR5cGUgPT0gU1FMSVRFX05VTEwpIHsKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IFB5X05vbmU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29sdHlwZSA9PSBTUUxJVEVfSU5URUdFUikgewogICAgICAgICAgICAgICAgaW50dmFsID0gc3FsaXRlM19jb2x1bW5faW50NjQoc2VsZi0+c3RhdGVtZW50LT5zdCwgaSk7CiAgICAgICAgICAgICAgICBpZiAoaW50dmFsIDwgSU5UMzJfTUlOIHx8IGludHZhbCA+IElOVDMyX01BWCkgewogICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IFB5TG9uZ19Gcm9tTG9uZ0xvbmcoaW50dmFsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlJbnRfRnJvbUxvbmcoKGxvbmcpaW50dmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChjb2x0eXBlID09IFNRTElURV9GTE9BVCkgewogICAgICAgICAgICAgICAgY29udmVydGVkID0gUHlGbG9hdF9Gcm9tRG91YmxlKHNxbGl0ZTNfY29sdW1uX2RvdWJsZShzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29sdHlwZSA9PSBTUUxJVEVfVEVYVCkgewogICAgICAgICAgICAgICAgdmFsX3N0ciA9IChjb25zdCBjaGFyKilzcWxpdGUzX2NvbHVtbl90ZXh0KHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpOwogICAgICAgICAgICAgICAgaWYgKChzZWxmLT5jb25uZWN0aW9uLT50ZXh0X2ZhY3RvcnkgPT0gKFB5T2JqZWN0KikmUHlVbmljb2RlX1R5cGUpCiAgICAgICAgICAgICAgICAgICAgfHwgKHNlbGYtPmNvbm5lY3Rpb24tPnRleHRfZmFjdG9yeSA9PSBPcHRpbWl6ZWRVbmljb2RlKSkgewoKICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ZWQgPSB1bmljb2RlX2Zyb21fc3RyaW5nKHZhbF9zdHIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmNvbm5lY3Rpb24tPnRleHRfZmFjdG9yeSA9PSBPcHRpbWl6ZWRVbmljb2RlID8gMSA6IDApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbnZlcnRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xuYW1lID0gc3FsaXRlM19jb2x1bW5fbmFtZShzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWUgPSAiPHVua25vd24gY29sdW1uIG5hbWU+IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZikgLSAxLCAiQ291bGQgbm90IGRlY29kZSB0byBVVEYtOCBjb2x1bW4gJXMgd2l0aCB0ZXh0ICVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5hbWUgLCB2YWxfc3RyKTsKICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE9wZXJhdGlvbmFsRXJyb3IsIGJ1Zik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxmLT5jb25uZWN0aW9uLT50ZXh0X2ZhY3RvcnkgPT0gKFB5T2JqZWN0KikmUHlTdHJpbmdfVHlwZSkgewogICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcodmFsX3N0cik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbihzZWxmLT5jb25uZWN0aW9uLT50ZXh0X2ZhY3RvcnksICJzIiwgdmFsX3N0cik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBjb2x0eXBlID09IFNRTElURV9CTE9CICovCiAgICAgICAgICAgICAgICBuYnl0ZXMgPSBzcWxpdGUzX2NvbHVtbl9ieXRlcyhzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKTsKICAgICAgICAgICAgICAgIGJ1ZmZlciA9IFB5QnVmZmVyX05ldyhuYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKCFidWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChQeU9iamVjdF9Bc1dyaXRlQnVmZmVyKGJ1ZmZlciwgJnJhd19idWZmZXIsICZuYnl0ZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtZW1jcHkocmF3X2J1ZmZlciwgc3FsaXRlM19jb2x1bW5fYmxvYihzZWxmLT5zdGF0ZW1lbnQtPnN0LCBpKSwgbmJ5dGVzKTsKICAgICAgICAgICAgICAgIGNvbnZlcnRlZCA9IGJ1ZmZlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgUHlUdXBsZV9TZXRJdGVtKHJvdywgaSwgY29udmVydGVkKTsKICAgIH0KCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIFB5X0RFQ1JFRihyb3cpOwogICAgICAgIHJvdyA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHJvdzsKfQoKUHlPYmplY3QqIF9xdWVyeV9leGVjdXRlKEN1cnNvciogc2VsZiwgaW50IG11bHRpcGxlLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIG9wZXJhdGlvbjsKICAgIFB5T2JqZWN0KiBvcGVyYXRpb25fYnl0ZXN0ciA9IE5VTEw7CiAgICBjaGFyKiBvcGVyYXRpb25fY3N0cjsKICAgIFB5T2JqZWN0KiBwYXJhbWV0ZXJzX2xpc3QgPSBOVUxMOwogICAgUHlPYmplY3QqIHBhcmFtZXRlcnNfaXRlciA9IE5VTEw7CiAgICBQeU9iamVjdCogcGFyYW1ldGVycyA9IE5VTEw7CiAgICBpbnQgaTsKICAgIGludCByYzsKICAgIFB5T2JqZWN0KiBmdW5jX2FyZ3M7CiAgICBQeU9iamVjdCogcmVzdWx0OwogICAgaW50IG51bWNvbHM7CiAgICBQWV9MT05HX0xPTkcgbGFzdHJvd2lkOwogICAgaW50IHN0YXRlbWVudF90eXBlOwogICAgUHlPYmplY3QqIGRlc2NyaXB0b3I7CiAgICBQeU9iamVjdCogc2Vjb25kX2FyZ3VtZW50ID0gTlVMTDsKICAgIGxvbmcgcm93Y291bnQgPSAwOwoKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pIHx8ICFjaGVja19jb25uZWN0aW9uKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgUHlfWERFQ1JFRihzZWxmLT5uZXh0X3Jvdyk7CiAgICBzZWxmLT5uZXh0X3JvdyA9IE5VTEw7CgogICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgLyogZXhlY3V0ZW1hbnkoKSAqLwogICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT08iLCAmb3BlcmF0aW9uLCAmc2Vjb25kX2FyZ3VtZW50KSkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsgCiAgICAgICAgfQoKICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG9wZXJhdGlvbikgJiYgIVB5VW5pY29kZV9DaGVjayhvcGVyYXRpb24pKSB7CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAib3BlcmF0aW9uIHBhcmFtZXRlciBtdXN0IGJlIHN0ciBvciB1bmljb2RlIik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKFB5SXRlcl9DaGVjayhzZWNvbmRfYXJndW1lbnQpKSB7CiAgICAgICAgICAgIC8qIGl0ZXJhdG9yICovCiAgICAgICAgICAgIFB5X0lOQ1JFRihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBwYXJhbWV0ZXJzX2l0ZXIgPSBzZWNvbmRfYXJndW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogc2VxdWVuY2UgKi8KICAgICAgICAgICAgcGFyYW1ldGVyc19pdGVyID0gUHlPYmplY3RfR2V0SXRlcihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBpZiAoIXBhcmFtZXRlcnNfaXRlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIGV4ZWN1dGUoKSAqLwogICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT3xPIiwgJm9wZXJhdGlvbiwgJnNlY29uZF9hcmd1bWVudCkpIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgICAgIH0KCiAgICAgICAgaWYgKCFQeVN0cmluZ19DaGVjayhvcGVyYXRpb24pICYmICFQeVVuaWNvZGVfQ2hlY2sob3BlcmF0aW9uKSkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm9wZXJhdGlvbiBwYXJhbWV0ZXIgbXVzdCBiZSBzdHIgb3IgdW5pY29kZSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIHBhcmFtZXRlcnNfbGlzdCA9IFB5TGlzdF9OZXcoMCk7CiAgICAgICAgaWYgKCFwYXJhbWV0ZXJzX2xpc3QpIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2Vjb25kX2FyZ3VtZW50ID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vjb25kX2FyZ3VtZW50ID0gUHlUdXBsZV9OZXcoMCk7CiAgICAgICAgICAgIGlmICghc2Vjb25kX2FyZ3VtZW50KSB7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUHlfSU5DUkVGKHNlY29uZF9hcmd1bWVudCk7CiAgICAgICAgfQogICAgICAgIGlmIChQeUxpc3RfQXBwZW5kKHBhcmFtZXRlcnNfbGlzdCwgc2Vjb25kX2FyZ3VtZW50KSAhPSAwKSB7CiAgICAgICAgICAgIFB5X0RFQ1JFRihzZWNvbmRfYXJndW1lbnQpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICBQeV9ERUNSRUYoc2Vjb25kX2FyZ3VtZW50KTsKCiAgICAgICAgcGFyYW1ldGVyc19pdGVyID0gUHlPYmplY3RfR2V0SXRlcihwYXJhbWV0ZXJzX2xpc3QpOwogICAgICAgIGlmICghcGFyYW1ldGVyc19pdGVyKSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzZWxmLT5zdGF0ZW1lbnQgIT0gTlVMTCkgewogICAgICAgIC8qIFRoZXJlIGlzIGFuIGFjdGl2ZSBzdGF0ZW1lbnQgKi8KICAgICAgICByYyA9IHN0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgfQoKICAgIGlmIChQeVN0cmluZ19DaGVjayhvcGVyYXRpb24pKSB7CiAgICAgICAgb3BlcmF0aW9uX2NzdHIgPSBQeVN0cmluZ19Bc1N0cmluZyhvcGVyYXRpb24pOwogICAgfSBlbHNlIHsKICAgICAgICBvcGVyYXRpb25fYnl0ZXN0ciA9IFB5VW5pY29kZV9Bc1VURjhTdHJpbmcob3BlcmF0aW9uKTsKICAgICAgICBpZiAoIW9wZXJhdGlvbl9ieXRlc3RyKSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBvcGVyYXRpb25fY3N0ciA9IFB5U3RyaW5nX0FzU3RyaW5nKG9wZXJhdGlvbl9ieXRlc3RyKTsKICAgIH0KCiAgICAvKiByZXNldCBkZXNjcmlwdGlvbiBhbmQgcm93Y291bnQgKi8KICAgIFB5X0RFQ1JFRihzZWxmLT5kZXNjcmlwdGlvbik7CiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICBzZWxmLT5kZXNjcmlwdGlvbiA9IFB5X05vbmU7CgogICAgUHlfREVDUkVGKHNlbGYtPnJvd2NvdW50KTsKICAgIHNlbGYtPnJvd2NvdW50ID0gUHlJbnRfRnJvbUxvbmcoLTFMKTsKICAgIGlmICghc2VsZi0+cm93Y291bnQpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHN0YXRlbWVudF90eXBlID0gZGV0ZWN0X3N0YXRlbWVudF90eXBlKG9wZXJhdGlvbl9jc3RyKTsKICAgIGlmIChzZWxmLT5jb25uZWN0aW9uLT5iZWdpbl9zdGF0ZW1lbnQpIHsKICAgICAgICBzd2l0Y2ggKHN0YXRlbWVudF90eXBlKSB7CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX1VQREFURToKICAgICAgICAgICAgY2FzZSBTVEFURU1FTlRfREVMRVRFOgogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9JTlNFUlQ6CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX1JFUExBQ0U6CiAgICAgICAgICAgICAgICBpZiAoIXNlbGYtPmNvbm5lY3Rpb24tPmluVHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBfY29ubmVjdGlvbl9iZWdpbihzZWxmLT5jb25uZWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9PVEhFUjoKICAgICAgICAgICAgICAgIC8qIGl0J3MgYSBEREwgc3RhdGVtZW50IG9yIHNvbWV0aGluZyBzaW1pbGFyCiAgICAgICAgICAgICAgICAgICAtIHdlIGJldHRlciBDT01NSVQgZmlyc3Qgc28gaXQgd29ya3MgZm9yIGFsbCBjYXNlcyAqLwogICAgICAgICAgICAgICAgaWYgKHNlbGYtPmNvbm5lY3Rpb24tPmluVHJhbnNhY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjb25uZWN0aW9uX2NvbW1pdChzZWxmLT5jb25uZWN0aW9uLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9TRUxFQ1Q6CiAgICAgICAgICAgICAgICBpZiAobXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHJvZ3JhbW1pbmdFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWW91IGNhbm5vdCBleGVjdXRlIFNFTEVDVCBzdGF0ZW1lbnRzIGluIGV4ZWN1dGVtYW55KCkuIik7CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jX2FyZ3MgPSBQeVR1cGxlX05ldygxKTsKICAgIGlmICghZnVuY19hcmdzKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5X0lOQ1JFRihvcGVyYXRpb24pOwogICAgaWYgKFB5VHVwbGVfU2V0SXRlbShmdW5jX2FyZ3MsIDAsIG9wZXJhdGlvbikgIT0gMCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHNlbGYtPnN0YXRlbWVudCkgewogICAgICAgICh2b2lkKXN0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnQpOwogICAgfQoKICAgIHNlbGYtPnN0YXRlbWVudCA9IChTdGF0ZW1lbnQqKWNhY2hlX2dldChzZWxmLT5jb25uZWN0aW9uLT5zdGF0ZW1lbnRfY2FjaGUsIGZ1bmNfYXJncyk7CiAgICBQeV9ERUNSRUYoZnVuY19hcmdzKTsKCiAgICBpZiAoIXNlbGYtPnN0YXRlbWVudCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHNlbGYtPnN0YXRlbWVudC0+aW5fdXNlKSB7CiAgICAgICAgUHlfREVDUkVGKHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgc2VsZi0+c3RhdGVtZW50ID0gUHlPYmplY3RfTmV3KFN0YXRlbWVudCwgJlN0YXRlbWVudFR5cGUpOwogICAgICAgIGlmICghc2VsZi0+c3RhdGVtZW50KSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIHJjID0gc3RhdGVtZW50X2NyZWF0ZShzZWxmLT5zdGF0ZW1lbnQsIHNlbGYtPmNvbm5lY3Rpb24sIG9wZXJhdGlvbik7CiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBzZWxmLT5zdGF0ZW1lbnQgPSAwOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0ZW1lbnRfcmVzZXQoc2VsZi0+c3RhdGVtZW50KTsKICAgIHN0YXRlbWVudF9tYXJrX2RpcnR5KHNlbGYtPnN0YXRlbWVudCk7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBwYXJhbWV0ZXJzID0gUHlJdGVyX05leHQocGFyYW1ldGVyc19pdGVyKTsKICAgICAgICBpZiAoIXBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBzdGF0ZW1lbnRfbWFya19kaXJ0eShzZWxmLT5zdGF0ZW1lbnQpOwoKICAgICAgICBzdGF0ZW1lbnRfYmluZF9wYXJhbWV0ZXJzKHNlbGYtPnN0YXRlbWVudCwgcGFyYW1ldGVycyk7CiAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIGlmIChidWlsZF9yb3dfY2FzdF9tYXAoc2VsZikgIT0gMCkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoT3BlcmF0aW9uYWxFcnJvciwgIkVycm9yIHdoaWxlIGJ1aWxkaW5nIHJvd19jYXN0X21hcCIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzZWxmLT5zdGF0ZW1lbnQtPnN0LCBzZWxmLT5jb25uZWN0aW9uKTsKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX0RPTkUgJiYgcmMgIT0gU1FMSVRFX1JPVykgewogICAgICAgICAgICByYyA9IHN0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBpZiAocmMgPT0gU1FMSVRFX1NDSEVNQSkgewogICAgICAgICAgICAgICAgcmMgPSBzdGF0ZW1lbnRfcmVjb21waWxlKHNlbGYtPnN0YXRlbWVudCwgcGFyYW1ldGVycyk7CiAgICAgICAgICAgICAgICBpZiAocmMgPT0gU1FMSVRFX09LKSB7CiAgICAgICAgICAgICAgICAgICAgcmMgPSBfc3FsaXRlX3N0ZXBfd2l0aF9idXN5aGFuZGxlcihzZWxmLT5zdGF0ZW1lbnQtPnN0LCBzZWxmLT5jb25uZWN0aW9uKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyYyA9PSBTUUxJVEVfUk9XIHx8IChyYyA9PSBTUUxJVEVfRE9ORSAmJiBzdGF0ZW1lbnRfdHlwZSA9PSBTVEFURU1FTlRfU0VMRUNUKSkgewogICAgICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgICAgIG51bWNvbHMgPSBzcWxpdGUzX2NvbHVtbl9jb3VudChzZWxmLT5zdGF0ZW1lbnQtPnN0KTsKICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKCiAgICAgICAgICAgIGlmIChzZWxmLT5kZXNjcmlwdGlvbiA9PSBQeV9Ob25lKSB7CiAgICAgICAgICAgICAgICBQeV9ERUNSRUYoc2VsZi0+ZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgc2VsZi0+ZGVzY3JpcHRpb24gPSBQeVR1cGxlX05ldyhudW1jb2xzKTsKICAgICAgICAgICAgICAgIGlmICghc2VsZi0+ZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWNvbHM7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IgPSBQeVR1cGxlX05ldyg3KTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2NyaXB0b3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgUHlUdXBsZV9TZXRJdGVtKGRlc2NyaXB0b3IsIDAsIF9idWlsZF9jb2x1bW5fbmFtZShzcWxpdGUzX2NvbHVtbl9uYW1lKHNlbGYtPnN0YXRlbWVudC0+c3QsIGkpKSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgMSwgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgMiwgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgMywgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgNCwgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgNSwgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOyBQeVR1cGxlX1NldEl0ZW0oZGVzY3JpcHRvciwgNiwgUHlfTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgUHlUdXBsZV9TZXRJdGVtKHNlbGYtPmRlc2NyaXB0aW9uLCBpLCBkZXNjcmlwdG9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHJjID09IFNRTElURV9ST1cpIHsKICAgICAgICAgICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHJvZ3JhbW1pbmdFcnJvciwgImV4ZWN1dGVtYW55KCkgY2FuIG9ubHkgZXhlY3V0ZSBETUwgc3RhdGVtZW50cy4iKTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGYtPm5leHRfcm93ID0gX2ZldGNoX29uZV9yb3coc2VsZik7CiAgICAgICAgfSBlbHNlIGlmIChyYyA9PSBTUUxJVEVfRE9ORSAmJiAhbXVsdGlwbGUpIHsKICAgICAgICAgICAgc3RhdGVtZW50X3Jlc2V0KHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBzZWxmLT5zdGF0ZW1lbnQgPSAwOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChzdGF0ZW1lbnRfdHlwZSkgewogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9VUERBVEU6CiAgICAgICAgICAgIGNhc2UgU1RBVEVNRU5UX0RFTEVURToKICAgICAgICAgICAgY2FzZSBTVEFURU1FTlRfSU5TRVJUOgogICAgICAgICAgICBjYXNlIFNUQVRFTUVOVF9SRVBMQUNFOgogICAgICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUwogICAgICAgICAgICAgICAgcm93Y291bnQgKz0gKGxvbmcpc3FsaXRlM19jaGFuZ2VzKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICAgICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCiAgICAgICAgICAgICAgICBQeV9ERUNSRUYoc2VsZi0+cm93Y291bnQpOwogICAgICAgICAgICAgICAgc2VsZi0+cm93Y291bnQgPSBQeUludF9Gcm9tTG9uZyhyb3djb3VudCk7CiAgICAgICAgfQoKICAgICAgICBQeV9ERUNSRUYoc2VsZi0+bGFzdHJvd2lkKTsKICAgICAgICBpZiAoc3RhdGVtZW50X3R5cGUgPT0gU1RBVEVNRU5UX0lOU0VSVCkgewogICAgICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCiAgICAgICAgICAgIGxhc3Ryb3dpZCA9IHNxbGl0ZTNfbGFzdF9pbnNlcnRfcm93aWQoc2VsZi0+Y29ubmVjdGlvbi0+ZGIpOwogICAgICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUwogICAgICAgICAgICBzZWxmLT5sYXN0cm93aWQgPSBQeUludF9Gcm9tTG9uZygobG9uZylsYXN0cm93aWQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgICAgICAgICAgc2VsZi0+bGFzdHJvd2lkID0gUHlfTm9uZTsKICAgICAgICB9CgogICAgICAgIGlmIChtdWx0aXBsZSkgewogICAgICAgICAgICByYyA9IHN0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgIH0KICAgICAgICBQeV9YREVDUkVGKHBhcmFtZXRlcnMpOwogICAgfQoKZXJyb3I6CiAgICBQeV9YREVDUkVGKG9wZXJhdGlvbl9ieXRlc3RyKTsKICAgIFB5X1hERUNSRUYocGFyYW1ldGVycyk7CiAgICBQeV9YREVDUkVGKHBhcmFtZXRlcnNfaXRlcik7CiAgICBQeV9YREVDUkVGKHBhcmFtZXRlcnNfbGlzdCk7CgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKHNlbGYpOwogICAgICAgIHJldHVybiAoUHlPYmplY3QqKXNlbGY7CiAgICB9Cn0KClB5T2JqZWN0KiBjdXJzb3JfZXhlY3V0ZShDdXJzb3IqIHNlbGYsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICByZXR1cm4gX3F1ZXJ5X2V4ZWN1dGUoc2VsZiwgMCwgYXJncyk7Cn0KClB5T2JqZWN0KiBjdXJzb3JfZXhlY3V0ZW1hbnkoQ3Vyc29yKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgcmV0dXJuIF9xdWVyeV9leGVjdXRlKHNlbGYsIDEsIGFyZ3MpOwp9CgpQeU9iamVjdCogY3Vyc29yX2V4ZWN1dGVzY3JpcHQoQ3Vyc29yKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIHNjcmlwdF9vYmo7CiAgICBQeU9iamVjdCogc2NyaXB0X3N0ciA9IE5VTEw7CiAgICBjb25zdCBjaGFyKiBzY3JpcHRfY3N0cjsKICAgIHNxbGl0ZTNfc3RtdCogc3RhdGVtZW50OwogICAgaW50IHJjOwogICAgUHlPYmplY3QqIHJlc3VsdDsKICAgIGludCBzdGF0ZW1lbnRfY29tcGxldGVkID0gMDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8iLCAmc2NyaXB0X29iaikpIHsKICAgICAgICByZXR1cm4gTlVMTDsgCiAgICB9CgogICAgaWYgKCFjaGVja190aHJlYWQoc2VsZi0+Y29ubmVjdGlvbikgfHwgIWNoZWNrX2Nvbm5lY3Rpb24oc2VsZi0+Y29ubmVjdGlvbikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoUHlTdHJpbmdfQ2hlY2soc2NyaXB0X29iaikpIHsKICAgICAgICBzY3JpcHRfY3N0ciA9IFB5U3RyaW5nX0FzU3RyaW5nKHNjcmlwdF9vYmopOwogICAgfSBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2soc2NyaXB0X29iaikpIHsKICAgICAgICBzY3JpcHRfc3RyID0gUHlVbmljb2RlX0FzVVRGOFN0cmluZyhzY3JpcHRfb2JqKTsKICAgICAgICBpZiAoIXNjcmlwdF9zdHIpIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICBzY3JpcHRfY3N0ciA9IFB5U3RyaW5nX0FzU3RyaW5nKHNjcmlwdF9zdHIpOwogICAgfSBlbHNlIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgInNjcmlwdCBhcmd1bWVudCBtdXN0IGJlIHVuaWNvZGUgb3Igc3RyaW5nLiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIGNvbW1pdCBmaXJzdCAqLwogICAgcmVzdWx0ID0gY29ubmVjdGlvbl9jb21taXQoc2VsZi0+Y29ubmVjdGlvbiwgTlVMTCk7CiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeV9ERUNSRUYocmVzdWx0KTsKCiAgICB3aGlsZSAoMSkgewogICAgICAgIGlmICghc3FsaXRlM19jb21wbGV0ZShzY3JpcHRfY3N0cikpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHN0YXRlbWVudF9jb21wbGV0ZWQgPSAxOwoKICAgICAgICByYyA9IHNxbGl0ZTNfcHJlcGFyZShzZWxmLT5jb25uZWN0aW9uLT5kYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRfY3N0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzY3JpcHRfY3N0cik7CiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+Y29ubmVjdGlvbi0+ZGIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgLyogZXhlY3V0ZSBzdGF0ZW1lbnQsIGFuZCBpZ25vcmUgcmVzdWx0cyBvZiBTRUxFQ1Qgc3RhdGVtZW50cyAqLwogICAgICAgIHJjID0gU1FMSVRFX1JPVzsKICAgICAgICB3aGlsZSAocmMgPT0gU1FMSVRFX1JPVykgewogICAgICAgICAgICByYyA9IF9zcWxpdGVfc3RlcF93aXRoX2J1c3loYW5kbGVyKHN0YXRlbWVudCwgc2VsZi0+Y29ubmVjdGlvbik7CiAgICAgICAgfQoKICAgICAgICBpZiAocmMgIT0gU1FMSVRFX0RPTkUpIHsKICAgICAgICAgICAgKHZvaWQpc3FsaXRlM19maW5hbGl6ZShzdGF0ZW1lbnQpOwogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+Y29ubmVjdGlvbi0+ZGIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgcmMgPSBzcWxpdGUzX2ZpbmFsaXplKHN0YXRlbWVudCk7CiAgICAgICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgICAgICBfc2V0ZXJyb3Ioc2VsZi0+Y29ubmVjdGlvbi0+ZGIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgIH0KCmVycm9yOgogICAgUHlfWERFQ1JFRihzY3JpcHRfc3RyKTsKCiAgICBpZiAoIXN0YXRlbWVudF9jb21wbGV0ZWQpIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHJvZ3JhbW1pbmdFcnJvciwgInlvdSBkaWQgbm90IHByb3ZpZGUgYSBjb21wbGV0ZSBTUUwgc3RhdGVtZW50Iik7CiAgICB9CgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlfSU5DUkVGKHNlbGYpOwogICAgICAgIHJldHVybiAoUHlPYmplY3QqKXNlbGY7CiAgICB9Cn0KClB5T2JqZWN0KiBjdXJzb3JfZ2V0aXRlcihDdXJzb3IgKnNlbGYpCnsKICAgIFB5X0lOQ1JFRihzZWxmKTsKICAgIHJldHVybiAoUHlPYmplY3QqKXNlbGY7Cn0KClB5T2JqZWN0KiBjdXJzb3JfaXRlcm5leHQoQ3Vyc29yICpzZWxmKQp7CiAgICBQeU9iamVjdCogbmV4dF9yb3dfdHVwbGU7CiAgICBQeU9iamVjdCogbmV4dF9yb3c7CiAgICBpbnQgcmM7CgogICAgaWYgKCFjaGVja190aHJlYWQoc2VsZi0+Y29ubmVjdGlvbikgfHwgIWNoZWNrX2Nvbm5lY3Rpb24oc2VsZi0+Y29ubmVjdGlvbikpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIXNlbGYtPm5leHRfcm93KSB7CiAgICAgICAgIGlmIChzZWxmLT5zdGF0ZW1lbnQpIHsKICAgICAgICAgICAgKHZvaWQpc3RhdGVtZW50X3Jlc2V0KHNlbGYtPnN0YXRlbWVudCk7CiAgICAgICAgICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgICAgICBzZWxmLT5zdGF0ZW1lbnQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBuZXh0X3Jvd190dXBsZSA9IHNlbGYtPm5leHRfcm93OwogICAgc2VsZi0+bmV4dF9yb3cgPSBOVUxMOwoKICAgIGlmIChzZWxmLT5yb3dfZmFjdG9yeSAhPSBQeV9Ob25lKSB7CiAgICAgICAgbmV4dF9yb3cgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oc2VsZi0+cm93X2ZhY3RvcnksICJPTyIsIHNlbGYsIG5leHRfcm93X3R1cGxlKTsKICAgICAgICBQeV9ERUNSRUYobmV4dF9yb3dfdHVwbGUpOwogICAgfSBlbHNlIHsKICAgICAgICBuZXh0X3JvdyA9IG5leHRfcm93X3R1cGxlOwogICAgfQoKICAgIHJjID0gX3NxbGl0ZV9zdGVwX3dpdGhfYnVzeWhhbmRsZXIoc2VsZi0+c3RhdGVtZW50LT5zdCwgc2VsZi0+Y29ubmVjdGlvbik7CiAgICBpZiAocmMgIT0gU1FMSVRFX0RPTkUgJiYgcmMgIT0gU1FMSVRFX1JPVykgewogICAgICAgIFB5X0RFQ1JFRihuZXh0X3Jvdyk7CiAgICAgICAgX3NldGVycm9yKHNlbGYtPmNvbm5lY3Rpb24tPmRiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAocmMgPT0gU1FMSVRFX1JPVykgewogICAgICAgIHNlbGYtPm5leHRfcm93ID0gX2ZldGNoX29uZV9yb3coc2VsZik7CiAgICB9CgogICAgcmV0dXJuIG5leHRfcm93Owp9CgpQeU9iamVjdCogY3Vyc29yX2ZldGNob25lKEN1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIFB5T2JqZWN0KiByb3c7CgogICAgcm93ID0gY3Vyc29yX2l0ZXJuZXh0KHNlbGYpOwogICAgaWYgKCFyb3cgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9CgogICAgcmV0dXJuIHJvdzsKfQoKUHlPYmplY3QqIGN1cnNvcl9mZXRjaG1hbnkoQ3Vyc29yKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIHJvdzsKICAgIFB5T2JqZWN0KiBsaXN0OwogICAgaW50IG1heHJvd3MgPSBzZWxmLT5hcnJheXNpemU7CiAgICBpbnQgY291bnRlciA9IDA7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aSIsICZtYXhyb3dzKSkgewogICAgICAgIHJldHVybiBOVUxMOyAKICAgIH0KCiAgICBsaXN0ID0gUHlMaXN0X05ldygwKTsKICAgIGlmICghbGlzdCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIGp1c3QgbWFrZSBzdXJlIHdlIGVudGVyIHRoZSBsb29wICovCiAgICByb3cgPSBQeV9Ob25lOwoKICAgIHdoaWxlIChyb3cpIHsKICAgICAgICByb3cgPSBjdXJzb3JfaXRlcm5leHQoc2VsZik7CiAgICAgICAgaWYgKHJvdykgewogICAgICAgICAgICBQeUxpc3RfQXBwZW5kKGxpc3QsIHJvdyk7CiAgICAgICAgICAgIFB5X0RFQ1JFRihyb3cpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKCsrY291bnRlciA9PSBtYXhyb3dzKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgewogICAgICAgIFB5X0RFQ1JFRihsaXN0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICB9Cn0KClB5T2JqZWN0KiBjdXJzb3JfZmV0Y2hhbGwoQ3Vyc29yKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlPYmplY3QqIHJvdzsKICAgIFB5T2JqZWN0KiBsaXN0OwoKICAgIGxpc3QgPSBQeUxpc3RfTmV3KDApOwogICAgaWYgKCFsaXN0KSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyoganVzdCBtYWtlIHN1cmUgd2UgZW50ZXIgdGhlIGxvb3AgKi8KICAgIHJvdyA9IChQeU9iamVjdCopUHlfTm9uZTsKCiAgICB3aGlsZSAocm93KSB7CiAgICAgICAgcm93ID0gY3Vyc29yX2l0ZXJuZXh0KHNlbGYpOwogICAgICAgIGlmIChyb3cpIHsKICAgICAgICAgICAgUHlMaXN0X0FwcGVuZChsaXN0LCByb3cpOwogICAgICAgICAgICBQeV9ERUNSRUYocm93KTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKICAgICAgICBQeV9ERUNSRUYobGlzdCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBsaXN0OwogICAgfQp9CgpQeU9iamVjdCogcHlzcWxpdGVfbm9vcChDb25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgLyogZG9uJ3QgY2FyZSwgcmV0dXJuIE5vbmUgKi8KICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpQeU9iamVjdCogY3Vyc29yX2Nsb3NlKEN1cnNvciogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIGlmICghY2hlY2tfdGhyZWFkKHNlbGYtPmNvbm5lY3Rpb24pIHx8ICFjaGVja19jb25uZWN0aW9uKHNlbGYtPmNvbm5lY3Rpb24pKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKHNlbGYtPnN0YXRlbWVudCkgewogICAgICAgICh2b2lkKXN0YXRlbWVudF9yZXNldChzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgIFB5X0RFQ1JFRihzZWxmLT5zdGF0ZW1lbnQpOwogICAgICAgIHNlbGYtPnN0YXRlbWVudCA9IDA7CiAgICB9CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7Cn0KCnN0YXRpYyBQeU1ldGhvZERlZiBjdXJzb3JfbWV0aG9kc1tdID0gewogICAgeyJleGVjdXRlIiwgKFB5Q0Z1bmN0aW9uKWN1cnNvcl9leGVjdXRlLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJFeGVjdXRlcyBhIFNRTCBzdGF0ZW1lbnQuIil9LAogICAgeyJleGVjdXRlbWFueSIsIChQeUNGdW5jdGlvbiljdXJzb3JfZXhlY3V0ZW1hbnksIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIlJlcGVhdGVkbHkgZXhlY3V0ZXMgYSBTUUwgc3RhdGVtZW50LiIpfSwKICAgIHsiZXhlY3V0ZXNjcmlwdCIsIChQeUNGdW5jdGlvbiljdXJzb3JfZXhlY3V0ZXNjcmlwdCwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiRXhlY3V0ZXMgYSBtdWx0aXBsZSBTUUwgc3RhdGVtZW50cyBhdCBvbmNlLiBOb24tc3RhbmRhcmQuIil9LAogICAgeyJmZXRjaG9uZSIsIChQeUNGdW5jdGlvbiljdXJzb3JfZmV0Y2hvbmUsIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiRmV0Y2hlcyBzZXZlcmFsIHJvd3MgZnJvbSB0aGUgcmVzdWx0c2V0LiIpfSwKICAgIHsiZmV0Y2htYW55IiwgKFB5Q0Z1bmN0aW9uKWN1cnNvcl9mZXRjaG1hbnksIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIkZldGNoZXMgYWxsIHJvd3MgZnJvbSB0aGUgcmVzdWx0c2V0LiIpfSwKICAgIHsiZmV0Y2hhbGwiLCAoUHlDRnVuY3Rpb24pY3Vyc29yX2ZldGNoYWxsLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkZldGNoZXMgb25lIHJvdyBmcm9tIHRoZSByZXN1bHRzZXQuIil9LAogICAgeyJjbG9zZSIsIChQeUNGdW5jdGlvbiljdXJzb3JfY2xvc2UsIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiQ2xvc2VzIHRoZSBjdXJzb3IuIil9LAogICAgeyJzZXRpbnB1dHNpemVzIiwgKFB5Q0Z1bmN0aW9uKXB5c3FsaXRlX25vb3AsIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIlJlcXVpcmVkIGJ5IERCLUFQSS4gRG9lcyBub3RoaW5nIGluIHB5c3FsaXRlLiIpfSwKICAgIHsic2V0b3V0cHV0c2l6ZSIsIChQeUNGdW5jdGlvbilweXNxbGl0ZV9ub29wLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJSZXF1aXJlZCBieSBEQi1BUEkuIERvZXMgbm90aGluZyBpbiBweXNxbGl0ZS4iKX0sCiAgICB7TlVMTCwgTlVMTH0KfTsKCnN0YXRpYyBzdHJ1Y3QgUHlNZW1iZXJEZWYgY3Vyc29yX21lbWJlcnNbXSA9CnsKICAgIHsiY29ubmVjdGlvbiIsIFRfT0JKRUNULCBvZmZzZXRvZihDdXJzb3IsIGNvbm5lY3Rpb24pLCBST30sCiAgICB7ImRlc2NyaXB0aW9uIiwgVF9PQkpFQ1QsIG9mZnNldG9mKEN1cnNvciwgZGVzY3JpcHRpb24pLCBST30sCiAgICB7ImFycmF5c2l6ZSIsIFRfSU5ULCBvZmZzZXRvZihDdXJzb3IsIGFycmF5c2l6ZSksIDB9LAogICAgeyJsYXN0cm93aWQiLCBUX09CSkVDVCwgb2Zmc2V0b2YoQ3Vyc29yLCBsYXN0cm93aWQpLCBST30sCiAgICB7InJvd2NvdW50IiwgVF9PQkpFQ1QsIG9mZnNldG9mKEN1cnNvciwgcm93Y291bnQpLCBST30sCiAgICB7InJvd19mYWN0b3J5IiwgVF9PQkpFQ1QsIG9mZnNldG9mKEN1cnNvciwgcm93X2ZhY3RvcnkpLCAwfSwKICAgIHtOVUxMfQp9OwoKc3RhdGljIGNoYXIgY3Vyc29yX2RvY1tdID0KUHlEb2NfU1RSKCJTUUxpdGUgZGF0YWJhc2UgY3Vyc29yIGNsYXNzLiIpOwoKUHlUeXBlT2JqZWN0IEN1cnNvclR5cGUgPSB7CiAgICAgICAgUHlPYmplY3RfSEVBRF9JTklUKE5VTEwpCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogb2Jfc2l6ZSAqLwogICAgICAgIE1PRFVMRV9OQU1FICIuQ3Vyc29yIiwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KICAgICAgICBzaXplb2YoQ3Vyc29yKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLwogICAgICAgIChkZXN0cnVjdG9yKWN1cnNvcl9kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFR8UHlfVFBGTEFHU19IQVZFX0lURVJ8UHlfVFBGTEFHU19CQVNFVFlQRSwgLyogdHBfZmxhZ3MgKi8KICAgICAgICBjdXJzb3JfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLwogICAgICAgIChnZXRpdGVyZnVuYyljdXJzb3JfZ2V0aXRlciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KICAgICAgICAoaXRlcm5leHRmdW5jKWN1cnNvcl9pdGVybmV4dCwgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLwogICAgICAgIGN1cnNvcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KICAgICAgICBjdXJzb3JfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCiAgICAgICAgKGluaXRwcm9jKWN1cnNvcl9pbml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCiAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLwp9OwoKZXh0ZXJuIGludCBjdXJzb3Jfc2V0dXBfdHlwZXModm9pZCkKewogICAgQ3Vyc29yVHlwZS50cF9uZXcgPSBQeVR5cGVfR2VuZXJpY05ldzsKICAgIHJldHVybiBQeVR5cGVfUmVhZHkoJkN1cnNvclR5cGUpOwp9Cg==