@cimplify/sdk 0.97.0 → 0.98.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkHKN3YG76_js = require('./chunk-HKN3YG76.js');
4
+ var chunkQPRI2NII_js = require('./chunk-QPRI2NII.js');
5
5
  var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
6
6
  var chunkW5PH7SPK_js = require('./chunk-W5PH7SPK.js');
7
7
  var chunkVEOAMBEX_js = require('./chunk-VEOAMBEX.js');
@@ -1298,7 +1298,7 @@ function CimplifyProvider({
1298
1298
  const apiCredentials = resolvedClient.getCredentialsMode() === "include" ? "use-credentials" : "anonymous";
1299
1299
  preconnectOrigin(resolvedClient.getBaseUrl(), apiCredentials);
1300
1300
  preconnectOrigin(resolvedClient.getLinkApiUrl(), apiCredentials);
1301
- preconnectOrigin(chunkHKN3YG76_js.DEFAULT_CDN_BASE_URL);
1301
+ preconnectOrigin(chunkQPRI2NII_js.DEFAULT_CDN_BASE_URL);
1302
1302
  }
1303
1303
  const setCurrentLocation = React14.useCallback(
1304
1304
  (location) => {
@@ -6810,7 +6810,7 @@ function VariantSelector({
6810
6810
  {
6811
6811
  "data-cimplify-variant-name": true,
6812
6812
  className: cn("flex-1 min-w-0 text-sm", classNames?.name),
6813
- children: chunkHKN3YG76_js.getVariantDisplayName(variant, productName)
6813
+ children: chunkQPRI2NII_js.getVariantDisplayName(variant, productName)
6814
6814
  }
6815
6815
  ),
6816
6816
  /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
@@ -8603,12 +8603,12 @@ function FieldInput({
8603
8603
  classNames?.input
8604
8604
  );
8605
8605
  switch (field.field_type) {
8606
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Text:
8607
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Url:
8606
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Text:
8607
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Url:
8608
8608
  return /* @__PURE__ */ jsxRuntime.jsx(
8609
8609
  "input",
8610
8610
  {
8611
- type: field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
8611
+ type: field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
8612
8612
  value: typeof value === "string" ? value : "",
8613
8613
  onChange: (e) => onValueChange(e.target.value),
8614
8614
  placeholder: field.placeholder,
@@ -8617,7 +8617,7 @@ function FieldInput({
8617
8617
  className: inputClass
8618
8618
  }
8619
8619
  );
8620
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Textarea:
8620
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Textarea:
8621
8621
  return /* @__PURE__ */ jsxRuntime.jsx(
8622
8622
  "textarea",
8623
8623
  {
@@ -8630,7 +8630,7 @@ function FieldInput({
8630
8630
  className: cn(inputClass, "resize-none", classNames?.textarea)
8631
8631
  }
8632
8632
  );
8633
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Number:
8633
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Number:
8634
8634
  return /* @__PURE__ */ jsxRuntime.jsx(
8635
8635
  "input",
8636
8636
  {
@@ -8644,7 +8644,7 @@ function FieldInput({
8644
8644
  className: inputClass
8645
8645
  }
8646
8646
  );
8647
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Select:
8647
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Select:
8648
8648
  return /* @__PURE__ */ jsxRuntime.jsxs(
8649
8649
  "select",
8650
8650
  {
@@ -8658,7 +8658,7 @@ function FieldInput({
8658
8658
  ]
8659
8659
  }
8660
8660
  );
8661
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Radio:
8661
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Radio:
8662
8662
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
8663
8663
  "label",
8664
8664
  {
@@ -8683,7 +8683,7 @@ function FieldInput({
8683
8683
  },
8684
8684
  opt
8685
8685
  )) });
8686
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Checkbox:
8686
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Checkbox:
8687
8687
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
8688
8688
  /* @__PURE__ */ jsxRuntime.jsx(
8689
8689
  "input",
@@ -8696,7 +8696,7 @@ function FieldInput({
8696
8696
  ),
8697
8697
  field.placeholder || field.name
8698
8698
  ] });
8699
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Color:
8699
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Color:
8700
8700
  return /* @__PURE__ */ jsxRuntime.jsx(
8701
8701
  "input",
8702
8702
  {
@@ -8706,7 +8706,7 @@ function FieldInput({
8706
8706
  className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
8707
8707
  }
8708
8708
  );
8709
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Date:
8709
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Date:
8710
8710
  return /* @__PURE__ */ jsxRuntime.jsx(
8711
8711
  DatePicker,
8712
8712
  {
@@ -8717,8 +8717,8 @@ function FieldInput({
8717
8717
  "aria-label": field.name
8718
8718
  }
8719
8719
  );
8720
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.File:
8721
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image:
8720
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.File:
8721
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image:
8722
8722
  return /* @__PURE__ */ jsxRuntime.jsx(
8723
8723
  FileUploadInput,
8724
8724
  {
@@ -8729,7 +8729,7 @@ function FieldInput({
8729
8729
  classNames
8730
8730
  }
8731
8731
  );
8732
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Email:
8732
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Email:
8733
8733
  return /* @__PURE__ */ jsxRuntime.jsx(
8734
8734
  "input",
8735
8735
  {
@@ -8741,7 +8741,7 @@ function FieldInput({
8741
8741
  className: inputClass
8742
8742
  }
8743
8743
  );
8744
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.DateTime: {
8744
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.DateTime: {
8745
8745
  const stringValue = typeof value === "string" ? value : "";
8746
8746
  const [datePart, timePartRaw] = stringValue.includes("T") ? stringValue.split("T", 2) : [stringValue, ""];
8747
8747
  const timePart = (timePartRaw ?? "").slice(0, 5);
@@ -8780,7 +8780,7 @@ function FieldInput({
8780
8780
  )
8781
8781
  ] });
8782
8782
  }
8783
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Time:
8783
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Time:
8784
8784
  return /* @__PURE__ */ jsxRuntime.jsx(
8785
8785
  TimePicker,
8786
8786
  {
@@ -8791,7 +8791,7 @@ function FieldInput({
8791
8791
  "aria-label": field.name
8792
8792
  }
8793
8793
  );
8794
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.MultiSelect:
8794
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.MultiSelect:
8795
8795
  return /* @__PURE__ */ jsxRuntime.jsx(
8796
8796
  MultiSelectInput,
8797
8797
  {
@@ -8801,7 +8801,7 @@ function FieldInput({
8801
8801
  classNames
8802
8802
  }
8803
8803
  );
8804
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.DateRange:
8804
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.DateRange:
8805
8805
  return /* @__PURE__ */ jsxRuntime.jsx(
8806
8806
  DateRangeInput,
8807
8807
  {
@@ -8811,7 +8811,7 @@ function FieldInput({
8811
8811
  classNames
8812
8812
  }
8813
8813
  );
8814
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Address:
8814
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Address:
8815
8815
  return /* @__PURE__ */ jsxRuntime.jsx(
8816
8816
  AddressInput,
8817
8817
  {
@@ -8822,7 +8822,7 @@ function FieldInput({
8822
8822
  inputClass
8823
8823
  }
8824
8824
  );
8825
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Location:
8825
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Location:
8826
8826
  return /* @__PURE__ */ jsxRuntime.jsx(
8827
8827
  LocationInput,
8828
8828
  {
@@ -8833,7 +8833,7 @@ function FieldInput({
8833
8833
  inputClass
8834
8834
  }
8835
8835
  );
8836
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Phone:
8836
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Phone:
8837
8837
  return /* @__PURE__ */ jsxRuntime.jsx(
8838
8838
  PhoneInput,
8839
8839
  {
@@ -8844,7 +8844,7 @@ function FieldInput({
8844
8844
  inputClass
8845
8845
  }
8846
8846
  );
8847
- case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Signature:
8847
+ case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Signature:
8848
8848
  return /* @__PURE__ */ jsxRuntime.jsx(
8849
8849
  SignatureInput,
8850
8850
  {
@@ -8877,7 +8877,7 @@ function FileUploadInput({
8877
8877
  const [isUploading, setIsUploading] = React14__default.default.useState(false);
8878
8878
  const fileUrl = typeof value === "string" ? value : void 0;
8879
8879
  const acceptedFormats = field.validation?.accepted_formats;
8880
- const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
8880
+ const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
8881
8881
  const handleFile = async (file) => {
8882
8882
  if (!onFileUpload) return;
8883
8883
  if (field.validation?.max_size_mb) {
@@ -8895,7 +8895,7 @@ function FileUploadInput({
8895
8895
  }
8896
8896
  };
8897
8897
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8898
- field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
8898
+ field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
8899
8899
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
8900
8900
  /* @__PURE__ */ jsxRuntime.jsx(
8901
8901
  "button",
@@ -8921,7 +8921,7 @@ function FileUploadInput({
8921
8921
  }
8922
8922
  ),
8923
8923
  isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8924
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
8924
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
8925
8925
  acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
8926
8926
  acceptedFormats.map((f) => f.toUpperCase()).join(", "),
8927
8927
  field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
@@ -9655,7 +9655,7 @@ function ProductCustomizer({
9655
9655
  const isBundle = productType === "bundle";
9656
9656
  const isDigital = productType === "digital";
9657
9657
  const isService = productType === "service";
9658
- const offersUnits = isService && chunkHKN3YG76_js.isMultiDayService(product);
9658
+ const offersUnits = isService && chunkQPRI2NII_js.isMultiDayService(product);
9659
9659
  const isStandard = !isComposite && !isBundle;
9660
9660
  const hasVariants = isStandard && product.variants && product.variants.length > 0;
9661
9661
  const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
@@ -9769,7 +9769,7 @@ function ProductCustomizer({
9769
9769
  }, [quote, quantity]);
9770
9770
  const displayTotalPrice = React14.useMemo(() => {
9771
9771
  const total = quotedTotalPrice ?? localTotalPrice;
9772
- const multiplier = chunkHKN3YG76_js.serviceBillingMultiplier(product, {
9772
+ const multiplier = chunkQPRI2NII_js.serviceBillingMultiplier(product, {
9773
9773
  quantity,
9774
9774
  units: unitsCount,
9775
9775
  scheduledStart: selectedSlot?.start_time,
@@ -10483,7 +10483,7 @@ function CartLineItemRow({
10483
10483
  const isOptimistic2 = item.isOptimistic === true;
10484
10484
  const lineTotal = chunkPTPOQVXS_js.parsePrice(unitPrice) * item.quantity;
10485
10485
  const imageUrl = item.product.image_url;
10486
- const variantLabel2 = item.variant ? chunkHKN3YG76_js.getVariantDisplayName(item.variant, item.product.name) : null;
10486
+ const variantLabel2 = item.variant ? chunkQPRI2NII_js.getVariantDisplayName(item.variant, item.product.name) : null;
10487
10487
  return /* @__PURE__ */ jsxRuntime.jsxs(
10488
10488
  "div",
10489
10489
  {
@@ -10583,7 +10583,7 @@ function CartLineItemRow({
10583
10583
  input.field_name,
10584
10584
  ":"
10585
10585
  ] }),
10586
- /* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.File || input.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
10586
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.File || input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
10587
10587
  ] }, input.field_id)) }),
10588
10588
  (item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-info": true, className: cn("mt-1.5 flex items-center gap-1.5 text-xs text-muted-foreground", classNames?.serviceInfo), children: [
10589
10589
  /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3.5 h-3.5 shrink-0", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
@@ -11468,7 +11468,7 @@ function FoodProductCard({
11468
11468
  const tags = product.tags || [];
11469
11469
  const isSignature = product.metadata?.is_signature === true;
11470
11470
  const isNew = product.metadata?.is_new === true;
11471
- const isComposite = product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite;
11471
+ const isComposite = product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite;
11472
11472
  return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
11473
11473
  /* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
11474
11474
  isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
@@ -12235,36 +12235,36 @@ var BUILT_IN_CARDS = {
12235
12235
  ["composite" /* Composite */]: CompositeProductCard,
12236
12236
  ["subscription" /* Subscription */]: SubscriptionCard
12237
12237
  };
12238
- var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkHKN3YG76_js.DURATION_UNIT.Days, chunkHKN3YG76_js.DURATION_UNIT.Hours]);
12239
- var LEASE_UNITS = /* @__PURE__ */ new Set([chunkHKN3YG76_js.DURATION_UNIT.Weeks, chunkHKN3YG76_js.DURATION_UNIT.Months, chunkHKN3YG76_js.DURATION_UNIT.Years]);
12238
+ var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkQPRI2NII_js.DURATION_UNIT.Days, chunkQPRI2NII_js.DURATION_UNIT.Hours]);
12239
+ var LEASE_UNITS = /* @__PURE__ */ new Set([chunkQPRI2NII_js.DURATION_UNIT.Weeks, chunkQPRI2NII_js.DURATION_UNIT.Months, chunkQPRI2NII_js.DURATION_UNIT.Years]);
12240
12240
  function resolveCardVariant(product) {
12241
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Bundle) {
12241
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Bundle) {
12242
12242
  return "bundle" /* Bundle */;
12243
12243
  }
12244
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite) {
12244
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite) {
12245
12245
  return "composite" /* Composite */;
12246
12246
  }
12247
12247
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
12248
12248
  return "wholesale" /* Wholesale */;
12249
12249
  }
12250
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Digital) {
12250
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Digital) {
12251
12251
  return "digital" /* Digital */;
12252
12252
  }
12253
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Service) {
12253
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Service) {
12254
12254
  switch (product.boundary_kind) {
12255
- case chunkHKN3YG76_js.BOUNDARY_KIND.CheckInOut:
12255
+ case chunkQPRI2NII_js.BOUNDARY_KIND.CheckInOut:
12256
12256
  return "accommodation" /* Accommodation */;
12257
- case chunkHKN3YG76_js.BOUNDARY_KIND.MoveInOut:
12257
+ case chunkQPRI2NII_js.BOUNDARY_KIND.MoveInOut:
12258
12258
  return "lease" /* Lease */;
12259
- case chunkHKN3YG76_js.BOUNDARY_KIND.PickupReturn:
12260
- case chunkHKN3YG76_js.BOUNDARY_KIND.DeliveryCollection:
12261
- case chunkHKN3YG76_js.BOUNDARY_KIND.AccessVacate:
12259
+ case chunkQPRI2NII_js.BOUNDARY_KIND.PickupReturn:
12260
+ case chunkQPRI2NII_js.BOUNDARY_KIND.DeliveryCollection:
12261
+ case chunkQPRI2NII_js.BOUNDARY_KIND.AccessVacate:
12262
12262
  return "rental" /* Rental */;
12263
12263
  }
12264
12264
  if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
12265
12265
  return "rental" /* Rental */;
12266
12266
  }
12267
- if (product.duration_unit === chunkHKN3YG76_js.DURATION_UNIT.Nights) {
12267
+ if (product.duration_unit === chunkQPRI2NII_js.DURATION_UNIT.Nights) {
12268
12268
  return "accommodation" /* Accommodation */;
12269
12269
  }
12270
12270
  if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
@@ -12275,10 +12275,10 @@ function resolveCardVariant(product) {
12275
12275
  }
12276
12276
  return "standard" /* Standard */;
12277
12277
  }
12278
- if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Food) {
12278
+ if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Food) {
12279
12279
  return "food" /* Food */;
12280
12280
  }
12281
- if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Physical) {
12281
+ if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Physical) {
12282
12282
  return "retail" /* Retail */;
12283
12283
  }
12284
12284
  return "retail" /* Retail */;
@@ -12558,14 +12558,14 @@ var PRESET_LABELS = {
12558
12558
  move_in_out: { start: "Move-in", end: "Move-out" }
12559
12559
  };
12560
12560
  function defaultBoundaryKind(unit) {
12561
- return unit === chunkHKN3YG76_js.DURATION_UNIT.Nights ? chunkHKN3YG76_js.BOUNDARY_KIND.CheckInOut : chunkHKN3YG76_js.BOUNDARY_KIND.PickupReturn;
12561
+ return unit === chunkQPRI2NII_js.DURATION_UNIT.Nights ? chunkQPRI2NII_js.BOUNDARY_KIND.CheckInOut : chunkQPRI2NII_js.BOUNDARY_KIND.PickupReturn;
12562
12562
  }
12563
12563
  function resolveBoundaryKind(product) {
12564
12564
  return product.boundary_kind ?? defaultBoundaryKind(product.duration_unit);
12565
12565
  }
12566
12566
  function getBoundaryLabels(product) {
12567
12567
  const kind = resolveBoundaryKind(product);
12568
- if (kind === chunkHKN3YG76_js.BOUNDARY_KIND.Custom) {
12568
+ if (kind === chunkQPRI2NII_js.BOUNDARY_KIND.Custom) {
12569
12569
  return {
12570
12570
  start: product.boundary_start_label?.trim() || "Start",
12571
12571
  end: product.boundary_end_label?.trim() || "End"
@@ -14653,7 +14653,7 @@ function DefaultProductLayout({
14653
14653
  className
14654
14654
  }) {
14655
14655
  const [selectedVariantId, setSelectedVariantId] = React14__default.default.useState();
14656
- const images = chunkHKN3YG76_js.resolveGallery(product, selectedVariantId);
14656
+ const images = chunkQPRI2NII_js.resolveGallery(product, selectedVariantId);
14657
14657
  const currency = chunkPTPOQVXS_js.getProductCurrency(product);
14658
14658
  const hasRange = product.quantity_pricing && product.quantity_pricing.length > 1 || product.variants && product.variants.length > 1;
14659
14659
  const onSale = chunkPTPOQVXS_js.isOnSale(product);
@@ -15300,25 +15300,25 @@ function resolveTemplateKey(product) {
15300
15300
  if (typeof metaTemplate === "string" && metaTemplate.trim()) {
15301
15301
  return metaTemplate.trim();
15302
15302
  }
15303
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Bundle) {
15303
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Bundle) {
15304
15304
  return "bundle" /* Bundle */;
15305
15305
  }
15306
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite) {
15306
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite) {
15307
15307
  return "composite" /* Composite */;
15308
15308
  }
15309
15309
  if (product.quantity_pricing && product.quantity_pricing.length > 1) {
15310
15310
  return "wholesale" /* Wholesale */;
15311
15311
  }
15312
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Service) {
15312
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Service) {
15313
15313
  return "service" /* Service */;
15314
15314
  }
15315
- if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Digital) {
15315
+ if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Digital) {
15316
15316
  return "digital" /* Digital */;
15317
15317
  }
15318
- if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Food) {
15318
+ if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Food) {
15319
15319
  return "food" /* Food */;
15320
15320
  }
15321
- if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Physical) {
15321
+ if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Physical) {
15322
15322
  return "physical" /* Physical */;
15323
15323
  }
15324
15324
  return "default" /* Default */;
@@ -17170,12 +17170,582 @@ var ChatMarkdown = React14.memo(function ChatMarkdown2({
17170
17170
  }
17171
17171
  return /* @__PURE__ */ jsxRuntime.jsx(SettledMarkdown, { text, className });
17172
17172
  });
17173
- var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
17174
- var KEEP_DISMISSED_KEY = "cimplify_keep_chat_dismissed";
17175
- var AT_BOTTOM_SLACK_PX = 48;
17173
+
17174
+ // src/react/chat-kit/motion.ts
17175
+ function prefersReducedMotion() {
17176
+ return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
17177
+ }
17178
+ function scrollBehavior() {
17179
+ return prefersReducedMotion() ? "auto" : "smooth";
17180
+ }
17181
+ function QuoteBlock({
17182
+ quote,
17183
+ inCustomerBubble,
17184
+ businessName,
17185
+ onMissing
17186
+ }) {
17187
+ const quotedIsCustomer = quote.sender_type === "customer";
17188
+ const jumpToOriginal = async () => {
17189
+ let original = document.getElementById(`chat-msg-${quote.id}`);
17190
+ if (!original && onMissing && await onMissing()) {
17191
+ original = document.getElementById(`chat-msg-${quote.id}`);
17192
+ }
17193
+ if (!original) return;
17194
+ original.scrollIntoView({ behavior: scrollBehavior(), block: "center" });
17195
+ original.classList.remove("animate-quote-flash");
17196
+ void original.offsetWidth;
17197
+ original.classList.add("animate-quote-flash");
17198
+ };
17199
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17200
+ "button",
17201
+ {
17202
+ type: "button",
17203
+ onClick: () => void jumpToOriginal(),
17204
+ className: cn(
17205
+ "flex w-full gap-2 rounded-[10px] px-2.5 py-1.5 text-left",
17206
+ inCustomerBubble ? "bg-primary-foreground/15" : "bg-background/70"
17207
+ ),
17208
+ children: [
17209
+ /* @__PURE__ */ jsxRuntime.jsx(
17210
+ "span",
17211
+ {
17212
+ className: cn(
17213
+ "w-[3px] shrink-0 self-stretch rounded-full",
17214
+ inCustomerBubble ? "bg-primary-foreground/50" : quotedIsCustomer ? "bg-primary" : "bg-muted-foreground/50"
17215
+ )
17216
+ }
17217
+ ),
17218
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
17219
+ /* @__PURE__ */ jsxRuntime.jsx(
17220
+ "span",
17221
+ {
17222
+ className: cn(
17223
+ "text-[11px] leading-4 font-semibold",
17224
+ inCustomerBubble ? "text-primary-foreground" : "text-foreground"
17225
+ ),
17226
+ children: quotedIsCustomer ? "You" : businessName
17227
+ }
17228
+ ),
17229
+ /* @__PURE__ */ jsxRuntime.jsx(
17230
+ "span",
17231
+ {
17232
+ className: cn(
17233
+ "truncate text-xs leading-4",
17234
+ inCustomerBubble ? "text-primary-foreground/75" : "text-muted-foreground"
17235
+ ),
17236
+ children: quote.preview
17237
+ }
17238
+ )
17239
+ ] })
17240
+ ]
17241
+ }
17242
+ );
17243
+ }
17244
+ var SWIPE_COMMIT_PX = 48;
17245
+ var SWIPE_ARM_PX = 10;
17246
+ var OVERDRAG_RATE = 0.25;
17247
+ var LONG_PRESS_MS = 450;
17248
+ var RETURN_TRANSITION = "transform 0.25s cubic-bezier(0.2, 0, 0, 1)";
17249
+ function swipeTravel(distance) {
17250
+ if (distance <= 0) return 0;
17251
+ if (distance <= SWIPE_COMMIT_PX) return distance;
17252
+ return SWIPE_COMMIT_PX + (distance - SWIPE_COMMIT_PX) * OVERDRAG_RATE;
17253
+ }
17254
+ function swipeCommitted(distance) {
17255
+ return distance >= SWIPE_COMMIT_PX;
17256
+ }
17257
+ function swipeProgress(distance) {
17258
+ return Math.min(Math.max(distance / SWIPE_COMMIT_PX, 0), 1);
17259
+ }
17260
+ function useSwipeReply({ onReply, onLongPress }) {
17261
+ const rowRef = React14.useRef(null);
17262
+ const glyphRef = React14.useRef(null);
17263
+ const gestureRef = React14.useRef(null);
17264
+ const suppressClickRef = React14.useRef(false);
17265
+ const optionsRef = React14.useRef({ onReply, onLongPress });
17266
+ optionsRef.current = { onReply, onLongPress };
17267
+ const settle = React14.useCallback((glyphVisible) => {
17268
+ const row = rowRef.current;
17269
+ const glyph = glyphRef.current;
17270
+ if (row) {
17271
+ row.style.transition = RETURN_TRANSITION;
17272
+ row.style.transform = "translateX(0px)";
17273
+ }
17274
+ if (glyph && !glyphVisible) {
17275
+ glyph.style.transition = "opacity 0.2s ease-out";
17276
+ glyph.style.opacity = "0";
17277
+ }
17278
+ }, []);
17279
+ const clearGesture = React14.useCallback(() => {
17280
+ const gesture = gestureRef.current;
17281
+ if (gesture?.longPressTimer) clearTimeout(gesture.longPressTimer);
17282
+ gestureRef.current = null;
17283
+ }, []);
17284
+ const onPointerDown = React14.useCallback((event) => {
17285
+ if (!event.isPrimary) return;
17286
+ suppressClickRef.current = false;
17287
+ gestureRef.current = {
17288
+ pointerId: event.pointerId,
17289
+ startX: event.clientX,
17290
+ startY: event.clientY,
17291
+ armed: false,
17292
+ distance: 0,
17293
+ longPressTimer: setTimeout(() => {
17294
+ gestureRef.current = null;
17295
+ suppressClickRef.current = true;
17296
+ optionsRef.current.onLongPress();
17297
+ }, LONG_PRESS_MS)
17298
+ };
17299
+ }, []);
17300
+ const onPointerMove = React14.useCallback((event) => {
17301
+ const gesture = gestureRef.current;
17302
+ if (!gesture || gesture.pointerId !== event.pointerId) return;
17303
+ const leftward = gesture.startX - event.clientX;
17304
+ const vertical = Math.abs(event.clientY - gesture.startY);
17305
+ if (!gesture.armed) {
17306
+ const scrolling = vertical > SWIPE_ARM_PX && vertical >= leftward;
17307
+ const rightward = leftward < -SWIPE_ARM_PX;
17308
+ if (scrolling || rightward) {
17309
+ clearGesture();
17310
+ return;
17311
+ }
17312
+ if (leftward <= SWIPE_ARM_PX || leftward <= vertical) return;
17313
+ if (prefersReducedMotion()) {
17314
+ clearGesture();
17315
+ return;
17316
+ }
17317
+ gesture.armed = true;
17318
+ if (gesture.longPressTimer) clearTimeout(gesture.longPressTimer);
17319
+ gesture.longPressTimer = null;
17320
+ event.currentTarget.setPointerCapture(event.pointerId);
17321
+ if (rowRef.current) rowRef.current.style.transition = "none";
17322
+ if (glyphRef.current) glyphRef.current.style.transition = "none";
17323
+ }
17324
+ gesture.distance = leftward;
17325
+ if (rowRef.current) {
17326
+ rowRef.current.style.transform = `translateX(-${swipeTravel(leftward)}px)`;
17327
+ }
17328
+ if (glyphRef.current) {
17329
+ glyphRef.current.style.opacity = String(swipeProgress(leftward));
17330
+ }
17331
+ }, [clearGesture]);
17332
+ const onPointerUp = React14.useCallback(
17333
+ (event) => {
17334
+ const gesture = gestureRef.current;
17335
+ if (!gesture || gesture.pointerId !== event.pointerId) return;
17336
+ const commit = gesture.armed && swipeCommitted(gesture.distance);
17337
+ const wasArmed = gesture.armed;
17338
+ clearGesture();
17339
+ if (wasArmed) {
17340
+ suppressClickRef.current = true;
17341
+ settle(false);
17342
+ }
17343
+ if (commit) optionsRef.current.onReply();
17344
+ },
17345
+ [clearGesture, settle]
17346
+ );
17347
+ const onPointerCancel = React14.useCallback(
17348
+ (event) => {
17349
+ const gesture = gestureRef.current;
17350
+ if (!gesture || gesture.pointerId !== event.pointerId) return;
17351
+ const wasArmed = gesture.armed;
17352
+ clearGesture();
17353
+ if (wasArmed) settle(false);
17354
+ },
17355
+ [clearGesture, settle]
17356
+ );
17357
+ const onClickCapture = React14.useCallback((event) => {
17358
+ if (!suppressClickRef.current) return;
17359
+ suppressClickRef.current = false;
17360
+ event.preventDefault();
17361
+ event.stopPropagation();
17362
+ }, []);
17363
+ return {
17364
+ rowRef,
17365
+ glyphRef,
17366
+ handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onClickCapture }
17367
+ };
17368
+ }
17369
+ var PROSE_CLASS = "[&_p]:my-0 [&_p+p]:mt-1.5 [&_ul]:my-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:my-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:my-0.5 [&_h1]:text-[15px] [&_h1]:font-bold [&_h2]:text-[15px] [&_h2]:font-bold [&_h3]:text-sm [&_h3]:font-semibold [&_hr]:my-2 [&_hr]:border-border [&_table]:my-1 [&_table]:w-full [&_th]:pb-1 [&_th]:text-left [&_th]:text-[11px] [&_th]:font-semibold [&_th]:uppercase [&_th]:text-muted-foreground [&_td]:border-b [&_td]:border-border/50 [&_td]:py-1 [&_td:last-child]:text-right [&_td:last-child]:font-semibold [&_td:last-child]:tabular-nums [&_tr:last-child_td]:border-b-0 [&_a]:underline [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:text-[13px]";
17370
+ function bubbleShape(isCustomer, group) {
17371
+ if (!hasTail(group)) return "rounded-[18px]";
17372
+ return isCustomer ? "rounded-[18px] rounded-br-none" : "rounded-[18px] rounded-bl-none";
17373
+ }
17374
+ function hasTail(group) {
17375
+ return group === "single" || group === "last";
17376
+ }
17377
+ var TAIL_SWEEP = "M21 0 L21 5 C21 15 25 16 25 16 C20.93 16.43 16.84 14.94 13.96 11.96 C9 16 5 16 0 16";
17378
+ var TAIL_FILL = `${TAIL_SWEEP} Z`;
17379
+ var TAIL_NOTCH = "M25 16 C20.93 16.43 16.84 14.94 13.96 11.96 C9 16 5 16 0 16 Z";
17380
+ function BubbleTail({ isCustomer }) {
17381
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17382
+ "svg",
17383
+ {
17384
+ width: "25",
17385
+ height: "16",
17386
+ viewBox: "0 0 25 16",
17387
+ "aria-hidden": "true",
17388
+ className: cn(
17389
+ "absolute bottom-0",
17390
+ isCustomer ? "-right-[4px] fill-primary" : "-left-[4px] -scale-x-100 fill-background"
17391
+ ),
17392
+ children: [
17393
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_FILL }),
17394
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_NOTCH, style: { fill: "var(--color-chat-canvas, var(--color-muted, #f3f5f3))" } }),
17395
+ !isCustomer && /* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_SWEEP, fill: "none", strokeWidth: "1", className: "stroke-foreground/[0.07]" })
17396
+ ]
17397
+ }
17398
+ );
17399
+ }
17400
+ function clockLabel(at) {
17401
+ const date = new Date(at);
17402
+ if (Number.isNaN(date.getTime())) return "";
17403
+ const hour = date.getHours() % 12 || 12;
17404
+ return `${hour}:${String(date.getMinutes()).padStart(2, "0")}`;
17405
+ }
17406
+ function DoubleTick() {
17407
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "9", viewBox: "0 0 15 9", fill: "none", "aria-hidden": "true", children: [
17408
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 4.5L4 7.5L9.5 1.5", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }),
17409
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.5 4.5L9.5 7.5L14 2.5", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" })
17410
+ ] });
17411
+ }
17412
+ function SendingClock() {
17413
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "11", height: "11", viewBox: "0 0 11 11", fill: "none", "aria-hidden": "true", children: [
17414
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "5.5", cy: "5.5", r: "4.5", stroke: "currentColor", strokeWidth: "1.2" }),
17415
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 3v2.7l1.8 1", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" })
17416
+ ] });
17417
+ }
17418
+ function PaperclipIcon() {
17419
+ return /* @__PURE__ */ jsxRuntime.jsx(
17420
+ "svg",
17421
+ {
17422
+ width: "14",
17423
+ height: "14",
17424
+ viewBox: "0 0 24 24",
17425
+ fill: "none",
17426
+ stroke: "currentColor",
17427
+ strokeWidth: "2",
17428
+ strokeLinecap: "round",
17429
+ strokeLinejoin: "round",
17430
+ "aria-hidden": "true",
17431
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" })
17432
+ }
17433
+ );
17434
+ }
17435
+ function ReplyGlyph() {
17436
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17437
+ "svg",
17438
+ {
17439
+ width: "18",
17440
+ height: "18",
17441
+ viewBox: "0 0 24 24",
17442
+ fill: "none",
17443
+ stroke: "currentColor",
17444
+ strokeWidth: "2.2",
17445
+ strokeLinecap: "round",
17446
+ strokeLinejoin: "round",
17447
+ "aria-hidden": "true",
17448
+ children: [
17449
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 17 4 12 9 7" }),
17450
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
17451
+ ]
17452
+ }
17453
+ );
17454
+ }
17455
+ var DELIVERY_LABELS = {
17456
+ sending: "Sending",
17457
+ delivered: "Delivered",
17458
+ seen: "Seen"
17459
+ };
17460
+ function BubbleMeta({
17461
+ at,
17462
+ isCustomer,
17463
+ delivery
17464
+ }) {
17465
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17466
+ "span",
17467
+ {
17468
+ className: cn(
17469
+ "ml-auto flex shrink-0 items-center gap-[3px] self-end pb-px whitespace-nowrap",
17470
+ isCustomer ? "text-primary-foreground/70" : "text-muted-foreground"
17471
+ ),
17472
+ children: [
17473
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10.5px] leading-[13px] font-medium", children: clockLabel(at) }),
17474
+ isCustomer && delivery && /* @__PURE__ */ jsxRuntime.jsx(
17475
+ "span",
17476
+ {
17477
+ role: "img",
17478
+ "aria-label": DELIVERY_LABELS[delivery],
17479
+ className: cn(
17480
+ "flex items-center text-primary-foreground",
17481
+ delivery !== "seen" && "opacity-55"
17482
+ ),
17483
+ children: delivery === "sending" ? /* @__PURE__ */ jsxRuntime.jsx(SendingClock, {}) : /* @__PURE__ */ jsxRuntime.jsx(DoubleTick, {})
17484
+ }
17485
+ )
17486
+ ]
17487
+ }
17488
+ );
17489
+ }
17490
+ function reactionPills(reactions) {
17491
+ const counts = /* @__PURE__ */ new Map();
17492
+ for (const reaction of reactions) {
17493
+ const emoji = reaction.content.trim();
17494
+ if (emoji) counts.set(emoji, (counts.get(emoji) ?? 0) + 1);
17495
+ }
17496
+ return [...counts.entries()].map(([emoji, count]) => ({ emoji, count }));
17497
+ }
17498
+ var MessageBubble = React14.memo(function MessageBubble2({
17499
+ message,
17500
+ reactions,
17501
+ businessName,
17502
+ group = "single",
17503
+ delivery,
17504
+ onReply,
17505
+ onLongPress,
17506
+ avatar,
17507
+ overlay,
17508
+ renderCards,
17509
+ renderProgram,
17510
+ onQuoteMiss
17511
+ }) {
17512
+ const showAvatar = group === "single" || group === "last";
17513
+ const isCustomer = message.sender_type === "customer";
17514
+ const isBusiness = !isCustomer;
17515
+ const segments = React14.useMemo(
17516
+ () => isCustomer ? [{ kind: "prose", text: message.content }] : chunkXREIZ56K_js.splitGenUIContent(message.content),
17517
+ [isCustomer, message.content]
17518
+ );
17519
+ const drawable = React14.useMemo(
17520
+ () => segments.filter(
17521
+ (segment) => segment.kind === "prose" && segment.text.trim() !== "" || segment.kind === "program" && renderProgram != null
17522
+ ),
17523
+ // eslint-disable-next-line react-hooks/exhaustive-deps
17524
+ [segments, renderProgram != null]
17525
+ );
17526
+ const swipe = useSwipeReply({
17527
+ onReply: () => onReply(message),
17528
+ onLongPress: () => onLongPress?.(message)
17529
+ });
17530
+ const quote = message.reply_to ?? null;
17531
+ const pills = reactions ? reactionPills(reactions) : [];
17532
+ const cards = renderCards?.(message);
17533
+ const proseSegments = drawable.filter((segment) => segment.kind === "prose");
17534
+ const lastProseIndex = drawable.lastIndexOf(proseSegments[proseSegments.length - 1]);
17535
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: `chat-msg-${message.id}`, className: "relative rounded-xl", children: [
17536
+ /* @__PURE__ */ jsxRuntime.jsx(
17537
+ "span",
17538
+ {
17539
+ ref: swipe.glyphRef,
17540
+ "aria-hidden": "true",
17541
+ className: "absolute top-1/2 right-1 -translate-y-1/2 text-muted-foreground opacity-0",
17542
+ children: /* @__PURE__ */ jsxRuntime.jsx(ReplyGlyph, {})
17543
+ }
17544
+ ),
17545
+ overlay,
17546
+ /* @__PURE__ */ jsxRuntime.jsxs(
17547
+ "div",
17548
+ {
17549
+ ref: swipe.rowRef,
17550
+ ...swipe.handlers,
17551
+ onContextMenu: onLongPress ? (event) => {
17552
+ event.preventDefault();
17553
+ onLongPress(message);
17554
+ } : void 0,
17555
+ className: cn(
17556
+ "flex touch-pan-y flex-col gap-[3px] select-none [-webkit-touch-callout:none]",
17557
+ isCustomer ? "items-end" : "items-start"
17558
+ ),
17559
+ children: [
17560
+ quote && drawable[0]?.kind !== "prose" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[280px] rounded-[14px] border border-foreground/[0.07] bg-background p-1.5 shadow-[0_1px_1px_rgba(15,23,42,0.03)]", children: /* @__PURE__ */ jsxRuntime.jsx(QuoteBlock, { quote, inCustomerBubble: false, businessName, onMissing: onQuoteMiss }) }),
17561
+ message.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-w-[280px] flex-wrap gap-1.5", children: message.attachments.map((attachment, index) => {
17562
+ const url = safeAttachmentUrl(attachment.url);
17563
+ if (!url) return null;
17564
+ return isImageAttachment(attachment) ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx(
17565
+ "img",
17566
+ {
17567
+ src: url,
17568
+ alt: attachment.filename ?? "Photo",
17569
+ loading: "lazy",
17570
+ className: "max-h-[240px] max-w-[240px] rounded-[16px] object-cover"
17571
+ }
17572
+ ) }, index) : /* @__PURE__ */ jsxRuntime.jsxs(
17573
+ "a",
17574
+ {
17575
+ href: url,
17576
+ target: "_blank",
17577
+ rel: "noreferrer",
17578
+ className: "flex items-center gap-2 rounded-[14px] border border-foreground/[0.07] bg-background px-3 py-2 text-[13px] font-medium text-foreground shadow-[0_1px_1px_rgba(15,23,42,0.03)]",
17579
+ children: [
17580
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(PaperclipIcon, {}) }),
17581
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[200px] truncate", children: attachment.filename ?? "Attachment" })
17582
+ ]
17583
+ },
17584
+ index
17585
+ );
17586
+ }) }),
17587
+ drawable.map(
17588
+ (segment, index) => segment.kind === "program" ? /* @__PURE__ */ jsxRuntime.jsx(React14__default.default.Fragment, { children: renderProgram?.(segment.source) }, index) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-w-full items-end gap-1.5", children: [
17589
+ isBusiness && avatar && /* @__PURE__ */ jsxRuntime.jsx(
17590
+ "span",
17591
+ {
17592
+ "aria-label": businessName,
17593
+ className: cn(
17594
+ "shrink-0",
17595
+ // One avatar per run, anchored to its last bubble.
17596
+ showAvatar && index === lastProseIndex ? "visible" : "invisible"
17597
+ ),
17598
+ children: avatar
17599
+ }
17600
+ ),
17601
+ /* @__PURE__ */ jsxRuntime.jsxs(
17602
+ "div",
17603
+ {
17604
+ className: cn(
17605
+ "relative flex max-w-[280px] min-w-0 flex-col gap-1.5 py-2 pr-[11px] pl-3.5 text-[15px] leading-[21px] font-[450] break-words",
17606
+ bubbleShape(isCustomer, index === lastProseIndex ? group : "middle"),
17607
+ isCustomer ? "bg-primary text-primary-foreground" : "border border-foreground/[0.07] bg-background text-foreground shadow-[0_1px_1px_rgba(15,23,42,0.03)]"
17608
+ ),
17609
+ children: [
17610
+ index === 0 && quote && /* @__PURE__ */ jsxRuntime.jsx(QuoteBlock, { quote, inCustomerBubble: isCustomer, businessName, onMissing: onQuoteMiss }),
17611
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-end gap-x-2 gap-y-0.5", children: [
17612
+ isCustomer ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-pre-wrap", children: segment.text }) : /* @__PURE__ */ jsxRuntime.jsx(ChatMarkdown, { text: segment.text, className: cn("min-w-0", PROSE_CLASS) }),
17613
+ index === lastProseIndex && /* @__PURE__ */ jsxRuntime.jsx(BubbleMeta, { at: message.created_at, isCustomer, delivery })
17614
+ ] }),
17615
+ index === lastProseIndex && hasTail(group) && /* @__PURE__ */ jsxRuntime.jsx(BubbleTail, { isCustomer })
17616
+ ]
17617
+ }
17618
+ )
17619
+ ] }, index)
17620
+ ),
17621
+ cards,
17622
+ pills.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17623
+ "div",
17624
+ {
17625
+ className: cn(
17626
+ "z-[1] -mt-3 flex gap-1",
17627
+ // Overlap the bubble corner by ~9px, tucked inside the tail side.
17628
+ isCustomer ? "mr-2.5" : "ml-10"
17629
+ ),
17630
+ children: pills.map((pill) => /* @__PURE__ */ jsxRuntime.jsxs(
17631
+ "span",
17632
+ {
17633
+ className: "flex items-center gap-[3px] rounded-full border border-foreground/[0.08] bg-background px-[7px] py-[2px] shadow-[0_1px_3px_rgba(15,23,42,0.08)]",
17634
+ children: [
17635
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs leading-4", children: pill.emoji }),
17636
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] leading-[13px] font-semibold text-muted-foreground", children: pill.count })
17637
+ ]
17638
+ },
17639
+ pill.emoji
17640
+ ))
17641
+ }
17642
+ )
17643
+ ]
17644
+ }
17645
+ )
17646
+ ] });
17647
+ });
17648
+ function Seam({
17649
+ label,
17650
+ variant = "line"
17651
+ }) {
17652
+ if (variant === "chip") {
17653
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-foreground/[0.06] bg-background px-3 py-1 text-[11px] leading-[14px] font-semibold tracking-[0.04em] text-muted-foreground uppercase shadow-[0_1px_2px_rgba(15,23,42,0.04)]", children: label }) });
17654
+ }
17655
+ const unread = variant === "unread";
17656
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 py-1.5", children: [
17657
+ /* @__PURE__ */ jsxRuntime.jsx(
17658
+ "span",
17659
+ {
17660
+ className: cn("h-px flex-1", unread ? "bg-primary/35" : "bg-foreground/[0.08]"),
17661
+ "aria-hidden": "true"
17662
+ }
17663
+ ),
17664
+ /* @__PURE__ */ jsxRuntime.jsx(
17665
+ "span",
17666
+ {
17667
+ className: cn(
17668
+ "whitespace-nowrap",
17669
+ unread ? "text-[11px] leading-[14px] font-semibold tracking-[0.04em] text-primary uppercase" : "text-[11.5px] leading-[15px] font-medium text-muted-foreground"
17670
+ ),
17671
+ children: label
17672
+ }
17673
+ ),
17674
+ /* @__PURE__ */ jsxRuntime.jsx(
17675
+ "span",
17676
+ {
17677
+ className: cn("h-px flex-1", unread ? "bg-primary/35" : "bg-foreground/[0.08]"),
17678
+ "aria-hidden": "true"
17679
+ }
17680
+ )
17681
+ ] });
17682
+ }
17683
+
17684
+ // src/react/chat-kit/timeline.ts
17685
+ function sameDay(a, b) {
17686
+ return new Date(a).toDateString() === new Date(b).toDateString();
17687
+ }
17688
+ function dayLabel(at) {
17689
+ const date = new Date(at);
17690
+ const today = /* @__PURE__ */ new Date();
17691
+ if (date.toDateString() === today.toDateString()) return "Today";
17692
+ const yesterday = new Date(today);
17693
+ yesterday.setDate(today.getDate() - 1);
17694
+ if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
17695
+ return date.toLocaleDateString([], { weekday: "short", day: "numeric", month: "short" });
17696
+ }
17176
17697
  function proseOf(content) {
17177
17698
  return chunkXREIZ56K_js.splitGenUIContent(content).filter((segment) => segment.kind === "prose").map((segment) => segment.text).join("\n\n").trim();
17178
17699
  }
17700
+ function hasProgram(content) {
17701
+ return chunkXREIZ56K_js.splitGenUIContent(content).some((segment) => segment.kind === "program");
17702
+ }
17703
+ function chatTimeline(messages, options = {}) {
17704
+ const { readAt = null, rendersPrograms = false } = options;
17705
+ const partitioned = partitionMessages(messages);
17706
+ const bubbles = partitioned.bubbles.filter(
17707
+ (message) => message.sender_type === "system" || message.attachments.length > 0 || chunkQPRI2NII_js.chatMessageCards(message).length > 0 || rendersPrograms && hasProgram(message.content) || (message.sender_type === "customer" ? message.content.trim() !== "" : proseOf(message.content) !== "")
17708
+ );
17709
+ let firstUnreadId;
17710
+ let unreadOnOpen = 0;
17711
+ if (readAt) {
17712
+ const readAtMs = new Date(readAt).getTime();
17713
+ for (const message of bubbles) {
17714
+ if (message.sender_type === "customer" || new Date(message.created_at).getTime() <= readAtMs)
17715
+ continue;
17716
+ firstUnreadId ?? (firstUnreadId = message.id);
17717
+ unreadOnOpen += 1;
17718
+ }
17719
+ }
17720
+ return {
17721
+ bubbles,
17722
+ reactionsByTarget: partitioned.reactionsByTarget,
17723
+ firstUnreadId,
17724
+ unreadOnOpen,
17725
+ firstAgentMessageId: bubbles.find((m) => m.sender_type === "agent")?.id
17726
+ };
17727
+ }
17728
+ function groupPosition(timeline, index) {
17729
+ const { bubbles, firstAgentMessageId, firstUnreadId } = timeline;
17730
+ const message = bubbles[index];
17731
+ const previous = bubbles[index - 1];
17732
+ const next = bubbles[index + 1];
17733
+ const startsRun = !previous || !sameDay(previous.created_at, message.created_at) || previous.sender_type !== message.sender_type || message.id === firstAgentMessageId || message.id === firstUnreadId || previous.sender_type === "system";
17734
+ const endsRun = !next || next.sender_type !== message.sender_type || next.sender_type === "system" || !sameDay(message.created_at, next.created_at);
17735
+ if (startsRun && endsRun) return "single";
17736
+ if (startsRun) return "first";
17737
+ if (endsRun) return "last";
17738
+ return "middle";
17739
+ }
17740
+ function deliveryState(message, timeline, seenAt, isOptimistic2) {
17741
+ if (message.sender_type !== "customer") return void 0;
17742
+ if (isOptimistic2(message)) return "sending";
17743
+ const seenCutoff = timeline.firstAgentMessageId ? seenAt : null;
17744
+ return seenCutoff && message.created_at <= seenCutoff ? "seen" : "delivered";
17745
+ }
17746
+ var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
17747
+ var KEEP_DISMISSED_KEY = "cimplify_keep_chat_dismissed";
17748
+ var AT_BOTTOM_SLACK_PX = 48;
17179
17749
  function ChatWidget({
17180
17750
  client: clientProp,
17181
17751
  businessName = "Support",
@@ -17300,6 +17870,7 @@ function ChatWidget({
17300
17870
  isSending,
17301
17871
  isTyping: showTyping,
17302
17872
  seenAt,
17873
+ readAt,
17303
17874
  error: error ?? attachError,
17304
17875
  isActive,
17305
17876
  isLeft,
@@ -17371,6 +17942,7 @@ function Panel({
17371
17942
  isSending,
17372
17943
  isTyping,
17373
17944
  seenAt,
17945
+ readAt,
17374
17946
  error,
17375
17947
  isActive,
17376
17948
  isLeft,
@@ -17429,6 +18001,7 @@ function Panel({
17429
18001
  isLoading,
17430
18002
  isSending: isTyping,
17431
18003
  seenAt,
18004
+ readAt,
17432
18005
  humanRequested,
17433
18006
  mayHaveOlder,
17434
18007
  onReact,
@@ -17589,22 +18162,8 @@ function Welcome({
17589
18162
  );
17590
18163
  }
17591
18164
  var QUICK_REACTIONS = ["\u{1F44D}", "\u2764\uFE0F"];
17592
- function lastSeenCustomerMessageId(bubbles, seenAt) {
17593
- if (!seenAt || !bubbles.some((m) => m.sender_type === "agent")) return null;
17594
- for (let i = bubbles.length - 1; i >= 0; i--) {
17595
- if (bubbles[i].sender_type !== "customer") continue;
17596
- return bubbles[i].created_at <= seenAt ? bubbles[i].id : null;
17597
- }
17598
- return null;
17599
- }
17600
- function dayLabel(at) {
17601
- const date = new Date(at);
17602
- const today = /* @__PURE__ */ new Date();
17603
- if (date.toDateString() === today.toDateString()) return "Today";
17604
- const yesterday = new Date(today);
17605
- yesterday.setDate(today.getDate() - 1);
17606
- if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
17607
- return date.toLocaleDateString([], { weekday: "short", day: "numeric", month: "short" });
18165
+ function LetterAvatar({ name }) {
18166
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-6 items-center justify-center rounded-full bg-foreground text-[10px] font-bold text-background", children: name.charAt(0).toUpperCase() });
17608
18167
  }
17609
18168
  function MessageList({
17610
18169
  messages,
@@ -17612,6 +18171,7 @@ function MessageList({
17612
18171
  isLoading,
17613
18172
  isSending,
17614
18173
  seenAt,
18174
+ readAt,
17615
18175
  humanRequested,
17616
18176
  mayHaveOlder,
17617
18177
  onReact,
@@ -17621,12 +18181,8 @@ function MessageList({
17621
18181
  className
17622
18182
  }) {
17623
18183
  const scrolledUpRef = React14.useRef(false);
17624
- const partitioned = partitionMessages(messages);
17625
- const bubbles = partitioned.bubbles.filter(
17626
- (m) => m.sender_type === "system" || m.attachments.length > 0 || (m.sender_type === "customer" ? m.content.trim() !== "" : proseOf(m.content) !== "")
17627
- );
17628
- const reactionsByTarget = partitioned.reactionsByTarget;
17629
- const seenMessageId = lastSeenCustomerMessageId(bubbles, seenAt);
18184
+ const timeline = chatTimeline(messages, { readAt });
18185
+ const { bubbles, reactionsByTarget, firstUnreadId, unreadOnOpen, firstAgentMessageId } = timeline;
17630
18186
  const lastBubble = bubbles[bubbles.length - 1];
17631
18187
  const offerHuman = !humanRequested && lastBubble?.sender_type === "bot" && !isSending;
17632
18188
  const handleScroll = (event) => {
@@ -17637,121 +18193,62 @@ function MessageList({
17637
18193
  "div",
17638
18194
  {
17639
18195
  onScroll: handleScroll,
17640
- className: cn(
17641
- "flex flex-1 flex-col gap-1 overflow-y-auto bg-muted/50 px-5 py-5",
17642
- className
17643
- ),
18196
+ style: { background: "var(--color-chat-canvas, var(--color-muted, #f3f5f3))" },
18197
+ className: cn("flex flex-1 flex-col gap-0.5 overflow-y-auto px-3.5 py-3.5", className),
17644
18198
  children: [
17645
18199
  isLoading && messages.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) }),
17646
- mayHaveOlder && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(
18200
+ mayHaveOlder && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-1", children: /* @__PURE__ */ jsxRuntime.jsx(
17647
18201
  "button",
17648
18202
  {
17649
18203
  type: "button",
17650
18204
  onClick: onLoadOlder,
17651
- className: "rounded-full border border-border bg-background px-3 py-1 text-[11px] font-semibold text-muted-foreground hover:text-foreground",
18205
+ className: "rounded-full border border-foreground/[0.06] bg-background px-3.5 py-[7px] text-xs font-semibold text-muted-foreground shadow-[0_1px_2px_rgba(15,23,42,0.04)]",
17652
18206
  children: "Show earlier messages"
17653
18207
  }
17654
18208
  ) }),
17655
18209
  bubbles.map((msg, i) => {
17656
- const isCustomer = msg.sender_type === "customer";
17657
18210
  const prev = bubbles[i - 1];
17658
- const sameSenderAsPrev = prev?.sender_type === msg.sender_type;
17659
- const optimistic = isOptimistic(msg);
17660
- const reactions = reactionsByTarget.get(msg.id);
17661
18211
  const newDay = !prev || !sameDay(prev.created_at, msg.created_at);
17662
- if (msg.sender_type === "system") {
17663
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-2 text-center text-[11px] font-medium text-muted-foreground", children: msg.content }, msg.id);
17664
- }
17665
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17666
- newDay && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-2 text-center text-[10px] font-semibold tracking-wide text-muted-foreground", children: dayLabel(msg.created_at) }),
17667
- !sameSenderAsPrev && i > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3" }),
17668
- /* @__PURE__ */ jsxRuntime.jsxs(
17669
- "div",
17670
- {
17671
- className: cn(
17672
- "group relative flex max-w-[85%]",
17673
- isCustomer ? "ml-auto" : "mr-auto"
18212
+ const group = groupPosition(timeline, i);
18213
+ const startsRun = group === "single" || group === "first";
18214
+ const delivery = deliveryState(msg, timeline, seenAt, isOptimistic);
18215
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18216
+ "div",
18217
+ {
18218
+ className: cn("flex flex-col gap-1.5", startsRun && i > 0 && "mt-2.5"),
18219
+ children: [
18220
+ newDay && /* @__PURE__ */ jsxRuntime.jsx(Seam, { variant: "chip", label: dayLabel(msg.created_at) }),
18221
+ msg.id === firstUnreadId && /* @__PURE__ */ jsxRuntime.jsx(
18222
+ Seam,
18223
+ {
18224
+ variant: "unread",
18225
+ label: `${unreadOnOpen} new message${unreadOnOpen === 1 ? "" : "s"}`
18226
+ }
17674
18227
  ),
17675
- children: [
17676
- !isCustomer && !optimistic && /* @__PURE__ */ jsxRuntime.jsx(HoverRail, { message: msg, onReact, onReply }),
17677
- /* @__PURE__ */ jsxRuntime.jsxs(
17678
- "div",
18228
+ msg.id === firstAgentMessageId && /* @__PURE__ */ jsxRuntime.jsx(Seam, { label: "A person joined" }),
18229
+ msg.sender_type === "system" ? /* @__PURE__ */ jsxRuntime.jsx(Seam, { label: "Passing you to the team" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
18230
+ msg.sender_type !== "customer" && !isOptimistic(msg) && /* @__PURE__ */ jsxRuntime.jsx(HoverRail, { message: msg, onReact, onReply }),
18231
+ /* @__PURE__ */ jsxRuntime.jsx(
18232
+ MessageBubble,
17679
18233
  {
17680
- className: cn(
17681
- "rounded-2xl px-3.5 py-2.5 text-sm leading-relaxed",
17682
- isCustomer ? "bg-foreground text-background" : "border border-border bg-background text-foreground",
17683
- isCustomer ? sameSenderAsPrev ? "rounded-tr" : "rounded-br" : sameSenderAsPrev ? "rounded-tl" : "rounded-bl",
17684
- optimistic && "opacity-70"
17685
- ),
17686
- children: [
17687
- !sameSenderAsPrev && /* @__PURE__ */ jsxRuntime.jsx(SenderChip, { sender: msg.sender_type, businessName }),
17688
- msg.reply_to && /* @__PURE__ */ jsxRuntime.jsxs(
17689
- "div",
17690
- {
17691
- className: cn(
17692
- "mb-1.5 flex gap-1.5 rounded-lg px-2 py-1 text-xs",
17693
- isCustomer ? "bg-background/15" : "bg-muted"
17694
- ),
17695
- children: [
17696
- /* @__PURE__ */ jsxRuntime.jsx(
17697
- "span",
17698
- {
17699
- className: cn(
17700
- "w-[3px] shrink-0 self-stretch rounded-full",
17701
- isCustomer ? "bg-background/40" : "bg-muted-foreground/40"
17702
- )
17703
- }
17704
- ),
17705
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate opacity-80", children: msg.reply_to.preview })
17706
- ]
17707
- }
17708
- ),
17709
- msg.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-1.5", msg.content && "mb-1.5"), children: msg.attachments.map((attachment, index) => {
17710
- const url = safeAttachmentUrl(attachment.url);
17711
- if (!url) return null;
17712
- return attachment.mime_type?.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx(
17713
- "img",
17714
- {
17715
- src: url,
17716
- alt: attachment.filename ?? "Photo",
17717
- loading: "lazy",
17718
- className: "max-h-48 max-w-full rounded-lg object-cover"
17719
- }
17720
- ) }, index) : /* @__PURE__ */ jsxRuntime.jsx(
17721
- "a",
17722
- {
17723
- href: url,
17724
- target: "_blank",
17725
- rel: "noreferrer",
17726
- className: "truncate text-xs underline",
17727
- children: attachment.filename ?? "Attachment"
17728
- },
17729
- index
17730
- );
17731
- }) }),
17732
- isCustomer ? msg.content && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap", children: msg.content }) : /* @__PURE__ */ jsxRuntime.jsx(
17733
- ChatMarkdown,
17734
- {
17735
- text: proseOf(msg.content),
17736
- className: "[&_p]:my-0 [&_p+p]:mt-1.5 [&_ul]:my-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:my-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:my-0.5 [&_h1]:text-sm [&_h1]:font-bold [&_h2]:text-sm [&_h2]:font-bold [&_h3]:text-sm [&_h3]:font-semibold [&_hr]:my-2 [&_table]:my-1 [&_table]:w-full [&_th]:pb-1 [&_th]:text-left [&_th]:text-[10px] [&_th]:font-semibold [&_th]:uppercase [&_td]:py-1 [&_td:last-child]:text-right [&_td:last-child]:font-semibold [&_td:last-child]:tabular-nums [&_a]:underline"
17737
- }
17738
- )
17739
- ]
18234
+ message: msg,
18235
+ reactions: reactionsByTarget.get(msg.id),
18236
+ businessName,
18237
+ group,
18238
+ delivery,
18239
+ onReply,
18240
+ avatar: /* @__PURE__ */ jsxRuntime.jsx(LetterAvatar, { name: businessName }),
18241
+ onQuoteMiss: async () => {
18242
+ onLoadOlder();
18243
+ return true;
18244
+ }
17740
18245
  }
17741
18246
  )
17742
- ]
17743
- }
17744
- ),
17745
- reactions && reactions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-0.5 flex gap-1", isCustomer ? "justify-end" : "justify-start"), children: reactions.map((reaction) => /* @__PURE__ */ jsxRuntime.jsx(
17746
- "span",
17747
- {
17748
- className: "rounded-full border border-border bg-background px-1.5 py-0.5 text-xs shadow-sm",
17749
- children: reaction.content
17750
- },
17751
- reaction.id
17752
- )) }),
17753
- msg.id === seenMessageId && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 text-right text-[10px] font-medium text-muted-foreground", children: "Seen" })
17754
- ] }, msg.id);
18247
+ ] })
18248
+ ]
18249
+ },
18250
+ msg.id
18251
+ );
17755
18252
  }),
17756
18253
  isSending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mr-auto mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) }),
17757
18254
  offerHuman && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -17776,24 +18273,6 @@ function MessageList({
17776
18273
  }
17777
18274
  );
17778
18275
  }
17779
- function sameDay(a, b) {
17780
- return new Date(a).toDateString() === new Date(b).toDateString();
17781
- }
17782
- function SenderChip({
17783
- sender,
17784
- businessName
17785
- }) {
17786
- if (sender === "bot") {
17787
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mb-1 inline-flex items-center gap-1 rounded bg-primary/10 px-1.5 py-0.5 text-[10px] font-semibold text-primary", children: [
17788
- /* @__PURE__ */ jsxRuntime.jsx(SparkleIcon, { className: "h-[11px] w-[11px]" }),
17789
- "AI"
17790
- ] });
17791
- }
17792
- if (sender === "agent") {
17793
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-[10px] font-semibold text-muted-foreground", children: businessName });
17794
- }
17795
- return null;
17796
- }
17797
18276
  function HoverRail({
17798
18277
  message,
17799
18278
  onReact,
@@ -18186,19 +18665,6 @@ function ReplyIcon({ className }) {
18186
18665
  }
18187
18666
  );
18188
18667
  }
18189
- function SparkleIcon({ className }) {
18190
- return /* @__PURE__ */ jsxRuntime.jsx(
18191
- "svg",
18192
- {
18193
- className,
18194
- viewBox: "0 0 24 24",
18195
- fill: "none",
18196
- stroke: "currentColor",
18197
- strokeWidth: 2.5,
18198
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" })
18199
- }
18200
- );
18201
- }
18202
18668
 
18203
18669
  // src/react/genui/catalog.ts
18204
18670
  function genUICatalog(registry) {
@@ -20023,7 +20489,7 @@ async function genUIFingerprint(manifest) {
20023
20489
 
20024
20490
  Object.defineProperty(exports, "getVariantDisplayName", {
20025
20491
  enumerable: true,
20026
- get: function () { return chunkHKN3YG76_js.getVariantDisplayName; }
20492
+ get: function () { return chunkQPRI2NII_js.getVariantDisplayName; }
20027
20493
  });
20028
20494
  Object.defineProperty(exports, "messagePreview", {
20029
20495
  enumerable: true,
@@ -20064,6 +20530,7 @@ exports.BookingPage = BookingPage;
20064
20530
  exports.BookingSummary = BookingSummary;
20065
20531
  exports.BookingsPage = BookingsPage;
20066
20532
  exports.BoxIcon24 = BoxIcon24;
20533
+ exports.BubbleTail = BubbleTail;
20067
20534
  exports.BundleProductCard = BundleProductCard;
20068
20535
  exports.BundleProductLayout = BundleProductLayout;
20069
20536
  exports.BundleSelector = BundleSelector;
@@ -20138,6 +20605,7 @@ exports.LeaseServiceCard = LeaseServiceCard;
20138
20605
  exports.LineItemDetails = LineItemDetails;
20139
20606
  exports.LocationPicker = LocationPicker;
20140
20607
  exports.MediaGallery = MediaGallery;
20608
+ exports.MessageBubble = MessageBubble;
20141
20609
  exports.MetadataStringList = MetadataStringList;
20142
20610
  exports.MobileAccountShell = MobileAccountShell;
20143
20611
  exports.MobileBackButton = MobileBackButton;
@@ -20172,6 +20640,7 @@ exports.ProductTemplate = ProductTemplate;
20172
20640
  exports.PropertiesTable = PropertiesTable;
20173
20641
  exports.QuantitySelector = QuantitySelector;
20174
20642
  exports.QuickAddButton = QuickAddButton;
20643
+ exports.QuoteBlock = QuoteBlock;
20175
20644
  exports.RecentlyViewed = RecentlyViewed;
20176
20645
  exports.RecommendationCarousel = RecommendationCarousel;
20177
20646
  exports.RelatedProductsSection = RelatedProductsSection;
@@ -20179,10 +20648,12 @@ exports.RentalServiceCard = RentalServiceCard;
20179
20648
  exports.ResourcePicker = ResourcePicker;
20180
20649
  exports.RetailProductCard = RetailProductCard;
20181
20650
  exports.RichText = RichText;
20651
+ exports.SWIPE_COMMIT_PX = SWIPE_COMMIT_PX;
20182
20652
  exports.SaleBadge = SaleBadge;
20183
20653
  exports.SalePrice = SalePrice;
20184
20654
  exports.SaleTeaser = SaleTeaser;
20185
20655
  exports.ScheduleServiceCard = ScheduleServiceCard;
20656
+ exports.Seam = Seam;
20186
20657
  exports.SearchInput = SearchInput;
20187
20658
  exports.SearchPage = SearchPage;
20188
20659
  exports.SearchTemplate = SearchTemplate;
@@ -20214,26 +20685,39 @@ exports.WelcomeCard = WelcomeCard;
20214
20685
  exports.WholesaleProductCard = WholesaleProductCard;
20215
20686
  exports.WholesaleProductLayout = WholesaleProductLayout;
20216
20687
  exports.WishlistButton = WishlistButton;
20688
+ exports.chatTimeline = chatTimeline;
20217
20689
  exports.clearOrdersCache = clearOrdersCache;
20218
20690
  exports.cn = cn;
20219
20691
  exports.createPlacesSessionToken = createPlacesSessionToken;
20692
+ exports.dayLabel = dayLabel;
20220
20693
  exports.defaultBoundaryKind = defaultBoundaryKind;
20694
+ exports.deliveryState = deliveryState;
20221
20695
  exports.genUICatalog = genUICatalog;
20222
20696
  exports.genUIFingerprint = genUIFingerprint;
20223
20697
  exports.genUIManifest = genUIManifest;
20224
20698
  exports.genUIManifestJson = genUIManifestJson;
20225
20699
  exports.getBoundaryLabels = getBoundaryLabels;
20700
+ exports.groupPosition = groupPosition;
20226
20701
  exports.isImageAttachment = isImageAttachment;
20702
+ exports.isOptimistic = isOptimistic;
20227
20703
  exports.isTerminalOrderStatus = isTerminalOrderStatus;
20704
+ exports.optimisticId = optimisticId;
20228
20705
  exports.parseGenUIProgram = parse;
20229
20706
  exports.partitionMessages = partitionMessages;
20707
+ exports.prefersReducedMotion = prefersReducedMotion;
20230
20708
  exports.prefetchProduct = prefetchProduct;
20231
20709
  exports.prefetchProducts = prefetchProducts;
20710
+ exports.proseOf = proseOf;
20232
20711
  exports.resolveBoundaryKind = resolveBoundaryKind;
20233
20712
  exports.roomToResource = roomToResource;
20234
20713
  exports.safeAttachmentUrl = safeAttachmentUrl;
20714
+ exports.sameDay = sameDay;
20235
20715
  exports.sanitizeRichTextHtml = sanitizeRichTextHtml;
20716
+ exports.scrollBehavior = scrollBehavior;
20236
20717
  exports.stripHtmlToText = stripHtmlToText;
20718
+ exports.swipeCommitted = swipeCommitted;
20719
+ exports.swipeProgress = swipeProgress;
20720
+ exports.swipeTravel = swipeTravel;
20237
20721
  exports.toAccountLineItem = toAccountLineItem;
20238
20722
  exports.toAccountLineItems = toAccountLineItems;
20239
20723
  exports.toAccountOrderView = toAccountOrderView;
@@ -20282,6 +20766,7 @@ exports.useServices = useServices;
20282
20766
  exports.useStoreCredit = useStoreCredit;
20283
20767
  exports.useSubscription = useSubscription;
20284
20768
  exports.useSubscriptions = useSubscriptions;
20769
+ exports.useSwipeReply = useSwipeReply;
20285
20770
  exports.useTaxonomies = useTaxonomies;
20286
20771
  exports.useTaxonomy = useTaxonomy;
20287
20772
  exports.useTaxonomyPath = useTaxonomyPath;