@eric-emg/symphiq-components 1.2.193 → 1.2.195

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { ViewModeEnum, MetricStatusEnum, TrendDirectionEnum, CompetitiveScoreEnum, ChartTypeEnum, IconSourceEnum, ProfileAnalysisRecommendationPriorityEnum, ProfileItemTypeEnum, PriceVsCompetitorsEnum, DifferentiationStrengthEnum, ThreatLevelEnum, normalizeToV3, MetricEnum, FocusAreaDetailStatusEnum, FocusAreaDomainEnumUtil, FocusAreaDomainEnum, ShopDataLoadStatusEnum, DimensionEnum, UiDataPeriodEnum, UiDataComparePeriodEnum, AiDynamicContentStatusEnum, FocusAreaHealthEnum, ProfileAnalysisPriorityEnum, CapabilityStateEnum, QuadrantEnum, AdvantageEnum, OverallGradeEnum, OperationalMaturityEnum, ProfileAnalysisEffortLevelEnum, ProfileAnalysisImpactLevelEnum, ProfileAnalysisTypeEnum, LineChartUseCaseEnum, BarChartUseCaseEnum } from '@jebgem/model';
1
+ import { ViewModeEnum, MetricStatusEnum, TrendDirectionEnum, CompetitiveScoreEnum, MetricEnum, DimensionEnum, UiDataPeriodEnum, UiDataComparePeriodEnum, ChartTypeEnum, IconSourceEnum, ProfileAnalysisRecommendationPriorityEnum, ProfileItemTypeEnum, PriceVsCompetitorsEnum, DifferentiationStrengthEnum, ThreatLevelEnum, normalizeToV3, FocusAreaDetailStatusEnum, FocusAreaDomainEnumUtil, FocusAreaDomainEnum, ShopDataLoadStatusEnum, MetricEnumUtil, NumberTypeEnum, AiDynamicContentStatusEnum, FocusAreaHealthEnum, ProfileAnalysisPriorityEnum, CapabilityStateEnum, QuadrantEnum, AdvantageEnum, OverallGradeEnum, OperationalMaturityEnum, ProfileAnalysisEffortLevelEnum, ProfileAnalysisImpactLevelEnum, ProfileAnalysisTypeEnum, LineChartUseCaseEnum, BarChartUseCaseEnum } from '@jebgem/model';
2
2
  export * from '@jebgem/model';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, signal, computed, input, ChangeDetectionStrategy, Component, output, inject, ElementRef, Renderer2, effect, Directive, HostListener, untracked, ViewChild, PLATFORM_ID, Inject, Input } from '@angular/core';
@@ -2535,8 +2535,663 @@ class ConfettiService {
2535
2535
  }]
2536
2536
  }], null, null); })();
2537
2537
 
2538
+ function getCurrentYearStart() {
2539
+ const now = new Date();
2540
+ return new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0);
2541
+ }
2542
+ function getCurrentYearEnd() {
2543
+ const now = new Date();
2544
+ return new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999);
2545
+ }
2546
+ function getPriorYearStart() {
2547
+ const now = new Date();
2548
+ return new Date(now.getFullYear() - 1, 0, 1, 0, 0, 0, 0);
2549
+ }
2550
+ function getPriorYearEnd() {
2551
+ const now = new Date();
2552
+ return new Date(now.getFullYear() - 1, 11, 31, 23, 59, 59, 999);
2553
+ }
2554
+ function isCurrentYearTarget(target) {
2555
+ if (!target.startDate || !target.endDate) {
2556
+ return false;
2557
+ }
2558
+ const currentYearStart = getCurrentYearStart();
2559
+ const currentYearEnd = getCurrentYearEnd();
2560
+ const targetStart = new Date(target.startDate);
2561
+ const targetEnd = new Date(target.endDate);
2562
+ return (targetStart.getTime() === currentYearStart.getTime() &&
2563
+ targetEnd.getTime() === currentYearEnd.getTime());
2564
+ }
2565
+ function formatCurrency(value, currencySymbol = '$') {
2566
+ return `${currencySymbol}${value.toLocaleString('en-US', {
2567
+ minimumFractionDigits: 0,
2568
+ maximumFractionDigits: 0
2569
+ })}`;
2570
+ }
2571
+ function formatPercentage(value, decimals = 1) {
2572
+ return `${value.toFixed(decimals)}%`;
2573
+ }
2574
+ function formatNumber(value) {
2575
+ return value.toLocaleString('en-US', {
2576
+ minimumFractionDigits: 0,
2577
+ maximumFractionDigits: 0
2578
+ });
2579
+ }
2580
+
2581
+ function calculateMetricTargetsFromRevenue(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues) {
2582
+ const revenuePercentageIncrease = ((revenueTarget - priorYearRevenue) / priorYearRevenue) * 100;
2583
+ const metricCalculations = [];
2584
+ const sortedFunnelMetrics = [...funnelMetrics].sort((a, b) => {
2585
+ const aFunnel = a.funnelInd ?? 999;
2586
+ const bFunnel = b.funnelInd ?? 999;
2587
+ if (aFunnel !== bFunnel)
2588
+ return aFunnel - bFunnel;
2589
+ const aRelated = a.relatedInd ?? 999;
2590
+ const bRelated = b.relatedInd ?? 999;
2591
+ return aRelated - bRelated;
2592
+ });
2593
+ const funnelStages = getUniqueFunnelStages(sortedFunnelMetrics);
2594
+ const numFunnelStages = funnelStages.length;
2595
+ const revenueIncreaseFactor = revenueTarget / priorYearRevenue;
2596
+ const perStageFactor = Math.pow(revenueIncreaseFactor, 1 / numFunnelStages);
2597
+ const funnelStageMetrics = new Map();
2598
+ sortedFunnelMetrics.forEach(fm => {
2599
+ if (fm.funnelMetric) {
2600
+ if (!funnelStageMetrics.has(fm.funnelMetric)) {
2601
+ funnelStageMetrics.set(fm.funnelMetric, []);
2602
+ }
2603
+ funnelStageMetrics.get(fm.funnelMetric).push(fm);
2604
+ }
2605
+ });
2606
+ const stagePercentageIncrease = (perStageFactor - 1) * 100;
2607
+ sortedFunnelMetrics.forEach((funnelMetric) => {
2608
+ const metric = funnelMetric.relatedMetric;
2609
+ if (!metric)
2610
+ return;
2611
+ const currentValue = baselineValues.get(metric) || 0;
2612
+ const isFunnelStage = funnelMetric.funnelMetric === metric;
2613
+ let percentageIncrease;
2614
+ let targetValue;
2615
+ if (metric === MetricEnum.BOUNCE_RATE) {
2616
+ percentageIncrease = -stagePercentageIncrease;
2617
+ targetValue = currentValue * (1 + percentageIncrease / 100);
2618
+ }
2619
+ else if (isDerivedMetric$1(metric)) {
2620
+ percentageIncrease = 0;
2621
+ targetValue = currentValue;
2622
+ }
2623
+ else {
2624
+ percentageIncrease = stagePercentageIncrease;
2625
+ targetValue = currentValue * perStageFactor;
2626
+ }
2627
+ metricCalculations.push({
2628
+ metric,
2629
+ funnelMetric: funnelMetric.funnelMetric,
2630
+ currentValue,
2631
+ targetValue,
2632
+ percentageIncrease,
2633
+ isFunnelStage,
2634
+ funnelInd: funnelMetric.funnelInd,
2635
+ relatedInd: funnelMetric.relatedInd,
2636
+ description: funnelMetric.relatedMetricDescription
2637
+ });
2638
+ });
2639
+ return {
2640
+ revenueTarget,
2641
+ revenuePercentageIncrease,
2642
+ metricCalculations
2643
+ };
2644
+ }
2645
+ function getUniqueFunnelStages(funnelMetrics) {
2646
+ const stages = [];
2647
+ const seen = new Set();
2648
+ funnelMetrics.forEach(fm => {
2649
+ if (fm.funnelMetric && fm.funnelMetric === fm.relatedMetric && !seen.has(fm.funnelMetric)) {
2650
+ seen.add(fm.funnelMetric);
2651
+ stages.push(fm.funnelMetric);
2652
+ }
2653
+ });
2654
+ return stages;
2655
+ }
2656
+ const DERIVED_METRICS$1 = new Set([
2657
+ MetricEnum.REVENUE_PER_PRODUCT_VIEW,
2658
+ MetricEnum.REVENUE_PER_ADD_TO_CART,
2659
+ MetricEnum.REVENUE_PER_CHECKOUT
2660
+ ]);
2661
+ function isDerivedMetric$1(metric) {
2662
+ return DERIVED_METRICS$1.has(metric);
2663
+ }
2664
+ function generateTargetsFromCalculations(shopId, calculations) {
2665
+ const startDate = getCurrentYearStart();
2666
+ const endDate = getCurrentYearEnd();
2667
+ return calculations.map((calc) => ({
2668
+ shopId,
2669
+ metric: calc.metric,
2670
+ amount: calc.targetValue,
2671
+ startDate,
2672
+ endDate
2673
+ }));
2674
+ }
2675
+ function groupMetricsByFunnelStage(calculations) {
2676
+ const grouped = new Map();
2677
+ calculations.forEach((calc) => {
2678
+ if (calc.funnelMetric) {
2679
+ if (!grouped.has(calc.funnelMetric)) {
2680
+ grouped.set(calc.funnelMetric, []);
2681
+ }
2682
+ grouped.get(calc.funnelMetric).push(calc);
2683
+ }
2684
+ });
2685
+ return grouped;
2686
+ }
2687
+ function getFunnelStageMetrics(calculations) {
2688
+ return calculations.filter((calc) => calc.isFunnelStage);
2689
+ }
2690
+
2691
+ function transformUiDataToChartSeries(mainUiData, ytdComparisonUiData, metricToExtract) {
2692
+ const series = [];
2693
+ if (ytdComparisonUiData?.convertedDataResults) {
2694
+ const priorYearSeries = extractSeriesFromConvertedData(ytdComparisonUiData.convertedDataResults, metricToExtract, 'Prior Year');
2695
+ if (priorYearSeries) {
2696
+ series.push(priorYearSeries);
2697
+ }
2698
+ }
2699
+ if (mainUiData?.convertedDataResults) {
2700
+ const currentYearSeries = extractSeriesFromConvertedData(mainUiData.convertedDataResults, metricToExtract, 'Current Year');
2701
+ if (currentYearSeries) {
2702
+ series.push(currentYearSeries);
2703
+ }
2704
+ }
2705
+ return series;
2706
+ }
2707
+ function extractSeriesFromConvertedData(convertedData, metricToExtract, seriesName) {
2708
+ const metricIndex = convertedData.metrics?.indexOf(metricToExtract);
2709
+ if (metricIndex === undefined || metricIndex === -1)
2710
+ return null;
2711
+ const dimensionIndex = convertedData.dimensions?.indexOf(DimensionEnum.MONTH);
2712
+ if (dimensionIndex === undefined || dimensionIndex === -1)
2713
+ return null;
2714
+ const dataPoints = [];
2715
+ convertedData.rows?.forEach((row) => {
2716
+ const monthValue = row.dimensionValues?.[dimensionIndex];
2717
+ const metricValue = parseFloat(row.metricValues?.[metricIndex] || '0');
2718
+ if (monthValue) {
2719
+ dataPoints.push({
2720
+ category: monthValue,
2721
+ value: metricValue,
2722
+ displayLabel: formatMonthLabel(monthValue)
2723
+ });
2724
+ }
2725
+ });
2726
+ return {
2727
+ name: seriesName,
2728
+ data: sortDataByMonth(dataPoints)
2729
+ };
2730
+ }
2731
+ function formatMonthLabel(monthValue) {
2732
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
2733
+ const monthNum = parseInt(monthValue, 10);
2734
+ if (monthNum >= 1 && monthNum <= 12) {
2735
+ return months[monthNum - 1];
2736
+ }
2737
+ return monthValue;
2738
+ }
2739
+ function sortDataByMonth(data) {
2740
+ return data.sort((a, b) => {
2741
+ const aMonth = parseInt(a.category, 10);
2742
+ const bMonth = parseInt(b.category, 10);
2743
+ return aMonth - bMonth;
2744
+ });
2745
+ }
2746
+ function transformTrendUiDataToChartSeries(trendUiData, metricToExtract) {
2747
+ if (!trendUiData?.convertedDataResults) {
2748
+ return [];
2749
+ }
2750
+ const convertedData = trendUiData.convertedDataResults;
2751
+ const metricIndex = convertedData.metrics?.indexOf(metricToExtract);
2752
+ if (metricIndex === undefined || metricIndex === -1)
2753
+ return [];
2754
+ const dateIndex = convertedData.dimensions?.indexOf(DimensionEnum.DATE);
2755
+ const monthIndex = convertedData.dimensions?.indexOf(DimensionEnum.MONTH);
2756
+ const dimensionIndex = dateIndex !== undefined && dateIndex !== -1
2757
+ ? dateIndex
2758
+ : (monthIndex !== undefined && monthIndex !== -1 ? monthIndex : -1);
2759
+ if (dimensionIndex === -1)
2760
+ return [];
2761
+ const currentYear = new Date().getFullYear();
2762
+ const priorYear = currentYear - 1;
2763
+ const priorYearPoints = [];
2764
+ const currentYearPoints = [];
2765
+ convertedData.rows?.forEach((row) => {
2766
+ const dimValue = row.dimensionValues?.[dimensionIndex];
2767
+ const metricValue = parseFloat(row.metricValues?.[metricIndex] || '0');
2768
+ if (dimValue) {
2769
+ let year;
2770
+ let month;
2771
+ if (dimValue.includes('-')) {
2772
+ const parts = dimValue.split('-');
2773
+ year = parseInt(parts[0], 10);
2774
+ month = parseInt(parts[1], 10);
2775
+ }
2776
+ else if (dimValue.length >= 6) {
2777
+ year = parseInt(dimValue.substring(0, 4), 10);
2778
+ month = parseInt(dimValue.substring(4, 6), 10);
2779
+ }
2780
+ else {
2781
+ month = parseInt(dimValue, 10);
2782
+ year = currentYear;
2783
+ }
2784
+ const point = {
2785
+ category: String(month),
2786
+ value: metricValue,
2787
+ displayLabel: formatMonthLabel(String(month))
2788
+ };
2789
+ if (year === priorYear) {
2790
+ priorYearPoints.push(point);
2791
+ }
2792
+ else if (year === currentYear) {
2793
+ currentYearPoints.push(point);
2794
+ }
2795
+ }
2796
+ });
2797
+ const series = [];
2798
+ if (priorYearPoints.length > 0) {
2799
+ series.push({
2800
+ name: String(priorYear),
2801
+ data: aggregateAndSortByMonth(priorYearPoints)
2802
+ });
2803
+ }
2804
+ if (currentYearPoints.length > 0) {
2805
+ series.push({
2806
+ name: String(currentYear),
2807
+ data: aggregateAndSortByMonth(currentYearPoints)
2808
+ });
2809
+ }
2810
+ return series;
2811
+ }
2812
+ function aggregateAndSortByMonth(points) {
2813
+ const monthMap = new Map();
2814
+ points.forEach(point => {
2815
+ const existing = monthMap.get(point.category);
2816
+ if (existing) {
2817
+ existing.value += point.value;
2818
+ }
2819
+ else {
2820
+ monthMap.set(point.category, { ...point });
2821
+ }
2822
+ });
2823
+ return sortDataByMonth(Array.from(monthMap.values()));
2824
+ }
2825
+ function getConvertedDataForSource(uiData, source) {
2826
+ if (!uiData)
2827
+ return undefined;
2828
+ const periodInfo = uiData.periodInfo;
2829
+ let result;
2830
+ switch (source) {
2831
+ case 'current':
2832
+ result = uiData.convertedDataResults;
2833
+ break;
2834
+ case 'compare':
2835
+ result = uiData.convertedDataResultsCompare;
2836
+ break;
2837
+ case 'priorYear':
2838
+ if (periodInfo?.period === UiDataPeriodEnum.THIS_YEAR &&
2839
+ periodInfo?.comparePeriod === UiDataComparePeriodEnum.PREVIOUS_PERIOD) {
2840
+ result = uiData.convertedDataResultsCompare;
2841
+ }
2842
+ else if (periodInfo?.period === UiDataPeriodEnum.THIS_AND_LAST_YEAR) {
2843
+ result = uiData.convertedDataResults;
2844
+ }
2845
+ else if (periodInfo?.comparePeriod === UiDataComparePeriodEnum.SAME_PERIOD_LAST_YEAR) {
2846
+ result = uiData.convertedDataResultsCompare;
2847
+ }
2848
+ else if (periodInfo?.comparePeriod === UiDataComparePeriodEnum.PREVIOUS_PERIOD) {
2849
+ result = uiData.convertedDataResultsCompare;
2850
+ }
2851
+ else {
2852
+ result = uiData.convertedDataResultsCompare;
2853
+ }
2854
+ break;
2855
+ }
2856
+ return result;
2857
+ }
2858
+ function sumMetricFromUiData(uiData, metricToSum, source = 'current') {
2859
+ const convertedData = getConvertedDataForSource(uiData, source);
2860
+ if (!convertedData) {
2861
+ return 0;
2862
+ }
2863
+ let total = 0;
2864
+ const metricIndex = convertedData.metrics?.indexOf(metricToSum);
2865
+ if (metricIndex === undefined || metricIndex === -1) {
2866
+ return 0;
2867
+ }
2868
+ convertedData.rows?.forEach((row) => {
2869
+ const rawValue = row.metricValues?.[metricIndex];
2870
+ const metricValue = parseFloat(rawValue || '0');
2871
+ total += metricValue;
2872
+ });
2873
+ return total;
2874
+ }
2875
+
2876
+ function calculateFunnelRatios(funnelMetrics, baselineValues) {
2877
+ const ratios = new Map();
2878
+ const stages = funnelMetrics
2879
+ .filter(fm => fm.funnelMetric === fm.relatedMetric)
2880
+ .sort((a, b) => (a.funnelInd ?? 0) - (b.funnelInd ?? 0));
2881
+ for (let i = 0; i < stages.length - 1; i++) {
2882
+ const fromStage = stages[i].relatedMetric;
2883
+ const toStage = stages[i + 1].relatedMetric;
2884
+ if (fromStage && toStage) {
2885
+ const fromValue = baselineValues.get(fromStage) || 0;
2886
+ const toValue = baselineValues.get(toStage) || 0;
2887
+ if (fromValue > 0) {
2888
+ const ratio = toValue / fromValue;
2889
+ const key = `${fromStage}_to_${toStage}`;
2890
+ ratios.set(key, ratio);
2891
+ }
2892
+ }
2893
+ }
2894
+ return ratios;
2895
+ }
2896
+ function calculateRelatedMetricRatios(funnelMetrics, baselineValues) {
2897
+ const ratios = new Map();
2898
+ const stageGroups = new Map();
2899
+ funnelMetrics.forEach(fm => {
2900
+ if (fm.funnelMetric && fm.relatedMetric && fm.funnelMetric !== fm.relatedMetric) {
2901
+ if (!stageGroups.has(fm.funnelMetric)) {
2902
+ stageGroups.set(fm.funnelMetric, []);
2903
+ }
2904
+ stageGroups.get(fm.funnelMetric).push(fm);
2905
+ }
2906
+ });
2907
+ stageGroups.forEach((relatedMetrics, funnelStage) => {
2908
+ const funnelValue = baselineValues.get(funnelStage) || 0;
2909
+ if (funnelValue > 0) {
2910
+ relatedMetrics.forEach(fm => {
2911
+ if (fm.relatedMetric) {
2912
+ const relatedValue = baselineValues.get(fm.relatedMetric) || 0;
2913
+ const ratio = relatedValue / funnelValue;
2914
+ const key = `${fm.relatedMetric}_to_${funnelStage}`;
2915
+ ratios.set(key, ratio);
2916
+ }
2917
+ });
2918
+ }
2919
+ });
2920
+ return ratios;
2921
+ }
2922
+ function calculateMetricTargetsFromRevenueReverse(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues) {
2923
+ console.log('\n🔄 === REVERSE REVENUE CALCULATOR START ===');
2924
+ console.log('📊 Inputs:');
2925
+ console.log(' - Revenue Target:', revenueTarget);
2926
+ console.log(' - Prior Year Revenue:', priorYearRevenue);
2927
+ console.log(' - Funnel Metrics Count:', funnelMetrics.length);
2928
+ console.log(' - Baseline Values:', Array.from(baselineValues.entries()));
2929
+ const revenuePercentageIncrease = ((revenueTarget - priorYearRevenue) / priorYearRevenue) * 100;
2930
+ console.log(' - Revenue % Increase:', revenuePercentageIncrease.toFixed(2) + '%');
2931
+ const funnelRatios = calculateFunnelRatios(funnelMetrics, baselineValues);
2932
+ console.log('\n📈 Funnel Ratios:', Array.from(funnelRatios.entries()));
2933
+ const relatedRatios = calculateRelatedMetricRatios(funnelMetrics, baselineValues);
2934
+ console.log('📈 Related Metric Ratios:', Array.from(relatedRatios.entries()));
2935
+ const sortedFunnelMetrics = [...funnelMetrics].sort((a, b) => {
2936
+ const aFunnel = a.funnelInd ?? 999;
2937
+ const bFunnel = b.funnelInd ?? 999;
2938
+ if (aFunnel !== bFunnel)
2939
+ return aFunnel - bFunnel;
2940
+ const aRelated = a.relatedInd ?? 999;
2941
+ const bRelated = b.relatedInd ?? 999;
2942
+ return aRelated - bRelated;
2943
+ });
2944
+ const stages = sortedFunnelMetrics
2945
+ .filter(fm => fm.funnelMetric === fm.relatedMetric)
2946
+ .map(fm => fm.relatedMetric)
2947
+ .filter(Boolean);
2948
+ const stageTargets = new Map();
2949
+ console.log('\n🎯 Calculating Stage Targets (Reverse Order):');
2950
+ let currentRevenue = revenueTarget;
2951
+ for (let i = stages.length - 1; i >= 0; i--) {
2952
+ const stage = stages[i];
2953
+ const baseline = baselineValues.get(stage) || 0;
2954
+ if (i === stages.length - 1) {
2955
+ stageTargets.set(stage, currentRevenue);
2956
+ console.log(` Stage ${i} (${stage}): ${currentRevenue.toFixed(2)} (Revenue Stage)`);
2957
+ }
2958
+ else {
2959
+ const nextStage = stages[i + 1];
2960
+ const ratioKey = `${stage}_to_${nextStage}`;
2961
+ const ratio = funnelRatios.get(ratioKey) || 0;
2962
+ if (ratio > 0) {
2963
+ const nextStageTarget = stageTargets.get(nextStage) || 0;
2964
+ currentRevenue = nextStageTarget / ratio;
2965
+ stageTargets.set(stage, currentRevenue);
2966
+ console.log(` Stage ${i} (${stage}): ${currentRevenue.toFixed(2)} (calculated from ${nextStage} with ratio ${ratio.toFixed(4)})`);
2967
+ }
2968
+ else {
2969
+ const increaseNeeded = revenueTarget / baseline;
2970
+ const calculatedValue = baseline * increaseNeeded;
2971
+ stageTargets.set(stage, calculatedValue);
2972
+ console.log(` Stage ${i} (${stage}): ${calculatedValue.toFixed(2)} (fallback: baseline * ${increaseNeeded.toFixed(4)})`);
2973
+ }
2974
+ }
2975
+ }
2976
+ console.log('🎯 Final Stage Targets:', Array.from(stageTargets.entries()));
2977
+ const metricCalculations = [];
2978
+ const stageGroups = new Map();
2979
+ sortedFunnelMetrics.forEach(fm => {
2980
+ if (fm.funnelMetric) {
2981
+ if (!stageGroups.has(fm.funnelMetric)) {
2982
+ stageGroups.set(fm.funnelMetric, []);
2983
+ }
2984
+ stageGroups.get(fm.funnelMetric).push(fm);
2985
+ }
2986
+ });
2987
+ console.log('\n📊 Calculating Individual Metric Targets:');
2988
+ stageGroups.forEach((metrics, funnelStage) => {
2989
+ const stageTarget = stageTargets.get(funnelStage);
2990
+ const stageBaseline = baselineValues.get(funnelStage) || 0;
2991
+ const stageIncrease = stageTarget ? stageTarget - stageBaseline : 0;
2992
+ console.log(`\n 📍 Funnel Stage: ${funnelStage}`);
2993
+ console.log(` - Stage Target: ${stageTarget?.toFixed(2)}`);
2994
+ console.log(` - Stage Baseline: ${stageBaseline.toFixed(2)}`);
2995
+ console.log(` - Stage Increase: ${stageIncrease.toFixed(2)}`);
2996
+ metrics.forEach(fm => {
2997
+ if (!fm.relatedMetric)
2998
+ return;
2999
+ const currentValue = baselineValues.get(fm.relatedMetric) || 0;
3000
+ const isFunnelStage = fm.funnelMetric === fm.relatedMetric;
3001
+ console.log(`\n 🔹 Metric: ${fm.relatedMetric}${isFunnelStage ? ' (STAGE)' : ''}`);
3002
+ console.log(` Current Value: ${currentValue.toFixed(2)}`);
3003
+ let targetValue;
3004
+ let percentageIncrease;
3005
+ if (isFunnelStage && stageTarget !== undefined) {
3006
+ targetValue = stageTarget;
3007
+ percentageIncrease = currentValue > 0 ? ((targetValue - currentValue) / currentValue) * 100 : 0;
3008
+ console.log(` Method: Direct Stage Target`);
3009
+ }
3010
+ else if (fm.relatedMetric === MetricEnum.BOUNCE_RATE) {
3011
+ const stageTargetValue = stageTargets.get(funnelStage) || stageBaseline;
3012
+ const stageIncreaseRatio = stageBaseline > 0 ? stageTargetValue / stageBaseline : 1;
3013
+ targetValue = currentValue / stageIncreaseRatio;
3014
+ percentageIncrease = currentValue > 0 ? ((targetValue - currentValue) / currentValue) * 100 : 0;
3015
+ console.log(` Method: Bounce Rate (inverse)`);
3016
+ console.log(` Stage Increase Ratio: ${stageIncreaseRatio.toFixed(4)}`);
3017
+ }
3018
+ else if (isDerivedMetric(fm.relatedMetric)) {
3019
+ targetValue = currentValue;
3020
+ percentageIncrease = 0;
3021
+ console.log(` Method: Derived Metric (no change)`);
3022
+ }
3023
+ else {
3024
+ const ratioKey = `${fm.relatedMetric}_to_${funnelStage}`;
3025
+ const impactRatio = relatedRatios.get(ratioKey) || 1;
3026
+ const relatedMetrics = metrics.filter(m => m.relatedMetric &&
3027
+ m.relatedMetric !== funnelStage &&
3028
+ !isDerivedMetric(m.relatedMetric) &&
3029
+ m.relatedMetric !== MetricEnum.BOUNCE_RATE);
3030
+ const numRelatedMetrics = relatedMetrics.length;
3031
+ if (numRelatedMetrics > 0 && stageBaseline > 0) {
3032
+ const avgIncreaseNeeded = stageIncrease / numRelatedMetrics;
3033
+ const metricIncreaseNeeded = impactRatio > 0 ? avgIncreaseNeeded / impactRatio : avgIncreaseNeeded;
3034
+ targetValue = currentValue + metricIncreaseNeeded;
3035
+ percentageIncrease = currentValue > 0 ? ((targetValue - currentValue) / currentValue) * 100 : 0;
3036
+ console.log(` Method: Related Metric with Impact Ratio`);
3037
+ console.log(` Num Related Metrics: ${numRelatedMetrics}`);
3038
+ console.log(` Avg Increase Needed: ${avgIncreaseNeeded.toFixed(2)}`);
3039
+ console.log(` Impact Ratio: ${impactRatio.toFixed(4)}`);
3040
+ console.log(` Metric Increase Needed: ${metricIncreaseNeeded.toFixed(2)}`);
3041
+ }
3042
+ else {
3043
+ const stageTargetValue = stageTargets.get(funnelStage) || stageBaseline;
3044
+ const stageIncreaseRatio = stageBaseline > 0 ? stageTargetValue / stageBaseline : 1;
3045
+ targetValue = currentValue * stageIncreaseRatio;
3046
+ percentageIncrease = currentValue > 0 ? ((targetValue - currentValue) / currentValue) * 100 : 0;
3047
+ console.log(` Method: Proportional to Stage`);
3048
+ console.log(` Stage Increase Ratio: ${stageIncreaseRatio.toFixed(4)}`);
3049
+ }
3050
+ }
3051
+ console.log(` ✅ Target Value: ${targetValue.toFixed(2)}`);
3052
+ console.log(` ✅ % Increase: ${percentageIncrease.toFixed(2)}%`);
3053
+ metricCalculations.push({
3054
+ metric: fm.relatedMetric,
3055
+ funnelMetric: fm.funnelMetric,
3056
+ currentValue,
3057
+ targetValue,
3058
+ percentageIncrease,
3059
+ isFunnelStage,
3060
+ funnelInd: fm.funnelInd,
3061
+ relatedInd: fm.relatedInd,
3062
+ description: fm.relatedMetricDescription
3063
+ });
3064
+ });
3065
+ });
3066
+ console.log('\n✅ Total Metric Calculations:', metricCalculations.length);
3067
+ const validation = validateRevenueTarget(revenueTarget, metricCalculations, baselineValues, funnelRatios);
3068
+ console.log('\n🔍 Validation Results:');
3069
+ console.log(' - Target Revenue:', revenueTarget.toFixed(2));
3070
+ console.log(' - Calculated Revenue:', validation.calculatedRevenue.toFixed(2));
3071
+ console.log(' - Difference:', validation.difference.toFixed(2));
3072
+ console.log(' - % Difference:', validation.percentageDifference.toFixed(4) + '%');
3073
+ console.log(' - Within Tolerance:', validation.withinTolerance);
3074
+ let adjustmentApplied = 0;
3075
+ if (Math.abs(validation.difference) > 0.01) {
3076
+ console.log('\n⚙️ Applying Precision Adjustment...');
3077
+ metricCalculations.forEach(calc => {
3078
+ if (calc.isFunnelStage && calc.metric !== MetricEnum.BOUNCE_RATE) {
3079
+ const oldValue = calc.targetValue;
3080
+ calc.targetValue += validation.difference / stages.length;
3081
+ calc.percentageIncrease = calc.currentValue > 0
3082
+ ? ((calc.targetValue - calc.currentValue) / calc.currentValue) * 100
3083
+ : 0;
3084
+ console.log(` Adjusted ${calc.metric}: ${oldValue.toFixed(2)} → ${calc.targetValue.toFixed(2)}`);
3085
+ }
3086
+ });
3087
+ adjustmentApplied = validation.difference;
3088
+ console.log(' Total Adjustment Applied:', adjustmentApplied.toFixed(2));
3089
+ }
3090
+ else {
3091
+ console.log('\n✅ No adjustment needed - within tolerance');
3092
+ }
3093
+ console.log('\n🏁 === REVERSE REVENUE CALCULATOR END ===\n');
3094
+ return {
3095
+ revenueTarget,
3096
+ revenuePercentageIncrease,
3097
+ metricCalculations,
3098
+ adjustmentApplied
3099
+ };
3100
+ }
3101
+ const DERIVED_METRICS = new Set([
3102
+ MetricEnum.REVENUE_PER_PRODUCT_VIEW,
3103
+ MetricEnum.REVENUE_PER_ADD_TO_CART,
3104
+ MetricEnum.REVENUE_PER_CHECKOUT
3105
+ ]);
3106
+ function isDerivedMetric(metric) {
3107
+ return DERIVED_METRICS.has(metric);
3108
+ }
3109
+ function validateRevenueTarget(targetRevenue, calculations, baselineValues, funnelRatios) {
3110
+ const stages = calculations
3111
+ .filter(c => c.isFunnelStage)
3112
+ .sort((a, b) => (a.funnelInd ?? 0) - (b.funnelInd ?? 0));
3113
+ let calculatedRevenue = 0;
3114
+ if (stages.length > 0) {
3115
+ calculatedRevenue = stages[stages.length - 1].targetValue;
3116
+ }
3117
+ const difference = targetRevenue - calculatedRevenue;
3118
+ const percentageDifference = targetRevenue > 0 ? (difference / targetRevenue) * 100 : 0;
3119
+ const withinTolerance = Math.abs(difference) < 0.01 || Math.abs(percentageDifference) < 0.001;
3120
+ return {
3121
+ calculatedRevenue,
3122
+ difference,
3123
+ percentageDifference,
3124
+ withinTolerance
3125
+ };
3126
+ }
3127
+
3128
+ class RevenueCalculatorService {
3129
+ calculateTargetsFromRevenue(revenueTarget, mainUiData, funnelMetrics) {
3130
+ const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
3131
+ const baselineValues = this.extractBaselineValues(mainUiData, funnelMetrics);
3132
+ return calculateMetricTargetsFromRevenue(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues);
3133
+ }
3134
+ calculateTargetsFromPercentage(percentageIncrease, mainUiData, funnelMetrics) {
3135
+ const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
3136
+ const revenueTarget = priorYearRevenue * (1 + percentageIncrease / 100);
3137
+ return this.calculateTargetsFromRevenue(revenueTarget, mainUiData, funnelMetrics);
3138
+ }
3139
+ calculateTargetsFromRevenueWithRatios(revenueTarget, mainUiData, funnelMetrics) {
3140
+ const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
3141
+ const baselineValues = this.extractBaselineValues(mainUiData, funnelMetrics);
3142
+ return calculateMetricTargetsFromRevenueReverse(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues);
3143
+ }
3144
+ calculateTargetsFromPercentageWithRatios(percentageIncrease, mainUiData, funnelMetrics) {
3145
+ const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
3146
+ const revenueTarget = priorYearRevenue * (1 + percentageIncrease / 100);
3147
+ return this.calculateTargetsFromRevenueWithRatios(revenueTarget, mainUiData, funnelMetrics);
3148
+ }
3149
+ extractPriorYearRevenue(mainUiData) {
3150
+ return sumMetricFromUiData(mainUiData, MetricEnum.PURCHASE_REVENUE, 'priorYear');
3151
+ }
3152
+ extractBaselineValues(mainUiData, funnelMetrics) {
3153
+ const baselineValues = new Map();
3154
+ if (!mainUiData) {
3155
+ return baselineValues;
3156
+ }
3157
+ funnelMetrics.forEach(fm => {
3158
+ if (fm.relatedMetric) {
3159
+ const value = sumMetricFromUiData(mainUiData, fm.relatedMetric, 'priorYear');
3160
+ baselineValues.set(fm.relatedMetric, value);
3161
+ }
3162
+ });
3163
+ return baselineValues;
3164
+ }
3165
+ getMetricsByFunnelStage(calculations) {
3166
+ const grouped = new Map();
3167
+ calculations.forEach(calc => {
3168
+ if (calc.isFunnelStage) {
3169
+ if (!grouped.has(calc.metric)) {
3170
+ grouped.set(calc.metric, []);
3171
+ }
3172
+ grouped.get(calc.metric).push(calc);
3173
+ }
3174
+ else if (calc.funnelMetric) {
3175
+ if (!grouped.has(calc.funnelMetric)) {
3176
+ grouped.set(calc.funnelMetric, []);
3177
+ }
3178
+ grouped.get(calc.funnelMetric).push(calc);
3179
+ }
3180
+ });
3181
+ return grouped;
3182
+ }
3183
+ static { this.ɵfac = function RevenueCalculatorService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RevenueCalculatorService)(); }; }
3184
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: RevenueCalculatorService, factory: RevenueCalculatorService.ɵfac, providedIn: 'root' }); }
3185
+ }
3186
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RevenueCalculatorService, [{
3187
+ type: Injectable,
3188
+ args: [{
3189
+ providedIn: 'root'
3190
+ }]
3191
+ }], null, null); })();
3192
+
2538
3193
  const _c0$16 = a0 => ["skeleton-loader", "rounded-lg", "relative", "overflow-hidden", a0];
2539
- const _c1$C = a0 => ["skeleton-shimmer-overlay", "absolute", "inset-0", "bg-gradient-to-r", a0];
3194
+ const _c1$D = a0 => ["skeleton-shimmer-overlay", "absolute", "inset-0", "bg-gradient-to-r", a0];
2540
3195
  class SkeletonLoaderComponent {
2541
3196
  constructor() {
2542
3197
  this.width = input('100%', ...(ngDevMode ? [{ debugName: "width" }] : []));
@@ -2554,7 +3209,7 @@ class SkeletonLoaderComponent {
2554
3209
  i0.ɵɵclassProp("skeleton-shimmer", true)("skeleton-pulse", ctx.pulse());
2555
3210
  i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(10, _c0$16, ctx.isLightMode() ? "bg-slate-200/80" : "bg-slate-700/80"));
2556
3211
  i0.ɵɵadvance();
2557
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(12, _c1$C, ctx.isLightMode() ? "from-transparent via-white/60 to-transparent" : "from-transparent via-slate-500/40 to-transparent"));
3212
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(12, _c1$D, ctx.isLightMode() ? "from-transparent via-white/60 to-transparent" : "from-transparent via-slate-500/40 to-transparent"));
2558
3213
  } }, dependencies: [NgClass], styles: [".skeleton-loader[_ngcontent-%COMP%]{position:relative;overflow:hidden}.skeleton-shimmer-overlay[_ngcontent-%COMP%]{animation:_ngcontent-%COMP%_shimmer 2s infinite cubic-bezier(.4,0,.6,1);transform:translate(-100%)}@keyframes _ngcontent-%COMP%_shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.skeleton-pulse[_ngcontent-%COMP%]{animation:_ngcontent-%COMP%_pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes _ngcontent-%COMP%_pulse{0%,to{opacity:1}50%{opacity:.6}}"], changeDetection: 0 }); }
2559
3214
  }
2560
3215
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SkeletonLoaderComponent, [{
@@ -5496,7 +6151,7 @@ class OverallAssessmentComponent {
5496
6151
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OverallAssessmentComponent, { className: "OverallAssessmentComponent", filePath: "lib/components/funnel-analysis-dashboard/overall-assessment.component.ts", lineNumber: 303 }); })();
5497
6152
 
5498
6153
  const _c0$13 = () => [1, 2, 3];
5499
- const _c1$B = () => [1, 2, 3, 4];
6154
+ const _c1$C = () => [1, 2, 3, 4];
5500
6155
  const _c2$q = () => [];
5501
6156
  function InsightCardComponent_Conditional_0_Conditional_0_For_7_Template(rf, ctx) { if (rf & 1) {
5502
6157
  i0.ɵɵelementStart(0, "div", 7);
@@ -5535,7 +6190,7 @@ function InsightCardComponent_Conditional_0_Conditional_0_Template(rf, ctx) { if
5535
6190
  i0.ɵɵadvance();
5536
6191
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(8, _c0$13));
5537
6192
  i0.ɵɵadvance(3);
5538
- i0.ɵɵrepeater(i0.ɵɵpureFunction0(9, _c1$B));
6193
+ i0.ɵɵrepeater(i0.ɵɵpureFunction0(9, _c1$C));
5539
6194
  } }
5540
6195
  function InsightCardComponent_Conditional_0_Conditional_1_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
5541
6196
  i0.ɵɵnamespaceSVG();
@@ -8234,7 +8889,7 @@ class MetricCardComponent {
8234
8889
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MetricCardComponent, { className: "MetricCardComponent", filePath: "lib/components/funnel-analysis-dashboard/metric-card.component.ts", lineNumber: 537 }); })();
8235
8890
 
8236
8891
  const _c0$12 = () => [1, 2, 3];
8237
- const _c1$A = (a0, a1, a2) => [a0, a1, a2];
8892
+ const _c1$B = (a0, a1, a2) => [a0, a1, a2];
8238
8893
  const _c2$p = (a0, a1) => [a0, a1];
8239
8894
  const _forTrack0$O = ($index, $item) => $item.metric;
8240
8895
  const _forTrack1$7 = ($index, $item) => $item.dimensionValue;
@@ -8446,7 +9101,7 @@ function BreakdownSectionComponent_Conditional_1_For_9_For_27_Template(rf, ctx)
8446
9101
  const ɵ$index_133_r9 = ctx.$index;
8447
9102
  const group_r5 = i0.ɵɵnextContext().$implicit;
8448
9103
  const ctx_r0 = i0.ɵɵnextContext(2);
8449
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(31, _c1$A, ctx_r0.getRowBackgroundClass(metric_r8, ɵ$index_133_r9), ctx_r0.getPriorityDividerClass(metric_r8, ɵ$index_133_r9, group_r5.values), ctx_r0.isLightMode() ? "hover:bg-blue-50" : "hover:bg-slate-700/30"));
9104
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(31, _c1$B, ctx_r0.getRowBackgroundClass(metric_r8, ɵ$index_133_r9), ctx_r0.getPriorityDividerClass(metric_r8, ɵ$index_133_r9, group_r5.values), ctx_r0.isLightMode() ? "hover:bg-blue-50" : "hover:bg-slate-700/30"));
8450
9105
  i0.ɵɵadvance(3);
8451
9106
  i0.ɵɵproperty("ngClass", ctx_r0.isLightMode() ? "text-slate-600 group-hover:text-slate-900" : "text-slate-400 group-hover:text-white")("libSymphiqTooltip", ctx_r0.getBreakdownRowTooltip(metric_r8))("tooltipPosition", "auto");
8452
9107
  i0.ɵɵadvance();
@@ -26701,7 +27356,7 @@ class FunnelWelcomeBannerComponent {
26701
27356
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FunnelWelcomeBannerComponent, { className: "FunnelWelcomeBannerComponent", filePath: "lib/components/funnel-analysis-dashboard/funnel-welcome-banner.component.ts", lineNumber: 113 }); })();
26702
27357
 
26703
27358
  const _c0$W = [[["", "slot", "overall-performance"]], [["", "slot", "performance-metrics"]], [["", "slot", "performance-breakdowns"]], [["", "slot", "competitive-intelligence"]]];
26704
- const _c1$z = ["[slot=overall-performance]", "[slot=performance-metrics]", "[slot=performance-breakdowns]", "[slot=competitive-intelligence]"];
27359
+ const _c1$A = ["[slot=overall-performance]", "[slot=performance-metrics]", "[slot=performance-breakdowns]", "[slot=competitive-intelligence]"];
26705
27360
  class CollapsibleFunnelSectionGroupComponent {
26706
27361
  constructor() {
26707
27362
  this.viewMode = input(ViewModeEnum.LIGHT, ...(ngDevMode ? [{ debugName: "viewMode" }] : []));
@@ -26832,7 +27487,7 @@ class CollapsibleFunnelSectionGroupComponent {
26832
27487
  : 'border-slate-200';
26833
27488
  }
26834
27489
  static { this.ɵfac = function CollapsibleFunnelSectionGroupComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CollapsibleFunnelSectionGroupComponent)(); }; }
26835
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CollapsibleFunnelSectionGroupComponent, selectors: [["symphiq-collapsible-funnel-section-group"]], inputs: { viewMode: [1, "viewMode"] }, ngContentSelectors: _c1$z, decls: 90, vars: 58, consts: [[1, "rounded-2xl", "border", "shadow-lg", "overflow-hidden", 3, "ngClass"], [1, "px-6", "py-5", "border-b", 3, "ngClass"], [1, "flex", "items-center", "justify-between"], [1, "flex", "items-center", "gap-3"], [1, "p-2.5", "rounded-lg", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-5", "h-5"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"], [1, "text-xl", "font-bold", 3, "ngClass"], [1, "text-sm", "mt-0.5", 3, "ngClass"], [1, "p-6", 3, "ngClass"], [1, "mb-6", "p-4", "rounded-xl", "border", "flex", "items-start", "gap-3", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-5", "h-5", "flex-shrink-0", "mt-0.5", 3, "ngClass"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"], [1, "flex-1"], [1, "font-semibold", "text-sm", "mb-1", 3, "ngClass"], [1, "text-sm", "leading-relaxed", 3, "ngClass"], [1, "space-y-3"], [1, "rounded-xl", "border", "overflow-hidden", "transition-all", "duration-200", 3, "id", "ngClass"], ["type", "button", 1, "cursor-pointer", "w-full", "px-5", "py-4", "flex", "items-center", "justify-between", "gap-4", "text-left", "transition-colors", "duration-200", 3, "click", "ngClass"], [1, "flex", "items-center", "gap-3", "flex-1", "min-w-0"], [1, "p-2", "rounded-lg", "flex-shrink-0", "transition-colors", "duration-200", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-4", "h-4"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"], [1, "flex-1", "min-w-0"], [1, "font-semibold", "transition-colors", "duration-200", 3, "ngClass"], [1, "text-sm", "mt-0.5", "transition-colors", "duration-200", 3, "ngClass"], [1, "w-5", "h-5", "flex-shrink-0", "transition-transform", "duration-200", 3, "ngClass"], ["stroke", "currentColor", "stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M19 9l-7 7-7-7"], [1, "grid", "transition-[grid-template-rows]", "duration-300", "ease-in-out"], [1, "overflow-hidden"], [1, "border-t", 3, "ngClass"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"]], template: function CollapsibleFunnelSectionGroupComponent_Template(rf, ctx) { if (rf & 1) {
27490
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CollapsibleFunnelSectionGroupComponent, selectors: [["symphiq-collapsible-funnel-section-group"]], inputs: { viewMode: [1, "viewMode"] }, ngContentSelectors: _c1$A, decls: 90, vars: 58, consts: [[1, "rounded-2xl", "border", "shadow-lg", "overflow-hidden", 3, "ngClass"], [1, "px-6", "py-5", "border-b", 3, "ngClass"], [1, "flex", "items-center", "justify-between"], [1, "flex", "items-center", "gap-3"], [1, "p-2.5", "rounded-lg", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-5", "h-5"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"], [1, "text-xl", "font-bold", 3, "ngClass"], [1, "text-sm", "mt-0.5", 3, "ngClass"], [1, "p-6", 3, "ngClass"], [1, "mb-6", "p-4", "rounded-xl", "border", "flex", "items-start", "gap-3", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-5", "h-5", "flex-shrink-0", "mt-0.5", 3, "ngClass"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"], [1, "flex-1"], [1, "font-semibold", "text-sm", "mb-1", 3, "ngClass"], [1, "text-sm", "leading-relaxed", 3, "ngClass"], [1, "space-y-3"], [1, "rounded-xl", "border", "overflow-hidden", "transition-all", "duration-200", 3, "id", "ngClass"], ["type", "button", 1, "cursor-pointer", "w-full", "px-5", "py-4", "flex", "items-center", "justify-between", "gap-4", "text-left", "transition-colors", "duration-200", 3, "click", "ngClass"], [1, "flex", "items-center", "gap-3", "flex-1", "min-w-0"], [1, "p-2", "rounded-lg", "flex-shrink-0", "transition-colors", "duration-200", 3, "ngClass"], ["fill", "none", "stroke", "currentColor", "viewBox", "0 0 24 24", 1, "w-4", "h-4"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"], [1, "flex-1", "min-w-0"], [1, "font-semibold", "transition-colors", "duration-200", 3, "ngClass"], [1, "text-sm", "mt-0.5", "transition-colors", "duration-200", 3, "ngClass"], [1, "w-5", "h-5", "flex-shrink-0", "transition-transform", "duration-200", 3, "ngClass"], ["stroke", "currentColor", "stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M19 9l-7 7-7-7"], [1, "grid", "transition-[grid-template-rows]", "duration-300", "ease-in-out"], [1, "overflow-hidden"], [1, "border-t", 3, "ngClass"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"], ["stroke-linecap", "round", "stroke-linejoin", "round", "stroke-width", "2", "d", "M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"]], template: function CollapsibleFunnelSectionGroupComponent_Template(rf, ctx) { if (rf & 1) {
26836
27491
  i0.ɵɵprojectionDef(_c0$W);
26837
27492
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3)(4, "div", 4);
26838
27493
  i0.ɵɵnamespaceSVG();
@@ -27677,7 +28332,7 @@ class ViewModeSwitcherModalComponent {
27677
28332
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ViewModeSwitcherModalComponent, { className: "ViewModeSwitcherModalComponent", filePath: "lib/components/shared/view-mode-switcher-modal.component.ts", lineNumber: 160 }); })();
27678
28333
 
27679
28334
  const _c0$V = a0 => ({ name: "check-badge", source: a0 });
27680
- const _c1$y = a0 => ({ name: "check-circle", source: a0 });
28335
+ const _c1$z = a0 => ({ name: "check-circle", source: a0 });
27681
28336
  const _c2$o = a0 => ({ name: "chevron-right", source: a0 });
27682
28337
  const _forTrack0$z = ($index, $item) => $item.area;
27683
28338
  function KeyStrengthsListModalContentComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -27738,7 +28393,7 @@ function KeyStrengthsListModalContentComponent_Conditional_2_For_2_Template(rf,
27738
28393
  i0.ɵɵadvance();
27739
28394
  i0.ɵɵtextInterpolate1(" ", strength_r3.description, " ");
27740
28395
  i0.ɵɵadvance(3);
27741
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$y, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses());
28396
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$z, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses());
27742
28397
  i0.ɵɵadvance();
27743
28398
  i0.ɵɵproperty("ngClass", ctx_r0.countClasses());
27744
28399
  i0.ɵɵadvance();
@@ -27909,7 +28564,7 @@ class KeyStrengthsListModalContentComponent {
27909
28564
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KeyStrengthsListModalContentComponent, { className: "KeyStrengthsListModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/key-strengths-list-modal-content.component.ts", lineNumber: 79 }); })();
27910
28565
 
27911
28566
  const _c0$U = a0 => ({ name: "shield-check", source: a0 });
27912
- const _c1$x = a0 => ({ name: "exclamation-triangle", source: a0 });
28567
+ const _c1$y = a0 => ({ name: "exclamation-triangle", source: a0 });
27913
28568
  const _c2$n = a0 => ({ name: "document-text", source: a0 });
27914
28569
  const _c3$h = a0 => ({ name: "chevron-right", source: a0 });
27915
28570
  const _forTrack0$y = ($index, $item) => $item.area;
@@ -27979,7 +28634,7 @@ function CriticalGapsListModalContentComponent_Conditional_2_For_2_Template(rf,
27979
28634
  i0.ɵɵadvance();
27980
28635
  i0.ɵɵproperty("ngClass", ctx_r0.impactContainerClasses());
27981
28636
  i0.ɵɵadvance(2);
27982
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(19, _c1$x, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.impactIconClasses(gap_r3.urgency));
28637
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(19, _c1$y, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.impactIconClasses(gap_r3.urgency));
27983
28638
  i0.ɵɵadvance(2);
27984
28639
  i0.ɵɵproperty("ngClass", ctx_r0.impactLabelClasses());
27985
28640
  i0.ɵɵadvance(2);
@@ -28225,7 +28880,7 @@ class CriticalGapsListModalContentComponent {
28225
28880
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CriticalGapsListModalContentComponent, { className: "CriticalGapsListModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/critical-gaps-list-modal-content.component.ts", lineNumber: 98 }); })();
28226
28881
 
28227
28882
  const _c0$T = a0 => ({ name: "check-circle", source: a0 });
28228
- const _c1$w = a0 => ({ name: "chat-bubble-left-right", source: a0 });
28883
+ const _c1$x = a0 => ({ name: "chat-bubble-left-right", source: a0 });
28229
28884
  const _forTrack0$x = ($index, $item) => $item.questionId;
28230
28885
  function KeyStrengthDetailModalContentComponent_Conditional_13_For_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
28231
28886
  i0.ɵɵelementStart(0, "div", 19)(1, "span", 20);
@@ -28255,7 +28910,7 @@ function KeyStrengthDetailModalContentComponent_Conditional_13_For_6_Template(rf
28255
28910
  const ctx_r1 = i0.ɵɵnextContext(2);
28256
28911
  i0.ɵɵproperty("ngClass", ctx_r1.answerCardClasses());
28257
28912
  i0.ɵɵadvance(2);
28258
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(8, _c1$w, ctx_r1.IconSourceEnum.HEROICONS))("ngClass", ctx_r1.answerIconClasses());
28913
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(8, _c1$x, ctx_r1.IconSourceEnum.HEROICONS))("ngClass", ctx_r1.answerIconClasses());
28259
28914
  i0.ɵɵadvance(2);
28260
28915
  i0.ɵɵproperty("ngClass", ctx_r1.questionClasses());
28261
28916
  i0.ɵɵadvance();
@@ -28466,7 +29121,7 @@ class KeyStrengthDetailModalContentComponent {
28466
29121
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KeyStrengthDetailModalContentComponent, { className: "KeyStrengthDetailModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/key-strength-detail-modal-content.component.ts", lineNumber: 79 }); })();
28467
29122
 
28468
29123
  const _c0$S = a0 => ({ name: "exclamation-triangle", source: a0 });
28469
- const _c1$v = a0 => ({ name: "document-text", source: a0 });
29124
+ const _c1$w = a0 => ({ name: "document-text", source: a0 });
28470
29125
  const _c2$m = a0 => ({ name: "chat-bubble-left-right", source: a0 });
28471
29126
  const _forTrack0$w = ($index, $item) => $item.questionId;
28472
29127
  function CriticalGapDetailModalContentComponent_Conditional_20_For_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
@@ -28544,7 +29199,7 @@ function CriticalGapDetailModalContentComponent_Conditional_20_Template(rf, ctx)
28544
29199
  i0.ɵɵclassMap(ctx_r1.isLightMode() ? "border-slate-200" : "border-slate-700");
28545
29200
  i0.ɵɵproperty("ngClass", ctx_r1.sectionTitleClasses());
28546
29201
  i0.ɵɵadvance();
28547
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(5, _c1$v, ctx_r1.IconSourceEnum.HEROICONS))("ngClass", ctx_r1.sectionIconClasses());
29202
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(5, _c1$w, ctx_r1.IconSourceEnum.HEROICONS))("ngClass", ctx_r1.sectionIconClasses());
28548
29203
  i0.ɵɵadvance(3);
28549
29204
  i0.ɵɵrepeater(ctx_r1.gap().supportingAnswers);
28550
29205
  } }
@@ -30329,7 +30984,7 @@ class TopPriorityDetailModalContentComponent {
30329
30984
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TopPriorityDetailModalContentComponent, { className: "TopPriorityDetailModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/top-priority-detail-modal-content.component.ts", lineNumber: 72 }); })();
30330
30985
 
30331
30986
  const _c0$R = a0 => ({ name: "check-badge", source: a0 });
30332
- const _c1$u = a0 => ({ name: "check-circle", source: a0 });
30987
+ const _c1$v = a0 => ({ name: "check-circle", source: a0 });
30333
30988
  const _c2$l = a0 => ({ name: "chevron-right", source: a0 });
30334
30989
  const _c3$g = a0 => ({ name: "chart-bar", source: a0 });
30335
30990
  const _forTrack0$v = ($index, $item) => $item.capability;
@@ -30437,7 +31092,7 @@ function FocusAreaStrengthsListModalContentComponent_Conditional_2_For_2_Templat
30437
31092
  i0.ɵɵadvance(2);
30438
31093
  i0.ɵɵconditional(ctx_r0.getLinkedMetricsCount(strength_r3) > 0 ? 9 : -1);
30439
31094
  i0.ɵɵadvance(2);
30440
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$u, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses());
31095
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$v, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses());
30441
31096
  i0.ɵɵadvance();
30442
31097
  i0.ɵɵproperty("ngClass", ctx_r0.countClasses());
30443
31098
  i0.ɵɵadvance();
@@ -30652,7 +31307,7 @@ class FocusAreaStrengthsListModalContentComponent {
30652
31307
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FocusAreaStrengthsListModalContentComponent, { className: "FocusAreaStrengthsListModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/focus-area-strengths-list-modal-content.component.ts", lineNumber: 109 }); })();
30653
31308
 
30654
31309
  const _c0$Q = a0 => ({ name: "exclamation-triangle", source: a0 });
30655
- const _c1$t = a0 => ({ name: "exclamation-circle", source: a0 });
31310
+ const _c1$u = a0 => ({ name: "exclamation-circle", source: a0 });
30656
31311
  const _c2$k = a0 => ({ name: "chevron-right", source: a0 });
30657
31312
  function _forTrack0$u($index, $item) { return this.getGapTitle($item); }
30658
31313
  function FocusAreaGapsListModalContentComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -30761,7 +31416,7 @@ function FocusAreaGapsListModalContentComponent_Conditional_2_For_2_Template(rf,
30761
31416
  i0.ɵɵadvance();
30762
31417
  i0.ɵɵconditional(ctx_r0.getImpactOnMetric(gap_r3) ? 8 : -1);
30763
31418
  i0.ɵɵadvance(3);
30764
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$t, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses(gap_r3));
31419
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(14, _c1$u, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.iconClasses(gap_r3));
30765
31420
  i0.ɵɵadvance();
30766
31421
  i0.ɵɵproperty("ngClass", ctx_r0.countClasses());
30767
31422
  i0.ɵɵadvance();
@@ -31046,7 +31701,7 @@ class FocusAreaGapsListModalContentComponent {
31046
31701
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FocusAreaGapsListModalContentComponent, { className: "FocusAreaGapsListModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/focus-area-gaps-list-modal-content.component.ts", lineNumber: 106 }); })();
31047
31702
 
31048
31703
  const _c0$P = a0 => ({ name: "light-bulb", source: a0 });
31049
- const _c1$s = a0 => ({ name: "chevron-right", source: a0 });
31704
+ const _c1$t = a0 => ({ name: "chevron-right", source: a0 });
31050
31705
  const _c2$j = a0 => ({ name: "chart-bar", source: a0 });
31051
31706
  const _forTrack0$t = ($index, $item) => $item.opportunity;
31052
31707
  function FocusAreaOpportunitiesListModalContentComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -31135,7 +31790,7 @@ function FocusAreaOpportunitiesListModalContentComponent_Conditional_2_For_2_Tem
31135
31790
  i0.ɵɵadvance(2);
31136
31791
  i0.ɵɵconditional(ctx_r0.getLinkedMetricsCount(opportunity_r3) > 0 ? 8 : -1);
31137
31792
  i0.ɵɵadvance(2);
31138
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(9, _c1$s, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.chevronClasses());
31793
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(9, _c1$t, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.chevronClasses());
31139
31794
  } }
31140
31795
  function FocusAreaOpportunitiesListModalContentComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
31141
31796
  i0.ɵɵelementStart(0, "div", 2);
@@ -31315,7 +31970,7 @@ class FocusAreaOpportunitiesListModalContentComponent {
31315
31970
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FocusAreaOpportunitiesListModalContentComponent, { className: "FocusAreaOpportunitiesListModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/focus-area-opportunities-list-modal-content.component.ts", lineNumber: 90 }); })();
31316
31971
 
31317
31972
  const _c0$O = a0 => ({ name: "chevron-right", source: a0 });
31318
- const _c1$r = a0 => ({ name: "chat-bubble-left-right", source: a0 });
31973
+ const _c1$s = a0 => ({ name: "chat-bubble-left-right", source: a0 });
31319
31974
  const _forTrack0$s = ($index, $item) => $item.performanceItemId;
31320
31975
  function FocusAreaStrengthDetailModalContentComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
31321
31976
  i0.ɵɵelementStart(0, "div")(1, "p", 2);
@@ -31438,7 +32093,7 @@ function FocusAreaStrengthDetailModalContentComponent_Conditional_6_For_5_Templa
31438
32093
  const ctx_r0 = i0.ɵɵnextContext(2);
31439
32094
  i0.ɵɵproperty("ngClass", ctx_r0.answerClasses());
31440
32095
  i0.ɵɵadvance(2);
31441
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$r, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.answerIconClasses());
32096
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$s, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.answerIconClasses());
31442
32097
  i0.ɵɵadvance();
31443
32098
  i0.ɵɵproperty("ngClass", ctx_r0.answerQuestionClasses());
31444
32099
  i0.ɵɵadvance();
@@ -32036,7 +32691,7 @@ class FocusAreaGapDetailModalContentComponent {
32036
32691
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FocusAreaGapDetailModalContentComponent, { className: "FocusAreaGapDetailModalContentComponent", filePath: "lib/components/profile-analysis-dashboard/modals/focus-area-gap-detail-modal-content.component.ts", lineNumber: 98 }); })();
32037
32692
 
32038
32693
  const _c0$M = a0 => ({ name: "chevron-right", source: a0 });
32039
- const _c1$q = () => [];
32694
+ const _c1$r = () => [];
32040
32695
  const _forTrack0$r = ($index, $item) => $item.performanceItemId;
32041
32696
  function FocusAreaOpportunityDetailModalContentComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
32042
32697
  i0.ɵɵelementStart(0, "div")(1, "p", 2);
@@ -32125,7 +32780,7 @@ function FocusAreaOpportunityDetailModalContentComponent_Conditional_4_Template(
32125
32780
  i0.ɵɵadvance();
32126
32781
  i0.ɵɵproperty("ngClass", ctx_r0.sectionTitleClasses());
32127
32782
  i0.ɵɵadvance(3);
32128
- i0.ɵɵrepeater(ctx_r0.opportunity().linkedGoalIds || i0.ɵɵpureFunction0(2, _c1$q));
32783
+ i0.ɵɵrepeater(ctx_r0.opportunity().linkedGoalIds || i0.ɵɵpureFunction0(2, _c1$r));
32129
32784
  } }
32130
32785
  function FocusAreaOpportunityDetailModalContentComponent_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
32131
32786
  i0.ɵɵelementStart(0, "span", 10);
@@ -32151,7 +32806,7 @@ function FocusAreaOpportunityDetailModalContentComponent_Conditional_5_Template(
32151
32806
  i0.ɵɵadvance();
32152
32807
  i0.ɵɵproperty("ngClass", ctx_r0.sectionTitleClasses());
32153
32808
  i0.ɵɵadvance(3);
32154
- i0.ɵɵrepeater(ctx_r0.opportunity().linkedFunnelStrengthIds || i0.ɵɵpureFunction0(2, _c1$q));
32809
+ i0.ɵɵrepeater(ctx_r0.opportunity().linkedFunnelStrengthIds || i0.ɵɵpureFunction0(2, _c1$r));
32155
32810
  } }
32156
32811
  class FocusAreaOpportunityDetailModalContentComponent {
32157
32812
  constructor() {
@@ -32488,7 +33143,7 @@ class CircularProgressComponent {
32488
33143
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CircularProgressComponent, { className: "CircularProgressComponent", filePath: "lib/components/business-analysis-dashboard/visualizations/circular-progress.component.ts", lineNumber: 41 }); })();
32489
33144
 
32490
33145
  const _c0$L = ["*"];
32491
- const _c1$p = (a0, a1) => [a0, a1];
33146
+ const _c1$q = (a0, a1) => [a0, a1];
32492
33147
  function VisualizationContainerComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
32493
33148
  const _r1 = i0.ɵɵgetCurrentView();
32494
33149
  i0.ɵɵelementStart(0, "button", 3);
@@ -32499,7 +33154,7 @@ function VisualizationContainerComponent_Conditional_1_Template(rf, ctx) { if (r
32499
33154
  i0.ɵɵelementEnd()();
32500
33155
  } if (rf & 2) {
32501
33156
  const ctx_r1 = i0.ɵɵnextContext();
32502
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(1, _c1$p, ctx_r1.iconClass(), ctx_r1.isLightMode() ? "bg-white/90 hover:bg-white" : "bg-slate-800/90 hover:bg-slate-800"));
33157
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(1, _c1$q, ctx_r1.iconClass(), ctx_r1.isLightMode() ? "bg-white/90 hover:bg-white" : "bg-slate-800/90 hover:bg-slate-800"));
32503
33158
  } }
32504
33159
  class VisualizationContainerComponent {
32505
33160
  constructor() {
@@ -32654,7 +33309,7 @@ class MetricBadgeComponent {
32654
33309
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MetricBadgeComponent, { className: "MetricBadgeComponent", filePath: "lib/components/business-analysis-dashboard/badges/metric-badge.component.ts", lineNumber: 22 }); })();
32655
33310
 
32656
33311
  const _c0$K = a0 => ({ name: "light-bulb", source: a0 });
32657
- const _c1$o = a0 => ({ name: "chevron-right", source: a0 });
33312
+ const _c1$p = a0 => ({ name: "chevron-right", source: a0 });
32658
33313
  function OpportunityHighlightBannerComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
32659
33314
  i0.ɵɵelementStart(0, "p", 7);
32660
33315
  i0.ɵɵtext(1);
@@ -32729,7 +33384,7 @@ class OpportunityHighlightBannerComponent {
32729
33384
  i0.ɵɵconditional(ctx.message() ? 9 : -1);
32730
33385
  i0.ɵɵadvance();
32731
33386
  i0.ɵɵclassProp("rotate-90", ctx.isExpanded());
32732
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(13, _c1$o, ctx.iconSource))("ngClass", ctx.chevronClasses());
33387
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(13, _c1$p, ctx.iconSource))("ngClass", ctx.chevronClasses());
32733
33388
  } }, dependencies: [CommonModule, i1$1.NgClass, SymphiqIconComponent], encapsulation: 2, changeDetection: 0 }); }
32734
33389
  }
32735
33390
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(OpportunityHighlightBannerComponent, [{
@@ -33355,7 +34010,7 @@ class ViewportAnimationDirective {
33355
34010
  }] }); })();
33356
34011
 
33357
34012
  const _c0$I = a0 => ({ name: "star", source: a0 });
33358
- const _c1$n = a0 => ({ name: "globe-americas", source: a0 });
34013
+ const _c1$o = a0 => ({ name: "globe-americas", source: a0 });
33359
34014
  const _c2$i = a0 => ({ name: "academic-cap", source: a0 });
33360
34015
  const _c3$f = a0 => ({ name: "information-circle", source: a0 });
33361
34016
  const _c4$b = a0 => ({ name: "signal", source: a0 });
@@ -33463,7 +34118,7 @@ function RegionCardComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
33463
34118
  const ctx_r0 = i0.ɵɵnextContext();
33464
34119
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedSectionClasses());
33465
34120
  i0.ɵɵadvance(2);
33466
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$n, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
34121
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$o, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
33467
34122
  i0.ɵɵadvance();
33468
34123
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedTitleClasses());
33469
34124
  i0.ɵɵadvance(2);
@@ -34433,7 +35088,7 @@ class CompetitiveInsightBadgeComponent {
34433
35088
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CompetitiveInsightBadgeComponent, { className: "CompetitiveInsightBadgeComponent", filePath: "lib/components/business-analysis-dashboard/badges/competitive-insight-badge.component.ts", lineNumber: 25 }); })();
34434
35089
 
34435
35090
  const _c0$H = a0 => ({ name: "calendar-days", source: a0 });
34436
- const _c1$m = a0 => ({ name: "chart-bar", source: a0 });
35091
+ const _c1$n = a0 => ({ name: "chart-bar", source: a0 });
34437
35092
  const _c2$h = a0 => ({ name: "academic-cap", source: a0 });
34438
35093
  const _c3$e = a0 => ({ name: "information-circle", source: a0 });
34439
35094
  const _c4$a = a0 => ({ name: "signal", source: a0 });
@@ -34549,7 +35204,7 @@ function SeasonCardComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
34549
35204
  const ctx_r0 = i0.ɵɵnextContext();
34550
35205
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedSectionClasses());
34551
35206
  i0.ɵɵadvance(2);
34552
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$m, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
35207
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$n, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
34553
35208
  i0.ɵɵadvance();
34554
35209
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedTitleClasses());
34555
35210
  i0.ɵɵadvance(2);
@@ -35271,7 +35926,7 @@ class SeasonCardComponent {
35271
35926
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SeasonCardComponent, { className: "SeasonCardComponent", filePath: "lib/components/business-analysis-dashboard/cards/season-card.component.ts", lineNumber: 270 }); })();
35272
35927
 
35273
35928
  const _c0$G = a0 => ({ name: "currency-dollar", source: a0 });
35274
- const _c1$l = a0 => ({ name: "chart-bar", source: a0 });
35929
+ const _c1$m = a0 => ({ name: "chart-bar", source: a0 });
35275
35930
  const _c2$g = a0 => ({ name: "academic-cap", source: a0 });
35276
35931
  const _c3$d = a0 => ({ name: "information-circle", source: a0 });
35277
35932
  const _c4$9 = a0 => ({ name: "signal", source: a0 });
@@ -35560,7 +36215,7 @@ function CustomerSegmentCardComponent_Conditional_23_Template(rf, ctx) { if (rf
35560
36215
  const ctx_r0 = i0.ɵɵnextContext();
35561
36216
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedSectionClasses());
35562
36217
  i0.ɵɵadvance(2);
35563
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(12, _c1$l, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
36218
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(12, _c1$m, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
35564
36219
  i0.ɵɵadvance();
35565
36220
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedTitleClasses());
35566
36221
  i0.ɵɵadvance(2);
@@ -36388,7 +37043,7 @@ class CustomerSegmentCardComponent {
36388
37043
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CustomerSegmentCardComponent, { className: "CustomerSegmentCardComponent", filePath: "lib/components/business-analysis-dashboard/cards/customer-segment-card.component.ts", lineNumber: 366 }); })();
36389
37044
 
36390
37045
  const _c0$F = a0 => ({ name: "currency-dollar", source: a0 });
36391
- const _c1$k = a0 => ({ name: "document-text", source: a0 });
37046
+ const _c1$l = a0 => ({ name: "document-text", source: a0 });
36392
37047
  const _c2$f = a0 => ({ name: "academic-cap", source: a0 });
36393
37048
  const _c3$c = a0 => ({ name: "information-circle", source: a0 });
36394
37049
  const _c4$8 = a0 => ({ name: "signal", source: a0 });
@@ -36508,7 +37163,7 @@ function PriceTierCardComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
36508
37163
  const ctx_r0 = i0.ɵɵnextContext();
36509
37164
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedSectionClasses());
36510
37165
  i0.ɵɵadvance(2);
36511
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$k, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
37166
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$l, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
36512
37167
  i0.ɵɵadvance();
36513
37168
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedTitleClasses());
36514
37169
  i0.ɵɵadvance(2);
@@ -37225,7 +37880,7 @@ class PriceTierCardComponent {
37225
37880
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PriceTierCardComponent, { className: "PriceTierCardComponent", filePath: "lib/components/business-analysis-dashboard/cards/price-tier-card.component.ts", lineNumber: 261 }); })();
37226
37881
 
37227
37882
  const _c0$E = () => ({ name: "cube", source: "HEROICONS" });
37228
- const _c1$j = () => ({ name: "currency-dollar", source: "HEROICONS" });
37883
+ const _c1$k = () => ({ name: "currency-dollar", source: "HEROICONS" });
37229
37884
  const _c2$e = () => ({ name: "chart-bar", source: "HEROICONS" });
37230
37885
  const _c3$b = a0 => ({ name: "chart-bar", source: a0 });
37231
37886
  const _c4$7 = a0 => ({ name: "academic-cap", source: a0 });
@@ -37292,7 +37947,7 @@ function ProductCategoryCardComponent_Conditional_14_Conditional_3_Template(rf,
37292
37947
  const ctx_r0 = i0.ɵɵnextContext(2);
37293
37948
  i0.ɵɵproperty("ngClass", ctx_r0.getStatBoxClasses());
37294
37949
  i0.ɵɵadvance(2);
37295
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction0(6, _c1$j))("ngClass", ctx_r0.getStatIconClasses());
37950
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction0(6, _c1$k))("ngClass", ctx_r0.getStatIconClasses());
37296
37951
  i0.ɵɵadvance(2);
37297
37952
  i0.ɵɵproperty("ngClass", ctx_r0.getStatLabelClasses());
37298
37953
  i0.ɵɵadvance(2);
@@ -38382,7 +39037,7 @@ function getCategoryBadgeClasses(category, isDark) {
38382
39037
  }
38383
39038
 
38384
39039
  const _c0$C = a0 => ({ name: "shield-check", source: a0 });
38385
- const _c1$i = a0 => ({ name: "building-storefront", source: a0 });
39040
+ const _c1$j = a0 => ({ name: "building-storefront", source: a0 });
38386
39041
  const _c2$d = a0 => ({ name: "academic-cap", source: a0 });
38387
39042
  const _c3$a = a0 => ({ name: "information-circle", source: a0 });
38388
39043
  const _c4$6 = a0 => ({ name: "signal", source: a0 });
@@ -38432,7 +39087,7 @@ function EnhancedListItemCardComponent_Conditional_21_Conditional_7_Template(rf,
38432
39087
  const ctx_r0 = i0.ɵɵnextContext(2);
38433
39088
  i0.ɵɵclassProp("mt-3", ctx_r0.getCompetitorPositioning() || ((tmp_2_0 = ctx_r0.item()) == null ? null : tmp_2_0.differentiationStrength));
38434
39089
  i0.ɵɵadvance(2);
38435
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$i, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
39090
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(7, _c1$j, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.getExpandedIconClasses());
38436
39091
  i0.ɵɵadvance();
38437
39092
  i0.ɵɵproperty("ngClass", ctx_r0.getExpandedSubtitleClasses());
38438
39093
  i0.ɵɵadvance(2);
@@ -39098,7 +39753,7 @@ class EnhancedListItemCardComponent {
39098
39753
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EnhancedListItemCardComponent, { className: "EnhancedListItemCardComponent", filePath: "lib/components/business-analysis-dashboard/cards/enhanced-list-item-card.component.ts", lineNumber: 221 }); })();
39099
39754
 
39100
39755
  const _c0$B = a0 => ({ name: "academic-cap", source: a0 });
39101
- const _c1$h = a0 => ({ name: "information-circle", source: a0 });
39756
+ const _c1$i = a0 => ({ name: "information-circle", source: a0 });
39102
39757
  const _c2$c = a0 => ({ name: "signal", source: a0 });
39103
39758
  const _c3$9 = a0 => ({ name: "wrench-screwdriver", source: a0 });
39104
39759
  function FocusAreaDetailCardComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
@@ -39199,7 +39854,7 @@ function FocusAreaDetailCardComponent_Conditional_16_Conditional_6_Template(rf,
39199
39854
  const ctx_r0 = i0.ɵɵnextContext(2);
39200
39855
  i0.ɵɵproperty("ngClass", ctx_r0.getCompetitiveGapSectionClasses());
39201
39856
  i0.ɵɵadvance(2);
39202
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$h, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.expandedIconClasses());
39857
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$i, ctx_r0.IconSourceEnum.HEROICONS))("ngClass", ctx_r0.expandedIconClasses());
39203
39858
  i0.ɵɵadvance();
39204
39859
  i0.ɵɵproperty("ngClass", ctx_r0.expandedTitleClasses());
39205
39860
  i0.ɵɵadvance(2);
@@ -42145,7 +42800,7 @@ class ProfileItemCardComponent {
42145
42800
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProfileItemCardComponent, { className: "ProfileItemCardComponent", filePath: "lib/components/business-analysis-dashboard/profile-item-card.component.ts", lineNumber: 171 }); })();
42146
42801
 
42147
42802
  const _c0$z = ["scrollContainer"];
42148
- const _c1$g = a0 => ({ name: "arrow-right", source: a0 });
42803
+ const _c1$h = a0 => ({ name: "arrow-right", source: a0 });
42149
42804
  function ItemDetailModalComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
42150
42805
  const _r2 = i0.ɵɵgetCurrentView();
42151
42806
  i0.ɵɵelementStart(0, "button", 7);
@@ -42157,7 +42812,7 @@ function ItemDetailModalComponent_Conditional_7_Template(rf, ctx) { if (rf & 1)
42157
42812
  const ctx_r2 = i0.ɵɵnextContext();
42158
42813
  i0.ɵɵproperty("ngClass", ctx_r2.getPrimaryButtonClasses());
42159
42814
  i0.ɵɵadvance();
42160
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(2, _c1$g, ctx_r2.IconSourceEnum.HEROICONS));
42815
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(2, _c1$h, ctx_r2.IconSourceEnum.HEROICONS));
42161
42816
  } }
42162
42817
  class ItemDetailModalComponent {
42163
42818
  constructor() {
@@ -42344,7 +42999,7 @@ class ItemDetailModalComponent {
42344
42999
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ItemDetailModalComponent, { className: "ItemDetailModalComponent", filePath: "lib/components/business-analysis-dashboard/modals/item-detail-modal.component.ts", lineNumber: 53 }); })();
42345
43000
 
42346
43001
  const _c0$y = ["modalContent"];
42347
- const _c1$f = ["modalWrapper"];
43002
+ const _c1$g = ["modalWrapper"];
42348
43003
  const _c2$b = ["*"];
42349
43004
  const ProfileAnalysisModalComponent_Conditional_0_Conditional_31_Conditional_3_Defer_2_DepsFn = () => [Promise.resolve().then(function () { return lineChart_component; }).then(m => m.LineChartComponent)];
42350
43005
  const ProfileAnalysisModalComponent_Conditional_0_Conditional_31_Conditional_4_Defer_2_DepsFn = () => [Promise.resolve().then(function () { return barChart_component; }).then(m => m.BarChartComponent)];
@@ -44593,7 +45248,7 @@ class ProfileAnalysisModalComponent {
44593
45248
  static { this.ɵfac = function ProfileAnalysisModalComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ProfileAnalysisModalComponent)(); }; }
44594
45249
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProfileAnalysisModalComponent, selectors: [["symphiq-profile-analysis-modal"]], viewQuery: function ProfileAnalysisModalComponent_Query(rf, ctx) { if (rf & 1) {
44595
45250
  i0.ɵɵviewQuery(_c0$y, 5);
44596
- i0.ɵɵviewQuery(_c1$f, 5);
45251
+ i0.ɵɵviewQuery(_c1$g, 5);
44597
45252
  } if (rf & 2) {
44598
45253
  let _t;
44599
45254
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.modalContent = _t.first);
@@ -45148,7 +45803,7 @@ class ProfileAnalysisModalComponent {
45148
45803
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProfileAnalysisModalComponent, { className: "ProfileAnalysisModalComponent", filePath: "lib/components/profile-analysis-dashboard/profile-analysis-modal.component.ts", lineNumber: 554 }); })();
45149
45804
 
45150
45805
  const _c0$x = a0 => ({ name: "light-bulb", source: a0 });
45151
- const _c1$e = a0 => ({ name: "trophy", source: a0 });
45806
+ const _c1$f = a0 => ({ name: "trophy", source: a0 });
45152
45807
  const _c2$a = a0 => ({ name: "academic-cap", source: a0 });
45153
45808
  const _c3$7 = a0 => ({ name: "signal", source: a0 });
45154
45809
  const _c4$4 = a0 => ({ name: "wrench-screwdriver", source: a0 });
@@ -45186,7 +45841,7 @@ function CompetitiveGapModalComponent_Conditional_10_Template(rf, ctx) { if (rf
45186
45841
  const ctx_r0 = i0.ɵɵnextContext();
45187
45842
  i0.ɵɵproperty("ngClass", ctx_r0.sectionClasses());
45188
45843
  i0.ɵɵadvance(2);
45189
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$e, ctx_r0.iconSource))("ngClass", ctx_r0.sectionIconClasses());
45844
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(6, _c1$f, ctx_r0.iconSource))("ngClass", ctx_r0.sectionIconClasses());
45190
45845
  i0.ɵɵadvance();
45191
45846
  i0.ɵɵproperty("ngClass", ctx_r0.sectionTitleClasses());
45192
45847
  i0.ɵɵadvance(2);
@@ -45479,7 +46134,7 @@ class CompetitiveGapModalComponent {
45479
46134
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CompetitiveGapModalComponent, { className: "CompetitiveGapModalComponent", filePath: "lib/components/business-analysis-dashboard/modals/competitive-gap-modal.component.ts", lineNumber: 101 }); })();
45480
46135
 
45481
46136
  const _c0$w = a0 => ({ name: "list-bullet", source: a0 });
45482
- const _c1$d = a0 => ({ name: "arrow-right", source: a0 });
46137
+ const _c1$e = a0 => ({ name: "arrow-right", source: a0 });
45483
46138
  const _c2$9 = a0 => ({ name: "check-circle", source: a0 });
45484
46139
  const _c3$6 = a0 => ({ name: "exclamation-circle", source: a0 });
45485
46140
  const _forTrack0$o = ($index, $item) => $item.order;
@@ -45551,7 +46206,7 @@ function RecommendationActionStepsModalComponent_For_4_Template(rf, ctx) { if (r
45551
46206
  i0.ɵɵadvance();
45552
46207
  i0.ɵɵtextInterpolate1(" ", step_r2.order, " ");
45553
46208
  i0.ɵɵadvance(4);
45554
- i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(9, _c1$d, ctx_r0.iconSource))("ngClass", ctx_r0.actionIconClasses());
46209
+ i0.ɵɵproperty("icon", i0.ɵɵpureFunction1(9, _c1$e, ctx_r0.iconSource))("ngClass", ctx_r0.actionIconClasses());
45555
46210
  i0.ɵɵadvance();
45556
46211
  i0.ɵɵproperty("ngClass", ctx_r0.actionTitleClasses());
45557
46212
  i0.ɵɵadvance(2);
@@ -45719,7 +46374,7 @@ class RecommendationActionStepsModalComponent {
45719
46374
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecommendationActionStepsModalComponent, { className: "RecommendationActionStepsModalComponent", filePath: "lib/components/business-analysis-dashboard/modals/recommendation-action-steps-modal.component.ts", lineNumber: 69 }); })();
45720
46375
 
45721
46376
  const _c0$v = ["modalContent"];
45722
- const _c1$c = ["modalWrapper"];
46377
+ const _c1$d = ["modalWrapper"];
45723
46378
  function BusinessAnalysisModalComponent_Conditional_0_Conditional_10_For_6_Conditional_0_Template(rf, ctx) { if (rf & 1) {
45724
46379
  const _r4 = i0.ɵɵgetCurrentView();
45725
46380
  i0.ɵɵelementStart(0, "button", 28);
@@ -46242,7 +46897,7 @@ class BusinessAnalysisModalComponent {
46242
46897
  static { this.ɵfac = function BusinessAnalysisModalComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || BusinessAnalysisModalComponent)(); }; }
46243
46898
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: BusinessAnalysisModalComponent, selectors: [["symphiq-business-analysis-modal"]], viewQuery: function BusinessAnalysisModalComponent_Query(rf, ctx) { if (rf & 1) {
46244
46899
  i0.ɵɵviewQuery(_c0$v, 5);
46245
- i0.ɵɵviewQuery(_c1$c, 5);
46900
+ i0.ɵɵviewQuery(_c1$d, 5);
46246
46901
  } if (rf & 2) {
46247
46902
  let _t;
46248
46903
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.modalContent = _t.first);
@@ -46427,7 +47082,7 @@ class BusinessAnalysisModalComponent {
46427
47082
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(BusinessAnalysisModalComponent, { className: "BusinessAnalysisModalComponent", filePath: "lib/components/business-analysis-dashboard/business-analysis-modal.component.ts", lineNumber: 171 }); })();
46428
47083
 
46429
47084
  const _c0$u = ["dashboardContainer"];
46430
- const _c1$b = () => ({});
47085
+ const _c1$c = () => ({});
46431
47086
  const _c2$8 = () => [1, 2, 3, 4, 5, 6];
46432
47087
  const _c3$5 = () => [1, 2, 3];
46433
47088
  const _c4$3 = () => [1, 2, 3, 4];
@@ -46734,7 +47389,7 @@ function SymphiqFunnelAnalysisDashboardComponent_Conditional_50_Conditional_8_Co
46734
47389
  i0.ɵɵelementEnd();
46735
47390
  } if (rf & 2) {
46736
47391
  const ctx_r2 = i0.ɵɵnextContext(3);
46737
- i0.ɵɵproperty("assessment", ctx_r2.performanceOverview().overallAssessment || i0.ɵɵpureFunction0(11, _c1$b))("revenueMetric", ctx_r2.revenueMetric())("charts", ctx_r2.chartsForItem("OVERALL_ASSESSMENT"))("metrics", ctx_r2.allMetrics())("isLightMode", ctx_r2.isLightMode())("isLoading", ctx_r2.isOverallAssessmentLoading())("isCompactMode", true)("isChartsLoading", ctx_r2.areChartsLoading())("strengths", ctx_r2.strengths())("weaknesses", ctx_r2.weaknesses())("currencySymbol", ctx_r2.currencySymbol());
47392
+ i0.ɵɵproperty("assessment", ctx_r2.performanceOverview().overallAssessment || i0.ɵɵpureFunction0(11, _c1$c))("revenueMetric", ctx_r2.revenueMetric())("charts", ctx_r2.chartsForItem("OVERALL_ASSESSMENT"))("metrics", ctx_r2.allMetrics())("isLightMode", ctx_r2.isLightMode())("isLoading", ctx_r2.isOverallAssessmentLoading())("isCompactMode", true)("isChartsLoading", ctx_r2.areChartsLoading())("strengths", ctx_r2.strengths())("weaknesses", ctx_r2.weaknesses())("currencySymbol", ctx_r2.currencySymbol());
46738
47393
  } }
46739
47394
  function SymphiqFunnelAnalysisDashboardComponent_Conditional_50_Conditional_8_Template(rf, ctx) { if (rf & 1) {
46740
47395
  i0.ɵɵelementStart(0, "div", 72);
@@ -46884,7 +47539,7 @@ function SymphiqFunnelAnalysisDashboardComponent_Conditional_51_Conditional_2_Co
46884
47539
  i0.ɵɵelementEnd();
46885
47540
  } if (rf & 2) {
46886
47541
  const ctx_r2 = i0.ɵɵnextContext(3);
46887
- i0.ɵɵproperty("assessment", ctx_r2.performanceOverview().overallAssessment || i0.ɵɵpureFunction0(11, _c1$b))("revenueMetric", ctx_r2.revenueMetric())("charts", ctx_r2.chartsForItem("OVERALL_ASSESSMENT"))("metrics", ctx_r2.allMetrics())("isLightMode", ctx_r2.isLightMode())("isLoading", ctx_r2.isOverallAssessmentLoading())("isCompactMode", ctx_r2.viewModeService.isCompact())("isChartsLoading", ctx_r2.areChartsLoading())("strengths", ctx_r2.strengths())("weaknesses", ctx_r2.weaknesses())("currencySymbol", ctx_r2.currencySymbol());
47542
+ i0.ɵɵproperty("assessment", ctx_r2.performanceOverview().overallAssessment || i0.ɵɵpureFunction0(11, _c1$c))("revenueMetric", ctx_r2.revenueMetric())("charts", ctx_r2.chartsForItem("OVERALL_ASSESSMENT"))("metrics", ctx_r2.allMetrics())("isLightMode", ctx_r2.isLightMode())("isLoading", ctx_r2.isOverallAssessmentLoading())("isCompactMode", ctx_r2.viewModeService.isCompact())("isChartsLoading", ctx_r2.areChartsLoading())("strengths", ctx_r2.strengths())("weaknesses", ctx_r2.weaknesses())("currencySymbol", ctx_r2.currencySymbol());
46888
47543
  } }
46889
47544
  function SymphiqFunnelAnalysisDashboardComponent_Conditional_51_Conditional_2_Template(rf, ctx) { if (rf & 1) {
46890
47545
  i0.ɵɵelementStart(0, "div", 93);
@@ -55619,49 +56274,6 @@ class RevenueCalculatorWelcomeBannerComponent {
55619
56274
  }], null, { viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], dataLoadStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataLoadStatus", required: false }] }], hasTargets: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasTargets", required: false }] }] }); })();
55620
56275
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RevenueCalculatorWelcomeBannerComponent, { className: "RevenueCalculatorWelcomeBannerComponent", filePath: "lib/components/revenue-calculator-dashboard/revenue-calculator-welcome-banner.component.ts", lineNumber: 85 }); })();
55621
56276
 
55622
- function getCurrentYearStart() {
55623
- const now = new Date();
55624
- return new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0);
55625
- }
55626
- function getCurrentYearEnd() {
55627
- const now = new Date();
55628
- return new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999);
55629
- }
55630
- function getPriorYearStart() {
55631
- const now = new Date();
55632
- return new Date(now.getFullYear() - 1, 0, 1, 0, 0, 0, 0);
55633
- }
55634
- function getPriorYearEnd() {
55635
- const now = new Date();
55636
- return new Date(now.getFullYear() - 1, 11, 31, 23, 59, 59, 999);
55637
- }
55638
- function isCurrentYearTarget(target) {
55639
- if (!target.startDate || !target.endDate) {
55640
- return false;
55641
- }
55642
- const currentYearStart = getCurrentYearStart();
55643
- const currentYearEnd = getCurrentYearEnd();
55644
- const targetStart = new Date(target.startDate);
55645
- const targetEnd = new Date(target.endDate);
55646
- return (targetStart.getTime() === currentYearStart.getTime() &&
55647
- targetEnd.getTime() === currentYearEnd.getTime());
55648
- }
55649
- function formatCurrency(value, currencySymbol = '$') {
55650
- return `${currencySymbol}${value.toLocaleString('en-US', {
55651
- minimumFractionDigits: 0,
55652
- maximumFractionDigits: 0
55653
- })}`;
55654
- }
55655
- function formatPercentage(value, decimals = 1) {
55656
- return `${value.toFixed(decimals)}%`;
55657
- }
55658
- function formatNumber(value) {
55659
- return value.toLocaleString('en-US', {
55660
- minimumFractionDigits: 0,
55661
- maximumFractionDigits: 0
55662
- });
55663
- }
55664
-
55665
56277
  function calculatePacingStatus(currentValue, priorValue, targetValue) {
55666
56278
  if (targetValue !== undefined && targetValue > 0) {
55667
56279
  const targetGrowth = ((targetValue - priorValue) / priorValue) * 100;
@@ -55908,7 +56520,7 @@ function FunnelMetricsVisualizationComponent_For_4_Conditional_17_Template(rf, c
55908
56520
  i0.ɵɵadvance();
55909
56521
  i0.ɵɵproperty("ngClass", ctx_r1.projectedValueClasses());
55910
56522
  i0.ɵɵadvance();
55911
- i0.ɵɵtextInterpolate1(" ", ctx_r1.formatMetricValue(stage_r1.pacingInfo.projectedValue, stage_r1.stageMetric.metric), " ");
56523
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.formatMetricValue(stage_r1.pacingInfo.projectedValue, stage_r1.stageMetric.metric, false), " ");
55912
56524
  } }
55913
56525
  function FunnelMetricsVisualizationComponent_For_4_Conditional_23_For_6_Conditional_5_Template(rf, ctx) { if (rf & 1) {
55914
56526
  i0.ɵɵelementStart(0, "button", 24);
@@ -55938,7 +56550,7 @@ function FunnelMetricsVisualizationComponent_For_4_Conditional_23_For_6_Conditio
55938
56550
  i0.ɵɵadvance();
55939
56551
  i0.ɵɵproperty("ngClass", ctx_r1.relatedLabelClasses());
55940
56552
  i0.ɵɵadvance();
55941
- i0.ɵɵtextInterpolate1("Proj: ", ctx_r1.formatMetricValue(metric_r3.pacingInfo.projectedValue, metric_r3.calc.metric));
56553
+ i0.ɵɵtextInterpolate1("Proj: ", ctx_r1.formatMetricValue(metric_r3.pacingInfo.projectedValue, metric_r3.calc.metric, false));
55942
56554
  } }
55943
56555
  function FunnelMetricsVisualizationComponent_For_4_Conditional_23_For_6_Template(rf, ctx) { if (rf & 1) {
55944
56556
  i0.ɵɵelementStart(0, "div", 20)(1, "div", 21)(2, "div", 22)(3, "p", 23);
@@ -56175,12 +56787,14 @@ class FunnelMetricsVisualizationComponent {
56175
56787
  formatPercentage(value, decimals) {
56176
56788
  return formatPercentage(value, decimals);
56177
56789
  }
56178
- formatMetricValue(value, metric) {
56790
+ formatMetricValue(value, metric, fromUiData = true) {
56179
56791
  if (metric.includes('REVENUE')) {
56180
56792
  return formatCurrency(value);
56181
56793
  }
56182
- if (metric.includes('RATE') || metric.includes('CONVERSION')) {
56183
- return formatPercentage(value, 2);
56794
+ const numberType = MetricEnumUtil.numberType(metric);
56795
+ if (numberType === NumberTypeEnum.PERCENTAGE) {
56796
+ const displayValue = fromUiData ? value * 100 : value;
56797
+ return formatPercentage(displayValue, 2);
56184
56798
  }
56185
56799
  return formatNumber(value);
56186
56800
  }
@@ -56217,140 +56831,140 @@ class FunnelMetricsVisualizationComponent {
56217
56831
  standalone: true,
56218
56832
  imports: [CommonModule, PacingStatusBadgeComponent, TooltipDirective, TooltipContainerComponent],
56219
56833
  changeDetection: ChangeDetectionStrategy.OnPush,
56220
- template: `
56221
- <div class="space-y-6">
56222
- <symphiq-tooltip-container />
56223
- <div class="space-y-8">
56224
- @for (stage of funnelStages(); track stage.stageMetric.metric) {
56225
- <div [ngClass]="stageCardClasses()" class="rounded-xl p-6 border-2 transition-all duration-200">
56226
- <div class="flex items-start justify-between mb-4">
56227
- <div class="flex-1">
56228
- <div class="flex items-center gap-2 mb-1">
56229
- <h3 [ngClass]="stageTitleClasses()" class="text-lg font-bold leading-tight m-0">
56230
- {{ getMetricTitle(stage.stageMetric) }}
56231
- </h3>
56232
- @if (stage.stageMetric.description) {
56233
- <button
56234
- type="button"
56235
- [ngClass]="infoIconClasses()"
56236
- class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center transition-colors"
56237
- [libSymphiqTooltip]="getMarkdownTooltipContent(stage.stageMetric.description, getMetricTitle(stage.stageMetric))"
56238
- tooltipType="markdown"
56239
- tooltipPosition="right">
56240
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
56241
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
56242
- </svg>
56243
- </button>
56244
- }
56245
- </div>
56246
- </div>
56247
- <div class="flex items-center gap-3">
56248
- @if (stage.pacingInfo) {
56249
- <symphiq-pacing-status-badge
56250
- [viewMode]="viewMode()"
56251
- [pacingPercentage]="stage.pacingInfo.pacingPercentage"
56252
- [status]="stage.pacingInfo.status"
56253
- />
56254
- }
56255
- <div [ngClass]="percentageBadgeClasses()" class="px-4 py-2 rounded-lg font-bold text-sm">
56256
- +{{ formatPercentage(stage.stageMetric.percentageIncrease, 1) }}
56257
- </div>
56258
- </div>
56259
- </div>
56260
-
56261
- <div class="grid grid-cols-3 gap-4 mb-4">
56262
- <div>
56263
- <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56264
- {{ priorYear() }} Actual
56265
- </p>
56266
- <p [ngClass]="valueClasses()" class="text-2xl font-bold">
56267
- {{ formatMetricValue(stage.stageMetric.currentValue, stage.stageMetric.metric) }}
56268
- </p>
56269
- </div>
56270
- @if (stage.pacingInfo) {
56271
- <div>
56272
- <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56273
- {{ currentYear() }} Projected
56274
- </p>
56275
- <p [ngClass]="projectedValueClasses()" class="text-2xl font-bold">
56276
- {{ formatMetricValue(stage.pacingInfo.projectedValue, stage.stageMetric.metric) }}
56277
- </p>
56278
- </div>
56279
- }
56280
- <div>
56281
- <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56282
- {{ currentYear() }} Target
56283
- </p>
56284
- <p [ngClass]="targetValueClasses()" class="text-2xl font-bold">
56285
- {{ formatMetricValue(stage.stageMetric.targetValue, stage.stageMetric.metric) }}
56286
- </p>
56287
- </div>
56288
- </div>
56289
-
56290
- @if (stage.relatedMetrics.length > 0) {
56291
- <div [ngClass]="dividerClasses()" class="my-4"></div>
56292
-
56293
- <div class="space-y-2">
56294
- <p [ngClass]="relatedTitleClasses()" class="text-xs font-semibold uppercase tracking-wider mb-3">
56295
- Related Metrics
56296
- </p>
56297
- <div class="grid gap-2">
56298
- @for (metric of stage.relatedMetrics; track metric.calc.metric) {
56299
- <div [ngClass]="relatedMetricCardClasses()" class="p-3 rounded-lg">
56300
- <div class="flex items-center justify-between mb-2">
56301
- <div class="flex items-center gap-2 flex-1">
56302
- <p [ngClass]="relatedMetricNameClasses()" class="text-sm font-semibold leading-tight">
56303
- {{ getMetricTitle(metric.calc) }}
56304
- </p>
56305
- @if (metric.calc.description) {
56306
- <button
56307
- type="button"
56308
- [ngClass]="infoIconClasses()"
56309
- class="flex-shrink-0 w-5 h-5 rounded-full inline-flex items-center justify-center transition-colors"
56310
- [libSymphiqTooltip]="getMarkdownTooltipContent(metric.calc.description, getMetricTitle(metric.calc))"
56311
- tooltipType="markdown"
56312
- tooltipPosition="right">
56313
- <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
56314
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
56315
- </svg>
56316
- </button>
56317
- }
56318
- </div>
56319
- <div class="flex items-center gap-2">
56320
- @if (metric.pacingInfo) {
56321
- <symphiq-pacing-status-badge
56322
- [viewMode]="viewMode()"
56323
- [pacingPercentage]="metric.pacingInfo.pacingPercentage"
56324
- [status]="metric.pacingInfo.status"
56325
- />
56326
- }
56327
- <span [ngClass]="relatedPercentageBadgeClasses()" class="px-2 py-1 rounded text-xs font-bold">
56328
- +{{ formatPercentage(metric.calc.percentageIncrease, 1) }}
56329
- </span>
56330
- </div>
56331
- </div>
56332
- <div class="grid gap-2 text-xs" [ngClass]="metric.pacingInfo ? 'grid-cols-3' : 'grid-cols-2'">
56333
- <div>
56334
- <p [ngClass]="relatedLabelClasses()">{{ priorYear() }}: {{ formatMetricValue(metric.calc.currentValue, metric.calc.metric) }}</p>
56335
- </div>
56336
- @if (metric.pacingInfo) {
56337
- <div>
56338
- <p [ngClass]="relatedLabelClasses()">Proj: {{ formatMetricValue(metric.pacingInfo.projectedValue, metric.calc.metric) }}</p>
56339
- </div>
56340
- }
56341
- <div>
56342
- <p [ngClass]="relatedLabelClasses()">Target: {{ formatMetricValue(metric.calc.targetValue, metric.calc.metric) }}</p>
56343
- </div>
56344
- </div>
56345
- </div>
56346
- }
56347
- </div>
56348
- </div>
56349
- }
56350
- </div>
56351
- }
56352
- </div>
56353
- </div>
56834
+ template: `
56835
+ <div class="space-y-6">
56836
+ <symphiq-tooltip-container />
56837
+ <div class="space-y-8">
56838
+ @for (stage of funnelStages(); track stage.stageMetric.metric) {
56839
+ <div [ngClass]="stageCardClasses()" class="rounded-xl p-6 border-2 transition-all duration-200">
56840
+ <div class="flex items-start justify-between mb-4">
56841
+ <div class="flex-1">
56842
+ <div class="flex items-center gap-2 mb-1">
56843
+ <h3 [ngClass]="stageTitleClasses()" class="text-lg font-bold leading-tight m-0">
56844
+ {{ getMetricTitle(stage.stageMetric) }}
56845
+ </h3>
56846
+ @if (stage.stageMetric.description) {
56847
+ <button
56848
+ type="button"
56849
+ [ngClass]="infoIconClasses()"
56850
+ class="flex-shrink-0 w-6 h-6 rounded-full inline-flex items-center justify-center transition-colors"
56851
+ [libSymphiqTooltip]="getMarkdownTooltipContent(stage.stageMetric.description, getMetricTitle(stage.stageMetric))"
56852
+ tooltipType="markdown"
56853
+ tooltipPosition="right">
56854
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
56855
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
56856
+ </svg>
56857
+ </button>
56858
+ }
56859
+ </div>
56860
+ </div>
56861
+ <div class="flex items-center gap-3">
56862
+ @if (stage.pacingInfo) {
56863
+ <symphiq-pacing-status-badge
56864
+ [viewMode]="viewMode()"
56865
+ [pacingPercentage]="stage.pacingInfo.pacingPercentage"
56866
+ [status]="stage.pacingInfo.status"
56867
+ />
56868
+ }
56869
+ <div [ngClass]="percentageBadgeClasses()" class="px-4 py-2 rounded-lg font-bold text-sm">
56870
+ +{{ formatPercentage(stage.stageMetric.percentageIncrease, 1) }}
56871
+ </div>
56872
+ </div>
56873
+ </div>
56874
+
56875
+ <div class="grid grid-cols-3 gap-4 mb-4">
56876
+ <div>
56877
+ <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56878
+ {{ priorYear() }} Actual
56879
+ </p>
56880
+ <p [ngClass]="valueClasses()" class="text-2xl font-bold">
56881
+ {{ formatMetricValue(stage.stageMetric.currentValue, stage.stageMetric.metric) }}
56882
+ </p>
56883
+ </div>
56884
+ @if (stage.pacingInfo) {
56885
+ <div>
56886
+ <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56887
+ {{ currentYear() }} Projected
56888
+ </p>
56889
+ <p [ngClass]="projectedValueClasses()" class="text-2xl font-bold">
56890
+ {{ formatMetricValue(stage.pacingInfo.projectedValue, stage.stageMetric.metric, false) }}
56891
+ </p>
56892
+ </div>
56893
+ }
56894
+ <div>
56895
+ <p [ngClass]="labelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56896
+ {{ currentYear() }} Target
56897
+ </p>
56898
+ <p [ngClass]="targetValueClasses()" class="text-2xl font-bold">
56899
+ {{ formatMetricValue(stage.stageMetric.targetValue, stage.stageMetric.metric) }}
56900
+ </p>
56901
+ </div>
56902
+ </div>
56903
+
56904
+ @if (stage.relatedMetrics.length > 0) {
56905
+ <div [ngClass]="dividerClasses()" class="my-4"></div>
56906
+
56907
+ <div class="space-y-2">
56908
+ <p [ngClass]="relatedTitleClasses()" class="text-xs font-semibold uppercase tracking-wider mb-3">
56909
+ Related Metrics
56910
+ </p>
56911
+ <div class="grid gap-2">
56912
+ @for (metric of stage.relatedMetrics; track metric.calc.metric) {
56913
+ <div [ngClass]="relatedMetricCardClasses()" class="p-3 rounded-lg">
56914
+ <div class="flex items-center justify-between mb-2">
56915
+ <div class="flex items-center gap-2 flex-1">
56916
+ <p [ngClass]="relatedMetricNameClasses()" class="text-sm font-semibold leading-tight">
56917
+ {{ getMetricTitle(metric.calc) }}
56918
+ </p>
56919
+ @if (metric.calc.description) {
56920
+ <button
56921
+ type="button"
56922
+ [ngClass]="infoIconClasses()"
56923
+ class="flex-shrink-0 w-5 h-5 rounded-full inline-flex items-center justify-center transition-colors"
56924
+ [libSymphiqTooltip]="getMarkdownTooltipContent(metric.calc.description, getMetricTitle(metric.calc))"
56925
+ tooltipType="markdown"
56926
+ tooltipPosition="right">
56927
+ <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
56928
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
56929
+ </svg>
56930
+ </button>
56931
+ }
56932
+ </div>
56933
+ <div class="flex items-center gap-2">
56934
+ @if (metric.pacingInfo) {
56935
+ <symphiq-pacing-status-badge
56936
+ [viewMode]="viewMode()"
56937
+ [pacingPercentage]="metric.pacingInfo.pacingPercentage"
56938
+ [status]="metric.pacingInfo.status"
56939
+ />
56940
+ }
56941
+ <span [ngClass]="relatedPercentageBadgeClasses()" class="px-2 py-1 rounded text-xs font-bold">
56942
+ +{{ formatPercentage(metric.calc.percentageIncrease, 1) }}
56943
+ </span>
56944
+ </div>
56945
+ </div>
56946
+ <div class="grid gap-2 text-xs" [ngClass]="metric.pacingInfo ? 'grid-cols-3' : 'grid-cols-2'">
56947
+ <div>
56948
+ <p [ngClass]="relatedLabelClasses()">{{ priorYear() }}: {{ formatMetricValue(metric.calc.currentValue, metric.calc.metric) }}</p>
56949
+ </div>
56950
+ @if (metric.pacingInfo) {
56951
+ <div>
56952
+ <p [ngClass]="relatedLabelClasses()">Proj: {{ formatMetricValue(metric.pacingInfo.projectedValue, metric.calc.metric, false) }}</p>
56953
+ </div>
56954
+ }
56955
+ <div>
56956
+ <p [ngClass]="relatedLabelClasses()">Target: {{ formatMetricValue(metric.calc.targetValue, metric.calc.metric) }}</p>
56957
+ </div>
56958
+ </div>
56959
+ </div>
56960
+ }
56961
+ </div>
56962
+ </div>
56963
+ }
56964
+ </div>
56965
+ }
56966
+ </div>
56967
+ </div>
56354
56968
  `
56355
56969
  }]
56356
56970
  }], null, { viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], calculations: [{ type: i0.Input, args: [{ isSignal: true, alias: "calculations", required: false }] }], pacingMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "pacingMetrics", required: false }] }] }); })();
@@ -57146,359 +57760,10 @@ var areaChart_component = /*#__PURE__*/Object.freeze({
57146
57760
  AreaChartComponent: AreaChartComponent
57147
57761
  });
57148
57762
 
57149
- function calculateMetricTargetsFromRevenue(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues) {
57150
- const revenuePercentageIncrease = ((revenueTarget - priorYearRevenue) / priorYearRevenue) * 100;
57151
- const metricCalculations = [];
57152
- const sortedFunnelMetrics = [...funnelMetrics].sort((a, b) => {
57153
- const aFunnel = a.funnelInd ?? 999;
57154
- const bFunnel = b.funnelInd ?? 999;
57155
- if (aFunnel !== bFunnel)
57156
- return aFunnel - bFunnel;
57157
- const aRelated = a.relatedInd ?? 999;
57158
- const bRelated = b.relatedInd ?? 999;
57159
- return aRelated - bRelated;
57160
- });
57161
- const funnelStages = getUniqueFunnelStages(sortedFunnelMetrics);
57162
- const numFunnelStages = funnelStages.length;
57163
- const revenueIncreaseFactor = revenueTarget / priorYearRevenue;
57164
- const perStageFactor = Math.pow(revenueIncreaseFactor, 1 / numFunnelStages);
57165
- const funnelStageMetrics = new Map();
57166
- sortedFunnelMetrics.forEach(fm => {
57167
- if (fm.funnelMetric) {
57168
- if (!funnelStageMetrics.has(fm.funnelMetric)) {
57169
- funnelStageMetrics.set(fm.funnelMetric, []);
57170
- }
57171
- funnelStageMetrics.get(fm.funnelMetric).push(fm);
57172
- }
57173
- });
57174
- const stagePercentageIncrease = (perStageFactor - 1) * 100;
57175
- sortedFunnelMetrics.forEach((funnelMetric) => {
57176
- const metric = funnelMetric.relatedMetric;
57177
- if (!metric)
57178
- return;
57179
- const currentValue = baselineValues.get(metric) || 0;
57180
- const isFunnelStage = funnelMetric.funnelMetric === metric;
57181
- let percentageIncrease;
57182
- let targetValue;
57183
- if (metric === MetricEnum.BOUNCE_RATE) {
57184
- percentageIncrease = -stagePercentageIncrease;
57185
- targetValue = currentValue * (1 + percentageIncrease / 100);
57186
- }
57187
- else if (isDerivedMetric(metric)) {
57188
- percentageIncrease = 0;
57189
- targetValue = currentValue;
57190
- }
57191
- else {
57192
- percentageIncrease = stagePercentageIncrease;
57193
- targetValue = currentValue * perStageFactor;
57194
- }
57195
- metricCalculations.push({
57196
- metric,
57197
- funnelMetric: funnelMetric.funnelMetric,
57198
- currentValue,
57199
- targetValue,
57200
- percentageIncrease,
57201
- isFunnelStage,
57202
- funnelInd: funnelMetric.funnelInd,
57203
- relatedInd: funnelMetric.relatedInd,
57204
- description: funnelMetric.relatedMetricDescription
57205
- });
57206
- });
57207
- return {
57208
- revenueTarget,
57209
- revenuePercentageIncrease,
57210
- metricCalculations
57211
- };
57212
- }
57213
- function getUniqueFunnelStages(funnelMetrics) {
57214
- const stages = [];
57215
- const seen = new Set();
57216
- funnelMetrics.forEach(fm => {
57217
- if (fm.funnelMetric && fm.funnelMetric === fm.relatedMetric && !seen.has(fm.funnelMetric)) {
57218
- seen.add(fm.funnelMetric);
57219
- stages.push(fm.funnelMetric);
57220
- }
57221
- });
57222
- return stages;
57223
- }
57224
- const DERIVED_METRICS = new Set([
57225
- MetricEnum.REVENUE_PER_PRODUCT_VIEW,
57226
- MetricEnum.REVENUE_PER_ADD_TO_CART,
57227
- MetricEnum.REVENUE_PER_CHECKOUT
57228
- ]);
57229
- function isDerivedMetric(metric) {
57230
- return DERIVED_METRICS.has(metric);
57231
- }
57232
- function generateTargetsFromCalculations(shopId, calculations) {
57233
- const startDate = getCurrentYearStart();
57234
- const endDate = getCurrentYearEnd();
57235
- return calculations.map((calc) => ({
57236
- shopId,
57237
- metric: calc.metric,
57238
- amount: calc.targetValue,
57239
- startDate,
57240
- endDate
57241
- }));
57242
- }
57243
- function groupMetricsByFunnelStage(calculations) {
57244
- const grouped = new Map();
57245
- calculations.forEach((calc) => {
57246
- if (calc.funnelMetric) {
57247
- if (!grouped.has(calc.funnelMetric)) {
57248
- grouped.set(calc.funnelMetric, []);
57249
- }
57250
- grouped.get(calc.funnelMetric).push(calc);
57251
- }
57252
- });
57253
- return grouped;
57254
- }
57255
- function getFunnelStageMetrics(calculations) {
57256
- return calculations.filter((calc) => calc.isFunnelStage);
57257
- }
57258
-
57259
- function transformUiDataToChartSeries(mainUiData, ytdComparisonUiData, metricToExtract) {
57260
- const series = [];
57261
- if (ytdComparisonUiData?.convertedDataResults) {
57262
- const priorYearSeries = extractSeriesFromConvertedData(ytdComparisonUiData.convertedDataResults, metricToExtract, 'Prior Year');
57263
- if (priorYearSeries) {
57264
- series.push(priorYearSeries);
57265
- }
57266
- }
57267
- if (mainUiData?.convertedDataResults) {
57268
- const currentYearSeries = extractSeriesFromConvertedData(mainUiData.convertedDataResults, metricToExtract, 'Current Year');
57269
- if (currentYearSeries) {
57270
- series.push(currentYearSeries);
57271
- }
57272
- }
57273
- return series;
57274
- }
57275
- function extractSeriesFromConvertedData(convertedData, metricToExtract, seriesName) {
57276
- const metricIndex = convertedData.metrics?.indexOf(metricToExtract);
57277
- if (metricIndex === undefined || metricIndex === -1)
57278
- return null;
57279
- const dimensionIndex = convertedData.dimensions?.indexOf(DimensionEnum.MONTH);
57280
- if (dimensionIndex === undefined || dimensionIndex === -1)
57281
- return null;
57282
- const dataPoints = [];
57283
- convertedData.rows?.forEach((row) => {
57284
- const monthValue = row.dimensionValues?.[dimensionIndex];
57285
- const metricValue = parseFloat(row.metricValues?.[metricIndex] || '0');
57286
- if (monthValue) {
57287
- dataPoints.push({
57288
- category: monthValue,
57289
- value: metricValue,
57290
- displayLabel: formatMonthLabel(monthValue)
57291
- });
57292
- }
57293
- });
57294
- return {
57295
- name: seriesName,
57296
- data: sortDataByMonth(dataPoints)
57297
- };
57298
- }
57299
- function formatMonthLabel(monthValue) {
57300
- const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
57301
- const monthNum = parseInt(monthValue, 10);
57302
- if (monthNum >= 1 && monthNum <= 12) {
57303
- return months[monthNum - 1];
57304
- }
57305
- return monthValue;
57306
- }
57307
- function sortDataByMonth(data) {
57308
- return data.sort((a, b) => {
57309
- const aMonth = parseInt(a.category, 10);
57310
- const bMonth = parseInt(b.category, 10);
57311
- return aMonth - bMonth;
57312
- });
57313
- }
57314
- function transformTrendUiDataToChartSeries(trendUiData, metricToExtract) {
57315
- if (!trendUiData?.convertedDataResults) {
57316
- return [];
57317
- }
57318
- const convertedData = trendUiData.convertedDataResults;
57319
- const metricIndex = convertedData.metrics?.indexOf(metricToExtract);
57320
- if (metricIndex === undefined || metricIndex === -1)
57321
- return [];
57322
- const dateIndex = convertedData.dimensions?.indexOf(DimensionEnum.DATE);
57323
- const monthIndex = convertedData.dimensions?.indexOf(DimensionEnum.MONTH);
57324
- const dimensionIndex = dateIndex !== undefined && dateIndex !== -1
57325
- ? dateIndex
57326
- : (monthIndex !== undefined && monthIndex !== -1 ? monthIndex : -1);
57327
- if (dimensionIndex === -1)
57328
- return [];
57329
- const currentYear = new Date().getFullYear();
57330
- const priorYear = currentYear - 1;
57331
- const priorYearPoints = [];
57332
- const currentYearPoints = [];
57333
- convertedData.rows?.forEach((row) => {
57334
- const dimValue = row.dimensionValues?.[dimensionIndex];
57335
- const metricValue = parseFloat(row.metricValues?.[metricIndex] || '0');
57336
- if (dimValue) {
57337
- let year;
57338
- let month;
57339
- if (dimValue.includes('-')) {
57340
- const parts = dimValue.split('-');
57341
- year = parseInt(parts[0], 10);
57342
- month = parseInt(parts[1], 10);
57343
- }
57344
- else if (dimValue.length >= 6) {
57345
- year = parseInt(dimValue.substring(0, 4), 10);
57346
- month = parseInt(dimValue.substring(4, 6), 10);
57347
- }
57348
- else {
57349
- month = parseInt(dimValue, 10);
57350
- year = currentYear;
57351
- }
57352
- const point = {
57353
- category: String(month),
57354
- value: metricValue,
57355
- displayLabel: formatMonthLabel(String(month))
57356
- };
57357
- if (year === priorYear) {
57358
- priorYearPoints.push(point);
57359
- }
57360
- else if (year === currentYear) {
57361
- currentYearPoints.push(point);
57362
- }
57363
- }
57364
- });
57365
- const series = [];
57366
- if (priorYearPoints.length > 0) {
57367
- series.push({
57368
- name: String(priorYear),
57369
- data: aggregateAndSortByMonth(priorYearPoints)
57370
- });
57371
- }
57372
- if (currentYearPoints.length > 0) {
57373
- series.push({
57374
- name: String(currentYear),
57375
- data: aggregateAndSortByMonth(currentYearPoints)
57376
- });
57377
- }
57378
- return series;
57379
- }
57380
- function aggregateAndSortByMonth(points) {
57381
- const monthMap = new Map();
57382
- points.forEach(point => {
57383
- const existing = monthMap.get(point.category);
57384
- if (existing) {
57385
- existing.value += point.value;
57386
- }
57387
- else {
57388
- monthMap.set(point.category, { ...point });
57389
- }
57390
- });
57391
- return sortDataByMonth(Array.from(monthMap.values()));
57392
- }
57393
- function getConvertedDataForSource(uiData, source) {
57394
- if (!uiData)
57395
- return undefined;
57396
- const periodInfo = uiData.periodInfo;
57397
- let result;
57398
- switch (source) {
57399
- case 'current':
57400
- result = uiData.convertedDataResults;
57401
- break;
57402
- case 'compare':
57403
- result = uiData.convertedDataResultsCompare;
57404
- break;
57405
- case 'priorYear':
57406
- if (periodInfo?.period === UiDataPeriodEnum.THIS_YEAR &&
57407
- periodInfo?.comparePeriod === UiDataComparePeriodEnum.PREVIOUS_PERIOD) {
57408
- result = uiData.convertedDataResultsCompare;
57409
- }
57410
- else if (periodInfo?.period === UiDataPeriodEnum.THIS_AND_LAST_YEAR) {
57411
- result = uiData.convertedDataResults;
57412
- }
57413
- else if (periodInfo?.comparePeriod === UiDataComparePeriodEnum.SAME_PERIOD_LAST_YEAR) {
57414
- result = uiData.convertedDataResultsCompare;
57415
- }
57416
- else if (periodInfo?.comparePeriod === UiDataComparePeriodEnum.PREVIOUS_PERIOD) {
57417
- result = uiData.convertedDataResultsCompare;
57418
- }
57419
- else {
57420
- result = uiData.convertedDataResultsCompare;
57421
- }
57422
- break;
57423
- }
57424
- return result;
57425
- }
57426
- function sumMetricFromUiData(uiData, metricToSum, source = 'current') {
57427
- const convertedData = getConvertedDataForSource(uiData, source);
57428
- if (!convertedData) {
57429
- return 0;
57430
- }
57431
- let total = 0;
57432
- const metricIndex = convertedData.metrics?.indexOf(metricToSum);
57433
- if (metricIndex === undefined || metricIndex === -1) {
57434
- return 0;
57435
- }
57436
- convertedData.rows?.forEach((row) => {
57437
- const rawValue = row.metricValues?.[metricIndex];
57438
- const metricValue = parseFloat(rawValue || '0');
57439
- total += metricValue;
57440
- });
57441
- return total;
57442
- }
57443
-
57444
- class RevenueCalculatorService {
57445
- calculateTargetsFromRevenue(revenueTarget, mainUiData, funnelMetrics) {
57446
- const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
57447
- const baselineValues = this.extractBaselineValues(mainUiData, funnelMetrics);
57448
- return calculateMetricTargetsFromRevenue(revenueTarget, priorYearRevenue, funnelMetrics, baselineValues);
57449
- }
57450
- calculateTargetsFromPercentage(percentageIncrease, mainUiData, funnelMetrics) {
57451
- const priorYearRevenue = this.extractPriorYearRevenue(mainUiData);
57452
- const revenueTarget = priorYearRevenue * (1 + percentageIncrease / 100);
57453
- return this.calculateTargetsFromRevenue(revenueTarget, mainUiData, funnelMetrics);
57454
- }
57455
- extractPriorYearRevenue(mainUiData) {
57456
- return sumMetricFromUiData(mainUiData, MetricEnum.PURCHASE_REVENUE, 'priorYear');
57457
- }
57458
- extractBaselineValues(mainUiData, funnelMetrics) {
57459
- const baselineValues = new Map();
57460
- if (!mainUiData) {
57461
- return baselineValues;
57462
- }
57463
- funnelMetrics.forEach(fm => {
57464
- if (fm.relatedMetric) {
57465
- const value = sumMetricFromUiData(mainUiData, fm.relatedMetric, 'priorYear');
57466
- baselineValues.set(fm.relatedMetric, value);
57467
- }
57468
- });
57469
- return baselineValues;
57470
- }
57471
- getMetricsByFunnelStage(calculations) {
57472
- const grouped = new Map();
57473
- calculations.forEach(calc => {
57474
- if (calc.isFunnelStage) {
57475
- if (!grouped.has(calc.metric)) {
57476
- grouped.set(calc.metric, []);
57477
- }
57478
- grouped.get(calc.metric).push(calc);
57479
- }
57480
- else if (calc.funnelMetric) {
57481
- if (!grouped.has(calc.funnelMetric)) {
57482
- grouped.set(calc.funnelMetric, []);
57483
- }
57484
- grouped.get(calc.funnelMetric).push(calc);
57485
- }
57486
- });
57487
- return grouped;
57488
- }
57489
- static { this.ɵfac = function RevenueCalculatorService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RevenueCalculatorService)(); }; }
57490
- static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: RevenueCalculatorService, factory: RevenueCalculatorService.ɵfac, providedIn: 'root' }); }
57491
- }
57492
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RevenueCalculatorService, [{
57493
- type: Injectable,
57494
- args: [{
57495
- providedIn: 'root'
57496
- }]
57497
- }], null, null); })();
57498
-
57499
57763
  const _c0$r = ["absoluteInputRef"];
57764
+ const _c1$b = ["percentageInputRef"];
57500
57765
  function InitialTargetSettingComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
57501
- i0.ɵɵelementStart(0, "p", 8);
57766
+ i0.ɵɵelementStart(0, "p", 9);
57502
57767
  i0.ɵɵtext(1);
57503
57768
  i0.ɵɵelementEnd();
57504
57769
  } if (rf & 2) {
@@ -57509,10 +57774,10 @@ function InitialTargetSettingComponent_Conditional_12_Template(rf, ctx) { if (rf
57509
57774
  } }
57510
57775
  function InitialTargetSettingComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
57511
57776
  const _r2 = i0.ɵɵgetCurrentView();
57512
- i0.ɵɵelementStart(0, "div", 11)(1, "span", 18);
57777
+ i0.ɵɵelementStart(0, "div", 12)(1, "span", 19);
57513
57778
  i0.ɵɵtext(2, " $ ");
57514
57779
  i0.ɵɵelementEnd();
57515
- i0.ɵɵelementStart(3, "input", 19, 0);
57780
+ i0.ɵɵelementStart(3, "input", 20, 0);
57516
57781
  i0.ɵɵtwoWayListener("ngModelChange", function InitialTargetSettingComponent_Conditional_18_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.absoluteInput, $event) || (ctx_r0.absoluteInput = $event); return i0.ɵɵresetView($event); });
57517
57782
  i0.ɵɵlistener("ngModelChange", function InitialTargetSettingComponent_Conditional_18_Template_input_ngModelChange_3_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onAbsoluteInputChange()); });
57518
57783
  i0.ɵɵelementEnd()();
@@ -57526,32 +57791,32 @@ function InitialTargetSettingComponent_Conditional_18_Template(rf, ctx) { if (rf
57526
57791
  } }
57527
57792
  function InitialTargetSettingComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
57528
57793
  const _r3 = i0.ɵɵgetCurrentView();
57529
- i0.ɵɵelementStart(0, "div", 11)(1, "input", 20);
57794
+ i0.ɵɵelementStart(0, "div", 12)(1, "input", 21, 1);
57530
57795
  i0.ɵɵtwoWayListener("ngModelChange", function InitialTargetSettingComponent_Conditional_19_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.percentageInput, $event) || (ctx_r0.percentageInput = $event); return i0.ɵɵresetView($event); });
57531
57796
  i0.ɵɵlistener("ngModelChange", function InitialTargetSettingComponent_Conditional_19_Template_input_ngModelChange_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onPercentageInputChange()); });
57532
57797
  i0.ɵɵelementEnd();
57533
- i0.ɵɵelementStart(2, "span", 21);
57534
- i0.ɵɵtext(3, " % ");
57798
+ i0.ɵɵelementStart(3, "span", 22);
57799
+ i0.ɵɵtext(4, " % ");
57535
57800
  i0.ɵɵelementEnd()();
57536
57801
  } if (rf & 2) {
57537
57802
  const ctx_r0 = i0.ɵɵnextContext();
57538
57803
  i0.ɵɵadvance();
57539
57804
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.percentageInput);
57540
57805
  i0.ɵɵproperty("ngClass", ctx_r0.inputClasses());
57541
- i0.ɵɵadvance();
57806
+ i0.ɵɵadvance(2);
57542
57807
  i0.ɵɵproperty("ngClass", ctx_r0.inputSuffixClasses());
57543
57808
  } }
57544
57809
  function InitialTargetSettingComponent_Conditional_20_Conditional_18_Template(rf, ctx) { if (rf & 1) {
57545
- i0.ɵɵelementStart(0, "div", 25)(1, "div")(2, "p", 23);
57810
+ i0.ɵɵelementStart(0, "div", 26)(1, "div")(2, "p", 24);
57546
57811
  i0.ɵɵtext(3, " Gap to Close ");
57547
57812
  i0.ɵɵelementEnd();
57548
- i0.ɵɵelementStart(4, "p", 26);
57813
+ i0.ɵɵelementStart(4, "p", 27);
57549
57814
  i0.ɵɵtext(5);
57550
57815
  i0.ɵɵelementEnd()();
57551
- i0.ɵɵelementStart(6, "div")(7, "p", 23);
57816
+ i0.ɵɵelementStart(6, "div")(7, "p", 24);
57552
57817
  i0.ɵɵtext(8, " Additional Growth Needed ");
57553
57818
  i0.ɵɵelementEnd();
57554
- i0.ɵɵelementStart(9, "p", 26);
57819
+ i0.ɵɵelementStart(9, "p", 27);
57555
57820
  i0.ɵɵtext(10);
57556
57821
  i0.ɵɵelementEnd()()();
57557
57822
  } if (rf & 2) {
@@ -57571,25 +57836,25 @@ function InitialTargetSettingComponent_Conditional_20_Conditional_18_Template(rf
57571
57836
  i0.ɵɵtextInterpolate2(" ", ctx_r0.gapToClose().amount > 0 ? "+" : "", "", ctx_r0.formatPercentage(ctx_r0.gapToClose().percentage, 1), " ");
57572
57837
  } }
57573
57838
  function InitialTargetSettingComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
57574
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 22)(2, "div")(3, "p", 23);
57839
+ i0.ɵɵelementStart(0, "div", 13)(1, "div", 23)(2, "div")(3, "p", 24);
57575
57840
  i0.ɵɵtext(4);
57576
57841
  i0.ɵɵelementEnd();
57577
- i0.ɵɵelementStart(5, "p", 24);
57842
+ i0.ɵɵelementStart(5, "p", 25);
57578
57843
  i0.ɵɵtext(6);
57579
57844
  i0.ɵɵelementEnd()();
57580
- i0.ɵɵelementStart(7, "div", 25)(8, "div")(9, "p", 23);
57845
+ i0.ɵɵelementStart(7, "div", 26)(8, "div")(9, "p", 24);
57581
57846
  i0.ɵɵtext(10, " Increase Amount ");
57582
57847
  i0.ɵɵelementEnd();
57583
- i0.ɵɵelementStart(11, "p", 26);
57848
+ i0.ɵɵelementStart(11, "p", 27);
57584
57849
  i0.ɵɵtext(12);
57585
57850
  i0.ɵɵelementEnd()();
57586
- i0.ɵɵelementStart(13, "div")(14, "p", 23);
57851
+ i0.ɵɵelementStart(13, "div")(14, "p", 24);
57587
57852
  i0.ɵɵtext(15, " % Growth ");
57588
57853
  i0.ɵɵelementEnd();
57589
- i0.ɵɵelementStart(16, "p", 26);
57854
+ i0.ɵɵelementStart(16, "p", 27);
57590
57855
  i0.ɵɵtext(17);
57591
57856
  i0.ɵɵelementEnd()()();
57592
- i0.ɵɵconditionalCreate(18, InitialTargetSettingComponent_Conditional_20_Conditional_18_Template, 11, 8, "div", 25);
57857
+ i0.ɵɵconditionalCreate(18, InitialTargetSettingComponent_Conditional_20_Conditional_18_Template, 11, 8, "div", 26);
57593
57858
  i0.ɵɵelementEnd()();
57594
57859
  } if (rf & 2) {
57595
57860
  const ctx_r0 = i0.ɵɵnextContext();
@@ -57620,13 +57885,13 @@ function InitialTargetSettingComponent_Conditional_20_Template(rf, ctx) { if (rf
57620
57885
  i0.ɵɵconditional(ctx_r0.currentPaceProjection() > 0 && ctx_r0.gapToClose().amount !== 0 ? 18 : -1);
57621
57886
  } }
57622
57887
  function InitialTargetSettingComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
57623
- i0.ɵɵelement(0, "symphiq-area-chart", 15);
57888
+ i0.ɵɵelement(0, "symphiq-area-chart", 16);
57624
57889
  } if (rf & 2) {
57625
57890
  const ctx_r0 = i0.ɵɵnextContext();
57626
57891
  i0.ɵɵproperty("chart", ctx_r0.revenueChartData())("showAxisLabels", true)("viewMode", ctx_r0.viewMode())("currencySymbol", "$")("height", "320px");
57627
57892
  } }
57628
57893
  function InitialTargetSettingComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
57629
- i0.ɵɵelementStart(0, "div", 16)(1, "p", 27);
57894
+ i0.ɵɵelementStart(0, "div", 17)(1, "p", 28);
57630
57895
  i0.ɵɵtext(2, " No revenue data available ");
57631
57896
  i0.ɵɵelementEnd()();
57632
57897
  } if (rf & 2) {
@@ -57635,13 +57900,13 @@ function InitialTargetSettingComponent_Conditional_26_Template(rf, ctx) { if (rf
57635
57900
  i0.ɵɵproperty("ngClass", ctx_r0.noDataClasses());
57636
57901
  } }
57637
57902
  function InitialTargetSettingComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
57638
- i0.ɵɵelementStart(0, "div", 2)(1, "div", 28)(2, "h2", 29);
57903
+ i0.ɵɵelementStart(0, "div", 3)(1, "div", 29)(2, "h2", 30);
57639
57904
  i0.ɵɵtext(3, " Contributing Metrics ");
57640
57905
  i0.ɵɵelementEnd();
57641
- i0.ɵɵelementStart(4, "p", 27);
57906
+ i0.ɵɵelementStart(4, "p", 28);
57642
57907
  i0.ɵɵtext(5);
57643
57908
  i0.ɵɵelementEnd()();
57644
- i0.ɵɵelement(6, "symphiq-funnel-metrics-visualization", 30);
57909
+ i0.ɵɵelement(6, "symphiq-funnel-metrics-visualization", 31);
57645
57910
  i0.ɵɵelementEnd();
57646
57911
  } if (rf & 2) {
57647
57912
  const ctx_r0 = i0.ɵɵnextContext();
@@ -57711,20 +57976,41 @@ class InitialTargetSettingComponent {
57711
57976
  }, ...(ngDevMode ? [{ debugName: "percentageIncrease" }] : []));
57712
57977
  this.metricCalculations = computed(() => {
57713
57978
  const revenue = this.calculatedRevenue();
57714
- if (revenue <= 0)
57979
+ console.log('=== METRIC CALCULATIONS START ===');
57980
+ console.log('Revenue Target:', revenue);
57981
+ if (revenue <= 0) {
57982
+ console.log('Revenue is <= 0, returning empty array');
57715
57983
  return [];
57984
+ }
57716
57985
  const mode = this.inputMode();
57717
57986
  const mainData = this.mainUiData();
57718
57987
  const metrics = this.funnelMetrics();
57988
+ const priorRevenue = this.priorYearRevenue();
57989
+ console.log('Input Mode:', mode);
57990
+ console.log('Prior Year Revenue:', priorRevenue);
57991
+ console.log('Funnel Metrics Count:', metrics.length);
57992
+ console.log('Main UI Data available:', !!mainData);
57993
+ let result;
57719
57994
  if (mode === 'absolute') {
57720
- return this.revenueCalcService.calculateTargetsFromRevenue(revenue, mainData, metrics).metricCalculations;
57995
+ console.log('Using calculateTargetsFromRevenueWithRatios (NEW REVERSE ALGORITHM)');
57996
+ result = this.revenueCalcService.calculateTargetsFromRevenueWithRatios(revenue, mainData, metrics);
57997
+ console.log('Adjustment Applied:', result.adjustmentApplied);
57721
57998
  }
57722
57999
  else {
57723
58000
  const pct = this.percentageInput();
57724
- if (pct === null)
58001
+ console.log('Percentage Input:', pct);
58002
+ if (pct === null) {
58003
+ console.log('Percentage is null, returning empty array');
57725
58004
  return [];
57726
- return this.revenueCalcService.calculateTargetsFromPercentage(pct, mainData, metrics).metricCalculations;
57727
- }
58005
+ }
58006
+ console.log('Using calculateTargetsFromPercentageWithRatios (NEW REVERSE ALGORITHM)');
58007
+ result = this.revenueCalcService.calculateTargetsFromPercentageWithRatios(pct, mainData, metrics);
58008
+ console.log('Adjustment Applied:', result.adjustmentApplied);
58009
+ }
58010
+ console.log('Metric Calculations Count:', result.metricCalculations.length);
58011
+ console.log('Metric Calculations:', result.metricCalculations);
58012
+ console.log('=== METRIC CALCULATIONS END ===');
58013
+ return result.metricCalculations;
57728
58014
  }, ...(ngDevMode ? [{ debugName: "metricCalculations" }] : []));
57729
58015
  this.isValid = computed(() => {
57730
58016
  return this.calculatedRevenue() > 0 && this.priorYearRevenue() > 0;
@@ -57773,6 +58059,14 @@ class InitialTargetSettingComponent {
57773
58059
  }
57774
58060
  setInputMode(mode) {
57775
58061
  this.inputMode.set(mode);
58062
+ setTimeout(() => {
58063
+ if (mode === 'absolute' && this.absoluteInput() === null) {
58064
+ this.absoluteInputRef?.nativeElement?.focus();
58065
+ }
58066
+ else if (mode === 'percentage' && this.percentageInput() === null) {
58067
+ this.percentageInputRef?.nativeElement?.focus();
58068
+ }
58069
+ });
57776
58070
  }
57777
58071
  onAbsoluteInputChange() {
57778
58072
  const value = this.absoluteInput() ?? 0;
@@ -57902,41 +58196,43 @@ class InitialTargetSettingComponent {
57902
58196
  static { this.ɵfac = function InitialTargetSettingComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || InitialTargetSettingComponent)(); }; }
57903
58197
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: InitialTargetSettingComponent, selectors: [["symphiq-initial-target-setting"]], viewQuery: function InitialTargetSettingComponent_Query(rf, ctx) { if (rf & 1) {
57904
58198
  i0.ɵɵviewQuery(_c0$r, 5);
58199
+ i0.ɵɵviewQuery(_c1$b, 5);
57905
58200
  } if (rf & 2) {
57906
58201
  let _t;
57907
58202
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.absoluteInputRef = _t.first);
57908
- } }, inputs: { viewMode: [1, "viewMode"], funnelMetrics: [1, "funnelMetrics"], mainUiData: [1, "mainUiData"], trendUiData: [1, "trendUiData"], shopId: [1, "shopId"], pacingMetrics: [1, "pacingMetrics"], dataResults: [1, "dataResults"] }, outputs: { targetsCreated: "targetsCreated" }, decls: 29, vars: 21, consts: [["absoluteInputRef", ""], [1, "space-y-8", "pb-32"], [1, "rounded-2xl", "border", "shadow-lg", "p-8", 3, "ngClass"], [1, "text-2xl", "font-bold", "mb-6", 3, "ngClass"], [1, "grid", "lg:grid-cols-2", "gap-8"], [1, "space-y-6"], [1, "block", "text-sm", "font-semibold", "mb-2", 3, "ngClass"], [1, "space-y-1", "mb-4"], [1, "text-xs", 3, "ngClass"], [1, "flex", "gap-2", "mb-4"], [1, "flex-1", "py-2", "px-4", "rounded-lg", "text-sm", "font-semibold", "transition-all", 3, "click", "ngClass"], [1, "relative"], [1, "p-6", "rounded-xl", "border-2", 3, "ngClass"], [1, "text-sm", "font-semibold", "mb-3", 3, "ngClass"], [1, "rounded-xl", "border", "p-4", 3, "ngClass"], [3, "chart", "showAxisLabels", "viewMode", "currencySymbol", "height"], [1, "h-64", "flex", "items-center", "justify-center"], [3, "submitClick", "viewMode", "isValid", "isSubmitting", "validationMessage", "buttonText"], [1, "absolute", "left-4", "top-1/2", "-translate-y-1/2", "text-xl", "font-bold", 3, "ngClass"], ["type", "number", "placeholder", "0", "min", "0", "step", "1000", 1, "w-full", "pl-10", "pr-4", "py-4", "rounded-xl", "text-2xl", "font-bold", "border-2", "transition-all", 3, "ngModelChange", "ngModel", "ngClass"], ["type", "number", "placeholder", "0", "min", "0", "max", "1000", "step", "0.1", 1, "w-full", "pr-10", "pl-4", "py-4", "rounded-xl", "text-2xl", "font-bold", "border-2", "transition-all", 3, "ngModelChange", "ngModel", "ngClass"], [1, "absolute", "right-4", "top-1/2", "-translate-y-1/2", "text-xl", "font-bold", 3, "ngClass"], [1, "space-y-4"], [1, "text-xs", "font-medium", "uppercase", "tracking-wider", "mb-1", 3, "ngClass"], [1, "text-3xl", "font-bold", 3, "ngClass"], [1, "grid", "grid-cols-2", "gap-4", "pt-4", 3, "ngClass"], [1, "text-xl", "font-bold", 3, "ngClass"], [1, "text-sm", 3, "ngClass"], [1, "mb-6"], [1, "text-2xl", "font-bold", "mb-2", 3, "ngClass"], [3, "viewMode", "calculations", "pacingMetrics"]], template: function InitialTargetSettingComponent_Template(rf, ctx) { if (rf & 1) {
57909
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h2", 3);
58203
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.percentageInputRef = _t.first);
58204
+ } }, inputs: { viewMode: [1, "viewMode"], funnelMetrics: [1, "funnelMetrics"], mainUiData: [1, "mainUiData"], trendUiData: [1, "trendUiData"], shopId: [1, "shopId"], pacingMetrics: [1, "pacingMetrics"], dataResults: [1, "dataResults"] }, outputs: { targetsCreated: "targetsCreated" }, decls: 29, vars: 21, consts: [["absoluteInputRef", ""], ["percentageInputRef", ""], [1, "space-y-8", "pb-32"], [1, "rounded-2xl", "border", "shadow-lg", "p-8", 3, "ngClass"], [1, "text-2xl", "font-bold", "mb-6", 3, "ngClass"], [1, "grid", "lg:grid-cols-2", "gap-8"], [1, "space-y-6"], [1, "block", "text-sm", "font-semibold", "mb-2", 3, "ngClass"], [1, "space-y-1", "mb-4"], [1, "text-xs", 3, "ngClass"], [1, "flex", "gap-2", "mb-4"], [1, "flex-1", "py-2", "px-4", "rounded-lg", "text-sm", "font-semibold", "transition-all", 3, "click", "ngClass"], [1, "relative"], [1, "p-6", "rounded-xl", "border-2", 3, "ngClass"], [1, "text-sm", "font-semibold", "mb-3", 3, "ngClass"], [1, "rounded-xl", "border", "p-4", 3, "ngClass"], [3, "chart", "showAxisLabels", "viewMode", "currencySymbol", "height"], [1, "h-64", "flex", "items-center", "justify-center"], [3, "submitClick", "viewMode", "isValid", "isSubmitting", "validationMessage", "buttonText"], [1, "absolute", "left-4", "top-1/2", "-translate-y-1/2", "text-xl", "font-bold", 3, "ngClass"], ["type", "number", "placeholder", "0", "min", "0", "step", "1000", 1, "w-full", "pl-10", "pr-4", "py-4", "rounded-xl", "text-2xl", "font-bold", "border-2", "transition-all", 3, "ngModelChange", "ngModel", "ngClass"], ["type", "number", "placeholder", "0", "min", "0", "max", "1000", "step", "0.1", 1, "w-full", "pr-10", "pl-4", "py-4", "rounded-xl", "text-2xl", "font-bold", "border-2", "transition-all", 3, "ngModelChange", "ngModel", "ngClass"], [1, "absolute", "right-4", "top-1/2", "-translate-y-1/2", "text-xl", "font-bold", 3, "ngClass"], [1, "space-y-4"], [1, "text-xs", "font-medium", "uppercase", "tracking-wider", "mb-1", 3, "ngClass"], [1, "text-3xl", "font-bold", 3, "ngClass"], [1, "grid", "grid-cols-2", "gap-4", "pt-4", 3, "ngClass"], [1, "text-xl", "font-bold", 3, "ngClass"], [1, "text-sm", 3, "ngClass"], [1, "mb-6"], [1, "text-2xl", "font-bold", "mb-2", 3, "ngClass"], [3, "viewMode", "calculations", "pacingMetrics"]], template: function InitialTargetSettingComponent_Template(rf, ctx) { if (rf & 1) {
58205
+ i0.ɵɵelementStart(0, "div", 2)(1, "div", 3)(2, "h2", 4);
57910
58206
  i0.ɵɵtext(3, " Calculate Your Revenue Target ");
57911
58207
  i0.ɵɵelementEnd();
57912
- i0.ɵɵelementStart(4, "div", 4)(5, "div", 5)(6, "div")(7, "label", 6);
58208
+ i0.ɵɵelementStart(4, "div", 5)(5, "div", 6)(6, "div")(7, "label", 7);
57913
58209
  i0.ɵɵtext(8);
57914
58210
  i0.ɵɵelementEnd();
57915
- i0.ɵɵelementStart(9, "div", 7)(10, "p", 8);
58211
+ i0.ɵɵelementStart(9, "div", 8)(10, "p", 9);
57916
58212
  i0.ɵɵtext(11);
57917
58213
  i0.ɵɵelementEnd();
57918
- i0.ɵɵconditionalCreate(12, InitialTargetSettingComponent_Conditional_12_Template, 2, 2, "p", 8);
58214
+ i0.ɵɵconditionalCreate(12, InitialTargetSettingComponent_Conditional_12_Template, 2, 2, "p", 9);
57919
58215
  i0.ɵɵelementEnd();
57920
- i0.ɵɵelementStart(13, "div", 9)(14, "button", 10);
58216
+ i0.ɵɵelementStart(13, "div", 10)(14, "button", 11);
57921
58217
  i0.ɵɵlistener("click", function InitialTargetSettingComponent_Template_button_click_14_listener() { return ctx.setInputMode("absolute"); });
57922
58218
  i0.ɵɵtext(15, " Absolute Amount ");
57923
58219
  i0.ɵɵelementEnd();
57924
- i0.ɵɵelementStart(16, "button", 10);
58220
+ i0.ɵɵelementStart(16, "button", 11);
57925
58221
  i0.ɵɵlistener("click", function InitialTargetSettingComponent_Template_button_click_16_listener() { return ctx.setInputMode("percentage"); });
57926
58222
  i0.ɵɵtext(17, " % Increase ");
57927
58223
  i0.ɵɵelementEnd()();
57928
- i0.ɵɵconditionalCreate(18, InitialTargetSettingComponent_Conditional_18_Template, 5, 3, "div", 11)(19, InitialTargetSettingComponent_Conditional_19_Template, 4, 3, "div", 11);
58224
+ i0.ɵɵconditionalCreate(18, InitialTargetSettingComponent_Conditional_18_Template, 5, 3, "div", 12)(19, InitialTargetSettingComponent_Conditional_19_Template, 5, 3, "div", 12);
57929
58225
  i0.ɵɵelementEnd();
57930
- i0.ɵɵconditionalCreate(20, InitialTargetSettingComponent_Conditional_20_Template, 19, 13, "div", 12);
58226
+ i0.ɵɵconditionalCreate(20, InitialTargetSettingComponent_Conditional_20_Template, 19, 13, "div", 13);
57931
58227
  i0.ɵɵelementEnd();
57932
- i0.ɵɵelementStart(21, "div")(22, "p", 13);
58228
+ i0.ɵɵelementStart(21, "div")(22, "p", 14);
57933
58229
  i0.ɵɵtext(23, " Year-over-Year Revenue Trend ");
57934
58230
  i0.ɵɵelementEnd();
57935
- i0.ɵɵelementStart(24, "div", 14);
57936
- i0.ɵɵconditionalCreate(25, InitialTargetSettingComponent_Conditional_25_Template, 1, 5, "symphiq-area-chart", 15)(26, InitialTargetSettingComponent_Conditional_26_Template, 3, 1, "div", 16);
58231
+ i0.ɵɵelementStart(24, "div", 15);
58232
+ i0.ɵɵconditionalCreate(25, InitialTargetSettingComponent_Conditional_25_Template, 1, 5, "symphiq-area-chart", 16)(26, InitialTargetSettingComponent_Conditional_26_Template, 3, 1, "div", 17);
57937
58233
  i0.ɵɵelementEnd()()()();
57938
- i0.ɵɵconditionalCreate(27, InitialTargetSettingComponent_Conditional_27_Template, 7, 7, "div", 2);
57939
- i0.ɵɵelementStart(28, "symphiq-sticky-submit-bar", 17);
58234
+ i0.ɵɵconditionalCreate(27, InitialTargetSettingComponent_Conditional_27_Template, 7, 7, "div", 3);
58235
+ i0.ɵɵelementStart(28, "symphiq-sticky-submit-bar", 18);
57940
58236
  i0.ɵɵlistener("submitClick", function InitialTargetSettingComponent_Template_symphiq_sticky_submit_bar_submitClick_28_listener() { return ctx.handleSubmit(); });
57941
58237
  i0.ɵɵelementEnd()();
57942
58238
  } if (rf & 2) {
@@ -57989,194 +58285,198 @@ class InitialTargetSettingComponent {
57989
58285
  AreaChartComponent
57990
58286
  ],
57991
58287
  changeDetection: ChangeDetectionStrategy.OnPush,
57992
- template: `
57993
- <div class="space-y-8 pb-32">
57994
- <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
57995
- <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-6">
57996
- Calculate Your Revenue Target
57997
- </h2>
57998
-
57999
- <div class="grid lg:grid-cols-2 gap-8">
58000
- <div class="space-y-6">
58001
- <div>
58002
- <label [ngClass]="labelClasses()" class="block text-sm font-semibold mb-2">
58003
- {{ currentYear() }} Revenue
58004
- </label>
58005
- <div class="space-y-1 mb-4">
58006
- <p [ngClass]="priorYearLabelClasses()" class="text-xs">
58007
- {{ priorYear() }} Revenue: {{ formatCurrency(priorYearRevenue()) }}
58008
- </p>
58009
- @if (currentPaceProjection() > 0) {
58010
- <p [ngClass]="priorYearLabelClasses()" class="text-xs">
58011
- Current Pace Projection: {{ formatCurrency(currentPaceProjection()) }}
58012
- </p>
58013
- }
58014
- </div>
58015
-
58016
- <div class="flex gap-2 mb-4">
58017
- <button
58018
- (click)="setInputMode('absolute')"
58019
- [ngClass]="inputModeButtonClasses('absolute')"
58020
- class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
58021
- Absolute Amount
58022
- </button>
58023
- <button
58024
- (click)="setInputMode('percentage')"
58025
- [ngClass]="inputModeButtonClasses('percentage')"
58026
- class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
58027
- % Increase
58028
- </button>
58029
- </div>
58030
-
58031
- @if (inputMode() === 'absolute') {
58032
- <div class="relative">
58033
- <span [ngClass]="inputPrefixClasses()" class="absolute left-4 top-1/2 -translate-y-1/2 text-xl font-bold">
58034
- $
58035
- </span>
58036
- <input
58037
- #absoluteInputRef
58038
- type="number"
58039
- [(ngModel)]="absoluteInput"
58040
- (ngModelChange)="onAbsoluteInputChange()"
58041
- [ngClass]="inputClasses()"
58042
- class="w-full pl-10 pr-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
58043
- placeholder="0"
58044
- min="0"
58045
- step="1000">
58046
- </div>
58047
- } @else {
58048
- <div class="relative">
58049
- <input
58050
- type="number"
58051
- [(ngModel)]="percentageInput"
58052
- (ngModelChange)="onPercentageInputChange()"
58053
- [ngClass]="inputClasses()"
58054
- class="w-full pr-10 pl-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
58055
- placeholder="0"
58056
- min="0"
58057
- max="1000"
58058
- step="0.1">
58059
- <span [ngClass]="inputSuffixClasses()" class="absolute right-4 top-1/2 -translate-y-1/2 text-xl font-bold">
58060
- %
58061
- </span>
58062
- </div>
58063
- }
58064
- </div>
58065
-
58066
- @if (calculatedRevenue() > 0) {
58067
- <div [ngClass]="calculatedValuesCardClasses()" class="p-6 rounded-xl border-2">
58068
- <div class="space-y-4">
58069
- <div>
58070
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58071
- {{ currentYear() }} Revenue Target
58072
- </p>
58073
- <p [ngClass]="calculatedValueClasses()" class="text-3xl font-bold">
58074
- {{ formatCurrency(calculatedRevenue()) }}
58075
- </p>
58076
- </div>
58077
- <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
58078
- <div>
58079
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58080
- Increase Amount
58081
- </p>
58082
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58083
- {{ formatCurrency(calculatedRevenue() - priorYearRevenue()) }}
58084
- </p>
58085
- </div>
58086
- <div>
58087
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58088
- % Growth
58089
- </p>
58090
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58091
- +{{ formatPercentage(percentageIncrease(), 1) }}
58092
- </p>
58093
- </div>
58094
- </div>
58095
- @if (currentPaceProjection() > 0 && gapToClose().amount !== 0) {
58096
- <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
58097
- <div>
58098
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58099
- Gap to Close
58100
- </p>
58101
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58102
- {{ formatCurrency(absValue(gapToClose().amount)) }}
58103
- </p>
58104
- </div>
58105
- <div>
58106
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58107
- Additional Growth Needed
58108
- </p>
58109
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58110
- {{ gapToClose().amount > 0 ? '+' : '' }}{{ formatPercentage(gapToClose().percentage, 1) }}
58111
- </p>
58112
- </div>
58113
- </div>
58114
- }
58115
- </div>
58116
- </div>
58117
- }
58118
- </div>
58119
-
58120
- <div>
58121
- <p [ngClass]="chartTitleClasses()" class="text-sm font-semibold mb-3">
58122
- Year-over-Year Revenue Trend
58123
- </p>
58124
- <div [ngClass]="chartContainerClasses()" class="rounded-xl border p-4">
58125
- @if (revenueChartData()) {
58126
- <symphiq-area-chart
58127
- [chart]="revenueChartData()!"
58128
- [showAxisLabels]="true"
58129
- [viewMode]="viewMode()"
58130
- [currencySymbol]="'$'"
58131
- [height]="'320px'"
58132
- />
58133
- } @else {
58134
- <div class="h-64 flex items-center justify-center">
58135
- <p [ngClass]="noDataClasses()" class="text-sm">
58136
- No revenue data available
58137
- </p>
58138
- </div>
58139
- }
58140
- </div>
58141
- </div>
58142
- </div>
58143
- </div>
58144
-
58145
- @if (showMetricsVisualization()) {
58146
- <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
58147
- <div class="mb-6">
58148
- <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-2">
58149
- Contributing Metrics
58150
- </h2>
58151
- <p [ngClass]="sectionDescriptionClasses()" class="text-sm">
58152
- To achieve your revenue target of {{ formatCurrency(calculatedRevenue()) }}, the following metrics need to improve by these amounts. These improvements compound through your funnel to drive revenue growth.
58153
- </p>
58154
- </div>
58155
-
58156
- <symphiq-funnel-metrics-visualization
58157
- [viewMode]="viewMode()"
58158
- [calculations]="metricCalculations()"
58159
- [pacingMetrics]="pacingMetrics()"
58160
- />
58161
- </div>
58162
- }
58163
-
58164
- <symphiq-sticky-submit-bar
58165
- [viewMode]="viewMode()"
58166
- [isValid]="isValid()"
58167
- [isSubmitting]="isSubmitting()"
58168
- [validationMessage]="validationMessage()"
58169
- [buttonText]="'Set Revenue Targets'"
58170
- (submitClick)="handleSubmit()"
58171
- />
58172
- </div>
58288
+ template: `
58289
+ <div class="space-y-8 pb-32">
58290
+ <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
58291
+ <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-6">
58292
+ Calculate Your Revenue Target
58293
+ </h2>
58294
+
58295
+ <div class="grid lg:grid-cols-2 gap-8">
58296
+ <div class="space-y-6">
58297
+ <div>
58298
+ <label [ngClass]="labelClasses()" class="block text-sm font-semibold mb-2">
58299
+ {{ currentYear() }} Revenue
58300
+ </label>
58301
+ <div class="space-y-1 mb-4">
58302
+ <p [ngClass]="priorYearLabelClasses()" class="text-xs">
58303
+ {{ priorYear() }} Revenue: {{ formatCurrency(priorYearRevenue()) }}
58304
+ </p>
58305
+ @if (currentPaceProjection() > 0) {
58306
+ <p [ngClass]="priorYearLabelClasses()" class="text-xs">
58307
+ Current Pace Projection: {{ formatCurrency(currentPaceProjection()) }}
58308
+ </p>
58309
+ }
58310
+ </div>
58311
+
58312
+ <div class="flex gap-2 mb-4">
58313
+ <button
58314
+ (click)="setInputMode('absolute')"
58315
+ [ngClass]="inputModeButtonClasses('absolute')"
58316
+ class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
58317
+ Absolute Amount
58318
+ </button>
58319
+ <button
58320
+ (click)="setInputMode('percentage')"
58321
+ [ngClass]="inputModeButtonClasses('percentage')"
58322
+ class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
58323
+ % Increase
58324
+ </button>
58325
+ </div>
58326
+
58327
+ @if (inputMode() === 'absolute') {
58328
+ <div class="relative">
58329
+ <span [ngClass]="inputPrefixClasses()" class="absolute left-4 top-1/2 -translate-y-1/2 text-xl font-bold">
58330
+ $
58331
+ </span>
58332
+ <input
58333
+ #absoluteInputRef
58334
+ type="number"
58335
+ [(ngModel)]="absoluteInput"
58336
+ (ngModelChange)="onAbsoluteInputChange()"
58337
+ [ngClass]="inputClasses()"
58338
+ class="w-full pl-10 pr-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
58339
+ placeholder="0"
58340
+ min="0"
58341
+ step="1000">
58342
+ </div>
58343
+ } @else {
58344
+ <div class="relative">
58345
+ <input
58346
+ #percentageInputRef
58347
+ type="number"
58348
+ [(ngModel)]="percentageInput"
58349
+ (ngModelChange)="onPercentageInputChange()"
58350
+ [ngClass]="inputClasses()"
58351
+ class="w-full pr-10 pl-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
58352
+ placeholder="0"
58353
+ min="0"
58354
+ max="1000"
58355
+ step="0.1">
58356
+ <span [ngClass]="inputSuffixClasses()" class="absolute right-4 top-1/2 -translate-y-1/2 text-xl font-bold">
58357
+ %
58358
+ </span>
58359
+ </div>
58360
+ }
58361
+ </div>
58362
+
58363
+ @if (calculatedRevenue() > 0) {
58364
+ <div [ngClass]="calculatedValuesCardClasses()" class="p-6 rounded-xl border-2">
58365
+ <div class="space-y-4">
58366
+ <div>
58367
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58368
+ {{ currentYear() }} Revenue Target
58369
+ </p>
58370
+ <p [ngClass]="calculatedValueClasses()" class="text-3xl font-bold">
58371
+ {{ formatCurrency(calculatedRevenue()) }}
58372
+ </p>
58373
+ </div>
58374
+ <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
58375
+ <div>
58376
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58377
+ Increase Amount
58378
+ </p>
58379
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58380
+ {{ formatCurrency(calculatedRevenue() - priorYearRevenue()) }}
58381
+ </p>
58382
+ </div>
58383
+ <div>
58384
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58385
+ % Growth
58386
+ </p>
58387
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58388
+ +{{ formatPercentage(percentageIncrease(), 1) }}
58389
+ </p>
58390
+ </div>
58391
+ </div>
58392
+ @if (currentPaceProjection() > 0 && gapToClose().amount !== 0) {
58393
+ <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
58394
+ <div>
58395
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58396
+ Gap to Close
58397
+ </p>
58398
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58399
+ {{ formatCurrency(absValue(gapToClose().amount)) }}
58400
+ </p>
58401
+ </div>
58402
+ <div>
58403
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
58404
+ Additional Growth Needed
58405
+ </p>
58406
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
58407
+ {{ gapToClose().amount > 0 ? '+' : '' }}{{ formatPercentage(gapToClose().percentage, 1) }}
58408
+ </p>
58409
+ </div>
58410
+ </div>
58411
+ }
58412
+ </div>
58413
+ </div>
58414
+ }
58415
+ </div>
58416
+
58417
+ <div>
58418
+ <p [ngClass]="chartTitleClasses()" class="text-sm font-semibold mb-3">
58419
+ Year-over-Year Revenue Trend
58420
+ </p>
58421
+ <div [ngClass]="chartContainerClasses()" class="rounded-xl border p-4">
58422
+ @if (revenueChartData()) {
58423
+ <symphiq-area-chart
58424
+ [chart]="revenueChartData()!"
58425
+ [showAxisLabels]="true"
58426
+ [viewMode]="viewMode()"
58427
+ [currencySymbol]="'$'"
58428
+ [height]="'320px'"
58429
+ />
58430
+ } @else {
58431
+ <div class="h-64 flex items-center justify-center">
58432
+ <p [ngClass]="noDataClasses()" class="text-sm">
58433
+ No revenue data available
58434
+ </p>
58435
+ </div>
58436
+ }
58437
+ </div>
58438
+ </div>
58439
+ </div>
58440
+ </div>
58441
+
58442
+ @if (showMetricsVisualization()) {
58443
+ <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
58444
+ <div class="mb-6">
58445
+ <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-2">
58446
+ Contributing Metrics
58447
+ </h2>
58448
+ <p [ngClass]="sectionDescriptionClasses()" class="text-sm">
58449
+ To achieve your revenue target of {{ formatCurrency(calculatedRevenue()) }}, the following metrics need to improve by these amounts. These improvements compound through your funnel to drive revenue growth.
58450
+ </p>
58451
+ </div>
58452
+
58453
+ <symphiq-funnel-metrics-visualization
58454
+ [viewMode]="viewMode()"
58455
+ [calculations]="metricCalculations()"
58456
+ [pacingMetrics]="pacingMetrics()"
58457
+ />
58458
+ </div>
58459
+ }
58460
+
58461
+ <symphiq-sticky-submit-bar
58462
+ [viewMode]="viewMode()"
58463
+ [isValid]="isValid()"
58464
+ [isSubmitting]="isSubmitting()"
58465
+ [validationMessage]="validationMessage()"
58466
+ [buttonText]="'Set Revenue Targets'"
58467
+ (submitClick)="handleSubmit()"
58468
+ />
58469
+ </div>
58173
58470
  `
58174
58471
  }]
58175
58472
  }], () => [], { absoluteInputRef: [{
58176
58473
  type: ViewChild,
58177
58474
  args: ['absoluteInputRef']
58475
+ }], percentageInputRef: [{
58476
+ type: ViewChild,
58477
+ args: ['percentageInputRef']
58178
58478
  }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], funnelMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "funnelMetrics", required: false }] }], mainUiData: [{ type: i0.Input, args: [{ isSignal: true, alias: "mainUiData", required: false }] }], trendUiData: [{ type: i0.Input, args: [{ isSignal: true, alias: "trendUiData", required: false }] }], shopId: [{ type: i0.Input, args: [{ isSignal: true, alias: "shopId", required: false }] }], pacingMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "pacingMetrics", required: false }] }], dataResults: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataResults", required: false }] }], targetsCreated: [{ type: i0.Output, args: ["targetsCreated"] }] }); })();
58179
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(InitialTargetSettingComponent, { className: "InitialTargetSettingComponent", filePath: "lib/components/revenue-calculator-dashboard/initial-target-setting.component.ts", lineNumber: 217 }); })();
58479
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(InitialTargetSettingComponent, { className: "InitialTargetSettingComponent", filePath: "lib/components/revenue-calculator-dashboard/initial-target-setting.component.ts", lineNumber: 218 }); })();
58180
58480
 
58181
58481
  function IndeterminateSpinnerComponent_For_5_Template(rf, ctx) { if (rf & 1) {
58182
58482
  i0.ɵɵelement(0, "div", 5);
@@ -108614,5 +108914,5 @@ const PROFILE_ANALYSIS_METRIC_SCREEN_PAGE_VIEWS = ({
108614
108914
  * Generated bundle index. Do not edit.
108615
108915
  */
108616
108916
 
108617
- export { AreaChartComponent, BUSINESS_PROFILE, BarChartComponent, BreakdownSectionComponent, BusinessAnalysisModalComponent, BusinessProfileSearchService, ChartCardComponent, ChartContainerComponent, ChartThemeService, CircularProgressComponent, CompetitivePositioningSummaryComponent, CompetitorAnalysisCardComponent, ConfettiService, ConfidenceLevelCardComponent, ContentGenerationProgressComponent, ContentGenerationProgressWithConfettiComponent, CrossDashboardRelationshipsService, FUNNEL_ANALYSIS, FloatingBackButtonComponent, FloatingTocComponent, FocusAreaDetailCardComponent, FocusAreaExecutiveSummaryComponent, FocusAreaQuestionComponent, FocusAreaToolsModalComponent, FunnelOrderService, GradeBadgeComponent, HeaderScrollService, HierarchyDisplayComponent, HorizontalBarComponent, IconService, IndeterminateSpinnerComponent, InsightCardComponent, JourneyProgressIndicatorComponent, JourneyStepIdEnum, LineChartComponent, MetricCardComponent, MetricExecutiveSummaryComponent, MetricFormatterService, MetricListItemComponent, MetricWelcomeBannerComponent, MobileBottomNavComponent, MobileFABComponent, ModalComponent, ModalService, NapkinVisualPlaceholderComponent, NavigationStateService, OpportunityHighlightBannerComponent, OverallAssessmentComponent, PROFILE_ANALYSIS_FOCUS_AREA_AFFILIATE, PROFILE_ANALYSIS_METRIC_SCREEN_PAGE_VIEWS, PROFILE_ANALYSIS_SHOP, PieChartComponent, ProfileItemCardComponent, ProfileSectionComponent, ProfileSubsectionComponent, RelatedContentSidebarComponent, RevenueCalculatorWelcomeBannerComponent, ScrollDepthService, ScrollProgressBarComponent, SearchButtonComponent, SearchModalComponent, SectionDividerComponent, SectionNavigationComponent, ShadowElevationDirective, ShopPlatformEnum, ShopWelcomeBannerComponent, SkeletonBarComponent, SkeletonCardBaseComponent, SkeletonCircleComponent, SkeletonCompetitorCardComponent, SkeletonCustomerSegmentCardComponent, SkeletonFocusAreaCardComponent, SkeletonGenericCardComponent, SkeletonLoaderComponent, SkeletonPriceTierCardComponent, SkeletonProductCategoryCardComponent, SkeletonRegionCardComponent, SkeletonSeasonCardComponent, SymphiqBusinessAnalysisDashboardComponent, SymphiqConnectGaDashboardComponent, SymphiqCreateAccountDashboardComponent, SymphiqFunnelAnalysisDashboardComponent, SymphiqFunnelAnalysisPreviewComponent, SymphiqIconComponent, SymphiqProfileAnalysisDashboardComponent, SymphiqRevenueCalculatorDashboardComponent, SymphiqWelcomeDashboardComponent, TooltipContainerComponent, TooltipDataService, TooltipDirective, TooltipService, ViewModeService, ViewportAnimationDirective, VisualizationContainerComponent, getBadgeLabelClasses, getButtonClasses, getCategoryBadgeClasses, getCategoryColor, getCompetitiveBadgeClasses, getContainerClasses, getFooterClasses, getGradeBadgeClasses, getHeaderClasses, getInsightsBadgeClasses, getInsightsCardClasses, getMetricLabelClasses, getMetricMiniCardClasses, getMetricValueClasses, getNarrativeTextClasses, getRevenueCardClasses, getRevenueIconClasses, getStatusBadgeClasses, getStatusDotClasses, getStatusIconClasses, getStatusSummaryClasses, getSubtitleClasses, getTitleClasses, getTrendClasses, getTrendIconClasses, getTrendValueClasses, isLightMode };
108917
+ export { AreaChartComponent, BUSINESS_PROFILE, BarChartComponent, BreakdownSectionComponent, BusinessAnalysisModalComponent, BusinessProfileSearchService, ChartCardComponent, ChartContainerComponent, ChartThemeService, CircularProgressComponent, CompetitivePositioningSummaryComponent, CompetitorAnalysisCardComponent, ConfettiService, ConfidenceLevelCardComponent, ContentGenerationProgressComponent, ContentGenerationProgressWithConfettiComponent, CrossDashboardRelationshipsService, FUNNEL_ANALYSIS, FloatingBackButtonComponent, FloatingTocComponent, FocusAreaDetailCardComponent, FocusAreaExecutiveSummaryComponent, FocusAreaQuestionComponent, FocusAreaToolsModalComponent, FunnelOrderService, GradeBadgeComponent, HeaderScrollService, HierarchyDisplayComponent, HorizontalBarComponent, IconService, IndeterminateSpinnerComponent, InsightCardComponent, JourneyProgressIndicatorComponent, JourneyStepIdEnum, LineChartComponent, MetricCardComponent, MetricExecutiveSummaryComponent, MetricFormatterService, MetricListItemComponent, MetricWelcomeBannerComponent, MobileBottomNavComponent, MobileFABComponent, ModalComponent, ModalService, NapkinVisualPlaceholderComponent, NavigationStateService, OpportunityHighlightBannerComponent, OverallAssessmentComponent, PROFILE_ANALYSIS_FOCUS_AREA_AFFILIATE, PROFILE_ANALYSIS_METRIC_SCREEN_PAGE_VIEWS, PROFILE_ANALYSIS_SHOP, PieChartComponent, ProfileItemCardComponent, ProfileSectionComponent, ProfileSubsectionComponent, RelatedContentSidebarComponent, RevenueCalculatorService, RevenueCalculatorWelcomeBannerComponent, ScrollDepthService, ScrollProgressBarComponent, SearchButtonComponent, SearchModalComponent, SectionDividerComponent, SectionNavigationComponent, ShadowElevationDirective, ShopPlatformEnum, ShopWelcomeBannerComponent, SkeletonBarComponent, SkeletonCardBaseComponent, SkeletonCircleComponent, SkeletonCompetitorCardComponent, SkeletonCustomerSegmentCardComponent, SkeletonFocusAreaCardComponent, SkeletonGenericCardComponent, SkeletonLoaderComponent, SkeletonPriceTierCardComponent, SkeletonProductCategoryCardComponent, SkeletonRegionCardComponent, SkeletonSeasonCardComponent, SymphiqBusinessAnalysisDashboardComponent, SymphiqConnectGaDashboardComponent, SymphiqCreateAccountDashboardComponent, SymphiqFunnelAnalysisDashboardComponent, SymphiqFunnelAnalysisPreviewComponent, SymphiqIconComponent, SymphiqProfileAnalysisDashboardComponent, SymphiqRevenueCalculatorDashboardComponent, SymphiqWelcomeDashboardComponent, TooltipContainerComponent, TooltipDataService, TooltipDirective, TooltipService, ViewModeService, ViewportAnimationDirective, VisualizationContainerComponent, calculateFunnelRatios, calculateMetricTargetsFromRevenue, calculateMetricTargetsFromRevenueReverse, calculateRelatedMetricRatios, generateTargetsFromCalculations, getBadgeLabelClasses, getButtonClasses, getCategoryBadgeClasses, getCategoryColor, getCompetitiveBadgeClasses, getContainerClasses, getFooterClasses, getFunnelStageMetrics, getGradeBadgeClasses, getHeaderClasses, getInsightsBadgeClasses, getInsightsCardClasses, getMetricLabelClasses, getMetricMiniCardClasses, getMetricValueClasses, getNarrativeTextClasses, getRevenueCardClasses, getRevenueIconClasses, getStatusBadgeClasses, getStatusDotClasses, getStatusIconClasses, getStatusSummaryClasses, getSubtitleClasses, getTitleClasses, getTrendClasses, getTrendIconClasses, getTrendValueClasses, groupMetricsByFunnelStage, isLightMode, validateRevenueTarget };
108618
108918
  //# sourceMappingURL=symphiq-components.mjs.map