Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEFsZWtzYW5kYXIgUm9kaWMgLSBDcmVhdG9yIGFuZCBXZWJHTCBpbXBsZW1lbnRhdGlvbiAKLy8gIEplc3NlIEJhcmtlciAtIGdsbWFyazIgcG9ydAovLwojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlICJzY2VuZS5oIgojaW5jbHVkZSAic2NlbmUtamVsbHlmaXNoLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInV0aWwuaCIKI2luY2x1ZGUgInRleHR1cmUuaCIKI2luY2x1ZGUgInNoYWRlci1zb3VyY2UuaCIKClNjZW5lSmVsbHlmaXNoOjpTY2VuZUplbGx5ZmlzaChDYW52YXMmIGNhbnZhcykgOgogICAgU2NlbmUoY2FudmFzLCAiamVsbHlmaXNoIiksIHByaXZfKDApCnsKCn0KClNjZW5lSmVsbHlmaXNoOjp+U2NlbmVKZWxseWZpc2goKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVKZWxseWZpc2g6OmxvYWQoKQp7CiAgICBydW5uaW5nXyA9IGZhbHNlOwogICAgcmV0dXJuIHRydWU7Cn0KCnZvaWQKU2NlbmVKZWxseWZpc2g6OnVubG9hZCgpCnsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6c2V0dXAoKQp7CiAgICBTY2VuZTo6c2V0dXAoKTsKCiAgICAvLyBTZXQgdXAgb3VyIHByaXZhdGUgb2JqZWN0IHRoYXQgZG9lcyBhbGwgb2YgdGhlIGxpZnRpbmcKICAgIHByaXZfID0gbmV3IEplbGx5ZmlzaFByaXZhdGUoKTsKICAgIHByaXZfLT5pbml0aWFsaXplKCk7CgogICAgLy8gU2V0IGNvcmUgc2NlbmUgdGltaW5nIGFmdGVyIGFjdHVhbCBpbml0aWFsaXphdGlvbiBzbyB3ZSBkb24ndCBtZWFzdXJlCiAgICAvLyBzZXQgdXAgdGltZS4KICAgIHN0YXJ0VGltZV8gPSBVdGlsOjpnZXRfdGltZXN0YW1wX3VzKCkgLyAxMDAwMDAwLjA7CiAgICBsYXN0VXBkYXRlVGltZV8gPSBzdGFydFRpbWVfOwogICAgcnVubmluZ18gPSB0cnVlOwp9Cgp2b2lkClNjZW5lSmVsbHlmaXNoOjp0ZWFyZG93bigpCnsKICAgIHByaXZfLT5jbGVhbnVwKCk7CiAgICBTY2VuZTo6dGVhcmRvd24oKTsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6dXBkYXRlKCkKewogICAgU2NlbmU6OnVwZGF0ZSgpOwogICAgcHJpdl8tPnVwZGF0ZV92aWV3cG9ydChMaWJNYXRyaXg6OnZlYzIoY2FudmFzXy53aWR0aCgpLCBjYW52YXNfLmhlaWdodCgpKSk7CiAgICBwcml2Xy0+dXBkYXRlX3RpbWUoKTsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6ZHJhdygpCnsKICAgIHByaXZfLT5kcmF3KCk7Cn0KClNjZW5lOjpWYWxpZGF0aW9uUmVzdWx0ClNjZW5lSmVsbHlmaXNoOjp2YWxpZGF0ZSgpCnsKICAgIHJldHVybiBTY2VuZTo6VmFsaWRhdGlvblVua25vd247Cn0KCgovLwovLyBKZWxseWZpc2hQcml2YXRlIGltcGxlbWVudGF0aW9uCi8vCnVzaW5nIExpYk1hdHJpeDo6bWF0NDsKdXNpbmcgTGliTWF0cml4Ojp2ZWMzOwp1c2luZyBMaWJNYXRyaXg6OnZlYzI7CnVzaW5nIHN0ZDo6c3RyaW5nOwp1c2luZyBzdGQ6OnZlY3RvcjsKCnZvaWQKR3JhZGllbnRSZW5kZXJlcjo6aW5pdCgpCnsKICAgIC8vIFByb2dyYW0gc2V0IHVwCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9ncmFkaWVudC52ZXJ0Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGZyZ19zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9ncmFkaWVudC5mcmFnIik7CiAgICBTaGFkZXJTb3VyY2UgdnR4X3NvdXJjZSh2dHhfc2hhZGVyX2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSBmcmdfc291cmNlKGZyZ19zaGFkZXJfZmlsZW5hbWUpOwogICAgaWYgKCFTY2VuZTo6bG9hZF9zaGFkZXJzX2Zyb21fc3RyaW5ncyhwcm9ncmFtXywgdnR4X3NvdXJjZS5zdHIoKSwKICAgICAgICBmcmdfc291cmNlLnN0cigpKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwb3NpdGlvbkxvY2F0aW9uXyA9IHByb2dyYW1fWyJwb3NpdGlvbiJdLmxvY2F0aW9uKCk7CiAgICB1dkxvY2F0aW9uXyA9IHByb2dyYW1fWyJ1dkluIl0ubG9jYXRpb24oKTsKCiAgICAvLyBTZXQgdXAgdGhlIHBvc2l0aW9uIGRhdGEgZm9yIG91ciAicXVhZCIuCiAgICB2ZXJ0aWNlc18ucHVzaF9iYWNrKHZlYzIoLTEuMCwgLTEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgLTEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKC0xLjAsIDEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDAuMCwgMC4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDAuMCwgMC4wKSk7CiAgICB1dk9mZnNldF8gPSB2ZXJ0aWNlc18uc2l6ZSgpICogc2l6ZW9mKHZlYzIpOwoKICAgIC8vIFNldCB1cCB0aGUgVkJPIGFuZCBzdGFzaCBvdXIgcG9zaXRpb24gZGF0YSBpbiBpdC4KICAgIGdsR2VuQnVmZmVycygxLCAmYnVmZmVyT2JqZWN0Xyk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RfKTsKICAgIGdsQnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsICh2ZXJ0aWNlc18uc2l6ZSgpICsgdXZzXy5zaXplKCkpICogc2l6ZW9mKHZlYzIpLAogICAgICAgICAgICAgICAgIDAsIEdMX1NUQVRJQ19EUkFXKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIDAsIHZlcnRpY2VzXy5zaXplKCkgKiBzaXplb2YodmVjMiksCiAgICAgICAgICAgICAgICAgICAgJnZlcnRpY2VzXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIHV2T2Zmc2V0XywgdXZzXy5zaXplKCkgKiBzaXplb2YodmVjMiksCiAgICAgICAgICAgICAgICAgICAgJnV2c18uZnJvbnQoKSk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAwKTsKfQoKdm9pZApHcmFkaWVudFJlbmRlcmVyOjpjbGVhbnVwKCkKewogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbERlbGV0ZUJ1ZmZlcnMoMSwgJmJ1ZmZlck9iamVjdF8pOwp9Cgp2b2lkCkdyYWRpZW50UmVuZGVyZXI6OmRyYXcoKQp7CiAgICBzdGF0aWMgY29uc3QgdmVjMyBsaWdodEJsdWUoMC4zNjA3ODQzMTQsIDAuNTg0MzEzNzI1LCAxLjApOwogICAgc3RhdGljIGNvbnN0IHZlYzMgZGFya0JsdWUoMC4wNzQ1MDk4MDQsIDAuMTU2ODYyNzQ1LCAwLjYxOTYwNzg0Myk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RfKTsKICAgIHByb2dyYW1fLnN0YXJ0KCk7CiAgICBwcm9ncmFtX1siY29sb3IxIl0gPSBsaWdodEJsdWU7CiAgICBwcm9ncmFtX1siY29sb3IyIl0gPSBkYXJrQmx1ZTsKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh1dkxvY2F0aW9uXyk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25Mb2NhdGlvbl8sIDIsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwgMCk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIodXZMb2NhdGlvbl8sIDIsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PEdMdm9pZCo+KHV2T2Zmc2V0XykpOwogICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFX1NUUklQLCAwLCA0KTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb25fKTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHV2TG9jYXRpb25fKTsKICAgIHByb2dyYW1fLnN0b3AoKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwp9CgovLyEKLy8gUGFyc2UgaW5kZXggdmFsdWVzIGZyb20gYW4gT0JKIGZpbGUuCi8vCi8vIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBsaW5lIHRvIHBhcnNlCi8vIEBwYXJhbSBpZHggdGhlIHVuc2lnbmVkIHNob3J0IHRvIHBvcHVsYXRlCi8vCnN0YXRpYyB2b2lkCm9ial9nZXRfaW5kZXgoY29uc3Qgc3RyaW5nJiBzb3VyY2UsIHVuc2lnbmVkIHNob3J0JiBpZHgpCnsKICAgICAvLyBTa2lwIHRoZSBkZWZpbml0aW9uIHR5cGUuLi4KICAgIHN0cmluZzo6c2l6ZV90eXBlIGVuZFBvcyA9IHNvdXJjZS5maW5kKCIgIik7CiAgICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydFBvcygwKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkJhZCBlbGVtZW50ICclcydcbiIsIHNvdXJjZS5jX3N0cigpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvLyBGaW5kIHRoZSBmaXJzdCB2YWx1ZS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgc3RyaW5nIGlzKHNvdXJjZSwgc3RhcnRQb3MpOwogICAgaWR4ID0gVXRpbDo6ZnJvbVN0cmluZzx1bnNpZ25lZCBzaG9ydD4oaXMpOyAgIAp9CgovLyEKLy8gUGFyc2UgdmVjMyB2YWx1ZXMgZnJvbSBhbiBPQkogZmlsZS4KLy8KLy8gQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIGxpbmUgdG8gcGFyc2UKLy8gQHBhcmFtIHYgdGhlIHZlYzMgdG8gcG9wdWxhdGUKLy8Kc3RhdGljIHZvaWQKb2JqX2dldF92YWx1ZXMoY29uc3Qgc3RyaW5nJiBzb3VyY2UsIHZlYzMmIHYpCnsKICAgIC8vIFNraXAgdGhlIGRlZmluaXRpb24gdHlwZS4uLgogICAgc3RyaW5nOjpzaXplX3R5cGUgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiKTsKICAgIHN0cmluZzo6c2l6ZV90eXBlIHN0YXJ0UG9zKDApOwogICAgaWYgKGVuZFBvcyA9PSBzdHJpbmc6Om5wb3MpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiQmFkIGVsZW1lbnQgJyVzJ1xuIiwgc291cmNlLmNfc3RyKCkpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIEZpbmQgdGhlIGZpcnN0IHZhbHVlLi4uCiAgICBzdGFydFBvcyA9IGVuZFBvcyArIDE7CiAgICBlbmRQb3MgPSBzb3VyY2UuZmluZCgiICIsIHN0YXJ0UG9zKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkJhZCBlbGVtZW50ICclcydcbiIsIHNvdXJjZS5jX3N0cigpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzdHJpbmc6OnNpemVfdHlwZSBudW1DaGFycyhlbmRQb3MgLSBzdGFydFBvcyk7CiAgICBzdHJpbmcgeHMoc291cmNlLCBzdGFydFBvcywgbnVtQ2hhcnMpOwogICAgZmxvYXQgeCA9IFV0aWw6OmZyb21TdHJpbmc8ZmxvYXQ+KHhzKTsKICAgIC8vIFRoZW4gdGhlIHNlY29uZCB2YWx1ZS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiLCBzdGFydFBvcyk7CiAgICBpZiAoZW5kUG9zID09IHN0cmluZzo6bnBvcykKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJCYWQgZWxlbWVudCAnJXMnXG4iLCBzb3VyY2UuY19zdHIoKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbnVtQ2hhcnMgPSBlbmRQb3MgLSBzdGFydFBvczsKICAgIHN0cmluZyB5cyhzb3VyY2UsIHN0YXJ0UG9zLCBudW1DaGFycyk7CiAgICBmbG9hdCB5ID0gVXRpbDo6ZnJvbVN0cmluZzxmbG9hdD4oeXMpOwogICAgLy8gQW5kIHRoZSB0aGlyZCB2YWx1ZSAodGhlcmUgbWlnaHQgYmUgYSBmb3VydGgsIGJ1dCB3ZSBkb24ndCBjYXJlKS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiLCBzdGFydFBvcyk7CiAgICBpZiAoZW5kUG9zID09IHN0cmluZzo6bnBvcykKICAgIHsKICAgICAgICBudW1DaGFycyA9IGVuZFBvczsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBudW1DaGFycyA9IGVuZFBvcyAtIHN0YXJ0UG9zOwogICAgfQogICAgc3RyaW5nIHpzKHNvdXJjZSwgc3RhcnRQb3MsIGVuZFBvcyAtIHN0YXJ0UG9zKTsKICAgIGZsb2F0IHogPSBVdGlsOjpmcm9tU3RyaW5nPGZsb2F0Pih6cyk7CiAgICB2LngoeCk7CiAgICB2LnkoeSk7CiAgICB2Lnooeik7Cn0KCi8vIEN1c3RvbSBPQkogbG9hZGVyLgovLwovLyBUbyBzdXBwb3J0IHRoZSBqZWxseWZpc2ggbW9kZWwsIHNvbWUgYW1lbmRtZW50cyB0byB0aGUgT0JKIGZvcm1hdCBhcmUKLy8gbmVjZXNzYXJ5LiAgSW4gcGFydGljdWxhciwgYSB2ZXJ0ZXggY29sb3IgYXR0cmlidXRlIGlzIHJlcXVpcmVkLCBhbmQKLy8gaXQgY29udGFpbnMgYW4gaW5kZXggbGlzdCByYXRoZXIgdGhhbiBhIGZhY2UgbGlzdC4KYm9vbApKZWxseWZpc2hQcml2YXRlOjpsb2FkX29iaihjb25zdCBzdGQ6OnN0cmluZyAmZmlsZW5hbWUpCnsKICAgIExvZzo6ZGVidWcoIkxvYWRpbmcgbW9kZWwgZnJvbSBmaWxlICclcydcbiIsIGZpbGVuYW1lLmNfc3RyKCkpOwoKICAgIGNvbnN0IHN0ZDo6YXV0b19wdHI8c3RkOjppc3RyZWFtPiBpbnB1dF9maWxlX3B0cihVdGlsOjpnZXRfcmVzb3VyY2UoZmlsZW5hbWUpKTsKICAgIHN0ZDo6aXN0cmVhbSYgaW5wdXRGaWxlKCppbnB1dF9maWxlX3B0cik7CiAgICBpZiAoIWlucHV0RmlsZSkKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gb3BlbiAnJXMnXG4iLCBmaWxlbmFtZS5jX3N0cigpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmVjdG9yPHN0cmluZz4gc291cmNlVmVjOwogICAgc3RyaW5nIGN1ckxpbmU7CiAgICB3aGlsZSAoZ2V0bGluZShpbnB1dEZpbGUsIGN1ckxpbmUpKQogICAgewogICAgICAgIHNvdXJjZVZlYy5wdXNoX2JhY2soY3VyTGluZSk7CiAgICB9CgogICAgc3RhdGljIGNvbnN0IHN0cmluZyB2ZXJ0ZXhfZGVmaW5pdGlvbigidiIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBub3JtYWxfZGVmaW5pdGlvbigidm4iKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdGV4Y29vcmRfZGVmaW5pdGlvbigidnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgY29sb3JfZGVmaW5pdGlvbigidmMiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgaW5kZXhfZGVmaW5pdGlvbigiaSIpOwogICAgZm9yICh2ZWN0b3I8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgbGluZUl0ID0gc291cmNlVmVjLmJlZ2luKCk7CiAgICAgICAgIGxpbmVJdCAhPSBzb3VyY2VWZWMuZW5kKCk7CiAgICAgICAgIGxpbmVJdCsrKQogICAgewogICAgICAgIGNvbnN0IHN0cmluZyYgY3VyU3JjID0gKmxpbmVJdDsKICAgICAgICAvLyBJcyBpdCBhIHZlcnRleCBhdHRyaWJ1dGUsIGEgZmFjZSBkZXNjcmlwdGlvbiwgY29tbWVudCBvciBvdGhlcj8KICAgICAgICAvLyBXZSBvbmx5IGNhcmUgYWJvdXQgdGhlIGZpcnN0IHR3bywgd2UgaWdub3JlIGNvbW1lbnRzLCBvYmplY3QgbmFtZXMsCiAgICAgICAgLy8gZ3JvdXAgbmFtZXMsIHNtb290aGluZyBncm91cHMsIGV0Yy4KICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydFBvcygwKTsKICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBzcGFjZVBvcyA9IGN1clNyYy5maW5kKCIgIiwgc3RhcnRQb3MpOwogICAgICAgIHN0cmluZyBkZWZpbml0aW9uVHlwZShjdXJTcmMsIHN0YXJ0UG9zLCBzcGFjZVBvcyAtIHN0YXJ0UG9zKTsKICAgICAgICBpZiAoZGVmaW5pdGlvblR5cGUgPT0gdmVydGV4X2RlZmluaXRpb24pCiAgICAgICAgewogICAgICAgICAgICB2ZWMzIHY7CiAgICAgICAgICAgIG9ial9nZXRfdmFsdWVzKGN1clNyYywgdik7CiAgICAgICAgICAgIHBvc2l0aW9uc18ucHVzaF9iYWNrKHYpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChkZWZpbml0aW9uVHlwZSA9PSBub3JtYWxfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZlYzMgdjsKICAgICAgICAgICAgb2JqX2dldF92YWx1ZXMoY3VyU3JjLCB2KTsKICAgICAgICAgICAgbm9ybWFsc18ucHVzaF9iYWNrKHYpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChkZWZpbml0aW9uVHlwZSA9PSBjb2xvcl9kZWZpbml0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdmVjMyB2OwogICAgICAgICAgICBvYmpfZ2V0X3ZhbHVlcyhjdXJTcmMsIHYpOwogICAgICAgICAgICBjb2xvcnNfLnB1c2hfYmFjayh2KTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGVmaW5pdGlvblR5cGUgPT0gdGV4Y29vcmRfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZlYzMgdjsKICAgICAgICAgICAgb2JqX2dldF92YWx1ZXMoY3VyU3JjLCB2KTsKICAgICAgICAgICAgdGV4Y29vcmRzXy5wdXNoX2JhY2sodik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGRlZmluaXRpb25UeXBlID09IGluZGV4X2RlZmluaXRpb24pCiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBpZHgoMCk7CiAgICAgICAgICAgIG9ial9nZXRfaW5kZXgoY3VyU3JjLCBpZHgpOwogICAgICAgICAgICBpbmRpY2VzXy5wdXNoX2JhY2soaWR4KTsKICAgICAgICB9CiAgICB9CgogICAgTG9nOjpkZWJ1ZygiT2JqZWN0IHBvcHVsYXRlZCB3aXRoICV1IHZlcnRpY2VzICV1IG5vcm1hbHMgJXUgY29sb3JzICV1IHRleGNvb3JkcyBhbmQgJXUgaW5kaWNlcy5cbiIsCiAgICAgICAgcG9zaXRpb25zXy5zaXplKCksIG5vcm1hbHNfLnNpemUoKSwgY29sb3JzXy5zaXplKCksIHRleGNvb3Jkc18uc2l6ZSgpLCBpbmRpY2VzXy5zaXplKCkpOwogICAgcmV0dXJuIHRydWU7Cn0KCkplbGx5ZmlzaFByaXZhdGU6OkplbGx5ZmlzaFByaXZhdGUoKSA6CiAgICBwb3NpdGlvbkxvY2F0aW9uXygwKSwKICAgIG5vcm1hbExvY2F0aW9uXygwKSwKICAgIGNvbG9yTG9jYXRpb25fKDApLAogICAgdGV4Y29vcmRMb2NhdGlvbl8oMCksCiAgICB2aWV3cG9ydF8oNTEyLjAsIDUxMi4wKSwKICAgIGxpZ2h0UG9zaXRpb25fKDEwLjAsIDQwLjAsIC02MC4wKSwKICAgIGxpZ2h0Q29sb3JfKDAuOCwgMS4zLCAxLjEsIDEuMCksCiAgICBsaWdodFJhZGl1c18oMjAwLjApLAogICAgYW1iaWVudENvbG9yXygwLjMsIDAuMiwgMS4wLCAxLjApLAogICAgZnJlc25lbENvbG9yXygwLjgsIDAuNywgMC42LCAxLjEpLAogICAgZnJlc25lbFBvd2VyXygxLjApLAogICAgcm90YXRpb25fKDAuMCksCiAgICBjdXJyZW50VGltZV8oMC4wKSwKICAgIGxhc3RVcGRhdGVUaW1lXygwLjApLAogICAgY3VsbEZhY2VfKDApLAogICAgZGVwdGhUZXN0XygwKSwKICAgIGJsZW5kXygwKSwKICAgIGJsZW5kRnVuY1NyY18oMCksCiAgICBibGVuZEZ1bmNEc3RfKDApCnsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgbW9kZWxGaWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9tb2RlbHMvamVsbHlmaXNoLmpvYmoiKTsKICAgIGlmICghbG9hZF9vYmoobW9kZWxGaWxlbmFtZSkpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIHNldHVwIHRoZSB2ZXJ0ZXggZGF0YSwgd2UgY2FuIHNldHVwIHRoZSBtYXAgb2YgaG93CiAgICAvLyB0aGF0IGRhdGEgd2lsbCBiZSBsYWlkIG91dCBpbiB0aGUgYnVmZmVyIG9iamVjdC4KICAgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgc3YzKHNpemVvZih2ZWMzKSk7CiAgICBkYXRhTWFwXy5wb3NpdGlvbk9mZnNldCA9IDA7CiAgICBkYXRhTWFwXy5wb3NpdGlvblNpemUgPSBwb3NpdGlvbnNfLnNpemUoKSAqIHN2MzsKICAgIGRhdGFNYXBfLnRvdGFsU2l6ZSA9IGRhdGFNYXBfLnBvc2l0aW9uU2l6ZTsKICAgIGRhdGFNYXBfLm5vcm1hbE9mZnNldCA9IGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0ICsgZGF0YU1hcF8ucG9zaXRpb25TaXplOwogICAgZGF0YU1hcF8ubm9ybWFsU2l6ZSA9IG5vcm1hbHNfLnNpemUoKSAqIHN2MzsKICAgIGRhdGFNYXBfLnRvdGFsU2l6ZSArPSBkYXRhTWFwXy5ub3JtYWxTaXplOwogICAgZGF0YU1hcF8uY29sb3JPZmZzZXQgPSBkYXRhTWFwXy5ub3JtYWxPZmZzZXQgKyBkYXRhTWFwXy5ub3JtYWxTaXplOwogICAgZGF0YU1hcF8uY29sb3JTaXplID0gY29sb3JzXy5zaXplKCkgKiBzdjM7CiAgICBkYXRhTWFwXy50b3RhbFNpemUgKz0gZGF0YU1hcF8uY29sb3JTaXplOwogICAgZGF0YU1hcF8udGV4Y29vcmRPZmZzZXQgPSBkYXRhTWFwXy5jb2xvck9mZnNldCArIGRhdGFNYXBfLmNvbG9yU2l6ZTsKICAgIGRhdGFNYXBfLnRleGNvb3JkU2l6ZSA9IHRleGNvb3Jkc18uc2l6ZSgpICogc3YzOwogICAgZGF0YU1hcF8udG90YWxTaXplICs9IGRhdGFNYXBfLnRleGNvb3JkU2l6ZTsKfQoKSmVsbHlmaXNoUHJpdmF0ZTo6fkplbGx5ZmlzaFByaXZhdGUoKQp7CiAgICBwb3NpdGlvbnNfLmNsZWFyKCk7CiAgICBub3JtYWxzXy5jbGVhcigpOwogICAgY29sb3JzXy5jbGVhcigpOwogICAgdGV4Y29vcmRzXy5jbGVhcigpOwogICAgaW5kaWNlc18uY2xlYXIoKTsKfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjppbml0aWFsaXplKCkKewogICAgbGFzdFVwZGF0ZVRpbWVfID0gVXRpbDo6Z2V0X3RpbWVzdGFtcF91cygpIC8gMTAwMC4wOwogICAgY3VycmVudFRpbWVfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KGxhc3RVcGRhdGVUaW1lXykgJSAxMDAwMDAwMDAgLyAxMDAwLjA7CiAgICB3aGljaENhdXN0aWNfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KGN1cnJlbnRUaW1lXyAqIDMwKSAlIDMyICsgMTsKICAgIHJvdGF0aW9uXyA9IDAuMDsKCiAgICBncmFkaWVudF8uaW5pdCgpOwoKICAgIC8vIFNldCB1cCBwcm9ncmFtIGZpcnN0IHNvIHdlIGNhbiBzdG9yZSBhdHRyaWJ1dGUgYW5kIHVuaWZvcm0gbG9jYXRpb25zCiAgICAvLyBhd2F5IGZvciB0aGUgCiAgICB1c2luZyBzdGQ6OnN0cmluZzsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdnR4X3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2plbGx5ZmlzaC52ZXJ0Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGZyZ19zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9qZWxseWZpc2guZnJhZyIpOwoKICAgIFNoYWRlclNvdXJjZSB2dHhfc291cmNlKHZ0eF9zaGFkZXJfZmlsZW5hbWUpOwogICAgU2hhZGVyU291cmNlIGZyZ19zb3VyY2UoZnJnX3NoYWRlcl9maWxlbmFtZSk7CgogICAgaWYgKCFTY2VuZTo6bG9hZF9zaGFkZXJzX2Zyb21fc3RyaW5ncyhwcm9ncmFtXywgdnR4X3NvdXJjZS5zdHIoKSwKICAgICAgICBmcmdfc291cmNlLnN0cigpKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gU3Rhc2ggYXdheSBhdHRyaWJ1dGUgYW5kIHVuaWZvcm0gbG9jYXRpb25zIGZvciBoYW5keSB1c2UuCiAgICBwb3NpdGlvbkxvY2F0aW9uXyA9IHByb2dyYW1fWyJhVmVydGV4UG9zaXRpb24iXS5sb2NhdGlvbigpOwogICAgbm9ybWFsTG9jYXRpb25fID0gcHJvZ3JhbV9bImFWZXJ0ZXhOb3JtYWwiXS5sb2NhdGlvbigpOwogICAgY29sb3JMb2NhdGlvbl8gPSBwcm9ncmFtX1siYVZlcnRleENvbG9yIl0ubG9jYXRpb24oKTsKICAgIHRleGNvb3JkTG9jYXRpb25fID0gcHJvZ3JhbV9bImFUZXh0dXJlQ29vcmQiXS5sb2NhdGlvbigpOwoKICAgIC8vIFdlIG5lZWQgMiBidWZmZXJzIGZvciBvdXIgd29yayBoZXJlLiAgT25lIGZvciB0aGUgdmVydGV4IGRhdGEuCiAgICAvLyBhbmQgb25lIGZvciB0aGUgaW5kZXggZGF0YS4KICAgIGdsR2VuQnVmZmVycygyLCAmYnVmZmVyT2JqZWN0c19bMF0pOwoKICAgIC8vIEZpcnN0LCBzZXR1cCB0aGUgdmVydGV4IGRhdGEgYnkgYmluZGluZyB0aGUgZmlyc3QgYnVmZmVyIG9iamVjdCwgCiAgICAvLyBhbGxvY2F0aW5nIGl0cyBkYXRhIHN0b3JlLCBhbmQgZmlsbGluZyBpdCBpbiB3aXRoIG91ciB2ZXJ0ZXggZGF0YS4KICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzBdKTsKICAgIGdsQnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLnRvdGFsU2l6ZSwgMCwgR0xfU1RBVElDX0RSQVcpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgZGF0YU1hcF8ucG9zaXRpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgZGF0YU1hcF8ucG9zaXRpb25TaXplLCAmcG9zaXRpb25zXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLm5vcm1hbE9mZnNldCwKICAgICAgICAgICAgICAgICAgICBkYXRhTWFwXy5ub3JtYWxTaXplLCAmbm9ybWFsc18uZnJvbnQoKSk7CiAgICBnbEJ1ZmZlclN1YkRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy5jb2xvck9mZnNldCwKICAgICAgICAgICAgICAgICAgICBkYXRhTWFwXy5jb2xvclNpemUsICZjb2xvcnNfLmZyb250KCkpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgZGF0YU1hcF8udGV4Y29vcmRPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgZGF0YU1hcF8udGV4Y29vcmRTaXplLCAmdGV4Y29vcmRzXy5mcm9udCgpKTsKCiAgICAvLyBOb3cgcmVwZWF0IGZvciBvdXIgaW5kZXggZGF0YS4KICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwogICAgZ2xCdWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBpbmRpY2VzXy5zaXplKCkgKiBzaXplb2YodW5zaWduZWQgc2hvcnQpLAogICAgICAgICAgICAgICAgICZpbmRpY2VzXy5mcm9udCgpLCBHTF9TVEFUSUNfRFJBVyk7CgogICAgLy8gIlVuYmluZCIgb3VyIGJ1ZmZlciBvYmplY3RzIHRvIG1ha2Ugc3VyZSB0aGUgc3RhdGUgaXMgY29uc2lzdGVudC4KICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwogICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKCiAgICAvLyBGaW5hbGx5LCBzZXQgdXAgb3VyIHRleHR1cmVzLgogICAgLy8KICAgIC8vIEZpcnN0LCB0aGUgbWFpbiBqZWxseWZpc2ggdGV4dHVyZQogICAgYm9vbCBnb3RUZXggPSBUZXh0dXJlOjpsb2FkKCJqZWxseWZpc2gyNTYiLCAmdGV4dHVyZU9iamVjdHNfWzBdLCBHTF9MSU5FQVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfTElORUFSLCAwKTsKICAgIGlmICghZ290VGV4IHx8IHRleHR1cmVPYmplY3RzX1swXSA9PSAwKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkplbGx5ZmlzaCB0ZXh0dXJlIHNldCB1cCBmYWlsZWQhISFcbiIpOwogICAgfQogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgIC8vIFRoZW4sIHRoZSBjYXVzdGljcyB0ZXh0dXJlcwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBiYXNlTmFtZSgiamVsbHlmaXNoLWNhdXN0aWNzLSIpOwogICAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDE7IGkgPCAzMzsgaSsrKQogICAgewogICAgICAgIHN0ZDo6c3RyaW5nc3RyZWFtIHNzOwogICAgICAgIHNzIDw8IHN0ZDo6c2V0dygyKSA8PCBzdGQ6OnNldGZpbGwoJzAnKSA8PCBpOwogICAgICAgIHN0cmluZyBjdXJOYW1lKGJhc2VOYW1lKTsKICAgICAgICBjdXJOYW1lICs9IHNzLnN0cigpOwogICAgICAgIGdvdFRleCA9IFRleHR1cmU6OmxvYWQoY3VyTmFtZSwgJnRleHR1cmVPYmplY3RzX1tpXSwgR0xfTElORUFSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfTElORUFSLCAwKTsKICAgICAgICBpZiAoIWdvdFRleCB8fCB0ZXh0dXJlT2JqZWN0c19baV0gPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIExvZzo6ZXJyb3IoIkNhdXN0aWNzIHRleHR1cmVbJXVdIHNldCB1cCBmYWlsZWQhISFcbiIsIGkpOwogICAgICAgIH0KICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX1JFUEVBVCk7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9ULCBHTF9SRVBFQVQpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICB9CgogICAgLy8gU2F2ZSB0aGUgR0wgc3RhdGUgd2UgYXJlIGNoYW5naW5nIHNvIHdlIGNhbiByZXN0b3JlIGl0IGxhdGVyLgogICAgY3VsbEZhY2VfID0gZ2xJc0VuYWJsZWQoR0xfQ1VMTF9GQUNFKTsKICAgIGRlcHRoVGVzdF8gPSBnbElzRW5hYmxlZChHTF9ERVBUSF9URVNUKTsKICAgIGJsZW5kXyA9IGdsSXNFbmFibGVkKEdMX0JMRU5EKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfQkxFTkRfU1JDX1JHQiwgJmJsZW5kRnVuY1NyY18pOwogICAgZ2xHZXRJbnRlZ2VydihHTF9CTEVORF9EU1RfUkdCLCAmYmxlbmRGdW5jRHN0Xyk7CgogICAgZ2xCbGVuZEZ1bmMoR0xfU1JDX0FMUEhBLCBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBKTsKICAgIGdsRW5hYmxlKEdMX0JMRU5EKTsKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwp9Cgp2b2lkCkplbGx5ZmlzaFByaXZhdGU6OnVwZGF0ZV92aWV3cG9ydChjb25zdCB2ZWMyJiB2cCkKewogICAgaWYgKHZpZXdwb3J0Xy54KCkgPT0gdnAueCgpICYmIHZpZXdwb3J0Xy55KCkgPT0gdnAueSgpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIHZpZXdwb3J0XyA9IHZwOwogICAgcHJvamVjdGlvbl8ubG9hZElkZW50aXR5KCk7CiAgICBwcm9qZWN0aW9uXy5wZXJzcGVjdGl2ZSgzMC4wLCB2aWV3cG9ydF8ueCgpL3ZpZXdwb3J0Xy55KCksIDIwLjAsIDEyMC4wKTsgICAgCn0KCnZvaWQKSmVsbHlmaXNoUHJpdmF0ZTo6dXBkYXRlX3RpbWUoKQp7CiAgICBkb3VibGUgbm93ID0gVXRpbDo6Z2V0X3RpbWVzdGFtcF91cygpIC8gMTAwMC4wOwogICAgZG91YmxlIGVsYXBzZWRUaW1lID0gbm93IC0gbGFzdFVwZGF0ZVRpbWVfOwogICAgcm90YXRpb25fICs9ICgyLjAgKiBlbGFwc2VkVGltZSkgLyAxMDAwLjA7CiAgICBjdXJyZW50VGltZV8gPSBzdGF0aWNfY2FzdDx1aW50NjRfdD4obm93KSAlIDEwMDAwMDAwMCAvIDEwMDAuMDsKICAgIHdoaWNoQ2F1c3RpY18gPSBzdGF0aWNfY2FzdDx1aW50NjRfdD4oY3VycmVudFRpbWVfICogMzApICUgMzIgKyAxOwogICAgbGFzdFVwZGF0ZVRpbWVfID0gbm93Owp9Cgp2b2lkCkplbGx5ZmlzaFByaXZhdGU6OmNsZWFudXAoKQp7CiAgICAvLyBSZXN0b3JlIHRoZSBHTCBzdGF0ZSB3ZSBjaGFuZ2VkIGZvciB0aGUgc2NlbmUuCiAgICBnbEJsZW5kRnVuYyhibGVuZEZ1bmNTcmNfLCBibGVuZEZ1bmNEc3RfKTsKICAgIGlmIChHTF9GQUxTRSA9PSBibGVuZF8pCiAgICB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgIH0KICAgIGlmIChHTF9UUlVFID09IGN1bGxGYWNlXykKICAgIHsKICAgICAgICBnbEVuYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgfQogICAgaWYgKEdMX1RSVUUgPT0gZGVwdGhUZXN0XykKICAgIHsKICAgICAgICBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgIH0KCiAgICBwcm9ncmFtXy5zdG9wKCk7CiAgICBwcm9ncmFtXy5yZWxlYXNlKCk7CgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIDApOwoKICAgIGdsRGVsZXRlVGV4dHVyZXMoMzMsICZ0ZXh0dXJlT2JqZWN0c19bMF0pOwogICAgZ2xEZWxldGVCdWZmZXJzKDIsICZidWZmZXJPYmplY3RzX1swXSk7CgogICAgZ3JhZGllbnRfLmNsZWFudXAoKTsKfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjpkcmF3KCkKewogICAgLy8gIkNsZWFyIiB0aGUgYmFja2dyb3VuZCB0byB0aGUgZGVzaXJlZCBncmFkaWVudC4KICAgIGdyYWRpZW50Xy5kcmF3KCk7CgogICAgLy8gV2UgbmVlZCAid29ybGQiLCAid29ybGQgdmlldyBwcm9qZWN0aW9uIiwgYW5kICJ3b3JsZCBpbnZlcnNlIHRyYW5zcG9zZSIKICAgIC8vIG1hdHJpeCB1bmlmb3JtcyBmb3IgdGhlIGN1cnJlbnQgc2hhZGVyLgogICAgLy8KICAgIC8vIE5PVEU6IFNvbWUgb2YgdGhpcyBzZWVtcyBhIGJpdCBvZiBhIG5vLW9wIChlLmcuLCBtdWx0aXB5aW5nIGJ5IGFuZAogICAgLy8gICAgICAgaW52ZXJ0aW5nIGlkZW50aXR5IG1hdHJpY2VzKSwgYnV0IGxlYXZlIGl0IGxpa2UgdGhlIG9yaWdpbmFsCiAgICAvLyAgICAgICBXZWJHTCBmaWxlcyBmb3IgdGhlIHRpbWUgYmVpbmcuICBXb3J0aCByZXZpc2l0aW5nIG5vdCBkb2luZyBhbGwKICAgIC8vICAgICAgIG9mIHRoYXQgbWF0aCBldmVyeSBkcmF3IGNhbGwgKG1pZ2h0IGV2ZW4gYmUgZ29vZCB0byBiZSBkb2luZwogICAgLy8gICAgICAgc29tZSBvZiBpdCBpbiB0aGUgc2hhZGVyIGFzIHdlbGwpLgogICAgd29ybGRfLnB1c2goKTsKICAgIHdvcmxkXy50cmFuc2xhdGUoMC4wLCA1LjAsIC03NS4wKTsKICAgIHdvcmxkXy5yb3RhdGUoc2luKHJvdGF0aW9uXyAvIDEwLjApICogMzAuMCwgMC4wLCAxLjAsIDAuMCk7CiAgICB3b3JsZF8ucm90YXRlKHNpbihyb3RhdGlvbl8gLyAyMC4wKSAqIDMwLjAsIDEuMCwgMC4wLCAwLjApOwogICAgd29ybGRfLnNjYWxlKDUuMCwgNS4wLCA1LjApOwogICAgd29ybGRfLnRyYW5zbGF0ZSgwLjAsIHNpbihyb3RhdGlvbl8gLyAxMC4wKSAqIDIuNSwgMC4wKTsKICAgIG1hdDQgd29ybGRWaWV3UHJvamVjdGlvbihwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCkpOwogICAgd29ybGRWaWV3UHJvamVjdGlvbiAqPSB3b3JsZF8uZ2V0Q3VycmVudCgpOzsKICAgIG1hdDQgd29ybGRJbnZlcnNlVHJhbnNwb3NlKHdvcmxkXy5nZXRDdXJyZW50KCkpOwogICAgd29ybGRJbnZlcnNlVHJhbnNwb3NlLmludmVyc2UoKS50cmFuc3Bvc2UoKTsKCiAgICAvLyBMb2FkIHVwIHRoZSB1bmlmb3JtcwogICAgcHJvZ3JhbV8uc3RhcnQoKTsKICAgIHByb2dyYW1fWyJ1V29ybGQiXSA9IHdvcmxkXy5nZXRDdXJyZW50KCk7CiAgICBwcm9ncmFtX1sidVdvcmxkVmlld1Byb2oiXSA9IHdvcmxkVmlld1Byb2plY3Rpb247CiAgICBwcm9ncmFtX1sidVdvcmxkSW52VHJhbnNwb3NlIl0gPSB3b3JsZEludmVyc2VUcmFuc3Bvc2U7CiAgICBwcm9ncmFtX1sidUN1cnJlbnRUaW1lIl0gPSBjdXJyZW50VGltZV87CiAgICAvLyBSZXZpc2l0IG1ha2luZyB0aGVzZSBjb25zdGFudHMgcmF0aGVyIHRoYW4gdW5pZm9ybXMgYXMgdGhleSBhcHBlYXIgbmV2ZXIKICAgIC8vIHRvIGNoYW5nZQogICAgcHJvZ3JhbV9bInVMaWdodFBvcyJdID0gbGlnaHRQb3NpdGlvbl87CiAgICBwcm9ncmFtX1sidUxpZ2h0UmFkaXVzIl0gPSBsaWdodFJhZGl1c187CiAgICBwcm9ncmFtX1sidUxpZ2h0Q29sIl0gPSBsaWdodENvbG9yXzsKICAgIHByb2dyYW1fWyJ1QW1iaWVudENvbCJdID0gYW1iaWVudENvbG9yXzsKICAgIHByb2dyYW1fWyJ1RnJlc25lbENvbCJdID0gZnJlc25lbENvbG9yXzsKICAgIHByb2dyYW1fWyJ1RnJlc25lbFBvd2VyIl0gPSBmcmVzbmVsUG93ZXJfOwogICAgLy8gU2V0IHVwIHRleHR1cmVzIGZvciB0aGlzIGZyYW1lLgogICAgZ2xBY3RpdmVUZXh0dXJlKEdMX1RFWFRVUkUwKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4dHVyZU9iamVjdHNfWzBdKTsKICAgIHByb2dyYW1fWyJ1U2FtcGxlciJdID0gMDsKICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMSk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVPYmplY3RzX1t3aGljaENhdXN0aWNfXSk7CiAgICBwcm9ncmFtX1sidVNhbXBsZXIxIl0gPSAxOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzBdKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwoKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShub3JtYWxMb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShjb2xvckxvY2F0aW9uXyk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleGNvb3JkTG9jYXRpb25fKTsKICAgIGdsVmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uXyAsIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0KSk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIobm9ybWFsTG9jYXRpb25fICwgMywgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oZGF0YU1hcF8ubm9ybWFsT2Zmc2V0KSk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIoY29sb3JMb2NhdGlvbl8gLCAzLCBHTF9GTE9BVCwgR0xfRkFMU0UsIDAsCiAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBHTHZvaWQqPihkYXRhTWFwXy5jb2xvck9mZnNldCkpOwogICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKHRleGNvb3JkTG9jYXRpb25fICwgMywgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oZGF0YU1hcF8udGV4Y29vcmRPZmZzZXQpKTsKCiAgICBnbERyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIGluZGljZXNfLnNpemUoKSwgR0xfVU5TSUdORURfU0hPUlQsIDApOwoKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb25fKTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KG5vcm1hbExvY2F0aW9uXyk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShjb2xvckxvY2F0aW9uXyk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheSh0ZXhjb29yZExvY2F0aW9uXyk7CgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIDApOwoKICAgIHByb2dyYW1fLnN0b3AoKTsKICAgIHdvcmxkXy5wb3AoKTsKfQo=