@contentgrowth/content-widget 1.2.4 → 1.3.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.
@@ -19,6 +19,9 @@ const {
19
19
  showBackButton = false,
20
20
  backUrl = '/articles',
21
21
  showAiSummary = true,
22
+ showCategory = true,
23
+ showTags = true,
24
+ excludeTags = [],
22
25
  class: className = ''
23
26
  } = Astro.props;
24
27
 
@@ -30,8 +33,8 @@ if (!uuid && !slug) {
30
33
  // Fetch article
31
34
  const client = new ContentGrowthClient({ apiKey, baseUrl });
32
35
  const article = slug
33
- ? await client.getArticleBySlug(slug)
34
- : await client.getArticle(uuid!);
36
+ ? await client.getArticleBySlug(slug, { excludeTags })
37
+ : await client.getArticle(uuid!, { excludeTags });
35
38
 
36
39
  // Render markdown to HTML (image syntax already processed by client)
37
40
  const contentHtml = marked(article.content);
@@ -57,7 +60,7 @@ const readingTime = calculateReadingTime(article.wordCount);
57
60
  )}
58
61
 
59
62
  <header class="cg-content-header">
60
- {article.category && (
63
+ {showCategory && article.category && (
61
64
  <div class="cg-content-category">
62
65
  <span class="cg-category-badge">{article.category}</span>
63
66
  </div>
@@ -87,7 +90,7 @@ const readingTime = calculateReadingTime(article.wordCount);
87
90
  <span class="cg-info-reading-time">{readingTime}</span>
88
91
  </div>
89
92
 
90
- {article.tags.length > 0 && (
93
+ {showTags && article.tags.length > 0 && (
91
94
  <div class="cg-content-tags">
92
95
  {article.tags.map((tag) => (
93
96
  <span class="cg-tag">{tag}</span>
@@ -0,0 +1,89 @@
1
+ ---
2
+ import { marked } from 'marked';
3
+ import { ContentGrowthClient } from '../core/client';
4
+ import type { FeaturedContentProps } from '../types';
5
+
6
+ type Props = FeaturedContentProps & { class?: string };
7
+
8
+ const {
9
+ apiKey,
10
+ baseUrl,
11
+ tags = [],
12
+ category,
13
+ excludeTags = [],
14
+ showAiSummary = true,
15
+ showCategory = true,
16
+ showTags = true,
17
+ class: className = ''
18
+ } = Astro.props;
19
+
20
+ // Fetch featured article
21
+ const client = new ContentGrowthClient({ apiKey, baseUrl });
22
+ let article = null;
23
+ let error = null;
24
+
25
+ try {
26
+ article = await client.getFeaturedArticle({
27
+ tags,
28
+ category,
29
+ excludeTags
30
+ });
31
+ } catch (e) {
32
+ // If 404, article remains null.
33
+ console.error('Failed to fetch featured article:', e);
34
+ error = e instanceof Error ? e.message : 'Failed to load featured article';
35
+ }
36
+
37
+ // Render markdown to HTML
38
+ const contentHtml = article ? marked(article.content) : '';
39
+ ---
40
+
41
+ {article ? (
42
+ <div class={`cg-widget cg-content-viewer ${className}`}>
43
+ <article class="cg-article">
44
+ {showCategory && article.category && (
45
+ <div class="cg-article-category">{article.category}</div>
46
+ )}
47
+
48
+ <h1 class="cg-article-title">{article.title}</h1>
49
+
50
+ <div class="cg-article-meta">
51
+ <span class="cg-author">{article.authorName}</span>
52
+ <span class="cg-date">
53
+ {new Date(article.publishedAt * 1000).toLocaleDateString()}
54
+ </span>
55
+ <span class="cg-read-time">
56
+ {Math.ceil(article.wordCount / 200)} min read
57
+ </span>
58
+ </div>
59
+
60
+ {showAiSummary && article.summary && (
61
+ <div class="cg-ai-summary">
62
+ <div class="cg-ai-label">AI Summary</div>
63
+ <p>{article.summary}</p>
64
+ </div>
65
+ )}
66
+
67
+ {/* Content */}
68
+ <div
69
+ class="cg-article-content"
70
+ set:html={contentHtml}
71
+ />
72
+
73
+ {/* Tags */}
74
+ {showTags && article.tags && article.tags.length > 0 && (
75
+ <div class="cg-article-tags">
76
+ {article.tags.map((tag: string) => (
77
+ <span class="cg-tag">#{tag}</span>
78
+ ))}
79
+ </div>
80
+ )}
81
+ </article>
82
+ </div>
83
+ ) : (
84
+ error ? (
85
+ <div class={`cg-widget cg-error ${className}`}>
86
+ {error}
87
+ </div>
88
+ ) : null
89
+ )}
@@ -5,5 +5,5 @@
5
5
  * They are copied directly to dist/ during the build process.
6
6
  * Import them directly from the .astro files in your Astro project.
7
7
  */
8
- export type { ContentListProps, ContentViewerProps } from '../types/index.js';
8
+ export type { ContentListProps, ContentViewerProps, FeaturedContentProps } from '../types/index.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/astro/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/astro/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -2,7 +2,7 @@
2
2
  * Content Growth API Client
3
3
  * Framework-agnostic API client for fetching articles
4
4
  */
5
- import type { ClientConfig, ListArticlesOptions, ArticlesResponse, ArticleWithContent, CategoriesResponse, TagsResponse } from '../types/index.js';
5
+ import type { ClientConfig, ListArticlesOptions, ArticlesResponse, ArticleWithContent, CategoriesResponse, TagsResponse, FeaturedArticleOptions } from '../types/index.js';
6
6
  /**
7
7
  * Content Growth API Client
8
8
  *
@@ -30,11 +30,19 @@ export declare class ContentGrowthClient {
30
30
  /**
31
31
  * Get a single article by UUID
32
32
  */
33
- getArticle(uuid: string): Promise<ArticleWithContent>;
33
+ getArticle(uuid: string, options?: {
34
+ excludeTags?: string[];
35
+ }): Promise<ArticleWithContent>;
34
36
  /**
35
37
  * Get a single article by slug
36
38
  */
37
- getArticleBySlug(slug: string): Promise<ArticleWithContent>;
39
+ getArticleBySlug(slug: string, options?: {
40
+ excludeTags?: string[];
41
+ }): Promise<ArticleWithContent>;
42
+ /**
43
+ * Get featured article (latest matching criteria)
44
+ */
45
+ getFeaturedArticle(options?: FeaturedArticleOptions): Promise<ArticleWithContent>;
38
46
  /**
39
47
  * Get all categories with article counts
40
48
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EAEb,MAAM,mBAAmB,CAAC;AAmB3B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,KAAK,CAA+B;gBAEhC,MAAM,EAAE,YAAY;IAmBhC;;OAEG;IACG,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwChF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwB3D;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwBjE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAelD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;IAetC;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;YACW,KAAK;IA2CnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;OAEG;IACH,OAAO,CAAC,GAAG;CAKZ"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EAEvB,MAAM,mBAAmB,CAAC;AAmB3B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,KAAK,CAA+B;gBAEhC,MAAM,EAAE,YAAY;IAmBhC;;OAEG;IACG,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwChF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgCjG;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgCvG;;OAEG;IACG,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiC3F;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAelD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;IAetC;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;YACW,KAAK;IA2CnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;OAEG;IACH,OAAO,CAAC,GAAG;CAKZ"}
@@ -83,17 +83,23 @@ export class ContentGrowthClient {
83
83
  /**
84
84
  * Get a single article by UUID
85
85
  */
86
- async getArticle(uuid) {
86
+ async getArticle(uuid, options) {
87
87
  if (!uuid) {
88
88
  throw new ContentGrowthError('Article UUID is required');
89
89
  }
90
- const cacheKey = `article:${uuid}`;
90
+ // Include excludeTags in cache key if present
91
+ const excludeTagsStr = options?.excludeTags?.sort().join(',') || '';
92
+ const cacheKey = `article:${uuid}${excludeTagsStr ? `:exclude:${excludeTagsStr}` : ''}`;
91
93
  const cached = this.getFromCache(cacheKey);
92
94
  if (cached) {
93
95
  this.log('Cache hit:', cacheKey);
94
96
  return cached;
95
97
  }
96
- const url = `${this.config.baseUrl}/widget/articles/${uuid}`;
98
+ const params = new URLSearchParams();
99
+ if (options?.excludeTags && options.excludeTags.length > 0) {
100
+ params.set('excludeTags', options.excludeTags.join(','));
101
+ }
102
+ const url = `${this.config.baseUrl}/widget/articles/${uuid}?${params.toString()}`;
97
103
  const data = await this.fetch(url);
98
104
  // Process image syntax in content
99
105
  if (data.content) {
@@ -105,17 +111,58 @@ export class ContentGrowthClient {
105
111
  /**
106
112
  * Get a single article by slug
107
113
  */
108
- async getArticleBySlug(slug) {
114
+ async getArticleBySlug(slug, options) {
109
115
  if (!slug) {
110
116
  throw new ContentGrowthError('Article slug is required');
111
117
  }
112
- const cacheKey = `article:slug:${slug}`;
118
+ // Include excludeTags in cache key if present
119
+ const excludeTagsStr = options?.excludeTags?.sort().join(',') || '';
120
+ const cacheKey = `article:slug:${slug}${excludeTagsStr ? `:exclude:${excludeTagsStr}` : ''}`;
113
121
  const cached = this.getFromCache(cacheKey);
114
122
  if (cached) {
115
123
  this.log('Cache hit:', cacheKey);
116
124
  return cached;
117
125
  }
118
- const url = `${this.config.baseUrl}/widget/articles/slug/${slug}`;
126
+ const params = new URLSearchParams();
127
+ if (options?.excludeTags && options.excludeTags.length > 0) {
128
+ params.set('excludeTags', options.excludeTags.join(','));
129
+ }
130
+ const url = `${this.config.baseUrl}/widget/articles/slug/${slug}?${params.toString()}`;
131
+ const data = await this.fetch(url);
132
+ // Process image syntax in content
133
+ if (data.content) {
134
+ data.content = processImageSyntax(data.content);
135
+ }
136
+ this.setCache(cacheKey, data);
137
+ return data;
138
+ }
139
+ /**
140
+ * Get featured article (latest matching criteria)
141
+ */
142
+ async getFeaturedArticle(options = {}) {
143
+ const { tags = [], category, excludeTags = [] } = options;
144
+ // Build cache key
145
+ const parts = ['featured'];
146
+ if (tags.length > 0)
147
+ parts.push(`tags:${tags.sort().join(',')}`);
148
+ if (category)
149
+ parts.push(`cat:${category}`);
150
+ if (excludeTags.length > 0)
151
+ parts.push(`exclude:${excludeTags.sort().join(',')}`);
152
+ const cacheKey = parts.join(':');
153
+ const cached = this.getFromCache(cacheKey);
154
+ if (cached) {
155
+ this.log('Cache hit:', cacheKey);
156
+ return cached;
157
+ }
158
+ const params = new URLSearchParams();
159
+ if (tags.length > 0)
160
+ params.set('tags', tags.join(','));
161
+ if (category)
162
+ params.set('category', category);
163
+ if (excludeTags.length > 0)
164
+ params.set('excludeTags', excludeTags.join(','));
165
+ const url = `${this.config.baseUrl}/widget/articles/featured?${params.toString()}`;
119
166
  const data = await this.fetch(url);
120
167
  // Process image syntax in content
121
168
  if (data.content) {
@@ -1 +1 @@
1
- {"version":3,"file":"ContentViewer.d.ts","sourceRoot":"","sources":["../../src/react/ContentViewer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA4H3D,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ContentViewer.d.ts","sourceRoot":"","sources":["../../src/react/ContentViewer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA+H3D,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -6,7 +6,7 @@ import React, { useEffect, useState } from 'react';
6
6
  import { ContentGrowthClient } from '../core/client.js';
7
7
  import { formatDate, calculateReadingTime } from '../core/utils.js';
8
8
  import { marked } from 'marked';
9
- export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', showBackButton = false, backUrl = '/articles', showAiSummary = true, className = '' }) => {
9
+ export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', showBackButton = false, backUrl = '/articles', showAiSummary = true, showCategory = true, showTags = true, excludeTags = [], className = '' }) => {
10
10
  const [article, setArticle] = useState(null);
11
11
  const [loading, setLoading] = useState(true);
12
12
  const [error, setError] = useState(null);
@@ -21,8 +21,8 @@ export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', sh
21
21
  try {
22
22
  const client = new ContentGrowthClient({ apiKey, baseUrl });
23
23
  const fetchedArticle = slug
24
- ? await client.getArticleBySlug(slug)
25
- : await client.getArticle(uuid);
24
+ ? await client.getArticleBySlug(slug, { excludeTags })
25
+ : await client.getArticle(uuid, { excludeTags });
26
26
  setArticle(fetchedArticle);
27
27
  }
28
28
  catch (err) {
@@ -33,7 +33,7 @@ export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', sh
33
33
  }
34
34
  };
35
35
  fetchArticle();
36
- }, [apiKey, baseUrl, uuid, slug]);
36
+ }, [apiKey, baseUrl, uuid, slug, JSON.stringify(excludeTags)]);
37
37
  if (loading) {
38
38
  return (React.createElement("div", { className: `cg-content-viewer cg-theme-${theme} ${className}` },
39
39
  React.createElement("div", { className: "cg-empty-state" },
@@ -55,7 +55,7 @@ export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', sh
55
55
  React.createElement("path", { d: "M12 16L6 10L12 4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })),
56
56
  "Back to articles"))),
57
57
  React.createElement("header", { className: "cg-content-header" },
58
- article.category && (React.createElement("div", { className: "cg-content-category" },
58
+ showCategory && article.category && (React.createElement("div", { className: "cg-content-category" },
59
59
  React.createElement("span", { className: "cg-category-badge" }, article.category))),
60
60
  React.createElement("h1", { className: "cg-content-title" }, article.title),
61
61
  showAiSummary && article.summary && (React.createElement("div", { className: "cg-ai-summary" },
@@ -70,7 +70,7 @@ export const ContentViewer = ({ apiKey, uuid, slug, baseUrl, theme = 'light', sh
70
70
  React.createElement("time", { className: "cg-info-date", dateTime: new Date(article.publishedAt * 1000).toISOString() }, publishedDate),
71
71
  React.createElement("span", { className: "cg-info-separator" }, "\u2022"),
72
72
  React.createElement("span", { className: "cg-info-reading-time" }, readingTime)),
73
- article.tags.length > 0 && (React.createElement("div", { className: "cg-content-tags" }, article.tags.map((tag) => (React.createElement("span", { key: tag, className: "cg-tag" }, tag)))))),
73
+ showTags && article.tags.length > 0 && (React.createElement("div", { className: "cg-content-tags" }, article.tags.map((tag) => (React.createElement("span", { key: tag, className: "cg-tag" }, tag)))))),
74
74
  React.createElement("div", { className: "cg-content-body", dangerouslySetInnerHTML: { __html: contentHtml } })));
75
75
  };
76
76
  export default ContentViewer;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { FeaturedContentProps } from '../types';
3
+ export declare const FeaturedContent: React.FC<FeaturedContentProps>;
4
+ //# sourceMappingURL=FeaturedContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeaturedContent.d.ts","sourceRoot":"","sources":["../../src/react/FeaturedContent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAAE,oBAAoB,EAAsB,MAAM,UAAU,CAAC;AAEzE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAsG1D,CAAC"}
@@ -0,0 +1,60 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { marked } from 'marked';
3
+ import { ContentGrowthClient } from '../core/client';
4
+ export const FeaturedContent = ({ apiKey, baseUrl, tags = [], category, excludeTags = [], showAiSummary = true, showCategory = true, showTags = true, className = '' }) => {
5
+ const [article, setArticle] = useState(null);
6
+ const [loading, setLoading] = useState(true);
7
+ const [error, setError] = useState(null);
8
+ useEffect(() => {
9
+ const fetchArticle = async () => {
10
+ setLoading(true);
11
+ try {
12
+ const client = new ContentGrowthClient({ apiKey, baseUrl });
13
+ const fetchedArticle = await client.getFeaturedArticle({
14
+ tags,
15
+ category,
16
+ excludeTags
17
+ });
18
+ setArticle(fetchedArticle);
19
+ }
20
+ catch (err) {
21
+ // 404 is valid for featured content (nothing matches criteria)
22
+ // We'll just set article to null so nothing renders, or show optional empty state?
23
+ // For a widget, usually empty is better than error if just no content matches.
24
+ // But for debugging, knowing it failed is good.
25
+ // Let's stick to error state for now, user can handle 'No featured content found'
26
+ setError(err instanceof Error ? err.message : 'Failed to load featured article');
27
+ }
28
+ finally {
29
+ setLoading(false);
30
+ }
31
+ };
32
+ fetchArticle();
33
+ }, [apiKey, baseUrl, category, JSON.stringify(tags), JSON.stringify(excludeTags)]);
34
+ if (loading) {
35
+ return (React.createElement("div", { className: `cg-widget cg-loading ${className}` },
36
+ React.createElement("div", { className: "cg-spinner" })));
37
+ }
38
+ if (error || !article) {
39
+ // If specifically "No featured content found" (404), maybe we just render nothing or an empty placeholder?
40
+ // For now render standard error container
41
+ return (React.createElement("div", { className: `cg-widget cg-error ${className}` }, error || 'No featured content found'));
42
+ }
43
+ return (React.createElement("div", { className: `cg-widget cg-content-viewer ${className}` },
44
+ React.createElement("article", { className: "cg-article" },
45
+ showCategory && article.category && (React.createElement("div", { className: "cg-article-category" }, article.category)),
46
+ React.createElement("h1", { className: "cg-article-title" }, article.title),
47
+ React.createElement("div", { className: "cg-article-meta" },
48
+ React.createElement("span", { className: "cg-author" }, article.authorName),
49
+ React.createElement("span", { className: "cg-date" }, new Date(article.publishedAt * 1000).toLocaleDateString()),
50
+ React.createElement("span", { className: "cg-read-time" },
51
+ Math.ceil(article.wordCount / 200),
52
+ " min read")),
53
+ showAiSummary && article.summary && (React.createElement("div", { className: "cg-ai-summary" },
54
+ React.createElement("div", { className: "cg-ai-label" }, "AI Summary"),
55
+ React.createElement("p", null, article.summary))),
56
+ React.createElement("div", { className: "cg-article-content", dangerouslySetInnerHTML: { __html: marked(article.content) } }),
57
+ showTags && article.tags && article.tags.length > 0 && (React.createElement("div", { className: "cg-article-tags" }, article.tags.map(tag => (React.createElement("span", { key: tag, className: "cg-tag" },
58
+ "#",
59
+ tag))))))));
60
+ };
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export { ContentList } from './ContentList.js';
5
5
  export { ContentViewer } from './ContentViewer.js';
6
+ export { FeaturedContent } from './FeaturedContent.js';
6
7
  export * from './hooks.js';
7
8
  export type { ReactContentListProps } from './ContentList.js';
8
9
  export type { ReactContentViewerProps } from './ContentViewer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,YAAY,CAAC;AAE3B,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,cAAc,YAAY,CAAC;AAE3B,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -3,4 +3,5 @@
3
3
  */
4
4
  export { ContentList } from './ContentList.js';
5
5
  export { ContentViewer } from './ContentViewer.js';
6
+ export { FeaturedContent } from './FeaturedContent.js';
6
7
  export * from './hooks.js';
@@ -207,6 +207,10 @@ export interface ContentListProps {
207
207
  * Custom CSS class
208
208
  */
209
209
  class?: string;
210
+ /**
211
+ * Custom CSS class (React alias)
212
+ */
213
+ className?: string;
210
214
  }
211
215
  /**
212
216
  * Component props for ContentViewer
@@ -248,10 +252,49 @@ export interface ContentViewerProps {
248
252
  * @default true
249
253
  */
250
254
  showAiSummary?: boolean;
255
+ /**
256
+ * Tags to exclude from display (e.g. used for filtering on list page)
257
+ */
258
+ excludeTags?: string[];
259
+ /**
260
+ * Show article category
261
+ * @default true
262
+ */
263
+ showCategory?: boolean;
264
+ /**
265
+ * Show article tags
266
+ * @default true
267
+ */
268
+ showTags?: boolean;
251
269
  /**
252
270
  * Custom CSS class
253
271
  */
254
272
  class?: string;
273
+ /**
274
+ * Custom CSS class (React alias)
275
+ */
276
+ className?: string;
277
+ }
278
+ /**
279
+ * Options for fetching featured article
280
+ */
281
+ export interface FeaturedArticleOptions {
282
+ tags?: string[];
283
+ category?: string;
284
+ excludeTags?: string[];
285
+ }
286
+ /**
287
+ * Component props for FeaturedContent
288
+ */
289
+ export interface FeaturedContentProps extends Omit<ContentViewerProps, 'uuid' | 'slug'> {
290
+ /**
291
+ * Filter by tags (find latest article with these tags)
292
+ */
293
+ tags?: string[];
294
+ /**
295
+ * Filter by category (find latest article in this category)
296
+ */
297
+ category?: string;
255
298
  }
256
299
  /**
257
300
  * Cache entry
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -158,7 +158,14 @@ onMounted(() => {
158
158
  });
159
159
 
160
160
  watch(
161
- () => [props.apiKey, props.baseUrl, currentPage.value, props.pageSize, props.tags, props.category],
161
+ [
162
+ () => props.apiKey,
163
+ () => props.baseUrl,
164
+ () => currentPage.value,
165
+ () => props.pageSize,
166
+ () => JSON.stringify(props.tags),
167
+ () => props.category
168
+ ],
162
169
  () => {
163
170
  fetchArticles();
164
171
  }
@@ -20,7 +20,7 @@
20
20
  </div>
21
21
 
22
22
  <header class="cg-content-header">
23
- <div v-if="article.category" class="cg-content-category">
23
+ <div v-if="showCategory && article.category" class="cg-content-category">
24
24
  <span class="cg-category-badge">{{ article.category }}</span>
25
25
  </div>
26
26
 
@@ -46,7 +46,7 @@
46
46
  <span class="cg-info-reading-time">{{ calculateReadingTime(article.wordCount) }}</span>
47
47
  </div>
48
48
 
49
- <div v-if="article.tags.length > 0" class="cg-content-tags">
49
+ <div v-if="showTags && article.tags.length > 0" class="cg-content-tags">
50
50
  <span v-for="tag in article.tags" :key="tag" class="cg-tag">{{ tag }}</span>
51
51
  </div>
52
52
  </header>
@@ -72,6 +72,9 @@ const props = withDefaults(defineProps<VueContentViewerProps>(), {
72
72
  showBackButton: false,
73
73
  backUrl: '/articles',
74
74
  showAiSummary: true,
75
+ showCategory: true,
76
+ showTags: true,
77
+ excludeTags: () => [],
75
78
  className: ''
76
79
  });
77
80
 
@@ -99,8 +102,8 @@ onMounted(async () => {
99
102
  baseUrl: props.baseUrl
100
103
  });
101
104
  const fetchedArticle = props.slug
102
- ? await client.getArticleBySlug(props.slug)
103
- : await client.getArticle(props.uuid!);
105
+ ? await client.getArticleBySlug(props.slug, { excludeTags: props.excludeTags })
106
+ : await client.getArticle(props.uuid!, { excludeTags: props.excludeTags });
104
107
  article.value = fetchedArticle;
105
108
  } catch (err) {
106
109
  error.value = err instanceof Error ? err.message : 'Failed to load article';
@@ -0,0 +1,101 @@
1
+ <script setup lang="ts">
2
+ import { ref, onMounted, computed } from 'vue';
3
+ import { marked } from 'marked';
4
+ import { ContentGrowthClient } from '../core/client';
5
+ import type { ArticleWithContent } from '../types';
6
+
7
+ const props = withDefaults(defineProps<{
8
+ apiKey: string;
9
+ baseUrl: string;
10
+ tags?: string[];
11
+ category?: string;
12
+ excludeTags?: string[];
13
+ showAiSummary?: boolean;
14
+ showCategory?: boolean;
15
+ showTags?: boolean;
16
+ className?: string;
17
+ }>(), {
18
+ tags: () => [],
19
+ excludeTags: () => [],
20
+ showAiSummary: true,
21
+ showCategory: true,
22
+ showTags: true,
23
+ className: ''
24
+ });
25
+
26
+ const article = ref<ArticleWithContent | null>(null);
27
+ const loading = ref(true);
28
+ const error = ref<string | null>(null);
29
+
30
+ // Render markdown to HTML
31
+ const contentHtml = computed(() => {
32
+ if (!article.value) return '';
33
+ return marked(article.value.content);
34
+ });
35
+
36
+ onMounted(async () => {
37
+ loading.value = true;
38
+ try {
39
+ const client = new ContentGrowthClient({
40
+ apiKey: props.apiKey,
41
+ baseUrl: props.baseUrl
42
+ });
43
+ const fetchedArticle = await client.getFeaturedArticle({
44
+ tags: props.tags,
45
+ category: props.category,
46
+ excludeTags: props.excludeTags
47
+ });
48
+ article.value = fetchedArticle;
49
+ } catch (err) {
50
+ error.value = err instanceof Error ? err.message : 'Failed to load featured article';
51
+ } finally {
52
+ loading.value = false;
53
+ }
54
+ });
55
+ </script>
56
+
57
+ <template>
58
+ <div v-if="loading" class="cg-widget cg-loading" :class="className">
59
+ <div class="cg-spinner"></div>
60
+ </div>
61
+
62
+ <div v-else-if="error || !article" class="cg-widget cg-error" :class="className">
63
+ {{ error || 'No featured content found' }}
64
+ </div>
65
+
66
+ <div v-else class="cg-widget cg-content-viewer" :class="className">
67
+ <article class="cg-article">
68
+ <div v-if="showCategory && article?.category" class="cg-article-category">
69
+ {{ article.category }}
70
+ </div>
71
+
72
+ <h1 class="cg-article-title">{{ article?.title }}</h1>
73
+
74
+ <div class="cg-article-meta">
75
+ <span class="cg-author">{{ article?.authorName }}</span>
76
+ <span v-if="article?.publishedAt" class="cg-date">
77
+ {{ new Date(article.publishedAt * 1000).toLocaleDateString() }}
78
+ </span>
79
+ <span v-if="article?.wordCount" class="cg-read-time">
80
+ {{ Math.ceil(article.wordCount / 200) }} min read
81
+ </span>
82
+ </div>
83
+
84
+ <div v-if="showAiSummary && article?.summary" class="cg-ai-summary">
85
+ <div class="cg-ai-label">AI Summary</div>
86
+ <p>{{ article.summary }}</p>
87
+ </div>
88
+
89
+ <!-- Content -->
90
+ <div
91
+ class="cg-article-content"
92
+ v-html="contentHtml"
93
+ ></div>
94
+
95
+ <!-- Tags -->
96
+ <div v-if="showTags && article?.tags && article.tags.length > 0" class="cg-article-tags">
97
+ <span v-for="tag in article.tags" :key="tag" class="cg-tag">#{{ tag }}</span>
98
+ </div>
99
+ </article>
100
+ </div>
101
+ </template>
@@ -6,5 +6,5 @@
6
6
  * Import them directly from the .vue files in your Vue project.
7
7
  */
8
8
  export * from './composables.js';
9
- export type { ContentListProps, ContentViewerProps } from '../types/index.js';
9
+ export type { ContentListProps, ContentViewerProps, FeaturedContentProps } from '../types/index.js';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,kBAAkB,CAAC;AAGjC,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,kBAAkB,CAAC;AAGjC,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Content Growth Widget - Standalone Bundle
3
- * Version: 1.2.4
3
+ * Version: 1.3.1
4
4
  * https://www.content-growth.com
5
5
  */
6
6
  (function(window) {
@@ -3514,7 +3514,7 @@ class ContentViewer {
3514
3514
 
3515
3515
  class ContentGrowthWidget {
3516
3516
  // Version will be injected during build from package.json
3517
- static version = '1.2.4';
3517
+ static version = '1.3.1';
3518
3518
 
3519
3519
  constructor(container, config) {
3520
3520
 
@@ -3826,6 +3826,6 @@ window.ContentGrowthWidget = ContentGrowthWidget;
3826
3826
  // ===== Expose to window =====
3827
3827
  window.ContentGrowthWidget = ContentGrowthWidget;
3828
3828
 
3829
- console.log('[ContentGrowthWidget] Loaded successfully v1.2.4');
3829
+ console.log('[ContentGrowthWidget] Loaded successfully v1.3.1');
3830
3830
 
3831
3831
  })(window);
@@ -1 +1 @@
1
- !function(e){"use strict";var t,n;function s(e){return new Date(1e3*e).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}function i(e){if(!e)return"Unknown";let t;if("number"==typeof e){if(t=e,0===t)return"Unknown"}else t=e.trim().split(/\s+/).filter(e=>e.length>0).length;return`${Math.ceil(t/200)} min read`}function r(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function o(e){return e?e.replace(/!\[([^\]]*)\]\(([^\s)]+)\s*=(\d+)x(\d*)\)/g,(e,t,n,s,i)=>`![${t}](${n})`):e}t=this,n=function(e){function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function n(t){e.defaults=t}e.defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};const s=/[&<>"']/,i=new RegExp(s.source,"g"),r=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,o=new RegExp(r.source,"g"),a={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},l=e=>a[e];function c(e,t){if(t){if(s.test(e))return e.replace(i,l)}else if(r.test(e))return e.replace(o,l);return e}const h=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function d(e){return e.replace(h,(e,t)=>"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):"")}const p=/(^|[^\[])\^/g;function u(e,t){let n="string"==typeof e?e:e.source;t=t||"";const s={replace:(e,t)=>{let i="string"==typeof t?t:t.source;return i=i.replace(p,"$1"),n=n.replace(e,i),s},getRegex:()=>new RegExp(n,t)};return s}function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return null}return e}const k={exec:()=>null};function f(e,t){const n=e.replace(/\|/g,(e,t,n)=>{let s=!1,i=t;for(;--i>=0&&"\\"===n[i];)s=!s;return s?"|":" |"}).split(/ \|/);let s=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;s<n.length;s++)n[s]=n[s].trim().replace(/\\\|/g,"|");return n}function w(e,t,n){const s=e.length;if(0===s)return"";let i=0;for(;i<s;){const r=e.charAt(s-i-1);if(r!==t||n){if(r===t||!n)break;i++}else i++}return e.slice(0,s-i)}function x(e,t,n,s){const i=t.href,r=t.title?c(t.title):null,o=e[1].replace(/\\([\[\]])/g,"$1");if("!"!==e[0].charAt(0)){s.state.inLink=!0;const e={type:"link",raw:n,href:i,title:r,text:o,tokens:s.inlineTokens(o)};return s.state.inLink=!1,e}return{type:"image",raw:n,href:i,title:r,text:c(o)}}class m{options;rules;lexer;constructor(t){this.options=t||e.defaults}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:w(e,"\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n=function(e,t){const n=e.match(/^(\s+)(?:```)/);if(null===n)return t;const s=n[1];return t.split("\n").map(e=>{const t=e.match(/^\s+/);if(null===t)return e;const[n]=t;return n.length>=s.length?e.slice(s.length):e}).join("\n")}(e,t[3]||"");return{type:"code",raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:n}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(/#$/.test(e)){const t=w(e,"#");this.options.pedantic?e=t.trim():t&&!/ $/.test(t)||(e=t.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const e=w(t[0].replace(/^ *>[ \t]?/gm,""),"\n"),n=this.lexer.state.top;this.lexer.state.top=!0;const s=this.lexer.blockTokens(e);return this.lexer.state.top=n,{type:"blockquote",raw:t[0],tokens:s,text:e}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();const s=n.length>1,i={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");const r=new RegExp(`^( {0,3}${n})((?:[\t ][^\\n]*)?(?:\\n|$))`);let o="",a="",l=!1;for(;e;){let n=!1;if(!(t=r.exec(e)))break;if(this.rules.block.hr.test(e))break;o=t[0],e=e.substring(o.length);let s=t[2].split("\n",1)[0].replace(/^\t+/,e=>" ".repeat(3*e.length)),c=e.split("\n",1)[0],h=0;this.options.pedantic?(h=2,a=s.trimStart()):(h=t[2].search(/[^ ]/),h=h>4?1:h,a=s.slice(h),h+=t[1].length);let d=!1;if(!s&&/^ *$/.test(c)&&(o+=c+"\n",e=e.substring(c.length+1),n=!0),!n){const t=new RegExp(`^ {0,${Math.min(3,h-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),n=new RegExp(`^ {0,${Math.min(3,h-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),i=new RegExp(`^ {0,${Math.min(3,h-1)}}(?:\`\`\`|~~~)`),r=new RegExp(`^ {0,${Math.min(3,h-1)}}#`);for(;e;){const l=e.split("\n",1)[0];if(c=l,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),i.test(c))break;if(r.test(c))break;if(t.test(c))break;if(n.test(e))break;if(c.search(/[^ ]/)>=h||!c.trim())a+="\n"+c.slice(h);else{if(d)break;if(s.search(/[^ ]/)>=4)break;if(i.test(s))break;if(r.test(s))break;if(n.test(s))break;a+="\n"+c}d||c.trim()||(d=!0),o+=l+"\n",e=e.substring(l.length+1),s=c.slice(h)}}i.loose||(l?i.loose=!0:/\n *\n *$/.test(o)&&(l=!0));let p,u=null;this.options.gfm&&(u=/^\[[ xX]\] /.exec(a),u&&(p="[ ] "!==u[0],a=a.replace(/^\[[ xX]\] +/,""))),i.items.push({type:"list_item",raw:o,task:!!u,checked:p,loose:!1,text:a,tokens:[]}),i.raw+=o}i.items[i.items.length-1].raw=o.trimEnd(),i.items[i.items.length-1].text=a.trimEnd(),i.raw=i.raw.trimEnd();for(let e=0;e<i.items.length;e++)if(this.lexer.state.top=!1,i.items[e].tokens=this.lexer.blockTokens(i.items[e].text,[]),!i.loose){const t=i.items[e].tokens.filter(e=>"space"===e.type),n=t.length>0&&t.some(e=>/\n.*\n/.test(e.raw));i.loose=n}if(i.loose)for(let e=0;e<i.items.length;e++)i.items[e].loose=!0;return i}}html(e){const t=this.rules.block.html.exec(e);if(t)return{type:"html",block:!0,raw:t[0],pre:"pre"===t[1]||"script"===t[1]||"style"===t[1],text:t[0]}}def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLowerCase().replace(/\s+/g," "),n=t[2]?t[2].replace(/^<(.*)>$/,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",s=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:e,raw:t[0],href:n,title:s}}}table(e){const t=this.rules.block.table.exec(e);if(!t)return;if(!/[:|]/.test(t[2]))return;const n=f(t[1]),s=t[2].replace(/^\||\| *$/g,"").split("|"),i=t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[],r={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===s.length){for(const e of s)/^ *-+: *$/.test(e)?r.align.push("right"):/^ *:-+: *$/.test(e)?r.align.push("center"):/^ *:-+ *$/.test(e)?r.align.push("left"):r.align.push(null);for(const e of n)r.header.push({text:e,tokens:this.lexer.inline(e)});for(const e of i)r.rows.push(f(e,r.header.length).map(e=>({text:e,tokens:this.lexer.inline(e)})));return r}}lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:"="===t[2].charAt(0)?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e="\n"===t[1].charAt(t[1].length-1)?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:e,tokens:this.lexer.inline(e)}}}text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:c(t[1])}}tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&/^<a /i.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&/^<\/a>/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&/^</.test(e)){if(!/>$/.test(e))return;const t=w(e.slice(0,-1),"\\");if((e.length-t.length)%2==0)return}else{const e=function(e,t){if(-1===e.indexOf(t[1]))return-1;let n=0;for(let s=0;s<e.length;s++)if("\\"===e[s])s++;else if(e[s]===t[0])n++;else if(e[s]===t[1]&&(n--,n<0))return s;return-1}(t[2],"()");if(e>-1){const n=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=""}}let n=t[2],s="";if(this.options.pedantic){const e=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);e&&(n=e[1],s=e[3])}else s=t[3]?t[3].slice(1,-1):"";return n=n.trim(),/^</.test(n)&&(n=this.options.pedantic&&!/>$/.test(e)?n.slice(1):n.slice(1,-1)),x(t,{href:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n,title:s?s.replace(this.rules.inline.anyPunctuation,"$1"):s},t[0],this.lexer)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const e=t[(n[2]||n[1]).replace(/\s+/g," ").toLowerCase()];if(!e){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return x(n,e,n[0],this.lexer)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(s&&(!s[3]||!n.match(/[\p{L}\p{N}]/u))&&(!s[1]&&!s[2]||!n||this.rules.inline.punctuation.exec(n))){const n=[...s[0]].length-1;let i,r,o=n,a=0;const l="*"===s[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(l.lastIndex=0,t=t.slice(-1*e.length+n);null!=(s=l.exec(t));){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i)continue;if(r=[...i].length,s[3]||s[4]){o+=r;continue}if((s[5]||s[6])&&n%3&&!((n+r)%3)){a+=r;continue}if(o-=r,o>0)continue;r=Math.min(r,r+o+a);const t=[...s[0]][0].length,l=e.slice(0,n+s.index+t+r);if(Math.min(n,r)%2){const e=l.slice(1,-1);return{type:"em",raw:l,text:e,tokens:this.lexer.inlineTokens(e)}}const c=l.slice(2,-2);return{type:"strong",raw:l,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(/\n/g," ");const n=/[^ ]/.test(e),s=/^ /.test(e)&&/ $/.test(e);return n&&s&&(e=e.substring(1,e.length-1)),e=c(e,!0),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;return"@"===t[2]?(e=c(t[1]),n="mailto:"+e):(e=c(t[1]),n=e),{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2])e=c(t[0]),n="mailto:"+e;else{let s;do{s=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??""}while(s!==t[0]);e=c(t[0]),n="www."===t[1]?"http://"+t[0]:t[0]}return{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;return e=this.lexer.state.inRawBlock?t[0]:c(t[0]),{type:"text",raw:t[0],text:e}}}}const y=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,b=/(?:[*+-]|\d{1,9}[.)])/,v=u(/^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g,b).getRegex(),$=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,M=/(?!\s*\])(?:\\.|[^\[\]\\])+/,C=u(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/).replace("label",M).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),T=u(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,b).getRegex(),L="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",S=/<!--(?!-?>)[\s\S]*?(?:-->|$)/,A=u("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))","i").replace("comment",S).replace("tag",L).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),E=u($).replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex(),z={blockquote:u(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",E).getRegex(),code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,def:C,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:y,html:A,lheading:v,list:T,newline:/^(?: *(?:\n|$))+/,paragraph:E,table:k,text:/^[^\n]+/},B=u("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex(),P={...z,table:B,paragraph:u($).replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",B).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex()},I={...z,html:u("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",S).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:k,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:u($).replace("hr",y).replace("heading"," *#{1,6} *[^\n]").replace("lheading",v).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},R=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,_=/^( {2,}|\\)\n(?!\s*$)/,q="\\p{P}$+<=>`^|~",U=u(/^((?![*_])[\spunctuation])/,"u").replace(/punctuation/g,q).getRegex(),H=u(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,"u").replace(/punct/g,q).getRegex(),Z=u("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])","gu").replace(/punct/g,q).getRegex(),V=u("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])","gu").replace(/punct/g,q).getRegex(),D=u(/\\([punct])/,"gu").replace(/punct/g,q).getRegex(),F=u(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),K=u(S).replace("(?:--\x3e|$)","--\x3e").getRegex(),Q=u("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",K).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),j=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,O=u(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",j).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),N=u(/^!?\[(label)\]\[(ref)\]/).replace("label",j).replace("ref",M).getRegex(),G=u(/^!?\[(ref)\](?:\[\])?/).replace("ref",M).getRegex(),W={_backpedal:k,anyPunctuation:D,autolink:F,blockSkip:/\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g,br:_,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:k,emStrongLDelim:H,emStrongRDelimAst:Z,emStrongRDelimUnd:V,escape:R,link:O,nolink:G,punctuation:U,reflink:N,reflinkSearch:u("reflink|nolink(?!\\()","g").replace("reflink",N).replace("nolink",G).getRegex(),tag:Q,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,url:k},X={...W,link:u(/^!?\[(label)\]\((.*?)\)/).replace("label",j).getRegex(),reflink:u(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",j).getRegex()},J={...W,escape:u(R).replace("])","~|])").getRegex(),url:u(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/},Y={...J,br:u(_).replace("{2,}","*").getRegex(),text:u(J.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},ee={normal:z,gfm:P,pedantic:I},te={normal:W,gfm:J,breaks:Y,pedantic:X};class ne{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||e.defaults,this.options.tokenizer=this.options.tokenizer||new m,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const n={block:ee.normal,inline:te.normal};this.options.pedantic?(n.block=ee.pedantic,n.inline=te.pedantic):this.options.gfm&&(n.block=ee.gfm,this.options.breaks?n.inline=te.breaks:n.inline=te.gfm),this.tokenizer.rules=n}static get rules(){return{block:ee,inline:te}}static lex(e,t){return new ne(t).lex(e)}static lexInline(e,t){return new ne(t).inlineTokens(e)}lex(e){e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){const t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[]){let n,s,i,r;for(e=this.options.pedantic?e.replace(/\t/g," ").replace(/^ +$/gm,""):e.replace(/^( *)(\t+)/gm,(e,t,n)=>t+" ".repeat(n.length));e;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some(s=>!!(n=s.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.space(e))e=e.substring(n.raw.length),1===n.raw.length&&t.length>0?t[t.length-1].raw+="\n":t.push(n);else if(n=this.tokenizer.code(e))e=e.substring(n.raw.length),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?t.push(n):(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=s.text);else if(n=this.tokenizer.fences(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.heading(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.hr(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.blockquote(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.list(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.html(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.def(e))e=e.substring(n.raw.length),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(s.raw+="\n"+n.raw,s.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=s.text);else if(n=this.tokenizer.table(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.lheading(e))e=e.substring(n.raw.length),t.push(n);else{if(i=e,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startBlock.forEach(e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))}),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(this.state.top&&(n=this.tokenizer.paragraph(i)))s=t[t.length-1],r&&"paragraph"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.text):t.push(n),r=i.length!==e.length,e=e.substring(n.raw.length);else if(n=this.tokenizer.text(e))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n,s,i,r,o,a,l=e;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(r=this.tokenizer.rules.inline.reflinkSearch.exec(l));)e.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(l=l.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(r=this.tokenizer.rules.inline.blockSkip.exec(l));)l=l.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(r=this.tokenizer.rules.inline.anyPunctuation.exec(l));)l=l.slice(0,r.index)+"++"+l.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;e;)if(o||(a=""),o=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some(s=>!!(n=s.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.escape(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.tag(e))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(n=this.tokenizer.link(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(n=this.tokenizer.emStrong(e,l,a))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.codespan(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.br(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.del(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.autolink(e))e=e.substring(n.raw.length),t.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(e))){if(i=e,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startInline.forEach(e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))}),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(n=this.tokenizer.inlineText(i))e=e.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(a=n.raw.slice(-1)),o=!0,s=t[t.length-1],s&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}else e=e.substring(n.raw.length),t.push(n);return t}}class se{options;constructor(t){this.options=t||e.defaults}code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$/,"")+"\n",s?'<pre><code class="language-'+c(s)+'">'+(n?e:c(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:c(e,!0))+"</code></pre>\n"}blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}html(e,t){return e}heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}hr(){return"<hr>\n"}list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"</"+s+">\n"}listitem(e,t,n){return`<li>${e}</li>\n`}checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph(e){return`<p>${e}</p>\n`}table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"}tablerow(e){return`<tr>\n${e}</tr>\n`}tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong(e){return`<strong>${e}</strong>`}em(e){return`<em>${e}</em>`}codespan(e){return`<code>${e}</code>`}br(){return"<br>"}del(e){return`<del>${e}</del>`}link(e,t,n){const s=g(e);if(null===s)return n;let i='<a href="'+(e=s)+'"';return t&&(i+=' title="'+t+'"'),i+=">"+n+"</a>",i}image(e,t,n){const s=g(e);if(null===s)return n;let i=`<img src="${e=s}" alt="${n}"`;return t&&(i+=` title="${t}"`),i+=">",i}text(e){return e}}class ie{strong(e){return e}em(e){return e}codespan(e){return e}del(e){return e}html(e){return e}text(e){return e}link(e,t,n){return""+n}image(e,t,n){return""+n}br(){return""}}class re{options;renderer;textRenderer;constructor(t){this.options=t||e.defaults,this.options.renderer=this.options.renderer||new se,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ie}static parse(e,t){return new re(t).parse(e)}static parseInline(e,t){return new re(t).parseInline(e)}parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const i=e[s];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const e=i,t=this.options.extensions.renderers[e.type].call({parser:this},e);if(!1!==t||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(e.type)){n+=t||"";continue}}switch(i.type){case"space":continue;case"hr":n+=this.renderer.hr();continue;case"heading":{const e=i;n+=this.renderer.heading(this.parseInline(e.tokens),e.depth,d(this.parseInline(e.tokens,this.textRenderer)));continue}case"code":{const e=i;n+=this.renderer.code(e.text,e.lang,!!e.escaped);continue}case"table":{const e=i;let t="",s="";for(let t=0;t<e.header.length;t++)s+=this.renderer.tablecell(this.parseInline(e.header[t].tokens),{header:!0,align:e.align[t]});t+=this.renderer.tablerow(s);let r="";for(let t=0;t<e.rows.length;t++){const n=e.rows[t];s="";for(let t=0;t<n.length;t++)s+=this.renderer.tablecell(this.parseInline(n[t].tokens),{header:!1,align:e.align[t]});r+=this.renderer.tablerow(s)}n+=this.renderer.table(t,r);continue}case"blockquote":{const e=i,t=this.parse(e.tokens);n+=this.renderer.blockquote(t);continue}case"list":{const e=i,t=e.ordered,s=e.start,r=e.loose;let o="";for(let t=0;t<e.items.length;t++){const n=e.items[t],s=n.checked,i=n.task;let a="";if(n.task){const e=this.renderer.checkbox(!!s);r?n.tokens.length>0&&"paragraph"===n.tokens[0].type?(n.tokens[0].text=e+" "+n.tokens[0].text,n.tokens[0].tokens&&n.tokens[0].tokens.length>0&&"text"===n.tokens[0].tokens[0].type&&(n.tokens[0].tokens[0].text=e+" "+n.tokens[0].tokens[0].text)):n.tokens.unshift({type:"text",text:e+" "}):a+=e+" "}a+=this.parse(n.tokens,r),o+=this.renderer.listitem(a,i,!!s)}n+=this.renderer.list(o,t,s);continue}case"html":{const e=i;n+=this.renderer.html(e.text,e.block);continue}case"paragraph":{const e=i;n+=this.renderer.paragraph(this.parseInline(e.tokens));continue}case"text":{let r=i,o=r.tokens?this.parseInline(r.tokens):r.text;for(;s+1<e.length&&"text"===e[s+1].type;)r=e[++s],o+="\n"+(r.tokens?this.parseInline(r.tokens):r.text);n+=t?this.renderer.paragraph(o):o;continue}default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s++){const i=e[s];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const e=this.options.extensions.renderers[i.type].call({parser:this},i);if(!1!==e||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=e||"";continue}}switch(i.type){case"escape":{const e=i;n+=t.text(e.text);break}case"html":{const e=i;n+=t.html(e.text);break}case"link":{const e=i;n+=t.link(e.href,e.title,this.parseInline(e.tokens,t));break}case"image":{const e=i;n+=t.image(e.href,e.title,e.text);break}case"strong":{const e=i;n+=t.strong(this.parseInline(e.tokens,t));break}case"em":{const e=i;n+=t.em(this.parseInline(e.tokens,t));break}case"codespan":{const e=i;n+=t.codespan(e.text);break}case"br":n+=t.br();break;case"del":{const e=i;n+=t.del(this.parseInline(e.tokens,t));break}case"text":{const e=i;n+=t.text(e.text);break}default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}}class oe{options;constructor(t){this.options=t||e.defaults}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}}class ae{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};options=this.setOptions;parse=this.#e(ne.lex,re.parse);parseInline=this.#e(ne.lexInline,re.parseInline);Parser=re;Renderer=se;TextRenderer=ie;Lexer=ne;Tokenizer=m;Hooks=oe;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(this,s)),s.type){case"table":{const e=s;for(const s of e.header)n=n.concat(this.walkTokens(s.tokens,t));for(const s of e.rows)for(const e of s)n=n.concat(this.walkTokens(e.tokens,t));break}case"list":{const e=s;n=n.concat(this.walkTokens(e.items,t));break}default:{const e=s;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(s=>{const i=e[s].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)}),n.extensions=t),e.renderer){const t=this.defaults.renderer||new se(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.renderer[s],r=t[s];t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new m(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,i=e.tokenizer[s],r=t[s];t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new oe;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.hooks[s],r=t[s];oe.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(i.call(t,e)).then(e=>r.call(t,e));const n=i.call(t,e);return r.call(t,n)}:t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return ne.lex(e,t??this.defaults)}parser(e,t){return re.parse(e,t??this.defaults)}#e(e,t){return(n,s)=>{const i={...s},r={...this.defaults,...i};!0===this.defaults.async&&!1===i.async&&(r.silent||console.warn("marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."),r.async=!0);const o=this.#t(!!r.silent,!!r.async);if(null==n)return o(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof n)return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(r.hooks&&(r.hooks.options=r),r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(n):n).then(t=>e(t,r)).then(e=>r.hooks?r.hooks.processAllTokens(e):e).then(e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then(()=>e):e).then(e=>t(e,r)).then(e=>r.hooks?r.hooks.postprocess(e):e).catch(o);try{r.hooks&&(n=r.hooks.preprocess(n));let s=e(n,r);r.hooks&&(s=r.hooks.processAllTokens(s)),r.walkTokens&&this.walkTokens(s,r.walkTokens);let i=t(s,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(e){return o(e)}}}#t(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="<p>An error occurred:</p><pre>"+c(n.message+"",!0)+"</pre>";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const le=new ae;function ce(e,t){return le.parse(e,t)}ce.options=ce.setOptions=function(e){return le.setOptions(e),ce.defaults=le.defaults,n(ce.defaults),ce},ce.getDefaults=t,ce.defaults=e.defaults,ce.use=function(...e){return le.use(...e),ce.defaults=le.defaults,n(ce.defaults),ce},ce.walkTokens=function(e,t){return le.walkTokens(e,t)},ce.parseInline=le.parseInline,ce.Parser=re,ce.parser=re.parse,ce.Renderer=se,ce.TextRenderer=ie,ce.Lexer=ne,ce.lexer=ne.lex,ce.Tokenizer=m,ce.Hooks=oe,ce.parse=ce;const he=ce.options,de=ce.setOptions,pe=ce.use,ue=ce.walkTokens,ge=ce.parseInline,ke=ce,fe=re.parse,we=ne.lex;e.Hooks=oe,e.Lexer=ne,e.Marked=ae,e.Parser=re,e.Renderer=se,e.TextRenderer=ie,e.Tokenizer=m,e.getDefaults=t,e.lexer=we,e.marked=ce,e.options=he,e.parse=ke,e.parseInline=ge,e.parser=fe,e.setOptions=de,e.use=pe,e.walkTokens=ue},"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).marked={});class a{constructor(e){this.apiKey=e.apiKey,this.baseUrl=e.baseUrl||"https://api.content-growth.com",this.cache=new Map,this.cacheTTL=3e5}async fetchArticles(e={}){const{page:t=1,limit:n=12,tags:s=[],category:i}=e,r=new URLSearchParams({page:t.toString(),limit:n.toString()});s.length>0&&r.set("tag",s.join(",")),i&&r.set("category",i);const o=`${this.baseUrl}/widget/articles?${r}`,a=o,l=this.getFromCache(a);if(l)return l;try{const e=await fetch(o,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const t=await e.json();return this.setCache(a,t),t}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch articles:",e),e}}async fetchArticle(e){const t=`${this.baseUrl}/widget/articles/${e}`,n=t,s=this.getFromCache(n);if(s)return s;try{const e=await fetch(t,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const s=await e.json();return s.content&&(s.content=o(s.content)),this.setCache(n,s),s}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch article:",e),e}}async fetchArticleBySlug(e){const t=`${this.baseUrl}/widget/articles/slug/${e}`,n=t,s=this.getFromCache(n);if(s)return s;try{const e=await fetch(t,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const s=await e.json();return s.content&&(s.content=o(s.content)),this.setCache(n,s),s}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch article by slug:",e),e}}getFromCache(e){const t=this.cache.get(e);if(!t)return null;return Date.now()-t.timestamp>this.cacheTTL?(this.cache.delete(e),null):t.data}setCache(e,t){this.cache.set(e,{data:t,timestamp:Date.now()})}clearCache(){this.cache.clear()}}class l{constructor(e,t={}){this.article=e,this.displayMode=t.displayMode||"compact",this.viewerMode=t.viewerMode||"inline",this.externalUrlPattern=t.externalUrlPattern||"/article/{id}",this.externalTarget=t.externalTarget||"article-{id}",this.onExpand=t.onExpand||null,this.onClick=t.onClick||null,this.aiSummaryMaxBytes=t.aiSummaryMaxBytes}render(){const e="expanded"===this.displayMode?"expanded":"compact";if("external"===this.viewerMode){const t=document.createElement("a");t.className=`cg-card cg-card--${this.displayMode}`,t.dataset.contentId=this.article.uuid;let n=this.externalUrlPattern.replace("{id}",this.article.uuid).replace("{slug}",this.article.slug||this.article.uuid),s=this.externalTarget.replace("{id}",this.article.uuid).replace("{slug}",this.article.slug||this.article.uuid);t.href=n,t.target=s,t.rel="noopener",t.innerHTML="compact"===e?this.renderCompact():this.renderExpanded();const i=t.querySelector(".cg-expand-btn");return i&&this.onExpand&&i.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.onExpand(this.article,t)}),t}const t=document.createElement("article");t.className=`cg-card cg-card--${this.displayMode}`,t.dataset.contentId=this.article.uuid,t.innerHTML="compact"===e?this.renderCompact():this.renderExpanded(),t.addEventListener("click",e=>{e.target.closest(".cg-expand-btn")||this.onClick&&this.onClick(this.article)});const n=t.querySelector(".cg-expand-btn");return n&&this.onExpand&&n.addEventListener("click",e=>{e.stopPropagation(),this.onExpand(this.article,t)}),t}renderCompact(){const e=i(this.article.wordCount);return`\n <div class="cg-card-header">\n <h3 class="cg-card-title">${r(this.article.title)}</h3>\n <button class="cg-expand-btn" aria-label="Show more" title="Show summary">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n </div>\n <div class="cg-card-meta">\n <span class="cg-meta-item cg-author">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <path d="M7 7C8.65685 7 10 5.65685 10 4C10 2.34315 8.65685 1 7 1C5.34315 1 4 2.34315 4 4C4 5.65685 5.34315 7 7 7Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M13 13C13 10.7909 10.3137 9 7 9C3.68629 9 1 10.7909 1 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item cg-date">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <rect x="1" y="2" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M4 1V3M10 1V3M1 5H13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item cg-reading-time">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M7 3.5V7L9.5 9.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n `}renderExpanded(){const e=i(this.article.wordCount),t=this.article.summary||"",n=this.aiSummaryMaxBytes?function(e,t){if(!e||!t||t<=0)return e||"";const n=new TextEncoder;if(n.encode(e).length<=t)return e;let s=0,i=e.length;for(;s<i;){const r=Math.floor((s+i+1)/2),o=e.slice(0,r);n.encode(o).length<=t?s=r:i=r-1}return e.slice(0,s).trimEnd()+"..."}(t,this.aiSummaryMaxBytes):t,o=this.article.tags||[];return`\n <div class="cg-card-header">\n <h3 class="cg-card-title">${r(this.article.title)}</h3>\n <button class="cg-expand-btn cg-expand-btn--collapse" aria-label="Show less" title="Hide summary">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M12 10L8 6L4 10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n </div>\n \n ${n?`\n <div class="cg-card-summary">\n <p>${r(n)}</p>\n </div>\n `:""}\n \n ${o.length>0?`\n <div class="cg-card-tags">\n ${o.map(e=>`\n <span class="cg-tag">${r(e)}</span>\n `).join("")}\n </div>\n `:""}\n \n <div class="cg-card-meta">\n <span class="cg-meta-item cg-author">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <path d="M7 7C8.65685 7 10 5.65685 10 4C10 2.34315 8.65685 1 7 1C5.34315 1 4 2.34315 4 4C4 5.65685 5.34315 7 7 7Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M13 13C13 10.7909 10.3137 9 7 9C3.68629 9 1 10.7909 1 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item cg-date">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <rect x="1" y="2" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M4 1V3M10 1V3M1 5H13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item cg-reading-time">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M7 3.5V7L9.5 9.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n `}}class c{constructor(e,t,n={}){console.log("[ContentList] Constructor called with options:",n),this.container=e,this.api=t,this.options={layoutMode:n.layoutMode||"cards",displayMode:n.displayMode||"comfortable",pageSize:parseInt(n.pageSize)||12,tags:n.tags||[],category:n.category,aiSummaryMaxBytes:n.aiSummaryMaxBytes,viewerMode:n.viewerMode||"inline",externalUrlPattern:n.externalUrlPattern||"/article/{id}",externalTarget:n.externalTarget||"article-{id}",onArticleClick:n.onArticleClick||null},console.log("[ContentList] Final options:",this.options),this.currentPage=1,this.totalPages=1,this.articles=[],this.loading=!1,this.expandedCards=new Set}async init(){console.log("[ContentList] Initializing..."),this.render(),await this.loadArticles(),console.log("[ContentList] Initialization complete")}render(){const e="rows"===this.options.layoutMode?"cg-content-rows":"cg-content-grid";this.container.innerHTML=`\n <div class="cg-content-list">\n <div class="cg-list-header">\n <button class="cg-display-toggle" title="Toggle display mode">\n <svg width="20" height="20" viewBox="0 0 20 20" fill="none">\n <rect x="2" y="2" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n <rect x="2" y="8" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n <rect x="2" y="14" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n </svg>\n <span>${"compact"===this.options.displayMode?"Show summaries":"Hide summaries"}</span>\n </button>\n </div>\n <div class="${e}"></div>\n <div class="cg-pagination"></div>\n </div>\n `;this.container.querySelector(".cg-display-toggle").addEventListener("click",()=>this.toggleDisplayMode())}async loadArticles(e=1){if(this.loading)console.log("[ContentList] Already loading, skipping...");else{console.log("[ContentList] Loading articles for page:",e),this.loading=!0,this.showLoading();try{console.log("[ContentList] Calling api.fetchArticles with:",{page:e,limit:this.options.pageSize,tags:this.options.tags,category:this.options.category});const t=await this.api.fetchArticles({page:e,limit:this.options.pageSize,tags:this.options.tags,category:this.options.category});console.log("[ContentList] Received data:",t),this.articles=t.articles||[],this.currentPage=t.pagination?.page||1,this.totalPages=t.pagination?.totalPages||1,console.log("[ContentList] Loaded",this.articles.length,"articles"),this.renderArticles(),this.renderPagination()}catch(e){console.error("[ContentList] Error loading articles:",e),this.showError("Failed to load articles. Please try again.")}finally{this.loading=!1}}}renderArticles(){const e=this.container.querySelector(".cg-content-grid, .cg-content-rows");0!==this.articles.length?(e.innerHTML="",this.articles.forEach(t=>{const n=this.expandedCards.has(t.uuid),s=new l(t,{displayMode:n?"expanded":this.options.displayMode,viewerMode:this.options.viewerMode,externalUrlPattern:this.options.externalUrlPattern,externalTarget:this.options.externalTarget,aiSummaryMaxBytes:this.options.aiSummaryMaxBytes,onExpand:(e,t)=>this.handleExpand(e,t),onClick:e=>this.handleArticleClick(e)});e.appendChild(s.render())})):e.innerHTML='\n <div class="cg-empty-state">\n <svg width="64" height="64" viewBox="0 0 64 64" fill="none">\n <rect x="8" y="12" width="48" height="40" rx="4" stroke="currentColor" stroke-width="2"/>\n <path d="M16 24H48M16 32H48M16 40H32" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>No articles found</p>\n </div>\n '}handleExpand(e,t){const n=this.expandedCards.has(e.uuid);n?this.expandedCards.delete(e.uuid):this.expandedCards.add(e.uuid);const s=new l(e,{displayMode:n?this.options.displayMode:"expanded",viewerMode:this.options.viewerMode,externalUrlPattern:this.options.externalUrlPattern,externalTarget:this.options.externalTarget,onExpand:(e,t)=>this.handleExpand(e,t),onClick:e=>this.handleArticleClick(e)});t.replaceWith(s.render())}handleArticleClick(e){this.options.onArticleClick&&this.options.onArticleClick(e)}toggleDisplayMode(){this.options.displayMode="compact"===this.options.displayMode?"expanded":"compact",this.expandedCards.clear(),this.renderArticles();this.container.querySelector(".cg-display-toggle span").textContent="compact"===this.options.displayMode?"Show summaries":"Hide summaries"}renderPagination(){const e=this.container.querySelector(".cg-pagination");if(this.totalPages<=1)return void(e.innerHTML="");const t=1===this.currentPage,n=this.currentPage===this.totalPages;e.innerHTML=`\n <button class="cg-btn-prev" ${t?"disabled":""}>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M10 12L6 8L10 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n Previous\n </button>\n <span class="cg-page-info">Page ${this.currentPage} of ${this.totalPages}</span>\n <button class="cg-btn-next" ${n?"disabled":""}>\n Next\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M6 4L10 8L6 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n `;const s=e.querySelector(".cg-btn-prev"),i=e.querySelector(".cg-btn-next");s.addEventListener("click",()=>{this.currentPage>1&&(this.loadArticles(this.currentPage-1),this.scrollToTop())}),i.addEventListener("click",()=>{this.currentPage<this.totalPages&&(this.loadArticles(this.currentPage+1),this.scrollToTop())})}showLoading(){const e=this.container.querySelector(".cg-content-grid, .cg-content-rows");e&&(e.innerHTML='\n <div class="cg-loading">\n <div class="cg-spinner"></div>\n <p>Loading articles...</p>\n </div>\n ')}showError(e){const t=this.container.querySelector(".cg-content-grid, .cg-content-rows");if(t){t.innerHTML=`\n <div class="cg-error">\n <svg width="48" height="48" viewBox="0 0 48 48" fill="none">\n <circle cx="24" cy="24" r="20" stroke="currentColor" stroke-width="2"/>\n <path d="M24 16V26M24 32V32.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>${e}</p>\n <button class="cg-retry-btn">Try Again</button>\n </div>\n `;t.querySelector(".cg-retry-btn").addEventListener("click",()=>this.loadArticles(this.currentPage))}}scrollToTop(){this.container.scrollIntoView({behavior:"smooth",block:"start"})}}class h{constructor(e,t,n={}){this.container=e,this.api=t,this.options={displayMode:n.displayMode||"inline",showBackButton:!1!==n.showBackButton,showSummary:!1!==n.showSummary,onBack:n.onBack||null},this.article=null,this.loading=!1,this.summaryExpanded=!0}async loadArticle(e){if(!this.loading){this.loading=!0,this.showLoading();try{this.article=await this.api.fetchArticle(e),this.render()}catch(e){this.showError("Failed to load article. Please try again."),console.error(e)}finally{this.loading=!1}}}async loadArticleBySlug(e){if(!this.loading){this.loading=!0,this.showLoading();try{this.article=await this.api.fetchArticleBySlug(e),this.render()}catch(e){this.showError("Failed to load article. Please try again."),console.error(e)}finally{this.loading=!1}}}render(){if(!this.article)return;const e=i(this.article.wordCount||this.article.content),t=this.renderMarkdown(this.article.content||"");if(this.container.innerHTML=`\n <div class="cg-content-viewer">\n ${this.options.showBackButton?'\n <div class="cg-viewer-header">\n <button class="cg-back-btn">\n <svg width="20" height="20" viewBox="0 0 20 20" fill="none">\n <path d="M12 16L6 10L12 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n Back to list\n </button>\n </div>\n ':""}\n \n <article class="cg-viewer-content">\n <header class="cg-content-header">\n <h1 class="cg-content-title">${r(this.article.title)}</h1>\n \n ${this.options.showSummary&&this.article.summary&&"announce"!==this.article.category?`\n <div class="cg-ai-summary ${this.summaryExpanded?"expanded":"collapsed"}">\n <div class="cg-ai-summary-header">\n <div class="cg-ai-summary-label">\n <svg class="cg-ai-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />\n </svg>\n <span>AI Generated Summary</span>\n </div>\n <button class="cg-summary-toggle" aria-label="Toggle summary">\n <svg class="cg-chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6l4 4 4-4" />\n </svg>\n </button>\n </div>\n <div class="cg-ai-summary-content">\n <p>${r(this.article.summary)}</p>\n </div>\n </div>\n `:""}\n \n <div class="cg-content-meta">\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M8 8C9.65685 8 11 6.65685 11 5C11 3.34315 9.65685 2 8 2C6.34315 2 5 3.34315 5 5C5 6.65685 6.34315 8 8 8Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M14 14C14 11.7909 11.3137 10 8 10C4.68629 10 2 11.7909 2 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <rect x="2" y="3" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M5 2V4M11 2V4M2 6H14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M8 4V8L10.5 10.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n </header>\n \n <div class="cg-content-body">\n ${t}\n </div>\n </article>\n </div>\n `,this.options.showBackButton){const e=this.container.querySelector(".cg-back-btn");e&&e.addEventListener("click",()=>this.handleBack())}const n=this.container.querySelector(".cg-summary-toggle");n&&n.addEventListener("click",()=>this.toggleSummary())}toggleSummary(){this.summaryExpanded=!this.summaryExpanded;const e=this.container.querySelector(".cg-ai-summary");e&&(this.summaryExpanded?(e.classList.add("expanded"),e.classList.remove("collapsed")):(e.classList.add("collapsed"),e.classList.remove("expanded")))}renderMarkdown(e){marked.setOptions({breaks:!0,gfm:!0,headerIds:!0,mangle:!1});try{return marked.parse(e)}catch(t){return console.error("Markdown parsing error:",t),`<p>${r(e)}</p>`}}handleBack(){this.options.onBack&&this.options.onBack()}showLoading(){this.container.innerHTML='\n <div class="cg-content-viewer">\n <div class="cg-viewer-loading">\n <div class="cg-spinner"></div>\n <p>Loading article...</p>\n </div>\n </div>\n '}showError(e){if(this.container.innerHTML=`\n <div class="cg-content-viewer">\n <div class="cg-viewer-error">\n <svg width="48" height="48" viewBox="0 0 48 48" fill="none">\n <circle cx="24" cy="24" r="20" stroke="currentColor" stroke-width="2"/>\n <path d="M24 16V26M24 32V32.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>${e}</p>\n ${this.options.showBackButton?'<button class="cg-back-btn">Back to articles</button>':""}\n </div>\n </div>\n `,this.options.showBackButton){const e=this.container.querySelector(".cg-back-btn");e&&e.addEventListener("click",()=>this.handleBack())}}clear(){this.container.innerHTML="",this.article=null}}class d{static version="1.2.4";constructor(e,t){if(this.container="string"==typeof e?document.querySelector(e):e,!this.container)throw new Error("Container not found");if(this.config={apiKey:t.apiKey||t["api-key"],baseUrl:t.baseUrl||"https://api.content-growth.com",tags:this.parseTags(t.tags),category:t.category,theme:t.theme||"light",layoutMode:t.layoutMode||t["layout-mode"]||"cards",displayMode:t.displayMode||t["display-mode"]||"comfortable",aiSummaryMaxBytes:t.aiSummaryMaxBytes||t["ai-summary-max-bytes"],viewerMode:t.viewerMode||t["viewer-mode"]||"inline",externalUrlPattern:t.externalUrlPattern||t["external-url-pattern"]||"/article/{id}",externalTarget:t.externalTarget||t["external-target"]||"article-{id}",pageSize:t.pageSize||t["page-size"]||12,mode:t.mode||"list",articleId:t.articleId||t["article-id"],slug:t.slug},!this.config.apiKey)throw new Error("API key is required");this.api=new a({apiKey:this.config.apiKey,baseUrl:this.config.baseUrl}),this.currentView="list",this.contentList=null,this.contentViewer=null,this.init()}init(){this.container.classList.add("cg-widget"),this.container.setAttribute("data-theme",this.config.theme),"article-only"===this.config.mode?this.config.slug?this.showPostInlineBySlug(this.config.slug):this.config.articleId&&this.showPostInline(this.config.articleId):this.showList()}showList(){this.currentView="list",this.container.innerHTML="";const e=document.createElement("div");e.className="cg-list-view",this.container.appendChild(e),this.contentList=new c(e,this.api,{layoutMode:this.config.layoutMode,displayMode:this.config.displayMode,pageSize:this.config.pageSize,tags:this.config.tags,category:this.config.category,aiSummaryMaxBytes:this.config.aiSummaryMaxBytes,viewerMode:this.config.viewerMode,externalUrlPattern:this.config.externalUrlPattern,externalTarget:this.config.externalTarget,onArticleClick:e=>this.showPost(e.uuid)}),this.contentList.init()}showPost(e){this.currentView="viewer","modal"===this.config.viewerMode?this.showPostModal(e):this.showPostInline(e)}showPostInline(e){this.container.innerHTML="";const t=document.createElement("div");t.className="cg-viewer-view",this.container.appendChild(t);const n="article-only"!==this.config.mode;this.contentViewer=new h(t,this.api,{displayMode:"inline",showBackButton:n,onBack:n?()=>this.showList():null}),this.contentViewer.loadArticle(e)}showPostInlineBySlug(e){this.container.innerHTML="";const t=document.createElement("div");t.className="cg-viewer-view",this.container.appendChild(t);const n="article-only"!==this.config.mode;this.contentViewer=new h(t,this.api,{displayMode:"inline",showBackButton:n,onBack:n?()=>this.showList():null}),this.contentViewer.loadArticleBySlug(e)}showPostModal(e){const t=document.createElement("div");t.className="cg-modal",this.config.theme&&t.setAttribute("data-theme",this.config.theme),t.innerHTML='\n <div class="cg-modal-overlay"></div>\n <div class="cg-modal-content">\n <button class="cg-modal-close" aria-label="Close">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none">\n <path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n <div class="cg-modal-body"></div>\n </div>\n ',document.body.appendChild(t),document.body.style.overflow="hidden";const n=t.querySelector(".cg-modal-body");this.contentViewer=new h(n,this.api,{displayMode:"modal",onBack:()=>this.closeModal(t)}),this.contentViewer.loadArticle(e);const s=t.querySelector(".cg-modal-close"),i=t.querySelector(".cg-modal-overlay"),r=()=>this.closeModal(t);s.addEventListener("click",r),i.addEventListener("click",r);const o=e=>{"Escape"===e.key&&(r(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o),requestAnimationFrame(()=>{t.classList.add("cg-modal--active")})}closeModal(e){e.classList.remove("cg-modal--active"),setTimeout(()=>{e.remove(),document.body.style.overflow=""},300)}parseTags(e){return e?Array.isArray(e)?e:e.split(",").map(e=>e.trim()).filter(Boolean):[]}updateConfig(e){Object.assign(this.config,e),this.init()}destroy(){this.container.innerHTML="",this.container.classList.remove("cg-widget"),this.container.removeAttribute("data-theme")}}function p(){document.querySelectorAll("[data-cg-content]").forEach((t,n)=>{const s={apiKey:t.dataset.apiKey||t.dataset.cgApiKey,baseUrl:e.WIDGET_BASE_URL||t.dataset.baseUrl||t.dataset.cgBaseUrl,tags:t.dataset.tags||t.dataset.cgTags,theme:t.dataset.theme||t.dataset.cgTheme||"light",layoutMode:t.dataset.layoutMode||t.dataset.cgLayoutMode||"cards",displayMode:t.dataset.displayMode||t.dataset.cgDisplayMode||"comfortable",viewerMode:t.dataset.viewerMode||t.dataset.cgViewerMode||"inline",externalUrlPattern:t.dataset.externalUrlPattern||t.dataset.cgExternalUrlPattern,externalTarget:t.dataset.externalTarget||t.dataset.cgExternalTarget,pageSize:t.dataset.pageSize||t.dataset.cgPageSize||12,mode:t.dataset.mode||t.dataset.cgMode||"list",articleId:t.dataset.articleId||t.dataset.cgArticleId};try{new d(t,s)}catch(e){console.error(`[Widget ${n}] Failed to initialize:`,e),t.innerHTML=`\n <div style="padding: 2rem; text-align: center; color: #ef4444;">\n <p>Failed to load widget: ${e.message}</p>\n <p style="font-size: 0.875rem; margin-top: 0.5rem;">Check console for details</p>\n </div>\n `}})}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",p):p(),e.ContentGrowthWidget=d,e.ContentGrowthWidget=d,console.log("[ContentGrowthWidget] Loaded successfully v1.2.4")}(window);
1
+ !function(e){"use strict";var t,n;function s(e){return new Date(1e3*e).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}function i(e){if(!e)return"Unknown";let t;if("number"==typeof e){if(t=e,0===t)return"Unknown"}else t=e.trim().split(/\s+/).filter(e=>e.length>0).length;return`${Math.ceil(t/200)} min read`}function r(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function o(e){return e?e.replace(/!\[([^\]]*)\]\(([^\s)]+)\s*=(\d+)x(\d*)\)/g,(e,t,n,s,i)=>`![${t}](${n})`):e}t=this,n=function(e){function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function n(t){e.defaults=t}e.defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};const s=/[&<>"']/,i=new RegExp(s.source,"g"),r=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,o=new RegExp(r.source,"g"),a={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},l=e=>a[e];function c(e,t){if(t){if(s.test(e))return e.replace(i,l)}else if(r.test(e))return e.replace(o,l);return e}const h=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function d(e){return e.replace(h,(e,t)=>"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):"")}const p=/(^|[^\[])\^/g;function u(e,t){let n="string"==typeof e?e:e.source;t=t||"";const s={replace:(e,t)=>{let i="string"==typeof t?t:t.source;return i=i.replace(p,"$1"),n=n.replace(e,i),s},getRegex:()=>new RegExp(n,t)};return s}function g(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return null}return e}const k={exec:()=>null};function f(e,t){const n=e.replace(/\|/g,(e,t,n)=>{let s=!1,i=t;for(;--i>=0&&"\\"===n[i];)s=!s;return s?"|":" |"}).split(/ \|/);let s=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;s<n.length;s++)n[s]=n[s].trim().replace(/\\\|/g,"|");return n}function w(e,t,n){const s=e.length;if(0===s)return"";let i=0;for(;i<s;){const r=e.charAt(s-i-1);if(r!==t||n){if(r===t||!n)break;i++}else i++}return e.slice(0,s-i)}function x(e,t,n,s){const i=t.href,r=t.title?c(t.title):null,o=e[1].replace(/\\([\[\]])/g,"$1");if("!"!==e[0].charAt(0)){s.state.inLink=!0;const e={type:"link",raw:n,href:i,title:r,text:o,tokens:s.inlineTokens(o)};return s.state.inLink=!1,e}return{type:"image",raw:n,href:i,title:r,text:c(o)}}class m{options;rules;lexer;constructor(t){this.options=t||e.defaults}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:w(e,"\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n=function(e,t){const n=e.match(/^(\s+)(?:```)/);if(null===n)return t;const s=n[1];return t.split("\n").map(e=>{const t=e.match(/^\s+/);if(null===t)return e;const[n]=t;return n.length>=s.length?e.slice(s.length):e}).join("\n")}(e,t[3]||"");return{type:"code",raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:n}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(/#$/.test(e)){const t=w(e,"#");this.options.pedantic?e=t.trim():t&&!/ $/.test(t)||(e=t.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){const e=w(t[0].replace(/^ *>[ \t]?/gm,""),"\n"),n=this.lexer.state.top;this.lexer.state.top=!0;const s=this.lexer.blockTokens(e);return this.lexer.state.top=n,{type:"blockquote",raw:t[0],tokens:s,text:e}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim();const s=n.length>1,i={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");const r=new RegExp(`^( {0,3}${n})((?:[\t ][^\\n]*)?(?:\\n|$))`);let o="",a="",l=!1;for(;e;){let n=!1;if(!(t=r.exec(e)))break;if(this.rules.block.hr.test(e))break;o=t[0],e=e.substring(o.length);let s=t[2].split("\n",1)[0].replace(/^\t+/,e=>" ".repeat(3*e.length)),c=e.split("\n",1)[0],h=0;this.options.pedantic?(h=2,a=s.trimStart()):(h=t[2].search(/[^ ]/),h=h>4?1:h,a=s.slice(h),h+=t[1].length);let d=!1;if(!s&&/^ *$/.test(c)&&(o+=c+"\n",e=e.substring(c.length+1),n=!0),!n){const t=new RegExp(`^ {0,${Math.min(3,h-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),n=new RegExp(`^ {0,${Math.min(3,h-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),i=new RegExp(`^ {0,${Math.min(3,h-1)}}(?:\`\`\`|~~~)`),r=new RegExp(`^ {0,${Math.min(3,h-1)}}#`);for(;e;){const l=e.split("\n",1)[0];if(c=l,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),i.test(c))break;if(r.test(c))break;if(t.test(c))break;if(n.test(e))break;if(c.search(/[^ ]/)>=h||!c.trim())a+="\n"+c.slice(h);else{if(d)break;if(s.search(/[^ ]/)>=4)break;if(i.test(s))break;if(r.test(s))break;if(n.test(s))break;a+="\n"+c}d||c.trim()||(d=!0),o+=l+"\n",e=e.substring(l.length+1),s=c.slice(h)}}i.loose||(l?i.loose=!0:/\n *\n *$/.test(o)&&(l=!0));let p,u=null;this.options.gfm&&(u=/^\[[ xX]\] /.exec(a),u&&(p="[ ] "!==u[0],a=a.replace(/^\[[ xX]\] +/,""))),i.items.push({type:"list_item",raw:o,task:!!u,checked:p,loose:!1,text:a,tokens:[]}),i.raw+=o}i.items[i.items.length-1].raw=o.trimEnd(),i.items[i.items.length-1].text=a.trimEnd(),i.raw=i.raw.trimEnd();for(let e=0;e<i.items.length;e++)if(this.lexer.state.top=!1,i.items[e].tokens=this.lexer.blockTokens(i.items[e].text,[]),!i.loose){const t=i.items[e].tokens.filter(e=>"space"===e.type),n=t.length>0&&t.some(e=>/\n.*\n/.test(e.raw));i.loose=n}if(i.loose)for(let e=0;e<i.items.length;e++)i.items[e].loose=!0;return i}}html(e){const t=this.rules.block.html.exec(e);if(t)return{type:"html",block:!0,raw:t[0],pre:"pre"===t[1]||"script"===t[1]||"style"===t[1],text:t[0]}}def(e){const t=this.rules.block.def.exec(e);if(t){const e=t[1].toLowerCase().replace(/\s+/g," "),n=t[2]?t[2].replace(/^<(.*)>$/,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",s=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:e,raw:t[0],href:n,title:s}}}table(e){const t=this.rules.block.table.exec(e);if(!t)return;if(!/[:|]/.test(t[2]))return;const n=f(t[1]),s=t[2].replace(/^\||\| *$/g,"").split("|"),i=t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[],r={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===s.length){for(const e of s)/^ *-+: *$/.test(e)?r.align.push("right"):/^ *:-+: *$/.test(e)?r.align.push("center"):/^ *:-+ *$/.test(e)?r.align.push("left"):r.align.push(null);for(const e of n)r.header.push({text:e,tokens:this.lexer.inline(e)});for(const e of i)r.rows.push(f(e,r.header.length).map(e=>({text:e,tokens:this.lexer.inline(e)})));return r}}lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:"="===t[2].charAt(0)?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e="\n"===t[1].charAt(t[1].length-1)?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:e,tokens:this.lexer.inline(e)}}}text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:c(t[1])}}tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&/^<a /i.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&/^<\/a>/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&/^</.test(e)){if(!/>$/.test(e))return;const t=w(e.slice(0,-1),"\\");if((e.length-t.length)%2==0)return}else{const e=function(e,t){if(-1===e.indexOf(t[1]))return-1;let n=0;for(let s=0;s<e.length;s++)if("\\"===e[s])s++;else if(e[s]===t[0])n++;else if(e[s]===t[1]&&(n--,n<0))return s;return-1}(t[2],"()");if(e>-1){const n=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=""}}let n=t[2],s="";if(this.options.pedantic){const e=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);e&&(n=e[1],s=e[3])}else s=t[3]?t[3].slice(1,-1):"";return n=n.trim(),/^</.test(n)&&(n=this.options.pedantic&&!/>$/.test(e)?n.slice(1):n.slice(1,-1)),x(t,{href:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n,title:s?s.replace(this.rules.inline.anyPunctuation,"$1"):s},t[0],this.lexer)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const e=t[(n[2]||n[1]).replace(/\s+/g," ").toLowerCase()];if(!e){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return x(n,e,n[0],this.lexer)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(s&&(!s[3]||!n.match(/[\p{L}\p{N}]/u))&&(!s[1]&&!s[2]||!n||this.rules.inline.punctuation.exec(n))){const n=[...s[0]].length-1;let i,r,o=n,a=0;const l="*"===s[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(l.lastIndex=0,t=t.slice(-1*e.length+n);null!=(s=l.exec(t));){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i)continue;if(r=[...i].length,s[3]||s[4]){o+=r;continue}if((s[5]||s[6])&&n%3&&!((n+r)%3)){a+=r;continue}if(o-=r,o>0)continue;r=Math.min(r,r+o+a);const t=[...s[0]][0].length,l=e.slice(0,n+s.index+t+r);if(Math.min(n,r)%2){const e=l.slice(1,-1);return{type:"em",raw:l,text:e,tokens:this.lexer.inlineTokens(e)}}const c=l.slice(2,-2);return{type:"strong",raw:l,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(/\n/g," ");const n=/[^ ]/.test(e),s=/^ /.test(e)&&/ $/.test(e);return n&&s&&(e=e.substring(1,e.length-1)),e=c(e,!0),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;return"@"===t[2]?(e=c(t[1]),n="mailto:"+e):(e=c(t[1]),n=e),{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2])e=c(t[0]),n="mailto:"+e;else{let s;do{s=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??""}while(s!==t[0]);e=c(t[0]),n="www."===t[1]?"http://"+t[0]:t[0]}return{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e){const t=this.rules.inline.text.exec(e);if(t){let e;return e=this.lexer.state.inRawBlock?t[0]:c(t[0]),{type:"text",raw:t[0],text:e}}}}const y=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,b=/(?:[*+-]|\d{1,9}[.)])/,v=u(/^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g,b).getRegex(),$=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,M=/(?!\s*\])(?:\\.|[^\[\]\\])+/,C=u(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/).replace("label",M).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),T=u(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,b).getRegex(),L="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",S=/<!--(?!-?>)[\s\S]*?(?:-->|$)/,A=u("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))","i").replace("comment",S).replace("tag",L).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),E=u($).replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex(),z={blockquote:u(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",E).getRegex(),code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,def:C,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:y,html:A,lheading:v,list:T,newline:/^(?: *(?:\n|$))+/,paragraph:E,table:k,text:/^[^\n]+/},B=u("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex(),P={...z,table:B,paragraph:u($).replace("hr",y).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",B).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",L).getRegex()},I={...z,html:u("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",S).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:k,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:u($).replace("hr",y).replace("heading"," *#{1,6} *[^\n]").replace("lheading",v).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},R=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,_=/^( {2,}|\\)\n(?!\s*$)/,q="\\p{P}$+<=>`^|~",U=u(/^((?![*_])[\spunctuation])/,"u").replace(/punctuation/g,q).getRegex(),H=u(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,"u").replace(/punct/g,q).getRegex(),Z=u("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])","gu").replace(/punct/g,q).getRegex(),V=u("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])","gu").replace(/punct/g,q).getRegex(),D=u(/\\([punct])/,"gu").replace(/punct/g,q).getRegex(),F=u(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),K=u(S).replace("(?:--\x3e|$)","--\x3e").getRegex(),Q=u("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",K).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),j=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,O=u(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",j).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),N=u(/^!?\[(label)\]\[(ref)\]/).replace("label",j).replace("ref",M).getRegex(),G=u(/^!?\[(ref)\](?:\[\])?/).replace("ref",M).getRegex(),W={_backpedal:k,anyPunctuation:D,autolink:F,blockSkip:/\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g,br:_,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:k,emStrongLDelim:H,emStrongRDelimAst:Z,emStrongRDelimUnd:V,escape:R,link:O,nolink:G,punctuation:U,reflink:N,reflinkSearch:u("reflink|nolink(?!\\()","g").replace("reflink",N).replace("nolink",G).getRegex(),tag:Q,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,url:k},X={...W,link:u(/^!?\[(label)\]\((.*?)\)/).replace("label",j).getRegex(),reflink:u(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",j).getRegex()},J={...W,escape:u(R).replace("])","~|])").getRegex(),url:u(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/},Y={...J,br:u(_).replace("{2,}","*").getRegex(),text:u(J.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},ee={normal:z,gfm:P,pedantic:I},te={normal:W,gfm:J,breaks:Y,pedantic:X};class ne{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||e.defaults,this.options.tokenizer=this.options.tokenizer||new m,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const n={block:ee.normal,inline:te.normal};this.options.pedantic?(n.block=ee.pedantic,n.inline=te.pedantic):this.options.gfm&&(n.block=ee.gfm,this.options.breaks?n.inline=te.breaks:n.inline=te.gfm),this.tokenizer.rules=n}static get rules(){return{block:ee,inline:te}}static lex(e,t){return new ne(t).lex(e)}static lexInline(e,t){return new ne(t).inlineTokens(e)}lex(e){e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){const t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[]){let n,s,i,r;for(e=this.options.pedantic?e.replace(/\t/g," ").replace(/^ +$/gm,""):e.replace(/^( *)(\t+)/gm,(e,t,n)=>t+" ".repeat(n.length));e;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some(s=>!!(n=s.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.space(e))e=e.substring(n.raw.length),1===n.raw.length&&t.length>0?t[t.length-1].raw+="\n":t.push(n);else if(n=this.tokenizer.code(e))e=e.substring(n.raw.length),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?t.push(n):(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=s.text);else if(n=this.tokenizer.fences(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.heading(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.hr(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.blockquote(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.list(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.html(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.def(e))e=e.substring(n.raw.length),s=t[t.length-1],!s||"paragraph"!==s.type&&"text"!==s.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(s.raw+="\n"+n.raw,s.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=s.text);else if(n=this.tokenizer.table(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.lheading(e))e=e.substring(n.raw.length),t.push(n);else{if(i=e,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startBlock.forEach(e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))}),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(this.state.top&&(n=this.tokenizer.paragraph(i)))s=t[t.length-1],r&&"paragraph"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.text):t.push(n),r=i.length!==e.length,e=e.substring(n.raw.length);else if(n=this.tokenizer.text(e))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===s.type?(s.raw+="\n"+n.raw,s.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=s.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n,s,i,r,o,a,l=e;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(r=this.tokenizer.rules.inline.reflinkSearch.exec(l));)e.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(l=l.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(r=this.tokenizer.rules.inline.blockSkip.exec(l));)l=l.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(r=this.tokenizer.rules.inline.anyPunctuation.exec(l));)l=l.slice(0,r.index)+"++"+l.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;e;)if(o||(a=""),o=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some(s=>!!(n=s.call({lexer:this},e,t))&&(e=e.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.escape(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.tag(e))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(n=this.tokenizer.link(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(n.raw.length),s=t[t.length-1],s&&"text"===n.type&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(n=this.tokenizer.emStrong(e,l,a))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.codespan(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.br(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.del(e))e=e.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.autolink(e))e=e.substring(n.raw.length),t.push(n);else if(this.state.inLink||!(n=this.tokenizer.url(e))){if(i=e,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startInline.forEach(e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))}),t<1/0&&t>=0&&(i=e.substring(0,t+1))}if(n=this.tokenizer.inlineText(i))e=e.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(a=n.raw.slice(-1)),o=!0,s=t[t.length-1],s&&"text"===s.type?(s.raw+=n.raw,s.text+=n.text):t.push(n);else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}else e=e.substring(n.raw.length),t.push(n);return t}}class se{options;constructor(t){this.options=t||e.defaults}code(e,t,n){const s=(t||"").match(/^\S*/)?.[0];return e=e.replace(/\n$/,"")+"\n",s?'<pre><code class="language-'+c(s)+'">'+(n?e:c(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:c(e,!0))+"</code></pre>\n"}blockquote(e){return`<blockquote>\n${e}</blockquote>\n`}html(e,t){return e}heading(e,t,n){return`<h${t}>${e}</h${t}>\n`}hr(){return"<hr>\n"}list(e,t,n){const s=t?"ol":"ul";return"<"+s+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"</"+s+">\n"}listitem(e,t,n){return`<li>${e}</li>\n`}checkbox(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph(e){return`<p>${e}</p>\n`}table(e,t){return t&&(t=`<tbody>${t}</tbody>`),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"}tablerow(e){return`<tr>\n${e}</tr>\n`}tablecell(e,t){const n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong(e){return`<strong>${e}</strong>`}em(e){return`<em>${e}</em>`}codespan(e){return`<code>${e}</code>`}br(){return"<br>"}del(e){return`<del>${e}</del>`}link(e,t,n){const s=g(e);if(null===s)return n;let i='<a href="'+(e=s)+'"';return t&&(i+=' title="'+t+'"'),i+=">"+n+"</a>",i}image(e,t,n){const s=g(e);if(null===s)return n;let i=`<img src="${e=s}" alt="${n}"`;return t&&(i+=` title="${t}"`),i+=">",i}text(e){return e}}class ie{strong(e){return e}em(e){return e}codespan(e){return e}del(e){return e}html(e){return e}text(e){return e}link(e,t,n){return""+n}image(e,t,n){return""+n}br(){return""}}class re{options;renderer;textRenderer;constructor(t){this.options=t||e.defaults,this.options.renderer=this.options.renderer||new se,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ie}static parse(e,t){return new re(t).parse(e)}static parseInline(e,t){return new re(t).parseInline(e)}parse(e,t=!0){let n="";for(let s=0;s<e.length;s++){const i=e[s];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const e=i,t=this.options.extensions.renderers[e.type].call({parser:this},e);if(!1!==t||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(e.type)){n+=t||"";continue}}switch(i.type){case"space":continue;case"hr":n+=this.renderer.hr();continue;case"heading":{const e=i;n+=this.renderer.heading(this.parseInline(e.tokens),e.depth,d(this.parseInline(e.tokens,this.textRenderer)));continue}case"code":{const e=i;n+=this.renderer.code(e.text,e.lang,!!e.escaped);continue}case"table":{const e=i;let t="",s="";for(let t=0;t<e.header.length;t++)s+=this.renderer.tablecell(this.parseInline(e.header[t].tokens),{header:!0,align:e.align[t]});t+=this.renderer.tablerow(s);let r="";for(let t=0;t<e.rows.length;t++){const n=e.rows[t];s="";for(let t=0;t<n.length;t++)s+=this.renderer.tablecell(this.parseInline(n[t].tokens),{header:!1,align:e.align[t]});r+=this.renderer.tablerow(s)}n+=this.renderer.table(t,r);continue}case"blockquote":{const e=i,t=this.parse(e.tokens);n+=this.renderer.blockquote(t);continue}case"list":{const e=i,t=e.ordered,s=e.start,r=e.loose;let o="";for(let t=0;t<e.items.length;t++){const n=e.items[t],s=n.checked,i=n.task;let a="";if(n.task){const e=this.renderer.checkbox(!!s);r?n.tokens.length>0&&"paragraph"===n.tokens[0].type?(n.tokens[0].text=e+" "+n.tokens[0].text,n.tokens[0].tokens&&n.tokens[0].tokens.length>0&&"text"===n.tokens[0].tokens[0].type&&(n.tokens[0].tokens[0].text=e+" "+n.tokens[0].tokens[0].text)):n.tokens.unshift({type:"text",text:e+" "}):a+=e+" "}a+=this.parse(n.tokens,r),o+=this.renderer.listitem(a,i,!!s)}n+=this.renderer.list(o,t,s);continue}case"html":{const e=i;n+=this.renderer.html(e.text,e.block);continue}case"paragraph":{const e=i;n+=this.renderer.paragraph(this.parseInline(e.tokens));continue}case"text":{let r=i,o=r.tokens?this.parseInline(r.tokens):r.text;for(;s+1<e.length&&"text"===e[s+1].type;)r=e[++s],o+="\n"+(r.tokens?this.parseInline(r.tokens):r.text);n+=t?this.renderer.paragraph(o):o;continue}default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}parseInline(e,t){t=t||this.renderer;let n="";for(let s=0;s<e.length;s++){const i=e[s];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const e=this.options.extensions.renderers[i.type].call({parser:this},i);if(!1!==e||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=e||"";continue}}switch(i.type){case"escape":{const e=i;n+=t.text(e.text);break}case"html":{const e=i;n+=t.html(e.text);break}case"link":{const e=i;n+=t.link(e.href,e.title,this.parseInline(e.tokens,t));break}case"image":{const e=i;n+=t.image(e.href,e.title,e.text);break}case"strong":{const e=i;n+=t.strong(this.parseInline(e.tokens,t));break}case"em":{const e=i;n+=t.em(this.parseInline(e.tokens,t));break}case"codespan":{const e=i;n+=t.codespan(e.text);break}case"br":n+=t.br();break;case"del":{const e=i;n+=t.del(this.parseInline(e.tokens,t));break}case"text":{const e=i;n+=t.text(e.text);break}default:{const e='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(e),"";throw new Error(e)}}}return n}}class oe{options;constructor(t){this.options=t||e.defaults}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}}class ae{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};options=this.setOptions;parse=this.#e(ne.lex,re.parse);parseInline=this.#e(ne.lexInline,re.parseInline);Parser=re;Renderer=se;TextRenderer=ie;Lexer=ne;Tokenizer=m;Hooks=oe;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(const s of e)switch(n=n.concat(t.call(this,s)),s.type){case"table":{const e=s;for(const s of e.header)n=n.concat(this.walkTokens(s.tokens,t));for(const s of e.rows)for(const e of s)n=n.concat(this.walkTokens(e.tokens,t));break}case"list":{const e=s;n=n.concat(this.walkTokens(e.items,t));break}default:{const e=s;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(s=>{const i=e[s].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)}),n.extensions=t),e.renderer){const t=this.defaults.renderer||new se(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.renderer[s],r=t[s];t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new m(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,i=e.tokenizer[s],r=t[s];t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new oe;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if("options"===n)continue;const s=n,i=e.hooks[s],r=t[s];oe.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(i.call(t,e)).then(e=>r.call(t,e));const n=i.call(t,e);return r.call(t,n)}:t[s]=(...e)=>{let n=i.apply(t,e);return!1===n&&(n=r.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return ne.lex(e,t??this.defaults)}parser(e,t){return re.parse(e,t??this.defaults)}#e(e,t){return(n,s)=>{const i={...s},r={...this.defaults,...i};!0===this.defaults.async&&!1===i.async&&(r.silent||console.warn("marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."),r.async=!0);const o=this.#t(!!r.silent,!!r.async);if(null==n)return o(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof n)return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(r.hooks&&(r.hooks.options=r),r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(n):n).then(t=>e(t,r)).then(e=>r.hooks?r.hooks.processAllTokens(e):e).then(e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then(()=>e):e).then(e=>t(e,r)).then(e=>r.hooks?r.hooks.postprocess(e):e).catch(o);try{r.hooks&&(n=r.hooks.preprocess(n));let s=e(n,r);r.hooks&&(s=r.hooks.processAllTokens(s)),r.walkTokens&&this.walkTokens(s,r.walkTokens);let i=t(s,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(e){return o(e)}}}#t(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="<p>An error occurred:</p><pre>"+c(n.message+"",!0)+"</pre>";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const le=new ae;function ce(e,t){return le.parse(e,t)}ce.options=ce.setOptions=function(e){return le.setOptions(e),ce.defaults=le.defaults,n(ce.defaults),ce},ce.getDefaults=t,ce.defaults=e.defaults,ce.use=function(...e){return le.use(...e),ce.defaults=le.defaults,n(ce.defaults),ce},ce.walkTokens=function(e,t){return le.walkTokens(e,t)},ce.parseInline=le.parseInline,ce.Parser=re,ce.parser=re.parse,ce.Renderer=se,ce.TextRenderer=ie,ce.Lexer=ne,ce.lexer=ne.lex,ce.Tokenizer=m,ce.Hooks=oe,ce.parse=ce;const he=ce.options,de=ce.setOptions,pe=ce.use,ue=ce.walkTokens,ge=ce.parseInline,ke=ce,fe=re.parse,we=ne.lex;e.Hooks=oe,e.Lexer=ne,e.Marked=ae,e.Parser=re,e.Renderer=se,e.TextRenderer=ie,e.Tokenizer=m,e.getDefaults=t,e.lexer=we,e.marked=ce,e.options=he,e.parse=ke,e.parseInline=ge,e.parser=fe,e.setOptions=de,e.use=pe,e.walkTokens=ue},"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).marked={});class a{constructor(e){this.apiKey=e.apiKey,this.baseUrl=e.baseUrl||"https://api.content-growth.com",this.cache=new Map,this.cacheTTL=3e5}async fetchArticles(e={}){const{page:t=1,limit:n=12,tags:s=[],category:i}=e,r=new URLSearchParams({page:t.toString(),limit:n.toString()});s.length>0&&r.set("tag",s.join(",")),i&&r.set("category",i);const o=`${this.baseUrl}/widget/articles?${r}`,a=o,l=this.getFromCache(a);if(l)return l;try{const e=await fetch(o,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const t=await e.json();return this.setCache(a,t),t}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch articles:",e),e}}async fetchArticle(e){const t=`${this.baseUrl}/widget/articles/${e}`,n=t,s=this.getFromCache(n);if(s)return s;try{const e=await fetch(t,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const s=await e.json();return s.content&&(s.content=o(s.content)),this.setCache(n,s),s}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch article:",e),e}}async fetchArticleBySlug(e){const t=`${this.baseUrl}/widget/articles/slug/${e}`,n=t,s=this.getFromCache(n);if(s)return s;try{const e=await fetch(t,{headers:{"X-API-Key":this.apiKey}});if(!e.ok){const t=await e.text();throw console.error("[ContentGrowthAPI] Error response body:",t),new Error(`API Error: ${e.status} ${e.statusText}`)}const s=await e.json();return s.content&&(s.content=o(s.content)),this.setCache(n,s),s}catch(e){throw console.error("[ContentGrowthAPI] Failed to fetch article by slug:",e),e}}getFromCache(e){const t=this.cache.get(e);if(!t)return null;return Date.now()-t.timestamp>this.cacheTTL?(this.cache.delete(e),null):t.data}setCache(e,t){this.cache.set(e,{data:t,timestamp:Date.now()})}clearCache(){this.cache.clear()}}class l{constructor(e,t={}){this.article=e,this.displayMode=t.displayMode||"compact",this.viewerMode=t.viewerMode||"inline",this.externalUrlPattern=t.externalUrlPattern||"/article/{id}",this.externalTarget=t.externalTarget||"article-{id}",this.onExpand=t.onExpand||null,this.onClick=t.onClick||null,this.aiSummaryMaxBytes=t.aiSummaryMaxBytes}render(){const e="expanded"===this.displayMode?"expanded":"compact";if("external"===this.viewerMode){const t=document.createElement("a");t.className=`cg-card cg-card--${this.displayMode}`,t.dataset.contentId=this.article.uuid;let n=this.externalUrlPattern.replace("{id}",this.article.uuid).replace("{slug}",this.article.slug||this.article.uuid),s=this.externalTarget.replace("{id}",this.article.uuid).replace("{slug}",this.article.slug||this.article.uuid);t.href=n,t.target=s,t.rel="noopener",t.innerHTML="compact"===e?this.renderCompact():this.renderExpanded();const i=t.querySelector(".cg-expand-btn");return i&&this.onExpand&&i.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.onExpand(this.article,t)}),t}const t=document.createElement("article");t.className=`cg-card cg-card--${this.displayMode}`,t.dataset.contentId=this.article.uuid,t.innerHTML="compact"===e?this.renderCompact():this.renderExpanded(),t.addEventListener("click",e=>{e.target.closest(".cg-expand-btn")||this.onClick&&this.onClick(this.article)});const n=t.querySelector(".cg-expand-btn");return n&&this.onExpand&&n.addEventListener("click",e=>{e.stopPropagation(),this.onExpand(this.article,t)}),t}renderCompact(){const e=i(this.article.wordCount);return`\n <div class="cg-card-header">\n <h3 class="cg-card-title">${r(this.article.title)}</h3>\n <button class="cg-expand-btn" aria-label="Show more" title="Show summary">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M4 6L8 10L12 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n </div>\n <div class="cg-card-meta">\n <span class="cg-meta-item cg-author">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <path d="M7 7C8.65685 7 10 5.65685 10 4C10 2.34315 8.65685 1 7 1C5.34315 1 4 2.34315 4 4C4 5.65685 5.34315 7 7 7Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M13 13C13 10.7909 10.3137 9 7 9C3.68629 9 1 10.7909 1 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item cg-date">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <rect x="1" y="2" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M4 1V3M10 1V3M1 5H13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item cg-reading-time">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M7 3.5V7L9.5 9.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n `}renderExpanded(){const e=i(this.article.wordCount),t=this.article.summary||"",n=this.aiSummaryMaxBytes?function(e,t){if(!e||!t||t<=0)return e||"";const n=new TextEncoder;if(n.encode(e).length<=t)return e;let s=0,i=e.length;for(;s<i;){const r=Math.floor((s+i+1)/2),o=e.slice(0,r);n.encode(o).length<=t?s=r:i=r-1}return e.slice(0,s).trimEnd()+"..."}(t,this.aiSummaryMaxBytes):t,o=this.article.tags||[];return`\n <div class="cg-card-header">\n <h3 class="cg-card-title">${r(this.article.title)}</h3>\n <button class="cg-expand-btn cg-expand-btn--collapse" aria-label="Show less" title="Hide summary">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M12 10L8 6L4 10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n </div>\n \n ${n?`\n <div class="cg-card-summary">\n <p>${r(n)}</p>\n </div>\n `:""}\n \n ${o.length>0?`\n <div class="cg-card-tags">\n ${o.map(e=>`\n <span class="cg-tag">${r(e)}</span>\n `).join("")}\n </div>\n `:""}\n \n <div class="cg-card-meta">\n <span class="cg-meta-item cg-author">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <path d="M7 7C8.65685 7 10 5.65685 10 4C10 2.34315 8.65685 1 7 1C5.34315 1 4 2.34315 4 4C4 5.65685 5.34315 7 7 7Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M13 13C13 10.7909 10.3137 9 7 9C3.68629 9 1 10.7909 1 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item cg-date">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <rect x="1" y="2" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M4 1V3M10 1V3M1 5H13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item cg-reading-time">\n <svg width="14" height="14" viewBox="0 0 14 14" fill="none">\n <circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M7 3.5V7L9.5 9.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n `}}class c{constructor(e,t,n={}){console.log("[ContentList] Constructor called with options:",n),this.container=e,this.api=t,this.options={layoutMode:n.layoutMode||"cards",displayMode:n.displayMode||"comfortable",pageSize:parseInt(n.pageSize)||12,tags:n.tags||[],category:n.category,aiSummaryMaxBytes:n.aiSummaryMaxBytes,viewerMode:n.viewerMode||"inline",externalUrlPattern:n.externalUrlPattern||"/article/{id}",externalTarget:n.externalTarget||"article-{id}",onArticleClick:n.onArticleClick||null},console.log("[ContentList] Final options:",this.options),this.currentPage=1,this.totalPages=1,this.articles=[],this.loading=!1,this.expandedCards=new Set}async init(){console.log("[ContentList] Initializing..."),this.render(),await this.loadArticles(),console.log("[ContentList] Initialization complete")}render(){const e="rows"===this.options.layoutMode?"cg-content-rows":"cg-content-grid";this.container.innerHTML=`\n <div class="cg-content-list">\n <div class="cg-list-header">\n <button class="cg-display-toggle" title="Toggle display mode">\n <svg width="20" height="20" viewBox="0 0 20 20" fill="none">\n <rect x="2" y="2" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n <rect x="2" y="8" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n <rect x="2" y="14" width="16" height="4" rx="1" stroke="currentColor" stroke-width="1.5"/>\n </svg>\n <span>${"compact"===this.options.displayMode?"Show summaries":"Hide summaries"}</span>\n </button>\n </div>\n <div class="${e}"></div>\n <div class="cg-pagination"></div>\n </div>\n `;this.container.querySelector(".cg-display-toggle").addEventListener("click",()=>this.toggleDisplayMode())}async loadArticles(e=1){if(this.loading)console.log("[ContentList] Already loading, skipping...");else{console.log("[ContentList] Loading articles for page:",e),this.loading=!0,this.showLoading();try{console.log("[ContentList] Calling api.fetchArticles with:",{page:e,limit:this.options.pageSize,tags:this.options.tags,category:this.options.category});const t=await this.api.fetchArticles({page:e,limit:this.options.pageSize,tags:this.options.tags,category:this.options.category});console.log("[ContentList] Received data:",t),this.articles=t.articles||[],this.currentPage=t.pagination?.page||1,this.totalPages=t.pagination?.totalPages||1,console.log("[ContentList] Loaded",this.articles.length,"articles"),this.renderArticles(),this.renderPagination()}catch(e){console.error("[ContentList] Error loading articles:",e),this.showError("Failed to load articles. Please try again.")}finally{this.loading=!1}}}renderArticles(){const e=this.container.querySelector(".cg-content-grid, .cg-content-rows");0!==this.articles.length?(e.innerHTML="",this.articles.forEach(t=>{const n=this.expandedCards.has(t.uuid),s=new l(t,{displayMode:n?"expanded":this.options.displayMode,viewerMode:this.options.viewerMode,externalUrlPattern:this.options.externalUrlPattern,externalTarget:this.options.externalTarget,aiSummaryMaxBytes:this.options.aiSummaryMaxBytes,onExpand:(e,t)=>this.handleExpand(e,t),onClick:e=>this.handleArticleClick(e)});e.appendChild(s.render())})):e.innerHTML='\n <div class="cg-empty-state">\n <svg width="64" height="64" viewBox="0 0 64 64" fill="none">\n <rect x="8" y="12" width="48" height="40" rx="4" stroke="currentColor" stroke-width="2"/>\n <path d="M16 24H48M16 32H48M16 40H32" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>No articles found</p>\n </div>\n '}handleExpand(e,t){const n=this.expandedCards.has(e.uuid);n?this.expandedCards.delete(e.uuid):this.expandedCards.add(e.uuid);const s=new l(e,{displayMode:n?this.options.displayMode:"expanded",viewerMode:this.options.viewerMode,externalUrlPattern:this.options.externalUrlPattern,externalTarget:this.options.externalTarget,onExpand:(e,t)=>this.handleExpand(e,t),onClick:e=>this.handleArticleClick(e)});t.replaceWith(s.render())}handleArticleClick(e){this.options.onArticleClick&&this.options.onArticleClick(e)}toggleDisplayMode(){this.options.displayMode="compact"===this.options.displayMode?"expanded":"compact",this.expandedCards.clear(),this.renderArticles();this.container.querySelector(".cg-display-toggle span").textContent="compact"===this.options.displayMode?"Show summaries":"Hide summaries"}renderPagination(){const e=this.container.querySelector(".cg-pagination");if(this.totalPages<=1)return void(e.innerHTML="");const t=1===this.currentPage,n=this.currentPage===this.totalPages;e.innerHTML=`\n <button class="cg-btn-prev" ${t?"disabled":""}>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M10 12L6 8L10 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n Previous\n </button>\n <span class="cg-page-info">Page ${this.currentPage} of ${this.totalPages}</span>\n <button class="cg-btn-next" ${n?"disabled":""}>\n Next\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M6 4L10 8L6 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n `;const s=e.querySelector(".cg-btn-prev"),i=e.querySelector(".cg-btn-next");s.addEventListener("click",()=>{this.currentPage>1&&(this.loadArticles(this.currentPage-1),this.scrollToTop())}),i.addEventListener("click",()=>{this.currentPage<this.totalPages&&(this.loadArticles(this.currentPage+1),this.scrollToTop())})}showLoading(){const e=this.container.querySelector(".cg-content-grid, .cg-content-rows");e&&(e.innerHTML='\n <div class="cg-loading">\n <div class="cg-spinner"></div>\n <p>Loading articles...</p>\n </div>\n ')}showError(e){const t=this.container.querySelector(".cg-content-grid, .cg-content-rows");if(t){t.innerHTML=`\n <div class="cg-error">\n <svg width="48" height="48" viewBox="0 0 48 48" fill="none">\n <circle cx="24" cy="24" r="20" stroke="currentColor" stroke-width="2"/>\n <path d="M24 16V26M24 32V32.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>${e}</p>\n <button class="cg-retry-btn">Try Again</button>\n </div>\n `;t.querySelector(".cg-retry-btn").addEventListener("click",()=>this.loadArticles(this.currentPage))}}scrollToTop(){this.container.scrollIntoView({behavior:"smooth",block:"start"})}}class h{constructor(e,t,n={}){this.container=e,this.api=t,this.options={displayMode:n.displayMode||"inline",showBackButton:!1!==n.showBackButton,showSummary:!1!==n.showSummary,onBack:n.onBack||null},this.article=null,this.loading=!1,this.summaryExpanded=!0}async loadArticle(e){if(!this.loading){this.loading=!0,this.showLoading();try{this.article=await this.api.fetchArticle(e),this.render()}catch(e){this.showError("Failed to load article. Please try again."),console.error(e)}finally{this.loading=!1}}}async loadArticleBySlug(e){if(!this.loading){this.loading=!0,this.showLoading();try{this.article=await this.api.fetchArticleBySlug(e),this.render()}catch(e){this.showError("Failed to load article. Please try again."),console.error(e)}finally{this.loading=!1}}}render(){if(!this.article)return;const e=i(this.article.wordCount||this.article.content),t=this.renderMarkdown(this.article.content||"");if(this.container.innerHTML=`\n <div class="cg-content-viewer">\n ${this.options.showBackButton?'\n <div class="cg-viewer-header">\n <button class="cg-back-btn">\n <svg width="20" height="20" viewBox="0 0 20 20" fill="none">\n <path d="M12 16L6 10L12 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n Back to list\n </button>\n </div>\n ':""}\n \n <article class="cg-viewer-content">\n <header class="cg-content-header">\n <h1 class="cg-content-title">${r(this.article.title)}</h1>\n \n ${this.options.showSummary&&this.article.summary&&"announce"!==this.article.category?`\n <div class="cg-ai-summary ${this.summaryExpanded?"expanded":"collapsed"}">\n <div class="cg-ai-summary-header">\n <div class="cg-ai-summary-label">\n <svg class="cg-ai-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />\n </svg>\n <span>AI Generated Summary</span>\n </div>\n <button class="cg-summary-toggle" aria-label="Toggle summary">\n <svg class="cg-chevron" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6l4 4 4-4" />\n </svg>\n </button>\n </div>\n <div class="cg-ai-summary-content">\n <p>${r(this.article.summary)}</p>\n </div>\n </div>\n `:""}\n \n <div class="cg-content-meta">\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <path d="M8 8C9.65685 8 11 6.65685 11 5C11 3.34315 9.65685 2 8 2C6.34315 2 5 3.34315 5 5C5 6.65685 6.34315 8 8 8Z" stroke="currentColor" stroke-width="1.5"/>\n <path d="M14 14C14 11.7909 11.3137 10 8 10C4.68629 10 2 11.7909 2 14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${r(this.article.authorName)}\n </span>\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <rect x="2" y="3" width="12" height="11" rx="2" stroke="currentColor" stroke-width="1.5"/>\n <path d="M5 2V4M11 2V4M2 6H14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${s(this.article.publishedAt)}\n </span>\n <span class="cg-meta-item">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none">\n <circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.5"/>\n <path d="M8 4V8L10.5 10.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n ${e}\n </span>\n </div>\n </header>\n \n <div class="cg-content-body">\n ${t}\n </div>\n </article>\n </div>\n `,this.options.showBackButton){const e=this.container.querySelector(".cg-back-btn");e&&e.addEventListener("click",()=>this.handleBack())}const n=this.container.querySelector(".cg-summary-toggle");n&&n.addEventListener("click",()=>this.toggleSummary())}toggleSummary(){this.summaryExpanded=!this.summaryExpanded;const e=this.container.querySelector(".cg-ai-summary");e&&(this.summaryExpanded?(e.classList.add("expanded"),e.classList.remove("collapsed")):(e.classList.add("collapsed"),e.classList.remove("expanded")))}renderMarkdown(e){marked.setOptions({breaks:!0,gfm:!0,headerIds:!0,mangle:!1});try{return marked.parse(e)}catch(t){return console.error("Markdown parsing error:",t),`<p>${r(e)}</p>`}}handleBack(){this.options.onBack&&this.options.onBack()}showLoading(){this.container.innerHTML='\n <div class="cg-content-viewer">\n <div class="cg-viewer-loading">\n <div class="cg-spinner"></div>\n <p>Loading article...</p>\n </div>\n </div>\n '}showError(e){if(this.container.innerHTML=`\n <div class="cg-content-viewer">\n <div class="cg-viewer-error">\n <svg width="48" height="48" viewBox="0 0 48 48" fill="none">\n <circle cx="24" cy="24" r="20" stroke="currentColor" stroke-width="2"/>\n <path d="M24 16V26M24 32V32.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n <p>${e}</p>\n ${this.options.showBackButton?'<button class="cg-back-btn">Back to articles</button>':""}\n </div>\n </div>\n `,this.options.showBackButton){const e=this.container.querySelector(".cg-back-btn");e&&e.addEventListener("click",()=>this.handleBack())}}clear(){this.container.innerHTML="",this.article=null}}class d{static version="1.3.1";constructor(e,t){if(this.container="string"==typeof e?document.querySelector(e):e,!this.container)throw new Error("Container not found");if(this.config={apiKey:t.apiKey||t["api-key"],baseUrl:t.baseUrl||"https://api.content-growth.com",tags:this.parseTags(t.tags),category:t.category,theme:t.theme||"light",layoutMode:t.layoutMode||t["layout-mode"]||"cards",displayMode:t.displayMode||t["display-mode"]||"comfortable",aiSummaryMaxBytes:t.aiSummaryMaxBytes||t["ai-summary-max-bytes"],viewerMode:t.viewerMode||t["viewer-mode"]||"inline",externalUrlPattern:t.externalUrlPattern||t["external-url-pattern"]||"/article/{id}",externalTarget:t.externalTarget||t["external-target"]||"article-{id}",pageSize:t.pageSize||t["page-size"]||12,mode:t.mode||"list",articleId:t.articleId||t["article-id"],slug:t.slug},!this.config.apiKey)throw new Error("API key is required");this.api=new a({apiKey:this.config.apiKey,baseUrl:this.config.baseUrl}),this.currentView="list",this.contentList=null,this.contentViewer=null,this.init()}init(){this.container.classList.add("cg-widget"),this.container.setAttribute("data-theme",this.config.theme),"article-only"===this.config.mode?this.config.slug?this.showPostInlineBySlug(this.config.slug):this.config.articleId&&this.showPostInline(this.config.articleId):this.showList()}showList(){this.currentView="list",this.container.innerHTML="";const e=document.createElement("div");e.className="cg-list-view",this.container.appendChild(e),this.contentList=new c(e,this.api,{layoutMode:this.config.layoutMode,displayMode:this.config.displayMode,pageSize:this.config.pageSize,tags:this.config.tags,category:this.config.category,aiSummaryMaxBytes:this.config.aiSummaryMaxBytes,viewerMode:this.config.viewerMode,externalUrlPattern:this.config.externalUrlPattern,externalTarget:this.config.externalTarget,onArticleClick:e=>this.showPost(e.uuid)}),this.contentList.init()}showPost(e){this.currentView="viewer","modal"===this.config.viewerMode?this.showPostModal(e):this.showPostInline(e)}showPostInline(e){this.container.innerHTML="";const t=document.createElement("div");t.className="cg-viewer-view",this.container.appendChild(t);const n="article-only"!==this.config.mode;this.contentViewer=new h(t,this.api,{displayMode:"inline",showBackButton:n,onBack:n?()=>this.showList():null}),this.contentViewer.loadArticle(e)}showPostInlineBySlug(e){this.container.innerHTML="";const t=document.createElement("div");t.className="cg-viewer-view",this.container.appendChild(t);const n="article-only"!==this.config.mode;this.contentViewer=new h(t,this.api,{displayMode:"inline",showBackButton:n,onBack:n?()=>this.showList():null}),this.contentViewer.loadArticleBySlug(e)}showPostModal(e){const t=document.createElement("div");t.className="cg-modal",this.config.theme&&t.setAttribute("data-theme",this.config.theme),t.innerHTML='\n <div class="cg-modal-overlay"></div>\n <div class="cg-modal-content">\n <button class="cg-modal-close" aria-label="Close">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none">\n <path d="M18 6L6 18M6 6L18 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n </button>\n <div class="cg-modal-body"></div>\n </div>\n ',document.body.appendChild(t),document.body.style.overflow="hidden";const n=t.querySelector(".cg-modal-body");this.contentViewer=new h(n,this.api,{displayMode:"modal",onBack:()=>this.closeModal(t)}),this.contentViewer.loadArticle(e);const s=t.querySelector(".cg-modal-close"),i=t.querySelector(".cg-modal-overlay"),r=()=>this.closeModal(t);s.addEventListener("click",r),i.addEventListener("click",r);const o=e=>{"Escape"===e.key&&(r(),document.removeEventListener("keydown",o))};document.addEventListener("keydown",o),requestAnimationFrame(()=>{t.classList.add("cg-modal--active")})}closeModal(e){e.classList.remove("cg-modal--active"),setTimeout(()=>{e.remove(),document.body.style.overflow=""},300)}parseTags(e){return e?Array.isArray(e)?e:e.split(",").map(e=>e.trim()).filter(Boolean):[]}updateConfig(e){Object.assign(this.config,e),this.init()}destroy(){this.container.innerHTML="",this.container.classList.remove("cg-widget"),this.container.removeAttribute("data-theme")}}function p(){document.querySelectorAll("[data-cg-content]").forEach((t,n)=>{const s={apiKey:t.dataset.apiKey||t.dataset.cgApiKey,baseUrl:e.WIDGET_BASE_URL||t.dataset.baseUrl||t.dataset.cgBaseUrl,tags:t.dataset.tags||t.dataset.cgTags,theme:t.dataset.theme||t.dataset.cgTheme||"light",layoutMode:t.dataset.layoutMode||t.dataset.cgLayoutMode||"cards",displayMode:t.dataset.displayMode||t.dataset.cgDisplayMode||"comfortable",viewerMode:t.dataset.viewerMode||t.dataset.cgViewerMode||"inline",externalUrlPattern:t.dataset.externalUrlPattern||t.dataset.cgExternalUrlPattern,externalTarget:t.dataset.externalTarget||t.dataset.cgExternalTarget,pageSize:t.dataset.pageSize||t.dataset.cgPageSize||12,mode:t.dataset.mode||t.dataset.cgMode||"list",articleId:t.dataset.articleId||t.dataset.cgArticleId};try{new d(t,s)}catch(e){console.error(`[Widget ${n}] Failed to initialize:`,e),t.innerHTML=`\n <div style="padding: 2rem; text-align: center; color: #ef4444;">\n <p>Failed to load widget: ${e.message}</p>\n <p style="font-size: 0.875rem; margin-top: 0.5rem;">Check console for details</p>\n </div>\n `}})}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",p):p(),e.ContentGrowthWidget=d,e.ContentGrowthWidget=d,console.log("[ContentGrowthWidget] Loaded successfully v1.3.1")}(window);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentgrowth/content-widget",
3
- "version": "1.2.4",
3
+ "version": "1.3.1",
4
4
  "description": "Embed your Content Growth articles anywhere with beautiful, customizable components",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,6 +33,10 @@
33
33
  },
34
34
  "./astro/ContentList.astro": "./dist/astro/ContentList.astro",
35
35
  "./astro/ContentViewer.astro": "./dist/astro/ContentViewer.astro",
36
+ "./astro/FeaturedContent.astro": "./dist/astro/FeaturedContent.astro",
37
+ "./vue/ContentList.vue": "./dist/vue/ContentList.vue",
38
+ "./vue/ContentViewer.vue": "./dist/vue/ContentViewer.vue",
39
+ "./vue/FeaturedContent.vue": "./dist/vue/FeaturedContent.vue",
36
40
  "./styles.css": "./dist/styles.css"
37
41
  },
38
42
  "files": [