{
  "version": 3,
  "sources": ["../../src/app/ai/agents/evals2/scenarios/richText/helpers.ts"],
  "sourcesContent": ["import type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport type { Node as ProseMirrorNode } from \"prosemirror-model\"\nimport { MarkName } from \"prosemirror/schema/names.ts\"\nimport { parseRichText } from \"prosemirror/serialization/dom.ts\"\nimport { isObject, isUndefined } from \"utils/typeChecks.ts\"\n\nexport const redTextColorPattern = /^(?:#ff0000|rgb\\(255,\\s*0,\\s*0\\))$/iu\nexport const greenTextColorPattern = /^(?:#00ff00|rgb\\(0,\\s*255,\\s*0\\))$/iu\nexport const blueTextColorPattern = /^(?:#0000ff|rgb\\(0,\\s*0,\\s*255\\))$/iu\n\nconst wordPattern = /\\b(?<word>[A-Za-z]+)\\b/gu\n\nexport function matchesTextColor(value: string | undefined, pattern: RegExp): boolean {\n\treturn value !== undefined && pattern.test(value)\n}\n\n/** Splits rich text by word and returns colors. Limitation: words must be unique */\nexport function getInlineWordTextColors(node: RichTextNode): Map<string, string | undefined> {\n\tconst doc = parseRichText(node.getHTMLContent(), node.getProseMirrorSchema())\n\tconst textColors = new Map<string, string | undefined>()\n\n\tdoc.descendants((child, _position, parent) => {\n\t\tif (!child.isText) return\n\t\tfor (const match of (child.text ?? \"\").matchAll(wordPattern)) {\n\t\t\tconst word = match.groups?.word\n\t\t\tif (word === undefined || textColors.has(word)) continue\n\t\t\ttextColors.set(word, getTextColor(child, parent))\n\t\t}\n\t})\n\n\treturn textColors\n}\n\nfunction getTextColor(node: ProseMirrorNode, parent: ProseMirrorNode | null): string | undefined {\n\tfor (const mark of node.marks) {\n\t\tif (mark.type.name !== MarkName.InlineStyles) continue\n\t\tconst color = getTextColorFromAttrs(mark.attrs)\n\t\tif (color !== undefined) return color\n\t}\n\n\treturn getTextColorFromAttrs(parent?.attrs)\n}\n\nfunction getTextColorFromAttrs(attrs: unknown): string | undefined {\n\tif (!isObject(attrs) || !isObject(attrs.inlineStyles)) return undefined\n\tconst { textColor } = attrs.inlineStyles\n\treturn typeof textColor === \"string\" ? textColor : undefined\n}\n\nexport interface WordStyles {\n\tbold: boolean\n\titalic: boolean\n\tunderline: boolean\n\tfontFamily: string | undefined\n}\n\n/** Splits rich text by word and returns styles. Limitation: words must be unique */\nexport function getInlineWordStyles(node: RichTextNode): Map<string, WordStyles> {\n\tconst doc = parseRichText(node.getHTMLContent(), node.getProseMirrorSchema())\n\tconst wordStyles = new Map<string, WordStyles>()\n\n\tdoc.descendants((child, _position, parent) => {\n\t\tif (!child.isText) return\n\t\tfor (const match of (child.text ?? \"\").matchAll(wordPattern)) {\n\t\t\tconst word = match.groups?.word\n\t\t\tif (isUndefined(word) || wordStyles.has(word)) continue\n\t\t\twordStyles.set(word, getWordStyles(child, parent))\n\t\t}\n\t})\n\n\treturn wordStyles\n}\n\nfunction getWordStyles(node: ProseMirrorNode, parent: ProseMirrorNode | null): WordStyles {\n\tconst marksByName = new Map(node.marks.map(mark => [mark.type.name, mark]))\n\tconst inlineStyles = {\n\t\t...getInlineStyles(parent?.attrs),\n\t\t...getInlineStyles(marksByName.get(MarkName.InlineStyles)?.attrs),\n\t}\n\tconst fontSelector = typeof inlineStyles.font === \"string\" ? inlineStyles.font : undefined\n\treturn {\n\t\tbold: marksByName.has(MarkName.Bold),\n\t\titalic: marksByName.has(MarkName.Italic) || isItalicFontSelector(fontSelector),\n\t\tunderline: inlineStyles.textDecoration === \"underline\",\n\t\tfontFamily: getPrimaryFontFamily(fontSelector),\n\t}\n}\n\nfunction getInlineStyles(attrs: unknown): Record<string, unknown> {\n\tif (!isObject(attrs) || !isObject(attrs.inlineStyles)) return {}\n\treturn attrs.inlineStyles\n}\n\n// A Framer font selector is `[GF;]<family>-<variant>`, e.g. `Geist-500`, `GF;Open Sans-400italic`.\n// Family names use spaces (never dashes), so everything before the first dash is the family.\n// Mirrors `getFontVariant` in document/.../utils/textStyle.ts.\nfunction getPrimaryFontFamily(fontSelector: string | undefined): string | undefined {\n\tif (!fontSelector) return\n\tconst withoutSourcePrefix = fontSelector.replace(/^GF;/u, \"\")\n\tconst dashIndex = withoutSourcePrefix.indexOf(\"-\")\n\treturn dashIndex < 0 ? withoutSourcePrefix : withoutSourcePrefix.slice(0, dashIndex)\n}\n\nfunction isItalicFontSelector(fontSelector: string | undefined): boolean {\n\treturn fontSelector !== undefined && /italic/iu.test(fontSelector)\n}\n"],
  "mappings": ";;;;;;;;;AAMO,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAEpC,IAAM,cAAc;AAEb,SAAS,iBAAiB,OAA2B,SAA0B;AACrF,SAAO,UAAU,UAAa,QAAQ,KAAK,KAAK;AACjD;AAGO,SAAS,wBAAwB,MAAqD;AAC5F,QAAM,MAAM,cAAc,KAAK,eAAe,GAAG,KAAK,qBAAqB,CAAC;AAC5E,QAAM,aAAa,oBAAI,IAAgC;AAEvD,MAAI,YAAY,CAAC,OAAO,WAAW,WAAW;AAC7C,QAAI,CAAC,MAAM,OAAQ;AACnB,eAAW,UAAU,MAAM,QAAQ,IAAI,SAAS,WAAW,GAAG;AAC7D,YAAM,OAAO,MAAM,QAAQ;AAC3B,UAAI,SAAS,UAAa,WAAW,IAAI,IAAI,EAAG;AAChD,iBAAW,IAAI,MAAM,aAAa,OAAO,MAAM,CAAC;AAAA,IACjD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAEA,SAAS,aAAa,MAAuB,QAAoD;AAChG,aAAW,QAAQ,KAAK,OAAO;AAC9B,QAAI,KAAK,KAAK,2CAAgC;AAC9C,UAAM,QAAQ,sBAAsB,KAAK,KAAK;AAC9C,QAAI,UAAU,OAAW,QAAO;AAAA,EACjC;AAEA,SAAO,sBAAsB,QAAQ,KAAK;AAC3C;AAEA,SAAS,sBAAsB,OAAoC;AAClE,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,YAAY,EAAG,QAAO;AAC9D,QAAM,EAAE,UAAU,IAAI,MAAM;AAC5B,SAAO,OAAO,cAAc,WAAW,YAAY;AACpD;AAUO,SAAS,oBAAoB,MAA6C;AAChF,QAAM,MAAM,cAAc,KAAK,eAAe,GAAG,KAAK,qBAAqB,CAAC;AAC5E,QAAM,aAAa,oBAAI,IAAwB;AAE/C,MAAI,YAAY,CAAC,OAAO,WAAW,WAAW;AAC7C,QAAI,CAAC,MAAM,OAAQ;AACnB,eAAW,UAAU,MAAM,QAAQ,IAAI,SAAS,WAAW,GAAG;AAC7D,YAAM,OAAO,MAAM,QAAQ;AAC3B,UAAI,YAAY,IAAI,KAAK,WAAW,IAAI,IAAI,EAAG;AAC/C,iBAAW,IAAI,MAAM,cAAc,OAAO,MAAM,CAAC;AAAA,IAClD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAEA,SAAS,cAAc,MAAuB,QAA4C;AACzF,QAAM,cAAc,IAAI,IAAI,KAAK,MAAM,IAAI,UAAQ,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;AAC1E,QAAM,eAAe;AAAA,IACpB,GAAG,gBAAgB,QAAQ,KAAK;AAAA,IAChC,GAAG,gBAAgB,YAAY,qCAAyB,GAAG,KAAK;AAAA,EACjE;AACA,QAAM,eAAe,OAAO,aAAa,SAAS,WAAW,aAAa,OAAO;AACjF,SAAO;AAAA,IACN,MAAM,YAAY,qBAAiB;AAAA,IACnC,QAAQ,YAAY,yBAAmB,KAAK,qBAAqB,YAAY;AAAA,IAC7E,WAAW,aAAa,mBAAmB;AAAA,IAC3C,YAAY,qBAAqB,YAAY;AAAA,EAC9C;AACD;AAEA,SAAS,gBAAgB,OAAyC;AACjE,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,YAAY,EAAG,QAAO,CAAC;AAC/D,SAAO,MAAM;AACd;AAKA,SAAS,qBAAqB,cAAsD;AACnF,MAAI,CAAC,aAAc;AACnB,QAAM,sBAAsB,aAAa,QAAQ,SAAS,EAAE;AAC5D,QAAM,YAAY,oBAAoB,QAAQ,GAAG;AACjD,SAAO,YAAY,IAAI,sBAAsB,oBAAoB,MAAM,GAAG,SAAS;AACpF;AAEA,SAAS,qBAAqB,cAA2C;AACxE,SAAO,iBAAiB,UAAa,WAAW,KAAK,YAAY;AAClE;",
  "names": []
}
