@flexireact/core 3.0.3 ā 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cli/index.js +14 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/core/build/index.js +689 -0
- package/dist/core/build/index.js.map +1 -0
- package/dist/core/config.js +86 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/start-dev.js +3092 -0
- package/dist/core/start-dev.js.map +1 -0
- package/dist/core/start-prod.js +3092 -0
- package/dist/core/start-prod.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../core/build/index.ts","../../../core/utils.ts","../../../core/router/index.ts"],"sourcesContent":["/**\r\n * FlexiReact Build System\r\n * Uses esbuild for fast bundling of client and server code\r\n */\r\n\r\nimport * as esbuild from 'esbuild';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport { findFiles, ensureDir, cleanDir, generateHash, isClientComponent, isIsland } from '../utils.js';\r\nimport { buildRouteTree } from '../router/index.js';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = path.dirname(__filename);\r\n\r\n/**\r\n * Build configuration\r\n */\r\nexport const BuildMode = {\r\n DEVELOPMENT: 'development',\r\n PRODUCTION: 'production'\r\n};\r\n\r\n/**\r\n * Main build function\r\n */\r\nexport async function build(options) {\r\n const {\r\n projectRoot,\r\n config,\r\n mode = BuildMode.PRODUCTION,\r\n analyze = false\r\n } = options;\r\n\r\n const startTime = Date.now();\r\n const outDir = config.outDir;\r\n const isDev = mode === BuildMode.DEVELOPMENT;\r\n\r\n console.log('\\nā” FlexiReact Build\\n');\r\n console.log(` Mode: ${mode}`);\r\n console.log(` Output: ${outDir}\\n`);\r\n\r\n // Clean output directory\r\n cleanDir(outDir);\r\n ensureDir(path.join(outDir, 'client'));\r\n ensureDir(path.join(outDir, 'server'));\r\n ensureDir(path.join(outDir, 'static'));\r\n\r\n // Build routes\r\n const routes = buildRouteTree(config.pagesDir, config.layoutsDir);\r\n \r\n // Find all client components and islands\r\n const clientEntries = findClientEntries(config.pagesDir, config.layoutsDir);\r\n \r\n // Build client bundle\r\n console.log('š¦ Building client bundle...');\r\n const clientResult = await buildClient({\r\n entries: clientEntries,\r\n outDir: path.join(outDir, 'client'),\r\n config,\r\n isDev\r\n });\r\n\r\n // Build server bundle\r\n console.log('š¦ Building server bundle...');\r\n const serverResult = await buildServer({\r\n pagesDir: config.pagesDir,\r\n layoutsDir: config.layoutsDir,\r\n outDir: path.join(outDir, 'server'),\r\n config,\r\n isDev\r\n });\r\n\r\n // Copy public assets\r\n console.log('š Copying public assets...');\r\n await copyPublicAssets(config.publicDir, path.join(outDir, 'static'));\r\n\r\n // Generate manifest\r\n const manifest = generateManifest({\r\n routes,\r\n clientResult,\r\n serverResult,\r\n config\r\n });\r\n \r\n fs.writeFileSync(\r\n path.join(outDir, 'manifest.json'),\r\n JSON.stringify(manifest, null, 2)\r\n );\r\n\r\n const duration = Date.now() - startTime;\r\n \r\n console.log('\\n⨠Build complete!\\n');\r\n console.log(` Duration: ${duration}ms`);\r\n console.log(` Client chunks: ${clientResult.outputs.length}`);\r\n console.log(` Server modules: ${serverResult.outputs.length}`);\r\n console.log('');\r\n\r\n // Generate bundle analysis if requested\r\n let analysis = null;\r\n if (analyze) {\r\n analysis = generateBundleAnalysis(clientResult, serverResult, outDir);\r\n }\r\n\r\n return {\r\n success: true,\r\n duration,\r\n manifest,\r\n clientResult,\r\n serverResult,\r\n analysis\r\n };\r\n}\r\n\r\n/**\r\n * Generates bundle analysis data\r\n */\r\nfunction generateBundleAnalysis(clientResult, serverResult, outDir) {\r\n const files: Record<string, { size: number; gzipSize?: number }> = {};\r\n let totalSize = 0;\r\n let totalGzipSize = 0;\r\n\r\n // Analyze client outputs\r\n for (const output of clientResult.outputs || []) {\r\n if (output.path && fs.existsSync(output.path)) {\r\n const stat = fs.statSync(output.path);\r\n const relativePath = path.relative(outDir, output.path);\r\n \r\n // Estimate gzip size (roughly 30% of original for JS)\r\n const gzipSize = Math.round(stat.size * 0.3);\r\n \r\n files[relativePath] = {\r\n size: stat.size,\r\n gzipSize\r\n };\r\n \r\n totalSize += stat.size;\r\n totalGzipSize += gzipSize;\r\n }\r\n }\r\n\r\n // Analyze server outputs\r\n for (const output of serverResult.outputs || []) {\r\n if (output.path && fs.existsSync(output.path)) {\r\n const stat = fs.statSync(output.path);\r\n const relativePath = path.relative(outDir, output.path);\r\n \r\n files[relativePath] = {\r\n size: stat.size\r\n };\r\n \r\n totalSize += stat.size;\r\n }\r\n }\r\n\r\n return {\r\n files,\r\n totalSize,\r\n totalGzipSize,\r\n clientSize: clientResult.outputs?.reduce((sum, o) => {\r\n if (o.path && fs.existsSync(o.path)) {\r\n return sum + fs.statSync(o.path).size;\r\n }\r\n return sum;\r\n }, 0) || 0,\r\n serverSize: serverResult.outputs?.reduce((sum, o) => {\r\n if (o.path && fs.existsSync(o.path)) {\r\n return sum + fs.statSync(o.path).size;\r\n }\r\n return sum;\r\n }, 0) || 0\r\n };\r\n}\r\n\r\n/**\r\n * Finds all client component entries\r\n */\r\nfunction findClientEntries(pagesDir, layoutsDir) {\r\n const entries = [];\r\n const dirs = [pagesDir, layoutsDir].filter(d => fs.existsSync(d));\r\n\r\n for (const dir of dirs) {\r\n const files = findFiles(dir, /\\.(jsx|tsx)$/);\r\n \r\n for (const file of files) {\r\n if (isClientComponent(file) || isIsland(file)) {\r\n entries.push(file);\r\n }\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n\r\n/**\r\n * Builds client-side JavaScript\r\n */\r\nasync function buildClient(options) {\r\n const { entries, outDir, config, isDev } = options;\r\n\r\n if (entries.length === 0) {\r\n return { outputs: [] };\r\n }\r\n\r\n // Create entry points map\r\n const entryPoints = {};\r\n for (const entry of entries) {\r\n const name = path.basename(entry, path.extname(entry));\r\n const hash = generateHash(entry);\r\n entryPoints[`${name}-${hash}`] = entry;\r\n }\r\n\r\n // Add runtime entry\r\n const runtimePath = path.join(__dirname, '..', 'client', 'runtime.js');\r\n if (fs.existsSync(runtimePath)) {\r\n entryPoints['runtime'] = runtimePath;\r\n }\r\n\r\n try {\r\n const result = await esbuild.build({\r\n entryPoints,\r\n bundle: true,\r\n splitting: true,\r\n format: 'esm',\r\n outdir: outDir,\r\n minify: !isDev && config.build.minify,\r\n sourcemap: config.build.sourcemap,\r\n target: config.build.target,\r\n jsx: 'automatic',\r\n jsxImportSource: 'react',\r\n metafile: true,\r\n external: [],\r\n define: {\r\n 'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production')\r\n },\r\n loader: {\r\n '.js': 'jsx',\r\n '.jsx': 'jsx',\r\n '.ts': 'tsx',\r\n '.tsx': 'tsx'\r\n }\r\n });\r\n\r\n const outputs = Object.keys(result.metafile.outputs).map(file => ({\r\n file: path.basename(file),\r\n size: result.metafile.outputs[file].bytes\r\n }));\r\n\r\n return { outputs, metafile: result.metafile };\r\n\r\n } catch (error) {\r\n console.error('Client build failed:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Builds server-side modules\r\n */\r\nasync function buildServer(options) {\r\n const { pagesDir, layoutsDir, outDir, config, isDev } = options;\r\n\r\n const entries = [];\r\n \r\n // Find all page and layout files\r\n for (const dir of [pagesDir, layoutsDir]) {\r\n if (fs.existsSync(dir)) {\r\n entries.push(...findFiles(dir, /\\.(jsx|tsx|js|ts)$/));\r\n }\r\n }\r\n\r\n if (entries.length === 0) {\r\n return { outputs: [] };\r\n }\r\n\r\n // Create entry points\r\n const entryPoints = {};\r\n for (const entry of entries) {\r\n const relativePath = path.relative(pagesDir, entry);\r\n const name = relativePath.replace(/[\\/\\\\]/g, '_').replace(/\\.(jsx|tsx|js|ts)$/, '');\r\n entryPoints[name] = entry;\r\n }\r\n\r\n try {\r\n const result = await esbuild.build({\r\n entryPoints,\r\n bundle: true,\r\n format: 'esm',\r\n platform: 'node',\r\n outdir: outDir,\r\n minify: false, // Keep server code readable\r\n sourcemap: true,\r\n target: 'node18',\r\n jsx: 'automatic',\r\n jsxImportSource: 'react',\r\n metafile: true,\r\n packages: 'external', // Don't bundle node_modules\r\n loader: {\r\n '.js': 'jsx',\r\n '.jsx': 'jsx',\r\n '.ts': 'tsx',\r\n '.tsx': 'tsx'\r\n }\r\n });\r\n\r\n const outputs = Object.keys(result.metafile.outputs).map(file => ({\r\n file: path.basename(file),\r\n size: result.metafile.outputs[file].bytes\r\n }));\r\n\r\n return { outputs, metafile: result.metafile };\r\n\r\n } catch (error) {\r\n console.error('Server build failed:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Copies public assets to output directory\r\n */\r\nasync function copyPublicAssets(publicDir, outDir) {\r\n if (!fs.existsSync(publicDir)) {\r\n return;\r\n }\r\n\r\n const copyRecursive = (src, dest) => {\r\n const entries = fs.readdirSync(src, { withFileTypes: true });\r\n \r\n ensureDir(dest);\r\n \r\n for (const entry of entries) {\r\n const srcPath = path.join(src, entry.name);\r\n const destPath = path.join(dest, entry.name);\r\n \r\n if (entry.isDirectory()) {\r\n copyRecursive(srcPath, destPath);\r\n } else {\r\n fs.copyFileSync(srcPath, destPath);\r\n }\r\n }\r\n };\r\n\r\n copyRecursive(publicDir, outDir);\r\n}\r\n\r\n/**\r\n * Generates build manifest\r\n */\r\nfunction generateManifest(options) {\r\n const { routes, clientResult, serverResult, config } = options;\r\n\r\n return {\r\n version: '2.0.0',\r\n generatedAt: new Date().toISOString(),\r\n routes: {\r\n pages: routes.pages.map(r => ({\r\n path: r.path,\r\n file: r.filePath,\r\n hasLayout: !!r.layout,\r\n hasLoading: !!r.loading,\r\n hasError: !!r.error\r\n })),\r\n api: routes.api.map(r => ({\r\n path: r.path,\r\n file: r.filePath\r\n }))\r\n },\r\n client: {\r\n chunks: clientResult.outputs || []\r\n },\r\n server: {\r\n modules: serverResult.outputs || []\r\n },\r\n config: {\r\n islands: config.islands.enabled,\r\n rsc: config.rsc.enabled\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Development build with watch mode\r\n */\r\nexport async function buildDev(options) {\r\n const { projectRoot, config, onChange } = options;\r\n\r\n const outDir = config.outDir;\r\n ensureDir(outDir);\r\n\r\n // Use esbuild's watch mode\r\n const ctx = await esbuild.context({\r\n entryPoints: findFiles(config.pagesDir, /\\.(jsx|tsx)$/),\r\n bundle: true,\r\n format: 'esm',\r\n outdir: path.join(outDir, 'dev'),\r\n sourcemap: true,\r\n jsx: 'automatic',\r\n jsxImportSource: 'react',\r\n loader: {\r\n '.js': 'jsx',\r\n '.jsx': 'jsx'\r\n },\r\n plugins: [{\r\n name: 'flexi-watch',\r\n setup(build) {\r\n build.onEnd(result => {\r\n if (result.errors.length === 0) {\r\n onChange?.();\r\n }\r\n });\r\n }\r\n }]\r\n });\r\n\r\n await ctx.watch();\r\n\r\n return ctx;\r\n}\r\n\r\nexport default {\r\n build,\r\n buildDev,\r\n BuildMode\r\n};\r\n","/**\r\n * FlexiReact Utility Functions\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport crypto from 'crypto';\r\n\r\n/**\r\n * Generates a unique hash for cache busting\r\n */\r\nexport function generateHash(content) {\r\n return crypto.createHash('md5').update(content).digest('hex').slice(0, 8);\r\n}\r\n\r\n/**\r\n * Escapes HTML special characters\r\n */\r\nexport function escapeHtml(str) {\r\n const htmlEntities = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": '''\r\n };\r\n return String(str).replace(/[&<>\"']/g, char => htmlEntities[char]);\r\n}\r\n\r\n/**\r\n * Recursively finds all files matching a pattern\r\n */\r\nexport function findFiles(dir, pattern, files = []) {\r\n if (!fs.existsSync(dir)) return files;\r\n \r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n \r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n \r\n if (entry.isDirectory()) {\r\n findFiles(fullPath, pattern, files);\r\n } else if (pattern.test(entry.name)) {\r\n files.push(fullPath);\r\n }\r\n }\r\n \r\n return files;\r\n}\r\n\r\n/**\r\n * Ensures a directory exists\r\n */\r\nexport function ensureDir(dir) {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n}\r\n\r\n/**\r\n * Cleans a directory\r\n */\r\nexport function cleanDir(dir) {\r\n if (fs.existsSync(dir)) {\r\n fs.rmSync(dir, { recursive: true, force: true });\r\n }\r\n fs.mkdirSync(dir, { recursive: true });\r\n}\r\n\r\n/**\r\n * Copies a directory recursively\r\n */\r\nexport function copyDir(src, dest) {\r\n ensureDir(dest);\r\n \r\n const entries = fs.readdirSync(src, { withFileTypes: true });\r\n \r\n for (const entry of entries) {\r\n const srcPath = path.join(src, entry.name);\r\n const destPath = path.join(dest, entry.name);\r\n \r\n if (entry.isDirectory()) {\r\n copyDir(srcPath, destPath);\r\n } else {\r\n fs.copyFileSync(srcPath, destPath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Debounce function for file watching\r\n */\r\nexport function debounce(fn, delay) {\r\n let timeout;\r\n return (...args) => {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => fn(...args), delay);\r\n };\r\n}\r\n\r\n/**\r\n * Formats bytes to human readable string\r\n */\r\nexport function formatBytes(bytes) {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\r\n}\r\n\r\n/**\r\n * Formats milliseconds to human readable string\r\n */\r\nexport function formatTime(ms) {\r\n if (ms < 1000) return `${ms}ms`;\r\n return `${(ms / 1000).toFixed(2)}s`;\r\n}\r\n\r\n/**\r\n * Creates a deferred promise\r\n */\r\nexport function createDeferred() {\r\n let resolve, reject;\r\n const promise = new Promise((res, rej) => {\r\n resolve = res;\r\n reject = rej;\r\n });\r\n return { promise, resolve, reject };\r\n}\r\n\r\n/**\r\n * Sleep utility\r\n */\r\nexport function sleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Check if a file is a server component (has 'use server' directive)\r\n */\r\nexport function isServerComponent(filePath) {\r\n try {\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const firstLine = content.split('\\n')[0].trim();\r\n return firstLine === \"'use server'\" || firstLine === '\"use server\"';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a file is a client component (has 'use client' directive)\r\n */\r\nexport function isClientComponent(filePath) {\r\n try {\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const firstLine = content.split('\\n')[0].trim();\r\n return firstLine === \"'use client'\" || firstLine === '\"use client\"';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a component is an island (has 'use island' directive)\r\n */\r\nexport function isIsland(filePath) {\r\n try {\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n const firstLine = content.split('\\n')[0].trim();\r\n return firstLine === \"'use island'\" || firstLine === '\"use island\"';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n","/**\r\n * FlexiReact Router v2\r\n * Advanced file-based routing with nested routes, loading, and error boundaries\r\n * \r\n * Supports multiple routing conventions:\r\n * - pages/ : Traditional file-based routing (index.tsx, about.tsx)\r\n * - app/ : Next.js style App Router (page.tsx, layout.tsx)\r\n * - routes/ : FlexiReact v2 routes directory (home.tsx ā /, [slug].tsx ā /:slug)\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { isServerComponent, isClientComponent, isIsland } from '../utils.js';\r\n\r\n/**\r\n * Route types\r\n */\r\nexport const RouteType = {\r\n PAGE: 'page',\r\n API: 'api',\r\n LAYOUT: 'layout',\r\n LOADING: 'loading',\r\n ERROR: 'error',\r\n NOT_FOUND: 'not-found'\r\n};\r\n\r\n/**\r\n * Builds the complete route tree from all routing directories\r\n */\r\nexport function buildRouteTree(pagesDir, layoutsDir, appDir = null, routesDir = null) {\r\n const projectRoot = path.dirname(pagesDir);\r\n \r\n const routes: {\r\n pages: any[];\r\n api: any[];\r\n layouts: Map<any, any>;\r\n tree: Record<string, any>;\r\n appRoutes: any[];\r\n flexiRoutes: any[];\r\n rootLayout?: string;\r\n } = {\r\n pages: [],\r\n api: [],\r\n layouts: new Map(),\r\n tree: {},\r\n appRoutes: [], // Next.js style app router routes\r\n flexiRoutes: [] // FlexiReact v2 routes/ directory\r\n };\r\n\r\n // 1. Scan routes/ directory (FlexiReact v2 - priority)\r\n const routesDirPath = routesDir || path.join(projectRoot, 'routes');\r\n if (fs.existsSync(routesDirPath)) {\r\n scanRoutesDirectory(routesDirPath, routesDirPath, routes);\r\n }\r\n\r\n // 2. Scan app/ directory (Next.js style App Router)\r\n const appDirPath = appDir || path.join(projectRoot, 'app');\r\n if (fs.existsSync(appDirPath)) {\r\n scanAppDirectory(appDirPath, appDirPath, routes);\r\n }\r\n\r\n // 3. Scan pages/ directory (traditional routing - fallback)\r\n if (fs.existsSync(pagesDir)) {\r\n scanDirectory(pagesDir, pagesDir, routes);\r\n }\r\n \r\n // 4. Scan layouts/ directory\r\n if (fs.existsSync(layoutsDir)) {\r\n scanLayouts(layoutsDir, routes.layouts);\r\n }\r\n\r\n // 5. Check for root layout in app/ directory\r\n const rootLayoutPath = path.join(appDirPath, 'layout.tsx');\r\n const rootLayoutPathJs = path.join(appDirPath, 'layout.jsx');\r\n if (fs.existsSync(rootLayoutPath)) {\r\n routes.rootLayout = rootLayoutPath;\r\n } else if (fs.existsSync(rootLayoutPathJs)) {\r\n routes.rootLayout = rootLayoutPathJs;\r\n }\r\n\r\n // Build route tree for nested routes\r\n routes.tree = buildTree([...routes.flexiRoutes, ...routes.appRoutes, ...routes.pages]);\r\n\r\n return routes;\r\n}\r\n\r\n/**\r\n * Scans routes/ directory for FlexiReact v2 style routing\r\n * \r\n * Convention:\r\n * - home.tsx ā /\r\n * - about.tsx ā /about\r\n * - blog/index.tsx ā /blog\r\n * - blog/[slug].tsx ā /blog/:slug\r\n * - (public)/home.tsx ā / (route group, not in URL)\r\n * - api/hello.ts ā /api/hello (API route)\r\n * - dashboard/layout.tsx ā layout for /dashboard/*\r\n */\r\nfunction scanRoutesDirectory(baseDir, currentDir, routes, parentSegments = [], parentLayout = null, parentMiddleware = null) {\r\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\r\n \r\n // Find special files in current directory\r\n let layoutFile = null;\r\n let loadingFile = null;\r\n let errorFile = null;\r\n let middlewareFile = null;\r\n \r\n for (const entry of entries) {\r\n if (entry.isFile()) {\r\n const name = entry.name.replace(/\\.(jsx|js|tsx|ts)$/, '');\r\n const fullPath = path.join(currentDir, entry.name);\r\n const ext = path.extname(entry.name);\r\n \r\n // Special files\r\n if (name === 'layout') layoutFile = fullPath;\r\n if (name === 'loading') loadingFile = fullPath;\r\n if (name === 'error') errorFile = fullPath;\r\n if (name === '_middleware' || name === 'middleware') middlewareFile = fullPath;\r\n \r\n // Skip special files and non-route files\r\n if (['layout', 'loading', 'error', 'not-found', '_middleware', 'middleware'].includes(name)) continue;\r\n if (!['.tsx', '.jsx', '.ts', '.js'].includes(ext)) continue;\r\n \r\n // API routes (in api/ folder or .ts/.js files in api/)\r\n const relativePath = path.relative(baseDir, currentDir);\r\n const isApiRoute = relativePath.startsWith('api') || relativePath.startsWith('api/');\r\n \r\n if (isApiRoute && ['.ts', '.js'].includes(ext)) {\r\n const apiPath = '/' + [...parentSegments, name === 'index' ? '' : name].filter(Boolean).join('/');\r\n routes.api.push({\r\n type: RouteType.API,\r\n path: apiPath.replace(/\\/+/g, '/') || '/',\r\n filePath: fullPath,\r\n pattern: createRoutePattern(apiPath),\r\n segments: [...parentSegments, name === 'index' ? '' : name].filter(Boolean)\r\n });\r\n continue;\r\n }\r\n \r\n // Page routes\r\n if (['.tsx', '.jsx'].includes(ext)) {\r\n let routePath;\r\n \r\n // home.tsx ā /\r\n if (name === 'home' && parentSegments.length === 0) {\r\n routePath = '/';\r\n }\r\n // index.tsx ā parent path\r\n else if (name === 'index') {\r\n routePath = '/' + parentSegments.join('/') || '/';\r\n }\r\n // [param].tsx ā /:param\r\n else if (name.startsWith('[') && name.endsWith(']')) {\r\n const paramName = name.slice(1, -1);\r\n // Handle catch-all [...slug]\r\n if (paramName.startsWith('...')) {\r\n routePath = '/' + [...parentSegments, '*' + paramName.slice(3)].join('/');\r\n } else {\r\n routePath = '/' + [...parentSegments, ':' + paramName].join('/');\r\n }\r\n }\r\n // regular.tsx ā /regular\r\n else {\r\n routePath = '/' + [...parentSegments, name].join('/');\r\n }\r\n \r\n routes.flexiRoutes.push({\r\n type: RouteType.PAGE,\r\n path: routePath.replace(/\\/+/g, '/'),\r\n filePath: fullPath,\r\n pattern: createRoutePattern(routePath),\r\n segments: routePath.split('/').filter(Boolean),\r\n layout: layoutFile || parentLayout,\r\n loading: loadingFile,\r\n error: errorFile,\r\n middleware: middlewareFile || parentMiddleware,\r\n isFlexiRouter: true,\r\n isServerComponent: isServerComponent(fullPath),\r\n isClientComponent: isClientComponent(fullPath),\r\n isIsland: isIsland(fullPath)\r\n });\r\n }\r\n }\r\n }\r\n \r\n // Recursively scan subdirectories\r\n for (const entry of entries) {\r\n if (entry.isDirectory()) {\r\n const fullPath = path.join(currentDir, entry.name);\r\n const dirName = entry.name;\r\n \r\n // Skip special directories\r\n if (dirName.startsWith('_') || dirName.startsWith('.')) continue;\r\n \r\n // Handle route groups (parentheses) - don't add to URL\r\n const isGroup = dirName.startsWith('(') && dirName.endsWith(')');\r\n \r\n // Handle dynamic segments [param]\r\n let segmentName = dirName;\r\n if (dirName.startsWith('[') && dirName.endsWith(']')) {\r\n const paramName = dirName.slice(1, -1);\r\n if (paramName.startsWith('...')) {\r\n segmentName = '*' + paramName.slice(3);\r\n } else {\r\n segmentName = ':' + paramName;\r\n }\r\n }\r\n \r\n const newSegments = isGroup ? parentSegments : [...parentSegments, segmentName];\r\n const newLayout = layoutFile || parentLayout;\r\n const newMiddleware = middlewareFile || parentMiddleware;\r\n \r\n scanRoutesDirectory(baseDir, fullPath, routes, newSegments, newLayout, newMiddleware);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Scans app directory for Next.js style routing\r\n * Supports: page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx\r\n */\r\nfunction scanAppDirectory(baseDir, currentDir, routes, parentSegments = [], parentLayout = null, parentMiddleware = null) {\r\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\r\n \r\n // Find special files in current directory\r\n const specialFiles: Record<string, string | null> = {\r\n page: null,\r\n layout: null,\r\n loading: null,\r\n error: null,\r\n notFound: null,\r\n template: null,\r\n middleware: null\r\n };\r\n\r\n for (const entry of entries) {\r\n if (entry.isFile()) {\r\n const name = entry.name.replace(/\\.(jsx|js|tsx|ts)$/, '');\r\n const fullPath = path.join(currentDir, entry.name);\r\n \r\n if (name === 'page') specialFiles.page = fullPath;\r\n if (name === 'layout') specialFiles.layout = fullPath;\r\n if (name === 'loading') specialFiles.loading = fullPath;\r\n if (name === 'error') specialFiles.error = fullPath;\r\n if (name === 'not-found') specialFiles.notFound = fullPath;\r\n if (name === 'template') specialFiles.template = fullPath;\r\n if (name === 'middleware' || name === '_middleware') specialFiles.middleware = fullPath;\r\n }\r\n }\r\n\r\n // If there's a page.tsx, create a route\r\n if (specialFiles.page) {\r\n const routePath = '/' + parentSegments.join('/') || '/';\r\n \r\n routes.appRoutes.push({\r\n type: RouteType.PAGE,\r\n path: routePath.replace(/\\/+/g, '/'),\r\n filePath: specialFiles.page,\r\n pattern: createRoutePattern(routePath),\r\n segments: parentSegments,\r\n layout: specialFiles.layout || parentLayout,\r\n loading: specialFiles.loading,\r\n error: specialFiles.error,\r\n notFound: specialFiles.notFound,\r\n template: specialFiles.template,\r\n middleware: specialFiles.middleware || parentMiddleware,\r\n isAppRouter: true,\r\n isServerComponent: isServerComponent(specialFiles.page),\r\n isClientComponent: isClientComponent(specialFiles.page),\r\n isIsland: isIsland(specialFiles.page)\r\n });\r\n }\r\n\r\n // Recursively scan subdirectories\r\n for (const entry of entries) {\r\n if (entry.isDirectory()) {\r\n const fullPath = path.join(currentDir, entry.name);\r\n \r\n // Handle route groups (parentheses) - don't add to URL\r\n const isGroup = entry.name.startsWith('(') && entry.name.endsWith(')');\r\n \r\n // Handle dynamic segments [param]\r\n let segmentName = entry.name;\r\n if (entry.name.startsWith('[') && entry.name.endsWith(']')) {\r\n // Convert [param] to :param\r\n segmentName = ':' + entry.name.slice(1, -1);\r\n // Handle catch-all [...param]\r\n if (entry.name.startsWith('[...')) {\r\n segmentName = '*' + entry.name.slice(4, -1);\r\n }\r\n // Handle optional catch-all [[...param]]\r\n if (entry.name.startsWith('[[...')) {\r\n segmentName = '*' + entry.name.slice(5, -2);\r\n }\r\n }\r\n \r\n const newSegments = isGroup ? parentSegments : [...parentSegments, segmentName];\r\n const newLayout = specialFiles.layout || parentLayout;\r\n const newMiddleware = specialFiles.middleware || parentMiddleware;\r\n \r\n scanAppDirectory(baseDir, fullPath, routes, newSegments, newLayout, newMiddleware);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Scans directory recursively for route files\r\n */\r\nfunction scanDirectory(baseDir, currentDir, routes, parentSegments = []) {\r\n const entries = fs.readdirSync(currentDir, { withFileTypes: true });\r\n \r\n // First, find special files in current directory\r\n const specialFiles = {\r\n layout: null,\r\n loading: null,\r\n error: null,\r\n notFound: null\r\n };\r\n\r\n for (const entry of entries) {\r\n if (entry.isFile()) {\r\n const name = entry.name.replace(/\\.(jsx|js|tsx|ts)$/, '');\r\n const fullPath = path.join(currentDir, entry.name);\r\n \r\n if (name === 'layout') specialFiles.layout = fullPath;\r\n if (name === 'loading') specialFiles.loading = fullPath;\r\n if (name === 'error') specialFiles.error = fullPath;\r\n if (name === 'not-found' || name === '404') specialFiles.notFound = fullPath;\r\n }\r\n }\r\n\r\n for (const entry of entries) {\r\n const fullPath = path.join(currentDir, entry.name);\r\n const relativePath = path.relative(baseDir, fullPath);\r\n\r\n if (entry.isDirectory()) {\r\n // Handle route groups (parentheses)\r\n const isGroup = entry.name.startsWith('(') && entry.name.endsWith(')');\r\n const newSegments = isGroup ? parentSegments : [...parentSegments, entry.name];\r\n \r\n scanDirectory(baseDir, fullPath, routes, newSegments);\r\n } else if (entry.isFile()) {\r\n const ext = path.extname(entry.name);\r\n const baseName = path.basename(entry.name, ext);\r\n \r\n // Skip special files (already processed)\r\n if (['layout', 'loading', 'error', 'not-found', '404'].includes(baseName)) {\r\n continue;\r\n }\r\n \r\n if (['.jsx', '.js', '.tsx', '.ts'].includes(ext)) {\r\n const isApi = relativePath.startsWith('api' + path.sep) || relativePath.startsWith('api/');\r\n \r\n if (isApi && ['.js', '.ts'].includes(ext)) {\r\n routes.api.push(createRoute(fullPath, baseDir, specialFiles, RouteType.API));\r\n } else if (!isApi && ['.jsx', '.tsx'].includes(ext)) {\r\n routes.pages.push(createRoute(fullPath, baseDir, specialFiles, RouteType.PAGE));\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Creates a route object from file path\r\n */\r\nfunction createRoute(filePath, baseDir, specialFiles, type) {\r\n const relativePath = path.relative(baseDir, filePath);\r\n const routePath = filePathToRoute(relativePath);\r\n \r\n return {\r\n type,\r\n path: routePath,\r\n filePath,\r\n pattern: createRoutePattern(routePath),\r\n segments: routePath.split('/').filter(Boolean),\r\n layout: specialFiles.layout,\r\n loading: specialFiles.loading,\r\n error: specialFiles.error,\r\n notFound: specialFiles.notFound,\r\n isServerComponent: isServerComponent(filePath),\r\n isClientComponent: isClientComponent(filePath),\r\n isIsland: isIsland(filePath)\r\n };\r\n}\r\n\r\n/**\r\n * Scans layouts directory\r\n */\r\nfunction scanLayouts(layoutsDir, layoutsMap) {\r\n const entries = fs.readdirSync(layoutsDir, { withFileTypes: true });\r\n \r\n for (const entry of entries) {\r\n if (entry.isFile() && /\\.(jsx|tsx)$/.test(entry.name)) {\r\n const name = entry.name.replace(/\\.(jsx|tsx)$/, '');\r\n layoutsMap.set(name, path.join(layoutsDir, entry.name));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Converts file path to route path\r\n */\r\nfunction filePathToRoute(filePath) {\r\n let route = filePath.replace(/\\\\/g, '/');\r\n \r\n // Remove extension\r\n route = route.replace(/\\.(jsx|js|tsx|ts)$/, '');\r\n \r\n // Convert [param] to :param\r\n route = route.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, '*$1'); // Catch-all [...slug]\r\n route = route.replace(/\\[([^\\]]+)\\]/g, ':$1');\r\n \r\n // Handle index files\r\n if (route.endsWith('/index')) {\r\n route = route.slice(0, -6) || '/';\r\n } else if (route === 'index') {\r\n route = '/';\r\n }\r\n \r\n // Handle route groups - remove (groupName) from path\r\n route = route.replace(/\\/?\\([^)]+\\)\\/?/g, '/');\r\n \r\n // Ensure leading slash and clean up\r\n if (!route.startsWith('/')) {\r\n route = '/' + route;\r\n }\r\n route = route.replace(/\\/+/g, '/');\r\n \r\n return route;\r\n}\r\n\r\n/**\r\n * Creates regex pattern for route matching\r\n */\r\nfunction createRoutePattern(routePath) {\r\n let pattern = routePath\r\n .replace(/\\*[^/]*/g, '(.*)') // Catch-all\r\n .replace(/:[^/]+/g, '([^/]+)') // Dynamic segments\r\n .replace(/\\//g, '\\\\/');\r\n \r\n return new RegExp(`^${pattern}$`);\r\n}\r\n\r\n/**\r\n * Builds a tree structure for nested routes\r\n */\r\nfunction buildTree(routes) {\r\n const tree = { children: {}, routes: [] };\r\n \r\n for (const route of routes) {\r\n let current = tree;\r\n \r\n for (const segment of route.segments) {\r\n if (!current.children[segment]) {\r\n current.children[segment] = { children: {}, routes: [] };\r\n }\r\n current = current.children[segment];\r\n }\r\n \r\n current.routes.push(route);\r\n }\r\n \r\n return tree;\r\n}\r\n\r\n/**\r\n * Matches URL path against routes\r\n */\r\nexport function matchRoute(urlPath, routes) {\r\n const normalizedPath = urlPath === '' ? '/' : urlPath.split('?')[0];\r\n \r\n for (const route of routes) {\r\n const match = normalizedPath.match(route.pattern);\r\n \r\n if (match) {\r\n const params = extractParams(route.path, match);\r\n return { ...route, params };\r\n }\r\n }\r\n \r\n return null;\r\n}\r\n\r\n/**\r\n * Extracts parameters from route match\r\n */\r\nfunction extractParams(routePath, match) {\r\n const params = {};\r\n const paramNames = [];\r\n \r\n // Extract param names from route path\r\n const paramRegex = /:([^/]+)|\\*([^/]*)/g;\r\n let paramMatch;\r\n \r\n while ((paramMatch = paramRegex.exec(routePath)) !== null) {\r\n paramNames.push(paramMatch[1] || paramMatch[2] || 'splat');\r\n }\r\n \r\n paramNames.forEach((name, index) => {\r\n params[name] = match[index + 1];\r\n });\r\n \r\n return params;\r\n}\r\n\r\n/**\r\n * Finds all layouts that apply to a route\r\n */\r\nexport function findRouteLayouts(route, layoutsMap) {\r\n const layouts = [];\r\n \r\n // Check for segment-based layouts\r\n let currentPath = '';\r\n for (const segment of route.segments) {\r\n currentPath += '/' + segment;\r\n const layoutName = segment;\r\n \r\n if (layoutsMap.has(layoutName)) {\r\n layouts.push({\r\n name: layoutName,\r\n filePath: layoutsMap.get(layoutName)\r\n });\r\n }\r\n }\r\n \r\n // Check for route-specific layout\r\n if (route.layout) {\r\n layouts.push({\r\n name: 'route',\r\n filePath: route.layout\r\n });\r\n }\r\n \r\n // Check for root layout\r\n if (layoutsMap.has('root')) {\r\n layouts.unshift({\r\n name: 'root',\r\n filePath: layoutsMap.get('root')\r\n });\r\n }\r\n \r\n return layouts;\r\n}\r\n\r\nexport default {\r\n buildRouteTree,\r\n matchRoute,\r\n findRouteLayouts,\r\n RouteType\r\n};\r\n"],"mappings":"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","names":["fs","path","fs","path","path","fs","__filename","__dirname","path","build","fs"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// core/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { pathToFileURL } from "url";
|
|
5
|
+
var defaultConfig = {
|
|
6
|
+
// Directories
|
|
7
|
+
pagesDir: "pages",
|
|
8
|
+
layoutsDir: "layouts",
|
|
9
|
+
publicDir: "public",
|
|
10
|
+
outDir: ".flexi",
|
|
11
|
+
// Build options
|
|
12
|
+
build: {
|
|
13
|
+
target: "es2022",
|
|
14
|
+
minify: true,
|
|
15
|
+
sourcemap: true,
|
|
16
|
+
splitting: true
|
|
17
|
+
},
|
|
18
|
+
// Server options
|
|
19
|
+
server: {
|
|
20
|
+
port: 3e3,
|
|
21
|
+
host: "localhost"
|
|
22
|
+
},
|
|
23
|
+
// SSG options
|
|
24
|
+
ssg: {
|
|
25
|
+
enabled: false,
|
|
26
|
+
paths: []
|
|
27
|
+
},
|
|
28
|
+
// Islands (partial hydration)
|
|
29
|
+
islands: {
|
|
30
|
+
enabled: true
|
|
31
|
+
},
|
|
32
|
+
// RSC options
|
|
33
|
+
rsc: {
|
|
34
|
+
enabled: true
|
|
35
|
+
},
|
|
36
|
+
// Plugins
|
|
37
|
+
plugins: [],
|
|
38
|
+
// Styles (CSS files to include)
|
|
39
|
+
styles: [],
|
|
40
|
+
// Scripts (JS files to include)
|
|
41
|
+
scripts: [],
|
|
42
|
+
// Favicon path
|
|
43
|
+
favicon: null
|
|
44
|
+
};
|
|
45
|
+
async function loadConfig(projectRoot) {
|
|
46
|
+
const configPathTs = path.join(projectRoot, "flexireact.config.ts");
|
|
47
|
+
const configPathJs = path.join(projectRoot, "flexireact.config.js");
|
|
48
|
+
const configPath = fs.existsSync(configPathTs) ? configPathTs : configPathJs;
|
|
49
|
+
let userConfig = {};
|
|
50
|
+
if (fs.existsSync(configPath)) {
|
|
51
|
+
try {
|
|
52
|
+
const configUrl = pathToFileURL(configPath).href;
|
|
53
|
+
const module = await import(`${configUrl}?t=${Date.now()}`);
|
|
54
|
+
userConfig = module.default || module;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.warn("Warning: Failed to load flexireact config:", error.message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return deepMerge(defaultConfig, userConfig);
|
|
60
|
+
}
|
|
61
|
+
function deepMerge(target, source) {
|
|
62
|
+
const result = { ...target };
|
|
63
|
+
for (const key in source) {
|
|
64
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
65
|
+
result[key] = deepMerge(target[key] || {}, source[key]);
|
|
66
|
+
} else {
|
|
67
|
+
result[key] = source[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
function resolvePaths(config, projectRoot) {
|
|
73
|
+
return {
|
|
74
|
+
...config,
|
|
75
|
+
pagesDir: path.resolve(projectRoot, config.pagesDir),
|
|
76
|
+
layoutsDir: path.resolve(projectRoot, config.layoutsDir),
|
|
77
|
+
publicDir: path.resolve(projectRoot, config.publicDir),
|
|
78
|
+
outDir: path.resolve(projectRoot, config.outDir)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
defaultConfig,
|
|
83
|
+
loadConfig,
|
|
84
|
+
resolvePaths
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../core/config.ts"],"sourcesContent":["/**\r\n * FlexiReact Configuration System\r\n * Handles loading and merging of configuration from flexireact.config.js\r\n */\r\n\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\n\r\n// Default configuration\r\nexport const defaultConfig = {\r\n // Directories\r\n pagesDir: 'pages',\r\n layoutsDir: 'layouts',\r\n publicDir: 'public',\r\n outDir: '.flexi',\r\n \r\n // Build options\r\n build: {\r\n target: 'es2022',\r\n minify: true,\r\n sourcemap: true,\r\n splitting: true\r\n },\r\n \r\n // Server options\r\n server: {\r\n port: 3000,\r\n host: 'localhost'\r\n },\r\n \r\n // SSG options\r\n ssg: {\r\n enabled: false,\r\n paths: []\r\n },\r\n \r\n // Islands (partial hydration)\r\n islands: {\r\n enabled: true\r\n },\r\n \r\n // RSC options\r\n rsc: {\r\n enabled: true\r\n },\r\n \r\n // Plugins\r\n plugins: [],\r\n \r\n // Styles (CSS files to include)\r\n styles: [],\r\n \r\n // Scripts (JS files to include)\r\n scripts: [],\r\n \r\n // Favicon path\r\n favicon: null\r\n};\r\n\r\n/**\r\n * Loads configuration from the project root\r\n * @param {string} projectRoot - Path to project root\r\n * @returns {Object} Merged configuration\r\n */\r\nexport async function loadConfig(projectRoot: string) {\r\n // Try .ts first, then .js\r\n const configPathTs = path.join(projectRoot, 'flexireact.config.ts');\r\n const configPathJs = path.join(projectRoot, 'flexireact.config.js');\r\n const configPath = fs.existsSync(configPathTs) ? configPathTs : configPathJs;\r\n \r\n let userConfig = {};\r\n \r\n if (fs.existsSync(configPath)) {\r\n try {\r\n const configUrl = pathToFileURL(configPath).href;\r\n const module = await import(`${configUrl}?t=${Date.now()}`);\r\n userConfig = module.default || module;\r\n } catch (error: any) {\r\n console.warn('Warning: Failed to load flexireact config:', error.message);\r\n }\r\n }\r\n \r\n // Deep merge configs\r\n return deepMerge(defaultConfig, userConfig);\r\n}\r\n\r\n/**\r\n * Deep merge two objects\r\n */\r\nfunction deepMerge(target, source) {\r\n const result = { ...target };\r\n \r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n result[key] = deepMerge(target[key] || {}, source[key]);\r\n } else {\r\n result[key] = source[key];\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Resolves all paths in config relative to project root\r\n */\r\nexport function resolvePaths(config, projectRoot) {\r\n return {\r\n ...config,\r\n pagesDir: path.resolve(projectRoot, config.pagesDir),\r\n layoutsDir: path.resolve(projectRoot, config.layoutsDir),\r\n publicDir: path.resolve(projectRoot, config.publicDir),\r\n outDir: path.resolve(projectRoot, config.outDir)\r\n };\r\n}\r\n"],"mappings":";AAKA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAGvB,IAAM,gBAAgB;AAAA;AAAA,EAE3B,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EAGR,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAGA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,SAAS;AAAA,EACX;AAAA;AAAA,EAGA,KAAK;AAAA,IACH,SAAS;AAAA,EACX;AAAA;AAAA,EAGA,SAAS,CAAC;AAAA;AAAA,EAGV,QAAQ,CAAC;AAAA;AAAA,EAGT,SAAS,CAAC;AAAA;AAAA,EAGV,SAAS;AACX;AAOA,eAAsB,WAAW,aAAqB;AAEpD,QAAM,eAAe,KAAK,KAAK,aAAa,sBAAsB;AAClE,QAAM,eAAe,KAAK,KAAK,aAAa,sBAAsB;AAClE,QAAM,aAAa,GAAG,WAAW,YAAY,IAAI,eAAe;AAEhE,MAAI,aAAa,CAAC;AAElB,MAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,QAAI;AACF,YAAM,YAAY,cAAc,UAAU,EAAE;AAC5C,YAAM,SAAS,MAAM,OAAO,GAAG,SAAS,MAAM,KAAK,IAAI,CAAC;AACxD,mBAAa,OAAO,WAAW;AAAA,IACjC,SAAS,OAAY;AACnB,cAAQ,KAAK,8CAA8C,MAAM,OAAO;AAAA,IAC1E;AAAA,EACF;AAGA,SAAO,UAAU,eAAe,UAAU;AAC5C;AAKA,SAAS,UAAU,QAAQ,QAAQ;AACjC,QAAM,SAAS,EAAE,GAAG,OAAO;AAE3B,aAAW,OAAO,QAAQ;AACxB,QAAI,OAAO,GAAG,KAAK,OAAO,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,QAAQ,OAAO,GAAG,CAAC,GAAG;AACjF,aAAO,GAAG,IAAI,UAAU,OAAO,GAAG,KAAK,CAAC,GAAG,OAAO,GAAG,CAAC;AAAA,IACxD,OAAO;AACL,aAAO,GAAG,IAAI,OAAO,GAAG;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,aAAa,QAAQ,aAAa;AAChD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,KAAK,QAAQ,aAAa,OAAO,QAAQ;AAAA,IACnD,YAAY,KAAK,QAAQ,aAAa,OAAO,UAAU;AAAA,IACvD,WAAW,KAAK,QAAQ,aAAa,OAAO,SAAS;AAAA,IACrD,QAAQ,KAAK,QAAQ,aAAa,OAAO,MAAM;AAAA,EACjD;AACF;","names":[]}
|