@skhema/web-component 0.0.14 → 0.0.15

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.
package/dist/index.es.js CHANGED
@@ -1,43 +1,11 @@
1
1
  import { ELEMENT_TYPES } from "@skhema/types";
2
- function isValidElementType(elementType) {
3
- const validTypes = Object.values(ELEMENT_TYPES).map((type) => type.value);
4
- return validTypes.includes(elementType);
5
- }
6
- function validateAttributes(element) {
7
- const errors = [];
8
- const elementType = element.getAttribute("element-type");
9
- const contributorId = element.getAttribute("contributor-id");
10
- if (!elementType) {
11
- errors.push("Missing required attribute: element-type");
12
- } else if (!isValidElementType(elementType)) {
13
- const validTypes = Object.values(ELEMENT_TYPES).map((t) => t.value).join(", ");
14
- errors.push(`Invalid element-type "${elementType}". Valid types: ${validTypes}`);
15
- }
16
- if (!contributorId) {
17
- errors.push("Missing required attribute: contributor-id");
18
- } else if (contributorId.trim().length === 0) {
19
- errors.push("contributor-id cannot be empty");
20
- }
21
- return {
22
- isValid: errors.length === 0,
23
- errors,
24
- elementType: isValidElementType(elementType || "") ? elementType : void 0,
25
- contributorId: contributorId || void 0
26
- };
27
- }
28
- function getElementTypeLabel(elementType) {
29
- const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType);
30
- return (type == null ? void 0 : type.label) || elementType;
31
- }
32
- function getElementTypeAcronym(elementType) {
33
- const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType);
34
- return (type == null ? void 0 : type.acronym) || elementType.substring(0, 2).toUpperCase();
35
- }
36
2
  function toUrlSafeBase64(str) {
37
- const base64 = btoa(encodeURIComponent(str).replace(
38
- /%([0-9A-F]{2})/g,
39
- (_, p1) => String.fromCharCode(parseInt(p1, 16))
40
- ));
3
+ const base64 = btoa(
4
+ encodeURIComponent(str).replace(
5
+ /%([0-9A-F]{2})/g,
6
+ (_, p1) => String.fromCharCode(parseInt(p1, 16))
7
+ )
8
+ );
41
9
  return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
42
10
  }
43
11
  async function trackEmbedLoad(analytics) {
@@ -53,7 +21,10 @@ async function trackEmbedLoad(analytics) {
53
21
  user_agent: analytics.userAgent || ""
54
22
  });
55
23
  if (navigator.sendBeacon) {
56
- navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/embed", data);
24
+ navigator.sendBeacon(
25
+ "https://api.skhema.com/api:XGdoUqHx/component/embed",
26
+ data
27
+ );
57
28
  } else {
58
29
  fetch("https://api.skhema.com/api:XGdoUqHx/component/embed", {
59
30
  method: "POST",
@@ -102,26 +73,62 @@ function generateContentHash(content) {
102
73
  }
103
74
  return Math.abs(hash).toString(36).substring(0, 12);
104
75
  }
76
+ function isValidElementType(elementType) {
77
+ const validTypes = Object.values(ELEMENT_TYPES).map((type) => type.value);
78
+ return validTypes.includes(elementType);
79
+ }
80
+ function validateAttributes(element) {
81
+ const errors = [];
82
+ const elementType = element.getAttribute("element-type");
83
+ const contributorId = element.getAttribute("contributor-id");
84
+ if (!elementType) {
85
+ errors.push("Missing required attribute: element-type");
86
+ } else if (!isValidElementType(elementType)) {
87
+ const validTypes = Object.values(ELEMENT_TYPES).map((t) => t.value).join(", ");
88
+ errors.push(
89
+ `Invalid element-type "${elementType}". Valid types: ${validTypes}`
90
+ );
91
+ }
92
+ if (!contributorId) {
93
+ errors.push("Missing required attribute: contributor-id");
94
+ } else if (contributorId.trim().length === 0) {
95
+ errors.push("contributor-id cannot be empty");
96
+ }
97
+ return {
98
+ isValid: errors.length === 0,
99
+ errors,
100
+ elementType: isValidElementType(elementType || "") ? elementType : void 0,
101
+ contributorId: contributorId || void 0
102
+ };
103
+ }
104
+ function getElementTypeLabel(elementType) {
105
+ const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType);
106
+ return type?.label || elementType;
107
+ }
108
+ function getElementTypeAcronym(elementType) {
109
+ const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType);
110
+ return type?.acronym || elementType.substring(0, 2).toUpperCase();
111
+ }
105
112
  function generateStructuredData(content, elementType, contributorId, sourceUrl) {
106
113
  return {
107
114
  "@context": "https://schema.org",
108
115
  "@type": "AnalysisContent",
109
- "text": content,
110
- "analysisType": elementType,
111
- "category": getElementTypeLabel(elementType),
112
- "contributor": contributorId,
113
- "url": generateRedirectUrl(content, elementType, contributorId),
114
- "provider": {
116
+ text: content,
117
+ analysisType: elementType,
118
+ category: getElementTypeLabel(elementType),
119
+ contributor: contributorId,
120
+ url: generateRedirectUrl(content, elementType, contributorId),
121
+ provider: {
115
122
  "@type": "Organization",
116
- "name": "Skhema",
117
- "url": "https://skhema.com"
123
+ name: "Skhema",
124
+ url: "https://skhema.com"
118
125
  },
119
- "isPartOf": {
126
+ isPartOf: {
120
127
  "@type": "WebPage",
121
- "url": sourceUrl
128
+ url: sourceUrl
122
129
  },
123
- "dateCreated": (/* @__PURE__ */ new Date()).toISOString(),
124
- "platform": "Skhema"
130
+ dateCreated: (/* @__PURE__ */ new Date()).toISOString(),
131
+ platform: "Skhema"
125
132
  };
126
133
  }
127
134
  function generateRedirectUrl(content, elementType, contributorId, options = {}) {
@@ -154,7 +161,7 @@ function createMetaTags(content, elementType, contributorId) {
154
161
  function createAriaAttributes(elementType) {
155
162
  const label = getElementTypeLabel(elementType);
156
163
  return {
157
- "role": "article",
164
+ role: "article",
158
165
  "aria-label": `${label} - Strategic insight`,
159
166
  "aria-describedby": "skhema-description"
160
167
  };
@@ -478,7 +485,14 @@ class SkhemaElement extends HTMLElement {
478
485
  this.shadow = this.attachShadow({ mode: "closed" });
479
486
  }
480
487
  static get observedAttributes() {
481
- return ["element-type", "contributor-id", "content", "source-url", "theme", "track-analytics"];
488
+ return [
489
+ "element-type",
490
+ "contributor-id",
491
+ "content",
492
+ "source-url",
493
+ "theme",
494
+ "track-analytics"
495
+ ];
482
496
  }
483
497
  connectedCallback() {
484
498
  if (this.componentConnected) return;
@@ -503,7 +517,9 @@ class SkhemaElement extends HTMLElement {
503
517
  }
504
518
  const content = this.getContent();
505
519
  if (!content.trim()) {
506
- this.renderError("Component requires content", ["Add content between the opening and closing tags, or use the content attribute"]);
520
+ this.renderError("Component requires content", [
521
+ "Add content between the opening and closing tags, or use the content attribute"
522
+ ]);
507
523
  return;
508
524
  }
509
525
  this.contentData = {
@@ -525,7 +541,11 @@ class SkhemaElement extends HTMLElement {
525
541
  if (!this.contentData) return;
526
542
  const { element_type, contributor_id, content } = this.contentData;
527
543
  const label = getElementTypeLabel(element_type);
528
- const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);
544
+ const redirectUrl = generateRedirectUrl(
545
+ content,
546
+ element_type,
547
+ contributor_id
548
+ );
529
549
  const theme = this.getAttribute("theme") || "auto";
530
550
  const displayName = this.formatContributorName(contributor_id);
531
551
  const initials = this.getInitials(displayName);
@@ -570,7 +590,9 @@ class SkhemaElement extends HTMLElement {
570
590
  </div>
571
591
  </div>
572
592
  `;
573
- const saveBtn = this.shadow.querySelector(".skhema-save-btn");
593
+ const saveBtn = this.shadow.querySelector(
594
+ ".skhema-save-btn"
595
+ );
574
596
  if (saveBtn) {
575
597
  saveBtn.addEventListener("click", (event) => {
576
598
  this.handleSaveClick(event);
@@ -597,15 +619,22 @@ class SkhemaElement extends HTMLElement {
597
619
  </div>
598
620
  </div>
599
621
  `;
600
- this.dispatchEvent(new CustomEvent("skhema:error", {
601
- detail: { error: title, details: errors },
602
- bubbles: true
603
- }));
622
+ this.dispatchEvent(
623
+ new CustomEvent("skhema:error", {
624
+ detail: { error: title, details: errors },
625
+ bubbles: true
626
+ })
627
+ );
604
628
  }
605
629
  addStructuredData() {
606
630
  if (!this.contentData) return;
607
631
  const { content, element_type, contributor_id, source_url } = this.contentData;
608
- const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);
632
+ const structuredData = generateStructuredData(
633
+ content,
634
+ element_type,
635
+ contributor_id,
636
+ source_url
637
+ );
609
638
  const script = document.createElement("script");
610
639
  script.type = "application/ld+json";
611
640
  script.textContent = JSON.stringify(structuredData);
@@ -629,20 +658,24 @@ class SkhemaElement extends HTMLElement {
629
658
  userAgent: navigator.userAgent
630
659
  };
631
660
  await trackEmbedLoad(analytics);
632
- this.dispatchEvent(new CustomEvent("skhema:load", {
633
- detail: analytics,
634
- bubbles: true
635
- }));
661
+ this.dispatchEvent(
662
+ new CustomEvent("skhema:load", {
663
+ detail: analytics,
664
+ bubbles: true
665
+ })
666
+ );
636
667
  }
637
668
  async handleSaveClick(_event) {
638
669
  if (!this.contentData) return;
639
670
  if (shouldTrackAnalytics(this)) {
640
671
  await trackClick(this.contentData);
641
672
  }
642
- this.dispatchEvent(new CustomEvent("skhema:click", {
643
- detail: this.contentData,
644
- bubbles: true
645
- }));
673
+ this.dispatchEvent(
674
+ new CustomEvent("skhema:click", {
675
+ detail: this.contentData,
676
+ bubbles: true
677
+ })
678
+ );
646
679
  }
647
680
  // Public API methods
648
681
  getContentData() {
@@ -654,11 +687,17 @@ class SkhemaElement extends HTMLElement {
654
687
  }
655
688
  function registerSkhemaElement() {
656
689
  if (typeof window !== "undefined" && !customElements.get("skhema-element")) {
657
- customElements.define("skhema-element", SkhemaElement);
690
+ customElements.define(
691
+ "skhema-element",
692
+ SkhemaElement
693
+ );
658
694
  }
659
695
  }
660
696
  if (typeof window !== "undefined" && !customElements.get("skhema-element")) {
661
- customElements.define("skhema-element", SkhemaElement);
697
+ customElements.define(
698
+ "skhema-element",
699
+ SkhemaElement
700
+ );
662
701
  }
663
702
  export {
664
703
  SkhemaElement,
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/utils/validation.ts","../src/utils/analytics.ts","../src/utils/hash.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import { ELEMENT_TYPES } from '@skhema/types';\nimport type { ElementValue } from '@skhema/types';\n\nexport function isValidElementType(elementType: string): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map(type => type.value);\n return validTypes.includes(elementType as ElementValue);\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean;\n errors: string[];\n elementType?: ElementValue;\n contributorId?: string;\n} {\n const errors: string[] = [];\n \n const elementType = element.getAttribute('element-type');\n const contributorId = element.getAttribute('contributor-id');\n \n if (!elementType) {\n errors.push('Missing required attribute: element-type');\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES).map(t => t.value).join(', ');\n errors.push(`Invalid element-type \"${elementType}\". Valid types: ${validTypes}`);\n }\n \n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id');\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty');\n }\n \n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '') ? elementType as ElementValue : undefined,\n contributorId: contributorId || undefined\n };\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.label || elementType;\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find(t => t.value === elementType);\n return type?.acronym || elementType.substring(0, 2).toUpperCase();\n}","import type { EmbedAnalytics, ContentData } from '../components/types.js';\n\n/**\n * Encode string to URL-safe base64\n */\nfunction toUrlSafeBase64(str: string): string {\n // Convert string to base64\n const base64 = btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_, p1) =>\n String.fromCharCode(parseInt(p1, 16))\n ));\n // Make it URL-safe by replacing + with -, / with _, and removing trailing =\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n content: toUrlSafeBase64(analytics.content),\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || ''\n });\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon('https://api.skhema.com/api:XGdoUqHx/component/embed', data);\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n });\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error);\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp\n };\n\n // Always use fetch for click tracking to ensure proper CORS handling\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n credentials: 'omit',\n keepalive: true\n }).catch(() => {\n // Fail silently\n });\n } catch (error) {\n console.debug('Click tracking failed:', error);\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics');\n return trackAnalytics !== 'false';\n}","export function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0;\n const cleanContent = content.trim().substring(0, 200);\n \n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n \n return Math.abs(hash).toString(36).substring(0, 12);\n}","import type { ElementValue } from '@skhema/types';\nimport { getElementTypeLabel } from './validation.js';\nimport { generateContentHash } from './hash.js';\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"AnalysisContent\",\n \"text\": content,\n \"analysisType\": elementType,\n \"category\": getElementTypeLabel(elementType),\n \"contributor\": contributorId,\n \"url\": generateRedirectUrl(content, elementType, contributorId),\n \"provider\": {\n \"@type\": \"Organization\",\n \"name\": \"Skhema\",\n \"url\": \"https://skhema.com\"\n },\n \"isPartOf\": {\n \"@type\": \"WebPage\",\n \"url\": sourceUrl\n },\n \"dateCreated\": new Date().toISOString(),\n \"platform\": \"Skhema\"\n };\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string;\n utmSource?: string;\n utmMedium?: string;\n utmCampaign?: string;\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://app.skhema.com/save'; // This page will handle the authentication and content saving\n const contentHash = generateContentHash(content);\n const sourceUrl = encodeURIComponent(window.location.href);\n const timestamp = Date.now();\n \n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId\n });\n \n \n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType);\n \n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `;\n}\n\nexport function createAriaAttributes(elementType: ElementValue): Record<string, string> {\n const label = getElementTypeLabel(elementType);\n \n return {\n 'role': 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description'\n };\n}","import type { SkhemaElementAttributes, EmbedAnalytics, ContentData, SkhemaElementEventMap } from './types.js';\nimport { validateAttributes, getElementTypeLabel } from '../utils/validation.js';\nimport { trackEmbedLoad, trackClick, shouldTrackAnalytics } from '../utils/analytics.js';\nimport { generateContentHash } from '../utils/hash.js';\nimport { generateStructuredData, generateRedirectUrl, createMetaTags, createAriaAttributes } from '../utils/seo.js';\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`;\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot;\n private contentData: ContentData | null = null;\n private componentConnected = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'closed' });\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return ['element-type', 'contributor-id', 'content', 'source-url', 'theme', 'track-analytics'];\n }\n\n connectedCallback() {\n if (this.componentConnected) return;\n this.componentConnected = true;\n \n try {\n this.render();\n this.trackLoad();\n } catch (error) {\n this.renderError('Failed to initialize component', error);\n }\n }\n\n attributeChangedCallback(_name: keyof SkhemaElementAttributes, oldValue: string | null, newValue: string | null) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render();\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement);\n \n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors);\n return;\n }\n\n const content = this.getContent();\n if (!content.trim()) {\n this.renderError('Component requires content', ['Add content between the opening and closing tags, or use the content attribute']);\n return;\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title\n };\n\n this.renderContent();\n this.addStructuredData();\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || '';\n }\n\n private renderContent() {\n if (!this.contentData) return;\n\n const { element_type, contributor_id, content } = this.contentData;\n const label = getElementTypeLabel(element_type);\n const redirectUrl = generateRedirectUrl(content, element_type, contributor_id);\n const theme = this.getAttribute('theme') || 'auto';\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id);\n const initials = this.getInitials(displayName);\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type);\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value);\n });\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `;\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector('.skhema-save-btn') as HTMLAnchorElement;\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event);\n });\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map(word => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2);\n }\n\n private renderError(title: string, errors: string | string[] | any) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)];\n \n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map(error => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `;\n\n // Dispatch error event\n this.dispatchEvent(new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true\n }));\n }\n\n private addStructuredData() {\n if (!this.contentData) return;\n\n const { content, element_type, contributor_id, source_url } = this.contentData;\n \n // Add structured data to the document head\n const structuredData = generateStructuredData(content, element_type, contributor_id, source_url);\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.textContent = JSON.stringify(structuredData);\n script.className = 'skhema-structured-data';\n document.head.appendChild(script);\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div');\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id);\n metaDiv.className = 'skhema-structured-data';\n document.body.appendChild(metaDiv);\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return;\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n content: this.contentData.content,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent\n };\n\n await trackEmbedLoad(analytics);\n\n // Dispatch load event\n this.dispatchEvent(new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true\n }));\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return;\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData);\n }\n\n // Dispatch click event\n this.dispatchEvent(new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true\n }));\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData;\n }\n\n public refresh(): void {\n this.render();\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n \n namespace JSX {\n interface IntrinsicElements {\n 'skhema-element': Partial<SkhemaElementAttributes> & {\n [key: string]: any;\n };\n }\n }\n}","import { SkhemaElement } from './components/SkhemaElement.js';\n\n// Export the component class\nexport { SkhemaElement };\n\n// Export types for TypeScript users\nexport type {\n SkhemaElementAttributes,\n EmbedAnalytics,\n ContentData,\n SkhemaElementEventMap\n} from './components/types.js';\n\n// Export utilities\nexport {\n isValidElementType,\n validateAttributes,\n getElementTypeLabel,\n getElementTypeAcronym\n} from './utils/validation.js';\n\nexport {\n // Removed generateContentHash\n shouldTrackAnalytics\n} from './utils/analytics.js';\n\nexport {\n generateStructuredData,\n generateRedirectUrl\n} from './utils/seo.js';\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define('skhema-element', SkhemaElement as CustomElementConstructor);\n}\n\n// Default export for convenience\nexport default SkhemaElement;"],"names":[],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwTR,MAAM,sBAAsB,YAAY;AAAA,EAK7C,cAAc;AACZ,UAAA;AAJF,SAAQ,cAAkC;AAC1C,SAAQ,qBAAqB;AAI3B,SAAK,SAAS,KAAK,aAAa,EAAE,MAAM,UAAU;AAAA,EACpD;AAAA,EAEA,WAAW,qBAAwD;AACjE,WAAO,CAAC,gBAAgB,kBAAkB,WAAW,cAAc,SAAS,iBAAiB;AAAA,EAC/F;AAAA,EAEA,oBAAoB;AAClB,QAAI,KAAK,mBAAoB;AAC7B,SAAK,qBAAqB;AAE1B,QAAI;AACF,WAAK,OAAA;AACL,WAAK,UAAA;AAAA,IACP,SAAS,OAAO;AACd,WAAK,YAAY,kCAAkC,KAAK;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,yBAAyB,OAAsC,UAAyB,UAAyB;AAC/G,QAAI,aAAa,YAAY,KAAK,oBAAoB;AACpD,WAAK,OAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,SAAS;AACf,UAAM,aAAa,mBAAmB,IAAmB;AAEzD,QAAI,CAAC,WAAW,SAAS;AACvB,WAAK,YAAY,gCAAgC,WAAW,MAAM;AAClE;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,WAAA;AACrB,QAAI,CAAC,QAAQ,QAAQ;AACnB,WAAK,YAAY,8BAA8B,CAAC,gFAAgF,CAAC;AACjI;AAAA,IACF;AAEA,SAAK,cAAc;AAAA,MACjB,gBAAgB,WAAW;AAAA,MAC3B,cAAc,WAAW;AAAA,MACzB;AAAA,MACA,cAAc,oBAAoB,OAAO;AAAA,MACzC,YAAY,KAAK,aAAa,YAAY,KAAK,OAAO,SAAS;AAAA,MAC/D,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MACtB,YAAY,SAAS;AAAA,IAAA;AAGvB,SAAK,cAAA;AACL,SAAK,kBAAA;AAAA,EACP;AAAA,EAEQ,aAAqB;AAC3B,WAAO,KAAK,aAAa,SAAS,KAAK,KAAK,eAAe;AAAA,EAC7D;AAAA,EAEQ,gBAAgB;AACtB,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,EAAE,cAAc,gBAAgB,QAAA,IAAY,KAAK;AACvD,UAAM,QAAQ,oBAAoB,YAAY;AAC9C,UAAM,cAAc,oBAAoB,SAAS,cAAc,cAAc;AAC7E,UAAM,QAAQ,KAAK,aAAa,OAAO,KAAK;AAG5C,UAAM,cAAc,KAAK,sBAAsB,cAAc;AAC7D,UAAM,WAAW,KAAK,YAAY,WAAW;AAG7C,UAAM,YAAY,qBAAqB,YAAY;AACnD,WAAO,QAAQ,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAClD,WAAK,aAAa,KAAK,KAAK;AAAA,IAC9B,CAAC;AAED,SAAK,OAAO,YAAY;AAAA,eACb,MAAM;AAAA;AAAA,qDAEgC,KAAK;AAAA;AAAA;AAAA,gDAGV,WAAW;AAAA,gBAC3C,QAAQ;AAAA;AAAA;AAAA,qDAG6B,WAAW;AAAA;AAAA;AAAA;AAAA,qDAIX,KAAK;AAAA,cAC5C,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,6CAK0B,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAO/B,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY5B,UAAM,UAAU,KAAK,OAAO,cAAc,kBAAkB;AAC5D,QAAI,SAAS;AACX,cAAQ,iBAAiB,SAAS,CAAC,UAAU;AAC3C,aAAK,gBAAgB,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,sBAAsB,eAA+B;AAE3D,WAAO,cACJ,MAAM,MAAM,EACZ,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,CAAC,EAAE,aAAa,EACtE,KAAK,GAAG;AAAA,EACb;AAAA,EAEQ,YAAY,MAAsB;AACxC,WAAO,KACJ,MAAM,GAAG,EACT,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC,CAAC,EAC1B,KAAK,EAAE,EACP,cACA,UAAU,GAAG,CAAC;AAAA,EACnB;AAAA,EAEQ,YAAY,OAAe,QAAiC;AAClE,UAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,OAAO,MAAM,CAAC;AAElE,SAAK,OAAO,YAAY;AAAA,eACb,MAAM;AAAA;AAAA;AAAA;AAAA,oEAI+C,KAAK;AAAA;AAAA,cAE3D,UAAU,IAAI,CAAA,UAAS,OAAO,KAAK,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAO9D,SAAK,cAAc,IAAI,YAAY,gBAAgB;AAAA,MACjD,QAAQ,EAAE,OAAO,OAAO,SAAS,OAAA;AAAA,MACjC,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,EAAE,SAAS,cAAc,gBAAgB,WAAA,IAAe,KAAK;AAGnE,UAAM,iBAAiB,uBAAuB,SAAS,cAAc,gBAAgB,UAAU;AAC/F,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,OAAO;AACd,WAAO,cAAc,KAAK,UAAU,cAAc;AAClD,WAAO,YAAY;AACnB,aAAS,KAAK,YAAY,MAAM;AAGhC,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY,eAAe,SAAS,cAAc,cAAc;AACxE,YAAQ,YAAY;AACpB,aAAS,KAAK,YAAY,OAAO;AAAA,EACnC;AAAA,EAEA,MAAc,YAAY;AACxB,QAAI,CAAC,qBAAqB,IAAmB,KAAK,CAAC,KAAK,YAAa;AAErE,UAAM,YAA4B;AAAA,MAChC,eAAe,KAAK,YAAY;AAAA,MAChC,aAAa,KAAK,YAAY;AAAA,MAC9B,aAAa,KAAK,YAAY;AAAA,MAC9B,SAAS,KAAK,YAAY;AAAA,MAC1B,SAAS,OAAO,SAAS;AAAA,MACzB,WAAW,SAAS;AAAA,MACpB,WAAW,KAAK,IAAA;AAAA,MAChB,WAAW,UAAU;AAAA,IAAA;AAGvB,UAAM,eAAe,SAAS;AAG9B,SAAK,cAAc,IAAI,YAAY,eAAe;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA,EAEA,MAAc,gBAAgB,QAAe;AAC3C,QAAI,CAAC,KAAK,YAAa;AAGvB,QAAI,qBAAqB,IAAmB,GAAG;AAC7C,YAAM,WAAW,KAAK,WAAW;AAAA,IACnC;AAGA,SAAK,cAAc,IAAI,YAAY,gBAAgB;AAAA,MACjD,QAAQ,KAAK;AAAA,MACb,SAAS;AAAA,IAAA,CACV,CAAC;AAAA,EACJ;AAAA;AAAA,EAGO,iBAAqC;AAC1C,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;AACrB,SAAK,OAAA;AAAA,EACP;AACF;AC1gBO,SAAS,wBAAwB;AACtC,MAAI,OAAO,WAAW,eAAe,CAAC,eAAe,IAAI,gBAAgB,GAAG;AAC1E,mBAAe,OAAO,kBAAkB,aAAyC;AAAA,EACnF;AACF;AAGA,IAAI,OAAO,WAAW,eAAe,CAAC,eAAe,IAAI,gBAAgB,GAAG;AAC1E,iBAAe,OAAO,kBAAkB,aAAyC;AACnF;"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/utils/analytics.ts","../src/utils/hash.ts","../src/utils/validation.ts","../src/utils/seo.ts","../src/components/SkhemaElement.ts","../src/index.ts"],"sourcesContent":["import type { ContentData, EmbedAnalytics } from '../components/types.js'\n\n/**\n * Encode string to URL-safe base64\n */\nfunction toUrlSafeBase64(str: string): string {\n // Convert string to base64\n const base64 = btoa(\n encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_, p1) =>\n String.fromCharCode(parseInt(p1, 16))\n )\n )\n // Make it URL-safe by replacing + with -, / with _, and removing trailing =\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport async function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void> {\n try {\n const data = new URLSearchParams({\n contributor_id: analytics.contributorId,\n element_type: analytics.elementType,\n content_hash: analytics.contentHash,\n content: toUrlSafeBase64(analytics.content),\n page_url: analytics.pageUrl,\n page_title: analytics.pageTitle || '',\n timestamp: analytics.timestamp.toString(),\n user_agent: analytics.userAgent || '',\n })\n\n // Use beacon for reliability\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n 'https://api.skhema.com/api:XGdoUqHx/component/embed',\n data\n )\n } else {\n // Fallback to fetch\n fetch('https://api.skhema.com/api:XGdoUqHx/component/embed', {\n method: 'POST',\n body: data,\n credentials: 'omit',\n keepalive: true,\n }).catch(() => {\n // Fail silently - analytics shouldn't break the component\n })\n }\n } catch (error) {\n // Fail silently\n console.debug('Analytics tracking failed:', error)\n }\n}\n\nexport async function trackClick(contentData: ContentData): Promise<void> {\n try {\n const data = {\n contributor_id: contentData.contributor_id,\n element_type: contentData.element_type,\n content_hash: contentData.content_hash,\n source_url: contentData.source_url,\n timestamp: contentData.timestamp,\n }\n\n // Always use fetch for click tracking to ensure proper CORS handling\n fetch('https://api.skhema.com/api:XGdoUqHx/component/click', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n credentials: 'omit',\n keepalive: true,\n }).catch(() => {\n // Fail silently\n })\n } catch (error) {\n console.debug('Click tracking failed:', error)\n }\n}\n\nexport function shouldTrackAnalytics(element: HTMLElement): boolean {\n const trackAnalytics = element.getAttribute('track-analytics')\n return trackAnalytics !== 'false'\n}\n","export function generateContentHash(content: string): string {\n // Simple hash function for content identification\n let hash = 0\n const cleanContent = content.trim().substring(0, 200)\n\n for (let i = 0; i < cleanContent.length; i++) {\n const char = cleanContent.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n\n return Math.abs(hash).toString(36).substring(0, 12)\n}\n","import type { ElementValue } from '@skhema/types'\nimport { ELEMENT_TYPES } from '@skhema/types'\n\nexport function isValidElementType(\n elementType: string\n): elementType is ElementValue {\n const validTypes = Object.values(ELEMENT_TYPES).map((type) => type.value)\n return validTypes.includes(elementType as ElementValue)\n}\n\nexport function validateAttributes(element: HTMLElement): {\n isValid: boolean\n errors: string[]\n elementType?: ElementValue\n contributorId?: string\n} {\n const errors: string[] = []\n\n const elementType = element.getAttribute('element-type')\n const contributorId = element.getAttribute('contributor-id')\n\n if (!elementType) {\n errors.push('Missing required attribute: element-type')\n } else if (!isValidElementType(elementType)) {\n const validTypes = Object.values(ELEMENT_TYPES)\n .map((t) => t.value)\n .join(', ')\n errors.push(\n `Invalid element-type \"${elementType}\". Valid types: ${validTypes}`\n )\n }\n\n if (!contributorId) {\n errors.push('Missing required attribute: contributor-id')\n } else if (contributorId.trim().length === 0) {\n errors.push('contributor-id cannot be empty')\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n elementType: isValidElementType(elementType || '')\n ? (elementType as ElementValue)\n : undefined,\n contributorId: contributorId || undefined,\n }\n}\n\nexport function getElementTypeLabel(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType)\n return type?.label || elementType\n}\n\nexport function getElementTypeAcronym(elementType: ElementValue): string {\n const type = Object.values(ELEMENT_TYPES).find((t) => t.value === elementType)\n return type?.acronym || elementType.substring(0, 2).toUpperCase()\n}\n","import type { ElementValue } from '@skhema/types'\nimport { generateContentHash } from './hash.js'\nimport { getElementTypeLabel } from './validation.js'\n\nexport function generateStructuredData(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n sourceUrl: string\n): object {\n return {\n '@context': 'https://schema.org',\n '@type': 'AnalysisContent',\n text: content,\n analysisType: elementType,\n category: getElementTypeLabel(elementType),\n contributor: contributorId,\n url: generateRedirectUrl(content, elementType, contributorId),\n provider: {\n '@type': 'Organization',\n name: 'Skhema',\n url: 'https://skhema.com',\n },\n isPartOf: {\n '@type': 'WebPage',\n url: sourceUrl,\n },\n dateCreated: new Date().toISOString(),\n platform: 'Skhema',\n }\n}\n\nexport function generateRedirectUrl(\n content: string,\n elementType: ElementValue,\n contributorId: string,\n options: {\n baseUrl?: string\n utmSource?: string\n utmMedium?: string\n utmCampaign?: string\n } = {}\n): string {\n const baseUrl = options.baseUrl || 'https://app.skhema.com/save' // This page will handle the authentication and content saving\n const contentHash = generateContentHash(content)\n const sourceUrl = encodeURIComponent(window.location.href)\n const timestamp = Date.now()\n\n const params = new URLSearchParams({\n source: sourceUrl,\n t: timestamp.toString(),\n utm_source: options.utmSource || 'web_component',\n utm_medium: options.utmMedium || 'embedded',\n utm_campaign: options.utmCampaign || elementType,\n utm_content: contributorId,\n })\n\n return `${baseUrl}?contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`\n // return `${baseUrl}/contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}?${params.toString()}`;\n}\n\nexport function createMetaTags(\n content: string,\n elementType: ElementValue,\n contributorId: string\n): string {\n const label = getElementTypeLabel(elementType)\n\n return `\n <div itemscope itemtype=\"https://schema.org/AnalysisContent\" style=\"display:none;\">\n <meta itemprop=\"analysisType\" content=\"${elementType}\">\n <meta itemprop=\"text\" content=\"${content}\">\n <meta itemprop=\"contributor\" content=\"${contributorId}\">\n <meta itemprop=\"category\" content=\"${label}\">\n <meta itemprop=\"platform\" content=\"Skhema\">\n </div>\n `\n}\n\nexport function createAriaAttributes(\n elementType: ElementValue\n): Record<string, string> {\n const label = getElementTypeLabel(elementType)\n\n return {\n role: 'article',\n 'aria-label': `${label} - Strategic insight`,\n 'aria-describedby': 'skhema-description',\n }\n}\n","import {\n shouldTrackAnalytics,\n trackClick,\n trackEmbedLoad,\n} from '../utils/analytics.js'\nimport { generateContentHash } from '../utils/hash.js'\nimport {\n createAriaAttributes,\n createMetaTags,\n generateRedirectUrl,\n generateStructuredData,\n} from '../utils/seo.js'\nimport { getElementTypeLabel, validateAttributes } from '../utils/validation.js'\nimport type {\n ContentData,\n EmbedAnalytics,\n SkhemaElementAttributes,\n SkhemaElementEventMap,\n} from './types.js'\n\n// Inline styles matching Skhema UI library design system\nconst styles = `\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n`\n\nexport class SkhemaElement extends HTMLElement {\n private shadow: ShadowRoot\n private contentData: ContentData | null = null\n private componentConnected = false\n\n constructor() {\n super()\n this.shadow = this.attachShadow({ mode: 'closed' })\n }\n\n static get observedAttributes(): (keyof SkhemaElementAttributes)[] {\n return [\n 'element-type',\n 'contributor-id',\n 'content',\n 'source-url',\n 'theme',\n 'track-analytics',\n ]\n }\n\n connectedCallback() {\n if (this.componentConnected) return\n this.componentConnected = true\n\n try {\n this.render()\n this.trackLoad()\n } catch (error) {\n this.renderError('Failed to initialize component', error)\n }\n }\n\n attributeChangedCallback(\n _name: keyof SkhemaElementAttributes,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue !== newValue && this.componentConnected) {\n this.render()\n }\n }\n\n private render() {\n const validation = validateAttributes(this as HTMLElement)\n\n if (!validation.isValid) {\n this.renderError('Invalid component attributes', validation.errors)\n return\n }\n\n const content = this.getContent()\n if (!content.trim()) {\n this.renderError('Component requires content', [\n 'Add content between the opening and closing tags, or use the content attribute',\n ])\n return\n }\n\n this.contentData = {\n contributor_id: validation.contributorId!,\n element_type: validation.elementType!,\n content: content,\n content_hash: generateContentHash(content),\n source_url: this.getAttribute('source-url') || window.location.href,\n timestamp: new Date().toISOString(),\n page_title: document.title,\n }\n\n this.renderContent()\n this.addStructuredData()\n }\n\n private getContent(): string {\n return this.getAttribute('content') || this.textContent || ''\n }\n\n private renderContent() {\n if (!this.contentData) return\n\n const { element_type, contributor_id, content } = this.contentData\n const label = getElementTypeLabel(element_type)\n const redirectUrl = generateRedirectUrl(\n content,\n element_type,\n contributor_id\n )\n const theme = this.getAttribute('theme') || 'auto'\n\n // Generate contributor display name and initials\n const displayName = this.formatContributorName(contributor_id)\n const initials = this.getInitials(displayName)\n\n // Set ARIA attributes on host element\n const ariaAttrs = createAriaAttributes(element_type)\n Object.entries(ariaAttrs).forEach(([key, value]) => {\n this.setAttribute(key, value)\n })\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\" data-theme=\"${theme}\">\n <div class=\"skhema-header\">\n <div class=\"skhema-contributor\">\n <div class=\"skhema-avatar\" title=\"${displayName}\">\n ${initials}\n </div>\n <div class=\"skhema-contributor-info\">\n <div class=\"skhema-contributor-name\">${displayName}</div>\n <div class=\"skhema-contributor-role\">Strategy Insight</div>\n </div>\n </div>\n <div class=\"skhema-element-badge\" title=\"${label}\">\n ${label}\n </div>\n </div>\n \n <div class=\"skhema-content\">\n <div class=\"skhema-content-text\">${content}</div>\n </div>\n \n <div class=\"skhema-footer\">\n <div class=\"skhema-attribution\">\n Powered by <a href=\"https://skhema.com\" target=\"_blank\" rel=\"noopener noreferrer\">Skhema</a>\n </div>\n <a href=\"${redirectUrl}\" \n class=\"skhema-save-btn\" \n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Save this insight to Skhema\">\n Save to Skhema\n </a>\n </div>\n </div>\n `\n\n // Add click event listener\n const saveBtn = this.shadow.querySelector(\n '.skhema-save-btn'\n ) as HTMLAnchorElement\n if (saveBtn) {\n saveBtn.addEventListener('click', (event) => {\n this.handleSaveClick(event)\n })\n }\n }\n\n private formatContributorName(contributorId: string): string {\n // Convert contributor_id to display name\n return contributorId\n .split(/[_-]/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n }\n\n private getInitials(name: string): string {\n return name\n .split(' ')\n .map((word) => word.charAt(0))\n .join('')\n .toUpperCase()\n .substring(0, 2)\n }\n\n private renderError(title: string, errors: string | string[] | unknown) {\n const errorList = Array.isArray(errors) ? errors : [String(errors)]\n\n this.shadow.innerHTML = `\n <style>${styles}</style>\n \n <div class=\"skhema-insight-card\">\n <div class=\"skhema-error\">\n <div class=\"skhema-error-title\">Skhema Component Error: ${title}</div>\n <ul class=\"skhema-error-list\">\n ${errorList.map((error) => `<li>${error}</li>`).join('')}\n </ul>\n </div>\n </div>\n `\n\n // Dispatch error event\n this.dispatchEvent(\n new CustomEvent('skhema:error', {\n detail: { error: title, details: errors },\n bubbles: true,\n })\n )\n }\n\n private addStructuredData() {\n if (!this.contentData) return\n\n const { content, element_type, contributor_id, source_url } =\n this.contentData\n\n // Add structured data to the document head\n const structuredData = generateStructuredData(\n content,\n element_type,\n contributor_id,\n source_url\n )\n const script = document.createElement('script')\n script.type = 'application/ld+json'\n script.textContent = JSON.stringify(structuredData)\n script.className = 'skhema-structured-data'\n document.head.appendChild(script)\n\n // Add meta tags for SEO\n const metaDiv = document.createElement('div')\n metaDiv.innerHTML = createMetaTags(content, element_type, contributor_id)\n metaDiv.className = 'skhema-structured-data'\n document.body.appendChild(metaDiv)\n }\n\n private async trackLoad() {\n if (!shouldTrackAnalytics(this as HTMLElement) || !this.contentData) return\n\n const analytics: EmbedAnalytics = {\n contributorId: this.contentData.contributor_id,\n elementType: this.contentData.element_type,\n contentHash: this.contentData.content_hash,\n content: this.contentData.content,\n pageUrl: window.location.href,\n pageTitle: document.title,\n timestamp: Date.now(),\n userAgent: navigator.userAgent,\n }\n\n await trackEmbedLoad(analytics)\n\n // Dispatch load event\n this.dispatchEvent(\n new CustomEvent('skhema:load', {\n detail: analytics,\n bubbles: true,\n })\n )\n }\n\n private async handleSaveClick(_event: Event) {\n if (!this.contentData) return\n\n // Track click analytics\n if (shouldTrackAnalytics(this as HTMLElement)) {\n await trackClick(this.contentData)\n }\n\n // Dispatch click event\n this.dispatchEvent(\n new CustomEvent('skhema:click', {\n detail: this.contentData,\n bubbles: true,\n })\n )\n }\n\n // Public API methods\n public getContentData(): ContentData | null {\n return this.contentData\n }\n\n public refresh(): void {\n this.render()\n }\n}\n\n// Type augmentation for custom events and JSX elements\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface HTMLElementEventMap extends SkhemaElementEventMap {}\n\n interface SkhemaElementJSX extends Partial<SkhemaElementAttributes> {\n [key: string]: unknown\n }\n\n // Module augmentation for JSX without using namespace\n interface JSXIntrinsicElements {\n 'skhema-element': SkhemaElementJSX\n }\n}\n","import { SkhemaElement } from './components/SkhemaElement.js'\n\n// Export the component class\nexport { SkhemaElement }\n\n// Export types for TypeScript users\nexport type {\n ContentData,\n EmbedAnalytics,\n SkhemaElementAttributes,\n SkhemaElementEventMap,\n} from './components/types.js'\n\n// Export utilities\nexport {\n getElementTypeAcronym,\n getElementTypeLabel,\n isValidElementType,\n validateAttributes,\n} from './utils/validation.js'\n\nexport {\n // Removed generateContentHash\n shouldTrackAnalytics,\n} from './utils/analytics.js'\n\nexport { generateRedirectUrl, generateStructuredData } from './utils/seo.js'\n\n// Manual registration function for consuming applications\nexport function registerSkhemaElement() {\n if (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define(\n 'skhema-element',\n SkhemaElement as CustomElementConstructor\n )\n }\n}\n\n// Auto-register in browser environments (can be tree-shaken if not needed)\nif (typeof window !== 'undefined' && !customElements.get('skhema-element')) {\n customElements.define(\n 'skhema-element',\n SkhemaElement as CustomElementConstructor\n )\n}\n\n// Default export for convenience\nexport default SkhemaElement\n"],"names":[],"mappings":";AAKA,SAAS,gBAAgB,KAAqB;AAE5C,QAAM,SAAS;AAAA,IACb,mBAAmB,GAAG,EAAE;AAAA,MAAQ;AAAA,MAAmB,CAAC,GAAG,OACrD,OAAO,aAAa,SAAS,IAAI,EAAE,CAAC;AAAA,IAAA;AAAA,EACtC;AAGF,SAAO,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AACzE;AAEA,eAAsB,eAAe,WAA0C;AAC7E,MAAI;AACF,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,gBAAgB,UAAU;AAAA,MAC1B,cAAc,UAAU;AAAA,MACxB,cAAc,UAAU;AAAA,MACxB,SAAS,gBAAgB,UAAU,OAAO;AAAA,MAC1C,UAAU,UAAU;AAAA,MACpB,YAAY,UAAU,aAAa;AAAA,MACnC,WAAW,UAAU,UAAU,SAAA;AAAA,MAC/B,YAAY,UAAU,aAAa;AAAA,IAAA,CACpC;AAGD,QAAI,UAAU,YAAY;AACxB,gBAAU;AAAA,QACR;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,OAAO;AAEL,YAAM,uDAAuD;AAAA,QAC3D,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,QACb,WAAW;AAAA,MAAA,CACZ,EAAE,MAAM,MAAM;AAAA,MAEf,CAAC;AAAA,IACH;AAAA,EACF,SAAS,OAAO;AAEd,YAAQ,MAAM,8BAA8B,KAAK;AAAA,EACnD;AACF;AAEA,eAAsB,WAAW,aAAyC;AACxE,MAAI;AACF,UAAM,OAAO;AAAA,MACX,gBAAgB,YAAY;AAAA,MAC5B,cAAc,YAAY;AAAA,MAC1B,cAAc,YAAY;AAAA,MAC1B,YAAY,YAAY;AAAA,MACxB,WAAW,YAAY;AAAA,IAAA;AAIzB,UAAM,uDAAuD;AAAA,MAC3D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAA;AAAA,MAC3B,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,aAAa;AAAA,MACb,WAAW;AAAA,IAAA,CACZ,EAAE,MAAM,MAAM;AAAA,IAEf,CAAC;AAAA,EACH,SAAS,OAAO;AACd,YAAQ,MAAM,0BAA0B,KAAK;AAAA,EAC/C;AACF;AAEO,SAAS,qBAAqB,SAA+B;AAClE,QAAM,iBAAiB,QAAQ,aAAa,iBAAiB;AAC7D,SAAO,mBAAmB;AAC5B;AChFO,SAAS,oBAAoB,SAAyB;AAE3D,MAAI,OAAO;AACX,QAAM,eAAe,QAAQ,KAAA,EAAO,UAAU,GAAG,GAAG;AAEpD,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,OAAO,aAAa,WAAW,CAAC;AACtC,YAAQ,QAAQ,KAAK,OAAO;AAC5B,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO,KAAK,IAAI,IAAI,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AACpD;ACTO,SAAS,mBACd,aAC6B;AAC7B,QAAM,aAAa,OAAO,OAAO,aAAa,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;AACxE,SAAO,WAAW,SAAS,WAA2B;AACxD;AAEO,SAAS,mBAAmB,SAKjC;AACA,QAAM,SAAmB,CAAA;AAEzB,QAAM,cAAc,QAAQ,aAAa,cAAc;AACvD,QAAM,gBAAgB,QAAQ,aAAa,gBAAgB;AAE3D,MAAI,CAAC,aAAa;AAChB,WAAO,KAAK,0CAA0C;AAAA,EACxD,WAAW,CAAC,mBAAmB,WAAW,GAAG;AAC3C,UAAM,aAAa,OAAO,OAAO,aAAa,EAC3C,IAAI,CAAC,MAAM,EAAE,KAAK,EAClB,KAAK,IAAI;AACZ,WAAO;AAAA,MACL,yBAAyB,WAAW,mBAAmB,UAAU;AAAA,IAAA;AAAA,EAErE;AAEA,MAAI,CAAC,eAAe;AAClB,WAAO,KAAK,4CAA4C;AAAA,EAC1D,WAAW,cAAc,KAAA,EAAO,WAAW,GAAG;AAC5C,WAAO,KAAK,gCAAgC;AAAA,EAC9C;AAEA,SAAO;AAAA,IACL,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA,aAAa,mBAAmB,eAAe,EAAE,IAC5C,cACD;AAAA,IACJ,eAAe,iBAAiB;AAAA,EAAA;AAEpC;AAEO,SAAS,oBAAoB,aAAmC;AACrE,QAAM,OAAO,OAAO,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW;AAC7E,SAAO,MAAM,SAAS;AACxB;AAEO,SAAS,sBAAsB,aAAmC;AACvE,QAAM,OAAO,OAAO,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW;AAC7E,SAAO,MAAM,WAAW,YAAY,UAAU,GAAG,CAAC,EAAE,YAAA;AACtD;ACpDO,SAAS,uBACd,SACA,aACA,eACA,WACQ;AACR,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,cAAc;AAAA,IACd,UAAU,oBAAoB,WAAW;AAAA,IACzC,aAAa;AAAA,IACb,KAAK,oBAAoB,SAAS,aAAa,aAAa;AAAA,IAC5D,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,MACN,KAAK;AAAA,IAAA;AAAA,IAEP,UAAU;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IAAA;AAAA,IAEP,cAAa,oBAAI,KAAA,GAAO,YAAA;AAAA,IACxB,UAAU;AAAA,EAAA;AAEd;AAEO,SAAS,oBACd,SACA,aACA,eACA,UAKI,CAAA,GACI;AACR,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,cAAc,oBAAoB,OAAO;AAC/C,QAAM,YAAY,mBAAmB,OAAO,SAAS,IAAI;AACzD,QAAM,YAAY,KAAK,IAAA;AAEvB,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC,QAAQ;AAAA,IACR,GAAG,UAAU,SAAA;AAAA,IACb,YAAY,QAAQ,aAAa;AAAA,IACjC,YAAY,QAAQ,aAAa;AAAA,IACjC,cAAc,QAAQ,eAAe;AAAA,IACrC,aAAa;AAAA,EAAA,CACd;AAED,SAAO,GAAG,OAAO,mBAAmB,aAAa,iBAAiB,WAAW,iBAAiB,WAAW,IAAI,OAAO,SAAA,CAAU;AAEhI;AAEO,SAAS,eACd,SACA,aACA,eACQ;AACR,QAAM,QAAQ,oBAAoB,WAAW;AAE7C,SAAO;AAAA;AAAA,+CAEsC,WAAW;AAAA,uCACnB,OAAO;AAAA,8CACA,aAAa;AAAA,2CAChB,KAAK;AAAA;AAAA;AAAA;AAIhD;AAEO,SAAS,qBACd,aACwB;AACxB,QAAM,QAAQ,oBAAoB,WAAW;AAE7C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,GAAG,KAAK;AAAA,IACtB,oBAAoB;AAAA,EAAA;AAExB;ACpEA,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
@@ -1,5 +1,4 @@
1
- import { EmbedAnalytics, ContentData } from '../components/types.js';
2
-
1
+ import { ContentData, EmbedAnalytics } from '../components/types.js';
3
2
  export declare function trackEmbedLoad(analytics: EmbedAnalytics): Promise<void>;
4
3
  export declare function trackClick(contentData: ContentData): Promise<void>;
5
4
  export declare function shouldTrackAnalytics(element: HTMLElement): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAc1E,wBAAsB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B7E;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBxE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAGlE"}
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAgBzE,wBAAsB,cAAc,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC7E;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBxE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAGlE"}
@@ -1,5 +1,4 @@
1
1
  import { ElementValue } from '@skhema/types';
2
-
3
2
  export declare function generateStructuredData(content: string, elementType: ElementValue, contributorId: string, sourceUrl: string): object;
4
3
  export declare function generateRedirectUrl(content: string, elementType: ElementValue, contributorId: string, options?: {
5
4
  baseUrl?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/utils/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAqBR;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,MAAM,CAkBR;AAGD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,GACpB,MAAM,CAYR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQtF"}
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/utils/seo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAIjD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAqBR;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CAChB,GACL,MAAM,CAiBR;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,GACpB,MAAM,CAYR;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,YAAY,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB"}
@@ -1,5 +1,4 @@
1
1
  import { ElementValue } from '@skhema/types';
2
-
3
2
  export declare function isValidElementType(elementType: string): elementType is ElementValue;
4
3
  export declare function validateAttributes(element: HTMLElement): {
5
4
  isValid: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,IAAI,YAAY,CAGnF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG;IACxD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAyBA;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAGrE;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAGvE"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGjD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,GAClB,WAAW,IAAI,YAAY,CAG7B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG;IACxD,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,CAAC,EAAE,YAAY,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CA+BA;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAGrE;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CAGvE"}
@@ -1,2 +1,2 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).SkhemaWebComponent={})}(this,function(e){"use strict";const n={KEY_CHALLENGE:{value:"key_challenge",label:"Key Challenge",acronym:"KC"},SUPPORTING_FACT:{value:"supporting_fact",label:"Supporting Fact",acronym:"SF"},ASSOCIATED_IMPACT:{value:"associated_impact",label:"Associated Impact",acronym:"AI"},GUIDING_POLICY:{value:"guiding_policy",label:"Guiding Policy",acronym:"GP"},COMPETITOR_MOVE:{value:"competitor_move",label:"Competitor Move",acronym:"CM"},SCOPE:{value:"scope",label:"Scope",acronym:"SC"},CONSTRAINT:{value:"constraint",label:"Constraint",acronym:"CN"},SOLUTION_ALTERNATIVE:{value:"solution_alternative",label:"Solution Alternative",acronym:"SA"},ASSUMPTION_HYPOTHESIS:{value:"assumption_hypothesis",label:"Assumption Hypothesis",acronym:"AH"},EXPERIMENT:{value:"experiment",label:"Experiment",acronym:"EX"},ACTION:{value:"action",label:"Action",acronym:"AC"},INVESTMENT:{value:"investment",label:"Investment",acronym:"IN"},ESTIMATE:{value:"estimate",label:"Estimate",acronym:"ES"},BASELINE:{value:"baseline",label:"Baseline",acronym:"BL"},OUTCOME:{value:"outcome",label:"Outcome",acronym:"OC"},PERFORMANCE_VARIABLE:{value:"performance_variable",label:"Performance Variable",acronym:"PV"},CAPABILITY:{value:"capability",label:"Capability",acronym:"CP"},SYSTEM:{value:"system",label:"System",acronym:"SY"},PRINCIPLE:{value:"principle",label:"Principle",acronym:"PR"}};function t(e){return Object.values(n).map(e=>e.value).includes(e)}function a(e){const t=Object.values(n).find(n=>n.value===e);return(null==t?void 0:t.label)||e}function r(e){return"false"!==e.getAttribute("track-analytics")}function o(e){let n=0;const t=e.trim().substring(0,200);for(let a=0;a<t.length;a++){n=(n<<5)-n+t.charCodeAt(a),n&=n}return Math.abs(n).toString(36).substring(0,12)}function i(e,n,t,a={}){const r=a.baseUrl||"https://app.skhema.com/save",i=o(e),s=encodeURIComponent(window.location.href),c=Date.now();return`${r}?contributor_id=${t}&element_type=${n}&content_hash=${i}&${new URLSearchParams({source:s,t:c.toString(),utm_source:a.utmSource||"web_component",utm_medium:a.utmMedium||"embedded",utm_campaign:a.utmCampaign||n,utm_content:t}).toString()}`}const s="\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n";class c extends HTMLElement{constructor(){super(),this.contentData=null,this.componentConnected=!1,this.shadow=this.attachShadow({mode:"closed"})}static get observedAttributes(){return["element-type","contributor-id","content","source-url","theme","track-analytics"]}connectedCallback(){if(!this.componentConnected){this.componentConnected=!0;try{this.render(),this.trackLoad()}catch(e){this.renderError("Failed to initialize component",e)}}}attributeChangedCallback(e,n,t){n!==t&&this.componentConnected&&this.render()}render(){const e=function(e){const a=[],r=e.getAttribute("element-type"),o=e.getAttribute("contributor-id");if(r){if(!t(r)){const e=Object.values(n).map(e=>e.value).join(", ");a.push(`Invalid element-type "${r}". Valid types: ${e}`)}}else a.push("Missing required attribute: element-type");return o?0===o.trim().length&&a.push("contributor-id cannot be empty"):a.push("Missing required attribute: contributor-id"),{isValid:0===a.length,errors:a,elementType:t(r||"")?r:void 0,contributorId:o||void 0}}(this);if(!e.isValid)return void this.renderError("Invalid component attributes",e.errors);const a=this.getContent();a.trim()?(this.contentData={contributor_id:e.contributorId,element_type:e.elementType,content:a,content_hash:o(a),source_url:this.getAttribute("source-url")||window.location.href,timestamp:(new Date).toISOString(),page_title:document.title},this.renderContent(),this.addStructuredData()):this.renderError("Component requires content",["Add content between the opening and closing tags, or use the content attribute"])}getContent(){return this.getAttribute("content")||this.textContent||""}renderContent(){if(!this.contentData)return;const{element_type:e,contributor_id:n,content:t}=this.contentData,r=a(e),o=i(t,e,n),c=this.getAttribute("theme")||"auto",l=this.formatContributorName(n),m=this.getInitials(l),h={role:"article","aria-label":`${a(e)} - Strategic insight`,"aria-describedby":"skhema-description"};Object.entries(h).forEach(([e,n])=>{this.setAttribute(e,n)}),this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card" data-theme="${c}">\n <div class="skhema-header">\n <div class="skhema-contributor">\n <div class="skhema-avatar" title="${l}">\n ${m}\n </div>\n <div class="skhema-contributor-info">\n <div class="skhema-contributor-name">${l}</div>\n <div class="skhema-contributor-role">Strategy Insight</div>\n </div>\n </div>\n <div class="skhema-element-badge" title="${r}">\n ${r}\n </div>\n </div>\n \n <div class="skhema-content">\n <div class="skhema-content-text">${t}</div>\n </div>\n \n <div class="skhema-footer">\n <div class="skhema-attribution">\n Powered by <a href="https://skhema.com" target="_blank" rel="noopener noreferrer">Skhema</a>\n </div>\n <a href="${o}" \n class="skhema-save-btn" \n target="_blank"\n rel="noopener noreferrer"\n title="Save this insight to Skhema">\n Save to Skhema\n </a>\n </div>\n </div>\n `;const d=this.shadow.querySelector(".skhema-save-btn");d&&d.addEventListener("click",e=>{this.handleSaveClick(e)})}formatContributorName(e){return e.split(/[_-]/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" ")}getInitials(e){return e.split(" ").map(e=>e.charAt(0)).join("").toUpperCase().substring(0,2)}renderError(e,n){const t=Array.isArray(n)?n:[String(n)];this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card">\n <div class="skhema-error">\n <div class="skhema-error-title">Skhema Component Error: ${e}</div>\n <ul class="skhema-error-list">\n ${t.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n </div>\n </div>\n `,this.dispatchEvent(new CustomEvent("skhema:error",{detail:{error:e,details:n},bubbles:!0}))}addStructuredData(){if(!this.contentData)return;const{content:e,element_type:n,contributor_id:t,source_url:r}=this.contentData,o=function(e,n,t,r){return{"@context":"https://schema.org","@type":"AnalysisContent",text:e,analysisType:n,category:a(n),contributor:t,url:i(e,n,t),provider:{"@type":"Organization",name:"Skhema",url:"https://skhema.com"},isPartOf:{"@type":"WebPage",url:r},dateCreated:(new Date).toISOString(),platform:"Skhema"}}(e,n,t,r),s=document.createElement("script");s.type="application/ld+json",s.textContent=JSON.stringify(o),s.className="skhema-structured-data",document.head.appendChild(s);const c=document.createElement("div");c.innerHTML=function(e,n,t){return`\n <div itemscope itemtype="https://schema.org/AnalysisContent" style="display:none;">\n <meta itemprop="analysisType" content="${n}">\n <meta itemprop="text" content="${e}">\n <meta itemprop="contributor" content="${t}">\n <meta itemprop="category" content="${a(n)}">\n <meta itemprop="platform" content="Skhema">\n </div>\n `}(e,n,t),c.className="skhema-structured-data",document.body.appendChild(c)}async trackLoad(){if(!r(this)||!this.contentData)return;const e={contributorId:this.contentData.contributor_id,elementType:this.contentData.element_type,contentHash:this.contentData.content_hash,content:this.contentData.content,pageUrl:window.location.href,pageTitle:document.title,timestamp:Date.now(),userAgent:navigator.userAgent};await async function(e){try{const t=new URLSearchParams({contributor_id:e.contributorId,element_type:e.elementType,content_hash:e.contentHash,content:(n=e.content,btoa(encodeURIComponent(n).replace(/%([0-9A-F]{2})/g,(e,n)=>String.fromCharCode(parseInt(n,16)))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")),page_url:e.pageUrl,page_title:e.pageTitle||"",timestamp:e.timestamp.toString(),user_agent:e.userAgent||""});navigator.sendBeacon?navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/embed",t):fetch("https://api.skhema.com/api:XGdoUqHx/component/embed",{method:"POST",body:t,credentials:"omit",keepalive:!0}).catch(()=>{})}catch(t){console.debug("Analytics tracking failed:",t)}var n}(e),this.dispatchEvent(new CustomEvent("skhema:load",{detail:e,bubbles:!0}))}async handleSaveClick(e){this.contentData&&(r(this)&&await async function(e){try{const n={contributor_id:e.contributor_id,element_type:e.element_type,content_hash:e.content_hash,source_url:e.source_url,timestamp:e.timestamp};fetch("https://api.skhema.com/api:XGdoUqHx/component/click",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),credentials:"omit",keepalive:!0}).catch(()=>{})}catch(n){console.debug("Click tracking failed:",n)}}(this.contentData),this.dispatchEvent(new CustomEvent("skhema:click",{detail:this.contentData,bubbles:!0})))}getContentData(){return this.contentData}refresh(){this.render()}}customElements.get("skhema-element")||customElements.define("skhema-element",c),"undefined"!=typeof window&&(window.SkhemaElement=c),e.SkhemaElement=c,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).SkhemaWebComponent={})}(this,function(e){"use strict";function n(e){return"false"!==e.getAttribute("track-analytics")}function t(e){let n=0;const t=e.trim().substring(0,200);for(let a=0;a<t.length;a++){n=(n<<5)-n+t.charCodeAt(a),n&=n}return Math.abs(n).toString(36).substring(0,12)}const a={KEY_CHALLENGE:{value:"key_challenge",label:"Key Challenge",acronym:"KC"},SUPPORTING_FACT:{value:"supporting_fact",label:"Supporting Fact",acronym:"SF"},ASSOCIATED_IMPACT:{value:"associated_impact",label:"Associated Impact",acronym:"AI"},GUIDING_POLICY:{value:"guiding_policy",label:"Guiding Policy",acronym:"GP"},COMPETITOR_MOVE:{value:"competitor_move",label:"Competitor Move",acronym:"CM"},SCOPE:{value:"scope",label:"Scope",acronym:"SC"},CONSTRAINT:{value:"constraint",label:"Constraint",acronym:"CN"},SOLUTION_ALTERNATIVE:{value:"solution_alternative",label:"Solution Alternative",acronym:"SA"},ASSUMPTION_HYPOTHESIS:{value:"assumption_hypothesis",label:"Assumption Hypothesis",acronym:"AH"},EXPERIMENT:{value:"experiment",label:"Experiment",acronym:"EX"},ACTION:{value:"action",label:"Action",acronym:"AC"},INVESTMENT:{value:"investment",label:"Investment",acronym:"IN"},ESTIMATE:{value:"estimate",label:"Estimate",acronym:"ES"},BASELINE:{value:"baseline",label:"Baseline",acronym:"BL"},OUTCOME:{value:"outcome",label:"Outcome",acronym:"OC"},PERFORMANCE_VARIABLE:{value:"performance_variable",label:"Performance Variable",acronym:"PV"},CAPABILITY:{value:"capability",label:"Capability",acronym:"CP"},SYSTEM:{value:"system",label:"System",acronym:"SY"},PRINCIPLE:{value:"principle",label:"Principle",acronym:"PR"}};function r(e){return Object.values(a).map(e=>e.value).includes(e)}function o(e){const n=Object.values(a).find(n=>n.value===e);return n?.label||e}function i(e,n,a,r={}){const o=r.baseUrl||"https://app.skhema.com/save",i=t(e),s=encodeURIComponent(window.location.href),c=Date.now();return`${o}?contributor_id=${a}&element_type=${n}&content_hash=${i}&${new URLSearchParams({source:s,t:c.toString(),utm_source:r.utmSource||"web_component",utm_medium:r.utmMedium||"embedded",utm_campaign:r.utmCampaign||n,utm_content:a}).toString()}`}const s="\n:host {\n /* Skhema Brand Colors - matching UI library */\n --skhema-primary: hsl(344 57% 54%); /* #cd476a */\n --skhema-primary-hover: hsl(344 50% 47%); /* #b53d5e */\n --skhema-primary-pressed: hsl(343 50% 41%); /* #9d3552 */\n --skhema-secondary: hsl(345 100% 75%); /* #ff82a2 */\n --skhema-gradient: linear-gradient(135deg, hsl(344 57% 54%) 0%, hsl(345 100% 75%) 100%);\n \n /* Light mode colors */\n --skhema-bg: hsl(0 0% 100%);\n --skhema-card: hsl(0 0% 100%);\n --skhema-border: hsl(214.3 31.8% 91.4%);\n --skhema-text: hsl(222.2 84% 4.9%);\n --skhema-text-muted: hsl(215.4 16.3% 46.9%);\n --skhema-accent: hsl(210 40% 96%);\n \n /* Shadows matching UI library */\n --skhema-shadow: 0 1px 3px 0 hsl(0 0 0 / 0.1), 0 1px 2px -1px hsl(0 0 0 / 0.1);\n --skhema-shadow-md: 0 4px 6px -1px hsl(0 0 0 / 0.1), 0 2px 4px -2px hsl(0 0 0 / 0.1);\n --skhema-shadow-lg: 0 10px 15px -3px hsl(0 0 0 / 0.1), 0 4px 6px -4px hsl(0 0 0 / 0.1);\n --skhema-radius: 0.375rem;\n \n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Inter', sans-serif;\n line-height: 1.5;\n color: var(--skhema-text);\n}\n\n:host([theme=\"dark\"]) {\n /* Dark mode colors */\n --skhema-bg: hsl(222.2 84% 4.9%);\n --skhema-card: hsl(222.2 84% 4.9%);\n --skhema-border: hsl(217.2 32.6% 17.5%);\n --skhema-text: hsl(210 40% 98%);\n --skhema-text-muted: hsl(215 20.2% 65.1%);\n --skhema-accent: hsl(217.2 32.6% 17.5%);\n}\n\n/* Main component card - inspired by your design */\n.skhema-insight-card {\n position: relative;\n background: var(--skhema-card);\n border: 1px solid var(--skhema-border);\n border-radius: calc(var(--skhema-radius) * 2);\n padding: 16px;\n box-shadow: var(--skhema-shadow);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 600px;\n margin: 8px 0;\n}\n\n.skhema-insight-card:hover {\n box-shadow: var(--skhema-shadow-lg);\n border-color: var(--skhema-primary);\n transform: translateY(-1px);\n}\n\n/* Header section with contributor info */\n.skhema-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n gap: 12px;\n}\n\n.skhema-contributor {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n}\n\n.skhema-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--skhema-gradient);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 14px;\n color: white;\n flex-shrink: 0;\n}\n\n.skhema-contributor-info {\n min-width: 0;\n flex: 1;\n}\n\n.skhema-contributor-name {\n font-weight: 500;\n font-size: 14px;\n color: var(--skhema-text);\n margin: 0;\n line-height: 1.2;\n}\n\n.skhema-contributor-role {\n font-size: 12px;\n color: var(--skhema-text-muted);\n margin: 0;\n line-height: 1.2;\n}\n\n/* Element type badge */\n.skhema-element-badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 8px;\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n border-radius: var(--skhema-radius);\n font-size: 11px;\n font-weight: 500;\n color: var(--skhema-text-muted);\n text-transform: capitalize;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Content section */\n.skhema-content {\n margin: 12px 0 16px 0;\n padding: 0;\n}\n\n.skhema-content-text {\n font-size: 15px;\n line-height: 1.6;\n color: var(--skhema-text);\n margin: 0;\n font-style: italic;\n position: relative;\n}\n\n.skhema-content-text::before {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-right: 4px;\n}\n\n.skhema-content-text::after {\n content: '\"';\n color: var(--skhema-primary);\n font-size: 20px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* Footer section */\n.skhema-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--skhema-border);\n}\n\n.skhema-attribution {\n font-size: 11px;\n color: var(--skhema-text-muted);\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.skhema-attribution a {\n color: var(--skhema-primary);\n text-decoration: none;\n font-weight: 500;\n}\n\n.skhema-attribution a:hover {\n text-decoration: underline;\n}\n\n/* Save button with gradient and arrow */\n.skhema-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n background: var(--skhema-gradient);\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n font-weight: 500;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--skhema-shadow);\n white-space: nowrap;\n}\n\n.skhema-save-btn:hover {\n transform: translateY(-1px);\n box-shadow: var(--skhema-shadow-md);\n}\n\n.skhema-save-btn:active {\n transform: translateY(0);\n}\n\n.skhema-save-btn:focus {\n outline: 2px solid var(--skhema-primary);\n outline-offset: 2px;\n}\n\n.skhema-save-btn::after {\n content: '→';\n transition: transform 0.2s ease;\n}\n\n.skhema-save-btn:hover::after {\n transform: translateX(2px);\n}\n\n/* Error state */\n.skhema-error {\n background: hsl(0 93% 94%);\n border: 1px solid hsl(0 84% 60%);\n color: hsl(0 74% 42%);\n padding: 12px;\n border-radius: var(--skhema-radius);\n font-size: 13px;\n}\n\n.skhema-error-title {\n font-weight: 600;\n margin-bottom: 8px;\n}\n\n.skhema-error-list {\n margin: 0;\n padding-left: 16px;\n}\n\n/* Loading state */\n.skhema-loading {\n background: var(--skhema-accent);\n border: 1px solid var(--skhema-border);\n padding: 12px;\n border-radius: var(--skhema-radius);\n color: var(--skhema-text-muted);\n font-size: 13px;\n text-align: center;\n}\n\n.skhema-loading::after {\n content: '...';\n animation: loading 1.5s infinite;\n}\n\n@keyframes loading {\n 0%, 33% { content: '...'; }\n 66% { content: '..'; }\n 100% { content: '.'; }\n}\n\n/* Responsive design */\n@media (max-width: 640px) {\n .skhema-insight-card {\n margin: 4px 0;\n padding: 12px;\n }\n \n .skhema-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n \n .skhema-footer {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n \n .skhema-save-btn {\n justify-content: center;\n }\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n .skhema-insight-card,\n .skhema-save-btn {\n transition: none;\n }\n \n .skhema-save-btn::after {\n transition: none;\n }\n \n .skhema-save-btn:hover::after {\n transform: none;\n }\n}\n\n.skhema-structured-data {\n display: none !important;\n}\n";class c extends HTMLElement{constructor(){super(),this.contentData=null,this.componentConnected=!1,this.shadow=this.attachShadow({mode:"closed"})}static get observedAttributes(){return["element-type","contributor-id","content","source-url","theme","track-analytics"]}connectedCallback(){if(!this.componentConnected){this.componentConnected=!0;try{this.render(),this.trackLoad()}catch(e){this.renderError("Failed to initialize component",e)}}}attributeChangedCallback(e,n,t){n!==t&&this.componentConnected&&this.render()}render(){const e=function(e){const n=[],t=e.getAttribute("element-type"),o=e.getAttribute("contributor-id");if(t){if(!r(t)){const e=Object.values(a).map(e=>e.value).join(", ");n.push(`Invalid element-type "${t}". Valid types: ${e}`)}}else n.push("Missing required attribute: element-type");return o?0===o.trim().length&&n.push("contributor-id cannot be empty"):n.push("Missing required attribute: contributor-id"),{isValid:0===n.length,errors:n,elementType:r(t||"")?t:void 0,contributorId:o||void 0}}(this);if(!e.isValid)return void this.renderError("Invalid component attributes",e.errors);const n=this.getContent();n.trim()?(this.contentData={contributor_id:e.contributorId,element_type:e.elementType,content:n,content_hash:t(n),source_url:this.getAttribute("source-url")||window.location.href,timestamp:(new Date).toISOString(),page_title:document.title},this.renderContent(),this.addStructuredData()):this.renderError("Component requires content",["Add content between the opening and closing tags, or use the content attribute"])}getContent(){return this.getAttribute("content")||this.textContent||""}renderContent(){if(!this.contentData)return;const{element_type:e,contributor_id:n,content:t}=this.contentData,a=o(e),r=i(t,e,n),c=this.getAttribute("theme")||"auto",l=this.formatContributorName(n),m=this.getInitials(l),h={role:"article","aria-label":`${o(e)} - Strategic insight`,"aria-describedby":"skhema-description"};Object.entries(h).forEach(([e,n])=>{this.setAttribute(e,n)}),this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card" data-theme="${c}">\n <div class="skhema-header">\n <div class="skhema-contributor">\n <div class="skhema-avatar" title="${l}">\n ${m}\n </div>\n <div class="skhema-contributor-info">\n <div class="skhema-contributor-name">${l}</div>\n <div class="skhema-contributor-role">Strategy Insight</div>\n </div>\n </div>\n <div class="skhema-element-badge" title="${a}">\n ${a}\n </div>\n </div>\n \n <div class="skhema-content">\n <div class="skhema-content-text">${t}</div>\n </div>\n \n <div class="skhema-footer">\n <div class="skhema-attribution">\n Powered by <a href="https://skhema.com" target="_blank" rel="noopener noreferrer">Skhema</a>\n </div>\n <a href="${r}" \n class="skhema-save-btn" \n target="_blank"\n rel="noopener noreferrer"\n title="Save this insight to Skhema">\n Save to Skhema\n </a>\n </div>\n </div>\n `;const d=this.shadow.querySelector(".skhema-save-btn");d&&d.addEventListener("click",e=>{this.handleSaveClick(e)})}formatContributorName(e){return e.split(/[_-]/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" ")}getInitials(e){return e.split(" ").map(e=>e.charAt(0)).join("").toUpperCase().substring(0,2)}renderError(e,n){const t=Array.isArray(n)?n:[String(n)];this.shadow.innerHTML=`\n <style>${s}</style>\n \n <div class="skhema-insight-card">\n <div class="skhema-error">\n <div class="skhema-error-title">Skhema Component Error: ${e}</div>\n <ul class="skhema-error-list">\n ${t.map(e=>`<li>${e}</li>`).join("")}\n </ul>\n </div>\n </div>\n `,this.dispatchEvent(new CustomEvent("skhema:error",{detail:{error:e,details:n},bubbles:!0}))}addStructuredData(){if(!this.contentData)return;const{content:e,element_type:n,contributor_id:t,source_url:a}=this.contentData,r=function(e,n,t,a){return{"@context":"https://schema.org","@type":"AnalysisContent",text:e,analysisType:n,category:o(n),contributor:t,url:i(e,n,t),provider:{"@type":"Organization",name:"Skhema",url:"https://skhema.com"},isPartOf:{"@type":"WebPage",url:a},dateCreated:(new Date).toISOString(),platform:"Skhema"}}(e,n,t,a),s=document.createElement("script");s.type="application/ld+json",s.textContent=JSON.stringify(r),s.className="skhema-structured-data",document.head.appendChild(s);const c=document.createElement("div");c.innerHTML=function(e,n,t){return`\n <div itemscope itemtype="https://schema.org/AnalysisContent" style="display:none;">\n <meta itemprop="analysisType" content="${n}">\n <meta itemprop="text" content="${e}">\n <meta itemprop="contributor" content="${t}">\n <meta itemprop="category" content="${o(n)}">\n <meta itemprop="platform" content="Skhema">\n </div>\n `}(e,n,t),c.className="skhema-structured-data",document.body.appendChild(c)}async trackLoad(){if(!n(this)||!this.contentData)return;const e={contributorId:this.contentData.contributor_id,elementType:this.contentData.element_type,contentHash:this.contentData.content_hash,content:this.contentData.content,pageUrl:window.location.href,pageTitle:document.title,timestamp:Date.now(),userAgent:navigator.userAgent};await async function(e){try{const t=new URLSearchParams({contributor_id:e.contributorId,element_type:e.elementType,content_hash:e.contentHash,content:(n=e.content,btoa(encodeURIComponent(n).replace(/%([0-9A-F]{2})/g,(e,n)=>String.fromCharCode(parseInt(n,16)))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")),page_url:e.pageUrl,page_title:e.pageTitle||"",timestamp:e.timestamp.toString(),user_agent:e.userAgent||""});navigator.sendBeacon?navigator.sendBeacon("https://api.skhema.com/api:XGdoUqHx/component/embed",t):fetch("https://api.skhema.com/api:XGdoUqHx/component/embed",{method:"POST",body:t,credentials:"omit",keepalive:!0}).catch(()=>{})}catch(t){console.debug("Analytics tracking failed:",t)}var n}(e),this.dispatchEvent(new CustomEvent("skhema:load",{detail:e,bubbles:!0}))}async handleSaveClick(e){this.contentData&&(n(this)&&await async function(e){try{const n={contributor_id:e.contributor_id,element_type:e.element_type,content_hash:e.content_hash,source_url:e.source_url,timestamp:e.timestamp};fetch("https://api.skhema.com/api:XGdoUqHx/component/click",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),credentials:"omit",keepalive:!0}).catch(()=>{})}catch(n){console.debug("Click tracking failed:",n)}}(this.contentData),this.dispatchEvent(new CustomEvent("skhema:click",{detail:this.contentData,bubbles:!0})))}getContentData(){return this.contentData}refresh(){this.render()}}customElements.get("skhema-element")||customElements.define("skhema-element",c),"undefined"!=typeof window&&(window.SkhemaElement=c),e.SkhemaElement=c,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=web-component.min.js.map