Ly89IFByaW50ZkZvcm1hdFN0cmluZ3MuY3BwIC0gQW5hbHlzaXMgb2YgcHJpbnRmIGZvcm1hdCBzdHJpbmdzIC0tKi0gQysrIC0qLT09Ly8KLy8KLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQovLwovLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwovLwovLyBIYW5kbGluZyBvZiBmb3JtYXQgc3RyaW5nIGluIHByaW50ZiBhbmQgZnJpZW5kcy4gIFRoZSBzdHJ1Y3R1cmUgb2YgZm9ybWF0Ci8vIHN0cmluZ3MgZm9yIGZwcmludGYoKSBhcmUgZGVzY3JpYmVkIGluIEM5OSA3LjE5LjYuMS4KLy8KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCiNpbmNsdWRlICJjbGFuZy9BbmFseXNpcy9BbmFseXNlcy9QcmludGZGb3JtYXRTdHJpbmcuaCIKI2luY2x1ZGUgImNsYW5nL0FTVC9BU1RDb250ZXh0LmgiCiNpbmNsdWRlICJjbGFuZy9BU1QvVHlwZS5oIgojaW5jbHVkZSAibGx2bS9TdXBwb3J0L3Jhd19vc3RyZWFtLmgiCgp1c2luZyBjbGFuZzo6YW5hbHl6ZV9wcmludGY6OkFyZ1R5cGVSZXN1bHQ7CnVzaW5nIGNsYW5nOjphbmFseXplX3ByaW50Zjo6Rm9ybWF0U3BlY2lmaWVyOwp1c2luZyBjbGFuZzo6YW5hbHl6ZV9wcmludGY6OkZvcm1hdFN0cmluZ0hhbmRsZXI7CnVzaW5nIGNsYW5nOjphbmFseXplX3ByaW50Zjo6T3B0aW9uYWxBbW91bnQ7CnVzaW5nIGNsYW5nOjphbmFseXplX3ByaW50Zjo6UG9zaXRpb25Db250ZXh0Owp1c2luZyBjbGFuZzo6YW5hbHl6ZV9wcmludGY6OkNvbnZlcnNpb25TcGVjaWZpZXI7CnVzaW5nIGNsYW5nOjphbmFseXplX3ByaW50Zjo6TGVuZ3RoTW9kaWZpZXI7Cgp1c2luZyBuYW1lc3BhY2UgY2xhbmc7CgpuYW1lc3BhY2UgewpjbGFzcyBGb3JtYXRTcGVjaWZpZXJSZXN1bHQgewogIEZvcm1hdFNwZWNpZmllciBGUzsKICBjb25zdCBjaGFyICpTdGFydDsKICBib29sIFN0b3A7CnB1YmxpYzoKICBGb3JtYXRTcGVjaWZpZXJSZXN1bHQoYm9vbCBzdG9wID0gZmFsc2UpCiAgICA6IFN0YXJ0KDApLCBTdG9wKHN0b3ApIHt9CiAgRm9ybWF0U3BlY2lmaWVyUmVzdWx0KGNvbnN0IGNoYXIgKnN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGb3JtYXRTcGVjaWZpZXIgJmZzKQogICAgOiBGUyhmcyksIFN0YXJ0KHN0YXJ0KSwgU3RvcChmYWxzZSkge30KCiAgY29uc3QgY2hhciAqZ2V0U3RhcnQoKSBjb25zdCB7IHJldHVybiBTdGFydDsgfQogIGJvb2wgc2hvdWxkU3RvcCgpIGNvbnN0IHsgcmV0dXJuIFN0b3A7IH0KICBib29sIGhhc1ZhbHVlKCkgY29uc3QgeyByZXR1cm4gU3RhcnQgIT0gMDsgfQogIGNvbnN0IEZvcm1hdFNwZWNpZmllciAmZ2V0VmFsdWUoKSBjb25zdCB7CiAgICBhc3NlcnQoaGFzVmFsdWUoKSk7CiAgICByZXR1cm4gRlM7CiAgfQogIGNvbnN0IEZvcm1hdFNwZWNpZmllciAmZ2V0VmFsdWUoKSB7IHJldHVybiBGUzsgfQp9Owp9IC8vIGVuZCBhbm9ueW1vdXMgbmFtZXNwYWNlCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KY2xhc3MgVXBkYXRlT25SZXR1cm4gewogIFQgJlZhbHVlVG9VcGRhdGU7CiAgY29uc3QgVCAmVmFsdWVUb0NvcHk7CnB1YmxpYzoKICBVcGRhdGVPblJldHVybihUICZ2YWx1ZVRvVXBkYXRlLCBjb25zdCBUICZ2YWx1ZVRvQ29weSkKICAgIDogVmFsdWVUb1VwZGF0ZSh2YWx1ZVRvVXBkYXRlKSwgVmFsdWVUb0NvcHkodmFsdWVUb0NvcHkpIHt9CgogIH5VcGRhdGVPblJldHVybigpIHsKICAgIFZhbHVlVG9VcGRhdGUgPSBWYWx1ZVRvQ29weTsKICB9Cn07CgovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwovLyBNZXRob2RzIGZvciBwYXJzaW5nIGZvcm1hdCBzdHJpbmdzLgovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwoKc3RhdGljIE9wdGlvbmFsQW1vdW50IFBhcnNlQW1vdW50KGNvbnN0IGNoYXIgKiZCZWcsIGNvbnN0IGNoYXIgKkUpIHsKICBjb25zdCBjaGFyICpJID0gQmVnOwogIFVwZGF0ZU9uUmV0dXJuIDxjb25zdCBjaGFyKj4gVXBkYXRlQmVnKEJlZywgSSk7CgogIHVuc2lnbmVkIGFjY3VtdWxhdG9yID0gMDsKICBib29sIGhhc0RpZ2l0cyA9IGZhbHNlOwoKICBmb3IgKCA7IEkgIT0gRTsgKytJKSB7CiAgICBjaGFyIGMgPSAqSTsKICAgIGlmIChjID49ICcwJyAmJiBjIDw9ICc5JykgewogICAgICBoYXNEaWdpdHMgPSB0cnVlOwogICAgICBhY2N1bXVsYXRvciA9IChhY2N1bXVsYXRvciAqIDEwKSArIChjIC0gJzAnKTsKICAgICAgY29udGludWU7CiAgICB9CgogICAgaWYgKGhhc0RpZ2l0cykKICAgICAgcmV0dXJuIE9wdGlvbmFsQW1vdW50KE9wdGlvbmFsQW1vdW50OjpDb25zdGFudCwgYWNjdW11bGF0b3IsIEJlZywgSSAtIEJlZywKICAgICAgICAgIGZhbHNlKTsKCiAgICBicmVhazsKICB9CgogIHJldHVybiBPcHRpb25hbEFtb3VudCgpOwp9CgpzdGF0aWMgT3B0aW9uYWxBbW91bnQgUGFyc2VOb25Qb3NpdGlvbkFtb3VudChjb25zdCBjaGFyIComQmVnLCBjb25zdCBjaGFyICpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmYXJnSW5kZXgpIHsKICBpZiAoKkJlZyA9PSAnKicpIHsKICAgICsrQmVnOwogICAgcmV0dXJuIE9wdGlvbmFsQW1vdW50KE9wdGlvbmFsQW1vdW50OjpBcmcsIGFyZ0luZGV4KyssIEJlZywgMCwgZmFsc2UpOwogIH0KCiAgcmV0dXJuIFBhcnNlQW1vdW50KEJlZywgRSk7Cn0KCnN0YXRpYyBPcHRpb25hbEFtb3VudCBQYXJzZVBvc2l0aW9uQW1vdW50KEZvcm1hdFN0cmluZ0hhbmRsZXIgJkgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyIComQmVnLCBjb25zdCBjaGFyICpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3NpdGlvbkNvbnRleHQgcCkgewogIGlmICgqQmVnID09ICcqJykgewogICAgY29uc3QgY2hhciAqSSA9IEJlZyArIDE7CiAgICBjb25zdCBPcHRpb25hbEFtb3VudCAmQW10ID0gUGFyc2VBbW91bnQoSSwgRSk7CgogICAgaWYgKEFtdC5nZXRIb3dTcGVjaWZpZWQoKSA9PSBPcHRpb25hbEFtb3VudDo6Tm90U3BlY2lmaWVkKSB7CiAgICAgIEguSGFuZGxlSW52YWxpZFBvc2l0aW9uKEJlZywgSSAtIEJlZywgcCk7CiAgICAgIHJldHVybiBPcHRpb25hbEFtb3VudChmYWxzZSk7CiAgICB9CgogICAgaWYgKEk9PSBFKSB7CiAgICAgIC8vIE5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0PwogICAgICBILkhhbmRsZUluY29tcGxldGVGb3JtYXRTcGVjaWZpZXIoU3RhcnQsIEUgLSBTdGFydCk7CiAgICAgIHJldHVybiBPcHRpb25hbEFtb3VudChmYWxzZSk7CiAgICB9CgogICAgYXNzZXJ0KEFtdC5nZXRIb3dTcGVjaWZpZWQoKSA9PSBPcHRpb25hbEFtb3VudDo6Q29uc3RhbnQpOwoKICAgIGlmICgqSSA9PSAnJCcpIHsKICAgICAgLy8gSGFuZGxlIHBvc2l0aW9uYWwgYXJndW1lbnRzCgogICAgICAvLyBTcGVjaWFsIGNhc2U6ICcqMCQnLCBzaW5jZSB0aGlzIGlzIGFuIGVhc3kgbWlzdGFrZS4KICAgICAgaWYgKEFtdC5nZXRDb25zdGFudEFtb3VudCgpID09IDApIHsKICAgICAgICBILkhhbmRsZVplcm9Qb3NpdGlvbihCZWcsIEkgLSBCZWcgKyAxKTsKICAgICAgICByZXR1cm4gT3B0aW9uYWxBbW91bnQoZmFsc2UpOwogICAgICB9CgogICAgICBjb25zdCBjaGFyICpUbXAgPSBCZWc7CiAgICAgIEJlZyA9ICsrSTsKCiAgICAgIHJldHVybiBPcHRpb25hbEFtb3VudChPcHRpb25hbEFtb3VudDo6QXJnLCBBbXQuZ2V0Q29uc3RhbnRBbW91bnQoKSAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbXAsIDAsIHRydWUpOwogICAgfQoKICAgIEguSGFuZGxlSW52YWxpZFBvc2l0aW9uKEJlZywgSSAtIEJlZywgcCk7CiAgICByZXR1cm4gT3B0aW9uYWxBbW91bnQoZmFsc2UpOwogIH0KCiAgcmV0dXJuIFBhcnNlQW1vdW50KEJlZywgRSk7Cn0KCnN0YXRpYyBib29sIFBhcnNlUHJlY2lzaW9uKEZvcm1hdFN0cmluZ0hhbmRsZXIgJkgsIEZvcm1hdFNwZWNpZmllciAmRlMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlN0YXJ0LCBjb25zdCBjaGFyIComQmVnLCBjb25zdCBjaGFyICpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAqYXJnSW5kZXgpIHsKICBpZiAoYXJnSW5kZXgpIHsKICAgIEZTLnNldFByZWNpc2lvbihQYXJzZU5vblBvc2l0aW9uQW1vdW50KEJlZywgRSwgKmFyZ0luZGV4KSk7CiAgfQogIGVsc2UgewogICAgY29uc3QgT3B0aW9uYWxBbW91bnQgQW10ID0gUGFyc2VQb3NpdGlvbkFtb3VudChILCBTdGFydCwgQmVnLCBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuYWx5emVfcHJpbnRmOjpQcmVjaXNpb25Qb3MpOwogICAgaWYgKEFtdC5pc0ludmFsaWQoKSkKICAgICAgcmV0dXJuIHRydWU7CiAgICBGUy5zZXRQcmVjaXNpb24oQW10KTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CgpzdGF0aWMgYm9vbCBQYXJzZUZpZWxkV2lkdGgoRm9ybWF0U3RyaW5nSGFuZGxlciAmSCwgRm9ybWF0U3BlY2lmaWVyICZGUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlN0YXJ0LCBjb25zdCBjaGFyIComQmVnLCBjb25zdCBjaGFyICpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgKmFyZ0luZGV4KSB7CiAgLy8gRklYTUU6IFN1cHBvcnQgbmVnYXRpdmUgZmllbGQgd2lkdGhzLgogIGlmIChhcmdJbmRleCkgewogICAgRlMuc2V0RmllbGRXaWR0aChQYXJzZU5vblBvc2l0aW9uQW1vdW50KEJlZywgRSwgKmFyZ0luZGV4KSk7CiAgfQogIGVsc2UgewogICAgY29uc3QgT3B0aW9uYWxBbW91bnQgQW10ID0gUGFyc2VQb3NpdGlvbkFtb3VudChILCBTdGFydCwgQmVnLCBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5hbHl6ZV9wcmludGY6OkZpZWxkV2lkdGhQb3MpOwogICAgaWYgKEFtdC5pc0ludmFsaWQoKSkKICAgICAgcmV0dXJuIHRydWU7CiAgICBGUy5zZXRGaWVsZFdpZHRoKEFtdCk7CiAgfQogIHJldHVybiBmYWxzZTsKfQoKc3RhdGljIGJvb2wgUGFyc2VBcmdQb3NpdGlvbihGb3JtYXRTdHJpbmdIYW5kbGVyICZILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdFNwZWNpZmllciAmRlMsIGNvbnN0IGNoYXIgKlN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiZCZWcsIGNvbnN0IGNoYXIgKkUpIHsKCiAgdXNpbmcgbmFtZXNwYWNlIGNsYW5nOjphbmFseXplX3ByaW50ZjsKICBjb25zdCBjaGFyICpJID0gQmVnOwoKICBjb25zdCBPcHRpb25hbEFtb3VudCAmQW10ID0gUGFyc2VBbW91bnQoSSwgRSk7CgogIGlmIChJID09IEUpIHsKICAgIC8vIE5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0PwogICAgSC5IYW5kbGVJbmNvbXBsZXRlRm9ybWF0U3BlY2lmaWVyKFN0YXJ0LCBFIC0gU3RhcnQpOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBpZiAoQW10LmdldEhvd1NwZWNpZmllZCgpID09IE9wdGlvbmFsQW1vdW50OjpDb25zdGFudCAmJiAqKEkrKykgPT0gJyQnKSB7CiAgICAvLyBTcGVjaWFsIGNhc2U6ICclMCQnLCBzaW5jZSB0aGlzIGlzIGFuIGVhc3kgbWlzdGFrZS4KICAgIGlmIChBbXQuZ2V0Q29uc3RhbnRBbW91bnQoKSA9PSAwKSB7CiAgICAgIEguSGFuZGxlWmVyb1Bvc2l0aW9uKFN0YXJ0LCBJIC0gU3RhcnQpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBGUy5zZXRBcmdJbmRleChBbXQuZ2V0Q29uc3RhbnRBbW91bnQoKSAtIDEpOwogICAgRlMuc2V0VXNlc1Bvc2l0aW9uYWxBcmcoKTsKICAgIC8vIFVwZGF0ZSB0aGUgY2FsbGVyJ3MgcG9pbnRlciBpZiB3ZSBkZWNpZGVkIHRvIGNvbnN1bWUKICAgIC8vIHRoZXNlIGNoYXJhY3RlcnMuCiAgICBCZWcgPSBJOwogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgcmV0dXJuIGZhbHNlOwp9CgpzdGF0aWMgRm9ybWF0U3BlY2lmaWVyUmVzdWx0IFBhcnNlRm9ybWF0U3BlY2lmaWVyKEZvcm1hdFN0cmluZ0hhbmRsZXIgJkgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqJkJlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZhcmdJbmRleCkgewoKICB1c2luZyBuYW1lc3BhY2UgY2xhbmc6OmFuYWx5emVfcHJpbnRmOwoKICBjb25zdCBjaGFyICpJID0gQmVnOwogIGNvbnN0IGNoYXIgKlN0YXJ0ID0gMDsKICBVcGRhdGVPblJldHVybiA8Y29uc3QgY2hhcio+IFVwZGF0ZUJlZyhCZWcsIEkpOwoKICAvLyBMb29rIGZvciBhICclJyBjaGFyYWN0ZXIgdGhhdCBpbmRpY2F0ZXMgdGhlIHN0YXJ0IG9mIGEgZm9ybWF0IHNwZWNpZmllci4KICBmb3IgKCA7IEkgIT0gRSA7ICsrSSkgewogICAgY2hhciBjID0gKkk7CiAgICBpZiAoYyA9PSAnXDAnKSB7CiAgICAgIC8vIERldGVjdCBzcHVyaW91cyBudWxsIGNoYXJhY3RlcnMsIHdoaWNoIGFyZSBsaWtlbHkgZXJyb3JzLgogICAgICBILkhhbmRsZU51bGxDaGFyKEkpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmIChjID09ICclJykgewogICAgICBTdGFydCA9IEkrKzsgIC8vIFJlY29yZCB0aGUgc3RhcnQgb2YgdGhlIGZvcm1hdCBzcGVjaWZpZXIuCiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgLy8gTm8gZm9ybWF0IHNwZWNpZmllciBmb3VuZD8KICBpZiAoIVN0YXJ0KQogICAgcmV0dXJuIGZhbHNlOwoKICBpZiAoSSA9PSBFKSB7CiAgICAvLyBObyBtb3JlIGNoYXJhY3RlcnMgbGVmdD8KICAgIEguSGFuZGxlSW5jb21wbGV0ZUZvcm1hdFNwZWNpZmllcihTdGFydCwgRSAtIFN0YXJ0KTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgRm9ybWF0U3BlY2lmaWVyIEZTOwogIGlmIChQYXJzZUFyZ1Bvc2l0aW9uKEgsIEZTLCBTdGFydCwgSSwgRSkpCiAgICByZXR1cm4gdHJ1ZTsKCiAgaWYgKEkgPT0gRSkgewogICAgLy8gTm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQ/CiAgICBILkhhbmRsZUluY29tcGxldGVGb3JtYXRTcGVjaWZpZXIoU3RhcnQsIEUgLSBTdGFydCk7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8vIExvb2sgZm9yIGZsYWdzIChpZiBhbnkpLgogIGJvb2wgaGFzTW9yZSA9IHRydWU7CiAgZm9yICggOyBJICE9IEU7ICsrSSkgewogICAgc3dpdGNoICgqSSkgewogICAgICBkZWZhdWx0OiBoYXNNb3JlID0gZmFsc2U7IGJyZWFrOwogICAgICBjYXNlICctJzogRlMuc2V0SXNMZWZ0SnVzdGlmaWVkKEkpOyBicmVhazsKICAgICAgY2FzZSAnKyc6IEZTLnNldEhhc1BsdXNQcmVmaXgoSSk7IGJyZWFrOwogICAgICBjYXNlICcgJzogRlMuc2V0SGFzU3BhY2VQcmVmaXgoSSk7IGJyZWFrOwogICAgICBjYXNlICcjJzogRlMuc2V0SGFzQWx0ZXJuYXRpdmVGb3JtKEkpOyBicmVhazsKICAgICAgY2FzZSAnMCc6IEZTLnNldEhhc0xlYWRpbmdaZXJvcyhJKTsgYnJlYWs7CiAgICB9CiAgICBpZiAoIWhhc01vcmUpCiAgICAgIGJyZWFrOwogIH0KCiAgaWYgKEkgPT0gRSkgewogICAgLy8gTm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQ/CiAgICBILkhhbmRsZUluY29tcGxldGVGb3JtYXRTcGVjaWZpZXIoU3RhcnQsIEUgLSBTdGFydCk7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8vIExvb2sgZm9yIHRoZSBmaWVsZCB3aWR0aCAoaWYgYW55KS4KICBpZiAoUGFyc2VGaWVsZFdpZHRoKEgsIEZTLCBTdGFydCwgSSwgRSwKICAgICAgICAgICAgICAgICAgICAgIEZTLnVzZXNQb3NpdGlvbmFsQXJnKCkgPyAwIDogJmFyZ0luZGV4KSkKICAgIHJldHVybiB0cnVlOwoKICBpZiAoSSA9PSBFKSB7CiAgICAvLyBObyBtb3JlIGNoYXJhY3RlcnMgbGVmdD8KICAgIEguSGFuZGxlSW5jb21wbGV0ZUZvcm1hdFNwZWNpZmllcihTdGFydCwgRSAtIFN0YXJ0KTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gTG9vayBmb3IgdGhlIHByZWNpc2lvbiAoaWYgYW55KS4KICBpZiAoKkkgPT0gJy4nKSB7CiAgICArK0k7CiAgICBpZiAoSSA9PSBFKSB7CiAgICAgIEguSGFuZGxlSW5jb21wbGV0ZUZvcm1hdFNwZWNpZmllcihTdGFydCwgRSAtIFN0YXJ0KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgaWYgKFBhcnNlUHJlY2lzaW9uKEgsIEZTLCBTdGFydCwgSSwgRSwKICAgICAgICAgICAgICAgICAgICAgICBGUy51c2VzUG9zaXRpb25hbEFyZygpID8gMCA6ICZhcmdJbmRleCkpCiAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmIChJID09IEUpIHsKICAgICAgLy8gTm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQ/CiAgICAgIEguSGFuZGxlSW5jb21wbGV0ZUZvcm1hdFNwZWNpZmllcihTdGFydCwgRSAtIFN0YXJ0KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICAvLyBMb29rIGZvciB0aGUgbGVuZ3RoIG1vZGlmaWVyLgogIExlbmd0aE1vZGlmaWVyOjpLaW5kIGxtS2luZCA9IExlbmd0aE1vZGlmaWVyOjpOb25lOwogIGNvbnN0IGNoYXIgKmxtUG9zaXRpb24gPSBJOwogIHN3aXRjaCAoKkkpIHsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogICAgY2FzZSAnaCc6CiAgICAgICsrSTsKICAgICAgbG1LaW5kID0gKEkgIT0gRSAmJiAqSSA9PSAnaCcpID8KICAgICAgICAgICsrSSwgTGVuZ3RoTW9kaWZpZXI6OkFzQ2hhciA6IExlbmd0aE1vZGlmaWVyOjpBc1Nob3J0OwogICAgICBicmVhazsKICAgIGNhc2UgJ2wnOgogICAgICArK0k7CiAgICAgIGxtS2luZCA9IChJICE9IEUgJiYgKkkgPT0gJ2wnKSA/CiAgICAgICAgICArK0ksIExlbmd0aE1vZGlmaWVyOjpBc0xvbmdMb25nIDogTGVuZ3RoTW9kaWZpZXI6OkFzTG9uZzsKICAgICAgYnJlYWs7CiAgICBjYXNlICdqJzogbG1LaW5kID0gTGVuZ3RoTW9kaWZpZXI6OkFzSW50TWF4OyAgICAgKytJOyBicmVhazsKICAgIGNhc2UgJ3onOiBsbUtpbmQgPSBMZW5ndGhNb2RpZmllcjo6QXNTaXplVDsgICAgICArK0k7IGJyZWFrOwogICAgY2FzZSAndCc6IGxtS2luZCA9IExlbmd0aE1vZGlmaWVyOjpBc1B0ckRpZmY7ICAgICsrSTsgYnJlYWs7CiAgICBjYXNlICdMJzogbG1LaW5kID0gTGVuZ3RoTW9kaWZpZXI6OkFzTG9uZ0RvdWJsZTsgKytJOyBicmVhazsKICAgIGNhc2UgJ3EnOiBsbUtpbmQgPSBMZW5ndGhNb2RpZmllcjo6QXNMb25nTG9uZzsgICArK0k7IGJyZWFrOwogIH0KICBMZW5ndGhNb2RpZmllciBsbShsbVBvc2l0aW9uLCBsbUtpbmQpOwogIEZTLnNldExlbmd0aE1vZGlmaWVyKGxtKTsKCiAgaWYgKEkgPT0gRSkgewogICAgLy8gTm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQ/CiAgICBILkhhbmRsZUluY29tcGxldGVGb3JtYXRTcGVjaWZpZXIoU3RhcnQsIEUgLSBTdGFydCk7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIGlmICgqSSA9PSAnXDAnKSB7CiAgICAvLyBEZXRlY3Qgc3B1cmlvdXMgbnVsbCBjaGFyYWN0ZXJzLCB3aGljaCBhcmUgbGlrZWx5IGVycm9ycy4KICAgIEguSGFuZGxlTnVsbENoYXIoSSk7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8vIEZpbmFsbHksIGxvb2sgZm9yIHRoZSBjb252ZXJzaW9uIHNwZWNpZmllci4KICBjb25zdCBjaGFyICpjb252ZXJzaW9uUG9zaXRpb24gPSBJKys7CiAgQ29udmVyc2lvblNwZWNpZmllcjo6S2luZCBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6SW52YWxpZFNwZWNpZmllcjsKICBzd2l0Y2ggKCpjb252ZXJzaW9uUG9zaXRpb24pIHsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogICAgLy8gQzk5OiA3LjE5LjYuMSAoc2VjdGlvbiA4KS4KICAgIGNhc2UgJyUnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6UGVyY2VudEFyZzsgICBicmVhazsKICAgIGNhc2UgJ0EnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6QUFyZzsgYnJlYWs7CiAgICBjYXNlICdFJzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OkVBcmc7IGJyZWFrOwogICAgY2FzZSAnRic6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpGQXJnOyBicmVhazsKICAgIGNhc2UgJ0cnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6R0FyZzsgYnJlYWs7CiAgICBjYXNlICdYJzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OlhBcmc7IGJyZWFrOwogICAgY2FzZSAnYSc6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjphQXJnOyBicmVhazsKICAgIGNhc2UgJ2MnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6SW50QXNDaGFyQXJnOyBicmVhazsKICAgIGNhc2UgJ2QnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6ZEFyZzsgYnJlYWs7CiAgICBjYXNlICdlJzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OmVBcmc7IGJyZWFrOwogICAgY2FzZSAnZic6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpmQXJnOyBicmVhazsKICAgIGNhc2UgJ2cnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6Z0FyZzsgYnJlYWs7CiAgICBjYXNlICdpJzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OmlBcmc7IGJyZWFrOwogICAgY2FzZSAnbic6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpPdXRJbnRQdHJBcmc7IGJyZWFrOwogICAgY2FzZSAnbyc6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpvQXJnOyBicmVhazsKICAgIGNhc2UgJ3AnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6Vm9pZFB0ckFyZzsgICBicmVhazsKICAgIGNhc2UgJ3MnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6Q1N0ckFyZzsgICAgICBicmVhazsKICAgIGNhc2UgJ3UnOiBrID0gQ29udmVyc2lvblNwZWNpZmllcjo6dUFyZzsgYnJlYWs7CiAgICBjYXNlICd4JzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OnhBcmc7IGJyZWFrOwogICAgLy8gTWFjIE9TIFggKHVuaWNvZGUpIHNwZWNpZmljCiAgICBjYXNlICdDJzogayA9IENvbnZlcnNpb25TcGVjaWZpZXI6OkNBcmc7IGJyZWFrOwogICAgY2FzZSAnUyc6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpVbmljb2RlU3RyQXJnOyBicmVhazsKICAgIC8vIE9iamVjdGl2ZS1DLgogICAgY2FzZSAnQCc6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpPYmpDT2JqQXJnOyBicmVhazsKICAgIC8vIEdsaWJjIHNwZWNpZmljLgogICAgY2FzZSAnbSc6IGsgPSBDb252ZXJzaW9uU3BlY2lmaWVyOjpQcmludEVycm5vOyBicmVhazsKICB9CiAgQ29udmVyc2lvblNwZWNpZmllciBDUyhjb252ZXJzaW9uUG9zaXRpb24sIGspOwogIEZTLnNldENvbnZlcnNpb25TcGVjaWZpZXIoQ1MpOwogIGlmIChDUy5jb25zdW1lc0RhdGFBcmd1bWVudCgpICYmICFGUy51c2VzUG9zaXRpb25hbEFyZygpKQogICAgRlMuc2V0QXJnSW5kZXgoYXJnSW5kZXgrKyk7CgogIGlmIChrID09IENvbnZlcnNpb25TcGVjaWZpZXI6OkludmFsaWRTcGVjaWZpZXIpIHsKICAgIC8vIEFzc3VtZSB0aGUgY29udmVyc2lvbiB0YWtlcyBvbmUgYXJndW1lbnQuCiAgICByZXR1cm4gIUguSGFuZGxlSW52YWxpZENvbnZlcnNpb25TcGVjaWZpZXIoRlMsIEJlZywgSSAtIEJlZyk7CiAgfQogIHJldHVybiBGb3JtYXRTcGVjaWZpZXJSZXN1bHQoU3RhcnQsIEZTKTsKfQoKYm9vbCBjbGFuZzo6YW5hbHl6ZV9wcmludGY6OlBhcnNlRm9ybWF0U3RyaW5nKEZvcm1hdFN0cmluZ0hhbmRsZXIgJkgsCiAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqSSwgY29uc3QgY2hhciAqRSkgewoKICB1bnNpZ25lZCBhcmdJbmRleCA9IDA7CgogIC8vIEtlZXAgbG9va2luZyBmb3IgYSBmb3JtYXQgc3BlY2lmaWVyIHVudGlsIHdlIGhhdmUgZXhoYXVzdGVkIHRoZSBzdHJpbmcuCiAgd2hpbGUgKEkgIT0gRSkgewogICAgY29uc3QgRm9ybWF0U3BlY2lmaWVyUmVzdWx0ICZGU1IgPSBQYXJzZUZvcm1hdFNwZWNpZmllcihILCBJLCBFLCBhcmdJbmRleCk7CiAgICAvLyBEaWQgYSBmYWlsLXN0b3AgZXJyb3Igb2YgYW55IGtpbmQgb2NjdXIgd2hlbiBwYXJzaW5nIHRoZSBzcGVjaWZpZXI/CiAgICAvLyBJZiBzbywgZG9uJ3QgZG8gYW55IG1vcmUgcHJvY2Vzc2luZy4KICAgIGlmIChGU1Iuc2hvdWxkU3RvcCgpKQogICAgICByZXR1cm4gdHJ1ZTs7CiAgICAvLyBEaWQgd2UgZXhoYXVzdCB0aGUgc3RyaW5nIG9yIGVuY291bnRlciBhbiBlcnJvciB0aGF0CiAgICAvLyB3ZSBjYW4gcmVjb3ZlciBmcm9tPwogICAgaWYgKCFGU1IuaGFzVmFsdWUoKSkKICAgICAgY29udGludWU7CiAgICAvLyBXZSBoYXZlIGEgZm9ybWF0IHNwZWNpZmllci4gIFBhc3MgaXQgdG8gdGhlIGNhbGxiYWNrLgogICAgaWYgKCFILkhhbmRsZUZvcm1hdFNwZWNpZmllcihGU1IuZ2V0VmFsdWUoKSwgRlNSLmdldFN0YXJ0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgLSBGU1IuZ2V0U3RhcnQoKSkpCiAgICAgIHJldHVybiB0cnVlOwogIH0KICBhc3NlcnQoSSA9PSBFICYmICJGb3JtYXQgc3RyaW5nIG5vdCBleGhhdXN0ZWQiKTsKICByZXR1cm4gZmFsc2U7Cn0KCkZvcm1hdFN0cmluZ0hhbmRsZXI6On5Gb3JtYXRTdHJpbmdIYW5kbGVyKCkge30KCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCi8vIE1ldGhvZHMgb24gQXJnVHlwZVJlc3VsdC4KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCmJvb2wgQXJnVHlwZVJlc3VsdDo6bWF0Y2hlc1R5cGUoQVNUQ29udGV4dCAmQywgUXVhbFR5cGUgYXJnVHkpIGNvbnN0IHsKICBzd2l0Y2ggKEspIHsKICAgIGNhc2UgSW52YWxpZFR5OgogICAgICBhc3NlcnQoZmFsc2UgJiYgIkFyZ1R5cGVSZXN1bHQgbXVzdCBiZSB2YWxpZCIpOwogICAgICByZXR1cm4gdHJ1ZTsKCiAgICBjYXNlIFVua25vd25UeToKICAgICAgcmV0dXJuIHRydWU7CgogICAgY2FzZSBTcGVjaWZpY1R5OiB7CiAgICAgIGFyZ1R5ID0gQy5nZXRDYW5vbmljYWxUeXBlKGFyZ1R5KS5nZXRVbnF1YWxpZmllZFR5cGUoKTsKICAgICAgaWYgKFQgPT0gYXJnVHkpCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIGlmIChjb25zdCBCdWlsdGluVHlwZSAqQlQgPSBhcmdUeS0+Z2V0QXM8QnVpbHRpblR5cGU+KCkpCiAgICAgICAgc3dpdGNoIChCVC0+Z2V0S2luZCgpKSB7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgQnVpbHRpblR5cGU6OkNoYXJfUzoKICAgICAgICAgIGNhc2UgQnVpbHRpblR5cGU6OlNDaGFyOgogICAgICAgICAgICByZXR1cm4gVCA9PSBDLlVuc2lnbmVkQ2hhclR5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6Q2hhcl9VOgogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6VUNoYXI6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuU2lnbmVkQ2hhclR5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6U2hvcnQ6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuVW5zaWduZWRTaG9ydFR5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6VVNob3J0OgogICAgICAgICAgICByZXR1cm4gVCA9PSBDLlNob3J0VHk7CiAgICAgICAgICBjYXNlIEJ1aWx0aW5UeXBlOjpJbnQ6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuVW5zaWduZWRJbnRUeTsKICAgICAgICAgIGNhc2UgQnVpbHRpblR5cGU6OlVJbnQ6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuSW50VHk7CiAgICAgICAgICBjYXNlIEJ1aWx0aW5UeXBlOjpMb25nOgogICAgICAgICAgICByZXR1cm4gVCA9PSBDLlVuc2lnbmVkTG9uZ1R5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6VUxvbmc6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuTG9uZ1R5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6TG9uZ0xvbmc6CiAgICAgICAgICAgIHJldHVybiBUID09IEMuVW5zaWduZWRMb25nTG9uZ1R5OwogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6VUxvbmdMb25nOgogICAgICAgICAgICByZXR1cm4gVCA9PSBDLkxvbmdMb25nVHk7CiAgICAgICAgfQogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgY2FzZSBDU3RyVHk6IHsKICAgICAgY29uc3QgUG9pbnRlclR5cGUgKlBUID0gYXJnVHktPmdldEFzPFBvaW50ZXJUeXBlPigpOwogICAgICBpZiAoIVBUKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgUXVhbFR5cGUgcG9pbnRlZVR5ID0gUFQtPmdldFBvaW50ZWVUeXBlKCk7CiAgICAgIGlmIChjb25zdCBCdWlsdGluVHlwZSAqQlQgPSBwb2ludGVlVHktPmdldEFzPEJ1aWx0aW5UeXBlPigpKQogICAgICAgIHN3aXRjaCAoQlQtPmdldEtpbmQoKSkgewogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6Vm9pZDoKICAgICAgICAgIGNhc2UgQnVpbHRpblR5cGU6OkNoYXJfVToKICAgICAgICAgIGNhc2UgQnVpbHRpblR5cGU6OlVDaGFyOgogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6Q2hhcl9TOgogICAgICAgICAgY2FzZSBCdWlsdGluVHlwZTo6U0NoYXI6CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGNhc2UgV0NTdHJUeTogewogICAgICBjb25zdCBQb2ludGVyVHlwZSAqUFQgPSBhcmdUeS0+Z2V0QXM8UG9pbnRlclR5cGU+KCk7CiAgICAgIGlmICghUFQpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICBRdWFsVHlwZSBwb2ludGVlVHkgPQogICAgICAgIEMuZ2V0Q2Fub25pY2FsVHlwZShQVC0+Z2V0UG9pbnRlZVR5cGUoKSkuZ2V0VW5xdWFsaWZpZWRUeXBlKCk7CiAgICAgIHJldHVybiBwb2ludGVlVHkgPT0gQy5nZXRXQ2hhclR5cGUoKTsKICAgIH0KCiAgICBjYXNlIENQb2ludGVyVHk6CiAgICAgIHJldHVybiBhcmdUeS0+Z2V0QXM8UG9pbnRlclR5cGU+KCkgIT0gTlVMTCB8fAogICAgICAJICAgICBhcmdUeS0+Z2V0QXM8T2JqQ09iamVjdFBvaW50ZXJUeXBlPigpICE9IE5VTEw7CgogICAgY2FzZSBPYmpDUG9pbnRlclR5OgogICAgICByZXR1cm4gYXJnVHktPmdldEFzPE9iakNPYmplY3RQb2ludGVyVHlwZT4oKSAhPSBOVUxMOwogIH0KCiAgLy8gRklYTUU6IFNob3VsZCBiZSB1bnJlYWNoYWJsZSwgYnV0IENsYW5nIGlzIGN1cnJlbnRseSBlbWl0dGluZwogIC8vIGEgd2FybmluZy4KICByZXR1cm4gZmFsc2U7Cn0KClF1YWxUeXBlIEFyZ1R5cGVSZXN1bHQ6OmdldFJlcHJlc2VudGF0aXZlVHlwZShBU1RDb250ZXh0ICZDKSBjb25zdCB7CiAgc3dpdGNoIChLKSB7CiAgICBjYXNlIEludmFsaWRUeToKICAgICAgYXNzZXJ0KGZhbHNlICYmICJObyByZXByZXNlbnRhdGl2ZSB0eXBlIGZvciBJbnZhbGlkIEFyZ1R5cGVSZXN1bHQiKTsKICAgICAgLy8gRmFsbC10aHJvdWdoLgogICAgY2FzZSBVbmtub3duVHk6CiAgICAgIHJldHVybiBRdWFsVHlwZSgpOwogICAgY2FzZSBTcGVjaWZpY1R5OgogICAgICByZXR1cm4gVDsKICAgIGNhc2UgQ1N0clR5OgogICAgICByZXR1cm4gQy5nZXRQb2ludGVyVHlwZShDLkNoYXJUeSk7CiAgICBjYXNlIFdDU3RyVHk6CiAgICAgIHJldHVybiBDLmdldFBvaW50ZXJUeXBlKEMuZ2V0V0NoYXJUeXBlKCkpOwogICAgY2FzZSBPYmpDUG9pbnRlclR5OgogICAgICByZXR1cm4gQy5PYmpDQnVpbHRpbklkVHk7CiAgICBjYXNlIENQb2ludGVyVHk6CiAgICAgIHJldHVybiBDLlZvaWRQdHJUeTsKICB9CgogIC8vIEZJWE1FOiBTaG91bGQgYmUgdW5yZWFjaGFibGUsIGJ1dCBDbGFuZyBpcyBjdXJyZW50bHkgZW1pdHRpbmcKICAvLyBhIHdhcm5pbmcuCiAgcmV0dXJuIFF1YWxUeXBlKCk7Cn0KCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCi8vIE1ldGhvZHMgb24gT3B0aW9uYWxBbW91bnQuCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCgpBcmdUeXBlUmVzdWx0IE9wdGlvbmFsQW1vdW50OjpnZXRBcmdUeXBlKEFTVENvbnRleHQgJkN0eCkgY29uc3QgewogIHJldHVybiBDdHguSW50VHk7Cn0KCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCi8vIE1ldGhvZHMgb24gQ29udmVyc2lvblNwZWNpZmllci4KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KY29uc3QgY2hhciAqQ29udmVyc2lvblNwZWNpZmllcjo6dG9TdHJpbmcoKSBjb25zdCB7CiAgc3dpdGNoIChraW5kKSB7CiAgY2FzZSBkQXJnOiByZXR1cm4gImQiOwogIGNhc2UgaUFyZzogcmV0dXJuICJpIjsKICBjYXNlIG9Bcmc6IHJldHVybiAibyI7CiAgY2FzZSB1QXJnOiByZXR1cm4gInUiOwogIGNhc2UgeEFyZzogcmV0dXJuICJ4IjsKICBjYXNlIFhBcmc6IHJldHVybiAiWCI7CiAgY2FzZSBmQXJnOiByZXR1cm4gImYiOwogIGNhc2UgRkFyZzogcmV0dXJuICJGIjsKICBjYXNlIGVBcmc6IHJldHVybiAiZSI7CiAgY2FzZSBFQXJnOiByZXR1cm4gIkUiOwogIGNhc2UgZ0FyZzogcmV0dXJuICJnIjsKICBjYXNlIEdBcmc6IHJldHVybiAiRyI7CiAgY2FzZSBhQXJnOiByZXR1cm4gImEiOwogIGNhc2UgQUFyZzogcmV0dXJuICJBIjsKICBjYXNlIEludEFzQ2hhckFyZzogICAgIHJldHVybiAiYyI7CiAgY2FzZSBDU3RyQXJnOiAgICAgICAgICByZXR1cm4gInMiOwogIGNhc2UgVm9pZFB0ckFyZzogICAgICAgcmV0dXJuICJwIjsKICBjYXNlIE91dEludFB0ckFyZzogICAgIHJldHVybiAibiI7CiAgY2FzZSBQZXJjZW50QXJnOiAgICAgICByZXR1cm4gIiUiOwogIGNhc2UgSW52YWxpZFNwZWNpZmllcjogcmV0dXJuIE5VTEw7CgogIC8vIE1hY09TIFggdW5pY29kZSBleHRlbnNpb25zLgogIGNhc2UgQ0FyZzogICAgICAgICAgcmV0dXJuICJDIjsKICBjYXNlIFVuaWNvZGVTdHJBcmc6IHJldHVybiAiUyI7CgogIC8vIE9iamVjdGl2ZS1DIHNwZWNpZmljIHNwZWNpZmllcnMuCiAgY2FzZSBPYmpDT2JqQXJnOiByZXR1cm4gIkAiOwoKICAvLyBHbGliQyBzcGVjaWZpYyBzcGVjaWZpZXJzLgogIGNhc2UgUHJpbnRFcnJubzogcmV0dXJuICJtIjsKICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCi8vIE1ldGhvZHMgb24gTGVuZ3RoTW9kaWZpZXIuCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCgpjb25zdCBjaGFyICpMZW5ndGhNb2RpZmllcjo6dG9TdHJpbmcoKSBjb25zdCB7CiAgc3dpdGNoIChraW5kKSB7CiAgY2FzZSBBc0NoYXI6CiAgICByZXR1cm4gImhoIjsKICBjYXNlIEFzU2hvcnQ6CiAgICByZXR1cm4gImgiOwogIGNhc2UgQXNMb25nOiAvLyBvciBBc1dpZGVDaGFyCiAgICByZXR1cm4gImwiOwogIGNhc2UgQXNMb25nTG9uZzoKICAgIHJldHVybiAibGwiOwogIGNhc2UgQXNJbnRNYXg6CiAgICByZXR1cm4gImoiOwogIGNhc2UgQXNTaXplVDoKICAgIHJldHVybiAieiI7CiAgY2FzZSBBc1B0ckRpZmY6CiAgICByZXR1cm4gInQiOwogIGNhc2UgQXNMb25nRG91YmxlOgogICAgcmV0dXJuICJMIjsKICBjYXNlIE5vbmU6CiAgICByZXR1cm4gIiI7CiAgfQogIHJldHVybiBOVUxMOwp9CgovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwovLyBNZXRob2RzIG9uIE9wdGlvbmFsQW1vdW50LgovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwoKdm9pZCBPcHRpb25hbEFtb3VudDo6dG9TdHJpbmcobGx2bTo6cmF3X29zdHJlYW0gJm9zKSBjb25zdCB7CiAgc3dpdGNoIChocykgewogIGNhc2UgSW52YWxpZDoKICBjYXNlIE5vdFNwZWNpZmllZDoKICAgIHJldHVybjsKICBjYXNlIEFyZzoKICAgIGlmIChVc2VzRG90UHJlZml4KQogICAgICAgIG9zIDw8ICIuIjsKICAgIGlmICh1c2VzUG9zaXRpb25hbEFyZygpKQogICAgICBvcyA8PCAiKiIgPDwgZ2V0UG9zaXRpb25hbEFyZ0luZGV4KCkgPDwgIiQiOwogICAgZWxzZQogICAgICBvcyA8PCAiKiI7CiAgICBicmVhazsKICBjYXNlIENvbnN0YW50OgogICAgaWYgKFVzZXNEb3RQcmVmaXgpCiAgICAgICAgb3MgPDwgIi4iOwogICAgb3MgPDwgYW10OwogICAgYnJlYWs7CiAgfQp9CgovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwovLyBNZXRob2RzIG9uIEZvcm1hdFNwZWNpZmllci4KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCkFyZ1R5cGVSZXN1bHQgRm9ybWF0U3BlY2lmaWVyOjpnZXRBcmdUeXBlKEFTVENvbnRleHQgJkN0eCkgY29uc3QgewogIGlmICghQ1MuY29uc3VtZXNEYXRhQXJndW1lbnQoKSkKICAgIHJldHVybiBBcmdUeXBlUmVzdWx0OjpJbnZhbGlkKCk7CgogIGlmIChDUy5pc0ludEFyZygpKQogICAgc3dpdGNoIChMTS5nZXRLaW5kKCkpIHsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nRG91YmxlOgogICAgICAgIHJldHVybiBBcmdUeXBlUmVzdWx0OjpJbnZhbGlkKCk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6Ok5vbmU6IHJldHVybiBDdHguSW50VHk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzQ2hhcjogcmV0dXJuIEN0eC5TaWduZWRDaGFyVHk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzU2hvcnQ6IHJldHVybiBDdHguU2hvcnRUeTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nOiByZXR1cm4gQ3R4LkxvbmdUeTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nTG9uZzogcmV0dXJuIEN0eC5Mb25nTG9uZ1R5OwogICAgICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc0ludE1heDoKICAgICAgICAvLyBGSVhNRTogUmV0dXJuIHVua25vd24gZm9yIG5vdy4KICAgICAgICByZXR1cm4gQXJnVHlwZVJlc3VsdCgpOwogICAgICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc1NpemVUOiByZXR1cm4gQ3R4LmdldFNpemVUeXBlKCk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzUHRyRGlmZjogcmV0dXJuIEN0eC5nZXRQb2ludGVyRGlmZlR5cGUoKTsKICAgIH0KCiAgaWYgKENTLmlzVUludEFyZygpKQogICAgc3dpdGNoIChMTS5nZXRLaW5kKCkpIHsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nRG91YmxlOgogICAgICAgIHJldHVybiBBcmdUeXBlUmVzdWx0OjpJbnZhbGlkKCk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6Ok5vbmU6IHJldHVybiBDdHguVW5zaWduZWRJbnRUeTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNDaGFyOiByZXR1cm4gQ3R4LlVuc2lnbmVkQ2hhclR5OwogICAgICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc1Nob3J0OiByZXR1cm4gQ3R4LlVuc2lnbmVkU2hvcnRUeTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nOiByZXR1cm4gQ3R4LlVuc2lnbmVkTG9uZ1R5OwogICAgICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc0xvbmdMb25nOiByZXR1cm4gQ3R4LlVuc2lnbmVkTG9uZ0xvbmdUeTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNJbnRNYXg6CiAgICAgICAgLy8gRklYTUU6IFJldHVybiB1bmtub3duIGZvciBub3cuCiAgICAgICAgcmV0dXJuIEFyZ1R5cGVSZXN1bHQoKTsKICAgICAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNTaXplVDoKICAgICAgICAvLyBGSVhNRTogSG93IHRvIGdldCB0aGUgY29ycmVzcG9uZGluZyB1bnNpZ25lZAogICAgICAgIC8vIHZlcnNpb24gb2Ygc2l6ZV90PwogICAgICAgIHJldHVybiBBcmdUeXBlUmVzdWx0KCk7CiAgICAgIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzUHRyRGlmZjoKICAgICAgICAvLyBGSVhNRTogSG93IHRvIGdldCB0aGUgY29ycmVzcG9uZGluZyB1bnNpZ25lZAogICAgICAgIC8vIHZlcnNpb24gb2YgcHRyZGlmZl90PwogICAgICAgIHJldHVybiBBcmdUeXBlUmVzdWx0KCk7CiAgICB9CgogIGlmIChDUy5pc0RvdWJsZUFyZygpKSB7CiAgICBpZiAoTE0uZ2V0S2luZCgpID09IExlbmd0aE1vZGlmaWVyOjpBc0xvbmdEb3VibGUpCiAgICAgIHJldHVybiBDdHguTG9uZ0RvdWJsZVR5OwogICAgcmV0dXJuIEN0eC5Eb3VibGVUeTsKICB9CgogIHN3aXRjaCAoQ1MuZ2V0S2luZCgpKSB7CiAgICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkNTdHJBcmc6CiAgICAgIHJldHVybiBBcmdUeXBlUmVzdWx0KExNLmdldEtpbmQoKSA9PSBMZW5ndGhNb2RpZmllcjo6QXNXaWRlQ2hhciA/CiAgICAgICAgICBBcmdUeXBlUmVzdWx0OjpXQ1N0clR5IDogQXJnVHlwZVJlc3VsdDo6Q1N0clR5KTsKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6VW5pY29kZVN0ckFyZzoKICAgICAgLy8gRklYTUU6IFRoaXMgYXBwZWFycyB0byBiZSBNYWMgT1MgWCBzcGVjaWZpYy4KICAgICAgcmV0dXJuIEFyZ1R5cGVSZXN1bHQ6OldDU3RyVHk7CiAgICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkNBcmc6CiAgICAgIHJldHVybiBDdHguV0NoYXJUeTsKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6Vm9pZFB0ckFyZzoKICAgICAgcmV0dXJuIEFyZ1R5cGVSZXN1bHQ6OkNQb2ludGVyVHk7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIC8vIEZJWE1FOiBIYW5kbGUgb3RoZXIgY2FzZXMuCiAgcmV0dXJuIEFyZ1R5cGVSZXN1bHQoKTsKfQoKYm9vbCBGb3JtYXRTcGVjaWZpZXI6OmZpeFR5cGUoUXVhbFR5cGUgUVQpIHsKICAvLyBIYW5kbGUgc3RyaW5ncyBmaXJzdCAoY2hhciAqLCB3Y2hhcl90ICopCiAgaWYgKFFULT5pc1BvaW50ZXJUeXBlKCkgJiYgKFFULT5nZXRQb2ludGVlVHlwZSgpLT5pc0FueUNoYXJhY3RlclR5cGUoKSkpIHsKICAgIENTLnNldEtpbmQoQ29udmVyc2lvblNwZWNpZmllcjo6Q1N0ckFyZyk7CgogICAgLy8gRGlzYWJsZSBpcnJlbGV2YW50IGZsYWdzCiAgICBIYXNBbHRlcm5hdGl2ZUZvcm0gPSAwOwogICAgSGFzTGVhZGluZ1plcm9lcyA9IDA7CgogICAgLy8gU2V0IHRoZSBsb25nIGxlbmd0aCBtb2RpZmllciBmb3Igd2lkZSBjaGFyYWN0ZXJzCiAgICBpZiAoUVQtPmdldFBvaW50ZWVUeXBlKCktPmlzV2lkZUNoYXJUeXBlKCkpCiAgICAgIExNLnNldEtpbmQoTGVuZ3RoTW9kaWZpZXI6OkFzV2lkZUNoYXIpOwoKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gV2UgY2FuIG9ubHkgd29yayB3aXRoIGJ1aWx0aW4gdHlwZXMuCiAgaWYgKCFRVC0+aXNCdWlsdGluVHlwZSgpKQogICAgcmV0dXJuIGZhbHNlOwoKICAvLyBFdmVyeXRoaW5nIGVsc2Ugc2hvdWxkIGJlIGEgYmFzZSB0eXBlCiAgY29uc3QgQnVpbHRpblR5cGUgKkJUID0gUVQtPmdldEFzPEJ1aWx0aW5UeXBlPigpOwoKICAvLyBTZXQgbGVuZ3RoIG1vZGlmaWVyCiAgc3dpdGNoIChCVC0+Z2V0S2luZCgpKSB7CiAgZGVmYXVsdDoKICAgIC8vIFRoZSByZXN0IG9mIHRoZSBjb252ZXJzaW9ucyBhcmUgZWl0aGVyIG9wdGlvbmFsIG9yIGZvciBub24tYnVpbHRpbiB0eXBlcwogICAgTE0uc2V0S2luZChMZW5ndGhNb2RpZmllcjo6Tm9uZSk7CiAgICBicmVhazsKCiAgY2FzZSBCdWlsdGluVHlwZTo6V0NoYXI6CiAgY2FzZSBCdWlsdGluVHlwZTo6TG9uZzoKICBjYXNlIEJ1aWx0aW5UeXBlOjpVTG9uZzoKICAgIExNLnNldEtpbmQoTGVuZ3RoTW9kaWZpZXI6OkFzTG9uZyk7CiAgICBicmVhazsKCiAgY2FzZSBCdWlsdGluVHlwZTo6TG9uZ0xvbmc6CiAgY2FzZSBCdWlsdGluVHlwZTo6VUxvbmdMb25nOgogICAgTE0uc2V0S2luZChMZW5ndGhNb2RpZmllcjo6QXNMb25nTG9uZyk7CiAgICBicmVhazsKCiAgY2FzZSBCdWlsdGluVHlwZTo6TG9uZ0RvdWJsZToKICAgIExNLnNldEtpbmQoTGVuZ3RoTW9kaWZpZXI6OkFzTG9uZ0RvdWJsZSk7CiAgICBicmVhazsKICB9CgogIC8vIFNldCBjb252ZXJzaW9uIHNwZWNpZmllciBhbmQgZGlzYWJsZSBhbnkgZmxhZ3Mgd2hpY2ggZG8gbm90IGFwcGx5IHRvIGl0LgogIGlmIChRVC0+aXNBbnlDaGFyYWN0ZXJUeXBlKCkpIHsKICAgIENTLnNldEtpbmQoQ29udmVyc2lvblNwZWNpZmllcjo6SW50QXNDaGFyQXJnKTsKICAgIFByZWNpc2lvbi5zZXRIb3dTcGVjaWZpZWQoT3B0aW9uYWxBbW91bnQ6Ok5vdFNwZWNpZmllZCk7CiAgICBIYXNBbHRlcm5hdGl2ZUZvcm0gPSAwOwogICAgSGFzTGVhZGluZ1plcm9lcyA9IDA7CiAgICBIYXNQbHVzUHJlZml4ID0gMDsKICB9CiAgLy8gVGVzdCBmb3IgRmxvYXRpbmcgdHlwZSBmaXJzdCBhcyBMb25nRG91YmxlIGNhbiBwYXNzIGlzVW5zaWduZWRJbnRlZ2VyVHlwZQogIGVsc2UgaWYgKFFULT5pc1JlYWxGbG9hdGluZ1R5cGUoKSkgewogICAgQ1Muc2V0S2luZChDb252ZXJzaW9uU3BlY2lmaWVyOjpmQXJnKTsKICB9CiAgZWxzZSBpZiAoUVQtPmlzUG9pbnRlclR5cGUoKSkgewogICAgQ1Muc2V0S2luZChDb252ZXJzaW9uU3BlY2lmaWVyOjpWb2lkUHRyQXJnKTsKICAgIFByZWNpc2lvbi5zZXRIb3dTcGVjaWZpZWQoT3B0aW9uYWxBbW91bnQ6Ok5vdFNwZWNpZmllZCk7CiAgICBIYXNBbHRlcm5hdGl2ZUZvcm0gPSAwOwogICAgSGFzTGVhZGluZ1plcm9lcyA9IDA7CiAgICBIYXNQbHVzUHJlZml4ID0gMDsKICB9CiAgZWxzZSBpZiAoUVQtPmlzU2lnbmVkSW50ZWdlclR5cGUoKSkgewogICAgQ1Muc2V0S2luZChDb252ZXJzaW9uU3BlY2lmaWVyOjpkQXJnKTsKICAgIEhhc0FsdGVybmF0aXZlRm9ybSA9IDA7CiAgfQogIGVsc2UgaWYgKFFULT5pc1Vuc2lnbmVkSW50ZWdlclR5cGUoKSkgewogICAgQ1Muc2V0S2luZChDb252ZXJzaW9uU3BlY2lmaWVyOjp1QXJnKTsKICAgIEhhc0FsdGVybmF0aXZlRm9ybSA9IDA7CiAgICBIYXNQbHVzUHJlZml4ID0gMDsKICB9CiAgZWxzZSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICByZXR1cm4gdHJ1ZTsKfQoKdm9pZCBGb3JtYXRTcGVjaWZpZXI6OnRvU3RyaW5nKGxsdm06OnJhd19vc3RyZWFtICZvcykgY29uc3QgewogIC8vIFdoaWxzdCBzb21lIGZlYXR1cmVzIGhhdmUgbm8gZGVmaW5lZCBvcmRlciwgd2UgYXJlIHVzaW5nIHRoZSBvcmRlcgogIC8vIGFwcGVhcmluZyBpbiB0aGUgQzk5IHN0YW5kYXJkIChJU08vSUVDIDk4OTk6MTk5OSAoRSkgpDcuMTkuNi4xKQogIG9zIDw8ICIlIjsKCiAgLy8gUG9zaXRpb25hbCBhcmdzCiAgaWYgKHVzZXNQb3NpdGlvbmFsQXJnKCkpIHsKICAgIG9zIDw8IGdldFBvc2l0aW9uYWxBcmdJbmRleCgpIDw8ICIkIjsKICB9CgogIC8vIENvbnZlcnNpb24gZmxhZ3MKICBpZiAoSXNMZWZ0SnVzdGlmaWVkKSAgICBvcyA8PCAiLSI7CiAgaWYgKEhhc1BsdXNQcmVmaXgpICAgICAgb3MgPDwgIisiOwogIGlmIChIYXNTcGFjZVByZWZpeCkgICAgIG9zIDw8ICIgIjsKICBpZiAoSGFzQWx0ZXJuYXRpdmVGb3JtKSBvcyA8PCAiIyI7CiAgaWYgKEhhc0xlYWRpbmdaZXJvZXMpICAgb3MgPDwgIjAiOwoKICAvLyBNaW5pbXVtIGZpZWxkIHdpZHRoCiAgRmllbGRXaWR0aC50b1N0cmluZyhvcyk7CiAgLy8gUHJlY2lzaW9uCiAgUHJlY2lzaW9uLnRvU3RyaW5nKG9zKTsKICAvLyBMZW5ndGggbW9kaWZpZXIKICBvcyA8PCBMTS50b1N0cmluZygpOwogIC8vIENvbnZlcnNpb24gc3BlY2lmaWVyCiAgb3MgPDwgQ1MudG9TdHJpbmcoKTsKfQoKYm9vbCBGb3JtYXRTcGVjaWZpZXI6Omhhc1ZhbGlkUGx1c1ByZWZpeCgpIGNvbnN0IHsKICBpZiAoIUhhc1BsdXNQcmVmaXgpCiAgICByZXR1cm4gdHJ1ZTsKCiAgLy8gVGhlIHBsdXMgcHJlZml4IG9ubHkgbWFrZXMgc2Vuc2UgZm9yIHNpZ25lZCBjb252ZXJzaW9ucwogIHN3aXRjaCAoQ1MuZ2V0S2luZCgpKSB7CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpkQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6aUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmZBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpGQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkVBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpnQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6R0FyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmFBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpBQXJnOgogICAgcmV0dXJuIHRydWU7CgogIGRlZmF1bHQ6CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9Cgpib29sIEZvcm1hdFNwZWNpZmllcjo6aGFzVmFsaWRBbHRlcm5hdGl2ZUZvcm0oKSBjb25zdCB7CiAgaWYgKCFIYXNBbHRlcm5hdGl2ZUZvcm0pCiAgICByZXR1cm4gdHJ1ZTsKCiAgLy8gQWx0ZXJuYXRlIGZvcm0gZmxhZyBvbmx5IHZhbGlkIHdpdGggdGhlIG94YUFlRWZGZ0cgY29udmVyc2lvbnMKICBzd2l0Y2ggKENTLmdldEtpbmQoKSkgewogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6b0FyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OnhBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjphQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6QUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmVBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpFQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZkFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkZBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpnQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6R0FyZzoKICAgIHJldHVybiB0cnVlOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKYm9vbCBGb3JtYXRTcGVjaWZpZXI6Omhhc1ZhbGlkTGVhZGluZ1plcm9zKCkgY29uc3QgewogIGlmICghSGFzTGVhZGluZ1plcm9lcykKICAgIHJldHVybiB0cnVlOwoKICAvLyBMZWFkaW5nIHplcm9lcyBmbGFnIG9ubHkgdmFsaWQgd2l0aCB0aGUgZGlvdXhYYUFlRWZGZ0cgY29udmVyc2lvbnMKICBzd2l0Y2ggKENTLmdldEtpbmQoKSkgewogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZEFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmlBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpvQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6dUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OnhBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpYQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6YUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkFBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjplQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6RUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmZBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpGQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6Z0FyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkdBcmc6CiAgICByZXR1cm4gdHJ1ZTsKCiAgZGVmYXVsdDoKICAgIHJldHVybiBmYWxzZTsKICB9Cn0KCmJvb2wgRm9ybWF0U3BlY2lmaWVyOjpoYXNWYWxpZFNwYWNlUHJlZml4KCkgY29uc3QgewogIGlmICghSGFzU3BhY2VQcmVmaXgpCiAgICByZXR1cm4gdHJ1ZTsKCiAgLy8gVGhlIHNwYWNlIHByZWZpeCBvbmx5IG1ha2VzIHNlbnNlIGZvciBzaWduZWQgY29udmVyc2lvbnMKICBzd2l0Y2ggKENTLmdldEtpbmQoKSkgewogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZEFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmlBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpmQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6RkFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmVBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpFQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6Z0FyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkdBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjphQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6QUFyZzoKICAgIHJldHVybiB0cnVlOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGZhbHNlOwogIH0KfQoKYm9vbCBGb3JtYXRTcGVjaWZpZXI6Omhhc1ZhbGlkTGVmdEp1c3RpZmllZCgpIGNvbnN0IHsKICBpZiAoIUlzTGVmdEp1c3RpZmllZCkKICAgIHJldHVybiB0cnVlOwoKICAvLyBUaGUgbGVmdCBqdXN0aWZpZWQgZmxhZyBpcyB2YWxpZCBmb3IgYWxsIGNvbnZlcnNpb25zIGV4Y2VwdCBuCiAgc3dpdGNoIChDUy5nZXRLaW5kKCkpIHsKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6Ok91dEludFB0ckFyZzoKICAgIHJldHVybiBmYWxzZTsKCiAgZGVmYXVsdDoKICAgIHJldHVybiB0cnVlOwogIH0KfQoKYm9vbCBGb3JtYXRTcGVjaWZpZXI6Omhhc1ZhbGlkTGVuZ3RoTW9kaWZpZXIoKSBjb25zdCB7CiAgc3dpdGNoIChMTS5nZXRLaW5kKCkpIHsKICBjYXNlIExlbmd0aE1vZGlmaWVyOjpOb25lOgogICAgcmV0dXJuIHRydWU7CgogIC8vIEhhbmRsZSBtb3N0IGludGVnZXIgZmxhZ3MKICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc0NoYXI6CiAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNTaG9ydDoKICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc0xvbmdMb25nOgogIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzSW50TWF4OgogIGNhc2UgTGVuZ3RoTW9kaWZpZXI6OkFzU2l6ZVQ6CiAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNQdHJEaWZmOgogICAgc3dpdGNoIChDUy5nZXRLaW5kKCkpIHsKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6aUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6b0FyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6dUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6eEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6WEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6T3V0SW50UHRyQXJnOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgLy8gSGFuZGxlICdsJyBmbGFnCiAgY2FzZSBMZW5ndGhNb2RpZmllcjo6QXNMb25nOgogICAgc3dpdGNoIChDUy5nZXRLaW5kKCkpIHsKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6aUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6b0FyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6dUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6eEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6WEFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6YUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6QUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZkFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6RkFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6RUFyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6Z0FyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6R0FyZzoKICAgIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6T3V0SW50UHRyQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpJbnRBc0NoYXJBcmc6CiAgICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkNTdHJBcmc6CiAgICAgIHJldHVybiB0cnVlOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICBjYXNlIExlbmd0aE1vZGlmaWVyOjpBc0xvbmdEb3VibGU6CiAgICBzd2l0Y2ggKENTLmdldEtpbmQoKSkgewogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjphQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpBQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpmQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpGQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjplQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpFQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpnQXJnOgogICAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpHQXJnOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIGZhbHNlOwp9Cgpib29sIEZvcm1hdFNwZWNpZmllcjo6aGFzVmFsaWRQcmVjaXNpb24oKSBjb25zdCB7CiAgaWYgKFByZWNpc2lvbi5nZXRIb3dTcGVjaWZpZWQoKSA9PSBPcHRpb25hbEFtb3VudDo6Tm90U3BlY2lmaWVkKQogICAgcmV0dXJuIHRydWU7CgogIC8vIFByZWNpc2lvbiBpcyBvbmx5IHZhbGlkIHdpdGggdGhlIGRpb3V4WGFBZUVmRmdHcyBjb252ZXJzaW9ucwogIHN3aXRjaCAoQ1MuZ2V0S2luZCgpKSB7CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpkQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6aUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6Om9Bcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjp1QXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6eEFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OlhBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjphQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6QUFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OmVBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpFQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6ZkFyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkZBcmc6CiAgY2FzZSBDb252ZXJzaW9uU3BlY2lmaWVyOjpnQXJnOgogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6R0FyZzoKICBjYXNlIENvbnZlcnNpb25TcGVjaWZpZXI6OkNTdHJBcmc6CiAgICByZXR1cm4gdHJ1ZTsKCiAgZGVmYXVsdDoKICAgIHJldHVybiBmYWxzZTsKICB9Cn0KYm9vbCBGb3JtYXRTcGVjaWZpZXI6Omhhc1ZhbGlkRmllbGRXaWR0aCgpIGNvbnN0IHsKICBpZiAoRmllbGRXaWR0aC5nZXRIb3dTcGVjaWZpZWQoKSA9PSBPcHRpb25hbEFtb3VudDo6Tm90U3BlY2lmaWVkKQogICAgICByZXR1cm4gdHJ1ZTsKCiAgLy8gVGhlIGZpZWxkIHdpZHRoIGlzIHZhbGlkIGZvciBhbGwgY29udmVyc2lvbnMgZXhjZXB0IG4KICBzd2l0Y2ggKENTLmdldEtpbmQoKSkgewogIGNhc2UgQ29udmVyc2lvblNwZWNpZmllcjo6T3V0SW50UHRyQXJnOgogICAgcmV0dXJuIGZhbHNlOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIHRydWU7CiAgfQp9Cg==