@nolebase/vitepress-plugin-page-properties
Version:
A VitePress plugin that renders frontmatter as page properties, and makes them editable.
1 lines • 21.8 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../../src/vite/path.ts","../../src/vite/markdownSection.ts","../../src/vite/pageProperties/dynamic/readingTime.ts","../../src/vite/pageProperties/index.ts"],"sourcesContent":["import { normalizePath } from 'vite'\n\nexport function pathEquals(path: string, equals: string): boolean {\n return normalizePath(path) === (normalizePath(equals))\n}\n\nexport function pathStartsWith(path: string, startsWith: string): boolean {\n return normalizePath(path).startsWith(normalizePath(startsWith))\n}\n\nexport function pathEndsWith(path: string, startsWith: string): boolean {\n return normalizePath(path).endsWith(normalizePath(startsWith))\n}\n","import type { Plugin } from 'vite'\n\nimport { relative } from 'node:path'\nimport { env } from 'node:process'\n\nimport GrayMatter from 'gray-matter'\n\nimport {\n pathEndsWith,\n pathEquals,\n pathStartsWith,\n} from './path'\n\nexport interface Context {\n helpers: {\n /**\n * A helper function to help to determine whether the passed string parameter equals the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param equalsWith - String to equal with\n * @returns boolean\n */\n idEquals: (equalsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed string parameter startsWith the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param startsWith - String to start with\n * @returns boolean\n */\n idStartsWith: (startsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed string parameter endsWith the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param endsWith - String to end with\n * @returns boolean\n */\n idEndsWith: (endsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * equals the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param equalsWith - String to equal with\n * @returns boolean\n */\n pathEquals: (path: string, equalsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * startsWith the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param startsWith - String to start with\n * @returns boolean\n */\n pathStartsWith: (path: string, startsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * endsWith the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param endsWith - String to end with\n * @returns boolean\n */\n pathEndsWith: (path: string, endsWith: string) => boolean\n }\n}\n\nexport interface PagePropertiesMarkdownSectionOptions {\n /**\n * The list of file names to exclude from the transformation\n *\n * @default ['index.md']\n */\n excludes?: string[]\n /**\n * The function to exclude the file from the transformation\n *\n * @param id - the current transforming module ID (comes from vite when transform hook is called)\n * @param context - the context object, contains several helper functions\n * @returns boolean\n * @default () => false\n */\n exclude?: (id: string, context: Context) => boolean\n}\n\nexport function PagePropertiesMarkdownSection(options?: PagePropertiesMarkdownSectionOptions): Plugin {\n const {\n excludes = ['index.md'],\n exclude = () => false,\n } = options ?? {}\n\n let root = ''\n\n return {\n name: '@nolebase/vitepress-plugin-page-properties-markdown-section',\n // May set to 'pre' since end user may use vitepress wrapped vite plugin to\n // specify the plugins, which may cause this plugin to be executed after\n // vitepress or the other markdown processing plugins.\n enforce: 'pre',\n configResolved(config) {\n root = config.root ?? ''\n },\n transform(code, id) {\n function idEndsWith(endsWith: string) {\n return pathEndsWith(relative(root, id), endsWith)\n }\n\n function idEquals(equals: string) {\n return pathEquals(relative(root, id), equals)\n }\n\n function idStartsWith(startsWith: string) {\n return pathStartsWith(relative(root, id), startsWith)\n }\n\n const context: Context = {\n helpers: {\n pathEndsWith,\n pathEquals,\n pathStartsWith,\n idEndsWith,\n idEquals,\n idStartsWith,\n },\n }\n\n if (!id.endsWith('.md'))\n return null\n if (excludes.includes(relative(root, id)))\n return null\n if (exclude(id, context))\n return null\n\n const targetComponent = env.NODE_ENV === 'development'\n ? TemplatePagePropertiesEditor()\n : TemplatePageProperties()\n\n const parsedMarkdownContent = GrayMatter(code)\n\n if ('nolebase' in parsedMarkdownContent.data && 'pageProperties' in parsedMarkdownContent.data.nolebase && !parsedMarkdownContent.data.nolebase.pageProperties)\n return null\n if ('pageProperties' in parsedMarkdownContent.data && !parsedMarkdownContent.data.pageProperties)\n return null\n\n const hasFrontmatter = Object.keys(parsedMarkdownContent.data).length > 0\n\n // match any heading and move heading to top, then insert component after heading\n const headingMatch = parsedMarkdownContent.content.match(/^# .*/m)\n if (!headingMatch || !headingMatch[0] || headingMatch.index === undefined) {\n if (!hasFrontmatter)\n return `${targetComponent}\\n\\n${code}`\n\n return `${GrayMatter.stringify(`${targetComponent}\\n\\n${parsedMarkdownContent.content}`, parsedMarkdownContent.data)}`\n }\n\n const headingPart = parsedMarkdownContent.content.slice(0, headingMatch.index + headingMatch[0].length)\n const contentPart = parsedMarkdownContent.content.slice(headingMatch.index + headingMatch[0].length)\n\n if (!hasFrontmatter)\n return `${headingPart}\\n${targetComponent}\\n\\n${contentPart}`\n\n return `${GrayMatter.stringify(`${headingPart}\\n${targetComponent}\\n\\n${contentPart}`, parsedMarkdownContent.data)}`\n },\n }\n}\n\nfunction TemplatePagePropertiesEditor(): string {\n return `\n\n<NolebasePagePropertiesEditor />\n`\n}\n\nfunction TemplatePageProperties(): string {\n return `\n\n<NolebasePageProperties />\n\n`\n}\n","// Great thanks to the following authors for the excellent reading time calculation code implementation\n//\n// Repository: vuepress-theme-hope\n// By: Mister-Hope <https://github.com/Mister-Hope>\n// Source code at: vuepress-theme-hope/packages/reading-time2/src/node/readingTime.ts <https://github.com/vuepress-theme-hope/vuepress-theme-hope/blob/main/packages/reading-time2/src/node/readingTime.ts>\n//\n// Repository: vuepress-theme-gungnir\n// By: Renovamen <https://github.com/Renovamen>\n// Source code at: vuepress-theme-gungnir/packages/plugins/reading-time/reading-time.js <https://github.com/Renovamen/vuepress-theme-gungnir/blob/v0/packages/plugins/reading-time/reading-time.js>\n//\n// Heavily inspired by the above two repositories, the following code is a combination of the two with some modifications and improvements.\n\n// Types for different language handlers and reading time calculation\nexport interface LanguageHandler {\n regex: RegExp\n wordsPerMinute: number\n}\n\nexport interface ReadingTimeStats {\n readingTime: number\n wordsCount: number\n}\n\n// Default language handlers for Chinese and Latin/Cyrillic based languages\nconst languageHandlers: Record<string, LanguageHandler> = {\n japanese: {\n regex: /\\p{Script=Hiragana}|\\p{Script=Katakana}/gu, // Match Japanese characters\n wordsPerMinute: 400, // Hypothetical average reading speed for Japanese\n },\n chinese: {\n regex: /\\p{Script=Han}/gu, // Match Chinese characters\n wordsPerMinute: 300, // Average reading speed for Chinese\n },\n latinCyrillic: {\n regex: /[\\p{Script=Latin}\\p{Script=Cyrillic}\\p{Mark}\\p{Punctuation}\\p{Number}]+/gu, // Match Latin and Cyrillic characters\n wordsPerMinute: 160, // Average reading speed for English and similar languages\n },\n}\n\n// Function to count words in a text based on the provided language handlers\nfunction countWordsByLanguage(content: string): Record<string, number> {\n return Object.keys(languageHandlers).reduce((accumulator, language) => {\n const match = content.match(languageHandlers[language].regex)\n accumulator[language] = match ? match.length : 0\n\n return accumulator\n }, {} as Record<string, number>)\n}\n\n// Function to calculate reading time across multiple languages\nexport function calculateWordsCountAndReadingTime(content: string): ReadingTimeStats {\n const wordsCounts = countWordsByLanguage(content)\n\n const totalWords = Object.values(wordsCounts).reduce((sum, count) => sum + count, 0)\n const totalMinutes = Object.entries(wordsCounts).reduce((sum, [language, count]) => {\n return sum + (count / languageHandlers[language].wordsPerMinute)\n }, 0)\n\n return {\n readingTime: Math.ceil(totalMinutes),\n wordsCount: totalWords,\n }\n}\n","import type { Plugin, ResolvedConfig } from 'vite'\nimport type { SiteConfig } from 'vitepress'\n\nimport type { LanguageHandler, ReadingTimeStats } from './dynamic/readingTime'\nimport type { PagePropertiesData } from './types'\n\nimport {\n existsSync,\n lstatSync,\n readFileSync,\n} from 'node:fs'\nimport { extname, relative } from 'node:path'\n\nimport GrayMatter from 'gray-matter'\n\nimport { normalizePath } from 'vite'\n\nimport { calculateWordsCountAndReadingTime } from './dynamic/readingTime'\n\nconst VirtualModuleID = 'virtual:nolebase-page-properties'\nconst ResolvedVirtualModuleId = `\\0${VirtualModuleID}`\n\nexport type {\n LanguageHandler,\n ReadingTimeStats as ReadingTimeResult,\n}\n\ninterface VitePressConfig extends ResolvedConfig {\n vitepress: SiteConfig\n}\n\nfunction normalizeWithRelative(from: string, path: string) {\n return normalizePath(relative(from, path)).toLowerCase()\n}\n\nexport function PageProperties(): Plugin {\n let _config: VitePressConfig\n let srcDir = ''\n const calculatedPagePropertiesActualData: PagePropertiesData = {}\n const knownMarkdownFiles = new Set<string>()\n\n return {\n name: '@nolebase/vitepress-plugin-page-properties',\n // May set to 'pre' since end user may use vitepress wrapped vite plugin to\n // specify the plugins, which may cause this plugin to be executed after\n // vitepress or the other markdown processing plugins.\n enforce: 'pre',\n config: () => ({\n optimizeDeps: {\n exclude: [\n '@nolebase/vitepress-plugin-page-properties/client',\n ],\n },\n ssr: {\n noExternal: [\n '@nolebase/vitepress-plugin-page-properties',\n ],\n },\n }),\n configResolved(config) {\n _config = config as VitePressConfig\n srcDir = _config.vitepress.srcDir\n },\n resolveId(id) {\n if (id === VirtualModuleID)\n return ResolvedVirtualModuleId\n },\n load(id) {\n if (id !== ResolvedVirtualModuleId)\n return null\n\n return `export default ${JSON.stringify(calculatedPagePropertiesActualData)}`\n },\n transform(code, id) {\n if (!id.endsWith('.md'))\n return null\n\n const parsedContent = GrayMatter(code)\n calculatedPagePropertiesActualData[normalizeWithRelative(srcDir, id)] = calculateWordsCountAndReadingTime(parsedContent.content)\n },\n configureServer(server) {\n compatibleConfigureServer(server, (_, env) => {\n env.hot.on('nolebase-page-properties:client-mounted', async (data) => {\n if (!data || typeof data !== 'object')\n return\n if (!('page' in data && 'filePath' in data.page))\n return\n\n const toMarkdownFilePath = data.page.filePath\n if (extname(data.page.filePath) !== '.md')\n return\n\n if (!knownMarkdownFiles.has(toMarkdownFilePath.toLowerCase())) {\n try {\n const exists = await existsSync(toMarkdownFilePath)\n if (!exists)\n return\n\n const stat = await lstatSync(toMarkdownFilePath)\n if (!stat.isFile())\n return\n\n knownMarkdownFiles.add(toMarkdownFilePath.toLowerCase())\n }\n catch {\n return\n }\n }\n if (!knownMarkdownFiles.has(toMarkdownFilePath.toLowerCase()))\n return\n\n const content = await readFileSync(toMarkdownFilePath, 'utf-8')\n const parsedContent = GrayMatter(content)\n calculatedPagePropertiesActualData[toMarkdownFilePath] = calculateWordsCountAndReadingTime(parsedContent.content)\n\n const virtualModule = env.moduleGraph.getModuleById(ResolvedVirtualModuleId)\n if (!virtualModule)\n return\n\n env.moduleGraph.invalidateModule(virtualModule)\n env.hot.send({\n type: 'custom',\n event: 'nolebase-page-properties:updated',\n data: calculatedPagePropertiesActualData,\n })\n })\n })\n },\n }\n}\n\ninterface Environment {\n hot: {\n on: (event: string, handler: (data: any) => void) => void\n send: (data: any) => void\n }\n moduleGraph: {\n getModuleById: (id: string) => any\n invalidateModule: (module: any) => void\n }\n}\n\nfunction compatibleConfigureServer<E extends Environment>(server: E, registerHandler: (name: string, env: E) => void | Promise<void>) {\n// Temporary workaround for Vite 5, both register for environments and server\n // When VitePress is upgraded to Vite 6, this can be removed\n if ('environments' in server && typeof server.environments === 'object' && server.environments != null) {\n Object.entries(server.environments).forEach(([name, env]) => registerHandler(name, env))\n }\n else {\n registerHandler('server', server)\n }\n}\n"],"names":["normalizePath","relative","env","GrayMatter","extname","existsSync","lstatSync","readFileSync"],"mappings":";;;;;;;;;;;;AAEO,SAAS,UAAA,CAAW,MAAc,MAAA,EAAyB;AAChE,EAAA,OAAOA,kBAAA,CAAc,IAAI,CAAA,KAAOA,kBAAA,CAAc,MAAM,CAAA;AACtD;AAEO,SAAS,cAAA,CAAe,MAAc,UAAA,EAA6B;AACxE,EAAA,OAAOA,mBAAc,IAAI,CAAA,CAAE,UAAA,CAAWA,kBAAA,CAAc,UAAU,CAAC,CAAA;AACjE;AAEO,SAAS,YAAA,CAAa,MAAc,UAAA,EAA6B;AACtE,EAAA,OAAOA,mBAAc,IAAI,CAAA,CAAE,QAAA,CAASA,kBAAA,CAAc,UAAU,CAAC,CAAA;AAC/D;;ACiFO,SAAS,8BAA8B,OAAA,EAAwD;AACpG,EAAA,MAAM;AAAA,IACJ,QAAA,GAAW,CAAC,UAAU,CAAA;AAAA,IACtB,UAAU,MAAM;AAAA,GAClB,GAAI,WAAW,EAAC;AAEhB,EAAA,IAAI,IAAA,GAAO,EAAA;AAEX,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,6DAAA;AAAA;AAAA;AAAA;AAAA,IAIN,OAAA,EAAS,KAAA;AAAA,IACT,eAAe,MAAA,EAAQ;AACrB,MAAA,IAAA,GAAO,OAAO,IAAA,IAAQ,EAAA;AAAA,IACxB,CAAA;AAAA,IACA,SAAA,CAAU,MAAM,EAAA,EAAI;AAClB,MAAA,SAAS,WAAW,QAAA,EAAkB;AACpC,QAAA,OAAO,YAAA,CAAaC,kBAAA,CAAS,IAAA,EAAM,EAAE,GAAG,QAAQ,CAAA;AAAA,MAClD;AAEA,MAAA,SAAS,SAAS,MAAA,EAAgB;AAChC,QAAA,OAAO,UAAA,CAAWA,kBAAA,CAAS,IAAA,EAAM,EAAE,GAAG,MAAM,CAAA;AAAA,MAC9C;AAEA,MAAA,SAAS,aAAa,UAAA,EAAoB;AACxC,QAAA,OAAO,cAAA,CAAeA,kBAAA,CAAS,IAAA,EAAM,EAAE,GAAG,UAAU,CAAA;AAAA,MACtD;AAEA,MAAA,MAAM,OAAA,GAAmB;AAAA,QACvB,OAAA,EAAS;AAAA,UACP,YAAA;AAAA,UACA,UAAA;AAAA,UACA,cAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AACF,OACF;AAEA,MAAA,IAAI,CAAC,EAAA,CAAG,QAAA,CAAS,KAAK,CAAA;AACpB,QAAA,OAAO,IAAA;AACT,MAAA,IAAI,QAAA,CAAS,QAAA,CAASA,kBAAA,CAAS,IAAA,EAAM,EAAE,CAAC,CAAA;AACtC,QAAA,OAAO,IAAA;AACT,MAAA,IAAI,OAAA,CAAQ,IAAI,OAAO,CAAA;AACrB,QAAA,OAAO,IAAA;AAET,MAAA,MAAM,kBAAkBC,gBAAA,CAAI,QAAA,KAAa,aAAA,GACrC,4BAAA,KACA,sBAAA,EAAuB;AAE3B,MAAA,MAAM,qBAAA,GAAwBC,oBAAW,IAAI,CAAA;AAE7C,MAAA,IAAI,UAAA,IAAc,qBAAA,CAAsB,IAAA,IAAQ,gBAAA,IAAoB,qBAAA,CAAsB,KAAK,QAAA,IAAY,CAAC,qBAAA,CAAsB,IAAA,CAAK,QAAA,CAAS,cAAA;AAC9I,QAAA,OAAO,IAAA;AACT,MAAA,IAAI,gBAAA,IAAoB,qBAAA,CAAsB,IAAA,IAAQ,CAAC,sBAAsB,IAAA,CAAK,cAAA;AAChF,QAAA,OAAO,IAAA;AAET,MAAA,MAAM,iBAAiB,MAAA,CAAO,IAAA,CAAK,qBAAA,CAAsB,IAAI,EAAE,MAAA,GAAS,CAAA;AAGxE,MAAA,MAAM,YAAA,GAAe,qBAAA,CAAsB,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA;AACjE,MAAA,IAAI,CAAC,gBAAgB,CAAC,YAAA,CAAa,CAAC,CAAA,IAAK,YAAA,CAAa,UAAU,MAAA,EAAW;AACzE,QAAA,IAAI,CAAC,cAAA;AACH,UAAA,OAAO,GAAG,eAAe;;AAAA,EAAO,IAAI,CAAA,CAAA;AAEtC,QAAA,OAAO,CAAA,EAAGA,mBAAA,CAAW,SAAA,CAAU,CAAA,EAAG,eAAe;;AAAA,EAAO,qBAAA,CAAsB,OAAO,CAAA,CAAA,EAAI,qBAAA,CAAsB,IAAI,CAAC,CAAA,CAAA;AAAA,MACtH;AAEA,MAAA,MAAM,WAAA,GAAc,qBAAA,CAAsB,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,aAAa,KAAA,GAAQ,YAAA,CAAa,CAAC,CAAA,CAAE,MAAM,CAAA;AACtG,MAAA,MAAM,WAAA,GAAc,sBAAsB,OAAA,CAAQ,KAAA,CAAM,aAAa,KAAA,GAAQ,YAAA,CAAa,CAAC,CAAA,CAAE,MAAM,CAAA;AAEnG,MAAA,IAAI,CAAC,cAAA;AACH,QAAA,OAAO,GAAG,WAAW;AAAA,EAAK,eAAe;;AAAA,EAAO,WAAW,CAAA,CAAA;AAE7D,MAAA,OAAO,CAAA,EAAGA,mBAAA,CAAW,SAAA,CAAU,CAAA,EAAG,WAAW;AAAA,EAAK,eAAe;;AAAA,EAAO,WAAW,CAAA,CAAA,EAAI,qBAAA,CAAsB,IAAI,CAAC,CAAA,CAAA;AAAA,IACpH;AAAA,GACF;AACF;AAEA,SAAS,4BAAA,GAAuC;AAC9C,EAAA,OAAO;;AAAA;AAAA,CAAA;AAIT;AAEA,SAAS,sBAAA,GAAiC;AACxC,EAAA,OAAO;;AAAA;;AAAA,CAAA;AAKT;;ACnKA,MAAM,gBAAA,GAAoD;AAAA,EACxD,QAAA,EAAU;AAAA,IACR,KAAA,EAAO,2CAAA;AAAA;AAAA,IACP,cAAA,EAAgB;AAAA;AAAA,GAClB;AAAA,EACA,OAAA,EAAS;AAAA,IACP,KAAA,EAAO,kBAAA;AAAA;AAAA,IACP,cAAA,EAAgB;AAAA;AAAA,GAClB;AAAA,EACA,aAAA,EAAe;AAAA,IACb,KAAA,EAAO,2EAAA;AAAA;AAAA,IACP,cAAA,EAAgB;AAAA;AAAA;AAEpB,CAAA;AAGA,SAAS,qBAAqB,OAAA,EAAyC;AACrE,EAAA,OAAO,OAAO,IAAA,CAAK,gBAAgB,EAAE,MAAA,CAAO,CAAC,aAAa,QAAA,KAAa;AACrE,IAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,gBAAA,CAAiB,QAAQ,EAAE,KAAK,CAAA;AAC5D,IAAA,WAAA,CAAY,QAAQ,CAAA,GAAI,KAAA,GAAQ,KAAA,CAAM,MAAA,GAAS,CAAA;AAE/C,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,EAA4B,CAAA;AACjC;AAGO,SAAS,kCAAkC,OAAA,EAAmC;AACnF,EAAA,MAAM,WAAA,GAAc,qBAAqB,OAAO,CAAA;AAEhD,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,WAAW,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,EAAK,KAAA,KAAU,GAAA,GAAM,KAAA,EAAO,CAAC,CAAA;AACnF,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,EAAK,CAAC,QAAA,EAAU,KAAK,CAAA,KAAM;AAClF,IAAA,OAAO,GAAA,GAAO,KAAA,GAAQ,gBAAA,CAAiB,QAAQ,CAAA,CAAE,cAAA;AAAA,EACnD,GAAG,CAAC,CAAA;AAEJ,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA;AAAA,IACnC,UAAA,EAAY;AAAA,GACd;AACF;;AC3CA,MAAM,eAAA,GAAkB,kCAAA;AACxB,MAAM,uBAAA,GAA0B,KAAK,eAAe,CAAA,CAAA;AAWpD,SAAS,qBAAA,CAAsB,MAAc,IAAA,EAAc;AACzD,EAAA,OAAOH,mBAAcC,kBAAA,CAAS,IAAA,EAAM,IAAI,CAAC,EAAE,WAAA,EAAY;AACzD;AAEO,SAAS,cAAA,GAAyB;AACvC,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,MAAM,qCAAyD,EAAC;AAChE,EAAA,MAAM,kBAAA,uBAAyB,GAAA,EAAY;AAE3C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,4CAAA;AAAA;AAAA;AAAA;AAAA,IAIN,OAAA,EAAS,KAAA;AAAA,IACT,QAAQ,OAAO;AAAA,MACb,YAAA,EAAc;AAAA,QACZ,OAAA,EAAS;AAAA,UACP;AAAA;AACF,OACF;AAAA,MACA,GAAA,EAAK;AAAA,QACH,UAAA,EAAY;AAAA,UACV;AAAA;AACF;AACF,KACF,CAAA;AAAA,IACA,eAAe,MAAA,EAAQ;AACrB,MAAA,OAAA,GAAU,MAAA;AACV,MAAA,MAAA,GAAS,QAAQ,SAAA,CAAU,MAAA;AAAA,IAC7B,CAAA;AAAA,IACA,UAAU,EAAA,EAAI;AACZ,MAAA,IAAI,EAAA,KAAO,eAAA;AACT,QAAA,OAAO,uBAAA;AAAA,IACX,CAAA;AAAA,IACA,KAAK,EAAA,EAAI;AACP,MAAA,IAAI,EAAA,KAAO,uBAAA;AACT,QAAA,OAAO,IAAA;AAET,MAAA,OAAO,CAAA,eAAA,EAAkB,IAAA,CAAK,SAAA,CAAU,kCAAkC,CAAC,CAAA,CAAA;AAAA,IAC7E,CAAA;AAAA,IACA,SAAA,CAAU,MAAM,EAAA,EAAI;AAClB,MAAA,IAAI,CAAC,EAAA,CAAG,QAAA,CAAS,KAAK,CAAA;AACpB,QAAA,OAAO,IAAA;AAET,MAAA,MAAM,aAAA,GAAgBE,oBAAW,IAAI,CAAA;AACrC,MAAA,kCAAA,CAAmC,sBAAsB,MAAA,EAAQ,EAAE,CAAC,CAAA,GAAI,iCAAA,CAAkC,cAAc,OAAO,CAAA;AAAA,IACjI,CAAA;AAAA,IACA,gBAAgB,MAAA,EAAQ;AACtB,MAAA,yBAAA,CAA0B,MAAA,EAAQ,CAAC,CAAA,EAAG,GAAA,KAAQ;AAC5C,QAAA,GAAA,CAAI,GAAA,CAAI,EAAA,CAAG,yCAAA,EAA2C,OAAO,IAAA,KAAS;AACpE,UAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA;AAC3B,YAAA;AACF,UAAA,IAAI,EAAE,MAAA,IAAU,IAAA,IAAQ,UAAA,IAAc,IAAA,CAAK,IAAA,CAAA;AACzC,YAAA;AAEF,UAAA,MAAM,kBAAA,GAAqB,KAAK,IAAA,CAAK,QAAA;AACrC,UAAA,IAAIC,iBAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,KAAM,KAAA;AAClC,YAAA;AAEF,UAAA,IAAI,CAAC,kBAAA,CAAmB,GAAA,CAAI,kBAAA,CAAmB,WAAA,EAAa,CAAA,EAAG;AAC7D,YAAA,IAAI;AACF,cAAA,MAAM,MAAA,GAAS,MAAMC,kBAAA,CAAW,kBAAkB,CAAA;AAClD,cAAA,IAAI,CAAC,MAAA;AACH,gBAAA;AAEF,cAAA,MAAM,IAAA,GAAO,MAAMC,iBAAA,CAAU,kBAAkB,CAAA;AAC/C,cAAA,IAAI,CAAC,KAAK,MAAA,EAAO;AACf,gBAAA;AAEF,cAAA,kBAAA,CAAmB,GAAA,CAAI,kBAAA,CAAmB,WAAA,EAAa,CAAA;AAAA,YACzD,CAAA,CAAA,MACM;AACJ,cAAA;AAAA,YACF;AAAA,UACF;AACA,UAAA,IAAI,CAAC,kBAAA,CAAmB,GAAA,CAAI,kBAAA,CAAmB,aAAa,CAAA;AAC1D,YAAA;AAEF,UAAA,MAAM,OAAA,GAAU,MAAMC,oBAAA,CAAa,kBAAA,EAAoB,OAAO,CAAA;AAC9D,UAAA,MAAM,aAAA,GAAgBJ,oBAAW,OAAO,CAAA;AACxC,UAAA,kCAAA,CAAmC,kBAAkB,CAAA,GAAI,iCAAA,CAAkC,aAAA,CAAc,OAAO,CAAA;AAEhH,UAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,WAAA,CAAY,aAAA,CAAc,uBAAuB,CAAA;AAC3E,UAAA,IAAI,CAAC,aAAA;AACH,YAAA;AAEF,UAAA,GAAA,CAAI,WAAA,CAAY,iBAAiB,aAAa,CAAA;AAC9C,UAAA,GAAA,CAAI,IAAI,IAAA,CAAK;AAAA,YACX,IAAA,EAAM,QAAA;AAAA,YACN,KAAA,EAAO,kCAAA;AAAA,YACP,IAAA,EAAM;AAAA,WACP,CAAA;AAAA,QACH,CAAC,CAAA;AAAA,MACH,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;AAaA,SAAS,yBAAA,CAAiD,QAAW,eAAA,EAAiE;AAGpI,EAAA,IAAI,cAAA,IAAkB,UAAU,OAAO,MAAA,CAAO,iBAAiB,QAAA,IAAY,MAAA,CAAO,gBAAgB,IAAA,EAAM;AACtG,IAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,YAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,IAAA,EAAM,GAAG,CAAA,KAAM,eAAA,CAAgB,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,EACzF,CAAA,MACK;AACH,IAAA,eAAA,CAAgB,UAAU,MAAM,CAAA;AAAA,EAClC;AACF;;;;;"}