@burdenoff/website-sdk 2026.829.5 → 2026.829.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useMemo, useContext, useState, useCallback, useLayoutEffect, useRef, useEffect } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { Instagram, Youtube, Facebook, Github, Linkedin, Twitter, Mail, Phone, MapPin, Clock, Send, CheckCircle, Upload, Globe, ChevronDown, Search, Rocket, ArrowRight, Download, Sparkles, RotateCcw, Link2, History, Trash2, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, FileText, ExternalLink } from 'lucide-react';
4
+ import { Instagram, Youtube, Facebook, Github, Linkedin, Twitter, Mail, Phone, MapPin, Clock, Send, CheckCircle, Upload, Globe, ChevronDown, Search, Rocket, ArrowRight, Download, Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, FileText, ExternalLink } from 'lucide-react';
5
5
  import ReCAPTCHA4 from 'react-google-recaptcha';
6
6
  import { toast } from 'sonner';
7
7
  import { Helmet } from 'react-helmet-async';
@@ -4768,6 +4768,12 @@ var EN = {
4768
4768
  disclaimerShort: "Grounded in our docs \u2014 check anything important.",
4769
4769
  dictate: "Dictate your question",
4770
4770
  stopDictating: "Stop dictating",
4771
+ attach: "Attach files",
4772
+ attachHint: "Up to {{max}} files, {{size}} MB each",
4773
+ removeAttachment: "Remove {{name}}",
4774
+ attachmentNameOnly: "name and type only",
4775
+ attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
4776
+ attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
4771
4777
  noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
4772
4778
  askHuman: "ask a human",
4773
4779
  prevSuggestion: "Previous suggestion",
@@ -4810,6 +4816,12 @@ var ZH = {
4810
4816
  disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
4811
4817
  dictate: "\u8BED\u97F3\u8F93\u5165",
4812
4818
  stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
4819
+ attach: "\u6DFB\u52A0\u6587\u4EF6",
4820
+ attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
4821
+ removeAttachment: "\u79FB\u9664 {{name}}",
4822
+ attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
4823
+ attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
4824
+ attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
4813
4825
  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",
4814
4826
  askHuman: "\u8054\u7CFB\u6211\u4EEC",
4815
4827
  prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
@@ -4848,6 +4860,12 @@ var HI = {
4848
4860
  disclaimerShort: "\u092F\u0939 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948 \u2014 \u092E\u0939\u0924\u094D\u0935\u092A\u0942\u0930\u094D\u0923 \u092C\u093E\u0924\u0947\u0902 \u091C\u093C\u0930\u0942\u0930 \u091C\u093E\u0901\u091A \u0932\u0947\u0902\u0964",
4849
4861
  dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
4850
4862
  stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
4863
+ attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
4864
+ attachHint: "\u0905\u0927\u093F\u0915\u0924\u092E {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902, \u092A\u094D\u0930\u0924\u094D\u092F\u0947\u0915 {{size}} MB \u0924\u0915",
4865
+ removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
4866
+ attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
4867
+ attachmentTooLarge: "{{name}} {{size}} MB \u0938\u0947 \u092C\u0921\u093C\u0940 \u0939\u0948, \u0907\u0938\u0932\u093F\u090F \u091C\u094B\u0921\u093C\u0940 \u0928\u0939\u0940\u0902 \u0917\u0908\u0964",
4868
+ 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",
4851
4869
  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",
4852
4870
  askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
4853
4871
  prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
@@ -4890,6 +4908,12 @@ var ES = {
4890
4908
  disclaimerShort: "Basado en nuestra documentaci\xF3n: comprueba cualquier dato importante.",
4891
4909
  dictate: "Dictar tu pregunta",
4892
4910
  stopDictating: "Dejar de dictar",
4911
+ attach: "Adjuntar archivos",
4912
+ attachHint: "Hasta {{max}} archivos, {{size}} MB cada uno",
4913
+ removeAttachment: "Quitar {{name}}",
4914
+ attachmentNameOnly: "solo nombre y tipo",
4915
+ attachmentTooLarge: "{{name}} supera los {{size}} MB y no se adjunt\xF3.",
4916
+ attachmentTooMany: "Solo se pueden adjuntar {{max}} archivos, as\xED que se omiti\xF3 {{name}}.",
4893
4917
  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",
4894
4918
  askHuman: "habla con una persona",
4895
4919
  prevSuggestion: "Sugerencia anterior",
@@ -4932,6 +4956,12 @@ var AR = {
4932
4956
  disclaimerShort: "\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627 \u2014 \u062A\u062D\u0642\u0651\u0642 \u0645\u0646 \u0623\u064A \u0645\u0639\u0644\u0648\u0645\u0629 \u0645\u0647\u0645\u0629.",
4933
4957
  dictate: "\u0623\u0645\u0644\u0650 \u0633\u0624\u0627\u0644\u0643",
4934
4958
  stopDictating: "\u0625\u064A\u0642\u0627\u0641 \u0627\u0644\u0625\u0645\u0644\u0627\u0621",
4959
+ attach: "\u0625\u0631\u0641\u0627\u0642 \u0645\u0644\u0641\u0627\u062A",
4960
+ attachHint: "\u062D\u062A\u0649 {{max}} \u0645\u0644\u0641\u0627\u062A\u060C \u0628\u062D\u062F \u0623\u0642\u0635\u0649 {{size}} \u0645\u064A\u063A\u0627\u0628\u0627\u064A\u062A \u0644\u0643\u0644 \u0645\u0644\u0641",
4961
+ removeAttachment: "\u0625\u0632\u0627\u0644\u0629 {{name}}",
4962
+ attachmentNameOnly: "\u0627\u0644\u0627\u0633\u0645 \u0648\u0627\u0644\u0646\u0648\u0639 \u0641\u0642\u0637",
4963
+ attachmentTooLarge: "{{name}} \u0623\u0643\u0628\u0631 \u0645\u0646 {{size}} \u0645\u064A\u063A\u0627\u0628\u0627\u064A\u062A \u0648\u0644\u0645 \u064A\u062A\u0645 \u0625\u0631\u0641\u0627\u0642\u0647.",
4964
+ 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}}.",
4935
4965
  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",
4936
4966
  askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
4937
4967
  prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
@@ -4974,6 +5004,12 @@ var TA = {
4974
5004
  disclaimerShort: "\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\u0BA4\u0BC1 \u2014 \u0BAE\u0BC1\u0B95\u0BCD\u0B95\u0BBF\u0BAF\u0BAE\u0BBE\u0BA9\u0BA4\u0BC8\u0B9A\u0BCD \u0B9A\u0BB0\u0BBF\u0BAA\u0BBE\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD.",
4975
5005
  dictate: "\u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BC7\u0BB3\u0BCD\u0BB5\u0BBF\u0BAF\u0BC8\u0BAA\u0BCD \u0BAA\u0BC7\u0B9A\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
4976
5006
  stopDictating: "\u0BAA\u0BC7\u0B9A\u0BC1\u0BB5\u0BA4\u0BC8 \u0BA8\u0BBF\u0BB1\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1",
5007
+ attach: "\u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95",
5008
+ attachHint: "\u0B85\u0BA4\u0BBF\u0B95\u0BAA\u0B9F\u0BCD\u0B9A\u0BAE\u0BCD {{max}} \u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD, \u0B92\u0BB5\u0BCD\u0BB5\u0BCA\u0BA9\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD {{size}} MB \u0BB5\u0BB0\u0BC8",
5009
+ removeAttachment: "{{name}} \u0B85\u0B95\u0BB1\u0BCD\u0BB1\u0BC1",
5010
+ attachmentNameOnly: "\u0BAA\u0BC6\u0BAF\u0BB0\u0BC1\u0BAE\u0BCD \u0BB5\u0B95\u0BC8\u0BAF\u0BC1\u0BAE\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD",
5011
+ attachmentTooLarge: "{{name}} {{size}} MB-\u0B90 \u0BB5\u0BBF\u0B9F \u0BAA\u0BC6\u0BB0\u0BBF\u0BAF\u0BA4\u0BC1, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
5012
+ 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.",
4977
5013
  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",
4978
5014
  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",
4979
5015
  prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
@@ -5222,6 +5258,12 @@ var EXPLORE_MESSAGE_FIELDS = (
5222
5258
  }
5223
5259
  followUps
5224
5260
  answered
5261
+ attachments {
5262
+ name
5263
+ mimeType
5264
+ size
5265
+ textExtracted
5266
+ }
5225
5267
  errorCode
5226
5268
  createdAt
5227
5269
  completedAt
@@ -5307,6 +5349,16 @@ var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
5307
5349
  }
5308
5350
  `
5309
5351
  );
5352
+ var EXPLORE_SHARED_CONVERSATION_QUERY = (
5353
+ /* GraphQL */
5354
+ `
5355
+ query ExploreSharedConversation($shareToken: String!) {
5356
+ exploreSharedConversation(shareToken: $shareToken) {
5357
+ ${EXPLORE_MESSAGE_FIELDS}
5358
+ }
5359
+ }
5360
+ `
5361
+ );
5310
5362
 
5311
5363
  // src/data/products.ts
5312
5364
  var ECOSYSTEM_PRODUCTS = [
@@ -5757,6 +5809,14 @@ function readPersisted(key) {
5757
5809
  return null;
5758
5810
  }
5759
5811
  }
5812
+ function readShareToken() {
5813
+ if (typeof window === "undefined") return null;
5814
+ try {
5815
+ return new URL(window.location.href).searchParams.get("c");
5816
+ } catch {
5817
+ return null;
5818
+ }
5819
+ }
5760
5820
  function visibleText(message) {
5761
5821
  return message.content || message.partialContent || "";
5762
5822
  }
@@ -5795,10 +5855,18 @@ function useExploreChat(options = {}) {
5795
5855
  const pollGenerationRef = useRef(0);
5796
5856
  const pollTimerRef = useRef(null);
5797
5857
  const conversationTokenRef = useRef(null);
5858
+ const shareTokenRef = useRef(void 0);
5859
+ if (shareTokenRef.current === void 0) {
5860
+ shareTokenRef.current = readShareToken();
5861
+ }
5862
+ const isSharedView = shareTokenRef.current !== null;
5798
5863
  const catalogRef = useRef(fallbackCatalog);
5799
5864
  const turnCountRef = useRef(0);
5800
5865
  const focusProductRef = useRef(null);
5801
5866
  const lastSentTextRef = useRef(null);
5867
+ const lastSentAttachmentsRef = useRef(
5868
+ []
5869
+ );
5802
5870
  const inFlightRef = useRef(false);
5803
5871
  catalogRef.current = catalog;
5804
5872
  const clearPollTimer = useCallback(() => {
@@ -5823,6 +5891,43 @@ function useExploreChat(options = {}) {
5823
5891
  };
5824
5892
  }, []);
5825
5893
  useEffect(() => {
5894
+ const shareToken = shareTokenRef.current;
5895
+ if (!shareToken) return;
5896
+ let cancelled = false;
5897
+ setHydrated(true);
5898
+ void client.query(
5899
+ EXPLORE_SHARED_CONVERSATION_QUERY,
5900
+ { shareToken },
5901
+ { cache: false }
5902
+ ).then((res) => {
5903
+ if (cancelled || !mountedRef.current) return;
5904
+ const shared = res?.data?.exploreSharedConversation;
5905
+ if (shared && shared.length > 0) {
5906
+ setMessages(shared);
5907
+ return;
5908
+ }
5909
+ setError({
5910
+ kind: "unknown",
5911
+ code: "SHARE_NOT_FOUND",
5912
+ message: "That shared conversation could not be found. The link may have expired.",
5913
+ // Nothing to retry: a bad token will stay bad.
5914
+ retryable: false
5915
+ });
5916
+ }).catch(() => {
5917
+ if (cancelled || !mountedRef.current) return;
5918
+ setError({
5919
+ kind: "unknown",
5920
+ code: "SHARE_NOT_FOUND",
5921
+ message: "That shared conversation could not be loaded.",
5922
+ retryable: true
5923
+ });
5924
+ });
5925
+ return () => {
5926
+ cancelled = true;
5927
+ };
5928
+ }, [client]);
5929
+ useEffect(() => {
5930
+ if (shareTokenRef.current !== null) return;
5826
5931
  if (!persist) {
5827
5932
  setHydrated(true);
5828
5933
  return;
@@ -5990,7 +6095,7 @@ function useExploreChat(options = {}) {
5990
6095
  [client, pollIntervalMs, pollTimeoutMs]
5991
6096
  );
5992
6097
  const submit = useCallback(
5993
- async (text, optimisticId, captchaAttempt) => {
6098
+ async (text, optimisticId, captchaAttempt, attachments) => {
5994
6099
  const activeCatalog = catalogRef.current;
5995
6100
  let recaptchaToken;
5996
6101
  if (activeCatalog.captchaRequired && activeCatalog.recaptchaSiteKey) {
@@ -6008,7 +6113,8 @@ function useExploreChat(options = {}) {
6008
6113
  ...focusProductRef.current || productSlug ? { productSlug: focusProductRef.current ?? productSlug } : {},
6009
6114
  ...recaptchaToken ? { recaptchaToken } : {},
6010
6115
  ...locale ? { locale } : {},
6011
- ...pageUrl ? { pageUrl } : {}
6116
+ ...pageUrl ? { pageUrl } : {},
6117
+ ...attachments.length > 0 ? { attachments: [...attachments] } : {}
6012
6118
  };
6013
6119
  const res = await client.mutate(
6014
6120
  SEND_EXPLORE_MESSAGE_MUTATION,
@@ -6022,7 +6128,7 @@ function useExploreChat(options = {}) {
6022
6128
  const code = typeof first?.extensions?.code === "string" ? first.extensions.code : void 0;
6023
6129
  const classified = classifyExploreError(code, first?.message);
6024
6130
  if (classified.kind === "captcha" && captchaAttempt === 0) {
6025
- await submit(text, optimisticId, 1);
6131
+ await submit(text, optimisticId, 1, attachments);
6026
6132
  return;
6027
6133
  }
6028
6134
  inFlightRef.current = false;
@@ -6059,7 +6165,7 @@ function useExploreChat(options = {}) {
6059
6165
  [client, locale, pageUrl, productSlug, startPolling]
6060
6166
  );
6061
6167
  const send = useCallback(
6062
- async (message) => {
6168
+ async (message, attachments = []) => {
6063
6169
  const text = message.trim();
6064
6170
  if (!text) return;
6065
6171
  if (inFlightRef.current) return;
@@ -6089,6 +6195,7 @@ function useExploreChat(options = {}) {
6089
6195
  }
6090
6196
  inFlightRef.current = true;
6091
6197
  lastSentTextRef.current = text;
6198
+ lastSentAttachmentsRef.current = attachments;
6092
6199
  setError(null);
6093
6200
  setPhase("sending");
6094
6201
  cancelPolling();
@@ -6111,7 +6218,7 @@ function useExploreChat(options = {}) {
6111
6218
  setTurnCount(turnCountRef.current);
6112
6219
  onSend?.(text);
6113
6220
  try {
6114
- await submit(text, optimistic.id, 0);
6221
+ await submit(text, optimistic.id, 0, attachments);
6115
6222
  } catch (err) {
6116
6223
  if (!mountedRef.current) return;
6117
6224
  console.error("[WebSDK] Explore send failed", err);
@@ -6160,7 +6267,7 @@ function useExploreChat(options = {}) {
6160
6267
  });
6161
6268
  turnCountRef.current = Math.max(0, turnCountRef.current - 1);
6162
6269
  setTurnCount(turnCountRef.current);
6163
- void send(text);
6270
+ void send(text, lastSentAttachmentsRef.current);
6164
6271
  }, [cancelPolling, send]);
6165
6272
  const reset = useCallback(() => {
6166
6273
  setArchive(
@@ -6174,6 +6281,7 @@ function useExploreChat(options = {}) {
6174
6281
  inFlightRef.current = false;
6175
6282
  conversationTokenRef.current = null;
6176
6283
  lastSentTextRef.current = null;
6284
+ lastSentAttachmentsRef.current = [];
6177
6285
  turnCountRef.current = 0;
6178
6286
  setTurnCount(0);
6179
6287
  setMessages([]);
@@ -6282,7 +6390,8 @@ function useExploreChat(options = {}) {
6282
6390
  deleteConversation,
6283
6391
  clearHistory,
6284
6392
  recordClick,
6285
- createShareLink
6393
+ createShareLink,
6394
+ isSharedView
6286
6395
  };
6287
6396
  }
6288
6397
  var optimisticCounter = 0;
@@ -6541,6 +6650,145 @@ function useSwipe({
6541
6650
  }, []);
6542
6651
  return { onPointerDown, onPointerUp, onPointerCancel };
6543
6652
  }
6653
+
6654
+ // src/utils/explore-attachments.ts
6655
+ var MAX_ATTACHMENTS = 5;
6656
+ var MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
6657
+ var MAX_TEXT_PER_ATTACHMENT = 2e4;
6658
+ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
6659
+ "txt",
6660
+ "md",
6661
+ "markdown",
6662
+ "csv",
6663
+ "tsv",
6664
+ "json",
6665
+ "jsonl",
6666
+ "yaml",
6667
+ "yml",
6668
+ "toml",
6669
+ "ini",
6670
+ "cfg",
6671
+ "conf",
6672
+ "env",
6673
+ "log",
6674
+ "sql",
6675
+ "graphql",
6676
+ "gql",
6677
+ "html",
6678
+ "htm",
6679
+ "xml",
6680
+ "svg",
6681
+ "css",
6682
+ "scss",
6683
+ "js",
6684
+ "jsx",
6685
+ "mjs",
6686
+ "cjs",
6687
+ "ts",
6688
+ "tsx",
6689
+ "py",
6690
+ "rb",
6691
+ "go",
6692
+ "rs",
6693
+ "java",
6694
+ "kt",
6695
+ "c",
6696
+ "h",
6697
+ "cpp",
6698
+ "cs",
6699
+ "php",
6700
+ "sh",
6701
+ "bash",
6702
+ "zsh",
6703
+ "ps1",
6704
+ "dockerfile",
6705
+ "tf",
6706
+ "tfvars"
6707
+ ]);
6708
+ function isTextualMimeType(mimeType) {
6709
+ if (mimeType.startsWith("text/")) return true;
6710
+ return mimeType === "application/json" || mimeType === "application/xml" || mimeType === "application/yaml" || mimeType === "application/x-yaml" || mimeType === "application/javascript" || mimeType === "application/graphql" || mimeType.endsWith("+json") || mimeType.endsWith("+xml");
6711
+ }
6712
+ function extensionOf(name) {
6713
+ const dot = name.lastIndexOf(".");
6714
+ if (dot <= 0 || dot === name.length - 1) return "";
6715
+ return name.slice(dot + 1).toLowerCase();
6716
+ }
6717
+ function looksTextual(name, mimeType) {
6718
+ if (isTextualMimeType(mimeType)) return true;
6719
+ return TEXT_EXTENSIONS.has(extensionOf(name));
6720
+ }
6721
+ function isDecodedTextUsable(decoded) {
6722
+ if (decoded.length === 0) return false;
6723
+ if (decoded.includes("\0")) return false;
6724
+ let replacements = 0;
6725
+ for (const char of decoded) if (char === "\uFFFD") replacements += 1;
6726
+ return replacements / decoded.length < 0.1;
6727
+ }
6728
+ function formatBytes(bytes) {
6729
+ if (bytes < 1024) return `${bytes} B`;
6730
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
6731
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
6732
+ }
6733
+ var counter = 0;
6734
+ function nextId() {
6735
+ counter += 1;
6736
+ return `att-${counter}`;
6737
+ }
6738
+ async function readArrayBuffer(blob) {
6739
+ if (typeof blob.arrayBuffer === "function") return blob.arrayBuffer();
6740
+ return new Promise((resolve, reject) => {
6741
+ const reader = new FileReader();
6742
+ reader.onload = () => resolve(reader.result);
6743
+ reader.onerror = () => reject(reader.error ?? new Error("file read failed"));
6744
+ reader.readAsArrayBuffer(blob);
6745
+ });
6746
+ }
6747
+ async function readTextPrefix(file) {
6748
+ try {
6749
+ const slice = file.slice(0, MAX_TEXT_PER_ATTACHMENT);
6750
+ const buffer = await readArrayBuffer(slice);
6751
+ const decoded = new TextDecoder("utf-8").decode(buffer);
6752
+ return isDecodedTextUsable(decoded) ? decoded : null;
6753
+ } catch {
6754
+ return null;
6755
+ }
6756
+ }
6757
+ async function stageFiles(files, alreadyStaged) {
6758
+ const accepted = [];
6759
+ const rejected = [];
6760
+ let slots = MAX_ATTACHMENTS - alreadyStaged.length;
6761
+ for (const file of files) {
6762
+ if (slots <= 0) {
6763
+ rejected.push({ name: file.name, reason: "too-many" });
6764
+ continue;
6765
+ }
6766
+ if (file.size > MAX_ATTACHMENT_BYTES) {
6767
+ rejected.push({ name: file.name, reason: "too-large" });
6768
+ continue;
6769
+ }
6770
+ const mimeType = file.type || "application/octet-stream";
6771
+ const textContent = looksTextual(file.name, mimeType) ? await readTextPrefix(file) : null;
6772
+ accepted.push({
6773
+ id: nextId(),
6774
+ name: file.name,
6775
+ mimeType,
6776
+ size: file.size,
6777
+ textContent,
6778
+ textExtracted: textContent !== null
6779
+ });
6780
+ slots -= 1;
6781
+ }
6782
+ return { accepted, rejected };
6783
+ }
6784
+ function toPayload(staged) {
6785
+ return staged.map(({ name, mimeType, size, textContent }) => ({
6786
+ name,
6787
+ mimeType,
6788
+ size,
6789
+ textContent
6790
+ }));
6791
+ }
6544
6792
  var EXPLORE_CSS = `
6545
6793
  @keyframes boff-explore-pulse {
6546
6794
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
@@ -6889,15 +7137,45 @@ function ThinkingIndicator({ activity }) {
6889
7137
  }
6890
7138
  );
6891
7139
  }
6892
- function UserBubble({ message }) {
6893
- return /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
6894
- "div",
6895
- {
6896
- "data-boff-explore": "user",
6897
- className: "max-w-[85%] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-sm leading-relaxed text-primary-foreground shadow-sm",
6898
- children: message.content
6899
- }
6900
- ) });
7140
+ function UserBubble({
7141
+ strings: T,
7142
+ message
7143
+ }) {
7144
+ const attachments = message.attachments ?? [];
7145
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [
7146
+ /* @__PURE__ */ jsx(
7147
+ "div",
7148
+ {
7149
+ "data-boff-explore": "user",
7150
+ className: "max-w-[85%] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-sm leading-relaxed text-primary-foreground shadow-sm",
7151
+ children: message.content
7152
+ }
7153
+ ),
7154
+ attachments.length > 0 ? /* @__PURE__ */ jsx(
7155
+ "ul",
7156
+ {
7157
+ "data-boff-explore": "user-attachments",
7158
+ className: "flex max-w-[85%] flex-wrap justify-end gap-1.5",
7159
+ children: attachments.map((attachment) => /* @__PURE__ */ jsxs(
7160
+ "li",
7161
+ {
7162
+ "data-boff-explore": "user-attachment",
7163
+ "data-text-extracted": attachment.textExtracted ? "true" : "false",
7164
+ className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 px-2.5 py-1 text-xs text-muted-foreground",
7165
+ children: [
7166
+ /* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0" }),
7167
+ /* @__PURE__ */ jsx("span", { className: "truncate", title: attachment.name, children: attachment.name }),
7168
+ attachment.textExtracted ? null : /* @__PURE__ */ jsxs("span", { className: "shrink-0", children: [
7169
+ "\xB7 ",
7170
+ T.attachmentNameOnly
7171
+ ] })
7172
+ ]
7173
+ },
7174
+ `${attachment.name}-${attachment.size}`
7175
+ ))
7176
+ }
7177
+ ) : null
7178
+ ] });
6901
7179
  }
6902
7180
  function AssistantBubble({
6903
7181
  strings: T,
@@ -7396,7 +7674,8 @@ function ExplorePage({
7396
7674
  deleteConversation,
7397
7675
  clearHistory,
7398
7676
  recordClick,
7399
- createShareLink
7677
+ createShareLink,
7678
+ isSharedView
7400
7679
  } = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
7401
7680
  const [draft, setDraft] = useState("");
7402
7681
  const textareaRef = useRef(null);
@@ -7422,6 +7701,11 @@ function ExplorePage({
7422
7701
  const T = useMemo(() => exploreStrings(activeLocale), [activeLocale]);
7423
7702
  const rtl = isRtlLocale(activeLocale);
7424
7703
  const [disclaimerOpen, setDisclaimerOpen] = useState(false);
7704
+ const [staged, setStaged] = useState([]);
7705
+ const [attachmentNotice, setAttachmentNotice] = useState(null);
7706
+ const fileInputRef = useRef(null);
7707
+ const stagedRef = useRef([]);
7708
+ stagedRef.current = staged;
7425
7709
  const [shareLabel, setShareLabel] = useState("Share");
7426
7710
  const [shareUrl, setShareUrl] = useState(null);
7427
7711
  const scrollRef = useRef(null);
@@ -7498,13 +7782,40 @@ function ExplorePage({
7498
7782
  setShareLabel("Share");
7499
7783
  }
7500
7784
  }, [createShareLink, pageUrl]);
7785
+ const handleFilesPicked = useCallback(
7786
+ async (picked) => {
7787
+ if (!picked || picked.length === 0) return;
7788
+ const { accepted, rejected } = await stageFiles(
7789
+ Array.from(picked),
7790
+ stagedRef.current
7791
+ );
7792
+ setStaged((prev) => [...prev, ...accepted]);
7793
+ const first = rejected[0];
7794
+ setAttachmentNotice(
7795
+ first ? first.reason === "too-large" ? fill(T.attachmentTooLarge, {
7796
+ name: first.name,
7797
+ size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
7798
+ }) : fill(T.attachmentTooMany, {
7799
+ name: first.name,
7800
+ max: String(MAX_ATTACHMENTS)
7801
+ }) : null
7802
+ );
7803
+ },
7804
+ [T]
7805
+ );
7806
+ const removeAttachment = useCallback((id) => {
7807
+ setStaged((prev) => prev.filter((entry) => entry.id !== id));
7808
+ setAttachmentNotice(null);
7809
+ }, []);
7501
7810
  const submitDraft = useCallback(() => {
7502
7811
  const text = draft.trim();
7503
7812
  if (!text || overLimit || busy || !canSend) return;
7504
7813
  stopDictation();
7505
7814
  setDraft("");
7506
7815
  stickToBottomRef.current = true;
7507
- void send(text);
7816
+ void send(text, toPayload(stagedRef.current));
7817
+ setStaged([]);
7818
+ setAttachmentNotice(null);
7508
7819
  textareaRef.current?.focus();
7509
7820
  }, [busy, canSend, draft, overLimit, send, stopDictation]);
7510
7821
  const sendPrompt = useCallback(
@@ -7512,7 +7823,9 @@ function ExplorePage({
7512
7823
  if (!canSend || busy) return;
7513
7824
  setDraft("");
7514
7825
  stickToBottomRef.current = true;
7515
- void send(prompt);
7826
+ void send(prompt, toPayload(stagedRef.current));
7827
+ setStaged([]);
7828
+ setAttachmentNotice(null);
7516
7829
  },
7517
7830
  [busy, canSend, send]
7518
7831
  );
@@ -7525,7 +7838,9 @@ function ExplorePage({
7525
7838
  },
7526
7839
  [submitDraft]
7527
7840
  );
7528
- const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled;
7841
+ const composerDisabled = phase === "limited" || phase === "disabled" || !catalog.enabled || // A share token grants read access only — the server would reject a send anyway, so
7842
+ // disable it here rather than letting the visitor type into a dead composer.
7843
+ isSharedView;
7529
7844
  const captchaOn = Boolean(
7530
7845
  catalog.captchaRequired && catalog.recaptchaSiteKey
7531
7846
  );
@@ -7719,7 +8034,7 @@ function ExplorePage({
7719
8034
  disabled: !canSend || busy
7720
8035
  }
7721
8036
  ) : /* @__PURE__ */ jsx("div", { className: "mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6", children: messages.map(
7722
- (message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { message }, message.id) : /* @__PURE__ */ jsx(
8037
+ (message) => message.role === "USER" ? /* @__PURE__ */ jsx(UserBubble, { strings: T, message }, message.id) : /* @__PURE__ */ jsx(
7723
8038
  AssistantBubble,
7724
8039
  {
7725
8040
  strings: T,
@@ -7743,6 +8058,33 @@ function ExplorePage({
7743
8058
  captchaOn
7744
8059
  }
7745
8060
  ),
8061
+ isSharedView ? /* @__PURE__ */ jsxs(
8062
+ "div",
8063
+ {
8064
+ "data-boff-explore": "shared-banner",
8065
+ className: "mx-auto flex w-full max-w-3xl items-center gap-2 px-4 pb-2 text-xs text-muted-foreground",
8066
+ children: [
8067
+ /* @__PURE__ */ jsx(Link2, { className: "h-3.5 w-3.5 shrink-0" }),
8068
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: "You are viewing a shared conversation. Start your own to ask a question." }),
8069
+ /* @__PURE__ */ jsx(
8070
+ "button",
8071
+ {
8072
+ type: "button",
8073
+ "data-boff-explore": "shared-start-own",
8074
+ onClick: () => {
8075
+ if (typeof window !== "undefined") {
8076
+ const url = new URL(window.location.href);
8077
+ url.searchParams.delete("c");
8078
+ window.location.href = url.toString();
8079
+ }
8080
+ },
8081
+ className: "shrink-0 underline underline-offset-2 hover:text-foreground",
8082
+ children: "New chat"
8083
+ }
8084
+ )
8085
+ ]
8086
+ }
8087
+ ) : null,
7746
8088
  /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md", children: /* @__PURE__ */ jsxs(
7747
8089
  "form",
7748
8090
  {
@@ -7754,6 +8096,51 @@ function ExplorePage({
7754
8096
  },
7755
8097
  children: [
7756
8098
  error ? /* @__PURE__ */ jsx(ErrorBanner, { error, onRetry: retry, onReset: reset }) : null,
8099
+ staged.length > 0 ? /* @__PURE__ */ jsx(
8100
+ "ul",
8101
+ {
8102
+ "data-boff-explore": "attachments",
8103
+ className: "mb-2 flex flex-wrap gap-1.5",
8104
+ "aria-label": T.attach,
8105
+ children: staged.map((entry) => /* @__PURE__ */ jsxs(
8106
+ "li",
8107
+ {
8108
+ "data-boff-explore": "attachment",
8109
+ "data-text-extracted": entry.textExtracted ? "true" : "false",
8110
+ className: "flex max-w-full items-center gap-1.5 rounded-full border border-border bg-muted/60 py-1 pl-2.5 pr-1 text-xs",
8111
+ children: [
8112
+ /* @__PURE__ */ jsx(Paperclip, { className: "h-3 w-3 shrink-0 text-muted-foreground" }),
8113
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: entry.name, children: entry.name }),
8114
+ /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-muted-foreground", children: [
8115
+ formatBytes(entry.size),
8116
+ entry.textExtracted ? "" : ` \xB7 ${T.attachmentNameOnly}`
8117
+ ] }),
8118
+ /* @__PURE__ */ jsx(
8119
+ "button",
8120
+ {
8121
+ type: "button",
8122
+ "data-boff-explore": "attachment-remove",
8123
+ onClick: () => removeAttachment(entry.id),
8124
+ "aria-label": fill(T.removeAttachment, { name: entry.name }),
8125
+ className: "ml-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-background hover:text-foreground",
8126
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
8127
+ }
8128
+ )
8129
+ ]
8130
+ },
8131
+ entry.id
8132
+ ))
8133
+ }
8134
+ ) : null,
8135
+ attachmentNotice !== null ? /* @__PURE__ */ jsx(
8136
+ "p",
8137
+ {
8138
+ "data-boff-explore": "attachment-notice",
8139
+ role: "status",
8140
+ className: "mb-2 text-xs text-destructive",
8141
+ children: attachmentNotice
8142
+ }
8143
+ ) : null,
7757
8144
  /* @__PURE__ */ jsxs(
7758
8145
  "div",
7759
8146
  {
@@ -7782,7 +8169,37 @@ function ExplorePage({
7782
8169
  placeholder: composerDisabled ? phase === "limited" ? "Message limit reached \u2014 please try again later" : "Explore is unavailable right now" : focusedProductName ? fill(T.placeholderProduct, {
7783
8170
  product: focusedProductName
7784
8171
  }) : T.placeholder,
7785
- 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-sm shadow-none focus-visible:ring-0 md:text-sm"
8172
+ 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"
8173
+ }
8174
+ ),
8175
+ /* @__PURE__ */ jsx(
8176
+ "input",
8177
+ {
8178
+ ref: fileInputRef,
8179
+ type: "file",
8180
+ multiple: true,
8181
+ className: "hidden",
8182
+ onChange: (event) => {
8183
+ void handleFilesPicked(event.target.files);
8184
+ event.target.value = "";
8185
+ }
8186
+ }
8187
+ ),
8188
+ /* @__PURE__ */ jsx(
8189
+ Button,
8190
+ {
8191
+ "data-boff-explore": "attach",
8192
+ type: "button",
8193
+ size: "icon",
8194
+ variant: "ghost",
8195
+ disabled: composerDisabled || staged.length >= MAX_ATTACHMENTS,
8196
+ "aria-label": T.attach,
8197
+ title: `${T.attach} \u2014 ${fill(T.attachHint, {
8198
+ max: String(MAX_ATTACHMENTS),
8199
+ size: String(MAX_ATTACHMENT_BYTES / (1024 * 1024))
8200
+ })}`,
8201
+ onClick: () => fileInputRef.current?.click(),
8202
+ children: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
7786
8203
  }
7787
8204
  ),
7788
8205
  speech.supported ? /* @__PURE__ */ jsx(
@@ -9767,7 +10184,7 @@ function ChangelogPage(props) {
9767
10184
  }
9768
10185
 
9769
10186
  // src/content/utils.ts
9770
- function formatBytes(bytes) {
10187
+ function formatBytes2(bytes) {
9771
10188
  if (bytes == null) return "";
9772
10189
  if (bytes < 1024) return `${bytes} B`;
9773
10190
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
@@ -9888,7 +10305,7 @@ function PressKitLightbox({
9888
10305
  }, [asset, onClose]);
9889
10306
  if (!asset) return null;
9890
10307
  const ext = (asset.mimeType || "file").split("/").pop()?.toUpperCase() || "FILE";
9891
- const size = formatBytes(asset.fileSize);
10308
+ const size = formatBytes2(asset.fileSize);
9892
10309
  return /* @__PURE__ */ jsx(
9893
10310
  "div",
9894
10311
  {
@@ -9997,7 +10414,7 @@ function AssetCard({
9997
10414
  day: "numeric"
9998
10415
  }) : "";
9999
10416
  const ext = (asset.mimeType || "file").split("/").pop()?.toUpperCase() || "FILE";
10000
- const size = formatBytes(asset.fileSize);
10417
+ const size = formatBytes2(asset.fileSize);
10001
10418
  const [imgError, setImgError] = useState(false);
10002
10419
  const thumb = asset.thumbnailUrl && !imgError ? /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsx(
10003
10420
  "img",
@@ -10501,7 +10918,7 @@ function ContractsPage(props) {
10501
10918
  ] }) }),
10502
10919
  /* @__PURE__ */ jsx("section", { className: "max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12", children: loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-20", children: /* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" }) }) : error ? /* @__PURE__ */ jsx("div", { className: "text-center py-16", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: error }) }) : contracts.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-center py-16", children: /* @__PURE__ */ jsx("p", { className: "text-base text-muted-foreground", children: "No contracts are available yet." }) }) : /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border rounded-xl border border-border overflow-hidden bg-card", children: contracts.map((c) => {
10503
10920
  const ext = fileExt(c);
10504
- const size = formatBytes(c.fileSize);
10921
+ const size = formatBytes2(c.fileSize);
10505
10922
  return /* @__PURE__ */ jsxs(
10506
10923
  "li",
10507
10924
  {