{"version":3,"file":"index.cjs","names":["Blockquote","Paragraph","Heading","TableRow","BulletList","OrderedList","ListItem","CodeBlock","HardBreak","HorizontalRule","Table","TableCell","TableHeader","Image","Emoji","Node","LinkOriginal","Mark","Document","Text","Details","DetailsContent","DetailsSummary","Bold","Italic","Strike","Underline","Code","Superscript","Subscript","Highlight","callExtensionRenderHTML"],"sources":["../src/images-optimization.ts","../src/utils/index.ts","../src/types/index.ts","../src/extensions/utils.ts","../src/extensions/nodes.ts","../src/render-segments.ts","../src/extensions/marks.ts","../src/extensions/index.ts","../src/richtext.ts","../src/richtext-segment.ts","../src/utils/segment-richtext.ts","../src/index.ts"],"sourcesContent":["import type { StoryblokRichTextImageOptimizationOptions } from './types';\n\nexport function optimizeImage(src: string, options?: boolean | Partial<StoryblokRichTextImageOptimizationOptions>): { src: string; attrs: Record<string, any> } {\n  if (!options) {\n    return { src, attrs: {} };\n  }\n  let w = 0;\n  let h = 0;\n  const attrs: Record<string, unknown> = {};\n  const filterParams: string[] = [];\n\n  function validateAndPushFilterParam(value: number, min: number, max: number, filter: string, filterParams: string[]) {\n    if (typeof value !== 'number' || value <= min || value >= max) {\n      console.warn(`[StoryblokRichText] - ${filter.charAt(0).toUpperCase() + filter.slice(1)} value must be a number between ${min} and ${max} (inclusive)`);\n    }\n    else {\n      filterParams.push(`${filter}(${value})`);\n    }\n  }\n\n  if (typeof options === 'object') {\n    if (options.width !== undefined) {\n      if (typeof options.width === 'number' && options.width >= 0) {\n        attrs.width = options.width;\n        w = options.width;\n      }\n      else {\n        console.warn('[StoryblokRichText] - Width value must be a number greater than or equal to 0');\n      }\n    }\n    if (options.height !== undefined) {\n      if (typeof options.height === 'number' && options.height >= 0) {\n        attrs.height = options.height;\n        h = options.height;\n      }\n      else {\n        console.warn('[StoryblokRichText] - Height value must be a number greater than or equal to 0');\n      }\n    }\n    if (options.height === 0 && options.width === 0) {\n      delete attrs.width;\n      delete attrs.height;\n      console.warn('[StoryblokRichText] - Width and height values cannot both be 0');\n    }\n    if (options.loading && ['lazy', 'eager'].includes(options.loading)) {\n      attrs.loading = options.loading;\n    }\n    if (options.class) {\n      attrs.class = options.class;\n    }\n\n    if (options.filters) {\n      const { filters } = options || {};\n      const { blur, brightness, fill, format, grayscale, quality, rotate } = filters || {};\n\n      if (blur) {\n        validateAndPushFilterParam(blur, 0, 100, 'blur', filterParams);\n      }\n      if (quality) {\n        validateAndPushFilterParam(quality, 0, 100, 'quality', filterParams);\n      }\n      if (brightness) {\n        validateAndPushFilterParam(brightness, 0, 100, 'brightness', filterParams);\n      }\n      if (fill) {\n        filterParams.push(`fill(${fill})`);\n      }\n      if (grayscale) {\n        filterParams.push(`grayscale()`);\n      }\n      if (rotate && [0, 90, 180, 270].includes(options.filters.rotate || 0)) {\n        filterParams.push(`rotate(${rotate})`);\n      }\n      if (format && ['webp', 'png', 'jpeg'].includes(format)) {\n        filterParams.push(`format(${format})`);\n      }\n    }\n\n    // Construct srcset attribute\n    if (options.srcset) {\n      attrs.srcset = options.srcset.map((entry): string | undefined => {\n        if (typeof entry === 'number') {\n          return `${src}/m/${entry}x0/${filterParams.length > 0 ? `filters:${filterParams.join(':')}` : ''} ${entry}w`;\n        }\n        if (Array.isArray(entry) && entry.length === 2) {\n          const [entryWidth, entryHeight] = entry;\n          return `${src}/m/${entryWidth}x${entryHeight}/${filterParams.length > 0 ? `filters:${filterParams.join(':')}` : ''} ${entryWidth}w`;\n        }\n        else {\n          console.warn('[StoryblokRichText] - srcset entry must be a number or a tuple of two numbers');\n          return undefined;\n        }\n      }).join(', ');\n    }\n\n    // Construct sizes attribute\n    if (options.sizes) {\n      attrs.sizes = options.sizes.join(', ');\n    }\n  }\n\n  // server-side WebP support detection https://www.storyblok.com/docs/image-service/#optimize\n  // https://a.storyblok.com/f/39898/3310x2192/e4ec08624e/demo-image.jpeg/m/\n  let resultSrc = `${src}/m/`;\n  if (w > 0 || h > 0) {\n    resultSrc = `${resultSrc}${w}x${h}/`;\n  }\n  if (filterParams.length > 0) {\n    resultSrc = `${resultSrc}filters:${filterParams.join(':')}`;\n  }\n\n  return {\n    src: resultSrc,\n    attrs,\n  };\n}\n","import type { BlockAttributes, MarkNode, StoryblokRichTextNode, TextNode } from '../types';\n\n/**\n * Deep equality comparison for plain objects, arrays, and primitives.\n */\nexport function deepEqual(a: any, b: any): boolean {\n  if (a === b) {\n    return true;\n  }\n  if (a === null || a === undefined || b === null || b === undefined) {\n    return a === b;\n  }\n  if (typeof a !== typeof b) {\n    return false;\n  }\n  if (typeof a !== 'object') {\n    return false;\n  }\n  if (Array.isArray(a) !== Array.isArray(b)) {\n    return false;\n  }\n  if (Array.isArray(a)) {\n    if (a.length !== (b as any[]).length) {\n      return false;\n    }\n    return a.every((v: any, i: number) => deepEqual(v, (b as any[])[i]));\n  }\n  const aKeys = Object.keys(a);\n  const bKeys = Object.keys(b);\n  if (aKeys.length !== bKeys.length) {\n    return false;\n  }\n  return aKeys.every(k => Object.prototype.hasOwnProperty.call(b, k) && deepEqual(a[k], b[k]));\n}\n\n/** Checks if two marks are equal by comparing their type and attrs. */\nexport function markEquals<T>(a: MarkNode<T>, b: MarkNode<T>): boolean {\n  return a.type === b.type && deepEqual(a.attrs, b.attrs);\n}\n\n/** Type guard: checks if a node is a text node with at least one mark. */\nexport function isMarkedTextNode<T>(node: StoryblokRichTextNode<T>): node is TextNode<T> {\n  return node.type === 'text' && !!(node as TextNode<T>).marks?.length;\n}\n\n/** Returns marks unique to a node (not in the shared set), or undefined if all marks are shared. */\nexport function getUniqueMarks<T>(marks: MarkNode<T>[], shared: MarkNode<T>[]): MarkNode<T>[] | undefined {\n  const unique = marks.filter(m => !shared.some(s => markEquals(s, m)));\n  return unique.length ? unique : undefined;\n}\n\nexport interface MarkedTextGroup<T> {\n  group: TextNode<T>[];\n  shared: MarkNode<T>[];\n  endIndex: number;\n}\n\n/**\n * Starting at `fromIndex`, collects adjacent marked text nodes that share at least one common mark.\n * Returns null if the node at `fromIndex` is not a marked text node.\n */\nexport function collectMarkedTextGroup<T>(\n  children: StoryblokRichTextNode<T>[],\n  fromIndex: number,\n): MarkedTextGroup<T> | null {\n  const child = children[fromIndex];\n  if (!isMarkedTextNode(child)) {\n    return null;\n  }\n\n  const group: TextNode<T>[] = [child];\n  let shared: MarkNode<T>[] = child.marks!;\n  let j = fromIndex + 1;\n  while (j < children.length) {\n    const next = children[j];\n    if (!isMarkedTextNode(next)) {\n      break;\n    }\n    const nextShared = shared.filter(m =>\n      next.marks!.some(n => markEquals(m, n)),\n    );\n    if (nextShared.length === 0) {\n      break;\n    }\n    shared = nextShared;\n    group.push(next);\n    j++;\n  }\n\n  return { group, shared, endIndex: j };\n}\n\nexport const SELF_CLOSING_TAGS = [\n  'area',\n  'base',\n  'br',\n  'col',\n  'embed',\n  'hr',\n  'img',\n  'input',\n  'link',\n  'meta',\n  'param',\n  'source',\n  'track',\n  'wbr',\n];\n\nexport const BLOCK_LEVEL_TAGS = [\n  'address',\n  'article',\n  'aside',\n  'blockquote',\n  'canvas',\n  'dd',\n  'div',\n  'dl',\n  'dt',\n  'fieldset',\n  'figcaption',\n  'figure',\n  'footer',\n  'form',\n  'h1',\n  'h2',\n  'h3',\n  'h4',\n  'h5',\n  'h6',\n  'header',\n  'hgroup',\n  'hr',\n  'li',\n  'main',\n  'nav',\n  'noscript',\n  'ol',\n  'output',\n  'p',\n  'pre',\n  'section',\n  'table',\n  'tfoot',\n  'ul',\n  'video',\n];\n\n/**\n * Converts an object of attributes to a string.\n *\n * @param {Record<string, string>} [attrs]\n *\n * @returns {string} The string representation of the attributes.\n *\n * @example\n *\n * ```typescript\n * const attrs = {\n *  class: 'text-red',\n *  style: 'color: red',\n * }\n *\n * const attrsString = attrsToString(attrs)\n *\n * console.log(attrsString) // 'class=\"text-red\" style=\"color: red\"'\n *\n * ```\n *\n */\nexport const attrsToString = (attrs: BlockAttributes = {}) => {\n  const { custom, ...attrsWithoutCustom } = attrs;\n  const normalizedAttrs = { ...attrsWithoutCustom, ...custom };\n  return Object.keys(normalizedAttrs)\n    .filter(key => normalizedAttrs[key] != null)\n    .map(key => `${key}=\"${String(normalizedAttrs[key]).replace(/&/g, '&amp;').replace(/\"/g, '&quot;')}\"`)\n    .join(' ');\n};\n\n/**\n * Converts an object of attributes to a CSS style string.\n *\n * @param {Record<string, string>} [attrs]\n *\n * @returns {string} The string representation of the CSS styles.\n *\n * @example\n *\n * ```typescript\n * const attrs = {\n *  color: 'red',\n *  fontSize: '16px',\n * }\n *\n * const styleString = attrsToStyle(attrs)\n *\n * console.log(styleString) // 'color: red; font-size: 16px'\n * ```\n */\nexport const attrsToStyle = (attrs: Record<string, string> = {}) => Object.keys(attrs)\n  .map(key => `${key}: ${attrs[key]}`)\n  .join('; ');\n\n/**\n * Escapes HTML entities in a string.\n *\n * @param {string} unsafeText\n * @return {*}  {string}\n *\n * @example\n *\n * ```typescript\n * const unsafeText = '<script>alert(\"Hello\")</script>'\n *\n * const safeText = escapeHtml(unsafeText)\n *\n * console.log(safeText) // '&lt;script&gt;alert(\"Hello\")&lt;/script&gt;'\n * ```\n */\nexport function escapeHtml(unsafeText: string): string {\n  return unsafeText\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#039;');\n}\n\n/**\n * Removes undefined values from an object.\n *\n * @param {Record<string, any>} obj\n * @return {*}  {Record<string, any>}\n *\n * @example\n *\n * ```typescript\n * const obj = {\n * name: 'John',\n * age: undefined,\n * }\n *\n * const cleanedObj = cleanObject(obj)\n *\n * console.log(cleanedObj) // { name: 'John' }\n * ```\n *\n */\nexport const cleanObject = (obj: Record<string, any>) => {\n  return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));\n};\n","export enum BlockTypes {\n  DOCUMENT = 'doc',\n  HEADING = 'heading',\n  PARAGRAPH = 'paragraph',\n  QUOTE = 'blockquote',\n  OL_LIST = 'ordered_list',\n  UL_LIST = 'bullet_list',\n  LIST_ITEM = 'list_item',\n  CODE_BLOCK = 'code_block',\n  HR = 'horizontal_rule',\n  BR = 'hard_break',\n  IMAGE = 'image',\n  EMOJI = 'emoji',\n  COMPONENT = 'blok',\n  TABLE = 'table',\n  TABLE_ROW = 'tableRow',\n  TABLE_CELL = 'tableCell',\n  TABLE_HEADER = 'tableHeader',\n}\n\nexport enum MarkTypes {\n  BOLD = 'bold',\n  STRONG = 'strong',\n  STRIKE = 'strike',\n  UNDERLINE = 'underline',\n  ITALIC = 'italic',\n  CODE = 'code',\n  LINK = 'link',\n  ANCHOR = 'anchor',\n  STYLED = 'styled',\n  SUPERSCRIPT = 'superscript',\n  SUBSCRIPT = 'subscript',\n  TEXT_STYLE = 'textStyle',\n  HIGHLIGHT = 'highlight',\n}\n\nexport enum TextTypes {\n  TEXT = 'text',\n}\n\nexport enum LinkTargets {\n  SELF = '_self',\n  BLANK = '_blank',\n}\n\nexport enum LinkTypes {\n  URL = 'url',\n  STORY = 'story',\n  ASSET = 'asset',\n  EMAIL = 'email',\n}\n\n/**\n * Represents text alignment attributes that can be applied to block-level elements.\n */\nexport interface TextAlignmentAttrs {\n  textAlign?: 'left' | 'center' | 'right' | 'justify';\n}\n\n/**\n * Represents common attributes that can be applied to block-level elements.\n */\nexport interface BlockAttributes extends TextAlignmentAttrs {\n  class?: string;\n  id?: string;\n  [key: string]: any;\n}\n\nexport interface StoryblokRichTextDocumentNode {\n  type: string;\n  content?: StoryblokRichTextDocumentNode[];\n  attrs?: BlockAttributes;\n  text?: string;\n  marks?: StoryblokRichTextDocumentNode[];\n}\n\nexport type StoryblokRichTextNodeTypes = BlockTypes | MarkTypes | TextTypes;\n\nexport interface StoryblokRichTextNode<T = string> {\n  type: StoryblokRichTextNodeTypes;\n  content: StoryblokRichTextNode<T>[];\n  children?: T;\n  attrs?: BlockAttributes;\n  text?: string;\n}\n\nexport interface LinkNode<T = string> extends StoryblokRichTextNode<T> {\n  type: MarkTypes.LINK | MarkTypes.ANCHOR;\n  linktype: LinkTypes;\n  attrs: BlockAttributes;\n}\n\nexport interface MarkNode<T = string> extends StoryblokRichTextNode<T> {\n  type: MarkTypes.BOLD |\n    MarkTypes.ITALIC |\n    MarkTypes.UNDERLINE |\n    MarkTypes.STRIKE |\n    MarkTypes.CODE |\n    MarkTypes.LINK |\n    MarkTypes.ANCHOR |\n    MarkTypes.STYLED |\n    MarkTypes.SUPERSCRIPT |\n    MarkTypes.SUBSCRIPT |\n    MarkTypes.TEXT_STYLE |\n    MarkTypes.HIGHLIGHT;\n  attrs?: BlockAttributes;\n}\n\nexport interface TextNode<T = string> extends StoryblokRichTextNode<T> {\n  type: TextTypes.TEXT;\n  text: string;\n  marks?: MarkNode<T>[];\n}\n\n/**\n * Represents the configuration options for optimizing images in rich text content.\n */\nexport interface StoryblokRichTextImageOptimizationOptions {\n  /**\n   * CSS class to be applied to the image.\n   */\n  class: string;\n\n  /**\n   * Width of the image in pixels.\n   */\n  width: number;\n\n  /**\n   * Height of the image in pixels.\n   */\n  height: number;\n\n  /**\n   * Loading strategy for the image. 'lazy' loads the image when it enters the viewport. 'eager' loads the image immediately.\n   */\n  loading: 'lazy' | 'eager';\n\n  /**\n   * Optional filters that can be applied to the image to adjust its appearance.\n   *\n   * @example\n   *\n   * ```typescript\n   * const filters: Partial<StoryblokRichTextImageOptimizationOptions['filters']> = {\n   *   blur: 5,\n   *   brightness: 150,\n   *   grayscale: true\n   * }\n   * ```\n   */\n  filters: Partial<{\n    blur: number;\n    brightness: number;\n    fill: 'transparent';\n    format: 'webp' | 'png' | 'jpg';\n    grayscale: boolean;\n    quality: number;\n    rotate: 0 | 90 | 180 | 270;\n  }>;\n\n  /**\n   * Defines a set of source set values that tell the browser different image sizes to load based on screen conditions.\n   * The entries can be just the width in pixels or a tuple of width and pixel density.\n   *\n   * @example\n   *\n   * ```typescript\n   * const srcset: (number | [number, number])[] = [\n   *   320,\n   *   [640, 2]\n   * ]\n   * ```\n   */\n  srcset: (number | [number, number])[];\n\n  /**\n   * A list of sizes that correspond to different viewport widths, instructing the browser on which srcset source to use.\n   *\n   * @example\n   *\n   * ```typescript\n   * const sizes: string[] = [\n   *   '(max-width: 320px) 280px',\n   *   '(max-width: 480px) 440px',\n   *   '800px'\n   * ]\n   * ```\n   */\n  sizes: string[];\n}\n\n/**\n * Represents the options for rendering rich text.\n */\nexport interface StoryblokRichTextOptions<T = string, S = (tag: string, attrs: BlockAttributes, children?: T) => T> {\n  /**\n   * Defines the function that will be used to render the final HTML string (vanilla) or Framework component (React, Vue).\n   *\n   * @example\n   *\n   * ```typescript\n   * const renderFn = (tag: string, attrs: Record<string, any>, text?: string) => {\n   *  return `<${tag} ${Object.keys(attrs).map(key => `${key}=\"${attrs[key]}\"`).join(' ')}>${text}</${tag}>`\n   * }\n   *\n   * const options: StoryblokRichTextOptions = {\n   *  renderFn\n   * }\n   * ```\n   */\n  renderFn?: S;\n\n  /**\n   * Defines the function that will be used to render HTML text.\n   *\n   * @example\n   *\n   * ```typescript\n   * import { h, createTextVNode } from 'vue'\n   *\n   * const options: StoryblokRichTextOptions = {\n   *  renderFn: h,\n   *  textFn: createTextVNode\n   * }\n   * ```\n   */\n  textFn?: (text: string, attrs?: BlockAttributes) => T;\n\n  /**\n   * Defines opt-out image optimization options.\n   *\n   * @example\n   *\n   * ```typescript\n   * const options: StoryblokRichTextOptions = {\n   *  optimizeImages: true\n   * }\n   * ```\n   *\n   * @example\n   *\n   * ```typescript\n   * const options: StoryblokRichTextOptions = {\n   *    optimizeImages: {\n   *    class: 'my-image',\n   *    width: 800,\n   *    height: 600,\n   *    loading: 'lazy',\n   * }\n   * ```\n   */\n  optimizeImages?: boolean | Partial<StoryblokRichTextImageOptimizationOptions>;\n  /**\n   * Defines whether to use the key attribute in the resolvers for framework use cases.\n   * @default false\n   * @example\n   *\n   * ```typescript\n   *\n   * const options: StoryblokRichTextOptions = {\n   *  renderFn: h,\n   *  keyedResolvers: true\n   * }\n   * ```\n   */\n  keyedResolvers?: boolean;\n  /**\n   * Custom tiptap extensions to override or add node/mark rendering.\n   * Extensions are merged with the built-in defaults, overriding by key.\n   */\n  tiptapExtensions?: Record<string, any>;\n}\n","import type { BlockAttributes } from '../types';\nimport { LinkTypes } from '../types';\nimport { cleanObject } from '../utils';\n\n/**\n * Processes block-level attributes, converting textAlign to inline style\n * and preserving class/id/existing style.\n */\nexport function processBlockAttrs(attrs: BlockAttributes = {}): BlockAttributes {\n  const { textAlign, class: className, id: idName, style: existingStyle, ...rest } = attrs;\n  const styles: string[] = [];\n\n  if (existingStyle) {\n    styles.push(existingStyle.endsWith(';') ? existingStyle : `${existingStyle};`);\n  }\n\n  if (textAlign) {\n    styles.push(`text-align: ${textAlign};`);\n  }\n\n  return cleanObject({\n    ...rest,\n    class: className,\n    id: idName,\n    ...(styles.length > 0 ? { style: styles.join(' ') } : {}),\n  });\n}\n\n/**\n * Resolves a Storyblok link's attributes into a final href and remaining attrs.\n */\nexport function resolveStoryblokLink(attrs: Record<string, any> = {}): { href: string; rest: Record<string, any> } {\n  const { linktype, href, anchor, uuid, custom, ...rest } = attrs;\n\n  let finalHref = href ?? '';\n  switch (linktype) {\n    case LinkTypes.ASSET:\n    case LinkTypes.URL:\n      break;\n    case LinkTypes.EMAIL:\n      if (finalHref && !finalHref.startsWith('mailto:')) {\n        finalHref = `mailto:${finalHref}`;\n      }\n      break;\n    case LinkTypes.STORY:\n      if (anchor) {\n        finalHref = `${finalHref}#${anchor}`;\n      }\n      break;\n    default:\n      break;\n  }\n\n  return { href: finalHref, rest: { ...rest, ...(custom || {}) } };\n}\n\n/**\n * Computes table cell attributes, converting colwidth/backgroundColor/textAlign to CSS styles.\n */\nexport function computeTableCellAttrs(attrs: Record<string, any> = {}): BlockAttributes {\n  const { colspan, rowspan, colwidth, backgroundColor, textAlign, ...rest } = attrs;\n  const styles: string[] = [];\n\n  if (colwidth) {\n    styles.push(`width: ${colwidth}px;`);\n  }\n\n  if (backgroundColor) {\n    styles.push(`background-color: ${backgroundColor};`);\n  }\n\n  if (textAlign) {\n    styles.push(`text-align: ${textAlign};`);\n  }\n\n  return cleanObject({\n    ...rest,\n    ...(colspan > 1 ? { colspan } : {}),\n    ...(rowspan > 1 ? { rowspan } : {}),\n    ...(styles.length > 0 ? { style: styles.join(' ') } : {}),\n  });\n}\n\n/**\n * List of supported HTML attributes by tag name, used by the Reporter mark.\n */\nexport const supportedAttributesByTagName: Record<string, string[]> = {\n  a: ['href', 'target', 'data-uuid', 'data-anchor', 'data-linktype'],\n  img: ['alt', 'src', 'title'],\n  span: ['class'],\n} as const;\n\n/**\n * Gets allowed style classes for an element, warning on invalid ones.\n */\nexport function getAllowedStylesForElement(element: HTMLElement, { allowedStyles }: { allowedStyles: string[] }): string[] {\n  const classString = element.getAttribute('class') || '';\n  const classes = classString.split(' ').filter(Boolean);\n  if (!classes.length) {\n    return [];\n  }\n\n  const invalidStyles = classes.filter(x => !allowedStyles.includes(x));\n  for (const invalidStyle of invalidStyles) {\n    console.warn(`[StoryblokRichText] - \\`class\\` \"${invalidStyle}\" on \\`<${element.tagName.toLowerCase()}>\\` can not be transformed to rich text.`);\n  }\n\n  return allowedStyles.filter(x => classes.includes(x));\n}\n","import { Node } from '@tiptap/core';\nimport { BulletList, ListItem, OrderedList } from '@tiptap/extension-list';\nimport { Details, DetailsContent, DetailsSummary } from '@tiptap/extension-details';\nimport { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table';\nimport Blockquote from '@tiptap/extension-blockquote';\nimport CodeBlock from '@tiptap/extension-code-block';\nimport Document from '@tiptap/extension-document';\nimport Emoji from '@tiptap/extension-emoji';\nimport HardBreak from '@tiptap/extension-hard-break';\nimport Heading from '@tiptap/extension-heading';\nimport HorizontalRule from '@tiptap/extension-horizontal-rule';\nimport Image from '@tiptap/extension-image';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport Text from '@tiptap/extension-text';\nimport { optimizeImage } from '../images-optimization';\nimport type { StoryblokRichTextImageOptimizationOptions } from '../types';\nimport { cleanObject } from '../utils';\nimport { computeTableCellAttrs, processBlockAttrs } from './utils';\n\n// Re-export unmodified extensions\nexport { Details, DetailsContent, DetailsSummary, Document, Text };\n\n// Blockquote, Paragraph, Heading need processBlockAttrs for textAlign support\nexport const StoryblokBlockquote = Blockquote.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['blockquote', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\nexport const StoryblokParagraph = Paragraph.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['p', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\nexport const StoryblokHeading = Heading.extend({\n  renderHTML({ node, HTMLAttributes }) {\n    const { level, ...rest } = HTMLAttributes;\n    return [`h${node.attrs.level}`, processBlockAttrs(rest), 0];\n  },\n});\n\nexport const StoryblokTableRow = TableRow.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['tr', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\n// Storyblok uses snake_case names for some extensions\nexport const StoryblokBulletList = BulletList.extend({\n  name: 'bullet_list',\n  addOptions() {\n    return { ...this.parent!(), itemTypeName: 'list_item' };\n  },\n  renderHTML({ HTMLAttributes }) {\n    return ['ul', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\nexport const StoryblokOrderedList = OrderedList.extend({\n  name: 'ordered_list',\n  addOptions() {\n    return { ...this.parent!(), itemTypeName: 'list_item' };\n  },\n  renderHTML({ HTMLAttributes }) {\n    return ['ol', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\nexport const StoryblokListItem = ListItem.extend({\n  name: 'list_item',\n  addOptions() {\n    return { ...this.parent!(), bulletListTypeName: 'bullet_list', orderedListTypeName: 'ordered_list' };\n  },\n  renderHTML({ HTMLAttributes }) {\n    return ['li', processBlockAttrs(HTMLAttributes), 0];\n  },\n});\n\nexport const StoryblokCodeBlock = CodeBlock.extend({\n  name: 'code_block',\n  renderHTML({ node, HTMLAttributes }) {\n    const { language: _, ...rest } = HTMLAttributes;\n    const attrs = processBlockAttrs(rest);\n    const lang = node.attrs.language;\n    const codeAttrs = lang ? { class: `language-${lang}` } : {};\n    return ['pre', attrs, ['code', codeAttrs, 0]];\n  },\n});\nexport const StoryblokHardBreak = HardBreak.extend({ name: 'hard_break' });\nexport const StoryblokHorizontalRule = HorizontalRule.extend({ name: 'horizontal_rule' });\n\n// Table with custom renderHTML\n// Note: thead/tbody grouping is handled by the richtext renderer,\n// which inspects child rows to detect header vs body rows.\nexport const StoryblokTable = Table.extend({\n  renderHTML({ HTMLAttributes }) {\n    const attrs = processBlockAttrs(HTMLAttributes);\n    return ['table', attrs, 0];\n  },\n});\n\n// Table cell with custom style handling\nexport const StoryblokTableCell = TableCell.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['td', computeTableCellAttrs(HTMLAttributes), 0];\n  },\n});\n\n// Table header with custom style handling\nexport const StoryblokTableHeader = TableHeader.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['th', computeTableCellAttrs(HTMLAttributes), 0];\n  },\n});\n\n// Image with optimizeImages support\nexport const StoryblokImage = Image.extend<{ optimizeImages: boolean | Partial<StoryblokRichTextImageOptimizationOptions> }>({\n  addOptions() {\n    return { ...this.parent?.(), optimizeImages: false };\n  },\n  renderHTML({ HTMLAttributes }) {\n    const { src, alt, title, srcset, sizes } = HTMLAttributes;\n    let finalSrc = src;\n    let extraAttrs = {};\n\n    if (this.options.optimizeImages) {\n      const result = optimizeImage(src, this.options.optimizeImages);\n      finalSrc = result.src;\n      extraAttrs = result.attrs;\n    }\n\n    return ['img', cleanObject({ src: finalSrc, alt, title, srcset, sizes, ...extraAttrs })];\n  },\n});\n\n// Emoji with custom renderHTML\nexport const StoryblokEmoji = Emoji.extend({\n  renderHTML({ HTMLAttributes }) {\n    return ['span', {\n      'data-type': 'emoji',\n      'data-name': HTMLAttributes.name,\n      'data-emoji': HTMLAttributes.emoji,\n    }, ['img', {\n      src: HTMLAttributes.fallbackImage,\n      alt: HTMLAttributes.alt,\n      style: 'width: 1.25em; height: 1.25em; vertical-align: text-top',\n      draggable: 'false',\n      loading: 'lazy',\n    }]];\n  },\n});\n\n// Blok node (component placeholder for vanilla usage)\n// Configure `renderComponent` option to render blok components in framework SDKs.\n// Similar to PHP Tiptap extension's `renderer` callback:\n// https://github.com/storyblok/php-tiptap-extension/blob/main/src/Node/Blok.php\nexport const ComponentBlok = Node.create<{ renderComponent: ((blok: Record<string, unknown>, id?: string) => unknown) | null }>({\n  name: 'blok',\n  group: 'block',\n  atom: true,\n  addOptions() {\n    return {\n      renderComponent: null,\n    };\n  },\n  addAttributes() {\n    return {\n      id: { default: null },\n      body: { default: [] },\n    };\n  },\n  parseHTML() {\n    return [{ tag: 'div[data-blok]' }];\n  },\n  renderHTML({ HTMLAttributes }) {\n    console.warn('[StoryblokRichText] - BLOK resolver is not available for vanilla usage. Configure `renderComponent` option on the blok tiptapExtension.');\n    return ['span', cleanObject({\n      'data-blok': JSON.stringify(HTMLAttributes?.body?.[0] ?? null),\n      'data-blok-id': HTMLAttributes?.id,\n      'style': 'display: none',\n    })];\n  },\n});\n","import type { SBRichTextSegment, StoryblokSegmentType } from './richtext-segment';\n\nexport interface RendererAdapter<T = unknown> {\n  createElement: (\n    tag: string,\n    attrs?: Record<string, unknown>,\n    children?: T[]\n  ) => T;\n\n  createText: (text: string) => T;\n\n  createComponent?: (\n    type: StoryblokSegmentType,\n    props: Record<string, unknown>\n  ) => T;\n}\n\nfunction renderSegment<T>(\n  segment: SBRichTextSegment,\n  adapter: RendererAdapter<T>,\n  customComponents: StoryblokSegmentType[],\n  key?: number,\n): T {\n  if (segment.kind === 'text') {\n    return adapter.createText(segment.text);\n  }\n  // Treat as component if it's a real component or a custom mapped type\n  if (segment.kind === 'component') {\n    if (!adapter.createComponent) {\n      throw new Error('Component renderer not provided');\n    }\n    return adapter.createComponent(segment.type as StoryblokSegmentType, { key, ...segment.props });\n  }\n  // Node or Mark segment overrides\n  if (customComponents.includes(segment.type as StoryblokSegmentType)) {\n    if (!adapter.createComponent) {\n      throw new Error('Component renderer not provided');\n    }\n\n    // Convert NodeSegment or MarkSegment to props\n    const props = {\n      ...('attrs' in segment ? segment.attrs : {}),\n      key,\n      children: segment.content?.map((child, i) => renderSegment(child, adapter, customComponents, i)),\n    };\n\n    return adapter.createComponent(segment.type as StoryblokSegmentType, props);\n  }\n  // node or mark\n  const children = segment.content?.map((child, i) =>\n    renderSegment(child, adapter, customComponents, i),\n  ) ?? [];\n\n  if (!segment.tag) {\n    throw new Error(`Missing tag for ${segment.type}`);\n  }\n\n  return adapter.createElement(segment.tag, { ...segment.attrs, key }, children);\n}\nexport function renderSegments<T>(\n  segments: SBRichTextSegment[],\n  adapter: RendererAdapter<T>,\n  customComponents: StoryblokSegmentType[],\n): T[] {\n  return segments.map((segment, index) => renderSegment(segment, adapter, customComponents, index));\n}\n","import { Mark } from '@tiptap/core';\nimport Bold from '@tiptap/extension-bold';\nimport Code from '@tiptap/extension-code';\nimport Highlight from '@tiptap/extension-highlight';\nimport Italic from '@tiptap/extension-italic';\nimport LinkOriginal from '@tiptap/extension-link';\nimport Strike from '@tiptap/extension-strike';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport { TextStyleKit } from '@tiptap/extension-text-style';\nimport Underline from '@tiptap/extension-underline';\nimport { attrsToStyle, cleanObject } from '../utils';\nimport { getAllowedStylesForElement, resolveStoryblokLink, supportedAttributesByTagName } from './utils';\n\n// Unmodified mark extensions\nexport { Bold, Code, Highlight, Italic, Strike, Subscript, Superscript, TextStyleKit, Underline };\n\n// Link with Storyblok-specific attributes and renderHTML\nexport const StoryblokLink = LinkOriginal.extend({\n  addAttributes() {\n    return {\n      href: {\n        parseHTML: (element: HTMLElement) => element.getAttribute('href'),\n      },\n      uuid: {\n        default: null,\n        parseHTML: (element: HTMLElement) => element.getAttribute('data-uuid') || null,\n      },\n      anchor: {\n        default: null,\n        parseHTML: (element: HTMLElement) => element.getAttribute('data-anchor') || null,\n      },\n      target: {\n        parseHTML: (element: HTMLElement) => element.getAttribute('target') || null,\n      },\n      linktype: {\n        default: 'url',\n        parseHTML: (element: HTMLElement) => element.getAttribute('data-linktype') || 'url',\n      },\n    };\n  },\n  renderHTML({ HTMLAttributes }) {\n    const { href, rest } = resolveStoryblokLink(HTMLAttributes);\n    return ['a', cleanObject({ ...(href ? { href } : {}), ...rest }), 0];\n  },\n});\n\n// Link with custom attributes support\nexport const StoryblokLinkWithCustomAttributes = StoryblokLink.extend({\n  addAttributes() {\n    return {\n      ...this.parent?.(),\n      custom: {\n        default: null,\n        parseHTML: (element: HTMLElement) => {\n          const defaultLinkAttributes = supportedAttributesByTagName.a;\n          const customAttributeNames = element.getAttributeNames().filter(n => !defaultLinkAttributes.includes(n));\n          const customAttributes: Record<string, string | null> = {};\n          for (const attributeName of customAttributeNames) {\n            customAttributes[attributeName] = element.getAttribute(attributeName);\n          }\n          return Object.keys(customAttributes).length ? customAttributes : null;\n        },\n      },\n    };\n  },\n});\n\n// Anchor mark (renders as span with id)\nexport const StoryblokAnchor = Mark.create({\n  name: 'anchor',\n  addAttributes() {\n    return {\n      id: { default: null },\n    };\n  },\n  parseHTML() {\n    return [{ tag: 'span[id]' }];\n  },\n  renderHTML({ HTMLAttributes }) {\n    return ['span', { id: HTMLAttributes.id }, 0];\n  },\n});\n\nexport interface StyledOptions {\n  allowedStyles?: string[];\n}\n\n// Styled mark with whitelisted CSS classes\nexport const StoryblokStyled = Mark.create<StyledOptions>({\n  name: 'styled',\n  addAttributes() {\n    return {\n      class: {\n        parseHTML: (element: HTMLElement) => {\n          const styles = getAllowedStylesForElement(element, { allowedStyles: this.options.allowedStyles || [] });\n          return styles.length ? styles.join(' ') : null;\n        },\n      },\n    };\n  },\n  parseHTML() {\n    return [\n      {\n        tag: 'span',\n        consuming: false,\n        getAttrs: (element: HTMLElement) => {\n          const styles = getAllowedStylesForElement(element, { allowedStyles: this.options.allowedStyles || [] });\n          return styles.length ? null : false;\n        },\n      },\n    ];\n  },\n  renderHTML({ HTMLAttributes }) {\n    const { class: className, ...rest } = HTMLAttributes;\n    return ['span', cleanObject({ class: className, style: attrsToStyle(rest) || undefined }), 0];\n  },\n});\n\n// TextStyle mark\nexport const StoryblokTextStyle = Mark.create({\n  name: 'textStyle',\n  addAttributes() {\n    return {\n      class: { default: null },\n      id: { default: null },\n      color: { default: null },\n    };\n  },\n  parseHTML() {\n    return [{\n      tag: 'span',\n      consuming: false,\n      getAttrs: (element: HTMLElement) => {\n        // Only match spans with inline style containing color\n        const style = element.getAttribute('style');\n        if (style && /color/i.test(style)) {\n          return null;\n        }\n        return false;\n      },\n    }];\n  },\n  renderHTML({ HTMLAttributes }) {\n    const { class: className, id: idName, ...styleAttrs } = HTMLAttributes;\n    return ['span', cleanObject({\n      class: className,\n      id: idName,\n      style: attrsToStyle(styleAttrs) || undefined,\n    }), 0];\n  },\n});\n\n// Reporter mark: parse-only diagnostic, no renderHTML needed\nexport const Reporter = Mark.create({\n  name: 'reporter',\n  priority: 0,\n  addOptions() {\n    return {\n      allowCustomAttributes: false,\n    };\n  },\n  parseHTML() {\n    return [\n      {\n        tag: '*',\n        consuming: false,\n        getAttrs: (element: HTMLElement) => {\n          const tagName = element.tagName.toLowerCase();\n          if (tagName === 'a' && this.options.allowCustomAttributes) {\n            return false;\n          }\n\n          const unsupportedAttributes = element.getAttributeNames().filter((attr) => {\n            const supportedAttrs = tagName in supportedAttributesByTagName ? supportedAttributesByTagName[tagName] : [];\n            return !supportedAttrs.includes(attr);\n          });\n          for (const attr of unsupportedAttributes) {\n            console.warn(`[StoryblokRichText] - \\`${attr}\\` \"${element.getAttribute(attr)}\" on \\`<${tagName}>\\` can not be transformed to rich text.`);\n          }\n\n          return false;\n        },\n      },\n    ];\n  },\n});\n","import type { Extension, Mark, Node } from '@tiptap/core';\nimport type { StoryblokRichTextImageOptimizationOptions } from '../types';\nimport {\n  ComponentBlok,\n  Details,\n  DetailsContent,\n  DetailsSummary,\n  Document,\n  StoryblokBlockquote,\n  StoryblokBulletList,\n  StoryblokCodeBlock,\n  StoryblokEmoji,\n  StoryblokHardBreak,\n  StoryblokHeading,\n  StoryblokHorizontalRule,\n  StoryblokImage,\n  StoryblokListItem,\n  StoryblokOrderedList,\n  StoryblokParagraph,\n  StoryblokTable,\n  StoryblokTableCell,\n  StoryblokTableHeader,\n  StoryblokTableRow,\n  Text,\n} from './nodes';\nimport {\n  Bold,\n  Code,\n  Highlight,\n  Italic,\n  Reporter,\n  StoryblokAnchor,\n  StoryblokLink,\n  StoryblokLinkWithCustomAttributes,\n  StoryblokStyled,\n  StoryblokTextStyle,\n  Strike,\n  Subscript,\n  Superscript,\n  Underline,\n} from './marks';\n\nexport interface StyleOption {\n  name: string;\n  value: string;\n}\n\nexport interface HTMLParserOptions {\n  allowCustomAttributes?: boolean;\n  preserveWhitespace?: boolean | 'full';\n  tiptapExtensions?: Partial<typeof defaultExtensions & Record<string, Extension | Mark | Node>>;\n  styleOptions?: StyleOption[];\n}\n\nexport interface StoryblokExtensionOptions {\n  optimizeImages?: boolean | Partial<StoryblokRichTextImageOptimizationOptions>;\n  allowCustomAttributes?: boolean;\n  styleOptions?: StyleOption[];\n}\n\nconst defaultExtensions = {\n  document: Document,\n  text: Text,\n  paragraph: StoryblokParagraph,\n  blockquote: StoryblokBlockquote,\n  heading: StoryblokHeading,\n  bulletList: StoryblokBulletList,\n  orderedList: StoryblokOrderedList,\n  listItem: StoryblokListItem,\n  codeBlock: StoryblokCodeBlock,\n  hardBreak: StoryblokHardBreak,\n  horizontalRule: StoryblokHorizontalRule,\n  image: StoryblokImage,\n  emoji: StoryblokEmoji,\n  table: StoryblokTable,\n  tableRow: StoryblokTableRow,\n  tableCell: StoryblokTableCell,\n  tableHeader: StoryblokTableHeader,\n  blok: ComponentBlok,\n  details: Details,\n  detailsContent: DetailsContent,\n  detailsSummary: DetailsSummary,\n  bold: Bold,\n  italic: Italic,\n  strike: Strike,\n  underline: Underline,\n  code: Code,\n  superscript: Superscript,\n  subscript: Subscript,\n  highlight: Highlight,\n  textStyle: StoryblokTextStyle,\n  link: StoryblokLink as typeof StoryblokLink,\n  anchor: StoryblokAnchor,\n  styled: StoryblokStyled,\n  reporter: Reporter,\n};\n\nexport { defaultExtensions };\n\nexport function getStoryblokExtensions(options: StoryblokExtensionOptions = {}) {\n  const Link = options.allowCustomAttributes ? StoryblokLinkWithCustomAttributes : StoryblokLink;\n\n  return {\n    ...defaultExtensions,\n    image: StoryblokImage.configure({ optimizeImages: options.optimizeImages || false }),\n    link: Link,\n    styled: StoryblokStyled.configure({ allowedStyles: options.styleOptions?.map(o => o.value) }),\n    reporter: Reporter.configure({ allowCustomAttributes: options.allowCustomAttributes }),\n  };\n}\n\nexport * from './marks';\nexport * from './nodes';\nexport { computeTableCellAttrs, processBlockAttrs, resolveStoryblokLink } from './utils';\n","import { getStoryblokExtensions } from './extensions';\nimport type { BlockAttributes, MarkNode, StoryblokRichTextDocumentNode, StoryblokRichTextNode, StoryblokRichTextOptions, TextNode } from './types';\nimport { attrsToString, collectMarkedTextGroup, escapeHtml, getUniqueMarks, SELF_CLOSING_TAGS } from './utils';\n\n/**\n * Default render function that creates an HTML string for a given tag, attributes, and children.\n */\nfunction defaultRenderFn<T = string | null>(tag: string, attrs: BlockAttributes = {}, children?: T): T {\n  const attrsString = attrsToString(attrs);\n  const tagString = attrsString ? `${tag} ${attrsString}` : tag;\n  const content = Array.isArray(children) ? children.join('') : children || '';\n\n  if (!tag) {\n    return content as unknown as T;\n  }\n  else if (SELF_CLOSING_TAGS.includes(tag)) {\n    return `<${tagString}>` as unknown as T;\n  }\n  return `<${tagString}>${content}</${tag}>` as unknown as T;\n}\n\n/**\n * Converts a ProseMirror DOMOutputSpec array to renderFn calls.\n */\nfunction specToRender<T>(\n  spec: any[],\n  renderFn: (tag: string, attrs?: BlockAttributes, children?: T) => T,\n  children: T | undefined,\n): T {\n  const [tag, ...rest] = spec;\n  let attrs: BlockAttributes = {};\n  let content = rest;\n\n  // First non-array, non-number, non-null plain object = attributes\n  if (\n    content.length > 0\n    && content[0] !== null\n    && content[0] !== undefined\n    && typeof content[0] === 'object'\n    && !Array.isArray(content[0])\n    && typeof content[0] !== 'number'\n  ) {\n    attrs = content[0] as BlockAttributes;\n    content = content.slice(1);\n  }\n\n  // Filter nulls (Table extension can produce them)\n  content = content.filter((c: any) => c !== null && c !== undefined);\n\n  // No content → self-closing (img, hr, br)\n  if (content.length === 0) {\n    return renderFn(tag, attrs) as T;\n  }\n\n  // Content hole (0) → insert children\n  if (content.length === 1 && content[0] === 0) {\n    return renderFn(tag, attrs, children) as T;\n  }\n\n  // Nested specs → recursive\n  const nested = content.map((item: any) => {\n    if (item === 0) {\n      return children;\n    }\n    if (Array.isArray(item)) {\n      return specToRender(item, renderFn, children);\n    }\n    return item;\n  });\n\n  return renderFn(tag, attrs, nested.length === 1 ? nested[0] : nested) as T;\n}\n\n/**\n * Calls renderHTML on a tiptap extension.\n */\nfunction callExtensionRenderHTML(ext: any, type: 'node' | 'mark', attrs: Record<string, any>): any[] {\n  const thisContext = { options: ext.options || {}, name: ext.name, type: ext.type };\n  if (type === 'node') {\n    return ext.config.renderHTML.call(thisContext, {\n      node: { attrs },\n      HTMLAttributes: attrs,\n    });\n  }\n  return ext.config.renderHTML.call(thisContext, {\n    mark: { attrs },\n    HTMLAttributes: attrs,\n  });\n}\n\n/**\n * Creates a rich text resolver with the given options.\n */\nexport function richTextResolver<T>(options: StoryblokRichTextOptions<T> = {}) {\n  const keyCounters = new Map<string, number>();\n\n  const {\n    renderFn = defaultRenderFn,\n    textFn = escapeHtml,\n    optimizeImages = false,\n    keyedResolvers = false,\n    tiptapExtensions,\n  } = options;\n  const isExternalRenderFn = renderFn !== defaultRenderFn;\n\n  // Get extensions configured with runtime options, merged with user overrides\n  const baseExtensions = getStoryblokExtensions({ optimizeImages });\n  const allExtensions = tiptapExtensions\n    ? { ...baseExtensions, ...tiptapExtensions }\n    : baseExtensions;\n  const extensionValues = Object.values(allExtensions);\n\n  // Build lookup maps: type name → extension config\n  const nodeExtMap = new Map<string, any>();\n  const markExtMap = new Map<string, any>();\n  for (const ext of extensionValues) {\n    if (ext.type === 'node') {\n      nodeExtMap.set(ext.name, ext);\n    }\n    else if (ext.type === 'mark') {\n      markExtMap.set(ext.name, ext);\n    }\n  }\n\n  // Wrap renderFn with auto-keying\n  const contextRenderFn = (tag: string, attrs: BlockAttributes = {}, children?: T): T => {\n    if (keyedResolvers && tag) {\n      const currentCount = keyCounters.get(tag) || 0;\n      keyCounters.set(tag, currentCount + 1);\n      attrs = { ...attrs, key: `${tag}-${currentCount}` };\n    }\n    return renderFn(tag, attrs, children);\n  };\n\n  // --- Mark merging (ProseMirror-style adjacent text node grouping) ---\n\n  /** Renders a group of text nodes with shared marks wrapped once around unique-mark content. */\n  function renderMergedTextNodes(group: TextNode<T>[], shared: MarkNode<T>[]): T {\n    const innerRendered = group.map((node) => {\n      return renderText({ ...node, marks: getUniqueMarks(node.marks || [], shared) } as TextNode<T>);\n    });\n\n    let content: T = isExternalRenderFn\n      ? innerRendered as unknown as T\n      : innerRendered.join('') as unknown as T;\n\n    // Forward order: matches renderText's marks.reduce() where marks[0] wraps first\n    // (innermost) and marks[last] wraps last (outermost).\n    for (const mark of shared) {\n      const ext = markExtMap.get(mark.type);\n      if (!ext?.config?.renderHTML) {\n        continue;\n      }\n      const markAttrs = mark.attrs || {};\n      const spec = callExtensionRenderHTML(ext, 'mark', markAttrs);\n      content = specToRender(spec, contextRenderFn, content);\n    }\n\n    return content;\n  }\n\n  /** Groups adjacent text nodes with shared marks and renders them merged. */\n  function groupAndRenderChildren(children: StoryblokRichTextNode<T>[]): T[] {\n    const result: T[] = [];\n    let i = 0;\n    while (i < children.length) {\n      const match = collectMarkedTextGroup(children, i);\n      if (!match) {\n        result.push(render(children[i]));\n        i++;\n        continue;\n      }\n      if (match.group.length === 1) {\n        result.push(renderText(match.group[0]));\n      }\n      else {\n        result.push(renderMergedTextNodes(match.group, match.shared));\n      }\n      i = match.endIndex;\n    }\n    return result;\n  }\n\n  function renderNode(node: StoryblokRichTextNode<T>): T {\n    // Text nodes — apply marks via reduce\n    if (node.type === 'text') {\n      return renderText(node as TextNode<T>);\n    }\n\n    // Document node renders without wrapper\n    if (node.type === 'doc') {\n      return render(node);\n    }\n\n    // Find extension and call renderHTML\n    const ext = nodeExtMap.get(node.type);\n    if (!ext?.config?.renderHTML) {\n      console.error('<Storyblok>', `No extension found for node type ${node.type}`);\n      return '' as unknown as T;\n    }\n\n    // Check for renderComponent option (e.g., blok nodes configured via tiptapExtensions)\n    if (ext.options?.renderComponent) {\n      const body = node.attrs?.body;\n      const id = node.attrs?.id;\n      if (!Array.isArray(body) || body.length === 0) {\n        return (isExternalRenderFn ? [] : '') as unknown as T;\n      }\n      const rendered = body.map((blok: Record<string, unknown>) => ext.options.renderComponent(blok, id));\n      return (isExternalRenderFn ? rendered : rendered.filter((r: unknown) => r != null).join('')) as unknown as T;\n    }\n\n    // Table: group rows into thead/tbody based on cell types\n    if (node.type === 'table' && node.content?.length) {\n      const headerRows: StoryblokRichTextNode<T>[] = [];\n      const bodyRows: StoryblokRichTextNode<T>[] = [];\n      for (const row of node.content) {\n        const isHeaderRow = bodyRows.length === 0\n          && row.content?.every((cell: StoryblokRichTextNode<T>) => cell.type === 'tableHeader');\n        if (isHeaderRow) {\n          headerRows.push(row);\n        }\n        else {\n          bodyRows.push(row);\n        }\n      }\n      const nodeAttrs = node.attrs || {};\n      const spec = callExtensionRenderHTML(ext, 'node', nodeAttrs);\n      const parts: T[] = [];\n      if (headerRows.length > 0) {\n        parts.push(contextRenderFn('thead', {}, headerRows.map(render) as T));\n      }\n      if (bodyRows.length > 0) {\n        parts.push(contextRenderFn('tbody', {}, bodyRows.map(render) as T));\n      }\n      return specToRender(spec, contextRenderFn, parts as T | undefined) as T;\n    }\n\n    const children = node.content ? groupAndRenderChildren(node.content) : undefined;\n\n    const nodeAttrs = node.attrs || {};\n    const spec = callExtensionRenderHTML(ext, 'node', nodeAttrs);\n    return specToRender(spec, contextRenderFn, children as T | undefined) as T;\n  }\n\n  function renderText(node: TextNode<T>): T {\n    const { marks, ...rest } = node;\n\n    if (marks?.length) {\n      // Base text\n      const baseText = (() => {\n        const attrs: BlockAttributes = {};\n        if (keyedResolvers) {\n          const currentCount = keyCounters.get('txt') || 0;\n          keyCounters.set('txt', currentCount + 1);\n          attrs.key = `txt-${currentCount}`;\n        }\n        return textFn(rest.text, attrs) as T;\n      })();\n\n      // Apply marks as reduce: text → mark1(text) → mark2(mark1(text))\n      return marks.reduce((text: T, mark: MarkNode<T>) => {\n        const ext = markExtMap.get(mark.type);\n        if (!ext?.config?.renderHTML) {\n          console.error('<Storyblok>', `No extension found for node type ${mark.type}`);\n          return text;\n        }\n\n        const markAttrs = mark.attrs || {};\n        const spec = callExtensionRenderHTML(ext, 'mark', markAttrs);\n        return specToRender(spec, contextRenderFn, text) as T;\n      }, baseText);\n    }\n\n    // Plain text, no marks\n    const attrs: BlockAttributes = node.attrs || {};\n    if (keyedResolvers) {\n      const currentCount = keyCounters.get('txt') || 0;\n      keyCounters.set('txt', currentCount + 1);\n      attrs.key = `txt-${currentCount}`;\n    }\n    return textFn(rest.text, attrs) as T;\n  }\n\n  function render(node: StoryblokRichTextNode<T> | StoryblokRichTextDocumentNode): T {\n    const n = node as StoryblokRichTextNode<T>;\n    if (n.type === 'doc') {\n      return isExternalRenderFn ? n.content.map(renderNode) as T : n.content.map(renderNode).join('') as T;\n    }\n    return Array.isArray(n) ? n.map(renderNode) as T : renderNode(n) as T;\n  }\n\n  return {\n    render,\n  };\n}\n","import { ComponentBlok, getStoryblokExtensions } from './extensions';\nimport type { Attributes, Mark as TiptapMark, Node as TiptapNode } from '@tiptap/core';\nimport type { BlockAttributes, MarkNode, StoryblokRichTextNode, TextNode } from './types';\nimport { collectMarkedTextGroup, getUniqueMarks, SELF_CLOSING_TAGS } from './utils';\n\n/**\n * ProseMirror DOMOutputSpec returned by renderHTML\n */\ntype DOMOutputSpec = (string | number | Attributes | DOMOutputSpec)[];\n\n/**\n * Segment Types\n */\n\nexport interface TextSegment {\n  kind: 'text';\n  text: string;\n}\n\nexport interface NodeSegment {\n  kind: 'node';\n  type: string;\n  tag: string | null;\n  attrs: Attributes;\n  content: SBRichTextSegment[];\n}\n\nexport interface MarkSegment {\n  kind: 'mark';\n  type: string;\n  tag: string | null;\n  attrs: Attributes;\n  content: SBRichTextSegment[];\n}\ninterface ComponentSegment {\n  kind: 'component';\n  type: string;\n  props: Record<string, unknown>;\n}\nexport type SBRichTextSegment =\n  | TextSegment\n  | NodeSegment\n  | MarkSegment\n  | ComponentSegment;\n\nexport type StoryblokExtensions = ReturnType<typeof getStoryblokExtensions>;\nexport type StoryblokSegmentType = keyof StoryblokExtensions; // e.g., \"paragraph\" | \"heading\" | \"image\" | ...\n/**\n * Renderer Options\n */\nexport interface StoryblokRichTextOptionsNew {\n  optimizeImages?: boolean;\n\n  /**\n   * Called when a node has no extension renderer\n   */\n  onUnknownNode?: (node: StoryblokRichTextNode) => SBRichTextSegment[];\n\n  /**\n   * Called when a mark has no extension renderer\n   */\n  onUnknownMark?: (mark: any) => SBRichTextSegment[];\n}\nexport function getRichTextSegments(richText: StoryblokRichTextNode, options: StoryblokRichTextOptionsNew = {}) {\n  const blokExtension = {\n    blok: ComponentBlok.configure({\n      renderComponent: blok => blok,\n    }),\n  };\n  const extensions = Object.values(\n    { ...getStoryblokExtensions({ optimizeImages: options.optimizeImages }), ...blokExtension },\n  );\n  // Build lookup maps: type name → extension config\n  const nodeExtMap = new Map<string, TiptapNode>();\n  const markExtMap = new Map<string, TiptapMark>();\n  for (const ext of extensions) {\n    if (ext.type === 'node') {\n      nodeExtMap.set(ext.name, ext as TiptapNode);\n    }\n    if (ext.type === 'mark') {\n      markExtMap.set(ext.name, ext as TiptapMark);\n    }\n  }\n\n  // --- Mark merging (ProseMirror-style adjacent text node grouping) ---\n\n  /** Renders a group of text nodes with shared marks wrapped once around unique-mark content. */\n  function renderMergedTextNodes(group: TextNode<string>[], shared: MarkNode<string>[]): SBRichTextSegment[] {\n    const innerSegments: SBRichTextSegment[] = group.flatMap((node) => {\n      return renderText({ ...node, marks: getUniqueMarks(node.marks || [], shared) } as TextNode<string>);\n    });\n\n    // Reverse: matches renderText's [...marks].reverse() iteration order,\n    // where the last mark in the array becomes the outermost segment wrapper.\n    let segments: SBRichTextSegment[] = innerSegments;\n    for (let i = shared.length - 1; i >= 0; i--) {\n      const mark = shared[i];\n      const ext = markExtMap.get(mark.type);\n      if (!ext?.config?.renderHTML) {\n        continue;\n      }\n      const attrs = mark.attrs ?? {};\n      const spec = callExtensionRenderHTML(ext, attrs);\n      const tag = getTagFromSpec(spec);\n      segments = [{\n        kind: 'mark' as const,\n        type: mark.type,\n        tag,\n        attrs,\n        content: segments,\n      }];\n    }\n\n    return segments;\n  }\n\n  /** Groups adjacent text nodes with shared marks and renders them merged. */\n  function groupAndFlatMapChildren(children: StoryblokRichTextNode[]): SBRichTextSegment[] {\n    const result: SBRichTextSegment[] = [];\n    let i = 0;\n    while (i < children.length) {\n      const match = collectMarkedTextGroup<string>(children, i);\n      if (!match) {\n        result.push(...renderNode(children[i]));\n        i++;\n        continue;\n      }\n      if (match.group.length === 1) {\n        result.push(...renderText(match.group[0]));\n      }\n      else {\n        result.push(...renderMergedTextNodes(match.group, match.shared));\n      }\n      i = match.endIndex;\n    }\n    return result;\n  }\n\n  // --- End mark merging helpers ---\n\n  function renderNode(node: StoryblokRichTextNode): SBRichTextSegment[] {\n    if (node.type === 'text') {\n      return renderText(node as TextNode<string>);\n    }\n    if (node.type === 'doc') {\n      return node.content?.flatMap(renderNode) ?? [];\n    }\n\n    const children = node.content ? groupAndFlatMapChildren(node.content) : [];\n    const ext = nodeExtMap.get(node.type);\n\n    if (!ext?.config?.renderHTML) {\n      return options.onUnknownNode?.(node) ?? children;\n    }\n    const component = tryRenderComponent(ext, node.attrs || {}, node.type);\n\n    if (component) {\n      return [component];\n    }\n    const attrs = node.attrs || {};\n\n    const spec = callExtensionRenderHTML(ext, attrs);\n    const segment = parseDOMSpec(\n      spec,\n      node.type,\n      children,\n    );\n\n    return [segment];\n  }\n\n  /**\n   * Render text nodes + marks\n   */\n  function renderText(node: TextNode<string>): SBRichTextSegment[] {\n    let segments: SBRichTextSegment[] = [\n      {\n        kind: 'text',\n        text: node.text,\n      },\n    ];\n\n    if (!node.marks?.length) {\n      return segments;\n    }\n\n    /**\n     * reverse to maintain correct nesting order\n     */\n    for (const mark of [...node.marks].reverse()) {\n      const ext = markExtMap.get(mark.type);\n\n      if (!ext?.config?.renderHTML) {\n        segments\n          = options.onUnknownMark?.(mark)\n            ?? segments;\n        continue;\n      }\n\n      const attrs = mark.attrs ?? {};\n\n      const spec = callExtensionRenderHTML(ext, attrs);\n      const tag = getTagFromSpec(spec);\n\n      segments = segments.map(seg => ({\n        kind: 'mark',\n        type: mark.type,\n        tag,\n        attrs,\n        content: [seg],\n      }));\n    }\n\n    return segments;\n  }\n  return renderNode(richText);\n}\n/**\n * Call renderHTML safely\n */\nfunction callExtensionRenderHTML(\n  ext: TiptapNode | TiptapMark,\n  attrs: Attributes,\n): DOMOutputSpec {\n  const render = ext.config.renderHTML;\n\n  if (!render) {\n    throw new Error(`Extension \"${ext.name}\" does not define renderHTML`);\n  }\n  const ctx = {\n    name: ext.name,\n    options: ext.options ?? {},\n    parent: null,\n  };\n\n  if (ext.type === 'node') {\n    return (render as any).call(ctx, {\n      node: { attrs },\n      HTMLAttributes: attrs,\n    }) as DOMOutputSpec;\n  }\n\n  return (render as any).call(ctx, {\n    mark: { attrs },\n    HTMLAttributes: attrs,\n  }) as DOMOutputSpec;\n}\n\n/**\n * Extract tag from DOMOutputSpec\n */\nfunction getTagFromSpec(spec: DOMOutputSpec): string | null {\n  const first = spec?.[0];\n  return typeof first === 'string' ? first : null;\n}\nexport function isVoidElement(tag: string) {\n  return SELF_CLOSING_TAGS.includes(tag);\n}\n\nfunction tryRenderComponent(\n  ext: TiptapNode,\n  attrs: BlockAttributes,\n  type: string,\n): ComponentSegment | null {\n  const renderComponent = (ext.options as any)?.renderComponent;\n\n  if (typeof renderComponent !== 'function') {\n    return null;\n  }\n\n  const result = renderComponent(attrs);\n\n  return {\n    kind: 'component',\n    type,\n    props: {\n      ...(result ?? {}),\n    },\n  };\n}\nfunction parseDOMSpec(\n  spec: DOMOutputSpec,\n  nodeType: string,\n  fallbackChildren: SBRichTextSegment[],\n): NodeSegment {\n  const [tag, maybeAttrs, ...rest] = spec;\n\n  let attrs: Attributes = {};\n  let childrenSpec: any[] = [];\n\n  if (isAttributes(maybeAttrs)) {\n    attrs = maybeAttrs;\n    childrenSpec = rest;\n  }\n  else {\n    childrenSpec = [maybeAttrs, ...rest];\n  }\n\n  let content: SBRichTextSegment[] = [];\n\n  for (const child of childrenSpec) {\n    if (child === 0) {\n      // Insert node children here\n      content.push(...fallbackChildren);\n      continue;\n    }\n\n    if (Array.isArray(child)) {\n      content.push(parseDOMSpec(child, nodeType, fallbackChildren));\n      continue;\n    }\n\n    if (typeof child === 'string') {\n      content.push({\n        kind: 'text',\n        text: child,\n      });\n    }\n  }\n  // --- TABLE FIX ---\n  if (tag === 'table') {\n    const headerRows: NodeSegment[] = [];\n    const bodyRows: NodeSegment[] = [];\n\n    for (const row of content as NodeSegment[]) {\n      if (\n        row.tag === 'tr'\n        && row.content.every(cell => (cell as NodeSegment).tag === 'th')\n      ) {\n        headerRows.push(row);\n      }\n      else {\n        bodyRows.push(row as NodeSegment);\n      }\n    }\n\n    content = [];\n\n    if (headerRows.length) {\n      content.push({\n        kind: 'node',\n        type: 'thead',\n        tag: 'thead',\n        attrs: {},\n        content: headerRows,\n      });\n    }\n\n    if (bodyRows.length) {\n      content.push({\n        kind: 'node',\n        type: 'tbody',\n        tag: 'tbody',\n        attrs: {},\n        content: bodyRows,\n      });\n    }\n  }\n  return {\n    kind: 'node',\n    type: nodeType,\n    tag: typeof tag === 'string' ? tag : null,\n    attrs,\n    content,\n  };\n}\nfunction isAttributes(value: unknown): value is Attributes {\n  return (\n    typeof value === 'object'\n    && value !== null\n    && !Array.isArray(value)\n  );\n}\n\n/**\n * Parses an inline CSS style string into an object.\n *\n * Example:\n *   parseStyleString(\"width: 1.25em; height: 1.25em; vertical-align: text-top\")\n *   -> { width: \"1.25em\", height: \"1.25em\", \"vertical-align\": \"text-top\" }\n */\nexport function parseStyleString(style: string): Record<string, string> {\n  const result: Record<string, string> = {};\n\n  if (!style) {\n    return {\n      ...result,\n    };\n  }\n\n  // Split by semicolon and remove empty entries\n  style.split(';').forEach((rule) => {\n    const [prop, value] = rule.split(':');\n\n    if (!prop || !value) {\n      return;\n    }\n\n    result[prop.trim()] = value.trim();\n  });\n\n  return result;\n}\n","import type { StoryblokRichTextNode, StoryblokRichTextOptions } from '../types';\nimport { richTextResolver } from '../richtext';\nimport { ComponentBlok } from '../extensions/nodes';\nimport type { ISbComponentType } from 'storyblok-js-client';\n\nexport type SbBlokKeyDataTypes = string | number | object | boolean | undefined;\n\nexport interface SbBlokData extends ISbComponentType<string> {\n  [index: string]: SbBlokKeyDataTypes;\n}\nexport interface RichTextHtmlSegment {\n  type: 'html';\n  content: string;\n}\nexport interface RichTextBlokSegment {\n  type: 'blok';\n  blok: SbBlokData;\n};\nexport type RichTextSegment = RichTextHtmlSegment | RichTextBlokSegment;\n\nconst BLOK_MARKER_PREFIX = 'SB_BLOK_GROUP_';\nconst BLOK_MARKER_REGEX = /<!--SB_BLOK_GROUP_(\\d+)-->/;\n\n/**\n * Converts a Storyblok Rich Text document into a linear list of segments.\n *\n * The returned segments preserve the original content order and consist of:\n * - HTML segments for regular rich text content\n * - Blok segments for embedded Storyblok components\n *\n * This allows consumers to render HTML normally while handling Storyblok\n * components separately using framework-specific logic.\n *\n * @param doc - The Storyblok Rich Text document to process\n * @param options - Optional rich text resolver options\n * @returns An ordered array of rich text segments (HTML and bloks)\n *\n * @example\n * ```ts\n * const segments = segmentStoryblokRichText(richTextDoc);\n *\n * for (const segment of segments) {\n *   if (segment.type === 'html') {\n *     renderHtml(segment.content);\n *   }\n *\n *   if (segment.type === 'blok') {\n *     renderBlokComponent(segment.blok);\n *   }\n * }\n * ```\n */\nexport function segmentStoryblokRichText(\n  doc: StoryblokRichTextNode<string>,\n  options: StoryblokRichTextOptions<string> = {},\n): RichTextSegment[] {\n  const segments: RichTextSegment[] = [];\n  const blokGroups: SbBlokData[][] = [];\n  const resolver: StoryblokRichTextOptions<string> = {\n    ...options,\n    tiptapExtensions: {\n      blok: ComponentBlok.configure({\n        renderComponent: (blok: Record<string, unknown>) => {\n          const body = [blok];\n          const index = blokGroups.push(body as SbBlokData[]) - 1;\n          return `<!--${BLOK_MARKER_PREFIX}${index}-->`;\n        },\n      }),\n      ...options.tiptapExtensions,\n    },\n  };\n  const html = richTextResolver<string>(resolver).render(doc);\n  const parts = html.split(BLOK_MARKER_REGEX);\n\n  for (let i = 0; i < parts.length; i++) {\n    if (i % 2 === 0) {\n      const htmlPart = parts[i];\n      if (htmlPart && htmlPart.trim()) {\n        segments.push({ type: 'html', content: htmlPart });\n      }\n    }\n    else {\n      const groupIndex = Number(parts[i]);\n      const bloks = blokGroups[groupIndex];\n      if (bloks) {\n        for (const blok of bloks) {\n          segments.push({ type: 'blok', blok });\n        }\n      }\n    }\n  }\n  return segments;\n}\n","export { ComponentBlok } from './extensions/nodes';\nexport * from './render-segments';\nexport * from './richtext';\nexport * from './richtext-segment';\nexport * from './types';\nexport * from './utils/segment-richtext';\n/**\n * Wraps a framework component (React, Vue, etc.) for use as a tag\n * in Tiptap's `renderHTML` DOMOutputSpec.\n *\n * Tiptap's `DOMOutputSpec` type only accepts strings at position 0,\n * but the Storyblok richtext resolver also handles component references.\n * Use this helper to satisfy TypeScript without a manual `as unknown as string` type assertion.\n *\n * @example\n * ```typescript\n * import { Mark } from '@tiptap/core';\n * import { asTag } from '@storyblok/vue'; // or @storyblok/react\n * import { RouterLink } from 'vue-router';\n *\n * const CustomLink = Mark.create({\n *   name: 'link',\n *   renderHTML({ HTMLAttributes }) {\n *     return [asTag(RouterLink), { to: HTMLAttributes.href }, 0];\n *   },\n * });\n * ```\n */\nexport function asTag(component: unknown): string {\n  return component as string;\n}\n"],"mappings":"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"}