{"version":3,"file":"CuAT0QVA.js","sources":["../../../../../../src/lib/utils/principalUtils.ts","../../../../../../src/lib/api/transactions.ts","../../../../../../src/lib/utils/clipboard.ts","../../../../../../src/lib/utils/dateFormatters.ts"],"sourcesContent":["/**\n * Generates a consistent color from a principal ID using a hash function\n * @param principalId The principal ID to generate a color for\n * @returns An HSL color string\n */\nexport function getPrincipalColor(principalId: string): string {\n // Use a simple hash function to generate a number from the string\n const hash = principalId.split('').reduce((acc, char) => {\n return char.charCodeAt(0) + ((acc << 5) - acc);\n }, 0);\n \n const hue = Math.abs(hash % 360);\n \n // Check if we're in dark mode\n const isDarkMode = document.documentElement.classList.contains('dark') || document.documentElement.classList.contains('plain-black');\n \n if (isDarkMode) {\n // Dark mode: More saturated, darker colors\n return `hsl(${hue}, 70%, 25%)`;\n } else {\n // Light mode: Less saturated, lighter colors\n return `hsl(${hue}, 60%, 75%)`;\n }\n} \n\nexport function truncateAddress(address: string): string {\n if (typeof address !== \"string\") {\n return \"\";\n }\n return `${address.substring(0, 6)}...${address.substring(address.length - 4)}`;\n}\n","import { API_URL } from \"$lib/api/index\";\n\nexport async function fetchTransactions(\n canisterId: string | number, \n page: number, \n limit: number,\n options: { signal?: AbortSignal } = {}\n): Promise {\n // Handle both string and number IDs\n const idParam = typeof canisterId === 'string' ? canisterId : canisterId.toString();\n const url = `${API_URL}/api/tokens/${idParam}/transactions?page=${page}&limit=${limit}`;\n \n try {\n const response = await fetch(url, {\n signal: options.signal\n });\n \n // Get the response text first\n const responseText = await response.text();\n \n // Check for specific error messages\n if (responseText.includes(\"Token not\")) {\n console.error('Token not found:', idParam);\n return []; // Return empty array instead of throwing\n }\n \n // If not OK and not a token error, throw with status\n if (!response.ok) {\n console.error('Transaction fetch error:', {\n status: response.status,\n statusText: response.statusText,\n body: responseText\n });\n return []; // Return empty array for any error\n }\n\n // Try to parse as JSON\n let data;\n try {\n data = JSON.parse(responseText);\n } catch (e) {\n console.error('Invalid JSON response:', responseText);\n return []; // Return empty array for parse errors\n }\n \n // Validate and transform the response data\n if (!data || !Array.isArray(data.items)) {\n console.error('Invalid response structure:', data);\n return [];\n }\n\n // Filter out any transactions without required fields\n const transactions = data.items\n .filter(tx => tx.tx_id && (tx.ts || tx.timestamp)) // Check for either timestamp field\n .map(tx => ({\n ...tx,\n tx_id: tx.tx_id,\n timestamp: tx.ts || tx.timestamp // Use ts if available, fallback to timestamp\n }));\n\n return transactions;\n } catch (error) {\n // If the request was aborted, rethrow the error\n if (error instanceof Error && error.name === 'AbortError') {\n throw error;\n }\n console.error('Transaction fetch error:', error);\n return []; // Return empty array for any other errors\n }\n} \n\nexport interface CandleData {\n candle_start: number;\n open_price: string | number;\n high_price: string | number;\n low_price: string | number;\n close_price: string | number;\n volume: string | number;\n}\n\nexport const fetchChartData = async (\n payTokenId: number,\n receiveTokenId: number,\n startTimestamp: number,\n endTimestamp: number,\n resolution: string\n): Promise => {\n // Convert timestamps to ISO format\n const startTime = new Date(startTimestamp * 1000).toISOString();\n const endTime = new Date(endTimestamp * 1000).toISOString();\n \n const intervalMap: Record = {\n '1m': '1',\n '5': '5',\n '15': '15',\n '30': '30',\n '60': '1h',\n '240': '4h',\n '1D': '1d',\n 'D': '1d',\n '1W': '1w',\n 'W': '1w'\n };\n const interval = intervalMap[resolution] || '1d';\n\n const url = `${API_URL}/api/swaps/ohlc?pay_token_id=${payTokenId}&receive_token_id=${receiveTokenId}&start_time=${startTime}&end_time=${endTime}&interval=${interval}`;\n \n try {\n const response = await fetch(url);\n const data = await response.json();\n \n if (!response.ok) {\n console.error('API error:', data);\n return [];\n }\n \n // Parse and transform the data\n if (Array.isArray(data)) {\n const processedData = data.map(candle => {\n // Parse the ISO string to UTC timestamp in milliseconds\n const timestamp = Date.parse(candle.candle_start);\n \n return {\n candle_start: timestamp, // Store as milliseconds timestamp\n open_price: candle.open_price,\n high_price: candle.high_price,\n low_price: candle.low_price,\n close_price: candle.close_price,\n volume: candle.volume || 0\n };\n });\n \n return processedData\n .filter(candle => !isNaN(candle.candle_start)) // Remove any invalid timestamps\n }\n \n return [];\n } catch (error) {\n console.error('Error fetching chart data:', error);\n return [];\n }\n};","import { toastStore } from \"$lib/stores/toastStore\";\n\nexport async function copyToClipboard(text: string) {\n try {\n await navigator.clipboard.writeText(text);\n toastStore.info(\"Copied to clipboard\");\n } catch (err) {\n console.error('Failed to copy text: ', err);\n }\n} ","export function formatTimestamp(timestamp: string): string {\n if (!timestamp) {\n return \"N/A\";\n }\n\n try {\n let txDate: Date;\n \n // Check if the timestamp is a Unix timestamp (milliseconds)\n if (/^\\d{13}$/.test(timestamp)) {\n txDate = new Date(parseInt(timestamp));\n } else {\n // Handle ISO string format\n txDate = new Date(timestamp.endsWith('Z') ? timestamp : timestamp + 'Z');\n }\n \n // Validate that we have a valid date\n if (isNaN(txDate.getTime())) {\n console.warn(\"Invalid date value received:\", timestamp);\n return \"N/A\";\n }\n\n // Check if the date is in the future\n const now = new Date();\n if (txDate > now) {\n console.warn(\"Future timestamp detected, using current time:\", timestamp);\n txDate = now;\n }\n \n // Format in local timezone with date and time\n const formatter = new Intl.DateTimeFormat('en-US', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n hour12: true,\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone // Use local timezone\n });\n\n return formatter.format(txDate);\n } catch (e) {\n console.error(\"Error formatting timestamp:\", e, \"Input:\", timestamp);\n return \"N/A\";\n }\n} \n\nexport function formatDate(date: Date): string {\n return new Date(date).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n });\n}"],"names":["getPrincipalColor","principalId","hash","split","reduce","acc","char","charCodeAt","hue","Math","abs","document","documentElement","classList","contains","truncateAddress","address","substring","length","async","fetchTransactions","canisterId","page","limit","options","idParam","toString","url","API_URL","response","fetch","signal","responseText","text","includes","console","error","ok","status","statusText","body","data","JSON","parse","e","Array","isArray","items","filter","tx","tx_id","ts","timestamp","map","Error","name","fetchChartData","payTokenId","receiveTokenId","startTimestamp","endTimestamp","resolution","startTime","Date","toISOString","endTime","D","W","json","candle","candle_start","open_price","high_price","low_price","close_price","volume","isNaN","copyToClipboard","navigator","clipboard","writeText","toastStore","info","err","formatTimestamp","txDate","test","parseInt","endsWith","getTime","warn","now","Intl","DateTimeFormat","month","day","hour","minute","hour12","timeZone","resolvedOptions","format","formatDate","date","toLocaleDateString","year"],"mappings":"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"}