{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/es6-promise/dist/es6-promise.js","node_modules/process/browser.js","public/assets/js/components/check-critical-css.js","public/assets/js/components/collapsible-section.js","public/assets/js/components/confirm.js","public/assets/js/components/cookies.js","public/assets/js/components/gmaps-api.js","public/assets/js/components/site/enroll-together.js","public/assets/js/components/site/gmaps-map.js","public/assets/js/components/site/menu-toggle.js","public/assets/js/components/site/schedule.js","public/assets/js/components/site/search-course.js","public/assets/js/components/site/search-widget.js","public/assets/js/components/site/table-divider.js","public/assets/js/components/site/time-difference.js","public/assets/js/components/site/truncate-text.js","public/assets/js/components/site/wrapper-padding.js","public/assets/js/components/user/profile-billing-toggle.js","public/assets/js/components/youtube-player.js","public/assets/js/site.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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC/pCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChCA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"site-00afb23ca2.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 postsJSON\n values[1] // => commentsJSON\n\n return values;\n });\n ```\n\n @class Promise\n @param {Function} resolver\n Useful for tooling.\n @constructor\n*/\n\nvar Promise$1 = function () {\n function Promise(resolver) {\n this[PROMISE_ID] = nextId();\n this._result = this._state = undefined;\n this._subscribers = [];\n\n if (noop !== resolver) {\n typeof resolver !== 'function' && needsResolver();\n this instanceof Promise ? initializePromise(this, resolver) : needsNew();\n }\n }\n\n /**\n The primary way of interacting with a promise is through its `then` method,\n which registers callbacks to receive either a promise's eventual value or the\n reason why the promise cannot be fulfilled.\n ```js\n findUser().then(function(user){\n // user is available\n }, function(reason){\n // user is unavailable, and you are given the reason why\n });\n ```\n Chaining\n --------\n The return value of `then` is itself a promise. This second, 'downstream'\n promise is resolved with the return value of the first promise's fulfillment\n or rejection handler, or rejected if the handler throws an exception.\n ```js\n findUser().then(function (user) {\n return user.name;\n }, function (reason) {\n return 'default name';\n }).then(function (userName) {\n // If `findUser` fulfilled, `userName` will be the user's name, otherwise it\n // will be `'default name'`\n });\n findUser().then(function (user) {\n throw new Error('Found user, but still unhappy');\n }, function (reason) {\n throw new Error('`findUser` rejected and we're unhappy');\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.\n // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.\n });\n ```\n If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.\n ```js\n findUser().then(function (user) {\n throw new PedagogicalException('Upstream error');\n }).then(function (value) {\n // never reached\n }).then(function (value) {\n // never reached\n }, function (reason) {\n // The `PedgagocialException` is propagated all the way down to here\n });\n ```\n Assimilation\n ------------\n Sometimes the value you want to propagate to a downstream promise can only be\n retrieved asynchronously. This can be achieved by returning a promise in the\n fulfillment or rejection handler. The downstream promise will then be pending\n until the returned promise is settled. This is called *assimilation*.\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // The user's comments are now available\n });\n ```\n If the assimliated promise rejects, then the downstream promise will also reject.\n ```js\n findUser().then(function (user) {\n return findCommentsByAuthor(user);\n }).then(function (comments) {\n // If `findCommentsByAuthor` fulfills, we'll have the value here\n }, function (reason) {\n // If `findCommentsByAuthor` rejects, we'll have the reason here\n });\n ```\n Simple Example\n --------------\n Synchronous Example\n ```javascript\n let result;\n try {\n result = findResult();\n // success\n } catch(reason) {\n // failure\n }\n ```\n Errback Example\n ```js\n findResult(function(result, err){\n if (err) {\n // failure\n } else {\n // success\n }\n });\n ```\n Promise Example;\n ```javascript\n findResult().then(function(result){\n // success\n }, function(reason){\n // failure\n });\n ```\n Advanced Example\n --------------\n Synchronous Example\n ```javascript\n let author, books;\n try {\n author = findAuthor();\n books = findBooksByAuthor(author);\n // success\n } catch(reason) {\n // failure\n }\n ```\n Errback Example\n ```js\n function foundBooks(books) {\n }\n function failure(reason) {\n }\n findAuthor(function(author, err){\n if (err) {\n failure(err);\n // failure\n } else {\n try {\n findBoooksByAuthor(author, function(books, err) {\n if (err) {\n failure(err);\n } else {\n try {\n foundBooks(books);\n } catch(reason) {\n failure(reason);\n }\n }\n });\n } catch(error) {\n failure(err);\n }\n // success\n }\n });\n ```\n Promise Example;\n ```javascript\n findAuthor().\n then(findBooksByAuthor).\n then(function(books){\n // found books\n }).catch(function(reason){\n // something went wrong\n });\n ```\n @method then\n @param {Function} onFulfilled\n @param {Function} onRejected\n Useful for tooling.\n @return {Promise}\n */\n\n /**\n `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same\n as the catch block of a try/catch statement.\n ```js\n function findAuthor(){\n throw new Error('couldn't find that author');\n }\n // synchronous\n try {\n findAuthor();\n } catch(reason) {\n // something went wrong\n }\n // async with promises\n findAuthor().catch(function(reason){\n // something went wrong\n });\n ```\n @method catch\n @param {Function} onRejection\n Useful for tooling.\n @return {Promise}\n */\n\n\n Promise.prototype.catch = function _catch(onRejection) {\n return this.then(null, onRejection);\n };\n\n /**\n `finally` will be invoked regardless of the promise's fate just as native\n try/catch/finally behaves\n \n Synchronous example:\n \n ```js\n findAuthor() {\n if (Math.random() > 0.5) {\n throw new Error();\n }\n return new Author();\n }\n \n try {\n return findAuthor(); // succeed or fail\n } catch(error) {\n return findOtherAuther();\n } finally {\n // always runs\n // doesn't affect the return value\n }\n ```\n \n Asynchronous example:\n \n ```js\n findAuthor().catch(function(reason){\n return findOtherAuther();\n }).finally(function(){\n // author was either found, or not\n });\n ```\n \n @method finally\n @param {Function} callback\n @return {Promise}\n */\n\n\n Promise.prototype.finally = function _finally(callback) {\n var promise = this;\n var constructor = promise.constructor;\n\n if (isFunction(callback)) {\n return promise.then(function (value) {\n return constructor.resolve(callback()).then(function () {\n return value;\n });\n }, function (reason) {\n return constructor.resolve(callback()).then(function () {\n throw reason;\n });\n });\n }\n\n return promise.then(callback, callback);\n };\n\n return Promise;\n}();\n\nPromise$1.prototype.then = then;\nPromise$1.all = all;\nPromise$1.race = race;\nPromise$1.resolve = resolve$1;\nPromise$1.reject = reject$1;\nPromise$1._setScheduler = setScheduler;\nPromise$1._setAsap = setAsap;\nPromise$1._asap = asap;\n\n/*global self*/\nfunction polyfill() {\n var local = void 0;\n\n if (typeof global !== 'undefined') {\n local = global;\n } else if (typeof self !== 'undefined') {\n local = self;\n } else {\n try {\n local = Function('return this')();\n } catch (e) {\n throw new Error('polyfill failed because global object is unavailable in this environment');\n }\n }\n\n var P = local.Promise;\n\n if (P) {\n var promiseToString = null;\n try {\n promiseToString = Object.prototype.toString.call(P.resolve());\n } catch (e) {\n // silently ignored\n }\n\n if (promiseToString === '[object Promise]' && !P.cast) {\n return;\n }\n }\n\n local.Promise = Promise$1;\n}\n\n// Strange compat..\nPromise$1.polyfill = polyfill;\nPromise$1.Promise = Promise$1;\n\nreturn Promise$1;\n\n})));\n\n\n\n//# sourceMappingURL=es6-promise.map\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","'use strict';\n\nvar cookies = require('./cookies');\n\n$(window).on('load', function () {\n\t// If rel is not preload, either browser or polyfill has loaded stylesheet\n\tif (\n\t\t$('link[data-stylesheet]').attr('rel') !== 'preload'\n\t\t&& (\n\t\t\t!cookies.getItem('fuentes_critical_css')\n\t\t\t||\n\t\t\tcookies.getItem('fuentes_critical_css') !== $('[data-mtime]').data('mtime')\n\t\t)\n\t) {\n\t\t// Check if new data-mtime is available and set it in cookie\n\t\tif ( $('[data-mtime]').data('mtime') !== undefined ) {\n\t\t\tcookies.setItem('fuentes_critical_css', $('[data-mtime]').data('mtime'));\n\t\t}\n\t}\n});\n","const TOGGLE_CLASS = 'is-shown';\nconst DEFAULT_OPEN_CLASS = 'default-open';\n\nfunction initCollapsibleSection(toggle) {\n const sectionParent = toggle.closest('[data-js-bind=\"collapsible-section\"]');\n const controlledPanel = document.querySelector(\n `#${toggle.getAttribute('aria-controls')}`\n );\n\n const closeOtherAccordionSection = () => {\n const expandedToggle = document.querySelector(\n '[data-js-bind=\"collapsible-toggle\"][aria-expanded=\"true\"]'\n );\n const expandedPanel = document.querySelector(\n '.is-shown[data-js-bind=\"collapsible-panel\"]'\n );\n\n if (!expandedToggle || !expandedPanel) return;\n\n expandedToggle.setAttribute('aria-expanded', false);\n expandedPanel.classList.remove(TOGGLE_CLASS);\n expandedPanel.classList.remove(DEFAULT_OPEN_CLASS);\n };\n\n const toggleSection = () => {\n const collapsibleAllToggle = document.querySelector(\n '[data-js-bind=\"collapsible-all-toggle\"]'\n );\n const expandedToggles = [...document.querySelectorAll(\n `[data-js-bind=\"collapsible-toggle\"]`\n )];\n const expanded = toggle.getAttribute('aria-expanded') === 'true' || false;\n\n if (toggle.getAttribute('data-accordion') === 'true') {\n closeOtherAccordionSection();\n }\n\n toggle.setAttribute('aria-expanded', !expanded);\n controlledPanel.classList.toggle(TOGGLE_CLASS, !expanded);\n controlledPanel.classList.remove(DEFAULT_OPEN_CLASS);\n\n if (!expanded && toggle.dataset.scrollIntoView === 'true') {\n toggle.parentNode.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n if (collapsibleAllToggle) {\n expandedToggles.some((expandedToggle) => {\n return expandedToggle.getAttribute('aria-expanded') === 'true';\n }) ? collapsibleAllToggle.textContent = \"Alles inklappen\" : collapsibleAllToggle.textContent = \"Alles uitklappen\";\n }\n };\n\n if (window.location.hash === `#${sectionParent.id}`) {\n toggleSection();\n toggle.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n toggle.addEventListener('click', toggleSection);\n\n // expose destroy method\n return () => {\n toggle.removeEventListener('click', toggleSection);\n };\n}\n\nconst toggles = document.querySelectorAll('[data-js-bind=\"collapsible-toggle\"]');\ntoggles.forEach((toggle) => {\n initCollapsibleSection(toggle);\n});\n\nmodule.exports = initCollapsibleSection;\n","if ($('[data-confirm]').length) {\n $('[data-confirm]').on('click', function (e) {\n if (!window.confirm($(this).data('confirm'))) {\n e.preventDefault();\n }\n });\n}","var docCookies = {\n\tgetItem: function (sKey) {\n\t\tif (!sKey) { return null; }\n\t\treturn decodeURIComponent(document.cookie.replace(new RegExp(\"(?:(?:^|.*;)\\\\s*\" + encodeURIComponent(sKey).replace(/[\\-\\.\\+\\*]/g, \"\\\\$&\") + \"\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$\"), \"$1\")) || null;\n\t},\n\tsetItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {\n\t\tif (!sKey || /^(?:expires|max\\-age|path|domain|secure)$/i.test(sKey)) { return false; }\n\t\tvar sExpires = \"\";\n\t\tif (vEnd) {\n\t\t\tswitch (vEnd.constructor) {\n\t\t\t\tcase Number:\n\t\t\t\t\tsExpires = vEnd === Infinity ? \"; expires=Fri, 31 Dec 9999 23:59:59 GMT\" : \"; max-age=\" + vEnd;\n\t\t\t\t\tbreak;\n\t\t\t\tcase String:\n\t\t\t\t\tsExpires = \"; expires=\" + vEnd;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Date:\n\t\t\t\t\tsExpires = \"; expires=\" + vEnd.toUTCString();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tdocument.cookie = encodeURIComponent(sKey) + \"=\" + encodeURIComponent(sValue) + sExpires + (sDomain ? \"; domain=\" + sDomain : \"\") + (sPath ? \"; path=\" + sPath : \"\") + (bSecure ? \"; secure\" : \"\");\n\t\treturn true;\n\t},\n\tremoveItem: function (sKey, sPath, sDomain) {\n\t\tif (!this.hasItem(sKey)) { return false; }\n\t\tdocument.cookie = encodeURIComponent(sKey) + \"=; expires=Thu, 01 Jan 1970 00:00:00 GMT\" + (sDomain ? \"; domain=\" + sDomain : \"\") + (sPath ? \"; path=\" + sPath : \"\");\n\t\treturn true;\n\t},\n\thasItem: function (sKey) {\n\t\tif (!sKey) { return false; }\n\t\treturn (new RegExp(\"(?:^|;\\\\s*)\" + encodeURIComponent(sKey).replace(/[\\-\\.\\+\\*]/g, \"\\\\$&\") + \"\\\\s*\\\\=\")).test(document.cookie);\n\t},\n\tkeys: function () {\n\t\tvar aKeys = document.cookie.replace(/((?:^|\\s*;)[^\\=]+)(?=;|$)|^\\s*|\\s*(?:\\=[^;]*)?(?:\\1|$)/g, \"\").split(/\\s*(?:\\=[^;]*)?;\\s*/);\n\t\tfor (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }\n\t\treturn aKeys;\n\t}\n};\n\nmodule.exports = docCookies;","'use strict';\n\n// Polyfill promises\nwindow.Promise = window.Promise || require('es6-promise').Promise;\n\nvar loaded = false;\n\n/**\n * Google Maps API service\n * @type {Promise}\n */\nfunction getMapsAPI() {\n\tif ( loaded === false ) {\n\t\tloadScript();\n\t}\n\n\treturn new Promise(function gmapsApiPromise(resolve, reject) {\n\t\tvar gmapApi;\n\n\t\t// Function gets called when Google Maps API has loaded\n\t\twindow.initGoogleMaps = function initGoogleMaps() {\n\t\t\tgmapApi = google.maps;\n\n\t\t\tloaded = true;\n\n\t\t\tresolve(gmapApi);\n\t\t};\n\t});\n};\n\n// Inits the appending of the gmaps script\nfunction loadScript() {\n\tvar script = document.createElement('script');\n\tscript.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyD_FKTPHezZ83BmvScUWOmNZNM3NMSgpgY&callback=window.initGoogleMaps';\n\tscript.async = true;\n\tscript.defer = true;\n\tdocument.body.appendChild(script);\n}\n\n// Utility function to get the maps API\nmodule.exports = {\n\tgetMapsAPI: getMapsAPI\n};","const $enrollTogetherInfo = $('[data-js-bind=\"enroll-together\"]');\nlet recalcPositions;\n\nfunction checkPopupPositions() {\n if (recalcPositions) cancelAnimationFrame(recalcPositions);\n recalcPositions = requestAnimationFrame(function() {\n for (let i = 0; i < $enrollTogetherInfo.length; i++) {\n const thisInfo = $enrollTogetherInfo[i];\n const thisPopup = thisInfo.querySelector('[data-js-bind=\"enroll-together-popup\"]');\n const thisInfoBottom = thisInfo.getBoundingClientRect().bottom;\n const popupHeight = thisPopup.getBoundingClientRect().height;\n thisInfo.classList[thisInfoBottom + popupHeight >= window.innerHeight? 'add' : 'remove']('c-enroll-together--popup-top');\n }\n });\n}\n\nwindow.addEventListener('resize', checkPopupPositions);\nwindow.addEventListener('scroll', checkPopupPositions);\n\ncheckPopupPositions();\n","'use strict';\n\nvar gmaps = require('../gmaps-api');\n\nvar $mapsContainer = $('.locations-map');\nvar zoomLevel = document.documentElement.clientWidth < 480 ? 9 : 10;\nvar isCityMap = $mapsContainer.data('maptype') === 'city';\n\nwindow.initMap = function () {\n if ( $mapsContainer.length ) {\n gmaps.getMapsAPI()\n // Loaded maps\n .then(loadMaps)\n // Error loading maps\n .catch(function mapsError(e) {\n console.error(e);\n });\n }\n}\n\nif (!isCityMap) {\n initMap();\n}\n\n\n// Load the map with markers\nfunction loadMaps(gmaps) {\n\tvar markerData = $mapsContainer.data('markers');\n\tvar markers = [];\n\n\t// Config options\n\tvar mapConfig = {\n\t\tzoom: isCityMap? 16 : 8,\n\t\tscrollwheel: false,\n\t\tgestureHandling: 'cooperative',\n\t\tmapTypeControl: false,\n\t\tcenter: new gmaps.LatLng(52.100556, 5.645833)\n\t};\n\tvar icon = {\n\t\tanchor: new gmaps.Point(19, 58),\n\t\tscaledSize: new gmaps.Size(60,64),\n\t\turl: '/assets/images/misc/marker.png'\n\t};\n\tvar markerOptions = {\n\t\tanimation: gmaps.Animation.DROP,\n\t\ticon: icon,\n\t\tmap: map\n\t};\n\n\t// Map feature instances\n\tvar bounds = new gmaps.LatLngBounds();\n\tvar map = new gmaps.Map($mapsContainer[0], mapConfig);\n\tvar infoWindow = new gmaps.InfoWindow();\n\n\t// Add markers\n\tmarkerData.forEach(function (marker, i) {\n\t\tvar position = {\n\t\t\tlat: marker.lat,\n\t\t\tlng: marker.lng\n\t\t};\n\n\t\tif ( position.lat === null && position.lng === null ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add marker to map\n\t\tmarkers[i] = new gmaps.Marker({\n\t\t\tposition: position,\n\t\t\ticon: icon,\n\t\t\tmap: map,\n\t\t\tmarkerName: marker.name,\n\t\t\tmarkerUrl: marker.url || false,\n\t\t\taddress1: marker.address1 || false,\n\t\t\taddress2: marker.address2 || false,\n\t\t\tdescription: marker.description || false\n\t\t});\n\n\t\t// Open infoWindow and set content on click on marker\n\t\tmarkers[i].addListener('click', function () {\n\t\t\tinfoWindow.setOptions({\n\t\t\t\tcontent: getInfoWindowContent({\n\t\t\t\t\tname: this.markerName,\n\t\t\t\t\taddress1: this.address1,\n\t\t\t\t\taddress2: this.address2,\n\t\t\t\t\tdescription: this.description,\n\t\t\t\t\turl: this.markerUrl\n\t\t\t\t}),\n\t\t\t\tposition: this.position,\n\t\t\t\tpixelOffset: new gmaps.Size(0, -70)\n\t\t\t});\n\t\t\tinfoWindow.open(map);\n\t\t});\n\n\t\t// Add marker to bounds\n\t\tbounds.extend(position);\n\t});\n\n\t// Fit map to marker bounds and center position\n\tmap.setCenter(bounds.getCenter());\n\tif (markers.length > 1) {\n\t\tmap.fitBounds(bounds);\n\t}\n\n\t// Init geolocation for supporting browsers\n\tinitGeolocation(map, gmaps);\n\n\t// Init geocoding for address search\n\tinitGeocoding(map, gmaps);\n}\n\nfunction getInfoWindowContent(opts) {\n\tvar html = '';\n\tvar directionsUrl;\n\n\thtml += isCityMap? '
' : '
';\n\thtml += \t'

' + opts.name + '

';\n\tif (isCityMap) {\n\t\tdirectionsUrl = encodeURIComponent(opts.address1 + ',' + opts.address2 + ',Nederland');\n\t\thtml += '

' + opts.address1 + ', ' + opts.address2 + '

';\n\t\thtml += opts.description.length > 0? its2017WhyCantFuckingJavascriptDecodeSomeHTML(opts.description) : '';\n\t\thtml += '';\n\t\thtml +=\t'Routebeschrijving';\n\t\thtml +=\tgetSvg('arrow-right', 8, 8);\n\t\thtml += '';\n\t} else {\n\t\thtml += \t'';\n\t\thtml +=\t\tgetSvg('book', 20, 20);\n\t\thtml +=\t\t'Bekijk het cursusaanbod';\n\t\thtml +=\t\tgetSvg('arrow-right', 8, 8);\n\t\thtml += \t'';\n\t}\n\thtml += '
';\n\n\treturn decodeURI(html);\n};\n\nfunction getSvg(name, width, height) {\n\tvar html = '';\n\n\thtml += '';\n\thtml += \t'';\n\thtml += '';\n\n\treturn html;\n}\n\nfunction initGeolocation(map) {\n\tif ( 'geolocation' in navigator && !isCityMap ) {\n\t\tnavigator.geolocation.getCurrentPosition(function processGeolocation(result) {\n\t\t\tif ( result.coords.latitude && result.coords.latitude ) {\n\t\t\t\tmap.setCenter({\n\t\t\t\t\tlat: result.coords.latitude,\n\t\t\t\t\tlng: result.coords.longitude\n\t\t\t\t});\n\t\t\t\tmap.setZoom(zoomLevel);\n\t\t\t}\n\t\t});\n\t}\n}\n\nfunction initGeocoding(map, gmaps) {\n\tvar $searchBar = $('.location-search-bar');\n\tvar $noResults = $searchBar.find('.no-results');\n\tvar geocoder = new gmaps.Geocoder();\n\n\t$searchBar.on('submit', function geocodeAddress(e) {\n\t\tvar $form = $(this);\n\n\t\te.preventDefault();\n\n\t\t$noResults.empty().addClass('hidden');\n\n\t\tgeocoder.geocode({\n\t\t\taddress: $searchBar.find('.location-search-input').val(),\n\t\t\tcomponentRestrictions: {\n\t\t\t\tcountry: 'nl'\n\t\t\t}\n\t\t}, function processResults (results) {\n\t\t\t// if ( results.length && checkTypes(results[0].types) ) {\n\n\t\t\tif ( results.length ) { // IvdW: Disabled result type checking for now (24-01-2017)\n\t\t\t\tmap.setCenter({\n\t\t\t\t\tlat: results[0].geometry.location.lat(),\n\t\t\t\t\tlng: results[0].geometry.location.lng()\n\t\t\t\t});\n\t\t\t\tmap.setZoom(zoomLevel);\n\t\t\t} else {\n\t\t\t\t$noResults.text('Geen resultaten gevonden, probeer het nogmaals').removeClass('hidden');\n\t\t\t}\n\t\t});\n\t});\n}\n\n// Check if items in the result match the allowed types\nfunction checkTypes(types) {\n\tvar allowedTypes = [\n\t\t'sublocality',\n\t\t'locality',\n\t\t'postal_code',\n\t\t'street_address',\n\t\t'colloquial_area',\n\t\t'administrative_area_level_2'\n\t];\n\n\treturn types.some(function functionName(type) {\n\t\treturn allowedTypes.indexOf(type) !== -1\n\t});\n}\n\nfunction its2017WhyCantFuckingJavascriptDecodeSomeHTML(html) {\n\tvar ugh = document.createElement(\"textarea\");\n\tvar comeOnnnn;\n\tugh.innerHTML = html;\n\tcomeOnnnn = ugh.value;\n\treturn comeOnnnn;\n}\n","const header = document.querySelector('[data-js-bind=\"header\"]');\n\nif (!header) return;\n\nconst toggleMenuButton = header.querySelector('[data-js-bind=\"toggle-menu\"]');\nconst menu = header.querySelector(`#${toggleMenuButton.getAttribute('aria-controls')}`);\nconst mainMenu = header.querySelector('[data-js-bind=\"main-menu\"]');\nconst showMenuOnHoverButtons = [...menu.querySelectorAll('[data-js-bind=\"show-menu-on-hover\"]')];\nconst toggleSubMenuButtons = [...menu.querySelectorAll('[data-js-bind=\"toggle-sub-menu\"]')];\nconst subMenus = [...menu.querySelectorAll('[data-js-bind=\"sub-menu\"]')];\nconst subMenuChilds = [...menu.querySelectorAll('[data-js-bind=\"sub-menu\"] [data-js-bind=\"sub-menu\"]')];\n\nif(!toggleMenuButton || !menu) return;\n\nconst MENU_SHOWN_CLASS = 'menu-is-shown';\nconst ACTIVE_BUTTON_CLASS = 'is-active';\nconst ACTIVE_SUBMENU_CLASS = 'is-shown';\n\n// Close the sub menu child\nconst hideSubMenuChildren = () => {\n toggleSubMenuButtons.forEach((subMenuButton) => {\n if (subMenuButton.getAttribute('aria-controls') === \"course-groups-submenu\") return;\n subMenuButton.classList.remove(ACTIVE_BUTTON_CLASS);\n subMenuButton.setAttribute('aria-expanded', false);\n });\n subMenuChilds.forEach((subMenuChild) => {\n subMenuChild.hidden = true;\n });\n};\n\nconst toggleMenu = (menuButton) => {\n const expanded =\n menuButton.getAttribute('aria-expanded') === 'true' || false;\n\n if (!expanded) {\n hideSubMenuChildren();\n };\n\n document.body.classList[expanded ? 'remove' : 'add'](MENU_SHOWN_CLASS);\n menuButton.setAttribute('aria-expanded', !expanded);\n menu.hidden = !expanded;\n};\n\nconst toggleMainMenu = () => {\n const expanded =\n toggleMenuButton.getAttribute('aria-expanded') === 'true' || false;\n \n if (!expanded) {\n hideSubMenuChildren();\n };\n\n toggleMenuButton.setAttribute('aria-expanded', !expanded);\n document.body.classList[expanded ? 'remove' : 'add'](MENU_SHOWN_CLASS);\n menu.hidden = expanded;\n}\n\nconst showSubMenu = (hoverButton) => {\n const button = hoverButton.querySelector('[data-js-bind=\"toggle-sub-menu\"]');\n const subMenuId = button.getAttribute('aria-controls');\n\n // Hide all sub menu childs\n hideSubMenuChildren();\n\n button.setAttribute('aria-expanded', true);\n button.classList.add(ACTIVE_BUTTON_CLASS);\n // Show/hide the submenu controlled by the clicked main menu button\n subMenus.forEach((subMenu) => {\n const clickedSubMenu = subMenu.id === subMenuId;\n // Focus first item in subMenu\n if (clickedSubMenu) {\n subMenu.hidden = false;\n }\n });\n}\n\nconst closeSubMenu = (hoverButton) => {\n const button = hoverButton.querySelector('[data-js-bind=\"toggle-sub-menu\"]');\n const subMenuId = button.getAttribute('aria-controls');\n \n // Hide all sub menu childs\n hideSubMenuChildren();\n\n button.setAttribute('aria-expanded', false);\n button.classList.remove(ACTIVE_BUTTON_CLASS);\n // Show/hide the submenu controlled by the clicked main menu button\n subMenus.forEach((subMenu) => {\n const clickedSubMenu = subMenu.id === subMenuId;\n // Focus first item in subMenu\n if (clickedSubMenu) {\n subMenu.hidden = true;\n }\n });\n};\n\nconst toggleShowSubMenu = (e) => {\n const button = e.target;\n const expanded =\n button.getAttribute('aria-expanded') === 'true' || false;\n const subMenuId = button.getAttribute('aria-controls');\n \n // Hide all sub menu childs\n hideSubMenuChildren();\n\n button.setAttribute('aria-expanded', !expanded);\n button.classList[expanded ? 'remove' : 'add'](ACTIVE_BUTTON_CLASS);\n // Show/hide the submenu controlled by the clicked main menu button\n subMenus.forEach((subMenu) => {\n const clickedSubMenu = subMenu.id === subMenuId;\n if (!subMenu.contains(e.target)) {\n subMenu.classList.remove(ACTIVE_SUBMENU_CLASS);\n }\n // Focus first item in subMenu\n if (clickedSubMenu) {\n subMenu.hidden = expanded;\n subMenu.classList[expanded ? 'remove' : 'add'](ACTIVE_SUBMENU_CLASS);\n }\n });\n};\n\n\nconst hasUserClickedOutsideHeader = (e) => {\n if (!mainMenu.contains(e.target)) {\n toggleSubMenuButtons.forEach((subMenuButton) => {\n subMenuButton.classList.remove(ACTIVE_BUTTON_CLASS);\n subMenuButton.setAttribute('aria-expanded', false);\n });\n subMenus.forEach((subMenu) => {\n subMenu.hidden = true;\n });\n }\n}\n\n// Close the select when clicking outside of it\ndocument.addEventListener('click',hasUserClickedOutsideHeader);\ntoggleMenuButton.addEventListener('click', toggleMainMenu);\ntoggleSubMenuButtons.forEach(toggleSubMenuButton => toggleSubMenuButton.addEventListener('click', toggleShowSubMenu))\n","(function (window, document, $) {\n 'use strict';\n\n if ( $('.modal-schedule').length ) {\n var tableContent, date, d, m, y, displayDate, start, end, displayStart, displayEnd, time, location, online;\n var days = ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'];\n var $modal = $('.modal-schedule').last();\n\n $('.show-schedule').on('click', function(e) {\n var data = JSON.parse($(this).data('schedule'));\n var $tableBody = $modal.find('tbody');\n var rowTemplate = $('.schedule-row').first().html();\n tableContent = '';\n e.preventDefault();\n\n // create table body content from template row\n for (var i = 0; i < data.length; i++) {\n date = data[i].date || false;\n start = data[i].start || false;\n end = data[i].end || false;\n location = data[i].location || 'Volgt nog';\n online = data[i].online;\n\n if ( date ) {\n date = new Date(date);\n d = pad(date.getUTCDate());\n m = pad(date.getUTCMonth() + 1); // yay zero-indexing!\n y = date.getUTCFullYear();\n displayDate = days[date.getDay()] + ' ' + d + '-' + m + '-' + y;\n } else {\n displayDate = 'onbekend';\n }\n\n if ( start ) {\n displayStart = start.substr(0,5);\n }\n\n if ( end ) {\n displayEnd = end.substr(0,5);\n }\n\n if ( start && end ) {\n time = displayStart + ' - ' + displayEnd;\n } else {\n time = 'onbekend';\n }\n\n var thisRowContent = rowTemplate\n .replace('[[ index ]]', (i + 1) )\n .replace('[[ date ]]', displayDate)\n .replace('[[ time ]]', time)\n .replace('[[ location ]]', location);\n\n var thisRowElement = document.createElement('table');\n thisRowElement.innerHTML = thisRowContent;\n\n if (online) {\n var thisRowAddresCell = thisRowElement.querySelector('[data-js-bind=\"schedule-address-cell\"]');\n thisRowAddresCell.parentElement.removeChild(thisRowAddresCell);\n $modal.find('[data-js-bind=\"schedule-address-header\"]').remove();\n }\n\n tableContent += thisRowElement.children[0].innerHTML;\n\n }\n\n // add rows to table\n $tableBody.html(tableContent);\n\n // show modal\n $modal.addClass('show-modal');\n });\n }\n\n function pad(input) {\n var input = input.toString() || false;\n\n if ( input === false ) {\n return false;\n } else {\n return ('00'+input).substring(input.length);\n }\n }\n}(this, document, jQuery));\n","'use strict';\n\n$('.search-course').on('submit', function (e) {\n\tvar $form = $(this)\n\tvar $selects = $form.find('select');\n\tvar value = '';\n\n\t$selects.forEach(function () {\n\t\tif ( this.value ) {\n\t\t\tvalue = this.value;\n\t\t}\n\t});\n\n\tif ( value === '' ) {\n\t\te.preventDefault();\n\t}\n});","/**\n * Lots of other stuff concerning the search widget can be found in this\n * monstrous bowl of spaghetti, just try to add new stuff here.\n */\n\nfunction conditionalRequirement(widget) {\n if(!widget) return;\n\n const onLocationRadio = widget.querySelector('[data-js-bind=\"radio-location\"]');\n const courseSelector = widget.querySelector('[data-js-bind=\"course\"]');\n const locationSelector = widget.querySelector('[data-js-bind=\"location\"]');\n const submitButton = widget.querySelector('[data-js-bind=\"search-widget-submit\"]');\n\n if(!onLocationRadio || !courseSelector || !locationSelector || !submitButton) return;\n\n submitButton.addEventListener('click', function(e) {\n /*\n Course selector is required when\n - looking for online courses (meaning location radio is NOT checked)\n - location radio is checked AND location selector is empty\n */\n courseSelector.required = onLocationRadio.checked ? locationSelector.value === '' : true;\n });\n}\n\nfunction initSearchWidget() {\n const widget = document.querySelector('[data-module=\"search-widget\"]');\n if(!widget) return;\n conditionalRequirement(widget);\n}\n\ninitSearchWidget();\n","$('[data-js=\"expand-future-lessons\"]').on('click', function() {\r\n $(this).closest('[data-js=\"period-divider-row\"]').toggleClass('lessons-table__period-divider--expanded');\r\n});\r\n","'use strict';\n\n/**\n * Compares a past date to current date and parses it in a readable string\n * returns \"8 jaar geleden\" / \"3 dagen geleden\" etc.\n */\n\nvar $timeDifferences = $('.js-time-difference');\n\n$timeDifferences.each(function () {\n var elem = this;\n var s = $(elem).html();\n var a = s.split(/[^0-9]/);\n var d = new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);\n $(elem).html(timeDifference(d));\n});\n\nfunction timeDifference(pastDate) {\n // in milliseconds\n let units = {\n year: 24 * 60 * 60 * 1000 * 365,\n month: 24 * 60 * 60 * 1000 * 365 / 12,\n day: 24 * 60 * 60 * 1000,\n hour: 60 * 60 * 1000,\n minute: 60 * 1000,\n second: 1000\n }\n\n let rtf = new Intl.RelativeTimeFormat('nl', {numeric: 'auto'})\n let getRelativeTime = (d1, d2 = Date.now()) => {\n let elapsed = d1 - d2;\n for (let u in units) {\n if (Math.abs(elapsed) > units[u] || u === 'second') {\n return rtf.format(Math.round(elapsed / units[u]), u);\n }\n }\n }\n return getRelativeTime(pastDate);\n};\n","'use strict';\n\nvar $truncateTexts = $('.js-truncate-text');\nvar truncAttr = 'trunc-amount';\n\n$truncateTexts.each(function () {\n var elem = this;\n var truncBy = $(elem).attr(truncAttr) || 330;\n var origStr = $(elem).html();\n var newStr = truncate(origStr, truncBy, true);\n\n if (origStr !== newStr) {\n $(elem).html(newStr);\n $(elem).append('');\n\n $('.btn-link', elem).on('click', function () {\n $(elem).html(origStr);\n });\n }\n});\n\nfunction truncate(str, n, useWordBoundary) {\n if (str.length <= n) {\n return str;\n }\n const subString = str.substr(0, n - 1);\n return (useWordBoundary\n ? subString.substr(0, subString.lastIndexOf(\" \"))\n : subString) + \"…\";\n};\n","'use strict';\nconst SB_ONLINE_CLASS = 'search-bar--online';\nconst SB_OFFLINE_CLASS = 'search-bar--offline';\nconst SMALLER_PADDING = 'smaller-padding';\nconst LARGER_PADDING = 'larger-padding';\n\nsetTimeout(() => {\n const $searchBar = $('.search-bar');\n const $wrapper = $('.wrapper-inner.layout-container');\n if ($searchBar.hasClass(SB_ONLINE_CLASS)) {\n $wrapper.addClass(SMALLER_PADDING)\n } else if ($searchBar.hasClass(SB_OFFLINE_CLASS)) {\n $wrapper.addClass(LARGER_PADDING)\n }\n}, 300);\n","'use strict';\n\nvar $billingFieldsToggle = $('.toggle-billing-address');\nvar $billingFields = $('.billing-fields');\nvar $optionalBillingfields = $billingFields.find('.billing-required');\n\n// Toggles billing form when address is not the same as billing address\n$billingFieldsToggle.on('change', function (e) {\n var checked = $(this).hasClass('inverse') ? !this.checked : this.checked;\n\n $billingFields.attr('hidden', checked);\n $optionalBillingfields\n .attr('required', !checked)\n .prev('label')\n .toggleClass('required', !checked);\n}).trigger('change');","function _init() {\n $(\".video-block-container\").each(function initYoutubeVideo() {\n var $videoBlock = $(this);\n var $videoPlayer = $videoBlock.find(\".video-player\");\n var $videoTitle = $videoBlock.find(\".video-title\");\n \n var player = new YT.Player($videoPlayer[0].id, {\n height: \"480\",\n width: \"640\",\n videoId: $videoPlayer.data(\"video-id\"),\n playerVars: {\n autoplay: 0,\n enablejsapi: 1,\n modestbranding: 0,\n showinfo: 0,\n rel: 0\n },\n events: {\n onReady: function initTitle(e) {\n setTitle($videoTitle, e.target);\n }\n }\n });\n\n $videoBlock.on(\"click\", \".js-click-to-play\", function playVideo() {\n $videoBlock.addClass(\"playing\");\n player.playVideo();\n });\n });\n}\n\n// Get title from video player and set it in the video title element\nfunction setTitle($el, player) {\n $el.text(player.getVideoData().title);\n}\n\nmodule.exports = {\n init: _init\n};\n","(function (document, $) {\n 'use strict';\n\n // IMPORTANT - Checks if CSS has loaded and sets cookie\n require('./components/check-critical-css');\n\n // Local scripts\n require('./components/site/menu-toggle');\n require('./components/site/search-course');\n require('./components/site/schedule');\n require('./components/site/gmaps-map');\n require('./components/site/enroll-together');\n require('./components/user/profile-billing-toggle');\n require('./components/confirm');\n require('./components/site/table-divider');\n require('./components/site/search-widget');\n require('./components/site/truncate-text');\n require('./components/site/time-difference');\n require('./components/site/wrapper-padding');\n require('./components/collapsible-section');\n\n // Youtube player init\n var ytPlayer = require('./components/youtube-player');\n window.onYouTubeIframeAPIReady = ytPlayer.init;\n\n // stuff too small to include\n if ($('.star-rating').length > 0) {\n $('.star-rating').each(function () {\n var percentage = parseFloat($(this).data('rating')) * 20;\n var meterWidth = ($(this).innerWidth() - 2 ) * (percentage / 100);\n $(this)\n .find('.meter')\n .css('width', meterWidth);\n });\n }\n\n if ($('.scroll-down').length > 0) {\n $('.scroll-down').on('click', function (e) {\n e.preventDefault();\n $('html, body').animate(\n {\n scrollTop: $('.c-hero')\n .next()\n .offset().top\n },\n 300\n );\n });\n }\n\n if ($('.search-bar').length) {\n $('.search-bar').on('submit', function (e) {\n var $form = $(this);\n var root = $form.find('.field-root').val();\n var online = $('[name=\"is-online\"]').val();\n var course = $form.find('.field-course').val();\n var loc = $form.find('.field-location').val();\n e.preventDefault();\n \n if ($(this).hasClass('for-alternatives') && online === 'false') {\n location = '?course=' + course + '&city=' + loc;\n } else if ($(this).hasClass('for-alternatives') && online === 'true') {\n location = '?course=' + course + '&online=true';\n } else if (root && course && loc) {\n location = root + course + '/' + loc;\n } else if (root && loc) {\n location = root + 'spaans-in-' + loc;\n } else if (root && course && online === 'true') {\n location = root + course + '/online';\n }\n });\n\n $('.js-search-toggle').on('click', function () {\n $('.search-wrapper').toggleClass('is-open');\n $('.search-toggle').toggleClass('is-open');\n $(this).toggleClass('arrow-reversed');\n });\n }\n\n /* sticky search widget */\n const searchWidget = document.querySelector('[data-module=\"search-widget\"]:not(.no-stick)');\n\n if (searchWidget) {\n function toggleStickySearchWidget() {\n let widgetBottom;\n const nextElement = searchWidget.previousElementSibling;\n\n widgetBottom = nextElement.getBoundingClientRect().top - parseFloat(getComputedStyle(searchWidget).marginBottom);\n searchWidget.classList[widgetBottom < 40 ? 'add' : 'remove']('sticky');\n }\n\n toggleStickySearchWidget();\n window.addEventListener('resize', toggleStickySearchWidget)\n window.addEventListener('scroll', toggleStickySearchWidget)\n }\n\n\n function isOnlineCheck() {\n const locationSelector = document.querySelector('[name=\"location\"]');\n if (!locationSelector) return;\n const form = document.querySelector('[data-module=\"search-widget\"]');\n const isOnlineValue = $('[name=\"is-online\"]').val();\n const isOnline = isOnlineValue === 'true' || isOnlineValue === '';\n\n $('.location-container').attr('hidden', isOnline);\n locationSelector.required = !isOnline;\n if (isOnline) locationSelector.value = '';\n form.classList[isOnline ? 'add' : 'remove']('search-bar--online');\n form.classList[isOnline ? 'remove' : 'add']('search-bar--offline');\n }\n\n $('[name=\"is-online\"]').on('change', isOnlineCheck);\n setTimeout(isOnlineCheck, 10);\n\n if ($('.almost-full').length) {\n $('*:not(.almost-full.icon)').on('click mouseover focus', function () {\n $('.almost-full.icon').blur();\n });\n }\n\n if ($('.payment-selection__button').length) {\n var $form = $('[name=\"payment_method_selection\"]');\n var $bankSelect = $('#payment_method_selection_issuerid');\n var $selectRow = $bankSelect.closest('.form-group');\n\n $('.payment-selection__button').on('click', function () {\n if ($(this).hasClass('payment-selection__button--ideal')) {\n $bankSelect.attr('required', 'required');\n $selectRow.slideDown();\n } else {\n $bankSelect.removeAttr('required');\n $selectRow.slideUp();\n }\n });\n }\n\n if ($('.cookie-bar').length) {\n var $bar = $('.cookie-bar');\n var $buttons = $('.js-cookie-button');\n\n if (!/.*allowTrackingCookies.*/.test(document.cookie)) {\n $bar.addClass('needs-permission');\n }\n\n $buttons.on('click', function (e) {\n document.cookie =\n 'allowTrackingCookies=' +\n $(this).val() +\n '; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/';\n $bar.removeClass('needs-permission');\n });\n }\n\n $('.js-reset-tracking-cookies').on('click', function (e) {\n e.preventDefault();\n document.cookie =\n 'allowTrackingCookies=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';\n $('.cookie-bar').addClass('needs-permission');\n });\n\n // read more tweaks\n if ($('#read-more-checkbox').length) {\n var firstTitle = $('main h2').first()[0];\n\n $('#read-more-checkbox').on('change', function () {\n if (!$(this)[0].checked) {\n var titleBB = firstTitle.getBoundingClientRect();\n if (titleBB.top < titleBB.height) {\n firstTitle.scrollIntoView();\n }\n }\n });\n }\n\n const locationInfoToggle = document.getElementById('more-info__input');\n if (locationInfoToggle) {\n locationInfoToggle.addEventListener('change', function () {\n if (locationInfoToggle.checked && typeof window.initMap === 'function' && typeof locationInfoToggle.dataset.init !== 'undefined') {\n window.initMap();\n locationInfoToggle.removeAttribute('data-init');\n }\n });\n }\n\n $('.copy').on('click', function () {\n this.focus();\n this.select();\n document.execCommand('copy');\n $('.copy-success').removeAttr('hidden');\n })\n\n setTimeout(() => {\n $('.js-popup').css({'display': 'block'});\n }, 5000);\n\n setTimeout(() => {\n const alertWasClosed = sessionStorage.getItem(\"alert-notification\");\n if (alertWasClosed) return;\n $('.js-notification').css('display', 'flex')\n }, 1000);\n \n $('.js-close').on('click', (e) => {\n window.sessionStorage.setItem(e.currentTarget.id, \"closed\");\n $('.notification-container').css('display', 'none');\n });\n\n // First we get the viewport height and we multiple it by 1% to get a value for a vh unit\n let vh = window.innerHeight * 0.01;\n // Then we set the value in the --vh custom property to the root of the document\n document.documentElement.style.setProperty('--vh', `${vh}px`);\n\n // We listen to the resize event\n window.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 });\n\n})(document, jQuery);\n"],"preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZXM2LXByb21pc2UvZGlzdC9lczYtcHJvbWlzZS5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJwdWJsaWMvYXNzZXRzL2pzL2NvbXBvbmVudHMvY2hlY2stY3JpdGljYWwtY3NzLmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL2NvbGxhcHNpYmxlLXNlY3Rpb24uanMiLCJwdWJsaWMvYXNzZXRzL2pzL2NvbXBvbmVudHMvY29uZmlybS5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy9jb29raWVzLmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL2dtYXBzLWFwaS5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy9zaXRlL2Vucm9sbC10b2dldGhlci5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy9zaXRlL2dtYXBzLW1hcC5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy9zaXRlL21lbnUtdG9nZ2xlLmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NpdGUvc2NoZWR1bGUuanMiLCJwdWJsaWMvYXNzZXRzL2pzL2NvbXBvbmVudHMvc2l0ZS9zZWFyY2gtY291cnNlLmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NpdGUvc2VhcmNoLXdpZGdldC5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy9zaXRlL3RhYmxlLWRpdmlkZXIuanMiLCJwdWJsaWMvYXNzZXRzL2pzL2NvbXBvbmVudHMvc2l0ZS90aW1lLWRpZmZlcmVuY2UuanMiLCJwdWJsaWMvYXNzZXRzL2pzL2NvbXBvbmVudHMvc2l0ZS90cnVuY2F0ZS10ZXh0LmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL3NpdGUvd3JhcHBlci1wYWRkaW5nLmpzIiwicHVibGljL2Fzc2V0cy9qcy9jb21wb25lbnRzL3VzZXIvcHJvZmlsZS1iaWxsaW5nLXRvZ2dsZS5qcyIsInB1YmxpYy9hc3NldHMvanMvY29tcG9uZW50cy95b3V0dWJlLXBsYXllci5qcyIsInB1YmxpYy9hc3NldHMvanMvc2l0ZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiLyohXG4gKiBAb3ZlcnZpZXcgZXM2LXByb21pc2UgLSBhIHRpbnkgaW1wbGVtZW50YXRpb24gb2YgUHJvbWlzZXMvQSsuXG4gKiBAY29weXJpZ2h0IENvcHlyaWdodCAoYykgMjAxNCBZZWh1ZGEgS2F0eiwgVG9tIERhbGUsIFN0ZWZhbiBQZW5uZXIgYW5kIGNvbnRyaWJ1dG9ycyAoQ29udmVyc2lvbiB0byBFUzYgQVBJIGJ5IEpha2UgQXJjaGliYWxkKVxuICogQGxpY2Vuc2UgICBMaWNlbnNlZCB1bmRlciBNSVQgbGljZW5zZVxuICogICAgICAgICAgICBTZWUgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N0ZWZhbnBlbm5lci9lczYtcHJvbWlzZS9tYXN0ZXIvTElDRU5TRVxuICogQHZlcnNpb24gICB2NC4yLjYrOTg2OWE0YmNcbiAqL1xuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHR0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG5cdChnbG9iYWwuRVM2UHJvbWlzZSA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb2JqZWN0T3JGdW5jdGlvbih4KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHg7XG4gIHJldHVybiB4ICE9PSBudWxsICYmICh0eXBlID09PSAnb2JqZWN0JyB8fCB0eXBlID09PSAnZnVuY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih4KSB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuXG5cbnZhciBfaXNBcnJheSA9IHZvaWQgMDtcbmlmIChBcnJheS5pc0FycmF5KSB7XG4gIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcbn0gZWxzZSB7XG4gIF9pc0FycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHgpID09PSAnW29iamVjdCBBcnJheV0nO1xuICB9O1xufVxuXG52YXIgaXNBcnJheSA9IF9pc0FycmF5O1xuXG52YXIgbGVuID0gMDtcbnZhciB2ZXJ0eE5leHQgPSB2b2lkIDA7XG52YXIgY3VzdG9tU2NoZWR1bGVyRm4gPSB2b2lkIDA7XG5cbnZhciBhc2FwID0gZnVuY3Rpb24gYXNhcChjYWxsYmFjaywgYXJnKSB7XG4gIHF1ZXVlW2xlbl0gPSBjYWxsYmFjaztcbiAgcXVldWVbbGVuICsgMV0gPSBhcmc7XG4gIGxlbiArPSAyO1xuICBpZiAobGVuID09PSAyKSB7XG4gICAgLy8gSWYgbGVuIGlzIDIsIHRoYXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHNjaGVkdWxlIGFuIGFzeW5jIGZsdXNoLlxuICAgIC8vIElmIGFkZGl0aW9uYWwgY2FsbGJhY2tzIGFyZSBxdWV1ZWQgYmVmb3JlIHRoZSBxdWV1ZSBpcyBmbHVzaGVkLCB0aGV5XG4gICAgLy8gd2lsbCBiZSBwcm9jZXNzZWQgYnkgdGhpcyBmbHVzaCB0aGF0IHdlIGFyZSBzY2hlZHVsaW5nLlxuICAgIGlmIChjdXN0b21TY2hlZHVsZXJGbikge1xuICAgICAgY3VzdG9tU2NoZWR1bGVyRm4oZmx1c2gpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2hlZHVsZUZsdXNoKCk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzZXRTY2hlZHVsZXIoc2NoZWR1bGVGbikge1xuICBjdXN0b21TY2hlZHVsZXJGbiA9IHNjaGVkdWxlRm47XG59XG5cbmZ1bmN0aW9uIHNldEFzYXAoYXNhcEZuKSB7XG4gIGFzYXAgPSBhc2FwRm47XG59XG5cbnZhciBicm93c2VyV2luZG93ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB1bmRlZmluZWQ7XG52YXIgYnJvd3Nlckdsb2JhbCA9IGJyb3dzZXJXaW5kb3cgfHwge307XG52YXIgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIgPSBicm93c2VyR2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgYnJvd3Nlckdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xudmFyIGlzTm9kZSA9IHR5cGVvZiBzZWxmID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYge30udG9TdHJpbmcuY2FsbChwcm9jZXNzKSA9PT0gJ1tvYmplY3QgcHJvY2Vzc10nO1xuXG4vLyB0ZXN0IGZvciB3ZWIgd29ya2VyIGJ1dCBub3QgaW4gSUUxMFxudmFyIGlzV29ya2VyID0gdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgaW1wb3J0U2NyaXB0cyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJztcblxuLy8gbm9kZVxuZnVuY3Rpb24gdXNlTmV4dFRpY2soKSB7XG4gIC8vIG5vZGUgdmVyc2lvbiAwLjEwLnggZGlzcGxheXMgYSBkZXByZWNhdGlvbiB3YXJuaW5nIHdoZW4gbmV4dFRpY2sgaXMgdXNlZCByZWN1cnNpdmVseVxuICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2N1am9qcy93aGVuL2lzc3Vlcy80MTAgZm9yIGRldGFpbHNcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gIH07XG59XG5cbi8vIHZlcnR4XG5mdW5jdGlvbiB1c2VWZXJ0eFRpbWVyKCkge1xuICBpZiAodHlwZW9mIHZlcnR4TmV4dCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgdmVydHhOZXh0KGZsdXNoKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHVzZVNldFRpbWVvdXQoKTtcbn1cblxuZnVuY3Rpb24gdXNlTXV0YXRpb25PYnNlcnZlcigpIHtcbiAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICB2YXIgb2JzZXJ2ZXIgPSBuZXcgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIoZmx1c2gpO1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBub2RlLmRhdGEgPSBpdGVyYXRpb25zID0gKytpdGVyYXRpb25zICUgMjtcbiAgfTtcbn1cblxuLy8gd2ViIHdvcmtlclxuZnVuY3Rpb24gdXNlTWVzc2FnZUNoYW5uZWwoKSB7XG4gIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZmx1c2g7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZVNldFRpbWVvdXQoKSB7XG4gIC8vIFN0b3JlIHNldFRpbWVvdXQgcmVmZXJlbmNlIHNvIGVzNi1wcm9taXNlIHdpbGwgYmUgdW5hZmZlY3RlZCBieVxuICAvLyBvdGhlciBjb2RlIG1vZGlmeWluZyBzZXRUaW1lb3V0IChsaWtlIHNpbm9uLnVzZUZha2VUaW1lcnMoKSlcbiAgdmFyIGdsb2JhbFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBnbG9iYWxTZXRUaW1lb3V0KGZsdXNoLCAxKTtcbiAgfTtcbn1cblxudmFyIHF1ZXVlID0gbmV3IEFycmF5KDEwMDApO1xuZnVuY3Rpb24gZmx1c2goKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICB2YXIgY2FsbGJhY2sgPSBxdWV1ZVtpXTtcbiAgICB2YXIgYXJnID0gcXVldWVbaSArIDFdO1xuXG4gICAgY2FsbGJhY2soYXJnKTtcblxuICAgIHF1ZXVlW2ldID0gdW5kZWZpbmVkO1xuICAgIHF1ZXVlW2kgKyAxXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIGF0dGVtcHRWZXJ0eCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgdmVydHggPSBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpLnJlcXVpcmUoJ3ZlcnR4Jyk7XG4gICAgdmVydHhOZXh0ID0gdmVydHgucnVuT25Mb29wIHx8IHZlcnR4LnJ1bk9uQ29udGV4dDtcbiAgICByZXR1cm4gdXNlVmVydHhUaW1lcigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHVzZVNldFRpbWVvdXQoKTtcbiAgfVxufVxuXG52YXIgc2NoZWR1bGVGbHVzaCA9IHZvaWQgMDtcbi8vIERlY2lkZSB3aGF0IGFzeW5jIG1ldGhvZCB0byB1c2UgdG8gdHJpZ2dlcmluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlZCBjYWxsYmFja3M6XG5pZiAoaXNOb2RlKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VOZXh0VGljaygpO1xufSBlbHNlIGlmIChCcm93c2VyTXV0YXRpb25PYnNlcnZlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTXV0YXRpb25PYnNlcnZlcigpO1xufSBlbHNlIGlmIChpc1dvcmtlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTWVzc2FnZUNoYW5uZWwoKTtcbn0gZWxzZSBpZiAoYnJvd3NlcldpbmRvdyA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiByZXF1aXJlID09PSAnZnVuY3Rpb24nKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSBhdHRlbXB0VmVydHgoKTtcbn0gZWxzZSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VTZXRUaW1lb3V0KCk7XG59XG5cbmZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcbiAgdmFyIHBhcmVudCA9IHRoaXM7XG5cbiAgdmFyIGNoaWxkID0gbmV3IHRoaXMuY29uc3RydWN0b3Iobm9vcCk7XG5cbiAgaWYgKGNoaWxkW1BST01JU0VfSURdID09PSB1bmRlZmluZWQpIHtcbiAgICBtYWtlUHJvbWlzZShjaGlsZCk7XG4gIH1cblxuICB2YXIgX3N0YXRlID0gcGFyZW50Ll9zdGF0ZTtcblxuXG4gIGlmIChfc3RhdGUpIHtcbiAgICB2YXIgY2FsbGJhY2sgPSBhcmd1bWVudHNbX3N0YXRlIC0gMV07XG4gICAgYXNhcChmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gaW52b2tlQ2FsbGJhY2soX3N0YXRlLCBjaGlsZCwgY2FsbGJhY2ssIHBhcmVudC5fcmVzdWx0KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzdWJzY3JpYmUocGFyZW50LCBjaGlsZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAgYFByb21pc2UucmVzb2x2ZWAgcmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlY29tZSByZXNvbHZlZCB3aXRoIHRoZVxuICBwYXNzZWQgYHZhbHVlYC4gSXQgaXMgc2hvcnRoYW5kIGZvciB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHJlc29sdmUoMSk7XG4gIH0pO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gdmFsdWUgPT09IDFcbiAgfSk7XG4gIGBgYFxuXG4gIEluc3RlYWQgb2Ygd3JpdGluZyB0aGUgYWJvdmUsIHlvdXIgY29kZSBub3cgc2ltcGx5IGJlY29tZXMgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKDEpO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSl7XG4gICAgLy8gdmFsdWUgPT09IDFcbiAgfSk7XG4gIGBgYFxuXG4gIEBtZXRob2QgcmVzb2x2ZVxuICBAc3RhdGljXG4gIEBwYXJhbSB7QW55fSB2YWx1ZSB2YWx1ZSB0aGF0IHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVzb2x2ZWQgd2l0aFxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHdpbGwgYmVjb21lIGZ1bGZpbGxlZCB3aXRoIHRoZSBnaXZlblxuICBgdmFsdWVgXG4qL1xuZnVuY3Rpb24gcmVzb2x2ZSQxKG9iamVjdCkge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuXG4gIGlmIChvYmplY3QgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0LmNvbnN0cnVjdG9yID09PSBDb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICB2YXIgcHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcbiAgcmVzb2x2ZShwcm9taXNlLCBvYmplY3QpO1xuICByZXR1cm4gcHJvbWlzZTtcbn1cblxudmFyIFBST01JU0VfSUQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMik7XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG52YXIgUEVORElORyA9IHZvaWQgMDtcbnZhciBGVUxGSUxMRUQgPSAxO1xudmFyIFJFSkVDVEVEID0gMjtcblxudmFyIFRSWV9DQVRDSF9FUlJPUiA9IHsgZXJyb3I6IG51bGwgfTtcblxuZnVuY3Rpb24gc2VsZkZ1bGZpbGxtZW50KCkge1xuICByZXR1cm4gbmV3IFR5cGVFcnJvcihcIllvdSBjYW5ub3QgcmVzb2x2ZSBhIHByb21pc2Ugd2l0aCBpdHNlbGZcIik7XG59XG5cbmZ1bmN0aW9uIGNhbm5vdFJldHVybk93bigpIHtcbiAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZXMgY2FsbGJhY2sgY2Fubm90IHJldHVybiB0aGF0IHNhbWUgcHJvbWlzZS4nKTtcbn1cblxuZnVuY3Rpb24gZ2V0VGhlbihwcm9taXNlKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbjtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBUUllfQ0FUQ0hfRVJST1IuZXJyb3IgPSBlcnJvcjtcbiAgICByZXR1cm4gVFJZX0NBVENIX0VSUk9SO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRyeVRoZW4odGhlbiQkMSwgdmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICB0cnkge1xuICAgIHRoZW4kJDEuY2FsbCh2YWx1ZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSwgdGhlbiQkMSkge1xuICBhc2FwKGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgdmFyIHNlYWxlZCA9IGZhbHNlO1xuICAgIHZhciBlcnJvciA9IHRyeVRoZW4odGhlbiQkMSwgdGhlbmFibGUsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHNlYWxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgaWYgKHRoZW5hYmxlICE9PSB2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIGlmIChzZWFsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2VhbGVkID0gdHJ1ZTtcblxuICAgICAgcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSwgJ1NldHRsZTogJyArIChwcm9taXNlLl9sYWJlbCB8fCAnIHVua25vd24gcHJvbWlzZScpKTtcblxuICAgIGlmICghc2VhbGVkICYmIGVycm9yKSB7XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICB9XG4gIH0sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVPd25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSkge1xuICBpZiAodGhlbmFibGUuX3N0YXRlID09PSBGVUxGSUxMRUQpIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICB9IGVsc2UgaWYgKHRoZW5hYmxlLl9zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICByZWplY3QocHJvbWlzZSwgdGhlbmFibGUuX3Jlc3VsdCk7XG4gIH0gZWxzZSB7XG4gICAgc3Vic2NyaWJlKHRoZW5hYmxlLCB1bmRlZmluZWQsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHJldHVybiByZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUsIHRoZW4kJDEpIHtcbiAgaWYgKG1heWJlVGhlbmFibGUuY29uc3RydWN0b3IgPT09IHByb21pc2UuY29uc3RydWN0b3IgJiYgdGhlbiQkMSA9PT0gdGhlbiAmJiBtYXliZVRoZW5hYmxlLmNvbnN0cnVjdG9yLnJlc29sdmUgPT09IHJlc29sdmUkMSkge1xuICAgIGhhbmRsZU93blRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICB9IGVsc2Uge1xuICAgIGlmICh0aGVuJCQxID09PSBUUllfQ0FUQ0hfRVJST1IpIHtcbiAgICAgIHJlamVjdChwcm9taXNlLCBUUllfQ0FUQ0hfRVJST1IuZXJyb3IpO1xuICAgICAgVFJZX0NBVENIX0VSUk9SLmVycm9yID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKHRoZW4kJDEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24odGhlbiQkMSkpIHtcbiAgICAgIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlLCB0aGVuJCQxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICByZWplY3QocHJvbWlzZSwgc2VsZkZ1bGZpbGxtZW50KCkpO1xuICB9IGVsc2UgaWYgKG9iamVjdE9yRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCB2YWx1ZSwgZ2V0VGhlbih2YWx1ZSkpO1xuICB9IGVsc2Uge1xuICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2hSZWplY3Rpb24ocHJvbWlzZSkge1xuICBpZiAocHJvbWlzZS5fb25lcnJvcikge1xuICAgIHByb21pc2UuX29uZXJyb3IocHJvbWlzZS5fcmVzdWx0KTtcbiAgfVxuXG4gIHB1Ymxpc2gocHJvbWlzZSk7XG59XG5cbmZ1bmN0aW9uIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvbWlzZS5fcmVzdWx0ID0gdmFsdWU7XG4gIHByb21pc2UuX3N0YXRlID0gRlVMRklMTEVEO1xuXG4gIGlmIChwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggIT09IDApIHtcbiAgICBhc2FwKHB1Ymxpc2gsIHByb21pc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlamVjdChwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHByb21pc2UuX3N0YXRlID0gUkVKRUNURUQ7XG4gIHByb21pc2UuX3Jlc3VsdCA9IHJlYXNvbjtcblxuICBhc2FwKHB1Ymxpc2hSZWplY3Rpb24sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBzdWJzY3JpYmUocGFyZW50LCBjaGlsZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcbiAgdmFyIF9zdWJzY3JpYmVycyA9IHBhcmVudC5fc3Vic2NyaWJlcnM7XG4gIHZhciBsZW5ndGggPSBfc3Vic2NyaWJlcnMubGVuZ3RoO1xuXG5cbiAgcGFyZW50Ll9vbmVycm9yID0gbnVsbDtcblxuICBfc3Vic2NyaWJlcnNbbGVuZ3RoXSA9IGNoaWxkO1xuICBfc3Vic2NyaWJlcnNbbGVuZ3RoICsgRlVMRklMTEVEXSA9IG9uRnVsZmlsbG1lbnQ7XG4gIF9zdWJzY3JpYmVyc1tsZW5ndGggKyBSRUpFQ1RFRF0gPSBvblJlamVjdGlvbjtcblxuICBpZiAobGVuZ3RoID09PSAwICYmIHBhcmVudC5fc3RhdGUpIHtcbiAgICBhc2FwKHB1Ymxpc2gsIHBhcmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHVibGlzaChwcm9taXNlKSB7XG4gIHZhciBzdWJzY3JpYmVycyA9IHByb21pc2UuX3N1YnNjcmliZXJzO1xuICB2YXIgc2V0dGxlZCA9IHByb21pc2UuX3N0YXRlO1xuXG4gIGlmIChzdWJzY3JpYmVycy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgY2hpbGQgPSB2b2lkIDAsXG4gICAgICBjYWxsYmFjayA9IHZvaWQgMCxcbiAgICAgIGRldGFpbCA9IHByb21pc2UuX3Jlc3VsdDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN1YnNjcmliZXJzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgY2hpbGQgPSBzdWJzY3JpYmVyc1tpXTtcbiAgICBjYWxsYmFjayA9IHN1YnNjcmliZXJzW2kgKyBzZXR0bGVkXTtcblxuICAgIGlmIChjaGlsZCkge1xuICAgICAgaW52b2tlQ2FsbGJhY2soc2V0dGxlZCwgY2hpbGQsIGNhbGxiYWNrLCBkZXRhaWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhkZXRhaWwpO1xuICAgIH1cbiAgfVxuXG4gIHByb21pc2UuX3N1YnNjcmliZXJzLmxlbmd0aCA9IDA7XG59XG5cbmZ1bmN0aW9uIHRyeUNhdGNoKGNhbGxiYWNrLCBkZXRhaWwpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gY2FsbGJhY2soZGV0YWlsKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIFRSWV9DQVRDSF9FUlJPUi5lcnJvciA9IGU7XG4gICAgcmV0dXJuIFRSWV9DQVRDSF9FUlJPUjtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VDYWxsYmFjayhzZXR0bGVkLCBwcm9taXNlLCBjYWxsYmFjaywgZGV0YWlsKSB7XG4gIHZhciBoYXNDYWxsYmFjayA9IGlzRnVuY3Rpb24oY2FsbGJhY2spLFxuICAgICAgdmFsdWUgPSB2b2lkIDAsXG4gICAgICBlcnJvciA9IHZvaWQgMCxcbiAgICAgIHN1Y2NlZWRlZCA9IHZvaWQgMCxcbiAgICAgIGZhaWxlZCA9IHZvaWQgMDtcblxuICBpZiAoaGFzQ2FsbGJhY2spIHtcbiAgICB2YWx1ZSA9IHRyeUNhdGNoKGNhbGxiYWNrLCBkZXRhaWwpO1xuXG4gICAgaWYgKHZhbHVlID09PSBUUllfQ0FUQ0hfRVJST1IpIHtcbiAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICBlcnJvciA9IHZhbHVlLmVycm9yO1xuICAgICAgdmFsdWUuZXJyb3IgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdWNjZWVkZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChwcm9taXNlID09PSB2YWx1ZSkge1xuICAgICAgcmVqZWN0KHByb21pc2UsIGNhbm5vdFJldHVybk93bigpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBkZXRhaWw7XG4gICAgc3VjY2VlZGVkID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwcm9taXNlLl9zdGF0ZSAhPT0gUEVORElORykge1xuICAgIC8vIG5vb3BcbiAgfSBlbHNlIGlmIChoYXNDYWxsYmFjayAmJiBzdWNjZWVkZWQpIHtcbiAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgfSBlbHNlIGlmIChmYWlsZWQpIHtcbiAgICByZWplY3QocHJvbWlzZSwgZXJyb3IpO1xuICB9IGVsc2UgaWYgKHNldHRsZWQgPT09IEZVTEZJTExFRCkge1xuICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICB9IGVsc2UgaWYgKHNldHRsZWQgPT09IFJFSkVDVEVEKSB7XG4gICAgcmVqZWN0KHByb21pc2UsIHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplUHJvbWlzZShwcm9taXNlLCByZXNvbHZlcikge1xuICB0cnkge1xuICAgIHJlc29sdmVyKGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHZhbHVlKSB7XG4gICAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiByZWplY3RQcm9taXNlKHJlYXNvbikge1xuICAgICAgcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZWplY3QocHJvbWlzZSwgZSk7XG4gIH1cbn1cblxudmFyIGlkID0gMDtcbmZ1bmN0aW9uIG5leHRJZCgpIHtcbiAgcmV0dXJuIGlkKys7XG59XG5cbmZ1bmN0aW9uIG1ha2VQcm9taXNlKHByb21pc2UpIHtcbiAgcHJvbWlzZVtQUk9NSVNFX0lEXSA9IGlkKys7XG4gIHByb21pc2UuX3N0YXRlID0gdW5kZWZpbmVkO1xuICBwcm9taXNlLl9yZXN1bHQgPSB1bmRlZmluZWQ7XG4gIHByb21pc2UuX3N1YnNjcmliZXJzID0gW107XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRpb25FcnJvcigpIHtcbiAgcmV0dXJuIG5ldyBFcnJvcignQXJyYXkgTWV0aG9kcyBtdXN0IGJlIHByb3ZpZGVkIGFuIEFycmF5Jyk7XG59XG5cbnZhciBFbnVtZXJhdG9yID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBFbnVtZXJhdG9yKENvbnN0cnVjdG9yLCBpbnB1dCkge1xuICAgIHRoaXMuX2luc3RhbmNlQ29uc3RydWN0b3IgPSBDb25zdHJ1Y3RvcjtcbiAgICB0aGlzLnByb21pc2UgPSBuZXcgQ29uc3RydWN0b3Iobm9vcCk7XG5cbiAgICBpZiAoIXRoaXMucHJvbWlzZVtQUk9NSVNFX0lEXSkge1xuICAgICAgbWFrZVByb21pc2UodGhpcy5wcm9taXNlKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheShpbnB1dCkpIHtcbiAgICAgIHRoaXMubGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgICAgdGhpcy5fcmVtYWluaW5nID0gaW5wdXQubGVuZ3RoO1xuXG4gICAgICB0aGlzLl9yZXN1bHQgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuXG4gICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxlbmd0aCA9IHRoaXMubGVuZ3RoIHx8IDA7XG4gICAgICAgIHRoaXMuX2VudW1lcmF0ZShpbnB1dCk7XG4gICAgICAgIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgICBmdWxmaWxsKHRoaXMucHJvbWlzZSwgdGhpcy5fcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZWplY3QodGhpcy5wcm9taXNlLCB2YWxpZGF0aW9uRXJyb3IoKSk7XG4gICAgfVxuICB9XG5cbiAgRW51bWVyYXRvci5wcm90b3R5cGUuX2VudW1lcmF0ZSA9IGZ1bmN0aW9uIF9lbnVtZXJhdGUoaW5wdXQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgdGhpcy5fc3RhdGUgPT09IFBFTkRJTkcgJiYgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLl9lYWNoRW50cnkoaW5wdXRbaV0sIGkpO1xuICAgIH1cbiAgfTtcblxuICBFbnVtZXJhdG9yLnByb3RvdHlwZS5fZWFjaEVudHJ5ID0gZnVuY3Rpb24gX2VhY2hFbnRyeShlbnRyeSwgaSkge1xuICAgIHZhciBjID0gdGhpcy5faW5zdGFuY2VDb25zdHJ1Y3RvcjtcbiAgICB2YXIgcmVzb2x2ZSQkMSA9IGMucmVzb2x2ZTtcblxuXG4gICAgaWYgKHJlc29sdmUkJDEgPT09IHJlc29sdmUkMSkge1xuICAgICAgdmFyIF90aGVuID0gZ2V0VGhlbihlbnRyeSk7XG5cbiAgICAgIGlmIChfdGhlbiA9PT0gdGhlbiAmJiBlbnRyeS5fc3RhdGUgIT09IFBFTkRJTkcpIHtcbiAgICAgICAgdGhpcy5fc2V0dGxlZEF0KGVudHJ5Ll9zdGF0ZSwgaSwgZW50cnkuX3Jlc3VsdCk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBfdGhlbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLl9yZW1haW5pbmctLTtcbiAgICAgICAgdGhpcy5fcmVzdWx0W2ldID0gZW50cnk7XG4gICAgICB9IGVsc2UgaWYgKGMgPT09IFByb21pc2UkMSkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IG5ldyBjKG5vb3ApO1xuICAgICAgICBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIGVudHJ5LCBfdGhlbik7XG4gICAgICAgIHRoaXMuX3dpbGxTZXR0bGVBdChwcm9taXNlLCBpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3dpbGxTZXR0bGVBdChuZXcgYyhmdW5jdGlvbiAocmVzb2x2ZSQkMSkge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlJCQxKGVudHJ5KTtcbiAgICAgICAgfSksIGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl93aWxsU2V0dGxlQXQocmVzb2x2ZSQkMShlbnRyeSksIGkpO1xuICAgIH1cbiAgfTtcblxuICBFbnVtZXJhdG9yLnByb3RvdHlwZS5fc2V0dGxlZEF0ID0gZnVuY3Rpb24gX3NldHRsZWRBdChzdGF0ZSwgaSwgdmFsdWUpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcblxuXG4gICAgaWYgKHByb21pc2UuX3N0YXRlID09PSBQRU5ESU5HKSB7XG4gICAgICB0aGlzLl9yZW1haW5pbmctLTtcblxuICAgICAgaWYgKHN0YXRlID09PSBSRUpFQ1RFRCkge1xuICAgICAgICByZWplY3QocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fcmVzdWx0W2ldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlbWFpbmluZyA9PT0gMCkge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCB0aGlzLl9yZXN1bHQpO1xuICAgIH1cbiAgfTtcblxuICBFbnVtZXJhdG9yLnByb3RvdHlwZS5fd2lsbFNldHRsZUF0ID0gZnVuY3Rpb24gX3dpbGxTZXR0bGVBdChwcm9taXNlLCBpKSB7XG4gICAgdmFyIGVudW1lcmF0b3IgPSB0aGlzO1xuXG4gICAgc3Vic2NyaWJlKHByb21pc2UsIHVuZGVmaW5lZCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZW51bWVyYXRvci5fc2V0dGxlZEF0KEZVTEZJTExFRCwgaSwgdmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHJldHVybiBlbnVtZXJhdG9yLl9zZXR0bGVkQXQoUkVKRUNURUQsIGksIHJlYXNvbik7XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIEVudW1lcmF0b3I7XG59KCk7XG5cbi8qKlxuICBgUHJvbWlzZS5hbGxgIGFjY2VwdHMgYW4gYXJyYXkgb2YgcHJvbWlzZXMsIGFuZCByZXR1cm5zIGEgbmV3IHByb21pc2Ugd2hpY2hcbiAgaXMgZnVsZmlsbGVkIHdpdGggYW4gYXJyYXkgb2YgZnVsZmlsbG1lbnQgdmFsdWVzIGZvciB0aGUgcGFzc2VkIHByb21pc2VzLCBvclxuICByZWplY3RlZCB3aXRoIHRoZSByZWFzb24gb2YgdGhlIGZpcnN0IHBhc3NlZCBwcm9taXNlIHRvIGJlIHJlamVjdGVkLiBJdCBjYXN0cyBhbGxcbiAgZWxlbWVudHMgb2YgdGhlIHBhc3NlZCBpdGVyYWJsZSB0byBwcm9taXNlcyBhcyBpdCBydW5zIHRoaXMgYWxnb3JpdGhtLlxuXG4gIEV4YW1wbGU6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSByZXNvbHZlKDEpO1xuICBsZXQgcHJvbWlzZTIgPSByZXNvbHZlKDIpO1xuICBsZXQgcHJvbWlzZTMgPSByZXNvbHZlKDMpO1xuICBsZXQgcHJvbWlzZXMgPSBbIHByb21pc2UxLCBwcm9taXNlMiwgcHJvbWlzZTMgXTtcblxuICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbihhcnJheSl7XG4gICAgLy8gVGhlIGFycmF5IGhlcmUgd291bGQgYmUgWyAxLCAyLCAzIF07XG4gIH0pO1xuICBgYGBcblxuICBJZiBhbnkgb2YgdGhlIGBwcm9taXNlc2AgZ2l2ZW4gdG8gYGFsbGAgYXJlIHJlamVjdGVkLCB0aGUgZmlyc3QgcHJvbWlzZVxuICB0aGF0IGlzIHJlamVjdGVkIHdpbGwgYmUgZ2l2ZW4gYXMgYW4gYXJndW1lbnQgdG8gdGhlIHJldHVybmVkIHByb21pc2VzJ3NcbiAgcmVqZWN0aW9uIGhhbmRsZXIuIEZvciBleGFtcGxlOlxuXG4gIEV4YW1wbGU6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSByZXNvbHZlKDEpO1xuICBsZXQgcHJvbWlzZTIgPSByZWplY3QobmV3IEVycm9yKFwiMlwiKSk7XG4gIGxldCBwcm9taXNlMyA9IHJlamVjdChuZXcgRXJyb3IoXCIzXCIpKTtcbiAgbGV0IHByb21pc2VzID0gWyBwcm9taXNlMSwgcHJvbWlzZTIsIHByb21pc2UzIF07XG5cbiAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24oYXJyYXkpe1xuICAgIC8vIENvZGUgaGVyZSBuZXZlciBydW5zIGJlY2F1c2UgdGhlcmUgYXJlIHJlamVjdGVkIHByb21pc2VzIVxuICB9LCBmdW5jdGlvbihlcnJvcikge1xuICAgIC8vIGVycm9yLm1lc3NhZ2UgPT09IFwiMlwiXG4gIH0pO1xuICBgYGBcblxuICBAbWV0aG9kIGFsbFxuICBAc3RhdGljXG4gIEBwYXJhbSB7QXJyYXl9IGVudHJpZXMgYXJyYXkgb2YgcHJvbWlzZXNcbiAgQHBhcmFtIHtTdHJpbmd9IGxhYmVsIG9wdGlvbmFsIHN0cmluZyBmb3IgbGFiZWxpbmcgdGhlIHByb21pc2UuXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aGVuIGFsbCBgcHJvbWlzZXNgIGhhdmUgYmVlblxuICBmdWxmaWxsZWQsIG9yIHJlamVjdGVkIGlmIGFueSBvZiB0aGVtIGJlY29tZSByZWplY3RlZC5cbiAgQHN0YXRpY1xuKi9cbmZ1bmN0aW9uIGFsbChlbnRyaWVzKSB7XG4gIHJldHVybiBuZXcgRW51bWVyYXRvcih0aGlzLCBlbnRyaWVzKS5wcm9taXNlO1xufVxuXG4vKipcbiAgYFByb21pc2UucmFjZWAgcmV0dXJucyBhIG5ldyBwcm9taXNlIHdoaWNoIGlzIHNldHRsZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZVxuICBmaXJzdCBwYXNzZWQgcHJvbWlzZSB0byBzZXR0bGUuXG5cbiAgRXhhbXBsZTpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlMSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgcmVzb2x2ZSgncHJvbWlzZSAxJyk7XG4gICAgfSwgMjAwKTtcbiAgfSk7XG5cbiAgbGV0IHByb21pc2UyID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDInKTtcbiAgICB9LCAxMDApO1xuICB9KTtcblxuICBQcm9taXNlLnJhY2UoW3Byb21pc2UxLCBwcm9taXNlMl0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KXtcbiAgICAvLyByZXN1bHQgPT09ICdwcm9taXNlIDInIGJlY2F1c2UgaXQgd2FzIHJlc29sdmVkIGJlZm9yZSBwcm9taXNlMVxuICAgIC8vIHdhcyByZXNvbHZlZC5cbiAgfSk7XG4gIGBgYFxuXG4gIGBQcm9taXNlLnJhY2VgIGlzIGRldGVybWluaXN0aWMgaW4gdGhhdCBvbmx5IHRoZSBzdGF0ZSBvZiB0aGUgZmlyc3RcbiAgc2V0dGxlZCBwcm9taXNlIG1hdHRlcnMuIEZvciBleGFtcGxlLCBldmVuIGlmIG90aGVyIHByb21pc2VzIGdpdmVuIHRvIHRoZVxuICBgcHJvbWlzZXNgIGFycmF5IGFyZ3VtZW50IGFyZSByZXNvbHZlZCwgYnV0IHRoZSBmaXJzdCBzZXR0bGVkIHByb21pc2UgaGFzXG4gIGJlY29tZSByZWplY3RlZCBiZWZvcmUgdGhlIG90aGVyIHByb21pc2VzIGJlY2FtZSBmdWxmaWxsZWQsIHRoZSByZXR1cm5lZFxuICBwcm9taXNlIHdpbGwgYmVjb21lIHJlamVjdGVkOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDEnKTtcbiAgICB9LCAyMDApO1xuICB9KTtcblxuICBsZXQgcHJvbWlzZTIgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoJ3Byb21pc2UgMicpKTtcbiAgICB9LCAxMDApO1xuICB9KTtcblxuICBQcm9taXNlLnJhY2UoW3Byb21pc2UxLCBwcm9taXNlMl0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KXtcbiAgICAvLyBDb2RlIGhlcmUgbmV2ZXIgcnVuc1xuICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgIC8vIHJlYXNvbi5tZXNzYWdlID09PSAncHJvbWlzZSAyJyBiZWNhdXNlIHByb21pc2UgMiBiZWNhbWUgcmVqZWN0ZWQgYmVmb3JlXG4gICAgLy8gcHJvbWlzZSAxIGJlY2FtZSBmdWxmaWxsZWRcbiAgfSk7XG4gIGBgYFxuXG4gIEFuIGV4YW1wbGUgcmVhbC13b3JsZCB1c2UgY2FzZSBpcyBpbXBsZW1lbnRpbmcgdGltZW91dHM6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBQcm9taXNlLnJhY2UoW2FqYXgoJ2Zvby5qc29uJyksIHRpbWVvdXQoNTAwMCldKVxuICBgYGBcblxuICBAbWV0aG9kIHJhY2VcbiAgQHN0YXRpY1xuICBAcGFyYW0ge0FycmF5fSBwcm9taXNlcyBhcnJheSBvZiBwcm9taXNlcyB0byBvYnNlcnZlXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHdoaWNoIHNldHRsZXMgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZSBmaXJzdCBwYXNzZWRcbiAgcHJvbWlzZSB0byBzZXR0bGUuXG4qL1xuZnVuY3Rpb24gcmFjZShlbnRyaWVzKSB7XG4gIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gIHZhciBDb25zdHJ1Y3RvciA9IHRoaXM7XG5cbiAgaWYgKCFpc0FycmF5KGVudHJpZXMpKSB7XG4gICAgcmV0dXJuIG5ldyBDb25zdHJ1Y3RvcihmdW5jdGlvbiAoXywgcmVqZWN0KSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYW4gYXJyYXkgdG8gcmFjZS4nKSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBDb25zdHJ1Y3RvcihmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gZW50cmllcy5sZW5ndGg7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIENvbnN0cnVjdG9yLnJlc29sdmUoZW50cmllc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICBgUHJvbWlzZS5yZWplY3RgIHJldHVybnMgYSBwcm9taXNlIHJlamVjdGVkIHdpdGggdGhlIHBhc3NlZCBgcmVhc29uYC5cbiAgSXQgaXMgc2hvcnRoYW5kIGZvciB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHJlamVjdChuZXcgRXJyb3IoJ1dIT09QUycpKTtcbiAgfSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyBDb2RlIGhlcmUgZG9lc24ndCBydW4gYmVjYXVzZSB0aGUgcHJvbWlzZSBpcyByZWplY3RlZCFcbiAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAvLyByZWFzb24ubWVzc2FnZSA9PT0gJ1dIT09QUydcbiAgfSk7XG4gIGBgYFxuXG4gIEluc3RlYWQgb2Ygd3JpdGluZyB0aGUgYWJvdmUsIHlvdXIgY29kZSBub3cgc2ltcGx5IGJlY29tZXMgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdXSE9PUFMnKSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyBDb2RlIGhlcmUgZG9lc24ndCBydW4gYmVjYXVzZSB0aGUgcHJvbWlzZSBpcyByZWplY3RlZCFcbiAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAvLyByZWFzb24ubWVzc2FnZSA9PT0gJ1dIT09QUydcbiAgfSk7XG4gIGBgYFxuXG4gIEBtZXRob2QgcmVqZWN0XG4gIEBzdGF0aWNcbiAgQHBhcmFtIHtBbnl9IHJlYXNvbiB2YWx1ZSB0aGF0IHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aC5cbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgcmVqZWN0ZWQgd2l0aCB0aGUgZ2l2ZW4gYHJlYXNvbmAuXG4qL1xuZnVuY3Rpb24gcmVqZWN0JDEocmVhc29uKSB7XG4gIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gIHZhciBDb25zdHJ1Y3RvciA9IHRoaXM7XG4gIHZhciBwcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKG5vb3ApO1xuICByZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIG5lZWRzUmVzb2x2ZXIoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYSByZXNvbHZlciBmdW5jdGlvbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIHByb21pc2UgY29uc3RydWN0b3InKTtcbn1cblxuZnVuY3Rpb24gbmVlZHNOZXcoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGYWlsZWQgdG8gY29uc3RydWN0ICdQcm9taXNlJzogUGxlYXNlIHVzZSB0aGUgJ25ldycgb3BlcmF0b3IsIHRoaXMgb2JqZWN0IGNvbnN0cnVjdG9yIGNhbm5vdCBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvbi5cIik7XG59XG5cbi8qKlxuICBQcm9taXNlIG9iamVjdHMgcmVwcmVzZW50IHRoZSBldmVudHVhbCByZXN1bHQgb2YgYW4gYXN5bmNocm9ub3VzIG9wZXJhdGlvbi4gVGhlXG4gIHByaW1hcnkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggYSBwcm9taXNlIGlzIHRocm91Z2ggaXRzIGB0aGVuYCBtZXRob2QsIHdoaWNoXG4gIHJlZ2lzdGVycyBjYWxsYmFja3MgdG8gcmVjZWl2ZSBlaXRoZXIgYSBwcm9taXNlJ3MgZXZlbnR1YWwgdmFsdWUgb3IgdGhlIHJlYXNvblxuICB3aHkgdGhlIHByb21pc2UgY2Fubm90IGJlIGZ1bGZpbGxlZC5cblxuICBUZXJtaW5vbG9neVxuICAtLS0tLS0tLS0tLVxuXG4gIC0gYHByb21pc2VgIGlzIGFuIG9iamVjdCBvciBmdW5jdGlvbiB3aXRoIGEgYHRoZW5gIG1ldGhvZCB3aG9zZSBiZWhhdmlvciBjb25mb3JtcyB0byB0aGlzIHNwZWNpZmljYXRpb24uXG4gIC0gYHRoZW5hYmxlYCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gdGhhdCBkZWZpbmVzIGEgYHRoZW5gIG1ldGhvZC5cbiAgLSBgdmFsdWVgIGlzIGFueSBsZWdhbCBKYXZhU2NyaXB0IHZhbHVlIChpbmNsdWRpbmcgdW5kZWZpbmVkLCBhIHRoZW5hYmxlLCBvciBhIHByb21pc2UpLlxuICAtIGBleGNlcHRpb25gIGlzIGEgdmFsdWUgdGhhdCBpcyB0aHJvd24gdXNpbmcgdGhlIHRocm93IHN0YXRlbWVudC5cbiAgLSBgcmVhc29uYCBpcyBhIHZhbHVlIHRoYXQgaW5kaWNhdGVzIHdoeSBhIHByb21pc2Ugd2FzIHJlamVjdGVkLlxuICAtIGBzZXR0bGVkYCB0aGUgZmluYWwgcmVzdGluZyBzdGF0ZSBvZiBhIHByb21pc2UsIGZ1bGZpbGxlZCBvciByZWplY3RlZC5cblxuICBBIHByb21pc2UgY2FuIGJlIGluIG9uZSBvZiB0aHJlZSBzdGF0ZXM6IHBlbmRpbmcsIGZ1bGZpbGxlZCwgb3IgcmVqZWN0ZWQuXG5cbiAgUHJvbWlzZXMgdGhhdCBhcmUgZnVsZmlsbGVkIGhhdmUgYSBmdWxmaWxsbWVudCB2YWx1ZSBhbmQgYXJlIGluIHRoZSBmdWxmaWxsZWRcbiAgc3RhdGUuICBQcm9taXNlcyB0aGF0IGFyZSByZWplY3RlZCBoYXZlIGEgcmVqZWN0aW9uIHJlYXNvbiBhbmQgYXJlIGluIHRoZVxuICByZWplY3RlZCBzdGF0ZS4gIEEgZnVsZmlsbG1lbnQgdmFsdWUgaXMgbmV2ZXIgYSB0aGVuYWJsZS5cblxuICBQcm9taXNlcyBjYW4gYWxzbyBiZSBzYWlkIHRvICpyZXNvbHZlKiBhIHZhbHVlLiAgSWYgdGhpcyB2YWx1ZSBpcyBhbHNvIGFcbiAgcHJvbWlzZSwgdGhlbiB0aGUgb3JpZ2luYWwgcHJvbWlzZSdzIHNldHRsZWQgc3RhdGUgd2lsbCBtYXRjaCB0aGUgdmFsdWUnc1xuICBzZXR0bGVkIHN0YXRlLiAgU28gYSBwcm9taXNlIHRoYXQgKnJlc29sdmVzKiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpbGxcbiAgaXRzZWxmIHJlamVjdCwgYW5kIGEgcHJvbWlzZSB0aGF0ICpyZXNvbHZlcyogYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgd2lsbFxuICBpdHNlbGYgZnVsZmlsbC5cblxuXG4gIEJhc2ljIFVzYWdlOlxuICAtLS0tLS0tLS0tLS1cblxuICBgYGBqc1xuICBsZXQgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIC8vIG9uIHN1Y2Nlc3NcbiAgICByZXNvbHZlKHZhbHVlKTtcblxuICAgIC8vIG9uIGZhaWx1cmVcbiAgICByZWplY3QocmVhc29uKTtcbiAgfSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gb24gZnVsZmlsbG1lbnRcbiAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgLy8gb24gcmVqZWN0aW9uXG4gIH0pO1xuICBgYGBcblxuICBBZHZhbmNlZCBVc2FnZTpcbiAgLS0tLS0tLS0tLS0tLS0tXG5cbiAgUHJvbWlzZXMgc2hpbmUgd2hlbiBhYnN0cmFjdGluZyBhd2F5IGFzeW5jaHJvbm91cyBpbnRlcmFjdGlvbnMgc3VjaCBhc1xuICBgWE1MSHR0cFJlcXVlc3Rgcy5cblxuICBgYGBqc1xuICBmdW5jdGlvbiBnZXRKU09OKHVybCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgICAgbGV0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG4gICAgICB4aHIub3BlbignR0VUJywgdXJsKTtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBoYW5kbGVyO1xuICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdqc29uJztcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgeGhyLnNlbmQoKTtcblxuICAgICAgZnVuY3Rpb24gaGFuZGxlcigpIHtcbiAgICAgICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PT0gdGhpcy5ET05FKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICAgIHJlc29sdmUodGhpcy5yZXNwb25zZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ2dldEpTT046IGAnICsgdXJsICsgJ2AgZmFpbGVkIHdpdGggc3RhdHVzOiBbJyArIHRoaXMuc3RhdHVzICsgJ10nKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0SlNPTignL3Bvc3RzLmpzb24nKS50aGVuKGZ1bmN0aW9uKGpzb24pIHtcbiAgICAvLyBvbiBmdWxmaWxsbWVudFxuICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAvLyBvbiByZWplY3Rpb25cbiAgfSk7XG4gIGBgYFxuXG4gIFVubGlrZSBjYWxsYmFja3MsIHByb21pc2VzIGFyZSBncmVhdCBjb21wb3NhYmxlIHByaW1pdGl2ZXMuXG5cbiAgYGBganNcbiAgUHJvbWlzZS5hbGwoW1xuICAgIGdldEpTT04oJy9wb3N0cycpLFxuICAgIGdldEpTT04oJy9jb21tZW50cycpXG4gIF0pLnRoZW4oZnVuY3Rpb24odmFsdWVzKXtcbiAgICB2YWx1ZXNbMF0gLy8gPT4gcG9zdHNKU09OXG4gICAgdmFsdWVzWzFdIC8vID0+IGNvbW1lbnRzSlNPTlxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfSk7XG4gIGBgYFxuXG4gIEBjbGFzcyBQcm9taXNlXG4gIEBwYXJhbSB7RnVuY3Rpb259IHJlc29sdmVyXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQGNvbnN0cnVjdG9yXG4qL1xuXG52YXIgUHJvbWlzZSQxID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBQcm9taXNlKHJlc29sdmVyKSB7XG4gICAgdGhpc1tQUk9NSVNFX0lEXSA9IG5leHRJZCgpO1xuICAgIHRoaXMuX3Jlc3VsdCA9IHRoaXMuX3N0YXRlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3N1YnNjcmliZXJzID0gW107XG5cbiAgICBpZiAobm9vcCAhPT0gcmVzb2x2ZXIpIHtcbiAgICAgIHR5cGVvZiByZXNvbHZlciAhPT0gJ2Z1bmN0aW9uJyAmJiBuZWVkc1Jlc29sdmVyKCk7XG4gICAgICB0aGlzIGluc3RhbmNlb2YgUHJvbWlzZSA/IGluaXRpYWxpemVQcm9taXNlKHRoaXMsIHJlc29sdmVyKSA6IG5lZWRzTmV3KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gIFRoZSBwcmltYXJ5IHdheSBvZiBpbnRlcmFjdGluZyB3aXRoIGEgcHJvbWlzZSBpcyB0aHJvdWdoIGl0cyBgdGhlbmAgbWV0aG9kLFxuICB3aGljaCByZWdpc3RlcnMgY2FsbGJhY2tzIHRvIHJlY2VpdmUgZWl0aGVyIGEgcHJvbWlzZSdzIGV2ZW50dWFsIHZhbHVlIG9yIHRoZVxuICByZWFzb24gd2h5IHRoZSBwcm9taXNlIGNhbm5vdCBiZSBmdWxmaWxsZWQuXG4gICBgYGBqc1xuICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24odXNlcil7XG4gICAgLy8gdXNlciBpcyBhdmFpbGFibGVcbiAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAvLyB1c2VyIGlzIHVuYXZhaWxhYmxlLCBhbmQgeW91IGFyZSBnaXZlbiB0aGUgcmVhc29uIHdoeVxuICB9KTtcbiAgYGBgXG4gICBDaGFpbmluZ1xuICAtLS0tLS0tLVxuICAgVGhlIHJldHVybiB2YWx1ZSBvZiBgdGhlbmAgaXMgaXRzZWxmIGEgcHJvbWlzZS4gIFRoaXMgc2Vjb25kLCAnZG93bnN0cmVhbSdcbiAgcHJvbWlzZSBpcyByZXNvbHZlZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZpcnN0IHByb21pc2UncyBmdWxmaWxsbWVudFxuICBvciByZWplY3Rpb24gaGFuZGxlciwgb3IgcmVqZWN0ZWQgaWYgdGhlIGhhbmRsZXIgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgIGBgYGpzXG4gIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgIHJldHVybiB1c2VyLm5hbWU7XG4gIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICByZXR1cm4gJ2RlZmF1bHQgbmFtZSc7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKHVzZXJOYW1lKSB7XG4gICAgLy8gSWYgYGZpbmRVc2VyYCBmdWxmaWxsZWQsIGB1c2VyTmFtZWAgd2lsbCBiZSB0aGUgdXNlcidzIG5hbWUsIG90aGVyd2lzZSBpdFxuICAgIC8vIHdpbGwgYmUgYCdkZWZhdWx0IG5hbWUnYFxuICB9KTtcbiAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignRm91bmQgdXNlciwgYnV0IHN0aWxsIHVuaGFwcHknKTtcbiAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScpO1xuICB9KS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIC8vIGlmIGBmaW5kVXNlcmAgZnVsZmlsbGVkLCBgcmVhc29uYCB3aWxsIGJlICdGb3VuZCB1c2VyLCBidXQgc3RpbGwgdW5oYXBweScuXG4gICAgLy8gSWYgYGZpbmRVc2VyYCByZWplY3RlZCwgYHJlYXNvbmAgd2lsbCBiZSAnYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScuXG4gIH0pO1xuICBgYGBcbiAgSWYgdGhlIGRvd25zdHJlYW0gcHJvbWlzZSBkb2VzIG5vdCBzcGVjaWZ5IGEgcmVqZWN0aW9uIGhhbmRsZXIsIHJlamVjdGlvbiByZWFzb25zIHdpbGwgYmUgcHJvcGFnYXRlZCBmdXJ0aGVyIGRvd25zdHJlYW0uXG4gICBgYGBqc1xuICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICB0aHJvdyBuZXcgUGVkYWdvZ2ljYWxFeGNlcHRpb24oJ1Vwc3RyZWFtIGVycm9yJyk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLy8gbmV2ZXIgcmVhY2hlZFxuICB9KS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIC8vIFRoZSBgUGVkZ2Fnb2NpYWxFeGNlcHRpb25gIGlzIHByb3BhZ2F0ZWQgYWxsIHRoZSB3YXkgZG93biB0byBoZXJlXG4gIH0pO1xuICBgYGBcbiAgIEFzc2ltaWxhdGlvblxuICAtLS0tLS0tLS0tLS1cbiAgIFNvbWV0aW1lcyB0aGUgdmFsdWUgeW91IHdhbnQgdG8gcHJvcGFnYXRlIHRvIGEgZG93bnN0cmVhbSBwcm9taXNlIGNhbiBvbmx5IGJlXG4gIHJldHJpZXZlZCBhc3luY2hyb25vdXNseS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkgcmV0dXJuaW5nIGEgcHJvbWlzZSBpbiB0aGVcbiAgZnVsZmlsbG1lbnQgb3IgcmVqZWN0aW9uIGhhbmRsZXIuIFRoZSBkb3duc3RyZWFtIHByb21pc2Ugd2lsbCB0aGVuIGJlIHBlbmRpbmdcbiAgdW50aWwgdGhlIHJldHVybmVkIHByb21pc2UgaXMgc2V0dGxlZC4gVGhpcyBpcyBjYWxsZWQgKmFzc2ltaWxhdGlvbiouXG4gICBgYGBqc1xuICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICByZXR1cm4gZmluZENvbW1lbnRzQnlBdXRob3IodXNlcik7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKGNvbW1lbnRzKSB7XG4gICAgLy8gVGhlIHVzZXIncyBjb21tZW50cyBhcmUgbm93IGF2YWlsYWJsZVxuICB9KTtcbiAgYGBgXG4gICBJZiB0aGUgYXNzaW1saWF0ZWQgcHJvbWlzZSByZWplY3RzLCB0aGVuIHRoZSBkb3duc3RyZWFtIHByb21pc2Ugd2lsbCBhbHNvIHJlamVjdC5cbiAgIGBgYGpzXG4gIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgIHJldHVybiBmaW5kQ29tbWVudHNCeUF1dGhvcih1c2VyKTtcbiAgfSkudGhlbihmdW5jdGlvbiAoY29tbWVudHMpIHtcbiAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIGZ1bGZpbGxzLCB3ZSdsbCBoYXZlIHRoZSB2YWx1ZSBoZXJlXG4gIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIHJlamVjdHMsIHdlJ2xsIGhhdmUgdGhlIHJlYXNvbiBoZXJlXG4gIH0pO1xuICBgYGBcbiAgIFNpbXBsZSBFeGFtcGxlXG4gIC0tLS0tLS0tLS0tLS0tXG4gICBTeW5jaHJvbm91cyBFeGFtcGxlXG4gICBgYGBqYXZhc2NyaXB0XG4gIGxldCByZXN1bHQ7XG4gICB0cnkge1xuICAgIHJlc3VsdCA9IGZpbmRSZXN1bHQoKTtcbiAgICAvLyBzdWNjZXNzXG4gIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgLy8gZmFpbHVyZVxuICB9XG4gIGBgYFxuICAgRXJyYmFjayBFeGFtcGxlXG4gICBgYGBqc1xuICBmaW5kUmVzdWx0KGZ1bmN0aW9uKHJlc3VsdCwgZXJyKXtcbiAgICBpZiAoZXJyKSB7XG4gICAgICAvLyBmYWlsdXJlXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHN1Y2Nlc3NcbiAgICB9XG4gIH0pO1xuICBgYGBcbiAgIFByb21pc2UgRXhhbXBsZTtcbiAgIGBgYGphdmFzY3JpcHRcbiAgZmluZFJlc3VsdCgpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KXtcbiAgICAvLyBzdWNjZXNzXG4gIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgLy8gZmFpbHVyZVxuICB9KTtcbiAgYGBgXG4gICBBZHZhbmNlZCBFeGFtcGxlXG4gIC0tLS0tLS0tLS0tLS0tXG4gICBTeW5jaHJvbm91cyBFeGFtcGxlXG4gICBgYGBqYXZhc2NyaXB0XG4gIGxldCBhdXRob3IsIGJvb2tzO1xuICAgdHJ5IHtcbiAgICBhdXRob3IgPSBmaW5kQXV0aG9yKCk7XG4gICAgYm9va3MgID0gZmluZEJvb2tzQnlBdXRob3IoYXV0aG9yKTtcbiAgICAvLyBzdWNjZXNzXG4gIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgLy8gZmFpbHVyZVxuICB9XG4gIGBgYFxuICAgRXJyYmFjayBFeGFtcGxlXG4gICBgYGBqc1xuICAgZnVuY3Rpb24gZm91bmRCb29rcyhib29rcykge1xuICAgfVxuICAgZnVuY3Rpb24gZmFpbHVyZShyZWFzb24pIHtcbiAgIH1cbiAgIGZpbmRBdXRob3IoZnVuY3Rpb24oYXV0aG9yLCBlcnIpe1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZmluZEJvb29rc0J5QXV0aG9yKGF1dGhvciwgZnVuY3Rpb24oYm9va3MsIGVycikge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgZm91bmRCb29rcyhib29rcyk7XG4gICAgICAgICAgICB9IGNhdGNoKHJlYXNvbikge1xuICAgICAgICAgICAgICBmYWlsdXJlKHJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgZmFpbHVyZShlcnIpO1xuICAgICAgfVxuICAgICAgLy8gc3VjY2Vzc1xuICAgIH1cbiAgfSk7XG4gIGBgYFxuICAgUHJvbWlzZSBFeGFtcGxlO1xuICAgYGBgamF2YXNjcmlwdFxuICBmaW5kQXV0aG9yKCkuXG4gICAgdGhlbihmaW5kQm9va3NCeUF1dGhvcikuXG4gICAgdGhlbihmdW5jdGlvbihib29rcyl7XG4gICAgICAvLyBmb3VuZCBib29rc1xuICB9KS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gIH0pO1xuICBgYGBcbiAgIEBtZXRob2QgdGhlblxuICBAcGFyYW0ge0Z1bmN0aW9ufSBvbkZ1bGZpbGxlZFxuICBAcGFyYW0ge0Z1bmN0aW9ufSBvblJlamVjdGVkXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX1cbiAgKi9cblxuICAvKipcbiAgYGNhdGNoYCBpcyBzaW1wbHkgc3VnYXIgZm9yIGB0aGVuKHVuZGVmaW5lZCwgb25SZWplY3Rpb24pYCB3aGljaCBtYWtlcyBpdCB0aGUgc2FtZVxuICBhcyB0aGUgY2F0Y2ggYmxvY2sgb2YgYSB0cnkvY2F0Y2ggc3RhdGVtZW50LlxuICBgYGBqc1xuICBmdW5jdGlvbiBmaW5kQXV0aG9yKCl7XG4gIHRocm93IG5ldyBFcnJvcignY291bGRuJ3QgZmluZCB0aGF0IGF1dGhvcicpO1xuICB9XG4gIC8vIHN5bmNocm9ub3VzXG4gIHRyeSB7XG4gIGZpbmRBdXRob3IoKTtcbiAgfSBjYXRjaChyZWFzb24pIHtcbiAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgfVxuICAvLyBhc3luYyB3aXRoIHByb21pc2VzXG4gIGZpbmRBdXRob3IoKS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICB9KTtcbiAgYGBgXG4gIEBtZXRob2QgY2F0Y2hcbiAgQHBhcmFtIHtGdW5jdGlvbn0gb25SZWplY3Rpb25cbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfVxuICAqL1xuXG5cbiAgUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2ggPSBmdW5jdGlvbiBfY2F0Y2gob25SZWplY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKG51bGwsIG9uUmVqZWN0aW9uKTtcbiAgfTtcblxuICAvKipcbiAgICBgZmluYWxseWAgd2lsbCBiZSBpbnZva2VkIHJlZ2FyZGxlc3Mgb2YgdGhlIHByb21pc2UncyBmYXRlIGp1c3QgYXMgbmF0aXZlXG4gICAgdHJ5L2NhdGNoL2ZpbmFsbHkgYmVoYXZlc1xuICBcbiAgICBTeW5jaHJvbm91cyBleGFtcGxlOlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRBdXRob3IoKSB7XG4gICAgICBpZiAoTWF0aC5yYW5kb20oKSA+IDAuNSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQXV0aG9yKCk7XG4gICAgfVxuICBcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGZpbmRBdXRob3IoKTsgLy8gc3VjY2VlZCBvciBmYWlsXG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgcmV0dXJuIGZpbmRPdGhlckF1dGhlcigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBhbHdheXMgcnVuc1xuICAgICAgLy8gZG9lc24ndCBhZmZlY3QgdGhlIHJldHVybiB2YWx1ZVxuICAgIH1cbiAgICBgYGBcbiAgXG4gICAgQXN5bmNocm9ub3VzIGV4YW1wbGU6XG4gIFxuICAgIGBgYGpzXG4gICAgZmluZEF1dGhvcigpLmNhdGNoKGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICByZXR1cm4gZmluZE90aGVyQXV0aGVyKCk7XG4gICAgfSkuZmluYWxseShmdW5jdGlvbigpe1xuICAgICAgLy8gYXV0aG9yIHdhcyBlaXRoZXIgZm91bmQsIG9yIG5vdFxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBAbWV0aG9kIGZpbmFsbHlcbiAgICBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgIEByZXR1cm4ge1Byb21pc2V9XG4gICovXG5cblxuICBQcm9taXNlLnByb3RvdHlwZS5maW5hbGx5ID0gZnVuY3Rpb24gX2ZpbmFsbHkoY2FsbGJhY2spIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gICAgdmFyIGNvbnN0cnVjdG9yID0gcHJvbWlzZS5jb25zdHJ1Y3RvcjtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGNhbGxiYWNrKSkge1xuICAgICAgcmV0dXJuIHByb21pc2UudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yLnJlc29sdmUoY2FsbGJhY2soKSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yLnJlc29sdmUoY2FsbGJhY2soKSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhyb3cgcmVhc29uO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oY2FsbGJhY2ssIGNhbGxiYWNrKTtcbiAgfTtcblxuICByZXR1cm4gUHJvbWlzZTtcbn0oKTtcblxuUHJvbWlzZSQxLnByb3RvdHlwZS50aGVuID0gdGhlbjtcblByb21pc2UkMS5hbGwgPSBhbGw7XG5Qcm9taXNlJDEucmFjZSA9IHJhY2U7XG5Qcm9taXNlJDEucmVzb2x2ZSA9IHJlc29sdmUkMTtcblByb21pc2UkMS5yZWplY3QgPSByZWplY3QkMTtcblByb21pc2UkMS5fc2V0U2NoZWR1bGVyID0gc2V0U2NoZWR1bGVyO1xuUHJvbWlzZSQxLl9zZXRBc2FwID0gc2V0QXNhcDtcblByb21pc2UkMS5fYXNhcCA9IGFzYXA7XG5cbi8qZ2xvYmFsIHNlbGYqL1xuZnVuY3Rpb24gcG9seWZpbGwoKSB7XG4gIHZhciBsb2NhbCA9IHZvaWQgMDtcblxuICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBsb2NhbCA9IGdsb2JhbDtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBsb2NhbCA9IHNlbGY7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsID0gRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BvbHlmaWxsIGZhaWxlZCBiZWNhdXNlIGdsb2JhbCBvYmplY3QgaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBlbnZpcm9ubWVudCcpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBQID0gbG9jYWwuUHJvbWlzZTtcblxuICBpZiAoUCkge1xuICAgIHZhciBwcm9taXNlVG9TdHJpbmcgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBwcm9taXNlVG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUC5yZXNvbHZlKCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIHNpbGVudGx5IGlnbm9yZWRcbiAgICB9XG5cbiAgICBpZiAocHJvbWlzZVRvU3RyaW5nID09PSAnW29iamVjdCBQcm9taXNlXScgJiYgIVAuY2FzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGxvY2FsLlByb21pc2UgPSBQcm9taXNlJDE7XG59XG5cbi8vIFN0cmFuZ2UgY29tcGF0Li5cblByb21pc2UkMS5wb2x5ZmlsbCA9IHBvbHlmaWxsO1xuUHJvbWlzZSQxLlByb21pc2UgPSBQcm9taXNlJDE7XG5cbnJldHVybiBQcm9taXNlJDE7XG5cbn0pKSk7XG5cblxuXG4vLyMgc291cmNlTWFwcGluZ1VSTD1lczYtcHJvbWlzZS5tYXBcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb29raWVzID0gcmVxdWlyZSgnLi9jb29raWVzJyk7XG5cbiQod2luZG93KS5vbignbG9hZCcsIGZ1bmN0aW9uICgpIHtcblx0Ly8gSWYgcmVsIGlzIG5vdCBwcmVsb2FkLCBlaXRoZXIgYnJvd3NlciBvciBwb2x5ZmlsbCBoYXMgbG9hZGVkIHN0eWxlc2hlZXRcblx0aWYgKFxuXHRcdCQoJ2xpbmtbZGF0YS1zdHlsZXNoZWV0XScpLmF0dHIoJ3JlbCcpICE9PSAncHJlbG9hZCdcblx0XHQmJiAoXG5cdFx0XHQhY29va2llcy5nZXRJdGVtKCdmdWVudGVzX2NyaXRpY2FsX2NzcycpXG5cdFx0XHR8fFxuXHRcdFx0Y29va2llcy5nZXRJdGVtKCdmdWVudGVzX2NyaXRpY2FsX2NzcycpICE9PSAkKCdbZGF0YS1tdGltZV0nKS5kYXRhKCdtdGltZScpXG5cdFx0KVxuXHQpIHtcblx0XHQvLyBDaGVjayBpZiBuZXcgZGF0YS1tdGltZSBpcyBhdmFpbGFibGUgYW5kIHNldCBpdCBpbiBjb29raWVcblx0XHRpZiAoICQoJ1tkYXRhLW10aW1lXScpLmRhdGEoJ210aW1lJykgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGNvb2tpZXMuc2V0SXRlbSgnZnVlbnRlc19jcml0aWNhbF9jc3MnLCAkKCdbZGF0YS1tdGltZV0nKS5kYXRhKCdtdGltZScpKTtcblx0XHR9XG5cdH1cbn0pO1xuIiwiY29uc3QgVE9HR0xFX0NMQVNTID0gJ2lzLXNob3duJztcbmNvbnN0IERFRkFVTFRfT1BFTl9DTEFTUyA9ICdkZWZhdWx0LW9wZW4nO1xuXG5mdW5jdGlvbiBpbml0Q29sbGFwc2libGVTZWN0aW9uKHRvZ2dsZSkge1xuICBjb25zdCBzZWN0aW9uUGFyZW50ID0gdG9nZ2xlLmNsb3Nlc3QoJ1tkYXRhLWpzLWJpbmQ9XCJjb2xsYXBzaWJsZS1zZWN0aW9uXCJdJyk7XG4gIGNvbnN0IGNvbnRyb2xsZWRQYW5lbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgYCMke3RvZ2dsZS5nZXRBdHRyaWJ1dGUoJ2FyaWEtY29udHJvbHMnKX1gXG4gICk7XG5cbiAgY29uc3QgY2xvc2VPdGhlckFjY29yZGlvblNlY3Rpb24gPSAoKSA9PiB7XG4gICAgY29uc3QgZXhwYW5kZWRUb2dnbGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgJ1tkYXRhLWpzLWJpbmQ9XCJjb2xsYXBzaWJsZS10b2dnbGVcIl1bYXJpYS1leHBhbmRlZD1cInRydWVcIl0nXG4gICAgKTtcbiAgICBjb25zdCBleHBhbmRlZFBhbmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICcuaXMtc2hvd25bZGF0YS1qcy1iaW5kPVwiY29sbGFwc2libGUtcGFuZWxcIl0nXG4gICAgKTtcblxuICAgIGlmICghZXhwYW5kZWRUb2dnbGUgfHwgIWV4cGFuZGVkUGFuZWwpIHJldHVybjtcblxuICAgIGV4cGFuZGVkVG9nZ2xlLnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsIGZhbHNlKTtcbiAgICBleHBhbmRlZFBhbmVsLmNsYXNzTGlzdC5yZW1vdmUoVE9HR0xFX0NMQVNTKTtcbiAgICBleHBhbmRlZFBhbmVsLmNsYXNzTGlzdC5yZW1vdmUoREVGQVVMVF9PUEVOX0NMQVNTKTtcbiAgfTtcblxuICBjb25zdCB0b2dnbGVTZWN0aW9uID0gKCkgPT4ge1xuICAgIGNvbnN0IGNvbGxhcHNpYmxlQWxsVG9nZ2xlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICdbZGF0YS1qcy1iaW5kPVwiY29sbGFwc2libGUtYWxsLXRvZ2dsZVwiXSdcbiAgICApO1xuICAgIGNvbnN0IGV4cGFuZGVkVG9nZ2xlcyA9IFsuLi5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBgW2RhdGEtanMtYmluZD1cImNvbGxhcHNpYmxlLXRvZ2dsZVwiXWBcbiAgICApXTtcbiAgICBjb25zdCBleHBhbmRlZCA9IHRvZ2dsZS5nZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnKSA9PT0gJ3RydWUnIHx8IGZhbHNlO1xuXG4gICAgaWYgKHRvZ2dsZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtYWNjb3JkaW9uJykgPT09ICd0cnVlJykge1xuICAgICAgY2xvc2VPdGhlckFjY29yZGlvblNlY3Rpb24oKTtcbiAgICB9XG5cbiAgICB0b2dnbGUuc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgIWV4cGFuZGVkKTtcbiAgICBjb250cm9sbGVkUGFuZWwuY2xhc3NMaXN0LnRvZ2dsZShUT0dHTEVfQ0xBU1MsICFleHBhbmRlZCk7XG4gICAgY29udHJvbGxlZFBhbmVsLmNsYXNzTGlzdC5yZW1vdmUoREVGQVVMVF9PUEVOX0NMQVNTKTtcblxuICAgIGlmICghZXhwYW5kZWQgJiYgdG9nZ2xlLmRhdGFzZXQuc2Nyb2xsSW50b1ZpZXcgPT09ICd0cnVlJykge1xuICAgICAgdG9nZ2xlLnBhcmVudE5vZGUuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnc3RhcnQnIH0pO1xuICAgIH1cblxuICAgIGlmIChjb2xsYXBzaWJsZUFsbFRvZ2dsZSkge1xuICAgICAgZXhwYW5kZWRUb2dnbGVzLnNvbWUoKGV4cGFuZGVkVG9nZ2xlKSA9PiB7XG4gICAgICAgIHJldHVybiBleHBhbmRlZFRvZ2dsZS5nZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnKSA9PT0gJ3RydWUnO1xuICAgICAgfSkgID8gY29sbGFwc2libGVBbGxUb2dnbGUudGV4dENvbnRlbnQgPSBcIkFsbGVzIGlua2xhcHBlblwiIDogY29sbGFwc2libGVBbGxUb2dnbGUudGV4dENvbnRlbnQgPSBcIkFsbGVzIHVpdGtsYXBwZW5cIjtcbiAgICB9XG4gIH07XG5cbiAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoID09PSBgIyR7c2VjdGlvblBhcmVudC5pZH1gKSB7XG4gICAgdG9nZ2xlU2VjdGlvbigpO1xuICAgIHRvZ2dsZS5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdzdGFydCcgfSk7XG4gIH1cblxuICB0b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0b2dnbGVTZWN0aW9uKTtcblxuICAvLyBleHBvc2UgZGVzdHJveSBtZXRob2RcbiAgcmV0dXJuICgpID0+IHtcbiAgICB0b2dnbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0b2dnbGVTZWN0aW9uKTtcbiAgfTtcbn1cblxuY29uc3QgdG9nZ2xlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWpzLWJpbmQ9XCJjb2xsYXBzaWJsZS10b2dnbGVcIl0nKTtcbnRvZ2dsZXMuZm9yRWFjaCgodG9nZ2xlKSA9PiB7XG4gIGluaXRDb2xsYXBzaWJsZVNlY3Rpb24odG9nZ2xlKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGluaXRDb2xsYXBzaWJsZVNlY3Rpb247XG4iLCJpZiAoJCgnW2RhdGEtY29uZmlybV0nKS5sZW5ndGgpIHtcbiAgICAkKCdbZGF0YS1jb25maXJtXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghd2luZG93LmNvbmZpcm0oJCh0aGlzKS5kYXRhKCdjb25maXJtJykpKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn0iLCJ2YXIgZG9jQ29va2llcyA9IHtcblx0Z2V0SXRlbTogZnVuY3Rpb24gKHNLZXkpIHtcblx0XHRpZiAoIXNLZXkpIHsgcmV0dXJuIG51bGw7IH1cblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKG5ldyBSZWdFeHAoXCIoPzooPzpefC4qOylcXFxccypcIiArIGVuY29kZVVSSUNvbXBvbmVudChzS2V5KS5yZXBsYWNlKC9bXFwtXFwuXFwrXFwqXS9nLCBcIlxcXFwkJlwiKSArIFwiXFxcXHMqXFxcXD1cXFxccyooW147XSopLiokKXxeLiokXCIpLCBcIiQxXCIpKSB8fCBudWxsO1xuXHR9LFxuXHRzZXRJdGVtOiBmdW5jdGlvbiAoc0tleSwgc1ZhbHVlLCB2RW5kLCBzUGF0aCwgc0RvbWFpbiwgYlNlY3VyZSkge1xuXHRcdGlmICghc0tleSB8fCAvXig/OmV4cGlyZXN8bWF4XFwtYWdlfHBhdGh8ZG9tYWlufHNlY3VyZSkkL2kudGVzdChzS2V5KSkgeyByZXR1cm4gZmFsc2U7IH1cblx0XHR2YXIgc0V4cGlyZXMgPSBcIlwiO1xuXHRcdGlmICh2RW5kKSB7XG5cdFx0XHRzd2l0Y2ggKHZFbmQuY29uc3RydWN0b3IpIHtcblx0XHRcdFx0Y2FzZSBOdW1iZXI6XG5cdFx0XHRcdFx0c0V4cGlyZXMgPSB2RW5kID09PSBJbmZpbml0eSA/IFwiOyBleHBpcmVzPUZyaSwgMzEgRGVjIDk5OTkgMjM6NTk6NTkgR01UXCIgOiBcIjsgbWF4LWFnZT1cIiArIHZFbmQ7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgU3RyaW5nOlxuXHRcdFx0XHRcdHNFeHBpcmVzID0gXCI7IGV4cGlyZXM9XCIgKyB2RW5kO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIERhdGU6XG5cdFx0XHRcdFx0c0V4cGlyZXMgPSBcIjsgZXhwaXJlcz1cIiArIHZFbmQudG9VVENTdHJpbmcoKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdFx0ZG9jdW1lbnQuY29va2llID0gZW5jb2RlVVJJQ29tcG9uZW50KHNLZXkpICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoc1ZhbHVlKSArIHNFeHBpcmVzICsgKHNEb21haW4gPyBcIjsgZG9tYWluPVwiICsgc0RvbWFpbiA6IFwiXCIpICsgKHNQYXRoID8gXCI7IHBhdGg9XCIgKyBzUGF0aCA6IFwiXCIpICsgKGJTZWN1cmUgPyBcIjsgc2VjdXJlXCIgOiBcIlwiKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblx0cmVtb3ZlSXRlbTogZnVuY3Rpb24gKHNLZXksIHNQYXRoLCBzRG9tYWluKSB7XG5cdFx0aWYgKCF0aGlzLmhhc0l0ZW0oc0tleSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cdFx0ZG9jdW1lbnQuY29va2llID0gZW5jb2RlVVJJQ29tcG9uZW50KHNLZXkpICsgXCI9OyBleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgR01UXCIgKyAoc0RvbWFpbiA/IFwiOyBkb21haW49XCIgKyBzRG9tYWluIDogXCJcIikgKyAoc1BhdGggPyBcIjsgcGF0aD1cIiArIHNQYXRoIDogXCJcIik7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cdGhhc0l0ZW06IGZ1bmN0aW9uIChzS2V5KSB7XG5cdFx0aWYgKCFzS2V5KSB7IHJldHVybiBmYWxzZTsgfVxuXHRcdHJldHVybiAobmV3IFJlZ0V4cChcIig/Ol58O1xcXFxzKilcIiArIGVuY29kZVVSSUNvbXBvbmVudChzS2V5KS5yZXBsYWNlKC9bXFwtXFwuXFwrXFwqXS9nLCBcIlxcXFwkJlwiKSArIFwiXFxcXHMqXFxcXD1cIikpLnRlc3QoZG9jdW1lbnQuY29va2llKTtcblx0fSxcblx0a2V5czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBhS2V5cyA9IGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKC8oKD86XnxcXHMqOylbXlxcPV0rKSg/PTt8JCl8Xlxccyp8XFxzKig/OlxcPVteO10qKT8oPzpcXDF8JCkvZywgXCJcIikuc3BsaXQoL1xccyooPzpcXD1bXjtdKik/O1xccyovKTtcblx0XHRmb3IgKHZhciBuTGVuID0gYUtleXMubGVuZ3RoLCBuSWR4ID0gMDsgbklkeCA8IG5MZW47IG5JZHgrKykgeyBhS2V5c1tuSWR4XSA9IGRlY29kZVVSSUNvbXBvbmVudChhS2V5c1tuSWR4XSk7IH1cblx0XHRyZXR1cm4gYUtleXM7XG5cdH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZG9jQ29va2llczsiLCIndXNlIHN0cmljdCc7XG5cbi8vIFBvbHlmaWxsIHByb21pc2VzXG53aW5kb3cuUHJvbWlzZSA9IHdpbmRvdy5Qcm9taXNlIHx8IHJlcXVpcmUoJ2VzNi1wcm9taXNlJykuUHJvbWlzZTtcblxudmFyIGxvYWRlZCA9IGZhbHNlO1xuXG4vKipcbiAqIEdvb2dsZSBNYXBzIEFQSSBzZXJ2aWNlXG4gKiBAdHlwZSB7UHJvbWlzZX1cbiAqL1xuZnVuY3Rpb24gZ2V0TWFwc0FQSSgpIHtcblx0aWYgKCBsb2FkZWQgPT09IGZhbHNlICkge1xuXHRcdGxvYWRTY3JpcHQoKTtcblx0fVxuXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiBnbWFwc0FwaVByb21pc2UocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdFx0dmFyIGdtYXBBcGk7XG5cblx0XHQvLyBGdW5jdGlvbiBnZXRzIGNhbGxlZCB3aGVuIEdvb2dsZSBNYXBzIEFQSSBoYXMgbG9hZGVkXG5cdFx0d2luZG93LmluaXRHb29nbGVNYXBzID0gZnVuY3Rpb24gaW5pdEdvb2dsZU1hcHMoKSB7XG5cdFx0XHRnbWFwQXBpID0gZ29vZ2xlLm1hcHM7XG5cblx0XHRcdGxvYWRlZCA9IHRydWU7XG5cblx0XHRcdHJlc29sdmUoZ21hcEFwaSk7XG5cdFx0fTtcblx0fSk7XG59O1xuXG4vLyBJbml0cyB0aGUgYXBwZW5kaW5nIG9mIHRoZSBnbWFwcyBzY3JpcHRcbmZ1bmN0aW9uIGxvYWRTY3JpcHQoKSB7XG5cdHZhciBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0c2NyaXB0LnNyYyA9ICdodHRwczovL21hcHMuZ29vZ2xlYXBpcy5jb20vbWFwcy9hcGkvanM/a2V5PUFJemFTeURfRktUUEhlelo4M0JtdlNjVVdPbU5aTk0zTk1TZ3BnWSZjYWxsYmFjaz13aW5kb3cuaW5pdEdvb2dsZU1hcHMnO1xuXHRzY3JpcHQuYXN5bmMgPSB0cnVlO1xuXHRzY3JpcHQuZGVmZXIgPSB0cnVlO1xuXHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcmlwdCk7XG59XG5cbi8vIFV0aWxpdHkgZnVuY3Rpb24gdG8gZ2V0IHRoZSBtYXBzIEFQSVxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGdldE1hcHNBUEk6IGdldE1hcHNBUElcbn07IiwiY29uc3QgJGVucm9sbFRvZ2V0aGVySW5mbyA9ICQoJ1tkYXRhLWpzLWJpbmQ9XCJlbnJvbGwtdG9nZXRoZXJcIl0nKTtcbmxldCByZWNhbGNQb3NpdGlvbnM7XG5cbmZ1bmN0aW9uIGNoZWNrUG9wdXBQb3NpdGlvbnMoKSB7XG4gIGlmIChyZWNhbGNQb3NpdGlvbnMpIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJlY2FsY1Bvc2l0aW9ucyk7XG4gIHJlY2FsY1Bvc2l0aW9ucyA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbigpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8ICRlbnJvbGxUb2dldGhlckluZm8ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHRoaXNJbmZvID0gJGVucm9sbFRvZ2V0aGVySW5mb1tpXTtcbiAgICAgIGNvbnN0IHRoaXNQb3B1cCA9IHRoaXNJbmZvLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWpzLWJpbmQ9XCJlbnJvbGwtdG9nZXRoZXItcG9wdXBcIl0nKTtcbiAgICAgIGNvbnN0IHRoaXNJbmZvQm90dG9tID0gdGhpc0luZm8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tO1xuICAgICAgY29uc3QgcG9wdXBIZWlnaHQgPSB0aGlzUG9wdXAuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuICAgICAgdGhpc0luZm8uY2xhc3NMaXN0W3RoaXNJbmZvQm90dG9tICsgcG9wdXBIZWlnaHQgPj0gd2luZG93LmlubmVySGVpZ2h0PyAnYWRkJyA6ICdyZW1vdmUnXSgnYy1lbnJvbGwtdG9nZXRoZXItLXBvcHVwLXRvcCcpO1xuICAgIH1cbiAgfSk7XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBjaGVja1BvcHVwUG9zaXRpb25zKTtcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBjaGVja1BvcHVwUG9zaXRpb25zKTtcblxuY2hlY2tQb3B1cFBvc2l0aW9ucygpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZ21hcHMgPSByZXF1aXJlKCcuLi9nbWFwcy1hcGknKTtcblxudmFyICRtYXBzQ29udGFpbmVyID0gJCgnLmxvY2F0aW9ucy1tYXAnKTtcbnZhciB6b29tTGV2ZWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggPCA0ODAgPyA5IDogMTA7XG52YXIgaXNDaXR5TWFwID0gJG1hcHNDb250YWluZXIuZGF0YSgnbWFwdHlwZScpID09PSAnY2l0eSc7XG5cbndpbmRvdy5pbml0TWFwID0gZnVuY3Rpb24gKCkge1xuICBpZiAoICRtYXBzQ29udGFpbmVyLmxlbmd0aCApIHtcbiAgICBnbWFwcy5nZXRNYXBzQVBJKClcbiAgICAgIC8vIExvYWRlZCBtYXBzXG4gICAgICAudGhlbihsb2FkTWFwcylcbiAgICAgIC8vIEVycm9yIGxvYWRpbmcgbWFwc1xuICAgICAgLmNhdGNoKGZ1bmN0aW9uIG1hcHNFcnJvcihlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICB9KTtcbiAgfVxufVxuXG5pZiAoIWlzQ2l0eU1hcCkge1xuICBpbml0TWFwKCk7XG59XG5cblxuLy8gTG9hZCB0aGUgbWFwIHdpdGggbWFya2Vyc1xuZnVuY3Rpb24gbG9hZE1hcHMoZ21hcHMpIHtcblx0dmFyIG1hcmtlckRhdGEgPSAkbWFwc0NvbnRhaW5lci5kYXRhKCdtYXJrZXJzJyk7XG5cdHZhciBtYXJrZXJzID0gW107XG5cblx0Ly8gQ29uZmlnIG9wdGlvbnNcblx0dmFyIG1hcENvbmZpZyA9IHtcblx0XHR6b29tOiBpc0NpdHlNYXA/IDE2IDogOCxcblx0XHRzY3JvbGx3aGVlbDogZmFsc2UsXG5cdFx0Z2VzdHVyZUhhbmRsaW5nOiAnY29vcGVyYXRpdmUnLFxuXHRcdG1hcFR5cGVDb250cm9sOiBmYWxzZSxcblx0XHRjZW50ZXI6IG5ldyBnbWFwcy5MYXRMbmcoNTIuMTAwNTU2LCA1LjY0NTgzMylcblx0fTtcblx0dmFyIGljb24gPSB7XG5cdFx0YW5jaG9yOiBuZXcgZ21hcHMuUG9pbnQoMTksIDU4KSxcblx0XHRzY2FsZWRTaXplOiBuZXcgZ21hcHMuU2l6ZSg2MCw2NCksXG5cdFx0dXJsOiAnL2Fzc2V0cy9pbWFnZXMvbWlzYy9tYXJrZXIucG5nJ1xuXHR9O1xuXHR2YXIgbWFya2VyT3B0aW9ucyA9IHtcblx0XHRhbmltYXRpb246IGdtYXBzLkFuaW1hdGlvbi5EUk9QLFxuXHRcdGljb246IGljb24sXG5cdFx0bWFwOiBtYXBcblx0fTtcblxuXHQvLyBNYXAgZmVhdHVyZSBpbnN0YW5jZXNcblx0dmFyIGJvdW5kcyA9IG5ldyBnbWFwcy5MYXRMbmdCb3VuZHMoKTtcblx0dmFyIG1hcCA9IG5ldyBnbWFwcy5NYXAoJG1hcHNDb250YWluZXJbMF0sIG1hcENvbmZpZyk7XG5cdHZhciBpbmZvV2luZG93ID0gbmV3IGdtYXBzLkluZm9XaW5kb3coKTtcblxuXHQvLyBBZGQgbWFya2Vyc1xuXHRtYXJrZXJEYXRhLmZvckVhY2goZnVuY3Rpb24gKG1hcmtlciwgaSkge1xuXHRcdHZhciBwb3NpdGlvbiA9IHtcblx0XHRcdGxhdDogbWFya2VyLmxhdCxcblx0XHRcdGxuZzogbWFya2VyLmxuZ1xuXHRcdH07XG5cblx0XHRpZiAoIHBvc2l0aW9uLmxhdCA9PT0gbnVsbCAmJiBwb3NpdGlvbi5sbmcgPT09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQWRkIG1hcmtlciB0byBtYXBcblx0XHRtYXJrZXJzW2ldID0gbmV3IGdtYXBzLk1hcmtlcih7XG5cdFx0XHRwb3NpdGlvbjogcG9zaXRpb24sXG5cdFx0XHRpY29uOiBpY29uLFxuXHRcdFx0bWFwOiBtYXAsXG5cdFx0XHRtYXJrZXJOYW1lOiBtYXJrZXIubmFtZSxcblx0XHRcdG1hcmtlclVybDogbWFya2VyLnVybCB8fCBmYWxzZSxcblx0XHRcdGFkZHJlc3MxOiBtYXJrZXIuYWRkcmVzczEgfHwgZmFsc2UsXG5cdFx0XHRhZGRyZXNzMjogbWFya2VyLmFkZHJlc3MyIHx8IGZhbHNlLFxuXHRcdFx0ZGVzY3JpcHRpb246IG1hcmtlci5kZXNjcmlwdGlvbiB8fCBmYWxzZVxuXHRcdH0pO1xuXG5cdFx0Ly8gT3BlbiBpbmZvV2luZG93IGFuZCBzZXQgY29udGVudCBvbiBjbGljayBvbiBtYXJrZXJcblx0XHRtYXJrZXJzW2ldLmFkZExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdGluZm9XaW5kb3cuc2V0T3B0aW9ucyh7XG5cdFx0XHRcdGNvbnRlbnQ6IGdldEluZm9XaW5kb3dDb250ZW50KHtcblx0XHRcdFx0XHRuYW1lOiB0aGlzLm1hcmtlck5hbWUsXG5cdFx0XHRcdFx0YWRkcmVzczE6IHRoaXMuYWRkcmVzczEsXG5cdFx0XHRcdFx0YWRkcmVzczI6IHRoaXMuYWRkcmVzczIsXG5cdFx0XHRcdFx0ZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG5cdFx0XHRcdFx0dXJsOiB0aGlzLm1hcmtlclVybFxuXHRcdFx0XHR9KSxcblx0XHRcdFx0cG9zaXRpb246IHRoaXMucG9zaXRpb24sXG5cdFx0XHRcdHBpeGVsT2Zmc2V0OiBuZXcgZ21hcHMuU2l6ZSgwLCAtNzApXG5cdFx0XHR9KTtcblx0XHRcdGluZm9XaW5kb3cub3BlbihtYXApO1xuXHRcdH0pO1xuXG5cdFx0Ly8gQWRkIG1hcmtlciB0byBib3VuZHNcblx0XHRib3VuZHMuZXh0ZW5kKHBvc2l0aW9uKTtcblx0fSk7XG5cblx0Ly8gRml0IG1hcCB0byBtYXJrZXIgYm91bmRzIGFuZCBjZW50ZXIgcG9zaXRpb25cblx0bWFwLnNldENlbnRlcihib3VuZHMuZ2V0Q2VudGVyKCkpO1xuXHRpZiAobWFya2Vycy5sZW5ndGggPiAxKSB7XG5cdFx0bWFwLmZpdEJvdW5kcyhib3VuZHMpO1xuXHR9XG5cblx0Ly8gSW5pdCBnZW9sb2NhdGlvbiBmb3Igc3VwcG9ydGluZyBicm93c2Vyc1xuXHRpbml0R2VvbG9jYXRpb24obWFwLCBnbWFwcyk7XG5cblx0Ly8gSW5pdCBnZW9jb2RpbmcgZm9yIGFkZHJlc3Mgc2VhcmNoXG5cdGluaXRHZW9jb2RpbmcobWFwLCBnbWFwcyk7XG59XG5cbmZ1bmN0aW9uIGdldEluZm9XaW5kb3dDb250ZW50KG9wdHMpIHtcblx0dmFyIGh0bWwgPSAnJztcblx0dmFyIGRpcmVjdGlvbnNVcmw7XG5cblx0aHRtbCArPSBpc0NpdHlNYXA/ICc8ZGl2IGNsYXNzPVwibG9jYXRpb25zLW1hcC1pbmZvIGxvY2F0aW9ucy1tYXAtaW5mby0tbG9jYXRpb25cIj4nIDogJzxkaXYgY2xhc3M9XCJsb2NhdGlvbnMtbWFwLWluZm9cIj4nO1xuXHRodG1sICs9IFx0JzxoMj4nICsgb3B0cy5uYW1lICsgJzwvaDI+Jztcblx0aWYgKGlzQ2l0eU1hcCkge1xuXHRcdGRpcmVjdGlvbnNVcmwgPSBlbmNvZGVVUklDb21wb25lbnQob3B0cy5hZGRyZXNzMSArICcsJyArIG9wdHMuYWRkcmVzczIgKyAnLE5lZGVybGFuZCcpO1xuXHRcdGh0bWwgKz0gJzxwIGNsYXNzPVwiYWRkcmVzc1wiPicgKyBvcHRzLmFkZHJlc3MxICsgJywgJyArIG9wdHMuYWRkcmVzczIgKyAnPC9wPic7XG5cdFx0aHRtbCArPSBvcHRzLmRlc2NyaXB0aW9uLmxlbmd0aCA+IDA/IGl0czIwMTdXaHlDYW50RnVja2luZ0phdmFzY3JpcHREZWNvZGVTb21lSFRNTChvcHRzLmRlc2NyaXB0aW9uKSA6ICcnO1xuXHRcdGh0bWwgKz0gJzxhIGhyZWY9XCJodHRwczovL3d3dy5nb29nbGUuY29tL21hcHMvZGlyL2N1cnJlbnQrbG9jYXRpb24vJyArIGRpcmVjdGlvbnNVcmwgKyAnL1wiIHRhcmdldD1cIl9ibGFua1wiPic7XG5cdFx0aHRtbCArPVx0J1JvdXRlYmVzY2hyaWp2aW5nJztcblx0XHRodG1sICs9XHRnZXRTdmcoJ2Fycm93LXJpZ2h0JywgOCwgOCk7XG5cdFx0aHRtbCArPSAnPC9hPic7XG5cdH0gZWxzZSB7XG5cdFx0aHRtbCArPSBcdCc8YSBocmVmPVwiJyArIG9wdHMudXJsICsgJ1wiPic7XG5cdFx0aHRtbCArPVx0XHRnZXRTdmcoJ2Jvb2snLCAyMCwgMjApO1xuXHRcdGh0bWwgKz1cdFx0J0Jla2lqayBoZXQgY3Vyc3VzYWFuYm9kJztcblx0XHRodG1sICs9XHRcdGdldFN2ZygnYXJyb3ctcmlnaHQnLCA4LCA4KTtcblx0XHRodG1sICs9IFx0JzwvYT4nO1xuXHR9XG5cdGh0bWwgKz0gJzwvZGl2Pic7XG5cblx0cmV0dXJuIGRlY29kZVVSSShodG1sKTtcbn07XG5cbmZ1bmN0aW9uIGdldFN2ZyhuYW1lLCB3aWR0aCwgaGVpZ2h0KSB7XG5cdHZhciBodG1sID0gJyc7XG5cblx0aHRtbCArPSAnPHN2ZyB3aWR0aD1cIicgKyB3aWR0aCArICdcIiBoZWlnaHQ9XCInICsgaGVpZ2h0ICsgJ1wiPic7XG5cdGh0bWwgKz0gXHQnPHVzZSB4bGluazpocmVmPVwiL2J1aWxkL3N2Zy9kaXN0LnN2ZyMnICsgbmFtZSArICdcIj4nO1xuXHRodG1sICs9ICc8L3N2Zz4nO1xuXG5cdHJldHVybiBodG1sO1xufVxuXG5mdW5jdGlvbiBpbml0R2VvbG9jYXRpb24obWFwKSB7XG5cdGlmICggJ2dlb2xvY2F0aW9uJyBpbiBuYXZpZ2F0b3IgJiYgIWlzQ2l0eU1hcCApIHtcblx0XHRuYXZpZ2F0b3IuZ2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKGZ1bmN0aW9uIHByb2Nlc3NHZW9sb2NhdGlvbihyZXN1bHQpIHtcblx0XHRcdGlmICggcmVzdWx0LmNvb3Jkcy5sYXRpdHVkZSAmJiByZXN1bHQuY29vcmRzLmxhdGl0dWRlICkge1xuXHRcdFx0XHRtYXAuc2V0Q2VudGVyKHtcblx0XHRcdFx0XHRsYXQ6IHJlc3VsdC5jb29yZHMubGF0aXR1ZGUsXG5cdFx0XHRcdFx0bG5nOiByZXN1bHQuY29vcmRzLmxvbmdpdHVkZVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0bWFwLnNldFpvb20oem9vbUxldmVsKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuXG5mdW5jdGlvbiBpbml0R2VvY29kaW5nKG1hcCwgZ21hcHMpIHtcblx0dmFyICRzZWFyY2hCYXIgPSAkKCcubG9jYXRpb24tc2VhcmNoLWJhcicpO1xuXHR2YXIgJG5vUmVzdWx0cyA9ICRzZWFyY2hCYXIuZmluZCgnLm5vLXJlc3VsdHMnKTtcblx0dmFyIGdlb2NvZGVyID0gbmV3IGdtYXBzLkdlb2NvZGVyKCk7XG5cblx0JHNlYXJjaEJhci5vbignc3VibWl0JywgZnVuY3Rpb24gZ2VvY29kZUFkZHJlc3MoZSkge1xuXHRcdHZhciAkZm9ybSA9ICQodGhpcyk7XG5cblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHQkbm9SZXN1bHRzLmVtcHR5KCkuYWRkQ2xhc3MoJ2hpZGRlbicpO1xuXG5cdFx0Z2VvY29kZXIuZ2VvY29kZSh7XG5cdFx0XHRhZGRyZXNzOiAkc2VhcmNoQmFyLmZpbmQoJy5sb2NhdGlvbi1zZWFyY2gtaW5wdXQnKS52YWwoKSxcblx0XHRcdGNvbXBvbmVudFJlc3RyaWN0aW9uczoge1xuXHRcdFx0XHRjb3VudHJ5OiAnbmwnXG5cdFx0XHR9XG5cdFx0fSwgZnVuY3Rpb24gcHJvY2Vzc1Jlc3VsdHMgKHJlc3VsdHMpIHtcblx0XHRcdC8vIGlmICggcmVzdWx0cy5sZW5ndGggJiYgY2hlY2tUeXBlcyhyZXN1bHRzWzBdLnR5cGVzKSApIHtcblxuXHRcdFx0aWYgKCByZXN1bHRzLmxlbmd0aCApIHsgLy8gSXZkVzogRGlzYWJsZWQgcmVzdWx0IHR5cGUgY2hlY2tpbmcgZm9yIG5vdyAoMjQtMDEtMjAxNylcblx0XHRcdFx0bWFwLnNldENlbnRlcih7XG5cdFx0XHRcdFx0bGF0OiByZXN1bHRzWzBdLmdlb21ldHJ5LmxvY2F0aW9uLmxhdCgpLFxuXHRcdFx0XHRcdGxuZzogcmVzdWx0c1swXS5nZW9tZXRyeS5sb2NhdGlvbi5sbmcoKVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0bWFwLnNldFpvb20oem9vbUxldmVsKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCRub1Jlc3VsdHMudGV4dCgnR2VlbiByZXN1bHRhdGVuIGdldm9uZGVuLCBwcm9iZWVyIGhldCBub2dtYWFscycpLnJlbW92ZUNsYXNzKCdoaWRkZW4nKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG59XG5cbi8vIENoZWNrIGlmIGl0ZW1zIGluIHRoZSByZXN1bHQgbWF0Y2ggdGhlIGFsbG93ZWQgdHlwZXNcbmZ1bmN0aW9uIGNoZWNrVHlwZXModHlwZXMpIHtcblx0dmFyIGFsbG93ZWRUeXBlcyA9IFtcblx0XHQnc3VibG9jYWxpdHknLFxuXHRcdCdsb2NhbGl0eScsXG5cdFx0J3Bvc3RhbF9jb2RlJyxcblx0XHQnc3RyZWV0X2FkZHJlc3MnLFxuXHRcdCdjb2xsb3F1aWFsX2FyZWEnLFxuXHRcdCdhZG1pbmlzdHJhdGl2ZV9hcmVhX2xldmVsXzInXG5cdF07XG5cblx0cmV0dXJuIHR5cGVzLnNvbWUoZnVuY3Rpb24gZnVuY3Rpb25OYW1lKHR5cGUpIHtcblx0XHRyZXR1cm4gYWxsb3dlZFR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xXG5cdH0pO1xufVxuXG5mdW5jdGlvbiBpdHMyMDE3V2h5Q2FudEZ1Y2tpbmdKYXZhc2NyaXB0RGVjb2RlU29tZUhUTUwoaHRtbCkge1xuXHR2YXIgdWdoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRleHRhcmVhXCIpO1xuXHR2YXIgY29tZU9ubm5uO1xuXHR1Z2guaW5uZXJIVE1MID0gaHRtbDtcblx0Y29tZU9ubm5uID0gdWdoLnZhbHVlO1xuXHRyZXR1cm4gY29tZU9ubm5uO1xufVxuIiwiY29uc3QgaGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtanMtYmluZD1cImhlYWRlclwiXScpO1xuXG5pZiAoIWhlYWRlcikgcmV0dXJuO1xuXG5jb25zdCB0b2dnbGVNZW51QnV0dG9uID0gaGVhZGVyLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWpzLWJpbmQ9XCJ0b2dnbGUtbWVudVwiXScpO1xuY29uc3QgbWVudSA9IGhlYWRlci5xdWVyeVNlbGVjdG9yKGAjJHt0b2dnbGVNZW51QnV0dG9uLmdldEF0dHJpYnV0ZSgnYXJpYS1jb250cm9scycpfWApO1xuY29uc3QgbWFpbk1lbnUgPSBoZWFkZXIucXVlcnlTZWxlY3RvcignW2RhdGEtanMtYmluZD1cIm1haW4tbWVudVwiXScpO1xuY29uc3Qgc2hvd01lbnVPbkhvdmVyQnV0dG9ucyA9IFsuLi5tZW51LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWpzLWJpbmQ9XCJzaG93LW1lbnUtb24taG92ZXJcIl0nKV07XG5jb25zdCB0b2dnbGVTdWJNZW51QnV0dG9ucyA9IFsuLi5tZW51LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWpzLWJpbmQ9XCJ0b2dnbGUtc3ViLW1lbnVcIl0nKV07XG5jb25zdCBzdWJNZW51cyA9IFsuLi5tZW51LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLWpzLWJpbmQ9XCJzdWItbWVudVwiXScpXTtcbmNvbnN0IHN1Yk1lbnVDaGlsZHMgPSBbLi4ubWVudS5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1qcy1iaW5kPVwic3ViLW1lbnVcIl0gW2RhdGEtanMtYmluZD1cInN1Yi1tZW51XCJdJyldO1xuXG5pZighdG9nZ2xlTWVudUJ1dHRvbiB8fCAhbWVudSkgcmV0dXJuO1xuXG5jb25zdCBNRU5VX1NIT1dOX0NMQVNTID0gJ21lbnUtaXMtc2hvd24nO1xuY29uc3QgQUNUSVZFX0JVVFRPTl9DTEFTUyA9ICdpcy1hY3RpdmUnO1xuY29uc3QgQUNUSVZFX1NVQk1FTlVfQ0xBU1MgPSAnaXMtc2hvd24nO1xuXG4vLyBDbG9zZSB0aGUgc3ViIG1lbnUgY2hpbGRcbmNvbnN0IGhpZGVTdWJNZW51Q2hpbGRyZW4gPSAoKSA9PiB7XG4gIHRvZ2dsZVN1Yk1lbnVCdXR0b25zLmZvckVhY2goKHN1Yk1lbnVCdXR0b24pID0+IHtcbiAgICBpZiAoc3ViTWVudUJ1dHRvbi5nZXRBdHRyaWJ1dGUoJ2FyaWEtY29udHJvbHMnKSA9PT0gXCJjb3Vyc2UtZ3JvdXBzLXN1Ym1lbnVcIikgcmV0dXJuO1xuICAgIHN1Yk1lbnVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZShBQ1RJVkVfQlVUVE9OX0NMQVNTKTtcbiAgICBzdWJNZW51QnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsIGZhbHNlKTtcbiAgfSk7XG4gIHN1Yk1lbnVDaGlsZHMuZm9yRWFjaCgoc3ViTWVudUNoaWxkKSA9PiB7XG4gICAgc3ViTWVudUNoaWxkLmhpZGRlbiA9IHRydWU7XG4gIH0pO1xufTtcblxuY29uc3QgdG9nZ2xlTWVudSA9IChtZW51QnV0dG9uKSA9PiB7XG4gIGNvbnN0IGV4cGFuZGVkID1cbiAgICBtZW51QnV0dG9uLmdldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcpID09PSAndHJ1ZScgfHwgZmFsc2U7XG5cbiAgaWYgKCFleHBhbmRlZCkge1xuICAgIGhpZGVTdWJNZW51Q2hpbGRyZW4oKTtcbiAgfTtcblxuICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdFtleHBhbmRlZCA/ICdyZW1vdmUnIDogJ2FkZCddKE1FTlVfU0hPV05fQ0xBU1MpO1xuICBtZW51QnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsICFleHBhbmRlZCk7XG4gIG1lbnUuaGlkZGVuID0gIWV4cGFuZGVkO1xufTtcblxuY29uc3QgdG9nZ2xlTWFpbk1lbnUgPSAoKSA9PiB7XG4gIGNvbnN0IGV4cGFuZGVkID1cbiAgICB0b2dnbGVNZW51QnV0dG9uLmdldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcpID09PSAndHJ1ZScgfHwgZmFsc2U7XG4gIFxuICBpZiAoIWV4cGFuZGVkKSB7XG4gICAgaGlkZVN1Yk1lbnVDaGlsZHJlbigpO1xuICB9O1xuXG4gIHRvZ2dsZU1lbnVCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgIWV4cGFuZGVkKTtcbiAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3RbZXhwYW5kZWQgPyAncmVtb3ZlJyA6ICdhZGQnXShNRU5VX1NIT1dOX0NMQVNTKTtcbiAgbWVudS5oaWRkZW4gPSBleHBhbmRlZDtcbn1cblxuY29uc3Qgc2hvd1N1Yk1lbnUgPSAoaG92ZXJCdXR0b24pID0+IHtcbiAgY29uc3QgYnV0dG9uID0gaG92ZXJCdXR0b24ucXVlcnlTZWxlY3RvcignW2RhdGEtanMtYmluZD1cInRvZ2dsZS1zdWItbWVudVwiXScpO1xuICBjb25zdCBzdWJNZW51SWQgPSBidXR0b24uZ2V0QXR0cmlidXRlKCdhcmlhLWNvbnRyb2xzJyk7XG5cbiAgLy8gSGlkZSBhbGwgc3ViIG1lbnUgY2hpbGRzXG4gIGhpZGVTdWJNZW51Q2hpbGRyZW4oKTtcblxuICBidXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgdHJ1ZSk7XG4gIGJ1dHRvbi5jbGFzc0xpc3QuYWRkKEFDVElWRV9CVVRUT05fQ0xBU1MpO1xuICAvLyBTaG93L2hpZGUgdGhlIHN1Ym1lbnUgY29udHJvbGxlZCBieSB0aGUgY2xpY2tlZCBtYWluIG1lbnUgYnV0dG9uXG4gIHN1Yk1lbnVzLmZvckVhY2goKHN1Yk1lbnUpID0+IHtcbiAgICBjb25zdCBjbGlja2VkU3ViTWVudSA9IHN1Yk1lbnUuaWQgPT09IHN1Yk1lbnVJZDtcbiAgICAvLyBGb2N1cyBmaXJzdCBpdGVtIGluIHN1Yk1lbnVcbiAgICBpZiAoY2xpY2tlZFN1Yk1lbnUpIHtcbiAgICAgIHN1Yk1lbnUuaGlkZGVuID0gZmFsc2U7XG4gICAgfVxuICB9KTtcbn1cblxuY29uc3QgY2xvc2VTdWJNZW51ID0gKGhvdmVyQnV0dG9uKSA9PiB7XG4gIGNvbnN0IGJ1dHRvbiA9IGhvdmVyQnV0dG9uLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWpzLWJpbmQ9XCJ0b2dnbGUtc3ViLW1lbnVcIl0nKTtcbiAgY29uc3Qgc3ViTWVudUlkID0gYnV0dG9uLmdldEF0dHJpYnV0ZSgnYXJpYS1jb250cm9scycpO1xuICBcbiAgLy8gSGlkZSBhbGwgc3ViIG1lbnUgY2hpbGRzXG4gIGhpZGVTdWJNZW51Q2hpbGRyZW4oKTtcblxuICBidXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgZmFsc2UpO1xuICBidXR0b24uY2xhc3NMaXN0LnJlbW92ZShBQ1RJVkVfQlVUVE9OX0NMQVNTKTtcbiAgLy8gU2hvdy9oaWRlIHRoZSBzdWJtZW51IGNvbnRyb2xsZWQgYnkgdGhlIGNsaWNrZWQgbWFpbiBtZW51IGJ1dHRvblxuICBzdWJNZW51cy5mb3JFYWNoKChzdWJNZW51KSA9PiB7XG4gICAgY29uc3QgY2xpY2tlZFN1Yk1lbnUgPSBzdWJNZW51LmlkID09PSBzdWJNZW51SWQ7XG4gICAgLy8gRm9jdXMgZmlyc3QgaXRlbSBpbiBzdWJNZW51XG4gICAgaWYgKGNsaWNrZWRTdWJNZW51KSB7XG4gICAgICBzdWJNZW51LmhpZGRlbiA9IHRydWU7XG4gICAgfVxuICB9KTtcbn07XG5cbmNvbnN0IHRvZ2dsZVNob3dTdWJNZW51ID0gKGUpID0+IHtcbiAgY29uc3QgYnV0dG9uID0gZS50YXJnZXQ7XG4gIGNvbnN0IGV4cGFuZGVkID1cbiAgICBidXR0b24uZ2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJykgPT09ICd0cnVlJyB8fCBmYWxzZTtcbiAgY29uc3Qgc3ViTWVudUlkID0gYnV0dG9uLmdldEF0dHJpYnV0ZSgnYXJpYS1jb250cm9scycpO1xuICBcbiAgLy8gSGlkZSBhbGwgc3ViIG1lbnUgY2hpbGRzXG4gIGhpZGVTdWJNZW51Q2hpbGRyZW4oKTtcblxuICBidXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgIWV4cGFuZGVkKTtcbiAgYnV0dG9uLmNsYXNzTGlzdFtleHBhbmRlZCA/ICdyZW1vdmUnIDogJ2FkZCddKEFDVElWRV9CVVRUT05fQ0xBU1MpO1xuICAvLyBTaG93L2hpZGUgdGhlIHN1Ym1lbnUgY29udHJvbGxlZCBieSB0aGUgY2xpY2tlZCBtYWluIG1lbnUgYnV0dG9uXG4gIHN1Yk1lbnVzLmZvckVhY2goKHN1Yk1lbnUpID0+IHtcbiAgICBjb25zdCBjbGlja2VkU3ViTWVudSA9IHN1Yk1lbnUuaWQgPT09IHN1Yk1lbnVJZDtcbiAgICBpZiAoIXN1Yk1lbnUuY29udGFpbnMoZS50YXJnZXQpKSB7XG4gICAgICBzdWJNZW51LmNsYXNzTGlzdC5yZW1vdmUoQUNUSVZFX1NVQk1FTlVfQ0xBU1MpO1xuICAgIH1cbiAgICAvLyBGb2N1cyBmaXJzdCBpdGVtIGluIHN1Yk1lbnVcbiAgICBpZiAoY2xpY2tlZFN1Yk1lbnUpIHtcbiAgICAgIHN1Yk1lbnUuaGlkZGVuID0gZXhwYW5kZWQ7XG4gICAgICBzdWJNZW51LmNsYXNzTGlzdFtleHBhbmRlZCA/ICdyZW1vdmUnIDogJ2FkZCddKEFDVElWRV9TVUJNRU5VX0NMQVNTKTtcbiAgICB9XG4gIH0pO1xufTtcblxuXG5jb25zdCBoYXNVc2VyQ2xpY2tlZE91dHNpZGVIZWFkZXIgPSAoZSkgPT4ge1xuICBpZiAoIW1haW5NZW51LmNvbnRhaW5zKGUudGFyZ2V0KSkge1xuICAgIHRvZ2dsZVN1Yk1lbnVCdXR0b25zLmZvckVhY2goKHN1Yk1lbnVCdXR0b24pID0+IHtcbiAgICAgIHN1Yk1lbnVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZShBQ1RJVkVfQlVUVE9OX0NMQVNTKTtcbiAgICAgIHN1Yk1lbnVCdXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgZmFsc2UpO1xuICAgIH0pO1xuICAgIHN1Yk1lbnVzLmZvckVhY2goKHN1Yk1lbnUpID0+IHtcbiAgICAgIHN1Yk1lbnUuaGlkZGVuID0gdHJ1ZTtcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBDbG9zZSB0aGUgc2VsZWN0IHdoZW4gY2xpY2tpbmcgb3V0c2lkZSBvZiBpdFxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGhhc1VzZXJDbGlja2VkT3V0c2lkZUhlYWRlcik7XG50b2dnbGVNZW51QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdG9nZ2xlTWFpbk1lbnUpO1xudG9nZ2xlU3ViTWVudUJ1dHRvbnMuZm9yRWFjaCh0b2dnbGVTdWJNZW51QnV0dG9uID0+IHRvZ2dsZVN1Yk1lbnVCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0b2dnbGVTaG93U3ViTWVudSkpXG4iLCIoZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQsICQpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICBpZiAoICQoJy5tb2RhbC1zY2hlZHVsZScpLmxlbmd0aCApIHtcbiAgICAgICAgdmFyIHRhYmxlQ29udGVudCwgZGF0ZSwgZCwgbSwgeSwgZGlzcGxheURhdGUsIHN0YXJ0LCBlbmQsIGRpc3BsYXlTdGFydCwgZGlzcGxheUVuZCwgdGltZSwgbG9jYXRpb24sIG9ubGluZTtcbiAgICAgICAgdmFyIGRheXMgPSBbJ3pvbmRhZycsICdtYWFuZGFnJywgJ2RpbnNkYWcnLCAnd29lbnNkYWcnLCAnZG9uZGVyZGFnJywgJ3ZyaWpkYWcnLCAnemF0ZXJkYWcnXTtcbiAgICAgICAgdmFyICRtb2RhbCA9ICQoJy5tb2RhbC1zY2hlZHVsZScpLmxhc3QoKTtcblxuICAgICAgICAkKCcuc2hvdy1zY2hlZHVsZScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIHZhciBkYXRhID0gSlNPTi5wYXJzZSgkKHRoaXMpLmRhdGEoJ3NjaGVkdWxlJykpO1xuICAgICAgICAgICAgdmFyICR0YWJsZUJvZHkgPSAkbW9kYWwuZmluZCgndGJvZHknKTtcbiAgICAgICAgICAgIHZhciByb3dUZW1wbGF0ZSA9ICQoJy5zY2hlZHVsZS1yb3cnKS5maXJzdCgpLmh0bWwoKTtcbiAgICAgICAgICAgIHRhYmxlQ29udGVudCA9ICcnO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgdGFibGUgYm9keSBjb250ZW50IGZyb20gdGVtcGxhdGUgcm93XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgZGF0ZSA9IGRhdGFbaV0uZGF0ZSB8fCBmYWxzZTtcbiAgICAgICAgICAgICAgc3RhcnQgPSBkYXRhW2ldLnN0YXJ0IHx8IGZhbHNlO1xuICAgICAgICAgICAgICBlbmQgPSBkYXRhW2ldLmVuZCB8fCBmYWxzZTtcbiAgICAgICAgICAgICAgbG9jYXRpb24gPSBkYXRhW2ldLmxvY2F0aW9uIHx8ICdWb2xndCBub2cnO1xuICAgICAgICAgICAgICBvbmxpbmUgPSBkYXRhW2ldLm9ubGluZTtcblxuICAgICAgICAgICAgICBpZiAoIGRhdGUgKSB7XG4gICAgICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICAgICAgICAgIGQgPSBwYWQoZGF0ZS5nZXRVVENEYXRlKCkpO1xuICAgICAgICAgICAgICAgIG0gPSBwYWQoZGF0ZS5nZXRVVENNb250aCgpICsgMSk7IC8vIHlheSB6ZXJvLWluZGV4aW5nIVxuICAgICAgICAgICAgICAgIHkgPSBkYXRlLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgZGlzcGxheURhdGUgPSBkYXlzW2RhdGUuZ2V0RGF5KCldICsgJyAnICsgZCArICctJyArIG0gKyAnLScgKyB5O1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRpc3BsYXlEYXRlID0gJ29uYmVrZW5kJztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICggc3RhcnQgKSB7XG4gICAgICAgICAgICAgICAgZGlzcGxheVN0YXJ0ID0gc3RhcnQuc3Vic3RyKDAsNSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoIGVuZCApIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5RW5kID0gZW5kLnN1YnN0cigwLDUpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKCBzdGFydCAmJiBlbmQgKSB7XG4gICAgICAgICAgICAgICAgdGltZSA9IGRpc3BsYXlTdGFydCArICcgLSAnICsgZGlzcGxheUVuZDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aW1lID0gJ29uYmVrZW5kJztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHZhciB0aGlzUm93Q29udGVudCA9IHJvd1RlbXBsYXRlXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJ1tbIGluZGV4IF1dJywgKGkgKyAxKSApXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJ1tbIGRhdGUgXV0nLCBkaXNwbGF5RGF0ZSlcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgnW1sgdGltZSBdXScsIHRpbWUpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJ1tbIGxvY2F0aW9uIF1dJywgbG9jYXRpb24pO1xuXG4gICAgICAgICAgICAgIHZhciB0aGlzUm93RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RhYmxlJyk7XG4gICAgICAgICAgICAgIHRoaXNSb3dFbGVtZW50LmlubmVySFRNTCA9IHRoaXNSb3dDb250ZW50O1xuXG4gICAgICAgICAgICAgIGlmIChvbmxpbmUpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGhpc1Jvd0FkZHJlc0NlbGwgPSB0aGlzUm93RWxlbWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1qcy1iaW5kPVwic2NoZWR1bGUtYWRkcmVzcy1jZWxsXCJdJyk7XG4gICAgICAgICAgICAgICAgdGhpc1Jvd0FkZHJlc0NlbGwucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzUm93QWRkcmVzQ2VsbCk7XG4gICAgICAgICAgICAgICAgJG1vZGFsLmZpbmQoJ1tkYXRhLWpzLWJpbmQ9XCJzY2hlZHVsZS1hZGRyZXNzLWhlYWRlclwiXScpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdGFibGVDb250ZW50ICs9IHRoaXNSb3dFbGVtZW50LmNoaWxkcmVuWzBdLmlubmVySFRNTDtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBhZGQgcm93cyB0byB0YWJsZVxuICAgICAgICAgICAgJHRhYmxlQm9keS5odG1sKHRhYmxlQ29udGVudCk7XG5cbiAgICAgICAgICAgIC8vIHNob3cgbW9kYWxcbiAgICAgICAgICAgICRtb2RhbC5hZGRDbGFzcygnc2hvdy1tb2RhbCcpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYWQoaW5wdXQpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gaW5wdXQudG9TdHJpbmcoKSB8fCBmYWxzZTtcblxuICAgICAgICBpZiAoIGlucHV0ID09PSBmYWxzZSApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAoJzAwJytpbnB1dCkuc3Vic3RyaW5nKGlucHV0Lmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9XG59KHRoaXMsIGRvY3VtZW50LCBqUXVlcnkpKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuJCgnLnNlYXJjaC1jb3Vyc2UnKS5vbignc3VibWl0JywgZnVuY3Rpb24gKGUpIHtcblx0dmFyICRmb3JtID0gJCh0aGlzKVxuXHR2YXIgJHNlbGVjdHMgPSAkZm9ybS5maW5kKCdzZWxlY3QnKTtcblx0dmFyIHZhbHVlID0gJyc7XG5cblx0JHNlbGVjdHMuZm9yRWFjaChmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKCB0aGlzLnZhbHVlICkge1xuXHRcdFx0dmFsdWUgPSB0aGlzLnZhbHVlO1xuXHRcdH1cblx0fSk7XG5cblx0aWYgKCB2YWx1ZSA9PT0gJycgKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHR9XG59KTsiLCIvKipcbiAqIExvdHMgb2Ygb3RoZXIgc3R1ZmYgY29uY2VybmluZyB0aGUgc2VhcmNoIHdpZGdldCBjYW4gYmUgZm91bmQgaW4gdGhpc1xuICogbW9uc3Ryb3VzIGJvd2wgb2Ygc3BhZ2hldHRpLCBqdXN0IHRyeSB0byBhZGQgbmV3IHN0dWZmIGhlcmUuXG4gKi9cblxuZnVuY3Rpb24gY29uZGl0aW9uYWxSZXF1aXJlbWVudCh3aWRnZXQpIHtcbiAgaWYoIXdpZGdldCkgcmV0dXJuO1xuXG4gIGNvbnN0IG9uTG9jYXRpb25SYWRpbyA9IHdpZGdldC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1qcy1iaW5kPVwicmFkaW8tbG9jYXRpb25cIl0nKTtcbiAgY29uc3QgY291cnNlU2VsZWN0b3IgPSB3aWRnZXQucXVlcnlTZWxlY3RvcignW2RhdGEtanMtYmluZD1cImNvdXJzZVwiXScpO1xuICBjb25zdCBsb2NhdGlvblNlbGVjdG9yID0gd2lkZ2V0LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWpzLWJpbmQ9XCJsb2NhdGlvblwiXScpO1xuICBjb25zdCBzdWJtaXRCdXR0b24gPSB3aWRnZXQucXVlcnlTZWxlY3RvcignW2RhdGEtanMtYmluZD1cInNlYXJjaC13aWRnZXQtc3VibWl0XCJdJyk7XG5cbiAgaWYoIW9uTG9jYXRpb25SYWRpbyB8fCAhY291cnNlU2VsZWN0b3IgfHwgIWxvY2F0aW9uU2VsZWN0b3IgfHwgIXN1Ym1pdEJ1dHRvbikgcmV0dXJuO1xuXG4gIHN1Ym1pdEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICAvKlxuICAgICAgQ291cnNlIHNlbGVjdG9yIGlzIHJlcXVpcmVkIHdoZW5cbiAgICAgIC0gbG9va2luZyBmb3Igb25saW5lIGNvdXJzZXMgKG1lYW5pbmcgbG9jYXRpb24gcmFkaW8gaXMgTk9UIGNoZWNrZWQpXG4gICAgICAtIGxvY2F0aW9uIHJhZGlvIGlzIGNoZWNrZWQgQU5EIGxvY2F0aW9uIHNlbGVjdG9yIGlzIGVtcHR5XG4gICAgICovXG4gICAgY291cnNlU2VsZWN0b3IucmVxdWlyZWQgPSBvbkxvY2F0aW9uUmFkaW8uY2hlY2tlZCA/IGxvY2F0aW9uU2VsZWN0b3IudmFsdWUgPT09ICcnIDogdHJ1ZTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGluaXRTZWFyY2hXaWRnZXQoKSB7XG4gIGNvbnN0IHdpZGdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLW1vZHVsZT1cInNlYXJjaC13aWRnZXRcIl0nKTtcbiAgaWYoIXdpZGdldCkgcmV0dXJuO1xuICBjb25kaXRpb25hbFJlcXVpcmVtZW50KHdpZGdldCk7XG59XG5cbmluaXRTZWFyY2hXaWRnZXQoKTtcbiIsIiQoJ1tkYXRhLWpzPVwiZXhwYW5kLWZ1dHVyZS1sZXNzb25zXCJdJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XHJcbiAgJCh0aGlzKS5jbG9zZXN0KCdbZGF0YS1qcz1cInBlcmlvZC1kaXZpZGVyLXJvd1wiXScpLnRvZ2dsZUNsYXNzKCdsZXNzb25zLXRhYmxlX19wZXJpb2QtZGl2aWRlci0tZXhwYW5kZWQnKTtcclxufSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiAgIENvbXBhcmVzIGEgcGFzdCBkYXRlIHRvIGN1cnJlbnQgZGF0ZSBhbmQgcGFyc2VzIGl0IGluIGEgcmVhZGFibGUgc3RyaW5nXG4gKiAgIHJldHVybnMgXCI4IGphYXIgZ2VsZWRlblwiIC8gXCIzIGRhZ2VuIGdlbGVkZW5cIiBldGMuXG4gKi9cblxudmFyICR0aW1lRGlmZmVyZW5jZXMgPSAkKCcuanMtdGltZS1kaWZmZXJlbmNlJyk7XG5cbiR0aW1lRGlmZmVyZW5jZXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gIHZhciBlbGVtID0gdGhpcztcbiAgdmFyIHMgPSAkKGVsZW0pLmh0bWwoKTtcbiAgdmFyIGEgPSBzLnNwbGl0KC9bXjAtOV0vKTtcbiAgdmFyIGQgPSBuZXcgRGF0ZShhWzBdLCBhWzFdIC0gMSwgYVsyXSwgYVszXSwgYVs0XSwgYVs1XSk7XG4gICQoZWxlbSkuaHRtbCh0aW1lRGlmZmVyZW5jZShkKSk7XG59KTtcblxuZnVuY3Rpb24gdGltZURpZmZlcmVuY2UocGFzdERhdGUpIHtcbiAgLy8gaW4gbWlsbGlzZWNvbmRzXG4gIGxldCB1bml0cyA9IHtcbiAgICB5ZWFyOiAyNCAqIDYwICogNjAgKiAxMDAwICogMzY1LFxuICAgIG1vbnRoOiAyNCAqIDYwICogNjAgKiAxMDAwICogMzY1IC8gMTIsXG4gICAgZGF5OiAyNCAqIDYwICogNjAgKiAxMDAwLFxuICAgIGhvdXI6IDYwICogNjAgKiAxMDAwLFxuICAgIG1pbnV0ZTogNjAgKiAxMDAwLFxuICAgIHNlY29uZDogMTAwMFxuICB9XG5cbiAgbGV0IHJ0ZiA9IG5ldyBJbnRsLlJlbGF0aXZlVGltZUZvcm1hdCgnbmwnLCB7bnVtZXJpYzogJ2F1dG8nfSlcbiAgbGV0IGdldFJlbGF0aXZlVGltZSA9IChkMSwgZDIgPSBEYXRlLm5vdygpKSA9PiB7XG4gICAgbGV0IGVsYXBzZWQgPSBkMSAtIGQyO1xuICAgIGZvciAobGV0IHUgaW4gdW5pdHMpIHtcbiAgICAgIGlmIChNYXRoLmFicyhlbGFwc2VkKSA+IHVuaXRzW3VdIHx8IHUgPT09ICdzZWNvbmQnKSB7XG4gICAgICAgIHJldHVybiBydGYuZm9ybWF0KE1hdGgucm91bmQoZWxhcHNlZCAvIHVuaXRzW3VdKSwgdSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBnZXRSZWxhdGl2ZVRpbWUocGFzdERhdGUpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICR0cnVuY2F0ZVRleHRzID0gJCgnLmpzLXRydW5jYXRlLXRleHQnKTtcbnZhciB0cnVuY0F0dHIgPSAndHJ1bmMtYW1vdW50JztcblxuJHRydW5jYXRlVGV4dHMuZWFjaChmdW5jdGlvbiAoKSB7XG4gIHZhciBlbGVtID0gdGhpcztcbiAgdmFyIHRydW5jQnkgPSAkKGVsZW0pLmF0dHIodHJ1bmNBdHRyKSB8fCAzMzA7XG4gIHZhciBvcmlnU3RyID0gJChlbGVtKS5odG1sKCk7XG4gIHZhciBuZXdTdHIgPSB0cnVuY2F0ZShvcmlnU3RyLCB0cnVuY0J5LCB0cnVlKTtcblxuICBpZiAob3JpZ1N0ciAhPT0gbmV3U3RyKSB7XG4gICAgJChlbGVtKS5odG1sKG5ld1N0cik7XG4gICAgJChlbGVtKS5hcHBlbmQoJzxidXR0b24gY2xhc3M9XCJidG4tbGluayBidG4taW5saW5lXCI+bWVlcjwvYnV0dG9uPicpO1xuXG4gICAgJCgnLmJ0bi1saW5rJywgZWxlbSkub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgJChlbGVtKS5odG1sKG9yaWdTdHIpO1xuICAgIH0pO1xuICB9XG59KTtcblxuZnVuY3Rpb24gdHJ1bmNhdGUoc3RyLCBuLCB1c2VXb3JkQm91bmRhcnkpIHtcbiAgaWYgKHN0ci5sZW5ndGggPD0gbikge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbiAgY29uc3Qgc3ViU3RyaW5nID0gc3RyLnN1YnN0cigwLCBuIC0gMSk7XG4gIHJldHVybiAodXNlV29yZEJvdW5kYXJ5XG4gICAgPyBzdWJTdHJpbmcuc3Vic3RyKDAsIHN1YlN0cmluZy5sYXN0SW5kZXhPZihcIiBcIikpXG4gICAgOiBzdWJTdHJpbmcpICsgXCImaGVsbGlwO1wiO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbmNvbnN0IFNCX09OTElORV9DTEFTUyA9ICdzZWFyY2gtYmFyLS1vbmxpbmUnO1xuY29uc3QgU0JfT0ZGTElORV9DTEFTUyA9ICdzZWFyY2gtYmFyLS1vZmZsaW5lJztcbmNvbnN0IFNNQUxMRVJfUEFERElORyA9ICdzbWFsbGVyLXBhZGRpbmcnO1xuY29uc3QgTEFSR0VSX1BBRERJTkcgPSAnbGFyZ2VyLXBhZGRpbmcnO1xuXG5zZXRUaW1lb3V0KCgpID0+IHtcbiAgY29uc3QgJHNlYXJjaEJhciA9ICQoJy5zZWFyY2gtYmFyJyk7XG4gIGNvbnN0ICR3cmFwcGVyID0gJCgnLndyYXBwZXItaW5uZXIubGF5b3V0LWNvbnRhaW5lcicpO1xuICBpZiAoJHNlYXJjaEJhci5oYXNDbGFzcyhTQl9PTkxJTkVfQ0xBU1MpKSB7XG4gICAgJHdyYXBwZXIuYWRkQ2xhc3MoU01BTExFUl9QQURESU5HKVxuICB9IGVsc2UgaWYgKCRzZWFyY2hCYXIuaGFzQ2xhc3MoU0JfT0ZGTElORV9DTEFTUykpIHtcbiAgICAkd3JhcHBlci5hZGRDbGFzcyhMQVJHRVJfUEFERElORylcbiAgfVxufSwgMzAwKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyICRiaWxsaW5nRmllbGRzVG9nZ2xlID0gJCgnLnRvZ2dsZS1iaWxsaW5nLWFkZHJlc3MnKTtcbnZhciAkYmlsbGluZ0ZpZWxkcyA9ICQoJy5iaWxsaW5nLWZpZWxkcycpO1xudmFyICRvcHRpb25hbEJpbGxpbmdmaWVsZHMgPSAkYmlsbGluZ0ZpZWxkcy5maW5kKCcuYmlsbGluZy1yZXF1aXJlZCcpO1xuXG4vLyBUb2dnbGVzIGJpbGxpbmcgZm9ybSB3aGVuIGFkZHJlc3MgaXMgbm90IHRoZSBzYW1lIGFzIGJpbGxpbmcgYWRkcmVzc1xuJGJpbGxpbmdGaWVsZHNUb2dnbGUub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIGNoZWNrZWQgPSAkKHRoaXMpLmhhc0NsYXNzKCdpbnZlcnNlJykgPyAhdGhpcy5jaGVja2VkIDogdGhpcy5jaGVja2VkO1xuXG4gICAgJGJpbGxpbmdGaWVsZHMuYXR0cignaGlkZGVuJywgY2hlY2tlZCk7XG4gICAgJG9wdGlvbmFsQmlsbGluZ2ZpZWxkc1xuICAgICAgICAuYXR0cigncmVxdWlyZWQnLCAhY2hlY2tlZClcbiAgICAgICAgLnByZXYoJ2xhYmVsJylcbiAgICAgICAgLnRvZ2dsZUNsYXNzKCdyZXF1aXJlZCcsICFjaGVja2VkKTtcbn0pLnRyaWdnZXIoJ2NoYW5nZScpOyIsImZ1bmN0aW9uIF9pbml0KCkge1xuICAkKFwiLnZpZGVvLWJsb2NrLWNvbnRhaW5lclwiKS5lYWNoKGZ1bmN0aW9uIGluaXRZb3V0dWJlVmlkZW8oKSB7XG4gICAgdmFyICR2aWRlb0Jsb2NrID0gJCh0aGlzKTtcbiAgICB2YXIgJHZpZGVvUGxheWVyID0gJHZpZGVvQmxvY2suZmluZChcIi52aWRlby1wbGF5ZXJcIik7XG4gICAgdmFyICR2aWRlb1RpdGxlID0gJHZpZGVvQmxvY2suZmluZChcIi52aWRlby10aXRsZVwiKTtcbiAgICBcbiAgICB2YXIgcGxheWVyID0gbmV3IFlULlBsYXllcigkdmlkZW9QbGF5ZXJbMF0uaWQsIHtcbiAgICAgIGhlaWdodDogXCI0ODBcIixcbiAgICAgIHdpZHRoOiBcIjY0MFwiLFxuICAgICAgdmlkZW9JZDogJHZpZGVvUGxheWVyLmRhdGEoXCJ2aWRlby1pZFwiKSxcbiAgICAgIHBsYXllclZhcnM6IHtcbiAgICAgICAgYXV0b3BsYXk6IDAsXG4gICAgICAgIGVuYWJsZWpzYXBpOiAxLFxuICAgICAgICBtb2Rlc3RicmFuZGluZzogMCxcbiAgICAgICAgc2hvd2luZm86IDAsXG4gICAgICAgIHJlbDogMFxuICAgICAgfSxcbiAgICAgIGV2ZW50czoge1xuICAgICAgICBvblJlYWR5OiBmdW5jdGlvbiBpbml0VGl0bGUoZSkge1xuICAgICAgICAgIHNldFRpdGxlKCR2aWRlb1RpdGxlLCBlLnRhcmdldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgICR2aWRlb0Jsb2NrLm9uKFwiY2xpY2tcIiwgXCIuanMtY2xpY2stdG8tcGxheVwiLCBmdW5jdGlvbiBwbGF5VmlkZW8oKSB7XG4gICAgICAkdmlkZW9CbG9jay5hZGRDbGFzcyhcInBsYXlpbmdcIik7XG4gICAgICBwbGF5ZXIucGxheVZpZGVvKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vLyBHZXQgdGl0bGUgZnJvbSB2aWRlbyBwbGF5ZXIgYW5kIHNldCBpdCBpbiB0aGUgdmlkZW8gdGl0bGUgZWxlbWVudFxuZnVuY3Rpb24gc2V0VGl0bGUoJGVsLCBwbGF5ZXIpIHtcbiAgJGVsLnRleHQocGxheWVyLmdldFZpZGVvRGF0YSgpLnRpdGxlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluaXQ6IF9pbml0XG59O1xuIiwiKGZ1bmN0aW9uIChkb2N1bWVudCwgJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gSU1QT1JUQU5UIC0gQ2hlY2tzIGlmIENTUyBoYXMgbG9hZGVkIGFuZCBzZXRzIGNvb2tpZVxuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvY2hlY2stY3JpdGljYWwtY3NzJyk7XG5cbiAgLy8gTG9jYWwgc2NyaXB0c1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2l0ZS9tZW51LXRvZ2dsZScpO1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2l0ZS9zZWFyY2gtY291cnNlJyk7XG4gIHJlcXVpcmUoJy4vY29tcG9uZW50cy9zaXRlL3NjaGVkdWxlJyk7XG4gIHJlcXVpcmUoJy4vY29tcG9uZW50cy9zaXRlL2dtYXBzLW1hcCcpO1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2l0ZS9lbnJvbGwtdG9nZXRoZXInKTtcbiAgcmVxdWlyZSgnLi9jb21wb25lbnRzL3VzZXIvcHJvZmlsZS1iaWxsaW5nLXRvZ2dsZScpO1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvY29uZmlybScpO1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2l0ZS90YWJsZS1kaXZpZGVyJyk7XG4gIHJlcXVpcmUoJy4vY29tcG9uZW50cy9zaXRlL3NlYXJjaC13aWRnZXQnKTtcbiAgcmVxdWlyZSgnLi9jb21wb25lbnRzL3NpdGUvdHJ1bmNhdGUtdGV4dCcpO1xuICByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2l0ZS90aW1lLWRpZmZlcmVuY2UnKTtcbiAgcmVxdWlyZSgnLi9jb21wb25lbnRzL3NpdGUvd3JhcHBlci1wYWRkaW5nJyk7XG4gIHJlcXVpcmUoJy4vY29tcG9uZW50cy9jb2xsYXBzaWJsZS1zZWN0aW9uJyk7XG5cbiAgLy8gWW91dHViZSBwbGF5ZXIgaW5pdFxuICB2YXIgeXRQbGF5ZXIgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMveW91dHViZS1wbGF5ZXInKTtcbiAgd2luZG93Lm9uWW91VHViZUlmcmFtZUFQSVJlYWR5ID0geXRQbGF5ZXIuaW5pdDtcblxuICAvLyBzdHVmZiB0b28gc21hbGwgdG8gaW5jbHVkZVxuICBpZiAoJCgnLnN0YXItcmF0aW5nJykubGVuZ3RoID4gMCkge1xuICAgICQoJy5zdGFyLXJhdGluZycpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KCQodGhpcykuZGF0YSgncmF0aW5nJykpICogMjA7XG4gICAgICB2YXIgbWV0ZXJXaWR0aCA9ICgkKHRoaXMpLmlubmVyV2lkdGgoKSAtIDIgKSAqIChwZXJjZW50YWdlIC8gMTAwKTtcbiAgICAgICQodGhpcylcbiAgICAgICAgLmZpbmQoJy5tZXRlcicpXG4gICAgICAgIC5jc3MoJ3dpZHRoJywgbWV0ZXJXaWR0aCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoJCgnLnNjcm9sbC1kb3duJykubGVuZ3RoID4gMCkge1xuICAgICQoJy5zY3JvbGwtZG93bicpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZShcbiAgICAgICAge1xuICAgICAgICAgIHNjcm9sbFRvcDogJCgnLmMtaGVybycpXG4gICAgICAgICAgICAubmV4dCgpXG4gICAgICAgICAgICAub2Zmc2V0KCkudG9wXG4gICAgICAgIH0sXG4gICAgICAgIDMwMFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmICgkKCcuc2VhcmNoLWJhcicpLmxlbmd0aCkge1xuICAgICQoJy5zZWFyY2gtYmFyJykub24oJ3N1Ym1pdCcsIGZ1bmN0aW9uIChlKSB7XG4gICAgICB2YXIgJGZvcm0gPSAkKHRoaXMpO1xuICAgICAgdmFyIHJvb3QgPSAkZm9ybS5maW5kKCcuZmllbGQtcm9vdCcpLnZhbCgpO1xuICAgICAgdmFyIG9ubGluZSA9ICQoJ1tuYW1lPVwiaXMtb25saW5lXCJdJykudmFsKCk7XG4gICAgICB2YXIgY291cnNlID0gJGZvcm0uZmluZCgnLmZpZWxkLWNvdXJzZScpLnZhbCgpO1xuICAgICAgdmFyIGxvYyA9ICRmb3JtLmZpbmQoJy5maWVsZC1sb2NhdGlvbicpLnZhbCgpO1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgXG4gICAgICBpZiAoJCh0aGlzKS5oYXNDbGFzcygnZm9yLWFsdGVybmF0aXZlcycpICYmIG9ubGluZSA9PT0gJ2ZhbHNlJykge1xuICAgICAgICBsb2NhdGlvbiA9ICc/Y291cnNlPScgKyBjb3Vyc2UgKyAnJmNpdHk9JyArIGxvYztcbiAgICAgIH0gZWxzZSBpZiAoJCh0aGlzKS5oYXNDbGFzcygnZm9yLWFsdGVybmF0aXZlcycpICYmIG9ubGluZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgIGxvY2F0aW9uID0gJz9jb3Vyc2U9JyArIGNvdXJzZSArICcmb25saW5lPXRydWUnO1xuICAgICAgfSBlbHNlIGlmIChyb290ICYmIGNvdXJzZSAmJiBsb2MpIHtcbiAgICAgICAgbG9jYXRpb24gPSByb290ICsgY291cnNlICsgJy8nICsgbG9jO1xuICAgICAgfSBlbHNlIGlmIChyb290ICYmIGxvYykge1xuICAgICAgICBsb2NhdGlvbiA9IHJvb3QgKyAnc3BhYW5zLWluLScgKyBsb2M7XG4gICAgICB9IGVsc2UgaWYgKHJvb3QgJiYgY291cnNlICYmIG9ubGluZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgIGxvY2F0aW9uID0gcm9vdCArIGNvdXJzZSArICcvb25saW5lJztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgICQoJy5qcy1zZWFyY2gtdG9nZ2xlJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgJCgnLnNlYXJjaC13cmFwcGVyJykudG9nZ2xlQ2xhc3MoJ2lzLW9wZW4nKTtcbiAgICAgICQoJy5zZWFyY2gtdG9nZ2xlJykudG9nZ2xlQ2xhc3MoJ2lzLW9wZW4nKTtcbiAgICAgICQodGhpcykudG9nZ2xlQ2xhc3MoJ2Fycm93LXJldmVyc2VkJyk7XG4gICAgfSk7XG4gIH1cblxuICAvKiBzdGlja3kgc2VhcmNoIHdpZGdldCAqL1xuICBjb25zdCBzZWFyY2hXaWRnZXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1tb2R1bGU9XCJzZWFyY2gtd2lkZ2V0XCJdOm5vdCgubm8tc3RpY2spJyk7XG5cbiAgaWYgKHNlYXJjaFdpZGdldCkge1xuICAgIGZ1bmN0aW9uIHRvZ2dsZVN0aWNreVNlYXJjaFdpZGdldCgpIHtcbiAgICAgIGxldCB3aWRnZXRCb3R0b207XG4gICAgICBjb25zdCBuZXh0RWxlbWVudCA9IHNlYXJjaFdpZGdldC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuXG4gICAgICB3aWRnZXRCb3R0b20gPSBuZXh0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgLSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUoc2VhcmNoV2lkZ2V0KS5tYXJnaW5Cb3R0b20pO1xuICAgICAgc2VhcmNoV2lkZ2V0LmNsYXNzTGlzdFt3aWRnZXRCb3R0b20gPCA0MCA/ICdhZGQnIDogJ3JlbW92ZSddKCdzdGlja3knKTtcbiAgICB9XG5cbiAgICB0b2dnbGVTdGlja3lTZWFyY2hXaWRnZXQoKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdG9nZ2xlU3RpY2t5U2VhcmNoV2lkZ2V0KVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0b2dnbGVTdGlja3lTZWFyY2hXaWRnZXQpXG4gIH1cblxuXG4gIGZ1bmN0aW9uIGlzT25saW5lQ2hlY2soKSB7XG4gICAgY29uc3QgbG9jYXRpb25TZWxlY3RvciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPVwibG9jYXRpb25cIl0nKTtcbiAgICBpZiAoIWxvY2F0aW9uU2VsZWN0b3IpIHJldHVybjtcbiAgICBjb25zdCBmb3JtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtbW9kdWxlPVwic2VhcmNoLXdpZGdldFwiXScpO1xuICAgIGNvbnN0IGlzT25saW5lVmFsdWUgPSAkKCdbbmFtZT1cImlzLW9ubGluZVwiXScpLnZhbCgpO1xuICAgIGNvbnN0IGlzT25saW5lID0gaXNPbmxpbmVWYWx1ZSA9PT0gJ3RydWUnIHx8IGlzT25saW5lVmFsdWUgPT09ICcnO1xuXG4gICAgJCgnLmxvY2F0aW9uLWNvbnRhaW5lcicpLmF0dHIoJ2hpZGRlbicsIGlzT25saW5lKTtcbiAgICBsb2NhdGlvblNlbGVjdG9yLnJlcXVpcmVkID0gIWlzT25saW5lO1xuICAgIGlmIChpc09ubGluZSkgbG9jYXRpb25TZWxlY3Rvci52YWx1ZSA9ICcnO1xuICAgIGZvcm0uY2xhc3NMaXN0W2lzT25saW5lID8gJ2FkZCcgOiAncmVtb3ZlJ10oJ3NlYXJjaC1iYXItLW9ubGluZScpO1xuICAgIGZvcm0uY2xhc3NMaXN0W2lzT25saW5lID8gJ3JlbW92ZScgOiAnYWRkJ10oJ3NlYXJjaC1iYXItLW9mZmxpbmUnKTtcbiAgfVxuXG4gICQoJ1tuYW1lPVwiaXMtb25saW5lXCJdJykub24oJ2NoYW5nZScsIGlzT25saW5lQ2hlY2spO1xuICBzZXRUaW1lb3V0KGlzT25saW5lQ2hlY2ssIDEwKTtcblxuICBpZiAoJCgnLmFsbW9zdC1mdWxsJykubGVuZ3RoKSB7XG4gICAgJCgnKjpub3QoLmFsbW9zdC1mdWxsLmljb24pJykub24oJ2NsaWNrIG1vdXNlb3ZlciBmb2N1cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICQoJy5hbG1vc3QtZnVsbC5pY29uJykuYmx1cigpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKCQoJy5wYXltZW50LXNlbGVjdGlvbl9fYnV0dG9uJykubGVuZ3RoKSB7XG4gICAgdmFyICRmb3JtID0gJCgnW25hbWU9XCJwYXltZW50X21ldGhvZF9zZWxlY3Rpb25cIl0nKTtcbiAgICB2YXIgJGJhbmtTZWxlY3QgPSAkKCcjcGF5bWVudF9tZXRob2Rfc2VsZWN0aW9uX2lzc3VlcmlkJyk7XG4gICAgdmFyICRzZWxlY3RSb3cgPSAkYmFua1NlbGVjdC5jbG9zZXN0KCcuZm9ybS1ncm91cCcpO1xuXG4gICAgJCgnLnBheW1lbnQtc2VsZWN0aW9uX19idXR0b24nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoJCh0aGlzKS5oYXNDbGFzcygncGF5bWVudC1zZWxlY3Rpb25fX2J1dHRvbi0taWRlYWwnKSkge1xuICAgICAgICAkYmFua1NlbGVjdC5hdHRyKCdyZXF1aXJlZCcsICdyZXF1aXJlZCcpO1xuICAgICAgICAkc2VsZWN0Um93LnNsaWRlRG93bigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJGJhbmtTZWxlY3QucmVtb3ZlQXR0cigncmVxdWlyZWQnKTtcbiAgICAgICAgJHNlbGVjdFJvdy5zbGlkZVVwKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoJCgnLmNvb2tpZS1iYXInKS5sZW5ndGgpIHtcbiAgICB2YXIgJGJhciA9ICQoJy5jb29raWUtYmFyJyk7XG4gICAgdmFyICRidXR0b25zID0gJCgnLmpzLWNvb2tpZS1idXR0b24nKTtcblxuICAgIGlmICghLy4qYWxsb3dUcmFja2luZ0Nvb2tpZXMuKi8udGVzdChkb2N1bWVudC5jb29raWUpKSB7XG4gICAgICAkYmFyLmFkZENsYXNzKCduZWVkcy1wZXJtaXNzaW9uJyk7XG4gICAgfVxuXG4gICAgJGJ1dHRvbnMub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGRvY3VtZW50LmNvb2tpZSA9XG4gICAgICAgICdhbGxvd1RyYWNraW5nQ29va2llcz0nICtcbiAgICAgICAgJCh0aGlzKS52YWwoKSArXG4gICAgICAgICc7IGV4cGlyZXM9RnJpLCAzMSBEZWMgOTk5OSAyMzo1OTo1OSBHTVQ7IHBhdGg9Lyc7XG4gICAgICAkYmFyLnJlbW92ZUNsYXNzKCduZWVkcy1wZXJtaXNzaW9uJyk7XG4gICAgfSk7XG4gIH1cblxuICAkKCcuanMtcmVzZXQtdHJhY2tpbmctY29va2llcycpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGRvY3VtZW50LmNvb2tpZSA9XG4gICAgICAnYWxsb3dUcmFja2luZ0Nvb2tpZXM9OyBleHBpcmVzPVRodSwgMDEgSmFuIDE5NzAgMDA6MDA6MDAgR01UOyBwYXRoPS8nO1xuICAgICQoJy5jb29raWUtYmFyJykuYWRkQ2xhc3MoJ25lZWRzLXBlcm1pc3Npb24nKTtcbiAgfSk7XG5cbiAgLy8gcmVhZCBtb3JlIHR3ZWFrc1xuICBpZiAoJCgnI3JlYWQtbW9yZS1jaGVja2JveCcpLmxlbmd0aCkge1xuICAgIHZhciBmaXJzdFRpdGxlID0gJCgnbWFpbiBoMicpLmZpcnN0KClbMF07XG5cbiAgICAkKCcjcmVhZC1tb3JlLWNoZWNrYm94Jykub24oJ2NoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghJCh0aGlzKVswXS5jaGVja2VkKSB7XG4gICAgICAgIHZhciB0aXRsZUJCID0gZmlyc3RUaXRsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgaWYgKHRpdGxlQkIudG9wIDwgdGl0bGVCQi5oZWlnaHQpIHtcbiAgICAgICAgICBmaXJzdFRpdGxlLnNjcm9sbEludG9WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGxvY2F0aW9uSW5mb1RvZ2dsZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtb3JlLWluZm9fX2lucHV0Jyk7XG4gIGlmIChsb2NhdGlvbkluZm9Ub2dnbGUpIHtcbiAgICBsb2NhdGlvbkluZm9Ub2dnbGUuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGxvY2F0aW9uSW5mb1RvZ2dsZS5jaGVja2VkICYmIHR5cGVvZiB3aW5kb3cuaW5pdE1hcCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbG9jYXRpb25JbmZvVG9nZ2xlLmRhdGFzZXQuaW5pdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgd2luZG93LmluaXRNYXAoKTtcbiAgICAgICAgbG9jYXRpb25JbmZvVG9nZ2xlLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1pbml0Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAkKCcuY29weScpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZvY3VzKCk7XG4gICAgdGhpcy5zZWxlY3QoKTtcbiAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgnY29weScpO1xuICAgICQoJy5jb3B5LXN1Y2Nlc3MnKS5yZW1vdmVBdHRyKCdoaWRkZW4nKTtcbiAgfSlcblxuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAkKCcuanMtcG9wdXAnKS5jc3MoeydkaXNwbGF5JzogJ2Jsb2NrJ30pO1xuICB9LCA1MDAwKTtcblxuICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICBjb25zdCBhbGVydFdhc0Nsb3NlZCA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oXCJhbGVydC1ub3RpZmljYXRpb25cIik7XG4gICAgaWYgKGFsZXJ0V2FzQ2xvc2VkKSByZXR1cm47XG4gICAgJCgnLmpzLW5vdGlmaWNhdGlvbicpLmNzcygnZGlzcGxheScsICdmbGV4JylcbiAgfSwgMTAwMCk7XG4gIFxuICAkKCcuanMtY2xvc2UnKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgIHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGUuY3VycmVudFRhcmdldC5pZCwgXCJjbG9zZWRcIik7XG4gICAgJCgnLm5vdGlmaWNhdGlvbi1jb250YWluZXInKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICB9KTtcblxuICAvLyBGaXJzdCB3ZSBnZXQgdGhlIHZpZXdwb3J0IGhlaWdodCBhbmQgd2UgbXVsdGlwbGUgaXQgYnkgMSUgdG8gZ2V0IGEgdmFsdWUgZm9yIGEgdmggdW5pdFxuICBsZXQgdmggPSB3aW5kb3cuaW5uZXJIZWlnaHQgKiAwLjAxO1xuICAvLyBUaGVuIHdlIHNldCB0aGUgdmFsdWUgaW4gdGhlIC0tdmggY3VzdG9tIHByb3BlcnR5IHRvIHRoZSByb290IG9mIHRoZSBkb2N1bWVudFxuICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tdmgnLCBgJHt2aH1weGApO1xuXG4gIC8vIFdlIGxpc3RlbiB0byB0aGUgcmVzaXplIGV2ZW50XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB7XG4gICAgLy8gV2UgZXhlY3V0ZSB0aGUgc2FtZSBzY3JpcHQgYXMgYmVmb3JlXG4gICAgbGV0IHZoID0gd2luZG93LmlubmVySGVpZ2h0ICogMC4wMTtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tdmgnLCBgJHt2aH1weGApO1xuICB9KTtcblxufSkoZG9jdW1lbnQsIGpRdWVyeSk7XG4iXX0="}