PageSourceSearch

https://hawaiistatefcu.com/wp-content/plugins/pbry-calculators/ass…/savings-goal-script-min.js?ver=1790147579

js hawaiistatefcu.com collected 2026-09-24 11:22:29 UTC 7,942 bytes, 1 lines download raw bytes

1window.savingsGoalChartData=window.savingsGoalChartData||{cumulative_color:"#008FFB",monthly_color:"#00E396",goal_line_color:"#FF4560",fontFamily:"sans-serif",fontWeight:"normal"};class SavingsGoalCalculator{chart=null;initialized=!1;isElementorEditor=!1;chartRetryCount=0;resizeObserver=null;config={chartLoadDelay:10,retryLimit:3};currencyFormatter=new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",minimumFractionDigits:2,maximumFractionDigits:2});numberFormatter=new Intl.NumberFormat("en-US",{minimumFractionDigits:0,maximumFractionDigits:2});formatInputValue=t=>{if(""===t||isNaN(t))return"";const e=parseFloat(t);return this.numberFormatter.format(e)};parseInputValue=t=>""===t?0:parseFloat(t.replace(/,/g,""));constructor(){}async init(){return!!document.getElementById("pbry-savings-goal-calc")&&(this.initialized||(this.initialized=!0,this.setInitialValues(),this.setupEventListeners(),this.isElementorEditor&&(await this.waitForElementReady("#savings-goal-chart"),await this.waitForInputsReady(),this.setupResizeObserver()),this.calculate()),!0)}setInitialValues(){document.getElementById("savings-goal").value=this.formatInputValue("15000"),document.getElementById("time-to-goal").value="5",document.getElementById("current-savings").value=this.formatInputValue("0"),document.getElementById("expected-return").value="3",document.getElementById("tax-rate").value="25"}setupEventListeners(){const t=(t,e)=>{let a;return(...i)=>{clearTimeout(a),a=setTimeout((()=>t.apply(this,i)),e)}};["savings-goal","time-to-goal","current-savings","expected-return","tax-rate"].forEach((e=>{const a=document.getElementById(e);a&&(a.addEventListener("blur",(t=>{"time-to-goal"!==e&&"expected-return"!==e&&"tax-rate"!==e&&(t.target.value=this.formatInputValue(this.parseInputValue(t.target.value)))})),a.addEventListener("input",t((()=>{if("time-to-goal"!==e&&"expected-return"!==e&&"tax-rate"!==e){const t=a.selectionStart,e=this.formatInputValue(this.parseInputValue(a.value));a.value=e;const i=(a.value.substring(0,t).match(/,/g)||[]).length,n=t+((e.substring(0,t).match(/,/g)||[].length)-i);a.setSelectionRange(n,n)}this.calculate()}),300)))}))}calculate(){const t=this.parseInputValue(document.getElementById("savings-goal").value),e=parseFloat(document.getElementById("time-to-goal").value)||0,a=Math.round(12*e),i=this.parseInputValue(document.getElementById("current-savings").value),n=(parseFloat(document.getElementById("expected-return").value)||0)/100/12*((100-(parseFloat(document.getElementById("tax-rate").value)||0))/100),o=this.calculateRequiredMonthly(i,t,n,a),s=12*o,r=this.calculateProjection(i,o,n,a,t);this.displayResults(r,o,s),this.createChart(r,e)}calculateRequiredMonthly(t,e,a,i){if(i<=0)return 0;const n=Math.pow(1+a,i);return 0===a?(e-t)/i:(e-t*n)/((n-1)/a)}calculateProjection(t,e,a,i,n){let o=t;const s=[],r=[];for(let t=1;t<=i;t++){const i=o*a;o+=i+e,r.push({x:t,y:o}),s.push({month:t,balance:o,monthlyAddition:e,interest:i})}return{projection:s,cumulativeData:r,goalAmount:n,projectedTotal:o}}displayResults(t,e,a){this.updateElementIfExists("required-monthly",this.numberFormatter.format(e)),this.updateElementIfExists("required-annual",this.numberFormatter.format(a)),this.updateElementIfExists("goal-amount",this.numberFormatter.format(t.goalAmount))}updateElementIfExists(t,e){const a=document.getElementById(t);a&&(a.textContent=e)}createChart(t,e){try{const a=document.getElementById("savings-goal-chart");if((!a||0===a.offsetWidth||0===a.offsetHeight)&&this.isElementorEditor)return void setTimeout((()=>this.createChart(t,e)),100);const i=t.cumulativeData.map((t=>({x:t.x/12,y:t.y||0}))),n={series:[{name:"Projected Savings",type:"line",data:i},{name:"Goal",type:"line",data:t.cumulativeData.map((e=>({x:e.x/12,y:t.goalAmount||0})))}],chart:{height:350,type:"line",stacked:!1,width:a?a.offsetWidth:"100%",toolbar:{show:!1},animations:{enabled:!0,easing:"easeinout",speed:800}},stroke:{width:[3,2],curve:"smooth",dashArray:[0,5]},colors:[this.getChartColor("cumulative"),this.getChartColor("goal_line")],labels:t.cumulativeData.map((t=>`Year ${(t.x/12).toFixed(1)}`)),xaxis:{type:"numeric",title:{text:"Years",style:{fontSize:"12px",fontWeight:this.setFontWeight(),fontFamily:this.setFont()}},labels:{formatter:function(t){return Math.floor(t).toString()},style:{fontSize:"12px",fontWeight:this.setFontWeight(),fontFamily:this.setFont()}},tickAmount:e>10?10:e,min:0,max:e},yaxis:{title:{text:"Amount ($)",style:{fontSize:"12px",fontWeight:this.setFontWeight(),fontFamily:this.setFont()}}
1,labels:{formatter:function(t){return"$"+t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})},style:{fontSize:"12px",fontWeight:this.setFontWeight(),fontFamily:this.setFont()}},min:0},tooltip:{shared:!0,intersect:!1,y:{formatter:function(t){return t?"$"+t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}):"$0.00"}},custom:function({series:t,seriesIndex:e,dataPointIndex:a,w:i}){const n=i.globals.series[0][a],o=i.globals.series[1][a],s=t=>t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2});return`\n                        <div class="apexcharts-tooltip-box" style="padding: 8px; background: #fff; border: 1px solid #ddd; border-radius: 4px; box-shadow: 0 2px 6px rgba(0,0,0,0.1)">\n                           \n                            <div style="margin-bottom: 2px">\n                                <span style="color: ${i.config.colors[0]}; font-weight: 500">●</span>\n                                <span style="font-weight: 500">Projected: </span>$${s(n)}\n                            </div>\n                            <div style="margin-bottom: 2px">\n                                <span style="color: ${i.config.colors[1]}; font-weight: 500">●</span>\n                                <span style="font-weight: 500">Goal: </span>$${s(o)}\n                            </div>\n                        </div>\n                    `}},legend:{position:"top",horizontalAlign:"left",offsetX:40,markers:{width:12,height:12,radius:0},itemMargin:{horizontal:10,vertical:5},onItemClick:{toggleDataSeries:!1},onItemHover:{highlightDataSeries:!0}}};if(this.chart){if(!this.isElementorEditor)return void this.chart.updateOptions(n);this.chart.destroy(),this.chart=null}this.chart=new ApexCharts(a,n),this.chart.render()}catch(a){this.chart&&(this.chart.destroy(),this.chart=null),setTimeout((()=>this.createChart(t,e)),500)}}getChartColor(t){const e={cumulative:"#008FFB",goal_line:"#FF4560"};if(void 0!==window.savingsGoalChartData)switch(t){case"cumulative":return window.savingsGoalChartData.cumulative_color||e.cumulative;case"goal_line":return window.savingsGoalChartData.goal_line_color||e.goal_line;default:return e[t]}return e[t]}setFont(){return"undefined"!=typeof savingsGoalChartData&&savingsGoalChartData.fontFamily||"sans-serif"}setFontWeight(){return"undefined"!=typeof savingsGoalChartData&&savingsGoalChartData.fontWeight||"normal"}async initCharts(){if(!(this.chartRetryCount>=this.config.retryLimit)){if("undefined"==typeof ApexCharts)return this.chartRetryCount++,void setTimeout((()=>this.initCharts()),this.config.chartLoadDelay);try{this.calculate()}catch(t){this.chartRetryCount++,setTimeout((()=>this.initCharts()),this.config.chartLoadDelay)}}}}document.addEventListener("DOMContentLoaded",(function(){const t=new SavingsGoalCalculator;if("undefined"!=typeof elementorFrontend&&elementorFrontend.isEditMode()){t.isElementorEditor=!0,window.savingsGoalChartData=window.savingsGoalChartData||{cumulative_color:"#008FFB",goal_line_color:"#FF4560",fontFamily:"sans-serif",fontWeight:"normal"};const e=()=>{t.init().then((()=>{setTimeout((()=>t.initCharts()),300)}))};if(document.getElementById("pbry-savings-goal-calc"))e();else{new MutationObserver((function(t,a){document.getElementById("pbry-savings-goal-calc")&&(e(),a.disconnect())})).observe(document.body,{childList:!0,subtree:!0})}}else t.init()}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.