@giro3d/giro3d
Version:
A JS/WebGL framework for 3D geospatial data visualization
13 lines (11 loc) • 749 kB
JavaScript
/*
* Copyright (c) 2015-2018, IGN France.
* Copyright (c) 2018-2026, Giro3D team.
* SPDX-License-Identifier: MIT
*/
// Note: this function has to be in its own file to avoid circular dependencies
// when using webpack (and possibly other bundlers)
// It cannot be in worker.ts nor in config.ts, unfortunately.
export default function createWorker(wasmBinary) {
return () => {
const worker = new Worker(URL.createObjectURL(new Blob([atob('InVzZSBzdHJpY3QiOygoKT0+e3ZhciBqZz1PYmplY3QuY3JlYXRlO3ZhciBGaD1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIFpnPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7dmFyICRnPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzO3ZhciBKZz1PYmplY3QuZ2V0UHJvdG90eXBlT2YsS2c9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTt2YXIgT2g9KG49PnR5cGVvZiByZXF1aXJlPCJ1Ij9yZXF1aXJlOnR5cGVvZiBQcm94eTwidSI/bmV3IFByb3h5KG4se2dldDoodCxlKT0+KHR5cGVvZiByZXF1aXJlPCJ1Ij9yZXF1aXJlOnQpW2VdfSk6bikoZnVuY3Rpb24obil7aWYodHlwZW9mIHJlcXVpcmU8InUiKXJldHVybiByZXF1aXJlLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt0aHJvdyBFcnJvcignRHluYW1pYyByZXF1aXJlIG9mICInK24rJyIgaXMgbm90IHN1cHBvcnRlZCcpfSk7dmFyIHN0PShuLHQpPT4oKT0+KHR8fG4oKHQ9e2V4cG9ydHM6e319KS5leHBvcnRzLHQpLHQuZXhwb3J0cyk7dmFyIFFnPShuLHQsZSxpKT0+e2lmKHQmJnR5cGVvZiB0PT0ib2JqZWN0Inx8dHlwZW9mIHQ9PSJmdW5jdGlvbiIpZm9yKGxldCByIG9mICRnKHQpKSFLZy5jYWxsKG4scikmJnIhPT1lJiZGaChuLHIse2dldDooKT0+dFtyXSxlbnVtZXJhYmxlOiEoaT1aZyh0LHIpKXx8aS5lbnVtZXJhYmxlfSk7cmV0dXJuIG59O3ZhciBCaD0obix0LGUpPT4oZT1uIT1udWxsP2pnKEpnKG4pKTp7fSxRZyh0fHwhbnx8IW4uX19lc01vZHVsZT9GaChlLCJkZWZhdWx0Iix7dmFsdWU6bixlbnVtZXJhYmxlOiEwfSk6ZSxuKSk7dmFyIHpoPXN0KEdoPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShHaCwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSl9KTt2YXIga2g9c3QobXM9PnsidXNlIHN0cmljdCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KG1zLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KTttcy5IaWVyYXJjaHk9dm9pZCAwO21zLkhpZXJhcmNoeT17cGFyc2U6dDB9O2Z1bmN0aW9uIHQwKG4pe3JldHVybiBPYmplY3QuZW50cmllcyhuKS5yZWR1Y2UoKHQsW2UsaV0pPT4oaT09PS0xP3QucGFnZXNbZV09e306aSYmKHQubm9kZXNbZV09e3BvaW50Q291bnQ6aX0pLHQpLHtub2Rlczp7fSxwYWdlczp7fX0pfX0pO3ZhciBIaD1zdChNbj0+eyJ1c2Ugc3RyaWN0Ijt2YXIgZTA9TW4mJk1uLl9fY3JlYXRlQmluZGluZ3x8KE9iamVjdC5jcmVhdGU/KGZ1bmN0aW9uKG4sdCxlLGkpe2k9PT12b2lkIDAmJihpPWUpO3ZhciByPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodCxlKTsoIXJ8fCgiZ2V0ImluIHI/IXQuX19lc01vZHVsZTpyLndyaXRhYmxlfHxyLmNvbmZpZ3VyYWJsZSkpJiYocj17ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdFtlXX19KSxPYmplY3QuZGVmaW5lUHJvcGVydHkobixpLHIpfSk6KGZ1bmN0aW9uKG4sdCxlLGkpe2k9PT12b2lkIDAmJihpPWUpLG5baV09dFtlXX0pKSxWaD1NbiYmTW4uX19leHBvcnRTdGFyfHxmdW5jdGlvbihuLHQpe2Zvcih2YXIgZSBpbiBuKWUhPT0iZGVmYXVsdCImJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKSYmZTAodCxuLGUpfTtPYmplY3QuZGVmaW5lUHJvcGVydHkoTW4sIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO1ZoKHpoKCksTW4pO1ZoKGtoKCksTW4pfSk7dmFyIGdzPXN0KG1pPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShtaSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7bWkuaGllcmFyY2h5SXRlbUxlbmd0aD1taS5pbmZvTGVuZ3RoPXZvaWQgMDttaS5pbmZvTGVuZ3RoPTE2MDttaS5oaWVyYXJjaHlJdGVtTGVuZ3RoPTMyfSk7dmFyIF9zPXN0KFNuPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShTbiwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7U24uZXZsckhlYWRlckxlbmd0aD1Tbi52bHJIZWFkZXJMZW5ndGg9U24ubWluSGVhZGVyTGVuZ3RoPXZvaWQgMDtTbi5taW5IZWFkZXJMZW5ndGg9Mzc1O1NuLnZsckhlYWRlckxlbmd0aD01NDtTbi5ldmxySGVhZGVyTGVuZ3RoPTYwfSk7dmFyIFdoPXN0KGdpPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShnaSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7Z2kuZ2V0QmlnVWludDY0PWdpLnBhcnNlQmlnSW50PXZvaWQgMDtmdW5jdGlvbiBuMChuKXtpZihuPkJpZ0ludChOdW1iZXIuTUFYX1NBRkVfSU5URUdFUil8fG48QmlnSW50KC1OdW1iZXIuTUFYX1NBRkVfSU5URUdFUikpdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCBiaWdpbnQgdG8gbnVtYmVyOiAke259YCk7cmV0dXJuIE51bWJlcihuKX1naS5wYXJzZUJpZ0ludD1uMDtmdW5jdGlvbiBpMChuLHQsZSl7aWYobi5nZXRCaWdVaW50NjQpcmV0dXJuIG4uZ2V0QmlnVWludDY0KHQsZSk7bGV0W2kscl09ZT9bNCwwXTpbMCw0XSxzPUJpZ0ludChuLmdldFVpbnQzMih0K2ksZSkpLGE9QmlnSW50KG4uZ2V0VWludDMyKHQrcixlKSk7cmV0dXJuKHM8PEJpZ0ludCgzMikpK2F9Z2kuZ2V0QmlnVWludDY0PWkwfSk7dmFyIHFoPXN0KGJuPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShibiwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7Ym4udG9DU3RyaW5nPWJuLnRvRGF0YVZpZXc9Ym4uQmluYXJ5PXZvaWQgMDtibi5CaW5hcnk9e3RvRGF0YVZpZXc6Q28sdG9DU3RyaW5nOlhofTtmdW5jdGlvbiBDbyhuKXtyZXR1cm4gbmV3IERhdGFWaWV3KG4uYnVmZmVyLG4uYnl0ZU9mZnNldCxuLmxlbmd0aCl9Ym4udG9EYXRhVmlldz1DbztmdW5jdGlvbiBYaChuKXtsZXQgdD1DbyhuKSxlPSIiO2ZvcihsZXQgaT0wO2k8dC5ieXRlTGVuZ3RoOysraSl7bGV0IHI9dC5nZXRJbnQ4KGkpO2lmKHI9PT0wKXJldHVybiBlO2UrPVN0cmluZy5mcm9tQ2hhckNvZGUocil9cmV0dXJuIGV9Ym4udG9DU3RyaW5nPVhofSk7dmFyIEpoPXN0KHlzPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh5cywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7eXMuQm91bmRzPXZvaWQgMDt5cy5Cb3VuZHM9e21pbjpyMCxtYXg6czAsbWlkOlBvLHdpZHRoOlloLGRlcHRoOmpoLGhlaWdodDpaaCxjdWJlOmEwLHN0ZXA6JGgsc3RlcFRvOm8wLGludGVyc2VjdGlvbjpsMH07ZnVuY3Rpb24gcjAobil7cmV0dXJuW25bMF0sblsxXSxuWzJdXX1mdW5jdGlvbiBzMChuKXtyZXR1cm5bblszXSxuWzRdLG5bNV1dfWZ1bmN0aW9uIFBvKFtuLHQsZSxpLHIsc10pe3JldHVybltuKyhpLW4pLzIsdCsoci10KS8yLGUrKHMtZSkvMl19ZnVuY3Rpb24gWWgobil7cmV0dXJuIG5bM10tblswXX1mdW5jdGlvbiBqaChuKXtyZXR1cm4gbls0XS1uWzFdfWZ1bmN0aW9uIFpoKG4pe3JldHVybiBuWzVdLW5bMl19ZnVuY3Rpb24gYTAobil7bGV0IHQ9UG8obiksZT1NYXRoLm1heChZaChuKSxqaChuKSxaaChuKSkvMjtyZXR1cm5bdFswXS1lLHRbMV0tZSx0WzJdLWUsdFswXStlLHRbMV0rZSx0WzJdK2VdfWZ1bmN0aW9uICRoKG4sW3QsZSxpXSl7bGV0W3IscyxhLG8sbCxjXT1uLFtoLHUsbV09UG8obik7cmV0dXJuW3Q/aDpyLGU/dTpzLGk/bTphLHQ/bzpoLGU/bDp1LGk/YzptXX1mdW5jdGlvbiBvMChuLFt0LGUsaSxyXSl7Zm9yKGxldCBzPXQtMTtzPj0wOy0tcyluPSRoKG4sW2U+PnMmMSxpPj5zJjEscj4+cyYxXSk7cmV0dXJuIG59ZnVuY3Rpb24gbDAobix0KXtyZXR1cm5bTWF0aC5tYXgoblswXSx0WzBdKSxNYXRoLm1heChuWzFdLHRbMV0pLE1hdGgubWF4KG5bMl0sdFsyXSksTWF0aC5taW4oblszXSx0WzNdKSxNYXRoLm1pbihuWzRdLHRbNF0pLE1hdGgubWluKG5bNV0sdFs1XSldfX0pO3ZhciBLaD1zdCh2cz0+eyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkodnMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO3ZzLkRpbWVuc2lvbj12b2lkIDA7dmFyIGMwPXtpbnQ4Ont0eXBlOiJzaWduZWQiLHNpemU6MX0saW50MTY6e3R5cGU6InNpZ25lZCIsc2l6ZToyfSxpbnQzMjp7dHlwZToic2lnbmVkIixzaXplOjR9LGludDY0Ont0eXBlOiJzaWduZWQiLHNpemU6OH0sdWludDg6e3R5cGU6InVuc2lnbmVkIixzaXplOjF9LHVpbnQxNjp7dHlwZToidW5zaWduZWQiLHNpemU6Mn0sdWludDMyOnt0eXBlOiJ1bnNpZ25lZCIsc2l6ZTo0fSx1aW50NjQ6e3R5cGU6InVuc2lnbmVkIixzaXplOjh9LGZsb2F0MzI6e3R5cGU6ImZsb2F0IixzaXplOjR9LGZsb2F0NjQ6e3R5cGU6ImZsb2F0IixzaXplOjh9LGZsb2F0Ont0eXBlOiJmbG9hdCIsc2l6ZTo0fSxkb3VibGU6e3R5cGU6ImZsb2F0IixzaXplOjh9LGJvb2w6e3R5cGU6InVuc2lnbmVkIixzaXplOjF9LGJvb2xlYW46e3R5cGU6InVuc2lnbmVkIixzaXplOjF9fTt2cy5EaW1lbnNpb249e1R5cGU6YzAsY3R5cGU6aDB9O2Z1bmN0aW9uIGgwKHt0eXBlOm4sc2l6ZTp0fSl7c3dpdGNoKG4pe2Nhc2Uic2lnbmVkIjpzd2l0Y2godCl7Y2FzZSAxOnJldHVybiJpbnQ4IjtjYXNlIDI6cmV0dXJuImludDE2IjtjYXNlIDQ6cmV0dXJuImludDMyIjtjYXNlIDg6cmV0dXJuImludDY0In1jYXNlInVuc2lnbmVkIjpzd2l0Y2godCl7Y2FzZSAxOnJldHVybiJ1aW50OCI7Y2FzZSAyOnJldHVybiJ1aW50MTYiO2Nhc2UgNDpyZXR1cm4idWludDMyIjtjYXNlIDg6cmV0dXJuInVpbnQ2NCJ9Y2FzZSJmbG9hdCI6c3dpdGNoKHQpe2Nhc2UgNDpyZXR1cm4iZmxvYXQiO2Nhc2UgODpyZXR1cm4iZG91YmxlIn19dGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRpbWVuc2lvbiB0eXBlL3NpemU6ICR7bn0vJHt0fWApfX0pO3ZhciB0dT1zdCgod24sUWgpPT57dmFyIHhzPXR5cGVvZiBnbG9iYWxUaGlzPCJ1IiYmZ2xvYmFsVGhpc3x8dHlwZW9mIHNlbGY8InUiJiZzZWxmfHx0eXBlb2YgZ2xvYmFsPCJ1IiYmZ2xvYmFsLE1zPShmdW5jdGlvbigpe2Z1bmN0aW9uIG4oKXt0aGlzLmZldGNoPSExLHRoaXMuRE9NRXhjZXB0aW9uPXhzLkRPTUV4Y2VwdGlvbn1yZXR1cm4gbi5wcm90b3R5cGU9eHMsbmV3IG59KSgpOyhmdW5jdGlvbihuKXt2YXIgdD0oZnVuY3Rpb24oZSl7dmFyIGk9dHlwZW9mIG48InUiJiZufHx0eXBlb2Ygc2VsZjwidSImJnNlbGZ8fHR5cGVvZiBnbG9iYWw8InUiJiZnbG9iYWx8fHt9LHI9e3NlYXJjaFBhcmFtczoiVVJMU2VhcmNoUGFyYW1zImluIGksaXRlcmFibGU6IlN5bWJvbCJpbiBpJiYiaXRlcmF0b3IiaW4gU3ltYm9sLGJsb2I6IkZpbGVSZWFkZXIiaW4gaSYmIkJsb2IiaW4gaSYmKGZ1bmN0aW9uKCl7dHJ5e3JldHVybiBuZXcgQmxvYiwhMH1jYXRjaHtyZXR1cm4hMX19KSgpLGZvcm1EYXRhOiJGb3JtRGF0YSJpbiBpLGFycmF5QnVmZmVyOiJBcnJheUJ1ZmZlciJpbiBpfTtmdW5jdGlvbiBzKE0pe3JldHVybiBNJiZEYXRhVmlldy5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihNKX1pZihyLmFycmF5QnVmZmVyKXZhciBhPVsiW29iamVjdCBJbnQ4QXJyYXldIiwiW29iamVjdCBVaW50OEFycmF5XSIsIltvYmplY3QgVWludDhDbGFtcGVkQXJyYXldIiwiW29iamVjdCBJbnQxNkFycmF5XSIsIltvYmplY3QgVWludDE2QXJyYXldIiwiW29iamVjdCBJbnQzMkFycmF5XSIsIltvYmplY3QgVWludDMyQXJyYXldIiwiW29iamVjdCBGbG9hdDMyQXJyYXldIiwiW29iamVjdCBGbG9hdDY0QXJyYXldIl0sbz1BcnJheUJ1ZmZlci5pc1ZpZXd8fGZ1bmN0aW9uKE0pe3JldHVybiBNJiZhLmluZGV4T2YoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKE0pKT4tMX07ZnVuY3Rpb24gbChNKXtpZih0eXBlb2YgTSE9InN0cmluZyImJihNPVN0cmluZyhNKSksL1teYS16MC05XC0jJCUmJyorLl5fYHx+IV0vaS50ZXN0KE0pfHxNPT09IiIpdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBjaGFyYWN0ZXIgaW4gaGVhZGVyIGZpZWxkIG5hbWU6ICInK00rJyInKTtyZXR1cm4gTS50b0xvd2VyQ2FzZSgpfWZ1bmN0aW9uIGMoTSl7cmV0dXJuIHR5cGVvZiBNIT0ic3RyaW5nIiYmKE09U3RyaW5nKE0pKSxNfWZ1bmN0aW9uIGgoTSl7dmFyIFA9e25leHQ6ZnVuY3Rpb24oKXt2YXIgVz1NLnNoaWZ0KCk7cmV0dXJue2RvbmU6Vz09PXZvaWQgMCx2YWx1ZTpXfX19O3JldHVybiByLml0ZXJhYmxlJiYoUFtTeW1ib2wuaXRlcmF0b3JdPWZ1bmN0aW9uKCl7cmV0dXJuIFB9KSxQfWZ1bmN0aW9uIHUoTSl7dGhpcy5tYXA9e30sTSBpbnN0YW5jZW9mIHU/TS5mb3JFYWNoKGZ1bmN0aW9uKFAsVyl7dGhpcy5hcHBlbmQoVyxQKX0sdGhpcyk6QXJyYXkuaXNBcnJheShNKT9NLmZvckVhY2goZnVuY3Rpb24oUCl7aWYoUC5sZW5ndGghPTIpdGhyb3cgbmV3IFR5cGVFcnJvcigiSGVhZGVycyBjb25zdHJ1Y3RvcjogZXhwZWN0ZWQgbmFtZS92YWx1ZSBwYWlyIHRvIGJlIGxlbmd0aCAyLCBmb3VuZCIrUC5sZW5ndGgpO3RoaXMuYXBwZW5kKFBbMF0sUFsxXSl9LHRoaXMpOk0mJk9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE0pLmZvckVhY2goZnVuY3Rpb24oUCl7dGhpcy5hcHBlbmQoUCxNW1BdKX0sdGhpcyl9dS5wcm90b3R5cGUuYXBwZW5kPWZ1bmN0aW9uKE0sUCl7TT1sKE0pLFA9YyhQKTt2YXIgVz10aGlzLm1hcFtNXTt0aGlzLm1hcFtNXT1XP1crIiwgIitQOlB9LHUucHJvdG90eXBlLmRlbGV0ZT1mdW5jdGlvbihNKXtkZWxldGUgdGhpcy5tYXBbbChNKV19LHUucHJvdG90eXBlLmdldD1mdW5jdGlvbihNKXtyZXR1cm4gTT1sKE0pLHRoaXMuaGFzKE0pP3RoaXMubWFwW01dOm51bGx9LHUucHJvdG90eXBlLmhhcz1mdW5jdGlvbihNKXtyZXR1cm4gdGhpcy5tYXAuaGFzT3duUHJvcGVydHkobChNKSl9LHUucHJvdG90eXBlLnNldD1mdW5jdGlvbihNLFApe3RoaXMubWFwW2woTSldPWMoUCl9LHUucHJvdG90eXBlLmZvckVhY2g9ZnVuY3Rpb24oTSxQKXtmb3IodmFyIFcgaW4gdGhpcy5tYXApdGhpcy5tYXAuaGFzT3duUHJvcGVydHkoVykmJk0uY2FsbChQLHRoaXMubWFwW1ddLFcsdGhpcyl9LHUucHJvdG90eXBlLmtleXM9ZnVuY3Rpb24oKXt2YXIgTT1bXTtyZXR1cm4gdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKFAsVyl7TS5wdXNoKFcpfSksaChNKX0sdS5wcm90b3R5cGUudmFsdWVzPWZ1bmN0aW9uKCl7dmFyIE09W107cmV0dXJuIHRoaXMuZm9yRWFjaChmdW5jdGlvbihQKXtNLnB1c2goUCl9KSxoKE0pfSx1LnByb3RvdHlwZS5lbnRyaWVzPWZ1bmN0aW9uKCl7dmFyIE09W107cmV0dXJuIHRoaXMuZm9yRWFjaChmdW5jdGlvbihQLFcpe00ucHVzaChbVyxQXSl9KSxoKE0pfSxyLml0ZXJhYmxlJiYodS5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXT11LnByb3RvdHlwZS5lbnRyaWVzKTtmdW5jdGlvbiBtKE0pe2lmKCFNLl9ub0JvZHkpe2lmKE0uYm9keVVzZWQpcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBUeXBlRXJyb3IoIkFscmVhZHkgcmVhZCIpKTtNLmJvZHlVc2VkPSEwfX1mdW5jdGlvbiBkKE0pe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihQLFcpe00ub25sb2FkPWZ1bmN0aW9uKCl7UChNLnJlc3VsdCl9LE0ub25lcnJvcj1mdW5jdGlvbigpe1coTS5lcnJvcil9fSl9ZnVuY3Rpb24gZyhNKXt2YXIgUD1uZXcgRmlsZVJlYWRlcixXPWQoUCk7cmV0dXJuIFAucmVhZEFzQXJyYXlCdWZmZXIoTSksV31mdW5jdGlvbiB5KE0pe3ZhciBQPW5ldyBGaWxlUmVhZGVyLFc9ZChQKSxqPS9jaGFyc2V0PShbQS1aYS16MC05Xy1dKykvLmV4ZWMoTS50eXBlKSxydD1qP2pbMV06InV0Zi04IjtyZXR1cm4gUC5yZWFkQXNUZXh0KE0scnQpLFd9ZnVuY3Rpb24gdihNKXtmb3IodmFyIFA9bmV3IFVpbnQ4QXJyYXkoTSksVz1uZXcgQXJyYXkoUC5sZW5ndGgpLGo9MDtqPFAubGVuZ3RoO2orKylXW2pdPVN0cmluZy5mcm9tQ2hhckNvZGUoUFtqXSk7cmV0dXJuIFcuam9pbigiIil9ZnVuY3Rpb24gUyhNKXtpZihNLnNsaWNlKXJldHVybiBNLnNsaWNlKDApO3ZhciBQPW5ldyBVaW50OEFycmF5KE0uYnl0ZUxlbmd0aCk7cmV0dXJuIFAuc2V0KG5ldyBVaW50OEFycmF5KE0pKSxQLmJ1ZmZlcn1mdW5jdGlvbiBDKCl7cmV0dXJuIHRoaXMuYm9keVVzZWQ9ITEsdGhpcy5faW5pdEJvZHk9ZnVuY3Rpb24oTSl7dGhpcy5ib2R5VXNlZD10aGlzLmJvZHlVc2VkLHRoaXMuX2JvZHlJbml0PU0sTT90eXBlb2YgTT09InN0cmluZyI/dGhpcy5fYm9keVRleHQ9TTpyLmJsb2ImJkJsb2IucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoTSk/dGhpcy5fYm9keUJsb2I9TTpyLmZvcm1EYXRhJiZGb3JtRGF0YS5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihNKT90aGlzLl9ib2R5Rm9ybURhdGE9TTpyLnNlYXJjaFBhcmFtcyYmVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKE0pP3RoaXMuX2JvZHlUZXh0PU0udG9TdHJpbmcoKTpyLmFycmF5QnVmZmVyJiZyLmJsb2ImJnMoTSk/KHRoaXMuX2JvZHlBcnJheUJ1ZmZlcj1TKE0uYnVmZmVyKSx0aGlzLl9ib2R5SW5pdD1uZXcgQmxvYihbdGhpcy5fYm9keUFycmF5QnVmZmVyXSkpOnIuYXJyYXlCdWZmZXImJihBcnJheUJ1ZmZlci5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihNKXx8byhNKSk/dGhpcy5fYm9keUFycmF5QnVmZmVyPVMoTSk6dGhpcy5fYm9keVRleHQ9TT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoTSk6KHRoaXMuX25vQm9keT0hMCx0aGlzLl9ib2R5VGV4dD0iIiksdGhpcy5oZWFkZXJzLmdldCgiY29udGVudC10eXBlIil8fCh0eXBlb2YgTT09InN0cmluZyI/dGhpcy5oZWFkZXJzLnNldCgiY29udGVudC10eXBlIiwidGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Iik6dGhpcy5fYm9keUJsb2ImJnRoaXMuX2JvZHlCbG9iLnR5cGU/dGhpcy5oZWFkZXJzLnNldCgiY29udGVudC10eXBlIix0aGlzLl9ib2R5QmxvYi50eXBlKTpyLnNlYXJjaFBhcmFtcyYmVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mKE0pJiZ0aGlzLmhlYWRlcnMuc2V0KCJjb250ZW50LXR5cGUiLCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD1VVEYtOCIpKX0sci5ibG9iJiYodGhpcy5ibG9iPWZ1bmN0aW9uKCl7dmFyIE09bSh0aGlzKTtpZihNKXJldHVybiBNO2lmKHRoaXMuX2JvZHlCbG9iKXJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUJsb2IpO2lmKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcilyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBCbG9iKFt0aGlzLl9ib2R5QXJyYXlCdWZmZXJdKSk7aWYodGhpcy5fYm9keUZvcm1EYXRhKXRocm93IG5ldyBFcnJvcigiY291bGQgbm90IHJlYWQgRm9ybURhdGEgYm9keSBhcyBibG9iIik7cmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgQmxvYihbdGhpcy5fYm9keVRleHRdKSl9KSx0aGlzLmFycmF5QnVmZmVyPWZ1bmN0aW9uKCl7aWYodGhpcy5fYm9keUFycmF5QnVmZmVyKXt2YXIgTT1tKHRoaXMpO3JldHVybiBNfHwoQXJyYXlCdWZmZXIuaXNWaWV3KHRoaXMuX2JvZHlBcnJheUJ1ZmZlcik/UHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JvZHlBcnJheUJ1ZmZlci5idWZmZXIuc2xpY2UodGhpcy5fYm9keUFycmF5QnVmZmVyLmJ5dGVPZmZzZXQsdGhpcy5fYm9keUFycmF5QnVmZmVyLmJ5dGVPZmZzZXQrdGhpcy5fYm9keUFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpKTpQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keUFycmF5QnVmZmVyKSl9ZWxzZXtpZihyLmJsb2IpcmV0dXJuIHRoaXMuYmxvYigpLnRoZW4oZyk7dGhyb3cgbmV3IEVycm9yKCJjb3VsZCBub3QgcmVhZCBhcyBBcnJheUJ1ZmZlciIpfX0sdGhpcy50ZXh0PWZ1bmN0aW9uKCl7dmFyIE09bSh0aGlzKTtpZihNKXJldHVybiBNO2lmKHRoaXMuX2JvZHlCbG9iKXJldHVybiB5KHRoaXMuX2JvZHlCbG9iKTtpZih0aGlzLl9ib2R5QXJyYXlCdWZmZXIpcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikpO2lmKHRoaXMuX2JvZHlGb3JtRGF0YSl0aHJvdyBuZXcgRXJyb3IoImNvdWxkIG5vdCByZWFkIEZvcm1EYXRhIGJvZHkgYXMgdGV4dCIpO3JldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fYm9keVRleHQpfSxyLmZvcm1EYXRhJiYodGhpcy5mb3JtRGF0YT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRleHQoKS50aGVuKFYpfSksdGhpcy5qc29uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGV4dCgpLnRoZW4oSlNPTi5wYXJzZSl9LHRoaXN9dmFyIE49WyJDT05ORUNUIiwiREVMRVRFIiwiR0VUIiwiSEVBRCIsIk9QVElPTlMiLCJQQVRDSCIsIlBPU1QiLCJQVVQiLCJUUkFDRSJdO2Z1bmN0aW9uIEYoTSl7dmFyIFA9TS50b1VwcGVyQ2FzZSgpO3JldHVybiBOLmluZGV4T2YoUCk+LTE/UDpNfWZ1bmN0aW9uIFIoTSxQKXtpZighKHRoaXMgaW5zdGFuY2VvZiBSKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdQbGVhc2UgdXNlIHRoZSAibmV3IiBvcGVyYXRvciwgdGhpcyBET00gb2JqZWN0IGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvbi4nKTtQPVB8fHt9O3ZhciBXPVAuYm9keTtpZihNIGluc3RhbmNlb2YgUil7aWYoTS5ib2R5VXNlZCl0aHJvdyBuZXcgVHlwZUVycm9yKCJBbHJlYWR5IHJlYWQiKTt0aGlzLnVybD1NLnVybCx0aGlzLmNyZWRlbnRpYWxzPU0uY3JlZGVudGlhbHMsUC5oZWFkZXJzfHwodGhpcy5oZWFkZXJzPW5ldyB1KE0uaGVhZGVycykpLHRoaXMubWV0aG9kPU0ubWV0aG9kLHRoaXMubW9kZT1NLm1vZGUsdGhpcy5zaWduYWw9TS5zaWduYWwsIVcmJk0uX2JvZHlJbml0IT1udWxsJiYoVz1NLl9ib2R5SW5pdCxNLmJvZHlVc2VkPSEwKX1lbHNlIHRoaXMudXJsPVN0cmluZyhNKTtpZih0aGlzLmNyZWRlbnRpYWxzPVAuY3JlZGVudGlhbHN8fHRoaXMuY3JlZGVudGlhbHN8fCJzYW1lLW9yaWdpbiIsKFAuaGVhZGVyc3x8IXRoaXMuaGVhZGVycykmJih0aGlzLmhlYWRlcnM9bmV3IHUoUC5oZWFkZXJzKSksdGhpcy5tZXRob2Q9RihQLm1ldGhvZHx8dGhpcy5tZXRob2R8fCJHRVQiKSx0aGlzLm1vZGU9UC5tb2RlfHx0aGlzLm1vZGV8fG51bGwsdGhpcy5zaWduYWw9UC5zaWduYWx8fHRoaXMuc2lnbmFsfHwoZnVuY3Rpb24oKXtpZigiQWJvcnRDb250cm9sbGVyImluIGkpe3ZhciBKPW5ldyBBYm9ydENvbnRyb2xsZXI7cmV0dXJuIEouc2lnbmFsfX0pKCksdGhpcy5yZWZlcnJlcj1udWxsLCh0aGlzLm1ldGhvZD09PSJHRVQifHx0aGlzLm1ldGhvZD09PSJIRUFEIikmJlcpdGhyb3cgbmV3IFR5cGVFcnJvcigiQm9keSBub3QgYWxsb3dlZCBmb3IgR0VUIG9yIEhFQUQgcmVxdWVzdHMiKTtpZih0aGlzLl9pbml0Qm9keShXKSwodGhpcy5tZXRob2Q9PT0iR0VUInx8dGhpcy5tZXRob2Q9PT0iSEVBRCIpJiYoUC5jYWNoZT09PSJuby1zdG9yZSJ8fFAuY2FjaGU9PT0ibm8tY2FjaGUiKSl7dmFyIGo9LyhbPyZdKV89W14mXSovO2lmKGoudGVzdCh0aGlzLnVybCkpdGhpcy51cmw9dGhpcy51cmwucmVwbGFjZShqLCIkMV89IituZXcgRGF0ZSgpLmdldFRpbWUoKSk7ZWxzZXt2YXIgcnQ9L1w/Lzt0aGlzLnVybCs9KHJ0LnRlc3QodGhpcy51cmwpPyImIjoiPyIpKyJfPSIrbmV3IERhdGUoKS5nZXRUaW1lKCl9fX1SLnByb3RvdHlwZS5jbG9uZT1mdW5jdGlvbigpe3JldHVybiBuZXcgUih0aGlzLHtib2R5OnRoaXMuX2JvZHlJbml0fSl9O2Z1bmN0aW9uIFYoTSl7dmFyIFA9bmV3IEZvcm1EYXRhO3JldHVybiBNLnRyaW0oKS5zcGxpdCgiJiIpLmZvckVhY2goZnVuY3Rpb24oVyl7aWYoVyl7dmFyIGo9Vy5zcGxpdCgiPSIpLHJ0PWouc2hpZnQoKS5yZXBsYWNlKC9cKy9nLCIgIiksSj1qLmpvaW4oIj0iKS5yZXBsYWNlKC9cKy9nLCIgIik7UC5hcHBlbmQoZGVjb2RlVVJJQ29tcG9uZW50KHJ0KSxkZWNvZGVVUklDb21wb25lbnQoSikpfX0pLFB9ZnVuY3Rpb24gQihNKXt2YXIgUD1uZXcgdSxXPU0ucmVwbGFjZSgvXHI/XG5bXHQgXSsvZywiICIpO3JldHVybiBXLnNwbGl0KCJcciIpLm1hcChmdW5jdGlvbihqKXtyZXR1cm4gai5pbmRleE9mKGAKYCk9PT0wP2ouc3Vic3RyKDEsai5sZW5ndGgpOmp9KS5mb3JFYWNoKGZ1bmN0aW9uKGope3ZhciBydD1qLnNwbGl0KCI6IiksSj1ydC5zaGlmdCgpLnRyaW0oKTtpZihKKXt2YXIgaz1ydC5qb2luKCI6IikudHJpbSgpO3RyeXtQLmFwcGVuZChKLGspfWNhdGNoKHhlKXtjb25zb2xlLndhcm4oIlJlc3BvbnNlICIreGUubWVzc2FnZSl9fX0pLFB9Qy5jYWxsKFIucHJvdG90eXBlKTtmdW5jdGlvbiBIKE0sUCl7aWYoISh0aGlzIGluc3RhbmNlb2YgSCkpdGhyb3cgbmV3IFR5cGVFcnJvcignUGxlYXNlIHVzZSB0aGUgIm5ldyIgb3BlcmF0b3IsIHRoaXMgRE9NIG9iamVjdCBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIGFzIGEgZnVuY3Rpb24uJyk7aWYoUHx8KFA9e30pLHRoaXMudHlwZT0iZGVmYXVsdCIsdGhpcy5zdGF0dXM9UC5zdGF0dXM9PT12b2lkIDA/MjAwOlAuc3RhdHVzLHRoaXMuc3RhdHVzPDIwMHx8dGhpcy5zdGF0dXM+NTk5KXRocm93IG5ldyBSYW5nZUVycm9yKCJGYWlsZWQgdG8gY29uc3RydWN0ICdSZXNwb25zZSc6IFRoZSBzdGF0dXMgcHJvdmlkZWQgKDApIGlzIG91dHNpZGUgdGhlIHJhbmdlIFsyMDAsIDU5OV0uIik7dGhpcy5vaz10aGlzLnN0YXR1cz49MjAwJiZ0aGlzLnN0YXR1czwzMDAsdGhpcy5zdGF0dXNUZXh0PVAuc3RhdHVzVGV4dD09PXZvaWQgMD8iIjoiIitQLnN0YXR1c1RleHQsdGhpcy5oZWFkZXJzPW5ldyB1KFAuaGVhZGVycyksdGhpcy51cmw9UC51cmx8fCIiLHRoaXMuX2luaXRCb2R5KE0pfUMuY2FsbChILnByb3RvdHlwZSksSC5wcm90b3R5cGUuY2xvbmU9ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEgodGhpcy5fYm9keUluaXQse3N0YXR1czp0aGlzLnN0YXR1cyxzdGF0dXNUZXh0OnRoaXMuc3RhdHVzVGV4dCxoZWFkZXJzOm5ldyB1KHRoaXMuaGVhZGVycyksdXJsOnRoaXMudXJsfSl9LEguZXJyb3I9ZnVuY3Rpb24oKXt2YXIgTT1uZXcgSChudWxsLHtzdGF0dXM6MjAwLHN0YXR1c1RleHQ6IiJ9KTtyZXR1cm4gTS5vaz0hMSxNLnN0YXR1cz0wLE0udHlwZT0iZXJyb3IiLE19O3ZhciAkPVszMDEsMzAyLDMwMywzMDcsMzA4XTtILnJlZGlyZWN0PWZ1bmN0aW9uKE0sUCl7aWYoJC5pbmRleE9mKFApPT09LTEpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIkludmFsaWQgc3RhdHVzIGNvZGUiKTtyZXR1cm4gbmV3IEgobnVsbCx7c3RhdHVzOlAsaGVhZGVyczp7bG9jYXRpb246TX19KX0sZS5ET01FeGNlcHRpb249aS5ET01FeGNlcHRpb247dHJ5e25ldyBlLkRPTUV4Y2VwdGlvbn1jYXRjaHtlLkRPTUV4Y2VwdGlvbj1mdW5jdGlvbihQLFcpe3RoaXMubWVzc2FnZT1QLHRoaXMubmFtZT1XO3ZhciBqPUVycm9yKFApO3RoaXMuc3RhY2s9ai5zdGFja30sZS5ET01FeGNlcHRpb24ucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKSxlLkRPTUV4Y2VwdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3I9ZS5ET01FeGNlcHRpb259ZnVuY3Rpb24gYXQoTSxQKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oVyxqKXt2YXIgcnQ9bmV3IFIoTSxQKTtpZihydC5zaWduYWwmJnJ0LnNpZ25hbC5hYm9ydGVkKXJldHVybiBqKG5ldyBlLkRPTUV4Y2VwdGlvbigiQWJvcnRlZCIsIkFib3J0RXJyb3IiKSk7dmFyIEo9bmV3IFhNTEh0dHBSZXF1ZXN0O2Z1bmN0aW9uIGsoKXtKLmFib3J0KCl9Si5vbmxvYWQ9ZnVuY3Rpb24oKXt2YXIgaHQ9e3N0YXR1c1RleHQ6Si5zdGF0dXNUZXh0LGhlYWRlcnM6QihKLmdldEFsbFJlc3BvbnNlSGVhZGVycygpfHwiIil9O3J0LnVybC5pbmRleE9mKCJmaWxlOi8vIik9PT0wJiYoSi5zdGF0dXM8MjAwfHxKLnN0YXR1cz41OTkpP2h0LnN0YXR1cz0yMDA6aHQuc3RhdHVzPUouc3RhdHVzLGh0LnVybD0icmVzcG9uc2VVUkwiaW4gSj9KLnJlc3BvbnNlVVJMOmh0LmhlYWRlcnMuZ2V0KCJYLVJlcXVlc3QtVVJMIik7dmFyIGt0PSJyZXNwb25zZSJpbiBKP0oucmVzcG9uc2U6Si5yZXNwb25zZVRleHQ7c2V0VGltZW91dChmdW5jdGlvbigpe1cobmV3IEgoa3QsaHQpKX0sMCl9LEoub25lcnJvcj1mdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXtqKG5ldyBUeXBlRXJyb3IoIk5ldHdvcmsgcmVxdWVzdCBmYWlsZWQiKSl9LDApfSxKLm9udGltZW91dD1mdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXtqKG5ldyBUeXBlRXJyb3IoIk5ldHdvcmsgcmVxdWVzdCB0aW1lZCBvdXQiKSl9LDApfSxKLm9uYWJvcnQ9ZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aihuZXcgZS5ET01FeGNlcHRpb24oIkFib3J0ZWQiLCJBYm9ydEVycm9yIikpfSwwKX07ZnVuY3Rpb24geGUoaHQpe3RyeXtyZXR1cm4gaHQ9PT0iIiYmaS5sb2NhdGlvbi5ocmVmP2kubG9jYXRpb24uaHJlZjpodH1jYXRjaHtyZXR1cm4gaHR9fWlmKEoub3BlbihydC5tZXRob2QseGUocnQudXJsKSwhMCkscnQuY3JlZGVudGlhbHM9PT0iaW5jbHVkZSI/Si53aXRoQ3JlZGVudGlhbHM9ITA6cnQuY3JlZGVudGlhbHM9PT0ib21pdCImJihKLndpdGhDcmVkZW50aWFscz0hMSksInJlc3BvbnNlVHlwZSJpbiBKJiYoci5ibG9iP0oucmVzcG9uc2VUeXBlPSJibG9iIjpyLmFycmF5QnVmZmVyJiYoSi5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIikpLFAmJnR5cGVvZiBQLmhlYWRlcnM9PSJvYmplY3QiJiYhKFAuaGVhZGVycyBpbnN0YW5jZW9mIHV8fGkuSGVhZGVycyYmUC5oZWFkZXJzIGluc3RhbmNlb2YgaS5IZWFkZXJzKSl7dmFyIFJlPVtdO09iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFAuaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbihodCl7UmUucHVzaChsKGh0KSksSi5zZXRSZXF1ZXN0SGVhZGVyKGh0LGMoUC5oZWFkZXJzW2h0XSkpfSkscnQuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKGh0LGt0KXtSZS5pbmRleE9mKGt0KT09PS0xJiZKLnNldFJlcXVlc3RIZWFkZXIoa3QsaHQpfSl9ZWxzZSBydC5oZWFkZXJzLmZvckVhY2goZnVuY3Rpb24oaHQsa3Qpe0ouc2V0UmVxdWVzdEhlYWRlcihrdCxodCl9KTtydC5zaWduYWwmJihydC5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcigiYWJvcnQiLGspLEoub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCl7Si5yZWFkeVN0YXRlPT09NCYmcnQuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoImFib3J0IixrKX0pLEouc2VuZCh0eXBlb2YgcnQuX2JvZHlJbml0PiJ1Ij9udWxsOnJ0Ll9ib2R5SW5pdCl9KX1yZXR1cm4gYXQucG9seWZpbGw9ITAsaS5mZXRjaHx8KGkuZmV0Y2g9YXQsaS5IZWFkZXJzPXUsaS5SZXF1ZXN0PVIsaS5SZXNwb25zZT1IKSxlLkhlYWRlcnM9dSxlLlJlcXVlc3Q9UixlLlJlc3BvbnNlPUgsZS5mZXRjaD1hdCxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSksZX0pKHt9KX0pKE1zKTtNcy5mZXRjaC5wb255ZmlsbD0hMDtkZWxldGUgTXMuZmV0Y2gucG9seWZpbGw7dmFyIF9pPXhzLmZldGNoP3hzOk1zO3duPV9pLmZldGNoO3duLmRlZmF1bHQ9X2kuZmV0Y2g7d24uZmV0Y2g9X2kuZmV0Y2g7d24uSGVhZGVycz1faS5IZWFkZXJzO3duLlJlcXVlc3Q9X2kuUmVxdWVzdDt3bi5SZXNwb25zZT1faS5SZXNwb25zZTtRaC5leHBvcnRzPXdufSk7dmFyIGV1PXN0KCgpPT57fSk7dmFyIHJ1PXN0KHVlPT57InVzZSBzdHJpY3QiO3ZhciB1MD11ZSYmdWUuX19jcmVhdGVCaW5kaW5nfHwoT2JqZWN0LmNyZWF0ZT8oZnVuY3Rpb24obix0LGUsaSl7aT09PXZvaWQgMCYmKGk9ZSk7dmFyIHI9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0LGUpOyghcnx8KCJnZXQiaW4gcj8hdC5fX2VzTW9kdWxlOnIud3JpdGFibGV8fHIuY29uZmlndXJhYmxlKSkmJihyPXtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0W2VdfX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuLGkscil9KTooZnVuY3Rpb24obix0LGUsaSl7aT09PXZvaWQgMCYmKGk9ZSksbltpXT10W2VdfSkpLGYwPXVlJiZ1ZS5fX3NldE1vZHVsZURlZmF1bHR8fChPYmplY3QuY3JlYXRlPyhmdW5jdGlvbihuLHQpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShuLCJkZWZhdWx0Iix7ZW51bWVyYWJsZTohMCx2YWx1ZTp0fSl9KTpmdW5jdGlvbihuLHQpe24uZGVmYXVsdD10fSksZDA9dWUmJnVlLl9faW1wb3J0U3Rhcnx8ZnVuY3Rpb24obil7aWYobiYmbi5fX2VzTW9kdWxlKXJldHVybiBuO3ZhciB0PXt9O2lmKG4hPW51bGwpZm9yKHZhciBlIGluIG4pZSE9PSJkZWZhdWx0IiYmT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sZSkmJnUwKHQsbixlKTtyZXR1cm4gZjAodCxuKSx0fSxwMD11ZSYmdWUuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihuKXtyZXR1cm4gbiYmbi5fX2VzTW9kdWxlP246e2RlZmF1bHQ6bn19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh1ZSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7dWUuR2V0dGVyPXZvaWQgMDt2YXIgbTA9cDAodHUoKSk7dWUuR2V0dGVyPXtjcmVhdGU6ZzAsaHR0cDpudSxmaWxlOml1fTtmdW5jdGlvbiBnMChuKXtyZXR1cm4gdHlwZW9mIG49PSJmdW5jdGlvbiI/bjpuLnN0YXJ0c1dpdGgoImh0dHA6Ly8iKXx8bi5zdGFydHNXaXRoKCJodHRwczovLyIpP251KG4pOml1KG4pfWZ1bmN0aW9uIG51KG4pe3JldHVybiBhc3luYyBmdW5jdGlvbihlLGkpe2lmKGU8MHx8aTwwfHxlPmkpdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIHJhbmdlIik7bGV0IHM9YXdhaXQoYXdhaXQoMCxtMC5kZWZhdWx0KShuLHtoZWFkZXJzOntSYW5nZTpgYnl0ZXM9JHtlfS0ke2ktMX1gfX0pKS5hcnJheUJ1ZmZlcigpO3JldHVybiBuZXcgVWludDhBcnJheShzKX19ZnVuY3Rpb24gaXUobil7cmV0dXJuIGFzeW5jIGZ1bmN0aW9uKGUsaSl7bGV0IHI9YXdhaXQgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKT0+ZDAoZXUoKSkpO2FzeW5jIGZ1bmN0aW9uIHMoYT0wLG89MS8wKXtpZihhPDB8fG88MHx8YT5vKXRocm93IG5ldyBFcnJvcigiSW52YWxpZCByYW5nZSIpO2F3YWl0IHIucHJvbWlzZXMuYWNjZXNzKG4pO2xldCBsPXIuY3JlYXRlUmVhZFN0cmVhbShuLHtzdGFydDphLGVuZDpvLTEsYXV0b0Nsb3NlOiEwfSk7cmV0dXJuIF8wKGwpfXJldHVybiBzKGUsaSl9fWFzeW5jIGZ1bmN0aW9uIF8wKG4pe3JldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgodCxlKT0+e2xldCBpPVtdO24ub24oImRhdGEiLHI9PmkucHVzaChyKSksbi5vbigiZXJyb3IiLGUpLG4ub24oImVuZCIsKCk9PnQoQnVmZmVyLmNvbmNhdChpKSkpfSl9fSk7dmFyIGF1PXN0KHlpPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh5aSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7eWkuS2V5PXZvaWQgMDt5aS5LZXk9e2NyZWF0ZTp5MCxwYXJzZTpzdSx0b1N0cmluZzp2MCxzdGVwOngwLHVwOk0wLGNvbXBhcmU6UzAsZGVwdGg6YjB9O2Z1bmN0aW9uIHkwKG4sdD0wLGU9MCxpPTApe3JldHVybiB0eXBlb2YgbiE9Im51bWJlciI/c3Uobik6W24sdCxlLGldfWZ1bmN0aW9uIHN1KG4pe2lmKHR5cGVvZiBuIT0ic3RyaW5nIilyZXR1cm4gbjtsZXRbdCxlLGksciwuLi5zXT1uLnNwbGl0KCItIikubWFwKG89PnBhcnNlSW50KG8sMTApKSxhPVt0LGUsaSxyXTtpZihzLmxlbmd0aCE9PTB8fGEuc29tZShvPT50eXBlb2YgbyE9Im51bWJlciJ8fE51bWJlci5pc05hTihvKSkpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGtleTogJHtufWApO3JldHVybiBhfWZ1bmN0aW9uIHYwKG4pe3JldHVybiB0eXBlb2Ygbj09InN0cmluZyI/bjpuLmpvaW4oIi0iKX1mdW5jdGlvbiB4MChuLFt0LGUsaV0pe2xldFtyLHMsYSxvXT15aS5LZXkuY3JlYXRlKG4pO3JldHVybltyKzEscyoyK3QsYSoyK2UsbyoyK2ldfWZ1bmN0aW9uIE0wKG4sdD0xKXtsZXRbZSxpLHIsc109eWkuS2V5LmNyZWF0ZShuKTtyZXR1cm5bZS10LGk+PnQscj4+dCxzPj50XX1mdW5jdGlvbiBTMChuLHQpe2ZvcihsZXQgZT0wO2U8bi5sZW5ndGg7KytlKXtpZihuW2VdPHRbZV0pcmV0dXJuLTE7aWYobltlXT50W2VdKXJldHVybiAxfXJldHVybiAwfWZ1bmN0aW9uIGIwKG4pe3JldHVybiBuWzBdfX0pO3ZhciBvdT1zdChTcz0+eyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3MsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO1NzLlNjYWxlPXZvaWQgMDtTcy5TY2FsZT17YXBwbHk6KG4sdD0xLGU9MCk9PihuLWUpL3QsdW5hcHBseToobix0PTEsZT0wKT0+bip0K2V9fSk7dmFyIGx1PXN0KGJzPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShicywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7YnMuU3RlcD12b2lkIDA7YnMuU3RlcD17ZnJvbUluZGV4OncwLGxpc3Q6RTB9O2Z1bmN0aW9uIHcwKG4pe2lmKG48MHx8bj49OCl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgc3RlcCBpbmRleDogJHtufWApO2xldCB0PW4+PjAmMT8xOjAsZT1uPj4xJjE/MTowLGk9bj4+MiYxPzE6MDtyZXR1cm5bdCxlLGldfWZ1bmN0aW9uIEUwKCl7cmV0dXJuW1swLDAsMF0sWzAsMCwxXSxbMCwxLDBdLFswLDEsMV0sWzEsMCwwXSxbMSwwLDFdLFsxLDEsMF0sWzEsMSwxXV19fSk7dmFyIGZlPXN0KFN0PT57InVzZSBzdHJpY3QiO3ZhciBUMD1TdCYmU3QuX19jcmVhdGVCaW5kaW5nfHwoT2JqZWN0LmNyZWF0ZT8oZnVuY3Rpb24obix0LGUsaSl7aT09PXZvaWQgMCYmKGk9ZSk7dmFyIHI9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0LGUpOyghcnx8KCJnZXQiaW4gcj8hdC5fX2VzTW9kdWxlOnIud3JpdGFibGV8fHIuY29uZmlndXJhYmxlKSkmJihyPXtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0W2VdfX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuLGkscil9KTooZnVuY3Rpb24obix0LGUsaSl7aT09PXZvaWQgMCYmKGk9ZSksbltpXT10W2VdfSkpLEEwPVN0JiZTdC5fX2V4cG9ydFN0YXJ8fGZ1bmN0aW9uKG4sdCl7Zm9yKHZhciBlIGluIG4pZSE9PSJkZWZhdWx0IiYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LGUpJiZUMCh0LG4sZSl9O09iamVjdC5kZWZpbmVQcm9wZXJ0eShTdCwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7U3QuU3RlcD1TdC5TY2FsZT1TdC5LZXk9U3QuR2V0dGVyPVN0LkRpbWVuc2lvbj1TdC5Cb3VuZHM9U3QuQmluYXJ5PXZvaWQgMDtBMChXaCgpLFN0KTt2YXIgQzA9cWgoKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIkJpbmFyeSIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIEMwLkJpbmFyeX19KTt2YXIgUDA9SmgoKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIkJvdW5kcyIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIFAwLkJvdW5kc319KTt2YXIgUjA9S2goKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIkRpbWVuc2lvbiIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIFIwLkRpbWVuc2lvbn19KTt2YXIgSTA9cnUoKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIkdldHRlciIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIEkwLkdldHRlcn19KTt2YXIgTDA9YXUoKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIktleSIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIEwwLktleX19KTt2YXIgRDA9b3UoKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoU3QsIlNjYWxlIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gRDAuU2NhbGV9fSk7dmFyIE4wPWx1KCk7T2JqZWN0LmRlZmluZVByb3BlcnR5KFN0LCJTdGVwIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gTjAuU3RlcH19KX0pO3ZhciBSbz1zdChFcz0+eyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkoRXMsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO0VzLkV4dHJhQnl0ZXM9dm9pZCAwO3ZhciBMdD1mZSgpO0VzLkV4dHJhQnl0ZXM9e2dldERpbWVuc2lvbjpVMCxwYXJzZTpGMCxwYXJzZU9uZTpjdX07dmFyIHdzPTE5MjtmdW5jdGlvbiBVMCh7dHlwZTpuLGxlbmd0aDp0fSl7c3dpdGNoKG4pe2Nhc2Uic2lnbmVkIjpjYXNlInVuc2lnbmVkIjpzd2l0Y2godCl7Y2FzZSAxOmNhc2UgMjpjYXNlIDQ6Y2FzZSA4OnJldHVybnt0eXBlOm4sc2l6ZTp0fX1jYXNlImZsb2F0Ijpzd2l0Y2godCl7Y2FzZSA0OmNhc2UgODpyZXR1cm57dHlwZTpuLHNpemU6dH19fX1mdW5jdGlvbiBGMChuKXtpZihuLmJ5dGVMZW5ndGgld3MhPT0wKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBleHRyYSBieXRlcyBWTFIgbGVuZ3RoOiAke24uYnl0ZUxlbmd0aH1gKTtsZXQgdD1bXTtmb3IobGV0IGU9MDtlPG4uYnl0ZUxlbmd0aDtlKz13cyl0LnB1c2goY3Uobi5zbGljZShlLGUrd3MpKSk7cmV0dXJuIHR9ZnVuY3Rpb24gY3Uobil7aWYobi5ieXRlTGVuZ3RoIT09d3MpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGV4dHJhIGJ5dGVzIGVudHJ5IGxlbmd0aDogJHtuLmJ5dGVMZW5ndGh9YCk7bGV0IHQ9THQuQmluYXJ5LnRvRGF0YVZpZXcobiksZT1MdC5CaW5hcnkudG9DU3RyaW5nKG4uc2xpY2UoNCwzNikpLGk9THQuQmluYXJ5LnRvQ1N0cmluZyhuLnNsaWNlKDYwLDE5MikpLHI9dC5nZXRVaW50OCgyKSxzPXQuZ2V0VWludDgoMyk7aWYocj49MTEpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGV4dHJhIGJ5dGVzICJ0eXBlIiB2YWx1ZTogJHtyfWApO2lmKHI9PT0wKXJldHVybntuYW1lOmUsZGVzY3JpcHRpb246aSxsZW5ndGg6c307bGV0IGE9QjAocyksbz1PMChyKTtpZighbyl0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBleHRyYWN0IGRpbWVuc2lvbiB0eXBlOiAke3J9YCk7bGV0e3R5cGU6bCxzaXplOmN9PW87ZnVuY3Rpb24gaChtKXtzd2l0Y2gobCl7Y2FzZSJzaWduZWQiOnJldHVybigwLEx0LnBhcnNlQmlnSW50KSh0LmdldEJpZ0ludDY0KG0sITApKTtjYXNlInVuc2lnbmVkIjpyZXR1cm4oMCxMdC5wYXJzZUJpZ0ludCkoKDAsTHQuZ2V0QmlnVWludDY0KSh0LG0sITApKTtjYXNlImZsb2F0IjpyZXR1cm4gdC5nZXRGbG9hdDY0KG0sITApfX1sZXQgdT17bmFtZTplLGRlc2NyaXB0aW9uOmksdHlwZTpsLGxlbmd0aDpjfTtyZXR1cm4gYS5oYXNOb2RhdGEmJih1Lm5vZGF0YT1oKDQwKSksYS5oYXNNaW4mJih1Lm1pbj1oKDY0KSksYS5oYXNNYXgmJih1Lm1heD1oKDg4KSksYS5oYXNTY2FsZSYmKHUuc2NhbGU9dC5nZXRGbG9hdDY0KDExMikpLGEuaGFzT2Zmc2V0JiYodS5vZmZzZXQ9dC5nZXRGbG9hdDY0KDEzNikpLHV9ZnVuY3Rpb24gTzAobil7c3dpdGNoKG4pe2Nhc2UgMTpyZXR1cm4gTHQuRGltZW5zaW9uLlR5cGUudWludDg7Y2FzZSAyOnJldHVybiBMdC5EaW1lbnNpb24uVHlwZS5pbnQ4O2Nhc2UgMzpyZXR1cm4gTHQuRGltZW5zaW9uLlR5cGUudWludDE2O2Nhc2UgNDpyZXR1cm4gTHQuRGltZW5zaW9uLlR5cGUuaW50MTY7Y2FzZSA1OnJldHVybiBMdC5EaW1lbnNpb24uVHlwZS51aW50MzI7Y2FzZSA2OnJldHVybiBMdC5EaW1lbnNpb24uVHlwZS5pbnQzMjtjYXNlIDc6cmV0dXJuIEx0LkRpbWVuc2lvbi5UeXBlLnVpbnQ2NDtjYXNlIDg6cmV0dXJuIEx0LkRpbWVuc2lvbi5UeXBlLmludDY0O2Nhc2UgOTpyZXR1cm4gTHQuRGltZW5zaW9uLlR5cGUuZmxvYXQzMjtjYXNlIDEwOnJldHVybiBMdC5EaW1lbnNpb24uVHlwZS5mbG9hdDY0fX1mdW5jdGlvbiBCMChuKXtyZXR1cm57aGFzTm9kYXRhOiEhKG4mMSksaGFzTWluOiEhKG4+PjEmMSksaGFzTWF4OiEhKG4+PjImMSksaGFzU2NhbGU6ISEobj4+MyYxKSxoYXNPZmZzZXQ6ISEobj4+NCYxKX19fSk7dmFyIElvPXN0KFRzPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShUcywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7VHMuRGltZW5zaW9ucz12b2lkIDA7dmFyIEcwPWZlKCksejA9Um8oKTtUcy5EaW1lbnNpb25zPXtjcmVhdGU6VjB9O3ZhcntUeXBlOk10fT1HMC5EaW1lbnNpb24sazA9e1g6TXQuZmxvYXQ2NCxZOk10LmZsb2F0NjQsWjpNdC5mbG9hdDY0LEludGVuc2l0eTpNdC51aW50MTYsUmV0dXJuTnVtYmVyOk10LnVpbnQ4LE51bWJlck9mUmV0dXJuczpNdC51aW50OCxTY2FuRGlyZWN0aW9uRmxhZzpNdC5ib29sZWFuLEVkZ2VPZkZsaWdodExpbmU6TXQuYm9vbGVhbixDbGFzc2lmaWNhdGlvbjpNdC51aW50OCxTeW50aGV0aWM6TXQuYm9vbGVhbixLZXlQb2ludDpNdC5ib29sZWFuLFdpdGhoZWxkOk10LmJvb2xlYW4sT3ZlcmxhcDpNdC5ib29sZWFuLFNjYW5BbmdsZTpNdC5mbG9hdDMyLFVzZXJEYXRhOk10LnVpbnQ4LFBvaW50U291cmNlSWQ6TXQudWludDE2LEdwc1RpbWU6TXQuZmxvYXQ2NCxSZWQ6TXQudWludDE2LEdyZWVuOk10LnVpbnQxNixCbHVlOk10LnVpbnQxNixTY2FubmVyQ2hhbm5lbDpNdC51aW50OCxJbmZyYXJlZDpNdC51aW50MTZ9O2Z1bmN0aW9uIFYwKG4sdD1bXSl7cmV0dXJuIE9iamVjdC5rZXlzKG4pLnJlZHVjZSgoZSxpKT0+e2xldCByPWswW2ldO2lmKHIpcmV0dXJuey4uLmUsW2ldOnJ9O2xldCBzPXQuZmluZChvPT5vLm5hbWU9PT1pKSxhPXMmJnowLkV4dHJhQnl0ZXMuZ2V0RGltZW5zaW9uKHMpO2lmKGEpcmV0dXJuey4uLmUsW2ldOmF9O3Rocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvb2sgdXAgTEFTIHR5cGU6ICR7aX1gKX0se30pfX0pO3ZhciBMbz1zdChDcz0+eyJ1c2Ugc3RyaWN0IjtPYmplY3QuZGVmaW5lUHJvcGVydHkoQ3MsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO0NzLkV4dHJhY3Rvcj12b2lkIDA7dmFyIE5lPWZlKCk7Q3MuRXh0cmFjdG9yPXtjcmVhdGU6cTB9O2Z1bmN0aW9uIEgwKG4pe3N3aXRjaChuKXtjYXNlIDA6cmV0dXJuIDIwO2Nhc2UgMTpyZXR1cm4gMjg7Y2FzZSAyOnJldHVybiAyNjtjYXNlIDM6cmV0dXJuIDM0O2Nhc2UgNjpyZXR1cm4gMzA7Y2FzZSA3OnJldHVybiAzNjtjYXNlIDg6cmV0dXJuIDM4O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBwb2ludCBkYXRhIHJlY29yZCBmb3JtYXQ6ICR7bn1gKX19ZnVuY3Rpb24gVzAobix0LHt0eXBlOmUsbGVuZ3RoOml9KXtsZXQgcj1FbihuKTtzd2l0Y2goZSl7Y2FzZSJzaWduZWQiOnN3aXRjaChpKXtjYXNlIDE6cmV0dXJuKHMsYSk9PnMuZ2V0SW50OChyKGEpK3QpO2Nhc2UgMjpyZXR1cm4ocyxhKT0+cy5nZXRJbnQxNihyKGEpK3QsITApO2Nhc2UgNDpyZXR1cm4ocyxhKT0+cy5nZXRJbnQzMihyKGEpK3QsITApO2Nhc2UgODpyZXR1cm4ocyxhKT0+KDAsTmUucGFyc2VCaWdJbnQpKHMuZ2V0QmlnSW50NjQocihhKSt0LCEwKSl9Y2FzZSJ1bnNpZ25lZCI6c3dpdGNoKGkpe2Nhc2UgMTpyZXR1cm4ocyxhKT0+cy5nZXRVaW50OChyKGEpK3QpO2Nhc2UgMjpyZXR1cm4ocyxhKT0+cy5nZXRVaW50MTYocihhKSt0LCEwKTtjYXNlIDQ6cmV0dXJuKHMsYSk9PnMuZ2V0VWludDMyKHIoYSkrdCwhMCk7Y2FzZSA4OnJldHVybihzLGEpPT4oMCxOZS5wYXJzZUJpZ0ludCkoKDAsTmUuZ2V0QmlnVWludDY0KShzLHIoYSkrdCwhMCkpfWNhc2UiZmxvYXQiOnN3aXRjaChpKXtjYXNlIDQ6cmV0dXJuKHMsYSk9PnMuZ2V0RmxvYXQzMihyKGEpK3QsITApO2Nhc2UgODpyZXR1cm4ocyxhKT0+cy5nZXRGbG9hdDY0KHIoYSkrdCwhMCl9fX1mdW5jdGlvbiBYMChuLHQpe2xldCBpPUgwKG4ucG9pbnREYXRhUmVjb3JkRm9ybWF0KTtyZXR1cm4gdC5yZWR1Y2UoKHIscyk9PntsZXQgYT1pO2krPXMubGVuZ3RoO2xldCBvPVcwKG4sYSxzKTtpZighbylyZXR1cm4gcjtsZXQgbD0oYyxoKT0+TmUuU2NhbGUudW5hcHBseShvKGMsaCkscy5zY2FsZSxzLm9mZnNldCk7cmV0dXJuey4uLnIsW3MubmFtZV06bH19LHt9KX1mdW5jdGlvbiBxMChuLHQ9W10pe2xldCBlPVgwKG4sdCk7cmV0dXJuey4uLigoKT0+e2xldHtwb2ludERhdGFSZWNvcmRGb3JtYXQ6cn09bjtzd2l0Y2gocil7Y2FzZSAwOnJldHVybiBBcyhuKTtjYXNlIDE6cmV0dXJuIFkwKG4pO2Nhc2UgMjpyZXR1cm4gajAobik7Y2FzZSAzOnJldHVybiBaMChuKTtjYXNlIDY6cmV0dXJuIGh1KG4pO2Nhc2UgNzpyZXR1cm4gdXUobik7Y2FzZSA4OnJldHVybiAkMChuKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcG9pbnQgZGF0YSByZWNvcmQgZm9ybWF0OiAke3J9YCl9fSkoKSwuLi5lfX1mdW5jdGlvbiBBcyhuKXtsZXR7c2NhbGU6dCxvZmZzZXQ6ZX09bixpPUVuKG4pO2Z1bmN0aW9uIHIobyxsKXtyZXR1cm4gby5nZXRVaW50OChpKGwpKzE0KX1mdW5jdGlvbiBzKG8sbCl7cmV0dXJuIG8uZ2V0VWludDgoaShsKSsxNSl9ZnVuY3Rpb24gYShvLGwpe3JldHVybiBzKG8sbCkmMzF9cmV0dXJue1g6KG8sbCk9Pk5lLlNjYWxlLnVuYXBwbHkoby5nZXRJbnQzMihpKGwpLCEwKSx0WzBdLGVbMF0pLFk6KG8sbCk9Pk5lLlNjYWxlLnVuYXBwbHkoby5nZXRJbnQzMihpKGwpKzQsITApLHRbMV0sZVsxXSksWjoobyxsKT0+TmUuU2NhbGUudW5hcHBseShvLmdldEludDMyKGkobCkrOCwhMCksdFsyXSxlWzJdKSxJbnRlbnNpdHk6KG8sbCk9Pm8uZ2V0VWludDE2KGkobCkrMTIsITApLFJldHVybk51bWJlcjoobyxsKT0+cihvLGwpJjcsTnVtYmVyT2ZSZXR1cm5zOihvLGwpPT4ocihvLGwpJjU2KT4+MyxTY2FuRGlyZWN0aW9uRmxhZzoobyxsKT0+KHIobyxsKSY2NCk+PjYsRWRnZU9mRmxpZ2h0TGluZToobyxsKT0+KHIobyxsKSYxMjgpPj43LENsYXNzaWZpY2F0aW9uOihvLGwpPT57bGV0IGM9YShvLGwpO3JldHVybiBjPT09MTI/MDpjfSxTeW50aGV0aWM6KG8sbCk9PihzKG8sbCkmMzIpPj41LEtleVBvaW50OihvLGwpPT4ocyhvLGwpJjY0KT4+NixXaXRoaGVsZDoobyxsKT0+KHMobyxsKSYxMjgpPj43LE92ZXJsYXA6KG8sbCk9PmEobyxsKT09PTEyPzE6MCxTY2FuQW5nbGU6KG8sbCk9Pm8uZ2V0SW50OChpKGwpKzE2KSxVc2VyRGF0YToobyxsKT0+by5nZXRVaW50OChpKGwpKzE3KSxQb2ludFNvdXJjZUlkOihvLGwpPT5vLmdldFVpbnQxNihpKGwpKzE4LCEwKX19ZnVuY3Rpb24gWTAobil7bGV0IHQ9RW4obik7cmV0dXJuey4uLkFzKG4pLEdwc1RpbWU6KGUsaSk9PmUuZ2V0RmxvYXQ2NCh0KGkpKzIwLCEwKX19ZnVuY3Rpb24gajAobil7bGV0IHQ9RW4obik7cmV0dXJuey4uLkFzKG4pLFJlZDooZSxpKT0+ZS5nZXRVaW50MTYodChpKSsyMCwhMCksR3JlZW46KGUsaSk9PmUuZ2V0VWludDE2KHQoaSkrMjIsITApLEJsdWU6KGUsaSk9PmUuZ2V0VWludDE2KHQoaSkrMjQsITApfX1mdW5jdGlvbiBaMChuKXtsZXQgdD1FbihuKTtyZXR1cm57Li4uQXMobiksR3BzVGltZTooZSxpKT0+ZS5nZXRGbG9hdDY0KHQoaSkrMjAsITApLFJlZDooZSxpKT0+ZS5nZXRVaW50MTYodChpKSsyOCwhMCksR3JlZW46KGUsaSk9PmUuZ2V0VWludDE2KHQoaSkrMzAsITApLEJsdWU6KGUsaSk9PmUuZ2V0VWludDE2KHQoaSkrMzIsITApfX1mdW5jdGlvbiBodShuKXtsZXR7c2NhbGU6dCxvZmZzZXQ6ZX09bixpPUVuKG4pO2Z1bmN0aW9uIHIocyxhKXtyZXR1cm4gcy5nZXRVaW50OChpKGEpKzE1KX1yZXR1cm57WDoocyxhKT0+TmUuU2NhbGUudW5hcHBseShzLmdldEludDMyKGkoYSksITApLHRbMF0sZVswXSksWToocyxhKT0+TmUuU2NhbGUudW5hcHBseShzLmdldEludDMyKGkoYSkrNCwhMCksdFsxXSxlWzFdKSxaOihzLGEpPT5OZS5TY2FsZS51bmFwcGx5KHMuZ2V0SW50MzIoaShhKSs4LCEwKSx0WzJdLGVbMl0pLEludGVuc2l0eToocyxhKT0+cy5nZXRVaW50MTYoaShhKSsxMiwhMCksUmV0dXJuTnVtYmVyOihzLGEpPT5zLmdldFVpbnQxNihpKGEpKzE0LCEwKSYxNSxOdW1iZXJPZlJldHVybnM6KHMsYSk9PihzLmdldFVpbnQxNihpKGEpKzE0LCEwKSYyNDApPj40LFN5bnRoZXRpYzoocyxhKT0+cihzLGEpJjEsS2V5UG9pbnQ6KHMsYSk9PihyKHMsYSkmMik+PjEsV2l0aGhlbGQ6KHMsYSk9PihyKHMsYSkmNCk+PjIsT3ZlcmxhcDoocyxhKT0+KHIocyxhKSY4KT4+MyxTY2FubmVyQ2hhbm5lbDoocyxhKT0+KHIocyxhKSY0OCk+PjQsU2NhbkRpcmVjdGlvbkZsYWc6KHMsYSk9PihyKHMsYSkmNjQpPj42LEVkZ2VPZkZsaWdodExpbmU6KHMsYSk9PihyKHMsYSkmMTI4KT4+NyxDbGFzc2lmaWNhdGlvbjoocyxhKT0+cy5nZXRVaW50OChpKGEpKzE2KSxVc2VyRGF0YToocyxhKT0+cy5nZXRVaW50OChpKGEpKzE3KSxTY2FuQW5nbGU6KHMsYSk9PnMuZ2V0SW50MTYoaShhKSsxOCwhMCkqLjAwNixQb2ludFNvdXJjZUlkOihzLGEpPT5zLmdldFVpbnQxNihpKGEpKzIwLCEwKSxHcHNUaW1lOihzLGEpPT5zLmdldEZsb2F0NjQoaShhKSsyMiwhMCl9fWZ1bmN0aW9uIHV1KG4pe2xldCB0PUVuKG4pO3JldHVybnsuLi5odShuKSxSZWQ6KGUsaSk9PmUuZ2V0VWludDE2KHQoaSkrMzAsITApLEdyZWVuOihlLGkpPT5lLmdldFVpbnQxNih0KGkpKzMyLCEwKSxCbHVlOihlLGkpPT5lLmdldFVpbnQxNih0KGkpKzM0LCEwKX19ZnVuY3Rpb24gJDAobil7bGV0IHQ9RW4obik7cmV0dXJuey4uLnV1KG4pLEluZnJhcmVkOihlLGkpPT5lLmdldFVpbnQxNih0KGkpKzM2LCEwKX19ZnVuY3Rpb24gRW4obil7bGV0e3BvaW50RGF0YVJlY29yZExlbmd0aDp0fT1uO3JldHVybiBmdW5jdGlvbihpKXtyZXR1cm4gaSp0fX19KTt2YXIgZHU9c3Qodmk9PnsidXNlIHN0cmljdCI7T2JqZWN0LmRlZmluZVByb3BlcnR5KHZpLCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KTt2aS5mb3JtYXRHdWlkPXZpLnBhcnNlUG9pbnQ9dm9pZCAwO3ZhciBmdT1mZSgpO2Z1bmN0aW9uIEowKG4pe2xldCB0PWZ1LkJpbmFyeS50b0RhdGFWaWV3KG4pO2lmKHQuYnl0ZUxlbmd0aCE9PTI0KXRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0dXBsZSBidWZmZXIgbGVuZ3RoOiAke3QuYnl0ZUxlbmd0aH1gKTtyZXR1cm5bdC5nZXRGbG9hdDY0KDAsITApLHQuZ2V0RmxvYXQ2NCg4LCEwKSx0LmdldEZsb2F0NjQoMTYsITApXX12aS5wYXJzZVBvaW50PUowO2Z1bmN0aW9uIEswKG4pe2xldCB0PWZ1LkJpbmFyeS50b0RhdGFWaWV3KG4pO2lmKHQuYnl0ZUxlbmd0aCE9PTE2KXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBHVUlEIGJ1ZmZlciBsZW5ndGg6ICR7dC5ieXRlTGVuZ3RofWApO2xldCBlPSIiO2ZvcihsZXQgaT0wO2k8dC5ieXRlTGVuZ3RoO2krPTQpe2xldCByPXQuZ2V0VWludDMyKGksITApO2UrPXIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDgsIjAiKX1yZXR1cm5bZS5zbGljZSgwLDgpLGUuc2xpY2UoOCwxMiksZS5zbGljZSgxMiwxNiksZS5zbGljZSgxNiwzMildLmpvaW4oIi0iKX12aS5mb3JtYXRHdWlkPUswfSk7dmFyIE5vPXN0KFBzPT57InVzZSBzdHJpY3QiO09iamVjdC5kZWZpbmVQcm9wZXJ0eShQcywiX19lc01vZHVsZSIse3ZhbHVlOiEwfSk7UHMuSGVhZGVyPXZvaWQgMDt2YXIgJHQ9ZmUoKSxwdT1fcygpLERvPWR1KCk7UHMuSGVhZGVyPXtwYXJzZTpRMH07ZnVuY3Rpb24gUTAobil7aWYobi5ieXRlTGVuZ3RoPHB1Lm1pbkhlYWRlckxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaGVhZGVyOiBtdXN0IGJlIGF0IGxlYXN0ICR7cHUubWluSGVhZGVyTGVuZ3RofSBieXRlc2ApO2xldCB0PSR0LkJpbmFyeS50b0RhdGFWaWV3KG4pLGU9JHQuQmluYXJ5LnRvQ1N0cmluZyhuLnNsaWNlKDAsNCkpO2lmKGUhPT0iTEFTRiIpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGZpbGUgc2lnbmF0dXJlOiAke2V9YCk7bGV0IGk9dC5nZXRVaW50OCgyNCkscj10LmdldFVpbnQ4KDI1KTtpZihpIT09MXx8ciE9PTImJnIhPT00KXRocm93IG5ldyBFcnJvcihgSW52YWxpZCB2ZXJzaW9uIChvbmx5IDEuMiBhbmQgMS40IHN1cHBvcnRlZCk6ICR7aX0uJHtyfWApO2xldCBzPXtmaWxlU2lnbmF0dXJlOmUsZmlsZVNvdXJjZUlkOnQuZ2V0VWludDE2KDQsITApLGdsb2JhbEVuY29kaW5nOnQuZ2V0VWludDE2KDYsITApLHByb2plY3RJZDooMCxEby5mb3JtYXRHdWlkKShuLnNsaWNlKDgsMjQpKSxtYWpvclZlcnNpb246aSxtaW5vclZlcnNpb246cixzeXN0ZW1JZGVudGlmaWVyOiR0LkJpbmFyeS50b0NTdHJpbmcobi5zbGljZSgyNiw1OCkpLGdlbmVyYXRpbmdTb2Z0d2FyZTokdC5CaW5hcnkudG9DU3RyaW5nKG4uc2xpY2UoNTgsOTApKSxmaWxlQ3JlYXRpb25EYXlPZlllYXI6dC5nZXRVaW50MTYoOTAsITApLGZpbGVDcmVhdGlvblllYXI6dC5nZXRVaW50MTYoOTIsITApLGhlYWRlckxlbmd0aDp0LmdldFVpbnQxNig5NCwhMCkscG9pbnREYXRhT2Zmc2V0OnQuZ2V0VWludDMyKDk2LCEwKSx2bHJDb3VudDp0LmdldFVpbnQzMigxMDAsITApLHBvaW50RGF0YVJlY29yZEZvcm1hdDp0LmdldFVpbnQ4KDEwNCkmMTUscG9pbnREYXRhUmVjb3JkTGVuZ3RoOnQuZ2V0VWludDE2KDEwNSwhMCkscG9pbnRDb3VudDp0LmdldFVpbnQzMigxMDcsITApLHBvaW50Q291bnRCeVJldHVybjplXyhuLnNsaWNlKDExMSwxMzEpKSxzY2FsZTooMCxEby5wYXJzZVBvaW50KShuLnNsaWNlKDEzMSwxNTUpKSxvZmZzZXQ6KDAsRG8ucGFyc2VQb2ludCkobi5zbGljZSgxNTUsMTc5KSksbWluOlt0LmdldEZsb2F0NjQoMTg3LCEwKSx0LmdldEZsb2F0NjQoMjAzLCEwKSx0LmdldEZsb2F0NjQoMjE5LCEwKV0sbWF4Olt0LmdldEZsb2F0NjQoMTc5LCEwKSx0LmdldEZsb2F0NjQoMTk1LCEwKSx0LmdldEZsb2F0NjQoMjExLCEwKV0sd2F2ZWZvcm1EYXRhT2Zmc2V0OjAsZXZsck9mZnNldDowLGV2bHJDb3VudDowfTtyZXR1cm4gcj09Mj9zOnsuLi5zLHBvaW50Q291bnQ6KDAsJHQucGFyc2VCaWdJbnQpKCgwLCR0LmdldEJpZ1VpbnQ2NCkodCwyNDcsITApKSxwb2ludENvdW50QnlSZXR1cm46dF8obi5zbGljZSgyNTUsMzc1KSksd2F2ZWZvcm1EYXRhT2Zmc2V0OigwLCR0LnBhcnNlQmlnSW50KSgoMCwkdC5nZXRCaWdVaW50NjQpKHQsMjI3LCEwKSksZXZsck9mZnNldDooMCwkdC5wYXJzZUJpZ0ludCkoKDAsJHQuZ2V0QmlnVWludDY0KSh0LDIzNSwhMCkpLGV2bHJDb3VudDp0LmdldFVpbnQzMigyNDMsITApfX1mdW5jdGlvbiB0XyhuKXtsZXQgdD0kdC5CaW5hcnkudG9EYXRhVmlldyhuKSxlPVtdO2ZvcihsZXQgaT0wO2k8MTIwO2krPTgpZS5wdXNoKCgwLCR0LmdldEJpZ1VpbnQ2NCkodCxpLCEwKSk7cmV0dXJuIGUubWFwKGk9PigwLCR0LnBhcnNlQmlnSW50KShpKSl9ZnVuY3Rpb24gZV8obil7bGV0IHQ9JHQuQmluYXJ5LnRvRGF0YVZpZXcobiksZT1bXTtmb3IobGV0IGk9MDtpPDIwO2krPTQpZS5wdXNoKHQuZ2V0VWludDMyKGksITApKTtyZXR1cm4gZX19KTt2YXIgbXU9c3QoKFJzLEZvKT0+e3ZhciBVbz0oKCk9Pnt2YXIgbj10eXBlb2YgZG9jdW1lbnQ8InUiJiZkb2N1bWVudC5jdXJyZW50U2NyaXB0P2RvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjOnZvaWQgMDtyZXR1cm4oZnVuY3Rpb24odCl7dD10fHx7fTt2YXIgZT10eXBlb2YgdDwidSI/dDp7fSxpLHI7ZS5yZWFkeT1uZXcgUHJvbWlzZShmdW5jdGlvbihmLHApe2k9ZixyPXB9KSxbIl9tYWluIiwiX19fZ2V0VHlwZU5hbWUiLCJfX2VtYmluZF9pbml0aWFsaXplX2JpbmRpbmdzIiwiX2ZmbHVzaCIsIm9uUnVudGltZUluaXRpYWxpemVkIl0uZm9yRWFjaChmPT57T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLnJlYWR5LGYpfHxPYmplY3QuZGVmaW5lUHJvcGVydHkoZS5yZWFkeSxmLHtnZXQ6KCk9Pmp0KCJZb3UgYXJlIGdldHRpbmcgIitmKyIgb24gdGhlIFByb21pc2Ugb2JqZWN0LCBpbnN0ZWFkIG9mIHRoZSBpbnN0YW5jZS4gVXNlIC50aGVuKCkgdG8gZ2V0IGNhbGxlZCBiYWNrIHdpdGggdGhlIGluc3RhbmNlLCBzZWUgdGhlIE1PRFVMQVJJWkUgZG9jcyBpbiBzcmMvc2V0dGluZ3MuanMiKSxzZXQ6KCk9Pmp0KCJZb3UgYXJlIHNldHRpbmcgIitmKyIgb24gdGhlIFByb21pc2Ugb2JqZWN0LCBpbnN0ZWFkIG9mIHRoZSBpbnN0YW5jZS4gVXNlIC50aGVuKCkgdG8gZ2V0IGNhbGxlZCBiYWNrIHdpdGggdGhlIGluc3RhbmNlLCBzZWUgdGhlIE1PRFVMQVJJWkUgZG9jcyBpbiBzcmMvc2V0dGluZ3MuanMiKX0pfSk7dmFyIHM9T2JqZWN0LmFzc2lnbih7fSxlKSxhPVtdLG89Ii4vdGhpcy5wcm9ncmFtIixsPShmLHApPT57dGhyb3cgcH0sYz0hMCxoPSExLHU9ITEsbT0hMTtpZihlLkVOVklST05NRU5UKXRocm93IG5ldyBFcnJvcigiTW9kdWxlLkVOVklST05NRU5UIGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFRvIGZvcmNlIHRoZSBlbnZpcm9ubWVudCwgdXNlIHRoZSBFTlZJUk9OTUVOVCBjb21waWxlLXRpbWUgb3B0aW9uIChmb3IgZXhhbXBsZSwgLXNFTlZJUk9OTUVOVD13ZWIgb3IgLXNFTlZJUk9OTUVOVD1ub2RlKSIpO3ZhciBkPSIiO2Z1bmN0aW9uIGcoZil7cmV0dXJuIGUubG9jYXRlRmlsZT9lLmxvY2F0ZUZpbGUoZixkKTpkK2Z9dmFyIHksdixTLEM7ZnVuY3Rpb24gTihmKXtpZihmIGluc3RhbmNlb2YgY20pcmV0dXJuO2xldCBwPWY7ZiYmdHlwZW9mIGY9PSJvYmplY3QiJiZmLnN0YWNrJiYocD1bZixmLnN0YWNrXSksUigiZXhpdGluZyBkdWUgdG8gZXhjZXB0aW9uOiAiK3ApfWlmKG0pe2lmKHR5cGVvZiBwcm9jZXNzPT0ib2JqZWN0IiYmdHlwZW9mIE9oPT0iZnVuY3Rpb24ifHx0eXBlb2Ygd2luZG93PT0ib2JqZWN0Inx8dHlwZW9mIGltcG9ydFNjcmlwdHM9PSJmdW5jdGlvbiIpdGhyb3cgbmV3IEVycm9yKCJub3QgY29tcGlsZWQgZm9yIHRoaXMgZW52aXJvbm1lbnQgKGRpZCB5b3UgYnVpbGQgdG8gSFRNTCBhbmQgdHJ5IHRvIHJ1biBpdCBub3Qgb24gdGhlIHdlYiwgb3Igc2V0IEVOVklST05NRU5UIHRvIHNvbWV0aGluZyAtIGxpa2Ugbm9kZSAtIGFuZCBydW4gaXQgc29tZXBsYWNlIGVsc2UgLSBsaWtlIG9uIHRoZSB3ZWI/KSIpO3R5cGVvZiByZWFkPCJ1IiYmKHk9ZnVuY3Rpb24ocCl7cmV0dXJuIHJlYWQocCl9KSxTPWZ1bmN0aW9uKHApe2xldCBfO3JldHVybiB0eXBlb2YgcmVhZGJ1ZmZlcj09ImZ1bmN0aW9uIj9uZXcgVWludDhBcnJheShyZWFkYnVmZmVyKHApKTooXz1yZWFkKHAsImJpbmFyeSIpLGsodHlwZW9mIF89PSJvYmplY3QiKSxfKX0sdj1mdW5jdGlvbihwLF8seCl7c2V0VGltZW91dCgoKT0+XyhTKHApKSwwKX0sdHlwZW9mIHNjcmlwdEFyZ3M8InUiP2E9c2NyaXB0QXJnczp0eXBlb2YgYXJndW1lbnRzPCJ1IiYmKGE9YXJndW1lbnRzKSx0eXBlb2YgcXVpdD09ImZ1bmN0aW9uIiYmKGw9KGYscCk9PntOKHApLHF1aXQoZil9KSx0eXBlb2YgcHJpbnQ8InUiJiYodHlwZW9mIGNvbnNvbGU+InUiJiYoY29uc29sZT17fSksY29uc29sZS5sb2c9cHJpbnQsY29uc29sZS53YXJuPWNvbnNvbGUuZXJyb3I9dHlwZW9mIHByaW50RXJyPCJ1Ij9wcmludEVycjpwcmludCl9ZWxzZSBpZihjfHxoKXtpZihoP2Q9c2VsZi5sb2NhdGlvbi5ocmVmOnR5cGVvZiBkb2N1bWVudDwidSImJmRvY3VtZW50LmN1cnJlbnRTY3JpcHQmJihkPWRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjKSxuJiYoZD1uKSxkLmluZGV4T2YoImJsb2I6IikhPT0wP2Q9ZC5zdWJzdHIoMCxkLnJlcGxhY2UoL1s/I10uKi8sIiIpLmxhc3RJbmRleE9mKCIvIikrMSk6ZD0iIiwhKHR5cGVvZiB3aW5kb3c9PSJvYmplY3QifHx0eXBlb2YgaW1wb3J0U2NyaXB0cz09ImZ1bmN0aW9uIikpdGhyb3cgbmV3IEVycm9yKCJub3QgY29tcGlsZWQgZm9yIHRoaXMgZW52aXJvbm1lbnQgKGRpZCB5b3UgYnVpbGQgdG8gSFRNTCBhbmQgdHJ5IHRvIHJ1biBpdCBub3Qgb24gdGhlIHdlYiwgb3Igc2V0IEVOVklST05NRU5UIHRvIHNvbWV0aGluZyAtIGxpa2Ugbm9kZSAtIGFuZCBydW4gaXQgc29tZXBsYWNlIGVsc2UgLSBsaWtlIG9uIHRoZSB3ZWI/KSIpO3k9Zj0+e3ZhciBwPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gcC5vcGVuKCJHRVQiLGYsITEpLHAuc2VuZChudWxsKSxwLnJlc3BvbnNlVGV4dH0saCYmKFM9Zj0+e3ZhciBwPW5ldyBYTUxIdHRwUmVxdWVzdDtyZXR1cm4gcC5vcGVuKCJHRVQiLGYsITEpLHAucmVzcG9uc2VUeXBlPSJhcnJheWJ1ZmZlciIscC5zZW5kKG51bGwpLG5ldyBVaW50OEFycmF5KHAucmVzcG9uc2UpfSksdj0oZixwLF8pPT57dmFyIHg9bmV3IFhNTEh0dHBSZXF1ZXN0O3gub3BlbigiR0VUIixmLCEwKSx4LnJlc3BvbnNlVHlwZT0iYXJyYXlidWZmZXIiLHgub25sb2FkPSgpPT57aWYoeC5zdGF0dXM9PTIwMHx8eC5zdGF0dXM9PTAmJngucmVzcG9uc2Upe3AoeC5yZXNwb25zZSk7cmV0dXJufV8oKX0seC5vbmVycm9yPV8seC5zZW5kKG51bGwpfSxDPWY9PmRvY3VtZW50LnRpdGxlPWZ9ZWxzZSB0aHJvdyBuZXcgRXJyb3IoImVudmlyb25tZW50IGRldGVjdGlvbiBlcnJvciIpO3ZhciBGPWUucHJpbnR8fGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSksUj1lLnByaW50RXJyfHxjb25zb2xlLndhcm4uYmluZChjb25zb2xlKTtPYmplY3QuYXNzaWduKGUscykscz1udWxsLE9nKCksZS5hcmd1bWVudHMmJihhPWUuYXJndW1lbnRzKSxCKCJhcmd1bWVudHMiLCJhcmd1bWVudHNfIiksZS50aGlzUHJvZ3JhbSYmKG89ZS50aGlzUHJvZ3JhbSksQigidGhpc1Byb2dyYW0iLCJ0aGlzUHJvZ3JhbSIpLGUucXVpdCYmKGw9ZS5xdWl0KSxCKCJxdWl0IiwicXVpdF8iKSxrKHR5cGVvZiBlLm1lbW9yeUluaXRpYWxpemVyUHJlZml4VVJMPiJ1IiwiTW9kdWxlLm1lbW9yeUluaXRpYWxpemVyUHJlZml4VVJMIG9wdGlvbiB3YXMgcmVtb3ZlZCwgdXNlIE1vZHVsZS5sb2NhdGVGaWxlIGluc3RlYWQiKSxrKHR5cGVvZiBlLnB0aHJlYWRNYWluUHJlZml4VVJMPiJ1IiwiTW9kdWxlLnB0aHJlYWRNYWluUHJlZml4VVJMIG9wdGlvbiB3YXMgcmVtb3ZlZCwgdXNlIE1vZHVsZS5sb2NhdGVGaWxlIGluc3RlYWQiKSxrKHR5cGVvZiBlLmNkSW5pdGlhbGl6ZXJQcmVmaXhVUkw+InUiLCJNb2R1bGUuY2RJbml0aWFsaXplclByZWZpeFVSTCBvcHRpb24gd2FzIHJlbW92ZWQsIHVzZSBNb2R1bGUubG9jYXRlRmlsZSBpbnN0ZWFkIiksayh0eXBlb2YgZS5maWxlUGFja2FnZVByZWZpeFVSTD4idSIsIk1vZHVsZS5maWxlUGFja2FnZVByZWZpeFVSTCBvcHRpb24gd2FzIHJlbW92ZWQsIHVzZSBNb2R1bGUubG9jYXRlRmlsZSBpbnN0ZWFkIiksayh0eXBlb2YgZS5yZWFkPiJ1IiwiTW9kdWxlLnJlYWQgb3B0aW9uIHdhcyByZW1vdmVkIChtb2RpZnkgcmVhZF8gaW4gSlMpIiksayh0eXBlb2YgZS5yZWFkQXN5bmM+InUiLCJNb2R1bGUucmVhZEFzeW5jIG9wdGlvbiB3YXMgcmVtb3ZlZCAobW9kaWZ5IHJlYWRBc3luYyBpbiBKUykiKSxrKHR5cGVvZiBlLnJlYWRCaW5hcnk+InUiLCJNb2R1bGUucmVhZEJpbmFyeSBvcHRpb24gd2FzIHJlbW92ZWQgKG1vZGlmeSByZWFkQmluYXJ5IGluIEpTKSIpLGsodHlwZW9mIGUuc2V0V2luZG93VGl0bGU+InUiLCJNb2R1bGUuc2V0V2luZG93VGl0bGUgb3B0aW9uIHdhcyByZW1vdmVkIChtb2RpZnkgc2V0V2luZG93VGl0bGUgaW4gSlMpIiksayh0eXBlb2YgZS5UT1RBTF9NRU1PUlk+InUiLCJNb2R1bGUuVE9UQUxfTUVNT1JZIGhhcyBiZWVuIHJlbmFtZWQgTW9kdWxlLklOSVRJQUxfTUVNT1JZIiksQigicmVhZCIsInJlYWRfIiksQigicmVhZEFzeW5jIiwicmVhZEFzeW5jIiksQigicmVhZEJpbmFyeSIsInJlYWRCaW5hcnkiKSxCKCJzZXRXaW5kb3dUaXRsZSIsInNldFdpbmRvd1RpdGxlIiksayghaCwid29ya2VyIGVudmlyb25tZW50IGRldGVjdGVkIGJ1dCBub3QgZW5hYmxlZCBhdCBidWlsZCB0aW1lLiAgQWRkICd3b3JrZXInIHRvIGAtc0VOVklST05NRU5UYCB0byBlbmFibGUuIiksayghdSwibm9kZSBlbnZpcm9ubWVudCBkZXRlY3RlZCBidXQgbm90IGVuYWJsZWQgYXQgYnVpbGQgdGltZS4gIEFkZCAnbm9kZScgdG8gYC1zRU5WSVJPTk1FTlRgIHRvIGVuYWJsZS4iKSxrKCFtLCJzaGVsbCBlbnZpcm9ubWVudCBkZXRlY3RlZCBidXQgbm90IGVuYWJsZWQgYXQgYnVpbGQgdGltZS4gIEFkZCAnc2hlbGwnIHRvIGAtc0VOVklST05NRU5UYCB0byBlbmFibGUuIik7dmFyIFY9NDtmdW5jdGlvbiBCKGYscCl7T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLGYpfHxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSxmLHtjb25maWd1cmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7anQoIk1vZHVsZS4iK2YrIiBoYXMgYmVlbiByZXBsYWNlZCB3aXRoIHBsYWluICIrcCsiICh0aGUgaW5pdGlhbCB2YWx1ZSBjYW4gYmUgcHJvdmlkZWQgb24gTW9kdWxlLCBidXQgYWZ0ZXIgc3RhcnR1cCB0aGUgdmFsdWUgaXMgb25seSBsb29rZWQgZm9yIG9uIGEgbG9jYWwgdmFyaWFibGUgb2YgdGhhdCBuYW1lKSIpfX0pfWZ1bmN0aW9uIEgoZil7T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLGYpJiZqdCgiYE1vZHVsZS4iK2YrImAgd2FzIHN1cHBsaWVkIGJ1dCBgIitmKyJgIG5vdCBpbmNsdWRlZCBpbiBJTkNPTUlOR19NT0RVTEVfSlNfQVBJIil9ZnVuY3Rpb24gJChmKXtyZXR1cm4gZj09PSJGU19jcmVhdGVQYXRoInx8Zj09PSJGU19jcmVhdGVEYXRhRmlsZSJ8fGY9PT0iRlNfY3JlYXRlUHJlbG9hZGVkRmlsZSJ8fGY9PT0iRlNfdW5saW5rInx8Zj09PSJhZGRSdW5EZXBlbmRlbmN5Inx8Zj09PSJGU19jcmVhdGVMYXp5RmlsZSJ8fGY9PT0iRlNfY3JlYXRlRGV2aWNlInx8Zj09PSJyZW1vdmVSdW5EZXBlbmRlbmN5In1mdW5jdGlvbiBhdChmKXt0eXBlb2YgZ2xvYmFsVGhpczwidSImJiFPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbFRoaXMsZikmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLGYse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXt2YXIgcD0iYCIrZisiYCBpcyBhIGxpYnJhcnkgc3ltYm9sIGFuZCBub3QgaW5jbHVkZWQgYnkgZGVmYXVsdDsgYWRkIGl0IHRvIHlvdXIgbGlicmFyeS5qcyBfX2RlcHMgb3IgdG8gREVGQVVMVF9MSUJSQVJZX0ZVTkNTX1RPX0lOQ0xVREUgb24gdGhlIGNvbW1hbmQgbGluZSI7JChmKSYmKHArPSIuIEFsdGVybmF0aXZlbHksIGZvcmNpbmcgZmlsZXN5c3RlbSBzdXBwb3J0ICgtc0ZPUkNFX0ZJTEVTWVNURU0pIGNhbiBleHBvcnQgdGhpcyBmb3IgeW91IikseW4ocCl9fSl9ZnVuY3Rpb24gTShmKXtPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGUsZil8fE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLGYse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXt2YXIgcD0iJyIrZisiJyB3YXMgbm90IGV4cG9ydGVkLiBhZGQgaXQgdG8gRVhQT1JURURfUlVOVElNRV9NRVRIT0RTIChzZWUgdGhlIEZBUSkiOyQoZikmJihwKz0iLiBBbHRlcm5hdGl2ZWx5LCBmb3JjaW5nIGZpbGVzeXN0ZW0gc3VwcG9ydCAoLXNGT1JDRV9GSUxFU1lTVEVNKSBjYW4gZXhwb3J0IHRoaXMgZm9yIHlvdSIpLGp0KHApfX0pfXZhciBQO2Uud2FzbUJpbmFyeSYmKFA9ZS53YXNtQmluYXJ5KSxCKCJ3YXNtQmluYXJ5Iiwid2FzbUJpbmFyeSIpO3ZhciBXPWUubm9FeGl0UnVudGltZXx8ITA7Qigibm9FeGl0UnVudGltZSIsIm5vRXhpdFJ1bnRpbWUiKSx0eXBlb2YgV2ViQXNzZW1ibHkhPSJvYmplY3QiJiZqdCgibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZCIpO3ZhciBqLHJ0PSExLEo7ZnVuY3Rpb24gayhmLHApe2Z8fGp0KCJBc3NlcnRpb24gZmFpbGVkIisocD8iOiAiK3A6IiIpKX12YXIgeGU9dHlwZW9mIFRleHREZWNvZGVyPCJ1Ij9uZXcgVGV4dERlY29kZXIoInV0ZjgiKTp2b2lkIDA7ZnVuY3Rpb24gUmUoZixwLF8pe2Zvcih2YXIgeD1wK18sYj1wO2ZbYl0mJiEoYj49eCk7KSsrYjtpZihiLXA+MTYmJmYuYnVmZmVyJiZ4ZSlyZXR1cm4geGUuZGVjb2RlKGYuc3ViYXJyYXkocCxiKSk7Zm9yKHZhciBBPSIiO3A8Yjspe3ZhciBJPWZbcCsrXTtpZighKEkmMTI4KSl7QSs9U3RyaW5nLmZyb21DaGFyQ29kZShJKTtjb250aW51ZX12YXIgdz1mW3ArK10mNjM7aWYoKEkmMjI0KT09MTkyKXtBKz1TdHJpbmcuZnJvbUNoYXJDb2RlKChJJjMxKTw8Nnx3KTtjb250aW51ZX12YXIgTz1mW3ArK10mNjM7aWYoKEkmMjQwKT09MjI0P0k9KEkmMTUpPDwxMnx3PDw2fE86KChJJjI0OCkhPTI0MCYmeW4oIkludmFsaWQgVVRGLTggbGVhZGluZyBieXRlIDB4IitJLnRvU3RyaW5nKDE2KSsiIGVuY291bnRlcmVkIHdoZW4gZGVzZXJpYWxpemluZyBhIFVURi04IHN0cmluZyBpbiB3YXNtIG1lbW9yeSB0byBhIEpTIHN0cmluZyEiKSxJPShJJjcpPDwxOHx3PDwxMnxPPDw2fGZbcCsrXSY2MyksSTw2NTUzNilBKz1TdHJpbmcuZnJvbUNoYXJDb2RlKEkpO2Vsc2V7dmFyIEc9SS02NTUzNjtBKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fEc+PjEwLDU2MzIwfEcmMTAyMyl9fXJldHVybiBBfWZ1bmN0aW9uIGh0KGYscCl7cmV0dXJuIGY/UmUoWXQsZixwKToiIn1mdW5jdGlvbiBrdChmLHAsXyx4KXtpZighKHg+MCkpcmV0dXJuIDA7Zm9yKHZhciBiPV8sQT1fK3gtMSxJPTA7STxmLmxlbmd0aDsrK0kpe3ZhciB3PWYuY2hhckNvZGVBdChJKTtpZih3Pj01NTI5NiYmdzw9NTczNDMpe3ZhciBPPWYuY2hhckNvZGVBdCgrK0kpO3c9NjU1MzYrKCh3JjEwMjMpPDwxMCl8TyYxMDIzfWlmKHc8PTEyNyl7aWYoXz49QSlicmVhaztwW18rK109d31lbHNlIGlmKHc8PTIwNDcpe2lmKF8rMT49QSlicmVhaztwW18rK109MTkyfHc+PjYscFtfKytdPTEyOHx3JjYzfWVsc2UgaWYodzw9NjU1MzUpe2lmKF8rMj49QSlicmVhaztwW18rK109MjI0fHc+PjEyLHBbXysrXT0xMjh8dz4+NiY2MyxwW18rK109MTI4fHcmNjN9ZWxzZXtpZihfKzM+PUEpYnJlYWs7dz4xMTE0MTExJiZ5bigiSW52YWxpZCBVbmljb2RlIGNvZGUgcG9pbnQgMHgiK3cudG9TdHJpbmcoMTYpKyIgZW5jb3VudGVyZWQgd2hlbiBzZXJpYWxpemluZyBhIEpTIHN0cmluZyB0byBhIFVURi04IHN0cmluZyBpbiB3YXNtIG1lbW9yeSEgKFZhbGlkIHVuaWNvZGUgY29kZSBwb2ludHMgc2hvdWxkIGJlIGluIHJhbmdlIDAtMHgxMEZGRkYpLiIpLHBbXysrXT0yNDB8dz4+MTgscFtfKytdPTEyOHx3Pj4xMiY2MyxwW18rK109MTI4fHc+PjYmNjMscFtfKytdPTEyOHx3JjYzfX1yZXR1cm4gcFtfXT0wLF8tYn1mdW5jdGlvbiBuaChmLHAsXyl7cmV0dXJuIGsodHlwZW9mIF89PSJudW1iZXIiLCJzdHJpbmdUb1VURjgoc3RyLCBvdXRQdHIsIG1heEJ5dGVzVG9Xcml0ZSkgaXMgbWlzc2luZyB0aGUgdGhpcmQgcGFyYW1ldGVyIHRoYXQgc3BlY2lmaWVzIHRoZSBsZW5ndGggb2YgdGhlIG91dHB1dCBidWZmZXIhIiksa3QoZixZdCxwLF8pfWZ1bmN0aW9uIGloKGYpe2Zvcih2YXIgcD0wLF89MDtfPGYubGVuZ3RoOysrXyl7dmFyIHg9Zi5jaGFyQ29kZUF0KF8pO3g8PTEyNz9wKys6eDw9MjA0Nz9wKz0yOng+PTU1Mjk2JiZ4PD01NzM0Mz8ocCs9NCwrK18pOnArPTN9cmV0dXJuIHB9dmFyIHNzLEllLFl0LGNpLGFzLG10LHV0LHJoLHNoO2Z1bmN0aW9uIGFoKGYpe3NzPWYsZS5IRUFQOD1JZT1uZXcgSW50OEFycmF5KGYpLGUuSEVBUDE2PWNpPW5ldyBJbnQxNkFycmF5KGYpLGUuSEVBUDMyPW10PW5ldyBJbnQzMkFycmF5KGYpLGUuSEVBUFU4PVl0PW5ldyBVaW50OEFycmF5KGYpLGUuSEVBUFUxNj1hcz1uZXcgVWludDE2QXJyYXkoZi