{"ast":null,"code":"var _jsxFileName = \"/Users/dwindown/CascadeProjects/developer-tools/src/components/Layout.js\",\n _s = $RefreshSig$();\nimport React, { useState, useEffect, useRef } from 'react';\nimport { Link, useLocation } from 'react-router-dom';\nimport { Code2, Home, ChevronDown, Menu, X, Database, FileText, Link as LinkIcon, Hash, FileSpreadsheet, Wand2, GitCompare } from 'lucide-react';\nimport ThemeToggle from './ThemeToggle';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst Layout = ({\n children\n}) => {\n _s();\n const location = useLocation();\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n const dropdownRef = useRef(null);\n const isActive = path => {\n return location.pathname === path;\n };\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = event => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {\n setIsDropdownOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n // Close mobile menu when route changes\n useEffect(() => {\n setIsMobileMenuOpen(false);\n setIsDropdownOpen(false);\n }, [location.pathname]);\n const tools = [{\n path: '/json',\n name: 'JSON Tool',\n icon: FileText,\n description: 'Format & validate JSON'\n }, {\n path: '/serialize',\n name: 'Serialize Tool',\n icon: Database,\n description: 'PHP serialize/unserialize'\n }, {\n path: '/url',\n name: 'URL Tool',\n icon: LinkIcon,\n description: 'URL encode/decode'\n }, {\n path: '/base64',\n name: 'Base64 Tool',\n icon: Hash,\n description: 'Base64 encode/decode'\n }, {\n path: '/csv-json',\n name: 'CSV/JSON Tool',\n icon: FileSpreadsheet,\n description: 'Convert CSV ↔ JSON'\n }, {\n path: '/beautifier',\n name: 'Beautifier Tool',\n icon: Wand2,\n description: 'Beautify/minify code'\n }, {\n path: '/diff',\n name: 'Diff Tool',\n icon: GitCompare,\n description: 'Compare text differences'\n }];\n return /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"min-h-screen bg-gray-50 dark:bg-gray-900\",\n children: [/*#__PURE__*/_jsxDEV(\"header\", {\n className: \"bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"flex justify-between items-center h-16\",\n children: [/*#__PURE__*/_jsxDEV(Link, {\n to: \"/\",\n className: \"flex items-center space-x-2\",\n children: [/*#__PURE__*/_jsxDEV(Code2, {\n className: \"h-8 w-8 text-primary-600\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 53,\n columnNumber: 15\n }, this), /*#__PURE__*/_jsxDEV(\"span\", {\n className: \"text-xl font-bold text-gray-900 dark:text-white\",\n children: \"DevTools\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 54,\n columnNumber: 15\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 52,\n columnNumber: 13\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"flex items-center space-x-4\",\n children: [/*#__PURE__*/_jsxDEV(\"nav\", {\n className: \"hidden md:flex items-center space-x-6\",\n children: [/*#__PURE__*/_jsxDEV(Link, {\n to: \"/\",\n className: `flex items-center space-x-1 px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive('/') ? 'bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300' : 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white'}`,\n children: [/*#__PURE__*/_jsxDEV(Home, {\n className: \"h-4 w-4\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 70,\n columnNumber: 19\n }, this), /*#__PURE__*/_jsxDEV(\"span\", {\n children: \"Home\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 71,\n columnNumber: 19\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 62,\n columnNumber: 17\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"relative\",\n children: [/*#__PURE__*/_jsxDEV(\"button\", {\n onClick: () => setIsDropdownOpen(!isDropdownOpen),\n className: \"flex items-center space-x-1 px-3 py-2 rounded-md text-sm font-medium text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white transition-colors\",\n children: [/*#__PURE__*/_jsxDEV(\"span\", {\n children: \"Tools\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 80,\n columnNumber: 21\n }, this), /*#__PURE__*/_jsxDEV(ChevronDown, {\n className: `h-4 w-4 transition-transform ${isDropdownOpen ? 'rotate-180' : ''}`\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 81,\n columnNumber: 21\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 76,\n columnNumber: 19\n }, this), isDropdownOpen && /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"absolute top-full left-0 mt-2 w-64 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-2 z-50\",\n children: tools.map(tool => {\n const IconComponent = tool.icon;\n return /*#__PURE__*/_jsxDEV(Link, {\n to: tool.path,\n onClick: () => setIsDropdownOpen(false),\n className: `flex items-center space-x-3 px-4 py-3 text-sm hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors ${isActive(tool.path) ? 'bg-primary-50 text-primary-700 dark:bg-primary-900 dark:text-primary-300' : 'text-gray-700 dark:text-gray-300'}`,\n children: [/*#__PURE__*/_jsxDEV(IconComponent, {\n className: \"h-4 w-4\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 102,\n columnNumber: 29\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n children: [/*#__PURE__*/_jsxDEV(\"div\", {\n className: \"font-medium\",\n children: tool.name\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 104,\n columnNumber: 31\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"text-xs text-gray-500 dark:text-gray-400\",\n children: tool.description\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 105,\n columnNumber: 31\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 103,\n columnNumber: 29\n }, this)]\n }, tool.path, true, {\n fileName: _jsxFileName,\n lineNumber: 92,\n columnNumber: 27\n }, this);\n })\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 88,\n columnNumber: 21\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 75,\n columnNumber: 17\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 61,\n columnNumber: 15\n }, this), /*#__PURE__*/_jsxDEV(ThemeToggle, {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 115,\n columnNumber: 15\n }, this), /*#__PURE__*/_jsxDEV(\"button\", {\n onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen),\n className: \"md:hidden p-2 rounded-md text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white transition-colors\",\n children: isMobileMenuOpen ? /*#__PURE__*/_jsxDEV(X, {\n className: \"h-6 w-6\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 122,\n columnNumber: 37\n }, this) : /*#__PURE__*/_jsxDEV(Menu, {\n className: \"h-6 w-6\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 122,\n columnNumber: 65\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 118,\n columnNumber: 15\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 59,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 51,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 50,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 49,\n columnNumber: 7\n }, this), isMobileMenuOpen && /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"md:hidden bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"space-y-2\",\n children: [/*#__PURE__*/_jsxDEV(Link, {\n to: \"/\",\n onClick: () => setIsMobileMenuOpen(false),\n className: `flex items-center space-x-3 px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive('/') ? 'bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300' : 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white'}`,\n children: [/*#__PURE__*/_jsxDEV(Home, {\n className: \"h-5 w-5\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 143,\n columnNumber: 17\n }, this), /*#__PURE__*/_jsxDEV(\"span\", {\n children: \"Home\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 144,\n columnNumber: 17\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 134,\n columnNumber: 15\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"border-t border-gray-200 dark:border-gray-700 pt-2 mt-2\",\n children: [/*#__PURE__*/_jsxDEV(\"div\", {\n className: \"text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider px-3 py-1\",\n children: \"Tools\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 148,\n columnNumber: 17\n }, this), tools.map(tool => {\n const IconComponent = tool.icon;\n return /*#__PURE__*/_jsxDEV(Link, {\n to: tool.path,\n onClick: () => setIsMobileMenuOpen(false),\n className: `flex items-center space-x-3 px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive(tool.path) ? 'bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300' : 'text-gray-600 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white'}`,\n children: [/*#__PURE__*/_jsxDEV(IconComponent, {\n className: \"h-5 w-5\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 164,\n columnNumber: 23\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n children: [/*#__PURE__*/_jsxDEV(\"div\", {\n className: \"font-medium\",\n children: tool.name\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 166,\n columnNumber: 25\n }, this), /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"text-xs text-gray-500 dark:text-gray-400\",\n children: tool.description\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 167,\n columnNumber: 25\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 165,\n columnNumber: 23\n }, this)]\n }, tool.path, true, {\n fileName: _jsxFileName,\n lineNumber: 154,\n columnNumber: 21\n }, this);\n })]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 147,\n columnNumber: 15\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 133,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 132,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 131,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(\"main\", {\n className: \"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\",\n children: children\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 179,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(\"footer\", {\n className: \"bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 mt-16\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8\",\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n className: \"text-center text-gray-600 dark:text-gray-400\",\n children: /*#__PURE__*/_jsxDEV(\"p\", {\n children: [\"\\xA9 \", new Date().getFullYear(), \" Dewe Toolsites - Developer Tools.\"]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 187,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 186,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 185,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 184,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 47,\n columnNumber: 5\n }, this);\n};\n_s(Layout, \"UuGVBSioUY9Dm7/zhJaEgul4HKY=\", false, function () {\n return [useLocation];\n});\n_c = Layout;\nexport default Layout;\nvar _c;\n$RefreshReg$(_c, \"Layout\");","map":{"version":3,"names":["React","useState","useEffect","useRef","Link","useLocation","Code2","Home","ChevronDown","Menu","X","Database","FileText","LinkIcon","Hash","FileSpreadsheet","Wand2","GitCompare","ThemeToggle","jsxDEV","_jsxDEV","Layout","children","_s","location","isDropdownOpen","setIsDropdownOpen","isMobileMenuOpen","setIsMobileMenuOpen","dropdownRef","isActive","path","pathname","handleClickOutside","event","current","contains","target","document","addEventListener","removeEventListener","tools","name","icon","description","className","to","fileName","_jsxFileName","lineNumber","columnNumber","onClick","map","tool","IconComponent","Date","getFullYear","_c","$RefreshReg$"],"sources":["/Users/dwindown/CascadeProjects/developer-tools/src/components/Layout.js"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { Link, useLocation } from 'react-router-dom';\nimport { Code2, Home, ChevronDown, Menu, X, Database, FileText, Link as LinkIcon, Hash, FileSpreadsheet, Wand2, GitCompare } from 'lucide-react';\nimport ThemeToggle from './ThemeToggle';\n\nconst Layout = ({ children }) => {\n const location = useLocation();\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);\n const dropdownRef = useRef(null);\n \n const isActive = (path) => {\n return location.pathname === path;\n };\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {\n setIsDropdownOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n // Close mobile menu when route changes\n useEffect(() => {\n setIsMobileMenuOpen(false);\n setIsDropdownOpen(false);\n }, [location.pathname]);\n\n const tools = [\n { path: '/json', name: 'JSON Tool', icon: FileText, description: 'Format & validate JSON' },\n { path: '/serialize', name: 'Serialize Tool', icon: Database, description: 'PHP serialize/unserialize' },\n { path: '/url', name: 'URL Tool', icon: LinkIcon, description: 'URL encode/decode' },\n { path: '/base64', name: 'Base64 Tool', icon: Hash, description: 'Base64 encode/decode' },\n { path: '/csv-json', name: 'CSV/JSON Tool', icon: FileSpreadsheet, description: 'Convert CSV ↔ JSON' },\n { path: '/beautifier', name: 'Beautifier Tool', icon: Wand2, description: 'Beautify/minify code' },\n { path: '/diff', name: 'Diff Tool', icon: GitCompare, description: 'Compare text differences' }\n ];\n\n return (\n