commit 92e23dc350ac38dee1a402dcb9cb70f8748e8d25 Author: Ricardo Campos Date: Wed Jun 11 21:09:35 2025 -0300 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b947077 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..33559e0 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Calories Tracker diff --git a/foodDatabase.js b/foodDatabase.js new file mode 100644 index 0000000..31f20f9 --- /dev/null +++ b/foodDatabase.js @@ -0,0 +1,70 @@ +const foodDatabase = { + // Fruits + 'Frutas - Abacate': { calories: 96, protein: 1.2, fat: 8.4, carbs: 6, fiber: 6.3 }, + 'Frutas - Abacaxi': { calories: 48, protein: 0.9, fat: 0.1, carbs: 12.3, fiber: 1 }, + 'Frutas - Banana Nanica': { calories: 92, protein: 1.4, fat: 0.1, carbs: 23.8, fiber: 1.9 }, + 'Frutas - Laranja': { calories: 37, protein: 1, fat: 0.1, carbs: 8.9, fiber: 0.8 }, + 'Frutas - Maçã': { calories: 56, protein: 0.3, fat: 0, carbs: 15.2, fiber: 1.3 }, + 'Frutas - Manga Palmer': { calories: 72, protein: 0.4, fat: 0.2, carbs: 19.4, fiber: 1.6 }, + 'Frutas - Mamão': { calories: 40, protein: 0.5, fat: 0.1, carbs: 10.4, fiber: 1 }, + 'Frutas - Melancia': { calories: 33, protein: 0.9, fat: 0, carbs: 8.1, fiber: 0.1 }, + 'Frutas - Melão': { calories: 29, protein: 0.7, fat: 0, carbs: 7.5, fiber: 0.3 }, + 'Frutas - Uva': { calories: 53, protein: 0.7, fat: 0.2, carbs: 13.6, fiber: 0.9 }, + + // Vegetables + 'Vegetais - Agrião': { calories: 17, protein: 2.7, fat: 0.2, carbs: 2.3, fiber: 2.1 }, + 'Vegetais - Brócolis (cozido)': { calories: 25, protein: 2.1, fat: 0.5, carbs: 4.4, fiber: 3.4 }, + 'Vegetais - Cenoura (cozida)': { calories: 30, protein: 0.8, fat: 0.2, carbs: 6.7, fiber: 2.6 }, + 'Vegetais - Couve flor (cozida)': { calories: 19, protein: 1.2, fat: 0.3, carbs: 3.9, fiber: 2.1 }, + 'Vegetais - Ervilha (cozida)': { calories: 88, protein: 7.5, fat: 0.5, carbs: 14.2, fiber: 9.7 }, + 'Vegetais - Espinafre': { calories: 16, protein: 2, fat: 0.2, carbs: 2.6, fiber: 2.1 }, + 'Vegetais - Feijão preto (cozido)': { calories: 77, protein: 4.5, fat: 0.5, carbs: 14, fiber: 8.4 }, + 'Vegetais - Lentilha (cozida)': { calories: 93, protein: 6.3, fat: 0.5, carbs: 16.3, fiber: 7.9 }, + 'Vegetais - Mandioca (cozida)': { calories: 125, protein: 0.6, fat: 0.3, carbs: 30.1, fiber: 1.6 }, + 'Vegetais - Pepino': { calories: 10, protein: 0.9, fat: 0, carbs: 2, fiber: 1.1 }, + 'Vegetais - Rúcula': { calories: 13, protein: 1.8, fat: 0.1, carbs: 2.2, fiber: 1.7 }, + 'Vegetais - Spirulina': { calories: 290, protein: 57.5, fat: 23.9, carbs: 7.7, fiber: 0 }, + 'Vegetais - Tomate': { calories: 15, protein: 1.1, fat: 0.2, carbs: 3.1, fiber: 1.2 }, + + // Carbohydrates + 'Carboidrados - Pão Francês': { calories: 300, protein: 8, fat: 3.1, carbs: 58.6, fiber: 2.3 }, + 'Carboidrados - Polenta (cozida)': { calories: 192, protein: 4.8, fat: 1.2, carbs: 40, fiber: 3.8 }, + + // Proteins + 'Proteínas - Atum Sólido (natural)': { calories: 135, protein: 28.3, fat: 2.7, carbs: 0, fiber: 0 }, + 'Proteínas - Filé de Tilápia (cozido)': { calories: 128, protein: 26.1, fat: 2.6, carbs: 0, fiber: 0 }, + 'Proteínas - Ovo inteiro (cozido)': { calories: 146, protein: 13.3, fat: 9.5, carbs: 0.6, fiber: 0 }, + 'Proteínas - Ovo clara (cozido)': { calories: 59, protein: 13.4, fat: 0.1, carbs: 0, fiber: 0 }, + 'Proteínas - PTS (crua)': { calories: 288, protein: 52, fat: 0, carbs: 20, fiber: 14 }, + 'Proteínas - Patinho moído (grelhado)': { calories: 219, protein: 35.9, fat: 7.3, carbs: 0, fiber: 0 }, + 'Proteínas - Soja em Pó Growth': { calories: 400, protein: 86.7, fat: 5, carbs: 3.3, fiber: 0 }, + 'Proteínas - Sobrecoxa s/pele (cozida)': { calories: 245, protein: 24.9, fat: 15.4, carbs: 0, fiber: 0 }, + 'Proteínas - Tofu': { calories: 65, protein: 6.5, fat: 4, carbs: 2, fiber: 0.75 }, + + // Grains + 'Grãos - Arroz integral (cozido)': { calories: 130, protein: 2.7, fat: 0.3, carbs: 28, fiber: 0.4 }, + 'Grãos - Aveia': { calories: 394, protein: 13.9, fat: 8.5, carbs: 66.6, fiber: 9.1 }, + 'Grãos - Grão de Bico (cozido)': { calories: 180, protein: 9.5, fat: 3, carbs: 30, fiber: 8.6 }, + 'Grãos - Pão integral de forma': { calories: 253, protein: 9.4, fat: 3.7, carbs: 49.9, fiber: 6.9 }, + 'Grãos - Pipoca c/óleo': { calories: 448, protein: 9.9, fat: 15.9, carbs: 70.3, fiber: 14.3 }, + 'Grãos - Pipoca s/óleo': { calories: 178, protein: 3.3, fat: 7.2, carbs: 25, fiber: 4.3 }, + 'Grãos - Quinoa (cozida)': { calories: 158, protein: 5.55, fat: 2.5, carbs: 29, fiber: 2.5 }, + + // Nuts & Seeds + 'Castanhas - Amêndoas': { calories: 581, protein: 18.6, fat: 47.3, carbs: 29.5, fiber: 11.6 }, + 'Castanhas - Amendoin natural': { calories: 611, protein: 26, fat: 49, carbs: 16, fiber: 8.5 }, + 'Castanhas - Castanha de Caju': { calories: 570, protein: 18.5, fat: 46.3, carbs: 29.1, fiber: 3.7 }, + 'Castanhas - Castanha do Pará': { calories: 643, protein: 14.5, fat: 63.5, carbs: 15.1, fiber: 7.9 }, + 'Sementes - Semente de Chia': { calories: 490, protein: 15.6, fat: 30.7, carbs: 43.8, fiber: 37.7 }, + 'Sementes - Semente de Linhaça': { calories: 495, protein: 14.1, fat: 32.3, carbs: 43.3, fiber: 33.5 }, + 'Sementes - Semente de Gergelim': { calories: 584, protein: 21.2, fat: 50.4, carbs: 21.6, fiber: 11.9 }, + + // Snacks + 'Lanches - Barra de Proteína Vegana Growth': { calories: 400, protein: 25, fat: 22, carbs: 25, fiber: 8 }, + 'Lanches - Goiabada': { calories: 320, protein: 0, fat: 0, carbs: 80, fiber: 4.5 }, + 'Lanches - Mel Silvestre': { calories: 230, protein: 0, fat: 0, carbs: 65, fiber: 0 }, + 'Lanches - Melado': { calories: 297, protein: 0, fat: 0, carbs: 76.6, fiber: 0 }, + 'Lanches - Pasta de Amendoim Growth': { calories: 544, protein: 27, fat: 33, carbs: 20, fiber: 8 }, + 'Lanches - Goma de Tapioca': { calories: 226, protein: 0, fat: 0, carbs: 57, fiber: 0 }, + 'Lanches - 70% Nibs Garoto': { calories: 544, protein: 8.4, fat: 40, carbs: 34, fiber: 0 } +}; diff --git a/index.html b/index.html new file mode 100644 index 0000000..1ed2616 --- /dev/null +++ b/index.html @@ -0,0 +1,98 @@ + + + + + + Daily Calorie Tracker + + + +
+

🍎 Daily Calorie Tracker

+ +
+ +
+
0
+
Calories Today
+
+ +
+
+
0
+
Protein (g)
+
+
+
0
+
Fat (g)
+
+
+
0
+
Carbs (g)
+
+
+
0
+
Fiber (g)
+
+
+ +
+

Add Food

+
+
+ + +
+
+ + +
+ +
+ +
+ +
+
Food Log
+
+ + + + + + + + + + + + + + + + + +
TimeFoodGramsCaloriesProtein (g)Fat (g)Carbs (g)Fiber (g)Action
+
+
+ +
+
+ +
Month Year
+ +
+
+ +
+
+
+ + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..f857d70 --- /dev/null +++ b/index.js @@ -0,0 +1,322 @@ +// App state +let selectedDate = new Date().toISOString().split('T')[0]; +let currentViewDate = new Date(); + +// Initialize the app +function init() { + populateFoodSelect(); + updateCurrentDate(); + loadDayData(selectedDate); + renderCalendar(); + addEvents(); +} + +function getFoodProportion(grams, foodData) { + const multiplier = grams / 100; // Database values are per 100g + return { + calories: Math.round(foodData.calories * multiplier), + protein: Math.round(foodData.protein * multiplier * 10) / 10, + fat: Math.round(foodData.fat * multiplier * 10) / 10, + carbs: Math.round(foodData.carbs * multiplier * 10) / 10, + fiber: Math.round(foodData.fiber * multiplier * 10) / 10 + }; +} + +function previewCalories() { + const foodSelect = document.getElementById('foodSelect'); + const gramAmount = document.getElementById('gramAmount'); + + if (!foodSelect.value) { + document.getElementById('food-preview').innerHTML = ''; + document.getElementById('food-preview').classList = 'add-food-form-item display-none'; + return; + } + + let grams = 100; + if (gramAmount && gramAmount.value && parseFloat(gramAmount.value) > 0) { + grams = parseFloat(gramAmount.value); + } + + const foodName = foodSelect.value; + const foodData = foodDatabase[foodName]; + const proportion = getFoodProportion(grams, foodData); + + const textArray = []; + textArray.push(`Calories in ${grams}g: ${proportion.calories}; `); + textArray.push(`Protein: ${proportion.protein}g; `); + textArray.push(`Fat: ${proportion.fat}g; `); + textArray.push(`Carbohydrates: ${proportion.carbs}g; `); + textArray.push(`Fiber: ${proportion.fiber}g;`); + + document.getElementById('food-preview').innerHTML = textArray.join(''); + document.getElementById('food-preview').classList = 'add-food-form-item display-block'; +} + +function addEvents() { + document.getElementById('foodSelect').addEventListener('change', () => { + previewCalories(); + }); + + document.getElementById('gramAmount').addEventListener('change', () => { + previewCalories(); + }); +} + +// Populate food select dropdown +function populateFoodSelect() { + const select = document.getElementById('foodSelect'); + select.innerHTML = ''; + + const sortedFoods = Object.keys(foodDatabase).sort(); + sortedFoods.forEach(food => { + const option = document.createElement('option'); + option.value = food; + option.textContent = food.charAt(0).toUpperCase() + food.slice(1); + select.appendChild(option); + }); +} + +// Update current date display +function updateCurrentDate() { + const date = new Date(selectedDate); + const options = { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }; + document.getElementById('currentDate').textContent = date.toLocaleDateString('en-US', options); +} + +// Add food to the log +function addFood() { + const foodSelect = document.getElementById('foodSelect'); + const gramAmount = document.getElementById('gramAmount'); + + if (!foodSelect.value || !gramAmount.value) { + alert('Please select a food item and enter amount'); + return; + } + + const foodName = foodSelect.value; + const grams = parseFloat(gramAmount.value); + const foodData = foodDatabase[foodName]; + + // Calculate nutrition for the amount + const proportion = getFoodProportion(grams, foodData); + const entry = { + id: Date.now(), + name: foodName, + grams: grams, + calories: proportion.calories, + protein: proportion.protein, + fat: proportion.fat, + carbs: proportion.carbs, + fiber: proportion.fiber, + time: new Date().toLocaleTimeString('en-US', { + hour12: false, + hour: '2-digit', + minute: '2-digit' + }) + }; + + // Save to localStorage + const dayData = getDayData(selectedDate); + dayData.push(entry); + saveDayData(selectedDate, dayData); + + // Update display + loadDayData(selectedDate); + renderCalendar(); + + // Reset form + foodSelect.value = ''; + gramAmount.value = '100'; + document.getElementById('food-preview').innerHTML = ''; + document.getElementById('food-preview').classList = 'add-food-form-item display-none'; +} + +// Get day data from localStorage +function getDayData(date) { + const key = `calories_${date}`; + return JSON.parse(localStorage.getItem(key)) || []; +} + +// Save day data to localStorage +function saveDayData(date, data) { + const key = `calories_${date}`; + localStorage.setItem(key, JSON.stringify(data)); +} + +// Load and display day data +function loadDayData(date) { + const dayData = getDayData(date); + + // Update counters + let totalCalories = 0; + let totalProtein = 0; + let totalFat = 0; + let totalCarbs = 0; + let totalFiber = 0; + + dayData.forEach(entry => { + totalCalories += entry.calories; + totalProtein += entry.protein; + totalFat += entry.fat; + totalCarbs += entry.carbs; + totalFiber += entry.fiber; + }); + + document.getElementById('caloriesCounter').textContent = totalCalories; + document.getElementById('proteinValue').textContent = Math.round(totalProtein * 10) / 10; + document.getElementById('fatValue').textContent = Math.round(totalFat * 10) / 10; + document.getElementById('carboValue').textContent = Math.round(totalCarbs * 10) / 10; + document.getElementById('fiberValue').textContent = Math.round(totalFiber * 10) / 10; + + // Update table + const tbody = document.getElementById('foodTableBody'); + tbody.innerHTML = ''; + + dayData.forEach(entry => { + const row = document.createElement('tr'); + row.innerHTML = ` + ${entry.time} + ${entry.name.charAt(0).toUpperCase() + entry.name.slice(1)} + ${entry.grams} + ${entry.calories} + ${entry.protein} + ${entry.fat} + ${entry.carbs} + ${entry.fiber} + + `; + tbody.appendChild(row); + }); +} + +// Delete an entry +function deleteEntry(date, entryId) { + if (confirm('Are you sure you want to delete this entry?')) { + let dayData = getDayData(date); + dayData = dayData.filter(entry => entry.id !== entryId); + saveDayData(date, dayData); + loadDayData(selectedDate); + renderCalendar(); + } +} + +// Calendar functions +function previousMonth() { + currentViewDate.setMonth(currentViewDate.getMonth() - 1); + renderCalendar(); +} + +function nextMonth() { + currentViewDate.setMonth(currentViewDate.getMonth() + 1); + renderCalendar(); +} + +function selectDate(date) { + selectedDate = date; + updateCurrentDate(); + loadDayData(selectedDate); + renderCalendar(); +} + +function renderCalendar() { + const year = currentViewDate.getFullYear(); + const month = currentViewDate.getMonth(); + + // Update calendar title + const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December']; + document.getElementById('calendarTitle').textContent = `${monthNames[month]} ${year}`; + + // Clear calendar + const grid = document.getElementById('calendarGrid'); + grid.innerHTML = ''; + + // Add day headers + const dayHeaders = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + dayHeaders.forEach(day => { + const header = document.createElement('div'); + header.className = 'calendar-day-header'; + header.textContent = day; + grid.appendChild(header); + }); + + // Get first day of month and number of days + const firstDay = new Date(year, month, 1); + const lastDay = new Date(year, month + 1, 0); + const daysInMonth = lastDay.getDate(); + const startingDayOfWeek = firstDay.getDay(); + + // Add empty cells for previous month + const prevMonth = new Date(year, month, 0); + const daysInPrevMonth = prevMonth.getDate(); + + for (let i = startingDayOfWeek - 1; i >= 0; i--) { + const day = daysInPrevMonth - i; + const dayElement = createDayElement(day, true, year, month - 1); + grid.appendChild(dayElement); + } + + // Add days of current month + for (let day = 1; day <= daysInMonth; day++) { + const dayElement = createDayElement(day, false, year, month); + grid.appendChild(dayElement); + } + + // Add days from next month to fill the grid + const totalCells = grid.children.length - 7; + const remainingCells = 42 - totalCells; + + for (let day = 1; day <= remainingCells; day++) { + const dayElement = createDayElement(day, true, year, month + 1); + grid.appendChild(dayElement); + } +} + +function createDayElement(day, isOtherMonth, year, month) { + const dayElement = document.createElement('div'); + dayElement.className = 'calendar-day'; + + const dayDate = new Date(year, month, day); + const dateString = dayDate.toISOString().split('T')[0]; + + if (isOtherMonth) { + dayElement.classList.add('other-month'); + } else { + dayElement.onclick = () => selectDate(dateString); + } + + // Check if this is today + const today = new Date().toISOString().split('T')[0]; + if (!isOtherMonth && dateString === today) { + dayElement.classList.add('today'); + } + + // Check if this is selected date + if (!isOtherMonth && dateString === selectedDate) { + dayElement.classList.add('selected'); + } + + // Check if this day has data + const dayData = getDayData(dateString); + if (dayData.length > 0) { + dayElement.classList.add('has-data'); + const totalCalories = dayData.reduce((sum, entry) => sum + entry.calories, 0); + + dayElement.innerHTML = ` +
${day}
+
${totalCalories} cal
+ `; + } else { + dayElement.textContent = day; + } + + return dayElement; +} + +// Initialize when page loads +document.addEventListener('DOMContentLoaded', init); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3def26f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1009 @@ +{ + "name": "calories-tracker", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "calories-tracker", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "vite": "^6.3.5" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz", + "integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz", + "integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz", + "integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz", + "integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz", + "integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz", + "integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz", + "integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz", + "integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz", + "integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz", + "integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz", + "integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz", + "integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz", + "integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz", + "integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz", + "integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz", + "integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz", + "integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz", + "integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz", + "integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz", + "integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz", + "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz", + "integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.43.0", + "@rollup/rollup-android-arm64": "4.43.0", + "@rollup/rollup-darwin-arm64": "4.43.0", + "@rollup/rollup-darwin-x64": "4.43.0", + "@rollup/rollup-freebsd-arm64": "4.43.0", + "@rollup/rollup-freebsd-x64": "4.43.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.43.0", + "@rollup/rollup-linux-arm-musleabihf": "4.43.0", + "@rollup/rollup-linux-arm64-gnu": "4.43.0", + "@rollup/rollup-linux-arm64-musl": "4.43.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.43.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.43.0", + "@rollup/rollup-linux-riscv64-gnu": "4.43.0", + "@rollup/rollup-linux-riscv64-musl": "4.43.0", + "@rollup/rollup-linux-s390x-gnu": "4.43.0", + "@rollup/rollup-linux-x64-gnu": "4.43.0", + "@rollup/rollup-linux-x64-musl": "4.43.0", + "@rollup/rollup-win32-arm64-msvc": "4.43.0", + "@rollup/rollup-win32-ia32-msvc": "4.43.0", + "@rollup/rollup-win32-x64-msvc": "4.43.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2190a29 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "calories-tracker", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "vite": "^6.3.5" + } +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..4cc9aef --- /dev/null +++ b/style.css @@ -0,0 +1,394 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; + color: #333; +} + +.container { + max-width: 1200px; + margin: 0 auto; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2); + padding: 40px; + backdrop-filter: blur(10px); +} + +h1 { + text-align: center; + margin-bottom: 40px; + font-size: 2.5rem; + color: #4a5568; + font-weight: 300; +} + +.calories-banner { + text-align: center; + background: linear-gradient(135deg, #FF6B6B, #4ECDC4); + color: white; + padding: 60px 40px; + border-radius: 15px; + margin-bottom: 30px; + box-shadow: 0 10px 30px rgba(255, 107, 107, 0.3); + transition: transform 0.3s ease; +} + +.calories-banner:hover { + transform: translateY(-5px); +} + +.calories-number { + font-size: 4rem; + font-weight: bold; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); +} + +.calories-text { + font-size: 1.3rem; + opacity: 0.9; +} + +.date-display { + text-align: center; + font-size: 1.5rem; + margin-bottom: 30px; + color: #4a5568; + font-weight: 500; +} + +.add-food-section { + background: white; + padding: 30px; + border-radius: 15px; + margin-bottom: 30px; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1); +} + +.add-food-title { + font-size: 1.5rem; + margin-bottom: 20px; + color: #4a5568; + text-align: center; +} + +.add-food-form { + display: grid; + grid-template-columns: 2fr 1fr auto; + gap: 15px; + align-items: end; + overflow: hidden; +} + +.add-food-form-item { + margin-top: 15px; + margin-left: 3px; +} + +.display-none { + display: none; +} + +.display-block { + display: block; +} + +.form-group { + display: flex; + flex-direction: column; + min-width: 0; +} + +label { + margin-bottom: 5px; + font-weight: 600; + color: #4a5568; +} + +select, input { + padding: 12px; + border: 2px solid #e2e8f0; + border-radius: 8px; + font-size: 1rem; + transition: border-color 0.3s ease; + width: 100%; + min-width: 0; + box-sizing: border-box; +} + +select:focus, input:focus { + outline: none; + border-color: #667eea; +} + +.add-btn { + padding: 12px 25px; + background: linear-gradient(135deg, #4CAF50, #45a049); + color: white; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 1rem; + font-weight: 600; + transition: all 0.3s ease; + height: fit-content; +} + +.add-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3); +} + +.food-table-section { + background: white; + border-radius: 15px; + margin-bottom: 30px; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +.table-title { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + padding: 20px; + font-size: 1.2rem; + font-weight: 600; + text-align: center; +} + +.table-wrapper { + overflow-x: auto; + overflow-y: visible; +} + +.food-table { + width: 100%; + border-collapse: collapse; + min-width: 600px; +} + +.food-table th, +.food-table td { + padding: 15px 10px; + text-align: left; + border-bottom: 1px solid #e2e8f0; + white-space: nowrap; +} + +.food-table th { + background: #f8fafc; + font-weight: 600; + color: #4a5568; + font-size: 0.9rem; +} + +.food-table tr:hover { + background: #f7fafc; +} + +.delete-btn { + background: #ff6b6b; + color: white; + border: none; + padding: 5px 10px; + border-radius: 5px; + cursor: pointer; + font-size: 0.8rem; + transition: background 0.3s ease; +} + +.delete-btn:hover { + background: #e55656; +} + +.calendar-section { + background: white; + border-radius: 15px; + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +.calendar-header { + background: linear-gradient(135deg, #667eea, #764ba2); + color: white; + padding: 20px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.calendar-nav { + background: rgba(255, 255, 255, 0.2); + border: none; + color: white; + padding: 10px 15px; + border-radius: 8px; + cursor: pointer; + font-size: 1.1rem; + transition: background 0.3s ease; +} + +.calendar-nav:hover { + background: rgba(255, 255, 255, 0.3); +} + +.calendar-title { + font-size: 1.2rem; + font-weight: 600; +} + +.calendar-grid { + display: grid; + grid-template-columns: repeat(7, 1fr); + gap: 1px; + background: #e2e8f0; +} + +.calendar-day-header { + background: #f8fafc; + padding: 15px 5px; + text-align: center; + font-weight: 600; + color: #4a5568; + font-size: 0.9rem; +} + +.calendar-day { + background: white; + padding: 15px 5px; + text-align: center; + cursor: pointer; + transition: all 0.2s ease; + min-height: 60px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: relative; +} + +.calendar-day:hover { + background: #f7fafc; +} + +.calendar-day.other-month { + color: #cbd5e0; + background: #f8fafc; +} + +.calendar-day.today { + background: #667eea; + /*color: white;*/ + font-weight: bold; +} + +.calendar-day.selected { + background: #4CAF50; + color: white; + font-weight: bold; +} + +.calendar-day.has-data { + background: #e6fffa; + border: 2px solid #4ECDC4; +} + +.calendar-day.has-data.selected { + background: #4CAF50; + border-color: #45a049; +} + +.day-calories { + font-size: 0.7rem; + margin-top: 2px; + opacity: 0.8; +} + +.nutrition-summary { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); + gap: 15px; + margin-top: 20px; + padding: 20px; + background: #f8fafc; + border-radius: 10px; +} + +.nutrition-item { + text-align: center; + padding: 10px; + background: white; + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.nutrition-value { + font-size: 1.2rem; + font-weight: bold; + color: #4a5568; +} + +.nutrition-label { + font-size: 0.8rem; + color: #718096; + margin-top: 2px; +} + +@media (max-width: 768px) { + .container { + margin: 0px; + padding: 15px; + } + + .calories-number { + font-size: 3rem; + } + + .add-food-form { + grid-template-columns: 1fr; + gap: 15px; + } + + .food-table { + font-size: 0.8rem; + min-width: 650px; + } + + .food-table th, + .food-table td { + padding: 8px 5px; + white-space: nowrap; + } + + .table-wrapper { + -webkit-overflow-scrolling: touch; + scrollbar-width: thin; + } + + /* Optional: Add a subtle shadow to indicate scrollability */ + .table-wrapper::-webkit-scrollbar { + height: 6px; + } + + .table-wrapper::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 3px; + } + + .table-wrapper::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 3px; + } + + h1 { + font-size: 2rem; + } +} \ No newline at end of file