N6Qw7H57nBQ/ELASpw0wDMMwDMMwDMPA7bdErSmtXLW9HLwbkRQyAQ873lu3xuLGaeORbjWEpI2qA/totLgD2Y6atgVwEHcCAwFIAAgFxKIBmVQ2olUPBMDAAwWEIyosJhkTFBSIw8FIKBCHgpEYBUEQhFEgx3FAjISGSgAAAFS8KmQIIQAAAAAAAAAAAAAAAAEAAAAEAAAACAAAACAgICAgICAgICBsZXQgaW5wdXQgPSBJbnB1dFN0cmVhbTo6bmV3KHZlYyFbXSk7CgogfQoKICAgICAgICAgICAgbW9kIHdyaXRlIHsKICAgICAgICAgICAgICAgIG1vZCBjb20wMCldCiAgICAgICAgICAgICAgICAgICAgZm4gbXVsdGlwbGVfbWVtYmVycygpIHsKICAgICAgICAgICAgICBhc3NlcnRfZXEhKHRyYWlsZXIsICZbNywgOCwgOSwgMTBdWy4ubWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gdHJhaWxlcigpIHsKICAKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRlY29kIHJlc3VsdCA9IHJlYWQ6OnBvbGxfcmVhZChlbmNvZGVyLCAmbXV0IG91dHB1dCk7CiBlc3Q6OnRpbWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gZW1wdHkoKQogICAgICAgIG1vZCAkaW1wbCB7CiAgICAgICAgICAgIG1vZCBidWZyZWFkIHsKICAgIHsKICAgICAgICBsaW1pdGVkOjpMaW1pdGVkOjpuZXcoc2VsZiwgbGltaXQpCiAgICBfY2FzZXM7CgpwdWIgbW9kIGFsZ29zOwpwdWIgbW9kIGltcGxzOwoKcHViIHVzZSBzZXVyZSA9ICJ0b2tpbyIpXQptb2QgdG9raW9fZXh0Owptb2QgdHJhY2tfY2xvc2VkOwptICAgICAgcmVhZHkhKHNlbGYuYXNfbXV0KCkuZG9fcG9sbF9mbHVzaChjeCkpPzsKCiA/OwogICAgZGVjb2Rlci5zaHV0ZG93bigpLmF3YWl0PzsKICAgIE9rKGRlY29kZXIuaWh1dGRvd25gCgojW3Rva2lvOjptYWluKGZsYXZvciA9ICJjdXJyZW50X3RocmVhZCIpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kIGluIGEgdGVybWluYWw6Ci8vIQovLyEgYGAgICAgICZtdXQgc2VsZi5idWZmZXIuYXNfbXV0KClbc2VsZi5pbmRleC4uXQogICAgfSwKICAgIGluZGV4OiB1c2l6ZSwKfQoKaW1wbDxCOiBBc1JlZjxbdThdPj4gUGFydGlheW5jPigpIHt9CgojW2Rlcml2ZShEZWJ1ZywgRGVmYXVsdCldCnB1YiBzdHJ1Y3QgUGFjb21wcmVzcy50b3RhbF9vdXQoKTsKCiAgICAgICAgbGV0IHN0YXR1cyA9CiAgICAgICwKfQoKaW1wbCBGbGF0ZURlY29kZXIgewogICAgcHViKGNyYXRlKSBmbiBuZXcoemxpX2FyZ3MhKCJ7fS97fSIsIHNlbGYuYnVmZmVyZWQsIHNlbGYuYnVmLmxlbigpKSwKICBzLmJ1ZmZlcmVkICs9IGxlbjsKICAgICAgICAgICAgUG9sbDo6UmVhZHkoT2sobGVuKSAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICp0aGlzLndyaXR0ZW4gPiAwZF0pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBvbGw6OlBlbmRpbmcgPT51ZldyaXRlcmAgd2l0aCB0aGUgc3BlY2lmaWVkIGJ1ZmZlcnN5bmNXcml0ZTsKCmNvbnN0IERFRkFVTFRlXQptb2QgdXRpbHM7Cgp0ZXN0X2Nhc2VzIShkZWZsYXRlKTsKLy8gT3JpZ2luYWxseSAgZm4gcHJvZHVjZShzZWxmOiBQaW48Jm11dCBTZWxmPiwgYW10OiB1c2l6ZSk7Cn0KaGlzIGZ1bmN0aW9uIGlzIGEgbG93ZXItbGV2ZWwgY2FsbC4gSXQgbmVlZHMgbmRlcmx5aW5nIElPIHdoZW4gcG9zc2libGUuCiAgICAvLy8KICAgIC8vLyBUaGlzIGZmdWxsLgogICAgLy8vCiAgICAvLy8gT24gc3VjY2VzcywgcmV0dXJucyBgUG9sbDo6UiBvdXRwdXQuYWR2YW5jZShsZW4pOwogICAgICAgIE9rKGJ5dGVzX2xlZnQgPT0gMCkKdHRlbl9tdXQoKSk/OwogICAgICAgIGlucHV0LmFkdmFuY2Uoc3RhdHVzLmJ5dGVzX3JhdGUpIGZuIG5ld193aXRoX2RpY3QoZGljdGlvbmFyeTogJlt1OF0pIC0+IGlvOjpSZXNoYXJlZDo6VW5zaGFyZWQsIHV0aWw6OlBhcnRpYWxCdWZmZXJ9Owp1c2UgbGlienN0YWRlcihfKSB8IFN0YXRlOjpGb290ZXIoXykgfCBTdGF0ZTo6RG9uZSA9PiByZXR1cm5sdCgpKTsKICAgICAgICBzZWxmLmhlYWRlciA9IEhlYWRlcjo6ZGVmYXVsdCgpOwogIHRlcihmb290ZXIpID0+IHsKICAgICAgICAgICAgICAgICAgICBmb290ZXIuY29weV91LnN0YXRlIHsKICAgICAgICAgICAgICAgIFN0YXRlOjpIZWFkZXIocGFyc2VyKSA9PiAgIH0KICAgIH0KCiAgICBmbiBwcm9jZXNzPEk6IEFzUmVmPFt1OF0+LCBPOiBBc1JlZgogICAgbGV0IGNyY19zdW0gPSBjcmMuc3VtKCkudG9fbGVfYnl0ZXMoKTsKICAgIGxlMjo6Q3JjOwoKI1tkZXJpdmUoRGVidWcpXQplbnVtIFN0YXRlIHsKICAgIEhlYWRlcigsIGxldmVsKSwKICAgICAgICB9CiAgICB9Cn0KCmltcGwgRW5jb2RlIGZvciBMem1hRWxCdWZmZXI6Om5ldygmW11bLi5dKSwgb3V0cHV0LCBBY3Rpb246OkZpbmlzaCk/IHsKb3RoaW5nIG11Y2ggdG8gcmVwb3J0LgogICAgICAgICAgICBTdGF0dXM6Ok9rID0+IHUKICAgICAgICBPayhzdGF0dXMpCiAgICB9Cn0KCmltcGwgRW5jb2RlIGZvciBCekVuYyAvLy8gZXF1aXZhbGVudCB0byB1c2luZyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiAzMC4KciBvdmVyIGEgd2lkZSByYW5nZSBvZgogICAgLy8vIGNpcmN1bXN0YW5jZXMuCiAgICAKICAgIC8vLyBhIGZhY3RvciBvZiB0aHJlZSwgYnV0IGFsd2F5cyBiZWhhdmVzIHJlYWRlciB7CiAgICAvLy8gQ3JlYXRlcyBhIG5ldyBzdHJlYW0gcHJlcGFyZWQgZm9yIGNvZXJ3aXNlIHdlJ2xsIGp1c3Qga2VlcCB3cml0aW5nCiAgICAgICAgLy8gb3V0IHN5bmMgQXNSZWY8W3U4XT4gKyBBc011dDxbdThdPj4sCiAgICAgICAgZmx1c2g6IEZsdXNoQ3cobGV2ZWwsIHpsaWJfaGVhZGVyKSwKICAgICAgICAgICAgZmx1c2hlZDogdHJ1ZSwKZDo6aW86OlJlc3VsdDsKCiNbZGVyaXZlKERlYnVnKV0KcHViIHN0cnVjdCBMem1hRGVieXRlcywgc28gaXQgbXVzdCBiZSBpbnZhbGlkCiAgICAgICAgICAgIC8vIHBhZGRpbipjb3VudCA9PSAwIHsKICAgICAgICAgICAgICAgICAgICAqY291bnQgPSA0OwogICAgS2luZCwgUmVzdWx0fTsKCiNbZGVyaXZlKERlYnVnKV0KcHViIHN0cnVjdCBYekRlY28gewogICAgcHViKGNyYXRlKSBmbiBuZXcobGV2ZWw6IENvbXByZXNzaW9uKSAtPiBTZXV0IFNlbGY+LCBhbXQ6IHVzaXplKSB7CiAgICAgICAgc2VsZi5wcm9qZWN0KCkuMC5jICAgICAgICAgfQogICAgICAgICAgICAgICAgUG9sbDo6UmVhZHkoT2soMCkpCiAgICBlciwgZW9mIH0gPSBQaW46OmludG9faW5uZXIoc2VsZik7CiAgICAgICAgKFBpbjo6biBpbm5lcjogUiwKICAgIGVvZjogYm9vbCwKfQoKaW1wbDxSOiBVbnBpbj4gVHJhY2tFYSBmcm9tIHRoZSBnaXZlbiBzdHJlYW0KICAgICAgICAgICAgICAgIC8vLyBhbmQgZW1TdGF0ZTo6RW5jb2RpbmcgPT4gewogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuaSAgICAgICAgICAgICAgICAgICAgICAgIHRydWUKICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgU3RhdGU6OkVuY29kaW5nID0+IHNlbGYuaWl0dGVuKCkuaXNfZW1wdHkoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gT2soKCkpLnN0YXRlIHsKICAgICAgICAgICAgICAgIFN0YXRlOjpIZWFkZXIoaGVhZGVyKSA9PiB0eSg4KTsKCiAgICAgICAgb3V0cHV0LmV4dGVuZCgmc2VsZi5jcmMuc3VtKCkudG9fbHgwOCwgMCwgMCwgMCwgMCwgMCwgbGV2ZWxfYnl0ZSwgMHhmZl0KfQoKaW1wbCBHemlwICAgY3JjOiBDcmMsCiAgICBzdGF0ZTogU3RhdGUsCn0KCmZuIGhlYWRlcihsZXZlbDovLyEgSW1wbGVtZW50YXRpb25zIGZvciBJTyB0cmFpdHMgZXhwb3J0ZWQgYnkgW2BmdXRlCiAgICAgICAgICAgIC8vLyB3aGVuIHJlYWNoaW5nIHRoZSBlbmQgb2YgYSBjb21wLy8gVGhpcyBzdHJ1Y3R1cmUgaW1wbGVtZW50cyBhbiBbYEFzeW5jUmVhZGBdKHRva2lhdGUpIHVzZSBzZWxmOjp7ZGVjb2Rlcjo6WHpEZWNvZGVyLCBlbmNvZGVyOjpYekVuYyAgICBtYXRjaCBzdGF0dXMgewogICAgICAgICAgICBTdGF0dXM6Ok9rIHwgU3RhdHVzICAgIHB1YiBmbiBuZXcoZm9ybWF0OiBYejJGaWxlRm9ybWF0LCBsZXZlbDogdTMyKSBmbiBmbXQoJnNlbGYsIGY6ICZtdXQgRm9ybWF0dGVyPCdfPikgLT4gRm10UmVzdWx0ICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFN0YXRlOjpDcmMoZGF0YSkgZShsZW4pID0gbWVtY2hyOjptZW1jaHIoMCwgaW5wdXQudW53cml0dGVuKCkpIHsKICAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFN0YXRlOjpDb21tZW50KDxfPjo6ZCAgICAgICAgICAgICAgICBpZiAhc2VsZi5oZWFkZXIuZmxhZ3MuZXh0cmEgewogICAgdCBzZWxmLnN0YXRlIHsKICAgICAgICAgICAgICAgIFN0YXRlOjpGaXhlZChkYXRhKSBFcnJvcktpbmQ6OkludmFsaWREYXRhLCAiSW52YWxpZCBnemlwIGhlYWRlciIpKTsKIHsKICAgICAgICBpZiBpbnB1dFswLi4zXSAhPSBbMHgxZiwgMHg4YiwgMHgwOF0gewogIHsKICAgIGFzY2lpOiBib29sLAogICAgY3JjOiBib29sLAogICAgZXh0cmE6IGJvb2wKaW1wbDxSOiBBc3luY0J1ZlJlYWQsIEU6IEVuY29kZT4gQXN5bmNSZWFkIGZvciBFbiAgI1tkZXJpdmUoRGVidWcpXQogICAgcHViIHN0cnVjdCBFbmNvZGVyPFIsIEU6IEVuaXRlOjpwaW5fcHJvamVjdDsKdXNlIHRva2lvOjppbzo6QXN5bmNXcml0ZTsKCiNbZGVzdHJ1Y3QoIkJyb3RsaURlY29kZXIiKQogICAgICAgICAgICAuZmllbGQoImRlY29tcCksCiAgICAgICAgICAgIEJyb3RsaVJlc3VsdDo6TmVlZHNNb3JlSW5wdXQgPT4gRXJyPyB7CiAgICAgICAgICAgIEJyb3RsaVJlc3VsdDo6UmVzdWx0U3VjY2VzcyB8IEJyb3RfbGVuLAogICAgICAgICAgICBvdXRfYnVmLAogICAgICAgICAgICAmbXV0IDAsCiAgICAgICAgICBsZXQgbXV0IG91dF9idWYgPSBvdXRwdXQudW53cml0dGVuX211dCgpOwoKLgogICAgc3RhdGU6IEJveDxCcm90bGlTdGF0ZTxTdGFuZGFyZEFsbG9jLCBTdGFuZGFyZXNzaW9uIHBhcmFtZXRlcnMuCiAgICAgICAgcHViIGZuIGpvYl9zaXplKHZhbHVlOmhyZWFkcyBhbmQgYGZsdXNoYCBwdXNoZXMgYnl0ZXMgdGhyb3VnaCB0aGUgY29tcHJlaW9uYXJ5IChkZWZhdWx0OiB0cnVlKS4KICAgICAgICBwdWIgZm4gZGljdF9pZF9mbGF1MzIpIC0+IFNlbGYgewogICAgICAgICAgICBTZWxmKExkbUhhc2hSYXRlTG9nKHZhbFNlbGYgewogICAgICAgICAgICBTZWxmKEVuYWJsZUxvbmdEaXN0YW5jZU1hdGNoaW5naGluZyBtb2RlIHRvIGxvb2sgZm9yIGFuZCBlbWl0IGxvbmctZGlzdGFuY2UgcmVmZXIgICAgfQoKICAgICAgICAvLy8gTnVtYmVyIG9mIHNlYXJjaCBhdHRlbXB0cyAoYXMgYW50YXRpb25dKGh0dHBzOi8vZmFjZWJvb2suZ2l0aHViLmlvL3pzdGQvenN0ZF9tYW51dHkpID0+IHF1YWxpdHkudHJ5X2ludG8oKS51bndyYXBfb3IoMCkubWluKDkpLAogICBienN0ZDo6Y29tcHJlc3Npb25fbGV2ZWxfcmFuZ2UoKS5pbnRvX2lubmVyKCk7CiAgICBmbiBpbnRvX2ZsYXRlMihzZWxmKSAtPiBmbGF0ZTI6OkNvbXByZXNzaW9uIHsKICAgY2ggc2VsZiB7CiAgICAgICAgICAgIFNlbGY6OkZhc3Rlc3QgPT4gZmFzdGVzdCwKICB0aGlzIGRlcGVuZHMgb24gdGhlIGFsZ29yaXRobSBjaG9zZW4KICAgIC8vLyBhbmQgdHJlc3NlZCB3aXRoLgojW25vbl9leGhhdXN0aXZlXQojW2Rlcml2ZShDbG9uZSwgQ29wa2lvIildCnB1YiBtb2QgdG9raW87Cgptb2QgdW5zaGFyZWQ7Cm1vZCB1dGlsOwoKI1sgICBkb2MgPSAiYHpsaWJgIHwgW2BabGliRW5jb2RlcmBdKD9zZWFyY2g9WmxpYkVuY2FyY2g9THptYUVuY29kZXIpLCBbYEx6bWFEZWNvZGVyYF0oP3NlYXJjaD1Mem1hRGVjIHwgW2BHemlwRW5jb2RlcmBdKD9zZWFyY2g9R3ppcEVuY29kZXIpLCBbYEd6aXBEZWMoP3NlYXJjaD1CekVuY29kZXIpLCBbYEJ6RGVjb2RlcmBdKD9zZWFyY2g9QnpEZWNvZGNXcml0ZWAiCildCi8vIQoKLy8hICMjIENvbXByZXNzaW9uIGFsZ29yaXRobQovLyEKaW9uLCBgIyFbcnVzdGZtdDo6c2tpcDo6YXR0cmlidXRlcyhjZmdfYXR0bGVjdGlvbiBvZiBhbGdvcml0aG1zCi8vISAgYGFsbC1hbGdvcml0aG1zYCB8IEFjdGkgd2hpY2ggY2FuIGVhY2ggYmUgaW5kaXZpZHVhbGx5IHNlbGVjdGVkIHZpYSBDYXJnbyAgICAgIH0KICAgIH0KfQovLyEgQWRhcHRvcnMgYmV0d2VlbiBjb21wcmVzc2lvbiBjICAjW2Rlcml2ZShEZWJ1ZyldCiAgICBwdWIgc3RydWN0IERlY29kZXI8UiwgRDogRGVvdGxpRW5jb2Rlck9wZXJhdGlvbjo6QlJPVExJX09QRVJBVElPTl9GSU5JU0gsCiAgIGNvZGVyT3BlcmF0aW9uOjpCUk9UTElfT1BFUkFUSU9OX1BST0NFU1MsCiAgICAgbik7CgogICAgICAgIE9rKCgpKQogICAgfQp9CgppbXBsIEVuY29kZSBmb3IgQnJvdGwgICAgICAgICZtdXQgTm9uZSwKICAgICAgICAgICAgJm11dCB8XywgXywgXywgX3wgKGIoY3JhdGUpIGZuIG5ldyhwYXJhbXM6IEJyb3RsaUVuY29kZXJQYXJhbXMpIC0+IFNlUGFyYW1zLAogICAgZW5jb2RlOjp7CiAgICAgICAgQnJvdGxpRW5jb2RlckNvbXByZXMKCiAgICAgICAgYWxnb3MhKEBhbGdvIHh6IFsieHoiXSBYekRlY29kZXIgWHpFbmNvZGhlIGRpY3Rpb25hcnkgdXNlZCBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSBvbmUKICAgICAgfSkKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB7IEBkZWMKICAgICBvbi4KICAgICAgICAgICAgLy8vCiAgICAgICAgICAgIC8vLyAjIEVycm9ycwogICAgIDo6bmV3X3dpdGhfcGFyYW1zKGxldmVsLmludG9fenN0ZCgpLCBwYXJhbXMpLAogICAgICAvLwogICAgICAgICAgICAvLyBUT0RPOiByZW1vdmUgcGFuaWMgbm90ZSBvbiBuZXggYW5kIHBhcmFtZXRlcnMsIHdoaWNoCiAgICAgICAgICAgIC8vLyB3aWxsIHJlYWQgdWlubmVyLAogICAgICAgICAgICAgICAgICAgICAgICBjcmF0ZTo6Y29kZWM6OlpsaWJFICAgIGFsZ29zIShAYWxnbyBnemlwIFsiZ3ppcCJdIEd6aXBEZW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgY3JhdGU6OmNvZGVjOjpEZWZsYXRlICAgICBhbGdvcyEoQGFsZ28gYnppcDIgWyJiemlwMiJdIEJ6RGVjb2RlciBCekVuY29Ccm90bGlFbmNvZGVyOjpuZXcobGV2ZWwuaW50b19icm90bGkocGFyYW1zKSksCiAgIHQhKCJBICIsICRhbGdvX3MsICIgZW5jb2Rlciwgb3IgY29tcHJlc3Nvci4iKV0KICAgCmFsZ29zIShmdXR1cmVzOjpidWZyZWFkPFI+KTsKbWFjcm9fcnVsZXMhIGFsZ29zIHtydWUpCiAgICB9Cn0KLy8hIFR5cGVzIHdoaWNoIG9wZXJhdGUgb3ZlciBbYEFzeW5jQnVzaE9rID0+IHVucmVhY2hhYmxlISgpLAoKICAgICAgICAgICAgLy8gVEhlIFJ1biBhICAgICAgbGV0IHByaW9yX2luID0gc2VsZi5kZWNvbXByZXNzLnRvdGFsX2luKCk7CiBvbXByZXNzLnRvdGFsX291dCgpCiAgICAgICAgKQogICAgfQp9CgppbXBsIEJ6RGVjbzo6RGVjb2RlLCB1dGlsOjpQYXJ0aWFsQnVmZmVyfTsKdXNlIHN0ZDo6Zm10Owp1c2UgICAgICAgaW5uZXI6IGNyYXRlOjp0b2tpbzo6d3JpdGU6OkRlY29kZXI8VywgY3JhdGU9PiBFcnIoc3RkOjppbzo6RXJyb3I6Om5ldygKICAgICAgICAgICAgICAgIHN0ZDo6aSkgLT4gUmVzdWx0PCgpPiB7CiAgICAgICAgKnNlbGYgPSBTZWxmOjpuZXcoKTsKICAgZGVyIHsKICAgIHN0cmVhbTogU3RyZWFtLAp9CgppbXBsIERlYnVnIGZvciBYejJEZWNudHMgYW4gW2BBc3luY1dyaXRlYF0odG9raW86OmlvOjpBc3luY1dyaXRlKSBpbnRlciB9Cn0KI1ttYWNyb191c2VdCm1vZCB1dGlsczsKCnRlc3RfY2FzZXMhKGJ6aXAyKTsKbmV4dCA9IFBpbjo6bmV3KCZtdXQgc2VsZi5pbm5lcikucG9sbF9mbHVzaChjeCk7CiB0b2tpbzo6aW86OkFzeW5jV3JpdGUgZm9yIEludGVybGVhdmVQZW5kaW5nPFc+IHsKIHNlbGY6OntkZWNvZGVyOjpCekRlY29kZXIsIGVuY29kZXI6OkJ6RW5jb2Rlcn07CnVzbWVtYmVyL2ZyYW1lIGFuZCBleHBlY3QgZWl0aGVyIEVPRiBvciBhbm90aGVyCiAgICBzc2VkIHN0cmVhbS4KICAgICAgICAgICAgcHViIGZuIG5ldyhyZWFkOiBSKSAtPiAkbnluY1JlYWQpIGludGVyZmFjZSBhbmQgd2lsbAogICAgICAgICAgICAvLy8gcmVhZCBjICAgICAgIFBpbjo6bmV3KCZtdXQgdGhpcy5yZWFkZXIpLmNvbnN1bWUoaSk7CiAgICAgIGxldCBidWZmZXIgPSByZWFkeSEoUGluOjpuZXcoJm11dCB0aGlzLnJlYWRlcikucHdyaXRlcjogJidhIG11dCBXLAogICAgYW10OiB1NjQsCn0KCmltcGw8UiwgVz4gRnV0b3B5X2J1ZjxSLCBXPihyZWFkZXI6IFIsIHdyaXRlcjogJm11dCBXKSAtPiBDb3B5QnVpbjo6bmV3KCZtdXQgc2VsZi5pbm5lcikucG9sbF93cml0ZShjeCwgYnVmKQogICAgfSBtYXRjaCBQaW46Om5ldygmbXV0IHNlbGYuaW5uZXIpLnBvbGxfY2xvc2UoY3gpIHsKV3JpdGUgZm9yIFRyYWNrQ2xvc2VkPFc+IHsKICAgIGZuIHBvbGxfd3JpdGUobXV0IHN9CiAgICB9CgogICAgcHViIGZuIGlzX2Nsb3NlZCgmc2VsZikgLT4gYm9vbCB7CiAgIHRkb3duIGJlZm9yZSBmaW5pc2hpbmcgaW5wdXQiLAogICAgICAgICAgICApKSkKICAgY2tfb24oZGVjb2Rlci5yZWFkX3RvX2VuZCgmbXV0IG91dHB1dCkpLmlzX2VycigpKTt0IGlucHV0ID0gSW5wdXRTdHJlYW06OmZyb20odmVjIVtjb21wcmVzc2VkXSk7CgogIFtdWy4uXSk7CgogICAgbGV0IGlucHV0ID0gSW5wdXRTdHJlYW06OmZyb20odmVjIVtjKV0KdXNlIHV0aWxzOjp7YWxnb3M6Onh6OjpzeW5jLCBJbnB1dFN0cmVhbX07CgojW2N0ZW4gdG8gYW5kIHNob3VsZAogICAgLy8vIGJlIHNlbnQuIEFzIHN1Y2gsIHRoaXMgZnMgYnVmZmVyLCBzbyB0aGV5IHNob3VsZCBiZQogICAgLy8vIHdyaXR0ZW4gb3V0IHRvayhidWYpKWAuCiAgICAvLy8KICAgIC8vLyBJZiB0aGUgYnVmZmVyIGlzIGZ1bGwgYW5ycyB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlY29kZXIucmVpbiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFN0YXRlOjpGbHVzaGluZyA9ICAgICAgICAgICAgICAgICAgICAgKnRoaXMubXVsdGlwbGVfbWVtYmVycyA9IGZhbHMpIHsKICAgICAgICBzZWxmLm11bHRpcGxlX21lbWJlcnMgPSBlbmFibGVkOwogICAgfWU+IERlY29kZXI8UiwgRD4gewogICAgcHViIGZuIG5ldyhyZWFkZXI6IFIsIGRlY29kKERlYnVnKV0KZW51bSBTdGF0ZSB7CiAgICBEZWNvZGluZywKICAgIEZsdXNoaW5nLAogd2hldGhlciB0aGUgZW5kIG9mIHRoZSBzdHJlYW0gaGFzIGJlZW4gcmVhZAogICAgZiBidWZmZXJzIGFyZSBmbHVzaGVkCiAgICBmbiBmbHVzaCgmbXV0IHNlbGYsIG91dHB1KV0KcHViKGNyYXRlKSB1c2Ugc2VsZjo6emxpYjo6e1psaWJEZWNvZGVyLCBabGliRW5wdWIoY3JhdGUpIHVzZSBzZWxmOjpmbGF0ZTo6e0ZsYXRlRGVjb2RlciwgRmxhdGVFbiAibHptYSIpXQptb2QgbHptYTsKI1tjZmcoZmVhdHVyZSA9ICJ4eiIpXQptb2QgeHo7Zl93cml0ZTo6QXN5bmNCdWZXcml0ZSwKICAgIGJ1Zl93cml0ZXI6OkJ1ZldyaXRlciwgewogICAgLy8vIFNlZWsgdG8gdGhlIG9mZnNldCwgaW4gYnl0ZXMsIGluIHRoZSB1bnQ6OlJlc3VsdCB7CiAgICAgICAgZi5kZWJ1Z19zdHJ1Y3QoIkJ1ZldyaXRlciIpCiAgKT87CiAgICAgICAgc2VsZi5wcm9qZWN0KCkuaW5uZXIucG9sbF9jbG9zZShjeCkKICAuKnRoaXMuYnVmZmVyZWQgKyBsZW5dLmNvcHlfZnJvbV9zbGljZSgmYnVmWy4ubGVuXXQgdGhpcyA9IHNlbGYuYXNfbXV0KCkucHJvamVjdCgpOwogICAgICAgIGlmIGJ1Zi5sdGhlIHVuZGVybHlpbmcgd3JpdGVyLgogICAgLy8vCiAgICAvLy8gTm90ZSB0aGF0IGFSZWFkeShyZXQpCiAgICAgICAgfSBlbHNlIGlmICp0aGlzLmJ1ZmZlcmVkID09IDAgey53cml0dGVuICs9IG4sCiAgICAgICAgICAgICAgICBQb2xsOjpSZWFkeShFcnIoZSkpZWRdKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBQb2xsOjpQZW5kaW5nID1wYWNpdHkuCiAgICBwdWIgZm4gd2l0aF9jYXBhY2l0eShjYXA6IHVzaXplLCBpbm5lcnR1cmVzX2lvOjp7QXN5bmNTZWVrLCBBc3luY1dyaXRlLCBTZWVrRnJvbX07CnVzZSBwCi8vIHRoZSBgQXN5bmNCdWZXcml0ZWAgaW1wbCBjYW4gYWNjZXNzIGl0cyBpbnRlcm4gICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbW9kIGRlY29tcGl0eSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQsCiAgKS5hc19yZWYoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxpbnB1dHwgewp0ZTo6RW5jb2Rlcjo6d2l0aF9xdWFsaXR5KGlucHV0LCBMZXZlbDo6QmVzdCkpLAogIHJlc3MgewogICAgICAgICAgICAgICAgICAgIHVzZSBjcmF0ZTo6dXRpbHM6OnsKICAgICAgICAgICAgICAgIGxldCBvdXRwdXQgPSByZWFkOjp0b192ZWMoZGVjb2Rlcik7CgogICAgICAgICAgc3luYzo6Y29tcHJlc3MoJlsxLCAyLCAzLCA0LCA1LCA2XSksCiAgICAgICAgIGxldCB0cmFpbGVyID0gcmVhZDo6dG9fdmVjKHJlYWRlcikgICAgbGV0IG91dHB1dCA9IGJ1ZnJlYWQ6OmRlY29tcHJlc3MoJm11dCByZWFkZXIpOzo6dGltZW91dCgxMDAwKV0KICAgICAgICAgICAgICAgICAgICBmbiB6ZXJvcygpIHsKICAgICAgICAgbGV0IGNvbXByZXNzZWQgPSBzeW5jOjpjb21wcmVzcygmW10pOwoKICA6OiR2YXJpYW50Ojp7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZXZlbDo6UHJlY2lzZSgwKSwKICAgYW0oKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZXZlbDo6QmVzdCwKICA6OmNvbXByZXNzKGJ1ZnJlYWQ6OmZyb20oJm9uZV90b19zaXhfc3RyZWFtKCkpKTsKIAogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbXV0IG91dHB1dCA9IFtdOwoKICAgICAgICAgICAgICAgICAgICBsZXQgbXV0IGlucHV0OiAmW3U4XSA9ICZbXTsKICAgICB0b2tpbzo6aW86OkFzeW5jV3JpdGU+IEFzeW5jV3JpdGVUZXN0RXh0IGZvciBUIHt9CmVuZGluZzsKbW9kIGxpbWl0ZWQ7CgpwdWIgdXNlIGNvcHlfYnVmOjpjb3B5X2J1ZjsKOntmdXR1cmU6OkZ1dHVyZSwgaW86OlJlc3VsdCwgaXRlcjo6RnJvbUl0ZXJhdG9yLCBlcmVudCB0ZXN0cyB1c2UgYSBkaWZmZXJlbnQgc3Vic2V0IG9mIGZ1bmN0aW9ucwoKbWxmLmFzX211dCgpLnByb2plY3QoKS5zdGF0ZSB7CiAgICAgICAgICAgICpzZWxmLmFzbiBjb21wcmVzcyhpbl9kYXRhOiAmW3U4XSkgLT4gUmVzdWx0PFZlYzx1OD4+IHsKICB0dXJlcz0idG9raW8semxpYiIKLy8hICJleGFtcGxlIgovLyEgYGBgCgp1c2UgICQgY2FyZ28gcnVuIC0tZXhhbXBsZSB6bGliX3Rva2lvX3dyaXRlIC0tZmVhdHVyZXMgPSBzdGQ6OmNtcDo6bWluKHNlbGYudW53cml0dGVuKCkubGVuKCksIG90aGVyLnVud2YuaW5kZXhdCiAgICB9CgogICAgcHViKGNyYXRlKSBmbiB1bndyaXR0ZW4oJnNlbGYpIH0KICAgIH0KfQpwdWIgZm4gX2Fzc2VydF9zZW5kPFQ6IFNlbmQ+KCkge30KcHViIGZ3KCZbXVsuLl0pLAogICAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICAgIEZsdXNoRHNNdXQ8W3U4XT4+LAogICAgICAgIGZsdXNoOiBGbHVzaERlY29tcHJlc3MsCiAgICApcmVzcywgU3RhdHVzfTsKCiNbZGVyaXZlKERlYnVnKV0KcHViIHN0cnVjdCBGbGF0ZUQgICAgICAgICAgICAuZmllbGQoCiAgICAgICAgICAgICAgICAiYnVmZmVyIiwKICAgIHVzaF9idWYoY3gpKT87CiAgICAgICAgc2VsZi5wcm9qZWN0KCkuaW5uZXIucG9sbF9zdCBsZW4gPSBtaW4odGhpcy5idWYubGVuKCkgLSAqdGhpcy5idWZmZXJlZCwgYnVmLmx3ZXJlIFBlbmRpbmcsIHNvIG91ciB3YWtlciB3YXMgYWxyZWFkeSBxdWV1ZWQKICAgIHQgVz4gewogICAgICAgIHNlbGYucHJvamVjdCgpLmlubmVyCj4gKnRoaXMud3JpdHRlbiArPSBuLAogICAgICAgICAgICAgICAgRXJyKGUpID0+IHsKOlJlYWR5KHJldCkKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXQ/OwogICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFBvbGw6OlJlYWR5KE9rKG4pKSA9PiAqdDogdmVjIVswOyBjYXBdLmludG8oKSwKICAgICAgICAgICAgd3JpdHRlbjogMCwKICAgU2VsZjo6d2l0aF9jYXBhY2l0eShERUZBVUxUX0JVRl9TSVpFLCBpbm5lcikKICAgIH0gZWZmaWNpZW50Ci8vIHdpdGggdGhvc2UgbWV0aG9kcy4KCnVzZSBzdXBlcjo6QXN5biAgICAgcmVhZHkhKHNlbGYucHJvamVjdCgpLndyaXRlci5hc19tdXQoKS5wb2xsX2NsZTo6RmluaXNoaW5nIHwgU3RhdGU6OkRvbmUgPT4gcGFuaWMhKCJGbHVzaCBhZnRlciA7Cgp1c2UgY3JhdGU6OnsKICAgIGNvZGVjOjpFbmNvZGUsCiAgICBmdXR1cmVzOjp3cmJ1ZmAgbWV0aG9kIHRvCiAgICAvLy8gZnVuY3Rpb24gcHJvcGVybHkuIFRoaXMgZnVuIGBQb2xsOjpQZW5kaW5nYCBhbmQKICAgIC8vLyBhcnJhbmdlcyBmb3IgdGhlIGN1cnJjcmF0ZSkgdHJhaXQgQXN5bmNCdWZXcml0ZSB7CiAgICAvLy8gQXR0ZW1wdCB0byByZXRfYnVmKT87CiAgICAgICAgbGV0IGxlbiA9IG91dF9idWYuYXNfc2xpY2UoKS5sZW4oICAgICAgLmdldF9tdXQoKQogICAgICAgICAgICAucnVuX29uX2J1ZmZlcnMoaW5wdXRjb2RlciA9IERlY29kZXI6OndpdGhfZGljdGlvbmFyeShkaWN0aW9uYXJ5KT87CiAgICAgICAgInVuZXhwZWN0ZWQgZW5kIG9mIGZpbGUiLAogICAgICAgICAgICApKQogICAgIGZsdXNoZWQgYWxsIHRoZSBkYXRhIG91dCBiZWZvcmUgd2UgZ2V0IGhlcmUKICAgICBIZWFkZXIoXykgfCBTdGF0ZTo6Rm9vdGVyKF8pIHwgU3RhdGU6OkRvbmUgPT4gcmV0dWltcGwgRGVjb2RlIGZvciBHemlwRGVjd3JpdHRlbigpLmlzX2VtcHR5KCkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGUgc2VsZi5zdGF0ZSA9IFN0YXRlOjpGb290ZXIodmVjIVswOyA4XS5pbnRvKCkpCiAgIHI8ST4sICZtdXQgUGFydGlhbEJ1ZmZlcjxPPikgLT4gUmVzdWx0PGJvb2w+LAogICAgCiAgICBpZiBieXRlc19yZWFkICE9IGlucHV0WzQuLjhdIHsKICAKfQoKZm4gY2hlY2tfZm9vdGVyKGNyYzogJkNyYywgaW5wdXQ6ICZbdThdKSAtPiBSZSBjb2RlYzo6ewogICAgICAgIGd6aXA6OmhlYWRlcjo6e3NlbGYsIEhlYWRlcn0sCiAgPiwKICAgICkgLT4gUmVzdWx0PGJvb2w+IHsKICAgICAgICAvLyBGbHVzaCBvbiBMWk0gICBpbm5lcjogY3JhdGU6OmNvZGVjOjpYejJFbmNvZGVyLAp9CgppbXBsIEx6bWFFbiAgLy8gRGVjb21wcmVzc2lvbiB3ZW50IGZpbmUsIG5vdGhpbmcgbXVjaCB0byByZXBvQnVmZmVyOjpuZXcoJltdWy4uXSksIG91dHB1dCwgQWN0aW9uOjpGbHVzaCk/IHsKICBhdGNoIHNlbGYuZW5jb2RlKGlucHV0LCBvdXRwdXQsIEFjdGlvbjo6UnVuKT8gewogIHVud3JpdHRlbigpLCBvdXRwdXQudW53cml0dGVuX211dCgpLCBhY3Rpb24pCiAgICAgdThdPiArIEFzTXV0PFt1OF0+PiwKICAgICAgICBhY3Rpb246IEFjdGlvbiwKICAgIClyZAogICAgLy8vIGFsZ29yaXRobSB3aWxsIGV4cGVuZCBiZWZvcmUgcmVzb3J0aW5nIHByZXNlbnRlZCB3aXRoIHdvcnN0IGNhc2UsIGhpZ2hseSByZXBldGl0aXZlLCBpbnB1ICAgICAgIHdyaXRlISgKICAgICAgICAgICAgZiwKICAgICAgICAgICAgIkJ6RW5jb2R1c2VdCm1vZCBkZWNvZGVyOwojW21hY3JvX3VzZV0KbW9kIGVuY29kZXI7CnVzZSBjcmRfbGVuID0gb3V0cHV0LndyaXR0ZW4oKS5sZW4oKTsKICAgICAgICAgICAgc2VsZi5lICAgIC8vIFdlIG5lZWQgdG8ga2VlcCB0cmFjayBvZiB3aGV0aGVyIHdlJ3ZlIGFscmVPayA9PiBPaygoKSksCiAgICAgICAgICAgIFN0YXR1czo6U3RyZWFtRW5kID0+IHVucmVuX211dCgpLCBmbHVzaCk/OwoKICAgICAgICBpbnB1dC5hZHZhbmNlKChzZWxmLmNvZXN1bHR9OwoKdXNlIGZsYXRlMjo6e0NvbXByZXNzLCBDb21wcmVzc2lvbiwgRmx1c2ggICBpbm5lcjogY3JhdGU6OmNvZGVjOjpYejJEZWNvZGVyLAp9CgppbXBsIEx6bWFEZSAgICAgICJzdHJlYW0gcGFkZGluZyB3YXMgbm90IGEgbXVsdGlwbGUgb2YgNCBieXRlbGV0IFNvbWUocmVmIG11dCBjb3VudCkgPSBzZWxmLnNraXBfcGFkZGluZyB7CiAgICBwYWRkaW5nID0gU29tZSg0KTsKICAgICAgICBzZWxmLmlubmVyLnJlaW5pdCgpCiAgIGVyOiBjcmF0ZTo6Y29kZWM6OkZsYXRlRW5jb2Rlcjo6bmV3KGxldmVsLCBmYWxzZSksY0J1ZlJlYWQgZm9yIFRyYWNrRW9mPFI+IHsKICAgIGZuIHBvbGxfZmlsbF9idWYoc2VQb2xsOjpSZWFkeShPaygoKSkpID0+IHsKICAgICAgICAgICAgICAgIGlmIGJ1Zi5maSAgICAgICB9CiAgICAgICAgICAgICAgICBQb2xsOjpSZWFkeShPayhidWYpKQogICAgdGV4dCkgLT4gUG9sbDxSZXN1bHQ8Jlt1OF0+PiB7CiAgICAgICAgbGV0IChpbm5lcix5bmNSZWFkICsgVW5waW4+IGZ1dHVyZXM6OmlvOjpBc3luY1JlYWQgZm9yIFRyYWNrRSBTZWxmIHsgaW5uZXIsIGVvZjogZmFsc2UgfQogICAgfQoKICAgIHB1YiBmbiBwcm9qICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbXBsPCRpbm5lcjogZnV0dXJBc3luY0J1ZlJlYWQ+ICRuYW1lPCRpbm5lcj4gewogICAgICAgICAgICAkKAogICAgIGZyb20gYW4gdW5kZXJseWluZyBzdHJlYW0gYW5kIGVtaXQgYSBzdHJlYW0gb2YgY29taXR0ZW4oKS5pc19lbXB0eSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBPayhmYWwgICAgc2VsZi5zdGF0ZSA9IFN0YXRlOjpGb290ZXIoc2VsZi5mb290ZXIoKS5pbnRvKCAgICAgIH0KCiAgICAgICAgICAgICAgICBTdGF0ZTo6RG9uZSA9PiB0cnVlLAogICAgICAgICAgICAgICAgICBvdXRwdXQuY29weV91bndyaXR0ZW5fZnJvbSgmbXV0ICpmb29TdGF0ZTo6RG9uZSA9PiBwYW5pYyEoImVuY29kZSBhZnRlciBjb21wbGV0ZSIpLAogICAgICAgICAgICAgICAgICAgIHNlbGYuc3RhdGUgPSBTdGF0ZTo6RW5jb2Rpbmc7CiAgbGV2ZWwpLmludG8oKSksCiAgICAgICAgfQogICAgfQoKICAgIGZuIGZvb3RlcigmbXUgICAgICAgIDB4MDIKICAgIH0gZWxzZSBpZiBsZXZlbC5sZXZlbCgpIDw9IENvbXByZUJ1ZmZlcjxWZWM8dTg+PiksCiAgICBFbmNvZGluZywKICAgIEZvb3RlcihQYXJ0aWFsbHQ8dXNpemU+PiB7CiAgICAgICAgbGV0IGxpbWl0ID0gc2VsZi5saW1pdDsKICAgICBvYF0oOjpmdXR1cmVzX2lvKS4KCnB1YiBtb2QgYnVmcmVhZDsKcHViIG1vZCB3cml0ZTwnXz4sCiAgICAgICAgICAgICAgICBidWY6ICZtdXQgdG9raW86OmlvOjpSZWFkQnVmIC8vLyBjb21wcmVzc2VkIG1lbWJlci9mcmFtZSB0byBmb2xsb3cgaXQgaW4gdGhlIHNldGhvZHMpKikqCgogICAgICAgICAgICAvLy8gQ29uZmlndXJlIG11bHRpLW1lbWJlciAgICBpbm5lcjogY3JhdGU6OnRva2lvOjpidWZyZWFkOjpEZWNvZGVyPFIsIGNyYXRlbmVyOmlkZW50PiAkKHsgJCgkaW5oZXJlbnRfbWV0aG9kczp0dCkqIH0pKikgPT4gewpbXSwgb3V0cHV0LnVud3JpdHRlbl9tdXQoKSwgQWN0aW9uOjpTeW5jRmx1c2gpPzsKCm91dCgpIGFzIHVzaXplIC0gcHJldmlvdXNfb3V0KTsKCiBlbGYuc3RyZWFtLnRvdGFsX2luKCkgYXMgdXNpemUgLSBwcmV2aW91c19pbik7CiAgIDpuZXdfbHptYV9lbmNvZGVyKCZMem1hT3B0aW9uczo6bmV3X3ByZXNldChsZXZlbCkuICAgICAgICAgICAgcGFuaWMhKCJwYXJzZXIgdXNlZCBhZnRlciBkb25lIik7CiAgICBmLmhlYWRlci5mbGFncy5jcmMgewogICAgICAgICAgICAgIGlucHV0LmFkdmFuY2UoaW5wdXQudW53cml0dGVuKCkubGVuKCkpOwogICAgICAgICAgICAgICAgICAgIHNlbGYuc3RhdGUgPSBTdGF0ZTo6Q3JjKDxfPjo6ZDpkZWZhdWx0KCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFN0YXRlOjpFeHRyYShkYXRhKSAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFN0YXRlOjpGaWxlbmFtZSg8Xz46OkFzUmVmPFt1OF0+PiwKICAgICkgLT4gUmVzdWx0PE9wdGlvbjxIZWFkZXI+PiB7CiAgICAgIE9rKEhlYWRlciB7IGZsYWdzIH0pCiAgICB9Cn0KCmltcGwgUGFyc2VyIHsKICBlLAogICAgaGVhZGVyOiBIZWFkZXIsCn0KCmltcGwgSGVhZGVyIHsKICAgIGZuIHBhcm9sLAogICAgZmlsZW5hbWU6IGJvb2wsCiAgICBjb21tZW50OiBib29sLAp9CgojW2RlICAgICBsZXQgbXV0IG91dHB1dCA9IFBhcnRpYWxCdWZmZXI6Om5ldyhidWYpOwogICB1bWUobGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGU6OkVuY29kaW5nCnQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVuY29kZXIuZW5jb2RlKCZtLAogICAgfQp9CgppbXBsPFI6IEFzeW5jQnVmUmVhZCwgRTogRW5jb2RlPiBFbmNvZGVlbGYucHJvamVjdCgpLndyaXRlci5hc19tdXQoKS5wb2xsX3NodXRkb3duKGN4KSk/OwogICAgfQoKICAgIGZuIGRvX3BvbGxfc2h1dGRvd24oc2VsZjogYWxCdWZmZXI6Om5ldyhvdXRwdXQpOwoKICAgICAgICAgICAgbGV0IGRvbmUgPSBtYXRuY29kaW5nID0+IHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmVuY29kZXIuZW5jb2l2ZShEZWJ1ZyldCiAgICBwdWIgc3RydWN0IEVuY29kZXI8VywgRTogRW5jb2RlPiB7b2YsCiAgICAgICAgICAgICAgICAicmVhY2hlZCB1bmV4cGVjdGVkIEVPRiIsCiAgICBzTW9yZU91dHB1dCA9PiAsCiAgICAgICAgICAgIEJyb3RsaVJlc3VsdDo6TmVlZHNNb3JlT3V0cHV0IHwgQnJvdAogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YXR1cyA9PiBzdGF0dXMsCiAgICAgICBsZXQgc3RhdHVzID0gbWF0Y2ggQnJvdGxpRGVjb21wcmVzc1N0cmVhbSgKICAgICBsaVN0YXRlYCBpcyB2ZXJ5IGxhcmdlIChvdmVyIDJrYikgd2hpY2ggaXMgd2h5IHdlJ3N0cmVhbTo6cmF3OjpDUGFyYW1ldGVyIHsKICAgICAgICAgICAgc2VsZi4wCiAgICAgOndpdGhfcXVhbGl0eV9hbmRfcGFyYW1zKClgIGNhbGxzLgogICAgICAgIC8vCiAgICAvLyBFbWl0IGEgZGljdGlvbmFyeSBJRCB3aGVuIHVzaW5nIGEgY3VzdG9tIGRpY3RpbyBwb3dlciBvZiB0d28pCiAgICAgICAgcHViIGZuIGxkbV9oYXNoX3JhdGVfbG9nKHZhICAgICAgICBwdWIgZm4gZW5hYmxlX2xvbmdfZGlzdGFuY2VfbWF0Y2hpbmcodmFsdWVlbmd0aCBtb2RpZmllcgogICAgICAgIHB1YiBmbiB0YXJnZXRfbGVuZ3RoKHZhbHVlOnVlOiB1MzIpIC0+IFNlbGYgewogICAgICAgICAgICBTZWxmKEhhc2hMb2codmFsdWUpZXNzaW9uIHBhcmFtZXRlciBmb3IgenN0ZC4gVGhpcyBpcyBhIHN0YWJsZSB3cmFwcGUgU2VsZjo6RGVmYXVsdCA9PiBsaWJ6c3RkOjpERUZBVUxUX0NPTVBSRVNTSU9OX0xFVmVsZikgLT4gaTMyIHsKICAgICAgICBsZXQgKGZhc3Rlc3QsIGJlc3QpID0gbGlienN0ICAgICAgICBsZXQgYmVzdCA9IGZsYXRlMjo6Q29tcHJlc3Npb246OmJlc3QoKTsKCiA6OkNvbXByZXNzaW9uOjpuZXcoCiAgICAgICAgICAgICAgICBxdWFsaXR5CiAgICAgIGcgaXQuCiAgICAvLy8gUXVhbGl0aWVzIGFyZSBpbXBsaWNpdGx5IGNsYW1wZWQgdG8gZXNzaW9uIGFsZ29yaXRobS4KICAgIERlZmF1bHQsCiAgICAvLy8gUHJlY2lzZSBxdWFybigKICAgIG1pc3NpbmdfZG9jcywKICAgIHJ1c3RfMjAxOF9pZGlvbXMsCiAgICBtaSAgIGRvYyA9ICJgenN0ZGAgfCBbYFpzdGRFbmNvZGVyYF0oP3NlYXJjaD1ac3RkRW5jZSA9ICJ4eiIpLAogICAgZG9jID0gImB4emAgKCppbmFjdGl2ZSopIHwgYFh6RW5jb2RvYyA9ICJgZGVmbGF0ZWAgfCBbYERlZmxhdGVFbmNvZGVyYF0oP3NlYXJjaD1EZWZsYWMgPSAiYGJyb3RsaWAgKCppbmFjdGl2ZSopIHwgYEJyb3RsaUVuY29kZXJgLCBgQnJvYWJsZSBjaG9pY2VzLCB0aGVzZSBkZXRlcm1pbmUgd2hpY2ggdHlwZXMgd2lsbCBiZSBmZ19hdHRyKV1gIHNob3VsZCBkbyBpdCwgYnV0Ci8vIHRoYXQncyB1bnN0YWJsZQojIXMgdGhhdCBoYXZlIGNvcnJlc3BvbmRpbmcgdG9wLWxldmVsIG1vZHVsZXM6Ci8vIQoKdGVzIGFuZCBSdXN0J3MgbW9kZXJuIGFzeW5jaHJvbm91cyBJTyB0eXBlcy4KLy8hCgp1dHB1dCA9IFBhcnRpYWxCdWZmZXI6Om5ldyhidWYuaW5pdGlhbGl6ZV91bmZpbGxlZD4gU3RhdGU6OkRvbmUsCgogICAgICAgICAgICAgICAgU3RhdGU6Ok5leHQgPT4gewogICAgICAgICAgICAgICAgICAgICAgIGlmICp0aGlzLm11bHRpcGxlX21lbWJlcnMgewpmIHRoZSByZWFkZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFzIHJldHVybiAgICAgIHNlbGYucmVhZGVyCiAgICB9CgogICAgcHViIGZuIG11bGY+KSAtPiBQaW48Jm11dCBSPiB7CiAgICAgICAgc2VsZi5wcm9qZWN0KCkucmVhZGVydDsKdXNlIHRva2lvOjppbzo6e0FzeW5jQnVmUmVhZCwgQXN5bmNSZWFkLCBSZWFkQnVrKEJyb3RsaUVuY29kZXJJc0ZpbmlzaGVkKCZzZWxmLnN0YXRlKSA9PSAxKQogICAgfSAgICBPayhCcm90bGlFbmNvZGVySGFzTW9yZU91dHB1dCgmc2VsZi5zdGF0ZSkgPT0gRXJyb3I6Om5ldyhFcnJvcktpbmQ6Ok90aGVyLCAiYnJvdGxpIGVycm9yIikpOwogICAgICAgICAgIG91dF9idWYsCiAgICAgICAgICAgICZtdXQgb3V0cHV0X2xlbiwKICAgIGlFbmNvZGVyU3RhdGVTdHJ1Y3Q8U3RhbmRhcmRBbGxvYz4sCn0KCmltcGwgQnJvdGxpcktpbmQsIFJlc3VsdH0sCn07Cgp1c2UgYnJvdGxpOjplbmM6OnsKICAgIGJhY2t3YXIgaW5uZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNyYXRlOjpjb2RlYzo6THptYSAgY3JhdGU6OmNvZGVjOjpac3RkRGVjb2Rlcjo6bmV3X3dpdGhfZGljdChkaWN0aW9uICAgLy8vIGJlIHByZXNlbnQgZHVyaW5nIGRlY29tcHJlc3Npb24uIFRoZSBkaWN0aW9oZSBnaXZlbiBzdHJlYW0gYW5kIGVtaXQgYW4KICAgICAgICAgICAgLy8vIHVuY29tcFJldHVybnMgZXJyb3Igd2hlbiBgZGljdGlvbmFyeWAgaXMgbm90IHZhbGlkLgogICAgOjpMZXZlbCwgcGFyYW1zOiAmW2NyYXRlOjp6c3RkOjpDUGFyYW1ldGVyXSkgLT4gU2UgLy8vIHRoZSBgenN0ZG10YCBjcmF0ZSBmZWF0dXJlIGlzIF9ub3RfIGVuYWJsZWQuCnByZXNzZWQgZGF0YSBmcm9tIHRoZSBnaXZlbiBzdHJlYW0gYW5kIGVtaXQgYSBjb21wYkVuY29kZXIgPCRpbm5lcj4KICAgICAgICB7IEBlbmMKICAgICAgICAgYWxnb3MhKEBhbGdvIHpsaWIgWyJ6bGliIl0gWmxpYkRlY29kZXIgWmxpYkVuYzsKCiAgICAgICAgYWxnb3MhKEBhbGdvIGRlZmxhdGUgWyJkZWZsYXRlIl0gRGVmbGF0Y29kZWM6OkJ6RW5jb2Rlcjo6bmV3KGxldmVsLmludG9fYnppcDIoKSwgMCksCiAgICBsZ29zIShAYWxnbyBicm90bGkgWyJicm90bGkiXSBCcm90bGlEZWNvZGVyIEJyb3RsaXRob2RzKSogfQogICAgICAgIH0KICAgIH07CgogICAgKCQoJG1vZDppZGVudCk6OisgICAgKEBhbGdvICRhbGdvOmlkZW50IFskYWxnb19zOmV4cHJdICRkZWNvZGVyOmlkZW5kYF0oZnV0dXJlc19pbzo6QXN5bmNCdWZSZWFkKSBzdHJlYW1zLCBib3RoIGVuY29kZWRlKCZtdXQgUGFydGlhbEJ1ZmZlcjo6bmV3KCZbXVsuLl0pLCBvdXRwdXQpPzsKCiAgdXQuCiAgICAgICAgICAgIFN0YXR1czo6U3RyZWFtRW5kID0+IE9rKHRydWUpLAoKICAuYWR2YW5jZSgoc2VsZi5kZWNvbXByZXNzLnRvdGFsX291dCgpIC0gcHJpbzo6RXJyb3I6Om5ldyhzdGQ6OmlvOjpFcnJvcktpbmQ6Ok90aGVyLCBlKSk/OwoKIHM6IERlY29tcHJlc3MsCn0KCmltcGwgZm10OjpEZWJ1ZyBmb3IgQno7CiAgICB9Cn0KbW9kIGRlY29kZXI7Cm1vZCBlbmNvZGVyOwptb2QgaGVhZGVyOwoKcCAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZuIHBvbGxfc2h1dGRvd24oCiAgICAgeCwgYnVmKQogICAgICAgICAgICB9CgogICAgICAgICAgICBmbiBwb2xsX2ZsdXNoKApvX2lubmVyKCkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW1wbDxXOmEgYW5kIHdyaXRlIGl0IHVuY29tcHJlc3NlZAogICAgICAgICAgICAvLy8gdG8gdGhlICAgLy8vIHRha2UgaW4gY29tcHJlc3NlZCBkYXRhIGFuZCB3cml0ZSBpdCB1bmNvbXBzZWxmLnN0cmVhbS50b3RhbF9vdXQoKSBhcyB1c2l6ZTsKCiAgIHsKICAgICAgICAvLyBXaGlsZSBkZWNvZGluZyBmbHVzaCBpcyBhIG5vb3AKICAgICAgdHRlbigpLCBvdXRwdXQudW53cml0dGVuX211dCgpLCBBY3Rpb246OlJ1bik/OwoKICB0PFt1OF0+PiwKICAgICkgLT4gUmVzdWx0PGJvb2w+IHsKICAgICAgICBsZXQgcHJldiBTdGF0dXMsIFN0cmVhbX07CgpwdWIgc3RydWN0IFh6MkRlY29kZXIgewogICAgc3RyX2Fzc2VydF9zZW5kOjo8JG5hbWU8UGluPEJveDxkeW4gQXN5bmNXcml0ZSArIFNlbmRzazo6Q29udGV4dDwnXz4sCiAgICAgICAgICAgICAgICBidWY6ICZbdThdLAogICAgICAgICAgICAgICAgIC8vLyBDb25zdW1lcyB0aGlzIGVwaW46OlBpbjwmbXV0IFNlbGY+KSAtPiBzdGQ6OnBpbjo6UGluPCZtdXQgJGlubmVyPiAgICAgICAvLy8gQ3JlYXRlcyBhIG5ldyBlbmNvZGVyIHdoaWNoIHdpbGwgdGFrZSBpZWNvZGVyLCBlbmNvZGVyOjpabGliRW5jb2Rlcn07Cm1hY3JvX3J1bGVzISBlbmNvZGU6IFBpbjwmbXV0IFNlbGY+LCBjeDogJm11dCBDb250ZXh0PCdfPikgLT4gUG9sbDxzdGFrZXIoKS53YWtlX2J5X3JlZigpOwogICAgICAgICAgICBzZWxmLnBlbmRlZCA9IHRyICAgIGlmIHNlbGYucGVuZGVkIHsKICAgICAgICAgICAgbGV0IG5leHQgPSBQaW46Om4gSW50ZXJsZWF2ZVBlbmRpbmc8VD4gewogICAgaW5uZXI6IFQsCiAgICBwZW5kZWQ6IHNzZXJ0X3NlbmQ6OjwkbmFtZTxQaW48Qm94PGR5biBBc3luY0J1ZlJlYWQgKyBTZW5kcmVzX2lvOjpBc3luY0J1ZlJlYWQ+IGZ1dHVyZXNfaW86OkFzeW5jUmVhZCBmb3IgJG5kZWNvZGVyIHN0YXRlCiAgICAgICAgICAgIC8vLyB3aGVuIHJlYWNoaW5nIHRoZSBlbkRlY29kZXI6Om5ldyhyZWFkLCBjcmF0ZTo6Y29kZWM6OiRuYW1lOjpuZXcoKSksCiAgbWFjcm9fcnVsZXMhIGRlY29kCiAgICAgICAgICAgIHRoaXMuYW10ICs9IGkgYXMgdTY0OwogICAgIE91dHB1dD4gewogICAgICAgIGxldCB0aGlzID0gJm11dCAqc2VsZjsKICAgICBVbnBpbiArID9TaXplZCwKewogICAgQ29weUJ1ZiB7CiAgICAgICAgcmVhZGVyLAogIG5jV3JpdGV9OwoKcHViIGZuIGNvcHlfYnVmPFIsIFc+KHJlYWRlcjogUiwgd3JpdGVydXJlID0gInRva2lvIildCmltcGw8VzogdG9raW90IENvbnRleHQsCiAgICAgICAgYnVmczogJltzdGQ6OmlvOjpJb1NsaWNlXSwKICAgIChtdXQgc2VsZjogUGluPCZtdXQgU2VsZj4sIGN4OiAmbXV0IENvbnRleHQsIGJ1ZjogdWN0IFRyYWNrQ2xvc2VkPFc+IHsKICAgIGlubmVyOiBXLAogICAgY2xvc2VkOiBib28pCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUG9sbDo6UmVhZHkoRXJyKEVycmVzdWx0PCgpPj4gewogICAgICAgIGlmIGxldCBTdGF0ZTo6RGVjb2RpbmcgPSBzZWxmCgppbXBsPFc6IEFzeW5jV3JpdGUsIEQ6IERlY29kZT4gQXN5bmNXcml0ZSBmb3IgRGV1dCk/IHsKICAgICAgICAgICAgICAgICAgICAgICAgKFN0YXRlOjpEb25lLCBmYWxzZXRwdXQpPyB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlOjpGaW5pc2hpbmcKLCBEPiB7CiAgICBwdWIgZm4gbmV3KHdyaXRlcjogVywgZGVjb2RlcjogRCkgLT4gU2VlbWJlcnModHJ1ZSk7CgogICAgbGV0IG11dCBvdXRwdXQgPSBWZWM6Om5ldygpOwogIDFdWy4uXSk7Cn0KCiNbdGVzdF0KI1tudGVzdDo6dGltZW91dCgxMDAwKV0KI1tjZmcoYmVyc193aXRoX3BhZGRpbmcoKSB7CiAgICBsZXQgY29tcHJlc3NlZCA9IFsKICAgICB1bnVzZWQpXQp1c2UgZnV0dXJlczo6e2V4ZWN1dG9yOjpibG9ja19vbiwgaW86OkFzeS8gVGhlIGBhbXRgIG11c3QgYmUgYDw9YCB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRodW5jdGlvbiBkb2VzIG5vdCBwZXJmb3JtIGFueSBJL08sIGl0IHNpbXBseSBpbmZvcm1jdXJyZW50IHRhc2sgY29udGV4dCAoYGN4YCkgdG8gcmVjZWl2ZSBhIG5vdGlmaWNhdCwgJm11dCBvdXRwdXQpPyB7CiAgICAgICAgICAgIFBvbGw6OlBlbmRpbmcgaWYgb3V0YmVycyB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlY29kZXIucmUsIG91dHB1dCk/OwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbGVuID0gaW5wdXB0eSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXZvaWQgYXR0ZW1wdGluPiwKICAgICAgICBvdXRwdXQ6ICZtdXQgUGFydGlhbEJ1ZmZlcjwmbXV0IFt1OF0+LApEZWNvZGluZywKICAgICAgICAgICAgbXVsdGlwbGVfbWVtYmVyczogZmFsc2UsCiAgIHk7CnVzZSBmdXR1cmVzX2lvOjp7QXN5bmNCdWZSZWFkLCBBc3luY1JlYWR9Owp1c2UgdThdPiArIEFzTXV0PFt1OF0+PikKICAgICAgICAtPiBSZXN1bHQ8Ym9vbD47CgogICAgYXJlIGZsdXNoZWQgYW5kIHRoZSBlbmQgb2YgdGhlIHN0cmVhbSBpcyB3cml0dGVuClpzdGREZWNvZGVyLCBac3RkRW5jb2Rlcn07CgpwdWIgdHJhaXQgRW5jb2RlIHsKICAgcHViKGNyYXRlKSB1c2Ugc2VsZjo6YnJvdGxpOjp7QnJvdGxpRGVjb2RlciwgQnJvdGxhdGUiKV0KbW9kIGRlZmxhdGU7CiNbY2ZnKGZlYXR1cmUgPSAiZmxhdGUyIildCm1vZHM7Cm1vZCBnZW5lcmljOwoKbW9kIGJ1Zl93cml0ZTsKbW9kIGJ1Zl93cml0ZXI7Cgp1ICAgICAgKQogICAgICAgICAgICAuZmllbGQoIndyaXR0ZW4iLCAmc2VsZi53cml0dGUmbXV0IFt1OF0+PiB7CiAgICAgICAgcmVhZHkhKHNlbGYuYXNfbXV0KCkucGFydGlhbFJlc3VsdDwoKT4+IHsKICAgICAgICByZWFkeSEoc2VsZi5hc19tdXQoKS5mbHVzaF9idWxkIGhhdmUgcmV0dXJuZWQgd2l0aAogICAgICAgICAgICAgICAgLy8gYHRoaXMuYnVmIGJ1Zi5sZW4oKSA+PSB0aGlzLmJ1Zi5sZW4oKSB7CiAgICAgICAgICAgIGlmICp0aCAgICAgJm11dCBzZWxmLmlubmVyCiAgICB9CgogICAgLy8vIEdldHMgYSBwaW4vIEdldHMgYSByZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgd3JpdGVyLgogICAgcGZlcmVkXSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9rKDApID0+IHsKICp0aGlzLmJ1ZmZlcmVkIHsKICAgICAgICAgICAgbWF0Y2ggcmVhZHkhKHRoaXMKICBFcnIoZSkpID0+IHsKICAgICAgICAgICAgICAgICAgICByZXQgPSBFcnIoZSk7CiAgIChPaygwKSkgPT4gewogICAgICAgICAgICAgICAgICAgIHJldCA9IEVycihpbzo6RXJyZWZhdWx0IGlzIGN1cnJlbnRseSA4IEtCLAogICAgLy8vIGJ1dCBtYXkgY2hhbmdlIGlvamVjdDsKdXNlIHN0ZDo6ewogICAgY21wOjptaW4sCiAgICBmbXQsIGlvLAogICAgcGRzIHRvIGJlIHJlZGVmaW5lZCBsb2NhbGx5IHNvIHRoYXQKLy8gdGhlIGBBc3luY0J1OnRpbWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gbG9uZ19jaHVua3M6OnRpbWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gc2hvcnQoKSB7CiA9IHdyaXRlOjpkZWNvbXByZXNzKGlucHV0LmFzX3JlZigpLCA2NV81MzYpOwoKICAgICAgICAgICAgICAgICAgICAgICBvbmVfdG9fc2l4LCBJbnB1dFN0cmVhbSwKICAgICAgICAgICBCb3g6OnBpbih3cml0ZTo6RW5jb2Rlcjo6d2l0aF9xdWFsaXR5KAogICAgIGNvZGVyOjp3aXRoX3F1YWxpdHkoaW5wdXQsIExldmVsOjpQcmVjaXNlKDApKSkKICAgIHxpbnB1dHwgQm94OjpwaW4od3JpdGU6OkVuY29kZXI6Om5ldyhpbnB1dCkpLAogICBzZWQgPSB3cml0ZTo6dG9fdmVjKAogICAgIHByZXNzZWQgPSB3cml0ZTo6Y29tcHJlc3MoaW5wdXQuYXNfcmVmKCksIDIwKTsKICAgICAgICAgICAgICAgIGxldCBpbnB1dCA9IElucHV0U3RyZWFtOjpuZXcodmVjIVsKICBlOjpjb21wcmVzcyhvbmVfdG9fc2l4X3N0cmVhbSgpLmFzX3JlZigpLCAyKTsKICAgIG1wcmVzcyhvbmVfdG9fc2l4X3N0cmVhbSgpLmFzX3JlZigpLCA2NV81MzYpOwogICAgdCgxMDAwKV0KICAgICAgICAgICAgICAgICAgICBmbiBlbXB0eV9jaHVuaygpIHsKICBtcHJlc3MgewogICAgICAgICAgICAgICAgICAgIHVzZSBjcmF0ZTo6dXRpbHM6OnsKIHV0cHV0LCAmWzEsIDIsIDMsIDQsIDUsIDYsIDYsIDUsIDQsIDMsIDIsIDFdWy4uXSk7bShjb21wcmVzc2VkLmNodW5rcygxMDI0KSk7CiAgICA9ICgwLi42NV81MzYpLm1hcCh8X3wgcmFuZDo6cmFuZG9tKCkpLmNvbGxlY3QoKTsKOnRpbWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gbG9uZygpIHsKICAgICAgIGNvbXByZXNzZWQuZXh0ZW5kX2Zyb21fc2xpY2UoJls3LCA4LCA5LCAxMF0pOygxMDAwKV0KICAgICAgICAgICAgICAgICAgICBmbiBzaG9ydF9jaHVua3MoKSB7CiAgICAgICAgICAgICAgICAgICBhc3NlcnRfZXEhKG91dHB1dCwgJlswOyAxMF1bLi5dKTsgICAgICAgbGV0IHJlc3VsdCA9IHJlYWQ6OnBvbGxfcmVhZChkZWNvZGVyLCAmbXV0IG1lb3V0KDEwMDApXQogICAgICAgICAgICAgICAgICAgIGZuIHRvX2Z1bGxfb3V0cHV0ICAgICAgICAgICAgICAgICAgICAgICRpbXBsOjp7YnVmcmVhZCwgcmVhZH0sCiAgICB0ZXN0XQogICAgICAgICAgICAgICAgICAgIGZuIHdpdGhfbGV2ZWxfbWF4KCkgewogICNbdGVzdF0KICAgICAgICAgICAgICAgICAgICBmbiB3aXRoX2xldmVsXzAoKSB7CiAgdF0KICAgICAgICAgICAgICAgICAgICBmbiB3aXRoX2xldmVsX2RlZmF1bHQoKSB7CiBlZCA9IGJ1ZnJlYWQ6OmNvbXByZXNzKGJ1ZnJlYWQ6OmZyb20oJmlucHV0KSk7CiAgIG5kb20oKSkuY29sbGVjdCgpLAogICAgICAgICAgICAgICAgICAgICAgICBdKTsKCiAgICAgbGV0IGlucHV0ID0gSW5wdXRTdHJlYW06Om5ldyh2ZWMhW3ZlYyFbXV0pOwoKICAgICAgICAgICAgICAgIGFzc2VydCEobWF0Y2hlcyEocmVzdWx0LCBPaygwKSkpOwogIF9zaXgsIG9uZV90b19zaXhfc3RyZWFtLCBJbnB1dFN0cmVhbSwgTGV2ZWwsCiAgICAgICAoJGltcGw6aWRlbnQsICR2YXJpYW50OmlkZW50KSA9PiB7CiAgICAgICAgbW9kICQgIFNlbGY6IFNpemVkICsgVW5waW4sCiAgICB7CiAgICAgICAgbGltaXRlZDo6TGltaXJhY2tDbG9zZWQsIHRyYWNrX2VvZjo6VHJhY2tFb2Z9OwpwdWIgdXNlIGFzeW5jX2NvIyFbYWxsb3coZGVhZF9jb2RlLCB1bnVzZWRfbWFjcm9zKV0gLy8gRGlmZmVyZW50IHRhc19tdXQoKS5wcm9qZWN0KCkuc3RhdGUgPSBTdGF0ZTo6RmluaXNoaW5nOwogICAgICBpZiBpbnB1dC53cml0dGVuKCkuaXNfZW1wdHkoKSA9PiBQb2xsOjpQZW5kaW5nLAogICAgICAgICAgICAgICBTdGF0ZTo6RG9uZSA9PiAoU3RhdGU6OkRvbmUsIHRydWUpLApwdXQpPyB7CiAgICAgICAgICAgICAgICAgICAgICAgIChTdGF0ZTo6RG9uZSwgZmFscyBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RhdGU6OkRlY29kaW5nCiAgcGw8VzogQXN5bmNXcml0ZSwgRDogRGVjb2RlPiBEZWNvZGVzeW5jV3JpdGU7CnVzZSBwaW5fcHJvamVjdF9saXRlOjpwaW5fcHJvamVjdDsKCiNbZHI6Om5ldyhWZWM6Om5ldygpKTsKICAgIGRlY29kZXIud3JpdGVfYWxsKGluX2RhdGEpCiAgICBwcmludGxuISgiezo/fSIsIFN0cmluZzo6ZnJvbV91dGY4KGRlX2NvbXByZXMgICAgICAgIHN0ZDo6bWVtOjpyZXBsYWNlKHNlbGYsIFNlbGY6Om5ldyhCOjpkZWZhdWl0dGVuX2Zyb208QzogQXNSZWY8W3U4XT4+KCZtdXQgc2VsZiwgb3RoZXI6ICZtdXQgQnVmZmVyPEI+IHsKICAgIHB1YihjcmF0ZSkgZm4gbmV3KGJ1ZmZlcjogQikgLT4gU2VydWN0IFBhcnRpYWxCdWZmZXI8QjogQXNSZWY8W3U4XT4+IHsKICAgIGJ1ZmZlcjogQik7CiAgICAgICAgICAgIHNlbGYuZGVjb2RlKAogICAgICAgICAgICAgICAgJm11dCBQZGVjb2RlKGlucHV0LCBvdXRwdXQsIEZsdXNoRGVjb21wcmVzczo6Tm9uZSk/IHsKICAgICAgICBPayhzdGF0dXMpCiAgICB9Cn0KCmltcGwgRGVjb2RlIGZvciBGbGF0ZURlYyAgICAgICAgICAgc2VsZi5kZWNvbXByZXNzCiAgICAgICAgICAgICAgICAuZGVjb21wdWIgZW51bSBYejJGaWxlRm9ybWF0IHsKICAgIFh6LAogICAgTHptYSwKfQoKcHViKGNpemUpIHsKICAgICAgICAqc2VsZi5wcm9qZWN0KCkuYnVmZmVyZWQgKz0gYW10OwogIGw6OlJlYWR5KE9rKCZtdXQgdGhpcy5idWZbKnRoaXMuYnVmZmVyZWQuLl0pKQogICAgWyp0aGlzLmJ1ZmZlcmVkLi4qdGhpcy5idWZmZXJlZCArIGxlbl0uY29weV9mcm9tX3MvLyBUaGUgb25seSB3YXkgdGhhdCBgcGFydGlhbF9mbHVzaF9idWZgIHdvdWxkIGhhdmVmdG92ZXIgZGF0YSBpbiB0aGUgaW50ZXJuYWwgYnVmZmVyIGlzIGxvc3QuCiAgICBwJlcgewogICAgICAgICZzZWxmLmlubmVyCiAgICB9CgogICAgLy8vIEdldHMgYSBtdXR0aGlzLmJ1ZmZlcmVkLCAwKTsKICAgICAgICAqdGhpcy5idWZmZXJlZCAtPSAqdGhpcyAgICAgfQogICAgfQoKICAgIGZuIGZsdXNoX2J1ZihzZWxmOiB0ZW4gPiAwIHsKICAgICAgICAgICAgdGhpcy5idWYuY29weV93aXRoaW4oKnRoaXMudyAgICAgICAgICAgICAgIC5hc19tdXQoKQogICAgICAgICAgICAgICAgLnBvbGxfdyBzZWxmLnByb2plY3QoKTsKCiAgICAgICAgbGV0IG11dCByZXQgPSBPaygoKSk7CiAgIGEgbmV3IGBCdWZXcml0ZXJgIHdpdGggYSBkZWZhdWx0IGJ1ZmZlciBjYXBhY2l0eS5udGVybmFscywgYW5kIGNoYW5nZWQgYSBiaXQgdG8gbWFrZSBpdCBtb3JlIGVmZmljaV9tdXQoKS5kb19wb2xsX2Nsb3NlKGN4KSk/OwogICAgICAgIHJlYWR5IShzZWxmLnBycHR5KCkgewogICAgICAgICAgICByZXR1cm4gUG9sbDo6UmVhZHkoT2soMCkpOwogICByb2R1Y2VkKTsKCiAgICAgICAgICAgIGlmIGxldCBTdGF0ZTo6RG9uZSA9IHRoaXMucyAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmbiBkb19wb2xsX2Nsb3NlKHNlbGY6CiAgICAgICAgfQogICAgfQoKICAgIGZuIGRvX3BvbGxfZmx1c2goc2VsZjogIHwgU3RhdGU6OkRvbmUgPT4gcGFuaWMhKCJXcml0ZSBhZnRlciBjbG9zZSIpLAogICBqZWN0KCk7CgogICAgICAgIGxvb3AgewogICAgICAgICAgICBsZXQgb3V0cHV0ID0gciwgRT4gewogICAgcHViIGZuIG5ldyh3cml0ZXI6IFcsIGVuY29kZXI6IEUpIC0+IFNlbGxfZmx1c2hfYnVmYC4KICAgIGZuIHByb2R1Y2Uoc2VsZjp1c2hfYnVmYCBpc24ndAogICAgLy8vIGNhbGxlZCBiZWZvcmUgY2FsbGluZyBpdC4KIHdoZW4gdGhlIG9iamVjdAogICAgLy8vIGJlY29tZXMgcmVhZGFibGUgb3IgaXMgY2xvdCB0byB0aGUgaW5uZXIgcmVhZGVyIGlmCiAgICAvLy8gaXQgaXMgZnVsbC4KICAgIC8gbXV0IG91dF9idWYgPSB6c3RkX3NhZmU6Ok91dEJ1ZmZlcjo6YXJvdW5kKG91dHB1dF93cml0dGVuKTsKICAgICAgICBPayhzdGF0dXMucmVtYWluaW5nID09IDApCiAgICB9ZWNvZGVyOiBVbnNoYXJlZDo6bmV3KERlY29kZXI6Om5ldygpLnVud3JhcCgpKSwKICAgIEVycm9yS2luZDo6VW5leHBlY3RlZEVvZiwKICAgICAgICAgICAgICAgICJ1bmV4cD4gewogICAgICAgIC8vIEJlY2F1c2Ugb2YgdGhlIGZvb3RlciB3ZSBoYXZlIHRvIGhhRGVjb2RpbmcgPT4gewogICAgICAgICAgICAgICAgICAgIGxldCBwcmlvciA9IG91dHByb2Nlc3MoaW5wdXQsIG91dHB1dCwgfHRoaXMsIGlucHV0LCBvdXRwdXR8IHsKICAgICAgICAgICAgIGlmIGlucHV0LnVud3JpdHRlbigpLmlzX2VtcHR5KCkgfHwgb3V0cHV0ICAgIHNlbGYuY3JjLnVwZGF0ZSgmb3V0cHV0LndyaXR0ZW4oKVtwcmlvci4uXSk7CiByOiBpbXBsIEZuKCZtdXQgU2VsZiwgJm11dCBQYXJ0aWFsQnVmZmVyPEk+LCAmbXV0ICAgICAgICAgImFtb3VudCBvZiBieXRlcyByZWFkIGRvZXMgbm90IG1hdGNoIiwKICAgdCBieXRlc19yZWFkID0gY3JjLmFtb3VudCgpLnRvX2xlX2J5dGVzKCk7CgogICAgaWYgICAgIERlY29kZSwKICAgIH0sCiAgICB1dGlsOjpQYXJ0aWFsQnVmZmVyLAp9Owp1cwogICAgZm4gZmx1c2goCiAgICAgICAgJm11dCBzZWxmLAogICAgICAgIF9vdXRwdXQ6cjo6bmV3KGNyYXRlOjpjb2RlYzo6WHoyRmlsZUZvcm1hdDo6THptYSwgbGV2ZWwpLApFcnJvcjo6bmV3KEVycm9yS2luZDo6T3RoZXIsICJvdXQgb2YgbWVtb3J5IikpLAogICA9PiB1bnJlYWNoYWJsZSEoKSwKCiAgICAgICAgICAgIC8vIFRoZSBSdW4gYWN0aW9uZXN0LCBidXQgb3RoZXJ3aXNlIGV2ZXJ5dGhpbmcgd2VudCBub3JtYWxseS4KICAgICBhdHVzOjpGbHVzaE9rID0+IE9rKGZhbHNlKSwKCiAgICAgICAgICAgIC8vIFRoZSBSdXMgYmVlbiBtZXQsIG1lYW5pbmcgdGhhdCBubyBtb3JlIGRhdGEgY2FuIGJlIGlucHV0b21wcmVzc2lvbiB3ZW50IG9rLgogICAgICAgICAgICBTdGF0dXM6OlJ1bk9rID0+IE8gICAgIGxldCBwcmlvcl9vdXQgPSBzZWxmLmNvbXByZXNzLnRvdGFsX291dCgpOwoKICB0byAyNTAgaW5jbHVzaXZlLiAwIGlzIGEgc3BlY2lhbCBjYXNlLAogICAgLy8vIGVxZWZhdWx0IHZhbHVlIG9mIDMwIGdpdmVzIHJlYXNvbmFibGUgYmVoYXZpb3VyIG92ZXJyIHRoYW4gdGhlIHN0YW5kYXJkIGFsZ29yaXRobSBieSBwZXJoYXBzCiAgICAvLy8gYSBmb3IgY29tcHJlc3Npb24uCiAgICAvLy8KICAgIC8vLyBUaGUgYHdvcmtfZmFjdG9yICAgICAgICAgICAgRmx1c2hDb21wcmVzczo6RmluaXNoLAogICAgICAgICk/IHsKICAKCiAgICAgICAgc2VsZi5mbHVzaGVkID0gdHJ1ZTsKICAgICAgICBPayghb3V0cHV0LnN5bmMgYmxvY2tzIGNvbnRpbnVvdXNseSBhbmQgcHJvYmFibHkgbmV2ZXIgY29tcGxlPiwKICAgICkgLT4gUmVzdWx0PCgpPiB7CiAgICAgICAgc2VsZi5mbHVzaGVkID0gZmFlbGYuY29tcHJlc3MudG90YWxfaW4oKSAtIHByaW9yX2luKSBhcyB1c2l6ZSk7CiAgIGF0ZSkgZm4gbmV3KGxldmVsOiBDb21wcmVzc2lvbiwgemxpYl9oZWFkZXI6IGJvb2wpY29kZXI6Om5ldygpLAogICAgICAgIH0KICAgIH0KfQoKaW1wbCBEZWNvZGUgZm9yIExub24tcGFkZGluZyB0aGVuIGl0IGNhbm5vdCBzdGFydCB3aXRoIG51bGwgYnl0ZXMsICB3aGlsZSBpbnB1dC51bndyaXR0ZW4oKS5maXJzdCgpID09IFNvbWUoJjApIHsKICAgb248dTg+LAp9CgppbXBsIFh6RGVjb2RlciB7CiAgICBwdWIgZm4gbmV3KCkgLT4gU2U+LAogICAgKSAtPiBSZXN1bHQ8Ym9vbD4gewogICAgICAgIHNlbGYuaW5uZXIuZmluaSBpbm5lcjogY3JhdGU6OmNvZGVjOjpGbGF0ZUVuY29kZXIsCn0KCmltcGwgRGVmbGF0bGxfYnVmKGN4KSB7CiAgICAgICAgICAgIFBvbGw6OlJlYWR5KE9rKGJ1ZikpID0+IHsuZmlsbGVkKCkubGVuKCkgPT0gbGVuICYmIGJ1Zi5yZW1haW5pbmcoKSA+IDAgewogIGYgYnVmLmlzX2VtcHR5KCkgewogICAgICAgICAgICAgICAgICAgICplb2YgPSB0cnVlQ29udGV4dCkgLT4gUG9sbDxSZXN1bHQ8Jlt1OF0+PiB7CiAgICAgICAgbGV0IChpbm5lb2YpOwogICAgICAgIG1hdGNoIGlubmVyLnBvbGxfcmVhZChjeCwgYnVmKSB7CiAgIGdfYXR0cihub3QoZmVhdHVyZSA9ICJhbGwtaW1wbGVtZW50YXRpb25zIiksIGFsbG93ICAgICAgICAgICAgICAgdXNlIGZ1dHVyZXNfaW86OkFzeW5jQnVmUmVhZDsKCiAgICAoc2VsZikgLT4gJGlubmVyIHsKICAgICAgICAgICAgICAgIHNlbGYuaW5uZXIuaW50byAgICAgICAgICAvLy8gbWF5IG90aGVyd2lzZSBjb25mdXNlIHRoaXMgZW5jb2Rlci4KLgogICAgICAgICAgICBwdWIgZm4gZ2V0X3JlZigmc2VsZikgLT4gJiRpbm5lciAgICAgICAgICAkKCRpbmhlcmVudF9tZXRob2RzKSoKICAgICAgICAgICAgKSoKCiAgIGwKICAgICAgICAgICAgLy8vIHJlYWQgdW5jb21wcmVzc2VkIGRhdGEgZnJvbSBhbiB1ICAgICAgICB9CgogICAgICAgICAgICAgICAgU3RhdGU6OkRvbmUgPT4ge30KICAgICAmbXV0ICpoZWFkZXIpOwoKICAgICAgICAgICAgICAgICAgICBpZiBoZWFkZXIudW53ciAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBmYWxzZQogICAgdXQgKmZvb3Rlcik7CgogICAgICAgICAgICAgICAgICAgIGlmIGZvb3Rlci51bndyaXRGb290ZXIoXykgfCBTdGF0ZTo6RG9uZSA9PiBwYW5pYyEoImVuY29kZSBhZnRlciBjb2VsZi5jcmMudXBkYXRlKCZpbnB1dC53cml0dGVuKClbcHJpb3Jfd3JpdHRlbi4uXSk7Yzo6d2l0aF9jYXBhY2l0eSg4KTsKCiAgICAgICAgb3V0cHV0LmV4dGVuZCgmc2VsZi5yZXNzaW9uKSAtPiBWZWM8dTg+IHsKICAgIGxldCBsZXZlbF9ieXRlID0gaWYgbGV2ZSBjcmF0ZTo6Y29kZWM6OkZsYXRlRW5jb2RlciwKICAgIGNyYzogQ3JjLAogICAgc3RhY3gsICZidWZbLi5zdGQ6OmNtcDo6bWluKGxpbWl0LCBidWYubGVuKCkpXSkKICAgIH0gZm4gbmV3KGlvOiBJbywgbGltaXQ6IHVzaXplKSAtPiBMaW1pdGVkPElvPiB7CiAgICArIFNlbmQ+Pj4+KCk7CiAgICAgICAgICAgICAgICBfYXNzZXJ0X3N5bmM6OjwkbmFtIH0KCiAgICAgICAgaW1wbDxSOiB0b2tpbzo6aW86OkFzeW5jQnVmUmVhZD4gdG9raW9zIHRoaXMgZGVjb2RlciByZXR1cm5pbmcgdGhlIHVuZGVybHlpbmcgcmVhZGVyLgogIG8gYXZvaWQgdGFtcGVyaW5nIHdpdGggdGhlIHN0YXRlIG9mIHRoZSByZWFkZXIgd2hpcmVzc2VkIG1lbWJlci9mcmFtZSBhbmQgZXhwZWN0IGVpdGhlciBFT0Ygb3IgYW5vdGhiZXIvZnJhbWUgZGVjb2RpbmcsIGlmIGVuYWJsZWQgdGhpcyB3aWxsIHJlc2V0IHRoZXJlYW0gYW5kIGVtaXQgYSBzdHJlYW0gb2YgdW5jb21wcmVzc2VkIGRhdGEuCiAgICAgZCBlbmNvZGVyOwoKcHViKGNyYXRlKSB1c2Ugc2VsZjo6e2RlY29kZXI6Olh6RGVjb2QmW10sIG91dHB1dC51bndyaXR0ZW5fbXV0KCksIEFjdGlvbjo6RmluaXNoKT87CgogICA9PiBwYW5pYyEoIlVuZXhwZWN0ZWQgbHptYSBpbnRlZ3JpdHkgY2hlY2siKSwKICAgS2luZDo6T3RoZXIsCiAgICAgICAgICAgICAgICAib3V0IG9mIG1lbW9yeSIsCiAgICByZXZpb3VzX2luID0gc2VsZi5zdHJlYW0udG90YWxfaW4oKSBhcyB1c2l6ZTsKICAgIGV3X2Vhc3lfZW5jb2RlcihsZXZlbCwgQ2hlY2s6OkNyYzY0KS51bndyYXAoKSwKICAgZXN1bHQ7CnVzZSB4ejI6OnN0cmVhbTo6e0FjdGlvbiwgQ2hlY2ssIEx6bWFPcHRpb25lbl9mcm9tKGlucHV0KTsKCiAgICAgICAgICAgICAgICAgICAgaWYgZGF0YS51bndyaSAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5hZHZhbmNlKGxlbiArIDEpOwogICAgICAgICB9CgogICAgICAgICAgICAgICAgU3RhdGU6OkNvbW1lbnQoZGF0YSkgPT4gewogU29tZShsZW4pID0gbWVtY2hyOjptZW1jaHIoMCwgaW5wdXQudW53cml0dGVuKCkpIHJhKHZlYyFbMDsgdXNpemU6OmZyb20obGVuKV0uaW50bygpKTsKICAgICAgICAgICAgICAgIGxldCBsZW4gPSB1MTY6OmZyb21fbGVfYnl0ZXMoZGF0YS50YSAgIHNlbGYuaGVhZGVyID0gSGVhZGVyOjpwYXJzZSgmZGF0YS50YWtlKCkuaW50b19pIGZsYWcgPSBpbnB1dFszXTsKCiAgICAgICAgbGV0IGZsYWdzID0gRmxhZ3MgewogICBCdWZmZXI8VmVjPHU4Pj4pLAogICAgRmlsZW5hbWUoVmVjPHU4PiksCiAgICBDb21tZWVmYXVsdCldCnB1YihzdXBlcikgc3RydWN0IEhlYWRlciB7CiAgICBmbGFnczogRmxheDogJm11dCBDb250ZXh0PCdfPiwKICAgICAgICBidWY6ICZtdXQgW3U4XSwKICAgICkgICAgICAgfTsKCiAgICAgICAgICAgIGlmIGxldCBTdGF0ZTo6RG9uZSA9ICp0aGlzLiAgICAgICAgIGxldCBtdXQgaW5wdXQgPSBQYXJ0aWFsQnVmZmVyOjpuZXcoaW5wdXQpCiAgICBwdWIgZm4gaW50b19pbm5lcihzZWxmKSAtPiBSIHsKICAgICAgICBzZWxmLnJbcGluXQogICAgICAgIHJlYWRlcjogUiwKICAgICAgICBlbmNvZGVyOiBFLAogICAgIDo6UmVhZHkoT2soKCkpKQogICAgfQoKICAgIGZuIHBvbGxfc2h1dGRvd24obXV0IHNlb250ZXh0PCdfPiwgYnVmOiAmW3U4XSkgLT4gUG9jV3JpdGUgZm9yIEVuY29kZXI8VywgRT4gewogICAgZm4gcG9sbF93cml0ZShzZWxmOiAgICAgICAgICAgIFN0YXRlOjpFbmNvZGluZyB8IFN0YXRlOjpGaW5pc2hpbmcgPT4gZTo6RW5jb2RpbmcgPT4gdGhpcy5lbmNvZGVyLmZsdXNoKCZtdXQgb3V0cHV0KT8sCgpTdGF0ZTo6RG9uZSA9PiBwYW5pYyEoIldyaXRlIGFmdGVyIHNodXRkb3duIiksCiAgIHh0PCdfPiwKICAgICAgICBpbnB1dDogJm11dCBQYXJ0aWFsQnVmZmVyPCZbdThdPiwKYXRlIHsKICAgIEVuY29kaW5nLAogICAgRmluaXNoaW5nLAogICAgRG9uZSwKfQoKcGkiZGVjb21wcmVzcyIsICYiPG5vIGRlYnVnPiIpCiAgICAgICAgICAgIC5maW5pc2goKT8gewogICAgICAgICAgICBCcm90bGlSZXN1bHQ6OlJlc3VsdFN1Y2Nlc3MgPT4gT2soc2VsZi5kZWNvZGUoJm11dCBQYXJ0aWFsQnVmZmVyOjpuZXcoJltdWy4uXSksIG91dHBzZWxmKSAtPiBSZXN1bHQ8KCk+IHsKICAgICAgICBzZWxmLnN0YXRlID0gQm94OjpuZWFkdmFuY2UoaW5wdXRfbGVuKTsKICAgICAgICBvdXRwdXQuYWR2YW5jZShvdXRwdXRfIC0+IFJlc3VsdDxCcm90bGlSZXN1bHQ+IHsKICAgICAgICBsZXQgaW5fYnVmID0gaW5Cb3g6Om5ldyhCcm90bGlTdGF0ZTo6bmV3KAogICAgICAgICAgICAgICAgU3RhbmRhci8vIElmIHNldCB0byAwLCB6c3RkIHNlbGVjdHMgYSBqb2Igc2l6ZSBiYXNlZCBvbiBjIGZlYXR1cmUgZ3VhcmRlZCBmbiBvbiBuZXh0IGJyZWFraW5nIHJlbGVhc2UKICAgICAgIH0KCiAgICAgICAgLy8vIE51bWJlciBvZiB0aHJlYWRzIHRvIHNwYXduLgogICAgICAgIC8vLyBFbWl0IHRoZSBzaXplIG9mIHRoZSBjb250ZW50IChkZWZhdWx0OiB0cnVlIC8vLyBUaGlzIGluY3JlYXNlcyB0aGUgZGVmYXVsdCB3aW5kb3cgc2l6ZS4KICAgICAgICAgLy8vIE1pbmltdW0gc2l6ZSBvZiBtYXRjaGVzIHNlYXJjaGVkIGZvcgogICAgIGYgdGhlIGluaXRpYWwgcHJvYmUgdGFibGUgaW4gNC1ieXRlIGVudHJpZXMgKGFzIGEgICAvLy8gdHlwZSwgdG8gYWJzdHJhY3Qgb3ZlciBkaWZmZXJlbnQgdmVyc2lvbnMgb2ZzcGVjaWZpYyB0eXBlcyBmb3IgYXN5bmMtY29tcHJlc3Npb24uCnB1YiBtb2QgenN0ZCAgICAgLnRyeV9pbnRvKCkKICAgICAgICAgICAgICAgICAgICAudW53cmFwX29yKDApICAgICAgICAgLmNsYW1wKGZhc3Rlc3QubGV2ZWwoKSwgYmVzdC5sZXZlbCgpKSwKICBhdHVyZSA9ICJiemlwMiIpXQogICAgZm4gaW50b19iemlwMihzZWxmKSAtPiBiemlwMmlzZShxdWFsaXR5KSA9PiBwYXJhbXMucXVhbGl0eSA9IHF1YWxpdHkuY2xhbXAoMCwgbGl0eSBvZiBjb21wcmVzc2lvbiwgdXN1YWxseSBwcm9kdWNlcyBiaWdnZXIgc2l6ZS4gImJ6aXAyIiwgZmVhdHVyZSA9ICJmbGF0ZTIiLCBmZWF0dXJlID0gInh6MiIpKV0KdXJgIgopXQovLyEKCiMhW2NmZ19hdHRyKGRvY3NycywgZmVhdHVyZShkb2NfYXV0b19jICAgZmVhdHVyZSA9ICJsem1hIiwKICAgIGRvYyA9ICJgbHptYWAgfCBbYEx6bWFFbmN1cmUgPSAiZ3ppcCIpLAogICAgZG9jID0gImBnemlwYCAoKmluYWN0aXZlKikgfCBgRz1Ccm90bGlFbmNvZGVyKSwgW2BCcm90bGlEZWNvZGVyYF0oP3NlYXJjaD1Ccm90bGlEc3VwcG9ydCwgdGhlcmUgYXJlIGN1cnJlbnRseSBhIGZldwovLyEgYXZhaWxhYmxlIGMgICBkb2MgPSAiW2BmdXR1cmVzLWlvYF0oY3JhdGU6OmZ1dHVyZXMpIHwgW2BmdXR1cm50YXRpb24KLy8hCi8vISBUaGUgZmlyc3QgZGl2aXNpb24gaXMgd2hpY2ggdW5kZXJsOgovLyEKCi8vISAgRmVhdHVyZSB8IERvZXMKLy8hIC0tLS0tLS0tLXwtLS0tLS0KLy9uZmlsbGVkKCkpOwogICAgICAgIG1hdGNoIHNlbGYuZG9fcG9sbF9yZWFkKGN4LCAmbSZtdXQgQ29udGV4dDwnXz4sCiAgICAgICAgYnVmOiAmbXV0IFJlYWRCdWY8J18+LAogICAgICAgU3RhdGU6Ok5leHQKICAgICAgICAgICAgICAgICAgIHRoaXMucmVhZGVyLmFzX211dCgpLmNvbnN1bWUobGVuKTtyZXR1cm5lZCBFT0YuCiAgICAgICAgICAgICAgICAgICAgICAgICp0aGlzLm11bHRpcG9sKSB7CiAgICAgICAgc2VsZi5tdWx0aXBsZV9tZW1iZXJzID0gZW5hYmxlZDsKICAgZXRfbXV0KCZtdXQgc2VsZikgLT4gJm11dCBSIHsKICAgICAgICAmbXV0IHNlbGYucmUgIGRlY29kZXI6IEQsCiAgICAgICAgc3RhdGU6IFN0YXRlLAogICAgICAgIG11bHRpcGVzdWx0IHsKICAgICAgICBmLmRlYnVnX3N0cnVjdCgiQnJvdGxpRW5jb2RlciIpCiAgdGxpRW5jb2Rlck9wZXJhdGlvbjo6QlJPVExJX09QRVJBVElPTl9GTFVTSCwKICAgICBfLCBffCAoKSwKICAgICAgICApIDw9IDAKICAgICAgICB7CiAgICAgICAgICAgJm11dCBpbl9idWYubGVuKCksCiAgICAgICAgICAgIGluX2J1ZiwKICAgIFN0YW5kYXJkQWxsb2M6OmRlZmF1bHQoKSk7CiAgICAgICAgc3RhdGUucGFyYW1zID0gRW5jb2RlckNyZWF0ZUluc3RhbmNlLCBCcm90bGlFbmNvZGVySGFzTW9yZU91dHB1dCwgY3JhdGU6OmNvZGVjOjpYekVuY29kZXI6Om5ldyhsZXZlbC5pbnRvX3h6MigpKSwKID8sCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgLy8vIERpY3Rpb25hcmllcyBwcm92aWRlIGJldHRlciBjb21wcmVzc2lvbiByYXR3X3dpdGhfZGljdChsZXZlbC5pbnRvX3pzdGQoKSwgZGljdGlvbmFyeSk/LAogICAgIG4gcmF0aW9zIGZvciBzbWFsbCBmaWxlcywgYnV0IGFyZSByZXF1aXJlZCB0bwogICAgYW5kIHByZS10cmFpbmVkCiAgICAgICAgICAgIC8vLyBkaWN0aW9uYXJ5LCB3aGljaCBldGVyOjpuYl93b3JrZXJzKClgXTogY3JhdGU6OnpzdGQ6OkNQYXJhbWV0ZXIKICAgIHNwZWNpZmllZCBjb21wcmVzc2lvbiBsZXZlbCBhbmQgcGFyYW1ldGVycywgd2hpY2gKICAgIGFsZ29zIShAYWxnbyB6c3RkIFsienN0ZCJdIFpzdGREZWNvZGVyIFpzdGRFbmNEZWNvZGVyIEd6aXBFbmNvZGVyIDwkaW5uZXI+CiAgICAgICAgeyBAZW5jCgogICAgIGhfcXVhbGl0eShpbm5lcjogJGlubmVyLCBsZXZlbDogY3JhdGU6OkxldmVsKSAtPiBTeyBAZGVjIH0KICAgICAgICApOwoKICAgICAgICBhbGdvcyEoQGFsZ28gYnppcDIgWyJ0bGk6OmVuYzo6YmFja3dhcmRfcmVmZXJlbmNlczo6QnJvdGxpRW5jb2RlclBhcmFtcyAgICAgI1tkb2MgPSBjb25jYXQhKCJBICIsICRhbGdvX3MsICIgZW5jb2Rlciwgb3IgKCRlbmNvZGVyX21ldGhvZHM6dHQpKiB9CiAgICAgICAgeyBAZGVjICQoJGRlY29kZXJ1ZlJlYWRgXShmdXR1cmVzX2lvOjpBc3luY0J1ZlJlYWQpIHN0cmVhbXMsIGJvdGggZSAgICAgICAgICAgLy8gVGhlcmUgd2FzIGluc3VmZmljaWVudCBtZW1vcnkgaW4gdGggICAgICAgICAgU3RhdHVzOjpGaW5pc2hPayA9PiB1bnJlYWNoYWJsZSEoKSwKCiAgICAgICAgc2VsZi5kZWNvbXByZXNzID0gRGVjb21wcmVzczo6bmV3KGZhbHNlKTsKICAgICAgICAgICAgICAubWFwX2Vycih8ZXwgc3RkOjppbzo6RXJyb3I6Om5ldyhzdGQ6OmkgIkJ6RGVjb2RlciB7e3RvdGFsX2luOiB7fSwgdG90YWxfb3V0OiB7fX19IiwKICAgIDsKCnVzZSBiemlwMjo6e0RlY29tcHJlc3MsIFN0YXR1c307CgpwdWIgc3RydWN0IEJ6ICAgICAgICAgICAgdXNlIGNyYXRlOjp1dGlsOjp7X2Fzc2VydF9zZW5kLCBfYXNzZXJuY1dyaXRlPiB0b2tpbzo6aW86OkFzeW5jV3JpdGUgZm9yICRuYW1lPG8gYXZvaWQgbG9zaW5nIHJlc291cmNlcyB3aGVuIHRoaXMgaXMgY2FsbGVkLgogICAgIC0+ICZtdXQgVyB7CiAgICAgICAgICAgICAgICBzZWxmLmlubmVyLmdldF9tdXQoKQopCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vLyBBY3F1aXJlcyBhIG11dGFibCBXKSAtPiAkbmFtZTwkaW5uZXI+IHsKICAgICAgICAgICAgICAgICRuYW1lIHsKICAgdGU6OnBpbl9wcm9qZWN0ISB7CiAgICAgICAgICAgICQoI1skYXR0cl0pKgogICAgICAuYWR2YW5jZShzZWxmLnN0cmVhbS50b3RhbF9vdXQoKSBhcyB1c2l6ZSAtIHByZXZpbyAgICAgICAgICJNb3JlIG1lbW9yeSBuZWVkZWQiLAogICAgICAgICAgICApKSwKICAgdGF0dXM6OkdldENoZWNrID0+IHBhbmljISgiVW5leHBlY3RlZCBsem1hIGludGVncmkgICAgICAgc3RyZWFtOiBTdHJlYW06Om5ld19hdXRvX2RlY29kZXIodTY0OjptYXhfdmUgc3RkOjpmbXQ6OntEZWJ1ZywgRm9ybWF0dGVyLCBSZXN1bHQgYXMgRm10UmVzdWx0aW47CiAgICAgICAgICAgICAgICB1c2UgdG9raW86OmlvOjpBc3luY1dyaXRlOwoKICAmbXV0IFNlbGY+LAogICAgICAgICAgICAgICAgY3g6ICZtdXQgc3RkOjp0YXNrOjpDb3RlIG9mIHRoaXMgZW5jb2Rlciwgc28gY2FyZSBzaG91bGQgYmUgdGFrZW4KICAgICAgIGF2b2lkIHRhbXBlcmluZyB3aXRoIHRoZSBzdGF0ZSBvZiB0aGUgd3JpdGVyIHdoaWMgdGhlIHVuZGVybHlpbmcgd3JpdGVyIHRoYXQgdGhpcyBlbmNvZGVyIGlzIHdyYXBwaSB3cml0ZSBpdAogICAgICAgICAgICAgICAgLy8vIGNvbXByZXNzZWQgdG8gdGhlIGdpICAvLy8gdGFrZSBpbiB1bmNvbXByZXNzZWQgZGF0YSBhbmQgd3JpdGUgaXQgY29tcHJsX3NodXRkb3duKGN4KTsKICAgICAgICAgICAgaWYgbmV4dC5pc19yZWFkeSgpIHsKICAgICAgY3gud2FrZXIoKS53YWtlX2J5X3JlZigpOwogICBkZWQgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBuZXh0CiAgICAgIGZSZWFkICsgU3luYz4+Pj4oKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9cnRfc3luY307CiAgICAgICAgICAgICAgICB1c2UgY29yZTo6cGluOjpQaW47CiAgICBvdGUgdGhhdCB0aGlzIG1heSBkaXNjYXJkIGludGVybmFsIHN0YXRlIG9mIHRoaXMgZHBpbjo6UGluPCZtdXQgU2VsZj4pIC0+IHN0ZDo6cGluOjpQaW48Jm11dCBSPiB7CiAgICAgICAgIC8vLyBtYXkgb3RoZXJ3aXNlIGNvbmZ1c2UgdGhpcyBkZWNvZGVyLgogICAgICAgICAgICAgICAkKCQoJGluaGVyZW50X21ldGhvZHMpKikqCgogICAgIGVhbSBhbmQKICAgICAgICAgICAgLy8vIGVtaXQgYSB1bmNvbXByZXNzZWQgc3RyZWFtZWNvZGVyIHsKICAgICgkKCNbJGF0dHI6bWV0YV0pKiAkbmFtZTppZGVudDwkaW5uZXI+LAogICAgKSAtPiBSZXN1bHQ8KCk+IHsKICAgICAgICBzZWxmLmlubmVyLmVuY29kZWUgc3RkOjppbzo6UmVzdWx0OwoKdXNlIGZsYXRlMjo6Q29tcHJlc3Npb247CgojW2RlZWFkeSEoUGluOjpuZXcoJm11dCB0aGlzLndyaXRlcikucG9sbF9mbHVzaChjeCkpPzsgVz4gRnV0dXJlIGZvciBDb3B5QnVmPCdfLCBSLCBXPgp3aGVyZQogICAgUjogQXN5bigpKSkgPT4gewogICAgICAgICAgICAgICAgc2VsZi5jbG9zZWQgPSB0cnVlOwogICAgY1dyaXRlICsgVW5waW4+IHRva2lvOjppbzo6QXN5bmNXcml0ZSBmb3IgVHJhY2tDbG91dCBzZWxmLmlubmVyKS5wb2xsX3dyaXRlX3ZlY3RvcmVkKGN4LCBidWZzKQogICAgfVJlc3VsdDx1c2l6ZT4+IHsKICAgICAgICBhc3NlcnQhKCFzZWxmLmNsb3NlZCk7CiAgIGFsbG93KHVudXNlZCkpXQp1c2Ugc3RkOjp7CiAgICBpbzo6UmVzdWx0LAogICAgcGkgICAgICAiQXR0ZW1wdCB0byBzaHV0ZG93biBiZWZvcmUgZmluaXNoaW5nIGlucHV0IiAgXyA9PiBQb2xsOjpSZWFkeShPayhpbnB1dC53cml0dGVuKCkubGVuKCkpKSwKICAgCiAgICAgICAgbWF0Y2ggc2VsZi5kb19wb2xsX3dyaXRlKGN4LCAmbXV0IGlucHV0KT8gICAgICAgIH07CgogICAgICAgICAgICAqdGhpcy5zdGF0ZSA9IHN0YXRlOwoKICAgIG5ldyhvdXRwdXQpOwoKICAgICAgICAgICAgbGV0IChzdGF0ZSwgZG9uZSkgPSBtYXRjICAgICAgICAgICAgICBTdGF0ZTo6RG9uZSA9PiBwYW5pYyEoIldyaXRlIGFmdGVyIGUgICAgICAgICAgICAgaWYgdGhpcy5kZWNvZGVyLmRlY29kZShpbnB1dCwgJm11dCBvdWY+KSAtPiBQaW48Jm11dCBXPiB7CiAgICAgICAgc2VsZi5wcm9qZWN0KCkud3JpdGVyKCZzZWxmKSAtPiAmVyB7CiAgICAgICAgc2VsZi53cml0ZXIuZ2V0X3JlZigpCiAgICBzdWx0fTsKCnVzZSBjcmF0ZTo6ewogICAgY29kZWM6OkRlY29kZSwKICAgIHRva2lvOmVzLWlvIildCmZuIGJ1ZnJlYWRfbXVsdGlwbGVfbWVtYmVyc193aXRoX2ludmFsaWRfLAogICAgICAgIHZlYyFbMCwgMCwgMCwgMF0sCiAgICBdCiAgICAuam9pbigmW11bLi5yaXRlciwKICAgIGdlbmVyaWM6OntEZWNvZGVyLCBFbmNvZGVyfSwKfTsKCmFsZ29zIS8hIFR5cGVzIHdoaWNoIG9wZXJhdGUgb3ZlciBbYEFzeW5jV3JpdGVgXSh0b2tpbzo6dWZmZXIgdGhhdCBgYW10YCBieXRlcyBoYXZlIGJlZW4gd3JpdHRlbiB0byBpdHMgYnVsbCBhbmQgY2Fubm90IGJlIGZsdXNoZWQsIHRoZSBtZXRob2QgcmV0dXJucyBgUG9sbEJ1ZlJlYWQsIEQ6IERlY29kZT4gQXN5bmNSZWFkIGZvciBEZWNvZGVyPFIsIEQ+IHsKaWxsX2J1ZihjeCkpPzsKICAgICAgICAgICAgICAgICAgICBpZiBpbnB1dC5pc19lbXBvbmUgPT4gU3RhdGU6OkRvbmUsCgogICAgICAgICAgICAgICAgU3RhdGU6Ok5leHQgPSAgICAgICAgbGV0IGRvbmUgPSB0aGlzLmRlY29kZXIuZGVjb2RlKCZtdXQgaW5wdXQsdGVtcHRpbmcgdG8gcmVpbml0aWFsaXNlIHRoZSBkZWNvZGVyIGlmIHRoZSByZWFkZXIgZm4gbXVsdGlwbGVfbWVtYmVycygmbXV0IHNlbGYsIGVuYWJsZWQ6IGJvb2wpIHsKIF9tZW1iZXJzOiBib29sLAogICAgfQp9CgppbXBsPFI6IEFzeW5jQnVmUmVhZCwgRDogCiAgICBEb25lLAogICAgTmV4dCwKfQoKcGluX3Byb2plY3QhIHsKICAgICNbZGVyaXZhIG5ldyBtZW1iZXIvZnJhbWUgb2YgZGF0YS4KICAgIGZuICAgLy8vIFJldHVybnMgd2hldGhlciB0aGUgaW50ZXJuYWwgYnVmZmVycyBhcmUgZmxFbmNvZGVyLCBYejJGaWxlRm9ybWF0fTsKI1tjZmcoZmVhdHVyZSA9ICJ6bGliIildCmVyLCBCekVuY29kZXJ9OwojW2NmZyhmZWF0dXJlID0gImRlZmxhdGUiKV0KcHViKGNycmUgPSAiYnJvdGxpIildCm1vZCBicm90bGk7CiNbY2ZnKGZlYXR1cmUgPSAiYnppcDJlbmNvZGVycyBhbmQKLy8hIGRlY29kZXJzIGZvciB2YXJpb3VzIGZvcm1hdHMuCgojWyAgICAgICAmZm9ybWF0X2FyZ3MhKCJ7fS97fSIsIHNlbGYuYnVmZmVyZWQsIHNlbGYuYW10OwogICAgfQp9CgppbXBsPFc6IGZtdDo6RGVidWc+IGZtdDo6RGVidWcgZm9yIEJ1ZldyaXRlcjxXPiB7CiAgICBmbiBwb2xsX3BhcnRpYWxfZmx1c2hfYnVmKAogICAgIGZmZXJlZCAhPSAwYCBpcyBpZiBpdCB3ZXJlIFBlbmRpbmcsIHNvIG91ciB3YWtlciB3ICApIC0+IFBvbGw8aW86OlJlc3VsdDx1c2l6ZT4+IHsKICAgICAgICBsZXQgdGhpcyAgdGhhdCBhbnkgbGVmdG92ZXIgZGF0YSBpbiB0aGUgaW50ZXJuYWwgYnVmZmVyIGlzIAogICAgLy8vIEl0IGlzIGluYWR2aXNhYmxlIHRvIGRpcmVjdGx5IHdyaXRlIHRvIHRoICAgICAgICAgICAgICAgIE9rKG4pID0+ICp0aGlzLndyaXR0ZW4gKz0gbiwKICAgICB0aGlzLndyaXR0ZW47CiAgICAgICAgICAgICp0aGlzLndyaXR0ZW4gPSAwOwoKICAgICAgICAgICAgICAgICAgICAgICBpbzo6RXJyb3JLaW5kOjpXcml0ZVplcm8sCiAgICAgYWR5KE9rKDApKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gRXJyKGlvOjphbmdlIGluIHRoZSBmdXR1cmUuCiAgICBwdWIgZm4gbmV3KGlubmVyOiBXKSAtPiBTZUZBVUxUX0JVRl9TSVpFOiB1c2l6ZSA9IDgxOTI7CgpwaW5fcHJvamVjdCEgewogICAgZ2luYWxseSBzb3VyY2VkIGZyb20gYGZ1dHVyZXNfdXRpbDo6aW86OmJ1Zl93cml0ZXIgICAgICAgICAgICAgICAgICAgYXNzZXJ0X2VxIShvdXRwdXQsIGJ5dGVzKTsKICAgICAgICAgbGV0IGNvbXByZXNzZWQgPSBzeW5jOjpjb21wcmVzcygmYnl0ZXMpOwoKICAgcHV0ID0gSW5wdXRTdHJlYW06OmZyb20oY29tcHJlc3NlZC5jaHVua3MoMikpOwogICAgIGxldCBvdXRwdXQgPSB3cml0ZTo6ZGVjb20gICAgICAgICAgICAgICAgICBhc3NlcnRfZXEhKG91dHB1dCwgJltdWy4uXSk7CiAgICAgICAgICBhbGdvczo6JHZhcmlhbnQ6OntzeW5jLCAkaW1wbDo6d3JpdGV9LAogICAgICAgICAgICAgICAgICBMZXZlbDo6UHJlY2lzZShpMzI6Om1heF92YWx1ZSgpKSwKICAgICAgICAgICAgICAgICBvbmVfdG9fc2l4X3N0cmVhbSgpLmFzX3JlZigpLAogICAgICAgICAgICAgIDY1XzUzNiwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgfGlucHV0fCBCb3g6OnBpbih3cml0ZTo6RW5jdGVzdF0KICAgICAgICAgICAgICAgICAgICBmbiB3aXRoX2xldmVsX2Jlc3QoKSB7CiA6dGltZW91dCgxMDAwKV0KICAgICAgICAgICAgICAgICAgICBmbiBsb25nX2NodW5rX2VjIVsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgwLi4zMl83NjgpLm1hcCh8KV0KICAgICAgICAgICAgICAgICAgICBmbiBzaG9ydF9jaHVua19vdXRwdXQoKSB7CiAgICAgICAgICAgICAgYXNzZXJ0X2VxIShvdXRwdXQsIGlucHV0LmJ5dGVzKCkpOwogIHNzZWQgPSB3cml0ZTo6Y29tcHJlc3MoaW5wdXQuYXNfcmVmKCksIDY1XzUzNik7CiAgICAgIGxldCBtdXQgZGVjb2RlciA9IGJ1ZnJlYWQ6OkRlY29kZXI6Om5ldyhidWZyZWEgICAgICAgICAgc3luYzo6Y29tcHJlc3MoJls2LCA1LCA0LCAzLCAyLCAxXSksCiAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGJ5dGVzOiBWZWM8dTg+ID0gKDAuPiA9ICgwLi42NV81MzYpLm1hcCh8X3wgcmFuZDo6cmFuZG9tKCkpLmNvbGxlY3QoKTsmaW5wdXQpOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgb3V0cHV0ID0gYnVmcj0gYnVmcmVhZDo6ZGVjb21wcmVzcyhidWZyZWFkOjpmcm9tKCZpbnB1dCkpOwoKICAgcHJlc3NlZCA9IHN5bmM6OmNvbXByZXNzKCZbMSwgMiwgMywgNCwgNSwgNl0pOwoKICAgICAgbGV0IGNvbXByZXNzZWQgPSBzeW5jOjpjb21wcmVzcygmWzA7IDEwXSk7CgogIGV0IGlucHV0ID0gSW5wdXRTdHJlYW06Om5ldyh2ZWMhW2NvbXByZXNzZWRdKTsKICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgb25lX3RvX3NpeCwgb25lX3QgICAgICAgICAgIGJ1ZnJlYWQ6OmZyb20oJm9uZV90b19zaXhfc3RyZWFtKCkpLAogICAgIGxldCBlbmNvZGVyID0gYnVmcmVhZDo6RW5jb2Rlcjo6d2l0aF9xdWFsaXR5KAogICAgICAgICAgbGV0IGNvbXByZXNzZWQgPSByZWFkOjp0b192ZWMoZW5jb2Rlcik7CiAgICAgbGV0IG91dHB1dCA9IHN5bmM6OmRlY29tcHJlc3MoJmNvbXByZXNzZWQpOwoKICAgICAgICAgICAgICAgYXNzZXJ0X2VxIShvdXRwdXQsIG9uZV90b19zaXgoKSk7CiAgICBsZXQgY29tcHJlc3NlZCA9IGJ1ZnJlYWQ6OmNvbXByZXNzKGJ1ZnJlYWQ6OmZyb21pbWVvdXQoMTAwMCldCiAgICAgICAgICAgICAgICAgICAgZm4gZW1wdHlfY2h1bmsoKSAgICAgI1t0ZXN0XQogICAgICAgICAgICAgICAgICAgICNbbnRlc3Q6OnRpbWVvdXQoZXIsIGVuY29kZXI6OkZsYXRlRW5jb2Rlcn07Cm1hY3JvX3J1bGVzISBpb190ZXN0X2MgaW50ZXJsZWF2ZV9wZW5kaW5nOjpJbnRlcmxlYXZlUGVuZGluZzxTZWxmPgogICAgdzsKCnB1YiBmbiBvbmVfdG9fc2l4X3N0cmVhbSgpIC0+IElucHV0U3RyZWFtIHsKICAgZCBpbnB1dF9zdHJlYW07CiNbY2ZnKGZlYXR1cmUgPSAidG9raW8iKV0KbW9kIHRva2lmIGxldCBTdGF0ZTo6RG9uZSA9IHNlbGYuYXNfbXV0KCkucHJvamVjdCgpLnN0YXRlIFBvbGw6OlBlbmRpbmcgaWYgaW5wdXQud3JpdHRlbigpLmlzX2VtcHR5KCkgPT4gUG9sICAgICAgICAgICAgICAgICAgICAoU3RhdGU6OkZpbmlzaGluZywgZmFsc2UpCiAgICAKICAgICAgICAgICAgICAgICAgICAoU3RhdGU6OkRlY29kaW5nLCBkb25lKQogICAgIGFmdGVyIGVuZCBvZiBzdHJlYW0iKSwKICAgIHRwdXQpPyB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlOjpEb25lCiAgICAgICAgIHNlbGYud3JpdGVyLmludG9faW5uZXIoKQogICAgfQoKICAgIGZuIGRvX3BvbGxlcjxXLCBEPiB7CiAgICBwdWIgZm4gbmV3KHdyaXRlcjogVywgZGVjb2RlcjogRCkgLURlYnVnKV0KICAgIHB1YiBzdHJ1Y3QgRGVjb2RlcjxXLCBEOiBEZWNvZGU+IHsKICAgPzsKICAgIE9rKGVuY29kZXIuaW50b19pbm5lcigpKQp9Cgphc3luYyBmbiBkZWNvbXBtcHJlc3MoJmNvbXByZXNzZWRfZGF0YSkuYXdhaXQ/OwogICAgYXNzZXJ0X2VxIShkZWxlbl0pOwoKICAgICAgICBzZWxmLmFkdmFuY2UobGVuKTsKICAgICAgICBvdGhlci5hLT4gQiB7CiAgICAgICAgc2VsZi5idWZmZXIKICAgIH0KfQoKaW1wbDxCOiBBc1JlZjw+ICZbdThdIHsKICAgICAgICAmc2VsZi5idWZmZXIuYXNfcmVmKClbc2VsZi5pbmRleHNzZXJ0X3N5bmM8VDogU3luYz4oKSB7fQoKI1tkZXJpdmUoRGVidWcsIERlZmF1bHQpcHJlc3M6Ok5vbmUsCiAgICAgICAgICAgICk/OwogICAgICAgICAgICBpZiBvdXRwdXQ+IE9rKHRydWUpLAogICAgICAgICAgICBTdGF0dXM6OkJ1ZkVycm9yID0+IEVycihFciAgICAgc2VsZi5kZWNvbXByZXNzLnJlc2V0KHNlbGYuemxpYl9oZWFkZXIpOwogICAgICAgICAgZGVjb21wcmVzczogRGVjb21wcmVzczo6bmV3KHpsaWJfaGVhZGVyKSwKICBkLCBSZXN1bHR9OwoKdXNlIGZsYXRlMjo6e0RlY29tcHJlc3MsIEZsdXNoRGVjb21wcmVyIikKICAgICAgICAgICAgLmZpZWxkKCJ3cml0ZXIiLCAmc2VsZi5pbm5lcikKICAgPFc6IEFzeW5jV3JpdGU+IEFzeW5jQnVmV3JpdGUgZm9yIEJ1ZldyaXRlcjxXPiB7CiBPayhsZW4pKQogICAgICAgIH0KICAgIH0KCiAgICBmbiBwb2xsX2ZsdXNoKG11dCBzZXVmZmVyZWQgKyBidWYubGVuKCkgPiB0aGlzLmJ1Zi5sZW4oKSB7CiAgZXIKICAgIH0KCiAgICAvLy8gQ29uc3VtZXMgdGhpcyBgQnVmV3JpdGVyYCwgcmV0dXJldF9waW5fbXV0KHNlbGY6IFBpbjwmbXV0IFNlbGY+KSAtPiBQaW48Jm11dCBXPiB7CiAgICAgICAgICJmYWlsZWQgdG8gd3JpdGUgdGhlIGJ1ZmZlcmVkIGRhdGEiLAogICAgdGhpcwogICAgICAgICAgICAgICAgLmlubmVyCiAgICAgICAgICAgICAgICAuYXNfbXU6UmVhZHkocmV0KQogICAgICAgIH0gZWxzZSBpZiAqdGhpcy5idWZmZXJlZCA9PSAwIGUoY3gsICZ0aGlzLmJ1ZlsqdGhpcy53cml0dGVuLi4qdGhpcy5idWZmZXJlZF0pCiAgOwogICAgICAgIHdoaWxlICp0aGlzLndyaXR0ZW4gPCAqdGhpcy5idWZmZXJlZCB7CiA8W3U4XT4sCiAgICAgICAgd3JpdHRlbjogdXNpemUsCiAgICAgICAgYnVmZmVyZWQ6IGNvcmU6OnJlYWR5Owp1c2UgcGluX3Byb2plY3RfbGl0ZTo6cGluX3Byb2plY3Q7CnVzbGw6OlJlYWR5KE9rKCgpKSkKICAgIH0KCiAgICBmbiBwb2xsX2Nsb3NlKG11dCBzZWxhbEJ1ZmZlcjo6bmV3KGJ1Zik7CgogICAgICAgIG1hdGNoIHNlbGYuZG9fcG9sbF93ciB7CiAgICAgICAgICAgICAgICAgICAgaWYgdGhpcy5lbmNvZGVyLmZpbmlzaCgmbXV0ICAgIH07CgogICAgICAgICAgICBsZXQgcHJvZHVjZWQgPSBvdXRwKSAtPiBQb2xsPFJlc3VsdDwoKT4+IHsKICAgICAgICBsZXQgbXV0IHRoaXMgPSBzZWwgICAgICB0aGlzLndyaXRlci5hc19tdXQoKS5wcm9kdWNlKHByb2R1Y2VkKTsKCiAgICAgICBsZXQgbXV0IG91dHB1dCA9IFBhcnRpYWxCdWZmZXI6Om5ldyhvdXRwdXQpOwoKdGVyOiBCdWZXcml0ZXI6Om5ldyh3cml0ZXIpLAogICAgICAgICAgICBlbmNvZGVyLApyZXM6OndyaXRlOjp7QXN5bmNCdWZXcml0ZSwgQnVmV3JpdGVyfSwKICAgIHV0aWw6OiBzb21lIGFtb3VudCBvZiBpdHMgYnVmZmVyLCByZXR1cm5lZCBmcm9tIGBwb2xsX2ZsICApIC0+IFBvbGw8aW86OlJlc3VsdDwmbXV0IFt1OF0+PjsKCiAgICAvLy8gVGVsbHN0ZXJuYWwgYnVmZmVyIHRvIHdyaXRlIHRvLCBmbHVzaGluZyBkYXRhIG91dCB0byB0aGJ5dGVzX2xlZnQgPSBzZWxmLmRlY29kZXIuZ2V0X211dCgpLmZsdXNoKCZtdXQgb3V0ICAgICAgICBvdXRwdXQuYWR2YW5jZShzdGF0dXMuYnl0ZXNfd3JpdHRlbik7CiAgICBsZi5kZWNvZGVyLmdldF9tdXQoKS5yZWluaXQoKT87CiAgICAgICAgT2soKCkpCiAgIHRydWN0IFpzdGREZWNvZGVyIHsKICAgIGRlY29kZXI6IFVuc2hhcmVkPERlY29kZXI8ZSB0byBoYXZlIGFscmVhZHkgZmx1c2hlZCBhbGwgdGhlIGRhdGEgb3V0IGJlZm9yZSAgICAgICAgdGhpcy5pbm5lci5kZWNvZGUoaW5wdXQsIG91dHB1dCkKICAgICAgICB9KS5pbm5lci5yZWluaXQoKT87CiAgICAgICAgc2VsZi5jcmMgPSBDcmM6Om5ldygpOwogICAgIGNoZWNrX2Zvb3Rlcigmc2VsZi5jcmMsIGZvb3Rlci53cml0dGVuKCkpPzsKICAgICAgICAgbGV0IGRvbmUgPSBpbm5lcihzZWxmLCBpbnB1dCwgb3V0cHV0KT87CiAgICAgICAgIGlmIGxldCBTb21lKGhlYWRlcikgPSBwYXJzZXIuaW5wdXQoaW5wdXQpPyB7dGF0ZTogU3RhdGU6OkhlYWRlcihoZWFkZXI6OlBhcnNlcjo6ZGVmYXVsdCgpKSwKICBpZCBnemlwIGZvb3RlciBsZW5ndGgiLAogICAgICAgICkpOwogICAgfQoKICAgIGxldEVuY29kZXJ9OwojW21hY3JvX3VzZV0KbW9kIHV0aWxzOwoKdGVzdF9jYXNlcyEoYnJvIG9uIExaTUEgMSBpcyBub3Qgc3VwcG9ydGVkCiAgICAgICAgT2sodHJ1ZSkKICAgIH1kOjppbzo6UmVzdWx0OwoKI1tkZXJpdmUoRGVidWcpXQpwdWIgc3RydWN0IEx6bWFFbiAgICAvLyB0aGUgcmVxdWVzdCwgYnV0IG90aGVyd2lzZSBldmVyeXRoaW5nIHdlbnQgICAgIC8vIERlY29tcHJlc3Npb24gd2VudCBmaW5lLCBub3RoaW5nIG11Y2ggdG8gcmUvLyBUaGUgc3RyZWFtJ3MgZW5kIGhhcyBiZWVuIG1ldCwgbWVhbmluZyB0aGF0IG5vIC8gVGhlIEZsdXNoIGFjdGlvbiBvbiBhIGNvbXByZXNzaW9uIHdlbnQgb2suCiAgICAgeSBpbiB0aGUgaW5wdXQgb3Igb3V0cHV0IGJ1ZmZlciB0byBjb21wbGV0ZQogICAgICB0byByZXBvcnQuCiAgICAgICAgICAgIFN0YXR1czo6T2sgPT4gT2soKCkpLAoKICAgICgpIC0gcHJpb3Jfb3V0KSBhcyB1c2l6ZSk7CgogICAgICAgIE9rKHN0YXR1cykKICAgZXN1bHQ8U3RhdHVzPiB7CiAgICAgICAgbGV0IHByaW9yX2luID0gc2VsZi5jb21wcmVlIGZhbGxiYWNrLiBZb3Ugc2hvdWxkIHNldAogICAgLy8vIHRoaXMgcGFyYW1ldGVyIG8gbWF0dGVyIGhvdyBiYWQgdGhlCiAgICAvLy8gaW5wdXQuCiAgICAvLy8KICAgIC8vLCBmOiAmbXV0IGZtdDo6Rm9ybWF0dGVyPCdfPikgLT4gZm10OjpSZXN1bHQgewogICBuZXcoRXJyb3JLaW5kOjpPdGhlciwgInVuZXhwZWN0ZWQgQnVmRXJyb3IiKSksCiAgICgpLmxlbigpID09IG9sZF9sZW4gewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgRmx1c2hDb21wcmVzczo6U3luYywKICAgICAgICApPzsKCiAgICBoIHNlbGYuZW5jb2RlKGlucHV0LCBvdXRwdXQsIEZsdXNoQ29tcHJlc3M6Ok5vbmUpP2VzcwogICAgICAgICAgICAuY29tcHJlc3MoaW5wdXQudW53cml0dGVuKCksIG91dHB1ewogICAgY29tcHJlc3M6IENvbXByZXNzLAogICAgZmx1c2hlZDogYm9vbCwKfQoKaW1lYzo6RW5jb2RlLCB1dGlsOjpQYXJ0aWFsQnVmZmVyfTsKdXNlIHN0ZDo6aW86OntFcmUgZm9yIEx6bWFEZWNvZGVyIHsKICAgIGZuIHJlaW5pdCgmbXV0IHNlbGYpIC0+IFJlb29sPiB7CiAgICAgICAgaWYgc2VsZi5za2lwX3BhZGRpbmcuaXNfc29tZSgpIHsKICAKICAgICAgICAgICAgICAgICAgICBFcnJvcktpbmQ6OkludmFsaWREYXRhLAogICAgICpjb3VudCAtPSAxOwogICAgICAgICAgICAgICAgaWYgKmNvdW50ID09IDAgewogICAgY29kZWM6Olh6MkRlY29kZXIsCiAgICBza2lwX3BhZGRpbmc6IE9wdGlvbjx1OD4sCn1zdWx0PGJvb2w+IHsKICAgICAgICBzZWxmLmlubmVyLmZsdXNoKG91dHB1dCkKICAgIHQoKS4wLmNvbnN1bWUoYW10KQogICAgfQp9CnVzZSBjcmF0ZTo6e2NvZGVjOjpFbmNvICAgICAgb3RoZXIgPT4gb3RoZXIsCiAgICAgICAgfQogICAgfQoKICAgIGZuIGNvbnN0ISghKmVvZik7CiAgICAgICAgbGV0IGxlbiA9IGJ1Zi5maWxsZWQoKS5sZW4oKTsKIGZuIGNvbnN1bWUoc2VsZjogUGluPCZtdXQgU2VsZj4sIGFtdDogdXNpemUpIHsKICAgLWlvIildCmltcGw8UjogZnV0dXJlczo6aW86OkFzeW5jQnVmUmVhZCArIFVucGluPiBpbm5lciwgZW9mKSA9IHNlbGYucHJvamVjdCgpOwogICAgICAgIGFzc2VydCEoISplb2x9LAp9OwoKcHViIHN0cnVjdCBUcmFja0VvZjxSPiB7CiAgICBpbm5lcjogUiwKICAgICAgICAgIGNvbnN0IF86ICgpID0gewogICAgICAgICAgICBmbiBfYXNzZXJ0KCkgewogaW50ZXJuYWwgc3RhdGUgb2YgdGhpcyBlbmNvZGVyLCBzbyBjYXJlIHNob3VsZCBiZSAgICAvLy8gQWNxdWlyZXMgYSBwaW5uZWQgbXV0YWJsZSByZWZlcmVkZXIgdGhhdCB0aGlzIGVuY29kZXIgaXMKICAgICAgICAgICAgLy8vIHdyYXBwaW5nLiAgIGlubmVyOiBjcmF0ZTo6ZnV0dXJlczo6YnVmcmVhZDo6RW5jb2RlcjwkaW5uZXIsYF0oZnV0dXJlc19pbzo6QXN5bmNSZWFkKSBpbnRlcmZhY2UgYW5kIHdpbGwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFN0YXRlOjpEb25lOwogICAgICAgICBvdXRwdXQuY29weV91bndyaXR0ZW5fZnJvbSgmbXV0ICpoZWFkZXIpOwoKICAgICAgIGlmIGRvbmUgewogICAgICAgICAgICAgICAgcmV0dXJuIE9rKHRydWUpOwogICB1dCk/LAoKICAgICAgICAgICAgICAgIFN0YXRlOjpGb290ZXIoZm9vdGVyKSA9PiB7CjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmbiBmbHVzaCgKICAgdGF0ZTo6RW5jb2RpbmcgPT4gewogICAgICAgICAgICAgICAgICAgIGxldCBwcmlvcl9zdWx0PCgpPiB7CiAgICAgICAgbG9vcCB7CiAgICAgICAgICAgIG1hdGNoICZtdXQgc0d6aXBFbmNvZGVyIHsKICAgIHB1YihjcmF0ZSkgZm4gbmV3KGxldmVsOiBDb21wcmVzLnBvbGxfc2h1dGRvd24oY3gpCiAgICB9Cn0KbW9kIGRlY29kZXI7Cm1vZCBlbmNvZGUgICAgICBQaW46Om5ldygmbXV0IHNlbGYuaW8pLnBvbGxfd3JpdGUoY3gsICZidWZbLm9yIExpbWl0ZWQ8Vz4gewogICAgZm4gcG9sbF93cml0ZSgKICAgICAgICBtdXQgc2VsICAgICAgICAgIF9hc3NlcnRfc2VuZDo6PCRuYW1lPFBpbjxCb3g8ZHluIEFzeW5jQnUgICAgLy8vIHRvIGF2b2lkIGxvc2luZyByZXNvdXJjZXMgd2hlbiB0aGlzIGlzIGNhbCAgIC8vLwogICAgICAgICAgICAvLy8gTm90ZSB0aGF0IGNhcmUgbXVzdCBiZSB0YWtlciB3aGljaAogICAgICAgICAgICAvLy8gbWF5IG90aGVyd2lzZSBjb25mdXNlIHRoaXMgICAgICAgICAgfQoKICAgICAgICAgICAgLy8vIEFjcXVpcmVzIGEgcmVmZXJlbmNlICAgLy8vIENyZWF0ZXMgYSBuZXcgZGVjb2RlciB3aGljaCB3aWxsIHJlYWQgY29tcHJlICAgLy8vIFRoaXMgc3RydWN0dXJlIGltcGxlbWVudHMgYW4gW2BBc3luY1JlYWRgXSgkaW5uZXI6aWRlbnQ+ICQoeyAkKCRpbmhlcmVudF9tZXRob2RzOnR0KSogfSkqKSA9PiAgICAgIGxldCBzdGF0dXMgPSBzZWxmCiAgICAgICAgICAgIC5zdHJlYW0KICAgICAgZSksCiAgICAgICAgICAgIFN0YXR1czo6U3RyZWFtRW5kID0+IE9rKHRydWUpLAogICAgICAgICAgICBTdGF0dXM6Ok1lbU5lZWRlZCA9PiBFcnIoc3RkOjppbzo6RXJyb3I6OmV0IHByZXZpb3VzX291dCA9IHNlbGYuc3RyZWFtLnRvdGFsX291dCgpIGFzIHVzaXplfQp9CgppbXBsIEVuY29kZSBmb3IgWHoyRW5jb2RlciB7CiAgICBmbiBlbmNvZGUoCiBuY29kZXIgewogICAgZm4gZm10KCZzZWxmLCBmOiAmbXV0IEZvcm1hdHRlcjwnXz4pIHVybiBPayhTb21lKHN0ZDo6bWVtOjp0YWtlKCZtdXQgc2VsZi5oZWFkZXIpKSk7CiAgICAgICBkYXRhLmV4dGVuZF9mcm9tX3NsaWNlKGlucHV0LnVud3JpdHRlbigpKTsKICAgICAgICAgICAgICAgIGlmICFzZWxmLmhlYWRlci5mbGFncy5jb21tZW50IHsKICAgIGV4dGVuZF9mcm9tX3NsaWNlKCZpbnB1dC51bndyaXR0ZW4oKVsuLmxlbl0pOwogICAgc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soTm9uZSk7CiAgICAgICAgICAgICAgICAgICBkYXRhLmNvcHlfdW53cml0dGVuX2Zyb20oaW5wdXQpOwoKICBzZWxmLnN0YXRlID0gU3RhdGU6OkV4dHJhTGVuKDxfPjo6ZGVmYXVsdCgpKTsKICAgICAgICAgICAgICBhc2NpaTogKGZsYWcgJiAwYjAwMDBfMDAwMSkgIT0gMCwKICAgICBCdWZmZXI8W3U4OyAyXT4pLAogICAgRG9uZSwKfQoKaW1wbCBEZWZhdWx0IGZvciBTdCAgICAgICBfID0+IFBvbGw6OlJlYWR5KE9rKG91dHB1dC53cml0dGVuKCkubGVuKCkpbGw8UmVzdWx0PHVzaXplPj4gewogICAgICAgIGlmIGJ1Zi5pc19lbXB0eSgpIHsKICBlOjpEb25lLAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaWYgbGV0IFN0YXRlOm9wIHsKICAgICAgICAgICAgKnRoaXMuc3RhdGUgPSBtYXRjaCB0aGlzLnN0YXRlIHsKKCZzZWxmKSAtPiAmUiB7CiAgICAgICAgJnNlbGYucmVhZGVyCiAgICB9CgogICAgcHVFbmNvZGVyPFIsIEU+IHsKICAgIHB1YiBmbiBuZXcocmVhZGVyOiBSLCBlbmNvZGVyOjpFbmNvZGUsIHV0aWw6OlBhcnRpYWxCdWZmZXJ9Owp1c2UgZnV0dXJlc19jb3JlOjpydWx0PCgpPj4gewogICAgICAgIHJlYWR5IShzZWxmLmFzX211dCgpLmRvX3BvbGxfZmx9CgppbXBsPFc6IEFzeW5jV3JpdGUsIEU6IEVuY29kZT4gQXN5bmNXcml0ZSBmb3IgRW9qZWN0KCk7CgogICAgICAgIGxvb3AgewogICAgICAgICAgICBsZXQgb3V0cHV0ID0gdGF0ZTo6RmluaXNoaW5nIHwgU3RhdGU6OkRvbmUgPT4gcGFuaWMhKCJGbHVzaCBhZnQgUGluPCZtdXQgU2VsZj4sIGN4OiAmbXV0IENvbnRleHQ8J18+KSAtPiBQb2xsPFJlc2R5ISh0aGlzLndyaXRlci5hc19tdXQoKS5wb2xsX3BhcnRpYWxfZmx1c2hfYnVmKGN4Zm4gZ2V0X3JlZigmc2VsZikgLT4gJlcgewogICAgICAgIHNlbGYud3JpdGVyLmdldF8KICAgICAgICAjW3Bpbl0KICAgICAgICB3cml0ZXI6IEJ1ZldyaXRlcjxXPiwKICAgICAgIHRhc2s6OntDb250ZXh0LCBQb2xsfSwKfTsKdXNlIHN0ZDo6aW86OlJlc3VsdDsKQnJvdGxpUmVzdWx0OjpSZXN1bHRGYWlsdXJlID0+IHVucmVhY2hhYmxlISgpLAogICAgfCBCcm90bGlSZXN1bHQ6Ok5lZWRzTW9yZUlucHV0ID0+IE9rKGZhbHNlKSwKICAgIHQ8Ym9vbD4gewogICAgICAgIG1hdGNoIHNlbGYuZGVjb2RlKGlucHV0LCBvdXRwdXQpICAgJm11dCBzZWxmLnN0YXRlLAogICAgICAgICkgewogICAgICAgICAgICBCcm90bGl1ZiA9IGlucHV0LnVud3JpdHRlbigpOwogICAgICAgIGxldCBtdXQgb3V0X2J1ZiA9IHRhbmRhcmRBbGxvYywgQnJvdGxpRGVjb21wcmVzc1N0cmVhbSwgQnJvdGxpUmVzdWx0fQoKICAgICAgICBwdWIoY3JhdGUpIGZuIGFzX3pzdGQoJnNlbGYpIC0+IGxpYnpzdGQgb3RoZXJ3aXNlIGl0IHdpbGwgY2F1c2UgYSBwYW5pYwogICAgICAgIC8vLyB3aGVuICkuCiAgICAgICAgcHViIGZuIGNoZWNrc3VtX2ZsYWcodmFsdWU6IGJvb2wpIC0+IFNlICAvLy8gU2l6ZSBvZiBlYWNoIGJ1Y2tldCBpbiB0aGUgTERNIGhhc2ggdGFibGUgZm9oZSBsb25nLWRpc3RhbmNlIG1hdGNoaW5nIHRhYmxlIChhcyBhIHBvd2VyIG9mIHR3byAgIFNlbGYoTWluTWF0Y2godmFsdWUpKQogICAgICAgIH0KCiAgICAgICAgLy8vIFN0IG9mIHR3bykKICAgICAgICBwdWIgZm4gaGFzaF9sb2codmFsdWU6IHUzMikgLT4gU2UpXQogICAgcHViIHN0cnVjdCBDUGFyYW1ldGVyKGxpYnpzdGQ6OnN0cmVhbTo6cmF3OiAgfQp9CgojW2NmZyhmZWF0dXJlID0gInpzdGQiKV0KLy8vIFRoaXMgbW9kdWxlIGNvIFNlbGY6OkJlc3QgPT4gYmVzdCwKICAgICAgICAgICAgU2VsZjo6UHJlY2lzZShxdWFsZjo6RGVmYXVsdCA9PiBiemlwMjo6Q29tcHJlc3Npb246OmRlZmF1bHQoKSwKICAgICAgICBsZXQgZmFzdGVzdCA9IGJ6aXAyOjpDb21wcmVzc2lvbjo6ZmFzdCgpOwogICAgbWF0Y2ggc2VsZiB7CiAgICAgICAgICAgIFNlbGY6OkZhc3Rlc3QgPT4gcGFyYW1zLnFlYnVnKV0KcHViIGVudW0gTGV2ZWwgewogICAgLy8vIEZhc3Rlc3QgcXVhbGl0eSBvZm50bzsKCiNbbWFjcm9fdXNlXQptb2QgbWFjcm9zOwptb2QgY29kZWM7CgojW2NmZyhmImB6bGliYCAoKmluYWN0aXZlKikgfCBgWmxpYkVuY29kZXJgLCBgWmxpYkRlY29kZXJYekVuY29kZXIpLCBbYFh6RGVjb2RlcmBdKD9zZWFyY2g9WHpEZWNvZGVyKSIKKV0KI2VyYCwgYERlZmxhdGVEZWNvZGVyYCIKKV0KIyFbY2ZnX2F0dHIoCiAgICBmZWF0dXJlcDIiLAogICAgZG9jID0gImBiemlwMmAgfCBbYEJ6RW5jb2RlcmBdKD9zZWFyY2g9Qnp0b2tpb2AgKCppbmFjdGl2ZSopIHwgYHRva2lvOjppbzo6QXN5bmNCdWZSZWFkYCwgYCkiCildCiMhW2NmZ19hdHRyKAogICAgbm90KGZlYXR1cmUgPSAiZnV0dXJlcy1pbyIpdGF0aW9ucywgbmVlZHMgdG8gYmUgcGFpcmVkIHdpdGggYSBzZWxlY3Rpb24gb2YgYWxgICAgfCBBY3RpdmF0ZXMgYWxsIGltcGxlbWVudGF0aW9ucyBhbmQgYWxnb3JpdGhtc29sbDxSZXN1bHQ8KCk+PiB7CiAgICAgICAgaWYgYnVmLnJlbWFpbmluZygpID09IDAgewogICAgICAgICAgICAgICAgcmV0dXJuIFBvbGw6OlJlYWR5KE9rKCgpKSk7CiAgICBwb2xsX2ZpbGxfYnVmKGN4KSk/OwogICAgICAgICAgICAgICAgICAgIGlmIGlucHV0LiAgICAgICAgICAgIGlmIHRoaXMuZGVjb2Rlci5maW5pc2gob3V0cHV0KT8gewogICAgICAgU3RhdGU6OkZsdXNoaW5nCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICBsZXQgaW5wdXQgPSByZWFkeSEodGhpcy5yZWFkZXIuYXNfbXV0KCkucG9sbF9maWRlY29kZXIsCiAgICAgICAgICAgIHN0YXRlOiBTdGF0ZTo6RGVjb2RpbmcsCiAgICAgCgojW2Rlcml2ZShEZWJ1ZyldCmVudW0gU3RhdGUgewogICAgRGVjb2RpbmcsCiAgICBpbmlzaCgpCiAgICB9Cn0KdXNlIGNvcmU6OnsKICAgIHBpbjo6UGluLAogICAgdGFza2lhbEJ1ZmZlcjo6bmV3KCZbXVsuLl0pLAogICAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICAgIHJldHVybiBFcnIoRXJyb3I6Om5ldyhFcnJvcktpbmQ6Ok90aGVyLCAiYnIgbGV0IG11dCBpbnB1dF9sZW4gPSAwOwogICAgICAgIGxldCBtdXQgb3V0cHV0X2xlbiAmbXV0IHNlbGYsCiAgICAgICAgaW5wdXQ6ICZtdXQgUGFydGlhbEJ1ZmZlcjxpbXBsc3RkOjp7CiAgICBmbXQsCiAgICBpbzo6e0Vycm9yLCBFcnJvcktpbmQsIFJlc3VsdH1hbGdvcyEoQGFsZ28gbHptYSBbImx6bWEiXSBMem1hRGVjb2RlciBMem1hRW5jb2RlciAgICAgICApOwoKICAgICAgICBhbGdvcyEoQGFsZ28geHogWyJ4eiJdIFh6RGVjb2Rlc3RkOjppbzo6UmVzdWx0PFNlbGY+IHsKICAgICAgICAgICAgICAgIE9rKFNlbGYgewpjb2RlYzo6WnN0ZEVuY29kZXI6Om5ld193aXRoX2RpY3QobGV2ZWwuaW50b196c3RkKCBkaWN0aW9uYXJ5OiAmW3U4XSkgLT4gOjpzdGQ6OmlvOjpSZXN1bHQ8U2VsZj4gewogICAgLy8vIENyZWF0ZXMgYSBuZXcgZW5jb2RlciwgdXNpbmcgdGhlIHNwZWNpZmllZCAgaWYgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBhIFtgQ1BhcmFtZXRlcjo6biB1bmNvbXByZXNzZWQgZGF0YSBmcm9tIHRoZSBnaXZlbiBzdHJlYW0gYW5kIGVtaXQgICAgcHViIGZuIHdpdGhfcXVhbGl0eShpbm5lcjogJGlubmVyLCBsZXZlbDogY3JhdGUobGV2ZWwuaW50b19mbGF0ZTIoKSksCiAgICAgICAgICAgICAgICAgICAgKSwKICAgIGxhdGVEZWNvZGVyIERlZmxhdGVFbmNvZGVyIDwkaW5uZXI+CiAgICAgICAgeyBAZW5jbmVyOiBjcmF0ZTo6JCgkbW9kOjopK2dlbmVyaWM6OkVuY29kZXI6Om5ldygKICAgICAgICAgICBjcmF0ZTo6Y29kZWM6OkJyb3RsaUVuY29kZXI6Om5ldyhsZXZlbC5pbnRvXyAgIFNlbGY6OndpdGhfcXVhbGl0eShpbm5lciwgY3JhdGU6OkxldmVsOjpEZWZhdWx0ICAgICAgI1tjZmcoZmVhdHVyZSA9ICRhbGdvX3MpXQogICAgICAgIGRlY29kZXIhIHtud3JpdHRlbigpLmlzX2VtcHR5KCkpCiAgICB9CgogICAgZm4gZmluaXNoKAogICAgIHAgewogICAgICAgICAgICBsZXQgb2xkX2xlbiA9IG91dHB1dC53cml0dGVuKCkubGVuICAgICAvLyBUaGUgRmluaXNoIGFjdGlvbiBvbiBjb21wcmVzc2lvbiB3ZW50IG9rLgopCiAgICB9Cn0KCmltcGwgRGVjb2RlIGZvciBCekRlY29kZXIgewogICAgZm4gcmVpbiAgICAgaW5wdXQuYWR2YW5jZSgoc2VsZi5kZWNvbXByZXNzLnRvdGFsX2luKCkgLSBwICB9CiAgICB9CgogICAgZm4gZGVjb2RlKAogICAgICAgICZtdXQgc2VsZiwKICAgICA7CgpwdWIoY3JhdGUpIHVzZSBzZWxmOjp7ZGVjb2Rlcjo6R3ppcERlY29kZXIsIGVuYyAgICAgICAgIHNlbGYucHJvamVjdCgpLmlubmVyLnBvbGxfZmx1c2goY3gpCiAgICAgICAgIHNlbGYucHJvamVjdCgpLmlubmVyLnBvbGxfd3JpdGUoY3gsIGJ1ZikKICAgICBkLgogICAgICAgICAgICBwdWIgZm4gaW50b19pbm5lcihzZWxmKSAtPiBXIHsKICAgIGJlIHRha2VuIHRvIGF2b2lkIHRhbXBlcmluZyB3aXRoIHRoZSBzdGF0ZSBvZiB0aGUgZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIHJlYWRlciB0aGF0IHRoaXMgZGVjb2RlciAgIGlubmVyOiBjcmF0ZTo6dG9raW86OndyaXRlOjpEZWNvZGVyOjpuZXcocmVhZCwgYykgPT4gewogICAgICAgIHBpbl9wcm9qZWN0X2xpdGU6OnBpbl9wcm9qZWN0ISB7CiAgICAgICAgIC5wcm9jZXNzKCZbXSwgb3V0cHV0LnVud3JpdHRlbl9tdXQoKSwgQWN0aW9mPFt1OF0+ICsgQXNNdXQ8W3U4XT4+LAogICAgKSAtPiBSZXN1bHQ8Ym9vbD4gewogIHV0KTsKCiAgICAgICAgbWF0Y2ggc3RhdHVzIHsKICAgICAgICAgICAgU3RhdHVzOjpPZXI8aW1wbCBBc1JlZjxbdThdPj4sCiAgICAgICAgb3V0cHV0OiAmbXV0IFBhcnRpYWw6Ontjb2RlYzo6RGVjb2RlLCB1dGlsOjpQYXJ0aWFsQnVmZmVyfTsKCnVzZSBzdGQ6OnJ0KCkgewogICAgICAgICAgICAgICAgdXNlIGNyYXRlOjp1dGlsOjp7X2Fzc2VydF9zYXNrOjpDb250ZXh0PCdfPiwKICAgICAgICAgICAgICAgIGJ1ZjogJlt1OF0sCiAgICBoaXMgZW5jb2RlciByZXR1cm5pbmcgdGhlIHVuZGVybHlpbmcgd3JpdGVyLgogICAgICAgICAgICAgIHNlbGYucHJvamVjdCgpLmlubmVyLmdldF9waW5fbXV0KCkKICAgICAgICAgcHViIGZuIGdldF9tdXQoJm11dCBzZWxmKSAtPiAmbXV0ICRpbm5lciB7CiAgICAgICAgICAgIGltcGw8JGlubmVyOiB0b2tpbzo6aW86OkFzeW5jV3JpdGU+ICRuYW1lPCBjb21wcmVzc2VkIHRvIGFuIHVuZGVybHlpbmcgc3RyZWFtLgogICAgICAgICAgICAjICAgICAgIFBvbGw6OlBlbmRpbmcKICAgICAgICB9CiAgICB9Cn0KI1ttYWNyb191c2V0PCgpPj4gewogICAgICAgIGlmIHNlbGYucGVuZGVkIHsKICAgICAgICAgICAgbGV0IG11dCBzZWxmOiBQaW48Jm11dCBTZWxmPiwKICAgICAgICBjeDogJm11dCBDb250ZXh0KSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsKICAgICAgICAgICAgaW5uZXIsCiAgICAgICAgICAgKSAtPiBzdGQ6OnRhc2s6OlBvbGw8c3RkOjppbzo6UmVzdWx0PHVzaXplPgogICAgICAgICAgICBmbiBwb2xsX3JlYWQoCiAgICAgICAgICAgICAgICBzZWxmOiBzICAgcHViIGZuIGdldF9waW5fbXV0KHNlbGY6IHN0ZDo6cGluOjpQaW48Jm11dCBTZWxhcHBpbmcuCiAgICAgICAgICAgIC8vLwogICAgICAgICAgICAvLy8gTm90ZSB0aGF0ICAgICAgIHNlbGYuaW5uZXIubXVsdGlwbGVfbWVtYmVycyhlbmFibGVkKTsKICAgICAgOmNvZGVjOjokbmFtZT4sCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGl1ZyldCiAgICAgICAgICAgIHB1YiBzdHJ1Y3QgJG5hbWU8JGlubmVyPiB7CiAgICAgIA==