markstream-vue2 0.0.26 → 0.0.28

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 (139) hide show
  1. package/README.md +8 -0
  2. package/dist/chunks/{cssMode-2e2be6eb.cjs → cssMode-86e8d6e4.cjs} +1 -1
  3. package/dist/chunks/{htmlMode-b62439a8.cjs → htmlMode-f84c7583.cjs} +1 -1
  4. package/dist/chunks/index.legacy-70f0e155.cjs +1 -0
  5. package/dist/chunks/{jsonMode-bb4aa400.cjs → jsonMode-e60229b9.cjs} +1 -1
  6. package/dist/chunks/{tsMode-1535ecd2.cjs → tsMode-5b9a0ba1.cjs} +1 -1
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.css +1 -1
  9. package/dist/index.d.ts +65 -2328
  10. package/dist/index.js +515 -75
  11. package/dist/index.px.css +1 -1
  12. package/dist/index.tailwind.css +1 -1
  13. package/dist/tailwind.ts +1 -1
  14. package/dist/types/components/AdmonitionNode/AdmonitionNode.vue.d.ts +33 -0
  15. package/dist/types/components/AdmonitionNode/index.d.ts +2 -0
  16. package/dist/types/components/BlockquoteNode/BlockquoteNode.vue.d.ts +28 -0
  17. package/dist/types/components/BlockquoteNode/index.d.ts +2 -0
  18. package/dist/types/components/CheckboxNode/CheckboxNode.vue.d.ts +18 -0
  19. package/dist/types/components/CheckboxNode/index.d.ts +2 -0
  20. package/dist/types/components/CodeBlockNode/CodeBlockNode.vue.d.ts +210 -0
  21. package/dist/types/components/CodeBlockNode/HtmlPreviewFrame.vue.d.ts +17 -0
  22. package/dist/types/components/CodeBlockNode/index.d.ts +2 -0
  23. package/dist/types/components/CodeBlockNode/monaco.d.ts +1 -0
  24. package/dist/types/components/CodeBlockNode/monacoThemeScheduler.d.ts +3 -0
  25. package/dist/types/components/D2BlockNode/D2BlockNode.vue.d.ts +66 -0
  26. package/dist/types/components/D2BlockNode/d2.d.ts +6 -0
  27. package/dist/types/components/D2BlockNode/index.d.ts +2 -0
  28. package/dist/types/components/DefinitionListNode/DefinitionListNode.vue.d.ts +36 -0
  29. package/dist/types/components/DefinitionListNode/index.d.ts +2 -0
  30. package/dist/types/components/EmojiNode/EmojiNode.vue.d.ts +19 -0
  31. package/dist/types/components/EmojiNode/index.d.ts +2 -0
  32. package/dist/types/components/EmphasisNode/EmphasisNode.vue.d.ts +25 -0
  33. package/dist/types/components/EmphasisNode/index.d.ts +2 -0
  34. package/dist/types/components/FootnoteAnchorNode/FootnoteAnchorNode.vue.d.ts +18 -0
  35. package/dist/types/components/FootnoteAnchorNode/index.d.ts +2 -0
  36. package/dist/types/components/FootnoteNode/FootnoteNode.vue.d.ts +28 -0
  37. package/dist/types/components/FootnoteNode/index.d.ts +2 -0
  38. package/dist/types/components/FootnoteReferenceNode/FootnoteReferenceNode.vue.d.ts +19 -0
  39. package/dist/types/components/FootnoteReferenceNode/index.d.ts +2 -0
  40. package/dist/types/components/HardBreakNode/HardBreakNode.vue.d.ts +18 -0
  41. package/dist/types/components/HardBreakNode/index.d.ts +2 -0
  42. package/dist/types/components/HeadingNode/HeadingNode.vue.d.ts +28 -0
  43. package/dist/types/components/HeadingNode/index.d.ts +2 -0
  44. package/dist/types/components/HighlightNode/HighlightNode.vue.d.ts +25 -0
  45. package/dist/types/components/HighlightNode/index.d.ts +2 -0
  46. package/dist/types/components/HtmlBlockNode/HtmlBlockNode.vue.d.ts +42 -0
  47. package/dist/types/components/HtmlBlockNode/index.d.ts +2 -0
  48. package/dist/types/components/HtmlInlineNode/HtmlInlineNode.vue.d.ts +21 -0
  49. package/dist/types/components/HtmlInlineNode/index.d.ts +2 -0
  50. package/dist/types/components/ImageNode/ImageNode.vue.d.ts +104 -0
  51. package/dist/types/components/ImageNode/index.d.ts +2 -0
  52. package/dist/types/components/InfographicBlockNode/InfographicBlockNode.vue.d.ts +86 -0
  53. package/dist/types/components/InfographicBlockNode/index.d.ts +2 -0
  54. package/dist/types/components/InfographicBlockNode/infographic.d.ts +1 -0
  55. package/dist/types/components/InlineCodeNode/InlineCodeNode.vue.d.ts +18 -0
  56. package/dist/types/components/InlineCodeNode/index.d.ts +2 -0
  57. package/dist/types/components/InsertNode/InsertNode.vue.d.ts +25 -0
  58. package/dist/types/components/InsertNode/index.d.ts +2 -0
  59. package/dist/types/components/LinkNode/LinkNode.vue.d.ts +49 -0
  60. package/dist/types/components/LinkNode/index.d.ts +2 -0
  61. package/dist/types/components/ListItemNode/ListItemNode.vue.d.ts +30 -0
  62. package/dist/types/components/ListItemNode/index.d.ts +2 -0
  63. package/dist/types/components/ListNode/ListNode.vue.d.ts +36 -0
  64. package/dist/types/components/ListNode/index.d.ts +2 -0
  65. package/dist/types/components/MarkdownCodeBlockNode/MarkdownCodeBlockNode.vue.d.ts +193 -0
  66. package/dist/types/components/MarkdownCodeBlockNode/index.d.ts +2 -0
  67. package/dist/types/components/MarkdownRenderCompat.vue.d.ts +94 -0
  68. package/dist/types/components/MathBlockNode/MathBlockNode.vue.d.ts +20 -0
  69. package/dist/types/components/MathBlockNode/index.d.ts +2 -0
  70. package/dist/types/components/MathInlineNode/MathInlineNode.vue.d.ts +40 -0
  71. package/dist/types/components/MathInlineNode/index.d.ts +2 -0
  72. package/dist/types/components/MathInlineNode/katex.d.ts +6 -0
  73. package/dist/types/components/MermaidBlockNode/MermaidBlockNode.vue.d.ts +134 -0
  74. package/dist/types/components/MermaidBlockNode/index.d.ts +2 -0
  75. package/dist/types/components/MermaidBlockNode/mermaid.d.ts +6 -0
  76. package/dist/types/components/NestedRenderer/NestedRenderer.vue.d.ts +30 -0
  77. package/dist/types/components/NestedRenderer/index.d.ts +2 -0
  78. package/dist/types/components/NodeRenderer/FallbackComponent.vue.d.ts +16 -0
  79. package/dist/types/components/NodeRenderer/LegacyNodesRenderer.vue.d.ts +53 -0
  80. package/dist/types/components/NodeRenderer/NodeRenderer.vue.d.ts +139 -0
  81. package/dist/types/components/NodeRenderer/asyncComponent.d.ts +2 -0
  82. package/dist/types/components/NodeRenderer/index.d.ts +2 -0
  83. package/dist/types/components/NodeRenderer/preloadMonaco.d.ts +1 -0
  84. package/dist/types/components/ParagraphNode/ParagraphNode.vue.d.ts +25 -0
  85. package/dist/types/components/ParagraphNode/index.d.ts +2 -0
  86. package/dist/types/components/Portal/Portal.vue.d.ts +31 -0
  87. package/dist/types/components/Portal/index.d.ts +2 -0
  88. package/dist/types/components/PreCodeNode/PreCodeNode.vue.d.ts +14 -0
  89. package/dist/types/components/PreCodeNode/index.d.ts +2 -0
  90. package/dist/types/components/ReferenceNode/ReferenceNode.vue.d.ts +24 -0
  91. package/dist/types/components/ReferenceNode/index.d.ts +2 -0
  92. package/dist/types/components/StrikethroughNode/StrikethroughNode.vue.d.ts +25 -0
  93. package/dist/types/components/StrikethroughNode/index.d.ts +2 -0
  94. package/dist/types/components/StrongNode/StrongNode.vue.d.ts +25 -0
  95. package/dist/types/components/StrongNode/index.d.ts +2 -0
  96. package/dist/types/components/SubscriptNode/SubscriptNode.vue.d.ts +25 -0
  97. package/dist/types/components/SubscriptNode/index.d.ts +2 -0
  98. package/dist/types/components/SuperscriptNode/SuperscriptNode.vue.d.ts +25 -0
  99. package/dist/types/components/SuperscriptNode/index.d.ts +2 -0
  100. package/dist/types/components/TableNode/TableNode.vue.d.ts +59 -0
  101. package/dist/types/components/TableNode/index.d.ts +2 -0
  102. package/dist/types/components/TextNode/TextNode.vue.d.ts +21 -0
  103. package/dist/types/components/TextNode/index.d.ts +2 -0
  104. package/dist/types/components/TextNode/streamingTextState.d.ts +11 -0
  105. package/dist/types/components/ThematicBreakNode/ThematicBreakNode.vue.d.ts +2 -0
  106. package/dist/types/components/ThematicBreakNode/index.d.ts +2 -0
  107. package/dist/types/components/Tooltip/Tooltip.vue.d.ts +22 -0
  108. package/dist/types/components/Tooltip/index.d.ts +2 -0
  109. package/dist/types/components/VmrContainerNode/VmrContainerNode.vue.d.ts +28 -0
  110. package/dist/types/components/VmrContainerNode/index.d.ts +2 -0
  111. package/dist/types/composables/useKatexReady.d.ts +1 -0
  112. package/dist/types/composables/useSafeI18n.d.ts +10 -0
  113. package/dist/types/composables/useSingletonTooltip.d.ts +14 -0
  114. package/dist/types/composables/viewportPriority.d.ts +20 -0
  115. package/dist/types/exports.d.ts +70 -0
  116. package/dist/types/index.d.ts +2 -0
  117. package/dist/types/tailwind-entry.d.ts +2 -0
  118. package/dist/types/types/component-props.d.ts +210 -0
  119. package/dist/types/types/index.d.ts +271 -0
  120. package/dist/types/utils/htmlRenderer.d.ts +43 -0
  121. package/dist/types/utils/index.d.ts +5 -0
  122. package/dist/types/utils/katex-threshold.d.ts +20 -0
  123. package/dist/types/utils/languageIcon.d.ts +8 -0
  124. package/dist/types/utils/languageIconExtended.d.ts +1 -0
  125. package/dist/types/utils/mathRenderCache.d.ts +7 -0
  126. package/dist/types/utils/nestedHtml.d.ts +19 -0
  127. package/dist/types/utils/nestedNodes.d.ts +14 -0
  128. package/dist/types/utils/nodeComponents.d.ts +20 -0
  129. package/dist/types/utils/performance-monitor.d.ts +121 -0
  130. package/dist/types/utils/safeRaf.d.ts +2 -0
  131. package/dist/types/utils/vue26.d.ts +8 -0
  132. package/dist/types/workers/katexCdnWorker.d.ts +52 -0
  133. package/dist/types/workers/katexRenderer.worker.d.ts +0 -0
  134. package/dist/types/workers/katexWorkerClient.d.ts +48 -0
  135. package/dist/types/workers/mermaidCdnWorker.d.ts +35 -0
  136. package/dist/types/workers/mermaidParser.worker.d.ts +1 -0
  137. package/dist/types/workers/mermaidWorkerClient.d.ts +21 -0
  138. package/package.json +2 -2
  139. package/dist/chunks/index.legacy-bcde4164.cjs +0 -1
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Performance monitoring utility for KaTeX rendering
3
+ * Helps determine if Worker is beneficial in production
4
+ */
5
+ interface RenderMetrics {
6
+ type: 'worker' | 'direct' | 'cache-hit';
7
+ duration: number;
8
+ formulaLength: number;
9
+ timestamp: number;
10
+ success: boolean;
11
+ error?: string;
12
+ }
13
+ declare class PerformanceMonitor {
14
+ private metrics;
15
+ private enabled;
16
+ private maxMetrics;
17
+ enable(): void;
18
+ disable(): void;
19
+ recordRender(metrics: RenderMetrics): void;
20
+ getStats(): {
21
+ totalRenders: number;
22
+ cacheHitRate: number;
23
+ averageWorkerTime: number;
24
+ averageDirectTime: number;
25
+ averageCacheHitTime: number;
26
+ workerSavings: number;
27
+ recommendation: string;
28
+ cacheHits?: undefined;
29
+ workerCalls?: undefined;
30
+ directCalls?: undefined;
31
+ } | {
32
+ totalRenders: number;
33
+ cacheHits: number;
34
+ cacheHitRate: string;
35
+ workerCalls: number;
36
+ directCalls: number;
37
+ averageWorkerTime: string;
38
+ averageDirectTime: string;
39
+ averageCacheHitTime: string;
40
+ workerSavings: string;
41
+ recommendation: string;
42
+ };
43
+ printReport(): {
44
+ totalRenders: number;
45
+ cacheHitRate: number;
46
+ averageWorkerTime: number;
47
+ averageDirectTime: number;
48
+ averageCacheHitTime: number;
49
+ workerSavings: number;
50
+ recommendation: string;
51
+ cacheHits?: undefined;
52
+ workerCalls?: undefined;
53
+ directCalls?: undefined;
54
+ } | {
55
+ totalRenders: number;
56
+ cacheHits: number;
57
+ cacheHitRate: string;
58
+ workerCalls: number;
59
+ directCalls: number;
60
+ averageWorkerTime: string;
61
+ averageDirectTime: string;
62
+ averageCacheHitTime: string;
63
+ workerSavings: string;
64
+ recommendation: string;
65
+ };
66
+ reset(): void;
67
+ exportMetrics(): {
68
+ metrics: RenderMetrics[];
69
+ stats: {
70
+ totalRenders: number;
71
+ cacheHitRate: number;
72
+ averageWorkerTime: number;
73
+ averageDirectTime: number;
74
+ averageCacheHitTime: number;
75
+ workerSavings: number;
76
+ recommendation: string;
77
+ cacheHits?: undefined;
78
+ workerCalls?: undefined;
79
+ directCalls?: undefined;
80
+ } | {
81
+ totalRenders: number;
82
+ cacheHits: number;
83
+ cacheHitRate: string;
84
+ workerCalls: number;
85
+ directCalls: number;
86
+ averageWorkerTime: string;
87
+ averageDirectTime: string;
88
+ averageCacheHitTime: string;
89
+ workerSavings: string;
90
+ recommendation: string;
91
+ };
92
+ timestamp: number;
93
+ };
94
+ }
95
+ export declare const perfMonitor: PerformanceMonitor;
96
+ export declare function enablePerfMonitoring(): void;
97
+ export declare function disablePerfMonitoring(): void;
98
+ export declare function getPerfReport(): {
99
+ totalRenders: number;
100
+ cacheHitRate: number;
101
+ averageWorkerTime: number;
102
+ averageDirectTime: number;
103
+ averageCacheHitTime: number;
104
+ workerSavings: number;
105
+ recommendation: string;
106
+ cacheHits?: undefined;
107
+ workerCalls?: undefined;
108
+ directCalls?: undefined;
109
+ } | {
110
+ totalRenders: number;
111
+ cacheHits: number;
112
+ cacheHitRate: string;
113
+ workerCalls: number;
114
+ directCalls: number;
115
+ averageWorkerTime: string;
116
+ averageDirectTime: string;
117
+ averageCacheHitTime: string;
118
+ workerSavings: string;
119
+ recommendation: string;
120
+ };
121
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare function safeRaf(cb: FrameRequestCallback): any;
2
+ export declare function safeCancelRaf(id: number | null): void;
@@ -0,0 +1,8 @@
1
+ export declare function getVue2MinorVersion(version: unknown): number;
2
+ export declare function isLegacyVue26Version(version: unknown): boolean;
3
+ export declare function resolveVueVersion(input: any): string;
4
+ export declare function isLegacyVue26Vm(input: any): boolean;
5
+ type VueListener = (...args: unknown[]) => unknown;
6
+ type VueListenerValue = VueListener | VueListener[];
7
+ export declare function resolveVueListeners(input: any): Record<string, VueListenerValue>;
8
+ export {};
@@ -0,0 +1,52 @@
1
+ export type KaTeXCDNWorkerMode = 'classic' | 'module';
2
+ export interface KaTeXCDNWorkerOptions {
3
+ /**
4
+ * Where to load KaTeX from inside the worker.
5
+ * - classic mode: UMD build (used via importScripts)
6
+ * - module mode: ESM build (used via dynamic import(url))
7
+ */
8
+ katexUrl: string;
9
+ /**
10
+ * Optional mhchem plugin URL to load in the worker (recommended).
11
+ * - classic mode: UMD build (importScripts)
12
+ * - module mode: ESM build (dynamic import(url))
13
+ */
14
+ mhchemUrl?: string;
15
+ /**
16
+ * - classic: widest compatibility, uses importScripts()
17
+ * - module: requires { type: 'module' } workers, uses import(url)
18
+ */
19
+ mode?: KaTeXCDNWorkerMode;
20
+ /**
21
+ * If set, worker prints verbose logs.
22
+ */
23
+ debug?: boolean;
24
+ /**
25
+ * Worker constructor options (name/type/credentials).
26
+ * Note: for module mode you should pass { type: 'module' }.
27
+ */
28
+ workerOptions?: WorkerOptions;
29
+ /**
30
+ * KaTeX render options used in the worker.
31
+ * Keep this minimal and stable for caching and predictable output.
32
+ */
33
+ renderOptions?: {
34
+ throwOnError?: boolean;
35
+ output?: string;
36
+ strict?: string;
37
+ };
38
+ }
39
+ export interface KaTeXCDNWorkerHandle {
40
+ worker: Worker | null;
41
+ /**
42
+ * Revoke the generated Blob URL. Call this when you no longer need the worker.
43
+ * This does not terminate the worker automatically.
44
+ */
45
+ dispose: () => void;
46
+ /**
47
+ * The generated worker source code (useful for debugging/tests).
48
+ */
49
+ source: string;
50
+ }
51
+ export declare function buildKaTeXCDNWorkerSource(options: KaTeXCDNWorkerOptions): string;
52
+ export declare function createKaTeXWorkerFromCDN(options: KaTeXCDNWorkerOptions): KaTeXCDNWorkerHandle;
File without changes
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Allow user to inject a Worker instance, e.g. from Vite ?worker import.
3
+ */
4
+ export declare function setKaTeXWorker(w: Worker): void;
5
+ /**
6
+ * Remove the current worker instance (for cleanup or SSR).
7
+ */
8
+ export declare function clearKaTeXWorker(): void;
9
+ export declare function setKaTeXWorkerDebug(enabled: boolean): void;
10
+ export declare function renderKaTeXInWorker(content: string, displayMode?: boolean, timeout?: number, signal?: AbortSignal): Promise<string>;
11
+ export declare function setKaTeXCache(content: string, displayMode: boolean, html: string): void;
12
+ /**
13
+ * Utilities for clients to inspect/adjust worker load behavior
14
+ */
15
+ export declare function getKaTeXWorkerLoad(): {
16
+ inFlight: number;
17
+ max: number;
18
+ };
19
+ export declare function setKaTeXWorkerMaxConcurrency(n: number): void;
20
+ export declare const WORKER_BUSY_CODE = "WORKER_BUSY";
21
+ export declare function isKaTeXWorkerBusy(): boolean;
22
+ export declare function waitForKaTeXWorkerSlot(timeout?: number, signal?: AbortSignal): Promise<void>;
23
+ export interface BackpressureOptions {
24
+ timeout?: number;
25
+ waitTimeout?: number;
26
+ backoffMs?: number;
27
+ maxRetries?: number;
28
+ signal?: AbortSignal;
29
+ }
30
+ declare const defaultBackpressure: {
31
+ timeout: number;
32
+ waitTimeout: number;
33
+ backoffMs: number;
34
+ maxRetries: number;
35
+ };
36
+ export declare function setKaTeXBackpressureDefaults(opts: Partial<typeof defaultBackpressure>): void;
37
+ export declare function getKaTeXBackpressureDefaults(): {
38
+ timeout: number;
39
+ waitTimeout: number;
40
+ backoffMs: number;
41
+ maxRetries: number;
42
+ };
43
+ /**
44
+ * Convenience wrapper: when worker reports busy, wait for a slot and retry.
45
+ * Does not implement fallback-to-main-thread; leave that to the caller.
46
+ */
47
+ export declare function renderKaTeXWithBackpressure(content: string, displayMode?: boolean, opts?: BackpressureOptions): Promise<string>;
48
+ export {};
@@ -0,0 +1,35 @@
1
+ export type MermaidCDNWorkerMode = 'classic' | 'module';
2
+ export interface MermaidCDNWorkerOptions {
3
+ /**
4
+ * Where to load mermaid from inside the worker.
5
+ * - classic mode: non-module build (used via importScripts)
6
+ * - module mode: ESM build (used via dynamic import(url))
7
+ */
8
+ mermaidUrl: string;
9
+ /**
10
+ * - classic: widest compatibility, uses importScripts()
11
+ * - module: requires { type: 'module' } workers, uses import(url)
12
+ */
13
+ mode?: MermaidCDNWorkerMode;
14
+ /**
15
+ * If set, worker prints verbose logs.
16
+ */
17
+ debug?: boolean;
18
+ /**
19
+ * Worker constructor options (name/type/credentials).
20
+ * Note: for module mode you should pass { type: 'module' }.
21
+ */
22
+ workerOptions?: WorkerOptions;
23
+ /**
24
+ * Mermaid initialize options used in the worker.
25
+ * This worker is used for parsing only; keep options minimal.
26
+ */
27
+ initializeOptions?: Record<string, any>;
28
+ }
29
+ export interface MermaidCDNWorkerHandle {
30
+ worker: Worker | null;
31
+ dispose: () => void;
32
+ source: string;
33
+ }
34
+ export declare function buildMermaidCDNWorkerSource(options: MermaidCDNWorkerOptions): string;
35
+ export declare function createMermaidWorkerFromCDN(options: MermaidCDNWorkerOptions): MermaidCDNWorkerHandle;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ type Theme = 'light' | 'dark';
2
+ export declare function setMermaidWorkerClientDebug(enabled: boolean): void;
3
+ export declare function setMermaidWorkerMaxConcurrency(n: number): void;
4
+ export declare function getMermaidWorkerLoad(): {
5
+ inFlight: number;
6
+ max: number;
7
+ };
8
+ export declare const MERMAID_WORKER_BUSY_CODE = "WORKER_BUSY";
9
+ export declare const MERMAID_DISABLED_CODE = "MERMAID_DISABLED";
10
+ /**
11
+ * Allow user to inject a Worker instance, e.g. from Vite ?worker import.
12
+ */
13
+ export declare function setMermaidWorker(w: Worker): void;
14
+ /**
15
+ * Remove the current worker instance (for cleanup or SSR).
16
+ */
17
+ export declare function clearMermaidWorker(): void;
18
+ export declare function canParseOffthread(code: string, theme: Theme, timeout?: number): Promise<boolean>;
19
+ export declare function findPrefixOffthread(code: string, theme: Theme, timeout?: number): Promise<string>;
20
+ export declare function terminateWorker(): void;
21
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "markstream-vue2",
3
3
  "type": "module",
4
- "version": "0.0.26",
4
+ "version": "0.0.28",
5
5
  "description": "Vue 2 Markdown renderer optimized for large documents with progressive Mermaid rendering, streaming diff code blocks, and fast real-time preview. Perfect for documentation sites, AI chat interfaces, and content management systems.",
6
6
  "author": "Simon He",
7
7
  "license": "MIT",
@@ -122,7 +122,7 @@
122
122
  "dependencies": {
123
123
  "@floating-ui/dom": "^1.7.6",
124
124
  "vue-demi": "^0.14.10",
125
- "stream-markdown-parser": "0.0.74"
125
+ "stream-markdown-parser": "0.0.76"
126
126
  },
127
127
  "devDependencies": {
128
128
  "@vitejs/plugin-vue2": "^2.3.4",