eatopia-ds 0.0.949 → 0.0.950
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.
- package/build/index10.js +237 -212
- package/build/index10.js.map +1 -1
- package/build/index11.js +1 -1
- package/build/index11.js.map +1 -1
- package/build/index18.js +25 -21
- package/build/index18.js.map +1 -1
- package/build/index31.js +2 -2
- package/build/index32.js +1 -1
- package/build/index34.js +2 -2
- package/build/index35.js +1 -1
- package/build/index46.js.map +1 -1
- package/build/index47.js +66 -52
- package/build/index47.js.map +1 -1
- package/build/index48.js +26 -22
- package/build/index48.js.map +1 -1
- package/build/index49.js.map +1 -1
- package/build/index50.js +52 -66
- package/build/index50.js.map +1 -1
- package/build/index51.js +22 -26
- package/build/index51.js.map +1 -1
- package/package.json +1 -1
package/build/index18.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index18.js","sources":["../src/components/StockLeadTime/index.tsx"],"sourcesContent":["import { HoverState, Point, StockLeadTimeProps, TimelineData } from \"./types\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\n// Paleta de cores por tema\nconst THEME_COLORS = {\n light: {\n stockSafe: \"#00E676\",\n stockPast: \"#c4ccd0\",\n stockFuture: \"#349d50\",\n alert: \"#f9f198\",\n todayIndicator: \"#2979FF\",\n textPrimary: \"#37474F\",\n textSecondary: \"#90A4AE\",\n background: \"#F5F5F5\",\n deliveryBar: \"#0d0f0d\",\n legendBackground: \"rgba(255, 255, 255, 0.8)\",\n tooltipBackground: \"#37474F\",\n tooltipText: \"#FFFFFF\",\n alertCritical: \"#D32F2F\",\n alertUrgent: \"#F57C00\",\n alertWarning: \"#FBC02D\",\n alertSuccess: \"#388E3C\",\n alertInfo: \"#0288D1\",\n selectedQtyBar: \"#2196F3\", // Azul para barra de quantidade selecionada\n },\n dark: {\n stockSafe: \"#00E676\",\n stockPast: \"#455A64\", // Cinza azulado escuro\n stockFuture: \"#43A047\", // Verde ligeiramente mais vibrante\n alert: \"#FDD835\", // Amarelo mais forte\n todayIndicator: \"#448AFF\",\n textPrimary: \"#ECEFF1\", // Quase branco\n textSecondary: \"#B0BEC5\", // Cinza claro\n background: \"#263238\", // Azul acinzentado bem escuro\n deliveryBar: \"#FFFFFF\",\n legendBackground: \"rgba(38, 50, 56, 0.9)\",\n tooltipBackground: \"#ECEFF1\",\n tooltipText: \"#263238\",\n alertCritical: \"#EF5350\",\n alertUrgent: \"#FFA726\",\n alertWarning: \"#FFEE58\",\n alertSuccess: \"#66BB6A\",\n alertInfo: \"#29B6F6\",\n selectedQtyBar: \"#42A5F5\", // Azul mais claro para tema escuro\n },\n};\n\nconst SIZE_CONFIG = {\n sm: {\n height: 170,\n segmentRatio: 0.2,\n fontSize: 10,\n padding: {\n top: 25,\n bottom: 40,\n left: 8,\n right: 8,\n },\n pillHeight: 14,\n pillPaddingX: 4,\n pillPaddingY: 2,\n pillFontSize: 8,\n },\n md: {\n height: 220,\n segmentRatio: 0.22,\n fontSize: 12,\n padding: {\n top: 30,\n bottom: 50,\n left: 10,\n right: 10,\n },\n pillHeight: 16,\n pillPaddingX: 6,\n pillPaddingY: 3,\n pillFontSize: 9,\n },\n lg: {\n height: 270,\n segmentRatio: 0.25,\n fontSize: 14,\n padding: {\n top: 35,\n bottom: 60,\n left: 12,\n right: 12,\n },\n pillHeight: 20,\n pillPaddingX: 8,\n pillPaddingY: 4,\n pillFontSize: 11,\n },\n};\n\n// Polyfill para roundRect (caso não esteja disponível)\nconst ensureRoundRect = (ctx: CanvasRenderingContext2D) => {\n if (!(ctx as any).roundRect) {\n (ctx as any).roundRect = function (\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n ) {\n if (w < 2 * r) r = w / 2;\n if (h < 2 * r) r = h / 2;\n this.beginPath();\n this.moveTo(x + r, y);\n this.arcTo(x + w, y, x + w, y + h, r);\n this.arcTo(x + w, y + h, x, y + h, r);\n this.arcTo(x, y + h, x, y, r);\n this.arcTo(x, y, x + w, y, r);\n this.closePath();\n };\n }\n};\n\n// Helper para ajustar brilho de cores Hex\nconst adjustColorBrightness = (hex: string, percent: number) => {\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) + amt;\n const G = ((num >> 8) & 0x00ff) + amt;\n const B = (num & 0x0000ff) + amt;\n return (\n \"#\" +\n (\n 0x1000000 +\n (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +\n (G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +\n (B < 255 ? (B < 1 ? 0 : B) : 255)\n )\n .toString(16)\n .slice(1)\n );\n};\n\ntype AlertStatus = \"critical\" | \"urgent\" | \"warning\" | \"success\" | \"info\";\n\ninterface StockAlertInfo {\n status: AlertStatus;\n title: string;\n message: string;\n}\n\n/** Interpreta \"YYYY-MM-DD\" como meia-noite no fuso local. */\nfunction parseDateLocal(dateStr: string): Date {\n const parts = dateStr.split(\"-\").map(Number);\n if (parts.length !== 3 || parts.some(Number.isNaN)) return new Date(NaN);\n return new Date(parts[0], parts[1] - 1, parts[2]);\n}\n\n/**\n * Interpreta data/hora no fuso local.\n * - \"YYYY-MM-DD\" → meia-noite (00:00)\n * - \"YYYY-MM-DDTHH:mm\" ou \"YYYY-MM-DDTHH:mm:ss\" → hora exata (ex: 06:00 para entrega)\n */\nfunction parseDateTimeLocal(dateStr: string): Date {\n const datePart = dateStr.split(\"T\")[0];\n const timePart = dateStr.includes(\"T\") ? dateStr.split(\"T\")[1] : null;\n const date = parseDateLocal(datePart);\n if (isNaN(date.getTime())) return date;\n if (timePart) {\n const [h, m, sMs] = timePart.split(\":\");\n const hour = parseInt(h ?? \"0\", 10);\n const min = parseInt(m ?? \"0\", 10);\n const s = sMs !== undefined ? parseInt(sMs.slice(0, 2), 10) || 0 : 0;\n const ms = sMs?.includes(\".\") ? parseInt(sMs.split(\".\")[1].slice(0, 3), 10) || 0 : 0;\n if (!Number.isNaN(hour)) date.setHours(hour, min, s, ms);\n }\n return date;\n}\n\n/** Para datas de fim de período: sem \"T\" = 23:59:59 do dia; com \"T\" = hora exata. */\nfunction parseDateTimeLocalEnd(dateStr: string): Date {\n if (!dateStr.includes(\"T\")) return getEndOfDay(parseDateLocal(dateStr));\n return parseDateTimeLocal(dateStr);\n}\n\n/** Retorna a mesma data às 23:59:59.999 (fim do dia) para barras irem até o fim do dia. */\nfunction getEndOfDay(d: Date): Date {\n const eod = new Date(d);\n eod.setHours(23, 59, 59, 999);\n return eod;\n}\n\nconst getStockAlert = (timeline: TimelineData[\"timeline\"]): StockAlertInfo => {\n const today = parseDateTimeLocal(timeline.todayDate).getTime();\n const stockEnd = parseDateTimeLocalEnd(timeline.stockEndDate).getTime();\n const delivery = parseDateTimeLocal(timeline.deliveryDate).getTime();\n const suggestStart = parseDateTimeLocal(timeline.restockSuggestionStart).getTime();\n const suggestEnd = parseDateTimeLocalEnd(timeline.restockSuggestionEnd).getTime();\n\n // 1. Crítico: Entrega após fim de estoque (Ruptura) ou no mesmo dia\n // Se delivery > stockEnd: Já passou, ruptura certa (Crítico)\n // Se delivery == stockEnd: Chega no dia que acaba (Crítico/Risco Altíssimo)\n if (delivery >= stockEnd) {\n const daysLate = Math.ceil((delivery - stockEnd) / (1000 * 60 * 60 * 24));\n return {\n status: \"critical\",\n title: \"Risco de Ruptura\",\n message:\n daysLate > 0\n ? `A entrega chegará ${daysLate} dia(s) após o estoque acabar.`\n : \"A entrega está prevista para o mesmo dia do fim do estoque.\",\n };\n }\n\n // 2. Crítico: Estoque Esgotado (Hoje já passou do fim do estoque)\n if (today >= stockEnd) {\n return {\n status: \"critical\",\n title: \"Estoque Esgotado\",\n message: \"Seu estoque previsto chegou ao fim.\",\n };\n }\n\n // Verifica margem de segurança entre entrega e fim do estoque\n const daysMargin = Math.floor((stockEnd - delivery) / (1000 * 60 * 60 * 24));\n\n // 3. Urgente (Laranja): Entrega chega com pouca margem (até 2 dias antes do fim)\n if (daysMargin <= 2) {\n return {\n status: \"urgent\",\n title: \"Atenção ao Prazo\",\n message: `Margem de segurança baixa: entrega prevista para ${daysMargin} dia(s) antes do fim do estoque.`,\n };\n }\n\n // 4. Warning (Amarelo): Janela de compra aberta (apenas se não cair nas regras acima)\n // Se ainda não comprou (assumindo que se tem data de entrega, já comprou?\n // A lógica original não distinguia \"já comprou\" de \"sugestão\".\n // Vou manter a lógica de sugestão, mas com menor prioridade que a margem de entrega.\n if (today >= suggestStart && today <= suggestEnd) {\n return {\n status: \"warning\",\n title: \"Sugestão de Compra\",\n message: \"Momento ideal para realizar o pedido de reposição.\",\n };\n }\n\n // 5. Sucesso (Verde): Margem segura (> 2 dias) ou antes do período de sugestão\n return {\n status: \"success\",\n title: \"Estoque Seguro\",\n message: \"Nível de estoque adequado. Nenhuma ação necessária.\",\n };\n};\n\nexport function StockLeadTime({\n data,\n className,\n style,\n controls = false,\n showLegend = true,\n size = \"md\",\n selectedQty,\n selectedQtyDays,\n showSuggestionBar: showSuggestionBarProp = true,\n unitLabel = \"kg\",\n}: StockLeadTimeProps) {\n const sizeConfig = useMemo(() => SIZE_CONFIG[size], [size]);\n\n // Define as cores com base no tema\n const COLORS = useMemo(\n () => THEME_COLORS[data.config.theme || \"light\"],\n [data.config.theme],\n );\n\n const alertInfo = useMemo(\n () => getStockAlert(data.timeline),\n [data.timeline],\n );\n\n // Constantes e funções auxiliares para o tooltip\n const DAY_NAMES = [\"DOM\", \"SEG\", \"TER\", \"QUA\", \"QUI\", \"SEX\", \"SAB\"];\n\n const getDailyConsumption = useCallback(\n (dayOfWeek: number): number | null => {\n if (!data.timeline.dailyConsumptionAverage) return null;\n\n const dayKeys: (keyof typeof data.timeline.dailyConsumptionAverage)[] = [\n \"0-domingo\",\n \"1-segunda\",\n \"2-terca\",\n \"3-quarta\",\n \"4-quinta\",\n \"5-sexta\",\n \"6-sabado\",\n ];\n\n const key = dayKeys[dayOfWeek];\n return data.timeline.dailyConsumptionAverage[key] ?? null;\n },\n [data],\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [hoverState, setHoverState] = useState<HoverState>({\n isHovering: false,\n hoveredSection: null,\n mouseX: 0,\n mouseY: 0,\n dateAtCursor: null,\n });\n const [tooltipPosition, setTooltipPosition] = useState<Point>({ x: 0, y: 0 });\n // Níveis de zoom relativos ao valor base de pixels por dia (4 opções)\n const ZOOM_LEVELS = useMemo(() => [0.6, 0.9, 1, 1.4] as const, []);\n const [zoomLevelIndex, setZoomLevelIndex] = useState<number>(2); // nível padrão próximo ao original\n // Estado para scroll horizontal\n const [scrollOffset, setScrollOffset] = useState<number>(0);\n // Estado para mostrar/esconder linha de consumo médio\n const [showConsumptionLine, setShowConsumptionLine] =\n useState<boolean>(false);\n // Estado para mostrar/esconder barra amarela (sugestão) quando controls=true\n const [suggestionBarVisible, setSuggestionBarVisible] = useState<boolean>(\n showSuggestionBarProp,\n );\n const showSuggestionBarEffective = controls\n ? suggestionBarVisible\n : showSuggestionBarProp;\n\n useEffect(() => {\n setSuggestionBarVisible(showSuggestionBarProp);\n }, [showSuggestionBarProp]);\n\n // Datas/horas em escala de horas: \"YYYY-MM-DD\" (00:00) ou \"YYYY-MM-DDTHH:mm\" (hora exata)\n const startDate = useMemo(\n () => parseDateTimeLocal(data.timeline.lastRestockDate),\n [data.timeline.lastRestockDate],\n );\n const todayDate = useMemo(\n () => parseDateTimeLocal(data.timeline.todayDate),\n [data.timeline.todayDate],\n );\n // Fim do estoque / fim da sugestão: sem \"T\" = 23:59 do dia; com \"T\" = hora exata\n const stockEndDate = useMemo(\n () => parseDateTimeLocalEnd(data.timeline.stockEndDate),\n [data.timeline.stockEndDate],\n );\n const restockStart = useMemo(\n () => parseDateTimeLocal(data.timeline.restockSuggestionStart),\n [data.timeline.restockSuggestionStart],\n );\n const restockEnd = useMemo(\n () => parseDateTimeLocalEnd(data.timeline.restockSuggestionEnd),\n [data.timeline.restockSuggestionEnd],\n );\n const deliveryDate = useMemo(\n () => parseDateTimeLocal(data.timeline.deliveryDate),\n [data.timeline.deliveryDate],\n );\n\n const MS_PER_DAY = 1000 * 60 * 60 * 24;\n\n // Pixels efetivos por dia considerando o zoom atual\n const pixelsPerDay = useMemo(\n () => data.config.pixelsPerDay * ZOOM_LEVELS[zoomLevelIndex],\n [data.config.pixelsPerDay, zoomLevelIndex, ZOOM_LEVELS],\n );\n\n // Calcula posições X no canvas (considerando scroll)\n const dateToX = useCallback(\n (date: Date): number => {\n // Usa milissegundos diretamente para preservar decimais\n const daysDiff = (date.getTime() - startDate.getTime()) / MS_PER_DAY;\n return sizeConfig.padding.left + daysDiff * pixelsPerDay - scrollOffset;\n },\n [\n startDate,\n pixelsPerDay,\n sizeConfig.padding.left,\n scrollOffset,\n MS_PER_DAY,\n ],\n );\n\n // Calcula data a partir da posição X (considerando scroll)\n const xToDate = useCallback(\n (x: number): Date => {\n const daysFromStart =\n (x - sizeConfig.padding.left + scrollOffset) / pixelsPerDay;\n const date = new Date(startDate);\n date.setDate(date.getDate() + Math.floor(daysFromStart));\n return date;\n },\n [startDate, pixelsPerDay, sizeConfig.padding.left, scrollOffset],\n );\n\n // Formata data para exibição (DD/MM)\n const formatDate = (date: Date): string => {\n return `${date.getDate().toString().padStart(2, \"0\")}/${(\n date.getMonth() + 1\n )\n .toString()\n .padStart(2, \"0\")}`;\n };\n\n // Formata data e hora quando não for meia-noite (DD/MM HH:mm)\n const formatDateTime = (date: Date): string => {\n const d = date.getDate().toString().padStart(2, \"0\");\n const m = (date.getMonth() + 1).toString().padStart(2, \"0\");\n if (date.getHours() === 0 && date.getMinutes() === 0) return `${d}/${m}`;\n const h = date.getHours().toString().padStart(2, \"0\");\n const min = date.getMinutes().toString().padStart(2, \"0\");\n return `${d}/${m} ${h}:${min}`;\n };\n\n // Desenha o canvas\n const drawCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Garante que roundRect está disponível\n ensureRoundRect(ctx);\n\n const dpr = window.devicePixelRatio || 1;\n const rect = canvas.getBoundingClientRect();\n const width = rect.width;\n const height = sizeConfig.height;\n\n // Ajusta resolução para High DPI\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n ctx.scale(dpr, dpr);\n\n // Limpa o canvas\n ctx.clearRect(0, 0, width, height);\n\n // Desenha background com bordas arredondadas\n ctx.fillStyle = COLORS.background;\n (ctx as any).roundRect(0, 0, width, height, 12);\n ctx.fill();\n\n // Desenha indicador de hover (dia selecionado)\n if (hoverState.isHovering && hoverState.dateAtCursor) {\n const hoverX = dateToX(hoverState.dateAtCursor);\n // Verifica limites (opcional, mas bom para evitar desenhar fora se o zoom mudar ou algo assim)\n // O dateToX já considera o padding.\n\n const isDark = data.config.theme === \"dark\";\n ctx.fillStyle = isDark\n ? \"rgba(255, 255, 255, 0.05)\"\n : \"rgba(0, 0, 0, 0.05)\";\n\n const graphTop = sizeConfig.padding.top;\n const graphHeight =\n height - sizeConfig.padding.bottom - sizeConfig.padding.top;\n\n ctx.fillRect(hoverX, graphTop, pixelsPerDay, graphHeight);\n }\n\n // Calcula posições das barras (barras vão até 23:59 do dia final)\n const lastRestockX = dateToX(startDate); // Último abastecimento\n const todayX = dateToX(todayDate);\n const stockEndX = dateToX(stockEndDate); // Previsão de duração (até 23:59)\n\n // Data de entrega (recebida diretamente)\n const deliveryStartX = dateToX(deliveryDate);\n\n const restockStartX = dateToX(restockStart);\n const restockEndX = dateToX(restockEnd); // Fim da sugestão (até 23:59)\n\n const barY = sizeConfig.padding.top;\n const fullHeight =\n height - sizeConfig.padding.top - sizeConfig.padding.bottom;\n const segmentHeight = fullHeight * sizeConfig.segmentRatio; // Altura proporcional ao tamanho\n\n const stockY = barY + 5; // Levemente deslocado do topo\n // Mantém em Y diferentes, mas reduz o espaçamento vertical para ficar visualmente agrupado\n const suggestionY = stockY + segmentHeight + 2;\n\n // Todas as barras sempre com opacidade total - sem alteração no hover\n\n // Desenha Grid de Tempo (linhas verticais)\n ctx.strokeStyle = COLORS.textSecondary;\n ctx.lineWidth = 1;\n ctx.setLineDash([]);\n\n // Usa a data mais recente entre restockEnd e deliveryDate para calcular o fim do grid (barras até 23:59)\n let maxTime = Math.max(\n restockEnd.getTime(),\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n );\n\n // Se há quantidade selecionada, considera também o fim dessa barra (até 23:59 do último dia)\n if (typeof selectedQtyDays === \"number\" && selectedQtyDays > 0) {\n const selectedQtyStartDateCalc = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDateCalc.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDateCalc = getEndOfDay(lastDayOfSelected);\n maxTime = Math.max(maxTime, selectedQtyEndDateCalc.getTime());\n }\n\n const endDate = new Date(maxTime);\n // Adiciona alguns dias de buffer para visualização\n endDate.setDate(endDate.getDate() + 2);\n const totalDays = Math.ceil(\n (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24),\n );\n\n // Nomes dos meses abreviados\n const MONTH_NAMES = [\n \"JAN\",\n \"FEV\",\n \"MAR\",\n \"ABR\",\n \"MAI\",\n \"JUN\",\n \"JUL\",\n \"AGO\",\n \"SET\",\n \"OUT\",\n \"NOV\",\n \"DEZ\",\n ];\n\n // Cores alternadas para meses (light e dark themes) - cores mais distintas\n const getMonthBackgroundColor = (monthIndex: number) => {\n const isEvenMonth = monthIndex % 2 === 0;\n if (data.config.theme === \"dark\") {\n return isEvenMonth\n ? \"rgba(71, 85, 105, 0.25)\"\n : \"rgba(51, 65, 85, 0.4)\";\n }\n return isEvenMonth\n ? \"rgba(241, 245, 249, 0.6)\"\n : \"rgba(203, 213, 225, 0.5)\";\n };\n\n // Cores dos labels dos dias alternando por mês\n const getDayLabelColor = (monthIndex: number, isWeekend: boolean) => {\n const isEvenMonth = monthIndex % 2 === 0;\n if (isWeekend) {\n return adjustColorBrightness(COLORS.textSecondary, -25);\n }\n if (data.config.theme === \"dark\") {\n return isEvenMonth\n ? \"rgba(148, 163, 184, 1)\"\n : \"rgba(226, 232, 240, 1)\";\n }\n return isEvenMonth ? \"rgba(100, 116, 139, 1)\" : \"rgba(51, 65, 85, 1)\";\n };\n\n // Primeiro, coleta informações dos meses\n const monthRanges: {\n month: number;\n year: number;\n startX: number;\n endX: number;\n }[] = [];\n let currentMonth = -1;\n let currentYear = -1;\n let monthStartX = sizeConfig.padding.left;\n\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(startDate);\n date.setDate(date.getDate() + i);\n const x = dateToX(date);\n const month = date.getMonth();\n const year = date.getFullYear();\n\n if (month !== currentMonth || year !== currentYear) {\n // Salva o mês anterior\n if (currentMonth !== -1) {\n monthRanges.push({\n month: currentMonth,\n year: currentYear,\n startX: monthStartX,\n endX: x,\n });\n }\n currentMonth = month;\n currentYear = year;\n monthStartX = x;\n }\n }\n // Adiciona o último mês\n if (currentMonth !== -1) {\n const lastDate = new Date(startDate);\n lastDate.setDate(lastDate.getDate() + totalDays);\n monthRanges.push({\n month: currentMonth,\n year: currentYear,\n startX: monthStartX,\n endX: dateToX(lastDate) + pixelsPerDay,\n });\n }\n\n // Desenha backgrounds dos meses ATRÁS do gráfico (área das barras)\n const graphAreaTop = barY;\n const graphAreaHeight = height - sizeConfig.padding.bottom - barY;\n\n for (const range of monthRanges) {\n const bgStartX = Math.max(range.startX, sizeConfig.padding.left);\n const bgEndX = Math.min(range.endX, width - sizeConfig.padding.right);\n const bgWidth = bgEndX - bgStartX;\n\n if (bgWidth > 0) {\n // Background do mês na área do gráfico\n ctx.fillStyle = getMonthBackgroundColor(range.month);\n ctx.fillRect(bgStartX, graphAreaTop, bgWidth, graphAreaHeight);\n\n // Nome do mês no começo e no final do mês (tamanho reduzido)\n const bottomY = graphAreaTop + graphAreaHeight - 15; // 5px de margem da base\n ctx.fillStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.35)\"\n : \"rgba(100, 116, 139, 0.25)\";\n const monthFont = `bold ${(sizeConfig.fontSize + 4) * 2}px system-ui, -apple-system, sans-serif`;\n\n // Calcula a posição real do dia 1 deste mês\n const firstDayOfMonth = new Date(range.year, range.month, 2);\n const firstDayOfMonthX = dateToX(firstDayOfMonth);\n const isFirstDayOfMonthVisible =\n firstDayOfMonthX >= sizeConfig.padding.left &&\n firstDayOfMonthX <= width - sizeConfig.padding.right;\n\n // Calcula a posição do primeiro dia do próximo mês (que é onde mostraremos o nome do mês atual no final)\n const nextMonthFirstDay = new Date(range.year, range.month + 1, 2);\n const nextMonthFirstDayX = dateToX(nextMonthFirstDay);\n const isNextMonthFirstDayVisible =\n nextMonthFirstDayX >= sizeConfig.padding.left &&\n nextMonthFirstDayX <= width - sizeConfig.padding.right;\n\n // Nome no último dia do mês - alinhado à direita da barra do primeiro dia do próximo mês\n // Mostra o nome do mês atual (ex: NOV) à direita da barra do dia 1 do próximo mês (ex: dia 1 de DEZ)\n if (isNextMonthFirstDayVisible) {\n ctx.save();\n ctx.font = monthFont;\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n ctx.fillText(\n MONTH_NAMES[range.month],\n nextMonthFirstDayX - 4,\n bottomY,\n );\n ctx.restore();\n }\n\n // Nome no primeiro dia do mês - alinhado à esquerda da barra do primeiro dia\n // O texto deve começar logo após a barra vertical (4px de espaçamento)\n if (isFirstDayOfMonthVisible) {\n ctx.save();\n ctx.font = monthFont;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n // A barra está em firstDayOfMonthX, então o texto começa 4px à direita da barra\n ctx.fillText(MONTH_NAMES[range.month], firstDayOfMonthX + 4, bottomY);\n ctx.restore();\n }\n }\n }\n\n // Nomes dos dias da semana\n const DAY_NAMES = [\"DOM\", \"SEG\", \"TER\", \"QUA\", \"QUI\", \"SEX\", \"SAB\"];\n\n // Helper para obter o consumo médio do dia da semana\n const getDailyConsumption = (dayOfWeek: number): number | null => {\n if (!data.timeline.dailyConsumptionAverage) return null;\n\n const dayKeys: (keyof typeof data.timeline.dailyConsumptionAverage)[] = [\n \"0-domingo\",\n \"1-segunda\",\n \"2-terca\",\n \"3-quarta\",\n \"4-quinta\",\n \"5-sexta\",\n \"6-sabado\",\n ];\n\n const key = dayKeys[dayOfWeek];\n return data.timeline.dailyConsumptionAverage[key] ?? null;\n };\n\n // Desenha as linhas verticais e labels dos dias (cada linha na meia-noite do dia civil)\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + i);\n const x = dateToX(date);\n\n if (\n x >= sizeConfig.padding.left &&\n x <= width - sizeConfig.padding.right\n ) {\n // Fins de semana (sábado = 6, domingo = 0)\n const dayOfWeek = date.getDay();\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\n const month = date.getMonth();\n const isFirstDayOfMonth = date.getDate() === 1;\n\n // Borda destacada no primeiro dia do mês\n if (isFirstDayOfMonth) {\n ctx.save();\n ctx.strokeStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.8)\"\n : \"rgba(71, 85, 105, 0.6)\";\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.moveTo(x, barY);\n ctx.lineTo(x, height - sizeConfig.padding.bottom + 20);\n ctx.stroke();\n ctx.restore();\n }\n\n // Linha normal do dia (mesma cor para todos os dias)\n ctx.strokeStyle = COLORS.textSecondary;\n ctx.lineWidth = 1;\n\n ctx.beginPath();\n ctx.moveTo(x, barY);\n ctx.lineTo(x, height - sizeConfig.padding.bottom);\n ctx.stroke();\n\n // Labels de data - mostra TODOS os dias (incluindo Hoje, Entrega, fim do estoque, etc.)\n const labelX = x + pixelsPerDay / 2;\n const baseY = height - sizeConfig.padding.bottom + 8;\n\n // Texto do dia (apenas o número)\n ctx.fillStyle = getDayLabelColor(month, false);\n ctx.font = `${sizeConfig.fontSize}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.fillText(\n date.getDate().toString().padStart(2, \"0\"),\n labelX,\n baseY,\n );\n\n // Consumo médio acima do nome do dia\n const dailyConsumption = getDailyConsumption(dayOfWeek);\n const consumptionValue =\n dailyConsumption !== null ? dailyConsumption : 0;\n ctx.fillStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.7)\"\n : \"rgba(100, 116, 139, 0.7)\";\n ctx.font = `${sizeConfig.fontSize - 3}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"bottom\";\n const consumptionY = height - sizeConfig.padding.bottom - 18;\n ctx.fillText(consumptionValue.toFixed(2), labelX, consumptionY);\n\n // Nome do dia da semana na parte inferior do gráfico\n const dayLabel = DAY_NAMES[dayOfWeek];\n ctx.fillStyle = getDayLabelColor(month, false);\n ctx.font = `${isWeekend ? \"bold \" : \"\"}${\n sizeConfig.fontSize - 2\n }px system-ui, -apple-system, sans-serif`;\n const dayLabelY = height - sizeConfig.padding.bottom - 4;\n ctx.textBaseline = \"bottom\";\n ctx.fillText(dayLabel, labelX, dayLabelY);\n }\n }\n\n // Desenha linha de consumo médio (atrás das barras)\n if (showConsumptionLine && data.timeline.dailyConsumptionAverage) {\n // Calcula o consumo máximo para criar uma escala\n const consumptionValues = Object.values(\n data.timeline.dailyConsumptionAverage,\n ).filter((v): v is number => typeof v === \"number\");\n const maxConsumption =\n consumptionValues.length > 0\n ? Math.max(...consumptionValues, 1) // Mínimo 1 para evitar divisão por zero\n : 1;\n\n // Altura máxima da linha = 50% da altura dos dias (padding.bottom)\n const maxLineHeight = sizeConfig.padding.bottom * 0.5;\n // Área onde a linha será desenhada (alinhada com a parte inferior dos dias)\n // Base: parte inferior dos dias (onde estão os labels)\n const lineAreaBottom = height - sizeConfig.padding.bottom;\n // Topo: 50% da altura dos dias acima da base\n const lineAreaTop = lineAreaBottom - maxLineHeight;\n const lineAreaHeight = maxLineHeight;\n\n // Coleta pontos da linha para cada dia visível\n const linePoints: { x: number; y: number }[] = [];\n\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(startDate);\n date.setDate(date.getDate() + i);\n const x = dateToX(date);\n\n if (\n x >= sizeConfig.padding.left &&\n x <= width - sizeConfig.padding.right\n ) {\n const dayOfWeek = date.getDay();\n const consumption = getDailyConsumption(dayOfWeek) ?? 0;\n\n // Calcula Y baseado no consumo (maior consumo = mais alto na tela)\n // A linha vai de lineAreaBottom (consumo 0) até lineAreaTop (consumo máximo)\n const consumptionRatio = consumption / maxConsumption;\n const y = lineAreaBottom - consumptionRatio * lineAreaHeight;\n\n linePoints.push({ x: x + pixelsPerDay / 2, y });\n }\n }\n\n // Desenha a linha conectando os pontos com quinas arredondadas\n if (linePoints.length > 1) {\n ctx.save();\n ctx.strokeStyle = \"rgba(0, 0, 0, 0.25)\"; // Cor clara e quase transparente\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n ctx.miterLimit = 2;\n\n ctx.beginPath();\n ctx.moveTo(linePoints[0].x, linePoints[0].y);\n\n // Conecta os pontos com linhas (lineJoin=\"round\" cria quinas arredondadas automaticamente)\n for (let i = 1; i < linePoints.length; i++) {\n ctx.lineTo(linePoints[i].x, linePoints[i].y);\n }\n\n ctx.stroke();\n ctx.restore();\n }\n }\n\n // Calcula posição inicial do estoque\n const stockStartX = Math.max(lastRestockX, sizeConfig.padding.left);\n\n // Desenha os segmentos na ordem da esquerda para a direita\n // Cada segmento é desenhado de forma completamente independente\n\n // Desenha os segmentos na ordem da esquerda para a direita\n // Cada segmento define sua cor ANTES de desenhar para garantir cores distintas\n\n // Função auxiliar para criar gradiente vertical\n const createGradient = (color: string, y: number, h: number) => {\n const gradient = ctx.createLinearGradient(0, y, 0, y + h);\n gradient.addColorStop(0, color);\n gradient.addColorStop(1, adjustColorBrightness(color, -15)); // Escurece 15% na base\n return gradient;\n };\n\n // Função auxiliar para criar gradiente horizontal (simulado com vertical)\n const createHorizontalGradient = (color: string, x: number, w: number) => {\n const gradient = ctx.createLinearGradient(x, 0, x + w, 0);\n gradient.addColorStop(0, color);\n gradient.addColorStop(1, adjustColorBrightness(color, -10)); // Levemente mais escuro no final\n return gradient;\n };\n\n // Função auxiliar para desenhar o texto de cada segmento\n // centralizado (horizontal e verticalmente) dentro do próprio segmento,\n // com maior contraste.\n const drawDaysLabelCentered = (\n segmentStartX: number,\n segmentEndX: number,\n segmentTopY: number,\n segmentHeightLocal: number,\n label: string,\n ) => {\n if (!label) return;\n\n const centerX = (segmentStartX + segmentEndX) / 2;\n const centerY = segmentTopY + segmentHeightLocal / 2;\n ctx.textAlign = \"center\";\n\n ctx.font = `${\n sizeConfig.fontSize - 1\n }px system-ui, -apple-system, sans-serif`;\n ctx.fillStyle = \"#FFFFFF\"; // alto contraste\n ctx.textBaseline = \"middle\";\n\n // Sombra para destacar em qualquer cor de fundo\n ctx.shadowColor = \"rgba(0, 0, 0, 0.35)\";\n ctx.shadowBlur = 3;\n ctx.shadowOffsetY = 1;\n\n ctx.fillText(label, centerX, centerY);\n\n // Reset da sombra para não afetar outros desenhos\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n };\n\n // Configurações de estilo comuns\n ctx.lineWidth = 1;\n ctx.lineJoin = \"round\";\n\n // Fim da barra de dias consumidos: no máximo hoje ou o fim do dia final do estoque (23:59)\n const consumedEndDate = new Date(\n Math.min(todayDate.getTime(), stockEndDate.getTime()),\n );\n const consumedEndX = dateToX(consumedEndDate);\n\n // Segmento 1: Último abastecimento até hoje ou fim do estoque (o que vier primeiro) - Cinza escuro\n if (consumedEndX > stockStartX) {\n const segment1Width = consumedEndX - stockStartX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente\n ctx.fillStyle = createGradient(COLORS.stockPast, stockY, segmentHeight);\n ctx.strokeStyle = adjustColorBrightness(COLORS.stockPast, -20); // Borda mais escura\n ctx.lineWidth = 1.5;\n\n // Desenha com canto arredondado apenas na esquerda\n const x = stockStartX;\n const y = stockY;\n const w = segment1Width;\n const h = segmentHeight;\n const r = 6;\n\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w, y); // Lado direito reto\n ctx.lineTo(x + w, y + h); // Lado direito reto\n ctx.lineTo(x + r, y + h);\n ctx.quadraticCurveTo(x, y + h, x, y + h - r);\n ctx.lineTo(x, y + r);\n ctx.quadraticCurveTo(x, y, x + r, y);\n\n ctx.fill();\n ctx.stroke(); // Opcional: desenhar borda\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 1 (abastecimento até hoje ou fim do estoque)\n const daysPast = Math.max(\n 0,\n Math.round(\n (consumedEndDate.getTime() - startDate.getTime()) / MS_PER_DAY,\n ),\n );\n // Label dentro do segmento (perto da base da barra)\n const labelPast = `${daysPast} dia${daysPast === 1 ? \"\" : \"s\"} consumido${\n daysPast === 1 ? \"\" : \"s\"\n }`;\n drawDaysLabelCentered(\n stockStartX,\n consumedEndX,\n stockY,\n segmentHeight,\n labelPast,\n );\n }\n\n // Segmento 2: Hoje até previsão de duração - Laranja\n if (stockEndX > todayX) {\n const segment2Width = stockEndX - todayX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente HORIZONTAL\n ctx.fillStyle = createHorizontalGradient(\n COLORS.stockFuture,\n todayX,\n segment2Width,\n );\n ctx.strokeStyle = adjustColorBrightness(COLORS.stockFuture, -20);\n ctx.lineWidth = 1.5;\n\n // Desenha com canto arredondado apenas na direita\n // E reto na esquerda para conectar perfeitamente com o segmento 1\n const x = todayX;\n const y = stockY;\n const w = segment2Width;\n const h = segmentHeight;\n const r = 6;\n\n ctx.moveTo(x, y); // Lado esquerdo reto\n ctx.lineTo(x + w - r, y);\n ctx.quadraticCurveTo(x + w, y, x + w, y + r);\n ctx.lineTo(x + w, y + h - r);\n ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n ctx.lineTo(x, y + h); // Lado esquerdo reto\n ctx.lineTo(x, y);\n\n ctx.fill();\n ctx.stroke();\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 2 (de hoje até 23:59 do fim do estoque)\n const daysFuture = Math.max(\n 0,\n Math.round((stockEndDate.getTime() - todayDate.getTime()) / MS_PER_DAY),\n );\n // Label dentro do segmento (perto da base da barra)\n const labelFuture = `${daysFuture} dia${\n daysFuture === 1 ? \"\" : \"s\"\n } restante${daysFuture === 1 ? \"\" : \"s\"}`;\n drawDaysLabelCentered(\n todayX,\n stockEndX,\n stockY,\n segmentHeight,\n labelFuture,\n );\n }\n\n // Segmento 3: Sugestão de Compra - Barra amarela (após o fim do estoque)\n const suggestionStartX = Math.max(deliveryStartX, stockEndX);\n if (\n showSuggestionBarEffective &&\n restockEndX > suggestionStartX &&\n suggestionStartX >= sizeConfig.padding.left\n ) {\n const segment3Width = restockEndX - suggestionStartX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente HORIZONTAL\n ctx.fillStyle = createHorizontalGradient(\n COLORS.alert,\n suggestionStartX,\n segment3Width,\n );\n ctx.strokeStyle = adjustColorBrightness(COLORS.alert, -20);\n ctx.lineWidth = 1.5;\n\n // Desenha como um bloco contíguo, mas visualmente separado se houver gap temporal\n // Se suggestionStartX for igual a stockEndX, eles \"tocam\" visualmente se estiverem na mesma altura.\n // Como suggestionY agora é igual a stockY, eles estarão alinhados.\n\n (ctx as any).roundRect(\n suggestionStartX,\n suggestionY,\n segment3Width,\n segmentHeight,\n 6,\n );\n ctx.fill();\n ctx.stroke();\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 3 (janela de sugestão)\n // Calcula baseado na largura visual real da barra, não nas datas originais\n const daysSuggestion = Math.max(\n 0,\n Math.round(segment3Width / pixelsPerDay),\n );\n const labelSuggestion = `${daysSuggestion} dia${\n daysSuggestion === 1 ? \"\" : \"s\"\n }`;\n drawDaysLabelCentered(\n suggestionStartX,\n restockEndX,\n suggestionY,\n segmentHeight,\n labelSuggestion,\n );\n }\n\n // Segmento 4: Barra de quantidade selecionada (selectedQty) - Azul\n // Começa no mesmo ponto da barra de sugestão (max entre entrega e fim do estoque); vai até 23:59 do último dia\n if (\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\"\n ) {\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n\n // Fim da barra às 23:59 do último dia\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n const selectedQtyWidth = selectedQtyEndX - selectedQtyStartX;\n\n if (selectedQtyWidth > 0) {\n // Altura de 50% das outras barras\n const selectedQtyHeight = segmentHeight * 0.5;\n // Posiciona abaixo da barra de sugestão, centralizada verticalmente\n const selectedQtyY = suggestionY + segmentHeight + 4;\n\n ctx.beginPath();\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente horizontal azul\n ctx.fillStyle = createHorizontalGradient(\n (COLORS as any).selectedQtyBar,\n selectedQtyStartX,\n selectedQtyWidth,\n );\n ctx.strokeStyle = adjustColorBrightness(\n (COLORS as any).selectedQtyBar,\n -20,\n );\n ctx.lineWidth = 1.5;\n\n // Desenha com bordas arredondadas\n (ctx as any).roundRect(\n selectedQtyStartX,\n selectedQtyY,\n selectedQtyWidth,\n selectedQtyHeight,\n 4,\n );\n ctx.fill();\n ctx.stroke();\n ctx.closePath();\n }\n }\n\n // Destaque de hover nos segmentos (sombra/overlay suave)\n if (hoverState.isHovering && hoverState.hoveredSection) {\n ctx.save();\n ctx.globalAlpha = 0.18;\n ctx.fillStyle = data.config.theme === \"dark\" ? \"#FFFFFF\" : \"#000000\";\n\n if (hoverState.hoveredSection === \"stock\") {\n // cobre toda a faixa de estoque (passado + futuro)\n ctx.fillRect(\n stockStartX,\n stockY,\n stockEndX - stockStartX,\n segmentHeight,\n );\n } else if (\n hoverState.hoveredSection === \"suggestion\" &&\n showSuggestionBarEffective\n ) {\n ctx.fillRect(\n suggestionStartX,\n suggestionY,\n restockEndX - suggestionStartX,\n segmentHeight,\n );\n } else if (\n hoverState.hoveredSection === \"selectedQty\" &&\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0\n ) {\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n const selectedQtyHeight = segmentHeight * 0.5;\n const selectedQtyY = suggestionY + segmentHeight + 4;\n\n ctx.fillRect(\n selectedQtyStartX,\n selectedQtyY,\n selectedQtyEndX - selectedQtyStartX,\n selectedQtyHeight,\n );\n }\n\n ctx.restore();\n }\n\n // Função auxiliar para desenhar labels estilizados (Pills/Tags)\n const drawModernLabel = (\n x: number,\n y: number,\n text: string,\n bgColor: string,\n ) => {\n ctx.font = `bold ${sizeConfig.pillFontSize}px system-ui, -apple-system, sans-serif`;\n const metrics = ctx.measureText(text.toUpperCase());\n const paddingX = sizeConfig.pillPaddingX;\n const paddingY = sizeConfig.pillPaddingY;\n const pillHeight = sizeConfig.pillHeight;\n const pillWidth = metrics.width + paddingX * 2;\n\n // Sombra suave para o pill\n ctx.shadowColor = \"rgba(0, 0, 0, 0.1)\";\n ctx.shadowBlur = 4;\n ctx.shadowOffsetY = 2;\n\n // Fundo do Pill\n ctx.fillStyle = bgColor;\n ctx.beginPath();\n (ctx as any).roundRect(\n x - pillWidth / 2,\n y,\n pillWidth,\n pillHeight,\n pillHeight / 2,\n );\n ctx.fill();\n\n // Reset de sombra\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n\n // Texto\n ctx.fillStyle = \"#FFFFFF\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text.toUpperCase(), x, y + pillHeight / 2 + 1); // +1 para ajuste ótico\n };\n\n // Desenha a coluna inteira do \"Hoje\" com fundo diferente + label centralizada\n if (\n todayX >= sizeConfig.padding.left &&\n todayX <= width - sizeConfig.padding.right\n ) {\n const todayColumnLeft = todayX;\n const todayColumnWidth = pixelsPerDay;\n const graphTop = barY;\n const graphBottom = height - sizeConfig.padding.bottom;\n\n // Fundo da coluna (toda a altura do gráfico)\n ctx.globalAlpha = 0.12;\n ctx.fillStyle = COLORS.todayIndicator;\n ctx.fillRect(todayColumnLeft, graphTop, todayColumnWidth, graphBottom - graphTop);\n ctx.globalAlpha = 1.0;\n\n // Linha sutil na borda esquerda da coluna\n ctx.strokeStyle = COLORS.todayIndicator;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n ctx.moveTo(todayColumnLeft, graphTop);\n ctx.lineTo(todayColumnLeft, graphBottom);\n ctx.stroke();\n\n // Label \"Hoje\" centralizada na coluna\n const todayLabelX = todayColumnLeft + todayColumnWidth / 2;\n drawModernLabel(\n todayLabelX,\n height - sizeConfig.padding.bottom + 20,\n \"Hoje\",\n COLORS.todayIndicator,\n );\n }\n\n // Desenha a linha vertical fina do dia da entrega\n if (\n deliveryStartX >= sizeConfig.padding.left &&\n deliveryStartX <= width - sizeConfig.padding.right\n ) {\n ctx.globalAlpha = 1.0;\n ctx.strokeStyle = COLORS.deliveryBar; // Verde escuro\n ctx.lineWidth = 1.5; // Um pouco mais grossa para a linha tracejada\n ctx.setLineDash([3, 3]); // Tracejado mais denso e técnico\n\n ctx.beginPath();\n ctx.moveTo(deliveryStartX, 0);\n ctx.lineTo(deliveryStartX, height - sizeConfig.padding.bottom);\n ctx.stroke();\n ctx.setLineDash([]); // Remove o tracejado\n\n // Label moderna\n drawModernLabel(\n deliveryStartX,\n height - sizeConfig.padding.bottom + 20,\n \"Entrega\",\n COLORS.deliveryBar,\n );\n }\n\n // Desenha o ícone de alerta no dia em que a sugestão começa (apenas se a barra amarela estiver visível)\n if (showSuggestionBarEffective) {\n const alertIconSize = sizeConfig.fontSize + 6;\n const alertIconX =\n suggestionStartX + pixelsPerDay / 2 - alertIconSize / 2;\n const alertIconY = suggestionY - alertIconSize - 4;\n\n // Cor do ícone baseada no status do alerta\n const alertIconColor =\n alertInfo.status === \"critical\"\n ? (COLORS as any).alertCritical\n : alertInfo.status === \"urgent\"\n ? (COLORS as any).alertUrgent\n : alertInfo.status === \"warning\"\n ? (COLORS as any).alertWarning\n : alertInfo.status === \"success\"\n ? (COLORS as any).alertSuccess\n : (COLORS as any).alertInfo;\n\n // Desenha círculo de fundo\n ctx.beginPath();\n ctx.arc(\n alertIconX + alertIconSize / 2,\n alertIconY + alertIconSize / 2,\n alertIconSize / 2,\n 0,\n Math.PI * 2,\n );\n ctx.fillStyle = alertIconColor;\n ctx.fill();\n\n // Sombra suave\n ctx.shadowColor = \"rgba(0, 0, 0, 0.2)\";\n ctx.shadowBlur = 4;\n ctx.shadowOffsetY = 2;\n\n // Desenha o símbolo dentro do círculo\n ctx.fillStyle = \"#FFFFFF\";\n ctx.font = `bold ${alertIconSize * 0.6}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n const iconSymbol =\n alertInfo.status === \"critical\"\n ? \"!\"\n : alertInfo.status === \"urgent\"\n ? \"!\"\n : alertInfo.status === \"warning\"\n ? \"!\"\n : alertInfo.status === \"success\"\n ? \"✓\"\n : \"i\";\n\n ctx.fillText(\n iconSymbol,\n alertIconX + alertIconSize / 2,\n alertIconY + alertIconSize / 2,\n );\n\n // Reset sombra\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Reset global alpha\n ctx.globalAlpha = 1.0;\n }, [\n data,\n dateToX,\n startDate,\n todayDate,\n stockEndDate,\n restockStart,\n restockEnd,\n deliveryDate,\n COLORS,\n sizeConfig,\n hoverState,\n MS_PER_DAY,\n pixelsPerDay,\n selectedQty,\n selectedQtyDays,\n alertInfo,\n showConsumptionLine,\n showSuggestionBarEffective,\n ]);\n\n // Detecta qual seção está sendo hovered\n const getHoveredSection = useCallback(\n (\n clientX: number,\n clientY: number,\n ):\n | \"stock\"\n | \"delivery\"\n | \"suggestion\"\n | \"selectedQty\"\n | \"alertIcon\"\n | null => {\n const canvas = canvasRef.current;\n if (!canvas) return null;\n\n const rect = canvas.getBoundingClientRect();\n const relativeX = clientX - rect.left;\n const relativeY = clientY - rect.top;\n\n const barY = sizeConfig.padding.top;\n const fullHeight =\n sizeConfig.height - sizeConfig.padding.top - sizeConfig.padding.bottom;\n const segmentHeight = fullHeight * sizeConfig.segmentRatio;\n\n const stockY = barY + 5;\n // Mantém o mesmo Y usado no desenho do segmento de sugestão\n const suggestionY = stockY + segmentHeight + 2;\n // Y da barra de quantidade selecionada (50% da altura)\n const selectedQtyY = suggestionY + segmentHeight + 4;\n const selectedQtyHeight = segmentHeight * 0.5;\n\n const lastRestockX = dateToX(startDate);\n const todayX = dateToX(todayDate);\n const stockEndX = dateToX(stockEndDate);\n const deliveryStartX = dateToX(deliveryDate);\n const restockEndX = dateToX(restockEnd);\n const suggestionStartX = Math.max(deliveryStartX, stockEndX);\n\n // Check alert icon first (está no dia em que a sugestão começa) - só se a barra amarela estiver visível\n if (showSuggestionBarEffective) {\n const alertIconSize = sizeConfig.fontSize + 6;\n const alertIconX =\n suggestionStartX + pixelsPerDay / 2 - alertIconSize / 2;\n const alertIconY = suggestionY - alertIconSize - 4;\n\n const distanceToAlertIcon = Math.sqrt(\n Math.pow(relativeX - (alertIconX + alertIconSize / 2), 2) +\n Math.pow(relativeY - (alertIconY + alertIconSize / 2), 2),\n );\n\n if (distanceToAlertIcon <= alertIconSize / 2 + 4) {\n return \"alertIcon\";\n }\n }\n\n if (\n relativeY < barY ||\n relativeY > barY + fullHeight + selectedQtyHeight + 10\n )\n return null;\n\n // Check selectedQty row (verifica primeiro pois está mais abaixo)\n if (\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\"\n ) {\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n\n if (\n relativeY >= selectedQtyY &&\n relativeY <= selectedQtyY + selectedQtyHeight &&\n relativeX >= selectedQtyStartX &&\n relativeX <= selectedQtyEndX\n ) {\n return \"selectedQty\";\n }\n }\n\n // Check stock row\n if (\n relativeY >= stockY &&\n relativeY <= stockY + segmentHeight &&\n relativeX >= lastRestockX &&\n relativeX <= stockEndX\n ) {\n return \"stock\";\n }\n\n // Check suggestion row (só se a barra amarela estiver visível)\n if (\n showSuggestionBarEffective &&\n relativeY >= suggestionY &&\n relativeY <= suggestionY + segmentHeight &&\n relativeX >= suggestionStartX &&\n relativeX <= restockEndX\n ) {\n return \"suggestion\";\n }\n\n return null;\n },\n [\n dateToX,\n todayDate,\n stockEndDate,\n restockEnd,\n startDate,\n deliveryDate,\n sizeConfig,\n selectedQty,\n selectedQtyDays,\n pixelsPerDay,\n MS_PER_DAY,\n showSuggestionBarEffective,\n ],\n );\n\n // Calcula a largura total do conteúdo e o máximo de scroll (barras até 23:59)\n const endDateCalc = useMemo(() => {\n let maxTime = Math.max(\n restockEnd.getTime(),\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n );\n\n if (typeof selectedQtyDays === \"number\" && selectedQtyDays > 0) {\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n maxTime = Math.max(maxTime, selectedQtyEndDate.getTime());\n }\n\n const end = new Date(maxTime);\n end.setDate(end.getDate() + 2); // Buffer de 2 dias\n return end;\n }, [restockEnd, deliveryDate, stockEndDate, selectedQtyDays, MS_PER_DAY]);\n\n const totalDaysCalc = useMemo(() => {\n return Math.ceil(\n (endDateCalc.getTime() - startDate.getTime()) / MS_PER_DAY,\n );\n }, [endDateCalc, startDate, MS_PER_DAY]);\n\n const totalContentWidth = useMemo(() => {\n return (\n sizeConfig.padding.left +\n totalDaysCalc * pixelsPerDay +\n sizeConfig.padding.right\n );\n }, [\n totalDaysCalc,\n pixelsPerDay,\n sizeConfig.padding.left,\n sizeConfig.padding.right,\n ]);\n\n // Estado para a largura visível do canvas\n const [canvasWidth, setCanvasWidth] = useState(0);\n\n // Atualiza a largura do canvas quando o container é redimensionado\n useEffect(() => {\n const updateCanvasWidth = () => {\n if (canvasRef.current) {\n setCanvasWidth(canvasRef.current.getBoundingClientRect().width);\n }\n };\n updateCanvasWidth();\n window.addEventListener(\"resize\", updateCanvasWidth);\n return () => window.removeEventListener(\"resize\", updateCanvasWidth);\n }, []);\n\n const maxScrollOffset = useMemo(() => {\n if (canvasWidth === 0) return 0;\n return Math.max(0, totalContentWidth - canvasWidth);\n }, [totalContentWidth, canvasWidth]);\n\n // Ref da barra de scroll (para calcular posição no arraste do thumb)\n const scrollTrackRef = useRef<HTMLDivElement>(null);\n\n // Estado para drag (arrastar o canvas)\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const dragStartXRef = useRef(0);\n const dragStartOffsetRef = useRef(0);\n\n // Estado para drag do thumb da barra de scroll\n const [isScrollBarDragging, setIsScrollBarDragging] = useState(false);\n const isScrollBarDraggingRef = useRef(false);\n\n // Handler de mousedown para iniciar drag\n const handleMouseDown = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n e.preventDefault();\n isDraggingRef.current = true;\n setIsDragging(true);\n dragStartXRef.current = e.clientX;\n dragStartOffsetRef.current = scrollOffset;\n },\n [scrollOffset],\n );\n\n // Handler de touchstart para iniciar drag em mobile\n const handleTouchStart = useCallback(\n (e: React.TouchEvent<HTMLCanvasElement>) => {\n if (e.touches.length === 1) {\n e.preventDefault();\n isDraggingRef.current = true;\n setIsDragging(true);\n dragStartXRef.current = e.touches[0].clientX;\n dragStartOffsetRef.current = scrollOffset;\n }\n },\n [scrollOffset],\n );\n\n // Handlers de mouse (usa ref para drag responder no primeiro mousemove, sem depender do re-render)\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n // Se estiver arrastando, atualiza o scroll offset\n if (isDraggingRef.current && maxScrollOffset > 0) {\n const deltaX = dragStartXRef.current - e.clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n return; // Não atualiza hover durante drag\n }\n\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n\n const hoveredSection = getHoveredSection(e.clientX, e.clientY);\n const dateAtCursor = xToDate(x);\n\n setHoverState({\n isHovering: true,\n hoveredSection,\n mouseX: e.clientX,\n mouseY: e.clientY,\n dateAtCursor,\n });\n\n setTooltipPosition({ x: e.clientX, y: e.clientY });\n },\n [getHoveredSection, xToDate, maxScrollOffset],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHoverState({\n isHovering: false,\n hoveredSection: null,\n mouseX: 0,\n mouseY: 0,\n dateAtCursor: null,\n });\n }, []);\n\n // Handler de mouseup para finalizar drag\n const handleMouseUp = useCallback(() => {\n isDraggingRef.current = false;\n setIsDragging(false);\n }, []);\n\n // Handler de touchmove para drag em mobile\n const handleTouchMove = useCallback(\n (e: React.TouchEvent<HTMLCanvasElement>) => {\n if (e.touches.length === 1 && isDraggingRef.current && maxScrollOffset > 0) {\n e.preventDefault();\n const deltaX = dragStartXRef.current - e.touches[0].clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n },\n [maxScrollOffset],\n );\n\n // Handler de touchend para finalizar drag em mobile\n const handleTouchEnd = useCallback(() => {\n isDraggingRef.current = false;\n setIsDragging(false);\n }, []);\n\n // Efeito para adicionar listeners globais de mousemove e mouseup (para drag fora do canvas)\n useEffect(() => {\n const handleGlobalMouseMove = (e: MouseEvent) => {\n if (isDraggingRef.current && maxScrollOffset > 0) {\n const deltaX = dragStartXRef.current - e.clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n };\n\n const handleGlobalMouseUp = () => {\n isDraggingRef.current = false;\n setIsDragging(false);\n };\n\n const handleGlobalTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 1 && isDraggingRef.current && maxScrollOffset > 0) {\n e.preventDefault();\n const deltaX = dragStartXRef.current - e.touches[0].clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n };\n\n const handleGlobalTouchEnd = () => {\n isDraggingRef.current = false;\n setIsDragging(false);\n };\n\n if (isDragging) {\n window.addEventListener(\"mousemove\", handleGlobalMouseMove);\n window.addEventListener(\"mouseup\", handleGlobalMouseUp);\n window.addEventListener(\"touchmove\", handleGlobalTouchMove, {\n passive: false,\n });\n window.addEventListener(\"touchend\", handleGlobalTouchEnd);\n }\n\n return () => {\n window.removeEventListener(\"mousemove\", handleGlobalMouseMove);\n window.removeEventListener(\"mouseup\", handleGlobalMouseUp);\n window.removeEventListener(\"touchmove\", handleGlobalTouchMove);\n window.removeEventListener(\"touchend\", handleGlobalTouchEnd);\n };\n }, [isDragging, maxScrollOffset]);\n\n // Atualiza scroll ao arrastar o thumb da barra (thumb segue o mouse e timeline atualiza)\n const updateScrollFromScrollBarMouse = useCallback(\n (clientX: number) => {\n const track = scrollTrackRef.current;\n if (!track || maxScrollOffset <= 0) return;\n const rect = track.getBoundingClientRect();\n const trackWidth = rect.width;\n const thumbWidthPx = (canvasWidth / totalContentWidth) * trackWidth;\n const range = trackWidth - thumbWidthPx;\n if (range <= 0) return;\n const mouseXInTrack = clientX - rect.left;\n const thumbLeft = mouseXInTrack - thumbWidthPx / 2;\n const percentage = Math.max(0, Math.min(1, thumbLeft / range));\n setScrollOffset(percentage * maxScrollOffset);\n },\n [maxScrollOffset, canvasWidth, totalContentWidth],\n );\n\n const handleScrollBarThumbMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n isScrollBarDraggingRef.current = true;\n setIsScrollBarDragging(true);\n },\n [],\n );\n\n const handleScrollBarThumbTouchStart = useCallback(\n (e: React.TouchEvent) => {\n e.stopPropagation();\n if (e.touches.length === 1) {\n isScrollBarDraggingRef.current = true;\n setIsScrollBarDragging(true);\n }\n },\n [],\n );\n\n useEffect(() => {\n const handleGlobalMouseMove = (e: MouseEvent) => {\n if (isScrollBarDraggingRef.current) {\n updateScrollFromScrollBarMouse(e.clientX);\n }\n };\n const handleGlobalMouseUp = () => {\n isScrollBarDraggingRef.current = false;\n setIsScrollBarDragging(false);\n };\n const handleGlobalTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 1 && isScrollBarDraggingRef.current) {\n e.preventDefault();\n updateScrollFromScrollBarMouse(e.touches[0].clientX);\n }\n };\n const handleGlobalTouchEnd = () => {\n isScrollBarDraggingRef.current = false;\n setIsScrollBarDragging(false);\n };\n\n if (isScrollBarDragging) {\n window.addEventListener(\"mousemove\", handleGlobalMouseMove);\n window.addEventListener(\"mouseup\", handleGlobalMouseUp);\n window.addEventListener(\"touchmove\", handleGlobalTouchMove, {\n passive: false,\n });\n window.addEventListener(\"touchend\", handleGlobalTouchEnd);\n }\n return () => {\n window.removeEventListener(\"mousemove\", handleGlobalMouseMove);\n window.removeEventListener(\"mouseup\", handleGlobalMouseUp);\n window.removeEventListener(\"touchmove\", handleGlobalTouchMove);\n window.removeEventListener(\"touchend\", handleGlobalTouchEnd);\n };\n }, [isScrollBarDragging, updateScrollFromScrollBarMouse]);\n\n // Redesenha quando necessário\n useEffect(() => {\n drawCanvas();\n }, [drawCanvas]);\n\n // Redesenha quando a janela é redimensionada ou o container muda de tamanho\n useEffect(() => {\n const handleResize = () => {\n drawCanvas();\n };\n\n window.addEventListener(\"resize\", handleResize);\n\n // Observa mudanças no tamanho do container\n const resizeObserver = new ResizeObserver(() => {\n drawCanvas();\n });\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current);\n }\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n resizeObserver.disconnect();\n };\n }, [drawCanvas]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n position: \"relative\",\n width: \"100%\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n touchAction: \"pan-x pan-y\", // Permite gestos de pan (scroll) em mobile\n ...style,\n }}\n >\n {/* Controles acima do gráfico (não sobrepõem os dias) */}\n {controls && (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: size === \"sm\" ? 6 : 8,\n paddingBottom: 8,\n paddingRight: sizeConfig.padding.right,\n }}\n >\n <button\n type=\"button\"\n onClick={() => setZoomLevelIndex((prev) => Math.max(0, prev - 1))}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background:\n data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 16 : 18,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n >\n -\n </button>\n <button\n type=\"button\"\n onClick={() =>\n setZoomLevelIndex((prev) =>\n Math.min(ZOOM_LEVELS.length - 1, prev + 1),\n )\n }\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background:\n data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 16 : 18,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n >\n +\n </button>\n {/* Botão para mostrar/esconder barra amarela (Sugestão de Compra) */}\n <button\n type=\"button\"\n onClick={() => setSuggestionBarVisible((prev) => !prev)}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background: showSuggestionBarEffective\n ? data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\"\n : data.config.theme === \"dark\"\n ? \"rgba(0,0,0,0.7)\"\n : \"rgba(0,0,0,0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 14 : 16,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n color: showSuggestionBarEffective\n ? data.config.theme === \"dark\"\n ? \"#ECEFF1\"\n : \"#263238\"\n : \"#FFFFFF\",\n fontWeight: \"bold\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n title={\n showSuggestionBarEffective\n ? \"Ocultar barra de sugestão de compra\"\n : \"Mostrar barra de sugestão de compra\"\n }\n >\n S\n </button>\n {/* Botão para mostrar/esconder linha de consumo médio */}\n {data.timeline.dailyConsumptionAverage && (\n <button\n type=\"button\"\n onClick={() => setShowConsumptionLine((prev) => !prev)}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background: showConsumptionLine\n ? data.config.theme === \"dark\"\n ? \"rgba(0,0,0,0.7)\"\n : \"rgba(0,0,0,0.5)\"\n : data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 14 : 16,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n color: showConsumptionLine\n ? \"#FFFFFF\"\n : data.config.theme === \"dark\"\n ? \"#ECEFF1\"\n : \"#263238\",\n fontWeight: \"bold\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n title={\n showConsumptionLine\n ? \"Ocultar linha de consumo\"\n : \"Mostrar linha de consumo\"\n }\n >\n C\n </button>\n )}\n </div>\n )}\n\n {/* Área do gráfico / canvas */}\n <div\n style={{\n position: \"relative\",\n width: \"100%\",\n minHeight:\n maxScrollOffset > 0 ? sizeConfig.height + 8 + 15 : sizeConfig.height,\n }}\n >\n <canvas\n ref={canvasRef}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n style={{\n width: \"100%\",\n height: `${sizeConfig.height}px`,\n display: \"block\",\n cursor:\n maxScrollOffset > 0\n ? isDragging\n ? \"grabbing\"\n : \"grab\"\n : \"pointer\",\n touchAction: \"pan-x\",\n }}\n />\n\n {/* Barra de scroll horizontal (abaixo do canvas para não sobrepor os dias) */}\n {maxScrollOffset > 0 && (\n <div\n ref={scrollTrackRef}\n style={{\n position: \"absolute\",\n top: sizeConfig.height + 8,\n left: 0,\n right: 0,\n height: 15,\n backgroundColor:\n data.config.theme === \"dark\"\n ? \"rgba(255,255,255,0.1)\"\n : \"rgba(0,0,0,0.1)\",\n borderRadius: 7.5,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n onClick={(e) => {\n if (e.target !== e.currentTarget) return;\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const percentage = clickX / rect.width;\n setScrollOffset(percentage * maxScrollOffset);\n }}\n >\n <div\n role=\"slider\"\n aria-valuenow={scrollOffset}\n aria-valuemin={0}\n aria-valuemax={maxScrollOffset}\n onMouseDown={handleScrollBarThumbMouseDown}\n onTouchStart={handleScrollBarThumbTouchStart}\n style={{\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: `${Math.max(10, (canvasWidth / totalContentWidth) * 100)}%`,\n left: `${\n maxScrollOffset > 0\n ? (scrollOffset / maxScrollOffset) *\n (100 - Math.max(10, (canvasWidth / totalContentWidth) * 100))\n : 0\n }%`,\n maxWidth: \"100%\",\n height: 9,\n backgroundColor:\n data.config.theme === \"dark\"\n ? \"rgba(255,255,255,0.4)\"\n : \"rgba(0,0,0,0.3)\",\n borderRadius: 4.5,\n cursor: isScrollBarDragging ? \"grabbing\" : \"grab\",\n transition:\n isDragging || isScrollBarDragging ? \"none\" : \"left 0.1s ease-out\",\n }}\n />\n </div>\n )}\n </div>\n {hoverState.isHovering &&\n (hoverState.dateAtCursor ||\n hoverState.hoveredSection === \"alertIcon\") &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div\n style={{\n position: \"fixed\",\n left: `${tooltipPosition.x}px`,\n top: `${tooltipPosition.y}px`,\n backgroundColor: COLORS.tooltipBackground,\n color: COLORS.tooltipText,\n padding: \"6px 10px\",\n borderRadius: \"6px\",\n fontSize: \"10px\",\n pointerEvents: \"none\",\n zIndex: 10000,\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.2)\",\n transform: \"translate(-50%, calc(-100% - 10px))\",\n whiteSpace: \"nowrap\",\n }}\n >\n {hoverState.hoveredSection === \"alertIcon\" ? (\n <>\n <div style={{ fontWeight: \"bold\", marginBottom: \"4px\" }}>\n {alertInfo.title}\n </div>\n <div>{alertInfo.message}</div>\n </>\n ) : (\n <>\n <div style={{ fontWeight: \"bold\", marginBottom: \"4px\" }}>\n {hoverState.dateAtCursor &&\n formatDate(hoverState.dateAtCursor)}\n </div>\n {hoverState.dateAtCursor && !hoverState.hoveredSection && (\n <>\n <div style={{ marginBottom: 2 }}>\n {DAY_NAMES[hoverState.dateAtCursor.getDay()]}\n </div>\n <div>\n Consumo médio:{\" \"}\n {(() => {\n const dayOfWeek = hoverState.dateAtCursor.getDay();\n const consumption = getDailyConsumption(dayOfWeek);\n return consumption !== null\n ? `${consumption.toFixed(2)}`\n : \"0.0\";\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"stock\" && (\n <>\n <div style={{ marginBottom: 2 }}>\n {formatDateTime(startDate)} — {formatDateTime(stockEndDate)}\n </div>\n <div>Estoque disponível até {formatDateTime(stockEndDate)}</div>\n <div style={{ marginTop: 2 }}>\n {(() => {\n const totalStockDays = Math.max(\n 0,\n Math.round(\n (stockEndDate.getTime() - startDate.getTime()) /\n MS_PER_DAY,\n ),\n );\n const weight =\n data.timeline.stockWeightKg ??\n data.timeline.restockSuggestionWeight;\n return `${totalStockDays} dia(s) de estoque${\n weight ? ` • ${weight} ${unitLabel}` : \"\"\n }`;\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"suggestion\" && (\n <>\n <div style={{ marginBottom: 2 }}>\n {(() => {\n const suggestionStartDate = new Date(\n Math.max(\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n ),\n );\n return `${formatDateTime(suggestionStartDate)} — ${formatDateTime(restockEnd)}`;\n })()}\n </div>\n <div>Período crítico para compra</div>\n <div style={{ marginTop: 2 }}>\n {(() => {\n const suggestionStartDate = new Date(\n Math.max(\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n ),\n );\n const suggestionDays = Math.max(\n 0,\n Math.round(\n (restockEnd.getTime() -\n suggestionStartDate.getTime()) /\n MS_PER_DAY,\n ),\n );\n const weight = data.timeline.restockSuggestionWeight;\n return `${suggestionDays} dia(s) de sugestão${\n weight ? ` • ${weight} ${unitLabel}` : \"\"\n }`;\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"selectedQty\" &&\n typeof selectedQty === \"number\" &&\n typeof selectedQtyDays === \"number\" && (\n <div>\n O estoque selecionado de {selectedQty} deve durar{\" \"}\n {selectedQtyDays % 1 === 0\n ? selectedQtyDays\n : selectedQtyDays.toFixed(1)}{\" \"}\n dia{selectedQtyDays === 1 ? \"\" : \"s\"}\n </div>\n )}\n </>\n )}\n </div>,\n document.body,\n )}\n {showLegend && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n justifyContent: \"flex-end\",\n gap: \"8px\",\n backgroundColor: COLORS.legendBackground,\n padding: \"8px 10px\",\n marginTop: \"8px\",\n borderRadius: \"4px\",\n fontSize: \"10px\",\n color: COLORS.textPrimary,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.stockPast,\n borderRadius: \"2px\",\n }}\n />\n <span>Estoque Passado</span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.stockFuture,\n borderRadius: \"2px\",\n }}\n />\n <span>Previsão Estoque</span>\n </div>\n {showSuggestionBarEffective && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.alert,\n borderRadius: \"2px\",\n }}\n />\n <span>Sugestão Compra</span>\n </div>\n )}\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"2px\",\n height: \"10px\",\n borderLeft: `2px dashed ${COLORS.deliveryBar}`,\n marginLeft: \"4px\",\n marginRight: \"4px\",\n }}\n />\n <span>Data Entrega</span>\n </div>\n {typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\" && (\n <div\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <div\n style={{\n width: \"10px\",\n height: \"5px\",\n backgroundColor: (COLORS as any).selectedQtyBar,\n borderRadius: \"2px\",\n }}\n />\n <span>Qtd. Selecionada</span>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// Re-exporta os tipos para uso externo\nexport type {\n StockLeadTimeProps,\n TimelineData,\n HoverState,\n Point,\n} from \"./types\";\n"],"names":["THEME_COLORS","SIZE_CONFIG","ensureRoundRect","ctx","x","y","w","h","r","adjustColorBrightness","hex","percent","num","amt","R","G","B","parseDateLocal","dateStr","parts","parseDateTimeLocal","datePart","timePart","date","m","sMs","hour","min","s","ms","parseDateTimeLocalEnd","getEndOfDay","d","eod","getStockAlert","timeline","today","stockEnd","delivery","suggestStart","suggestEnd","daysLate","daysMargin","StockLeadTime","data","className","style","controls","showLegend","size","selectedQty","selectedQtyDays","showSuggestionBarProp","unitLabel","sizeConfig","useMemo","COLORS","alertInfo","DAY_NAMES","getDailyConsumption","useCallback","dayOfWeek","key","canvasRef","useRef","containerRef","hoverState","setHoverState","useState","tooltipPosition","setTooltipPosition","ZOOM_LEVELS","zoomLevelIndex","setZoomLevelIndex","scrollOffset","setScrollOffset","showConsumptionLine","setShowConsumptionLine","suggestionBarVisible","setSuggestionBarVisible","showSuggestionBarEffective","useEffect","startDate","todayDate","stockEndDate","restockStart","restockEnd","deliveryDate","MS_PER_DAY","pixelsPerDay","dateToX","daysDiff","xToDate","daysFromStart","formatDate","formatDateTime","drawCanvas","canvas","dpr","width","height","hoverX","isDark","graphTop","graphHeight","lastRestockX","todayX","stockEndX","deliveryStartX","restockEndX","barY","segmentHeight","stockY","suggestionY","maxTime","selectedQtyStartDateCalc","lastDayOfSelected","selectedQtyEndDateCalc","endDate","totalDays","MONTH_NAMES","getMonthBackgroundColor","monthIndex","isEvenMonth","getDayLabelColor","isWeekend","monthRanges","currentMonth","currentYear","monthStartX","i","month","year","lastDate","graphAreaTop","graphAreaHeight","range","bgStartX","bgWidth","bottomY","monthFont","firstDayOfMonth","firstDayOfMonthX","isFirstDayOfMonthVisible","nextMonthFirstDay","nextMonthFirstDayX","labelX","baseY","dailyConsumption","consumptionValue","consumptionY","dayLabel","dayLabelY","consumptionValues","v","maxConsumption","maxLineHeight","lineAreaBottom","lineAreaHeight","linePoints","consumptionRatio","stockStartX","createGradient","color","gradient","createHorizontalGradient","drawDaysLabelCentered","segmentStartX","segmentEndX","segmentTopY","segmentHeightLocal","label","centerX","centerY","consumedEndDate","consumedEndX","segment1Width","daysPast","labelPast","segment2Width","daysFuture","labelFuture","suggestionStartX","segment3Width","daysSuggestion","labelSuggestion","selectedQtyStartDate","selectedQtyStartX","selectedQtyEndDate","selectedQtyWidth","selectedQtyHeight","selectedQtyY","selectedQtyEndX","drawModernLabel","text","bgColor","metrics","paddingX","pillHeight","pillWidth","todayColumnLeft","todayColumnWidth","graphBottom","todayLabelX","alertIconSize","alertIconX","alertIconY","alertIconColor","iconSymbol","getHoveredSection","clientX","clientY","rect","relativeX","relativeY","fullHeight","endDateCalc","end","totalDaysCalc","totalContentWidth","canvasWidth","setCanvasWidth","updateCanvasWidth","maxScrollOffset","scrollTrackRef","isDragging","setIsDragging","isDraggingRef","dragStartXRef","dragStartOffsetRef","isScrollBarDragging","setIsScrollBarDragging","isScrollBarDraggingRef","handleMouseDown","handleTouchStart","handleMouseMove","deltaX","newOffset","hoveredSection","dateAtCursor","handleMouseLeave","handleMouseUp","handleTouchMove","handleTouchEnd","handleGlobalMouseMove","e","handleGlobalMouseUp","handleGlobalTouchMove","handleGlobalTouchEnd","updateScrollFromScrollBarMouse","track","trackWidth","thumbWidthPx","thumbLeft","percentage","handleScrollBarThumbMouseDown","handleScrollBarThumbTouchStart","handleResize","resizeObserver","jsxs","jsx","prev","createPortal","Fragment","consumption","totalStockDays","weight","suggestionStartDate","suggestionDays"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index18.js","sources":["../src/components/StockLeadTime/index.tsx"],"sourcesContent":["import { HoverState, Point, StockLeadTimeProps, TimelineData } from \"./types\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\n// Paleta de cores por tema\nconst THEME_COLORS = {\n light: {\n stockSafe: \"#00E676\",\n stockPast: \"#c4ccd0\",\n stockFuture: \"#349d50\",\n alert: \"#f9f198\",\n todayIndicator: \"#2979FF\",\n textPrimary: \"#37474F\",\n textSecondary: \"#90A4AE\",\n background: \"#F5F5F5\",\n deliveryBar: \"#0d0f0d\",\n legendBackground: \"rgba(255, 255, 255, 0.8)\",\n tooltipBackground: \"#37474F\",\n tooltipText: \"#FFFFFF\",\n alertCritical: \"#D32F2F\",\n alertUrgent: \"#F57C00\",\n alertWarning: \"#FBC02D\",\n alertSuccess: \"#388E3C\",\n alertInfo: \"#0288D1\",\n selectedQtyBar: \"#2196F3\", // Azul para barra de quantidade selecionada\n },\n dark: {\n stockSafe: \"#00E676\",\n stockPast: \"#455A64\", // Cinza azulado escuro\n stockFuture: \"#43A047\", // Verde ligeiramente mais vibrante\n alert: \"#FDD835\", // Amarelo mais forte\n todayIndicator: \"#448AFF\",\n textPrimary: \"#ECEFF1\", // Quase branco\n textSecondary: \"#B0BEC5\", // Cinza claro\n background: \"#263238\", // Azul acinzentado bem escuro\n deliveryBar: \"#FFFFFF\",\n legendBackground: \"rgba(38, 50, 56, 0.9)\",\n tooltipBackground: \"#ECEFF1\",\n tooltipText: \"#263238\",\n alertCritical: \"#EF5350\",\n alertUrgent: \"#FFA726\",\n alertWarning: \"#FFEE58\",\n alertSuccess: \"#66BB6A\",\n alertInfo: \"#29B6F6\",\n selectedQtyBar: \"#42A5F5\", // Azul mais claro para tema escuro\n },\n};\n\nconst SIZE_CONFIG = {\n sm: {\n height: 170,\n segmentRatio: 0.2,\n fontSize: 10,\n padding: {\n top: 25,\n bottom: 40,\n left: 8,\n right: 8,\n },\n pillHeight: 14,\n pillPaddingX: 4,\n pillPaddingY: 2,\n pillFontSize: 8,\n },\n md: {\n height: 220,\n segmentRatio: 0.22,\n fontSize: 12,\n padding: {\n top: 30,\n bottom: 50,\n left: 10,\n right: 10,\n },\n pillHeight: 16,\n pillPaddingX: 6,\n pillPaddingY: 3,\n pillFontSize: 9,\n },\n lg: {\n height: 270,\n segmentRatio: 0.25,\n fontSize: 14,\n padding: {\n top: 35,\n bottom: 60,\n left: 12,\n right: 12,\n },\n pillHeight: 20,\n pillPaddingX: 8,\n pillPaddingY: 4,\n pillFontSize: 11,\n },\n};\n\n// Polyfill para roundRect (caso não esteja disponível)\nconst ensureRoundRect = (ctx: CanvasRenderingContext2D) => {\n if (!(ctx as any).roundRect) {\n (ctx as any).roundRect = function (\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n ) {\n if (w < 2 * r) r = w / 2;\n if (h < 2 * r) r = h / 2;\n this.beginPath();\n this.moveTo(x + r, y);\n this.arcTo(x + w, y, x + w, y + h, r);\n this.arcTo(x + w, y + h, x, y + h, r);\n this.arcTo(x, y + h, x, y, r);\n this.arcTo(x, y, x + w, y, r);\n this.closePath();\n };\n }\n};\n\n// Helper para ajustar brilho de cores Hex\nconst adjustColorBrightness = (hex: string, percent: number) => {\n const num = parseInt(hex.replace(\"#\", \"\"), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) + amt;\n const G = ((num >> 8) & 0x00ff) + amt;\n const B = (num & 0x0000ff) + amt;\n return (\n \"#\" +\n (\n 0x1000000 +\n (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +\n (G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +\n (B < 255 ? (B < 1 ? 0 : B) : 255)\n )\n .toString(16)\n .slice(1)\n );\n};\n\ntype AlertStatus = \"critical\" | \"urgent\" | \"warning\" | \"success\" | \"info\";\n\ninterface StockAlertInfo {\n status: AlertStatus;\n title: string;\n message: string;\n}\n\n/** Interpreta \"YYYY-MM-DD\" como meia-noite no fuso local. */\nfunction parseDateLocal(dateStr: string): Date {\n const parts = dateStr.split(\"-\").map(Number);\n if (parts.length !== 3 || parts.some(Number.isNaN)) return new Date(NaN);\n return new Date(parts[0], parts[1] - 1, parts[2]);\n}\n\n/**\n * Interpreta data/hora no fuso local.\n * - \"YYYY-MM-DD\" → meia-noite (00:00)\n * - \"YYYY-MM-DDTHH:mm\" ou \"YYYY-MM-DDTHH:mm:ss\" → hora exata (ex: 06:00 para entrega)\n */\nfunction parseDateTimeLocal(dateStr: string): Date {\n const datePart = dateStr.split(\"T\")[0];\n const timePart = dateStr.includes(\"T\") ? dateStr.split(\"T\")[1] : null;\n const date = parseDateLocal(datePart);\n if (isNaN(date.getTime())) return date;\n if (timePart) {\n const [h, m, sMs] = timePart.split(\":\");\n const hour = parseInt(h ?? \"0\", 10);\n const min = parseInt(m ?? \"0\", 10);\n const s = sMs !== undefined ? parseInt(sMs.slice(0, 2), 10) || 0 : 0;\n const ms = sMs?.includes(\".\")\n ? parseInt(sMs.split(\".\")[1].slice(0, 3), 10) || 0\n : 0;\n if (!Number.isNaN(hour)) date.setHours(hour, min, s, ms);\n }\n return date;\n}\n\n/** Para datas de fim de período: sem \"T\" = 23:59:59 do dia; com \"T\" = hora exata. */\nfunction parseDateTimeLocalEnd(dateStr: string): Date {\n if (!dateStr.includes(\"T\")) return getEndOfDay(parseDateLocal(dateStr));\n return parseDateTimeLocal(dateStr);\n}\n\n/** Retorna a mesma data às 23:59:59.999 (fim do dia) para barras irem até o fim do dia. */\nfunction getEndOfDay(d: Date): Date {\n const eod = new Date(d);\n eod.setHours(23, 59, 59, 999);\n return eod;\n}\n\nconst getStockAlert = (timeline: TimelineData[\"timeline\"]): StockAlertInfo => {\n const today = parseDateTimeLocal(timeline.todayDate).getTime();\n const stockEnd = parseDateTimeLocalEnd(timeline.stockEndDate).getTime();\n const delivery = parseDateTimeLocal(timeline.deliveryDate).getTime();\n const suggestStart = parseDateTimeLocal(\n timeline.restockSuggestionStart,\n ).getTime();\n const suggestEnd = parseDateTimeLocalEnd(\n timeline.restockSuggestionEnd,\n ).getTime();\n\n // 1. Crítico: Entrega após fim de estoque (Ruptura) ou no mesmo dia\n // Se delivery > stockEnd: Já passou, ruptura certa (Crítico)\n // Se delivery == stockEnd: Chega no dia que acaba (Crítico/Risco Altíssimo)\n if (delivery >= stockEnd) {\n const daysLate = Math.ceil((delivery - stockEnd) / (1000 * 60 * 60 * 24));\n return {\n status: \"critical\",\n title: \"Risco de Ruptura\",\n message:\n daysLate > 0\n ? `A entrega chegará ${daysLate} dia(s) após o estoque acabar.`\n : \"A entrega está prevista para o mesmo dia do fim do estoque.\",\n };\n }\n\n // 2. Crítico: Estoque Esgotado (Hoje já passou do fim do estoque)\n if (today >= stockEnd) {\n return {\n status: \"critical\",\n title: \"Estoque Esgotado\",\n message: \"Seu estoque previsto chegou ao fim.\",\n };\n }\n\n // Verifica margem de segurança entre entrega e fim do estoque\n const daysMargin = Math.floor((stockEnd - delivery) / (1000 * 60 * 60 * 24));\n\n // 3. Urgente (Laranja): Entrega chega com pouca margem (até 2 dias antes do fim)\n if (daysMargin <= 2) {\n return {\n status: \"urgent\",\n title: \"Atenção ao Prazo\",\n message: `Margem de segurança baixa: entrega prevista para ${daysMargin} dia(s) antes do fim do estoque.`,\n };\n }\n\n // 4. Warning (Amarelo): Janela de compra aberta (apenas se não cair nas regras acima)\n // Se ainda não comprou (assumindo que se tem data de entrega, já comprou?\n // A lógica original não distinguia \"já comprou\" de \"sugestão\".\n // Vou manter a lógica de sugestão, mas com menor prioridade que a margem de entrega.\n if (today >= suggestStart && today <= suggestEnd) {\n return {\n status: \"warning\",\n title: \"Sugestão de Compra\",\n message: \"Momento ideal para realizar o pedido de reposição.\",\n };\n }\n\n // 5. Sucesso (Verde): Margem segura (> 2 dias) ou antes do período de sugestão\n return {\n status: \"success\",\n title: \"Estoque Seguro\",\n message: \"Nível de estoque adequado. Nenhuma ação necessária.\",\n };\n};\n\nexport function StockLeadTime({\n data,\n className,\n style,\n controls = false,\n showLegend = true,\n size = \"md\",\n selectedQty,\n selectedQtyDays,\n showSuggestionBar: showSuggestionBarProp = true,\n unitLabel = \"kg\",\n}: StockLeadTimeProps) {\n const sizeConfig = useMemo(() => SIZE_CONFIG[size], [size]);\n\n // Define as cores com base no tema\n const COLORS = useMemo(\n () => THEME_COLORS[data.config.theme || \"light\"],\n [data.config.theme],\n );\n\n const alertInfo = useMemo(\n () => getStockAlert(data.timeline),\n [data.timeline],\n );\n\n // Constantes e funções auxiliares para o tooltip\n const DAY_NAMES = [\"DOM\", \"SEG\", \"TER\", \"QUA\", \"QUI\", \"SEX\", \"SAB\"];\n\n const getDailyConsumption = useCallback(\n (dayOfWeek: number): number | null => {\n if (!data.timeline.dailyConsumptionAverage) return null;\n\n const dayKeys: (keyof typeof data.timeline.dailyConsumptionAverage)[] = [\n \"0-domingo\",\n \"1-segunda\",\n \"2-terca\",\n \"3-quarta\",\n \"4-quinta\",\n \"5-sexta\",\n \"6-sabado\",\n ];\n\n const key = dayKeys[dayOfWeek];\n return data.timeline.dailyConsumptionAverage[key] ?? null;\n },\n [data],\n );\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [hoverState, setHoverState] = useState<HoverState>({\n isHovering: false,\n hoveredSection: null,\n mouseX: 0,\n mouseY: 0,\n dateAtCursor: null,\n });\n const [tooltipPosition, setTooltipPosition] = useState<Point>({ x: 0, y: 0 });\n // Níveis de zoom relativos ao valor base de pixels por dia (4 opções)\n const ZOOM_LEVELS = useMemo(() => [0.6, 0.9, 1, 1.4, 1.8] as const, []);\n const [zoomLevelIndex, setZoomLevelIndex] = useState<number>(3); // nível padrão próximo ao original\n // Estado para scroll horizontal\n const [scrollOffset, setScrollOffset] = useState<number>(0);\n // Estado para mostrar/esconder linha de consumo médio\n const [showConsumptionLine, setShowConsumptionLine] =\n useState<boolean>(false);\n // Estado para mostrar/esconder barra amarela (sugestão) quando controls=true\n const [suggestionBarVisible, setSuggestionBarVisible] = useState<boolean>(\n showSuggestionBarProp,\n );\n const showSuggestionBarEffective = controls\n ? suggestionBarVisible\n : showSuggestionBarProp;\n\n useEffect(() => {\n setSuggestionBarVisible(showSuggestionBarProp);\n }, [showSuggestionBarProp]);\n\n // Datas/horas em escala de horas: \"YYYY-MM-DD\" (00:00) ou \"YYYY-MM-DDTHH:mm\" (hora exata)\n const startDate = useMemo(\n () => parseDateTimeLocal(data.timeline.lastRestockDate),\n [data.timeline.lastRestockDate],\n );\n const todayDate = useMemo(\n () => parseDateTimeLocal(data.timeline.todayDate),\n [data.timeline.todayDate],\n );\n // Fim do estoque / fim da sugestão: sem \"T\" = 23:59 do dia; com \"T\" = hora exata\n const stockEndDate = useMemo(\n () => parseDateTimeLocalEnd(data.timeline.stockEndDate),\n [data.timeline.stockEndDate],\n );\n const restockStart = useMemo(\n () => parseDateTimeLocal(data.timeline.restockSuggestionStart),\n [data.timeline.restockSuggestionStart],\n );\n const restockEnd = useMemo(\n () => parseDateTimeLocalEnd(data.timeline.restockSuggestionEnd),\n [data.timeline.restockSuggestionEnd],\n );\n const deliveryDate = useMemo(\n () => parseDateTimeLocal(data.timeline.deliveryDate),\n [data.timeline.deliveryDate],\n );\n\n const MS_PER_DAY = 1000 * 60 * 60 * 24;\n\n // Pixels efetivos por dia considerando o zoom atual\n const pixelsPerDay = useMemo(\n () => data.config.pixelsPerDay * ZOOM_LEVELS[zoomLevelIndex],\n [data.config.pixelsPerDay, zoomLevelIndex, ZOOM_LEVELS],\n );\n\n // Calcula posições X no canvas (considerando scroll)\n const dateToX = useCallback(\n (date: Date): number => {\n // Usa milissegundos diretamente para preservar decimais\n const daysDiff = (date.getTime() - startDate.getTime()) / MS_PER_DAY;\n return sizeConfig.padding.left + daysDiff * pixelsPerDay - scrollOffset;\n },\n [\n startDate,\n pixelsPerDay,\n sizeConfig.padding.left,\n scrollOffset,\n MS_PER_DAY,\n ],\n );\n\n // Calcula data a partir da posição X (considerando scroll)\n const xToDate = useCallback(\n (x: number): Date => {\n const daysFromStart =\n (x - sizeConfig.padding.left + scrollOffset) / pixelsPerDay;\n const date = new Date(startDate);\n date.setDate(date.getDate() + Math.floor(daysFromStart));\n return date;\n },\n [startDate, pixelsPerDay, sizeConfig.padding.left, scrollOffset],\n );\n\n // Formata data para exibição (DD/MM)\n const formatDate = (date: Date): string => {\n return `${date.getDate().toString().padStart(2, \"0\")}/${(\n date.getMonth() + 1\n )\n .toString()\n .padStart(2, \"0\")}`;\n };\n\n // Formata data e hora quando não for meia-noite (DD/MM HH:mm)\n const formatDateTime = (date: Date): string => {\n const d = date.getDate().toString().padStart(2, \"0\");\n const m = (date.getMonth() + 1).toString().padStart(2, \"0\");\n if (date.getHours() === 0 && date.getMinutes() === 0) return `${d}/${m}`;\n const h = date.getHours().toString().padStart(2, \"0\");\n const min = date.getMinutes().toString().padStart(2, \"0\");\n return `${d}/${m} ${h}:${min}`;\n };\n\n // Desenha o canvas\n const drawCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Garante que roundRect está disponível\n ensureRoundRect(ctx);\n\n const dpr = window.devicePixelRatio || 1;\n const rect = canvas.getBoundingClientRect();\n const width = rect.width;\n const height = sizeConfig.height;\n\n // Ajusta resolução para High DPI\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n ctx.scale(dpr, dpr);\n\n // Limpa o canvas\n ctx.clearRect(0, 0, width, height);\n\n // Desenha background com bordas arredondadas\n ctx.fillStyle = COLORS.background;\n (ctx as any).roundRect(0, 0, width, height, 12);\n ctx.fill();\n\n // Desenha indicador de hover (dia selecionado)\n if (hoverState.isHovering && hoverState.dateAtCursor) {\n const hoverX = dateToX(hoverState.dateAtCursor);\n // Verifica limites (opcional, mas bom para evitar desenhar fora se o zoom mudar ou algo assim)\n // O dateToX já considera o padding.\n\n const isDark = data.config.theme === \"dark\";\n ctx.fillStyle = isDark\n ? \"rgba(255, 255, 255, 0.05)\"\n : \"rgba(0, 0, 0, 0.05)\";\n\n const graphTop = sizeConfig.padding.top;\n const graphHeight =\n height - sizeConfig.padding.bottom - sizeConfig.padding.top;\n\n ctx.fillRect(hoverX, graphTop, pixelsPerDay, graphHeight);\n }\n\n // Calcula posições das barras (barras vão até 23:59 do dia final)\n const lastRestockX = dateToX(startDate); // Último abastecimento\n const todayX = dateToX(todayDate);\n const stockEndX = dateToX(stockEndDate); // Previsão de duração (até 23:59)\n\n // Data de entrega (recebida diretamente)\n const deliveryStartX = dateToX(deliveryDate);\n\n const restockStartX = dateToX(restockStart);\n const restockEndX = dateToX(restockEnd); // Fim da sugestão (até 23:59)\n\n const barY = sizeConfig.padding.top;\n const fullHeight =\n height - sizeConfig.padding.top - sizeConfig.padding.bottom;\n const segmentHeight = fullHeight * sizeConfig.segmentRatio; // Altura proporcional ao tamanho\n\n const stockY = barY + 5; // Levemente deslocado do topo\n // Mantém em Y diferentes, mas reduz o espaçamento vertical para ficar visualmente agrupado\n const suggestionY = stockY + segmentHeight + 2;\n\n // Todas as barras sempre com opacidade total - sem alteração no hover\n\n // Desenha Grid de Tempo (linhas verticais)\n ctx.strokeStyle = COLORS.textSecondary;\n ctx.lineWidth = 1;\n ctx.setLineDash([]);\n\n // Usa a data mais recente entre restockEnd e deliveryDate para calcular o fim do grid (barras até 23:59)\n let maxTime = Math.max(\n restockEnd.getTime(),\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n );\n\n // Se há quantidade selecionada, considera também o fim dessa barra (até 23:59 do último dia)\n if (typeof selectedQtyDays === \"number\" && selectedQtyDays > 0) {\n const selectedQtyStartDateCalc = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDateCalc.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDateCalc = getEndOfDay(lastDayOfSelected);\n maxTime = Math.max(maxTime, selectedQtyEndDateCalc.getTime());\n }\n\n const endDate = new Date(maxTime);\n // Adiciona alguns dias de buffer para visualização\n endDate.setDate(endDate.getDate() + 2);\n const totalDays = Math.ceil(\n (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24),\n );\n\n // Nomes dos meses abreviados\n const MONTH_NAMES = [\n \"JAN\",\n \"FEV\",\n \"MAR\",\n \"ABR\",\n \"MAI\",\n \"JUN\",\n \"JUL\",\n \"AGO\",\n \"SET\",\n \"OUT\",\n \"NOV\",\n \"DEZ\",\n ];\n\n // Cores alternadas para meses (light e dark themes) - cores mais distintas\n const getMonthBackgroundColor = (monthIndex: number) => {\n const isEvenMonth = monthIndex % 2 === 0;\n if (data.config.theme === \"dark\") {\n return isEvenMonth\n ? \"rgba(71, 85, 105, 0.25)\"\n : \"rgba(51, 65, 85, 0.4)\";\n }\n return isEvenMonth\n ? \"rgba(241, 245, 249, 0.6)\"\n : \"rgba(203, 213, 225, 0.5)\";\n };\n\n // Cores dos labels dos dias alternando por mês\n const getDayLabelColor = (monthIndex: number, isWeekend: boolean) => {\n const isEvenMonth = monthIndex % 2 === 0;\n if (isWeekend) {\n return adjustColorBrightness(COLORS.textSecondary, -25);\n }\n if (data.config.theme === \"dark\") {\n return isEvenMonth\n ? \"rgba(148, 163, 184, 1)\"\n : \"rgba(226, 232, 240, 1)\";\n }\n return isEvenMonth ? \"rgba(100, 116, 139, 1)\" : \"rgba(51, 65, 85, 1)\";\n };\n\n // Primeiro, coleta informações dos meses\n const monthRanges: {\n month: number;\n year: number;\n startX: number;\n endX: number;\n }[] = [];\n let currentMonth = -1;\n let currentYear = -1;\n let monthStartX = sizeConfig.padding.left;\n\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(startDate);\n date.setDate(date.getDate() + i);\n const x = dateToX(date);\n const month = date.getMonth();\n const year = date.getFullYear();\n\n if (month !== currentMonth || year !== currentYear) {\n // Salva o mês anterior\n if (currentMonth !== -1) {\n monthRanges.push({\n month: currentMonth,\n year: currentYear,\n startX: monthStartX,\n endX: x,\n });\n }\n currentMonth = month;\n currentYear = year;\n monthStartX = x;\n }\n }\n // Adiciona o último mês\n if (currentMonth !== -1) {\n const lastDate = new Date(startDate);\n lastDate.setDate(lastDate.getDate() + totalDays);\n monthRanges.push({\n month: currentMonth,\n year: currentYear,\n startX: monthStartX,\n endX: dateToX(lastDate) + pixelsPerDay,\n });\n }\n\n // Desenha backgrounds dos meses ATRÁS do gráfico (área das barras)\n const graphAreaTop = barY;\n const graphAreaHeight = height - sizeConfig.padding.bottom - barY;\n\n for (const range of monthRanges) {\n const bgStartX = Math.max(range.startX, sizeConfig.padding.left);\n const bgEndX = Math.min(range.endX, width - sizeConfig.padding.right);\n const bgWidth = bgEndX - bgStartX;\n\n if (bgWidth > 0) {\n // Background do mês na área do gráfico\n ctx.fillStyle = getMonthBackgroundColor(range.month);\n ctx.fillRect(bgStartX, graphAreaTop, bgWidth, graphAreaHeight);\n\n // Nome do mês no começo e no final do mês (tamanho reduzido)\n const bottomY = graphAreaTop + graphAreaHeight - 15; // 5px de margem da base\n ctx.fillStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.35)\"\n : \"rgba(100, 116, 139, 0.25)\";\n const monthFont = `bold ${(sizeConfig.fontSize + 4) * 2}px system-ui, -apple-system, sans-serif`;\n\n // Calcula a posição real do dia 1 deste mês\n const firstDayOfMonth = new Date(range.year, range.month, 2);\n const firstDayOfMonthX = dateToX(firstDayOfMonth);\n const isFirstDayOfMonthVisible =\n firstDayOfMonthX >= sizeConfig.padding.left &&\n firstDayOfMonthX <= width - sizeConfig.padding.right;\n\n // Calcula a posição do primeiro dia do próximo mês (que é onde mostraremos o nome do mês atual no final)\n const nextMonthFirstDay = new Date(range.year, range.month + 1, 2);\n const nextMonthFirstDayX = dateToX(nextMonthFirstDay);\n const isNextMonthFirstDayVisible =\n nextMonthFirstDayX >= sizeConfig.padding.left &&\n nextMonthFirstDayX <= width - sizeConfig.padding.right;\n\n // Nome no último dia do mês - alinhado à direita da barra do primeiro dia do próximo mês\n // Mostra o nome do mês atual (ex: NOV) à direita da barra do dia 1 do próximo mês (ex: dia 1 de DEZ)\n if (isNextMonthFirstDayVisible) {\n ctx.save();\n ctx.font = monthFont;\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n ctx.fillText(\n MONTH_NAMES[range.month],\n nextMonthFirstDayX - 4,\n bottomY,\n );\n ctx.restore();\n }\n\n // Nome no primeiro dia do mês - alinhado à esquerda da barra do primeiro dia\n // O texto deve começar logo após a barra vertical (4px de espaçamento)\n if (isFirstDayOfMonthVisible) {\n ctx.save();\n ctx.font = monthFont;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n // A barra está em firstDayOfMonthX, então o texto começa 4px à direita da barra\n ctx.fillText(MONTH_NAMES[range.month], firstDayOfMonthX + 4, bottomY);\n ctx.restore();\n }\n }\n }\n\n // Nomes dos dias da semana\n const DAY_NAMES = [\"DOM\", \"SEG\", \"TER\", \"QUA\", \"QUI\", \"SEX\", \"SAB\"];\n\n // Helper para obter o consumo médio do dia da semana\n const getDailyConsumption = (dayOfWeek: number): number | null => {\n if (!data.timeline.dailyConsumptionAverage) return null;\n\n const dayKeys: (keyof typeof data.timeline.dailyConsumptionAverage)[] = [\n \"0-domingo\",\n \"1-segunda\",\n \"2-terca\",\n \"3-quarta\",\n \"4-quinta\",\n \"5-sexta\",\n \"6-sabado\",\n ];\n\n const key = dayKeys[dayOfWeek];\n return data.timeline.dailyConsumptionAverage[key] ?? null;\n };\n\n // Desenha as linhas verticais e labels dos dias (cada linha na meia-noite do dia civil)\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(\n startDate.getFullYear(),\n startDate.getMonth(),\n startDate.getDate() + i,\n );\n const x = dateToX(date);\n\n if (\n x >= sizeConfig.padding.left &&\n x <= width - sizeConfig.padding.right\n ) {\n // Fins de semana (sábado = 6, domingo = 0)\n const dayOfWeek = date.getDay();\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\n const month = date.getMonth();\n const isFirstDayOfMonth = date.getDate() === 1;\n\n // Borda destacada no primeiro dia do mês\n if (isFirstDayOfMonth) {\n ctx.save();\n ctx.strokeStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.8)\"\n : \"rgba(71, 85, 105, 0.6)\";\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.moveTo(x, barY);\n ctx.lineTo(x, height - sizeConfig.padding.bottom + 20);\n ctx.stroke();\n ctx.restore();\n }\n\n // Linha normal do dia (mesma cor para todos os dias)\n ctx.strokeStyle = COLORS.textSecondary;\n ctx.lineWidth = 1;\n\n ctx.beginPath();\n ctx.moveTo(x, barY);\n ctx.lineTo(x, height - sizeConfig.padding.bottom);\n ctx.stroke();\n\n // Labels de data - mostra TODOS os dias (incluindo Hoje, Entrega, fim do estoque, etc.)\n const labelX = x + pixelsPerDay / 2;\n const baseY = height - sizeConfig.padding.bottom + 8;\n\n // Texto do dia (apenas o número)\n ctx.fillStyle = getDayLabelColor(month, false);\n ctx.font = `${sizeConfig.fontSize}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n ctx.fillText(date.getDate().toString().padStart(2, \"0\"), labelX, baseY);\n\n // Consumo médio acima do nome do dia\n const dailyConsumption = getDailyConsumption(dayOfWeek);\n const consumptionValue =\n dailyConsumption !== null ? dailyConsumption : 0;\n ctx.fillStyle =\n data.config.theme === \"dark\"\n ? \"rgba(148, 163, 184, 0.7)\"\n : \"rgba(100, 116, 139, 0.7)\";\n ctx.font = `${sizeConfig.fontSize - 3}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"bottom\";\n const consumptionY = height - sizeConfig.padding.bottom - 18;\n ctx.fillText(consumptionValue.toFixed(2), labelX, consumptionY);\n\n // Nome do dia da semana na parte inferior do gráfico\n const dayLabel = DAY_NAMES[dayOfWeek];\n ctx.fillStyle = getDayLabelColor(month, false);\n ctx.font = `${isWeekend ? \"bold \" : \"\"}${\n sizeConfig.fontSize - 2\n }px system-ui, -apple-system, sans-serif`;\n const dayLabelY = height - sizeConfig.padding.bottom - 4;\n ctx.textBaseline = \"bottom\";\n ctx.fillText(dayLabel, labelX, dayLabelY);\n }\n }\n\n // Desenha linha de consumo médio (atrás das barras)\n if (showConsumptionLine && data.timeline.dailyConsumptionAverage) {\n // Calcula o consumo máximo para criar uma escala\n const consumptionValues = Object.values(\n data.timeline.dailyConsumptionAverage,\n ).filter((v): v is number => typeof v === \"number\");\n const maxConsumption =\n consumptionValues.length > 0\n ? Math.max(...consumptionValues, 1) // Mínimo 1 para evitar divisão por zero\n : 1;\n\n // Altura máxima da linha = 50% da altura dos dias (padding.bottom)\n const maxLineHeight = sizeConfig.padding.bottom * 0.5;\n // Área onde a linha será desenhada (alinhada com a parte inferior dos dias)\n // Base: parte inferior dos dias (onde estão os labels)\n const lineAreaBottom = height - sizeConfig.padding.bottom;\n // Topo: 50% da altura dos dias acima da base\n const lineAreaTop = lineAreaBottom - maxLineHeight;\n const lineAreaHeight = maxLineHeight;\n\n // Coleta pontos da linha para cada dia visível\n const linePoints: { x: number; y: number }[] = [];\n\n for (let i = 0; i <= totalDays; i++) {\n const date = new Date(startDate);\n date.setDate(date.getDate() + i);\n const x = dateToX(date);\n\n if (\n x >= sizeConfig.padding.left &&\n x <= width - sizeConfig.padding.right\n ) {\n const dayOfWeek = date.getDay();\n const consumption = getDailyConsumption(dayOfWeek) ?? 0;\n\n // Calcula Y baseado no consumo (maior consumo = mais alto na tela)\n // A linha vai de lineAreaBottom (consumo 0) até lineAreaTop (consumo máximo)\n const consumptionRatio = consumption / maxConsumption;\n const y = lineAreaBottom - consumptionRatio * lineAreaHeight;\n\n linePoints.push({ x: x + pixelsPerDay / 2, y });\n }\n }\n\n // Desenha a linha conectando os pontos com quinas arredondadas\n if (linePoints.length > 1) {\n ctx.save();\n ctx.strokeStyle = \"rgba(0, 0, 0, 0.25)\"; // Cor clara e quase transparente\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n ctx.miterLimit = 2;\n\n ctx.beginPath();\n ctx.moveTo(linePoints[0].x, linePoints[0].y);\n\n // Conecta os pontos com linhas (lineJoin=\"round\" cria quinas arredondadas automaticamente)\n for (let i = 1; i < linePoints.length; i++) {\n ctx.lineTo(linePoints[i].x, linePoints[i].y);\n }\n\n ctx.stroke();\n ctx.restore();\n }\n }\n\n // Calcula posição inicial do estoque\n const stockStartX = Math.max(lastRestockX, sizeConfig.padding.left);\n\n // Desenha os segmentos na ordem da esquerda para a direita\n // Cada segmento é desenhado de forma completamente independente\n\n // Desenha os segmentos na ordem da esquerda para a direita\n // Cada segmento define sua cor ANTES de desenhar para garantir cores distintas\n\n // Função auxiliar para criar gradiente vertical\n const createGradient = (color: string, y: number, h: number) => {\n const gradient = ctx.createLinearGradient(0, y, 0, y + h);\n gradient.addColorStop(0, color);\n gradient.addColorStop(1, adjustColorBrightness(color, -15)); // Escurece 15% na base\n return gradient;\n };\n\n // Função auxiliar para criar gradiente horizontal (simulado com vertical)\n const createHorizontalGradient = (color: string, x: number, w: number) => {\n const gradient = ctx.createLinearGradient(x, 0, x + w, 0);\n gradient.addColorStop(0, color);\n gradient.addColorStop(1, adjustColorBrightness(color, -10)); // Levemente mais escuro no final\n return gradient;\n };\n\n // Função auxiliar para desenhar o texto de cada segmento\n // centralizado (horizontal e verticalmente) dentro do próprio segmento,\n // com maior contraste.\n const drawDaysLabelCentered = (\n segmentStartX: number,\n segmentEndX: number,\n segmentTopY: number,\n segmentHeightLocal: number,\n label: string,\n ) => {\n if (!label) return;\n\n const centerX = (segmentStartX + segmentEndX) / 2;\n const centerY = segmentTopY + segmentHeightLocal / 2;\n ctx.textAlign = \"center\";\n\n ctx.font = `${\n sizeConfig.fontSize - 1\n }px system-ui, -apple-system, sans-serif`;\n ctx.fillStyle = \"#FFFFFF\"; // alto contraste\n ctx.textBaseline = \"middle\";\n\n // Sombra para destacar em qualquer cor de fundo\n ctx.shadowColor = \"rgba(0, 0, 0, 0.35)\";\n ctx.shadowBlur = 3;\n ctx.shadowOffsetY = 1;\n\n ctx.fillText(label, centerX, centerY);\n\n // Reset da sombra para não afetar outros desenhos\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n };\n\n // Configurações de estilo comuns\n ctx.lineWidth = 1;\n ctx.lineJoin = \"round\";\n\n // Fim da barra de dias consumidos: no máximo hoje ou o fim do dia final do estoque (23:59)\n const consumedEndDate = new Date(\n Math.min(todayDate.getTime(), stockEndDate.getTime()),\n );\n const consumedEndX = dateToX(consumedEndDate);\n\n // Segmento 1: Último abastecimento até hoje ou fim do estoque (o que vier primeiro) - Cinza escuro\n if (consumedEndX > stockStartX) {\n const segment1Width = consumedEndX - stockStartX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente\n ctx.fillStyle = createGradient(COLORS.stockPast, stockY, segmentHeight);\n ctx.strokeStyle = adjustColorBrightness(COLORS.stockPast, -20); // Borda mais escura\n ctx.lineWidth = 1.5;\n\n // Desenha com canto arredondado apenas na esquerda\n const x = stockStartX;\n const y = stockY;\n const w = segment1Width;\n const h = segmentHeight;\n const r = 6;\n\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w, y); // Lado direito reto\n ctx.lineTo(x + w, y + h); // Lado direito reto\n ctx.lineTo(x + r, y + h);\n ctx.quadraticCurveTo(x, y + h, x, y + h - r);\n ctx.lineTo(x, y + r);\n ctx.quadraticCurveTo(x, y, x + r, y);\n\n ctx.fill();\n ctx.stroke(); // Opcional: desenhar borda\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 1 (abastecimento até hoje ou fim do estoque)\n const daysPast = Math.max(\n 0,\n Math.round(\n (consumedEndDate.getTime() - startDate.getTime()) / MS_PER_DAY,\n ),\n );\n // Label dentro do segmento (perto da base da barra)\n const labelPast = `${daysPast} dia${daysPast === 1 ? \"\" : \"s\"} consumido${\n daysPast === 1 ? \"\" : \"s\"\n }`;\n drawDaysLabelCentered(\n stockStartX,\n consumedEndX,\n stockY,\n segmentHeight,\n labelPast,\n );\n }\n\n // Segmento 2: Hoje até previsão de duração - Laranja\n if (stockEndX > todayX) {\n const segment2Width = stockEndX - todayX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente HORIZONTAL\n ctx.fillStyle = createHorizontalGradient(\n COLORS.stockFuture,\n todayX,\n segment2Width,\n );\n ctx.strokeStyle = adjustColorBrightness(COLORS.stockFuture, -20);\n ctx.lineWidth = 1.5;\n\n // Desenha com canto arredondado apenas na direita\n // E reto na esquerda para conectar perfeitamente com o segmento 1\n const x = todayX;\n const y = stockY;\n const w = segment2Width;\n const h = segmentHeight;\n const r = 6;\n\n ctx.moveTo(x, y); // Lado esquerdo reto\n ctx.lineTo(x + w - r, y);\n ctx.quadraticCurveTo(x + w, y, x + w, y + r);\n ctx.lineTo(x + w, y + h - r);\n ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);\n ctx.lineTo(x, y + h); // Lado esquerdo reto\n ctx.lineTo(x, y);\n\n ctx.fill();\n ctx.stroke();\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 2 (de hoje até 23:59 do fim do estoque)\n const daysFuture = Math.max(\n 0,\n Math.round((stockEndDate.getTime() - todayDate.getTime()) / MS_PER_DAY),\n );\n // Label dentro do segmento (perto da base da barra)\n const labelFuture = `${daysFuture} dia${\n daysFuture === 1 ? \"\" : \"s\"\n } restante${daysFuture === 1 ? \"\" : \"s\"}`;\n drawDaysLabelCentered(\n todayX,\n stockEndX,\n stockY,\n segmentHeight,\n labelFuture,\n );\n }\n\n // Segmento 3: Sugestão de Compra - Barra amarela (após o fim do estoque)\n const suggestionStartX = Math.max(deliveryStartX, stockEndX);\n if (\n showSuggestionBarEffective &&\n restockEndX > suggestionStartX &&\n suggestionStartX >= sizeConfig.padding.left\n ) {\n const segment3Width = restockEndX - suggestionStartX;\n ctx.beginPath(); // Inicia novo path\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente HORIZONTAL\n ctx.fillStyle = createHorizontalGradient(\n COLORS.alert,\n suggestionStartX,\n segment3Width,\n );\n ctx.strokeStyle = adjustColorBrightness(COLORS.alert, -20);\n ctx.lineWidth = 1.5;\n\n // Desenha como um bloco contíguo, mas visualmente separado se houver gap temporal\n // Se suggestionStartX for igual a stockEndX, eles \"tocam\" visualmente se estiverem na mesma altura.\n // Como suggestionY agora é igual a stockY, eles estarão alinhados.\n\n (ctx as any).roundRect(\n suggestionStartX,\n suggestionY,\n segment3Width,\n segmentHeight,\n 6,\n );\n ctx.fill();\n ctx.stroke();\n ctx.closePath(); // Fecha o path\n // Quantidade de dias do segmento 3 (janela de sugestão)\n // Calcula baseado na largura visual real da barra, não nas datas originais\n const daysSuggestion = Math.max(\n 0,\n Math.round(segment3Width / pixelsPerDay),\n );\n const labelSuggestion = `${daysSuggestion} dia${\n daysSuggestion === 1 ? \"\" : \"s\"\n }`;\n drawDaysLabelCentered(\n suggestionStartX,\n restockEndX,\n suggestionY,\n segmentHeight,\n labelSuggestion,\n );\n }\n\n // Segmento 4: Barra de quantidade selecionada (selectedQty) - Azul\n // Começa no mesmo ponto da barra de sugestão (max entre entrega e fim do estoque); vai até 23:59 do último dia\n if (\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\"\n ) {\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n\n // Fim da barra às 23:59 do último dia\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n const selectedQtyWidth = selectedQtyEndX - selectedQtyStartX;\n\n if (selectedQtyWidth > 0) {\n // Altura de 50% das outras barras\n const selectedQtyHeight = segmentHeight * 0.5;\n // Posiciona abaixo da barra de sugestão, centralizada verticalmente\n const selectedQtyY = suggestionY + segmentHeight + 4;\n\n ctx.beginPath();\n ctx.globalAlpha = 1.0;\n\n // Aplica gradiente horizontal azul\n ctx.fillStyle = createHorizontalGradient(\n (COLORS as any).selectedQtyBar,\n selectedQtyStartX,\n selectedQtyWidth,\n );\n ctx.strokeStyle = adjustColorBrightness(\n (COLORS as any).selectedQtyBar,\n -20,\n );\n ctx.lineWidth = 1.5;\n\n // Desenha com bordas arredondadas\n (ctx as any).roundRect(\n selectedQtyStartX,\n selectedQtyY,\n selectedQtyWidth,\n selectedQtyHeight,\n 4,\n );\n ctx.fill();\n ctx.stroke();\n ctx.closePath();\n }\n }\n\n // Destaque de hover nos segmentos (sombra/overlay suave)\n if (hoverState.isHovering && hoverState.hoveredSection) {\n ctx.save();\n ctx.globalAlpha = 0.18;\n ctx.fillStyle = data.config.theme === \"dark\" ? \"#FFFFFF\" : \"#000000\";\n\n if (hoverState.hoveredSection === \"stock\") {\n // cobre toda a faixa de estoque (passado + futuro)\n ctx.fillRect(\n stockStartX,\n stockY,\n stockEndX - stockStartX,\n segmentHeight,\n );\n } else if (\n hoverState.hoveredSection === \"suggestion\" &&\n showSuggestionBarEffective\n ) {\n ctx.fillRect(\n suggestionStartX,\n suggestionY,\n restockEndX - suggestionStartX,\n segmentHeight,\n );\n } else if (\n hoverState.hoveredSection === \"selectedQty\" &&\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0\n ) {\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n const selectedQtyHeight = segmentHeight * 0.5;\n const selectedQtyY = suggestionY + segmentHeight + 4;\n\n ctx.fillRect(\n selectedQtyStartX,\n selectedQtyY,\n selectedQtyEndX - selectedQtyStartX,\n selectedQtyHeight,\n );\n }\n\n ctx.restore();\n }\n\n // Função auxiliar para desenhar labels estilizados (Pills/Tags)\n const drawModernLabel = (\n x: number,\n y: number,\n text: string,\n bgColor: string,\n ) => {\n ctx.font = `bold ${sizeConfig.pillFontSize}px system-ui, -apple-system, sans-serif`;\n const metrics = ctx.measureText(text.toUpperCase());\n const paddingX = sizeConfig.pillPaddingX;\n const paddingY = sizeConfig.pillPaddingY;\n const pillHeight = sizeConfig.pillHeight;\n const pillWidth = metrics.width + paddingX * 2;\n\n // Sombra suave para o pill\n ctx.shadowColor = \"rgba(0, 0, 0, 0.1)\";\n ctx.shadowBlur = 4;\n ctx.shadowOffsetY = 2;\n\n // Fundo do Pill\n ctx.fillStyle = bgColor;\n ctx.beginPath();\n (ctx as any).roundRect(\n x - pillWidth / 2,\n y,\n pillWidth,\n pillHeight,\n pillHeight / 2,\n );\n ctx.fill();\n\n // Reset de sombra\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n\n // Texto\n ctx.fillStyle = \"#FFFFFF\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text.toUpperCase(), x, y + pillHeight / 2 + 1); // +1 para ajuste ótico\n };\n\n // Desenha a coluna inteira do \"Hoje\" com fundo diferente + label centralizada\n if (\n todayX >= sizeConfig.padding.left &&\n todayX <= width - sizeConfig.padding.right\n ) {\n const todayColumnLeft = todayX;\n const todayColumnWidth = pixelsPerDay;\n const graphTop = barY;\n const graphBottom = height - sizeConfig.padding.bottom;\n\n // Fundo da coluna (toda a altura do gráfico)\n ctx.globalAlpha = 0.12;\n ctx.fillStyle = COLORS.todayIndicator;\n ctx.fillRect(\n todayColumnLeft,\n graphTop,\n todayColumnWidth,\n graphBottom - graphTop,\n );\n ctx.globalAlpha = 1.0;\n\n // Linha sutil na borda esquerda da coluna\n ctx.strokeStyle = COLORS.todayIndicator;\n ctx.lineWidth = 1.5;\n ctx.beginPath();\n ctx.moveTo(todayColumnLeft, graphTop);\n ctx.lineTo(todayColumnLeft, graphBottom);\n ctx.stroke();\n\n // Label \"Hoje\" centralizada na coluna\n const todayLabelX = todayColumnLeft + todayColumnWidth / 2;\n drawModernLabel(\n todayLabelX,\n height - sizeConfig.padding.bottom + 20,\n \"Hoje\",\n COLORS.todayIndicator,\n );\n }\n\n // Desenha a linha vertical fina do dia da entrega\n if (\n deliveryStartX >= sizeConfig.padding.left &&\n deliveryStartX <= width - sizeConfig.padding.right\n ) {\n ctx.globalAlpha = 1.0;\n ctx.strokeStyle = COLORS.deliveryBar; // Verde escuro\n ctx.lineWidth = 1.5; // Um pouco mais grossa para a linha tracejada\n ctx.setLineDash([3, 3]); // Tracejado mais denso e técnico\n\n ctx.beginPath();\n ctx.moveTo(deliveryStartX, 0);\n ctx.lineTo(deliveryStartX, height - sizeConfig.padding.bottom);\n ctx.stroke();\n ctx.setLineDash([]); // Remove o tracejado\n\n // Label moderna\n drawModernLabel(\n deliveryStartX,\n height - sizeConfig.padding.bottom + 20,\n \"Entrega\",\n COLORS.deliveryBar,\n );\n }\n\n // Desenha o ícone de alerta no dia em que a sugestão começa (apenas se a barra amarela estiver visível)\n if (showSuggestionBarEffective) {\n const alertIconSize = sizeConfig.fontSize + 6;\n const alertIconX =\n suggestionStartX + pixelsPerDay / 2 - alertIconSize / 2;\n const alertIconY = suggestionY - alertIconSize - 4;\n\n // Cor do ícone baseada no status do alerta\n const alertIconColor =\n alertInfo.status === \"critical\"\n ? (COLORS as any).alertCritical\n : alertInfo.status === \"urgent\"\n ? (COLORS as any).alertUrgent\n : alertInfo.status === \"warning\"\n ? (COLORS as any).alertWarning\n : alertInfo.status === \"success\"\n ? (COLORS as any).alertSuccess\n : (COLORS as any).alertInfo;\n\n // Desenha círculo de fundo\n ctx.beginPath();\n ctx.arc(\n alertIconX + alertIconSize / 2,\n alertIconY + alertIconSize / 2,\n alertIconSize / 2,\n 0,\n Math.PI * 2,\n );\n ctx.fillStyle = alertIconColor;\n ctx.fill();\n\n // Sombra suave\n ctx.shadowColor = \"rgba(0, 0, 0, 0.2)\";\n ctx.shadowBlur = 4;\n ctx.shadowOffsetY = 2;\n\n // Desenha o símbolo dentro do círculo\n ctx.fillStyle = \"#FFFFFF\";\n ctx.font = `bold ${alertIconSize * 0.6}px system-ui, -apple-system, sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n const iconSymbol =\n alertInfo.status === \"critical\"\n ? \"!\"\n : alertInfo.status === \"urgent\"\n ? \"!\"\n : alertInfo.status === \"warning\"\n ? \"!\"\n : alertInfo.status === \"success\"\n ? \"✓\"\n : \"i\";\n\n ctx.fillText(\n iconSymbol,\n alertIconX + alertIconSize / 2,\n alertIconY + alertIconSize / 2,\n );\n\n // Reset sombra\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Reset global alpha\n ctx.globalAlpha = 1.0;\n }, [\n data,\n dateToX,\n startDate,\n todayDate,\n stockEndDate,\n restockStart,\n restockEnd,\n deliveryDate,\n COLORS,\n sizeConfig,\n hoverState,\n MS_PER_DAY,\n pixelsPerDay,\n selectedQty,\n selectedQtyDays,\n alertInfo,\n showConsumptionLine,\n showSuggestionBarEffective,\n ]);\n\n // Detecta qual seção está sendo hovered\n const getHoveredSection = useCallback(\n (\n clientX: number,\n clientY: number,\n ):\n | \"stock\"\n | \"delivery\"\n | \"suggestion\"\n | \"selectedQty\"\n | \"alertIcon\"\n | null => {\n const canvas = canvasRef.current;\n if (!canvas) return null;\n\n const rect = canvas.getBoundingClientRect();\n const relativeX = clientX - rect.left;\n const relativeY = clientY - rect.top;\n\n const barY = sizeConfig.padding.top;\n const fullHeight =\n sizeConfig.height - sizeConfig.padding.top - sizeConfig.padding.bottom;\n const segmentHeight = fullHeight * sizeConfig.segmentRatio;\n\n const stockY = barY + 5;\n // Mantém o mesmo Y usado no desenho do segmento de sugestão\n const suggestionY = stockY + segmentHeight + 2;\n // Y da barra de quantidade selecionada (50% da altura)\n const selectedQtyY = suggestionY + segmentHeight + 4;\n const selectedQtyHeight = segmentHeight * 0.5;\n\n const lastRestockX = dateToX(startDate);\n const todayX = dateToX(todayDate);\n const stockEndX = dateToX(stockEndDate);\n const deliveryStartX = dateToX(deliveryDate);\n const restockEndX = dateToX(restockEnd);\n const suggestionStartX = Math.max(deliveryStartX, stockEndX);\n\n // Check alert icon first (está no dia em que a sugestão começa) - só se a barra amarela estiver visível\n if (showSuggestionBarEffective) {\n const alertIconSize = sizeConfig.fontSize + 6;\n const alertIconX =\n suggestionStartX + pixelsPerDay / 2 - alertIconSize / 2;\n const alertIconY = suggestionY - alertIconSize - 4;\n\n const distanceToAlertIcon = Math.sqrt(\n Math.pow(relativeX - (alertIconX + alertIconSize / 2), 2) +\n Math.pow(relativeY - (alertIconY + alertIconSize / 2), 2),\n );\n\n if (distanceToAlertIcon <= alertIconSize / 2 + 4) {\n return \"alertIcon\";\n }\n }\n\n if (\n relativeY < barY ||\n relativeY > barY + fullHeight + selectedQtyHeight + 10\n )\n return null;\n\n // Check selectedQty row (verifica primeiro pois está mais abaixo)\n if (\n typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\"\n ) {\n const selectedQtyStartX = Math.max(deliveryStartX, stockEndX);\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n const selectedQtyEndX = dateToX(selectedQtyEndDate);\n\n if (\n relativeY >= selectedQtyY &&\n relativeY <= selectedQtyY + selectedQtyHeight &&\n relativeX >= selectedQtyStartX &&\n relativeX <= selectedQtyEndX\n ) {\n return \"selectedQty\";\n }\n }\n\n // Check stock row\n if (\n relativeY >= stockY &&\n relativeY <= stockY + segmentHeight &&\n relativeX >= lastRestockX &&\n relativeX <= stockEndX\n ) {\n return \"stock\";\n }\n\n // Check suggestion row (só se a barra amarela estiver visível)\n if (\n showSuggestionBarEffective &&\n relativeY >= suggestionY &&\n relativeY <= suggestionY + segmentHeight &&\n relativeX >= suggestionStartX &&\n relativeX <= restockEndX\n ) {\n return \"suggestion\";\n }\n\n return null;\n },\n [\n dateToX,\n todayDate,\n stockEndDate,\n restockEnd,\n startDate,\n deliveryDate,\n sizeConfig,\n selectedQty,\n selectedQtyDays,\n pixelsPerDay,\n MS_PER_DAY,\n showSuggestionBarEffective,\n ],\n );\n\n // Calcula a largura total do conteúdo e o máximo de scroll (barras até 23:59)\n const endDateCalc = useMemo(() => {\n let maxTime = Math.max(\n restockEnd.getTime(),\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n );\n\n if (typeof selectedQtyDays === \"number\" && selectedQtyDays > 0) {\n const selectedQtyStartDate = new Date(\n Math.max(deliveryDate.getTime(), stockEndDate.getTime()),\n );\n const lastDayOfSelected = new Date(\n selectedQtyStartDate.getTime() + (selectedQtyDays - 1) * MS_PER_DAY,\n );\n const selectedQtyEndDate = getEndOfDay(lastDayOfSelected);\n maxTime = Math.max(maxTime, selectedQtyEndDate.getTime());\n }\n\n const end = new Date(maxTime);\n end.setDate(end.getDate() + 2); // Buffer de 2 dias\n return end;\n }, [restockEnd, deliveryDate, stockEndDate, selectedQtyDays, MS_PER_DAY]);\n\n const totalDaysCalc = useMemo(() => {\n return Math.ceil(\n (endDateCalc.getTime() - startDate.getTime()) / MS_PER_DAY,\n );\n }, [endDateCalc, startDate, MS_PER_DAY]);\n\n const totalContentWidth = useMemo(() => {\n return (\n sizeConfig.padding.left +\n totalDaysCalc * pixelsPerDay +\n sizeConfig.padding.right\n );\n }, [\n totalDaysCalc,\n pixelsPerDay,\n sizeConfig.padding.left,\n sizeConfig.padding.right,\n ]);\n\n // Estado para a largura visível do canvas\n const [canvasWidth, setCanvasWidth] = useState(0);\n\n // Atualiza a largura do canvas quando o container é redimensionado\n useEffect(() => {\n const updateCanvasWidth = () => {\n if (canvasRef.current) {\n setCanvasWidth(canvasRef.current.getBoundingClientRect().width);\n }\n };\n updateCanvasWidth();\n window.addEventListener(\"resize\", updateCanvasWidth);\n return () => window.removeEventListener(\"resize\", updateCanvasWidth);\n }, []);\n\n const maxScrollOffset = useMemo(() => {\n if (canvasWidth === 0) return 0;\n return Math.max(0, totalContentWidth - canvasWidth);\n }, [totalContentWidth, canvasWidth]);\n\n // Ref da barra de scroll (para calcular posição no arraste do thumb)\n const scrollTrackRef = useRef<HTMLDivElement>(null);\n\n // Estado para drag (arrastar o canvas)\n const [isDragging, setIsDragging] = useState(false);\n const isDraggingRef = useRef(false);\n const dragStartXRef = useRef(0);\n const dragStartOffsetRef = useRef(0);\n\n // Estado para drag do thumb da barra de scroll\n const [isScrollBarDragging, setIsScrollBarDragging] = useState(false);\n const isScrollBarDraggingRef = useRef(false);\n\n // Handler de mousedown para iniciar drag\n const handleMouseDown = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n e.preventDefault();\n isDraggingRef.current = true;\n setIsDragging(true);\n dragStartXRef.current = e.clientX;\n dragStartOffsetRef.current = scrollOffset;\n },\n [scrollOffset],\n );\n\n // Handler de touchstart para iniciar drag em mobile\n const handleTouchStart = useCallback(\n (e: React.TouchEvent<HTMLCanvasElement>) => {\n if (e.touches.length === 1) {\n e.preventDefault();\n isDraggingRef.current = true;\n setIsDragging(true);\n dragStartXRef.current = e.touches[0].clientX;\n dragStartOffsetRef.current = scrollOffset;\n }\n },\n [scrollOffset],\n );\n\n // Handlers de mouse (usa ref para drag responder no primeiro mousemove, sem depender do re-render)\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n // Se estiver arrastando, atualiza o scroll offset\n if (isDraggingRef.current && maxScrollOffset > 0) {\n const deltaX = dragStartXRef.current - e.clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n return; // Não atualiza hover durante drag\n }\n\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n\n const hoveredSection = getHoveredSection(e.clientX, e.clientY);\n const dateAtCursor = xToDate(x);\n\n setHoverState({\n isHovering: true,\n hoveredSection,\n mouseX: e.clientX,\n mouseY: e.clientY,\n dateAtCursor,\n });\n\n setTooltipPosition({ x: e.clientX, y: e.clientY });\n },\n [getHoveredSection, xToDate, maxScrollOffset],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHoverState({\n isHovering: false,\n hoveredSection: null,\n mouseX: 0,\n mouseY: 0,\n dateAtCursor: null,\n });\n }, []);\n\n // Handler de mouseup para finalizar drag\n const handleMouseUp = useCallback(() => {\n isDraggingRef.current = false;\n setIsDragging(false);\n }, []);\n\n // Handler de touchmove para drag em mobile\n const handleTouchMove = useCallback(\n (e: React.TouchEvent<HTMLCanvasElement>) => {\n if (\n e.touches.length === 1 &&\n isDraggingRef.current &&\n maxScrollOffset > 0\n ) {\n e.preventDefault();\n const deltaX = dragStartXRef.current - e.touches[0].clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n },\n [maxScrollOffset],\n );\n\n // Handler de touchend para finalizar drag em mobile\n const handleTouchEnd = useCallback(() => {\n isDraggingRef.current = false;\n setIsDragging(false);\n }, []);\n\n // Efeito para adicionar listeners globais de mousemove e mouseup (para drag fora do canvas)\n useEffect(() => {\n const handleGlobalMouseMove = (e: MouseEvent) => {\n if (isDraggingRef.current && maxScrollOffset > 0) {\n const deltaX = dragStartXRef.current - e.clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n };\n\n const handleGlobalMouseUp = () => {\n isDraggingRef.current = false;\n setIsDragging(false);\n };\n\n const handleGlobalTouchMove = (e: TouchEvent) => {\n if (\n e.touches.length === 1 &&\n isDraggingRef.current &&\n maxScrollOffset > 0\n ) {\n e.preventDefault();\n const deltaX = dragStartXRef.current - e.touches[0].clientX;\n const newOffset = dragStartOffsetRef.current + deltaX;\n setScrollOffset(Math.max(0, Math.min(maxScrollOffset, newOffset)));\n }\n };\n\n const handleGlobalTouchEnd = () => {\n isDraggingRef.current = false;\n setIsDragging(false);\n };\n\n if (isDragging) {\n window.addEventListener(\"mousemove\", handleGlobalMouseMove);\n window.addEventListener(\"mouseup\", handleGlobalMouseUp);\n window.addEventListener(\"touchmove\", handleGlobalTouchMove, {\n passive: false,\n });\n window.addEventListener(\"touchend\", handleGlobalTouchEnd);\n }\n\n return () => {\n window.removeEventListener(\"mousemove\", handleGlobalMouseMove);\n window.removeEventListener(\"mouseup\", handleGlobalMouseUp);\n window.removeEventListener(\"touchmove\", handleGlobalTouchMove);\n window.removeEventListener(\"touchend\", handleGlobalTouchEnd);\n };\n }, [isDragging, maxScrollOffset]);\n\n // Atualiza scroll ao arrastar o thumb da barra (thumb segue o mouse e timeline atualiza)\n const updateScrollFromScrollBarMouse = useCallback(\n (clientX: number) => {\n const track = scrollTrackRef.current;\n if (!track || maxScrollOffset <= 0) return;\n const rect = track.getBoundingClientRect();\n const trackWidth = rect.width;\n const thumbWidthPx = (canvasWidth / totalContentWidth) * trackWidth;\n const range = trackWidth - thumbWidthPx;\n if (range <= 0) return;\n const mouseXInTrack = clientX - rect.left;\n const thumbLeft = mouseXInTrack - thumbWidthPx / 2;\n const percentage = Math.max(0, Math.min(1, thumbLeft / range));\n setScrollOffset(percentage * maxScrollOffset);\n },\n [maxScrollOffset, canvasWidth, totalContentWidth],\n );\n\n const handleScrollBarThumbMouseDown = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n isScrollBarDraggingRef.current = true;\n setIsScrollBarDragging(true);\n }, []);\n\n const handleScrollBarThumbTouchStart = useCallback((e: React.TouchEvent) => {\n e.stopPropagation();\n if (e.touches.length === 1) {\n isScrollBarDraggingRef.current = true;\n setIsScrollBarDragging(true);\n }\n }, []);\n\n useEffect(() => {\n const handleGlobalMouseMove = (e: MouseEvent) => {\n if (isScrollBarDraggingRef.current) {\n updateScrollFromScrollBarMouse(e.clientX);\n }\n };\n const handleGlobalMouseUp = () => {\n isScrollBarDraggingRef.current = false;\n setIsScrollBarDragging(false);\n };\n const handleGlobalTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 1 && isScrollBarDraggingRef.current) {\n e.preventDefault();\n updateScrollFromScrollBarMouse(e.touches[0].clientX);\n }\n };\n const handleGlobalTouchEnd = () => {\n isScrollBarDraggingRef.current = false;\n setIsScrollBarDragging(false);\n };\n\n if (isScrollBarDragging) {\n window.addEventListener(\"mousemove\", handleGlobalMouseMove);\n window.addEventListener(\"mouseup\", handleGlobalMouseUp);\n window.addEventListener(\"touchmove\", handleGlobalTouchMove, {\n passive: false,\n });\n window.addEventListener(\"touchend\", handleGlobalTouchEnd);\n }\n return () => {\n window.removeEventListener(\"mousemove\", handleGlobalMouseMove);\n window.removeEventListener(\"mouseup\", handleGlobalMouseUp);\n window.removeEventListener(\"touchmove\", handleGlobalTouchMove);\n window.removeEventListener(\"touchend\", handleGlobalTouchEnd);\n };\n }, [isScrollBarDragging, updateScrollFromScrollBarMouse]);\n\n // Redesenha quando necessário\n useEffect(() => {\n drawCanvas();\n }, [drawCanvas]);\n\n // Redesenha quando a janela é redimensionada ou o container muda de tamanho\n useEffect(() => {\n const handleResize = () => {\n drawCanvas();\n };\n\n window.addEventListener(\"resize\", handleResize);\n\n // Observa mudanças no tamanho do container\n const resizeObserver = new ResizeObserver(() => {\n drawCanvas();\n });\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current);\n }\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n resizeObserver.disconnect();\n };\n }, [drawCanvas]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n position: \"relative\",\n width: \"100%\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n touchAction: \"pan-x pan-y\", // Permite gestos de pan (scroll) em mobile\n ...style,\n }}\n >\n {/* Controles acima do gráfico (não sobrepõem os dias) */}\n {controls && (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: size === \"sm\" ? 6 : 8,\n paddingBottom: 8,\n paddingRight: sizeConfig.padding.right,\n }}\n >\n <button\n type=\"button\"\n onClick={() => setZoomLevelIndex((prev) => Math.max(0, prev - 1))}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background:\n data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 16 : 18,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n >\n -\n </button>\n <button\n type=\"button\"\n onClick={() =>\n setZoomLevelIndex((prev) =>\n Math.min(ZOOM_LEVELS.length - 1, prev + 1),\n )\n }\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background:\n data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 16 : 18,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n >\n +\n </button>\n {/* Botão para mostrar/esconder barra amarela (Sugestão de Compra) */}\n <button\n type=\"button\"\n onClick={() => setSuggestionBarVisible((prev) => !prev)}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background: showSuggestionBarEffective\n ? data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\"\n : data.config.theme === \"dark\"\n ? \"rgba(0,0,0,0.7)\"\n : \"rgba(0,0,0,0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 14 : 16,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n color: showSuggestionBarEffective\n ? data.config.theme === \"dark\"\n ? \"#ECEFF1\"\n : \"#263238\"\n : \"#FFFFFF\",\n fontWeight: \"bold\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n title={\n showSuggestionBarEffective\n ? \"Ocultar barra de sugestão de compra\"\n : \"Mostrar barra de sugestão de compra\"\n }\n >\n S\n </button>\n {/* Botão para mostrar/esconder linha de consumo médio */}\n {data.timeline.dailyConsumptionAverage && (\n <button\n type=\"button\"\n onClick={() => setShowConsumptionLine((prev) => !prev)}\n style={{\n width: size === \"sm\" ? 36 : 44,\n height: size === \"sm\" ? 36 : 44,\n minWidth: size === \"sm\" ? 36 : 44,\n minHeight: size === \"sm\" ? 36 : 44,\n borderRadius: 999,\n border: \"1px solid rgba(0,0,0,0.16)\",\n background: showConsumptionLine\n ? data.config.theme === \"dark\"\n ? \"rgba(0,0,0,0.7)\"\n : \"rgba(0,0,0,0.5)\"\n : data.config.theme === \"dark\"\n ? \"rgba(38,50,56,0.9)\"\n : \"rgba(255,255,255,0.9)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size === \"sm\" ? 14 : 16,\n cursor: \"pointer\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.25)\",\n color: showConsumptionLine\n ? \"#FFFFFF\"\n : data.config.theme === \"dark\"\n ? \"#ECEFF1\"\n : \"#263238\",\n fontWeight: \"bold\",\n touchAction: \"manipulation\",\n WebkitTapHighlightColor: \"transparent\",\n }}\n title={\n showConsumptionLine\n ? \"Ocultar linha de consumo\"\n : \"Mostrar linha de consumo\"\n }\n >\n C\n </button>\n )}\n </div>\n )}\n\n {/* Área do gráfico / canvas */}\n <div\n style={{\n position: \"relative\",\n width: \"100%\",\n minHeight:\n maxScrollOffset > 0\n ? sizeConfig.height + 8 + 15\n : sizeConfig.height,\n }}\n >\n <canvas\n ref={canvasRef}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n style={{\n width: \"100%\",\n height: `${sizeConfig.height}px`,\n display: \"block\",\n cursor:\n maxScrollOffset > 0\n ? isDragging\n ? \"grabbing\"\n : \"grab\"\n : \"pointer\",\n touchAction: \"pan-x\",\n }}\n />\n\n {/* Barra de scroll horizontal (abaixo do canvas para não sobrepor os dias) */}\n {maxScrollOffset > 0 && (\n <div\n ref={scrollTrackRef}\n style={{\n position: \"absolute\",\n top: sizeConfig.height + 8,\n left: 0,\n right: 0,\n height: 15,\n backgroundColor:\n data.config.theme === \"dark\"\n ? \"rgba(255,255,255,0.1)\"\n : \"rgba(0,0,0,0.1)\",\n borderRadius: 7.5,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n }}\n onClick={(e) => {\n if (e.target !== e.currentTarget) return;\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const percentage = clickX / rect.width;\n setScrollOffset(percentage * maxScrollOffset);\n }}\n >\n <div\n role=\"slider\"\n aria-valuenow={scrollOffset}\n aria-valuemin={0}\n aria-valuemax={maxScrollOffset}\n onMouseDown={handleScrollBarThumbMouseDown}\n onTouchStart={handleScrollBarThumbTouchStart}\n style={{\n position: \"absolute\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: `${Math.max(10, (canvasWidth / totalContentWidth) * 100)}%`,\n left: `${\n maxScrollOffset > 0\n ? (scrollOffset / maxScrollOffset) *\n (100 -\n Math.max(10, (canvasWidth / totalContentWidth) * 100))\n : 0\n }%`,\n maxWidth: \"100%\",\n height: 9,\n backgroundColor:\n data.config.theme === \"dark\"\n ? \"rgba(255,255,255,0.4)\"\n : \"rgba(0,0,0,0.3)\",\n borderRadius: 4.5,\n cursor: isScrollBarDragging ? \"grabbing\" : \"grab\",\n transition:\n isDragging || isScrollBarDragging\n ? \"none\"\n : \"left 0.1s ease-out\",\n }}\n />\n </div>\n )}\n </div>\n {hoverState.isHovering &&\n (hoverState.dateAtCursor ||\n hoverState.hoveredSection === \"alertIcon\") &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div\n style={{\n position: \"fixed\",\n left: `${tooltipPosition.x}px`,\n top: `${tooltipPosition.y}px`,\n backgroundColor: COLORS.tooltipBackground,\n color: COLORS.tooltipText,\n padding: \"6px 10px\",\n borderRadius: \"6px\",\n fontSize: \"10px\",\n pointerEvents: \"none\",\n zIndex: 10000,\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.2)\",\n transform: \"translate(-50%, calc(-100% - 10px))\",\n whiteSpace: \"nowrap\",\n }}\n >\n {hoverState.hoveredSection === \"alertIcon\" ? (\n <>\n <div style={{ fontWeight: \"bold\", marginBottom: \"4px\" }}>\n {alertInfo.title}\n </div>\n <div>{alertInfo.message}</div>\n </>\n ) : (\n <>\n <div style={{ fontWeight: \"bold\", marginBottom: \"4px\" }}>\n {hoverState.dateAtCursor &&\n formatDate(hoverState.dateAtCursor)}\n </div>\n {hoverState.dateAtCursor && !hoverState.hoveredSection && (\n <>\n <div style={{ marginBottom: 2 }}>\n {DAY_NAMES[hoverState.dateAtCursor.getDay()]}\n </div>\n <div>\n Consumo médio:{\" \"}\n {(() => {\n const dayOfWeek = hoverState.dateAtCursor.getDay();\n const consumption = getDailyConsumption(dayOfWeek);\n return consumption !== null\n ? `${consumption.toFixed(2)}`\n : \"0.0\";\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"stock\" && (\n <>\n <div style={{ marginBottom: 2 }}>\n {formatDateTime(startDate)} —{\" \"}\n {formatDateTime(stockEndDate)}\n </div>\n <div>\n Estoque disponível até {formatDateTime(stockEndDate)}\n </div>\n <div style={{ marginTop: 2 }}>\n {(() => {\n const totalStockDays = Math.max(\n 0,\n Math.round(\n (stockEndDate.getTime() - startDate.getTime()) /\n MS_PER_DAY,\n ),\n );\n const weight =\n data.timeline.stockWeightKg ??\n data.timeline.restockSuggestionWeight;\n return `${totalStockDays} dia(s) de estoque${\n weight ? ` • ${weight} ${unitLabel}` : \"\"\n }`;\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"suggestion\" && (\n <>\n <div style={{ marginBottom: 2 }}>\n {(() => {\n const suggestionStartDate = new Date(\n Math.max(\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n ),\n );\n return `${formatDateTime(suggestionStartDate)} — ${formatDateTime(restockEnd)}`;\n })()}\n </div>\n <div>Período crítico para compra</div>\n <div style={{ marginTop: 2 }}>\n {(() => {\n const suggestionStartDate = new Date(\n Math.max(\n deliveryDate.getTime(),\n stockEndDate.getTime(),\n ),\n );\n const suggestionDays = Math.max(\n 0,\n Math.round(\n (restockEnd.getTime() -\n suggestionStartDate.getTime()) /\n MS_PER_DAY,\n ),\n );\n const weight = data.timeline.restockSuggestionWeight;\n return `${suggestionDays} dia(s) de sugestão${\n weight ? ` • ${weight} ${unitLabel}` : \"\"\n }`;\n })()}\n </div>\n </>\n )}\n {hoverState.hoveredSection === \"selectedQty\" &&\n typeof selectedQty === \"number\" &&\n typeof selectedQtyDays === \"number\" && (\n <div>\n O estoque selecionado de {selectedQty} deve durar{\" \"}\n {selectedQtyDays % 1 === 0\n ? selectedQtyDays\n : selectedQtyDays.toFixed(1)}{\" \"}\n dia{selectedQtyDays === 1 ? \"\" : \"s\"}\n </div>\n )}\n </>\n )}\n </div>,\n document.body,\n )}\n {showLegend && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n flexWrap: \"wrap\",\n justifyContent: \"flex-end\",\n gap: \"8px\",\n backgroundColor: COLORS.legendBackground,\n padding: \"8px 10px\",\n marginTop: \"8px\",\n borderRadius: \"4px\",\n fontSize: \"10px\",\n color: COLORS.textPrimary,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.stockPast,\n borderRadius: \"2px\",\n }}\n />\n <span>Estoque Passado</span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.stockFuture,\n borderRadius: \"2px\",\n }}\n />\n <span>Previsão Estoque</span>\n </div>\n {showSuggestionBarEffective && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n backgroundColor: COLORS.alert,\n borderRadius: \"2px\",\n }}\n />\n <span>Sugestão Compra</span>\n </div>\n )}\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\n <div\n style={{\n width: \"2px\",\n height: \"10px\",\n borderLeft: `2px dashed ${COLORS.deliveryBar}`,\n marginLeft: \"4px\",\n marginRight: \"4px\",\n }}\n />\n <span>Data Entrega</span>\n </div>\n {typeof selectedQtyDays === \"number\" &&\n selectedQtyDays > 0 &&\n typeof selectedQty === \"number\" && (\n <div\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <div\n style={{\n width: \"10px\",\n height: \"5px\",\n backgroundColor: (COLORS as any).selectedQtyBar,\n borderRadius: \"2px\",\n }}\n />\n <span>Qtd. Selecionada</span>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// Re-exporta os tipos para uso externo\nexport type {\n StockLeadTimeProps,\n TimelineData,\n HoverState,\n Point,\n} from \"./types\";\n"],"names":["THEME_COLORS","SIZE_CONFIG","ensureRoundRect","ctx","x","y","w","h","r","adjustColorBrightness","hex","percent","num","amt","R","G","B","parseDateLocal","dateStr","parts","parseDateTimeLocal","datePart","timePart","date","m","sMs","hour","min","s","ms","parseDateTimeLocalEnd","getEndOfDay","d","eod","getStockAlert","timeline","today","stockEnd","delivery","suggestStart","suggestEnd","daysLate","daysMargin","StockLeadTime","data","className","style","controls","showLegend","size","selectedQty","selectedQtyDays","showSuggestionBarProp","unitLabel","sizeConfig","useMemo","COLORS","alertInfo","DAY_NAMES","getDailyConsumption","useCallback","dayOfWeek","key","canvasRef","useRef","containerRef","hoverState","setHoverState","useState","tooltipPosition","setTooltipPosition","ZOOM_LEVELS","zoomLevelIndex","setZoomLevelIndex","scrollOffset","setScrollOffset","showConsumptionLine","setShowConsumptionLine","suggestionBarVisible","setSuggestionBarVisible","showSuggestionBarEffective","useEffect","startDate","todayDate","stockEndDate","restockStart","restockEnd","deliveryDate","MS_PER_DAY","pixelsPerDay","dateToX","daysDiff","xToDate","daysFromStart","formatDate","formatDateTime","drawCanvas","canvas","dpr","width","height","hoverX","isDark","graphTop","graphHeight","lastRestockX","todayX","stockEndX","deliveryStartX","restockEndX","barY","segmentHeight","stockY","suggestionY","maxTime","selectedQtyStartDateCalc","lastDayOfSelected","selectedQtyEndDateCalc","endDate","totalDays","MONTH_NAMES","getMonthBackgroundColor","monthIndex","isEvenMonth","getDayLabelColor","isWeekend","monthRanges","currentMonth","currentYear","monthStartX","i","month","year","lastDate","graphAreaTop","graphAreaHeight","range","bgStartX","bgWidth","bottomY","monthFont","firstDayOfMonth","firstDayOfMonthX","isFirstDayOfMonthVisible","nextMonthFirstDay","nextMonthFirstDayX","labelX","baseY","dailyConsumption","consumptionValue","consumptionY","dayLabel","dayLabelY","consumptionValues","v","maxConsumption","maxLineHeight","lineAreaBottom","lineAreaHeight","linePoints","consumptionRatio","stockStartX","createGradient","color","gradient","createHorizontalGradient","drawDaysLabelCentered","segmentStartX","segmentEndX","segmentTopY","segmentHeightLocal","label","centerX","centerY","consumedEndDate","consumedEndX","segment1Width","daysPast","labelPast","segment2Width","daysFuture","labelFuture","suggestionStartX","segment3Width","daysSuggestion","labelSuggestion","selectedQtyStartDate","selectedQtyStartX","selectedQtyEndDate","selectedQtyWidth","selectedQtyHeight","selectedQtyY","selectedQtyEndX","drawModernLabel","text","bgColor","metrics","paddingX","pillHeight","pillWidth","todayColumnLeft","todayColumnWidth","graphBottom","todayLabelX","alertIconSize","alertIconX","alertIconY","alertIconColor","iconSymbol","getHoveredSection","clientX","clientY","rect","relativeX","relativeY","fullHeight","endDateCalc","end","totalDaysCalc","totalContentWidth","canvasWidth","setCanvasWidth","updateCanvasWidth","maxScrollOffset","scrollTrackRef","isDragging","setIsDragging","isDraggingRef","dragStartXRef","dragStartOffsetRef","isScrollBarDragging","setIsScrollBarDragging","isScrollBarDraggingRef","handleMouseDown","handleTouchStart","handleMouseMove","deltaX","newOffset","hoveredSection","dateAtCursor","handleMouseLeave","handleMouseUp","handleTouchMove","handleTouchEnd","handleGlobalMouseMove","e","handleGlobalMouseUp","handleGlobalTouchMove","handleGlobalTouchEnd","updateScrollFromScrollBarMouse","track","trackWidth","thumbWidthPx","thumbLeft","percentage","handleScrollBarThumbMouseDown","handleScrollBarThumbTouchStart","handleResize","resizeObserver","jsxs","jsx","prev","createPortal","Fragment","consumption","totalStockDays","weight","suggestionStartDate","suggestionDays"],"mappings":"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"}
|