@seed-design/figma 0.2.5 → 1.0.0

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.
Files changed (32) hide show
  1. package/lib/codegen/index.cjs +716 -448
  2. package/lib/codegen/index.d.ts +127 -91
  3. package/lib/codegen/index.d.ts.map +1 -1
  4. package/lib/codegen/index.js +716 -448
  5. package/lib/codegen/targets/react/index.cjs +1060 -764
  6. package/lib/codegen/targets/react/index.d.ts.map +1 -1
  7. package/lib/codegen/targets/react/index.js +1060 -764
  8. package/lib/index.cjs +716 -448
  9. package/lib/index.js +716 -448
  10. package/package.json +3 -3
  11. package/src/codegen/component-properties.ts +4 -0
  12. package/src/codegen/targets/react/component/handlers/list-header.ts +20 -0
  13. package/src/codegen/targets/react/component/handlers/list-item.ts +8 -1
  14. package/src/codegen/targets/react/component/handlers/switch-mark.ts +26 -0
  15. package/src/codegen/targets/react/component/handlers/switch.ts +9 -3
  16. package/src/codegen/targets/react/component/index.ts +6 -2
  17. package/src/entities/data/__generated__/component-sets/index.d.ts +1 -0
  18. package/src/entities/data/__generated__/component-sets/index.mjs +1 -0
  19. package/src/entities/data/__generated__/component-sets/list-header.d.ts +3 -3
  20. package/src/entities/data/__generated__/component-sets/list-header.mjs +3 -3
  21. package/src/entities/data/__generated__/component-sets/manner-temp-badge.d.ts +10 -6
  22. package/src/entities/data/__generated__/component-sets/manner-temp-badge.mjs +10 -6
  23. package/src/entities/data/__generated__/component-sets/manner-temp.d.ts +10 -6
  24. package/src/entities/data/__generated__/component-sets/manner-temp.mjs +10 -6
  25. package/src/entities/data/__generated__/component-sets/segmented-control.d.ts +0 -9
  26. package/src/entities/data/__generated__/component-sets/segmented-control.mjs +0 -9
  27. package/src/entities/data/__generated__/component-sets/switch-mark.d.ts +35 -0
  28. package/src/entities/data/__generated__/component-sets/switch-mark.mjs +35 -0
  29. package/src/entities/data/__generated__/component-sets/switch.d.ts +2 -2
  30. package/src/entities/data/__generated__/component-sets/switch.mjs +2 -2
  31. package/src/entities/data/__generated__/variable-collections/index.mjs +13 -5
  32. package/src/entities/data/__generated__/variables/index.mjs +546 -322
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sources":["../../src/normalizer/types.ts","../../src/codegen/core/jsx.ts","../../src/codegen/core/element-transformer.ts","../../src/codegen/core/codegen.ts","../../src/codegen/core/component-handler.ts","../../src/codegen/core/component-type-helper.ts","../../src/entities/component.interface.ts","../../src/entities/variable.interface.ts","../../src/entities/style.service.ts","../../src/entities/variable.service.ts","../../src/entities/component.repository.ts","../../src/codegen/core/props-converter.ts","../../src/codegen/core/value-resolver.ts","../../src/codegen/core/infer-layout.ts","../../src/entities/data/__generated__/component-sets/template-error-state.d.ts","../../src/entities/data/__generated__/component-sets/template-select-box-group.d.ts","../../src/entities/data/__generated__/component-sets/action-button.d.ts","../../src/entities/data/__generated__/component-sets/alert-dialog.d.ts","../../src/entities/data/__generated__/component-sets/avatar.d.ts","../../src/entities/data/__generated__/component-sets/avatar-stack.d.ts","../../src/entities/data/__generated__/component-sets/badge.d.ts","../../src/entities/data/__generated__/component-sets/bottom-sheet.d.ts","../../src/entities/data/__generated__/component-sets/callout.d.ts","../../src/entities/data/__generated__/component-sets/checkbox.d.ts","../../src/entities/data/__generated__/component-sets/checkmark.d.ts","../../src/entities/data/__generated__/component-sets/chip.d.ts","../../src/entities/data/__generated__/component-sets/contextual-floating-button.d.ts","../../src/entities/data/__generated__/component-sets/divider.d.ts","../../src/entities/data/__generated__/component-sets/floating-action-button.d.ts","../../src/entities/data/__generated__/component-sets/help-bubble.d.ts","../../src/entities/data/__generated__/component-sets/list-header.d.ts","../../src/entities/data/__generated__/component-sets/list-item.d.ts","../../src/entities/data/__generated__/component-sets/manner-temp.d.ts","../../src/entities/data/__generated__/component-sets/manner-temp-badge.d.ts","../../src/entities/data/__generated__/component-sets/menu-sheet.d.ts","../../src/entities/data/__generated__/component-sets/multiline-text-field.d.ts","../../src/entities/data/__generated__/component-sets/page-banner.d.ts","../../src/entities/data/__generated__/component-sets/progress-circle.d.ts","../../src/entities/data/__generated__/component-sets/radio.d.ts","../../src/entities/data/__generated__/component-sets/radio-mark.d.ts","../../src/entities/data/__generated__/component-sets/reaction-button.d.ts","../../src/entities/data/__generated__/component-sets/segmented-control.d.ts","../../src/entities/data/__generated__/component-sets/select-box.d.ts","../../src/entities/data/__generated__/component-sets/skeleton.d.ts","../../src/entities/data/__generated__/component-sets/snackbar.d.ts","../../src/entities/data/__generated__/component-sets/switch.d.ts","../../src/entities/data/__generated__/component-sets/tabs.d.ts","../../src/entities/data/__generated__/component-sets/text-field.d.ts","../../src/entities/data/__generated__/component-sets/toggle-button.d.ts","../../src/entities/data/__generated__/component-sets/top-navigation.d.ts","../../src/codegen/component-properties.ts","../../src/codegen/targets/figma/pipeline.ts","../../src/codegen/targets/figma/value-resolver.ts","../../src/codegen/targets/figma/props.ts","../../src/codegen/targets/figma/frame.ts","../../src/codegen/targets/figma/instance.ts","../../src/codegen/targets/figma/shape.ts","../../src/codegen/targets/figma/text.ts"],"sourcesContent":["import type * as FigmaRestSpec from \"@figma/rest-api-spec\";\n\nexport type NormalizedIsLayerTrait = Pick<\n FigmaRestSpec.IsLayerTrait,\n \"type\" | \"id\" | \"name\" | \"boundVariables\"\n>;\n\nexport type NormalizedCornerTrait = Pick<\n FigmaRestSpec.CornerTrait,\n \"cornerRadius\" | \"rectangleCornerRadii\"\n>;\n\nexport type NormalizedHasChildrenTrait = {\n children: NormalizedSceneNode[];\n};\n\nexport type NormalizedHasLayoutTrait = Pick<\n FigmaRestSpec.HasLayoutTrait,\n | \"layoutAlign\"\n | \"layoutGrow\"\n | \"absoluteBoundingBox\"\n | \"relativeTransform\"\n | \"layoutPositioning\"\n | \"layoutSizingHorizontal\"\n | \"layoutSizingVertical\"\n | \"minHeight\"\n | \"minWidth\"\n | \"maxHeight\"\n | \"maxWidth\"\n>;\n\nexport type NormalizedHasGeometryTrait = Pick<\n FigmaRestSpec.HasGeometryTrait,\n \"fills\" | \"strokes\" | \"strokeWeight\" | \"styles\"\n> & {\n fillStyleKey?: string;\n};\n\nexport type NormalizedHasFramePropertiesTrait = Pick<\n FigmaRestSpec.HasFramePropertiesTrait,\n | \"layoutMode\"\n | \"layoutWrap\"\n | \"paddingLeft\"\n | \"paddingRight\"\n | \"paddingTop\"\n | \"paddingBottom\"\n | \"primaryAxisAlignItems\"\n | \"primaryAxisSizingMode\"\n | \"counterAxisAlignItems\"\n | \"counterAxisSizingMode\"\n | \"itemSpacing\"\n | \"counterAxisSpacing\"\n>;\n\nexport interface NormalizedTextSegment {\n characters: string;\n start: number;\n end: number;\n style: {\n fontFamily?: string;\n fontWeight?: number;\n fontSize?: number;\n italic?: boolean;\n textDecoration?: string;\n letterSpacing?: number;\n lineHeight?: number | { unit: string; value: number };\n };\n}\n\nexport type NormalizedTypePropertiesTrait = Pick<\n FigmaRestSpec.TypePropertiesTrait,\n \"style\" | \"characters\"\n> & {\n segments: NormalizedTextSegment[];\n\n textStyleKey?: string;\n};\n\nexport type NormalizedDefaultShapeTrait = NormalizedIsLayerTrait &\n NormalizedHasLayoutTrait &\n NormalizedHasGeometryTrait;\n\nexport type NormalizedFrameTrait = NormalizedIsLayerTrait &\n NormalizedHasLayoutTrait &\n NormalizedHasGeometryTrait &\n NormalizedHasChildrenTrait &\n NormalizedCornerTrait &\n NormalizedHasFramePropertiesTrait;\n\nexport interface NormalizedFrameNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.FrameNode[\"type\"];\n}\n\nexport interface NormalizedRectangleNode\n extends NormalizedDefaultShapeTrait,\n NormalizedCornerTrait {\n type: FigmaRestSpec.RectangleNode[\"type\"];\n}\n\nexport interface NormalizedTextNode\n extends NormalizedDefaultShapeTrait,\n NormalizedTypePropertiesTrait {\n type: FigmaRestSpec.TextNode[\"type\"];\n}\n\nexport interface NormalizedComponentNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.ComponentNode[\"type\"];\n}\n\nexport interface NormalizedInstanceNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.InstanceNode[\"type\"];\n\n componentProperties: {\n [key: string]: FigmaRestSpec.ComponentProperty & {\n componentKey?: string;\n componentSetKey?: string;\n };\n };\n\n componentKey: string;\n\n componentSetKey?: string;\n\n overrides?: FigmaRestSpec.InstanceNode[\"overrides\"];\n\n children: NormalizedSceneNode[];\n}\n\nexport interface NormalizedVectorNode extends NormalizedDefaultShapeTrait, NormalizedCornerTrait {\n type: FigmaRestSpec.VectorNode[\"type\"];\n}\n\nexport interface NormalizedBooleanOperationNode\n extends NormalizedIsLayerTrait,\n NormalizedHasChildrenTrait,\n NormalizedHasLayoutTrait,\n NormalizedHasGeometryTrait {\n type: FigmaRestSpec.BooleanOperationNode[\"type\"];\n}\n\nexport interface NormalizedUnhandledNode {\n type: \"UNHANDLED\";\n id: string;\n original: FigmaRestSpec.Node | SceneNode;\n}\n\nexport type NormalizedSceneNode =\n | NormalizedFrameNode\n | NormalizedRectangleNode\n | NormalizedTextNode\n | NormalizedComponentNode\n | NormalizedInstanceNode\n | NormalizedVectorNode\n | NormalizedBooleanOperationNode\n | NormalizedUnhandledNode;\n","import { ensureArray, exists } from \"@/utils/common\";\n\nexport interface ElementNode {\n __IS_JSX_ELEMENT_NODE: true;\n tag: string;\n props: Record<string, string | number | boolean | ElementNode | object | undefined>;\n children: (ElementNode | string)[];\n\n meta: {\n comment?: string;\n source?: string;\n importPath?: string;\n };\n}\n\nexport function createElement(\n tag: string,\n props: Record<string, string | number | boolean | object | undefined> = {},\n children?: ElementNode | string | undefined | (ElementNode | string | undefined)[],\n meta?: ElementNode[\"meta\"],\n): ElementNode {\n return {\n __IS_JSX_ELEMENT_NODE: true,\n tag,\n props,\n children: ensureArray(children).filter(exists),\n meta: meta ?? {},\n };\n}\n\nexport function cloneElement(\n element: ElementNode,\n props: Record<string, string | number | boolean | object | undefined> = {},\n children?: ElementNode | string | undefined | (ElementNode | string | undefined)[],\n) {\n return {\n ...element,\n props: { ...element.props, ...props },\n children: children ? ensureArray(children).filter(exists) : element.children,\n };\n}\n\nexport function appendSource(element: ElementNode, source: string) {\n return {\n ...element,\n source,\n };\n}\n\nexport function isElement(node: unknown): node is ElementNode {\n return (\n typeof node === \"object\" &&\n node != null &&\n \"__IS_JSX_ELEMENT_NODE\" in node &&\n node.__IS_JSX_ELEMENT_NODE === true\n );\n}\n\nexport function stringifyElement(element: ElementNode, options: { printSource?: boolean } = {}) {\n const importMap = new Map<string, Set<string>>();\n\n function recursive(node: ElementNode | string, depth: number): string {\n if (typeof node === \"string\") {\n return node;\n }\n\n const {\n tag,\n props,\n children,\n meta: { comment, source, importPath },\n } = node;\n\n if (importPath) {\n const existing = importMap.get(importPath);\n\n const [namespace] = tag.split(\".\");\n\n if (existing) {\n existing.add(namespace);\n } else {\n importMap.set(importPath, new Set([namespace]));\n }\n }\n\n const propEntries = Object.entries(\n options.printSource ? { ...props, \"data-figma-node-id\": source } : props,\n );\n const propFragments = propEntries\n .map(([key, value]) => {\n if (typeof value === \"string\") {\n if (value.includes(\"\\n\")) {\n return `${key}={\"${value.replaceAll(\"\\n\", \"\\\\n\")}\"}`;\n }\n\n return `${key}=\"${value}\"`;\n }\n\n if (typeof value === \"number\") {\n return `${key}={${value}}`;\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) return key;\n\n return `${key}={${value}}`;\n }\n\n if (isElement(value)) {\n const elementStr = recursive(value, depth + 1);\n\n const commentMatch = elementStr.match(/\\{\\/\\* (.+?)\\*\\/\\}$/);\n\n if (commentMatch) {\n const elementWithoutComment = elementStr.replace(/\\{\\/\\* .+? \\*\\/\\}$/, \"\");\n\n return `${key}={${elementWithoutComment}}/* ${commentMatch[1]} */`;\n }\n\n return `${key}={${elementStr}}`;\n }\n\n if (typeof value === \"object\") {\n return `${key}={${JSON.stringify(value)}}`;\n }\n\n if (typeof value === \"undefined\") {\n return undefined;\n }\n\n return undefined;\n })\n .filter(exists);\n\n const oneLiner = propFragments.join(\" \");\n const propsString =\n propEntries.length === 0\n ? \"\"\n : ` ${\n oneLiner.length < 80\n ? oneLiner\n : `\\n${\" \".repeat(depth + 1)}${propFragments.join(\n `\\n${\" \".repeat(depth + 1)}`,\n )}\\n${\" \".repeat(depth)}`\n }`;\n\n if (children == null || children.length === 0) {\n return `<${tag}${propsString} />${comment ? `{/* ${comment} */}` : \"\"}`;\n }\n\n const result = [\n `<${tag}${propsString}>`,\n ...ensureArray(children)\n .filter(exists)\n .map((child) => recursive(child, depth + 1))\n .map((str) => \" \".repeat(depth + 1) + str),\n `${\" \".repeat(depth)}</${tag}>${comment ? `{/* ${comment} */}` : \"\"}`,\n ].join(\"\\n\");\n\n return result;\n }\n\n const jsx = recursive(element, 0);\n\n const imports = Array.from(importMap.entries())\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([importPath, tags]) => `import { ${Array.from(tags).join(\", \")} } from \"${importPath}\";`)\n .join(\"\\n\");\n\n return {\n imports,\n jsx,\n };\n}\n","import type { NormalizedSceneNode } from \"@/normalizer\";\nimport type { ElementNode } from \"./jsx\";\n\nexport type ElementTransformer<T extends NormalizedSceneNode> = (\n node: T,\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n) => ElementNode | undefined;\n\nexport function defineElementTransformer<T extends NormalizedSceneNode>(\n transformer: ElementTransformer<T>,\n) {\n return transformer;\n}\n","import type {\n NormalizedBooleanOperationNode,\n NormalizedComponentNode,\n NormalizedFrameNode,\n NormalizedInstanceNode,\n NormalizedRectangleNode,\n NormalizedSceneNode,\n NormalizedTextNode,\n NormalizedVectorNode,\n} from \"@/normalizer\";\nimport { match } from \"ts-pattern\";\nimport { appendSource, createElement, stringifyElement, type ElementNode } from \"../core/jsx\";\nimport type { ElementTransformer } from \"./element-transformer\";\nimport { applyInferredLayout, inferLayout } from \"./infer-layout\";\n\nexport interface CodeGeneratorDeps {\n frameTransformer: ElementTransformer<\n NormalizedFrameNode | NormalizedComponentNode | NormalizedInstanceNode\n >;\n textTransformer: ElementTransformer<NormalizedTextNode>;\n rectangleTransformer: ElementTransformer<NormalizedRectangleNode>;\n instanceTransformer: ElementTransformer<NormalizedInstanceNode>;\n vectorTransformer: ElementTransformer<NormalizedVectorNode>;\n booleanOperationTransformer: ElementTransformer<NormalizedBooleanOperationNode>;\n shouldInferAutoLayout: boolean;\n}\n\nexport interface CodeGenerator {\n generateJsxTree: (node: NormalizedSceneNode) => ElementNode | undefined;\n generateCode: (\n node: NormalizedSceneNode,\n options: { shouldPrintSource: boolean },\n ) => { imports: string; jsx: string } | undefined;\n}\n\nexport function createCodeGenerator({\n frameTransformer,\n textTransformer,\n rectangleTransformer,\n instanceTransformer,\n vectorTransformer,\n booleanOperationTransformer,\n shouldInferAutoLayout,\n}: CodeGeneratorDeps): CodeGenerator {\n function traverse(node: NormalizedSceneNode): ElementNode | undefined {\n if (\"visible\" in node && !node.visible) {\n return;\n }\n\n const result = match(node)\n .with({ type: \"FRAME\" }, (node) =>\n shouldInferAutoLayout\n ? frameTransformer(applyInferredLayout(node, inferLayout(node)), traverse)\n : frameTransformer(node, traverse),\n )\n .with({ type: \"TEXT\" }, (node) => textTransformer(node, traverse))\n .with({ type: \"RECTANGLE\" }, (node) => rectangleTransformer(node, traverse))\n .with({ type: \"COMPONENT\" }, (node) => frameTransformer(node, traverse)) // NOTE: Treat component node as Frame for now\n .with({ type: \"INSTANCE\" }, (node) => instanceTransformer(node, traverse))\n .with({ type: \"VECTOR\" }, (node) => vectorTransformer(node, traverse))\n .with({ type: \"BOOLEAN_OPERATION\" }, (node) => booleanOperationTransformer(node, traverse))\n .with({ type: \"UNHANDLED\" }, () => createElement(\"UnhandledFigmaNode\"))\n .exhaustive();\n\n if (result) {\n return appendSource(result, node.id);\n }\n\n return;\n }\n\n function generateJsxTree(node: NormalizedSceneNode) {\n return traverse(node);\n }\n\n function generateCode(node: NormalizedSceneNode, options: { shouldPrintSource: boolean }) {\n const jsxTree = generateJsxTree(node);\n\n if (!jsxTree) {\n return undefined;\n }\n\n return stringifyElement(jsxTree, { printSource: options.shouldPrintSource });\n }\n\n return { generateJsxTree, generateCode };\n}\n","import type { NormalizedInstanceNode, NormalizedSceneNode } from \"@/normalizer\";\nimport type { ElementNode } from \"./jsx\";\n\nexport interface ComponentHandler<\n T extends\n NormalizedInstanceNode[\"componentProperties\"] = NormalizedInstanceNode[\"componentProperties\"],\n> {\n key: string;\n transform: (\n node: Omit<NormalizedInstanceNode, \"componentProperties\"> & { componentProperties: T },\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n ) => ElementNode;\n}\n\nexport function defineComponentHandler<T extends NormalizedInstanceNode[\"componentProperties\"]>(\n key: string,\n transform: (\n node: Omit<NormalizedInstanceNode, \"componentProperties\"> & { componentProperties: T },\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n ) => ElementNode,\n): ComponentHandler<T> {\n return { key, transform };\n}\n","import type { ComponentPropertyType, InstanceSwapPreferredValue } from \"@figma/rest-api-spec\";\n\nexport interface ComponentPropertyDefinition {\n type: ComponentPropertyType;\n preferredValues?: InstanceSwapPreferredValue[];\n variantOptions?: string[];\n}\n\nexport type InferComponentPropertyType<T extends ComponentPropertyDefinition> =\n T[\"type\"] extends \"TEXT\"\n ? string\n : T[\"type\"] extends \"BOOLEAN\"\n ? boolean\n : T[\"type\"] extends \"INSTANCE_SWAP\"\n ? string\n : T[\"type\"] extends \"VARIANT\"\n ? T[\"variantOptions\"] extends string[]\n ? T[\"variantOptions\"][number]\n : never\n : never;\n\nexport type InferComponentDefinition<T extends Record<string, ComponentPropertyDefinition>> = {\n [K in keyof T]: {\n type: T[K][\"type\"];\n value: InferComponentPropertyType<T[K]>;\n readonly boundVariables?: {\n [field in VariableBindableComponentPropertyField]?: VariableAlias;\n };\n } & (T[K][\"type\"] extends \"INSTANCE_SWAP\"\n ? {\n componentKey: string;\n preferredValues: InstanceSwapPreferredValue[];\n }\n : {});\n};\n","import type { ComponentPropertyDefinition } from \"@/codegen\";\n\nexport interface ComponentMetadata {\n name: string;\n key: string;\n componentPropertyDefinitions: Record<string, ComponentPropertyDefinition>;\n}\n","import type {\n LocalVariable,\n LocalVariableCollection,\n VariableAlias,\n VariableResolvedDataType,\n} from \"@figma/rest-api-spec\";\n\nexport type Variable = LocalVariable;\n\nexport type VariableCollection = LocalVariableCollection;\n\nexport type VariableType = VariableResolvedDataType;\n\nexport type VariableValue = Variable[\"valuesByMode\"][string];\n\nexport type VariableValueResolved = Exclude<VariableValue, VariableAlias>;\n\nexport type { VariableScope } from \"@figma/rest-api-spec\";\n","import type { StyleRepository } from \"./style.repository\";\n\nexport interface StyleService {\n getSlug: (id: string) => string[] | undefined;\n}\n\n// TODO: inferStyleName 추가해야 함, rest api에서 style value가 제공되지 않고 있어 보류\nexport function createStyleService({\n styleRepository,\n}: {\n styleRepository: StyleRepository;\n}): StyleService {\n function getName(id: string) {\n const style = styleRepository.findOneByKey(id);\n\n if (!style) {\n return undefined;\n }\n\n return style.name;\n }\n\n function getSlug(id: string): string[] | undefined {\n const name = getName(id);\n\n if (!name) {\n return undefined;\n }\n\n return name.split(\"/\");\n }\n\n return {\n getSlug,\n };\n}\n","import {\n isIdenticalVariableValue,\n isInsideScope,\n isVariableAlias,\n sanitizeVariableId,\n} from \"@/utils/figma-variable\";\nimport type { Variable, VariableScope, VariableValueResolved } from \"./variable.interface\";\nimport type { VariableRepository } from \"./variable.repository\";\n\nexport interface VariableService {\n getSlug: (id: string) => string[] | undefined;\n resolveValue: (variable: Variable, mode: string) => VariableValueResolved;\n infer: (value: VariableValueResolved, scope: VariableScope) => Variable | undefined;\n}\n\nexport interface VariableServiceDeps {\n variableRepository: VariableRepository;\n inferCompareFunction: (a: Variable, b: Variable) => number;\n}\n\nexport function createVariableService({\n variableRepository,\n inferCompareFunction,\n}: VariableServiceDeps): VariableService {\n const variables = variableRepository.getVariableList();\n\n // private\n function getName(key: string) {\n const sanitizedId = sanitizeVariableId(key);\n const variable = variableRepository.findVariableByKey(sanitizedId);\n\n if (!variable) {\n return undefined;\n }\n\n return variable.name;\n }\n\n function getDefaultModeId(variable: Variable) {\n const variableCollection = variableRepository.findVariableCollectionById(\n variable.variableCollectionId,\n );\n\n if (!variableCollection) {\n // Variable collection not found: ${variable.variableCollectionId}, falling back to variable.valuesByMode key\n return Object.keys(variable.valuesByMode)[0]!;\n }\n\n return variableCollection.defaultModeId;\n }\n\n // public\n function getSlug(key: string): string[] | undefined {\n const name = getName(key);\n\n if (!name) {\n return undefined;\n }\n\n return name.split(\"/\");\n }\n\n function resolveValue(variable: Variable, mode: string): VariableValueResolved {\n const value = variable.valuesByMode[mode];\n\n if (value === undefined) {\n throw new Error(`Variable value not found: ${variable.id} ${mode}`);\n }\n\n if (isVariableAlias(value)) {\n const resolvedVariable = variableRepository.findVariableById(value.id);\n\n if (!resolvedVariable) {\n throw new Error(`Variable not found: ${value.id}`);\n }\n\n return resolveValue(resolvedVariable, mode);\n }\n\n return value;\n }\n\n function infer(value: VariableValueResolved, scope: VariableScope) {\n // NOTE: We assume that the variable is in the default mode or value is equal between all modes for simplicity.\n const inferredVariables = variables.filter(\n (variable) =>\n isInsideScope(variable, scope) &&\n isIdenticalVariableValue(resolveValue(variable, getDefaultModeId(variable)), value),\n );\n\n const sortedVariables = inferredVariables.sort(inferCompareFunction);\n\n return sortedVariables[0];\n }\n\n return {\n getSlug,\n resolveValue,\n infer,\n };\n}\n","import type { ComponentMetadata } from \"./component.interface\";\n\nexport interface ComponentRepository {\n getOne(key: string): ComponentMetadata | undefined;\n}\n\nexport function createStaticComponentRepository(data: Record<string, ComponentMetadata>) {\n const componentRecord: Record<string, ComponentMetadata> = {};\n Object.values(data).forEach((component) => {\n componentRecord[component.key] = component;\n });\n\n return {\n getOne: (key: string) => componentRecord[key],\n };\n}\n","import type { VariableValueResolved } from \"@/entities\";\nimport { objectEntries } from \"@/utils/common\";\n\nexport type PropsConverter<\n T extends Record<string, any> = Record<string, any>,\n R extends Record<string, any> = Record<string, any>,\n> = (node: T) => R;\n\nexport function definePropsConverter<T extends Record<string, any>, R extends Record<string, any>>(\n converter: PropsConverter<T, R>,\n) {\n return converter;\n}\n\ntype Handlers<\n TTrait extends Record<string, VariableValueResolved>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps = keyof TProps,\n> = {\n [K in HandlerKeys]: (node: TTrait) => TProps[K];\n};\n\ntype Shorthands<TProps extends Record<string, any>, HandlerKeys extends keyof TProps> = Record<\n Exclude<keyof TProps, HandlerKeys>,\n HandlerKeys[]\n>;\n\nexport interface CreatePropsConverterConfig<\n TTrait extends Record<string, any>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps,\n> {\n _types: {\n trait: TTrait;\n props: TProps;\n };\n handlers: Handlers<TTrait, TProps, HandlerKeys>;\n shorthands?: Shorthands<TProps, HandlerKeys>;\n defaults?: Partial<TProps>;\n}\n\nexport function createPropsConverter<\n TTrait extends Record<string, any>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps,\n>({\n handlers,\n shorthands,\n defaults,\n}: CreatePropsConverterConfig<TTrait, TProps, HandlerKeys>): PropsConverter<TTrait, TProps> {\n return definePropsConverter((node: TTrait) => {\n const result = {} as TProps;\n\n for (const [prop, handler] of objectEntries(handlers)) {\n const value = handler(node);\n if (value !== undefined && (!defaults || value !== defaults[prop as keyof TProps])) {\n result[prop as keyof TProps] = value as any;\n }\n }\n\n if (shorthands) {\n for (const [shorthand, props] of objectEntries(shorthands)) {\n const values = props.map((prop) => result[prop as keyof TProps]);\n const allDefined = values.every((value) => value !== undefined);\n const allEqual = allDefined && values.every((value) => value === values[0]);\n\n if (allEqual && values[0] !== undefined) {\n result[shorthand as keyof TProps] = values[0] as any;\n for (const prop of props) {\n delete result[prop as keyof TProps];\n }\n }\n }\n }\n\n return result;\n });\n}\n","import type { StyleService, VariableValueResolved } from \"@/entities\";\nimport type {\n NormalizedCornerTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasGeometryTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n NormalizedTypePropertiesTrait,\n} from \"@/normalizer\";\nimport {\n getFirstFillVariable,\n getFirstSolidFill,\n getFirstStroke,\n getFirstStrokeVariable,\n} from \"@/utils/figma-node\";\nimport type { RGBA } from \"@figma/rest-api-spec\";\nimport type { VariableService } from \"../../entities/variable.service\";\n\nexport interface ValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {\n getFormattedValue: {\n frameFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | TGradient | undefined;\n shapeFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n textFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n stroke: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n width: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n height: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n minWidth: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n minHeight: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n maxWidth: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n maxHeight: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingLeft: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingRight: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingTop: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingBottom: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n itemSpacing: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n topLeftRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n topRightRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n bottomLeftRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n bottomRightRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n fontSize: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontDimension | undefined;\n fontWeight: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontWeight | undefined;\n lineHeight: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontDimension | undefined;\n };\n getTextStyleValue: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | undefined; // TODO: we might turn this into a generic; not sure yet\n}\n\nexport interface ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {\n variableService: VariableService;\n variableNameFormatter: (props: { slug: string[] }) => string;\n styleService: StyleService;\n textStyleNameFormatter: (props: { slug: string[] }) => string;\n fillStyleResolver: (props: { slug: string[] }) => TGradient | undefined;\n rawValueFormatters: {\n color: (value: RGBA) => string | TColor;\n dimension: (value: number) => string | TDimension;\n fontDimension: (value: number) => string | TFontDimension;\n fontWeight: (value: number) => string | TFontWeight;\n };\n shouldInferVariableName: boolean;\n}\n\nexport function createValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight>({\n variableService,\n variableNameFormatter,\n styleService,\n textStyleNameFormatter,\n fillStyleResolver,\n rawValueFormatters,\n shouldInferVariableName,\n}: ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight>): ValueResolver<\n TColor,\n TGradient,\n TDimension,\n TFontDimension,\n TFontWeight\n> {\n function getVariableName(key: string) {\n const slug = variableService.getSlug(key);\n\n if (!slug) {\n return undefined;\n }\n\n return variableNameFormatter({ slug });\n }\n\n function inferVariableName(value: VariableValueResolved, scope: VariableScope) {\n if (!shouldInferVariableName) {\n return undefined;\n }\n\n try {\n const inferred = variableService.infer(value, scope);\n\n if (!inferred) {\n return undefined;\n }\n\n return getVariableName(inferred.key);\n } catch {\n return undefined;\n }\n }\n\n function processColor(\n key: string | undefined,\n value: RGBA | undefined,\n scope: \"FRAME_FILL\" | \"SHAPE_FILL\" | \"STROKE_COLOR\" | \"TEXT_FILL\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.color(value);\n }\n\n return undefined;\n }\n\n function processFillStyle(key: string) {\n const slug = styleService.getSlug(key);\n\n if (!slug) {\n return undefined;\n }\n\n return fillStyleResolver({ slug });\n }\n\n function processDimension(\n key: string | undefined,\n value: number | undefined,\n scope: \"WIDTH_HEIGHT\" | \"GAP\" | \"CORNER_RADIUS\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.dimension(value);\n }\n\n return undefined;\n }\n\n function processFontDimension(\n key: string | undefined,\n value: number | undefined,\n scope: \"FONT_SIZE\" | \"LINE_HEIGHT\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.fontDimension(value);\n }\n\n return undefined;\n }\n\n function processFontWeight(key: string | undefined, value: number | undefined) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n const fontWeightToString: Record<number, string> = {\n 100: \"thin\",\n 200: \"extra-light\",\n 300: \"light\",\n 400: \"regular\",\n 500: \"medium\",\n 600: \"semi-bold\",\n 700: \"bold\",\n 800: \"extra-bold\",\n 900: \"black\",\n };\n\n return (\n inferVariableName(value, \"FONT_WEIGHT\") ??\n inferVariableName(fontWeightToString[value], \"FONT_STYLE\") ??\n rawValueFormatters.fontWeight(value)\n );\n }\n\n return undefined;\n }\n\n const getFormattedValue: ValueResolver<\n TColor,\n TGradient,\n TDimension,\n TFontDimension,\n TFontWeight\n >[\"getFormattedValue\"] = {\n width: (node) =>\n processDimension(\n node.boundVariables?.size?.x?.id,\n node.absoluteBoundingBox?.width,\n \"WIDTH_HEIGHT\",\n ),\n height: (node) =>\n processDimension(\n node.boundVariables?.size?.y?.id,\n node.absoluteBoundingBox?.height,\n \"WIDTH_HEIGHT\",\n ),\n minWidth: (node) =>\n processDimension(node.boundVariables?.minWidth?.id, node.minWidth, \"WIDTH_HEIGHT\"),\n minHeight: (node) =>\n processDimension(node.boundVariables?.minHeight?.id, node.minHeight, \"WIDTH_HEIGHT\"),\n maxWidth: (node) =>\n processDimension(node.boundVariables?.maxWidth?.id, node.maxWidth, \"WIDTH_HEIGHT\"),\n maxHeight: (node) =>\n processDimension(node.boundVariables?.maxHeight?.id, node.maxHeight, \"WIDTH_HEIGHT\"),\n paddingLeft: (node) =>\n processDimension(node.boundVariables?.paddingLeft?.id, node.paddingLeft, \"GAP\"),\n paddingRight: (node) =>\n processDimension(node.boundVariables?.paddingRight?.id, node.paddingRight, \"GAP\"),\n paddingTop: (node) =>\n processDimension(node.boundVariables?.paddingTop?.id, node.paddingTop, \"GAP\"),\n paddingBottom: (node) =>\n processDimension(node.boundVariables?.paddingBottom?.id, node.paddingBottom, \"GAP\"),\n itemSpacing: (node) =>\n processDimension(node.boundVariables?.itemSpacing?.id, node.itemSpacing, \"GAP\"),\n frameFill: (node) =>\n node.fillStyleKey\n ? processFillStyle(node.fillStyleKey)\n : processColor(\n getFirstFillVariable(node)?.id,\n getFirstSolidFill(node)?.color,\n \"FRAME_FILL\",\n ),\n shapeFill: (node) =>\n processColor(getFirstFillVariable(node)?.id, getFirstSolidFill(node)?.color, \"SHAPE_FILL\"),\n textFill: (node) =>\n processColor(getFirstFillVariable(node)?.id, getFirstSolidFill(node)?.color, \"TEXT_FILL\"),\n stroke: (node) =>\n processColor(getFirstStrokeVariable(node)?.id, getFirstStroke(node)?.color, \"STROKE_COLOR\"),\n topLeftRadius: (node) =>\n processDimension(\n node.boundVariables?.topLeftRadius?.id,\n node.rectangleCornerRadii?.[0] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n topRightRadius: (node) =>\n processDimension(\n node.boundVariables?.topRightRadius?.id,\n node.rectangleCornerRadii?.[1] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n bottomLeftRadius: (node) =>\n processDimension(\n node.boundVariables?.bottomLeftRadius?.id,\n node.rectangleCornerRadii?.[2] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n bottomRightRadius: (node) =>\n processDimension(\n node.boundVariables?.bottomRightRadius?.id,\n node.rectangleCornerRadii?.[3] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n fontSize: (node) =>\n processFontDimension(\n node.boundVariables?.fontSize?.[0]?.id,\n node.style.fontSize,\n \"FONT_SIZE\",\n ),\n fontWeight: (node) =>\n processFontWeight(node.boundVariables?.fontWeight?.[0]?.id, node.style.fontWeight),\n lineHeight: (node) =>\n processFontDimension(\n node.boundVariables?.lineHeight?.[0]?.id,\n node.style.lineHeightPx,\n \"LINE_HEIGHT\",\n ),\n };\n\n function getTextStyleValue(node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait) {\n if (!node.textStyleKey) return undefined;\n\n const slug = styleService.getSlug(node.textStyleKey);\n\n if (!slug) {\n return undefined;\n }\n\n return textStyleNameFormatter({ slug });\n }\n\n return {\n getFormattedValue,\n getTextStyleValue,\n };\n}\n","import type {\n NormalizedHasChildrenTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n} from \"@/normalizer\";\n\ninterface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface LayoutProperties {\n layoutMode?: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\";\n primaryAxisSizingMode?: \"FIXED\" | \"AUTO\";\n counterAxisSizingMode?: \"FIXED\" | \"AUTO\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\"; // 'BASELINE' requires more info\n paddingLeft?: number;\n paddingRight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n itemSpacing?: number;\n}\n\ninterface InferResult {\n properties: LayoutProperties;\n childProperties: {\n [childId: string]: {\n layoutAlign?: \"MIN\" | \"STRETCH\";\n };\n };\n}\n\ntype LayoutNode = NormalizedIsLayerTrait &\n NormalizedHasFramePropertiesTrait &\n NormalizedHasChildrenTrait &\n NormalizedHasLayoutTrait;\n\n// --- Helper Functions ---\n\nfunction getCollectiveBoundingBox(nodes: LayoutNode[]): BoundingBox | null {\n if (nodes.length === 0) {\n return null;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n nodes.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n minX = Math.min(minX, box.x);\n minY = Math.min(minY, box.y);\n maxX = Math.max(maxX, box.x + box.width);\n maxY = Math.max(maxY, box.y + box.height);\n });\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\nfunction calculateMean(arr: number[]): number {\n if (arr.length === 0) return 0;\n return arr.reduce((sum, val) => sum + val, 0) / arr.length;\n}\n\nfunction calculateVariance(arr: number[]): number {\n if (arr.length < 2) return 0;\n const mean = calculateMean(arr);\n return arr.reduce((sum, val) => sum + (val - mean) ** 2, 0) / arr.length;\n}\n\nfunction calculateMedian(arr: number[]): number {\n if (arr.length === 0) return 0;\n const sortedArr = [...arr].sort((a, b) => a - b);\n const mid = Math.floor(sortedArr.length / 2);\n if (sortedArr.length % 2 === 0) {\n return (sortedArr[mid - 1] + sortedArr[mid]) / 2;\n }\n return sortedArr[mid];\n}\n\n// Tolerance for floating point comparisons and alignment checks\nconst EPSILON = 1; // 1 pixel tolerance\n\n// --- Main Inference Function ---\n\nexport function inferLayout(parentNode: LayoutNode): InferResult {\n if (parentNode.layoutMode !== \"NONE\") {\n return {\n properties: {},\n childProperties: {},\n };\n }\n\n const children = (parentNode.children || []) as LayoutNode[];\n const parentBox = parentNode.absoluteBoundingBox!;\n const result: LayoutProperties = { layoutMode: \"NONE\" };\n\n if (children.length === 0) {\n return {\n properties: result,\n childProperties: {},\n }; // Cannot infer layout for no children\n }\n\n if (children.length === 1) {\n // Default for single child: Horizontal, Hug contents, No spacing, Calculate padding\n result.layoutMode = \"HORIZONTAL\";\n result.primaryAxisSizingMode = \"AUTO\";\n result.counterAxisSizingMode = \"AUTO\";\n result.itemSpacing = 0;\n result.primaryAxisAlignItems = \"MIN\"; // Doesn't matter for one item\n result.counterAxisAlignItems = \"MIN\"; // Doesn't matter for one item\n\n const childBox = children[0].absoluteBoundingBox!;\n result.paddingLeft = Math.max(0, childBox.x - parentBox.x);\n result.paddingRight = Math.max(\n 0,\n parentBox.x + parentBox.width - (childBox.x + childBox.width),\n );\n result.paddingTop = Math.max(0, childBox.y - parentBox.y);\n result.paddingBottom = Math.max(\n 0,\n parentBox.y + parentBox.height - (childBox.y + childBox.height),\n );\n return {\n properties: result,\n childProperties: {},\n };\n }\n\n // --- 1. Determine Layout Direction ---\n const sortedByX = [...children].sort(\n (a, b) => a.absoluteBoundingBox!.x - b.absoluteBoundingBox!.x,\n );\n const sortedByY = [...children].sort(\n (a, b) => a.absoluteBoundingBox!.y - b.absoluteBoundingBox!.y,\n );\n\n const horizontalGaps: number[] = [];\n for (let i = 0; i < sortedByX.length - 1; i++) {\n const current = sortedByX[i].absoluteBoundingBox!;\n const next = sortedByX[i + 1].absoluteBoundingBox!;\n // Ensure items don't significantly overlap vertically for horizontal check\n if (Math.max(current.y, next.y) < Math.min(current.y + current.height, next.y + next.height)) {\n horizontalGaps.push(next.x - (current.x + current.width));\n }\n }\n\n const verticalGaps: number[] = [];\n for (let i = 0; i < sortedByY.length - 1; i++) {\n const current = sortedByY[i].absoluteBoundingBox!;\n const next = sortedByY[i + 1].absoluteBoundingBox!;\n // Ensure items don't significantly overlap horizontally for vertical check\n if (Math.max(current.x, next.x) < Math.min(current.x + current.width, next.x + next.width)) {\n verticalGaps.push(next.y - (current.y + current.height));\n }\n }\n\n // Heuristic: Prefer axis with more non-negative gaps and lower variance\n const hVariance = calculateVariance(horizontalGaps.filter((g) => g >= -EPSILON));\n const vVariance = calculateVariance(verticalGaps.filter((g) => g >= -EPSILON));\n const hCount = horizontalGaps.filter((g) => g >= -EPSILON).length;\n const vCount = verticalGaps.filter((g) => g >= -EPSILON).length;\n\n let primaryAxisSortedNodes = sortedByX; // Default guess\n\n // Basic variance check (lower is better). Add slight bias for horizontal if equal.\n if (\n vCount > 0 &&\n (hCount === 0 ||\n (vVariance < hVariance - EPSILON && vCount >= hCount) ||\n (vVariance <= hVariance && vCount > hCount))\n ) {\n result.layoutMode = \"VERTICAL\";\n primaryAxisSortedNodes = sortedByY;\n } else if (hCount > 0) {\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n } else {\n // Ambiguous case based on gaps, fall back to bounding box aspect ratio\n const collectiveBox = getCollectiveBoundingBox(children);\n if (collectiveBox) {\n if (collectiveBox.height > collectiveBox.width) {\n result.layoutMode = \"VERTICAL\";\n primaryAxisSortedNodes = sortedByY;\n } else {\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n }\n } else {\n // Still nothing? Default to Horizontal\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n }\n }\n\n const primaryGaps = result.layoutMode === \"HORIZONTAL\" ? horizontalGaps : verticalGaps;\n const validGaps = primaryGaps.filter((g) => g >= -EPSILON); // Allow slight overlap\n\n // --- 2. Calculate Spacing & Primary Alignment ---\n let isSpaceBetween = false;\n const collectiveBox = getCollectiveBoundingBox(children);\n\n if (collectiveBox && children.length >= 2) {\n // Check for Space Between potential\n const first = primaryAxisSortedNodes[0].absoluteBoundingBox!;\n const last = primaryAxisSortedNodes[primaryAxisSortedNodes.length - 1].absoluteBoundingBox!;\n let firstStart: number;\n let lastEnd: number;\n let parentSize: number;\n\n if (result.layoutMode === \"HORIZONTAL\") {\n firstStart = first.x;\n lastEnd = last.x + last.width;\n parentSize = parentBox.width;\n } else {\n firstStart = first.y;\n lastEnd = last.y + last.height;\n parentSize = parentBox.height;\n }\n\n const contentSpan = lastEnd - firstStart;\n\n // Heuristic for Space Between: Content spans most of the parent & average gap is large\n const averageGap = calculateMean(validGaps);\n // Example threshold: Content fills > 85% AND average gap is > 20% of average item size? Or just large?\n if (contentSpan > parentSize * 0.8 && validGaps.length > 0 && averageGap > 10) {\n // Additional check: are first/last items close to parent edges (considering padding)?\n const startPadding =\n result.layoutMode === \"HORIZONTAL\" ? first.x - parentBox.x : first.y - parentBox.y;\n const endPadding =\n result.layoutMode === \"HORIZONTAL\"\n ? parentBox.x + parentBox.width - (last.x + last.width)\n : parentBox.y + parentBox.height - (last.y + last.height);\n\n // If start/end items are reasonably close to edges (e.g., < 2 * average gap?)\n if (\n Math.abs(startPadding) < Math.max(20, averageGap * 1.5) &&\n Math.abs(endPadding) < Math.max(20, averageGap * 1.5)\n ) {\n isSpaceBetween = true;\n }\n }\n }\n\n if (isSpaceBetween) {\n result.primaryAxisAlignItems = \"SPACE_BETWEEN\";\n result.itemSpacing = 0; // Spacing is implicit\n result.primaryAxisSizingMode = \"FIXED\"; // Usually fixed when using space between\n } else {\n result.primaryAxisAlignItems = \"MIN\"; // Default to MIN for packed, could refine later\n if (validGaps.length > 0) {\n // Use median spacing for robustness against outliers\n result.itemSpacing = calculateMedian(validGaps);\n // Clamp negative spacing if it's very small (likely float error)\n if (result.itemSpacing < 0 && result.itemSpacing > -EPSILON) {\n result.itemSpacing = 0;\n }\n } else {\n result.itemSpacing = 0; // No valid gaps found\n }\n result.primaryAxisSizingMode = \"AUTO\"; // Default to hug content for packed\n }\n\n // --- 3. Calculate Padding ---\n if (collectiveBox) {\n result.paddingLeft = Math.max(0, collectiveBox.x - parentBox.x);\n result.paddingRight = Math.max(\n 0,\n parentBox.x + parentBox.width - (collectiveBox.x + collectiveBox.width),\n );\n result.paddingTop = Math.max(0, collectiveBox.y - parentBox.y);\n result.paddingBottom = Math.max(\n 0,\n parentBox.y + parentBox.height - (collectiveBox.y + collectiveBox.height),\n );\n } else {\n result.paddingLeft = 0;\n result.paddingRight = 0;\n result.paddingTop = 0;\n result.paddingBottom = 0;\n }\n\n // --- 4. Determine Counter Axis Alignment ---\n const counterCoordsMin: number[] = [];\n const counterCoordsCenter: number[] = [];\n const counterCoordsMax: number[] = [];\n\n if (result.layoutMode === \"HORIZONTAL\") {\n // Check vertical alignment (Y)\n children.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n counterCoordsMin.push(box.y);\n counterCoordsCenter.push(box.y + box.height / 2);\n counterCoordsMax.push(box.y + box.height);\n });\n } else {\n // VERTICAL layout\n // Check horizontal alignment (X)\n children.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n counterCoordsMin.push(box.x);\n counterCoordsCenter.push(box.x + box.width / 2);\n counterCoordsMax.push(box.x + box.width);\n });\n }\n\n const minVariance = calculateVariance(counterCoordsMin);\n const centerVariance = calculateVariance(counterCoordsCenter);\n const maxVariance = calculateVariance(counterCoordsMax);\n\n const alignmentTolerance = EPSILON * EPSILON * 4; // Allow slightly more variance for alignment match\n if (\n minVariance <= centerVariance &&\n minVariance <= maxVariance &&\n minVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"MIN\";\n } else if (\n centerVariance <= minVariance &&\n centerVariance <= maxVariance &&\n centerVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"CENTER\";\n } else if (\n maxVariance <= minVariance &&\n maxVariance <= centerVariance &&\n maxVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"MAX\";\n } else {\n // Default if variances are high or similar\n result.counterAxisAlignItems = \"CENTER\";\n }\n\n // --- 5. Determine Counter Axis Sizing Mode ---\n // Default to AUTO unless children perfectly fill the parent counter dimension\n result.counterAxisSizingMode = \"AUTO\";\n if (collectiveBox) {\n let collectiveCounterSize: number;\n let parentCounterSize: number;\n if (result.layoutMode === \"HORIZONTAL\") {\n collectiveCounterSize = collectiveBox.height;\n parentCounterSize = parentBox.height - (result.paddingTop ?? 0) - (result.paddingBottom ?? 0);\n } else {\n collectiveCounterSize = collectiveBox.width;\n parentCounterSize = parentBox.width - (result.paddingLeft ?? 0) - (result.paddingRight ?? 0);\n }\n // If collective size is very close to parent size on counter axis\n if (Math.abs(collectiveCounterSize - parentCounterSize) < EPSILON) {\n result.counterAxisSizingMode = \"FIXED\";\n }\n }\n\n // 6. Infer layoutAlign for each child\n const childProperties: InferResult[\"childProperties\"] = {};\n const availableWidth = parentBox.width - (result.paddingLeft ?? 0) - (result.paddingRight ?? 0);\n const availableHeight = parentBox.height - (result.paddingTop ?? 0) - (result.paddingBottom ?? 0);\n\n children.forEach((child) => {\n const childBox = child.absoluteBoundingBox!;\n let inferredChildAlign: \"INHERIT\" | \"STRETCH\" | undefined = undefined;\n\n // Check STRETCH\n if (result.layoutMode === \"HORIZONTAL\") {\n // Counter: Vertical\n if (Math.abs(childBox.height - availableHeight) < EPSILON && availableHeight > 0) {\n inferredChildAlign = \"STRETCH\";\n }\n } else {\n // Counter: Horizontal\n if (Math.abs(childBox.width - availableWidth) < EPSILON && availableWidth > 0) {\n inferredChildAlign = \"STRETCH\";\n }\n }\n\n if (inferredChildAlign) {\n childProperties[child.id] = { layoutAlign: inferredChildAlign };\n }\n });\n\n return {\n properties: result,\n childProperties,\n };\n}\n\nexport function applyInferredLayout<T extends LayoutNode>(parentNode: T, result: InferResult): T {\n const { properties, childProperties } = result;\n\n if (properties.layoutMode === \"NONE\") {\n return parentNode;\n }\n\n return {\n ...parentNode,\n ...properties,\n children: parentNode.children.map((child) => {\n const props = childProperties[child.id];\n if (props) {\n return { ...child, ...props };\n }\n return child;\n }),\n };\n}\n","export declare const metadata: {\n \"name\": \"🔵 [Template] Error State\",\n \"key\": \"39b4ecd0b5b4d35f4dc5791765ca04aa062a5172\",\n \"componentPropertyDefinitions\": {\n \"Show Buttons#9080:5\": {\n \"type\": \"BOOLEAN\"\n },\n \"Title#16237:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#16237:5\": {\n \"type\": \"TEXT\"\n },\n \"Secondary Action Label#17042:0\": {\n \"type\": \"TEXT\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Default\",\n \"Basement\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"With Title\",\n \"Description Only\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🔵 [Template] Select Box Group\",\n \"key\": \"a3d58bb8540600878742cdcf2608a4b3851667ec\",\n \"componentPropertyDefinitions\": {\n \"Control\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Checkbox\",\n \"Radio\"\n ]\n },\n \"Item Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Action Button\",\n \"key\": \"450ede9d0bf42fc6ef14345c77e6e407d6d5ee89\",\n \"componentPropertyDefinitions\": {\n \"Label#5987:61\": {\n \"type\": \"TEXT\"\n },\n \"Suffix Icon#5987:244\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Prefix Icon#5987:305\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Icon#7574:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"XSmall\",\n \"Small\",\n \"Medium\",\n \"Large\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Text Only\",\n \"Icon First\",\n \"Icon Last\",\n \"Icon Only\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Solid\",\n \"Neutral Weak\",\n \"Neutral Outline\",\n \"Brand Solid\",\n \"Brand Outline\",\n \"Critical Solid\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Alert Dialog\",\n \"key\": \"e0c89524a554ca1bf95c016b7255f29e257624aa\",\n \"componentPropertyDefinitions\": {\n \"Title Text#20361:0\": {\n \"type\": \"TEXT\"\n },\n \"Description Text#20361:7\": {\n \"type\": \"TEXT\"\n },\n \"Show Title#20361:14\": {\n \"type\": \"BOOLEAN\"\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Single\",\n \"Neutral\",\n \"Neutral (Overflow)\",\n \"Critical\",\n \"Critical (Overflow)\",\n \"Nonpreferred\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Avatar\",\n \"key\": \"4a8853c3068c08b69b13e71dd42ce186e968697e\",\n \"componentPropertyDefinitions\": {\n \"Has Image Contents#33407:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"20\",\n \"24\",\n \"36\",\n \"42\",\n \"48\",\n \"64\",\n \"80\",\n \"96\",\n \"108\"\n ]\n },\n \"Badge\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Circle\",\n \"Shield\",\n \"Flower\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Avatar Stack\",\n \"key\": \"e8e91e01000d878742c55cd6e44b6786460440f7\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"20\",\n \"24\",\n \"36\",\n \"42\",\n \"48\",\n \"64\",\n \"80\",\n \"96\",\n \"108\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Badge\",\n \"key\": \"04609a35d47a1a0ef4904b3c25f79451892a85a1\",\n \"componentPropertyDefinitions\": {\n \"Label#1584:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Brand\",\n \"Informative\",\n \"Positive\",\n \"Critical\",\n \"Warning\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Weak\",\n \"Outline\",\n \"Solid\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Bottom Sheet\",\n \"key\": \"16bafa5d1155896fe18fb6f52f904f5cd2048686\",\n \"componentPropertyDefinitions\": {\n \"Title#19787:3\": {\n \"type\": \"TEXT\"\n },\n \"Description#19787:7\": {\n \"type\": \"TEXT\"\n },\n \"Show Close Button#19787:11\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Footer#25162:14\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#25192:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Contents#25320:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"ec1901cb37dc88360ae8fd2b61f71e630fda7924\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5c5369d9c22115fd240d7b75ac2a334e9163ea57\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"8670afb7520ac44dfed003e3e9c7cce359897d0c\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"e3d337e6eddbe9ec025fe69520c1cff0bd697b60\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0c6c58d5b7a159e7db1a0c1ccf32916ca8a51164\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"088624580ee501efed377bb4f42561a387db5699\"\n }\n ]\n },\n \"Show Safe Area#25488:8\": {\n \"type\": \"BOOLEAN\"\n },\n \"Header Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Bottom Left\",\n \"None\",\n \"Bottom Center\",\n \"Top Center\",\n \"Top Left\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Callout\",\n \"key\": \"ec46d38baac3c367c4a5ffa47a2110d51ba0a4fe\",\n \"componentPropertyDefinitions\": {\n \"Prefix Icon#35087:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#35087:1\": {\n \"type\": \"BOOLEAN\"\n },\n \"Pressed#35087:2\": {\n \"type\": \"BOOLEAN\"\n },\n \"Interaction\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Display\",\n \"Actionable\",\n \"Dismissible\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Informative\",\n \"Warning\",\n \"Critical\",\n \"Magic\"\n ]\n },\n \"Show Title\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n },\n \"Show Link Text\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Checkbox\",\n \"key\": \"94a2f6957a86f8ae3b8c7ca200dfcd5e29f6075b\",\n \"componentPropertyDefinitions\": {\n \"Label#49990:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Shape\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Square\",\n \"Ghost\"\n ]\n },\n \"Weight\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Bold\",\n \"Regular\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\",\n \"Indeterminate\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Checkmark\",\n \"key\": \"fae60fb392f55bde60de1dbccb2f453320068805\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Shape\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Square\",\n \"Ghost\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\",\n \"Indeterminate\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Chip\",\n \"key\": \"8156ef08d9aaa2b0de1cc4a113ec0c9d0586f831\",\n \"componentPropertyDefinitions\": {\n \"Label#7185:0\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Icon#8722:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"8ed05ef62a40f2dc034ee7eb6945bd0e63ad49aa\"\n }\n ]\n },\n \"Suffix Type#32538:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"27343e0e5ab2c66948e9b10fde03d58b5e037212\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5f0d74c959c49dadf5920b19c6267924982ab130\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"a1233c35c4368aba2439d39bc8aedc37cf95bd86\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"43b6e51bc372e108a4ee17fbf4c75800d95f4b8c\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"df43b92004c850e7c6d2869e7a4ba1ef9a2d7db6\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"19923052d4152393ecdc6e2f5853ea0359849127\"\n }\n ]\n },\n \"Has Suffix#32538:181\": {\n \"type\": \"BOOLEAN\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Solid\",\n \"Outline Strong\",\n \"Outline Weak\"\n ]\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Large\",\n \"Medium\",\n \"Small\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n },\n \"Prefix Type\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Icon\",\n \"Avatar\",\n \"Image\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Contextual Floating Button\",\n \"key\": \"032f3fddaad0aa3fa5a7f680768c1f5d02fb463f\",\n \"componentPropertyDefinitions\": {\n \"Icon#28796:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Label#28936:0\": {\n \"type\": \"TEXT\"\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Icon First\",\n \"Icon Only\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Solid\",\n \"Layer\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Divider\",\n \"key\": \"848e953725f757ea1a79e1fecc0b608a035032d3\",\n \"componentPropertyDefinitions\": {\n \"Inset (Figma-Only)#36435:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Muted\",\n \"Neutral Subtle\"\n ]\n },\n \"Orientation\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Vertical\",\n \"Horizontal\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Floating Action Button\",\n \"key\": \"65f9e7eede627b893fb8ff94ed9a7d0db900c464\",\n \"componentPropertyDefinitions\": {\n \"Type\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Button\",\n \"Menu\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Help Bubble\",\n \"key\": \"804b327c091278a40d5891939eaed90bb2889659\",\n \"componentPropertyDefinitions\": {\n \"Show Close Button#40538:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#62499:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Title#62535:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#62535:98\": {\n \"type\": \"TEXT\"\n },\n \"Placement\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Right-Top\",\n \"Right-Center\",\n \"Right-Bottom\",\n \"Left-Top\",\n \"Left-Center\",\n \"Left-Bottom\",\n \"Bottom-Left\",\n \"Bottom-Center\",\n \"Bottom-Right\",\n \"Top-Left\",\n \"Top-Center\",\n \"Top-Right\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 List Header\",\n \"key\": \"609f93ed0608ef0a6d9a351e47595ad631bae0fa\",\n \"componentPropertyDefinitions\": {\n \"Title#28588:0\": {\n \"type\": \"TEXT\"\n },\n \"Suffix\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Button\",\n \"Custom\"\n ]\n },\n \"Title Weight\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Bold\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 List Item\",\n \"key\": \"b51b7d07c659fee5d696565b8e1151636573b27c\",\n \"componentPropertyDefinitions\": {\n \"Divider#28441:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Type#28441:42\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"8c52207687ffed15cd5931d71ed9d196b3358a68\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"fe0e25f4fecda59d0a3730ead7c5bc0a66a41e7e\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"abf9810103ae6e6afe8fa253ec5f05d6a7304b38\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0a9464ad270bfd7f56438f62bb0155a25ca146a9\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"4cc7e9b84a8388a36cb3898c6c02e6110a3281b9\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"1e933f75dd6bb4b21c3289b5c3b4402d2c623125\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"11ba71b11b336199654cd2801967a44996705449\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"c0eaee6146c6dc92bfd9b081d667f45ee611b1d2\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"3d788f28c785d1c60b937b253c39ce582dbe1ed3\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"5636566f6de6f58200dce388f7b1ac9f517b30e1\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"3a70bf5bb9856c13893931b7a0df652bcf0be895\"\n }\n ]\n },\n \"Title#28452:21\": {\n \"type\": \"TEXT\"\n },\n \"Has Suffix#28452:64\": {\n \"type\": \"BOOLEAN\"\n },\n \"Has Prefix#28452:85\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Type#28452:106\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0e4c05f097d3fa2dc0cbfdbf8db2662bcf8439ca\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"ef0e8bd6c2f92e620acf204bb9a8079ef25a1e5c\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"82239325aa1cb65af7c649fc71a8f2b48fb9b9f3\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"f24c9ef42ef08df79483fbae0fa7d9037e566748\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5a77ad37a2291989dfe77c44ddee9aa39e447f90\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"81f201fc876e38f016ab7427a6b3da000ee919a2\"\n }\n ]\n },\n \"Has Detail#28469:1\": {\n \"type\": \"BOOLEAN\"\n },\n \"Detail Type#28469:11\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"b27f70404d8f055ec39f9049a5a86920c11be979\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"43795c2e3e507dc555f9ec08bf4bf1abf8c2051a\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"73bcdff1b73998d1f440fb8827df2eafc4338c1d\"\n }\n ]\n },\n \"Title #28487:0\": {\n \"type\": \"TEXT\"\n },\n \"Detail Type #28487:11\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"870d50d39feae5bcfd59d7fbf8ae510233a97a8b\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"43795c2e3e507dc555f9ec08bf4bf1abf8c2051a\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"73bcdff1b73998d1f440fb8827df2eafc4338c1d\"\n }\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\",\n \"Highlighted\"\n ]\n },\n \"Variants\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Single Line\",\n \"Multi Line\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Manner Temp\",\n \"key\": \"37c0a35f73a730fdfba7929cea91a7590fc93733\",\n \"componentPropertyDefinitions\": {\n \"Level\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"L1 (~29.9)\",\n \"L2 (30.0~36.2)\",\n \"L3 (36.3~37.5)\",\n \"L4 (37.6~41.9)\",\n \"L5 (42~51.9)\",\n \"L6 (52~)\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Manner Temp Badge\",\n \"key\": \"3ef9a84d4d80046ff9a581136bd56269554a6e00\",\n \"componentPropertyDefinitions\": {\n \"Level\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"L1 (~29.9)\",\n \"L2 (30.0~36.2)\",\n \"L3 (36.3~37.5)\",\n \"L4 (37.6~41.9)\",\n \"L5 (42~51.9)\",\n \"L6 (52~)\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Menu Sheet\",\n \"key\": \"cd4cf8a850bf3de87b79080b36b421a649bf3fcb\",\n \"componentPropertyDefinitions\": {\n \"Title Text#14599:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Header#17043:12\": {\n \"type\": \"BOOLEAN\"\n },\n \"Description Text#21827:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Safe Area#25531:15\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#32984:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Menu Group Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"2\",\n \"3\",\n \"1\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Text Only\",\n \"Text with Icon\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Multiline Text Field\",\n \"key\": \"88b2399c930c85f9ce2972163a078bc684b84bbe\",\n \"componentPropertyDefinitions\": {\n \"Show Header#870:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Placeholder#958:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Footer#958:25\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#958:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Character count#958:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Indicator#1259:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Filled Text#1304:0\": {\n \"type\": \"TEXT\"\n },\n \"Max Character Count#15327:175\": {\n \"type\": \"TEXT\"\n },\n \"Description#15327:212\": {\n \"type\": \"TEXT\"\n },\n \"Indicator#15327:286\": {\n \"type\": \"TEXT\"\n },\n \"Label#15327:323\": {\n \"type\": \"TEXT\"\n },\n \"Character Count#15327:360\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\",\n \"XLarge\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Focused\",\n \"Invalid\",\n \"Invalid-Focused\",\n \"Disabled\",\n \"Read Only\"\n ]\n },\n \"Filled\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Page Banner\",\n \"key\": \"ce587d0f21754af05240cb32a4880227cb0ea1e1\",\n \"componentPropertyDefinitions\": {\n \"Show Prefix Icon#11840:27\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Icon#35433:45\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Pressed#36736:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Interaction\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Display\",\n \"Actionable\",\n \"Dismissible\",\n \"With Action\",\n \"Custom\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Informative\",\n \"Positive\",\n \"Warning\",\n \"Critical\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Weak\",\n \"Solid\"\n ]\n },\n \"Show Title\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Progress Circle\",\n \"key\": \"6e6779a372cab2485a0e25529bc4dbc9932a7346\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"24\",\n \"40\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Brand\",\n \"Static White\",\n \"Custom(inherit)\"\n ]\n },\n \"Value\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Indeterminate\",\n \"0%\",\n \"25%\",\n \"75%\",\n \"100%\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Radio\",\n \"key\": \"ac72d9e5ab04a1d59eaf77dffd380fd6e491ecf8\",\n \"componentPropertyDefinitions\": {\n \"Label#49990:171\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Weight\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Regular\",\n \"Bold\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Radio Mark\",\n \"key\": \"832d696d6e9566610968cd70f128f500ec009d6a\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"🚫[Deprecated]Brand\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Reaction Button\",\n \"key\": \"ec43e4e881f7048e95601f8b58c01a0905a174e0\",\n \"componentPropertyDefinitions\": {\n \"Label#6397:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Count#6397:33\": {\n \"type\": \"BOOLEAN\"\n },\n \"Icon#12379:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Count#15816:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"XSmall\",\n \"Small\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Segmented Control\",\n \"key\": \"3ad7133ba52755867f42f9232375f75639e00d58\",\n \"componentPropertyDefinitions\": {\n \"Item Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"2\",\n \"3\",\n \"4\"\n ]\n },\n \"Selected Item\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"1\",\n \"2\",\n \"3\",\n \"4\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Select Box\",\n \"key\": \"38722ffeb4c966256a709155e8ddac50c93d7c60\",\n \"componentPropertyDefinitions\": {\n \"Show Description#3033:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Description #3033:5\": {\n \"type\": \"TEXT\"\n },\n \"Label#3635:0\": {\n \"type\": \"TEXT\"\n },\n \"Control\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Checkbox\",\n \"Radio\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Skeleton\",\n \"key\": \"ef22c3288722fbfa64a5ab73df397ade88f8e05a\",\n \"componentPropertyDefinitions\": {\n \"Radius\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"0\",\n \"8\",\n \"16\",\n \"Full\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Magic\",\n \"Neutral\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Snackbar\",\n \"key\": \"81b17fb8c7d731a19cf8d36a8605559d41414eca\",\n \"componentPropertyDefinitions\": {\n \"Show Action#1528:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Message#1528:4\": {\n \"type\": \"TEXT\"\n },\n \"Action Label#1528:8\": {\n \"type\": \"TEXT\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Default\",\n \"Positive\",\n \"Critical\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Switch\",\n \"key\": \"65e0e7ba1a0c13b42e5fd0ceb17d5f756128dd6b\",\n \"componentPropertyDefinitions\": {\n \"Label#36578:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"16\",\n \"24\",\n \"32\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"🚫[Deprecated] Brand\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Disabled\"\n ]\n },\n \"Label Layout(Figma Only)\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Label Last\",\n \"Label First\",\n \"Switch Only\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Tabs\",\n \"key\": \"3e3af9f7f235cbcbbe862d5da552ab23e16ff34e\",\n \"componentPropertyDefinitions\": {\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Line\",\n \"Chip\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Text Field\",\n \"key\": \"c49873c37a639f0dffdea4efd0eb43760d66c141\",\n \"componentPropertyDefinitions\": {\n \"Show Header#870:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Placeholder#958:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Footer#958:25\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#958:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Character Count#958:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Suffix#958:100\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Prefix#958:125\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Indicator#1259:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Prefix Text#1267:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Icon#1267:25\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#1267:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Suffix Icon#1267:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Icon #1267:100\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Suffix Text#1267:125\": {\n \"type\": \"BOOLEAN\"\n },\n \"Filled Text#1304:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#12626:5\": {\n \"type\": \"TEXT\"\n },\n \"Label#14964:0\": {\n \"type\": \"TEXT\"\n },\n \"Max Character Count#15327:27\": {\n \"type\": \"TEXT\"\n },\n \"Character Count#15327:64\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Text#15327:101\": {\n \"type\": \"TEXT\"\n },\n \"Suffix Text#15327:138\": {\n \"type\": \"TEXT\"\n },\n \"Indicator#15327:249\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large(Default)\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Focused\",\n \"Invalid\",\n \"Invalid-Focused\",\n \"Disabled\",\n \"Read Only\"\n ]\n },\n \"Filled\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Toggle Button\",\n \"key\": \"1d240ee5fd7a56879713e69cbea1b6f006f0ea22\",\n \"componentPropertyDefinitions\": {\n \"Label#6122:49\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Icon#6122:98\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Suffix Icon#6122:147\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Icon#6122:343\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#6122:392\": {\n \"type\": \"BOOLEAN\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Small\",\n \"XSmall\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Weak\",\n \"Brand Solid\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Top Navigation\",\n \"key\": \"f6d069d65f8ffc8b430fd8f3013910557f36e9da\",\n \"componentPropertyDefinitions\": {\n \"Show Title#33588:82\": {\n \"type\": \"BOOLEAN\"\n },\n \"OS (Figma Only)\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"iOS\",\n \"Android\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Layer Default\",\n \"Transparent\"\n ]\n },\n \"Left\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Back\",\n \"Close\",\n \"Custom\",\n \"None\"\n ]\n },\n \"Right\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"1 Icon Button\",\n \"2 Icon Button\",\n \"3 Icon Button\",\n \"Text Button\",\n \"None\"\n ]\n }\n }\n};\n","import type { InferComponentDefinition } from \"@/codegen/core\";\nimport type * as metadata from \"@/entities/data/__generated__/component-sets\";\n\nexport type ActionButtonProperties = InferComponentDefinition<\n typeof metadata.actionButton.componentPropertyDefinitions\n>;\n\nexport type ActionButtonGhostProperties = InferComponentDefinition<{\n \"Label#30511:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Prefix Icon#30511:3\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24682\";\n preferredValues: [];\n };\n \"Suffix Icon#30525:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23545\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"c8415f85843e5aea5a1d3620d03d16b643bf86cd\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"0d0a2bc648a2c4e1f06a56a30ef16299b6e91037\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"8f28ae559baf8f388d84ccc3ad65a282966e1b05\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"57341e8a9961bf31590240dd288e57c76969098d\";\n },\n ];\n };\n \"Icon#30525:15\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102336\";\n preferredValues: [];\n };\n Bleed: {\n type: \"VARIANT\";\n defaultValue: \"true\";\n variantOptions: [\"true\", \"false\"];\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Xsmall\", \"Small\", \"Medium\", \"Large\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Icon First\";\n variantOptions: [\"Text Only\", \"Icon First\", \"Icon Last\", \"Icon Only\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Loading\", \"Disabled\"];\n };\n}>;\n\nexport type AlertDialogProperties = InferComponentDefinition<\n typeof metadata.alertDialog.componentPropertyDefinitions\n>;\n\nexport type AlertDialogFooterProperties = InferComponentDefinition<{\n Type: {\n type: \"VARIANT\";\n defaultValue: \"Single\";\n variantOptions: [\n \"Single\",\n \"Neutral\",\n \"Neutral (Overflow)\",\n \"Critical\",\n \"Critical (Overflow)\",\n \"Nonpreferred\",\n ];\n };\n}>;\n\nexport type AvatarProperties = InferComponentDefinition<\n typeof metadata.avatar.componentPropertyDefinitions\n>;\n\nexport type AvatarStackProperties = InferComponentDefinition<\n typeof metadata.avatarStack.componentPropertyDefinitions\n>;\n\nexport type BadgeProperties = InferComponentDefinition<\n typeof metadata.badge.componentPropertyDefinitions\n>;\n\nexport type BottomSheetProperties = InferComponentDefinition<\n typeof metadata.bottomSheet.componentPropertyDefinitions\n>;\n\nexport type CalloutProperties = InferComponentDefinition<\n typeof metadata.callout.componentPropertyDefinitions\n>;\n\nexport type CheckboxProperties = InferComponentDefinition<\n typeof metadata.checkbox.componentPropertyDefinitions\n>;\n\nexport type CheckmarkProperties = InferComponentDefinition<\n typeof metadata.checkmark.componentPropertyDefinitions\n>;\n\nexport type ChipProperties = InferComponentDefinition<\n typeof metadata.chip.componentPropertyDefinitions\n>;\n\nexport type ChipIconSuffixProperties = InferComponentDefinition<{\n \"Icon#33203:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23250\";\n preferredValues: [];\n };\n}>;\n\nexport type ContextualFloatingButtonProperties = InferComponentDefinition<\n typeof metadata.contextualFloatingButton.componentPropertyDefinitions\n>;\n\nexport type DividerProperties = InferComponentDefinition<\n typeof metadata.divider.componentPropertyDefinitions\n>;\n\nexport type ErrorStateProperties = InferComponentDefinition<\n typeof metadata.templateErrorState.componentPropertyDefinitions\n>;\n\nexport type MenuSheetProperties = InferComponentDefinition<\n typeof metadata.menuSheet.componentPropertyDefinitions\n>;\n\nexport type MenuSheetGroupProperties = InferComponentDefinition<{\n \"Action Count\": {\n type: \"VARIANT\";\n defaultValue: \"8\";\n variantOptions: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"];\n };\n}>;\n\nexport type MenuSheetItemProperties = InferComponentDefinition<{\n \"Show Prefix Icon#17043:5\": {\n type: \"BOOLEAN\";\n defaultValue: true;\n };\n \"Label#55905:8\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Prefix Icon#55948:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23245\";\n preferredValues: [];\n };\n Tone: {\n type: \"VARIANT\";\n defaultValue: \"Neutral\";\n variantOptions: [\"Neutral\", \"Critical\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Disabled\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Text Only\";\n variantOptions: [\"Text with Icon\", \"Text Only\"];\n };\n}>;\n\nexport type FloatingActionButtonProperties = InferComponentDefinition<\n typeof metadata.floatingActionButton.componentPropertyDefinitions\n>;\n\nexport type FloatingActionButtonButtonItemProperties = InferComponentDefinition<{\n \"Icon#29766:18\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24681\";\n preferredValues: [];\n };\n \"Label#29808:0\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\"];\n };\n Extended: {\n type: \"VARIANT\";\n defaultValue: \"True\";\n variantOptions: [\"True\", \"False\"];\n };\n}>;\n\nexport type FloatingActionButtonMenuItemProperties = InferComponentDefinition<{\n \"Icon#29766:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24681\";\n preferredValues: [];\n };\n \"Label#29766:9\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Pressed\", \"Enabled\"];\n };\n Extended: {\n type: \"VARIANT\";\n defaultValue: \"True\";\n variantOptions: [\"True\", \"False\"];\n };\n Open: {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"True\", \"False\"];\n };\n}>;\n\nexport type HelpBubbleProperties = InferComponentDefinition<\n typeof metadata.helpBubble.componentPropertyDefinitions\n>;\n\nexport type IdentityPlaceholderProperties = InferComponentDefinition<{\n Identity: {\n type: \"VARIANT\";\n defaultValue: \"Person\";\n variantOptions: [\"Person\", \"Business\"];\n };\n}>;\n\nexport type PageBannerProperties = InferComponentDefinition<\n typeof metadata.pageBanner.componentPropertyDefinitions\n>;\n\nexport type PageBannerButtonProperties = InferComponentDefinition<{\n \"Label#39890:0\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n}>;\n\nexport type ListHeaderProperties = InferComponentDefinition<\n typeof metadata.listHeader.componentPropertyDefinitions\n>;\n\nexport type ListItemProperties = InferComponentDefinition<\n typeof metadata.listItem.componentPropertyDefinitions\n>;\n\nexport type ListItemPrefixIconProperties = InferComponentDefinition<{\n \"Icon#28452:111\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102336\";\n preferredValues: [{ type: \"COMPONENT_SET\"; key: \"1449adc3a216979ac3e6a4a99183a9e9790b220c\" }];\n };\n}>;\n\nexport type ListItemSuffixIconProperties = InferComponentDefinition<{\n \"Icon#28347:9\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23412\";\n preferredValues: [];\n };\n}>;\n\nexport type MannerTempProperties = InferComponentDefinition<\n typeof metadata.mannerTemp.componentPropertyDefinitions\n>;\n\nexport type MannerTempBadgeProperties = InferComponentDefinition<\n typeof metadata.mannerTempBadge.componentPropertyDefinitions\n>;\n\nexport type MultilineTextFieldProperties = InferComponentDefinition<\n typeof metadata.multilineTextField.componentPropertyDefinitions\n>;\n\nexport type ProgressCircleProperties = InferComponentDefinition<\n typeof metadata.progressCircle.componentPropertyDefinitions\n>;\n\nexport type RadioProperties = InferComponentDefinition<\n typeof metadata.radio.componentPropertyDefinitions\n>;\n\nexport type RadioMarkProperties = InferComponentDefinition<\n typeof metadata.radioMark.componentPropertyDefinitions\n>;\n\nexport type ReactionButtonProperties = InferComponentDefinition<\n typeof metadata.reactionButton.componentPropertyDefinitions\n>;\n\nexport type SegmentedControlProperties = InferComponentDefinition<\n typeof metadata.segmentedControl.componentPropertyDefinitions\n>;\n\nexport type SegmentedControlItemProperties = InferComponentDefinition<{\n \"Label#11366:15\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Selected\", \"Disabled\", \"Disabled-Selected\"];\n };\n}>;\n\nexport type SkeletonProperties = InferComponentDefinition<\n typeof metadata.skeleton.componentPropertyDefinitions\n>;\n\nexport type SnackbarProperties = InferComponentDefinition<\n typeof metadata.snackbar.componentPropertyDefinitions\n>;\n\nexport type SwitchProperties = InferComponentDefinition<\n typeof metadata.switch.componentPropertyDefinitions\n>;\n\nexport type ToggleButtonProperties = InferComponentDefinition<\n typeof metadata.toggleButton.componentPropertyDefinitions\n>;\n\nexport type SelectBoxGroupProperties = InferComponentDefinition<\n typeof metadata.templateSelectBoxGroup.componentPropertyDefinitions\n>;\n\nexport type SelectBoxProperties = InferComponentDefinition<\n typeof metadata.selectBox.componentPropertyDefinitions\n>;\n\nexport type TextFieldProperties = InferComponentDefinition<\n typeof metadata.textField.componentPropertyDefinitions\n>;\n\nexport type AppBarProperties = InferComponentDefinition<\n typeof metadata.topNavigation.componentPropertyDefinitions\n>;\n\nexport type AppBarMainProperties = InferComponentDefinition<{\n \"Title#16944:0\": {\n type: \"TEXT\";\n defaultValue: \"타이틀\";\n };\n \"Logo#16958:5\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"1574:3942\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"c7dab3f6d0df0a150564e696c0df00bd43ffef3f\";\n },\n ];\n };\n \"Subtitle#16958:9\": {\n type: \"TEXT\";\n defaultValue: \"서브타이틀\";\n };\n \"Show Right#16958:13\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n \"Show Left#16958:17\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Type: {\n type: \"VARIANT\";\n defaultValue: \"Title\";\n variantOptions: [\"Title\", \"Title-Subtitle\", \"Logo (Figma Only)\"];\n };\n}>;\n\nexport type AppBarLeftIconButtonProperties = InferComponentDefinition<{\n \"Icon#33580:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23427\";\n preferredValues: [];\n };\n}>;\n\nexport type AppBarRightIconButtonProperties = InferComponentDefinition<{\n \"Icon#6406:3\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102301\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"bc7bc98e19d8ffdd9efdc94b610c6af28156f867\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"d766c026e52ee6c78cbf1a474068264e831ddfe3\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"a4cb85e4d25a320d27a48c3e8132a6c01b45ab3c\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"e262d9b447adff63d15a6f1af60ae47cbc1ca47f\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"1d3918afcac320eff3aafc2719b98cf5141afa55\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"8ed05ef62a40f2dc034ee7eb6945bd0e63ad49aa\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"98ee886122c725ac9e3e682f31efd1d1a1bec90d\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"bf71b0c5c8664149298fe1b3c58905715a523e19\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"47a8df3d59bc52aef1c584d992c05771a8125965\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"0fcbc3c123d5c7ee7a5dd20e0860ee25bdc19e30\";\n },\n ];\n };\n Notification: {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"False\", \"True\"];\n };\n}>;\n\nexport type TabsProperties = InferComponentDefinition<\n typeof metadata.tabs.componentPropertyDefinitions\n>;\n\nexport type TabsLineWrapperProperties = InferComponentDefinition<{\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Fill\";\n variantOptions: [\"Hug\", \"Fill\"];\n };\n}>;\n\nexport type TabsLineTriggerHugProperties = InferComponentDefinition<{\n \"Label#4478:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Has Notification#32892:0\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Small\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n}>;\n\nexport type TabsLineTriggerFillProperties = InferComponentDefinition<{\n \"Label#4478:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Has Notification#32904:13\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Small\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n}>;\n\nexport type TabsChipWrapperProperties = InferComponentDefinition<{\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Large\";\n variantOptions: [\"Medium\", \"Large\"];\n };\n Variant: {\n type: \"VARIANT\";\n defaultValue: \"Solid\";\n variantOptions: [\"Solid\", \"Outline\"];\n };\n}>;\n\nexport type ChipTabsTriggerProperties = InferComponentDefinition<{\n \"\\bSize\": {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Medium\", \"Large\"];\n };\n Variant: {\n type: \"VARIANT\";\n defaultValue: \"Solid\";\n variantOptions: [\"Outline\", \"Solid\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n \"Has Notification\": {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"False\", \"True\"];\n };\n}>;\n","import { createCodeGenerator, createValueResolver } from \"@/codegen/core\";\nimport type { CodeGenerator } from \"@/codegen/core/codegen\";\nimport { styleService, variableService } from \"@/codegen/default-services\";\nimport { componentRepository } from \"@/entities\";\nimport { createFrameTransformer } from \"./frame\";\nimport { createInstanceTransformer } from \"./instance\";\nimport {\n createContainerLayoutPropsConverter,\n createFrameFillPropsConverter,\n createRadiusPropsConverter,\n createSelfLayoutPropsConverter,\n createShapeFillPropsConverter,\n createStrokePropsConverter,\n createTextFillPropsConverter,\n createTypeStylePropsConverter,\n} from \"./props\";\nimport {\n createBooleanOperationTransformer,\n createRectangleTransformer,\n createVectorTransformer,\n} from \"./shape\";\nimport { createTextTransformer } from \"./text\";\nimport {\n defaultFillStyleResolver,\n defaultRawValueFormatters,\n defaultTextStyleNameFormatter,\n defaultVariableNameFormatter,\n} from \"./value-resolver\";\n\nexport interface CreatePipelineConfig {\n shouldInferAutoLayout?: boolean;\n shouldInferVariableName?: boolean;\n}\n\nexport function createPipeline(options: CreatePipelineConfig = {}): CodeGenerator {\n const { shouldInferAutoLayout = true, shouldInferVariableName = true } = options;\n\n const valueResolver = createValueResolver({\n variableService,\n variableNameFormatter: defaultVariableNameFormatter,\n styleService,\n textStyleNameFormatter: defaultTextStyleNameFormatter,\n fillStyleResolver: defaultFillStyleResolver,\n rawValueFormatters: defaultRawValueFormatters,\n shouldInferVariableName,\n });\n\n const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);\n const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);\n const frameFillPropsConverter = createFrameFillPropsConverter(valueResolver);\n const shapeFillPropsConverter = createShapeFillPropsConverter(valueResolver);\n const textFillPropsConverter = createTextFillPropsConverter(valueResolver);\n const radiusPropsConverter = createRadiusPropsConverter(valueResolver);\n const strokePropsConverter = createStrokePropsConverter(valueResolver);\n const typeStylePropsConverter = createTypeStylePropsConverter(valueResolver);\n\n const propsConverters = {\n containerLayout: containerLayoutPropsConverter,\n selfLayout: selfLayoutPropsConverter,\n frameFill: frameFillPropsConverter,\n shapeFill: shapeFillPropsConverter,\n textFill: textFillPropsConverter,\n radius: radiusPropsConverter,\n stroke: strokePropsConverter,\n typeStyle: typeStylePropsConverter,\n };\n\n const frameTransformer = createFrameTransformer({\n propsConverters,\n });\n const instanceTransformer = createInstanceTransformer({\n frameTransformer,\n componentRepository,\n });\n const textTransformer = createTextTransformer({\n propsConverters,\n });\n const rectangleTransformer = createRectangleTransformer({\n propsConverters,\n });\n const vectorTransformer = createVectorTransformer({\n propsConverters,\n });\n const booleanOperationTransformer = createBooleanOperationTransformer({\n propsConverters,\n });\n\n const codegenTransformer = createCodeGenerator({\n frameTransformer,\n textTransformer,\n rectangleTransformer,\n instanceTransformer,\n vectorTransformer,\n booleanOperationTransformer,\n shouldInferAutoLayout,\n });\n\n return codegenTransformer;\n}\n","import type { ValueResolver } from \"@/codegen/core\";\nimport { toCssRgba } from \"@/utils/css\";\nimport { camelCase } from \"change-case\";\n\nexport type FigmaValueResolver = ValueResolver<\n string,\n { value: string; direction?: string },\n number,\n number,\n number\n>;\n\nexport const defaultVariableNameFormatter = ({ slug }: { slug: string[] }) =>\n slug\n .filter((s) => s !== \"dimension\")\n .map((s) => s.replaceAll(\",\", \"_\"))\n .join(\"/\");\n\nexport const defaultTextStyleNameFormatter = ({ slug }: { slug: string[] }) =>\n slug[slug.length - 1]!;\n\nexport const defaultFillStyleResolver = ({ slug }: { slug: string[] }) => {\n const [, ...rest] = slug;\n\n if (rest.includes(\"fade\")) {\n // [\"fade\", \"layer-default\", \"↓(to-bottom)\"]\n\n const last = rest[rest.length - 1];\n\n const direction = (() => {\n if (last.startsWith(\"↓\")) return \"to bottom\";\n if (last.startsWith(\"↑\")) return \"to top\";\n if (last.startsWith(\"→\")) return \"to right\";\n if (last.startsWith(\"←\")) return \"to left\";\n\n return \"unknown\";\n })();\n\n return {\n value: camelCase(rest.slice(0, -1).join(\"-\"), { mergeAmbiguousCharacters: true }),\n direction,\n };\n }\n\n return {\n value: camelCase(rest.join(\"-\"), { mergeAmbiguousCharacters: true }),\n };\n};\n\nexport const defaultRawValueFormatters = {\n color: (value: RGBA) => toCssRgba(value),\n dimension: (value: number) => value,\n fontDimension: (value: number) => value,\n fontWeight: (value: number) => value,\n};\n","import { createPropsConverter, definePropsConverter, type PropsConverter } from \"@/codegen/core\";\nimport type {\n NormalizedCornerTrait,\n NormalizedHasChildrenTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasGeometryTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n NormalizedTypePropertiesTrait,\n} from \"@/normalizer\";\nimport type { FigmaValueResolver } from \"./value-resolver\";\n\nexport interface PropsConverters {\n containerLayout: PropsConverter<ContainerLayoutTrait, ContainerLayoutProps>;\n selfLayout: PropsConverter<SelfLayoutTrait, SelfLayoutProps>;\n radius: PropsConverter<RadiusTrait, RadiusProps>;\n frameFill: PropsConverter<FillTrait, FillProps>;\n shapeFill: PropsConverter<FillTrait, FillProps>;\n textFill: PropsConverter<FillTrait, FillProps>;\n stroke: PropsConverter<StrokeTrait, StrokeProps>;\n typeStyle: PropsConverter<TypeStyleTrait, TypeStyleProps>;\n}\n\nexport type ContainerLayoutTrait = NormalizedHasFramePropertiesTrait &\n NormalizedHasChildrenTrait &\n NormalizedHasLayoutTrait &\n NormalizedIsLayerTrait;\n\nexport type SelfLayoutTrait = NormalizedIsLayerTrait & NormalizedHasLayoutTrait;\n\nexport type RadiusTrait = NormalizedCornerTrait & NormalizedIsLayerTrait;\n\nexport type FillTrait = NormalizedIsLayerTrait & NormalizedHasGeometryTrait;\n\nexport type StrokeTrait = NormalizedIsLayerTrait & NormalizedHasGeometryTrait;\n\nexport type TypeStyleTrait = NormalizedTypePropertiesTrait & NormalizedIsLayerTrait;\n\nexport interface ContainerLayoutProps {\n layoutMode?: \"HORIZONTAL\" | \"VERTICAL\" | \"NONE\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"BASELINE\";\n layoutWrap?: \"WRAP\" | \"NO_WRAP\";\n itemSpacing?: number | string; // string when variable\n paddingTop?: number | string; // string when variable\n paddingBottom?: number | string; // string when variable\n paddingLeft?: number | string; // string when variable\n paddingRight?: number | string; // string when variable\n horizontalPadding?: number | string; // string when variable\n verticalPadding?: number | string; // string when variable\n}\n\nexport function createContainerLayoutPropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<ContainerLayoutTrait, ContainerLayoutProps> {\n return createPropsConverter({\n _types: {\n trait: {} as ContainerLayoutTrait,\n props: {} as ContainerLayoutProps,\n },\n handlers: {\n layoutMode: ({ layoutMode }) => (!layoutMode || layoutMode === \"GRID\" ? \"NONE\" : layoutMode),\n primaryAxisAlignItems: ({ primaryAxisAlignItems }) => primaryAxisAlignItems,\n counterAxisAlignItems: ({ counterAxisAlignItems }) => counterAxisAlignItems,\n layoutWrap: ({ layoutWrap }) => layoutWrap,\n itemSpacing: (node) => valueResolver.getFormattedValue.itemSpacing(node),\n paddingTop: (node) => valueResolver.getFormattedValue.paddingTop(node),\n paddingBottom: (node) => valueResolver.getFormattedValue.paddingBottom(node),\n paddingLeft: (node) => valueResolver.getFormattedValue.paddingLeft(node),\n paddingRight: (node) => valueResolver.getFormattedValue.paddingRight(node),\n },\n shorthands: {\n horizontalPadding: [\"paddingLeft\", \"paddingRight\"],\n verticalPadding: [\"paddingTop\", \"paddingBottom\"],\n },\n defaults: {},\n });\n}\n\nexport interface SelfLayoutProps {\n layoutGrow?: number;\n layoutAlign?: \"STRETCH\" | \"INHERIT\" | \"MIN\" | \"CENTER\" | \"MAX\";\n layoutSizingVertical?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutSizingHorizontal?: \"FIXED\" | \"HUG\" | \"FILL\";\n width?: string | number; // string when variable\n height?: string | number; // string when variable\n minWidth?: string | number; // string when variable\n minHeight?: string | number; // string when variable\n maxWidth?: string | number; // string when variable\n maxHeight?: string | number; // string when variable\n}\n\nexport function createSelfLayoutPropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<SelfLayoutTrait, SelfLayoutProps> {\n return createPropsConverter({\n _types: {\n trait: {} as SelfLayoutTrait,\n props: {} as SelfLayoutProps,\n },\n handlers: {\n layoutGrow: ({ layoutGrow }) => layoutGrow,\n layoutAlign: ({ layoutAlign }) => layoutAlign,\n layoutSizingVertical: ({ layoutSizingVertical }) => layoutSizingVertical,\n layoutSizingHorizontal: ({ layoutSizingHorizontal }) => layoutSizingHorizontal,\n width: (node) => valueResolver.getFormattedValue.width(node),\n height: (node) => valueResolver.getFormattedValue.height(node),\n minWidth: (node) => valueResolver.getFormattedValue.minWidth(node),\n minHeight: (node) => valueResolver.getFormattedValue.minHeight(node),\n maxWidth: (node) => valueResolver.getFormattedValue.maxWidth(node),\n maxHeight: (node) => valueResolver.getFormattedValue.maxHeight(node),\n },\n defaults: {},\n });\n}\n\nexport interface RadiusProps {\n cornerRadius?: number | string; // string when variable\n topLeftRadius?: number | string; // string when variable\n topRightRadius?: number | string; // string when variable\n bottomLeftRadius?: number | string; // string when variable\n bottomRightRadius?: number | string; // string when variable\n}\n\nexport function createRadiusPropsConverter(valueResolver: FigmaValueResolver) {\n return createPropsConverter({\n _types: {\n trait: {} as RadiusTrait,\n props: {} as RadiusProps,\n },\n handlers: {\n topLeftRadius: (node) => valueResolver.getFormattedValue.topLeftRadius(node),\n topRightRadius: (node) => valueResolver.getFormattedValue.topRightRadius(node),\n bottomLeftRadius: (node) => valueResolver.getFormattedValue.bottomLeftRadius(node),\n bottomRightRadius: (node) => valueResolver.getFormattedValue.bottomRightRadius(node),\n },\n shorthands: {\n cornerRadius: [\"topLeftRadius\", \"topRightRadius\", \"bottomLeftRadius\", \"bottomRightRadius\"],\n },\n defaults: {\n cornerRadius: 0,\n topLeftRadius: 0,\n topRightRadius: 0,\n bottomLeftRadius: 0,\n bottomRightRadius: 0,\n },\n });\n}\n\nexport interface FillProps {\n fill?: string;\n}\n\nexport function createFrameFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.frameFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport function createShapeFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.shapeFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport function createTextFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.textFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport interface StrokeProps {\n stroke?: string;\n strokeWeight?: number;\n}\n\nexport function createStrokePropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<StrokeTrait, StrokeProps> {\n return definePropsConverter((node: StrokeTrait) => {\n const stroke = valueResolver.getFormattedValue.stroke(node);\n const strokeWeight = node.strokeWeight;\n\n return {\n stroke,\n strokeWeight,\n };\n });\n}\n\nexport interface TypeStyleProps {\n textStyle?: string;\n fontSize?: string | number;\n fontWeight?: string | number;\n lineHeight?: string | number;\n maxLines?: number;\n}\n\nexport function createTypeStylePropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<TypeStyleTrait, TypeStyleProps> {\n return definePropsConverter((node) => {\n const styleName = valueResolver.getTextStyleValue(node);\n const maxLines =\n node.style.textTruncation === \"ENDING\" ? (node.style.maxLines ?? undefined) : undefined;\n\n if (styleName) {\n return {\n textStyle: styleName,\n maxLines,\n };\n }\n\n return {\n fontSize: valueResolver.getFormattedValue.fontSize(node),\n fontWeight: valueResolver.getFormattedValue.fontWeight(node),\n lineHeight: valueResolver.getFormattedValue.lineHeight(node),\n maxLines,\n };\n });\n}\n","import type {\n NormalizedComponentNode,\n NormalizedFrameNode,\n NormalizedInstanceNode,\n} from \"@/normalizer\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface FrameTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createFrameTransformer({\n propsConverters,\n}: FrameTransformerDeps): ElementTransformer<\n NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode\n> {\n return defineElementTransformer(\n (node: NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode, traverse) => {\n const children = node.children;\n\n const props = {\n ...propsConverters.radius(node),\n ...propsConverters.containerLayout(node),\n ...propsConverters.selfLayout(node),\n ...propsConverters.frameFill(node),\n ...propsConverters.stroke(node),\n };\n\n return createElement(\n \"Frame\",\n props,\n children.map((child) => traverse(child)),\n );\n },\n );\n}\n","import type { ComponentRepository } from \"@/entities\";\nimport type { NormalizedInstanceNode } from \"@/normalizer\";\nimport { camelCase } from \"change-case\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\n\nexport interface InstanceTransformerDeps {\n frameTransformer: ElementTransformer<NormalizedInstanceNode>;\n componentRepository?: ComponentRepository;\n}\n\nexport function createInstanceTransformer({\n frameTransformer,\n componentRepository,\n}: InstanceTransformerDeps): ElementTransformer<NormalizedInstanceNode> {\n const transform = defineElementTransformer((node: NormalizedInstanceNode, traverse) => {\n const component = componentRepository?.getOne(node.componentSetKey ?? node.componentKey);\n\n if (component) {\n return createElement(\"Instance\", {\n componentName: component.name,\n ...Object.fromEntries(\n Object.entries(node.componentProperties)\n .filter(([_, props]) => props.type === \"VARIANT\" || props.type === \"TEXT\")\n .map(([key, props]) => [\n camelCase(key.split(\"#\")[0]),\n camelCase(props.value as string),\n ]),\n ),\n });\n }\n\n return frameTransformer(node, traverse);\n });\n\n return transform;\n}\n","import type {\n NormalizedBooleanOperationNode,\n NormalizedRectangleNode,\n NormalizedVectorNode,\n} from \"@/normalizer\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface RectangleTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createRectangleTransformer({\n propsConverters,\n}: RectangleTransformerDeps): ElementTransformer<NormalizedRectangleNode> {\n return defineElementTransformer((node: NormalizedRectangleNode) => {\n return createElement(\"Rectangle\", { ...propsConverters.selfLayout(node) });\n });\n}\n\nexport interface VectorTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createVectorTransformer({\n propsConverters,\n}: VectorTransformerDeps): ElementTransformer<NormalizedVectorNode> {\n return defineElementTransformer((node) => {\n return createElement(\n \"Vector\",\n {\n ...propsConverters.selfLayout(node),\n ...propsConverters.radius(node),\n ...propsConverters.stroke(node),\n ...propsConverters.shapeFill(node),\n },\n [],\n {\n comment: \"Vector Node Placeholder\",\n },\n );\n });\n}\n\nexport interface BooleanOperationTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createBooleanOperationTransformer({\n propsConverters,\n}: BooleanOperationTransformerDeps): ElementTransformer<NormalizedBooleanOperationNode> {\n return defineElementTransformer((node, traverse) => {\n return createElement(\n \"BooleanOperation\",\n {\n ...propsConverters.selfLayout(node),\n ...propsConverters.radius(node),\n ...propsConverters.stroke(node),\n ...propsConverters.shapeFill(node),\n },\n node.children.map(traverse),\n );\n });\n}\n","import type { NormalizedTextNode } from \"@/normalizer\";\nimport { compactObject } from \"@/utils/common\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface TextTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createTextTransformer({\n propsConverters,\n}: TextTransformerDeps): ElementTransformer<NormalizedTextNode> {\n return defineElementTransformer((node: NormalizedTextNode) => {\n const hasMultipleFills = node.fills.length > 1;\n\n const fillProps = propsConverters.textFill(node);\n const typeStyleProps = propsConverters.typeStyle(node);\n\n const props = compactObject({\n ...typeStyleProps,\n ...fillProps,\n });\n\n return createElement(\"Text\", props, node.characters, {\n comment: hasMultipleFills\n ? \"Multiple fills in Text node encountered, only the first fill is used.\"\n : undefined,\n });\n });\n}\n"],"names":[],"mappings":";;;;;AACO;AACA;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACA;AACA;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACA;AACA;AACO;;ACtEA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACA;;ACAA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACnBA;AACP;AACA;AACA;AACA;AACA;AACO;AACP;AACA;;ACTO;AACP;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBO;AACP;AACA;AACA;AACA;;ACJO;AAGA;AACA;;ACJA;AACP;AACA;;ACDO;AACP;AACA;AACA;AACA;;ACLO;AACP;AACA;;ACFO;AACA;AACP;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACZA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;AClDP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACtBA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9DO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClGO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnaO;AACP;AACA;AACA;AACO;;ACJA;AACP;AACA;AACA;;ACDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACA;AACA;AACP;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;;ACrEA;AACP;AACA;AACO;;ACHA;AACP;AACA;AACA;AACO;;ACJA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;;ACXA;AACP;AACA;AACO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.d.ts","sources":["../../src/normalizer/types.ts","../../src/codegen/core/jsx.ts","../../src/codegen/core/element-transformer.ts","../../src/codegen/core/codegen.ts","../../src/codegen/core/component-handler.ts","../../src/codegen/core/component-type-helper.ts","../../src/entities/component.interface.ts","../../src/entities/variable.interface.ts","../../src/entities/style.service.ts","../../src/entities/variable.service.ts","../../src/entities/component.repository.ts","../../src/codegen/core/props-converter.ts","../../src/codegen/core/value-resolver.ts","../../src/codegen/core/infer-layout.ts","../../src/entities/data/__generated__/component-sets/template-error-state.d.ts","../../src/entities/data/__generated__/component-sets/template-select-box-group.d.ts","../../src/entities/data/__generated__/component-sets/action-button.d.ts","../../src/entities/data/__generated__/component-sets/alert-dialog.d.ts","../../src/entities/data/__generated__/component-sets/avatar.d.ts","../../src/entities/data/__generated__/component-sets/avatar-stack.d.ts","../../src/entities/data/__generated__/component-sets/badge.d.ts","../../src/entities/data/__generated__/component-sets/bottom-sheet.d.ts","../../src/entities/data/__generated__/component-sets/callout.d.ts","../../src/entities/data/__generated__/component-sets/checkbox.d.ts","../../src/entities/data/__generated__/component-sets/checkmark.d.ts","../../src/entities/data/__generated__/component-sets/chip.d.ts","../../src/entities/data/__generated__/component-sets/contextual-floating-button.d.ts","../../src/entities/data/__generated__/component-sets/divider.d.ts","../../src/entities/data/__generated__/component-sets/floating-action-button.d.ts","../../src/entities/data/__generated__/component-sets/help-bubble.d.ts","../../src/entities/data/__generated__/component-sets/list-header.d.ts","../../src/entities/data/__generated__/component-sets/list-item.d.ts","../../src/entities/data/__generated__/component-sets/manner-temp.d.ts","../../src/entities/data/__generated__/component-sets/manner-temp-badge.d.ts","../../src/entities/data/__generated__/component-sets/menu-sheet.d.ts","../../src/entities/data/__generated__/component-sets/multiline-text-field.d.ts","../../src/entities/data/__generated__/component-sets/page-banner.d.ts","../../src/entities/data/__generated__/component-sets/progress-circle.d.ts","../../src/entities/data/__generated__/component-sets/radio.d.ts","../../src/entities/data/__generated__/component-sets/radio-mark.d.ts","../../src/entities/data/__generated__/component-sets/reaction-button.d.ts","../../src/entities/data/__generated__/component-sets/segmented-control.d.ts","../../src/entities/data/__generated__/component-sets/select-box.d.ts","../../src/entities/data/__generated__/component-sets/skeleton.d.ts","../../src/entities/data/__generated__/component-sets/snackbar.d.ts","../../src/entities/data/__generated__/component-sets/switch.d.ts","../../src/entities/data/__generated__/component-sets/switch-mark.d.ts","../../src/entities/data/__generated__/component-sets/tabs.d.ts","../../src/entities/data/__generated__/component-sets/text-field.d.ts","../../src/entities/data/__generated__/component-sets/toggle-button.d.ts","../../src/entities/data/__generated__/component-sets/top-navigation.d.ts","../../src/codegen/component-properties.ts","../../src/codegen/targets/figma/pipeline.ts","../../src/codegen/targets/figma/value-resolver.ts","../../src/codegen/targets/figma/props.ts","../../src/codegen/targets/figma/frame.ts","../../src/codegen/targets/figma/instance.ts","../../src/codegen/targets/figma/shape.ts","../../src/codegen/targets/figma/text.ts"],"sourcesContent":["import type * as FigmaRestSpec from \"@figma/rest-api-spec\";\n\nexport type NormalizedIsLayerTrait = Pick<\n FigmaRestSpec.IsLayerTrait,\n \"type\" | \"id\" | \"name\" | \"boundVariables\"\n>;\n\nexport type NormalizedCornerTrait = Pick<\n FigmaRestSpec.CornerTrait,\n \"cornerRadius\" | \"rectangleCornerRadii\"\n>;\n\nexport type NormalizedHasChildrenTrait = {\n children: NormalizedSceneNode[];\n};\n\nexport type NormalizedHasLayoutTrait = Pick<\n FigmaRestSpec.HasLayoutTrait,\n | \"layoutAlign\"\n | \"layoutGrow\"\n | \"absoluteBoundingBox\"\n | \"relativeTransform\"\n | \"layoutPositioning\"\n | \"layoutSizingHorizontal\"\n | \"layoutSizingVertical\"\n | \"minHeight\"\n | \"minWidth\"\n | \"maxHeight\"\n | \"maxWidth\"\n>;\n\nexport type NormalizedHasGeometryTrait = Pick<\n FigmaRestSpec.HasGeometryTrait,\n \"fills\" | \"strokes\" | \"strokeWeight\" | \"styles\"\n> & {\n fillStyleKey?: string;\n};\n\nexport type NormalizedHasFramePropertiesTrait = Pick<\n FigmaRestSpec.HasFramePropertiesTrait,\n | \"layoutMode\"\n | \"layoutWrap\"\n | \"paddingLeft\"\n | \"paddingRight\"\n | \"paddingTop\"\n | \"paddingBottom\"\n | \"primaryAxisAlignItems\"\n | \"primaryAxisSizingMode\"\n | \"counterAxisAlignItems\"\n | \"counterAxisSizingMode\"\n | \"itemSpacing\"\n | \"counterAxisSpacing\"\n>;\n\nexport interface NormalizedTextSegment {\n characters: string;\n start: number;\n end: number;\n style: {\n fontFamily?: string;\n fontWeight?: number;\n fontSize?: number;\n italic?: boolean;\n textDecoration?: string;\n letterSpacing?: number;\n lineHeight?: number | { unit: string; value: number };\n };\n}\n\nexport type NormalizedTypePropertiesTrait = Pick<\n FigmaRestSpec.TypePropertiesTrait,\n \"style\" | \"characters\"\n> & {\n segments: NormalizedTextSegment[];\n\n textStyleKey?: string;\n};\n\nexport type NormalizedDefaultShapeTrait = NormalizedIsLayerTrait &\n NormalizedHasLayoutTrait &\n NormalizedHasGeometryTrait;\n\nexport type NormalizedFrameTrait = NormalizedIsLayerTrait &\n NormalizedHasLayoutTrait &\n NormalizedHasGeometryTrait &\n NormalizedHasChildrenTrait &\n NormalizedCornerTrait &\n NormalizedHasFramePropertiesTrait;\n\nexport interface NormalizedFrameNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.FrameNode[\"type\"];\n}\n\nexport interface NormalizedRectangleNode\n extends NormalizedDefaultShapeTrait,\n NormalizedCornerTrait {\n type: FigmaRestSpec.RectangleNode[\"type\"];\n}\n\nexport interface NormalizedTextNode\n extends NormalizedDefaultShapeTrait,\n NormalizedTypePropertiesTrait {\n type: FigmaRestSpec.TextNode[\"type\"];\n}\n\nexport interface NormalizedComponentNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.ComponentNode[\"type\"];\n}\n\nexport interface NormalizedInstanceNode extends NormalizedFrameTrait {\n type: FigmaRestSpec.InstanceNode[\"type\"];\n\n componentProperties: {\n [key: string]: FigmaRestSpec.ComponentProperty & {\n componentKey?: string;\n componentSetKey?: string;\n };\n };\n\n componentKey: string;\n\n componentSetKey?: string;\n\n overrides?: FigmaRestSpec.InstanceNode[\"overrides\"];\n\n children: NormalizedSceneNode[];\n}\n\nexport interface NormalizedVectorNode extends NormalizedDefaultShapeTrait, NormalizedCornerTrait {\n type: FigmaRestSpec.VectorNode[\"type\"];\n}\n\nexport interface NormalizedBooleanOperationNode\n extends NormalizedIsLayerTrait,\n NormalizedHasChildrenTrait,\n NormalizedHasLayoutTrait,\n NormalizedHasGeometryTrait {\n type: FigmaRestSpec.BooleanOperationNode[\"type\"];\n}\n\nexport interface NormalizedUnhandledNode {\n type: \"UNHANDLED\";\n id: string;\n original: FigmaRestSpec.Node | SceneNode;\n}\n\nexport type NormalizedSceneNode =\n | NormalizedFrameNode\n | NormalizedRectangleNode\n | NormalizedTextNode\n | NormalizedComponentNode\n | NormalizedInstanceNode\n | NormalizedVectorNode\n | NormalizedBooleanOperationNode\n | NormalizedUnhandledNode;\n","import { ensureArray, exists } from \"@/utils/common\";\n\nexport interface ElementNode {\n __IS_JSX_ELEMENT_NODE: true;\n tag: string;\n props: Record<string, string | number | boolean | ElementNode | object | undefined>;\n children: (ElementNode | string)[];\n\n meta: {\n comment?: string;\n source?: string;\n importPath?: string;\n };\n}\n\nexport function createElement(\n tag: string,\n props: Record<string, string | number | boolean | object | undefined> = {},\n children?: ElementNode | string | undefined | (ElementNode | string | undefined)[],\n meta?: ElementNode[\"meta\"],\n): ElementNode {\n return {\n __IS_JSX_ELEMENT_NODE: true,\n tag,\n props,\n children: ensureArray(children).filter(exists),\n meta: meta ?? {},\n };\n}\n\nexport function cloneElement(\n element: ElementNode,\n props: Record<string, string | number | boolean | object | undefined> = {},\n children?: ElementNode | string | undefined | (ElementNode | string | undefined)[],\n) {\n return {\n ...element,\n props: { ...element.props, ...props },\n children: children ? ensureArray(children).filter(exists) : element.children,\n };\n}\n\nexport function appendSource(element: ElementNode, source: string) {\n return {\n ...element,\n source,\n };\n}\n\nexport function isElement(node: unknown): node is ElementNode {\n return (\n typeof node === \"object\" &&\n node != null &&\n \"__IS_JSX_ELEMENT_NODE\" in node &&\n node.__IS_JSX_ELEMENT_NODE === true\n );\n}\n\nexport function stringifyElement(element: ElementNode, options: { printSource?: boolean } = {}) {\n const importMap = new Map<string, Set<string>>();\n\n function recursive(node: ElementNode | string, depth: number): string {\n if (typeof node === \"string\") {\n return node;\n }\n\n const {\n tag,\n props,\n children,\n meta: { comment, source, importPath },\n } = node;\n\n if (importPath) {\n const existing = importMap.get(importPath);\n\n const [namespace] = tag.split(\".\");\n\n if (existing) {\n existing.add(namespace);\n } else {\n importMap.set(importPath, new Set([namespace]));\n }\n }\n\n const propEntries = Object.entries(\n options.printSource ? { ...props, \"data-figma-node-id\": source } : props,\n );\n const propFragments = propEntries\n .map(([key, value]) => {\n if (typeof value === \"string\") {\n if (value.includes(\"\\n\")) {\n return `${key}={\"${value.replaceAll(\"\\n\", \"\\\\n\")}\"}`;\n }\n\n return `${key}=\"${value}\"`;\n }\n\n if (typeof value === \"number\") {\n return `${key}={${value}}`;\n }\n\n if (typeof value === \"boolean\") {\n if (value === true) return key;\n\n return `${key}={${value}}`;\n }\n\n if (isElement(value)) {\n const elementStr = recursive(value, depth + 1);\n\n const commentMatch = elementStr.match(/\\{\\/\\* (.+?)\\*\\/\\}$/);\n\n if (commentMatch) {\n const elementWithoutComment = elementStr.replace(/\\{\\/\\* .+? \\*\\/\\}$/, \"\");\n\n return `${key}={${elementWithoutComment}}/* ${commentMatch[1]} */`;\n }\n\n return `${key}={${elementStr}}`;\n }\n\n if (typeof value === \"object\") {\n return `${key}={${JSON.stringify(value)}}`;\n }\n\n if (typeof value === \"undefined\") {\n return undefined;\n }\n\n return undefined;\n })\n .filter(exists);\n\n const oneLiner = propFragments.join(\" \");\n const propsString =\n propEntries.length === 0\n ? \"\"\n : ` ${\n oneLiner.length < 80\n ? oneLiner\n : `\\n${\" \".repeat(depth + 1)}${propFragments.join(\n `\\n${\" \".repeat(depth + 1)}`,\n )}\\n${\" \".repeat(depth)}`\n }`;\n\n if (children == null || children.length === 0) {\n return `<${tag}${propsString} />${comment ? `{/* ${comment} */}` : \"\"}`;\n }\n\n const result = [\n `<${tag}${propsString}>`,\n ...ensureArray(children)\n .filter(exists)\n .map((child) => recursive(child, depth + 1))\n .map((str) => \" \".repeat(depth + 1) + str),\n `${\" \".repeat(depth)}</${tag}>${comment ? `{/* ${comment} */}` : \"\"}`,\n ].join(\"\\n\");\n\n return result;\n }\n\n const jsx = recursive(element, 0);\n\n const imports = Array.from(importMap.entries())\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([importPath, tags]) => `import { ${Array.from(tags).join(\", \")} } from \"${importPath}\";`)\n .join(\"\\n\");\n\n return {\n imports,\n jsx,\n };\n}\n","import type { NormalizedSceneNode } from \"@/normalizer\";\nimport type { ElementNode } from \"./jsx\";\n\nexport type ElementTransformer<T extends NormalizedSceneNode> = (\n node: T,\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n) => ElementNode | undefined;\n\nexport function defineElementTransformer<T extends NormalizedSceneNode>(\n transformer: ElementTransformer<T>,\n) {\n return transformer;\n}\n","import type {\n NormalizedBooleanOperationNode,\n NormalizedComponentNode,\n NormalizedFrameNode,\n NormalizedInstanceNode,\n NormalizedRectangleNode,\n NormalizedSceneNode,\n NormalizedTextNode,\n NormalizedVectorNode,\n} from \"@/normalizer\";\nimport { match } from \"ts-pattern\";\nimport { appendSource, createElement, stringifyElement, type ElementNode } from \"../core/jsx\";\nimport type { ElementTransformer } from \"./element-transformer\";\nimport { applyInferredLayout, inferLayout } from \"./infer-layout\";\n\nexport interface CodeGeneratorDeps {\n frameTransformer: ElementTransformer<\n NormalizedFrameNode | NormalizedComponentNode | NormalizedInstanceNode\n >;\n textTransformer: ElementTransformer<NormalizedTextNode>;\n rectangleTransformer: ElementTransformer<NormalizedRectangleNode>;\n instanceTransformer: ElementTransformer<NormalizedInstanceNode>;\n vectorTransformer: ElementTransformer<NormalizedVectorNode>;\n booleanOperationTransformer: ElementTransformer<NormalizedBooleanOperationNode>;\n shouldInferAutoLayout: boolean;\n}\n\nexport interface CodeGenerator {\n generateJsxTree: (node: NormalizedSceneNode) => ElementNode | undefined;\n generateCode: (\n node: NormalizedSceneNode,\n options: { shouldPrintSource: boolean },\n ) => { imports: string; jsx: string } | undefined;\n}\n\nexport function createCodeGenerator({\n frameTransformer,\n textTransformer,\n rectangleTransformer,\n instanceTransformer,\n vectorTransformer,\n booleanOperationTransformer,\n shouldInferAutoLayout,\n}: CodeGeneratorDeps): CodeGenerator {\n function traverse(node: NormalizedSceneNode): ElementNode | undefined {\n if (\"visible\" in node && !node.visible) {\n return;\n }\n\n const result = match(node)\n .with({ type: \"FRAME\" }, (node) =>\n shouldInferAutoLayout\n ? frameTransformer(applyInferredLayout(node, inferLayout(node)), traverse)\n : frameTransformer(node, traverse),\n )\n .with({ type: \"TEXT\" }, (node) => textTransformer(node, traverse))\n .with({ type: \"RECTANGLE\" }, (node) => rectangleTransformer(node, traverse))\n .with({ type: \"COMPONENT\" }, (node) => frameTransformer(node, traverse)) // NOTE: Treat component node as Frame for now\n .with({ type: \"INSTANCE\" }, (node) => instanceTransformer(node, traverse))\n .with({ type: \"VECTOR\" }, (node) => vectorTransformer(node, traverse))\n .with({ type: \"BOOLEAN_OPERATION\" }, (node) => booleanOperationTransformer(node, traverse))\n .with({ type: \"UNHANDLED\" }, () => createElement(\"UnhandledFigmaNode\"))\n .exhaustive();\n\n if (result) {\n return appendSource(result, node.id);\n }\n\n return;\n }\n\n function generateJsxTree(node: NormalizedSceneNode) {\n return traverse(node);\n }\n\n function generateCode(node: NormalizedSceneNode, options: { shouldPrintSource: boolean }) {\n const jsxTree = generateJsxTree(node);\n\n if (!jsxTree) {\n return undefined;\n }\n\n return stringifyElement(jsxTree, { printSource: options.shouldPrintSource });\n }\n\n return { generateJsxTree, generateCode };\n}\n","import type { NormalizedInstanceNode, NormalizedSceneNode } from \"@/normalizer\";\nimport type { ElementNode } from \"./jsx\";\n\nexport interface ComponentHandler<\n T extends\n NormalizedInstanceNode[\"componentProperties\"] = NormalizedInstanceNode[\"componentProperties\"],\n> {\n key: string;\n transform: (\n node: Omit<NormalizedInstanceNode, \"componentProperties\"> & { componentProperties: T },\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n ) => ElementNode;\n}\n\nexport function defineComponentHandler<T extends NormalizedInstanceNode[\"componentProperties\"]>(\n key: string,\n transform: (\n node: Omit<NormalizedInstanceNode, \"componentProperties\"> & { componentProperties: T },\n traverse: (node: NormalizedSceneNode) => ElementNode | undefined,\n ) => ElementNode,\n): ComponentHandler<T> {\n return { key, transform };\n}\n","import type { ComponentPropertyType, InstanceSwapPreferredValue } from \"@figma/rest-api-spec\";\n\nexport interface ComponentPropertyDefinition {\n type: ComponentPropertyType;\n preferredValues?: InstanceSwapPreferredValue[];\n variantOptions?: string[];\n}\n\nexport type InferComponentPropertyType<T extends ComponentPropertyDefinition> =\n T[\"type\"] extends \"TEXT\"\n ? string\n : T[\"type\"] extends \"BOOLEAN\"\n ? boolean\n : T[\"type\"] extends \"INSTANCE_SWAP\"\n ? string\n : T[\"type\"] extends \"VARIANT\"\n ? T[\"variantOptions\"] extends string[]\n ? T[\"variantOptions\"][number]\n : never\n : never;\n\nexport type InferComponentDefinition<T extends Record<string, ComponentPropertyDefinition>> = {\n [K in keyof T]: {\n type: T[K][\"type\"];\n value: InferComponentPropertyType<T[K]>;\n readonly boundVariables?: {\n [field in VariableBindableComponentPropertyField]?: VariableAlias;\n };\n } & (T[K][\"type\"] extends \"INSTANCE_SWAP\"\n ? {\n componentKey: string;\n preferredValues: InstanceSwapPreferredValue[];\n }\n : {});\n};\n","import type { ComponentPropertyDefinition } from \"@/codegen\";\n\nexport interface ComponentMetadata {\n name: string;\n key: string;\n componentPropertyDefinitions: Record<string, ComponentPropertyDefinition>;\n}\n","import type {\n LocalVariable,\n LocalVariableCollection,\n VariableAlias,\n VariableResolvedDataType,\n} from \"@figma/rest-api-spec\";\n\nexport type Variable = LocalVariable;\n\nexport type VariableCollection = LocalVariableCollection;\n\nexport type VariableType = VariableResolvedDataType;\n\nexport type VariableValue = Variable[\"valuesByMode\"][string];\n\nexport type VariableValueResolved = Exclude<VariableValue, VariableAlias>;\n\nexport type { VariableScope } from \"@figma/rest-api-spec\";\n","import type { StyleRepository } from \"./style.repository\";\n\nexport interface StyleService {\n getSlug: (id: string) => string[] | undefined;\n}\n\n// TODO: inferStyleName 추가해야 함, rest api에서 style value가 제공되지 않고 있어 보류\nexport function createStyleService({\n styleRepository,\n}: {\n styleRepository: StyleRepository;\n}): StyleService {\n function getName(id: string) {\n const style = styleRepository.findOneByKey(id);\n\n if (!style) {\n return undefined;\n }\n\n return style.name;\n }\n\n function getSlug(id: string): string[] | undefined {\n const name = getName(id);\n\n if (!name) {\n return undefined;\n }\n\n return name.split(\"/\");\n }\n\n return {\n getSlug,\n };\n}\n","import {\n isIdenticalVariableValue,\n isInsideScope,\n isVariableAlias,\n sanitizeVariableId,\n} from \"@/utils/figma-variable\";\nimport type { Variable, VariableScope, VariableValueResolved } from \"./variable.interface\";\nimport type { VariableRepository } from \"./variable.repository\";\n\nexport interface VariableService {\n getSlug: (id: string) => string[] | undefined;\n resolveValue: (variable: Variable, mode: string) => VariableValueResolved;\n infer: (value: VariableValueResolved, scope: VariableScope) => Variable | undefined;\n}\n\nexport interface VariableServiceDeps {\n variableRepository: VariableRepository;\n inferCompareFunction: (a: Variable, b: Variable) => number;\n}\n\nexport function createVariableService({\n variableRepository,\n inferCompareFunction,\n}: VariableServiceDeps): VariableService {\n const variables = variableRepository.getVariableList();\n\n // private\n function getName(key: string) {\n const sanitizedId = sanitizeVariableId(key);\n const variable = variableRepository.findVariableByKey(sanitizedId);\n\n if (!variable) {\n return undefined;\n }\n\n return variable.name;\n }\n\n function getDefaultModeId(variable: Variable) {\n const variableCollection = variableRepository.findVariableCollectionById(\n variable.variableCollectionId,\n );\n\n if (!variableCollection) {\n // Variable collection not found: ${variable.variableCollectionId}, falling back to variable.valuesByMode key\n return Object.keys(variable.valuesByMode)[0]!;\n }\n\n return variableCollection.defaultModeId;\n }\n\n // public\n function getSlug(key: string): string[] | undefined {\n const name = getName(key);\n\n if (!name) {\n return undefined;\n }\n\n return name.split(\"/\");\n }\n\n function resolveValue(variable: Variable, mode: string): VariableValueResolved {\n const value = variable.valuesByMode[mode];\n\n if (value === undefined) {\n throw new Error(`Variable value not found: ${variable.id} ${mode}`);\n }\n\n if (isVariableAlias(value)) {\n const resolvedVariable = variableRepository.findVariableById(value.id);\n\n if (!resolvedVariable) {\n throw new Error(`Variable not found: ${value.id}`);\n }\n\n return resolveValue(resolvedVariable, mode);\n }\n\n return value;\n }\n\n function infer(value: VariableValueResolved, scope: VariableScope) {\n // NOTE: We assume that the variable is in the default mode or value is equal between all modes for simplicity.\n const inferredVariables = variables.filter(\n (variable) =>\n isInsideScope(variable, scope) &&\n isIdenticalVariableValue(resolveValue(variable, getDefaultModeId(variable)), value),\n );\n\n const sortedVariables = inferredVariables.sort(inferCompareFunction);\n\n return sortedVariables[0];\n }\n\n return {\n getSlug,\n resolveValue,\n infer,\n };\n}\n","import type { ComponentMetadata } from \"./component.interface\";\n\nexport interface ComponentRepository {\n getOne(key: string): ComponentMetadata | undefined;\n}\n\nexport function createStaticComponentRepository(data: Record<string, ComponentMetadata>) {\n const componentRecord: Record<string, ComponentMetadata> = {};\n Object.values(data).forEach((component) => {\n componentRecord[component.key] = component;\n });\n\n return {\n getOne: (key: string) => componentRecord[key],\n };\n}\n","import type { VariableValueResolved } from \"@/entities\";\nimport { objectEntries } from \"@/utils/common\";\n\nexport type PropsConverter<\n T extends Record<string, any> = Record<string, any>,\n R extends Record<string, any> = Record<string, any>,\n> = (node: T) => R;\n\nexport function definePropsConverter<T extends Record<string, any>, R extends Record<string, any>>(\n converter: PropsConverter<T, R>,\n) {\n return converter;\n}\n\ntype Handlers<\n TTrait extends Record<string, VariableValueResolved>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps = keyof TProps,\n> = {\n [K in HandlerKeys]: (node: TTrait) => TProps[K];\n};\n\ntype Shorthands<TProps extends Record<string, any>, HandlerKeys extends keyof TProps> = Record<\n Exclude<keyof TProps, HandlerKeys>,\n HandlerKeys[]\n>;\n\nexport interface CreatePropsConverterConfig<\n TTrait extends Record<string, any>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps,\n> {\n _types: {\n trait: TTrait;\n props: TProps;\n };\n handlers: Handlers<TTrait, TProps, HandlerKeys>;\n shorthands?: Shorthands<TProps, HandlerKeys>;\n defaults?: Partial<TProps>;\n}\n\nexport function createPropsConverter<\n TTrait extends Record<string, any>,\n TProps extends Record<string, any>,\n HandlerKeys extends keyof TProps,\n>({\n handlers,\n shorthands,\n defaults,\n}: CreatePropsConverterConfig<TTrait, TProps, HandlerKeys>): PropsConverter<TTrait, TProps> {\n return definePropsConverter((node: TTrait) => {\n const result = {} as TProps;\n\n for (const [prop, handler] of objectEntries(handlers)) {\n const value = handler(node);\n if (value !== undefined && (!defaults || value !== defaults[prop as keyof TProps])) {\n result[prop as keyof TProps] = value as any;\n }\n }\n\n if (shorthands) {\n for (const [shorthand, props] of objectEntries(shorthands)) {\n const values = props.map((prop) => result[prop as keyof TProps]);\n const allDefined = values.every((value) => value !== undefined);\n const allEqual = allDefined && values.every((value) => value === values[0]);\n\n if (allEqual && values[0] !== undefined) {\n result[shorthand as keyof TProps] = values[0] as any;\n for (const prop of props) {\n delete result[prop as keyof TProps];\n }\n }\n }\n }\n\n return result;\n });\n}\n","import type { StyleService, VariableValueResolved } from \"@/entities\";\nimport type {\n NormalizedCornerTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasGeometryTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n NormalizedTypePropertiesTrait,\n} from \"@/normalizer\";\nimport {\n getFirstFillVariable,\n getFirstSolidFill,\n getFirstStroke,\n getFirstStrokeVariable,\n} from \"@/utils/figma-node\";\nimport type { RGBA } from \"@figma/rest-api-spec\";\nimport type { VariableService } from \"../../entities/variable.service\";\n\nexport interface ValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {\n getFormattedValue: {\n frameFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | TGradient | undefined;\n shapeFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n textFill: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n stroke: (\n node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,\n ) => string | TColor | undefined;\n width: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n height: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n minWidth: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n minHeight: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n maxWidth: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n maxHeight: (\n node: NormalizedHasLayoutTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingLeft: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingRight: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingTop: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n paddingBottom: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n itemSpacing: (\n node: NormalizedHasFramePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n topLeftRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n topRightRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n bottomLeftRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n bottomRightRadius: (\n node: NormalizedCornerTrait & NormalizedIsLayerTrait,\n ) => string | TDimension | undefined;\n fontSize: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontDimension | undefined;\n fontWeight: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontWeight | undefined;\n lineHeight: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | TFontDimension | undefined;\n };\n getTextStyleValue: (\n node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait,\n ) => string | undefined; // TODO: we might turn this into a generic; not sure yet\n}\n\nexport interface ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {\n variableService: VariableService;\n variableNameFormatter: (props: { slug: string[] }) => string;\n styleService: StyleService;\n textStyleNameFormatter: (props: { slug: string[] }) => string;\n fillStyleResolver: (props: { slug: string[] }) => TGradient | undefined;\n rawValueFormatters: {\n color: (value: RGBA) => string | TColor;\n dimension: (value: number) => string | TDimension;\n fontDimension: (value: number) => string | TFontDimension;\n fontWeight: (value: number) => string | TFontWeight;\n };\n shouldInferVariableName: boolean;\n}\n\nexport function createValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight>({\n variableService,\n variableNameFormatter,\n styleService,\n textStyleNameFormatter,\n fillStyleResolver,\n rawValueFormatters,\n shouldInferVariableName,\n}: ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight>): ValueResolver<\n TColor,\n TGradient,\n TDimension,\n TFontDimension,\n TFontWeight\n> {\n function getVariableName(key: string) {\n const slug = variableService.getSlug(key);\n\n if (!slug) {\n return undefined;\n }\n\n return variableNameFormatter({ slug });\n }\n\n function inferVariableName(value: VariableValueResolved, scope: VariableScope) {\n if (!shouldInferVariableName) {\n return undefined;\n }\n\n try {\n const inferred = variableService.infer(value, scope);\n\n if (!inferred) {\n return undefined;\n }\n\n return getVariableName(inferred.key);\n } catch {\n return undefined;\n }\n }\n\n function processColor(\n key: string | undefined,\n value: RGBA | undefined,\n scope: \"FRAME_FILL\" | \"SHAPE_FILL\" | \"STROKE_COLOR\" | \"TEXT_FILL\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.color(value);\n }\n\n return undefined;\n }\n\n function processFillStyle(key: string) {\n const slug = styleService.getSlug(key);\n\n if (!slug) {\n return undefined;\n }\n\n return fillStyleResolver({ slug });\n }\n\n function processDimension(\n key: string | undefined,\n value: number | undefined,\n scope: \"WIDTH_HEIGHT\" | \"GAP\" | \"CORNER_RADIUS\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.dimension(value);\n }\n\n return undefined;\n }\n\n function processFontDimension(\n key: string | undefined,\n value: number | undefined,\n scope: \"FONT_SIZE\" | \"LINE_HEIGHT\",\n ) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n return inferVariableName(value, scope) ?? rawValueFormatters.fontDimension(value);\n }\n\n return undefined;\n }\n\n function processFontWeight(key: string | undefined, value: number | undefined) {\n if (key) {\n return getVariableName(key);\n }\n\n if (value !== undefined) {\n const fontWeightToString: Record<number, string> = {\n 100: \"thin\",\n 200: \"extra-light\",\n 300: \"light\",\n 400: \"regular\",\n 500: \"medium\",\n 600: \"semi-bold\",\n 700: \"bold\",\n 800: \"extra-bold\",\n 900: \"black\",\n };\n\n return (\n inferVariableName(value, \"FONT_WEIGHT\") ??\n inferVariableName(fontWeightToString[value], \"FONT_STYLE\") ??\n rawValueFormatters.fontWeight(value)\n );\n }\n\n return undefined;\n }\n\n const getFormattedValue: ValueResolver<\n TColor,\n TGradient,\n TDimension,\n TFontDimension,\n TFontWeight\n >[\"getFormattedValue\"] = {\n width: (node) =>\n processDimension(\n node.boundVariables?.size?.x?.id,\n node.absoluteBoundingBox?.width,\n \"WIDTH_HEIGHT\",\n ),\n height: (node) =>\n processDimension(\n node.boundVariables?.size?.y?.id,\n node.absoluteBoundingBox?.height,\n \"WIDTH_HEIGHT\",\n ),\n minWidth: (node) =>\n processDimension(node.boundVariables?.minWidth?.id, node.minWidth, \"WIDTH_HEIGHT\"),\n minHeight: (node) =>\n processDimension(node.boundVariables?.minHeight?.id, node.minHeight, \"WIDTH_HEIGHT\"),\n maxWidth: (node) =>\n processDimension(node.boundVariables?.maxWidth?.id, node.maxWidth, \"WIDTH_HEIGHT\"),\n maxHeight: (node) =>\n processDimension(node.boundVariables?.maxHeight?.id, node.maxHeight, \"WIDTH_HEIGHT\"),\n paddingLeft: (node) =>\n processDimension(node.boundVariables?.paddingLeft?.id, node.paddingLeft, \"GAP\"),\n paddingRight: (node) =>\n processDimension(node.boundVariables?.paddingRight?.id, node.paddingRight, \"GAP\"),\n paddingTop: (node) =>\n processDimension(node.boundVariables?.paddingTop?.id, node.paddingTop, \"GAP\"),\n paddingBottom: (node) =>\n processDimension(node.boundVariables?.paddingBottom?.id, node.paddingBottom, \"GAP\"),\n itemSpacing: (node) =>\n processDimension(node.boundVariables?.itemSpacing?.id, node.itemSpacing, \"GAP\"),\n frameFill: (node) =>\n node.fillStyleKey\n ? processFillStyle(node.fillStyleKey)\n : processColor(\n getFirstFillVariable(node)?.id,\n getFirstSolidFill(node)?.color,\n \"FRAME_FILL\",\n ),\n shapeFill: (node) =>\n processColor(getFirstFillVariable(node)?.id, getFirstSolidFill(node)?.color, \"SHAPE_FILL\"),\n textFill: (node) =>\n processColor(getFirstFillVariable(node)?.id, getFirstSolidFill(node)?.color, \"TEXT_FILL\"),\n stroke: (node) =>\n processColor(getFirstStrokeVariable(node)?.id, getFirstStroke(node)?.color, \"STROKE_COLOR\"),\n topLeftRadius: (node) =>\n processDimension(\n node.boundVariables?.topLeftRadius?.id,\n node.rectangleCornerRadii?.[0] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n topRightRadius: (node) =>\n processDimension(\n node.boundVariables?.topRightRadius?.id,\n node.rectangleCornerRadii?.[1] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n bottomLeftRadius: (node) =>\n processDimension(\n node.boundVariables?.bottomLeftRadius?.id,\n node.rectangleCornerRadii?.[2] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n bottomRightRadius: (node) =>\n processDimension(\n node.boundVariables?.bottomRightRadius?.id,\n node.rectangleCornerRadii?.[3] ?? node.cornerRadius,\n \"CORNER_RADIUS\",\n ),\n fontSize: (node) =>\n processFontDimension(\n node.boundVariables?.fontSize?.[0]?.id,\n node.style.fontSize,\n \"FONT_SIZE\",\n ),\n fontWeight: (node) =>\n processFontWeight(node.boundVariables?.fontWeight?.[0]?.id, node.style.fontWeight),\n lineHeight: (node) =>\n processFontDimension(\n node.boundVariables?.lineHeight?.[0]?.id,\n node.style.lineHeightPx,\n \"LINE_HEIGHT\",\n ),\n };\n\n function getTextStyleValue(node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait) {\n if (!node.textStyleKey) return undefined;\n\n const slug = styleService.getSlug(node.textStyleKey);\n\n if (!slug) {\n return undefined;\n }\n\n return textStyleNameFormatter({ slug });\n }\n\n return {\n getFormattedValue,\n getTextStyleValue,\n };\n}\n","import type {\n NormalizedHasChildrenTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n} from \"@/normalizer\";\n\ninterface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface LayoutProperties {\n layoutMode?: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\";\n primaryAxisSizingMode?: \"FIXED\" | \"AUTO\";\n counterAxisSizingMode?: \"FIXED\" | \"AUTO\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\"; // 'BASELINE' requires more info\n paddingLeft?: number;\n paddingRight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n itemSpacing?: number;\n}\n\ninterface InferResult {\n properties: LayoutProperties;\n childProperties: {\n [childId: string]: {\n layoutAlign?: \"MIN\" | \"STRETCH\";\n };\n };\n}\n\ntype LayoutNode = NormalizedIsLayerTrait &\n NormalizedHasFramePropertiesTrait &\n NormalizedHasChildrenTrait &\n NormalizedHasLayoutTrait;\n\n// --- Helper Functions ---\n\nfunction getCollectiveBoundingBox(nodes: LayoutNode[]): BoundingBox | null {\n if (nodes.length === 0) {\n return null;\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n nodes.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n minX = Math.min(minX, box.x);\n minY = Math.min(minY, box.y);\n maxX = Math.max(maxX, box.x + box.width);\n maxY = Math.max(maxY, box.y + box.height);\n });\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\nfunction calculateMean(arr: number[]): number {\n if (arr.length === 0) return 0;\n return arr.reduce((sum, val) => sum + val, 0) / arr.length;\n}\n\nfunction calculateVariance(arr: number[]): number {\n if (arr.length < 2) return 0;\n const mean = calculateMean(arr);\n return arr.reduce((sum, val) => sum + (val - mean) ** 2, 0) / arr.length;\n}\n\nfunction calculateMedian(arr: number[]): number {\n if (arr.length === 0) return 0;\n const sortedArr = [...arr].sort((a, b) => a - b);\n const mid = Math.floor(sortedArr.length / 2);\n if (sortedArr.length % 2 === 0) {\n return (sortedArr[mid - 1] + sortedArr[mid]) / 2;\n }\n return sortedArr[mid];\n}\n\n// Tolerance for floating point comparisons and alignment checks\nconst EPSILON = 1; // 1 pixel tolerance\n\n// --- Main Inference Function ---\n\nexport function inferLayout(parentNode: LayoutNode): InferResult {\n if (parentNode.layoutMode !== \"NONE\") {\n return {\n properties: {},\n childProperties: {},\n };\n }\n\n const children = (parentNode.children || []) as LayoutNode[];\n const parentBox = parentNode.absoluteBoundingBox!;\n const result: LayoutProperties = { layoutMode: \"NONE\" };\n\n if (children.length === 0) {\n return {\n properties: result,\n childProperties: {},\n }; // Cannot infer layout for no children\n }\n\n if (children.length === 1) {\n // Default for single child: Horizontal, Hug contents, No spacing, Calculate padding\n result.layoutMode = \"HORIZONTAL\";\n result.primaryAxisSizingMode = \"AUTO\";\n result.counterAxisSizingMode = \"AUTO\";\n result.itemSpacing = 0;\n result.primaryAxisAlignItems = \"MIN\"; // Doesn't matter for one item\n result.counterAxisAlignItems = \"MIN\"; // Doesn't matter for one item\n\n const childBox = children[0].absoluteBoundingBox!;\n result.paddingLeft = Math.max(0, childBox.x - parentBox.x);\n result.paddingRight = Math.max(\n 0,\n parentBox.x + parentBox.width - (childBox.x + childBox.width),\n );\n result.paddingTop = Math.max(0, childBox.y - parentBox.y);\n result.paddingBottom = Math.max(\n 0,\n parentBox.y + parentBox.height - (childBox.y + childBox.height),\n );\n return {\n properties: result,\n childProperties: {},\n };\n }\n\n // --- 1. Determine Layout Direction ---\n const sortedByX = [...children].sort(\n (a, b) => a.absoluteBoundingBox!.x - b.absoluteBoundingBox!.x,\n );\n const sortedByY = [...children].sort(\n (a, b) => a.absoluteBoundingBox!.y - b.absoluteBoundingBox!.y,\n );\n\n const horizontalGaps: number[] = [];\n for (let i = 0; i < sortedByX.length - 1; i++) {\n const current = sortedByX[i].absoluteBoundingBox!;\n const next = sortedByX[i + 1].absoluteBoundingBox!;\n // Ensure items don't significantly overlap vertically for horizontal check\n if (Math.max(current.y, next.y) < Math.min(current.y + current.height, next.y + next.height)) {\n horizontalGaps.push(next.x - (current.x + current.width));\n }\n }\n\n const verticalGaps: number[] = [];\n for (let i = 0; i < sortedByY.length - 1; i++) {\n const current = sortedByY[i].absoluteBoundingBox!;\n const next = sortedByY[i + 1].absoluteBoundingBox!;\n // Ensure items don't significantly overlap horizontally for vertical check\n if (Math.max(current.x, next.x) < Math.min(current.x + current.width, next.x + next.width)) {\n verticalGaps.push(next.y - (current.y + current.height));\n }\n }\n\n // Heuristic: Prefer axis with more non-negative gaps and lower variance\n const hVariance = calculateVariance(horizontalGaps.filter((g) => g >= -EPSILON));\n const vVariance = calculateVariance(verticalGaps.filter((g) => g >= -EPSILON));\n const hCount = horizontalGaps.filter((g) => g >= -EPSILON).length;\n const vCount = verticalGaps.filter((g) => g >= -EPSILON).length;\n\n let primaryAxisSortedNodes = sortedByX; // Default guess\n\n // Basic variance check (lower is better). Add slight bias for horizontal if equal.\n if (\n vCount > 0 &&\n (hCount === 0 ||\n (vVariance < hVariance - EPSILON && vCount >= hCount) ||\n (vVariance <= hVariance && vCount > hCount))\n ) {\n result.layoutMode = \"VERTICAL\";\n primaryAxisSortedNodes = sortedByY;\n } else if (hCount > 0) {\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n } else {\n // Ambiguous case based on gaps, fall back to bounding box aspect ratio\n const collectiveBox = getCollectiveBoundingBox(children);\n if (collectiveBox) {\n if (collectiveBox.height > collectiveBox.width) {\n result.layoutMode = \"VERTICAL\";\n primaryAxisSortedNodes = sortedByY;\n } else {\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n }\n } else {\n // Still nothing? Default to Horizontal\n result.layoutMode = \"HORIZONTAL\";\n primaryAxisSortedNodes = sortedByX;\n }\n }\n\n const primaryGaps = result.layoutMode === \"HORIZONTAL\" ? horizontalGaps : verticalGaps;\n const validGaps = primaryGaps.filter((g) => g >= -EPSILON); // Allow slight overlap\n\n // --- 2. Calculate Spacing & Primary Alignment ---\n let isSpaceBetween = false;\n const collectiveBox = getCollectiveBoundingBox(children);\n\n if (collectiveBox && children.length >= 2) {\n // Check for Space Between potential\n const first = primaryAxisSortedNodes[0].absoluteBoundingBox!;\n const last = primaryAxisSortedNodes[primaryAxisSortedNodes.length - 1].absoluteBoundingBox!;\n let firstStart: number;\n let lastEnd: number;\n let parentSize: number;\n\n if (result.layoutMode === \"HORIZONTAL\") {\n firstStart = first.x;\n lastEnd = last.x + last.width;\n parentSize = parentBox.width;\n } else {\n firstStart = first.y;\n lastEnd = last.y + last.height;\n parentSize = parentBox.height;\n }\n\n const contentSpan = lastEnd - firstStart;\n\n // Heuristic for Space Between: Content spans most of the parent & average gap is large\n const averageGap = calculateMean(validGaps);\n // Example threshold: Content fills > 85% AND average gap is > 20% of average item size? Or just large?\n if (contentSpan > parentSize * 0.8 && validGaps.length > 0 && averageGap > 10) {\n // Additional check: are first/last items close to parent edges (considering padding)?\n const startPadding =\n result.layoutMode === \"HORIZONTAL\" ? first.x - parentBox.x : first.y - parentBox.y;\n const endPadding =\n result.layoutMode === \"HORIZONTAL\"\n ? parentBox.x + parentBox.width - (last.x + last.width)\n : parentBox.y + parentBox.height - (last.y + last.height);\n\n // If start/end items are reasonably close to edges (e.g., < 2 * average gap?)\n if (\n Math.abs(startPadding) < Math.max(20, averageGap * 1.5) &&\n Math.abs(endPadding) < Math.max(20, averageGap * 1.5)\n ) {\n isSpaceBetween = true;\n }\n }\n }\n\n if (isSpaceBetween) {\n result.primaryAxisAlignItems = \"SPACE_BETWEEN\";\n result.itemSpacing = 0; // Spacing is implicit\n result.primaryAxisSizingMode = \"FIXED\"; // Usually fixed when using space between\n } else {\n result.primaryAxisAlignItems = \"MIN\"; // Default to MIN for packed, could refine later\n if (validGaps.length > 0) {\n // Use median spacing for robustness against outliers\n result.itemSpacing = calculateMedian(validGaps);\n // Clamp negative spacing if it's very small (likely float error)\n if (result.itemSpacing < 0 && result.itemSpacing > -EPSILON) {\n result.itemSpacing = 0;\n }\n } else {\n result.itemSpacing = 0; // No valid gaps found\n }\n result.primaryAxisSizingMode = \"AUTO\"; // Default to hug content for packed\n }\n\n // --- 3. Calculate Padding ---\n if (collectiveBox) {\n result.paddingLeft = Math.max(0, collectiveBox.x - parentBox.x);\n result.paddingRight = Math.max(\n 0,\n parentBox.x + parentBox.width - (collectiveBox.x + collectiveBox.width),\n );\n result.paddingTop = Math.max(0, collectiveBox.y - parentBox.y);\n result.paddingBottom = Math.max(\n 0,\n parentBox.y + parentBox.height - (collectiveBox.y + collectiveBox.height),\n );\n } else {\n result.paddingLeft = 0;\n result.paddingRight = 0;\n result.paddingTop = 0;\n result.paddingBottom = 0;\n }\n\n // --- 4. Determine Counter Axis Alignment ---\n const counterCoordsMin: number[] = [];\n const counterCoordsCenter: number[] = [];\n const counterCoordsMax: number[] = [];\n\n if (result.layoutMode === \"HORIZONTAL\") {\n // Check vertical alignment (Y)\n children.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n counterCoordsMin.push(box.y);\n counterCoordsCenter.push(box.y + box.height / 2);\n counterCoordsMax.push(box.y + box.height);\n });\n } else {\n // VERTICAL layout\n // Check horizontal alignment (X)\n children.forEach((node) => {\n const box = node.absoluteBoundingBox!;\n counterCoordsMin.push(box.x);\n counterCoordsCenter.push(box.x + box.width / 2);\n counterCoordsMax.push(box.x + box.width);\n });\n }\n\n const minVariance = calculateVariance(counterCoordsMin);\n const centerVariance = calculateVariance(counterCoordsCenter);\n const maxVariance = calculateVariance(counterCoordsMax);\n\n const alignmentTolerance = EPSILON * EPSILON * 4; // Allow slightly more variance for alignment match\n if (\n minVariance <= centerVariance &&\n minVariance <= maxVariance &&\n minVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"MIN\";\n } else if (\n centerVariance <= minVariance &&\n centerVariance <= maxVariance &&\n centerVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"CENTER\";\n } else if (\n maxVariance <= minVariance &&\n maxVariance <= centerVariance &&\n maxVariance < alignmentTolerance\n ) {\n result.counterAxisAlignItems = \"MAX\";\n } else {\n // Default if variances are high or similar\n result.counterAxisAlignItems = \"CENTER\";\n }\n\n // --- 5. Determine Counter Axis Sizing Mode ---\n // Default to AUTO unless children perfectly fill the parent counter dimension\n result.counterAxisSizingMode = \"AUTO\";\n if (collectiveBox) {\n let collectiveCounterSize: number;\n let parentCounterSize: number;\n if (result.layoutMode === \"HORIZONTAL\") {\n collectiveCounterSize = collectiveBox.height;\n parentCounterSize = parentBox.height - (result.paddingTop ?? 0) - (result.paddingBottom ?? 0);\n } else {\n collectiveCounterSize = collectiveBox.width;\n parentCounterSize = parentBox.width - (result.paddingLeft ?? 0) - (result.paddingRight ?? 0);\n }\n // If collective size is very close to parent size on counter axis\n if (Math.abs(collectiveCounterSize - parentCounterSize) < EPSILON) {\n result.counterAxisSizingMode = \"FIXED\";\n }\n }\n\n // 6. Infer layoutAlign for each child\n const childProperties: InferResult[\"childProperties\"] = {};\n const availableWidth = parentBox.width - (result.paddingLeft ?? 0) - (result.paddingRight ?? 0);\n const availableHeight = parentBox.height - (result.paddingTop ?? 0) - (result.paddingBottom ?? 0);\n\n children.forEach((child) => {\n const childBox = child.absoluteBoundingBox!;\n let inferredChildAlign: \"INHERIT\" | \"STRETCH\" | undefined = undefined;\n\n // Check STRETCH\n if (result.layoutMode === \"HORIZONTAL\") {\n // Counter: Vertical\n if (Math.abs(childBox.height - availableHeight) < EPSILON && availableHeight > 0) {\n inferredChildAlign = \"STRETCH\";\n }\n } else {\n // Counter: Horizontal\n if (Math.abs(childBox.width - availableWidth) < EPSILON && availableWidth > 0) {\n inferredChildAlign = \"STRETCH\";\n }\n }\n\n if (inferredChildAlign) {\n childProperties[child.id] = { layoutAlign: inferredChildAlign };\n }\n });\n\n return {\n properties: result,\n childProperties,\n };\n}\n\nexport function applyInferredLayout<T extends LayoutNode>(parentNode: T, result: InferResult): T {\n const { properties, childProperties } = result;\n\n if (properties.layoutMode === \"NONE\") {\n return parentNode;\n }\n\n return {\n ...parentNode,\n ...properties,\n children: parentNode.children.map((child) => {\n const props = childProperties[child.id];\n if (props) {\n return { ...child, ...props };\n }\n return child;\n }),\n };\n}\n","export declare const metadata: {\n \"name\": \"🔵 [Template] Error State\",\n \"key\": \"39b4ecd0b5b4d35f4dc5791765ca04aa062a5172\",\n \"componentPropertyDefinitions\": {\n \"Show Buttons#9080:5\": {\n \"type\": \"BOOLEAN\"\n },\n \"Title#16237:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#16237:5\": {\n \"type\": \"TEXT\"\n },\n \"Secondary Action Label#17042:0\": {\n \"type\": \"TEXT\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Default\",\n \"Basement\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"With Title\",\n \"Description Only\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🔵 [Template] Select Box Group\",\n \"key\": \"a3d58bb8540600878742cdcf2608a4b3851667ec\",\n \"componentPropertyDefinitions\": {\n \"Control\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Checkbox\",\n \"Radio\"\n ]\n },\n \"Item Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"5\",\n \"6\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Action Button\",\n \"key\": \"450ede9d0bf42fc6ef14345c77e6e407d6d5ee89\",\n \"componentPropertyDefinitions\": {\n \"Label#5987:61\": {\n \"type\": \"TEXT\"\n },\n \"Suffix Icon#5987:244\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Prefix Icon#5987:305\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Icon#7574:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"XSmall\",\n \"Small\",\n \"Medium\",\n \"Large\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Text Only\",\n \"Icon First\",\n \"Icon Last\",\n \"Icon Only\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Solid\",\n \"Neutral Weak\",\n \"Neutral Outline\",\n \"Brand Solid\",\n \"Brand Outline\",\n \"Critical Solid\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Alert Dialog\",\n \"key\": \"e0c89524a554ca1bf95c016b7255f29e257624aa\",\n \"componentPropertyDefinitions\": {\n \"Title Text#20361:0\": {\n \"type\": \"TEXT\"\n },\n \"Description Text#20361:7\": {\n \"type\": \"TEXT\"\n },\n \"Show Title#20361:14\": {\n \"type\": \"BOOLEAN\"\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Single\",\n \"Neutral\",\n \"Neutral (Overflow)\",\n \"Critical\",\n \"Critical (Overflow)\",\n \"Nonpreferred\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Avatar\",\n \"key\": \"4a8853c3068c08b69b13e71dd42ce186e968697e\",\n \"componentPropertyDefinitions\": {\n \"Has Image Contents#33407:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"20\",\n \"24\",\n \"36\",\n \"42\",\n \"48\",\n \"64\",\n \"80\",\n \"96\",\n \"108\"\n ]\n },\n \"Badge\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Circle\",\n \"Shield\",\n \"Flower\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Avatar Stack\",\n \"key\": \"e8e91e01000d878742c55cd6e44b6786460440f7\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"20\",\n \"24\",\n \"36\",\n \"42\",\n \"48\",\n \"64\",\n \"80\",\n \"96\",\n \"108\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Badge\",\n \"key\": \"04609a35d47a1a0ef4904b3c25f79451892a85a1\",\n \"componentPropertyDefinitions\": {\n \"Label#1584:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Brand\",\n \"Informative\",\n \"Positive\",\n \"Critical\",\n \"Warning\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Weak\",\n \"Outline\",\n \"Solid\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Bottom Sheet\",\n \"key\": \"16bafa5d1155896fe18fb6f52f904f5cd2048686\",\n \"componentPropertyDefinitions\": {\n \"Title#19787:3\": {\n \"type\": \"TEXT\"\n },\n \"Description#19787:7\": {\n \"type\": \"TEXT\"\n },\n \"Show Close Button#19787:11\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Footer#25162:14\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#25192:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Contents#25320:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"ec1901cb37dc88360ae8fd2b61f71e630fda7924\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5c5369d9c22115fd240d7b75ac2a334e9163ea57\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"8670afb7520ac44dfed003e3e9c7cce359897d0c\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"e3d337e6eddbe9ec025fe69520c1cff0bd697b60\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0c6c58d5b7a159e7db1a0c1ccf32916ca8a51164\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"088624580ee501efed377bb4f42561a387db5699\"\n }\n ]\n },\n \"Show Safe Area#25488:8\": {\n \"type\": \"BOOLEAN\"\n },\n \"Header Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Bottom Left\",\n \"None\",\n \"Bottom Center\",\n \"Top Center\",\n \"Top Left\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Callout\",\n \"key\": \"ec46d38baac3c367c4a5ffa47a2110d51ba0a4fe\",\n \"componentPropertyDefinitions\": {\n \"Prefix Icon#35087:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#35087:1\": {\n \"type\": \"BOOLEAN\"\n },\n \"Pressed#35087:2\": {\n \"type\": \"BOOLEAN\"\n },\n \"Interaction\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Display\",\n \"Actionable\",\n \"Dismissible\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Informative\",\n \"Warning\",\n \"Critical\",\n \"Magic\"\n ]\n },\n \"Show Title\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n },\n \"Show Link Text\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Checkbox\",\n \"key\": \"94a2f6957a86f8ae3b8c7ca200dfcd5e29f6075b\",\n \"componentPropertyDefinitions\": {\n \"Label#49990:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Shape\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Square\",\n \"Ghost\"\n ]\n },\n \"Weight\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Bold\",\n \"Regular\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\",\n \"Indeterminate\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Checkmark\",\n \"key\": \"fae60fb392f55bde60de1dbccb2f453320068805\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Shape\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Square\",\n \"Ghost\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\",\n \"Indeterminate\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Chip\",\n \"key\": \"8156ef08d9aaa2b0de1cc4a113ec0c9d0586f831\",\n \"componentPropertyDefinitions\": {\n \"Label#7185:0\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Icon#8722:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"8ed05ef62a40f2dc034ee7eb6945bd0e63ad49aa\"\n }\n ]\n },\n \"Suffix Type#32538:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"27343e0e5ab2c66948e9b10fde03d58b5e037212\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5f0d74c959c49dadf5920b19c6267924982ab130\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"a1233c35c4368aba2439d39bc8aedc37cf95bd86\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"43b6e51bc372e108a4ee17fbf4c75800d95f4b8c\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"df43b92004c850e7c6d2869e7a4ba1ef9a2d7db6\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"19923052d4152393ecdc6e2f5853ea0359849127\"\n }\n ]\n },\n \"Has Suffix#32538:181\": {\n \"type\": \"BOOLEAN\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Solid\",\n \"Outline Strong\",\n \"Outline Weak\"\n ]\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Large\",\n \"Medium\",\n \"Small\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n },\n \"Prefix Type\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Icon\",\n \"Avatar\",\n \"Image\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Contextual Floating Button\",\n \"key\": \"032f3fddaad0aa3fa5a7f680768c1f5d02fb463f\",\n \"componentPropertyDefinitions\": {\n \"Icon#28796:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Label#28936:0\": {\n \"type\": \"TEXT\"\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Icon First\",\n \"Icon Only\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Solid\",\n \"Layer\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Divider\",\n \"key\": \"848e953725f757ea1a79e1fecc0b608a035032d3\",\n \"componentPropertyDefinitions\": {\n \"Inset (Figma-Only)#36435:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Muted\",\n \"Neutral Subtle\"\n ]\n },\n \"Orientation\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Vertical\",\n \"Horizontal\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Floating Action Button\",\n \"key\": \"65f9e7eede627b893fb8ff94ed9a7d0db900c464\",\n \"componentPropertyDefinitions\": {\n \"Type\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Button\",\n \"Menu\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Help Bubble\",\n \"key\": \"804b327c091278a40d5891939eaed90bb2889659\",\n \"componentPropertyDefinitions\": {\n \"Show Close Button#40538:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#62499:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Title#62535:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#62535:98\": {\n \"type\": \"TEXT\"\n },\n \"Placement\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Right-Top\",\n \"Right-Center\",\n \"Right-Bottom\",\n \"Left-Top\",\n \"Left-Center\",\n \"Left-Bottom\",\n \"Bottom-Left\",\n \"Bottom-Center\",\n \"Bottom-Right\",\n \"Top-Left\",\n \"Top-Center\",\n \"Top-Right\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 List Header\",\n \"key\": \"609f93ed0608ef0a6d9a351e47595ad631bae0fa\",\n \"componentPropertyDefinitions\": {\n \"Title#28588:0\": {\n \"type\": \"TEXT\"\n },\n \"Suffix\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"None\",\n \"Button\",\n \"Custom\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium Weak\",\n \"Bold Solid\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 List Item\",\n \"key\": \"b51b7d07c659fee5d696565b8e1151636573b27c\",\n \"componentPropertyDefinitions\": {\n \"Divider#28441:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Type#28441:42\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"8c52207687ffed15cd5931d71ed9d196b3358a68\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"fe0e25f4fecda59d0a3730ead7c5bc0a66a41e7e\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"abf9810103ae6e6afe8fa253ec5f05d6a7304b38\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0a9464ad270bfd7f56438f62bb0155a25ca146a9\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"4cc7e9b84a8388a36cb3898c6c02e6110a3281b9\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"1e933f75dd6bb4b21c3289b5c3b4402d2c623125\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"11ba71b11b336199654cd2801967a44996705449\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"c0eaee6146c6dc92bfd9b081d667f45ee611b1d2\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"3d788f28c785d1c60b937b253c39ce582dbe1ed3\"\n },\n {\n \"type\": \"COMPONENT_SET\",\n \"key\": \"5636566f6de6f58200dce388f7b1ac9f517b30e1\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"3a70bf5bb9856c13893931b7a0df652bcf0be895\"\n }\n ]\n },\n \"Title#28452:21\": {\n \"type\": \"TEXT\"\n },\n \"Has Suffix#28452:64\": {\n \"type\": \"BOOLEAN\"\n },\n \"Has Prefix#28452:85\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Type#28452:106\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"0e4c05f097d3fa2dc0cbfdbf8db2662bcf8439ca\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"ef0e8bd6c2f92e620acf204bb9a8079ef25a1e5c\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"82239325aa1cb65af7c649fc71a8f2b48fb9b9f3\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"f24c9ef42ef08df79483fbae0fa7d9037e566748\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"5a77ad37a2291989dfe77c44ddee9aa39e447f90\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"81f201fc876e38f016ab7427a6b3da000ee919a2\"\n }\n ]\n },\n \"Has Detail#28469:1\": {\n \"type\": \"BOOLEAN\"\n },\n \"Detail Type#28469:11\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"b27f70404d8f055ec39f9049a5a86920c11be979\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"43795c2e3e507dc555f9ec08bf4bf1abf8c2051a\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"73bcdff1b73998d1f440fb8827df2eafc4338c1d\"\n }\n ]\n },\n \"Title #28487:0\": {\n \"type\": \"TEXT\"\n },\n \"Detail Type #28487:11\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": [\n {\n \"type\": \"COMPONENT\",\n \"key\": \"870d50d39feae5bcfd59d7fbf8ae510233a97a8b\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"43795c2e3e507dc555f9ec08bf4bf1abf8c2051a\"\n },\n {\n \"type\": \"COMPONENT\",\n \"key\": \"73bcdff1b73998d1f440fb8827df2eafc4338c1d\"\n }\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\",\n \"Highlighted\"\n ]\n },\n \"Variants\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Single Line\",\n \"Multi Line\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Manner Temp\",\n \"key\": \"37c0a35f73a730fdfba7929cea91a7590fc93733\",\n \"componentPropertyDefinitions\": {\n \"Level\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"L1\",\n \"L2\",\n \"L3\",\n \"L4\",\n \"L5\",\n \"L6\",\n \"L7\",\n \"L8\",\n \"L9\",\n \"L10\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Manner Temp Badge\",\n \"key\": \"3ef9a84d4d80046ff9a581136bd56269554a6e00\",\n \"componentPropertyDefinitions\": {\n \"Level\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"L1\",\n \"L2\",\n \"L3\",\n \"L4\",\n \"L5\",\n \"L6\",\n \"L7\",\n \"L8\",\n \"L9\",\n \"L10\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Menu Sheet\",\n \"key\": \"cd4cf8a850bf3de87b79080b36b421a649bf3fcb\",\n \"componentPropertyDefinitions\": {\n \"Title Text#14599:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Header#17043:12\": {\n \"type\": \"BOOLEAN\"\n },\n \"Description Text#21827:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Safe Area#25531:15\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#32984:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Menu Group Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"2\",\n \"3\",\n \"1\"\n ]\n },\n \"Layout\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Text Only\",\n \"Text with Icon\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Multiline Text Field\",\n \"key\": \"88b2399c930c85f9ce2972163a078bc684b84bbe\",\n \"componentPropertyDefinitions\": {\n \"Show Header#870:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Placeholder#958:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Footer#958:25\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#958:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Character count#958:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Indicator#1259:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Filled Text#1304:0\": {\n \"type\": \"TEXT\"\n },\n \"Max Character Count#15327:175\": {\n \"type\": \"TEXT\"\n },\n \"Description#15327:212\": {\n \"type\": \"TEXT\"\n },\n \"Indicator#15327:286\": {\n \"type\": \"TEXT\"\n },\n \"Label#15327:323\": {\n \"type\": \"TEXT\"\n },\n \"Character Count#15327:360\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\",\n \"XLarge\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Focused\",\n \"Invalid\",\n \"Invalid-Focused\",\n \"Disabled\",\n \"Read Only\"\n ]\n },\n \"Filled\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Page Banner\",\n \"key\": \"ce587d0f21754af05240cb32a4880227cb0ea1e1\",\n \"componentPropertyDefinitions\": {\n \"Show Prefix Icon#11840:27\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Icon#35433:45\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Pressed#36736:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Interaction\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Display\",\n \"Actionable\",\n \"Dismissible\",\n \"With Action\",\n \"Custom\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Informative\",\n \"Positive\",\n \"Warning\",\n \"Critical\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Weak\",\n \"Solid\"\n ]\n },\n \"Show Title\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"False\",\n \"True\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Progress Circle\",\n \"key\": \"6e6779a372cab2485a0e25529bc4dbc9932a7346\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"24\",\n \"40\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"Brand\",\n \"Static White\",\n \"Custom(inherit)\"\n ]\n },\n \"Value\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Indeterminate\",\n \"0%\",\n \"25%\",\n \"75%\",\n \"100%\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Radio\",\n \"key\": \"ac72d9e5ab04a1d59eaf77dffd380fd6e491ecf8\",\n \"componentPropertyDefinitions\": {\n \"Label#49990:171\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"🚫[Deprecated]Brand\",\n \"Neutral\"\n ]\n },\n \"Weight\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Regular\",\n \"Bold\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Radio Mark\",\n \"key\": \"832d696d6e9566610968cd70f128f500ec009d6a\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"🚫[Deprecated]Brand\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Reaction Button\",\n \"key\": \"ec43e4e881f7048e95601f8b58c01a0905a174e0\",\n \"componentPropertyDefinitions\": {\n \"Label#6397:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Count#6397:33\": {\n \"type\": \"BOOLEAN\"\n },\n \"Icon#12379:0\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Count#15816:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"XSmall\",\n \"Small\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Segmented Control\",\n \"key\": \"3ad7133ba52755867f42f9232375f75639e00d58\",\n \"componentPropertyDefinitions\": {\n \"Item Count\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"2\",\n \"3\",\n \"4\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Select Box\",\n \"key\": \"38722ffeb4c966256a709155e8ddac50c93d7c60\",\n \"componentPropertyDefinitions\": {\n \"Show Description#3033:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Description #3033:5\": {\n \"type\": \"TEXT\"\n },\n \"Label#3635:0\": {\n \"type\": \"TEXT\"\n },\n \"Control\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Checkbox\",\n \"Radio\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Skeleton\",\n \"key\": \"ef22c3288722fbfa64a5ab73df397ade88f8e05a\",\n \"componentPropertyDefinitions\": {\n \"Radius\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"0\",\n \"8\",\n \"16\",\n \"Full\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Magic\",\n \"Neutral\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Snackbar\",\n \"key\": \"81b17fb8c7d731a19cf8d36a8605559d41414eca\",\n \"componentPropertyDefinitions\": {\n \"Show Action#1528:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Message#1528:4\": {\n \"type\": \"TEXT\"\n },\n \"Action Label#1528:8\": {\n \"type\": \"TEXT\"\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Default\",\n \"Positive\",\n \"Critical\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Switch\",\n \"key\": \"65e0e7ba1a0c13b42e5fd0ceb17d5f756128dd6b\",\n \"componentPropertyDefinitions\": {\n \"Label#36578:0\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"16\",\n \"24\",\n \"32\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"🚫[Deprecated] Brand\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Disabled\"\n ]\n },\n \"Layout(Figma Only)\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Label Last\",\n \"Label First\",\n \"🚫[Switch Mark 사용] Switch Only\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Switch Mark\",\n \"key\": \"bc53f269089e02a1d241e2a21ac7631bfa49834e\",\n \"componentPropertyDefinitions\": {\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"16\",\n \"24\",\n \"32\"\n ]\n },\n \"Tone\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral\",\n \"🚫[Deprecated] Brand\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Tabs\",\n \"key\": \"3e3af9f7f235cbcbbe862d5da552ab23e16ff34e\",\n \"componentPropertyDefinitions\": {\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Line\",\n \"Chip\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Text Field\",\n \"key\": \"c49873c37a639f0dffdea4efd0eb43760d66c141\",\n \"componentPropertyDefinitions\": {\n \"Show Header#870:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Placeholder#958:0\": {\n \"type\": \"TEXT\"\n },\n \"Show Footer#958:25\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Description#958:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Character Count#958:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Suffix#958:100\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Prefix#958:125\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Indicator#1259:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Prefix Text#1267:0\": {\n \"type\": \"BOOLEAN\"\n },\n \"Prefix Icon#1267:25\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#1267:50\": {\n \"type\": \"BOOLEAN\"\n },\n \"Show Suffix Icon#1267:75\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Icon #1267:100\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Suffix Text#1267:125\": {\n \"type\": \"BOOLEAN\"\n },\n \"Filled Text#1304:0\": {\n \"type\": \"TEXT\"\n },\n \"Description#12626:5\": {\n \"type\": \"TEXT\"\n },\n \"Label#14964:0\": {\n \"type\": \"TEXT\"\n },\n \"Max Character Count#15327:27\": {\n \"type\": \"TEXT\"\n },\n \"Character Count#15327:64\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Text#15327:101\": {\n \"type\": \"TEXT\"\n },\n \"Suffix Text#15327:138\": {\n \"type\": \"TEXT\"\n },\n \"Indicator#15327:249\": {\n \"type\": \"TEXT\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Medium\",\n \"Large(Default)\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Focused\",\n \"Invalid\",\n \"Invalid-Focused\",\n \"Disabled\",\n \"Read Only\"\n ]\n },\n \"Filled\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Toggle Button\",\n \"key\": \"1d240ee5fd7a56879713e69cbea1b6f006f0ea22\",\n \"componentPropertyDefinitions\": {\n \"Label#6122:49\": {\n \"type\": \"TEXT\"\n },\n \"Prefix Icon#6122:98\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Suffix Icon#6122:147\": {\n \"type\": \"BOOLEAN\"\n },\n \"Suffix Icon#6122:343\": {\n \"type\": \"INSTANCE_SWAP\",\n \"preferredValues\": []\n },\n \"Show Prefix Icon#6122:392\": {\n \"type\": \"BOOLEAN\"\n },\n \"Size\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Small\",\n \"XSmall\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Neutral Weak\",\n \"Brand Solid\"\n ]\n },\n \"Selected\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"True\",\n \"False\"\n ]\n },\n \"State\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Enabled\",\n \"Pressed\",\n \"Loading\",\n \"Disabled\"\n ]\n }\n }\n};\n","export declare const metadata: {\n \"name\": \"🟢 Top Navigation\",\n \"key\": \"f6d069d65f8ffc8b430fd8f3013910557f36e9da\",\n \"componentPropertyDefinitions\": {\n \"Show Title#33588:82\": {\n \"type\": \"BOOLEAN\"\n },\n \"OS (Figma Only)\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"iOS\",\n \"Android\"\n ]\n },\n \"Variant\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Layer Default\",\n \"Transparent\"\n ]\n },\n \"Left\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"Back\",\n \"Close\",\n \"Custom\",\n \"None\"\n ]\n },\n \"Right\": {\n \"type\": \"VARIANT\",\n \"variantOptions\": [\n \"1 Icon Button\",\n \"2 Icon Button\",\n \"3 Icon Button\",\n \"Text Button\",\n \"None\"\n ]\n }\n }\n};\n","import type { InferComponentDefinition } from \"@/codegen/core\";\nimport type * as metadata from \"@/entities/data/__generated__/component-sets\";\n\nexport type ActionButtonProperties = InferComponentDefinition<\n typeof metadata.actionButton.componentPropertyDefinitions\n>;\n\nexport type ActionButtonGhostProperties = InferComponentDefinition<{\n \"Label#30511:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Prefix Icon#30511:3\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24682\";\n preferredValues: [];\n };\n \"Suffix Icon#30525:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23545\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"c8415f85843e5aea5a1d3620d03d16b643bf86cd\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"0d0a2bc648a2c4e1f06a56a30ef16299b6e91037\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"8f28ae559baf8f388d84ccc3ad65a282966e1b05\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"57341e8a9961bf31590240dd288e57c76969098d\";\n },\n ];\n };\n \"Icon#30525:15\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102336\";\n preferredValues: [];\n };\n Bleed: {\n type: \"VARIANT\";\n defaultValue: \"true\";\n variantOptions: [\"true\", \"false\"];\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Xsmall\", \"Small\", \"Medium\", \"Large\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Icon First\";\n variantOptions: [\"Text Only\", \"Icon First\", \"Icon Last\", \"Icon Only\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Loading\", \"Disabled\"];\n };\n}>;\n\nexport type AlertDialogProperties = InferComponentDefinition<\n typeof metadata.alertDialog.componentPropertyDefinitions\n>;\n\nexport type AlertDialogFooterProperties = InferComponentDefinition<{\n Type: {\n type: \"VARIANT\";\n defaultValue: \"Single\";\n variantOptions: [\n \"Single\",\n \"Neutral\",\n \"Neutral (Overflow)\",\n \"Critical\",\n \"Critical (Overflow)\",\n \"Nonpreferred\",\n ];\n };\n}>;\n\nexport type AvatarProperties = InferComponentDefinition<\n typeof metadata.avatar.componentPropertyDefinitions\n>;\n\nexport type AvatarStackProperties = InferComponentDefinition<\n typeof metadata.avatarStack.componentPropertyDefinitions\n>;\n\nexport type BadgeProperties = InferComponentDefinition<\n typeof metadata.badge.componentPropertyDefinitions\n>;\n\nexport type BottomSheetProperties = InferComponentDefinition<\n typeof metadata.bottomSheet.componentPropertyDefinitions\n>;\n\nexport type CalloutProperties = InferComponentDefinition<\n typeof metadata.callout.componentPropertyDefinitions\n>;\n\nexport type CheckboxProperties = InferComponentDefinition<\n typeof metadata.checkbox.componentPropertyDefinitions\n>;\n\nexport type CheckmarkProperties = InferComponentDefinition<\n typeof metadata.checkmark.componentPropertyDefinitions\n>;\n\nexport type ChipProperties = InferComponentDefinition<\n typeof metadata.chip.componentPropertyDefinitions\n>;\n\nexport type ChipIconSuffixProperties = InferComponentDefinition<{\n \"Icon#33203:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23250\";\n preferredValues: [];\n };\n}>;\n\nexport type ContextualFloatingButtonProperties = InferComponentDefinition<\n typeof metadata.contextualFloatingButton.componentPropertyDefinitions\n>;\n\nexport type DividerProperties = InferComponentDefinition<\n typeof metadata.divider.componentPropertyDefinitions\n>;\n\nexport type ErrorStateProperties = InferComponentDefinition<\n typeof metadata.templateErrorState.componentPropertyDefinitions\n>;\n\nexport type MenuSheetProperties = InferComponentDefinition<\n typeof metadata.menuSheet.componentPropertyDefinitions\n>;\n\nexport type MenuSheetGroupProperties = InferComponentDefinition<{\n \"Action Count\": {\n type: \"VARIANT\";\n defaultValue: \"8\";\n variantOptions: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"];\n };\n}>;\n\nexport type MenuSheetItemProperties = InferComponentDefinition<{\n \"Show Prefix Icon#17043:5\": {\n type: \"BOOLEAN\";\n defaultValue: true;\n };\n \"Label#55905:8\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Prefix Icon#55948:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23245\";\n preferredValues: [];\n };\n Tone: {\n type: \"VARIANT\";\n defaultValue: \"Neutral\";\n variantOptions: [\"Neutral\", \"Critical\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Disabled\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Text Only\";\n variantOptions: [\"Text with Icon\", \"Text Only\"];\n };\n}>;\n\nexport type FloatingActionButtonProperties = InferComponentDefinition<\n typeof metadata.floatingActionButton.componentPropertyDefinitions\n>;\n\nexport type FloatingActionButtonButtonItemProperties = InferComponentDefinition<{\n \"Icon#29766:18\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24681\";\n preferredValues: [];\n };\n \"Label#29808:0\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\"];\n };\n Extended: {\n type: \"VARIANT\";\n defaultValue: \"True\";\n variantOptions: [\"True\", \"False\"];\n };\n}>;\n\nexport type FloatingActionButtonMenuItemProperties = InferComponentDefinition<{\n \"Icon#29766:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:24681\";\n preferredValues: [];\n };\n \"Label#29766:9\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Pressed\", \"Enabled\"];\n };\n Extended: {\n type: \"VARIANT\";\n defaultValue: \"True\";\n variantOptions: [\"True\", \"False\"];\n };\n Open: {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"True\", \"False\"];\n };\n}>;\n\nexport type HelpBubbleProperties = InferComponentDefinition<\n typeof metadata.helpBubble.componentPropertyDefinitions\n>;\n\nexport type IdentityPlaceholderProperties = InferComponentDefinition<{\n Identity: {\n type: \"VARIANT\";\n defaultValue: \"Person\";\n variantOptions: [\"Person\", \"Business\"];\n };\n}>;\n\nexport type PageBannerProperties = InferComponentDefinition<\n typeof metadata.pageBanner.componentPropertyDefinitions\n>;\n\nexport type PageBannerButtonProperties = InferComponentDefinition<{\n \"Label#39890:0\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n}>;\n\nexport type ListHeaderProperties = InferComponentDefinition<\n typeof metadata.listHeader.componentPropertyDefinitions\n>;\n\nexport type ListItemProperties = InferComponentDefinition<\n typeof metadata.listItem.componentPropertyDefinitions\n>;\n\nexport type ListItemPrefixIconProperties = InferComponentDefinition<{\n \"Icon#28452:111\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102336\";\n preferredValues: [{ type: \"COMPONENT_SET\"; key: \"1449adc3a216979ac3e6a4a99183a9e9790b220c\" }];\n };\n}>;\n\nexport type ListItemSuffixIconProperties = InferComponentDefinition<{\n \"Icon#28347:9\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23412\";\n preferredValues: [];\n };\n}>;\n\nexport type MannerTempProperties = InferComponentDefinition<\n typeof metadata.mannerTemp.componentPropertyDefinitions\n>;\n\nexport type MannerTempBadgeProperties = InferComponentDefinition<\n typeof metadata.mannerTempBadge.componentPropertyDefinitions\n>;\n\nexport type MultilineTextFieldProperties = InferComponentDefinition<\n typeof metadata.multilineTextField.componentPropertyDefinitions\n>;\n\nexport type ProgressCircleProperties = InferComponentDefinition<\n typeof metadata.progressCircle.componentPropertyDefinitions\n>;\n\nexport type RadioProperties = InferComponentDefinition<\n typeof metadata.radio.componentPropertyDefinitions\n>;\n\nexport type RadioMarkProperties = InferComponentDefinition<\n typeof metadata.radioMark.componentPropertyDefinitions\n>;\n\nexport type ReactionButtonProperties = InferComponentDefinition<\n typeof metadata.reactionButton.componentPropertyDefinitions\n>;\n\nexport type SegmentedControlProperties = InferComponentDefinition<\n typeof metadata.segmentedControl.componentPropertyDefinitions\n>;\n\nexport type SegmentedControlItemProperties = InferComponentDefinition<{\n \"Label#11366:15\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Enabled\";\n variantOptions: [\"Enabled\", \"Pressed\", \"Selected\", \"Disabled\", \"Disabled-Selected\"];\n };\n}>;\n\nexport type SkeletonProperties = InferComponentDefinition<\n typeof metadata.skeleton.componentPropertyDefinitions\n>;\n\nexport type SnackbarProperties = InferComponentDefinition<\n typeof metadata.snackbar.componentPropertyDefinitions\n>;\n\nexport type SwitchProperties = InferComponentDefinition<\n typeof metadata.switch.componentPropertyDefinitions\n>;\n\nexport type SwitchMarkProperties = InferComponentDefinition<\n typeof metadata.switchMark.componentPropertyDefinitions\n>;\n\nexport type ToggleButtonProperties = InferComponentDefinition<\n typeof metadata.toggleButton.componentPropertyDefinitions\n>;\n\nexport type SelectBoxGroupProperties = InferComponentDefinition<\n typeof metadata.templateSelectBoxGroup.componentPropertyDefinitions\n>;\n\nexport type SelectBoxProperties = InferComponentDefinition<\n typeof metadata.selectBox.componentPropertyDefinitions\n>;\n\nexport type TextFieldProperties = InferComponentDefinition<\n typeof metadata.textField.componentPropertyDefinitions\n>;\n\nexport type AppBarProperties = InferComponentDefinition<\n typeof metadata.topNavigation.componentPropertyDefinitions\n>;\n\nexport type AppBarMainProperties = InferComponentDefinition<{\n \"Title#16944:0\": {\n type: \"TEXT\";\n defaultValue: \"타이틀\";\n };\n \"Logo#16958:5\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"1574:3942\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"c7dab3f6d0df0a150564e696c0df00bd43ffef3f\";\n },\n ];\n };\n \"Subtitle#16958:9\": {\n type: \"TEXT\";\n defaultValue: \"서브타이틀\";\n };\n \"Show Right#16958:13\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n \"Show Left#16958:17\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Type: {\n type: \"VARIANT\";\n defaultValue: \"Title\";\n variantOptions: [\"Title\", \"Title-Subtitle\", \"Logo (Figma Only)\"];\n };\n}>;\n\nexport type AppBarLeftIconButtonProperties = InferComponentDefinition<{\n \"Icon#33580:0\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"26621:23427\";\n preferredValues: [];\n };\n}>;\n\nexport type AppBarRightIconButtonProperties = InferComponentDefinition<{\n \"Icon#6406:3\": {\n type: \"INSTANCE_SWAP\";\n defaultValue: \"34885:102301\";\n preferredValues: [\n {\n type: \"COMPONENT_SET\";\n key: \"bc7bc98e19d8ffdd9efdc94b610c6af28156f867\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"d766c026e52ee6c78cbf1a474068264e831ddfe3\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"a4cb85e4d25a320d27a48c3e8132a6c01b45ab3c\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"e262d9b447adff63d15a6f1af60ae47cbc1ca47f\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"1d3918afcac320eff3aafc2719b98cf5141afa55\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"8ed05ef62a40f2dc034ee7eb6945bd0e63ad49aa\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"98ee886122c725ac9e3e682f31efd1d1a1bec90d\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"bf71b0c5c8664149298fe1b3c58905715a523e19\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"47a8df3d59bc52aef1c584d992c05771a8125965\";\n },\n {\n type: \"COMPONENT_SET\";\n key: \"0fcbc3c123d5c7ee7a5dd20e0860ee25bdc19e30\";\n },\n ];\n };\n Notification: {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"False\", \"True\"];\n };\n}>;\n\nexport type TabsProperties = InferComponentDefinition<\n typeof metadata.tabs.componentPropertyDefinitions\n>;\n\nexport type TabsLineWrapperProperties = InferComponentDefinition<{\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n Layout: {\n type: \"VARIANT\";\n defaultValue: \"Fill\";\n variantOptions: [\"Hug\", \"Fill\"];\n };\n}>;\n\nexport type TabsLineTriggerHugProperties = InferComponentDefinition<{\n \"Label#4478:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Has Notification#32892:0\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Small\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n}>;\n\nexport type TabsLineTriggerFillProperties = InferComponentDefinition<{\n \"Label#4478:2\": {\n type: \"TEXT\";\n defaultValue: \"라벨\";\n };\n \"Has Notification#32904:13\": {\n type: \"BOOLEAN\";\n defaultValue: false;\n };\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Small\";\n variantOptions: [\"Medium\", \"Small\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n}>;\n\nexport type TabsChipWrapperProperties = InferComponentDefinition<{\n Size: {\n type: \"VARIANT\";\n defaultValue: \"Large\";\n variantOptions: [\"Medium\", \"Large\"];\n };\n Variant: {\n type: \"VARIANT\";\n defaultValue: \"Solid\";\n variantOptions: [\"Solid\", \"Outline\"];\n };\n}>;\n\nexport type ChipTabsTriggerProperties = InferComponentDefinition<{\n \"\\bSize\": {\n type: \"VARIANT\";\n defaultValue: \"Medium\";\n variantOptions: [\"Medium\", \"Large\"];\n };\n Variant: {\n type: \"VARIANT\";\n defaultValue: \"Solid\";\n variantOptions: [\"Outline\", \"Solid\"];\n };\n State: {\n type: \"VARIANT\";\n defaultValue: \"Selected\";\n variantOptions: [\"Enabled\", \"Selected\", \"Disabled\"];\n };\n \"Has Notification\": {\n type: \"VARIANT\";\n defaultValue: \"False\";\n variantOptions: [\"False\", \"True\"];\n };\n}>;\n","import { createCodeGenerator, createValueResolver } from \"@/codegen/core\";\nimport type { CodeGenerator } from \"@/codegen/core/codegen\";\nimport { styleService, variableService } from \"@/codegen/default-services\";\nimport { componentRepository } from \"@/entities\";\nimport { createFrameTransformer } from \"./frame\";\nimport { createInstanceTransformer } from \"./instance\";\nimport {\n createContainerLayoutPropsConverter,\n createFrameFillPropsConverter,\n createRadiusPropsConverter,\n createSelfLayoutPropsConverter,\n createShapeFillPropsConverter,\n createStrokePropsConverter,\n createTextFillPropsConverter,\n createTypeStylePropsConverter,\n} from \"./props\";\nimport {\n createBooleanOperationTransformer,\n createRectangleTransformer,\n createVectorTransformer,\n} from \"./shape\";\nimport { createTextTransformer } from \"./text\";\nimport {\n defaultFillStyleResolver,\n defaultRawValueFormatters,\n defaultTextStyleNameFormatter,\n defaultVariableNameFormatter,\n} from \"./value-resolver\";\n\nexport interface CreatePipelineConfig {\n shouldInferAutoLayout?: boolean;\n shouldInferVariableName?: boolean;\n}\n\nexport function createPipeline(options: CreatePipelineConfig = {}): CodeGenerator {\n const { shouldInferAutoLayout = true, shouldInferVariableName = true } = options;\n\n const valueResolver = createValueResolver({\n variableService,\n variableNameFormatter: defaultVariableNameFormatter,\n styleService,\n textStyleNameFormatter: defaultTextStyleNameFormatter,\n fillStyleResolver: defaultFillStyleResolver,\n rawValueFormatters: defaultRawValueFormatters,\n shouldInferVariableName,\n });\n\n const containerLayoutPropsConverter = createContainerLayoutPropsConverter(valueResolver);\n const selfLayoutPropsConverter = createSelfLayoutPropsConverter(valueResolver);\n const frameFillPropsConverter = createFrameFillPropsConverter(valueResolver);\n const shapeFillPropsConverter = createShapeFillPropsConverter(valueResolver);\n const textFillPropsConverter = createTextFillPropsConverter(valueResolver);\n const radiusPropsConverter = createRadiusPropsConverter(valueResolver);\n const strokePropsConverter = createStrokePropsConverter(valueResolver);\n const typeStylePropsConverter = createTypeStylePropsConverter(valueResolver);\n\n const propsConverters = {\n containerLayout: containerLayoutPropsConverter,\n selfLayout: selfLayoutPropsConverter,\n frameFill: frameFillPropsConverter,\n shapeFill: shapeFillPropsConverter,\n textFill: textFillPropsConverter,\n radius: radiusPropsConverter,\n stroke: strokePropsConverter,\n typeStyle: typeStylePropsConverter,\n };\n\n const frameTransformer = createFrameTransformer({\n propsConverters,\n });\n const instanceTransformer = createInstanceTransformer({\n frameTransformer,\n componentRepository,\n });\n const textTransformer = createTextTransformer({\n propsConverters,\n });\n const rectangleTransformer = createRectangleTransformer({\n propsConverters,\n });\n const vectorTransformer = createVectorTransformer({\n propsConverters,\n });\n const booleanOperationTransformer = createBooleanOperationTransformer({\n propsConverters,\n });\n\n const codegenTransformer = createCodeGenerator({\n frameTransformer,\n textTransformer,\n rectangleTransformer,\n instanceTransformer,\n vectorTransformer,\n booleanOperationTransformer,\n shouldInferAutoLayout,\n });\n\n return codegenTransformer;\n}\n","import type { ValueResolver } from \"@/codegen/core\";\nimport { toCssRgba } from \"@/utils/css\";\nimport { camelCase } from \"change-case\";\n\nexport type FigmaValueResolver = ValueResolver<\n string,\n { value: string; direction?: string },\n number,\n number,\n number\n>;\n\nexport const defaultVariableNameFormatter = ({ slug }: { slug: string[] }) =>\n slug\n .filter((s) => s !== \"dimension\")\n .map((s) => s.replaceAll(\",\", \"_\"))\n .join(\"/\");\n\nexport const defaultTextStyleNameFormatter = ({ slug }: { slug: string[] }) =>\n slug[slug.length - 1]!;\n\nexport const defaultFillStyleResolver = ({ slug }: { slug: string[] }) => {\n const [, ...rest] = slug;\n\n if (rest.includes(\"fade\")) {\n // [\"fade\", \"layer-default\", \"↓(to-bottom)\"]\n\n const last = rest[rest.length - 1];\n\n const direction = (() => {\n if (last.startsWith(\"↓\")) return \"to bottom\";\n if (last.startsWith(\"↑\")) return \"to top\";\n if (last.startsWith(\"→\")) return \"to right\";\n if (last.startsWith(\"←\")) return \"to left\";\n\n return \"unknown\";\n })();\n\n return {\n value: camelCase(rest.slice(0, -1).join(\"-\"), { mergeAmbiguousCharacters: true }),\n direction,\n };\n }\n\n return {\n value: camelCase(rest.join(\"-\"), { mergeAmbiguousCharacters: true }),\n };\n};\n\nexport const defaultRawValueFormatters = {\n color: (value: RGBA) => toCssRgba(value),\n dimension: (value: number) => value,\n fontDimension: (value: number) => value,\n fontWeight: (value: number) => value,\n};\n","import { createPropsConverter, definePropsConverter, type PropsConverter } from \"@/codegen/core\";\nimport type {\n NormalizedCornerTrait,\n NormalizedHasChildrenTrait,\n NormalizedHasFramePropertiesTrait,\n NormalizedHasGeometryTrait,\n NormalizedHasLayoutTrait,\n NormalizedIsLayerTrait,\n NormalizedTypePropertiesTrait,\n} from \"@/normalizer\";\nimport type { FigmaValueResolver } from \"./value-resolver\";\n\nexport interface PropsConverters {\n containerLayout: PropsConverter<ContainerLayoutTrait, ContainerLayoutProps>;\n selfLayout: PropsConverter<SelfLayoutTrait, SelfLayoutProps>;\n radius: PropsConverter<RadiusTrait, RadiusProps>;\n frameFill: PropsConverter<FillTrait, FillProps>;\n shapeFill: PropsConverter<FillTrait, FillProps>;\n textFill: PropsConverter<FillTrait, FillProps>;\n stroke: PropsConverter<StrokeTrait, StrokeProps>;\n typeStyle: PropsConverter<TypeStyleTrait, TypeStyleProps>;\n}\n\nexport type ContainerLayoutTrait = NormalizedHasFramePropertiesTrait &\n NormalizedHasChildrenTrait &\n NormalizedHasLayoutTrait &\n NormalizedIsLayerTrait;\n\nexport type SelfLayoutTrait = NormalizedIsLayerTrait & NormalizedHasLayoutTrait;\n\nexport type RadiusTrait = NormalizedCornerTrait & NormalizedIsLayerTrait;\n\nexport type FillTrait = NormalizedIsLayerTrait & NormalizedHasGeometryTrait;\n\nexport type StrokeTrait = NormalizedIsLayerTrait & NormalizedHasGeometryTrait;\n\nexport type TypeStyleTrait = NormalizedTypePropertiesTrait & NormalizedIsLayerTrait;\n\nexport interface ContainerLayoutProps {\n layoutMode?: \"HORIZONTAL\" | \"VERTICAL\" | \"NONE\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"BASELINE\";\n layoutWrap?: \"WRAP\" | \"NO_WRAP\";\n itemSpacing?: number | string; // string when variable\n paddingTop?: number | string; // string when variable\n paddingBottom?: number | string; // string when variable\n paddingLeft?: number | string; // string when variable\n paddingRight?: number | string; // string when variable\n horizontalPadding?: number | string; // string when variable\n verticalPadding?: number | string; // string when variable\n}\n\nexport function createContainerLayoutPropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<ContainerLayoutTrait, ContainerLayoutProps> {\n return createPropsConverter({\n _types: {\n trait: {} as ContainerLayoutTrait,\n props: {} as ContainerLayoutProps,\n },\n handlers: {\n layoutMode: ({ layoutMode }) => (!layoutMode || layoutMode === \"GRID\" ? \"NONE\" : layoutMode),\n primaryAxisAlignItems: ({ primaryAxisAlignItems }) => primaryAxisAlignItems,\n counterAxisAlignItems: ({ counterAxisAlignItems }) => counterAxisAlignItems,\n layoutWrap: ({ layoutWrap }) => layoutWrap,\n itemSpacing: (node) => valueResolver.getFormattedValue.itemSpacing(node),\n paddingTop: (node) => valueResolver.getFormattedValue.paddingTop(node),\n paddingBottom: (node) => valueResolver.getFormattedValue.paddingBottom(node),\n paddingLeft: (node) => valueResolver.getFormattedValue.paddingLeft(node),\n paddingRight: (node) => valueResolver.getFormattedValue.paddingRight(node),\n },\n shorthands: {\n horizontalPadding: [\"paddingLeft\", \"paddingRight\"],\n verticalPadding: [\"paddingTop\", \"paddingBottom\"],\n },\n defaults: {},\n });\n}\n\nexport interface SelfLayoutProps {\n layoutGrow?: number;\n layoutAlign?: \"STRETCH\" | \"INHERIT\" | \"MIN\" | \"CENTER\" | \"MAX\";\n layoutSizingVertical?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutSizingHorizontal?: \"FIXED\" | \"HUG\" | \"FILL\";\n width?: string | number; // string when variable\n height?: string | number; // string when variable\n minWidth?: string | number; // string when variable\n minHeight?: string | number; // string when variable\n maxWidth?: string | number; // string when variable\n maxHeight?: string | number; // string when variable\n}\n\nexport function createSelfLayoutPropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<SelfLayoutTrait, SelfLayoutProps> {\n return createPropsConverter({\n _types: {\n trait: {} as SelfLayoutTrait,\n props: {} as SelfLayoutProps,\n },\n handlers: {\n layoutGrow: ({ layoutGrow }) => layoutGrow,\n layoutAlign: ({ layoutAlign }) => layoutAlign,\n layoutSizingVertical: ({ layoutSizingVertical }) => layoutSizingVertical,\n layoutSizingHorizontal: ({ layoutSizingHorizontal }) => layoutSizingHorizontal,\n width: (node) => valueResolver.getFormattedValue.width(node),\n height: (node) => valueResolver.getFormattedValue.height(node),\n minWidth: (node) => valueResolver.getFormattedValue.minWidth(node),\n minHeight: (node) => valueResolver.getFormattedValue.minHeight(node),\n maxWidth: (node) => valueResolver.getFormattedValue.maxWidth(node),\n maxHeight: (node) => valueResolver.getFormattedValue.maxHeight(node),\n },\n defaults: {},\n });\n}\n\nexport interface RadiusProps {\n cornerRadius?: number | string; // string when variable\n topLeftRadius?: number | string; // string when variable\n topRightRadius?: number | string; // string when variable\n bottomLeftRadius?: number | string; // string when variable\n bottomRightRadius?: number | string; // string when variable\n}\n\nexport function createRadiusPropsConverter(valueResolver: FigmaValueResolver) {\n return createPropsConverter({\n _types: {\n trait: {} as RadiusTrait,\n props: {} as RadiusProps,\n },\n handlers: {\n topLeftRadius: (node) => valueResolver.getFormattedValue.topLeftRadius(node),\n topRightRadius: (node) => valueResolver.getFormattedValue.topRightRadius(node),\n bottomLeftRadius: (node) => valueResolver.getFormattedValue.bottomLeftRadius(node),\n bottomRightRadius: (node) => valueResolver.getFormattedValue.bottomRightRadius(node),\n },\n shorthands: {\n cornerRadius: [\"topLeftRadius\", \"topRightRadius\", \"bottomLeftRadius\", \"bottomRightRadius\"],\n },\n defaults: {\n cornerRadius: 0,\n topLeftRadius: 0,\n topRightRadius: 0,\n bottomLeftRadius: 0,\n bottomRightRadius: 0,\n },\n });\n}\n\nexport interface FillProps {\n fill?: string;\n}\n\nexport function createFrameFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.frameFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport function createShapeFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.shapeFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport function createTextFillPropsConverter(valueResolver: FigmaValueResolver) {\n return definePropsConverter<FillTrait, FillProps>((node: FillTrait) => {\n const fill = valueResolver.getFormattedValue.textFill(node);\n\n return {\n fill,\n };\n });\n}\n\nexport interface StrokeProps {\n stroke?: string;\n strokeWeight?: number;\n}\n\nexport function createStrokePropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<StrokeTrait, StrokeProps> {\n return definePropsConverter((node: StrokeTrait) => {\n const stroke = valueResolver.getFormattedValue.stroke(node);\n const strokeWeight = node.strokeWeight;\n\n return {\n stroke,\n strokeWeight,\n };\n });\n}\n\nexport interface TypeStyleProps {\n textStyle?: string;\n fontSize?: string | number;\n fontWeight?: string | number;\n lineHeight?: string | number;\n maxLines?: number;\n}\n\nexport function createTypeStylePropsConverter(\n valueResolver: FigmaValueResolver,\n): PropsConverter<TypeStyleTrait, TypeStyleProps> {\n return definePropsConverter((node) => {\n const styleName = valueResolver.getTextStyleValue(node);\n const maxLines =\n node.style.textTruncation === \"ENDING\" ? (node.style.maxLines ?? undefined) : undefined;\n\n if (styleName) {\n return {\n textStyle: styleName,\n maxLines,\n };\n }\n\n return {\n fontSize: valueResolver.getFormattedValue.fontSize(node),\n fontWeight: valueResolver.getFormattedValue.fontWeight(node),\n lineHeight: valueResolver.getFormattedValue.lineHeight(node),\n maxLines,\n };\n });\n}\n","import type {\n NormalizedComponentNode,\n NormalizedFrameNode,\n NormalizedInstanceNode,\n} from \"@/normalizer\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface FrameTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createFrameTransformer({\n propsConverters,\n}: FrameTransformerDeps): ElementTransformer<\n NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode\n> {\n return defineElementTransformer(\n (node: NormalizedFrameNode | NormalizedInstanceNode | NormalizedComponentNode, traverse) => {\n const children = node.children;\n\n const props = {\n ...propsConverters.radius(node),\n ...propsConverters.containerLayout(node),\n ...propsConverters.selfLayout(node),\n ...propsConverters.frameFill(node),\n ...propsConverters.stroke(node),\n };\n\n return createElement(\n \"Frame\",\n props,\n children.map((child) => traverse(child)),\n );\n },\n );\n}\n","import type { ComponentRepository } from \"@/entities\";\nimport type { NormalizedInstanceNode } from \"@/normalizer\";\nimport { camelCase } from \"change-case\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\n\nexport interface InstanceTransformerDeps {\n frameTransformer: ElementTransformer<NormalizedInstanceNode>;\n componentRepository?: ComponentRepository;\n}\n\nexport function createInstanceTransformer({\n frameTransformer,\n componentRepository,\n}: InstanceTransformerDeps): ElementTransformer<NormalizedInstanceNode> {\n const transform = defineElementTransformer((node: NormalizedInstanceNode, traverse) => {\n const component = componentRepository?.getOne(node.componentSetKey ?? node.componentKey);\n\n if (component) {\n return createElement(\"Instance\", {\n componentName: component.name,\n ...Object.fromEntries(\n Object.entries(node.componentProperties)\n .filter(([_, props]) => props.type === \"VARIANT\" || props.type === \"TEXT\")\n .map(([key, props]) => [\n camelCase(key.split(\"#\")[0]),\n camelCase(props.value as string),\n ]),\n ),\n });\n }\n\n return frameTransformer(node, traverse);\n });\n\n return transform;\n}\n","import type {\n NormalizedBooleanOperationNode,\n NormalizedRectangleNode,\n NormalizedVectorNode,\n} from \"@/normalizer\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface RectangleTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createRectangleTransformer({\n propsConverters,\n}: RectangleTransformerDeps): ElementTransformer<NormalizedRectangleNode> {\n return defineElementTransformer((node: NormalizedRectangleNode) => {\n return createElement(\"Rectangle\", { ...propsConverters.selfLayout(node) });\n });\n}\n\nexport interface VectorTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createVectorTransformer({\n propsConverters,\n}: VectorTransformerDeps): ElementTransformer<NormalizedVectorNode> {\n return defineElementTransformer((node) => {\n return createElement(\n \"Vector\",\n {\n ...propsConverters.selfLayout(node),\n ...propsConverters.radius(node),\n ...propsConverters.stroke(node),\n ...propsConverters.shapeFill(node),\n },\n [],\n {\n comment: \"Vector Node Placeholder\",\n },\n );\n });\n}\n\nexport interface BooleanOperationTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createBooleanOperationTransformer({\n propsConverters,\n}: BooleanOperationTransformerDeps): ElementTransformer<NormalizedBooleanOperationNode> {\n return defineElementTransformer((node, traverse) => {\n return createElement(\n \"BooleanOperation\",\n {\n ...propsConverters.selfLayout(node),\n ...propsConverters.radius(node),\n ...propsConverters.stroke(node),\n ...propsConverters.shapeFill(node),\n },\n node.children.map(traverse),\n );\n });\n}\n","import type { NormalizedTextNode } from \"@/normalizer\";\nimport { compactObject } from \"@/utils/common\";\nimport { createElement, defineElementTransformer, type ElementTransformer } from \"../../core\";\nimport type { PropsConverters } from \"./props\";\n\nexport interface TextTransformerDeps {\n propsConverters: PropsConverters;\n}\n\nexport function createTextTransformer({\n propsConverters,\n}: TextTransformerDeps): ElementTransformer<NormalizedTextNode> {\n return defineElementTransformer((node: NormalizedTextNode) => {\n const hasMultipleFills = node.fills.length > 1;\n\n const fillProps = propsConverters.textFill(node);\n const typeStyleProps = propsConverters.typeStyle(node);\n\n const props = compactObject({\n ...typeStyleProps,\n ...fillProps,\n });\n\n return createElement(\"Text\", props, node.characters, {\n comment: hasMultipleFills\n ? \"Multiple fills in Text node encountered, only the first fill is used.\"\n : undefined,\n });\n });\n}\n"],"names":[],"mappings":";;;;;AACO;AACA;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACA;AACA;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACO;AACP;AACA;AACA;AACA;AACO;;ACtEA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACA;;ACAA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACnBA;AACP;AACA;AACA;AACA;AACA;AACO;AACP;AACA;;ACTO;AACP;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBO;AACP;AACA;AACA;AACA;;ACJO;AAGA;AACA;;ACJA;AACP;AACA;;ACDO;AACP;AACA;AACA;AACA;;ACLO;AACP;AACA;;ACFO;AACA;AACP;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACZA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;AClDP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACtBA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9DO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClGO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpaO;AACP;AACA;AACA;AACO;;ACJA;AACP;AACA;AACA;;ACDO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACA;AACA;AACA;AACA;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACA;AACA;AACP;AACA;AACA;AACO;AACA;AACP;AACA;AACA;AACA;AACA;AACA;AACO;;ACrEA;AACP;AACA;AACO;;ACHA;AACP;AACA;AACA;AACO;;ACJA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;AACA;AACP;AACA;AACO;;ACXA;AACP;AACA;AACO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}