@life-cockpit/angular-ui-kit 2.4.0 → 2.5.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.
@@ -11118,16 +11118,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
11118
11118
  * Renders GitHub-Flavored Markdown (GFM) to sanitized HTML with
11119
11119
  * optional syntax highlighting via `<lc-code-block>`.
11120
11120
  *
11121
+ * Optionally highlights *changed* blocks in place: pass the pre-edit markdown as
11122
+ * `previousContent` and set `highlightChanges` — added/edited blocks (diffed at
11123
+ * block / list-item level) gain a left accent bar + subtle tint, can auto-fade
11124
+ * (`changeHighlightFadeMs`) and scroll into view (`scrollToFirstChange`).
11125
+ *
11121
11126
  * @example
11122
11127
  * ```html
11123
11128
  * <lc-markdown [content]="'# Hello World'" />
11124
11129
  * <lc-markdown [src]="'/docs/readme.md'" />
11130
+ * <lc-markdown
11131
+ * [content]="current" [previousContent]="prev"
11132
+ * [highlightChanges]="true" [changeHighlightFadeMs]="3000" />
11125
11133
  * ```
11126
11134
  */
11127
11135
  class MarkdownComponent {
11128
11136
  sanitizer = inject(DomSanitizer);
11129
11137
  http = inject(HttpClient);
11138
+ host = inject((ElementRef));
11130
11139
  httpSub;
11140
+ fadeTimer;
11141
+ scrollTimer;
11131
11142
  mermaidApiPromise;
11132
11143
  mermaidInitialized = false;
11133
11144
  mermaidRenderRun = 0;
@@ -11147,10 +11158,24 @@ class MarkdownComponent {
11147
11158
  showHeadingAnchors = input(false, ...(ngDevMode ? [{ debugName: "showHeadingAnchors" }] : /* istanbul ignore next */ []));
11148
11159
  /** Base URL for resolving relative links/images */
11149
11160
  baseUrl = input(...(ngDevMode ? [undefined, { debugName: "baseUrl" }] : /* istanbul ignore next */ []));
11161
+ // -- Change highlighting --
11162
+ /** Enable change highlighting (requires `previousContent` to compute a diff). */
11163
+ highlightChanges = input(false, ...(ngDevMode ? [{ debugName: "highlightChanges" }] : /* istanbul ignore next */ []));
11164
+ /**
11165
+ * The prior Markdown. When it differs from `content`, the changed/added blocks
11166
+ * in `content` are highlighted. The caller passes the pre-edit markdown.
11167
+ */
11168
+ previousContent = input(...(ngDevMode ? [undefined, { debugName: "previousContent" }] : /* istanbul ignore next */ []));
11169
+ /** Auto-fade the highlight after N ms. 0 / undefined ⇒ persist until content changes. */
11170
+ changeHighlightFadeMs = input(...(ngDevMode ? [undefined, { debugName: "changeHighlightFadeMs" }] : /* istanbul ignore next */ []));
11171
+ /** Scroll the first changed block into view when highlights appear. */
11172
+ scrollToFirstChange = input(false, ...(ngDevMode ? [{ debugName: "scrollToFirstChange" }] : /* istanbul ignore next */ []));
11150
11173
  /** Emitted when a link is clicked */
11151
11174
  linkClick = output();
11152
11175
  /** Emitted after rendering with heading TOC */
11153
11176
  rendered = output();
11177
+ /** Emitted after a render that produced change highlights. */
11178
+ changesHighlighted = output();
11154
11179
  /** Internal resolved markdown source */
11155
11180
  resolvedMarkdown = signal('', ...(ngDevMode ? [{ debugName: "resolvedMarkdown" }] : /* istanbul ignore next */ []));
11156
11181
  /** Parsed result (computed once from resolvedMarkdown) */
@@ -11165,9 +11190,37 @@ class MarkdownComponent {
11165
11190
  }
11166
11191
  return this.parseMarkdown(md);
11167
11192
  }, ...(ngDevMode ? [{ debugName: "parsed" }] : /* istanbul ignore next */ []));
11193
+ /**
11194
+ * Rendered HTML after applying change highlights. When highlighting is off (or
11195
+ * there is no differing `previousContent`) this returns the parsed HTML
11196
+ * unchanged, so the non-highlight path is byte-for-byte identical to before.
11197
+ */
11198
+ highlightResult = computed(() => {
11199
+ const { html } = this.parsed();
11200
+ const prev = this.previousContent();
11201
+ if (!html ||
11202
+ !this.highlightChanges() ||
11203
+ prev == null ||
11204
+ prev === this.resolvedMarkdown()) {
11205
+ return { html, count: 0 };
11206
+ }
11207
+ return this.applyChangeHighlights(html, prev);
11208
+ }, ...(ngDevMode ? [{ debugName: "highlightResult" }] : /* istanbul ignore next */ []));
11209
+ /** Number of changed/added blocks highlighted in the current render. */
11210
+ changedCount = computed(() => this.highlightResult().count, ...(ngDevMode ? [{ debugName: "changedCount" }] : /* istanbul ignore next */ []));
11211
+ /** Visually-hidden polite summary announced when highlights appear. */
11212
+ changeSummary = computed(() => {
11213
+ const n = this.changedCount();
11214
+ if (n <= 0)
11215
+ return '';
11216
+ return `${n} ${n === 1 ? 'Abschnitt' : 'Abschnitte'} geändert`;
11217
+ }, ...(ngDevMode ? [{ debugName: "changeSummary" }] : /* istanbul ignore next */ []));
11218
+ /** Whether the current highlights have faded out (after `changeHighlightFadeMs`). */
11219
+ highlightsFaded = signal(false, ...(ngDevMode ? [{ debugName: "highlightsFaded" }] : /* istanbul ignore next */ []));
11168
11220
  /** Computed render parts (HTML chunks + code blocks interleaved) */
11169
11221
  renderParts = computed(() => {
11170
- const { html, blocks } = this.parsed();
11222
+ const html = this.highlightResult().html;
11223
+ const { blocks } = this.parsed();
11171
11224
  if (!html)
11172
11225
  return [];
11173
11226
  if (this.syntaxHighlight() && blocks.length > 0) {
@@ -11184,7 +11237,10 @@ class MarkdownComponent {
11184
11237
  }];
11185
11238
  }, ...(ngDevMode ? [{ debugName: "renderParts" }] : /* istanbul ignore next */ []));
11186
11239
  containerClasses = computed(() => {
11187
- return `lc-markdown lc-markdown--${this.variant()}`;
11240
+ let classes = `lc-markdown lc-markdown--${this.variant()}`;
11241
+ if (this.highlightsFaded())
11242
+ classes += ' lc-markdown--faded';
11243
+ return classes;
11188
11244
  }, ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
11189
11245
  mermaidSvgs = signal({}, ...(ngDevMode ? [{ debugName: "mermaidSvgs" }] : /* istanbul ignore next */ []));
11190
11246
  mermaidErrors = signal({}, ...(ngDevMode ? [{ debugName: "mermaidErrors" }] : /* istanbul ignore next */ []));
@@ -11215,9 +11271,17 @@ class MarkdownComponent {
11215
11271
  effect(() => {
11216
11272
  void this.renderMermaidParts(this.renderParts());
11217
11273
  });
11274
+ // React to a render that produced change highlights: emit, schedule fade,
11275
+ // and optionally scroll the first changed block into view.
11276
+ effect(() => {
11277
+ const count = this.highlightResult().count;
11278
+ untracked(() => this.onHighlightResult(count));
11279
+ });
11218
11280
  }
11219
11281
  ngOnDestroy() {
11220
11282
  this.httpSub?.unsubscribe();
11283
+ clearTimeout(this.fadeTimer);
11284
+ clearTimeout(this.scrollTimer);
11221
11285
  }
11222
11286
  onLinkClick(event) {
11223
11287
  const target = event.target;
@@ -11226,6 +11290,108 @@ class MarkdownComponent {
11226
11290
  this.linkClick.emit({ href: anchor.href, event });
11227
11291
  }
11228
11292
  }
11293
+ // -- Change highlighting -----------------------------------------------------
11294
+ /** Side-effects for a render: emit, (re)arm the fade timer, optional scroll. */
11295
+ onHighlightResult(count) {
11296
+ clearTimeout(this.fadeTimer);
11297
+ clearTimeout(this.scrollTimer);
11298
+ // A fresh render starts un-faded (re-entrant: never reuse stale fade state).
11299
+ this.highlightsFaded.set(false);
11300
+ if (count <= 0)
11301
+ return;
11302
+ this.changesHighlighted.emit({ changedBlocks: count });
11303
+ const fadeMs = this.changeHighlightFadeMs();
11304
+ if (fadeMs && fadeMs > 0) {
11305
+ this.fadeTimer = setTimeout(() => this.highlightsFaded.set(true), fadeMs);
11306
+ }
11307
+ if (this.scrollToFirstChange()) {
11308
+ // Defer until the highlighted HTML has been written to the DOM.
11309
+ this.scrollTimer = setTimeout(() => this.scrollToFirstChanged(), 0);
11310
+ }
11311
+ }
11312
+ scrollToFirstChanged() {
11313
+ if (typeof document === 'undefined')
11314
+ return;
11315
+ const el = this.host.nativeElement.querySelector('.lc-markdown__block--changed');
11316
+ el?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
11317
+ }
11318
+ /**
11319
+ * Wraps the changed/added top-level blocks of `html` with
11320
+ * `.lc-markdown__block--changed`. A block is "changed" when its normalized
11321
+ * text is not present among the blocks of `prevMarkdown`. Lists are diffed
11322
+ * per `<li>` and tables per `<tr>` so a single edited item highlights alone.
11323
+ */
11324
+ applyChangeHighlights(html, prevMarkdown) {
11325
+ if (typeof document === 'undefined')
11326
+ return { html, count: 0 };
11327
+ const prevKeys = this.collectBlockKeys(this.parseMarkdown(prevMarkdown).html);
11328
+ const root = this.htmlToElement(html);
11329
+ if (!root)
11330
+ return { html, count: 0 };
11331
+ let count = 0;
11332
+ const markIfChanged = (el) => {
11333
+ const key = this.blockTextKey(el.textContent ?? '');
11334
+ if (!key || prevKeys.has(key))
11335
+ return;
11336
+ el.classList.add('lc-markdown__block--changed');
11337
+ const sr = document.createElement('span');
11338
+ sr.className = 'lc-markdown__sr-only';
11339
+ sr.textContent = '(geändert) ';
11340
+ el.insertBefore(sr, el.firstChild);
11341
+ count++;
11342
+ };
11343
+ this.eachLogicalBlock(root, markIfChanged);
11344
+ return { html: root.innerHTML, count };
11345
+ }
11346
+ /** Normalized text set of the logical blocks within an HTML fragment. */
11347
+ collectBlockKeys(html) {
11348
+ const keys = new Set();
11349
+ const root = this.htmlToElement(html);
11350
+ if (!root)
11351
+ return keys;
11352
+ this.eachLogicalBlock(root, (el) => {
11353
+ const key = this.blockTextKey(el.textContent ?? '');
11354
+ if (key)
11355
+ keys.add(key);
11356
+ });
11357
+ return keys;
11358
+ }
11359
+ /**
11360
+ * Visits each diffable block under `root`: top-level elements, but descending
11361
+ * into `<ul>`/`<ol>` (per `<li>`) and `<table>` (per `<tr>`).
11362
+ */
11363
+ eachLogicalBlock(root, visit) {
11364
+ for (const node of Array.from(root.childNodes)) {
11365
+ if (node.nodeType !== 1)
11366
+ continue; // elements only (skips code placeholders)
11367
+ const el = node;
11368
+ const tag = el.tagName;
11369
+ if (tag === 'UL' || tag === 'OL') {
11370
+ for (const li of Array.from(el.children)) {
11371
+ if (li.tagName === 'LI')
11372
+ visit(li);
11373
+ }
11374
+ }
11375
+ else if (tag === 'TABLE') {
11376
+ for (const tr of Array.from(el.querySelectorAll('tr'))) {
11377
+ visit(tr);
11378
+ }
11379
+ }
11380
+ else {
11381
+ visit(el);
11382
+ }
11383
+ }
11384
+ }
11385
+ blockTextKey(text) {
11386
+ return text.replace(/\s+/g, ' ').trim().toLowerCase();
11387
+ }
11388
+ htmlToElement(html) {
11389
+ if (typeof document === 'undefined')
11390
+ return null;
11391
+ const div = document.createElement('div');
11392
+ div.innerHTML = html;
11393
+ return div;
11394
+ }
11229
11395
  loadFromUrl(url) {
11230
11396
  this.httpSub?.unsubscribe();
11231
11397
  this.httpSub = this.http.get(url, { responseType: 'text' }).subscribe({
@@ -11490,12 +11656,12 @@ class MarkdownComponent {
11490
11656
  return this.mermaidApiPromise;
11491
11657
  }
11492
11658
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MarkdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11493
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MarkdownComponent, isStandalone: true, selector: "lc-markdown", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, linkTarget: { classPropertyName: "linkTarget", publicName: "linkTarget", isSignal: true, isRequired: false, transformFunction: null }, sanitize: { classPropertyName: "sanitize", publicName: "sanitize", isSignal: true, isRequired: false, transformFunction: null }, syntaxHighlight: { classPropertyName: "syntaxHighlight", publicName: "syntaxHighlight", isSignal: true, isRequired: false, transformFunction: null }, showHeadingAnchors: { classPropertyName: "showHeadingAnchors", publicName: "showHeadingAnchors", isSignal: true, isRequired: false, transformFunction: null }, baseUrl: { classPropertyName: "baseUrl", publicName: "baseUrl", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { linkClick: "linkClick", rendered: "rendered" }, ngImport: i0, template: "<div [class]=\"containerClasses()\" (click)=\"onLinkClick($event)\">\n @for (part of renderParts(); track part.index) {\n @if (part.type === 'html') {\n <div [innerHTML]=\"part.safeHtml\"></div>\n } @else if (part.type === 'code') {\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"part.lang ?? 'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n } @else {\n @if (mermaidSvgFor(part.index); as svg) {\n <div class=\"lc-markdown__mermaid\" [innerHTML]=\"svg\"></div>\n } @else if (mermaidErrorFor(part.index); as errorMessage) {\n <div class=\"lc-markdown__mermaid-fallback\">\n <p class=\"lc-markdown__mermaid-error\">{{ errorMessage }}</p>\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n </div>\n } @else {\n <div class=\"lc-markdown__mermaid-loading\">Rendering Mermaid diagram...</div>\n }\n }\n }\n</div>\n", styles: [".lc-markdown{color:var(--color-text-primary);font-family:var(--font-family-sans);font-size:var(--font-size-base, 1rem);line-height:var(--line-height-relaxed, 1.75)}.lc-markdown h1,.lc-markdown h2,.lc-markdown h3,.lc-markdown h4,.lc-markdown h5,.lc-markdown h6{color:var(--color-text-primary);font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-tight, 1.25);margin:1.5em 0 .5em}.lc-markdown h1:first-child,.lc-markdown h2:first-child,.lc-markdown h3:first-child,.lc-markdown h4:first-child,.lc-markdown h5:first-child,.lc-markdown h6:first-child{margin-top:0}.lc-markdown h1{font-size:2rem}.lc-markdown h2{font-size:1.5rem}.lc-markdown h3{font-size:1.25rem}.lc-markdown h4{font-size:1.125rem}.lc-markdown h5{font-size:1rem}.lc-markdown h6{font-size:.875rem}.lc-markdown p{margin:0 0 1em}.lc-markdown a{color:var(--color-primary-600, #2563eb);text-decoration:none}.lc-markdown a:hover{text-decoration:underline}.lc-markdown strong{font-weight:var(--font-weight-semibold, 600)}.lc-markdown code{background-color:var(--color-surface-hover);color:var(--color-text-primary);padding:.125em .375em;border-radius:var(--border-radius-sm, .25rem);font-family:var(--font-family-mono, monospace);font-size:.875em}.lc-markdown pre{margin:1em 0;overflow-x:auto}.lc-markdown pre code{background:none;padding:0;border-radius:0}.lc-markdown blockquote{margin:1em 0;padding:.5em 1em;border-left:4px solid var(--color-primary-300, #93c5fd);background-color:var(--color-surface-2);color:var(--color-text-secondary, #4b5563)}.lc-markdown blockquote p{margin:0}.lc-markdown ul,.lc-markdown ol{margin:0 0 1em;padding-left:1.5em}.lc-markdown ul{list-style:disc}.lc-markdown ol{list-style:decimal}.lc-markdown li{margin:.25em 0}.lc-markdown hr{border:none;border-top:1px solid var(--color-divider, #e5e7eb);margin:1.5em 0}.lc-markdown img{max-width:100%;height:auto;border-radius:var(--border-radius-md, .375rem)}.lc-markdown del{text-decoration:line-through;color:var(--color-text-secondary, #6b7280)}.lc-markdown__table{width:100%;border-collapse:collapse;margin:1em 0;font-size:var(--font-size-sm, .875rem)}.lc-markdown__table th,.lc-markdown__table td{padding:.5rem .75rem;border:1px solid var(--color-divider, #e5e7eb);text-align:left}.lc-markdown__table th{background-color:var(--color-surface-2);font-weight:var(--font-weight-semibold, 600)}.lc-markdown__table tr:hover td{background-color:var(--color-surface-2)}.lc-markdown__task{list-style:none;margin-left:-1.5em}.lc-markdown__task input[type=checkbox]{margin-right:.5em;vertical-align:middle}.lc-markdown__anchor{color:var(--color-text-tertiary);text-decoration:none;margin-right:.25em;opacity:0;transition:opacity .15s ease}h1:hover .lc-markdown__anchor,h2:hover .lc-markdown__anchor,h3:hover .lc-markdown__anchor,h4:hover .lc-markdown__anchor,h5:hover .lc-markdown__anchor,h6:hover .lc-markdown__anchor{opacity:1}.lc-markdown lc-code-block{display:block;margin:1em 0}.lc-markdown lc-code-block code{background:none;color:inherit;padding:0;border-radius:0;font-size:inherit}.lc-markdown__mermaid{margin:1em 0;padding:.75rem;border:1px solid var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);background:var(--color-surface, #ffffff);overflow-x:auto}.lc-markdown__mermaid svg{display:block;margin:0 auto;max-width:100%;height:auto}.lc-markdown__mermaid-loading{margin:1em 0;padding:.75rem;border:1px dashed var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary, #6b7280);font-size:var(--font-size-sm, .875rem)}.lc-markdown__mermaid-fallback{margin:1em 0}.lc-markdown__mermaid-error{margin:0 0 .5rem;color:var(--color-error);font-size:var(--font-size-sm, .875rem)}.lc-markdown--compact{font-size:var(--font-size-sm, .875rem);line-height:var(--line-height-normal, 1.5)}.lc-markdown--compact h1{font-size:1.5rem}.lc-markdown--compact h2{font-size:1.25rem}.lc-markdown--compact h3{font-size:1.125rem}.lc-markdown--compact h4{font-size:1rem}.lc-markdown--compact h5,.lc-markdown--compact h6{font-size:.875rem}.lc-markdown--compact h1,.lc-markdown--compact h2,.lc-markdown--compact h3,.lc-markdown--compact h4,.lc-markdown--compact h5,.lc-markdown--compact h6{margin:1em 0 .25em}.lc-markdown--compact p{margin:0 0 .5em}.lc-markdown--compact blockquote{margin:.5em 0;padding:.25em .75em}.lc-markdown--compact ul,.lc-markdown--compact ol{margin:0 0 .5em}.lc-markdown--chat{font-size:inherit;line-height:1.4}.lc-markdown--chat p,.lc-markdown--chat ul,.lc-markdown--chat ol,.lc-markdown--chat pre,.lc-markdown--chat blockquote,.lc-markdown--chat table{margin:0 0 6px}.lc-markdown--chat h1,.lc-markdown--chat h2,.lc-markdown--chat h3,.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{margin:8px 0 4px;line-height:1.25}.lc-markdown--chat h1{font-size:1.25rem}.lc-markdown--chat h2{font-size:1.125rem}.lc-markdown--chat h3{font-size:1rem}.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{font-size:.9375rem}.lc-markdown--chat li{margin:0;line-height:1.4}.lc-markdown--chat ul,.lc-markdown--chat ol{padding-left:1.25em}.lc-markdown--chat blockquote{padding:.25em .75em}.lc-markdown--chat lc-code-block{margin:6px 0}.lc-markdown--chat .lc-markdown__mermaid,.lc-markdown--chat .lc-markdown__mermaid-loading,.lc-markdown--chat .lc-markdown__mermaid-fallback{margin:6px 0}.lc-markdown--chat>*:first-child{margin-top:0}.lc-markdown--chat>*:last-child{margin-bottom:0}\n"], dependencies: [{ kind: "component", type: CodeBlockComponent, selector: "lc-code-block", inputs: ["code", "language", "filename", "showLineNumbers", "showCopy", "showHeader"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11659
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MarkdownComponent, isStandalone: true, selector: "lc-markdown", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, linkTarget: { classPropertyName: "linkTarget", publicName: "linkTarget", isSignal: true, isRequired: false, transformFunction: null }, sanitize: { classPropertyName: "sanitize", publicName: "sanitize", isSignal: true, isRequired: false, transformFunction: null }, syntaxHighlight: { classPropertyName: "syntaxHighlight", publicName: "syntaxHighlight", isSignal: true, isRequired: false, transformFunction: null }, showHeadingAnchors: { classPropertyName: "showHeadingAnchors", publicName: "showHeadingAnchors", isSignal: true, isRequired: false, transformFunction: null }, baseUrl: { classPropertyName: "baseUrl", publicName: "baseUrl", isSignal: true, isRequired: false, transformFunction: null }, highlightChanges: { classPropertyName: "highlightChanges", publicName: "highlightChanges", isSignal: true, isRequired: false, transformFunction: null }, previousContent: { classPropertyName: "previousContent", publicName: "previousContent", isSignal: true, isRequired: false, transformFunction: null }, changeHighlightFadeMs: { classPropertyName: "changeHighlightFadeMs", publicName: "changeHighlightFadeMs", isSignal: true, isRequired: false, transformFunction: null }, scrollToFirstChange: { classPropertyName: "scrollToFirstChange", publicName: "scrollToFirstChange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { linkClick: "linkClick", rendered: "rendered", changesHighlighted: "changesHighlighted" }, ngImport: i0, template: "<div [class]=\"containerClasses()\" (click)=\"onLinkClick($event)\">\n @if (highlightChanges()) {\n <div class=\"lc-markdown__sr-only\" role=\"status\" aria-live=\"polite\">{{ changeSummary() }}</div>\n }\n @for (part of renderParts(); track part.index) {\n @if (part.type === 'html') {\n <div [innerHTML]=\"part.safeHtml\"></div>\n } @else if (part.type === 'code') {\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"part.lang ?? 'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n } @else {\n @if (mermaidSvgFor(part.index); as svg) {\n <div class=\"lc-markdown__mermaid\" [innerHTML]=\"svg\"></div>\n } @else if (mermaidErrorFor(part.index); as errorMessage) {\n <div class=\"lc-markdown__mermaid-fallback\">\n <p class=\"lc-markdown__mermaid-error\">{{ errorMessage }}</p>\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n </div>\n } @else {\n <div class=\"lc-markdown__mermaid-loading\">Rendering Mermaid diagram...</div>\n }\n }\n }\n</div>\n", styles: [".lc-markdown{color:var(--color-text-primary);font-family:var(--font-family-sans);font-size:var(--font-size-base, 1rem);line-height:var(--line-height-relaxed, 1.75)}.lc-markdown h1,.lc-markdown h2,.lc-markdown h3,.lc-markdown h4,.lc-markdown h5,.lc-markdown h6{color:var(--color-text-primary);font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-tight, 1.25);margin:1.5em 0 .5em}.lc-markdown h1:first-child,.lc-markdown h2:first-child,.lc-markdown h3:first-child,.lc-markdown h4:first-child,.lc-markdown h5:first-child,.lc-markdown h6:first-child{margin-top:0}.lc-markdown h1{font-size:2rem}.lc-markdown h2{font-size:1.5rem}.lc-markdown h3{font-size:1.25rem}.lc-markdown h4{font-size:1.125rem}.lc-markdown h5{font-size:1rem}.lc-markdown h6{font-size:.875rem}.lc-markdown p{margin:0 0 1em}.lc-markdown a{color:var(--color-primary-600, #2563eb);text-decoration:none}.lc-markdown a:hover{text-decoration:underline}.lc-markdown strong{font-weight:var(--font-weight-semibold, 600)}.lc-markdown code{background-color:var(--color-surface-hover);color:var(--color-text-primary);padding:.125em .375em;border-radius:var(--border-radius-sm, .25rem);font-family:var(--font-family-mono, monospace);font-size:.875em}.lc-markdown pre{margin:1em 0;overflow-x:auto}.lc-markdown pre code{background:none;padding:0;border-radius:0}.lc-markdown blockquote{margin:1em 0;padding:.5em 1em;border-left:4px solid var(--color-primary-300, #93c5fd);background-color:var(--color-surface-2);color:var(--color-text-secondary, #4b5563)}.lc-markdown blockquote p{margin:0}.lc-markdown ul,.lc-markdown ol{margin:0 0 1em;padding-left:1.5em}.lc-markdown ul{list-style:disc}.lc-markdown ol{list-style:decimal}.lc-markdown li{margin:.25em 0}.lc-markdown hr{border:none;border-top:1px solid var(--color-divider, #e5e7eb);margin:1.5em 0}.lc-markdown img{max-width:100%;height:auto;border-radius:var(--border-radius-md, .375rem)}.lc-markdown del{text-decoration:line-through;color:var(--color-text-secondary, #6b7280)}.lc-markdown__table{width:100%;border-collapse:collapse;margin:1em 0;font-size:var(--font-size-sm, .875rem)}.lc-markdown__table th,.lc-markdown__table td{padding:.5rem .75rem;border:1px solid var(--color-divider, #e5e7eb);text-align:left}.lc-markdown__table th{background-color:var(--color-surface-2);font-weight:var(--font-weight-semibold, 600)}.lc-markdown__table tr:hover td{background-color:var(--color-surface-2)}.lc-markdown__task{list-style:none;margin-left:-1.5em}.lc-markdown__task input[type=checkbox]{margin-right:.5em;vertical-align:middle}.lc-markdown__anchor{color:var(--color-text-tertiary);text-decoration:none;margin-right:.25em;opacity:0;transition:opacity .15s ease}h1:hover .lc-markdown__anchor,h2:hover .lc-markdown__anchor,h3:hover .lc-markdown__anchor,h4:hover .lc-markdown__anchor,h5:hover .lc-markdown__anchor,h6:hover .lc-markdown__anchor{opacity:1}.lc-markdown lc-code-block{display:block;margin:1em 0}.lc-markdown lc-code-block code{background:none;color:inherit;padding:0;border-radius:0;font-size:inherit}.lc-markdown__mermaid{margin:1em 0;padding:.75rem;border:1px solid var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);background:var(--color-surface, #ffffff);overflow-x:auto}.lc-markdown__mermaid svg{display:block;margin:0 auto;max-width:100%;height:auto}.lc-markdown__mermaid-loading{margin:1em 0;padding:.75rem;border:1px dashed var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary, #6b7280);font-size:var(--font-size-sm, .875rem)}.lc-markdown__mermaid-fallback{margin:1em 0}.lc-markdown__mermaid-error{margin:0 0 .5rem;color:var(--color-error);font-size:var(--font-size-sm, .875rem)}.lc-markdown--compact{font-size:var(--font-size-sm, .875rem);line-height:var(--line-height-normal, 1.5)}.lc-markdown--compact h1{font-size:1.5rem}.lc-markdown--compact h2{font-size:1.25rem}.lc-markdown--compact h3{font-size:1.125rem}.lc-markdown--compact h4{font-size:1rem}.lc-markdown--compact h5,.lc-markdown--compact h6{font-size:.875rem}.lc-markdown--compact h1,.lc-markdown--compact h2,.lc-markdown--compact h3,.lc-markdown--compact h4,.lc-markdown--compact h5,.lc-markdown--compact h6{margin:1em 0 .25em}.lc-markdown--compact p{margin:0 0 .5em}.lc-markdown--compact blockquote{margin:.5em 0;padding:.25em .75em}.lc-markdown--compact ul,.lc-markdown--compact ol{margin:0 0 .5em}.lc-markdown--chat{font-size:inherit;line-height:1.4}.lc-markdown--chat p,.lc-markdown--chat ul,.lc-markdown--chat ol,.lc-markdown--chat pre,.lc-markdown--chat blockquote,.lc-markdown--chat table{margin:0 0 6px}.lc-markdown--chat h1,.lc-markdown--chat h2,.lc-markdown--chat h3,.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{margin:8px 0 4px;line-height:1.25}.lc-markdown--chat h1{font-size:1.25rem}.lc-markdown--chat h2{font-size:1.125rem}.lc-markdown--chat h3{font-size:1rem}.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{font-size:.9375rem}.lc-markdown--chat li{margin:0;line-height:1.4}.lc-markdown--chat ul,.lc-markdown--chat ol{padding-left:1.25em}.lc-markdown--chat blockquote{padding:.25em .75em}.lc-markdown--chat lc-code-block{margin:6px 0}.lc-markdown--chat .lc-markdown__mermaid,.lc-markdown--chat .lc-markdown__mermaid-loading,.lc-markdown--chat .lc-markdown__mermaid-fallback{margin:6px 0}.lc-markdown--chat>*:first-child{margin-top:0}.lc-markdown--chat>*:last-child{margin-bottom:0}.lc-markdown__block--changed{position:relative;padding:.4rem .875rem;border-radius:0 6px 6px 0;background-color:color-mix(in srgb,var(--color-primary) 13%,var(--color-surface));transition:background-color .42s ease,padding .42s ease}.lc-markdown__block--changed:before{content:\"\";position:absolute;inset-block:0;left:0;width:3px;border-radius:0 3px 3px 0;background-color:var(--color-primary);transition:opacity .42s ease}.lc-markdown--faded .lc-markdown__block--changed{padding:0;background-color:transparent}.lc-markdown--faded .lc-markdown__block--changed:before{opacity:0}.lc-markdown__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: CodeBlockComponent, selector: "lc-code-block", inputs: ["code", "language", "filename", "showLineNumbers", "showCopy", "showHeader"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11494
11660
  }
11495
11661
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MarkdownComponent, decorators: [{
11496
11662
  type: Component,
11497
- args: [{ selector: 'lc-markdown', standalone: true, imports: [CodeBlockComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div [class]=\"containerClasses()\" (click)=\"onLinkClick($event)\">\n @for (part of renderParts(); track part.index) {\n @if (part.type === 'html') {\n <div [innerHTML]=\"part.safeHtml\"></div>\n } @else if (part.type === 'code') {\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"part.lang ?? 'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n } @else {\n @if (mermaidSvgFor(part.index); as svg) {\n <div class=\"lc-markdown__mermaid\" [innerHTML]=\"svg\"></div>\n } @else if (mermaidErrorFor(part.index); as errorMessage) {\n <div class=\"lc-markdown__mermaid-fallback\">\n <p class=\"lc-markdown__mermaid-error\">{{ errorMessage }}</p>\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n </div>\n } @else {\n <div class=\"lc-markdown__mermaid-loading\">Rendering Mermaid diagram...</div>\n }\n }\n }\n</div>\n", styles: [".lc-markdown{color:var(--color-text-primary);font-family:var(--font-family-sans);font-size:var(--font-size-base, 1rem);line-height:var(--line-height-relaxed, 1.75)}.lc-markdown h1,.lc-markdown h2,.lc-markdown h3,.lc-markdown h4,.lc-markdown h5,.lc-markdown h6{color:var(--color-text-primary);font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-tight, 1.25);margin:1.5em 0 .5em}.lc-markdown h1:first-child,.lc-markdown h2:first-child,.lc-markdown h3:first-child,.lc-markdown h4:first-child,.lc-markdown h5:first-child,.lc-markdown h6:first-child{margin-top:0}.lc-markdown h1{font-size:2rem}.lc-markdown h2{font-size:1.5rem}.lc-markdown h3{font-size:1.25rem}.lc-markdown h4{font-size:1.125rem}.lc-markdown h5{font-size:1rem}.lc-markdown h6{font-size:.875rem}.lc-markdown p{margin:0 0 1em}.lc-markdown a{color:var(--color-primary-600, #2563eb);text-decoration:none}.lc-markdown a:hover{text-decoration:underline}.lc-markdown strong{font-weight:var(--font-weight-semibold, 600)}.lc-markdown code{background-color:var(--color-surface-hover);color:var(--color-text-primary);padding:.125em .375em;border-radius:var(--border-radius-sm, .25rem);font-family:var(--font-family-mono, monospace);font-size:.875em}.lc-markdown pre{margin:1em 0;overflow-x:auto}.lc-markdown pre code{background:none;padding:0;border-radius:0}.lc-markdown blockquote{margin:1em 0;padding:.5em 1em;border-left:4px solid var(--color-primary-300, #93c5fd);background-color:var(--color-surface-2);color:var(--color-text-secondary, #4b5563)}.lc-markdown blockquote p{margin:0}.lc-markdown ul,.lc-markdown ol{margin:0 0 1em;padding-left:1.5em}.lc-markdown ul{list-style:disc}.lc-markdown ol{list-style:decimal}.lc-markdown li{margin:.25em 0}.lc-markdown hr{border:none;border-top:1px solid var(--color-divider, #e5e7eb);margin:1.5em 0}.lc-markdown img{max-width:100%;height:auto;border-radius:var(--border-radius-md, .375rem)}.lc-markdown del{text-decoration:line-through;color:var(--color-text-secondary, #6b7280)}.lc-markdown__table{width:100%;border-collapse:collapse;margin:1em 0;font-size:var(--font-size-sm, .875rem)}.lc-markdown__table th,.lc-markdown__table td{padding:.5rem .75rem;border:1px solid var(--color-divider, #e5e7eb);text-align:left}.lc-markdown__table th{background-color:var(--color-surface-2);font-weight:var(--font-weight-semibold, 600)}.lc-markdown__table tr:hover td{background-color:var(--color-surface-2)}.lc-markdown__task{list-style:none;margin-left:-1.5em}.lc-markdown__task input[type=checkbox]{margin-right:.5em;vertical-align:middle}.lc-markdown__anchor{color:var(--color-text-tertiary);text-decoration:none;margin-right:.25em;opacity:0;transition:opacity .15s ease}h1:hover .lc-markdown__anchor,h2:hover .lc-markdown__anchor,h3:hover .lc-markdown__anchor,h4:hover .lc-markdown__anchor,h5:hover .lc-markdown__anchor,h6:hover .lc-markdown__anchor{opacity:1}.lc-markdown lc-code-block{display:block;margin:1em 0}.lc-markdown lc-code-block code{background:none;color:inherit;padding:0;border-radius:0;font-size:inherit}.lc-markdown__mermaid{margin:1em 0;padding:.75rem;border:1px solid var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);background:var(--color-surface, #ffffff);overflow-x:auto}.lc-markdown__mermaid svg{display:block;margin:0 auto;max-width:100%;height:auto}.lc-markdown__mermaid-loading{margin:1em 0;padding:.75rem;border:1px dashed var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary, #6b7280);font-size:var(--font-size-sm, .875rem)}.lc-markdown__mermaid-fallback{margin:1em 0}.lc-markdown__mermaid-error{margin:0 0 .5rem;color:var(--color-error);font-size:var(--font-size-sm, .875rem)}.lc-markdown--compact{font-size:var(--font-size-sm, .875rem);line-height:var(--line-height-normal, 1.5)}.lc-markdown--compact h1{font-size:1.5rem}.lc-markdown--compact h2{font-size:1.25rem}.lc-markdown--compact h3{font-size:1.125rem}.lc-markdown--compact h4{font-size:1rem}.lc-markdown--compact h5,.lc-markdown--compact h6{font-size:.875rem}.lc-markdown--compact h1,.lc-markdown--compact h2,.lc-markdown--compact h3,.lc-markdown--compact h4,.lc-markdown--compact h5,.lc-markdown--compact h6{margin:1em 0 .25em}.lc-markdown--compact p{margin:0 0 .5em}.lc-markdown--compact blockquote{margin:.5em 0;padding:.25em .75em}.lc-markdown--compact ul,.lc-markdown--compact ol{margin:0 0 .5em}.lc-markdown--chat{font-size:inherit;line-height:1.4}.lc-markdown--chat p,.lc-markdown--chat ul,.lc-markdown--chat ol,.lc-markdown--chat pre,.lc-markdown--chat blockquote,.lc-markdown--chat table{margin:0 0 6px}.lc-markdown--chat h1,.lc-markdown--chat h2,.lc-markdown--chat h3,.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{margin:8px 0 4px;line-height:1.25}.lc-markdown--chat h1{font-size:1.25rem}.lc-markdown--chat h2{font-size:1.125rem}.lc-markdown--chat h3{font-size:1rem}.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{font-size:.9375rem}.lc-markdown--chat li{margin:0;line-height:1.4}.lc-markdown--chat ul,.lc-markdown--chat ol{padding-left:1.25em}.lc-markdown--chat blockquote{padding:.25em .75em}.lc-markdown--chat lc-code-block{margin:6px 0}.lc-markdown--chat .lc-markdown__mermaid,.lc-markdown--chat .lc-markdown__mermaid-loading,.lc-markdown--chat .lc-markdown__mermaid-fallback{margin:6px 0}.lc-markdown--chat>*:first-child{margin-top:0}.lc-markdown--chat>*:last-child{margin-bottom:0}\n"] }]
11498
- }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], linkTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkTarget", required: false }] }], sanitize: [{ type: i0.Input, args: [{ isSignal: true, alias: "sanitize", required: false }] }], syntaxHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "syntaxHighlight", required: false }] }], showHeadingAnchors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeadingAnchors", required: false }] }], baseUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseUrl", required: false }] }], linkClick: [{ type: i0.Output, args: ["linkClick"] }], rendered: [{ type: i0.Output, args: ["rendered"] }] } });
11663
+ args: [{ selector: 'lc-markdown', standalone: true, imports: [CodeBlockComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div [class]=\"containerClasses()\" (click)=\"onLinkClick($event)\">\n @if (highlightChanges()) {\n <div class=\"lc-markdown__sr-only\" role=\"status\" aria-live=\"polite\">{{ changeSummary() }}</div>\n }\n @for (part of renderParts(); track part.index) {\n @if (part.type === 'html') {\n <div [innerHTML]=\"part.safeHtml\"></div>\n } @else if (part.type === 'code') {\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"part.lang ?? 'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n } @else {\n @if (mermaidSvgFor(part.index); as svg) {\n <div class=\"lc-markdown__mermaid\" [innerHTML]=\"svg\"></div>\n } @else if (mermaidErrorFor(part.index); as errorMessage) {\n <div class=\"lc-markdown__mermaid-fallback\">\n <p class=\"lc-markdown__mermaid-error\">{{ errorMessage }}</p>\n <lc-code-block\n [code]=\"part.code!\"\n [language]=\"'text'\"\n [showLineNumbers]=\"true\"\n [showCopy]=\"true\"\n />\n </div>\n } @else {\n <div class=\"lc-markdown__mermaid-loading\">Rendering Mermaid diagram...</div>\n }\n }\n }\n</div>\n", styles: [".lc-markdown{color:var(--color-text-primary);font-family:var(--font-family-sans);font-size:var(--font-size-base, 1rem);line-height:var(--line-height-relaxed, 1.75)}.lc-markdown h1,.lc-markdown h2,.lc-markdown h3,.lc-markdown h4,.lc-markdown h5,.lc-markdown h6{color:var(--color-text-primary);font-weight:var(--font-weight-semibold, 600);line-height:var(--line-height-tight, 1.25);margin:1.5em 0 .5em}.lc-markdown h1:first-child,.lc-markdown h2:first-child,.lc-markdown h3:first-child,.lc-markdown h4:first-child,.lc-markdown h5:first-child,.lc-markdown h6:first-child{margin-top:0}.lc-markdown h1{font-size:2rem}.lc-markdown h2{font-size:1.5rem}.lc-markdown h3{font-size:1.25rem}.lc-markdown h4{font-size:1.125rem}.lc-markdown h5{font-size:1rem}.lc-markdown h6{font-size:.875rem}.lc-markdown p{margin:0 0 1em}.lc-markdown a{color:var(--color-primary-600, #2563eb);text-decoration:none}.lc-markdown a:hover{text-decoration:underline}.lc-markdown strong{font-weight:var(--font-weight-semibold, 600)}.lc-markdown code{background-color:var(--color-surface-hover);color:var(--color-text-primary);padding:.125em .375em;border-radius:var(--border-radius-sm, .25rem);font-family:var(--font-family-mono, monospace);font-size:.875em}.lc-markdown pre{margin:1em 0;overflow-x:auto}.lc-markdown pre code{background:none;padding:0;border-radius:0}.lc-markdown blockquote{margin:1em 0;padding:.5em 1em;border-left:4px solid var(--color-primary-300, #93c5fd);background-color:var(--color-surface-2);color:var(--color-text-secondary, #4b5563)}.lc-markdown blockquote p{margin:0}.lc-markdown ul,.lc-markdown ol{margin:0 0 1em;padding-left:1.5em}.lc-markdown ul{list-style:disc}.lc-markdown ol{list-style:decimal}.lc-markdown li{margin:.25em 0}.lc-markdown hr{border:none;border-top:1px solid var(--color-divider, #e5e7eb);margin:1.5em 0}.lc-markdown img{max-width:100%;height:auto;border-radius:var(--border-radius-md, .375rem)}.lc-markdown del{text-decoration:line-through;color:var(--color-text-secondary, #6b7280)}.lc-markdown__table{width:100%;border-collapse:collapse;margin:1em 0;font-size:var(--font-size-sm, .875rem)}.lc-markdown__table th,.lc-markdown__table td{padding:.5rem .75rem;border:1px solid var(--color-divider, #e5e7eb);text-align:left}.lc-markdown__table th{background-color:var(--color-surface-2);font-weight:var(--font-weight-semibold, 600)}.lc-markdown__table tr:hover td{background-color:var(--color-surface-2)}.lc-markdown__task{list-style:none;margin-left:-1.5em}.lc-markdown__task input[type=checkbox]{margin-right:.5em;vertical-align:middle}.lc-markdown__anchor{color:var(--color-text-tertiary);text-decoration:none;margin-right:.25em;opacity:0;transition:opacity .15s ease}h1:hover .lc-markdown__anchor,h2:hover .lc-markdown__anchor,h3:hover .lc-markdown__anchor,h4:hover .lc-markdown__anchor,h5:hover .lc-markdown__anchor,h6:hover .lc-markdown__anchor{opacity:1}.lc-markdown lc-code-block{display:block;margin:1em 0}.lc-markdown lc-code-block code{background:none;color:inherit;padding:0;border-radius:0;font-size:inherit}.lc-markdown__mermaid{margin:1em 0;padding:.75rem;border:1px solid var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);background:var(--color-surface, #ffffff);overflow-x:auto}.lc-markdown__mermaid svg{display:block;margin:0 auto;max-width:100%;height:auto}.lc-markdown__mermaid-loading{margin:1em 0;padding:.75rem;border:1px dashed var(--color-divider, #e5e7eb);border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary, #6b7280);font-size:var(--font-size-sm, .875rem)}.lc-markdown__mermaid-fallback{margin:1em 0}.lc-markdown__mermaid-error{margin:0 0 .5rem;color:var(--color-error);font-size:var(--font-size-sm, .875rem)}.lc-markdown--compact{font-size:var(--font-size-sm, .875rem);line-height:var(--line-height-normal, 1.5)}.lc-markdown--compact h1{font-size:1.5rem}.lc-markdown--compact h2{font-size:1.25rem}.lc-markdown--compact h3{font-size:1.125rem}.lc-markdown--compact h4{font-size:1rem}.lc-markdown--compact h5,.lc-markdown--compact h6{font-size:.875rem}.lc-markdown--compact h1,.lc-markdown--compact h2,.lc-markdown--compact h3,.lc-markdown--compact h4,.lc-markdown--compact h5,.lc-markdown--compact h6{margin:1em 0 .25em}.lc-markdown--compact p{margin:0 0 .5em}.lc-markdown--compact blockquote{margin:.5em 0;padding:.25em .75em}.lc-markdown--compact ul,.lc-markdown--compact ol{margin:0 0 .5em}.lc-markdown--chat{font-size:inherit;line-height:1.4}.lc-markdown--chat p,.lc-markdown--chat ul,.lc-markdown--chat ol,.lc-markdown--chat pre,.lc-markdown--chat blockquote,.lc-markdown--chat table{margin:0 0 6px}.lc-markdown--chat h1,.lc-markdown--chat h2,.lc-markdown--chat h3,.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{margin:8px 0 4px;line-height:1.25}.lc-markdown--chat h1{font-size:1.25rem}.lc-markdown--chat h2{font-size:1.125rem}.lc-markdown--chat h3{font-size:1rem}.lc-markdown--chat h4,.lc-markdown--chat h5,.lc-markdown--chat h6{font-size:.9375rem}.lc-markdown--chat li{margin:0;line-height:1.4}.lc-markdown--chat ul,.lc-markdown--chat ol{padding-left:1.25em}.lc-markdown--chat blockquote{padding:.25em .75em}.lc-markdown--chat lc-code-block{margin:6px 0}.lc-markdown--chat .lc-markdown__mermaid,.lc-markdown--chat .lc-markdown__mermaid-loading,.lc-markdown--chat .lc-markdown__mermaid-fallback{margin:6px 0}.lc-markdown--chat>*:first-child{margin-top:0}.lc-markdown--chat>*:last-child{margin-bottom:0}.lc-markdown__block--changed{position:relative;padding:.4rem .875rem;border-radius:0 6px 6px 0;background-color:color-mix(in srgb,var(--color-primary) 13%,var(--color-surface));transition:background-color .42s ease,padding .42s ease}.lc-markdown__block--changed:before{content:\"\";position:absolute;inset-block:0;left:0;width:3px;border-radius:0 3px 3px 0;background-color:var(--color-primary);transition:opacity .42s ease}.lc-markdown--faded .lc-markdown__block--changed{padding:0;background-color:transparent}.lc-markdown--faded .lc-markdown__block--changed:before{opacity:0}.lc-markdown__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
11664
+ }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], linkTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkTarget", required: false }] }], sanitize: [{ type: i0.Input, args: [{ isSignal: true, alias: "sanitize", required: false }] }], syntaxHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "syntaxHighlight", required: false }] }], showHeadingAnchors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeadingAnchors", required: false }] }], baseUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseUrl", required: false }] }], highlightChanges: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightChanges", required: false }] }], previousContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousContent", required: false }] }], changeHighlightFadeMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "changeHighlightFadeMs", required: false }] }], scrollToFirstChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToFirstChange", required: false }] }], linkClick: [{ type: i0.Output, args: ["linkClick"] }], rendered: [{ type: i0.Output, args: ["rendered"] }], changesHighlighted: [{ type: i0.Output, args: ["changesHighlighted"] }] } });
11499
11665
 
11500
11666
  /**
11501
11667
  * Chat component for conversational user interfaces.
@@ -11796,7 +11962,7 @@ class ChatComponent {
11796
11962
  }
11797
11963
  }
11798
11964
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11799
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: ChatComponent, isStandalone: true, selector: "lc-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, isStreaming: { classPropertyName: "isStreaming", publicName: "isStreaming", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, messageAnchor: { classPropertyName: "messageAnchor", publicName: "messageAnchor", isSignal: true, isRequired: false, transformFunction: null }, contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showAvatars: { classPropertyName: "showAvatars", publicName: "showAvatars", isSignal: true, isRequired: false, transformFunction: null }, showTimestamps: { classPropertyName: "showTimestamps", publicName: "showTimestamps", isSignal: true, isRequired: false, transformFunction: null }, renderMarkdown: { classPropertyName: "renderMarkdown", publicName: "renderMarkdown", isSignal: true, isRequired: false, transformFunction: null }, allowFileUpload: { classPropertyName: "allowFileUpload", publicName: "allowFileUpload", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageSend: "messageSend", fileAttach: "fileAttach" }, queries: [{ propertyName: "messageTemplate", first: true, predicate: ["messageTemplate"], descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"lc-chat\"\n [class.lc-chat--borderless]=\"!bordered()\"\n [class.lc-chat--width-narrow]=\"contentWidth() === 'narrow'\"\n [class.lc-chat--width-full]=\"contentWidth() === 'full'\"\n>\n @if (showHeader()) {\n <div class=\"lc-chat__header\">\n <span class=\"lc-chat__title\">{{ title() }}</span>\n @if (isStreaming()) {\n <span class=\"lc-chat__streaming-badge\">Streaming\u2026</span>\n }\n </div>\n }\n\n <div\n class=\"lc-chat__messages\"\n [class.lc-chat__messages--anchor-bottom]=\"messageAnchor() === 'bottom'\"\n #scrollContainer\n >\n <div class=\"lc-chat__thread\">\n @for (msg of formattedMessages(); track msg.id) {\n <div\n class=\"lc-chat__message\"\n [class.lc-chat__message--user]=\"msg.role === 'user'\"\n [class.lc-chat__message--agent]=\"msg.role === 'agent'\"\n [class.lc-chat__message--system]=\"msg.role === 'system'\"\n [class.lc-chat__message--streaming]=\"msg.streaming\"\n [attr.role]=\"msg.status === 'error' ? 'alert' : null\"\n [attr.aria-live]=\"statusAriaLive(msg.status)\"\n >\n @if (msg.role !== 'user' && (showAvatars() || isSemanticStatus(msg.status))) {\n <div class=\"lc-chat__marker\">\n @if (isSemanticStatus(msg.status)) {\n <span class=\"lc-chat__status-icon\">\n <lc-icon [name]=\"statusIcon(msg.status)\" size=\"xs\" [color]=\"statusColor(msg.status)\" [decorative]=\"true\" />\n </span>\n } @else if (msg.avatar) {\n <img [src]=\"msg.avatar\" [alt]=\"msg.name || msg.role\" class=\"lc-chat__avatar-img\" />\n } @else {\n <span\n class=\"lc-chat__dot\"\n [class.lc-chat__dot--agent]=\"msg.role === 'agent'\"\n [class.lc-chat__dot--system]=\"msg.role === 'system'\"\n ></span>\n }\n </div>\n }\n\n <div class=\"lc-chat__bubble\" [class.lc-chat__bubble--streaming]=\"msg.streaming\">\n @if (msg.role === 'user') {\n <div class=\"lc-chat__meta\">\n <span class=\"lc-chat__name\">{{ msg.name || 'Du' }}</span>\n @if (showTimestamps() && msg.timestamp) {\n <span class=\"lc-chat__time\">{{ formatTime(msg.timestamp) }}</span>\n }\n </div>\n } @else if (msg.name) {\n <div class=\"lc-chat__name\">{{ msg.name }}</div>\n }\n <div class=\"lc-chat__content\">\n @if (isSemanticStatus(msg.status)) {\n <span class=\"lc-chat__sr-only\">{{ statusLabel(msg.status) }} </span>\n }\n @if (messageTemplate) {\n <ng-container *ngTemplateOutlet=\"messageTemplate; context: { $implicit: msg }\" />\n } @else if (shouldRenderMarkdown(msg.role)) {\n <lc-markdown [content]=\"msg.content\" variant=\"chat\" />\n } @else {\n {{ msg.content }}\n }\n <span class=\"lc-chat__cursor\" [class.lc-chat__cursor--visible]=\"msg.streaming\"></span>\n </div>\n @if (msg.attachments?.length) {\n <div class=\"lc-chat__attachments\">\n @for (att of msg.attachments; track att.id) {\n @if (isImage(att) && att.url) {\n <a class=\"lc-chat__attachment lc-chat__attachment--image\" [href]=\"att.url\" target=\"_blank\" rel=\"noopener\">\n <img [src]=\"att.url\" [alt]=\"att.name\" />\n </a>\n } @else {\n <a\n class=\"lc-chat__attachment lc-chat__attachment--file\"\n [href]=\"att.url || null\"\n [attr.download]=\"att.url ? att.name : null\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n <svg class=\"lc-chat__attachment-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 2.5h6L16 6.5v10A1.5 1.5 0 0 1 14.5 18h-9A1.5 1.5 0 0 1 4 16.5v-12A1.5 1.5 0 0 1 5.5 3H6V2.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n <path d=\"M12 2.5V6.5H16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n </svg>\n <span class=\"lc-chat__attachment-name\">{{ att.name }}</span>\n @if (att.size) {\n <span class=\"lc-chat__attachment-size\">{{ formatBytes(att.size) }}</span>\n }\n </a>\n }\n }\n </div>\n }\n @if (showTimestamps() && msg.timestamp && msg.role !== 'user') {\n <div class=\"lc-chat__time\">{{ formatTime(msg.timestamp) }}</div>\n }\n </div>\n </div>\n }\n\n @if (isStreaming() && !(formattedMessages().length && formattedMessages()[formattedMessages().length - 1].streaming)) {\n <div class=\"lc-chat__message lc-chat__message--agent\">\n @if (showAvatars()) {\n <div class=\"lc-chat__marker\">\n <span class=\"lc-chat__dot lc-chat__dot--agent\"></span>\n </div>\n }\n <div class=\"lc-chat__bubble\">\n <div class=\"lc-chat__typing\">\n <span></span><span></span><span></span>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"lc-chat__input-area\">\n <div class=\"lc-chat__composer\">\n @if (allowFileUpload() && pendingAttachments().length) {\n <div class=\"lc-chat__pending-attachments\">\n @for (att of pendingAttachments(); track att.id) {\n <div class=\"lc-chat__pending-attachment\" [class.lc-chat__pending-attachment--image]=\"isImage(att)\">\n @if (isImage(att) && att.url) {\n <img class=\"lc-chat__pending-thumb\" [src]=\"att.url\" [alt]=\"att.name\" />\n } @else {\n <svg class=\"lc-chat__attachment-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 2.5h6L16 6.5v10A1.5 1.5 0 0 1 14.5 18h-9A1.5 1.5 0 0 1 4 16.5v-12A1.5 1.5 0 0 1 5.5 3H6V2.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n <path d=\"M12 2.5V6.5H16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n </svg>\n }\n <span class=\"lc-chat__pending-name\">{{ att.name }}</span>\n @if (att.size) {\n <span class=\"lc-chat__pending-size\">{{ formatBytes(att.size) }}</span>\n }\n <button\n type=\"button\"\n class=\"lc-chat__pending-remove\"\n (click)=\"removeAttachment(att.id)\"\n [attr.aria-label]=\"'Entfernen: ' + att.name\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M3 3l6 6M9 3l-6 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n }\n\n <textarea\n #composerInput\n class=\"lc-chat__input\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n [disabled]=\"disabled()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n rows=\"1\"\n ></textarea>\n\n <div class=\"lc-chat__composer-actions\">\n @if (allowFileUpload()) {\n <input\n #fileInput\n type=\"file\"\n class=\"lc-chat__file-input\"\n [accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n (change)=\"onFilesSelected($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-chat__attach-btn\"\n [disabled]=\"disabled()\"\n (click)=\"openFilePicker()\"\n aria-label=\"Datei anh\u00E4ngen\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M14.5 9.5l-5 5a3 3 0 0 1-4.243-4.243l6.364-6.364a2 2 0 0 1 2.829 2.829l-6.364 6.364a1 1 0 1 1-1.415-1.415L11.5 6.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n }\n <button\n class=\"lc-chat__send-btn\"\n [disabled]=\"(!inputValue().trim() && !pendingAttachments().length) || disabled()\"\n (click)=\"send()\"\n aria-label=\"Send\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M3 10l7-7m0 0l7 7m-7-7v14\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" transform=\"rotate(90 10 10)\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".lc-chat{--lc-chat-content-width: 46rem;display:flex;flex-direction:column;height:100%;min-height:20rem;border:1px solid var(--color-border);border-radius:var(--border-radius-lg);overflow:hidden;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--font-family-sans, sans-serif)}.lc-chat--borderless{border:none;border-radius:0}.lc-chat--width-full{--lc-chat-content-width: 100%}.lc-chat__header{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-4);border-bottom:1px solid var(--color-divider);background:var(--color-surface)}.lc-chat__title{font-size:var(--font-size-sm, .875rem);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-primary)}.lc-chat__streaming-badge{font-size:var(--font-size-xs, .6875rem);padding:.125rem .5rem;background:color-mix(in srgb,var(--color-primary-500) 15%,transparent);color:var(--color-primary-500);border-radius:var(--border-radius-full, 1rem);font-weight:var(--font-weight-medium, 500);animation:pulse-badge 1.5s infinite}@keyframes pulse-badge{0%,to{opacity:1}50%{opacity:.6}}.lc-chat__messages{flex:1;overflow-y:auto;display:flex;flex-direction:column;padding-block:var(--spacing-6, 1.5rem);padding-inline:var(--spacing-4, 1rem)}.lc-chat__thread{position:relative;width:100%;max-width:var(--lc-chat-content-width, 46rem);margin-inline:auto;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:var(--spacing-5, 1.25rem)}.lc-chat__messages--anchor-bottom .lc-chat__thread>.lc-chat__message:first-child{margin-top:auto}.lc-chat__message{position:relative;display:flex;align-items:stretch;gap:var(--spacing-3, .75rem);align-self:stretch;max-width:100%}.lc-chat__marker{position:relative;z-index:1;flex-shrink:0;width:.875rem;display:flex;flex-direction:column;align-items:center}.lc-chat__marker:before{content:\"\";position:absolute;left:50%;top:.55rem;bottom:calc(-1 * var(--spacing-5, 1.25rem));width:1.5px;transform:translate(-50%);background:var(--color-divider);z-index:-1}.lc-chat__message:last-child .lc-chat__marker:before{display:none}.lc-chat__dot{position:relative;z-index:1;width:.625rem;height:.625rem;margin-top:.25rem;border-radius:50%;background:var(--color-text-tertiary);box-shadow:0 0 0 3px var(--color-surface)}.lc-chat__dot--agent{background:var(--color-primary-500)}.lc-chat__dot--system{background:var(--color-text-tertiary);opacity:.6}.lc-chat__message--streaming .lc-chat__dot--agent{animation:dot-pulse 1.4s ease-out infinite}@keyframes dot-pulse{0%{box-shadow:0 0 0 3px var(--color-surface),0 0 0 3px color-mix(in srgb,var(--color-primary-500) 45%,transparent)}70%,to{box-shadow:0 0 0 3px var(--color-surface),0 0 0 9px color-mix(in srgb,var(--color-primary-500) 0%,transparent)}}.lc-chat__avatar-img{width:1.5rem;height:1.5rem;border-radius:50%;object-fit:cover;box-shadow:0 0 0 3px var(--color-surface)}.lc-chat__status-icon{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:1rem;height:1rem;margin-top:.0625rem;border-radius:50%;background:var(--color-surface);box-shadow:0 0 0 2px var(--color-surface)}.lc-chat__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.lc-chat__bubble{flex:1;min-width:0;font-size:var(--font-size-base, .9375rem);line-height:var(--line-height-relaxed, 1.6);word-break:break-word;color:var(--color-text-primary)}.lc-chat__message--user .lc-chat__bubble{position:relative;z-index:1;padding:var(--spacing-3, .75rem) var(--spacing-4, 1rem);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);background:var(--color-surface-2)}.lc-chat__message--agent .lc-chat__bubble{padding:0;background:transparent}.lc-chat__message--system .lc-chat__bubble{padding:0;background:transparent;color:var(--color-text-tertiary);font-size:var(--font-size-sm, .8125rem)}.lc-chat__meta{display:flex;align-items:baseline;justify-content:space-between;gap:var(--spacing-2, .5rem);margin-bottom:var(--spacing-1, .25rem)}.lc-chat__meta .lc-chat__name{margin-bottom:0}.lc-chat__meta .lc-chat__time{margin-top:0}.lc-chat__name{font-size:var(--font-size-xs, .75rem);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-secondary);margin-bottom:var(--spacing-1, .25rem)}.lc-chat__content{white-space:pre-wrap}.lc-chat__cursor{display:none}.lc-chat__cursor--visible{display:inline-block;width:2px;height:1em;background:currentColor;margin-left:1px;vertical-align:text-bottom;animation:blink-cursor .8s step-end infinite}@keyframes blink-cursor{0%,to{opacity:1}50%{opacity:0}}.lc-chat__time{font-size:var(--font-size-xs, .75rem);color:var(--color-text-tertiary);margin-top:var(--spacing-1, .25rem);flex-shrink:0}.lc-chat__typing{display:flex;gap:.25rem;padding:.25rem 0}.lc-chat__typing span{width:.375rem;height:.375rem;border-radius:50%;background:var(--color-text-tertiary);animation:typing-bounce 1.4s ease-in-out infinite}.lc-chat__typing span:nth-child(2){animation-delay:.2s}.lc-chat__typing span:nth-child(3){animation-delay:.4s}@keyframes typing-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-.375rem)}}.lc-chat__input-area{padding:var(--spacing-4, .75rem);border-top:1px solid var(--color-divider);background:var(--color-surface)}.lc-chat__composer{width:100%;max-width:var(--lc-chat-content-width, 46rem);margin-inline:auto;display:flex;flex-direction:column;gap:var(--spacing-2, .5rem);padding:var(--spacing-3, .75rem);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--border-radius-xl);transition:border-color .15s,box-shadow .15s}.lc-chat__composer:focus-within{border-color:var(--color-primary-500);box-shadow:var(--elevation-1)}.lc-chat__input{display:block;width:100%;box-sizing:border-box;resize:none;border:none;background:transparent;padding:var(--spacing-1, .25rem) var(--spacing-2, .5rem);font-size:var(--font-size-base, .875rem);font-family:inherit;line-height:var(--line-height-normal, 1.4);color:var(--color-text-primary);outline:none;height:auto;max-height:12rem;overflow-y:auto}.lc-chat__input:disabled{opacity:.5;cursor:not-allowed}.lc-chat__input::placeholder{color:var(--color-text-tertiary)}.lc-chat__composer-actions{display:flex;align-items:center;gap:var(--spacing-2, .5rem)}.lc-chat__send-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;margin-left:auto;border:none;border-radius:var(--border-radius-md);background:var(--color-primary-fill);color:var(--color-on-primary);cursor:pointer;flex-shrink:0;transition:background .15s,opacity .15s}.lc-chat__send-btn:hover:not(:disabled){background:var(--color-primary-fill-hover)}.lc-chat__send-btn:disabled{opacity:.4;cursor:not-allowed}.lc-chat__file-input{display:none}.lc-chat__attach-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:none;border-radius:var(--border-radius-md);background:transparent;color:var(--color-text-tertiary);cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.lc-chat__attach-btn:hover:not(:disabled){background:var(--color-surface-hover);color:var(--color-text-primary)}.lc-chat__attach-btn:disabled{opacity:.4;cursor:not-allowed}.lc-chat__pending-attachments{display:flex;flex-wrap:wrap;gap:.375rem}.lc-chat__pending-attachment{display:inline-flex;align-items:center;gap:.375rem;padding:.25rem .375rem .25rem .5rem;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-md, .5rem);font-size:var(--font-size-xs, .75rem);color:var(--color-text-primary);max-width:16rem}.lc-chat__pending-thumb{width:1.75rem;height:1.75rem;object-fit:cover;border-radius:.25rem;flex-shrink:0}.lc-chat__pending-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:9rem}.lc-chat__pending-size{color:var(--color-text-tertiary);font-variant-numeric:tabular-nums}.lc-chat__pending-remove{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:none;border-radius:50%;background:transparent;color:var(--color-text-tertiary);cursor:pointer;flex-shrink:0}.lc-chat__pending-remove:hover{background:var(--color-surface-hover);color:var(--color-text-primary)}.lc-chat__attachments{display:flex;flex-wrap:wrap;gap:.375rem;margin-top:.5rem}.lc-chat__attachment{display:inline-flex;align-items:center;gap:.375rem;text-decoration:none;color:inherit;font-size:var(--font-size-xs, .75rem)}.lc-chat__attachment--file{padding:.25rem .5rem;background:color-mix(in srgb,currentColor 8%,transparent);border-radius:var(--border-radius-md, .375rem);max-width:16rem}.lc-chat__attachment--file:hover{background:color-mix(in srgb,currentColor 16%,transparent)}.lc-chat__attachment--image img{max-width:12rem;max-height:8rem;border-radius:var(--border-radius-md, .375rem);object-fit:cover;display:block}.lc-chat__attachment-icon{flex-shrink:0}.lc-chat__attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lc-chat__attachment-size{opacity:.7;font-variant-numeric:tabular-nums}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MarkdownComponent, selector: "lc-markdown", inputs: ["src", "content", "variant", "linkTarget", "sanitize", "syntaxHighlight", "showHeadingAnchors", "baseUrl"], outputs: ["linkClick", "rendered"] }, { kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11965
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: ChatComponent, isStandalone: true, selector: "lc-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, isStreaming: { classPropertyName: "isStreaming", publicName: "isStreaming", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, messageAnchor: { classPropertyName: "messageAnchor", publicName: "messageAnchor", isSignal: true, isRequired: false, transformFunction: null }, contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showAvatars: { classPropertyName: "showAvatars", publicName: "showAvatars", isSignal: true, isRequired: false, transformFunction: null }, showTimestamps: { classPropertyName: "showTimestamps", publicName: "showTimestamps", isSignal: true, isRequired: false, transformFunction: null }, renderMarkdown: { classPropertyName: "renderMarkdown", publicName: "renderMarkdown", isSignal: true, isRequired: false, transformFunction: null }, allowFileUpload: { classPropertyName: "allowFileUpload", publicName: "allowFileUpload", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageSend: "messageSend", fileAttach: "fileAttach" }, queries: [{ propertyName: "messageTemplate", first: true, predicate: ["messageTemplate"], descendants: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "composerInput", first: true, predicate: ["composerInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"lc-chat\"\n [class.lc-chat--borderless]=\"!bordered()\"\n [class.lc-chat--width-narrow]=\"contentWidth() === 'narrow'\"\n [class.lc-chat--width-full]=\"contentWidth() === 'full'\"\n>\n @if (showHeader()) {\n <div class=\"lc-chat__header\">\n <span class=\"lc-chat__title\">{{ title() }}</span>\n @if (isStreaming()) {\n <span class=\"lc-chat__streaming-badge\">Streaming\u2026</span>\n }\n </div>\n }\n\n <div\n class=\"lc-chat__messages\"\n [class.lc-chat__messages--anchor-bottom]=\"messageAnchor() === 'bottom'\"\n #scrollContainer\n >\n <div class=\"lc-chat__thread\">\n @for (msg of formattedMessages(); track msg.id) {\n <div\n class=\"lc-chat__message\"\n [class.lc-chat__message--user]=\"msg.role === 'user'\"\n [class.lc-chat__message--agent]=\"msg.role === 'agent'\"\n [class.lc-chat__message--system]=\"msg.role === 'system'\"\n [class.lc-chat__message--streaming]=\"msg.streaming\"\n [attr.role]=\"msg.status === 'error' ? 'alert' : null\"\n [attr.aria-live]=\"statusAriaLive(msg.status)\"\n >\n @if (msg.role !== 'user' && (showAvatars() || isSemanticStatus(msg.status))) {\n <div class=\"lc-chat__marker\">\n @if (isSemanticStatus(msg.status)) {\n <span class=\"lc-chat__status-icon\">\n <lc-icon [name]=\"statusIcon(msg.status)\" size=\"xs\" [color]=\"statusColor(msg.status)\" [decorative]=\"true\" />\n </span>\n } @else if (msg.avatar) {\n <img [src]=\"msg.avatar\" [alt]=\"msg.name || msg.role\" class=\"lc-chat__avatar-img\" />\n } @else {\n <span\n class=\"lc-chat__dot\"\n [class.lc-chat__dot--agent]=\"msg.role === 'agent'\"\n [class.lc-chat__dot--system]=\"msg.role === 'system'\"\n ></span>\n }\n </div>\n }\n\n <div class=\"lc-chat__bubble\" [class.lc-chat__bubble--streaming]=\"msg.streaming\">\n @if (msg.role === 'user') {\n <div class=\"lc-chat__meta\">\n <span class=\"lc-chat__name\">{{ msg.name || 'Du' }}</span>\n @if (showTimestamps() && msg.timestamp) {\n <span class=\"lc-chat__time\">{{ formatTime(msg.timestamp) }}</span>\n }\n </div>\n } @else if (msg.name) {\n <div class=\"lc-chat__name\">{{ msg.name }}</div>\n }\n <div class=\"lc-chat__content\">\n @if (isSemanticStatus(msg.status)) {\n <span class=\"lc-chat__sr-only\">{{ statusLabel(msg.status) }} </span>\n }\n @if (messageTemplate) {\n <ng-container *ngTemplateOutlet=\"messageTemplate; context: { $implicit: msg }\" />\n } @else if (shouldRenderMarkdown(msg.role)) {\n <lc-markdown [content]=\"msg.content\" variant=\"chat\" />\n } @else {\n {{ msg.content }}\n }\n <span class=\"lc-chat__cursor\" [class.lc-chat__cursor--visible]=\"msg.streaming\"></span>\n </div>\n @if (msg.attachments?.length) {\n <div class=\"lc-chat__attachments\">\n @for (att of msg.attachments; track att.id) {\n @if (isImage(att) && att.url) {\n <a class=\"lc-chat__attachment lc-chat__attachment--image\" [href]=\"att.url\" target=\"_blank\" rel=\"noopener\">\n <img [src]=\"att.url\" [alt]=\"att.name\" />\n </a>\n } @else {\n <a\n class=\"lc-chat__attachment lc-chat__attachment--file\"\n [href]=\"att.url || null\"\n [attr.download]=\"att.url ? att.name : null\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n <svg class=\"lc-chat__attachment-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 2.5h6L16 6.5v10A1.5 1.5 0 0 1 14.5 18h-9A1.5 1.5 0 0 1 4 16.5v-12A1.5 1.5 0 0 1 5.5 3H6V2.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n <path d=\"M12 2.5V6.5H16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n </svg>\n <span class=\"lc-chat__attachment-name\">{{ att.name }}</span>\n @if (att.size) {\n <span class=\"lc-chat__attachment-size\">{{ formatBytes(att.size) }}</span>\n }\n </a>\n }\n }\n </div>\n }\n @if (showTimestamps() && msg.timestamp && msg.role !== 'user') {\n <div class=\"lc-chat__time\">{{ formatTime(msg.timestamp) }}</div>\n }\n </div>\n </div>\n }\n\n @if (isStreaming() && !(formattedMessages().length && formattedMessages()[formattedMessages().length - 1].streaming)) {\n <div class=\"lc-chat__message lc-chat__message--agent\">\n @if (showAvatars()) {\n <div class=\"lc-chat__marker\">\n <span class=\"lc-chat__dot lc-chat__dot--agent\"></span>\n </div>\n }\n <div class=\"lc-chat__bubble\">\n <div class=\"lc-chat__typing\">\n <span></span><span></span><span></span>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n\n <div class=\"lc-chat__input-area\">\n <div class=\"lc-chat__composer\">\n @if (allowFileUpload() && pendingAttachments().length) {\n <div class=\"lc-chat__pending-attachments\">\n @for (att of pendingAttachments(); track att.id) {\n <div class=\"lc-chat__pending-attachment\" [class.lc-chat__pending-attachment--image]=\"isImage(att)\">\n @if (isImage(att) && att.url) {\n <img class=\"lc-chat__pending-thumb\" [src]=\"att.url\" [alt]=\"att.name\" />\n } @else {\n <svg class=\"lc-chat__attachment-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M6 2.5h6L16 6.5v10A1.5 1.5 0 0 1 14.5 18h-9A1.5 1.5 0 0 1 4 16.5v-12A1.5 1.5 0 0 1 5.5 3H6V2.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n <path d=\"M12 2.5V6.5H16\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linejoin=\"round\"/>\n </svg>\n }\n <span class=\"lc-chat__pending-name\">{{ att.name }}</span>\n @if (att.size) {\n <span class=\"lc-chat__pending-size\">{{ formatBytes(att.size) }}</span>\n }\n <button\n type=\"button\"\n class=\"lc-chat__pending-remove\"\n (click)=\"removeAttachment(att.id)\"\n [attr.aria-label]=\"'Entfernen: ' + att.name\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M3 3l6 6M9 3l-6 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n }\n\n <textarea\n #composerInput\n class=\"lc-chat__input\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n [disabled]=\"disabled()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n rows=\"1\"\n ></textarea>\n\n <div class=\"lc-chat__composer-actions\">\n @if (allowFileUpload()) {\n <input\n #fileInput\n type=\"file\"\n class=\"lc-chat__file-input\"\n [accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n (change)=\"onFilesSelected($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-chat__attach-btn\"\n [disabled]=\"disabled()\"\n (click)=\"openFilePicker()\"\n aria-label=\"Datei anh\u00E4ngen\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M14.5 9.5l-5 5a3 3 0 0 1-4.243-4.243l6.364-6.364a2 2 0 0 1 2.829 2.829l-6.364 6.364a1 1 0 1 1-1.415-1.415L11.5 6.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n }\n <button\n class=\"lc-chat__send-btn\"\n [disabled]=\"(!inputValue().trim() && !pendingAttachments().length) || disabled()\"\n (click)=\"send()\"\n aria-label=\"Send\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M3 10l7-7m0 0l7 7m-7-7v14\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" transform=\"rotate(90 10 10)\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".lc-chat{--lc-chat-content-width: 46rem;display:flex;flex-direction:column;height:100%;min-height:20rem;border:1px solid var(--color-border);border-radius:var(--border-radius-lg);overflow:hidden;background-color:var(--color-surface);color:var(--color-text-primary);font-family:var(--font-family-sans, sans-serif)}.lc-chat--borderless{border:none;border-radius:0}.lc-chat--width-full{--lc-chat-content-width: 100%}.lc-chat__header{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-4);border-bottom:1px solid var(--color-divider);background:var(--color-surface)}.lc-chat__title{font-size:var(--font-size-sm, .875rem);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-primary)}.lc-chat__streaming-badge{font-size:var(--font-size-xs, .6875rem);padding:.125rem .5rem;background:color-mix(in srgb,var(--color-primary-500) 15%,transparent);color:var(--color-primary-500);border-radius:var(--border-radius-full, 1rem);font-weight:var(--font-weight-medium, 500);animation:pulse-badge 1.5s infinite}@keyframes pulse-badge{0%,to{opacity:1}50%{opacity:.6}}.lc-chat__messages{flex:1;overflow-y:auto;display:flex;flex-direction:column;padding-block:var(--spacing-6, 1.5rem);padding-inline:var(--spacing-4, 1rem)}.lc-chat__thread{position:relative;width:100%;max-width:var(--lc-chat-content-width, 46rem);margin-inline:auto;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:var(--spacing-5, 1.25rem)}.lc-chat__messages--anchor-bottom .lc-chat__thread>.lc-chat__message:first-child{margin-top:auto}.lc-chat__message{position:relative;display:flex;align-items:stretch;gap:var(--spacing-3, .75rem);align-self:stretch;max-width:100%}.lc-chat__marker{position:relative;z-index:1;flex-shrink:0;width:.875rem;display:flex;flex-direction:column;align-items:center}.lc-chat__marker:before{content:\"\";position:absolute;left:50%;top:.55rem;bottom:calc(-1 * var(--spacing-5, 1.25rem));width:1.5px;transform:translate(-50%);background:var(--color-divider);z-index:-1}.lc-chat__message:last-child .lc-chat__marker:before{display:none}.lc-chat__dot{position:relative;z-index:1;width:.625rem;height:.625rem;margin-top:.25rem;border-radius:50%;background:var(--color-text-tertiary);box-shadow:0 0 0 3px var(--color-surface)}.lc-chat__dot--agent{background:var(--color-primary-500)}.lc-chat__dot--system{background:var(--color-text-tertiary);opacity:.6}.lc-chat__message--streaming .lc-chat__dot--agent{animation:dot-pulse 1.4s ease-out infinite}@keyframes dot-pulse{0%{box-shadow:0 0 0 3px var(--color-surface),0 0 0 3px color-mix(in srgb,var(--color-primary-500) 45%,transparent)}70%,to{box-shadow:0 0 0 3px var(--color-surface),0 0 0 9px color-mix(in srgb,var(--color-primary-500) 0%,transparent)}}.lc-chat__avatar-img{width:1.5rem;height:1.5rem;border-radius:50%;object-fit:cover;box-shadow:0 0 0 3px var(--color-surface)}.lc-chat__status-icon{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:1rem;height:1rem;margin-top:.0625rem;border-radius:50%;background:var(--color-surface);box-shadow:0 0 0 2px var(--color-surface)}.lc-chat__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.lc-chat__bubble{flex:1;min-width:0;font-size:var(--font-size-base, .9375rem);line-height:var(--line-height-relaxed, 1.6);word-break:break-word;color:var(--color-text-primary)}.lc-chat__message--user .lc-chat__bubble{position:relative;z-index:1;padding:var(--spacing-3, .75rem) var(--spacing-4, 1rem);border:1px solid var(--color-border);border-radius:var(--border-radius-lg);background:var(--color-surface-2)}.lc-chat__message--agent .lc-chat__bubble{padding:0;background:transparent}.lc-chat__message--system .lc-chat__bubble{padding:0;background:transparent;color:var(--color-text-tertiary);font-size:var(--font-size-sm, .8125rem)}.lc-chat__meta{display:flex;align-items:baseline;justify-content:space-between;gap:var(--spacing-2, .5rem);margin-bottom:var(--spacing-1, .25rem)}.lc-chat__meta .lc-chat__name{margin-bottom:0}.lc-chat__meta .lc-chat__time{margin-top:0}.lc-chat__name{font-size:var(--font-size-xs, .75rem);font-weight:var(--font-weight-semibold, 600);color:var(--color-text-secondary);margin-bottom:var(--spacing-1, .25rem)}.lc-chat__content{white-space:pre-wrap}.lc-chat__cursor{display:none}.lc-chat__cursor--visible{display:inline-block;width:2px;height:1em;background:currentColor;margin-left:1px;vertical-align:text-bottom;animation:blink-cursor .8s step-end infinite}@keyframes blink-cursor{0%,to{opacity:1}50%{opacity:0}}.lc-chat__time{font-size:var(--font-size-xs, .75rem);color:var(--color-text-tertiary);margin-top:var(--spacing-1, .25rem);flex-shrink:0}.lc-chat__typing{display:flex;gap:.25rem;padding:.25rem 0}.lc-chat__typing span{width:.375rem;height:.375rem;border-radius:50%;background:var(--color-text-tertiary);animation:typing-bounce 1.4s ease-in-out infinite}.lc-chat__typing span:nth-child(2){animation-delay:.2s}.lc-chat__typing span:nth-child(3){animation-delay:.4s}@keyframes typing-bounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-.375rem)}}.lc-chat__input-area{padding:var(--spacing-4, .75rem);border-top:1px solid var(--color-divider);background:var(--color-surface)}.lc-chat__composer{width:100%;max-width:var(--lc-chat-content-width, 46rem);margin-inline:auto;display:flex;flex-direction:column;gap:var(--spacing-2, .5rem);padding:var(--spacing-3, .75rem);background:var(--color-surface-2);border:1px solid var(--color-border);border-radius:var(--border-radius-xl);transition:border-color .15s,box-shadow .15s}.lc-chat__composer:focus-within{border-color:var(--color-primary-500);box-shadow:var(--elevation-1)}.lc-chat__input{display:block;width:100%;box-sizing:border-box;resize:none;border:none;background:transparent;padding:var(--spacing-1, .25rem) var(--spacing-2, .5rem);font-size:var(--font-size-base, .875rem);font-family:inherit;line-height:var(--line-height-normal, 1.4);color:var(--color-text-primary);outline:none;height:auto;max-height:12rem;overflow-y:auto}.lc-chat__input:disabled{opacity:.5;cursor:not-allowed}.lc-chat__input::placeholder{color:var(--color-text-tertiary)}.lc-chat__composer-actions{display:flex;align-items:center;gap:var(--spacing-2, .5rem)}.lc-chat__send-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;margin-left:auto;border:none;border-radius:var(--border-radius-md);background:var(--color-primary-fill);color:var(--color-on-primary);cursor:pointer;flex-shrink:0;transition:background .15s,opacity .15s}.lc-chat__send-btn:hover:not(:disabled){background:var(--color-primary-fill-hover)}.lc-chat__send-btn:disabled{opacity:.4;cursor:not-allowed}.lc-chat__file-input{display:none}.lc-chat__attach-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:none;border-radius:var(--border-radius-md);background:transparent;color:var(--color-text-tertiary);cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}.lc-chat__attach-btn:hover:not(:disabled){background:var(--color-surface-hover);color:var(--color-text-primary)}.lc-chat__attach-btn:disabled{opacity:.4;cursor:not-allowed}.lc-chat__pending-attachments{display:flex;flex-wrap:wrap;gap:.375rem}.lc-chat__pending-attachment{display:inline-flex;align-items:center;gap:.375rem;padding:.25rem .375rem .25rem .5rem;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--border-radius-md, .5rem);font-size:var(--font-size-xs, .75rem);color:var(--color-text-primary);max-width:16rem}.lc-chat__pending-thumb{width:1.75rem;height:1.75rem;object-fit:cover;border-radius:.25rem;flex-shrink:0}.lc-chat__pending-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:9rem}.lc-chat__pending-size{color:var(--color-text-tertiary);font-variant-numeric:tabular-nums}.lc-chat__pending-remove{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:none;border-radius:50%;background:transparent;color:var(--color-text-tertiary);cursor:pointer;flex-shrink:0}.lc-chat__pending-remove:hover{background:var(--color-surface-hover);color:var(--color-text-primary)}.lc-chat__attachments{display:flex;flex-wrap:wrap;gap:.375rem;margin-top:.5rem}.lc-chat__attachment{display:inline-flex;align-items:center;gap:.375rem;text-decoration:none;color:inherit;font-size:var(--font-size-xs, .75rem)}.lc-chat__attachment--file{padding:.25rem .5rem;background:color-mix(in srgb,currentColor 8%,transparent);border-radius:var(--border-radius-md, .375rem);max-width:16rem}.lc-chat__attachment--file:hover{background:color-mix(in srgb,currentColor 16%,transparent)}.lc-chat__attachment--image img{max-width:12rem;max-height:8rem;border-radius:var(--border-radius-md, .375rem);object-fit:cover;display:block}.lc-chat__attachment-icon{flex-shrink:0}.lc-chat__attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lc-chat__attachment-size{opacity:.7;font-variant-numeric:tabular-nums}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MarkdownComponent, selector: "lc-markdown", inputs: ["src", "content", "variant", "linkTarget", "sanitize", "syntaxHighlight", "showHeadingAnchors", "baseUrl", "highlightChanges", "previousContent", "changeHighlightFadeMs", "scrollToFirstChange"], outputs: ["linkClick", "rendered", "changesHighlighted"] }, { kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11800
11966
  }
11801
11967
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: ChatComponent, decorators: [{
11802
11968
  type: Component,