UNPKG

ems-web-app-utils

Version:

Utility methods that are intended for use in Angular.io [web applications developed by Educational Media Solutions](https://github.com/spencech/ems-web-app-template)

281 lines 37.1 kB
import { NgModule } from '@angular/core'; import * as _ from 'underscore'; import * as i0 from "@angular/core"; export function alphabetize(...parameters) { if (typeof parameters[0] === 'string') { // if this method is supplied as a callback to Array.sort const a = parameters[0]; const b = parameters[1]; if (a > b) return 1; if (a < b) return -1; return 0; } else { // if we're sorting a list with a supplied key to alphabetize const list = parameters[0]; const property = parameters[1]; list.sort((a, b) => { if (a[property] > b[property]) return 1; if (a[property] < b[property]) return -1; return 0; }); return list; } } export function clone(obj) { if (obj === null || obj === undefined) return obj; return JSON.parse(JSON.stringify(obj)); } export function convertToEST(date) { const gmtDate = new Date(date + " GMT"); const options = { timeZone: 'America/New_York', year: "numeric", month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true }; const formatter = new Intl.DateTimeFormat('en-US', options); return formatter.format(gmtDate); } export function dateStrings(date) { date = date || new Date(); return { year: date.getFullYear(), month: (date.getMonth() + 1).toString().padStart(2, '0'), date: date.getDate().toString().padStart(2, '0'), time: `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`, seconds: date.getSeconds().toString().padStart(2, '0'), }; } export function delay(method, ms = 0) { return window.setTimeout(method, ms); } export function download(content, name, extension = 'csv') { const blob = new Blob([content]); name = kebab(name); if (window.navigator.msSaveOrOpenBlob) window.navigator.msSaveBlob(blob, `${name}.${extension}`); else { const a = window.document.createElement('a'); a.href = window.URL.createObjectURL(blob); a.download = `${name}.${extension}`; document.body.appendChild(a); a.click(); document.body.removeChild(a); } } export function empty(e) { return falsy(e); } export function enumKeys(obj) { return Object.keys(obj).filter(k => Number.isNaN(+k)); } export function enumValues(obj) { const output = []; for (const value of enumKeys(obj)) { output.push(obj[value]); } return output; } export function falsy(e) { if (typeof e === 'string' && trim(e).match(/^false$/i)) return true; if (typeof e === 'string') return _.isEmpty(e.replace(/\s+/gim, '')); if (typeof e === 'boolean') return e === false; if (!isNaN(parseInt(e, 10))) return e === 0; return _.isEmpty(e); } export function focus(selector) { const element = document.querySelector(selector); if (!element || !element.focus) return 0; return delay(() => element.focus()); } export function getLargestRemainder(values, desiredSum) { let sum = 0; let valueParts = values.map((value, index) => { const integerValue = value || 0; sum += integerValue; return { integer: integerValue, decimal: value % 1, originalIndex: index, }; }); if (sum !== desiredSum && sum) { valueParts = valueParts.sort((a, b) => b.decimal - a.decimal); const diff = desiredSum - sum; let i = 0; while (i < diff) { valueParts[i].integer++; i++; } } return valueParts.sort((a, b) => a.originalIndex - b.originalIndex).map((p) => p.integer); } export function getparams(requestedProperty) { const vars = {}; const parts = window.location.href.replace(/[?&#]+([^=&]+)=([^&]*)/gi, ((m, key, value) => { vars[key] = value; })); for (const prop in vars) { if (vars[prop].toLowerCase() === 'true') vars[prop] = true; else if (vars[prop].toLowerCase() === 'false') vars[prop] = false; else if (!isNaN(parseFloat(vars[prop])) && !vars[prop].match(/[^0-9]+/gim)) vars[prop] = parseFloat(vars[prop]); } if (requestedProperty) return vars[requestedProperty]; return vars; } export function isset(e) { return truthy(e); } export function kebab(e) { if (_.isEmpty(e)) return e; return e.toLowerCase().replace(/\s+/gim, '-').replace(/_/g, '-').replace(/-+/g, '-'); } export function paginate(method, offset, limit, key, output = [], callback, prevResolve) { return new Promise(async (resolve, reject) => { let response; try { response = await method(offset, limit); } catch (e) { reject(e); } output = output.concat(response[key]); if (callback) callback(output, response[key]); if (response.nextPage) { await paginate(method, response.nextPage, limit, key, output, callback, prevResolve ?? resolve); } else { (prevResolve ?? resolve)(output); } }); } export function prepareSearchString(value) { if (!value) return ""; return value.toLowerCase().replace(/\s+/gim, ""); } export function replaceItem(array, item, key = 'id', position = 'current') { const lookup = {}; lookup[key] = item[key]; const oldItem = _.findWhere(array, lookup); if (!oldItem) { array.unshift(item); return item; } const index = array.indexOf(oldItem); if (position === 'first') { array.splice(index, 1); array.unshift(item); } else { array.splice(index, 1, item); } return item; } export function sleep(duration = 0) { return new Promise((resolve) => { delay(() => resolve(duration), duration); }); } export function snakecase(e) { if (_.isEmpty(e)) return e; return e.toLowerCase().replace(/\s+/gim, '_').replace(/-/g, '_').replace(/_+/g, '_'); } export function tick(returnValue) { return new Promise((resolve, reject) => { delay(() => resolve(returnValue)); }); } export function timestamp(date, includeTime = true) { const info = dateStrings(date); const time = ` ${info.time}:${info.seconds}`; return `${info.year}-${info.month}-${info.date}${includeTime ? time : ''}`; } export function trace(...parameters) { if (!getparams().debug) return; for (let i = 0, count = parameters.length; i < count; i++) { // tslint:disable-next-line console.log(parameters[i]); } } export function trim(e) { if (_.isEmpty(e)) return e; return e.replace(/^\s+/, '').replace(/\s+$/, ''); } export function truthy(e) { return !falsy(e); } export function validateEmail(email) { if (!email) return null; return String(email) .toLowerCase() .match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); } export function viewport(el, percentVisible = 100) { const rect = el.getBoundingClientRect(); const windowHeight = window.innerHeight || document.documentElement.clientHeight; return !(Math.floor(100 - ((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100) < percentVisible || Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible); } export function password(length) { const upperCaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const lowerCaseChars = 'abcdefghijklmnopqrstuvwxyz'; const numbers = '0123456789'; const specialChars = '!@#$%^&*()-_=+[]|;:,.?'; length = length ?? 8; // Ensure each type of character appears at least once const password = [ upperCaseChars[Math.floor(Math.random() * upperCaseChars.length)], lowerCaseChars[Math.floor(Math.random() * lowerCaseChars.length)], numbers[Math.floor(Math.random() * numbers.length)], specialChars[Math.floor(Math.random() * specialChars.length)], // One special char ]; // Pool of all allowed characters for remaining password characters const allChars = upperCaseChars + lowerCaseChars + numbers + specialChars; // Fill the rest of the password length (64 characters) with random characters for (let i = password.length; i < length; i++) { password.push(allChars[Math.floor(Math.random() * allChars.length)]); } // Shuffle the password array to ensure randomness, then join it into a string const randomPassword = password.sort(() => Math.random() - 0.5).join(''); return randomPassword; } export class UtilsModule { } UtilsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UtilsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); UtilsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UtilsModule }); UtilsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UtilsModule, imports: [[]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UtilsModule, decorators: [{ type: NgModule, args: [{ declarations: [], imports: [], exports: [] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi91dGlscy5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6QyxPQUFPLEtBQUssQ0FBQyxNQUFNLFlBQVksQ0FBQzs7QUFFaEMsTUFBTSxVQUFVLFdBQVcsQ0FBQyxHQUFHLFVBQWlCO0lBQzlDLElBQUksT0FBTyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFO1FBQ3JDLHlEQUF5RDtRQUN6RCxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUM7WUFBRSxPQUFPLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNyQixPQUFPLENBQUMsQ0FBQztLQUNWO1NBQU07UUFDTCw2REFBNkQ7UUFDN0QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUM7Z0JBQUUsT0FBTyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQztnQkFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQztLQUNiO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxLQUFLLENBQUMsR0FBUTtJQUM1QixJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLFNBQVM7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUNsRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLElBQVk7SUFDdkMsTUFBTSxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sT0FBTyxHQUErQjtRQUMxQyxRQUFRLEVBQUUsa0JBQWtCO1FBQzVCLElBQUksRUFBRSxTQUFTO1FBQ2YsS0FBSyxFQUFFLFNBQVM7UUFDaEIsR0FBRyxFQUFFLFNBQVM7UUFDZCxJQUFJLEVBQUUsU0FBUztRQUNmLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxJQUFJO0tBQ2IsQ0FBQztJQUVGLE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUQsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLElBQVc7SUFDckMsSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDO0lBQzFCLE9BQU87UUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRTtRQUN4QixLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7UUFDeEQsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztRQUNoRCxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRTtRQUN2RyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO0tBQ3ZELENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLEtBQUssQ0FBQyxNQUFrQixFQUFFLEtBQWEsQ0FBQztJQUN0RCxPQUFPLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFFRCxNQUFNLFVBQVUsUUFBUSxDQUFDLE9BQWUsRUFBRSxJQUFZLEVBQUUsWUFBb0IsS0FBSztJQUMvRSxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDakMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVuQixJQUFLLE1BQU0sQ0FBQyxTQUFpQixDQUFDLGdCQUFnQjtRQUFHLE1BQU0sQ0FBQyxTQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQztTQUM5RztRQUNILE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxHQUFHLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNwQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDVixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM5QjtBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsS0FBSyxDQUFDLENBQU07SUFDMUIsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRLENBQWdELEdBQU07SUFDMUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBUSxDQUFDO0FBQ2pFLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFnRCxHQUFNO0lBQzVFLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQTtJQUNqQixLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNqQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0tBQ3pCO0lBQ0QsT0FBTyxNQUFlLENBQUM7QUFDM0IsQ0FBQztBQUVELE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBTTtJQUMxQixJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3BFLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUTtRQUFFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLElBQUksT0FBTyxDQUFDLEtBQUssU0FBUztRQUFFLE9BQU8sQ0FBQyxLQUFLLEtBQUssQ0FBQztJQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCxNQUFNLFVBQVUsS0FBSyxDQUFDLFFBQWdCO0lBQ3BDLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFnQixDQUFDO0lBQ2hFLElBQUcsQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztRQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsTUFBZ0IsRUFBRSxVQUFrQjtJQUN0RSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDWixJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBYSxFQUFFLEtBQWEsRUFBRSxFQUFFO1FBQzNELE1BQU0sWUFBWSxHQUFHLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDaEMsR0FBRyxJQUFJLFlBQVksQ0FBQztRQUNwQixPQUFPO1lBQ0wsT0FBTyxFQUFFLFlBQVk7WUFDckIsT0FBTyxFQUFFLEtBQUssR0FBRyxDQUFDO1lBQ2xCLGFBQWEsRUFBRSxLQUFLO1NBQ3JCLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksR0FBRyxLQUFLLFVBQVUsSUFBSSxHQUFHLEVBQUU7UUFDN0IsVUFBVSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUU5RCxNQUFNLElBQUksR0FBRyxVQUFVLEdBQUcsR0FBRyxDQUFDO1FBQzlCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVWLE9BQU8sQ0FBQyxHQUFHLElBQUksRUFBRTtZQUNmLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN4QixDQUFDLEVBQUUsQ0FBQztTQUNMO0tBQ0Y7SUFFRCxPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM1RixDQUFDO0FBRUQsTUFBTSxVQUFVLFNBQVMsQ0FBQyxpQkFBMEI7SUFDbEQsTUFBTSxJQUFJLEdBQUcsRUFBUyxDQUFDO0lBQ3ZCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsQ0FBTSxFQUFFLEdBQVcsRUFBRSxLQUFVLEVBQUUsRUFBRTtRQUMxRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLENBQUMsQ0FBUSxDQUFDLENBQUM7SUFFWCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksRUFBRTtRQUN2QixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxNQUFNO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQzthQUN0RCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQzthQUM3RCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0tBQ2pIO0lBRUQsSUFBSSxpQkFBaUI7UUFBRSxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBTTtJQUMxQixPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBTSxVQUFVLEtBQUssQ0FBQyxDQUFTO0lBQzdCLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUMzQixPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2RixDQUFDO0FBRUQsTUFBTSxVQUFVLFFBQVEsQ0FBQyxNQUE4QyxFQUFFLE1BQWMsRUFBRSxLQUFhLEVBQUUsR0FBVyxFQUFFLFNBQWdCLEVBQUUsRUFBRSxRQUFrRCxFQUFFLFdBQW1DO0lBQzVOLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLE9BQThCLEVBQUUsTUFBNkIsRUFBRSxFQUFFO1FBQ3pGLElBQUksUUFBUSxDQUFDO1FBQ2IsSUFBSTtZQUNGLFFBQVEsR0FBRyxNQUFNLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDeEM7UUFBQyxPQUFNLENBQU0sRUFBRTtZQUNkLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNYO1FBRUQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFdEMsSUFBRyxRQUFRO1lBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUU3QyxJQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUU7WUFDcEIsTUFBTSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQTtTQUNoRzthQUFNO1lBQ0wsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDbEM7SUFFSCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsS0FBYTtJQUM3QyxJQUFHLENBQUMsS0FBSztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBWSxFQUFFLElBQVMsRUFBRSxNQUFjLElBQUksRUFBRSxXQUFtQixTQUFTO0lBQ25HLE1BQU0sTUFBTSxHQUFHLEVBQVMsQ0FBQztJQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXhCLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRTNDLElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDWixLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXJDLElBQUksUUFBUSxLQUFLLE9BQU8sRUFBRTtRQUN4QixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2QixLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3JCO1NBQU07UUFDTCxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDOUI7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxNQUFNLFVBQVUsS0FBSyxDQUFDLFdBQW1CLENBQUM7SUFDeEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQTZCLEVBQUUsRUFBRTtRQUNuRCxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzNDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsQ0FBUztJQUNqQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQUUsT0FBTyxDQUFDLENBQUM7SUFDM0IsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDdkYsQ0FBQztBQUVELE1BQU0sVUFBVSxJQUFJLENBQUMsV0FBaUI7SUFDcEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQWdDLEVBQUUsTUFBK0IsRUFBRSxFQUFFO1FBQ3ZGLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxNQUFNLFVBQVUsU0FBUyxDQUFDLElBQVcsRUFBRSxjQUF1QixJQUFJO0lBQ2hFLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzdDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7QUFDN0UsQ0FBQztBQUVELE1BQU0sVUFBVSxLQUFLLENBQUMsR0FBRyxVQUFpQjtJQUN4QyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsS0FBSztRQUFFLE9BQU87SUFFL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN6RCwyQkFBMkI7UUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM1QjtBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsSUFBSSxDQUFDLENBQVM7SUFDNUIsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzNCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsTUFBTSxVQUFVLE1BQU0sQ0FBQyxDQUFNO0lBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQUVELE1BQU0sVUFBVSxhQUFhLENBQUMsS0FBb0I7SUFDaEQsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLElBQUksQ0FBQztJQUV4QixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDakIsV0FBVyxFQUFFO1NBQ2IsS0FBSyxDQUNKLHVKQUF1SixDQUN4SixDQUFDO0FBQ04sQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRLENBQUMsRUFBZSxFQUFFLGlCQUF5QixHQUFHO0lBQ3BFLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ3hDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUM7SUFFakYsT0FBTyxDQUFDLENBQ04sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsY0FBYztRQUMvRixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsY0FBYyxDQUN0RixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRLENBQUMsTUFBYztJQUNyQyxNQUFNLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQztJQUNwRCxNQUFNLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQztJQUNwRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUM7SUFDN0IsTUFBTSxZQUFZLEdBQUcsd0JBQXdCLENBQUM7SUFDOUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUM7SUFFckIsc0RBQXNEO0lBQ3RELE1BQU0sUUFBUSxHQUFHO1FBQ2YsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRSxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pFLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkQsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLG1CQUFtQjtLQUNuRixDQUFDO0lBRUYsbUVBQW1FO0lBQ25FLE1BQU0sUUFBUSxHQUFHLGNBQWMsR0FBRyxjQUFjLEdBQUcsT0FBTyxHQUFHLFlBQVksQ0FBQztJQUUxRSw4RUFBOEU7SUFDOUUsS0FBSyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDN0MsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN0RTtJQUVELDhFQUE4RTtJQUM5RSxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekUsT0FBTyxjQUFjLENBQUM7QUFDeEIsQ0FBQztBQVlELE1BQU0sT0FBTyxXQUFXOzt3R0FBWCxXQUFXO3lHQUFYLFdBQVc7eUdBQVgsV0FBVyxZQUxiLEVBQ1I7MkZBSVUsV0FBVztrQkFSdkIsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUUsRUFDYjtvQkFDRCxPQUFPLEVBQUUsRUFDUjtvQkFDRCxPQUFPLEVBQUUsRUFDUjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVdGlsc0NvbXBvbmVudCB9IGZyb20gJy4vdXRpbHMuY29tcG9uZW50JztcbmltcG9ydCAqIGFzIF8gZnJvbSAndW5kZXJzY29yZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhbHBoYWJldGl6ZSguLi5wYXJhbWV0ZXJzOiBhbnlbXSk6IGFueSB7XG4gIGlmICh0eXBlb2YgcGFyYW1ldGVyc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBpZiB0aGlzIG1ldGhvZCBpcyBzdXBwbGllZCBhcyBhIGNhbGxiYWNrIHRvIEFycmF5LnNvcnRcbiAgICBjb25zdCBhID0gcGFyYW1ldGVyc1swXTtcbiAgICBjb25zdCBiID0gcGFyYW1ldGVyc1sxXTtcbiAgICBpZiAoYSA+IGIpIHJldHVybiAxO1xuICAgIGlmIChhIDwgYikgcmV0dXJuIC0xO1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIC8vIGlmIHdlJ3JlIHNvcnRpbmcgYSBsaXN0IHdpdGggYSBzdXBwbGllZCBrZXkgdG8gYWxwaGFiZXRpemVcbiAgICBjb25zdCBsaXN0ID0gcGFyYW1ldGVyc1swXTtcbiAgICBjb25zdCBwcm9wZXJ0eSA9IHBhcmFtZXRlcnNbMV07XG4gICAgbGlzdC5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xuICAgICAgaWYgKGFbcHJvcGVydHldID4gYltwcm9wZXJ0eV0pIHJldHVybiAxO1xuICAgICAgaWYgKGFbcHJvcGVydHldIDwgYltwcm9wZXJ0eV0pIHJldHVybiAtMTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0pO1xuICAgIHJldHVybiBsaXN0O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShvYmo6IGFueSk6IGFueSB7XG4gIGlmIChvYmogPT09IG51bGwgfHwgb2JqID09PSB1bmRlZmluZWQpIHJldHVybiBvYmo7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFRvRVNUKGRhdGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGdtdERhdGUgPSBuZXcgRGF0ZShkYXRlICsgXCIgR01UXCIpO1xuICBjb25zdCBvcHRpb25zOiBJbnRsLkRhdGVUaW1lRm9ybWF0T3B0aW9ucyA9IHtcbiAgICB0aW1lWm9uZTogJ0FtZXJpY2EvTmV3X1lvcmsnLFxuICAgIHllYXI6IFwibnVtZXJpY1wiLFxuICAgIG1vbnRoOiAnbnVtZXJpYycsXG4gICAgZGF5OiAnbnVtZXJpYycsXG4gICAgaG91cjogJ251bWVyaWMnLFxuICAgIG1pbnV0ZTogJ251bWVyaWMnLFxuICAgIHNlY29uZDogJ251bWVyaWMnLFxuICAgIGhvdXIxMjogdHJ1ZVxuICB9O1xuICBcbiAgY29uc3QgZm9ybWF0dGVyID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoJ2VuLVVTJywgb3B0aW9ucyk7XG4gIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KGdtdERhdGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGF0ZVN0cmluZ3MoZGF0ZT86IERhdGUpIHtcbiAgZGF0ZSA9IGRhdGUgfHwgbmV3IERhdGUoKTtcbiAgcmV0dXJuIHtcbiAgICB5ZWFyOiBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgbW9udGg6IChkYXRlLmdldE1vbnRoKCkgKyAxKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyksXG4gICAgZGF0ZTogZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpLFxuICAgIHRpbWU6IGAke2RhdGUuZ2V0SG91cnMoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyl9OiR7ZGF0ZS5nZXRNaW51dGVzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpfWAsXG4gICAgc2Vjb25kczogZGF0ZS5nZXRTZWNvbmRzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVsYXkobWV0aG9kOiAoKSA9PiB2b2lkLCBtczogbnVtYmVyID0gMCk6IG51bWJlciB7XG4gIHJldHVybiB3aW5kb3cuc2V0VGltZW91dChtZXRob2QsIG1zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRvd25sb2FkKGNvbnRlbnQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCBleHRlbnNpb246IHN0cmluZyA9ICdjc3YnKSB7XG4gIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbY29udGVudF0pO1xuICBuYW1lID0ga2ViYWIobmFtZSk7XG5cbiAgaWYgKCh3aW5kb3cubmF2aWdhdG9yIGFzIGFueSkubXNTYXZlT3JPcGVuQmxvYikgKHdpbmRvdy5uYXZpZ2F0b3IgYXMgYW55KS5tc1NhdmVCbG9iKGJsb2IsIGAke25hbWV9LiR7ZXh0ZW5zaW9ufWApO1xuICBlbHNlIHtcbiAgICBjb25zdCBhID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBhLmhyZWYgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBhLmRvd25sb2FkID0gYCR7bmFtZX0uJHtleHRlbnNpb259YDtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xuICAgIGEuY2xpY2soKTtcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbXB0eShlOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIGZhbHN5KGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW51bUtleXM8TyBleHRlbmRzIG9iamVjdCwgSyBleHRlbmRzIGtleW9mIE8gPSBrZXlvZiBPPihvYmo6IE8pOiBLW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvYmopLmZpbHRlcihrID0+IE51bWJlci5pc05hTigraykpIGFzIEtbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVudW1WYWx1ZXM8TyBleHRlbmRzIG9iamVjdCwgSyBleHRlbmRzIGtleW9mIE8gPSBrZXlvZiBPPihvYmo6IE8pOiBhbnlbXSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gW11cbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGVudW1LZXlzKG9iaikpIHtcbiAgICAgIG91dHB1dC5wdXNoKG9ialt2YWx1ZV0pOyAgICBcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dCBhcyBhbnlbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZhbHN5KGU6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnICYmIHRyaW0oZSkubWF0Y2goL15mYWxzZSQvaSkpIHJldHVybiB0cnVlO1xuICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSByZXR1cm4gXy5pc0VtcHR5KGUucmVwbGFjZSgvXFxzKy9naW0sICcnKSk7XG4gIGlmICh0eXBlb2YgZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gZSA9PT0gZmFsc2U7XG4gIGlmICghaXNOYU4ocGFyc2VJbnQoZSwgMTApKSkgcmV0dXJuIGUgPT09IDA7XG4gIHJldHVybiBfLmlzRW1wdHkoZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb2N1cyhzZWxlY3Rvcjogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpIGFzIEhUTUxFbGVtZW50O1xuICBpZighZWxlbWVudCB8fCAhZWxlbWVudC5mb2N1cykgcmV0dXJuIDA7XG4gIHJldHVybiBkZWxheSgoKSA9PiBlbGVtZW50LmZvY3VzKCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGFyZ2VzdFJlbWFpbmRlcih2YWx1ZXM6IG51bWJlcltdLCBkZXNpcmVkU3VtOiBudW1iZXIpIHtcbiAgbGV0IHN1bSA9IDA7XG4gIGxldCB2YWx1ZVBhcnRzID0gdmFsdWVzLm1hcCgodmFsdWU6IG51bWJlciwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IGludGVnZXJWYWx1ZSA9IHZhbHVlIHx8IDA7XG4gICAgc3VtICs9IGludGVnZXJWYWx1ZTtcbiAgICByZXR1cm4ge1xuICAgICAgaW50ZWdlcjogaW50ZWdlclZhbHVlLFxuICAgICAgZGVjaW1hbDogdmFsdWUgJSAxLFxuICAgICAgb3JpZ2luYWxJbmRleDogaW5kZXgsXG4gICAgfTtcbiAgfSk7XG5cbiAgaWYgKHN1bSAhPT0gZGVzaXJlZFN1bSAmJiBzdW0pIHtcbiAgICB2YWx1ZVBhcnRzID0gdmFsdWVQYXJ0cy5zb3J0KChhLCBiKSA9PiBiLmRlY2ltYWwgLSBhLmRlY2ltYWwpO1xuXG4gICAgY29uc3QgZGlmZiA9IGRlc2lyZWRTdW0gLSBzdW07XG4gICAgbGV0IGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBkaWZmKSB7XG4gICAgICB2YWx1ZVBhcnRzW2ldLmludGVnZXIrKztcbiAgICAgIGkrKztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsdWVQYXJ0cy5zb3J0KChhLCBiKSA9PiBhLm9yaWdpbmFsSW5kZXggLSBiLm9yaWdpbmFsSW5kZXgpLm1hcCgocCkgPT4gcC5pbnRlZ2VyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldHBhcmFtcyhyZXF1ZXN0ZWRQcm9wZXJ0eT86IHN0cmluZyk6IGFueSB7XG4gIGNvbnN0IHZhcnMgPSB7fSBhcyBhbnk7XG4gIGNvbnN0IHBhcnRzID0gd2luZG93LmxvY2F0aW9uLmhyZWYucmVwbGFjZSgvWz8mI10rKFtePSZdKyk9KFteJl0qKS9naSwgKChtOiBhbnksIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSA9PiB7XG4gICAgdmFyc1trZXldID0gdmFsdWU7XG4gIH0pIGFzIGFueSk7XG5cbiAgZm9yIChjb25zdCBwcm9wIGluIHZhcnMpIHtcbiAgICBpZiAodmFyc1twcm9wXS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScpIHZhcnNbcHJvcF0gPSB0cnVlO1xuICAgIGVsc2UgaWYgKHZhcnNbcHJvcF0udG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJykgdmFyc1twcm9wXSA9IGZhbHNlO1xuICAgIGVsc2UgaWYgKCFpc05hTihwYXJzZUZsb2F0KHZhcnNbcHJvcF0pKSAmJiAhdmFyc1twcm9wXS5tYXRjaCgvW14wLTldKy9naW0pKSB2YXJzW3Byb3BdID0gcGFyc2VGbG9hdCh2YXJzW3Byb3BdKTtcbiAgfVxuXG4gIGlmIChyZXF1ZXN0ZWRQcm9wZXJ0eSkgcmV0dXJuIHZhcnNbcmVxdWVzdGVkUHJvcGVydHldO1xuICByZXR1cm4gdmFycztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzc2V0KGU6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHJ1dGh5KGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24ga2ViYWIoZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKF8uaXNFbXB0eShlKSkgcmV0dXJuIGU7XG4gIHJldHVybiBlLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxzKy9naW0sICctJykucmVwbGFjZSgvXy9nLCAnLScpLnJlcGxhY2UoLy0rL2csICctJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYWdpbmF0ZShtZXRob2Q6IChvZmZzZXQ6IG51bWJlciwgbGltaXQ6IG51bWJlcikgPT4gYW55LCBvZmZzZXQ6IG51bWJlciwgbGltaXQ6IG51bWJlciwga2V5OiBzdHJpbmcsIG91dHB1dDogYW55W10gPSBbXSwgY2FsbGJhY2s/OiAoYWxsUm93czphbnlbXSwgbmV3Um93czogYW55W10pID0+IHZvaWQsIHByZXZSZXNvbHZlPzogKHJlc3VsdDogYW55KSA9PiB2b2lkKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlOiAocmVzdWx0OiBhbnkpID0+IHZvaWQsIHJlamVjdDogKHJlc3VsdDogYW55KSA9PiB2b2lkKSA9PiB7XG4gICAgICBsZXQgcmVzcG9uc2U7XG4gICAgICB0cnkge1xuICAgICAgICByZXNwb25zZSA9IGF3YWl0IG1ldGhvZChvZmZzZXQsIGxpbWl0KTtcbiAgICAgIH0gY2F0Y2goZTogYW55KSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgb3V0cHV0ID0gb3V0cHV0LmNvbmNhdChyZXNwb25zZVtrZXldKTtcbiAgICAgIFxuICAgICAgaWYoY2FsbGJhY2spIGNhbGxiYWNrKG91dHB1dCwgcmVzcG9uc2Vba2V5XSk7XG4gICAgICBcbiAgICAgIGlmKHJlc3BvbnNlLm5leHRQYWdlKSB7XG4gICAgICAgIGF3YWl0IHBhZ2luYXRlKG1ldGhvZCwgcmVzcG9uc2UubmV4dFBhZ2UsIGxpbWl0LCBrZXksIG91dHB1dCwgY2FsbGJhY2ssIHByZXZSZXNvbHZlID8/IHJlc29sdmUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAocHJldlJlc29sdmUgPz8gcmVzb2x2ZSkob3V0cHV0KTtcbiAgICAgIH1cbiAgICAgIFxuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJlcGFyZVNlYXJjaFN0cmluZyh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZighdmFsdWUpIHJldHVybiBcIlwiO1xuICAgIHJldHVybiB2YWx1ZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1xccysvZ2ltLFwiXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUl0ZW0oYXJyYXk6IGFueVtdLCBpdGVtOiBhbnksIGtleTogc3RyaW5nID0gJ2lkJywgcG9zaXRpb246IHN0cmluZyA9ICdjdXJyZW50Jyk6IGFueSB7XG4gIGNvbnN0IGxvb2t1cCA9IHt9IGFzIGFueTtcbiAgbG9va3VwW2tleV0gPSBpdGVtW2tleV07XG5cbiAgY29uc3Qgb2xkSXRlbSA9IF8uZmluZFdoZXJlKGFycmF5LCBsb29rdXApO1xuXG4gIGlmICghb2xkSXRlbSkge1xuICAgIGFycmF5LnVuc2hpZnQoaXRlbSk7XG4gICAgcmV0dXJuIGl0ZW07XG4gIH1cblxuICBjb25zdCBpbmRleCA9IGFycmF5LmluZGV4T2Yob2xkSXRlbSk7XG5cbiAgaWYgKHBvc2l0aW9uID09PSAnZmlyc3QnKSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBhcnJheS51bnNoaWZ0KGl0ZW0pO1xuICB9IGVsc2Uge1xuICAgIGFycmF5LnNwbGljZShpbmRleCwgMSwgaXRlbSk7XG4gIH1cblxuICByZXR1cm4gaXRlbTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNsZWVwKGR1cmF0aW9uOiBudW1iZXIgPSAwKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZTogKHZhbHVlOiBhbnkpID0+IHZvaWQpID0+IHtcbiAgICBkZWxheSgoKSA9PiByZXNvbHZlKGR1cmF0aW9uKSwgZHVyYXRpb24pO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNuYWtlY2FzZShlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoXy5pc0VtcHR5KGUpKSByZXR1cm4gZTtcbiAgcmV0dXJuIGUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXHMrL2dpbSwgJ18nKS5yZXBsYWNlKC8tL2csICdfJykucmVwbGFjZSgvXysvZywgJ18nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpY2socmV0dXJuVmFsdWU/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmU6IChyZXNwb25zZTogYW55KSA9PiB2b2lkLCByZWplY3Q6IChyZXNwb25zZTogYW55KSA9PiB2b2lkKSA9PiB7XG4gICAgZGVsYXkoKCkgPT4gcmVzb2x2ZShyZXR1cm5WYWx1ZSkpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpbWVzdGFtcChkYXRlPzogRGF0ZSwgaW5jbHVkZVRpbWU6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nIHtcbiAgY29uc3QgaW5mbyA9IGRhdGVTdHJpbmdzKGRhdGUpO1xuICBjb25zdCB0aW1lID0gYCAke2luZm8udGltZX06JHtpbmZvLnNlY29uZHN9YDtcbiAgcmV0dXJuIGAke2luZm8ueWVhcn0tJHtpbmZvLm1vbnRofS0ke2luZm8uZGF0ZX0ke2luY2x1ZGVUaW1lID8gdGltZSA6ICcnfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFjZSguLi5wYXJhbWV0ZXJzOiBhbnlbXSkge1xuICBpZiAoIWdldHBhcmFtcygpLmRlYnVnKSByZXR1cm47XG5cbiAgZm9yIChsZXQgaSA9IDAsIGNvdW50ID0gcGFyYW1ldGVycy5sZW5ndGg7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gICAgY29uc29sZS5sb2cocGFyYW1ldGVyc1tpXSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaW0oZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKF8uaXNFbXB0eShlKSkgcmV0dXJuIGU7XG4gIHJldHVybiBlLnJlcGxhY2UoL15cXHMrLywgJycpLnJlcGxhY2UoL1xccyskLywgJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJ1dGh5KGU6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gIWZhbHN5KGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVFbWFpbChlbWFpbDogc3RyaW5nIHwgbnVsbCk6IFJlZ0V4cE1hdGNoQXJyYXkgfCBudWxsIHtcbiAgaWYgKCFlbWFpbCkgcmV0dXJuIG51bGw7XG5cbiAgcmV0dXJuIFN0cmluZyhlbWFpbClcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5tYXRjaChcbiAgICAgIC9eKChbXjw+KClbXFxdXFxcXC4sOzpcXHNAXCJdKyhcXC5bXjw+KClbXFxdXFxcXC4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKChcXFtbMC05XXsxLDN9XFwuWzAtOV17MSwzfVxcLlswLTldezEsM31cXC5bMC05XXsxLDN9XFxdKXwoKFthLXpBLVpcXC0wLTldK1xcLikrW2EtekEtWl17Mix9KSkkLyxcbiAgICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmlld3BvcnQoZWw6IEhUTUxFbGVtZW50LCBwZXJjZW50VmlzaWJsZTogbnVtYmVyID0gMTAwKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgY29uc3Qgd2luZG93SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG5cbiAgcmV0dXJuICEoXG4gICAgTWF0aC5mbG9vcigxMDAgLSAoKHJlY3QudG9wID49IDAgPyAwIDogcmVjdC50b3ApIC8gKy0ocmVjdC5oZWlnaHQgLyAxKSkgKiAxMDApIDwgcGVyY2VudFZpc2libGUgfHxcbiAgICBNYXRoLmZsb29yKDEwMCAtICgocmVjdC5ib3R0b20gLSB3aW5kb3dIZWlnaHQpIC8gcmVjdC5oZWlnaHQpICogMTAwKSA8IHBlcmNlbnRWaXNpYmxlXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXNzd29yZChsZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IHVwcGVyQ2FzZUNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaJztcbiAgY29uc3QgbG93ZXJDYXNlQ2hhcnMgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonO1xuICBjb25zdCBudW1iZXJzID0gJzAxMjM0NTY3ODknO1xuICBjb25zdCBzcGVjaWFsQ2hhcnMgPSAnIUAjJCVeJiooKS1fPStbXXw7OiwuPyc7XG4gIGxlbmd0aCA9IGxlbmd0aCA/PyA4O1xuXG4gIC8vIEVuc3VyZSBlYWNoIHR5cGUgb2YgY2hhcmFjdGVyIGFwcGVhcnMgYXQgbGVhc3Qgb25jZVxuICBjb25zdCBwYXNzd29yZCA9IFtcbiAgICB1cHBlckNhc2VDaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB1cHBlckNhc2VDaGFycy5sZW5ndGgpXSwgLy8gT25lIHVwcGVyY2FzZVxuICAgIGxvd2VyQ2FzZUNoYXJzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxvd2VyQ2FzZUNoYXJzLmxlbmd0aCldLCAvLyBPbmUgbG93ZXJjYXNlXG4gICAgbnVtYmVyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBudW1iZXJzLmxlbmd0aCldLCAvLyBPbmUgbnVtYmVyXG4gICAgc3BlY2lhbENoYXJzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHNwZWNpYWxDaGFycy5sZW5ndGgpXSwgLy8gT25lIHNwZWNpYWwgY2hhclxuICBdO1xuXG4gIC8vIFBvb2wgb2YgYWxsIGFsbG93ZWQgY2hhcmFjdGVycyBmb3IgcmVtYWluaW5nIHBhc3N3b3JkIGNoYXJhY3RlcnNcbiAgY29uc3QgYWxsQ2hhcnMgPSB1cHBlckNhc2VDaGFycyArIGxvd2VyQ2FzZUNoYXJzICsgbnVtYmVycyArIHNwZWNpYWxDaGFycztcblxuICAvLyBGaWxsIHRoZSByZXN0IG9mIHRoZSBwYXNzd29yZCBsZW5ndGggKDY0IGNoYXJhY3RlcnMpIHdpdGggcmFuZG9tIGNoYXJhY3RlcnNcbiAgZm9yIChsZXQgaSA9IHBhc3N3b3JkLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgcGFzc3dvcmQucHVzaChhbGxDaGFyc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhbGxDaGFycy5sZW5ndGgpXSk7XG4gIH1cblxuICAvLyBTaHVmZmxlIHRoZSBwYXNzd29yZCBhcnJheSB0byBlbnN1cmUgcmFuZG9tbmVzcywgdGhlbiBqb2luIGl0IGludG8gYSBzdHJpbmdcbiAgY29uc3QgcmFuZG9tUGFzc3dvcmQgPSBwYXNzd29yZC5zb3J0KCgpID0+IE1hdGgucmFuZG9tKCkgLSAwLjUpLmpvaW4oJycpO1xuICByZXR1cm4gcmFuZG9tUGFzc3dvcmQ7XG59XG5cblxuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtcbiAgXSxcbiAgaW1wb3J0czogW1xuICBdLFxuICBleHBvcnRzOiBbXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgVXRpbHNNb2R1bGUgeyB9XG4iXX0=