|  | @ -13,6 +13,7 @@ import { | 
			
		
	
		
		
			
				
					|  |  |   ViewChild |  |  |   ViewChild | 
			
		
	
		
		
			
				
					|  |  | } from '@angular/core'; |  |  | } from '@angular/core'; | 
			
		
	
		
		
			
				
					|  |  | import { FormBuilder, FormControl } from '@angular/forms'; |  |  | import { FormBuilder, FormControl } from '@angular/forms'; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | import { MatDatepicker } from '@angular/material/datepicker'; | 
			
		
	
		
		
			
				
					|  |  | import { |  |  | import { | 
			
		
	
		
		
			
				
					|  |  |   getTooltipOptions, |  |  |   getTooltipOptions, | 
			
		
	
		
		
			
				
					|  |  |   transformTickToAbbreviation |  |  |   transformTickToAbbreviation | 
			
		
	
	
		
		
			
				
					|  | @ -28,17 +29,25 @@ import { | 
			
		
	
		
		
			
				
					|  |  |   Tooltip |  |  |   Tooltip | 
			
		
	
		
		
			
				
					|  |  | } from 'chart.js'; |  |  | } from 'chart.js'; | 
			
		
	
		
		
			
				
					|  |  | import * as Color from 'color'; |  |  | import * as Color from 'color'; | 
			
		
	
		
		
			
				
					
					|  |  | import { getMonth } from 'date-fns'; |  |  | import { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |   add, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   addYears, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   getMonth, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   setMonth, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   setYear, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   startOfMonth, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   sub | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } from 'date-fns'; | 
			
		
	
		
		
			
				
					|  |  | import { isNumber } from 'lodash'; |  |  | import { isNumber } from 'lodash'; | 
			
		
	
		
		
			
				
					|  |  | import { Subject, takeUntil } from 'rxjs'; |  |  | import { Subject, takeUntil } from 'rxjs'; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | import { FireCalculatorService } from './fire-calculator.service'; |  |  | import { FireCalculatorService } from './fire-calculator.service'; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | @Component({ |  |  | @Component({ | 
			
		
	
		
		
			
				
					|  |  |   selector: 'gf-fire-calculator', |  |  |  | 
			
		
	
		
		
			
				
					|  |  |   changeDetection: ChangeDetectionStrategy.OnPush, |  |  |   changeDetection: ChangeDetectionStrategy.OnPush, | 
			
		
	
		
		
			
				
					
					|  |  |   templateUrl: './fire-calculator.component.html', |  |  |   selector: 'gf-fire-calculator', | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |   styleUrls: ['./fire-calculator.component.scss'] |  |  |   styleUrls: ['./fire-calculator.component.scss'], | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |   templateUrl: './fire-calculator.component.html' | 
			
		
	
		
		
			
				
					|  |  | }) |  |  | }) | 
			
		
	
		
		
			
				
					|  |  | export class FireCalculatorComponent |  |  | export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |   implements AfterViewInit, OnChanges, OnDestroy |  |  |   implements AfterViewInit, OnChanges, OnDestroy | 
			
		
	
	
		
		
			
				
					|  | @ -49,8 +58,12 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |   @Input() fireWealth: number; |  |  |   @Input() fireWealth: number; | 
			
		
	
		
		
			
				
					|  |  |   @Input() hasPermissionToUpdateUserSettings: boolean; |  |  |   @Input() hasPermissionToUpdateUserSettings: boolean; | 
			
		
	
		
		
			
				
					|  |  |   @Input() locale: string; |  |  |   @Input() locale: string; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   @Input() projectedTotalAmount = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   @Input() retirementDate: Date; | 
			
		
	
		
		
			
				
					|  |  |   @Input() savingsRate = 0; |  |  |   @Input() savingsRate = 0; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   @Output() projectedTotalAmountChanged = new EventEmitter<number>(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   @Output() retirementDateChanged = new EventEmitter<Date>(); | 
			
		
	
		
		
			
				
					|  |  |   @Output() savingsRateChanged = new EventEmitter<number>(); |  |  |   @Output() savingsRateChanged = new EventEmitter<number>(); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   @ViewChild('chartCanvas') chartCanvas; |  |  |   @ViewChild('chartCanvas') chartCanvas; | 
			
		
	
	
		
		
			
				
					|  | @ -59,13 +72,17 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |     annualInterestRate: new FormControl<number>(undefined), |  |  |     annualInterestRate: new FormControl<number>(undefined), | 
			
		
	
		
		
			
				
					|  |  |     paymentPerPeriod: new FormControl<number>(undefined), |  |  |     paymentPerPeriod: new FormControl<number>(undefined), | 
			
		
	
		
		
			
				
					|  |  |     principalInvestmentAmount: new FormControl<number>(undefined), |  |  |     principalInvestmentAmount: new FormControl<number>(undefined), | 
			
		
	
		
		
			
				
					
					|  |  |     time: new FormControl<number>(undefined) |  |  |     projectedTotalAmount: new FormControl<number>(undefined), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |     retirementDate: new FormControl<Date>(undefined) | 
			
		
	
		
		
			
				
					|  |  |   }); |  |  |   }); | 
			
		
	
		
		
			
				
					|  |  |   public chart: Chart<'bar'>; |  |  |   public chart: Chart<'bar'>; | 
			
		
	
		
		
			
				
					|  |  |   public isLoading = true; |  |  |   public isLoading = true; | 
			
		
	
		
		
			
				
					
					|  |  |   public projectedTotalAmount: number; |  |  |   public periodsToRetire = 0; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   private readonly CONTRIBUTION_PERIOD = 12; |  |  |   private readonly CONTRIBUTION_PERIOD = 12; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private readonly DEFAULT_RETIREMENT_DATE = startOfMonth( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     addYears(new Date(), 10) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   ); | 
			
		
	
		
		
			
				
					|  |  |   private unsubscribeSubject = new Subject<void>(); |  |  |   private unsubscribeSubject = new Subject<void>(); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   public constructor( |  |  |   public constructor( | 
			
		
	
	
		
		
			
				
					|  | @ -86,7 +103,8 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |         annualInterestRate: 5, |  |  |         annualInterestRate: 5, | 
			
		
	
		
		
			
				
					|  |  |         paymentPerPeriod: this.savingsRate, |  |  |         paymentPerPeriod: this.savingsRate, | 
			
		
	
		
		
			
				
					|  |  |         principalInvestmentAmount: 0, |  |  |         principalInvestmentAmount: 0, | 
			
		
	
		
		
			
				
					
					|  |  |         time: 10 |  |  |         projectedTotalAmount: this.projectedTotalAmount, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |         retirementDate: this.retirementDate ?? this.DEFAULT_RETIREMENT_DATE | 
			
		
	
		
		
			
				
					|  |  |       }, |  |  |       }, | 
			
		
	
		
		
			
				
					|  |  |       { |  |  |       { | 
			
		
	
		
		
			
				
					|  |  |         emitEvent: false |  |  |         emitEvent: false | 
			
		
	
	
		
		
			
				
					|  | @ -105,6 +123,18 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |       .subscribe((savingsRate) => { |  |  |       .subscribe((savingsRate) => { | 
			
		
	
		
		
			
				
					|  |  |         this.savingsRateChanged.emit(savingsRate); |  |  |         this.savingsRateChanged.emit(savingsRate); | 
			
		
	
		
		
			
				
					|  |  |       }); |  |  |       }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .get('projectedTotalAmount') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .valueChanges.pipe(takeUntil(this.unsubscribeSubject)) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .subscribe((projectedTotalAmount) => { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.projectedTotalAmountChanged.emit(projectedTotalAmount); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .get('retirementDate') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .valueChanges.pipe(takeUntil(this.unsubscribeSubject)) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       .subscribe((retirementDate) => { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.retirementDateChanged.emit(retirementDate); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       }); | 
			
		
	
		
		
			
				
					|  |  |   } |  |  |   } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   public ngAfterViewInit() { |  |  |   public ngAfterViewInit() { | 
			
		
	
	
		
		
			
				
					|  | @ -113,8 +143,12 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |         // Wait for the chartCanvas
 |  |  |         // Wait for the chartCanvas
 | 
			
		
	
		
		
			
				
					|  |  |         this.calculatorForm.patchValue( |  |  |         this.calculatorForm.patchValue( | 
			
		
	
		
		
			
				
					|  |  |           { |  |  |           { | 
			
		
	
		
		
			
				
					
					|  |  |             principalInvestmentAmount: this.fireWealth, |  |  |             paymentPerPeriod: this.getPMT(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             paymentPerPeriod: this.savingsRate ?? 0 |  |  |             principalInvestmentAmount: this.getP(), | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             projectedTotalAmount: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |               Number(this.getProjectedTotalAmount().toFixed(2)) ?? 0, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             retirementDate: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |               this.getRetirementDate() ?? this.DEFAULT_RETIREMENT_DATE | 
			
		
	
		
		
			
				
					|  |  |           }, |  |  |           }, | 
			
		
	
		
		
			
				
					|  |  |           { |  |  |           { | 
			
		
	
		
		
			
				
					|  |  |             emitEvent: false |  |  |             emitEvent: false | 
			
		
	
	
		
		
			
				
					|  | @ -128,19 +162,32 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     if (this.hasPermissionToUpdateUserSettings === true) { |  |  |     if (this.hasPermissionToUpdateUserSettings === true) { | 
			
		
	
		
		
			
				
					|  |  |       this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); |  |  |       this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .get('projectedTotalAmount') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm.get('retirementDate').enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |     } else { |  |  |     } else { | 
			
		
	
		
		
			
				
					|  |  |       this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); |  |  |       this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .get('projectedTotalAmount') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm.get('retirementDate').disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |   } |  |  |   } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   public ngOnChanges() { |  |  |   public ngOnChanges() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     this.periodsToRetire = this.getPeriodsToRetire(); | 
			
		
	
		
		
			
				
					|  |  |     if (isNumber(this.fireWealth) && this.fireWealth >= 0) { |  |  |     if (isNumber(this.fireWealth) && this.fireWealth >= 0) { | 
			
		
	
		
		
			
				
					|  |  |       setTimeout(() => { |  |  |       setTimeout(() => { | 
			
		
	
		
		
			
				
					|  |  |         // Wait for the chartCanvas
 |  |  |         // Wait for the chartCanvas
 | 
			
		
	
		
		
			
				
					|  |  |         this.calculatorForm.patchValue( |  |  |         this.calculatorForm.patchValue( | 
			
		
	
		
		
			
				
					|  |  |           { |  |  |           { | 
			
		
	
		
		
			
				
					|  |  |             principalInvestmentAmount: this.fireWealth, |  |  |             principalInvestmentAmount: this.fireWealth, | 
			
		
	
		
		
			
				
					
					|  |  |             paymentPerPeriod: this.savingsRate ?? 0 |  |  |             paymentPerPeriod: this.savingsRate ?? 0, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             projectedTotalAmount: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |               Number(this.getProjectedTotalAmount().toFixed(2)) ?? 0, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             retirementDate: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |               this.getRetirementDate() ?? this.DEFAULT_RETIREMENT_DATE | 
			
		
	
		
		
			
				
					|  |  |           }, |  |  |           }, | 
			
		
	
		
		
			
				
					|  |  |           { |  |  |           { | 
			
		
	
		
		
			
				
					|  |  |             emitEvent: false |  |  |             emitEvent: false | 
			
		
	
	
		
		
			
				
					|  | @ -154,11 +201,32 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     if (this.hasPermissionToUpdateUserSettings === true) { |  |  |     if (this.hasPermissionToUpdateUserSettings === true) { | 
			
		
	
		
		
			
				
					|  |  |       this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); |  |  |       this.calculatorForm.get('paymentPerPeriod').enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .get('projectedTotalAmount') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm.get('retirementDate').enable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |     } else { |  |  |     } else { | 
			
		
	
		
		
			
				
					|  |  |       this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); |  |  |       this.calculatorForm.get('paymentPerPeriod').disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .get('projectedTotalAmount') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         .disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       this.calculatorForm.get('retirementDate').disable({ emitEvent: false }); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |   } |  |  |   } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   public setMonthAndYear( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     normalizedMonthAndYear: Date, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     datepicker: MatDatepicker<Date> | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const retirementDate = this.calculatorForm.get('retirementDate').value; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const newRetirementDate = setMonth( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       setYear(retirementDate, normalizedMonthAndYear.getFullYear()), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       normalizedMonthAndYear.getMonth() | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     this.calculatorForm.get('retirementDate').setValue(newRetirementDate); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     datepicker.close(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |   public ngOnDestroy() { |  |  |   public ngOnDestroy() { | 
			
		
	
		
		
			
				
					|  |  |     this.chart?.destroy(); |  |  |     this.chart?.destroy(); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -261,17 +329,22 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |     const labels = []; |  |  |     const labels = []; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Principal investment amount
 |  |  |     // Principal investment amount
 | 
			
		
	
		
		
			
				
					
					|  |  |     const P: number = |  |  |     const P: number = this.getP(); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |       this.calculatorForm.get('principalInvestmentAmount').value || 0; |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Payment per period
 |  |  |     // Payment per period
 | 
			
		
	
		
		
			
				
					
					|  |  |     const PMT = this.calculatorForm.get('paymentPerPeriod').value; |  |  |     const PMT = this.getPMT(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Annual interest rate
 |  |  |     // Annual interest rate
 | 
			
		
	
		
		
			
				
					
					|  |  |     const r: number = this.calculatorForm.get('annualInterestRate').value / 100; |  |  |     const r: number = this.getR(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     // Calculate retirement date
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     // if we want to retire at month x, we need the projectedTotalAmount at month x-1
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const lastPeriodDate = sub(this.getRetirementDate(), { months: 1 }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const yearsToRetire = lastPeriodDate.getFullYear() - currentYear; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Time
 |  |  |     // Time
 | 
			
		
	
		
		
			
				
					
					|  |  |     const t = this.calculatorForm.get('time').value; |  |  |     // +1 to take into account the current year
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |     const t = yearsToRetire + 1; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     for (let year = currentYear; year < currentYear + t; year++) { |  |  |     for (let year = currentYear; year < currentYear + t; year++) { | 
			
		
	
		
		
			
				
					|  |  |       labels.push(year); |  |  |       labels.push(year); | 
			
		
	
	
		
		
			
				
					|  | @ -308,7 +381,7 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |     for (let period = 1; period <= t; period++) { |  |  |     for (let period = 1; period <= t; period++) { | 
			
		
	
		
		
			
				
					|  |  |       const periodInMonths = |  |  |       const periodInMonths = | 
			
		
	
		
		
			
				
					|  |  |         period * this.CONTRIBUTION_PERIOD - monthsPassedInCurrentYear; |  |  |         period * this.CONTRIBUTION_PERIOD - monthsPassedInCurrentYear; | 
			
		
	
		
		
			
				
					
					|  |  |       const { interest, principal, totalAmount } = |  |  |       const { interest, principal } = | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         this.fireCalculatorService.calculateCompoundInterest({ |  |  |         this.fireCalculatorService.calculateCompoundInterest({ | 
			
		
	
		
		
			
				
					|  |  |           P, |  |  |           P, | 
			
		
	
		
		
			
				
					|  |  |           periodInMonths, |  |  |           periodInMonths, | 
			
		
	
	
		
		
			
				
					|  | @ -319,10 +392,6 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |       datasetDeposit.data.push(this.fireWealth); |  |  |       datasetDeposit.data.push(this.fireWealth); | 
			
		
	
		
		
			
				
					|  |  |       datasetInterest.data.push(interest.toNumber()); |  |  |       datasetInterest.data.push(interest.toNumber()); | 
			
		
	
		
		
			
				
					|  |  |       datasetSavings.data.push(principal.minus(this.fireWealth).toNumber()); |  |  |       datasetSavings.data.push(principal.minus(this.fireWealth).toNumber()); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |       if (period === t) { |  |  |  | 
			
		
	
		
		
			
				
					|  |  |         this.projectedTotalAmount = totalAmount.toNumber(); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |       } |  |  |  | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     return { |  |  |     return { | 
			
		
	
	
		
		
			
				
					|  | @ -330,4 +399,67 @@ export class FireCalculatorComponent | 
			
		
	
		
		
			
				
					|  |  |       datasets: [datasetDeposit, datasetSavings, datasetInterest] |  |  |       datasets: [datasetDeposit, datasetSavings, datasetInterest] | 
			
		
	
		
		
			
				
					|  |  |     }; |  |  |     }; | 
			
		
	
		
		
			
				
					|  |  |   } |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getP() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return this.fireWealth || 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getPeriodsToRetire(): number { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     if (this.projectedTotalAmount) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       const periods = this.fireCalculatorService.calculatePeriodsToRetire({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         P: this.getP(), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         totalAmount: this.projectedTotalAmount, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         PMT: this.getPMT(), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         r: this.getR() | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       return periods; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       const today = new Date(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       const retirementDate = | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.retirementDate ?? this.DEFAULT_RETIREMENT_DATE; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       return ( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         12 * (retirementDate.getFullYear() - today.getFullYear()) + | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         retirementDate.getMonth() - | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         today.getMonth() | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       ); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getPMT() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return this.savingsRate ?? 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getProjectedTotalAmount() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     if (this.projectedTotalAmount) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       return this.projectedTotalAmount || 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       const { totalAmount } = | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.fireCalculatorService.calculateCompoundInterest({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |           P: this.getP(), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |           periodInMonths: this.periodsToRetire, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |           PMT: this.getPMT(), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |           r: this.getR() | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       return totalAmount.toNumber(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getR() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return this.calculatorForm.get('annualInterestRate').value / 100; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   private getRetirementDate(): Date { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const monthsToRetire = this.periodsToRetire % 12; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const yearsToRetire = Math.floor(this.periodsToRetire / 12); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return startOfMonth( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       add(new Date(), { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         months: monthsToRetire, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         years: yearsToRetire | 
			
		
	
		
		
			
				
					|  |  |  |  |  |       }) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
	
		
		
			
				
					|  | 
 |