@git-stats-components/vue 1.0.2 → 1.0.4

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 +1 @@
1
- {"version":3,"file":"vue.umd.js","sources":["../../core/src/api/fetchGitStats.ts","../../core/src/utils/generateDummyData.js","../../core/src/index.ts","../src/composables/useGitStats.ts","../src/components/ContributionGraph.vue","../src/components/StatsBreakdown.vue","../src/index.ts"],"sourcesContent":["import type { GitStatsData } from '../types'\r\n\r\nexport async function fetchGitStats(url: string): Promise<GitStatsData> {\r\n\tconst response = await fetch(url)\r\n\tif (!response.ok) {\r\n\t\tthrow new Error(`Failed to fetch git stats: ${response.statusText}`)\r\n\t}\r\n\treturn response.json()\r\n}\r\n","/**\n * Generate realistic dummy data for testing and development\n */\n\n/**\n * Generate dummy contribution data (53 weeks)\n */\nexport function generateDummyContributions() {\n\tconst weeks = []\n\tconst now = new Date()\n\n\t// Get the Sunday that starts the week containing today\n\tconst endDate = new Date(now)\n\tendDate.setDate(endDate.getDate() - endDate.getDay())\n\n\t// Go back exactly 52 weeks\n\tconst startDate = new Date(endDate)\n\tstartDate.setDate(startDate.getDate() - 52 * 7)\n\n\tconst currentDate = new Date(startDate)\n\n\tfor (let week = 0; week < 53; week++) {\n\t\tconst weekData = {\n\t\t\tweekStart: new Date(currentDate).toISOString().split('T')[0],\n\t\t\tcontributionDays: [],\n\t\t}\n\n\t\tfor (let day = 0; day < 7; day++) {\n\t\t\tconst isInFuture = currentDate > now\n\t\t\tconst isWeekend = day === 0 || day === 6\n\n\t\t\t// More realistic pattern: fewer commits on weekends, none in future\n\t\t\tlet dayCount = 0\n\t\t\tif (!isInFuture) {\n\t\t\t\tif (isWeekend) {\n\t\t\t\t\tdayCount =\n\t\t\t\t\t\tMath.random() < 0.3 ? Math.floor(Math.random() * 5) : 0\n\t\t\t\t} else {\n\t\t\t\t\tdayCount = Math.floor(Math.random() * 15)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tweekData.contributionDays.push({\n\t\t\t\tdate: new Date(currentDate).toISOString().split('T')[0],\n\t\t\t\tcontributionCount: dayCount,\n\t\t\t\tweekday: day,\n\t\t\t})\n\t\t\tcurrentDate.setDate(currentDate.getDate() + 1)\n\t\t}\n\n\t\tweeks.push(weekData)\n\t}\n\n\treturn weeks\n}\n\n/**\n * Generate complete dummy stats data\n */\nexport function generateDummyStats(options = {}) {\n\tconst {\n\t\tusername = 'demo-user',\n\t\tplatform = 'github',\n\t\tprojectCount = 30,\n\t\tcommitCount = 2500,\n\t} = options\n\n\tconst contributions = generateDummyContributions()\n\tconst totalContributions = contributions.reduce((total, week) => {\n\t\treturn (\n\t\t\ttotal +\n\t\t\tweek.contributionDays.reduce(\n\t\t\t\t(sum, day) => sum + day.contributionCount,\n\t\t\t\t0\n\t\t\t)\n\t\t)\n\t}, 0)\n\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [\n\t\t\t{\n\t\t\t\tusername,\n\t\t\t\tplatform,\n\t\t\t\tstats: {\n\t\t\t\t\tprojectCount,\n\t\t\t\t\tcommitCount,\n\t\t\t\t\tcontributions: contributions.map((week) => ({\n\t\t\t\t\t\tfirstDay: week.weekStart,\n\t\t\t\t\t\tcontributionDays: week.contributionDays,\n\t\t\t\t\t})),\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\ttotals: {\n\t\t\tprojectCount,\n\t\t\tcommitCount,\n\t\t},\n\t\tmetadata: {\n\t\t\tfetchedAt: Date.now(),\n\t\t\tsource: 'dummy_data',\n\t\t\tisDummy: true,\n\t\t},\n\t}\n}\n\n/**\n * Generate multiple profiles dummy data\n */\nexport function generateMultiProfileDummyStats() {\n\tconst githubProfile = generateDummyStats({\n\t\tusername: 'demo-github',\n\t\tplatform: 'github',\n\t\tprojectCount: 45,\n\t\tcommitCount: 2847,\n\t})\n\n\tconst gitlabProfile = generateDummyStats({\n\t\tusername: 'demo-gitlab',\n\t\tplatform: 'gitlab',\n\t\tprojectCount: 7,\n\t\tcommitCount: 523,\n\t})\n\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [githubProfile.profiles[0], gitlabProfile.profiles[0]],\n\t\ttotals: {\n\t\t\tprojectCount: 45 + 7,\n\t\t\tcommitCount: 2847 + 523,\n\t\t},\n\t\tmetadata: {\n\t\t\tfetchedAt: Date.now(),\n\t\t\tsource: 'dummy_data',\n\t\t\tisDummy: true,\n\t\t},\n\t}\n}\n\n/**\n * Save dummy data to a file (for testing)\n */\nexport function saveDummyDataToFile(filepath = 'dummy-git-stats.json') {\n\tconst data = generateDummyStats()\n\tconst json = JSON.stringify(data, null, '\\t')\n\n\tif (typeof window !== 'undefined') {\n\t\t// Browser environment - trigger download\n\t\tconst blob = new Blob([json], { type: 'application/json' })\n\t\tconst url = URL.createObjectURL(blob)\n\t\tconst a = document.createElement('a')\n\t\ta.href = url\n\t\ta.download = filepath\n\t\ta.click()\n\t\tURL.revokeObjectURL(url)\n\t} else {\n\t\t// Node environment\n\t\ttry {\n\t\t\tconst fs = require('fs')\n\t\t\tfs.writeFileSync(filepath, json)\n\t\t\tconsole.log(`✓ Dummy data saved to ${filepath}`)\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to save dummy data:', err)\n\t\t}\n\t}\n}\n","// packages/core/src/index.ts\n// Framework-agnostic core logic\n\n// Re-export everything from types\nexport type {\n\tColorScheme,\n\tContributionDay,\n\tContributionWeek,\n\tProfile,\n\tGitStatsData,\n\tExperienceEntry,\n\tDataSource,\n\tPlatform,\n\tProfileStats,\n\tStatsTotals,\n\tStatsMetadata,\n\tCustomStatCalculator,\n\tCustomStatCalculatorParams,\n} from './types/index.js'\n\n// Export API functions\nexport { fetchGitStats as fetchGitStatsAPI } from './api/fetchGitStats.js'\n\n// Export utility functions with explicit imports\nexport {\n\tgenerateDummyStats,\n\tgenerateDummyContributions,\n\tgenerateMultiProfileDummyStats,\n\tsaveDummyDataToFile,\n} from './utils/generateDummyData.js'\n\n// Core data fetching (framework-agnostic)\nimport type { GitStatsData } from './types/index.js'\n\nexport interface FetchOptions {\n\tdataUrl: string\n\tcacheTTL?: number\n\tcacheKey?: string\n\tuseStaleCache?: boolean\n}\n\nexport interface DataResult<T> {\n\tdata: T | null\n\terror: Error | null\n\tsource: 'static' | 'cache' | 'mock' | 'dummy' | null\n\tisDummy: boolean\n}\n\n/**\n * Framework-agnostic data fetcher\n */\nexport async function fetchGitStats(\n\toptions: FetchOptions\n): Promise<DataResult<GitStatsData>> {\n\tconst { dataUrl, cacheKey = 'git_stats_cache', useStaleCache = true } = options\n\n\ttry {\n\t\t// Try static file first\n\t\tconst response = await fetch(dataUrl)\n\t\tif (response.ok) {\n\t\t\tconst data = await response.json()\n\t\t\t// Cache the data\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tlocalStorage.setItem(\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\tcachedAt: Date.now(),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata,\n\t\t\t\terror: null,\n\t\t\t\tsource: 'static',\n\t\t\t\tisDummy: data.metadata?.isDummy === true,\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn('Failed to fetch from static file:', err)\n\t}\n\n\t// Try cache\n\tif (useStaleCache && typeof window !== 'undefined') {\n\t\ttry {\n\t\t\tconst cached = localStorage.getItem(cacheKey)\n\t\t\tif (cached) {\n\t\t\t\tconst data = JSON.parse(cached)\n\t\t\t\treturn {\n\t\t\t\t\tdata,\n\t\t\t\t\terror: null,\n\t\t\t\t\tsource: 'cache',\n\t\t\t\t\tisDummy: data.metadata?.isDummy === true,\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.warn('Failed to load from cache:', err)\n\t\t}\n\t}\n\n\t// Fallback to mock\n\tconst mockData = generateMockData()\n\treturn {\n\t\tdata: mockData,\n\t\terror: null,\n\t\tsource: 'mock',\n\t\tisDummy: false,\n\t}\n}\n\n/**\n * Format last updated time\n */\nexport function formatLastUpdated(dateString: string): string {\n\tconst date = new Date(dateString)\n\tconst now = new Date()\n\tconst diffHours = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60))\n\n\tif (diffHours < 1) return 'just now'\n\tif (diffHours < 24) return `${diffHours} hours ago`\n\n\tconst diffDays = Math.floor(diffHours / 24)\n\tif (diffDays === 1) return 'yesterday'\n\tif (diffDays < 7) return `${diffDays} days ago`\n\n\treturn date.toLocaleDateString('en-US', {\n\t\tmonth: 'short',\n\t\tday: 'numeric',\n\t\tyear: date.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,\n\t})\n}\n\n/**\n * Get contribution level (0-4)\n */\nexport function getContributionLevel(count: number): number {\n\tif (count === 0) return 0\n\tif (count <= 3) return 1\n\tif (count <= 6) return 2\n\tif (count <= 9) return 3\n\treturn 4\n}\n\n/**\n * Calculate years of experience\n */\nexport function calculateYearsExperience(\n\texperienceData: { startDate: string; endDate: string | null; skills?: string[] }[]\n): number {\n\tif (experienceData.length === 0) return 0\n\n\tconst skillExperience: Record<string, number> = {}\n\n\texperienceData.forEach((exp) => {\n\t\tconst end = exp.endDate ? new Date(exp.endDate) : new Date()\n\t\tconst start = new Date(exp.startDate)\n\t\tconst years = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24 * 365.25)\n\n\t\texp.skills?.forEach((skill) => {\n\t\t\tif (!skillExperience[skill]) {\n\t\t\t\tskillExperience[skill] = 0\n\t\t\t}\n\t\t\tskillExperience[skill] += years\n\t\t})\n\t})\n\n\treturn Math.max(...Object.values(skillExperience), 0)\n}\n\n// Mock data generator\nfunction generateMockData(): GitStatsData {\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [\n\t\t\t{\n\t\t\t\tusername: 'mockuser',\n\t\t\t\tplatform: 'github',\n\t\t\t\tstats: {\n\t\t\t\t\tprojectCount: 30,\n\t\t\t\t\tcommitCount: 2500,\n\t\t\t\t\tcontributions: [],\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\ttotals: {\n\t\t\tprojectCount: 30,\n\t\t\tcommitCount: 2500,\n\t\t},\n\t\tmetadata: {\n\t\t\tsource: 'mock',\n\t\t\tfetchedAt: Date.now(),\n\t\t},\n\t}\n}","import { ref, computed } from 'vue'\r\nimport {\r\n\tfetchGitStats,\r\n\tformatLastUpdated,\r\n\ttype GitStatsData,\r\n\ttype DataSource,\r\n} from '@git-stats-components/core'\r\n\r\nexport interface UseGitStatsConfig {\r\n\tdataUrl?: string\r\n\tcacheTTL?: number\r\n\tuseStaleCache?: boolean\r\n\tcacheKey?: string\r\n}\r\n\r\nexport function useGitStats(config: UseGitStatsConfig = {}) {\r\n\tconst {\r\n\t\tdataUrl = '/data/git-stats.json',\r\n\t\tcacheTTL = 24 * 60 * 60 * 1000,\r\n\t\tuseStaleCache = true,\r\n\t\tcacheKey = 'git_stats_cache',\r\n\t} = config\r\n\r\n\tconst loading = ref(false)\r\n\tconst error = ref<Error | null>(null)\r\n\tconst data = ref<GitStatsData | null>(null)\r\n\tconst dataSource = ref<DataSource | null>(null)\r\n\tconst isDummy = ref(false)\r\n\r\n\t/**\r\n\t * Load data with fallback strategy\r\n\t */\r\n\tasync function loadData(): Promise<GitStatsData | null> {\r\n\t\tloading.value = true\r\n\t\terror.value = null\r\n\r\n\t\ttry {\r\n\t\t\tconst result = await fetchGitStats({\r\n\t\t\t\tdataUrl,\r\n\t\t\t\tcacheTTL,\r\n\t\t\t\tcacheKey,\r\n\t\t\t\tuseStaleCache,\r\n\t\t\t})\r\n\r\n\t\t\tdata.value = result.data\r\n\t\t\terror.value = result.error\r\n\t\t\tdataSource.value = result.source\r\n\t\t\tisDummy.value = result.isDummy\r\n\r\n\t\t\treturn result.data\r\n\t\t} catch (err) {\r\n\t\t\terror.value =\r\n\t\t\t\terr instanceof Error ? err : new Error('Failed to load data')\r\n\t\t\treturn null\r\n\t\t} finally {\r\n\t\t\tloading.value = false\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Format \"last updated\" text\r\n\t */\r\n\tconst lastUpdatedText = computed(() => {\r\n\t\tif (!data.value?.lastUpdated) return ''\r\n\t\treturn formatLastUpdated(data.value.lastUpdated)\r\n\t})\r\n\r\n\t/**\r\n\t * Computed data source display text\r\n\t */\r\n\tconst dataSourceText = computed(() => {\r\n\t\tif (isDummy.value) {\r\n\t\t\treturn '⚠️ Using dummy data for testing'\r\n\t\t}\r\n\r\n\t\tswitch (dataSource.value) {\r\n\t\t\tcase 'static':\r\n\t\t\t\treturn 'Real-time data'\r\n\t\t\tcase 'cache':\r\n\t\t\t\treturn 'Cached data'\r\n\t\t\tcase 'mock':\r\n\t\t\t\treturn 'Sample data'\r\n\t\t\tdefault:\r\n\t\t\t\treturn ''\r\n\t\t}\r\n\t})\r\n\r\n\t// Auto-load on creation\r\n\tloadData()\r\n\r\n\treturn {\r\n\t\tdata,\r\n\t\tloading,\r\n\t\terror,\r\n\t\tdataSource,\r\n\t\tdataSourceText,\r\n\t\tlastUpdatedText,\r\n\t\tisDummy,\r\n\t\tloadData,\r\n\t}\r\n}\r\n","<template>\r\n\t<div class=\"git-contribution-graph\">\r\n\t\t<!-- Header -->\r\n\t\t<div class=\"graph-header\">\r\n\t\t\t<div class=\"header-info\">\r\n\t\t\t\t<h5 class=\"contribution-count\">\r\n\t\t\t\t\t{{ totalContributions.toLocaleString() }} contributions in\r\n\t\t\t\t\tthe last year\r\n\t\t\t\t</h5>\r\n\t\t\t\t<small\r\n\t\t\t\t\tclass=\"data-source-text\"\r\n\t\t\t\t\t:class=\"{ 'is-dummy': isDummy }\"\r\n\t\t\t\t>\r\n\t\t\t\t\t{{ dataSourceText }}\r\n\t\t\t\t</small>\r\n\t\t\t</div>\r\n\t\t\t<div class=\"header-actions\" v-if=\"showSettings\">\r\n\t\t\t\t<button\r\n\t\t\t\t\tclass=\"settings-btn\"\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t@click=\"toggleSettings\"\r\n\t\t\t\t>\r\n\t\t\t\t\t<slot name=\"settings-icon\">⚙️</slot>\r\n\t\t\t\t\tSettings\r\n\t\t\t\t</button>\r\n\t\t\t\t<div v-if=\"settingsOpen\" class=\"settings-dropdown\">\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\tv-for=\"scheme in colorSchemes\"\r\n\t\t\t\t\t\t:key=\"scheme\"\r\n\t\t\t\t\t\t@click=\"changeColorScheme(scheme)\"\r\n\t\t\t\t\t\tclass=\"settings-item\"\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t{{ scheme }} theme\r\n\t\t\t\t\t</button>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\r\n\t\t<!-- Loading state -->\r\n\t\t<div v-if=\"loading\" class=\"loading-state\">\r\n\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t<span>Loading contributions...</span>\r\n\t\t</div>\r\n\r\n\t\t<!-- Contribution grid -->\r\n\t\t<div v-else class=\"graph-container\">\r\n\t\t\t<div class=\"graph-content-wrapper\">\r\n\t\t\t\t<!-- Month labels -->\r\n\t\t\t\t<div class=\"months-row\">\r\n\t\t\t\t\t<div class=\"month-spacer\"></div>\r\n\t\t\t\t\t<div class=\"months-container\">\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tv-for=\"month in monthLabels\"\r\n\t\t\t\t\t\t\t:key=\"`${month.year}-${month.month}`\"\r\n\t\t\t\t\t\t\tclass=\"month-label\"\r\n\t\t\t\t\t\t\t:style=\"{\r\n\t\t\t\t\t\t\t\tgridColumn: `${month.week + 1} / span 1`,\r\n\t\t\t\t\t\t\t}\"\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{{ month.label }}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<!-- Grid with day labels -->\r\n\t\t\t\t<div class=\"grid-container\">\r\n\t\t\t\t\t<!-- Day labels -->\r\n\t\t\t\t\t<div class=\"day-labels\">\r\n\t\t\t\t\t\t<div class=\"day-label\">Mon</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\">Wed</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\">Fri</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<!-- Contribution squares -->\r\n\t\t\t\t\t<div class=\"contribution-grid\">\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tv-for=\"week in contributionData\"\r\n\t\t\t\t\t\t\t:key=\"week.weekStart\"\r\n\t\t\t\t\t\t\tclass=\"contribution-week\"\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\t\tv-for=\"day in week.days\"\r\n\t\t\t\t\t\t\t\t:key=\"day.date\"\r\n\t\t\t\t\t\t\t\tclass=\"contribution-day\"\r\n\t\t\t\t\t\t\t\t:class=\"getContributionLevel(day.count)\"\r\n\t\t\t\t\t\t\t\t:title=\"getTooltipText(day)\"\r\n\t\t\t\t\t\t\t\t@click=\"onDayClick(day)\"\r\n\t\t\t\t\t\t\t></div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Legend -->\r\n\t\t\t<div class=\"graph-footer\">\r\n\t\t\t\t<small class=\"last-updated\" v-if=\"lastUpdatedText\">\r\n\t\t\t\t\tLast updated: {{ lastUpdatedText }}\r\n\t\t\t\t</small>\r\n\t\t\t\t<div class=\"legend\">\r\n\t\t\t\t\t<small class=\"legend-label\">Less</small>\r\n\t\t\t\t\t<div class=\"legend-squares\">\r\n\t\t\t\t\t\t<div class=\"contribution-day level-0\"></div>\r\n\t\t\t\t\t\t<div class=\"contribution-day level-1\"></div>\r\n\t\t\t\t\t\t<div class=\"contribution-day level-2\"></div>\r\n\t\t\t\t\t\t<div class=\"contribution-day level-3\"></div>\r\n\t\t\t\t\t\t<div class=\"contribution-day level-4\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<small class=\"legend-label\">More</small>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch } from 'vue'\r\nimport { useGitStats } from '../composables/useGitStats'\r\nimport {\r\n\ttype ColorScheme,\r\n\ttype ContributionWeek,\r\n} from '@git-stats-components/core'\r\n\r\ninterface ProcessedWeek {\r\n\tweekStart: string\r\n\tdays: ProcessedDay[]\r\n}\r\n\r\ninterface ProcessedDay {\r\n\tdate: string\r\n\tcount: number\r\n\tweekday: number\r\n}\r\n\r\ninterface MonthLabel {\r\n\tweek: number\r\n\tmonth: number\r\n\tyear: number\r\n\tlabel: string\r\n}\r\n\r\ninterface Props {\r\n\tdataUrl?: string\r\n\tprofileIndex?: number\r\n\tcolorScheme?: ColorScheme\r\n\tshowSettings?: boolean\r\n\tcacheTTL?: number\r\n}\r\n\r\ninterface Emits {\r\n\t(e: 'day-click', data: { date: string; count: number }): void\r\n\t(e: 'color-scheme-change', scheme: ColorScheme): void\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tdataUrl: '/data/git-stats.json',\r\n\tprofileIndex: 0,\r\n\tcolorScheme: 'green',\r\n\tshowSettings: true,\r\n\tcacheTTL: 24 * 60 * 60 * 1000,\r\n})\r\n\r\nconst emit = defineEmits<Emits>()\r\n\r\n// Use the shared composable\r\nconst { data, loading, dataSourceText, lastUpdatedText, isDummy } = useGitStats(\r\n\t{\r\n\t\tdataUrl: props.dataUrl,\r\n\t\tcacheTTL: props.cacheTTL,\r\n\t}\r\n)\r\n\r\nconst currentColorScheme = ref<ColorScheme>(props.colorScheme)\r\nconst settingsOpen = ref(false)\r\nconst colorSchemes: ColorScheme[] = ['green', 'blue', 'purple', 'orange']\r\nconst contributionData = ref<ProcessedWeek[]>([])\r\nconst monthLabels = ref<MonthLabel[]>([])\r\n\r\n// Process contribution data when loaded\r\nwatch(\r\n\tdata,\r\n\t(newData) => {\r\n\t\tif (newData?.profiles?.[props.profileIndex]?.stats?.contributions) {\r\n\t\t\tconst contributions =\r\n\t\t\t\tnewData.profiles[props.profileIndex].stats.contributions\r\n\t\t\tif (contributions) {\r\n\t\t\t\tcontributionData.value = processContributions(contributions)\r\n\t\t\t\tgenerateMonthLabels()\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tcontributionData.value = []\r\n\t\t}\r\n\t},\r\n\t{ immediate: true }\r\n)\r\n\r\nconst totalContributions = computed(() => {\r\n\tif (!contributionData.value || contributionData.value.length === 0) {\r\n\t\treturn 0\r\n\t}\r\n\r\n\treturn contributionData.value.reduce((total, week) => {\r\n\t\tif (!week.days || !Array.isArray(week.days)) {\r\n\t\t\treturn total\r\n\t\t}\r\n\t\treturn (\r\n\t\t\ttotal +\r\n\t\t\tweek.days.reduce((weekTotal, day) => {\r\n\t\t\t\treturn weekTotal + (day.count || 0)\r\n\t\t\t}, 0)\r\n\t\t)\r\n\t}, 0)\r\n})\r\n\r\nfunction processContributions(\r\n\tcontributions: ContributionWeek[]\r\n): ProcessedWeek[] {\r\n\tif (!contributions || !Array.isArray(contributions)) {\r\n\t\treturn generateEmptyWeeks()\r\n\t}\r\n\r\n\tconst weeks = contributions.map((week) => ({\r\n\t\tweekStart: week.firstDay || '',\r\n\t\tdays: week.contributionDays.map((day) => ({\r\n\t\t\tdate: day.date || '',\r\n\t\t\tcount: day.contributionCount ?? 0,\r\n\t\t\tweekday: day.weekday || 0,\r\n\t\t})),\r\n\t}))\r\n\r\n\twhile (weeks.length < 53) {\r\n\t\tweeks.push(generateEmptyWeek())\r\n\t}\r\n\r\n\treturn weeks\r\n}\r\n\r\nfunction generateEmptyWeeks(): ProcessedWeek[] {\r\n\tconst weeks: ProcessedWeek[] = []\r\n\tfor (let i = 0; i < 53; i++) {\r\n\t\tweeks.push(generateEmptyWeek())\r\n\t}\r\n\treturn weeks\r\n}\r\n\r\nfunction generateEmptyWeek(): ProcessedWeek {\r\n\tconst days: ProcessedDay[] = []\r\n\tfor (let i = 0; i < 7; i++) {\r\n\t\tdays.push({ date: '', count: 0, weekday: i })\r\n\t}\r\n\treturn { weekStart: '', days }\r\n}\r\n\r\nfunction generateMonthLabels(): void {\r\n\tif (!contributionData.value || contributionData.value.length === 0) {\r\n\t\tmonthLabels.value = []\r\n\t\treturn\r\n\t}\r\n\r\n\tconst monthPositions: MonthLabel[] = []\r\n\tlet lastMonth = -1\r\n\tlet lastYear = -1\r\n\r\n\tcontributionData.value.forEach((week, weekIndex) => {\r\n\t\tif (!week.days || week.days.length === 0) return\r\n\r\n\t\tconst firstDay = week.days[0].date\r\n\t\tif (!firstDay) return\r\n\r\n\t\tconst dateParts = firstDay.split('-')\r\n\t\tif (dateParts.length !== 3) return\r\n\r\n\t\tconst [year, month] = dateParts.map(Number)\r\n\t\tif (isNaN(year) || isNaN(month)) return\r\n\r\n\t\tif (month !== lastMonth || year !== lastYear) {\r\n\t\t\tconst date = new Date(year, month - 1, 1)\r\n\t\t\tmonthPositions.push({\r\n\t\t\t\tweek: weekIndex,\r\n\t\t\t\tmonth: month - 1,\r\n\t\t\t\tyear: year,\r\n\t\t\t\tlabel: date.toLocaleDateString('en-US', { month: 'short' }),\r\n\t\t\t})\r\n\t\t\tlastMonth = month\r\n\t\t\tlastYear = year\r\n\t\t}\r\n\t})\r\n\r\n\tmonthLabels.value = monthPositions\r\n}\r\n\r\nfunction getContributionLevel(count: number): string {\r\n\tconst level = getContributionLevelNumber(count)\r\n\treturn `level-${level} ${currentColorScheme.value}`\r\n}\r\n\r\nfunction getContributionLevelNumber(count: number): number {\r\n\tif (count === 0) return 0\r\n\tif (count <= 3) return 1\r\n\tif (count <= 6) return 2\r\n\tif (count <= 9) return 3\r\n\treturn 4\r\n}\r\n\r\nfunction getTooltipText(day: ProcessedDay): string {\r\n\tif (!day.date) return ''\r\n\r\n\tconst [year, month, dayNum] = day.date.split('-').map(Number)\r\n\tconst date = new Date(year, month - 1, dayNum)\r\n\r\n\tconst formattedDate = date.toLocaleDateString('en-US', {\r\n\t\tweekday: 'short',\r\n\t\tyear: 'numeric',\r\n\t\tmonth: 'short',\r\n\t\tday: 'numeric',\r\n\t})\r\n\r\n\tconst contributionText = day.count === 1 ? 'contribution' : 'contributions'\r\n\treturn `${day.count} ${contributionText} on ${formattedDate}`\r\n}\r\n\r\nfunction onDayClick(day: ProcessedDay): void {\r\n\temit('day-click', { date: day.date, count: day.count })\r\n}\r\n\r\nfunction toggleSettings(): void {\r\n\tsettingsOpen.value = !settingsOpen.value\r\n}\r\n\r\nfunction changeColorScheme(scheme: ColorScheme): void {\r\n\tcurrentColorScheme.value = scheme\r\n\tsettingsOpen.value = false\r\n\temit('color-scheme-change', scheme)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.graph-content-wrapper {\r\n\tjustify-items: anchor-center;\r\n}\r\n.git-contribution-graph {\r\n\tfont-family:\r\n\t\t-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica,\r\n\t\tArial, sans-serif;\r\n\tfont-size: 12px;\r\n\tbackground: transparent;\r\n\tcolor: #e6edf3;\r\n\tpadding: 16px;\r\n\tmax-width: 1200px;\r\n\tmargin: 0 auto;\r\n\twidth: 100%;\r\n}\r\n\r\n.graph-header {\r\n\tdisplay: flex;\r\n\tjustify-content: space-between;\r\n\talign-items: center;\r\n\tmargin-bottom: 16px;\r\n}\r\n\r\n.contribution-count {\r\n\tmargin: 0 0 4px 0;\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n}\r\n\r\n.data-source-text {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.data-source-text.is-dummy {\r\n\tcolor: #f85149;\r\n\tfont-weight: 600;\r\n\tbackground: rgba(248, 81, 73, 0.1);\r\n\tpadding: 2px 8px;\r\n\tborder-radius: 4px;\r\n}\r\n\r\n.settings-btn {\r\n\tbackground: transparent;\r\n\tborder: 1px solid #30363d;\r\n\tcolor: #7d8590;\r\n\tpadding: 6px 12px;\r\n\tborder-radius: 6px;\r\n\tcursor: pointer;\r\n\tfont-size: 12px;\r\n}\r\n\r\n.settings-btn:hover {\r\n\tbackground: #21262d;\r\n\tcolor: #e6edf3;\r\n}\r\n\r\n.header-actions {\r\n\tposition: relative;\r\n}\r\n\r\n.settings-dropdown {\r\n\tposition: absolute;\r\n\tright: 0;\r\n\ttop: 100%;\r\n\tmargin-top: 4px;\r\n\tbackground: #21262d;\r\n\tborder: 1px solid #30363d;\r\n\tborder-radius: 6px;\r\n\tpadding: 4px;\r\n\tz-index: 10;\r\n\tmin-width: 150px;\r\n}\r\n\r\n.settings-item {\r\n\tdisplay: block;\r\n\twidth: 100%;\r\n\tbackground: transparent;\r\n\tborder: none;\r\n\tcolor: #e6edf3;\r\n\tpadding: 8px 12px;\r\n\ttext-align: left;\r\n\tcursor: pointer;\r\n\tborder-radius: 4px;\r\n}\r\n\r\n.settings-item:hover {\r\n\tbackground: #30363d;\r\n}\r\n\r\n.loading-state {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 12px;\r\n\tpadding: 40px;\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.spinner {\r\n\twidth: 20px;\r\n\theight: 20px;\r\n\tborder: 2px solid #30363d;\r\n\tborder-top-color: #58a6ff;\r\n\tborder-radius: 50%;\r\n\tanimation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n\tto {\r\n\t\ttransform: rotate(360deg);\r\n\t}\r\n}\r\n\r\n.months-row {\r\n\tdisplay: flex;\r\n\tmargin-bottom: 4px;\r\n}\r\n\r\n.month-spacer {\r\n\twidth: 27px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.months-container {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: repeat(53, 11px);\r\n\tgap: 2px;\r\n\tflex: 1;\r\n\tmargin-left: 3px;\r\n\tmin-width: 0;\r\n}\r\n\r\n.month-label {\r\n\tfont-size: 11px;\r\n\tcolor: #7d8590;\r\n\ttext-align: left;\r\n}\r\n\r\n.grid-container {\r\n\tdisplay: flex;\r\n\tgap: 3px;\r\n\tmin-width: fit-content;\r\n}\r\n\r\n.day-labels {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\twidth: 24px;\r\n\tgap: 2px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.day-label {\r\n\theight: 11px;\r\n\tfont-size: 9px;\r\n\tcolor: #7d8590;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n}\r\n\r\n.contribution-grid {\r\n\tdisplay: flex;\r\n\tgap: 2px;\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n}\r\n\r\n.contribution-week {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\tgap: 2px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.contribution-day {\r\n\twidth: 11px;\r\n\theight: 11px;\r\n\tborder-radius: 2px;\r\n\tcursor: pointer;\r\n\toutline: 1px solid rgba(27, 31, 36, 0.06);\r\n\toutline-offset: -1px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n/* Color schemes */\r\n.contribution-day.level-0.green {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.green {\r\n\tbackground-color: #0e4429;\r\n}\r\n.contribution-day.level-2.green {\r\n\tbackground-color: #006d32;\r\n}\r\n.contribution-day.level-3.green {\r\n\tbackground-color: #26a641;\r\n}\r\n.contribution-day.level-4.green {\r\n\tbackground-color: #39d353;\r\n}\r\n\r\n.contribution-day.level-0.blue {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.blue {\r\n\tbackground-color: #0a3069;\r\n}\r\n.contribution-day.level-2.blue {\r\n\tbackground-color: #1f6feb;\r\n}\r\n.contribution-day.level-3.blue {\r\n\tbackground-color: #58a6ff;\r\n}\r\n.contribution-day.level-4.blue {\r\n\tbackground-color: #79c0ff;\r\n}\r\n\r\n.contribution-day.level-0.purple {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.purple {\r\n\tbackground-color: #3b1e6d;\r\n}\r\n.contribution-day.level-2.purple {\r\n\tbackground-color: #8250df;\r\n}\r\n.contribution-day.level-3.purple {\r\n\tbackground-color: #a475f9;\r\n}\r\n.contribution-day.level-4.purple {\r\n\tbackground-color: #d2a8ff;\r\n}\r\n\r\n.contribution-day.level-0.orange {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.orange {\r\n\tbackground-color: #7d2d00;\r\n}\r\n.contribution-day.level-2.orange {\r\n\tbackground-color: #da7b00;\r\n}\r\n.contribution-day.level-3.orange {\r\n\tbackground-color: #ffa348;\r\n}\r\n.contribution-day.level-4.orange {\r\n\tbackground-color: #ffb366;\r\n}\r\n\r\n.contribution-day:hover {\r\n\toutline: 1px solid #c9d1d9;\r\n\toutline-offset: -1px;\r\n}\r\n\r\n.graph-footer {\r\n\tdisplay: flex;\r\n\tjustify-content: space-between;\r\n\talign-items: center;\r\n\tmargin-top: 8px;\r\n}\r\n\r\n.last-updated {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.legend {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: 4px;\r\n}\r\n\r\n.legend-label {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.legend-squares {\r\n\tdisplay: flex;\r\n\tgap: 2px;\r\n}\r\n\r\n.legend-squares .contribution-day {\r\n\tcursor: default;\r\n}\r\n\r\n.legend-squares .contribution-day:hover {\r\n\toutline: none;\r\n}\r\n\r\n/* Mobile responsive */\r\n@media (max-width: 768px) {\r\n\t.git-contribution-graph {\r\n\t\tpadding: 12px;\r\n\t\tfont-size: 11px;\r\n\t\toverflow-x: auto;\r\n\t}\r\n\t.months-container {\r\n\t\tgrid-template-columns: repeat(53, 10px);\r\n\t\tgap: 1px;\r\n\t}\r\n\t.grid-container {\r\n\t\tgap: 2px;\r\n\t}\r\n\t.day-labels {\r\n\t\twidth: 20px;\r\n\t}\r\n\t.day-label {\r\n\t\theight: 10px;\r\n\t\tfont-size: 8px;\r\n\t}\r\n\t.contribution-grid {\r\n\t\tgap: 1px;\r\n\t}\r\n\t.contribution-week {\r\n\t\tgap: 1px;\r\n\t}\r\n\t.contribution-day {\r\n\t\twidth: 10px;\r\n\t\theight: 10px;\r\n\t}\r\n\t.settings-btn {\r\n\t\tfont-size: 10px;\r\n\t\tpadding: 4px 8px;\r\n\t}\r\n\t.contribution-count {\r\n\t\tfont-size: 14px;\r\n\t}\r\n}\r\n\r\n@media (max-width: 480px) {\r\n\t.graph-header {\r\n\t\tflex-direction: column;\r\n\t\talign-items: flex-start;\r\n\t\tgap: 8px;\r\n\t}\r\n}\r\n</style>\r\n","<template>\r\n\t<div class=\"git-stats-breakdown\">\r\n\t\t<div class=\"stats-grid\">\r\n\t\t\t<!-- Years Experience -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-experience\">⏱️</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div class=\"stat-value\">{{ yearsExperience }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Years Experience</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Projects -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-projects\">📦</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ totalProjects }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Projects</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Commits -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-commits\">💻</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ totalCommits }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Commits</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Custom Stat -->\r\n\t\t\t<div class=\"stat-card\" v-if=\"showCustomStat\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-custom\">☕</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ customStatValue }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">\r\n\t\t\t\t\t\t<slot name=\"custom-stat-label\">Coffee Consumed</slot>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\r\n\t\t<!-- Footer -->\r\n\t\t<div class=\"stats-footer\">\r\n\t\t\t<small v-if=\"dataSourceText\" class=\"data-source\">\r\n\t\t\t\t{{ dataSourceText }}\r\n\t\t\t\t<span v-if=\"lastUpdatedText\"> · {{ lastUpdatedText }}</span>\r\n\t\t\t</small>\r\n\t\t</div>\r\n\t</div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch } from 'vue'\r\nimport { useGitStats } from '../composables/useGitStats'\r\nimport {\r\n\tcalculateYearsExperience,\r\n\ttype ExperienceEntry,\r\n\ttype CustomStatCalculator,\r\n\ttype CustomStatCalculatorParams,\r\n} from '@git-stats-components/core'\r\n\r\ninterface Props {\r\n\tdataUrl?: string\r\n\tprofileIndexes?: number[]\r\n\texperienceData?: ExperienceEntry[]\r\n\tshowCustomStat?: boolean\r\n\tcustomStatCalculator?: CustomStatCalculator | null\r\n\tcacheTTL?: number\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tdataUrl: '/data/git-stats.json',\r\n\tprofileIndexes: () => [],\r\n\texperienceData: () => [],\r\n\tshowCustomStat: true,\r\n\tcustomStatCalculator: null,\r\n\tcacheTTL: 24 * 60 * 60 * 1000,\r\n})\r\n\r\n// Use the shared composable\r\nconst { data, loading, dataSourceText, lastUpdatedText } = useGitStats({\r\n\tdataUrl: props.dataUrl,\r\n\tcacheTTL: props.cacheTTL,\r\n})\r\n\r\nconst totalProjects = ref(0)\r\nconst totalCommits = ref(0)\r\n\r\n// Calculate totals when data loads\r\nwatch(\r\n\tdata,\r\n\t(newData) => {\r\n\t\tif (!newData) return\r\n\r\n\t\t// If profileIndexes specified, sum only those profiles\r\n\t\tif (props.profileIndexes.length > 0) {\r\n\t\t\tlet projects = 0\r\n\t\t\tlet commits = 0\r\n\r\n\t\t\tprops.profileIndexes.forEach((index) => {\r\n\t\t\t\tconst profile = newData.profiles?.[index]\r\n\t\t\t\tif (profile?.stats) {\r\n\t\t\t\t\tprojects += profile.stats.projectCount || 0\r\n\t\t\t\t\tcommits += profile.stats.commitCount || 0\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t\ttotalProjects.value = projects\r\n\t\t\ttotalCommits.value = commits\r\n\t\t} else {\r\n\t\t\t// Use totals from data (aggregates all profiles)\r\n\t\t\ttotalProjects.value = newData.totals?.projectCount || 0\r\n\t\t\ttotalCommits.value = newData.totals?.commitCount || 0\r\n\t\t}\r\n\t},\r\n\t{ immediate: true }\r\n)\r\n\r\n// Calculate years of experience using core utility\r\nconst yearsExperience = computed(() => {\r\n\tconst years = calculateYearsExperience(props.experienceData)\r\n\treturn years.toFixed(1)\r\n})\r\n\r\n// Custom stat calculation\r\nconst customStatValue = computed(() => {\r\n\tif (props.customStatCalculator) {\r\n\t\tconst params: CustomStatCalculatorParams = {\r\n\t\t\tprojects: totalProjects.value,\r\n\t\t\tcommits: totalCommits.value,\r\n\t\t\tyears: parseFloat(yearsExperience.value),\r\n\t\t}\r\n\t\treturn props.customStatCalculator(params)\r\n\t}\r\n\r\n\t// Default: fun coffee calculation\r\n\tconst kA = 1.5\r\n\tconst kB = 1.2\r\n\tconst kC = 1.5\r\n\r\n\tconst cups =\r\n\t\ttotalProjects.value * kA +\r\n\t\ttotalCommits.value * kB +\r\n\t\tparseFloat(yearsExperience.value) * kC\r\n\r\n\treturn cups.toFixed(2)\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.git-stats-breakdown {\r\n\tfont-family:\r\n\t\t-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica,\r\n\t\tArial, sans-serif;\r\n\tpadding: 40px 20px;\r\n\tmax-width: 1200px;\r\n\tmargin: 0 auto;\r\n}\r\n\r\n.stats-grid {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\r\n\tgap: 24px;\r\n\tmargin-bottom: 24px;\r\n}\r\n\r\n.stat-card {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: 16px;\r\n\tpadding: 24px;\r\n\tbackground: rgba(255, 255, 255, 0.05);\r\n\tborder-radius: 12px;\r\n\tborder: 1px solid rgba(255, 255, 255, 0.1);\r\n\ttransition: all 0.3s ease;\r\n}\r\n\r\n.stat-card:hover {\r\n\tbackground: rgba(255, 255, 255, 0.08);\r\n\tborder-color: rgba(255, 255, 255, 0.2);\r\n\ttransform: translateY(-2px);\r\n}\r\n\r\n.stat-icon {\r\n\tfont-size: 48px;\r\n\tline-height: 1;\r\n\topacity: 0.9;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.stat-content {\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n}\r\n\r\n.stat-value {\r\n\tfont-size: 32px;\r\n\tfont-weight: bold;\r\n\tline-height: 1.2;\r\n\tcolor: #e6edf3;\r\n\tmargin-bottom: 4px;\r\n}\r\n\r\n.stat-label {\r\n\tfont-size: 14px;\r\n\tcolor: #7d8590;\r\n\ttext-transform: uppercase;\r\n\tletter-spacing: 0.5px;\r\n}\r\n\r\n.stat-loading {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\theight: 38px;\r\n}\r\n\r\n.spinner {\r\n\twidth: 24px;\r\n\theight: 24px;\r\n\tborder: 3px solid rgba(255, 255, 255, 0.1);\r\n\tborder-top-color: #58a6ff;\r\n\tborder-radius: 50%;\r\n\tanimation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n\tto {\r\n\t\ttransform: rotate(360deg);\r\n\t}\r\n}\r\n\r\n.stats-footer {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\talign-items: center;\r\n\tgap: 8px;\r\n\tpadding-top: 16px;\r\n\tborder-top: 1px solid rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.data-source {\r\n\tfont-size: 12px;\r\n\tcolor: #7d8590;\r\n\ttext-align: center;\r\n}\r\n\r\n/* Responsive */\r\n@media (max-width: 768px) {\r\n\t.git-stats-breakdown {\r\n\t\tpadding: 20px 12px;\r\n\t}\r\n\t.stats-grid {\r\n\t\tgrid-template-columns: 1fr;\r\n\t\tgap: 16px;\r\n\t}\r\n\t.stat-card {\r\n\t\tpadding: 16px;\r\n\t}\r\n\t.stat-icon {\r\n\t\tfont-size: 36px;\r\n\t}\r\n\t.stat-value {\r\n\t\tfont-size: 24px;\r\n\t}\r\n\t.stat-label {\r\n\t\tfont-size: 12px;\r\n\t}\r\n}\r\n\r\n@media (max-width: 480px) {\r\n\t.stat-card {\r\n\t\tflex-direction: column;\r\n\t\ttext-align: center;\r\n\t}\r\n\t.stat-content {\r\n\t\twidth: 100%;\r\n\t}\r\n}\r\n</style>\r\n","// Main entry point for git-stats-components\n\nimport type { App } from 'vue'\nimport ContributionGraph from './components/ContributionGraph.vue'\nimport StatsBreakdown from './components/StatsBreakdown.vue'\nimport { useGitStats } from './composables/useGitStats'\n\n// Re-export everything from core\nexport * from '@git-stats-components/core'\n\n// Export Vue-specific components and composables\nexport { ContributionGraph, StatsBreakdown, useGitStats }\n\n// Auto-import styles\nimport './styles/index.css'\n\n// Plugin for Vue.use()\nexport interface VueGitStatsPlugin {\n\tinstall: (app: App) => void\n}\n\nconst VueGitStats: VueGitStatsPlugin = {\n\tinstall(app: App) {\n\t\tapp.component('ContributionGraph', ContributionGraph)\n\t\tapp.component('StatsBreakdown', StatsBreakdown)\n\t},\n}\n\n// Export as default for Vue.use()\nexport default VueGitStats\n"],"names":["fetchGitStats","url","__async","response","generateDummyContributions","weeks","now","endDate","startDate","currentDate","week","weekData","day","isInFuture","isWeekend","dayCount","generateDummyStats","options","username","platform","projectCount","commitCount","contributions","total","sum","generateMultiProfileDummyStats","githubProfile","gitlabProfile","saveDummyDataToFile","filepath","data","json","blob","a","err","dataUrl","cacheKey","useStaleCache","__spreadProps","__spreadValues","_a","cached","_b","generateMockData","formatLastUpdated","dateString","date","diffHours","diffDays","getContributionLevel","count","calculateYearsExperience","experienceData","skillExperience","exp","end","start","years","skill","useGitStats","config","cacheTTL","loading","ref","error","dataSource","isDummy","loadData","result","lastUpdatedText","computed","dataSourceText","props","__props","emit","__emit","currentColorScheme","settingsOpen","colorSchemes","contributionData","monthLabels","watch","newData","_c","processContributions","generateMonthLabels","totalContributions","weekTotal","generateEmptyWeeks","generateEmptyWeek","i","days","monthPositions","lastMonth","lastYear","weekIndex","firstDay","dateParts","year","month","getContributionLevelNumber","getTooltipText","dayNum","formattedDate","contributionText","onDayClick","toggleSettings","changeColorScheme","scheme","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_hoisted_4","_toDisplayString","_normalizeClass","_unref","_hoisted_5","_renderSlot","_ctx","_hoisted_6","_Fragment","_renderList","$event","_hoisted_7","_hoisted_8","_cache","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_normalizeStyle","_hoisted_13","_hoisted_14","_hoisted_16","_hoisted_17","totalProjects","totalCommits","projects","commits","index","profile","yearsExperience","customStatValue","params","_hoisted_15","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_createTextVNode","_hoisted_25","VueGitStats","app","ContributionGraph","StatsBreakdown"],"mappings":"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"}
1
+ {"version":3,"file":"vue.umd.js","sources":["../../core/src/api/fetchGitStats.ts","../../core/src/utils/generateDummyData.js","../../core/src/index.ts","../src/composables/useGitStats.ts","../src/components/ContributionGraph.vue","../src/components/StatsBreakdown.vue","../src/index.ts"],"sourcesContent":["import type { GitStatsData } from '../types'\r\n\r\nexport async function fetchGitStats(url: string): Promise<GitStatsData> {\r\n\tconst response = await fetch(url)\r\n\tif (!response.ok) {\r\n\t\tthrow new Error(`Failed to fetch git stats: ${response.statusText}`)\r\n\t}\r\n\treturn response.json()\r\n}\r\n","/**\n * Generate realistic dummy data for testing and development\n */\n\n/**\n * Generate dummy contribution data (53 weeks)\n */\nexport function generateDummyContributions() {\n\tconst weeks = []\n\tconst now = new Date()\n\n\t// Get the Sunday that starts the week containing today\n\tconst endDate = new Date(now)\n\tendDate.setDate(endDate.getDate() - endDate.getDay())\n\n\t// Go back exactly 52 weeks\n\tconst startDate = new Date(endDate)\n\tstartDate.setDate(startDate.getDate() - 52 * 7)\n\n\tconst currentDate = new Date(startDate)\n\n\tfor (let week = 0; week < 53; week++) {\n\t\tconst weekData = {\n\t\t\tweekStart: new Date(currentDate).toISOString().split('T')[0],\n\t\t\tcontributionDays: [],\n\t\t}\n\n\t\tfor (let day = 0; day < 7; day++) {\n\t\t\tconst isInFuture = currentDate > now\n\t\t\tconst isWeekend = day === 0 || day === 6\n\n\t\t\t// More realistic pattern: fewer commits on weekends, none in future\n\t\t\tlet dayCount = 0\n\t\t\tif (!isInFuture) {\n\t\t\t\tif (isWeekend) {\n\t\t\t\t\tdayCount =\n\t\t\t\t\t\tMath.random() < 0.3 ? Math.floor(Math.random() * 5) : 0\n\t\t\t\t} else {\n\t\t\t\t\tdayCount = Math.floor(Math.random() * 15)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tweekData.contributionDays.push({\n\t\t\t\tdate: new Date(currentDate).toISOString().split('T')[0],\n\t\t\t\tcontributionCount: dayCount,\n\t\t\t\tweekday: day,\n\t\t\t})\n\t\t\tcurrentDate.setDate(currentDate.getDate() + 1)\n\t\t}\n\n\t\tweeks.push(weekData)\n\t}\n\n\treturn weeks\n}\n\n/**\n * Generate complete dummy stats data\n */\nexport function generateDummyStats(options = {}) {\n\tconst {\n\t\tusername = 'demo-user',\n\t\tplatform = 'github',\n\t\tprojectCount = 30,\n\t\tcommitCount = 2500,\n\t} = options\n\n\tconst contributions = generateDummyContributions()\n\tconst totalContributions = contributions.reduce((total, week) => {\n\t\treturn (\n\t\t\ttotal +\n\t\t\tweek.contributionDays.reduce(\n\t\t\t\t(sum, day) => sum + day.contributionCount,\n\t\t\t\t0\n\t\t\t)\n\t\t)\n\t}, 0)\n\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [\n\t\t\t{\n\t\t\t\tusername,\n\t\t\t\tplatform,\n\t\t\t\tstats: {\n\t\t\t\t\tprojectCount,\n\t\t\t\t\tcommitCount,\n\t\t\t\t\tcontributions: contributions.map((week) => ({\n\t\t\t\t\t\tfirstDay: week.weekStart,\n\t\t\t\t\t\tcontributionDays: week.contributionDays,\n\t\t\t\t\t})),\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\ttotals: {\n\t\t\tprojectCount,\n\t\t\tcommitCount,\n\t\t},\n\t\tmetadata: {\n\t\t\tfetchedAt: Date.now(),\n\t\t\tsource: 'dummy_data',\n\t\t\tisDummy: true,\n\t\t},\n\t}\n}\n\n/**\n * Generate multiple profiles dummy data\n */\nexport function generateMultiProfileDummyStats() {\n\tconst githubProfile = generateDummyStats({\n\t\tusername: 'demo-github',\n\t\tplatform: 'github',\n\t\tprojectCount: 45,\n\t\tcommitCount: 2847,\n\t})\n\n\tconst gitlabProfile = generateDummyStats({\n\t\tusername: 'demo-gitlab',\n\t\tplatform: 'gitlab',\n\t\tprojectCount: 7,\n\t\tcommitCount: 523,\n\t})\n\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [githubProfile.profiles[0], gitlabProfile.profiles[0]],\n\t\ttotals: {\n\t\t\tprojectCount: 45 + 7,\n\t\t\tcommitCount: 2847 + 523,\n\t\t},\n\t\tmetadata: {\n\t\t\tfetchedAt: Date.now(),\n\t\t\tsource: 'dummy_data',\n\t\t\tisDummy: true,\n\t\t},\n\t}\n}\n\n/**\n * Save dummy data to a file (for testing)\n */\nexport function saveDummyDataToFile(filepath = 'dummy-git-stats.json') {\n\tconst data = generateDummyStats()\n\tconst json = JSON.stringify(data, null, '\\t')\n\n\tif (typeof window !== 'undefined') {\n\t\t// Browser environment - trigger download\n\t\tconst blob = new Blob([json], { type: 'application/json' })\n\t\tconst url = URL.createObjectURL(blob)\n\t\tconst a = document.createElement('a')\n\t\ta.href = url\n\t\ta.download = filepath\n\t\ta.click()\n\t\tURL.revokeObjectURL(url)\n\t} else {\n\t\t// Node environment\n\t\ttry {\n\t\t\tconst fs = require('fs')\n\t\t\tfs.writeFileSync(filepath, json)\n\t\t\tconsole.log(`✓ Dummy data saved to ${filepath}`)\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to save dummy data:', err)\n\t\t}\n\t}\n}\n","// packages/core/src/index.ts\n// Framework-agnostic core logic\n\n// Re-export everything from types\nexport type {\n\tColorScheme,\n\tContributionDay,\n\tContributionWeek,\n\tProfile,\n\tGitStatsData,\n\tExperienceEntry,\n\tDataSource,\n\tPlatform,\n\tProfileStats,\n\tStatsTotals,\n\tStatsMetadata,\n\tCustomStatCalculator,\n\tCustomStatCalculatorParams,\n} from './types/index.js'\n\n// Export API functions\nexport { fetchGitStats as fetchGitStatsAPI } from './api/fetchGitStats.js'\n\n// Export utility functions with explicit imports\nexport {\n\tgenerateDummyStats,\n\tgenerateDummyContributions,\n\tgenerateMultiProfileDummyStats,\n\tsaveDummyDataToFile,\n} from './utils/generateDummyData.js'\n\n// Core data fetching (framework-agnostic)\nimport type { GitStatsData } from './types/index.js'\n\nexport interface FetchOptions {\n\tdataUrl: string\n\tcacheTTL?: number\n\tcacheKey?: string\n\tuseStaleCache?: boolean\n}\n\nexport interface DataResult<T> {\n\tdata: T | null\n\terror: Error | null\n\tsource: 'static' | 'cache' | 'mock' | 'dummy' | null\n\tisDummy: boolean\n}\n\n/**\n * Framework-agnostic data fetcher\n */\nexport async function fetchGitStats(\n\toptions: FetchOptions\n): Promise<DataResult<GitStatsData>> {\n\tconst { dataUrl, cacheKey = 'git_stats_cache', useStaleCache = true } = options\n\n\ttry {\n\t\t// Try static file first\n\t\tconst response = await fetch(dataUrl)\n\t\tif (response.ok) {\n\t\t\tconst data = await response.json()\n\t\t\t// Cache the data\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tlocalStorage.setItem(\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\tcachedAt: Date.now(),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata,\n\t\t\t\terror: null,\n\t\t\t\tsource: 'static',\n\t\t\t\tisDummy: data.metadata?.isDummy === true,\n\t\t\t}\n\t\t}\n\t} catch (err) {\n\t\tconsole.warn('Failed to fetch from static file:', err)\n\t}\n\n\t// Try cache\n\tif (useStaleCache && typeof window !== 'undefined') {\n\t\ttry {\n\t\t\tconst cached = localStorage.getItem(cacheKey)\n\t\t\tif (cached) {\n\t\t\t\tconst data = JSON.parse(cached)\n\t\t\t\treturn {\n\t\t\t\t\tdata,\n\t\t\t\t\terror: null,\n\t\t\t\t\tsource: 'cache',\n\t\t\t\t\tisDummy: data.metadata?.isDummy === true,\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.warn('Failed to load from cache:', err)\n\t\t}\n\t}\n\n\t// Fallback to mock\n\tconst mockData = generateMockData()\n\treturn {\n\t\tdata: mockData,\n\t\terror: null,\n\t\tsource: 'mock',\n\t\tisDummy: false,\n\t}\n}\n\n/**\n * Format last updated time\n */\nexport function formatLastUpdated(dateString: string): string {\n\tconst date = new Date(dateString)\n\tconst now = new Date()\n\tconst diffHours = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60))\n\n\tif (diffHours < 1) return 'just now'\n\tif (diffHours < 24) return `${diffHours} hours ago`\n\n\tconst diffDays = Math.floor(diffHours / 24)\n\tif (diffDays === 1) return 'yesterday'\n\tif (diffDays < 7) return `${diffDays} days ago`\n\n\treturn date.toLocaleDateString('en-US', {\n\t\tmonth: 'short',\n\t\tday: 'numeric',\n\t\tyear: date.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,\n\t})\n}\n\n/**\n * Get contribution level (0-4)\n */\nexport function getContributionLevel(count: number): number {\n\tif (count === 0) return 0\n\tif (count <= 3) return 1\n\tif (count <= 6) return 2\n\tif (count <= 9) return 3\n\treturn 4\n}\n\n/**\n * Calculate years of experience\n */\nexport function calculateYearsExperience(\n\texperienceData: { startDate: string; endDate: string | null; skills?: string[] }[]\n): number {\n\tif (experienceData.length === 0) return 0\n\n\tconst skillExperience: Record<string, number> = {}\n\n\texperienceData.forEach((exp) => {\n\t\tconst end = exp.endDate ? new Date(exp.endDate) : new Date()\n\t\tconst start = new Date(exp.startDate)\n\t\tconst years = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24 * 365.25)\n\n\t\texp.skills?.forEach((skill) => {\n\t\t\tif (!skillExperience[skill]) {\n\t\t\t\tskillExperience[skill] = 0\n\t\t\t}\n\t\t\tskillExperience[skill] += years\n\t\t})\n\t})\n\n\treturn Math.max(...Object.values(skillExperience), 0)\n}\n\n// Mock data generator\nfunction generateMockData(): GitStatsData {\n\treturn {\n\t\tlastUpdated: new Date().toISOString(),\n\t\tprofiles: [\n\t\t\t{\n\t\t\t\tusername: 'mockuser',\n\t\t\t\tplatform: 'github',\n\t\t\t\tstats: {\n\t\t\t\t\tprojectCount: 30,\n\t\t\t\t\tcommitCount: 2500,\n\t\t\t\t\tcontributions: [],\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\ttotals: {\n\t\t\tprojectCount: 30,\n\t\t\tcommitCount: 2500,\n\t\t},\n\t\tmetadata: {\n\t\t\tsource: 'mock',\n\t\t\tfetchedAt: Date.now(),\n\t\t},\n\t}\n}","import { ref, computed } from 'vue'\r\nimport {\r\n\tfetchGitStats,\r\n\tformatLastUpdated,\r\n\ttype GitStatsData,\r\n\ttype DataSource,\r\n} from '@git-stats-components/core'\r\n\r\nexport interface UseGitStatsConfig {\r\n\tdataUrl?: string\r\n\tcacheTTL?: number\r\n\tuseStaleCache?: boolean\r\n\tcacheKey?: string\r\n}\r\n\r\nexport function useGitStats(config: UseGitStatsConfig = {}) {\r\n\tconst {\r\n\t\tdataUrl = '/data/git-stats.json',\r\n\t\tcacheTTL = 24 * 60 * 60 * 1000,\r\n\t\tuseStaleCache = true,\r\n\t\tcacheKey = 'git_stats_cache',\r\n\t} = config\r\n\r\n\tconst loading = ref(false)\r\n\tconst error = ref<Error | null>(null)\r\n\tconst data = ref<GitStatsData | null>(null)\r\n\tconst dataSource = ref<DataSource | null>(null)\r\n\tconst isDummy = ref(false)\r\n\r\n\t/**\r\n\t * Load data with fallback strategy\r\n\t */\r\n\tasync function loadData(): Promise<GitStatsData | null> {\r\n\t\tloading.value = true\r\n\t\terror.value = null\r\n\r\n\t\ttry {\r\n\t\t\tconst result = await fetchGitStats({\r\n\t\t\t\tdataUrl,\r\n\t\t\t\tcacheTTL,\r\n\t\t\t\tcacheKey,\r\n\t\t\t\tuseStaleCache,\r\n\t\t\t})\r\n\r\n\t\t\tdata.value = result.data\r\n\t\t\terror.value = result.error\r\n\t\t\tdataSource.value = result.source\r\n\t\t\tisDummy.value = result.isDummy\r\n\r\n\t\t\treturn result.data\r\n\t\t} catch (err) {\r\n\t\t\terror.value =\r\n\t\t\t\terr instanceof Error ? err : new Error('Failed to load data')\r\n\t\t\treturn null\r\n\t\t} finally {\r\n\t\t\tloading.value = false\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Format \"last updated\" text\r\n\t */\r\n\tconst lastUpdatedText = computed(() => {\r\n\t\tif (!data.value?.lastUpdated) return ''\r\n\t\treturn formatLastUpdated(data.value.lastUpdated)\r\n\t})\r\n\r\n\t/**\r\n\t * Computed data source display text\r\n\t */\r\n\tconst dataSourceText = computed(() => {\r\n\t\tif (isDummy.value) {\r\n\t\t\treturn '⚠️ Using dummy data for testing'\r\n\t\t}\r\n\r\n\t\tswitch (dataSource.value) {\r\n\t\t\tcase 'static':\r\n\t\t\t\treturn 'Real-time data'\r\n\t\t\tcase 'cache':\r\n\t\t\t\treturn 'Cached data'\r\n\t\t\tcase 'mock':\r\n\t\t\t\treturn 'Sample data'\r\n\t\t\tdefault:\r\n\t\t\t\treturn ''\r\n\t\t}\r\n\t})\r\n\r\n\t// Auto-load on creation\r\n\tloadData()\r\n\r\n\treturn {\r\n\t\tdata,\r\n\t\tloading,\r\n\t\terror,\r\n\t\tdataSource,\r\n\t\tdataSourceText,\r\n\t\tlastUpdatedText,\r\n\t\tisDummy,\r\n\t\tloadData,\r\n\t}\r\n}\r\n","<template>\r\n\t<div class=\"git-contribution-graph\">\r\n\t\t<!-- Header -->\r\n\t\t<div class=\"graph-header\">\r\n\t\t\t<div class=\"header-info\">\r\n\t\t\t\t<h5 class=\"contribution-count\">\r\n\t\t\t\t\t{{ totalContributions.toLocaleString() }} contributions in\r\n\t\t\t\t\tthe last year\r\n\t\t\t\t</h5>\r\n\t\t\t\t<small\r\n\t\t\t\t\tclass=\"data-source-text\"\r\n\t\t\t\t\t:class=\"{ 'is-dummy': isDummy }\"\r\n\t\t\t\t>\r\n\t\t\t\t\t{{ dataSourceText }}\r\n\t\t\t\t</small>\r\n\t\t\t</div>\r\n\t\t\t<div class=\"header-actions\" v-if=\"showSettings\">\r\n\t\t\t\t<button\r\n\t\t\t\t\tclass=\"settings-btn\"\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t@click=\"toggleSettings\"\r\n\t\t\t\t>\r\n\t\t\t\t\t<slot name=\"settings-icon\">⚙️</slot>\r\n\t\t\t\t\tSettings\r\n\t\t\t\t</button>\r\n\t\t\t\t<div v-if=\"settingsOpen\" class=\"settings-dropdown\">\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\tv-for=\"scheme in colorSchemes\"\r\n\t\t\t\t\t\t:key=\"scheme\"\r\n\t\t\t\t\t\t@click=\"changeColorScheme(scheme)\"\r\n\t\t\t\t\t\tclass=\"settings-item\"\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t{{ scheme }} theme\r\n\t\t\t\t\t</button>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\r\n\t\t<!-- Loading state -->\r\n\t\t<div v-if=\"loading\" class=\"loading-state\">\r\n\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t<span>Loading contributions...</span>\r\n\t\t</div>\r\n\r\n\t\t<!-- Contribution grid -->\r\n\t\t<div v-else class=\"graph-container\">\r\n\t\t\t<div class=\"graph-content-wrapper\">\r\n\t\t\t\t<!-- Month labels -->\r\n\t\t\t\t<div class=\"months-row\">\r\n\t\t\t\t\t<div class=\"month-spacer\"></div>\r\n\t\t\t\t\t<div class=\"months-container\">\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tv-for=\"month in monthLabels\"\r\n\t\t\t\t\t\t\t:key=\"`${month.year}-${month.month}`\"\r\n\t\t\t\t\t\t\tclass=\"month-label\"\r\n\t\t\t\t\t\t\t:style=\"{\r\n\t\t\t\t\t\t\t\tgridColumn: `${month.week + 1} / span 1`,\r\n\t\t\t\t\t\t\t}\"\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{{ month.label }}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<!-- Grid with day labels -->\r\n\t\t\t\t<div class=\"grid-container\">\r\n\t\t\t\t\t<!-- Day labels -->\r\n\t\t\t\t\t<div class=\"day-labels\">\r\n\t\t\t\t\t\t<div class=\"day-label\">Mon</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\">Wed</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\">Fri</div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t\t<div class=\"day-label\"></div>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<!-- Contribution squares -->\r\n\t\t\t\t\t<div class=\"contribution-grid\">\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tv-for=\"week in contributionData\"\r\n\t\t\t\t\t\t\t:key=\"week.weekStart\"\r\n\t\t\t\t\t\t\tclass=\"contribution-week\"\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\t\tv-for=\"day in week.days\"\r\n\t\t\t\t\t\t\t\t:key=\"day.date\"\r\n\t\t\t\t\t\t\t\tclass=\"contribution-day\"\r\n\t\t\t\t\t\t\t\t:class=\"getContributionLevel(day.count)\"\r\n\t\t\t\t\t\t\t\t:title=\"getTooltipText(day)\"\r\n\t\t\t\t\t\t\t\t@click=\"onDayClick(day)\"\r\n\t\t\t\t\t\t\t></div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Legend -->\r\n\t\t\t<div class=\"graph-footer\">\r\n\t\t\t\t<small class=\"last-updated\" v-if=\"lastUpdatedText\">\r\n\t\t\t\t\tLast updated: {{ lastUpdatedText }}\r\n\t\t\t\t</small>\r\n\t\t\t\t<div class=\"legend\">\r\n\t\t\t\t\t<small class=\"legend-label\">Less</small>\r\n\t\t\t\t\t<div class=\"legend-squares\">\r\n\t\t\t\t\t\t<div :class=\"currentColorScheme + ' contribution-day level-0'\"></div>\r\n\t\t\t\t\t\t<div :class=\"currentColorScheme + ' contribution-day level-1'\"></div>\r\n\t\t\t\t\t\t<div :class=\"currentColorScheme + ' contribution-day level-2'\"></div>\r\n\t\t\t\t\t\t<div :class=\"currentColorScheme + ' contribution-day level-3'\"></div>\r\n\t\t\t\t\t\t<div :class=\"currentColorScheme + ' contribution-day level-4'\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<small class=\"legend-label\">More</small>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch } from 'vue'\r\nimport { useGitStats } from '../composables/useGitStats'\r\nimport {\r\n\ttype ColorScheme,\r\n\ttype ContributionWeek,\r\n} from '@git-stats-components/core'\r\n\r\ninterface ProcessedWeek {\r\n\tweekStart: string\r\n\tdays: ProcessedDay[]\r\n}\r\n\r\ninterface ProcessedDay {\r\n\tdate: string\r\n\tcount: number\r\n\tweekday: number\r\n}\r\n\r\ninterface MonthLabel {\r\n\tweek: number\r\n\tmonth: number\r\n\tyear: number\r\n\tlabel: string\r\n}\r\n\r\ninterface Props {\r\n\tdataUrl?: string\r\n\tprofileIndex?: number\r\n\tcolorScheme?: ColorScheme\r\n\tshowSettings?: boolean\r\n\tcacheTTL?: number\r\n}\r\n\r\ninterface Emits {\r\n\t(e: 'day-click', data: { date: string; count: number }): void\r\n\t(e: 'color-scheme-change', scheme: ColorScheme): void\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tdataUrl: '/data/git-stats.json',\r\n\tprofileIndex: 0,\r\n\tcolorScheme: 'green',\r\n\tshowSettings: true,\r\n\tcacheTTL: 24 * 60 * 60 * 1000,\r\n})\r\n\r\nconst emit = defineEmits<Emits>()\r\n\r\n// Use the shared composable\r\nconst { data, loading, dataSourceText, lastUpdatedText, isDummy } = useGitStats(\r\n\t{\r\n\t\tdataUrl: props.dataUrl,\r\n\t\tcacheTTL: props.cacheTTL,\r\n\t}\r\n)\r\n\r\nconst currentColorScheme = ref<ColorScheme>(props.colorScheme)\r\nconst settingsOpen = ref(false)\r\nconst colorSchemes: ColorScheme[] = ['green', 'blue', 'purple', 'orange']\r\nconst contributionData = ref<ProcessedWeek[]>([])\r\nconst monthLabels = ref<MonthLabel[]>([])\r\n\r\n// Process contribution data when loaded\r\nwatch(\r\n\tdata,\r\n\t(newData) => {\r\n\t\tif (newData?.profiles?.[props.profileIndex]?.stats?.contributions) {\r\n\t\t\tconst contributions =\r\n\t\t\t\tnewData.profiles[props.profileIndex].stats.contributions\r\n\t\t\tif (contributions) {\r\n\t\t\t\tcontributionData.value = processContributions(contributions)\r\n\t\t\t\tgenerateMonthLabels()\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tcontributionData.value = []\r\n\t\t}\r\n\t},\r\n\t{ immediate: true }\r\n)\r\n\r\nconst totalContributions = computed(() => {\r\n\tif (!contributionData.value || contributionData.value.length === 0) {\r\n\t\treturn 0\r\n\t}\r\n\r\n\treturn contributionData.value.reduce((total, week) => {\r\n\t\tif (!week.days || !Array.isArray(week.days)) {\r\n\t\t\treturn total\r\n\t\t}\r\n\t\treturn (\r\n\t\t\ttotal +\r\n\t\t\tweek.days.reduce((weekTotal, day) => {\r\n\t\t\t\treturn weekTotal + (day.count || 0)\r\n\t\t\t}, 0)\r\n\t\t)\r\n\t}, 0)\r\n})\r\n\r\nfunction processContributions(\r\n\tcontributions: ContributionWeek[]\r\n): ProcessedWeek[] {\r\n\tif (!contributions || !Array.isArray(contributions)) {\r\n\t\treturn generateEmptyWeeks()\r\n\t}\r\n\r\n\tconst weeks = contributions.map((week) => ({\r\n\t\tweekStart: week.firstDay || '',\r\n\t\tdays: week.contributionDays.map((day) => ({\r\n\t\t\tdate: day.date || '',\r\n\t\t\tcount: day.contributionCount ?? 0,\r\n\t\t\tweekday: day.weekday || 0,\r\n\t\t})),\r\n\t}))\r\n\r\n\twhile (weeks.length < 53) {\r\n\t\tweeks.push(generateEmptyWeek())\r\n\t}\r\n\r\n\treturn weeks\r\n}\r\n\r\nfunction generateEmptyWeeks(): ProcessedWeek[] {\r\n\tconst weeks: ProcessedWeek[] = []\r\n\tfor (let i = 0; i < 53; i++) {\r\n\t\tweeks.push(generateEmptyWeek())\r\n\t}\r\n\treturn weeks\r\n}\r\n\r\nfunction generateEmptyWeek(): ProcessedWeek {\r\n\tconst days: ProcessedDay[] = []\r\n\tfor (let i = 0; i < 7; i++) {\r\n\t\tdays.push({ date: '', count: 0, weekday: i })\r\n\t}\r\n\treturn { weekStart: '', days }\r\n}\r\n\r\nfunction generateMonthLabels(): void {\r\n\tif (!contributionData.value || contributionData.value.length === 0) {\r\n\t\tmonthLabels.value = []\r\n\t\treturn\r\n\t}\r\n\r\n\tconst monthPositions: MonthLabel[] = []\r\n\tlet lastMonth = -1\r\n\tlet lastYear = -1\r\n\r\n\tcontributionData.value.forEach((week, weekIndex) => {\r\n\t\tif (!week.days || week.days.length === 0) return\r\n\r\n\t\tconst firstDay = week.days[0].date\r\n\t\tif (!firstDay) return\r\n\r\n\t\tconst dateParts = firstDay.split('-')\r\n\t\tif (dateParts.length !== 3) return\r\n\r\n\t\tconst [year, month] = dateParts.map(Number)\r\n\t\tif (isNaN(year) || isNaN(month)) return\r\n\r\n\t\tif (month !== lastMonth || year !== lastYear) {\r\n\t\t\tconst date = new Date(year, month - 1, 1)\r\n\t\t\tmonthPositions.push({\r\n\t\t\t\tweek: weekIndex,\r\n\t\t\t\tmonth: month - 1,\r\n\t\t\t\tyear: year,\r\n\t\t\t\tlabel: date.toLocaleDateString('en-US', { month: 'short' }),\r\n\t\t\t})\r\n\t\t\tlastMonth = month\r\n\t\t\tlastYear = year\r\n\t\t}\r\n\t})\r\n\r\n\tmonthLabels.value = monthPositions\r\n}\r\n\r\nfunction getContributionLevel(count: number): string {\r\n\tconst level = getContributionLevelNumber(count)\r\n\treturn `level-${level} ${currentColorScheme.value}`\r\n}\r\n\r\nfunction getContributionLevelNumber(count: number): number {\r\n\tif (count === 0) return 0\r\n\tif (count <= 3) return 1\r\n\tif (count <= 6) return 2\r\n\tif (count <= 9) return 3\r\n\treturn 4\r\n}\r\n\r\nfunction getTooltipText(day: ProcessedDay): string {\r\n\tif (!day.date) return ''\r\n\r\n\tconst [year, month, dayNum] = day.date.split('-').map(Number)\r\n\tconst date = new Date(year, month - 1, dayNum)\r\n\r\n\tconst formattedDate = date.toLocaleDateString('en-US', {\r\n\t\tweekday: 'short',\r\n\t\tyear: 'numeric',\r\n\t\tmonth: 'short',\r\n\t\tday: 'numeric',\r\n\t})\r\n\r\n\tconst contributionText = day.count === 1 ? 'contribution' : 'contributions'\r\n\treturn `${day.count} ${contributionText} on ${formattedDate}`\r\n}\r\n\r\nfunction onDayClick(day: ProcessedDay): void {\r\n\temit('day-click', { date: day.date, count: day.count })\r\n}\r\n\r\nfunction toggleSettings(): void {\r\n\tsettingsOpen.value = !settingsOpen.value\r\n}\r\n\r\nfunction changeColorScheme(scheme: ColorScheme): void {\r\n\tcurrentColorScheme.value = scheme\r\n\tsettingsOpen.value = false\r\n\temit('color-scheme-change', scheme)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.graph-content-wrapper {\r\n\tjustify-items: anchor-center;\r\n}\r\n.git-contribution-graph {\r\n\tfont-family:\r\n\t\t-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica,\r\n\t\tArial, sans-serif;\r\n\tfont-size: 12px;\r\n\tbackground: transparent;\r\n\tcolor: #e6edf3;\r\n\tpadding: 16px;\r\n\tmax-width: 1200px;\r\n\tmargin: 0 auto;\r\n\twidth: 100%;\r\n}\r\n\r\n.graph-header {\r\n\tdisplay: flex;\r\n\tjustify-content: space-between;\r\n\talign-items: center;\r\n\tmargin-bottom: 16px;\r\n}\r\n\r\n.contribution-count {\r\n\tmargin: 0 0 4px 0;\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n}\r\n\r\n.data-source-text {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.data-source-text.is-dummy {\r\n\tcolor: #f85149;\r\n\tfont-weight: 600;\r\n\tbackground: rgba(248, 81, 73, 0.1);\r\n\tpadding: 2px 8px;\r\n\tborder-radius: 4px;\r\n}\r\n\r\n.settings-btn {\r\n\tbackground: transparent;\r\n\tborder: 1px solid #30363d;\r\n\tcolor: #7d8590;\r\n\tpadding: 6px 12px;\r\n\tborder-radius: 6px;\r\n\tcursor: pointer;\r\n\tfont-size: 12px;\r\n}\r\n\r\n.settings-btn:hover {\r\n\tbackground: #21262d;\r\n\tcolor: #e6edf3;\r\n}\r\n\r\n.header-actions {\r\n\tposition: relative;\r\n}\r\n\r\n.settings-dropdown {\r\n\tposition: absolute;\r\n\tright: 0;\r\n\ttop: 100%;\r\n\tmargin-top: 4px;\r\n\tbackground: #21262d;\r\n\tborder: 1px solid #30363d;\r\n\tborder-radius: 6px;\r\n\tpadding: 4px;\r\n\tz-index: 10;\r\n\tmin-width: 150px;\r\n}\r\n\r\n.settings-item {\r\n\tdisplay: block;\r\n\twidth: 100%;\r\n\tbackground: transparent;\r\n\tborder: none;\r\n\tcolor: #e6edf3;\r\n\tpadding: 8px 12px;\r\n\ttext-align: left;\r\n\tcursor: pointer;\r\n\tborder-radius: 4px;\r\n}\r\n\r\n.settings-item:hover {\r\n\tbackground: #30363d;\r\n}\r\n\r\n.loading-state {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 12px;\r\n\tpadding: 40px;\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.spinner {\r\n\twidth: 20px;\r\n\theight: 20px;\r\n\tborder: 2px solid #30363d;\r\n\tborder-top-color: #58a6ff;\r\n\tborder-radius: 50%;\r\n\tanimation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n\tto {\r\n\t\ttransform: rotate(360deg);\r\n\t}\r\n}\r\n\r\n.months-row {\r\n\tdisplay: flex;\r\n\tmargin-bottom: 4px;\r\n}\r\n\r\n.month-spacer {\r\n\twidth: 27px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.months-container {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: repeat(53, 11px);\r\n\tgap: 2px;\r\n\tflex: 1;\r\n\tmargin-left: 3px;\r\n\tmin-width: 0;\r\n}\r\n\r\n.month-label {\r\n\tfont-size: 11px;\r\n\tcolor: #7d8590;\r\n\ttext-align: left;\r\n}\r\n\r\n.grid-container {\r\n\tdisplay: flex;\r\n\tgap: 3px;\r\n\tmin-width: fit-content;\r\n}\r\n\r\n.day-labels {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\twidth: 24px;\r\n\tgap: 2px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.day-label {\r\n\theight: 11px;\r\n\tfont-size: 9px;\r\n\tcolor: #7d8590;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n}\r\n\r\n.contribution-grid {\r\n\tdisplay: flex;\r\n\tgap: 2px;\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n}\r\n\r\n.contribution-week {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\tgap: 2px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.contribution-day {\r\n\twidth: 11px;\r\n\theight: 11px;\r\n\tborder-radius: 2px;\r\n\tcursor: pointer;\r\n\toutline: 1px solid rgba(27, 31, 36, 0.06);\r\n\toutline-offset: -1px;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n/* Color schemes */\r\n.contribution-day.level-0.green {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.green {\r\n\tbackground-color: #0e4429;\r\n}\r\n.contribution-day.level-2.green {\r\n\tbackground-color: #006d32;\r\n}\r\n.contribution-day.level-3.green {\r\n\tbackground-color: #26a641;\r\n}\r\n.contribution-day.level-4.green {\r\n\tbackground-color: #39d353;\r\n}\r\n\r\n.contribution-day.level-0.blue {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.blue {\r\n\tbackground-color: #0a3069;\r\n}\r\n.contribution-day.level-2.blue {\r\n\tbackground-color: #1f6feb;\r\n}\r\n.contribution-day.level-3.blue {\r\n\tbackground-color: #58a6ff;\r\n}\r\n.contribution-day.level-4.blue {\r\n\tbackground-color: #79c0ff;\r\n}\r\n\r\n.contribution-day.level-0.purple {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.purple {\r\n\tbackground-color: #3b1e6d;\r\n}\r\n.contribution-day.level-2.purple {\r\n\tbackground-color: #8250df;\r\n}\r\n.contribution-day.level-3.purple {\r\n\tbackground-color: #a475f9;\r\n}\r\n.contribution-day.level-4.purple {\r\n\tbackground-color: #d2a8ff;\r\n}\r\n\r\n.contribution-day.level-0.orange {\r\n\tbackground-color: #161b22;\r\n}\r\n.contribution-day.level-1.orange {\r\n\tbackground-color: #7d2d00;\r\n}\r\n.contribution-day.level-2.orange {\r\n\tbackground-color: #da7b00;\r\n}\r\n.contribution-day.level-3.orange {\r\n\tbackground-color: #ffa348;\r\n}\r\n.contribution-day.level-4.orange {\r\n\tbackground-color: #ffb366;\r\n}\r\n\r\n.contribution-day:hover {\r\n\toutline: 1px solid #c9d1d9;\r\n\toutline-offset: -1px;\r\n}\r\n\r\n.graph-footer {\r\n\tdisplay: flex;\r\n\tjustify-content: space-between;\r\n\talign-items: center;\r\n\tmargin-top: 8px;\r\n}\r\n\r\n.last-updated {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.legend {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: 4px;\r\n}\r\n\r\n.legend-label {\r\n\tcolor: #7d8590;\r\n}\r\n\r\n.legend-squares {\r\n\tdisplay: flex;\r\n\tgap: 2px;\r\n}\r\n\r\n.legend-squares .contribution-day {\r\n\tcursor: default;\r\n}\r\n\r\n.legend-squares .contribution-day:hover {\r\n\toutline: none;\r\n}\r\n\r\n/* Mobile responsive */\r\n@media (max-width: 768px) {\r\n\t.git-contribution-graph {\r\n\t\tpadding: 12px;\r\n\t\tfont-size: 11px;\r\n\t\toverflow-x: auto;\r\n\t}\r\n\t.months-container {\r\n\t\tgrid-template-columns: repeat(53, 10px);\r\n\t\tgap: 1px;\r\n\t}\r\n\t.grid-container {\r\n\t\tgap: 2px;\r\n\t}\r\n\t.day-labels {\r\n\t\twidth: 20px;\r\n\t}\r\n\t.day-label {\r\n\t\theight: 10px;\r\n\t\tfont-size: 8px;\r\n\t}\r\n\t.contribution-grid {\r\n\t\tgap: 1px;\r\n\t}\r\n\t.contribution-week {\r\n\t\tgap: 1px;\r\n\t}\r\n\t.contribution-day {\r\n\t\twidth: 10px;\r\n\t\theight: 10px;\r\n\t}\r\n\t.settings-btn {\r\n\t\tfont-size: 10px;\r\n\t\tpadding: 4px 8px;\r\n\t}\r\n\t.contribution-count {\r\n\t\tfont-size: 14px;\r\n\t}\r\n}\r\n\r\n@media (max-width: 480px) {\r\n\t.graph-header {\r\n\t\tflex-direction: column;\r\n\t\talign-items: flex-start;\r\n\t\tgap: 8px;\r\n\t}\r\n}\r\n</style>\r\n","<template>\r\n\t<div class=\"git-stats-breakdown\">\r\n\t\t<div class=\"stats-grid\">\r\n\t\t\t<!-- Years Experience -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-experience\">⏱️</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div class=\"stat-value\">{{ yearsExperience }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Years Experience</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Projects -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-projects\">📦</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ totalProjects }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Projects</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Commits -->\r\n\t\t\t<div class=\"stat-card\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-commits\">💻</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ totalCommits }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">Commits</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<!-- Custom Stat -->\r\n\t\t\t<div class=\"stat-card\" v-if=\"showCustomStat\">\r\n\t\t\t\t<div class=\"stat-icon\">\r\n\t\t\t\t\t<slot name=\"icon-custom\">☕</slot>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div class=\"stat-content\">\r\n\t\t\t\t\t<div v-if=\"loading\" class=\"stat-loading\">\r\n\t\t\t\t\t\t<div class=\"spinner\"></div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div v-else class=\"stat-value\">{{ customStatValue }}</div>\r\n\t\t\t\t\t<div class=\"stat-label\">\r\n\t\t\t\t\t\t<slot name=\"custom-stat-label\">Coffee Consumed</slot>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\r\n\t\t<!-- Footer -->\r\n\t\t<div class=\"stats-footer\">\r\n\t\t\t<small v-if=\"dataSourceText\" class=\"data-source\">\r\n\t\t\t\t{{ dataSourceText }}\r\n\t\t\t\t<span v-if=\"lastUpdatedText\"> · {{ lastUpdatedText }}</span>\r\n\t\t\t</small>\r\n\t\t</div>\r\n\t</div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch } from 'vue'\r\nimport { useGitStats } from '../composables/useGitStats'\r\nimport {\r\n\tcalculateYearsExperience,\r\n\ttype ExperienceEntry,\r\n\ttype CustomStatCalculator,\r\n\ttype CustomStatCalculatorParams,\r\n} from '@git-stats-components/core'\r\n\r\ninterface Props {\r\n\tdataUrl?: string\r\n\tprofileIndexes?: number[]\r\n\texperienceData?: ExperienceEntry[]\r\n\tshowCustomStat?: boolean\r\n\tcustomStatCalculator?: CustomStatCalculator | null\r\n\tcacheTTL?: number\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tdataUrl: '/data/git-stats.json',\r\n\tprofileIndexes: () => [],\r\n\texperienceData: () => [],\r\n\tshowCustomStat: true,\r\n\tcustomStatCalculator: null,\r\n\tcacheTTL: 24 * 60 * 60 * 1000,\r\n})\r\n\r\n// Use the shared composable\r\nconst { data, loading, dataSourceText, lastUpdatedText } = useGitStats({\r\n\tdataUrl: props.dataUrl,\r\n\tcacheTTL: props.cacheTTL,\r\n})\r\n\r\nconst totalProjects = ref(0)\r\nconst totalCommits = ref(0)\r\n\r\n// Calculate totals when data loads\r\nwatch(\r\n\tdata,\r\n\t(newData) => {\r\n\t\tif (!newData) return\r\n\r\n\t\t// If profileIndexes specified, sum only those profiles\r\n\t\tif (props.profileIndexes.length > 0) {\r\n\t\t\tlet projects = 0\r\n\t\t\tlet commits = 0\r\n\r\n\t\t\tprops.profileIndexes.forEach((index) => {\r\n\t\t\t\tconst profile = newData.profiles?.[index]\r\n\t\t\t\tif (profile?.stats) {\r\n\t\t\t\t\tprojects += profile.stats.projectCount || 0\r\n\t\t\t\t\tcommits += profile.stats.commitCount || 0\r\n\t\t\t\t}\r\n\t\t\t})\r\n\r\n\t\t\ttotalProjects.value = projects\r\n\t\t\ttotalCommits.value = commits\r\n\t\t} else {\r\n\t\t\t// Use totals from data (aggregates all profiles)\r\n\t\t\ttotalProjects.value = newData.totals?.projectCount || 0\r\n\t\t\ttotalCommits.value = newData.totals?.commitCount || 0\r\n\t\t}\r\n\t},\r\n\t{ immediate: true }\r\n)\r\n\r\n// Calculate years of experience using core utility\r\nconst yearsExperience = computed(() => {\r\n\tconst years = calculateYearsExperience(props.experienceData)\r\n\treturn years.toFixed(1)\r\n})\r\n\r\n// Custom stat calculation\r\nconst customStatValue = computed(() => {\r\n\tif (props.customStatCalculator) {\r\n\t\tconst params: CustomStatCalculatorParams = {\r\n\t\t\tprojects: totalProjects.value,\r\n\t\t\tcommits: totalCommits.value,\r\n\t\t\tyears: parseFloat(yearsExperience.value),\r\n\t\t}\r\n\t\treturn props.customStatCalculator(params)\r\n\t}\r\n\r\n\t// Default: fun coffee calculation\r\n\tconst kA = 1.5\r\n\tconst kB = 1.2\r\n\tconst kC = 1.5\r\n\r\n\tconst cups =\r\n\t\ttotalProjects.value * kA +\r\n\t\ttotalCommits.value * kB +\r\n\t\tparseFloat(yearsExperience.value) * kC\r\n\r\n\treturn cups.toFixed(2)\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.git-stats-breakdown {\r\n\tfont-family:\r\n\t\t-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica,\r\n\t\tArial, sans-serif;\r\n\tpadding: 40px 20px;\r\n\tmax-width: 1200px;\r\n\tmargin: 0 auto;\r\n}\r\n\r\n.stats-grid {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: repeat(4, 1fr); /* Always 4 columns on desktop */\r\n\tgap: 24px;\r\n\tmargin-bottom: 24px;\r\n}\r\n\r\n.stat-card {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: 16px;\r\n\tpadding: 24px;\r\n\tbackground: rgba(255, 255, 255, 0.05);\r\n\tborder-radius: 12px;\r\n\tborder: 1px solid rgba(255, 255, 255, 0.1);\r\n\ttransition: all 0.3s ease;\r\n}\r\n\r\n.stat-card:hover {\r\n\tbackground: rgba(255, 255, 255, 0.08);\r\n\tborder-color: rgba(255, 255, 255, 0.2);\r\n\ttransform: translateY(-2px);\r\n}\r\n\r\n.stat-icon {\r\n\tfont-size: 48px;\r\n\tline-height: 1;\r\n\topacity: 0.9;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.stat-content {\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n}\r\n\r\n.stat-value {\r\n\tfont-size: 32px;\r\n\tfont-weight: bold;\r\n\tline-height: 1.2;\r\n\tcolor: #e6edf3;\r\n\tmargin-bottom: 4px;\r\n}\r\n\r\n.stat-label {\r\n\tfont-size: 14px;\r\n\tcolor: #7d8590;\r\n\ttext-transform: uppercase;\r\n\tletter-spacing: 0.5px;\r\n}\r\n\r\n.stat-loading {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\theight: 38px;\r\n}\r\n\r\n.spinner {\r\n\twidth: 24px;\r\n\theight: 24px;\r\n\tborder: 3px solid rgba(255, 255, 255, 0.1);\r\n\tborder-top-color: #58a6ff;\r\n\tborder-radius: 50%;\r\n\tanimation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n\tto {\r\n\t\ttransform: rotate(360deg);\r\n\t}\r\n}\r\n\r\n.stats-footer {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\talign-items: center;\r\n\tgap: 8px;\r\n\tpadding-top: 16px;\r\n\tborder-top: 1px solid rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.data-source {\r\n\tfont-size: 12px;\r\n\tcolor: #7d8590;\r\n\ttext-align: center;\r\n}\r\n\r\n/* Responsive */\r\n@media (max-width: 1400px) {\r\n\t.git-stats-breakdown {\r\n\t\tpadding: 20px 12px;\r\n\t}\r\n\t.stats-grid {\r\n\t\tgrid-template-columns: repeat(2, 1fr); /* 2 columns on tablets */\r\n\t\tgap: 16px;\r\n\t}\r\n\t.stat-card {\r\n\t\tpadding: 16px;\r\n\t}\r\n\t.stat-icon {\r\n\t\tfont-size: 36px;\r\n\t}\r\n\t.stat-value {\r\n\t\tfont-size: 24px;\r\n\t}\r\n\t.stat-label {\r\n\t\tfont-size: 12px;\r\n\t}\r\n}\r\n\r\n@media (max-width: 480px) {\r\n\t.stats-grid {\r\n\t\tgrid-template-columns: 1fr; /* 1 column on mobile */\r\n\t}\r\n\t.stat-card {\r\n\t\tflex-direction: column;\r\n\t\ttext-align: center;\r\n\t}\r\n\t.stat-content {\r\n\t\twidth: 100%;\r\n\t}\r\n}\r\n</style>\r\n","// Main entry point for git-stats-components\n\nimport type { App } from 'vue'\nimport ContributionGraph from './components/ContributionGraph.vue'\nimport StatsBreakdown from './components/StatsBreakdown.vue'\nimport { useGitStats } from './composables/useGitStats'\n\n// Re-export everything from core\nexport * from '@git-stats-components/core'\n\n// Export Vue-specific components and composables\nexport { ContributionGraph, StatsBreakdown, useGitStats }\n\n// Auto-import styles\nimport './styles/index.css'\n\n// Plugin for Vue.use()\nexport interface VueGitStatsPlugin {\n\tinstall: (app: App) => void\n}\n\nconst VueGitStats: VueGitStatsPlugin = {\n\tinstall(app: App) {\n\t\tapp.component('ContributionGraph', ContributionGraph)\n\t\tapp.component('StatsBreakdown', StatsBreakdown)\n\t},\n}\n\n// Export as default for Vue.use()\nexport default VueGitStats\n"],"names":["fetchGitStats","url","__async","response","generateDummyContributions","weeks","now","endDate","startDate","currentDate","week","weekData","day","isInFuture","isWeekend","dayCount","generateDummyStats","options","username","platform","projectCount","commitCount","contributions","total","sum","generateMultiProfileDummyStats","githubProfile","gitlabProfile","saveDummyDataToFile","filepath","data","json","blob","a","err","dataUrl","cacheKey","useStaleCache","__spreadProps","__spreadValues","_a","cached","_b","generateMockData","formatLastUpdated","dateString","date","diffHours","diffDays","getContributionLevel","count","calculateYearsExperience","experienceData","skillExperience","exp","end","start","years","skill","useGitStats","config","cacheTTL","loading","ref","error","dataSource","isDummy","loadData","result","lastUpdatedText","computed","dataSourceText","props","__props","emit","__emit","currentColorScheme","settingsOpen","colorSchemes","contributionData","monthLabels","watch","newData","_c","processContributions","generateMonthLabels","totalContributions","weekTotal","generateEmptyWeeks","generateEmptyWeek","i","days","monthPositions","lastMonth","lastYear","weekIndex","firstDay","dateParts","year","month","getContributionLevelNumber","getTooltipText","dayNum","formattedDate","contributionText","onDayClick","toggleSettings","changeColorScheme","scheme","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_hoisted_4","_toDisplayString","_normalizeClass","_unref","_hoisted_5","_renderSlot","_ctx","_hoisted_6","_Fragment","_renderList","$event","_hoisted_7","_hoisted_8","_cache","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_normalizeStyle","_hoisted_13","_hoisted_14","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","totalProjects","totalCommits","projects","commits","index","profile","yearsExperience","customStatValue","params","_hoisted_15","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_createTextVNode","_hoisted_25","VueGitStats","app","ContributionGraph","StatsBreakdown"],"mappings":"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"}
package/package.json CHANGED
@@ -1,72 +1,72 @@
1
1
  {
2
- "name": "@git-stats-components/vue",
3
- "version": "1.0.2",
4
- "description": "Beautiful GitHub/GitLab/Bitbucket contribution graphs for Vue 3",
5
- "author": "Derek Johnston",
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./dist/vue.umd.js",
9
- "module": "./dist/vue.es.js",
10
- "types": "./dist/index.d.ts",
11
- "exports": {
12
- ".": {
13
- "types": "./dist/index.d.ts",
14
- "import": "./dist/vue.es.js",
15
- "require": "./dist/vue.umd.js"
16
- },
17
- "./style.css": "./dist/style.css"
18
- },
19
- "files": [
20
- "dist",
21
- "README.md",
22
- "LICENSE"
23
- ],
24
- "keywords": [
25
- "vue",
26
- "vue3",
27
- "github",
28
- "gitlab",
29
- "bitbucket",
30
- "contributions",
31
- "stats",
32
- "component",
33
- "git-stats"
34
- ],
35
- "repository": {
36
- "type": "git",
37
- "url": "https://github.com/derekjj/git-stats-components.git",
38
- "directory": "packages/vue"
39
- },
40
- "bugs": {
41
- "url": "https://github.com/derekjj/git-stats-components/issues"
42
- },
43
- "homepage": "https://github.com/derekjj/git-stats-components/tree/main/packages/vue#readme",
44
- "peerDependencies": {
45
- "vue": "^3.3.0"
46
- },
47
- "dependencies": {
48
- "@git-stats-components/core": "^1.0.0"
49
- },
50
- "devDependencies": {
51
- "@vitejs/plugin-vue": "^5.0.0",
52
- "@types/node": "^20.10.6",
53
- "@vue/test-utils": "^2.4.3",
54
- "@testing-library/jest-dom": "^6.1.5",
55
- "jsdom": "^23.0.1",
56
- "typescript": "^5.3.3",
57
- "vite": "^5.0.0",
58
- "vite-plugin-dts": "^3.7.0",
59
- "vitest": "^1.0.4",
60
- "@vitest/ui": "^1.0.4",
61
- "vue": "^3.4.0",
62
- "vue-tsc": "^2.0.0"
63
- },
64
- "scripts": {
65
- "build": "vite build",
66
- "dev": "vite build --watch",
67
- "clean": "rm -rf dist",
68
- "test": "vitest run",
69
- "test:watch": "vitest",
70
- "test:ui": "vitest --ui"
71
- }
72
- }
2
+ "name": "@git-stats-components/vue",
3
+ "version": "1.0.4",
4
+ "description": "Beautiful GitHub/GitLab/Bitbucket contribution graphs for Vue 3",
5
+ "author": "Derek Johnston",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/vue.umd.js",
9
+ "module": "./dist/vue.es.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/vue.es.js",
15
+ "require": "./dist/vue.umd.js"
16
+ },
17
+ "./style.css": "./dist/style.css"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "keywords": [
25
+ "vue",
26
+ "vue3",
27
+ "github",
28
+ "gitlab",
29
+ "bitbucket",
30
+ "contributions",
31
+ "stats",
32
+ "component",
33
+ "git-stats"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/derekjj/git-stats-components.git",
38
+ "directory": "packages/vue"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/derekjj/git-stats-components/issues"
42
+ },
43
+ "homepage": "https://github.com/derekjj/git-stats-components/tree/main/packages/vue#readme",
44
+ "scripts": {
45
+ "build": "vite build",
46
+ "dev": "vite build --watch",
47
+ "clean": "rm -rf dist",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:ui": "vitest --ui"
51
+ },
52
+ "peerDependencies": {
53
+ "vue": "^3.3.0"
54
+ },
55
+ "dependencies": {
56
+ "@git-stats-components/core": "^1.0.0"
57
+ },
58
+ "devDependencies": {
59
+ "@vitejs/plugin-vue": "^5.0.0",
60
+ "@types/node": "^20.10.6",
61
+ "@vue/test-utils": "^2.4.3",
62
+ "@testing-library/jest-dom": "^6.1.5",
63
+ "jsdom": "^23.0.1",
64
+ "typescript": "^5.3.3",
65
+ "vite": "^5.0.0",
66
+ "vite-plugin-dts": "^3.7.0",
67
+ "vitest": "^1.0.4",
68
+ "@vitest/ui": "^1.0.4",
69
+ "vue": "^3.4.0",
70
+ "vue-tsc": "^2.0.0"
71
+ }
72
+ }