LyoKICogKGMpIENvcHlyaWdodCAxOTkzLCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCiAqIENvcHlyaWdodCCpIDIwMTIgTGluYXJvIExpbWl0ZWQKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIGdsbWFyazIgT3BlbkdMIChFUykgMi4wIGJlbmNobWFyay4KICoKICogZ2xtYXJrMiBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyCiAqIHZlcnNpb24uCiAqCiAqIGdsbWFyazIgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCiAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZQogKiBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoCiAqIGdsbWFyazIuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCiAqCiAqIEF1dGhvcnM6CiAqICBKZXNzZSBCYXJrZXIKICovCiNpbmNsdWRlICJzY2VuZS5oIgojaW5jbHVkZSAic3RhY2suaCIKI2luY2x1ZGUgInNwbGluZXMuaCIKI2luY2x1ZGUgInRhYmxlLmgiCiNpbmNsdWRlICJsb2dvLmgiCiNpbmNsdWRlICJsYW1wLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgPHN5cy90aW1lLmg+Cgp1c2luZyBMaWJNYXRyaXg6OlN0YWNrNDsKdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzM7CnVzaW5nIExpYk1hdHJpeDo6dmVjNDsKdXNpbmcgTGliTWF0cml4Ojp1dmVjMzsKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIHN0ZDo6bWFwOwoKY2xhc3MgU2NlbmVJZGVhc1ByaXZhdGUKewpwdWJsaWM6CiAgICBTY2VuZUlkZWFzUHJpdmF0ZSgpIDoKICAgICAgICB2YWxpZF8oZmFsc2UpLAogICAgICAgIGN1cnJlbnRTcGVlZF8oMS4wKSwgLy8gUmVhbCB0aW1lLgogICAgICAgIGN1cnJlbnRUaW1lXyhTVEFSVF9USU1FXyksCiAgICAgICAgdGltZU9mZnNldF8oU1RBUlRfVElNRV8pCiAgICB7CiAgICAgICAgc3RhcnRUaW1lXy50dl9zZWMgPSAwOwogICAgICAgIHN0YXJ0VGltZV8udHZfdXNlYyA9IDA7IAogICAgfQogICAgflNjZW5lSWRlYXNQcml2YXRlKCkKICAgIHsKICAgIH0KICAgIHZvaWQgaW5pdGlhbGl6ZShtYXA8c3RyaW5nLCBTY2VuZTo6T3B0aW9uPiYgb3B0aW9ucyk7CiAgICB2b2lkIHJlc2V0X3RpbWUoKTsKICAgIHZvaWQgdXBkYXRlX3RpbWUoKTsKICAgIHZvaWQgdXBkYXRlX3Byb2plY3Rpb24oY29uc3QgbWF0NCYgcHJvaik7CiAgICB2b2lkIGRyYXcoKTsKCnByaXZhdGU6CiAgICB2b2lkIHBvc3RJZGxlKCk7CiAgICB2b2lkIGluaXRMaWdodHMoKTsKICAgIGJvb2wgdmFsaWRfOwogICAgU3RhY2s0IHByb2plY3Rpb25fOwogICAgU3RhY2s0IG1vZGVsdmlld187CiAgICBmbG9hdCBjdXJyZW50U3BlZWRfOwogICAgZmxvYXQgY3VycmVudFRpbWVfOwogICAgZmxvYXQgdGltZU9mZnNldF87CiAgICBzdHJ1Y3QgdGltZXZhbCBzdGFydFRpbWVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IENZQ0xFX1RJTUVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IFRJTUVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IFNUQVJUX1RJTUVfOwogICAgLy8gVGFibGUKICAgIFRhYmxlIHRhYmxlXzsKICAgIC8vIExvZ28KICAgIFNHSUxvZ28gbG9nb187CiAgICAvLyBMYW1wCiAgICBMYW1wIGxhbXBfOwogICAgLy8gTGlnaHQgY29uc3RhbnRzCiAgICBzdGF0aWMgY29uc3QgdmVjNCBsaWdodDBfcG9zaXRpb25fOwogICAgc3RhdGljIGNvbnN0IHZlYzQgbGlnaHQxX3Bvc2l0aW9uXzsKICAgIHN0YXRpYyBjb25zdCB2ZWM0IGxpZ2h0Ml9wb3NpdGlvbl87CiAgICAvLyBPYmplY3QgY29uc3RhbnRzCiAgICBWaWV3RnJvbVNwbGluZSB2aWV3RnJvbVNwbGluZV87CiAgICBWaWV3VG9TcGxpbmUgdmlld1RvU3BsaW5lXzsKICAgIExpZ2h0UG9zaXRpb25TcGxpbmUgbGlnaHRQb3NTcGxpbmVfOwogICAgTG9nb1Bvc2l0aW9uU3BsaW5lIGxvZ29Qb3NTcGxpbmVfOwogICAgTG9nb1JvdGF0aW9uU3BsaW5lIGxvZ29Sb3RTcGxpbmVfOwogICAgdmVjMyB2aWV3RnJvbV87CiAgICB2ZWMzIHZpZXdUb187CiAgICB2ZWMzIGxpZ2h0UG9zXzsKICAgIHZlYzMgbG9nb1Bvc187CiAgICB2ZWMzIGxvZ29Sb3RfOwogICAgdmVjNCBsaWdodFBvc2l0aW9uc19bM107Cn07Cgpjb25zdCBmbG9hdCBTY2VuZUlkZWFzUHJpdmF0ZTo6VElNRV8oMTUuMCk7CmNvbnN0IGZsb2F0IFNjZW5lSWRlYXNQcml2YXRlOjpDWUNMRV9USU1FXyhUSU1FXyAqIDEuMCAtIDMuMCk7CmNvbnN0IGZsb2F0IFNjZW5lSWRlYXNQcml2YXRlOjpTVEFSVF9USU1FXygwLjYpOwpjb25zdCB2ZWM0IFNjZW5lSWRlYXNQcml2YXRlOjpsaWdodDBfcG9zaXRpb25fKDAuMCwgMS4wLCAwLjAsIDAuMCk7CmNvbnN0IHZlYzQgU2NlbmVJZGVhc1ByaXZhdGU6OmxpZ2h0MV9wb3NpdGlvbl8oLTEuMCwgMC4wLCAwLjAsIDAuMCk7CmNvbnN0IHZlYzQgU2NlbmVJZGVhc1ByaXZhdGU6OmxpZ2h0Ml9wb3NpdGlvbl8oMC4wLCAtMS4wLCAwLjAsIDAuMCk7Cgp2b2lkClNjZW5lSWRlYXNQcml2YXRlOjppbml0TGlnaHRzKCkKewogICAgY29uc3QgbWF0NCYgY3VyTVYobW9kZWx2aWV3Xy5nZXRDdXJyZW50KCkpOwogICAgbGlnaHRQb3NpdGlvbnNfWzBdID0gY3VyTVYgKiBsaWdodDBfcG9zaXRpb25fOwogICAgbGlnaHRQb3NpdGlvbnNfWzFdID0gY3VyTVYgKiBsaWdodDFfcG9zaXRpb25fOwogICAgbGlnaHRQb3NpdGlvbnNfWzJdID0gY3VyTVYgKiBsaWdodDJfcG9zaXRpb25fOwp9Cgp2b2lkClNjZW5lSWRlYXNQcml2YXRlOjppbml0aWFsaXplKG1hcDxzdHJpbmcsIFNjZW5lOjpPcHRpb24+JiBvcHRpb25zKQp7CiAgICAvLyBJbml0aWFsaXplIHRoZSBwb3NpdGlvbnMgZm9yIHRoZSBsaWdodHMgd2UnbGwgdXNlLgogICAgaW5pdExpZ2h0cygpOwoKICAgIC8vIFRlbGwgdGhlIG9iamVjdHMgaW4gdGhlIHNjZW5lIHRvIGluaXRpYWxpemUgdGhlbXNlbHZlcy4KICAgIHRhYmxlXy5pbml0KCk7CiAgICBpZiAoIXRhYmxlXy52YWxpZCgpKQogICAgewogICAgICAgIExvZzo6ZGVidWcoIlNjZW5lSWRlYXM6IHRhYmxlIG9iamVjdCBub3QgcHJvcGVybHkgaW5pdGlhbGl6ZWQhXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBsb2dvXy5pbml0KCk7CiAgICBpZiAoIWxvZ29fLnZhbGlkKCkpCiAgICB7CiAgICAgICAgTG9nOjpkZWJ1ZygiU2NlbmVJZGVhczogbG9nbyBvYmplY3Qgbm90IHByb3Blcmx5IGluaXRpYWxpemVkIVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbGFtcF8uaW5pdCgpOwogICAgaWYgKCFsYW1wXy52YWxpZCgpKQogICAgewogICAgICAgIExvZzo6ZGVidWcoIlNjZW5lSWRlYXM6IGxhbXAgb2JqZWN0IG5vdCBwcm9wZXJseSBpbml0aWFsaXplZCFcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICByZXNldF90aW1lKCk7CgogICAgLy8gSWYgdGhlIG9wdGlvbiBzdHJpbmcgdGVsbHMgdXMgdGhlIHVzZXIgd2FudHMgdGhlIHNwZWVkIHRvIGJlIGEgZnVuY3Rpb24KICAgIC8vIG9mIHRoZSBzY2VuZSBkdXJhdGlvbiwgZG8gaXQuICBPdGhlcndpc2UsIHRha2UgdGhlIHZhbHVlIGV4cGxpY2l0bHkuCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGR1cmF0aW9uTGFiZWwoImR1cmF0aW9uIik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHNwZWVkTGFiZWwoInNwZWVkIik7CiAgICBpZiAob3B0aW9uc1tzcGVlZExhYmVsXS52YWx1ZSA9PSBkdXJhdGlvbkxhYmVsKQogICAgewogICAgICAgIGZsb2F0IGR1cmF0aW9uID0gVXRpbDo6ZnJvbVN0cmluZzxmbG9hdD4ob3B0aW9uc1tkdXJhdGlvbkxhYmVsXS52YWx1ZSk7CiAgICAgICAgY3VycmVudFNwZWVkXyA9IChDWUNMRV9USU1FXyAtIFNUQVJUX1RJTUVfKSAvIGR1cmF0aW9uOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGN1cnJlbnRTcGVlZF8gPSBVdGlsOjpmcm9tU3RyaW5nPGZsb2F0PihvcHRpb25zW3NwZWVkTGFiZWxdLnZhbHVlKTsKICAgIH0KCiAgICAvLyBJZiB3ZSdyZSBoZXJlLCB3ZSdyZSBva2F5IHRvIHJ1bi4KICAgIHZhbGlkXyA9IHRydWU7Cn0KCnZvaWQKU2NlbmVJZGVhc1ByaXZhdGU6OnJlc2V0X3RpbWUoKQp7CiAgICB0aW1lT2Zmc2V0XyA9IFNUQVJUX1RJTUVfOwogICAgZ2V0dGltZW9mZGF5KCZzdGFydFRpbWVfLCBOVUxMKTsKfQoKdm9pZApTY2VuZUlkZWFzUHJpdmF0ZTo6dXBkYXRlX3RpbWUoKQp7CiAgICAvLyBDb21wdXRlIG5ldyB0aW1lCiAgICBzdHJ1Y3QgdGltZXZhbCBjdXJyZW50ID0gezAsIDB9OwogICAgZ2V0dGltZW9mZGF5KCZjdXJyZW50LCBOVUxMKTsKICAgIGZsb2F0IHRpbWVkaWZmID0gKGN1cnJlbnQudHZfc2VjIC0gc3RhcnRUaW1lXy50dl9zZWMpICsgCiAgICAgICAgc3RhdGljX2Nhc3Q8ZG91YmxlPihjdXJyZW50LnR2X3VzZWMgLSBzdGFydFRpbWVfLnR2X3VzZWMpIC8gMTAwMDAwMC4wOwogICAgZmxvYXQgc2NlbmVUaW1lID0gdGltZWRpZmYgKiBjdXJyZW50U3BlZWRfICsgdGltZU9mZnNldF87CgogICAgLy8gS2VlcCB0aGUgY3VycmVudCB0aW1lIGluIFtTVEFSVF9USU1FXy4uQ1lDTEVfVElNRV8pCiAgICAvLyBFdmVyeSBvdGhlciBjeWNsZSBzdGFydGluZyB3aXRoIDAgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBhbmQgZ29lcwogICAgLy8gZm9yd2FyZCBpbiB0aW1lLiAgT3RoZXIgY3ljbGVzIHN0YXJ0IGF0IHRoZSBlbmQgYW5kIGdvIGJhY2t3YXJkcy4KICAgIGN1cnJlbnRUaW1lXyA9IHN0ZDo6Zm1vZChzY2VuZVRpbWUsIENZQ0xFX1RJTUVfKTsKICAgIHVuc2lnbmVkIGludCBjeWNsZSA9IHNjZW5lVGltZS9DWUNMRV9USU1FXzsKICAgIGlmIChjeWNsZSAlIDIpCiAgICB7CiAgICAgICAgY3VycmVudFRpbWVfID0gQ1lDTEVfVElNRV8gLSBjdXJyZW50VGltZV87CiAgICB9Cn0KCnZvaWQKU2NlbmVJZGVhc1ByaXZhdGU6OnVwZGF0ZV9wcm9qZWN0aW9uKGNvbnN0IG1hdDQmIHByb2opCnsKICAgIC8vIFByb2plY3Rpb24gaGFzbid0IGNoYW5nZWQgc2luY2UgbGFzdCBmcmFtZS4KICAgIGlmIChwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCkgPT0gcHJvaikKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcHJvamVjdGlvbl8ubG9hZElkZW50aXR5KCk7CiAgICBwcm9qZWN0aW9uXyAqPSBwcm9qOwp9CgpTY2VuZUlkZWFzOjpTY2VuZUlkZWFzKENhbnZhcyYgY2FudmFzKSA6CiAgICBTY2VuZShjYW52YXMsICJpZGVhcyIpLCBwcml2XygwKQp7CiAgICBvcHRpb25zX1sic3BlZWQiXSA9IFNjZW5lOjpPcHRpb24oInNwZWVkIiwgImR1cmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGltZSBjb2VmZmljaWVudCAoMS4wIGlzIFwid2FsbCBjbG9ja1wiIHNwZWVkLCA8MS4wIGlzIHNsb3dlciwgPjEuMCBpcyBmYXN0ZXIpLiAgQSBzcGVjaWFsIHZhbHVlIG9mIFwiZHVyYXRpb25cIiBjb21wdXRlcyB0aGlzIGFzIGEgZnVuY3Rpb24gb2YgdGhlIFwiZHVyYXRpb25cIiBvcHRpb24iKTsKfQoKU2NlbmVJZGVhczo6flNjZW5lSWRlYXMoKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVJZGVhczo6bG9hZCgpCnsKICAgIHJ1bm5pbmdfID0gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZUlkZWFzOjp1bmxvYWQoKQp7Cn0KCnZvaWQKU2NlbmVJZGVhczo6c2V0dXAoKQp7CiAgICBTY2VuZTo6c2V0dXAoKTsKICAgIHByaXZfID0gbmV3IFNjZW5lSWRlYXNQcml2YXRlKCk7CiAgICBwcml2Xy0+aW5pdGlhbGl6ZShvcHRpb25zXyk7CiAgICBwcml2Xy0+dXBkYXRlX3Byb2plY3Rpb24oY2FudmFzXy5wcm9qZWN0aW9uKCkpOwoKICAgIC8vIENvcmUgU2NlbmUgc3RhdGUKICAgIGN1cnJlbnRGcmFtZV8gPSAwOwogICAgcnVubmluZ18gPSB0cnVlOwogICAgc3RhcnRUaW1lXyA9IFV0aWw6OmdldF90aW1lc3RhbXBfdXMoKSAvIDEwMDAwMDAuMDsKICAgIGxhc3RVcGRhdGVUaW1lXyA9IHN0YXJ0VGltZV87Cn0KCnZvaWQKU2NlbmVJZGVhczo6dXBkYXRlKCkKewogICAgU2NlbmU6OnVwZGF0ZSgpOwogICAgcHJpdl8tPnVwZGF0ZV90aW1lKCk7CiAgICBwcml2Xy0+dXBkYXRlX3Byb2plY3Rpb24oY2FudmFzXy5wcm9qZWN0aW9uKCkpOwp9Cgp2b2lkClNjZW5lSWRlYXNQcml2YXRlOjpkcmF3KCkKewogICAgdmlld0Zyb21TcGxpbmVfLmdldEN1cnJlbnRWZWMoY3VycmVudFRpbWVfLCB2aWV3RnJvbV8pOwogICAgdmlld1RvU3BsaW5lXy5nZXRDdXJyZW50VmVjKGN1cnJlbnRUaW1lXywgdmlld1RvXyk7CiAgICBsaWdodFBvc1NwbGluZV8uZ2V0Q3VycmVudFZlYyhjdXJyZW50VGltZV8sIGxpZ2h0UG9zXyk7CiAgICBsb2dvUG9zU3BsaW5lXy5nZXRDdXJyZW50VmVjKGN1cnJlbnRUaW1lXywgbG9nb1Bvc18pOwogICAgbG9nb1JvdFNwbGluZV8uZ2V0Q3VycmVudFZlYyhjdXJyZW50VGltZV8sIGxvZ29Sb3RfKTsKCiAgICAvLyBUZWxsIHRoZSBsb2dvIGl0cyBuZXcgcG9zaXRpb24KICAgIGxvZ29fLnNldFBvc2l0aW9uKGxvZ29Qb3NfKTsKCiAgICB2ZWM0IGxwNChsaWdodFBvc18ueCgpLCBsaWdodFBvc18ueSgpLCBsaWdodFBvc18ueigpLCAwLjApOwoKICAgIC8vCiAgICAvLyBTSEFET1cKICAgIC8vCiAgICBtb2RlbHZpZXdfLmxvYWRJZGVudGl0eSgpOwogICAgbW9kZWx2aWV3Xy5sb29rQXQodmlld0Zyb21fLngoKSwgdmlld0Zyb21fLnkoKSwgdmlld0Zyb21fLnooKSwgCiAgICAgICAgICAgICAgICAgICAgICB2aWV3VG9fLngoKSwgdmlld1RvXy55KCksIHZpZXdUb18ueigpLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAxLjAsIDAuMCk7CgogICAgZmxvYXQgcGNhKDAuMCk7CiAgICBpZiAodmlld0Zyb21fLnkoKSA+IDAuMCkKICAgIHsKICAgICAgICB0YWJsZV8uZHJhdyhtb2RlbHZpZXdfLCBwcm9qZWN0aW9uXywgbGlnaHRQb3NfLCBsb2dvUG9zXywgY3VycmVudFRpbWVfLCBwY2EpOwogICAgfQoKICAgIGdsRW5hYmxlKEdMX0NVTExfRkFDRSk7IAogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOyAKCiAgICBpZiAobG9nb1Bvc18ueSgpIDwgMC4wKQogICAgewogICAgICAgIC8vIFNldCB0aGUgY29sb3IgYXNzdW1pbmcgd2UncmUgc3RpbGwgdW5kZXIgdGhlIHRhYmxlLgogICAgICAgIHV2ZWMzIGZsYXRDb2xvcigxMjggLyAyLCAgMTAyIC8gMiwgIDE3OSAvIDIpOwogICAgICAgIGlmIChsb2dvUG9zXy55KCkgPiAtMC4zMykKICAgICAgICB7CiAgICAgICAgICAgIC8vIFdlJ3JlIGVtZXJnaW5nIGZyb20gdGhlIHRhYmxlCiAgICAgICAgICAgIGZsb2F0IGMoMS4wIC0gbG9nb1Bvc18ueSgpIC8gLTAuMzMpOwogICAgICAgICAgICBwY2EgLz0gNC4wOwogICAgICAgICAgICBmbGF0Q29sb3IueChzdGF0aWNfY2FzdDx1bnNpZ25lZCBpbnQ+KDEyOC4wICogKDEuMCAtIGMpICogMC41ICsgMjU1LjAgKiBwY2EgKiBjKSk7CiAgICAgICAgICAgIGZsYXRDb2xvci55KHN0YXRpY19jYXN0PHVuc2lnbmVkIGludD4oMTAyLjAgKiAoMS4wIC0gYykgKiAwLjUgKyAyNTUuMCAqIHBjYSAqIGMpKTsKICAgICAgICAgICAgZmxhdENvbG9yLnooc3RhdGljX2Nhc3Q8dW5zaWduZWQgaW50PigxNzkuMCAqICgxLjAgLSBjKSAqIDAuNSArIDIwMC4wICogcGNhICogYykpOwogICAgICAgIH0KCiAgICAgICAgbW9kZWx2aWV3Xy5wdXNoKCk7CiAgICAgICAgbW9kZWx2aWV3Xy5zY2FsZSgwLjA0LCAwLjAsIDAuMDQpOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKC05MC4wLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy56KCkpLCAwLjAsIDAuMCwgMS4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy55KCkpLCAwLjAsIDEuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy54KCkpLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiAzNTMsIDEuMCwgMC4wLCAwLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIDQ1MCwgMC4wLCAxLjAsIDAuMCk7CgogICAgICAgIGxvZ29fLmRyYXcobW9kZWx2aWV3XywgcHJvamVjdGlvbl8sIGxpZ2h0UG9zaXRpb25zX1swXSwgU0dJTG9nbzo6TE9HT19GTEFULCBmbGF0Q29sb3IpOwoKICAgICAgICBtb2RlbHZpZXdfLnBvcCgpOwogICAgfQogICAgCiAgICBpZiAobG9nb1Bvc18ueSgpID4gMC4wKQogICAgewogICAgICAgIG1vZGVsdmlld18ucHVzaCgpOwogICAgICAgIG1vZGVsdmlld18udHJhbnNsYXRlKGxpZ2h0UG9zXy54KCksIGxpZ2h0UG9zXy55KCksIGxpZ2h0UG9zXy56KCkpOwogICAgICAgIG1hdDQgdHY7CiAgICAgICAgdHZbM11bMV0gPSAtMS4wOwogICAgICAgIHR2WzNdWzNdID0gMC4wOwogICAgICAgIHR2WzBdWzBdID0gdHZbMV1bMV0gPSB0dlsyXVsyXSA9IGxpZ2h0UG9zXy55KCk7CiAgICAgICAgbW9kZWx2aWV3XyAqPSB0djsKICAgICAgICBtb2RlbHZpZXdfLnRyYW5zbGF0ZSgtbGlnaHRQb3NfLngoKSArIGxvZ29Qb3NfLngoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtbGlnaHRQb3NfLnkoKSArIGxvZ29Qb3NfLnkoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtbGlnaHRQb3NfLnooKSArIGxvZ29Qb3NfLnooKSk7CiAgICAgICAgbW9kZWx2aWV3Xy5zY2FsZSgwLjA0LCAwLjA0LCAwLjA0KTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgtOTAuMCwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueigpKSwgMC4wLCAwLjAsIDEuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueSgpKSwgMC4wLCAxLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueCgpKSwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMzUuMywgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoNDUuMCwgMC4wLCAxLjAsIDAuMCk7CgogICAgICAgIGxvZ29fLmRyYXcobW9kZWx2aWV3XywgcHJvamVjdGlvbl8sIGxpZ2h0UG9zaXRpb25zX1swXSwgU0dJTG9nbzo6TE9HT19TSEFET1cpOwoKICAgICAgICBtb2RlbHZpZXdfLnBvcCgpOwogICAgfQogICAgLy8KICAgIC8vIERPTkUgU0hBRE9XIAogICAgLy8KCiAgICBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwoKICAgIG1vZGVsdmlld18ubG9hZElkZW50aXR5KCk7CiAgICBtb2RlbHZpZXdfLmxvb2tBdCh2aWV3RnJvbV8ueCgpLCB2aWV3RnJvbV8ueSgpLCB2aWV3RnJvbV8ueigpLAogICAgICAgICAgICAgICAgICAgICAgdmlld1RvXy54KCksIHZpZXdUb18ueSgpLCB2aWV3VG9fLnooKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLjAsIDEuMCwgMC4wKTsKICAgIG1vZGVsdmlld18ucHVzaCgpOwogICAgbW9kZWx2aWV3Xy50cmFuc2xhdGUobGlnaHRQb3NfLngoKSwgbGlnaHRQb3NfLnkoKSwgbGlnaHRQb3NfLnooKSk7CiAgICBtb2RlbHZpZXdfLnNjYWxlKDAuMSwgMC4xLCAwLjEpOwogICAgZmxvYXQgeChsaWdodFBvc18ueCgpIC0gbG9nb1Bvc18ueCgpKTsKICAgIGZsb2F0IHkobGlnaHRQb3NfLnkoKSAtIGxvZ29Qb3NfLnkoKSk7CiAgICBmbG9hdCB6KGxpZ2h0UG9zXy56KCkgLSBsb2dvUG9zXy56KCkpOwogICAgZG91YmxlIGEzKDAuMCk7CiAgICBpZiAoeCAhPSAwLjApCiAgICB7CiAgICAgICAgYTMgPSAtYXRhbjIoeiwgeCkgKiAxMC4wICogMTgwLjAgLyBNX1BJOwogICAgfQogICAgZG91YmxlIGE0KC1hdGFuMihzcXJ0KHggKiB4ICsgeiAqIHopLCB5KSAqIDEwLjAgKiAxODAuMCAvIE1fUEkpOwogICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PihhMyksIDAuMCwgMS4wLCAwLjApOwogICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PihhNCksIDAuMCwgMC4wLCAxLjApOwogICAgbW9kZWx2aWV3Xy5yb3RhdGUoLTkwLjAsIDEuMCwgMC4wLCAwLjApOwoKICAgIGxhbXBfLmRyYXcobW9kZWx2aWV3XywgcHJvamVjdGlvbl8sIGxpZ2h0UG9zaXRpb25zXyk7CgogICAgbW9kZWx2aWV3Xy5wb3AoKTsKICAgIAogICAgbGlnaHRQb3NpdGlvbnNfWzBdID0gbW9kZWx2aWV3Xy5nZXRDdXJyZW50KCkgKiBscDQ7CiAgICAKICAgIGlmIChsb2dvUG9zXy55KCkgPiAtMC4zMykKICAgIHsKICAgICAgICBtb2RlbHZpZXdfLnB1c2goKTsKICAgICAgICBtb2RlbHZpZXdfLnRyYW5zbGF0ZShsb2dvUG9zXy54KCksIGxvZ29Qb3NfLnkoKSwgbG9nb1Bvc18ueigpKTsKICAgICAgICBtb2RlbHZpZXdfLnNjYWxlKDAuMDQsIDAuMDQsIDAuMDQpOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKC05MC4wLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy56KCkpLCAwLjAsIDAuMCwgMS4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy55KCkpLCAwLjAsIDEuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiBzdGF0aWNfY2FzdDxpbnQ+KDEwLjAgKiBsb2dvUm90Xy54KCkpLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgzNS4zLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSg0NS4wLCAwLjAsIDEuMCwgMC4wKTsKCiAgICAgICAgbG9nb18uZHJhdyhtb2RlbHZpZXdfLCBwcm9qZWN0aW9uXywgbGlnaHRQb3NpdGlvbnNfWzBdLCBTR0lMb2dvOjpMT0dPX05PUk1BTCk7CgogICAgICAgIG1vZGVsdmlld18ucG9wKCk7CiAgICB9CiAgICAKICAgIGlmICh2aWV3RnJvbV8ueSgpIDwgMC4wKQogICAgewogICAgICAgIHRhYmxlXy5kcmF3VW5kZXIobW9kZWx2aWV3XywgcHJvamVjdGlvbl8pOwogICAgfQp9Cgp2b2lkClNjZW5lSWRlYXM6OmRyYXcoKQp7CiAgICBwcml2Xy0+ZHJhdygpOwp9CgpTY2VuZTo6VmFsaWRhdGlvblJlc3VsdApTY2VuZUlkZWFzOjp2YWxpZGF0ZSgpCnsKICAgIHJldHVybiBTY2VuZTo6VmFsaWRhdGlvblVua25vd247Cn0KCnZvaWQKU2NlbmVJZGVhczo6dGVhcmRvd24oKQp7CiAgICBkZWxldGUgcHJpdl87CiAgICBwcml2XyA9IDA7CiAgICBTY2VuZTo6dGVhcmRvd24oKTsKfQo=