I2lmbmRlZiBCVF9CQVNJQ19HRU9NRVRSWV9PUEVSQVRJT05TX0hfSU5DTFVERUQKI2RlZmluZSBCVF9CQVNJQ19HRU9NRVRSWV9PUEVSQVRJT05TX0hfSU5DTFVERUQKCi8qISBcZmlsZSBidEdlb21ldHJ5T3BlcmF0aW9ucy5oCipcYXV0aG9yIEZyYW5jaXNjbyBMZX9uIE7famVyYQoKKi8KLyoKVGhpcyBzb3VyY2UgZmlsZSBpcyBwYXJ0IG9mIEdJTVBBQ1QgTGlicmFyeS4KCkZvciB0aGUgbGF0ZXN0IGluZm8sIHNlZSBodHRwOi8vZ2ltcGFjdC5zb3VyY2Vmb3JnZS5uZXQvCgpDb3B5cmlnaHQgKGMpIDIwMDcgRnJhbmNpc2NvIExlb24gTmFqZXJhLiBDLkMuIDgwMDg3MzcxLgplbWFpbDogcHJvamVjdGlsZW1hbkB5YWhvby5jb20KCgpUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCmluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQgZnJlZWx5LApzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgoKMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCjIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KKi8KCiNpbmNsdWRlICJidEJveENvbGxpc2lvbi5oIgoKCgoKCiNkZWZpbmUgUExBTkVESVJFUFNJTE9OIDAuMDAwMDAwMWYKI2RlZmluZSBQQVJBTEVMRU5PUk1BTFMgMC4wMDAwMDFmCgoKI2RlZmluZSBCVF9DTEFNUChudW1iZXIsbWludmFsLG1heHZhbCkgKG51bWJlcjxtaW52YWw/bWludmFsOihudW1iZXI+bWF4dmFsP21heHZhbDpudW1iZXIpKQoKLy8vIENhbGMgYSBwbGFuZSBmcm9tIGEgdHJpYW5nbGUgZWRnZSBhbiBhIG5vcm1hbC4gcGxhbmUgaXMgYSB2ZWM0ZgpTSU1EX0ZPUkNFX0lOTElORSB2b2lkIGJ0X2VkZ2VfcGxhbmUoY29uc3QgYnRWZWN0b3IzICYgZTEsY29uc3QgYnRWZWN0b3IzICYgIGUyLCBjb25zdCBidFZlY3RvcjMgJiBub3JtYWwsYnRWZWN0b3I0ICYgcGxhbmUpCnsKCWJ0VmVjdG9yMyBwbGFuZW5vcm1hbCA9IChlMi1lMSkuY3Jvc3Mobm9ybWFsKTsKCXBsYW5lbm9ybWFsLm5vcm1hbGl6ZSgpOwoJcGxhbmUuc2V0VmFsdWUocGxhbmVub3JtYWxbMF0scGxhbmVub3JtYWxbMV0scGxhbmVub3JtYWxbMl0sZTIuZG90KHBsYW5lbm9ybWFsKSk7Cn0KCgoKLy8qKioqKioqKioqKioqKioqKiBTRUdNRU5UIGFuZCBMSU5FIEZVTkNUSU9OUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLy8vCgovKiEgRmluZHMgdGhlIGNsb3Nlc3QgcG9pbnQoY3ApIHRvICh2KSBvbiBhIHNlZ21lbnQgKGUxLGUyKQogKi8KU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBidF9jbG9zZXN0X3BvaW50X29uX3NlZ21lbnQoCglidFZlY3RvcjMgJiBjcCwgY29uc3QgYnRWZWN0b3IzICYgdiwKCWNvbnN0IGJ0VmVjdG9yMyAgJmUxLGNvbnN0IGJ0VmVjdG9yMyAmZTIpCnsKICAgIGJ0VmVjdG9yMyBuID0gZTItZTE7CiAgICBjcCA9IHYgLSBlMTsKCWJ0U2NhbGFyIF9zY2FsYXIgPSBjcC5kb3Qobikvbi5kb3Qobik7CglpZihfc2NhbGFyIDwwLjBmKQoJewoJICAgIGNwID0gZTE7Cgl9CgllbHNlIGlmKF9zY2FsYXIgPjEuMGYpCgl7CgkgICAgY3AgPSBlMjsKCX0KCWVsc2UKCXsKCQljcCA9IF9zY2FsYXIqbiArIGUxOwoJfQp9CgoKLy8hIGxpbmUgcGxhbmUgY29sbGlzaW9uCi8qIQoqXHJldHVybgoJLTAgIGlmIHRoZSByYXkgbmV2ZXIgaW50ZXJzZWN0cwoJLTEgaWYgdGhlIHJheSBjb2xsaWRlcyBpbiBmcm9udAoJLTIgaWYgdGhlIHJheSBjb2xsaWRlcyBpbiBiYWNrCiovCgpTSU1EX0ZPUkNFX0lOTElORSBpbnQgYnRfbGluZV9wbGFuZV9jb2xsaXNpb24oCgljb25zdCBidFZlY3RvcjQgJiBwbGFuZSwKCWNvbnN0IGJ0VmVjdG9yMyAmIHZEaXIsCgljb25zdCBidFZlY3RvcjMgJiB2UG9pbnQsCglidFZlY3RvcjMgJiBwb3V0LAoJYnRTY2FsYXIgJnRwYXJhbSwKCWJ0U2NhbGFyIHRtaW4sIGJ0U2NhbGFyIHRtYXgpCnsKCglidFNjYWxhciBfZG90ZGlyID0gdkRpci5kb3QocGxhbmUpOwoKCWlmKGJ0RmFicyhfZG90ZGlyKTxQTEFORURJUkVQU0lMT04pCgl7CgkJdHBhcmFtID0gdG1heDsKCSAgICByZXR1cm4gMDsKCX0KCglidFNjYWxhciBfZGlzID0gYnRfZGlzdGFuY2VfcG9pbnRfcGxhbmUocGxhbmUsdlBvaW50KTsKCWNoYXIgcmV0dXJudmFsdWUgPSBfZGlzPDAuMGY/IDI6MTsKCXRwYXJhbSA9IC1fZGlzL19kb3RkaXI7CgoJaWYodHBhcmFtPHRtaW4pCgl7CgkJcmV0dXJudmFsdWUgPSAwOwoJCXRwYXJhbSA9IHRtaW47Cgl9CgllbHNlIGlmKHRwYXJhbT50bWF4KQoJewoJCXJldHVybnZhbHVlID0gMDsKCQl0cGFyYW0gPSB0bWF4OwoJfQoJcG91dCA9IHRwYXJhbSp2RGlyICsgdlBvaW50OwoJcmV0dXJuIHJldHVybnZhbHVlOwp9CgoKLy8hIEZpbmQgY2xvc2VzdCBwb2ludHMgb24gc2VnbWVudHMKU0lNRF9GT1JDRV9JTkxJTkUgdm9pZCBidF9zZWdtZW50X2NvbGxpc2lvbigKCWNvbnN0IGJ0VmVjdG9yMyAmIHZBMSwKCWNvbnN0IGJ0VmVjdG9yMyAmIHZBMiwKCWNvbnN0IGJ0VmVjdG9yMyAmIHZCMSwKCWNvbnN0IGJ0VmVjdG9yMyAmIHZCMiwKCWJ0VmVjdG9yMyAmIHZQb2ludEEsCglidFZlY3RvcjMgJiB2UG9pbnRCKQp7CiAgICBidFZlY3RvcjMgQUQgPSB2QTIgLSB2QTE7CiAgICBidFZlY3RvcjMgQkQgPSB2QjIgLSB2QjE7CiAgICBidFZlY3RvcjMgTiA9IEFELmNyb3NzKEJEKTsKICAgIGJ0U2NhbGFyIHRwID0gTi5sZW5ndGgyKCk7CgogICAgYnRWZWN0b3I0IF9NOy8vcGxhbmUKCiAgICBpZih0cDxTSU1EX0VQU0lMT04pLy9BUkUgUEFSQUxFTEUKICAgIHsKICAgIAkvL3Byb2plY3QgQiBvdmVyIEEKICAgIAlib29sIGludmVydF9iX29yZGVyID0gZmFsc2U7CiAgICAJX01bMF0gPSB2QjEuZG90KEFEKTsKICAgIAlfTVsxXSA9IHZCMi5kb3QoQUQpOwoKICAgIAlpZihfTVswXT5fTVsxXSkKICAgIAl7CiAgICAJCWludmVydF9iX29yZGVyICA9IHRydWU7CiAgICAJCUJUX1NXQVBfTlVNQkVSUyhfTVswXSxfTVsxXSk7CiAgICAJfQogICAgCV9NWzJdID0gdkExLmRvdChBRCk7CiAgICAJX01bM10gPSB2QTIuZG90KEFEKTsKICAgIAkvL21pZCBwb2ludHMKICAgIAlOWzBdID0gKF9NWzBdK19NWzFdKSowLjVmOwogICAgCU5bMV0gPSAoX01bMl0rX01bM10pKjAuNWY7CgogICAgCWlmKE5bMF08TlsxXSkKICAgIAl7CiAgICAJCWlmKF9NWzFdPF9NWzJdKQogICAgCQl7CiAgICAJCQl2UG9pbnRCID0gaW52ZXJ0X2Jfb3JkZXI/dkIxOnZCMjsKICAgIAkJCXZQb2ludEEgPSB2QTE7CiAgICAJCX0KICAgIAkJZWxzZSBpZihfTVsxXTxfTVszXSkKICAgIAkJewogICAgCQkJdlBvaW50QiA9IGludmVydF9iX29yZGVyP3ZCMTp2QjI7CiAgICAJCQlidF9jbG9zZXN0X3BvaW50X29uX3NlZ21lbnQodlBvaW50QSx2UG9pbnRCLHZBMSx2QTIpOwogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJdlBvaW50QSA9IHZBMjsKICAgIAkJCWJ0X2Nsb3Nlc3RfcG9pbnRfb25fc2VnbWVudCh2UG9pbnRCLHZQb2ludEEsdkIxLHZCMik7CiAgICAJCX0KICAgIAl9CiAgICAJZWxzZQogICAgCXsKICAgIAkJaWYoX01bM108X01bMF0pCiAgICAJCXsKICAgIAkJCXZQb2ludEIgPSBpbnZlcnRfYl9vcmRlcj92QjI6dkIxOwogICAgCQkJdlBvaW50QSA9IHZBMjsKICAgIAkJfQogICAgCQllbHNlIGlmKF9NWzNdPF9NWzFdKQogICAgCQl7CiAgICAJCQl2UG9pbnRBID0gdkEyOwogICAgCQkJYnRfY2xvc2VzdF9wb2ludF9vbl9zZWdtZW50KHZQb2ludEIsdlBvaW50QSx2QjEsdkIyKTsKICAgIAkJfQogICAgCQllbHNlCiAgICAJCXsKICAgIAkJCXZQb2ludEIgPSBpbnZlcnRfYl9vcmRlcj92QjE6dkIyOwogICAgCQkJYnRfY2xvc2VzdF9wb2ludF9vbl9zZWdtZW50KHZQb2ludEEsdlBvaW50Qix2QTEsdkEyKTsKICAgIAkJfQogICAgCX0KICAgIAlyZXR1cm47CiAgICB9CgogICAgTiA9IE4uY3Jvc3MoQkQpOwogICAgX00uc2V0VmFsdWUoTlswXSxOWzFdLE5bMl0sdkIxLmRvdChOKSk7CgoJLy8gZ2V0IHBvaW50IEEgYXMgdGhlIHBsYW5lIGNvbGxpc2lvbiBwb2ludAogICAgYnRfbGluZV9wbGFuZV9jb2xsaXNpb24oX00sQUQsdkExLHZQb2ludEEsdHAsYnRTY2FsYXIoMCksIGJ0U2NhbGFyKDEpKTsKCiAgICAvKkNsb3Nlc3QgcG9pbnQgb24gc2VnbWVudCovCiAgICB2UG9pbnRCID0gdlBvaW50QSAtIHZCMTsKCXRwID0gdlBvaW50Qi5kb3QoQkQpOwoJdHAvPSBCRC5kb3QoQkQpOwoJdHAgPSBCVF9DTEFNUCh0cCwwLjBmLDEuMGYpOwoKCXZQb2ludEIgPSB0cCpCRCArIHZCMTsKfQoKCgoKCiNlbmRpZiAvLyBHSU1fVkVDVE9SX0hfSU5DTFVERUQK