Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEFsZWtzYW5kYXIgUm9kaWMgLSBDcmVhdG9yIGFuZCBXZWJHTCBpbXBsZW1lbnRhdGlvbiAKLy8gIEplc3NlIEJhcmtlciAtIGdsbWFyazIgcG9ydAovLwojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlICJzY2VuZS5oIgojaW5jbHVkZSAic2NlbmUtamVsbHlmaXNoLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInV0aWwuaCIKI2luY2x1ZGUgInRleHR1cmUuaCIKI2luY2x1ZGUgInNoYWRlci1zb3VyY2UuaCIKClNjZW5lSmVsbHlmaXNoOjpTY2VuZUplbGx5ZmlzaChDYW52YXMmIGNhbnZhcykgOgogICAgU2NlbmUoY2FudmFzLCAiamVsbHlmaXNoIikKewoKfQoKU2NlbmVKZWxseWZpc2g6On5TY2VuZUplbGx5ZmlzaCgpCnsKICAgIGRlbGV0ZSBwcml2XzsKfQoKYm9vbApTY2VuZUplbGx5ZmlzaDo6bG9hZCgpCnsKICAgIHJ1bm5pbmdfID0gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6dW5sb2FkKCkKewp9Cgp2b2lkClNjZW5lSmVsbHlmaXNoOjpzZXR1cCgpCnsKICAgIFNjZW5lOjpzZXR1cCgpOwoKICAgIC8vIFNldCB1cCBvdXIgcHJpdmF0ZSBvYmplY3QgdGhhdCBkb2VzIGFsbCBvZiB0aGUgbGlmdGluZwogICAgcHJpdl8gPSBuZXcgSmVsbHlmaXNoUHJpdmF0ZSgpOwogICAgcHJpdl8tPmluaXRpYWxpemUoKTsKCiAgICAvLyBTZXQgY29yZSBzY2VuZSB0aW1pbmcgYWZ0ZXIgYWN0dWFsIGluaXRpYWxpemF0aW9uIHNvIHdlIGRvbid0IG1lYXN1cmUKICAgIC8vIHNldCB1cCB0aW1lLgogICAgc3RhcnRUaW1lXyA9IFV0aWw6OmdldF90aW1lc3RhbXBfdXMoKSAvIDEwMDAwMDAuMDsKICAgIGxhc3RVcGRhdGVUaW1lXyA9IHN0YXJ0VGltZV87CiAgICBydW5uaW5nXyA9IHRydWU7Cn0KCnZvaWQKU2NlbmVKZWxseWZpc2g6OnRlYXJkb3duKCkKewogICAgcHJpdl8tPmNsZWFudXAoKTsKICAgIFNjZW5lOjp0ZWFyZG93bigpOwp9Cgp2b2lkClNjZW5lSmVsbHlmaXNoOjp1cGRhdGUoKQp7CiAgICBTY2VuZTo6dXBkYXRlKCk7CiAgICBwcml2Xy0+dXBkYXRlX3ZpZXdwb3J0KExpYk1hdHJpeDo6dmVjMihjYW52YXNfLndpZHRoKCksIGNhbnZhc18uaGVpZ2h0KCkpKTsKICAgIHByaXZfLT51cGRhdGVfdGltZSgpOwp9Cgp2b2lkClNjZW5lSmVsbHlmaXNoOjpkcmF3KCkKewogICAgcHJpdl8tPmRyYXcoKTsKfQoKU2NlbmU6OlZhbGlkYXRpb25SZXN1bHQKU2NlbmVKZWxseWZpc2g6OnZhbGlkYXRlKCkKewogICAgcmV0dXJuIFNjZW5lOjpWYWxpZGF0aW9uVW5rbm93bjsKfQoKCi8vCi8vIEplbGx5ZmlzaFByaXZhdGUgaW1wbGVtZW50YXRpb24KLy8KdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzM7CnVzaW5nIExpYk1hdHJpeDo6dmVjMjsKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIHN0ZDo6dmVjdG9yOwoKdm9pZApHcmFkaWVudFJlbmRlcmVyOjppbml0KCkKewogICAgLy8gUHJvZ3JhbSBzZXQgdXAKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdnR4X3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2dyYWRpZW50LnZlcnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgZnJnX3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2dyYWRpZW50LmZyYWciKTsKICAgIFNoYWRlclNvdXJjZSB2dHhfc291cmNlKHZ0eF9zaGFkZXJfZmlsZW5hbWUpOwogICAgU2hhZGVyU291cmNlIGZyZ19zb3VyY2UoZnJnX3NoYWRlcl9maWxlbmFtZSk7CiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHByb2dyYW1fLCB2dHhfc291cmNlLnN0cigpLAogICAgICAgIGZyZ19zb3VyY2Uuc3RyKCkpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIHBvc2l0aW9uTG9jYXRpb25fID0gcHJvZ3JhbV9bInBvc2l0aW9uIl0ubG9jYXRpb24oKTsKICAgIHV2TG9jYXRpb25fID0gcHJvZ3JhbV9bInV2SW4iXS5sb2NhdGlvbigpOwoKICAgIC8vIFNldCB1cCB0aGUgcG9zaXRpb24gZGF0YSBmb3Igb3VyICJxdWFkIi4KICAgIHZlcnRpY2VzXy5wdXNoX2JhY2sodmVjMigtMS4wLCAtMS4wKSk7CiAgICB2ZXJ0aWNlc18ucHVzaF9iYWNrKHZlYzIoMS4wLCAtMS4wKSk7CiAgICB2ZXJ0aWNlc18ucHVzaF9iYWNrKHZlYzIoLTEuMCwgMS4wKSk7CiAgICB2ZXJ0aWNlc18ucHVzaF9iYWNrKHZlYzIoMS4wLCAxLjApKTsKICAgIHV2c18ucHVzaF9iYWNrKHZlYzIoMS4wLCAxLjApKTsKICAgIHV2c18ucHVzaF9iYWNrKHZlYzIoMS4wLCAxLjApKTsKICAgIHV2c18ucHVzaF9iYWNrKHZlYzIoMC4wLCAwLjApKTsKICAgIHV2c18ucHVzaF9iYWNrKHZlYzIoMC4wLCAwLjApKTsKICAgIHV2T2Zmc2V0XyA9IHZlcnRpY2VzXy5zaXplKCkgKiBzaXplb2YodmVjMik7CgogICAgLy8gU2V0IHVwIHRoZSBWQk8gYW5kIHN0YXNoIG91ciBwb3NpdGlvbiBkYXRhIGluIGl0LgogICAgZ2xHZW5CdWZmZXJzKDEsICZidWZmZXJPYmplY3RfKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdF8pOwogICAgZ2xCdWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgKHZlcnRpY2VzXy5zaXplKCkgKyB1dnNfLnNpemUoKSkgKiBzaXplb2YodmVjMiksCiAgICAgICAgICAgICAgICAgMCwgR0xfU1RBVElDX0RSQVcpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgMCwgdmVydGljZXNfLnNpemUoKSAqIHNpemVvZih2ZWMyKSwKICAgICAgICAgICAgICAgICAgICAmdmVydGljZXNfLmZyb250KCkpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgdXZPZmZzZXRfLCB1dnNfLnNpemUoKSAqIHNpemVvZih2ZWMyKSwKICAgICAgICAgICAgICAgICAgICAmdXZzXy5mcm9udCgpKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwp9Cgp2b2lkCkdyYWRpZW50UmVuZGVyZXI6OmNsZWFudXAoKQp7CiAgICBwcm9ncmFtXy5zdG9wKCk7CiAgICBwcm9ncmFtXy5yZWxlYXNlKCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAwKTsKICAgIGdsRGVsZXRlQnVmZmVycygxLCAmYnVmZmVyT2JqZWN0Xyk7Cn0KCnZvaWQKR3JhZGllbnRSZW5kZXJlcjo6ZHJhdygpCnsKICAgIHN0YXRpYyBjb25zdCB2ZWMzIGxpZ2h0Qmx1ZSgwLjM2MDc4NDMxNCwgMC41ODQzMTM3MjUsIDEuMCk7CiAgICBzdGF0aWMgY29uc3QgdmVjMyBkYXJrQmx1ZSgwLjA3NDUwOTgwNCwgMC4xNTY4NjI3NDUsIDAuNjE5NjA3ODQzKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdF8pOwogICAgcHJvZ3JhbV8uc3RhcnQoKTsKICAgIHByb2dyYW1fWyJjb2xvcjEiXSA9IGxpZ2h0Qmx1ZTsKICAgIHByb2dyYW1fWyJjb2xvcjIiXSA9IGRhcmtCbHVlOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uXyk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHV2TG9jYXRpb25fKTsKICAgIGdsVmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uXywgMiwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLCAwKTsKICAgIGdsVmVydGV4QXR0cmliUG9pbnRlcih1dkxvY2F0aW9uXywgMiwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8R0x2b2lkKj4odXZPZmZzZXRfKSk7CiAgICBnbERyYXdBcnJheXMoR0xfVFJJQU5HTEVfU1RSSVAsIDAsIDQpOwogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbl8pOwogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkodXZMb2NhdGlvbl8pOwogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7Cn0KCi8vIQovLyBQYXJzZSBpbmRleCB2YWx1ZXMgZnJvbSBhbiBPQkogZmlsZS4KLy8KLy8gQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIGxpbmUgdG8gcGFyc2UKLy8gQHBhcmFtIGlkeCB0aGUgdW5zaWduZWQgc2hvcnQgdG8gcG9wdWxhdGUKLy8Kc3RhdGljIHZvaWQKb2JqX2dldF9pbmRleChjb25zdCBzdHJpbmcmIHNvdXJjZSwgdW5zaWduZWQgc2hvcnQmIGlkeCkKewogICAgIC8vIFNraXAgdGhlIGRlZmluaXRpb24gdHlwZS4uLgogICAgc3RyaW5nOjpzaXplX3R5cGUgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiKTsKICAgIHN0cmluZzo6c2l6ZV90eXBlIHN0YXJ0UG9zKDApOwogICAgaWYgKGVuZFBvcyA9PSBzdHJpbmc6Om5wb3MpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiQmFkIGVsZW1lbnQgJyVzJ1xuIiwgc291cmNlLmNfc3RyKCkpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIEZpbmQgdGhlIGZpcnN0IHZhbHVlLi4uCiAgICBzdGFydFBvcyA9IGVuZFBvcyArIDE7CiAgICBzdHJpbmcgaXMoc291cmNlLCBzdGFydFBvcyk7CiAgICBpZHggPSBVdGlsOjpmcm9tU3RyaW5nPHVuc2lnbmVkIHNob3J0Pihpcyk7ICAgCn0KCi8vIQovLyBQYXJzZSB2ZWMzIHZhbHVlcyBmcm9tIGFuIE9CSiBmaWxlLgovLwovLyBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2UgbGluZSB0byBwYXJzZQovLyBAcGFyYW0gdiB0aGUgdmVjMyB0byBwb3B1bGF0ZQovLwpzdGF0aWMgdm9pZApvYmpfZ2V0X3ZhbHVlcyhjb25zdCBzdHJpbmcmIHNvdXJjZSwgdmVjMyYgdikKewogICAgLy8gU2tpcCB0aGUgZGVmaW5pdGlvbiB0eXBlLi4uCiAgICBzdHJpbmc6OnNpemVfdHlwZSBlbmRQb3MgPSBzb3VyY2UuZmluZCgiICIpOwogICAgc3RyaW5nOjpzaXplX3R5cGUgc3RhcnRQb3MoMCk7CiAgICBpZiAoZW5kUG9zID09IHN0cmluZzo6bnBvcykKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJCYWQgZWxlbWVudCAnJXMnXG4iLCBzb3VyY2UuY19zdHIoKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgLy8gRmluZCB0aGUgZmlyc3QgdmFsdWUuLi4KICAgIHN0YXJ0UG9zID0gZW5kUG9zICsgMTsKICAgIGVuZFBvcyA9IHNvdXJjZS5maW5kKCIgIiwgc3RhcnRQb3MpOwogICAgaWYgKGVuZFBvcyA9PSBzdHJpbmc6Om5wb3MpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiQmFkIGVsZW1lbnQgJyVzJ1xuIiwgc291cmNlLmNfc3RyKCkpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN0cmluZzo6c2l6ZV90eXBlIG51bUNoYXJzKGVuZFBvcyAtIHN0YXJ0UG9zKTsKICAgIHN0cmluZyB4cyhzb3VyY2UsIHN0YXJ0UG9zLCBudW1DaGFycyk7CiAgICBmbG9hdCB4ID0gVXRpbDo6ZnJvbVN0cmluZzxmbG9hdD4oeHMpOwogICAgLy8gVGhlbiB0aGUgc2Vjb25kIHZhbHVlLi4uCiAgICBzdGFydFBvcyA9IGVuZFBvcyArIDE7CiAgICBlbmRQb3MgPSBzb3VyY2UuZmluZCgiICIsIHN0YXJ0UG9zKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkJhZCBlbGVtZW50ICclcydcbiIsIHNvdXJjZS5jX3N0cigpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBudW1DaGFycyA9IGVuZFBvcyAtIHN0YXJ0UG9zOwogICAgc3RyaW5nIHlzKHNvdXJjZSwgc3RhcnRQb3MsIG51bUNoYXJzKTsKICAgIGZsb2F0IHkgPSBVdGlsOjpmcm9tU3RyaW5nPGZsb2F0Pih5cyk7CiAgICAvLyBBbmQgdGhlIHRoaXJkIHZhbHVlICh0aGVyZSBtaWdodCBiZSBhIGZvdXJ0aCwgYnV0IHdlIGRvbid0IGNhcmUpLi4uCiAgICBzdGFydFBvcyA9IGVuZFBvcyArIDE7CiAgICBlbmRQb3MgPSBzb3VyY2UuZmluZCgiICIsIHN0YXJ0UG9zKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIG51bUNoYXJzID0gZW5kUG9zOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG51bUNoYXJzID0gZW5kUG9zIC0gc3RhcnRQb3M7CiAgICB9CiAgICBzdHJpbmcgenMoc291cmNlLCBzdGFydFBvcywgZW5kUG9zIC0gc3RhcnRQb3MpOwogICAgZmxvYXQgeiA9IFV0aWw6OmZyb21TdHJpbmc8ZmxvYXQ+KHpzKTsKICAgIHYueCh4KTsKICAgIHYueSh5KTsKICAgIHYueih6KTsKfQoKLy8gQ3VzdG9tIE9CSiBsb2FkZXIuCi8vCi8vIFRvIHN1cHBvcnQgdGhlIGplbGx5ZmlzaCBtb2RlbCwgc29tZSBhbWVuZG1lbnRzIHRvIHRoZSBPQkogZm9ybWF0IGFyZQovLyBuZWNlc3NhcnkuICBJbiBwYXJ0aWN1bGFyLCBhIHZlcnRleCBjb2xvciBhdHRyaWJ1dGUgaXMgcmVxdWlyZWQsIGFuZAovLyBpdCBjb250YWlucyBhbiBpbmRleCBsaXN0IHJhdGhlciB0aGFuIGEgZmFjZSBsaXN0Lgpib29sCkplbGx5ZmlzaFByaXZhdGU6OmxvYWRfb2JqKGNvbnN0IHN0ZDo6c3RyaW5nICZmaWxlbmFtZSkKewogICAgTG9nOjpkZWJ1ZygiTG9hZGluZyBtb2RlbCBmcm9tIGZpbGUgJyVzJ1xuIiwgZmlsZW5hbWUuY19zdHIoKSk7CgogICAgY29uc3Qgc3RkOjphdXRvX3B0cjxzdGQ6OmlzdHJlYW0+IGlucHV0X2ZpbGVfcHRyKFV0aWw6OmdldF9yZXNvdXJjZShmaWxlbmFtZSkpOwogICAgc3RkOjppc3RyZWFtJiBpbnB1dEZpbGUoKmlucHV0X2ZpbGVfcHRyKTsKICAgIGlmICghaW5wdXRGaWxlKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBvcGVuICclcydcbiIsIGZpbGVuYW1lLmNfc3RyKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICB2ZWN0b3I8c3RyaW5nPiBzb3VyY2VWZWM7CiAgICBzdHJpbmcgY3VyTGluZTsKICAgIHdoaWxlIChnZXRsaW5lKGlucHV0RmlsZSwgY3VyTGluZSkpCiAgICB7CiAgICAgICAgc291cmNlVmVjLnB1c2hfYmFjayhjdXJMaW5lKTsKICAgIH0KCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZlcnRleF9kZWZpbml0aW9uKCJ2Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIG5vcm1hbF9kZWZpbml0aW9uKCJ2biIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyB0ZXhjb29yZF9kZWZpbml0aW9uKCJ2dCIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBjb2xvcl9kZWZpbml0aW9uKCJ2YyIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBpbmRleF9kZWZpbml0aW9uKCJpIik7CiAgICBmb3IgKHZlY3RvcjxzdHJpbmc+Ojpjb25zdF9pdGVyYXRvciBsaW5lSXQgPSBzb3VyY2VWZWMuYmVnaW4oKTsKICAgICAgICAgbGluZUl0ICE9IHNvdXJjZVZlYy5lbmQoKTsKICAgICAgICAgbGluZUl0KyspCiAgICB7CiAgICAgICAgY29uc3Qgc3RyaW5nJiBjdXJTcmMgPSAqbGluZUl0OwogICAgICAgIC8vIElzIGl0IGEgdmVydGV4IGF0dHJpYnV0ZSwgYSBmYWNlIGRlc2NyaXB0aW9uLCBjb21tZW50IG9yIG90aGVyPwogICAgICAgIC8vIFdlIG9ubHkgY2FyZSBhYm91dCB0aGUgZmlyc3QgdHdvLCB3ZSBpZ25vcmUgY29tbWVudHMsIG9iamVjdCBuYW1lcywKICAgICAgICAvLyBncm91cCBuYW1lcywgc21vb3RoaW5nIGdyb3VwcywgZXRjLgogICAgICAgIHN0cmluZzo6c2l6ZV90eXBlIHN0YXJ0UG9zKDApOwogICAgICAgIHN0cmluZzo6c2l6ZV90eXBlIHNwYWNlUG9zID0gY3VyU3JjLmZpbmQoIiAiLCBzdGFydFBvcyk7CiAgICAgICAgc3RyaW5nIGRlZmluaXRpb25UeXBlKGN1clNyYywgc3RhcnRQb3MsIHNwYWNlUG9zIC0gc3RhcnRQb3MpOwogICAgICAgIGlmIChkZWZpbml0aW9uVHlwZSA9PSB2ZXJ0ZXhfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZlYzMgdjsKICAgICAgICAgICAgb2JqX2dldF92YWx1ZXMoY3VyU3JjLCB2KTsKICAgICAgICAgICAgcG9zaXRpb25zXy5wdXNoX2JhY2sodik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGRlZmluaXRpb25UeXBlID09IG5vcm1hbF9kZWZpbml0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdmVjMyB2OwogICAgICAgICAgICBvYmpfZ2V0X3ZhbHVlcyhjdXJTcmMsIHYpOwogICAgICAgICAgICBub3JtYWxzXy5wdXNoX2JhY2sodik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGRlZmluaXRpb25UeXBlID09IGNvbG9yX2RlZmluaXRpb24pCiAgICAgICAgewogICAgICAgICAgICB2ZWMzIHY7CiAgICAgICAgICAgIG9ial9nZXRfdmFsdWVzKGN1clNyYywgdik7CiAgICAgICAgICAgIGNvbG9yc18ucHVzaF9iYWNrKHYpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChkZWZpbml0aW9uVHlwZSA9PSB0ZXhjb29yZF9kZWZpbml0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdmVjMyB2OwogICAgICAgICAgICBvYmpfZ2V0X3ZhbHVlcyhjdXJTcmMsIHYpOwogICAgICAgICAgICB0ZXhjb29yZHNfLnB1c2hfYmFjayh2KTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGVmaW5pdGlvblR5cGUgPT0gaW5kZXhfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IGlkeCgwKTsKICAgICAgICAgICAgb2JqX2dldF9pbmRleChjdXJTcmMsIGlkeCk7CiAgICAgICAgICAgIGluZGljZXNfLnB1c2hfYmFjayhpZHgpOwogICAgICAgIH0KICAgIH0KCiAgICBMb2c6OmRlYnVnKCJPYmplY3QgcG9wdWxhdGVkIHdpdGggJXUgdmVydGljZXMgJXUgbm9ybWFscyAldSBjb2xvcnMgJXUgdGV4Y29vcmRzIGFuZCAldSBpbmRpY2VzLlxuIiwKICAgICAgICBwb3NpdGlvbnNfLnNpemUoKSwgbm9ybWFsc18uc2l6ZSgpLCBjb2xvcnNfLnNpemUoKSwgdGV4Y29vcmRzXy5zaXplKCksIGluZGljZXNfLnNpemUoKSk7CiAgICByZXR1cm4gdHJ1ZTsKfQoKSmVsbHlmaXNoUHJpdmF0ZTo6SmVsbHlmaXNoUHJpdmF0ZSgpIDoKICAgIHBvc2l0aW9uTG9jYXRpb25fKDApLAogICAgbm9ybWFsTG9jYXRpb25fKDApLAogICAgY29sb3JMb2NhdGlvbl8oMCksCiAgICB0ZXhjb29yZExvY2F0aW9uXygwKSwKICAgIHZpZXdwb3J0Xyg1MTIuMCwgNTEyLjApLAogICAgbGlnaHRQb3NpdGlvbl8oMTAuMCwgNDAuMCwgLTYwLjApLAogICAgbGlnaHRDb2xvcl8oMC44LCAxLjMsIDEuMSwgMS4wKSwKICAgIGxpZ2h0UmFkaXVzXygyMDAuMCksCiAgICBhbWJpZW50Q29sb3JfKDAuMywgMC4yLCAxLjAsIDEuMCksCiAgICBmcmVzbmVsQ29sb3JfKDAuOCwgMC43LCAwLjYsIDEuMSksCiAgICBmcmVzbmVsUG93ZXJfKDEuMCksCiAgICByb3RhdGlvbl8oMC4wKSwKICAgIGN1cnJlbnRUaW1lXygwLjApLAogICAgbGFzdFVwZGF0ZVRpbWVfKDAuMCkKewogICAgc3RhdGljIGNvbnN0IHN0cmluZyBtb2RlbEZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL21vZGVscy9qZWxseWZpc2guam9iaiIpOwogICAgaWYgKCFsb2FkX29iaihtb2RlbEZpbGVuYW1lKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gTm93IHRoYXQgd2UndmUgc2V0dXAgdGhlIHZlcnRleCBkYXRhLCB3ZSBjYW4gc2V0dXAgdGhlIG1hcCBvZiBob3cKICAgIC8vIHRoYXQgZGF0YSB3aWxsIGJlIGxhaWQgb3V0IGluIHRoZSBidWZmZXIgb2JqZWN0LgogICAgc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBzdjMoc2l6ZW9mKHZlYzMpKTsKICAgIGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0ID0gMDsKICAgIGRhdGFNYXBfLnBvc2l0aW9uU2l6ZSA9IHBvc2l0aW9uc18uc2l6ZSgpICogc3YzOwogICAgZGF0YU1hcF8udG90YWxTaXplID0gZGF0YU1hcF8ucG9zaXRpb25TaXplOwogICAgZGF0YU1hcF8ubm9ybWFsT2Zmc2V0ID0gZGF0YU1hcF8ucG9zaXRpb25PZmZzZXQgKyBkYXRhTWFwXy5wb3NpdGlvblNpemU7CiAgICBkYXRhTWFwXy5ub3JtYWxTaXplID0gbm9ybWFsc18uc2l6ZSgpICogc3YzOwogICAgZGF0YU1hcF8udG90YWxTaXplICs9IGRhdGFNYXBfLm5vcm1hbFNpemU7CiAgICBkYXRhTWFwXy5jb2xvck9mZnNldCA9IGRhdGFNYXBfLm5vcm1hbE9mZnNldCArIGRhdGFNYXBfLm5vcm1hbFNpemU7CiAgICBkYXRhTWFwXy5jb2xvclNpemUgPSBjb2xvcnNfLnNpemUoKSAqIHN2MzsKICAgIGRhdGFNYXBfLnRvdGFsU2l6ZSArPSBkYXRhTWFwXy5jb2xvclNpemU7CiAgICBkYXRhTWFwXy50ZXhjb29yZE9mZnNldCA9IGRhdGFNYXBfLmNvbG9yT2Zmc2V0ICsgZGF0YU1hcF8uY29sb3JTaXplOwogICAgZGF0YU1hcF8udGV4Y29vcmRTaXplID0gdGV4Y29vcmRzXy5zaXplKCkgKiBzdjM7CiAgICBkYXRhTWFwXy50b3RhbFNpemUgKz0gZGF0YU1hcF8udGV4Y29vcmRTaXplOwp9CgpKZWxseWZpc2hQcml2YXRlOjp+SmVsbHlmaXNoUHJpdmF0ZSgpCnsKICAgIHBvc2l0aW9uc18uY2xlYXIoKTsKICAgIG5vcm1hbHNfLmNsZWFyKCk7CiAgICBjb2xvcnNfLmNsZWFyKCk7CiAgICB0ZXhjb29yZHNfLmNsZWFyKCk7CiAgICBpbmRpY2VzXy5jbGVhcigpOwp9Cgp2b2lkCkplbGx5ZmlzaFByaXZhdGU6OmluaXRpYWxpemUoKQp7CiAgICBsYXN0VXBkYXRlVGltZV8gPSBVdGlsOjpnZXRfdGltZXN0YW1wX3VzKCkgLyAxMDAwLjA7CiAgICBjdXJyZW50VGltZV8gPSBzdGF0aWNfY2FzdDx1aW50NjRfdD4obGFzdFVwZGF0ZVRpbWVfKSAlIDEwMDAwMDAwMCAvIDEwMDAuMDsKICAgIHdoaWNoQ2F1c3RpY18gPSBzdGF0aWNfY2FzdDx1aW50NjRfdD4oY3VycmVudFRpbWVfICogMzApICUgMzIgKyAxOwogICAgcm90YXRpb25fID0gMC4wOwoKICAgIGdyYWRpZW50Xy5pbml0KCk7CgogICAgLy8gU2V0IHVwIHByb2dyYW0gZmlyc3Qgc28gd2UgY2FuIHN0b3JlIGF0dHJpYnV0ZSBhbmQgdW5pZm9ybSBsb2NhdGlvbnMKICAgIC8vIGF3YXkgZm9yIHRoZSAKICAgIHVzaW5nIHN0ZDo6c3RyaW5nOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyB2dHhfc2hhZGVyX2ZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL3NoYWRlcnMvamVsbHlmaXNoLnZlcnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgZnJnX3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2plbGx5ZmlzaC5mcmFnIik7CgogICAgU2hhZGVyU291cmNlIHZ0eF9zb3VyY2UodnR4X3NoYWRlcl9maWxlbmFtZSk7CiAgICBTaGFkZXJTb3VyY2UgZnJnX3NvdXJjZShmcmdfc2hhZGVyX2ZpbGVuYW1lKTsKCiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHByb2dyYW1fLCB2dHhfc291cmNlLnN0cigpLAogICAgICAgIGZyZ19zb3VyY2Uuc3RyKCkpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBTdGFzaCBhd2F5IGF0dHJpYnV0ZSBhbmQgdW5pZm9ybSBsb2NhdGlvbnMgZm9yIGhhbmR5IHVzZS4KICAgIHBvc2l0aW9uTG9jYXRpb25fID0gcHJvZ3JhbV9bImFWZXJ0ZXhQb3NpdGlvbiJdLmxvY2F0aW9uKCk7CiAgICBub3JtYWxMb2NhdGlvbl8gPSBwcm9ncmFtX1siYVZlcnRleE5vcm1hbCJdLmxvY2F0aW9uKCk7CiAgICBjb2xvckxvY2F0aW9uXyA9IHByb2dyYW1fWyJhVmVydGV4Q29sb3IiXS5sb2NhdGlvbigpOwogICAgdGV4Y29vcmRMb2NhdGlvbl8gPSBwcm9ncmFtX1siYVRleHR1cmVDb29yZCJdLmxvY2F0aW9uKCk7CgogICAgLy8gV2UgbmVlZCAyIGJ1ZmZlcnMgZm9yIG91ciB3b3JrIGhlcmUuICBPbmUgZm9yIHRoZSB2ZXJ0ZXggZGF0YS4KICAgIC8vIGFuZCBvbmUgZm9yIHRoZSBpbmRleCBkYXRhLgogICAgZ2xHZW5CdWZmZXJzKDIsICZidWZmZXJPYmplY3RzX1swXSk7CgogICAgLy8gRmlyc3QsIHNldHVwIHRoZSB2ZXJ0ZXggZGF0YSBieSBiaW5kaW5nIHRoZSBmaXJzdCBidWZmZXIgb2JqZWN0LCAKICAgIC8vIGFsbG9jYXRpbmcgaXRzIGRhdGEgc3RvcmUsIGFuZCBmaWxsaW5nIGl0IGluIHdpdGggb3VyIHZlcnRleCBkYXRhLgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMF0pOwogICAgZ2xCdWZmZXJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgZGF0YU1hcF8udG90YWxTaXplLCAwLCBHTF9TVEFUSUNfRFJBVyk7CiAgICBnbEJ1ZmZlclN1YkRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy5wb3NpdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICBkYXRhTWFwXy5wb3NpdGlvblNpemUsICZwb3NpdGlvbnNfLmZyb250KCkpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgZGF0YU1hcF8ubm9ybWFsT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgIGRhdGFNYXBfLm5vcm1hbFNpemUsICZub3JtYWxzXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLmNvbG9yT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgIGRhdGFNYXBfLmNvbG9yU2l6ZSwgJmNvbG9yc18uZnJvbnQoKSk7CiAgICBnbEJ1ZmZlclN1YkRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy50ZXhjb29yZE9mZnNldCwKICAgICAgICAgICAgICAgICAgICBkYXRhTWFwXy50ZXhjb29yZFNpemUsICZ0ZXhjb29yZHNfLmZyb250KCkpOwoKICAgIC8vIE5vdyByZXBlYXQgZm9yIG91ciBpbmRleCBkYXRhLgogICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1sxXSk7CiAgICBnbEJ1ZmZlckRhdGEoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGluZGljZXNfLnNpemUoKSAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCksCiAgICAgICAgICAgICAgICAgJmluZGljZXNfLmZyb250KCksIEdMX1NUQVRJQ19EUkFXKTsKCiAgICAvLyAiVW5iaW5kIiBvdXIgYnVmZmVyIG9iamVjdHMgdG8gbWFrZSBzdXJlIHRoZSBzdGF0ZSBpcyBjb25zaXN0ZW50LgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIDApOwoKICAgIC8vIEZpbmFsbHksIHNldCB1cCBvdXIgdGV4dHVyZXMuCiAgICAvLwogICAgLy8gRmlyc3QsIHRoZSBtYWluIGplbGx5ZmlzaCB0ZXh0dXJlCiAgICBib29sIGdvdFRleCA9IFRleHR1cmU6OmxvYWQoImplbGx5ZmlzaDI1NiIsICZ0ZXh0dXJlT2JqZWN0c19bMF0sIEdMX0xJTkVBUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9MSU5FQVIsIDApOwogICAgaWYgKCFnb3RUZXggfHwgdGV4dHVyZU9iamVjdHNfWzBdID09IDApCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiSmVsbHlmaXNoIHRleHR1cmUgc2V0IHVwIGZhaWxlZCEhIVxuIik7CiAgICB9CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgLy8gVGhlbiwgdGhlIGNhdXN0aWNzIHRleHR1cmVzCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGJhc2VOYW1lKCJqZWxseWZpc2gtY2F1c3RpY3MtIik7CiAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMTsgaSA8IDMzOyBpKyspCiAgICB7CiAgICAgICAgc3RkOjpzdHJpbmdzdHJlYW0gc3M7CiAgICAgICAgc3MgPDwgc3RkOjpzZXR3KDIpIDw8IHN0ZDo6c2V0ZmlsbCgnMCcpIDw8IGk7CiAgICAgICAgc3RyaW5nIGN1ck5hbWUoYmFzZU5hbWUpOwogICAgICAgIGN1ck5hbWUgKz0gc3Muc3RyKCk7CiAgICAgICAgZ290VGV4ID0gVGV4dHVyZTo6bG9hZChjdXJOYW1lLCAmdGV4dHVyZU9iamVjdHNfW2ldLCBHTF9MSU5FQVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9MSU5FQVIsIDApOwogICAgICAgIGlmICghZ290VGV4IHx8IHRleHR1cmVPYmplY3RzX1tpXSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgTG9nOjplcnJvcigiQ2F1c3RpY3MgdGV4dHVyZVsldV0gc2V0IHVwIGZhaWxlZCEhIVxuIiwgaSk7CiAgICAgICAgfQogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfUkVQRUFUKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX1JFUEVBVCk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgIH0KfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjp1cGRhdGVfdmlld3BvcnQoY29uc3QgdmVjMiYgdnApCnsKICAgIGlmICh2aWV3cG9ydF8ueCgpID09IHZwLngoKSAmJiB2aWV3cG9ydF8ueSgpID09IHZwLnkoKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB2aWV3cG9ydF8gPSB2cDsKICAgIHByb2plY3Rpb25fLmxvYWRJZGVudGl0eSgpOwogICAgcHJvamVjdGlvbl8ucGVyc3BlY3RpdmUoMzAuMCwgdmlld3BvcnRfLngoKS92aWV3cG9ydF8ueSgpLCAyMC4wLCAxMjAuMCk7ICAgIAp9Cgp2b2lkCkplbGx5ZmlzaFByaXZhdGU6OnVwZGF0ZV90aW1lKCkKewogICAgZG91YmxlIG5vdyA9IFV0aWw6OmdldF90aW1lc3RhbXBfdXMoKSAvIDEwMDAuMDsKICAgIGRvdWJsZSBlbGFwc2VkVGltZSA9IG5vdyAtIGxhc3RVcGRhdGVUaW1lXzsKICAgIHJvdGF0aW9uXyArPSAoMi4wICogZWxhcHNlZFRpbWUpIC8gMTAwMC4wOwogICAgY3VycmVudFRpbWVfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KG5vdykgJSAxMDAwMDAwMDAgLyAxMDAwLjA7CiAgICB3aGljaENhdXN0aWNfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KGN1cnJlbnRUaW1lXyAqIDMwKSAlIDMyICsgMTsKICAgIGxhc3RVcGRhdGVUaW1lXyA9IG5vdzsKfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjpjbGVhbnVwKCkKewogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwogICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKCiAgICBnbERlbGV0ZVRleHR1cmVzKDMzLCAmdGV4dHVyZU9iamVjdHNfWzBdKTsKICAgIGdsRGVsZXRlQnVmZmVycygyLCAmYnVmZmVyT2JqZWN0c19bMF0pOwoKICAgIGdyYWRpZW50Xy5jbGVhbnVwKCk7Cn0KCnZvaWQKSmVsbHlmaXNoUHJpdmF0ZTo6ZHJhdygpCnsKICAgIC8vICJDbGVhciIgdGhlIGJhY2tncm91bmQgdG8gdGhlIGRlc2lyZWQgZ3JhZGllbnQuCiAgICBncmFkaWVudF8uZHJhdygpOwoKICAgIC8vIFdlIG5lZWQgIndvcmxkIiwgIndvcmxkIHZpZXcgcHJvamVjdGlvbiIsIGFuZCAid29ybGQgaW52ZXJzZSB0cmFuc3Bvc2UiCiAgICAvLyBtYXRyaXggdW5pZm9ybXMgZm9yIHRoZSBjdXJyZW50IHNoYWRlci4KICAgIC8vCiAgICAvLyBOT1RFOiBTb21lIG9mIHRoaXMgc2VlbXMgYSBiaXQgb2YgYSBuby1vcCAoZS5nLiwgbXVsdGlweWluZyBieSBhbmQKICAgIC8vICAgICAgIGludmVydGluZyBpZGVudGl0eSBtYXRyaWNlcyksIGJ1dCBsZWF2ZSBpdCBsaWtlIHRoZSBvcmlnaW5hbAogICAgLy8gICAgICAgV2ViR0wgZmlsZXMgZm9yIHRoZSB0aW1lIGJlaW5nLiAgV29ydGggcmV2aXNpdGluZyBub3QgZG9pbmcgYWxsCiAgICAvLyAgICAgICBvZiB0aGF0IG1hdGggZXZlcnkgZHJhdyBjYWxsIChtaWdodCBldmVuIGJlIGdvb2QgdG8gYmUgZG9pbmcKICAgIC8vICAgICAgIHNvbWUgb2YgaXQgaW4gdGhlIHNoYWRlciBhcyB3ZWxsKS4KICAgIHdvcmxkXy5wdXNoKCk7CiAgICB3b3JsZF8udHJhbnNsYXRlKDAuMCwgNS4wLCAtNzUuMCk7CiAgICB3b3JsZF8ucm90YXRlKHNpbihyb3RhdGlvbl8gLyAxMC4wKSAqIDMwLjAsIDAuMCwgMS4wLCAwLjApOwogICAgd29ybGRfLnJvdGF0ZShzaW4ocm90YXRpb25fIC8gMjAuMCkgKiAzMC4wLCAxLjAsIDAuMCwgMC4wKTsKICAgIHdvcmxkXy5zY2FsZSg1LjAsIDUuMCwgNS4wKTsKICAgIHdvcmxkXy50cmFuc2xhdGUoMC4wLCBzaW4ocm90YXRpb25fIC8gMTAuMCkgKiAyLjUsIDAuMCk7CiAgICBtYXQ0IHdvcmxkVmlld1Byb2plY3Rpb24ocHJvamVjdGlvbl8uZ2V0Q3VycmVudCgpKTsKICAgIHdvcmxkVmlld1Byb2plY3Rpb24gKj0gd29ybGRfLmdldEN1cnJlbnQoKTs7CiAgICBtYXQ0IHdvcmxkSW52ZXJzZVRyYW5zcG9zZSh3b3JsZF8uZ2V0Q3VycmVudCgpKTsKICAgIHdvcmxkSW52ZXJzZVRyYW5zcG9zZS5pbnZlcnNlKCkudHJhbnNwb3NlKCk7CgogICAgLy8gTG9hZCB1cCB0aGUgdW5pZm9ybXMKICAgIHByb2dyYW1fLnN0YXJ0KCk7CiAgICBwcm9ncmFtX1sidVdvcmxkIl0gPSB3b3JsZF8uZ2V0Q3VycmVudCgpOwogICAgcHJvZ3JhbV9bInVXb3JsZFZpZXdQcm9qIl0gPSB3b3JsZFZpZXdQcm9qZWN0aW9uOwogICAgcHJvZ3JhbV9bInVXb3JsZEludlRyYW5zcG9zZSJdID0gd29ybGRJbnZlcnNlVHJhbnNwb3NlOwogICAgcHJvZ3JhbV9bInVDdXJyZW50VGltZSJdID0gY3VycmVudFRpbWVfOwogICAgLy8gUmV2aXNpdCBtYWtpbmcgdGhlc2UgY29uc3RhbnRzIHJhdGhlciB0aGFuIHVuaWZvcm1zIGFzIHRoZXkgYXBwZWFyIG5ldmVyCiAgICAvLyB0byBjaGFuZ2UKICAgIHByb2dyYW1fWyJ1TGlnaHRQb3MiXSA9IGxpZ2h0UG9zaXRpb25fOwogICAgcHJvZ3JhbV9bInVMaWdodFJhZGl1cyJdID0gbGlnaHRSYWRpdXNfOwogICAgcHJvZ3JhbV9bInVMaWdodENvbCJdID0gbGlnaHRDb2xvcl87CiAgICBwcm9ncmFtX1sidUFtYmllbnRDb2wiXSA9IGFtYmllbnRDb2xvcl87CiAgICBwcm9ncmFtX1sidUZyZXNuZWxDb2wiXSA9IGZyZXNuZWxDb2xvcl87CiAgICBwcm9ncmFtX1sidUZyZXNuZWxQb3dlciJdID0gZnJlc25lbFBvd2VyXzsKICAgIC8vIFNldCB1cCB0ZXh0dXJlcyBmb3IgdGhpcyBmcmFtZS4KICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMCk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVPYmplY3RzX1swXSk7CiAgICBwcm9ncmFtX1sidVNhbXBsZXIiXSA9IDA7CiAgICBnbEFjdGl2ZVRleHR1cmUoR0xfVEVYVFVSRTEpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXh0dXJlT2JqZWN0c19bd2hpY2hDYXVzdGljX10pOwogICAgcHJvZ3JhbV9bInVTYW1wbGVyMSJdID0gMTsKCiAgICBnbEVuYWJsZShHTF9CTEVORCk7CiAgICBnbEJsZW5kRnVuYyhHTF9TUkNfQUxQSEEsIEdMX09ORV9NSU5VU19TUkNfQUxQSEEpOwoKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzBdKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwoKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShub3JtYWxMb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShjb2xvckxvY2F0aW9uXyk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleGNvb3JkTG9jYXRpb25fKTsKICAgIGdsVmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uXyAsIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0KSk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIobm9ybWFsTG9jYXRpb25fICwgMywgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oZGF0YU1hcF8ubm9ybWFsT2Zmc2V0KSk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIoY29sb3JMb2NhdGlvbl8gLCAzLCBHTF9GTE9BVCwgR0xfRkFMU0UsIDAsCiAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBHTHZvaWQqPihkYXRhTWFwXy5jb2xvck9mZnNldCkpOwogICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKHRleGNvb3JkTG9jYXRpb25fICwgMywgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oZGF0YU1hcF8udGV4Y29vcmRPZmZzZXQpKTsKCiAgICBnbERyYXdFbGVtZW50cyhHTF9UUklBTkdMRVMsIGluZGljZXNfLnNpemUoKSwgR0xfVU5TSUdORURfU0hPUlQsIDApOwoKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb25fKTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KG5vcm1hbExvY2F0aW9uXyk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShjb2xvckxvY2F0aW9uXyk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheSh0ZXhjb29yZExvY2F0aW9uXyk7CgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIDApOwoKICAgIHByb2dyYW1fLnN0b3AoKTsKICAgIHdvcmxkXy5wb3AoKTsKfQo=