@fayz-ai/plugin-agenda 0.1.3 → 0.1.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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.cjs +412 -201
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +254 -48
  7. package/dist/index.js.map +1 -1
  8. package/dist/integrations/google-calendar/GoogleCalendarSettings.d.ts +3 -0
  9. package/dist/integrations/google-calendar/GoogleCalendarSettings.d.ts.map +1 -0
  10. package/dist/integrations/google-calendar/connector.d.ts +3 -0
  11. package/dist/integrations/google-calendar/connector.d.ts.map +1 -0
  12. package/dist/integrations/google-calendar/connectorDef.d.ts +3 -0
  13. package/dist/integrations/google-calendar/connectorDef.d.ts.map +1 -0
  14. package/dist/integrations/google-calendar/data/supabase.d.ts +16 -0
  15. package/dist/integrations/google-calendar/data/supabase.d.ts.map +1 -0
  16. package/dist/integrations/google-calendar/index.d.ts +8 -0
  17. package/dist/integrations/google-calendar/index.d.ts.map +1 -0
  18. package/dist/integrations/google-calendar/integration.test.d.ts +2 -0
  19. package/dist/integrations/google-calendar/integration.test.d.ts.map +1 -0
  20. package/dist/integrations/google-calendar/mapping.d.ts +25 -0
  21. package/dist/integrations/google-calendar/mapping.d.ts.map +1 -0
  22. package/dist/integrations/google-calendar/types.d.ts +36 -0
  23. package/dist/integrations/google-calendar/types.d.ts.map +1 -0
  24. package/package.json +10 -7
  25. package/src/index.ts +12 -2
  26. package/src/integrations/google-calendar/GoogleCalendarSettings.tsx +136 -0
  27. package/src/integrations/google-calendar/connector.ts +20 -0
  28. package/src/integrations/google-calendar/connectorDef.tsx +94 -0
  29. package/src/integrations/google-calendar/data/supabase.ts +74 -0
  30. package/src/integrations/google-calendar/index.ts +36 -0
  31. package/src/integrations/google-calendar/integration.test.ts +74 -0
  32. package/src/integrations/google-calendar/mapping.ts +43 -0
  33. package/src/integrations/google-calendar/migrations/001_google_calendar.sql +94 -0
  34. package/src/integrations/google-calendar/types.ts +31 -0
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkSYDBDI3Q_cjs = require('./chunk-SYDBDI3Q.cjs');
4
- var React10 = require('react');
4
+ var React11 = require('react');
5
5
  var core = require('@fayz-ai/core');
6
6
  var saas = require('@fayz-ai/saas');
7
7
  var FullCalendar = require('@fullcalendar/react');
@@ -19,7 +19,7 @@ var vanilla = require('zustand/vanilla');
19
19
 
20
20
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
21
 
22
- var React10__default = /*#__PURE__*/_interopDefault(React10);
22
+ var React11__default = /*#__PURE__*/_interopDefault(React11);
23
23
  var FullCalendar__default = /*#__PURE__*/_interopDefault(FullCalendar);
24
24
  var dayGridPlugin__default = /*#__PURE__*/_interopDefault(dayGridPlugin);
25
25
  var timeGridPlugin__default = /*#__PURE__*/_interopDefault(timeGridPlugin);
@@ -431,10 +431,10 @@ function toDateLocale(locale) {
431
431
  }
432
432
  function MiniCalendar({ selectedDate, onDateSelect, onMonthChange }) {
433
433
  const locale = core.getCurrentLocale();
434
- const [viewMonth, setViewMonth] = React10__default.default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
434
+ const [viewMonth, setViewMonth] = React11__default.default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
435
435
  const monthLabel = viewMonth.toLocaleDateString(toDateLocale(locale), { month: "long", year: "numeric" });
436
436
  const dayLabels = DAY_LABELS[locale] ?? DAY_LABELS.en;
437
- const weeks = React10.useMemo(() => {
437
+ const weeks = React11.useMemo(() => {
438
438
  const year = viewMonth.getFullYear();
439
439
  const month = viewMonth.getMonth();
440
440
  const firstDay = new Date(year, month, 1);
@@ -505,14 +505,14 @@ function SearchCombobox({
505
505
  loading,
506
506
  onFocus: onFocusProp
507
507
  }) {
508
- const [open, setOpen] = React10.useState(false);
509
- const [activeIndex, setActiveIndex] = React10.useState(-1);
510
- const [expanded, setExpanded] = React10.useState(!inlineLabel);
511
- const [dropRect, setDropRect] = React10.useState(null);
512
- const inputRef = React10.useRef(null);
513
- const wrapperRef = React10.useRef(null);
514
- const listRef = React10.useRef(null);
515
- React10.useEffect(() => {
508
+ const [open, setOpen] = React11.useState(false);
509
+ const [activeIndex, setActiveIndex] = React11.useState(-1);
510
+ const [expanded, setExpanded] = React11.useState(!inlineLabel);
511
+ const [dropRect, setDropRect] = React11.useState(null);
512
+ const inputRef = React11.useRef(null);
513
+ const wrapperRef = React11.useRef(null);
514
+ const listRef = React11.useRef(null);
515
+ React11.useEffect(() => {
516
516
  if (value && inlineLabel) setExpanded(true);
517
517
  if (!value && inlineLabel && !open) setExpanded(false);
518
518
  }, [value, open]);
@@ -521,13 +521,13 @@ function SearchCombobox({
521
521
  }
522
522
  const showCreate = open && allowCreate && onCreateNew && value.trim().length > 0 && !options.some((o) => o.label.toLowerCase() === value.trim().toLowerCase());
523
523
  const totalItems = options.length + (showCreate ? 1 : 0);
524
- React10.useEffect(() => {
524
+ React11.useEffect(() => {
525
525
  setActiveIndex(-1);
526
526
  }, [options]);
527
- React10.useEffect(() => {
527
+ React11.useEffect(() => {
528
528
  if ((options.length > 0 || showCreate || loading) && document.activeElement === inputRef.current) setOpen(true);
529
529
  }, [options, showCreate, loading]);
530
- const handleKeyDown = React10.useCallback((e) => {
530
+ const handleKeyDown = React11.useCallback((e) => {
531
531
  if (!open || totalItems === 0) {
532
532
  if (e.key === "ArrowDown" && totalItems > 0) {
533
533
  e.preventDefault();
@@ -564,7 +564,7 @@ function SearchCombobox({
564
564
  break;
565
565
  }
566
566
  }, [open, options, totalItems, activeIndex, onSelect, showCreate, onCreateNew, value]);
567
- React10.useEffect(() => {
567
+ React11.useEffect(() => {
568
568
  if (activeIndex < 0 || !listRef.current) return;
569
569
  const items = listRef.current.children;
570
570
  if (items[activeIndex]) items[activeIndex].scrollIntoView({ block: "nearest" });
@@ -724,23 +724,23 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
724
724
  const t = core.useTranslation();
725
725
  const config = useAgendaConfig();
726
726
  const bridge = config.financialBridge;
727
- const [visible, setVisible] = React10.useState(false);
728
- const [loading, setLoading] = React10.useState(true);
729
- const [detail, setDetail] = React10.useState(null);
730
- const [selectedTypeId, setSelectedTypeId] = React10.useState("");
731
- const [paymentTypes, setPaymentTypes] = React10.useState([]);
732
- const [bankAccounts, setBankAccounts] = React10.useState([]);
733
- const [filteredMethods, setFilteredMethods] = React10.useState([]);
734
- const [selectedBankId, setSelectedBankId] = React10.useState("");
735
- const [paymentMethodId, setPaymentMethodId] = React10.useState("");
736
- const [cardBrand, setCardBrand] = React10.useState("");
737
- const [cardInstallments, setCardInstallments] = React10.useState(1);
738
- const [processing, setProcessing] = React10.useState(false);
739
- const [justPaid, setJustPaid] = React10.useState(false);
740
- React10.useEffect(() => {
727
+ const [visible, setVisible] = React11.useState(false);
728
+ const [loading, setLoading] = React11.useState(true);
729
+ const [detail, setDetail] = React11.useState(null);
730
+ const [selectedTypeId, setSelectedTypeId] = React11.useState("");
731
+ const [paymentTypes, setPaymentTypes] = React11.useState([]);
732
+ const [bankAccounts, setBankAccounts] = React11.useState([]);
733
+ const [filteredMethods, setFilteredMethods] = React11.useState([]);
734
+ const [selectedBankId, setSelectedBankId] = React11.useState("");
735
+ const [paymentMethodId, setPaymentMethodId] = React11.useState("");
736
+ const [cardBrand, setCardBrand] = React11.useState("");
737
+ const [cardInstallments, setCardInstallments] = React11.useState(1);
738
+ const [processing, setProcessing] = React11.useState(false);
739
+ const [justPaid, setJustPaid] = React11.useState(false);
740
+ React11.useEffect(() => {
741
741
  requestAnimationFrame(() => setVisible(true));
742
742
  }, []);
743
- React10.useEffect(() => {
743
+ React11.useEffect(() => {
744
744
  let cancelled = false;
745
745
  setLoading(true);
746
746
  Promise.all([
@@ -1043,9 +1043,9 @@ function formatCompactDate(dateStr, locale) {
1043
1043
  });
1044
1044
  }
1045
1045
  function InlineNumber({ value, onChange, min = 0, step = 1, className, disabled, tooltip }) {
1046
- const [draft, setDraft] = React10.useState(String(value));
1047
- const [focused, setFocused] = React10.useState(false);
1048
- React10.useEffect(() => {
1046
+ const [draft, setDraft] = React11.useState(String(value));
1047
+ const [focused, setFocused] = React11.useState(false);
1048
+ React11.useEffect(() => {
1049
1049
  if (!focused) setDraft(String(value));
1050
1050
  }, [value, focused]);
1051
1051
  function commit() {
@@ -1089,11 +1089,11 @@ function InlineNumber({ value, onChange, min = 0, step = 1, className, disabled,
1089
1089
  ] }) });
1090
1090
  }
1091
1091
  function StatusSelect({ value, onChange, statuses, bookingDate }) {
1092
- const [open, setOpen] = React10.useState(false);
1093
- const ref = React10.useRef(null);
1094
- const dropdownRef = React10.useRef(null);
1092
+ const [open, setOpen] = React11.useState(false);
1093
+ const ref = React11.useRef(null);
1094
+ const dropdownRef = React11.useRef(null);
1095
1095
  const current = statuses.find((s) => s.value === value);
1096
- React10.useEffect(() => {
1096
+ React11.useEffect(() => {
1097
1097
  if (!open) return;
1098
1098
  const handler = (e) => {
1099
1099
  const target = e.target;
@@ -1104,8 +1104,8 @@ function StatusSelect({ value, onChange, statuses, bookingDate }) {
1104
1104
  document.addEventListener("mousedown", handler);
1105
1105
  return () => document.removeEventListener("mousedown", handler);
1106
1106
  }, [open]);
1107
- const btnRef = React10.useRef(null);
1108
- const [dropRect, setDropRect] = React10.useState(null);
1107
+ const btnRef = React11.useRef(null);
1108
+ const [dropRect, setDropRect] = React11.useState(null);
1109
1109
  function handleOpen() {
1110
1110
  if (btnRef.current) setDropRect(btnRef.current.getBoundingClientRect());
1111
1111
  setOpen((p) => !p);
@@ -1165,10 +1165,10 @@ function StatusSelect({ value, onChange, statuses, bookingDate }) {
1165
1165
  }
1166
1166
  function ProfessionalSelect({ value, onChange, professionals }) {
1167
1167
  const t = core.useTranslation();
1168
- const [open, setOpen] = React10.useState(false);
1169
- const ref = React10.useRef(null);
1168
+ const [open, setOpen] = React11.useState(false);
1169
+ const ref = React11.useRef(null);
1170
1170
  const current = professionals.find((p) => p.id === value);
1171
- React10.useEffect(() => {
1171
+ React11.useEffect(() => {
1172
1172
  if (!open) return;
1173
1173
  const handler = (e) => {
1174
1174
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -1206,10 +1206,10 @@ function ProfessionalSelect({ value, onChange, professionals }) {
1206
1206
  }
1207
1207
  function LocationSelect({ value, onChange, locations }) {
1208
1208
  const t = core.useTranslation();
1209
- const [open, setOpen] = React10.useState(false);
1210
- const ref = React10.useRef(null);
1209
+ const [open, setOpen] = React11.useState(false);
1210
+ const ref = React11.useRef(null);
1211
1211
  const current = locations.find((l) => l.id === value);
1212
- React10.useEffect(() => {
1212
+ React11.useEffect(() => {
1213
1213
  if (!open) return;
1214
1214
  const handler = (e) => {
1215
1215
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -1249,8 +1249,8 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1249
1249
  const t = core.useTranslation();
1250
1250
  const locale = core.getCurrentLocale();
1251
1251
  const config = useAgendaConfig();
1252
- const provider = useAgendaProvider();
1253
- const initialSnapshot = React10.useRef("");
1252
+ const provider2 = useAgendaProvider();
1253
+ const initialSnapshot = React11.useRef("");
1254
1254
  const createBooking = useAgendaStore((s) => s.createBooking);
1255
1255
  const updateBooking = useAgendaStore((s) => s.updateBooking);
1256
1256
  const deleteBooking = useAgendaStore((s) => s.deleteBooking);
@@ -1258,54 +1258,54 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1258
1258
  const agendaDateRange = useAgendaStore((s) => s.dateRange);
1259
1259
  const professionals = useAgendaStore((s) => s.professionals);
1260
1260
  const storeLocations = useAgendaStore((s) => s.locations);
1261
- const [loading, setLoading] = React10.useState(mode === "edit");
1262
- const [bookingType, setBookingType] = React10.useState(prefill?.kind ?? "appointment");
1263
- const [clientId, setClientId] = React10.useState(prefill?.clientId ?? "");
1264
- const [clientSearch, setClientSearch] = React10.useState("");
1265
- const [clientPhone, setClientPhone] = React10.useState("");
1266
- const [professionalId, setProfessionalId] = React10.useState(prefill?.professionalId ?? "");
1267
- const [locationId, setLocationId] = React10.useState(prefill?.locationId ?? "");
1268
- const [services, setServices] = React10.useState([]);
1269
- const [serviceSearch, setServiceSearch] = React10.useState("");
1270
- const [date, setDate] = React10.useState(() => {
1261
+ const [loading, setLoading] = React11.useState(mode === "edit");
1262
+ const [bookingType, setBookingType] = React11.useState(prefill?.kind ?? "appointment");
1263
+ const [clientId, setClientId] = React11.useState(prefill?.clientId ?? "");
1264
+ const [clientSearch, setClientSearch] = React11.useState("");
1265
+ const [clientPhone, setClientPhone] = React11.useState("");
1266
+ const [professionalId, setProfessionalId] = React11.useState(prefill?.professionalId ?? "");
1267
+ const [locationId, setLocationId] = React11.useState(prefill?.locationId ?? "");
1268
+ const [services, setServices] = React11.useState([]);
1269
+ const [serviceSearch, setServiceSearch] = React11.useState("");
1270
+ const [date, setDate] = React11.useState(() => {
1271
1271
  if (prefill?.startsAt) return prefill.startsAt.slice(0, 10);
1272
1272
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1273
1273
  });
1274
- const [startTime, setStartTime] = React10.useState(() => {
1274
+ const [startTime, setStartTime] = React11.useState(() => {
1275
1275
  if (prefill?.startsAt) {
1276
1276
  const d = new Date(prefill.startsAt);
1277
1277
  return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
1278
1278
  }
1279
1279
  return "09:00";
1280
1280
  });
1281
- const [status, setStatus] = React10.useState("scheduled");
1282
- const [notes, setNotes] = React10.useState("");
1283
- const [showNotes, setShowNotes] = React10.useState(false);
1284
- const [saving, setSaving] = React10.useState(false);
1285
- const [conflict, setConflict] = React10.useState(false);
1286
- const [quickCreate, setQuickCreate] = React10.useState(false);
1287
- const [newClientName, setNewClientName] = React10.useState("");
1288
- const [newClientPhone, setNewClientPhone] = React10.useState("");
1289
- const [newClientEmail, setNewClientEmail] = React10.useState("");
1290
- const [creatingClient, setCreatingClient] = React10.useState(false);
1291
- const [clientOptions, setClientOptions] = React10.useState([]);
1292
- const [clientSearching, setClientSearching] = React10.useState(false);
1293
- const [serviceOptions, setServiceOptions] = React10.useState([]);
1294
- const [initialServiceOptions, setInitialServiceOptions] = React10.useState([]);
1295
- const [editingDate, setEditingDate] = React10.useState(false);
1296
- const [editingTime, setEditingTime] = React10.useState(false);
1297
- const [confirmingDelete, setConfirmingDelete] = React10.useState(false);
1298
- const [deleting, setDeleting] = React10.useState(false);
1299
- const [editOrderId, setEditOrderId] = React10.useState(null);
1300
- const [editOrderTotal, setEditOrderTotal] = React10.useState(0);
1301
- const [editPaymentStatus, setEditPaymentStatus] = React10.useState("none");
1302
- const [paymentStatusLoading, setPaymentStatusLoading] = React10.useState(false);
1303
- const [modalTab, setModalTab] = React10.useState("appointment");
1304
- const [clientData, setClientData] = React10.useState(null);
1305
- const [clientDataLoading, setClientDataLoading] = React10.useState(false);
1306
- const [clientEditing, setClientEditing] = React10.useState(false);
1281
+ const [status, setStatus] = React11.useState("scheduled");
1282
+ const [notes, setNotes] = React11.useState("");
1283
+ const [showNotes, setShowNotes] = React11.useState(false);
1284
+ const [saving, setSaving] = React11.useState(false);
1285
+ const [conflict, setConflict] = React11.useState(false);
1286
+ const [quickCreate, setQuickCreate] = React11.useState(false);
1287
+ const [newClientName, setNewClientName] = React11.useState("");
1288
+ const [newClientPhone, setNewClientPhone] = React11.useState("");
1289
+ const [newClientEmail, setNewClientEmail] = React11.useState("");
1290
+ const [creatingClient, setCreatingClient] = React11.useState(false);
1291
+ const [clientOptions, setClientOptions] = React11.useState([]);
1292
+ const [clientSearching, setClientSearching] = React11.useState(false);
1293
+ const [serviceOptions, setServiceOptions] = React11.useState([]);
1294
+ const [initialServiceOptions, setInitialServiceOptions] = React11.useState([]);
1295
+ const [editingDate, setEditingDate] = React11.useState(false);
1296
+ const [editingTime, setEditingTime] = React11.useState(false);
1297
+ const [confirmingDelete, setConfirmingDelete] = React11.useState(false);
1298
+ const [deleting, setDeleting] = React11.useState(false);
1299
+ const [editOrderId, setEditOrderId] = React11.useState(null);
1300
+ const [editOrderTotal, setEditOrderTotal] = React11.useState(0);
1301
+ const [editPaymentStatus, setEditPaymentStatus] = React11.useState("none");
1302
+ const [paymentStatusLoading, setPaymentStatusLoading] = React11.useState(false);
1303
+ const [modalTab, setModalTab] = React11.useState("appointment");
1304
+ const [clientData, setClientData] = React11.useState(null);
1305
+ const [clientDataLoading, setClientDataLoading] = React11.useState(false);
1306
+ const [clientEditing, setClientEditing] = React11.useState(false);
1307
1307
  const activeType = config.bookingTypes.find((bt) => bt.id === bookingType) ?? config.bookingTypes[0];
1308
- React10.useEffect(() => {
1308
+ React11.useEffect(() => {
1309
1309
  if (!open) return;
1310
1310
  setClientId(prefill?.clientId ?? "");
1311
1311
  setClientSearch("");
@@ -1350,10 +1350,10 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1350
1350
  return "09:00";
1351
1351
  });
1352
1352
  }, [open]);
1353
- React10.useEffect(() => {
1353
+ React11.useEffect(() => {
1354
1354
  if (!open || mode !== "edit" || !bookingId) return;
1355
1355
  setLoading(true);
1356
- provider.getBookingById(bookingId).then((b) => {
1356
+ provider2.getBookingById(bookingId).then((b) => {
1357
1357
  if (!b) {
1358
1358
  setLoading(false);
1359
1359
  return;
@@ -1403,7 +1403,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1403
1403
  }
1404
1404
  }).catch(() => setLoading(false));
1405
1405
  }, [open, mode, bookingId]);
1406
- React10.useEffect(() => {
1406
+ React11.useEffect(() => {
1407
1407
  if (modalTab !== "client" || !clientId || !config.contactLookup || clientData) return;
1408
1408
  setClientDataLoading(true);
1409
1409
  config.contactLookup.getById(clientId).then((result) => {
@@ -1411,7 +1411,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1411
1411
  setClientDataLoading(false);
1412
1412
  }).catch(() => setClientDataLoading(false));
1413
1413
  }, [modalTab, clientId]);
1414
- React10.useEffect(() => {
1414
+ React11.useEffect(() => {
1415
1415
  if (!open || !config.serviceLookup) return;
1416
1416
  const lookup = config.serviceLookup;
1417
1417
  const fetch = lookup.list ? () => lookup.list() : () => lookup.search("");
@@ -1420,7 +1420,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1420
1420
  setInitialServiceOptions(opts);
1421
1421
  }).catch(() => setInitialServiceOptions([]));
1422
1422
  }, [open]);
1423
- React10.useEffect(() => {
1423
+ React11.useEffect(() => {
1424
1424
  if (!config.contactLookup || clientSearch.length < 1 || clientId) {
1425
1425
  setClientOptions([]);
1426
1426
  setClientSearching(false);
@@ -1438,7 +1438,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1438
1438
  }, 250);
1439
1439
  return () => clearTimeout(timer);
1440
1440
  }, [clientSearch, clientId]);
1441
- React10.useEffect(() => {
1441
+ React11.useEffect(() => {
1442
1442
  if (!config.serviceLookup || serviceSearch.length < 1) {
1443
1443
  setServiceOptions([]);
1444
1444
  return;
@@ -1454,25 +1454,25 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1454
1454
  return () => clearTimeout(timer);
1455
1455
  }, [serviceSearch]);
1456
1456
  const serviceDuration = services.reduce((sum, s) => sum + s.durationMinutes, 0);
1457
- const selectionDuration = React10.useMemo(() => {
1457
+ const selectionDuration = React11.useMemo(() => {
1458
1458
  if (!prefill?.startsAt || !prefill?.endsAt) return 0;
1459
1459
  return Math.round((new Date(prefill.endsAt).getTime() - new Date(prefill.startsAt).getTime()) / 6e4);
1460
1460
  }, [prefill?.startsAt, prefill?.endsAt]);
1461
1461
  const totalDuration = serviceDuration > 0 ? serviceDuration : selectionDuration;
1462
1462
  const totalPrice = services.reduce((sum, s) => sum + s.price, 0);
1463
1463
  const { currency } = config;
1464
- const endTime = React10.useMemo(() => {
1464
+ const endTime = React11.useMemo(() => {
1465
1465
  const [h, m] = startTime.split(":").map(Number);
1466
1466
  const total = h * 60 + m + totalDuration;
1467
1467
  return `${String(Math.floor(total / 60) % 24).padStart(2, "0")}:${String(total % 60).padStart(2, "0")}`;
1468
1468
  }, [startTime, totalDuration]);
1469
- React10.useEffect(() => {
1469
+ React11.useEffect(() => {
1470
1470
  if (!professionalId || totalDuration === 0) {
1471
1471
  setConflict(false);
1472
1472
  return;
1473
1473
  }
1474
1474
  const timer = setTimeout(() => {
1475
- provider.checkConflict({
1475
+ provider2.checkConflict({
1476
1476
  assigneeId: professionalId,
1477
1477
  startsAt: `${date}T${startTime}:00`,
1478
1478
  endsAt: `${date}T${endTime}:00`,
@@ -1541,7 +1541,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1541
1541
  setDeleting(false);
1542
1542
  }
1543
1543
  const isPaidBooking = editPaymentStatus === "paid";
1544
- const formSnapshot = React10.useMemo(
1544
+ const formSnapshot = React11.useMemo(
1545
1545
  () => JSON.stringify({ clientId, professionalId, locationId, date, startTime, status, notes, services: services.map((s) => ({ id: s.serviceId, dur: s.durationMinutes, price: s.price })) }),
1546
1546
  [clientId, professionalId, locationId, date, startTime, status, notes, services]
1547
1547
  );
@@ -1667,8 +1667,8 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1667
1667
  onCancel: () => setClientEditing(false),
1668
1668
  onSubmit: async (data) => {
1669
1669
  try {
1670
- const { getSupabaseClientOptional: getSupabaseClientOptional3 } = await import('@fayz-ai/core');
1671
- const supabase = getSupabaseClientOptional3();
1670
+ const { getSupabaseClientOptional: getSupabaseClientOptional4 } = await import('@fayz-ai/core');
1671
+ const supabase = getSupabaseClientOptional4();
1672
1672
  if (!supabase) return;
1673
1673
  const dbData = {};
1674
1674
  for (const [k, v] of Object.entries(data)) {
@@ -1815,9 +1815,9 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1815
1815
  onClick: async () => {
1816
1816
  setCreatingClient(true);
1817
1817
  try {
1818
- const { getSupabaseClientOptional: getSupabaseClientOptional3 } = await import('@fayz-ai/core');
1818
+ const { getSupabaseClientOptional: getSupabaseClientOptional4 } = await import('@fayz-ai/core');
1819
1819
  const { getAgendaTenantId: getAgendaTenantId2 } = await import('./tenant-222EHYUC.cjs');
1820
- const supabase = getSupabaseClientOptional3();
1820
+ const supabase = getSupabaseClientOptional4();
1821
1821
  const tenantId = getAgendaTenantId2();
1822
1822
  if (!supabase || !tenantId) throw new Error("Not initialized");
1823
1823
  const { data: personRow, error: personError } = await supabase.schema("saas_core").from("persons").insert({
@@ -1840,8 +1840,8 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, onClose,
1840
1840
  setClientSearch(personRow.name);
1841
1841
  setQuickCreate(false);
1842
1842
  } catch (err) {
1843
- const { toast: toast2 } = await import('@fayz-ai/ui');
1844
- toast2.error(t("agenda.appointment.createClientFailed"), { description: err?.message });
1843
+ const { toast: toast3 } = await import('@fayz-ai/ui');
1844
+ toast3.error(t("agenda.appointment.createClientFailed"), { description: err?.message });
1845
1845
  }
1846
1846
  setCreatingClient(false);
1847
1847
  },
@@ -2060,19 +2060,19 @@ function FloatingPanel({
2060
2060
  children,
2061
2061
  zIndex = 100
2062
2062
  }) {
2063
- const ref = React10.useRef(null);
2064
- const [phase, setPhase] = React10.useState("visible");
2065
- const phaseRef = React10.useRef("visible");
2063
+ const ref = React11.useRef(null);
2064
+ const [phase, setPhase] = React11.useState("visible");
2065
+ const phaseRef = React11.useRef("visible");
2066
2066
  phaseRef.current = phase;
2067
- const onCloseRef = React10.useRef(onClose);
2067
+ const onCloseRef = React11.useRef(onClose);
2068
2068
  onCloseRef.current = onClose;
2069
- const expandCallbackRef = React10.useRef(null);
2070
- const dismiss = React10.useCallback(() => {
2069
+ const expandCallbackRef = React11.useRef(null);
2070
+ const dismiss = React11.useCallback(() => {
2071
2071
  if (phaseRef.current !== "visible") return;
2072
2072
  setPhase("dismissing");
2073
2073
  setTimeout(() => onCloseRef.current(), 150);
2074
2074
  }, []);
2075
- const expandThen = React10.useCallback((callback) => {
2075
+ const expandThen = React11.useCallback((callback) => {
2076
2076
  if (phaseRef.current !== "visible") return;
2077
2077
  expandCallbackRef.current = callback;
2078
2078
  setPhase("expanding");
@@ -2081,7 +2081,7 @@ function FloatingPanel({
2081
2081
  onCloseRef.current();
2082
2082
  }, 220);
2083
2083
  }, []);
2084
- React10.useEffect(() => {
2084
+ React11.useEffect(() => {
2085
2085
  function handleClick(e) {
2086
2086
  if (phaseRef.current !== "visible") return;
2087
2087
  if (ref.current && !ref.current.contains(e.target)) {
@@ -2132,10 +2132,10 @@ function fmtCurrency2(amount, locale, code) {
2132
2132
  return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(amount);
2133
2133
  }
2134
2134
  function PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }) {
2135
- const [open, setOpen] = React10.useState(false);
2136
- const ref = React10.useRef(null);
2135
+ const [open, setOpen] = React11.useState(false);
2136
+ const ref = React11.useRef(null);
2137
2137
  const current = statuses.find((s) => s.value === value);
2138
- React10.useEffect(() => {
2138
+ React11.useEffect(() => {
2139
2139
  if (!open) return;
2140
2140
  const h = (e) => {
2141
2141
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -2188,8 +2188,8 @@ function AppointmentPopover({ booking, position, onClose, onEdit }) {
2188
2188
  const deleteBooking = useAgendaStore((s) => s.deleteBooking);
2189
2189
  const updateStatus = useAgendaStore((s) => s.updateBookingStatus);
2190
2190
  const openModal = useAgendaStore((s) => s.openAppointmentModal);
2191
- const [confirmingDelete, setConfirmingDelete] = React10.useState(false);
2192
- const [deleting, setDeleting] = React10.useState(false);
2191
+ const [confirmingDelete, setConfirmingDelete] = React11.useState(false);
2192
+ const [deleting, setDeleting] = React11.useState(false);
2193
2193
  const statusConfig = config.statuses.find((s) => s.value === booking.status);
2194
2194
  const color = statusConfig?.color ?? "#6b7280";
2195
2195
  const timeRange = `${fmtTime(booking.startsAt)}${booking.endsAt ? " \u2013 " + fmtTime(booking.endsAt) : ""}`;
@@ -2347,9 +2347,9 @@ function Tooltip2({ anchor, label }) {
2347
2347
  );
2348
2348
  }
2349
2349
  function StatusDot({ color, label, isActive, disabled, onClick }) {
2350
- const [hover, setHover] = React10.useState(false);
2351
- const btnRef = React10.useRef(null);
2352
- const [rect, setRect] = React10.useState(null);
2350
+ const [hover, setHover] = React11.useState(false);
2351
+ const btnRef = React11.useRef(null);
2352
+ const [rect, setRect] = React11.useState(null);
2353
2353
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2354
2354
  /* @__PURE__ */ jsxRuntime.jsx(
2355
2355
  "button",
@@ -2376,8 +2376,8 @@ function EventContextMenu({ booking, position, onClose, onEdit }) {
2376
2376
  const config = useAgendaConfig();
2377
2377
  const updateStatus = useAgendaStore((s) => s.updateBookingStatus);
2378
2378
  const deleteBooking = useAgendaStore((s) => s.deleteBooking);
2379
- const [confirming, setConfirming] = React10.useState(false);
2380
- const [deleting, setDeleting] = React10.useState(false);
2379
+ const [confirming, setConfirming] = React11.useState(false);
2380
+ const [deleting, setDeleting] = React11.useState(false);
2381
2381
  async function handleDelete() {
2382
2382
  setDeleting(true);
2383
2383
  try {
@@ -2592,7 +2592,7 @@ function CalendarView() {
2592
2592
  const t = core.useTranslation();
2593
2593
  const currentLocale = core.getCurrentLocale();
2594
2594
  const fcLocale = currentLocale === "pt-BR" ? ptBrLocale__default.default : void 0;
2595
- const calendarRef = React10.useRef(null);
2595
+ const calendarRef = React11.useRef(null);
2596
2596
  const prefs = saas.usePluginPrefs("agenda", { calendarView: config.defaultCalendarView ?? "resourceTimeGridWeek" });
2597
2597
  const agendaSettings = useAgendaSettings();
2598
2598
  const effectiveBusinessHours = {
@@ -2618,28 +2618,28 @@ function CalendarView() {
2618
2618
  const _openModal = useAgendaStore((s) => s.openAppointmentModal);
2619
2619
  const closeModal = useAgendaStore((s) => s.closeAppointmentModal);
2620
2620
  const modalState = useAgendaStore((s) => s.appointmentModal);
2621
- const [selectedBooking, setSelectedBooking] = React10.useState(null);
2622
- const [popoverAnchor, setPopoverAnchor] = React10.useState(null);
2623
- const [popoverVisible, _setPopoverVisible] = React10.useState(false);
2624
- const popoverVisibleRef = React10.useRef(false);
2625
- const setPopoverVisible = React10.useCallback((v) => {
2621
+ const [selectedBooking, setSelectedBooking] = React11.useState(null);
2622
+ const [popoverAnchor, setPopoverAnchor] = React11.useState(null);
2623
+ const [popoverVisible, _setPopoverVisible] = React11.useState(false);
2624
+ const popoverVisibleRef = React11.useRef(false);
2625
+ const setPopoverVisible = React11.useCallback((v) => {
2626
2626
  popoverVisibleRef.current = v;
2627
2627
  _setPopoverVisible(v);
2628
2628
  }, []);
2629
- const [contextMenu, setContextMenu] = React10.useState(null);
2630
- const [contextMenuVisible, _setContextMenuVisible] = React10.useState(false);
2631
- const contextMenuVisibleRef = React10.useRef(false);
2632
- const setContextMenuVisible = React10.useCallback((v) => {
2629
+ const [contextMenu, setContextMenu] = React11.useState(null);
2630
+ const [contextMenuVisible, _setContextMenuVisible] = React11.useState(false);
2631
+ const contextMenuVisibleRef = React11.useRef(false);
2632
+ const setContextMenuVisible = React11.useCallback((v) => {
2633
2633
  contextMenuVisibleRef.current = v;
2634
2634
  _setContextMenuVisible(v);
2635
2635
  }, []);
2636
- const [scheduleConfirm, setScheduleConfirm] = React10.useState(null);
2637
- const [calendarTitle, setCalendarTitle] = React10.useState("");
2638
- const [selectedDate, setSelectedDate] = React10.useState(/* @__PURE__ */ new Date());
2639
- const [profSectionOpen, setProfSectionOpen] = React10.useState(true);
2640
- const [statusSectionOpen, setStatusSectionOpen] = React10.useState(false);
2641
- const [visibleRange, setVisibleRange] = React10.useState(null);
2642
- const openModal = React10.useCallback((...args) => {
2636
+ const [scheduleConfirm, setScheduleConfirm] = React11.useState(null);
2637
+ const [calendarTitle, setCalendarTitle] = React11.useState("");
2638
+ const [selectedDate, setSelectedDate] = React11.useState(/* @__PURE__ */ new Date());
2639
+ const [profSectionOpen, setProfSectionOpen] = React11.useState(true);
2640
+ const [statusSectionOpen, setStatusSectionOpen] = React11.useState(false);
2641
+ const [visibleRange, setVisibleRange] = React11.useState(null);
2642
+ const openModal = React11.useCallback((...args) => {
2643
2643
  setPopoverVisible(false);
2644
2644
  setSelectedBooking(null);
2645
2645
  setPopoverAnchor(null);
@@ -2647,17 +2647,17 @@ function CalendarView() {
2647
2647
  setContextMenu(null);
2648
2648
  _openModal(...args);
2649
2649
  }, [_openModal]);
2650
- const statusColors = React10.useMemo(() => {
2650
+ const statusColors = React11.useMemo(() => {
2651
2651
  const map = {};
2652
2652
  for (const s of config.statuses) map[s.value] = s.color;
2653
2653
  return map;
2654
2654
  }, [config.statuses]);
2655
- React10.useEffect(() => {
2655
+ React11.useEffect(() => {
2656
2656
  fetchProfessionals();
2657
2657
  fetchSchedules();
2658
2658
  if (config.modules.locationSelection) fetchLocations();
2659
2659
  }, []);
2660
- const resources = React10.useMemo(() => {
2660
+ const resources = React11.useMemo(() => {
2661
2661
  const filtered = selectedProfIds.length > 0 ? professionals.filter((p) => selectedProfIds.includes(p.id)) : professionals;
2662
2662
  return filtered.map((p) => ({
2663
2663
  id: p.id,
@@ -2665,29 +2665,29 @@ function CalendarView() {
2665
2665
  extendedProps: { avatarUrl: p.avatarUrl, locationName: p.locationName }
2666
2666
  }));
2667
2667
  }, [professionals, selectedProfIds]);
2668
- const bookingEvents = React10.useMemo(() => bookings.map((b) => bookingToEvent(b, statusColors)), [bookings, statusColors]);
2669
- const allLocations = React10.useMemo(() => {
2668
+ const bookingEvents = React11.useMemo(() => bookings.map((b) => bookingToEvent(b, statusColors)), [bookings, statusColors]);
2669
+ const allLocations = React11.useMemo(() => {
2670
2670
  const map = /* @__PURE__ */ new Map();
2671
2671
  for (const loc of config.locations) map.set(loc.id, loc.name);
2672
2672
  for (const loc of storeLocations) map.set(loc.id, loc.name);
2673
2673
  return map;
2674
2674
  }, [config.locations, storeLocations]);
2675
- const locationMap = React10.useMemo(() => {
2675
+ const locationMap = React11.useMemo(() => {
2676
2676
  if (!config.modules.locationSelection || allLocations.size === 0) return void 0;
2677
2677
  return allLocations;
2678
2678
  }, [config.modules.locationSelection, allLocations]);
2679
- const availabilityEvents = React10.useMemo(
2679
+ const availabilityEvents = React11.useMemo(
2680
2680
  () => generateAvailabilityEvents(schedules, professionals, visibleRange, effectiveBusinessHours, locationMap),
2681
2681
  [schedules, professionals, visibleRange, effectiveBusinessHours, locationMap]
2682
2682
  );
2683
- const events = React10.useMemo(() => [...bookingEvents, ...availabilityEvents], [bookingEvents, availabilityEvents]);
2684
- const handleDatesSet = React10.useCallback((arg) => {
2683
+ const events = React11.useMemo(() => [...bookingEvents, ...availabilityEvents], [bookingEvents, availabilityEvents]);
2684
+ const handleDatesSet = React11.useCallback((arg) => {
2685
2685
  setCalendarTitle(arg.view.title);
2686
2686
  setView(arg.view.type);
2687
2687
  setVisibleRange({ start: arg.startStr, end: arg.endStr });
2688
2688
  fetchBookings({ start: arg.startStr, end: arg.endStr });
2689
2689
  }, [fetchBookings, setView]);
2690
- const handleEventDidMount = React10.useCallback((arg) => {
2690
+ const handleEventDidMount = React11.useCallback((arg) => {
2691
2691
  const booking = arg.event.extendedProps?.booking;
2692
2692
  if (booking) arg.el.setAttribute("data-booking-id", booking.id);
2693
2693
  arg.el.addEventListener("dblclick", (e) => {
@@ -2714,9 +2714,9 @@ function CalendarView() {
2714
2714
  setPopoverAnchor(null);
2715
2715
  });
2716
2716
  }, []);
2717
- const skipClickRef = React10.useRef(false);
2718
- const hoverTimerRef = React10.useRef(null);
2719
- const handleEventMouseEnter = React10.useCallback((arg) => {
2717
+ const skipClickRef = React11.useRef(false);
2718
+ const hoverTimerRef = React11.useRef(null);
2719
+ const handleEventMouseEnter = React11.useCallback((arg) => {
2720
2720
  if (arg.event.display === "background") return;
2721
2721
  if (arg.event.extendedProps?.isLocationLabel) return;
2722
2722
  const booking = arg.event.extendedProps.booking;
@@ -2735,13 +2735,13 @@ function CalendarView() {
2735
2735
  setPopoverVisible(true);
2736
2736
  }, 3e3);
2737
2737
  }, []);
2738
- const handleEventMouseLeave = React10.useCallback(() => {
2738
+ const handleEventMouseLeave = React11.useCallback(() => {
2739
2739
  if (hoverTimerRef.current) {
2740
2740
  clearTimeout(hoverTimerRef.current);
2741
2741
  hoverTimerRef.current = null;
2742
2742
  }
2743
2743
  }, []);
2744
- const handleEventClick = React10.useCallback((arg) => {
2744
+ const handleEventClick = React11.useCallback((arg) => {
2745
2745
  if (skipClickRef.current) {
2746
2746
  skipClickRef.current = false;
2747
2747
  return;
@@ -2764,7 +2764,7 @@ function CalendarView() {
2764
2764
  setPopoverAnchor({ x, y });
2765
2765
  setPopoverVisible(true);
2766
2766
  }, []);
2767
- const findScheduleForSlot = React10.useCallback((professionalId, dateTimeStr) => {
2767
+ const findScheduleForSlot = React11.useCallback((professionalId, dateTimeStr) => {
2768
2768
  if (!professionalId) return null;
2769
2769
  const dt = new Date(dateTimeStr);
2770
2770
  const dateStr = dt.toISOString().slice(0, 10);
@@ -2781,7 +2781,7 @@ function CalendarView() {
2781
2781
  }
2782
2782
  return null;
2783
2783
  }, [schedules]);
2784
- const handleSelect = React10.useCallback((arg) => {
2784
+ const handleSelect = React11.useCallback((arg) => {
2785
2785
  calendarRef.current?.getApi().unselect();
2786
2786
  if (popoverVisibleRef.current || contextMenuVisibleRef.current) {
2787
2787
  setPopoverVisible(false);
@@ -2803,7 +2803,7 @@ function CalendarView() {
2803
2803
  }
2804
2804
  proceed();
2805
2805
  }, [openModal, findScheduleForSlot]);
2806
- const handleEventDrop = React10.useCallback(async (arg) => {
2806
+ const handleEventDrop = React11.useCallback(async (arg) => {
2807
2807
  const booking = arg.event.extendedProps.booking;
2808
2808
  try {
2809
2809
  await rescheduleBooking(booking.id, arg.event.startStr, arg.event.endStr, arg.newResource?.id ?? void 0);
@@ -2811,13 +2811,13 @@ function CalendarView() {
2811
2811
  arg.revert();
2812
2812
  }
2813
2813
  }, [rescheduleBooking]);
2814
- const handleViewChange = React10.useCallback((v) => {
2814
+ const handleViewChange = React11.useCallback((v) => {
2815
2815
  calendarRef.current?.getApi().changeView(v);
2816
2816
  prefs.set("calendarView", v);
2817
2817
  }, [prefs]);
2818
- const handlePrev = React10.useCallback(() => calendarRef.current?.getApi().prev(), []);
2819
- const handleNext = React10.useCallback(() => calendarRef.current?.getApi().next(), []);
2820
- const handleToday = React10.useCallback(() => {
2818
+ const handlePrev = React11.useCallback(() => calendarRef.current?.getApi().prev(), []);
2819
+ const handleNext = React11.useCallback(() => calendarRef.current?.getApi().next(), []);
2820
+ const handleToday = React11.useCallback(() => {
2821
2821
  calendarRef.current?.getApi().today();
2822
2822
  setSelectedDate(/* @__PURE__ */ new Date());
2823
2823
  }, []);
@@ -2833,9 +2833,9 @@ function CalendarView() {
2833
2833
  const next = selectedStatuses.includes(value) ? selectedStatuses.filter((s) => s !== value) : [...selectedStatuses, value];
2834
2834
  setFilters({ statuses: next });
2835
2835
  }
2836
- const wrapperRef = React10.useRef(null);
2837
- const [dayHeaderCompact, setDayHeaderCompact] = React10.useState(false);
2838
- React10.useEffect(() => {
2836
+ const wrapperRef = React11.useRef(null);
2837
+ const [dayHeaderCompact, setDayHeaderCompact] = React11.useState(false);
2838
+ React11.useEffect(() => {
2839
2839
  const container = wrapperRef.current;
2840
2840
  if (!container) return;
2841
2841
  let frame = 0;
@@ -2878,7 +2878,7 @@ function CalendarView() {
2878
2878
  ro.disconnect();
2879
2879
  };
2880
2880
  }, [resources, currentView, visibleRange]);
2881
- const applyResourceStriping = React10.useCallback(() => {
2881
+ const applyResourceStriping = React11.useCallback(() => {
2882
2882
  const container = wrapperRef.current;
2883
2883
  if (!container) return;
2884
2884
  const resourceIds = resources.map((r) => r.id);
@@ -2889,7 +2889,7 @@ function CalendarView() {
2889
2889
  el.classList.toggle("fc-resource-alt", idx % 2 === 1);
2890
2890
  });
2891
2891
  }, [resources]);
2892
- React10.useEffect(() => {
2892
+ React11.useEffect(() => {
2893
2893
  applyResourceStriping();
2894
2894
  const t1 = setTimeout(applyResourceStriping, 100);
2895
2895
  const t2 = setTimeout(applyResourceStriping, 300);
@@ -2898,7 +2898,7 @@ function CalendarView() {
2898
2898
  clearTimeout(t2);
2899
2899
  };
2900
2900
  }, [applyResourceStriping, currentView, visibleRange, bookings]);
2901
- React10.useEffect(() => {
2901
+ React11.useEffect(() => {
2902
2902
  function handleOpenBooking(e) {
2903
2903
  const bookingId = e.detail?.bookingId;
2904
2904
  if (bookingId) openModal("edit", { bookingId });
@@ -2906,7 +2906,7 @@ function CalendarView() {
2906
2906
  window.addEventListener("agenda:open-booking", handleOpenBooking);
2907
2907
  return () => window.removeEventListener("agenda:open-booking", handleOpenBooking);
2908
2908
  }, [openModal]);
2909
- const dayHeaderContent = React10.useCallback((arg) => {
2909
+ const dayHeaderContent = React11.useCallback((arg) => {
2910
2910
  const date = arg.date;
2911
2911
  const dateLocale = currentLocale === "pt-BR" ? "pt-BR" : "en";
2912
2912
  const wrapStyle = { display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1.15 };
@@ -2924,7 +2924,7 @@ function CalendarView() {
2924
2924
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: dateStyle, children: `${date.getMonth() + 1}/${date.getDate()}` })
2925
2925
  ] });
2926
2926
  }, [dayHeaderCompact, currentLocale]);
2927
- const resourceLabelContent = React10.useCallback((arg) => {
2927
+ const resourceLabelContent = React11.useCallback((arg) => {
2928
2928
  const { id, title, extendedProps } = arg.resource;
2929
2929
  const initials = title.split(" ").map((n) => n[0]).join("").slice(0, 2);
2930
2930
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-2 py-1.5", children: [
@@ -2944,7 +2944,7 @@ function CalendarView() {
2944
2944
  ] })
2945
2945
  ] });
2946
2946
  }, []);
2947
- const eventContent = React10.useCallback((arg) => {
2947
+ const eventContent = React11.useCallback((arg) => {
2948
2948
  if (arg.event.extendedProps?.isLocationLabel) {
2949
2949
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1.5 py-0.5 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] font-medium truncate", children: arg.event.title }) });
2950
2950
  }
@@ -3192,14 +3192,14 @@ function CalendarView() {
3192
3192
  )
3193
3193
  ] });
3194
3194
  }
3195
- function AgendaPage({ config, provider, store }) {
3195
+ function AgendaPage({ config, provider: provider2, store }) {
3196
3196
  const runtime = core.usePluginRuntimeOptional();
3197
3197
  const tenantId = runtime?.context.tenant?.id;
3198
- React10__default.default.useEffect(() => {
3198
+ React11__default.default.useEffect(() => {
3199
3199
  chunkSYDBDI3Q_cjs.setAgendaTenantId(tenantId);
3200
3200
  return () => chunkSYDBDI3Q_cjs.setAgendaTenantId(void 0);
3201
3201
  }, [tenantId]);
3202
- return /* @__PURE__ */ jsxRuntime.jsx(AgendaContextProvider, { config, provider, store, children: /* @__PURE__ */ jsxRuntime.jsx(CalendarView, {}) });
3202
+ return /* @__PURE__ */ jsxRuntime.jsx(AgendaContextProvider, { config, provider: provider2, store, children: /* @__PURE__ */ jsxRuntime.jsx(CalendarView, {}) });
3203
3203
  }
3204
3204
  function getTenantId() {
3205
3205
  return chunkSYDBDI3Q_cjs.getAgendaTenantId() ?? core.getActiveTenantId();
@@ -4059,7 +4059,7 @@ function getCurrentBookingQuery(state, dateRange = state.dateRange) {
4059
4059
  statuses: state.selectedStatuses.length ? state.selectedStatuses : void 0
4060
4060
  };
4061
4061
  }
4062
- function createAgendaStore(provider, financialBridge) {
4062
+ function createAgendaStore(provider2, financialBridge) {
4063
4063
  return vanilla.createStore((set, get) => ({
4064
4064
  bookings: [],
4065
4065
  bookingsLoading: false,
@@ -4083,7 +4083,7 @@ function createAgendaStore(provider, financialBridge) {
4083
4083
  set({ bookingsLoading: true, dateRange: range });
4084
4084
  const state = get();
4085
4085
  const query = getCurrentBookingQuery(state, range);
4086
- let bookings = await provider.getBookings(query);
4086
+ let bookings = await provider2.getBookings(query);
4087
4087
  if (financialBridge) {
4088
4088
  const orderIds = bookings.map((b) => b.orderId).filter((id) => !!id);
4089
4089
  if (orderIds.length > 0) {
@@ -4104,14 +4104,14 @@ function createAgendaStore(provider, financialBridge) {
4104
4104
  async fetchProfessionals() {
4105
4105
  return saas.dedup("agenda:professionals", async () => {
4106
4106
  set({ professionalsLoading: true });
4107
- const professionals = await provider.getProfessionals();
4107
+ const professionals = await provider2.getProfessionals();
4108
4108
  set({ professionals, professionalsLoading: false });
4109
4109
  });
4110
4110
  },
4111
4111
  async fetchLocations() {
4112
4112
  return saas.dedup("agenda:locations", async () => {
4113
- if (!provider.getLocations) return;
4114
- const locations = await provider.getLocations();
4113
+ if (!provider2.getLocations) return;
4114
+ const locations = await provider2.getLocations();
4115
4115
  set({ locations });
4116
4116
  const current = saas.getScheduleBlockConfig();
4117
4117
  if (current) {
@@ -4122,23 +4122,23 @@ function createAgendaStore(provider, financialBridge) {
4122
4122
  async fetchSchedules(professionalId) {
4123
4123
  return saas.dedup("agenda:schedules:" + (professionalId ?? "all"), async () => {
4124
4124
  set({ schedulesLoading: true });
4125
- const schedules = await provider.getSchedules(professionalId);
4125
+ const schedules = await provider2.getSchedules(professionalId);
4126
4126
  set({ schedules, schedulesLoading: false });
4127
4127
  });
4128
4128
  },
4129
4129
  async fetchConfirmations() {
4130
4130
  return saas.dedup("agenda:confirmations", async () => {
4131
4131
  set({ confirmationsLoading: true });
4132
- const pendingConfirmations = await provider.getConfirmationsPending();
4132
+ const pendingConfirmations = await provider2.getConfirmationsPending();
4133
4133
  set({ pendingConfirmations, confirmationsLoading: false });
4134
4134
  });
4135
4135
  },
4136
4136
  async createBooking(input) {
4137
4137
  try {
4138
- const booking = await provider.createBooking(input);
4138
+ const booking = await provider2.createBooking(input);
4139
4139
  const state = get();
4140
4140
  if (state.dateRange.start && state.dateRange.end) {
4141
- const bookings = await provider.getBookings(getCurrentBookingQuery(state));
4141
+ const bookings = await provider2.getBookings(getCurrentBookingQuery(state));
4142
4142
  set({ bookings });
4143
4143
  }
4144
4144
  ui.toast.success("Appointment created");
@@ -4150,10 +4150,10 @@ function createAgendaStore(provider, financialBridge) {
4150
4150
  },
4151
4151
  async updateBooking(id, data) {
4152
4152
  try {
4153
- const booking = await provider.updateBooking(id, data);
4153
+ const booking = await provider2.updateBooking(id, data);
4154
4154
  const state = get();
4155
4155
  if (state.dateRange.start && state.dateRange.end) {
4156
- const bookings = await provider.getBookings(getCurrentBookingQuery(state));
4156
+ const bookings = await provider2.getBookings(getCurrentBookingQuery(state));
4157
4157
  set({ bookings });
4158
4158
  }
4159
4159
  ui.toast.success("Appointment updated");
@@ -4165,10 +4165,10 @@ function createAgendaStore(provider, financialBridge) {
4165
4165
  },
4166
4166
  async deleteBooking(id) {
4167
4167
  try {
4168
- await provider.deleteBooking(id);
4168
+ await provider2.deleteBooking(id);
4169
4169
  const state = get();
4170
4170
  if (state.dateRange.start && state.dateRange.end) {
4171
- const bookings = await provider.getBookings(getCurrentBookingQuery(state));
4171
+ const bookings = await provider2.getBookings(getCurrentBookingQuery(state));
4172
4172
  set({ bookings });
4173
4173
  }
4174
4174
  ui.toast.success("Appointment deleted");
@@ -4181,10 +4181,10 @@ function createAgendaStore(provider, financialBridge) {
4181
4181
  const prev = get().bookings;
4182
4182
  set({ bookings: prev.map((b) => b.id === id ? { ...b, status } : b) });
4183
4183
  try {
4184
- await provider.updateBookingStatus(id, status);
4184
+ await provider2.updateBookingStatus(id, status);
4185
4185
  const state = get();
4186
4186
  if (state.dateRange.start && state.dateRange.end) {
4187
- const bookings = await provider.getBookings(getCurrentBookingQuery(state));
4187
+ const bookings = await provider2.getBookings(getCurrentBookingQuery(state));
4188
4188
  set({ bookings });
4189
4189
  }
4190
4190
  ui.toast.success("Status updated");
@@ -4199,7 +4199,7 @@ function createAgendaStore(provider, financialBridge) {
4199
4199
  const existing = get().bookings.find((b) => b.id === id);
4200
4200
  const assigneeId = newProfessionalId ?? existing?.professionalId;
4201
4201
  if (assigneeId) {
4202
- const hasConflict = await provider.checkConflict({
4202
+ const hasConflict = await provider2.checkConflict({
4203
4203
  assigneeId,
4204
4204
  startsAt: newStart,
4205
4205
  endsAt: newEnd,
@@ -4210,14 +4210,14 @@ function createAgendaStore(provider, financialBridge) {
4210
4210
  throw new Error("Time conflict");
4211
4211
  }
4212
4212
  }
4213
- await provider.updateBooking(id, {
4213
+ await provider2.updateBooking(id, {
4214
4214
  startsAt: newStart,
4215
4215
  endsAt: newEnd,
4216
4216
  ...newProfessionalId && { professionalId: newProfessionalId }
4217
4217
  });
4218
4218
  const state = get();
4219
4219
  if (state.dateRange.start && state.dateRange.end) {
4220
- const bookings = await provider.getBookings(getCurrentBookingQuery(state));
4220
+ const bookings = await provider2.getBookings(getCurrentBookingQuery(state));
4221
4221
  set({ bookings });
4222
4222
  }
4223
4223
  ui.toast.success("Appointment rescheduled");
@@ -4793,7 +4793,7 @@ function computeStatus(movements) {
4793
4793
  if (anyPaid) return "partial";
4794
4794
  return "pending";
4795
4795
  }
4796
- function createFinancialBridge(provider) {
4796
+ function createFinancialBridge(provider2) {
4797
4797
  return {
4798
4798
  async resolvePaymentStatuses(orderIds) {
4799
4799
  const result = /* @__PURE__ */ new Map();
@@ -4878,7 +4878,7 @@ function createFinancialBridge(provider) {
4878
4878
  return orderId;
4879
4879
  },
4880
4880
  async payMovement(input) {
4881
- await provider.payMovement({
4881
+ await provider2.payMovement({
4882
4882
  movementId: input.movementId,
4883
4883
  amount: input.amount,
4884
4884
  paymentDate: input.paymentDate,
@@ -4941,15 +4941,15 @@ function createFinancialBridge(provider) {
4941
4941
  return await this.getPaymentDetail(invoiceId);
4942
4942
  },
4943
4943
  async getPaymentMethodTypes() {
4944
- const types = await provider.getPaymentMethodTypes();
4944
+ const types = await provider2.getPaymentMethodTypes();
4945
4945
  return types.map((t) => ({ id: t.id, name: t.name, transactionType: t.transactionType }));
4946
4946
  },
4947
4947
  async getBankAccounts() {
4948
- const accounts = await provider.getBankAccounts();
4948
+ const accounts = await provider2.getBankAccounts();
4949
4949
  return accounts.filter((a) => a.isActive).map((a) => ({ id: a.id, name: a.name, accountType: a.accountType }));
4950
4950
  },
4951
4951
  async getPaymentMethods(paymentMethodTypeId) {
4952
- const methods = await provider.getPaymentMethods();
4952
+ const methods = await provider2.getPaymentMethods();
4953
4953
  return methods.filter((m) => m.paymentMethodTypeId === paymentMethodTypeId && m.isActive).map((m) => ({ id: m.id, name: m.name }));
4954
4954
  }
4955
4955
  };
@@ -4984,16 +4984,215 @@ function mapInvoiceStatus(status) {
4984
4984
  return "pending";
4985
4985
  }
4986
4986
  }
4987
+ var FUNCTION = "google-calendar-sync";
4988
+ function sb() {
4989
+ const supabase = core.getSupabaseClientOptional();
4990
+ if (!supabase) throw new Error("Supabase not initialized");
4991
+ return supabase;
4992
+ }
4993
+ function createGoogleCalendarProvider() {
4994
+ return {
4995
+ async getIntegration() {
4996
+ const { data } = await sb().from("calendar_integrations").select("*").eq("provider", "google").limit(1).maybeSingle();
4997
+ if (!data) return null;
4998
+ return {
4999
+ id: data.id,
5000
+ provider: data.provider,
5001
+ calendarId: data.calendar_id ?? "primary",
5002
+ active: data.active ?? true,
5003
+ connected: !!data.oauth_refresh_token,
5004
+ lastSyncAt: data.last_sync_at ?? void 0
5005
+ };
5006
+ },
5007
+ async getConnectUrl(redirectTo) {
5008
+ const { data, error } = await sb().functions.invoke(FUNCTION, {
5009
+ body: { action: "oauth_start", redirectTo: redirectTo ?? window.location.href }
5010
+ });
5011
+ if (error) throw new Error(error.message);
5012
+ return data.url;
5013
+ },
5014
+ async setCalendar(calendarId) {
5015
+ await sb().from("calendar_integrations").update({ calendar_id: calendarId, updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("provider", "google");
5016
+ },
5017
+ async disconnect() {
5018
+ await sb().from("calendar_integrations").update({ active: false, oauth_refresh_token: null, oauth_access_token: null }).eq("provider", "google");
5019
+ },
5020
+ async syncNow() {
5021
+ const { data, error } = await sb().functions.invoke(FUNCTION, { body: { action: "pull_events", trigger: "manual" } });
5022
+ if (error) throw new Error(error.message);
5023
+ return data;
5024
+ },
5025
+ async getSyncLog() {
5026
+ const { data } = await sb().from("calendar_sync_log").select("*").order("created_at", { ascending: false }).limit(20);
5027
+ return (data ?? []).map((r) => ({
5028
+ id: r.id,
5029
+ direction: r.direction,
5030
+ trigger: r.trigger ?? void 0,
5031
+ status: r.status,
5032
+ fetched: r.fetched ?? 0,
5033
+ written: r.written ?? 0,
5034
+ error: r.error ?? void 0,
5035
+ createdAt: r.created_at
5036
+ }));
5037
+ }
5038
+ };
5039
+ }
5040
+ var provider = createGoogleCalendarProvider();
5041
+ function GoogleCalendarExtraPanel() {
5042
+ const [connected, setConnected] = React11.useState(false);
5043
+ const [calendarId, setCalendarId] = React11.useState("primary");
5044
+ const [syncing, setSyncing] = React11.useState(false);
5045
+ const [log, setLog] = React11.useState([]);
5046
+ const [loaded, setLoaded] = React11.useState(false);
5047
+ async function load() {
5048
+ const integ = await provider.getIntegration();
5049
+ setConnected(!!integ?.connected);
5050
+ if (integ) {
5051
+ setCalendarId(integ.calendarId);
5052
+ void provider.getSyncLog().then(setLog);
5053
+ }
5054
+ setLoaded(true);
5055
+ }
5056
+ React11.useEffect(() => {
5057
+ void load();
5058
+ }, []);
5059
+ if (!loaded || !connected) return null;
5060
+ async function handleSaveCalendar() {
5061
+ await provider.setCalendar(calendarId);
5062
+ ui.toast.success("Saved");
5063
+ }
5064
+ async function handleSyncNow() {
5065
+ setSyncing(true);
5066
+ try {
5067
+ const r = await provider.syncNow();
5068
+ ui.toast.success(`Synced \u2014 ${r.written} updated`);
5069
+ void provider.getSyncLog().then(setLog);
5070
+ } catch (e) {
5071
+ ui.toast.error(e?.message ?? "Sync failed");
5072
+ } finally {
5073
+ setSyncing(false);
5074
+ }
5075
+ }
5076
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 border-t pt-4", children: [
5077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [
5078
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block flex-1 min-w-[200px]", children: [
5079
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Calendar ID" }),
5080
+ /* @__PURE__ */ jsxRuntime.jsx(
5081
+ "input",
5082
+ {
5083
+ value: calendarId,
5084
+ onChange: (e) => setCalendarId(e.target.value),
5085
+ placeholder: "primary",
5086
+ className: "w-full mt-1 rounded-input border border-input bg-card px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
5087
+ }
5088
+ )
5089
+ ] }),
5090
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", size: "sm", onClick: handleSaveCalendar, children: "Save" }),
5091
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "outline", size: "sm", onClick: handleSyncNow, disabled: syncing, children: [
5092
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: `h-3.5 w-3.5 ${syncing ? "animate-spin" : ""}` }),
5093
+ " Sync now"
5094
+ ] })
5095
+ ] }),
5096
+ log.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
5097
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
5098
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-4 w-4 text-muted-foreground" }),
5099
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "History" })
5100
+ ] }),
5101
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border divide-y text-sm", children: log.map((r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 px-3 py-2", children: [
5102
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: new Date(r.createdAt).toLocaleString() }),
5103
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] uppercase tracking-wide px-1 py-px rounded bg-muted text-muted-foreground", children: r.direction }),
5104
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto text-xs", children: [
5105
+ r.written,
5106
+ " written / ",
5107
+ r.fetched,
5108
+ " fetched"
5109
+ ] }),
5110
+ r.status === "success" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-3.5 w-3.5 text-success" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "h-3.5 w-3.5 text-warning" })
5111
+ ] }, r.id)) })
5112
+ ] })
5113
+ ] });
5114
+ }
5115
+ var googleCalendarConnectorDef = {
5116
+ id: "google-calendar",
5117
+ hostPluginId: "agenda",
5118
+ name: "Google Calendar",
5119
+ description: "Two-way sync between your bookings and Google Calendar.",
5120
+ icon: "Calendar",
5121
+ authKind: "oauth",
5122
+ async getStatus() {
5123
+ const integ = await provider.getIntegration();
5124
+ return { connected: !!integ?.connected };
5125
+ },
5126
+ startOAuth: (redirectTo) => provider.getConnectUrl(redirectTo),
5127
+ disconnect: () => provider.disconnect(),
5128
+ ExtraPanel: GoogleCalendarExtraPanel
5129
+ };
5130
+
5131
+ // src/integrations/google-calendar/connector.ts
5132
+ var googleCalendarConnector = {
5133
+ id: "google-calendar",
5134
+ provider: "google",
5135
+ pluginId: "agenda",
5136
+ authKind: "oauth",
5137
+ capabilities: [
5138
+ {
5139
+ entity: "booking",
5140
+ direction: "bidirectional",
5141
+ triggers: ["on-write", "scheduled", "webhook"]
5142
+ }
5143
+ ]
5144
+ };
5145
+
5146
+ // src/integrations/google-calendar/mapping.ts
5147
+ function bookingSummary(b) {
5148
+ const services = (b.services ?? []).map((s) => s.name).filter(Boolean).join(", ");
5149
+ const who = b.clientName ?? "";
5150
+ if (services && who) return `${services} \u2014 ${who}`;
5151
+ return services || who || "Appointment";
5152
+ }
5153
+ function bookingToEvent2(b, timeZone) {
5154
+ if (!b.startsAt || !b.endsAt) return null;
5155
+ const notes = [b.notes, b.professionalName ? `Pro: ${b.professionalName}` : "", b.locationName ?? ""].filter(Boolean).join("\n");
5156
+ return {
5157
+ summary: bookingSummary(b),
5158
+ description: notes || void 0,
5159
+ start: { dateTime: b.startsAt, timeZone },
5160
+ end: { dateTime: b.endsAt, timeZone }
5161
+ };
5162
+ }
5163
+ function eventToBookingPatch(ev) {
5164
+ if (ev.status === "cancelled") return { status: "cancelled" };
5165
+ return {
5166
+ startsAt: ev.start?.dateTime,
5167
+ endsAt: ev.end?.dateTime
5168
+ };
5169
+ }
5170
+
5171
+ // src/integrations/google-calendar/index.ts
5172
+ function createGoogleCalendarPlugin() {
5173
+ return {
5174
+ id: "google-calendar",
5175
+ name: "Google Calendar",
5176
+ icon: "Calendar",
5177
+ version: "0.1.0",
5178
+ scope: "addon",
5179
+ defaultEnabled: true,
5180
+ dependencies: ["agenda"],
5181
+ navigation: [],
5182
+ routes: [],
5183
+ connectors: [googleCalendarConnectorDef]
5184
+ };
5185
+ }
4987
5186
 
4988
5187
  // src/index.ts
4989
5188
  function createAgendaPlugin(options) {
4990
5189
  const config = resolveConfig(options);
4991
5190
  core.registerTranslations(agendaLocales);
4992
- const provider = options?.dataProvider ?? core.createSafeDataProvider(
5191
+ const provider2 = options?.dataProvider ?? core.createSafeDataProvider(
4993
5192
  () => createSupabaseAgendaProvider(),
4994
5193
  () => createMockAgendaProvider()
4995
5194
  );
4996
- const store = createAgendaStore(provider, options?.financialBridge);
5195
+ const store = createAgendaStore(provider2, options?.financialBridge);
4997
5196
  saas.setScheduleBlockConfig({
4998
5197
  defaults: config.scheduleBlockDefaults,
4999
5198
  showServices: !!config.serviceLookup,
@@ -5002,14 +5201,14 @@ function createAgendaPlugin(options) {
5002
5201
  showLocations: config.modules.locationSelection,
5003
5202
  locations: config.locations.map((l) => ({ id: l.id, name: l.name })),
5004
5203
  // Lazy fetcher — called by ScheduleEditor when locations are needed but empty
5005
- fetchLocations: config.modules.locationSelection && provider.getLocations ? async () => {
5006
- const locations = await provider.getLocations();
5204
+ fetchLocations: config.modules.locationSelection && provider2.getLocations ? async () => {
5205
+ const locations = await provider2.getLocations();
5007
5206
  const current = saas.getScheduleBlockConfig();
5008
5207
  if (current) saas.setScheduleBlockConfig({ ...current, locations });
5009
5208
  return locations;
5010
5209
  } : void 0
5011
5210
  });
5012
- const PageComponent = () => React10__default.default.createElement(AgendaPage, { config, provider, store });
5211
+ const PageComponent = () => React11__default.default.createElement(AgendaPage, { config, provider: provider2, store });
5013
5212
  return {
5014
5213
  id: "agenda",
5015
5214
  name: config.labels.pageTitle,
@@ -5115,8 +5314,15 @@ function createAgendaPlugin(options) {
5115
5314
  id: "agenda",
5116
5315
  label: "Agenda",
5117
5316
  icon: "Calendar",
5317
+ // Standard layout: General | Integrations (Google Calendar addon) | Properties (holidays).
5118
5318
  component: (() => {
5119
- const AgendaSettingsTab = () => React10__default.default.createElement(AgendaGeneralSettings);
5319
+ const AgendaSettingsTab = () => React11__default.default.createElement(saas.PluginSettingsPanel, {
5320
+ title: "Agenda",
5321
+ generalSettings: React11__default.default.createElement(AgendaGeneralSettings),
5322
+ registries: agendaRegistries,
5323
+ hostPluginId: "agenda",
5324
+ routeBase: "/settings/agenda"
5325
+ });
5120
5326
  AgendaSettingsTab.displayName = "AgendaSettingsTab";
5121
5327
  return AgendaSettingsTab;
5122
5328
  })(),
@@ -5128,8 +5334,13 @@ function createAgendaPlugin(options) {
5128
5334
  };
5129
5335
  }
5130
5336
 
5337
+ exports.bookingToEvent = bookingToEvent2;
5131
5338
  exports.computeCommissionAmount = computeCommissionAmount;
5132
5339
  exports.createAgendaPlugin = createAgendaPlugin;
5133
5340
  exports.createFinancialBridge = createFinancialBridge;
5341
+ exports.createGoogleCalendarPlugin = createGoogleCalendarPlugin;
5342
+ exports.createGoogleCalendarProvider = createGoogleCalendarProvider;
5343
+ exports.eventToBookingPatch = eventToBookingPatch;
5344
+ exports.googleCalendarConnector = googleCalendarConnector;
5134
5345
  //# sourceMappingURL=index.cjs.map
5135
5346
  //# sourceMappingURL=index.cjs.map