@intlayer/chokidar
Version:
Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.
1 lines • 35 kB
Source Map (JSON)
{"version":3,"file":"transformJSFile.mjs","names":[],"sources":["../../../src/writeContentDeclaration/transformJSFile.ts"],"sourcesContent":["import { getNodeType } from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { ContentNode, Dictionary } from '@intlayer/types/dictionary';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport * as recast from 'recast';\nimport * as babelTsParser from 'recast/parsers/babel-ts.js';\n\nconst b = recast.types.builders;\nconst n = recast.types.namedTypes;\n\n/**\n * Unwraps TypeScript/Babel expression wrappers (satisfies, as, !, <Type>).\n * Uses string fallbacks to bypass outdated ast-types definitions.\n */\nconst unwrap = (node: any) => {\n while (\n node &&\n (n.TSSatisfiesExpression?.check(node) ||\n n.TSAsExpression?.check(node) ||\n n.TSTypeAssertion?.check(node) ||\n n.TSNonNullExpression?.check(node) ||\n [\n 'TSSatisfiesExpression',\n 'TSAsExpression',\n 'TSTypeAssertion',\n 'TSNonNullExpression',\n ].includes(node.type))\n ) {\n node = node.expression;\n }\n return node;\n};\n\n/**\n * Robustly finds a property in a recast ObjectExpression.\n * Handles quoted (\"key\") or unquoted (key) properties.\n */\nconst getMatchingProperty = (node: any, key: string) => {\n return node.properties.find((prop: any) => {\n if (n.Property.check(prop) || n.ObjectProperty.check(prop)) {\n if (n.Identifier.check(prop.key) && prop.key.name === key) return true;\n\n if (n.StringLiteral.check(prop.key) && prop.key.value === key)\n return true;\n\n if (n.Literal.check(prop.key) && prop.key.value === key) return true;\n }\n\n return false;\n });\n};\n\n/**\n * Synchronizes numeric suffixes across locales.\n * E.g. \"Hello 1\" -> \"Hello 3\" updates \"Bonjour 1\" to \"Bonjour 3\".\n */\nconst syncNumericSuffixAcrossLocales = (\n existingNode: any,\n fallbackLocaleCode: string,\n newFallbackValue: string\n) => {\n const trailingNumberMatch = newFallbackValue.match(/\\d+(?!.*\\d)/);\n if (!trailingNumberMatch) return;\n const newTrailingNumber = trailingNumberMatch[0];\n\n if (n.ObjectExpression.check(existingNode)) {\n for (const prop of existingNode.properties) {\n if (n.Property.check(prop) || n.ObjectProperty.check(prop)) {\n let propName = '';\n\n if (n.Identifier.check(prop.key)) propName = prop.key.name;\n else if (\n n.Literal.check(prop.key) &&\n typeof prop.key.value === 'string'\n )\n propName = prop.key.value;\n else if (n.StringLiteral.check(prop.key)) propName = prop.key.value;\n\n if (propName && propName !== fallbackLocaleCode) {\n if (\n n.Literal.check(prop.value) &&\n typeof prop.value.value === 'string'\n ) {\n const currentValue = prop.value.value;\n const currentTrailingNumberMatch =\n currentValue.match(/\\d+(?!.*\\d)/);\n\n if (currentTrailingNumberMatch) {\n prop.value = b.literal(\n currentValue.replace(/(\\d+)(?!.*\\d)/, newTrailingNumber)\n );\n }\n } else if (n.StringLiteral.check(prop.value)) {\n const currentValue = prop.value.value;\n const currentTrailingNumberMatch =\n currentValue.match(/\\d+(?!.*\\d)/);\n\n if (currentTrailingNumberMatch) {\n prop.value = b.stringLiteral(\n currentValue.replace(/(\\d+)(?!.*\\d)/, newTrailingNumber)\n );\n }\n }\n }\n }\n }\n }\n};\n\n/**\n * Checks if a value represents a multilingual Intlayer node.\n * A node is multilingual if it is a Translation node, or if it is a specialized node\n * (Markdown, HTML, etc.) that contains a Translation node.\n */\nconst isMultilingualNode = (val: any): boolean => {\n if (typeof val !== 'object' || val === null || Array.isArray(val)) {\n return false;\n }\n\n const nodeType = getNodeType(val as ContentNode);\n\n if (nodeType === NodeTypes.TRANSLATION) {\n return true;\n }\n\n if (\n nodeType === NodeTypes.MARKDOWN ||\n nodeType === NodeTypes.HTML ||\n nodeType === NodeTypes.INSERTION\n ) {\n return isMultilingualNode((val as any)[nodeType]);\n }\n\n if (\n nodeType === NodeTypes.ENUMERATION ||\n nodeType === NodeTypes.PLURAL ||\n nodeType === NodeTypes.CONDITION ||\n nodeType === NodeTypes.GENDER\n ) {\n const data = (val as any)[nodeType];\n\n if (data && typeof data === 'object') {\n return Object.values(data).some((v) => isMultilingualNode(v));\n }\n }\n\n return false;\n};\n\n/**\n * Recursively builds or updates an AST node for a given dictionary value.\n */\nconst buildNodeForValue = (\n val: any,\n existingNode: any,\n fallbackLocale: string | undefined, // In per-locale mode, this is the locale of the file\n requiredImports: Set<string>\n): any => {\n const unwrappedExisting = unwrap(existingNode);\n\n // --- CRITICAL GUARD: STRICT AST PRESERVATION ---\n // If the existing node is code (JSX, Variables, standard functions), leave it alone.\n // Only allow updates to literals, plain objects, arrays, and Intlayer helpers.\n if (unwrappedExisting) {\n const isUpdatableNode =\n n.Literal.check(unwrappedExisting) ||\n n.StringLiteral.check(unwrappedExisting) ||\n n.NumericLiteral.check(unwrappedExisting) ||\n n.BooleanLiteral.check(unwrappedExisting) ||\n n.TemplateLiteral.check(unwrappedExisting) ||\n n.ObjectExpression.check(unwrappedExisting) ||\n n.ArrayExpression.check(unwrappedExisting) ||\n (n.CallExpression.check(unwrappedExisting) &&\n n.Identifier.check(unwrappedExisting.callee) &&\n [\n 't',\n 'enu',\n 'plural',\n 'cond',\n 'gender',\n 'insert',\n 'md',\n 'html',\n 'file',\n 'nest',\n ].includes(unwrappedExisting.callee.name));\n\n if (!isUpdatableNode) {\n return existingNode;\n }\n }\n\n // If we are in per-locale mode (fallbackLocale is set)\n // and the value is not already a complex translation node,\n // we want to store it as a simple literal, NOT wrapped in t().\n if (fallbackLocale && !existingNode && !isMultilingualNode(val)) {\n if (val === null) return b.literal(null);\n if (\n typeof val === 'string' ||\n typeof val === 'number' ||\n typeof val === 'boolean'\n ) {\n if (typeof val === 'string' && val.includes('\\n')) {\n return b.templateLiteral(\n [b.templateElement({ raw: val, cooked: val }, true)],\n []\n );\n }\n return b.literal(val);\n }\n }\n\n if (fallbackLocale && existingNode && !isMultilingualNode(val)) {\n if (\n n.CallExpression.check(existingNode) &&\n n.Identifier.check(existingNode.callee) &&\n existingNode.callee.name === 't'\n ) {\n const arg = unwrap(existingNode.arguments[0]);\n\n if (n.ObjectExpression.check(arg)) {\n if (typeof val === 'string') {\n syncNumericSuffixAcrossLocales(arg, fallbackLocale, val);\n }\n updateObjectLiteral(\n arg,\n { [fallbackLocale]: val },\n fallbackLocale,\n requiredImports\n );\n\n if (!fallbackLocale) {\n requiredImports.add('t');\n }\n\n return existingNode;\n }\n }\n\n if (\n (!val || typeof val !== 'object') &&\n n.CallExpression.check(existingNode) &&\n n.Identifier.check(existingNode.callee) &&\n existingNode.callee.name === 'md'\n ) {\n const innerArg = existingNode.arguments[0];\n\n if (\n n.CallExpression.check(innerArg) &&\n n.Identifier.check(innerArg.callee) &&\n innerArg.callee.name === 't'\n ) {\n const tArg = unwrap(innerArg.arguments[0]);\n\n if (n.ObjectExpression.check(tArg)) {\n if (typeof val === 'string') {\n syncNumericSuffixAcrossLocales(tArg, fallbackLocale, val);\n }\n updateObjectLiteral(\n tArg,\n { [fallbackLocale]: val },\n fallbackLocale,\n requiredImports\n );\n requiredImports.add('md');\n requiredImports.add('t');\n\n return existingNode;\n }\n }\n }\n }\n\n // 1. Primitives\n if (val === null) return b.literal(null);\n if (\n typeof val === 'string' ||\n typeof val === 'number' ||\n typeof val === 'boolean'\n ) {\n if (unwrappedExisting) {\n // Preserve existing template literals (backticks)\n if (\n n.TemplateLiteral.check(unwrappedExisting) &&\n unwrappedExisting.expressions.length === 0\n ) {\n unwrappedExisting.quasis[0].value.raw = String(val);\n unwrappedExisting.quasis[0].value.cooked = String(val);\n return existingNode;\n }\n // Preserve existing standard literals (keeps quote styling)\n if (\n n.Literal.check(unwrappedExisting) ||\n n.StringLiteral.check(unwrappedExisting)\n ) {\n unwrappedExisting.value = val;\n return existingNode;\n }\n }\n\n // Force multiline strings to use Template Literals\n if (typeof val === 'string' && val.includes('\\n')) {\n return b.templateLiteral(\n [b.templateElement({ raw: val, cooked: val }, true)],\n []\n );\n }\n return b.literal(val);\n }\n\n // 2. Arrays\n if (Array.isArray(val)) {\n if (unwrappedExisting && n.ArrayExpression.check(unwrappedExisting)) {\n const elements = [...unwrappedExisting.elements];\n val.forEach((item, i) => {\n elements[i] = buildNodeForValue(\n item,\n elements[i],\n fallbackLocale,\n requiredImports\n );\n });\n\n if (elements.length > val.length) elements.length = val.length;\n unwrappedExisting.elements = elements as any;\n\n return existingNode;\n } else {\n return b.arrayExpression(\n val.map((item) =>\n buildNodeForValue(item, null, fallbackLocale, requiredImports)\n )\n );\n }\n }\n\n // 3. Intlayer Specialized Nodes\n const nodeType =\n val && typeof val === 'object' && !Array.isArray(val)\n ? getNodeType(val as ContentNode)\n : null;\n\n if (\n nodeType &&\n [\n NodeTypes.TRANSLATION,\n NodeTypes.ENUMERATION,\n NodeTypes.PLURAL,\n NodeTypes.CONDITION,\n NodeTypes.GENDER,\n NodeTypes.INSERTION,\n NodeTypes.MARKDOWN,\n NodeTypes.HTML,\n NodeTypes.FILE,\n NodeTypes.NESTED,\n NodeTypes.ARRAY,\n NodeTypes.OBJECT,\n NodeTypes.REACT_NODE,\n NodeTypes.NUMBER,\n NodeTypes.BOOLEAN,\n NodeTypes.NULL,\n NodeTypes.UNKNOWN,\n ].includes(nodeType as any) &&\n nodeType !== NodeTypes.TEXT\n ) {\n const nodeData = (val as any)[nodeType];\n let calleeName = '';\n\n if (nodeType === NodeTypes.TRANSLATION) calleeName = 't';\n else if (nodeType === NodeTypes.ENUMERATION) calleeName = 'enu';\n else if (nodeType === NodeTypes.PLURAL) calleeName = 'plural';\n else if (nodeType === NodeTypes.CONDITION) calleeName = 'cond';\n else if (nodeType === NodeTypes.GENDER) calleeName = 'gender';\n else if (nodeType === NodeTypes.INSERTION) calleeName = 'insert';\n else if (nodeType === NodeTypes.MARKDOWN) calleeName = 'md';\n else if (nodeType === NodeTypes.HTML) calleeName = 'html';\n else if (nodeType === NodeTypes.FILE) calleeName = 'file';\n else if (nodeType === NodeTypes.NESTED) calleeName = 'nest';\n\n if (calleeName) requiredImports.add(calleeName);\n\n const isMatchingCall =\n existingNode &&\n n.CallExpression.check(existingNode) &&\n n.Identifier.check(existingNode.callee) &&\n existingNode.callee.name === calleeName;\n\n if (['t', 'enu', 'plural', 'cond', 'gender'].includes(calleeName)) {\n let objArg: any = null;\n\n if (\n isMatchingCall &&\n existingNode.arguments.length > 0 &&\n n.ObjectExpression.check(existingNode.arguments[0])\n ) {\n objArg = existingNode.arguments[0];\n } else {\n objArg = b.objectExpression([]);\n }\n updateObjectLiteral(objArg, nodeData, fallbackLocale, requiredImports);\n\n return isMatchingCall\n ? existingNode\n : b.callExpression(b.identifier(calleeName), [objArg]);\n }\n\n if (['md', 'html', 'insert', 'file'].includes(calleeName)) {\n const argNode = buildNodeForValue(\n nodeData,\n isMatchingCall && existingNode.arguments.length > 0\n ? existingNode.arguments[0]\n : null,\n fallbackLocale,\n requiredImports\n );\n\n if (isMatchingCall) {\n existingNode.arguments[0] = argNode;\n\n return existingNode;\n }\n\n return b.callExpression(b.identifier(calleeName), [argNode]);\n }\n\n if (calleeName === 'nest') {\n const args = [b.literal(nodeData.dictionaryKey)];\n\n if (nodeData.path) args.push(b.literal(nodeData.path));\n\n if (isMatchingCall) {\n existingNode.arguments = args;\n\n return existingNode;\n }\n\n return b.callExpression(b.identifier('nest'), args);\n }\n }\n\n // 4. Plain Object\n const objNode =\n unwrappedExisting && n.ObjectExpression.check(unwrappedExisting)\n ? unwrappedExisting\n : b.objectExpression([]);\n\n updateObjectLiteral(objNode, val, fallbackLocale, requiredImports);\n\n return existingNode && unwrappedExisting === existingNode\n ? objNode\n : existingNode || objNode;\n};\n\n/**\n * Recursively updates the AST object literal properties.\n */\nconst updateObjectLiteral = (\n node: recast.types.namedTypes.ObjectExpression,\n data: Record<string, any>,\n fallbackLocale: string | undefined,\n requiredImports: Set<string>\n) => {\n for (const [key, val] of Object.entries(data)) {\n if (val === undefined) continue;\n\n const existingProp = getMatchingProperty(node, key);\n\n if (existingProp) {\n existingProp.value = buildNodeForValue(\n val,\n existingProp.value,\n fallbackLocale,\n requiredImports\n );\n } else {\n const isValidId = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);\n const keyNode = isValidId ? b.identifier(key) : b.literal(key);\n const valueNode = buildNodeForValue(\n val,\n null,\n fallbackLocale,\n requiredImports\n );\n node.properties.push(b.property('init', keyNode, valueNode));\n }\n }\n};\n\n/**\n * Modifies the AST's top-level imports to inject dynamically needed helper utilities seamlessly.\n */\nconst addImports = (ast: any, requiredImports: Set<string>, isESM: boolean) => {\n if (requiredImports.size === 0) return;\n\n const existingCoreImports = new Set<string>();\n let coreImportPath: any = null;\n\n recast.visit(ast, {\n visitImportDeclaration(path) {\n const source = path.node.source.value;\n\n if (source === 'intlayer') {\n coreImportPath = path;\n path.node.specifiers?.forEach((spec) => {\n if (\n n.ImportSpecifier.check(spec) &&\n typeof spec.imported.name === 'string'\n ) {\n existingCoreImports.add(spec.imported.name);\n }\n });\n }\n\n return false;\n },\n visitVariableDeclaration(path) {\n path.node.declarations.forEach((decl) => {\n if (\n n.VariableDeclarator.check(decl) &&\n n.CallExpression.check(decl.init) &&\n n.Identifier.check(decl.init.callee) &&\n decl.init.callee.name === 'require'\n ) {\n const arg = decl.init.arguments[0];\n\n if (n.Literal.check(arg)) {\n if (arg.value === 'intlayer') {\n if (n.ObjectPattern.check(decl.id)) {\n decl.id.properties.forEach((prop) => {\n if (\n n.Property.check(prop) &&\n (n.Identifier.check(prop.key) ||\n n.Identifier.check(prop.value))\n ) {\n const name = n.Identifier.check(prop.key)\n ? prop.key.name\n : (prop.value as any).name;\n existingCoreImports.add(name);\n }\n });\n } else if (n.Identifier.check(decl.id)) {\n // Handle const intlayer = require('intlayer')\n existingCoreImports.add(decl.id.name);\n }\n }\n }\n }\n });\n\n return false;\n },\n });\n\n const missingCore = Array.from(requiredImports).filter(\n (imp) => !existingCoreImports.has(imp)\n );\n\n if (missingCore.length === 0) return;\n\n if (isESM) {\n if (coreImportPath) {\n missingCore.forEach((imp) => {\n coreImportPath.node.specifiers.push(\n b.importSpecifier(b.identifier(imp))\n );\n });\n coreImportPath.node.specifiers.sort((a: any, b: any) =>\n a.imported.name.localeCompare(b.imported.name)\n );\n } else {\n const specifiers = missingCore\n .sort()\n .map((imp) => b.importSpecifier(b.identifier(imp)));\n const newImport = b.importDeclaration(specifiers, b.literal('intlayer'));\n ast.program.body.unshift(newImport);\n }\n } else {\n let insertIndex = 0;\n\n if (\n ast.program.body.length > 0 &&\n n.ExpressionStatement.check(ast.program.body[0]) &&\n n.Literal.check(ast.program.body[0].expression)\n ) {\n insertIndex = 1; // Insert after 'use strict'\n }\n const cjsLines: any[] = [];\n\n const properties = missingCore.sort().map((imp) => {\n const prop = b.property('init', b.identifier(imp), b.identifier(imp));\n prop.shorthand = true;\n\n return prop;\n });\n cjsLines.push(\n b.variableDeclaration('const', [\n b.variableDeclarator(\n b.objectPattern(properties),\n b.callExpression(b.identifier('require'), [b.literal('intlayer')])\n ),\n ])\n );\n\n ast.program.body.splice(insertIndex, 0, ...cjsLines);\n }\n};\n\n/**\n * Updates a JS/TS file seamlessly to map new localization keys, arrays, complex nodes and nested dictionaries gracefully using AST updates via Recast parser.\n */\nexport const transformJSFile = async (\n fileContent: string,\n dictionary: Dictionary,\n fallbackLocale?: Locale,\n noMetadata?: boolean\n): Promise<string> => {\n if (!dictionary || typeof dictionary !== 'object') return fileContent;\n\n let ast: any;\n try {\n ast = recast.parse(fileContent, {\n parser: babelTsParser,\n });\n } catch (error) {\n console.error({ error });\n return fileContent;\n }\n\n let rootObject: any = null;\n let isESM = false;\n\n recast.visit(ast, {\n visitExportDefaultDeclaration() {\n isESM = true;\n\n return false;\n },\n visitImportDeclaration() {\n isESM = true;\n\n return false;\n },\n });\n\n recast.visit(ast, {\n visitExportDefaultDeclaration(path) {\n const decl = path.node.declaration;\n const unwrappedDecl = unwrap(decl);\n\n if (n.ObjectExpression.check(unwrappedDecl)) {\n rootObject = unwrappedDecl;\n } else if (n.Identifier.check(unwrappedDecl)) {\n const varName = unwrappedDecl.name;\n recast.visit(ast, {\n visitVariableDeclarator(vp) {\n const unwrappedInit = unwrap(vp.node.init);\n\n if (\n n.Identifier.check(vp.node.id) &&\n vp.node.id.name === varName &&\n n.ObjectExpression.check(unwrappedInit)\n ) {\n rootObject = unwrappedInit;\n }\n\n return false;\n },\n });\n }\n\n return false;\n },\n visitAssignmentExpression(path) {\n const left = path.node.left;\n\n if (n.MemberExpression.check(left)) {\n if (\n n.Identifier.check(left.object) &&\n left.object.name === 'module' &&\n n.Identifier.check(left.property) &&\n left.property.name === 'exports'\n ) {\n const unwrappedRight = unwrap(path.node.right);\n\n if (n.ObjectExpression.check(unwrappedRight)) {\n rootObject = unwrappedRight;\n }\n }\n\n if (\n n.Identifier.check(left.object) &&\n left.object.name === 'exports' &&\n n.Identifier.check(left.property) &&\n left.property.name === 'default'\n ) {\n const unwrappedRight = unwrap(path.node.right);\n\n if (n.ObjectExpression.check(unwrappedRight)) {\n rootObject = unwrappedRight;\n }\n }\n }\n this.traverse(path);\n },\n });\n\n if (!rootObject) {\n recast.visit(ast, {\n visitVariableDeclarator(path) {\n const unwrappedInit = unwrap(path.node.init);\n\n if (!rootObject && n.ObjectExpression.check(unwrappedInit)) {\n rootObject = unwrappedInit;\n }\n\n return false;\n },\n });\n }\n\n if (!rootObject) return fileContent;\n\n const requiredImports = new Set<string>();\n const effectiveFallbackLocale = (fallbackLocale as string) ?? 'en';\n\n const metadataProperties = [\n 'id',\n 'locale',\n 'filled',\n 'fill',\n 'title',\n 'description',\n 'tags',\n 'version',\n 'priority',\n 'contentAutoTransformation',\n ];\n\n if (noMetadata) {\n // Remove key, content and metadata properties if they exist\n rootObject.properties = rootObject.properties.filter((prop: any) => {\n if (n.Property.check(prop) || n.ObjectProperty.check(prop)) {\n let propName = '';\n if (n.Identifier.check(prop.key)) propName = prop.key.name;\n else if (n.StringLiteral.check(prop.key)) propName = prop.key.value;\n else if (n.Literal.check(prop.key)) propName = String(prop.key.value);\n\n return !['key', 'content', ...metadataProperties].includes(propName);\n }\n return true;\n });\n\n // Update satisfies type if exists\n recast.visit(ast, {\n visitNode(path) {\n const node = path.node;\n if (\n (n.TSSatisfiesExpression?.check(node) ||\n node.type === 'TSSatisfiesExpression') &&\n (node as any).typeAnnotation &&\n n.TSTypeReference.check((node as any).typeAnnotation) &&\n n.Identifier.check((node as any).typeAnnotation.typeName) &&\n (node as any).typeAnnotation.typeName.name === 'Dictionary'\n ) {\n (node as any).typeAnnotation = b.tsIndexedAccessType(\n b.tsTypeReference(b.identifier('Dictionary')),\n b.tsLiteralType(b.stringLiteral('content'))\n );\n }\n this.traverse(path);\n },\n });\n } else {\n for (const prop of metadataProperties) {\n if ((dictionary as any)[prop] !== undefined) {\n updateObjectLiteral(\n rootObject,\n { [prop]: (dictionary as any)[prop] },\n undefined,\n requiredImports\n );\n }\n }\n }\n\n if (dictionary.content !== undefined) {\n updateObjectLiteral(\n rootObject,\n noMetadata\n ? (dictionary.content as Record<string, any>)\n : { content: dictionary.content },\n effectiveFallbackLocale,\n requiredImports\n );\n }\n\n addImports(ast, requiredImports, isESM);\n\n return recast.print(ast).code;\n};\n"],"mappings":";;;;;;AAOA,MAAM,IAAI,OAAO,MAAM;AACvB,MAAM,IAAI,OAAO,MAAM;;;;;AAMvB,MAAM,UAAU,SAAc;CAC5B,OACE,SACC,EAAE,uBAAuB,MAAM,IAAI,KAClC,EAAE,gBAAgB,MAAM,IAAI,KAC5B,EAAE,iBAAiB,MAAM,IAAI,KAC7B,EAAE,qBAAqB,MAAM,IAAI,KACjC;EACE;EACA;EACA;EACA;CACF,EAAE,SAAS,KAAK,IAAI,IAEtB,OAAO,KAAK;CAEd,OAAO;AACT;;;;;AAMA,MAAM,uBAAuB,MAAW,QAAgB;CACtD,OAAO,KAAK,WAAW,MAAM,SAAc;EACzC,IAAI,EAAE,SAAS,MAAM,IAAI,KAAK,EAAE,eAAe,MAAM,IAAI,GAAG;GAC1D,IAAI,EAAE,WAAW,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO;GAElE,IAAI,EAAE,cAAc,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,UAAU,KACxD,OAAO;GAET,IAAI,EAAE,QAAQ,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,UAAU,KAAK,OAAO;EAClE;EAEA,OAAO;CACT,CAAC;AACH;;;;;AAMA,MAAM,kCACJ,cACA,oBACA,qBACG;CACH,MAAM,sBAAsB,iBAAiB,MAAM,aAAa;CAChE,IAAI,CAAC,qBAAqB;CAC1B,MAAM,oBAAoB,oBAAoB;CAE9C,IAAI,EAAE,iBAAiB,MAAM,YAAY,GACvC;OAAK,MAAM,QAAQ,aAAa,YAC9B,IAAI,EAAE,SAAS,MAAM,IAAI,KAAK,EAAE,eAAe,MAAM,IAAI,GAAG;GAC1D,IAAI,WAAW;GAEf,IAAI,EAAE,WAAW,MAAM,KAAK,GAAG,GAAG,WAAW,KAAK,IAAI;QACjD,IACH,EAAE,QAAQ,MAAM,KAAK,GAAG,KACxB,OAAO,KAAK,IAAI,UAAU,UAE1B,WAAW,KAAK,IAAI;QACjB,IAAI,EAAE,cAAc,MAAM,KAAK,GAAG,GAAG,WAAW,KAAK,IAAI;GAE9D,IAAI,YAAY,aAAa,oBAC3B;QACE,EAAE,QAAQ,MAAM,KAAK,KAAK,KAC1B,OAAO,KAAK,MAAM,UAAU,UAC5B;KACA,MAAM,eAAe,KAAK,MAAM;KAIhC,IAFE,aAAa,MAAM,aAEQ,GAC3B,KAAK,QAAQ,EAAE,QACb,aAAa,QAAQ,iBAAiB,iBAAiB,CACzD;IAEJ,OAAO,IAAI,EAAE,cAAc,MAAM,KAAK,KAAK,GAAG;KAC5C,MAAM,eAAe,KAAK,MAAM;KAIhC,IAFE,aAAa,MAAM,aAEQ,GAC3B,KAAK,QAAQ,EAAE,cACb,aAAa,QAAQ,iBAAiB,iBAAiB,CACzD;IAEJ;;EAEJ;CACF;AAEJ;;;;;;AAOA,MAAM,sBAAsB,QAAsB;CAChD,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAC9D,OAAO;CAGT,MAAM,WAAW,YAAY,GAAkB;CAE/C,IAAI,aAAa,UAAU,aACzB,OAAO;CAGT,IACE,aAAa,UAAU,YACvB,aAAa,UAAU,QACvB,aAAa,UAAU,WAEvB,OAAO,mBAAoB,IAAY,SAAS;CAGlD,IACE,aAAa,UAAU,eACvB,aAAa,UAAU,UACvB,aAAa,UAAU,aACvB,aAAa,UAAU,QACvB;EACA,MAAM,OAAQ,IAAY;EAE1B,IAAI,QAAQ,OAAO,SAAS,UAC1B,OAAO,OAAO,OAAO,IAAI,EAAE,MAAM,MAAM,mBAAmB,CAAC,CAAC;CAEhE;CAEA,OAAO;AACT;;;;AAKA,MAAM,qBACJ,KACA,cACA,gBACA,oBACQ;CACR,MAAM,oBAAoB,OAAO,YAAY;CAK7C,IAAI,mBAwBF;MAAI,EAtBF,EAAE,QAAQ,MAAM,iBAAiB,KACjC,EAAE,cAAc,MAAM,iBAAiB,KACvC,EAAE,eAAe,MAAM,iBAAiB,KACxC,EAAE,eAAe,MAAM,iBAAiB,KACxC,EAAE,gBAAgB,MAAM,iBAAiB,KACzC,EAAE,iBAAiB,MAAM,iBAAiB,KAC1C,EAAE,gBAAgB,MAAM,iBAAiB,KACxC,EAAE,eAAe,MAAM,iBAAiB,KACvC,EAAE,WAAW,MAAM,kBAAkB,MAAM,KAC3C;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,EAAE,SAAS,kBAAkB,OAAO,IAAI,IAG1C,OAAO;CACT;CAMF,IAAI,kBAAkB,CAAC,gBAAgB,CAAC,mBAAmB,GAAG,GAAG;EAC/D,IAAI,QAAQ,MAAM,OAAO,EAAE,QAAQ,IAAI;EACvC,IACE,OAAO,QAAQ,YACf,OAAO,QAAQ,YACf,OAAO,QAAQ,WACf;GACA,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,GAC9C,OAAO,EAAE,gBACP,CAAC,EAAE,gBAAgB;IAAE,KAAK;IAAK,QAAQ;GAAI,GAAG,IAAI,CAAC,GACnD,CAAC,CACH;GAEF,OAAO,EAAE,QAAQ,GAAG;EACtB;CACF;CAEA,IAAI,kBAAkB,gBAAgB,CAAC,mBAAmB,GAAG,GAAG;EAC9D,IACE,EAAE,eAAe,MAAM,YAAY,KACnC,EAAE,WAAW,MAAM,aAAa,MAAM,KACtC,aAAa,OAAO,SAAS,KAC7B;GACA,MAAM,MAAM,OAAO,aAAa,UAAU,EAAE;GAE5C,IAAI,EAAE,iBAAiB,MAAM,GAAG,GAAG;IACjC,IAAI,OAAO,QAAQ,UACjB,+BAA+B,KAAK,gBAAgB,GAAG;IAEzD,oBACE,KACA,GAAG,iBAAiB,IAAI,GACxB,gBACA,eACF;IAEA,IAAI,CAAC,gBACH,gBAAgB,IAAI,GAAG;IAGzB,OAAO;GACT;EACF;EAEA,KACG,CAAC,OAAO,OAAO,QAAQ,aACxB,EAAE,eAAe,MAAM,YAAY,KACnC,EAAE,WAAW,MAAM,aAAa,MAAM,KACtC,aAAa,OAAO,SAAS,MAC7B;GACA,MAAM,WAAW,aAAa,UAAU;GAExC,IACE,EAAE,eAAe,MAAM,QAAQ,KAC/B,EAAE,WAAW,MAAM,SAAS,MAAM,KAClC,SAAS,OAAO,SAAS,KACzB;IACA,MAAM,OAAO,OAAO,SAAS,UAAU,EAAE;IAEzC,IAAI,EAAE,iBAAiB,MAAM,IAAI,GAAG;KAClC,IAAI,OAAO,QAAQ,UACjB,+BAA+B,MAAM,gBAAgB,GAAG;KAE1D,oBACE,MACA,GAAG,iBAAiB,IAAI,GACxB,gBACA,eACF;KACA,gBAAgB,IAAI,IAAI;KACxB,gBAAgB,IAAI,GAAG;KAEvB,OAAO;IACT;GACF;EACF;CACF;CAGA,IAAI,QAAQ,MAAM,OAAO,EAAE,QAAQ,IAAI;CACvC,IACE,OAAO,QAAQ,YACf,OAAO,QAAQ,YACf,OAAO,QAAQ,WACf;EACA,IAAI,mBAAmB;GAErB,IACE,EAAE,gBAAgB,MAAM,iBAAiB,KACzC,kBAAkB,YAAY,WAAW,GACzC;IACA,kBAAkB,OAAO,GAAG,MAAM,MAAM,OAAO,GAAG;IAClD,kBAAkB,OAAO,GAAG,MAAM,SAAS,OAAO,GAAG;IACrD,OAAO;GACT;GAEA,IACE,EAAE,QAAQ,MAAM,iBAAiB,KACjC,EAAE,cAAc,MAAM,iBAAiB,GACvC;IACA,kBAAkB,QAAQ;IAC1B,OAAO;GACT;EACF;EAGA,IAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,GAC9C,OAAO,EAAE,gBACP,CAAC,EAAE,gBAAgB;GAAE,KAAK;GAAK,QAAQ;EAAI,GAAG,IAAI,CAAC,GACnD,CAAC,CACH;EAEF,OAAO,EAAE,QAAQ,GAAG;CACtB;CAGA,IAAI,MAAM,QAAQ,GAAG,GACnB,IAAI,qBAAqB,EAAE,gBAAgB,MAAM,iBAAiB,GAAG;EACnE,MAAM,WAAW,CAAC,GAAG,kBAAkB,QAAQ;EAC/C,IAAI,SAAS,MAAM,MAAM;GACvB,SAAS,KAAK,kBACZ,MACA,SAAS,IACT,gBACA,eACF;EACF,CAAC;EAED,IAAI,SAAS,SAAS,IAAI,QAAQ,SAAS,SAAS,IAAI;EACxD,kBAAkB,WAAW;EAE7B,OAAO;CACT,OACE,OAAO,EAAE,gBACP,IAAI,KAAK,SACP,kBAAkB,MAAM,MAAM,gBAAgB,eAAe,CAC/D,CACF;CAKJ,MAAM,WACJ,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IAChD,YAAY,GAAkB,IAC9B;CAEN,IACE,YACA;EACE,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;EACV,UAAU;CACZ,EAAE,SAAS,QAAe,KAC1B,aAAa,UAAU,MACvB;EACA,MAAM,WAAY,IAAY;EAC9B,IAAI,aAAa;EAEjB,IAAI,aAAa,UAAU,aAAa,aAAa;OAChD,IAAI,aAAa,UAAU,aAAa,aAAa;OACrD,IAAI,aAAa,UAAU,QAAQ,aAAa;OAChD,IAAI,aAAa,UAAU,WAAW,aAAa;OACnD,IAAI,aAAa,UAAU,QAAQ,aAAa;OAChD,IAAI,aAAa,UAAU,WAAW,aAAa;OACnD,IAAI,aAAa,UAAU,UAAU,aAAa;OAClD,IAAI,aAAa,UAAU,MAAM,aAAa;OAC9C,IAAI,aAAa,UAAU,MAAM,aAAa;OAC9C,IAAI,aAAa,UAAU,QAAQ,aAAa;EAErD,IAAI,YAAY,gBAAgB,IAAI,UAAU;EAE9C,MAAM,iBACJ,gBACA,EAAE,eAAe,MAAM,YAAY,KACnC,EAAE,WAAW,MAAM,aAAa,MAAM,KACtC,aAAa,OAAO,SAAS;EAE/B,IAAI;GAAC;GAAK;GAAO;GAAU;GAAQ;EAAQ,EAAE,SAAS,UAAU,GAAG;GACjE,IAAI,SAAc;GAElB,IACE,kBACA,aAAa,UAAU,SAAS,KAChC,EAAE,iBAAiB,MAAM,aAAa,UAAU,EAAE,GAElD,SAAS,aAAa,UAAU;QAEhC,SAAS,EAAE,iBAAiB,CAAC,CAAC;GAEhC,oBAAoB,QAAQ,UAAU,gBAAgB,eAAe;GAErE,OAAO,iBACH,eACA,EAAE,eAAe,EAAE,WAAW,UAAU,GAAG,CAAC,MAAM,CAAC;EACzD;EAEA,IAAI;GAAC;GAAM;GAAQ;GAAU;EAAM,EAAE,SAAS,UAAU,GAAG;GACzD,MAAM,UAAU,kBACd,UACA,kBAAkB,aAAa,UAAU,SAAS,IAC9C,aAAa,UAAU,KACvB,MACJ,gBACA,eACF;GAEA,IAAI,gBAAgB;IAClB,aAAa,UAAU,KAAK;IAE5B,OAAO;GACT;GAEA,OAAO,EAAE,eAAe,EAAE,WAAW,UAAU,GAAG,CAAC,OAAO,CAAC;EAC7D;EAEA,IAAI,eAAe,QAAQ;GACzB,MAAM,OAAO,CAAC,EAAE,QAAQ,SAAS,aAAa,CAAC;GAE/C,IAAI,SAAS,MAAM,KAAK,KAAK,EAAE,QAAQ,SAAS,IAAI,CAAC;GAErD,IAAI,gBAAgB;IAClB,aAAa,YAAY;IAEzB,OAAO;GACT;GAEA,OAAO,EAAE,eAAe,EAAE,WAAW,MAAM,GAAG,IAAI;EACpD;CACF;CAGA,MAAM,UACJ,qBAAqB,EAAE,iBAAiB,MAAM,iBAAiB,IAC3D,oBACA,EAAE,iBAAiB,CAAC,CAAC;CAE3B,oBAAoB,SAAS,KAAK,gBAAgB,eAAe;CAEjE,OAAO,gBAAgB,sBAAsB,eACzC,UACA,gBAAgB;AACtB;;;;AAKA,MAAM,uBACJ,MACA,MACA,gBACA,oBACG;CACH,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,IAAI,GAAG;EAC7C,IAAI,QAAQ,QAAW;EAEvB,MAAM,eAAe,oBAAoB,MAAM,GAAG;EAElD,IAAI,cACF,aAAa,QAAQ,kBACnB,KACA,aAAa,OACb,gBACA,eACF;OACK;GAEL,MAAM,UADY,6BAA6B,KAAK,GAC5B,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,GAAG;GAC7D,MAAM,YAAY,kBAChB,KACA,MACA,gBACA,eACF;GACA,KAAK,WAAW,KAAK,EAAE,SAAS,QAAQ,SAAS,SAAS,CAAC;EAC7D;CACF;AACF;;;;AAKA,MAAM,cAAc,KAAU,iBAA8B,UAAmB;CAC7E,IAAI,gBAAgB,SAAS,GAAG;CAEhC,MAAM,sCAAsB,IAAI,IAAY;CAC5C,IAAI,iBAAsB;CAE1B,OAAO,MAAM,KAAK;EAChB,uBAAuB,MAAM;GAG3B,IAFe,KAAK,KAAK,OAAO,UAEjB,YAAY;IACzB,iBAAiB;IACjB,KAAK,KAAK,YAAY,SAAS,SAAS;KACtC,IACE,EAAE,gBAAgB,MAAM,IAAI,KAC5B,OAAO,KAAK,SAAS,SAAS,UAE9B,oBAAoB,IAAI,KAAK,SAAS,IAAI;IAE9C,CAAC;GACH;GAEA,OAAO;EACT;EACA,yBAAyB,MAAM;GAC7B,KAAK,KAAK,aAAa,SAAS,SAAS;IACvC,IACE,EAAE,mBAAmB,MAAM,IAAI,KAC/B,EAAE,eAAe,MAAM,KAAK,IAAI,KAChC,EAAE,WAAW,MAAM,KAAK,KAAK,MAAM,KACnC,KAAK,KAAK,OAAO,SAAS,WAC1B;KACA,MAAM,MAAM,KAAK,KAAK,UAAU;KAEhC,IAAI,EAAE,QAAQ,MAAM,GAAG,GACrB;UAAI,IAAI,UAAU,YAChB;WAAI,EAAE,cAAc,MAAM,KAAK,EAAE,GAC/B,KAAK,GAAG,WAAW,SAAS,SAAS;QACnC,IACE,EAAE,SAAS,MAAM,IAAI,MACpB,EAAE,WAAW,MAAM,KAAK,GAAG,KAC1B,EAAE,WAAW,MAAM,KAAK,KAAK,IAC/B;SACA,MAAM,OAAO,EAAE,WAAW,MAAM,KAAK,GAAG,IACpC,KAAK,IAAI,OACR,KAAK,MAAc;SACxB,oBAAoB,IAAI,IAAI;QAC9B;OACF,CAAC;YACI,IAAI,EAAE,WAAW,MAAM,KAAK,EAAE,GAEnC,oBAAoB,IAAI,KAAK,GAAG,IAAI;MACtC;KACF;IAEJ;GACF,CAAC;GAED,OAAO;EACT;CACF,CAAC;CAED,MAAM,cAAc,MAAM,KAAK,eAAe,EAAE,QAC7C,QAAQ,CAAC,oBAAoB,IAAI,GAAG,CACvC;CAEA,IAAI,YAAY,WAAW,GAAG;CAE9B,IAAI,OACF,IAAI,gBAAgB;EAClB,YAAY,SAAS,QAAQ;GAC3B,eAAe,KAAK,WAAW,KAC7B,EAAE,gBAAgB,EAAE,WAAW,GAAG,CAAC,CACrC;EACF,CAAC;EACD,eAAe,KAAK,WAAW,MAAM,GAAQ,MAC3C,EAAE,SAAS,KAAK,cAAc,EAAE,SAAS,IAAI,CAC/C;CACF,OAAO;EACL,MAAM,aAAa,YAChB,KAAK,EACL,KAAK,QAAQ,EAAE,gBAAgB,EAAE,WAAW,GAAG,CAAC,CAAC;EACpD,MAAM,YAAY,EAAE,kBAAkB,YAAY,EAAE,QAAQ,UAAU,CAAC;EACvE,IAAI,QAAQ,KAAK,QAAQ,SAAS;CACpC;MACK;EACL,IAAI,cAAc;EAElB,IACE,IAAI,QAAQ,KAAK,SAAS,KAC1B,EAAE,oBAAoB,MAAM,IAAI,QAAQ,KAAK,EAAE,KAC/C,EAAE,QAAQ,MAAM,IAAI,QAAQ,KAAK,GAAG,UAAU,GAE9C,cAAc;EAEhB,MAAM,WAAkB,CAAC;EAEzB,MAAM,aAAa,YAAY,KAAK,EAAE,KAAK,QAAQ;GACjD,MAAM,OAAO,EAAE,SAAS,QAAQ,EAAE,WAAW,GAAG,GAAG,EAAE,WAAW,GAAG,CAAC;GACpE,KAAK,YAAY;GAEjB,OAAO;EACT,CAAC;EACD,SAAS,KACP,EAAE,oBAAoB,SAAS,CAC7B,EAAE,mBACA,EAAE,cAAc,UAAU,GAC1B,EAAE,eAAe,EAAE,WAAW,SAAS,GAAG,CAAC,EAAE,QAAQ,UAAU,CAAC,CAAC,CACnE,CACF,CAAC,CACH;EAEA,IAAI,QAAQ,KAAK,OAAO,aAAa,GAAG,GAAG,QAAQ;CACrD;AACF;;;;AAKA,MAAa,kBAAkB,OAC7B,aACA,YACA,gBACA,eACoB;CACpB,IAAI,CAAC,cAAc,OAAO,eAAe,UAAU,OAAO;CAE1D,IAAI;CACJ,IAAI;EACF,MAAM,OAAO,MAAM,aAAa,EAC9B,QAAQ,cACV,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,EAAE,MAAM,CAAC;EACvB,OAAO;CACT;CAEA,IAAI,aAAkB;CACtB,IAAI,QAAQ;CAEZ,OAAO,MAAM,KAAK;EAChB,gCAAgC;GAC9B,QAAQ;GAER,OAAO;EACT;EACA,yBAAyB;GACvB,QAAQ;GAER,OAAO;EACT;CACF,CAAC;CAED,OAAO,MAAM,KAAK;EAChB,8BAA8B,MAAM;GAClC,MAAM,OAAO,KAAK,KAAK;GACvB,MAAM,gBAAgB,OAAO,IAAI;GAEjC,IAAI,EAAE,iBAAiB,MAAM,aAAa,GACxC,aAAa;QACR,IAAI,EAAE,WAAW,MAAM,aAAa,GAAG;IAC5C,MAAM,UAAU,cAAc;IAC9B,OAAO,MAAM,KAAK,EAChB,wBAAwB,IAAI;KAC1B,MAAM,gBAAgB,OAAO,GAAG,KAAK,IAAI;KAEzC,IACE,EAAE,WAAW,MAAM,GAAG,KAAK,EAAE,KAC7B,GAAG,KAAK,GAAG,SAAS,WACpB,EAAE,iBAAiB,MAAM,aAAa,GAEtC,aAAa;KAGf,OAAO;IACT,EACF,CAAC;GACH;GAEA,OAAO;EACT;EACA,0BAA0B,MAAM;GAC9B,MAAM,OAAO,KAAK,KAAK;GAEvB,IAAI,EAAE,iBAAiB,MAAM,IAAI,GAAG;IAClC,IACE,EAAE,WAAW,MAAM,KAAK,MAAM,KAC9B,KAAK,OAAO,SAAS,YACrB,EAAE,WAAW,MAAM,KAAK,QAAQ,KAChC,KAAK,SAAS,SAAS,WACvB;KACA,MAAM,iBAAiB,OAAO,KAAK,KAAK,KAAK;KAE7C,IAAI,EAAE,iBAAiB,MAAM,cAAc,GACzC,aAAa;IAEjB;IAEA,IACE,EAAE,WAAW,MAAM,KAAK,MAAM,KAC9B,KAAK,OAAO,SAAS,aACrB,EAAE,WAAW,MAAM,KAAK,QAAQ,KAChC,KAAK,SAAS,SAAS,WACvB;KACA,MAAM,iBAAiB,OAAO,KAAK,KAAK,KAAK;KAE7C,IAAI,EAAE,iBAAiB,MAAM,cAAc,GACzC,aAAa;IAEjB;GACF;GACA,KAAK,SAAS,IAAI;EACpB;CACF,CAAC;CAED,IAAI,CAAC,YACH,OAAO,MAAM,KAAK,EAChB,wBAAwB,MAAM;EAC5B,MAAM,gBAAgB,OAAO,KAAK,KAAK,IAAI;EAE3C,IAAI,CAAC,cAAc,EAAE,iBAAiB,MAAM,aAAa,GACvD,aAAa;EAGf,OAAO;CACT,EACF,CAAC;CAGH,IAAI,CAAC,YAAY,OAAO;CAExB,MAAM,kCAAkB,IAAI,IAAY;CACxC,MAAM,0BAA2B,kBAA6B;CAE9D,MAAM,qBAAqB;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,IAAI,YAAY;EAEd,WAAW,aAAa,WAAW,WAAW,QAAQ,SAAc;GAClE,IAAI,EAAE,SAAS,MAAM,IAAI,KAAK,EAAE,eAAe,MAAM,IAAI,GAAG;IAC1D,IAAI,WAAW;IACf,IAAI,EAAE,WAAW,MAAM,KAAK,GAAG,GAAG,WAAW,KAAK,IAAI;SACjD,IAAI,EAAE,cAAc,MAAM,KAAK,GAAG,GAAG,WAAW,KAAK,IAAI;SACzD,IAAI,EAAE,QAAQ,MAAM,KAAK,GAAG,GAAG,WAAW,OAAO,KAAK,IAAI,KAAK;IAEpE,OAAO,CAAC;KAAC;KAAO;KAAW,GAAG;IAAkB,EAAE,SAAS,QAAQ;GACrE;GACA,OAAO;EACT,CAAC;EAGD,OAAO,MAAM,KAAK,EAChB,UAAU,MAAM;GACd,MAAM,OAAO,KAAK;GAClB,KACG,EAAE,uBAAuB,MAAM,IAAI,KAClC,KAAK,SAAS,4BACf,KAAa,kBACd,EAAE,gBAAgB,MAAO,KAAa,cAAc,KACpD,EAAE,WAAW,MAAO,KAAa,eAAe,QAAQ,KACvD,KAAa,eAAe,SAAS,SAAS,cAE/C,AAAC,KAAa,iBAAiB,EAAE,oBAC/B,EAAE,gBAAgB,EAAE,WAAW,YAAY,CAAC,GAC5C,EAAE,cAAc,EAAE,cAAc,SAAS,CAAC,CAC5C;GAEF,KAAK,SAAS,IAAI;EACpB,EACF,CAAC;CACH,OACE,KAAK,MAAM,QAAQ,oBACjB,IAAK,WAAmB,UAAU,QAChC,oBACE,YACA,GAAG,OAAQ,WAAmB,MAAM,GACpC,QACA,eACF;CAKN,IAAI,WAAW,YAAY,QACzB,oBACE,YACA,aACK,WAAW,UACZ,EAAE,SAAS,WAAW,QAAQ,GAClC,yBACA,eACF;CAGF,WAAW,KAAK,iBAAiB,KAAK;CAEtC,OAAO,OAAO,MAAM,GAAG,EAAE;AAC3B"}