Lyogcm93LmMgLSBhbiBlbmhhbmNlZCB0dXBsZSBmb3IgZGF0YWJhc2Ugcm93cwogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDUtMjAwNiBHZXJoYXJkIEjkcmluZyA8Z2hAZ2hhZXJpbmcuZGU+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgogKgogKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAogKiB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAqIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogKiBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0CiAqIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICoKICogMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICogICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKICogICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAqICAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAqIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAqICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KICogMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KICovCgojaW5jbHVkZSAicm93LmgiCiNpbmNsdWRlICJjdXJzb3IuaCIKI2luY2x1ZGUgInNxbGl0ZWNvbXBhdC5oIgoKdm9pZCByb3dfZGVhbGxvYyhSb3cqIHNlbGYpCnsKICAgIFB5X1hERUNSRUYoc2VsZi0+ZGF0YSk7CiAgICBQeV9YREVDUkVGKHNlbGYtPmRlc2NyaXB0aW9uKTsKCiAgICBzZWxmLT5vYl90eXBlLT50cF9mcmVlKChQeU9iamVjdCopc2VsZik7Cn0KCmludCByb3dfaW5pdChSb3cqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKQp7CiAgICBQeU9iamVjdCogZGF0YTsKICAgIEN1cnNvciogY3Vyc29yOwoKICAgIHNlbGYtPmRhdGEgPSAwOwogICAgc2VsZi0+ZGVzY3JpcHRpb24gPSAwOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT08iLCAmY3Vyc29yLCAmZGF0YSkpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKCFQeU9iamVjdF9Jc0luc3RhbmNlKChQeU9iamVjdCopY3Vyc29yLCAoUHlPYmplY3QqKSZDdXJzb3JUeXBlKSkgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJpbnN0YW5jZSBvZiBjdXJzb3IgcmVxdWlyZWQgZm9yIGZpcnN0IGFyZ3VtZW50Iik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGlmICghUHlUdXBsZV9DaGVjayhkYXRhKSkgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJ0dXBsZSByZXF1aXJlZCBmb3Igc2Vjb25kIGFyZ3VtZW50Iik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIFB5X0lOQ1JFRihkYXRhKTsKICAgIHNlbGYtPmRhdGEgPSBkYXRhOwoKICAgIFB5X0lOQ1JFRihjdXJzb3ItPmRlc2NyaXB0aW9uKTsKICAgIHNlbGYtPmRlc2NyaXB0aW9uID0gY3Vyc29yLT5kZXNjcmlwdGlvbjsKCiAgICByZXR1cm4gMDsKfQoKUHlPYmplY3QqIHJvd19zdWJzY3JpcHQoUm93KiBzZWxmLCBQeU9iamVjdCogaWR4KQp7CiAgICBsb25nIF9pZHg7CiAgICBjaGFyKiBrZXk7CiAgICBpbnQgbml0ZW1zLCBpOwogICAgY2hhciogY29tcGFyZV9rZXk7CgogICAgY2hhciogcDE7CiAgICBjaGFyKiBwMjsKCiAgICBQeU9iamVjdCogaXRlbTsKCiAgICBpZiAoUHlJbnRfQ2hlY2soaWR4KSkgewogICAgICAgIF9pZHggPSBQeUludF9Bc0xvbmcoaWR4KTsKICAgICAgICBpdGVtID0gUHlUdXBsZV9HZXRJdGVtKHNlbGYtPmRhdGEsIF9pZHgpOwogICAgICAgIFB5X1hJTkNSRUYoaXRlbSk7CiAgICAgICAgcmV0dXJuIGl0ZW07CiAgICB9IGVsc2UgaWYgKFB5TG9uZ19DaGVjayhpZHgpKSB7CiAgICAgICAgX2lkeCA9IFB5TG9uZ19Bc0xvbmcoaWR4KTsKICAgICAgICBpdGVtID0gUHlUdXBsZV9HZXRJdGVtKHNlbGYtPmRhdGEsIF9pZHgpOwogICAgICAgIFB5X1hJTkNSRUYoaXRlbSk7CiAgICAgICAgcmV0dXJuIGl0ZW07CiAgICB9IGVsc2UgaWYgKFB5U3RyaW5nX0NoZWNrKGlkeCkpIHsKICAgICAgICBrZXkgPSBQeVN0cmluZ19Bc1N0cmluZyhpZHgpOwoKICAgICAgICBuaXRlbXMgPSBQeVR1cGxlX1NpemUoc2VsZi0+ZGVzY3JpcHRpb24pOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbml0ZW1zOyBpKyspIHsKICAgICAgICAgICAgY29tcGFyZV9rZXkgPSBQeVN0cmluZ19Bc1N0cmluZyhQeVR1cGxlX0dFVF9JVEVNKFB5VHVwbGVfR0VUX0lURU0oc2VsZi0+ZGVzY3JpcHRpb24sIGkpLCAwKSk7CiAgICAgICAgICAgIGlmICghY29tcGFyZV9rZXkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwMSA9IGtleTsKICAgICAgICAgICAgcDIgPSBjb21wYXJlX2tleTsKCiAgICAgICAgICAgIHdoaWxlICgxKSB7CiAgICAgICAgICAgICAgICBpZiAoKCpwMSA9PSAoY2hhcikwKSB8fCAoKnAyID09IChjaGFyKTApKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCgqcDEgfCAweDIwKSAhPSAoKnAyIHwgMHgyMCkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwMSsrOwogICAgICAgICAgICAgICAgcDIrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgqcDEgPT0gKGNoYXIpMCkgJiYgKCpwMiA9PSAoY2hhcikwKSkgewogICAgICAgICAgICAgICAgLyogZm91bmQgaXRlbSAqLwogICAgICAgICAgICAgICAgaXRlbSA9IFB5VHVwbGVfR2V0SXRlbShzZWxmLT5kYXRhLCBpKTsKICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihpdGVtKTsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsICJObyBpdGVtIHdpdGggdGhhdCBrZXkiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSBpZiAoUHlTbGljZV9DaGVjayhpZHgpKSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJzbGljZXMgbm90IGltcGxlbWVudGVkLCB5ZXQiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsICJJbmRleCBtdXN0IGJlIGludCBvciBzdHJpbmciKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KfQoKUHlfc3NpemVfdCByb3dfbGVuZ3RoKFJvdyogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIHJldHVybiBQeVR1cGxlX0dFVF9TSVpFKHNlbGYtPmRhdGEpOwp9CgpzdGF0aWMgaW50IHJvd19wcmludChSb3cqIHNlbGYsIEZJTEUgKmZwLCBpbnQgZmxhZ3MpCnsKICAgIHJldHVybiAoJlB5VHVwbGVfVHlwZSktPnRwX3ByaW50KHNlbGYtPmRhdGEsIGZwLCBmbGFncyk7Cn0KCgpQeU1hcHBpbmdNZXRob2RzIHJvd19hc19tYXBwaW5nID0gewogICAgLyogbXBfbGVuZ3RoICAgICAgICAqLyAobGVuZnVuYylyb3dfbGVuZ3RoLAogICAgLyogbXBfc3Vic2NyaXB0ICAgICAqLyAoYmluYXJ5ZnVuYylyb3dfc3Vic2NyaXB0LAogICAgLyogbXBfYXNzX3N1YnNjcmlwdCAqLyAob2Jqb2JqYXJncHJvYykwLAp9OwoKClB5VHlwZU9iamVjdCBSb3dUeXBlID0gewogICAgICAgIFB5T2JqZWN0X0hFQURfSU5JVChOVUxMKQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9iX3NpemUgKi8KICAgICAgICBNT0RVTEVfTkFNRSAiLlJvdyIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCiAgICAgICAgc2l6ZW9mKFJvdyksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KICAgICAgICAoZGVzdHJ1Y3Rvcilyb3dfZGVhbGxvYywgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCiAgICAgICAgKHByaW50ZnVuYylyb3dfcHJpbnQsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxUfFB5X1RQRkxBR1NfQkFTRVRZUEUsICAgICAgICAgLyogdHBfZmxhZ3MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCiAgICAgICAgKGluaXRwcm9jKXJvd19pbml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCiAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLwp9OwoKZXh0ZXJuIGludCByb3dfc2V0dXBfdHlwZXModm9pZCkKewogICAgUm93VHlwZS50cF9uZXcgPSBQeVR5cGVfR2VuZXJpY05ldzsKICAgIFJvd1R5cGUudHBfYXNfbWFwcGluZyA9ICZyb3dfYXNfbWFwcGluZzsKICAgIHJldHVybiBQeVR5cGVfUmVhZHkoJlJvd1R5cGUpOwp9Cg==