@burdenoff/website-sdk 2026.1024.1 → 2026.1027.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +77 -1
  2. package/dist/components/explore-cta.d.mts +10 -1
  3. package/dist/components/explore-cta.d.ts +10 -1
  4. package/dist/components/explore-cta.js +82 -74
  5. package/dist/components/explore-cta.js.map +1 -1
  6. package/dist/components/explore-cta.mjs +83 -75
  7. package/dist/components/explore-cta.mjs.map +1 -1
  8. package/dist/components/explore.d.mts +2 -2
  9. package/dist/components/explore.d.ts +2 -2
  10. package/dist/components/explore.js +876 -510
  11. package/dist/components/explore.js.map +1 -1
  12. package/dist/components/explore.mjs +877 -511
  13. package/dist/components/explore.mjs.map +1 -1
  14. package/dist/{explore-POqE7J8r.d.mts → explore-BEgq1_0O.d.mts} +65 -3
  15. package/dist/{explore-D6kon7uz.d.ts → explore-CHiP9u-4.d.ts} +65 -3
  16. package/dist/{explore-types-BB8HNFzX.d.mts → explore-types-_9UJu6EA.d.mts} +1 -1
  17. package/dist/{explore-types-BB8HNFzX.d.ts → explore-types-_9UJu6EA.d.ts} +1 -1
  18. package/dist/hooks/index.d.mts +2 -2
  19. package/dist/hooks/index.d.ts +2 -2
  20. package/dist/hooks/index.js +15 -9
  21. package/dist/hooks/index.js.map +1 -1
  22. package/dist/hooks/index.mjs +15 -9
  23. package/dist/hooks/index.mjs.map +1 -1
  24. package/dist/index.d.mts +177 -6
  25. package/dist/index.d.ts +177 -6
  26. package/dist/index.js +1236 -152
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +1236 -155
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/{use-progressive-reveal-Kr6DwGXG.d.mts → use-progressive-reveal-BFPWbEXy.d.mts} +25 -2
  31. package/dist/{use-progressive-reveal-BVJn9NIr.d.ts → use-progressive-reveal-C0hkdu_i.d.ts} +25 -2
  32. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { createContext, useMemo, useState, useRef, useEffect, useCallback, useContext, Children, isValidElement, cloneElement, useId } from 'react';
2
+ import { createContext, useContext, useMemo, useRef, useEffect, useState, useCallback, Children, isValidElement, cloneElement, useId } from 'react';
3
3
  import { Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink, Check, Copy, ThumbsUp, ThumbsDown, Volume2, Film, Play, Minimize, Maximize, VideoOff } from 'lucide-react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -22,10 +22,26 @@ var RTL_LOCALES = /* @__PURE__ */ new Set(["ar"]);
22
22
  function isRtlLocale(locale) {
23
23
  return RTL_LOCALES.has(locale);
24
24
  }
25
+ var PORTFOLIO_PROMPT = {
26
+ en: "Which of your products fits a problem like mine?",
27
+ zh: "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u8FD9\u6837\u7684\u95EE\u9898\uFF1F",
28
+ hi: "\u092E\u0947\u0930\u0940 \u091C\u0948\u0938\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?",
29
+ es: "\xBFQu\xE9 producto encaja con un problema como el m\xEDo?",
30
+ ar: "\u0623\u064A \u0645\u0646\u062A\u062C \u064A\u0646\u0627\u0633\u0628 \u0645\u0634\u0643\u0644\u0629 \u0645\u062B\u0644 \u0645\u0634\u0643\u0644\u062A\u064A\u061F",
31
+ ta: "\u0B8E\u0BA9\u0BCD \u0BAA\u0BBF\u0BB0\u0B9A\u0BCD\u0B9A\u0BBF\u0BA9\u0BC8\u0B95\u0BCD\u0B95\u0BC1 \u0B8E\u0BA8\u0BCD\u0BA4\u0BA4\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD?"
32
+ };
33
+ var PORTFOLIO_PROMPTS = new Set(
34
+ Object.values(PORTFOLIO_PROMPT)
35
+ );
36
+ function isPortfolioPrompt(prompt) {
37
+ return PORTFOLIO_PROMPTS.has(prompt);
38
+ }
25
39
  var EN = {
26
40
  badge: "AI answers, grounded in our documentation",
27
41
  welcomeTitle: "What problem are you trying to solve?",
28
42
  welcomeBody: "Describe the problem, in your own words. You can also ask about a specific product or compare a few. Every answer comes straight from our documentation.",
43
+ welcomeBodyProduct: "Describe the problem in your own words, or ask what {product} does. Every answer comes straight from our documentation.",
44
+ welcomeBodyScoped: "Describe the problem in your own words. Every answer comes straight from our documentation.",
29
45
  tryAsking: "Try asking",
30
46
  focusProduct: "Focus on a product",
31
47
  allProducts: "All products",
@@ -35,6 +51,7 @@ var EN = {
35
51
  nextYouCouldAsk: "Next you could ask",
36
52
  placeholder: "Describe the problem\u2026",
37
53
  placeholderProduct: "Describe a problem, or ask about {product}\u2026",
54
+ placeholderScoped: "Ask about {product}\u2026",
38
55
  send: "Send",
39
56
  stop: "Stop",
40
57
  newChat: "New chat",
@@ -56,6 +73,7 @@ var EN = {
56
73
  attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
57
74
  noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
58
75
  answerDidNotArrive: "That answer didn't come through. Try asking again.",
76
+ toolBudgetScoped: "That question covers more than I can look through in one go. Try asking about one part of it.",
59
77
  askHuman: "ask a human",
60
78
  // An offer, not a demand: this row sits under every answer on 38 marketing sites, so the
61
79
  // wording has to be shruggable. "Was this helpful?" invites; "Please rate this answer"
@@ -109,6 +127,15 @@ var EN = {
109
127
  closeVideo: "Close video",
110
128
  enterFullScreen: "Full screen",
111
129
  exitFullScreen: "Exit full screen",
130
+ panelTitle: "AI assistant",
131
+ panelTitleProduct: "{product} assistant",
132
+ panelViews: "Assistant views",
133
+ tabChat: "Chat",
134
+ tabAvatar: "Avatar",
135
+ closePanel: "Close",
136
+ liveAvatar: "Live avatar",
137
+ avatarComingSoon: "Live avatar coming soon",
138
+ continueInChat: "Continue in Chat",
112
139
  videoUnavailable: "This video can't be played right now.",
113
140
  groundedIn: "What this answer is based on",
114
141
  sourceCountOne: "1 source",
@@ -121,6 +148,7 @@ var EN = {
121
148
  seoTitle: "Describe a problem, get an answer",
122
149
  seoDescription: "Describe the problem in your own words and get an answer drawn from our product documentation, with links to the exact pages it came from.",
123
150
  seoDescriptionProduct: "Describe the problem in your own words and get an answer drawn from {product}'s documentation \u2014 and every other product we build \u2014 with links to the exact pages it came from.",
151
+ seoDescriptionScoped: "Answers about {product}, drawn from {product}'s documentation, with links to the exact pages they came from.",
124
152
  capabilities: [
125
153
  "Grounded in our own docs",
126
154
  "Compare across the ecosystem",
@@ -130,13 +158,15 @@ var EN = {
130
158
  "Every course we run lives in a different spreadsheet.",
131
159
  "We only hear a machine is down after the line has stopped.",
132
160
  "Members quietly stop showing up and we never know why.",
133
- "Which of your products fits a problem like mine?"
161
+ PORTFOLIO_PROMPT.en
134
162
  ]
135
163
  };
136
164
  var ZH = {
137
165
  badge: "\u57FA\u4E8E\u6211\u4EEC\u6587\u6863\u7684 AI \u56DE\u7B54",
138
166
  welcomeTitle: "\u4F60\u60F3\u89E3\u51B3\u4EC0\u4E48\u95EE\u9898\uFF1F",
139
167
  welcomeBody: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u95EE\u9898\u3002\u4F60\u4E5F\u53EF\u4EE5\u8BE2\u95EE\u67D0\u4E00\u6B3E\u4EA7\u54C1\uFF0C\u6216\u6BD4\u8F83\u51E0\u6B3E\u4EA7\u54C1\u3002\u6240\u6709\u56DE\u7B54\u90FD\u76F4\u63A5\u6765\u81EA\u6211\u4EEC\u7684\u6587\u6863\u3002",
168
+ welcomeBodyProduct: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u95EE\u9898\uFF0C\u6216\u8005\u95EE\u95EE {product} \u662F\u505A\u4EC0\u4E48\u7684\u3002\u6240\u6709\u56DE\u7B54\u90FD\u76F4\u63A5\u6765\u81EA\u6211\u4EEC\u7684\u6587\u6863\u3002",
169
+ welcomeBodyScoped: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u95EE\u9898\u3002\u6240\u6709\u56DE\u7B54\u90FD\u76F4\u63A5\u6765\u81EA\u6211\u4EEC\u7684\u6587\u6863\u3002",
140
170
  tryAsking: "\u8BD5\u7740\u95EE",
141
171
  focusProduct: "\u805A\u7126\u67D0\u4E2A\u4EA7\u54C1",
142
172
  allProducts: "\u5168\u90E8\u4EA7\u54C1",
@@ -146,6 +176,7 @@ var ZH = {
146
176
  nextYouCouldAsk: "\u4F60\u8FD8\u53EF\u4EE5\u95EE",
147
177
  placeholder: "\u63CF\u8FF0\u4F60\u7684\u95EE\u9898\u2026",
148
178
  placeholderProduct: "\u63CF\u8FF0\u95EE\u9898\uFF0C\u6216\u8BE2\u95EE {product}\u2026",
179
+ placeholderScoped: "\u5C31 {product} \u63D0\u95EE\u2026",
149
180
  send: "\u53D1\u9001",
150
181
  stop: "\u505C\u6B62",
151
182
  newChat: "\u65B0\u5BF9\u8BDD",
@@ -167,6 +198,7 @@ var ZH = {
167
198
  attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
168
199
  noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
169
200
  answerDidNotArrive: "\u8FD9\u6761\u56DE\u7B54\u6CA1\u6709\u8FD4\u56DE\u3002\u8BF7\u518D\u95EE\u4E00\u6B21\u3002",
201
+ toolBudgetScoped: "\u8FD9\u4E2A\u95EE\u9898\u6D89\u53CA\u7684\u5185\u5BB9\u592A\u591A\uFF0C\u6211\u6CA1\u6CD5\u4E00\u6B21\u67E5\u5B8C\u3002\u8BD5\u7740\u53EA\u95EE\u5176\u4E2D\u7684\u4E00\u90E8\u5206\u3002",
170
202
  askHuman: "\u8054\u7CFB\u6211\u4EEC",
171
203
  feedbackPrompt: "\u8FD9\u4E2A\u56DE\u7B54\u6709\u5E2E\u52A9\u5417\uFF1F",
172
204
  feedbackHelpful: "\u6709\u5E2E\u52A9",
@@ -217,6 +249,15 @@ var ZH = {
217
249
  closeVideo: "\u5173\u95ED\u89C6\u9891",
218
250
  enterFullScreen: "\u5168\u5C4F",
219
251
  exitFullScreen: "\u9000\u51FA\u5168\u5C4F",
252
+ panelTitle: "AI \u52A9\u624B",
253
+ panelTitleProduct: "{product} \u52A9\u624B",
254
+ panelViews: "\u52A9\u624B\u89C6\u56FE",
255
+ tabChat: "\u804A\u5929",
256
+ tabAvatar: "\u865A\u62DF\u5F62\u8C61",
257
+ closePanel: "\u5173\u95ED",
258
+ liveAvatar: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61",
259
+ avatarComingSoon: "\u5B9E\u65F6\u865A\u62DF\u5F62\u8C61\u5373\u5C06\u63A8\u51FA",
260
+ continueInChat: "\u5728\u804A\u5929\u4E2D\u7EE7\u7EED",
220
261
  videoUnavailable: "\u6682\u65F6\u65E0\u6CD5\u64AD\u653E\u6B64\u89C6\u9891\u3002",
221
262
  groundedIn: "\u8FD9\u4E2A\u56DE\u7B54\u7684\u4F9D\u636E",
222
263
  sourceCountOne: "1 \u4E2A\u6765\u6E90",
@@ -229,18 +270,21 @@ var ZH = {
229
270
  seoTitle: "\u63CF\u8FF0\u95EE\u9898\uFF0C\u83B7\u5F97\u7B54\u6848",
230
271
  seoDescription: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u95EE\u9898\uFF0C\u5373\u53EF\u83B7\u5F97\u6765\u81EA\u6211\u4EEC\u4EA7\u54C1\u6587\u6863\u7684\u56DE\u7B54\uFF0C\u5E76\u9644\u4E0A\u7B54\u6848\u51FA\u5904\u7684\u9875\u9762\u94FE\u63A5\u3002",
231
272
  seoDescriptionProduct: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u95EE\u9898\uFF0C\u5373\u53EF\u83B7\u5F97\u6765\u81EA {product} \u53CA\u6211\u4EEC\u5176\u4ED6\u4EA7\u54C1\u6587\u6863\u7684\u56DE\u7B54\uFF0C\u5E76\u9644\u4E0A\u7B54\u6848\u51FA\u5904\u7684\u9875\u9762\u94FE\u63A5\u3002",
273
+ seoDescriptionScoped: "\u6709\u5173 {product} \u7684\u56DE\u7B54\uFF0C\u5747\u6765\u81EA {product} \u7684\u6587\u6863\uFF0C\u5E76\u9644\u4E0A\u7B54\u6848\u51FA\u5904\u7684\u9875\u9762\u94FE\u63A5\u3002",
232
274
  capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
233
275
  prompts: [
234
276
  "\u6BCF\u95E8\u8BFE\u7A0B\u90FD\u8BB0\u5728\u4E0D\u540C\u7684\u8868\u683C\u91CC\u3002",
235
277
  "\u673A\u5668\u505C\u4E86\uFF0C\u8981\u7B49\u6574\u6761\u7EBF\u505C\u4E0B\u6765\u624D\u77E5\u9053\u3002",
236
278
  "\u4F1A\u5458\u6162\u6162\u5C31\u4E0D\u6765\u4E86\uFF0C\u6211\u4EEC\u4E5F\u4E0D\u77E5\u9053\u4E3A\u4EC0\u4E48\u3002",
237
- "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u8FD9\u6837\u7684\u95EE\u9898\uFF1F"
279
+ PORTFOLIO_PROMPT.zh
238
280
  ]
239
281
  };
240
282
  var HI = {
241
283
  badge: "\u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 AI \u0909\u0924\u094D\u0924\u0930",
242
284
  welcomeTitle: "\u0906\u092A \u0915\u094C\u0928 \u0938\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0939\u0932 \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902?",
243
285
  welcomeBody: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902\u0964 \u0906\u092A \u0915\u093F\u0938\u0940 \u090F\u0915 \u0909\u0924\u094D\u092A\u093E\u0926 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092D\u0940 \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902 \u092F\u093E \u0915\u0941\u091B \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930 \u0938\u0915\u0924\u0947 \u0939\u0948\u0902\u0964 \u0939\u0930 \u0909\u0924\u094D\u0924\u0930 \u0938\u0940\u0927\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C \u0938\u0947 \u0906\u0924\u093E \u0939\u0948\u0964",
286
+ welcomeBodyProduct: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902, \u092F\u093E \u092A\u0942\u091B\u0947\u0902 \u0915\u093F {product} \u0915\u094D\u092F\u093E \u0915\u0930\u0924\u093E \u0939\u0948\u0964 \u0939\u0930 \u0909\u0924\u094D\u0924\u0930 \u0938\u0940\u0927\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C \u0938\u0947 \u0906\u0924\u093E \u0939\u0948\u0964",
287
+ welcomeBodyScoped: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902\u0964 \u0939\u0930 \u0909\u0924\u094D\u0924\u0930 \u0938\u0940\u0927\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C \u0938\u0947 \u0906\u0924\u093E \u0939\u0948\u0964",
244
288
  tryAsking: "\u092F\u0939 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902",
245
289
  focusProduct: "\u0915\u093F\u0938\u0940 \u0909\u0924\u094D\u092A\u093E\u0926 \u092A\u0930 \u0927\u094D\u092F\u093E\u0928 \u0926\u0947\u0902",
246
290
  allProducts: "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926",
@@ -250,6 +294,7 @@ var HI = {
250
294
  nextYouCouldAsk: "\u0906\u0917\u0947 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902",
251
295
  placeholder: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u092C\u0924\u093E\u090F\u0902\u2026",
252
296
  placeholderProduct: "\u0938\u092E\u0938\u094D\u092F\u093E \u092C\u0924\u093E\u090F\u0902, \u092F\u093E {product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
297
+ placeholderScoped: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
253
298
  send: "\u092D\u0947\u091C\u0947\u0902",
254
299
  stop: "\u0930\u094B\u0915\u0947\u0902",
255
300
  newChat: "\u0928\u0908 \u092C\u093E\u0924\u091A\u0940\u0924",
@@ -271,6 +316,7 @@ var HI = {
271
316
  attachmentTooMany: "\u0915\u0947\u0935\u0932 {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0940 \u091C\u093E \u0938\u0915\u0924\u0940 \u0939\u0948\u0902, \u0907\u0938\u0932\u093F\u090F {{name}} \u091B\u094B\u0921\u093C \u0926\u0940 \u0917\u0908\u0964",
272
317
  noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
273
318
  answerDidNotArrive: "\u0935\u0939 \u0909\u0924\u094D\u0924\u0930 \u0928\u0939\u0940\u0902 \u0906 \u0938\u0915\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u0926\u094B\u092C\u093E\u0930\u093E \u092A\u0942\u091B\u0947\u0902\u0964",
319
+ toolBudgetScoped: "\u0907\u0938 \u0938\u0935\u093E\u0932 \u092E\u0947\u0902 \u0907\u0924\u0928\u093E \u0915\u0941\u091B \u0939\u0948 \u0915\u093F \u090F\u0915 \u092C\u093E\u0930 \u092E\u0947\u0902 \u0938\u092C \u0928\u0939\u0940\u0902 \u0926\u0947\u0916\u093E \u091C\u093E \u0938\u0915\u0924\u093E\u0964 \u0907\u0938\u0915\u0947 \u0915\u093F\u0938\u0940 \u090F\u0915 \u0939\u093F\u0938\u094D\u0938\u0947 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902\u0964",
274
320
  askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
275
321
  feedbackPrompt: "\u0915\u094D\u092F\u093E \u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u092E\u0926\u0926\u0917\u093E\u0930 \u0925\u093E?",
276
322
  feedbackHelpful: "\u092E\u0926\u0926\u0917\u093E\u0930",
@@ -321,6 +367,15 @@ var HI = {
321
367
  closeVideo: "\u0935\u0940\u0921\u093F\u092F\u094B \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
322
368
  enterFullScreen: "\u092A\u0942\u0930\u094D\u0923 \u0938\u094D\u0915\u094D\u0930\u0940\u0928",
323
369
  exitFullScreen: "\u092A\u0942\u0930\u094D\u0923 \u0938\u094D\u0915\u094D\u0930\u0940\u0928 \u0938\u0947 \u092C\u093E\u0939\u0930 \u0928\u093F\u0915\u0932\u0947\u0902",
370
+ panelTitle: "AI \u0938\u0939\u093E\u092F\u0915",
371
+ panelTitleProduct: "{product} \u0938\u0939\u093E\u092F\u0915",
372
+ panelViews: "\u0938\u0939\u093E\u092F\u0915 \u0926\u0943\u0936\u094D\u092F",
373
+ tabChat: "\u091A\u0948\u091F",
374
+ tabAvatar: "\u0905\u0935\u0924\u093E\u0930",
375
+ closePanel: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
376
+ liveAvatar: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930",
377
+ avatarComingSoon: "\u0932\u093E\u0907\u0935 \u0905\u0935\u0924\u093E\u0930 \u091C\u0932\u094D\u0926 \u0906 \u0930\u0939\u093E \u0939\u0948",
378
+ continueInChat: "\u091A\u0948\u091F \u092E\u0947\u0902 \u091C\u093E\u0930\u0940 \u0930\u0916\u0947\u0902",
324
379
  videoUnavailable: "\u092F\u0939 \u0935\u0940\u0921\u093F\u092F\u094B \u0905\u092D\u0940 \u0928\u0939\u0940\u0902 \u091A\u0932 \u0938\u0915\u0924\u093E\u0964",
325
380
  groundedIn: "\u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948",
326
381
  sourceCountOne: "1 \u0938\u094D\u0930\u094B\u0924",
@@ -333,6 +388,7 @@ var HI = {
333
388
  seoTitle: "\u0938\u092E\u0938\u094D\u092F\u093E \u092C\u0924\u093E\u090F\u0902, \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902",
334
389
  seoDescription: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902 \u0914\u0930 \u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u0938\u0947 \u0932\u093F\u092F\u093E \u0917\u092F\u093E \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902, \u0938\u093E\u0925 \u092E\u0947\u0902 \u0909\u0928\u094D\u0939\u0940\u0902 \u092A\u0928\u094D\u0928\u094B\u0902 \u0915\u0947 \u0932\u093F\u0902\u0915 \u091C\u0939\u093E\u0901 \u0938\u0947 \u0935\u0939 \u0906\u092F\u093E \u0939\u0948\u0964",
335
390
  seoDescriptionProduct: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902 \u0914\u0930 {product} \u0924\u0925\u093E \u0939\u092E\u093E\u0930\u0947 \u092C\u093E\u0915\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u0938\u0947 \u0932\u093F\u092F\u093E \u0917\u092F\u093E \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902, \u0938\u093E\u0925 \u092E\u0947\u0902 \u0909\u0928\u094D\u0939\u0940\u0902 \u092A\u0928\u094D\u0928\u094B\u0902 \u0915\u0947 \u0932\u093F\u0902\u0915 \u091C\u0939\u093E\u0901 \u0938\u0947 \u0935\u0939 \u0906\u092F\u093E \u0939\u0948\u0964",
391
+ seoDescriptionScoped: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902, \u091C\u094B {product} \u0915\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u0938\u0947 \u0932\u093F\u090F \u0917\u090F \u0939\u0948\u0902, \u0938\u093E\u0925 \u092E\u0947\u0902 \u0909\u0928\u094D\u0939\u0940\u0902 \u092A\u0928\u094D\u0928\u094B\u0902 \u0915\u0947 \u0932\u093F\u0902\u0915 \u091C\u0939\u093E\u0901 \u0938\u0947 \u0935\u0947 \u0906\u090F \u0939\u0948\u0902\u0964",
336
392
  capabilities: [
337
393
  "\u0939\u092E\u093E\u0930\u0947 \u0905\u092A\u0928\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924",
338
394
  "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930\u0947\u0902",
@@ -342,13 +398,15 @@ var HI = {
342
398
  "\u0939\u0930 \u0915\u094B\u0930\u094D\u0938 \u0915\u093E \u0939\u093F\u0938\u093E\u092C \u0905\u0932\u0917 \u0936\u0940\u091F \u092E\u0947\u0902 \u0930\u0916\u093E \u091C\u093E\u0924\u093E \u0939\u0948\u0964",
343
399
  "\u092E\u0936\u0940\u0928 \u092C\u0902\u0926 \u0939\u094B\u0928\u0947 \u0915\u093E \u092A\u0924\u093E \u0924\u092D\u0940 \u091A\u0932\u0924\u093E \u0939\u0948 \u091C\u092C \u0932\u093E\u0907\u0928 \u0930\u0941\u0915 \u091C\u093E\u090F\u0964",
344
400
  "\u0938\u0926\u0938\u094D\u092F \u0927\u0940\u0930\u0947-\u0927\u0940\u0930\u0947 \u0906\u0928\u093E \u092C\u0902\u0926 \u0915\u0930 \u0926\u0947\u0924\u0947 \u0939\u0948\u0902, \u0935\u091C\u0939 \u092A\u0924\u093E \u0928\u0939\u0940\u0902 \u091A\u0932\u0924\u0940\u0964",
345
- "\u092E\u0947\u0930\u0940 \u091C\u0948\u0938\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?"
401
+ PORTFOLIO_PROMPT.hi
346
402
  ]
347
403
  };
348
404
  var ES = {
349
405
  badge: "Respuestas de IA basadas en nuestra documentaci\xF3n",
350
406
  welcomeTitle: "\xBFQu\xE9 problema quieres resolver?",
351
407
  welcomeBody: "Describe el problema con tus propias palabras. Tambi\xE9n puedes preguntar por un producto concreto o comparar varios. Cada respuesta procede directamente de nuestra documentaci\xF3n.",
408
+ welcomeBodyProduct: "Describe el problema con tus propias palabras o pregunta qu\xE9 hace {product}. Cada respuesta procede directamente de nuestra documentaci\xF3n.",
409
+ welcomeBodyScoped: "Describe el problema con tus propias palabras. Cada respuesta procede directamente de nuestra documentaci\xF3n.",
352
410
  tryAsking: "Prueba a preguntar",
353
411
  focusProduct: "Centrarse en un producto",
354
412
  allProducts: "Todos los productos",
@@ -358,6 +416,7 @@ var ES = {
358
416
  nextYouCouldAsk: "Tambi\xE9n puedes preguntar",
359
417
  placeholder: "Describe el problema\u2026",
360
418
  placeholderProduct: "Describe un problema o pregunta por {product}\u2026",
419
+ placeholderScoped: "Pregunta sobre {product}\u2026",
361
420
  send: "Enviar",
362
421
  stop: "Detener",
363
422
  newChat: "Nueva conversaci\xF3n",
@@ -379,6 +438,7 @@ var ES = {
379
438
  attachmentTooMany: "Solo se pueden adjuntar {{max}} archivos, as\xED que se omiti\xF3 {{name}}.",
380
439
  noAnswer: "No he encontrado esto en nuestra documentaci\xF3n, as\xED que la respuesta de abajo no se apoya en ninguna fuente. Prueba a reformularla, o",
381
440
  answerDidNotArrive: "Esa respuesta no lleg\xF3. Int\xE9ntalo de nuevo.",
441
+ toolBudgetScoped: "Esa pregunta abarca m\xE1s de lo que puedo revisar de una vez. Prueba a preguntar por una parte de ella.",
382
442
  askHuman: "habla con una persona",
383
443
  feedbackPrompt: "\xBFTe ha servido?",
384
444
  feedbackHelpful: "Me sirve",
@@ -429,6 +489,15 @@ var ES = {
429
489
  closeVideo: "Cerrar v\xEDdeo",
430
490
  enterFullScreen: "Pantalla completa",
431
491
  exitFullScreen: "Salir de pantalla completa",
492
+ panelTitle: "Asistente de IA",
493
+ panelTitleProduct: "Asistente de {product}",
494
+ panelViews: "Vistas del asistente",
495
+ tabChat: "Chat",
496
+ tabAvatar: "Avatar",
497
+ closePanel: "Cerrar",
498
+ liveAvatar: "Avatar en vivo",
499
+ avatarComingSoon: "Avatar en vivo: pr\xF3ximamente",
500
+ continueInChat: "Continuar en el chat",
432
501
  videoUnavailable: "Ahora mismo no se puede reproducir este v\xEDdeo.",
433
502
  groundedIn: "En qu\xE9 se basa esta respuesta",
434
503
  sourceCountOne: "1 fuente",
@@ -441,6 +510,7 @@ var ES = {
441
510
  seoTitle: "Describe un problema y obt\xE9n una respuesta",
442
511
  seoDescription: "Describe el problema con tus palabras y recibe una respuesta extra\xEDda de la documentaci\xF3n de nuestros productos, con enlaces a las p\xE1ginas exactas de las que procede.",
443
512
  seoDescriptionProduct: "Describe el problema con tus palabras y recibe una respuesta extra\xEDda de la documentaci\xF3n de {product} y del resto de nuestros productos, con enlaces a las p\xE1ginas exactas de las que procede.",
513
+ seoDescriptionScoped: "Respuestas sobre {product}, extra\xEDdas de la documentaci\xF3n de {product}, con enlaces a las p\xE1ginas exactas de las que proceden.",
444
514
  capabilities: [
445
515
  "Basado en nuestra documentaci\xF3n",
446
516
  "Compara todo el ecosistema",
@@ -450,13 +520,15 @@ var ES = {
450
520
  "Cada curso que damos est\xE1 en una hoja de c\xE1lculo distinta.",
451
521
  "Nos enteramos de que una m\xE1quina falla cuando para la l\xEDnea.",
452
522
  "Los socios dejan de venir poco a poco y nunca sabemos por qu\xE9.",
453
- "\xBFQu\xE9 producto encaja con un problema como el m\xEDo?"
523
+ PORTFOLIO_PROMPT.es
454
524
  ]
455
525
  };
456
526
  var AR = {
457
527
  badge: "\u0625\u062C\u0627\u0628\u0627\u062A \u0630\u0643\u0627\u0621 \u0627\u0635\u0637\u0646\u0627\u0639\u064A \u0645\u0628\u0646\u064A\u0629 \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
458
528
  welcomeTitle: "\u0645\u0627 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u062D\u0627\u0648\u0644 \u062D\u0644\u0647\u0627\u061F",
459
529
  welcomeBody: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0623\u0646\u062A. \u064A\u0645\u0643\u0646\u0643 \u0623\u064A\u0636\u064B\u0627 \u0627\u0644\u0633\u0624\u0627\u0644 \u0639\u0646 \u0645\u0646\u062A\u062C \u0628\u0639\u064A\u0646\u0647 \u0623\u0648 \u0627\u0644\u0645\u0642\u0627\u0631\u0646\u0629 \u0628\u064A\u0646 \u0639\u062F\u0629 \u0645\u0646\u062A\u062C\u0627\u062A. \u062A\u0623\u062A\u064A \u0643\u0644 \u0625\u062C\u0627\u0628\u0629 \u0645\u0628\u0627\u0634\u0631\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642\u0646\u0627.",
530
+ welcomeBodyProduct: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0623\u0646\u062A\u060C \u0623\u0648 \u0627\u0633\u0623\u0644 \u0639\u0645\u0651\u0627 \u064A\u0641\u0639\u0644\u0647 {product}. \u062A\u0623\u062A\u064A \u0643\u0644 \u0625\u062C\u0627\u0628\u0629 \u0645\u0628\u0627\u0634\u0631\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642\u0646\u0627.",
531
+ welcomeBodyScoped: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0623\u0646\u062A. \u062A\u0623\u062A\u064A \u0643\u0644 \u0625\u062C\u0627\u0628\u0629 \u0645\u0628\u0627\u0634\u0631\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642\u0646\u0627.",
460
532
  tryAsking: "\u062C\u0631\u0651\u0628 \u0623\u0646 \u062A\u0633\u0623\u0644",
461
533
  focusProduct: "\u0627\u0644\u062A\u0631\u0643\u064A\u0632 \u0639\u0644\u0649 \u0645\u0646\u062A\u062C",
462
534
  allProducts: "\u0643\u0644 \u0627\u0644\u0645\u0646\u062A\u062C\u0627\u062A",
@@ -466,6 +538,7 @@ var AR = {
466
538
  nextYouCouldAsk: "\u064A\u0645\u0643\u0646\u0643 \u0623\u0646 \u062A\u0633\u0623\u0644 \u0628\u0639\u062F \u0630\u0644\u0643",
467
539
  placeholder: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629\u2026",
468
540
  placeholderProduct: "\u0635\u0641 \u0645\u0634\u0643\u0644\u062A\u0643 \u0623\u0648 \u0627\u0633\u0623\u0644 \u0639\u0646 {product}\u2026",
541
+ placeholderScoped: "\u0627\u0633\u0623\u0644 \u0639\u0646 {product}\u2026",
469
542
  send: "\u0625\u0631\u0633\u0627\u0644",
470
543
  stop: "\u0625\u064A\u0642\u0627\u0641",
471
544
  newChat: "\u0645\u062D\u0627\u062F\u062B\u0629 \u062C\u062F\u064A\u062F\u0629",
@@ -487,6 +560,7 @@ var AR = {
487
560
  attachmentTooMany: "\u064A\u0645\u0643\u0646 \u0625\u0631\u0641\u0627\u0642 {{max}} \u0645\u0644\u0641\u0627\u062A \u0641\u0642\u0637\u060C \u0644\u0630\u0627 \u062A\u0645 \u062A\u062E\u0637\u064A {{name}}.",
488
561
  noAnswer: "\u0644\u0645 \u0623\u062C\u062F \u0647\u0630\u0627 \u0641\u064A \u0648\u062B\u0627\u0626\u0642\u0646\u0627\u060C \u0644\u0630\u0627 \u0641\u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0623\u062F\u0646\u0627\u0647 \u063A\u064A\u0631 \u0645\u0633\u062A\u0646\u062F\u0629 \u0625\u0644\u0649 \u0645\u0635\u062F\u0631. \u062D\u0627\u0648\u0644 \u0625\u0639\u0627\u062F\u0629 \u0627\u0644\u0635\u064A\u0627\u063A\u0629\u060C \u0623\u0648",
489
562
  answerDidNotArrive: "\u0644\u0645 \u062A\u0635\u0644 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
563
+ toolBudgetScoped: "\u0647\u0630\u0627 \u0627\u0644\u0633\u0624\u0627\u0644 \u064A\u0634\u0645\u0644 \u0623\u0643\u062B\u0631 \u0645\u0645\u0627 \u0623\u0633\u062A\u0637\u064A\u0639 \u0627\u0644\u0628\u062D\u062B \u0641\u064A\u0647 \u062F\u0641\u0639\u0629 \u0648\u0627\u062D\u062F\u0629. \u062C\u0631\u0651\u0628 \u0623\u0646 \u062A\u0633\u0623\u0644 \u0639\u0646 \u062C\u0632\u0621 \u0648\u0627\u062D\u062F \u0645\u0646\u0647.",
490
564
  askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
491
565
  feedbackPrompt: "\u0647\u0644 \u0643\u0627\u0646\u062A \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0645\u0641\u064A\u062F\u0629\u061F",
492
566
  feedbackHelpful: "\u0645\u0641\u064A\u062F\u0629",
@@ -537,6 +611,15 @@ var AR = {
537
611
  closeVideo: "\u0625\u063A\u0644\u0627\u0642 \u0627\u0644\u0641\u064A\u062F\u064A\u0648",
538
612
  enterFullScreen: "\u0645\u0644\u0621 \u0627\u0644\u0634\u0627\u0634\u0629",
539
613
  exitFullScreen: "\u0627\u0644\u062E\u0631\u0648\u062C \u0645\u0646 \u0645\u0644\u0621 \u0627\u0644\u0634\u0627\u0634\u0629",
614
+ panelTitle: "\u0645\u0633\u0627\u0639\u062F \u0627\u0644\u0630\u0643\u0627\u0621 \u0627\u0644\u0627\u0635\u0637\u0646\u0627\u0639\u064A",
615
+ panelTitleProduct: "\u0645\u0633\u0627\u0639\u062F {product}",
616
+ panelViews: "\u0637\u0631\u0642 \u0639\u0631\u0636 \u0627\u0644\u0645\u0633\u0627\u0639\u062F",
617
+ tabChat: "\u062F\u0631\u062F\u0634\u0629",
618
+ tabAvatar: "\u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631",
619
+ closePanel: "\u0625\u063A\u0644\u0627\u0642",
620
+ liveAvatar: "\u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631",
621
+ avatarComingSoon: "\u0627\u0644\u0623\u0641\u0627\u062A\u0627\u0631 \u0627\u0644\u0645\u0628\u0627\u0634\u0631 \u0642\u0631\u064A\u0628\u064B\u0627",
622
+ continueInChat: "\u0627\u0644\u0645\u062A\u0627\u0628\u0639\u0629 \u0641\u064A \u0627\u0644\u062F\u0631\u062F\u0634\u0629",
540
623
  videoUnavailable: "\u062A\u0639\u0630\u0651\u0631 \u062A\u0634\u063A\u064A\u0644 \u0647\u0630\u0627 \u0627\u0644\u0641\u064A\u062F\u064A\u0648 \u0627\u0644\u0622\u0646.",
541
624
  groundedIn: "\u0639\u0644\u0649 \u0645\u0627\u0630\u0627 \u062A\u0633\u062A\u0646\u062F \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
542
625
  sourceCountOne: "\u0645\u0635\u062F\u0631 \u0648\u0627\u062D\u062F",
@@ -549,6 +632,7 @@ var AR = {
549
632
  seoTitle: "\u0635\u0641 \u0645\u0634\u0643\u0644\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629",
550
633
  seoDescription: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629 \u0645\u0633\u062A\u0645\u062F\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627\u060C \u0645\u0639 \u0631\u0648\u0627\u0628\u0637 \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062C\u0627\u0621\u062A \u0645\u0646\u0647\u0627.",
551
634
  seoDescriptionProduct: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629 \u0645\u0633\u062A\u0645\u062F\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642 {product} \u0648\u0628\u0642\u064A\u0629 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627\u060C \u0645\u0639 \u0631\u0648\u0627\u0628\u0637 \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062C\u0627\u0621\u062A \u0645\u0646\u0647\u0627.",
635
+ seoDescriptionScoped: "\u0625\u062C\u0627\u0628\u0627\u062A \u0639\u0646 {product} \u0645\u0633\u062A\u0645\u062F\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642 {product}\u060C \u0645\u0639 \u0631\u0648\u0627\u0628\u0637 \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062C\u0627\u0621\u062A \u0645\u0646\u0647\u0627.",
552
636
  capabilities: [
553
637
  "\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
554
638
  "\u0642\u0627\u0631\u0646 \u0639\u0628\u0631 \u0627\u0644\u0645\u0646\u0638\u0648\u0645\u0629",
@@ -558,13 +642,15 @@ var AR = {
558
642
  "\u0643\u0644 \u062F\u0648\u0631\u0629 \u062A\u062F\u0631\u064A\u0628\u064A\u0629 \u0644\u062F\u064A\u0646\u0627 \u0641\u064A \u062C\u062F\u0648\u0644 \u0628\u064A\u0627\u0646\u0627\u062A \u0645\u062E\u062A\u0644\u0641.",
559
643
  "\u0644\u0627 \u0646\u0639\u0644\u0645 \u0628\u062A\u0639\u0637\u0644 \u0627\u0644\u0645\u0627\u0643\u064A\u0646\u0629 \u0625\u0644\u0627 \u0628\u0639\u062F \u062A\u0648\u0642\u0641 \u062E\u0637 \u0627\u0644\u0625\u0646\u062A\u0627\u062C.",
560
644
  "\u0623\u0639\u0636\u0627\u0624\u0646\u0627 \u064A\u062A\u0648\u0642\u0641\u0648\u0646 \u0639\u0646 \u0627\u0644\u062D\u0636\u0648\u0631 \u062A\u062F\u0631\u064A\u062C\u064A\u064B\u0627 \u062F\u0648\u0646 \u0623\u0646 \u0646\u0639\u0631\u0641 \u0627\u0644\u0633\u0628\u0628.",
561
- "\u0623\u064A \u0645\u0646\u062A\u062C \u064A\u0646\u0627\u0633\u0628 \u0645\u0634\u0643\u0644\u0629 \u0645\u062B\u0644 \u0645\u0634\u0643\u0644\u062A\u064A\u061F"
645
+ PORTFOLIO_PROMPT.ar
562
646
  ]
563
647
  };
564
648
  var TA = {
565
649
  badge: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BC8 \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F AI \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BCD",
566
650
  welcomeTitle: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA8\u0BCD\u0BA4\u0B9A\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8\u0BA4\u0BCD \u0BA4\u0BC0\u0BB0\u0BCD\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0BAF\u0BB2\u0BCD\u0B95\u0BBF\u0BB1\u0BC0\u0BB0\u0BCD\u0B95\u0BB3\u0BCD?",
567
651
  welcomeBody: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD. \u0B92\u0BB0\u0BC1 \u0B95\u0BC1\u0BB1\u0BBF\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BCD\u0B9F \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0BAF\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD, \u0B9A\u0BBF\u0BB2\u0BB5\u0BB1\u0BCD\u0BB1\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BB5\u0BC1\u0BAE\u0BCD \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BB2\u0BBE\u0BAE\u0BCD. \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BB2\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC7\u0BB0\u0B9F\u0BBF\u0BAF\u0BBE\u0B95 \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
652
+ welcomeBodyProduct: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1 {product} \u0B8E\u0BA9\u0BCD\u0BA9 \u0B9A\u0BC6\u0BAF\u0BCD\u0B95\u0BBF\u0BB1\u0BA4\u0BC1 \u0B8E\u0BA9\u0BCD\u0BB1\u0BC1 \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD. \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BB2\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC7\u0BB0\u0B9F\u0BBF\u0BAF\u0BBE\u0B95 \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
653
+ welcomeBodyScoped: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD. \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BB2\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC7\u0BB0\u0B9F\u0BBF\u0BAF\u0BBE\u0B95 \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
568
654
  tryAsking: "\u0B87\u0BA4\u0BC8\u0B95\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
569
655
  focusProduct: "\u0B92\u0BB0\u0BC1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BBF\u0BB2\u0BCD \u0B95\u0BB5\u0BA9\u0BAE\u0BCD",
570
656
  allProducts: "\u0B85\u0BA9\u0BC8\u0BA4\u0BCD\u0BA4\u0BC1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD",
@@ -574,6 +660,7 @@ var TA = {
574
660
  nextYouCouldAsk: "\u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1 \u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B95\u0BB2\u0BBE\u0BAE\u0BCD",
575
661
  placeholder: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
576
662
  placeholderProduct: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1 {product} \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
663
+ placeholderScoped: "{product} \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD\u2026",
577
664
  send: "\u0B85\u0BA9\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1",
578
665
  stop: "\u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
579
666
  newChat: "\u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0B89\u0BB0\u0BC8\u0BAF\u0BBE\u0B9F\u0BB2\u0BCD",
@@ -595,6 +682,7 @@ var TA = {
595
682
  attachmentTooMany: "{{max}} \u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BC1\u0BAE\u0BCD, \u0B8E\u0BA9\u0BB5\u0BC7 {{name}} \u0BA4\u0BB5\u0BBF\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
596
683
  noAnswer: "\u0B87\u0BA4\u0BC1 \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B95\u0BC0\u0BB4\u0BC7 \u0B89\u0BB3\u0BCD\u0BB3 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8. \u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0B95\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1",
597
684
  answerDidNotArrive: "\u0B85\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BB5\u0BB0\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
685
+ toolBudgetScoped: "\u0B87\u0BA8\u0BCD\u0BA4\u0B95\u0BCD \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BBF\u0BB2\u0BCD \u0B92\u0BB0\u0BC7 \u0BAE\u0BC1\u0BB1\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B8E\u0BA9\u0BCD\u0BA9\u0BBE\u0BB2\u0BCD \u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BA4\u0BC8 \u0BB5\u0BBF\u0B9F \u0B85\u0BA4\u0BBF\u0B95\u0BAE\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1. \u0B85\u0BA4\u0BA9\u0BCD \u0B92\u0BB0\u0BC1 \u0BAA\u0B95\u0BC1\u0BA4\u0BBF\u0BAF\u0BC8\u0BAA\u0BCD \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0B95\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
598
686
  askHuman: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BCD\u0BAA\u0BC1 \u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
599
687
  feedbackPrompt: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BAF\u0BA9\u0BC1\u0BB3\u0BCD\u0BB3\u0BA4\u0BBE\u0B95 \u0B87\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BA4\u0BBE?",
600
688
  feedbackHelpful: "\u0BAA\u0BAF\u0BA9\u0BC1\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1",
@@ -645,6 +733,15 @@ var TA = {
645
733
  closeVideo: "\u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB\u0BB5\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1",
646
734
  enterFullScreen: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC8",
647
735
  exitFullScreen: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BA4\u0BCD \u0BA4\u0BBF\u0BB0\u0BC8\u0BAF\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BB5\u0BC6\u0BB3\u0BBF\u0BAF\u0BC7\u0BB1\u0BC1",
736
+ panelTitle: "AI \u0B89\u0BA4\u0BB5\u0BBF\u0BAF\u0BBE\u0BB3\u0BB0\u0BCD",
737
+ panelTitleProduct: "{product} \u0B89\u0BA4\u0BB5\u0BBF\u0BAF\u0BBE\u0BB3\u0BB0\u0BCD",
738
+ panelViews: "\u0B89\u0BA4\u0BB5\u0BBF\u0BAF\u0BBE\u0BB3\u0BB0\u0BCD \u0B95\u0BBE\u0B9F\u0BCD\u0B9A\u0BBF\u0B95\u0BB3\u0BCD",
739
+ tabChat: "\u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8",
740
+ tabAvatar: "\u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD",
741
+ closePanel: "\u0BAE\u0BC2\u0B9F\u0BC1",
742
+ liveAvatar: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD",
743
+ avatarComingSoon: "\u0BA8\u0BC7\u0BB0\u0BB2\u0BC8 \u0B85\u0BB5\u0BA4\u0BBE\u0BB0\u0BCD \u0BB5\u0BBF\u0BB0\u0BC8\u0BB5\u0BBF\u0BB2\u0BCD",
744
+ continueInChat: "\u0B85\u0BB0\u0B9F\u0BCD\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BB5\u0BC1\u0BAE\u0BCD",
648
745
  videoUnavailable: "\u0B87\u0BA8\u0BCD\u0BA4 \u0BB5\u0BC0\u0B9F\u0BBF\u0BAF\u0BCB\u0BB5\u0BC8 \u0B87\u0BAA\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1 \u0B87\u0BAF\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
649
746
  groundedIn: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B8E\u0BA4\u0BC8 \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBE\u0B95\u0B95\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BA4\u0BC1",
650
747
  sourceCountOne: "1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD",
@@ -657,6 +754,7 @@ var TA = {
657
754
  seoTitle: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BC6\u0BB1\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
658
755
  seoDescription: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD; \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD, \u0B85\u0BA4\u0BC1 \u0BB5\u0BA8\u0BCD\u0BA4 \u0BAA\u0B95\u0BCD\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC1\u0B9F\u0BA9\u0BCD.",
659
756
  seoDescriptionProduct: "{product} \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BAA\u0BBF\u0BB1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BC6\u0BB1, \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u2014 \u0B85\u0BA4\u0BC1 \u0BB5\u0BA8\u0BCD\u0BA4 \u0BAA\u0B95\u0BCD\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC1\u0B9F\u0BA9\u0BCD.",
757
+ seoDescriptionScoped: "{product} \u0BAA\u0BB1\u0BCD\u0BB1\u0BBF\u0BAF \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD\u0B95\u0BB3\u0BCD, {product} \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1, \u0B85\u0BB5\u0BC8 \u0BB5\u0BA8\u0BCD\u0BA4 \u0BAA\u0B95\u0BCD\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC1\u0B9F\u0BA9\u0BCD.",
660
758
  capabilities: [
661
759
  "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD",
662
760
  "\u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
@@ -666,7 +764,7 @@ var TA = {
666
764
  "\u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BB0\u0BC1 \u0BAA\u0BAF\u0BBF\u0BB1\u0BCD\u0B9A\u0BBF \u0BB5\u0B95\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1\u0BAE\u0BCD \u0BB5\u0BC6\u0BB5\u0BCD\u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0BBF\u0BB0\u0BBF\u0BA4\u0BBE\u0BB3\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1.",
667
765
  "\u0B87\u0BAF\u0BA8\u0BCD\u0BA4\u0BBF\u0BB0\u0BAE\u0BCD \u0BA8\u0BBF\u0BA9\u0BCD\u0BB1\u0BA4\u0BC1 \u0BB2\u0BC8\u0BA9\u0BCD \u0BA8\u0BBF\u0BB1\u0BCD\u0B95\u0BC1\u0BAE\u0BCD\u0BAA\u0BCB\u0BA4\u0BC1\u0BA4\u0BBE\u0BA9\u0BCD \u0BA4\u0BC6\u0BB0\u0BBF\u0BAF \u0BB5\u0BB0\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
668
766
  "\u0B89\u0BB1\u0BC1\u0BAA\u0BCD\u0BAA\u0BBF\u0BA9\u0BB0\u0BCD\u0B95\u0BB3\u0BCD \u0BAE\u0BC6\u0BB2\u0BCD\u0BB2 \u0BB5\u0BB0\u0BC1\u0BB5\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BBF\u0BB1\u0BBE\u0BB0\u0BCD\u0B95\u0BB3\u0BCD, \u0B95\u0BBE\u0BB0\u0BA3\u0BAE\u0BCD \u0BA4\u0BC6\u0BB0\u0BBF\u0BAF\u0BBE\u0BA4\u0BC1.",
669
- "\u0B8E\u0BA9\u0BCD \u0BAA\u0BBF\u0BB0\u0B9A\u0BCD\u0B9A\u0BBF\u0BA9\u0BC8\u0B95\u0BCD\u0B95\u0BC1 \u0B8E\u0BA8\u0BCD\u0BA4\u0BA4\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD?"
767
+ PORTFOLIO_PROMPT.ta
670
768
  ]
671
769
  };
672
770
  var STRINGS = {
@@ -1661,6 +1759,230 @@ function ExploreAnswerBody({
1661
1759
  return /* @__PURE__ */ jsx("div", { className: cn("boff-prose boff-explore-body min-w-0", className), children: /* @__PURE__ */ jsx(AnswerScopeContext.Provider, { value: scope, children: /* @__PURE__ */ jsx(Markdown, { components: overrides, rehypePlugins, children }) }) });
1662
1760
  }
1663
1761
 
1762
+ // src/client/security.ts
1763
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
1764
+ var RESERVED_HEADERS = /* @__PURE__ */ new Set([
1765
+ "authorization",
1766
+ "cookie",
1767
+ "x-actor-id",
1768
+ "x-actor-type",
1769
+ "x-consent-granted-by",
1770
+ "x-consent-scope",
1771
+ "x-consent-granted-at",
1772
+ "x-consent-expires-at"
1773
+ ]);
1774
+ function validateGatewayUrl(value) {
1775
+ let url;
1776
+ try {
1777
+ url = new URL(value);
1778
+ } catch {
1779
+ throw new Error("Gateway URL must be a valid absolute URL");
1780
+ }
1781
+ if (url.protocol === "https:") {
1782
+ return url.toString();
1783
+ }
1784
+ if (url.protocol === "http:" && LOOPBACK_HOSTS.has(url.hostname.toLowerCase())) {
1785
+ return url.toString();
1786
+ }
1787
+ throw new Error("Gateway URL must use HTTPS unless it targets localhost");
1788
+ }
1789
+ function sanitizeHeaders(headers) {
1790
+ if (!headers) return void 0;
1791
+ return Object.fromEntries(
1792
+ Object.entries(headers).filter(
1793
+ ([key]) => !RESERVED_HEADERS.has(key.toLowerCase())
1794
+ )
1795
+ );
1796
+ }
1797
+ var CF_ACCESS_GATED_HOSTS = /* @__PURE__ */ new Set([
1798
+ "alphagraphql.burdenoff.com",
1799
+ "alphagraphqlworkspaces.burdenoff.com"
1800
+ ]);
1801
+ function cfAccessHeaders(gatewayUrl, cfAccess) {
1802
+ const clientId = cfAccess?.clientId?.trim();
1803
+ const clientSecret = cfAccess?.clientSecret?.trim();
1804
+ if (!clientId || !clientSecret) return {};
1805
+ let host;
1806
+ try {
1807
+ host = new URL(gatewayUrl).hostname.toLowerCase();
1808
+ } catch {
1809
+ return {};
1810
+ }
1811
+ if (!CF_ACCESS_GATED_HOSTS.has(host)) return {};
1812
+ return {
1813
+ "CF-Access-Client-Id": clientId,
1814
+ "CF-Access-Client-Secret": clientSecret
1815
+ };
1816
+ }
1817
+
1818
+ // src/client/graphql-client.ts
1819
+ var _WebSDKClient = class _WebSDKClient {
1820
+ constructor(config) {
1821
+ __publicField(this, "config");
1822
+ __publicField(this, "queryCache", /* @__PURE__ */ new Map());
1823
+ __publicField(this, "inflight", /* @__PURE__ */ new Map());
1824
+ this.config = {
1825
+ ...config,
1826
+ gatewayUrl: validateGatewayUrl(config.gatewayUrl),
1827
+ headers: sanitizeHeaders(config.headers)
1828
+ };
1829
+ }
1830
+ getConfig() {
1831
+ return this.config;
1832
+ }
1833
+ /**
1834
+ * Execute a GraphQL query (with deduplication and caching).
1835
+ *
1836
+ * Pass `{ cache: false }` to bypass the cache entirely — required for poll
1837
+ * loops, where every tick must reach the network.
1838
+ */
1839
+ async query(query, variables, options) {
1840
+ if (options?.cache === false) {
1841
+ return this.request(query, variables, true, options.timeoutMs);
1842
+ }
1843
+ const cacheKey = JSON.stringify({ query, variables });
1844
+ const cached = this.queryCache.get(cacheKey);
1845
+ if (cached) {
1846
+ if (Date.now() - cached.ts < _WebSDKClient.CACHE_TTL) {
1847
+ return cached.data;
1848
+ }
1849
+ this.queryCache.delete(cacheKey);
1850
+ }
1851
+ const existing = this.inflight.get(cacheKey);
1852
+ if (existing) {
1853
+ return existing;
1854
+ }
1855
+ const promise = this.request(query, variables, true, options?.timeoutMs).then((result) => {
1856
+ if (result.data && !result.errors?.length) {
1857
+ if (this.queryCache.size >= _WebSDKClient.MAX_CACHE_ENTRIES) {
1858
+ const oldestEntry = this.queryCache.keys().next().value;
1859
+ if (oldestEntry) {
1860
+ this.queryCache.delete(oldestEntry);
1861
+ }
1862
+ }
1863
+ this.queryCache.set(cacheKey, { data: result, ts: Date.now() });
1864
+ }
1865
+ return result;
1866
+ }).finally(() => {
1867
+ this.inflight.delete(cacheKey);
1868
+ });
1869
+ this.inflight.set(cacheKey, promise);
1870
+ return promise;
1871
+ }
1872
+ /**
1873
+ * Execute a GraphQL mutation
1874
+ */
1875
+ async mutate(mutation, variables, options) {
1876
+ return this.request(mutation, variables, false, options?.timeoutMs);
1877
+ }
1878
+ /** HTTP statuses worth another attempt — transient server/edge conditions. */
1879
+ static isRetriableStatus(status) {
1880
+ return status === 429 || status === 408 || status >= 500 && status < 600;
1881
+ }
1882
+ static sleep(ms) {
1883
+ return new Promise((resolve) => setTimeout(resolve, ms));
1884
+ }
1885
+ /**
1886
+ * Perform the HTTP call with a hard timeout. Every outcome resolves to a
1887
+ * GraphQLResponse — callers never hang, so a UI's `loading` state always
1888
+ * settles into data or a renderable error.
1889
+ */
1890
+ async attempt(query, variables, timeoutMs) {
1891
+ const controller = new AbortController();
1892
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
1893
+ try {
1894
+ const response = await fetch(this.config.gatewayUrl, {
1895
+ method: "POST",
1896
+ headers: {
1897
+ "Content-Type": "application/json",
1898
+ "x-product-id": this.config.productId,
1899
+ ...this.config.headers,
1900
+ ...cfAccessHeaders(this.config.gatewayUrl, this.config.cfAccess)
1901
+ },
1902
+ body: JSON.stringify({ query, variables }),
1903
+ signal: controller.signal
1904
+ });
1905
+ if (!response.ok) {
1906
+ console.error(
1907
+ "[WebSDK] GraphQL request failed",
1908
+ response.status,
1909
+ response.statusText
1910
+ );
1911
+ return {
1912
+ res: {
1913
+ errors: [
1914
+ {
1915
+ message: `HTTP ${response.status}: ${response.statusText}`,
1916
+ extensions: { code: `HTTP_${response.status}` }
1917
+ }
1918
+ ]
1919
+ },
1920
+ retriable: _WebSDKClient.isRetriableStatus(response.status)
1921
+ };
1922
+ }
1923
+ return {
1924
+ res: await response.json(),
1925
+ retriable: false
1926
+ };
1927
+ } catch (error) {
1928
+ const aborted = error instanceof Error && (error.name === "AbortError" || controller.signal.aborted);
1929
+ const message = aborted ? `Request timed out after ${timeoutMs}ms` : error instanceof Error ? error.message : "Network error";
1930
+ console.error("[WebSDK] Network error", message);
1931
+ return {
1932
+ res: {
1933
+ errors: [
1934
+ {
1935
+ message,
1936
+ extensions: { code: aborted ? "TIMEOUT" : "NETWORK_ERROR" }
1937
+ }
1938
+ ]
1939
+ },
1940
+ // Transport-level failures are worth one more try; a genuine outage
1941
+ // just fails twice quickly and still renders an error state.
1942
+ retriable: true
1943
+ };
1944
+ } finally {
1945
+ clearTimeout(timer);
1946
+ }
1947
+ }
1948
+ async request(query, variables, retry = true, timeoutOverrideMs) {
1949
+ const timeoutMs = timeoutOverrideMs ?? this.config.timeoutMs ?? _WebSDKClient.DEFAULT_TIMEOUT_MS;
1950
+ const maxRetries = retry ? this.config.maxRetries ?? _WebSDKClient.DEFAULT_MAX_RETRIES : 0;
1951
+ let last;
1952
+ for (let i = 0; i <= maxRetries; i++) {
1953
+ const { res, retriable } = await this.attempt(
1954
+ query,
1955
+ variables,
1956
+ timeoutMs
1957
+ );
1958
+ if (!retriable || i === maxRetries) return res;
1959
+ last = res;
1960
+ await _WebSDKClient.sleep(
1961
+ _WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200
1962
+ );
1963
+ }
1964
+ return last;
1965
+ }
1966
+ };
1967
+ __publicField(_WebSDKClient, "CACHE_TTL", 5 * 60 * 1e3);
1968
+ // 5 minutes
1969
+ __publicField(_WebSDKClient, "MAX_CACHE_ENTRIES", 100);
1970
+ __publicField(_WebSDKClient, "DEFAULT_TIMEOUT_MS", 12e3);
1971
+ __publicField(_WebSDKClient, "DEFAULT_MAX_RETRIES", 1);
1972
+ __publicField(_WebSDKClient, "RETRY_BASE_DELAY_MS", 400);
1973
+ var WebSDKContext = createContext(null);
1974
+ function useWebSDK() {
1975
+ const client = useContext(WebSDKContext);
1976
+ if (!client) {
1977
+ throw new Error("useWebSDK must be used within a WebSDKProvider");
1978
+ }
1979
+ return client;
1980
+ }
1981
+ function useWebSDKConfig() {
1982
+ const client = useWebSDK();
1983
+ return client.getConfig();
1984
+ }
1985
+
1664
1986
  // src/components/explore-types.ts
1665
1987
  var EXPLORE_FEEDBACK_REASONS = [
1666
1988
  "INACCURATE",
@@ -1870,420 +2192,20 @@ var EXPLORE_SHARED_CONVERSATION_QUERY = (
1870
2192
  }
1871
2193
  `
1872
2194
  );
1873
- var PROSE_CSS = `
1874
- .boff-prose {
1875
- max-width: none;
1876
- }
1877
2195
 
1878
- .boff-prose h1 {
1879
- font-size: 2.25rem;
1880
- font-weight: 800;
1881
- line-height: 1.2;
1882
- margin-top: 0;
1883
- margin-bottom: 1rem;
1884
- color: hsl(var(--foreground));
1885
- }
1886
-
1887
- .boff-prose h2 {
1888
- font-size: 1.75rem;
1889
- font-weight: 700;
1890
- line-height: 1.3;
1891
- margin-top: 2rem;
1892
- margin-bottom: 1rem;
1893
- color: hsl(var(--foreground));
1894
- }
1895
-
1896
- .boff-prose h3 {
1897
- font-size: 1.5rem;
1898
- font-weight: 600;
1899
- line-height: 1.4;
1900
- margin-top: 1.5rem;
1901
- margin-bottom: 0.75rem;
1902
- color: hsl(var(--foreground));
1903
- }
1904
-
1905
- .boff-prose h4 {
1906
- font-size: 1.25rem;
1907
- font-weight: 600;
1908
- line-height: 1.5;
1909
- margin-top: 1.25rem;
1910
- margin-bottom: 0.5rem;
1911
- color: hsl(var(--foreground));
1912
- }
1913
-
1914
- .boff-prose p {
1915
- margin-bottom: 1rem;
1916
- line-height: 1.75;
1917
- color: hsl(var(--foreground));
1918
- }
1919
-
1920
- .boff-prose ul,
1921
- .boff-prose ol {
1922
- margin-bottom: 1rem;
1923
- padding-left: 1.5rem;
1924
- }
1925
-
1926
- .boff-prose ul {
1927
- list-style-type: disc;
1928
- }
1929
-
1930
- .boff-prose ol {
1931
- list-style-type: decimal;
1932
- }
1933
-
1934
- .boff-prose li {
1935
- margin-bottom: 0.25rem;
1936
- line-height: 1.75;
1937
- color: hsl(var(--foreground));
1938
- }
1939
-
1940
- .boff-prose li > ul,
1941
- .boff-prose li > ol {
1942
- margin-top: 0.25rem;
1943
- margin-bottom: 0.25rem;
1944
- }
1945
-
1946
- .boff-prose a {
1947
- color: hsl(var(--primary));
1948
- text-decoration: underline;
1949
- text-underline-offset: 2px;
1950
- }
1951
-
1952
- .boff-prose a:hover {
1953
- opacity: 0.8;
1954
- }
1955
-
1956
- .boff-prose hr {
1957
- border: none;
1958
- height: 1px;
1959
- background-color: hsl(var(--border));
1960
- margin: 2rem 0;
1961
- }
1962
-
1963
- .boff-prose blockquote {
1964
- border-left: 4px solid hsl(var(--border));
1965
- padding-left: 1rem;
1966
- margin: 1.5rem 0;
1967
- font-style: italic;
1968
- color: hsl(var(--muted-foreground));
1969
- }
1970
-
1971
- .boff-prose strong {
1972
- font-weight: 700;
1973
- color: hsl(var(--foreground));
1974
- }
1975
-
1976
- .boff-prose code {
1977
- background-color: hsl(var(--muted));
1978
- padding: 0.125rem 0.25rem;
1979
- border-radius: 0.25rem;
1980
- font-size: 0.875em;
1981
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
1982
- }
1983
-
1984
- .boff-prose pre {
1985
- background-color: hsl(var(--muted));
1986
- padding: 1rem;
1987
- border-radius: 0.5rem;
1988
- overflow-x: auto;
1989
- margin-bottom: 1rem;
1990
- }
1991
-
1992
- .boff-prose pre code {
1993
- background-color: transparent;
1994
- padding: 0;
1995
- }
1996
-
1997
- .boff-prose img {
1998
- max-width: 100%;
1999
- height: auto;
2000
- }
2001
-
2002
- .boff-prose table {
2003
- width: 100%;
2004
- border-collapse: collapse;
2005
- margin-bottom: 1rem;
2006
- }
2007
-
2008
- .boff-prose th,
2009
- .boff-prose td {
2010
- border: 1px solid hsl(var(--border));
2011
- padding: 0.5rem;
2012
- text-align: left;
2013
- }
2014
-
2015
- .boff-prose th {
2016
- font-weight: 600;
2017
- background-color: hsl(var(--muted));
2018
- }
2019
-
2020
- /* Smaller variant used inside cards and compact panels */
2021
- .boff-prose-sm {
2022
- font-size: 0.875rem;
2023
- }
2024
-
2025
- .boff-prose-sm h1 {
2026
- font-size: 1.75rem;
2027
- }
2028
-
2029
- .boff-prose-sm h2 {
2030
- font-size: 1.5rem;
2031
- }
2032
-
2033
- .boff-prose-sm h3 {
2034
- font-size: 1.25rem;
2035
- }
2036
-
2037
- .boff-prose-sm h4 {
2038
- font-size: 1.125rem;
2039
- }
2040
-
2041
- .boff-prose-sm p,
2042
- .boff-prose-sm li {
2043
- line-height: 1.625;
2044
- }
2045
- `;
2046
- function ProseStyles() {
2047
- return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: PROSE_CSS } });
2048
- }
2049
-
2050
- // src/client/security.ts
2051
- var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
2052
- var RESERVED_HEADERS = /* @__PURE__ */ new Set([
2053
- "authorization",
2054
- "cookie",
2055
- "x-actor-id",
2056
- "x-actor-type",
2057
- "x-consent-granted-by",
2058
- "x-consent-scope",
2059
- "x-consent-granted-at",
2060
- "x-consent-expires-at"
2061
- ]);
2062
- function validateGatewayUrl(value) {
2063
- let url;
2064
- try {
2065
- url = new URL(value);
2066
- } catch {
2067
- throw new Error("Gateway URL must be a valid absolute URL");
2068
- }
2069
- if (url.protocol === "https:") {
2070
- return url.toString();
2071
- }
2072
- if (url.protocol === "http:" && LOOPBACK_HOSTS.has(url.hostname.toLowerCase())) {
2073
- return url.toString();
2074
- }
2075
- throw new Error("Gateway URL must use HTTPS unless it targets localhost");
2076
- }
2077
- function sanitizeHeaders(headers) {
2078
- if (!headers) return void 0;
2079
- return Object.fromEntries(
2080
- Object.entries(headers).filter(
2081
- ([key]) => !RESERVED_HEADERS.has(key.toLowerCase())
2082
- )
2083
- );
2084
- }
2085
- var CF_ACCESS_GATED_HOSTS = /* @__PURE__ */ new Set([
2086
- "alphagraphql.burdenoff.com",
2087
- "alphagraphqlworkspaces.burdenoff.com"
2088
- ]);
2089
- function cfAccessHeaders(gatewayUrl, cfAccess) {
2090
- const clientId = cfAccess?.clientId?.trim();
2091
- const clientSecret = cfAccess?.clientSecret?.trim();
2092
- if (!clientId || !clientSecret) return {};
2093
- let host;
2094
- try {
2095
- host = new URL(gatewayUrl).hostname.toLowerCase();
2096
- } catch {
2097
- return {};
2098
- }
2099
- if (!CF_ACCESS_GATED_HOSTS.has(host)) return {};
2100
- return {
2101
- "CF-Access-Client-Id": clientId,
2102
- "CF-Access-Client-Secret": clientSecret
2103
- };
2104
- }
2105
-
2106
- // src/client/graphql-client.ts
2107
- var _WebSDKClient = class _WebSDKClient {
2108
- constructor(config) {
2109
- __publicField(this, "config");
2110
- __publicField(this, "queryCache", /* @__PURE__ */ new Map());
2111
- __publicField(this, "inflight", /* @__PURE__ */ new Map());
2112
- this.config = {
2113
- ...config,
2114
- gatewayUrl: validateGatewayUrl(config.gatewayUrl),
2115
- headers: sanitizeHeaders(config.headers)
2116
- };
2117
- }
2118
- getConfig() {
2119
- return this.config;
2120
- }
2121
- /**
2122
- * Execute a GraphQL query (with deduplication and caching).
2123
- *
2124
- * Pass `{ cache: false }` to bypass the cache entirely — required for poll
2125
- * loops, where every tick must reach the network.
2126
- */
2127
- async query(query, variables, options) {
2128
- if (options?.cache === false) {
2129
- return this.request(query, variables, true, options.timeoutMs);
2130
- }
2131
- const cacheKey = JSON.stringify({ query, variables });
2132
- const cached = this.queryCache.get(cacheKey);
2133
- if (cached) {
2134
- if (Date.now() - cached.ts < _WebSDKClient.CACHE_TTL) {
2135
- return cached.data;
2136
- }
2137
- this.queryCache.delete(cacheKey);
2138
- }
2139
- const existing = this.inflight.get(cacheKey);
2140
- if (existing) {
2141
- return existing;
2142
- }
2143
- const promise = this.request(query, variables, true, options?.timeoutMs).then((result) => {
2144
- if (result.data && !result.errors?.length) {
2145
- if (this.queryCache.size >= _WebSDKClient.MAX_CACHE_ENTRIES) {
2146
- const oldestEntry = this.queryCache.keys().next().value;
2147
- if (oldestEntry) {
2148
- this.queryCache.delete(oldestEntry);
2149
- }
2150
- }
2151
- this.queryCache.set(cacheKey, { data: result, ts: Date.now() });
2152
- }
2153
- return result;
2154
- }).finally(() => {
2155
- this.inflight.delete(cacheKey);
2156
- });
2157
- this.inflight.set(cacheKey, promise);
2158
- return promise;
2159
- }
2160
- /**
2161
- * Execute a GraphQL mutation
2162
- */
2163
- async mutate(mutation, variables, options) {
2164
- return this.request(mutation, variables, false, options?.timeoutMs);
2165
- }
2166
- /** HTTP statuses worth another attempt — transient server/edge conditions. */
2167
- static isRetriableStatus(status) {
2168
- return status === 429 || status === 408 || status >= 500 && status < 600;
2169
- }
2170
- static sleep(ms) {
2171
- return new Promise((resolve) => setTimeout(resolve, ms));
2172
- }
2173
- /**
2174
- * Perform the HTTP call with a hard timeout. Every outcome resolves to a
2175
- * GraphQLResponse — callers never hang, so a UI's `loading` state always
2176
- * settles into data or a renderable error.
2177
- */
2178
- async attempt(query, variables, timeoutMs) {
2179
- const controller = new AbortController();
2180
- const timer = setTimeout(() => controller.abort(), timeoutMs);
2181
- try {
2182
- const response = await fetch(this.config.gatewayUrl, {
2183
- method: "POST",
2184
- headers: {
2185
- "Content-Type": "application/json",
2186
- "x-product-id": this.config.productId,
2187
- ...this.config.headers,
2188
- ...cfAccessHeaders(this.config.gatewayUrl, this.config.cfAccess)
2189
- },
2190
- body: JSON.stringify({ query, variables }),
2191
- signal: controller.signal
2192
- });
2193
- if (!response.ok) {
2194
- console.error(
2195
- "[WebSDK] GraphQL request failed",
2196
- response.status,
2197
- response.statusText
2198
- );
2199
- return {
2200
- res: {
2201
- errors: [
2202
- {
2203
- message: `HTTP ${response.status}: ${response.statusText}`,
2204
- extensions: { code: `HTTP_${response.status}` }
2205
- }
2206
- ]
2207
- },
2208
- retriable: _WebSDKClient.isRetriableStatus(response.status)
2209
- };
2210
- }
2211
- return {
2212
- res: await response.json(),
2213
- retriable: false
2214
- };
2215
- } catch (error) {
2216
- const aborted = error instanceof Error && (error.name === "AbortError" || controller.signal.aborted);
2217
- const message = aborted ? `Request timed out after ${timeoutMs}ms` : error instanceof Error ? error.message : "Network error";
2218
- console.error("[WebSDK] Network error", message);
2219
- return {
2220
- res: {
2221
- errors: [
2222
- {
2223
- message,
2224
- extensions: { code: aborted ? "TIMEOUT" : "NETWORK_ERROR" }
2225
- }
2226
- ]
2227
- },
2228
- // Transport-level failures are worth one more try; a genuine outage
2229
- // just fails twice quickly and still renders an error state.
2230
- retriable: true
2231
- };
2232
- } finally {
2233
- clearTimeout(timer);
2234
- }
2235
- }
2236
- async request(query, variables, retry = true, timeoutOverrideMs) {
2237
- const timeoutMs = timeoutOverrideMs ?? this.config.timeoutMs ?? _WebSDKClient.DEFAULT_TIMEOUT_MS;
2238
- const maxRetries = retry ? this.config.maxRetries ?? _WebSDKClient.DEFAULT_MAX_RETRIES : 0;
2239
- let last;
2240
- for (let i = 0; i <= maxRetries; i++) {
2241
- const { res, retriable } = await this.attempt(
2242
- query,
2243
- variables,
2244
- timeoutMs
2245
- );
2246
- if (!retriable || i === maxRetries) return res;
2247
- last = res;
2248
- await _WebSDKClient.sleep(
2249
- _WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200
2250
- );
2251
- }
2252
- return last;
2253
- }
2254
- };
2255
- __publicField(_WebSDKClient, "CACHE_TTL", 5 * 60 * 1e3);
2256
- // 5 minutes
2257
- __publicField(_WebSDKClient, "MAX_CACHE_ENTRIES", 100);
2258
- __publicField(_WebSDKClient, "DEFAULT_TIMEOUT_MS", 12e3);
2259
- __publicField(_WebSDKClient, "DEFAULT_MAX_RETRIES", 1);
2260
- __publicField(_WebSDKClient, "RETRY_BASE_DELAY_MS", 400);
2261
- var WebSDKContext = createContext(null);
2262
- function useWebSDK() {
2263
- const client = useContext(WebSDKContext);
2264
- if (!client) {
2265
- throw new Error("useWebSDK must be used within a WebSDKProvider");
2266
- }
2267
- return client;
2268
- }
2269
- function useWebSDKConfig() {
2270
- const client = useWebSDK();
2271
- return client.getConfig();
2272
- }
2273
-
2274
- // src/utils/product-slug.ts
2275
- var PRODUCT_SLUG_RENAMES = Object.freeze(
2276
- [Object.freeze({ legacy: "botlit", current: "botmanor" })]
2277
- );
2278
- Object.freeze(
2279
- Object.fromEntries(PRODUCT_SLUG_RENAMES.map((r) => [r.legacy, r.current]))
2280
- );
2281
- var PRODUCT_SLUG_EMIT = Object.freeze({ productSlug: "current" });
2282
- function findRename(slug) {
2283
- const wanted = slug.toLowerCase();
2284
- return PRODUCT_SLUG_RENAMES.find(
2285
- (r) => r.legacy === wanted || r.current === wanted
2286
- );
2196
+ // src/utils/product-slug.ts
2197
+ var PRODUCT_SLUG_RENAMES = Object.freeze(
2198
+ [Object.freeze({ legacy: "botlit", current: "botmanor" })]
2199
+ );
2200
+ Object.freeze(
2201
+ Object.fromEntries(PRODUCT_SLUG_RENAMES.map((r) => [r.legacy, r.current]))
2202
+ );
2203
+ var PRODUCT_SLUG_EMIT = Object.freeze({ productSlug: "current" });
2204
+ function findRename(slug) {
2205
+ const wanted = slug.toLowerCase();
2206
+ return PRODUCT_SLUG_RENAMES.find(
2207
+ (r) => r.legacy === wanted || r.current === wanted
2208
+ );
2287
2209
  }
2288
2210
  function normalizeProductSlug(slug) {
2289
2211
  if (slug == null) return slug;
@@ -2292,6 +2214,11 @@ function normalizeProductSlug(slug) {
2292
2214
  function legacyProductSlug(slug) {
2293
2215
  return findRename(slug)?.legacy ?? slug;
2294
2216
  }
2217
+ function productSlugVariants(slug) {
2218
+ return [
2219
+ .../* @__PURE__ */ new Set([slug, normalizeProductSlug(slug), legacyProductSlug(slug)])
2220
+ ];
2221
+ }
2295
2222
  function isSameProductSlug(a, b) {
2296
2223
  if (a == null || b == null) return a === b;
2297
2224
  return a === b || normalizeProductSlug(a) === normalizeProductSlug(b);
@@ -2872,7 +2799,9 @@ function useExploreChat(options = {}) {
2872
2799
  pollTimeoutMs = DEFAULT_POLL_TIMEOUT_MS,
2873
2800
  storageKey = DEFAULT_STORAGE_KEY,
2874
2801
  persist = true,
2875
- onSend
2802
+ onSend,
2803
+ enabled = true,
2804
+ shareToken: shareTokenOption
2876
2805
  } = options;
2877
2806
  const client = useWebSDK();
2878
2807
  const { productId } = useWebSDKConfig();
@@ -2910,7 +2839,7 @@ function useExploreChat(options = {}) {
2910
2839
  const [hasConversation, setHasConversation] = useState(false);
2911
2840
  const shareTokenRef = useRef(void 0);
2912
2841
  if (shareTokenRef.current === void 0) {
2913
- shareTokenRef.current = readShareToken();
2842
+ shareTokenRef.current = shareTokenOption === void 0 ? readShareToken() : shareTokenOption;
2914
2843
  }
2915
2844
  const isSharedView = shareTokenRef.current !== null;
2916
2845
  const catalogRef = useRef(catalog);
@@ -2948,6 +2877,7 @@ function useExploreChat(options = {}) {
2948
2877
  };
2949
2878
  }, []);
2950
2879
  useEffect(() => {
2880
+ if (!enabled) return;
2951
2881
  const shareToken = shareTokenRef.current;
2952
2882
  if (!shareToken) return;
2953
2883
  let cancelled = false;
@@ -2982,8 +2912,9 @@ function useExploreChat(options = {}) {
2982
2912
  return () => {
2983
2913
  cancelled = true;
2984
2914
  };
2985
- }, [client]);
2915
+ }, [client, enabled]);
2986
2916
  useEffect(() => {
2917
+ if (!enabled) return;
2987
2918
  if (shareTokenRef.current !== null) return;
2988
2919
  if (!persist) {
2989
2920
  setHydrated(true);
@@ -3008,9 +2939,10 @@ function useExploreChat(options = {}) {
3008
2939
  setTurnCount(turns);
3009
2940
  }
3010
2941
  setHydrated(true);
3011
- }, [persist, rememberConversationToken, storageKey]);
2942
+ }, [persist, rememberConversationToken, storageKey, enabled]);
3012
2943
  useEffect(() => {
3013
- if (!persist || !hydrated || typeof window === "undefined") return;
2944
+ if (!persist || !hydrated || isSharedView || typeof window === "undefined")
2945
+ return;
3014
2946
  try {
3015
2947
  const payload = {
3016
2948
  conversationToken: conversationTokenRef.current,
@@ -3024,10 +2956,10 @@ function useExploreChat(options = {}) {
3024
2956
  window.localStorage.setItem(storageKey, JSON.stringify(payload));
3025
2957
  } catch {
3026
2958
  }
3027
- }, [persist, hydrated, storageKey, messages, focusProduct]);
2959
+ }, [persist, hydrated, isSharedView, storageKey, messages, focusProduct]);
3028
2960
  useEffect(() => {
3029
2961
  messagesRef.current = messages;
3030
- if (!persist || !hydrated) return;
2962
+ if (!persist || !hydrated || isSharedView) return;
3031
2963
  const settled = messages.some(
3032
2964
  (m) => m.role === "ASSISTANT" && (m.status === "COMPLETED" || m.status === "FAILED")
3033
2965
  );
@@ -3039,8 +2971,9 @@ function useExploreChat(options = {}) {
3039
2971
  focusProduct: focusProductRef.current
3040
2972
  })
3041
2973
  );
3042
- }, [messages, persist, hydrated, storageKey]);
2974
+ }, [messages, persist, hydrated, isSharedView, storageKey]);
3043
2975
  useEffect(() => {
2976
+ if (!enabled) return;
3044
2977
  let cancelled = false;
3045
2978
  const load = async () => {
3046
2979
  const variables = { productSlug: productSlug ?? null };
@@ -3081,7 +3014,7 @@ function useExploreChat(options = {}) {
3081
3014
  return () => {
3082
3015
  cancelled = true;
3083
3016
  };
3084
- }, [client, productSlug, fallbackCatalog, bakedRaw]);
3017
+ }, [client, productSlug, fallbackCatalog, bakedRaw, enabled]);
3085
3018
  const startPolling = useCallback(
3086
3019
  (conversationToken, messageId) => {
3087
3020
  pollGenerationRef.current += 1;
@@ -3573,10 +3506,326 @@ function useExploreChat(options = {}) {
3573
3506
  isSharedView
3574
3507
  };
3575
3508
  }
3576
- var optimisticCounter = 0;
3577
- function makeOptimisticId() {
3578
- optimisticCounter += 1;
3579
- return `boff-explore-local-${Date.now()}-${optimisticCounter}`;
3509
+ var optimisticCounter = 0;
3510
+ function makeOptimisticId() {
3511
+ optimisticCounter += 1;
3512
+ return `boff-explore-local-${Date.now()}-${optimisticCounter}`;
3513
+ }
3514
+ var ExploreConversationContext = createContext(null);
3515
+ createContext(null);
3516
+ function useExploreConversation(options = {}) {
3517
+ const {
3518
+ productSlug,
3519
+ locale,
3520
+ examplePrompts,
3521
+ onSend,
3522
+ pageUrl,
3523
+ enabled,
3524
+ shareToken
3525
+ } = options;
3526
+ const urlAtMount = useMemo(
3527
+ () => typeof window === "undefined" ? void 0 : window.location.href,
3528
+ []
3529
+ );
3530
+ const T = useMemo(
3531
+ () => exploreStrings(resolveExploreLocale(locale)),
3532
+ [locale]
3533
+ );
3534
+ const chat = useExploreChat({
3535
+ productSlug,
3536
+ pageUrl: pageUrl ?? urlAtMount,
3537
+ onSend,
3538
+ // Locale-aware, so a catalog outage degrades to a translated welcome rather than an English one.
3539
+ examplePrompts: examplePrompts ?? T.prompts,
3540
+ fallbackWelcome: { title: T.welcomeTitle, body: T.welcomeBody },
3541
+ ...enabled === void 0 ? {} : { enabled },
3542
+ ...shareToken === void 0 ? {} : { shareToken }
3543
+ });
3544
+ const [draft, setDraft] = useState("");
3545
+ const [staged, setStaged] = useState([]);
3546
+ return useMemo(
3547
+ () => ({ ...chat, draft, setDraft, staged, setStaged }),
3548
+ [chat, draft, staged]
3549
+ );
3550
+ }
3551
+
3552
+ // src/components/explore-scope.ts
3553
+ function pinnedProductSlug(scope, productSlug) {
3554
+ if (scope !== "product" || productSlug === void 0) return null;
3555
+ return productSlug.trim() === "" ? null : productSlug;
3556
+ }
3557
+ function productNameFor(products, slug, given) {
3558
+ const own = given?.trim();
3559
+ if (own) return own;
3560
+ return products.find((product) => isSameProductSlug(product.slug, slug))?.name ?? null;
3561
+ }
3562
+ var NAME_CHARACTER = /[a-z0-9]/;
3563
+ var MIN_SPELLING_LENGTH = 3;
3564
+ function siteNameOf(website) {
3565
+ if (!website) return "";
3566
+ try {
3567
+ const labels = new URL(website).hostname.split(".");
3568
+ return labels.length >= 2 ? labels[labels.length - 2] ?? "" : "";
3569
+ } catch {
3570
+ return "";
3571
+ }
3572
+ }
3573
+ function spellingsOf(product) {
3574
+ const spellings = [
3575
+ product.name,
3576
+ product.name.replace(/\s+/g, ""),
3577
+ ...productSlugVariants(product.slug),
3578
+ siteNameOf(product.website)
3579
+ ].map((spelling) => spelling.trim().toLowerCase()).filter((spelling) => spelling.length >= MIN_SPELLING_LENGTH);
3580
+ return [...new Set(spellings)];
3581
+ }
3582
+ function wordAt(text, spelling, from = 0) {
3583
+ for (let at = text.indexOf(spelling, from); at !== -1; at = text.indexOf(spelling, at + 1)) {
3584
+ const before = text[at - 1];
3585
+ const after = text[at + spelling.length];
3586
+ const bounded = (before === void 0 || !NAME_CHARACTER.test(before)) && (after === void 0 || !NAME_CHARACTER.test(after));
3587
+ if (bounded) return at;
3588
+ }
3589
+ return -1;
3590
+ }
3591
+ function withoutWord(text, spelling) {
3592
+ let result = text;
3593
+ for (let at = wordAt(result, spelling); at !== -1; at = wordAt(result, spelling, at + spelling.length)) {
3594
+ result = `${result.slice(0, at)}${" ".repeat(spelling.length)}${result.slice(at + spelling.length)}`;
3595
+ }
3596
+ return result;
3597
+ }
3598
+ function anotherProductMatcher(products, pinnedSlug) {
3599
+ const own = productSlugVariants(pinnedSlug).map((slug) => slug.toLowerCase());
3600
+ const others = [];
3601
+ for (const product of products) {
3602
+ if (isSameProductSlug(product.slug, pinnedSlug)) {
3603
+ own.push(...spellingsOf(product));
3604
+ } else {
3605
+ others.push(...spellingsOf(product));
3606
+ }
3607
+ }
3608
+ const ownSpellings = [...new Set(own)].sort((a, b) => b.length - a.length);
3609
+ const otherSpellings = [...new Set(others)].filter(
3610
+ (spelling) => !ownSpellings.includes(spelling)
3611
+ );
3612
+ return (text) => {
3613
+ let rest = text.toLowerCase();
3614
+ for (const spelling of ownSpellings) rest = withoutWord(rest, spelling);
3615
+ return otherSpellings.some((spelling) => wordAt(rest, spelling) !== -1);
3616
+ };
3617
+ }
3618
+ function distinctPrompts(prompts) {
3619
+ return [...new Set(prompts.filter((prompt) => prompt.trim() !== ""))];
3620
+ }
3621
+ function productScopedPrompts(hostPrompts, catalogPrompts, namesAnotherProduct) {
3622
+ const own = distinctPrompts(hostPrompts ?? []);
3623
+ if (own.length > 0) return own;
3624
+ return distinctPrompts(
3625
+ catalogPrompts.filter(
3626
+ (prompt) => !isPortfolioPrompt(prompt) && !namesAnotherProduct(prompt)
3627
+ )
3628
+ );
3629
+ }
3630
+ function productScopedHighlights(highlights, pinnedSlug, namesAnotherProduct) {
3631
+ return highlights.filter(
3632
+ (highlight) => isSameProductSlug(highlight.product, pinnedSlug) && !namesAnotherProduct(`${highlight.title}
3633
+ ${highlight.alt}`)
3634
+ );
3635
+ }
3636
+ function productScopedError(error, toolBudgetMessage) {
3637
+ return error.code === "TOOL_BUDGET" ? { ...error, message: toolBudgetMessage } : error;
3638
+ }
3639
+ function isDevelopmentBuild() {
3640
+ try {
3641
+ return process.env.NODE_ENV !== "production";
3642
+ } catch {
3643
+ return false;
3644
+ }
3645
+ }
3646
+ var warnedWithoutSlug = false;
3647
+ function warnProductScopeWithoutSlug() {
3648
+ if (warnedWithoutSlug || !isDevelopmentBuild()) return;
3649
+ warnedWithoutSlug = true;
3650
+ console.warn(
3651
+ `[WebSDK] Explore scope="product" needs a productSlug. Without one the assistant stays the portfolio's: every product, and a product picker.`
3652
+ );
3653
+ }
3654
+ var PROSE_CSS = `
3655
+ .boff-prose {
3656
+ max-width: none;
3657
+ }
3658
+
3659
+ .boff-prose h1 {
3660
+ font-size: 2.25rem;
3661
+ font-weight: 800;
3662
+ line-height: 1.2;
3663
+ margin-top: 0;
3664
+ margin-bottom: 1rem;
3665
+ color: hsl(var(--foreground));
3666
+ }
3667
+
3668
+ .boff-prose h2 {
3669
+ font-size: 1.75rem;
3670
+ font-weight: 700;
3671
+ line-height: 1.3;
3672
+ margin-top: 2rem;
3673
+ margin-bottom: 1rem;
3674
+ color: hsl(var(--foreground));
3675
+ }
3676
+
3677
+ .boff-prose h3 {
3678
+ font-size: 1.5rem;
3679
+ font-weight: 600;
3680
+ line-height: 1.4;
3681
+ margin-top: 1.5rem;
3682
+ margin-bottom: 0.75rem;
3683
+ color: hsl(var(--foreground));
3684
+ }
3685
+
3686
+ .boff-prose h4 {
3687
+ font-size: 1.25rem;
3688
+ font-weight: 600;
3689
+ line-height: 1.5;
3690
+ margin-top: 1.25rem;
3691
+ margin-bottom: 0.5rem;
3692
+ color: hsl(var(--foreground));
3693
+ }
3694
+
3695
+ .boff-prose p {
3696
+ margin-bottom: 1rem;
3697
+ line-height: 1.75;
3698
+ color: hsl(var(--foreground));
3699
+ }
3700
+
3701
+ .boff-prose ul,
3702
+ .boff-prose ol {
3703
+ margin-bottom: 1rem;
3704
+ padding-left: 1.5rem;
3705
+ }
3706
+
3707
+ .boff-prose ul {
3708
+ list-style-type: disc;
3709
+ }
3710
+
3711
+ .boff-prose ol {
3712
+ list-style-type: decimal;
3713
+ }
3714
+
3715
+ .boff-prose li {
3716
+ margin-bottom: 0.25rem;
3717
+ line-height: 1.75;
3718
+ color: hsl(var(--foreground));
3719
+ }
3720
+
3721
+ .boff-prose li > ul,
3722
+ .boff-prose li > ol {
3723
+ margin-top: 0.25rem;
3724
+ margin-bottom: 0.25rem;
3725
+ }
3726
+
3727
+ .boff-prose a {
3728
+ color: hsl(var(--primary));
3729
+ text-decoration: underline;
3730
+ text-underline-offset: 2px;
3731
+ }
3732
+
3733
+ .boff-prose a:hover {
3734
+ opacity: 0.8;
3735
+ }
3736
+
3737
+ .boff-prose hr {
3738
+ border: none;
3739
+ height: 1px;
3740
+ background-color: hsl(var(--border));
3741
+ margin: 2rem 0;
3742
+ }
3743
+
3744
+ .boff-prose blockquote {
3745
+ border-left: 4px solid hsl(var(--border));
3746
+ padding-left: 1rem;
3747
+ margin: 1.5rem 0;
3748
+ font-style: italic;
3749
+ color: hsl(var(--muted-foreground));
3750
+ }
3751
+
3752
+ .boff-prose strong {
3753
+ font-weight: 700;
3754
+ color: hsl(var(--foreground));
3755
+ }
3756
+
3757
+ .boff-prose code {
3758
+ background-color: hsl(var(--muted));
3759
+ padding: 0.125rem 0.25rem;
3760
+ border-radius: 0.25rem;
3761
+ font-size: 0.875em;
3762
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
3763
+ }
3764
+
3765
+ .boff-prose pre {
3766
+ background-color: hsl(var(--muted));
3767
+ padding: 1rem;
3768
+ border-radius: 0.5rem;
3769
+ overflow-x: auto;
3770
+ margin-bottom: 1rem;
3771
+ }
3772
+
3773
+ .boff-prose pre code {
3774
+ background-color: transparent;
3775
+ padding: 0;
3776
+ }
3777
+
3778
+ .boff-prose img {
3779
+ max-width: 100%;
3780
+ height: auto;
3781
+ }
3782
+
3783
+ .boff-prose table {
3784
+ width: 100%;
3785
+ border-collapse: collapse;
3786
+ margin-bottom: 1rem;
3787
+ }
3788
+
3789
+ .boff-prose th,
3790
+ .boff-prose td {
3791
+ border: 1px solid hsl(var(--border));
3792
+ padding: 0.5rem;
3793
+ text-align: left;
3794
+ }
3795
+
3796
+ .boff-prose th {
3797
+ font-weight: 600;
3798
+ background-color: hsl(var(--muted));
3799
+ }
3800
+
3801
+ /* Smaller variant used inside cards and compact panels */
3802
+ .boff-prose-sm {
3803
+ font-size: 0.875rem;
3804
+ }
3805
+
3806
+ .boff-prose-sm h1 {
3807
+ font-size: 1.75rem;
3808
+ }
3809
+
3810
+ .boff-prose-sm h2 {
3811
+ font-size: 1.5rem;
3812
+ }
3813
+
3814
+ .boff-prose-sm h3 {
3815
+ font-size: 1.25rem;
3816
+ }
3817
+
3818
+ .boff-prose-sm h4 {
3819
+ font-size: 1.125rem;
3820
+ }
3821
+
3822
+ .boff-prose-sm p,
3823
+ .boff-prose-sm li {
3824
+ line-height: 1.625;
3825
+ }
3826
+ `;
3827
+ function ProseStyles() {
3828
+ return /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: PROSE_CSS } });
3580
3829
  }
3581
3830
  var DRAIN_TARGET_MS = 1200;
3582
3831
  var MIN_CHARS_PER_SECOND = 90;
@@ -4785,21 +5034,25 @@ var CAPABILITIES = [
4785
5034
  {
4786
5035
  icon: BookOpenText,
4787
5036
  title: "Grounded in our own docs",
4788
- body: "Every answer comes from published product pages and documentation \u2014 never invented."
5037
+ body: "Every answer comes from published product pages and documentation \u2014 never invented.",
5038
+ invitesOtherProducts: false
4789
5039
  },
4790
5040
  {
4791
5041
  icon: Layers,
4792
5042
  title: "Compare across the ecosystem",
4793
- body: "Ask which product fits your team, or how two of them work together."
5043
+ body: "Ask which product fits your team, or how two of them work together.",
5044
+ invitesOtherProducts: true
4794
5045
  },
4795
5046
  {
4796
5047
  icon: Link2,
4797
5048
  title: "Straight to the right page",
4798
- body: "Get the sources and next steps \u2014 pricing, docs, a demo \u2014 without hunting."
5049
+ body: "Get the sources and next steps \u2014 pricing, docs, a demo \u2014 without hunting.",
5050
+ invitesOtherProducts: false
4799
5051
  }
4800
5052
  ];
4801
5053
  var MIN_VISIBLE_FRACTION = 0.25;
4802
5054
  var SDK_OVERLAY_SELECTOR = "[data-boff-explore]";
5055
+ var NO_PRODUCTS = [];
4803
5056
  var CTA_VARIANTS = {
4804
5057
  CONTACT: "default",
4805
5058
  WAITLIST: "default",
@@ -6348,29 +6601,40 @@ function WelcomeState({
6348
6601
  focusProduct,
6349
6602
  onPrompt,
6350
6603
  onFocus,
6351
- disabled
6604
+ disabled,
6605
+ heading = "h1",
6606
+ productScoped = false
6352
6607
  }) {
6608
+ const Heading = heading;
6353
6609
  return /* @__PURE__ */ jsxs("div", { className: "boff-explore-aura mx-auto my-auto w-full max-w-3xl px-4 py-4 sm:py-5", children: [
6354
6610
  /* @__PURE__ */ jsxs("div", { className: "boff-explore-rise text-center", children: [
6355
6611
  /* @__PURE__ */ jsxs("span", { className: "boff-explore-hero-badge inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1 text-xs font-medium text-muted-foreground", children: [
6356
6612
  /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" }),
6357
6613
  T.badge
6358
6614
  ] }),
6359
- /* @__PURE__ */ jsx("h1", { className: "mt-2 text-balance break-words text-2xl font-bold tracking-tight sm:text-3xl", children: title }),
6615
+ /* @__PURE__ */ jsx(Heading, { className: "mt-2 text-balance break-words text-2xl font-bold tracking-tight sm:text-3xl", children: title }),
6360
6616
  /* @__PURE__ */ jsx("p", { className: "mx-auto mt-2 max-w-2xl text-pretty text-sm leading-relaxed text-muted-foreground", children: body })
6361
6617
  ] }),
6362
- /* @__PURE__ */ jsx("ul", { className: "boff-explore-capabilities boff-explore-rise boff-explore-rise-1 mt-4 grid grid-cols-3 gap-2 sm:gap-2.5", children: CAPABILITIES.map(({ icon: Icon, body: capBody }, i) => /* @__PURE__ */ jsxs(
6363
- "li",
6618
+ /* @__PURE__ */ jsx(
6619
+ "ul",
6364
6620
  {
6365
- className: "rounded-xl border border-border/70 bg-card/60 p-2.5 text-center transition-colors hover:border-border sm:p-2.5 sm:text-left",
6366
- children: [
6367
- /* @__PURE__ */ jsx("span", { className: "mx-auto mb-1.5 flex h-7 w-7 items-center justify-center rounded-lg bg-primary/10 text-primary sm:mx-0 sm:mb-2 sm:h-8 sm:w-8", children: /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5 sm:h-4 sm:w-4" }) }),
6368
- /* @__PURE__ */ jsx("p", { className: "text-[11px] font-semibold leading-tight text-card-foreground sm:text-sm sm:leading-snug", children: T.capabilities[i] ?? "" }),
6369
- /* @__PURE__ */ jsx("p", { className: "mt-1 hidden text-xs leading-snug text-muted-foreground lg:block", children: capBody })
6370
- ]
6371
- },
6372
- i
6373
- )) }),
6621
+ className: `boff-explore-capabilities boff-explore-rise boff-explore-rise-1 mt-4 grid ${productScoped ? "grid-cols-2" : "grid-cols-3"} gap-2 sm:gap-2.5`,
6622
+ children: CAPABILITIES.map(
6623
+ ({ icon: Icon, body: capBody, invitesOtherProducts }, i) => productScoped && invitesOtherProducts ? null : /* @__PURE__ */ jsxs(
6624
+ "li",
6625
+ {
6626
+ className: "rounded-xl border border-border/70 bg-card/60 p-2.5 text-center transition-colors hover:border-border sm:p-2.5 sm:text-left",
6627
+ children: [
6628
+ /* @__PURE__ */ jsx("span", { className: "mx-auto mb-1.5 flex h-7 w-7 items-center justify-center rounded-lg bg-primary/10 text-primary sm:mx-0 sm:mb-2 sm:h-8 sm:w-8", children: /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5 sm:h-4 sm:w-4" }) }),
6629
+ /* @__PURE__ */ jsx("p", { className: "text-[11px] font-semibold leading-tight text-card-foreground sm:text-sm sm:leading-snug", children: T.capabilities[i] ?? "" }),
6630
+ /* @__PURE__ */ jsx("p", { className: "mt-1 hidden text-xs leading-snug text-muted-foreground lg:block", children: capBody })
6631
+ ]
6632
+ },
6633
+ i
6634
+ )
6635
+ )
6636
+ }
6637
+ ),
6374
6638
  prompts.length > 0 ? /* @__PURE__ */ jsx("div", { className: "boff-explore-rise boff-explore-rise-2 mt-4", children: /* @__PURE__ */ jsx(
6375
6639
  PromptCarousel,
6376
6640
  {
@@ -6411,19 +6675,39 @@ function exploreQuestionHref(question, base = "/explore") {
6411
6675
  const joiner = base.includes("?") ? "&" : "?";
6412
6676
  return `${base}${joiner}q=${encodeURIComponent(trimmed)}`;
6413
6677
  }
6414
- function ExplorePage({
6678
+ function ExplorePage(props) {
6679
+ const shared = useContext(ExploreConversationContext);
6680
+ return shared ? /* @__PURE__ */ jsx(ExploreView, { ...props, conversation: shared }) : /* @__PURE__ */ jsx(StandaloneExplorePage, { ...props });
6681
+ }
6682
+ function StandaloneExplorePage(props) {
6683
+ const conversation = useExploreConversation({
6684
+ productSlug: props.productSlug,
6685
+ locale: props.locale,
6686
+ examplePrompts: props.examplePrompts,
6687
+ onSend: props.onSend
6688
+ });
6689
+ return /* @__PURE__ */ jsx(ExploreView, { ...props, conversation });
6690
+ }
6691
+ function ExploreView({
6415
6692
  seo,
6416
6693
  productSlug,
6417
- examplePrompts,
6418
6694
  className,
6419
6695
  heightMode = "viewport",
6420
6696
  viewportOffset,
6421
6697
  onNavigate,
6422
- onSend,
6423
6698
  welcomeTitle,
6424
6699
  welcomeBody,
6425
- locale
6700
+ locale,
6701
+ presentation = "page",
6702
+ active = true,
6703
+ explorePath = "/explore",
6704
+ examplePrompts,
6705
+ scope,
6706
+ productName,
6707
+ conversation
6426
6708
  }) {
6709
+ const panel = presentation === "panel";
6710
+ const viewportPage = !panel && heightMode === "viewport";
6427
6711
  const pageUrl = useMemo(
6428
6712
  () => typeof window === "undefined" ? void 0 : window.location.href,
6429
6713
  []
@@ -6459,26 +6743,21 @@ function ExplorePage({
6459
6743
  escalate,
6460
6744
  canEscalate,
6461
6745
  createShareLink,
6462
- isSharedView
6463
- } = useExploreChat({
6464
- productSlug,
6465
- pageUrl,
6466
- onSend,
6467
- // Locale-aware, so a catalog outage degrades to a translated welcome rather than an
6468
- // English one. `T.prompts` seeds the chips the same way.
6469
- examplePrompts: examplePrompts ?? T.prompts,
6470
- fallbackWelcome: { title: T.welcomeTitle, body: T.welcomeBody }
6471
- });
6472
- const [draft, setDraft] = useState("");
6746
+ isSharedView,
6747
+ draft,
6748
+ setDraft,
6749
+ staged,
6750
+ setStaged
6751
+ } = conversation;
6473
6752
  const textareaRef = useRef(null);
6474
6753
  useEffect(() => {
6475
- if (typeof window === "undefined") return;
6754
+ if (typeof window === "undefined" || panel) return;
6476
6755
  const params = new URLSearchParams(window.location.search);
6477
6756
  if (params.has("c")) return;
6478
6757
  const question = params.get("q")?.trim();
6479
6758
  if (!question) return;
6480
6759
  setDraft(question.slice(0, EXPLORE_PREFILL_MAX_LENGTH));
6481
- }, []);
6760
+ }, [panel, setDraft]);
6482
6761
  const [historyOpen, setHistoryOpen] = useState(false);
6483
6762
  const speechStopRef = useRef(() => void 0);
6484
6763
  const stopDictation = useCallback(() => {
@@ -6494,8 +6773,12 @@ function ExplorePage({
6494
6773
  }
6495
6774
  });
6496
6775
  speechStopRef.current = speech.stop;
6776
+ useEffect(() => {
6777
+ if (active) return;
6778
+ stopDictation();
6779
+ stopSpeaking();
6780
+ }, [active, stopDictation]);
6497
6781
  const [disclaimerOpen, setDisclaimerOpen] = useState(false);
6498
- const [staged, setStaged] = useState([]);
6499
6782
  const [attachmentNotice, setAttachmentNotice] = useState(null);
6500
6783
  const fileInputRef = useRef(null);
6501
6784
  const stagedRef = useRef([]);
@@ -6515,16 +6798,47 @@ function ExplorePage({
6515
6798
  const maxLength = catalog.limits.maxMessageLength;
6516
6799
  const overLimit = draft.length > maxLength;
6517
6800
  const canSubmit = canSend && draft.trim().length > 0 && !overLimit && !busy;
6518
- const resolvedTitle = welcomeTitle ?? catalog.welcomeTitle;
6519
- const resolvedBody = welcomeBody ?? catalog.welcomeBody;
6520
- const prompts = catalog.examplePrompts;
6801
+ const pinnedSlug = pinnedProductSlug(scope, productSlug);
6802
+ useEffect(() => {
6803
+ if (scope === "product" && pinnedSlug === null) {
6804
+ warnProductScopeWithoutSlug();
6805
+ }
6806
+ }, [pinnedSlug, scope]);
6807
+ const pinnedName = useMemo(
6808
+ () => pinnedSlug === null ? null : productNameFor(catalog.products, pinnedSlug, productName),
6809
+ [catalog.products, pinnedSlug, productName]
6810
+ );
6811
+ const namesAnotherProduct = useMemo(
6812
+ () => pinnedSlug === null ? null : anotherProductMatcher(catalog.products, pinnedSlug),
6813
+ [catalog.products, pinnedSlug]
6814
+ );
6815
+ const resolvedTitle = welcomeTitle ?? (namesAnotherProduct?.(catalog.welcomeTitle) ? T.welcomeTitle : catalog.welcomeTitle);
6816
+ const resolvedBody = welcomeBody ?? (pinnedSlug === null ? catalog.welcomeBody : pinnedName === null ? T.welcomeBodyScoped : fill(T.welcomeBodyProduct, { product: pinnedName }));
6817
+ const prompts = useMemo(
6818
+ () => namesAnotherProduct === null ? catalog.examplePrompts : productScopedPrompts(
6819
+ examplePrompts,
6820
+ catalog.examplePrompts,
6821
+ namesAnotherProduct
6822
+ ),
6823
+ [catalog.examplePrompts, examplePrompts, namesAnotherProduct]
6824
+ );
6825
+ const conceptHighlights = useMemo(
6826
+ () => pinnedSlug === null || namesAnotherProduct === null ? catalog.conceptHighlights : productScopedHighlights(
6827
+ catalog.conceptHighlights,
6828
+ pinnedSlug,
6829
+ namesAnotherProduct
6830
+ ),
6831
+ [catalog.conceptHighlights, namesAnotherProduct, pinnedSlug]
6832
+ );
6521
6833
  const focusedProductName = useMemo(
6522
- () => catalog.products.find((p) => isSameProductSlug(p.slug, focusProduct))?.name ?? null,
6523
- [catalog.products, focusProduct]
6834
+ () => pinnedSlug !== null ? pinnedName : catalog.products.find((p) => isSameProductSlug(p.slug, focusProduct))?.name ?? null,
6835
+ [catalog.products, focusProduct, pinnedName, pinnedSlug]
6524
6836
  );
6525
6837
  const headProductName = useMemo(
6526
- () => productSlug ? catalog.products.find((p) => isSameProductSlug(p.slug, productSlug))?.name ?? null : null,
6527
- [catalog.products, productSlug]
6838
+ () => pinnedSlug !== null ? pinnedName : productSlug ? catalog.products.find(
6839
+ (p) => isSameProductSlug(p.slug, productSlug)
6840
+ )?.name ?? null : null,
6841
+ [catalog.products, pinnedName, pinnedSlug, productSlug]
6528
6842
  );
6529
6843
  const imageOrigins = useMemo(
6530
6844
  () => inlineImageOrigins(catalog.products),
@@ -6548,7 +6862,7 @@ function ExplorePage({
6548
6862
  const [bottomInset, setBottomInset] = useState(0);
6549
6863
  const paneOffsetRef = useRef(0);
6550
6864
  const measurePane = useCallback(() => {
6551
- if (heightMode !== "viewport") return;
6865
+ if (!viewportPage) return;
6552
6866
  const el = rootRef.current;
6553
6867
  if (!el) return;
6554
6868
  const layoutHeight = window.innerHeight;
@@ -6567,7 +6881,7 @@ function ExplorePage({
6567
6881
  paneOffsetRef.current = top;
6568
6882
  setPaneOffset((current) => current === top ? current : top);
6569
6883
  setBottomInset((current) => current === inset ? current : inset);
6570
- }, [heightMode]);
6884
+ }, [viewportPage]);
6571
6885
  const [chromeOverlap, setChromeOverlap] = useState(0);
6572
6886
  const measureChrome = useCallback(() => {
6573
6887
  const root = rootRef.current;
@@ -6592,7 +6906,7 @@ function ExplorePage({
6592
6906
  measureChrome();
6593
6907
  }, [measurePane, measureChrome]);
6594
6908
  useEffect(() => {
6595
- if (typeof window === "undefined") return;
6909
+ if (typeof window === "undefined" || panel) return;
6596
6910
  let frame = 0;
6597
6911
  const run = () => {
6598
6912
  frame = 0;
@@ -6630,12 +6944,12 @@ function ExplorePage({
6630
6944
  setBottomInset(0);
6631
6945
  setChromeOverlap(0);
6632
6946
  };
6633
- }, [remeasure]);
6947
+ }, [remeasure, panel]);
6634
6948
  useEffect(() => {
6635
6949
  measureChrome();
6636
6950
  }, [measureChrome, paneOffset, bottomInset]);
6637
6951
  useEffect(() => {
6638
- if (heightMode !== "viewport" || typeof window === "undefined") return;
6952
+ if (!viewportPage || typeof window === "undefined") return;
6639
6953
  const { history: browserHistory } = window;
6640
6954
  const previousRestoration = "scrollRestoration" in browserHistory ? browserHistory.scrollRestoration : null;
6641
6955
  if (previousRestoration !== null)
@@ -6703,14 +7017,14 @@ function ExplorePage({
6703
7017
  if (previousRestoration !== null)
6704
7018
  browserHistory.scrollRestoration = previousRestoration;
6705
7019
  };
6706
- }, [heightMode, remeasure]);
7020
+ }, [viewportPage, remeasure]);
6707
7021
  const handleScroll = useCallback(() => {
6708
7022
  const el = scrollRef.current;
6709
7023
  if (!el) return;
6710
7024
  stickToBottomRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
6711
7025
  }, []);
6712
7026
  useEffect(() => {
6713
- if (typeof window === "undefined") return;
7027
+ if (typeof window === "undefined" || panel) return;
6714
7028
  let frame = 0;
6715
7029
  const run = () => {
6716
7030
  frame = 0;
@@ -6733,7 +7047,7 @@ function ExplorePage({
6733
7047
  if (frame) window.cancelAnimationFrame(frame);
6734
7048
  window.removeEventListener("scroll", schedule);
6735
7049
  };
6736
- }, []);
7050
+ }, [panel]);
6737
7051
  const latestAssistantId = useMemo(() => {
6738
7052
  for (let i = messages.length - 1; i >= 0; i -= 1) {
6739
7053
  const message = messages[i];
@@ -6749,7 +7063,7 @@ function ExplorePage({
6749
7063
  if (!stickToBottomRef.current) return;
6750
7064
  if (anchor.offsetHeight === 0) return;
6751
7065
  alignedForRef.current = latestAssistantId;
6752
- if (!pageOwnsScrolling(el)) {
7066
+ if (panel || !pageOwnsScrolling(el)) {
6753
7067
  const delta2 = anchor.getBoundingClientRect().top - el.getBoundingClientRect().top;
6754
7068
  el.scrollTop = Math.max(0, el.scrollTop + delta2 - 12);
6755
7069
  return;
@@ -6758,7 +7072,7 @@ function ExplorePage({
6758
7072
  anchor.getBoundingClientRect().top - paneOffsetRef.current - 12
6759
7073
  );
6760
7074
  if (delta !== 0) window.scrollBy({ top: delta, left: 0, behavior: "auto" });
6761
- }, [latestAssistantId, messages]);
7075
+ }, [latestAssistantId, messages, panel]);
6762
7076
  useEffect(() => {
6763
7077
  if (messages.length === 0) return;
6764
7078
  if (!stickToBottomRef.current) return;
@@ -6766,7 +7080,7 @@ function ExplorePage({
6766
7080
  return;
6767
7081
  const el = scrollRef.current;
6768
7082
  if (!el) return;
6769
- if (!pageOwnsScrolling(el)) {
7083
+ if (panel || !pageOwnsScrolling(el)) {
6770
7084
  el.scrollTop = el.scrollHeight;
6771
7085
  return;
6772
7086
  }
@@ -6775,7 +7089,7 @@ function ExplorePage({
6775
7089
  dock.getBoundingClientRect().bottom - visualViewportHeight()
6776
7090
  );
6777
7091
  if (delta > 0) window.scrollBy({ top: delta, left: 0, behavior: "auto" });
6778
- }, [activity, latestAssistantId, messages]);
7092
+ }, [activity, latestAssistantId, messages, panel]);
6779
7093
  const handleShare = useCallback(async () => {
6780
7094
  setShareLabel(T.copying);
6781
7095
  setShareUrl(null);
@@ -6785,7 +7099,7 @@ function ExplorePage({
6785
7099
  setTimeout(() => setShareLabel(T.share), 2500);
6786
7100
  return;
6787
7101
  }
6788
- const url = new URL(pageUrl ?? window.location.href);
7102
+ const url = panel ? new URL(explorePath, window.location.href) : new URL(pageUrl ?? window.location.href);
6789
7103
  url.search = "";
6790
7104
  url.hash = "";
6791
7105
  url.searchParams.set("c", token);
@@ -6801,6 +7115,8 @@ function ExplorePage({
6801
7115
  }, [
6802
7116
  createShareLink,
6803
7117
  pageUrl,
7118
+ panel,
7119
+ explorePath,
6804
7120
  T.copied,
6805
7121
  T.copying,
6806
7122
  T.share,
@@ -6829,12 +7145,26 @@ function ExplorePage({
6829
7145
  });
6830
7146
  return pickQueueRef.current;
6831
7147
  },
6832
- [T]
7148
+ [T, setStaged]
7149
+ );
7150
+ const removeAttachment = useCallback(
7151
+ (id) => {
7152
+ setStaged((prev) => prev.filter((entry) => entry.id !== id));
7153
+ setAttachmentNotice(null);
7154
+ },
7155
+ [setStaged]
7156
+ );
7157
+ const pinFocus = useCallback(() => {
7158
+ if (pinnedSlug !== null) setFocusProduct(pinnedSlug);
7159
+ }, [pinnedSlug, setFocusProduct]);
7160
+ const retryTurn = useCallback(() => {
7161
+ pinFocus();
7162
+ retry();
7163
+ }, [pinFocus, retry]);
7164
+ const shownError = useMemo(
7165
+ () => error !== null && pinnedSlug !== null ? productScopedError(error, T.toolBudgetScoped) : error,
7166
+ [T, error, pinnedSlug]
6833
7167
  );
6834
- const removeAttachment = useCallback((id) => {
6835
- setStaged((prev) => prev.filter((entry) => entry.id !== id));
6836
- setAttachmentNotice(null);
6837
- }, []);
6838
7168
  const submitDraft = useCallback(() => {
6839
7169
  const text = draft.trim();
6840
7170
  if (!text || overLimit || busy || !canSend) return;
@@ -6842,22 +7172,34 @@ function ExplorePage({
6842
7172
  stopSpeaking();
6843
7173
  setDraft("");
6844
7174
  stickToBottomRef.current = true;
7175
+ pinFocus();
6845
7176
  void send(text, toPayload(stagedRef.current));
6846
7177
  setStaged([]);
6847
7178
  setAttachmentNotice(null);
6848
7179
  textareaRef.current?.focus();
6849
- }, [busy, canSend, draft, overLimit, send, stopDictation]);
7180
+ }, [
7181
+ busy,
7182
+ canSend,
7183
+ draft,
7184
+ overLimit,
7185
+ pinFocus,
7186
+ send,
7187
+ setDraft,
7188
+ setStaged,
7189
+ stopDictation
7190
+ ]);
6850
7191
  const sendPrompt = useCallback(
6851
7192
  (prompt) => {
6852
7193
  if (!canSend || busy) return;
6853
7194
  stopSpeaking();
6854
7195
  setDraft("");
6855
7196
  stickToBottomRef.current = true;
7197
+ pinFocus();
6856
7198
  void send(prompt, toPayload(stagedRef.current));
6857
7199
  setStaged([]);
6858
7200
  setAttachmentNotice(null);
6859
7201
  },
6860
- [busy, canSend, send]
7202
+ [busy, canSend, pinFocus, send, setDraft, setStaged]
6861
7203
  );
6862
7204
  const handleKeyDown = useCallback(
6863
7205
  (event) => {
@@ -6879,7 +7221,7 @@ function ExplorePage({
6879
7221
  [serverCatalogRaw]
6880
7222
  );
6881
7223
  const rootStyle = {};
6882
- if (heightMode === "viewport") {
7224
+ if (viewportPage) {
6883
7225
  rootStyle["--boff-explore-offset"] = paneOffset === null ? normalizeOffset(viewportOffset) : `${paneOffset}px`;
6884
7226
  if (bottomInset > 0) {
6885
7227
  rootStyle["--boff-explore-inset"] = `${bottomInset}px`;
@@ -6892,23 +7234,29 @@ function ExplorePage({
6892
7234
  "div",
6893
7235
  {
6894
7236
  ref: rootRef,
6895
- "data-boff-explore": "page",
7237
+ "data-boff-explore": panel ? "panel" : "page",
6896
7238
  "data-phase": phase,
6897
7239
  "data-locale": activeLocale,
6898
7240
  dir: rtl ? "rtl" : void 0,
6899
7241
  className: cn(
6900
- "flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground",
6901
- heightMode === "viewport" && "boff-explore-viewport",
6902
- heightMode === "auto" && "min-h-[70vh]",
7242
+ panel ? "boff-explore-panel flex h-full min-h-0 w-full min-w-0 flex-col overflow-hidden bg-background text-foreground" : "flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground",
7243
+ viewportPage && "boff-explore-viewport",
7244
+ !panel && heightMode === "auto" && "min-h-[70vh]",
6903
7245
  className
6904
7246
  ),
6905
- style: rootStyle,
7247
+ style: panel ? void 0 : rootStyle,
6906
7248
  children: [
6907
- /* @__PURE__ */ jsx(
7249
+ panel ? null : /* @__PURE__ */ jsx(
6908
7250
  PageHead,
6909
7251
  {
6910
7252
  title: seo?.title ?? T.seoTitle,
6911
- description: seo?.description ?? (headProductName ? fill(T.seoDescriptionProduct, { product: headProductName }) : T.seoDescription),
7253
+ description: seo?.description ?? (headProductName ? fill(
7254
+ // BOFF-9796: one product's own page promises that product's answers alone, never "and every
7255
+ // other product we build". The title ("Describe a problem, get an answer | {product}") and the
7256
+ // site name already name this product only, and the og:/twitter: tags repeat these two.
7257
+ pinnedSlug === null ? T.seoDescriptionProduct : T.seoDescriptionScoped,
7258
+ { product: headProductName }
7259
+ ) : T.seoDescription),
6912
7260
  productName: seo?.title ? void 0 : headProductName ?? void 0,
6913
7261
  keywords: seo?.keywords,
6914
7262
  image: seo?.image,
@@ -6917,7 +7265,11 @@ function ExplorePage({
6917
7265
  ),
6918
7266
  /* @__PURE__ */ jsx(ProseStyles, {}),
6919
7267
  /* @__PURE__ */ jsx(ExploreStyles, {}),
6920
- bakedCatalogJson ? /* @__PURE__ */ jsx(
7268
+ panel ? /* @__PURE__ */ jsx("style", { children: `.boff-explore-panel .boff-explore-scroll { container: boff-explore-pane / size; }
7269
+ @container boff-explore-pane (width < ${toRem(WELCOME_FIT_MIN_WIDTH_PX)}) {
7270
+ .boff-explore-panel .boff-explore-scroll .boff-explore-capabilities { display: none; }
7271
+ }` }) : null,
7272
+ !panel && bakedCatalogJson ? /* @__PURE__ */ jsx(
6921
7273
  "script",
6922
7274
  {
6923
7275
  id: BAKED_CATALOG_ELEMENT_ID,
@@ -6937,7 +7289,7 @@ function ExplorePage({
6937
7289
  children: /* @__PURE__ */ jsx(Sparkles, { className: "h-4 w-4" })
6938
7290
  }
6939
7291
  ),
6940
- /* @__PURE__ */ jsx("h1", { className: "truncate text-sm font-semibold", children: resolvedTitle }),
7292
+ panel ? /* @__PURE__ */ jsx("h2", { className: "truncate text-sm font-semibold", children: resolvedTitle }) : /* @__PURE__ */ jsx("h1", { className: "truncate text-sm font-semibold", children: resolvedTitle }),
6941
7293
  focusedProductName ? /* @__PURE__ */ jsx("span", { className: "hidden shrink-0 rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground sm:inline", children: focusedProductName }) : null,
6942
7294
  /* @__PURE__ */ jsxs(
6943
7295
  Button,
@@ -7081,16 +7433,18 @@ function ExplorePage({
7081
7433
  children: showWelcome ? /* @__PURE__ */ jsx(
7082
7434
  WelcomeState,
7083
7435
  {
7436
+ heading: panel ? "h2" : "h1",
7084
7437
  strings: T,
7085
7438
  title: resolvedTitle,
7086
7439
  body: resolvedBody,
7087
7440
  prompts,
7088
- products: catalog.products,
7089
- conceptHighlights: catalog.conceptHighlights,
7441
+ products: pinnedSlug === null ? catalog.products : NO_PRODUCTS,
7442
+ conceptHighlights,
7090
7443
  focusProduct,
7091
7444
  onPrompt: sendPrompt,
7092
7445
  onFocus: setFocusProduct,
7093
- disabled: !canSend || busy
7446
+ disabled: !canSend || busy,
7447
+ productScoped: pinnedSlug !== null
7094
7448
  }
7095
7449
  ) : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
7096
7450
  (message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { strings: T, message }, message.id) : /* @__PURE__ */ jsx(
@@ -7167,7 +7521,14 @@ function ExplorePage({
7167
7521
  submitDraft();
7168
7522
  },
7169
7523
  children: [
7170
- error ? /* @__PURE__ */ jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
7524
+ shownError ? /* @__PURE__ */ jsx(
7525
+ ErrorBanner,
7526
+ {
7527
+ error: shownError,
7528
+ onRetry: retryTurn,
7529
+ onReset: reset
7530
+ }
7531
+ ) : null,
7171
7532
  staged.length > 0 ? /* @__PURE__ */ jsx(
7172
7533
  "ul",
7173
7534
  {
@@ -7253,9 +7614,14 @@ function ExplorePage({
7253
7614
  composingRef.current = false;
7254
7615
  },
7255
7616
  "aria-label": "Ask a question",
7256
- placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
7257
- product: focusedProductName
7258
- }) : T.placeholder,
7617
+ placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(
7618
+ // BOFF-9796: one product's own assistant keeps this field exactly as every site has it, its
7619
+ // classes and its fit to the draft alone; only its placeholder says less. On a phone the
7620
+ // field is one line tall and cuts off a placeholder that wraps: in English, "Ask about
7621
+ // {product}…" fits that line at 320px and wider.
7622
+ pinnedSlug === null ? T.placeholderProduct : T.placeholderScoped,
7623
+ { product: focusedProductName }
7624
+ ) : T.placeholder,
7259
7625
  className: "max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-base shadow-none focus-visible:ring-0 sm:text-sm"
7260
7626
  }
7261
7627
  ),