/
www
/
wwwroot
/
alo88.autos
/
wp-content
/
plugins
/
wp-content-crawler
/
app
/
public
/
Upload File
HOME
PD9waHAKLyoqCiAqIENyZWF0ZWQgYnkgUGhwU3Rvcm0uCiAqIFVzZXI6IHR1cmd1dHNhcmljYW0KICogRGF0ZTogMTgvMDQvMTYKICogVGltZTogMDg6MzMKICovCgpuYW1lc3BhY2UgV1BDQ3Jhd2xlcjsKCnVzZSBEYXRlVGltZTsKdXNlIEV4Y2VwdGlvbjsKCmlmKCFjbGFzc19leGlzdHMoJ1dQVFNMTUNsaWVudCcpKSB7CgpmaW5hbCBjbGFzcyBXUFRTTE1DbGllbnQgewoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkcHJvZHVjdE5hbWU7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRwcm9kdWN0SWQ7CgogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICR0eXBlOwoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkYXBpVXJsOwoKICAgIC8qKiBAdmFyIHN0cmluZ3xudWxsICovCiAgICBwcml2YXRlICRwbHVnaW5GaWxlUGF0aDsKCiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJHRleHREb21haW47CgogICAgLyoqIEB2YXIgY2FsbGFibGV8bnVsbCAqLwogICAgcHJpdmF0ZSAkaXNQcm9kdWN0UGFnZUNhbGxiYWNrID0gbnVsbDsKCiAgICAvKiogQHZhciBib29sfG51bGwgKi8KICAgIHByaXZhdGUgJGFkbWluTm90aWNlSGlkZGVuID0gbnVsbDsKCiAgICAvKiogQHZhciBudWxsfERhdGVUaW1lICovCiAgICBwcml2YXRlICRsYXN0UmVxdWVzdERhdGUgPSBudWxsOwoKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkbXlzcWxEYXRlVGltZUZvcm1hdCA9ICdZLW0tZCBIOmk6cyc7CgogICAgLyoqIEB2YXIgbnVsbHxzdHJpbmcgKi8KICAgIHByaXZhdGUgJHVybEhvd1RvRmluZExpY2Vuc2VLZXkgPSBudWxsOwoKICAgIC8qKiBAdmFyIGJvb2wgKi8KICAgIHByaXZhdGUgJGNhbGxlZEZyb21BY3RpdmF0aW9uSG9vayA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRwcm9kdWN0TmFtZQogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRwcm9kdWN0SWQKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdHlwZSAgICAgICAgICAgJ3BsdWdpbicgb3IgJ3RoZW1lJwogICAgICogQHBhcmFtIHN0cmluZyAgICAgICRhcGlVcmwKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkcGx1Z2luRmlsZVBhdGggUmVxdWlyZWQgb25seSBpZiB0aGlzIGlzIGEgcGx1Z2luLiBGdWxsIHBhdGggZm9yIHRoZSBwbHVnaW4gZmlsZS4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkdGV4dERvbWFpbiAgICAgVGV4dCBkb21haW4gb2YgdGhlIHBsdWdpbi90aGVtZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KHN0cmluZyAkcHJvZHVjdE5hbWUsIHN0cmluZyAkcHJvZHVjdElkLCBzdHJpbmcgJHR5cGUsIHN0cmluZyAkYXBpVXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID9zdHJpbmcgJHBsdWdpbkZpbGVQYXRoLCBzdHJpbmcgJHRleHREb21haW4pIHsKICAgICAgICAkdGhpcy0+cHJvZHVjdE5hbWUgICAgICA9ICRwcm9kdWN0TmFtZTsKICAgICAgICAkdGhpcy0+cHJvZHVjdElkICAgICAgICA9ICRwcm9kdWN0SWQ7CiAgICAgICAgJHRoaXMtPnR5cGUgICAgICAgICAgICAgPSAkdHlwZTsKICAgICAgICAkdGhpcy0+YXBpVXJsICAgICAgICAgICA9ICRhcGlVcmw7CiAgICAgICAgJHRoaXMtPnBsdWdpbkZpbGVQYXRoICAgPSAkcGx1Z2luRmlsZVBhdGg7CiAgICAgICAgJHRoaXMtPnRleHREb21haW4gICAgICAgPSAkdGV4dERvbWFpbjsKCiAgICAgICAgJHRoaXMtPmluaXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkdXJsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRVcmxIb3dUb0ZpbmRMaWNlbnNlS2V5KD9zdHJpbmcgJHVybCk6IHZvaWQgewogICAgICAgICR0aGlzLT51cmxIb3dUb0ZpbmRMaWNlbnNlS2V5ID0gJHVybDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFVybEhvd1RvRmluZExpY2Vuc2VLZXkoKTogP3N0cmluZyB7CiAgICAgICAgcmV0dXJuICR0aGlzLT51cmxIb3dUb0ZpbmRMaWNlbnNlS2V5OwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaW5pdCgpOiB2b2lkIHsKICAgICAgICAkdGhpcy0+cmVnaXN0ZXJJbnRlcnZhbHMoKTsKICAgICAgICBpZighd3BfbmV4dF9zY2hlZHVsZWQoJHRoaXMtPmdldEV2ZW50TmFtZSgpKSkgJHRoaXMtPnNjaGVkdWxlRXZlbnRzKCk7CgogICAgICAgIGFkZF9hY3Rpb24oJHRoaXMtPmdldEV2ZW50TmFtZSgpLCBbJHRoaXMsICd2YWxpZGF0ZSddKTsKICAgICAgICAkdGhpcy0+bWF5YmVSdW4oKTsKCiAgICAgICAgaWYgKCR0aGlzLT5wbHVnaW5GaWxlUGF0aCAhPT0gbnVsbCkgewogICAgICAgICAgICByZWdpc3Rlcl9hY3RpdmF0aW9uX2hvb2soJHRoaXMtPnBsdWdpbkZpbGVQYXRoLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5jYWxsZWRGcm9tQWN0aXZhdGlvbkhvb2sgPSB0cnVlOwogICAgICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlKCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+Y2FsbGVkRnJvbUFjdGl2YXRpb25Ib29rID0gZmFsc2U7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZWdpc3Rlcl9kZWFjdGl2YXRpb25faG9vaygkdGhpcy0+cGx1Z2luRmlsZVBhdGgsIFskdGhpcywgJ2RlYWN0aXZhdGUnXSk7CiAgICAgICAgfQoKICAgICAgICAkdmFsaWQgPSAkdGhpcy0+Z2V0VmFsaWQoKTsKICAgICAgICBpZigkdmFsaWQgIT09ICcwJyAmJiAkdmFsaWQgIT09ICcxJyAmJiAkdmFsaWQgIT09IG51bGwpIHsKICAgICAgICAgICAgJGR0ID0gbmV3IERhdGVUaW1lKCR2YWxpZCk7CiAgICAgICAgICAgICRub3cgPSAkdGhpcy0+Z2V0Tm93QXNEYXRlVGltZSgpOwogICAgICAgICAgICBpZigkZHQgPD0gJG5vdykgJHRoaXMtPnNldFZhbGlkKCcwJyk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgbGljZW5zZSBtZW51CiAgICAgICAgYWRkX2FjdGlvbignYWRtaW5fbWVudScsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvLyBDcmVhdGUgc3ViIG1lbnUgcGFnZQogICAgICAgICAgICBhZGRfb3B0aW9uc19wYWdlKAogICAgICAgICAgICAgICAgX18oJ0xpY2Vuc2UgU2V0dGluZ3MnLCAkdGhpcy0+dGV4dERvbWFpbiksCiAgICAgICAgICAgICAgICBzcHJpbnRmKF9fKCclcyBMaWNlbnNlIFNldHRpbmdzJywgJHRoaXMtPnRleHREb21haW4pLCAkdGhpcy0+Z2V0UHJvZHVjdE5hbWUoKSksCiAgICAgICAgICAgICAgICAnbWFuYWdlX29wdGlvbnMnLAogICAgICAgICAgICAgICAgJHRoaXMtPmdldFBhZ2VTbHVnKCksCiAgICAgICAgICAgICAgICBmdW5jdGlvbigpIHsgJHRoaXMtPnJlbmRlckxpY2Vuc2VTZXR0aW5nc1BhZ2UoKTsgfQogICAgICAgICAgICApOwogICAgICAgIH0sIDMpOwoKICAgICAgICAvLyBBZGQgYSBub3RpY2UgZm9yIHRoZSB1c2VyIHRvIHJlbWluZCB0aGF0IGxpY2Vuc2Ugc2V0dGluZ3Mgc2hvdWxkIGJlIHVwZGF0ZWQKICAgICAgICBhZGRfYWN0aW9uKCdhZG1pbl9ub3RpY2VzJywgWyR0aGlzLCAnc2hvd0FkbWluTm90aWNlJ10pOwoKICAgICAgICAvLyBMaXN0ZW4gcG9zdCByZXF1ZXN0cwogICAgICAgIGFkZF9hY3Rpb24oc3ByaW50ZignYWRtaW5fcG9zdF8lcycsICR0aGlzLT5nZXRQYWdlU2x1ZygpKSwgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICR0aGlzLT5wb3N0TGljZW5zZVNldHRpbmdzUGFnZSgpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBIYW5kbGUgdXBkYXRlcwogICAgICAgIGlmKCR0aGlzLT5pc1BsdWdpbigpKSB7CiAgICAgICAgICAgIC8vIENoZWNrIGZvciB1cGRhdGVzIGZvciBwbHVnaW5zCiAgICAgICAgICAgIGFkZF9maWx0ZXIoJ3ByZV9zZXRfc2l0ZV90cmFuc2llbnRfdXBkYXRlX3BsdWdpbnMnLCBbJHRoaXMsICdjaGVja0ZvclVwZGF0ZSddKTsKCiAgICAgICAgICAgIC8vIFNob3cgcGx1Z2luIGluZm9ybWF0aW9uIHdoZW4gdGhlIHVzZXIgd2FudHMgdG8gc2VlIGl0CiAgICAgICAgICAgIGFkZF9maWx0ZXIoJ3BsdWdpbnNfYXBpJywgWyR0aGlzLCAnaGFuZGxlUGx1Z2luc0FwaSddLCAxMCwgMyk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENoZWNrIGZvciB1cGRhdGVzIGZvciB0aGVtZXMKICAgICAgICAgICAgYWRkX2ZpbHRlcigncHJlX3NldF9zaXRlX3RyYW5zaWVudF91cGRhdGVfdGhlbWVzJywgWyR0aGlzLCAnY2hlY2tGb3JVcGRhdGUnXSk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgYSBsaW5rIGFtb25nIHBsdWdpbiBhY3Rpb24gbGlua3MKICAgICAgICBpZiAoJHRoaXMtPnBsdWdpbkZpbGVQYXRoICE9PSBudWxsKSB7CiAgICAgICAgICAgIGFkZF9maWx0ZXIoc3ByaW50ZigncGx1Z2luX2FjdGlvbl9saW5rc18lcycsIHBsdWdpbl9iYXNlbmFtZSgkdGhpcy0+cGx1Z2luRmlsZVBhdGgpKSwgZnVuY3Rpb24oJGxpbmtzKSB7CiAgICAgICAgICAgICAgICAvKiogQG5vaW5zcGVjdGlvbiBIdG1sVW5rbm93blRhcmdldCAqLwogICAgICAgICAgICAgICAgJG5ld0xpbmtzID0gWwogICAgICAgICAgICAgICAgICAgIHNwcmludGYoJzxhIGhyZWY9IiVzIj4lczwvYT4nLCAkdGhpcy0+Z2V0TGljZW5zZVNldHRpbmdzUGFnZVVybCgpLCBfXygiTGljZW5zZSBTZXR0aW5ncyIsICR0aGlzLT50ZXh0RG9tYWluKSksCiAgICAgICAgICAgICAgICBdOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X21lcmdlKCRsaW5rcywgJG5ld0xpbmtzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgIH0KCiAgICAvKioKICAgICAqIEEgZnVuY3Rpb24gZm9yIHRoZSBXb3JkUHJlc3MgInBsdWdpbnNfYXBpIiBmaWx0ZXIuIENoZWNrcyBpZiB0aGUgdXNlciBpcyByZXF1ZXN0aW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZQogICAgICogY3VycmVudCBwbHVnaW4gYW5kIHJldHVybnMgaXRzIGRldGFpbHMgaWYgbmVlZGVkLgogICAgICoKICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJlZm9yZSB0aGUgUGx1Z2lucyBBUEkgY2hlY2tzIGZvciBwbHVnaW4gaW5mb3JtYXRpb24gb24gV29yZFByZXNzLm9yZy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm9vbHxvYmplY3QgJHJlcyAgICBUaGUgcmVzdWx0IG9iamVjdCwgb3IgZmFsc2UgKD0gZGVmYXVsdCB2YWx1ZSkuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGFjdGlvbiBUaGUgUGx1Z2lucyBBUEkgYWN0aW9uLiBXZSdyZSBpbnRlcmVzdGVkIGluICdwbHVnaW5faW5mb3JtYXRpb24nLgogICAgICogQHBhcmFtIGFycmF5ICAgICAgICRhcmdzICAgVGhlIFBsdWdpbnMgQVBJIHBhcmFtZXRlcnMuCiAgICAgKgogICAgICogQHJldHVybiBib29sfG9iamVjdCBUaGUgQVBJIHJlc3BvbnNlLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFuZGxlUGx1Z2luc0FwaSgkcmVzLCAkYWN0aW9uLCAkYXJncykgewogICAgICAgIGlmKCRhY3Rpb24gPT0gJ3BsdWdpbl9pbmZvcm1hdGlvbicpIHsKICAgICAgICAgICAgLy8gSWYgdGhlIHJlcXVlc3QgaXMgZm9yIHRoaXMgcGx1Z2luLCByZXNwb25kIHRvIGl0CiAgICAgICAgICAgIGlmIChpc3NldCgkYXJncy0+c2x1ZykgJiYgJHRoaXMtPnBsdWdpbkZpbGVQYXRoICE9PSBudWxsICYmICRhcmdzLT5zbHVnID09IHBsdWdpbl9iYXNlbmFtZSgkdGhpcy0+cGx1Z2luRmlsZVBhdGgpKSB7CiAgICAgICAgICAgICAgICAkaW5mbyA9ICR0aGlzLT5tYWtlUmVxdWVzdFByb2R1Y3RJbmZvKCk7CiAgICAgICAgICAgICAgICBpZiAoJGluZm8gPT09IG51bGwpIHJldHVybiAkcmVzOwoKICAgICAgICAgICAgICAgICRyZXMgPSAob2JqZWN0KSBbCiAgICAgICAgICAgICAgICAgICAgJ25hbWUnICAgICAgICAgICAgICA9PiBpc3NldCgkaW5mby0+dGl0bGUpICAgICAgICAgICAgICA/ICRpbmZvLT50aXRsZSAgICAgICAgICAgICAgOiAnJywKICAgICAgICAgICAgICAgICAgICAndmVyc2lvbicgICAgICAgICAgID0+IGlzc2V0KCRpbmZvLT52ZXJzaW9uX3ByZXR0eSkgICAgID8gJGluZm8tPnZlcnNpb25fcHJldHR5ICAgICA6ICcnLAogICAgICAgICAgICAgICAgICAgICdob21lcGFnZScgICAgICAgICAgPT4gaXNzZXQoJGluZm8tPmhvbWVwYWdlKSAgICAgICAgICAgPyAkaW5mby0+aG9tZXBhZ2UgICAgICAgICAgIDogbnVsbCwKICAgICAgICAgICAgICAgICAgICAnYXV0aG9yJyAgICAgICAgICAgID0+IGlzc2V0KCRpbmZvLT5hdXRob3IpICAgICAgICAgICAgID8gJGluZm8tPmF1dGhvciAgICAgICAgICAgICA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgJ3NsdWcnICAgICAgICAgICAgICA9PiAkYXJncy0+c2x1ZywKICAgICAgICAgICAgICAgICAgICAnZG93bmxvYWRfbGluaycgICAgID0+IGlzc2V0KCRpbmZvLT5wYWNrYWdlX3VybCkgPyAkaW5mby0+cGFja2FnZV91cmwgOiAnJywKCiAgICAgICAgICAgICAgICAgICAgJ3Rlc3RlZCcgICAgICAgICAgICA9PiBpc3NldCgkaW5mby0+dGVzdGVkKSAgICAgICAgICAgICA/ICRpbmZvLT50ZXN0ZWQgICAgICAgICAgICAgOiAnJywKICAgICAgICAgICAgICAgICAgICAncmVxdWlyZXMnICAgICAgICAgID0+IGlzc2V0KCRpbmZvLT5yZXF1aXJlcykgICAgICAgICAgID8gJGluZm8tPnJlcXVpcmVzICAgICAgICAgICA6ICcnLAogICAgICAgICAgICAgICAgICAgICdsYXN0X3VwZGF0ZWQnICAgICAgPT4gaXNzZXQoJGluZm8tPmxhc3RfdXBkYXRlZCkgICAgICAgPyAkaW5mby0+bGFzdF91cGRhdGVkICAgICAgIDogJycsCgogICAgICAgICAgICAgICAgICAgICdzZWN0aW9ucycgID0+IFsKICAgICAgICAgICAgICAgICAgICAgICAgJ2Rlc2NyaXB0aW9uJyAgID0+IGlzc2V0KCRpbmZvLT5kZXNjcmlwdGlvbikgPyAkaW5mby0+ZGVzY3JpcHRpb24gOiAnJywKICAgICAgICAgICAgICAgICAgICBdLAoKICAgICAgICAgICAgICAgICAgICAnYmFubmVycycgICA9PiBbCiAgICAgICAgICAgICAgICAgICAgICAgICdsb3cnICAgICAgID0+IGlzc2V0KCRpbmZvLT5iYW5uZXJfbG93KSAgPyAkaW5mby0+YmFubmVyX2xvdyAgOiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgJ2hpZ2gnICAgICAgPT4gaXNzZXQoJGluZm8tPmJhbm5lcl9oaWdoKSA/ICRpbmZvLT5iYW5uZXJfaGlnaCA6ICcnLAogICAgICAgICAgICAgICAgICAgIF0sCgogICAgICAgICAgICAgICAgICAgICdleHRlcm5hbCcgPT4gdHJ1ZSwKICAgICAgICAgICAgICAgIF07CgogICAgICAgICAgICAgICAgLy8gQWRkIGEgZmV3IHRhYnMKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkaW5mby0+aW5zdGFsbGF0aW9uKSkgJHJlcy0+c2VjdGlvbnNbJ2luc3RhbGxhdGlvbiddICA9ICRpbmZvLT5pbnN0YWxsYXRpb247CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGluZm8tPnNjcmVlbnNob3RzKSkgICRyZXMtPnNlY3Rpb25zWydzY3JlZW5zaG90cyddICAgPSAkaW5mby0+c2NyZWVuc2hvdHM7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJGluZm8tPmNoYW5nZWxvZykpICAgICRyZXMtPnNlY3Rpb25zWydjaGFuZ2Vsb2cnXSAgICAgPSAkaW5mby0+Y2hhbmdlbG9nOwogICAgICAgICAgICAgICAgaWYgKGlzc2V0KCRpbmZvLT5mYXEpKSAgICAgICAgICAkcmVzLT5zZWN0aW9uc1snZmFxJ10gICAgICAgICAgID0gJGluZm8tPmZhcTsKCiAgICAgICAgICAgICAgICByZXR1cm4gJHJlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gTm90IG91ciByZXF1ZXN0LCBsZXQgV29yZFByZXNzIGhhbmRsZSB0aGlzLgogICAgICAgIHJldHVybiAkcmVzOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIG1peGVkfG9iamVjdCAkdHJhbnNpZW50CiAgICAgKiBAcmV0dXJuIG1peGVkfG9iamVjdAogICAgICogQHNpbmNlIDEuMTEuMQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2tGb3JVcGRhdGUoJHRyYW5zaWVudCkgewogICAgICAgIGlmICghaXNfb2JqZWN0KCR0cmFuc2llbnQpICYmICFpc19hcnJheSgkdHJhbnNpZW50KSkgcmV0dXJuICR0cmFuc2llbnQ7CgogICAgICAgIGlmIChpc19hcnJheSgkdHJhbnNpZW50KSkgewogICAgICAgICAgICAkdHJhbnNpZW50ID0gKG9iamVjdCkgJHRyYW5zaWVudDsKICAgICAgICB9CgogICAgICAgIGlmKGVtcHR5KCR0cmFuc2llbnQtPmNoZWNrZWQpIHx8ICEkdGhpcy0+Y2FuTWFrZVJlcXVlc3QoKSkgcmV0dXJuICR0cmFuc2llbnQ7CgogICAgICAgICRpbmZvID0gJHRoaXMtPmlzVXBkYXRlQXZhaWxhYmxlKCk7CiAgICAgICAgaWYgKCRpbmZvID09PSBmYWxzZSB8fCAhaXNzZXQoJHRyYW5zaWVudC0+cmVzcG9uc2UpKSByZXR1cm4gJHRyYW5zaWVudDsKCiAgICAgICAgaWYoJHRoaXMtPmlzUGx1Z2luKCkpIHsKICAgICAgICAgICAgLy8gUGx1Z2luCiAgICAgICAgICAgIGlmICgkdGhpcy0+cGx1Z2luRmlsZVBhdGggIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICRwbHVnaW5TbHVnID0gcGx1Z2luX2Jhc2VuYW1lKCR0aGlzLT5wbHVnaW5GaWxlUGF0aCk7CgogICAgICAgICAgICAgICAgJHRyYW5zaWVudC0+cmVzcG9uc2VbJHBsdWdpblNsdWddID0gKG9iamVjdCkgWwogICAgICAgICAgICAgICAgICAgICduZXdfdmVyc2lvbicgICA9PiBpc3NldCgkaW5mby0+dmVyc2lvbl9wcmV0dHkpID8gJGluZm8tPnZlcnNpb25fcHJldHR5IDogJycsCiAgICAgICAgICAgICAgICAgICAgJ3BhY2thZ2UnICAgICAgID0+IGlzc2V0KCRpbmZvLT5wYWNrYWdlX3VybCkgICAgPyAkaW5mby0+cGFja2FnZV91cmwgICAgOiAnJywKICAgICAgICAgICAgICAgICAgICAnc2x1ZycgICAgICAgICAgPT4gJHBsdWdpblNsdWcsCiAgICAgICAgICAgICAgICBdOwogICAgICAgICAgICB9CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFRoZW1lCiAgICAgICAgICAgICR0aGVtZURhdGEgPSB3cF9nZXRfdGhlbWUoKTsKICAgICAgICAgICAgJHRoZW1lU2x1ZyA9ICR0aGVtZURhdGEtPmdldF90ZW1wbGF0ZSgpOwoKICAgICAgICAgICAgJHRyYW5zaWVudC0+cmVzcG9uc2VbJHRoZW1lU2x1Z10gPSBbCiAgICAgICAgICAgICAgICAnbmV3X3ZlcnNpb24nICAgPT4gaXNzZXQoJGluZm8tPnZlcnNpb25fcHJldHR5KSA/ICRpbmZvLT52ZXJzaW9uX3ByZXR0eSA6ICcnLAogICAgICAgICAgICAgICAgJ3BhY2thZ2UnICAgICAgID0+IGlzc2V0KCRpbmZvLT5wYWNrYWdlX3VybCkgICAgPyAkaW5mby0+cGFja2FnZV91cmwgICAgOiAnJywKLy8gICAgICAgICAgICAgICAgJ3VybCcgICAgICAgICAgID0+ICRpbmZvLT5kZXNjcmlwdGlvbl91cmwKICAgICAgICAgICAgXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkdHJhbnNpZW50OwogICAgfQoKICAgIC8qKgogICAgICogU2hvdyBhIG5vdGljZSB0byByZW1pbmQgdGhlIHVzZXIgdGhhdCBoZS9zaGUgc2hvdWxkIGZpbGwgbGljZW5zZSBjcmVkZW50aWFscy4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3dBZG1pbk5vdGljZSgpOiB2b2lkIHsKICAgICAgICAkaGlkZVBhcmFtTmFtZSA9ICR0aGlzLT5nZXRIaWRlQWRtaW5Ob3RpY2VVcmxQYXJhbU5hbWUoKTsKICAgICAgICBpZiAoaXNzZXQoJF9HRVRbJGhpZGVQYXJhbU5hbWVdKSkgewogICAgICAgICAgICAkdGhpcy0+c2V0QWRtaW5Ob3RpY2VIaWRkZW4oJF9HRVRbJGhpZGVQYXJhbU5hbWVdKTsKICAgICAgICB9CgogICAgICAgICR2YWxpZCA9ICR0aGlzLT5nZXRWYWxpZCgpOwogICAgICAgIGlmKCEkdGhpcy0+Z2V0TGljZW5zZUtleSgpIHx8ICR2YWxpZCAhPT0gJzEnKSB7CiAgICAgICAgICAgIC8vIERvIG5vdCBzaG93IGlmIHRoaXMgaXMgbm90IGEgcHJvZHVjdCBwYWdlIGFuZCB0aGUgbm90aWNlIGlzIHNldCB0byBiZSBoaWRkZW4uCiAgICAgICAgICAgIGlmICghJHRoaXMtPmlzUHJvZHVjdFBhZ2UoKSAmJiAkdGhpcy0+aXNBZG1pbk5vdGljZUhpZGRlbigpKSByZXR1cm47CgogICAgICAgICAgICBpZigkdmFsaWQgIT09ICcxJyAmJiAkdmFsaWQgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmKCR2YWxpZCAhPT0gJzAnKSB7CiAgICAgICAgICAgICAgICAgICAgJGR0ID0gbmV3IERhdGVUaW1lKCR2YWxpZCk7CiAgICAgICAgICAgICAgICAgICAgJG1zZyA9IF9fKCdUaGUgbGljZW5zZSBrZXkgZW50ZXJlZCBmb3IgJTEkcyBpcyBub3QgdmFsaWQgb3IgaXQgY291bGQgbm90IGJlIGNoZWNrZWQuIFBsZWFzZSB2ZXJpZnkgeW91ciBsaWNlbnNlIHVudGlsICUyJHMgdG8gY29udGludWUgdXNpbmcgJTMkcy4nLCAkdGhpcy0+dGV4dERvbWFpbik7CiAgICAgICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoJG1zZywgJHRoaXMtPmdldFByb2R1Y3ROYW1lKCksICc8Yj4nIC4gJGR0LT5mb3JtYXQoJ2QvbS9ZIEg6aScpIC4gJzwvYj4nLCAkdGhpcy0+Z2V0UHJvZHVjdE5hbWUoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRtc2cgPSBfXygnVGhlIGxpY2Vuc2Uga2V5IGVudGVyZWQgZm9yICUxJHMgaXMgbm90IHZhbGlkIG9yIGl0IGNvdWxkIG5vdCBiZSBjaGVja2VkLiBZb3UgZGlkIG5vdCB2ZXJpZnkgeW91ciBsaWNlbnNlLiBUaGUgZmVhdHVyZXMgYXJlIGRpc2FibGVkLgogICAgICAgICAgICAgICAgICAgICAgICBQbGVhc2UgdmVyaWZ5IHlvdXIgbGljZW5zZSB0byBjb250aW51ZSB1c2luZyAlMiRzLicsICR0aGlzLT50ZXh0RG9tYWluKTsKICAgICAgICAgICAgICAgICAgICAkbXNnID0gc3ByaW50ZigkbXNnLCAkdGhpcy0+Z2V0UHJvZHVjdE5hbWUoKSwgJHRoaXMtPmdldFByb2R1Y3ROYW1lKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJG1zZyA9IF9fKCdQbGVhc2UgZW50ZXIgeW91ciBsaWNlbnNlIGtleSBmb3IgJXMgdG8gdXNlIGl0cyBmZWF0dXJlcyBhbmQgZ2V0IHVwZGF0ZXMuJywgJHRoaXMtPnRleHREb21haW4pOwogICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoJG1zZywgJHRoaXMtPmdldFByb2R1Y3ROYW1lKCkpOwoKICAgICAgICAgICAgICAgICR0aGlzLT5pbml0RXhwaXJhdGlvbkRvTm90T3ZlcnJpZGUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHRyaWFsTWVzc2FnZSA9ICcnOwogICAgICAgICAgICAkdHJpYWxDb3VudCA9ICR0aGlzLT5nZXRUcmlhbENvdW50KCk7CiAgICAgICAgICAgIGlmICgkdHJpYWxDb3VudCA8IDMgJiYgJHRyaWFsQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAkdHJpYWxNZXNzYWdlID0gc3ByaW50ZihfXygnTnVtYmVyIG9mIGF0dGVtcHRzIGxlZnQgdW50aWwgdGhlIGZlYXR1cmVzIGFyZSBkaXNhYmxlZDogJXMnLCAkdGhpcy0+dGV4dERvbWFpbiksICc8Yj4nIC4gJHRyaWFsQ291bnQgLiAnPC9iPicpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkZXJyb3JNZXNzYWdlICAgICAgID0gJHRoaXMtPmdldEVycm9yTWVzc2FnZSgpOwogICAgICAgICAgICAkc2hvd05vdGljZU1lc3NhZ2UgID0gc3ByaW50ZihfXygnQWx3YXlzIHNob3cgdGhpcyBub3RpY2UnLCAkdGhpcy0+dGV4dERvbWFpbiksICR0aGlzLT5nZXRQcm9kdWN0TmFtZSgpKTsKICAgICAgICAgICAgJGhpZGVOb3RpY2VNZXNzYWdlICA9IHNwcmludGYoX18oJ0hpZGUgdGhpcyBub3RpY2Ugb3V0c2lkZSBvZiAlMSRzIHBhZ2VzJywgJHRoaXMtPnRleHREb21haW4pLCAkdGhpcy0+Z2V0UHJvZHVjdE5hbWUoKSk7CgogICAgICAgICAgICAkdG9nZ2xlTm90aWNlVXJsID0gJHRoaXMtPmdldEN1cnJlbnRQYWdlVXJsKFsKICAgICAgICAgICAgICAgICRoaWRlUGFyYW1OYW1lID0+ICEkdGhpcy0+aXNBZG1pbk5vdGljZUhpZGRlbigpCiAgICAgICAgICAgIF0pOwoKICAgICAgICAgICAgJHRvZ2dsZU5vdGljZU1lc3NhZ2UgPSAkdGhpcy0+aXNBZG1pbk5vdGljZUhpZGRlbigpID8gJHNob3dOb3RpY2VNZXNzYWdlIDogJGhpZGVOb3RpY2VNZXNzYWdlOwogICAgICAgICAgICAkdHh0Q3VycmVudERvbWFpbiA9IHNwcmludGYoX18oJ0N1cnJlbnQgZG9tYWluOiAlMSRzJywgJHRoaXMtPnRleHREb21haW4pLCAkdGhpcy0+Z2V0U2VydmVyTmFtZSgpKTsKICAgICAgICAgICAgJG1zZ0N1cnJlbnREb21haW4gPSAiPHNwYW4gc3R5bGU9J2Rpc3BsYXk6IGJsb2NrOyBmb250LXNpemU6IDExcHgnPih7JHR4dEN1cnJlbnREb21haW59KTwvc3Bhbj4iOwoKICAgICAgICAgICAgPz4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InVwZGF0ZS1uYWciIHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGxpbmUtaGVpZ2h0OiAxLjQ7IHBhZGRpbmc6IDExcHggMTVweDsKICAgICAgICAgICAgICAgICAgICBmb250LXNpemU6IDE0cHg7IHRleHQtYWxpZ246IGxlZnQ7IG1hcmdpbjogMjVweCAyMHB4IDAgMnB4OyBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwogICAgICAgICAgICAgICAgICAgIGJvcmRlci1sZWZ0OiA0cHggc29saWQgI2ZmYmEwMDsgYm94LXNoYWRvdzogMCAxcHggMXB4IDAgcmdiYSgwLCAwLCAwLCAwLjEpOyI+CiAgICAgICAgICAgICAgICAgICAgPHA+PD9waHAgZWNobyAkbXNnIC4gJG1zZ0N1cnJlbnREb21haW47ID8+PC9wPgogICAgICAgICAgICAgICAgICAgIDw/cGhwIGlmKCRlcnJvck1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAiPHA+IiAuIF9fKCJNZXNzYWdlIiwgJHRoaXMtPnRleHREb21haW4pIC4gJzogPGIgc3R5bGU9ImNvbG9yOiAjZmYwMDAwIj4nIC4gX18oJGVycm9yTWVzc2FnZSwgJHRoaXMtPnRleHREb21haW4pIC4gIjwvYj48L3A+IjsKICAgICAgICAgICAgICAgICAgICB9ID8+CiAgICAgICAgICAgICAgICAgICAgPD9waHAgaWYgKCR0cmlhbE1lc3NhZ2UgIT09ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gIjxwPiIgLiAkdHJpYWxNZXNzYWdlIC4gIjwvcD4iOwogICAgICAgICAgICAgICAgICAgIH0gPz4KICAgICAgICAgICAgICAgICAgICA8cD4KICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iPD9waHAgZWNobyBhZG1pbl91cmwoJ29wdGlvbnMtZ2VuZXJhbC5waHA/cGFnZT0nIC4gJHRoaXMtPmdldFBhZ2VTbHVnKCkpOyA/PiI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3BocCBfZSgnQ29tcGxldGUgdGhlIHNldHVwIG5vdy4nLCAkdGhpcy0+dGV4dERvbWFpbik7ID8+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT4KICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9Im1hcmdpbjogMCAycHggMCA0cHg7Ij58PC9zcGFuPgogICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSI8P3BocCBlY2hvICR0b2dnbGVOb3RpY2VVcmwgPz4iPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPD9waHAgZWNobyAkdG9nZ2xlTm90aWNlTWVzc2FnZSA/PgogICAgICAgICAgICAgICAgICAgICAgICA8L2E+CiAgICAgICAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDw/cGhwCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBmYWxzZXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB2YWxpZGF0ZSgpOiA/Ym9vbCB7CiAgICAgICAgaWYgKCEkdGhpcy0+Y2FuTWFrZVJlcXVlc3QoKSkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAkdGhpcy0+dXBkYXRlTGFzdFJ1bigpOwogICAgICAgICR0aGlzLT5tYWtlUmVxdWVzdFByb2R1Y3RJbmZvKCk7CiAgICAgICAgJHZhbGlkID0gJHRoaXMtPmdldFZhbGlkKCk7CgogICAgICAgIGlmKCR2YWxpZCAhPT0gJzAnICYmICR2YWxpZCAhPT0gJzEnKSB7CiAgICAgICAgICAgICRkdCA9IG5ldyBEYXRlVGltZSgkdmFsaWQpOwogICAgICAgICAgICAkbm93ID0gJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKTsKCiAgICAgICAgICAgIGlmKCRkdCA8PSAkbm93KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2V0VmFsaWQoJzAnKTsKICAgICAgICAgICAgICAgICR0aGlzLT51cGRhdGVUcmlhbENvdW50KDApOwogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGRlYWN0aXZhdGUoP2Jvb2wgJG5ldHdvcmtfd2lkZSk6IGJvb2wgewogICAgICAgICRyZXN1bHQgPSBbXTsKICAgICAgICBpZihpc19tdWx0aXNpdGUoKSAmJiAkbmV0d29ya193aWRlKSB7CiAgICAgICAgICAgIGdsb2JhbCAkd3BkYjsKCiAgICAgICAgICAgIC8vIEdldCBhbGwgYmxvZ3MgaW4gdGhlIG5ldHdvcmsgYW5kIGFjdGl2YXRlIHBsdWdpbiBvbiBlYWNoIG9uZQogICAgICAgICAgICAkYmxvZ0lkcyA9ICR3cGRiLT5nZXRfY29sKCJTRUxFQ1QgYmxvZ19pZCBGUk9NICR3cGRiLT5ibG9ncyIpOwoKICAgICAgICAgICAgJHNlcnZlck5hbWVzID0gW107CiAgICAgICAgICAgIGZvcmVhY2ggKCRibG9nSWRzIGFzICRibG9nSWQpIHsKICAgICAgICAgICAgICAgIHN3aXRjaF90b19ibG9nKCRibG9nSWQpOwogICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+Z2V0TGljZW5zZUtleSgpKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAvLyBEbyBub3QgY2FsbCB0aGUgQVBJIGlmIGl0IGlzIGFscmVhZHkgY2FsbGVkIGZvciB0aGlzIHNlcnZlciBuYW1lLgogICAgICAgICAgICAgICAgaWYoaW5fYXJyYXkoJHRoaXMtPmdldFNlcnZlck5hbWUoKSwgJHNlcnZlck5hbWVzKSkgY29udGludWU7CgogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5tYWtlUmVxdWVzdFVuaW5zdGFsbCgpOwogICAgICAgICAgICAgICAgJHNlcnZlck5hbWVzW10gPSAkdGhpcy0+Z2V0U2VydmVyTmFtZSgpOwoKICAgICAgICAgICAgICAgIHJlc3RvcmVfY3VycmVudF9ibG9nKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+Z2V0TGljZW5zZUtleSgpKSByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPm1ha2VSZXF1ZXN0VW5pbnN0YWxsKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gaXNzZXQoJHJlc3VsdFsic3VjY2VzcyJdKSAmJiAkcmVzdWx0WyJzdWNjZXNzIl07CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgYSBjYWxsYmFjayB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoZSBjdXJyZW50IHBhZ2UgYmVsb25ncyB0byB0aGUgcHJvZHVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gY2FsbGFibGV8bnVsbCAkY2FsbGJhY2sgQSBjYWxsYmFjayB0aGF0IHJldHVybnMgdHJ1ZSBvciBmYWxzZS4gUmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IHBhZ2UgaXMgcHJvZHVjdAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2UuIE90aGVyd2lzZSwgZmFsc2UuCiAgICAgKiBAc2luY2UgMS45LjAKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldElzUHJvZHVjdFBhZ2VDYWxsYmFjayg/Y2FsbGFibGUgJGNhbGxiYWNrKTogdm9pZCB7CiAgICAgICAgaWYgKCRjYWxsYmFjayAhPT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+aXNQcm9kdWN0UGFnZUNhbGxiYWNrID0gJGNhbGxiYWNrOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNVc2VyQ29vbCgpOiBib29sIHsKICAgICAgICAkdmFsaWQgPSAkdGhpcy0+Z2V0VmFsaWQoKTsKCiAgICAgICAgaWYoJHZhbGlkID09PSAnMScpIHJldHVybiB0cnVlOwogICAgICAgIGlmKCR2YWxpZCA9PT0gJzAnKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYoJHZhbGlkICE9PSBudWxsKSB7CiAgICAgICAgICAgICRkdCA9IG5ldyBEYXRlVGltZSgkdmFsaWQpOwogICAgICAgICAgICAkbm93ID0gJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKTsKICAgICAgICAgICAgaWYoJGR0IDw9ICRub3cpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoKICAgICAqIFBSSVZBVEUgSEVMUEVSUwogICAgICovCgogICAgLyoqCiAgICAgKiBDaGVja3MgdGhlIGxpY2Vuc2UgbWFuYWdlciB0byBzZWUgaWYgdGhlcmUgaXMgYW4gdXBkYXRlIGF2YWlsYWJsZSBmb3IgdGhpcyB0aGVtZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIG9iamVjdHxib29sICBJZiB0aGVyZSBpcyBhbiB1cGRhdGUsIHJldHVybnMgdGhlIGxpY2Vuc2UgaW5mb3JtYXRpb24uCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBPdGhlcndpc2UgcmV0dXJucyBmYWxzZS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1VwZGF0ZUF2YWlsYWJsZSgpIHsKICAgICAgICAkbGljZW5zZUluZm8gPSAkdGhpcy0+bWFrZVJlcXVlc3RQcm9kdWN0SW5mbygpOwogICAgICAgIGlmICgkbGljZW5zZUluZm8gPT09IG51bGwgfHwgIWlzX29iamVjdCgkbGljZW5zZUluZm8pCiAgICAgICAgICAgIHx8IGlzc2V0KCRsaWNlbnNlSW5mby0+ZXJyb3IpIHx8ICFpc3NldCgkbGljZW5zZUluZm8tPnZlcnNpb25fcHJldHR5KSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAkbG9jYWxWZXJzaW9uID0gJHRoaXMtPmdldExvY2FsVmVyc2lvbigpOwogICAgICAgIGlmICgkbG9jYWxWZXJzaW9uID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoJGxpY2Vuc2VJbmZvLT52ZXJzaW9uX3ByZXR0eSwgJGxvY2FsVmVyc2lvbiwgJz4nKSkgewogICAgICAgICAgICByZXR1cm4gJGxpY2Vuc2VJbmZvOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogSGFuZGxlcyBwb3N0IHJlcXVlc3QgbWFkZSBmcm9tIGxpY2Vuc2Ugc2V0dGluZ3MgcGFnZSdzIGZvcm0KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBwb3N0TGljZW5zZVNldHRpbmdzUGFnZSgpOiB2b2lkIHsKICAgICAgICBpZiAoVXRpbHM6OmlzQWpheCgpKSByZXR1cm47CgogICAgICAgICRkYXRhID0gJF9QT1NUOwogICAgICAgICRzdWNjZXNzID0gdHJ1ZTsKICAgICAgICAkbXNnID0gbnVsbDsKCiAgICAgICAgaWYoaXNzZXQoJGRhdGFbImRlYWN0aXZhdGUiXSkgJiYgJGRhdGFbImRlYWN0aXZhdGUiXSkgewogICAgICAgICAgICAvLyBJZiB0aGUgdXNlciB3YW50cyB0byBkZWFjdGl2YXRlIHRoZSBwbHVnaW4gb24gY3VycmVudCBkb21haW4KICAgICAgICAgICAgJHN1Y2Nlc3MgPSAkdGhpcy0+ZGVhY3RpdmF0ZSh0cnVlKTsKICAgICAgICAgICAgaWYoJHN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cGx1Z2luRmlsZVBhdGggIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBkZWFjdGl2YXRlX3BsdWdpbnMocGx1Z2luX2Jhc2VuYW1lKCR0aGlzLT5wbHVnaW5GaWxlUGF0aCksIHRydWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHdwX3JlZGlyZWN0KGFkbWluX3VybCgicGx1Z2lucy5waHAiKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+Y2FuTWFrZVJlcXVlc3QoKSkgewogICAgICAgICAgICAgICAgJHJlbWFpbmluZ1NlYyA9ICR0aGlzLT5nZXRSZW1haW5pbmdTZWNvbmRzRm9yTmV3UmVxdWVzdCgpOwogICAgICAgICAgICAgICAgJG1zZyA9IHNwcmludGYoX18oJ1lvdSBjYW4gc2F2ZSB0aGUgc2V0dGluZ3MgaW4gJXMgc2Vjb25kcy4nLCAkdGhpcy0+dGV4dERvbWFpbiksICc8Yj4nIC4gJHJlbWFpbmluZ1NlYyAuICc8L2I+Jyk7CiAgICAgICAgICAgICAgICAkc3VjY2VzcyA9IGZhbHNlOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFNhdmUgc2V0dGluZ3MKICAgICAgICAgICAgICAgIGlmIChpc3NldCgkZGF0YVskdGhpcy0+Z2V0TGljZW5zZUtleU9wdGlvbk5hbWUoKV0pKSB7CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlX29wdGlvbigkdGhpcy0+Z2V0TGljZW5zZUtleU9wdGlvbk5hbWUoKSwgJGRhdGFbJHRoaXMtPmdldExpY2Vuc2VLZXlPcHRpb25OYW1lKCldLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPnZhbGlkYXRlKCk7CiAgICAgICAgICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAkc3VjY2VzcyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICRtc2cgPSBfXygnTGljZW5zZSB2YWxpZGF0aW9uIGZhaWxlZC4nLCAkdGhpcy0+dGV4dERvbWFpbik7CgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2NoZWR1bGVFdmVudHMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIC8vIFJlZGlyZWN0IGJhY2sKICAgICAgICAkdXJsID0gYWRtaW5fdXJsKHNwcmludGYoJ29wdGlvbnMtZ2VuZXJhbC5waHA/cGFnZT0lcyZzdWNjZXNzPSVzJywgJHRoaXMtPmdldFBhZ2VTbHVnKCksICRzdWNjZXNzID8gJ3RydWUnIDogJ2ZhbHNlJykpOwogICAgICAgIGlmICgkbXNnKSB7CiAgICAgICAgICAgICR1cmwgLj0gJyZtZXNzYWdlPScgLiB1cmxlbmNvZGUoJG1zZyk7CiAgICAgICAgfQoKICAgICAgICB3cF9yZWRpcmVjdCgkdXJsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbmRlcnMgbGljZW5zZSBzZXR0aW5ncyBwYWdlLgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlbmRlckxpY2Vuc2VTZXR0aW5nc1BhZ2UoKTogdm9pZCB7CiAgICAgICAgJHNob3dBbGVydCA9IGlzc2V0KCRfR0VUWyJzdWNjZXNzIl0pICYmICRfR0VUWyJzdWNjZXNzIl0gPT0gJ3RydWUnOwogICAgICAgICRtc2cgPSBpc3NldCgkX0dFVFsnbWVzc2FnZSddKSAmJiAkX0dFVFsnbWVzc2FnZSddID8gdXJsZGVjb2RlKCRfR0VUWydtZXNzYWdlJ10pIDogbnVsbDsKICAgICAgICA/PgogICAgICAgIDxkaXYgY2xhc3M9IndyYXAiPgogICAgICAgICAgICA8aDE+PD9waHAgZWNobyBzcHJpbnRmKF9fKCdMaWNlbnNlIFNldHRpbmdzIGZvciAlcycsICR0aGlzLT50ZXh0RG9tYWluKSwgJHRoaXMtPmdldFByb2R1Y3ROYW1lKCkpID8+PC9oMT4KCiAgICAgICAgICAgIDxkaXYgY2xhc3M9Im5vdGljZSBub3RpY2Utc3VjY2VzcyA8P3BocCBpZighJHNob3dBbGVydCkgZWNobyAnaGlkZGVuJzsgPz4iPgogICAgICAgICAgICAgICAgPHA+PD9waHAgX2UoJ0xpY2Vuc2Ugc2V0dGluZ3MgdXBkYXRlZC4nLCAkdGhpcy0+dGV4dERvbWFpbikgPz48L3A+CiAgICAgICAgICAgIDwvZGl2PgoKICAgICAgICAgICAgPD9waHAgaWYoJG1zZyAhPT0gbnVsbCkgeyA/PgogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibm90aWNlIG5vdGljZS13YXJuaW5nIj4KICAgICAgICAgICAgICAgICAgICA8cD48P3BocCBlY2hvICRtc2c7ID8+PC9wPgogICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDw/cGhwIH0gPz4KCiAgICAgICAgICAgIDwhLS1zdXBwcmVzcyBIdG1sVW5rbm93blRhcmdldCAtLT4KICAgICAgICAgICAgPGZvcm0gYWN0aW9uPSJhZG1pbi1wb3N0LnBocCIgbWV0aG9kPSJwb3N0IiBub3ZhbGlkYXRlPSJub3ZhbGlkYXRlIj4KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImFjdGlvbiIgdmFsdWU9Ijw/cGhwIGVjaG8gJHRoaXMtPmdldFBhZ2VTbHVnKCk7ID8+IiBpZD0iaGlkZGVuYWN0aW9uIj4KICAgICAgICAgICAgICAgIDw/cGhwIHdwX25vbmNlX2ZpZWxkKCkgPz4KCiAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9ImZvcm0tdGFibGUiPgogICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT0icm93Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9Ijw/cGhwIGVjaG8gJHRoaXMtPmdldExpY2Vuc2VLZXlPcHRpb25OYW1lKCk7ID8+Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3BocCBfZSgnTGljZW5zZSBLZXknLCAkdGhpcy0+dGV4dERvbWFpbikgPz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+CiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJwYXNzd29yZCIgY2xhc3M9InJlZ3VsYXItdGV4dCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSI8P3BocCBlY2hvICR0aGlzLT5nZXRMaWNlbnNlS2V5T3B0aW9uTmFtZSgpOyA/PiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZD0iPD9waHAgZWNobyAkdGhpcy0+Z2V0TGljZW5zZUtleU9wdGlvbk5hbWUoKTsgPz4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9Ijw/cGhwIGVjaG8gJHRoaXMtPmdldExpY2Vuc2VLZXkoKTsgPz4iPgogICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgPC90Ym9keT4KICAgICAgICAgICAgICAgIDwvdGFibGU+CgogICAgICAgICAgICAgICAgPD9waHAgaWYoJHRoaXMtPmdldFVybEhvd1RvRmluZExpY2Vuc2VLZXkoKSkgeyA/PgogICAgICAgICAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Ijw/cGhwIGVjaG8gJHRoaXMtPmdldFVybEhvd1RvRmluZExpY2Vuc2VLZXkoKSA/PiIgdGFyZ2V0PSJfYmxhbmsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPD9waHAgZWNobyBfXygnSG93IHRvIGZpbmQgbXkgbGljZW5zZSBrZXk/Jyk7ID8+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT4KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgIDw/cGhwIH0gPz4KCiAgICAgICAgICAgICAgICA8P3BocCBzdWJtaXRfYnV0dG9uKCk7ID8+CiAgICAgICAgICAgIDwvZm9ybT4KCiAgICAgICAgICAgIDw/cGhwIGlmKCR0aGlzLT5nZXRMaWNlbnNlS2V5KCkpIHsgPz4KICAgICAgICAgICAgICAgIDwhLS1zdXBwcmVzcyBIdG1sVW5rbm93blRhcmdldCAtLT4KICAgICAgICAgICAgICAgIDxmb3JtIGFjdGlvbj0iYWRtaW4tcG9zdC5waHAiIG1ldGhvZD0icG9zdCIgbm92YWxpZGF0ZT0ibm92YWxpZGF0ZSI+CiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYWN0aW9uIiB2YWx1ZT0iPD9waHAgZWNobyAkdGhpcy0+Z2V0UGFnZVNsdWcoKTsgPz4iIGlkPSJoaWRkZW5hY3Rpb24yIj4KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJkZWFjdGl2YXRlIiB2YWx1ZT0iMSI+CiAgICAgICAgICAgICAgICAgICAgPD9waHAgd3Bfbm9uY2VfZmllbGQoKSA/PgogICAgICAgICAgICAgICAgICAgIDw/cGhwIHN1Ym1pdF9idXR0b24oX18oJ0RlYWN0aXZhdGUgb24gdGhpcyBkb21haW4nLCAkdGhpcy0+dGV4dERvbWFpbiksICdzZWNvbmRhcnkgcmlnaHQnKTsgPz4KICAgICAgICAgICAgICAgIDwvZm9ybT4KICAgICAgICAgICAgPD9waHAgfSA/PgogICAgICAgIDwvZGl2PgoKICAgICAgICA8P3BocAogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0TGljZW5zZVNldHRpbmdzUGFnZVVybCgpOiBzdHJpbmcgewogICAgICAgIHJldHVybiBhZG1pbl91cmwoIm9wdGlvbnMtZ2VuZXJhbC5waHA/cGFnZT0iIC4gJHRoaXMtPmdldFBhZ2VTbHVnKCkpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaXNMaWNlbnNlU2V0dGluZ3NQYWdlKCk6IGJvb2wgewogICAgICAgIHJldHVybiBpc3NldCgkX0dFVFsncGFnZSddKSAmJiBzdHJ0b2xvd2VyKCRfR0VUWydwYWdlJ10pID09PSBzdHJ0b2xvd2VyKCR0aGlzLT5nZXRQYWdlU2x1ZygpKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzUHJvZHVjdFBhZ2UoKTogYm9vbCB7CiAgICAgICAgaWYgKCEkdGhpcy0+aXNQcm9kdWN0UGFnZUNhbGxiYWNrKSByZXR1cm4gdHJ1ZTsKICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoJHRoaXMtPmlzUHJvZHVjdFBhZ2VDYWxsYmFjaykgfHwgJHRoaXMtPmlzTGljZW5zZVNldHRpbmdzUGFnZSgpOwogICAgfQoKICAgIC8qCiAgICAgKiBBUEkgTUVUSE9EUwogICAgICovCgogICAgLyoqCiAgICAgKiBNYWtlIGEgcmVxdWVzdCB0byAiaW5mbyIgZW5kcG9pbnQgb2YgdGhlIEFQSS4KICAgICAqIEByZXR1cm4gbnVsbHxvYmplY3QKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYWtlUmVxdWVzdFByb2R1Y3RJbmZvKCk6ID9vYmplY3QgewogICAgICAgICRyZXNwb25zZSA9ICR0aGlzLT5jYWxsQXBpKCdpbmZvJyk7CiAgICAgICAgaWYoISRyZXNwb25zZSB8fCAkdGhpcy0+aGFuZGxlQVBJUmVzcG9uc2VGb3JJbmZvKCRyZXNwb25zZSkgPT09IGZhbHNlKSByZXR1cm4gbnVsbDsKCiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRSZXNwb25zZUJvZHkoJHJlc3BvbnNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1ha2UgYSByZXF1ZXN0IHRvICJ1bmluc3RhbGwiIGVuZHBvaW50IG9mIHRoZSBBUEkuCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKiBAc2luY2UgMS45LjAKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYWtlUmVxdWVzdFVuaW5zdGFsbCgpOiBhcnJheSB7CiAgICAgICAgJHJlc3BvbnNlID0gJHRoaXMtPmNhbGxBcGkoJ3VuaW5zdGFsbCcpOwogICAgICAgIHJldHVybiAkcmVzcG9uc2UgPyAoYXJyYXkpICR0aGlzLT5nZXRSZXNwb25zZUJvZHkoJHJlc3BvbnNlKSA6IFtdOwogICAgfQoKICAgIC8qCiAgICAgKgogICAgICovCgogICAgLyoqCiAgICAgKiBNYWtlIGFuIEFQSSBjYWxsCiAgICAgKgogICAgICogQHBhcmFtIHN0cmluZyAkYWN0aW9uCiAgICAgKiBAcmV0dXJuIGZhbHNlfGFycmF5IEZhbHNlIGlmIGZhaWxzLCB0aGUgcmVzcG9uc2UgYXMgYXJyYXkgaWYgc3VjY2VlZHMuIFNlZSB7QGxpbmsgd3BfcmVtb3RlX2dldCgpfS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjYWxsQXBpKCRhY3Rpb24pIHsKICAgICAgICBpZighJHRoaXMtPmdldExpY2Vuc2VLZXkoKSkgewogICAgICAgICAgICAkdGhpcy0+aGFuZGxlTGljZW5zZUVycm9yKCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgICRwYXJhbXMgPSBbCiAgICAgICAgICAgICdwJyA9PiAkdGhpcy0+cHJvZHVjdElkLAogICAgICAgICAgICAnbCcgPT4gJHRoaXMtPmdldExpY2Vuc2VLZXkoKSwKICAgICAgICAgICAgJ2QnID0+ICR0aGlzLT5nZXRTZXJ2ZXJOYW1lKCkKICAgICAgICBdOwoKICAgICAgICAkdXJsID0gJHRoaXMtPmFwaVVybCAuICcvJyAuICRhY3Rpb247CiAgICAgICAgJHVybCAuPSAnPycgLiBodHRwX2J1aWxkX3F1ZXJ5KCRwYXJhbXMpOwoKICAgICAgICAkcmVzcG9uc2UgPSB3cF9yZW1vdGVfZ2V0KCR1cmwpOwogICAgICAgICR0aGlzLT51cGRhdGVMYXN0UmVxdWVzdERhdGVBc05vdygpOwoKICAgICAgICBpZiAoaXNfd3BfZXJyb3IoJHJlc3BvbnNlKSkgewogICAgICAgICAgICAkdGhpcy0+aGFuZGxlTGljZW5zZUVycm9yKCk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzcG9uc2U7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBoYW5kbGVMaWNlbnNlRXJyb3IoKTogdm9pZCB7CiAgICAgICAgJHRoaXMtPmluaXRFeHBpcmF0aW9uRG9Ob3RPdmVycmlkZSgpOwogICAgICAgICR0aGlzLT5zZXRFcnJvck1lc3NhZ2UoKTsKCiAgICAgICAgaWYgKCR0aGlzLT5jYWxsZWRGcm9tQWN0aXZhdGlvbkhvb2spIHsKICAgICAgICAgICAgJHRoaXMtPnJlc2V0VHJpYWxDb3VudCgpOwogICAgICAgICAgICAkdHJpYWxDb3VudCA9ICR0aGlzLT5nZXRUcmlhbENvdW50KCk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0cmlhbENvdW50ID0gJHRoaXMtPmdldFRyaWFsQ291bnQoKSAtIDE7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVUcmlhbENvdW50KCR0cmlhbENvdW50KTsKICAgICAgICB9CgogICAgICAgIGlmICgkdHJpYWxDb3VudCA8IDEpIHsKICAgICAgICAgICAgJHRoaXMtPnNldFZhbGlkKCcwJyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gaGFuZGxlQVBJUmVzcG9uc2VGb3JJbmZvKGFycmF5ICRyZXNwb25zZSk6IGJvb2wgewogICAgICAgICRjb2RlID0gJHRoaXMtPmdldFJlc3BvbnNlQ29kZSgkcmVzcG9uc2UpOwogICAgICAgICRib2R5ID0gJHRoaXMtPmdldFJlc3BvbnNlQm9keSgkcmVzcG9uc2UpOwoKICAgICAgICBpZiAoJGNvZGUgPT09IG51bGwgfHwgKCRjb2RlID49IDIwMCAmJiAkY29kZSA8IDMwMCkpIHsKICAgICAgICAgICAgaWYgKCRib2R5ID09PSBudWxsIHx8ICRjb2RlID09PSBudWxsIHx8ICEkY29kZSkgewogICAgICAgICAgICAgICAgJHRoaXMtPmluaXRFeHBpcmF0aW9uRG9Ob3RPdmVycmlkZSgpOwogICAgICAgICAgICAgICAgJHRoaXMtPnJlc2V0VHJpYWxDb3VudCgpOwogICAgICAgICAgICAgICAgJHRoaXMtPnNldEVycm9yTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkbGVnaXQgPSAoaXNzZXQoJGJvZHktPnZhbGlkKSAmJiAkYm9keS0+dmFsaWQpIHx8ICFpc3NldCgkYm9keS0+ZXJyb3IpOwogICAgICAgICAgICBpZiAoJGxlZ2l0KSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVzZXRUcmlhbENvdW50KCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2V0VmFsaWQoJzEnKTsKICAgICAgICAgICAgICAgICR0aGlzLT5zZXRFcnJvck1lc3NhZ2UobnVsbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJHZhbGlkID0gJHRoaXMtPmdldFZhbGlkKCk7CiAgICAgICAgICAgIGlmICgkdmFsaWQgPT09ICcxJykgJHRoaXMtPmluaXRFeHBpcmF0aW9uKCk7CgogICAgICAgICAgICBpZihpc3NldCgkYm9keS0+ZXhwaXJhdGlvbikpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5pbml0RXhwaXJhdGlvbigoc3RyaW5nKSAkYm9keS0+ZXhwaXJhdGlvbiwgdHJ1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICR0cmlhbENvdW50ID0gJHRoaXMtPmdldFRyaWFsQ291bnQoKSAtIDE7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVUcmlhbENvdW50KCR0cmlhbENvdW50KTsKICAgICAgICAgICAgaWYgKCR0cmlhbENvdW50IDwgMSkgewogICAgICAgICAgICAgICAgJHRoaXMtPnNldFZhbGlkKCcwJyk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3JNZXNzYWdlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSBlbHNlIGlmICgkY29kZSA+PSA1MDAgJiYgJGNvZGUgPCA2MDApIHsKICAgICAgICAgICAgJHRoaXMtPmluaXRFeHBpcmF0aW9uKCk7CiAgICAgICAgICAgICR0aGlzLT5yZXNldFRyaWFsQ291bnQoKTsKCiAgICAgICAgfSBlbHNlIGlmICgkY29kZSA9PT0gNDAzKSB7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVUcmlhbENvdW50KDApOwogICAgICAgICAgICAkdGhpcy0+c2V0VmFsaWQoJzAnKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnNldFZhbGlkKCcwJyk7CiAgICAgICAgICAgICR0aGlzLT51cGRhdGVUcmlhbENvdW50KDApOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNldEVycm9yTWVzc2FnZSgkYm9keSAmJiBpc3NldCgkYm9keS0+ZXJyb3IpID8gJGJvZHktPmVycm9yIDogZmFsc2UpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkcmVzcG9uc2UKICAgICAqIEByZXR1cm4gb2JqZWN0fG51bGwgVGhlIHJlc3BvbnNlIGFzIG9iamVjdCAocGFyc2VkIEpTT04gdmFsdWUpLiBPdGhlcndpc2UsIG51bGwuCiAgICAgKiBAc2luY2UgMS45LjAKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRSZXNwb25zZUJvZHkoYXJyYXkgJHJlc3BvbnNlKTogP29iamVjdCB7CiAgICAgICAgJHJlc3BvbnNlQm9keSA9IHdwX3JlbW90ZV9yZXRyaWV2ZV9ib2R5KCRyZXNwb25zZSk7CiAgICAgICAgcmV0dXJuIGpzb25fZGVjb2RlKCRyZXNwb25zZUJvZHkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFycmF5ICRyZXNwb25zZQogICAgICogQHJldHVybiBpbnR8bnVsbAogICAgICogQHNpbmNlIDEuOS4wCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UmVzcG9uc2VDb2RlKGFycmF5ICRyZXNwb25zZSk6ID9pbnQgewogICAgICAgICRjb2RlID0gd3BfcmVtb3RlX3JldHJpZXZlX3Jlc3BvbnNlX2NvZGUoJHJlc3BvbnNlKTsKICAgICAgICByZXR1cm4gJGNvZGUgIT09ICcnID8gKGludCkgJGNvZGUgOiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0U2VydmVyTmFtZSgpOiBzdHJpbmcgewogICAgICAgICRob3N0ID0gcGFyc2VfdXJsKGdldF9ob21lX3VybCgpLCBQSFBfVVJMX0hPU1QpOwogICAgICAgIGlmICgkaG9zdCkgcmV0dXJuIChzdHJpbmcpICRob3N0OwoKICAgICAgICByZXR1cm4gKHN0cmluZykgKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddID86ICcnKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXRFeHBpcmF0aW9uRG9Ob3RPdmVycmlkZSgpOiBzdHJpbmcgewogICAgICAgICRjdXJyZW50VmFsaWQgPSAkdGhpcy0+Z2V0VmFsaWQoKTsKICAgICAgICBpZiAoJGN1cnJlbnRWYWxpZCAhPT0gbnVsbCAmJiAkY3VycmVudFZhbGlkICE9PSAnMScpIHJldHVybiAkY3VycmVudFZhbGlkOwoKICAgICAgICByZXR1cm4gJHRoaXMtPmluaXRFeHBpcmF0aW9uKCk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBpbml0RXhwaXJhdGlvbig/c3RyaW5nICRleHBpcmF0aW9uRGF0ZVN0ciA9IG51bGwsIGJvb2wgJHRyYW5zbGF0ZVRvTG9jYWxUaW1lID0gZmFsc2UpOiBzdHJpbmcgewogICAgICAgICRkdCA9ICRleHBpcmF0aW9uRGF0ZVN0ciA/IG5ldyBEYXRlVGltZSgkZXhwaXJhdGlvbkRhdGVTdHIpIDogJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKTsKICAgICAgICBpZiAoJHRyYW5zbGF0ZVRvTG9jYWxUaW1lICYmICRleHBpcmF0aW9uRGF0ZVN0cikgJHRoaXMtPm1vZGlmeURhdGVUb0xvY2FsVGltZSgkZHQpOwoKICAgICAgICAkZHQtPm1vZGlmeSgnKzMgZGF5cycpOwoKICAgICAgICAkdmFsaWQgPSAkZHQtPmZvcm1hdCgkdGhpcy0+bXlzcWxEYXRlVGltZUZvcm1hdCk7CgogICAgICAgIGlmICgkZXhwaXJhdGlvbkRhdGVTdHIpIHsKICAgICAgICAgICAgJG5vdyA9ICR0aGlzLT5nZXROb3dBc0RhdGVUaW1lKCk7CiAgICAgICAgICAgIGlmKCRkdCA8PSAkbm93KSAkdmFsaWQgPSAnMCc7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0VmFsaWQoJHZhbGlkKTsKCiAgICAgICAgcmV0dXJuICR2YWxpZDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldExpY2Vuc2VLZXlPcHRpb25OYW1lKCk6IHN0cmluZyB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRQcmVmaXgoKSAuICdfbGljZW5zZV9rZXknOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0TGljZW5zZUtleSgpOiA/c3RyaW5nIHsKICAgICAgICAka2V5ID0gZ2V0X29wdGlvbigkdGhpcy0+Z2V0TGljZW5zZUtleU9wdGlvbk5hbWUoKSwgbnVsbCk7CiAgICAgICAgcmV0dXJuICRrZXkgIT09IG51bGwgPyB0cmltKCRrZXkpIDogbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFZhbGlkT3B0aW9uTmFtZSgpOiBzdHJpbmcgewogICAgICAgIHJldHVybiBtZDUoJHRoaXMtPmdldFByZWZpeCgpIC4gJ190b29sbScpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0VmFsaWQoc3RyaW5nICR2YWx1ZSk6IHZvaWQgewogICAgICAgIHVwZGF0ZV9vcHRpb24oJHRoaXMtPmdldFZhbGlkT3B0aW9uTmFtZSgpLCBiYXNlNjRfZW5jb2RlKCR2YWx1ZSksIHRydWUpOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0VmFsaWQoKTogc3RyaW5nIHsKICAgICAgICAkdmFsaWQgPSBnZXRfb3B0aW9uKCR0aGlzLT5nZXRWYWxpZE9wdGlvbk5hbWUoKSwgbnVsbCk7CiAgICAgICAgaWYgKCR2YWxpZCAhPT0gbnVsbCkgewogICAgICAgICAgICAkdmFsID0gYmFzZTY0X2RlY29kZSgoc3RyaW5nKSAkdmFsaWQpOwoKICAgICAgICAgICAgaWYgKCR2YWwgIT09ICcwJyAmJiAkdmFsICE9PSAnMScpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbmV3IERhdGVUaW1lKCR2YWwpOwoKICAgICAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5pbml0RXhwaXJhdGlvbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gKHN0cmluZykgJHZhbDsKICAgICAgICB9CgogICAgICAgICR0cmlhbENvdW50ID0gJHRoaXMtPmdldFRyaWFsQ291bnQoKTsKICAgICAgICBpZiAoJHRyaWFsQ291bnQgPCAxKSB7CiAgICAgICAgICAgICR2YWxpZCA9ICcwJzsKICAgICAgICAgICAgJHRoaXMtPnNldFZhbGlkKCR2YWxpZCk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR2YWxpZCA9ICR0aGlzLT5pbml0RXhwaXJhdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICR2YWxpZDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZU9wdGlvbk5hbWUoKTogc3RyaW5nIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZWZpeCgpIC4gJ19saWNlbnNlX21lc3NhZ2UnOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlKCk6ID9zdHJpbmcgewogICAgICAgICRtc2cgPSBnZXRfb3B0aW9uKCR0aGlzLT5nZXRFcnJvck1lc3NhZ2VPcHRpb25OYW1lKCksIG51bGwpOwogICAgICAgIHJldHVybiAkbXNnID09PSBudWxsID8gbnVsbCA6IChzdHJpbmcpICRtc2c7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nfG51bGx8ZmFsc2UgJG1lc3NhZ2UgSWYgZmFsc2UsIGRlZmF1bHQgZXJyb3IgbWVzc2FnZSB3aWxsIGJlIHNob3duLiBPdGhlcndpc2UsIHRoZSBnaXZlbiBtZXNzYWdlIHdpbGwgYmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93bi4gSWYgbnVsbCwgdGhlIGVycm9yIG1lc3NhZ2Ugd2lsbCBiZSByZW1vdmVkLgogICAgICogQHNpbmNlIDEuOS4wCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0RXJyb3JNZXNzYWdlKCRtZXNzYWdlID0gZmFsc2UpOiB2b2lkIHsKICAgICAgICBpZiAoJG1lc3NhZ2UgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICRtZXNzYWdlID0gX18oIlRoZSBsaWNlbnNlIGNvdWxkIG5vdCBiZSBjaGVja2VkIHdpdGggdGhlIHNlcnZlci4gUGxlYXNlIHRyeSBzYXZpbmcgeW91ciBsaWNlbnNlCiAgICAgICAgICAgICAgICBzZXR0aW5ncyBhZ2FpbiBpbiBhIGZldyBtaW51dGVzLiBJZiB0aGUgZXJyb3IgcGVyc2lzdHMsIHBsZWFzZSBjb250YWN0IHRoZSBkZXZlbG9wZXIuIiwgJHRoaXMtPnRleHREb21haW4pOwogICAgICAgIH0KICAgICAgICB1cGRhdGVfb3B0aW9uKCR0aGlzLT5nZXRFcnJvck1lc3NhZ2VPcHRpb25OYW1lKCksICRtZXNzYWdlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFRyaWFsQ291bnRPcHRpb25OYW1lKCk6IHN0cmluZyB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5nZXRQcmVmaXgoKSAuICdfdHJpYWxjJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFRyaWFsQ291bnQoKTogaW50IHsKICAgICAgICAkdmFsID0gZ2V0X29wdGlvbigkdGhpcy0+Z2V0VHJpYWxDb3VudE9wdGlvbk5hbWUoKSwgZmFsc2UpOwogICAgICAgIGlmICgkdmFsID09PSBmYWxzZSkgewogICAgICAgICAgICAkdGhpcy0+cmVzZXRUcmlhbENvdW50KCk7CiAgICAgICAgICAgICR2YWwgPSBnZXRfb3B0aW9uKCR0aGlzLT5nZXRUcmlhbENvdW50T3B0aW9uTmFtZSgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1pbigoaW50KSAkdmFsLCAzKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVwZGF0ZVRyaWFsQ291bnQoaW50ICRjb3VudCk6IHZvaWQgewogICAgICAgIHVwZGF0ZV9vcHRpb24oJHRoaXMtPmdldFRyaWFsQ291bnRPcHRpb25OYW1lKCksIG1heCgwLCAkY291bnQpKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlc2V0VHJpYWxDb3VudCgpOiB2b2lkIHsKICAgICAgICAkdGhpcy0+dXBkYXRlVHJpYWxDb3VudCgzKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldExhc3RSZXF1ZXN0RGF0ZU9wdGlvbk5hbWUoKTogc3RyaW5nIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZWZpeCgpIC4gJ19sYXN0X3JlcV9kYXRlJzsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gRGF0ZVRpbWUKICAgICAqIEBzaW5jZSAxLjkuMAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldExhc3RSZXF1ZXN0RGF0ZSgpOiBEYXRlVGltZSB7CiAgICAgICAgaWYgKCR0aGlzLT5sYXN0UmVxdWVzdERhdGUgIT09IG51bGwpIHJldHVybiAkdGhpcy0+bGFzdFJlcXVlc3REYXRlOwoKICAgICAgICAkZGF0ZSA9IG51bGw7CiAgICAgICAgJGRhdGVTdHIgPSBnZXRfb3B0aW9uKCR0aGlzLT5nZXRMYXN0UmVxdWVzdERhdGVPcHRpb25OYW1lKCkpOwogICAgICAgIGlmICgkZGF0ZVN0cikgewogICAgICAgICAgICAkZGF0ZSA9IG5ldyBEYXRlVGltZSgkZGF0ZVN0cik7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRkYXRlID0gJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKTsKICAgICAgICAgICAgJGRhdGUtPm1vZGlmeSgnLTMwIGRheScpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmxhc3RSZXF1ZXN0RGF0ZSA9ICRkYXRlOwoKICAgICAgICByZXR1cm4gJGRhdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgaWYgYSBuZXcgQVBJIHJlcXVlc3QgY2FuIGJlIG1hZGUKICAgICAqCiAgICAgKiBAcmV0dXJuIGJvb2wgVHJ1ZSBpZiBhIG5ldyBBUEkgcmVxdWVzdCBjYW4gYmUgbWFkZQogICAgICogQHNpbmNlIDEuOS4wCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gY2FuTWFrZVJlcXVlc3QoKTogYm9vbCB7CiAgICAgICAgJG5vdyAgPSAkdGhpcy0+Z2V0Tm93QXNEYXRlVGltZSgpOwogICAgICAgICRuZXdSZXFEYXRlID0gJHRoaXMtPmdldERhdGVGb3JOZXdSZXF1ZXN0KCk7CgogICAgICAgIHJldHVybiAkbm93ID49ICRuZXdSZXFEYXRlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBkYXRlIHdoZW4gYSBuZXcgQVBJIHJlcXVlc3QgaXMgYWxsb3dlZCB0byBiZSBtYWRlLgogICAgICoKICAgICAqIEByZXR1cm4gRGF0ZVRpbWUKICAgICAqIEBzaW5jZSAxLjkuMAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldERhdGVGb3JOZXdSZXF1ZXN0KCk6IERhdGVUaW1lIHsKICAgICAgICAkbGFzdCA9IChuZXcgRGF0ZVRpbWUoKSktPnNldFRpbWVzdGFtcCgkdGhpcy0+Z2V0TGFzdFJlcXVlc3REYXRlKCktPmdldFRpbWVzdGFtcCgpKTsKCiAgICAgICAgLy8gQWxsb3cgMjAgc2Vjb25kcwogICAgICAgICRsYXN0LT5tb2RpZnkoJysyMCBzZWMnKTsKCiAgICAgICAgcmV0dXJuICRsYXN0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGhvdyBtYW55IHNlY29uZHMgcmVtYWluIHRvIG1ha2UgYSBuZXcgQVBJIHJlcXVlc3QKICAgICAqCiAgICAgKiBAcmV0dXJuIGludAogICAgICogQHNpbmNlIDEuOS4wCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gZ2V0UmVtYWluaW5nU2Vjb25kc0Zvck5ld1JlcXVlc3QoKTogaW50IHsKICAgICAgICAkZHROb3cgICAgICAgICAgICAgID0gJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKTsKICAgICAgICAkZHRGb3JOZXdSZXF1ZXN0ICAgID0gJHRoaXMtPmdldERhdGVGb3JOZXdSZXF1ZXN0KCk7CgogICAgICAgICRub3dUaW1lc3RhbXAgICAgICAgPSAkZHROb3ctPmdldFRpbWVzdGFtcCgpOwogICAgICAgICRyZXF1ZXN0VGltZXN0YW1wICAgPSAkZHRGb3JOZXdSZXF1ZXN0LT5nZXRUaW1lc3RhbXAoKTsKCiAgICAgICAgJHNlYyA9ICRyZXF1ZXN0VGltZXN0YW1wIC0gJG5vd1RpbWVzdGFtcDsKCiAgICAgICAgcmV0dXJuIG1heCgoaW50KSAkc2VjLCAwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIGxhc3QgcmVxdWVzdCBkYXRlIGFzIG5vdy4KICAgICAqIEBzaW5jZSAxLjkuMAogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVwZGF0ZUxhc3RSZXF1ZXN0RGF0ZUFzTm93KCk6IHZvaWQgewogICAgICAgIHVwZGF0ZV9vcHRpb24oJHRoaXMtPmdldExhc3RSZXF1ZXN0RGF0ZU9wdGlvbk5hbWUoKSwgJHRoaXMtPmdldE5vd0FzRGF0ZVRpbWUoKS0+Zm9ybWF0KCR0aGlzLT5teXNxbERhdGVUaW1lRm9ybWF0KSk7CiAgICAgICAgJHRoaXMtPmxhc3RSZXF1ZXN0RGF0ZSA9IG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRBZG1pbk5vdGljZUhpZGRlbk9wdGlvbk5hbWUoKTogc3RyaW5nIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmdldFByZWZpeCgpIC4gJ19hZG1pbl9ub3RpY2VfaGlkZGVuJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGlzQWRtaW5Ob3RpY2VIaWRkZW4oKTogYm9vbCB7CiAgICAgICAgaWYgKCR0aGlzLT5hZG1pbk5vdGljZUhpZGRlbiA9PT0gbnVsbCkgewogICAgICAgICAgICAkdGhpcy0+YWRtaW5Ob3RpY2VIaWRkZW4gPSBnZXRfb3B0aW9uKCR0aGlzLT5nZXRBZG1pbk5vdGljZUhpZGRlbk9wdGlvbk5hbWUoKSwgbnVsbCkgPT0gMTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5hZG1pbk5vdGljZUhpZGRlbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICRpc0hpZGRlbgogICAgICogQHNpbmNlIDEuOS4wCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0QWRtaW5Ob3RpY2VIaWRkZW4oJGlzSGlkZGVuKTogdm9pZCB7CiAgICAgICAgdXBkYXRlX29wdGlvbigkdGhpcy0+Z2V0QWRtaW5Ob3RpY2VIaWRkZW5PcHRpb25OYW1lKCksICRpc0hpZGRlbiA/IDEgOiAwKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEhpZGVBZG1pbk5vdGljZVVybFBhcmFtTmFtZSgpOiBzdHJpbmcgewogICAgICAgIHJldHVybiAkdGhpcy0+Z2V0UHJlZml4KCkgLiAnX2hpZGVfYWRtaW5fbm90aWNlJzsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldEN1cnJlbnRQYWdlVXJsKGFycmF5ICRwYXJhbXMgPSBbXSk6IHN0cmluZyB7CiAgICAgICAgJGN1cnJlbnRQYWdlVXJsID0gZ2V0X3NpdGVfdXJsKG51bGwsICRfU0VSVkVSWydSRVFVRVNUX1VSSSddLCAnYWRtaW4nKTsKICAgICAgICAkcXVlcnkgPSAnJzsKICAgICAgICBpZiAoJHBhcmFtcykgewogICAgICAgICAgICAkcXVlcnkgPSAoc3RycG9zKCRjdXJyZW50UGFnZVVybCwgJz8nKSAhPT0gZmFsc2UgPyAnJicgOiAnPycpIC4gaHR0cF9idWlsZF9xdWVyeSgkcGFyYW1zKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkY3VycmVudFBhZ2VVcmwgLiAkcXVlcnk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRFdmVudE5hbWUoKTogc3RyaW5nIHsKICAgICAgICByZXR1cm4gJ3dwdHNsbV8nIC4gbWQ1KCR0aGlzLT50ZXh0RG9tYWluKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldFBhZ2VTbHVnKCk6IHN0cmluZyB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50ZXh0RG9tYWluIC4gJ19saWNlbnNlX3NldHRpbmdzJzsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIHN0cmluZyB0byBiZSB1c2VkIGFzIHByZWZpeCBmb3Igb3B0aW9uIG5hbWVzLgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQcmVmaXgoKTogc3RyaW5nIHsKICAgICAgICByZXR1cm4gc3Vic3RyKCR0aGlzLT50ZXh0RG9tYWluLCAwLCAxKSA9PSAnXycgPyAkdGhpcy0+dGV4dERvbWFpbiA6ICdfJyAuICR0aGlzLT50ZXh0RG9tYWluOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHZlcnNpb24gb2YgdGhlIHBsdWdpbi90aGVtZS4KICAgICAqIEByZXR1cm4gc3RyaW5nfG51bGwKICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRMb2NhbFZlcnNpb24oKTogP3N0cmluZyB7CiAgICAgICAgaWYoJHRoaXMtPmlzUGx1Z2luKCkpIHsKICAgICAgICAgICAgJHBsdWdpbkRhdGEgPSAkdGhpcy0+cGx1Z2luRmlsZVBhdGggIT09IG51bGwKICAgICAgICAgICAgICAgID8gZ2V0X3BsdWdpbl9kYXRhKCR0aGlzLT5wbHVnaW5GaWxlUGF0aCwgZmFsc2UpCiAgICAgICAgICAgICAgICA6IFtdOwogICAgICAgICAgICByZXR1cm4gaXNzZXQoJHBsdWdpbkRhdGFbIlZlcnNpb24iXSkgPyAoc3RyaW5nKSAkcGx1Z2luRGF0YVsiVmVyc2lvbiJdIDogbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIFRoaXMgaXMgYSB0aGVtZQogICAgICAgICR0aGVtZURhdGEgPSB3cF9nZXRfdGhlbWUoKTsKICAgICAgICByZXR1cm4gaXNzZXQoJHRoZW1lRGF0YS0+VmVyc2lvbikgPyAoc3RyaW5nKSAkdGhlbWVEYXRhLT5WZXJzaW9uIDogbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIGlmIHRoaXMgaXMgYSBwbHVnaW4sIGZhbHNlIG90aGVyd2lzZS4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBpc1BsdWdpbigpOiBib29sIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnR5cGUgPT0gJ3BsdWdpbic7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXliZVJ1bigpOiB2b2lkIHsKICAgICAgICAkbGFzdFJ1biA9IGdldF9vcHRpb24oJHRoaXMtPmdldEV2ZW50TmFtZSgpIC4gJ19ydW4nKTsKICAgICAgICBpZighJGxhc3RSdW4gfHwgJGxhc3RSdW4gPCB0aW1lKCkgLSAyLjUgKiAyNCAqIDYwICogNjApIHsKICAgICAgICAgICAgJHRoaXMtPnZhbGlkYXRlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gdXBkYXRlTGFzdFJ1bigpOiB2b2lkIHsKICAgICAgICB1cGRhdGVfb3B0aW9uKCR0aGlzLT5nZXRFdmVudE5hbWUoKSAuICdfcnVuJywgdGltZSgpLCB0cnVlKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGdldE5vd0FzRGF0ZVRpbWUoKTogRGF0ZVRpbWUgewogICAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoKHN0cmluZykgY3VycmVudF90aW1lKCdteXNxbCcpKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1vZGlmeSBhIHVuaXZlcnNhbCB0aW1lIHRvIGNvbnZlcnQgaXQgdG8gbG9jYWwgdGltZQogICAgICogQHBhcmFtIERhdGVUaW1lICAkZHQKICAgICAqIEBwYXJhbSBib29sfGludCAgJGdtdE9mZnNldCBHTVQgb2Zmc2V0IG9mIHRhcmdldCBsb2NhbCB0aW1lLiBJZiBmYWxzZSwgV29yZFByZXNzIHNldHRpbmdzIHdpbGwgYmUgdXNlZCB0byBnZXQKICAgICAqICAgICAgICAgICAgICAgICAgR01UIG9mZnNldC4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBtb2RpZnlEYXRlVG9Mb2NhbFRpbWUoJGR0LCAkZ210T2Zmc2V0ID0gZmFsc2UpOiB2b2lkIHsKICAgICAgICBpZighJGdtdE9mZnNldCkgJGdtdE9mZnNldCA9IGdldF9vcHRpb24oJ2dtdF9vZmZzZXQnKTsKICAgICAgICAkZHQtPm1vZGlmeSgoJGdtdE9mZnNldCA+PSAwID8gIisiIDogIi0iKSAuICRnbXRPZmZzZXQgLiAiIGhvdXIiIC4gKCRnbXRPZmZzZXQgPiAxIHx8ICRnbXRPZmZzZXQgPCAtMSA/ICJzIiA6ICIiKSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRQcm9kdWN0TmFtZSgpOiBzdHJpbmcgewogICAgICAgIHJldHVybiBfXygkdGhpcy0+cHJvZHVjdE5hbWUsICR0aGlzLT50ZXh0RG9tYWluKTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNjaGVkdWxlRXZlbnRzKCk6IHZvaWQgewogICAgICAgICR0aGlzLT5yZW1vdmVTY2hlZHVsZWRFdmVudHMoKTsKICAgICAgICBpZighd3BfZ2V0X3NjaGVkdWxlKCR0aGlzLT5nZXRFdmVudE5hbWUoKSkpIHsKICAgICAgICAgICAgJGludGVydmFsTmFtZSAgICAgICA9ICdfd3B0c2xtXzFfZGF5JzsKICAgICAgICAgICAgJGludGVydmFsU2Vjb25kcyAgICA9ICR0aGlzLT5nZXRJbnRlcnZhbHMoKVskaW50ZXJ2YWxOYW1lXVsxXTsKCiAgICAgICAgICAgIHdwX3NjaGVkdWxlX2V2ZW50KHRpbWUoKSArICRpbnRlcnZhbFNlY29uZHMsICRpbnRlcnZhbE5hbWUsICR0aGlzLT5nZXRFdmVudE5hbWUoKSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcmVtb3ZlU2NoZWR1bGVkRXZlbnRzKCk6IHZvaWQgewogICAgICAgICRldmVudE5hbWVzID0gWyR0aGlzLT5nZXRFdmVudE5hbWUoKV07CiAgICAgICAgZm9yZWFjaCgkZXZlbnROYW1lcyBhcyAkZXZlbnROYW1lKSB7CiAgICAgICAgICAgIGlmKCR0aW1lc3RhbXAgPSB3cF9uZXh0X3NjaGVkdWxlZCgkZXZlbnROYW1lKSkgewogICAgICAgICAgICAgICAgd3BfdW5zY2hlZHVsZV9ldmVudCgkdGltZXN0YW1wLCAkZXZlbnROYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHJlZ2lzdGVySW50ZXJ2YWxzKCk6IHZvaWQgewogICAgICAgICRpbnRlcnZhbHMgPSAkdGhpcy0+Z2V0SW50ZXJ2YWxzKCk7CiAgICAgICAgYWRkX2ZpbHRlcignY3Jvbl9zY2hlZHVsZXMnLCBmdW5jdGlvbigkc2NoZWR1bGVzKSB1c2UgKCRpbnRlcnZhbHMpIHsKICAgICAgICAgICAgZm9yZWFjaCgkaW50ZXJ2YWxzIGFzICRuYW1lID0+ICRpbnRlcnZhbCkgewogICAgICAgICAgICAgICAgJHNjaGVkdWxlc1skbmFtZV0gPSBbCiAgICAgICAgICAgICAgICAgICAgJ2ludGVydmFsJyAgPT4gICRpbnRlcnZhbFsxXSwKICAgICAgICAgICAgICAgICAgICAnZGlzcGxheScgICA9PiAgJGludGVydmFsWzBdCiAgICAgICAgICAgICAgICBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHNjaGVkdWxlczsKICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXk8c3RyaW5nLCBhcnJheT4KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBnZXRJbnRlcnZhbHMoKTogYXJyYXkgewogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICdfd3B0c2xtXzFfbWludXRlJyA9PiBbJ0V2ZXJ5IG1pbnV0ZScsICA2MF0sCiAgICAgICAgICAgICdfd3B0c2xtXzFfZGF5JyAgICA9PiBbJ0V2ZXJ5IGRheScsICAgICAyNCAqIDYwICogNjBdLAogICAgICAgICAgICAnX3dwdHNsbV8yX2RheXMnICAgPT4gWydFdmVyeSAyIGRheXMnLCAgMiAqIDI0ICogNjAgKiA2MF0sCiAgICAgICAgXTsKICAgIH0KCn0KCn0=