@memberjunction/ng-markdown 2.133.0 → 3.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.
@@ -487,7 +487,7 @@ export class MarkdownComponent {
487
487
  html = html.replace(/\s+src\s*=\s*["']data:text\/html[^"']*["']/gi, '');
488
488
  return html;
489
489
  }
490
- static { this.ɵfac = function MarkdownComponent_Factory(t) { return new (t || MarkdownComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DomSanitizer), i0.ɵɵdirectiveInject(i2.MarkdownService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
490
+ static { this.ɵfac = function MarkdownComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MarkdownComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DomSanitizer), i0.ɵɵdirectiveInject(i2.MarkdownService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
491
491
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MarkdownComponent, selectors: [["mj-markdown"]], inputs: { data: "data", enableHighlight: "enableHighlight", enableMermaid: "enableMermaid", enableCodeCopy: "enableCodeCopy", enableCollapsibleHeadings: "enableCollapsibleHeadings", collapsibleHeadingLevel: "collapsibleHeadingLevel", collapsibleDefaultExpanded: "collapsibleDefaultExpanded", autoExpandLevels: "autoExpandLevels", enableAlerts: "enableAlerts", enableSmartypants: "enableSmartypants", enableSvgRenderer: "enableSvgRenderer", enableHtml: "enableHtml", enableJavaScript: "enableJavaScript", enableHeadingIds: "enableHeadingIds", headingIdPrefix: "headingIdPrefix", enableLineNumbers: "enableLineNumbers", containerClass: "containerClass", mermaidTheme: "mermaidTheme", sanitize: "sanitize" }, outputs: { rendered: "rendered", headingClick: "headingClick", codeCopied: "codeCopied" }, features: [i0.ɵɵNgOnChangesFeature], decls: 1, vars: 3, consts: [[1, "mj-markdown-container", 3, "innerHTML"]], template: function MarkdownComponent_Template(rf, ctx) { if (rf & 1) {
492
492
  i0.ɵɵelement(0, "div", 0);
493
493
  } if (rf & 2) {
@@ -549,5 +549,5 @@ export class MarkdownComponent {
549
549
  }], codeCopied: [{
550
550
  type: Output
551
551
  }] }); })();
552
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MarkdownComponent, { className: "MarkdownComponent", filePath: "src/lib/components/markdown.component.ts", lineNumber: 61 }); })();
552
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MarkdownComponent, { className: "MarkdownComponent" }); })();
553
553
  //# sourceMappingURL=markdown.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.component.js","sourceRoot":"","sources":["../../../src/lib/components/markdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n SecurityContext,\n ViewEncapsulation,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { MarkdownService } from '../services/markdown.service';\nimport {\n MarkdownConfig,\n DEFAULT_MARKDOWN_CONFIG,\n MarkdownRenderEvent,\n HeadingInfo\n} from '../types/markdown.types';\n// Collapsible section toggle is handled inline in setupCollapsibleListeners\n\n/**\n * Angular component for rendering markdown content.\n *\n * Features:\n * - Prism.js syntax highlighting for code blocks\n * - Mermaid diagram rendering\n * - Copy-to-clipboard for code blocks\n * - Collapsible heading sections\n * - GitHub-style alerts and heading IDs\n *\n * Usage:\n * ```html\n * <mj-markdown [data]=\"markdownContent\"></mj-markdown>\n *\n * <mj-markdown\n * [data]=\"content\"\n * [enableMermaid]=\"true\"\n * [enableCollapsibleHeadings]=\"true\"\n * (rendered)=\"onRendered($event)\">\n * </mj-markdown>\n * ```\n */\n@Component({\n selector: 'mj-markdown',\n template: `\n <div\n class=\"mj-markdown-container\"\n [class]=\"containerClass\"\n [innerHTML]=\"renderedContent\">\n </div>\n `,\n styleUrls: ['./markdown.component.css'],\n encapsulation: ViewEncapsulation.None, // Allow styles to penetrate into rendered content\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MarkdownComponent implements OnChanges, AfterViewInit, OnDestroy {\n /**\n * The markdown content to render\n */\n @Input() data: string = '';\n\n /**\n * Enable syntax highlighting\n */\n @Input() enableHighlight: boolean = DEFAULT_MARKDOWN_CONFIG.enableHighlight;\n\n /**\n * Enable Mermaid diagram rendering\n */\n @Input() enableMermaid: boolean = DEFAULT_MARKDOWN_CONFIG.enableMermaid;\n\n /**\n * Enable copy button on code blocks\n */\n @Input() enableCodeCopy: boolean = DEFAULT_MARKDOWN_CONFIG.enableCodeCopy;\n\n /**\n * Enable collapsible heading sections\n */\n @Input() enableCollapsibleHeadings: boolean = DEFAULT_MARKDOWN_CONFIG.enableCollapsibleHeadings;\n\n /**\n * Heading level at which to start collapsing\n */\n @Input() collapsibleHeadingLevel: 1 | 2 | 3 | 4 | 5 | 6 = DEFAULT_MARKDOWN_CONFIG.collapsibleHeadingLevel;\n\n /**\n * Whether collapsible sections should be expanded by default\n */\n @Input() collapsibleDefaultExpanded: boolean = DEFAULT_MARKDOWN_CONFIG.collapsibleDefaultExpanded;\n\n /**\n * Specify which heading levels should start expanded.\n * Array of heading levels (2-6) that should be expanded by default.\n * Takes precedence over collapsibleDefaultExpanded for specified levels.\n *\n * Examples:\n * - [2] = Only h2 expanded, h3-h6 collapsed\n * - [2, 3] = h2 and h3 expanded, h4-h6 collapsed\n * - [] = All collapsed\n * - undefined = Uses collapsibleDefaultExpanded for all levels\n */\n @Input() autoExpandLevels?: number[];\n\n /**\n * Enable GitHub-style alerts\n */\n @Input() enableAlerts: boolean = DEFAULT_MARKDOWN_CONFIG.enableAlerts;\n\n /**\n * Enable smartypants for typography (curly quotes, em/en dashes, ellipses)\n */\n @Input() enableSmartypants: boolean = DEFAULT_MARKDOWN_CONFIG.enableSmartypants;\n\n /**\n * Enable SVG code block rendering\n * When enabled, ```svg code blocks are rendered as actual SVG images\n */\n @Input() enableSvgRenderer: boolean = DEFAULT_MARKDOWN_CONFIG.enableSvgRenderer;\n\n /**\n * Enable raw HTML passthrough in markdown content.\n * Scripts and event handlers are still stripped unless enableJavaScript is true.\n */\n @Input() enableHtml: boolean = DEFAULT_MARKDOWN_CONFIG.enableHtml;\n\n /**\n * Enable JavaScript in HTML content (<script> tags and on* handlers).\n * WARNING: Major security risk - only enable for fully trusted content.\n */\n @Input() enableJavaScript: boolean = DEFAULT_MARKDOWN_CONFIG.enableJavaScript;\n\n /**\n * Enable heading IDs for anchor links\n */\n @Input() enableHeadingIds: boolean = DEFAULT_MARKDOWN_CONFIG.enableHeadingIds;\n\n /**\n * Prefix for heading IDs\n */\n @Input() headingIdPrefix: string = DEFAULT_MARKDOWN_CONFIG.headingIdPrefix;\n\n /**\n * Enable line numbers in code blocks\n */\n @Input() enableLineNumbers: boolean = DEFAULT_MARKDOWN_CONFIG.enableLineNumbers;\n\n /**\n * Custom CSS class for the container\n */\n @Input() containerClass: string = '';\n\n /**\n * Mermaid theme\n */\n @Input() mermaidTheme: 'default' | 'dark' | 'forest' | 'neutral' | 'base' = DEFAULT_MARKDOWN_CONFIG.mermaidTheme;\n\n /**\n * Whether to sanitize HTML output\n */\n @Input() sanitize: boolean = DEFAULT_MARKDOWN_CONFIG.sanitize;\n\n /**\n * Emitted when rendering is complete\n */\n @Output() rendered = new EventEmitter<MarkdownRenderEvent>();\n\n /**\n * Emitted when a heading anchor is clicked\n */\n @Output() headingClick = new EventEmitter<HeadingInfo>();\n\n /**\n * Emitted when code is copied to clipboard\n */\n @Output() codeCopied = new EventEmitter<string>();\n\n /**\n * The sanitized HTML content to display\n */\n public renderedContent: SafeHtml = '';\n\n /**\n * Public accessor for the component's element reference.\n * Provided for backward compatibility with ngx-markdown API.\n */\n public get element(): ElementRef<HTMLElement> {\n return this.elementRef;\n }\n\n private renderStartTime: number = 0;\n private hasMermaid: boolean = false;\n private hasCodeBlocks: boolean = false;\n\n constructor(\n private elementRef: ElementRef<HTMLElement>,\n private sanitizer: DomSanitizer,\n private markdownService: MarkdownService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n // Check if any relevant input changed\n const needsRerender =\n changes['data'] ||\n changes['enableHighlight'] ||\n changes['enableMermaid'] ||\n changes['enableCodeCopy'] ||\n changes['enableCollapsibleHeadings'] ||\n changes['collapsibleHeadingLevel'] ||\n changes['collapsibleDefaultExpanded'] ||\n changes['autoExpandLevels'] ||\n changes['enableAlerts'] ||\n changes['enableSmartypants'] ||\n changes['enableSvgRenderer'] ||\n changes['enableHtml'] ||\n changes['enableJavaScript'] ||\n changes['enableHeadingIds'] ||\n changes['headingIdPrefix'] ||\n changes['mermaidTheme'] ||\n changes['sanitize'];\n\n if (needsRerender) {\n this.render();\n }\n }\n\n ngAfterViewInit(): void {\n // Initial render if data was provided\n if (this.data) {\n this.postRenderProcessing();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup any event listeners\n this.cleanupEventListeners();\n }\n\n /**\n * Render the markdown content\n */\n private render(): void {\n if (!this.data) {\n this.renderedContent = '';\n this.cdr.markForCheck();\n return;\n }\n\n this.renderStartTime = performance.now();\n\n // Build config from inputs\n const config: MarkdownConfig = {\n enableHighlight: this.enableHighlight,\n enableMermaid: this.enableMermaid,\n enableCodeCopy: this.enableCodeCopy,\n enableCollapsibleHeadings: this.enableCollapsibleHeadings,\n collapsibleHeadingLevel: this.collapsibleHeadingLevel,\n collapsibleDefaultExpanded: this.collapsibleDefaultExpanded,\n autoExpandLevels: this.autoExpandLevels,\n enableAlerts: this.enableAlerts,\n enableSmartypants: this.enableSmartypants,\n enableSvgRenderer: this.enableSvgRenderer,\n enableHtml: this.enableHtml,\n enableJavaScript: this.enableJavaScript,\n enableHeadingIds: this.enableHeadingIds,\n headingIdPrefix: this.headingIdPrefix,\n mermaidTheme: this.mermaidTheme,\n sanitize: this.sanitize\n };\n\n // Configure service and parse\n this.markdownService.configureMarked(config);\n let html = this.markdownService.parse(this.data);\n\n // Check for mermaid and code blocks\n this.hasMermaid = html.includes('language-mermaid') || html.includes('class=\"mermaid\"');\n this.hasCodeBlocks = html.includes('<pre>') && html.includes('<code');\n\n // Sanitize if enabled\n // Note: We bypass Angular's sanitizer when SVG renderer or HTML passthrough is enabled\n // because it strips SVG elements and most HTML layout tags.\n const bypassAngularSanitizer = this.enableSvgRenderer || this.enableHtml;\n if (this.sanitize && !bypassAngularSanitizer) {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, html);\n html = sanitized || '';\n }\n\n // Strip JavaScript unless explicitly enabled\n // This removes <script> tags and on* event handlers while keeping layout HTML\n if (bypassAngularSanitizer && !this.enableJavaScript) {\n html = this.stripJavaScript(html);\n }\n\n // Trust the HTML for display\n this.renderedContent = this.sanitizer.bypassSecurityTrustHtml(html);\n this.cdr.markForCheck();\n\n // Schedule post-render processing for next tick (after DOM update)\n Promise.resolve().then(() => this.postRenderProcessing());\n }\n\n /**\n * Process rendered content after DOM update\n * Handles syntax highlighting, mermaid rendering, copy buttons, etc.\n */\n private async postRenderProcessing(): Promise<void> {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n // Add copy buttons to code blocks\n if (this.enableCodeCopy && this.hasCodeBlocks) {\n this.markdownService.addCodeCopyButtons(container as HTMLElement);\n }\n\n // Initialize collapsible headings\n if (this.enableCollapsibleHeadings) {\n this.markdownService.initializeCollapsibleHeadings(container as HTMLElement);\n this.setupCollapsibleListeners(container as HTMLElement);\n }\n\n // Render mermaid diagrams (async)\n if (this.enableMermaid && this.hasMermaid) {\n await this.markdownService.renderMermaid(container as HTMLElement);\n }\n\n // Setup heading click listeners\n if (this.enableHeadingIds) {\n this.setupHeadingClickListeners(container as HTMLElement);\n }\n\n // Setup code copy listeners for custom event emission\n if (this.enableCodeCopy) {\n this.setupCodeCopyListeners(container as HTMLElement);\n }\n\n // Emit rendered event\n const renderTime = performance.now() - this.renderStartTime;\n const headingIds = this.markdownService.getHeadingList();\n\n this.rendered.emit({\n html: (container as HTMLElement).innerHTML,\n renderTime,\n hasMermaid: this.hasMermaid,\n hasCodeBlocks: this.hasCodeBlocks,\n headingIds\n });\n }\n\n /**\n * Setup collapsible sections by adding toggle buttons and click listeners\n */\n private setupCollapsibleListeners(container: HTMLElement): void {\n const sections = container.querySelectorAll('.collapsible-section');\n\n sections.forEach((section) => {\n const wrapper = section.querySelector(':scope > .collapsible-heading-wrapper') as HTMLElement | null;\n if (!wrapper) return;\n\n // Check if toggle already exists\n if (wrapper.querySelector('.collapsible-toggle')) return;\n\n const isExpanded = !section.classList.contains('collapsed');\n const hasChildren = section.querySelector('.collapsible-section') !== null;\n\n // Create toggle button (chevron)\n const toggle = document.createElement('span');\n toggle.className = 'collapsible-toggle';\n toggle.setAttribute('role', 'button');\n toggle.setAttribute('tabindex', '0');\n toggle.setAttribute('aria-expanded', String(isExpanded));\n toggle.innerHTML = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M6 12l4-4-4-4\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n // Insert toggle before heading\n wrapper.insertBefore(toggle, wrapper.firstChild);\n\n // Add action buttons container (only if has children)\n if (hasChildren) {\n const actions = this.createActionButtons(section as HTMLElement);\n wrapper.appendChild(actions);\n }\n\n // Make the whole wrapper clickable\n wrapper.style.cursor = 'pointer';\n\n // Add click listener to wrapper (but not on action buttons)\n wrapper.addEventListener('click', (e: Event) => {\n const target = e.target as HTMLElement;\n // Don't toggle if clicking on action buttons\n if (target.closest('.collapsible-actions')) return;\n\n e.preventDefault();\n e.stopPropagation();\n this.toggleSection(section as HTMLElement, toggle);\n });\n\n // Add keyboard support\n wrapper.addEventListener('keydown', (e: Event) => {\n const target = e.target as HTMLElement;\n if (target.closest('.collapsible-actions')) return;\n\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {\n e.preventDefault();\n this.toggleSection(section as HTMLElement, toggle);\n }\n });\n });\n }\n\n /**\n * Create the expand/collapse all action buttons for sections with children\n */\n private createActionButtons(section: HTMLElement): HTMLElement {\n const container = document.createElement('span');\n container.className = 'collapsible-actions';\n\n // Expand all button\n const expandBtn = document.createElement('button');\n expandBtn.className = 'collapsible-action-btn expand-all';\n expandBtn.setAttribute('type', 'button');\n expandBtn.setAttribute('title', 'Expand all');\n expandBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 6l4 4 4-4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4 10l4 4 4-4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n expandBtn.addEventListener('click', (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n this.expandDescendants(section);\n // Also expand the section itself if collapsed\n if (section.classList.contains('collapsed')) {\n section.classList.remove('collapsed');\n const toggle = section.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) toggle.setAttribute('aria-expanded', 'true');\n }\n });\n\n // Collapse all button\n const collapseBtn = document.createElement('button');\n collapseBtn.className = 'collapsible-action-btn collapse-all';\n collapseBtn.setAttribute('type', 'button');\n collapseBtn.setAttribute('title', 'Collapse all');\n collapseBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 10l4-4 4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4 14l4-4 4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n collapseBtn.addEventListener('click', (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n this.collapseDescendants(section);\n });\n\n container.appendChild(expandBtn);\n container.appendChild(collapseBtn);\n\n return container;\n }\n\n /**\n * Toggle a collapsible section\n * @param section The section element to toggle\n * @param toggle The toggle button element\n */\n private toggleSection(section: HTMLElement, toggle: HTMLElement): void {\n const isCollapsed = section.classList.contains('collapsed');\n\n // Toggle the section\n section.classList.toggle('collapsed');\n toggle.setAttribute('aria-expanded', String(isCollapsed));\n // Children retain their state - CSS handles visibility via parent collapse\n }\n\n /**\n * Collapse all descendant sections (used by action button)\n */\n private collapseDescendants(section: HTMLElement): void {\n const descendants = section.querySelectorAll('.collapsible-section');\n descendants.forEach((desc) => {\n desc.classList.add('collapsed');\n const toggle = desc.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) {\n toggle.setAttribute('aria-expanded', 'false');\n }\n });\n }\n\n /**\n * Expand all descendant sections (used by action button)\n */\n private expandDescendants(section: HTMLElement): void {\n const descendants = section.querySelectorAll('.collapsible-section');\n descendants.forEach((desc) => {\n desc.classList.remove('collapsed');\n const toggle = desc.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) {\n toggle.setAttribute('aria-expanded', 'true');\n }\n });\n }\n\n /**\n * Setup click listeners for heading anchors\n */\n private setupHeadingClickListeners(container: HTMLElement): void {\n const headings = container.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]');\n\n headings.forEach((heading) => {\n heading.addEventListener('click', () => {\n const id = heading.getAttribute('id') || '';\n const text = heading.textContent || '';\n const level = parseInt(heading.tagName.charAt(1), 10);\n\n this.headingClick.emit({\n id,\n text,\n level,\n raw: text\n });\n });\n });\n }\n\n /**\n * Setup listeners to emit code copy events\n */\n private setupCodeCopyListeners(container: HTMLElement): void {\n const copyButtons = container.querySelectorAll('.code-copy-btn');\n\n copyButtons.forEach((button) => {\n button.addEventListener('click', () => {\n const pre = button.closest('pre');\n const code = pre?.querySelector('code');\n if (code) {\n this.codeCopied.emit(code.textContent || '');\n }\n });\n });\n }\n\n /**\n * Cleanup event listeners\n */\n private cleanupEventListeners(): void {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n // Clone and replace to remove all listeners\n const clone = container.cloneNode(true);\n container.parentNode?.replaceChild(clone, container);\n }\n\n /**\n * Force a re-render of the markdown content\n */\n public refresh(): void {\n this.render();\n }\n\n /**\n * Get the current heading list (for TOC building)\n */\n public getHeadings(): HeadingInfo[] {\n return this.markdownService.getHeadingList();\n }\n\n /**\n * Scroll to a heading by ID\n */\n public scrollToHeading(headingId: string): void {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n const heading = container.querySelector(`#${headingId}`);\n if (heading) {\n heading.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n }\n\n /**\n * Strip JavaScript from HTML content while preserving layout HTML.\n * Removes <script> tags, on* event handlers, and javascript: URLs.\n */\n private stripJavaScript(html: string): string {\n // Remove <script> tags and their content\n html = html.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n\n // Remove on* event handlers (onclick, onload, onerror, etc.)\n html = html.replace(/\\s+on\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi, '');\n html = html.replace(/\\s+on\\w+\\s*=\\s*[^\\s>]+/gi, '');\n\n // Remove javascript: URLs from href and src attributes\n html = html.replace(/\\s+href\\s*=\\s*[\"']javascript:[^\"']*[\"']/gi, '');\n html = html.replace(/\\s+src\\s*=\\s*[\"']javascript:[^\"']*[\"']/gi, '');\n\n // Remove data: URLs that could contain scripts (data:text/html, etc.)\n html = html.replace(/\\s+src\\s*=\\s*[\"']data:text\\/html[^\"']*[\"']/gi, '');\n\n return html;\n }\n}\n"]}
1
+ {"version":3,"file":"markdown.component.js","sourceRoot":"","sources":["../../../src/lib/components/markdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n SecurityContext,\n ViewEncapsulation,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { MarkdownService } from '../services/markdown.service';\nimport {\n MarkdownConfig,\n DEFAULT_MARKDOWN_CONFIG,\n MarkdownRenderEvent,\n HeadingInfo\n} from '../types/markdown.types';\n// Collapsible section toggle is handled inline in setupCollapsibleListeners\n\n/**\n * Angular component for rendering markdown content.\n *\n * Features:\n * - Prism.js syntax highlighting for code blocks\n * - Mermaid diagram rendering\n * - Copy-to-clipboard for code blocks\n * - Collapsible heading sections\n * - GitHub-style alerts and heading IDs\n *\n * Usage:\n * ```html\n * <mj-markdown [data]=\"markdownContent\"></mj-markdown>\n *\n * <mj-markdown\n * [data]=\"content\"\n * [enableMermaid]=\"true\"\n * [enableCollapsibleHeadings]=\"true\"\n * (rendered)=\"onRendered($event)\">\n * </mj-markdown>\n * ```\n */\n@Component({\n selector: 'mj-markdown',\n template: `\n <div\n class=\"mj-markdown-container\"\n [class]=\"containerClass\"\n [innerHTML]=\"renderedContent\">\n </div>\n `,\n styleUrls: ['./markdown.component.css'],\n encapsulation: ViewEncapsulation.None, // Allow styles to penetrate into rendered content\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MarkdownComponent implements OnChanges, AfterViewInit, OnDestroy {\n /**\n * The markdown content to render\n */\n @Input() data: string = '';\n\n /**\n * Enable syntax highlighting\n */\n @Input() enableHighlight: boolean = DEFAULT_MARKDOWN_CONFIG.enableHighlight;\n\n /**\n * Enable Mermaid diagram rendering\n */\n @Input() enableMermaid: boolean = DEFAULT_MARKDOWN_CONFIG.enableMermaid;\n\n /**\n * Enable copy button on code blocks\n */\n @Input() enableCodeCopy: boolean = DEFAULT_MARKDOWN_CONFIG.enableCodeCopy;\n\n /**\n * Enable collapsible heading sections\n */\n @Input() enableCollapsibleHeadings: boolean = DEFAULT_MARKDOWN_CONFIG.enableCollapsibleHeadings;\n\n /**\n * Heading level at which to start collapsing\n */\n @Input() collapsibleHeadingLevel: 1 | 2 | 3 | 4 | 5 | 6 = DEFAULT_MARKDOWN_CONFIG.collapsibleHeadingLevel;\n\n /**\n * Whether collapsible sections should be expanded by default\n */\n @Input() collapsibleDefaultExpanded: boolean = DEFAULT_MARKDOWN_CONFIG.collapsibleDefaultExpanded;\n\n /**\n * Specify which heading levels should start expanded.\n * Array of heading levels (2-6) that should be expanded by default.\n * Takes precedence over collapsibleDefaultExpanded for specified levels.\n *\n * Examples:\n * - [2] = Only h2 expanded, h3-h6 collapsed\n * - [2, 3] = h2 and h3 expanded, h4-h6 collapsed\n * - [] = All collapsed\n * - undefined = Uses collapsibleDefaultExpanded for all levels\n */\n @Input() autoExpandLevels?: number[];\n\n /**\n * Enable GitHub-style alerts\n */\n @Input() enableAlerts: boolean = DEFAULT_MARKDOWN_CONFIG.enableAlerts;\n\n /**\n * Enable smartypants for typography (curly quotes, em/en dashes, ellipses)\n */\n @Input() enableSmartypants: boolean = DEFAULT_MARKDOWN_CONFIG.enableSmartypants;\n\n /**\n * Enable SVG code block rendering\n * When enabled, ```svg code blocks are rendered as actual SVG images\n */\n @Input() enableSvgRenderer: boolean = DEFAULT_MARKDOWN_CONFIG.enableSvgRenderer;\n\n /**\n * Enable raw HTML passthrough in markdown content.\n * Scripts and event handlers are still stripped unless enableJavaScript is true.\n */\n @Input() enableHtml: boolean = DEFAULT_MARKDOWN_CONFIG.enableHtml;\n\n /**\n * Enable JavaScript in HTML content (<script> tags and on* handlers).\n * WARNING: Major security risk - only enable for fully trusted content.\n */\n @Input() enableJavaScript: boolean = DEFAULT_MARKDOWN_CONFIG.enableJavaScript;\n\n /**\n * Enable heading IDs for anchor links\n */\n @Input() enableHeadingIds: boolean = DEFAULT_MARKDOWN_CONFIG.enableHeadingIds;\n\n /**\n * Prefix for heading IDs\n */\n @Input() headingIdPrefix: string = DEFAULT_MARKDOWN_CONFIG.headingIdPrefix;\n\n /**\n * Enable line numbers in code blocks\n */\n @Input() enableLineNumbers: boolean = DEFAULT_MARKDOWN_CONFIG.enableLineNumbers;\n\n /**\n * Custom CSS class for the container\n */\n @Input() containerClass: string = '';\n\n /**\n * Mermaid theme\n */\n @Input() mermaidTheme: 'default' | 'dark' | 'forest' | 'neutral' | 'base' = DEFAULT_MARKDOWN_CONFIG.mermaidTheme;\n\n /**\n * Whether to sanitize HTML output\n */\n @Input() sanitize: boolean = DEFAULT_MARKDOWN_CONFIG.sanitize;\n\n /**\n * Emitted when rendering is complete\n */\n @Output() rendered = new EventEmitter<MarkdownRenderEvent>();\n\n /**\n * Emitted when a heading anchor is clicked\n */\n @Output() headingClick = new EventEmitter<HeadingInfo>();\n\n /**\n * Emitted when code is copied to clipboard\n */\n @Output() codeCopied = new EventEmitter<string>();\n\n /**\n * The sanitized HTML content to display\n */\n public renderedContent: SafeHtml = '';\n\n /**\n * Public accessor for the component's element reference.\n * Provided for backward compatibility with ngx-markdown API.\n */\n public get element(): ElementRef<HTMLElement> {\n return this.elementRef;\n }\n\n private renderStartTime: number = 0;\n private hasMermaid: boolean = false;\n private hasCodeBlocks: boolean = false;\n\n constructor(\n private elementRef: ElementRef<HTMLElement>,\n private sanitizer: DomSanitizer,\n private markdownService: MarkdownService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnChanges(changes: SimpleChanges): void {\n // Check if any relevant input changed\n const needsRerender =\n changes['data'] ||\n changes['enableHighlight'] ||\n changes['enableMermaid'] ||\n changes['enableCodeCopy'] ||\n changes['enableCollapsibleHeadings'] ||\n changes['collapsibleHeadingLevel'] ||\n changes['collapsibleDefaultExpanded'] ||\n changes['autoExpandLevels'] ||\n changes['enableAlerts'] ||\n changes['enableSmartypants'] ||\n changes['enableSvgRenderer'] ||\n changes['enableHtml'] ||\n changes['enableJavaScript'] ||\n changes['enableHeadingIds'] ||\n changes['headingIdPrefix'] ||\n changes['mermaidTheme'] ||\n changes['sanitize'];\n\n if (needsRerender) {\n this.render();\n }\n }\n\n ngAfterViewInit(): void {\n // Initial render if data was provided\n if (this.data) {\n this.postRenderProcessing();\n }\n }\n\n ngOnDestroy(): void {\n // Cleanup any event listeners\n this.cleanupEventListeners();\n }\n\n /**\n * Render the markdown content\n */\n private render(): void {\n if (!this.data) {\n this.renderedContent = '';\n this.cdr.markForCheck();\n return;\n }\n\n this.renderStartTime = performance.now();\n\n // Build config from inputs\n const config: MarkdownConfig = {\n enableHighlight: this.enableHighlight,\n enableMermaid: this.enableMermaid,\n enableCodeCopy: this.enableCodeCopy,\n enableCollapsibleHeadings: this.enableCollapsibleHeadings,\n collapsibleHeadingLevel: this.collapsibleHeadingLevel,\n collapsibleDefaultExpanded: this.collapsibleDefaultExpanded,\n autoExpandLevels: this.autoExpandLevels,\n enableAlerts: this.enableAlerts,\n enableSmartypants: this.enableSmartypants,\n enableSvgRenderer: this.enableSvgRenderer,\n enableHtml: this.enableHtml,\n enableJavaScript: this.enableJavaScript,\n enableHeadingIds: this.enableHeadingIds,\n headingIdPrefix: this.headingIdPrefix,\n mermaidTheme: this.mermaidTheme,\n sanitize: this.sanitize\n };\n\n // Configure service and parse\n this.markdownService.configureMarked(config);\n let html = this.markdownService.parse(this.data);\n\n // Check for mermaid and code blocks\n this.hasMermaid = html.includes('language-mermaid') || html.includes('class=\"mermaid\"');\n this.hasCodeBlocks = html.includes('<pre>') && html.includes('<code');\n\n // Sanitize if enabled\n // Note: We bypass Angular's sanitizer when SVG renderer or HTML passthrough is enabled\n // because it strips SVG elements and most HTML layout tags.\n const bypassAngularSanitizer = this.enableSvgRenderer || this.enableHtml;\n if (this.sanitize && !bypassAngularSanitizer) {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, html);\n html = sanitized || '';\n }\n\n // Strip JavaScript unless explicitly enabled\n // This removes <script> tags and on* event handlers while keeping layout HTML\n if (bypassAngularSanitizer && !this.enableJavaScript) {\n html = this.stripJavaScript(html);\n }\n\n // Trust the HTML for display\n this.renderedContent = this.sanitizer.bypassSecurityTrustHtml(html);\n this.cdr.markForCheck();\n\n // Schedule post-render processing for next tick (after DOM update)\n Promise.resolve().then(() => this.postRenderProcessing());\n }\n\n /**\n * Process rendered content after DOM update\n * Handles syntax highlighting, mermaid rendering, copy buttons, etc.\n */\n private async postRenderProcessing(): Promise<void> {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n // Add copy buttons to code blocks\n if (this.enableCodeCopy && this.hasCodeBlocks) {\n this.markdownService.addCodeCopyButtons(container as HTMLElement);\n }\n\n // Initialize collapsible headings\n if (this.enableCollapsibleHeadings) {\n this.markdownService.initializeCollapsibleHeadings(container as HTMLElement);\n this.setupCollapsibleListeners(container as HTMLElement);\n }\n\n // Render mermaid diagrams (async)\n if (this.enableMermaid && this.hasMermaid) {\n await this.markdownService.renderMermaid(container as HTMLElement);\n }\n\n // Setup heading click listeners\n if (this.enableHeadingIds) {\n this.setupHeadingClickListeners(container as HTMLElement);\n }\n\n // Setup code copy listeners for custom event emission\n if (this.enableCodeCopy) {\n this.setupCodeCopyListeners(container as HTMLElement);\n }\n\n // Emit rendered event\n const renderTime = performance.now() - this.renderStartTime;\n const headingIds = this.markdownService.getHeadingList();\n\n this.rendered.emit({\n html: (container as HTMLElement).innerHTML,\n renderTime,\n hasMermaid: this.hasMermaid,\n hasCodeBlocks: this.hasCodeBlocks,\n headingIds\n });\n }\n\n /**\n * Setup collapsible sections by adding toggle buttons and click listeners\n */\n private setupCollapsibleListeners(container: HTMLElement): void {\n const sections = container.querySelectorAll('.collapsible-section');\n\n sections.forEach((section) => {\n const wrapper = section.querySelector(':scope > .collapsible-heading-wrapper') as HTMLElement | null;\n if (!wrapper) return;\n\n // Check if toggle already exists\n if (wrapper.querySelector('.collapsible-toggle')) return;\n\n const isExpanded = !section.classList.contains('collapsed');\n const hasChildren = section.querySelector('.collapsible-section') !== null;\n\n // Create toggle button (chevron)\n const toggle = document.createElement('span');\n toggle.className = 'collapsible-toggle';\n toggle.setAttribute('role', 'button');\n toggle.setAttribute('tabindex', '0');\n toggle.setAttribute('aria-expanded', String(isExpanded));\n toggle.innerHTML = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M6 12l4-4-4-4\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n // Insert toggle before heading\n wrapper.insertBefore(toggle, wrapper.firstChild);\n\n // Add action buttons container (only if has children)\n if (hasChildren) {\n const actions = this.createActionButtons(section as HTMLElement);\n wrapper.appendChild(actions);\n }\n\n // Make the whole wrapper clickable\n wrapper.style.cursor = 'pointer';\n\n // Add click listener to wrapper (but not on action buttons)\n wrapper.addEventListener('click', (e: Event) => {\n const target = e.target as HTMLElement;\n // Don't toggle if clicking on action buttons\n if (target.closest('.collapsible-actions')) return;\n\n e.preventDefault();\n e.stopPropagation();\n this.toggleSection(section as HTMLElement, toggle);\n });\n\n // Add keyboard support\n wrapper.addEventListener('keydown', (e: Event) => {\n const target = e.target as HTMLElement;\n if (target.closest('.collapsible-actions')) return;\n\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.key === 'Enter' || keyEvent.key === ' ') {\n e.preventDefault();\n this.toggleSection(section as HTMLElement, toggle);\n }\n });\n });\n }\n\n /**\n * Create the expand/collapse all action buttons for sections with children\n */\n private createActionButtons(section: HTMLElement): HTMLElement {\n const container = document.createElement('span');\n container.className = 'collapsible-actions';\n\n // Expand all button\n const expandBtn = document.createElement('button');\n expandBtn.className = 'collapsible-action-btn expand-all';\n expandBtn.setAttribute('type', 'button');\n expandBtn.setAttribute('title', 'Expand all');\n expandBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 6l4 4 4-4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4 10l4 4 4-4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n expandBtn.addEventListener('click', (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n this.expandDescendants(section);\n // Also expand the section itself if collapsed\n if (section.classList.contains('collapsed')) {\n section.classList.remove('collapsed');\n const toggle = section.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) toggle.setAttribute('aria-expanded', 'true');\n }\n });\n\n // Collapse all button\n const collapseBtn = document.createElement('button');\n collapseBtn.className = 'collapsible-action-btn collapse-all';\n collapseBtn.setAttribute('type', 'button');\n collapseBtn.setAttribute('title', 'Collapse all');\n collapseBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 10l4-4 4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4 14l4-4 4 4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`;\n\n collapseBtn.addEventListener('click', (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n this.collapseDescendants(section);\n });\n\n container.appendChild(expandBtn);\n container.appendChild(collapseBtn);\n\n return container;\n }\n\n /**\n * Toggle a collapsible section\n * @param section The section element to toggle\n * @param toggle The toggle button element\n */\n private toggleSection(section: HTMLElement, toggle: HTMLElement): void {\n const isCollapsed = section.classList.contains('collapsed');\n\n // Toggle the section\n section.classList.toggle('collapsed');\n toggle.setAttribute('aria-expanded', String(isCollapsed));\n // Children retain their state - CSS handles visibility via parent collapse\n }\n\n /**\n * Collapse all descendant sections (used by action button)\n */\n private collapseDescendants(section: HTMLElement): void {\n const descendants = section.querySelectorAll('.collapsible-section');\n descendants.forEach((desc) => {\n desc.classList.add('collapsed');\n const toggle = desc.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) {\n toggle.setAttribute('aria-expanded', 'false');\n }\n });\n }\n\n /**\n * Expand all descendant sections (used by action button)\n */\n private expandDescendants(section: HTMLElement): void {\n const descendants = section.querySelectorAll('.collapsible-section');\n descendants.forEach((desc) => {\n desc.classList.remove('collapsed');\n const toggle = desc.querySelector(':scope > .collapsible-heading-wrapper .collapsible-toggle');\n if (toggle) {\n toggle.setAttribute('aria-expanded', 'true');\n }\n });\n }\n\n /**\n * Setup click listeners for heading anchors\n */\n private setupHeadingClickListeners(container: HTMLElement): void {\n const headings = container.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]');\n\n headings.forEach((heading) => {\n heading.addEventListener('click', () => {\n const id = heading.getAttribute('id') || '';\n const text = heading.textContent || '';\n const level = parseInt(heading.tagName.charAt(1), 10);\n\n this.headingClick.emit({\n id,\n text,\n level,\n raw: text\n });\n });\n });\n }\n\n /**\n * Setup listeners to emit code copy events\n */\n private setupCodeCopyListeners(container: HTMLElement): void {\n const copyButtons = container.querySelectorAll('.code-copy-btn');\n\n copyButtons.forEach((button) => {\n button.addEventListener('click', () => {\n const pre = button.closest('pre');\n const code = pre?.querySelector('code');\n if (code) {\n this.codeCopied.emit(code.textContent || '');\n }\n });\n });\n }\n\n /**\n * Cleanup event listeners\n */\n private cleanupEventListeners(): void {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n // Clone and replace to remove all listeners\n const clone = container.cloneNode(true);\n container.parentNode?.replaceChild(clone, container);\n }\n\n /**\n * Force a re-render of the markdown content\n */\n public refresh(): void {\n this.render();\n }\n\n /**\n * Get the current heading list (for TOC building)\n */\n public getHeadings(): HeadingInfo[] {\n return this.markdownService.getHeadingList();\n }\n\n /**\n * Scroll to a heading by ID\n */\n public scrollToHeading(headingId: string): void {\n const container = this.elementRef.nativeElement.querySelector('.mj-markdown-container');\n if (!container) return;\n\n const heading = container.querySelector(`#${headingId}`);\n if (heading) {\n heading.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n }\n\n /**\n * Strip JavaScript from HTML content while preserving layout HTML.\n * Removes <script> tags, on* event handlers, and javascript: URLs.\n */\n private stripJavaScript(html: string): string {\n // Remove <script> tags and their content\n html = html.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n\n // Remove on* event handlers (onclick, onload, onerror, etc.)\n html = html.replace(/\\s+on\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi, '');\n html = html.replace(/\\s+on\\w+\\s*=\\s*[^\\s>]+/gi, '');\n\n // Remove javascript: URLs from href and src attributes\n html = html.replace(/\\s+href\\s*=\\s*[\"']javascript:[^\"']*[\"']/gi, '');\n html = html.replace(/\\s+src\\s*=\\s*[\"']javascript:[^\"']*[\"']/gi, '');\n\n // Remove data: URLs that could contain scripts (data:text/html, etc.)\n html = html.replace(/\\s+src\\s*=\\s*[\"']data:text\\/html[^\"']*[\"']/gi, '');\n\n return html;\n }\n}\n"]}
@@ -33,7 +33,7 @@ import * as i0 from "@angular/core";
33
33
  * level for efficient sharing across the application.
34
34
  */
35
35
  export class MarkdownModule {
36
- static { this.ɵfac = function MarkdownModule_Factory(t) { return new (t || MarkdownModule)(); }; }
36
+ static { this.ɵfac = function MarkdownModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MarkdownModule)(); }; }
37
37
  static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: MarkdownModule }); }
38
38
  static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule] }); }
39
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.module.js","sourceRoot":"","sources":["../../src/lib/markdown.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;;AAGpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgBH,MAAM,OAAO,cAAc;+EAAd,cAAc;mEAAd,cAAc;uEAVvB,YAAY;;iFAUH,cAAc;cAf1B,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,iBAAiB;iBAClB;gBACD,OAAO,EAAE;oBACP,YAAY;iBACb;gBACD,OAAO,EAAE;oBACP,iBAAiB;iBAClB;gBACD,SAAS,EAAE;gBACT,oEAAoE;gBACpE,0DAA0D;iBAC3D;aACF;;wFACY,cAAc,mBAbvB,iBAAiB,aAGjB,YAAY,aAGZ,iBAAiB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MarkdownComponent } from './components/markdown.component';\nimport { MarkdownService } from './services/markdown.service';\n\n/**\n * MemberJunction Markdown Module\n *\n * A lightweight Angular module for rendering markdown content with:\n * - Prism.js syntax highlighting\n * - Mermaid diagram support\n * - Copy-to-clipboard for code blocks\n * - Collapsible heading sections\n * - GitHub-style alerts\n * - Heading anchor IDs\n *\n * Usage:\n * ```typescript\n * import { MarkdownModule } from '@memberjunction/ng-markdown';\n *\n * @NgModule({\n * imports: [MarkdownModule]\n * })\n * export class YourModule { }\n * ```\n *\n * Then in your template:\n * ```html\n * <mj-markdown [data]=\"markdownContent\"></mj-markdown>\n * ```\n *\n * Note: This module does NOT use forRoot(). Simply import it in any module\n * where you need markdown rendering. The MarkdownService is provided at root\n * level for efficient sharing across the application.\n */\n@NgModule({\n declarations: [\n MarkdownComponent\n ],\n imports: [\n CommonModule\n ],\n exports: [\n MarkdownComponent\n ],\n providers: [\n // MarkdownService is providedIn: 'root', so no need to provide here\n // This ensures a single instance is shared across the app\n ]\n})\nexport class MarkdownModule { }\n"]}
1
+ {"version":3,"file":"markdown.module.js","sourceRoot":"","sources":["../../src/lib/markdown.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;;AAGpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAgBH,MAAM,OAAO,cAAc;+GAAd,cAAc;mEAAd,cAAc;uEAVvB,YAAY;;iFAUH,cAAc;cAf1B,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,iBAAiB;iBAClB;gBACD,OAAO,EAAE;oBACP,YAAY;iBACb;gBACD,OAAO,EAAE;oBACP,iBAAiB;iBAClB;gBACD,SAAS,EAAE;gBACT,oEAAoE;gBACpE,0DAA0D;iBAC3D;aACF;;wFACY,cAAc,mBAbvB,iBAAiB,aAGjB,YAAY,aAGZ,iBAAiB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MarkdownComponent } from './components/markdown.component';\nimport { MarkdownService } from './services/markdown.service';\n\n/**\n * MemberJunction Markdown Module\n *\n * A lightweight Angular module for rendering markdown content with:\n * - Prism.js syntax highlighting\n * - Mermaid diagram support\n * - Copy-to-clipboard for code blocks\n * - Collapsible heading sections\n * - GitHub-style alerts\n * - Heading anchor IDs\n *\n * Usage:\n * ```typescript\n * import { MarkdownModule } from '@memberjunction/ng-markdown';\n *\n * @NgModule({\n * imports: [MarkdownModule]\n * })\n * export class YourModule { }\n * ```\n *\n * Then in your template:\n * ```html\n * <mj-markdown [data]=\"markdownContent\"></mj-markdown>\n * ```\n *\n * Note: This module does NOT use forRoot(). Simply import it in any module\n * where you need markdown rendering. The MarkdownService is provided at root\n * level for efficient sharing across the application.\n */\n@NgModule({\n declarations: [\n MarkdownComponent\n ],\n imports: [\n CommonModule\n ],\n exports: [\n MarkdownComponent\n ],\n providers: [\n // MarkdownService is providedIn: 'root', so no need to provide here\n // This ensures a single instance is shared across the app\n ]\n})\nexport class MarkdownModule { }\n"]}
@@ -511,7 +511,7 @@ export class MarkdownService {
511
511
  }
512
512
  }
513
513
  }
514
- static { this.ɵfac = function MarkdownService_Factory(t) { return new (t || MarkdownService)(); }; }
514
+ static { this.ɵfac = function MarkdownService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MarkdownService)(); }; }
515
515
  static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MarkdownService, factory: MarkdownService.ɵfac, providedIn: 'root' }); }
516
516
  }
517
517
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MarkdownService, [{
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.service.js","sourceRoot":"","sources":["../../../src/lib/services/markdown.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Marked } from 'marked';\nimport { markedHighlight } from 'marked-highlight';\nimport { gfmHeadingId, getHeadingList } from 'marked-gfm-heading-id';\nimport markedAlert from 'marked-alert';\nimport { markedSmartypants } from 'marked-smartypants';\nimport Prism from 'prismjs';\nimport mermaid from 'mermaid';\nimport {\n MarkdownConfig,\n DEFAULT_MARKDOWN_CONFIG,\n HeadingInfo,\n MarkdownRenderEvent\n} from '../types/markdown.types';\nimport { createCollapsibleHeadingsExtension } from '../extensions/collapsible-headings.extension';\nimport { createSvgRendererExtension } from '../extensions/svg-renderer.extension';\n\n// Import common Prism language components\n// Additional languages can be imported by the consuming application\nimport 'prismjs/components/prism-typescript';\nimport 'prismjs/components/prism-javascript';\nimport 'prismjs/components/prism-css';\nimport 'prismjs/components/prism-scss';\nimport 'prismjs/components/prism-json';\nimport 'prismjs/components/prism-bash';\nimport 'prismjs/components/prism-sql';\nimport 'prismjs/components/prism-python';\nimport 'prismjs/components/prism-csharp';\nimport 'prismjs/components/prism-java';\nimport 'prismjs/components/prism-markup';\nimport 'prismjs/components/prism-yaml';\nimport 'prismjs/components/prism-markdown';\nimport 'prismjs/components/prism-graphql';\n\n// Type for config with optional autoExpandLevels\ntype ResolvedMarkdownConfig = Required<Omit<MarkdownConfig, 'autoExpandLevels'>> & { autoExpandLevels?: number[] };\n\n/**\n * Service for parsing and rendering markdown content.\n * Uses marked.js with various extensions for syntax highlighting,\n * diagrams, alerts, and more.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class MarkdownService {\n private marked: Marked;\n private mermaidInitialized = false;\n private currentConfig: ResolvedMarkdownConfig = { ...DEFAULT_MARKDOWN_CONFIG };\n private headingList: HeadingInfo[] = [];\n\n constructor() {\n this.marked = new Marked();\n this.configureMarked(this.currentConfig);\n }\n\n /**\n * Configure the marked instance with the provided options\n */\n public configureMarked(config: MarkdownConfig): void {\n this.currentConfig = { ...DEFAULT_MARKDOWN_CONFIG, ...config };\n\n // Create a fresh Marked instance\n this.marked = new Marked();\n\n // Configure base options\n this.marked.setOptions({\n gfm: true,\n breaks: true\n });\n\n // Apply extensions based on config\n const extensions: any[] = [];\n\n // SVG code block renderer - MUST be before syntax highlighting\n // so it can intercept svg blocks before Prism processes them\n if (this.currentConfig.enableSvgRenderer) {\n extensions.push(createSvgRendererExtension());\n }\n\n // Syntax highlighting with Prism\n if (this.currentConfig.enableHighlight) {\n extensions.push(\n markedHighlight({\n langPrefix: 'language-',\n highlight: (code: string, lang: string) => {\n // Skip SVG blocks - they're handled by the SVG renderer\n if (lang === 'svg' && this.currentConfig.enableSvgRenderer) {\n return code;\n }\n if (lang && Prism.languages[lang]) {\n try {\n return Prism.highlight(code, Prism.languages[lang], lang);\n } catch (e) {\n console.warn(`Prism highlighting failed for language: ${lang}`, e);\n }\n }\n // Return code as-is if language not found or highlighting fails\n return code;\n }\n })\n );\n }\n\n // GitHub-style heading IDs\n if (this.currentConfig.enableHeadingIds) {\n extensions.push(\n gfmHeadingId({\n prefix: this.currentConfig.headingIdPrefix\n })\n );\n }\n\n // GitHub-style alerts\n if (this.currentConfig.enableAlerts) {\n extensions.push(markedAlert());\n }\n\n // Collapsible headings (custom extension)\n if (this.currentConfig.enableCollapsibleHeadings) {\n extensions.push(\n createCollapsibleHeadingsExtension({\n startLevel: this.currentConfig.collapsibleHeadingLevel,\n defaultExpanded: this.currentConfig.collapsibleDefaultExpanded,\n autoExpandLevels: this.currentConfig.autoExpandLevels\n })\n );\n }\n\n // Smartypants for typography (curly quotes, em/en dashes, ellipses)\n if (this.currentConfig.enableSmartypants) {\n extensions.push(markedSmartypants());\n }\n\n // Apply all extensions\n if (extensions.length > 0) {\n this.marked.use(...extensions);\n }\n }\n\n /**\n * Initialize Mermaid with the current theme configuration\n */\n private initializeMermaid(): void {\n if (this.mermaidInitialized) return;\n\n mermaid.initialize({\n startOnLoad: false,\n theme: this.currentConfig.mermaidTheme,\n securityLevel: 'loose',\n fontFamily: 'inherit',\n suppressErrorRendering: true // Suppress visual error diagrams - errors go to console only\n });\n\n this.mermaidInitialized = true;\n }\n\n /**\n * Parse markdown to HTML\n * @param markdown The markdown string to parse\n * @param config Optional config overrides for this parse operation\n * @returns The rendered HTML string\n */\n public parse(markdown: string, config?: Partial<MarkdownConfig>): string {\n if (!markdown) return '';\n\n // Apply config overrides if provided\n if (config) {\n this.configureMarked({ ...this.currentConfig, ...config });\n }\n\n try {\n // Preprocess markdown to fix indentation in HTML blocks\n // This prevents marked from treating indented HTML as code blocks\n let processedMarkdown = markdown;\n if (this.currentConfig.enableHtml) {\n processedMarkdown = this.normalizeHtmlBlockIndentation(markdown);\n }\n\n let html = this.marked.parse(processedMarkdown) as string;\n\n // Capture heading list after parsing\n if (this.currentConfig.enableHeadingIds) {\n this.headingList = getHeadingList() as HeadingInfo[];\n }\n\n // When HTML passthrough is enabled, fix incorrectly code-wrapped HTML\n // marked sometimes wraps inline HTML in <pre><code> blocks\n if (this.currentConfig.enableHtml) {\n html = this.unwrapMiscodedHtml(html);\n }\n\n return html;\n } catch (error) {\n console.error('Markdown parsing error:', error);\n return `<pre class=\"markdown-error\">${this.escapeHtml(markdown)}</pre>`;\n }\n }\n\n /**\n * Parse markdown asynchronously (useful for large documents)\n */\n public async parseAsync(markdown: string, config?: Partial<MarkdownConfig>): Promise<string> {\n return this.parse(markdown, config);\n }\n\n /**\n * Render Mermaid diagrams in a container element\n * Call this after the HTML has been inserted into the DOM\n * @param container The DOM element containing mermaid code blocks\n */\n public async renderMermaid(container: HTMLElement): Promise<boolean> {\n if (!this.currentConfig.enableMermaid) return false;\n\n this.initializeMermaid();\n\n // Find all mermaid code blocks\n const mermaidBlocks = container.querySelectorAll('pre > code.language-mermaid, .mermaid');\n\n if (mermaidBlocks.length === 0) return false;\n\n for (let i = 0; i < mermaidBlocks.length; i++) {\n const block = mermaidBlocks[i];\n const code = block.textContent || '';\n\n if (!code.trim()) continue;\n\n try {\n // Create a unique ID for this diagram\n const id = `mermaid-${Date.now()}-${i}`;\n\n // Render the diagram\n const { svg } = await mermaid.render(id, code);\n\n // Replace the code block with the rendered SVG\n const wrapper = document.createElement('div');\n wrapper.className = 'mermaid-diagram';\n wrapper.innerHTML = svg;\n\n // Replace the pre element (parent of code) or the mermaid element itself\n const elementToReplace = block.tagName === 'CODE' ? block.parentElement : block;\n elementToReplace?.parentNode?.replaceChild(wrapper, elementToReplace);\n } catch (error) {\n console.warn('Mermaid rendering failed:', error);\n // Add error class to show it failed\n const parent = block.tagName === 'CODE' ? block.parentElement : block;\n parent?.classList.add('mermaid-error');\n }\n }\n\n return true;\n }\n\n /**\n * Highlight code blocks with Prism\n * Call this after the HTML has been inserted into the DOM\n * @param container The DOM element containing code blocks\n */\n public highlightCode(container: HTMLElement): void {\n if (!this.currentConfig.enableHighlight) return;\n\n // Prism.highlightAllUnder handles finding and highlighting code blocks\n Prism.highlightAllUnder(container);\n }\n\n /**\n * Add copy buttons to code blocks\n * @param container The DOM element containing code blocks\n */\n public addCodeCopyButtons(container: HTMLElement): void {\n if (!this.currentConfig.enableCodeCopy) return;\n\n const codeBlocks = container.querySelectorAll('pre > code');\n\n codeBlocks.forEach((codeBlock) => {\n const pre = codeBlock.parentElement;\n if (!pre || pre.querySelector('.code-copy-btn')) return; // Already has button\n\n // Create copy button\n const button = document.createElement('button');\n button.className = 'code-copy-btn';\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n button.title = 'Copy code';\n button.type = 'button';\n\n button.addEventListener('click', async () => {\n const code = codeBlock.textContent || '';\n\n try {\n await navigator.clipboard.writeText(code);\n button.innerHTML = '<i class=\"fas fa-check\"></i>';\n button.classList.add('copied');\n\n setTimeout(() => {\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n button.classList.remove('copied');\n }, 2000);\n } catch (err) {\n console.error('Failed to copy code:', err);\n button.innerHTML = '<i class=\"fas fa-times\"></i>';\n\n setTimeout(() => {\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n }, 2000);\n }\n });\n\n // Add toolbar wrapper\n const toolbar = document.createElement('div');\n toolbar.className = 'code-toolbar';\n toolbar.appendChild(button);\n\n // Make pre position relative for absolute positioning of toolbar\n pre.style.position = 'relative';\n pre.appendChild(toolbar);\n });\n }\n\n /**\n * Initialize collapsible heading functionality\n * This method is a no-op - the component handles event binding\n * @param container The DOM element containing collapsible sections\n */\n public initializeCollapsibleHeadings(_container: HTMLElement): void {\n // Event binding is handled by the component's setupCollapsibleListeners\n // This method exists for API compatibility but does nothing\n }\n\n /**\n * Get the list of headings from the last parsed document\n * Useful for building table of contents\n */\n public getHeadingList(): HeadingInfo[] {\n return this.headingList;\n }\n\n /**\n * Get the current configuration\n */\n public getConfig(): ResolvedMarkdownConfig {\n return { ...this.currentConfig };\n }\n\n /**\n * Reset configuration to defaults\n */\n public resetConfig(): void {\n this.configureMarked(DEFAULT_MARKDOWN_CONFIG);\n }\n\n /**\n * Check if a language is supported by Prism\n */\n public isLanguageSupported(lang: string): boolean {\n return !!Prism.languages[lang];\n }\n\n /**\n * Get list of supported Prism languages\n */\n public getSupportedLanguages(): string[] {\n return Object.keys(Prism.languages).filter(\n lang => typeof Prism.languages[lang] === 'object'\n );\n }\n\n /**\n * Escape HTML entities for safe display\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Fix HTML that was incorrectly wrapped in <pre><code> blocks by marked.\n * This happens when marked interprets inline HTML (especially indented HTML)\n * as code blocks. We detect this by checking if the code block content\n * looks like valid HTML structure rather than actual code.\n *\n * Only processes code blocks WITHOUT a language class (e.g., language-javascript)\n * to avoid unwrapping intentional code examples.\n */\n private unwrapMiscodedHtml(html: string): string {\n // Quick check - if no pre tags, nothing to do\n if (!html.includes('<pre>')) {\n return html;\n }\n\n // Skip if SVG is present - DOMParser mangles SVG elements like <rect>\n // when parsing as 'text/html' due to namespace issues\n if (html.includes('<svg')) {\n return html;\n }\n\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<div>${html}</div>`, 'text/html');\n const container = doc.body.firstChild as HTMLElement;\n\n if (!container) return html;\n\n // Find all pre > code elements WITHOUT a language class\n // Code blocks with language classes (language-javascript, etc.) are intentional\n const preElements = container.querySelectorAll('pre');\n let modified = false;\n\n for (const pre of Array.from(preElements)) {\n const code = pre.querySelector('code');\n if (!code) continue;\n\n // Skip if code has a language class - it's intentional code\n const hasLanguageClass = code.className && /language-\\w+/.test(code.className);\n if (hasLanguageClass) continue;\n\n // Get the text content (this is HTML-decoded by the browser)\n const content = code.textContent?.trim() || '';\n\n // Check if this looks like HTML that was incorrectly wrapped\n if (this.looksLikeStructuralHtml(content)) {\n // Verify it parses as valid HTML with actual elements\n const testDoc = parser.parseFromString(content, 'text/html');\n const hasStructure = testDoc.body.children.length > 0 ||\n (testDoc.body.innerHTML.trim().length > 0 &&\n testDoc.body.innerHTML.includes('<'));\n\n if (hasStructure) {\n // Replace the <pre> with the actual HTML content\n const wrapper = document.createElement('div');\n wrapper.className = 'unwrapped-html';\n wrapper.innerHTML = content;\n\n // Move all children from wrapper to replace pre\n const fragment = document.createDocumentFragment();\n while (wrapper.firstChild) {\n fragment.appendChild(wrapper.firstChild);\n }\n pre.parentNode?.replaceChild(fragment, pre);\n modified = true;\n }\n }\n }\n\n if (modified) {\n return container.innerHTML;\n }\n } catch (error) {\n console.warn('Error in unwrapMiscodedHtml:', error);\n }\n\n return html;\n }\n\n /**\n * Check if content looks like structural HTML that was incorrectly\n * wrapped in a code block. We look for common HTML element patterns\n * that indicate this is meant to be rendered HTML, not code.\n */\n private looksLikeStructuralHtml(content: string): boolean {\n // Must start with < to be HTML\n if (!content.startsWith('<')) return false;\n\n // Must end with > (closing tag)\n if (!content.endsWith('>')) return false;\n\n // Check for common structural HTML tags that indicate layout HTML\n // These are tags that would typically appear in a UI mockup/prototype\n const structuralTagPattern = /<(div|span|table|tr|td|th|thead|tbody|p|ul|ol|li|section|article|header|footer|nav|main|aside|form|input|button|label|select|option|textarea|h[1-6]|img|a|strong|em|b|i|br|hr)\\b/i;\n\n if (!structuralTagPattern.test(content)) return false;\n\n // Additional check: should have multiple tags or nested structure\n // Single self-closing tags like <br> or <img> shouldn't trigger unwrapping\n const tagCount = (content.match(/<\\w+/g) || []).length;\n if (tagCount < 2) return false;\n\n // Check it's not just showing HTML as an example (common in docs)\n // If content has lots of &lt; or &gt; it's probably escaped HTML being shown\n if (content.includes('&lt;') || content.includes('&gt;')) return false;\n\n return true;\n }\n\n /**\n * Normalize indentation in HTML blocks to prevent marked from treating\n * indented HTML as code blocks (4 spaces = code block in markdown).\n *\n * This finds HTML blocks (starting with common block-level tags) and\n * removes ALL leading whitespace from lines within those blocks to ensure\n * marked doesn't interpret any nested content as code blocks.\n */\n private normalizeHtmlBlockIndentation(markdown: string): string {\n // Match HTML blocks that start with common block-level tags\n // These tags indicate structural HTML that should be rendered, not code\n const htmlBlockTags = [\n 'div', 'table', 'thead', 'tbody', 'tr', 'td', 'th',\n 'ul', 'ol', 'li', 'p', 'section', 'article', 'header',\n 'footer', 'nav', 'main', 'aside', 'form', 'svg', 'figure'\n ];\n\n const tagPattern = htmlBlockTags.join('|');\n // Match opening tag at start of line (possibly with leading whitespace)\n const htmlBlockStartRegex = new RegExp(`^[ \\\\t]*<(${tagPattern})\\\\b`, 'i');\n\n const lines = markdown.split('\\n');\n const result: string[] = [];\n let inHtmlBlock = false;\n let tagStack: string[] = [];\n\n for (const line of lines) {\n const trimmedLine = line.trimStart();\n\n if (!inHtmlBlock) {\n // Check if this line starts an HTML block\n const match = trimmedLine.match(htmlBlockStartRegex);\n if (match) {\n inHtmlBlock = true;\n const tag = match[1].toLowerCase();\n\n // Push to stack if it's not a self-closing tag on this line\n if (!this.isSelfClosingLine(trimmedLine, tag)) {\n tagStack.push(tag);\n }\n\n // Remove leading indentation\n result.push(trimmedLine);\n continue;\n }\n result.push(line);\n } else {\n // We're inside an HTML block - remove ALL leading whitespace\n // to prevent any nested content from being treated as code blocks\n\n // Track tag stack for proper nesting\n this.updateTagStack(trimmedLine, tagStack, htmlBlockTags);\n\n // Remove leading whitespace from this line\n result.push(trimmedLine);\n\n // Check if we've closed all HTML blocks\n if (tagStack.length === 0) {\n inHtmlBlock = false;\n }\n }\n }\n\n return result.join('\\n');\n }\n\n /**\n * Check if a line contains a self-closing tag or opens and closes the same tag\n */\n private isSelfClosingLine(line: string, tag: string): boolean {\n // Check for self-closing syntax: <tag ... />\n if (new RegExp(`<${tag}[^>]*/>`,'i').test(line)) {\n return true;\n }\n // Check if tag opens and closes on same line: <tag>...</tag>\n const openCount = (line.match(new RegExp(`<${tag}\\\\b`, 'gi')) || []).length;\n const closeCount = (line.match(new RegExp(`</${tag}>`, 'gi')) || []).length;\n return openCount > 0 && openCount === closeCount;\n }\n\n /**\n * Update the tag stack based on opening/closing tags in the line\n */\n private updateTagStack(line: string, tagStack: string[], validTags: string[]): void {\n // Find all opening tags\n const openTagRegex = /<(\\w+)\\b[^>]*(?<!\\/)>/gi;\n const closeTagRegex = /<\\/(\\w+)>/gi;\n\n let match;\n\n // Process closing tags first (they might close tags opened earlier)\n while ((match = closeTagRegex.exec(line)) !== null) {\n const tag = match[1].toLowerCase();\n const idx = tagStack.lastIndexOf(tag);\n if (idx !== -1) {\n tagStack.splice(idx, 1);\n }\n }\n\n // Process opening tags\n while ((match = openTagRegex.exec(line)) !== null) {\n const tag = match[1].toLowerCase();\n // Only track block-level tags we care about\n if (validTags.includes(tag)) {\n // Don't add if it's self-closing or closed on same line\n if (!this.isSelfClosingLine(line, tag)) {\n // Check if there's a closing tag for this specific opening\n const closeRegex = new RegExp(`</${tag}>`, 'gi');\n const opens = (line.match(new RegExp(`<${tag}\\\\b`, 'gi')) || []).length;\n const closes = (line.match(closeRegex) || []).length;\n if (opens > closes) {\n tagStack.push(tag);\n }\n }\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"markdown.service.js","sourceRoot":"","sources":["../../../src/lib/services/markdown.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAEL,uBAAuB,EAGxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kCAAkC,EAAE,MAAM,8CAA8C,CAAC;AAClG,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAElF,0CAA0C;AAC1C,oEAAoE;AACpE,OAAO,qCAAqC,CAAC;AAC7C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,8BAA8B,CAAC;AACtC,OAAO,+BAA+B,CAAC;AACvC,OAAO,+BAA+B,CAAC;AACvC,OAAO,+BAA+B,CAAC;AACvC,OAAO,8BAA8B,CAAC;AACtC,OAAO,iCAAiC,CAAC;AACzC,OAAO,iCAAiC,CAAC;AACzC,OAAO,+BAA+B,CAAC;AACvC,OAAO,iCAAiC,CAAC;AACzC,OAAO,+BAA+B,CAAC;AACvC,OAAO,mCAAmC,CAAC;AAC3C,OAAO,kCAAkC,CAAC;;AAK1C;;;;GAIG;AAIH,MAAM,OAAO,eAAe;IAM1B;QAJQ,uBAAkB,GAAG,KAAK,CAAC;QAC3B,kBAAa,GAA2B,EAAE,GAAG,uBAAuB,EAAE,CAAC;QACvE,gBAAW,GAAkB,EAAE,CAAC;QAGtC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,MAAsB;QAC3C,IAAI,CAAC,aAAa,GAAG,EAAE,GAAG,uBAAuB,EAAE,GAAG,MAAM,EAAE,CAAC;QAE/D,iCAAiC;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAE3B,yBAAyB;QACzB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YACrB,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QAEH,mCAAmC;QACnC,MAAM,UAAU,GAAU,EAAE,CAAC;QAE7B,+DAA+D;QAC/D,6DAA6D;QAC7D,IAAI,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;YACzC,UAAU,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;YACvC,UAAU,CAAC,IAAI,CACb,eAAe,CAAC;gBACd,UAAU,EAAE,WAAW;gBACvB,SAAS,EAAE,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE;oBACxC,wDAAwD;oBACxD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;wBAC3D,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,IAAI,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;wBAClC,IAAI,CAAC;4BACH,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;wBAC5D,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,OAAO,CAAC,IAAI,CAAC,2CAA2C,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;wBACrE,CAAC;oBACH,CAAC;oBACD,gEAAgE;oBAChE,OAAO,IAAI,CAAC;gBACd,CAAC;aACF,CAAC,CACH,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;YACxC,UAAU,CAAC,IAAI,CACb,YAAY,CAAC;gBACX,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,eAAe;aAC3C,CAAC,CACH,CAAC;QACJ,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;YACpC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACjC,CAAC;QAED,0CAA0C;QAC1C,IAAI,IAAI,CAAC,aAAa,CAAC,yBAAyB,EAAE,CAAC;YACjD,UAAU,CAAC,IAAI,CACb,kCAAkC,CAAC;gBACjC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,uBAAuB;gBACtD,eAAe,EAAE,IAAI,CAAC,aAAa,CAAC,0BAA0B;gBAC9D,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB;aACtD,CAAC,CACH,CAAC;QACJ,CAAC;QAED,oEAAoE;QACpE,IAAI,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;YACzC,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvC,CAAC;QAED,uBAAuB;QACvB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,IAAI,CAAC,kBAAkB;YAAE,OAAO;QAEpC,OAAO,CAAC,UAAU,CAAC;YACjB,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,YAAY;YACtC,aAAa,EAAE,OAAO;YACtB,UAAU,EAAE,SAAS;YACrB,sBAAsB,EAAE,IAAI,CAAC,6DAA6D;SAC3F,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,QAAgB,EAAE,MAAgC;QAC7D,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QAEzB,qCAAqC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,CAAC;YACH,wDAAwD;YACxD,kEAAkE;YAClE,IAAI,iBAAiB,GAAG,QAAQ,CAAC;YACjC,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;gBAClC,iBAAiB,GAAG,IAAI,CAAC,6BAA6B,CAAC,QAAQ,CAAC,CAAC;YACnE,CAAC;YAED,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAW,CAAC;YAE1D,qCAAqC;YACrC,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;gBACxC,IAAI,CAAC,WAAW,GAAG,cAAc,EAAmB,CAAC;YACvD,CAAC;YAED,sEAAsE;YACtE,2DAA2D;YAC3D,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;gBAClC,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO,+BAA+B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1E,CAAC;IACH,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,MAAgC;QACxE,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,aAAa,CAAC,SAAsB;QAC/C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa;YAAE,OAAO,KAAK,CAAC;QAEpD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,+BAA+B;QAC/B,MAAM,aAAa,GAAG,SAAS,CAAC,gBAAgB,CAAC,uCAAuC,CAAC,CAAC;QAE1F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAE7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;YAErC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAE3B,IAAI,CAAC;gBACH,sCAAsC;gBACtC,MAAM,EAAE,GAAG,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBAExC,qBAAqB;gBACrB,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAE/C,+CAA+C;gBAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC9C,OAAO,CAAC,SAAS,GAAG,iBAAiB,CAAC;gBACtC,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC;gBAExB,yEAAyE;gBACzE,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;gBAChF,gBAAgB,EAAE,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YACxE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBACjD,oCAAoC;gBACpC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;gBACtE,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,SAAsB;QACzC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,eAAe;YAAE,OAAO;QAEhD,uEAAuE;QACvE,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,SAAsB;QAC9C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc;YAAE,OAAO;QAE/C,MAAM,UAAU,GAAG,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAE5D,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC/B,MAAM,GAAG,GAAG,SAAS,CAAC,aAAa,CAAC;YACpC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,gBAAgB,CAAC;gBAAE,OAAO,CAAC,qBAAqB;YAE9E,qBAAqB;YACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,SAAS,GAAG,eAAe,CAAC;YACnC,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;YACjD,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;YAC3B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;YAEvB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC;gBAEzC,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC1C,MAAM,CAAC,SAAS,GAAG,8BAA8B,CAAC;oBAClD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBAE/B,UAAU,CAAC,GAAG,EAAE;wBACd,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;wBACjD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACpC,CAAC,EAAE,IAAI,CAAC,CAAC;gBACX,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;oBAC3C,MAAM,CAAC,SAAS,GAAG,8BAA8B,CAAC;oBAElD,UAAU,CAAC,GAAG,EAAE;wBACd,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;oBACnD,CAAC,EAAE,IAAI,CAAC,CAAC;gBACX,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,sBAAsB;YACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,GAAG,cAAc,CAAC;YACnC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAE5B,iEAAiE;YACjE,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;YAChC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,6BAA6B,CAAC,UAAuB;QAC1D,wEAAwE;QACxE,4DAA4D;IAC9D,CAAC;IAED;;;OAGG;IACI,cAAc;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,SAAS;QACd,OAAO,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;IACnC,CAAC;IAED;;OAEG;IACI,WAAW;QAChB,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACI,mBAAmB,CAAC,IAAY;QACrC,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACI,qBAAqB;QAC1B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CACxC,IAAI,CAAC,EAAE,CAAC,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,QAAQ,CAClD,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,IAAY;QAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;QACvB,OAAO,GAAG,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CAAC,IAAY;QACrC,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,sEAAsE;QACtE,sDAAsD;QACtD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,eAAe,CAAC,QAAQ,IAAI,QAAQ,EAAE,WAAW,CAAC,CAAC;YACtE,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,UAAyB,CAAC;YAErD,IAAI,CAAC,SAAS;gBAAE,OAAO,IAAI,CAAC;YAE5B,wDAAwD;YACxD,gFAAgF;YAChF,MAAM,WAAW,GAAG,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACtD,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBACvC,IAAI,CAAC,IAAI;oBAAE,SAAS;gBAEpB,4DAA4D;gBAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/E,IAAI,gBAAgB;oBAAE,SAAS;gBAE/B,6DAA6D;gBAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAE/C,6DAA6D;gBAC7D,IAAI,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1C,sDAAsD;oBACtD,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;oBAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;wBACjC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;4BACxC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;oBAE3D,IAAI,YAAY,EAAE,CAAC;wBACjB,iDAAiD;wBACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBAC9C,OAAO,CAAC,SAAS,GAAG,gBAAgB,CAAC;wBACrC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC;wBAE5B,gDAAgD;wBAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;wBACnD,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC;4BAC1B,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;wBAC3C,CAAC;wBACD,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;wBAC5C,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,SAAS,CAAC,SAAS,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACK,uBAAuB,CAAC,OAAe;QAC7C,+BAA+B;QAC/B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAE3C,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAEzC,kEAAkE;QAClE,sEAAsE;QACtE,MAAM,oBAAoB,GAAG,mLAAmL,CAAC;QAEjN,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QAEtD,kEAAkE;QAClE,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACvD,IAAI,QAAQ,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/B,kEAAkE;QAClE,6EAA6E;QAC7E,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACK,6BAA6B,CAAC,QAAgB;QACpD,4DAA4D;QAC5D,wEAAwE;QACxE,MAAM,aAAa,GAAG;YACpB,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;YAClD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ;YACrD,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ;SAC1D,CAAC;QAEF,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,wEAAwE;QACxE,MAAM,mBAAmB,GAAG,IAAI,MAAM,CAAC,aAAa,UAAU,MAAM,EAAE,GAAG,CAAC,CAAC;QAE3E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,QAAQ,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAErC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,0CAA0C;gBAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACrD,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,GAAG,IAAI,CAAC;oBACnB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;oBAEnC,4DAA4D;oBAC5D,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;wBAC9C,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;oBAED,6BAA6B;oBAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACzB,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,6DAA6D;gBAC7D,kEAAkE;gBAElE,qCAAqC;gBACrC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;gBAE1D,2CAA2C;gBAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAEzB,wCAAwC;gBACxC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,WAAW,GAAG,KAAK,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,IAAY,EAAE,GAAW;QACjD,6CAA6C;QAC7C,IAAI,IAAI,MAAM,CAAC,IAAI,GAAG,SAAS,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,6DAA6D;QAC7D,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC5E,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC5E,OAAO,SAAS,GAAG,CAAC,IAAI,SAAS,KAAK,UAAU,CAAC;IACnD,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAY,EAAE,QAAkB,EAAE,SAAmB;QAC1E,wBAAwB;QACxB,MAAM,YAAY,GAAG,yBAAyB,CAAC;QAC/C,MAAM,aAAa,GAAG,aAAa,CAAC;QAEpC,IAAI,KAAK,CAAC;QAEV,oEAAoE;QACpE,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACnC,4CAA4C;YAC5C,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,wDAAwD;gBACxD,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;oBACvC,2DAA2D;oBAC3D,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;oBACjD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;oBACxE,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;oBACrD,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;wBACnB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;gHA3iBU,eAAe;uEAAf,eAAe,WAAf,eAAe,mBAFd,MAAM;;iFAEP,eAAe;cAH3B,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Marked } from 'marked';\nimport { markedHighlight } from 'marked-highlight';\nimport { gfmHeadingId, getHeadingList } from 'marked-gfm-heading-id';\nimport markedAlert from 'marked-alert';\nimport { markedSmartypants } from 'marked-smartypants';\nimport Prism from 'prismjs';\nimport mermaid from 'mermaid';\nimport {\n MarkdownConfig,\n DEFAULT_MARKDOWN_CONFIG,\n HeadingInfo,\n MarkdownRenderEvent\n} from '../types/markdown.types';\nimport { createCollapsibleHeadingsExtension } from '../extensions/collapsible-headings.extension';\nimport { createSvgRendererExtension } from '../extensions/svg-renderer.extension';\n\n// Import common Prism language components\n// Additional languages can be imported by the consuming application\nimport 'prismjs/components/prism-typescript';\nimport 'prismjs/components/prism-javascript';\nimport 'prismjs/components/prism-css';\nimport 'prismjs/components/prism-scss';\nimport 'prismjs/components/prism-json';\nimport 'prismjs/components/prism-bash';\nimport 'prismjs/components/prism-sql';\nimport 'prismjs/components/prism-python';\nimport 'prismjs/components/prism-csharp';\nimport 'prismjs/components/prism-java';\nimport 'prismjs/components/prism-markup';\nimport 'prismjs/components/prism-yaml';\nimport 'prismjs/components/prism-markdown';\nimport 'prismjs/components/prism-graphql';\n\n// Type for config with optional autoExpandLevels\ntype ResolvedMarkdownConfig = Required<Omit<MarkdownConfig, 'autoExpandLevels'>> & { autoExpandLevels?: number[] };\n\n/**\n * Service for parsing and rendering markdown content.\n * Uses marked.js with various extensions for syntax highlighting,\n * diagrams, alerts, and more.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class MarkdownService {\n private marked: Marked;\n private mermaidInitialized = false;\n private currentConfig: ResolvedMarkdownConfig = { ...DEFAULT_MARKDOWN_CONFIG };\n private headingList: HeadingInfo[] = [];\n\n constructor() {\n this.marked = new Marked();\n this.configureMarked(this.currentConfig);\n }\n\n /**\n * Configure the marked instance with the provided options\n */\n public configureMarked(config: MarkdownConfig): void {\n this.currentConfig = { ...DEFAULT_MARKDOWN_CONFIG, ...config };\n\n // Create a fresh Marked instance\n this.marked = new Marked();\n\n // Configure base options\n this.marked.setOptions({\n gfm: true,\n breaks: true\n });\n\n // Apply extensions based on config\n const extensions: any[] = [];\n\n // SVG code block renderer - MUST be before syntax highlighting\n // so it can intercept svg blocks before Prism processes them\n if (this.currentConfig.enableSvgRenderer) {\n extensions.push(createSvgRendererExtension());\n }\n\n // Syntax highlighting with Prism\n if (this.currentConfig.enableHighlight) {\n extensions.push(\n markedHighlight({\n langPrefix: 'language-',\n highlight: (code: string, lang: string) => {\n // Skip SVG blocks - they're handled by the SVG renderer\n if (lang === 'svg' && this.currentConfig.enableSvgRenderer) {\n return code;\n }\n if (lang && Prism.languages[lang]) {\n try {\n return Prism.highlight(code, Prism.languages[lang], lang);\n } catch (e) {\n console.warn(`Prism highlighting failed for language: ${lang}`, e);\n }\n }\n // Return code as-is if language not found or highlighting fails\n return code;\n }\n })\n );\n }\n\n // GitHub-style heading IDs\n if (this.currentConfig.enableHeadingIds) {\n extensions.push(\n gfmHeadingId({\n prefix: this.currentConfig.headingIdPrefix\n })\n );\n }\n\n // GitHub-style alerts\n if (this.currentConfig.enableAlerts) {\n extensions.push(markedAlert());\n }\n\n // Collapsible headings (custom extension)\n if (this.currentConfig.enableCollapsibleHeadings) {\n extensions.push(\n createCollapsibleHeadingsExtension({\n startLevel: this.currentConfig.collapsibleHeadingLevel,\n defaultExpanded: this.currentConfig.collapsibleDefaultExpanded,\n autoExpandLevels: this.currentConfig.autoExpandLevels\n })\n );\n }\n\n // Smartypants for typography (curly quotes, em/en dashes, ellipses)\n if (this.currentConfig.enableSmartypants) {\n extensions.push(markedSmartypants());\n }\n\n // Apply all extensions\n if (extensions.length > 0) {\n this.marked.use(...extensions);\n }\n }\n\n /**\n * Initialize Mermaid with the current theme configuration\n */\n private initializeMermaid(): void {\n if (this.mermaidInitialized) return;\n\n mermaid.initialize({\n startOnLoad: false,\n theme: this.currentConfig.mermaidTheme,\n securityLevel: 'loose',\n fontFamily: 'inherit',\n suppressErrorRendering: true // Suppress visual error diagrams - errors go to console only\n });\n\n this.mermaidInitialized = true;\n }\n\n /**\n * Parse markdown to HTML\n * @param markdown The markdown string to parse\n * @param config Optional config overrides for this parse operation\n * @returns The rendered HTML string\n */\n public parse(markdown: string, config?: Partial<MarkdownConfig>): string {\n if (!markdown) return '';\n\n // Apply config overrides if provided\n if (config) {\n this.configureMarked({ ...this.currentConfig, ...config });\n }\n\n try {\n // Preprocess markdown to fix indentation in HTML blocks\n // This prevents marked from treating indented HTML as code blocks\n let processedMarkdown = markdown;\n if (this.currentConfig.enableHtml) {\n processedMarkdown = this.normalizeHtmlBlockIndentation(markdown);\n }\n\n let html = this.marked.parse(processedMarkdown) as string;\n\n // Capture heading list after parsing\n if (this.currentConfig.enableHeadingIds) {\n this.headingList = getHeadingList() as HeadingInfo[];\n }\n\n // When HTML passthrough is enabled, fix incorrectly code-wrapped HTML\n // marked sometimes wraps inline HTML in <pre><code> blocks\n if (this.currentConfig.enableHtml) {\n html = this.unwrapMiscodedHtml(html);\n }\n\n return html;\n } catch (error) {\n console.error('Markdown parsing error:', error);\n return `<pre class=\"markdown-error\">${this.escapeHtml(markdown)}</pre>`;\n }\n }\n\n /**\n * Parse markdown asynchronously (useful for large documents)\n */\n public async parseAsync(markdown: string, config?: Partial<MarkdownConfig>): Promise<string> {\n return this.parse(markdown, config);\n }\n\n /**\n * Render Mermaid diagrams in a container element\n * Call this after the HTML has been inserted into the DOM\n * @param container The DOM element containing mermaid code blocks\n */\n public async renderMermaid(container: HTMLElement): Promise<boolean> {\n if (!this.currentConfig.enableMermaid) return false;\n\n this.initializeMermaid();\n\n // Find all mermaid code blocks\n const mermaidBlocks = container.querySelectorAll('pre > code.language-mermaid, .mermaid');\n\n if (mermaidBlocks.length === 0) return false;\n\n for (let i = 0; i < mermaidBlocks.length; i++) {\n const block = mermaidBlocks[i];\n const code = block.textContent || '';\n\n if (!code.trim()) continue;\n\n try {\n // Create a unique ID for this diagram\n const id = `mermaid-${Date.now()}-${i}`;\n\n // Render the diagram\n const { svg } = await mermaid.render(id, code);\n\n // Replace the code block with the rendered SVG\n const wrapper = document.createElement('div');\n wrapper.className = 'mermaid-diagram';\n wrapper.innerHTML = svg;\n\n // Replace the pre element (parent of code) or the mermaid element itself\n const elementToReplace = block.tagName === 'CODE' ? block.parentElement : block;\n elementToReplace?.parentNode?.replaceChild(wrapper, elementToReplace);\n } catch (error) {\n console.warn('Mermaid rendering failed:', error);\n // Add error class to show it failed\n const parent = block.tagName === 'CODE' ? block.parentElement : block;\n parent?.classList.add('mermaid-error');\n }\n }\n\n return true;\n }\n\n /**\n * Highlight code blocks with Prism\n * Call this after the HTML has been inserted into the DOM\n * @param container The DOM element containing code blocks\n */\n public highlightCode(container: HTMLElement): void {\n if (!this.currentConfig.enableHighlight) return;\n\n // Prism.highlightAllUnder handles finding and highlighting code blocks\n Prism.highlightAllUnder(container);\n }\n\n /**\n * Add copy buttons to code blocks\n * @param container The DOM element containing code blocks\n */\n public addCodeCopyButtons(container: HTMLElement): void {\n if (!this.currentConfig.enableCodeCopy) return;\n\n const codeBlocks = container.querySelectorAll('pre > code');\n\n codeBlocks.forEach((codeBlock) => {\n const pre = codeBlock.parentElement;\n if (!pre || pre.querySelector('.code-copy-btn')) return; // Already has button\n\n // Create copy button\n const button = document.createElement('button');\n button.className = 'code-copy-btn';\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n button.title = 'Copy code';\n button.type = 'button';\n\n button.addEventListener('click', async () => {\n const code = codeBlock.textContent || '';\n\n try {\n await navigator.clipboard.writeText(code);\n button.innerHTML = '<i class=\"fas fa-check\"></i>';\n button.classList.add('copied');\n\n setTimeout(() => {\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n button.classList.remove('copied');\n }, 2000);\n } catch (err) {\n console.error('Failed to copy code:', err);\n button.innerHTML = '<i class=\"fas fa-times\"></i>';\n\n setTimeout(() => {\n button.innerHTML = '<i class=\"fas fa-copy\"></i>';\n }, 2000);\n }\n });\n\n // Add toolbar wrapper\n const toolbar = document.createElement('div');\n toolbar.className = 'code-toolbar';\n toolbar.appendChild(button);\n\n // Make pre position relative for absolute positioning of toolbar\n pre.style.position = 'relative';\n pre.appendChild(toolbar);\n });\n }\n\n /**\n * Initialize collapsible heading functionality\n * This method is a no-op - the component handles event binding\n * @param container The DOM element containing collapsible sections\n */\n public initializeCollapsibleHeadings(_container: HTMLElement): void {\n // Event binding is handled by the component's setupCollapsibleListeners\n // This method exists for API compatibility but does nothing\n }\n\n /**\n * Get the list of headings from the last parsed document\n * Useful for building table of contents\n */\n public getHeadingList(): HeadingInfo[] {\n return this.headingList;\n }\n\n /**\n * Get the current configuration\n */\n public getConfig(): ResolvedMarkdownConfig {\n return { ...this.currentConfig };\n }\n\n /**\n * Reset configuration to defaults\n */\n public resetConfig(): void {\n this.configureMarked(DEFAULT_MARKDOWN_CONFIG);\n }\n\n /**\n * Check if a language is supported by Prism\n */\n public isLanguageSupported(lang: string): boolean {\n return !!Prism.languages[lang];\n }\n\n /**\n * Get list of supported Prism languages\n */\n public getSupportedLanguages(): string[] {\n return Object.keys(Prism.languages).filter(\n lang => typeof Prism.languages[lang] === 'object'\n );\n }\n\n /**\n * Escape HTML entities for safe display\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Fix HTML that was incorrectly wrapped in <pre><code> blocks by marked.\n * This happens when marked interprets inline HTML (especially indented HTML)\n * as code blocks. We detect this by checking if the code block content\n * looks like valid HTML structure rather than actual code.\n *\n * Only processes code blocks WITHOUT a language class (e.g., language-javascript)\n * to avoid unwrapping intentional code examples.\n */\n private unwrapMiscodedHtml(html: string): string {\n // Quick check - if no pre tags, nothing to do\n if (!html.includes('<pre>')) {\n return html;\n }\n\n // Skip if SVG is present - DOMParser mangles SVG elements like <rect>\n // when parsing as 'text/html' due to namespace issues\n if (html.includes('<svg')) {\n return html;\n }\n\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(`<div>${html}</div>`, 'text/html');\n const container = doc.body.firstChild as HTMLElement;\n\n if (!container) return html;\n\n // Find all pre > code elements WITHOUT a language class\n // Code blocks with language classes (language-javascript, etc.) are intentional\n const preElements = container.querySelectorAll('pre');\n let modified = false;\n\n for (const pre of Array.from(preElements)) {\n const code = pre.querySelector('code');\n if (!code) continue;\n\n // Skip if code has a language class - it's intentional code\n const hasLanguageClass = code.className && /language-\\w+/.test(code.className);\n if (hasLanguageClass) continue;\n\n // Get the text content (this is HTML-decoded by the browser)\n const content = code.textContent?.trim() || '';\n\n // Check if this looks like HTML that was incorrectly wrapped\n if (this.looksLikeStructuralHtml(content)) {\n // Verify it parses as valid HTML with actual elements\n const testDoc = parser.parseFromString(content, 'text/html');\n const hasStructure = testDoc.body.children.length > 0 ||\n (testDoc.body.innerHTML.trim().length > 0 &&\n testDoc.body.innerHTML.includes('<'));\n\n if (hasStructure) {\n // Replace the <pre> with the actual HTML content\n const wrapper = document.createElement('div');\n wrapper.className = 'unwrapped-html';\n wrapper.innerHTML = content;\n\n // Move all children from wrapper to replace pre\n const fragment = document.createDocumentFragment();\n while (wrapper.firstChild) {\n fragment.appendChild(wrapper.firstChild);\n }\n pre.parentNode?.replaceChild(fragment, pre);\n modified = true;\n }\n }\n }\n\n if (modified) {\n return container.innerHTML;\n }\n } catch (error) {\n console.warn('Error in unwrapMiscodedHtml:', error);\n }\n\n return html;\n }\n\n /**\n * Check if content looks like structural HTML that was incorrectly\n * wrapped in a code block. We look for common HTML element patterns\n * that indicate this is meant to be rendered HTML, not code.\n */\n private looksLikeStructuralHtml(content: string): boolean {\n // Must start with < to be HTML\n if (!content.startsWith('<')) return false;\n\n // Must end with > (closing tag)\n if (!content.endsWith('>')) return false;\n\n // Check for common structural HTML tags that indicate layout HTML\n // These are tags that would typically appear in a UI mockup/prototype\n const structuralTagPattern = /<(div|span|table|tr|td|th|thead|tbody|p|ul|ol|li|section|article|header|footer|nav|main|aside|form|input|button|label|select|option|textarea|h[1-6]|img|a|strong|em|b|i|br|hr)\\b/i;\n\n if (!structuralTagPattern.test(content)) return false;\n\n // Additional check: should have multiple tags or nested structure\n // Single self-closing tags like <br> or <img> shouldn't trigger unwrapping\n const tagCount = (content.match(/<\\w+/g) || []).length;\n if (tagCount < 2) return false;\n\n // Check it's not just showing HTML as an example (common in docs)\n // If content has lots of &lt; or &gt; it's probably escaped HTML being shown\n if (content.includes('&lt;') || content.includes('&gt;')) return false;\n\n return true;\n }\n\n /**\n * Normalize indentation in HTML blocks to prevent marked from treating\n * indented HTML as code blocks (4 spaces = code block in markdown).\n *\n * This finds HTML blocks (starting with common block-level tags) and\n * removes ALL leading whitespace from lines within those blocks to ensure\n * marked doesn't interpret any nested content as code blocks.\n */\n private normalizeHtmlBlockIndentation(markdown: string): string {\n // Match HTML blocks that start with common block-level tags\n // These tags indicate structural HTML that should be rendered, not code\n const htmlBlockTags = [\n 'div', 'table', 'thead', 'tbody', 'tr', 'td', 'th',\n 'ul', 'ol', 'li', 'p', 'section', 'article', 'header',\n 'footer', 'nav', 'main', 'aside', 'form', 'svg', 'figure'\n ];\n\n const tagPattern = htmlBlockTags.join('|');\n // Match opening tag at start of line (possibly with leading whitespace)\n const htmlBlockStartRegex = new RegExp(`^[ \\\\t]*<(${tagPattern})\\\\b`, 'i');\n\n const lines = markdown.split('\\n');\n const result: string[] = [];\n let inHtmlBlock = false;\n let tagStack: string[] = [];\n\n for (const line of lines) {\n const trimmedLine = line.trimStart();\n\n if (!inHtmlBlock) {\n // Check if this line starts an HTML block\n const match = trimmedLine.match(htmlBlockStartRegex);\n if (match) {\n inHtmlBlock = true;\n const tag = match[1].toLowerCase();\n\n // Push to stack if it's not a self-closing tag on this line\n if (!this.isSelfClosingLine(trimmedLine, tag)) {\n tagStack.push(tag);\n }\n\n // Remove leading indentation\n result.push(trimmedLine);\n continue;\n }\n result.push(line);\n } else {\n // We're inside an HTML block - remove ALL leading whitespace\n // to prevent any nested content from being treated as code blocks\n\n // Track tag stack for proper nesting\n this.updateTagStack(trimmedLine, tagStack, htmlBlockTags);\n\n // Remove leading whitespace from this line\n result.push(trimmedLine);\n\n // Check if we've closed all HTML blocks\n if (tagStack.length === 0) {\n inHtmlBlock = false;\n }\n }\n }\n\n return result.join('\\n');\n }\n\n /**\n * Check if a line contains a self-closing tag or opens and closes the same tag\n */\n private isSelfClosingLine(line: string, tag: string): boolean {\n // Check for self-closing syntax: <tag ... />\n if (new RegExp(`<${tag}[^>]*/>`,'i').test(line)) {\n return true;\n }\n // Check if tag opens and closes on same line: <tag>...</tag>\n const openCount = (line.match(new RegExp(`<${tag}\\\\b`, 'gi')) || []).length;\n const closeCount = (line.match(new RegExp(`</${tag}>`, 'gi')) || []).length;\n return openCount > 0 && openCount === closeCount;\n }\n\n /**\n * Update the tag stack based on opening/closing tags in the line\n */\n private updateTagStack(line: string, tagStack: string[], validTags: string[]): void {\n // Find all opening tags\n const openTagRegex = /<(\\w+)\\b[^>]*(?<!\\/)>/gi;\n const closeTagRegex = /<\\/(\\w+)>/gi;\n\n let match;\n\n // Process closing tags first (they might close tags opened earlier)\n while ((match = closeTagRegex.exec(line)) !== null) {\n const tag = match[1].toLowerCase();\n const idx = tagStack.lastIndexOf(tag);\n if (idx !== -1) {\n tagStack.splice(idx, 1);\n }\n }\n\n // Process opening tags\n while ((match = openTagRegex.exec(line)) !== null) {\n const tag = match[1].toLowerCase();\n // Only track block-level tags we care about\n if (validTags.includes(tag)) {\n // Don't add if it's self-closing or closed on same line\n if (!this.isSelfClosingLine(line, tag)) {\n // Check if there's a closing tag for this specific opening\n const closeRegex = new RegExp(`</${tag}>`, 'gi');\n const opens = (line.match(new RegExp(`<${tag}\\\\b`, 'gi')) || []).length;\n const closes = (line.match(closeRegex) || []).length;\n if (opens > closes) {\n tagStack.push(tag);\n }\n }\n }\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-markdown",
3
- "version": "2.133.0",
3
+ "version": "3.0.0",
4
4
  "description": "MemberJunction: Lightweight Angular markdown component with Prism.js highlighting, Mermaid diagrams, and extensible features",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -22,13 +22,13 @@
22
22
  "author": "MemberJunction",
23
23
  "license": "ISC",
24
24
  "devDependencies": {
25
- "@angular/compiler": "18.0.2",
26
- "@angular/compiler-cli": "18.0.2"
25
+ "@angular/compiler": "18.2.14",
26
+ "@angular/compiler-cli": "18.2.14"
27
27
  },
28
28
  "peerDependencies": {
29
- "@angular/common": "18.0.2",
30
- "@angular/core": "18.0.2",
31
- "@angular/platform-browser": "18.0.2"
29
+ "@angular/common": "18.2.14",
30
+ "@angular/core": "18.2.14",
31
+ "@angular/platform-browser": "18.2.14"
32
32
  },
33
33
  "dependencies": {
34
34
  "marked": "^14.0.0",