LyoKICogQ29weXJpZ2h0IChDKSAyMDIwIGJ5IFNhdm9pci1mYWlyZSBMaW51eAogKiBBdXRob3I6IEVkcmljIExhZGVudCBNaWxhcmV0IDxlZHJpYy5sYWRlbnQtbWlsYXJldEBzYXZvaXJmYWlyZWxpbnV4LmNvbT4KICogQXV0aG9yOiBBbnRob255IEzpb25hcmQgPGFudGhvbnkubGVvbmFyZEBzYXZvaXJmYWlyZWxpbnV4LmNvbT4KICogQXV0aG9yOiBPbGl2aWVyIFNvbGRhbm8gPG9saXZpZXIuc29sZGFub0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4KICogQXV0aG9yOiBBbmRyZWFzIFRyYWN6eWsgPGFuZHJlYXMudHJhY3p5a0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4KICogQXV0aG9yOiBJc2EgTmFuaWMgPGlzYS5uYW5pY0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4KICogQXV0aG9yOiBNaW5ncnVpIFpoYW5nIDxtaW5ncnVpLnpoYW5nQHNhdm9pcmZhaXJlbGludXguY29tPgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KICovCgojaW5jbHVkZSAiY29udmVyc2F0aW9uc2FkYXB0ZXIuaCIKCiNpbmNsdWRlICJ1dGlscy5oIgoKQ29udmVyc2F0aW9uc0FkYXB0ZXI6OkNvbnZlcnNhdGlvbnNBZGFwdGVyKFFPYmplY3QgKnBhcmVudCkKICAgIDogUW1sQWRhcHRlckJhc2UocGFyZW50KQp7fQoKQ29udmVyc2F0aW9uc0FkYXB0ZXI6On5Db252ZXJzYXRpb25zQWRhcHRlcigpIHt9Cgp2b2lkCkNvbnZlcnNhdGlvbnNBZGFwdGVyOjppbml0UW1sT2JqZWN0KCkKewogICAgY29udmVyc2F0aW9uU21hcnRMaXN0TW9kZWxfID0gbmV3IFNtYXJ0TGlzdE1vZGVsKExSQ0luc3RhbmNlOjpnZXRDdXJyQWNjSWQoKSwgdGhpcyk7CgogICAgUU1ldGFPYmplY3Q6Omludm9rZU1ldGhvZChxbWxPYmpfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2V0TW9kZWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRX0FSRyhRVmFyaWFudCwgUVZhcmlhbnQ6OmZyb21WYWx1ZShjb252ZXJzYXRpb25TbWFydExpc3RNb2RlbF8pKSk7CgogICAgY29ubmVjdCgmTFJDSW5zdGFuY2U6OmJlaGF2aW9yQ29udHJvbGxlcigpLAogICAgICAgICAgICAmQmVoYXZpb3JDb250cm9sbGVyOjpzaG93Q2hhdFZpZXcsCiAgICAgICAgICAgIFt0aGlzXShjb25zdCBRU3RyaW5nICZhY2NvdW50SWQsIGxyYzo6YXBpOjpjb252ZXJzYXRpb246OkluZm8gY29udkluZm8pIHsKICAgICAgICAgICAgICAgIGVtaXQgc2hvd0NoYXRWaWV3KGFjY291bnRJZCwgY29udkluZm8udWlkKTsKICAgICAgICAgICAgfSk7CgogICAgY29ubmVjdENvbnZlcnNhdGlvbk1vZGVsKCk7Cn0KCnZvaWQKQ29udmVyc2F0aW9uc0FkYXB0ZXI6OmJhY2tUb1dlbGNvbWVQYWdlKCkKewogICAgZGVzZWxlY3RDb252ZXJzYXRpb24oKTsKICAgIFFNZXRhT2JqZWN0OjppbnZva2VNZXRob2QocW1sT2JqXywgImJhY2tUb1dlbGNvbWVQYWdlIik7Cn0KCnZvaWQKQ29udmVyc2F0aW9uc0FkYXB0ZXI6OnNlbGVjdENvbnZlcnNhdGlvbihjb25zdCBRU3RyaW5nICZhY2NvdW50SWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVN0cmluZyAmY29udlVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHByZXZlbnRTZW5kaW5nU2lnbmFsKQp7CiAgICBzZWxlY3RDb252ZXJzYXRpb24oTFJDSW5zdGFuY2U6OmdldENvbnZlcnNhdGlvbkZyb21Db252VWlkKGNvbnZVaWQsIGFjY291bnRJZCksCiAgICAgICAgICAgICAgICAgICAgICAgcHJldmVudFNlbmRpbmdTaWduYWwpOwp9Cgp2b2lkCkNvbnZlcnNhdGlvbnNBZGFwdGVyOjpzZWxlY3RDb252ZXJzYXRpb24oaW50IGluZGV4KQp7CiAgICBhdXRvIGNvbnZNb2RlbCA9IExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q29udmVyc2F0aW9uTW9kZWwoKTsKCiAgICBpZiAoY29udk1vZGVsID09IG51bGxwdHIpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3QgYXV0byBpdGVtID0gY29udk1vZGVsLT5maWx0ZXJlZENvbnZlcnNhdGlvbihpbmRleCk7CgogICAgaWYgKHNlbGVjdENvbnZlcnNhdGlvbihpdGVtLCBmYWxzZSkpIHsKICAgICAgICBhdXRvIGNvbnZVaWQgPSBjb252ZXJzYXRpb25TbWFydExpc3RNb2RlbF8KICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5kYXRhKGNvbnZlcnNhdGlvblNtYXJ0TGlzdE1vZGVsXy0+aW5kZXgoaW5kZXgsIDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6VUlEKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCk7CiAgICAgICAgYXV0byAmY29udmVyc2F0aW9uID0gTFJDSW5zdGFuY2U6OmdldENvbnZlcnNhdGlvbkZyb21Db252VWlkKGNvbnZVaWQpOwogICAgICAgIC8qCiAgICAgICAgICogSWYgaXQgaXMgY2FsbGluZywgc2hvdyBjYWxsdmlldyAoY2FuIHVzZSBzaG93Q2hhdFZpZXcgc2lnbmFsLCBzaW5jZSBpdCB3aWxsIGJlIGRldGVybWluZWQgb24gcW1sKS4KICAgICAgICAgKi8KICAgICAgICBpZiAoIWNvbnZlcnNhdGlvbi51aWQuaXNFbXB0eSgpCiAgICAgICAgICAgICYmIExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q2FsbE1vZGVsKCktPmhhc0NhbGwoY29udmVyc2F0aW9uLmNhbGxJZCkpIHsKICAgICAgICAgICAgZW1pdCBzaG93Q2hhdFZpZXcoTFJDSW5zdGFuY2U6OmdldEN1cnJBY2NJZCgpLCBjb252ZXJzYXRpb24udWlkKTsKICAgICAgICB9CiAgICB9Cn0KCmJvb2wKQ29udmVyc2F0aW9uc0FkYXB0ZXI6OnNlbGVjdENvbnZlcnNhdGlvbihjb25zdCBscmM6OmFwaTo6Y29udmVyc2F0aW9uOjpJbmZvICZpdGVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgcHJldmVudFNlbmRpbmdTaWduYWwpCnsKICAgIC8qCiAgICAgKiBhY2NJbmZvLmNvbnZlcnNhdGlvbk1vZGVsLT5zZWxlY3RDb252ZXJzYXRpb24oaXRlbS51aWQpIG9ubHkgZW1pdCB1aQogICAgICogYmVoYXZpb3IgY29udHJvbCBzaWduYWxzLCBidXQgc29tZXRpbWVzIHdlIGRvIG5vdCB3YW50IHRoYXQsCiAgICAgKiBwcmV2ZW50U2VuZGluZ1NpZ25hbCBib29sZWFuIGNhbiBoZWxwIHVzIHRvIGRldGVybWluZS4KICAgICAqLwogICAgaWYgKExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q29udlVpZCgpID09IGl0ZW0udWlkKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfSBlbHNlIGlmIChpdGVtLnBhcnRpY2lwYW50cy5zaXplKCkgPiAwKSB7CiAgICAgICAgYXV0byAmYWNjSW5mbyA9IExSQ0luc3RhbmNlOjpnZXRBY2NvdW50SW5mbyhpdGVtLmFjY291bnRJZCk7CiAgICAgICAgTFJDSW5zdGFuY2U6OnNldFNlbGVjdGVkQ29udklkKGl0ZW0udWlkKTsKICAgICAgICBpZiAoIXByZXZlbnRTZW5kaW5nU2lnbmFsKQogICAgICAgICAgICBhY2NJbmZvLmNvbnZlcnNhdGlvbk1vZGVsLT5zZWxlY3RDb252ZXJzYXRpb24oaXRlbS51aWQpOwogICAgICAgIGFjY0luZm8uY29udmVyc2F0aW9uTW9kZWwtPmNsZWFyVW5yZWFkSW50ZXJhY3Rpb25zKGl0ZW0udWlkKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25zQWRhcHRlcjo6ZGVzZWxlY3RDb252ZXJzYXRpb24oKQp7CiAgICBpZiAoTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252VWlkKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGF1dG8gY3VycmVudENvbnZlcnNhdGlvbk1vZGVsID0gTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCgpOwoKICAgIGlmIChjdXJyZW50Q29udmVyc2F0aW9uTW9kZWwgPT0gbnVsbHB0cikgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBjdXJyZW50Q29udmVyc2F0aW9uTW9kZWwtPnNlbGVjdENvbnZlcnNhdGlvbigiIik7CiAgICBMUkNJbnN0YW5jZTo6c2V0U2VsZWN0ZWRDb252SWQoKTsKfQoKdm9pZApDb252ZXJzYXRpb25zQWRhcHRlcjo6YWNjb3VudENoYW5nZWRTZXRVcChjb25zdCBRU3RyaW5nICZhY2NvdW50SWQpCnsKICAgIC8qCiAgICAgKiBTaG91bGQgYmUgY2FsbGVkIHdoZW4gY3VycmVudCBhY2NvdW50IGlzIGNoYW5nZWQuCiAgICAgKi8KICAgIGF1dG8gJmFjY291bnRJbmZvID0gTFJDSW5zdGFuY2U6OmFjY291bnRNb2RlbCgpLmdldEFjY291bnRJbmZvKGFjY291bnRJZCk7CiAgICBjdXJyZW50VHlwZUZpbHRlcl8gPSBhY2NvdW50SW5mby5wcm9maWxlSW5mby50eXBlOwogICAgTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCgpLT5zZXRGaWx0ZXIoYWNjb3VudEluZm8ucHJvZmlsZUluZm8udHlwZSk7CiAgICB1cGRhdGVDb252ZXJzYXRpb25zRmlsdGVyV2lkZ2V0KCk7CgogICAgY29ubmVjdENvbnZlcnNhdGlvbk1vZGVsKCk7Cn0KCnZvaWQKQ29udmVyc2F0aW9uc0FkYXB0ZXI6OnVwZGF0ZUNvbnZlcnNhdGlvbnNGaWx0ZXJXaWRnZXQoKQp7CiAgICAvKgogICAgICogVXBkYXRlIHN0YXR1cyBvZiAiQ29udmVyc2F0aW9ucyIgYW5kICJJbnZpdGF0aW9ucyIuCiAgICAgKi8KICAgIGF1dG8gaW52aXRlcyA9IExSQ0luc3RhbmNlOjpnZXRDdXJyZW50QWNjb3VudEluZm8oKS5jb250YWN0TW9kZWwtPnBlbmRpbmdSZXF1ZXN0Q291bnQoKTsKICAgIGlmIChpbnZpdGVzID09IDAgJiYgY3VycmVudFR5cGVGaWx0ZXJfID09IGxyYzo6YXBpOjpwcm9maWxlOjpUeXBlOjpQRU5ESU5HKSB7CiAgICAgICAgY3VycmVudFR5cGVGaWx0ZXJfID0gbHJjOjphcGk6OnByb2ZpbGU6OlR5cGU6OlJJTkc7CiAgICAgICAgTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCgpLT5zZXRGaWx0ZXIoY3VycmVudFR5cGVGaWx0ZXJfKTsKICAgIH0KICAgIHNob3dDb252ZXJzYXRpb25UYWJzKGludml0ZXMpOwp9Cgp2b2lkCkNvbnZlcnNhdGlvbnNBZGFwdGVyOjpzZXRDb252ZXJzYXRpb25GaWx0ZXIoY29uc3QgUVN0cmluZyAmdHlwZSkKewogICAgLyoKICAgICAqIFNldCBjb252ZXJzYXRpb24gZmlsdGVyIGFjY29yZGluZyB0byB0eXBlLAogICAgICogdHlwZSBuZWVkcyB0byBiZSByZWNvZ25pemFibGUgYnkgbHJjOjphcGk6OnByb2ZpbGU6OnRvX3R5cGUuCiAgICAgKi8KICAgIGlmICh0eXBlLmlzRW1wdHkoKSkgewogICAgICAgIGlmIChMUkNJbnN0YW5jZTo6Z2V0Q3VycmVudEFjY291bnRJbmZvKCkucHJvZmlsZUluZm8udHlwZSA9PSBscmM6OmFwaTo6cHJvZmlsZTo6VHlwZTo6UklORykKICAgICAgICAgICAgc2V0Q29udmVyc2F0aW9uRmlsdGVyKGxyYzo6YXBpOjpwcm9maWxlOjpUeXBlOjpSSU5HKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNldENvbnZlcnNhdGlvbkZpbHRlcihscmM6OmFwaTo6cHJvZmlsZTo6VHlwZTo6U0lQKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2V0Q29udmVyc2F0aW9uRmlsdGVyKGxyYzo6YXBpOjpwcm9maWxlOjp0b190eXBlKHR5cGUpKTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25zQWRhcHRlcjo6c2V0Q29udmVyc2F0aW9uRmlsdGVyKGxyYzo6YXBpOjpwcm9maWxlOjpUeXBlIGZpbHRlcikKewogICAgaWYgKGN1cnJlbnRUeXBlRmlsdGVyXyA9PSBmaWx0ZXIpIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjdXJyZW50VHlwZUZpbHRlcl8gPSBmaWx0ZXI7CiAgICBMUkNJbnN0YW5jZTo6Z2V0Q3VycmVudENvbnZlcnNhdGlvbk1vZGVsKCktPnNldEZpbHRlcihjdXJyZW50VHlwZUZpbHRlcl8pOwp9Cgpib29sCkNvbnZlcnNhdGlvbnNBZGFwdGVyOjpjb25uZWN0Q29udmVyc2F0aW9uTW9kZWwoKQp7CiAgICAvKgogICAgICogU2lnbmFsIGNvbm5lY3Rpb25zCiAgICAgKi8KICAgIGF1dG8gY3VycmVudENvbnZlcnNhdGlvbk1vZGVsID0gTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRBY2NvdW50SW5mbygpLmNvbnZlcnNhdGlvbk1vZGVsLmdldCgpOwoKICAgIFFPYmplY3Q6OmRpc2Nvbm5lY3QobW9kZWxTb3J0ZWRDb25uZWN0aW9uXyk7CiAgICBRT2JqZWN0OjpkaXNjb25uZWN0KG1vZGVsVXBkYXRlZENvbm5lY3Rpb25fKTsKICAgIFFPYmplY3Q6OmRpc2Nvbm5lY3QoZmlsdGVyQ2hhbmdlZENvbm5lY3Rpb25fKTsKICAgIFFPYmplY3Q6OmRpc2Nvbm5lY3QobmV3Q29udmVyc2F0aW9uQ29ubmVjdGlvbl8pOwogICAgUU9iamVjdDo6ZGlzY29ubmVjdChjb252ZXJzYXRpb25SZW1vdmVkQ29ubmVjdGlvbl8pOwogICAgUU9iamVjdDo6ZGlzY29ubmVjdChjb252ZXJzYXRpb25DbGVhcmVkQ29ubmVjdGlvbik7CiAgICBRT2JqZWN0OjpkaXNjb25uZWN0KG5ld0ludGVyYWN0aW9uQ29ubmVjdGlvbl8pOwogICAgUU9iamVjdDo6ZGlzY29ubmVjdChpbnRlcmFjdGlvblJlbW92ZWRDb25uZWN0aW9uXyk7CgogICAgbW9kZWxTb3J0ZWRDb25uZWN0aW9uXyA9IFFPYmplY3Q6OmNvbm5lY3QoCiAgICAgICAgY3VycmVudENvbnZlcnNhdGlvbk1vZGVsLCAmbHJjOjphcGk6OkNvbnZlcnNhdGlvbk1vZGVsOjptb2RlbFNvcnRlZCwgW3RoaXNdKCkgewogICAgICAgICAgICB1cGRhdGVDb252ZXJzYXRpb25zRmlsdGVyV2lkZ2V0KCk7CiAgICAgICAgICAgIFFNZXRhT2JqZWN0OjppbnZva2VNZXRob2QocW1sT2JqXywgInVwZGF0ZUNvbnZlcnNhdGlvblNtYXJ0TGlzdFZpZXciKTsKICAgICAgICAgICAgYXV0byBjb252VWlkID0gTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252ZXJzYXRpb24oKS51aWQ7CiAgICAgICAgICAgIGF1dG8gY29udk1vZGVsID0gTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCgpOwogICAgICAgICAgICBhdXRvICZjb252ZXJzYXRpb24gPSBMUkNJbnN0YW5jZTo6Z2V0Q29udmVyc2F0aW9uRnJvbUNvbnZVaWQoY29udlVpZCk7CiAgICAgICAgICAgIGlmIChjb252ZXJzYXRpb24udWlkLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGF1dG8gY29udGFjdFVSSSA9IGNvbnZlcnNhdGlvbi5wYXJ0aWNpcGFudHNbMF07CiAgICAgICAgICAgIGlmIChjb250YWN0VVJJLmlzRW1wdHkoKQogICAgICAgICAgICAgICAgfHwgY29udk1vZGVsLT5vd25lci5jb250YWN0TW9kZWwtPmdldENvbnRhY3QoY29udGFjdFVSSSkucHJvZmlsZUluZm8udHlwZQogICAgICAgICAgICAgICAgICAgICAgID09IGxyYzo6YXBpOjpwcm9maWxlOjpUeXBlOjpURU1QT1JBUlkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBRTWV0YU9iamVjdDo6aW52b2tlTWV0aG9kKHFtbE9ial8sICJtb2RlbFNvcnRlZCIsIFFfQVJHKFFWYXJpYW50LCBjb250YWN0VVJJKSk7CiAgICAgICAgfSk7CgogICAgbW9kZWxVcGRhdGVkQ29ubmVjdGlvbl8KICAgICAgICA9IFFPYmplY3Q6OmNvbm5lY3QoY3VycmVudENvbnZlcnNhdGlvbk1vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAmbHJjOjphcGk6OkNvbnZlcnNhdGlvbk1vZGVsOjpjb252ZXJzYXRpb25VcGRhdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBbdGhpc10oY29uc3QgUVN0cmluZyAmY29udlVpZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUV9VTlVTRUQoY29udlVpZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVDb252ZXJzYXRpb25zRmlsdGVyV2lkZ2V0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTWV0YU9iamVjdDo6aW52b2tlTWV0aG9kKHFtbE9ial8sICJ1cGRhdGVDb252ZXJzYXRpb25TbWFydExpc3RWaWV3Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgIGZpbHRlckNoYW5nZWRDb25uZWN0aW9uXyA9IFFPYmplY3Q6OmNvbm5lY3QoCiAgICAgICAgY3VycmVudENvbnZlcnNhdGlvbk1vZGVsLCAmbHJjOjphcGk6OkNvbnZlcnNhdGlvbk1vZGVsOjpmaWx0ZXJDaGFuZ2VkLCBbdGhpc10oKSB7CiAgICAgICAgICAgIFFNZXRhT2JqZWN0OjppbnZva2VNZXRob2QocW1sT2JqXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidXBkYXRlU21hcnRMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRX0FSRyhRVmFyaWFudCwgTFJDSW5zdGFuY2U6OmdldEN1cnJBY2NJZCgpKSk7CiAgICAgICAgICAgIHVwZGF0ZUNvbnZlcnNhdGlvbnNGaWx0ZXJXaWRnZXQoKTsKICAgICAgICAgICAgUU1ldGFPYmplY3Q6Omludm9rZU1ldGhvZChxbWxPYmpfLCAidXBkYXRlQ29udmVyc2F0aW9uU21hcnRMaXN0VmlldyIpOwogICAgICAgIH0pOwoKICAgIG5ld0NvbnZlcnNhdGlvbkNvbm5lY3Rpb25fCiAgICAgICAgPSBRT2JqZWN0Ojpjb25uZWN0KGN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxyYzo6YXBpOjpDb252ZXJzYXRpb25Nb2RlbDo6bmV3Q29udmVyc2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBbdGhpc10oY29uc3QgUVN0cmluZyAmY29udlVpZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUU1ldGFPYmplY3Q6Omludm9rZU1ldGhvZChxbWxPYmpfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidXBkYXRlU21hcnRMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUV9BUkcoUVZhcmlhbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExSQ0luc3RhbmNlOjpnZXRDdXJyQWNjSWQoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29udmVyc2F0aW9uRm9yTmV3Q29udGFjdChjb252VWlkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgY29udmVyc2F0aW9uUmVtb3ZlZENvbm5lY3Rpb25fCiAgICAgICAgPSBRT2JqZWN0Ojpjb25uZWN0KGN1cnJlbnRDb252ZXJzYXRpb25Nb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxyYzo6YXBpOjpDb252ZXJzYXRpb25Nb2RlbDo6Y29udmVyc2F0aW9uUmVtb3ZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RoaXNdKCkgeyBiYWNrVG9XZWxjb21lUGFnZSgpOyB9KTsKCiAgICBjb252ZXJzYXRpb25DbGVhcmVkQ29ubmVjdGlvbgogICAgICAgID0gUU9iamVjdDo6Y29ubmVjdChjdXJyZW50Q29udmVyc2F0aW9uTW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZscmM6OmFwaTo6Q29udmVyc2F0aW9uTW9kZWw6OmNvbnZlcnNhdGlvbkNsZWFyZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aGlzXShjb25zdCBRU3RyaW5nICZjb252VWlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogSWYgY3VycmVudGx5IHNlbGVjdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3dpdGNoIHRvIHdlbGNvbWUgc2NyZWVuIChkZXNlbGVjdGluZyBjdXJyZW50IHNtYXJ0bGlzdCBpdGVtICkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb252VWlkICE9IExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q29udlVpZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFja1RvV2VsY29tZVBhZ2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgbmV3SW50ZXJhY3Rpb25Db25uZWN0aW9uXwogICAgICAgID0gUU9iamVjdDo6Y29ubmVjdChjdXJyZW50Q29udmVyc2F0aW9uTW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZscmM6OmFwaTo6Q29udmVyc2F0aW9uTW9kZWw6Om5ld0ludGVyYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBbdGhpc10gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQ29udmVyc2F0aW9uc0ZpbHRlcldpZGdldCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUU1ldGFPYmplY3Q6Omludm9rZU1ldGhvZChxbWxPYmpfLCAidXBkYXRlQ29udmVyc2F0aW9uU21hcnRMaXN0VmlldyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICBjdXJyZW50Q29udmVyc2F0aW9uTW9kZWwtPnNldEZpbHRlcigiIik7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApDb252ZXJzYXRpb25zQWRhcHRlcjo6dXBkYXRlQ29udmVyc2F0aW9uRm9yTmV3Q29udGFjdChjb25zdCBRU3RyaW5nICZjb252VWlkKQp7CiAgICBhdXRvIGNvbnZNb2RlbCA9IExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q29udmVyc2F0aW9uTW9kZWwoKTsKICAgIGlmIChjb252TW9kZWwgPT0gbnVsbHB0cikgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGF1dG8gc2VsZWN0ZWRVaWQgPSBMUkNJbnN0YW5jZTo6Z2V0Q3VycmVudENvbnZVaWQoKTsKICAgIGF1dG8gJmNvbnZlcnNhdGlvbiA9IExSQ0luc3RhbmNlOjpnZXRDb252ZXJzYXRpb25Gcm9tQ29udlVpZChjb252VWlkLCB7fSwgdHJ1ZSk7CiAgICBpZiAoIWNvbnZlcnNhdGlvbi51aWQuaXNFbXB0eSgpKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYXV0byBjb250YWN0ID0gY29udk1vZGVsLT5vd25lci5jb250YWN0TW9kZWwtPmdldENvbnRhY3QoY29udmVyc2F0aW9uLnBhcnRpY2lwYW50c1swXSk7CiAgICAgICAgICAgIGlmICghY29udGFjdC5wcm9maWxlSW5mby51cmkuaXNFbXB0eSgpICYmIGNvbnRhY3QucHJvZmlsZUluZm8udXJpID09IHNlbGVjdGVkVWlkKSB7CiAgICAgICAgICAgICAgICBMUkNJbnN0YW5jZTo6c2V0U2VsZWN0ZWRDb252SWQoY29udlVpZCk7CiAgICAgICAgICAgICAgICBjb252TW9kZWwtPnNlbGVjdENvbnZlcnNhdGlvbihjb252VWlkKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKC4uLikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQp9