@matechat/ng 0.0.1-alpha.0 → 0.0.1-alpha.1

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.
Files changed (39) hide show
  1. package/Bubble/bubble.component.d.ts +5 -3
  2. package/Input/input.component.d.ts +10 -1
  3. package/MarkdownCard/code-block.component.d.ts +46 -0
  4. package/MarkdownCard/index.d.ts +3 -0
  5. package/MarkdownCard/markdown-card.component.d.ts +198 -0
  6. package/MarkdownCard/markdown-card.module.d.ts +13 -0
  7. package/README.md +117 -13
  8. package/components-common/Base/foundation.d.ts +2 -0
  9. package/components-common/MarkdownCard/codeblock-foundation.d.ts +20 -0
  10. package/components-common/MarkdownCard/common/MDCardService.d.ts +14 -0
  11. package/components-common/MarkdownCard/common/MermaidService.d.ts +23 -0
  12. package/components-common/MarkdownCard/common/mdCard.types.d.ts +56 -0
  13. package/components-common/MarkdownCard/common/parser.d.ts +150 -0
  14. package/components-common/MarkdownCard/foundation.d.ts +38 -0
  15. package/esm2022/Base/base.component.mjs +2 -1
  16. package/esm2022/Bubble/bubble.component.mjs +15 -8
  17. package/esm2022/Input/input.component.mjs +107 -3
  18. package/esm2022/Locale/locale.service.mjs +5 -5
  19. package/esm2022/MarkdownCard/code-block.component.mjs +150 -0
  20. package/esm2022/MarkdownCard/index.mjs +4 -0
  21. package/esm2022/MarkdownCard/markdown-card.component.mjs +406 -0
  22. package/esm2022/MarkdownCard/markdown-card.module.mjs +44 -0
  23. package/esm2022/components-common/Base/foundation.mjs +4 -1
  24. package/esm2022/components-common/Input/foundation.mjs +1 -2
  25. package/esm2022/components-common/MarkdownCard/codeblock-foundation.mjs +132 -0
  26. package/esm2022/components-common/MarkdownCard/common/MDCardService.mjs +69 -0
  27. package/esm2022/components-common/MarkdownCard/common/MermaidService.mjs +222 -0
  28. package/esm2022/components-common/MarkdownCard/common/mdCard.types.mjs +6 -0
  29. package/esm2022/components-common/MarkdownCard/common/parser.mjs +194 -0
  30. package/esm2022/components-common/MarkdownCard/foundation.mjs +84 -0
  31. package/esm2022/public-api.mjs +2 -1
  32. package/fesm2022/matechat-ng.mjs +1460 -16
  33. package/fesm2022/matechat-ng.mjs.map +1 -1
  34. package/package.json +8 -5
  35. package/public-api.d.ts +1 -0
  36. package/fesm2022/matechat-ng-en-us-DsYnUbZd.mjs +0 -28
  37. package/fesm2022/matechat-ng-en-us-DsYnUbZd.mjs.map +0 -1
  38. package/fesm2022/matechat-ng-zh-cn--_YVZHnW.mjs +0 -28
  39. package/fesm2022/matechat-ng-zh-cn--_YVZHnW.mjs.map +0 -1
@@ -1,10 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Input, Injectable, Pipe, ContentChild, NgModule, EventEmitter, HostListener, ViewChild, Output } from '@angular/core';
2
+ import { Component, Input, Injectable, Pipe, ContentChildren, ContentChild, NgModule, EventEmitter, HostListener, ViewChild, Output, ViewContainerRef } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
- import { Subject } from 'rxjs';
5
+ import { Subject, debounceTime } from 'rxjs';
6
6
  import * as i3 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
8
+ import { DiffDOM } from 'diff-dom';
9
+ import markdownit from 'markdown-it';
10
+ import { getDefaultWhiteList, getDefaultCSSWhiteList, filterXSS } from 'xss';
11
+ import hljs from 'highlight.js';
8
12
 
9
13
  class BubbleLoadingComponent {
10
14
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: BubbleLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -49,6 +53,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
49
53
  type: Input
50
54
  }] } });
51
55
 
56
+ var zhCN = {
57
+ Input: {
58
+ send: "发送",
59
+ pauseAnswer: "停止回答",
60
+ pleaseEnter: "请输入您的问题...",
61
+ pleaseEnterPlaceholder: "请输入您的问题,并按{enterKey}发送,按{shiftEnterKey}换行",
62
+ ariaLabel: "输入框",
63
+ },
64
+ Md: {
65
+ toggle: "收起/展开",
66
+ copy: "复制",
67
+ diagram: '图形',
68
+ code: '代码',
69
+ zoomIn: '放大',
70
+ zoomOut: '缩小',
71
+ downLoad: '下载',
72
+ },
73
+ Bubble: {
74
+ ariaLabel: "聊天消息气泡",
75
+ emptyAvatar: "无头像占位",
76
+ userName: "用户名称: {name}",
77
+ content: "消息内容",
78
+ avatar: "用户头像: {name}"
79
+ },
80
+ };
81
+
82
+ var enUS = {
83
+ Input: {
84
+ send: "Send",
85
+ pauseAnswer: "Stop",
86
+ pleaseEnter: "Please enter your question...",
87
+ pleaseEnterPlaceholder: "Please enter your question and press {enterKey} to send, {shiftEnterKey} to wrap.",
88
+ ariaLabel: "Input box",
89
+ },
90
+ Md: {
91
+ toggle: "Collapse/Expand",
92
+ copy: "Copy",
93
+ diagram: 'Diagram',
94
+ code: 'Code',
95
+ zoomIn: 'Zoom In',
96
+ zoomOut: 'Zoom Out',
97
+ downLoad: 'Download',
98
+ },
99
+ Bubble: {
100
+ ariaLabel: "Chat message bubble",
101
+ emptyAvatar: "Empty avatar placeholder",
102
+ userName: "User name: {name}",
103
+ content: "Message content",
104
+ avatar: "User avatar: {name}"
105
+ },
106
+ };
107
+
52
108
  class LocaleService {
53
109
  constructor() {
54
110
  // 当前语言
@@ -73,10 +129,8 @@ class LocaleService {
73
129
  async loadDefaultLocales() {
74
130
  try {
75
131
  // 动态导入默认语言包
76
- const zhCN = await import('./matechat-ng-zh-cn--_YVZHnW.mjs');
77
- const enUS = await import('./matechat-ng-en-us-DsYnUbZd.mjs');
78
- this._localeData.set('zh-cn', zhCN.default);
79
- this._localeData.set('en-us', enUS.default);
132
+ this._localeData.set('zh-cn', zhCN);
133
+ this._localeData.set('en-us', enUS);
80
134
  }
81
135
  catch (error) {
82
136
  console.error('Failed to load default locales:', error);
@@ -394,6 +448,9 @@ class BaseFoundation {
394
448
  setCache(key, value) {
395
449
  return key && this._adapter.setCache(key, value);
396
450
  }
451
+ nextTick(cb) {
452
+ return this._adapter.nextTick(cb);
453
+ }
397
454
  _isInProps(key) {
398
455
  const props = this.getProps();
399
456
  return key in props;
@@ -460,6 +517,7 @@ class BaseComponent {
460
517
  getCache: (key) => key && this.cache[key],
461
518
  getCaches: () => this.cache,
462
519
  setCache: (key, value) => key && (this.cache[key] = value),
520
+ nextTick: (cb) => setTimeout(cb, 0),
463
521
  };
464
522
  }
465
523
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: BaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -475,6 +533,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
475
533
  }], ctorParameters: () => [] });
476
534
 
477
535
  class BubbleComponent extends BaseComponent {
536
+ // 计算是否有内容投影
537
+ get ngContentProjected() {
538
+ return this.contentChildren && this.contentChildren.length > 0;
539
+ }
478
540
  constructor() {
479
541
  super();
480
542
  // 组件属性
@@ -484,9 +546,9 @@ class BubbleComponent extends BaseComponent {
484
546
  this.avatarPosition = 'side';
485
547
  this.variant = 'filled';
486
548
  // 内容投影模板引用
549
+ this.avatarTemplate = null;
487
550
  this.topTemplate = null;
488
551
  this.loadingTplTemplate = null;
489
- this.defaultTemplate = null;
490
552
  this.bottomTemplate = null;
491
553
  }
492
554
  ngOnInit() {
@@ -516,11 +578,11 @@ class BubbleComponent extends BaseComponent {
516
578
  }
517
579
  ;
518
580
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: BubbleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
519
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: BubbleComponent, isStandalone: true, selector: "mc-bubble", inputs: { content: "content", loading: "loading", align: "align", avatarPosition: "avatarPosition", variant: "variant", avatarConfig: "avatarConfig" }, queries: [{ propertyName: "topTemplate", first: true, predicate: ["top"], descendants: true }, { propertyName: "loadingTplTemplate", first: true, predicate: ["loadingTpl"], descendants: true }, { propertyName: "defaultTemplate", first: true, predicate: ["defaultTemplate"], descendants: true }, { propertyName: "bottomTemplate", first: true, predicate: ["bottom"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"mc-bubble\" [ngClass]=\"bubbleClasses\" role=\"group\" [attr.aria-label]=\"'Bubble.ariaLabel' | translate\">\n <div\n *ngIf=\"avatarConfig\"\n class=\"mc-bubble-avatar\" role=\"img\"\n [ngClass]=\"{ 'empty-avatar': isEmptyAvatar }\"\n >\n <mc-avatar\n *ngIf=\"!isEmptyAvatar\"\n [imgSrc]=\"avatarConfig?.imgSrc || ''\"\n [name]=\"avatarConfig?.name || ''\"\n [width]=\"avatarConfig?.width || 36\"\n [height]=\"avatarConfig?.height || 36\"\n [gender]=\"avatarConfig?.gender || ''\"\n />\n <div *ngIf=\"isEmptyAvatar\" class=\"mc-bubble-avatar-wrapper\" [attr.aria-label]=\"'Bubble.emptyAvatar' | translate\"\n [style.width.px]=\"avatarConfig?.width || 36\"\n [style.height.px]=\"avatarConfig?.height || 36\"></div>\n <span *ngIf=\"avatarPosition === 'top'\" class=\"mc-bubble-avatar-name\" [attr.aria-label]=\"'Bubble.userName' | translate:{ name: avatarConfig?.displayName || '' } \">{{\n avatarConfig?.displayName\n }}</span>\n </div>\n <div\n class=\"mc-bubble-content-container\" aria-live=\"polite\"\n [ngClass]=\"{ 'with-avatar': avatarConfig }\"\n >\n <!-- \u9876\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"topTemplate\"></ng-container>\n <ng-content select=\"[top]\"></ng-content>\n </ng-container>\n \n <!-- \u52A0\u8F7D\u72B6\u6001 -->\n <div *ngIf=\"loading\" class=\"loading-container\" role=\"status\" aria-busy=\"true\">\n <ng-container *ngIf=\"loadingTplTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTplTemplate\"></ng-container>\n <ng-content select=\"[loadingTpl]\"></ng-content>\n </ng-container>\n <ng-template #defaultLoadingTemplate>\n <mc-bubble-loading></mc-bubble-loading>\n </ng-template>\n </div>\n \n <!-- \u4E3B\u8981\u5185\u5BB9 -->\n <div\n *ngIf=\"(defaultTemplate || content) && !loading\"\n class=\"mc-bubble-content\"\n [ngClass]=\"[variant]\"\n role=\"region\"\n >\n <ng-container *ngIf=\"defaultTemplate; else contentTemplate\">\n <ng-container *ngTemplateOutlet=\"defaultTemplate\"></ng-container>\n <ng-content></ng-content>\n </ng-container>\n <ng-template #contentTemplate>\n <span [attr.aria-label]=\"'Bubble.content' | translate\">{{ content }}</span>\n </ng-template>\n </div>\n \n <!-- \u5E95\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"bottomTemplate\"></ng-container>\n <ng-content select=\"[bottom]\"></ng-content>\n </ng-container>\n </div>\n</div>\n", styles: [".mc-bubble{display:flex;gap:4px;font-size:var(--devui-font-size, 14px)}.mc-bubble .mc-bubble-content{word-wrap:break-word}.mc-bubble .mc-bubble-content.filled,.mc-bubble .mc-bubble-content.bordered{padding:12px 16px;border-radius:12px}.mc-bubble .mc-bubble-content.filled{background-color:var(--devui-global-bg, #f6f6f8)}.mc-bubble .mc-bubble-content.bordered{border:1px solid var(--devui-dividing-line, #f2f2f3)}.mc-bubble .mc-bubble-avatar{flex-shrink:0;display:flex;gap:4px}.mc-bubble .mc-bubble-avatar .mc-bubble-avatar-name{font-size:14px}.mc-bubble .mc-bubble-avatar.empty-avatar{visibility:hidden}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar{align-items:center}.mc-bubble .mc-bubble-content-container{max-width:100%}.mc-bubble.mc-bubble-avatar-top{flex-direction:column}.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{align-items:flex-start;flex-direction:column}.mc-bubble.mc-bubble-loading.mc-bubble-avatar-side{align-items:center}.mc-bubble.mc-bubble-avatar-side.mc-bubble-right{flex-direction:row-reverse;justify-content:end}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{display:flex}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-content-container{align-items:flex-end}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar{flex-direction:row-reverse}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: BubbleLoadingComponent, selector: "mc-bubble-loading" }, { kind: "component", type: AvatarComponent, selector: "mc-avatar", inputs: ["imgSrc", "name", "width", "height", "isRound", "gender"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
581
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: BubbleComponent, isStandalone: true, selector: "mc-bubble", inputs: { content: "content", loading: "loading", align: "align", avatarPosition: "avatarPosition", variant: "variant", avatarConfig: "avatarConfig" }, queries: [{ propertyName: "avatarTemplate", first: true, predicate: ["avatar"], descendants: true }, { propertyName: "topTemplate", first: true, predicate: ["top"], descendants: true }, { propertyName: "loadingTplTemplate", first: true, predicate: ["loadingTpl"], descendants: true }, { propertyName: "bottomTemplate", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "contentChildren", predicate: ["ng-content"] }], usesInheritance: true, ngImport: i0, template: "<div class=\"mc-bubble\" [ngClass]=\"bubbleClasses\" role=\"group\" [attr.aria-label]=\"'Bubble.ariaLabel' | translate\">\n <!-- \u81EA\u5B9A\u4E49\u5934\u50CF\u533A\u57DF -->\n <div *ngIf=\"avatarTemplate\" class=\"mc-bubble-avatar\" role=\"img\">\n <ng-container *ngTemplateOutlet=\"avatarTemplate\"></ng-container>\n <ng-content select=\"[avatar]\"></ng-content>\n </div>\n \n <!-- \u9ED8\u8BA4\u5934\u50CF\u914D\u7F6E -->\n <div *ngIf=\"!avatarTemplate && avatarConfig\"\n class=\"mc-bubble-avatar\" role=\"img\"\n [ngClass]=\"{ 'empty-avatar': isEmptyAvatar }\"\n >\n <mc-avatar\n *ngIf=\"!isEmptyAvatar\"\n [imgSrc]=\"avatarConfig?.imgSrc || ''\"\n [name]=\"avatarConfig?.name || ''\"\n [width]=\"avatarConfig?.width || 36\"\n [height]=\"avatarConfig?.height || 36\"\n [gender]=\"avatarConfig?.gender || ''\"\n />\n <div *ngIf=\"isEmptyAvatar\" class=\"mc-bubble-avatar-wrapper\" [attr.aria-label]=\"'Bubble.emptyAvatar' | translate\"\n [style.width.px]=\"avatarConfig?.width || 36\"\n [style.height.px]=\"avatarConfig?.height || 36\"></div>\n <span *ngIf=\"avatarPosition === 'top'\" class=\"mc-bubble-avatar-name\" [attr.aria-label]=\"'Bubble.userName' | translate:{ name: avatarConfig?.displayName || '' } \">{{\n avatarConfig?.displayName\n }}</span>\n </div>\n <div\n class=\"mc-bubble-content-container\" aria-live=\"polite\"\n [ngClass]=\"{ 'with-avatar': avatarTemplate || avatarConfig }\"\n >\n <!-- \u9876\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"topTemplate\"></ng-container>\n <ng-content select=\"[top]\"></ng-content>\n </ng-container>\n \n <!-- \u52A0\u8F7D\u72B6\u6001 -->\n <div *ngIf=\"loading\" class=\"loading-container\" role=\"status\" aria-busy=\"true\">\n <ng-container *ngIf=\"loadingTplTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTplTemplate\"></ng-container>\n <ng-content select=\"[loadingTpl]\"></ng-content>\n </ng-container>\n <ng-template #defaultLoadingTemplate>\n <mc-bubble-loading></mc-bubble-loading>\n </ng-template>\n </div>\n \n <!-- \u4E3B\u8981\u5185\u5BB9 -->\n <div\n *ngIf=\"!loading\"\n class=\"mc-bubble-content\"\n [ngClass]=\"[variant]\"\n role=\"region\"\n >\n <ng-content></ng-content>\n <ng-container *ngIf=\"content && !ngContentProjected\">\n <span [attr.aria-label]=\"'Bubble.content' | translate\">{{ content }}</span>\n </ng-container>\n </div>\n \n <!-- \u5E95\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"bottomTemplate\"></ng-container>\n <ng-content select=\"[bottom]\"></ng-content>\n </ng-container>\n </div>\n</div>\n", styles: [".mc-bubble{display:flex;gap:4px;font-size:var(--devui-font-size, 14px)}.mc-bubble .mc-bubble-content{word-wrap:break-word}.mc-bubble .mc-bubble-content.filled,.mc-bubble .mc-bubble-content.bordered{padding:12px 16px;border-radius:12px}.mc-bubble .mc-bubble-content.filled{background-color:var(--devui-global-bg, #f6f6f8)}.mc-bubble .mc-bubble-content.bordered{border:1px solid var(--devui-dividing-line, #f2f2f3)}.mc-bubble .mc-bubble-avatar{flex-shrink:0;display:flex;gap:4px}.mc-bubble .mc-bubble-avatar .mc-bubble-avatar-name{font-size:14px}.mc-bubble .mc-bubble-avatar.empty-avatar{visibility:hidden}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar{align-items:center}.mc-bubble .mc-bubble-content-container{max-width:100%}.mc-bubble.mc-bubble-avatar-top{flex-direction:column}.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{align-items:flex-start;flex-direction:column}.mc-bubble.mc-bubble-loading.mc-bubble-avatar-side{align-items:center}.mc-bubble.mc-bubble-avatar-side.mc-bubble-right{flex-direction:row-reverse;justify-content:end}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{display:flex}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-content-container{align-items:flex-end}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar{flex-direction:row-reverse}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: BubbleLoadingComponent, selector: "mc-bubble-loading" }, { kind: "component", type: AvatarComponent, selector: "mc-avatar", inputs: ["imgSrc", "name", "width", "height", "isRound", "gender"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
520
582
  }
521
583
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: BubbleComponent, decorators: [{
522
584
  type: Component,
523
- args: [{ selector: 'mc-bubble', standalone: true, imports: [CommonModule, BubbleLoadingComponent, AvatarComponent, TranslatePipe], template: "<div class=\"mc-bubble\" [ngClass]=\"bubbleClasses\" role=\"group\" [attr.aria-label]=\"'Bubble.ariaLabel' | translate\">\n <div\n *ngIf=\"avatarConfig\"\n class=\"mc-bubble-avatar\" role=\"img\"\n [ngClass]=\"{ 'empty-avatar': isEmptyAvatar }\"\n >\n <mc-avatar\n *ngIf=\"!isEmptyAvatar\"\n [imgSrc]=\"avatarConfig?.imgSrc || ''\"\n [name]=\"avatarConfig?.name || ''\"\n [width]=\"avatarConfig?.width || 36\"\n [height]=\"avatarConfig?.height || 36\"\n [gender]=\"avatarConfig?.gender || ''\"\n />\n <div *ngIf=\"isEmptyAvatar\" class=\"mc-bubble-avatar-wrapper\" [attr.aria-label]=\"'Bubble.emptyAvatar' | translate\"\n [style.width.px]=\"avatarConfig?.width || 36\"\n [style.height.px]=\"avatarConfig?.height || 36\"></div>\n <span *ngIf=\"avatarPosition === 'top'\" class=\"mc-bubble-avatar-name\" [attr.aria-label]=\"'Bubble.userName' | translate:{ name: avatarConfig?.displayName || '' } \">{{\n avatarConfig?.displayName\n }}</span>\n </div>\n <div\n class=\"mc-bubble-content-container\" aria-live=\"polite\"\n [ngClass]=\"{ 'with-avatar': avatarConfig }\"\n >\n <!-- \u9876\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"topTemplate\"></ng-container>\n <ng-content select=\"[top]\"></ng-content>\n </ng-container>\n \n <!-- \u52A0\u8F7D\u72B6\u6001 -->\n <div *ngIf=\"loading\" class=\"loading-container\" role=\"status\" aria-busy=\"true\">\n <ng-container *ngIf=\"loadingTplTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTplTemplate\"></ng-container>\n <ng-content select=\"[loadingTpl]\"></ng-content>\n </ng-container>\n <ng-template #defaultLoadingTemplate>\n <mc-bubble-loading></mc-bubble-loading>\n </ng-template>\n </div>\n \n <!-- \u4E3B\u8981\u5185\u5BB9 -->\n <div\n *ngIf=\"(defaultTemplate || content) && !loading\"\n class=\"mc-bubble-content\"\n [ngClass]=\"[variant]\"\n role=\"region\"\n >\n <ng-container *ngIf=\"defaultTemplate; else contentTemplate\">\n <ng-container *ngTemplateOutlet=\"defaultTemplate\"></ng-container>\n <ng-content></ng-content>\n </ng-container>\n <ng-template #contentTemplate>\n <span [attr.aria-label]=\"'Bubble.content' | translate\">{{ content }}</span>\n </ng-template>\n </div>\n \n <!-- \u5E95\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"bottomTemplate\"></ng-container>\n <ng-content select=\"[bottom]\"></ng-content>\n </ng-container>\n </div>\n</div>\n", styles: [".mc-bubble{display:flex;gap:4px;font-size:var(--devui-font-size, 14px)}.mc-bubble .mc-bubble-content{word-wrap:break-word}.mc-bubble .mc-bubble-content.filled,.mc-bubble .mc-bubble-content.bordered{padding:12px 16px;border-radius:12px}.mc-bubble .mc-bubble-content.filled{background-color:var(--devui-global-bg, #f6f6f8)}.mc-bubble .mc-bubble-content.bordered{border:1px solid var(--devui-dividing-line, #f2f2f3)}.mc-bubble .mc-bubble-avatar{flex-shrink:0;display:flex;gap:4px}.mc-bubble .mc-bubble-avatar .mc-bubble-avatar-name{font-size:14px}.mc-bubble .mc-bubble-avatar.empty-avatar{visibility:hidden}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar{align-items:center}.mc-bubble .mc-bubble-content-container{max-width:100%}.mc-bubble.mc-bubble-avatar-top{flex-direction:column}.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{align-items:flex-start;flex-direction:column}.mc-bubble.mc-bubble-loading.mc-bubble-avatar-side{align-items:center}.mc-bubble.mc-bubble-avatar-side.mc-bubble-right{flex-direction:row-reverse;justify-content:end}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{display:flex}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-content-container{align-items:flex-end}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar{flex-direction:row-reverse}\n"] }]
585
+ args: [{ selector: 'mc-bubble', standalone: true, imports: [CommonModule, BubbleLoadingComponent, AvatarComponent, TranslatePipe], template: "<div class=\"mc-bubble\" [ngClass]=\"bubbleClasses\" role=\"group\" [attr.aria-label]=\"'Bubble.ariaLabel' | translate\">\n <!-- \u81EA\u5B9A\u4E49\u5934\u50CF\u533A\u57DF -->\n <div *ngIf=\"avatarTemplate\" class=\"mc-bubble-avatar\" role=\"img\">\n <ng-container *ngTemplateOutlet=\"avatarTemplate\"></ng-container>\n <ng-content select=\"[avatar]\"></ng-content>\n </div>\n \n <!-- \u9ED8\u8BA4\u5934\u50CF\u914D\u7F6E -->\n <div *ngIf=\"!avatarTemplate && avatarConfig\"\n class=\"mc-bubble-avatar\" role=\"img\"\n [ngClass]=\"{ 'empty-avatar': isEmptyAvatar }\"\n >\n <mc-avatar\n *ngIf=\"!isEmptyAvatar\"\n [imgSrc]=\"avatarConfig?.imgSrc || ''\"\n [name]=\"avatarConfig?.name || ''\"\n [width]=\"avatarConfig?.width || 36\"\n [height]=\"avatarConfig?.height || 36\"\n [gender]=\"avatarConfig?.gender || ''\"\n />\n <div *ngIf=\"isEmptyAvatar\" class=\"mc-bubble-avatar-wrapper\" [attr.aria-label]=\"'Bubble.emptyAvatar' | translate\"\n [style.width.px]=\"avatarConfig?.width || 36\"\n [style.height.px]=\"avatarConfig?.height || 36\"></div>\n <span *ngIf=\"avatarPosition === 'top'\" class=\"mc-bubble-avatar-name\" [attr.aria-label]=\"'Bubble.userName' | translate:{ name: avatarConfig?.displayName || '' } \">{{\n avatarConfig?.displayName\n }}</span>\n </div>\n <div\n class=\"mc-bubble-content-container\" aria-live=\"polite\"\n [ngClass]=\"{ 'with-avatar': avatarTemplate || avatarConfig }\"\n >\n <!-- \u9876\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"topTemplate\"></ng-container>\n <ng-content select=\"[top]\"></ng-content>\n </ng-container>\n \n <!-- \u52A0\u8F7D\u72B6\u6001 -->\n <div *ngIf=\"loading\" class=\"loading-container\" role=\"status\" aria-busy=\"true\">\n <ng-container *ngIf=\"loadingTplTemplate; else defaultLoadingTemplate\">\n <ng-container *ngTemplateOutlet=\"loadingTplTemplate\"></ng-container>\n <ng-content select=\"[loadingTpl]\"></ng-content>\n </ng-container>\n <ng-template #defaultLoadingTemplate>\n <mc-bubble-loading></mc-bubble-loading>\n </ng-template>\n </div>\n \n <!-- \u4E3B\u8981\u5185\u5BB9 -->\n <div\n *ngIf=\"!loading\"\n class=\"mc-bubble-content\"\n [ngClass]=\"[variant]\"\n role=\"region\"\n >\n <ng-content></ng-content>\n <ng-container *ngIf=\"content && !ngContentProjected\">\n <span [attr.aria-label]=\"'Bubble.content' | translate\">{{ content }}</span>\n </ng-container>\n </div>\n \n <!-- \u5E95\u90E8\u5185\u5BB9\u6295\u5F71 -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngTemplateOutlet=\"bottomTemplate\"></ng-container>\n <ng-content select=\"[bottom]\"></ng-content>\n </ng-container>\n </div>\n</div>\n", styles: [".mc-bubble{display:flex;gap:4px;font-size:var(--devui-font-size, 14px)}.mc-bubble .mc-bubble-content{word-wrap:break-word}.mc-bubble .mc-bubble-content.filled,.mc-bubble .mc-bubble-content.bordered{padding:12px 16px;border-radius:12px}.mc-bubble .mc-bubble-content.filled{background-color:var(--devui-global-bg, #f6f6f8)}.mc-bubble .mc-bubble-content.bordered{border:1px solid var(--devui-dividing-line, #f2f2f3)}.mc-bubble .mc-bubble-avatar{flex-shrink:0;display:flex;gap:4px}.mc-bubble .mc-bubble-avatar .mc-bubble-avatar-name{font-size:14px}.mc-bubble .mc-bubble-avatar.empty-avatar{visibility:hidden}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar{align-items:center}.mc-bubble .mc-bubble-content-container{max-width:100%}.mc-bubble.mc-bubble-avatar-top{flex-direction:column}.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{align-items:flex-start;flex-direction:column}.mc-bubble.mc-bubble-loading.mc-bubble-avatar-side{align-items:center}.mc-bubble.mc-bubble-avatar-side.mc-bubble-right{flex-direction:row-reverse;justify-content:end}.mc-bubble.mc-bubble-avatar-top .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top .mc-bubble-content-container{display:flex}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar,.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-content-container{align-items:flex-end}.mc-bubble.mc-bubble-avatar-top.mc-bubble-right .mc-bubble-avatar{flex-direction:row-reverse}\n"] }]
524
586
  }], ctorParameters: () => [], propDecorators: { content: [{
525
587
  type: Input
526
588
  }], loading: [{
@@ -533,18 +595,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
533
595
  type: Input
534
596
  }], avatarConfig: [{
535
597
  type: Input
598
+ }], avatarTemplate: [{
599
+ type: ContentChild,
600
+ args: ['avatar']
536
601
  }], topTemplate: [{
537
602
  type: ContentChild,
538
603
  args: ['top']
539
604
  }], loadingTplTemplate: [{
540
605
  type: ContentChild,
541
606
  args: ['loadingTpl']
542
- }], defaultTemplate: [{
543
- type: ContentChild,
544
- args: ['defaultTemplate']
545
607
  }], bottomTemplate: [{
546
608
  type: ContentChild,
547
609
  args: ['bottom']
610
+ }], contentChildren: [{
611
+ type: ContentChildren,
612
+ args: ['ng-content']
548
613
  }] } });
549
614
 
550
615
  class BubbleModule {
@@ -791,7 +856,6 @@ class InputFoundation extends BaseFoundation {
791
856
  this._adapter.emitChange();
792
857
  }
793
858
  emitChange() {
794
- console.log('emitChange---2');
795
859
  this._adapter.emitChange();
796
860
  }
797
861
  submit(inputValue) {
@@ -819,6 +883,11 @@ class InputFoundation extends BaseFoundation {
819
883
  }
820
884
  }
821
885
 
886
+ // 默认的autosize配置
887
+ const DEFAULT_AUTOSIZE = {
888
+ minRows: 1,
889
+ maxRows: 5
890
+ };
822
891
  // 创建一个token用于组件间通信
823
892
  const inputContextToken = 'input-context';
824
893
  class InputComponent extends BaseComponent {
@@ -836,6 +905,9 @@ class InputComponent extends BaseComponent {
836
905
  this.maxLength = null;
837
906
  this.submitShortKey = SubmitShortKey.Enter;
838
907
  this.autofocus = false;
908
+ this.autosize = false;
909
+ // textarea样式
910
+ this.textareaStyle = {};
839
911
  this.change = new EventEmitter();
840
912
  this.submit = new EventEmitter();
841
913
  this.cancel = new EventEmitter();
@@ -873,6 +945,12 @@ class InputComponent extends BaseComponent {
873
945
  ngOnChanges(changes) {
874
946
  if (changes['value']) {
875
947
  this.inputValue = changes['value']?.currentValue || '';
948
+ // 值变化时更新textarea样式
949
+ this.updateTextareaStyle();
950
+ }
951
+ if (changes['autosize']) {
952
+ // autosize配置变化时更新textarea样式
953
+ this.updateTextareaStyle();
876
954
  }
877
955
  }
878
956
  get inputClasses() {
@@ -884,6 +962,8 @@ class InputComponent extends BaseComponent {
884
962
  onInput() {
885
963
  if (!this.lock) {
886
964
  this.foundation.emitChange();
965
+ // 输入时更新textarea样式
966
+ this.updateTextareaStyle();
887
967
  }
888
968
  }
889
969
  onCompositionStart() {
@@ -920,6 +1000,92 @@ class InputComponent extends BaseComponent {
920
1000
  this.textareaElement.nativeElement.focus();
921
1001
  });
922
1002
  }
1003
+ // 初始化时更新textarea样式
1004
+ this.updateTextareaStyle();
1005
+ }
1006
+ // 更新textarea样式
1007
+ updateTextareaStyle() {
1008
+ if (!this.textareaElement || this.autosize === false) {
1009
+ this.textareaStyle = {};
1010
+ return;
1011
+ }
1012
+ const config = this.getAutosizeConfig();
1013
+ const result = this.computeTextareaHeight(this.textareaElement.nativeElement, config.minRows, config.maxRows);
1014
+ this.textareaStyle = {
1015
+ ...result,
1016
+ resize: 'none'
1017
+ };
1018
+ }
1019
+ // 获取autosize配置
1020
+ getAutosizeConfig() {
1021
+ return typeof this.autosize === 'boolean'
1022
+ ? DEFAULT_AUTOSIZE
1023
+ : this.autosize;
1024
+ }
1025
+ // 计算textarea高度
1026
+ computeTextareaHeight(targetElement, minRows = 1, maxRows) {
1027
+ const style = window.getComputedStyle(targetElement);
1028
+ const boxSizing = style.getPropertyValue('box-sizing');
1029
+ const paddingSize = Number.parseFloat(style.getPropertyValue('padding-top')) +
1030
+ Number.parseFloat(style.getPropertyValue('padding-bottom'));
1031
+ const borderSize = Number.parseFloat(style.getPropertyValue('border-top-width')) +
1032
+ Number.parseFloat(style.getPropertyValue('border-bottom-width'));
1033
+ // 创建临时textarea元素
1034
+ const tempTextarea = document.createElement('textarea');
1035
+ const sizingStyle = [
1036
+ 'letter-spacing', 'line-height', 'padding-top', 'padding-bottom',
1037
+ 'font-family', 'font-weight', 'font-size', 'font-variant',
1038
+ 'text-rendering', 'text-transform', 'width', 'text-indent',
1039
+ 'padding-left', 'padding-right', 'border-width', 'box-sizing',
1040
+ 'word-break', 'white-space'
1041
+ ];
1042
+ const contextStyle = sizingStyle
1043
+ .map(name => `${name}:${style.getPropertyValue(name)}`)
1044
+ .join(';');
1045
+ const hiddenStyle = `
1046
+ min-height:0 !important;
1047
+ max-height:none !important;
1048
+ height:0 !important;
1049
+ visibility:hidden !important;
1050
+ overflow:hidden !important;
1051
+ position:absolute !important;
1052
+ z-index:-1000 !important;
1053
+ top:0 !important;
1054
+ right:0 !important;
1055
+ pointer-events:none !important;
1056
+ `;
1057
+ tempTextarea.setAttribute('style', `${contextStyle};${hiddenStyle}`);
1058
+ tempTextarea.value = targetElement.value || targetElement.placeholder || '';
1059
+ document.body.appendChild(tempTextarea);
1060
+ let height = tempTextarea.scrollHeight;
1061
+ const result = {
1062
+ height: `${height}px`
1063
+ };
1064
+ if (minRows !== undefined || maxRows !== undefined) {
1065
+ tempTextarea.value = ' ';
1066
+ const singleRowHeight = tempTextarea.scrollHeight - paddingSize;
1067
+ if (minRows !== undefined) {
1068
+ let minHeight = singleRowHeight * minRows;
1069
+ if (boxSizing === 'border-box') {
1070
+ minHeight = minHeight + paddingSize + borderSize;
1071
+ }
1072
+ height = Math.max(minHeight, height);
1073
+ result['minHeight'] = `${minHeight}px`;
1074
+ }
1075
+ if (maxRows !== undefined) {
1076
+ let maxHeight = singleRowHeight * maxRows;
1077
+ if (boxSizing === 'border-box') {
1078
+ maxHeight = maxHeight + paddingSize + borderSize;
1079
+ }
1080
+ if (height > maxHeight) {
1081
+ height = maxHeight;
1082
+ result['overflowY'] = 'auto';
1083
+ }
1084
+ }
1085
+ }
1086
+ document.body.removeChild(tempTextarea);
1087
+ result['height'] = `${height}px`;
1088
+ return result;
923
1089
  }
924
1090
  get placeholderText() {
925
1091
  return this.foundation.getPlaceholderText();
@@ -931,11 +1097,11 @@ class InputComponent extends BaseComponent {
931
1097
  this.blur.emit(event);
932
1098
  }
933
1099
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InputComponent, deps: [{ token: LocaleService }], target: i0.ɵɵFactoryTarget.Component }); }
934
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: InputComponent, isStandalone: true, selector: "mc-input", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled", displayType: "displayType", variant: "variant", sendBtnVariant: "sendBtnVariant", loading: "loading", showCount: "showCount", maxLength: "maxLength", submitShortKey: "submitShortKey", autofocus: "autofocus" }, outputs: { change: "change", submit: "submit", cancel: "cancel", focus: "focus", blur: "blur" }, providers: [{ provide: inputContextToken, useExisting: InputComponent }], queries: [{ propertyName: "headTemplate", first: true, predicate: ["head"], descendants: true }, { propertyName: "prefixTemplate", first: true, predicate: ["prefix"], descendants: true }, { propertyName: "suffixTemplate", first: true, predicate: ["suffix"], descendants: true }, { propertyName: "buttonTemplate", first: true, predicate: ["button"], descendants: true }, { propertyName: "extraTemplate", first: true, predicate: ["extra"], descendants: true }], viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["textarea"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"inputClasses\">\n <ng-container *ngIf=\"headTemplate; then headTemplate\"></ng-container>\n\n <div class=\"mc-input-content\">\n <ng-container *ngIf=\"prefixTemplate; then prefixTemplate\"></ng-container>\n\n <textarea\n #textarea\n [(ngModel)]=\"inputValue\"\n [placeholder]=\"placeholderText\"\n [disabled]=\"disabled\"\n [maxlength]=\"maxLength\"\n class=\"mc-textarea\"\n [ngClass]=\"{\n 'mc-textarea-simple': displayType === 'simple',\n 'mc-textarea-disabled': disabled\n }\"\n [attr.aria-label]=\"'Input.ariaLabel' | translate\"\n [attr.aria-disabled]=\"disabled\"\n (input)=\"onInput()\"\n (change)=\"onChange($event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n ></textarea>\n <ng-container *ngIf=\"suffixTemplate; then suffixTemplate\"></ng-container>\n\n <ng-container *ngIf=\"displayType === 'simple'\">\n <ng-container *ngIf=\"buttonTemplate; else defaultButton\">\n <ng-container\n *ngIf=\"buttonTemplate; then buttonTemplate\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </ng-container>\n </div>\n\n <div *ngIf=\"displayType === 'full'\" class=\"mc-input-foot\">\n <div class=\"mc-input-foot-left\">\n <ng-container *ngIf=\"extraTemplate; then extraTemplate\"></ng-container>\n <span *ngIf=\"showCount\" id=\"mc-input-count\" class=\"mc-input-foot-count\">\n {{ inputValue.length }}{{ !maxLength ? \"\" : \"/\" + maxLength }}\n </span>\n </div>\n\n <ng-container *ngIf=\"buttonTemplate; else defaultFooterButton\">\n <ng-container *ngIf=\"buttonTemplate; then buttonTemplate\"></ng-container>\n </ng-container>\n <ng-template #defaultFooterButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";body[ui-theme=infinity-theme]{--mc-text: #aeaeae;--mc-box-shadow: rgba(25, 25, 25, .06)}body[ui-theme=galaxy-theme]{--mc-text: #4e5057;--mc-box-shadow: rgba(206, 209, 219, .06)}.mc-input{display:flex;flex-direction:column;width:100%;padding:12px 0;border:1px solid var(--devui-form-control-line, #d7d8da);border-radius:16px;box-sizing:border-box;background-color:var(--devui-base-bg, #ffffff)}.mc-input.mc-input-simple{border-radius:24px}.mc-input.mc-input-simple .mc-input-content{padding:0 20px}.mc-input.mc-input-borderless{border:none;box-shadow:0 1px 8px 0 var(--mc-box-shadow, rgba(25, 25, 25, .06))}.mc-input.mc-input-disabled{background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-input .mc-input-content{display:flex;align-items:flex-end;padding:0 16px}.mc-input .mc-input-foot{display:flex;justify-content:space-between;align-items:center;height:32px;padding:0 16px}.mc-input .mc-input-foot .mc-input-foot-left{flex:1;height:100%;display:flex;align-items:center}.mc-input .mc-input-foot .mc-input-foot-left .mc-input-foot-count{color:var(--mc-text, #aeaeae);font-size:var(--devui-font-size-sm, 12px)}.mc-textarea{width:100%;height:64px;padding:4px 0;color:var(--devui-text, #252b3a);font-size:var(--devui-font-size, 14px);background-color:var(--devui-form-control-bg, #ffffff);vertical-align:middle;outline:none;box-sizing:border-box;resize:none;border:none}.mc-textarea.mc-textarea-simple{height:32px}.mc-textarea.mc-textarea-disabled{color:var(--devui-disabled-text, #cfd0d3);background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-textarea::placeholder{color:var(--devui-placeholder, #babbc0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "mc-button", inputs: ["disabled", "loading", "inputValue", "sendBtnVariant"], outputs: ["submit", "cancel", "change"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1100
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: InputComponent, isStandalone: true, selector: "mc-input", inputs: { value: "value", placeholder: "placeholder", disabled: "disabled", displayType: "displayType", variant: "variant", sendBtnVariant: "sendBtnVariant", loading: "loading", showCount: "showCount", maxLength: "maxLength", submitShortKey: "submitShortKey", autofocus: "autofocus", autosize: "autosize" }, outputs: { change: "change", submit: "submit", cancel: "cancel", focus: "focus", blur: "blur" }, providers: [{ provide: inputContextToken, useExisting: InputComponent }], queries: [{ propertyName: "headTemplate", first: true, predicate: ["head"], descendants: true }, { propertyName: "prefixTemplate", first: true, predicate: ["prefix"], descendants: true }, { propertyName: "suffixTemplate", first: true, predicate: ["suffix"], descendants: true }, { propertyName: "buttonTemplate", first: true, predicate: ["button"], descendants: true }, { propertyName: "extraTemplate", first: true, predicate: ["extra"], descendants: true }], viewQueries: [{ propertyName: "textareaElement", first: true, predicate: ["textarea"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"inputClasses\">\n <ng-container *ngIf=\"headTemplate; then headTemplate\"></ng-container>\n\n <div class=\"mc-input-content\">\n <ng-container *ngIf=\"prefixTemplate; then prefixTemplate\"></ng-container>\n\n <textarea\n #textarea\n [(ngModel)]=\"inputValue\"\n [placeholder]=\"placeholderText\"\n [disabled]=\"disabled\"\n [maxlength]=\"maxLength\"\n class=\"mc-textarea\"\n [ngClass]=\"{\n 'mc-textarea-simple': displayType === 'simple',\n 'mc-textarea-disabled': disabled\n }\"\n [ngStyle]=\"textareaStyle\"\n [attr.aria-label]=\"'Input.ariaLabel' | translate\"\n [attr.aria-disabled]=\"disabled\"\n (input)=\"onInput()\"\n (change)=\"onChange($event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n ></textarea>\n <ng-container *ngIf=\"suffixTemplate; then suffixTemplate\"></ng-container>\n\n <ng-container *ngIf=\"displayType === 'simple'\">\n <ng-container *ngIf=\"buttonTemplate; else defaultButton\">\n <ng-container\n *ngIf=\"buttonTemplate; then buttonTemplate\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </ng-container>\n </div>\n\n <div *ngIf=\"displayType === 'full'\" class=\"mc-input-foot\">\n <div class=\"mc-input-foot-left\">\n <ng-container *ngIf=\"extraTemplate; then extraTemplate\"></ng-container>\n <span *ngIf=\"showCount\" id=\"mc-input-count\" class=\"mc-input-foot-count\">\n {{ inputValue.length }}{{ !maxLength ? \"\" : \"/\" + maxLength }}\n </span>\n </div>\n\n <ng-container *ngIf=\"buttonTemplate; else defaultFooterButton\">\n <ng-container *ngIf=\"buttonTemplate; then buttonTemplate\"></ng-container>\n </ng-container>\n <ng-template #defaultFooterButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";body[ui-theme=infinity-theme]{--mc-text: #aeaeae;--mc-box-shadow: rgba(25, 25, 25, .06)}body[ui-theme=galaxy-theme]{--mc-text: #4e5057;--mc-box-shadow: rgba(206, 209, 219, .06)}.mc-input{display:flex;flex-direction:column;width:100%;padding:12px 0;border:1px solid var(--devui-form-control-line, #d7d8da);border-radius:16px;box-sizing:border-box;background-color:var(--devui-base-bg, #ffffff)}.mc-input.mc-input-simple{border-radius:24px}.mc-input.mc-input-simple .mc-input-content{padding:0 20px}.mc-input.mc-input-borderless{border:none;box-shadow:0 1px 8px 0 var(--mc-box-shadow, rgba(25, 25, 25, .06))}.mc-input.mc-input-disabled{background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-input .mc-input-content{display:flex;align-items:flex-end;padding:0 16px}.mc-input .mc-input-foot{display:flex;justify-content:space-between;align-items:center;height:32px;padding:0 16px}.mc-input .mc-input-foot .mc-input-foot-left{flex:1;height:100%;display:flex;align-items:center}.mc-input .mc-input-foot .mc-input-foot-left .mc-input-foot-count{color:var(--mc-text, #aeaeae);font-size:var(--devui-font-size-sm, 12px)}.mc-textarea{width:100%;height:64px;padding:4px 0;color:var(--devui-text, #252b3a);font-size:var(--devui-font-size, 14px);background-color:var(--devui-form-control-bg, #ffffff);vertical-align:middle;outline:none;box-sizing:border-box;resize:none;border:none}.mc-textarea.mc-textarea-simple{height:32px}.mc-textarea.mc-textarea-disabled{color:var(--devui-disabled-text, #cfd0d3);background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-textarea::placeholder{color:var(--devui-placeholder, #babbc0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "mc-button", inputs: ["disabled", "loading", "inputValue", "sendBtnVariant"], outputs: ["submit", "cancel", "change"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
935
1101
  }
936
1102
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: InputComponent, decorators: [{
937
1103
  type: Component,
938
- args: [{ selector: 'mc-input', standalone: true, imports: [CommonModule, FormsModule, ButtonComponent, TranslatePipe], providers: [{ provide: inputContextToken, useExisting: InputComponent }], template: "<div [ngClass]=\"inputClasses\">\n <ng-container *ngIf=\"headTemplate; then headTemplate\"></ng-container>\n\n <div class=\"mc-input-content\">\n <ng-container *ngIf=\"prefixTemplate; then prefixTemplate\"></ng-container>\n\n <textarea\n #textarea\n [(ngModel)]=\"inputValue\"\n [placeholder]=\"placeholderText\"\n [disabled]=\"disabled\"\n [maxlength]=\"maxLength\"\n class=\"mc-textarea\"\n [ngClass]=\"{\n 'mc-textarea-simple': displayType === 'simple',\n 'mc-textarea-disabled': disabled\n }\"\n [attr.aria-label]=\"'Input.ariaLabel' | translate\"\n [attr.aria-disabled]=\"disabled\"\n (input)=\"onInput()\"\n (change)=\"onChange($event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n ></textarea>\n <ng-container *ngIf=\"suffixTemplate; then suffixTemplate\"></ng-container>\n\n <ng-container *ngIf=\"displayType === 'simple'\">\n <ng-container *ngIf=\"buttonTemplate; else defaultButton\">\n <ng-container\n *ngIf=\"buttonTemplate; then buttonTemplate\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </ng-container>\n </div>\n\n <div *ngIf=\"displayType === 'full'\" class=\"mc-input-foot\">\n <div class=\"mc-input-foot-left\">\n <ng-container *ngIf=\"extraTemplate; then extraTemplate\"></ng-container>\n <span *ngIf=\"showCount\" id=\"mc-input-count\" class=\"mc-input-foot-count\">\n {{ inputValue.length }}{{ !maxLength ? \"\" : \"/\" + maxLength }}\n </span>\n </div>\n\n <ng-container *ngIf=\"buttonTemplate; else defaultFooterButton\">\n <ng-container *ngIf=\"buttonTemplate; then buttonTemplate\"></ng-container>\n </ng-container>\n <ng-template #defaultFooterButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";body[ui-theme=infinity-theme]{--mc-text: #aeaeae;--mc-box-shadow: rgba(25, 25, 25, .06)}body[ui-theme=galaxy-theme]{--mc-text: #4e5057;--mc-box-shadow: rgba(206, 209, 219, .06)}.mc-input{display:flex;flex-direction:column;width:100%;padding:12px 0;border:1px solid var(--devui-form-control-line, #d7d8da);border-radius:16px;box-sizing:border-box;background-color:var(--devui-base-bg, #ffffff)}.mc-input.mc-input-simple{border-radius:24px}.mc-input.mc-input-simple .mc-input-content{padding:0 20px}.mc-input.mc-input-borderless{border:none;box-shadow:0 1px 8px 0 var(--mc-box-shadow, rgba(25, 25, 25, .06))}.mc-input.mc-input-disabled{background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-input .mc-input-content{display:flex;align-items:flex-end;padding:0 16px}.mc-input .mc-input-foot{display:flex;justify-content:space-between;align-items:center;height:32px;padding:0 16px}.mc-input .mc-input-foot .mc-input-foot-left{flex:1;height:100%;display:flex;align-items:center}.mc-input .mc-input-foot .mc-input-foot-left .mc-input-foot-count{color:var(--mc-text, #aeaeae);font-size:var(--devui-font-size-sm, 12px)}.mc-textarea{width:100%;height:64px;padding:4px 0;color:var(--devui-text, #252b3a);font-size:var(--devui-font-size, 14px);background-color:var(--devui-form-control-bg, #ffffff);vertical-align:middle;outline:none;box-sizing:border-box;resize:none;border:none}.mc-textarea.mc-textarea-simple{height:32px}.mc-textarea.mc-textarea-disabled{color:var(--devui-disabled-text, #cfd0d3);background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-textarea::placeholder{color:var(--devui-placeholder, #babbc0)}\n"] }]
1104
+ args: [{ selector: 'mc-input', standalone: true, imports: [CommonModule, FormsModule, ButtonComponent, TranslatePipe], providers: [{ provide: inputContextToken, useExisting: InputComponent }], template: "<div [ngClass]=\"inputClasses\">\n <ng-container *ngIf=\"headTemplate; then headTemplate\"></ng-container>\n\n <div class=\"mc-input-content\">\n <ng-container *ngIf=\"prefixTemplate; then prefixTemplate\"></ng-container>\n\n <textarea\n #textarea\n [(ngModel)]=\"inputValue\"\n [placeholder]=\"placeholderText\"\n [disabled]=\"disabled\"\n [maxlength]=\"maxLength\"\n class=\"mc-textarea\"\n [ngClass]=\"{\n 'mc-textarea-simple': displayType === 'simple',\n 'mc-textarea-disabled': disabled\n }\"\n [ngStyle]=\"textareaStyle\"\n [attr.aria-label]=\"'Input.ariaLabel' | translate\"\n [attr.aria-disabled]=\"disabled\"\n (input)=\"onInput()\"\n (change)=\"onChange($event)\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd()\"\n (keydown)=\"onKeydown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\"\n ></textarea>\n <ng-container *ngIf=\"suffixTemplate; then suffixTemplate\"></ng-container>\n\n <ng-container *ngIf=\"displayType === 'simple'\">\n <ng-container *ngIf=\"buttonTemplate; else defaultButton\">\n <ng-container\n *ngIf=\"buttonTemplate; then buttonTemplate\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </ng-container>\n </div>\n\n <div *ngIf=\"displayType === 'full'\" class=\"mc-input-foot\">\n <div class=\"mc-input-foot-left\">\n <ng-container *ngIf=\"extraTemplate; then extraTemplate\"></ng-container>\n <span *ngIf=\"showCount\" id=\"mc-input-count\" class=\"mc-input-foot-count\">\n {{ inputValue.length }}{{ !maxLength ? \"\" : \"/\" + maxLength }}\n </span>\n </div>\n\n <ng-container *ngIf=\"buttonTemplate; else defaultFooterButton\">\n <ng-container *ngIf=\"buttonTemplate; then buttonTemplate\"></ng-container>\n </ng-container>\n <ng-template #defaultFooterButton>\n <mc-button\n [disabled]=\"disabled || (!loading && !inputValue)\"\n [loading]=\"loading\"\n [inputValue]=\"inputValue\"\n [sendBtnVariant]=\"sendBtnVariant\"\n (submit)=\"onButtonSubmit($event)\"\n (cancel)=\"onButtonCancel()\"\n (change)=\"onButtonChange($event)\"\n ></mc-button>\n </ng-template>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";body[ui-theme=infinity-theme]{--mc-text: #aeaeae;--mc-box-shadow: rgba(25, 25, 25, .06)}body[ui-theme=galaxy-theme]{--mc-text: #4e5057;--mc-box-shadow: rgba(206, 209, 219, .06)}.mc-input{display:flex;flex-direction:column;width:100%;padding:12px 0;border:1px solid var(--devui-form-control-line, #d7d8da);border-radius:16px;box-sizing:border-box;background-color:var(--devui-base-bg, #ffffff)}.mc-input.mc-input-simple{border-radius:24px}.mc-input.mc-input-simple .mc-input-content{padding:0 20px}.mc-input.mc-input-borderless{border:none;box-shadow:0 1px 8px 0 var(--mc-box-shadow, rgba(25, 25, 25, .06))}.mc-input.mc-input-disabled{background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-input .mc-input-content{display:flex;align-items:flex-end;padding:0 16px}.mc-input .mc-input-foot{display:flex;justify-content:space-between;align-items:center;height:32px;padding:0 16px}.mc-input .mc-input-foot .mc-input-foot-left{flex:1;height:100%;display:flex;align-items:center}.mc-input .mc-input-foot .mc-input-foot-left .mc-input-foot-count{color:var(--mc-text, #aeaeae);font-size:var(--devui-font-size-sm, 12px)}.mc-textarea{width:100%;height:64px;padding:4px 0;color:var(--devui-text, #252b3a);font-size:var(--devui-font-size, 14px);background-color:var(--devui-form-control-bg, #ffffff);vertical-align:middle;outline:none;box-sizing:border-box;resize:none;border:none}.mc-textarea.mc-textarea-simple{height:32px}.mc-textarea.mc-textarea-disabled{color:var(--devui-disabled-text, #cfd0d3);background-color:var(--devui-disabled-bg, #f5f5f5);cursor:not-allowed}.mc-textarea::placeholder{color:var(--devui-placeholder, #babbc0)}\n"] }]
939
1105
  }], ctorParameters: () => [{ type: LocaleService }], propDecorators: { value: [{
940
1106
  type: Input
941
1107
  }], placeholder: [{
@@ -958,6 +1124,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
958
1124
  type: Input
959
1125
  }], autofocus: [{
960
1126
  type: Input
1127
+ }], autosize: [{
1128
+ type: Input
961
1129
  }], change: [{
962
1130
  type: Output
963
1131
  }], submit: [{
@@ -1015,6 +1183,1282 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
1015
1183
  }]
1016
1184
  }] });
1017
1185
 
1186
+ class MDCardService {
1187
+ constructor() {
1188
+ this.xssWhiteList = getDefaultWhiteList();
1189
+ this.cssWhiteList = getDefaultCSSWhiteList();
1190
+ this.setDefaultXss();
1191
+ }
1192
+ setDefaultXss() {
1193
+ this.xssWhiteList['input'] = ['type', 'checked', 'disabled', 'class'];
1194
+ this.xssWhiteList['label'] = ['for'];
1195
+ this.xssWhiteList['ul'] = ['class'];
1196
+ this.xssWhiteList['div'] = ['class'];
1197
+ this.xssWhiteList['a'] = ['href', 'class', 'target', 'name'];
1198
+ this.xssWhiteList['ol'] = ['start'];
1199
+ this.xssWhiteList['p'] = ['class'];
1200
+ this.xssWhiteList['span'] = ['style', 'class', 'title', 'id'];
1201
+ this.xssWhiteList['svg'] = ['style', 'class', 'width', 'height', 'viewbox', 'preserveaspectratio', 'id', 'fill', 'stroke'];
1202
+ this.xssWhiteList['path'] = ['style', 'class', 'd', 'id', 'fill', 'stroke'];
1203
+ this.xssWhiteList['th'] = ['style'];
1204
+ this.xssWhiteList['td'] = ['style'];
1205
+ }
1206
+ onIgnoreTagAttr(tag, name, value, isWhiteAttr) {
1207
+ if (!isWhiteAttr && (name === 'id' || (tag === 'span' && name === 'style'))) {
1208
+ return name + '=' + value;
1209
+ }
1210
+ return undefined;
1211
+ }
1212
+ getXssWhiteList() {
1213
+ return this.xssWhiteList;
1214
+ }
1215
+ setXssWhiteList(list) {
1216
+ this.xssWhiteList = list;
1217
+ }
1218
+ setCustomXssRules(rules) {
1219
+ if (rules) {
1220
+ rules.forEach((rule) => {
1221
+ if (rule['value'] === null) {
1222
+ delete this.xssWhiteList[rule['key']];
1223
+ }
1224
+ else {
1225
+ this.xssWhiteList[rule['key']] = rule['value'];
1226
+ }
1227
+ });
1228
+ }
1229
+ }
1230
+ setMdPlugins(plugins, mdt) {
1231
+ if (plugins && plugins.length) {
1232
+ plugins.forEach(item => {
1233
+ const { plugin, opts } = item;
1234
+ mdt.use(plugin, opts);
1235
+ });
1236
+ }
1237
+ }
1238
+ filterHtml(html) {
1239
+ return filterXSS(html, {
1240
+ whiteList: this.xssWhiteList,
1241
+ onIgnoreTagAttr: this.onIgnoreTagAttr,
1242
+ css: {
1243
+ whiteList: Object.assign({}, this.cssWhiteList, {
1244
+ top: true,
1245
+ left: true,
1246
+ bottom: true,
1247
+ right: true,
1248
+ }),
1249
+ },
1250
+ });
1251
+ }
1252
+ }
1253
+
1254
+ class MermaidService {
1255
+ constructor(config = {}) {
1256
+ this.config = config;
1257
+ this.mermaidInstance = null;
1258
+ this.isLoading = false;
1259
+ this.lastValidResult = '';
1260
+ this.viewStateMap = new WeakMap();
1261
+ this.containerHeight = 400;
1262
+ }
1263
+ async loadMermaid() {
1264
+ if (this.mermaidInstance) {
1265
+ return this.mermaidInstance;
1266
+ }
1267
+ if (this.isLoading) {
1268
+ return new Promise((resolve) => {
1269
+ const checkInstance = () => {
1270
+ if (this.mermaidInstance) {
1271
+ resolve(this.mermaidInstance);
1272
+ }
1273
+ else {
1274
+ setTimeout(checkInstance, 50);
1275
+ }
1276
+ };
1277
+ checkInstance();
1278
+ });
1279
+ }
1280
+ this.isLoading = true;
1281
+ try {
1282
+ const { default: mermaid } = await import('mermaid');
1283
+ mermaid.initialize({
1284
+ theme: this.config.theme || 'default',
1285
+ startOnLoad: false,
1286
+ suppressErrorRendering: true,
1287
+ ...this.config
1288
+ });
1289
+ this.mermaidInstance = mermaid;
1290
+ return mermaid;
1291
+ }
1292
+ catch (error) {
1293
+ console.error('Failed to load mermaid:', error);
1294
+ throw new Error('Failed to load mermaid library');
1295
+ }
1296
+ finally {
1297
+ this.isLoading = false;
1298
+ }
1299
+ }
1300
+ async renderToContainer(container, code, theme = 'light') {
1301
+ const svgStr = await this.renderMermaid(code, theme);
1302
+ container.innerHTML = svgStr;
1303
+ const svg = container.querySelector('svg');
1304
+ if (svg) {
1305
+ this.initViewState(container, svg);
1306
+ this.applyTransform(container, svg);
1307
+ svg.addEventListener('mousedown', (e) => this.onSvgMouseDown(e, container, svg));
1308
+ }
1309
+ }
1310
+ initViewState(container, svg) {
1311
+ // 获取svg的viewBox或宽高
1312
+ let vb = svg.getAttribute('viewBox');
1313
+ let svgW = 0, svgH = 0;
1314
+ if (vb) {
1315
+ const arr = vb.split(/\s+/);
1316
+ svgW = parseFloat(arr[2]);
1317
+ svgH = parseFloat(arr[3]);
1318
+ }
1319
+ else {
1320
+ svgW = svg.width.baseVal.value || svg.getBoundingClientRect().width;
1321
+ svgH = svg.height.baseVal.value || svg.getBoundingClientRect().height;
1322
+ }
1323
+ const contW = container.clientWidth || 0;
1324
+ const contH = this.containerHeight;
1325
+ let scale = 1;
1326
+ if (svgW && svgH && contW && contH) {
1327
+ scale = Math.min(contW / svgW, contH / svgH, 1);
1328
+ }
1329
+ this.viewStateMap.set(container, {
1330
+ scale,
1331
+ offsetX: 0,
1332
+ offsetY: 0,
1333
+ dragging: false,
1334
+ dragStart: { x: 0, y: 0 },
1335
+ lastOffset: { x: 0, y: 0 },
1336
+ });
1337
+ }
1338
+ applyTransform(container, svg) {
1339
+ const state = this.viewStateMap.get(container);
1340
+ if (!state)
1341
+ return;
1342
+ svg.style.position = 'absolute';
1343
+ svg.style.left = '50%';
1344
+ svg.style.top = '50%';
1345
+ svg.style.transform = `translate(-50%, -50%) translate(${state.offsetX}px, ${state.offsetY}px) scale(${state.scale})`;
1346
+ svg.style.transformOrigin = 'center center';
1347
+ svg.style.cursor = state.dragging ? 'grabbing' : 'grab';
1348
+ }
1349
+ zoomIn(container) {
1350
+ const svg = container.querySelector('svg');
1351
+ const state = this.viewStateMap.get(container);
1352
+ if (svg && state) {
1353
+ state.scale = Math.min(state.scale + 0.2, 3);
1354
+ this.applyTransform(container, svg);
1355
+ }
1356
+ }
1357
+ zoomOut(container) {
1358
+ const svg = container.querySelector('svg');
1359
+ const state = this.viewStateMap.get(container);
1360
+ if (svg && state) {
1361
+ state.scale = Math.max(state.scale - 0.2, 0.2);
1362
+ this.applyTransform(container, svg);
1363
+ }
1364
+ }
1365
+ reset(container) {
1366
+ const svg = container.querySelector('svg');
1367
+ if (svg) {
1368
+ this.initViewState(container, svg);
1369
+ this.applyTransform(container, svg);
1370
+ }
1371
+ }
1372
+ async download(container, filename = 'diagram.png') {
1373
+ const svg = container.querySelector('svg');
1374
+ if (!svg)
1375
+ return;
1376
+ try {
1377
+ const clonedSvg = svg.cloneNode(true);
1378
+ const svgData = new XMLSerializer().serializeToString(clonedSvg);
1379
+ const svgUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgData)}`;
1380
+ const img = new Image();
1381
+ await new Promise((resolve, reject) => {
1382
+ img.onload = () => resolve();
1383
+ img.onerror = (e) => reject(new Error('Image loading failed'));
1384
+ img.src = svgUrl;
1385
+ });
1386
+ const canvas = document.createElement('canvas');
1387
+ const ctx = canvas.getContext('2d');
1388
+ if (!ctx)
1389
+ throw new Error('Canvas context not available');
1390
+ canvas.width = img.width * 2;
1391
+ canvas.height = img.height * 2;
1392
+ ctx.fillStyle = 'white';
1393
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
1394
+ ctx.drawImage(img, 0, 0);
1395
+ canvas.toBlob((blob) => {
1396
+ if (!blob) {
1397
+ console.error('Failed to create blob from canvas');
1398
+ return;
1399
+ }
1400
+ const url = URL.createObjectURL(blob);
1401
+ const a = document.createElement('a');
1402
+ a.href = url;
1403
+ a.download = filename;
1404
+ document.body.appendChild(a);
1405
+ a.click();
1406
+ setTimeout(() => {
1407
+ document.body.removeChild(a);
1408
+ URL.revokeObjectURL(url);
1409
+ }, 100);
1410
+ }, 'image/png');
1411
+ }
1412
+ catch (error) {
1413
+ console.error('Failed to download diagram:', error);
1414
+ }
1415
+ }
1416
+ onSvgMouseDown(e, container, svg) {
1417
+ const state = this.viewStateMap.get(container);
1418
+ if (!state)
1419
+ return;
1420
+ state.dragging = true;
1421
+ state.dragStart = { x: e.clientX, y: e.clientY };
1422
+ state.lastOffset = { x: state.offsetX, y: state.offsetY };
1423
+ const move = (ev) => this.onSvgMouseMove(ev, container, svg);
1424
+ const up = () => this.onSvgMouseUp(container, svg, move, up);
1425
+ document.addEventListener('mousemove', move);
1426
+ document.addEventListener('mouseup', up);
1427
+ this.applyTransform(container, svg);
1428
+ }
1429
+ onSvgMouseMove(e, container, svg) {
1430
+ const state = this.viewStateMap.get(container);
1431
+ if (!state || !state.dragging)
1432
+ return;
1433
+ state.offsetX = state.lastOffset.x + (e.clientX - state.dragStart.x);
1434
+ state.offsetY = state.lastOffset.y + (e.clientY - state.dragStart.y);
1435
+ this.applyTransform(container, svg);
1436
+ }
1437
+ onSvgMouseUp(container, svg, move, up) {
1438
+ const state = this.viewStateMap.get(container);
1439
+ if (!state)
1440
+ return;
1441
+ state.dragging = false;
1442
+ document.removeEventListener('mousemove', move);
1443
+ document.removeEventListener('mouseup', up);
1444
+ this.applyTransform(container, svg);
1445
+ }
1446
+ async renderMermaid(code, theme = 'light') {
1447
+ try {
1448
+ const mermaid = await this.loadMermaid();
1449
+ if (this.config.theme !== theme) {
1450
+ this.config.theme = theme;
1451
+ mermaid.initialize({
1452
+ startOnLoad: false,
1453
+ suppressErrorRendering: true,
1454
+ theme: theme === 'dark' ? 'dark' : 'default',
1455
+ ...this.config
1456
+ });
1457
+ }
1458
+ const id = `mc_mermaid_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1459
+ const { svg } = await mermaid.render(id, code);
1460
+ this.lastValidResult = svg;
1461
+ return svg;
1462
+ }
1463
+ catch (error) {
1464
+ return this.lastValidResult;
1465
+ }
1466
+ }
1467
+ // 设置配置
1468
+ setConfig(config = {}) {
1469
+ this.config = {
1470
+ theme: 'default',
1471
+ ...config
1472
+ };
1473
+ }
1474
+ }
1475
+
1476
+ class CodeBlockFoundation extends BaseFoundation {
1477
+ constructor(adapter) {
1478
+ super({ ...adapter });
1479
+ this.toggleExpand = () => {
1480
+ this.setState({ expanded: !this.getStates().expanded });
1481
+ };
1482
+ this.zoomOut = () => {
1483
+ const container = this._adapter.getContainer();
1484
+ if (container && this.mermaidService) {
1485
+ this.mermaidService.zoomOut(container);
1486
+ }
1487
+ };
1488
+ this.zoomIn = () => {
1489
+ const container = this._adapter.getContainer();
1490
+ if (container && this.mermaidService) {
1491
+ this.mermaidService.zoomIn(container);
1492
+ }
1493
+ };
1494
+ this.checkIsMermaid = () => {
1495
+ const { enableMermaid, language } = this.getProps();
1496
+ return enableMermaid && language?.toLowerCase() === 'mermaid';
1497
+ };
1498
+ this.download = () => {
1499
+ const container = this._adapter.getContainer();
1500
+ if (container && this.mermaidService) {
1501
+ this.mermaidService.download(container);
1502
+ }
1503
+ };
1504
+ this.handleCopySuccess = () => {
1505
+ this.setState({ copied: true });
1506
+ setTimeout(() => {
1507
+ this.setState({ copied: false });
1508
+ }, 1500);
1509
+ };
1510
+ this.updateHighlightedCode = () => {
1511
+ const { code, language } = this.getProps();
1512
+ let highlightedCode = '';
1513
+ try {
1514
+ const typeIndex = code.indexOf(`<span class="mc-typewriter`);
1515
+ if (language && hljs.getLanguage(language)) {
1516
+ if (typeIndex !== -1) {
1517
+ highlightedCode =
1518
+ hljs.highlight(code.slice(0, typeIndex), {
1519
+ language,
1520
+ }).value + code.slice(typeIndex);
1521
+ }
1522
+ else {
1523
+ highlightedCode = hljs.highlight(code, {
1524
+ language,
1525
+ }).value;
1526
+ }
1527
+ }
1528
+ else {
1529
+ if (typeof hljs.highlightAuto !== 'undefined') {
1530
+ if (typeIndex !== -1) {
1531
+ highlightedCode =
1532
+ hljs.highlightAuto(code.slice(0, typeIndex)).value +
1533
+ code.slice(typeIndex);
1534
+ }
1535
+ else {
1536
+ highlightedCode = hljs.highlightAuto(code).value;
1537
+ }
1538
+ }
1539
+ else {
1540
+ highlightedCode = this.mdCardService.filterHtml(code);
1541
+ }
1542
+ }
1543
+ }
1544
+ catch (_) {
1545
+ highlightedCode = code;
1546
+ }
1547
+ this.setState({ highlightedCode });
1548
+ };
1549
+ this.renderMermaid = async () => {
1550
+ const { code, theme, mermaidConfig, } = this.getProps();
1551
+ const { mermaidContentRef } = this.getStates();
1552
+ const isMermaid = this.checkIsMermaid();
1553
+ if (!isMermaid || !code || !mermaidContentRef) {
1554
+ return;
1555
+ }
1556
+ if (!this.mermaidService) {
1557
+ try {
1558
+ this.mermaidService = new MermaidService();
1559
+ const config = {
1560
+ theme: theme === 'dark' ? 'dark' : 'default',
1561
+ ...mermaidConfig,
1562
+ };
1563
+ this.mermaidService.setConfig(config);
1564
+ }
1565
+ catch (error) {
1566
+ console.error('Failed to load MermaidService:', error);
1567
+ return;
1568
+ }
1569
+ }
1570
+ this.nextTick(async () => {
1571
+ const container = mermaidContentRef.nativeElement;
1572
+ if (container) {
1573
+ // 移除打字效果相关的span标签
1574
+ const cleanCode = code.replace(/<span[^>]*\bclass\s*=\s*['"]mc-typewriter[^>]*>([\s\S]*?)<\/span>/g, `$1`);
1575
+ await this.mermaidService?.renderToContainer(container, cleanCode, theme);
1576
+ }
1577
+ });
1578
+ };
1579
+ this.mdCardService = new MDCardService();
1580
+ }
1581
+ copyCodeInternal() {
1582
+ const { code } = this.getProps();
1583
+ if (navigator.clipboard) {
1584
+ navigator.clipboard.writeText(code).then(() => {
1585
+ this.handleCopySuccess();
1586
+ });
1587
+ }
1588
+ else {
1589
+ const textarea = document.createElement('textarea');
1590
+ textarea.style.position = 'fixed';
1591
+ textarea.style.top = '-9999px';
1592
+ textarea.style.left = '-9999px';
1593
+ textarea.style.zIndex = '-1';
1594
+ textarea.value = code;
1595
+ document.body.appendChild(textarea);
1596
+ textarea.select();
1597
+ document.execCommand('copy');
1598
+ document.body.removeChild(textarea);
1599
+ this.handleCopySuccess();
1600
+ }
1601
+ }
1602
+ }
1603
+
1604
+ class CodeBlockComponent extends BaseComponent {
1605
+ get showMermaidDiagram() {
1606
+ return this._showMermaidDiagram;
1607
+ }
1608
+ set showMermaidDiagram(value) {
1609
+ if (this._showMermaidDiagram !== value) {
1610
+ this._showMermaidDiagram = value;
1611
+ // 当切换为显示图表且当前是mermaid类型时,渲染图表
1612
+ if (value && this.isMermaid) {
1613
+ // 在视图更新后渲染mermaid
1614
+ setTimeout(() => {
1615
+ this.renderMermaid();
1616
+ });
1617
+ }
1618
+ }
1619
+ }
1620
+ constructor(cdr) {
1621
+ super();
1622
+ this.cdr = cdr;
1623
+ this.code = '';
1624
+ this.language = '';
1625
+ this.blockIndex = 0;
1626
+ this.theme = 'light';
1627
+ this.enableMermaid = false;
1628
+ this.mermaidConfig = {};
1629
+ this.contentTemplate = null;
1630
+ this.headerTemplate = null;
1631
+ this.actionsTemplate = null;
1632
+ this.expanded = true;
1633
+ this.copied = false;
1634
+ this.mermaidContent = '';
1635
+ this._showMermaidDiagram = true;
1636
+ this.highlightedCode = '';
1637
+ this.isMermaid = false;
1638
+ this.copySubject = new Subject();
1639
+ this.copySubject
1640
+ .pipe(debounceTime(300))
1641
+ .subscribe(() => this.copyCodeInternal());
1642
+ this.foundation = new CodeBlockFoundation(this.adapter);
1643
+ }
1644
+ get adapter() {
1645
+ return {
1646
+ ...super.adapter,
1647
+ getContainer: () => {
1648
+ return this.mermaidContentRef.nativeElement;
1649
+ },
1650
+ };
1651
+ }
1652
+ switchShowMermaid(show) {
1653
+ this.showMermaidDiagram = show;
1654
+ this.cdr.detectChanges();
1655
+ }
1656
+ ngOnInit() {
1657
+ this.checkIsMermaid();
1658
+ this.updateHighlightedCode();
1659
+ if (this.isMermaid) {
1660
+ this.renderMermaid();
1661
+ }
1662
+ }
1663
+ ngAfterViewInit() {
1664
+ if (this.isMermaid) {
1665
+ this.renderMermaid();
1666
+ }
1667
+ }
1668
+ ngOnChanges(changes) {
1669
+ if (changes['code'] || changes['language']) {
1670
+ this.checkIsMermaid();
1671
+ this.updateHighlightedCode();
1672
+ }
1673
+ if (changes['enableMermaid'] || changes['theme'] || changes['code']) {
1674
+ this.checkIsMermaid();
1675
+ if (this.isMermaid) {
1676
+ this.renderMermaid();
1677
+ }
1678
+ }
1679
+ if (changes['showMermaidDiagram'] &&
1680
+ this.isMermaid &&
1681
+ this.showMermaidDiagram) {
1682
+ this.renderMermaid();
1683
+ }
1684
+ }
1685
+ checkIsMermaid() {
1686
+ this.isMermaid = this.foundation.checkIsMermaid();
1687
+ }
1688
+ updateHighlightedCode() {
1689
+ this.foundation.updateHighlightedCode();
1690
+ }
1691
+ zoomIn() {
1692
+ this.foundation.zoomIn();
1693
+ this.cdr.detectChanges();
1694
+ }
1695
+ zoomOut() {
1696
+ this.foundation.zoomOut();
1697
+ this.cdr.detectChanges();
1698
+ }
1699
+ download() {
1700
+ this.foundation.download();
1701
+ }
1702
+ async renderMermaid() {
1703
+ await this.foundation.renderMermaid();
1704
+ }
1705
+ toggleExpand() {
1706
+ this.foundation.toggleExpand();
1707
+ this.cdr.detectChanges();
1708
+ }
1709
+ copyCode() {
1710
+ this.copySubject.next();
1711
+ }
1712
+ copyCodeInternal() {
1713
+ this.foundation.copyCodeInternal();
1714
+ }
1715
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: CodeBlockComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1716
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.0", type: CodeBlockComponent, selector: "mc-code-block", inputs: { code: "code", language: "language", blockIndex: "blockIndex", theme: "theme", enableMermaid: "enableMermaid", mermaidConfig: "mermaidConfig", contentTemplate: "contentTemplate", headerTemplate: "headerTemplate", actionsTemplate: "actionsTemplate" }, viewQueries: [{ propertyName: "rootRef", first: true, predicate: ["rootRef"], descendants: true }, { propertyName: "mermaidContentRef", first: true, predicate: ["mermaidContent"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"mc-code-block\"\n [ngClass]=\"theme === 'dark' ? 'mc-code-block-dark' : 'mc-code-block-light'\"\n #rootRef\n>\n <div class=\"mc-code-block-header\" *ngIf=\"!headerTemplate\">\n <span class=\"mc-code-lang\">{{ language }}</span>\n <ng-container *ngIf=\"!actionsTemplate\">\n <div class=\"mc-code-block-actions\">\n <div *ngIf=\"isMermaid\" style=\"margin-right: 8px\">\n <ul\n class=\"mc-diagram-switch\"\n [ngClass]=\"{ 'mc-show-code': !showMermaidDiagram }\"\n >\n <li\n (click)=\"switchShowMermaid(true)\"\n [ngClass]=\"{ 'mc-diagram-switch-active': showMermaidDiagram }\"\n >\n \u56FE\u8868\n </li>\n <li\n (click)=\"switchShowMermaid(false)\"\n [ngClass]=\"{ 'mc-diagram-switch-active': !showMermaidDiagram }\"\n >\n \u4EE3\u7801\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n [title]=\"'Md.zoomIn' | translate\"\n (click)=\"zoomIn()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"enlarge\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M7.16666667,1 C10.572409,1 13.3333333,3.76092429 13.3333333,7.16666667 C13.3333333,8.68984984 12.781084,10.0840543 11.8658888,11.1599767 L14.4225201,13.7154466 C14.6177822,13.9107088 14.6177822,14.2272912 14.4225201,14.4225534 C14.2489537,14.5961197 13.9795293,14.6154049 13.7846612,14.4804088 L13.7154133,14.4225534 L11.158968,11.8667467 C10.083183,12.7814291 8.68937384,13.3333333 7.16666667,13.3333333 C3.76092429,13.3333333 1,10.572409 1,7.16666667 C1,3.76092429 3.76092429,1 7.16666667,1 Z M7.16666667,2 C4.31320904,2 2,4.31320904 2,7.16666667 C2,10.0201243 4.31320904,12.3333333 7.16666667,12.3333333 C10.0201243,12.3333333 12.3333333,10.0201243 12.3333333,7.16666667 C12.3333333,4.31320904 10.0201243,2 7.16666667,2 Z M7.16666667,4.66666667 C7.41212656,4.66666667 7.61627504,4.84354183 7.658611,5.07679103 L7.66666667,5.16666667 L7.666,6.668 L9.16601582,6.66666666 C9.44215796,6.66630764 9.66630679,6.88987368 9.66666668,7.16601582 C9.66698576,7.4114755 9.49037648,7.61585405 9.25718258,7.65849359 L9.16731751,7.66666666 L7.666,7.668 L7.66666667,9.16666667 C7.66666667,9.44280904 7.44280904,9.66666667 7.16666667,9.66666667 C6.92120678,9.66666667 6.7170583,9.48979151 6.67472234,9.2565423 L6.66666667,9.16666667 L6.666,7.669 L5.17251751,7.67186668 C4.89637537,7.6722257 4.67222654,7.44865965 4.67186666,7.17251751 C4.67154758,6.92705783 4.84815685,6.72267929 5.08135075,6.68003974 L5.17121582,6.67186709 L6.666,6.669 L6.66666667,5.16666667 C6.66666667,4.89052429 6.89052429,4.66666667 7.16666667,4.66666667 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u7F29\u5C0F\"\n (click)=\"zoomOut()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"zoom-out\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M7.16666667,1 C10.572409,1 13.3333333,3.76092429 13.3333333,7.16666667 C13.3333333,8.68984984 12.781084,10.0840543 11.8658888,11.1599767 L14.4225201,13.7154466 C14.6177822,13.9107088 14.6177822,14.2272912 14.4225201,14.4225534 C14.2489537,14.5961197 13.9795293,14.6154049 13.7846612,14.4804088 L13.7154133,14.4225534 L11.158968,11.8667467 C10.083183,12.7814291 8.68937384,13.3333333 7.16666667,13.3333333 C3.76092429,13.3333333 1,10.572409 1,7.16666667 C1,3.76092429 3.76092429,1 7.16666667,1 Z M7.16666667,2 C4.31320904,2 2,4.31320904 2,7.16666667 C2,10.0201243 4.31320904,12.3333333 7.16666667,12.3333333 C10.0201243,12.3333333 12.3333333,10.0201243 12.3333333,7.16666667 C12.3333333,4.31320904 10.0201243,2 7.16666667,2 Z M9.16601582,6.66666666 C9.44215796,6.66630764 9.66630679,6.88987368 9.66666668,7.16601582 C9.66698576,7.4114755 9.49037648,7.61585405 9.25718258,7.65849359 L9.16731751,7.66666666 L5.17251751,7.67186668 C4.89637537,7.6722257 4.67222654,7.44865965 4.67186666,7.17251751 C4.67154758,6.92705783 4.84815685,6.72267929 5.08135075,6.68003974 L5.17121582,6.67186709 L9.16601582,6.66666666 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u4E0B\u8F7D\"\n (click)=\"download()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u9875\u9762-1\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g id=\"i\u4E0B\u8F7D\">\n <path\n d=\"M14.5,14 C14.7761424,14 15,14.2238576 15,14.5 C15,14.7761424 14.7761424,15 14.5,15 L1.5,15 C1.22385763,15 1,14.7761424 1,14.5 C1,14.2238576 1.22385763,14 1.5,14 L14.5,14 Z M8,1 C8.24545989,1 8.44960837,1.17687516 8.49194433,1.41012437 L8.5,1.5 L8.5,10.793 L11.6464466,7.64644661 C11.820013,7.47288026 12.0894374,7.45359511 12.2843055,7.58859116 L12.3535534,7.64644661 C12.5271197,7.82001296 12.5464049,8.08943736 12.4114088,8.2843055 L12.3535534,8.35355339 L8.35355339,12.3535534 L8.34128643,12.3654113 C8.32881868,12.3770608 8.31575424,12.3880797 8.30214392,12.3984173 L8.35355339,12.3535534 C8.32671912,12.3803877 8.29759357,12.4035342 8.26680652,12.422993 C8.25568247,12.4299807 8.24404667,12.4367067 8.23212724,12.4429657 C8.21827569,12.4502504 8.20453886,12.4566485 8.1905951,12.4623894 C8.17802507,12.4675915 8.16473685,12.4724419 8.15119917,12.4767316 C8.13583471,12.481552 8.12047425,12.4856039 8.10498705,12.4889143 C8.09430622,12.4912471 8.08325248,12.4932298 8.07207924,12.494843 C8.05487076,12.4972949 8.03773477,12.498877 8.02056948,12.4995793 C8.01375728,12.4998604 8.00689494,12.5 8,12.5 L7.98043349,12.4996194 C7.96293275,12.4989382 7.94546098,12.4973429 7.92809589,12.4948333 L8,12.5 C7.96390296,12.5 7.92869933,12.4961748 7.89477235,12.4889078 C7.87952575,12.4856039 7.86416529,12.481552 7.84898836,12.4767587 C7.83526315,12.4724419 7.82197493,12.4675915 7.80896344,12.4622078 C7.79546114,12.4566485 7.78172431,12.4502504 7.76824181,12.443195 C7.75595333,12.4367067 7.74431753,12.4299807 7.73298968,12.422812 C7.72729809,12.4192668 7.72146362,12.4154054 7.7156945,12.4114088 L7.69785608,12.3984173 C7.68424576,12.3880797 7.67118132,12.3770608 7.65871357,12.3654113 L7.64644661,12.3535534 L3.64644661,8.35355339 C3.45118446,8.15829124 3.45118446,7.84170876 3.64644661,7.64644661 C3.82001296,7.47288026 4.08943736,7.45359511 4.2843055,7.58859116 L4.35355339,7.64644661 L7.5,10.793 L7.5,1.5 C7.5,1.22385763 7.72385763,1 8,1 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n ></path>\n </g>\n </g>\n </svg>\n </div>\n <div\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u5C55\u5F00/\u6298\u53E0\"\n (click)=\"toggleExpand()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u5168\u90E8\u6536\u8D77\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M4.715694,14.4114091 C4.910563,14.5464051 5.179987,14.5271201 5.353553,14.3535531 L5.353553,14.3535531 L7.99999988,11.7070001 L10.646447,14.3535531 L10.715694,14.4114091 C10.910563,14.5464051 11.179987,14.5271201 11.353553,14.3535531 C11.548816,14.1582911 11.548816,13.8417091 11.353553,13.6464471 L11.353553,13.6464471 L8.353553,10.6464471 L8.284306,10.5885911 C8.089437,10.4535951 7.820013,10.4728801 7.646447,10.6464471 L7.646447,10.6464471 L4.646447,13.6464471 L4.588591,13.7156941 C4.453595,13.9105631 4.47288,14.1799871 4.646447,14.3535531 L4.646447,14.3535531 L4.715694,14.4114091 Z M14.5,7.50000012 C14.776142,7.50000012 15,7.72385812 15,8.00000012 C15,8.27614212 14.776142,8.50000012 14.5,8.50000012 L1.5,8.50000012 C1.223858,8.50000012 1,8.27614212 1,8.00000012 C1,7.72385812 1.223858,7.50000012 1.5,7.50000012 L14.5,7.50000012 Z M8.284306,5.41140912 L8.353553,5.35355312 L11.353553,2.35355312 C11.548816,2.15829112 11.548816,1.84170912 11.353553,1.64644712 C11.179987,1.47288012 10.910563,1.45359512 10.715694,1.58859112 L10.646447,1.64644712 L7.99999988,4.29300012 L5.353553,1.64644712 C5.179987,1.47288012 4.910563,1.45359512 4.715694,1.58859112 L4.646447,1.64644712 C4.47288,1.82001312 4.453595,2.08943712 4.588591,2.28430612 L4.646447,2.35355312 L7.646447,5.35355312 C7.820013,5.52712012 8.089437,5.54640512 8.284306,5.41140912 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n class=\"mc-action-btn mc-copy-btn\"\n title=\"\u590D\u5236\"\n (click)=\"copyCode()\"\n >\n @if(copied) {\n <span>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <defs>\n <polygon\n id=\"path-1\"\n points=\"6.53553391 9.77817459 12.1923882 4.12132034 13.6066017 5.53553391 6.53553391 12.6066017 3 9.07106781 4.41421356 7.65685425 6.53553391 9.77817459\"\n ></polygon>\n </defs>\n <g\n id=\"status/whiteBG/correct\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <mask id=\"mask-2\" fill=\"white\">\n <use xlink:href=\"#path-1\"></use>\n </mask>\n <use id=\"Mask\" fill=\"#3DCCA6\" xlink:href=\"#path-1\"></use>\n </g>\n </svg>\n </span>\n } @else {\n <span>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u9875\u9762-1\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"API-starter-\u56FE\u6807\u5165\u5E93\"\n transform=\"translate(-592.000000, -204.000000)\"\n >\n <g\n id=\"\u65B9\u683C\u5907\u4EFD-16\"\n transform=\"translate(560.000000, 180.000000)\"\n >\n <text\n id=\"\u56FE\u6807\"\n font-family=\"PingFangSC-Regular, PingFang SC\"\n font-size=\"12\"\n font-weight=\"normal\"\n line-spacing=\"16\"\n fill=\"#71757F\"\n >\n <tspan x=\"27.136\" y=\"61\">\u590D\u5236</tspan>\n </text>\n </g>\n <path\n d=\"M604.5,206 C605.279696,206 605.920449,206.594888 605.993133,207.35554 L606,207.5 L606,214.5 C606,215.279696 605.405112,215.920449 604.64446,215.993133 L604.5,216 L604,216 L604,216.5 C604,217.279696 603.405112,217.920449 602.64446,217.993133 L602.5,218 L595.5,218 C594.671573,218 594,217.328427 594,216.5 L594,216.5 L594,209.5 C594,208.671573 594.671573,208 595.5,208 L595.5,208 L596,208 L596,207.5 C596,206.720304 596.594888,206.079551 597.35554,206.006867 L597.5,206 L604.5,206 Z M602.5,209 L595.5,209 C595.223858,209 595,209.223858 595,209.5 L595,209.5 L595,216.5 C595,216.776142 595.223858,217 595.5,217 L595.5,217 L602.5,217 C602.776142,217 603,216.776142 603,216.5 L603,216.5 L603,209.5 C603,209.223858 602.776142,209 602.5,209 L602.5,209 Z M604.5,207 L597.5,207 C597.25454,207 597.050392,207.176875 597.008056,207.410124 L597,207.5 L597,208 L602.5,208 C603.279696,208 603.920449,208.594888 603.993133,209.35554 L604,209.5 L604,215 L604.5,215 C604.74546,215 604.949608,214.823125 604.991944,214.589876 L605,214.5 L605,207.5 C605,207.25454 604.823125,207.050392 604.589876,207.008056 L604.5,207 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </g>\n </svg>\n </span>\n }\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"actionsTemplate\">\n <ng-template [ngTemplateOutlet]=\"actionsTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n </div>\n <ng-container *ngIf=\"headerTemplate\">\n <ng-template [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n\n <div [ngClass]=\"{ 'mc-block-hidden': !expanded }\">\n @if (showMermaidDiagram && isMermaid && !contentTemplate) {\n <div class=\"mc-mermaid-content\" #mermaidContent></div>\n } @else if(!contentTemplate) {\n <pre><code [ngClass]=\"'hljs language-' + language\" [innerHTML]=\"highlightedCode\"></code></pre>\n } @else {\n <ng-container *ngIf=\"contentTemplate\">\n <ng-template [ngTemplateOutlet]=\"contentTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n }\n </div>\n</div>\n", styles: [".mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{list-style:none;margin:0;padding:0}.mc-markdown-render ::ng-deep ul{list-style-type:disc;padding-left:16px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep p{line-height:28px;margin:0;padding:0;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:underline;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}.mc-code-block-light ::ng-deep pre code.hljs{display:block;overflow-x:auto;padding:1em}.mc-code-block-light ::ng-deep code.hljs{padding:3px 5px}.mc-code-block-light ::ng-deep .hljs{background:#fefefe;color:#545454}.mc-code-block-light ::ng-deep .hljs-comment,.mc-code-block-light ::ng-deep .hljs-quote{color:#696969}.mc-code-block-light ::ng-deep .hljs-variable,.mc-code-block-light ::ng-deep .hljs-template-variable,.mc-code-block-light ::ng-deep .hljs-tag,.mc-code-block-light ::ng-deep .hljs-name,.mc-code-block-light ::ng-deep .hljs-selector-id,.mc-code-block-light ::ng-deep .hljs-selector-class,.mc-code-block-light ::ng-deep .hljs-regexp,.mc-code-block-light ::ng-deep .hljs-deletion{color:#d91e18}.mc-code-block-light ::ng-deep .hljs-number,.mc-code-block-light ::ng-deep .hljs-built_in,.mc-code-block-light ::ng-deep .hljs-literal,.mc-code-block-light ::ng-deep .hljs-type,.mc-code-block-light ::ng-deep .hljs-params,.mc-code-block-light ::ng-deep .hljs-meta,.mc-code-block-light ::ng-deep .hljs-link{color:#aa5d00}.mc-code-block-light ::ng-deep .hljs-attribute{color:#aa5d00}.mc-code-block-light ::ng-deep .hljs-string,.mc-code-block-light ::ng-deep .hljs-symbol,.mc-code-block-light ::ng-deep .hljs-bullet,.mc-code-block-light ::ng-deep .hljs-addition{color:green}.mc-code-block-light ::ng-deep .hljs-title,.mc-code-block-light ::ng-deep .hljs-section{color:#007faa}.mc-code-block-light ::ng-deep .hljs-keyword,.mc-code-block-light ::ng-deep .hljs-selector-tag{color:#7928a1}.mc-code-block-light ::ng-deep .hljs-emphasis{font-style:italic}.mc-code-block-light ::ng-deep .hljs-strong{font-weight:700}@media screen and (-ms-high-contrast: active){.mc-code-block-light ::ng-deep .hljs-addition,.mc-code-block-light ::ng-deep .hljs-attribute,.mc-code-block-light ::ng-deep .hljs-built_in,.mc-code-block-light ::ng-deep .hljs-bullet,.mc-code-block-light ::ng-deep .hljs-comment,.mc-code-block-light ::ng-deep .hljs-link,.mc-code-block-light ::ng-deep .hljs-literal,.mc-code-block-light ::ng-deep .hljs-meta,.mc-code-block-light ::ng-deep .hljs-number,.mc-code-block-light ::ng-deep .hljs-params,.mc-code-block-light ::ng-deep .hljs-string,.mc-code-block-light ::ng-deep .hljs-symbol,.mc-code-block-light ::ng-deep .hljs-type,.mc-code-block-light ::ng-deep .hljs-quote{color:highlight}.mc-code-block-light ::ng-deep .hljs-keyword,.mc-code-block-light ::ng-deep .hljs-selector-tag{font-weight:700}}.mc-code-block-light{border:1px solid #d7d8da}.mc-code-block-light code.hljs{padding:1em}.mc-code-block-light{background-color:#f5f5f5}.mc-code-block-light .mc-code-lang,.mc-code-block-light .mc-code-block-actions .mc-copy-btn,.mc-code-block-light .mc-code-block-actions .mc-toggle-btn{color:#252b3a}.mc-code-block-light .mc-code-block-actions .mc-copy-btn:hover,.mc-code-block-light .mc-code-block-actions .mc-toggle-btn:hover{background-color:#ebebeb}.mc-code-block-light .mc-mermaid-content{background:#fefefe}.mc-code-block-dark ::ng-deep pre code.hljs{display:block;overflow-x:auto;padding:1em}.mc-code-block-dark ::ng-deep code.hljs{padding:3px 5px}.mc-code-block-dark ::ng-deep .hljs{background:#2b2b2b;color:#f8f8f2}.mc-code-block-dark ::ng-deep .hljs-comment,.mc-code-block-dark ::ng-deep .hljs-quote{color:#d4d0ab}.mc-code-block-dark ::ng-deep .hljs-variable,.mc-code-block-dark ::ng-deep .hljs-template-variable,.mc-code-block-dark ::ng-deep .hljs-tag,.mc-code-block-dark ::ng-deep .hljs-name,.mc-code-block-dark ::ng-deep .hljs-selector-id,.mc-code-block-dark ::ng-deep .hljs-selector-class,.mc-code-block-dark ::ng-deep .hljs-regexp,.mc-code-block-dark ::ng-deep .hljs-deletion{color:#ffa07a}.mc-code-block-dark ::ng-deep .hljs-number,.mc-code-block-dark ::ng-deep .hljs-built_in,.mc-code-block-dark ::ng-deep .hljs-literal,.mc-code-block-dark ::ng-deep .hljs-type,.mc-code-block-dark ::ng-deep .hljs-params,.mc-code-block-dark ::ng-deep .hljs-meta,.mc-code-block-dark ::ng-deep .hljs-link{color:#f5ab35}.mc-code-block-dark ::ng-deep .hljs-attribute{color:gold}.mc-code-block-dark ::ng-deep .hljs-string,.mc-code-block-dark ::ng-deep .hljs-symbol,.mc-code-block-dark ::ng-deep .hljs-bullet,.mc-code-block-dark ::ng-deep .hljs-addition{color:#abe338}.mc-code-block-dark ::ng-deep .hljs-title,.mc-code-block-dark ::ng-deep .hljs-section{color:#00e0e0}.mc-code-block-dark ::ng-deep .hljs-keyword,.mc-code-block-dark ::ng-deep .hljs-selector-tag{color:#dcc6e0}.mc-code-block-dark ::ng-deep .hljs-emphasis{font-style:italic}.mc-code-block-dark ::ng-deep .hljs-strong{font-weight:700}@media screen and (-ms-high-contrast: active){.mc-code-block-dark ::ng-deep .hljs-addition,.mc-code-block-dark ::ng-deep .hljs-attribute,.mc-code-block-dark ::ng-deep .hljs-built_in,.mc-code-block-dark ::ng-deep .hljs-bullet,.mc-code-block-dark ::ng-deep .hljs-comment,.mc-code-block-dark ::ng-deep .hljs-link,.mc-code-block-dark ::ng-deep .hljs-literal,.mc-code-block-dark ::ng-deep .hljs-meta,.mc-code-block-dark ::ng-deep .hljs-number,.mc-code-block-dark ::ng-deep .hljs-params,.mc-code-block-dark ::ng-deep .hljs-string,.mc-code-block-dark ::ng-deep .hljs-symbol,.mc-code-block-dark ::ng-deep .hljs-type,.mc-code-block-dark ::ng-deep .hljs-quote{color:highlight}.mc-code-block-dark ::ng-deep .hljs-keyword,.mc-code-block-dark ::ng-deep .hljs-selector-tag{font-weight:700}}.mc-code-block-dark{border:1px solid #4e5057}.mc-code-block-dark code.hljs{padding:1em}.mc-code-block-dark{background-color:#34363a}.mc-code-block-dark .mc-code-lang,.mc-code-block-dark .mc-code-block-actions .mc-copy-btn,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn{color:#ced1db}.mc-code-block-dark .mc-code-block-actions .mc-copy-btn:hover,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn:hover{background-color:#393a3e}.mc-code-block-dark .mc-code-block-actions .mc-copy-btn img,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn img{filter:brightness(1.5)}.mc-code-block-dark .mc-mermaid-content{background:#2b2b2b!important}@keyframes collapse-expand{0%{opacity:0;max-height:0}to{opacity:1;max-height:1000px}}@keyframes collapse-collapse{0%{opacity:1;max-height:1000px}to{opacity:0;max-height:0}}.mc-block-hidden{display:none}.collapse-expanded{animation:collapse-expand .5s ease-out}.collapse-collapsed{animation:collapse-collapse .5s ease-in}.mc-code-block{margin:1rem 0;overflow:hidden;border-radius:14px}.mc-code-block pre{margin:0}.mc-code-block .mc-action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;box-sizing:border-box}.mc-code-block .mc-code-block-header{display:flex;justify-content:space-between;align-items:center;padding:.5rem 1rem}.mc-code-block .mc-code-block-header .mc-code-lang{font-size:14px}.mc-code-block .mc-mermaid-content{position:relative;width:100%;height:400px;overflow:hidden;background:inherit}.mc-code-block .mc-code-block-actions{display:flex;align-items:center}.mc-code-block .mc-code-block-actions .mc-copy-btn,.mc-code-block .mc-code-block-actions .mc-toggle-btn{cursor:pointer;border-radius:4px;font-size:18px;padding:4px}.mc-code-block .mc-diagram-switch{display:flex;align-items:center;list-style:none;margin:0;padding:2px;border-radius:4px;background-color:var(--devui-icon-hover-bg);position:relative;transition:all .3s ease;overflow:hidden;height:24px}.mc-code-block .mc-diagram-switch:before{content:\"\";position:absolute;top:2px;left:2px;width:calc(50% - 2px);height:calc(100% - 4px);background-color:var(--devui-base-bg);border-radius:4px;transition:transform .3s ease;box-shadow:0 1px 2px #0000001a;z-index:1}.mc-code-block .mc-diagram-switch.mc-show-code:before{transform:translate(100%)}.mc-code-block .mc-diagram-switch .mc-diagram-switch-active{text-shadow:0 0 .4px #252b3a}.mc-code-block .mc-diagram-switch li{position:relative;padding:0 8px;margin:0;font-size:12px;cursor:pointer;transition:color .3s ease;z-index:2}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
1717
+ }
1718
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: CodeBlockComponent, decorators: [{
1719
+ type: Component,
1720
+ args: [{ selector: 'mc-code-block', standalone: false, template: "<div\n class=\"mc-code-block\"\n [ngClass]=\"theme === 'dark' ? 'mc-code-block-dark' : 'mc-code-block-light'\"\n #rootRef\n>\n <div class=\"mc-code-block-header\" *ngIf=\"!headerTemplate\">\n <span class=\"mc-code-lang\">{{ language }}</span>\n <ng-container *ngIf=\"!actionsTemplate\">\n <div class=\"mc-code-block-actions\">\n <div *ngIf=\"isMermaid\" style=\"margin-right: 8px\">\n <ul\n class=\"mc-diagram-switch\"\n [ngClass]=\"{ 'mc-show-code': !showMermaidDiagram }\"\n >\n <li\n (click)=\"switchShowMermaid(true)\"\n [ngClass]=\"{ 'mc-diagram-switch-active': showMermaidDiagram }\"\n >\n \u56FE\u8868\n </li>\n <li\n (click)=\"switchShowMermaid(false)\"\n [ngClass]=\"{ 'mc-diagram-switch-active': !showMermaidDiagram }\"\n >\n \u4EE3\u7801\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n [title]=\"'Md.zoomIn' | translate\"\n (click)=\"zoomIn()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"enlarge\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M7.16666667,1 C10.572409,1 13.3333333,3.76092429 13.3333333,7.16666667 C13.3333333,8.68984984 12.781084,10.0840543 11.8658888,11.1599767 L14.4225201,13.7154466 C14.6177822,13.9107088 14.6177822,14.2272912 14.4225201,14.4225534 C14.2489537,14.5961197 13.9795293,14.6154049 13.7846612,14.4804088 L13.7154133,14.4225534 L11.158968,11.8667467 C10.083183,12.7814291 8.68937384,13.3333333 7.16666667,13.3333333 C3.76092429,13.3333333 1,10.572409 1,7.16666667 C1,3.76092429 3.76092429,1 7.16666667,1 Z M7.16666667,2 C4.31320904,2 2,4.31320904 2,7.16666667 C2,10.0201243 4.31320904,12.3333333 7.16666667,12.3333333 C10.0201243,12.3333333 12.3333333,10.0201243 12.3333333,7.16666667 C12.3333333,4.31320904 10.0201243,2 7.16666667,2 Z M7.16666667,4.66666667 C7.41212656,4.66666667 7.61627504,4.84354183 7.658611,5.07679103 L7.66666667,5.16666667 L7.666,6.668 L9.16601582,6.66666666 C9.44215796,6.66630764 9.66630679,6.88987368 9.66666668,7.16601582 C9.66698576,7.4114755 9.49037648,7.61585405 9.25718258,7.65849359 L9.16731751,7.66666666 L7.666,7.668 L7.66666667,9.16666667 C7.66666667,9.44280904 7.44280904,9.66666667 7.16666667,9.66666667 C6.92120678,9.66666667 6.7170583,9.48979151 6.67472234,9.2565423 L6.66666667,9.16666667 L6.666,7.669 L5.17251751,7.67186668 C4.89637537,7.6722257 4.67222654,7.44865965 4.67186666,7.17251751 C4.67154758,6.92705783 4.84815685,6.72267929 5.08135075,6.68003974 L5.17121582,6.67186709 L6.666,6.669 L6.66666667,5.16666667 C6.66666667,4.89052429 6.89052429,4.66666667 7.16666667,4.66666667 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u7F29\u5C0F\"\n (click)=\"zoomOut()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"zoom-out\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M7.16666667,1 C10.572409,1 13.3333333,3.76092429 13.3333333,7.16666667 C13.3333333,8.68984984 12.781084,10.0840543 11.8658888,11.1599767 L14.4225201,13.7154466 C14.6177822,13.9107088 14.6177822,14.2272912 14.4225201,14.4225534 C14.2489537,14.5961197 13.9795293,14.6154049 13.7846612,14.4804088 L13.7154133,14.4225534 L11.158968,11.8667467 C10.083183,12.7814291 8.68937384,13.3333333 7.16666667,13.3333333 C3.76092429,13.3333333 1,10.572409 1,7.16666667 C1,3.76092429 3.76092429,1 7.16666667,1 Z M7.16666667,2 C4.31320904,2 2,4.31320904 2,7.16666667 C2,10.0201243 4.31320904,12.3333333 7.16666667,12.3333333 C10.0201243,12.3333333 12.3333333,10.0201243 12.3333333,7.16666667 C12.3333333,4.31320904 10.0201243,2 7.16666667,2 Z M9.16601582,6.66666666 C9.44215796,6.66630764 9.66630679,6.88987368 9.66666668,7.16601582 C9.66698576,7.4114755 9.49037648,7.61585405 9.25718258,7.65849359 L9.16731751,7.66666666 L5.17251751,7.67186668 C4.89637537,7.6722257 4.67222654,7.44865965 4.67186666,7.17251751 C4.67154758,6.92705783 4.84815685,6.72267929 5.08135075,6.68003974 L5.17121582,6.67186709 L9.16601582,6.66666666 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n *ngIf=\"isMermaid && showMermaidDiagram\"\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u4E0B\u8F7D\"\n (click)=\"download()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u9875\u9762-1\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g id=\"i\u4E0B\u8F7D\">\n <path\n d=\"M14.5,14 C14.7761424,14 15,14.2238576 15,14.5 C15,14.7761424 14.7761424,15 14.5,15 L1.5,15 C1.22385763,15 1,14.7761424 1,14.5 C1,14.2238576 1.22385763,14 1.5,14 L14.5,14 Z M8,1 C8.24545989,1 8.44960837,1.17687516 8.49194433,1.41012437 L8.5,1.5 L8.5,10.793 L11.6464466,7.64644661 C11.820013,7.47288026 12.0894374,7.45359511 12.2843055,7.58859116 L12.3535534,7.64644661 C12.5271197,7.82001296 12.5464049,8.08943736 12.4114088,8.2843055 L12.3535534,8.35355339 L8.35355339,12.3535534 L8.34128643,12.3654113 C8.32881868,12.3770608 8.31575424,12.3880797 8.30214392,12.3984173 L8.35355339,12.3535534 C8.32671912,12.3803877 8.29759357,12.4035342 8.26680652,12.422993 C8.25568247,12.4299807 8.24404667,12.4367067 8.23212724,12.4429657 C8.21827569,12.4502504 8.20453886,12.4566485 8.1905951,12.4623894 C8.17802507,12.4675915 8.16473685,12.4724419 8.15119917,12.4767316 C8.13583471,12.481552 8.12047425,12.4856039 8.10498705,12.4889143 C8.09430622,12.4912471 8.08325248,12.4932298 8.07207924,12.494843 C8.05487076,12.4972949 8.03773477,12.498877 8.02056948,12.4995793 C8.01375728,12.4998604 8.00689494,12.5 8,12.5 L7.98043349,12.4996194 C7.96293275,12.4989382 7.94546098,12.4973429 7.92809589,12.4948333 L8,12.5 C7.96390296,12.5 7.92869933,12.4961748 7.89477235,12.4889078 C7.87952575,12.4856039 7.86416529,12.481552 7.84898836,12.4767587 C7.83526315,12.4724419 7.82197493,12.4675915 7.80896344,12.4622078 C7.79546114,12.4566485 7.78172431,12.4502504 7.76824181,12.443195 C7.75595333,12.4367067 7.74431753,12.4299807 7.73298968,12.422812 C7.72729809,12.4192668 7.72146362,12.4154054 7.7156945,12.4114088 L7.69785608,12.3984173 C7.68424576,12.3880797 7.67118132,12.3770608 7.65871357,12.3654113 L7.64644661,12.3535534 L3.64644661,8.35355339 C3.45118446,8.15829124 3.45118446,7.84170876 3.64644661,7.64644661 C3.82001296,7.47288026 4.08943736,7.45359511 4.2843055,7.58859116 L4.35355339,7.64644661 L7.5,10.793 L7.5,1.5 C7.5,1.22385763 7.72385763,1 8,1 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n ></path>\n </g>\n </g>\n </svg>\n </div>\n <div\n class=\"mc-action-btn mc-toggle-btn\"\n title=\"\u5C55\u5F00/\u6298\u53E0\"\n (click)=\"toggleExpand()\"\n >\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u5168\u90E8\u6536\u8D77\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <path\n d=\"M4.715694,14.4114091 C4.910563,14.5464051 5.179987,14.5271201 5.353553,14.3535531 L5.353553,14.3535531 L7.99999988,11.7070001 L10.646447,14.3535531 L10.715694,14.4114091 C10.910563,14.5464051 11.179987,14.5271201 11.353553,14.3535531 C11.548816,14.1582911 11.548816,13.8417091 11.353553,13.6464471 L11.353553,13.6464471 L8.353553,10.6464471 L8.284306,10.5885911 C8.089437,10.4535951 7.820013,10.4728801 7.646447,10.6464471 L7.646447,10.6464471 L4.646447,13.6464471 L4.588591,13.7156941 C4.453595,13.9105631 4.47288,14.1799871 4.646447,14.3535531 L4.646447,14.3535531 L4.715694,14.4114091 Z M14.5,7.50000012 C14.776142,7.50000012 15,7.72385812 15,8.00000012 C15,8.27614212 14.776142,8.50000012 14.5,8.50000012 L1.5,8.50000012 C1.223858,8.50000012 1,8.27614212 1,8.00000012 C1,7.72385812 1.223858,7.50000012 1.5,7.50000012 L14.5,7.50000012 Z M8.284306,5.41140912 L8.353553,5.35355312 L11.353553,2.35355312 C11.548816,2.15829112 11.548816,1.84170912 11.353553,1.64644712 C11.179987,1.47288012 10.910563,1.45359512 10.715694,1.58859112 L10.646447,1.64644712 L7.99999988,4.29300012 L5.353553,1.64644712 C5.179987,1.47288012 4.910563,1.45359512 4.715694,1.58859112 L4.646447,1.64644712 C4.47288,1.82001312 4.453595,2.08943712 4.588591,2.28430612 L4.646447,2.35355312 L7.646447,5.35355312 C7.820013,5.52712012 8.089437,5.54640512 8.284306,5.41140912 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n <div\n class=\"mc-action-btn mc-copy-btn\"\n title=\"\u590D\u5236\"\n (click)=\"copyCode()\"\n >\n @if(copied) {\n <span>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <defs>\n <polygon\n id=\"path-1\"\n points=\"6.53553391 9.77817459 12.1923882 4.12132034 13.6066017 5.53553391 6.53553391 12.6066017 3 9.07106781 4.41421356 7.65685425 6.53553391 9.77817459\"\n ></polygon>\n </defs>\n <g\n id=\"status/whiteBG/correct\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <mask id=\"mask-2\" fill=\"white\">\n <use xlink:href=\"#path-1\"></use>\n </mask>\n <use id=\"Mask\" fill=\"#3DCCA6\" xlink:href=\"#path-1\"></use>\n </g>\n </svg>\n </span>\n } @else {\n <span>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g\n id=\"\u9875\u9762-1\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n >\n <g\n id=\"API-starter-\u56FE\u6807\u5165\u5E93\"\n transform=\"translate(-592.000000, -204.000000)\"\n >\n <g\n id=\"\u65B9\u683C\u5907\u4EFD-16\"\n transform=\"translate(560.000000, 180.000000)\"\n >\n <text\n id=\"\u56FE\u6807\"\n font-family=\"PingFangSC-Regular, PingFang SC\"\n font-size=\"12\"\n font-weight=\"normal\"\n line-spacing=\"16\"\n fill=\"#71757F\"\n >\n <tspan x=\"27.136\" y=\"61\">\u590D\u5236</tspan>\n </text>\n </g>\n <path\n d=\"M604.5,206 C605.279696,206 605.920449,206.594888 605.993133,207.35554 L606,207.5 L606,214.5 C606,215.279696 605.405112,215.920449 604.64446,215.993133 L604.5,216 L604,216 L604,216.5 C604,217.279696 603.405112,217.920449 602.64446,217.993133 L602.5,218 L595.5,218 C594.671573,218 594,217.328427 594,216.5 L594,216.5 L594,209.5 C594,208.671573 594.671573,208 595.5,208 L595.5,208 L596,208 L596,207.5 C596,206.720304 596.594888,206.079551 597.35554,206.006867 L597.5,206 L604.5,206 Z M602.5,209 L595.5,209 C595.223858,209 595,209.223858 595,209.5 L595,209.5 L595,216.5 C595,216.776142 595.223858,217 595.5,217 L595.5,217 L602.5,217 C602.776142,217 603,216.776142 603,216.5 L603,216.5 L603,209.5 C603,209.223858 602.776142,209 602.5,209 L602.5,209 Z M604.5,207 L597.5,207 C597.25454,207 597.050392,207.176875 597.008056,207.410124 L597,207.5 L597,208 L602.5,208 C603.279696,208 603.920449,208.594888 603.993133,209.35554 L604,209.5 L604,215 L604.5,215 C604.74546,215 604.949608,214.823125 604.991944,214.589876 L605,214.5 L605,207.5 C605,207.25454 604.823125,207.050392 604.589876,207.008056 L604.5,207 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill=\"#71757F\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </g>\n </svg>\n </span>\n }\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"actionsTemplate\">\n <ng-template [ngTemplateOutlet]=\"actionsTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n </div>\n <ng-container *ngIf=\"headerTemplate\">\n <ng-template [ngTemplateOutlet]=\"headerTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n\n <div [ngClass]=\"{ 'mc-block-hidden': !expanded }\">\n @if (showMermaidDiagram && isMermaid && !contentTemplate) {\n <div class=\"mc-mermaid-content\" #mermaidContent></div>\n } @else if(!contentTemplate) {\n <pre><code [ngClass]=\"'hljs language-' + language\" [innerHTML]=\"highlightedCode\"></code></pre>\n } @else {\n <ng-container *ngIf=\"contentTemplate\">\n <ng-template [ngTemplateOutlet]=\"contentTemplate\" [ngTemplateOutletContext]=\"{ $implicit: {code, language}, codeBlockData: {code, language} }\"></ng-template>\n </ng-container>\n }\n </div>\n</div>\n", styles: [".mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{list-style:none;margin:0;padding:0}.mc-markdown-render ::ng-deep ul{list-style-type:disc;padding-left:16px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep p{line-height:28px;margin:0;padding:0;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:underline;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}.mc-code-block-light ::ng-deep pre code.hljs{display:block;overflow-x:auto;padding:1em}.mc-code-block-light ::ng-deep code.hljs{padding:3px 5px}.mc-code-block-light ::ng-deep .hljs{background:#fefefe;color:#545454}.mc-code-block-light ::ng-deep .hljs-comment,.mc-code-block-light ::ng-deep .hljs-quote{color:#696969}.mc-code-block-light ::ng-deep .hljs-variable,.mc-code-block-light ::ng-deep .hljs-template-variable,.mc-code-block-light ::ng-deep .hljs-tag,.mc-code-block-light ::ng-deep .hljs-name,.mc-code-block-light ::ng-deep .hljs-selector-id,.mc-code-block-light ::ng-deep .hljs-selector-class,.mc-code-block-light ::ng-deep .hljs-regexp,.mc-code-block-light ::ng-deep .hljs-deletion{color:#d91e18}.mc-code-block-light ::ng-deep .hljs-number,.mc-code-block-light ::ng-deep .hljs-built_in,.mc-code-block-light ::ng-deep .hljs-literal,.mc-code-block-light ::ng-deep .hljs-type,.mc-code-block-light ::ng-deep .hljs-params,.mc-code-block-light ::ng-deep .hljs-meta,.mc-code-block-light ::ng-deep .hljs-link{color:#aa5d00}.mc-code-block-light ::ng-deep .hljs-attribute{color:#aa5d00}.mc-code-block-light ::ng-deep .hljs-string,.mc-code-block-light ::ng-deep .hljs-symbol,.mc-code-block-light ::ng-deep .hljs-bullet,.mc-code-block-light ::ng-deep .hljs-addition{color:green}.mc-code-block-light ::ng-deep .hljs-title,.mc-code-block-light ::ng-deep .hljs-section{color:#007faa}.mc-code-block-light ::ng-deep .hljs-keyword,.mc-code-block-light ::ng-deep .hljs-selector-tag{color:#7928a1}.mc-code-block-light ::ng-deep .hljs-emphasis{font-style:italic}.mc-code-block-light ::ng-deep .hljs-strong{font-weight:700}@media screen and (-ms-high-contrast: active){.mc-code-block-light ::ng-deep .hljs-addition,.mc-code-block-light ::ng-deep .hljs-attribute,.mc-code-block-light ::ng-deep .hljs-built_in,.mc-code-block-light ::ng-deep .hljs-bullet,.mc-code-block-light ::ng-deep .hljs-comment,.mc-code-block-light ::ng-deep .hljs-link,.mc-code-block-light ::ng-deep .hljs-literal,.mc-code-block-light ::ng-deep .hljs-meta,.mc-code-block-light ::ng-deep .hljs-number,.mc-code-block-light ::ng-deep .hljs-params,.mc-code-block-light ::ng-deep .hljs-string,.mc-code-block-light ::ng-deep .hljs-symbol,.mc-code-block-light ::ng-deep .hljs-type,.mc-code-block-light ::ng-deep .hljs-quote{color:highlight}.mc-code-block-light ::ng-deep .hljs-keyword,.mc-code-block-light ::ng-deep .hljs-selector-tag{font-weight:700}}.mc-code-block-light{border:1px solid #d7d8da}.mc-code-block-light code.hljs{padding:1em}.mc-code-block-light{background-color:#f5f5f5}.mc-code-block-light .mc-code-lang,.mc-code-block-light .mc-code-block-actions .mc-copy-btn,.mc-code-block-light .mc-code-block-actions .mc-toggle-btn{color:#252b3a}.mc-code-block-light .mc-code-block-actions .mc-copy-btn:hover,.mc-code-block-light .mc-code-block-actions .mc-toggle-btn:hover{background-color:#ebebeb}.mc-code-block-light .mc-mermaid-content{background:#fefefe}.mc-code-block-dark ::ng-deep pre code.hljs{display:block;overflow-x:auto;padding:1em}.mc-code-block-dark ::ng-deep code.hljs{padding:3px 5px}.mc-code-block-dark ::ng-deep .hljs{background:#2b2b2b;color:#f8f8f2}.mc-code-block-dark ::ng-deep .hljs-comment,.mc-code-block-dark ::ng-deep .hljs-quote{color:#d4d0ab}.mc-code-block-dark ::ng-deep .hljs-variable,.mc-code-block-dark ::ng-deep .hljs-template-variable,.mc-code-block-dark ::ng-deep .hljs-tag,.mc-code-block-dark ::ng-deep .hljs-name,.mc-code-block-dark ::ng-deep .hljs-selector-id,.mc-code-block-dark ::ng-deep .hljs-selector-class,.mc-code-block-dark ::ng-deep .hljs-regexp,.mc-code-block-dark ::ng-deep .hljs-deletion{color:#ffa07a}.mc-code-block-dark ::ng-deep .hljs-number,.mc-code-block-dark ::ng-deep .hljs-built_in,.mc-code-block-dark ::ng-deep .hljs-literal,.mc-code-block-dark ::ng-deep .hljs-type,.mc-code-block-dark ::ng-deep .hljs-params,.mc-code-block-dark ::ng-deep .hljs-meta,.mc-code-block-dark ::ng-deep .hljs-link{color:#f5ab35}.mc-code-block-dark ::ng-deep .hljs-attribute{color:gold}.mc-code-block-dark ::ng-deep .hljs-string,.mc-code-block-dark ::ng-deep .hljs-symbol,.mc-code-block-dark ::ng-deep .hljs-bullet,.mc-code-block-dark ::ng-deep .hljs-addition{color:#abe338}.mc-code-block-dark ::ng-deep .hljs-title,.mc-code-block-dark ::ng-deep .hljs-section{color:#00e0e0}.mc-code-block-dark ::ng-deep .hljs-keyword,.mc-code-block-dark ::ng-deep .hljs-selector-tag{color:#dcc6e0}.mc-code-block-dark ::ng-deep .hljs-emphasis{font-style:italic}.mc-code-block-dark ::ng-deep .hljs-strong{font-weight:700}@media screen and (-ms-high-contrast: active){.mc-code-block-dark ::ng-deep .hljs-addition,.mc-code-block-dark ::ng-deep .hljs-attribute,.mc-code-block-dark ::ng-deep .hljs-built_in,.mc-code-block-dark ::ng-deep .hljs-bullet,.mc-code-block-dark ::ng-deep .hljs-comment,.mc-code-block-dark ::ng-deep .hljs-link,.mc-code-block-dark ::ng-deep .hljs-literal,.mc-code-block-dark ::ng-deep .hljs-meta,.mc-code-block-dark ::ng-deep .hljs-number,.mc-code-block-dark ::ng-deep .hljs-params,.mc-code-block-dark ::ng-deep .hljs-string,.mc-code-block-dark ::ng-deep .hljs-symbol,.mc-code-block-dark ::ng-deep .hljs-type,.mc-code-block-dark ::ng-deep .hljs-quote{color:highlight}.mc-code-block-dark ::ng-deep .hljs-keyword,.mc-code-block-dark ::ng-deep .hljs-selector-tag{font-weight:700}}.mc-code-block-dark{border:1px solid #4e5057}.mc-code-block-dark code.hljs{padding:1em}.mc-code-block-dark{background-color:#34363a}.mc-code-block-dark .mc-code-lang,.mc-code-block-dark .mc-code-block-actions .mc-copy-btn,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn{color:#ced1db}.mc-code-block-dark .mc-code-block-actions .mc-copy-btn:hover,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn:hover{background-color:#393a3e}.mc-code-block-dark .mc-code-block-actions .mc-copy-btn img,.mc-code-block-dark .mc-code-block-actions .mc-toggle-btn img{filter:brightness(1.5)}.mc-code-block-dark .mc-mermaid-content{background:#2b2b2b!important}@keyframes collapse-expand{0%{opacity:0;max-height:0}to{opacity:1;max-height:1000px}}@keyframes collapse-collapse{0%{opacity:1;max-height:1000px}to{opacity:0;max-height:0}}.mc-block-hidden{display:none}.collapse-expanded{animation:collapse-expand .5s ease-out}.collapse-collapsed{animation:collapse-collapse .5s ease-in}.mc-code-block{margin:1rem 0;overflow:hidden;border-radius:14px}.mc-code-block pre{margin:0}.mc-code-block .mc-action-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;box-sizing:border-box}.mc-code-block .mc-code-block-header{display:flex;justify-content:space-between;align-items:center;padding:.5rem 1rem}.mc-code-block .mc-code-block-header .mc-code-lang{font-size:14px}.mc-code-block .mc-mermaid-content{position:relative;width:100%;height:400px;overflow:hidden;background:inherit}.mc-code-block .mc-code-block-actions{display:flex;align-items:center}.mc-code-block .mc-code-block-actions .mc-copy-btn,.mc-code-block .mc-code-block-actions .mc-toggle-btn{cursor:pointer;border-radius:4px;font-size:18px;padding:4px}.mc-code-block .mc-diagram-switch{display:flex;align-items:center;list-style:none;margin:0;padding:2px;border-radius:4px;background-color:var(--devui-icon-hover-bg);position:relative;transition:all .3s ease;overflow:hidden;height:24px}.mc-code-block .mc-diagram-switch:before{content:\"\";position:absolute;top:2px;left:2px;width:calc(50% - 2px);height:calc(100% - 4px);background-color:var(--devui-base-bg);border-radius:4px;transition:transform .3s ease;box-shadow:0 1px 2px #0000001a;z-index:1}.mc-code-block .mc-diagram-switch.mc-show-code:before{transform:translate(100%)}.mc-code-block .mc-diagram-switch .mc-diagram-switch-active{text-shadow:0 0 .4px #252b3a}.mc-code-block .mc-diagram-switch li{position:relative;padding:0 8px;margin:0;font-size:12px;cursor:pointer;transition:color .3s ease;z-index:2}\n"] }]
1721
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { code: [{
1722
+ type: Input
1723
+ }], language: [{
1724
+ type: Input
1725
+ }], blockIndex: [{
1726
+ type: Input
1727
+ }], theme: [{
1728
+ type: Input
1729
+ }], enableMermaid: [{
1730
+ type: Input
1731
+ }], mermaidConfig: [{
1732
+ type: Input
1733
+ }], contentTemplate: [{
1734
+ type: Input
1735
+ }], headerTemplate: [{
1736
+ type: Input
1737
+ }], actionsTemplate: [{
1738
+ type: Input
1739
+ }], rootRef: [{
1740
+ type: ViewChild,
1741
+ args: ['rootRef']
1742
+ }], mermaidContentRef: [{
1743
+ type: ViewChild,
1744
+ args: ['mermaidContent']
1745
+ }] } });
1746
+
1747
+ const defaultTypingConfig = {
1748
+ step: 2,
1749
+ interval: 50,
1750
+ style: 'normal',
1751
+ };
1752
+
1753
+ class MarkdownCardFoundation extends BaseFoundation {
1754
+ constructor(adapter) {
1755
+ super({ ...adapter });
1756
+ this.isToken = (node) => {
1757
+ return 'type' in node && 'content' in node;
1758
+ };
1759
+ this.typewriterEnd = () => {
1760
+ this.setState({ isTyping: false });
1761
+ this._adapter.typingEnd?.();
1762
+ };
1763
+ this.getThinkContent = (content, thinkOptions) => {
1764
+ const thinkClass = thinkOptions?.customClass || 'mc-think-block';
1765
+ return (content
1766
+ ?.replace('<think>', `<div class="${thinkClass}">`)
1767
+ ?.replace('</think>', '</div>') || '');
1768
+ };
1769
+ this.parseTypingContent = (content) => {
1770
+ const { typingOptions } = this.getProps();
1771
+ const { typingIndex } = this.getStates();
1772
+ content = content.slice(0, typingIndex) || '';
1773
+ const options = { ...defaultTypingConfig, ...typingOptions };
1774
+ if (options.style === 'cursor') {
1775
+ content += `<span class="mc-typewriter mc-typewriter-cursor">|</span>`;
1776
+ }
1777
+ else if (options.style === 'color' || options.style === 'gradient') {
1778
+ content =
1779
+ content.slice(0, -5) +
1780
+ `<span class="mc-typewriter mc-typewriter-${options.style}">${content.slice(-5)}</span>`;
1781
+ }
1782
+ return content || '';
1783
+ };
1784
+ this.parseContent = () => {
1785
+ const { content, thinkOptions, enableThink } = this.getProps();
1786
+ const { typing, isTyping } = this.getStates();
1787
+ let parseContent = content || '';
1788
+ if (typing && isTyping) {
1789
+ parseContent = this.parseTypingContent(content);
1790
+ }
1791
+ if (enableThink) {
1792
+ parseContent = this.getThinkContent(content, thinkOptions);
1793
+ }
1794
+ parseContent = this._adapter.parseContent(parseContent);
1795
+ };
1796
+ this.typewriterStart = () => {
1797
+ const { typingOptions } = this.getProps();
1798
+ const { timer } = this.getStates();
1799
+ if (timer) {
1800
+ clearTimeout(timer);
1801
+ }
1802
+ this.setState({ isTyping: true });
1803
+ this._adapter.typingStart?.();
1804
+ const options = { ...defaultTypingConfig, ...typingOptions };
1805
+ const typingStep = () => {
1806
+ const { typingIndex, content } = this.getStates();
1807
+ let step = options.step || 2;
1808
+ if (Array.isArray(options.step)) {
1809
+ step =
1810
+ options.step[0] +
1811
+ Math.floor(Math.random() * (options.step[1] - options.step[0]));
1812
+ }
1813
+ let index = typingIndex + step;
1814
+ this.setState({ typingIndex: index });
1815
+ this.parseContent();
1816
+ this._adapter.typingEvent();
1817
+ if (index >= content.length) {
1818
+ this.typewriterEnd();
1819
+ this.parseContent();
1820
+ return;
1821
+ }
1822
+ let typingTimeout = setTimeout(typingStep, typeof options.interval === 'number' ? options.interval : 50);
1823
+ this.setState({
1824
+ timer: typingTimeout,
1825
+ });
1826
+ };
1827
+ let typingStepTimeout = setTimeout(typingStep);
1828
+ this.setState({
1829
+ timer: typingStepTimeout,
1830
+ });
1831
+ };
1832
+ }
1833
+ }
1834
+
1835
+ // 判断是否自闭合标签
1836
+ const isSelfClosingTag = (token) => {
1837
+ // 判断token.content里面是否包含完整的HTML结构(所有开始标签都有对应的结束标签)
1838
+ const content = token.content || '';
1839
+ // 检查是否是自闭合标签(如 <img />, <br /> 等)
1840
+ if (content.match(/<(\w+)[^>]*\/>/)) {
1841
+ return true;
1842
+ }
1843
+ // 检查是否包含完整的HTML结构
1844
+ const tagStack = [];
1845
+ const openTagRegex = /<(\w+)[^>]*>/g;
1846
+ const closeTagRegex = /<\/(\w+)>/g;
1847
+ let openMatch;
1848
+ let closeMatch;
1849
+ // 重置正则表达式的lastIndex
1850
+ openTagRegex.lastIndex = 0;
1851
+ closeTagRegex.lastIndex = 0;
1852
+ // 按顺序处理所有标签
1853
+ const allMatches = [];
1854
+ // 收集所有开始标签
1855
+ while ((openMatch = openTagRegex.exec(content)) !== null) {
1856
+ allMatches.push({
1857
+ type: 'open',
1858
+ tagName: openMatch[1],
1859
+ index: openMatch.index
1860
+ });
1861
+ }
1862
+ // 收集所有结束标签
1863
+ while ((closeMatch = closeTagRegex.exec(content)) !== null) {
1864
+ allMatches.push({
1865
+ type: 'close',
1866
+ tagName: closeMatch[1],
1867
+ index: closeMatch.index
1868
+ });
1869
+ }
1870
+ // 按位置排序
1871
+ allMatches.sort((a, b) => a.index - b.index);
1872
+ // 检查标签是否完全匹配
1873
+ for (const match of allMatches) {
1874
+ if (match.type === 'open') {
1875
+ tagStack.push(match.tagName);
1876
+ }
1877
+ else {
1878
+ if (tagStack.length === 0) {
1879
+ return false; // 没有对应的开始标签
1880
+ }
1881
+ const lastOpenTag = tagStack[tagStack.length - 1];
1882
+ if (lastOpenTag !== match.tagName) {
1883
+ return false; // 标签不匹配
1884
+ }
1885
+ tagStack.pop();
1886
+ }
1887
+ }
1888
+ // 只有当所有标签都正确匹配时,才认为是自闭合的
1889
+ return tagStack.length === 0;
1890
+ };
1891
+ // 判断是否是结束标签
1892
+ const isClosingTag = (openToken, closeToken) => {
1893
+ const openContent = openToken?.content || '';
1894
+ const closeContent = closeToken?.content || '';
1895
+ const openTagMatch = openContent.match(/<(\w+)/);
1896
+ const closeTagMatch = closeContent.match(/<\/(\w+)/);
1897
+ if (openTagMatch && closeTagMatch) {
1898
+ return openTagMatch[1] === closeTagMatch[1];
1899
+ }
1900
+ return false;
1901
+ };
1902
+ // 创建ast树节点
1903
+ const genTreeNode = (node) => {
1904
+ return {
1905
+ nodeType: node ? node.type.replace('_open', '') : 'root',
1906
+ openNode: node,
1907
+ closeNode: null,
1908
+ children: [],
1909
+ vNodeKey: node?.vNodeKey || ''
1910
+ };
1911
+ };
1912
+ // 匹配成对html token
1913
+ const matchHtmlToken = (token, stack) => {
1914
+ // 简单排除单独的闭合标签
1915
+ const isCloseTag = token.content.startsWith('</');
1916
+ if (!stack.length) {
1917
+ token.nesting = isCloseTag ? 0 : 1;
1918
+ stack.push(token);
1919
+ return;
1920
+ }
1921
+ // 判断当前token是否是上一个html token的闭合标签
1922
+ const prevToken = stack[stack.length - 1];
1923
+ const closing = isClosingTag(prevToken, token);
1924
+ if (closing) {
1925
+ token.nesting = -1;
1926
+ stack.pop();
1927
+ }
1928
+ else {
1929
+ if (isCloseTag) {
1930
+ token.nesting = 0;
1931
+ }
1932
+ else {
1933
+ token.nesting = 1;
1934
+ stack.push(token);
1935
+ }
1936
+ }
1937
+ };
1938
+ const isValidTagName = (tagName) => {
1939
+ if (!tagName)
1940
+ return false;
1941
+ try {
1942
+ document.createElement(tagName);
1943
+ return true;
1944
+ }
1945
+ catch (error) {
1946
+ return false;
1947
+ }
1948
+ };
1949
+ const tokensToAst = (tokens) => {
1950
+ // 递归处理 inline 类型的 token
1951
+ const processInlineToken = (token) => {
1952
+ const node = genTreeNode(token);
1953
+ // 如果 token 有 children,递归处理它们
1954
+ if (token.children && token.children.length > 0) {
1955
+ node.children = tokensToAst(token.children);
1956
+ }
1957
+ return node;
1958
+ };
1959
+ // 创建根节点
1960
+ const rootNode = genTreeNode(null);
1961
+ let curr = rootNode;
1962
+ const stack = [];
1963
+ const htmlInlineTokenStack = [];
1964
+ const htmlBlockTokenStack = [];
1965
+ // 处理html token nesting值
1966
+ tokens.forEach((tok, idx) => {
1967
+ tok.vNodeKey = `mc-markdown-content-key-${idx}`;
1968
+ tok.tokenIndex = idx;
1969
+ if (tok.type.includes('html_')) {
1970
+ if (isSelfClosingTag(tok)) {
1971
+ tok.nesting = 0;
1972
+ return;
1973
+ }
1974
+ const stack = tok.type === 'html_block'
1975
+ ? htmlBlockTokenStack
1976
+ : htmlInlineTokenStack;
1977
+ matchHtmlToken(tok, stack);
1978
+ }
1979
+ });
1980
+ tokens.forEach((tok, idx) => {
1981
+ let tmp;
1982
+ if (tok.nesting === 1) {
1983
+ // 开始标签
1984
+ tmp = genTreeNode(tok);
1985
+ curr.children.push(tmp);
1986
+ stack.push(curr);
1987
+ curr = tmp;
1988
+ }
1989
+ else if (tok.nesting === -1) {
1990
+ // 结束标签
1991
+ curr.closeNode = tok;
1992
+ if (!stack.length) {
1993
+ throw new Error('AST stack underflow.');
1994
+ }
1995
+ tmp = stack.pop();
1996
+ curr = tmp;
1997
+ }
1998
+ else if (tok.nesting === 0) {
1999
+ // 自闭合标签或 inline 内容
2000
+ if (tok.type === 'inline' && tok.children && tok.children.length > 0) {
2001
+ // 对于 inline 类型,递归处理其 children
2002
+ const inlineNode = processInlineToken(tok);
2003
+ curr.children.push(inlineNode);
2004
+ }
2005
+ else {
2006
+ // 普通 token,直接添加
2007
+ curr.children.push(tok);
2008
+ }
2009
+ }
2010
+ else {
2011
+ throw new Error(`Invalid nesting level found in token index ${idx}.`);
2012
+ }
2013
+ });
2014
+ if (stack.length !== 0) {
2015
+ // throw new Error('Unbalanced block open/close tokens.');
2016
+ }
2017
+ return rootNode.children;
2018
+ };
2019
+ // 声明一个utils静态默认导出
2020
+ var MdParserUtils = {
2021
+ isSelfClosingTag,
2022
+ isClosingTag,
2023
+ tokensToAst,
2024
+ genTreeNode,
2025
+ matchHtmlToken,
2026
+ isValidTagName
2027
+ };
2028
+
2029
+ class MarkdownCardComponent extends BaseComponent {
2030
+ constructor(resolver, renderer, cdr) {
2031
+ super();
2032
+ this.resolver = resolver;
2033
+ this.renderer = renderer;
2034
+ this.cdr = cdr;
2035
+ this.content = '';
2036
+ this.typing = false;
2037
+ this.enableThink = false;
2038
+ this.typingOptions = {};
2039
+ this.thinkOptions = {};
2040
+ this.mdOptions = {};
2041
+ this.mdPlugins = [];
2042
+ this.customXssRules = [];
2043
+ this.theme = 'light';
2044
+ this.enableMermaid = false;
2045
+ this.mermaidConfig = {};
2046
+ this.actionsTemplate = null;
2047
+ this.headerTemplate = null;
2048
+ this.contentTemplate = null;
2049
+ // 组件缓存映射表,用于存储已创建的CodeBlockComponent实例
2050
+ this.codeBlockComponentsCache = new Map();
2051
+ this.afterMdtInit = new EventEmitter();
2052
+ this.typingStart = new EventEmitter();
2053
+ this.typingEvent = new EventEmitter();
2054
+ this.typingEnd = new EventEmitter();
2055
+ this.typingIndex = 0;
2056
+ this.isTyping = false;
2057
+ this.timer = null;
2058
+ this.parser = MdParserUtils;
2059
+ this.mdt = markdownit({
2060
+ breaks: true,
2061
+ linkify: true,
2062
+ html: true,
2063
+ highlight: (str, lang) => {
2064
+ // 与Vue组件保持一致的高亮处理
2065
+ return '';
2066
+ },
2067
+ ...this.mdOptions,
2068
+ });
2069
+ this.mdCardService = new MDCardService();
2070
+ this.foundation = new MarkdownCardFoundation(this.adapter);
2071
+ // 初始化 diffDom 实例
2072
+ this.diffDom = new DiffDOM({
2073
+ // 配置filterOuterDiff钩子,识别code-block-wrapper元素并直接替换
2074
+ filterOuterDiff: (t1, t2, diffs) => {
2075
+ // 检查是否是class为code-block-wrapper的div元素
2076
+ const isTargetElement = t2.nodeName === 'DIV' &&
2077
+ t2.attributes && t2.attributes.class && t2.attributes.class.includes('code-block-wrapper');
2078
+ if (isTargetElement) {
2079
+ t1.innerDone = true;
2080
+ }
2081
+ }
2082
+ });
2083
+ }
2084
+ ngOnInit() {
2085
+ this.mdCardService.setMdPlugins(this.mdPlugins || [], this.mdt);
2086
+ this.parseContent();
2087
+ this.afterMdtInit.emit(this.mdt);
2088
+ }
2089
+ get adapter() {
2090
+ return {
2091
+ ...super.adapter,
2092
+ locale: (key, params) => this.adapter.locale(key, params),
2093
+ typingStart: () => this.typingStart.emit(),
2094
+ typingEnd: () => this.typingEnd.emit(),
2095
+ typingEvent: () => this.typingEvent.emit(),
2096
+ parseContent: (content) => {
2097
+ // 解析 Markdown 内容
2098
+ const tokens = this.mdt.parse(content, {});
2099
+ const ast = this.parser.tokensToAst(tokens);
2100
+ const vnodes = this.astToVnodes(ast);
2101
+ this.renderContent(vnodes);
2102
+ },
2103
+ };
2104
+ }
2105
+ ngOnChanges(changes) {
2106
+ if (changes['content']) {
2107
+ if (!this.typing) {
2108
+ this.typingIndex = this.content?.length || 0;
2109
+ this.parseContent();
2110
+ return;
2111
+ }
2112
+ if (this.content.indexOf(changes['content']?.previousValue) === -1) {
2113
+ this.typingIndex = 0;
2114
+ }
2115
+ // 使用setTimeout模拟Vue的nextTick行为
2116
+ setTimeout(() => this.typewriterStart());
2117
+ }
2118
+ if (changes['enableThink'] || changes['thinkOptions'] || changes['theme']) {
2119
+ this.parseContent();
2120
+ }
2121
+ if (changes['customXssRules']) {
2122
+ this.mdCardService.setCustomXssRules(this.customXssRules || []);
2123
+ this.parseContent();
2124
+ }
2125
+ if (changes['mdPlugins']) {
2126
+ this.mdCardService.setMdPlugins(this.mdPlugins || [], this.mdt);
2127
+ this.parseContent();
2128
+ }
2129
+ }
2130
+ parseContent() {
2131
+ this.foundation.parseContent(this.content || '');
2132
+ }
2133
+ renderContent(vnodes) {
2134
+ if (!this.markdownContainer ||
2135
+ !this.markdownContainer.element ||
2136
+ !this.markdownContainer.element.nativeElement) {
2137
+ return;
2138
+ }
2139
+ const container = this.markdownContainer.element.nativeElement;
2140
+ // 创建新内容容器
2141
+ const newContent = document.createElement('div');
2142
+ vnodes.forEach((node) => {
2143
+ if (node &&
2144
+ (node.nodeType ||
2145
+ typeof node === 'string' ||
2146
+ node instanceof HTMLElement)) {
2147
+ newContent.appendChild(node);
2148
+ }
2149
+ });
2150
+ // 不适用diff-dom,直接替换内容
2151
+ let noDIff = false;
2152
+ if (noDIff) {
2153
+ while (container.firstChild) {
2154
+ container.removeChild(container.firstChild);
2155
+ }
2156
+ container.appendChild(newContent);
2157
+ return;
2158
+ }
2159
+ let oldNode = container;
2160
+ let newNode = newContent;
2161
+ const patches = this.diffDom.diff(oldNode, newNode);
2162
+ //code-block-wrapper
2163
+ this.diffDom.apply(container, patches);
2164
+ // 从vNodes中找到所有class为code-block-wrapper的div元素
2165
+ const codeBlockWrappers = vnodes.filter((node) => {
2166
+ return node.nodeName === 'DIV' && node.className?.includes('code-block-wrapper');
2167
+ });
2168
+ // 将codeBlockWrappers中的每个div元素替换container中的对应key属性的元素
2169
+ codeBlockWrappers.forEach((newCodeBlock) => {
2170
+ if (newCodeBlock && newCodeBlock.attributes && newCodeBlock.attributes.key) {
2171
+ const key = newCodeBlock.attributes.key.value;
2172
+ // 查找container中对应key的元素
2173
+ const existingElement = container.querySelector(`[key="${key}"]`);
2174
+ if (existingElement && newCodeBlock instanceof HTMLElement) {
2175
+ // 替换元素
2176
+ if (newCodeBlock !== existingElement) {
2177
+ existingElement.parentNode?.replaceChild(newCodeBlock, existingElement);
2178
+ }
2179
+ }
2180
+ }
2181
+ });
2182
+ }
2183
+ astToVnodes(nodes) {
2184
+ return nodes.map((node) => this.processASTNode(node));
2185
+ }
2186
+ processASTNode(node) {
2187
+ if (node.nodeType === 'html_inline' || node.nodeType === 'html_block') {
2188
+ return this.processHTMLNode(node);
2189
+ }
2190
+ if (node.nodeType === 'inline') {
2191
+ return this.processInlineToken(node);
2192
+ }
2193
+ if (this.foundation.isToken(node)) {
2194
+ return this.processToken(node);
2195
+ }
2196
+ return this.processASTNodeInternal(node);
2197
+ }
2198
+ processHTMLNode(node) {
2199
+ if (!node.openNode?.content)
2200
+ return;
2201
+ const container = this.renderer.createElement(node.nodeType === 'html_block' ? 'div' : 'span');
2202
+ this.renderer.setProperty(container, 'innerHTML', node.openNode.content);
2203
+ // 处理子节点
2204
+ if (node.children && node.children.length > 0) {
2205
+ node.children.forEach((child) => {
2206
+ const childVnode = this.processASTNode(child);
2207
+ if (childVnode) {
2208
+ this.renderer.appendChild(container.firstChild || container, childVnode);
2209
+ }
2210
+ });
2211
+ }
2212
+ return container;
2213
+ }
2214
+ processInlineToken(node) {
2215
+ const div = this.renderer.createElement('div');
2216
+ let html = '';
2217
+ try {
2218
+ if (!node.openNode) {
2219
+ return null;
2220
+ }
2221
+ html = this.mdt.renderer.render([node.openNode], this.mdt.options, {});
2222
+ }
2223
+ catch (error) {
2224
+ console.error('Error rendering inline token:', node);
2225
+ return null;
2226
+ }
2227
+ // 将HTML字符串转换为DOM节点
2228
+ this.renderer.setProperty(div, 'innerHTML', html);
2229
+ // 如果只有一个子节点,直接返回子节点而不是包含div
2230
+ if (div.firstChild && div.childNodes.length === 1) {
2231
+ return div.firstChild;
2232
+ }
2233
+ return div;
2234
+ }
2235
+ processFenceNode(token) {
2236
+ const language = token.info?.replace(/<span\b[^>]*>/i, '').replace('</span>', '') || '';
2237
+ const code = token.content || '';
2238
+ return this.createCodeBlock(language, code, token.tokenIndex || 0);
2239
+ }
2240
+ processASTNodeInternal(node) {
2241
+ let tagName = 'div';
2242
+ if (node.openNode?.tag && this.parser.isValidTagName(node.openNode?.tag)) {
2243
+ tagName = node.openNode?.tag;
2244
+ }
2245
+ const element = this.renderer.createElement(tagName);
2246
+ // 设置属性
2247
+ if (node.openNode.attrs) {
2248
+ node.openNode.attrs.forEach(([key, value]) => {
2249
+ this.renderer.setAttribute(element, key, value);
2250
+ });
2251
+ }
2252
+ // 特殊处理fence类型的token
2253
+ if (node.openNode.type === 'fence') {
2254
+ return this.processFenceNode(node.openNode);
2255
+ }
2256
+ // 处理所有带tag的AST节点
2257
+ if (node.openNode?.tag) {
2258
+ let tagName = this.parser.isValidTagName(node.openNode?.tag)
2259
+ ? node.openNode?.tag
2260
+ : 'div';
2261
+ const element = this.renderer.createElement(tagName);
2262
+ // 递归处理所有子节点并添加到当前元素
2263
+ node.children.forEach((child) => {
2264
+ const childNode = this.processASTNode(child);
2265
+ if (childNode) {
2266
+ this.renderer.appendChild(element, childNode);
2267
+ }
2268
+ });
2269
+ return element;
2270
+ }
2271
+ node.children.forEach((child) => {
2272
+ const childNode = this.processASTNode(child);
2273
+ if (childNode) {
2274
+ this.renderer.appendChild(element, childNode);
2275
+ }
2276
+ });
2277
+ return element;
2278
+ }
2279
+ processToken(token) {
2280
+ if (token.type === 'text') {
2281
+ return this.renderer.createText(token.content || '');
2282
+ }
2283
+ if (token.type === 'inline') {
2284
+ return this.processInlineToken(token);
2285
+ }
2286
+ if (token.type === 'fence') {
2287
+ return this.processFenceNode(token);
2288
+ }
2289
+ if (token.type === 'softbreak') {
2290
+ if (this.mdt.options.breaks) {
2291
+ return this.renderer.createElement('br');
2292
+ }
2293
+ else {
2294
+ return this.renderer.createText('\n');
2295
+ }
2296
+ }
2297
+ if (token.type === 'html_block' || token.type === 'html_inline') {
2298
+ const htmlContainer = this.renderer.createElement(token.type === 'html_block' ? 'div' : 'span');
2299
+ this.renderer.setProperty(htmlContainer, 'innerHTML', token.content || '');
2300
+ return htmlContainer;
2301
+ }
2302
+ if (token.tag) {
2303
+ const tagName = this.parser.isValidTagName(token.tag) ? token.tag : 'div';
2304
+ const element = this.renderer.createElement(tagName);
2305
+ if (token.attrs) {
2306
+ token.attrs.forEach(([key, value]) => {
2307
+ this.renderer.setAttribute(element, key, value);
2308
+ });
2309
+ }
2310
+ // 设置内容
2311
+ if (token.content) {
2312
+ const textNode = this.renderer.createText(token.content);
2313
+ this.renderer.appendChild(element, textNode);
2314
+ }
2315
+ return element;
2316
+ }
2317
+ return this.renderer.createText(token.content || '');
2318
+ }
2319
+ createCodeBlock(language, code, blockIndex) {
2320
+ const key = `code-block-${blockIndex}`;
2321
+ // 检查缓存中是否已存在相同blockIndex的组件
2322
+ if (this.codeBlockComponentsCache.has(key)) {
2323
+ const cachedItem = this.codeBlockComponentsCache.get(key);
2324
+ if (cachedItem) {
2325
+ // 更新现有组件的属性
2326
+ const componentRef = cachedItem.componentRef;
2327
+ componentRef.setInput('language', language);
2328
+ componentRef.setInput('code', code);
2329
+ componentRef.setInput('theme', this.theme);
2330
+ // 触发变更检测
2331
+ componentRef.changeDetectorRef.detectChanges();
2332
+ // 返回缓存的容器,无需重新创建
2333
+ return cachedItem.container;
2334
+ }
2335
+ }
2336
+ // 缓存中不存在,创建新组件
2337
+ const codeBlockContainer = this.renderer.createElement('div');
2338
+ this.renderer.setAttribute(codeBlockContainer, 'key', key);
2339
+ const componentRef = this.markdownContainer.createComponent(CodeBlockComponent, {
2340
+ projectableNodes: [],
2341
+ injector: this.markdownContainer.injector,
2342
+ });
2343
+ // 设置组件属性
2344
+ componentRef.instance.language = language;
2345
+ componentRef.instance.code = code;
2346
+ componentRef.instance.blockIndex = blockIndex;
2347
+ componentRef.instance.theme = this.theme;
2348
+ componentRef.instance.enableMermaid = this.enableMermaid;
2349
+ componentRef.instance.mermaidConfig = this.mermaidConfig || {};
2350
+ componentRef.instance.actionsTemplate = this.actionsTemplate;
2351
+ componentRef.instance.headerTemplate = this.headerTemplate;
2352
+ componentRef.instance.contentTemplate = this.contentTemplate;
2353
+ // 触发变更检测
2354
+ componentRef.changeDetectorRef.detectChanges();
2355
+ // 将组件的DOM元素附加到容器中
2356
+ this.renderer.appendChild(codeBlockContainer, componentRef.location.nativeElement);
2357
+ // 添加样式类
2358
+ this.renderer.addClass(codeBlockContainer, 'code-block-wrapper');
2359
+ // 缓存组件实例和容器
2360
+ this.codeBlockComponentsCache.set(key, {
2361
+ componentRef: componentRef,
2362
+ container: codeBlockContainer
2363
+ });
2364
+ // 返回创建的DOM容器
2365
+ return codeBlockContainer;
2366
+ }
2367
+ typewriterStart() {
2368
+ this.foundation.typewriterStart();
2369
+ }
2370
+ // 在组件销毁时清理缓存,避免内存泄漏
2371
+ ngOnDestroy() {
2372
+ // 销毁所有缓存的组件实例
2373
+ this.codeBlockComponentsCache.forEach((cachedItem) => {
2374
+ cachedItem.componentRef.destroy();
2375
+ });
2376
+ this.codeBlockComponentsCache.clear();
2377
+ }
2378
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardComponent, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2379
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.0", type: MarkdownCardComponent, selector: "mc-markdown-card", inputs: { content: "content", typing: "typing", enableThink: "enableThink", typingOptions: "typingOptions", thinkOptions: "thinkOptions", mdOptions: "mdOptions", mdPlugins: "mdPlugins", customXssRules: "customXssRules", theme: "theme", enableMermaid: "enableMermaid", mermaidConfig: "mermaidConfig", actionsTemplate: "actionsTemplate", headerTemplate: "headerTemplate", contentTemplate: "contentTemplate" }, outputs: { afterMdtInit: "afterMdtInit", typingStart: "typingStart", typingEvent: "typingEvent", typingEnd: "typingEnd" }, viewQueries: [{ propertyName: "markdownContainer", first: true, predicate: ["markdownContainer"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mc-markdown-render\" [ngClass]=\"theme === 'dark' ? 'mc-markdown-render-dark' : 'mc-markdown-render-light'\">\n <div #markdownContainer></div>\n</div>\n<ng-content></ng-content>", styles: [".mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{list-style:none;margin:0;padding:0}.mc-markdown-render ::ng-deep ul{list-style-type:disc;padding-left:16px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep p{line-height:28px;margin:0;padding:0;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:underline;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
2380
+ }
2381
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardComponent, decorators: [{
2382
+ type: Component,
2383
+ args: [{ selector: 'mc-markdown-card', template: "<div class=\"mc-markdown-render\" [ngClass]=\"theme === 'dark' ? 'mc-markdown-render-dark' : 'mc-markdown-render-light'\">\n <div #markdownContainer></div>\n</div>\n<ng-content></ng-content>", styles: [".mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{list-style:none;margin:0;padding:0}.mc-markdown-render ::ng-deep ul{list-style-type:disc;padding-left:16px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep p{line-height:28px;margin:0;padding:0;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:underline;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"] }]
2384
+ }], ctorParameters: () => [{ type: i0.ComponentFactoryResolver }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
2385
+ type: Input
2386
+ }], typing: [{
2387
+ type: Input
2388
+ }], enableThink: [{
2389
+ type: Input
2390
+ }], typingOptions: [{
2391
+ type: Input
2392
+ }], thinkOptions: [{
2393
+ type: Input
2394
+ }], mdOptions: [{
2395
+ type: Input
2396
+ }], mdPlugins: [{
2397
+ type: Input
2398
+ }], customXssRules: [{
2399
+ type: Input
2400
+ }], theme: [{
2401
+ type: Input
2402
+ }], enableMermaid: [{
2403
+ type: Input
2404
+ }], mermaidConfig: [{
2405
+ type: Input
2406
+ }], actionsTemplate: [{
2407
+ type: Input
2408
+ }], headerTemplate: [{
2409
+ type: Input
2410
+ }], contentTemplate: [{
2411
+ type: Input
2412
+ }], afterMdtInit: [{
2413
+ type: Output
2414
+ }], typingStart: [{
2415
+ type: Output
2416
+ }], typingEvent: [{
2417
+ type: Output
2418
+ }], typingEnd: [{
2419
+ type: Output
2420
+ }], markdownContainer: [{
2421
+ type: ViewChild,
2422
+ args: ['markdownContainer', { read: ViewContainerRef, static: true }]
2423
+ }] } });
2424
+
2425
+ class MarkdownCardModule {
2426
+ static forRoot() {
2427
+ return {
2428
+ ngModule: MarkdownCardModule,
2429
+ providers: []
2430
+ };
2431
+ }
2432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2433
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardModule, declarations: [MarkdownCardComponent,
2434
+ CodeBlockComponent], imports: [CommonModule,
2435
+ TranslatePipe,
2436
+ LocaleModule], exports: [MarkdownCardComponent,
2437
+ CodeBlockComponent] }); }
2438
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardModule, imports: [CommonModule,
2439
+ LocaleModule] }); }
2440
+ }
2441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImport: i0, type: MarkdownCardModule, decorators: [{
2442
+ type: NgModule,
2443
+ args: [{
2444
+ declarations: [
2445
+ MarkdownCardComponent,
2446
+ CodeBlockComponent
2447
+ ],
2448
+ imports: [
2449
+ CommonModule,
2450
+ TranslatePipe,
2451
+ LocaleModule,
2452
+ ],
2453
+ exports: [
2454
+ MarkdownCardComponent,
2455
+ CodeBlockComponent
2456
+ ],
2457
+ providers: [],
2458
+ bootstrap: []
2459
+ }]
2460
+ }] });
2461
+
1018
2462
  /*
1019
2463
  * Public API Surface of components-ng
1020
2464
  */
@@ -1023,5 +2467,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.0", ngImpor
1023
2467
  * Generated bundle index. Do not edit.
1024
2468
  */
1025
2469
 
1026
- export { AvatarBodyIconComponent, AvatarComponent, AvatarNoBodyIconComponent, BubbleComponent, BubbleLoadingComponent, BubbleModule, InputComponent, InputModule, LocaleModule, LocaleService, TranslatePipe, inputContextToken };
2470
+ export { AvatarBodyIconComponent, AvatarComponent, AvatarNoBodyIconComponent, BubbleComponent, BubbleLoadingComponent, BubbleModule, CodeBlockComponent, InputComponent, InputModule, LocaleModule, LocaleService, MarkdownCardComponent, MarkdownCardModule, TranslatePipe, inputContextToken };
1027
2471
  //# sourceMappingURL=matechat-ng.mjs.map