@sonordev/site-kit 8.5.2 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/agent-manifest.json +1 -1
  3. package/dist/{AnalyticsProvider-HSJMHYBA.js → AnalyticsProvider-3UIQMIRW.js} +6 -6
  4. package/dist/{ArticleViewTracker-XEA6ZY67.js → ArticleViewTracker-KNXP2DXL.js} +5 -5
  5. package/dist/{BlocksPopup-DUTOENMQ.js → BlocksPopup-DFE32GPX.js} +9 -8
  6. package/dist/{ChatWidget-PMVQTSEU.js → ChatWidget-L74L4YAD.js} +6 -6
  7. package/dist/FileField-P3PLEAON.js +237 -0
  8. package/dist/{FormSpotlight-RTPJPLQ3.js → FormSpotlight-DNBSBRIE.js} +2 -2
  9. package/dist/{FormStage-UANGD66Z.js → FormStage-I4JGLT57.js} +2 -2
  10. package/dist/{ManagedForm-4AACRHEY.js → ManagedForm-GJRGBM6W.js} +8 -8
  11. package/dist/{ManagedNewsletterForm-RWKFWZ72.js → ManagedNewsletterForm-AUZ6YB7G.js} +11 -11
  12. package/dist/{SignalCore-XULLPKPX.js → SignalCore-UV7K7PT4.js} +5 -5
  13. package/dist/SiteChat-6UWE545R.js +6 -0
  14. package/dist/SiteDesignReporter-ZSU76DZJ.js +13 -0
  15. package/dist/{SitePopups-US6VQN7X.js → SitePopups-XHWU7GNF.js} +6 -6
  16. package/dist/SitemapSync-ELWV6W7Y.js +9 -0
  17. package/dist/_client/booking-widget.js +5 -5
  18. package/dist/affiliates/index.js +3 -3
  19. package/dist/analytics/content-text.d.ts +17 -0
  20. package/dist/analytics/index.js +6 -6
  21. package/dist/{article-styles-VASFBYA3.js → article-styles-D7VCDXMG.js} +2 -1
  22. package/dist/article-tables-W45BE353.js +3 -0
  23. package/dist/articles/index.js +7 -20
  24. package/dist/articles/server-ui.js +29 -55
  25. package/dist/articles/server.js +6 -5
  26. package/dist/chat/index.js +9 -9
  27. package/dist/{chunk-3RDJKIYO.js → chunk-2WDWQI7K.js} +1 -1
  28. package/dist/{chunk-DLTLXYOV.js → chunk-36ZMNBXZ.js} +4 -9
  29. package/dist/chunk-3MJNBOUO.js +8 -0
  30. package/dist/{chunk-IXA7ZB6U.js → chunk-3MLWIBHX.js} +1 -1
  31. package/dist/{chunk-BF7TZYC3.js → chunk-52KO4LKD.js} +1 -1
  32. package/dist/{chunk-ZDUTXHM6.js → chunk-5WHBYQJ4.js} +3 -3
  33. package/dist/{chunk-5D7ZISUP.js → chunk-7DYMM6SS.js} +11 -6
  34. package/dist/{chunk-HNYECNCU.js → chunk-7YB3QA4P.js} +15 -7
  35. package/dist/{chunk-N4ZCNYWF.js → chunk-A2MDVP47.js} +1 -1
  36. package/dist/{chunk-E4PTMORJ.js → chunk-AL5UCWLI.js} +23 -8
  37. package/dist/{chunk-ANVHRT35.js → chunk-BAJUXQTH.js} +2 -2
  38. package/dist/{chunk-ITQND6IB.js → chunk-BJYX6SFI.js} +2 -2
  39. package/dist/{chunk-TYAVHRWH.js → chunk-CVADNHJ4.js} +8 -2
  40. package/dist/{chunk-5BRHTBPO.js → chunk-DJIGFX33.js} +1 -1
  41. package/dist/{chunk-ZSU7KTIE.js → chunk-DPYGC7WE.js} +2 -2
  42. package/dist/{chunk-XA7Q2VQA.js → chunk-EK7P62DT.js} +1 -1
  43. package/dist/chunk-FXR5PJDL.js +420 -0
  44. package/dist/{chunk-GLLFIE2R.js → chunk-G5FD7UXK.js} +2 -2
  45. package/dist/{chunk-OFQ3BU52.js → chunk-HM7CDWFK.js} +1 -1
  46. package/dist/{chunk-Q4Y3WIHE.js → chunk-HWQPCZOX.js} +1 -1
  47. package/dist/{chunk-6KU7STM3.js → chunk-HY7ZEU2C.js} +3 -1
  48. package/dist/chunk-IBHBEUZV.js +27 -0
  49. package/dist/{chunk-7HRYSLY2.js → chunk-IXZBOOAD.js} +4 -4
  50. package/dist/chunk-JESLPEST.js +14 -0
  51. package/dist/{chunk-BC7JMY4Z.js → chunk-JG53YJLM.js} +58 -1
  52. package/dist/{chunk-FVXCQC7W.js → chunk-JWCCY72G.js} +1 -1
  53. package/dist/{chunk-RI2N2EBI.js → chunk-JYITKUUB.js} +13 -5
  54. package/dist/chunk-KIYACQW3.js +1 -0
  55. package/dist/{chunk-YW3LNSBM.js → chunk-KLIDCNML.js} +1 -1
  56. package/dist/{chunk-3PT6SO65.js → chunk-L2KSHJS2.js} +5 -5
  57. package/dist/{chunk-27LYZVPP.js → chunk-LGWN6KCN.js} +2 -2
  58. package/dist/{chunk-GTVOB5RN.js → chunk-MJW6YIDJ.js} +1 -1
  59. package/dist/{chunk-CFSIGEUW.js → chunk-MNORERMF.js} +1 -1
  60. package/dist/{chunk-Y35BWW2C.js → chunk-ODOV76VW.js} +1 -1
  61. package/dist/{chunk-EQHGPB3J.js → chunk-OHLCE4GC.js} +2 -2
  62. package/dist/{chunk-OEA7U4HJ.js → chunk-P5PRR2BB.js} +1 -1
  63. package/dist/{chunk-JJ4JS3LD.js → chunk-PAYCK7FC.js} +1 -1
  64. package/dist/{chunk-DLM4FFNH.js → chunk-QTBAKOCZ.js} +1 -1
  65. package/dist/{chunk-2QFIYYMP.js → chunk-RHT7OZNF.js} +1 -1
  66. package/dist/{chunk-UGZ3B5AK.js → chunk-RWWSOYJO.js} +9 -9
  67. package/dist/{chunk-T6U6J3QK.js → chunk-T6TWPKBL.js} +1 -1
  68. package/dist/{chunk-5SQK3D53.js → chunk-TYSIAWC3.js} +1 -0
  69. package/dist/{chunk-24NM64IV.js → chunk-U4OQJQK6.js} +3 -3
  70. package/dist/{chunk-GDQKDL3E.js → chunk-UYOE3HA4.js} +2 -2
  71. package/dist/chunk-VEJD5EJ2.js +344 -0
  72. package/dist/{chunk-LNSF6BJC.js → chunk-VPZJ7ZTL.js} +2 -2
  73. package/dist/chunk-XAZC2TUD.js +1119 -0
  74. package/dist/{chunk-A7RZQI6H.js → chunk-XC2TWYDV.js} +3 -3
  75. package/dist/{chunk-URJN75ZG.js → chunk-XIDWNXZN.js} +3 -3
  76. package/dist/chunk-XLAHRN4B.js +1 -0
  77. package/dist/{chunk-URZTBPZO.js → chunk-XZFOQ2V4.js} +113 -93
  78. package/dist/{chunk-I4LMZNBN.js → chunk-YYPYLYZM.js} +1 -1
  79. package/dist/client/index.js +4 -4
  80. package/dist/contracts/broadcast-layouts.d.ts +133 -0
  81. package/dist/contracts/business-claims.d.ts +456 -0
  82. package/dist/contracts/campaign-normalize.d.ts +2 -0
  83. package/dist/contracts/entries.d.ts +1 -1
  84. package/dist/contracts/funnels.d.ts +576 -0
  85. package/dist/contracts/inbox.d.ts +42 -0
  86. package/dist/contracts/llms.d.ts +200 -0
  87. package/dist/contracts/outreach.d.ts +267 -0
  88. package/dist/contracts/page-titles.d.ts +140 -0
  89. package/dist/contracts/portfolio.d.ts +170 -0
  90. package/dist/contracts/public-url-host.d.ts +10 -0
  91. package/dist/contracts/publication-branding.d.ts +151 -0
  92. package/dist/contracts/publication-charter.d.ts +14 -0
  93. package/dist/contracts/site-cache.d.ts +2 -0
  94. package/dist/fleet/index.js +6 -6
  95. package/dist/forms/FileField.d.ts +3 -1
  96. package/dist/forms/PrivateFileField.d.ts +3 -0
  97. package/dist/forms/index.js +11 -11
  98. package/dist/forms/private-file-rules.d.ts +8 -0
  99. package/dist/forms/server.js +5 -5
  100. package/dist/forms/static.js +3 -3
  101. package/dist/forms/styles.css +17 -1
  102. package/dist/forms/types.d.ts +4 -0
  103. package/dist/images/index.js +4 -4
  104. package/dist/index.js +1 -1
  105. package/dist/landing/contract.d.ts +2 -13
  106. package/dist/landing/contract.js +2 -0
  107. package/dist/landing/index.js +4 -2
  108. package/dist/landing/managed-server.d.ts +21 -0
  109. package/dist/landing/managed.d.ts +11 -0
  110. package/dist/landing/metadata.js +2 -0
  111. package/dist/landing/server.d.ts +5 -0
  112. package/dist/landing/server.js +19 -2
  113. package/dist/layout/client.js +9 -9
  114. package/dist/layout/index.js +10 -10
  115. package/dist/llms/contract.js +2 -1
  116. package/dist/llms/index.js +9 -7
  117. package/dist/llms/merge.d.ts +29 -0
  118. package/dist/maps/index.js +3 -3
  119. package/dist/mcp/sonor.js +12 -11
  120. package/dist/portfolio/contract.js +1 -1
  121. package/dist/press-kit/articles/article-body.d.ts +13 -0
  122. package/dist/press-kit/articles/article-heading-ids.d.ts +7 -0
  123. package/dist/press-kit/articles/article-headings.d.ts +61 -0
  124. package/dist/press-kit/articles/html-tags.d.ts +46 -0
  125. package/dist/press-kit/articles/types.d.ts +2 -0
  126. package/dist/revalidate/index.js +3 -3
  127. package/dist/runtime/index.js +3 -3
  128. package/dist/seo/client.js +6 -6
  129. package/dist/seo/index.js +14 -13
  130. package/dist/seo/llms/contract.js +2 -1
  131. package/dist/seo/llms.js +9 -7
  132. package/dist/seo/meta/contract.js +2 -1
  133. package/dist/seo/register-sitemap-cli.js +1 -1
  134. package/dist/seo/server.js +5 -4
  135. package/dist/seo/sitemap.js +7 -5
  136. package/dist/seo-meta/contract.js +2 -1
  137. package/dist/server/index.js +3 -3
  138. package/dist/{server-api-EGOKC7Q3.js → server-api-XIKDWSNO.js} +2 -2
  139. package/dist/shared/build-entries.d.ts +3 -1
  140. package/dist/shared/markdown.d.ts +7 -6
  141. package/dist/shared/version.d.ts +1 -1
  142. package/dist/signal/index.js +2 -2
  143. package/dist/sitemap/index.js +7 -5
  144. package/dist/slots/index.js +2 -2
  145. package/dist/sync/index.js +5 -5
  146. package/dist/website/contract.js +2 -1
  147. package/dist/website/images.js +4 -4
  148. package/dist/website/index.js +10 -9
  149. package/dist/website/landing/server.js +19 -2
  150. package/dist/website/landing.js +4 -2
  151. package/dist/website/popups.js +9 -8
  152. package/dist/website/slots.js +2 -2
  153. package/dist/{writeLLMsTxt-BAK5XMRR.js → writeLLMsTxt-QN2HIVT4.js} +6 -4
  154. package/docs.json +5 -0
  155. package/package.json +1 -1
  156. package/src/analytics/README.md +1 -1
  157. package/src/forms/README.md +22 -0
  158. package/src/landing/README.md +64 -0
  159. package/src/llms/README.md +52 -20
  160. package/dist/FileField-F7BG4XAZ.js +0 -83
  161. package/dist/SiteChat-P4CRBRJZ.js +0 -6
  162. package/dist/SiteDesignReporter-QDVP4WMK.js +0 -12
  163. package/dist/SitemapSync-5FBRDGHG.js +0 -9
  164. package/dist/article-tables-6XHVULPU.js +0 -2
  165. package/dist/chunk-EKBEOXTH.js +0 -114
  166. package/dist/chunk-NZ4RXN3G.js +0 -145
  167. package/dist/chunk-OSYCOC3K.js +0 -21
  168. /package/dist/{chunk-7ZWO5HDQ.js → chunk-BTHEQDN4.js} +0 -0
  169. /package/dist/{chunk-BQR4IPBW.js → chunk-ISRBSTB7.js} +0 -0
  170. /package/dist/{chunk-IHG36STL.js → chunk-XHYE24HU.js} +0 -0
@@ -1,13 +1,14 @@
1
1
  'use client';
2
- import { NewsletterShell } from '../chunk-JHTPHA2D.js';
3
2
  export { ArticleFAQ } from '../chunk-BVB5FBAA.js';
4
- import { getAuthorSocialLinks, readingTimeMinutes } from '../chunk-BC7JMY4Z.js';
5
- export { ClusterNavigation, ServiceCallout, ServiceCallouts } from '../chunk-BC7JMY4Z.js';
3
+ import { NewsletterShell } from '../chunk-JHTPHA2D.js';
4
+ import { getAuthorSocialLinks, generateTableOfContents, readingTimeMinutes } from '../chunk-JG53YJLM.js';
5
+ export { ClusterNavigation, ServiceCallout, ServiceCallouts } from '../chunk-JG53YJLM.js';
6
6
  import '../chunk-DJAYFHVF.js';
7
- export { addExternalLinkTargets, linkClassificationHost, normalizeSiteHost, resolvePublicationSiteUrl } from '../chunk-5D7ZISUP.js';
7
+ export { addExternalLinkTargets, linkClassificationHost, normalizeSiteHost, resolvePublicationSiteUrl } from '../chunk-7DYMM6SS.js';
8
8
  import { generateAuthorSchema, resolveArticleArtwork, articleArtworkImageStyle } from '../chunk-UVYUTBT4.js';
9
9
  export { resolveArticleArtwork } from '../chunk-UVYUTBT4.js';
10
10
  import '../chunk-H72ZFO3F.js';
11
+ import '../chunk-IBHBEUZV.js';
11
12
  import { createPublicationRoutes } from '../chunk-4K735O3J.js';
12
13
  export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-4K735O3J.js';
13
14
  import { safeJsonLd } from '../chunk-4KZ6W3ZH.js';
@@ -20,7 +21,7 @@ import '../chunk-PKBMQBKP.js';
20
21
  import React, { useState, Suspense, useEffect } from 'react';
21
22
  import { jsx, jsxs } from 'react/jsx-runtime';
22
23
 
23
- var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-RWKFWZ72.js'));
24
+ var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-AUZ6YB7G.js'));
24
25
  function NewsletterWidget({
25
26
  title = "Subscribe to Our Newsletter",
26
27
  description = "Get the latest posts delivered straight to your inbox.",
@@ -376,27 +377,13 @@ function AuthorPage({ author, posts, basePath, routing, siteUrl, siteName, jsonL
376
377
  ] })
377
378
  ] });
378
379
  }
379
- function parseHeadings(content) {
380
- const headingRegex = /<h([2-4])[^>]*id="([^"]*)"[^>]*>(.*?)<\/h[2-4]>/gi;
381
- const items = [];
382
- let match;
383
- while ((match = headingRegex.exec(content)) !== null) {
384
- items.push({
385
- level: parseInt(match[1]),
386
- id: match[2],
387
- text: match[3].replace(/<[^>]*>/g, "")
388
- // Strip any nested HTML
389
- });
390
- }
391
- return items;
392
- }
393
380
  function TableOfContents({
394
381
  content,
395
382
  className,
396
383
  maxDepth = 3
397
384
  }) {
398
385
  const [activeId, setActiveId] = useState("");
399
- const items = parseHeadings(content).filter((item) => item.level <= maxDepth);
386
+ const items = generateTableOfContents(content).filter((item) => item.level <= maxDepth);
400
387
  useEffect(() => {
401
388
  if (typeof window === "undefined") return;
402
389
  const observer = new IntersectionObserver(
@@ -1,37 +1,52 @@
1
- import { readingTimeMinutes, ServiceCallouts, ClusterNavigation, getAuthorSocialLinks } from '../chunk-BC7JMY4Z.js';
2
- export { ClusterNavigation } from '../chunk-BC7JMY4Z.js';
1
+ import { generateTableOfContents, readingTimeMinutes, ServiceCallouts, ClusterNavigation, getAuthorSocialLinks, scanHeadings, ownId, slugify } from '../chunk-JG53YJLM.js';
2
+ export { ClusterNavigation } from '../chunk-JG53YJLM.js';
3
3
  import { widgetStyle, widgetTitleStyle } from '../chunk-DJAYFHVF.js';
4
- import { resolvePublicationSiteUrl, addExternalLinkTargets } from '../chunk-5D7ZISUP.js';
5
- import { fetchArticleBySlug, fetchRelatedArticles, fetchArticleCategories, getTopicCluster, ArticleUnavailableError } from '../chunk-RI2N2EBI.js';
4
+ import { resolvePublicationSiteUrl, addExternalLinkTargets } from '../chunk-7DYMM6SS.js';
5
+ import { fetchArticleBySlug, articleBodyHtml, fetchRelatedArticles, fetchArticleCategories, getTopicCluster, ArticleUnavailableError } from '../chunk-JYITKUUB.js';
6
6
  import { insertArticlePhotos } from '../chunk-WHPCGQHC.js';
7
7
  export { articlePhotoCss, insertArticlePhotos } from '../chunk-WHPCGQHC.js';
8
- export { articleTableCss, wrapArticleTables } from '../chunk-E4PTMORJ.js';
8
+ export { articleTableCss, wrapArticleTables } from '../chunk-AL5UCWLI.js';
9
9
  import { resolveArticleArtwork, articleArtworkImageStyle } from '../chunk-UVYUTBT4.js';
10
10
  export { resolveArticleArtwork } from '../chunk-UVYUTBT4.js';
11
11
  import '../chunk-H72ZFO3F.js';
12
+ import { stripHtmlTags } from '../chunk-IBHBEUZV.js';
12
13
  import { createPublicationRoutes, articleCategorySlug } from '../chunk-4K735O3J.js';
13
14
  export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-4K735O3J.js';
14
15
  import '../chunk-34ZYJTQR.js';
15
- import '../chunk-T6U6J3QK.js';
16
+ import '../chunk-T6TWPKBL.js';
16
17
  import '../chunk-UAYAJPEP.js';
17
18
  import '../chunk-VWWITFWM.js';
18
19
  import '../chunk-4KZ6W3ZH.js';
19
20
  import { withSiteParam } from '../chunk-MJP63SSS.js';
20
- import '../chunk-6KU7STM3.js';
21
+ import '../chunk-HY7ZEU2C.js';
21
22
  import '../chunk-C7TLGL3R.js';
22
23
  import '../chunk-MH2DSGC6.js';
23
24
  import '../chunk-YVKRYQRG.js';
24
25
  import '../chunk-FESKKJAS.js';
25
26
  import '../chunk-A4CC4ZG3.js';
26
27
  import '../chunk-W7OPEMGJ.js';
27
- import '../chunk-CFSIGEUW.js';
28
+ import '../chunk-MNORERMF.js';
28
29
  import '../chunk-PKBMQBKP.js';
29
30
  import 'server-only';
30
- import { marked } from 'marked';
31
31
  import { notFound } from 'next/navigation';
32
32
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
33
33
  import React from 'react';
34
34
 
35
+ // packages/press-kit/src/articles/article-heading-ids.ts
36
+ function injectHeadingIds(html) {
37
+ let output = "";
38
+ let cursor = 0;
39
+ for (const { level, attributes, inner, start, end } of scanHeadings(html)) {
40
+ output += html.slice(cursor, start);
41
+ cursor = end;
42
+ if (ownId(attributes) !== null) {
43
+ output += html.slice(start, end);
44
+ continue;
45
+ }
46
+ output += `<h${level}${attributes} id="${slugify(stripHtmlTags(inner))}">${inner}</h${level}>`;
47
+ }
48
+ return output + html.slice(cursor);
49
+ }
35
50
  function getClusterNav(post) {
36
51
  if (!post.cluster_id && !post.cluster_slug) return null;
37
52
  const isPillar = post.article_type === "pillar";
@@ -47,46 +62,6 @@ function getClusterNav(post) {
47
62
  is_pillar: isPillar
48
63
  };
49
64
  }
50
- function looksLikeMarkdown(text) {
51
- if (text.trimStart().startsWith("<")) return false;
52
- const markers = [/^#{1,6}\s/m, /\*\*[^*]+\*\*/, /\[([^\]]+)\]\([^)]+\)/, /^[-*]\s/m, /^>\s/m];
53
- let hits = 0;
54
- for (const re of markers) if (re.test(text)) hits++;
55
- return hits >= 2;
56
- }
57
- function slugify(text) {
58
- return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
59
- }
60
- function ensureHtml(raw) {
61
- if (!raw) return raw;
62
- let html = raw;
63
- if (looksLikeMarkdown(html)) {
64
- html = marked.parse(html, { gfm: true, breaks: false, async: false });
65
- }
66
- html = injectHeadingIds(html);
67
- return html;
68
- }
69
- function injectHeadingIds(html) {
70
- return html.replace(/<h([2-4])([^>]*)>(.*?)<\/h[2-4]>/gi, (_full, level, attrs, inner) => {
71
- if (/\bid\s*=/i.test(attrs)) return _full;
72
- const text = inner.replace(/<[^>]*>/g, "");
73
- const id = slugify(text);
74
- return `<h${level}${attrs} id="${id}">${inner}</h${level}>`;
75
- });
76
- }
77
- function generateTableOfContents(html) {
78
- const headingRegex = /<h([2-4])[^>]*(?:id="([^"]*)")?[^>]*>(.*?)<\/h[2-4]>/gi;
79
- const items = [];
80
- let match;
81
- while ((match = headingRegex.exec(html)) !== null) {
82
- const level = parseInt(match[1]);
83
- const existingId = match[2];
84
- const text = match[3].replace(/<[^>]*>/g, "");
85
- const id = existingId || slugify(text);
86
- items.push({ id, text, level });
87
- }
88
- return items;
89
- }
90
65
  function cls(unstyled, styles, key, defaultClass, extra) {
91
66
  if (unstyled) return styles[key] || void 0;
92
67
  const base = styles[key] || defaultClass;
@@ -118,8 +93,8 @@ async function Article({
118
93
  }
119
94
  const [post, { articleCss }, { wrapArticleTables: wrapArticleTables2 }] = await Promise.all([
120
95
  fetchArticleBySlug({ apiUrl, apiKey, site }, slug),
121
- unstyled ? Promise.resolve({ articleCss: "" }) : import('../article-styles-VASFBYA3.js'),
122
- import('../article-tables-6XHVULPU.js')
96
+ unstyled ? Promise.resolve({ articleCss: "" }) : import('../article-styles-D7VCDXMG.js'),
97
+ import('../article-tables-W45BE353.js')
123
98
  ]);
124
99
  if (!post) {
125
100
  if (notFound$1) notFound();
@@ -132,8 +107,7 @@ async function Article({
132
107
  ] })
133
108
  ] });
134
109
  }
135
- const rawContent = post.content_html || post.content || "";
136
- const content = ensureHtml(rawContent);
110
+ const content = injectHeadingIds(articleBodyHtml(post));
137
111
  const siteUrlResolved = resolvePublicationSiteUrl(siteUrl);
138
112
  const contentWithExternalTargets = wrapArticleTables2(addExternalLinkTargets(insertArticlePhotos(content, post.editorial_photos), siteUrlResolved));
139
113
  const artwork = resolveArticleArtwork(post, "article");
@@ -144,7 +118,7 @@ async function Article({
144
118
  ...item,
145
119
  answer: addExternalLinkTargets(item.answer || "", siteUrlResolved)
146
120
  })) ?? faqRaw;
147
- const { ArticleViewTracker } = await import('../ArticleViewTracker-XEA6ZY67.js');
121
+ const { ArticleViewTracker } = await import('../ArticleViewTracker-KNXP2DXL.js');
148
122
  if (children) {
149
123
  return /* @__PURE__ */ jsxs(Fragment, { children: [
150
124
  /* @__PURE__ */ jsx(ArticleViewTracker, { slug: post.slug, site }),
@@ -426,7 +400,7 @@ async function ArticleList({
426
400
  const [articleData, categories, { articleListCss }] = await Promise.all([
427
401
  fetchArticleList({ apiUrl, apiKey, category, tag, author, featured, search, cluster, page, perPage, orderBy, order, site }),
428
402
  showCategoryFilter ? fetchArticleCategories({ apiUrl, apiKey, site }) : Promise.resolve([]),
429
- unstyled || children ? Promise.resolve({ articleListCss: "" }) : import('../article-styles-VASFBYA3.js')
403
+ unstyled || children ? Promise.resolve({ articleListCss: "" }) : import('../article-styles-D7VCDXMG.js')
430
404
  ]);
431
405
  if (children) {
432
406
  return children({ posts: articleData.posts, pagination: articleData.pagination, categories });
@@ -1,21 +1,22 @@
1
- export { ArticleUnavailableError, FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, PUBLICATION_PREVIEW_COOKIE, PUBLICATION_PREVIEW_HEADERS, SEO_LIMITS, buildNewsSitemapXml, cdata, createPublicationPreviewHandler, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getArticlePreview, getArticleResult, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getPublicationIssue, getPublicationIssues, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle } from '../chunk-RI2N2EBI.js';
1
+ export { ArticleUnavailableError, FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, PUBLICATION_PREVIEW_COOKIE, PUBLICATION_PREVIEW_HEADERS, SEO_LIMITS, buildNewsSitemapXml, cdata, createPublicationPreviewHandler, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getArticlePreview, getArticleResult, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getPublicationIssue, getPublicationIssues, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle } from '../chunk-JYITKUUB.js';
2
2
  export { articlePhotoCss, insertArticlePhotos } from '../chunk-WHPCGQHC.js';
3
- export { articleTableCss, wrapArticleTables } from '../chunk-E4PTMORJ.js';
3
+ export { articleTableCss, wrapArticleTables } from '../chunk-AL5UCWLI.js';
4
4
  export { articleImageSchema, authorEntityId, generateArticleAuthorNode, generateAuthorPersonSchema, generateAuthorSchema, resolveArticleArtwork, resolveRepresentativeImage, withArticleAuthorIdentity } from '../chunk-UVYUTBT4.js';
5
5
  import '../chunk-H72ZFO3F.js';
6
+ import '../chunk-IBHBEUZV.js';
6
7
  export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-4K735O3J.js';
7
8
  import '../chunk-34ZYJTQR.js';
8
- import '../chunk-T6U6J3QK.js';
9
+ import '../chunk-T6TWPKBL.js';
9
10
  import '../chunk-UAYAJPEP.js';
10
11
  import '../chunk-VWWITFWM.js';
11
12
  import '../chunk-4KZ6W3ZH.js';
12
13
  import '../chunk-MJP63SSS.js';
13
- import '../chunk-6KU7STM3.js';
14
+ import '../chunk-HY7ZEU2C.js';
14
15
  import '../chunk-C7TLGL3R.js';
15
16
  import '../chunk-MH2DSGC6.js';
16
17
  import '../chunk-YVKRYQRG.js';
17
18
  import '../chunk-FESKKJAS.js';
18
19
  import '../chunk-A4CC4ZG3.js';
19
20
  import '../chunk-W7OPEMGJ.js';
20
- import '../chunk-CFSIGEUW.js';
21
+ import '../chunk-MNORERMF.js';
21
22
  import '../chunk-PKBMQBKP.js';
@@ -1,26 +1,26 @@
1
1
  'use client';
2
- export { ChatWidget, DEFAULT_LAUNCHER_OFFSET_BOTTOM, EchoChat, chatLauncherStyles, isChatEnabled } from '../chunk-ITQND6IB.js';
3
- export { SiteChat } from '../chunk-ANVHRT35.js';
2
+ export { ChatWidget, DEFAULT_LAUNCHER_OFFSET_BOTTOM, EchoChat, chatLauncherStyles, isChatEnabled } from '../chunk-BJYX6SFI.js';
3
+ export { SiteChat } from '../chunk-BAJUXQTH.js';
4
4
  import '../chunk-6T6CQVNL.js';
5
5
  import '../chunk-JE4A5S4F.js';
6
6
  import '../chunk-27FISYK4.js';
7
- import '../chunk-27LYZVPP.js';
7
+ import '../chunk-LGWN6KCN.js';
8
8
  import '../chunk-Q6E4OPGG.js';
9
9
  import '../chunk-5ROTTMBL.js';
10
10
  import '../chunk-C2FZBUSS.js';
11
- import '../chunk-5SQK3D53.js';
11
+ import '../chunk-TYSIAWC3.js';
12
12
  import '../chunk-HW7B43E5.js';
13
13
  import '../chunk-NJCTQH2P.js';
14
14
  import '../chunk-S22FSH7C.js';
15
15
  import '../chunk-L2V5PUFN.js';
16
16
  import '../chunk-GJWI74ZZ.js';
17
17
  import '../chunk-5TM3WPCI.js';
18
- import '../chunk-DLM4FFNH.js';
19
- import '../chunk-EKBEOXTH.js';
20
- import '../chunk-GDQKDL3E.js';
21
- import '../chunk-OEA7U4HJ.js';
18
+ import '../chunk-QTBAKOCZ.js';
19
+ import '../chunk-VEJD5EJ2.js';
20
+ import '../chunk-UYOE3HA4.js';
21
+ import '../chunk-P5PRR2BB.js';
22
22
  import '../chunk-W7OPEMGJ.js';
23
- import '../chunk-CFSIGEUW.js';
23
+ import '../chunk-MNORERMF.js';
24
24
  import '../chunk-PKBMQBKP.js';
25
25
 
26
26
  // src/chat/echo-config.ts
@@ -1,6 +1,6 @@
1
1
  import { SLOTS_CONTRACT_VERSION, verifySlotContent, canonicalJson } from './chunk-VCJYLYJV.js';
2
2
  import { isValidSlotId, SLOT_CONTENT_MAX_LENGTH, parseSlotRichText, normalizeSlotValue } from './chunk-LPH5FANE.js';
3
- import { SITE_CACHE_TAGS } from './chunk-6KU7STM3.js';
3
+ import { SITE_CACHE_TAGS } from './chunk-HY7ZEU2C.js';
4
4
  import { resolveServerApiConfig } from './chunk-C7TLGL3R.js';
5
5
  import 'server-only';
6
6
  import * as React from 'react';
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { isEmptyValue, isDisplayOnly } from './chunk-C2FZBUSS.js';
3
- import { useMemo, useState, useRef, useEffect } from 'react';
3
+ import { useMemo, useState, useEffect } from 'react';
4
4
 
5
5
  var NO_CONTROLS = {};
6
6
  function useFieldControls(fields) {
@@ -13,23 +13,18 @@ function useFieldControls(fields) {
13
13
  [fields]
14
14
  );
15
15
  const [controls, setControls] = useState(NO_CONTROLS);
16
- const requested = useRef({ date: false, file: false });
17
16
  useEffect(() => {
18
17
  let cancelled = false;
19
- if (needsDate && !requested.current.date) {
20
- requested.current.date = true;
18
+ if (needsDate) {
21
19
  import('./DatePicker-JEBV6WYJ.js').then((m) => {
22
20
  if (!cancelled) setControls((prev) => ({ ...prev, Date: m.DatePicker }));
23
21
  }).catch(() => {
24
- requested.current.date = false;
25
22
  });
26
23
  }
27
- if (needsFile && !requested.current.file) {
28
- requested.current.file = true;
29
- import('./FileField-F7BG4XAZ.js').then((m) => {
24
+ if (needsFile) {
25
+ import('./FileField-P3PLEAON.js').then((m) => {
30
26
  if (!cancelled) setControls((prev) => ({ ...prev, File: m.FileField }));
31
27
  }).catch(() => {
32
- requested.current.file = false;
33
28
  });
34
29
  }
35
30
  return () => {
@@ -0,0 +1,8 @@
1
+ // src/contracts/campaign-normalize.ts
2
+ function normalizeCampaignSlug(input) {
3
+ if (!input || typeof input !== "string") return null;
4
+ const slug = input.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
5
+ return slug || null;
6
+ }
7
+
8
+ export { normalizeCampaignSlug };
@@ -1,4 +1,4 @@
1
- import { writeLLMsTxtToPublic } from './chunk-URZTBPZO.js';
1
+ import { writeLLMsTxtToPublic } from './chunk-XZFOQ2V4.js';
2
2
  import { getSiteConfig } from './chunk-Z22QVHT4.js';
3
3
  import { buildFetch } from './chunk-UAYAJPEP.js';
4
4
  import { findAppDirForDiscovery } from './chunk-ZEGVKVD5.js';
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { normalizeDesignTokens, designTokenCssVars, sanitizePopupHtml, isSafePopupUrl } from './chunk-IHG36STL.js';
2
+ import { normalizeDesignTokens, designTokenCssVars, sanitizePopupHtml, isSafePopupUrl } from './chunk-XHYE24HU.js';
3
3
  import { useId, useRef, useEffect } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZTZQPYP6.js';
3
3
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
4
- import { resolveAnalyticsTarget } from './chunk-DLM4FFNH.js';
5
- import { sonorFetch } from './chunk-GDQKDL3E.js';
6
- import { SITE_KIT_VERSION } from './chunk-CFSIGEUW.js';
4
+ import { resolveAnalyticsTarget } from './chunk-QTBAKOCZ.js';
5
+ import { sonorFetch } from './chunk-UYOE3HA4.js';
6
+ import { SITE_KIT_VERSION } from './chunk-MNORERMF.js';
7
7
  import { useRef, useEffect } from 'react';
8
8
 
9
9
  // src/fleet/heartbeat.ts
@@ -1,3 +1,5 @@
1
+ import { htmlTags, isClosingTag, htmlTagName, openTagAttributes } from './chunk-IBHBEUZV.js';
2
+
1
3
  // packages/press-kit/src/articles/processArticleHtml.ts
2
4
  function linkClassificationHost(siteUrl) {
3
5
  try {
@@ -24,20 +26,23 @@ function addExternalLinkTargets(html, siteUrl) {
24
26
  if (!html || !siteUrl) return html;
25
27
  const siteHost = linkClassificationHost(siteUrl);
26
28
  if (!siteHost) return html;
27
- return html.replace(/<a\b([^>]*)>/gi, (_full, attrs) => {
29
+ return html.replace(htmlTags(), (tag) => {
30
+ if (isClosingTag(tag) || htmlTagName(tag) !== "a") return tag;
31
+ const attrs = openTagAttributes(tag);
32
+ const unchanged = `<a${attrs}>`;
28
33
  const hrefMatch = attrs.match(/\bhref\s*=\s*(["'])([^"']*)\1/i);
29
- if (!hrefMatch) return `<a${attrs}>`;
34
+ if (!hrefMatch) return unchanged;
30
35
  const href = hrefMatch[2].trim();
31
- if (!/^https?:\/\//i.test(href)) return `<a${attrs}>`;
36
+ if (!/^https?:\/\//i.test(href)) return unchanged;
32
37
  try {
33
38
  const url = new URL(href);
34
39
  const linkHost = url.hostname.replace(/^www\./i, "").toLowerCase();
35
- if (linkHost === siteHost) return `<a${attrs}>`;
36
- if (/\btarget\s*=/i.test(attrs)) return `<a${attrs}>`;
40
+ if (linkHost === siteHost) return unchanged;
41
+ if (/\btarget\s*=/i.test(attrs)) return unchanged;
37
42
  const trimmed = attrs.trim();
38
43
  return `<a ${trimmed} target="_blank" rel="noopener noreferrer">`;
39
44
  } catch {
40
- return `<a${attrs}>`;
45
+ return unchanged;
41
46
  }
42
47
  });
43
48
  }
@@ -2,8 +2,8 @@
2
2
  import { registerAnalyticsDispatcher } from './chunk-LCDVPAMR.js';
3
3
  import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-IPQKQEWI.js';
4
4
  import { onPageLeave } from './chunk-L2V5PUFN.js';
5
- import { resolveAnalyticsTarget } from './chunk-DLM4FFNH.js';
6
- import { sonorFetch, sonorBeacon } from './chunk-GDQKDL3E.js';
5
+ import { resolveAnalyticsTarget } from './chunk-QTBAKOCZ.js';
6
+ import { sonorFetch, sonorBeacon } from './chunk-UYOE3HA4.js';
7
7
  import { createContext, useRef, useEffect, useState, useMemo, useCallback, useContext } from 'react';
8
8
  import { usePathname } from 'next/navigation';
9
9
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -228,6 +228,18 @@ function WebVitals({
228
228
  }, []);
229
229
  return null;
230
230
  }
231
+
232
+ // src/analytics/content-text.ts
233
+ var BLOCK_ELEMENTS = "address, article, aside, blockquote, dd, details, div, dl, dt, fieldset, figcaption, figure, h1, h2, h3, h4, h5, h6, hr, li, ol, p, pre, section, summary, table, td, th, tr, ul";
234
+ var NOT_CONTENT = 'script, style, noscript, template, svg, nav, header, footer, label, button, input, select, textarea, option, [role="navigation"], [role="banner"], [role="contentinfo"], [role="dialog"], [role="alert"]';
235
+ var CONTENT_TEXT_MAX_LENGTH = 1e4;
236
+ function extractContentText(root) {
237
+ const clone = root.cloneNode(true);
238
+ clone.querySelectorAll(NOT_CONTENT).forEach((el) => el.remove());
239
+ clone.querySelectorAll("br").forEach((br) => br.replaceWith(" "));
240
+ clone.querySelectorAll(BLOCK_ELEMENTS).forEach((el) => el.append(" "));
241
+ return (clone.textContent || "").replace(/\s+/g, " ").trim().slice(0, CONTENT_TEXT_MAX_LENGTH);
242
+ }
231
243
  var AnalyticsContext = createContext(null);
232
244
  function scheduleIdleTask(callback, timeout = 2e3) {
233
245
  if (typeof window !== "undefined" && "requestIdleCallback" in window) {
@@ -485,11 +497,7 @@ function getContentPageMetadata() {
485
497
  };
486
498
  const getContentText = () => {
487
499
  const main = document.querySelector('main, article, [role="main"]') || document.body;
488
- const clone = main.cloneNode(true);
489
- clone.querySelectorAll('script, style, nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]').forEach((el) => el.remove());
490
- let text = clone.textContent || "";
491
- text = text.replace(/\s+/g, " ").trim();
492
- text = text.slice(0, 1e4);
500
+ const text = extractContentText(main);
493
501
  let hash = 0;
494
502
  for (let i = 0; i < text.length; i++) {
495
503
  const chr = text.charCodeAt(i);
@@ -1,4 +1,4 @@
1
- import { publishSiteCredential } from './chunk-FVXCQC7W.js';
1
+ import { publishSiteCredential } from './chunk-JWCCY72G.js';
2
2
 
3
3
  // src/client/SiteKitCredential.tsx
4
4
  function SiteKitCredential({
@@ -1,3 +1,5 @@
1
+ import { htmlTags, htmlTagName, isClosingTag } from './chunk-IBHBEUZV.js';
2
+
1
3
  // packages/press-kit/src/articles/article-tables.ts
2
4
  var tableScrollClass = "sk-article-table-scroll";
3
5
  var legacyTableScrollClass = "sk-blog-table-scroll";
@@ -18,9 +20,6 @@ var voidElements = /* @__PURE__ */ new Set([
18
20
  "wbr"
19
21
  ]);
20
22
  var preservedElements = /* @__PURE__ */ new Set(["pre", "code", "script", "style", "textarea", "xmp", "template"]);
21
- function htmlTags() {
22
- return /<!--[\s\S]*?(?:-->|$)|<\/?[a-z][\w:-]*(?=[\s/>])(?:[^"'<>]|"[^"]*"|'[^']*')*>/gi;
23
- }
24
23
  function hasScrollClass(tag) {
25
24
  const attributes = tag.replace(/^<[\w:-]+/, "").replace(/\/?>$/, "");
26
25
  const pattern = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
@@ -31,14 +30,30 @@ function hasScrollClass(tag) {
31
30
  return false;
32
31
  }
33
32
  function labelText(html) {
34
- return html.replace(/<!--[\s\S]*?(?:-->|$)/g, "").replace(htmlTags(), " ").replace(/\s+/g, " ").trim();
33
+ return html.replace(htmlTags(), (token) => token.startsWith("<!--") ? "" : " ").replace(/\s+/g, " ").trim();
35
34
  }
36
35
  function escapeLabel(text) {
37
36
  return text.replace(/&(?!(?:#\d+|#x[\da-f]+|[a-z][\da-z]+);)/gi, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
38
37
  }
38
+ function elementContents(table, name) {
39
+ const tags = htmlTags();
40
+ const contents = [];
41
+ let from = -1;
42
+ let token;
43
+ while (token = tags.exec(table)) {
44
+ if (htmlTagName(token[0]) !== name) continue;
45
+ if (!isClosingTag(token[0])) {
46
+ if (from < 0) from = tags.lastIndex;
47
+ } else if (from >= 0) {
48
+ contents.push(table.slice(from, token.index));
49
+ from = -1;
50
+ }
51
+ }
52
+ return contents;
53
+ }
39
54
  function tableLabel(table, number) {
40
- const caption = table.match(/<caption\b(?:[^"'<>]|"[^"]*"|'[^']*')*>([\s\S]*?)<\/caption\s*>/i)?.[1];
41
- const headers = [...table.matchAll(/<th\b(?:[^"'<>]|"[^"]*"|'[^']*')*>([\s\S]*?)<\/th\s*>/gi)].slice(0, 4).map((match) => labelText(match[1])).filter(Boolean).join(", ");
55
+ const caption = elementContents(table, "caption")[0];
56
+ const headers = elementContents(table, "th").slice(0, 4).map(labelText).filter(Boolean).join(", ");
42
57
  const summary = labelText(caption || headers).slice(0, 180);
43
58
  return escapeLabel(`Table ${number}${summary ? `: ${summary}` : ""}`);
44
59
  }
@@ -50,8 +65,8 @@ function wrapArticleTables(html) {
50
65
  let token;
51
66
  while (token = tags.exec(html)) {
52
67
  const tag = token[0];
53
- if (tag.startsWith("<!--")) continue;
54
- const tagName = /^<\/?([\w:-]+)/.exec(tag)[1].toLowerCase();
68
+ const tagName = htmlTagName(tag);
69
+ if (!tagName) continue;
55
70
  if (tag.startsWith("</")) {
56
71
  const index = stack.map((frame3) => frame3.tag).lastIndexOf(tagName);
57
72
  if (index < 0) continue;
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
  import { DEFAULT_WIDGET_Z_INDEX } from './chunk-27FISYK4.js';
3
- import { resolveAnalyticsTarget } from './chunk-DLM4FFNH.js';
3
+ import { resolveAnalyticsTarget } from './chunk-QTBAKOCZ.js';
4
4
  import { useState, useEffect } from 'react';
5
5
  import ReactDOM from 'react-dom';
6
6
  import dynamic from 'next/dynamic';
7
7
  import { jsx } from 'react/jsx-runtime';
8
8
 
9
9
  var LazyChatWidget = dynamic(
10
- () => import('./ChatWidget-PMVQTSEU.js').then((m) => ({ default: m.ChatWidget })),
10
+ () => import('./ChatWidget-L74L4YAD.js').then((m) => ({ default: m.ChatWidget })),
11
11
  { ssr: false }
12
12
  );
13
13
  function SiteChat(props) {
@@ -2,9 +2,9 @@
2
2
  import { VISUAL_VIEWPORT_GAP_PROPERTY } from './chunk-6T6CQVNL.js';
3
3
  import { GlassStyles } from './chunk-JE4A5S4F.js';
4
4
  import { DEFAULT_WIDGET_Z_INDEX } from './chunk-27FISYK4.js';
5
- import { useForm } from './chunk-27LYZVPP.js';
5
+ import { useForm } from './chunk-LGWN6KCN.js';
6
6
  import { parseColor, relativeLuminance, DARK_LUMINANCE, contrastRatio } from './chunk-S22FSH7C.js';
7
- import { sonorFetch } from './chunk-GDQKDL3E.js';
7
+ import { sonorFetch } from './chunk-UYOE3HA4.js';
8
8
  import { readPublishedApiConfig } from './chunk-W7OPEMGJ.js';
9
9
  import { useState, useEffect, useRef, useLayoutEffect, useCallback, Fragment as Fragment$1 } from 'react';
10
10
  import { lexer } from 'marked';
@@ -609,12 +609,18 @@ function FormField({ field, value, error, onChange, onFocus, onBlur, classPrefix
609
609
  inputId,
610
610
  classPrefix,
611
611
  baseInputStyle,
612
- onChange: emit
612
+ onChange: emit,
613
+ ariaInvalid: a11y["aria-invalid"],
614
+ describedBy
613
615
  }
614
616
  ) : (
615
617
  // Static: a real file input so the field is visible and labelled,
616
618
  // but the Sonor upload only happens once enhanced.
617
- /* @__PURE__ */ jsx(
619
+ field.validation?.private_attachments ? /* @__PURE__ */ jsxs("div", { className: "sk-file-dropzone", "aria-busy": "true", children: [
620
+ /* @__PURE__ */ jsx("span", { className: "sk-file-dropzone__title", children: "Drop your estimate here" }),
621
+ /* @__PURE__ */ jsx("span", { className: "sk-file-dropzone__hint", children: "Preparing private upload\u2026" }),
622
+ /* @__PURE__ */ jsx("input", { id: inputId, type: "file", name: field.slug, disabled: true, "aria-label": field.label, className: "sk-file-dropzone__input" })
623
+ ] }) : /* @__PURE__ */ jsx(
618
624
  "input",
619
625
  {
620
626
  id: inputId,
@@ -1,5 +1,5 @@
1
1
  import { readAnalyticsIdentity } from './chunk-5ROTTMBL.js';
2
- import { sonorFetch } from './chunk-GDQKDL3E.js';
2
+ import { sonorFetch } from './chunk-UYOE3HA4.js';
3
3
  import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
4
4
 
5
5
  // src/sync/api.ts
@@ -1,5 +1,5 @@
1
- import { FormEnhancer } from './chunk-GLLFIE2R.js';
2
- import { StaticForm } from './chunk-LNSF6BJC.js';
1
+ import { FormEnhancer } from './chunk-G5FD7UXK.js';
2
+ import { StaticForm } from './chunk-VPZJ7ZTL.js';
3
3
  import { serverApiFetch } from './chunk-C7TLGL3R.js';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { freshFetch } from './chunk-UAYAJPEP.js';
2
- import { LLM_GEO_CONTRACT_VERSION } from './chunk-NZ4RXN3G.js';
2
+ import { LLM_GEO_CONTRACT_VERSION } from './chunk-XAZC2TUD.js';
3
3
  import { withSiteParam } from './chunk-MJP63SSS.js';
4
4
  import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
5
5
  import { cache } from 'react';