{"version":3,"file":"zoom.v1.6737.min.js?t=9a90aa3815448cc78c0e","mappings":"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","sources":["webpack://@hero-digital/zoom/./src/components/components/AicRoiCalculator/AicRoiCalculator.js","webpack://@hero-digital/zoom/./src/js/utilities/utilities.js"],"sourcesContent":["import { setCookie } from '../../../js/utilities/utilities'\r\n\r\nclass AicRoiCalculator {\r\n static HOSTED_MIN_PER_MIN = 28.3\r\n static ATTENDED_MIN_PER_MIN = 18.6\r\n static SKIP_PER_MEETING = 30.3\r\n static COEF_ACTION = 3.2\r\n static COEF_REPORT = 6.4\r\n static COEF_PROPOSAL = 2.8\r\n static COEF_PRD = 9.9\r\n static COEF_ENABLE = 17.0\r\n static WEEKS_PER_YEAR = 52\r\n static MIN_CORE_NUMERIC_INPUTS = 5\r\n static TOTAL_NUMERIC_INPUTS_WITH_DELIVERABLES = 10\r\n static LICENSE_MONTHLY_USD = 15\r\n static LICENSE_MONTHS = 12\r\n static COOKIE_NAME = 'AicRoiCalculatorResults'\r\n /** Debounce cookie + form persistence while sliders fire rapid `input` events */\r\n static PERSIST_DEBOUNCE_MS = 200\r\n\r\n static ROOT = '.fdn-aicrocalculator-wrapper'\r\n\r\n static SEL = (() => {\r\n const R = AicRoiCalculator.ROOT\r\n return {\r\n resultsContainer: `${R}__results--container`,\r\n calculator: `${R}__calculator`,\r\n calculatorBody: `${R}__calculator__body`,\r\n someNote: `${R}__calculator__head--someNote`,\r\n questionRow: `${R}__calculator__body--wrapper--question`,\r\n slider: `${R}__calculator__body--wrapper--question--sliderWrapper--slider`,\r\n slideValue: `${R}__calculator__body--wrapper--question--sliderWrapper--content--slidervalue`,\r\n errorMessage: `${R}__calculator__body--wrapper--question--errorMessage`,\r\n summaryYes: `${R}__calculator__head--button--yes`,\r\n summaryNo: `${R}__calculator__head--button--no`,\r\n summarySome: `${R}__calculator__head--button--some`,\r\n deliverablesYes: `${R}__calculator__deliverables--yes`,\r\n deliverablesNo: `${R}__calculator__deliverables--no`,\r\n getResultsBtn: `${R}__results--container--data ${R}__calculator__head--button`\r\n }\r\n })()\r\n\r\n static SUMMARY_STATE_CLASSES = [\r\n 'aic-yes',\r\n 'aic-no',\r\n 'aic-summaries-yes',\r\n 'aic-summaries-no',\r\n 'aic-summaries-some'\r\n ]\r\n\r\n static sliderGradient(pct) {\r\n return `linear-gradient(to right, #0b5cff ${pct}%, #e0e0e6 ${pct}%)`\r\n }\r\n\r\n static clonePlainObject(obj) {\r\n return typeof structuredClone === 'function'\r\n ? structuredClone(obj)\r\n : JSON.parse(JSON.stringify(obj))\r\n }\r\n\r\n constructor(el) {\r\n this.el = el\r\n this.hasExpandedBody = false\r\n this.meetingSummaryUsage = null\r\n this.deliverablesGenAi = 'no'\r\n this.deliverablesChosen = false\r\n this._persistRoiTimer = null\r\n this._lastPersistQuestions = null\r\n this._flushPersistOnUnload = () => {\r\n clearTimeout(this._persistRoiTimer)\r\n this._persistRoiTimer = null\r\n if (this._lastPersistQuestions) {\r\n this.flushPersistRoiState()\r\n }\r\n }\r\n window.addEventListener('pagehide', this._flushPersistOnUnload)\r\n\r\n const $ = (s) => el.querySelector(s)\r\n const $$ = (s) => el.querySelectorAll(s)\r\n const { SEL } = AicRoiCalculator\r\n\r\n this.resultContainer = $(SEL.resultsContainer)\r\n this.calculatorWrapper = $(SEL.calculator)\r\n this.calculatorBody = $(SEL.calculatorBody)\r\n this.someNote = $(SEL.someNote)\r\n\r\n this.sliders = $$(SEL.slider)\r\n const valueInputs = $$(SEL.slideValue)\r\n this.sliderTextBoxValue = Array.from(valueInputs).slice(\r\n 0,\r\n this.sliders.length\r\n )\r\n\r\n this.useMeetingSummaryYes = $(SEL.summaryYes)\r\n this.useMeetingSummaryNo = $(SEL.summaryNo)\r\n this.useMeetingSummarySome = $(SEL.summarySome)\r\n this.deliverablesYes = $(SEL.deliverablesYes)\r\n this.deliverablesNo = $(SEL.deliverablesNo)\r\n this.buttonGetResults = $(SEL.getResultsBtn)\r\n\r\n this.result1 = el.querySelector('#result-1')\r\n this.result2 = el.querySelector('#result-2')\r\n\r\n this.locale = document.documentElement.lang || 'en'\r\n\r\n this.calculatorResults = {\r\n whatYouCanSaveWithZoomAICompanionPerWeek: '0',\r\n whatYouCanSaveWithZoomAICompanionPerYear: '0',\r\n totalTimeSavingsPerYearIndividual: '0',\r\n totalTimeSavingsPerWeekIndividual: '0',\r\n takingMeetingNotesWithMeetingSummaryPerYearIndividual: '0',\r\n takingMeetingNotesWithMeetingSummaryPerWeekIndividual: '0',\r\n readingMeetingSummaryVsAttendingTheMeetingPerYearIndividual: '0',\r\n readingMeetingSummaryVsAttendingTheMeetingPerWeekIndividual: '0',\r\n percentOfTimeSavedInAMeetingIndividual: '0',\r\n totalTimeSavingsPerYearCompany: '0',\r\n totalTimeSavingsPerWeekCompany: '0',\r\n takingMeetingNotesWithMeetingSummaryPerYearCompany: '0',\r\n takingMeetingNotesWithMeetingSummaryPerWeekCompany: '0',\r\n readingMeetingSummaryVsAttendingTheMeetingPerYearCompany: '0',\r\n readingMeetingSummaryVsAttendingTheMeetingPerWeekCompany: '0',\r\n totalLicenseCostSavingsPerYear: '0',\r\n isIndividual: false,\r\n alreadySavingMinutesPerWeek: '0',\r\n alreadySavingMinutesPerYear: '0',\r\n couldSaveMoreMinutesPerWeek: '0',\r\n couldSaveMoreMinutesPerYear: '0',\r\n deliverablesGenAi: ''\r\n }\r\n\r\n this.init()\r\n }\r\n\r\n init() {\r\n this.bindMeetingSummaryChoice()\r\n this.bindDeliverablesChoice()\r\n this.bindSliders()\r\n }\r\n\r\n questionRow(el) {\r\n return el.closest(AicRoiCalculator.SEL.questionRow)\r\n }\r\n\r\n bindMeetingSummaryChoice() {\r\n const expandBody = () => {\r\n if (!this.hasExpandedBody && this.calculatorBody) {\r\n this.hasExpandedBody = true\r\n this.calculatorBody.removeAttribute('hidden')\r\n // Keep compatibility with both old and new CSS implementations.\r\n this.calculatorBody.classList.add('aic-calculator-body--expanded')\r\n this.calculatorBody.style.maxHeight = `${this.calculatorBody.scrollHeight}px`\r\n this.calculatorBody.style.opacity = '1'\r\n this.calculatorBody.style.overflow = 'visible'\r\n // Once the expand transition finishes, drop the fixed max-height so the\r\n // body can grow freely as its content changes (e.g. error messages,\r\n // the \"some\" note). Runs once per expansion.\r\n this.calculatorBody.addEventListener(\r\n 'transitionend',\r\n () => {\r\n if (\r\n this.calculatorBody.classList.contains(\r\n 'aic-calculator-body--expanded'\r\n )\r\n ) {\r\n this.calculatorBody.style.maxHeight = 'none'\r\n }\r\n },\r\n { once: true }\r\n )\r\n this.setDeliverablesChoice('no', false)\r\n }\r\n }\r\n\r\n const setSummary = (usage) => {\r\n this.meetingSummaryUsage = usage\r\n this.resultContainer?.classList.remove('default-state')\r\n AicRoiCalculator.SUMMARY_STATE_CLASSES.forEach((c) =>\r\n this.calculatorWrapper?.classList.remove(c)\r\n )\r\n const isYes = usage === 'yes'\r\n this.calculatorWrapper?.classList.add(isYes ? 'aic-yes' : 'aic-no')\r\n this.calculatorWrapper?.classList.add(\r\n isYes ? 'aic-summaries-yes' : usage === 'some' ? 'aic-summaries-some' : 'aic-summaries-no'\r\n )\r\n if (usage === 'some') {\r\n this.someNote?.removeAttribute('hidden')\r\n } else {\r\n this.someNote?.setAttribute('hidden', 'hidden')\r\n }\r\n expandBody()\r\n this.calculator()\r\n this.refreshGetResultsButton()\r\n }\r\n\r\n this.useMeetingSummaryYes?.addEventListener('click', () =>\r\n setSummary('yes')\r\n )\r\n this.useMeetingSummaryNo?.addEventListener('click', () => setSummary('no'))\r\n this.useMeetingSummarySome?.addEventListener('click', () =>\r\n setSummary('some')\r\n )\r\n }\r\n\r\n bindDeliverablesChoice() {\r\n this.deliverablesYes?.addEventListener('click', () =>\r\n this.setDeliverablesChoice('yes', true)\r\n )\r\n this.deliverablesNo?.addEventListener('click', () =>\r\n this.setDeliverablesChoice('no', true)\r\n )\r\n }\r\n\r\n setDeliverablesChoice(choice, runCalc) {\r\n this.deliverablesGenAi = choice\r\n // Only a real user selection counts toward \"all conditions met\"; the\r\n // silent default applied on expand (runCalc === false) does not.\r\n if (runCalc) {\r\n this.deliverablesChosen = true\r\n }\r\n this.calculatorWrapper?.classList.remove(\r\n 'aic-deliverables-yes',\r\n 'aic-deliverables-no'\r\n )\r\n this.calculatorWrapper?.classList.add(\r\n choice === 'yes' ? 'aic-deliverables-yes' : 'aic-deliverables-no'\r\n )\r\n this.updateResultHero(choice)\r\n if (runCalc) {\r\n this.calculator()\r\n this.refreshGetResultsButton()\r\n }\r\n }\r\n\r\n updateResultHero(choice) {\r\n const heroSection = document.querySelector('.aic-roi-result-hero')\r\n const heroHeading = document.getElementById('aic-roi-result-hero-heading')\r\n if (!heroSection || !heroHeading) return\r\n const isYes = choice === 'yes'\r\n heroSection.classList.toggle('aic-roi-result-hero--deliverables-yes', isYes)\r\n heroSection.classList.toggle('aic-roi-result-hero--deliverables-no', !isYes)\r\n const next = isYes\r\n ? heroHeading.dataset.roiHeadingYes\r\n : heroHeading.dataset.roiHeadingNo\r\n if (next) {\r\n heroHeading.textContent = next\r\n }\r\n }\r\n\r\n updateSliderGradient(slider) {\r\n const min = Number(slider.min)\r\n const max = Number(slider.max)\r\n const val = Number(slider.value)\r\n const pct = max === min ? 0 : ((val - min) / (max - min)) * 100\r\n slider.style.background = AicRoiCalculator.sliderGradient(pct)\r\n }\r\n\r\n bindSliders() {\r\n this.sliders.forEach((slider, index) => {\r\n this.updateSliderGradient(slider)\r\n const textInput = this.sliderTextBoxValue[index]\r\n slider.addEventListener('input', () => {\r\n this.updateSliderGradient(slider)\r\n if (this.validateField(slider, slider.value)) {\r\n textInput.value = slider.value\r\n textInput.setAttribute('value', slider.value)\r\n slider.setAttribute('value', slider.value)\r\n this.calculator()\r\n }\r\n })\r\n })\r\n\r\n this.sliderTextBoxValue.forEach((input, index) => {\r\n input.addEventListener('input', () => {\r\n // Numbers only — strip anything that isn't a digit as the user types.\r\n const digitsOnly = input.value.replace(/\\D/g, '')\r\n if (digitsOnly !== input.value) {\r\n input.value = digitsOnly\r\n }\r\n const raw = input.value\r\n if (raw === '') {\r\n this.displayErrorMessage(input)\r\n this.disableGetResultsButton()\r\n return\r\n }\r\n if (this.validateField(input, raw)) {\r\n const slider = this.sliders[index]\r\n slider.value = raw\r\n slider.setAttribute('value', raw)\r\n this.updateSliderGradient(slider)\r\n this.calculator()\r\n } else {\r\n this.disableGetResultsButton()\r\n }\r\n })\r\n })\r\n }\r\n\r\n allConditionsMet() {\r\n // 1) The meeting-summary question must be answered.\r\n if (!this.meetingSummaryUsage) {\r\n return false\r\n }\r\n // 2) The deliverables question must be explicitly chosen by the user.\r\n if (!this.deliverablesChosen) {\r\n return false\r\n }\r\n // 3) Every numeric input must be present and within its slider range.\r\n if (\r\n this.sliderTextBoxValue.length < AicRoiCalculator.MIN_CORE_NUMERIC_INPUTS\r\n ) {\r\n return false\r\n }\r\n return this.sliderTextBoxValue.every((input) =>\r\n this.isNumericInputValid(input, input.value)\r\n )\r\n }\r\n\r\n refreshGetResultsButton() {\r\n if (this.allConditionsMet()) {\r\n this.enableGetResultsButton()\r\n } else {\r\n this.disableGetResultsButton()\r\n }\r\n }\r\n\r\n enableGetResultsButton() {\r\n if (this.buttonGetResults?.disabled) {\r\n this.buttonGetResults.disabled = false\r\n this.buttonGetResults.removeAttribute('data-disabled')\r\n }\r\n }\r\n\r\n disableGetResultsButton() {\r\n if (this.buttonGetResults && !this.buttonGetResults.disabled) {\r\n this.buttonGetResults.disabled = true\r\n this.buttonGetResults.setAttribute('data-disabled', 'disabled')\r\n }\r\n }\r\n\r\n isNumericInputValid(element, inputValue) {\r\n const digitsOnly = /^\\d+$/.test(inputValue)\r\n const value = parseInt(inputValue, 10)\r\n if (!(digitsOnly && inputValue !== '')) {\r\n return false\r\n }\r\n const row = this.questionRow(element)\r\n const slider = row?.querySelector(AicRoiCalculator.SEL.slider)\r\n if (!slider) {\r\n return true\r\n }\r\n const sliderMinValue = parseInt(slider.getAttribute('min'), 10)\r\n const sliderMaxValue = parseInt(slider.getAttribute('max'), 10)\r\n return value >= sliderMinValue && value <= sliderMaxValue\r\n }\r\n\r\n validateField(element, inputValue) {\r\n if (this.isNumericInputValid(element, inputValue)) {\r\n this.hideErrorMessage(element)\r\n this.refreshGetResultsButton()\r\n return true\r\n }\r\n this.disableGetResultsButton()\r\n this.displayErrorMessage(element)\r\n return false\r\n }\r\n\r\n displayErrorMessage(element) {\r\n this.questionRow(element)\r\n ?.querySelector(AicRoiCalculator.SEL.errorMessage)\r\n ?.removeAttribute('hidden')\r\n }\r\n\r\n hideErrorMessage(element) {\r\n this.questionRow(element)\r\n ?.querySelector(AicRoiCalculator.SEL.errorMessage)\r\n ?.setAttribute('hidden', 'hidden')\r\n }\r\n\r\n readNumericQuestions() {\r\n if (this.sliderTextBoxValue.length < AicRoiCalculator.MIN_CORE_NUMERIC_INPUTS) {\r\n return null\r\n }\r\n const values = this.sliderTextBoxValue.map((input) =>\r\n parseInt(input.value, 10)\r\n )\r\n if (values.some((v) => Number.isNaN(v))) {\r\n return null\r\n }\r\n const normalizedValues = values.slice(\r\n 0,\r\n AicRoiCalculator.TOTAL_NUMERIC_INPUTS_WITH_DELIVERABLES\r\n )\r\n while (\r\n normalizedValues.length < AicRoiCalculator.TOTAL_NUMERIC_INPUTS_WITH_DELIVERABLES\r\n ) {\r\n normalizedValues.push(0)\r\n }\r\n\r\n const [\r\n meetingsHostedPerWeek,\r\n avgHostedMeetingLength,\r\n meetingsAttendedPerWeek,\r\n avgAttendedMeetingLength,\r\n skippableMeetingsPerWeek,\r\n genAiActionList,\r\n genAiReport,\r\n genAiProposal,\r\n genAiPrd,\r\n genAiEnablement\r\n ] = normalizedValues\r\n\r\n return {\r\n meetingsHostedPerWeek,\r\n avgHostedMeetingLength,\r\n meetingsAttendedPerWeek,\r\n avgAttendedMeetingLength,\r\n skippableMeetingsPerWeek,\r\n genAiActionList,\r\n genAiReport,\r\n genAiProposal,\r\n genAiPrd,\r\n genAiEnablement\r\n }\r\n }\r\n\r\n computeWeeklyMinutes(q) {\r\n const C = AicRoiCalculator\r\n const hosted =\r\n (C.HOSTED_MIN_PER_MIN *\r\n q.meetingsHostedPerWeek *\r\n q.avgHostedMeetingLength) /\r\n 60\r\n const attended =\r\n (C.ATTENDED_MIN_PER_MIN *\r\n q.meetingsAttendedPerWeek *\r\n q.avgAttendedMeetingLength) /\r\n 60\r\n const skip = C.SKIP_PER_MEETING * q.skippableMeetingsPerWeek\r\n const postMeeting = hosted + attended + skip\r\n const genAi =\r\n C.COEF_ACTION * q.genAiActionList +\r\n C.COEF_REPORT * q.genAiReport +\r\n C.COEF_PROPOSAL * q.genAiProposal +\r\n C.COEF_PRD * q.genAiPrd +\r\n C.COEF_ENABLE * q.genAiEnablement\r\n return { postMeeting, genAi, total: postMeeting + genAi }\r\n }\r\n\r\n splitAlreadyVsCould(postMeeting, genAi) {\r\n const summaries = this.meetingSummaryUsage\r\n const meetingAlready = summaries === 'yes' ? postMeeting : 0\r\n const meetingCould =\r\n summaries === 'no' || summaries === 'some' ? postMeeting : 0\r\n\r\n const useGen = this.deliverablesGenAi === 'yes'\r\n const genAlready = useGen ? genAi : 0\r\n const genCould = useGen ? 0 : genAi\r\n\r\n return {\r\n alreadyWeekly: meetingAlready + genAlready,\r\n couldWeekly: meetingCould + genCould\r\n }\r\n }\r\n\r\n calculator() {\r\n if (!this.meetingSummaryUsage) {\r\n return false\r\n }\r\n\r\n const q = this.readNumericQuestions()\r\n if (!q) {\r\n return false\r\n }\r\n\r\n const inputsValid = this.sliderTextBoxValue.every((input) =>\r\n this.isNumericInputValid(input, input.value)\r\n )\r\n if (!inputsValid) {\r\n this.sliderTextBoxValue.forEach((input) => {\r\n if (this.isNumericInputValid(input, input.value)) {\r\n this.hideErrorMessage(input)\r\n } else {\r\n this.displayErrorMessage(input)\r\n }\r\n })\r\n this.disableGetResultsButton()\r\n return false\r\n }\r\n this.refreshGetResultsButton()\r\n\r\n const { postMeeting, genAi, total } = this.computeWeeklyMinutes(q)\r\n const { alreadyWeekly, couldWeekly } = this.splitAlreadyVsCould(\r\n postMeeting,\r\n genAi\r\n )\r\n\r\n const W = AicRoiCalculator.WEEKS_PER_YEAR\r\n const alreadyYearly = alreadyWeekly * W\r\n const couldYearly = couldWeekly * W\r\n\r\n const fmt = (n) => Math.round(n).toLocaleString(this.locale)\r\n\r\n this.calculatorResults.whatYouCanSaveWithZoomAICompanionPerWeek = fmt(total)\r\n this.calculatorResults.whatYouCanSaveWithZoomAICompanionPerYear = fmt(\r\n total * W\r\n )\r\n this.calculatorResults.alreadySavingMinutesPerWeek = fmt(alreadyWeekly)\r\n this.calculatorResults.alreadySavingMinutesPerYear = fmt(alreadyYearly)\r\n this.calculatorResults.couldSaveMoreMinutesPerWeek = fmt(couldWeekly)\r\n this.calculatorResults.couldSaveMoreMinutesPerYear = fmt(couldYearly)\r\n this.calculatorResults.deliverablesGenAi = this.deliverablesGenAi\r\n\r\n this.calculatorResults.isIndividual = true\r\n\r\n this.applyMirroredTimeSavingsResults(\r\n fmt,\r\n total,\r\n W,\r\n alreadyWeekly,\r\n alreadyYearly,\r\n couldWeekly,\r\n couldYearly\r\n )\r\n const pct = total > 0 ? Math.round((100 * alreadyWeekly) / total) : 0\r\n this.calculatorResults.percentOfTimeSavedInAMeetingIndividual =\r\n pct.toLocaleString(this.locale)\r\n\r\n const licenseAnnual =\r\n AicRoiCalculator.LICENSE_MONTHLY_USD * AicRoiCalculator.LICENSE_MONTHS\r\n this.calculatorResults.totalLicenseCostSavingsPerYear = Math.round(\r\n licenseAnnual\r\n ).toLocaleString(this.locale)\r\n\r\n this.bindResultsOnTheHTML(total, total * W)\r\n\r\n this._lastPersistQuestions = q\r\n this.schedulePersistRoiState()\r\n return true\r\n }\r\n\r\n applyMirroredTimeSavingsResults(\r\n fmt,\r\n total,\r\n weeksPerYear,\r\n alreadyWeekly,\r\n alreadyYearly,\r\n couldWeekly,\r\n couldYearly\r\n ) {\r\n const blocks = [\r\n { keyBase: 'totalTimeSavings', weekVal: total, yearVal: total * weeksPerYear },\r\n {\r\n keyBase: 'takingMeetingNotesWithMeetingSummary',\r\n weekVal: alreadyWeekly,\r\n yearVal: alreadyYearly\r\n },\r\n {\r\n keyBase: 'readingMeetingSummaryVsAttendingTheMeeting',\r\n weekVal: couldWeekly,\r\n yearVal: couldYearly\r\n }\r\n ]\r\n const scopes = ['Individual', 'Company']\r\n for (const { keyBase, weekVal, yearVal } of blocks) {\r\n for (const scope of scopes) {\r\n this.calculatorResults[`${keyBase}PerWeek${scope}`] = fmt(weekVal)\r\n this.calculatorResults[`${keyBase}PerYear${scope}`] = fmt(yearVal)\r\n }\r\n }\r\n }\r\n\r\n roiResultInput() {\r\n return (\r\n this.el.querySelector('input[name=\"mh_roi_calc_result\"]') ||\r\n document.querySelector('input[name=\"mh_roi_calc_result\"]')\r\n )\r\n }\r\n\r\n schedulePersistRoiState() {\r\n clearTimeout(this._persistRoiTimer)\r\n this._persistRoiTimer = setTimeout(() => {\r\n this._persistRoiTimer = null\r\n this.flushPersistRoiState()\r\n }, AicRoiCalculator.PERSIST_DEBOUNCE_MS)\r\n }\r\n\r\n flushPersistRoiState() {\r\n this.setObjectCookie(\r\n AicRoiCalculator.COOKIE_NAME,\r\n this.calculatorResults,\r\n 1\r\n )\r\n\r\n const roiInput = this.roiResultInput()\r\n if (roiInput) {\r\n const calculations = AicRoiCalculator.clonePlainObject(this.calculatorResults)\r\n if (calculations.isIndividual === true) {\r\n calculations.totalTimeSavingsPerYearCompany = '0'\r\n calculations.totalTimeSavingsPerWeekCompany = '0'\r\n calculations.takingMeetingNotesWithMeetingSummaryPerYearCompany = '0'\r\n calculations.takingMeetingNotesWithMeetingSummaryPerWeekCompany = '0'\r\n calculations.readingMeetingSummaryVsAttendingTheMeetingPerYearCompany =\r\n '0'\r\n calculations.readingMeetingSummaryVsAttendingTheMeetingPerWeekCompany =\r\n '0'\r\n }\r\n roiInput.value = JSON.stringify(calculations)\r\n }\r\n\r\n const q = this._lastPersistQuestions\r\n const hiddenInput = this.el.querySelector('input[name=\"mh_page_source\"]')\r\n if (hiddenInput && q) {\r\n hiddenInput.value =\r\n `meeting summaries AI Companion:${this.meetingSummaryUsage};` +\r\n `deliverables GenAI:${this.deliverablesGenAi};` +\r\n `hosted/week:${q.meetingsHostedPerWeek};` +\r\n `avg hosted length:${q.avgHostedMeetingLength};` +\r\n `attended/week:${q.meetingsAttendedPerWeek};` +\r\n `avg attended length:${q.avgAttendedMeetingLength};` +\r\n `skippable/week:${q.skippableMeetingsPerWeek}`\r\n }\r\n }\r\n\r\n bindResultsOnTheHTML(totalWeeklyMinutes, totalYearlyMinutes) {\r\n const fmtHours = (mins) =>\r\n (mins / 60).toLocaleString(this.locale, {\r\n maximumFractionDigits: 1,\r\n minimumFractionDigits: 0\r\n })\r\n if (this.result1) {\r\n this.result1.textContent = fmtHours(totalWeeklyMinutes)\r\n }\r\n if (this.result2) {\r\n this.result2.textContent = fmtHours(totalYearlyMinutes)\r\n }\r\n }\r\n\r\n setObjectCookie(name, obj, days) {\r\n const value = JSON.stringify(obj)\r\n setCookie(name, encodeURIComponent(value), days)\r\n }\r\n}\r\n\r\nexport default AicRoiCalculator\r\n","/**\r\n * A function which adds click detection to document\r\n * and performs a prescribed action when a click is detected\r\n * outside of the supllied element.\r\n * Use an array for params.exceptionClassArray to create exceptions.\r\n *\r\n * @param {Object} elem A DOM element\r\n * @param {Function} name of class to search for\r\n * @param {Object} an object containing parameters\r\n */\r\nexport function actionOnClickOutside(element, action, params = {}) {\r\n\tlet exceptionClassArray = params.exceptionClassArray || [];\r\n\tlet useCapture = params.useCapture || false;\r\n\r\n\tconst outsideClickListener = event => {\r\n\t\tif (!element.contains(event.target) && event.target.classList.length && !exceptionClassArray.includes(...event.target.classList)) {\r\n\t\t\taction();\r\n\t\t\tremoveClickListener();\r\n\t\t}\r\n\t}\r\n\r\n\tconst removeClickListener = () => {\r\n\t\tdocument.removeEventListener('click', outsideClickListener)\r\n\t}\r\n\r\n\tdocument.addEventListener('click', outsideClickListener, useCapture);\r\n\telement.clearListener = function () {\r\n\t\tremoveClickListener();\r\n\t}\r\n}\r\n\r\n/**\r\n * Simple function to return an array of sibling elements\r\n */\r\nexport function getSiblings(elem) {\r\n\treturn Array.prototype.filter.call(elem.parentNode.children, function (sibling) {\r\n\t\treturn sibling !== elem;\r\n\t});\r\n}\r\n\r\n/**\r\n * A function which traps tabbing to modal element.\r\n * Escape key will close modal.\r\n */\r\nexport function limitKeyboardAccesibility(element, closeFunction) {\r\n\t// get all accessibile elements, put into array\r\n\tconst focusableElsRaw = element.querySelectorAll(\r\n\t\t'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex=\"0\"]'\r\n\t);\r\n\tconst focusableEls = Array.prototype.slice.call(focusableElsRaw);\r\n\t// go through elements and pull out only the ones that are visible\r\n\tlet visibleEls = [].filter.call(focusableEls, el => {\r\n\t\treturn (el.offsetParent !== null);\r\n\t});\r\n\t// get the first and last elements\r\n\tconst firstFocusableEl = visibleEls[0];\r\n\tconst lastFocusableEl = visibleEls[visibleEls.length - 1];\r\n\t// set up keyboard handler\r\n\tconst KEY_TAB = 9;\r\n\tconst KEY_ESC = 27;\r\n\tconst keyHandler = (e) => {\r\n\t\t// special case to return when keyhandling is disabled on this element\r\n\t\tif (element.disableKeyHandler) return;\r\n\r\n\t\t// specials key actions\r\n\t\tswitch (e.keyCode) {\r\n\t\t\tcase KEY_TAB:\r\n\t\t\t\t// forward tab\r\n\t\t\t\tif (!e.shiftKey) {\r\n\t\t\t\t\tif (document.activeElement === lastFocusableEl) {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\tfirstFocusableEl.focus();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// backward tab\r\n\t\t\t\telse {\r\n\t\t\t\t\tif (document.activeElement === firstFocusableEl) {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\tlastFocusableEl.focus();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase KEY_ESC:\r\n\t\t\t\tif (closeFunction) closeFunction();\r\n\t\t\t\tremoveKeyHandler();\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tbreak\r\n\t\t}\r\n\t}\r\n\t// clear function\r\n\tconst removeKeyHandler = () => {\r\n\t\tdocument.removeEventListener('keydown', keyHandler);\r\n\t}\r\n\t// attach clear function to element\r\n\telement.clearKeyHandler = () => {\r\n\t\tremoveKeyHandler();\r\n\t}\r\n\t// attach keyboard handler to doc\r\n\tdocument.addEventListener('keydown', keyHandler, false);\r\n}\r\n\r\n/**\r\n * A function which traverses all parents of a given DOM element\r\n * and returns the first parent with a class name that matches\r\n * the supplied class. This matches the JavaScript \"closest\"\r\n * function which IE11 does not support.\r\n *\r\n * @param {Object} elem A DOM element\r\n * @param {String} name of class to search for\r\n * @return {Object} the closest DOM parent with matching class\r\n */\r\nexport function closestByClass(el, clazz) {\r\n\t// Traverse the DOM up with a while loop\r\n\r\n\r\n\twhile (!el.classList.contains(clazz)) {\r\n\t\t// Increment the loop to the parent node\r\n\t\tel = el.parentNode;\r\n\t\tif (!el || el instanceof HTMLDocument) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n\t// At this point, the while loop has stopped and `el` represents the element that has\r\n\t// the class you specified in the second parameter of the function `clazz`\r\n\r\n\t// Then return the matched element\r\n\treturn el;\r\n}\r\n\r\n\r\n/**\r\n * Utility functions for setting and getting cookies\r\n */\r\nexport function setCookie(name, value, days) {\r\n\tvar expires = \"\";\r\n\tif (days) {\r\n\t\tvar date = new Date();\r\n\t\tdate.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));\r\n\t\texpires = \"; expires=\" + date.toUTCString();\r\n\t}\r\n\tif (typeof value === 'object') {\r\n\t\t// because of Safari bug handling JSON in cookies commas need to be stripped out\r\n\t\tlet obj = {};\r\n\t\tfor (const [key, item] of Object.entries(value)) {\r\n\t\t\tif (typeof item == 'string') obj[key] = item.replace(/,/,'U+0002C');\r\n\t\t\telse obj[key] = item;\r\n\t\t}\r\n\t\t// turn value into JSON\r\n\t\tvalue = JSON.stringify(obj);\r\n\t}\r\n\t// create cookie\r\n\tdocument.cookie = name + \"=\" + (value || \"\") + expires + \"; path=/;SameSite=Strict\";\r\n}\r\n\r\nexport function setCookieWithDomain(cookieName, value, days, domain) {\r\n try{\r\n var expires = \"\"\r\n if (days) {\r\n var date = new Date()\r\n date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))\r\n expires = \"; expires=\" + date.toUTCString()\r\n }\r\n if (typeof value === 'object') {\r\n // because of Safari bug handling JSON in cookies commas need to be stripped out\r\n let obj = {}\r\n for (const [key, item] of Object.entries(value)) {\r\n if (typeof item == 'string') obj[key] = item.replace(/,/,'U+0002C')\r\n else obj[key] = item\r\n }\r\n // turn value into JSON\r\n value = JSON.stringify(obj)\r\n }\r\n // create cookie\r\n document.cookie = cookieName + \"=\" + (value || \"\") + expires + \"; path=/;secure;samesite=none;domain=.\" + domain \r\n }\r\n catch(err){\r\n console.log('set cookie error:', err)\r\n }\r\n } \r\n\r\n // Save content in localStorage with expiration\r\n export function saveToLocalStorage(key, content, expirationInMinutes = null) {\r\n\t const data = {\r\n\t content: content,\r\n\t timestamp: new Date().getTime(),\r\n\t expiration: expirationInMinutes ? expirationInMinutes * 60 * 1000 : null\r\n\t };\r\n\t localStorage.setItem(key, JSON.stringify(data));\r\n\t}\r\n\r\n // Retrieve content from localStorage with expiration check\r\n export function getFromLocalStorage(key) {\r\n const data = JSON.parse(localStorage.getItem(key));\r\n\r\n if (!data) {\r\n return null;\r\n }\r\n\r\n if (data.expiration !== null && (new Date().getTime() - data.timestamp) > data.expiration) {\r\n localStorage.removeItem(key);\r\n return null;\r\n }\r\n\r\n return data.content;\r\n} \r\n\r\nexport function getCookie(name) {\r\n\tvar nameEQ = name + \"=\";\r\n\tvar ca = document.cookie.split(';');\r\n\t// see if value is JSON\r\n\tlet isJSON = function isJson(str) {\r\n\t\ttry {\r\n\t\t\tJSON.parse(str);\r\n\t\t} catch (e) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t};\r\n\tfor (var i = 0; i < ca.length; i++) {\r\n\t\tvar c = ca[i];\r\n\t\twhile (c.charAt(0) == ' ') c = c.substring(1, c.length);\r\n\t\tif (c.indexOf(nameEQ) == 0) {\r\n\t\t\tlet content = c.substring(nameEQ.length, c.length);\r\n\t\t\tif (isJSON(content)) {\r\n\t\t\t\tcontent = JSON.parse(content);\r\n\t\t\t\t// replace commas\r\n\t\t\t\tfor (const [key, item] of Object.entries(content)) {\r\n\t\t\t\t\tif (typeof item == 'string') content[key] = item.replace('U+0002C',',')\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn content;\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n}\r\n\r\n// Get a cookie without an exact name - Adobe cookies are unique to a machine\r\nexport function getCookieFuzzy(nameStartsWith,nameEndsWith) {\r\n\tlet cookies = document.cookie.split(';');\r\n\t\r\n\t// see if value is JSON\r\n\tlet isJSON = function isJson(str) {\r\n\t\ttry {\r\n\t\t\tJSON.parse(str);\r\n\t\t} catch (e) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t};\r\n\r\n\t// Loop through the cookies\r\n\tfor (var i = 0; i < cookies.length; i++) {\r\n\t\tvar cookie = cookies[i];\r\n\t\t\r\n\t\t// Trim the cookie\r\n\t\twhile (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);\r\n\r\n\t\t// Split the cookie name and value\r\n\t\tvar cookiePair = cookie.split('=');\r\n\r\n\t\t// Check that we got something to work with\r\n\t\tif (cookiePair.length > 1)\r\n\t\t{\r\n\t\t\t// Get the cookie name and value\r\n\t\t\tvar cookieName = cookiePair[0];\r\n\t\t\tvar cookieValue = cookiePair[1];\r\n\t\t\t\r\n\t\t\t// Name comparison\r\n\t\t\tif (cookieName.startsWith(nameStartsWith) && cookieName.endsWith(nameEndsWith))\r\n\t\t\t{\r\n\t\t\t\treturn cookieValue;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n}\r\n\r\nexport function eraseCookie(name) {\r\n\tdocument.cookie = name + '=; Max-Age=-99999999;';\r\n}\r\n\r\nexport function eraseCookieByPath(name) {\r\n\tdocument.cookie = `${name}=; path=/; Max-Age=-99999999;`;\r\n}\r\n\r\n/**\r\n * Convert a string to title case\r\n */\r\nexport function toTitleCase(str) {\r\n\treturn str\r\n\t\t.toLowerCase()\r\n\t\t.split(' ')\r\n\t\t.map(word => word.charAt(0).toUpperCase() + word.slice(1))\r\n\t\t.join(' ');\r\n};\r\n\r\n/**\r\n * Validate US zip code\r\n */\r\nexport function validateZipCode(str, allowPlusFour) {\r\n\tlet regexp;\r\n\tif (allowPlusFour) regexp = /^[0-9]{5}(?:-[0-9]{4})?$/;\r\n\telse regexp = /^[0-9]{5}?$/;\r\n\tif (regexp.test(str)) return true;\r\n\telse return false;\r\n};\r\n\r\n/**\r\n * Returns a function, that, as long as it continues to be invoked, will not\r\n * be triggered. The function will be called after it stops being called for\r\n * N milliseconds. If `immediate` is passed, trigger the function on the\r\n * leading edge, instead of the trailing.\r\n *\r\n * @param {Function} func A function to call after N milliseconds\r\n * @param {number} wait The number of milliseconds to wait\r\n * @param {boolean} immediate Trigger the function on the leading edge instead of the trailing\r\n * @return {Function} A function, that, as long as it continues to be invoked, will not be triggered\r\n */\r\nexport function debounce(func, wait, immediate) {\r\n\tvar timeout;\r\n\treturn function () {\r\n\t\tvar context = this,\r\n\t\t\targs = arguments;\r\n\t\tvar later = function () {\r\n\t\t\ttimeout = null;\r\n\t\t\tif (!immediate) func.apply(context, args);\r\n\t\t};\r\n\t\tvar callNow = immediate && !timeout;\r\n\t\tclearTimeout(timeout);\r\n\t\ttimeout = setTimeout(later, wait);\r\n\t\tif (callNow) func.apply(context, args);\r\n\t}\r\n}\r\n\r\n\r\n/* function to add smooth scrolling from a click event */\r\nexport function scrollAnchors(e, respond = null) {\r\n\te.preventDefault();\r\n\r\n\tfunction distanceToTop(el) {\r\n\t\treturn Math.floor((el.getBoundingClientRect().top) - 150);\r\n\t}\r\n\tvar targetID = (respond) ? respond.getAttribute('href') : this.getAttribute('href');\r\n\tvar targetAnchor = document.querySelector(targetID);\r\n\tif (!targetAnchor) return;\r\n\tvar originalTop = distanceToTop(targetAnchor);\r\n\t\r\n\t// detect if the user is on IE11\r\n\tconst isIE11 = !!window.MSInputMethodContext && !!document.documentMode;\r\n\tconst agent = window.navigator.userAgent.toLowerCase();\r\n\tconst isEdge = agent.indexOf(\"edge\") > -1 || agent.indexOf(\"edg\") > -1;\r\n\r\n\tif (isIE11 || isEdge) {\r\n\t\twindow.scroll(0, originalTop);\r\n\t} else {\r\n\t\twindow.scrollBy({\r\n\t\t\ttop: originalTop,\r\n\t\t\tleft: 0,\r\n\t\t\tbehavior: 'smooth'\r\n\t\t});\r\n\t}\r\n\r\n\tvar checkIfDone = setInterval(function () {\r\n\r\n\t\tif (distanceToTop(targetAnchor) === 0) {\r\n\t\t\ttargetAnchor.tabIndex = '-1';\r\n\t\t\ttargetAnchor.focus();\r\n\t\t\tconsole.log('scroll anchors');\r\n\t\t\t// Let's make sure the History API even exists first..\r\n\t\t\tif ('history' in window) {\r\n\r\n\t\t\t\twindow.history.pushState('', '', targetID);\r\n\r\n\t\t\t} else {\r\n\t\t\t\t// Do it the old-fashioned way!\r\n\t\t\t\twindow.location = targetID;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tclearInterval(checkIfDone);\r\n\t\t}\r\n\t}, 100);\r\n}\r\n\r\n/* get browser window dimentions */\r\nexport function viewportSize() {\r\n\tconst vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);\r\n\tconst vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);\r\n\treturn { width: vw, height: vh }\r\n}\r\n\r\n/* test a string for JSON and return if true */\r\nexport function tryParseJSON (jsonString) {\r\n try {\r\n var o = JSON.parse(jsonString);\r\n\r\n // Handle non-exception-throwing cases:\r\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\r\n // but... JSON.parse(null) returns null, and typeof null === \"object\", \r\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\r\n if (o && typeof o === \"object\") {\r\n return o;\r\n }\r\n }\r\n catch (e) { }\r\n\r\n return false;\r\n};\r\n\r\n// Function to remove a parameter from URL\r\nexport function removeURLParameter(url, parameter) {\r\n // Prefer not to use regex to avoid potential issues with special characters in parameter values\r\n var urlParts = url.split('?');\r\n if (urlParts.length >= 2) {\r\n var prefix = encodeURIComponent(parameter) + '=';\r\n var params = urlParts[1].split(/[&;]/g);\r\n\r\n // Reverse iteration to properly remove parameter\r\n for (var i = params.length; i-- > 0;) { \r\n if (params[i].lastIndexOf(prefix, 0) !== -1) { \r\n params.splice(i, 1);\r\n }\r\n }\r\n\r\n // Join back the parts\r\n url = urlParts[0] + (params.length > 0 ? '?' + params.join('&') : \"\");\r\n return url;\r\n } else {\r\n return url;\r\n }\r\n}\r\n\r\nexport function getURLParameter(url, parameter) {\r\n\tconst query = url.search\r\n\tconst params = new URLSearchParams(query)\r\n\treturn params[parameter] !== undefined ? params[parameter] : ''\r\n}\r\n\r\nexport function ensureCurrencyFilterFlag(enabled) {\r\n let flag = document.getElementById(\"IsIncludeCurrencyFilter\");\r\n if ((flag==null || !flag) && enabled==\"1\") {\r\n flag = document.createElement(\"input\");\r\n flag.type = \"hidden\";\r\n flag.id = \"IsIncludeCurrencyFilter\";\r\n\tflag.value = \"1\";\r\n document.body.appendChild(flag);\r\n }\r\n}\r\n\r\nexport function listenCurrencyChange(handler) {\r\n const flag = document.getElementById(\"IsIncludeCurrencyFilter\");\r\n if (flag && flag.value === \"1\") {\r\n document.addEventListener(\"currencyChanged\", e => {\r\n handler();\r\n });\r\n }\r\n}"],"names":["R","AicRoiCalculator","el","_this","this","_classCallCheck","hasExpandedBody","meetingSummaryUsage","deliverablesGenAi","deliverablesChosen","_persistRoiTimer","_lastPersistQuestions","_flushPersistOnUnload","clearTimeout","flushPersistRoiState","window","addEventListener","$","s","querySelector","$$","querySelectorAll","SEL","resultContainer","resultsContainer","calculatorWrapper","calculator","calculatorBody","someNote","sliders","slider","valueInputs","slideValue","sliderTextBoxValue","Array","from","slice","length","useMeetingSummaryYes","summaryYes","useMeetingSummaryNo","summaryNo","useMeetingSummarySome","summarySome","deliverablesYes","deliverablesNo","buttonGetResults","getResultsBtn","result1","result2","locale","document","documentElement","lang","calculatorResults","whatYouCanSaveWithZoomAICompanionPerWeek","whatYouCanSaveWithZoomAICompanionPerYear","totalTimeSavingsPerYearIndividual","totalTimeSavingsPerWeekIndividual","takingMeetingNotesWithMeetingSummaryPerYearIndividual","takingMeetingNotesWithMeetingSummaryPerWeekIndividual","readingMeetingSummaryVsAttendingTheMeetingPerYearIndividual","readingMeetingSummaryVsAttendingTheMeetingPerWeekIndividual","percentOfTimeSavedInAMeetingIndividual","totalTimeSavingsPerYearCompany","totalTimeSavingsPerWeekCompany","takingMeetingNotesWithMeetingSummaryPerYearCompany","takingMeetingNotesWithMeetingSummaryPerWeekCompany","readingMeetingSummaryVsAttendingTheMeetingPerYearCompany","readingMeetingSummaryVsAttendingTheMeetingPerWeekCompany","totalLicenseCostSavingsPerYear","isIndividual","alreadySavingMinutesPerWeek","alreadySavingMinutesPerYear","couldSaveMoreMinutesPerWeek","couldSaveMoreMinutesPerYear","init","key","value","pct","concat","obj","structuredClone","JSON","parse","stringify","bindMeetingSummaryChoice","bindDeliverablesChoice","bindSliders","closest","questionRow","_this$useMeetingSumma","_this$useMeetingSumma2","_this$useMeetingSumma3","_this2","setSummary","usage","_this2$resultContaine","_this2$calculatorWrap2","_this2$calculatorWrap3","classList","remove","SUMMARY_STATE_CLASSES","forEach","c","_this2$calculatorWrap","_this2$someNote","_this2$someNote2","isYes","add","removeAttribute","setAttribute","style","maxHeight","scrollHeight","opacity","overflow","contains","once","setDeliverablesChoice","refreshGetResultsButton","_this$deliverablesYes","_this$deliverablesNo","_this3","choice","runCalc","_this$calculatorWrapp","_this$calculatorWrapp2","updateResultHero","heroSection","heroHeading","getElementById","toggle","next","dataset","roiHeadingYes","roiHeadingNo","textContent","min","Number","max","val","background","sliderGradient","_this4","index","updateSliderGradient","textInput","validateField","input","digitsOnly","replace","raw","displayErrorMessage","disableGetResultsButton","_this5","MIN_CORE_NUMERIC_INPUTS","every","isNumericInputValid","allConditionsMet","enableGetResultsButton","_this$buttonGetResult","disabled","element","inputValue","test","parseInt","row","sliderMinValue","getAttribute","sliderMaxValue","hideErrorMessage","_this$questionRow","errorMessage","_this$questionRow2","values","map","some","v","isNaN","normalizedValues","TOTAL_NUMERIC_INPUTS_WITH_DELIVERABLES","push","_normalizedValues","_slicedToArray","meetingsHostedPerWeek","avgHostedMeetingLength","meetingsAttendedPerWeek","avgAttendedMeetingLength","skippableMeetingsPerWeek","genAiActionList","genAiReport","genAiProposal","genAiPrd","genAiEnablement","q","C","postMeeting","HOSTED_MIN_PER_MIN","ATTENDED_MIN_PER_MIN","SKIP_PER_MEETING","genAi","COEF_ACTION","COEF_REPORT","COEF_PROPOSAL","COEF_PRD","COEF_ENABLE","total","summaries","meetingAlready","meetingCould","useGen","alreadyWeekly","couldWeekly","_this6","readNumericQuestions","_this$computeWeeklyMi","computeWeeklyMinutes","_this$splitAlreadyVsC","splitAlreadyVsCould","W","WEEKS_PER_YEAR","alreadyYearly","couldYearly","fmt","n","Math","round","toLocaleString","applyMirroredTimeSavingsResults","licenseAnnual","LICENSE_MONTHLY_USD","LICENSE_MONTHS","bindResultsOnTheHTML","schedulePersistRoiState","weeksPerYear","scopes","_i","_blocks","keyBase","weekVal","yearVal","_step","_blocks$_i","_iterator","_createForOfIteratorHelper","done","scope","err","e","f","_this7","setTimeout","PERSIST_DEBOUNCE_MS","setObjectCookie","COOKIE_NAME","roiInput","roiResultInput","calculations","clonePlainObject","hiddenInput","totalWeeklyMinutes","totalYearlyMinutes","_this8","fmtHours","mins","maximumFractionDigits","minimumFractionDigits","name","days","setCookie","encodeURIComponent","_AicRoiCalculator","_defineProperty","ROOT","AicRoiCalculator_AicRoiCalculator","expires","date","Date","setTime","getTime","toUTCString","_typeof","_Object$entries","Object","entries","_Object$entries$_i","item","cookie","setCookieWithDomain","cookieName","domain","_i2","_Object$entries2","_Object$entries2$_i","console","log","saveToLocalStorage","content","expirationInMinutes","arguments","undefined","data","timestamp","expiration","localStorage","setItem","getFromLocalStorage","getItem","removeItem","getCookie","nameEQ","ca","split","isJSON","str","i","charAt","substring","indexOf","_i3","_Object$entries3","_Object$entries3$_i","eraseCookieByPath","ensureCurrencyFilterFlag","enabled","flag","createElement","type","id","body","appendChild","listenCurrencyChange","handler"],"sourceRoot":""}