UNPKG

@cisstech/nge

Version:

NG Essentials is a collection of libraries for Angular developers.

1,219 lines 52.9 kB
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Optional, Inject, inject, ElementRef, ChangeDetectorRef, EventEmitter, Component, ChangeDetectionStrategy, Input, HostBinding, Output, NgModule } from '@angular/core';
import * as i1 from '@angular/router';
import { RouterModule } from '@angular/router';
import * as i2 from '@angular/common';
import { HttpClient } from '@angular/common/http';
import * as i1$1 from '@cisstech/nge/services';
import { ResourceLoaderService } from '@cisstech/nge/services';
import { lastValueFrom, firstValueFrom } from 'rxjs';
import { marked } from 'marked';

/** Inject this token to get the list of contributions to nge-markdown api.  */
const NGE_MARKDOWN_CONTRIBUTION = new InjectionToken('NGE_MARKDOWN_CONTRIBUTION');

const OPEN = /^:::(\+?)\s+(\w+)(\s+.+)?/;
const CLOSE = /^:::\s*$/;
/**
 * Contribution to add collapsible styled block to markdown syntax.
 */
class NgeMarkdownAdmonitions {
    contribute(transformer) {
        this.addStyles();
        this.autoFixAdmonitionsSyntax(transformer);
        this.createAdmonitions(transformer);
    }
    addStyles() {
        const head = document.head;
        if (head.querySelector('[nge-markdown-admonitions]')) {
            return;
        }
        const admonitions = {
            note: {
                bg: 'rgba(68, 138, 255, 0.1)',
                border: '#448aff',
            },
            abstract: {
                bg: 'rgba(0, 176, 255, 0.1)',
                border: '#00b0ff',
            },
            info: {
                bg: 'rgba(0, 184, 212, 0.1)',
                border: '#00b8d4',
            },
            tip: {
                bg: 'rgba(0, 191, 165, 0.1)',
                border: '#00bfa5',
            },
            success: {
                bg: 'rgba(0, 200, 83, 0.1)',
                border: '#00c853',
            },
            question: {
                bg: 'rgba(100, 221, 23, 0.1)',
                border: '#64dd17',
            },
            warning: {
                bg: 'rgba(255, 145, 0, 0.1)',
                border: '#ff9100',
            },
            failure: {
                bg: 'rgba(255, 82, 82, 0.1)',
                border: '#ff5252',
            },
            danger: {
                bg: 'rgba(255, 23, 68, 0.1)',
                border: '#ff1744',
            },
            bug: {
                bg: 'rgba(245, 0, 87, 0.1)',
                border: '#f50057',
            },
            example: {
                bg: 'rgba(101, 31, 255, 0.1)',
                border: '#651fff',
            },
            quote: {
                bg: 'rgba(158, 158, 158, 0.1)',
                border: '#9e9e9e',
            },
        };
        const stylesheet = [
            `
            /* CONTAINER */
            .nge-md-admonition {
                margin: 1.5625em 0;
                overflow: hidden;
                font-size: 0.84rem;
                page-break-inside: avoid;
                border-radius: 0.1rem;
                box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.05rem rgba(0, 0, 0, 0.1);

                --admonition--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>');
                --admonition--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 5h16v2H4V5m0 4h16v2H4V9m0 4h16v2H4v-2m0 4h10v2H4v-2z"/></svg>');
                --admonition--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10A10 10 0 0012 2z"/></svg>');
                --admonition--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.55 11.2c-.23-.3-.5-.56-.76-.82-.65-.6-1.4-1.03-2.03-1.66C13.3 7.26 13 4.85 13.91 3c-.91.23-1.75.75-2.45 1.32-2.54 2.08-3.54 5.75-2.34 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.22.1-.46.04-.64-.12a.83.83 0 01-.15-.17c-1.1-1.43-1.28-3.48-.53-5.12C5.89 10 5 12.3 5.14 14.47c.04.5.1 1 .27 1.5.14.6.4 1.2.72 1.73 1.04 1.73 2.87 2.97 4.84 3.22 2.1.27 4.35-.12 5.96-1.6 1.8-1.66 2.45-4.32 1.5-6.6l-.13-.26c-.2-.46-.47-.87-.8-1.25l.05-.01m-3.1 6.3c-.28.24-.73.5-1.08.6-1.1.4-2.2-.16-2.87-.82 1.19-.28 1.89-1.16 2.09-2.05.17-.8-.14-1.46-.27-2.23-.12-.74-.1-1.37.18-2.06.17.38.37.76.6 1.06.76 1 1.95 1.44 2.2 2.8.04.14.06.28.06.43.03.82-.32 1.72-.92 2.27h.01z"/></svg>');
                --admonition--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>');
                --admonition--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.07 11.25l-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 00-2-2 2 2 0 00-2 2H8a4 4 0 014-4 4 4 0 014 4 3.2 3.2 0 01-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 002 12a10 10 0 0010 10 10 10 0 0010-10c0-5.53-4.5-10-10-10z"/></svg>');
                --admonition--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 14h-2v-4h2m0 8h-2v-2h2M1 21h22L12 2 1 21z"/></svg>');
                --admonition--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2c5.53 0 10 4.47 10 10s-4.47 10-10 10S2 17.53 2 12 6.47 2 12 2m3.59 5L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41 15.59 7z"/></svg>');
                --admonition--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.5 20l4.86-9.73H13V4l-5 9.73h3.5V20M12 2c2.75 0 5.1 1 7.05 2.95C21 6.9 22 9.25 22 12s-1 5.1-2.95 7.05C17.1 21 14.75 22 12 22s-5.1-1-7.05-2.95C3 17.1 2 14.75 2 12s1-5.1 2.95-7.05C6.9 3 9.25 2 12 2z"/></svg>');
                --admonition--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 00-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 00-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z"/></svg>');
                --admonition--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 01.75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z"/></svg>');
                --admonition--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z"/></svg>');
                --admonition--chevron-right: url('data:image/svg+xml;:charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/></svg>');
                --admonition--chevron-down: url('data:image/svg+xml;:charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/></svg>');
            }

            /* TITLE */
            .nge-md-admonition-title {
                min-height: 24px;
                box-sizing: border-box;
                position: relative;
                display: flex;
                align-items: center;
                margin-top: 0 !important;
                margin-bottom: 0 !important;
                padding: 0.4rem 0.6rem 0.4rem 2rem;
                font-weight: 700;
                /*REMOVE DETAILS MARKER IN FIREFOX*/
                list-style-type: none;
            }
            .nge-md-admonition-title:focus {
                outline: none;
            }

            /* DETAILS MARKER */
            .nge-md-admonition-title::marker,
            .nge-md-admonition-title::-webkit-details-marker {
                display: none;
            }

            /* TITLE COLLAPSIBLE */

            details .nge-md-admonition-title {
                cursor: pointer;
            }
            details .nge-md-admonition-title:after {
                position: absolute;
                right: 0.6rem;
                width: 1rem;
                height: 1rem;
                -o-mask-image: var(--admonition--chevron-right);
                -webkit-mask-image: var(--admonition--chevron-right);
                mask-image: var(--admonition--chevron-right);
                content: "";
            }
            details[open] .nge-md-admonition-title:after {
                -o-mask-image: var(--admonition--chevron-down);
                -webkit-mask-image: var(--admonition--chevron-down);
                mask-image: var(--admonition--chevron-down);
            }

            /* CONTENT */
            .nge-md-admonition-content {
                padding: 0 0.6rem;
            }
        `,
        ];
        Object.keys(admonitions).forEach((type) => {
            const map = admonitions[type];
            stylesheet.push(`
                .nge-md-admonition--${type} {
                    border-left: 0.2rem solid ${map.border};
                }
                .nge-md-admonition-title--${type} {
                    background-color: ${map.bg};
                }
                .nge-md-admonition-title--${type}:before,
                .nge-md-admonition-title--${type}:after {
                    background-color: ${map.border};
                }
                .nge-md-admonition-title--${type}:before {
                    position: absolute;
                    left: 0.6rem;
                    width: 1rem;
                    height: 1rem;
                    -o-mask-image: var(--admonition--${type});
                    -webkit-mask-image: var(--admonition--${type});
                    mask-image: var(--admonition--${type});
                    content: "";
                }
            `);
        });
        const style = document.createElement('style');
        style.setAttribute('nge-markdown-admonitions', '');
        style.innerHTML = stylesheet.join('\n');
        head.appendChild(style);
    }
    createAdmonitions(transformer) {
        transformer.addHtmlTransformer((element) => {
            const paragraphs = element.querySelectorAll('p');
            paragraphs.forEach((p) => {
                const text = p.innerHTML;
                const match = text.match(OPEN);
                if (match) {
                    const opener = match[1];
                    const type = match[2];
                    const title = (match[3] || '').trim();
                    const admonition = document.createElement('details');
                    if (opener.endsWith('+')) {
                        admonition.open = true;
                    }
                    admonition.className = 'nge-md-admonition nge-md-admonition--' + type;
                    const summary = document.createElement('summary');
                    summary.className = 'nge-md-admonition-title nge-md-admonition-title--' + type;
                    summary.innerHTML = title;
                    const content = [];
                    admonition.appendChild(summary);
                    let node = p.nextElementSibling;
                    let opened = 1;
                    while (node) {
                        const innerHTML = node.innerHTML.trim();
                        if (innerHTML.match(OPEN)) {
                            opened++;
                        }
                        else if (innerHTML.match(CLOSE)) {
                            opened--;
                            if (opened === 0) {
                                node.remove();
                                break;
                            }
                        }
                        content.push(node);
                        node = node.nextElementSibling;
                    }
                    const div = document.createElement('div');
                    div.className = 'nge-md-admonition-content';
                    content.forEach((e) => div.appendChild(e));
                    admonition.appendChild(div);
                    p.parentElement?.insertBefore(admonition, p);
                    p.remove();
                }
            });
        });
    }
    autoFixAdmonitionsSyntax(transformer) {
        transformer.addMarkdownTransformer((markdown) => {
            const lines = markdown.split('\n');
            const length = lines.length;
            let insideCodeBlock = false;
            for (let i = 0; i < length; i++) {
                const curr = lines[i];
                if (curr.startsWith('```')) {
                    insideCodeBlock = !insideCodeBlock;
                }
                if (insideCodeBlock) {
                    continue;
                }
                const prev = i > 0 ? lines[i - 1] : undefined;
                const next = i < length - 1 ? lines[i + 1] : undefined;
                if (curr.match(OPEN)) {
                    if (next?.trim()) {
                        lines[i] = curr + '\n';
                    }
                }
                else if (curr.match(CLOSE)) {
                    if (prev?.trim()) {
                        lines[i] = '\n' + curr;
                    }
                }
            }
            return lines.join('\n');
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownAdmonitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownAdmonitions }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownAdmonitions, decorators: [{
            type: Injectable
        }] });
/**
 * Injection token to register `NgeMarkdownAdmonitions` contribution.
 */
const NgeMarkdownAdmonitionsProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownAdmonitions,
};

/** Injection token to pass custom options to `NgeMarkdownEmoji` contribution. */
const NGE_MARKDOWN_EMOJI_OPTIONS = new InjectionToken('NGE_MARKDOWN_EMOJI_OPTIONS');
/**
 * Contribution to use emoji in markdown using [emoji-toolkit](https://github.com/joypixels/emoji-toolkit) library.
 */
class NgeMarkdownEmoji {
    constructor(options) {
        this.options = options;
        this.options = options || {};
        this.options.url = this.options.url || 'https://cdn.jsdelivr.net/npm/emoji-toolkit@8.0.0/lib/js/joypixels.min.js';
    }
    dependencies() {
        const deps = [];
        if (!('joypixels' in window)) {
            deps.push(['script', this.options.url]);
        }
        return deps;
    }
    contribute(transformer) {
        transformer.addMarkdownTransformer((markdown) => {
            const { joypixels } = window;
            const lines = markdown.split('\n');
            const length = lines.length;
            let insideCodeBlock = false;
            for (let i = 0; i < length; i++) {
                const curr = lines[i];
                if (curr.startsWith('```')) {
                    insideCodeBlock = !insideCodeBlock;
                }
                if (insideCodeBlock) {
                    continue;
                }
                if (lines[i].match(/:[a-z0-9_+-]+:/g)) {
                    lines[i] = joypixels.shortnameToUnicode(lines[i]);
                }
            }
            return lines.join('\n');
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownEmoji, deps: [{ token: NGE_MARKDOWN_EMOJI_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownEmoji }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownEmoji, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NGE_MARKDOWN_EMOJI_OPTIONS]
                }] }] });
/**
 * Provider to register `NgeMarkdownEmoji` contribution.
 */
const NgeMarkdownEmojiProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownEmoji,
};
/**
 * Provider to pass options to `NgeMarkdownEmoji` contribution.
 * @param options `NgeMarkdownEmoji` options.
 */
function NgeMarkdownEmojiOptionsProvider(options) {
    return {
        provide: NGE_MARKDOWN_EMOJI_OPTIONS,
        useValue: options,
    };
}

const DATA_LINES = 'data-nge-md-hl-lines';
const DATA_LANGUAGE = 'data-nge-md-hl-language';
const DATA_HIGHLIGHTS = 'data-nge-md-hl-highlights';
const DATA_FILENAME = 'data-nge-md-hl-filename';
/**
 * Injection token to register a highlighter service.
 */
const NGE_MARKDOWN_HIGHLIGHTER_SERVICE = new InjectionToken('NGE_MARKDOWN_HIGHLIGHTER_SERVICE');
/**
 * Contribution to add an abstract syntax highlighter.
 */
class NgeMarkdownHighlighter {
    constructor(injector, options) {
        this.injector = injector;
        this.options = options;
    }
    contribute(transformer) {
        this.createAttributes(transformer);
        this.colorizeCodes(transformer);
    }
    createAttributes(transformer) {
        transformer.addRendererTransformer((renderer) => {
            renderer.code = (code, args) => {
                args = args || '';
                const attributes = new Map();
                // LANGUAGE
                const language = args.split(' ').slice(0, 1).pop() || 'plaintext';
                attributes.set(DATA_LANGUAGE, language);
                // LINE NUMBERING
                let match = args.match(/lines="(.+?)"/);
                if (match) {
                    attributes.set(DATA_LINES, match[1]);
                }
                // LINE HIGHLIGHTING
                match = args.match(/highlights="(.+?)"/);
                if (match) {
                    attributes.set(DATA_HIGHLIGHTS, match[1]);
                }
                // FILENAME
                match = args.match(/filename="(.+?)"/);
                if (match) {
                    attributes.set(DATA_FILENAME, match[1]);
                }
                const attribs = Array.from(attributes.entries())
                    .map(([attributeName, attributeValue]) => {
                    return `${attributeName}="${attributeValue}"`;
                })
                    .join(' ');
                console.log(attribs);
                return `<pre ${attribs}><code>${this.escapeHtml(code)}</code></pre>`;
            };
            return renderer;
        });
    }
    colorizeCodes(transformer) {
        if (!this.options?.highligtht) {
            return;
        }
        const highlight = this.options.highligtht;
        transformer.addHtmlTransformer(async (element) => {
            const preElements = Array.from(element.querySelectorAll(`pre[${DATA_LANGUAGE}]`));
            for (const pre of preElements) {
                highlight(this.injector, {
                    lines: pre.getAttribute(DATA_LINES) || '',
                    element: pre.querySelector('code'),
                    language: pre.getAttribute(DATA_LANGUAGE) || 'plaintext',
                    highlights: pre.getAttribute(DATA_HIGHLIGHTS) || '',
                    filename: pre.getAttribute(DATA_FILENAME) || '',
                });
            }
        });
    }
    escapeHtml(input) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const map = {
            '<': '&lt;',
            '>': '&gt;',
        };
        return input.replace(/[<>]/g, (tag) => map[tag] || tag);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownHighlighter, deps: [{ token: i0.Injector }, { token: NGE_MARKDOWN_HIGHLIGHTER_SERVICE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownHighlighter }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownHighlighter, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i0.Injector }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NGE_MARKDOWN_HIGHLIGHTER_SERVICE]
                }] }] });
/**
 * Injection token to register `NgeMarkdownHighlighter` contribution.
 */
const NgeMarkdownHighlighterProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownHighlighter,
};
/**
 * Provider to register `NgeMonacoColorizerService` as the syntax highlighter.
 * @param type A reference to NgeMonacoColorizerService type.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function NgeMarkdownHighlighterMonacoProvider(type) {
    return {
        provide: NGE_MARKDOWN_HIGHLIGHTER_SERVICE,
        useValue: {
            highligtht: (injector, options) => {
                const colorizer = injector.get(type, null);
                const code = options.element;
                const pre = code.parentElement;
                pre.style.margin = '0.5em 0';
                pre.style.overflow = 'auto';
                pre.style.border = '1px solid #F2F2F2';
                colorizer?.colorizeElement({
                    element: code,
                    language: options.language,
                    code: code.textContent,
                    lines: options.lines,
                    filename: options.filename,
                    highlights: options.highlights,
                });
            },
        },
    };
}

/**
 * Contribution to use icons in markdown library using https://icongr.am/.
 */
class NgeMarkdownIcons {
    contribute(transformer) {
        transformer.addMarkdownTransformer((markdown) => {
            const pattern = /@(\w+)\s+([\w-]+)((\s+(?:color|size)=[^\s]+)*?)?@/gm;
            const lines = markdown.split('\n');
            const length = lines.length;
            let insideCodeBlock = false;
            for (let i = 0; i < length; i++) {
                const curr = lines[i];
                if (curr.startsWith('```')) {
                    insideCodeBlock = !insideCodeBlock;
                }
                if (insideCodeBlock) {
                    continue;
                }
                lines[i] = lines[i].replace(pattern, (_, type, name, params) => {
                    params = (params ?? '')
                        .trim()
                        .split(' ')
                        .filter((e) => e.trim())
                        .join('&');
                    params = params ? '?' + params : '';
                    return `<img src="https://icongr.am/${type.trim()}/${name.trim()}.svg${params}"/>`;
                });
            }
            return lines.join('\n');
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownIcons, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownIcons }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownIcons, decorators: [{
            type: Injectable
        }] });
/**
 * Injection token to register `NgeMarkdownIcons` contribution.
 */
const NgeMarkdownIconsProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownIcons,
};

/** Custom options to pass to NgeMarkdownKatex contribution. */
const NGE_MARKDOWN_KATEX_OPTIONS = new InjectionToken('NGE_MARKDOWN_KATEX_OPTIONS');
/**
 * Contribution to render math expressions in markdown using [Katex](https://katex.org) library.
 */
class NgeMarkdownKatex {
    constructor(options) {
        this.options = options;
        this.options = options || {
            extensions: {
                mhchem: true,
                copyTex: true,
            },
        };
        this.options.extensions = this.options.extensions || {};
        this.options.extensions.mhchem = this.options.extensions.mhchem ?? true;
        this.options.extensions.copyTex = this.options.extensions.copyTex ?? true;
    }
    dependencies() {
        if ('katex' in window) {
            return [];
        }
        let baseUrl = this.options?.baseUrl || 'https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/';
        if (!baseUrl.endsWith('/')) {
            baseUrl += '/';
        }
        const deps = [
            ['style', `${baseUrl}katex.min.css`],
            ['script', `${baseUrl}katex.js`],
            ['script', `${baseUrl}contrib/auto-render.js`],
        ];
        if (this.options.extensions?.copyTex) {
            deps.push(['script', `${baseUrl}contrib/copy-tex.min.js`]);
        }
        if (this.options.extensions?.mhchem) {
            deps.push(['script', `${baseUrl}contrib/mhchem.js`]);
        }
        return deps;
    }
    contribute(transformer) {
        // pattern to search multiline latex between $$...$$ or inline latex between $...$
        // const pattern = /(\$\$\n((.|\s|\n)+?)\n\$\$)|(\$([^\s][^$\n]+?[^\s])\$)/gm;
        transformer.addHtmlTransformer((element) => {
            const { renderMathInElement } = window;
            try {
                renderMathInElement(element, this.options.options || {
                    delimiters: [
                        { left: '$$', right: '$$', display: false },
                        { left: '$', right: '$', display: false },
                        { left: '\\(', right: '\\)', display: false },
                        { left: '\\[', right: '\\]', display: false },
                    ],
                });
            }
            catch (error) {
                console.error(error);
            }
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownKatex, deps: [{ token: NGE_MARKDOWN_KATEX_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownKatex }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownKatex, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NGE_MARKDOWN_KATEX_OPTIONS]
                }] }] });
/**
 * Provider to render math expressions in markdown using [Katex](https://katex.org) library.
 */
const NgeMarkdownKatexProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownKatex,
};
/**
 * Provider to pass options to `NgeMarkdownKatex` contribution.
 * @param options `NgeMarkdownKatex` options.
 */
function NgeMarkdownKatexOptionsProvider(options) {
    return {
        provide: NGE_MARKDOWN_KATEX_OPTIONS,
        useValue: options,
    };
}

/**
 * Contribution to handle fragment navigation in anchor elements.
 */
class NgeMarkdownLinkAnchor {
    constructor(router, location) {
        this.router = router;
        this.location = location;
    }
    contribute(transformer) {
        transformer.addRendererTransformer((renderer) => {
            renderer.link = (href, _, text) => {
                const attributes = new Map();
                if (href.startsWith('#')) {
                    href = this.location.path() + href;
                }
                attributes.set('href', href);
                // open in new tab if its a link external to the application
                const routes = (this.router.config || []).map((config) => {
                    if (!config.path?.startsWith('/')) {
                        return '/' + config.path;
                    }
                    return config.path;
                });
                if (!routes.find((route) => href.startsWith(route))) {
                    attributes.set('target', '_blank');
                }
                return `<a ${Array.from(attributes.entries())
                    .map((entry) => {
                    return entry[0] + '=' + entry[1];
                })
                    .join(' ')}>${text}</a>`;
            };
            return renderer;
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownLinkAnchor, deps: [{ token: i1.Router }, { token: i2.Location }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownLinkAnchor }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownLinkAnchor, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.Router }, { type: i2.Location }] });
/**
 * Injection token to register `NgeMarkdownLinkAnchor` contribution.
 */
const NgeMarkdownLinkAnchorProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownLinkAnchor,
};

let TABSET_COUNTER = 0;
/**
 * Contribution to render tabs inside markdown files.
 */
class NgeMarkdownTabbedSet {
    contribute(transformer) {
        this.addStyles();
        transformer.addHtmlTransformer((el) => {
            const open = /^===\s*(.+)/;
            const close = /^===\s*$/;
            const processed = [];
            const toRemoves = [];
            el.querySelectorAll('p').forEach((paragraph) => {
                if (processed.indexOf(paragraph) !== -1) {
                    return;
                }
                const match = paragraph.innerHTML.match(open);
                if (match) {
                    const tabs = [];
                    let tab = {
                        title: match[1],
                        content: [],
                    };
                    let node = paragraph.nextElementSibling;
                    while (node) {
                        let push = true;
                        const innerHTML = node.innerHTML.trim();
                        if (innerHTML.match(open)) {
                            tabs.push(tab);
                            tab = {
                                title: innerHTML.replace('===', '').trim(),
                                content: [],
                            };
                            push = false;
                            toRemoves.push(node);
                        }
                        else if (innerHTML.match(close)) {
                            tabs.push(tab);
                            toRemoves.push(node);
                            break;
                        }
                        if (push) {
                            tab.content.push(node);
                        }
                        processed.push(node);
                        node = node.nextElementSibling;
                    }
                    paragraph.parentElement?.replaceChild(this.createTabs(tabs), paragraph);
                    paragraph.remove();
                    toRemoves.forEach((e) => e.remove());
                }
            });
        });
    }
    createTabs(tabs) {
        const tabset = document.createElement('div');
        tabset.className = 'nge-md-tabbed-set';
        let i = 0;
        TABSET_COUNTER++;
        tabs.forEach((e) => {
            const checkbox = document.createElement('input');
            checkbox.type = 'radio';
            checkbox.id = 'nge-md-tabbed-' + TABSET_COUNTER + '-' + i;
            checkbox.name = 'nge-md-tabbed-' + TABSET_COUNTER;
            if (i === 0) {
                checkbox.setAttribute('checked', 'checked');
            }
            const label = document.createElement('label');
            label.setAttribute('for', checkbox.id);
            label.innerHTML = e.title;
            const content = document.createElement('div');
            content.className = 'nge-md-tabbed-content';
            e.content.forEach((c) => content.appendChild(c));
            tabset.append(checkbox, label, content);
            i++;
        });
        return tabset;
    }
    addStyles() {
        const head = document.head;
        if (head.querySelector('[nge-markdown-tabbed-set]')) {
            return;
        }
        const style = document.createElement('style');
        style.setAttribute('nge-markdown-tabbed-set', '');
        style.innerHTML = `
            /*  TAB SET */
            .nge-md-tabbed-set {
                display: flex;
                position: relative;
                flex-wrap: wrap;
                margin: 1em 0;
                border-radius: .1rem;
            }

            .nge-md-tabbed-set .highlight {
                background: #ddd;
            }

            .nge-md-tabbed-set .nge-md-tabbed-content {
                display: none;
                order: 99;
                width: 100%;
            }
            .nge-md-tabbed-set .nge-md-tabbed-content :first-child {
                margin: 0;
            }

            .nge-md-tabbed-set label {
                width: auto;
                /*padding: 0.25em;*/
                padding: .9375em 1.25em .78125em;
                font-weight: 700;
                font-size: .84rem;
                cursor: pointer;
            }

            .nge-md-tabbed-set input {
                position: absolute;
                opacity: 0;
            }

            .nge-md-tabbed-set input:nth-child(n+1) {
                color: #333333;
            }

            .nge-md-tabbed-set input:nth-child(n+1):checked + label {
                color: #ff5252;
                transition: all 0.3s;
                /* background-color: rgba(255, 82, 82, 0.1);*/
                border-bottom: .1rem solid;
            }

            .nge-md-tabbed-set input:nth-child(n+1):checked + label + .nge-md-tabbed-content {
                display: block;
                border-top: 1px solid #F5F5F5;
            }
        `;
        head.appendChild(style);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownTabbedSet, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownTabbedSet }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownTabbedSet, decorators: [{
            type: Injectable
        }] });
/**  * Injection token to register `NgeMarkdownTabbedSet` contribution. */
const NgeMarkdownTabbedSetProvider = {
    provide: NGE_MARKDOWN_CONTRIBUTION,
    multi: true,
    useClass: NgeMarkdownTabbedSet,
};

/**
 * Nge markdown transformer used by the contributions.
 */
class NgeMarkdownTransformer {
    constructor(
    /** Configuration option */
    config) {
        this.config = config;
        this.astTransformers = [];
        this.htmlTransformers = [];
        this.markdownTransformers = [];
        this.rendererTransformers = [];
        this.tokenizerTransformers = [];
    }
    /**
     * Registers a function to call to update the ast generated by the markdown compiler.
     * @param transform the function to call.
     */
    addAstTransformer(transform) {
        if (transform == null) {
            throw new ReferenceError('argument "transform" is required');
        }
        this.astTransformers.push(transform);
    }
    /**
     * Registers a function to call to transform the html generated by the markdown compiler.
     * @param transformer the function to call.
     */
    addHtmlTransformer(transformer) {
        if (transformer == null) {
            throw new ReferenceError('argument "transform" is required');
        }
        this.htmlTransformers.push(transformer);
    }
    /**
     * Registers a function to call to transform the markdown before it's parsed by the markdown compiler.
     * @param transform the function to call.
     */
    addMarkdownTransformer(transform) {
        if (transform == null) {
            throw new ReferenceError('argument "transform" is required');
        }
        this.markdownTransformers.push(transform);
    }
    /**
     * Registers a function to call to update marked library renderer.
     * @param transform the function to call.
     */
    addRendererTransformer(transform) {
        if (transform == null) {
            throw new ReferenceError('argument "transform" is required');
        }
        this.rendererTransformers.push(transform);
    }
    /**
     * Registers a function to call to update marked library tokenizer.
     * @param transform the function to call.
     */
    addTokenizerTransformer(transform) {
        if (transform == null) {
            throw new ReferenceError('argument "transform" is required');
        }
        this.tokenizerTransformers.push(transform);
    }
    /**
     * Apply the registered ast transformer functions to the given ast.
     * @param ast the ast to transform.
     * @returns the transformed ast.
     */
    transformAst(ast) {
        if (ast == null) {
            throw new ReferenceError('argument "ast" is required');
        }
        for (const fn of this.astTransformers) {
            ast = fn(ast);
        }
        return ast;
    }
    /**
     * Apply the registered html transformer functions to the given html.
     * @param element the html element to transform.
     * @returns the transformed html.
     */
    transformHTML(element) {
        if (element == null) {
            throw new ReferenceError('argument "html" is required');
        }
        for (const fn of this.htmlTransformers) {
            fn(element);
        }
        return element;
    }
    /**
     * Apply the registered markdown transformer functions to the given markdown.
     * @param markdown the markdown to transform.
     * @returns the transformed markdown.
     */
    transformMarkdown(markdown) {
        if (markdown == null) {
            throw new ReferenceError('argument "markdown" is required');
        }
        for (const fn of this.markdownTransformers) {
            markdown = fn(markdown);
        }
        return markdown;
    }
    /**
     * Apply the registered renderer transformer functions to the given renderer.
     * @param renderer the renderer to transform.
     * @returns the transformed renderer.
     */
    transformRenderer(renderer) {
        if (renderer == null) {
            throw new ReferenceError('argument "renderer" is required');
        }
        for (const fn of this.rendererTransformers) {
            renderer = fn(renderer);
        }
        return renderer;
    }
    /**
     * Apply the registered tokenizer transformer functions to the given tokenizer.
     * @param tokenizer the tokenizer to transform.
     * @returns the transformed tokenizer.
     */
    transformTokenizer(tokenizer) {
        if (tokenizer == null) {
            throw new ReferenceError('argument "tokenizer" is required');
        }
        for (const fn of this.tokenizerTransformers) {
            tokenizer = fn(tokenizer);
        }
        return tokenizer;
    }
    /**
     * Add new stylesheet element to the document.
     * @param url url to the stylesheet.
     * @returns A promise that resolves once the element is loaded.
     */
    addStyle(url) {
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = url;
        document.body.appendChild(link);
        return new Promise((resolve, reject) => {
            link.onload = resolve;
            link.onerror = reject;
        });
    }
    /**
     * Add new script element to the document.
     * @param url url to the script.
     * @returns A promise that resolves once the element is loaded.
     */
    addScript(url) {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        script.defer = true;
        document.body.appendChild(script);
        return new Promise((resolve, reject) => {
            script.onload = resolve;
            script.onerror = reject;
        });
    }
}

const NGE_MARKDOWN_CONFIG = new InjectionToken('NGE_MARKDOWN_CONFIG');
const NGE_MARKDOWN_THEMES = new InjectionToken('NGE_MARKDOWN_THEMES');
const NgeMarkdownConfigProvider = (config) => typeof config === 'function'
    ? {
        provide: NGE_MARKDOWN_CONFIG,
        useFactory: config,
    }
    : {
        provide: NGE_MARKDOWN_CONFIG,
        useValue: config,
    };
//  darkThemeClassName: 'dark-theme',
const NgeMarkdownThemeProvider = (...themes) => themes.map((theme) => ({
    provide: NGE_MARKDOWN_THEMES,
    useValue: theme,
    multi: true,
}));

const WINDOW = window;
/**
 * Markdown compiler service.
 */
class NgeMarkdownService {
    constructor(config, resourceLoader) {
        this.config = config;
        this.resourceLoader = resourceLoader;
        this.config = config || {};
    }
    /**
     * Compiles a markdown string to an html string.
     * @param options compilation options.
     * @returns A promise that resolve with the AST of the compiled markdown
     * (with the modifications of the contributions).
     */
    async compile(options) {
        let markdown = this.trimIndent(options.markdown);
        if (options.isHtmlString) {
            markdown = this.decodeHtml(markdown);
        }
        const transformer = await this.createTransformer(options);
        const renderer = this.renderer(transformer);
        const tokenizer = this.tokenizer(transformer);
        const markedOptions = {
            gfm: true,
            ...this.config,
            renderer,
            tokenizer,
        };
        markdown = transformer.transformMarkdown(markdown);
        const tokens = transformer.transformAst(marked.lexer(markdown, markedOptions));
        options.target.innerHTML = marked.parser(tokens, markedOptions);
        transformer.transformHTML(options.target);
        return tokens;
    }
    async createTransformer(options) {
        const contributions = [...(options.contributions || [])];
        const transformer = new NgeMarkdownTransformer(this.config);
        const dependencies = [];
        for (const contrib of contributions) {
            if (contrib.dependencies) {
                dependencies.push(...contrib.dependencies());
            }
            contrib.contribute(transformer);
        }
        // Try to fix the issues described here by loading monaco editor
        // after all the other scripts.
        // https://stackoverflow.com/a/33635881
        // https://github.com/microsoft/monaco-editor/issues/662
        // https://github.com/microsoft/monaco-editor/issues/1249
        const define = WINDOW.define;
        WINDOW.define = undefined;
        await lastValueFrom(this.resourceLoader.loadAllSync(dependencies));
        WINDOW.define = define;
        return transformer;
    }
    renderer(transformer) {
        const renderer = transformer.transformRenderer(this.config?.renderer || new marked.Renderer());
        return renderer;
    }
    tokenizer(transformer) {
        return transformer.transformTokenizer(this.config?.tokenizer || new marked.Tokenizer());
    }
    decodeHtml(html) {
        const textarea = document.createElement('textarea');
        textarea.innerHTML = html;
        return textarea.value;
    }
    trimIndent(markdown) {
        if (!markdown) {
            return '';
        }
        let indentStart;
        return markdown
            .split('\n')
            .map((line) => {
            let lineIdentStart = indentStart;
            if (line.length > 0) {
                lineIdentStart = isNaN(lineIdentStart) ? line.search(/\S|$/) : Math.min(line.search(/\S|$/), lineIdentStart);
            }
            if (isNaN(indentStart)) {
                indentStart = lineIdentStart;
            }
            return !!lineIdentStart ? line.substring(lineIdentStart) : line;
        })
            .join('\n');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownService, deps: [{ token: NGE_MARKDOWN_CONFIG, optional: true }, { token: i1$1.ResourceLoaderService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [NGE_MARKDOWN_CONFIG]
                }] }, { type: i1$1.ResourceLoaderService }] });

class NgeMarkdownComponent {
    get klass() {
        if (!this.theme)
            return '';
        const classeNames = [`nge-markdown-theme--${this.theme}`];
        if (this.isDark) {
            classeNames.push(`nge-markdown-theme--${this.theme}--dark`);
        }
        return classeNames.join(' ');
    }
    constructor() {
        this.el = inject(ElementRef);
        this.http = inject(HttpClient, { optional: true });
        this.markdownService = inject(NgeMarkdownService);
        this.resourceLoader = inject(ResourceLoaderService);
        this.changeDetectorRef = inject(ChangeDetectorRef);
        this.themes = inject(NGE_MARKDOWN_THEMES, { optional: true });
        this.contributions = inject(NGE_MARKDOWN_CONTRIBUTION, {
            optional: true,
        });
        this.isDark = false;
        /** Theme to apply to the markdown content. */
        this.theme = 'github';
        /**
         * An event that emit after each rendering pass
         * with the list of tokens parsed from the input markdown.
         */
        this.render = new EventEmitter();
        this.themes = this.themes || [];
    }
    ngOnInit() {
        this.el.nativeElement.style.opacity = '0';
    }
    async ngOnChanges() {
        await this.checkTheme();
        this.file ? await this.renderFromFile(this.file) : await this.renderFromString(this.data || '');
        this.el.nativeElement.style.opacity = '1';
    }
    async ngAfterViewInit() {
        await this.checkTheme();
        if (!this.file && !this.data) {
            await this.renderFromString(this.el.nativeElement.innerHTML, true);
        }
        this.el.nativeElement.style.opacity = '1';
    }
    async renderFromFile(file) {
        if (!this.http) {
            throw new Error('[nge-markdown] When using the `file` attribute you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information');
        }
        const markdown = await firstValueFrom(this.http.get(file, { responseType: 'text' }));
        await this.renderFromString(markdown);
    }
    async renderFromString(markdown, isHtmlString = false) {
        const tokens = await this.markdownService.compile({
            target: this.el.nativeElement,
            markdown,
            isHtmlString,
            contributions: this.contributions,
        });
        this.render.emit(tokens);
        this.changeDetectorRef.markForCheck();
    }
    async checkTheme() {
        if (this.theme) {
            const themeInfo = this.themes?.find((theme) => theme.name === this.theme);
            if (themeInfo) {
                await firstValueFrom(this.resourceLoader.loadAllSync([['style', themeInfo.styleUrl]])).catch();
            }
        }
        const { darkThemeClassName } = this.markdownService.config;
        if (darkThemeClassName) {
            // TODO: support angular universal
            this.isDark =
                document.querySelector(darkThemeClassName.startsWith('.') ? darkThemeClassName : `.${darkThemeClassName}`) !=
                    null;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.1", type: NgeMarkdownComponent, selector: "nge-markdown, [nge-markdown]", inputs: { file: "file", data: "data", theme: "theme" }, outputs: { render: "render" }, host: { properties: { "class": "this.klass" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [":host{transition:opacity .3s ease-in-out}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownComponent, decorators: [{
            type: Component,
            args: [{ selector: 'nge-markdown, [nge-markdown]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>\n", styles: [":host{transition:opacity .3s ease-in-out}\n"] }]
        }], ctorParameters: () => [], propDecorators: { file: [{
                type: Input
            }], data: [{
                type: Input
            }], theme: [{
                type: Input
            }], klass: [{
                type: HostBinding,
                args: ['class']
            }], render: [{
                type: Output
            }] } });

class NgeMarkdownModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownModule, declarations: [NgeMarkdownComponent], imports: [RouterModule], exports: [NgeMarkdownComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownModule, imports: [RouterModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NgeMarkdownModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [RouterModule],
                    declarations: [NgeMarkdownComponent],
                    exports: [NgeMarkdownComponent],
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { NGE_MARKDOWN_CONFIG, NGE_MARKDOWN_CONTRIBUTION, NGE_MARKDOWN_EMOJI_OPTIONS, NGE_MARKDOWN_HIGHLIGHTER_SERVICE, NGE_MARKDOWN_KATEX_OPTIONS, NGE_MARKDOWN_THEMES, NgeMarkdownAdmonitions, NgeMarkdownAdmonitionsProvider, NgeMarkdownComponent, NgeMarkdownConfigProvider, NgeMarkdownEmoji, NgeMarkdownEmojiOptionsProvider, NgeMarkdownEmojiProvider, NgeMarkdownHighlighter, NgeMarkdownHighlighterMonacoProvider, NgeMarkdownHighlighterProvider, NgeMarkdownIcons, NgeMarkdownIconsProvider, NgeMarkdownKatex, NgeMarkdownKatexOptionsProvider, NgeMarkdownKatexProvider, NgeMarkdownLinkAnchor, NgeMarkdownLinkAnchorProvider, NgeMarkdownModule, NgeMarkdownService, NgeMarkdownTabbedSet, NgeMarkdownTabbedSetProvider, NgeMarkdownThemeProvider, NgeMarkdownTransformer };
//# sourceMappingURL=cisstech-nge-markdown.mjs.map