{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/object-fit-images/dist/ofi.common-js.js","node_modules/picturefill/dist/picturefill.js","node_modules/smoothscroll-polyfill/dist/smoothscroll.js","wp-content/themes/jcore2/js/jcore.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxgDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACjbA;;AACA;;AACA;;;;AADqB;AAGrB;AACA,8BAAa,QAAb;;AAEA,MAAM,CAAC,QAAD,CAAN,CAAiB,KAAjB,CAAuB,YAAY;AAC/B;AACA,EAAA,MAAM,CAAC,yBAAD,CAAN,CAAkC,OAAlC;AACH,CAHD,E,CAKA;;AACA,IAAI,cAAc,MAAd,IAAwB,CAAC,QAAQ,CAAC,SAAT,CAAmB,OAAhD,EAAyD;AACrD,EAAA,QAAQ,CAAC,SAAT,CAAmB,OAAnB,GAA6B,UAAU,QAAV,EAAoB,OAApB,EAA6B;AACtD,IAAA,OAAO,GAAG,OAAO,IAAI,MAArB;;AAEA,SAAK,IAAI,CAAC,GAAG,CAAb,EAAgB,CAAC,GAAG,KAAK,MAAzB,EAAiC,CAAC,EAAlC,EAAsC;AAClC,MAAA,QAAQ,CAAC,IAAT,CAAc,OAAd,EAAuB,KAAK,CAAL,CAAvB,EAAgC,CAAhC,EAAmC,IAAnC;AACH;AACJ,GAND;AAOH,C,CAED;AACA;;;AACA,IAAI,EAAE,GAAG,MAAM,CAAC,WAAP,GAAqB,IAA9B;AACA,QAAQ,CAAC,eAAT,CAAyB,KAAzB,CAA+B,WAA/B,CAA2C,MAA3C,YAAsD,EAAtD;AAEA,MAAM,CAAC,gBAAP,CAAwB,QAAxB,EAAkC,YAAM;AACpC;AACA,MAAI,EAAE,GAAG,MAAM,CAAC,WAAP,GAAqB,IAA9B;AACA,EAAA,QAAQ,CAAC,eAAT,CAAyB,KAAzB,CAA+B,WAA/B,CAA2C,MAA3C,YAAsD,EAAtD;AACH,CAJD","file":"jcore.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i el.width || ofi.img.naturalHeight > el.height) {\n\t\t\t\tel.style.backgroundSize = 'contain';\n\t\t\t} else {\n\t\t\t\tel.style.backgroundSize = 'auto';\n\t\t\t}\n\t\t});\n\t} else {\n\t\tel.style.backgroundSize = style['object-fit'].replace('none', 'auto').replace('fill', '100% 100%');\n\t}\n\n\tonImageReady(ofi.img, function (img) {\n\t\tsetPlaceholder(el, img.naturalWidth, img.naturalHeight);\n\t});\n}\n\nfunction keepSrcUsable(el) {\n\tvar descriptors = {\n\t\tget: function get(prop) {\n\t\t\treturn el[OFI].img[prop ? prop : 'src'];\n\t\t},\n\t\tset: function set(value, prop) {\n\t\t\tel[OFI].img[prop ? prop : 'src'] = value;\n\t\t\tnativeSetAttribute.call(el, (\"data-ofi-\" + prop), value); // preserve for any future cloneNode\n\t\t\tfixOne(el);\n\t\t\treturn value;\n\t\t}\n\t};\n\tObject.defineProperty(el, 'src', descriptors);\n\tObject.defineProperty(el, 'currentSrc', {\n\t\tget: function () { return descriptors.get('currentSrc'); }\n\t});\n\tObject.defineProperty(el, 'srcset', {\n\t\tget: function () { return descriptors.get('srcset'); },\n\t\tset: function (ss) { return descriptors.set(ss, 'srcset'); }\n\t});\n}\n\nfunction hijackAttributes() {\n\tfunction getOfiImageMaybe(el, name) {\n\t\treturn el[OFI] && el[OFI].img && (name === 'src' || name === 'srcset') ? el[OFI].img : el;\n\t}\n\tif (!supportsObjectPosition) {\n\t\tHTMLImageElement.prototype.getAttribute = function (name) {\n\t\t\treturn nativeGetAttribute.call(getOfiImageMaybe(this, name), name);\n\t\t};\n\n\t\tHTMLImageElement.prototype.setAttribute = function (name, value) {\n\t\t\treturn nativeSetAttribute.call(getOfiImageMaybe(this, name), name, String(value));\n\t\t};\n\t}\n}\n\nfunction fix(imgs, opts) {\n\tvar startAutoMode = !autoModeEnabled && !imgs;\n\topts = opts || {};\n\timgs = imgs || 'img';\n\n\tif ((supportsObjectPosition && !opts.skipTest) || !supportsOFI) {\n\t\treturn false;\n\t}\n\n\t// use imgs as a selector or just select all images\n\tif (imgs === 'img') {\n\t\timgs = document.getElementsByTagName('img');\n\t} else if (typeof imgs === 'string') {\n\t\timgs = document.querySelectorAll(imgs);\n\t} else if (!('length' in imgs)) {\n\t\timgs = [imgs];\n\t}\n\n\t// apply fix to all\n\tfor (var i = 0; i < imgs.length; i++) {\n\t\timgs[i][OFI] = imgs[i][OFI] || {\n\t\t\tskipTest: opts.skipTest\n\t\t};\n\t\tfixOne(imgs[i]);\n\t}\n\n\tif (startAutoMode) {\n\t\tdocument.body.addEventListener('load', function (e) {\n\t\t\tif (e.target.tagName === 'IMG') {\n\t\t\t\tfix(e.target, {\n\t\t\t\t\tskipTest: opts.skipTest\n\t\t\t\t});\n\t\t\t}\n\t\t}, true);\n\t\tautoModeEnabled = true;\n\t\timgs = 'img'; // reset to a generic selector for watchMQ\n\t}\n\n\t// if requested, watch media queries for object-fit change\n\tif (opts.watchMQ) {\n\t\twindow.addEventListener('resize', fix.bind(null, imgs, {\n\t\t\tskipTest: opts.skipTest\n\t\t}));\n\t}\n}\n\nfix.supportsObjectFit = supportsObjectFit;\nfix.supportsObjectPosition = supportsObjectPosition;\n\nhijackAttributes();\n\nmodule.exports = fix;\n","/*! picturefill - v3.0.2 - 2016-02-12\n * https://scottjehl.github.io/picturefill/\n * Copyright (c) 2016 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT\n */\n/*! Gecko-Picture - v1.0\n * https://github.com/scottjehl/picturefill/tree/3.0/src/plugins/gecko-picture\n * Firefox's early picture implementation (prior to FF41) is static and does\n * not react to viewport changes. This tiny module fixes this.\n */\n(function(window) {\n\t/*jshint eqnull:true */\n\tvar ua = navigator.userAgent;\n\n\tif ( window.HTMLPictureElement && ((/ecko/).test(ua) && ua.match(/rv\\:(\\d+)/) && RegExp.$1 < 45) ) {\n\t\taddEventListener(\"resize\", (function() {\n\t\t\tvar timer;\n\n\t\t\tvar dummySrc = document.createElement(\"source\");\n\n\t\t\tvar fixRespimg = function(img) {\n\t\t\t\tvar source, sizes;\n\t\t\t\tvar picture = img.parentNode;\n\n\t\t\t\tif (picture.nodeName.toUpperCase() === \"PICTURE\") {\n\t\t\t\t\tsource = dummySrc.cloneNode();\n\n\t\t\t\t\tpicture.insertBefore(source, picture.firstElementChild);\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tpicture.removeChild(source);\n\t\t\t\t\t});\n\t\t\t\t} else if (!img._pfLastSize || img.offsetWidth > img._pfLastSize) {\n\t\t\t\t\timg._pfLastSize = img.offsetWidth;\n\t\t\t\t\tsizes = img.sizes;\n\t\t\t\t\timg.sizes += \",100vw\";\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\timg.sizes = sizes;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvar findPictureImgs = function() {\n\t\t\t\tvar i;\n\t\t\t\tvar imgs = document.querySelectorAll(\"picture > img, img[srcset][sizes]\");\n\t\t\t\tfor (i = 0; i < imgs.length; i++) {\n\t\t\t\t\tfixRespimg(imgs[i]);\n\t\t\t\t}\n\t\t\t};\n\t\t\tvar onResize = function() {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = setTimeout(findPictureImgs, 99);\n\t\t\t};\n\t\t\tvar mq = window.matchMedia && matchMedia(\"(orientation: landscape)\");\n\t\t\tvar init = function() {\n\t\t\t\tonResize();\n\n\t\t\t\tif (mq && mq.addListener) {\n\t\t\t\t\tmq.addListener(onResize);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tdummySrc.srcset = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n\n\t\t\tif (/^[c|i]|d$/.test(document.readyState || \"\")) {\n\t\t\t\tinit();\n\t\t\t} else {\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", init);\n\t\t\t}\n\n\t\t\treturn onResize;\n\t\t})());\n\t}\n})(window);\n\n/*! Picturefill - v3.0.2\n * http://scottjehl.github.io/picturefill\n * Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt;\n * License: MIT\n */\n\n(function( window, document, undefined ) {\n\t// Enable strict mode\n\t\"use strict\";\n\n\t// HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround)\n\tdocument.createElement( \"picture\" );\n\n\tvar warn, eminpx, alwaysCheckWDescriptor, evalId;\n\t// local object for method references and testing exposure\n\tvar pf = {};\n\tvar isSupportTestReady = false;\n\tvar noop = function() {};\n\tvar image = document.createElement( \"img\" );\n\tvar getImgAttr = image.getAttribute;\n\tvar setImgAttr = image.setAttribute;\n\tvar removeImgAttr = image.removeAttribute;\n\tvar docElem = document.documentElement;\n\tvar types = {};\n\tvar cfg = {\n\t\t//resource selection:\n\t\talgorithm: \"\"\n\t};\n\tvar srcAttr = \"data-pfsrc\";\n\tvar srcsetAttr = srcAttr + \"set\";\n\t// ua sniffing is done for undetectable img loading features,\n\t// to do some non crucial perf optimizations\n\tvar ua = navigator.userAgent;\n\tvar supportAbort = (/rident/).test(ua) || ((/ecko/).test(ua) && ua.match(/rv\\:(\\d+)/) && RegExp.$1 > 35 );\n\tvar curSrcProp = \"currentSrc\";\n\tvar regWDesc = /\\s+\\+?\\d+(e\\d+)?w/;\n\tvar regSize = /(\\([^)]+\\))?\\s*(.+)/;\n\tvar setOptions = window.picturefillCFG;\n\t/**\n\t * Shortcut property for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests )\n\t */\n\t// baseStyle also used by getEmValue (i.e.: width: 1em is important)\n\tvar baseStyle = \"position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)\";\n\tvar fsCss = \"font-size:100%!important;\";\n\tvar isVwDirty = true;\n\n\tvar cssCache = {};\n\tvar sizeLengthCache = {};\n\tvar DPR = window.devicePixelRatio;\n\tvar units = {\n\t\tpx: 1,\n\t\t\"in\": 96\n\t};\n\tvar anchor = document.createElement( \"a\" );\n\t/**\n\t * alreadyRun flag used for setOptions. is it true setOptions will reevaluate\n\t * @type {boolean}\n\t */\n\tvar alreadyRun = false;\n\n\t// Reusable, non-\"g\" Regexes\n\n\t// (Don't use \\s, to avoid matching non-breaking space.)\n\tvar regexLeadingSpaces = /^[ \\t\\n\\r\\u000c]+/,\n\t regexLeadingCommasOrSpaces = /^[, \\t\\n\\r\\u000c]+/,\n\t regexLeadingNotSpaces = /^[^ \\t\\n\\r\\u000c]+/,\n\t regexTrailingCommas = /[,]+$/,\n\t regexNonNegativeInteger = /^\\d+$/,\n\n\t // ( Positive or negative or unsigned integers or decimals, without or without exponents.\n\t // Must include at least one digit.\n\t // According to spec tests any decimal point must be followed by a digit.\n\t // No leading plus sign is allowed.)\n\t // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number\n\t regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;\n\n\tvar on = function(obj, evt, fn, capture) {\n\t\tif ( obj.addEventListener ) {\n\t\t\tobj.addEventListener(evt, fn, capture || false);\n\t\t} else if ( obj.attachEvent ) {\n\t\t\tobj.attachEvent( \"on\" + evt, fn);\n\t\t}\n\t};\n\n\t/**\n\t * simple memoize function:\n\t */\n\n\tvar memoize = function(fn) {\n\t\tvar cache = {};\n\t\treturn function(input) {\n\t\t\tif ( !(input in cache) ) {\n\t\t\t\tcache[ input ] = fn(input);\n\t\t\t}\n\t\t\treturn cache[ input ];\n\t\t};\n\t};\n\n\t// UTILITY FUNCTIONS\n\n\t// Manual is faster than RegEx\n\t// http://jsperf.com/whitespace-character/5\n\tfunction isSpace(c) {\n\t\treturn (c === \"\\u0020\" || // space\n\t\t c === \"\\u0009\" || // horizontal tab\n\t\t c === \"\\u000A\" || // new line\n\t\t c === \"\\u000C\" || // form feed\n\t\t c === \"\\u000D\"); // carriage return\n\t}\n\n\t/**\n\t * gets a mediaquery and returns a boolean or gets a css length and returns a number\n\t * @param css mediaqueries or css length\n\t * @returns {boolean|number}\n\t *\n\t * based on: https://gist.github.com/jonathantneal/db4f77009b155f083738\n\t */\n\tvar evalCSS = (function() {\n\n\t\tvar regLength = /^([\\d\\.]+)(em|vw|px)$/;\n\t\tvar replace = function() {\n\t\t\tvar args = arguments, index = 0, string = args[0];\n\t\t\twhile (++index in args) {\n\t\t\t\tstring = string.replace(args[index], args[++index]);\n\t\t\t}\n\t\t\treturn string;\n\t\t};\n\n\t\tvar buildStr = memoize(function(css) {\n\n\t\t\treturn \"return \" + replace((css || \"\").toLowerCase(),\n\t\t\t\t// interpret `and`\n\t\t\t\t/\\band\\b/g, \"&&\",\n\n\t\t\t\t// interpret `,`\n\t\t\t\t/,/g, \"||\",\n\n\t\t\t\t// interpret `min-` as >=\n\t\t\t\t/min-([a-z-\\s]+):/g, \"e.$1>=\",\n\n\t\t\t\t// interpret `max-` as <=\n\t\t\t\t/max-([a-z-\\s]+):/g, \"e.$1<=\",\n\n\t\t\t\t//calc value\n\t\t\t\t/calc([^)]+)/g, \"($1)\",\n\n\t\t\t\t// interpret css values\n\t\t\t\t/(\\d+[\\.]*[\\d]*)([a-z]+)/g, \"($1 * e.$2)\",\n\t\t\t\t//make eval less evil\n\t\t\t\t/^(?!(e.[a-z]|[0-9\\.&=|><\\+\\-\\*\\(\\)\\/])).*/ig, \"\"\n\t\t\t) + \";\";\n\t\t});\n\n\t\treturn function(css, length) {\n\t\t\tvar parsedLength;\n\t\t\tif (!(css in cssCache)) {\n\t\t\t\tcssCache[css] = false;\n\t\t\t\tif (length && (parsedLength = css.match( regLength ))) {\n\t\t\t\t\tcssCache[css] = parsedLength[ 1 ] * units[parsedLength[ 2 ]];\n\t\t\t\t} else {\n\t\t\t\t\t/*jshint evil:true */\n\t\t\t\t\ttry{\n\t\t\t\t\t\tcssCache[css] = new Function(\"e\", buildStr(css))(units);\n\t\t\t\t\t} catch(e) {}\n\t\t\t\t\t/*jshint evil:false */\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cssCache[css];\n\t\t};\n\t})();\n\n\tvar setResolution = function( candidate, sizesattr ) {\n\t\tif ( candidate.w ) { // h = means height: || descriptor.type === 'h' do not handle yet...\n\t\t\tcandidate.cWidth = pf.calcListLength( sizesattr || \"100vw\" );\n\t\t\tcandidate.res = candidate.w / candidate.cWidth ;\n\t\t} else {\n\t\t\tcandidate.res = candidate.d;\n\t\t}\n\t\treturn candidate;\n\t};\n\n\t/**\n\t *\n\t * @param opt\n\t */\n\tvar picturefill = function( opt ) {\n\n\t\tif (!isSupportTestReady) {return;}\n\n\t\tvar elements, i, plen;\n\n\t\tvar options = opt || {};\n\n\t\tif ( options.elements && options.elements.nodeType === 1 ) {\n\t\t\tif ( options.elements.nodeName.toUpperCase() === \"IMG\" ) {\n\t\t\t\toptions.elements = [ options.elements ];\n\t\t\t} else {\n\t\t\t\toptions.context = options.elements;\n\t\t\t\toptions.elements = null;\n\t\t\t}\n\t\t}\n\n\t\telements = options.elements || pf.qsa( (options.context || document), ( options.reevaluate || options.reselect ) ? pf.sel : pf.selShort );\n\n\t\tif ( (plen = elements.length) ) {\n\n\t\t\tpf.setupRun( options );\n\t\t\talreadyRun = true;\n\n\t\t\t// Loop through all elements\n\t\t\tfor ( i = 0; i < plen; i++ ) {\n\t\t\t\tpf.fillImg(elements[ i ], options);\n\t\t\t}\n\n\t\t\tpf.teardownRun( options );\n\t\t}\n\t};\n\n\t/**\n\t * outputs a warning for the developer\n\t * @param {message}\n\t * @type {Function}\n\t */\n\twarn = ( window.console && console.warn ) ?\n\t\tfunction( message ) {\n\t\t\tconsole.warn( message );\n\t\t} :\n\t\tnoop\n\t;\n\n\tif ( !(curSrcProp in image) ) {\n\t\tcurSrcProp = \"src\";\n\t}\n\n\t// Add support for standard mime types.\n\ttypes[ \"image/jpeg\" ] = true;\n\ttypes[ \"image/gif\" ] = true;\n\ttypes[ \"image/png\" ] = true;\n\n\tfunction detectTypeSupport( type, typeUri ) {\n\t\t// based on Modernizr's lossless img-webp test\n\t\t// note: asynchronous\n\t\tvar image = new window.Image();\n\t\timage.onerror = function() {\n\t\t\ttypes[ type ] = false;\n\t\t\tpicturefill();\n\t\t};\n\t\timage.onload = function() {\n\t\t\ttypes[ type ] = image.width === 1;\n\t\t\tpicturefill();\n\t\t};\n\t\timage.src = typeUri;\n\t\treturn \"pending\";\n\t}\n\n\t// test svg support\n\ttypes[ \"image/svg+xml\" ] = document.implementation.hasFeature( \"http://www.w3.org/TR/SVG11/feature#Image\", \"1.1\" );\n\n\t/**\n\t * updates the internal vW property with the current viewport width in px\n\t */\n\tfunction updateMetrics() {\n\n\t\tisVwDirty = false;\n\t\tDPR = window.devicePixelRatio;\n\t\tcssCache = {};\n\t\tsizeLengthCache = {};\n\n\t\tpf.DPR = DPR || 1;\n\n\t\tunits.width = Math.max(window.innerWidth || 0, docElem.clientWidth);\n\t\tunits.height = Math.max(window.innerHeight || 0, docElem.clientHeight);\n\n\t\tunits.vw = units.width / 100;\n\t\tunits.vh = units.height / 100;\n\n\t\tevalId = [ units.height, units.width, DPR ].join(\"-\");\n\n\t\tunits.em = pf.getEmValue();\n\t\tunits.rem = units.em;\n\t}\n\n\tfunction chooseLowRes( lowerValue, higherValue, dprValue, isCached ) {\n\t\tvar bonusFactor, tooMuch, bonus, meanDensity;\n\n\t\t//experimental\n\t\tif (cfg.algorithm === \"saveData\" ){\n\t\t\tif ( lowerValue > 2.7 ) {\n\t\t\t\tmeanDensity = dprValue + 1;\n\t\t\t} else {\n\t\t\t\ttooMuch = higherValue - dprValue;\n\t\t\t\tbonusFactor = Math.pow(lowerValue - 0.6, 1.5);\n\n\t\t\t\tbonus = tooMuch * bonusFactor;\n\n\t\t\t\tif (isCached) {\n\t\t\t\t\tbonus += 0.1 * bonusFactor;\n\t\t\t\t}\n\n\t\t\t\tmeanDensity = lowerValue + bonus;\n\t\t\t}\n\t\t} else {\n\t\t\tmeanDensity = (dprValue > 1) ?\n\t\t\t\tMath.sqrt(lowerValue * higherValue) :\n\t\t\t\tlowerValue;\n\t\t}\n\n\t\treturn meanDensity > dprValue;\n\t}\n\n\tfunction applyBestCandidate( img ) {\n\t\tvar srcSetCandidates;\n\t\tvar matchingSet = pf.getSet( img );\n\t\tvar evaluated = false;\n\t\tif ( matchingSet !== \"pending\" ) {\n\t\t\tevaluated = evalId;\n\t\t\tif ( matchingSet ) {\n\t\t\t\tsrcSetCandidates = pf.setRes( matchingSet );\n\t\t\t\tpf.applySetCandidate( srcSetCandidates, img );\n\t\t\t}\n\t\t}\n\t\timg[ pf.ns ].evaled = evaluated;\n\t}\n\n\tfunction ascendingSort( a, b ) {\n\t\treturn a.res - b.res;\n\t}\n\n\tfunction setSrcToCur( img, src, set ) {\n\t\tvar candidate;\n\t\tif ( !set && src ) {\n\t\t\tset = img[ pf.ns ].sets;\n\t\t\tset = set && set[set.length - 1];\n\t\t}\n\n\t\tcandidate = getCandidateForSrc(src, set);\n\n\t\tif ( candidate ) {\n\t\t\tsrc = pf.makeUrl(src);\n\t\t\timg[ pf.ns ].curSrc = src;\n\t\t\timg[ pf.ns ].curCan = candidate;\n\n\t\t\tif ( !candidate.res ) {\n\t\t\t\tsetResolution( candidate, candidate.set.sizes );\n\t\t\t}\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tfunction getCandidateForSrc( src, set ) {\n\t\tvar i, candidate, candidates;\n\t\tif ( src && set ) {\n\t\t\tcandidates = pf.parseSet( set );\n\t\t\tsrc = pf.makeUrl(src);\n\t\t\tfor ( i = 0; i < candidates.length; i++ ) {\n\t\t\t\tif ( src === pf.makeUrl(candidates[ i ].url) ) {\n\t\t\t\t\tcandidate = candidates[ i ];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tfunction getAllSourceElements( picture, candidates ) {\n\t\tvar i, len, source, srcset;\n\n\t\t// SPEC mismatch intended for size and perf:\n\t\t// actually only source elements preceding the img should be used\n\t\t// also note: don't use qsa here, because IE8 sometimes doesn't like source as the key part in a selector\n\t\tvar sources = picture.getElementsByTagName( \"source\" );\n\n\t\tfor ( i = 0, len = sources.length; i < len; i++ ) {\n\t\t\tsource = sources[ i ];\n\t\t\tsource[ pf.ns ] = true;\n\t\t\tsrcset = source.getAttribute( \"srcset\" );\n\n\t\t\t// if source does not have a srcset attribute, skip\n\t\t\tif ( srcset ) {\n\t\t\t\tcandidates.push( {\n\t\t\t\t\tsrcset: srcset,\n\t\t\t\t\tmedia: source.getAttribute( \"media\" ),\n\t\t\t\t\ttype: source.getAttribute( \"type\" ),\n\t\t\t\t\tsizes: source.getAttribute( \"sizes\" )\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Srcset Parser\n\t * By Alex Bell | MIT License\n\t *\n\t * @returns Array [{url: _, d: _, w: _, h:_, set:_(????)}, ...]\n\t *\n\t * Based super duper closely on the reference algorithm at:\n\t * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute\n\t */\n\n\t// 1. Let input be the value passed to this algorithm.\n\t// (TO-DO : Explain what \"set\" argument is here. Maybe choose a more\n\t// descriptive & more searchable name. Since passing the \"set\" in really has\n\t// nothing to do with parsing proper, I would prefer this assignment eventually\n\t// go in an external fn.)\n\tfunction parseSrcset(input, set) {\n\n\t\tfunction collectCharacters(regEx) {\n\t\t\tvar chars,\n\t\t\t match = regEx.exec(input.substring(pos));\n\t\t\tif (match) {\n\t\t\t\tchars = match[ 0 ];\n\t\t\t\tpos += chars.length;\n\t\t\t\treturn chars;\n\t\t\t}\n\t\t}\n\n\t\tvar inputLength = input.length,\n\t\t url,\n\t\t descriptors,\n\t\t currentDescriptor,\n\t\t state,\n\t\t c,\n\n\t\t // 2. Let position be a pointer into input, initially pointing at the start\n\t\t // of the string.\n\t\t pos = 0,\n\n\t\t // 3. Let candidates be an initially empty source set.\n\t\t candidates = [];\n\n\t\t/**\n\t\t* Adds descriptor properties to a candidate, pushes to the candidates array\n\t\t* @return undefined\n\t\t*/\n\t\t// (Declared outside of the while loop so that it's only created once.\n\t\t// (This fn is defined before it is used, in order to pass JSHINT.\n\t\t// Unfortunately this breaks the sequencing of the spec comments. :/ )\n\t\tfunction parseDescriptors() {\n\n\t\t\t// 9. Descriptor parser: Let error be no.\n\t\t\tvar pError = false,\n\n\t\t\t// 10. Let width be absent.\n\t\t\t// 11. Let density be absent.\n\t\t\t// 12. Let future-compat-h be absent. (We're implementing it now as h)\n\t\t\t w, d, h, i,\n\t\t\t candidate = {},\n\t\t\t desc, lastChar, value, intVal, floatVal;\n\n\t\t\t// 13. For each descriptor in descriptors, run the appropriate set of steps\n\t\t\t// from the following list:\n\t\t\tfor (i = 0 ; i < descriptors.length; i++) {\n\t\t\t\tdesc = descriptors[ i ];\n\n\t\t\t\tlastChar = desc[ desc.length - 1 ];\n\t\t\t\tvalue = desc.substring(0, desc.length - 1);\n\t\t\t\tintVal = parseInt(value, 10);\n\t\t\t\tfloatVal = parseFloat(value);\n\n\t\t\t\t// If the descriptor consists of a valid non-negative integer followed by\n\t\t\t\t// a U+0077 LATIN SMALL LETTER W character\n\t\t\t\tif (regexNonNegativeInteger.test(value) && (lastChar === \"w\")) {\n\n\t\t\t\t\t// If width and density are not both absent, then let error be yes.\n\t\t\t\t\tif (w || d) {pError = true;}\n\n\t\t\t\t\t// Apply the rules for parsing non-negative integers to the descriptor.\n\t\t\t\t\t// If the result is zero, let error be yes.\n\t\t\t\t\t// Otherwise, let width be the result.\n\t\t\t\t\tif (intVal === 0) {pError = true;} else {w = intVal;}\n\n\t\t\t\t// If the descriptor consists of a valid floating-point number followed by\n\t\t\t\t// a U+0078 LATIN SMALL LETTER X character\n\t\t\t\t} else if (regexFloatingPoint.test(value) && (lastChar === \"x\")) {\n\n\t\t\t\t\t// If width, density and future-compat-h are not all absent, then let error\n\t\t\t\t\t// be yes.\n\t\t\t\t\tif (w || d || h) {pError = true;}\n\n\t\t\t\t\t// Apply the rules for parsing floating-point number values to the descriptor.\n\t\t\t\t\t// If the result is less than zero, let error be yes. Otherwise, let density\n\t\t\t\t\t// be the result.\n\t\t\t\t\tif (floatVal < 0) {pError = true;} else {d = floatVal;}\n\n\t\t\t\t// If the descriptor consists of a valid non-negative integer followed by\n\t\t\t\t// a U+0068 LATIN SMALL LETTER H character\n\t\t\t\t} else if (regexNonNegativeInteger.test(value) && (lastChar === \"h\")) {\n\n\t\t\t\t\t// If height and density are not both absent, then let error be yes.\n\t\t\t\t\tif (h || d) {pError = true;}\n\n\t\t\t\t\t// Apply the rules for parsing non-negative integers to the descriptor.\n\t\t\t\t\t// If the result is zero, let error be yes. Otherwise, let future-compat-h\n\t\t\t\t\t// be the result.\n\t\t\t\t\tif (intVal === 0) {pError = true;} else {h = intVal;}\n\n\t\t\t\t// Anything else, Let error be yes.\n\t\t\t\t} else {pError = true;}\n\t\t\t} // (close step 13 for loop)\n\n\t\t\t// 15. If error is still no, then append a new image source to candidates whose\n\t\t\t// URL is url, associated with a width width if not absent and a pixel\n\t\t\t// density density if not absent. Otherwise, there is a parse error.\n\t\t\tif (!pError) {\n\t\t\t\tcandidate.url = url;\n\n\t\t\t\tif (w) { candidate.w = w;}\n\t\t\t\tif (d) { candidate.d = d;}\n\t\t\t\tif (h) { candidate.h = h;}\n\t\t\t\tif (!h && !d && !w) {candidate.d = 1;}\n\t\t\t\tif (candidate.d === 1) {set.has1x = true;}\n\t\t\t\tcandidate.set = set;\n\n\t\t\t\tcandidates.push(candidate);\n\t\t\t}\n\t\t} // (close parseDescriptors fn)\n\n\t\t/**\n\t\t* Tokenizes descriptor properties prior to parsing\n\t\t* Returns undefined.\n\t\t* (Again, this fn is defined before it is used, in order to pass JSHINT.\n\t\t* Unfortunately this breaks the logical sequencing of the spec comments. :/ )\n\t\t*/\n\t\tfunction tokenize() {\n\n\t\t\t// 8.1. Descriptor tokeniser: Skip whitespace\n\t\t\tcollectCharacters(regexLeadingSpaces);\n\n\t\t\t// 8.2. Let current descriptor be the empty string.\n\t\t\tcurrentDescriptor = \"\";\n\n\t\t\t// 8.3. Let state be in descriptor.\n\t\t\tstate = \"in descriptor\";\n\n\t\t\twhile (true) {\n\n\t\t\t\t// 8.4. Let c be the character at position.\n\t\t\t\tc = input.charAt(pos);\n\n\t\t\t\t// Do the following depending on the value of state.\n\t\t\t\t// For the purpose of this step, \"EOF\" is a special character representing\n\t\t\t\t// that position is past the end of input.\n\n\t\t\t\t// In descriptor\n\t\t\t\tif (state === \"in descriptor\") {\n\t\t\t\t\t// Do the following, depending on the value of c:\n\n\t\t\t\t // Space character\n\t\t\t\t // If current descriptor is not empty, append current descriptor to\n\t\t\t\t // descriptors and let current descriptor be the empty string.\n\t\t\t\t // Set state to after descriptor.\n\t\t\t\t\tif (isSpace(c)) {\n\t\t\t\t\t\tif (currentDescriptor) {\n\t\t\t\t\t\t\tdescriptors.push(currentDescriptor);\n\t\t\t\t\t\t\tcurrentDescriptor = \"\";\n\t\t\t\t\t\t\tstate = \"after descriptor\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// U+002C COMMA (,)\n\t\t\t\t\t// Advance position to the next character in input. If current descriptor\n\t\t\t\t\t// is not empty, append current descriptor to descriptors. Jump to the step\n\t\t\t\t\t// labeled descriptor parser.\n\t\t\t\t\t} else if (c === \",\") {\n\t\t\t\t\t\tpos += 1;\n\t\t\t\t\t\tif (currentDescriptor) {\n\t\t\t\t\t\t\tdescriptors.push(currentDescriptor);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparseDescriptors();\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t// U+0028 LEFT PARENTHESIS (()\n\t\t\t\t\t// Append c to current descriptor. Set state to in parens.\n\t\t\t\t\t} else if (c === \"\\u0028\") {\n\t\t\t\t\t\tcurrentDescriptor = currentDescriptor + c;\n\t\t\t\t\t\tstate = \"in parens\";\n\n\t\t\t\t\t// EOF\n\t\t\t\t\t// If current descriptor is not empty, append current descriptor to\n\t\t\t\t\t// descriptors. Jump to the step labeled descriptor parser.\n\t\t\t\t\t} else if (c === \"\") {\n\t\t\t\t\t\tif (currentDescriptor) {\n\t\t\t\t\t\t\tdescriptors.push(currentDescriptor);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparseDescriptors();\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t// Anything else\n\t\t\t\t\t// Append c to current descriptor.\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrentDescriptor = currentDescriptor + c;\n\t\t\t\t\t}\n\t\t\t\t// (end \"in descriptor\"\n\n\t\t\t\t// In parens\n\t\t\t\t} else if (state === \"in parens\") {\n\n\t\t\t\t\t// U+0029 RIGHT PARENTHESIS ())\n\t\t\t\t\t// Append c to current descriptor. Set state to in descriptor.\n\t\t\t\t\tif (c === \")\") {\n\t\t\t\t\t\tcurrentDescriptor = currentDescriptor + c;\n\t\t\t\t\t\tstate = \"in descriptor\";\n\n\t\t\t\t\t// EOF\n\t\t\t\t\t// Append current descriptor to descriptors. Jump to the step labeled\n\t\t\t\t\t// descriptor parser.\n\t\t\t\t\t} else if (c === \"\") {\n\t\t\t\t\t\tdescriptors.push(currentDescriptor);\n\t\t\t\t\t\tparseDescriptors();\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t// Anything else\n\t\t\t\t\t// Append c to current descriptor.\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrentDescriptor = currentDescriptor + c;\n\t\t\t\t\t}\n\n\t\t\t\t// After descriptor\n\t\t\t\t} else if (state === \"after descriptor\") {\n\n\t\t\t\t\t// Do the following, depending on the value of c:\n\t\t\t\t\t// Space character: Stay in this state.\n\t\t\t\t\tif (isSpace(c)) {\n\n\t\t\t\t\t// EOF: Jump to the step labeled descriptor parser.\n\t\t\t\t\t} else if (c === \"\") {\n\t\t\t\t\t\tparseDescriptors();\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t// Anything else\n\t\t\t\t\t// Set state to in descriptor. Set position to the previous character in input.\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate = \"in descriptor\";\n\t\t\t\t\t\tpos -= 1;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Advance position to the next character in input.\n\t\t\t\tpos += 1;\n\n\t\t\t// Repeat this step.\n\t\t\t} // (close while true loop)\n\t\t}\n\n\t\t// 4. Splitting loop: Collect a sequence of characters that are space\n\t\t// characters or U+002C COMMA characters. If any U+002C COMMA characters\n\t\t// were collected, that is a parse error.\n\t\twhile (true) {\n\t\t\tcollectCharacters(regexLeadingCommasOrSpaces);\n\n\t\t\t// 5. If position is past the end of input, return candidates and abort these steps.\n\t\t\tif (pos >= inputLength) {\n\t\t\t\treturn candidates; // (we're done, this is the sole return path)\n\t\t\t}\n\n\t\t\t// 6. Collect a sequence of characters that are not space characters,\n\t\t\t// and let that be url.\n\t\t\turl = collectCharacters(regexLeadingNotSpaces);\n\n\t\t\t// 7. Let descriptors be a new empty list.\n\t\t\tdescriptors = [];\n\n\t\t\t// 8. If url ends with a U+002C COMMA character (,), follow these substeps:\n\t\t\t//\t\t(1). Remove all trailing U+002C COMMA characters from url. If this removed\n\t\t\t// more than one character, that is a parse error.\n\t\t\tif (url.slice(-1) === \",\") {\n\t\t\t\turl = url.replace(regexTrailingCommas, \"\");\n\t\t\t\t// (Jump ahead to step 9 to skip tokenization and just push the candidate).\n\t\t\t\tparseDescriptors();\n\n\t\t\t//\tOtherwise, follow these substeps:\n\t\t\t} else {\n\t\t\t\ttokenize();\n\t\t\t} // (close else of step 8)\n\n\t\t// 16. Return to the step labeled splitting loop.\n\t\t} // (Close of big while loop.)\n\t}\n\n\t/*\n\t * Sizes Parser\n\t *\n\t * By Alex Bell | MIT License\n\t *\n\t * Non-strict but accurate and lightweight JS Parser for the string value \n\t *\n\t * Reference algorithm at:\n\t * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-sizes-attribute\n\t *\n\t * Most comments are copied in directly from the spec\n\t * (except for comments in parens).\n\t *\n\t * Grammar is:\n\t * = # [ , ]? | \n\t * = \n\t * = \n\t * http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-sizes\n\t *\n\t * E.g. \"(max-width: 30em) 100vw, (max-width: 50em) 70vw, 100vw\"\n\t * or \"(min-width: 30em), calc(30vw - 15px)\" or just \"30vw\"\n\t *\n\t * Returns the first valid with a media condition that evaluates to true,\n\t * or \"100vw\" if all valid media conditions evaluate to false.\n\t *\n\t */\n\n\tfunction parseSizes(strValue) {\n\n\t\t// (Percentage CSS lengths are not allowed in this case, to avoid confusion:\n\t\t// https://html.spec.whatwg.org/multipage/embedded-content.html#valid-source-size-list\n\t\t// CSS allows a single optional plus or minus sign:\n\t\t// http://www.w3.org/TR/CSS2/syndata.html#numbers\n\t\t// CSS is ASCII case-insensitive:\n\t\t// http://www.w3.org/TR/CSS2/syndata.html#characters )\n\t\t// Spec allows exponential notation for type:\n\t\t// http://dev.w3.org/csswg/css-values/#numbers\n\t\tvar regexCssLengthWithUnits = /^(?:[+-]?[0-9]+|[0-9]*\\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i;\n\n\t\t// (This is a quick and lenient test. Because of optional unlimited-depth internal\n\t\t// grouping parens and strict spacing rules, this could get very complicated.)\n\t\tvar regexCssCalc = /^calc\\((?:[0-9a-z \\.\\+\\-\\*\\/\\(\\)]+)\\)$/i;\n\n\t\tvar i;\n\t\tvar unparsedSizesList;\n\t\tvar unparsedSizesListLength;\n\t\tvar unparsedSize;\n\t\tvar lastComponentValue;\n\t\tvar size;\n\n\t\t// UTILITY FUNCTIONS\n\n\t\t// (Toy CSS parser. The goals here are:\n\t\t// 1) expansive test coverage without the weight of a full CSS parser.\n\t\t// 2) Avoiding regex wherever convenient.\n\t\t// Quick tests: http://jsfiddle.net/gtntL4gr/3/\n\t\t// Returns an array of arrays.)\n\t\tfunction parseComponentValues(str) {\n\t\t\tvar chrctr;\n\t\t\tvar component = \"\";\n\t\t\tvar componentArray = [];\n\t\t\tvar listArray = [];\n\t\t\tvar parenDepth = 0;\n\t\t\tvar pos = 0;\n\t\t\tvar inComment = false;\n\n\t\t\tfunction pushComponent() {\n\t\t\t\tif (component) {\n\t\t\t\t\tcomponentArray.push(component);\n\t\t\t\t\tcomponent = \"\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction pushComponentArray() {\n\t\t\t\tif (componentArray[0]) {\n\t\t\t\t\tlistArray.push(componentArray);\n\t\t\t\t\tcomponentArray = [];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// (Loop forwards from the beginning of the string.)\n\t\t\twhile (true) {\n\t\t\t\tchrctr = str.charAt(pos);\n\n\t\t\t\tif (chrctr === \"\") { // ( End of string reached.)\n\t\t\t\t\tpushComponent();\n\t\t\t\t\tpushComponentArray();\n\t\t\t\t\treturn listArray;\n\t\t\t\t} else if (inComment) {\n\t\t\t\t\tif ((chrctr === \"*\") && (str[pos + 1] === \"/\")) { // (At end of a comment.)\n\t\t\t\t\t\tinComment = false;\n\t\t\t\t\t\tpos += 2;\n\t\t\t\t\t\tpushComponent();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpos += 1; // (Skip all characters inside comments.)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else if (isSpace(chrctr)) {\n\t\t\t\t\t// (If previous character in loop was also a space, or if\n\t\t\t\t\t// at the beginning of the string, do not add space char to\n\t\t\t\t\t// component.)\n\t\t\t\t\tif ( (str.charAt(pos - 1) && isSpace( str.charAt(pos - 1) ) ) || !component ) {\n\t\t\t\t\t\tpos += 1;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (parenDepth === 0) {\n\t\t\t\t\t\tpushComponent();\n\t\t\t\t\t\tpos +=1;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// (Replace any space character with a plain space for legibility.)\n\t\t\t\t\t\tchrctr = \" \";\n\t\t\t\t\t}\n\t\t\t\t} else if (chrctr === \"(\") {\n\t\t\t\t\tparenDepth += 1;\n\t\t\t\t} else if (chrctr === \")\") {\n\t\t\t\t\tparenDepth -= 1;\n\t\t\t\t} else if (chrctr === \",\") {\n\t\t\t\t\tpushComponent();\n\t\t\t\t\tpushComponentArray();\n\t\t\t\t\tpos += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if ( (chrctr === \"/\") && (str.charAt(pos + 1) === \"*\") ) {\n\t\t\t\t\tinComment = true;\n\t\t\t\t\tpos += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcomponent = component + chrctr;\n\t\t\t\tpos += 1;\n\t\t\t}\n\t\t}\n\n\t\tfunction isValidNonNegativeSourceSizeValue(s) {\n\t\t\tif (regexCssLengthWithUnits.test(s) && (parseFloat(s) >= 0)) {return true;}\n\t\t\tif (regexCssCalc.test(s)) {return true;}\n\t\t\t// ( http://www.w3.org/TR/CSS2/syndata.html#numbers says:\n\t\t\t// \"-0 is equivalent to 0 and is not a negative number.\" which means that\n\t\t\t// unitless zero and unitless negative zero must be accepted as special cases.)\n\t\t\tif ((s === \"0\") || (s === \"-0\") || (s === \"+0\")) {return true;}\n\t\t\treturn false;\n\t\t}\n\n\t\t// When asked to parse a sizes attribute from an element, parse a\n\t\t// comma-separated list of component values from the value of the element's\n\t\t// sizes attribute (or the empty string, if the attribute is absent), and let\n\t\t// unparsed sizes list be the result.\n\t\t// http://dev.w3.org/csswg/css-syntax/#parse-comma-separated-list-of-component-values\n\n\t\tunparsedSizesList = parseComponentValues(strValue);\n\t\tunparsedSizesListLength = unparsedSizesList.length;\n\n\t\t// For each unparsed size in unparsed sizes list:\n\t\tfor (i = 0; i < unparsedSizesListLength; i++) {\n\t\t\tunparsedSize = unparsedSizesList[i];\n\n\t\t\t// 1. Remove all consecutive s from the end of unparsed size.\n\t\t\t// ( parseComponentValues() already omits spaces outside of parens. )\n\n\t\t\t// If unparsed size is now empty, that is a parse error; continue to the next\n\t\t\t// iteration of this algorithm.\n\t\t\t// ( parseComponentValues() won't push an empty array. )\n\n\t\t\t// 2. If the last component value in unparsed size is a valid non-negative\n\t\t\t// , let size be its value and remove the component value\n\t\t\t// from unparsed size. Any CSS function other than the calc() function is\n\t\t\t// invalid. Otherwise, there is a parse error; continue to the next iteration\n\t\t\t// of this algorithm.\n\t\t\t// http://dev.w3.org/csswg/css-syntax/#parse-component-value\n\t\t\tlastComponentValue = unparsedSize[unparsedSize.length - 1];\n\n\t\t\tif (isValidNonNegativeSourceSizeValue(lastComponentValue)) {\n\t\t\t\tsize = lastComponentValue;\n\t\t\t\tunparsedSize.pop();\n\t\t\t} else {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 3. Remove all consecutive s from the end of unparsed\n\t\t\t// size. If unparsed size is now empty, return size and exit this algorithm.\n\t\t\t// If this was not the last item in unparsed sizes list, that is a parse error.\n\t\t\tif (unparsedSize.length === 0) {\n\t\t\t\treturn size;\n\t\t\t}\n\n\t\t\t// 4. Parse the remaining component values in unparsed size as a\n\t\t\t// . If it does not parse correctly, or it does parse\n\t\t\t// correctly but the evaluates to false, continue to the\n\t\t\t// next iteration of this algorithm.\n\t\t\t// (Parsing all possible compound media conditions in JS is heavy, complicated,\n\t\t\t// and the payoff is unclear. Is there ever an situation where the\n\t\t\t// media condition parses incorrectly but still somehow evaluates to true?\n\t\t\t// Can we just rely on the browser/polyfill to do it?)\n\t\t\tunparsedSize = unparsedSize.join(\" \");\n\t\t\tif (!(pf.matchesMedia( unparsedSize ) ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// 5. Return size and exit this algorithm.\n\t\t\treturn size;\n\t\t}\n\n\t\t// If the above algorithm exhausts unparsed sizes list without returning a\n\t\t// size value, return 100vw.\n\t\treturn \"100vw\";\n\t}\n\n\t// namespace\n\tpf.ns = (\"pf\" + new Date().getTime()).substr(0, 9);\n\n\t// srcset support test\n\tpf.supSrcset = \"srcset\" in image;\n\tpf.supSizes = \"sizes\" in image;\n\tpf.supPicture = !!window.HTMLPictureElement;\n\n\t// UC browser does claim to support srcset and picture, but not sizes,\n\t// this extended test reveals the browser does support nothing\n\tif (pf.supSrcset && pf.supPicture && !pf.supSizes) {\n\t\t(function(image2) {\n\t\t\timage.srcset = \"data:,a\";\n\t\t\timage2.src = \"data:,a\";\n\t\t\tpf.supSrcset = image.complete === image2.complete;\n\t\t\tpf.supPicture = pf.supSrcset && pf.supPicture;\n\t\t})(document.createElement(\"img\"));\n\t}\n\n\t// Safari9 has basic support for sizes, but does't expose the `sizes` idl attribute\n\tif (pf.supSrcset && !pf.supSizes) {\n\n\t\t(function() {\n\t\t\tvar width2 = \"data:image/gif;base64,R0lGODlhAgABAPAAAP///wAAACH5BAAAAAAALAAAAAACAAEAAAICBAoAOw==\";\n\t\t\tvar width1 = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n\t\t\tvar img = document.createElement(\"img\");\n\t\t\tvar test = function() {\n\t\t\t\tvar width = img.width;\n\n\t\t\t\tif (width === 2) {\n\t\t\t\t\tpf.supSizes = true;\n\t\t\t\t}\n\n\t\t\t\talwaysCheckWDescriptor = pf.supSrcset && !pf.supSizes;\n\n\t\t\t\tisSupportTestReady = true;\n\t\t\t\t// force async\n\t\t\t\tsetTimeout(picturefill);\n\t\t\t};\n\n\t\t\timg.onload = test;\n\t\t\timg.onerror = test;\n\t\t\timg.setAttribute(\"sizes\", \"9px\");\n\n\t\t\timg.srcset = width1 + \" 1w,\" + width2 + \" 9w\";\n\t\t\timg.src = width1;\n\t\t})();\n\n\t} else {\n\t\tisSupportTestReady = true;\n\t}\n\n\t// using pf.qsa instead of dom traversing does scale much better,\n\t// especially on sites mixing responsive and non-responsive images\n\tpf.selShort = \"picture>img,img[srcset]\";\n\tpf.sel = pf.selShort;\n\tpf.cfg = cfg;\n\n\t/**\n\t * Shortcut property for `devicePixelRatio` ( for easy overriding in tests )\n\t */\n\tpf.DPR = (DPR || 1 );\n\tpf.u = units;\n\n\t// container of supported mime types that one might need to qualify before using\n\tpf.types = types;\n\n\tpf.setSize = noop;\n\n\t/**\n\t * Gets a string and returns the absolute URL\n\t * @param src\n\t * @returns {String} absolute URL\n\t */\n\n\tpf.makeUrl = memoize(function(src) {\n\t\tanchor.href = src;\n\t\treturn anchor.href;\n\t});\n\n\t/**\n\t * Gets a DOM element or document and a selctor and returns the found matches\n\t * Can be extended with jQuery/Sizzle for IE7 support\n\t * @param context\n\t * @param sel\n\t * @returns {NodeList|Array}\n\t */\n\tpf.qsa = function(context, sel) {\n\t\treturn ( \"querySelector\" in context ) ? context.querySelectorAll(sel) : [];\n\t};\n\n\t/**\n\t * Shortcut method for matchMedia ( for easy overriding in tests )\n\t * wether native or pf.mMQ is used will be decided lazy on first call\n\t * @returns {boolean}\n\t */\n\tpf.matchesMedia = function() {\n\t\tif ( window.matchMedia && (matchMedia( \"(min-width: 0.1em)\" ) || {}).matches ) {\n\t\t\tpf.matchesMedia = function( media ) {\n\t\t\t\treturn !media || ( matchMedia( media ).matches );\n\t\t\t};\n\t\t} else {\n\t\t\tpf.matchesMedia = pf.mMQ;\n\t\t}\n\n\t\treturn pf.matchesMedia.apply( this, arguments );\n\t};\n\n\t/**\n\t * A simplified matchMedia implementation for IE8 and IE9\n\t * handles only min-width/max-width with px or em values\n\t * @param media\n\t * @returns {boolean}\n\t */\n\tpf.mMQ = function( media ) {\n\t\treturn media ? evalCSS(media) : true;\n\t};\n\n\t/**\n\t * Returns the calculated length in css pixel from the given sourceSizeValue\n\t * http://dev.w3.org/csswg/css-values-3/#length-value\n\t * intended Spec mismatches:\n\t * * Does not check for invalid use of CSS functions\n\t * * Does handle a computed length of 0 the same as a negative and therefore invalid value\n\t * @param sourceSizeValue\n\t * @returns {Number}\n\t */\n\tpf.calcLength = function( sourceSizeValue ) {\n\n\t\tvar value = evalCSS(sourceSizeValue, true) || false;\n\t\tif (value < 0) {\n\t\t\tvalue = false;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\t/**\n\t * Takes a type string and checks if its supported\n\t */\n\n\tpf.supportsType = function( type ) {\n\t\treturn ( type ) ? types[ type ] : true;\n\t};\n\n\t/**\n\t * Parses a sourceSize into mediaCondition (media) and sourceSizeValue (length)\n\t * @param sourceSizeStr\n\t * @returns {*}\n\t */\n\tpf.parseSize = memoize(function( sourceSizeStr ) {\n\t\tvar match = ( sourceSizeStr || \"\" ).match(regSize);\n\t\treturn {\n\t\t\tmedia: match && match[1],\n\t\t\tlength: match && match[2]\n\t\t};\n\t});\n\n\tpf.parseSet = function( set ) {\n\t\tif ( !set.cands ) {\n\t\t\tset.cands = parseSrcset(set.srcset, set);\n\t\t}\n\t\treturn set.cands;\n\t};\n\n\t/**\n\t * returns 1em in css px for html/body default size\n\t * function taken from respondjs\n\t * @returns {*|number}\n\t */\n\tpf.getEmValue = function() {\n\t\tvar body;\n\t\tif ( !eminpx && (body = document.body) ) {\n\t\t\tvar div = document.createElement( \"div\" ),\n\t\t\t\toriginalHTMLCSS = docElem.style.cssText,\n\t\t\t\toriginalBodyCSS = body.style.cssText;\n\n\t\t\tdiv.style.cssText = baseStyle;\n\n\t\t\t// 1em in a media query is the value of the default font size of the browser\n\t\t\t// reset docElem and body to ensure the correct value is returned\n\t\t\tdocElem.style.cssText = fsCss;\n\t\t\tbody.style.cssText = fsCss;\n\n\t\t\tbody.appendChild( div );\n\t\t\teminpx = div.offsetWidth;\n\t\t\tbody.removeChild( div );\n\n\t\t\t//also update eminpx before returning\n\t\t\teminpx = parseFloat( eminpx, 10 );\n\n\t\t\t// restore the original values\n\t\t\tdocElem.style.cssText = originalHTMLCSS;\n\t\t\tbody.style.cssText = originalBodyCSS;\n\n\t\t}\n\t\treturn eminpx || 16;\n\t};\n\n\t/**\n\t * Takes a string of sizes and returns the width in pixels as a number\n\t */\n\tpf.calcListLength = function( sourceSizeListStr ) {\n\t\t// Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33%\n\t\t//\n\t\t// or (min-width:30em) calc(30% - 15px)\n\t\tif ( !(sourceSizeListStr in sizeLengthCache) || cfg.uT ) {\n\t\t\tvar winningLength = pf.calcLength( parseSizes( sourceSizeListStr ) );\n\n\t\t\tsizeLengthCache[ sourceSizeListStr ] = !winningLength ? units.width : winningLength;\n\t\t}\n\n\t\treturn sizeLengthCache[ sourceSizeListStr ];\n\t};\n\n\t/**\n\t * Takes a candidate object with a srcset property in the form of url/\n\t * ex. \"images/pic-medium.png 1x, images/pic-medium-2x.png 2x\" or\n\t * \"images/pic-medium.png 400w, images/pic-medium-2x.png 800w\" or\n\t * \"images/pic-small.png\"\n\t * Get an array of image candidates in the form of\n\t * {url: \"/foo/bar.png\", resolution: 1}\n\t * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value\n\t * If sizes is specified, res is calculated\n\t */\n\tpf.setRes = function( set ) {\n\t\tvar candidates;\n\t\tif ( set ) {\n\n\t\t\tcandidates = pf.parseSet( set );\n\n\t\t\tfor ( var i = 0, len = candidates.length; i < len; i++ ) {\n\t\t\t\tsetResolution( candidates[ i ], set.sizes );\n\t\t\t}\n\t\t}\n\t\treturn candidates;\n\t};\n\n\tpf.setRes.res = setResolution;\n\n\tpf.applySetCandidate = function( candidates, img ) {\n\t\tif ( !candidates.length ) {return;}\n\t\tvar candidate,\n\t\t\ti,\n\t\t\tj,\n\t\t\tlength,\n\t\t\tbestCandidate,\n\t\t\tcurSrc,\n\t\t\tcurCan,\n\t\t\tcandidateSrc,\n\t\t\tabortCurSrc;\n\n\t\tvar imageData = img[ pf.ns ];\n\t\tvar dpr = pf.DPR;\n\n\t\tcurSrc = imageData.curSrc || img[curSrcProp];\n\n\t\tcurCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set);\n\n\t\t// if we have a current source, we might either become lazy or give this source some advantage\n\t\tif ( curCan && curCan.set === candidates[ 0 ].set ) {\n\n\t\t\t// if browser can abort image request and the image has a higher pixel density than needed\n\t\t\t// and this image isn't downloaded yet, we skip next part and try to save bandwidth\n\t\t\tabortCurSrc = (supportAbort && !img.complete && curCan.res - 0.1 > dpr);\n\n\t\t\tif ( !abortCurSrc ) {\n\t\t\t\tcurCan.cached = true;\n\n\t\t\t\t// if current candidate is \"best\", \"better\" or \"okay\",\n\t\t\t\t// set it to bestCandidate\n\t\t\t\tif ( curCan.res >= dpr ) {\n\t\t\t\t\tbestCandidate = curCan;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( !bestCandidate ) {\n\n\t\t\tcandidates.sort( ascendingSort );\n\n\t\t\tlength = candidates.length;\n\t\t\tbestCandidate = candidates[ length - 1 ];\n\n\t\t\tfor ( i = 0; i < length; i++ ) {\n\t\t\t\tcandidate = candidates[ i ];\n\t\t\t\tif ( candidate.res >= dpr ) {\n\t\t\t\t\tj = i - 1;\n\n\t\t\t\t\t// we have found the perfect candidate,\n\t\t\t\t\t// but let's improve this a little bit with some assumptions ;-)\n\t\t\t\t\tif (candidates[ j ] &&\n\t\t\t\t\t\t(abortCurSrc || curSrc !== pf.makeUrl( candidate.url )) &&\n\t\t\t\t\t\tchooseLowRes(candidates[ j ].res, candidate.res, dpr, candidates[ j ].cached)) {\n\n\t\t\t\t\t\tbestCandidate = candidates[ j ];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbestCandidate = candidate;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( bestCandidate ) {\n\n\t\t\tcandidateSrc = pf.makeUrl( bestCandidate.url );\n\n\t\t\timageData.curSrc = candidateSrc;\n\t\t\timageData.curCan = bestCandidate;\n\n\t\t\tif ( candidateSrc !== curSrc ) {\n\t\t\t\tpf.setSrc( img, bestCandidate );\n\t\t\t}\n\t\t\tpf.setSize( img );\n\t\t}\n\t};\n\n\tpf.setSrc = function( img, bestCandidate ) {\n\t\tvar origWidth;\n\t\timg.src = bestCandidate.url;\n\n\t\t// although this is a specific Safari issue, we don't want to take too much different code paths\n\t\tif ( bestCandidate.set.type === \"image/svg+xml\" ) {\n\t\t\torigWidth = img.style.width;\n\t\t\timg.style.width = (img.offsetWidth + 1) + \"px\";\n\n\t\t\t// next line only should trigger a repaint\n\t\t\t// if... is only done to trick dead code removal\n\t\t\tif ( img.offsetWidth + 1 ) {\n\t\t\t\timg.style.width = origWidth;\n\t\t\t}\n\t\t}\n\t};\n\n\tpf.getSet = function( img ) {\n\t\tvar i, set, supportsType;\n\t\tvar match = false;\n\t\tvar sets = img [ pf.ns ].sets;\n\n\t\tfor ( i = 0; i < sets.length && !match; i++ ) {\n\t\t\tset = sets[i];\n\n\t\t\tif ( !set.srcset || !pf.matchesMedia( set.media ) || !(supportsType = pf.supportsType( set.type )) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( supportsType === \"pending\" ) {\n\t\t\t\tset = supportsType;\n\t\t\t}\n\n\t\t\tmatch = set;\n\t\t\tbreak;\n\t\t}\n\n\t\treturn match;\n\t};\n\n\tpf.parseSets = function( element, parent, options ) {\n\t\tvar srcsetAttribute, imageSet, isWDescripor, srcsetParsed;\n\n\t\tvar hasPicture = parent && parent.nodeName.toUpperCase() === \"PICTURE\";\n\t\tvar imageData = element[ pf.ns ];\n\n\t\tif ( imageData.src === undefined || options.src ) {\n\t\t\timageData.src = getImgAttr.call( element, \"src\" );\n\t\t\tif ( imageData.src ) {\n\t\t\t\tsetImgAttr.call( element, srcAttr, imageData.src );\n\t\t\t} else {\n\t\t\t\tremoveImgAttr.call( element, srcAttr );\n\t\t\t}\n\t\t}\n\n\t\tif ( imageData.srcset === undefined || options.srcset || !pf.supSrcset || element.srcset ) {\n\t\t\tsrcsetAttribute = getImgAttr.call( element, \"srcset\" );\n\t\t\timageData.srcset = srcsetAttribute;\n\t\t\tsrcsetParsed = true;\n\t\t}\n\n\t\timageData.sets = [];\n\n\t\tif ( hasPicture ) {\n\t\t\timageData.pic = true;\n\t\t\tgetAllSourceElements( parent, imageData.sets );\n\t\t}\n\n\t\tif ( imageData.srcset ) {\n\t\t\timageSet = {\n\t\t\t\tsrcset: imageData.srcset,\n\t\t\t\tsizes: getImgAttr.call( element, \"sizes\" )\n\t\t\t};\n\n\t\t\timageData.sets.push( imageSet );\n\n\t\t\tisWDescripor = (alwaysCheckWDescriptor || imageData.src) && regWDesc.test(imageData.srcset || \"\");\n\n\t\t\t// add normal src as candidate, if source has no w descriptor\n\t\t\tif ( !isWDescripor && imageData.src && !getCandidateForSrc(imageData.src, imageSet) && !imageSet.has1x ) {\n\t\t\t\timageSet.srcset += \", \" + imageData.src;\n\t\t\t\timageSet.cands.push({\n\t\t\t\t\turl: imageData.src,\n\t\t\t\t\td: 1,\n\t\t\t\t\tset: imageSet\n\t\t\t\t});\n\t\t\t}\n\n\t\t} else if ( imageData.src ) {\n\t\t\timageData.sets.push( {\n\t\t\t\tsrcset: imageData.src,\n\t\t\t\tsizes: null\n\t\t\t} );\n\t\t}\n\n\t\timageData.curCan = null;\n\t\timageData.curSrc = undefined;\n\n\t\t// if img has picture or the srcset was removed or has a srcset and does not support srcset at all\n\t\t// or has a w descriptor (and does not support sizes) set support to false to evaluate\n\t\timageData.supported = !( hasPicture || ( imageSet && !pf.supSrcset ) || (isWDescripor && !pf.supSizes) );\n\n\t\tif ( srcsetParsed && pf.supSrcset && !imageData.supported ) {\n\t\t\tif ( srcsetAttribute ) {\n\t\t\t\tsetImgAttr.call( element, srcsetAttr, srcsetAttribute );\n\t\t\t\telement.srcset = \"\";\n\t\t\t} else {\n\t\t\t\tremoveImgAttr.call( element, srcsetAttr );\n\t\t\t}\n\t\t}\n\n\t\tif (imageData.supported && !imageData.srcset && ((!imageData.src && element.src) || element.src !== pf.makeUrl(imageData.src))) {\n\t\t\tif (imageData.src === null) {\n\t\t\t\telement.removeAttribute(\"src\");\n\t\t\t} else {\n\t\t\t\telement.src = imageData.src;\n\t\t\t}\n\t\t}\n\n\t\timageData.parsed = true;\n\t};\n\n\tpf.fillImg = function(element, options) {\n\t\tvar imageData;\n\t\tvar extreme = options.reselect || options.reevaluate;\n\n\t\t// expando for caching data on the img\n\t\tif ( !element[ pf.ns ] ) {\n\t\t\telement[ pf.ns ] = {};\n\t\t}\n\n\t\timageData = element[ pf.ns ];\n\n\t\t// if the element has already been evaluated, skip it\n\t\t// unless `options.reevaluate` is set to true ( this, for example,\n\t\t// is set to true when running `picturefill` on `resize` ).\n\t\tif ( !extreme && imageData.evaled === evalId ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !imageData.parsed || options.reevaluate ) {\n\t\t\tpf.parseSets( element, element.parentNode, options );\n\t\t}\n\n\t\tif ( !imageData.supported ) {\n\t\t\tapplyBestCandidate( element );\n\t\t} else {\n\t\t\timageData.evaled = evalId;\n\t\t}\n\t};\n\n\tpf.setupRun = function() {\n\t\tif ( !alreadyRun || isVwDirty || (DPR !== window.devicePixelRatio) ) {\n\t\t\tupdateMetrics();\n\t\t}\n\t};\n\n\t// If picture is supported, well, that's awesome.\n\tif ( pf.supPicture ) {\n\t\tpicturefill = noop;\n\t\tpf.fillImg = noop;\n\t} else {\n\n\t\t // Set up picture polyfill by polling the document\n\t\t(function() {\n\t\t\tvar isDomReady;\n\t\t\tvar regReady = window.attachEvent ? /d$|^c/ : /d$|^c|^i/;\n\n\t\t\tvar run = function() {\n\t\t\t\tvar readyState = document.readyState || \"\";\n\n\t\t\t\ttimerId = setTimeout(run, readyState === \"loading\" ? 200 : 999);\n\t\t\t\tif ( document.body ) {\n\t\t\t\t\tpf.fillImgs();\n\t\t\t\t\tisDomReady = isDomReady || regReady.test(readyState);\n\t\t\t\t\tif ( isDomReady ) {\n\t\t\t\t\t\tclearTimeout( timerId );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvar timerId = setTimeout(run, document.body ? 9 : 99);\n\n\t\t\t// Also attach picturefill on resize and readystatechange\n\t\t\t// http://modernjavascript.blogspot.com/2013/08/building-better-debounce.html\n\t\t\tvar debounce = function(func, wait) {\n\t\t\t\tvar timeout, timestamp;\n\t\t\t\tvar later = function() {\n\t\t\t\t\tvar last = (new Date()) - timestamp;\n\n\t\t\t\t\tif (last < wait) {\n\t\t\t\t\t\ttimeout = setTimeout(later, wait - last);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttimeout = null;\n\t\t\t\t\t\tfunc();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\treturn function() {\n\t\t\t\t\ttimestamp = new Date();\n\n\t\t\t\t\tif (!timeout) {\n\t\t\t\t\t\ttimeout = setTimeout(later, wait);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\t\t\tvar lastClientWidth = docElem.clientHeight;\n\t\t\tvar onResize = function() {\n\t\t\t\tisVwDirty = Math.max(window.innerWidth || 0, docElem.clientWidth) !== units.width || docElem.clientHeight !== lastClientWidth;\n\t\t\t\tlastClientWidth = docElem.clientHeight;\n\t\t\t\tif ( isVwDirty ) {\n\t\t\t\t\tpf.fillImgs();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ton( window, \"resize\", debounce(onResize, 99 ) );\n\t\t\ton( document, \"readystatechange\", run );\n\t\t})();\n\t}\n\n\tpf.picturefill = picturefill;\n\t//use this internally for easy monkey patching/performance testing\n\tpf.fillImgs = picturefill;\n\tpf.teardownRun = noop;\n\n\t/* expose methods for testing */\n\tpicturefill._ = pf;\n\n\twindow.picturefillCFG = {\n\t\tpf: pf,\n\t\tpush: function(args) {\n\t\t\tvar name = args.shift();\n\t\t\tif (typeof pf[name] === \"function\") {\n\t\t\t\tpf[name].apply(pf, args);\n\t\t\t} else {\n\t\t\t\tcfg[name] = args[0];\n\t\t\t\tif (alreadyRun) {\n\t\t\t\t\tpf.fillImgs( { reselect: true } );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\twhile (setOptions && setOptions.length) {\n\t\twindow.picturefillCFG.push(setOptions.shift());\n\t}\n\n\t/* expose picturefill */\n\twindow.picturefill = picturefill;\n\n\t/* expose picturefill */\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// CommonJS, just export\n\t\tmodule.exports = picturefill;\n\t} else if ( typeof define === \"function\" && define.amd ) {\n\t\t// AMD support\n\t\tdefine( \"picturefill\", function() { return picturefill; } );\n\t}\n\n\t// IE8 evals this sync, so it must be the last thing we do\n\tif ( !pf.supPicture ) {\n\t\ttypes[ \"image/webp\" ] = detectTypeSupport(\"image/webp\", \"data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==\" );\n\t}\n\n} )( window, document );\n","/* smoothscroll v0.4.4 - 2019 - Dustan Kasten, Jeremias Menichelli - MIT License */\n(function () {\n 'use strict';\n\n // polyfill\n function polyfill() {\n // aliases\n var w = window;\n var d = document;\n\n // return if scroll behavior is supported and polyfill is not forced\n if (\n 'scrollBehavior' in d.documentElement.style &&\n w.__forceSmoothScrollPolyfill__ !== true\n ) {\n return;\n }\n\n // globals\n var Element = w.HTMLElement || w.Element;\n var SCROLL_TIME = 468;\n\n // object gathering original scroll methods\n var original = {\n scroll: w.scroll || w.scrollTo,\n scrollBy: w.scrollBy,\n elementScroll: Element.prototype.scroll || scrollElement,\n scrollIntoView: Element.prototype.scrollIntoView\n };\n\n // define timing method\n var now =\n w.performance && w.performance.now\n ? w.performance.now.bind(w.performance)\n : Date.now;\n\n /**\n * indicates if a the current browser is made by Microsoft\n * @method isMicrosoftBrowser\n * @param {String} userAgent\n * @returns {Boolean}\n */\n function isMicrosoftBrowser(userAgent) {\n var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];\n\n return new RegExp(userAgentPatterns.join('|')).test(userAgent);\n }\n\n /*\n * IE has rounding bug rounding down clientHeight and clientWidth and\n * rounding up scrollHeight and scrollWidth causing false positives\n * on hasScrollableSpace\n */\n var ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;\n\n /**\n * changes scroll position inside an element\n * @method scrollElement\n * @param {Number} x\n * @param {Number} y\n * @returns {undefined}\n */\n function scrollElement(x, y) {\n this.scrollLeft = x;\n this.scrollTop = y;\n }\n\n /**\n * returns result of applying ease math function to a number\n * @method ease\n * @param {Number} k\n * @returns {Number}\n */\n function ease(k) {\n return 0.5 * (1 - Math.cos(Math.PI * k));\n }\n\n /**\n * indicates if a smooth behavior should be applied\n * @method shouldBailOut\n * @param {Number|Object} firstArg\n * @returns {Boolean}\n */\n function shouldBailOut(firstArg) {\n if (\n firstArg === null ||\n typeof firstArg !== 'object' ||\n firstArg.behavior === undefined ||\n firstArg.behavior === 'auto' ||\n firstArg.behavior === 'instant'\n ) {\n // first argument is not an object/null\n // or behavior is auto, instant or undefined\n return true;\n }\n\n if (typeof firstArg === 'object' && firstArg.behavior === 'smooth') {\n // first argument is an object and behavior is smooth\n return false;\n }\n\n // throw error when behavior is not supported\n throw new TypeError(\n 'behavior member of ScrollOptions ' +\n firstArg.behavior +\n ' is not a valid value for enumeration ScrollBehavior.'\n );\n }\n\n /**\n * indicates if an element has scrollable space in the provided axis\n * @method hasScrollableSpace\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function hasScrollableSpace(el, axis) {\n if (axis === 'Y') {\n return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;\n }\n\n if (axis === 'X') {\n return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;\n }\n }\n\n /**\n * indicates if an element has a scrollable overflow property in the axis\n * @method canOverflow\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function canOverflow(el, axis) {\n var overflowValue = w.getComputedStyle(el, null)['overflow' + axis];\n\n return overflowValue === 'auto' || overflowValue === 'scroll';\n }\n\n /**\n * indicates if an element can be scrolled in either axis\n * @method isScrollable\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function isScrollable(el) {\n var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');\n var isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');\n\n return isScrollableY || isScrollableX;\n }\n\n /**\n * finds scrollable parent of an element\n * @method findScrollableParent\n * @param {Node} el\n * @returns {Node} el\n */\n function findScrollableParent(el) {\n while (el !== d.body && isScrollable(el) === false) {\n el = el.parentNode || el.host;\n }\n\n return el;\n }\n\n /**\n * self invoked function that, given a context, steps through scrolling\n * @method step\n * @param {Object} context\n * @returns {undefined}\n */\n function step(context) {\n var time = now();\n var value;\n var currentX;\n var currentY;\n var elapsed = (time - context.startTime) / SCROLL_TIME;\n\n // avoid elapsed times higher than one\n elapsed = elapsed > 1 ? 1 : elapsed;\n\n // apply easing to elapsed time\n value = ease(elapsed);\n\n currentX = context.startX + (context.x - context.startX) * value;\n currentY = context.startY + (context.y - context.startY) * value;\n\n context.method.call(context.scrollable, currentX, currentY);\n\n // scroll more if we have not reached our destination\n if (currentX !== context.x || currentY !== context.y) {\n w.requestAnimationFrame(step.bind(w, context));\n }\n }\n\n /**\n * scrolls window or element with a smooth behavior\n * @method smoothScroll\n * @param {Object|Node} el\n * @param {Number} x\n * @param {Number} y\n * @returns {undefined}\n */\n function smoothScroll(el, x, y) {\n var scrollable;\n var startX;\n var startY;\n var method;\n var startTime = now();\n\n // define scroll context\n if (el === d.body) {\n scrollable = w;\n startX = w.scrollX || w.pageXOffset;\n startY = w.scrollY || w.pageYOffset;\n method = original.scroll;\n } else {\n scrollable = el;\n startX = el.scrollLeft;\n startY = el.scrollTop;\n method = scrollElement;\n }\n\n // scroll looping over a frame\n step({\n scrollable: scrollable,\n method: method,\n startTime: startTime,\n startX: startX,\n startY: startY,\n x: x,\n y: y\n });\n }\n\n // ORIGINAL METHODS OVERRIDES\n // w.scroll and w.scrollTo\n w.scroll = w.scrollTo = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.scroll.call(\n w,\n arguments[0].left !== undefined\n ? arguments[0].left\n : typeof arguments[0] !== 'object'\n ? arguments[0]\n : w.scrollX || w.pageXOffset,\n // use top prop, second argument if present or fallback to scrollY\n arguments[0].top !== undefined\n ? arguments[0].top\n : arguments[1] !== undefined\n ? arguments[1]\n : w.scrollY || w.pageYOffset\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n arguments[0].left !== undefined\n ? ~~arguments[0].left\n : w.scrollX || w.pageXOffset,\n arguments[0].top !== undefined\n ? ~~arguments[0].top\n : w.scrollY || w.pageYOffset\n );\n };\n\n // w.scrollBy\n w.scrollBy = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.scrollBy.call(\n w,\n arguments[0].left !== undefined\n ? arguments[0].left\n : typeof arguments[0] !== 'object' ? arguments[0] : 0,\n arguments[0].top !== undefined\n ? arguments[0].top\n : arguments[1] !== undefined ? arguments[1] : 0\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n ~~arguments[0].left + (w.scrollX || w.pageXOffset),\n ~~arguments[0].top + (w.scrollY || w.pageYOffset)\n );\n };\n\n // Element.prototype.scroll and Element.prototype.scrollTo\n Element.prototype.scroll = Element.prototype.scrollTo = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n // if one number is passed, throw error to match Firefox implementation\n if (typeof arguments[0] === 'number' && arguments[1] === undefined) {\n throw new SyntaxError('Value could not be converted');\n }\n\n original.elementScroll.call(\n this,\n // use left prop, first number argument or fallback to scrollLeft\n arguments[0].left !== undefined\n ? ~~arguments[0].left\n : typeof arguments[0] !== 'object' ? ~~arguments[0] : this.scrollLeft,\n // use top prop, second argument or fallback to scrollTop\n arguments[0].top !== undefined\n ? ~~arguments[0].top\n : arguments[1] !== undefined ? ~~arguments[1] : this.scrollTop\n );\n\n return;\n }\n\n var left = arguments[0].left;\n var top = arguments[0].top;\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n this,\n this,\n typeof left === 'undefined' ? this.scrollLeft : ~~left,\n typeof top === 'undefined' ? this.scrollTop : ~~top\n );\n };\n\n // Element.prototype.scrollBy\n Element.prototype.scrollBy = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.elementScroll.call(\n this,\n arguments[0].left !== undefined\n ? ~~arguments[0].left + this.scrollLeft\n : ~~arguments[0] + this.scrollLeft,\n arguments[0].top !== undefined\n ? ~~arguments[0].top + this.scrollTop\n : ~~arguments[1] + this.scrollTop\n );\n\n return;\n }\n\n this.scroll({\n left: ~~arguments[0].left + this.scrollLeft,\n top: ~~arguments[0].top + this.scrollTop,\n behavior: arguments[0].behavior\n });\n };\n\n // Element.prototype.scrollIntoView\n Element.prototype.scrollIntoView = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.scrollIntoView.call(\n this,\n arguments[0] === undefined ? true : arguments[0]\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n var scrollableParent = findScrollableParent(this);\n var parentRects = scrollableParent.getBoundingClientRect();\n var clientRects = this.getBoundingClientRect();\n\n if (scrollableParent !== d.body) {\n // reveal element inside parent\n smoothScroll.call(\n this,\n scrollableParent,\n scrollableParent.scrollLeft + clientRects.left - parentRects.left,\n scrollableParent.scrollTop + clientRects.top - parentRects.top\n );\n\n // reveal parent in viewport unless is fixed\n if (w.getComputedStyle(scrollableParent).position !== 'fixed') {\n w.scrollBy({\n left: parentRects.left,\n top: parentRects.top,\n behavior: 'smooth'\n });\n }\n } else {\n // reveal element in viewport\n w.scrollBy({\n left: clientRects.left,\n top: clientRects.top,\n behavior: 'smooth'\n });\n }\n };\n }\n\n if (typeof exports === 'object' && typeof module !== 'undefined') {\n // commonjs\n module.exports = { polyfill: polyfill };\n } else {\n // global\n polyfill();\n }\n\n}());\n","import objectFitImages from 'object-fit-images'\nimport 'picturefill' // This autofixes srcset on IE/Edge\nimport smoothscroll from 'smoothscroll-polyfill'\n\n// kick off the polyfill!\nsmoothscroll.polyfill()\n\njQuery(document).ready(function () {\n objectFitImages()\n jQuery('[data-toggle=\"tooltip\"]').tooltip()\n});\n\n//IE forEach polyfill\nif ('NodeList' in window && !NodeList.prototype.forEach) {\n NodeList.prototype.forEach = function (callback, thisArg) {\n thisArg = thisArg || window\n\n for (var i = 0; i < this.length; i++) {\n callback.call(thisArg, this[i], i, this)\n }\n };\n}\n\n// Mobile vh fix\n// We listen to the resize event\nlet vh = window.innerHeight * 0.01;\ndocument.documentElement.style.setProperty('--vh', `${vh}px`);\n\nwindow.addEventListener('resize', () => {\n // We execute the same script as before\n let vh = window.innerHeight * 0.01;\n document.documentElement.style.setProperty('--vh', `${vh}px`);\n});"],"preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LWZpdC1pbWFnZXMvZGlzdC9vZmkuY29tbW9uLWpzLmpzIiwibm9kZV9tb2R1bGVzL3BpY3R1cmVmaWxsL2Rpc3QvcGljdHVyZWZpbGwuanMiLCJub2RlX21vZHVsZXMvc21vb3Roc2Nyb2xsLXBvbHlmaWxsL2Rpc3Qvc21vb3Roc2Nyb2xsLmpzIiwid3AtY29udGVudC90aGVtZXMvamNvcmUyL2pzL2pjb3JlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Z0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqYkE7O0FBQ0E7O0FBQ0E7Ozs7QUFEcUI7QUFHckI7QUFDQSw4QkFBYSxRQUFiOztBQUVBLE1BQU0sQ0FBQyxRQUFELENBQU4sQ0FBaUIsS0FBakIsQ0FBdUIsWUFBWTtBQUMvQjtBQUNBLEVBQUEsTUFBTSxDQUFDLHlCQUFELENBQU4sQ0FBa0MsT0FBbEM7QUFDSCxDQUhELEUsQ0FLQTs7QUFDQSxJQUFJLGNBQWMsTUFBZCxJQUF3QixDQUFDLFFBQVEsQ0FBQyxTQUFULENBQW1CLE9BQWhELEVBQXlEO0FBQ3JELEVBQUEsUUFBUSxDQUFDLFNBQVQsQ0FBbUIsT0FBbkIsR0FBNkIsVUFBVSxRQUFWLEVBQW9CLE9BQXBCLEVBQTZCO0FBQ3RELElBQUEsT0FBTyxHQUFHLE9BQU8sSUFBSSxNQUFyQjs7QUFFQSxTQUFLLElBQUksQ0FBQyxHQUFHLENBQWIsRUFBZ0IsQ0FBQyxHQUFHLEtBQUssTUFBekIsRUFBaUMsQ0FBQyxFQUFsQyxFQUFzQztBQUNsQyxNQUFBLFFBQVEsQ0FBQyxJQUFULENBQWMsT0FBZCxFQUF1QixLQUFLLENBQUwsQ0FBdkIsRUFBZ0MsQ0FBaEMsRUFBbUMsSUFBbkM7QUFDSDtBQUNKLEdBTkQ7QUFPSCxDLENBRUQ7QUFDQTs7O0FBQ0EsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFdBQVAsR0FBcUIsSUFBOUI7QUFDQSxRQUFRLENBQUMsZUFBVCxDQUF5QixLQUF6QixDQUErQixXQUEvQixDQUEyQyxNQUEzQyxZQUFzRCxFQUF0RDtBQUVBLE1BQU0sQ0FBQyxnQkFBUCxDQUF3QixRQUF4QixFQUFrQyxZQUFNO0FBQ3BDO0FBQ0EsTUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFdBQVAsR0FBcUIsSUFBOUI7QUFDQSxFQUFBLFFBQVEsQ0FBQyxlQUFULENBQXlCLEtBQXpCLENBQStCLFdBQS9CLENBQTJDLE1BQTNDLFlBQXNELEVBQXREO0FBQ0gsQ0FKRCIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qISBucG0uaW0vb2JqZWN0LWZpdC1pbWFnZXMgMy4yLjQgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIE9GSSA9ICdiZnJlZC1pdDpvYmplY3QtZml0LWltYWdlcyc7XG52YXIgcHJvcFJlZ2V4ID0gLyhvYmplY3QtZml0fG9iamVjdC1wb3NpdGlvbilcXHMqOlxccyooWy0uXFx3XFxzJV0rKS9nO1xudmFyIHRlc3RJbWcgPSB0eXBlb2YgSW1hZ2UgPT09ICd1bmRlZmluZWQnID8ge3N0eWxlOiB7J29iamVjdC1wb3NpdGlvbic6IDF9fSA6IG5ldyBJbWFnZSgpO1xudmFyIHN1cHBvcnRzT2JqZWN0Rml0ID0gJ29iamVjdC1maXQnIGluIHRlc3RJbWcuc3R5bGU7XG52YXIgc3VwcG9ydHNPYmplY3RQb3NpdGlvbiA9ICdvYmplY3QtcG9zaXRpb24nIGluIHRlc3RJbWcuc3R5bGU7XG52YXIgc3VwcG9ydHNPRkkgPSAnYmFja2dyb3VuZC1zaXplJyBpbiB0ZXN0SW1nLnN0eWxlO1xudmFyIHN1cHBvcnRzQ3VycmVudFNyYyA9IHR5cGVvZiB0ZXN0SW1nLmN1cnJlbnRTcmMgPT09ICdzdHJpbmcnO1xudmFyIG5hdGl2ZUdldEF0dHJpYnV0ZSA9IHRlc3RJbWcuZ2V0QXR0cmlidXRlO1xudmFyIG5hdGl2ZVNldEF0dHJpYnV0ZSA9IHRlc3RJbWcuc2V0QXR0cmlidXRlO1xudmFyIGF1dG9Nb2RlRW5hYmxlZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBjcmVhdGVQbGFjZWhvbGRlcih3LCBoKSB7XG5cdHJldHVybiAoXCJkYXRhOmltYWdlL3N2Zyt4bWwsJTNDc3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgd2lkdGg9J1wiICsgdyArIFwiJyBoZWlnaHQ9J1wiICsgaCArIFwiJyUzRSUzQy9zdmclM0VcIik7XG59XG5cbmZ1bmN0aW9uIHBvbHlmaWxsQ3VycmVudFNyYyhlbCkge1xuXHRpZiAoZWwuc3Jjc2V0ICYmICFzdXBwb3J0c0N1cnJlbnRTcmMgJiYgd2luZG93LnBpY3R1cmVmaWxsKSB7XG5cdFx0dmFyIHBmID0gd2luZG93LnBpY3R1cmVmaWxsLl87XG5cdFx0Ly8gcGFyc2Ugc3Jjc2V0IHdpdGggcGljdHVyZWZpbGwgd2hlcmUgY3VycmVudFNyYyBpc24ndCBhdmFpbGFibGVcblx0XHRpZiAoIWVsW3BmLm5zXSB8fCAhZWxbcGYubnNdLmV2YWxlZCkge1xuXHRcdFx0Ly8gZm9yY2Ugc3luY2hyb25vdXMgc3Jjc2V0IHBhcnNpbmdcblx0XHRcdHBmLmZpbGxJbWcoZWwsIHtyZXNlbGVjdDogdHJ1ZX0pO1xuXHRcdH1cblxuXHRcdGlmICghZWxbcGYubnNdLmN1clNyYykge1xuXHRcdFx0Ly8gZm9yY2UgcGljdHVyZWZpbGwgdG8gcGFyc2Ugc3Jjc2V0XG5cdFx0XHRlbFtwZi5uc10uc3VwcG9ydGVkID0gZmFsc2U7XG5cdFx0XHRwZi5maWxsSW1nKGVsLCB7cmVzZWxlY3Q6IHRydWV9KTtcblx0XHR9XG5cblx0XHQvLyByZXRyaWV2ZSBwYXJzZWQgY3VycmVudFNyYywgaWYgYW55XG5cdFx0ZWwuY3VycmVudFNyYyA9IGVsW3BmLm5zXS5jdXJTcmMgfHwgZWwuc3JjO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGdldFN0eWxlKGVsKSB7XG5cdHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWwpLmZvbnRGYW1pbHk7XG5cdHZhciBwYXJzZWQ7XG5cdHZhciBwcm9wcyA9IHt9O1xuXHR3aGlsZSAoKHBhcnNlZCA9IHByb3BSZWdleC5leGVjKHN0eWxlKSkgIT09IG51bGwpIHtcblx0XHRwcm9wc1twYXJzZWRbMV1dID0gcGFyc2VkWzJdO1xuXHR9XG5cdHJldHVybiBwcm9wcztcbn1cblxuZnVuY3Rpb24gc2V0UGxhY2Vob2xkZXIoaW1nLCB3aWR0aCwgaGVpZ2h0KSB7XG5cdC8vIERlZmF1bHQ6IGZpbGwgd2lkdGgsIG5vIGhlaWdodFxuXHR2YXIgcGxhY2Vob2xkZXIgPSBjcmVhdGVQbGFjZWhvbGRlcih3aWR0aCB8fCAxLCBoZWlnaHQgfHwgMCk7XG5cblx0Ly8gT25seSBzZXQgcGxhY2Vob2xkZXIgaWYgaXQncyBkaWZmZXJlbnRcblx0aWYgKG5hdGl2ZUdldEF0dHJpYnV0ZS5jYWxsKGltZywgJ3NyYycpICE9PSBwbGFjZWhvbGRlcikge1xuXHRcdG5hdGl2ZVNldEF0dHJpYnV0ZS5jYWxsKGltZywgJ3NyYycsIHBsYWNlaG9sZGVyKTtcblx0fVxufVxuXG5mdW5jdGlvbiBvbkltYWdlUmVhZHkoaW1nLCBjYWxsYmFjaykge1xuXHQvLyBuYXR1cmFsV2lkdGggaXMgb25seSBhdmFpbGFibGUgd2hlbiB0aGUgaW1hZ2UgaGVhZGVycyBhcmUgbG9hZGVkLFxuXHQvLyB0aGlzIGxvb3Agd2lsbCBwb2xsIGl0IGV2ZXJ5IDEwMG1zLlxuXHRpZiAoaW1nLm5hdHVyYWxXaWR0aCkge1xuXHRcdGNhbGxiYWNrKGltZyk7XG5cdH0gZWxzZSB7XG5cdFx0c2V0VGltZW91dChvbkltYWdlUmVhZHksIDEwMCwgaW1nLCBjYWxsYmFjayk7XG5cdH1cbn1cblxuZnVuY3Rpb24gZml4T25lKGVsKSB7XG5cdHZhciBzdHlsZSA9IGdldFN0eWxlKGVsKTtcblx0dmFyIG9maSA9IGVsW09GSV07XG5cdHN0eWxlWydvYmplY3QtZml0J10gPSBzdHlsZVsnb2JqZWN0LWZpdCddIHx8ICdmaWxsJzsgLy8gZGVmYXVsdCB2YWx1ZVxuXG5cdC8vIEF2b2lkIHJ1bm5pbmcgd2hlcmUgdW5uZWNlc3NhcnksIHVubGVzcyBPRkkgaGFkIGFscmVhZHkgZG9uZSBpdHMgZGVlZFxuXHRpZiAoIW9maS5pbWcpIHtcblx0XHQvLyBmaWxsIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIHNvIG5vIGFjdGlvbiBpcyBuZWNlc3Nhcnlcblx0XHRpZiAoc3R5bGVbJ29iamVjdC1maXQnXSA9PT0gJ2ZpbGwnKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gV2hlcmUgb2JqZWN0LWZpdCBpcyBzdXBwb3J0ZWQgYW5kIG9iamVjdC1wb3NpdGlvbiBpc24ndCAoU2FmYXJpIDwgMTApXG5cdFx0aWYgKFxuXHRcdFx0IW9maS5za2lwVGVzdCAmJiAvLyB1bmxlc3MgdXNlciB3YW50cyB0byBhcHBseSByZWdhcmRsZXNzIG9mIGJyb3dzZXIgc3VwcG9ydFxuXHRcdFx0c3VwcG9ydHNPYmplY3RGaXQgJiYgLy8gaWYgYnJvd3NlciBhbHJlYWR5IHN1cHBvcnRzIG9iamVjdC1maXRcblx0XHRcdCFzdHlsZVsnb2JqZWN0LXBvc2l0aW9uJ10gLy8gdW5sZXNzIG9iamVjdC1wb3NpdGlvbiBpcyB1c2VkXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHR9XG5cblx0Ly8ga2VlcCBhIGNsb25lIGluIG1lbW9yeSB3aGlsZSByZXNldHRpbmcgdGhlIG9yaWdpbmFsIHRvIGEgYmxhbmtcblx0aWYgKCFvZmkuaW1nKSB7XG5cdFx0b2ZpLmltZyA9IG5ldyBJbWFnZShlbC53aWR0aCwgZWwuaGVpZ2h0KTtcblx0XHRvZmkuaW1nLnNyY3NldCA9IG5hdGl2ZUdldEF0dHJpYnV0ZS5jYWxsKGVsLCBcImRhdGEtb2ZpLXNyY3NldFwiKSB8fCBlbC5zcmNzZXQ7XG5cdFx0b2ZpLmltZy5zcmMgPSBuYXRpdmVHZXRBdHRyaWJ1dGUuY2FsbChlbCwgXCJkYXRhLW9maS1zcmNcIikgfHwgZWwuc3JjO1xuXG5cdFx0Ly8gcHJlc2VydmUgZm9yIGFueSBmdXR1cmUgY2xvbmVOb2RlIGNhbGxzXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2JmcmVkLWl0L29iamVjdC1maXQtaW1hZ2VzL2lzc3Vlcy81M1xuXHRcdG5hdGl2ZVNldEF0dHJpYnV0ZS5jYWxsKGVsLCBcImRhdGEtb2ZpLXNyY1wiLCBlbC5zcmMpO1xuXHRcdGlmIChlbC5zcmNzZXQpIHtcblx0XHRcdG5hdGl2ZVNldEF0dHJpYnV0ZS5jYWxsKGVsLCBcImRhdGEtb2ZpLXNyY3NldFwiLCBlbC5zcmNzZXQpO1xuXHRcdH1cblxuXHRcdHNldFBsYWNlaG9sZGVyKGVsLCBlbC5uYXR1cmFsV2lkdGggfHwgZWwud2lkdGgsIGVsLm5hdHVyYWxIZWlnaHQgfHwgZWwuaGVpZ2h0KTtcblxuXHRcdC8vIHJlbW92ZSBzcmNzZXQgYmVjYXVzZSBpdCBvdmVycmlkZXMgc3JjXG5cdFx0aWYgKGVsLnNyY3NldCkge1xuXHRcdFx0ZWwuc3Jjc2V0ID0gJyc7XG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRrZWVwU3JjVXNhYmxlKGVsKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdGlmICh3aW5kb3cuY29uc29sZSkge1xuXHRcdFx0XHRjb25zb2xlLndhcm4oJ2h0dHBzOi8vYml0Lmx5L29maS1vbGQtYnJvd3NlcicpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHBvbHlmaWxsQ3VycmVudFNyYyhvZmkuaW1nKTtcblxuXHRlbC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgPSBcInVybChcXFwiXCIgKyAoKG9maS5pbWcuY3VycmVudFNyYyB8fCBvZmkuaW1nLnNyYykucmVwbGFjZSgvXCIvZywgJ1xcXFxcIicpKSArIFwiXFxcIilcIjtcblx0ZWwuc3R5bGUuYmFja2dyb3VuZFBvc2l0aW9uID0gc3R5bGVbJ29iamVjdC1wb3NpdGlvbiddIHx8ICdjZW50ZXInO1xuXHRlbC5zdHlsZS5iYWNrZ3JvdW5kUmVwZWF0ID0gJ25vLXJlcGVhdCc7XG5cdGVsLnN0eWxlLmJhY2tncm91bmRPcmlnaW4gPSAnY29udGVudC1ib3gnO1xuXG5cdGlmICgvc2NhbGUtZG93bi8udGVzdChzdHlsZVsnb2JqZWN0LWZpdCddKSkge1xuXHRcdG9uSW1hZ2VSZWFkeShvZmkuaW1nLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpZiAob2ZpLmltZy5uYXR1cmFsV2lkdGggPiBlbC53aWR0aCB8fCBvZmkuaW1nLm5hdHVyYWxIZWlnaHQgPiBlbC5oZWlnaHQpIHtcblx0XHRcdFx0ZWwuc3R5bGUuYmFja2dyb3VuZFNpemUgPSAnY29udGFpbic7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbC5zdHlsZS5iYWNrZ3JvdW5kU2l6ZSA9ICdhdXRvJztcblx0XHRcdH1cblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHRlbC5zdHlsZS5iYWNrZ3JvdW5kU2l6ZSA9IHN0eWxlWydvYmplY3QtZml0J10ucmVwbGFjZSgnbm9uZScsICdhdXRvJykucmVwbGFjZSgnZmlsbCcsICcxMDAlIDEwMCUnKTtcblx0fVxuXG5cdG9uSW1hZ2VSZWFkeShvZmkuaW1nLCBmdW5jdGlvbiAoaW1nKSB7XG5cdFx0c2V0UGxhY2Vob2xkZXIoZWwsIGltZy5uYXR1cmFsV2lkdGgsIGltZy5uYXR1cmFsSGVpZ2h0KTtcblx0fSk7XG59XG5cbmZ1bmN0aW9uIGtlZXBTcmNVc2FibGUoZWwpIHtcblx0dmFyIGRlc2NyaXB0b3JzID0ge1xuXHRcdGdldDogZnVuY3Rpb24gZ2V0KHByb3ApIHtcblx0XHRcdHJldHVybiBlbFtPRkldLmltZ1twcm9wID8gcHJvcCA6ICdzcmMnXTtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24gc2V0KHZhbHVlLCBwcm9wKSB7XG5cdFx0XHRlbFtPRkldLmltZ1twcm9wID8gcHJvcCA6ICdzcmMnXSA9IHZhbHVlO1xuXHRcdFx0bmF0aXZlU2V0QXR0cmlidXRlLmNhbGwoZWwsIChcImRhdGEtb2ZpLVwiICsgcHJvcCksIHZhbHVlKTsgLy8gcHJlc2VydmUgZm9yIGFueSBmdXR1cmUgY2xvbmVOb2RlXG5cdFx0XHRmaXhPbmUoZWwpO1xuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH1cblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGVsLCAnc3JjJywgZGVzY3JpcHRvcnMpO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZWwsICdjdXJyZW50U3JjJywge1xuXHRcdGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVzY3JpcHRvcnMuZ2V0KCdjdXJyZW50U3JjJyk7IH1cblx0fSk7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbCwgJ3NyY3NldCcsIHtcblx0XHRnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRlc2NyaXB0b3JzLmdldCgnc3Jjc2V0Jyk7IH0sXG5cdFx0c2V0OiBmdW5jdGlvbiAoc3MpIHsgcmV0dXJuIGRlc2NyaXB0b3JzLnNldChzcywgJ3NyY3NldCcpOyB9XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBoaWphY2tBdHRyaWJ1dGVzKCkge1xuXHRmdW5jdGlvbiBnZXRPZmlJbWFnZU1heWJlKGVsLCBuYW1lKSB7XG5cdFx0cmV0dXJuIGVsW09GSV0gJiYgZWxbT0ZJXS5pbWcgJiYgKG5hbWUgPT09ICdzcmMnIHx8IG5hbWUgPT09ICdzcmNzZXQnKSA/IGVsW09GSV0uaW1nIDogZWw7XG5cdH1cblx0aWYgKCFzdXBwb3J0c09iamVjdFBvc2l0aW9uKSB7XG5cdFx0SFRNTEltYWdlRWxlbWVudC5wcm90b3R5cGUuZ2V0QXR0cmlidXRlID0gZnVuY3Rpb24gKG5hbWUpIHtcblx0XHRcdHJldHVybiBuYXRpdmVHZXRBdHRyaWJ1dGUuY2FsbChnZXRPZmlJbWFnZU1heWJlKHRoaXMsIG5hbWUpLCBuYW1lKTtcblx0XHR9O1xuXG5cdFx0SFRNTEltYWdlRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0cmlidXRlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRyZXR1cm4gbmF0aXZlU2V0QXR0cmlidXRlLmNhbGwoZ2V0T2ZpSW1hZ2VNYXliZSh0aGlzLCBuYW1lKSwgbmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0fTtcblx0fVxufVxuXG5mdW5jdGlvbiBmaXgoaW1ncywgb3B0cykge1xuXHR2YXIgc3RhcnRBdXRvTW9kZSA9ICFhdXRvTW9kZUVuYWJsZWQgJiYgIWltZ3M7XG5cdG9wdHMgPSBvcHRzIHx8IHt9O1xuXHRpbWdzID0gaW1ncyB8fCAnaW1nJztcblxuXHRpZiAoKHN1cHBvcnRzT2JqZWN0UG9zaXRpb24gJiYgIW9wdHMuc2tpcFRlc3QpIHx8ICFzdXBwb3J0c09GSSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8vIHVzZSBpbWdzIGFzIGEgc2VsZWN0b3Igb3IganVzdCBzZWxlY3QgYWxsIGltYWdlc1xuXHRpZiAoaW1ncyA9PT0gJ2ltZycpIHtcblx0XHRpbWdzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2ltZycpO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiBpbWdzID09PSAnc3RyaW5nJykge1xuXHRcdGltZ3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGltZ3MpO1xuXHR9IGVsc2UgaWYgKCEoJ2xlbmd0aCcgaW4gaW1ncykpIHtcblx0XHRpbWdzID0gW2ltZ3NdO1xuXHR9XG5cblx0Ly8gYXBwbHkgZml4IHRvIGFsbFxuXHRmb3IgKHZhciBpID0gMDsgaSA8IGltZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRpbWdzW2ldW09GSV0gPSBpbWdzW2ldW09GSV0gfHwge1xuXHRcdFx0c2tpcFRlc3Q6IG9wdHMuc2tpcFRlc3Rcblx0XHR9O1xuXHRcdGZpeE9uZShpbWdzW2ldKTtcblx0fVxuXG5cdGlmIChzdGFydEF1dG9Nb2RlKSB7XG5cdFx0ZG9jdW1lbnQuYm9keS5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdGlmIChlLnRhcmdldC50YWdOYW1lID09PSAnSU1HJykge1xuXHRcdFx0XHRmaXgoZS50YXJnZXQsIHtcblx0XHRcdFx0XHRza2lwVGVzdDogb3B0cy5za2lwVGVzdFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9LCB0cnVlKTtcblx0XHRhdXRvTW9kZUVuYWJsZWQgPSB0cnVlO1xuXHRcdGltZ3MgPSAnaW1nJzsgLy8gcmVzZXQgdG8gYSBnZW5lcmljIHNlbGVjdG9yIGZvciB3YXRjaE1RXG5cdH1cblxuXHQvLyBpZiByZXF1ZXN0ZWQsIHdhdGNoIG1lZGlhIHF1ZXJpZXMgZm9yIG9iamVjdC1maXQgY2hhbmdlXG5cdGlmIChvcHRzLndhdGNoTVEpIHtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgZml4LmJpbmQobnVsbCwgaW1ncywge1xuXHRcdFx0c2tpcFRlc3Q6IG9wdHMuc2tpcFRlc3Rcblx0XHR9KSk7XG5cdH1cbn1cblxuZml4LnN1cHBvcnRzT2JqZWN0Rml0ID0gc3VwcG9ydHNPYmplY3RGaXQ7XG5maXguc3VwcG9ydHNPYmplY3RQb3NpdGlvbiA9IHN1cHBvcnRzT2JqZWN0UG9zaXRpb247XG5cbmhpamFja0F0dHJpYnV0ZXMoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmaXg7XG4iLCIvKiEgcGljdHVyZWZpbGwgLSB2My4wLjIgLSAyMDE2LTAyLTEyXG4gKiBodHRwczovL3Njb3R0amVobC5naXRodWIuaW8vcGljdHVyZWZpbGwvXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgaHR0cHM6Ly9naXRodWIuY29tL3Njb3R0amVobC9waWN0dXJlZmlsbC9ibG9iL21hc3Rlci9BdXRob3JzLnR4dDsgTGljZW5zZWQgTUlUXG4gKi9cbi8qISBHZWNrby1QaWN0dXJlIC0gdjEuMFxuICogaHR0cHM6Ly9naXRodWIuY29tL3Njb3R0amVobC9waWN0dXJlZmlsbC90cmVlLzMuMC9zcmMvcGx1Z2lucy9nZWNrby1waWN0dXJlXG4gKiBGaXJlZm94J3MgZWFybHkgcGljdHVyZSBpbXBsZW1lbnRhdGlvbiAocHJpb3IgdG8gRkY0MSkgaXMgc3RhdGljIGFuZCBkb2VzXG4gKiBub3QgcmVhY3QgdG8gdmlld3BvcnQgY2hhbmdlcy4gVGhpcyB0aW55IG1vZHVsZSBmaXhlcyB0aGlzLlxuICovXG4oZnVuY3Rpb24od2luZG93KSB7XG5cdC8qanNoaW50IGVxbnVsbDp0cnVlICovXG5cdHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG5cblx0aWYgKCB3aW5kb3cuSFRNTFBpY3R1cmVFbGVtZW50ICYmICgoL2Vja28vKS50ZXN0KHVhKSAmJiB1YS5tYXRjaCgvcnZcXDooXFxkKykvKSAmJiBSZWdFeHAuJDEgPCA0NSkgKSB7XG5cdFx0YWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCAoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdGltZXI7XG5cblx0XHRcdHZhciBkdW1teVNyYyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzb3VyY2VcIik7XG5cblx0XHRcdHZhciBmaXhSZXNwaW1nID0gZnVuY3Rpb24oaW1nKSB7XG5cdFx0XHRcdHZhciBzb3VyY2UsIHNpemVzO1xuXHRcdFx0XHR2YXIgcGljdHVyZSA9IGltZy5wYXJlbnROb2RlO1xuXG5cdFx0XHRcdGlmIChwaWN0dXJlLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiUElDVFVSRVwiKSB7XG5cdFx0XHRcdFx0c291cmNlID0gZHVtbXlTcmMuY2xvbmVOb2RlKCk7XG5cblx0XHRcdFx0XHRwaWN0dXJlLmluc2VydEJlZm9yZShzb3VyY2UsIHBpY3R1cmUuZmlyc3RFbGVtZW50Q2hpbGQpO1xuXHRcdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRwaWN0dXJlLnJlbW92ZUNoaWxkKHNvdXJjZSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIWltZy5fcGZMYXN0U2l6ZSB8fCBpbWcub2Zmc2V0V2lkdGggPiBpbWcuX3BmTGFzdFNpemUpIHtcblx0XHRcdFx0XHRpbWcuX3BmTGFzdFNpemUgPSBpbWcub2Zmc2V0V2lkdGg7XG5cdFx0XHRcdFx0c2l6ZXMgPSBpbWcuc2l6ZXM7XG5cdFx0XHRcdFx0aW1nLnNpemVzICs9IFwiLDEwMHZ3XCI7XG5cdFx0XHRcdFx0c2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGltZy5zaXplcyA9IHNpemVzO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHR2YXIgZmluZFBpY3R1cmVJbWdzID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBpO1xuXHRcdFx0XHR2YXIgaW1ncyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJwaWN0dXJlID4gaW1nLCBpbWdbc3Jjc2V0XVtzaXplc11cIik7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBpbWdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0Zml4UmVzcGltZyhpbWdzW2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdHZhciBvblJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRjbGVhclRpbWVvdXQodGltZXIpO1xuXHRcdFx0XHR0aW1lciA9IHNldFRpbWVvdXQoZmluZFBpY3R1cmVJbWdzLCA5OSk7XG5cdFx0XHR9O1xuXHRcdFx0dmFyIG1xID0gd2luZG93Lm1hdGNoTWVkaWEgJiYgbWF0Y2hNZWRpYShcIihvcmllbnRhdGlvbjogbGFuZHNjYXBlKVwiKTtcblx0XHRcdHZhciBpbml0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdG9uUmVzaXplKCk7XG5cblx0XHRcdFx0aWYgKG1xICYmIG1xLmFkZExpc3RlbmVyKSB7XG5cdFx0XHRcdFx0bXEuYWRkTGlzdGVuZXIob25SZXNpemUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHRkdW1teVNyYy5zcmNzZXQgPSBcImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEFRQUJBQUFBQUNINUJBRUtBQUVBTEFBQUFBQUJBQUVBQUFJQ1RBRUFPdz09XCI7XG5cblx0XHRcdGlmICgvXltjfGldfGQkLy50ZXN0KGRvY3VtZW50LnJlYWR5U3RhdGUgfHwgXCJcIikpIHtcblx0XHRcdFx0aW5pdCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgaW5pdCk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvblJlc2l6ZTtcblx0XHR9KSgpKTtcblx0fVxufSkod2luZG93KTtcblxuLyohIFBpY3R1cmVmaWxsIC0gdjMuMC4yXG4gKiBodHRwOi8vc2NvdHRqZWhsLmdpdGh1Yi5pby9waWN0dXJlZmlsbFxuICogQ29weXJpZ2h0IChjKSAyMDE1IGh0dHBzOi8vZ2l0aHViLmNvbS9zY290dGplaGwvcGljdHVyZWZpbGwvYmxvYi9tYXN0ZXIvQXV0aG9ycy50eHQ7XG4gKiAgTGljZW5zZTogTUlUXG4gKi9cblxuKGZ1bmN0aW9uKCB3aW5kb3csIGRvY3VtZW50LCB1bmRlZmluZWQgKSB7XG5cdC8vIEVuYWJsZSBzdHJpY3QgbW9kZVxuXHRcInVzZSBzdHJpY3RcIjtcblxuXHQvLyBIVE1MIHNoaW18diBpdCBmb3Igb2xkIElFIChJRTkgd2lsbCBzdGlsbCBuZWVkIHRoZSBIVE1MIHZpZGVvIHRhZyB3b3JrYXJvdW5kKVxuXHRkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInBpY3R1cmVcIiApO1xuXG5cdHZhciB3YXJuLCBlbWlucHgsIGFsd2F5c0NoZWNrV0Rlc2NyaXB0b3IsIGV2YWxJZDtcblx0Ly8gbG9jYWwgb2JqZWN0IGZvciBtZXRob2QgcmVmZXJlbmNlcyBhbmQgdGVzdGluZyBleHBvc3VyZVxuXHR2YXIgcGYgPSB7fTtcblx0dmFyIGlzU3VwcG9ydFRlc3RSZWFkeSA9IGZhbHNlO1xuXHR2YXIgbm9vcCA9IGZ1bmN0aW9uKCkge307XG5cdHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW1nXCIgKTtcblx0dmFyIGdldEltZ0F0dHIgPSBpbWFnZS5nZXRBdHRyaWJ1dGU7XG5cdHZhciBzZXRJbWdBdHRyID0gaW1hZ2Uuc2V0QXR0cmlidXRlO1xuXHR2YXIgcmVtb3ZlSW1nQXR0ciA9IGltYWdlLnJlbW92ZUF0dHJpYnV0ZTtcblx0dmFyIGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cdHZhciB0eXBlcyA9IHt9O1xuXHR2YXIgY2ZnID0ge1xuXHRcdC8vcmVzb3VyY2Ugc2VsZWN0aW9uOlxuXHRcdGFsZ29yaXRobTogXCJcIlxuXHR9O1xuXHR2YXIgc3JjQXR0ciA9IFwiZGF0YS1wZnNyY1wiO1xuXHR2YXIgc3Jjc2V0QXR0ciA9IHNyY0F0dHIgKyBcInNldFwiO1xuXHQvLyB1YSBzbmlmZmluZyBpcyBkb25lIGZvciB1bmRldGVjdGFibGUgaW1nIGxvYWRpbmcgZmVhdHVyZXMsXG5cdC8vIHRvIGRvIHNvbWUgbm9uIGNydWNpYWwgcGVyZiBvcHRpbWl6YXRpb25zXG5cdHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG5cdHZhciBzdXBwb3J0QWJvcnQgPSAoL3JpZGVudC8pLnRlc3QodWEpIHx8ICgoL2Vja28vKS50ZXN0KHVhKSAmJiB1YS5tYXRjaCgvcnZcXDooXFxkKykvKSAmJiBSZWdFeHAuJDEgPiAzNSApO1xuXHR2YXIgY3VyU3JjUHJvcCA9IFwiY3VycmVudFNyY1wiO1xuXHR2YXIgcmVnV0Rlc2MgPSAvXFxzK1xcKz9cXGQrKGVcXGQrKT93Lztcblx0dmFyIHJlZ1NpemUgPSAvKFxcKFteKV0rXFwpKT9cXHMqKC4rKS87XG5cdHZhciBzZXRPcHRpb25zID0gd2luZG93LnBpY3R1cmVmaWxsQ0ZHO1xuXHQvKipcblx0ICogU2hvcnRjdXQgcHJvcGVydHkgZm9yIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJhcHBzZWMvc3BlY3MvbWl4ZWRjb250ZW50LyNyZXN0cmljdHMtbWl4ZWQtY29udGVudCAoIGZvciBlYXN5IG92ZXJyaWRpbmcgaW4gdGVzdHMgKVxuXHQgKi9cblx0Ly8gYmFzZVN0eWxlIGFsc28gdXNlZCBieSBnZXRFbVZhbHVlIChpLmUuOiB3aWR0aDogMWVtIGlzIGltcG9ydGFudClcblx0dmFyIGJhc2VTdHlsZSA9IFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3Zpc2liaWxpdHk6aGlkZGVuO2Rpc3BsYXk6YmxvY2s7cGFkZGluZzowO2JvcmRlcjpub25lO2ZvbnQtc2l6ZToxZW07d2lkdGg6MWVtO292ZXJmbG93OmhpZGRlbjtjbGlwOnJlY3QoMHB4LCAwcHgsIDBweCwgMHB4KVwiO1xuXHR2YXIgZnNDc3MgPSBcImZvbnQtc2l6ZToxMDAlIWltcG9ydGFudDtcIjtcblx0dmFyIGlzVndEaXJ0eSA9IHRydWU7XG5cblx0dmFyIGNzc0NhY2hlID0ge307XG5cdHZhciBzaXplTGVuZ3RoQ2FjaGUgPSB7fTtcblx0dmFyIERQUiA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuXHR2YXIgdW5pdHMgPSB7XG5cdFx0cHg6IDEsXG5cdFx0XCJpblwiOiA5NlxuXHR9O1xuXHR2YXIgYW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcblx0LyoqXG5cdCAqIGFscmVhZHlSdW4gZmxhZyB1c2VkIGZvciBzZXRPcHRpb25zLiBpcyBpdCB0cnVlIHNldE9wdGlvbnMgd2lsbCByZWV2YWx1YXRlXG5cdCAqIEB0eXBlIHtib29sZWFufVxuXHQgKi9cblx0dmFyIGFscmVhZHlSdW4gPSBmYWxzZTtcblxuXHQvLyBSZXVzYWJsZSwgbm9uLVwiZ1wiIFJlZ2V4ZXNcblxuXHQvLyAoRG9uJ3QgdXNlIFxccywgdG8gYXZvaWQgbWF0Y2hpbmcgbm9uLWJyZWFraW5nIHNwYWNlLilcblx0dmFyIHJlZ2V4TGVhZGluZ1NwYWNlcyA9IC9eWyBcXHRcXG5cXHJcXHUwMDBjXSsvLFxuXHQgICAgcmVnZXhMZWFkaW5nQ29tbWFzT3JTcGFjZXMgPSAvXlssIFxcdFxcblxcclxcdTAwMGNdKy8sXG5cdCAgICByZWdleExlYWRpbmdOb3RTcGFjZXMgPSAvXlteIFxcdFxcblxcclxcdTAwMGNdKy8sXG5cdCAgICByZWdleFRyYWlsaW5nQ29tbWFzID0gL1ssXSskLyxcblx0ICAgIHJlZ2V4Tm9uTmVnYXRpdmVJbnRlZ2VyID0gL15cXGQrJC8sXG5cblx0ICAgIC8vICggUG9zaXRpdmUgb3IgbmVnYXRpdmUgb3IgdW5zaWduZWQgaW50ZWdlcnMgb3IgZGVjaW1hbHMsIHdpdGhvdXQgb3Igd2l0aG91dCBleHBvbmVudHMuXG5cdCAgICAvLyBNdXN0IGluY2x1ZGUgYXQgbGVhc3Qgb25lIGRpZ2l0LlxuXHQgICAgLy8gQWNjb3JkaW5nIHRvIHNwZWMgdGVzdHMgYW55IGRlY2ltYWwgcG9pbnQgbXVzdCBiZSBmb2xsb3dlZCBieSBhIGRpZ2l0LlxuXHQgICAgLy8gTm8gbGVhZGluZyBwbHVzIHNpZ24gaXMgYWxsb3dlZC4pXG5cdCAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9pbmZyYXN0cnVjdHVyZS5odG1sI3ZhbGlkLWZsb2F0aW5nLXBvaW50LW51bWJlclxuXHQgICAgcmVnZXhGbG9hdGluZ1BvaW50ID0gL14tPyg/OlswLTldK3xbMC05XSpcXC5bMC05XSspKD86W2VFXVsrLV0/WzAtOV0rKT8kLztcblxuXHR2YXIgb24gPSBmdW5jdGlvbihvYmosIGV2dCwgZm4sIGNhcHR1cmUpIHtcblx0XHRpZiAoIG9iai5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0b2JqLmFkZEV2ZW50TGlzdGVuZXIoZXZ0LCBmbiwgY2FwdHVyZSB8fCBmYWxzZSk7XG5cdFx0fSBlbHNlIGlmICggb2JqLmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0b2JqLmF0dGFjaEV2ZW50KCBcIm9uXCIgKyBldnQsIGZuKTtcblx0XHR9XG5cdH07XG5cblx0LyoqXG5cdCAqIHNpbXBsZSBtZW1vaXplIGZ1bmN0aW9uOlxuXHQgKi9cblxuXHR2YXIgbWVtb2l6ZSA9IGZ1bmN0aW9uKGZuKSB7XG5cdFx0dmFyIGNhY2hlID0ge307XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGlucHV0KSB7XG5cdFx0XHRpZiAoICEoaW5wdXQgaW4gY2FjaGUpICkge1xuXHRcdFx0XHRjYWNoZVsgaW5wdXQgXSA9IGZuKGlucHV0KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBjYWNoZVsgaW5wdXQgXTtcblx0XHR9O1xuXHR9O1xuXG5cdC8vIFVUSUxJVFkgRlVOQ1RJT05TXG5cblx0Ly8gTWFudWFsIGlzIGZhc3RlciB0aGFuIFJlZ0V4XG5cdC8vIGh0dHA6Ly9qc3BlcmYuY29tL3doaXRlc3BhY2UtY2hhcmFjdGVyLzVcblx0ZnVuY3Rpb24gaXNTcGFjZShjKSB7XG5cdFx0cmV0dXJuIChjID09PSBcIlxcdTAwMjBcIiB8fCAvLyBzcGFjZVxuXHRcdCAgICAgICAgYyA9PT0gXCJcXHUwMDA5XCIgfHwgLy8gaG9yaXpvbnRhbCB0YWJcblx0XHQgICAgICAgIGMgPT09IFwiXFx1MDAwQVwiIHx8IC8vIG5ldyBsaW5lXG5cdFx0ICAgICAgICBjID09PSBcIlxcdTAwMENcIiB8fCAvLyBmb3JtIGZlZWRcblx0XHQgICAgICAgIGMgPT09IFwiXFx1MDAwRFwiKTsgIC8vIGNhcnJpYWdlIHJldHVyblxuXHR9XG5cblx0LyoqXG5cdCAqIGdldHMgYSBtZWRpYXF1ZXJ5IGFuZCByZXR1cm5zIGEgYm9vbGVhbiBvciBnZXRzIGEgY3NzIGxlbmd0aCBhbmQgcmV0dXJucyBhIG51bWJlclxuXHQgKiBAcGFyYW0gY3NzIG1lZGlhcXVlcmllcyBvciBjc3MgbGVuZ3RoXG5cdCAqIEByZXR1cm5zIHtib29sZWFufG51bWJlcn1cblx0ICpcblx0ICogYmFzZWQgb246IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2pvbmF0aGFudG5lYWwvZGI0Zjc3MDA5YjE1NWYwODM3Mzhcblx0ICovXG5cdHZhciBldmFsQ1NTID0gKGZ1bmN0aW9uKCkge1xuXG5cdFx0dmFyIHJlZ0xlbmd0aCA9IC9eKFtcXGRcXC5dKykoZW18dnd8cHgpJC87XG5cdFx0dmFyIHJlcGxhY2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBhcmdzID0gYXJndW1lbnRzLCBpbmRleCA9IDAsIHN0cmluZyA9IGFyZ3NbMF07XG5cdFx0XHR3aGlsZSAoKytpbmRleCBpbiBhcmdzKSB7XG5cdFx0XHRcdHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKGFyZ3NbaW5kZXhdLCBhcmdzWysraW5kZXhdKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBzdHJpbmc7XG5cdFx0fTtcblxuXHRcdHZhciBidWlsZFN0ciA9IG1lbW9pemUoZnVuY3Rpb24oY3NzKSB7XG5cblx0XHRcdHJldHVybiBcInJldHVybiBcIiArIHJlcGxhY2UoKGNzcyB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHQvLyBpbnRlcnByZXQgYGFuZGBcblx0XHRcdFx0L1xcYmFuZFxcYi9nLCBcIiYmXCIsXG5cblx0XHRcdFx0Ly8gaW50ZXJwcmV0IGAsYFxuXHRcdFx0XHQvLC9nLCBcInx8XCIsXG5cblx0XHRcdFx0Ly8gaW50ZXJwcmV0IGBtaW4tYCBhcyA+PVxuXHRcdFx0XHQvbWluLShbYS16LVxcc10rKTovZywgXCJlLiQxPj1cIixcblxuXHRcdFx0XHQvLyBpbnRlcnByZXQgYG1heC1gIGFzIDw9XG5cdFx0XHRcdC9tYXgtKFthLXotXFxzXSspOi9nLCBcImUuJDE8PVwiLFxuXG5cdFx0XHRcdC8vY2FsYyB2YWx1ZVxuXHRcdFx0XHQvY2FsYyhbXildKykvZywgXCIoJDEpXCIsXG5cblx0XHRcdFx0Ly8gaW50ZXJwcmV0IGNzcyB2YWx1ZXNcblx0XHRcdFx0LyhcXGQrW1xcLl0qW1xcZF0qKShbYS16XSspL2csIFwiKCQxICogZS4kMilcIixcblx0XHRcdFx0Ly9tYWtlIGV2YWwgbGVzcyBldmlsXG5cdFx0XHRcdC9eKD8hKGUuW2Etel18WzAtOVxcLiY9fD48XFwrXFwtXFwqXFwoXFwpXFwvXSkpLiovaWcsIFwiXCJcblx0XHRcdCkgKyBcIjtcIjtcblx0XHR9KTtcblxuXHRcdHJldHVybiBmdW5jdGlvbihjc3MsIGxlbmd0aCkge1xuXHRcdFx0dmFyIHBhcnNlZExlbmd0aDtcblx0XHRcdGlmICghKGNzcyBpbiBjc3NDYWNoZSkpIHtcblx0XHRcdFx0Y3NzQ2FjaGVbY3NzXSA9IGZhbHNlO1xuXHRcdFx0XHRpZiAobGVuZ3RoICYmIChwYXJzZWRMZW5ndGggPSBjc3MubWF0Y2goIHJlZ0xlbmd0aCApKSkge1xuXHRcdFx0XHRcdGNzc0NhY2hlW2Nzc10gPSBwYXJzZWRMZW5ndGhbIDEgXSAqIHVuaXRzW3BhcnNlZExlbmd0aFsgMiBdXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvKmpzaGludCBldmlsOnRydWUgKi9cblx0XHRcdFx0XHR0cnl7XG5cdFx0XHRcdFx0XHRjc3NDYWNoZVtjc3NdID0gbmV3IEZ1bmN0aW9uKFwiZVwiLCBidWlsZFN0cihjc3MpKSh1bml0cyk7XG5cdFx0XHRcdFx0fSBjYXRjaChlKSB7fVxuXHRcdFx0XHRcdC8qanNoaW50IGV2aWw6ZmFsc2UgKi9cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGNzc0NhY2hlW2Nzc107XG5cdFx0fTtcblx0fSkoKTtcblxuXHR2YXIgc2V0UmVzb2x1dGlvbiA9IGZ1bmN0aW9uKCBjYW5kaWRhdGUsIHNpemVzYXR0ciApIHtcblx0XHRpZiAoIGNhbmRpZGF0ZS53ICkgeyAvLyBoID0gbWVhbnMgaGVpZ2h0OiB8fCBkZXNjcmlwdG9yLnR5cGUgPT09ICdoJyBkbyBub3QgaGFuZGxlIHlldC4uLlxuXHRcdFx0Y2FuZGlkYXRlLmNXaWR0aCA9IHBmLmNhbGNMaXN0TGVuZ3RoKCBzaXplc2F0dHIgfHwgXCIxMDB2d1wiICk7XG5cdFx0XHRjYW5kaWRhdGUucmVzID0gY2FuZGlkYXRlLncgLyBjYW5kaWRhdGUuY1dpZHRoIDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2FuZGlkYXRlLnJlcyA9IGNhbmRpZGF0ZS5kO1xuXHRcdH1cblx0XHRyZXR1cm4gY2FuZGlkYXRlO1xuXHR9O1xuXG5cdC8qKlxuXHQgKlxuXHQgKiBAcGFyYW0gb3B0XG5cdCAqL1xuXHR2YXIgcGljdHVyZWZpbGwgPSBmdW5jdGlvbiggb3B0ICkge1xuXG5cdFx0aWYgKCFpc1N1cHBvcnRUZXN0UmVhZHkpIHtyZXR1cm47fVxuXG5cdFx0dmFyIGVsZW1lbnRzLCBpLCBwbGVuO1xuXG5cdFx0dmFyIG9wdGlvbnMgPSBvcHQgfHwge307XG5cblx0XHRpZiAoIG9wdGlvbnMuZWxlbWVudHMgJiYgb3B0aW9ucy5lbGVtZW50cy5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdGlmICggb3B0aW9ucy5lbGVtZW50cy5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09PSBcIklNR1wiICkge1xuXHRcdFx0XHRvcHRpb25zLmVsZW1lbnRzID0gIFsgb3B0aW9ucy5lbGVtZW50cyBdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3B0aW9ucy5jb250ZXh0ID0gb3B0aW9ucy5lbGVtZW50cztcblx0XHRcdFx0b3B0aW9ucy5lbGVtZW50cyA9ICBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGVsZW1lbnRzID0gb3B0aW9ucy5lbGVtZW50cyB8fCBwZi5xc2EoIChvcHRpb25zLmNvbnRleHQgfHwgZG9jdW1lbnQpLCAoIG9wdGlvbnMucmVldmFsdWF0ZSB8fCBvcHRpb25zLnJlc2VsZWN0ICkgPyBwZi5zZWwgOiBwZi5zZWxTaG9ydCApO1xuXG5cdFx0aWYgKCAocGxlbiA9IGVsZW1lbnRzLmxlbmd0aCkgKSB7XG5cblx0XHRcdHBmLnNldHVwUnVuKCBvcHRpb25zICk7XG5cdFx0XHRhbHJlYWR5UnVuID0gdHJ1ZTtcblxuXHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCBlbGVtZW50c1xuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBwbGVuOyBpKysgKSB7XG5cdFx0XHRcdHBmLmZpbGxJbWcoZWxlbWVudHNbIGkgXSwgb3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdHBmLnRlYXJkb3duUnVuKCBvcHRpb25zICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qKlxuXHQgKiBvdXRwdXRzIGEgd2FybmluZyBmb3IgdGhlIGRldmVsb3BlclxuXHQgKiBAcGFyYW0ge21lc3NhZ2V9XG5cdCAqIEB0eXBlIHtGdW5jdGlvbn1cblx0ICovXG5cdHdhcm4gPSAoIHdpbmRvdy5jb25zb2xlICYmIGNvbnNvbGUud2FybiApID9cblx0XHRmdW5jdGlvbiggbWVzc2FnZSApIHtcblx0XHRcdGNvbnNvbGUud2FybiggbWVzc2FnZSApO1xuXHRcdH0gOlxuXHRcdG5vb3Bcblx0O1xuXG5cdGlmICggIShjdXJTcmNQcm9wIGluIGltYWdlKSApIHtcblx0XHRjdXJTcmNQcm9wID0gXCJzcmNcIjtcblx0fVxuXG5cdC8vIEFkZCBzdXBwb3J0IGZvciBzdGFuZGFyZCBtaW1lIHR5cGVzLlxuXHR0eXBlc1sgXCJpbWFnZS9qcGVnXCIgXSA9IHRydWU7XG5cdHR5cGVzWyBcImltYWdlL2dpZlwiIF0gPSB0cnVlO1xuXHR0eXBlc1sgXCJpbWFnZS9wbmdcIiBdID0gdHJ1ZTtcblxuXHRmdW5jdGlvbiBkZXRlY3RUeXBlU3VwcG9ydCggdHlwZSwgdHlwZVVyaSApIHtcblx0XHQvLyBiYXNlZCBvbiBNb2Rlcm5penIncyBsb3NzbGVzcyBpbWctd2VicCB0ZXN0XG5cdFx0Ly8gbm90ZTogYXN5bmNocm9ub3VzXG5cdFx0dmFyIGltYWdlID0gbmV3IHdpbmRvdy5JbWFnZSgpO1xuXHRcdGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcblx0XHRcdHR5cGVzWyB0eXBlIF0gPSBmYWxzZTtcblx0XHRcdHBpY3R1cmVmaWxsKCk7XG5cdFx0fTtcblx0XHRpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdHR5cGVzWyB0eXBlIF0gPSBpbWFnZS53aWR0aCA9PT0gMTtcblx0XHRcdHBpY3R1cmVmaWxsKCk7XG5cdFx0fTtcblx0XHRpbWFnZS5zcmMgPSB0eXBlVXJpO1xuXHRcdHJldHVybiBcInBlbmRpbmdcIjtcblx0fVxuXG5cdC8vIHRlc3Qgc3ZnIHN1cHBvcnRcblx0dHlwZXNbIFwiaW1hZ2Uvc3ZnK3htbFwiIF0gPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5oYXNGZWF0dXJlKCBcImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjSW1hZ2VcIiwgXCIxLjFcIiApO1xuXG5cdC8qKlxuXHQgKiB1cGRhdGVzIHRoZSBpbnRlcm5hbCB2VyBwcm9wZXJ0eSB3aXRoIHRoZSBjdXJyZW50IHZpZXdwb3J0IHdpZHRoIGluIHB4XG5cdCAqL1xuXHRmdW5jdGlvbiB1cGRhdGVNZXRyaWNzKCkge1xuXG5cdFx0aXNWd0RpcnR5ID0gZmFsc2U7XG5cdFx0RFBSID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG5cdFx0Y3NzQ2FjaGUgPSB7fTtcblx0XHRzaXplTGVuZ3RoQ2FjaGUgPSB7fTtcblxuXHRcdHBmLkRQUiA9IERQUiB8fCAxO1xuXG5cdFx0dW5pdHMud2lkdGggPSBNYXRoLm1heCh3aW5kb3cuaW5uZXJXaWR0aCB8fCAwLCBkb2NFbGVtLmNsaWVudFdpZHRoKTtcblx0XHR1bml0cy5oZWlnaHQgPSBNYXRoLm1heCh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgMCwgZG9jRWxlbS5jbGllbnRIZWlnaHQpO1xuXG5cdFx0dW5pdHMudncgPSB1bml0cy53aWR0aCAvIDEwMDtcblx0XHR1bml0cy52aCA9IHVuaXRzLmhlaWdodCAvIDEwMDtcblxuXHRcdGV2YWxJZCA9IFsgdW5pdHMuaGVpZ2h0LCB1bml0cy53aWR0aCwgRFBSIF0uam9pbihcIi1cIik7XG5cblx0XHR1bml0cy5lbSA9IHBmLmdldEVtVmFsdWUoKTtcblx0XHR1bml0cy5yZW0gPSB1bml0cy5lbTtcblx0fVxuXG5cdGZ1bmN0aW9uIGNob29zZUxvd1JlcyggbG93ZXJWYWx1ZSwgaGlnaGVyVmFsdWUsIGRwclZhbHVlLCBpc0NhY2hlZCApIHtcblx0XHR2YXIgYm9udXNGYWN0b3IsIHRvb011Y2gsIGJvbnVzLCBtZWFuRGVuc2l0eTtcblxuXHRcdC8vZXhwZXJpbWVudGFsXG5cdFx0aWYgKGNmZy5hbGdvcml0aG0gPT09IFwic2F2ZURhdGFcIiApe1xuXHRcdFx0aWYgKCBsb3dlclZhbHVlID4gMi43ICkge1xuXHRcdFx0XHRtZWFuRGVuc2l0eSA9IGRwclZhbHVlICsgMTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRvb011Y2ggPSBoaWdoZXJWYWx1ZSAtIGRwclZhbHVlO1xuXHRcdFx0XHRib251c0ZhY3RvciA9IE1hdGgucG93KGxvd2VyVmFsdWUgLSAwLjYsIDEuNSk7XG5cblx0XHRcdFx0Ym9udXMgPSB0b29NdWNoICogYm9udXNGYWN0b3I7XG5cblx0XHRcdFx0aWYgKGlzQ2FjaGVkKSB7XG5cdFx0XHRcdFx0Ym9udXMgKz0gMC4xICogYm9udXNGYWN0b3I7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRtZWFuRGVuc2l0eSA9IGxvd2VyVmFsdWUgKyBib251cztcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0bWVhbkRlbnNpdHkgPSAoZHByVmFsdWUgPiAxKSA/XG5cdFx0XHRcdE1hdGguc3FydChsb3dlclZhbHVlICogaGlnaGVyVmFsdWUpIDpcblx0XHRcdFx0bG93ZXJWYWx1ZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWVhbkRlbnNpdHkgPiBkcHJWYWx1ZTtcblx0fVxuXG5cdGZ1bmN0aW9uIGFwcGx5QmVzdENhbmRpZGF0ZSggaW1nICkge1xuXHRcdHZhciBzcmNTZXRDYW5kaWRhdGVzO1xuXHRcdHZhciBtYXRjaGluZ1NldCA9IHBmLmdldFNldCggaW1nICk7XG5cdFx0dmFyIGV2YWx1YXRlZCA9IGZhbHNlO1xuXHRcdGlmICggbWF0Y2hpbmdTZXQgIT09IFwicGVuZGluZ1wiICkge1xuXHRcdFx0ZXZhbHVhdGVkID0gZXZhbElkO1xuXHRcdFx0aWYgKCBtYXRjaGluZ1NldCApIHtcblx0XHRcdFx0c3JjU2V0Q2FuZGlkYXRlcyA9IHBmLnNldFJlcyggbWF0Y2hpbmdTZXQgKTtcblx0XHRcdFx0cGYuYXBwbHlTZXRDYW5kaWRhdGUoIHNyY1NldENhbmRpZGF0ZXMsIGltZyApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpbWdbIHBmLm5zIF0uZXZhbGVkID0gZXZhbHVhdGVkO1xuXHR9XG5cblx0ZnVuY3Rpb24gYXNjZW5kaW5nU29ydCggYSwgYiApIHtcblx0XHRyZXR1cm4gYS5yZXMgLSBiLnJlcztcblx0fVxuXG5cdGZ1bmN0aW9uIHNldFNyY1RvQ3VyKCBpbWcsIHNyYywgc2V0ICkge1xuXHRcdHZhciBjYW5kaWRhdGU7XG5cdFx0aWYgKCAhc2V0ICYmIHNyYyApIHtcblx0XHRcdHNldCA9IGltZ1sgcGYubnMgXS5zZXRzO1xuXHRcdFx0c2V0ID0gc2V0ICYmIHNldFtzZXQubGVuZ3RoIC0gMV07XG5cdFx0fVxuXG5cdFx0Y2FuZGlkYXRlID0gZ2V0Q2FuZGlkYXRlRm9yU3JjKHNyYywgc2V0KTtcblxuXHRcdGlmICggY2FuZGlkYXRlICkge1xuXHRcdFx0c3JjID0gcGYubWFrZVVybChzcmMpO1xuXHRcdFx0aW1nWyBwZi5ucyBdLmN1clNyYyA9IHNyYztcblx0XHRcdGltZ1sgcGYubnMgXS5jdXJDYW4gPSBjYW5kaWRhdGU7XG5cblx0XHRcdGlmICggIWNhbmRpZGF0ZS5yZXMgKSB7XG5cdFx0XHRcdHNldFJlc29sdXRpb24oIGNhbmRpZGF0ZSwgY2FuZGlkYXRlLnNldC5zaXplcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FuZGlkYXRlO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2V0Q2FuZGlkYXRlRm9yU3JjKCBzcmMsIHNldCApIHtcblx0XHR2YXIgaSwgY2FuZGlkYXRlLCBjYW5kaWRhdGVzO1xuXHRcdGlmICggc3JjICYmIHNldCApIHtcblx0XHRcdGNhbmRpZGF0ZXMgPSBwZi5wYXJzZVNldCggc2V0ICk7XG5cdFx0XHRzcmMgPSBwZi5tYWtlVXJsKHNyYyk7XG5cdFx0XHRmb3IgKCBpID0gMDsgaSA8IGNhbmRpZGF0ZXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggc3JjID09PSBwZi5tYWtlVXJsKGNhbmRpZGF0ZXNbIGkgXS51cmwpICkge1xuXHRcdFx0XHRcdGNhbmRpZGF0ZSA9IGNhbmRpZGF0ZXNbIGkgXTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FuZGlkYXRlO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2V0QWxsU291cmNlRWxlbWVudHMoIHBpY3R1cmUsIGNhbmRpZGF0ZXMgKSB7XG5cdFx0dmFyIGksIGxlbiwgc291cmNlLCBzcmNzZXQ7XG5cblx0XHQvLyBTUEVDIG1pc21hdGNoIGludGVuZGVkIGZvciBzaXplIGFuZCBwZXJmOlxuXHRcdC8vIGFjdHVhbGx5IG9ubHkgc291cmNlIGVsZW1lbnRzIHByZWNlZGluZyB0aGUgaW1nIHNob3VsZCBiZSB1c2VkXG5cdFx0Ly8gYWxzbyBub3RlOiBkb24ndCB1c2UgcXNhIGhlcmUsIGJlY2F1c2UgSUU4IHNvbWV0aW1lcyBkb2Vzbid0IGxpa2Ugc291cmNlIGFzIHRoZSBrZXkgcGFydCBpbiBhIHNlbGVjdG9yXG5cdFx0dmFyIHNvdXJjZXMgPSBwaWN0dXJlLmdldEVsZW1lbnRzQnlUYWdOYW1lKCBcInNvdXJjZVwiICk7XG5cblx0XHRmb3IgKCBpID0gMCwgbGVuID0gc291cmNlcy5sZW5ndGg7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdHNvdXJjZSA9IHNvdXJjZXNbIGkgXTtcblx0XHRcdHNvdXJjZVsgcGYubnMgXSA9IHRydWU7XG5cdFx0XHRzcmNzZXQgPSBzb3VyY2UuZ2V0QXR0cmlidXRlKCBcInNyY3NldFwiICk7XG5cblx0XHRcdC8vIGlmIHNvdXJjZSBkb2VzIG5vdCBoYXZlIGEgc3Jjc2V0IGF0dHJpYnV0ZSwgc2tpcFxuXHRcdFx0aWYgKCBzcmNzZXQgKSB7XG5cdFx0XHRcdGNhbmRpZGF0ZXMucHVzaCgge1xuXHRcdFx0XHRcdHNyY3NldDogc3Jjc2V0LFxuXHRcdFx0XHRcdG1lZGlhOiBzb3VyY2UuZ2V0QXR0cmlidXRlKCBcIm1lZGlhXCIgKSxcblx0XHRcdFx0XHR0eXBlOiBzb3VyY2UuZ2V0QXR0cmlidXRlKCBcInR5cGVcIiApLFxuXHRcdFx0XHRcdHNpemVzOiBzb3VyY2UuZ2V0QXR0cmlidXRlKCBcInNpemVzXCIgKVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNyY3NldCBQYXJzZXJcblx0ICogQnkgQWxleCBCZWxsIHwgIE1JVCBMaWNlbnNlXG5cdCAqXG5cdCAqIEByZXR1cm5zIEFycmF5IFt7dXJsOiBfLCBkOiBfLCB3OiBfLCBoOl8sIHNldDpfKD8/Pz8pfSwgLi4uXVxuXHQgKlxuXHQgKiBCYXNlZCBzdXBlciBkdXBlciBjbG9zZWx5IG9uIHRoZSByZWZlcmVuY2UgYWxnb3JpdGhtIGF0OlxuXHQgKiBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9lbWJlZGRlZC1jb250ZW50Lmh0bWwjcGFyc2UtYS1zcmNzZXQtYXR0cmlidXRlXG5cdCAqL1xuXG5cdC8vIDEuIExldCBpbnB1dCBiZSB0aGUgdmFsdWUgcGFzc2VkIHRvIHRoaXMgYWxnb3JpdGhtLlxuXHQvLyAoVE8tRE8gOiBFeHBsYWluIHdoYXQgXCJzZXRcIiBhcmd1bWVudCBpcyBoZXJlLiBNYXliZSBjaG9vc2UgYSBtb3JlXG5cdC8vIGRlc2NyaXB0aXZlICYgbW9yZSBzZWFyY2hhYmxlIG5hbWUuICBTaW5jZSBwYXNzaW5nIHRoZSBcInNldFwiIGluIHJlYWxseSBoYXNcblx0Ly8gbm90aGluZyB0byBkbyB3aXRoIHBhcnNpbmcgcHJvcGVyLCBJIHdvdWxkIHByZWZlciB0aGlzIGFzc2lnbm1lbnQgZXZlbnR1YWxseVxuXHQvLyBnbyBpbiBhbiBleHRlcm5hbCBmbi4pXG5cdGZ1bmN0aW9uIHBhcnNlU3Jjc2V0KGlucHV0LCBzZXQpIHtcblxuXHRcdGZ1bmN0aW9uIGNvbGxlY3RDaGFyYWN0ZXJzKHJlZ0V4KSB7XG5cdFx0XHR2YXIgY2hhcnMsXG5cdFx0XHQgICAgbWF0Y2ggPSByZWdFeC5leGVjKGlucHV0LnN1YnN0cmluZyhwb3MpKTtcblx0XHRcdGlmIChtYXRjaCkge1xuXHRcdFx0XHRjaGFycyA9IG1hdGNoWyAwIF07XG5cdFx0XHRcdHBvcyArPSBjaGFycy5sZW5ndGg7XG5cdFx0XHRcdHJldHVybiBjaGFycztcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgsXG5cdFx0ICAgIHVybCxcblx0XHQgICAgZGVzY3JpcHRvcnMsXG5cdFx0ICAgIGN1cnJlbnREZXNjcmlwdG9yLFxuXHRcdCAgICBzdGF0ZSxcblx0XHQgICAgYyxcblxuXHRcdCAgICAvLyAyLiBMZXQgcG9zaXRpb24gYmUgYSBwb2ludGVyIGludG8gaW5wdXQsIGluaXRpYWxseSBwb2ludGluZyBhdCB0aGUgc3RhcnRcblx0XHQgICAgLy8gICAgb2YgdGhlIHN0cmluZy5cblx0XHQgICAgcG9zID0gMCxcblxuXHRcdCAgICAvLyAzLiBMZXQgY2FuZGlkYXRlcyBiZSBhbiBpbml0aWFsbHkgZW1wdHkgc291cmNlIHNldC5cblx0XHQgICAgY2FuZGlkYXRlcyA9IFtdO1xuXG5cdFx0LyoqXG5cdFx0KiBBZGRzIGRlc2NyaXB0b3IgcHJvcGVydGllcyB0byBhIGNhbmRpZGF0ZSwgcHVzaGVzIHRvIHRoZSBjYW5kaWRhdGVzIGFycmF5XG5cdFx0KiBAcmV0dXJuIHVuZGVmaW5lZFxuXHRcdCovXG5cdFx0Ly8gKERlY2xhcmVkIG91dHNpZGUgb2YgdGhlIHdoaWxlIGxvb3Agc28gdGhhdCBpdCdzIG9ubHkgY3JlYXRlZCBvbmNlLlxuXHRcdC8vIChUaGlzIGZuIGlzIGRlZmluZWQgYmVmb3JlIGl0IGlzIHVzZWQsIGluIG9yZGVyIHRvIHBhc3MgSlNISU5ULlxuXHRcdC8vIFVuZm9ydHVuYXRlbHkgdGhpcyBicmVha3MgdGhlIHNlcXVlbmNpbmcgb2YgdGhlIHNwZWMgY29tbWVudHMuIDovIClcblx0XHRmdW5jdGlvbiBwYXJzZURlc2NyaXB0b3JzKCkge1xuXG5cdFx0XHQvLyA5LiBEZXNjcmlwdG9yIHBhcnNlcjogTGV0IGVycm9yIGJlIG5vLlxuXHRcdFx0dmFyIHBFcnJvciA9IGZhbHNlLFxuXG5cdFx0XHQvLyAxMC4gTGV0IHdpZHRoIGJlIGFic2VudC5cblx0XHRcdC8vIDExLiBMZXQgZGVuc2l0eSBiZSBhYnNlbnQuXG5cdFx0XHQvLyAxMi4gTGV0IGZ1dHVyZS1jb21wYXQtaCBiZSBhYnNlbnQuIChXZSdyZSBpbXBsZW1lbnRpbmcgaXQgbm93IGFzIGgpXG5cdFx0XHQgICAgdywgZCwgaCwgaSxcblx0XHRcdCAgICBjYW5kaWRhdGUgPSB7fSxcblx0XHRcdCAgICBkZXNjLCBsYXN0Q2hhciwgdmFsdWUsIGludFZhbCwgZmxvYXRWYWw7XG5cblx0XHRcdC8vIDEzLiBGb3IgZWFjaCBkZXNjcmlwdG9yIGluIGRlc2NyaXB0b3JzLCBydW4gdGhlIGFwcHJvcHJpYXRlIHNldCBvZiBzdGVwc1xuXHRcdFx0Ly8gZnJvbSB0aGUgZm9sbG93aW5nIGxpc3Q6XG5cdFx0XHRmb3IgKGkgPSAwIDsgaSA8IGRlc2NyaXB0b3JzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGRlc2MgPSBkZXNjcmlwdG9yc1sgaSBdO1xuXG5cdFx0XHRcdGxhc3RDaGFyID0gZGVzY1sgZGVzYy5sZW5ndGggLSAxIF07XG5cdFx0XHRcdHZhbHVlID0gZGVzYy5zdWJzdHJpbmcoMCwgZGVzYy5sZW5ndGggLSAxKTtcblx0XHRcdFx0aW50VmFsID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcblx0XHRcdFx0ZmxvYXRWYWwgPSBwYXJzZUZsb2F0KHZhbHVlKTtcblxuXHRcdFx0XHQvLyBJZiB0aGUgZGVzY3JpcHRvciBjb25zaXN0cyBvZiBhIHZhbGlkIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIGZvbGxvd2VkIGJ5XG5cdFx0XHRcdC8vIGEgVSswMDc3IExBVElOIFNNQUxMIExFVFRFUiBXIGNoYXJhY3RlclxuXHRcdFx0XHRpZiAocmVnZXhOb25OZWdhdGl2ZUludGVnZXIudGVzdCh2YWx1ZSkgJiYgKGxhc3RDaGFyID09PSBcIndcIikpIHtcblxuXHRcdFx0XHRcdC8vIElmIHdpZHRoIGFuZCBkZW5zaXR5IGFyZSBub3QgYm90aCBhYnNlbnQsIHRoZW4gbGV0IGVycm9yIGJlIHllcy5cblx0XHRcdFx0XHRpZiAodyB8fCBkKSB7cEVycm9yID0gdHJ1ZTt9XG5cblx0XHRcdFx0XHQvLyBBcHBseSB0aGUgcnVsZXMgZm9yIHBhcnNpbmcgbm9uLW5lZ2F0aXZlIGludGVnZXJzIHRvIHRoZSBkZXNjcmlwdG9yLlxuXHRcdFx0XHRcdC8vIElmIHRoZSByZXN1bHQgaXMgemVybywgbGV0IGVycm9yIGJlIHllcy5cblx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGxldCB3aWR0aCBiZSB0aGUgcmVzdWx0LlxuXHRcdFx0XHRcdGlmIChpbnRWYWwgPT09IDApIHtwRXJyb3IgPSB0cnVlO30gZWxzZSB7dyA9IGludFZhbDt9XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGRlc2NyaXB0b3IgY29uc2lzdHMgb2YgYSB2YWxpZCBmbG9hdGluZy1wb2ludCBudW1iZXIgZm9sbG93ZWQgYnlcblx0XHRcdFx0Ly8gYSBVKzAwNzggTEFUSU4gU01BTEwgTEVUVEVSIFggY2hhcmFjdGVyXG5cdFx0XHRcdH0gZWxzZSBpZiAocmVnZXhGbG9hdGluZ1BvaW50LnRlc3QodmFsdWUpICYmIChsYXN0Q2hhciA9PT0gXCJ4XCIpKSB7XG5cblx0XHRcdFx0XHQvLyBJZiB3aWR0aCwgZGVuc2l0eSBhbmQgZnV0dXJlLWNvbXBhdC1oIGFyZSBub3QgYWxsIGFic2VudCwgdGhlbiBsZXQgZXJyb3Jcblx0XHRcdFx0XHQvLyBiZSB5ZXMuXG5cdFx0XHRcdFx0aWYgKHcgfHwgZCB8fCBoKSB7cEVycm9yID0gdHJ1ZTt9XG5cblx0XHRcdFx0XHQvLyBBcHBseSB0aGUgcnVsZXMgZm9yIHBhcnNpbmcgZmxvYXRpbmctcG9pbnQgbnVtYmVyIHZhbHVlcyB0byB0aGUgZGVzY3JpcHRvci5cblx0XHRcdFx0XHQvLyBJZiB0aGUgcmVzdWx0IGlzIGxlc3MgdGhhbiB6ZXJvLCBsZXQgZXJyb3IgYmUgeWVzLiBPdGhlcndpc2UsIGxldCBkZW5zaXR5XG5cdFx0XHRcdFx0Ly8gYmUgdGhlIHJlc3VsdC5cblx0XHRcdFx0XHRpZiAoZmxvYXRWYWwgPCAwKSB7cEVycm9yID0gdHJ1ZTt9IGVsc2Uge2QgPSBmbG9hdFZhbDt9XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGRlc2NyaXB0b3IgY29uc2lzdHMgb2YgYSB2YWxpZCBub24tbmVnYXRpdmUgaW50ZWdlciBmb2xsb3dlZCBieVxuXHRcdFx0XHQvLyBhIFUrMDA2OCBMQVRJTiBTTUFMTCBMRVRURVIgSCBjaGFyYWN0ZXJcblx0XHRcdFx0fSBlbHNlIGlmIChyZWdleE5vbk5lZ2F0aXZlSW50ZWdlci50ZXN0KHZhbHVlKSAmJiAobGFzdENoYXIgPT09IFwiaFwiKSkge1xuXG5cdFx0XHRcdFx0Ly8gSWYgaGVpZ2h0IGFuZCBkZW5zaXR5IGFyZSBub3QgYm90aCBhYnNlbnQsIHRoZW4gbGV0IGVycm9yIGJlIHllcy5cblx0XHRcdFx0XHRpZiAoaCB8fCBkKSB7cEVycm9yID0gdHJ1ZTt9XG5cblx0XHRcdFx0XHQvLyBBcHBseSB0aGUgcnVsZXMgZm9yIHBhcnNpbmcgbm9uLW5lZ2F0aXZlIGludGVnZXJzIHRvIHRoZSBkZXNjcmlwdG9yLlxuXHRcdFx0XHRcdC8vIElmIHRoZSByZXN1bHQgaXMgemVybywgbGV0IGVycm9yIGJlIHllcy4gT3RoZXJ3aXNlLCBsZXQgZnV0dXJlLWNvbXBhdC1oXG5cdFx0XHRcdFx0Ly8gYmUgdGhlIHJlc3VsdC5cblx0XHRcdFx0XHRpZiAoaW50VmFsID09PSAwKSB7cEVycm9yID0gdHJ1ZTt9IGVsc2Uge2ggPSBpbnRWYWw7fVxuXG5cdFx0XHRcdC8vIEFueXRoaW5nIGVsc2UsIExldCBlcnJvciBiZSB5ZXMuXG5cdFx0XHRcdH0gZWxzZSB7cEVycm9yID0gdHJ1ZTt9XG5cdFx0XHR9IC8vIChjbG9zZSBzdGVwIDEzIGZvciBsb29wKVxuXG5cdFx0XHQvLyAxNS4gSWYgZXJyb3IgaXMgc3RpbGwgbm8sIHRoZW4gYXBwZW5kIGEgbmV3IGltYWdlIHNvdXJjZSB0byBjYW5kaWRhdGVzIHdob3NlXG5cdFx0XHQvLyBVUkwgaXMgdXJsLCBhc3NvY2lhdGVkIHdpdGggYSB3aWR0aCB3aWR0aCBpZiBub3QgYWJzZW50IGFuZCBhIHBpeGVsXG5cdFx0XHQvLyBkZW5zaXR5IGRlbnNpdHkgaWYgbm90IGFic2VudC4gT3RoZXJ3aXNlLCB0aGVyZSBpcyBhIHBhcnNlIGVycm9yLlxuXHRcdFx0aWYgKCFwRXJyb3IpIHtcblx0XHRcdFx0Y2FuZGlkYXRlLnVybCA9IHVybDtcblxuXHRcdFx0XHRpZiAodykgeyBjYW5kaWRhdGUudyA9IHc7fVxuXHRcdFx0XHRpZiAoZCkgeyBjYW5kaWRhdGUuZCA9IGQ7fVxuXHRcdFx0XHRpZiAoaCkgeyBjYW5kaWRhdGUuaCA9IGg7fVxuXHRcdFx0XHRpZiAoIWggJiYgIWQgJiYgIXcpIHtjYW5kaWRhdGUuZCA9IDE7fVxuXHRcdFx0XHRpZiAoY2FuZGlkYXRlLmQgPT09IDEpIHtzZXQuaGFzMXggPSB0cnVlO31cblx0XHRcdFx0Y2FuZGlkYXRlLnNldCA9IHNldDtcblxuXHRcdFx0XHRjYW5kaWRhdGVzLnB1c2goY2FuZGlkYXRlKTtcblx0XHRcdH1cblx0XHR9IC8vIChjbG9zZSBwYXJzZURlc2NyaXB0b3JzIGZuKVxuXG5cdFx0LyoqXG5cdFx0KiBUb2tlbml6ZXMgZGVzY3JpcHRvciBwcm9wZXJ0aWVzIHByaW9yIHRvIHBhcnNpbmdcblx0XHQqIFJldHVybnMgdW5kZWZpbmVkLlxuXHRcdCogKEFnYWluLCB0aGlzIGZuIGlzIGRlZmluZWQgYmVmb3JlIGl0IGlzIHVzZWQsIGluIG9yZGVyIHRvIHBhc3MgSlNISU5ULlxuXHRcdCogVW5mb3J0dW5hdGVseSB0aGlzIGJyZWFrcyB0aGUgbG9naWNhbCBzZXF1ZW5jaW5nIG9mIHRoZSBzcGVjIGNvbW1lbnRzLiA6LyApXG5cdFx0Ki9cblx0XHRmdW5jdGlvbiB0b2tlbml6ZSgpIHtcblxuXHRcdFx0Ly8gOC4xLiBEZXNjcmlwdG9yIHRva2VuaXNlcjogU2tpcCB3aGl0ZXNwYWNlXG5cdFx0XHRjb2xsZWN0Q2hhcmFjdGVycyhyZWdleExlYWRpbmdTcGFjZXMpO1xuXG5cdFx0XHQvLyA4LjIuIExldCBjdXJyZW50IGRlc2NyaXB0b3IgYmUgdGhlIGVtcHR5IHN0cmluZy5cblx0XHRcdGN1cnJlbnREZXNjcmlwdG9yID0gXCJcIjtcblxuXHRcdFx0Ly8gOC4zLiBMZXQgc3RhdGUgYmUgaW4gZGVzY3JpcHRvci5cblx0XHRcdHN0YXRlID0gXCJpbiBkZXNjcmlwdG9yXCI7XG5cblx0XHRcdHdoaWxlICh0cnVlKSB7XG5cblx0XHRcdFx0Ly8gOC40LiBMZXQgYyBiZSB0aGUgY2hhcmFjdGVyIGF0IHBvc2l0aW9uLlxuXHRcdFx0XHRjID0gaW5wdXQuY2hhckF0KHBvcyk7XG5cblx0XHRcdFx0Ly8gIERvIHRoZSBmb2xsb3dpbmcgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZSBvZiBzdGF0ZS5cblx0XHRcdFx0Ly8gIEZvciB0aGUgcHVycG9zZSBvZiB0aGlzIHN0ZXAsIFwiRU9GXCIgaXMgYSBzcGVjaWFsIGNoYXJhY3RlciByZXByZXNlbnRpbmdcblx0XHRcdFx0Ly8gIHRoYXQgcG9zaXRpb24gaXMgcGFzdCB0aGUgZW5kIG9mIGlucHV0LlxuXG5cdFx0XHRcdC8vIEluIGRlc2NyaXB0b3Jcblx0XHRcdFx0aWYgKHN0YXRlID09PSBcImluIGRlc2NyaXB0b3JcIikge1xuXHRcdFx0XHRcdC8vIERvIHRoZSBmb2xsb3dpbmcsIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgYzpcblxuXHRcdFx0XHQgIC8vIFNwYWNlIGNoYXJhY3RlclxuXHRcdFx0XHQgIC8vIElmIGN1cnJlbnQgZGVzY3JpcHRvciBpcyBub3QgZW1wdHksIGFwcGVuZCBjdXJyZW50IGRlc2NyaXB0b3IgdG9cblx0XHRcdFx0ICAvLyBkZXNjcmlwdG9ycyBhbmQgbGV0IGN1cnJlbnQgZGVzY3JpcHRvciBiZSB0aGUgZW1wdHkgc3RyaW5nLlxuXHRcdFx0XHQgIC8vIFNldCBzdGF0ZSB0byBhZnRlciBkZXNjcmlwdG9yLlxuXHRcdFx0XHRcdGlmIChpc1NwYWNlKGMpKSB7XG5cdFx0XHRcdFx0XHRpZiAoY3VycmVudERlc2NyaXB0b3IpIHtcblx0XHRcdFx0XHRcdFx0ZGVzY3JpcHRvcnMucHVzaChjdXJyZW50RGVzY3JpcHRvcik7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnREZXNjcmlwdG9yID0gXCJcIjtcblx0XHRcdFx0XHRcdFx0c3RhdGUgPSBcImFmdGVyIGRlc2NyaXB0b3JcIjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFUrMDAyQyBDT01NQSAoLClcblx0XHRcdFx0XHQvLyBBZHZhbmNlIHBvc2l0aW9uIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBpbiBpbnB1dC4gSWYgY3VycmVudCBkZXNjcmlwdG9yXG5cdFx0XHRcdFx0Ly8gaXMgbm90IGVtcHR5LCBhcHBlbmQgY3VycmVudCBkZXNjcmlwdG9yIHRvIGRlc2NyaXB0b3JzLiBKdW1wIHRvIHRoZSBzdGVwXG5cdFx0XHRcdFx0Ly8gbGFiZWxlZCBkZXNjcmlwdG9yIHBhcnNlci5cblx0XHRcdFx0XHR9IGVsc2UgaWYgKGMgPT09IFwiLFwiKSB7XG5cdFx0XHRcdFx0XHRwb3MgKz0gMTtcblx0XHRcdFx0XHRcdGlmIChjdXJyZW50RGVzY3JpcHRvcikge1xuXHRcdFx0XHRcdFx0XHRkZXNjcmlwdG9ycy5wdXNoKGN1cnJlbnREZXNjcmlwdG9yKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHBhcnNlRGVzY3JpcHRvcnMoKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHRcdC8vIFUrMDAyOCBMRUZUIFBBUkVOVEhFU0lTICgoKVxuXHRcdFx0XHRcdC8vIEFwcGVuZCBjIHRvIGN1cnJlbnQgZGVzY3JpcHRvci4gU2V0IHN0YXRlIHRvIGluIHBhcmVucy5cblx0XHRcdFx0XHR9IGVsc2UgaWYgKGMgPT09IFwiXFx1MDAyOFwiKSB7XG5cdFx0XHRcdFx0XHRjdXJyZW50RGVzY3JpcHRvciA9IGN1cnJlbnREZXNjcmlwdG9yICsgYztcblx0XHRcdFx0XHRcdHN0YXRlID0gXCJpbiBwYXJlbnNcIjtcblxuXHRcdFx0XHRcdC8vIEVPRlxuXHRcdFx0XHRcdC8vIElmIGN1cnJlbnQgZGVzY3JpcHRvciBpcyBub3QgZW1wdHksIGFwcGVuZCBjdXJyZW50IGRlc2NyaXB0b3IgdG9cblx0XHRcdFx0XHQvLyBkZXNjcmlwdG9ycy4gSnVtcCB0byB0aGUgc3RlcCBsYWJlbGVkIGRlc2NyaXB0b3IgcGFyc2VyLlxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoYyA9PT0gXCJcIikge1xuXHRcdFx0XHRcdFx0aWYgKGN1cnJlbnREZXNjcmlwdG9yKSB7XG5cdFx0XHRcdFx0XHRcdGRlc2NyaXB0b3JzLnB1c2goY3VycmVudERlc2NyaXB0b3IpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0cGFyc2VEZXNjcmlwdG9ycygpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHRcdFx0Ly8gQW55dGhpbmcgZWxzZVxuXHRcdFx0XHRcdC8vIEFwcGVuZCBjIHRvIGN1cnJlbnQgZGVzY3JpcHRvci5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y3VycmVudERlc2NyaXB0b3IgPSBjdXJyZW50RGVzY3JpcHRvciArIGM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQvLyAoZW5kIFwiaW4gZGVzY3JpcHRvclwiXG5cblx0XHRcdFx0Ly8gSW4gcGFyZW5zXG5cdFx0XHRcdH0gZWxzZSBpZiAoc3RhdGUgPT09IFwiaW4gcGFyZW5zXCIpIHtcblxuXHRcdFx0XHRcdC8vIFUrMDAyOSBSSUdIVCBQQVJFTlRIRVNJUyAoKSlcblx0XHRcdFx0XHQvLyBBcHBlbmQgYyB0byBjdXJyZW50IGRlc2NyaXB0b3IuIFNldCBzdGF0ZSB0byBpbiBkZXNjcmlwdG9yLlxuXHRcdFx0XHRcdGlmIChjID09PSBcIilcIikge1xuXHRcdFx0XHRcdFx0Y3VycmVudERlc2NyaXB0b3IgPSBjdXJyZW50RGVzY3JpcHRvciArIGM7XG5cdFx0XHRcdFx0XHRzdGF0ZSA9IFwiaW4gZGVzY3JpcHRvclwiO1xuXG5cdFx0XHRcdFx0Ly8gRU9GXG5cdFx0XHRcdFx0Ly8gQXBwZW5kIGN1cnJlbnQgZGVzY3JpcHRvciB0byBkZXNjcmlwdG9ycy4gSnVtcCB0byB0aGUgc3RlcCBsYWJlbGVkXG5cdFx0XHRcdFx0Ly8gZGVzY3JpcHRvciBwYXJzZXIuXG5cdFx0XHRcdFx0fSBlbHNlIGlmIChjID09PSBcIlwiKSB7XG5cdFx0XHRcdFx0XHRkZXNjcmlwdG9ycy5wdXNoKGN1cnJlbnREZXNjcmlwdG9yKTtcblx0XHRcdFx0XHRcdHBhcnNlRGVzY3JpcHRvcnMoKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHRcdC8vIEFueXRoaW5nIGVsc2Vcblx0XHRcdFx0XHQvLyBBcHBlbmQgYyB0byBjdXJyZW50IGRlc2NyaXB0b3IuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGN1cnJlbnREZXNjcmlwdG9yID0gY3VycmVudERlc2NyaXB0b3IgKyBjO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZnRlciBkZXNjcmlwdG9yXG5cdFx0XHRcdH0gZWxzZSBpZiAoc3RhdGUgPT09IFwiYWZ0ZXIgZGVzY3JpcHRvclwiKSB7XG5cblx0XHRcdFx0XHQvLyBEbyB0aGUgZm9sbG93aW5nLCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIGM6XG5cdFx0XHRcdFx0Ly8gU3BhY2UgY2hhcmFjdGVyOiBTdGF5IGluIHRoaXMgc3RhdGUuXG5cdFx0XHRcdFx0aWYgKGlzU3BhY2UoYykpIHtcblxuXHRcdFx0XHRcdC8vIEVPRjogSnVtcCB0byB0aGUgc3RlcCBsYWJlbGVkIGRlc2NyaXB0b3IgcGFyc2VyLlxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoYyA9PT0gXCJcIikge1xuXHRcdFx0XHRcdFx0cGFyc2VEZXNjcmlwdG9ycygpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXG5cdFx0XHRcdFx0Ly8gQW55dGhpbmcgZWxzZVxuXHRcdFx0XHRcdC8vIFNldCBzdGF0ZSB0byBpbiBkZXNjcmlwdG9yLiBTZXQgcG9zaXRpb24gdG8gdGhlIHByZXZpb3VzIGNoYXJhY3RlciBpbiBpbnB1dC5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c3RhdGUgPSBcImluIGRlc2NyaXB0b3JcIjtcblx0XHRcdFx0XHRcdHBvcyAtPSAxO1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWR2YW5jZSBwb3NpdGlvbiB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gaW5wdXQuXG5cdFx0XHRcdHBvcyArPSAxO1xuXG5cdFx0XHQvLyBSZXBlYXQgdGhpcyBzdGVwLlxuXHRcdFx0fSAvLyAoY2xvc2Ugd2hpbGUgdHJ1ZSBsb29wKVxuXHRcdH1cblxuXHRcdC8vIDQuIFNwbGl0dGluZyBsb29wOiBDb2xsZWN0IGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0aGF0IGFyZSBzcGFjZVxuXHRcdC8vICAgIGNoYXJhY3RlcnMgb3IgVSswMDJDIENPTU1BIGNoYXJhY3RlcnMuIElmIGFueSBVKzAwMkMgQ09NTUEgY2hhcmFjdGVyc1xuXHRcdC8vICAgIHdlcmUgY29sbGVjdGVkLCB0aGF0IGlzIGEgcGFyc2UgZXJyb3IuXG5cdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdGNvbGxlY3RDaGFyYWN0ZXJzKHJlZ2V4TGVhZGluZ0NvbW1hc09yU3BhY2VzKTtcblxuXHRcdFx0Ly8gNS4gSWYgcG9zaXRpb24gaXMgcGFzdCB0aGUgZW5kIG9mIGlucHV0LCByZXR1cm4gY2FuZGlkYXRlcyBhbmQgYWJvcnQgdGhlc2Ugc3RlcHMuXG5cdFx0XHRpZiAocG9zID49IGlucHV0TGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiBjYW5kaWRhdGVzOyAvLyAod2UncmUgZG9uZSwgdGhpcyBpcyB0aGUgc29sZSByZXR1cm4gcGF0aClcblx0XHRcdH1cblxuXHRcdFx0Ly8gNi4gQ29sbGVjdCBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IHNwYWNlIGNoYXJhY3RlcnMsXG5cdFx0XHQvLyAgICBhbmQgbGV0IHRoYXQgYmUgdXJsLlxuXHRcdFx0dXJsID0gY29sbGVjdENoYXJhY3RlcnMocmVnZXhMZWFkaW5nTm90U3BhY2VzKTtcblxuXHRcdFx0Ly8gNy4gTGV0IGRlc2NyaXB0b3JzIGJlIGEgbmV3IGVtcHR5IGxpc3QuXG5cdFx0XHRkZXNjcmlwdG9ycyA9IFtdO1xuXG5cdFx0XHQvLyA4LiBJZiB1cmwgZW5kcyB3aXRoIGEgVSswMDJDIENPTU1BIGNoYXJhY3RlciAoLCksIGZvbGxvdyB0aGVzZSBzdWJzdGVwczpcblx0XHRcdC8vXHRcdCgxKS4gUmVtb3ZlIGFsbCB0cmFpbGluZyBVKzAwMkMgQ09NTUEgY2hhcmFjdGVycyBmcm9tIHVybC4gSWYgdGhpcyByZW1vdmVkXG5cdFx0XHQvLyAgICAgICAgIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyLCB0aGF0IGlzIGEgcGFyc2UgZXJyb3IuXG5cdFx0XHRpZiAodXJsLnNsaWNlKC0xKSA9PT0gXCIsXCIpIHtcblx0XHRcdFx0dXJsID0gdXJsLnJlcGxhY2UocmVnZXhUcmFpbGluZ0NvbW1hcywgXCJcIik7XG5cdFx0XHRcdC8vIChKdW1wIGFoZWFkIHRvIHN0ZXAgOSB0byBza2lwIHRva2VuaXphdGlvbiBhbmQganVzdCBwdXNoIHRoZSBjYW5kaWRhdGUpLlxuXHRcdFx0XHRwYXJzZURlc2NyaXB0b3JzKCk7XG5cblx0XHRcdC8vXHRPdGhlcndpc2UsIGZvbGxvdyB0aGVzZSBzdWJzdGVwczpcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRva2VuaXplKCk7XG5cdFx0XHR9IC8vIChjbG9zZSBlbHNlIG9mIHN0ZXAgOClcblxuXHRcdC8vIDE2LiBSZXR1cm4gdG8gdGhlIHN0ZXAgbGFiZWxlZCBzcGxpdHRpbmcgbG9vcC5cblx0XHR9IC8vIChDbG9zZSBvZiBiaWcgd2hpbGUgbG9vcC4pXG5cdH1cblxuXHQvKlxuXHQgKiBTaXplcyBQYXJzZXJcblx0ICpcblx0ICogQnkgQWxleCBCZWxsIHwgIE1JVCBMaWNlbnNlXG5cdCAqXG5cdCAqIE5vbi1zdHJpY3QgYnV0IGFjY3VyYXRlIGFuZCBsaWdodHdlaWdodCBKUyBQYXJzZXIgZm9yIHRoZSBzdHJpbmcgdmFsdWUgPGltZyBzaXplcz1cImhlcmVcIj5cblx0ICpcblx0ICogUmVmZXJlbmNlIGFsZ29yaXRobSBhdDpcblx0ICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZW1iZWRkZWQtY29udGVudC5odG1sI3BhcnNlLWEtc2l6ZXMtYXR0cmlidXRlXG5cdCAqXG5cdCAqIE1vc3QgY29tbWVudHMgYXJlIGNvcGllZCBpbiBkaXJlY3RseSBmcm9tIHRoZSBzcGVjXG5cdCAqIChleGNlcHQgZm9yIGNvbW1lbnRzIGluIHBhcmVucykuXG5cdCAqXG5cdCAqIEdyYW1tYXIgaXM6XG5cdCAqIDxzb3VyY2Utc2l6ZS1saXN0PiA9IDxzb3VyY2Utc2l6ZT4jIFsgLCA8c291cmNlLXNpemUtdmFsdWU+IF0/IHwgPHNvdXJjZS1zaXplLXZhbHVlPlxuXHQgKiA8c291cmNlLXNpemU+ID0gPG1lZGlhLWNvbmRpdGlvbj4gPHNvdXJjZS1zaXplLXZhbHVlPlxuXHQgKiA8c291cmNlLXNpemUtdmFsdWU+ID0gPGxlbmd0aD5cblx0ICogaHR0cDovL3d3dy53My5vcmcvaHRtbC93Zy9kcmFmdHMvaHRtbC9tYXN0ZXIvZW1iZWRkZWQtY29udGVudC5odG1sI2F0dHItaW1nLXNpemVzXG5cdCAqXG5cdCAqIEUuZy4gXCIobWF4LXdpZHRoOiAzMGVtKSAxMDB2dywgKG1heC13aWR0aDogNTBlbSkgNzB2dywgMTAwdndcIlxuXHQgKiBvciBcIihtaW4td2lkdGg6IDMwZW0pLCBjYWxjKDMwdncgLSAxNXB4KVwiIG9yIGp1c3QgXCIzMHZ3XCJcblx0ICpcblx0ICogUmV0dXJucyB0aGUgZmlyc3QgdmFsaWQgPGNzcy1sZW5ndGg+IHdpdGggYSBtZWRpYSBjb25kaXRpb24gdGhhdCBldmFsdWF0ZXMgdG8gdHJ1ZSxcblx0ICogb3IgXCIxMDB2d1wiIGlmIGFsbCB2YWxpZCBtZWRpYSBjb25kaXRpb25zIGV2YWx1YXRlIHRvIGZhbHNlLlxuXHQgKlxuXHQgKi9cblxuXHRmdW5jdGlvbiBwYXJzZVNpemVzKHN0clZhbHVlKSB7XG5cblx0XHQvLyAoUGVyY2VudGFnZSBDU1MgbGVuZ3RocyBhcmUgbm90IGFsbG93ZWQgaW4gdGhpcyBjYXNlLCB0byBhdm9pZCBjb25mdXNpb246XG5cdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZW1iZWRkZWQtY29udGVudC5odG1sI3ZhbGlkLXNvdXJjZS1zaXplLWxpc3Rcblx0XHQvLyBDU1MgYWxsb3dzIGEgc2luZ2xlIG9wdGlvbmFsIHBsdXMgb3IgbWludXMgc2lnbjpcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyL3N5bmRhdGEuaHRtbCNudW1iZXJzXG5cdFx0Ly8gQ1NTIGlzIEFTQ0lJIGNhc2UtaW5zZW5zaXRpdmU6XG5cdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvQ1NTMi9zeW5kYXRhLmh0bWwjY2hhcmFjdGVycyApXG5cdFx0Ly8gU3BlYyBhbGxvd3MgZXhwb25lbnRpYWwgbm90YXRpb24gZm9yIDxudW1iZXI+IHR5cGU6XG5cdFx0Ly8gaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3NzLXZhbHVlcy8jbnVtYmVyc1xuXHRcdHZhciByZWdleENzc0xlbmd0aFdpdGhVbml0cyA9IC9eKD86WystXT9bMC05XSt8WzAtOV0qXFwuWzAtOV0rKSg/OltlRV1bKy1dP1swLTldKyk/KD86Y2h8Y218ZW18ZXh8aW58bW18cGN8cHR8cHh8cmVtfHZofHZtaW58dm1heHx2dykkL2k7XG5cblx0XHQvLyAoVGhpcyBpcyBhIHF1aWNrIGFuZCBsZW5pZW50IHRlc3QuIEJlY2F1c2Ugb2Ygb3B0aW9uYWwgdW5saW1pdGVkLWRlcHRoIGludGVybmFsXG5cdFx0Ly8gZ3JvdXBpbmcgcGFyZW5zIGFuZCBzdHJpY3Qgc3BhY2luZyBydWxlcywgdGhpcyBjb3VsZCBnZXQgdmVyeSBjb21wbGljYXRlZC4pXG5cdFx0dmFyIHJlZ2V4Q3NzQ2FsYyA9IC9eY2FsY1xcKCg/OlswLTlhLXogXFwuXFwrXFwtXFwqXFwvXFwoXFwpXSspXFwpJC9pO1xuXG5cdFx0dmFyIGk7XG5cdFx0dmFyIHVucGFyc2VkU2l6ZXNMaXN0O1xuXHRcdHZhciB1bnBhcnNlZFNpemVzTGlzdExlbmd0aDtcblx0XHR2YXIgdW5wYXJzZWRTaXplO1xuXHRcdHZhciBsYXN0Q29tcG9uZW50VmFsdWU7XG5cdFx0dmFyIHNpemU7XG5cblx0XHQvLyBVVElMSVRZIEZVTkNUSU9OU1xuXG5cdFx0Ly8gIChUb3kgQ1NTIHBhcnNlci4gVGhlIGdvYWxzIGhlcmUgYXJlOlxuXHRcdC8vICAxKSBleHBhbnNpdmUgdGVzdCBjb3ZlcmFnZSB3aXRob3V0IHRoZSB3ZWlnaHQgb2YgYSBmdWxsIENTUyBwYXJzZXIuXG5cdFx0Ly8gIDIpIEF2b2lkaW5nIHJlZ2V4IHdoZXJldmVyIGNvbnZlbmllbnQuXG5cdFx0Ly8gIFF1aWNrIHRlc3RzOiBodHRwOi8vanNmaWRkbGUubmV0L2d0bnRMNGdyLzMvXG5cdFx0Ly8gIFJldHVybnMgYW4gYXJyYXkgb2YgYXJyYXlzLilcblx0XHRmdW5jdGlvbiBwYXJzZUNvbXBvbmVudFZhbHVlcyhzdHIpIHtcblx0XHRcdHZhciBjaHJjdHI7XG5cdFx0XHR2YXIgY29tcG9uZW50ID0gXCJcIjtcblx0XHRcdHZhciBjb21wb25lbnRBcnJheSA9IFtdO1xuXHRcdFx0dmFyIGxpc3RBcnJheSA9IFtdO1xuXHRcdFx0dmFyIHBhcmVuRGVwdGggPSAwO1xuXHRcdFx0dmFyIHBvcyA9IDA7XG5cdFx0XHR2YXIgaW5Db21tZW50ID0gZmFsc2U7XG5cblx0XHRcdGZ1bmN0aW9uIHB1c2hDb21wb25lbnQoKSB7XG5cdFx0XHRcdGlmIChjb21wb25lbnQpIHtcblx0XHRcdFx0XHRjb21wb25lbnRBcnJheS5wdXNoKGNvbXBvbmVudCk7XG5cdFx0XHRcdFx0Y29tcG9uZW50ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBwdXNoQ29tcG9uZW50QXJyYXkoKSB7XG5cdFx0XHRcdGlmIChjb21wb25lbnRBcnJheVswXSkge1xuXHRcdFx0XHRcdGxpc3RBcnJheS5wdXNoKGNvbXBvbmVudEFycmF5KTtcblx0XHRcdFx0XHRjb21wb25lbnRBcnJheSA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIChMb29wIGZvcndhcmRzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLilcblx0XHRcdHdoaWxlICh0cnVlKSB7XG5cdFx0XHRcdGNocmN0ciA9IHN0ci5jaGFyQXQocG9zKTtcblxuXHRcdFx0XHRpZiAoY2hyY3RyID09PSBcIlwiKSB7IC8vICggRW5kIG9mIHN0cmluZyByZWFjaGVkLilcblx0XHRcdFx0XHRwdXNoQ29tcG9uZW50KCk7XG5cdFx0XHRcdFx0cHVzaENvbXBvbmVudEFycmF5KCk7XG5cdFx0XHRcdFx0cmV0dXJuIGxpc3RBcnJheTtcblx0XHRcdFx0fSBlbHNlIGlmIChpbkNvbW1lbnQpIHtcblx0XHRcdFx0XHRpZiAoKGNocmN0ciA9PT0gXCIqXCIpICYmIChzdHJbcG9zICsgMV0gPT09IFwiL1wiKSkgeyAvLyAoQXQgZW5kIG9mIGEgY29tbWVudC4pXG5cdFx0XHRcdFx0XHRpbkNvbW1lbnQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdHBvcyArPSAyO1xuXHRcdFx0XHRcdFx0cHVzaENvbXBvbmVudCgpO1xuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHBvcyArPSAxOyAvLyAoU2tpcCBhbGwgY2hhcmFjdGVycyBpbnNpZGUgY29tbWVudHMuKVxuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKGlzU3BhY2UoY2hyY3RyKSkge1xuXHRcdFx0XHRcdC8vIChJZiBwcmV2aW91cyBjaGFyYWN0ZXIgaW4gbG9vcCB3YXMgYWxzbyBhIHNwYWNlLCBvciBpZlxuXHRcdFx0XHRcdC8vIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZywgZG8gbm90IGFkZCBzcGFjZSBjaGFyIHRvXG5cdFx0XHRcdFx0Ly8gY29tcG9uZW50Lilcblx0XHRcdFx0XHRpZiAoIChzdHIuY2hhckF0KHBvcyAtIDEpICYmIGlzU3BhY2UoIHN0ci5jaGFyQXQocG9zIC0gMSkgKSApIHx8ICFjb21wb25lbnQgKSB7XG5cdFx0XHRcdFx0XHRwb3MgKz0gMTtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAocGFyZW5EZXB0aCA9PT0gMCkge1xuXHRcdFx0XHRcdFx0cHVzaENvbXBvbmVudCgpO1xuXHRcdFx0XHRcdFx0cG9zICs9MTtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvLyAoUmVwbGFjZSBhbnkgc3BhY2UgY2hhcmFjdGVyIHdpdGggYSBwbGFpbiBzcGFjZSBmb3IgbGVnaWJpbGl0eS4pXG5cdFx0XHRcdFx0XHRjaHJjdHIgPSBcIiBcIjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoY2hyY3RyID09PSBcIihcIikge1xuXHRcdFx0XHRcdHBhcmVuRGVwdGggKz0gMTtcblx0XHRcdFx0fSBlbHNlIGlmIChjaHJjdHIgPT09IFwiKVwiKSB7XG5cdFx0XHRcdFx0cGFyZW5EZXB0aCAtPSAxO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGNocmN0ciA9PT0gXCIsXCIpIHtcblx0XHRcdFx0XHRwdXNoQ29tcG9uZW50KCk7XG5cdFx0XHRcdFx0cHVzaENvbXBvbmVudEFycmF5KCk7XG5cdFx0XHRcdFx0cG9zICs9IDE7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIChjaHJjdHIgPT09IFwiL1wiKSAmJiAoc3RyLmNoYXJBdChwb3MgKyAxKSA9PT0gXCIqXCIpICkge1xuXHRcdFx0XHRcdGluQ29tbWVudCA9IHRydWU7XG5cdFx0XHRcdFx0cG9zICs9IDI7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb21wb25lbnQgPSBjb21wb25lbnQgKyBjaHJjdHI7XG5cdFx0XHRcdHBvcyArPSAxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGlzVmFsaWROb25OZWdhdGl2ZVNvdXJjZVNpemVWYWx1ZShzKSB7XG5cdFx0XHRpZiAocmVnZXhDc3NMZW5ndGhXaXRoVW5pdHMudGVzdChzKSAmJiAocGFyc2VGbG9hdChzKSA+PSAwKSkge3JldHVybiB0cnVlO31cblx0XHRcdGlmIChyZWdleENzc0NhbGMudGVzdChzKSkge3JldHVybiB0cnVlO31cblx0XHRcdC8vICggaHR0cDovL3d3dy53My5vcmcvVFIvQ1NTMi9zeW5kYXRhLmh0bWwjbnVtYmVycyBzYXlzOlxuXHRcdFx0Ly8gXCItMCBpcyBlcXVpdmFsZW50IHRvIDAgYW5kIGlzIG5vdCBhIG5lZ2F0aXZlIG51bWJlci5cIiB3aGljaCBtZWFucyB0aGF0XG5cdFx0XHQvLyB1bml0bGVzcyB6ZXJvIGFuZCB1bml0bGVzcyBuZWdhdGl2ZSB6ZXJvIG11c3QgYmUgYWNjZXB0ZWQgYXMgc3BlY2lhbCBjYXNlcy4pXG5cdFx0XHRpZiAoKHMgPT09IFwiMFwiKSB8fCAocyA9PT0gXCItMFwiKSB8fCAocyA9PT0gXCIrMFwiKSkge3JldHVybiB0cnVlO31cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBXaGVuIGFza2VkIHRvIHBhcnNlIGEgc2l6ZXMgYXR0cmlidXRlIGZyb20gYW4gZWxlbWVudCwgcGFyc2UgYVxuXHRcdC8vIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGNvbXBvbmVudCB2YWx1ZXMgZnJvbSB0aGUgdmFsdWUgb2YgdGhlIGVsZW1lbnQnc1xuXHRcdC8vIHNpemVzIGF0dHJpYnV0ZSAob3IgdGhlIGVtcHR5IHN0cmluZywgaWYgdGhlIGF0dHJpYnV0ZSBpcyBhYnNlbnQpLCBhbmQgbGV0XG5cdFx0Ly8gdW5wYXJzZWQgc2l6ZXMgbGlzdCBiZSB0aGUgcmVzdWx0LlxuXHRcdC8vIGh0dHA6Ly9kZXYudzMub3JnL2Nzc3dnL2Nzcy1zeW50YXgvI3BhcnNlLWNvbW1hLXNlcGFyYXRlZC1saXN0LW9mLWNvbXBvbmVudC12YWx1ZXNcblxuXHRcdHVucGFyc2VkU2l6ZXNMaXN0ID0gcGFyc2VDb21wb25lbnRWYWx1ZXMoc3RyVmFsdWUpO1xuXHRcdHVucGFyc2VkU2l6ZXNMaXN0TGVuZ3RoID0gdW5wYXJzZWRTaXplc0xpc3QubGVuZ3RoO1xuXG5cdFx0Ly8gRm9yIGVhY2ggdW5wYXJzZWQgc2l6ZSBpbiB1bnBhcnNlZCBzaXplcyBsaXN0OlxuXHRcdGZvciAoaSA9IDA7IGkgPCB1bnBhcnNlZFNpemVzTGlzdExlbmd0aDsgaSsrKSB7XG5cdFx0XHR1bnBhcnNlZFNpemUgPSB1bnBhcnNlZFNpemVzTGlzdFtpXTtcblxuXHRcdFx0Ly8gMS4gUmVtb3ZlIGFsbCBjb25zZWN1dGl2ZSA8d2hpdGVzcGFjZS10b2tlbj5zIGZyb20gdGhlIGVuZCBvZiB1bnBhcnNlZCBzaXplLlxuXHRcdFx0Ly8gKCBwYXJzZUNvbXBvbmVudFZhbHVlcygpIGFscmVhZHkgb21pdHMgc3BhY2VzIG91dHNpZGUgb2YgcGFyZW5zLiApXG5cblx0XHRcdC8vIElmIHVucGFyc2VkIHNpemUgaXMgbm93IGVtcHR5LCB0aGF0IGlzIGEgcGFyc2UgZXJyb3I7IGNvbnRpbnVlIHRvIHRoZSBuZXh0XG5cdFx0XHQvLyBpdGVyYXRpb24gb2YgdGhpcyBhbGdvcml0aG0uXG5cdFx0XHQvLyAoIHBhcnNlQ29tcG9uZW50VmFsdWVzKCkgd29uJ3QgcHVzaCBhbiBlbXB0eSBhcnJheS4gKVxuXG5cdFx0XHQvLyAyLiBJZiB0aGUgbGFzdCBjb21wb25lbnQgdmFsdWUgaW4gdW5wYXJzZWQgc2l6ZSBpcyBhIHZhbGlkIG5vbi1uZWdhdGl2ZVxuXHRcdFx0Ly8gPHNvdXJjZS1zaXplLXZhbHVlPiwgbGV0IHNpemUgYmUgaXRzIHZhbHVlIGFuZCByZW1vdmUgdGhlIGNvbXBvbmVudCB2YWx1ZVxuXHRcdFx0Ly8gZnJvbSB1bnBhcnNlZCBzaXplLiBBbnkgQ1NTIGZ1bmN0aW9uIG90aGVyIHRoYW4gdGhlIGNhbGMoKSBmdW5jdGlvbiBpc1xuXHRcdFx0Ly8gaW52YWxpZC4gT3RoZXJ3aXNlLCB0aGVyZSBpcyBhIHBhcnNlIGVycm9yOyBjb250aW51ZSB0byB0aGUgbmV4dCBpdGVyYXRpb25cblx0XHRcdC8vIG9mIHRoaXMgYWxnb3JpdGhtLlxuXHRcdFx0Ly8gaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3NzLXN5bnRheC8jcGFyc2UtY29tcG9uZW50LXZhbHVlXG5cdFx0XHRsYXN0Q29tcG9uZW50VmFsdWUgPSB1bnBhcnNlZFNpemVbdW5wYXJzZWRTaXplLmxlbmd0aCAtIDFdO1xuXG5cdFx0XHRpZiAoaXNWYWxpZE5vbk5lZ2F0aXZlU291cmNlU2l6ZVZhbHVlKGxhc3RDb21wb25lbnRWYWx1ZSkpIHtcblx0XHRcdFx0c2l6ZSA9IGxhc3RDb21wb25lbnRWYWx1ZTtcblx0XHRcdFx0dW5wYXJzZWRTaXplLnBvcCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIDMuIFJlbW92ZSBhbGwgY29uc2VjdXRpdmUgPHdoaXRlc3BhY2UtdG9rZW4+cyBmcm9tIHRoZSBlbmQgb2YgdW5wYXJzZWRcblx0XHRcdC8vIHNpemUuIElmIHVucGFyc2VkIHNpemUgaXMgbm93IGVtcHR5LCByZXR1cm4gc2l6ZSBhbmQgZXhpdCB0aGlzIGFsZ29yaXRobS5cblx0XHRcdC8vIElmIHRoaXMgd2FzIG5vdCB0aGUgbGFzdCBpdGVtIGluIHVucGFyc2VkIHNpemVzIGxpc3QsIHRoYXQgaXMgYSBwYXJzZSBlcnJvci5cblx0XHRcdGlmICh1bnBhcnNlZFNpemUubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdHJldHVybiBzaXplO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyA0LiBQYXJzZSB0aGUgcmVtYWluaW5nIGNvbXBvbmVudCB2YWx1ZXMgaW4gdW5wYXJzZWQgc2l6ZSBhcyBhXG5cdFx0XHQvLyA8bWVkaWEtY29uZGl0aW9uPi4gSWYgaXQgZG9lcyBub3QgcGFyc2UgY29ycmVjdGx5LCBvciBpdCBkb2VzIHBhcnNlXG5cdFx0XHQvLyBjb3JyZWN0bHkgYnV0IHRoZSA8bWVkaWEtY29uZGl0aW9uPiBldmFsdWF0ZXMgdG8gZmFsc2UsIGNvbnRpbnVlIHRvIHRoZVxuXHRcdFx0Ly8gbmV4dCBpdGVyYXRpb24gb2YgdGhpcyBhbGdvcml0aG0uXG5cdFx0XHQvLyAoUGFyc2luZyBhbGwgcG9zc2libGUgY29tcG91bmQgbWVkaWEgY29uZGl0aW9ucyBpbiBKUyBpcyBoZWF2eSwgY29tcGxpY2F0ZWQsXG5cdFx0XHQvLyBhbmQgdGhlIHBheW9mZiBpcyB1bmNsZWFyLiBJcyB0aGVyZSBldmVyIGFuIHNpdHVhdGlvbiB3aGVyZSB0aGVcblx0XHRcdC8vIG1lZGlhIGNvbmRpdGlvbiBwYXJzZXMgaW5jb3JyZWN0bHkgYnV0IHN0aWxsIHNvbWVob3cgZXZhbHVhdGVzIHRvIHRydWU/XG5cdFx0XHQvLyBDYW4gd2UganVzdCByZWx5IG9uIHRoZSBicm93c2VyL3BvbHlmaWxsIHRvIGRvIGl0Pylcblx0XHRcdHVucGFyc2VkU2l6ZSA9IHVucGFyc2VkU2l6ZS5qb2luKFwiIFwiKTtcblx0XHRcdGlmICghKHBmLm1hdGNoZXNNZWRpYSggdW5wYXJzZWRTaXplICkgKSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIDUuIFJldHVybiBzaXplIGFuZCBleGl0IHRoaXMgYWxnb3JpdGhtLlxuXHRcdFx0cmV0dXJuIHNpemU7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIGFib3ZlIGFsZ29yaXRobSBleGhhdXN0cyB1bnBhcnNlZCBzaXplcyBsaXN0IHdpdGhvdXQgcmV0dXJuaW5nIGFcblx0XHQvLyBzaXplIHZhbHVlLCByZXR1cm4gMTAwdncuXG5cdFx0cmV0dXJuIFwiMTAwdndcIjtcblx0fVxuXG5cdC8vIG5hbWVzcGFjZVxuXHRwZi5ucyA9IChcInBmXCIgKyBuZXcgRGF0ZSgpLmdldFRpbWUoKSkuc3Vic3RyKDAsIDkpO1xuXG5cdC8vIHNyY3NldCBzdXBwb3J0IHRlc3Rcblx0cGYuc3VwU3Jjc2V0ID0gXCJzcmNzZXRcIiBpbiBpbWFnZTtcblx0cGYuc3VwU2l6ZXMgPSBcInNpemVzXCIgaW4gaW1hZ2U7XG5cdHBmLnN1cFBpY3R1cmUgPSAhIXdpbmRvdy5IVE1MUGljdHVyZUVsZW1lbnQ7XG5cblx0Ly8gVUMgYnJvd3NlciBkb2VzIGNsYWltIHRvIHN1cHBvcnQgc3Jjc2V0IGFuZCBwaWN0dXJlLCBidXQgbm90IHNpemVzLFxuXHQvLyB0aGlzIGV4dGVuZGVkIHRlc3QgcmV2ZWFscyB0aGUgYnJvd3NlciBkb2VzIHN1cHBvcnQgbm90aGluZ1xuXHRpZiAocGYuc3VwU3Jjc2V0ICYmIHBmLnN1cFBpY3R1cmUgJiYgIXBmLnN1cFNpemVzKSB7XG5cdFx0KGZ1bmN0aW9uKGltYWdlMikge1xuXHRcdFx0aW1hZ2Uuc3Jjc2V0ID0gXCJkYXRhOixhXCI7XG5cdFx0XHRpbWFnZTIuc3JjID0gXCJkYXRhOixhXCI7XG5cdFx0XHRwZi5zdXBTcmNzZXQgPSBpbWFnZS5jb21wbGV0ZSA9PT0gaW1hZ2UyLmNvbXBsZXRlO1xuXHRcdFx0cGYuc3VwUGljdHVyZSA9IHBmLnN1cFNyY3NldCAmJiBwZi5zdXBQaWN0dXJlO1xuXHRcdH0pKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIikpO1xuXHR9XG5cblx0Ly8gU2FmYXJpOSBoYXMgYmFzaWMgc3VwcG9ydCBmb3Igc2l6ZXMsIGJ1dCBkb2VzJ3QgZXhwb3NlIHRoZSBgc2l6ZXNgIGlkbCBhdHRyaWJ1dGVcblx0aWYgKHBmLnN1cFNyY3NldCAmJiAhcGYuc3VwU2l6ZXMpIHtcblxuXHRcdChmdW5jdGlvbigpIHtcblx0XHRcdHZhciB3aWR0aDIgPSBcImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEFnQUJBUEFBQVAvLy93QUFBQ0g1QkFBQUFBQUFMQUFBQUFBQ0FBRUFBQUlDQkFvQU93PT1cIjtcblx0XHRcdHZhciB3aWR0aDEgPSBcImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEFRQUJBQUFBQUNINUJBRUtBQUVBTEFBQUFBQUJBQUVBQUFJQ1RBRUFPdz09XCI7XG5cdFx0XHR2YXIgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcblx0XHRcdHZhciB0ZXN0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciB3aWR0aCA9IGltZy53aWR0aDtcblxuXHRcdFx0XHRpZiAod2lkdGggPT09IDIpIHtcblx0XHRcdFx0XHRwZi5zdXBTaXplcyA9IHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRhbHdheXNDaGVja1dEZXNjcmlwdG9yID0gcGYuc3VwU3Jjc2V0ICYmICFwZi5zdXBTaXplcztcblxuXHRcdFx0XHRpc1N1cHBvcnRUZXN0UmVhZHkgPSB0cnVlO1xuXHRcdFx0XHQvLyBmb3JjZSBhc3luY1xuXHRcdFx0XHRzZXRUaW1lb3V0KHBpY3R1cmVmaWxsKTtcblx0XHRcdH07XG5cblx0XHRcdGltZy5vbmxvYWQgPSB0ZXN0O1xuXHRcdFx0aW1nLm9uZXJyb3IgPSB0ZXN0O1xuXHRcdFx0aW1nLnNldEF0dHJpYnV0ZShcInNpemVzXCIsIFwiOXB4XCIpO1xuXG5cdFx0XHRpbWcuc3Jjc2V0ID0gd2lkdGgxICsgXCIgMXcsXCIgKyB3aWR0aDIgKyBcIiA5d1wiO1xuXHRcdFx0aW1nLnNyYyA9IHdpZHRoMTtcblx0XHR9KSgpO1xuXG5cdH0gZWxzZSB7XG5cdFx0aXNTdXBwb3J0VGVzdFJlYWR5ID0gdHJ1ZTtcblx0fVxuXG5cdC8vIHVzaW5nIHBmLnFzYSBpbnN0ZWFkIG9mIGRvbSB0cmF2ZXJzaW5nIGRvZXMgc2NhbGUgbXVjaCBiZXR0ZXIsXG5cdC8vIGVzcGVjaWFsbHkgb24gc2l0ZXMgbWl4aW5nIHJlc3BvbnNpdmUgYW5kIG5vbi1yZXNwb25zaXZlIGltYWdlc1xuXHRwZi5zZWxTaG9ydCA9IFwicGljdHVyZT5pbWcsaW1nW3NyY3NldF1cIjtcblx0cGYuc2VsID0gcGYuc2VsU2hvcnQ7XG5cdHBmLmNmZyA9IGNmZztcblxuXHQvKipcblx0ICogU2hvcnRjdXQgcHJvcGVydHkgZm9yIGBkZXZpY2VQaXhlbFJhdGlvYCAoIGZvciBlYXN5IG92ZXJyaWRpbmcgaW4gdGVzdHMgKVxuXHQgKi9cblx0cGYuRFBSID0gKERQUiAgfHwgMSApO1xuXHRwZi51ID0gdW5pdHM7XG5cblx0Ly8gY29udGFpbmVyIG9mIHN1cHBvcnRlZCBtaW1lIHR5cGVzIHRoYXQgb25lIG1pZ2h0IG5lZWQgdG8gcXVhbGlmeSBiZWZvcmUgdXNpbmdcblx0cGYudHlwZXMgPSAgdHlwZXM7XG5cblx0cGYuc2V0U2l6ZSA9IG5vb3A7XG5cblx0LyoqXG5cdCAqIEdldHMgYSBzdHJpbmcgYW5kIHJldHVybnMgdGhlIGFic29sdXRlIFVSTFxuXHQgKiBAcGFyYW0gc3JjXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IGFic29sdXRlIFVSTFxuXHQgKi9cblxuXHRwZi5tYWtlVXJsID0gbWVtb2l6ZShmdW5jdGlvbihzcmMpIHtcblx0XHRhbmNob3IuaHJlZiA9IHNyYztcblx0XHRyZXR1cm4gYW5jaG9yLmhyZWY7XG5cdH0pO1xuXG5cdC8qKlxuXHQgKiBHZXRzIGEgRE9NIGVsZW1lbnQgb3IgZG9jdW1lbnQgYW5kIGEgc2VsY3RvciBhbmQgcmV0dXJucyB0aGUgZm91bmQgbWF0Y2hlc1xuXHQgKiBDYW4gYmUgZXh0ZW5kZWQgd2l0aCBqUXVlcnkvU2l6emxlIGZvciBJRTcgc3VwcG9ydFxuXHQgKiBAcGFyYW0gY29udGV4dFxuXHQgKiBAcGFyYW0gc2VsXG5cdCAqIEByZXR1cm5zIHtOb2RlTGlzdHxBcnJheX1cblx0ICovXG5cdHBmLnFzYSA9IGZ1bmN0aW9uKGNvbnRleHQsIHNlbCkge1xuXHRcdHJldHVybiAoIFwicXVlcnlTZWxlY3RvclwiIGluIGNvbnRleHQgKSA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWwpIDogW107XG5cdH07XG5cblx0LyoqXG5cdCAqIFNob3J0Y3V0IG1ldGhvZCBmb3IgbWF0Y2hNZWRpYSAoIGZvciBlYXN5IG92ZXJyaWRpbmcgaW4gdGVzdHMgKVxuXHQgKiB3ZXRoZXIgbmF0aXZlIG9yIHBmLm1NUSBpcyB1c2VkIHdpbGwgYmUgZGVjaWRlZCBsYXp5IG9uIGZpcnN0IGNhbGxcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRwZi5tYXRjaGVzTWVkaWEgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoIHdpbmRvdy5tYXRjaE1lZGlhICYmIChtYXRjaE1lZGlhKCBcIihtaW4td2lkdGg6IDAuMWVtKVwiICkgfHwge30pLm1hdGNoZXMgKSB7XG5cdFx0XHRwZi5tYXRjaGVzTWVkaWEgPSBmdW5jdGlvbiggbWVkaWEgKSB7XG5cdFx0XHRcdHJldHVybiAhbWVkaWEgfHwgKCBtYXRjaE1lZGlhKCBtZWRpYSApLm1hdGNoZXMgKTtcblx0XHRcdH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBmLm1hdGNoZXNNZWRpYSA9IHBmLm1NUTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcGYubWF0Y2hlc01lZGlhLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0fTtcblxuXHQvKipcblx0ICogQSBzaW1wbGlmaWVkIG1hdGNoTWVkaWEgaW1wbGVtZW50YXRpb24gZm9yIElFOCBhbmQgSUU5XG5cdCAqIGhhbmRsZXMgb25seSBtaW4td2lkdGgvbWF4LXdpZHRoIHdpdGggcHggb3IgZW0gdmFsdWVzXG5cdCAqIEBwYXJhbSBtZWRpYVxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdHBmLm1NUSA9IGZ1bmN0aW9uKCBtZWRpYSApIHtcblx0XHRyZXR1cm4gbWVkaWEgPyBldmFsQ1NTKG1lZGlhKSA6IHRydWU7XG5cdH07XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGNhbGN1bGF0ZWQgbGVuZ3RoIGluIGNzcyBwaXhlbCBmcm9tIHRoZSBnaXZlbiBzb3VyY2VTaXplVmFsdWVcblx0ICogaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3NzLXZhbHVlcy0zLyNsZW5ndGgtdmFsdWVcblx0ICogaW50ZW5kZWQgU3BlYyBtaXNtYXRjaGVzOlxuXHQgKiAqIERvZXMgbm90IGNoZWNrIGZvciBpbnZhbGlkIHVzZSBvZiBDU1MgZnVuY3Rpb25zXG5cdCAqICogRG9lcyBoYW5kbGUgYSBjb21wdXRlZCBsZW5ndGggb2YgMCB0aGUgc2FtZSBhcyBhIG5lZ2F0aXZlIGFuZCB0aGVyZWZvcmUgaW52YWxpZCB2YWx1ZVxuXHQgKiBAcGFyYW0gc291cmNlU2l6ZVZhbHVlXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9XG5cdCAqL1xuXHRwZi5jYWxjTGVuZ3RoID0gZnVuY3Rpb24oIHNvdXJjZVNpemVWYWx1ZSApIHtcblxuXHRcdHZhciB2YWx1ZSA9IGV2YWxDU1Moc291cmNlU2l6ZVZhbHVlLCB0cnVlKSB8fCBmYWxzZTtcblx0XHRpZiAodmFsdWUgPCAwKSB7XG5cdFx0XHR2YWx1ZSA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB2YWx1ZTtcblx0fTtcblxuXHQvKipcblx0ICogVGFrZXMgYSB0eXBlIHN0cmluZyBhbmQgY2hlY2tzIGlmIGl0cyBzdXBwb3J0ZWRcblx0ICovXG5cblx0cGYuc3VwcG9ydHNUeXBlID0gZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuICggdHlwZSApID8gdHlwZXNbIHR5cGUgXSA6IHRydWU7XG5cdH07XG5cblx0LyoqXG5cdCAqIFBhcnNlcyBhIHNvdXJjZVNpemUgaW50byBtZWRpYUNvbmRpdGlvbiAobWVkaWEpIGFuZCBzb3VyY2VTaXplVmFsdWUgKGxlbmd0aClcblx0ICogQHBhcmFtIHNvdXJjZVNpemVTdHJcblx0ICogQHJldHVybnMgeyp9XG5cdCAqL1xuXHRwZi5wYXJzZVNpemUgPSBtZW1vaXplKGZ1bmN0aW9uKCBzb3VyY2VTaXplU3RyICkge1xuXHRcdHZhciBtYXRjaCA9ICggc291cmNlU2l6ZVN0ciB8fCBcIlwiICkubWF0Y2gocmVnU2l6ZSk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdG1lZGlhOiBtYXRjaCAmJiBtYXRjaFsxXSxcblx0XHRcdGxlbmd0aDogbWF0Y2ggJiYgbWF0Y2hbMl1cblx0XHR9O1xuXHR9KTtcblxuXHRwZi5wYXJzZVNldCA9IGZ1bmN0aW9uKCBzZXQgKSB7XG5cdFx0aWYgKCAhc2V0LmNhbmRzICkge1xuXHRcdFx0c2V0LmNhbmRzID0gcGFyc2VTcmNzZXQoc2V0LnNyY3NldCwgc2V0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHNldC5jYW5kcztcblx0fTtcblxuXHQvKipcblx0ICogcmV0dXJucyAxZW0gaW4gY3NzIHB4IGZvciBodG1sL2JvZHkgZGVmYXVsdCBzaXplXG5cdCAqIGZ1bmN0aW9uIHRha2VuIGZyb20gcmVzcG9uZGpzXG5cdCAqIEByZXR1cm5zIHsqfG51bWJlcn1cblx0ICovXG5cdHBmLmdldEVtVmFsdWUgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgYm9keTtcblx0XHRpZiAoICFlbWlucHggJiYgKGJvZHkgPSBkb2N1bWVudC5ib2R5KSApIHtcblx0XHRcdHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXG5cdFx0XHRcdG9yaWdpbmFsSFRNTENTUyA9IGRvY0VsZW0uc3R5bGUuY3NzVGV4dCxcblx0XHRcdFx0b3JpZ2luYWxCb2R5Q1NTID0gYm9keS5zdHlsZS5jc3NUZXh0O1xuXG5cdFx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9IGJhc2VTdHlsZTtcblxuXHRcdFx0Ly8gMWVtIGluIGEgbWVkaWEgcXVlcnkgaXMgdGhlIHZhbHVlIG9mIHRoZSBkZWZhdWx0IGZvbnQgc2l6ZSBvZiB0aGUgYnJvd3NlclxuXHRcdFx0Ly8gcmVzZXQgZG9jRWxlbSBhbmQgYm9keSB0byBlbnN1cmUgdGhlIGNvcnJlY3QgdmFsdWUgaXMgcmV0dXJuZWRcblx0XHRcdGRvY0VsZW0uc3R5bGUuY3NzVGV4dCA9IGZzQ3NzO1xuXHRcdFx0Ym9keS5zdHlsZS5jc3NUZXh0ID0gZnNDc3M7XG5cblx0XHRcdGJvZHkuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXHRcdFx0ZW1pbnB4ID0gZGl2Lm9mZnNldFdpZHRoO1xuXHRcdFx0Ym9keS5yZW1vdmVDaGlsZCggZGl2ICk7XG5cblx0XHRcdC8vYWxzbyB1cGRhdGUgZW1pbnB4IGJlZm9yZSByZXR1cm5pbmdcblx0XHRcdGVtaW5weCA9IHBhcnNlRmxvYXQoIGVtaW5weCwgMTAgKTtcblxuXHRcdFx0Ly8gcmVzdG9yZSB0aGUgb3JpZ2luYWwgdmFsdWVzXG5cdFx0XHRkb2NFbGVtLnN0eWxlLmNzc1RleHQgPSBvcmlnaW5hbEhUTUxDU1M7XG5cdFx0XHRib2R5LnN0eWxlLmNzc1RleHQgPSBvcmlnaW5hbEJvZHlDU1M7XG5cblx0XHR9XG5cdFx0cmV0dXJuIGVtaW5weCB8fCAxNjtcblx0fTtcblxuXHQvKipcblx0ICogVGFrZXMgYSBzdHJpbmcgb2Ygc2l6ZXMgYW5kIHJldHVybnMgdGhlIHdpZHRoIGluIHBpeGVscyBhcyBhIG51bWJlclxuXHQgKi9cblx0cGYuY2FsY0xpc3RMZW5ndGggPSBmdW5jdGlvbiggc291cmNlU2l6ZUxpc3RTdHIgKSB7XG5cdFx0Ly8gU3BsaXQgdXAgc291cmNlIHNpemUgbGlzdCwgaWUgKCBtYXgtd2lkdGg6IDMwZW0gKSAxMDAlLCAoIG1heC13aWR0aDogNTBlbSApIDUwJSwgMzMlXG5cdFx0Ly9cblx0XHQvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIChtaW4td2lkdGg6MzBlbSkgY2FsYygzMCUgLSAxNXB4KVxuXHRcdGlmICggIShzb3VyY2VTaXplTGlzdFN0ciBpbiBzaXplTGVuZ3RoQ2FjaGUpIHx8IGNmZy51VCApIHtcblx0XHRcdHZhciB3aW5uaW5nTGVuZ3RoID0gcGYuY2FsY0xlbmd0aCggcGFyc2VTaXplcyggc291cmNlU2l6ZUxpc3RTdHIgKSApO1xuXG5cdFx0XHRzaXplTGVuZ3RoQ2FjaGVbIHNvdXJjZVNpemVMaXN0U3RyIF0gPSAhd2lubmluZ0xlbmd0aCA/IHVuaXRzLndpZHRoIDogd2lubmluZ0xlbmd0aDtcblx0XHR9XG5cblx0XHRyZXR1cm4gc2l6ZUxlbmd0aENhY2hlWyBzb3VyY2VTaXplTGlzdFN0ciBdO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBUYWtlcyBhIGNhbmRpZGF0ZSBvYmplY3Qgd2l0aCBhIHNyY3NldCBwcm9wZXJ0eSBpbiB0aGUgZm9ybSBvZiB1cmwvXG5cdCAqIGV4LiBcImltYWdlcy9waWMtbWVkaXVtLnBuZyAxeCwgaW1hZ2VzL3BpYy1tZWRpdW0tMngucG5nIDJ4XCIgb3Jcblx0ICogICAgIFwiaW1hZ2VzL3BpYy1tZWRpdW0ucG5nIDQwMHcsIGltYWdlcy9waWMtbWVkaXVtLTJ4LnBuZyA4MDB3XCIgb3Jcblx0ICogICAgIFwiaW1hZ2VzL3BpYy1zbWFsbC5wbmdcIlxuXHQgKiBHZXQgYW4gYXJyYXkgb2YgaW1hZ2UgY2FuZGlkYXRlcyBpbiB0aGUgZm9ybSBvZlxuXHQgKiAgICAgIHt1cmw6IFwiL2Zvby9iYXIucG5nXCIsIHJlc29sdXRpb246IDF9XG5cdCAqIHdoZXJlIHJlc29sdXRpb24gaXMgaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3NzLXZhbHVlcy0zLyNyZXNvbHV0aW9uLXZhbHVlXG5cdCAqIElmIHNpemVzIGlzIHNwZWNpZmllZCwgcmVzIGlzIGNhbGN1bGF0ZWRcblx0ICovXG5cdHBmLnNldFJlcyA9IGZ1bmN0aW9uKCBzZXQgKSB7XG5cdFx0dmFyIGNhbmRpZGF0ZXM7XG5cdFx0aWYgKCBzZXQgKSB7XG5cblx0XHRcdGNhbmRpZGF0ZXMgPSBwZi5wYXJzZVNldCggc2V0ICk7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMCwgbGVuID0gY2FuZGlkYXRlcy5sZW5ndGg7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0c2V0UmVzb2x1dGlvbiggY2FuZGlkYXRlc1sgaSBdLCBzZXQuc2l6ZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNhbmRpZGF0ZXM7XG5cdH07XG5cblx0cGYuc2V0UmVzLnJlcyA9IHNldFJlc29sdXRpb247XG5cblx0cGYuYXBwbHlTZXRDYW5kaWRhdGUgPSBmdW5jdGlvbiggY2FuZGlkYXRlcywgaW1nICkge1xuXHRcdGlmICggIWNhbmRpZGF0ZXMubGVuZ3RoICkge3JldHVybjt9XG5cdFx0dmFyIGNhbmRpZGF0ZSxcblx0XHRcdGksXG5cdFx0XHRqLFxuXHRcdFx0bGVuZ3RoLFxuXHRcdFx0YmVzdENhbmRpZGF0ZSxcblx0XHRcdGN1clNyYyxcblx0XHRcdGN1ckNhbixcblx0XHRcdGNhbmRpZGF0ZVNyYyxcblx0XHRcdGFib3J0Q3VyU3JjO1xuXG5cdFx0dmFyIGltYWdlRGF0YSA9IGltZ1sgcGYubnMgXTtcblx0XHR2YXIgZHByID0gcGYuRFBSO1xuXG5cdFx0Y3VyU3JjID0gaW1hZ2VEYXRhLmN1clNyYyB8fCBpbWdbY3VyU3JjUHJvcF07XG5cblx0XHRjdXJDYW4gPSBpbWFnZURhdGEuY3VyQ2FuIHx8IHNldFNyY1RvQ3VyKGltZywgY3VyU3JjLCBjYW5kaWRhdGVzWzBdLnNldCk7XG5cblx0XHQvLyBpZiB3ZSBoYXZlIGEgY3VycmVudCBzb3VyY2UsIHdlIG1pZ2h0IGVpdGhlciBiZWNvbWUgbGF6eSBvciBnaXZlIHRoaXMgc291cmNlIHNvbWUgYWR2YW50YWdlXG5cdFx0aWYgKCBjdXJDYW4gJiYgY3VyQ2FuLnNldCA9PT0gY2FuZGlkYXRlc1sgMCBdLnNldCApIHtcblxuXHRcdFx0Ly8gaWYgYnJvd3NlciBjYW4gYWJvcnQgaW1hZ2UgcmVxdWVzdCBhbmQgdGhlIGltYWdlIGhhcyBhIGhpZ2hlciBwaXhlbCBkZW5zaXR5IHRoYW4gbmVlZGVkXG5cdFx0XHQvLyBhbmQgdGhpcyBpbWFnZSBpc24ndCBkb3dubG9hZGVkIHlldCwgd2Ugc2tpcCBuZXh0IHBhcnQgYW5kIHRyeSB0byBzYXZlIGJhbmR3aWR0aFxuXHRcdFx0YWJvcnRDdXJTcmMgPSAoc3VwcG9ydEFib3J0ICYmICFpbWcuY29tcGxldGUgJiYgY3VyQ2FuLnJlcyAtIDAuMSA+IGRwcik7XG5cblx0XHRcdGlmICggIWFib3J0Q3VyU3JjICkge1xuXHRcdFx0XHRjdXJDYW4uY2FjaGVkID0gdHJ1ZTtcblxuXHRcdFx0XHQvLyBpZiBjdXJyZW50IGNhbmRpZGF0ZSBpcyBcImJlc3RcIiwgXCJiZXR0ZXJcIiBvciBcIm9rYXlcIixcblx0XHRcdFx0Ly8gc2V0IGl0IHRvIGJlc3RDYW5kaWRhdGVcblx0XHRcdFx0aWYgKCBjdXJDYW4ucmVzID49IGRwciApIHtcblx0XHRcdFx0XHRiZXN0Q2FuZGlkYXRlID0gY3VyQ2FuO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCAhYmVzdENhbmRpZGF0ZSApIHtcblxuXHRcdFx0Y2FuZGlkYXRlcy5zb3J0KCBhc2NlbmRpbmdTb3J0ICk7XG5cblx0XHRcdGxlbmd0aCA9IGNhbmRpZGF0ZXMubGVuZ3RoO1xuXHRcdFx0YmVzdENhbmRpZGF0ZSA9IGNhbmRpZGF0ZXNbIGxlbmd0aCAtIDEgXTtcblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0Y2FuZGlkYXRlID0gY2FuZGlkYXRlc1sgaSBdO1xuXHRcdFx0XHRpZiAoIGNhbmRpZGF0ZS5yZXMgPj0gZHByICkge1xuXHRcdFx0XHRcdGogPSBpIC0gMTtcblxuXHRcdFx0XHRcdC8vIHdlIGhhdmUgZm91bmQgdGhlIHBlcmZlY3QgY2FuZGlkYXRlLFxuXHRcdFx0XHRcdC8vIGJ1dCBsZXQncyBpbXByb3ZlIHRoaXMgYSBsaXR0bGUgYml0IHdpdGggc29tZSBhc3N1bXB0aW9ucyA7LSlcblx0XHRcdFx0XHRpZiAoY2FuZGlkYXRlc1sgaiBdICYmXG5cdFx0XHRcdFx0XHQoYWJvcnRDdXJTcmMgfHwgY3VyU3JjICE9PSBwZi5tYWtlVXJsKCBjYW5kaWRhdGUudXJsICkpICYmXG5cdFx0XHRcdFx0XHRjaG9vc2VMb3dSZXMoY2FuZGlkYXRlc1sgaiBdLnJlcywgY2FuZGlkYXRlLnJlcywgZHByLCBjYW5kaWRhdGVzWyBqIF0uY2FjaGVkKSkge1xuXG5cdFx0XHRcdFx0XHRiZXN0Q2FuZGlkYXRlID0gY2FuZGlkYXRlc1sgaiBdO1xuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGJlc3RDYW5kaWRhdGUgPSBjYW5kaWRhdGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBiZXN0Q2FuZGlkYXRlICkge1xuXG5cdFx0XHRjYW5kaWRhdGVTcmMgPSBwZi5tYWtlVXJsKCBiZXN0Q2FuZGlkYXRlLnVybCApO1xuXG5cdFx0XHRpbWFnZURhdGEuY3VyU3JjID0gY2FuZGlkYXRlU3JjO1xuXHRcdFx0aW1hZ2VEYXRhLmN1ckNhbiA9IGJlc3RDYW5kaWRhdGU7XG5cblx0XHRcdGlmICggY2FuZGlkYXRlU3JjICE9PSBjdXJTcmMgKSB7XG5cdFx0XHRcdHBmLnNldFNyYyggaW1nLCBiZXN0Q2FuZGlkYXRlICk7XG5cdFx0XHR9XG5cdFx0XHRwZi5zZXRTaXplKCBpbWcgKTtcblx0XHR9XG5cdH07XG5cblx0cGYuc2V0U3JjID0gZnVuY3Rpb24oIGltZywgYmVzdENhbmRpZGF0ZSApIHtcblx0XHR2YXIgb3JpZ1dpZHRoO1xuXHRcdGltZy5zcmMgPSBiZXN0Q2FuZGlkYXRlLnVybDtcblxuXHRcdC8vIGFsdGhvdWdoIHRoaXMgaXMgYSBzcGVjaWZpYyBTYWZhcmkgaXNzdWUsIHdlIGRvbid0IHdhbnQgdG8gdGFrZSB0b28gbXVjaCBkaWZmZXJlbnQgY29kZSBwYXRoc1xuXHRcdGlmICggYmVzdENhbmRpZGF0ZS5zZXQudHlwZSA9PT0gXCJpbWFnZS9zdmcreG1sXCIgKSB7XG5cdFx0XHRvcmlnV2lkdGggPSBpbWcuc3R5bGUud2lkdGg7XG5cdFx0XHRpbWcuc3R5bGUud2lkdGggPSAoaW1nLm9mZnNldFdpZHRoICsgMSkgKyBcInB4XCI7XG5cblx0XHRcdC8vIG5leHQgbGluZSBvbmx5IHNob3VsZCB0cmlnZ2VyIGEgcmVwYWludFxuXHRcdFx0Ly8gaWYuLi4gaXMgb25seSBkb25lIHRvIHRyaWNrIGRlYWQgY29kZSByZW1vdmFsXG5cdFx0XHRpZiAoIGltZy5vZmZzZXRXaWR0aCArIDEgKSB7XG5cdFx0XHRcdGltZy5zdHlsZS53aWR0aCA9IG9yaWdXaWR0aDtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0cGYuZ2V0U2V0ID0gZnVuY3Rpb24oIGltZyApIHtcblx0XHR2YXIgaSwgc2V0LCBzdXBwb3J0c1R5cGU7XG5cdFx0dmFyIG1hdGNoID0gZmFsc2U7XG5cdFx0dmFyIHNldHMgPSBpbWcgWyBwZi5ucyBdLnNldHM7XG5cblx0XHRmb3IgKCBpID0gMDsgaSA8IHNldHMubGVuZ3RoICYmICFtYXRjaDsgaSsrICkge1xuXHRcdFx0c2V0ID0gc2V0c1tpXTtcblxuXHRcdFx0aWYgKCAhc2V0LnNyY3NldCB8fCAhcGYubWF0Y2hlc01lZGlhKCBzZXQubWVkaWEgKSB8fCAhKHN1cHBvcnRzVHlwZSA9IHBmLnN1cHBvcnRzVHlwZSggc2V0LnR5cGUgKSkgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHN1cHBvcnRzVHlwZSA9PT0gXCJwZW5kaW5nXCIgKSB7XG5cdFx0XHRcdHNldCA9IHN1cHBvcnRzVHlwZTtcblx0XHRcdH1cblxuXHRcdFx0bWF0Y2ggPSBzZXQ7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2g7XG5cdH07XG5cblx0cGYucGFyc2VTZXRzID0gZnVuY3Rpb24oIGVsZW1lbnQsIHBhcmVudCwgb3B0aW9ucyApIHtcblx0XHR2YXIgc3Jjc2V0QXR0cmlidXRlLCBpbWFnZVNldCwgaXNXRGVzY3JpcG9yLCBzcmNzZXRQYXJzZWQ7XG5cblx0XHR2YXIgaGFzUGljdHVyZSA9IHBhcmVudCAmJiBwYXJlbnQubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gXCJQSUNUVVJFXCI7XG5cdFx0dmFyIGltYWdlRGF0YSA9IGVsZW1lbnRbIHBmLm5zIF07XG5cblx0XHRpZiAoIGltYWdlRGF0YS5zcmMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnNyYyApIHtcblx0XHRcdGltYWdlRGF0YS5zcmMgPSBnZXRJbWdBdHRyLmNhbGwoIGVsZW1lbnQsIFwic3JjXCIgKTtcblx0XHRcdGlmICggaW1hZ2VEYXRhLnNyYyApIHtcblx0XHRcdFx0c2V0SW1nQXR0ci5jYWxsKCBlbGVtZW50LCBzcmNBdHRyLCBpbWFnZURhdGEuc3JjICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZW1vdmVJbWdBdHRyLmNhbGwoIGVsZW1lbnQsIHNyY0F0dHIgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGltYWdlRGF0YS5zcmNzZXQgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnNyY3NldCB8fCAhcGYuc3VwU3Jjc2V0IHx8IGVsZW1lbnQuc3Jjc2V0ICkge1xuXHRcdFx0c3Jjc2V0QXR0cmlidXRlID0gZ2V0SW1nQXR0ci5jYWxsKCBlbGVtZW50LCBcInNyY3NldFwiICk7XG5cdFx0XHRpbWFnZURhdGEuc3Jjc2V0ID0gc3Jjc2V0QXR0cmlidXRlO1xuXHRcdFx0c3Jjc2V0UGFyc2VkID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpbWFnZURhdGEuc2V0cyA9IFtdO1xuXG5cdFx0aWYgKCBoYXNQaWN0dXJlICkge1xuXHRcdFx0aW1hZ2VEYXRhLnBpYyA9IHRydWU7XG5cdFx0XHRnZXRBbGxTb3VyY2VFbGVtZW50cyggcGFyZW50LCBpbWFnZURhdGEuc2V0cyApO1xuXHRcdH1cblxuXHRcdGlmICggaW1hZ2VEYXRhLnNyY3NldCApIHtcblx0XHRcdGltYWdlU2V0ID0ge1xuXHRcdFx0XHRzcmNzZXQ6IGltYWdlRGF0YS5zcmNzZXQsXG5cdFx0XHRcdHNpemVzOiBnZXRJbWdBdHRyLmNhbGwoIGVsZW1lbnQsIFwic2l6ZXNcIiApXG5cdFx0XHR9O1xuXG5cdFx0XHRpbWFnZURhdGEuc2V0cy5wdXNoKCBpbWFnZVNldCApO1xuXG5cdFx0XHRpc1dEZXNjcmlwb3IgPSAoYWx3YXlzQ2hlY2tXRGVzY3JpcHRvciB8fCBpbWFnZURhdGEuc3JjKSAmJiByZWdXRGVzYy50ZXN0KGltYWdlRGF0YS5zcmNzZXQgfHwgXCJcIik7XG5cblx0XHRcdC8vIGFkZCBub3JtYWwgc3JjIGFzIGNhbmRpZGF0ZSwgaWYgc291cmNlIGhhcyBubyB3IGRlc2NyaXB0b3Jcblx0XHRcdGlmICggIWlzV0Rlc2NyaXBvciAmJiBpbWFnZURhdGEuc3JjICYmICFnZXRDYW5kaWRhdGVGb3JTcmMoaW1hZ2VEYXRhLnNyYywgaW1hZ2VTZXQpICYmICFpbWFnZVNldC5oYXMxeCApIHtcblx0XHRcdFx0aW1hZ2VTZXQuc3Jjc2V0ICs9IFwiLCBcIiArIGltYWdlRGF0YS5zcmM7XG5cdFx0XHRcdGltYWdlU2V0LmNhbmRzLnB1c2goe1xuXHRcdFx0XHRcdHVybDogaW1hZ2VEYXRhLnNyYyxcblx0XHRcdFx0XHRkOiAxLFxuXHRcdFx0XHRcdHNldDogaW1hZ2VTZXRcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBpbWFnZURhdGEuc3JjICkge1xuXHRcdFx0aW1hZ2VEYXRhLnNldHMucHVzaCgge1xuXHRcdFx0XHRzcmNzZXQ6IGltYWdlRGF0YS5zcmMsXG5cdFx0XHRcdHNpemVzOiBudWxsXG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0aW1hZ2VEYXRhLmN1ckNhbiA9IG51bGw7XG5cdFx0aW1hZ2VEYXRhLmN1clNyYyA9IHVuZGVmaW5lZDtcblxuXHRcdC8vIGlmIGltZyBoYXMgcGljdHVyZSBvciB0aGUgc3Jjc2V0IHdhcyByZW1vdmVkIG9yIGhhcyBhIHNyY3NldCBhbmQgZG9lcyBub3Qgc3VwcG9ydCBzcmNzZXQgYXQgYWxsXG5cdFx0Ly8gb3IgaGFzIGEgdyBkZXNjcmlwdG9yIChhbmQgZG9lcyBub3Qgc3VwcG9ydCBzaXplcykgc2V0IHN1cHBvcnQgdG8gZmFsc2UgdG8gZXZhbHVhdGVcblx0XHRpbWFnZURhdGEuc3VwcG9ydGVkID0gISggaGFzUGljdHVyZSB8fCAoIGltYWdlU2V0ICYmICFwZi5zdXBTcmNzZXQgKSB8fCAoaXNXRGVzY3JpcG9yICYmICFwZi5zdXBTaXplcykgKTtcblxuXHRcdGlmICggc3Jjc2V0UGFyc2VkICYmIHBmLnN1cFNyY3NldCAmJiAhaW1hZ2VEYXRhLnN1cHBvcnRlZCApIHtcblx0XHRcdGlmICggc3Jjc2V0QXR0cmlidXRlICkge1xuXHRcdFx0XHRzZXRJbWdBdHRyLmNhbGwoIGVsZW1lbnQsIHNyY3NldEF0dHIsIHNyY3NldEF0dHJpYnV0ZSApO1xuXHRcdFx0XHRlbGVtZW50LnNyY3NldCA9IFwiXCI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZW1vdmVJbWdBdHRyLmNhbGwoIGVsZW1lbnQsIHNyY3NldEF0dHIgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaW1hZ2VEYXRhLnN1cHBvcnRlZCAmJiAhaW1hZ2VEYXRhLnNyY3NldCAmJiAoKCFpbWFnZURhdGEuc3JjICYmIGVsZW1lbnQuc3JjKSB8fCAgZWxlbWVudC5zcmMgIT09IHBmLm1ha2VVcmwoaW1hZ2VEYXRhLnNyYykpKSB7XG5cdFx0XHRpZiAoaW1hZ2VEYXRhLnNyYyA9PT0gbnVsbCkge1xuXHRcdFx0XHRlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShcInNyY1wiKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnQuc3JjID0gaW1hZ2VEYXRhLnNyYztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpbWFnZURhdGEucGFyc2VkID0gdHJ1ZTtcblx0fTtcblxuXHRwZi5maWxsSW1nID0gZnVuY3Rpb24oZWxlbWVudCwgb3B0aW9ucykge1xuXHRcdHZhciBpbWFnZURhdGE7XG5cdFx0dmFyIGV4dHJlbWUgPSBvcHRpb25zLnJlc2VsZWN0IHx8IG9wdGlvbnMucmVldmFsdWF0ZTtcblxuXHRcdC8vIGV4cGFuZG8gZm9yIGNhY2hpbmcgZGF0YSBvbiB0aGUgaW1nXG5cdFx0aWYgKCAhZWxlbWVudFsgcGYubnMgXSApIHtcblx0XHRcdGVsZW1lbnRbIHBmLm5zIF0gPSB7fTtcblx0XHR9XG5cblx0XHRpbWFnZURhdGEgPSBlbGVtZW50WyBwZi5ucyBdO1xuXG5cdFx0Ly8gaWYgdGhlIGVsZW1lbnQgaGFzIGFscmVhZHkgYmVlbiBldmFsdWF0ZWQsIHNraXAgaXRcblx0XHQvLyB1bmxlc3MgYG9wdGlvbnMucmVldmFsdWF0ZWAgaXMgc2V0IHRvIHRydWUgKCB0aGlzLCBmb3IgZXhhbXBsZSxcblx0XHQvLyBpcyBzZXQgdG8gdHJ1ZSB3aGVuIHJ1bm5pbmcgYHBpY3R1cmVmaWxsYCBvbiBgcmVzaXplYCApLlxuXHRcdGlmICggIWV4dHJlbWUgJiYgaW1hZ2VEYXRhLmV2YWxlZCA9PT0gZXZhbElkICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggIWltYWdlRGF0YS5wYXJzZWQgfHwgb3B0aW9ucy5yZWV2YWx1YXRlICkge1xuXHRcdFx0cGYucGFyc2VTZXRzKCBlbGVtZW50LCBlbGVtZW50LnBhcmVudE5vZGUsIG9wdGlvbnMgKTtcblx0XHR9XG5cblx0XHRpZiAoICFpbWFnZURhdGEuc3VwcG9ydGVkICkge1xuXHRcdFx0YXBwbHlCZXN0Q2FuZGlkYXRlKCBlbGVtZW50ICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGltYWdlRGF0YS5ldmFsZWQgPSBldmFsSWQ7XG5cdFx0fVxuXHR9O1xuXG5cdHBmLnNldHVwUnVuID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhYWxyZWFkeVJ1biB8fCBpc1Z3RGlydHkgfHwgKERQUiAhPT0gd2luZG93LmRldmljZVBpeGVsUmF0aW8pICkge1xuXHRcdFx0dXBkYXRlTWV0cmljcygpO1xuXHRcdH1cblx0fTtcblxuXHQvLyBJZiBwaWN0dXJlIGlzIHN1cHBvcnRlZCwgd2VsbCwgdGhhdCdzIGF3ZXNvbWUuXG5cdGlmICggcGYuc3VwUGljdHVyZSApIHtcblx0XHRwaWN0dXJlZmlsbCA9IG5vb3A7XG5cdFx0cGYuZmlsbEltZyA9IG5vb3A7XG5cdH0gZWxzZSB7XG5cblx0XHQgLy8gU2V0IHVwIHBpY3R1cmUgcG9seWZpbGwgYnkgcG9sbGluZyB0aGUgZG9jdW1lbnRcblx0XHQoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaXNEb21SZWFkeTtcblx0XHRcdHZhciByZWdSZWFkeSA9IHdpbmRvdy5hdHRhY2hFdmVudCA/IC9kJHxeYy8gOiAvZCR8XmN8XmkvO1xuXG5cdFx0XHR2YXIgcnVuID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciByZWFkeVN0YXRlID0gZG9jdW1lbnQucmVhZHlTdGF0ZSB8fCBcIlwiO1xuXG5cdFx0XHRcdHRpbWVySWQgPSBzZXRUaW1lb3V0KHJ1biwgcmVhZHlTdGF0ZSA9PT0gXCJsb2FkaW5nXCIgPyAyMDAgOiAgOTk5KTtcblx0XHRcdFx0aWYgKCBkb2N1bWVudC5ib2R5ICkge1xuXHRcdFx0XHRcdHBmLmZpbGxJbWdzKCk7XG5cdFx0XHRcdFx0aXNEb21SZWFkeSA9IGlzRG9tUmVhZHkgfHwgcmVnUmVhZHkudGVzdChyZWFkeVN0YXRlKTtcblx0XHRcdFx0XHRpZiAoIGlzRG9tUmVhZHkgKSB7XG5cdFx0XHRcdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVySWQgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0dmFyIHRpbWVySWQgPSBzZXRUaW1lb3V0KHJ1biwgZG9jdW1lbnQuYm9keSA/IDkgOiA5OSk7XG5cblx0XHRcdC8vIEFsc28gYXR0YWNoIHBpY3R1cmVmaWxsIG9uIHJlc2l6ZSBhbmQgcmVhZHlzdGF0ZWNoYW5nZVxuXHRcdFx0Ly8gaHR0cDovL21vZGVybmphdmFzY3JpcHQuYmxvZ3Nwb3QuY29tLzIwMTMvMDgvYnVpbGRpbmctYmV0dGVyLWRlYm91bmNlLmh0bWxcblx0XHRcdHZhciBkZWJvdW5jZSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcblx0XHRcdFx0dmFyIHRpbWVvdXQsIHRpbWVzdGFtcDtcblx0XHRcdFx0dmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyIGxhc3QgPSAobmV3IERhdGUoKSkgLSB0aW1lc3RhbXA7XG5cblx0XHRcdFx0XHRpZiAobGFzdCA8IHdhaXQpIHtcblx0XHRcdFx0XHRcdHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0IC0gbGFzdCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRpbWVvdXQgPSBudWxsO1xuXHRcdFx0XHRcdFx0ZnVuYygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblxuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dGltZXN0YW1wID0gbmV3IERhdGUoKTtcblxuXHRcdFx0XHRcdGlmICghdGltZW91dCkge1xuXHRcdFx0XHRcdFx0dGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH07XG5cdFx0XHR2YXIgbGFzdENsaWVudFdpZHRoID0gZG9jRWxlbS5jbGllbnRIZWlnaHQ7XG5cdFx0XHR2YXIgb25SZXNpemUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aXNWd0RpcnR5ID0gTWF0aC5tYXgod2luZG93LmlubmVyV2lkdGggfHwgMCwgZG9jRWxlbS5jbGllbnRXaWR0aCkgIT09IHVuaXRzLndpZHRoIHx8IGRvY0VsZW0uY2xpZW50SGVpZ2h0ICE9PSBsYXN0Q2xpZW50V2lkdGg7XG5cdFx0XHRcdGxhc3RDbGllbnRXaWR0aCA9IGRvY0VsZW0uY2xpZW50SGVpZ2h0O1xuXHRcdFx0XHRpZiAoIGlzVndEaXJ0eSApIHtcblx0XHRcdFx0XHRwZi5maWxsSW1ncygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHRvbiggd2luZG93LCBcInJlc2l6ZVwiLCBkZWJvdW5jZShvblJlc2l6ZSwgOTkgKSApO1xuXHRcdFx0b24oIGRvY3VtZW50LCBcInJlYWR5c3RhdGVjaGFuZ2VcIiwgcnVuICk7XG5cdFx0fSkoKTtcblx0fVxuXG5cdHBmLnBpY3R1cmVmaWxsID0gcGljdHVyZWZpbGw7XG5cdC8vdXNlIHRoaXMgaW50ZXJuYWxseSBmb3IgZWFzeSBtb25rZXkgcGF0Y2hpbmcvcGVyZm9ybWFuY2UgdGVzdGluZ1xuXHRwZi5maWxsSW1ncyA9IHBpY3R1cmVmaWxsO1xuXHRwZi50ZWFyZG93blJ1biA9IG5vb3A7XG5cblx0LyogZXhwb3NlIG1ldGhvZHMgZm9yIHRlc3RpbmcgKi9cblx0cGljdHVyZWZpbGwuXyA9IHBmO1xuXG5cdHdpbmRvdy5waWN0dXJlZmlsbENGRyA9IHtcblx0XHRwZjogcGYsXG5cdFx0cHVzaDogZnVuY3Rpb24oYXJncykge1xuXHRcdFx0dmFyIG5hbWUgPSBhcmdzLnNoaWZ0KCk7XG5cdFx0XHRpZiAodHlwZW9mIHBmW25hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0cGZbbmFtZV0uYXBwbHkocGYsIGFyZ3MpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2ZnW25hbWVdID0gYXJnc1swXTtcblx0XHRcdFx0aWYgKGFscmVhZHlSdW4pIHtcblx0XHRcdFx0XHRwZi5maWxsSW1ncyggeyByZXNlbGVjdDogdHJ1ZSB9ICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0d2hpbGUgKHNldE9wdGlvbnMgJiYgc2V0T3B0aW9ucy5sZW5ndGgpIHtcblx0XHR3aW5kb3cucGljdHVyZWZpbGxDRkcucHVzaChzZXRPcHRpb25zLnNoaWZ0KCkpO1xuXHR9XG5cblx0LyogZXhwb3NlIHBpY3R1cmVmaWxsICovXG5cdHdpbmRvdy5waWN0dXJlZmlsbCA9IHBpY3R1cmVmaWxsO1xuXG5cdC8qIGV4cG9zZSBwaWN0dXJlZmlsbCAqL1xuXHRpZiAoIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiICkge1xuXHRcdC8vIENvbW1vbkpTLCBqdXN0IGV4cG9ydFxuXHRcdG1vZHVsZS5leHBvcnRzID0gcGljdHVyZWZpbGw7XG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xuXHRcdC8vIEFNRCBzdXBwb3J0XG5cdFx0ZGVmaW5lKCBcInBpY3R1cmVmaWxsXCIsIGZ1bmN0aW9uKCkgeyByZXR1cm4gcGljdHVyZWZpbGw7IH0gKTtcblx0fVxuXG5cdC8vIElFOCBldmFscyB0aGlzIHN5bmMsIHNvIGl0IG11c3QgYmUgdGhlIGxhc3QgdGhpbmcgd2UgZG9cblx0aWYgKCAhcGYuc3VwUGljdHVyZSApIHtcblx0XHR0eXBlc1sgXCJpbWFnZS93ZWJwXCIgXSA9IGRldGVjdFR5cGVTdXBwb3J0KFwiaW1hZ2Uvd2VicFwiLCBcImRhdGE6aW1hZ2Uvd2VicDtiYXNlNjQsVWtsR1Jrb0FBQUJYUlVKUVZsQTRXQW9BQUFBUUFBQUFBQUFBQUFBQVFVeFFTQXdBQUFBQkJ4QVIvUTlFUlA4REFBQldVRGdnR0FBQUFEQUJBSjBCS2dFQUFRQURBRFFscEFBRGNBRCsrLzFRQUE9PVwiICk7XG5cdH1cblxufSApKCB3aW5kb3csIGRvY3VtZW50ICk7XG4iLCIvKiBzbW9vdGhzY3JvbGwgdjAuNC40IC0gMjAxOSAtIER1c3RhbiBLYXN0ZW4sIEplcmVtaWFzIE1lbmljaGVsbGkgLSBNSVQgTGljZW5zZSAqL1xuKGZ1bmN0aW9uICgpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIHBvbHlmaWxsXG4gIGZ1bmN0aW9uIHBvbHlmaWxsKCkge1xuICAgIC8vIGFsaWFzZXNcbiAgICB2YXIgdyA9IHdpbmRvdztcbiAgICB2YXIgZCA9IGRvY3VtZW50O1xuXG4gICAgLy8gcmV0dXJuIGlmIHNjcm9sbCBiZWhhdmlvciBpcyBzdXBwb3J0ZWQgYW5kIHBvbHlmaWxsIGlzIG5vdCBmb3JjZWRcbiAgICBpZiAoXG4gICAgICAnc2Nyb2xsQmVoYXZpb3InIGluIGQuZG9jdW1lbnRFbGVtZW50LnN0eWxlICYmXG4gICAgICB3Ll9fZm9yY2VTbW9vdGhTY3JvbGxQb2x5ZmlsbF9fICE9PSB0cnVlXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZ2xvYmFsc1xuICAgIHZhciBFbGVtZW50ID0gdy5IVE1MRWxlbWVudCB8fCB3LkVsZW1lbnQ7XG4gICAgdmFyIFNDUk9MTF9USU1FID0gNDY4O1xuXG4gICAgLy8gb2JqZWN0IGdhdGhlcmluZyBvcmlnaW5hbCBzY3JvbGwgbWV0aG9kc1xuICAgIHZhciBvcmlnaW5hbCA9IHtcbiAgICAgIHNjcm9sbDogdy5zY3JvbGwgfHwgdy5zY3JvbGxUbyxcbiAgICAgIHNjcm9sbEJ5OiB3LnNjcm9sbEJ5LFxuICAgICAgZWxlbWVudFNjcm9sbDogRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsIHx8IHNjcm9sbEVsZW1lbnQsXG4gICAgICBzY3JvbGxJbnRvVmlldzogRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsSW50b1ZpZXdcbiAgICB9O1xuXG4gICAgLy8gZGVmaW5lIHRpbWluZyBtZXRob2RcbiAgICB2YXIgbm93ID1cbiAgICAgIHcucGVyZm9ybWFuY2UgJiYgdy5wZXJmb3JtYW5jZS5ub3dcbiAgICAgICAgPyB3LnBlcmZvcm1hbmNlLm5vdy5iaW5kKHcucGVyZm9ybWFuY2UpXG4gICAgICAgIDogRGF0ZS5ub3c7XG5cbiAgICAvKipcbiAgICAgKiBpbmRpY2F0ZXMgaWYgYSB0aGUgY3VycmVudCBicm93c2VyIGlzIG1hZGUgYnkgTWljcm9zb2Z0XG4gICAgICogQG1ldGhvZCBpc01pY3Jvc29mdEJyb3dzZXJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdXNlckFnZW50XG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNaWNyb3NvZnRCcm93c2VyKHVzZXJBZ2VudCkge1xuICAgICAgdmFyIHVzZXJBZ2VudFBhdHRlcm5zID0gWydNU0lFICcsICdUcmlkZW50LycsICdFZGdlLyddO1xuXG4gICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1c2VyQWdlbnRQYXR0ZXJucy5qb2luKCd8JykpLnRlc3QodXNlckFnZW50KTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElFIGhhcyByb3VuZGluZyBidWcgcm91bmRpbmcgZG93biBjbGllbnRIZWlnaHQgYW5kIGNsaWVudFdpZHRoIGFuZFxuICAgICAqIHJvdW5kaW5nIHVwIHNjcm9sbEhlaWdodCBhbmQgc2Nyb2xsV2lkdGggY2F1c2luZyBmYWxzZSBwb3NpdGl2ZXNcbiAgICAgKiBvbiBoYXNTY3JvbGxhYmxlU3BhY2VcbiAgICAgKi9cbiAgICB2YXIgUk9VTkRJTkdfVE9MRVJBTkNFID0gaXNNaWNyb3NvZnRCcm93c2VyKHcubmF2aWdhdG9yLnVzZXJBZ2VudCkgPyAxIDogMDtcblxuICAgIC8qKlxuICAgICAqIGNoYW5nZXMgc2Nyb2xsIHBvc2l0aW9uIGluc2lkZSBhbiBlbGVtZW50XG4gICAgICogQG1ldGhvZCBzY3JvbGxFbGVtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHhcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geVxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICovXG4gICAgZnVuY3Rpb24gc2Nyb2xsRWxlbWVudCh4LCB5KSB7XG4gICAgICB0aGlzLnNjcm9sbExlZnQgPSB4O1xuICAgICAgdGhpcy5zY3JvbGxUb3AgPSB5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgcmVzdWx0IG9mIGFwcGx5aW5nIGVhc2UgbWF0aCBmdW5jdGlvbiB0byBhIG51bWJlclxuICAgICAqIEBtZXRob2QgZWFzZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBrXG4gICAgICogQHJldHVybnMge051bWJlcn1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlYXNlKGspIHtcbiAgICAgIHJldHVybiAwLjUgKiAoMSAtIE1hdGguY29zKE1hdGguUEkgKiBrKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogaW5kaWNhdGVzIGlmIGEgc21vb3RoIGJlaGF2aW9yIHNob3VsZCBiZSBhcHBsaWVkXG4gICAgICogQG1ldGhvZCBzaG91bGRCYWlsT3V0XG4gICAgICogQHBhcmFtIHtOdW1iZXJ8T2JqZWN0fSBmaXJzdEFyZ1xuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNob3VsZEJhaWxPdXQoZmlyc3RBcmcpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZmlyc3RBcmcgPT09IG51bGwgfHxcbiAgICAgICAgdHlwZW9mIGZpcnN0QXJnICE9PSAnb2JqZWN0JyB8fFxuICAgICAgICBmaXJzdEFyZy5iZWhhdmlvciA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIGZpcnN0QXJnLmJlaGF2aW9yID09PSAnYXV0bycgfHxcbiAgICAgICAgZmlyc3RBcmcuYmVoYXZpb3IgPT09ICdpbnN0YW50J1xuICAgICAgKSB7XG4gICAgICAgIC8vIGZpcnN0IGFyZ3VtZW50IGlzIG5vdCBhbiBvYmplY3QvbnVsbFxuICAgICAgICAvLyBvciBiZWhhdmlvciBpcyBhdXRvLCBpbnN0YW50IG9yIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBmaXJzdEFyZyA9PT0gJ29iamVjdCcgJiYgZmlyc3RBcmcuYmVoYXZpb3IgPT09ICdzbW9vdGgnKSB7XG4gICAgICAgIC8vIGZpcnN0IGFyZ3VtZW50IGlzIGFuIG9iamVjdCBhbmQgYmVoYXZpb3IgaXMgc21vb3RoXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGhyb3cgZXJyb3Igd2hlbiBiZWhhdmlvciBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAnYmVoYXZpb3IgbWVtYmVyIG9mIFNjcm9sbE9wdGlvbnMgJyArXG4gICAgICAgICAgZmlyc3RBcmcuYmVoYXZpb3IgK1xuICAgICAgICAgICcgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGVudW1lcmF0aW9uIFNjcm9sbEJlaGF2aW9yLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogaW5kaWNhdGVzIGlmIGFuIGVsZW1lbnQgaGFzIHNjcm9sbGFibGUgc3BhY2UgaW4gdGhlIHByb3ZpZGVkIGF4aXNcbiAgICAgKiBAbWV0aG9kIGhhc1Njcm9sbGFibGVTcGFjZVxuICAgICAqIEBwYXJhbSB7Tm9kZX0gZWxcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYXhpc1xuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc1Njcm9sbGFibGVTcGFjZShlbCwgYXhpcykge1xuICAgICAgaWYgKGF4aXMgPT09ICdZJykge1xuICAgICAgICByZXR1cm4gZWwuY2xpZW50SGVpZ2h0ICsgUk9VTkRJTkdfVE9MRVJBTkNFIDwgZWwuc2Nyb2xsSGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBpZiAoYXhpcyA9PT0gJ1gnKSB7XG4gICAgICAgIHJldHVybiBlbC5jbGllbnRXaWR0aCArIFJPVU5ESU5HX1RPTEVSQU5DRSA8IGVsLnNjcm9sbFdpZHRoO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGluZGljYXRlcyBpZiBhbiBlbGVtZW50IGhhcyBhIHNjcm9sbGFibGUgb3ZlcmZsb3cgcHJvcGVydHkgaW4gdGhlIGF4aXNcbiAgICAgKiBAbWV0aG9kIGNhbk92ZXJmbG93XG4gICAgICogQHBhcmFtIHtOb2RlfSBlbFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBheGlzXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FuT3ZlcmZsb3coZWwsIGF4aXMpIHtcbiAgICAgIHZhciBvdmVyZmxvd1ZhbHVlID0gdy5nZXRDb21wdXRlZFN0eWxlKGVsLCBudWxsKVsnb3ZlcmZsb3cnICsgYXhpc107XG5cbiAgICAgIHJldHVybiBvdmVyZmxvd1ZhbHVlID09PSAnYXV0bycgfHwgb3ZlcmZsb3dWYWx1ZSA9PT0gJ3Njcm9sbCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogaW5kaWNhdGVzIGlmIGFuIGVsZW1lbnQgY2FuIGJlIHNjcm9sbGVkIGluIGVpdGhlciBheGlzXG4gICAgICogQG1ldGhvZCBpc1Njcm9sbGFibGVcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGF4aXNcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1Njcm9sbGFibGUoZWwpIHtcbiAgICAgIHZhciBpc1Njcm9sbGFibGVZID0gaGFzU2Nyb2xsYWJsZVNwYWNlKGVsLCAnWScpICYmIGNhbk92ZXJmbG93KGVsLCAnWScpO1xuICAgICAgdmFyIGlzU2Nyb2xsYWJsZVggPSBoYXNTY3JvbGxhYmxlU3BhY2UoZWwsICdYJykgJiYgY2FuT3ZlcmZsb3coZWwsICdYJyk7XG5cbiAgICAgIHJldHVybiBpc1Njcm9sbGFibGVZIHx8IGlzU2Nyb2xsYWJsZVg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogZmluZHMgc2Nyb2xsYWJsZSBwYXJlbnQgb2YgYW4gZWxlbWVudFxuICAgICAqIEBtZXRob2QgZmluZFNjcm9sbGFibGVQYXJlbnRcbiAgICAgKiBAcGFyYW0ge05vZGV9IGVsXG4gICAgICogQHJldHVybnMge05vZGV9IGVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZFNjcm9sbGFibGVQYXJlbnQoZWwpIHtcbiAgICAgIHdoaWxlIChlbCAhPT0gZC5ib2R5ICYmIGlzU2Nyb2xsYWJsZShlbCkgPT09IGZhbHNlKSB7XG4gICAgICAgIGVsID0gZWwucGFyZW50Tm9kZSB8fCBlbC5ob3N0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogc2VsZiBpbnZva2VkIGZ1bmN0aW9uIHRoYXQsIGdpdmVuIGEgY29udGV4dCwgc3RlcHMgdGhyb3VnaCBzY3JvbGxpbmdcbiAgICAgKiBAbWV0aG9kIHN0ZXBcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RlcChjb250ZXh0KSB7XG4gICAgICB2YXIgdGltZSA9IG5vdygpO1xuICAgICAgdmFyIHZhbHVlO1xuICAgICAgdmFyIGN1cnJlbnRYO1xuICAgICAgdmFyIGN1cnJlbnRZO1xuICAgICAgdmFyIGVsYXBzZWQgPSAodGltZSAtIGNvbnRleHQuc3RhcnRUaW1lKSAvIFNDUk9MTF9USU1FO1xuXG4gICAgICAvLyBhdm9pZCBlbGFwc2VkIHRpbWVzIGhpZ2hlciB0aGFuIG9uZVxuICAgICAgZWxhcHNlZCA9IGVsYXBzZWQgPiAxID8gMSA6IGVsYXBzZWQ7XG5cbiAgICAgIC8vIGFwcGx5IGVhc2luZyB0byBlbGFwc2VkIHRpbWVcbiAgICAgIHZhbHVlID0gZWFzZShlbGFwc2VkKTtcblxuICAgICAgY3VycmVudFggPSBjb250ZXh0LnN0YXJ0WCArIChjb250ZXh0LnggLSBjb250ZXh0LnN0YXJ0WCkgKiB2YWx1ZTtcbiAgICAgIGN1cnJlbnRZID0gY29udGV4dC5zdGFydFkgKyAoY29udGV4dC55IC0gY29udGV4dC5zdGFydFkpICogdmFsdWU7XG5cbiAgICAgIGNvbnRleHQubWV0aG9kLmNhbGwoY29udGV4dC5zY3JvbGxhYmxlLCBjdXJyZW50WCwgY3VycmVudFkpO1xuXG4gICAgICAvLyBzY3JvbGwgbW9yZSBpZiB3ZSBoYXZlIG5vdCByZWFjaGVkIG91ciBkZXN0aW5hdGlvblxuICAgICAgaWYgKGN1cnJlbnRYICE9PSBjb250ZXh0LnggfHwgY3VycmVudFkgIT09IGNvbnRleHQueSkge1xuICAgICAgICB3LnJlcXVlc3RBbmltYXRpb25GcmFtZShzdGVwLmJpbmQodywgY29udGV4dCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHNjcm9sbHMgd2luZG93IG9yIGVsZW1lbnQgd2l0aCBhIHNtb290aCBiZWhhdmlvclxuICAgICAqIEBtZXRob2Qgc21vb3RoU2Nyb2xsXG4gICAgICogQHBhcmFtIHtPYmplY3R8Tm9kZX0gZWxcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5XG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzbW9vdGhTY3JvbGwoZWwsIHgsIHkpIHtcbiAgICAgIHZhciBzY3JvbGxhYmxlO1xuICAgICAgdmFyIHN0YXJ0WDtcbiAgICAgIHZhciBzdGFydFk7XG4gICAgICB2YXIgbWV0aG9kO1xuICAgICAgdmFyIHN0YXJ0VGltZSA9IG5vdygpO1xuXG4gICAgICAvLyBkZWZpbmUgc2Nyb2xsIGNvbnRleHRcbiAgICAgIGlmIChlbCA9PT0gZC5ib2R5KSB7XG4gICAgICAgIHNjcm9sbGFibGUgPSB3O1xuICAgICAgICBzdGFydFggPSB3LnNjcm9sbFggfHwgdy5wYWdlWE9mZnNldDtcbiAgICAgICAgc3RhcnRZID0gdy5zY3JvbGxZIHx8IHcucGFnZVlPZmZzZXQ7XG4gICAgICAgIG1ldGhvZCA9IG9yaWdpbmFsLnNjcm9sbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjcm9sbGFibGUgPSBlbDtcbiAgICAgICAgc3RhcnRYID0gZWwuc2Nyb2xsTGVmdDtcbiAgICAgICAgc3RhcnRZID0gZWwuc2Nyb2xsVG9wO1xuICAgICAgICBtZXRob2QgPSBzY3JvbGxFbGVtZW50O1xuICAgICAgfVxuXG4gICAgICAvLyBzY3JvbGwgbG9vcGluZyBvdmVyIGEgZnJhbWVcbiAgICAgIHN0ZXAoe1xuICAgICAgICBzY3JvbGxhYmxlOiBzY3JvbGxhYmxlLFxuICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUsXG4gICAgICAgIHN0YXJ0WDogc3RhcnRYLFxuICAgICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgICAgeDogeCxcbiAgICAgICAgeTogeVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gT1JJR0lOQUwgTUVUSE9EUyBPVkVSUklERVNcbiAgICAvLyB3LnNjcm9sbCBhbmQgdy5zY3JvbGxUb1xuICAgIHcuc2Nyb2xsID0gdy5zY3JvbGxUbyA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gYXZvaWQgYWN0aW9uIHdoZW4gbm8gYXJndW1lbnRzIGFyZSBwYXNzZWRcbiAgICAgIGlmIChhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGF2b2lkIHNtb290aCBiZWhhdmlvciBpZiBub3QgcmVxdWlyZWRcbiAgICAgIGlmIChzaG91bGRCYWlsT3V0KGFyZ3VtZW50c1swXSkgPT09IHRydWUpIHtcbiAgICAgICAgb3JpZ2luYWwuc2Nyb2xsLmNhbGwoXG4gICAgICAgICAgdyxcbiAgICAgICAgICBhcmd1bWVudHNbMF0ubGVmdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGFyZ3VtZW50c1swXS5sZWZ0XG4gICAgICAgICAgICA6IHR5cGVvZiBhcmd1bWVudHNbMF0gIT09ICdvYmplY3QnXG4gICAgICAgICAgICAgID8gYXJndW1lbnRzWzBdXG4gICAgICAgICAgICAgIDogdy5zY3JvbGxYIHx8IHcucGFnZVhPZmZzZXQsXG4gICAgICAgICAgLy8gdXNlIHRvcCBwcm9wLCBzZWNvbmQgYXJndW1lbnQgaWYgcHJlc2VudCBvciBmYWxsYmFjayB0byBzY3JvbGxZXG4gICAgICAgICAgYXJndW1lbnRzWzBdLnRvcCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGFyZ3VtZW50c1swXS50b3BcbiAgICAgICAgICAgIDogYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBhcmd1bWVudHNbMV1cbiAgICAgICAgICAgICAgOiB3LnNjcm9sbFkgfHwgdy5wYWdlWU9mZnNldFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gTEVUIFRIRSBTTU9PVEhORVNTIEJFR0lOIVxuICAgICAgc21vb3RoU2Nyb2xsLmNhbGwoXG4gICAgICAgIHcsXG4gICAgICAgIGQuYm9keSxcbiAgICAgICAgYXJndW1lbnRzWzBdLmxlZnQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gfn5hcmd1bWVudHNbMF0ubGVmdFxuICAgICAgICAgIDogdy5zY3JvbGxYIHx8IHcucGFnZVhPZmZzZXQsXG4gICAgICAgIGFyZ3VtZW50c1swXS50b3AgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gfn5hcmd1bWVudHNbMF0udG9wXG4gICAgICAgICAgOiB3LnNjcm9sbFkgfHwgdy5wYWdlWU9mZnNldFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgLy8gdy5zY3JvbGxCeVxuICAgIHcuc2Nyb2xsQnkgPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGF2b2lkIGFjdGlvbiB3aGVuIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkXG4gICAgICBpZiAoYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pKSB7XG4gICAgICAgIG9yaWdpbmFsLnNjcm9sbEJ5LmNhbGwoXG4gICAgICAgICAgdyxcbiAgICAgICAgICBhcmd1bWVudHNbMF0ubGVmdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGFyZ3VtZW50c1swXS5sZWZ0XG4gICAgICAgICAgICA6IHR5cGVvZiBhcmd1bWVudHNbMF0gIT09ICdvYmplY3QnID8gYXJndW1lbnRzWzBdIDogMCxcbiAgICAgICAgICBhcmd1bWVudHNbMF0udG9wICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gYXJndW1lbnRzWzBdLnRvcFxuICAgICAgICAgICAgOiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDBcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIExFVCBUSEUgU01PT1RITkVTUyBCRUdJTiFcbiAgICAgIHNtb290aFNjcm9sbC5jYWxsKFxuICAgICAgICB3LFxuICAgICAgICBkLmJvZHksXG4gICAgICAgIH5+YXJndW1lbnRzWzBdLmxlZnQgKyAody5zY3JvbGxYIHx8IHcucGFnZVhPZmZzZXQpLFxuICAgICAgICB+fmFyZ3VtZW50c1swXS50b3AgKyAody5zY3JvbGxZIHx8IHcucGFnZVlPZmZzZXQpXG4gICAgICApO1xuICAgIH07XG5cbiAgICAvLyBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGwgYW5kIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbFRvXG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsID0gRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsVG8gPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGF2b2lkIGFjdGlvbiB3aGVuIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkXG4gICAgICBpZiAoYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pID09PSB0cnVlKSB7XG4gICAgICAgIC8vIGlmIG9uZSBudW1iZXIgaXMgcGFzc2VkLCB0aHJvdyBlcnJvciB0byBtYXRjaCBGaXJlZm94IGltcGxlbWVudGF0aW9uXG4gICAgICAgIGlmICh0eXBlb2YgYXJndW1lbnRzWzBdID09PSAnbnVtYmVyJyAmJiBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignVmFsdWUgY291bGQgbm90IGJlIGNvbnZlcnRlZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3JpZ2luYWwuZWxlbWVudFNjcm9sbC5jYWxsKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgLy8gdXNlIGxlZnQgcHJvcCwgZmlyc3QgbnVtYmVyIGFyZ3VtZW50IG9yIGZhbGxiYWNrIHRvIHNjcm9sbExlZnRcbiAgICAgICAgICBhcmd1bWVudHNbMF0ubGVmdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IH5+YXJndW1lbnRzWzBdLmxlZnRcbiAgICAgICAgICAgIDogdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ29iamVjdCcgPyB+fmFyZ3VtZW50c1swXSA6IHRoaXMuc2Nyb2xsTGVmdCxcbiAgICAgICAgICAvLyB1c2UgdG9wIHByb3AsIHNlY29uZCBhcmd1bWVudCBvciBmYWxsYmFjayB0byBzY3JvbGxUb3BcbiAgICAgICAgICBhcmd1bWVudHNbMF0udG9wICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gfn5hcmd1bWVudHNbMF0udG9wXG4gICAgICAgICAgICA6IGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gfn5hcmd1bWVudHNbMV0gOiB0aGlzLnNjcm9sbFRvcFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlZnQgPSBhcmd1bWVudHNbMF0ubGVmdDtcbiAgICAgIHZhciB0b3AgPSBhcmd1bWVudHNbMF0udG9wO1xuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgdGhpcyxcbiAgICAgICAgdHlwZW9mIGxlZnQgPT09ICd1bmRlZmluZWQnID8gdGhpcy5zY3JvbGxMZWZ0IDogfn5sZWZ0LFxuICAgICAgICB0eXBlb2YgdG9wID09PSAndW5kZWZpbmVkJyA/IHRoaXMuc2Nyb2xsVG9wIDogfn50b3BcbiAgICAgICk7XG4gICAgfTtcblxuICAgIC8vIEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbEJ5XG4gICAgRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsQnkgPSBmdW5jdGlvbigpIHtcbiAgICAgIC8vIGF2b2lkIGFjdGlvbiB3aGVuIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkXG4gICAgICBpZiAoYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBhdm9pZCBzbW9vdGggYmVoYXZpb3IgaWYgbm90IHJlcXVpcmVkXG4gICAgICBpZiAoc2hvdWxkQmFpbE91dChhcmd1bWVudHNbMF0pID09PSB0cnVlKSB7XG4gICAgICAgIG9yaWdpbmFsLmVsZW1lbnRTY3JvbGwuY2FsbChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGFyZ3VtZW50c1swXS5sZWZ0ICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gfn5hcmd1bWVudHNbMF0ubGVmdCArIHRoaXMuc2Nyb2xsTGVmdFxuICAgICAgICAgICAgOiB+fmFyZ3VtZW50c1swXSArIHRoaXMuc2Nyb2xsTGVmdCxcbiAgICAgICAgICBhcmd1bWVudHNbMF0udG9wICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gfn5hcmd1bWVudHNbMF0udG9wICsgdGhpcy5zY3JvbGxUb3BcbiAgICAgICAgICAgIDogfn5hcmd1bWVudHNbMV0gKyB0aGlzLnNjcm9sbFRvcFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zY3JvbGwoe1xuICAgICAgICBsZWZ0OiB+fmFyZ3VtZW50c1swXS5sZWZ0ICsgdGhpcy5zY3JvbGxMZWZ0LFxuICAgICAgICB0b3A6IH5+YXJndW1lbnRzWzBdLnRvcCArIHRoaXMuc2Nyb2xsVG9wLFxuICAgICAgICBiZWhhdmlvcjogYXJndW1lbnRzWzBdLmJlaGF2aW9yXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gRWxlbWVudC5wcm90b3R5cGUuc2Nyb2xsSW50b1ZpZXdcbiAgICBFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxJbnRvVmlldyA9IGZ1bmN0aW9uKCkge1xuICAgICAgLy8gYXZvaWQgc21vb3RoIGJlaGF2aW9yIGlmIG5vdCByZXF1aXJlZFxuICAgICAgaWYgKHNob3VsZEJhaWxPdXQoYXJndW1lbnRzWzBdKSA9PT0gdHJ1ZSkge1xuICAgICAgICBvcmlnaW5hbC5zY3JvbGxJbnRvVmlldy5jYWxsKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB0cnVlIDogYXJndW1lbnRzWzBdXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMRVQgVEhFIFNNT09USE5FU1MgQkVHSU4hXG4gICAgICB2YXIgc2Nyb2xsYWJsZVBhcmVudCA9IGZpbmRTY3JvbGxhYmxlUGFyZW50KHRoaXMpO1xuICAgICAgdmFyIHBhcmVudFJlY3RzID0gc2Nyb2xsYWJsZVBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHZhciBjbGllbnRSZWN0cyA9IHRoaXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIGlmIChzY3JvbGxhYmxlUGFyZW50ICE9PSBkLmJvZHkpIHtcbiAgICAgICAgLy8gcmV2ZWFsIGVsZW1lbnQgaW5zaWRlIHBhcmVudFxuICAgICAgICBzbW9vdGhTY3JvbGwuY2FsbChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIHNjcm9sbGFibGVQYXJlbnQsXG4gICAgICAgICAgc2Nyb2xsYWJsZVBhcmVudC5zY3JvbGxMZWZ0ICsgY2xpZW50UmVjdHMubGVmdCAtIHBhcmVudFJlY3RzLmxlZnQsXG4gICAgICAgICAgc2Nyb2xsYWJsZVBhcmVudC5zY3JvbGxUb3AgKyBjbGllbnRSZWN0cy50b3AgLSBwYXJlbnRSZWN0cy50b3BcbiAgICAgICAgKTtcblxuICAgICAgICAvLyByZXZlYWwgcGFyZW50IGluIHZpZXdwb3J0IHVubGVzcyBpcyBmaXhlZFxuICAgICAgICBpZiAody5nZXRDb21wdXRlZFN0eWxlKHNjcm9sbGFibGVQYXJlbnQpLnBvc2l0aW9uICE9PSAnZml4ZWQnKSB7XG4gICAgICAgICAgdy5zY3JvbGxCeSh7XG4gICAgICAgICAgICBsZWZ0OiBwYXJlbnRSZWN0cy5sZWZ0LFxuICAgICAgICAgICAgdG9wOiBwYXJlbnRSZWN0cy50b3AsXG4gICAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gcmV2ZWFsIGVsZW1lbnQgaW4gdmlld3BvcnRcbiAgICAgICAgdy5zY3JvbGxCeSh7XG4gICAgICAgICAgbGVmdDogY2xpZW50UmVjdHMubGVmdCxcbiAgICAgICAgICB0b3A6IGNsaWVudFJlY3RzLnRvcCxcbiAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBjb21tb25qc1xuICAgIG1vZHVsZS5leHBvcnRzID0geyBwb2x5ZmlsbDogcG9seWZpbGwgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBnbG9iYWxcbiAgICBwb2x5ZmlsbCgpO1xuICB9XG5cbn0oKSk7XG4iLCJpbXBvcnQgb2JqZWN0Rml0SW1hZ2VzIGZyb20gJ29iamVjdC1maXQtaW1hZ2VzJ1xuaW1wb3J0ICdwaWN0dXJlZmlsbCcgLy8gVGhpcyBhdXRvZml4ZXMgc3Jjc2V0IG9uIElFL0VkZ2VcbmltcG9ydCBzbW9vdGhzY3JvbGwgZnJvbSAnc21vb3Roc2Nyb2xsLXBvbHlmaWxsJ1xuXG4vLyBraWNrIG9mZiB0aGUgcG9seWZpbGwhXG5zbW9vdGhzY3JvbGwucG9seWZpbGwoKVxuXG5qUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICBvYmplY3RGaXRJbWFnZXMoKVxuICAgIGpRdWVyeSgnW2RhdGEtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKVxufSk7XG5cbi8vSUUgZm9yRWFjaCBwb2x5ZmlsbFxuaWYgKCdOb2RlTGlzdCcgaW4gd2luZG93ICYmICFOb2RlTGlzdC5wcm90b3R5cGUuZm9yRWFjaCkge1xuICAgIE5vZGVMaXN0LnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgICAgIHRoaXNBcmcgPSB0aGlzQXJnIHx8IHdpbmRvd1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzW2ldLCBpLCB0aGlzKVxuICAgICAgICB9XG4gICAgfTtcbn1cblxuLy8gTW9iaWxlIHZoIGZpeFxuLy8gV2UgbGlzdGVuIHRvIHRoZSByZXNpemUgZXZlbnRcbmxldCB2aCA9IHdpbmRvdy5pbm5lckhlaWdodCAqIDAuMDE7XG5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tdmgnLCBgJHt2aH1weGApO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgKCkgPT4ge1xuICAgIC8vIFdlIGV4ZWN1dGUgdGhlIHNhbWUgc2NyaXB0IGFzIGJlZm9yZVxuICAgIGxldCB2aCA9IHdpbmRvdy5pbm5lckhlaWdodCAqIDAuMDE7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLXZoJywgYCR7dmh9cHhgKTtcbn0pOyJdfQ=="}