{"version":3,"file":"getRouteNodes.cjs","names":[],"sources":["../../../../src/filesystem/physical/getRouteNodes.ts"],"sourcesContent":["import path from 'node:path'\nimport * as fsp from 'node:fs/promises'\nimport {\n  cleanPath,\n  createRoutePathSegmentMetadata,\n  determineInitialRoutePath,\n  escapeRegExp,\n  hasEscapedLeadingUnderscore,\n  joinRoutePathSegmentMetadata,\n  removeExt,\n  replaceBackslash,\n  routePathToVariable,\n  unwrapBracketWrappedSegment,\n} from '../../utils'\nimport { getRouteNodes as getRouteNodesVirtual } from '../virtual/getRouteNodes'\nimport { loadConfigFile } from '../virtual/loadConfigFile'\nimport { logging } from '../../logger'\nimport { rootPathId } from './rootPathId'\nimport type {\n  VirtualRootRoute,\n  VirtualRouteSubtreeConfig,\n} from '@tanstack/virtual-file-routes'\nimport type { FsRouteType, GetRouteNodesResult, RouteNode } from '../../types'\nimport type { Config } from '../../config'\n\n/**\n * Pre-compiled segment regexes for matching token patterns against route segments.\n * These are created once (in Generator constructor) and passed through to avoid\n * repeated regex compilation during route crawling.\n */\nexport interface TokenRegexBundle {\n  indexTokenSegmentRegex: RegExp\n  routeTokenSegmentRegex: RegExp\n}\n\nconst disallowedRouteGroupConfiguration = /\\(([^)]+)\\).(ts|js|tsx|jsx|vue)/\n\nconst virtualConfigFileRegExp = /__virtual\\.[mc]?[jt]s$/\nexport function isVirtualConfigFile(fileName: string): boolean {\n  return virtualConfigFileRegExp.test(fileName)\n}\n\nexport async function getRouteNodes(\n  config: Pick<\n    Config,\n    | 'routesDirectory'\n    | 'routeFilePrefix'\n    | 'routeFileIgnorePrefix'\n    | 'routeFileIgnorePattern'\n    | 'disableLogging'\n    | 'routeToken'\n    | 'indexToken'\n  >,\n  root: string,\n  tokenRegexes: TokenRegexBundle,\n): Promise<GetRouteNodesResult> {\n  const { routeFilePrefix, routeFileIgnorePrefix, routeFileIgnorePattern } =\n    config\n\n  const logger = logging({ disabled: config.disableLogging })\n  const routeFileIgnoreRegExp = new RegExp(routeFileIgnorePattern ?? '', 'g')\n\n  const routeNodes: Array<RouteNode> = []\n  const allPhysicalDirectories: Array<string> = []\n\n  async function recurse(dir: string) {\n    const fullDir = path.resolve(config.routesDirectory, dir)\n    let dirList = await fsp.readdir(fullDir, { withFileTypes: true })\n\n    dirList = dirList.filter((d) => {\n      if (\n        d.name.startsWith('.') ||\n        (routeFileIgnorePrefix && d.name.startsWith(routeFileIgnorePrefix))\n      ) {\n        return false\n      }\n\n      if (routeFilePrefix) {\n        if (routeFileIgnorePattern) {\n          return (\n            d.name.startsWith(routeFilePrefix) &&\n            !d.name.match(routeFileIgnoreRegExp)\n          )\n        }\n\n        return d.name.startsWith(routeFilePrefix)\n      }\n\n      if (routeFileIgnorePattern) {\n        return !d.name.match(routeFileIgnoreRegExp)\n      }\n\n      return true\n    })\n\n    const virtualConfigFile = dirList.find((dirent) => {\n      return dirent.isFile() && isVirtualConfigFile(dirent.name)\n    })\n\n    if (virtualConfigFile !== undefined) {\n      const virtualRouteConfigExport = await loadConfigFile(\n        path.resolve(fullDir, virtualConfigFile.name),\n      )\n      let virtualRouteSubtreeConfig: VirtualRouteSubtreeConfig\n      if (typeof virtualRouteConfigExport.default === 'function') {\n        virtualRouteSubtreeConfig = await virtualRouteConfigExport.default()\n      } else {\n        virtualRouteSubtreeConfig = virtualRouteConfigExport.default\n      }\n      const dummyRoot: VirtualRootRoute = {\n        type: 'root',\n        file: '',\n        children: virtualRouteSubtreeConfig,\n      }\n      const { routeNodes: virtualRouteNodes, physicalDirectories } =\n        await getRouteNodesVirtual(\n          {\n            ...config,\n            routesDirectory: fullDir,\n            virtualRouteConfig: dummyRoot,\n          },\n          root,\n          tokenRegexes,\n        )\n      allPhysicalDirectories.push(...physicalDirectories)\n      virtualRouteNodes.forEach((node) => {\n        const normalizedDir = dir === './' ? '' : dir\n        const filePath = replaceBackslash(\n          path.join(normalizedDir, node.filePath),\n        )\n        const { routePath: prefixPath, originalRoutePath: originalPrefixPath } =\n          normalizedDir\n            ? determineInitialRoutePath(normalizedDir)\n            : { routePath: '', originalRoutePath: '' }\n        const routePath = cleanPath(`${prefixPath}${node.routePath}`)\n\n        node.variableName = routePathToVariable(\n          cleanPath(`${prefixPath}/${removeExt(node.filePath)}`),\n        )\n        node._routePathSegmentMetadata = joinRoutePathSegmentMetadata(\n          routePath,\n          prefixPath,\n          createRoutePathSegmentMetadata(prefixPath, originalPrefixPath),\n          node._routePathSegmentMetadata,\n        )\n        node.routePath = routePath\n        // Keep originalRoutePath aligned with routePath for escape detection\n        if (node.originalRoutePath) {\n          node.originalRoutePath = cleanPath(\n            `${originalPrefixPath}${node.originalRoutePath}`,\n          )\n        }\n        node.filePath = filePath\n        // Virtual subtree nodes (from __virtual.ts) are embedded in a\n        // physical directory tree. They should use path-based parent\n        // inference, not the explicit virtual parent tracking. Clear any\n        // _virtualParentRoutePath that was set at construction time.\n        delete node._virtualParentRoutePath\n      })\n\n      routeNodes.push(...virtualRouteNodes)\n\n      return\n    }\n\n    await Promise.all(\n      dirList.map(async (dirent) => {\n        const fullPath = replaceBackslash(path.join(fullDir, dirent.name))\n        const relativePath = path.posix.join(dir, dirent.name)\n\n        if (dirent.isDirectory()) {\n          await recurse(relativePath)\n        } else if (fullPath.match(/\\.(tsx|ts|jsx|js|vue)$/)) {\n          const filePath = replaceBackslash(path.join(dir, dirent.name))\n          const filePathNoExt = removeExt(filePath)\n          const {\n            routePath: initialRoutePath,\n            originalRoutePath: initialOriginalRoutePath,\n          } = determineInitialRoutePath(filePathNoExt)\n\n          let routePath = initialRoutePath\n          let originalRoutePath = initialOriginalRoutePath\n\n          if (routeFilePrefix) {\n            routePath = routePath.replaceAll(routeFilePrefix, '')\n            originalRoutePath = originalRoutePath.replaceAll(\n              routeFilePrefix,\n              '',\n            )\n          }\n\n          if (disallowedRouteGroupConfiguration.test(dirent.name)) {\n            const errorMessage = `A route configuration for a route group was found at \\`${filePath}\\`. This is not supported. Did you mean to use a layout/pathless route instead?`\n            logger.error(`ERROR: ${errorMessage}`)\n            throw new Error(errorMessage)\n          }\n\n          const meta = getRouteMeta(routePath, originalRoutePath, tokenRegexes)\n          const variableName = meta.variableName\n          let routeType: FsRouteType = meta.fsRouteType\n\n          if (routeType === 'lazy') {\n            routePath = routePath.replace(/\\/lazy$/, '')\n            originalRoutePath = originalRoutePath.replace(/\\/lazy$/, '')\n          }\n\n          // this check needs to happen after the lazy route has been cleaned up\n          // since the routePath is used to determine if a route is pathless\n          if (\n            isValidPathlessLayoutRoute(\n              routePath,\n              originalRoutePath,\n              routeType,\n              tokenRegexes,\n            )\n          ) {\n            routeType = 'pathless_layout'\n          }\n\n          // Only show deprecation warning for .tsx/.ts files, not .vue files\n          // Vue files using .component.vue is the Vue-native way\n          const isVueFile = filePath.endsWith('.vue')\n          if (!isVueFile) {\n            ;(\n              [\n                ['component', 'component'],\n                ['errorComponent', 'errorComponent'],\n                ['notFoundComponent', 'notFoundComponent'],\n                ['pendingComponent', 'pendingComponent'],\n                ['loader', 'loader'],\n              ] satisfies Array<[FsRouteType, string]>\n            ).forEach(([matcher, type]) => {\n              if (routeType === matcher) {\n                logger.warn(\n                  `WARNING: The \\`.${type}.tsx\\` suffix used for the ${filePath} file is deprecated. Use the new \\`.lazy.tsx\\` suffix instead.`,\n                )\n              }\n            })\n          }\n\n          // Get the last segment of originalRoutePath to check for escaping\n          const originalSegments = originalRoutePath.split('/').filter(Boolean)\n          const lastOriginalSegmentForSuffix =\n            originalSegments[originalSegments.length - 1] || ''\n\n          const { routeTokenSegmentRegex, indexTokenSegmentRegex } =\n            tokenRegexes\n\n          // List of special suffixes that can be escaped\n          const specialSuffixes = [\n            'component',\n            'errorComponent',\n            'notFoundComponent',\n            'pendingComponent',\n            'loader',\n            'lazy',\n          ]\n\n          const routePathSegments = routePath.split('/').filter(Boolean)\n          const lastRouteSegment =\n            routePathSegments[routePathSegments.length - 1] || ''\n\n          const suffixToStrip = specialSuffixes.find((suffix) => {\n            const endsWithSuffix = routePath.endsWith(`/${suffix}`)\n            // A suffix is escaped if wrapped in brackets in the original: [lazy] means literal \"lazy\"\n            const isEscaped =\n              lastOriginalSegmentForSuffix.startsWith('[') &&\n              lastOriginalSegmentForSuffix.endsWith(']') &&\n              unwrapBracketWrappedSegment(lastOriginalSegmentForSuffix) ===\n                suffix\n            return endsWithSuffix && !isEscaped\n          })\n\n          const routeTokenCandidate = unwrapBracketWrappedSegment(\n            lastOriginalSegmentForSuffix,\n          )\n          const isRouteTokenEscaped =\n            lastOriginalSegmentForSuffix !== routeTokenCandidate &&\n            routeTokenSegmentRegex.test(routeTokenCandidate)\n\n          const shouldStripRouteToken =\n            routeTokenSegmentRegex.test(lastRouteSegment) &&\n            !isRouteTokenEscaped\n\n          if (suffixToStrip || shouldStripRouteToken) {\n            const stripSegment = suffixToStrip ?? lastRouteSegment\n            routePath = routePath.replace(\n              new RegExp(`/${escapeRegExp(stripSegment)}$`),\n              '',\n            )\n            originalRoutePath = originalRoutePath.replace(\n              new RegExp(`/${escapeRegExp(stripSegment)}$`),\n              '',\n            )\n          }\n\n          // Check if the index token should be treated specially or as a literal path\n          // Escaping stays literal-only: if the last original segment is bracket-wrapped,\n          // treat it as literal even if it matches the token regex.\n          const lastOriginalSegment =\n            originalRoutePath.split('/').filter(Boolean).pop() || ''\n\n          const indexTokenCandidate =\n            unwrapBracketWrappedSegment(lastOriginalSegment)\n          const isIndexEscaped =\n            lastOriginalSegment !== indexTokenCandidate &&\n            indexTokenSegmentRegex.test(indexTokenCandidate)\n\n          if (!isIndexEscaped) {\n            const updatedRouteSegments = routePath.split('/').filter(Boolean)\n            const updatedLastRouteSegment =\n              updatedRouteSegments[updatedRouteSegments.length - 1] || ''\n\n            if (indexTokenSegmentRegex.test(updatedLastRouteSegment)) {\n              if (routePathSegments.length === 1) {\n                routePath = '/'\n              }\n\n              // For layout routes, don't use '/' fallback - an empty path means\n              // \"layout for the parent path\" which is important for physical() mounts\n              // where route.tsx at root should have empty path, not '/'\n              const isLayoutRoute = routeType === 'layout'\n\n              routePath =\n                routePath.replace(\n                  new RegExp(`/${escapeRegExp(updatedLastRouteSegment)}$`),\n                  '/',\n                ) || (isLayoutRoute ? '' : '/')\n\n              originalRoutePath =\n                originalRoutePath.replace(\n                  new RegExp(`/${escapeRegExp(indexTokenCandidate)}$`),\n                  '/',\n                ) || (isLayoutRoute ? '' : '/')\n            }\n          }\n\n          routeNodes.push({\n            filePath,\n            fullPath,\n            routePath,\n            variableName,\n            _fsRouteType: routeType,\n            originalRoutePath,\n            _routePathSegmentMetadata: createRoutePathSegmentMetadata(\n              routePath,\n              originalRoutePath,\n            ),\n          })\n        }\n      }),\n    )\n\n    return routeNodes\n  }\n\n  await recurse('./')\n\n  // Find the root route node - prefer the actual route file over component/loader files\n  const rootRouteNode =\n    routeNodes.find(\n      (d) =>\n        d.routePath === `/${rootPathId}` &&\n        ![\n          'component',\n          'errorComponent',\n          'notFoundComponent',\n          'pendingComponent',\n          'loader',\n          'lazy',\n        ].includes(d._fsRouteType),\n    ) ?? routeNodes.find((d) => d.routePath === `/${rootPathId}`)\n  if (rootRouteNode) {\n    rootRouteNode._fsRouteType = '__root'\n    rootRouteNode.variableName = 'root'\n  }\n\n  return {\n    rootRouteNode,\n    routeNodes,\n    physicalDirectories: allPhysicalDirectories,\n  }\n}\n\n/**\n * Determines the metadata for a given route path based on the provided configuration.\n *\n * @param routePath - The determined initial routePath (with brackets removed).\n * @param originalRoutePath - The original route path (may contain brackets for escaped content).\n * @param tokenRegexes - Pre-compiled token regexes for matching.\n * @returns An object containing the type of the route and the variable name derived from the route path.\n */\nexport function getRouteMeta(\n  routePath: string,\n  originalRoutePath: string,\n  tokenRegexes: TokenRegexBundle,\n): {\n  // `__root` is can be more easily determined by filtering down to routePath === /${rootPathId}\n  // `pathless` is needs to determined after `lazy` has been cleaned up from the routePath\n  fsRouteType: Extract<\n    FsRouteType,\n    | 'static'\n    | 'layout'\n    | 'api'\n    | 'lazy'\n    | 'loader'\n    | 'component'\n    | 'pendingComponent'\n    | 'errorComponent'\n    | 'notFoundComponent'\n  >\n  variableName: string\n} {\n  let fsRouteType: FsRouteType = 'static'\n\n  // Get the last segment from the original path to check for escaping\n  const originalSegments = originalRoutePath.split('/').filter(Boolean)\n  const lastOriginalSegment =\n    originalSegments[originalSegments.length - 1] || ''\n\n  const { routeTokenSegmentRegex } = tokenRegexes\n\n  // Helper to check if a specific suffix is escaped (literal-only)\n  // A suffix is escaped if the original segment is wrapped in brackets: [lazy] means literal \"lazy\"\n  const isSuffixEscaped = (suffix: string): boolean => {\n    return (\n      lastOriginalSegment.startsWith('[') &&\n      lastOriginalSegment.endsWith(']') &&\n      unwrapBracketWrappedSegment(lastOriginalSegment) === suffix\n    )\n  }\n\n  const routeSegments = routePath.split('/').filter(Boolean)\n  const lastRouteSegment = routeSegments[routeSegments.length - 1] || ''\n\n  const routeTokenCandidate = unwrapBracketWrappedSegment(lastOriginalSegment)\n  const isRouteTokenEscaped =\n    lastOriginalSegment !== routeTokenCandidate &&\n    routeTokenSegmentRegex.test(routeTokenCandidate)\n\n  if (routeTokenSegmentRegex.test(lastRouteSegment) && !isRouteTokenEscaped) {\n    // layout routes, i.e `/foo/route.tsx` or `/foo/_layout/route.tsx`\n    fsRouteType = 'layout'\n  } else if (routePath.endsWith('/lazy') && !isSuffixEscaped('lazy')) {\n    // lazy routes, i.e. `/foo.lazy.tsx`\n    fsRouteType = 'lazy'\n  } else if (routePath.endsWith('/loader') && !isSuffixEscaped('loader')) {\n    // loader routes, i.e. `/foo.loader.tsx`\n    fsRouteType = 'loader'\n  } else if (\n    routePath.endsWith('/component') &&\n    !isSuffixEscaped('component')\n  ) {\n    // component routes, i.e. `/foo.component.tsx`\n    fsRouteType = 'component'\n  } else if (\n    routePath.endsWith('/pendingComponent') &&\n    !isSuffixEscaped('pendingComponent')\n  ) {\n    // pending component routes, i.e. `/foo.pendingComponent.tsx`\n    fsRouteType = 'pendingComponent'\n  } else if (\n    routePath.endsWith('/errorComponent') &&\n    !isSuffixEscaped('errorComponent')\n  ) {\n    // error component routes, i.e. `/foo.errorComponent.tsx`\n    fsRouteType = 'errorComponent'\n  } else if (\n    routePath.endsWith('/notFoundComponent') &&\n    !isSuffixEscaped('notFoundComponent')\n  ) {\n    // not found component routes, i.e. `/foo.notFoundComponent.tsx`\n    fsRouteType = 'notFoundComponent'\n  }\n\n  // Use originalRoutePath for variable name when any segment is fully\n  // bracket-wrapped (e.g. [index], [route], [_]auth) to avoid collisions\n  // with their non-escaped counterparts that get special token treatment\n  const hasFullyEscapedSegment = originalSegments.some(\n    (seg) =>\n      seg.startsWith('[') &&\n      seg.endsWith(']') &&\n      !seg.slice(1, -1).includes('[') &&\n      !seg.slice(1, -1).includes(']'),\n  )\n  const variableName = routePathToVariable(\n    hasFullyEscapedSegment ? originalRoutePath : routePath,\n  )\n\n  return { fsRouteType, variableName }\n}\n\n/**\n * Used to validate if a route is a pathless layout route\n * @param normalizedRoutePath Normalized route path, i.e `/foo/_layout/route.tsx` and `/foo._layout.route.tsx` to `/foo/_layout/route`\n * @param originalRoutePath Original route path with brackets for escaped content\n * @param routeType The route type determined from file extension\n * @param tokenRegexes Pre-compiled token regexes for matching\n * @returns Boolean indicating if the route is a pathless layout route\n */\nfunction isValidPathlessLayoutRoute(\n  normalizedRoutePath: string,\n  originalRoutePath: string,\n  routeType: FsRouteType,\n  tokenRegexes: TokenRegexBundle,\n): boolean {\n  if (routeType === 'lazy') {\n    return false\n  }\n\n  const segments = normalizedRoutePath.split('/').filter(Boolean)\n  const originalSegments = originalRoutePath.split('/').filter(Boolean)\n\n  if (segments.length === 0) {\n    return false\n  }\n\n  const lastRouteSegment = segments[segments.length - 1]!\n  const lastOriginalSegment =\n    originalSegments[originalSegments.length - 1] || ''\n  const secondToLastRouteSegment = segments[segments.length - 2]\n  const secondToLastOriginalSegment =\n    originalSegments[originalSegments.length - 2]\n\n  // If segment === __root, then exit as false\n  if (lastRouteSegment === rootPathId) {\n    return false\n  }\n\n  const { routeTokenSegmentRegex, indexTokenSegmentRegex } = tokenRegexes\n\n  // If segment matches routeToken and secondToLastSegment is a string that starts with _, then exit as true\n  // Since the route is actually a configuration route for a layout/pathless route\n  // i.e. /foo/_layout/route.tsx === /foo/_layout.tsx\n  // But if the underscore is escaped, it's not a pathless layout\n  if (\n    routeTokenSegmentRegex.test(lastRouteSegment) &&\n    typeof secondToLastRouteSegment === 'string' &&\n    typeof secondToLastOriginalSegment === 'string'\n  ) {\n    // Check if the underscore is escaped\n    if (hasEscapedLeadingUnderscore(secondToLastOriginalSegment)) {\n      return false\n    }\n    return secondToLastRouteSegment.startsWith('_')\n  }\n\n  // Segment starts with _ but check if it's escaped\n  // If the original segment has [_] at the start, the underscore is escaped and it's not a pathless layout\n  if (hasEscapedLeadingUnderscore(lastOriginalSegment)) {\n    return false\n  }\n\n  return (\n    !indexTokenSegmentRegex.test(lastRouteSegment) &&\n    !routeTokenSegmentRegex.test(lastRouteSegment) &&\n    lastRouteSegment.startsWith('_')\n  )\n}\n"],"mappings":";;;;;;;;;;;AAmCA,IAAM,oCAAoC;AAE1C,IAAM,0BAA0B;AAChC,SAAgB,oBAAoB,UAA2B;CAC7D,OAAO,wBAAwB,KAAK,QAAQ;AAC9C;AAEA,eAAsB,cACpB,QAUA,MACA,cAC8B;CAC9B,MAAM,EAAE,iBAAiB,uBAAuB,2BAC9C;CAEF,MAAM,SAAS,eAAA,QAAQ,EAAE,UAAU,OAAO,eAAe,CAAC;CAC1D,MAAM,wBAAwB,IAAI,OAAO,0BAA0B,IAAI,GAAG;CAE1E,MAAM,aAA+B,CAAC;CACtC,MAAM,yBAAwC,CAAC;CAE/C,eAAe,QAAQ,KAAa;EAClC,MAAM,UAAU,UAAA,QAAK,QAAQ,OAAO,iBAAiB,GAAG;EACxD,IAAI,UAAU,MAAM,iBAAI,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;EAEhE,UAAU,QAAQ,QAAQ,MAAM;GAC9B,IACE,EAAE,KAAK,WAAW,GAAG,KACpB,yBAAyB,EAAE,KAAK,WAAW,qBAAqB,GAEjE,OAAO;GAGT,IAAI,iBAAiB;IACnB,IAAI,wBACF,OACE,EAAE,KAAK,WAAW,eAAe,KACjC,CAAC,EAAE,KAAK,MAAM,qBAAqB;IAIvC,OAAO,EAAE,KAAK,WAAW,eAAe;GAC1C;GAEA,IAAI,wBACF,OAAO,CAAC,EAAE,KAAK,MAAM,qBAAqB;GAG5C,OAAO;EACT,CAAC;EAED,MAAM,oBAAoB,QAAQ,MAAM,WAAW;GACjD,OAAO,OAAO,OAAO,KAAK,oBAAoB,OAAO,IAAI;EAC3D,CAAC;EAED,IAAI,sBAAsB,KAAA,GAAW;GACnC,MAAM,2BAA2B,MAAM,uBAAA,eACrC,UAAA,QAAK,QAAQ,SAAS,kBAAkB,IAAI,CAC9C;GACA,IAAI;GACJ,IAAI,OAAO,yBAAyB,YAAY,YAC9C,4BAA4B,MAAM,yBAAyB,QAAQ;QAEnE,4BAA4B,yBAAyB;GAEvD,MAAM,YAA8B;IAClC,MAAM;IACN,MAAM;IACN,UAAU;GACZ;GACA,MAAM,EAAE,YAAY,mBAAmB,wBACrC,MAAM,sBAAA,cACJ;IACE,GAAG;IACH,iBAAiB;IACjB,oBAAoB;GACtB,GACA,MACA,YACF;GACF,uBAAuB,KAAK,GAAG,mBAAmB;GAClD,kBAAkB,SAAS,SAAS;IAClC,MAAM,gBAAgB,QAAQ,OAAO,KAAK;IAC1C,MAAM,WAAW,cAAA,iBACf,UAAA,QAAK,KAAK,eAAe,KAAK,QAAQ,CACxC;IACA,MAAM,EAAE,WAAW,YAAY,mBAAmB,uBAChD,gBACI,cAAA,0BAA0B,aAAa,IACvC;KAAE,WAAW;KAAI,mBAAmB;IAAG;IAC7C,MAAM,YAAY,cAAA,UAAU,GAAG,aAAa,KAAK,WAAW;IAE5D,KAAK,eAAe,cAAA,oBAClB,cAAA,UAAU,GAAG,WAAW,GAAG,cAAA,UAAU,KAAK,QAAQ,GAAG,CACvD;IACA,KAAK,4BAA4B,cAAA,6BAC/B,WACA,YACA,cAAA,+BAA+B,YAAY,kBAAkB,GAC7D,KAAK,yBACP;IACA,KAAK,YAAY;IAEjB,IAAI,KAAK,mBACP,KAAK,oBAAoB,cAAA,UACvB,GAAG,qBAAqB,KAAK,mBAC/B;IAEF,KAAK,WAAW;IAKhB,OAAO,KAAK;GACd,CAAC;GAED,WAAW,KAAK,GAAG,iBAAiB;GAEpC;EACF;EAEA,MAAM,QAAQ,IACZ,QAAQ,IAAI,OAAO,WAAW;GAC5B,MAAM,WAAW,cAAA,iBAAiB,UAAA,QAAK,KAAK,SAAS,OAAO,IAAI,CAAC;GACjE,MAAM,eAAe,UAAA,QAAK,MAAM,KAAK,KAAK,OAAO,IAAI;GAErD,IAAI,OAAO,YAAY,GACrB,MAAM,QAAQ,YAAY;QACrB,IAAI,SAAS,MAAM,wBAAwB,GAAG;IACnD,MAAM,WAAW,cAAA,iBAAiB,UAAA,QAAK,KAAK,KAAK,OAAO,IAAI,CAAC;IAE7D,MAAM,EACJ,WAAW,kBACX,mBAAmB,6BACjB,cAAA,0BAJkB,cAAA,UAAU,QAIF,CAAa;IAE3C,IAAI,YAAY;IAChB,IAAI,oBAAoB;IAExB,IAAI,iBAAiB;KACnB,YAAY,UAAU,WAAW,iBAAiB,EAAE;KACpD,oBAAoB,kBAAkB,WACpC,iBACA,EACF;IACF;IAEA,IAAI,kCAAkC,KAAK,OAAO,IAAI,GAAG;KACvD,MAAM,eAAe,0DAA0D,SAAS;KACxF,OAAO,MAAM,UAAU,cAAc;KACrC,MAAM,IAAI,MAAM,YAAY;IAC9B;IAEA,MAAM,OAAO,aAAa,WAAW,mBAAmB,YAAY;IACpE,MAAM,eAAe,KAAK;IAC1B,IAAI,YAAyB,KAAK;IAElC,IAAI,cAAc,QAAQ;KACxB,YAAY,UAAU,QAAQ,WAAW,EAAE;KAC3C,oBAAoB,kBAAkB,QAAQ,WAAW,EAAE;IAC7D;IAIA,IACE,2BACE,WACA,mBACA,WACA,YACF,GAEA,YAAY;IAMd,IAAI,CADc,SAAS,SAAS,MAC/B,GACF;KAEG,CAAC,aAAa,WAAW;KACzB,CAAC,kBAAkB,gBAAgB;KACnC,CAAC,qBAAqB,mBAAmB;KACzC,CAAC,oBAAoB,kBAAkB;KACvC,CAAC,UAAU,QAAQ;IACrB,EACA,SAAS,CAAC,SAAS,UAAU;KAC7B,IAAI,cAAc,SAChB,OAAO,KACL,mBAAmB,KAAK,6BAA6B,SAAS,+DAChE;IAEJ,CAAC;IAIH,MAAM,mBAAmB,kBAAkB,MAAM,GAAG,EAAE,OAAO,OAAO;IACpE,MAAM,+BACJ,iBAAiB,iBAAiB,SAAS,MAAM;IAEnD,MAAM,EAAE,wBAAwB,2BAC9B;IAGF,MAAM,kBAAkB;KACtB;KACA;KACA;KACA;KACA;KACA;IACF;IAEA,MAAM,oBAAoB,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO;IAC7D,MAAM,mBACJ,kBAAkB,kBAAkB,SAAS,MAAM;IAErD,MAAM,gBAAgB,gBAAgB,MAAM,WAAW;KACrD,MAAM,iBAAiB,UAAU,SAAS,IAAI,QAAQ;KAEtD,MAAM,YACJ,6BAA6B,WAAW,GAAG,KAC3C,6BAA6B,SAAS,GAAG,KACzC,cAAA,4BAA4B,4BAA4B,MACtD;KACJ,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,MAAM,sBAAsB,cAAA,4BAC1B,4BACF;IACA,MAAM,sBACJ,iCAAiC,uBACjC,uBAAuB,KAAK,mBAAmB;IAEjD,MAAM,wBACJ,uBAAuB,KAAK,gBAAgB,KAC5C,CAAC;IAEH,IAAI,iBAAiB,uBAAuB;KAC1C,MAAM,eAAe,iBAAiB;KACtC,YAAY,UAAU,QACpB,IAAI,OAAO,IAAI,cAAA,aAAa,YAAY,EAAE,EAAE,GAC5C,EACF;KACA,oBAAoB,kBAAkB,QACpC,IAAI,OAAO,IAAI,cAAA,aAAa,YAAY,EAAE,EAAE,GAC5C,EACF;IACF;IAKA,MAAM,sBACJ,kBAAkB,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK;IAExD,MAAM,sBACJ,cAAA,4BAA4B,mBAAmB;IAKjD,IAAI,EAHF,wBAAwB,uBACxB,uBAAuB,KAAK,mBAAmB,IAE5B;KACnB,MAAM,uBAAuB,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO;KAChE,MAAM,0BACJ,qBAAqB,qBAAqB,SAAS,MAAM;KAE3D,IAAI,uBAAuB,KAAK,uBAAuB,GAAG;MACxD,IAAI,kBAAkB,WAAW,GAC/B,YAAY;MAMd,MAAM,gBAAgB,cAAc;MAEpC,YACE,UAAU,QACR,IAAI,OAAO,IAAI,cAAA,aAAa,uBAAuB,EAAE,EAAE,GACvD,GACF,MAAM,gBAAgB,KAAK;MAE7B,oBACE,kBAAkB,QAChB,IAAI,OAAO,IAAI,cAAA,aAAa,mBAAmB,EAAE,EAAE,GACnD,GACF,MAAM,gBAAgB,KAAK;KAC/B;IACF;IAEA,WAAW,KAAK;KACd;KACA;KACA;KACA;KACA,cAAc;KACd;KACA,2BAA2B,cAAA,+BACzB,WACA,iBACF;IACF,CAAC;GACH;EACF,CAAC,CACH;EAEA,OAAO;CACT;CAEA,MAAM,QAAQ,IAAI;CAGlB,MAAM,gBACJ,WAAW,MACR,MACC,EAAE,cAAc,aAChB,CAAC;EACC;EACA;EACA;EACA;EACA;EACA;CACF,EAAE,SAAS,EAAE,YAAY,CAC7B,KAAK,WAAW,MAAM,MAAM,EAAE,cAAc,SAAgB;CAC9D,IAAI,eAAe;EACjB,cAAc,eAAe;EAC7B,cAAc,eAAe;CAC/B;CAEA,OAAO;EACL;EACA;EACA,qBAAqB;CACvB;AACF;;;;;;;;;AAUA,SAAgB,aACd,WACA,mBACA,cAiBA;CACA,IAAI,cAA2B;CAG/B,MAAM,mBAAmB,kBAAkB,MAAM,GAAG,EAAE,OAAO,OAAO;CACpE,MAAM,sBACJ,iBAAiB,iBAAiB,SAAS,MAAM;CAEnD,MAAM,EAAE,2BAA2B;CAInC,MAAM,mBAAmB,WAA4B;EACnD,OACE,oBAAoB,WAAW,GAAG,KAClC,oBAAoB,SAAS,GAAG,KAChC,cAAA,4BAA4B,mBAAmB,MAAM;CAEzD;CAEA,MAAM,gBAAgB,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO;CACzD,MAAM,mBAAmB,cAAc,cAAc,SAAS,MAAM;CAEpE,MAAM,sBAAsB,cAAA,4BAA4B,mBAAmB;CAC3E,MAAM,sBACJ,wBAAwB,uBACxB,uBAAuB,KAAK,mBAAmB;CAEjD,IAAI,uBAAuB,KAAK,gBAAgB,KAAK,CAAC,qBAEpD,cAAc;MACT,IAAI,UAAU,SAAS,OAAO,KAAK,CAAC,gBAAgB,MAAM,GAE/D,cAAc;MACT,IAAI,UAAU,SAAS,SAAS,KAAK,CAAC,gBAAgB,QAAQ,GAEnE,cAAc;MACT,IACL,UAAU,SAAS,YAAY,KAC/B,CAAC,gBAAgB,WAAW,GAG5B,cAAc;MACT,IACL,UAAU,SAAS,mBAAmB,KACtC,CAAC,gBAAgB,kBAAkB,GAGnC,cAAc;MACT,IACL,UAAU,SAAS,iBAAiB,KACpC,CAAC,gBAAgB,gBAAgB,GAGjC,cAAc;MACT,IACL,UAAU,SAAS,oBAAoB,KACvC,CAAC,gBAAgB,mBAAmB,GAGpC,cAAc;CAahB,MAAM,eAAe,cAAA,oBAPU,iBAAiB,MAC7C,QACC,IAAI,WAAW,GAAG,KAClB,IAAI,SAAS,GAAG,KAChB,CAAC,IAAI,MAAM,GAAG,EAAE,EAAE,SAAS,GAAG,KAC9B,CAAC,IAAI,MAAM,GAAG,EAAE,EAAE,SAAS,GAAG,CAGhC,IAAyB,oBAAoB,SAC/C;CAEA,OAAO;EAAE;EAAa;CAAa;AACrC;;;;;;;;;AAUA,SAAS,2BACP,qBACA,mBACA,WACA,cACS;CACT,IAAI,cAAc,QAChB,OAAO;CAGT,MAAM,WAAW,oBAAoB,MAAM,GAAG,EAAE,OAAO,OAAO;CAC9D,MAAM,mBAAmB,kBAAkB,MAAM,GAAG,EAAE,OAAO,OAAO;CAEpE,IAAI,SAAS,WAAW,GACtB,OAAO;CAGT,MAAM,mBAAmB,SAAS,SAAS,SAAS;CACpD,MAAM,sBACJ,iBAAiB,iBAAiB,SAAS,MAAM;CACnD,MAAM,2BAA2B,SAAS,SAAS,SAAS;CAC5D,MAAM,8BACJ,iBAAiB,iBAAiB,SAAS;CAG7C,IAAI,qBAAA,UACF,OAAO;CAGT,MAAM,EAAE,wBAAwB,2BAA2B;CAM3D,IACE,uBAAuB,KAAK,gBAAgB,KAC5C,OAAO,6BAA6B,YACpC,OAAO,gCAAgC,UACvC;EAEA,IAAI,cAAA,4BAA4B,2BAA2B,GACzD,OAAO;EAET,OAAO,yBAAyB,WAAW,GAAG;CAChD;CAIA,IAAI,cAAA,4BAA4B,mBAAmB,GACjD,OAAO;CAGT,OACE,CAAC,uBAAuB,KAAK,gBAAgB,KAC7C,CAAC,uBAAuB,KAAK,gBAAgB,KAC7C,iBAAiB,WAAW,GAAG;AAEnC"}