{"version":3,"sources":["cost-calculator.js"],"names":["Zone","constructor","options","this","name","zone","q","deltaU","openingSize","dt","toFixed","energySavings","Math","round","time","energySavingsSecondary","adjustedEnergySavings","efficiencyRating","savings","costOfElectricity","paybackPeriod","thermiserMaxLowUPrice","thermiserMaxPrice","calculator","document","querySelector","element","app","uFactor1","uFactor2","inputErrorCount","doorSize","widthFt","widthIn","heightFt","heightIn","headings","zones","singleComponents","submit","resultsContainer","notificationContainer","formError","doorSelect","multiComponents","inputs","errors","setUpComponents","eventHandlers","key","value","Object","entries","querySelectorAll","addEventListener","calculateResults","forEach","input","onInputChange","onDoorSelectChange","e","target","Number","validateInput","calculateOpeningSize","inputField","isNumber","match","error","nextElementSibling","hasAttribute","classList","remove","innerHTML","add","textContent","validateForm","let","isValid","hasHeight","item","contains","hasWidth","width","height","formIsValid","results","map","heading","join","zoneOptions","insertAdjacentHTML"],"mappings":"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","file":"cost-calculator.min.js","sourcesContent":["(function () {\r\n // Formula based off excel doc\r\n // https://intranet.americaneagle.com/tickets/view.asp?MODE=VIEW&TICKET_ID=705071&\r\n\r\n class Zone {\r\n constructor(options) {\r\n this.options = options;\r\n this.name = this.options.zone;\r\n this.q = (this.options.deltaU * this.options.openingSize * this.options.dt).toFixed(2);\r\n this.energySavings = Math.round(this.options.time * this.q);\r\n this.energySavingsSecondary = (this.energySavings / 3412).toFixed(2);\r\n this.adjustedEnergySavings = (this.energySavingsSecondary / this.options.efficiencyRating).toFixed(2);\r\n this.savings = (this.adjustedEnergySavings * this.options.costOfElectricity).toFixed(2);\r\n this.paybackPeriod = ((this.options.thermiserMaxLowUPrice - this.options.thermiserMaxPrice) / this.savings).toFixed(2);\r\n }\r\n }\r\n\r\n class CostCalculator {\r\n constructor(element) {\r\n this.app = element;\r\n this.uFactor1 = 0.82;\r\n this.uFactor2 = 0.53;\r\n this.inputErrorCount = 0;\r\n this.doorSize = {\r\n \"widthFt\": '',\r\n \"widthIn\": '',\r\n \"heightFt\": '',\r\n \"heightIn\": '',\r\n };\r\n this.options = {\r\n deltaU: this.uFactor1 - this.uFactor2,\r\n efficiencyRating: .9,\r\n costOfElectricity: 0.155,\r\n thermiserMaxPrice: 5746.00,\r\n thermiserMaxLowUPrice: 6200.00,\r\n openingSize: 0,\r\n time: 365 * 24,\r\n };\r\n this.headings = [\r\n 'Climate Zone',\r\n 'Annual Savings per Door',\r\n ];\r\n this.zones = [\r\n {\r\n zone: \"Zone 1 (Hot)\",\r\n dt: 20,\r\n },\r\n {\r\n zone: \"Zone 2 (Hot-Humid)\",\r\n dt: 23.30,\r\n },\r\n {\r\n zone: \"Zone 3 (Warm)\",\r\n dt: 32.50,\r\n },\r\n {\r\n zone: \"Zone 4 (Mixed)\",\r\n dt: 37.50,\r\n },\r\n {\r\n zone: \"Zone 5 (Cool)\",\r\n dt: 45.00,\r\n },\r\n {\r\n zone: \"Zone 6 (Cold)\",\r\n dt: 56.25,\r\n },\r\n {\r\n zone: \"Zone 7 (Very Cold)\",\r\n dt: 73.00,\r\n },\r\n {\r\n zone: \"Zone 8 (Subarctic/Arctic)\",\r\n dt: 81.50,\r\n },\r\n ];\r\n this.singleComponents = {\r\n submit: '[cost-calculator-submit]',\r\n resultsContainer: '[cost-calculator-results]',\r\n notificationContainer: '[cost-calculator-notification]',\r\n formError: '[cost-calculator-form-error]',\r\n doorSelect: '[cost-calculator-door]',\r\n };\r\n this.multiComponents = {\r\n inputs: '[cost-calculator-input]',\r\n errors: '[cost-calculator-error]',\r\n };\r\n this.setUpComponents();\r\n this.eventHandlers();\r\n }\r\n \r\n setUpComponents() {\r\n for (const [key,value] of Object.entries(this.singleComponents)) {\r\n this[key] = this.app.querySelector(value);\r\n }\r\n\r\n for (const [key,value] of Object.entries(this.multiComponents)) {\r\n this[key] = this.app.querySelectorAll(value);\r\n }\r\n }\r\n\r\n eventHandlers() {\r\n this.submit?.addEventListener('click', () => this.calculateResults());\r\n\r\n this.inputs.forEach((input) => {\r\n input.addEventListener('input', (input) => this.onInputChange(input));\r\n });\r\n\r\n this.doorSelect?.addEventListener('change', (e) => this.onDoorSelectChange(e));\r\n }\r\n\r\n onDoorSelectChange(e) {\r\n const target = e.target;\r\n const value = target.value;\r\n this.uFactor1 = Number(value);\r\n this.options.deltaU = this.uFactor1 - this.uFactor2;\r\n }\r\n\r\n onInputChange(input) {\r\n const target = input.target;\r\n const name = target.name;\r\n const value = target.value;\r\n const isValid = this.validateInput(target);\r\n if (isValid) {\r\n if (value === '') {\r\n this.doorSize[name] = 0;\r\n } else {\r\n this.doorSize[name] = value;\r\n }\r\n this.calculateOpeningSize();\r\n }\r\n }\r\n \r\n validateInput(inputField) {\r\n const isNumberRegex =/^[0-9]+$/;\r\n const value = inputField.value;\r\n const isNumber = value.match(isNumberRegex);\r\n const error = inputField.nextElementSibling;\r\n if (isNumber || value === '') {\r\n if (error.hasAttribute('cost-calculator-error')) {\r\n error.classList.remove('active');\r\n error.innerHTML = '';\r\n }\r\n return true;\r\n }\r\n error.classList.add('active');\r\n error.textContent = `'${value}' is not a number`;\r\n return false;\r\n }\r\n\r\n validateForm() {\r\n // since validation is done on input change\r\n // if any errors are visible, it means the form is not valid\r\n let isValid = true;\r\n this.errors.forEach((item) => {\r\n if (item.classList.contains('active')) {\r\n isValid = false;\r\n }\r\n });\r\n // at least one width and height value must be entered\r\n let hasHeight = false;\r\n let hasWidth = false;\r\n for (const [key,value] of Object.entries(this.doorSize)) {\r\n if (value !== '' && value > 0) {\r\n if (key === 'widthFt' || key === 'widthIn') {\r\n hasWidth = true;\r\n }\r\n\r\n if (key === 'heightFt' || key === 'heightIn') {\r\n hasHeight = true;\r\n }\r\n }\r\n }\r\n if (!hasHeight || !hasWidth) {\r\n this.formError.innerHTML = '';\r\n this.formError.textContent = `At least one height and width value is required`;\r\n isValid = false;\r\n }\r\n return isValid;\r\n }\r\n\r\n calculateOpeningSize() {\r\n const width = Number(this.doorSize['widthFt']) + (Number(this.doorSize['widthIn']) / 12);\r\n const height = Number(this.doorSize['heightFt']) + (Number(this.doorSize['heightIn']) / 12);\r\n this.options.openingSize = width * height;\r\n }\r\n\r\n calculateResults() {\r\n const formIsValid = this.validateForm();\r\n this.notificationContainer.innerHTML = '';\r\n if (formIsValid) {\r\n this.formError.innerHTML = '';\r\n this.notificationContainer.textContent = `Cost calculator table results updated`;\r\n const results = `\r\n
\r\n \r\n \r\n \r\n ${this.headings.map((heading) => {\r\n return ``;\r\n }).join('')}\r\n \r\n \r\n \r\n ${this.zones.map((zoneOptions) =>{\r\n const options = {\r\n ...this.options,\r\n ...zoneOptions\r\n };\r\n const zone = new Zone(options);\r\n return `\r\n \r\n \r\n \r\n \r\n `\r\n }).join('')}\r\n \r\n
${heading}
${zone.name}${zone.savings}
\r\n
\r\n `;\r\n this.resultsContainer.innerHTML = '';\r\n this.resultsContainer.insertAdjacentHTML('beforeend', results);\r\n } else {\r\n this.notificationContainer.textContent = `There are errors in the cost calculator form`;\r\n }\r\n }\r\n }\r\n\r\n const calculator = document.querySelector('[cost-calculator]');\r\n if (calculator) {\r\n new CostCalculator(calculator);\r\n }\r\n})();"]}