{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "split-consensus-diagram-vertical-viewer-block",
  "title": "Split Consensus Diagram Vertical",
  "description": "A split consensus segment diagram with the page axis running vertically for a narrow sidebar beside the PDF.",
  "registryDependencies": [
    "@retab/file-viewer",
    "@retab/pdf-viewer",
    "@retab/segment-legend",
    "@retab/page-ribbon",
    "@retab/use-segment-interaction"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/blocks/split-consensus-diagram-vertical-viewer-block.tsx",
      "content": "\"use client\";\n\nimport { SplitConsensusSegmentDiagramViewer } from \"@/components/blocks/split-consensus-segment-diagram\";\n\nexport function SplitConsensusDiagramVerticalViewerBlock() {\n  return <SplitConsensusSegmentDiagramViewer orientation=\"vertical\" />;\n}\n",
      "type": "registry:component",
      "target": "@components/blocks/split-consensus-diagram-vertical-viewer-block.tsx"
    },
    {
      "path": "registry/new-york-v4/blocks/split-consensus-segment-diagram.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n  FileViewer,\n  FileViewerContent,\n  FileViewerControls,\n  FileViewerHeader,\n  FileViewerInset,\n  FileViewerLegend,\n  FileViewerProvider,\n  FileViewerSidebar,\n  FileViewerSidebarContent,\n  FileViewerSidebarHeader,\n  FileViewerSidebarTrigger,\n  FileViewerTitle,\n  FileViewerViewport,\n} from \"@/components/ui/file-viewer\";\nimport {\n  PdfViewerPages,\n  PdfViewerProvider,\n  type PdfViewerHandle,\n} from \"@/components/ui/pdf-viewer\";\nimport { PageRibbon, type RibbonRow } from \"@/components/ui/page-ribbon\";\nimport { SegmentLegend } from \"@/components/ui/segment-legend\";\nimport type { DocumentSegment } from \"@/components/ui/segmented-document-model\";\nimport { useSegmentInteraction } from \"@/components/ui/use-segment-interaction\";\n\ntype SegmentVoteCounts = Record<string, number>;\n\ntype Segment = {\n  type: string;\n  startPage: number;\n  endPage: number;\n};\n\ntype SegmentRow = {\n  id: string;\n  label: string;\n  shortLabel: string;\n  ribbonSegments: DocumentSegment[];\n};\n\ntype SegmentDiagramDoc = {\n  fileName: string;\n  label: string;\n  pageCount: number;\n  pdfUrl: string;\n  legendSegments: DocumentSegment[];\n  rows: SegmentRow[];\n  ribbonRows: RibbonRow[];\n  diffRibbonRow: RibbonRow;\n};\n\ntype DiagramOrientation = \"horizontal\" | \"vertical\";\ntype DiagramSegmentInteraction = ReturnType<typeof useSegmentInteraction>;\n\nconst HARRIS_SOURCE = {\n  kind: \"url\" as const,\n  url: \"/samples/harris_2023_federal_state_returns.pdf\",\n  fileName: \"harris_2023_federal_state_returns.pdf\",\n};\n\nconst TYPE_COLORS = new Map<string, string>([\n  [\"Form 1040\", \"#4E79A7\"],\n  [\"misc_form\", \"#F28E2B\"],\n  [\"Schedule 2 (Form 1040)\", \"#59A14F\"],\n  [\"Schedule B (Form 1040)\", \"#B6992D\"],\n  [\"Schedule H (Form 1040)\", \"#499894\"],\n  [\"supplement\", \"#E15759\"],\n  [\"Form 8960\", \"#A0CBE8\"],\n  [\"Schedule 1 (Form 1040)\", \"#FFBE7D\"],\n  [\"Schedule A (Form 1040)\", \"#8CD17D\"],\n  [\"Schedule C (Form 1040)\", \"#F1CE63\"],\n  [\"Schedule SE (Form 1040)\", \"#86BCB6\"],\n]);\n\nconst TYPE_ORDER = Array.from(TYPE_COLORS.keys());\n\n/** Floor for the diff shading so a single dissenting vote still reads clearly. */\nconst DIFF_MIN_PERCENT = 40;\nconst VERTICAL_LANE_WIDTH = 32;\n\nconst VOTE_SEGMENTS: Segment[][] = [\n  [\n    segment(\"Form 1040\", 1, 2),\n    segment(\"Schedule 1 (Form 1040)\", 3, 4),\n    segment(\"Schedule 2 (Form 1040)\", 5, 6),\n    segment(\"Schedule A (Form 1040)\", 7, 7),\n    segment(\"Schedule B (Form 1040)\", 8, 8),\n    segment(\"Schedule C (Form 1040)\", 9, 9),\n    segment(\"Schedule SE (Form 1040)\", 10, 10),\n    segment(\"Schedule H (Form 1040)\", 11, 12),\n    segment(\"misc_form\", 13, 13),\n    segment(\"Form 8960\", 14, 14),\n    segment(\"supplement\", 15, 20),\n    segment(\"misc_form\", 21, 40),\n  ],\n  [\n    segment(\"Form 1040\", 1, 2),\n    segment(\"Schedule 1 (Form 1040)\", 3, 4),\n    segment(\"Schedule 2 (Form 1040)\", 5, 6),\n    segment(\"Schedule A (Form 1040)\", 7, 7),\n    segment(\"Schedule B (Form 1040)\", 8, 8),\n    segment(\"Schedule C (Form 1040)\", 9, 9),\n    segment(\"Schedule SE (Form 1040)\", 10, 10),\n    segment(\"Schedule H (Form 1040)\", 11, 12),\n    segment(\"misc_form\", 13, 13),\n    segment(\"Form 8960\", 14, 14),\n    segment(\"supplement\", 15, 20),\n    segment(\"misc_form\", 21, 39),\n    segment(\"supplement\", 40, 40),\n  ],\n  [\n    segment(\"Form 1040\", 1, 2),\n    segment(\"Schedule 1 (Form 1040)\", 3, 4),\n    segment(\"Schedule 2 (Form 1040)\", 5, 6),\n    segment(\"Schedule A (Form 1040)\", 7, 7),\n    segment(\"Schedule B (Form 1040)\", 8, 8),\n    segment(\"Schedule C (Form 1040)\", 9, 9),\n    segment(\"Schedule SE (Form 1040)\", 10, 10),\n    segment(\"Schedule H (Form 1040)\", 11, 12),\n    segment(\"misc_form\", 13, 13),\n    segment(\"Form 8960\", 14, 15),\n    segment(\"supplement\", 16, 20),\n    segment(\"misc_form\", 21, 39),\n    segment(\"supplement\", 40, 40),\n  ],\n  [\n    segment(\"Form 1040\", 1, 2),\n    segment(\"Schedule 1 (Form 1040)\", 3, 4),\n    segment(\"Schedule 2 (Form 1040)\", 5, 6),\n    segment(\"Schedule A (Form 1040)\", 7, 7),\n    segment(\"Schedule B (Form 1040)\", 8, 8),\n    segment(\"Schedule C (Form 1040)\", 9, 9),\n    segment(\"Schedule SE (Form 1040)\", 10, 10),\n    segment(\"Schedule H (Form 1040)\", 11, 12),\n    segment(\"misc_form\", 13, 13),\n    segment(\"Form 8960\", 14, 14),\n    segment(\"supplement\", 15, 20),\n    segment(\"misc_form\", 21, 40),\n  ],\n  [\n    segment(\"Form 1040\", 1, 2),\n    segment(\"Schedule 1 (Form 1040)\", 3, 4),\n    segment(\"Schedule 2 (Form 1040)\", 5, 6),\n    segment(\"Schedule A (Form 1040)\", 7, 7),\n    segment(\"Schedule B (Form 1040)\", 8, 8),\n    segment(\"Schedule C (Form 1040)\", 9, 9),\n    segment(\"Schedule SE (Form 1040)\", 10, 10),\n    segment(\"Schedule H (Form 1040)\", 11, 12),\n    segment(\"misc_form\", 13, 13),\n    segment(\"Form 8960\", 14, 14),\n    segment(\"supplement\", 15, 20),\n    segment(\"misc_form\", 21, 39),\n    segment(\"supplement\", 40, 40),\n  ],\n];\n\nconst HARRIS_CONSOLIDATION_SEGMENTS = weightedConsolidationSegments(\n  VOTE_SEGMENTS,\n  40,\n);\nconst HARRIS_SEGMENT_ROWS: SegmentRow[] = [\n  createSegmentRow(\n    \"harris-consolidation\",\n    \"consolidation\",\n    \"cons\",\n    HARRIS_CONSOLIDATION_SEGMENTS,\n  ),\n  ...VOTE_SEGMENTS.map((segments, index) =>\n    createSegmentRow(\n      `harris-vote-${index + 1}`,\n      `vote ${index + 1}`,\n      `v${index + 1}`,\n      segments,\n    ),\n  ),\n];\n\nconst HARRIS_SEGMENT_DOC: SegmentDiagramDoc = {\n  fileName: HARRIS_SOURCE.fileName,\n  label: \"Harris 2023 Federal / State Returns\",\n  pageCount: 40,\n  pdfUrl: HARRIS_SOURCE.url,\n  legendSegments: createLegendSegments(HARRIS_CONSOLIDATION_SEGMENTS),\n  rows: HARRIS_SEGMENT_ROWS,\n  ribbonRows: HARRIS_SEGMENT_ROWS.map(toRibbonRow),\n  diffRibbonRow: createDiffRibbonRow({\n    id: \"harris-diff\",\n    voteRows: VOTE_SEGMENTS,\n    pageCount: 40,\n  }),\n};\n\nexport function SplitConsensusSegmentDiagramViewer({\n  orientation,\n}: {\n  orientation: DiagramOrientation;\n}) {\n  const [currentPage, setCurrentPage] = React.useState(1);\n  const [scrollProgress, setScrollProgress] = React.useState(0);\n  const segmentInteraction = useSegmentInteraction();\n  const pdfRef = React.useRef<PdfViewerHandle | null>(null);\n  const isHorizontal = orientation === \"horizontal\";\n\n  const jumpToPage = React.useCallback((page: number) => {\n    const nextPage = clampPage(page, HARRIS_SEGMENT_DOC.pageCount);\n    setCurrentPage(nextPage);\n    pdfRef.current?.scrollToPage(nextPage, { behavior: \"smooth\" });\n  }, []);\n\n  return (\n    <div className=\"bg-background text-foreground flex h-full min-h-[760px] flex-col\">\n      <FileViewerProvider source={HARRIS_SOURCE} defaultSidebarOpen>\n        <FileViewer className=\"bg-background\">\n          <PdfViewerProvider>\n            <FileViewerHeader>\n              <FileViewerSidebarTrigger className=\"-ms-1\" />\n              <FileViewerTitle />\n              <FileViewerControls />\n            </FileViewerHeader>\n            <FileViewerContent>\n              <FileViewerSidebar\n                aria-label={\n                  isHorizontal\n                    ? \"Horizontal split consensus diagram\"\n                    : \"Vertical split consensus diagram\"\n                }\n                width={isHorizontal ? \"42rem\" : \"19rem\"}\n                className=\"border-r\"\n              >\n                {isHorizontal ? (\n                  <FileViewerSidebarHeader className=\"min-h-12\">\n                    <div className=\"min-w-0\">\n                      <div className=\"text-sm font-medium\">Segment diagram</div>\n                      <div className=\"text-muted-foreground mt-0.5 font-mono text-[10px]\">\n                        {HARRIS_SEGMENT_DOC.rows.length - 1} votes /{\" \"}\n                        {HARRIS_SEGMENT_DOC.pageCount} pages\n                      </div>\n                    </div>\n                  </FileViewerSidebarHeader>\n                ) : null}\n                <FileViewerSidebarContent>\n                  {isHorizontal ? (\n                    <HorizontalSegmentDiagram\n                      doc={HARRIS_SEGMENT_DOC}\n                      currentPage={currentPage}\n                      scrollProgress={scrollProgress}\n                      interaction={segmentInteraction}\n                      onJumpToPage={jumpToPage}\n                    />\n                  ) : (\n                    <VerticalSegmentDiagram\n                      doc={HARRIS_SEGMENT_DOC}\n                      currentPage={currentPage}\n                      scrollProgress={scrollProgress}\n                      interaction={segmentInteraction}\n                      onJumpToPage={jumpToPage}\n                    />\n                  )}\n                </FileViewerSidebarContent>\n              </FileViewerSidebar>\n\n              <FileViewerInset>\n                <FileViewerLegend>\n                  <SegmentLegend\n                    segments={HARRIS_SEGMENT_DOC.legendSegments}\n                    currentPage={currentPage}\n                    interaction={segmentInteraction}\n                    onSelect={(segment) => jumpToPage(firstLegendPage(segment))}\n                    columns={4}\n                    variant=\"plain\"\n                    showUnusedToggle\n                    className=\"px-3 py-2\"\n                  />\n                </FileViewerLegend>\n                <FileViewerViewport>\n                  <PdfViewerPages\n                    ref={pdfRef}\n                    bare\n                    className=\"h-full\"\n                    onVisiblePageChange={(page) =>\n                      setCurrentPage(\n                        clampPage(page, HARRIS_SEGMENT_DOC.pageCount),\n                      )\n                    }\n                    onScrollProgressChange={setScrollProgress}\n                  />\n                </FileViewerViewport>\n              </FileViewerInset>\n            </FileViewerContent>\n          </PdfViewerProvider>\n        </FileViewer>\n      </FileViewerProvider>\n    </div>\n  );\n}\n\nfunction HorizontalSegmentDiagram({\n  doc,\n  currentPage,\n  scrollProgress,\n  interaction,\n  onJumpToPage,\n}: {\n  doc: SegmentDiagramDoc;\n  currentPage: number;\n  scrollProgress: number;\n  interaction: DiagramSegmentInteraction;\n  onJumpToPage: (page: number) => void;\n}) {\n  const rows = [...doc.ribbonRows, doc.diffRibbonRow];\n\n  return (\n    <div className=\"flex min-h-full flex-col gap-5 overflow-auto p-5\">\n      <DiagramIntro doc={doc} />\n      <div className=\"flex min-w-0 items-start gap-4 pb-6\">\n        <div className=\"flex w-28 shrink-0 flex-col gap-px\">\n          {rows.map((row) => (\n            <div\n              key={row.id}\n              className=\"text-muted-foreground flex h-9 items-center justify-end font-mono text-[11px]\"\n            >\n              {row.label}\n            </div>\n          ))}\n        </div>\n        <PageRibbon\n          orientation=\"horizontal\"\n          rows={rows}\n          pageCount={doc.pageCount}\n          currentPage={currentPage}\n          scrollProgress={scrollProgress}\n          interaction={interaction}\n          onSelectPage={onJumpToPage}\n          showTicks\n          rowThickness={36}\n          className=\"min-w-0 flex-1\"\n        />\n      </div>\n    </div>\n  );\n}\n\nfunction VerticalSegmentDiagram({\n  doc,\n  currentPage,\n  scrollProgress,\n  interaction,\n  onJumpToPage,\n}: {\n  doc: SegmentDiagramDoc;\n  currentPage: number;\n  scrollProgress: number;\n  interaction: DiagramSegmentInteraction;\n  onJumpToPage: (page: number) => void;\n}) {\n  const rows = [...doc.ribbonRows, doc.diffRibbonRow];\n\n  return (\n    <div className=\"flex h-full min-h-0 flex-col gap-4 overflow-hidden p-4\">\n      <div className=\"flex min-h-0 flex-1 flex-col gap-1\">\n        <div\n          className=\"grid gap-1\"\n          style={{\n            gridTemplateColumns: `repeat(${rows.length}, ${VERTICAL_LANE_WIDTH}px) 1rem`,\n          }}\n        >\n          {doc.rows.map((row) => (\n            <div\n              key={row.id}\n              className=\"text-muted-foreground text-center font-mono text-[10px]\"\n              title={row.label}\n            >\n              {row.shortLabel}\n            </div>\n          ))}\n          <div\n            className=\"text-muted-foreground text-center font-mono text-[10px]\"\n            title={doc.diffRibbonRow.label}\n          >\n            diff\n          </div>\n          <div />\n        </div>\n        <PageRibbon\n          orientation=\"vertical\"\n          rows={rows}\n          pageCount={doc.pageCount}\n          currentPage={currentPage}\n          scrollProgress={scrollProgress}\n          interaction={interaction}\n          onSelectPage={onJumpToPage}\n          showTicks\n          rowThickness={VERTICAL_LANE_WIDTH}\n          className=\"min-h-0 flex-1\"\n        />\n      </div>\n    </div>\n  );\n}\n\nfunction DiagramIntro({\n  doc,\n  compact = false,\n}: {\n  doc: SegmentDiagramDoc;\n  compact?: boolean;\n}) {\n  return (\n    <div className={cn(\"grid gap-3\", !compact && \"grid-cols-[1fr_0.8fr]\")}>\n      <div>\n        <h2 className={cn(\"font-semibold\", compact ? \"text-base\" : \"text-xl\")}>\n          Segment diagram\n        </h2>\n        <p className=\"text-muted-foreground mt-1 text-[11px] leading-5\">\n          Consolidation, all {doc.rows.length - 1} raw consensus votes, and a\n          per-page vote-disagreement diff.\n        </p>\n      </div>\n      <p className=\"text-muted-foreground text-[11px] leading-5\">{doc.label}</p>\n    </div>\n  );\n}\n\nfunction segment(type: string, startPage: number, endPage: number): Segment {\n  return { type, startPage, endPage };\n}\n\nfunction createSegmentRow(\n  id: string,\n  label: string,\n  shortLabel: string,\n  segments: Segment[],\n): SegmentRow {\n  return {\n    id,\n    label,\n    shortLabel,\n    ribbonSegments: createRibbonSegments(id, segments),\n  };\n}\n\nfunction toRibbonRow(row: SegmentRow): RibbonRow {\n  return {\n    id: row.id,\n    label: row.label,\n    segments: row.ribbonSegments,\n  };\n}\n\nfunction createLegendSegments(segments: readonly Segment[]): DocumentSegment[] {\n  return TYPE_ORDER.map((type, index) => ({\n    id: segmentIdForType(type),\n    label: type,\n    pages: segmentPagesForType(segments, type),\n    color: colorForType(type),\n    index,\n    confidence: null,\n  }));\n}\n\nfunction createRibbonSegments(\n  rowId: string,\n  segments: readonly Segment[],\n): DocumentSegment[] {\n  return segments.map((segment, index) => ({\n    id: segmentIdForType(segment.type),\n    sourceId: `${rowId}-${index}`,\n    label: segment.type,\n    pages: pagesInRange(segment.startPage, segment.endPage),\n    color: colorForType(segment.type),\n    index,\n    confidence: null,\n  }));\n}\n\n/**\n * The \"diff\" lane: each page shaded proportionally to how much the votes\n * disagree on it. A page where every vote assigns the same type reads as empty;\n * an even split reads as full-strength. Intensity is the share of dissenting\n * votes, normalized so a maximally-split page (the most even split possible for\n * the vote count) saturates the color — floored to DIFF_MIN_PERCENT so any\n * non-zero disagreement stays visible.\n */\nfunction createDiffRibbonRow({\n  id,\n  voteRows,\n  pageCount,\n}: {\n  id: string;\n  voteRows: readonly (readonly Segment[])[];\n  pageCount: number;\n}): RibbonRow {\n  const pageVotes = buildPageVotes(voteRows, pageCount);\n  const maxDissent = Math.max(1, Math.floor(voteRows.length / 2));\n  const pagesByPercent = new Map<number, number[]>();\n\n  for (let page = 1; page <= pageCount; page += 1) {\n    const counts = Object.values(pageVotes[page]!);\n    const total = counts.reduce((sum, count) => sum + count, 0);\n    if (total === 0) continue;\n    const dissent = total - Math.max(...counts);\n    if (dissent <= 0) continue;\n    // Proportional to the dissent share, but floored so even a single\n    // dissenting vote stays clearly visible rather than reading as empty.\n    const normalized = Math.min(1, dissent / maxDissent);\n    const percent = Math.round(\n      DIFF_MIN_PERCENT + normalized * (100 - DIFF_MIN_PERCENT),\n    );\n    const bucket = pagesByPercent.get(percent) ?? [];\n    bucket.push(page);\n    pagesByPercent.set(percent, bucket);\n  }\n\n  const segments: DocumentSegment[] = Array.from(pagesByPercent.entries())\n    .sort(([left], [right]) => left - right)\n    .map(([percent, pages], index) => ({\n      id: `${id}-diff-${percent}`,\n      label: `${percent}% disagreement`,\n      pages: pages.sort((left, right) => left - right),\n      color: `color-mix(in oklab, var(--warning) ${percent}%, transparent)`,\n      index,\n      confidence: null,\n    }));\n\n  return {\n    id,\n    label: \"diff\",\n    segments,\n  };\n}\n\nfunction segmentPagesForType(segments: readonly Segment[], type: string) {\n  const pages = new Set<number>();\n  segments\n    .filter((segment) => segment.type === type)\n    .forEach((segment) => {\n      pagesInRange(segment.startPage, segment.endPage).forEach((page) =>\n        pages.add(page),\n      );\n    });\n  return Array.from(pages).sort((left, right) => left - right);\n}\n\nfunction firstLegendPage(segment: DocumentSegment) {\n  return segment.pages[0] ?? 1;\n}\n\nfunction pagesInRange(startPage: number, endPage: number) {\n  const start = Math.max(1, Math.min(startPage, endPage));\n  const end = Math.max(start, endPage);\n  return Array.from({ length: end - start + 1 }, (_, index) => start + index);\n}\n\nfunction segmentIdForType(type: string) {\n  const index = TYPE_ORDER.indexOf(type);\n  return `segment-type-${index === -1 ? type : index}`;\n}\n\nfunction buildPageVotes(\n  voteRows: readonly (readonly Segment[])[],\n  pageCount: number,\n): SegmentVoteCounts[] {\n  const pageVotes: SegmentVoteCounts[] = Array.from(\n    { length: pageCount + 1 },\n    () => ({}),\n  );\n\n  voteRows.forEach((segments) => {\n    segments.forEach((seg) => {\n      for (let page = seg.startPage; page <= seg.endPage; page += 1) {\n        if (page < 1 || page > pageCount) continue;\n        pageVotes[page]![seg.type] = (pageVotes[page]![seg.type] ?? 0) + 1;\n      }\n    });\n  });\n\n  return pageVotes;\n}\n\nfunction weightedConsolidationSegments(\n  voteRows: readonly (readonly Segment[])[],\n  pageCount: number,\n): Segment[] {\n  const pageVotes = buildPageVotes(voteRows, pageCount);\n\n  const weightedSegments: Segment[] = [];\n  let currentKey = voteSignature(pageVotes[1]!);\n  let startPage: number | null = currentKey === \"\" ? null : 1;\n\n  for (let page = 2; page <= pageCount; page += 1) {\n    const nextKey = voteSignature(pageVotes[page]!);\n    if (nextKey === currentKey) continue;\n\n    if (currentKey !== \"\" && startPage !== null) {\n      weightedSegments.push(\n        weightedSegment(pageVotes[startPage]!, startPage, page - 1),\n      );\n    }\n    currentKey = nextKey;\n    startPage = nextKey === \"\" ? null : page;\n  }\n\n  if (currentKey !== \"\" && startPage !== null) {\n    weightedSegments.push(\n      weightedSegment(pageVotes[startPage]!, startPage, pageCount),\n    );\n  }\n\n  return weightedSegments;\n}\n\nfunction weightedSegment(\n  voteCounts: SegmentVoteCounts,\n  startPage: number,\n  endPage: number,\n): Segment {\n  return {\n    type: winningType(voteCounts),\n    startPage,\n    endPage,\n  };\n}\n\nfunction voteSignature(voteCounts: SegmentVoteCounts) {\n  return Object.entries(voteCounts)\n    .sort(([left], [right]) => left.localeCompare(right))\n    .map(([type, count]) => `${type}:${count}`)\n    .join(\"|\");\n}\n\nfunction winningType(voteCounts: SegmentVoteCounts) {\n  return (\n    Object.entries(voteCounts).sort(\n      ([leftType, leftCount], [rightType, rightCount]) =>\n        rightCount === leftCount\n          ? leftType.localeCompare(rightType)\n          : rightCount - leftCount,\n    )[0]?.[0] ?? \"unassigned\"\n  );\n}\n\nfunction colorForType(type: string) {\n  return TYPE_COLORS.get(type) ?? \"#888\";\n}\n\nfunction clampPage(page: number, pageCount: number) {\n  if (!Number.isFinite(page)) return 1;\n  return Math.max(1, Math.min(pageCount, Math.round(page)));\n}\n",
      "type": "registry:component",
      "target": "@components/blocks/split-consensus-segment-diagram.tsx"
    }
  ],
  "categories": [
    "primitives"
  ],
  "type": "registry:block"
}
