LyoKICogKGMpIENvcHlyaWdodCAxOTkzLCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCiAqIENvcHlyaWdodCCpIDIwMTIgTGluYXJvIExpbWl0ZWQKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIGdsbWFyazIgT3BlbkdMIChFUykgMi4wIGJlbmNobWFyay4KICoKICogZ2xtYXJrMiBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyCiAqIHZlcnNpb24uCiAqCiAqIGdsbWFyazIgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCiAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZQogKiBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoCiAqIGdsbWFyazIuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCiAqCiAqIEF1dGhvcnM6CiAqICBKZXNzZSBCYXJrZXIKICovCiNpbmNsdWRlICJ0YWJsZS5oIgojaW5jbHVkZSAic2NlbmUuaCIKI2luY2x1ZGUgInNoYWRlci1zb3VyY2UuaCIKI2luY2x1ZGUgImxvZy5oIgoKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIExpYk1hdHJpeDo6dmVjMzsKdXNpbmcgTGliTWF0cml4OjpTdGFjazQ7Cgpjb25zdCBzdHJpbmcgVGFibGU6Om1vZGVsdmlld05hbWVfKCJtb2RlbHZpZXciKTsKY29uc3Qgc3RyaW5nIFRhYmxlOjpwcm9qZWN0aW9uTmFtZV8oInByb2plY3Rpb24iKTsKY29uc3Qgc3RyaW5nIFRhYmxlOjpsaWdodFBvc2l0aW9uTmFtZV8oImxpZ2h0UG9zaXRpb24iKTsKY29uc3Qgc3RyaW5nIFRhYmxlOjpsb2dvRGlyZWN0aW9uTmFtZV8oImxvZ29EaXJlY3Rpb24iKTsKY29uc3Qgc3RyaW5nIFRhYmxlOjpjdXJUaW1lTmFtZV8oImN1cnJlbnRUaW1lIik7CmNvbnN0IHN0cmluZyBUYWJsZTo6dmVydGV4QXR0cmliTmFtZV8oInZlcnRleCIpOwpjb25zdCB1bnNpZ25lZCBpbnQgVGFibGU6OlRBQkxFUkVTXygxMik7CmNvbnN0IHZlYzMgVGFibGU6OnBhcGVyVmVydGljZXNfWzRdID0gewogICAgdmVjMygtMC44LCAwLjAsIDAuNCksCiAgICB2ZWMzKC0wLjIsIDAuMCwgLTEuNCksCiAgICB2ZWMzKDAuNCwgMC4wLCAwLjgpLAogICAgdmVjMygxLjAsIDAuMCwgLTEuMCksCn07CgpUYWJsZTo6VGFibGUoKSA6CiAgICB0YWJsZVZlcnRleEluZGV4XygwKSwKICAgIHBhcGVyVmVydGV4SW5kZXhfKDApLAogICAgdGV4dFZlcnRleEluZGV4XygwKSwKICAgIHVuZGVyVmVydGV4SW5kZXhfKDApLAogICAgdmFsaWRfKGZhbHNlKQp7CiAgICB0YWJsZVZlcnRpY2VzXy5yZXNlcnZlKChUQUJMRVJFU18gKyAxKSAqIChUQUJMRVJFU18gKyAxKSk7CiAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8PSBUQUJMRVJFU187IGkrKykKICAgIHsKICAgICAgICBmb3IgKHVuc2lnbmVkIGludCBqID0gMDsgaiA8PSBUQUJMRVJFU187IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGZsb2F0IHgoKHN0YXRpY19jYXN0PGZsb2F0PihpKSAtIHN0YXRpY19jYXN0PGZsb2F0PihUQUJMRVJFU18pICogMS4wIC8gMi4wKSAvIDIuMCk7CiAgICAgICAgICAgIGZsb2F0IHooKHN0YXRpY19jYXN0PGZsb2F0PihqKSAtIHN0YXRpY19jYXN0PGZsb2F0PihUQUJMRVJFU18pICogMS4wIC8gMi4wKSAvIDIuMCk7CiAgICAgICAgICAgIHRhYmxlVmVydGljZXNfLnB1c2hfYmFjayh2ZWMzKHgsIDAuMCwgeikpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBOb3cgdGhhdCB3ZSd2ZSBzZXR1cCB0aGUgdmVydGV4IGRhdGEsIHdlIGNhbiBzZXR1cCB0aGUgbWFwIG9mIGhvdwogICAgLy8gdGhhdCBkYXRhIHdpbGwgYmUgbGFpZCBvdXQgaW4gdGhlIGJ1ZmZlciBvYmplY3QuCiAgICBkYXRhTWFwXy50dk9mZnNldCA9IDA7CiAgICBkYXRhTWFwXy50dlNpemUgPSB0YWJsZVZlcnRpY2VzXy5zaXplKCkgKiBzaXplb2YodmVjMyk7CiAgICBkYXRhTWFwXy50b3RhbFNpemUgPSBkYXRhTWFwXy50dlNpemU7CiAgICBkYXRhTWFwXy5wdk9mZnNldCA9IGRhdGFNYXBfLnR2T2Zmc2V0ICsgZGF0YU1hcF8udHZTaXplOwogICAgZGF0YU1hcF8ucHZTaXplID0gNCAqIHNpemVvZih2ZWMzKTsKICAgIGRhdGFNYXBfLnRvdGFsU2l6ZSArPSBkYXRhTWFwXy5wdlNpemU7CgogICAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBUQUJMRVJFU187IGkrKykKICAgIHsKICAgICAgICBmb3IgKHVuc2lnbmVkIGludCBqID0gMDsgaiA8PSBUQUJMRVJFU187IGorKykKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBjdXJJbmRleDEoaSAqIChUQUJMRVJFU18gKyAxKSArIGopOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgY3VySW5kZXgyKChpICsgMSkgKiAoVEFCTEVSRVNfICsgMSkgKyBqKTsKICAgICAgICAgICAgaW5kZXhEYXRhXy5wdXNoX2JhY2soY3VySW5kZXgxKTsKICAgICAgICAgICAgaW5kZXhEYXRhXy5wdXNoX2JhY2soY3VySW5kZXgyKTsKICAgICAgICB9CiAgICB9Cn0KClRhYmxlOjp+VGFibGUodm9pZCkKewogICAgaWYgKHZhbGlkXykKICAgIHsKICAgICAgICBnbERlbGV0ZUJ1ZmZlcnMoMiwgJmJ1ZmZlck9iamVjdHNfWzBdKTsKICAgIH0KfQoKdm9pZApUYWJsZTo6aW5pdCh2b2lkKQp7CiAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgcmUtaW5pdGlhbGl6ZS4uLgogICAgaWYgKHZhbGlkXykKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gSW5pdGlhbGl6ZSBzaGFkZXIgc291cmNlcyBmcm9tIGlucHV0IGZpbGVzIGFuZCBjcmVhdGUgcHJvZ3JhbXMgZnJvbSB0aGVtCiAgICAvLyBQcm9ncmFtIHRvIHJlbmRlciB0aGUgdGFibGUgd2l0aCBsaWdodGluZyBhbmQgYSB0aW1lLWJhc2VkIGZhZGUuLi4KICAgIHN0cmluZyB0YWJsZV92dHhfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9pZGVhcy10YWJsZS52ZXJ0Iik7CiAgICBzdHJpbmcgdGFibGVfZnJnX2ZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL3NoYWRlcnMvaWRlYXMtdGFibGUuZnJhZyIpOwogICAgU2hhZGVyU291cmNlIHRhYmxlX3Z0eF9zb3VyY2UodGFibGVfdnR4X2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSB0YWJsZV9mcmdfc291cmNlKHRhYmxlX2ZyZ19maWxlbmFtZSk7CiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHRhYmxlUHJvZ3JhbV8sIHRhYmxlX3Z0eF9zb3VyY2Uuc3RyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2ZyZ19zb3VyY2Uuc3RyKCkpKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIk5vIHZhbGlkIHByb2dyYW0gZm9yIHRhYmxlIHJlbmRlcmluZy5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRleHRWZXJ0ZXhJbmRleF8gPSB0YWJsZVByb2dyYW1fW3ZlcnRleEF0dHJpYk5hbWVfXS5sb2NhdGlvbigpOwoKICAgIC8vIFByb2dyYW0gdG8gcmVuZGVyIHRoZSBwYXBlciB3aXRoIGxpZ2h0aW5nIGFuZCBhIHRpbWUtYmFzZWQgZmFkZS4uLgogICAgc3RyaW5nIHBhcGVyX3Z0eF9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2lkZWFzLXBhcGVyLnZlcnQiKTsKICAgIHN0cmluZyBwYXBlcl9mcmdfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9pZGVhcy1wYXBlci5mcmFnIik7CiAgICBTaGFkZXJTb3VyY2UgcGFwZXJfdnR4X3NvdXJjZShwYXBlcl92dHhfZmlsZW5hbWUpOwogICAgU2hhZGVyU291cmNlIHBhcGVyX2ZyZ19zb3VyY2UocGFwZXJfZnJnX2ZpbGVuYW1lKTsKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3MocGFwZXJQcm9ncmFtXywgcGFwZXJfdnR4X3NvdXJjZS5zdHIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFwZXJfZnJnX3NvdXJjZS5zdHIoKSkpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiTm8gdmFsaWQgcHJvZ3JhbSBmb3IgcGFwZXIgcmVuZGVyaW5nLlxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcGFwZXJWZXJ0ZXhJbmRleF8gPSBwYXBlclByb2dyYW1fW3ZlcnRleEF0dHJpYk5hbWVfXS5sb2NhdGlvbigpOwoKICAgIC8vIFByb2dyYW0gdG8gaGFuZGxlIHRoZSB0ZXh0ICh0aW1lLWJhc2VkIGNvbG9yIGZhZGUpLi4uCiAgICBzdHJpbmcgdGV4dF92dHhfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9pZGVhcy10ZXh0LnZlcnQiKTsKICAgIHN0cmluZyB0ZXh0X2ZyZ19maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2lkZWFzLXRleHQuZnJhZyIpOwogICAgU2hhZGVyU291cmNlIHRleHRfdnR4X3NvdXJjZSh0ZXh0X3Z0eF9maWxlbmFtZSk7CiAgICBTaGFkZXJTb3VyY2UgdGV4dF9mcmdfc291cmNlKHRleHRfZnJnX2ZpbGVuYW1lKTsKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3ModGV4dFByb2dyYW1fLCB0ZXh0X3Z0eF9zb3VyY2Uuc3RyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRfZnJnX3NvdXJjZS5zdHIoKSkpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiTm8gdmFsaWQgcHJvZ3JhbSBmb3IgdGV4dCByZW5kZXJpbmcuXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB0ZXh0VmVydGV4SW5kZXhfID0gdGV4dFByb2dyYW1fW3ZlcnRleEF0dHJpYk5hbWVfXS5sb2NhdGlvbigpOwoKICAgIC8vIFByb2dyYW0gZm9yIHRoZSBkcmF3VW5kZXIgZnVuY3Rpb25hbGl0eSAoanVzdCBwYWludCBpdCBibGFjaykuLi4KICAgIHN0cmluZyB1bmRlcl90YWJsZV92dHhfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9pZGVhcy11bmRlci10YWJsZS52ZXJ0Iik7CiAgICBzdHJpbmcgdW5kZXJfdGFibGVfZnJnX2ZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL3NoYWRlcnMvaWRlYXMtdW5kZXItdGFibGUuZnJhZyIpOwogICAgU2hhZGVyU291cmNlIHVuZGVyX3RhYmxlX3Z0eF9zb3VyY2UodW5kZXJfdGFibGVfdnR4X2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSB1bmRlcl90YWJsZV9mcmdfc291cmNlKHVuZGVyX3RhYmxlX2ZyZ19maWxlbmFtZSk7CiAgICBpZiAoIVNjZW5lOjpsb2FkX3NoYWRlcnNfZnJvbV9zdHJpbmdzKHVuZGVyUHJvZ3JhbV8sIHVuZGVyX3RhYmxlX3Z0eF9zb3VyY2Uuc3RyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVyX3RhYmxlX2ZyZ19zb3VyY2Uuc3RyKCkpKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIk5vIHZhbGlkIHByb2dyYW0gZm9yIHVuZGVyIHRhYmxlIHJlbmRlcmluZy5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHVuZGVyVmVydGV4SW5kZXhfID0gdW5kZXJQcm9ncmFtX1t2ZXJ0ZXhBdHRyaWJOYW1lX10ubG9jYXRpb24oKTsKCiAgICAvLyBUZWxsIGFsbCBvZiB0aGUgY2hhcmFjdGVycyB0byBpbml0aWFsaXplIHRoZW1zZWx2ZXMuLi4KICAgIGlfLmluaXQodGV4dFZlcnRleEluZGV4Xyk7CiAgICBkXy5pbml0KHRleHRWZXJ0ZXhJbmRleF8pOwogICAgZV8uaW5pdCh0ZXh0VmVydGV4SW5kZXhfKTsKICAgIGFfLmluaXQodGV4dFZlcnRleEluZGV4Xyk7CiAgICBzXy5pbml0KHRleHRWZXJ0ZXhJbmRleF8pOwogICAgbl8uaW5pdCh0ZXh0VmVydGV4SW5kZXhfKTsKICAgIG1fLmluaXQodGV4dFZlcnRleEluZGV4Xyk7CiAgICBvXy5pbml0KHRleHRWZXJ0ZXhJbmRleF8pOwogICAgdF8uaW5pdCh0ZXh0VmVydGV4SW5kZXhfKTsKCiAgICAvLyBXZSBuZWVkIDIgYnVmZmVycyBmb3Igb3VyIHdvcmsgaGVyZS4gIE9uZSBmb3IgdGhlIHZlcnRleCBkYXRhLgogICAgLy8gYW5kIG9uZSBmb3IgdGhlIGluZGV4IGRhdGEuCiAgICBnbEdlbkJ1ZmZlcnMoMiwgJmJ1ZmZlck9iamVjdHNfWzBdKTsKCiAgICAvLyBGaXJzdCwgc2V0dXAgdGhlIHZlcnRleCBkYXRhIGJ5IGJpbmRpbmcgdGhlIGZpcnN0IGJ1ZmZlciBvYmplY3QsIAogICAgLy8gYWxsb2NhdGluZyBpdHMgZGF0YSBzdG9yZSwgYW5kIGZpbGxpbmcgaXQgaW4gd2l0aCBvdXIgdmVydGV4IGRhdGEuCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1swXSk7CiAgICBnbEJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy50b3RhbFNpemUsIDAsIEdMX1NUQVRJQ19EUkFXKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLnR2T2Zmc2V0LCBkYXRhTWFwXy50dlNpemUsIAogICAgICAgICAgICAgICAgICAgICZ0YWJsZVZlcnRpY2VzXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLnB2T2Zmc2V0LCBkYXRhTWFwXy5wdlNpemUsCiAgICAgICAgICAgICAgICAgICAgJnBhcGVyVmVydGljZXNfWzBdKTsKCiAgICAvLyBOb3cgcmVwZWF0IGZvciBvdXIgaW5kZXggZGF0YS4KICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwogICAgZ2xCdWZmZXJEYXRhKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBpbmRleERhdGFfLnNpemUoKSAqIHNpemVvZih1bnNpZ25lZCBzaG9ydCksCiAgICAgICAgICAgICAgICAgJmluZGV4RGF0YV8uZnJvbnQoKSwgR0xfU1RBVElDX0RSQVcpOwoKICAgIC8vIFdlJ3JlIHJlYWR5IHRvIGdvLgogICAgdmFsaWRfID0gdHJ1ZTsKfQoKdm9pZApUYWJsZTo6ZHJhdyhTdGFjazQmIG1vZGVsdmlldywKICAgIFN0YWNrNCYgcHJvamVjdGlvbiwKICAgIGNvbnN0IHZlYzMmIGxpZ2h0UG9zLAogICAgY29uc3QgdmVjMyYgbG9nb1BvcywKICAgIGNvbnN0IGZsb2F0JiBjdXJyZW50VGltZSwKICAgIGZsb2F0JiBwYXBlckFscGhhX291dCkKewogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwoKICAgIC8vIENvbXB1dGUgdGhlIGxpZ2h0IGRpcmVjdGlvbiB3aXRoIHJlc3BlY3QgdG8gdGhlIGxvZ28uLi4KICAgIHZlYzMgbG9nb0RpcmVjdGlvbihsaWdodFBvcy54KCkgLSBsb2dvUG9zLngoKSwgbGlnaHRQb3MueSgpIC0gbG9nb1Bvcy55KCksIAogICAgICAgIGxpZ2h0UG9zLnooKSAtIGxvZ29Qb3MueigpKTsKICAgIGxvZ29EaXJlY3Rpb24ubm9ybWFsaXplKCk7CgogICAgLy8gQ29tcHV0ZSB0aGUgYWxwaGEgY29tcG9uZW50IGJhc2VkIHVwb24gZHJhd2luZyB0aGUgcGFwZXIgKGFsbCBvZiB0aGlzIHdpbGwKICAgIC8vIGJlIGRvbmUgaW4gdGhlIHNoYWRlciwgYnV0IHdlIG5lZWQgdG8gcGFzcyB0aGlzIGJhY2sgc28gdGhhdCB0aGUgbG9nbydzCiAgICAvLyBzaGFkb3cgd2lsbCBsb29rIHJpZ2h0KS4KICAgIGZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpIDwgNDsgaSsrKQogICAgewogICAgICAgIHZlYzMgbGlnaHREaXJlY3Rpb24obGlnaHRQb3MueCgpIC0gcGFwZXJWZXJ0aWNlc19baV0ueCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHRQb3MueSgpIC0gcGFwZXJWZXJ0aWNlc19baV0ueSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlnaHRQb3MueigpIC0gcGFwZXJWZXJ0aWNlc19baV0ueigpKTsKICAgICAgICBsaWdodERpcmVjdGlvbi5ub3JtYWxpemUoKTsKICAgICAgICBmbG9hdCBjID0gdmVjMzo6ZG90KGxpZ2h0RGlyZWN0aW9uLCBsb2dvRGlyZWN0aW9uKTsKICAgICAgICBpZiAoYyA8IDAuMCkKICAgICAgICB7CiAgICAgICAgICAgIGMgPSAwLjA7CiAgICAgICAgfQogICAgICAgIGMgPSBjICogYyAqIGMgKiBsaWdodERpcmVjdGlvbi55KCk7CiAgICAgICAgaWYgKChjdXJyZW50VGltZSA+IDEwLjApICYmIChjdXJyZW50VGltZSA8IDEyLjApKQogICAgICAgIHsKICAgICAgICAgICAgYyAqPSAxLjAgLSAoY3VycmVudFRpbWUgLSAxMC4wKSAqIDAuNTsKICAgICAgICB9CiAgICAgICAgcGFwZXJBbHBoYV9vdXQgKz0gYzsKICAgIH0KCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1swXSk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzFdKTsKCiAgICAvLyBEcmF3IHRoZSB0YWJsZSB0b3AKICAgIHRhYmxlUHJvZ3JhbV8uc3RhcnQoKTsKICAgIHRhYmxlUHJvZ3JhbV9bcHJvamVjdGlvbk5hbWVfXSA9IHByb2plY3Rpb24uZ2V0Q3VycmVudCgpOwogICAgdGFibGVQcm9ncmFtX1ttb2RlbHZpZXdOYW1lX10gPSBtb2RlbHZpZXcuZ2V0Q3VycmVudCgpOwogICAgdGFibGVQcm9ncmFtX1tsaWdodFBvc2l0aW9uTmFtZV9dID0gbGlnaHRQb3M7CiAgICB0YWJsZVByb2dyYW1fW2xvZ29EaXJlY3Rpb25OYW1lX10gPSBsb2dvRGlyZWN0aW9uOwogICAgdGFibGVQcm9ncmFtX1tjdXJUaW1lTmFtZV9dID0gY3VycmVudFRpbWU7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIodGFibGVWZXJ0ZXhJbmRleF8sIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnR2T2Zmc2V0KSk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRhYmxlVmVydGV4SW5kZXhfKTsKICAgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdHdpY2VSZXMoMiAqIChUQUJMRVJFU18gKyAxKSk7CiAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IFRBQkxFUkVTXzsgaSsrKQogICAgewogICAgICAgIGdsRHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFX1NUUklQLCB0d2ljZVJlcywgR0xfVU5TSUdORURfU0hPUlQsCiAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oaSAqIHR3aWNlUmVzICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSkpOwogICAgfQogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkodGFibGVWZXJ0ZXhJbmRleF8pOwogICAgdGFibGVQcm9ncmFtXy5zdG9wKCk7CgogICAgaWYgKGxvZ29Qb3MueSgpID4gLTAuMzMgJiYgbG9nb1Bvcy55KCkgPCAwLjMzKQogICAgewogICAgICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgfQoKICAgIC8vIERyYXcgdGhlIHBhcGVyIGx5aW5nIG9uIHRoZSB0YWJsZSB0b3AKICAgIHBhcGVyUHJvZ3JhbV8uc3RhcnQoKTsKICAgIHBhcGVyUHJvZ3JhbV9bcHJvamVjdGlvbk5hbWVfXSA9IHByb2plY3Rpb24uZ2V0Q3VycmVudCgpOwogICAgcGFwZXJQcm9ncmFtX1ttb2RlbHZpZXdOYW1lX10gPSBtb2RlbHZpZXcuZ2V0Q3VycmVudCgpOwogICAgcGFwZXJQcm9ncmFtX1tsaWdodFBvc2l0aW9uTmFtZV9dID0gbGlnaHRQb3M7CiAgICBwYXBlclByb2dyYW1fW2xvZ29EaXJlY3Rpb25OYW1lX10gPSBsb2dvRGlyZWN0aW9uOwogICAgcGFwZXJQcm9ncmFtX1tjdXJUaW1lTmFtZV9dID0gY3VycmVudFRpbWU7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIocGFwZXJWZXJ0ZXhJbmRleF8sIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnB2T2Zmc2V0KSk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBhcGVyVmVydGV4SW5kZXhfKTsKICAgIGdsRHJhd0FycmF5cyhHTF9UUklBTkdMRV9TVFJJUCwgMCwgNCk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShwYXBlclZlcnRleEluZGV4Xyk7CiAgICBwYXBlclByb2dyYW1fLnN0b3AoKTsKCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAwKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgMCk7CgogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwoKICAgIG1vZGVsdmlldy5wdXNoKCk7CiAgICBtb2RlbHZpZXcucm90YXRlKC0xOC40LCAwLjAsIDEuMCwgMC4wKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoLTAuMywgMC4wLCAtMC44KTsKICAgIG1vZGVsdmlldy5yb3RhdGUoLTkwLjAsIDEuMCwgMC4wLCAwLjApOwogICAgbW9kZWx2aWV3LnNjYWxlKDAuMDE1LCAwLjAxNSwgMC4wMTUpOwoKICAgIC8vIERyYXcgdGhlIHRleHQgb24gdGhlIHBhcGVyIGx5aW5nIG9uIHRoZSB0YWJsZSB0b3AuCiAgICAvLyBFYWNoIGNoYXJhY3RlciBoYXMgaXRzIG93biBhcnJheSBhbmQgZWxlbWVudCBidWZmZXJzLCBhbmQgdGhleSBoYXZlCiAgICAvLyBiZWVuIGluaXRpYWxpemVkIHdpdGggdGhlIHZlcnRleCBhdHRyaWIgbG9jYXRpb24gZm9yIHRoaXMgcHJvZ3JhbS4KICAgIHRleHRQcm9ncmFtXy5zdGFydCgpOwogICAgdGV4dFByb2dyYW1fW3Byb2plY3Rpb25OYW1lX10gPSBwcm9qZWN0aW9uLmdldEN1cnJlbnQoKTsKICAgIHRleHRQcm9ncmFtX1ttb2RlbHZpZXdOYW1lX10gPSBtb2RlbHZpZXcuZ2V0Q3VycmVudCgpOwogICAgdGV4dFByb2dyYW1fW2N1clRpbWVOYW1lX10gPSBjdXJyZW50VGltZTsKICAgIGlfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoMy4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIGRfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNi4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIGVfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNS4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIGFfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNi4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIHNfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoMTAuMCwgMC4wLCAwLjApOwogICAgdGV4dFByb2dyYW1fW21vZGVsdmlld05hbWVfXSA9IG1vZGVsdmlldy5nZXRDdXJyZW50KCk7CiAgICBpXy5kcmF3KCk7CiAgICBtb2RlbHZpZXcudHJhbnNsYXRlKDMuMCwgMC4wLCAwLjApOwogICAgdGV4dFByb2dyYW1fW21vZGVsdmlld05hbWVfXSA9IG1vZGVsdmlldy5nZXRDdXJyZW50KCk7CiAgICBuXy5kcmF3KCk7CiAgICBtb2RlbHZpZXcudHJhbnNsYXRlKC0zMS4wLCAtMTMuMCwgMC4wKTsKICAgIHRleHRQcm9ncmFtX1ttb2RlbHZpZXdOYW1lX10gPSBtb2RlbHZpZXcuZ2V0Q3VycmVudCgpOwogICAgbV8uZHJhdygpOwogICAgbW9kZWx2aWV3LnRyYW5zbGF0ZSgxMC4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIG9fLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNS4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIHRfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNC4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIGlfLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoMy41LCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIG9fLmRyYXcoKTsKICAgIG1vZGVsdmlldy50cmFuc2xhdGUoNS4wLCAwLjAsIDAuMCk7CiAgICB0ZXh0UHJvZ3JhbV9bbW9kZWx2aWV3TmFtZV9dID0gbW9kZWx2aWV3LmdldEN1cnJlbnQoKTsKICAgIG5fLmRyYXcoKTsKICAgIHRleHRQcm9ncmFtXy5zdG9wKCk7CgogICAgbW9kZWx2aWV3LnBvcCgpOwp9Cgp2b2lkClRhYmxlOjpkcmF3VW5kZXIoU3RhY2s0JiBtb2RlbHZpZXcsIFN0YWNrNCYgcHJvamVjdGlvbikKewogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzBdKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwoKICAgIHVuZGVyUHJvZ3JhbV8uc3RhcnQoKTsgIAogICAgdW5kZXJQcm9ncmFtX1ttb2RlbHZpZXdOYW1lX10gPSBtb2RlbHZpZXcuZ2V0Q3VycmVudCgpOwogICAgdW5kZXJQcm9ncmFtX1twcm9qZWN0aW9uTmFtZV9dID0gcHJvamVjdGlvbi5nZXRDdXJyZW50KCk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIodW5kZXJWZXJ0ZXhJbmRleF8sIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnR2T2Zmc2V0KSk7CiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHVuZGVyVmVydGV4SW5kZXhfKTsKICAgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgdHdpY2VSZXMoMiAqIChUQUJMRVJFU18gKyAxKSk7CiAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IFRBQkxFUkVTXzsgaSsrKQogICAgewogICAgICAgIGdsRHJhd0VsZW1lbnRzKEdMX1RSSUFOR0xFX1NUUklQLCB0d2ljZVJlcywgR0xfVU5TSUdORURfU0hPUlQsCiAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oaSAqIHR3aWNlUmVzICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSkpOwogICAgfQogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkodW5kZXJWZXJ0ZXhJbmRleF8pOwogICAgdW5kZXJQcm9ncmFtXy5zdG9wKCk7CgogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIDApOwoKICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOyAKfQo=