LyoKICogIE1HdG9vbC0xLjMKICogIEZpbGU6IE1HdG9vbC5jCiAqICBNYWludGFpbmVyOiBLaXJrQE1vcmdlbkdyYXVlbgogKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KLyogdGhlIG9yaWdpbmFsIFh0b29sIGlzIGNvcHlyaWdodGVkIGJ5IEh5cCAqLwovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgojcHJhZ21hIHN0cmljdF90eXBlcwoKaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKCiNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CiNpZiAhZGVmaW5lZChRVUVSWUNBQ0hFRCkKI2RlZmluZSBRVUVSWUNBQ0hFRCA0MDk2CiNlbmRpZgojaWYgIWRlZmluZWQgKFNFVENBQ0hFRCkKI2RlZmluZSBTRVRDQUNIRUQgNDA5NgojZW5kaWYKI2luY2x1ZGUgPG1vdmluZy5oPgojaW5jbHVkZSAiL3NlY3VyZS93aXpsZXZlbHMuaCIKI2luY2x1ZGUgIi9zZWN1cmUvY29uZmlnLmgiCiNpbmNsdWRlIDx1c2VyaW5mby5oPgojaW5jbHVkZSA8ZGVmaW5lcy5oPgoKI2luY2x1ZGUgIk1HdG9vbC90b29sLmgiCgojaW5jbHVkZSAiTUd0b29sL3Rvb2xsaWIuaCIKCiNkZWZpbmUgWERCRyAxCgpub3NhdmUgb2JqZWN0ICBjbG9uZXI7Cm5vc2F2ZSBvYmplY3QgIG1zZ3RvPU5VTEw7Cm5vc2F2ZSBzdHJpbmcgKm1hbnBhdGg9KHtUT09MX1BBVEgrIi9tYW4uZC8iLAoJCQkgIi9kb2MvZWZ1bi8iLAoJCQkgIi9kb2MvbGZ1bi8iLAoJCQkgIi9kb2Mvdy8iLAoJCQkgIi9kb2MvaGVscGRpci8iLAoJCQkgIi9kb2MvTFBDLyIsCgkJCSAiL2RvYy9zdGQvIiwKCQkJICIvZG9jL2NvbmNlcHRzLyIsCgkJCSAiIn0pOwpub3NhdmUgc3RyaW5nICBtb3JlZmlsZT1OVUxMOwpub3NhdmUgc3RyaW5nICpzY3JpcHRsaW5lPU5VTEw7Cm5vc2F2ZSBzdHJpbmcgKmhpc3Rvcnk9YWxsb2NhdGUoTUFYX0hJU1RPUlkpOwpub3NhdmUgaW50ICAgICBtb3JlZmxhZz1GQUxTRTsKbm9zYXZlIGludCAgICAgbW9yZW9mZnNldD0xOwpub3NhdmUgaW50ICAgICB0ZXJtPU5VTEw7Cm5vc2F2ZSBpbnQgICAgIHNjcmlwdHNpemU9TlVMTDsKbm9zYXZlIGludCAgICAgbm9zdG9yZT1GQUxTRTsKbm9zYXZlIGludCAgICAgeGxpZ2h0PTA7Cm5vc2F2ZSBpbnQgICAgIHBpcGVfaW49RkFMU0U7Cm5vc2F2ZSBpbnQgICAgIHBpcGVfb3V0PUZBTFNFOwpub3NhdmUgaW50ICAgICBwaXBlX292cj1UUlVFOwpub3NhdmUgc3RyaW5nICBwaXBlX2lmPU5VTEw7Cm5vc2F2ZSBzdHJpbmcgIHBpcGVfb2Y9TlVMTDsKbm9zYXZlIGludCAgICAgeHRrPUZBTFNFOwpub3NhdmUgbWFwcGluZyB2YXJpYWJsZT0oW10pOwpub3NhdmUgc3RyaW5nICpjbWRzOwpwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGxpbmVfYnVmZmVyPShbXSk7CnByaXZhdGUgbm9zYXZlIHN0cmluZyBsaW5lX2J1ZmZlcl9uYW1lPSIiOwpwcml2YXRlIG5vc2F2ZSBzdHJpbmcgbW9yZV9zZWFyY2hleHByPSIiOwppbnQgICAgbW9yZWxpbmVzPU1PUkVfTElORVM7CmludCAgICBtb2RpPShNT0RFX0ZJUlNUfE1PREVfUFJPVEVDVHxNT0RFX1NIT1JUKTsKCiNpbmNsdWRlICJNR3Rvb2wvdG9vbGxpYi5jIgojaW5jbHVkZSAiTUd0b29sL3Rvb2xjbWQuYyIKCiNkZWZpbmUgU2FmZVJldHVybih4KSBcCnsgXAogIGNtZHM9KHt9KTsgXAogIHBpcGVfaW49RkFMU0U7IFwKICBwaXBlX29mPU5VTEw7IFwKICBwaXBlX292cj1UUlVFOyBcCiAgcGlwZV9vdXQ9RkFMU0U7IFwKICBwaXBlX29mPU5VTEw7IFwKICByZXR1cm4gKHgpOyBcCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBjaGVjayBzb21lIHNlY3VyaXR5IGFzcGVjdHMKICovCgpzdGF0aWMgaW50IHNlY3VyaXR5KCkKewogIG9iamVjdCBwcmV2OwogCiAgaWYoIHByb2Nlc3NfY2FsbCgpIHx8IGdldHVpZCgpIT1nZXR1aWQoY2xvbmVyKSApIHJldHVybiBGQUxTRTsgLy8gUnVtYXRhCgogIFRLKCJVSUQ6ICIrZ2V0dWlkKE1FKSsiIGNsb25lcjoiK2dldHVpZChjbG9uZXIpKTsKLy8gIFRLKCJwcmV2OiAiK29iamVjdF9uYW1lKFBSRVYpKyIgbWU6IitvYmplY3RfbmFtZShNRSkpOwogIGlmKHByZXY9UFJFVikKICB7CiAgICBpZighY2xvbmVyKQogICAgICByZXR1cm4gVFJVRTsKICAgIGlmKGdldHVpZChwcmV2KT09Uk9PVElEfHxJU19BUkNIKHByZXYpKQogICAgICByZXR1cm4gVFJVRTsKICAgIGlmKHByZXY9PU1FKQogICAgICByZXR1cm4gVFJVRTsKICAgIHJldHVybiBzZWN1cmVfbGV2ZWwoKT49cXVlcnlfd2l6X2xldmVsKGNsb25lcik7IC8vIFJ1bWF0YQogICAgLy9yZXR1cm4gZ2V0dWlkKHByZXYpPT1nZXR1aWQoKSYmZ2V0ZXVpZChwcmV2KT09Z2V0ZXVpZCgpJiZjbG9uZXI9PVJUUDsKICB9CiAgZWxzZQogICAgcmV0dXJuIGNsb25lcj09TlVMTDsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG93biB3cml0ZSBmdW5jdGlvbgogKi8KCnN0YXRpYyBpbnQgV3JpdGUoc3RyaW5nIHN0cikKewogIGlmKCFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIikKICAgIHJldHVybiBGQUxTRTsKICBpZighY2xvbmVyICYmIG9iamVjdHAodGhpc19wbGF5ZXIoKSkpCiAgICB3cml0ZShzdHIpOwogIGVsc2UKICAgIHRlbGxfb2JqZWN0KGNsb25lciwgc3RyKTsKICByZXR1cm4gVFJVRTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG93biBjb21tYW5kIGZ1bmN0aW9uCiAqLwoKc3RhdGljIGludCBDb21tYW5kKHN0cmluZyBzdHIpCnsKICBpbnQgaTsKICBUSygiQ29tbWFuZDogc3RyOiAiKyhzdHI/c3RyOiIoTlVMTCkiKSk7CiAgbm9zdG9yZSsrOwogIGlmKE1PREUoTU9ERV9FQ0hPKSkKICAgIFdMTigiRG9pbmc6ICIrc3RyKTsKICBpPShpbnQpY2xvbmVyLT5jb21tYW5kX21lKHN0cik7CiAgbm9zdG9yZS0tOwogIHJldHVybiBpOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogb2JqZWN0IHNlYXJjaGluZwogKi8KCnN0YXRpYyB2YXJhcmdzIG9iamVjdCBYRmluZE9iaihzdHJpbmcgc3RyLCBpbnQgc2lsZW50KQp7CiAgb2JqZWN0IG9iaiwgZW52OwogIHN0cmluZyAqc3RyczsKICBpbnQgaSwgcywgY250OwogIAogIGlmKCFzdHIpCiAgICByZXR1cm4gTlVMTDsKICBUSygiWEZpbmRPYmo6IHN0cjogIisoc3RyP3N0cjoiKE5VTEwpIikpOwogIGVudj1FTlYoY2xvbmVyKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCAiXFwuIiwisDAxIik7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwgIlxcXiIsICKwMDIiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCAiXFwkIiwgIrAwMyIpOwogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICJcXFxcIiwgIlxcIik7CiAgaWYgKGZpbmRfb2JqZWN0KHN0cikpIHJldHVybiBmaW5kX29iamVjdChzdHIpOwogIGlmIChmaWxlX3NpemUoc3RyKT4xKSB7CiAgICAgcmV0dXJuIGxvYWRfb2JqZWN0KHN0cik7CiAgfQogIHM9c2l6ZW9mKHN0cnM9c3RyaXBfZXhwbG9kZShzdHIsICIuIikpOwogIHdoaWxlKHMtLSkKICB7CiAgICBpZihzdHJzW2ldPT0ibSJ8fHN0cnNbaV09PSJtZSIpCiAgICAgIHN0cnNbaV09Uk5BTUUoY2xvbmVyKTsKICAgIGVsc2UgaWYoc3Ryc1tpXT09ImgifHxzdHJzW2ldPT0iaGVyZSIpCiAgICAgIHN0cnNbaV09b2JqZWN0X25hbWUoRU5WKGNsb25lcikpOwogICAgaWYob2JqPUZpbmRPYmooc3Ryc1tpKytdLGVudiwoc2lsZW50PzE6MCkpKQogICAgICBlbnY9b2JqOwogICAgZWxzZQogICAgICBicmVhazsKICB9CiAgcmV0dXJuIG9iajsKfQoKc3RhdGljIHZhcmFyZ3Mgb2JqZWN0IEZpbmRPYmooc3RyaW5nIHN0ciwgb2JqZWN0IGVudiwgaW50IHNpbGVudCkKewogIG9iamVjdCBvYmosICppbnY7CiAgc3RyaW5nIHRtcDsKICBpbnQgbnVtLCBlOwogIAogIGlmICghc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSB8fCAhb2JqZWN0cChlbnYpKQogICAgcmV0dXJuIE5VTEw7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwgIrAwMSIsICIuIik7CiAgd2hpbGUoc3RyW2UrK109PSdeJykKICAgIDsKICBzdHI9c3RyWy0tZS4uPDFdOwogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICKwMDIiLCAiXiIpOwogIGlmKG9iaj1WYXJUb09iaihzdHIpKQogICAgOwogIGVsc2UgaWYoc3RyWzBdPT0nAycpCiAgICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCAisDAzIiwgIiQiKTsKICBlbHNlIGlmKHNzY2FuZihzdHIsICIlZCIsIG51bSkmJihpbnY9YWxsX2ludmVudG9yeShlbnYpKSkKICB7CiAgICBpZihudW0+MCYmbnVtPD1zaXplb2YoaW52KSkKICAgICAgb2JqPWludltudW0tMV07CiAgICBlbHNlCiAgICB7CiAgICAgIFdETE4oIlNwZWNpZmllZCBvYmplY3QgbnVtYmVyIG91dCBvZiByYW5nZSBbMS0iK3NpemVvZihpbnYpKyJdIik7CiAgICAgIHJldHVybiBOVUxMOwogICAgfQogIH0KICBpZihvYmp8fChvYmo9cHJlc2VudChzdHIsIGVudikpfHwKICAgICAob2JqPWZpbmRfcGxheWVyKExPV0VSKHN0cikpKXx8CiAgICAgKG9iaj1maW5kX2xpdmluZyhzdHIpKXx8CiAgICAgKG9iaj1maW5kX29iamVjdChsb25nX3BhdGgoc3RyKSkpKQogIHsKICAgIHdoaWxlKGUtLSkKICAgIHsKICAgICAgaWYoIShvYmo9RU5WKG9iaikpKQogICAgICB7CglXKCJTcGVjaWZpZWQgb2JqZWN0IGhhcyBubyBlbnZpcm9ubWVudCBbIik7Cgl3aGlsZShlLS0pCgkgIFcoIl4iKTsKCVdETE4oc3RyKyJdIik7CglyZXR1cm4gTlVMTDsKICAgICAgfQogICAgfQogIH0KICBlbHNlCiAgICBpZighc2lsZW50KQogICAgICBXRExOKCJTcGVjaWZpZWQgb2JqZWN0IGRvZXMgbm90IGV4aXN0IFsiK3N0cisiXSIpOwogIHJldHVybiBvYmo7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBvYmplY3QgdmFyaWFibGUgaGFuZGxpbmcKICovCgpzdGF0aWMgb2JqZWN0IFZhclRvT2JqKHN0cmluZyBzdHIpCnsKICBpZiAoIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikgfHwgc3RyWzBdIT0nJCcpCiAgICByZXR1cm4gTlVMTDsKICBzd2l0Y2goc3RyKQogIHsKICAgIGNhc2UgIiRtIjoKICAgIGNhc2UgIiRtZSI6CiAgICByZXR1cm4gY2xvbmVyOwogICAgY2FzZSAiJGgiOgogICAgY2FzZSAiJGhlcmUiOgogICAgcmV0dXJuIEVOVihjbG9uZXIpOwogICAgZGVmYXVsdDoKICAgIHJldHVybiB2YXJpYWJsZVtzdHJbMS4uPDFdXTsKICB9CiAgcmV0dXJuKE5VTEwpOyAvL25ldmVyIHJlYWNoZWQKfQoKc3RhdGljIHN0cmluZyBWYXJUb0ZpbGUoc3RyaW5nIHN0cikKewogIHJldHVybiBzb3VyY2VfZmlsZV9uYW1lKFZhclRvT2JqKHN0cikpOwp9CgpzdGF0aWMgc3RyaW5nIFZhclRvUHVyZUZpbGUoc3RyaW5nIHN0cikKewogIHJldHVybiBwdXJlX2ZpbGVfbmFtZShWYXJUb09iaihzdHIpKTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG9iamVjdCBkZXNjcmlwdGlvbiBwcmludGluZwogKi8KCnN0YXRpYyB2b2lkIFByaW50T2JqKG9iamVjdCBvYmosIHN0cmluZyBmaWxlKQp7CiAgb2JqZWN0IGl0ZW0sIHRtcDsKICBzdHJpbmcgc3RyOwogIGludCBpOwoKICBTRUNVUkUxKCk7CiAgaWYoIW9iaikKICAgIHJldHVybjsKICBQcmludFNob3J0KCJTaG9ydDogIiwgb2JqLCBmaWxlKTsKICBpZighZmlsZXx8ZmlsZT09IiIpCiAgICBXTE4oIkxvbmcgOiIpOwogIGVsc2UKICAgIHdyaXRlX2ZpbGUoZmlsZSwiTG9uZyA6XG4iKTsKICBpZihxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikpCiAgICBzdHI9Y2FwaXRhbGl6ZShnZXR1aWQob2JqKSk7CiAgZWxzZQogIHsKICAgIGlmKG9iamVjdF9uYW1lKG9iailbMC4uMjZdPT0iL2QvdW50ZXJ3ZWx0L29iamVrdGUvdGVkZHkjIiAmJgogICAgICAgSVNfQVJDSCh0aGlzX2ludGVyYWN0aXZlKCkpKQogICAgICBzdHI9IkVpbiBUZWRkeSAoc3R1bW0pIjsKICAgIGVsc2UKICAgIHsKICAgICAgaWYoc3RyPShzdHJpbmcpb2JqLT5RdWVyeVByb3AoUF9JTlRfTE9ORykpCgk7CiAgICAgIGVsc2UgaWYoc3RyPShzdHJpbmcpb2JqLT5RdWVyeVByb3AoUF9MT05HKSkKCTsKICAgICAgZWxzZQoJc3RyPSItIG5vIGxvbmcgZGVzY3JpcHRpb24gLVxuIjsKICAgIH0KICB9CiAgaWYoIWZpbGV8fGZpbGU9PSIiKQogICAgVyhzdHIpOwogIGVsc2UKICAgIHdyaXRlX2ZpbGUoZmlsZSxzdHIpOwogIEZPUkFMTChpdGVtLCBvYmopCiAgewogICAgaWYoIWkpCiAgICAgIGlmKCFmaWxlfHxmaWxlPT0iIikKCVdMTigiQ29udGVudDoiKTsKICAgICAgZWxzZQoJd3JpdGVfZmlsZShmaWxlLCJDb250ZW50OlxuIik7CiAgICBQcmludFNob3J0KEFSSUdIVCgrK2krIi4gIiwgNCwgIiAiKSwgaXRlbSwgZmlsZSk7CiAgfQp9CgpzdGF0aWMgc3RyaW5nIE9iakZpbGUob2JqZWN0IG9iaikKewogIHJldHVybiAiWyIrc2hvcnRfcGF0aChvYmplY3RfbmFtZShvYmopKSsiXSI7Cn0KCnN0YXRpYyB2YXJhcmdzIHZvaWQgUHJpbnRTaG9ydChzdHJpbmcgcHJlLCBvYmplY3Qgb2JqLCBzdHJpbmcgZmlsZSkKewogIHN0cmluZyBzdHI7CgogIFNFQ1VSRTEoKTsKICBpZighb2JqKQogICAgcmV0dXJuOwogIGlmKE1PREUoTU9ERV9TSE9SVCkpCiAgewogICAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2JqKSkKICAgICAgc3RyPWNhcGl0YWxpemUoZ2V0dWlkKG9iaikpOwogICAgZWxzZQogICAgewogICAgICBpZighKChzdHI9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX0lOVF9TSE9SVCkpfHwKCSAgIChzdHI9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX1NIT1JUKSkpKQoJaWYoaXNfcGxheWVyKG9iaikpCgkgIHN0cj1DUk5BTUUob2JqKSsiIChpbnZpc2libGUpIjsKCWVsc2UKCSAgc3RyPSItIG5vIHNob3J0IGRlc2NyaXB0aW9uIC0iOwogICAgfQogICAgc3RyPUFMRUZUKHNwcmludGYoIiVPICIsc3RyKSwgMzQsICIuIikrIiAiOwogIH0KICBlbHNlCiAgICBzdHI9IiI7CiAgaWYoaW50ZXJhY3RpdmUob2JqKSkKICAgIHN0cis9ImkiOwogIGVsc2UgaWYobGl2aW5nKG9iaikpCiAgICBzdHIrPSJsIjsKICBlbHNlCiAgICBzdHIrPSIuIjsKICBzdHIrPShzaGFkb3cob2JqLCAwKSA/ICJzIiA6ICIuIik7CiAgaWYoIWZpbGV8fGZpbGU9PSIiKQogICAgV0xOKChwcmUrQ0FQKHN0cikrIiAiK09iakZpbGUob2JqKSlbMC4uNzldKTsKICBlbHNlCiAgICB3cml0ZV9maWxlKGZpbGUsKHByZStDQVAoc3RyKSsiICIrT2JqRmlsZShvYmopKVswLi43OV0rIlxuIik7Cn0KCnN0YXRpYyB2YXJhcmdzIHZvaWQgRGVlcFByaW50U2hvcnQob2JqZWN0IGVudiwgaW50IGluZGVudCwgc3RyaW5nIHByZSwgc3RyaW5nIGZpbGUpCnsKICBpbnQgaTsKICBvYmplY3QgaXRlbTsKICBzdHJpbmcgc3RyOwogIAogIFNFQ1VSRTEoKTsKICBpZighZW52KQogICAgcmV0dXJuOwogIGZvcihpPWluZGVudCxzdHI9IiI7IGktLTsgc3RyKz0iICAiKTsKICBpZihwcmUpCiAgICBzdHIrPXByZTsKICBpZighZmlsZXx8ZmlsZT09IiIpCiAgICBXKHN0cik7CiAgZWxzZQogICAgd3JpdGVfZmlsZShmaWxlLHN0cik7CiAgaSsrOwogIFByaW50U2hvcnQoIiIsZW52LGZpbGUpOwogIEZPUkFMTChpdGVtLCBlbnYpCiAgICBEZWVwUHJpbnRTaG9ydChpdGVtLGluZGVudCsxLEFSSUdIVCgoKytpKSsiLiAiLDQsIiAiKSxmaWxlKTsKfQoKc3RhdGljIHN0cmluZyBicmVha19zdHJpbmdfaGFyZChzdHJpbmcgc3RyLCBpbnQgbGVuLCBzdHJpbmcgcHJlKQp7CiAgaW50IHMscCx0OwogIHN0cmluZyB0bXA7CgogIGlmKCFzdHJ8fCEocz1zaXplb2Yoc3RyKSkpCiAgICByZXR1cm4gIiI7CiAgdD1sZW4tKHA9c2l6ZW9mKHByZSkpLTE7CgogIHRtcD0iIjsKICB3aGlsZShwK3M+bGVuKQogIHsKICAgIHRtcCs9cHJlK3N0clswLi50XSsiXG4iOwoJc3RyPXN0clt0KzEuLl07CglzLT10OwogIH0KICBpZihzaXplb2Yoc3RyKSkKICAgIHRtcCs9cHJlK3N0clswLi5dKyJcbiI7CiAgcmV0dXJuIHRtcDsKfQogIApzdGF0aWMgdm9pZCBkcHJvcChzdHJpbmcga2V5LCBtaXhlZCBkYXRhLCBvYmplY3Qgb2JqKQp7CiAgaWYocGlwZV9vdXQmJnBpcGVfb2YpCiAgICB3cml0ZV9maWxlKHBpcGVfb2YsYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKG9iai0+UXVlcnlQcm9wKGtleSksTUFYX1JFQ1VSU0lPTiksNzgsQUxFRlQoa2V5KyIgIiwxOCwiLiIpKyIgPSAiKSk7CiAgZWxzZQogICAgVyhicmVha19zdHJpbmdfaGFyZChtaXhlZF90b19zdHJpbmcob2JqLT5RdWVyeVByb3Aoa2V5KSxNQVhfUkVDVVJTSU9OKSw3OCxBTEVGVChrZXkrIiAiLDE4LCIuIikrIiA9ICIpKTsKfQoKc3RhdGljIHN0cmluZyBwcm9wZmxhZ3Moc3RyaW5nIGtleSwgb2JqZWN0IG9iKQp7CiAgaW50IHRtcDsKICBzdHJpbmcgKmZsYWdzOwogIHRtcD0oaW50KW9iLT5RdWVyeShrZXksMSk7CiAgZmxhZ3M9KHt9KTsKICB0bXAmU0FWRSA/CSAgICAgICBmbGFncys9KHsiU0FWIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmUFJPVEVDVEVEID8gICAgICBmbGFncys9KHsiUFJPIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmU0VDVVJFRCA/ICAgICAgICBmbGFncys9KHsiU0VDIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmTk9TRVRNRVRIT0QgPyAgICBmbGFncys9KHsiTlNNIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmU0VUTU5PVEZPVU5EID8gICBmbGFncys9KHsiU01OIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmUVVFUllNTk9URk9VTkQgPyBmbGFncys9KHsiUU1OIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmUVVFUllDQUNIRUQgPyAgICBmbGFncys9KHsiUUNBIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICB0bXAmU0VUQ0FDSEVEID8gICAgICBmbGFncys9KHsiU0NBIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKICByZXR1cm4gIiIraW1wbG9kZShmbGFncywifCIpOwp9CgpzdGF0aWMgdm9pZCBkcHJvcDIoc3RyaW5nIGtleSwgbWl4ZWQgZGF0YSwgb2JqZWN0IG9iKQp7CiAgaWYocGlwZV9vdXQmJnBpcGVfb2YpCiAgICB3cml0ZV9maWxlKHBpcGVfb2YsYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKHByb3BmbGFncyhrZXksb2IpLE1BWF9SRUNVUlNJT04pLDc4LEFMRUZUKGtleSsiICIsMTgsIi4iKSsiID0gIikpOwogIGVsc2UKICAgIFcoYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKHByb3BmbGFncyhrZXksb2IpLE1BWF9SRUNVUlNJT04pLDc4LEFMRUZUKGtleSsiICIsMTgsIi4iKSsiID0gIikpOwp9CgpzdGF0aWMgbWl4ZWQgcHJvcG1ldGhvZHMoc3RyaW5nIGtleSwgb2JqZWN0IG9iKQp7CiAgcmV0dXJuIChtaXhlZClvYi0+UXVlcnkoa2V5LDIpOwp9CgpzdGF0aWMgdm9pZCBkcHJvcDMoc3RyaW5nIGtleSwgbWl4ZWQgZGF0YSwgb2JqZWN0IG9iKQp7CiAgaWYocGlwZV9vdXQmJnBpcGVfb2YpCiAgICB3cml0ZV9maWxlKHBpcGVfb2YsYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKHByb3BtZXRob2RzKGtleSxvYiksTUFYX1JFQ1VSU0lPTiksNzgsQUxFRlQoa2V5KyIgIiwxOCwiLiIpKyIgPSAiKSk7CiAgZWxzZQogICAgVyhicmVha19zdHJpbmdfaGFyZChtaXhlZF90b19zdHJpbmcocHJvcG1ldGhvZHMoa2V5LG9iKSxNQVhfUkVDVVJTSU9OKSw3OCxBTEVGVChrZXkrIiAiLDE4LCIuIikrIiA9ICIpKTsKfQoKc3RhdGljIHZvaWQgRHVtcFByb3BlcnRpZXMob2JqZWN0IG9iaiwgaW50IGZsYWcpCnsKICBTRUNVUkUxKCk7CiAgaWYoIW9iaikKICAgIHJldHVybjsKICBQSVBFX0RFTEVURShwaXBlX29mKTsKICBzd2l0Y2ggKGZsYWcpIHsKICAgIGNhc2UgMDoKICAgICAgd2Fsa19tYXBwaW5nKCgobWFwcGluZyAqKShvYmotPl9fcXVlcnlfcHJvcGVydGllcygpKSlbMF0sIydkcHJvcCxvYmopOyAvLycpCiAgICAgIGJyZWFrOwogICAgY2FzZSAxOgogICAgICB3YWxrX21hcHBpbmcoKChtYXBwaW5nICopKG9iai0+X19xdWVyeV9wcm9wZXJ0aWVzKCkpKVswXSwjJ2Rwcm9wMixvYmopOyAvLycpCiAgICAgIGJyZWFrOwogICAgY2FzZSAyOgogICAgICB3YWxrX21hcHBpbmcoKChtYXBwaW5nICopKG9iai0+X19xdWVyeV9wcm9wZXJ0aWVzKCkpKVswXSwjJ2Rwcm9wMyxvYmopOyAvLycpCiAgICAgIGJyZWFrOwogIH0KfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG1vdmluZyBvYmplY3RzCiAqLwoKc3RhdGljIGludCBNb3ZlT2JqKG9iamVjdCBvYmoxLCBvYmplY3Qgb2JqMiwgaW50IHNpbGVudCkKewogIGludCBlcnI7CiAgb2JqZWN0IG9sZGVudjsKCiAgU0VDVVJFMihGQUxTRSk7CiAgaWYoIShvYmoxJiZvYmoyKSkKICAgIHJldHVybiBGQUxTRTsKICBvbGRlbnY9RU5WKG9iajEpOwogIGVycj0oaW50KW9iajEtPm1vdmUob2JqMiwgTV9TSUxFTlR8TV9OT0NIRUNLKTsKICBpZighc2lsZW50KQogICAgc3dpdGNoKGVycikKICAgIHsKICAgICAgY2FzZSBNRV9QTEFZRVI6CiAgICAgIFdETE4oIk9iamVjdCByZXR1cm5lZCBNRV9QTEFZRVIiKTsKICAgICAgaWYob2xkZW52ICYmIG9sZGVudiAhPSBFTlYob2JqMSkpCglXRExOKCJPYmplY3QgaGFzIGJlZW4gbW92ZWQiKTsKICAgICAgcmV0dXJuIEZBTFNFOwogICAgICBjYXNlIE1FX1RPT19IRUFWWToKICAgICAgV0RMTigiT2JqZWN0IHJldHVybmVkIE1FX1RPT19IRUFWWSIpOwogICAgICBpZihvbGRlbnYgJiYgb2xkZW52ICE9IEVOVihvYmoxKSkKCVdETE4oIk9iamVjdCBoYXMgYmVlbiBtb3ZlZCIpOwogICAgICByZXR1cm4gRkFMU0U7CiAgICAgIGNhc2UgTUVfQ0FOVF9UUE9SVF9JTjoKICAgICAgV0RMTigiT2JqZWN0IHJldHVybmVkIE1FX0NBTlRfVFBPUlRfSU4iKTsKICAgICAgaWYob2xkZW52ICYmIG9sZGVudiAhPSBFTlYob2JqMSkpCglXRExOKCJPYmplY3QgaGFzIGJlZW4gbW92ZWQiKTsKICAgICAgcmV0dXJuIEZBTFNFOwogICAgICBjYXNlIE1FX0NBTlRfVFBPUlRfT1VUOgogICAgICBXRExOKCJPYmplY3QgcmV0dXJuZWQgTUVfQ0FOVF9UUE9SVF9PVVQiKTsKICAgICAgaWYob2xkZW52ICYmIG9sZGVudiAhPSBFTlYob2JqMSkpCglXRExOKCJPYmplY3QgaGFzIGJlZW4gbW92ZWQiKTsKICAgICAgcmV0dXJuIEZBTFNFOwogICAgICBkZWZhdWx0OgogICAgICBXRExOKCJPYmplY3QgcmV0dXJuZWQgdW5rbm93biByZXR1cm4gdmFsdWUiKTsKICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogIHJldHVybiBUUlVFOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogc2F2ZSBkZXN0cnVjdGluZyBvZiBvYmplY3RzCiAqLwoKc3RhdGljIHZvaWQgRGVzdHJ1Y3Qob2JqZWN0IG9iaikKewogIGlmKCFvYmogfHwgIXRoaXNfb2JqZWN0KCkpCiAgICByZXR1cm47CiAgY2F0Y2gob2JqLT5yZW1vdmUoKSk7CiAgaWYob2JqZWN0cChvYmopICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikpCiAgICBkZXN0cnVjdChvYmopOwp9CgpzdGF0aWMgdm9pZCBEZWVwQ2xlYW4ob2JqZWN0IG9iaikKewogIGlmKCFvYmopCiAgICByZXR1cm47CiAgZmlsdGVyKGZpbHRlcihkZWVwX2ludmVudG9yeShvYmopLCAiaXNfbm90X3BsYXllciIsIE1FKSwKCSAgICAgICAiRGVzdHJ1Y3QiLCBNRSk7CiAgaWYoaXNfbm90X3BsYXllcihvYmopKQogICAgRGVzdHJ1Y3Qob2JqKTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFNob3cgdGhlIGluaGVyaXRhbmNlIHRyZWUgb2Ygb2JqZWN0cwogKi8KCnN0YXRpYyBvYmplY3QgKlN1Yk5vZGVzKG9iamVjdCBvYmopCnsKICBpbnQgczsKICBvYmplY3QgKm9ianM7CiAgc3RyaW5nICppbmxpc3Q7CiAgCiAgaWYoIW9iaikKICAgIHJldHVybiBOVUxMOwogIGlubGlzdD1pbmhlcml0X2xpc3Qob2JqKTsKICBzPXNpemVvZihpbmxpc3QpOwogIG9ianM9KHt9KTsKICB3aGlsZShzLS0+MSkKICAgIG9ianM9KHtmaW5kX29iamVjdChpbmxpc3Rbc10pfSkrb2JqczsKICByZXR1cm4gb2JqczsKfQoKc3RhdGljIHZvaWQgSW5oZXJpdGFuY2Uob2JqZWN0IG9iaiwgc3RyaW5nIGZ1bmMsIHN0cmluZyBwcmUpCnsKICBpbnQgaSwgczsKICBvYmplY3QgKmxuOwogIHN0cmluZyBzdHI7CiAgCiAgaWYoIW9iaikKICAgIHJldHVybjsKICBzdHI9cHJlKyIgIitPYmpGaWxlKG9iaik7CiAgaWYoZnVuYykKICB7CiAgICBzdHI9QUxFRlQoc3RyKyIgIiwgNTAsICIuIik7CiAgICBpZihmdW5jdGlvbl9leGlzdHMoZnVuYywgb2JqKT09b2JqZWN0X25hbWUob2JqKSkKICAgICAgc3RyKz1BUklHSFQoIiAiK2Z1bmMsIDE5LCAiLiIpOwogICAgZWxzZQogICAgICBzdHIrPUFSSUdIVCgiIiwgMTksICIuIik7CiAgfQogIGlmKHBpcGVfb3V0JiZwaXBlX29mKQogICAgd3JpdGVfZmlsZShwaXBlX29mLHN0cisiXG4iKTsKICBlbHNlCiAgICBXTE4oc3RyKTsKICBsbj1TdWJOb2RlcyhvYmopOwogIGZvcihpPTA7IGk8c2l6ZW9mKGxuKTsgaSsrKQogICAgbG49bG4tU3ViTm9kZXMobG5baV0pOwogIHM9c2l6ZW9mKGxuKTsKICBmb3IoaT0wOyBpPHM7IGkrKykKICAgIEluaGVyaXRhbmNlKGxuW2ldLCBmdW5jLCBwcmUrIi4uLi4uIik7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBmaWxlIG5hbWUgaGFuZGxpbmcKICovCgpzdGF0aWMgc3RyaW5nIFhGaWxlKHN0cmluZyBmaWxlKQp7CiAgVEsoIlhGaWxlOiBmaWxlOiAiKyhmaWxlP2ZpbGU6IihOVUxMKSIpKTsKICBpZihmaWxlKQogICAgc3dpdGNoKGZpbGVbMF0pCiAgICB7CiAgICAgIGNhc2UgJ0AnOgoJcmV0dXJuIHNvdXJjZV9maWxlX25hbWUoWEZpbmRPYmooZmlsZVsxLi48MV0pKTsKICAgICAgY2FzZSAnJCc6CglyZXR1cm4gc291cmNlX2ZpbGVfbmFtZShYRmluZE9iaihmaWxlKSk7CiAgICAgIGRlZmF1bHQ6CglyZXR1cm4gb2xkX2V4cGxvZGUobG9uZ19wYXRoKGZpbGUpLCIjIilbMF07CiAgICB9CiAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBzdHJpbmcgWEZpbmRGaWxlKHN0cmluZyBmaWxlKQp7CiAgVEsoIlhGaW5kRmlsZTogZmlsZTogIisoZmlsZT9maWxlOiIoTlVMTCkiKSk7CiAgaWYoZmlsZT1YRmlsZShmaWxlKSkKICB7CiAgICBpZihmaWxlX3NpemUoZmlsZSk+PTApCiAgICAgIHJldHVybiBmaWxlOwogICAgaWYoZmlsZVs8My4uPDFdIT0iLmMiICYmIGZpbGVfc2l6ZShmaWxlKyIuYyIpPjApCiAgICAgIHJldHVybiBmaWxlKyIuYyI7CiAgfQogIFdETE4oIkZpbGUgbm90IGZvdW5kIG9yIG5vdCByZWFkYWJsZSBbIitzaG9ydF9wYXRoKGZpbGUpKyJdIik7CiAgcmV0dXJuIE5VTEw7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBmaWxlIHByaW50aW5nLCBzZWFyY2hpbmcgYW5kIGV4ZWN1dGluZwogKi8KCnN0YXRpYyB2b2lkIFhNb3JlRmlsZShzdHJpbmcgZmlsZSwgaW50IGZsYWcpCnsKICBpbnQgcyxzaXplOwogIAogIFNFQ1VSRTEoKTsKICBpZighZmlsZSkKICAgIHJldHVybjsKICAKICAvLyB0ZXJtPShzdHJpbmcpY2xvbmVyLT5RdWVyeVByb3AoUF9UVFkpIT0iZHVtYiI7CiAgaWYoKHNpemU9KGZpbGVfc2l6ZShtb3JlZmlsZT1sb25nX3BhdGgoZmlsZSkpKSk+MCkKICB7CiAgICBpZihzaXplPjEwMDAwMCkKICAgICAgV0RMTigiV2FybmluZzogbGFyZ2UgZmlsZSIpOwogICAgTW9yZUZpbGUoTlVMTCk7CiAgfQogIGVsc2UgaWYoZmxhZykKICAgIFdETE4oIkNhbm5vdCByZWFkIGZpbGUiKTsKfQoKLyoKc3RhdGljIHN0cmluZyByZWFkX2J1ZmZlcihzdHJpbmcgZmlsZW5hbWUsIGludCBzdGFydCwgaW50IG51bWJlcikKewogIG1peGVkIHRtcDsKICBzdHJpbmcgcmVzdWx0OwogIGludCBjdXJyZW50OwoKICBpZighZmlsZW5hbWV8fGZpbGVuYW1lPT0iIikKICAgIHJldHVybiAiIjsKICBpZihudW1iZXI8PTEpCiAgICBudW1iZXI9MTsKICBudW1iZXItLTsKICByZXN1bHQ9IiI7CiAgaWYoZmlsZW5hbWUhPWxpbmVfYnVmZmVyX25hbWUpCiAgewogICAgLy8gVEsoInJlYWRfYnVmZmVyOiBpbml0aWFsaXppbmciKTsKICAgIGxpbmVfYnVmZmVyPShbXSk7CiAgICBsaW5lX2J1ZmZlcl9uYW1lPWZpbGVuYW1lOwogICAgY3VycmVudD0wOwogIH0KICBlbHNlCiAgICBjdXJyZW50PXN0YXJ0OwoKICB3aGlsZShjdXJyZW50PD1zdGFydCtudW1iZXIgJiYgc3RyaW5ncCgodG1wPWxvYWRfYnVmZmVyKGN1cnJlbnQrKykpKSkKICAgIGlmKGN1cnJlbnQ+PXN0YXJ0KQogICAgICByZXN1bHQrPXRtcDsKICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgc3RyaW5nIGxvYWRfYnVmZmVyKGludCBsaW5lKQp7CiAgaW50IGksIGN1cnJlbnQsIHN0YXJ0LCBsZW5ndGgsICppZHg7CgogIGlmKGludHAobGluZV9idWZmZXJbbGluZV0pKQogIHsKICAgIC8vIFRLKCJsb2FkX2J1ZmZlcjogTm90Zm91bmQ6ICIrbGluZSk7CiAgICBjdXJyZW50PWxpbmU7CiAgICB3aGlsZShjdXJyZW50PjAmJmludHAobGluZV9idWZmZXJbLS1jdXJyZW50XSkpOwogICAgZm9yKGk9Y3VycmVudDtpPD1saW5lO2krKykKICAgIHsKICAgICAgLy8gVEsoImxvYWRfYnVmZmVyOiB0cnlpbmc6ICIraSk7CiAgICAgIGlmKGk+MCkKCWlkeD1saW5lX2J1ZmZlcltpLTFdOwogICAgICBlbHNlCglpZHg9KHswLDB9KTsKICAgICAgbGVuZ3RoPXJlYWRfbGluZSgoc3RhcnQ9aWR4WzBdK2lkeFsxXSkpOwogICAgICAvLyBUSygibG9hZF9idWZmZXI6ICIrc3RhcnQrIi8iK2xlbmd0aCk7CiAgICAgIGxpbmVfYnVmZmVyW2ldPSh7c3RhcnQsbGVuZ3RofSk7CiAgICB9CiAgfQogIGlkeD1saW5lX2J1ZmZlcltsaW5lXTsKICByZXR1cm4KICAgIHJlYWRfYnl0ZXMobGluZV9idWZmZXJfbmFtZSxpZHhbMF0saWR4WzFdKTsKfQoKc3RhdGljIGludCByZWFkX2xpbmUoaW50IG9mZnNldCkKewogIG1peGVkIGxvY19idWY7CiAgaW50IGxlbmd0aCwgcG9zOwoKICAvLyBUSygicmVhZF9saW5lOiAiK29mZnNldCk7CiAgbGVuZ3RoPTA7CiAgd2hpbGUoIWludHAoKGxvY19idWY9cmVhZF9ieXRlcyhsaW5lX2J1ZmZlcl9uYW1lLG9mZnNldCtsZW5ndGgsMTAyNCkpKSkKICB7CiAgICBpZigocG9zPW1lbWJlcihsb2NfYnVmLCdcbicpKT49MCkKICAgICAgcmV0dXJuIGxlbmd0aCtwb3MrMTsKICAgIGxlbmd0aCs9MTAyNDsKICB9CiAgcmV0dXJuIGxlbmd0aDsKfQoqLwoKc3RhdGljIHZvaWQgTW9yZUZpbGUoc3RyaW5nIHN0cikKewogIGludCBpLCBvZmY7CiAgc3RyaW5nIGYsIGwsIHI7CiAgCiAgU0VDVVJFMSgpOwogIAogIGlmIChzdHIgLyomJiBzaXplb2Yoc3RyKSovKQogIHsKCQlpZiggIXNpemVvZihzdHIpICkgc3RyPSJcMCI7CiAgICBpZih0ZXJtKQogICAgICBXKCIbTRtbMU0iKTsKICAgIHN3aXRjaChzdHJbMF0pCiAgICB7CiAgICAgIGNhc2UgJ3EnOgogICAgICBjYXNlICd4JzoKICAgICAgbW9yZWZsYWc9RkFMU0U7CiAgICAgIG1vcmVvZmZzZXQ9MTsKICAgICAgaWYobW9yZWZpbGU9PVRNUF9GSUxFfHxtb3JlZmlsZT09UElQRV9GSUxFKQoJcm0obW9yZWZpbGUpOwogICAgICByZXR1cm4gTlVMTDsKICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ1AnOgogICAgICBjYXNlICdVJzoKICAgICAgbW9yZWZsYWc9RkFMU0U7CiAgICAgIG1vcmVvZmZzZXQ9bW9yZW9mZnNldC1tb3JlbGluZXM7CiAgICAgIGNhc2UgJ3AnOgogICAgICBjYXNlICd1JzoKICAgICAgbW9yZW9mZnNldD1tb3Jlb2Zmc2V0LTIqbW9yZWxpbmVzOwogICAgICBicmVhazsKICAgICAgY2FzZSAnRCc6CiAgICAgIGNhc2UgJ04nOgogICAgICBtb3Jlb2Zmc2V0Kz1tb3JlbGluZXM7CiAgICAgIGNhc2UgMDoJLyogUkVUVVJOICovCiAgICAgIGNhc2UgJ2QnOgogICAgICBpZihtb3JlZmxhZykKICAgICAgewoJbW9yZWZsYWc9RkFMU0U7Cgltb3Jlb2Zmc2V0PTE7CglpZihtb3JlZmlsZT09VE1QX0ZJTEUpCgkgIHJtKG1vcmVmaWxlKTsKCXJldHVybjsKICAgICAgfQogICAgICBicmVhazsKICAgICAgY2FzZSAnLyc6CiAgICAgIG1vcmVvZmZzZXQtLTsKICAgICAgbW9yZV9zZWFyY2hleHByPXN0clsxLi48MV07CiAgICAgIGNhc2UgJ24nOgogICAgICBpPW1vcmVvZmZzZXQtbW9yZWxpbmVzKzE7CiAgICAgIGlmKG1vcmVfc2VhcmNoZXhwcj09IiIpCiAgICAgIHsKCVdETE4oIk5vIHByZXZpb3VzIHJlZ3VsYXIgZXhwcmVzc2lvbiIpOwoJcmV0dXJuOwogICAgICB9CiAgICAgIGlmKCFyZWdleHAoKHsiZHVtbXkifSksIG1vcmVfc2VhcmNoZXhwcikpCglXRExOKCJCYWQgcmVndWxhciBleHByZXNzaW9uIik7CiAgICAgIGVsc2UKCXdoaWxlKChsPXJlYWRfZmlsZShtb3JlZmlsZSwgaSsrLCAxKSkmJgoJICAgICAgIXNpemVvZihyZWdleHAoKHtsfSksIG1vcmVfc2VhcmNoZXhwcikpKQoJICA7CiAgICAgIGlmKGwpCiAgICAgIHsKCVdMTigiKioqIFNraXBwaW5nIC4uLiIpOwoJbW9yZW9mZnNldD1pLTE7CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CglXTE4oIioqKiBQYXR0ZXJuIG5vdCBmb3VuZCIpOwoJbW9yZW9mZnNldC09bW9yZWxpbmVzOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgICBjYXNlICcwJy4uJzknOgogICAgICBzc2NhbmYoc3RyLCAiJWQiLCBpKTsKICAgICAgbW9yZW9mZnNldD1pOwogICAgICBicmVhazsKICAgIH0KICB9CiAgZWxzZQogIHsKICAgIG1vcmVvZmZzZXQ9MTsKICAgIG1vcmVmbGFnPUZBTFNFOwogIH0KICBpZihtb3Jlb2Zmc2V0PDEpCiAgICBtb3Jlb2Zmc2V0PTE7CiAgaWYoQ2F0RmlsZSgpKQogICAgVygiKioqIE1vcmU6IHEsdSxVLGQsRCwvPHJlZ2V4cD4sPGxpbmU+IFsiKyhtb3Jlb2Zmc2V0LTEpKyJdICoqKiAiKTsKICBlbHNlCiAgewogICAgVygiKioqIE1vcmU6IHEsdSxVLGQsRCwvPHJlZ2V4cD4sPGxpbmU+IFsiKyhtb3Jlb2Zmc2V0LTEpKyI9RU9GXSAqKiogIik7CiAgICBtb3JlZmxhZz1UUlVFOwogIH0KICBpbnB1dF90bygiTW9yZUZpbGUiKTsKICByZXR1cm47Cn0KCi8vIFNjaGFkZSBlaWdlbnRsaWNoIGRhcyBpY2ggZXMgbmV1c2NocmVpYmVuIG11c3N0ZSwgYWJlciBlcyBpc3QKLy8gc2NobmVsbGVyIG5ldSBnZXNjaHJpZWJlbiBhbHMgZHVyY2ggZGllIHVuZG9rdW1lbnRpZXJlbiBhbHRlbiBGdW5rdGlvbmVuCi8vIGR1cmNoenVzdGVpZ2VuLi4uICpzZXVmeioKLy8JCQkJCSAgUGFkcmVpYwoKc3RhdGljIHN0cmluZyBsYXN0X2ZpbGUsICpsYXN0X2ZpbGVfYnVmZmVyOwpzdGF0aWMgaW50ICAgIGxhc3RfZmlsZV9kYXRlLCBsYXN0X2ZpbGVfc2l6ZSwgbGFzdF9maWxlX2NvbXBsZXRlOwoKc3RhdGljIHN0cmluZyBzcmVhZF9saW5lKGludCBudW0pCnsKICAgaWYgKCFtb3JlZmlsZSkgcmV0dXJuICIiOwogICBpZiAobGFzdF9maWxlIT1tb3JlZmlsZSB8fCBsYXN0X2ZpbGVfZGF0ZSE9ZmlsZV90aW1lKG1vcmVmaWxlKSkgewogICAgICBpZiAoIShsYXN0X2ZpbGU9cmVhZF9ieXRlcyhtb3JlZmlsZSwgMCwgNTAwMDApKSkgcmV0dXJuICIiOwogICAgICBsYXN0X2ZpbGVfZGF0ZT1maWxlX3RpbWUobW9yZWZpbGUpOwogICAgICBsYXN0X2ZpbGVfYnVmZmVyPWV4cGxvZGUobGFzdF9maWxlLCAiXG4iKTsKICAgICAgbGFzdF9maWxlX3NpemU9c2l6ZW9mKGxhc3RfZmlsZV9idWZmZXIpOwogICAgICBpZiAoc2l6ZW9mKGxhc3RfZmlsZSk9PTUwMDAwICYmIGxhc3RfZmlsZVs8MV0hPSdcbicpIHsKCSBsYXN0X2ZpbGVfc2l6ZS0tOyAvLyBsZXR6dGUgWmVpbGUgbmljaHQgdm9sbHN0YWVuZGlnIGdlbGVzZW4KCSBsYXN0X2ZpbGVfY29tcGxldGU9MDsKICAgICAgfQogICAgICBlbHNlIGlmIChmaWxlX3NpemUobW9yZWZpbGUpPjUwMDAwKQoJbGFzdF9maWxlX2NvbXBsZXRlPTA7CiAgICAgIGVsc2UgbGFzdF9maWxlX2NvbXBsZXRlPTE7CiAgICAgIGxhc3RfZmlsZT1tb3JlZmlsZTsKICAgfQogICBpZiAobnVtPT0wKSBudW09MTsKICAgLy8gYmVpIHp1IGdyb3NzZW4gRmlsZXMgbmljaHQgbWVociBhbGxlcyBidWZmZXJuLi4uCiAgIGlmIChudW0+bGFzdF9maWxlX3NpemUpIHsKICAgICAgaWYgKGxhc3RfZmlsZV9jb21wbGV0ZSkgcmV0dXJuICIiOwogICAgICByZXR1cm4gKHJlYWRfZmlsZShtb3JlZmlsZSwgbnVtLCAxKSB8fCAiIik7CiAgIH0KICAgcmV0dXJuIGxhc3RfZmlsZV9idWZmZXJbbnVtLTFdKyJcbiI7Cn0KCnN0YXRpYyBpbnQgQ2F0RmlsZSgpCnsKICBpbnQgZW5kOwogIHN0cmluZyBsOwogIAogIGVuZD1tb3Jlb2Zmc2V0K21vcmVsaW5lczsKICB3aGlsZShtb3Jlb2Zmc2V0PGVuZCkKLy8gICAgaWYoKGw9cmVhZF9maWxlKG1vcmVmaWxlLCBtb3Jlb2Zmc2V0LCAxKSkhPSIiKQogICAgaWYoKGw9c3JlYWRfbGluZShtb3Jlb2Zmc2V0KSkhPSIiKQogICAgewogICAgICBtb3Jlb2Zmc2V0Kys7CiAgICAgIFcobCk7CiAgICB9CiAgICBlbHNlCiAgICAgIHJldHVybiBGQUxTRTsKLy8gIGlmKHJlYWRfZmlsZShtb3JlZmlsZSwgbW9yZW9mZnNldCsxLCAxKSE9IiIpCiAgaWYoc3JlYWRfbGluZShtb3Jlb2Zmc2V0KzEpIT0iIikKICAgIHJldHVybiBUUlVFOwogIGVsc2UKICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIGludCBYR3JlcEZpbGUoc3RyaW5nIHBhdCwgc3RyaW5nIGZpbGUsIGludCBtb2RlKQp7CiAgaW50IGksIGosIGYsIHMsIGZzaXplOwogIHN0cmluZyB0ZmlsZSwgKnRtcCwgKnRzLCB0OwogIAogIFNFQ1VSRTIoRkFMU0UpOwogIFRLKCJYR3JlcEZpbGU6IHBhdDogIitwYXQrIiBmaWxlOiAiK2ZpbGUrIiBtb2RlOiAiK21vZGUpOwogIGlmKCEocGF0JiZmaWxlKSkKICAgIHJldHVybiBGQUxTRTsKICB0ZmlsZT1UTVBfRklMRTsKICBmc2l6ZT1maWxlX3NpemUoZmlsZSk7CiAgZm9yKGk9MCxmPTA7IGk8ZnNpemUgJiYgdD1yZWFkX2J5dGVzKGZpbGUsIGksIDUwMDAwKTsgaSs9NTAwMDApCiAgICB0bXA9c3RyaXBfZXhwbG9kZSh0LCJcbiIpOwogICAgaWYgKHQgJiYgdFs8MV0hPSdcbicgJiYgc2l6ZW9mKHQpPT01MDAwMCkgewogICAgICAgaS09c2l6ZW9mKHRtcFs8MV0pOwogICAgICAgdG1wPXRtcFswLi48Ml07CiAgICB9CiAgICBpZihzPXNpemVvZih0bXApKQogICAgewogICAgICBmb3Ioaj0wO2o8cztqKyspCiAgICAgIHsKCWlmKHNpemVvZih0cz1yZWdleHAoKHsobW9kZSZYR1JFUF9JQ0FTRT9sb3dlcl9jYXNlKHRtcFtqXSk6dG1wW2pdKX0pLHBhdCkpKQoJewoJICBpZighKG1vZGUmWEdSRVBfUkVWRVJUKSkKCSAgIHsKCSAgICAgaWYoIWYrKykKCSAgICAgICB3cml0ZV9maWxlKHRmaWxlLCAiKioqIEZpbGU6ICIrZmlsZSsiICoqKlxuIik7CgkgICAgIHdyaXRlX2ZpbGUodGZpbGUsIHRtcFtqXSsiXG4iKTsKCSAgIH0KCX0KCWVsc2UgaWYobW9kZSZYR1JFUF9SRVZFUlQpCgl7CgkgIGlmKCFmKyspCgkgICAgd3JpdGVfZmlsZSh0ZmlsZSwgIioqKiBGaWxlOiAiK2ZpbGUrIiAqKipcbiIpOwoJICB3cml0ZV9maWxlKHRmaWxlLCB0bXBbal0rIlxuIik7Cgl9CiAgICAgIH0KICAgIH0KICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgWEV4ZWNGaWxlKGludCBsaW5lKQp7CiAgaW50IGk7CiAgCiAgaWYoIXNjcmlwdGxpbmUpCiAgICByZXR1cm47CiAgZm9yKGk9bGluZTsgaTxzY3JpcHRzaXplJiZpPGxpbmUrRVhFQ19MSU5FUzsgaSsrKQogIHsKICAgIGlmKCFzY3JpcHRsaW5lW2ldKQogICAgICBjb250aW51ZTsKICAgIGlmKCFDb21tYW5kKHNjcmlwdGxpbmVbaV0pKQogICAgewogICAgICBzY3JpcHRsaW5lPU5VTEw7CiAgICAgIHJldHVybjsKICAgIH0KICB9CiAgaWYoaTxzY3JpcHRzaXplKQogICAgY2FsbF9vdXQoIlhFeGVjRmlsZSIsIEVYRUNfVElNRSwgaSk7CiAgZWxzZQogICAgc2NyaXB0bGluZT1OVUxMOwp9CgpzdGF0aWMgdm9pZCBYbXRwU2NyaXB0KHN0cmluZyBkaXIsIHN0cmluZyBmaWxlLCBzdHJpbmcgb3B0KQp7CiAgaW50IHMsIHQ7CiAgc3RyaW5nICpmaWxlczsKICAKICBzPXNpemVvZihmaWxlcz1nZXRfZGlyKGRpcisiLyoiKSk7CiAgd2hpbGUocy0tKQogIHsKICAgIHQ9c2l6ZW9mKGZpbGVzW3NdKS0xOwogICAgaWYoZmlsZXNbc10gPT0gIi4uIiB8fCBmaWxlc1tzXSA9PSAiLiIgfHwgZmlsZXNbc11bdF0gPT0gJ34nIHx8CiAgICAgICAoZmlsZXNbc11bMF0gPT0gJyMnICYmIGZpbGVzW3NdW3RdID09ICcjJykpCiAgICAgIGNvbnRpbnVlOwogICAgaWYoZmlsZV9zaXplKGRpcisiLyIrZmlsZXNbc10pPT0tMikKICAgIHsKICAgICAgd3JpdGVfZmlsZShmaWxlLCAibWtkaXIgIitmaWxlc1tzXSsiIDsgY2QgIitmaWxlc1tzXSsiXG4iKTsKICAgICAgWG10cFNjcmlwdChkaXIrIi8iK2ZpbGVzW3NdLCBmaWxlLCBvcHQpOwogICAgICB3cml0ZV9maWxlKGZpbGUsICJjZCAuLlxuIik7CiAgICB9CiAgICBlbHNlCiAgICAgIHdyaXRlX2ZpbGUoZmlsZSwgIm10cCAtciAiK29wdCsiICIrZGlyKyIvIitmaWxlc1tzXSsiXG4iKTsKICB9Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgcGxheWVyIHByb3BlcnRpZXMgaGFuZGxpbmcKICovCgpzdGF0aWMgc3RyaW5nIFBsYXllcklkbGUob2JqZWN0IG9iaikKewogIHN0cmluZyBzdHI7CiAgaW50IGksIHRtcDsKICAKICBpZighb2JqKQogICAgcmV0dXJuIE5VTEw7CiAgaWYoKGk9cXVlcnlfaWRsZShvYmopKT49NjApCiAgewogICAgc3RyPUFSSUdIVCgiIisoaS8zNjAwKSwgMiwgIjAiKTsKICAgIGktPShpLzM2MDApKjM2MDA7CiAgICBzdHIrPSInIitBUklHSFQoIiIrKGkvNjApLCAyLCAiMCIpOwogIH0KICBlbHNlCiAgICBzdHI9Ii4uLi4uIjsKICByZXR1cm4gc3RyOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllckFnZShvYmplY3Qgb2JqKQp7CiAgc3RyaW5nIHN0cjsKICBpbnQgaSwgdG1wOwogIAogIGlmKCFvYmopCiAgICByZXR1cm4gTlVMTDsKICBpPShpbnQpb2JqLT5RdWVyeVByb3AoUF9BR0UpOwogIHN0cj0iICIrQVJJR0hUKCIiKyhpLzQzMjAwKSwgNCwgIi4iKTsKICBpLT0oaS80MzIwMCkqNDMyMDA7CiAgcmV0dXJuIHN0cisiOiIrQVJJR0hUKCIiKyhpLzE4MDApLCAyLCAiMCIpOwp9CgpzdGF0aWMgc3RyaW5nIGNybmFtZShvYmplY3Qgd2hvKQp7CiAgc3RyaW5nIHVpZCwgbG5hbWU7CgogIGlmKCh1aWQ9Z2V0dWlkKHdobykpPT1ST09USUQgJiYgCiAgICAgb2JqZWN0X25hbWUod2hvKVswLi43XT09Ii9zZWN1cmUvIiAmJgogICAgIChsbmFtZT0oc3RyaW5nKXdoby0+bG9naW5uYW1lKCkpKQogICAgcmV0dXJuIENBUChsbmFtZSk7CiAgcmV0dXJuIENBUCh1aWQpOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllcldobyhvYmplY3Qgb2JqKQp7CiAgb2JqZWN0IHRtcDsKICBzdHJpbmcgc3RyLCBzdG1wOwogIHN0cj1BUklHSFQoIiIrTEVWRUwob2JqKSAgLCAgMywgIiAiKTsKICBzdHIrPUFMRUZUKCIgIitjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpOwogIHN0cis9UGxheWVyQWdlKG9iaik7CiAgc3RyKz0oKGludClvYmotPlF1ZXJ5UHJvcChQX0dFTkRFUik9PTEgPyAiIG0gIiA6ICIgZiAiKTsKICBzdHIrPShvYmotPlF1ZXJ5UHJvcChQX0ZST0cpKSAgPyAiZiIgOiAiLiI7CiAgc3RyKz0ob2JqLT5RdWVyeVByb3AoUF9HSE9TVCkpID8gImciIDogIi4iOwogIHN0cis9KG9iai0+UXVlcnlQcm9wKFBfSU5WSVMpKSA/ICJpIiA6ICIuIjsKICBzdHIrPShxdWVyeV9lZGl0aW5nKG9iail8fHF1ZXJ5X2lucHV0X3BlbmRpbmcob2JqKSA/ICJlIiA6ICIuIik7CiAgc3RyKz0ob2JqLT5RdWVyeVByb3AoUF9BV0FZKSkgID8gImEiIDogIi4iOwogIHN0cis9IiAiK1BsYXllcklkbGUob2JqKSsiICI7CiAgc3RyKz0odG1wPUVOVihvYmopKSA/IE9iakZpbGUodG1wKSA6ICItIGZhYnJpYyBvZiBzcGFjZSAtIjsKICByZXR1cm4gc3RyOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllck1haWwob2JqZWN0IG9iaiwgaW50IGZsYWcpCnsKICBzdHJpbmcgcHJlOwogIAogIHByZT0oZmxhZykgPyBBTEVGVChjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpKyIgIiA6ICIiOwogIHJldHVybiBwcmUrIm1haWw6ICIrb2JqLT5RdWVyeVByb3AoUF9NQUlMQUREUik7Cn0KCnN0YXRpYyBzdHJpbmcgUGxheWVySVAob2JqZWN0IG9iaiwgaW50IGZsYWcpCnsKICBzdHJpbmcgcHJlOwogIAogIHByZT0oZmxhZykgPyBBTEVGVChjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpKyIgIiA6ICIiOwogIHJldHVybiBwcmUrImhvc3Q6ICIrcXVlcnlfaXBfbmFtZShvYmopKyIgKCIrcXVlcnlfaXBfbnVtYmVyKG9iaikrIikiOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllclJhY2Uob2JqZWN0IG9iaiwgaW50IGZsYWcpCnsKICBzdHJpbmcgdG1wLCBwcmU7CiAgCiAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CiAgcHJlPXByZSsicmFjZTogIitBTEVGVChvYmotPlF1ZXJ5UHJvcChQX1JBQ0UpKyIgIiwgMTAsICIuIikrIiBndWlsZDogIjsKICB0bXA9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX0dVSUxEKTsKICByZXR1cm4gdG1wID8gcHJlK3RtcCA6IHByZSsiLSBub25lIC0iOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllckRvbWFpbihvYmplY3Qgb2JqLCBpbnQgZmxhZykKewogIGludCBpLCBzOwogIG1peGVkICp1aW5mbzsKICBzdHJpbmcgKmRvbWFpbnMsIHByZTsKICAKICBwcmU9KGZsYWcpID8gQUxFRlQoY3JuYW1lKG9iaikrIiAiLCAxMiwgIi4iKSsiICIgOiAiIjsKICBwcmUrPSJkb21haW5sb3JkIG9mOiAiOwogIHVpbmZvPShtaXhlZCopTUFTVEVSLT5nZXRfdXNlcmluZm8oZ2V0dWlkKG9iaikpOwogIGlmKHVpbmZvJiYoZG9tYWlucz11aW5mb1szXSkmJihzPXNpemVvZihkb21haW5zKSkpCiAgewogICAgZm9yKGk9MDsgaTxzOyBpKyspCiAgICB7CiAgICAgIHByZSArPSBDQVAoZG9tYWluc1tpXSk7CiAgICAgIGlmKGk8cy0xKQoJcHJlICs9ICIsICI7CiAgICB9CiAgfQogIHJldHVybiBwcmU7Cn0KCnN0YXRpYyBzdHJpbmcgUGxheWVyU3RhdHMob2JqZWN0IG9iaiwgaW50IGZsYWcpCnsKICBzdHJpbmcgcHJlOwogIAogIHByZT0oZmxhZykgPyBBTEVGVChjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpKyIgIiA6ICIiOwogIHByZSs9ImhwPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfSFApLCAzLCAiMCIpOwogIHByZSs9Ii8iK0FSSUdIVChvYmotPlF1ZXJ5UHJvcChQX01BWF9IUCksIDMsICIwIik7CiAgcHJlKz0iIHNwPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfU1ApLCAzLCAiMCIpOwogIHByZSs9Ii8iK0FSSUdIVChvYmotPlF1ZXJ5UHJvcChQX01BWF9TUCksIDMsICIwIik7CiAgcHJlKz0iIGZvb2Q9IitBUklHSFQob2JqLT5RdWVyeVByb3AoUF9GT09EKSwgMywgIjAiKTsKICBwcmUrPSIvIitBUklHSFQob2JqLT5RdWVyeVByb3AoUF9NQVhfRk9PRCksIDMsICIwIik7CiAgcHJlKz0iIGRyaW5rPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfRFJJTkspLCAzLCAiMCIpOwogIHByZSs9Ii8iK0FSSUdIVChvYmotPlF1ZXJ5UHJvcChQX01BWF9EUklOSyksIDMsICIwIik7CiAgcHJlKz0iIGV4cHM9IitvYmotPlF1ZXJ5UHJvcChQX1hQKTsKICByZXR1cm4gcHJlOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllclNub29wKG9iamVjdCBvYmosIGludCBmbGFnKQp7CiAgc3RyaW5nIHRtcCwgcHJlOwogIG9iamVjdCB2aWN0aW07CiAgCiAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CiAgcHJlPXByZSsiaXMgc25vb3BlZCBieTogIjsKICBpZih2aWN0aW09cXVlcnlfc25vb3Aob2JqKSkKICAgIHByZSs9QVJJR0hUKCIgIitjcm5hbWUodmljdGltKSwgMTIsICIuIik7CiAgZWxzZQogICAgcHJlKz0iLi4uLi4uLi4uLi4uIjsKICByZXR1cm4gcHJlOwp9CgpzdGF0aWMgc3RyaW5nIFBsYXllckNtZEF2ZyhvYmplY3Qgb2JqLCBpbnQgZmxhZykKewogIHN0cmluZyBwcmU7CiAgCiAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CiAgcmV0dXJuIHByZSsiY21kYXZnOiAiKyhpbnQpb2JqLT5fcXVlcnlfY29tbWFuZF9hdmVyYWdlKCk7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogbXNnIGlucHV0IHRvIG9iamVjdHMKICovCgpzdGF0aWMgdm9pZCBYTXNnU2F5KHN0cmluZyBzdHIpCnsKICBpZihzdHI9PSIuInx8c3RyPT0iKioiKQogIHsKICAgIFdMTigiW0VuZCBvZiBtZXNzYWdlXSIpOwogICAgc2F5KCJbRW5kIG9mIG1lc3NhZ2VdXG4iKTsKICB9CiAgZWxzZQogIHsKICAgIHNheShzdHIrIlxuIik7CiAgICBpbnB1dF90bygiWE1zZ1NheSIpOwogIH0KfQoKc3RhdGljIHZvaWQgWE1zZ1RlbGwoc3RyaW5nIHN0cikKewogIGlmKHN0cj09Ii4ifHxzdHI9PSIqKiIpCiAgewogICAgV0xOKCJbRW5kIG9mIG1lc3NhZ2VdIik7CiAgICB0ZWxsX29iamVjdChtc2d0bywgIltFbmQgb2YgbWVzc2FnZV1cbiIpOwogIH0KICBlbHNlCiAgewogICAgdGVsbF9vYmplY3QobXNndG8sIHN0cisiXG4iKTsKICAgIGlucHV0X3RvKCJYTXNnVGVsbCIpOwogIH0KfQoKc3RhdGljIHZvaWQgWE1zZ1Nob3V0KHN0cmluZyBzdHIpCnsKICBpZihzdHI9PSIuInx8c3RyPT0iKioiKQogIHsKICAgIFdMTigiW0VuZCBvZiBtZXNzYWdlXSIpOwogICAgc2hvdXQoIltFbmQgb2YgbWVzc2FnZV1cbiIpOwogIH0KICBlbHNlCiAgewogICAgc2hvdXQoc3RyKyJcbiIpOwogICAgaW5wdXRfdG8oIlhNc2dTaG91dCIpOwogIH0KfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIG93biBvYmplY3QgbW92aW5nCiAqLwoKaW50IG1vdmUobWl4ZWQgZGVzdCkKewogIG1vdmVfb2JqZWN0KE1FLCBjbG9uZXI/Y2xvbmVyOmRlc3QpOwogIHJldHVybiBUUlVFOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogb2JqZWN0IGlkCiAqLwoKaW50IGlkKHN0cmluZyBzdHIpCnsKICBpZighc2VjdXJpdHkoKSYmTU9ERShNT0RFX1NDQU5DSEspJiZSVFAmJiFJU19BUkNIKFJUUCkpCiAgICBXRExOKGNybmFtZShSVFApKyIgc2Nhbm5lZCB5b3UgKGlkKSBbIitxdWVyeV92ZXJiKCkrIl0gIisKCSAoUFJFViA/IE9iakZpbGUoUFJFVikgOiAiW2Rlc3RydWN0ZWQgb2JqZWN0XSIpKTsKICByZXR1cm4gTE9XRVIoc3RyKT09TE9XRVIoVE9PTF9OQU1FKTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHNob3J0IGFuZCBsb25nIGRlc2NyaXB0aW9uCiAqLwoKc3RyaW5nIHNob3J0KCkKewogIHJldHVybiBfcXVlcnlfc2hvcnQoKSsiLlxuIjsKfQoKc3RyaW5nIF9xdWVyeV9zaG9ydCgpCnsKICBzdHJpbmcgc2g7IC8vIGFkZGVkIGJ5IFJ1bWF0YQogIGlmKGNsb25lcikKICB7CiAgICBpZigoIXNlY3VyaXR5KCkpJiZNT0RFKE1PREVfU0NBTkNISykmJiFJU19BUkNIKFJUUCkpCiAgICAgIFdETE4oY3JuYW1lKFJUUCkrIiBzY2FubmVkIHlvdSAoc2hvcnQpIFsiK3F1ZXJ5X3ZlcmIoKSsiXSAiKwoJICAgKFBSRVYgPyBPYmpGaWxlKFBSRVYpIDogIltkZXN0cnVjdGVkIG9iamVjdF0iKSk7CglpZiggc2g9UXVlcnkoUF9TSE9SVCkgKSByZXR1cm4gc2g7IC8vIGFkZGVkIGJ5IFJ1bWF0YQogICAgcmV0dXJuIGNsb25lci0+bmFtZShXRVNTRU4pKyIgIitUT09MX1RJVExFKyIgWyIrCiAgICAgIGN0aW1lKHRpbWUoKSlbMTEuLjE4XSsiXSI7CiAgfQogIHJldHVybiBUT09MX1RJVExFOwp9CgpzdHJpbmcgbG9uZygpCnsKICByZXR1cm4gX3F1ZXJ5X2xvbmcoKTsKfQoKc3RyaW5nIF9xdWVyeV9sb25nKCkKewogIGlmKGNsb25lciYmIXNlY3VyaXR5KCkmJk1PREUoTU9ERV9TQ0FOQ0hLKSYmIUlTX0FSQ0goUlRQKSkKICB7CiAgICBXRExOKGNybmFtZShSVFApKyIgc2Nhbm5lZCB5b3UgKGxvbmcpIFsiK3F1ZXJ5X3ZlcmIoKSsiXSAiKwoJIChQUkVWID8gT2JqRmlsZShQUkVWKSA6ICJbZGVzdHJ1Y3RlZCBvYmplY3RdIikpOwogIH0KICByZXR1cm4gCiAgICAiVGhpcyBpcyAiK1RPT0xfTkFNRSsiIHZlcnNpb24gIitUT09MX1ZFUlNJT04rCiAgICAiIChtYWludGFpbmVkIGJ5IEtpcmtATW9yZ2VuR3JhdWVuKVxuIisKICAgICJPcmlnaW5hbCBjb3B5cmlnaHQgaGVsZCBieSBIeXAuXG4iKwogICAgIkdhbWVkcml2ZXIgcGF0Y2hsZXZlbDogIitfX1ZFUlNJT05fXysiIG1hc3RlciBvYmplY3Q6ICIrX19NQVNURVJfT0JKRUNUX18rCiAgICAiXG5cbkRvICd4aGVscCcgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4iOwp9CgpzdHJpbmcgbmFtZShtaXhlZCBkdW1teTEsIG1peGVkIGR1bW15MikKewogIHJldHVybiBfcXVlcnlfc2hvcnQoKTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGxpZ2h0IHN0dWZmCiAqLwoKaW50IF9xdWVyeV9saWdodCgpCnsKICByZXR1cm4geGxpZ2h0Owp9CgppbnQgX3NldF9saWdodChpbnQgeCkKewogIHJldHVybiB4bGlnaHQ7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBBdXRvbG9hZGluZwogKi8KCm1peGVkICpfcXVlcnlfYXV0b2xvYWRvYmooKQp7CiAgcmV0dXJuIEFVVE9MT0FEX0FSR1M7Cn0KCnZvaWQgX3NldF9hdXRvbG9hZG9iaihtaXhlZCAqYXJncykKewogIFdMTihUT09MX1RJVExFKyIgLi4uIik7CiAgaWYoIXBvaW50ZXJwKGFyZ3MpKQogICAgOwogIGVsc2UgaWYoc2l6ZW9mKGFyZ3MpIT0zKQogICAgOwogIGVsc2UgaWYoIXN0cmluZ3AoYXJnc1swXSkpCiAgICA7CiAgZWxzZSBpZighaW50cChhcmdzWzFdKSkKICAgIDsKICBlbHNlIGlmKCFpbnRwKGFyZ3NbMl0pKQogICAgOwogIGVsc2UKICB7CiAgICBpZigoc3RyaW5nKWFyZ3NbMF0hPVRPT0xfSU5URVJOQUwpCiAgICB7CiAgICAgIFdMTigiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKICAgICAgV0xOKCIqKioJICAgIE5FVyBFRElUSU9OICAgICAgKioqIik7CiAgICAgIFdMTigiKioqCWRvICd4dG9vbCBuZXdzJyBmb3IgICoqKiIpOwogICAgICBXTE4oIioqKgkgbW9yZSBpbmZvcm1hdGlvbiAgICAqKioiKTsKICAgICAgV0xOKCIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwogICAgfQogICAgbW9kaT0oaW50KWFyZ3NbMV07CiAgICBtb3JlbGluZXM9KGludClhcmdzWzJdOwogICAgcmV0dXJuOwogIH0KICBXKCIoYmFkIGF1dG9sb2FkLCB1c2luZyBkZWZhdWx0KVxuIik7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBjcmVhdGlvbiwgdXBkYXRpbmcgYW5kIGluaXRpYWxpemF0aW9uIHN0dWZmCiAqLwoKdm9pZCB1cGRhdGVfdG9vbChtaXhlZCAqYXJncywgb2JqZWN0IG9iaikKewogIFNFQ1VSRTEoKTsKICBpZighKG9iaiYmYXJncykpCiAgICByZXR1cm47CiAgRGVzdHJ1Y3QoUFJFVik7CiAgX3NldF9hdXRvbG9hZG9iaihhcmdzKTsKICBtb3ZlKG9iaik7Cn0KCnZvaWQgY3JlYXRlKCkKewogIG9iamVjdCBvYmo7CiAgCiAgaWYobWVtYmVyKG9iamVjdF9uYW1lKCksJyMnKTwwKQogICAgcmV0dXJuOwogIGlmKCFjbG9uZXImJiEoKGNsb25lcj1UUCl8fChjbG9uZXI9RU5WKE1FKSkpJiYhaW50ZXJhY3RpdmUoY2xvbmVyKSkKICAgIGRlc3RydWN0KE1FKTsKICBpZighSVNfTEVBUk5FUihjbG9uZXIpKQogICAgZGVzdHJ1Y3QoTUUpOwogIFNldFByb3AoUF9OT0RST1AsIkRhcyB3YWVyZSB6dSBnZWZhZWhybGljaC5cbiIpOwogIFNldFByb3AoUF9ORVZFUkRST1AsMSk7CiAgU2V0UHJvcChQX05PQlVZLDEpOwogIGlmKGZpbGVfc2l6ZShTQVZFX0ZJTEUrIi5vIik+MCkKICB7CiAgICBXRExOKCJMb2FkaW5nICIrVE9PTF9USVRMRSsiIHNldHRpbmdzIik7CiAgICByZXN0b3JlX29iamVjdChTQVZFX0ZJTEUpOwogIH0KICBpZihNT0RFKE1PREVfRklSU1QpKQogICAgY2FsbF9vdXQoIm1vdmUiLDAsY2xvbmVyKTsKICBjYWxsX291dCgiYWRkX2luc2VydF9ob29rIiwxLE1FKTsKfQoKdm9pZCBUSyhzdHJpbmcgc3RyKQp7CiAgaWYgKCF4dGspCiAgICByZXR1cm47CiAgdGVsbF9vYmplY3QoY2xvbmVyLCJYVE9PTDogIitzdHIrIlxuIik7Cn0KCmludCBYdGsoc3RyaW5nIHN0cikKewogIHh0az0heHRrOwogIFdETE4oIlh0b29sIGludGVybmFsIHRyYWNpbmcgIisoeHRrPyJlbmFibGVkIjoiZGlzYWJsZWQiKSk7CiAgcmV0dXJuIFRSVUU7Cn0KCnZvaWQgYWRkX2luc2VydF9ob29rKG9iamVjdCBvYmopCnsKICBpZihvYmplY3RwKG9iaikpCiAgICBjbG9uZXItPkFkZEluc2VydEhvb2sob2JqKTsKfQoKdm9pZCBpbml0KCkKewogIG9iamVjdCBmaXJzdCwgcHJldjsKICAKICBpZihtZW1iZXIob2JqZWN0X25hbWUoKSwnIycpPDApIHJldHVybjsKICBmaXJzdD1maXJzdF9pbnZlbnRvcnkoRU5WKE1FKSk7CiAgaWYoTU9ERShNT0RFX1BST1RFQ1QpJiZpc19wbGF5ZXIoZmlyc3QpJiYhSVNfQVJDSChmaXJzdCkpCiAgewogICAgV0RMTigiV0FSTklORzogIitjcm5hbWUoZmlyc3QpKyIgdHJpZWQgdG8gbW92ZSBpbnRvIHlvdXIgaW52ZW50b3J5Iik7CiAgICB0ZWxsX29iamVjdChmaXJzdCwgIllvdSBjYW5ub3QgbW92ZSB5b3Vyc2VsZiBpbnRvICIrCgkJY3JuYW1lKGNsb25lcikrIidzIGludmVudG9yeS5cbiIpOwogICAgY2FsbF9vdXQoIkRyb3BPYmoiLDAsZmlyc3QpOwogICAgcmV0dXJuOwogIH0KICBlbHNlIGlmKE1PREUoTU9ERV9GSVJTVCkmJmZpcnN0IT1NRSkKICAgIG1vdmUoY2xvbmVyKTsKICBlbHNlIGFjdGlvbnMoKTsKfQoKdm9pZCBEcm9wT2JqKG9iamVjdCBvYmopCnsKICBpZighb2JqfHwhb2JqZWN0cChvYmopKQogICAgcmV0dXJuOwogIG9iai0+bW92ZShFTlYoY2xvbmVyKSxNX05PQ0hFQ0t8TV9OT19TSE9XKTsKfQoKI2RlZmluZSBBQ1RJT05TXAooW1wKICAieGNhbGxvdXRzIiA6ICJYY2FsbG91dHMiOzA7MSxcCiAgInhjYWxsIiAgICAgOiAiWGNhbGwiOzA7MSxcCiAgInhjYXQiICAgICAgOiAiWGNhdCI7MTsxLFwKICAieGNkIiAgICAgICA6ICJYY2QiOzA7MCxcCiAgInhjbGVhbiIgICAgOiAiWGNsZWFuIjswOzAsXAogICJ4Y2xvbmUiICAgIDogIlhjbG9uZSI7MDswLFwKICAieHVjbG9uZSIgICA6ICJYdWNsb25lIjswOzAsXAogICJ4Y21kcyIgICAgIDogIlhjbWRzIjswOzEsXAogICJ4ZGJnIiAgICAgIDogIlhkYmciOzA7MCxcCiAgInhkY2xlYW4iICAgOiAiWGRjbGVhbiI7MDswLFwKICAieGRkZXMiICAgICA6ICJYZGRlcyI7MDswLFwKICAieGRlcyIgICAgICA6ICJYZGVzIjswOzAsXAogICJ4ZGVzdCIgICAgIDogIlhkZXMiOzA7MCxcCiAgInhkbG9vayIgICAgOiAiWGRsb29rIjswOzEsXAogICJ4ZG8iICAgICAgIDogIlhkbyI7MDswLFwKICAieGR1cGRhdGUiICA6ICJYZHVwZGF0ZSI7MDswLFwKICAieGVjaG8iICAgICA6ICJYZWNobyI7MDswLFwKICAieGV2YWwiICAgICA6ICJYZXZhbCI7MDsxLFwKICAieGZvcmFsbCIgICA6ICJYZm9yYWxsIjswOzAsXAogICJ4Z290byIgICAgIDogIlhnb3RvIjswOzAsXAogICJ4aGJlYXRzIiAgIDogIlhoYmVhdHMiOzA7MSxcCiAgInhncmVwIiAgICAgOiAiWGdyZXAiOzE7MSxcCiAgInhoZWFkIiAgICAgOiAiWGhlYWQiOzE7MSxcCiAgInhoZWxwIiAgICAgOiAiWGhlbHAiOzA7MCxcCiAgInhpbnZlbnRvcnkiOiAiWGludmVudG9yeSI7MDsxLFwKICAieGlkcyIgICAgICA6ICJYaWRzIjswOzAsXAogICJ4aW5mbyIgICAgIDogIlhpbmZvIjswOzAsXAogICJ4aW5oZXJpdCIgIDogIlhpbmhlcml0IjswOzEsXAogICJ4bGFnIiAgICAgIDogIlhsYWciOzA7MCxcCiAgInhsaWdodCIgICAgOiAiWGxpZ2h0IjswOzAsXAogICJ4bG9hZCIgICAgIDogIlhsb2FkIjswOzAsXAogICJ4bG9vayIgICAgIDogIlhsb29rIjswOzEsXAogICJ4bHBjIiAgICAgIDogIlhscGMiOzA7MCxcCiAgInhtYW4iICAgICAgOiAiWG1hbiI7MDswLFwKICAieG1vcmUiICAgICA6ICJYbW9yZSI7MTswLFwKICAieG1vdmUiICAgICA6ICJYbW92ZSI7MDswLFwKICAieG1zZyIgICAgICA6ICJYbXNnIjsxOzAsXAogICJ4bXRwIiAgICAgIDogIlhtdHAiOzA7MCxcCiAgInhwcm9jIiAgICAgOiAiWHByb2MiOzA7MSxcCiAgInhwcm9mIiAgICAgOiAiWHByb2YiOzA7MCxcCiAgInhwcm9wcyIgICAgOiAiWHByb3BzIjswOzEsXAogICJ4cXVpdCIgICAgIDogIlhxdWl0IjswOzAsXAogICJ4c2NhbiIgICAgIDogIlhzY2FuIjswOzAsXAogICJ4c2V0IiAgICAgIDogIlhzZXQiOzA7MCxcCiAgInhzaCIgICAgICAgOiAiWHNoIjswOzAsXAogICJ4c29ydCIgICAgIDogIlhzb3J0IjsxOzEsXAogICJ4dGFpbCIgICAgIDogIlh0YWlsIjsxOzEsXAogICJ4dGsiICAgICAgIDogIlh0ayI7MDswLFwKICAieHRvb2wiICAgICA6ICJYdG9vbCI7MDswLFwKICAieHRyYWNlIiAgICA6ICJYdHJhY2UiOzA7MCxcCiAgInh0cmFucyIgICAgOiAiWHRyYW5zIjswOzAsXAogICJ4dXBkYXRlIiAgIDogIlh1cGRhdGUiOzA7MCxcCiAgInh3YyIgICAgICAgOiAiWHdjIjsxOzAsXAogICJ4d2hvIiAgICAgIDogIlh3aG8iOzA7MSxcCiAgXSkKCnN0YXRpYyBzdHJpbmcgUHJlcGFyZUxpbmUoc3RyaW5nIHN0cikKewogIHJldHVybiBzdHI7Cn0KCnN0YXRpYyBzdHJpbmcgUXVvdGVMaW5lKHN0cmluZyBzdHIpCnsKICBzdHJpbmcgKnRtcCwqdG1wMjsKICBpbnQgaSwgaTIsIGxlbiwgbGVuMiwgcWQsIHFzOwoKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXFxcIiwisEJTSEwiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXFwiIiwisERCTFEiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXFwnIiwisFNHTFEiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXHwiLCKwUElQRSIpOwogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsInx8IiwisE9ST1IiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCItPiIsIrBMQVJSIik7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwiXFwkIiwisERPTFIiKTsKICB0bXA9cmVnZXhwbG9kZShzdHIsIihcInwnKSIpOwogIGxlbj1zaXplb2YodG1wKTsKICBxZD1xcz0wOwogIGZvcihpPTA7aTxsZW47aSsrKQogIHsKICAgIGlmKGklMikKICAgIHsKICAgICAgaWYodG1wW2ldPT0iJyIpCglxZD0oIXFzPyFxZDpxZCk7CiAgICAgIGVsc2UKCXFzPSghcWQ/IXFzOnFzKTsKICAgICAgaWYoKHRtcFtpXT09IlwiIiYmIXFkKXx8KHRtcFtpXT09IiciJiYhcXMpKQoJdG1wW2ldPSIiOwogICAgfQogICAgZWxzZQogICAgewogICAgICBpZighcWQpCiAgICAgIHsKCWxlbjI9c2l6ZW9mKHRtcDI9cmVnZXhwbG9kZSh0bXBbaV0sIlxcJFteIF1bXiBdKiIpKTsKCWZvcihpMj0wO2kyPGxlbjI7aTIrKykKCSAgaWYoaTIlMikKCSAgewoJICAgIFRLKCJRdW90ZUxpbmU6ICIrdG1wMltpMl1bMS4uXSk7CgkgICAgdG1wMltpMl09KHN0cmluZylYRmluZE9iaigodG1wMltpMl0pWzEuLl0pOwoJICB9Cgl0bXBbaV09aW1wbG9kZSh0bXAyLCIiKTsKICAgICAgfQogICAgfQogIH0KICBpZihxZHx8cXMpCiAgICByZXR1cm4gTlVMTDsKICBzdHI9aW1wbG9kZSh0bXAsIiIpOwogIFRLKCJRdW90ZUxpbmU6IHN0cjogIitzdHIpOwogIHJldHVybiBzdHI7Cn0KCnN0YXRpYyBzdHJpbmcgVW5xdW90ZUxpbmUoc3RyaW5nIHN0cikKewogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIrBCU0hMIiwiXFwiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCKwREJMUSIsIlwiIik7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisFNHTFEiLCJcJyIpOwogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIrBEUVVPIiwiIik7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisFNRVU8iLCIiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCKwUElQRSIsInwiKTsKICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCKwT1JPUiIsInx8Iik7CiAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisExBUlIiLCItPiIpOwogIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIrBET0xSIiwiJCIpOwogIFRLKCJVbnF1b3RlTGluZTogc3RyOiAiK3N0cik7CiAgcmV0dXJuIHN0cjsKfQoKc3RhdGljIHN0cmluZyAqRXhwbG9kZUNtZHMoc3RyaW5nIHN0cikKewogIHN0cmluZyAqdG1wOwogIAogIHRtcD1yZWdleHBsb2RlKHN0ciwiXFx8fD58Pj4iKTsKICB3aGlsZSh0bXBbPDFdPT0iIikKICAgIHRtcD10bXBbMC4uPDJdOwogIHJldHVybiB0bXA7Cn0KCnZhcmFyZ3MgaW50IFBhcnNlTGluZShzdHJpbmcgc3RyKQp7CiAgc3RyaW5nIHZlcmIsIGFyZzsKICBpbnQgcmV0OwogIAogIFRLKCJQYXJzZUxpbmU6IHN0cjogIisoc3RyP3N0cjoiIikpOwogIGlmKCFzaXplb2YoY21kcykpCiAgewogICAgLy8gdGhpcyBpcyBhIHNpbmdsZSBjb21tYW5kIG9yIGJlZ2lubmluZyBvZiBhIGNvbW1hbmQgcGlwZQogICAgdmVyYj1xdWVyeV92ZXJiKCk7CgogICAgLy8gcmV0dXJuIG9uIHVua25vd24gY29tbWFuZHMKICAgIGlmKCF2ZXJifHwhc2l6ZW9mKHZlcmIpfHwhR2V0RnVuYyh2ZXJiLFRSVUUpKQogICAgICByZXR1cm4gRkFMU0U7CgogICAgc3RyPShzdHJpbmcpdGhpc19wbGF5ZXIoKS0+X3VucGFyc2VkX2FyZ3MoKTsKICAgIHBpcGVfaW49RkFMU0U7CiAgICBwaXBlX29mPU5VTEw7CiAgICBwaXBlX292cj1UUlVFOwogICAgcGlwZV9vdXQ9RkFMU0U7CiAgICBwaXBlX29mPU5VTEw7CiAgICAvLyBwYXNzIGFyZ3VtZW50cyB0byBzb21lIHNwZWNpYWwgZnVuY3Rpb25zIHVucGFyc2VkCiAgICBpZihtZW1iZXIoKHsieGxwYyIsInhjYWxsIiwieGV2YWwifSksdmVyYik+PTApCiAgICB7CiNpZmRlZiBYREJHCiAgICAgIFRLKCJQYXJzZUxpbmU6IHNwZWNpYWwgZnVuYzogIit2ZXJiKTsKI2VuZGlmCiAgICAgIHJldD1DYWxsRnVuYyh2ZXJiLHN0cik7CiAgICAgIFNhZmVSZXR1cm4ocmV0KTsKICAgIH0KICAgIC8vIG9rLCBoZXJlIHdlIGdvCiAgICBwaXBlX2luPXBpcGVfb3V0PUZBTFNFOwogICAgcGlwZV9pZj1waXBlX29mPU5VTEw7CiAgICBwaXBlX292cj1UUlVFOwogICAgaWYoZmlsZV9zaXplKFBJUEVfRklMRSk+PTApCiAgICAgIHJtKFBJUEVfRklMRSk7CiAgICBpZiAoc3RyJiZzdHIhPSIiKQkgIAogICAgewogICAgICBpZighKHN0cj1RdW90ZUxpbmUoc3RyKSkpCiAgICAgIHsKCVdETE4oIlVudGVybWluYXRlZCBxdW90YXRpb24iKTsKCVNhZmVSZXR1cm4oVFJVRSk7CiAgICAgIH0KICAgICAgY21kcz1FeHBsb2RlQ21kcyhzdHIpOwogICAgfQogICAgZWxzZQogICAgICBjbWRzPSh7IiJ9KTsKICAgIGFyZz1zdHJpcF9zdHJpbmcoY21kc1swXSk7CiAgfQogIGVsc2UKICB7CiAgICBjbWRzWzBdPXN0cmlwX3N0cmluZyhjbWRzWzBdKTsKICAgIFRLKCJQYXJzZUxpbmU6IGNtZHNbMF06ICIrY21kc1swXSk7CiAgICBpZihzc2NhbmYoY21kc1swXSwiJXMgJXMiLHZlcmIsYXJnKSE9MikKICAgIHsKICAgICAgdmVyYj1jbWRzWzBdOwogICAgICBhcmc9IiI7CiAgICB9CiAgfQogIGNtZHM9Y21kc1sxLi5dOwogIFRLKCJQYXJzZUxpbmU6IHZlcmI6ICIrdmVyYik7CiAgaWYgKCF2ZXJifHwhc2l6ZW9mKHZlcmIpfHwhR2V0RnVuYyh2ZXJiLFRSVUUpKQogICAgU2FmZVJldHVybihGQUxTRSk7CiAgVEsoIlBhcnNlTGluZSgxKTogYXJnOiAiK2FyZysiIGNtZHM6ICIrc3ByaW50ZigiJU8iLGNtZHMpKTsKICBzd2l0Y2goc2l6ZW9mKGNtZHMpKQogIHsKICAgIGNhc2UgMDoKICAgIHJldD1DYWxsRnVuYyh2ZXJiLHN0cmlwX3N0cmluZyhVbnF1b3RlTGluZShhcmcpKSk7CiAgICBTYWZlUmV0dXJuKHJldCk7CiAgICBicmVhazsKICAgIAogICAgY2FzZSAxOgogICAgV0RMTigiTWlzc2luZyByaHMgb2YgY29tbWFuZCBwaXBlIik7CiAgICBTYWZlUmV0dXJuKFRSVUUpOwogICAgYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6CiAgICBwaXBlX291dD1UUlVFOwogICAgc3dpdGNoKGNtZHNbMF0pCiAgICB7CiAgICAgIGNhc2UgInwiOgogICAgICBwaXBlX29mPVBJUEVfRklMRTsKICAgICAgcGlwZV9vdnI9VFJVRTsKICAgICAgY21kcz1jbWRzWzEuLl07CiAgICAgIGJyZWFrOwogICAgICAKICAgICAgY2FzZSAiPiI6CiAgICAgIHBpcGVfb3ZyPVRSVUU7CiAgICAgIGlmKHNpemVvZihjbWRzKSE9MikKICAgICAgewoJV0RMTigiSWxsZWdhbCBJTyByZWRpcmVjdGlvbiIpOwoJU2FmZVJldHVybihUUlVFKTsKICAgICAgfQogICAgICBwaXBlX29mPWNtZHNbMV07CiAgICAgIGNtZHM9KHt9KTsKICAgICAgYnJlYWs7CiAgICAgIAogICAgICBjYXNlICI+PiI6CiAgICAgIHBpcGVfb3ZyPUZBTFNFOwogICAgICBpZihzaXplb2YoY21kcykhPTIpCiAgICAgIHsKCVdETE4oIklsbGVnYWwgSU8gcmVkaXJlY3Rpb24iKTsKCVNhZmVSZXR1cm4oVFJVRSk7CiAgICAgIH0KICAgICAgcGlwZV9vZj1jbWRzWzFdOwogICAgICBjbWRzPSh7fSk7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBUSygiUGFyc2VMaW5lKDIpOiBhcmc6ICIrYXJnKyIgY21kczogIitzcHJpbnRmKCIlTyIsY21kcykpOwogIGlmKCFDYWxsRnVuYyh2ZXJiLHN0cmlwX3N0cmluZyhhcmcpKSkKICAgIFNhZmVSZXR1cm4oRkFMU0UpOwogIHBpcGVfaW49cGlwZV9vdXQ7CiAgcGlwZV9pZj1waXBlX29mOwogIHBpcGVfb3ZyPUZBTFNFOwogIHBpcGVfb3V0PUZBTFNFOwogIHBpcGVfb2Y9TlVMTDsKICBpZihzaXplb2YoY21kcykpCiAgICBjYWxsX291dCgiUGFyc2VMaW5lIiwwKTsKICBlbHNlCiAgICBTYWZlUmV0dXJuKFRSVUUpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgaW50IENhbGxGdW5jKHN0cmluZyB2ZXJiLCBzdHJpbmcgc3RyKQp7CiAgc3RyaW5nIGZ1bjsKCiAgZnVuPUdldEZ1bmModmVyYixGQUxTRSk7CiNpZmRlZiBYREJHCiAgVEsoIkNhbGxGdW5jOiB2ZXJiOiAiK3ZlcmIrIiBzdHI6ICIrc3RyKTsKICBUSygiQ2FsbEZ1bmM6IHJlc29sdmVkIGZ1bmN0aW9uOiAiKyhmdW4/ZnVuOiIodW5yZXNvbHZlZCkiKSk7CiNlbmRpZgogIGlmKHN0cj09IiIpCiAgICBzdHI9TlVMTDsKICByZXR1cm4gZnVuPyhpbnQpY2FsbF9vdGhlcihNRSxmdW4sc3RyKTpGQUxTRTsKfQoKc3RhdGljIHN0cmluZyBHZXRGdW5jKHN0cmluZyB2ZXJiLCBpbnQgdGVzdCkKewogIHN0cmluZyBmdW4sKmtleXMsa2V5OwogIGludCBpLGxlbjsKCiAgVEsoIkdldEZ1bmM6IHZlcmI6ICIrdmVyYik7CgogIGlmKHZlcmJbMC4uMF0hPSJ4IikgLy8gQXNzdW1lIGFsbCBjb21tYW5kcyBzdGFydCB3aXRoICJ4IgogICAgcmV0dXJuIDA7CgogIGlmICghKGZ1bj0oc3RyaW5nKUFDVElPTlNbdmVyYiwwXSkpIHsgLy8gVHJ5IGV4YWN0IGhpdCBmaXJzdAogICAga2V5PSIiOwogICAgbGVuPXNpemVvZih2ZXJiKTsKICAgIGZvciAoaT1zaXplb2Yoa2V5cz1tX2luZGljZXMoQUNUSU9OUykpLTE7aT49MDtpLS0pIHsKICAgICAgVEsoIiAgdHJ5aW5nOiAiK2tleXNbaV0pOwogICAgICBpZihzaXplb2Yoa2V5c1tpXSk+PWxlbiYma2V5c1tpXVswLi5sZW4tMV09PXZlcmIpIHsKCWlmKHNpemVvZihrZXkpKSB7CgkgIFdMTigiRGFzIGlzdCBuaWNodCBlaW5kZXV0aWcgLi4uIik7CgkgIHJldHVybiAwOwoJfQoJZnVuPUFDVElPTlNba2V5c1tpXSwwXTsKCWtleT1rZXlzW2ldOwoJLy9icmVhazsKICAgICAgfQogICAgfQogIH0gZWxzZQogICAga2V5PXZlcmI7CgogIGlmKHRlc3QpCiAgICByZXR1cm4gZnVuOwogIAogIGlmIChrZXkpIHsKI2lmZGVmIFhEQkcKICAgIFRLKCJHZXRGdW5jOiBmdW46ICIrZnVuKyIgKGtleTogIitrZXkrIilcbiIrCiAgICAgICAicGlwZV9pbjogIisocGlwZV9pbj8iVFJVRSAgIjoiRkFMU0UgIikrKHBpcGVfaWY/cGlwZV9pZjoiKE5VTEwpIikrIlxuIisKICAgICAgICJwaXBlX291dDogIisocGlwZV9vdXQ/IlRSVUUgICI6IkZBTFNFICIpKyhwaXBlX29mP3BpcGVfb2Y6IihOVUxMKSIpKyJcbiIrCiAgICAgICAicGlwZV9vdnI6ICIrKHBpcGVfb3ZyPyJUUlVFIjoiRkFMU0UiKSk7CiNlbmRpZgogICAgaWYgKHBpcGVfaW4mJiFBQ1RJT05TW2tleSxQSVBFX0lOXSkKICAgIHsKICAgICAgLy8gdGhpcyBjb21tYW5kIGRvZXMgbm90IHJlYWQgcGlwZXMKI2lmZGVmIFhEQkcKICAgICAgVEsoIklsbGVnYWwgcmhzIG9mIGNvbW1hbmQgcGlwZSBcIiIrZnVuKyJcIlxuIik7CiNlbmRpZgogICAgICBub3RpZnlfZmFpbCgiSWxsZWdhbCByaHMgb2YgY29tbWFuZCBwaXBlIFwiIitmdW4rIlwiXG4iKTsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBlbHNlIGlmIChwaXBlX291dCYmIUFDVElPTlNba2V5LFBJUEVfT1VUXSkKICAgIHsKICAgICAgLy8gdGhpcyBjb21tYW5kIGRvZXMgbm90IGZlZWQgcGlwZXMKI2lmZGVmIFhEQkcKICAgICAgVEsoIklsbGVnYWwgbGhzIG9mIGNvbW1hbmQgcGlwZSBcIiIrZnVuKyJcIlxuIik7CiNlbmRpZgogICAgICBub3RpZnlfZmFpbCgiSWxsZWdhbCBsaHMgb2YgY29tbWFuZCBwaXBlIFwiIitmdW4rIlwiXG4iKTsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgfQogIHJldHVybiBmdW47Cn0KCnZvaWQgYWN0aW9ucygpCnsKICBpZiAoIWNsb25lcnx8IVJUUHx8Y2xvbmVyPT1SVFB8fHF1ZXJ5X3dpel9sZXZlbChjbG9uZXIpPD1xdWVyeV93aXpfbGV2ZWwoUlRQKSkKICAgIGFkZF9hY3Rpb24oIlBhcnNlTGluZSIsIiIsMSk7CiAgYWRkX2FjdGlvbigiQ29tbWFuZFNjYW4iLCAiIiwgMSk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgdGhlIGNoZWNraW5nIHN0dWZmCiAqLwoKdm9pZCBJbnNlcnROb3RpZnkob2JqZWN0IG9iaikKewogIGlmKCFjbG9uZXIpCiAgICByZXR1cm47CiAgaWYoTU9ERShNT0RFX0ZJUlNUKSAmJiBmaW5kX2NhbGxfb3V0KCJtb3ZlIik9PS0xKQogICAgY2FsbF9vdXQoIm1vdmUiLDAsY2xvbmVyKTsKICBpZihNT0RFKE1PREVfSU5WQ0hFQ0spKQogICAgd3JpdGVfbmV3aW52b2JqKG9iaik7Cn0KCnN0YXRpYyB2b2lkIFZhckNoZWNrKGludCBzaG93KQp7CiAgaW50IGksIHM7CiAgZm9yZWFjaChzdHJpbmcgaywgbWl4ZWQgdiA6IHZhcmlhYmxlKQogIHsKICAgIGlmICh2KSBjb250aW51ZTsKICAgIGlmKHNob3cpIFdETE4oIioqKiBWYXJpYWJsZSAkIitrKyIgaGFzIGJlZW4gZGVzdHJ1Y3RlZCIpOwogICAgbV9kZWxldGUodmFyaWFibGUsIGspOwogIH0KfQoKCmludCB3cml0ZV9uZXdpbnZvYmoob2JqZWN0IG9iaikKewogIGlmKG9iaikgV0RMTigiKioqIE5ldyBvYmplY3QgaW4gaW52ZW50b3J5ICIrT2JqRmlsZShvYmopKTsKICByZXR1cm4oMSk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgY2F0Y2ggYWxsIGNvbW1hbmRzLCBhYnNvcmIgZm9yY2VzIGFuZCBjaGVjayBoaXN0b3J5CiAqLwoKaW50IENvbW1hbmRTY2FuKHN0cmluZyBhcmcpCnsKICBzdHJpbmcgdmVyYiwgY21kOwogIG9iamVjdCBydHA7CiAgcnRwPVJUUDsKCiAgaWYoIWNsb25lciYmIShjbG9uZXI9cnRwKSkgZGVzdHJ1Y3QoTUUpOwoKICBpZigoIU1PREUoTU9ERV9QUk9URUNUKSl8fHNlY3VyaXR5KCl8fAogICAgIHF1ZXJ5X3dpel9sZXZlbChjbG9uZXIpPHF1ZXJ5X3dpel9sZXZlbChydHApKQogIHsKICAgIHZlcmI9cXVlcnlfdmVyYigpOwogICAgaWYodmVyYiYmRG9IaXN0b3J5KHZlcmIrKGFyZyA/ICIgIithcmcgOiAiIikpKQogICAgICByZXR1cm4gVFJVRTsKICAgIG5vc3RvcmU9RkFMU0U7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIGVsc2UKICB7CiAgICBpZihydHApCiAgICB7CiAgICAgIFdETE4oIllvdXIgIitUT09MX1RJVExFKyIgcHJvdGVjdHMgeW91IGZyb20gYSBmb3JjZSBieSAiK2NybmFtZShydHApKwoJICAgIiBbIitxdWVyeV92ZXJiKCkrKGFyZyA/ICIgIithcmcrIl0iIDogIl0iKSk7CiAgICAgIHRlbGxfb2JqZWN0KHJ0cCwgY3JuYW1lKGNsb25lcikrIidzICIrVE9PTF9USVRMRSsKCQkgICIgYWJzb3JiZXMgeW91ciBmb3JjZS5cbiIpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBXRExOKCJZb3VyICIrVE9PTF9USVRMRSsiIHByb3RlY3RzIHlvdSBmcm9tIGEgZm9yY2UgWyIrCgkgICBxdWVyeV92ZXJiKCkrKGFyZyA/ICIgIithcmcrIl0iIDogIl0iKSk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKICB9Cn0KCmludCBEb0hpc3Rvcnkoc3RyaW5nIGxpbmUpCnsKICBpbnQgaTsKICBzdHJpbmcgY21kLCAqc3RyczsKICAKICBTRUNVUkUyKEZBTFNFKTsKICBpZighc3RyaW5ncChsaW5lKSB8fCAhc2l6ZW9mKGxpbmUpKQogICAgcmV0dXJuIFRSVUU7CiAgZWxzZSBpZihsaW5lPT0iJSEiKQogIHsKICAgIFdMTigiQ3VycmVudCBjb21tYW5kIGhpc3Rvcnk6Iik7CiAgICBmb3IoaT1NQVhfSElTVE9SWTsgaTsgLS1pKQogICAgICBpZihoaXN0b3J5W2ktMV0pCiAgICAgIHsKCVcoIiAiK0FSSUdIVCgiIitpLCAyLCAiICIpKyI6ICIpOwoJaWYoc2l6ZW9mKGhpc3RvcnlbaS0xXSk+NzApCgkgIFdMTihBTEVGVChoaXN0b3J5W2ktMV0sIDcwLCAiICIpKTsKCWVsc2UKCSAgV0xOKGhpc3RvcnlbaS0xXSk7CiAgICAgIH0KICAgIHJldHVybiBUUlVFOwogIH0KICBlbHNlIGlmKGxpbmVbMC4uMV09PSIlJSIgJiYgKGNtZD1oaXN0b3J5WzBdK2xpbmVbMi4uPDFdKSkKICB7CiAgICBDb21tYW5kKGNtZCk7CiAgICByZXR1cm4gVFJVRTsKICB9CiAgZWxzZSBpZihsaW5lWzBdPT0nXicmJihzdHJzPXN0cmlwX2V4cGxvZGUobGluZSwgIl4iKSkpCiAgewogICAgaWYoc2l6ZW9mKHN0cnMpJiZzdHJzWzBdJiYoY21kPWhpc3RvcnlbMF0pKQogICAgewogICAgICBpZihzaXplb2Yoc3Rycyk9PTIpCgljbWQ9c3RyaW5nX3JlcGxhY2UoY21kLCBzdHJzWzBdLCBzdHJzWzFdKTsKICAgICAgZWxzZQoJY21kPXN0cmluZ19yZXBsYWNlKGNtZCwgc3Ryc1swXSwgIiIpOwogICAgICBub3N0b3JlLS07CiAgICAgIENvbW1hbmQoY21kKTsKICAgICAgbm9zdG9yZSsrOwogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CiAgZWxzZSBpZihsaW5lWzBdPT0nJScgJiYgKHNzY2FuZihsaW5lWzEuLjwxXSwgIiVkIiwgaSkpKQogIHsKICAgIGk9IGk+MCA/IGkgOiAxOwogICAgaT0gaTw9TUFYX0hJU1RPUlkgPyBpIDogTUFYX0hJU1RPUlk7CiAgICBpZihjbWQ9aGlzdG9yeVtpLTFdKQogICAgICBDb21tYW5kKGNtZCk7CiAgICByZXR1cm4gVFJVRTsKICB9CiAgZWxzZSBpZihsaW5lWzBdPT0nJScpCiAgewogICAgZm9yKGk9MDsgaTxNQVhfSElTVE9SWTsgaSsrKQogICAgewogICAgICBpZihoaXN0b3J5W2ldJiYKCSBoaXN0b3J5W2ldWzAuLnNpemVvZihsaW5lKS0yXT09bGluZVsxLi4gPDFdKQogICAgICB7CglDb21tYW5kKGhpc3RvcnlbaV0pOwoJcmV0dXJuIFRSVUU7CiAgICAgIH0KICAgIH0KICB9CiAgZWxzZSBpZihub3N0b3JlPDEpCiAgICBoaXN0b3J5PSh7bGluZX0pK2hpc3RvcnlbMC4uTUFYX0hJU1RPUlktMl07CiAgcmV0dXJuIEZBTFNFOwp9Cgo=