@snowcone-app/ui 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5911,16 +5911,29 @@ function useFocusTrap(isActive, onClose) {
5911
5911
  }
5912
5912
 
5913
5913
  // src/hooks/useCanvasContext.ts
5914
- var import_react26 = require("react");
5914
+ var import_react27 = require("react");
5915
5915
 
5916
5916
  // src/patterns/RealtimeProvider.tsx
5917
- var import_react24 = require("react");
5918
- var import_react25 = require("@snowcone-app/sdk/react");
5917
+ var import_react25 = require("react");
5918
+ var import_react26 = require("@snowcone-app/sdk/react");
5919
5919
  var import_sdk8 = require("@snowcone-app/sdk");
5920
+
5921
+ // src/patterns/MockupBackground.tsx
5922
+ var import_react24 = require("react");
5920
5923
  var import_jsx_runtime51 = require("react/jsx-runtime");
5924
+ var MockupBackgroundContext = (0, import_react24.createContext)(void 0);
5925
+ function MockupBackground({ bg, children }) {
5926
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(MockupBackgroundContext.Provider, { value: bg, children });
5927
+ }
5928
+ function useMockupBackgroundOptional() {
5929
+ return (0, import_react24.useContext)(MockupBackgroundContext);
5930
+ }
5931
+
5932
+ // src/patterns/RealtimeProvider.tsx
5933
+ var import_jsx_runtime52 = require("react/jsx-runtime");
5921
5934
  var DEFAULT_ARTBOARD_SIZE = 2e3;
5922
5935
  var MAX_CONCURRENT_BLOBS = 5;
5923
- var RealtimeContext = (0, import_react24.createContext)(
5936
+ var RealtimeContext = (0, import_react25.createContext)(
5924
5937
  void 0
5925
5938
  );
5926
5939
  function RealtimeProvider({
@@ -5934,9 +5947,10 @@ function RealtimeProvider({
5934
5947
  grantUrl
5935
5948
  }) {
5936
5949
  const productContext = useProductOptional();
5937
- const [isEnabled, setIsEnabled] = (0, import_react24.useState)(autoEnable);
5950
+ const mockupBg = useMockupBackgroundOptional();
5951
+ const [isEnabled, setIsEnabled] = (0, import_react25.useState)(autoEnable);
5938
5952
  const useSessionGrant = Boolean(shop && grantUrl);
5939
- const getToken = (0, import_react24.useCallback)(async () => {
5953
+ const getToken = (0, import_react25.useCallback)(async () => {
5940
5954
  const res = await fetch(grantUrl, {
5941
5955
  method: "POST",
5942
5956
  headers: { "Content-Type": "application/json" },
@@ -5947,15 +5961,16 @@ function RealtimeProvider({
5947
5961
  }
5948
5962
  return await res.json();
5949
5963
  }, [shop, grantUrl]);
5950
- const canvasBlobsSentRef = (0, import_react24.useRef)(0);
5951
- const colorBlobsSentRef = (0, import_react24.useRef)(0);
5952
- const lastBlobSentTimeRef = (0, import_react24.useRef)(null);
5953
- const isPendingMockupsRef = (0, import_react24.useRef)(false);
5954
- const configSentRef = (0, import_react24.useRef)(false);
5955
- const placementSettingsOverridesRef = (0, import_react24.useRef)({});
5956
- const lastSentVariantIdRef = (0, import_react24.useRef)(null);
5957
- const lastSentColorsRef = (0, import_react24.useRef)({});
5958
- const realtimeMockup = (0, import_react25.useRealtimeMockup)({
5964
+ const canvasBlobsSentRef = (0, import_react25.useRef)(0);
5965
+ const colorBlobsSentRef = (0, import_react25.useRef)(0);
5966
+ const lastBlobSentTimeRef = (0, import_react25.useRef)(null);
5967
+ const isPendingMockupsRef = (0, import_react25.useRef)(false);
5968
+ const configSentRef = (0, import_react25.useRef)(false);
5969
+ const placementSettingsOverridesRef = (0, import_react25.useRef)({});
5970
+ const lastSentVariantIdRef = (0, import_react25.useRef)(null);
5971
+ const lastSentBgRef = (0, import_react25.useRef)(void 0);
5972
+ const lastSentColorsRef = (0, import_react25.useRef)({});
5973
+ const realtimeMockup = (0, import_react26.useRealtimeMockup)({
5959
5974
  wsUrl,
5960
5975
  getToken: useSessionGrant ? getToken : void 0,
5961
5976
  onConnected: (sessionId) => {
@@ -5986,7 +6001,7 @@ function RealtimeProvider({
5986
6001
  console.error(`[RealtimeProvider] Render error [${detail.code}]:`, error);
5987
6002
  }
5988
6003
  });
5989
- const subscribeRTCTiming = (0, import_react24.useCallback)((_callback) => {
6004
+ const subscribeRTCTiming = (0, import_react25.useCallback)((_callback) => {
5990
6005
  return () => {
5991
6006
  };
5992
6007
  }, []);
@@ -6006,31 +6021,31 @@ function RealtimeProvider({
6006
6021
  flushPendingBlobs,
6007
6022
  hasPendingBlobs
6008
6023
  } = realtimeMockup;
6009
- const mockupResultsRef = (0, import_react24.useRef)([]);
6010
- const mockupSubscribersRef = (0, import_react24.useRef)(
6024
+ const mockupResultsRef = (0, import_react25.useRef)([]);
6025
+ const mockupSubscribersRef = (0, import_react25.useRef)(
6011
6026
  /* @__PURE__ */ new Set()
6012
6027
  );
6013
- const mockupSubscribersByIdRef = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
6014
- const pendingExportCancelledSubscribersRef = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
6015
- const pendingBlobSubscribersRef = (0, import_react24.useRef)(
6028
+ const mockupSubscribersByIdRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
6029
+ const pendingExportCancelledSubscribersRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
6030
+ const pendingBlobSubscribersRef = (0, import_react25.useRef)(
6016
6031
  /* @__PURE__ */ new Set()
6017
6032
  );
6018
- const blobReceivedSubscribersRef = (0, import_react24.useRef)(
6033
+ const blobReceivedSubscribersRef = (0, import_react25.useRef)(
6019
6034
  /* @__PURE__ */ new Set()
6020
6035
  );
6021
- const blobSentSubscribersRef = (0, import_react24.useRef)(
6036
+ const blobSentSubscribersRef = (0, import_react25.useRef)(
6022
6037
  /* @__PURE__ */ new Set()
6023
6038
  );
6024
- const pipelineSettledSubscribersRef = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
6025
- const pipelineGenRef = (0, import_react24.useRef)(0);
6026
- const blobQueuedGenRef = (0, import_react24.useRef)(0);
6027
- const hasBlobInFlightRef = (0, import_react24.useRef)(false);
6028
- const pipelineResetCooldownRef = (0, import_react24.useRef)(false);
6029
- const mockupUrlCacheRef = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
6030
- const registeredBlobUrlsRef = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
6031
- const pendingPlacementsRef = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
6032
- const pendingMockupIdsRef = (0, import_react24.useRef)(/* @__PURE__ */ new Set());
6033
- (0, import_react24.useEffect)(() => {
6039
+ const pipelineSettledSubscribersRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
6040
+ const pipelineGenRef = (0, import_react25.useRef)(0);
6041
+ const blobQueuedGenRef = (0, import_react25.useRef)(0);
6042
+ const hasBlobInFlightRef = (0, import_react25.useRef)(false);
6043
+ const pipelineResetCooldownRef = (0, import_react25.useRef)(false);
6044
+ const mockupUrlCacheRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
6045
+ const registeredBlobUrlsRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
6046
+ const pendingPlacementsRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
6047
+ const pendingMockupIdsRef = (0, import_react25.useRef)(/* @__PURE__ */ new Set());
6048
+ (0, import_react25.useEffect)(() => {
6034
6049
  if (rawMockupResults.length === 0) {
6035
6050
  if (mockupResultsRef.current.length > 0) {
6036
6051
  mockupResultsRef.current = [];
@@ -6082,7 +6097,7 @@ function RealtimeProvider({
6082
6097
  pipelineSettledSubscribersRef.current.forEach((cb) => cb());
6083
6098
  }
6084
6099
  }, [rawMockupResults]);
6085
- const sendCanvasBlob = (0, import_react24.useCallback)(
6100
+ const sendCanvasBlob = (0, import_react25.useCallback)(
6086
6101
  (placement, blob, mockupCount, baseThrottleMs) => {
6087
6102
  blobQueuedGenRef.current = pipelineGenRef.current;
6088
6103
  const result = sendCanvasBlobRaw(
@@ -6101,7 +6116,7 @@ function RealtimeProvider({
6101
6116
  },
6102
6117
  [sendCanvasBlobRaw]
6103
6118
  );
6104
- const sendCanvasState = (0, import_react24.useCallback)(
6119
+ const sendCanvasState = (0, import_react25.useCallback)(
6105
6120
  (placement, state, mockupCount, baseThrottleMs) => {
6106
6121
  blobQueuedGenRef.current = pipelineGenRef.current;
6107
6122
  const result = sendCanvasStateRaw(
@@ -6120,7 +6135,7 @@ function RealtimeProvider({
6120
6135
  },
6121
6136
  [sendCanvasStateRaw]
6122
6137
  );
6123
- const sendColorBlobTracked = (0, import_react24.useCallback)(
6138
+ const sendColorBlobTracked = (0, import_react25.useCallback)(
6124
6139
  (placement, color) => {
6125
6140
  const result = sendColorBlob(placement, color);
6126
6141
  if (result) {
@@ -6132,23 +6147,24 @@ function RealtimeProvider({
6132
6147
  },
6133
6148
  [sendColorBlob]
6134
6149
  );
6135
- (0, import_react24.useEffect)(() => {
6150
+ (0, import_react25.useEffect)(() => {
6136
6151
  if (isEnabled) {
6137
6152
  connect();
6138
6153
  return () => {
6139
6154
  disconnect();
6140
6155
  configSentRef.current = false;
6141
6156
  lastSentVariantIdRef.current = null;
6157
+ lastSentBgRef.current = void 0;
6142
6158
  lastSentColorsRef.current = {};
6143
6159
  };
6144
6160
  }
6145
6161
  }, [isEnabled, connect, disconnect, wsUrl]);
6146
- (0, import_react24.useEffect)(() => {
6162
+ (0, import_react25.useEffect)(() => {
6147
6163
  if (rawMockupResults.length > 0 && isPendingMockupsRef.current) {
6148
6164
  isPendingMockupsRef.current = false;
6149
6165
  }
6150
6166
  }, [rawMockupResults.length]);
6151
- (0, import_react24.useEffect)(() => {
6167
+ (0, import_react25.useEffect)(() => {
6152
6168
  if (!isEnabled || !isConnected || !productContext?.product) return;
6153
6169
  const product = productContext.product;
6154
6170
  const productId = product.id;
@@ -6160,7 +6176,8 @@ function RealtimeProvider({
6160
6176
  );
6161
6177
  const isFirstSend = !configSentRef.current;
6162
6178
  const variantChanged = lastSentVariantIdRef.current !== null && lastSentVariantIdRef.current !== variantId;
6163
- if (!isFirstSend && !variantChanged) {
6179
+ const bgChanged = configSentRef.current && lastSentBgRef.current !== mockupBg;
6180
+ if (!isFirstSend && !variantChanged && !bgChanged) {
6164
6181
  return;
6165
6182
  }
6166
6183
  const mockupIds = [];
@@ -6177,6 +6194,7 @@ function RealtimeProvider({
6177
6194
  variantId,
6178
6195
  shop,
6179
6196
  width: mockupWidth,
6197
+ ...mockupBg ? { bg: mockupBg } : {},
6180
6198
  placementSettings: { ...placementSettingsOverridesRef.current }
6181
6199
  } : {
6182
6200
  productId,
@@ -6185,6 +6203,7 @@ function RealtimeProvider({
6185
6203
  shop: "hTidnpNnNa",
6186
6204
  seal: "bypass-sig-for-k6-load-test",
6187
6205
  width: mockupWidth,
6206
+ ...mockupBg ? { bg: mockupBg } : {},
6188
6207
  placementSettings: { ...placementSettingsOverridesRef.current }
6189
6208
  };
6190
6209
  if (variantChanged) {
@@ -6196,6 +6215,7 @@ function RealtimeProvider({
6196
6215
  sendConfigRaw(configPayload);
6197
6216
  configSentRef.current = true;
6198
6217
  lastSentVariantIdRef.current = variantId;
6218
+ lastSentBgRef.current = mockupBg;
6199
6219
  setTimeout(() => {
6200
6220
  const colorPlacements = placements.filter((p) => p.type === "color");
6201
6221
  colorPlacements.forEach((p) => {
@@ -6213,9 +6233,10 @@ function RealtimeProvider({
6213
6233
  productContext?.selection,
6214
6234
  sendConfigRaw,
6215
6235
  sendColorBlobTracked,
6216
- mockupWidth
6236
+ mockupWidth,
6237
+ mockupBg
6217
6238
  ]);
6218
- (0, import_react24.useEffect)(() => {
6239
+ (0, import_react25.useEffect)(() => {
6219
6240
  if (!isEnabled || !isConnected || !isConfigured || !productContext?.product)
6220
6241
  return;
6221
6242
  const placements = productContext.product.placements || [];
@@ -6240,20 +6261,20 @@ function RealtimeProvider({
6240
6261
  productContext?.selection,
6241
6262
  sendColorBlobTracked
6242
6263
  ]);
6243
- const updatePlacementSettingsWrapped = (0, import_react24.useCallback)(
6264
+ const updatePlacementSettingsWrapped = (0, import_react25.useCallback)(
6244
6265
  (settings) => {
6245
6266
  placementSettingsOverridesRef.current = settings;
6246
6267
  return updatePlacementSettingsRaw(settings);
6247
6268
  },
6248
6269
  [updatePlacementSettingsRaw]
6249
6270
  );
6250
- const enableRealtime = (0, import_react24.useCallback)(() => {
6271
+ const enableRealtime = (0, import_react25.useCallback)(() => {
6251
6272
  setIsEnabled(true);
6252
6273
  }, []);
6253
- const disableRealtime = (0, import_react24.useCallback)(() => {
6274
+ const disableRealtime = (0, import_react25.useCallback)(() => {
6254
6275
  setIsEnabled(false);
6255
6276
  }, []);
6256
- const placementDimensions = (0, import_react24.useMemo)(() => {
6277
+ const placementDimensions = (0, import_react25.useMemo)(() => {
6257
6278
  if (!productContext?.product?.placements) return [];
6258
6279
  return productContext.product.placements.map((p) => ({
6259
6280
  label: p.label,
@@ -6262,14 +6283,14 @@ function RealtimeProvider({
6262
6283
  type: p.type || "image"
6263
6284
  }));
6264
6285
  }, [productContext?.product?.placements]);
6265
- const canvasExportSize = (0, import_react24.useMemo)(() => {
6286
+ const canvasExportSize = (0, import_react25.useMemo)(() => {
6266
6287
  const firstPlacement = productContext?.product?.placements?.[0];
6267
6288
  if (firstPlacement?.width && firstPlacement?.height) {
6268
6289
  return { width: firstPlacement.width, height: firstPlacement.height };
6269
6290
  }
6270
6291
  return { width: DEFAULT_ARTBOARD_SIZE, height: DEFAULT_ARTBOARD_SIZE };
6271
6292
  }, [productContext?.product?.placements]);
6272
- const subscribeMockupResults = (0, import_react24.useCallback)(
6293
+ const subscribeMockupResults = (0, import_react25.useCallback)(
6273
6294
  (callback) => {
6274
6295
  mockupSubscribersRef.current.add(callback);
6275
6296
  return () => {
@@ -6278,7 +6299,7 @@ function RealtimeProvider({
6278
6299
  },
6279
6300
  []
6280
6301
  );
6281
- const subscribeMockupResultById = (0, import_react24.useCallback)(
6302
+ const subscribeMockupResultById = (0, import_react25.useCallback)(
6282
6303
  (mockupId, callback) => {
6283
6304
  if (!mockupSubscribersByIdRef.current.has(mockupId)) {
6284
6305
  mockupSubscribersByIdRef.current.set(mockupId, /* @__PURE__ */ new Set());
@@ -6305,7 +6326,7 @@ function RealtimeProvider({
6305
6326
  },
6306
6327
  []
6307
6328
  );
6308
- const subscribePendingBlob = (0, import_react24.useCallback)(
6329
+ const subscribePendingBlob = (0, import_react25.useCallback)(
6309
6330
  (callback) => {
6310
6331
  pendingBlobSubscribersRef.current.add(callback);
6311
6332
  return () => {
@@ -6314,7 +6335,7 @@ function RealtimeProvider({
6314
6335
  },
6315
6336
  []
6316
6337
  );
6317
- const subscribePendingExportCancelled = (0, import_react24.useCallback)(
6338
+ const subscribePendingExportCancelled = (0, import_react25.useCallback)(
6318
6339
  (callback) => {
6319
6340
  pendingExportCancelledSubscribersRef.current.add(callback);
6320
6341
  return () => {
@@ -6323,7 +6344,7 @@ function RealtimeProvider({
6323
6344
  },
6324
6345
  []
6325
6346
  );
6326
- const subscribeBlobReceived = (0, import_react24.useCallback)(
6347
+ const subscribeBlobReceived = (0, import_react25.useCallback)(
6327
6348
  (callback) => {
6328
6349
  blobReceivedSubscribersRef.current.add(callback);
6329
6350
  return () => {
@@ -6332,7 +6353,7 @@ function RealtimeProvider({
6332
6353
  },
6333
6354
  []
6334
6355
  );
6335
- const subscribeBlobSent = (0, import_react24.useCallback)(
6356
+ const subscribeBlobSent = (0, import_react25.useCallback)(
6336
6357
  (callback) => {
6337
6358
  blobSentSubscribersRef.current.add(callback);
6338
6359
  return () => {
@@ -6341,7 +6362,7 @@ function RealtimeProvider({
6341
6362
  },
6342
6363
  []
6343
6364
  );
6344
- const subscribePipelineSettled = (0, import_react24.useCallback)(
6365
+ const subscribePipelineSettled = (0, import_react25.useCallback)(
6345
6366
  (callback) => {
6346
6367
  pipelineSettledSubscribersRef.current.add(callback);
6347
6368
  return () => {
@@ -6350,7 +6371,7 @@ function RealtimeProvider({
6350
6371
  },
6351
6372
  []
6352
6373
  );
6353
- const resetPipelineSettled = (0, import_react24.useCallback)(
6374
+ const resetPipelineSettled = (0, import_react25.useCallback)(
6354
6375
  () => {
6355
6376
  pipelineGenRef.current++;
6356
6377
  hasBlobInFlightRef.current = false;
@@ -6361,7 +6382,7 @@ function RealtimeProvider({
6361
6382
  },
6362
6383
  []
6363
6384
  );
6364
- const notifyPendingExport = (0, import_react24.useCallback)(
6385
+ const notifyPendingExport = (0, import_react25.useCallback)(
6365
6386
  (placement) => {
6366
6387
  if (pendingPlacementsRef.current.has(placement)) {
6367
6388
  return;
@@ -6381,7 +6402,7 @@ function RealtimeProvider({
6381
6402
  },
6382
6403
  [productContext?.product?.mockups]
6383
6404
  );
6384
- const notifyPendingExportCancelled = (0, import_react24.useCallback)(
6405
+ const notifyPendingExportCancelled = (0, import_react25.useCallback)(
6385
6406
  (placement) => {
6386
6407
  if (!pendingPlacementsRef.current.has(placement)) {
6387
6408
  return;
@@ -6405,7 +6426,7 @@ function RealtimeProvider({
6405
6426
  },
6406
6427
  [productContext?.product?.mockups]
6407
6428
  );
6408
- const getMockupUrl3 = (0, import_react24.useCallback)((mockupId) => {
6429
+ const getMockupUrl3 = (0, import_react25.useCallback)((mockupId) => {
6409
6430
  if (pendingMockupIdsRef.current.has(mockupId)) {
6410
6431
  console.log(`[RTP] getMockupUrl("${mockupId}") \u2192 null (pending)`);
6411
6432
  return null;
@@ -6413,7 +6434,7 @@ function RealtimeProvider({
6413
6434
  const cached = mockupUrlCacheRef.current.get(mockupId);
6414
6435
  return cached?.url ?? null;
6415
6436
  }, []);
6416
- const getMockupUrls = (0, import_react24.useCallback)((mockupIds) => {
6437
+ const getMockupUrls = (0, import_react25.useCallback)((mockupIds) => {
6417
6438
  const result = {};
6418
6439
  for (const mockupId of mockupIds) {
6419
6440
  if (pendingMockupIdsRef.current.has(mockupId)) {
@@ -6425,10 +6446,10 @@ function RealtimeProvider({
6425
6446
  }
6426
6447
  return result;
6427
6448
  }, []);
6428
- const isMockupLoading = (0, import_react24.useCallback)((mockupId) => {
6449
+ const isMockupLoading = (0, import_react25.useCallback)((mockupId) => {
6429
6450
  return pendingMockupIdsRef.current.has(mockupId);
6430
6451
  }, []);
6431
- const registerBlobUrl = (0, import_react24.useCallback)((blobOrUrl, placementName) => {
6452
+ const registerBlobUrl = (0, import_react25.useCallback)((blobOrUrl, placementName) => {
6432
6453
  let url;
6433
6454
  if (blobOrUrl instanceof Blob) {
6434
6455
  if (registeredBlobUrlsRef.current.size >= MAX_CONCURRENT_BLOBS) {
@@ -6450,13 +6471,13 @@ function RealtimeProvider({
6450
6471
  }
6451
6472
  return url;
6452
6473
  }, []);
6453
- const subscribeMockupResultsRef = (0, import_react24.useRef)(subscribeMockupResults);
6454
- const subscribeMockupResultByIdRef = (0, import_react24.useRef)(subscribeMockupResultById);
6455
- const subscribePendingBlobRef = (0, import_react24.useRef)(subscribePendingBlob);
6456
- const subscribeBlobReceivedRef = (0, import_react24.useRef)(subscribeBlobReceived);
6457
- const subscribeBlobSentRef = (0, import_react24.useRef)(subscribeBlobSent);
6458
- const subscribePipelineSettledRef = (0, import_react24.useRef)(subscribePipelineSettled);
6459
- const subscribePendingExportCancelledRef = (0, import_react24.useRef)(
6474
+ const subscribeMockupResultsRef = (0, import_react25.useRef)(subscribeMockupResults);
6475
+ const subscribeMockupResultByIdRef = (0, import_react25.useRef)(subscribeMockupResultById);
6476
+ const subscribePendingBlobRef = (0, import_react25.useRef)(subscribePendingBlob);
6477
+ const subscribeBlobReceivedRef = (0, import_react25.useRef)(subscribeBlobReceived);
6478
+ const subscribeBlobSentRef = (0, import_react25.useRef)(subscribeBlobSent);
6479
+ const subscribePipelineSettledRef = (0, import_react25.useRef)(subscribePipelineSettled);
6480
+ const subscribePendingExportCancelledRef = (0, import_react25.useRef)(
6460
6481
  subscribePendingExportCancelled
6461
6482
  );
6462
6483
  subscribeMockupResultsRef.current = subscribeMockupResults;
@@ -6466,49 +6487,49 @@ function RealtimeProvider({
6466
6487
  subscribeBlobSentRef.current = subscribeBlobSent;
6467
6488
  subscribePipelineSettledRef.current = subscribePipelineSettled;
6468
6489
  subscribePendingExportCancelledRef.current = subscribePendingExportCancelled;
6469
- const stableSubscribeMockupResults = (0, import_react24.useCallback)(
6490
+ const stableSubscribeMockupResults = (0, import_react25.useCallback)(
6470
6491
  (callback) => {
6471
6492
  return subscribeMockupResultsRef.current(callback);
6472
6493
  },
6473
6494
  []
6474
6495
  );
6475
- const stableSubscribeMockupResultById = (0, import_react24.useCallback)(
6496
+ const stableSubscribeMockupResultById = (0, import_react25.useCallback)(
6476
6497
  (mockupId, callback) => {
6477
6498
  return subscribeMockupResultByIdRef.current(mockupId, callback);
6478
6499
  },
6479
6500
  []
6480
6501
  );
6481
- const stableSubscribePendingBlob = (0, import_react24.useCallback)(
6502
+ const stableSubscribePendingBlob = (0, import_react25.useCallback)(
6482
6503
  (callback) => {
6483
6504
  return subscribePendingBlobRef.current(callback);
6484
6505
  },
6485
6506
  []
6486
6507
  );
6487
- const stableSubscribePendingExportCancelled = (0, import_react24.useCallback)(
6508
+ const stableSubscribePendingExportCancelled = (0, import_react25.useCallback)(
6488
6509
  (callback) => {
6489
6510
  return subscribePendingExportCancelledRef.current(callback);
6490
6511
  },
6491
6512
  []
6492
6513
  );
6493
- const stableSubscribeBlobReceived = (0, import_react24.useCallback)(
6514
+ const stableSubscribeBlobReceived = (0, import_react25.useCallback)(
6494
6515
  (callback) => {
6495
6516
  return subscribeBlobReceivedRef.current(callback);
6496
6517
  },
6497
6518
  []
6498
6519
  );
6499
- const stableSubscribeBlobSent = (0, import_react24.useCallback)(
6520
+ const stableSubscribeBlobSent = (0, import_react25.useCallback)(
6500
6521
  (callback) => {
6501
6522
  return subscribeBlobSentRef.current(callback);
6502
6523
  },
6503
6524
  []
6504
6525
  );
6505
- const stableSubscribePipelineSettled = (0, import_react24.useCallback)(
6526
+ const stableSubscribePipelineSettled = (0, import_react25.useCallback)(
6506
6527
  (callback) => {
6507
6528
  return subscribePipelineSettledRef.current(callback);
6508
6529
  },
6509
6530
  []
6510
6531
  );
6511
- const contextValue = (0, import_react24.useMemo)(
6532
+ const contextValue = (0, import_react25.useMemo)(
6512
6533
  () => ({
6513
6534
  isEnabled,
6514
6535
  isConnected,
@@ -6581,31 +6602,31 @@ function RealtimeProvider({
6581
6602
  registerBlobUrl
6582
6603
  ]
6583
6604
  );
6584
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(RealtimeContext.Provider, { value: contextValue, children });
6605
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(RealtimeContext.Provider, { value: contextValue, children });
6585
6606
  }
6586
6607
  function useRealtime() {
6587
- const context = (0, import_react24.useContext)(RealtimeContext);
6608
+ const context = (0, import_react25.useContext)(RealtimeContext);
6588
6609
  if (!context) {
6589
6610
  throw new Error("useRealtime must be used within a RealtimeProvider");
6590
6611
  }
6591
6612
  return context;
6592
6613
  }
6593
6614
  function useRealtimeOptional() {
6594
- return (0, import_react24.useContext)(RealtimeContext);
6615
+ return (0, import_react25.useContext)(RealtimeContext);
6595
6616
  }
6596
6617
 
6597
6618
  // src/hooks/useCanvasContext.ts
6598
6619
  function useCanvasContext() {
6599
6620
  const context = useProductOptional();
6600
6621
  const realtimeContext = useRealtimeOptional();
6601
- const sendCanvasBlobRef = (0, import_react26.useRef)(realtimeContext?.sendCanvasBlob);
6602
- const isRealtimeEnabledRef = (0, import_react26.useRef)(realtimeContext?.isEnabled ?? false);
6603
- const isConfiguredRef = (0, import_react26.useRef)(realtimeContext?.isConfigured ?? false);
6604
- const mockupCountRef = (0, import_react26.useRef)(context?.product?.mockups?.length ?? 1);
6605
- const selectedPlacementRef = (0, import_react26.useRef)(context?.selectedPlacement);
6606
- const enableRealtimeRef = (0, import_react26.useRef)(realtimeContext?.enableRealtime);
6607
- const selectedArtworkRef = (0, import_react26.useRef)(context?.selectedArtwork);
6608
- (0, import_react26.useEffect)(() => {
6622
+ const sendCanvasBlobRef = (0, import_react27.useRef)(realtimeContext?.sendCanvasBlob);
6623
+ const isRealtimeEnabledRef = (0, import_react27.useRef)(realtimeContext?.isEnabled ?? false);
6624
+ const isConfiguredRef = (0, import_react27.useRef)(realtimeContext?.isConfigured ?? false);
6625
+ const mockupCountRef = (0, import_react27.useRef)(context?.product?.mockups?.length ?? 1);
6626
+ const selectedPlacementRef = (0, import_react27.useRef)(context?.selectedPlacement);
6627
+ const enableRealtimeRef = (0, import_react27.useRef)(realtimeContext?.enableRealtime);
6628
+ const selectedArtworkRef = (0, import_react27.useRef)(context?.selectedArtwork);
6629
+ (0, import_react27.useEffect)(() => {
6609
6630
  sendCanvasBlobRef.current = realtimeContext?.sendCanvasBlob;
6610
6631
  isRealtimeEnabledRef.current = realtimeContext?.isEnabled ?? false;
6611
6632
  isConfiguredRef.current = realtimeContext?.isConfigured ?? false;
@@ -6614,7 +6635,7 @@ function useCanvasContext() {
6614
6635
  enableRealtimeRef.current = realtimeContext?.enableRealtime;
6615
6636
  selectedArtworkRef.current = context?.selectedArtwork;
6616
6637
  });
6617
- return (0, import_react26.useMemo)(() => ({
6638
+ return (0, import_react27.useMemo)(() => ({
6618
6639
  /** Ref to sendCanvasBlob function - call via sendCanvasBlobRef.current?.(...) */
6619
6640
  sendCanvasBlobRef,
6620
6641
  /** Ref to isRealtimeEnabled boolean */
@@ -6647,7 +6668,7 @@ function useCanvasContext() {
6647
6668
  function useCanvasContextStatic() {
6648
6669
  const context = useProductOptional();
6649
6670
  const realtimeContext = useRealtimeOptional();
6650
- const [staticValues] = (0, import_react26.useState)(() => ({
6671
+ const [staticValues] = (0, import_react27.useState)(() => ({
6651
6672
  sendCanvasBlob: realtimeContext?.sendCanvasBlob,
6652
6673
  isRealtimeEnabled: realtimeContext?.isEnabled ?? false,
6653
6674
  isConfigured: realtimeContext?.isConfigured ?? false,
@@ -6660,14 +6681,14 @@ function useCanvasContextStatic() {
6660
6681
  }
6661
6682
 
6662
6683
  // src/hooks/useRenderGuard.ts
6663
- var import_react27 = require("react");
6684
+ var import_react28 = require("react");
6664
6685
  function useRenderGuard({
6665
6686
  name,
6666
6687
  maxRendersPerSecond = 3,
6667
6688
  enabled = process.env.NODE_ENV === "development"
6668
6689
  }) {
6669
6690
  if (!enabled) return;
6670
- const timestampsRef = (0, import_react27.useRef)([]);
6691
+ const timestampsRef = (0, import_react28.useRef)([]);
6671
6692
  const now = performance.now();
6672
6693
  timestampsRef.current = timestampsRef.current.filter((t) => t > now - 1e3);
6673
6694
  timestampsRef.current.push(now);
@@ -6684,7 +6705,7 @@ function useRenderGuard({
6684
6705
  }
6685
6706
  }
6686
6707
  function useRenderCount(componentName) {
6687
- const countRef = (0, import_react27.useRef)(0);
6708
+ const countRef = (0, import_react28.useRef)(0);
6688
6709
  countRef.current++;
6689
6710
  if (process.env.NODE_ENV === "development" && componentName && countRef.current % 5 === 0) {
6690
6711
  }
@@ -6692,22 +6713,22 @@ function useRenderCount(componentName) {
6692
6713
  }
6693
6714
 
6694
6715
  // src/hooks/useScrollDirection.ts
6695
- var import_react28 = require("react");
6716
+ var import_react29 = require("react");
6696
6717
  var IDLE_TIMEOUT_MS = 150;
6697
6718
  var MIN_DELTA_PX = 5;
6698
6719
  function useScrollDirection() {
6699
- const [state, setState] = (0, import_react28.useState)({
6720
+ const [state, setState] = (0, import_react29.useState)({
6700
6721
  direction: "idle",
6701
6722
  velocity: 0,
6702
6723
  scrollY: typeof window !== "undefined" ? window.scrollY : 0
6703
6724
  });
6704
- const lastScrollRef = (0, import_react28.useRef)({
6725
+ const lastScrollRef = (0, import_react29.useRef)({
6705
6726
  top: typeof window !== "undefined" ? window.scrollY : 0,
6706
6727
  time: Date.now()
6707
6728
  });
6708
- const rafIdRef = (0, import_react28.useRef)(null);
6709
- const idleTimeoutRef = (0, import_react28.useRef)(null);
6710
- const handleScroll = (0, import_react28.useCallback)(() => {
6729
+ const rafIdRef = (0, import_react29.useRef)(null);
6730
+ const idleTimeoutRef = (0, import_react29.useRef)(null);
6731
+ const handleScroll = (0, import_react29.useCallback)(() => {
6711
6732
  if (rafIdRef.current !== null) return;
6712
6733
  rafIdRef.current = requestAnimationFrame(() => {
6713
6734
  const currentTop = window.scrollY;
@@ -6742,7 +6763,7 @@ function useScrollDirection() {
6742
6763
  rafIdRef.current = null;
6743
6764
  });
6744
6765
  }, []);
6745
- (0, import_react28.useEffect)(() => {
6766
+ (0, import_react29.useEffect)(() => {
6746
6767
  if (typeof window === "undefined") return;
6747
6768
  lastScrollRef.current = {
6748
6769
  top: window.scrollY,
@@ -6813,7 +6834,7 @@ function createScrollDirectionTracker() {
6813
6834
  }
6814
6835
 
6815
6836
  // src/hooks/useImageTransition.ts
6816
- var import_react29 = require("react");
6837
+ var import_react30 = require("react");
6817
6838
  var layerIdCounter = 0;
6818
6839
  function useImageTransition(options = {}) {
6819
6840
  const {
@@ -6823,7 +6844,7 @@ function useImageTransition(options = {}) {
6823
6844
  darkShimmerFadeInDuration = 300,
6824
6845
  initialUrl
6825
6846
  } = options;
6826
- const [state, setState] = (0, import_react29.useState)(() => {
6847
+ const [state, setState] = (0, import_react30.useState)(() => {
6827
6848
  return {
6828
6849
  layers: initialUrl ? [{ url: initialUrl, opacity: 1, id: ++layerIdCounter, loaded: true }] : [],
6829
6850
  preloadUrl: null,
@@ -6832,12 +6853,12 @@ function useImageTransition(options = {}) {
6832
6853
  shimmerType: "light"
6833
6854
  };
6834
6855
  });
6835
- const versionRef = (0, import_react29.useRef)(0);
6836
- const preloaderRef = (0, import_react29.useRef)(null);
6837
- const currentPreloadUrlRef = (0, import_react29.useRef)(null);
6838
- const shimmerTimerRef = (0, import_react29.useRef)(null);
6839
- const isMountedRef = (0, import_react29.useRef)(true);
6840
- (0, import_react29.useEffect)(() => {
6856
+ const versionRef = (0, import_react30.useRef)(0);
6857
+ const preloaderRef = (0, import_react30.useRef)(null);
6858
+ const currentPreloadUrlRef = (0, import_react30.useRef)(null);
6859
+ const shimmerTimerRef = (0, import_react30.useRef)(null);
6860
+ const isMountedRef = (0, import_react30.useRef)(true);
6861
+ (0, import_react30.useEffect)(() => {
6841
6862
  isMountedRef.current = true;
6842
6863
  return () => {
6843
6864
  isMountedRef.current = false;
@@ -6851,7 +6872,7 @@ function useImageTransition(options = {}) {
6851
6872
  }
6852
6873
  };
6853
6874
  }, []);
6854
- const setTargetUrl = (0, import_react29.useCallback)(
6875
+ const setTargetUrl = (0, import_react30.useCallback)(
6855
6876
  (url, shimmerType = "light") => {
6856
6877
  const version = ++versionRef.current;
6857
6878
  if (shimmerTimerRef.current) {
@@ -6969,7 +6990,7 @@ function useImageTransition(options = {}) {
6969
6990
  },
6970
6991
  [shimmerDelay]
6971
6992
  );
6972
- (0, import_react29.useEffect)(() => {
6993
+ (0, import_react30.useEffect)(() => {
6973
6994
  const topLayer = state.layers[state.layers.length - 1];
6974
6995
  if (topLayer && topLayer.opacity === 0 && !topLayer.waitForLoad) {
6975
6996
  const targetId = topLayer.id;
@@ -6989,7 +7010,7 @@ function useImageTransition(options = {}) {
6989
7010
  return () => cancelAnimationFrame(raf1);
6990
7011
  }
6991
7012
  }, [state.layers]);
6992
- (0, import_react29.useEffect)(() => {
7013
+ (0, import_react30.useEffect)(() => {
6993
7014
  if (state.showShimmer && state.shimmerOpacity === 0 && state.preloadUrl) {
6994
7015
  const raf = requestAnimationFrame(() => {
6995
7016
  if (!isMountedRef.current) return;
@@ -7004,7 +7025,7 @@ function useImageTransition(options = {}) {
7004
7025
  return () => cancelAnimationFrame(raf);
7005
7026
  }
7006
7027
  }, [state.showShimmer, state.shimmerOpacity, state.preloadUrl]);
7007
- (0, import_react29.useEffect)(() => {
7028
+ (0, import_react30.useEffect)(() => {
7008
7029
  if (state.showShimmer && state.shimmerOpacity === 0 && !state.preloadUrl) {
7009
7030
  const duration = state.shimmerType === "dark" ? fadeDuration : shimmerFadeDuration;
7010
7031
  const timer = setTimeout(() => {
@@ -7013,7 +7034,7 @@ function useImageTransition(options = {}) {
7013
7034
  return () => clearTimeout(timer);
7014
7035
  }
7015
7036
  }, [state.showShimmer, state.shimmerOpacity, state.preloadUrl, state.shimmerType, fadeDuration, shimmerFadeDuration]);
7016
- const onLayerTransitionEnd = (0, import_react29.useCallback)((layerId) => {
7037
+ const onLayerTransitionEnd = (0, import_react30.useCallback)((layerId) => {
7017
7038
  setState((prev) => {
7018
7039
  const idx = prev.layers.findIndex((l) => l.id === layerId);
7019
7040
  if (idx === -1 || prev.layers[idx].opacity !== 1) return prev;
@@ -7027,11 +7048,11 @@ function useImageTransition(options = {}) {
7027
7048
  return prev;
7028
7049
  });
7029
7050
  }, []);
7030
- const onPreloadComplete = (0, import_react29.useCallback)((_loadedUrl) => {
7051
+ const onPreloadComplete = (0, import_react30.useCallback)((_loadedUrl) => {
7031
7052
  }, []);
7032
- const onPreloadError = (0, import_react29.useCallback)(() => {
7053
+ const onPreloadError = (0, import_react30.useCallback)(() => {
7033
7054
  }, []);
7034
- const addLayerDirectly = (0, import_react29.useCallback)((url, options2) => {
7055
+ const addLayerDirectly = (0, import_react30.useCallback)((url, options2) => {
7035
7056
  const shouldShowShimmer = options2?.showShimmer ?? true;
7036
7057
  const skipTransition = options2?.skipTransition ?? false;
7037
7058
  const currentVersion = ++versionRef.current;
@@ -7122,7 +7143,7 @@ function useImageTransition(options = {}) {
7122
7143
  }, 500);
7123
7144
  }
7124
7145
  }, []);
7125
- const triggerShimmer = (0, import_react29.useCallback)((type = "dark") => {
7146
+ const triggerShimmer = (0, import_react30.useCallback)((type = "dark") => {
7126
7147
  setState((prev) => {
7127
7148
  if (prev.layers.length === 0) {
7128
7149
  return prev;
@@ -7141,7 +7162,7 @@ function useImageTransition(options = {}) {
7141
7162
  };
7142
7163
  });
7143
7164
  }, []);
7144
- const onImageLoad = (0, import_react29.useCallback)((layerId) => {
7165
+ const onImageLoad = (0, import_react30.useCallback)((layerId) => {
7145
7166
  if (shimmerTimerRef.current) {
7146
7167
  clearTimeout(shimmerTimerRef.current);
7147
7168
  shimmerTimerRef.current = null;
@@ -7183,7 +7204,7 @@ function useImageTransition(options = {}) {
7183
7204
  }
7184
7205
 
7185
7206
  // src/hooks/useImagePreloader.ts
7186
- var import_react30 = require("react");
7207
+ var import_react31 = require("react");
7187
7208
 
7188
7209
  // src/hooks/visibility/observerPool.ts
7189
7210
  var observerCallbacks = /* @__PURE__ */ new WeakMap();
@@ -7245,12 +7266,12 @@ function getObservedElementCount() {
7245
7266
  // src/hooks/useImagePreloader.ts
7246
7267
  function useImagePreloader(options = {}) {
7247
7268
  const { preloadMargin = 1e3, maxConcurrent = 2 } = options;
7248
- const [preloadedUrls, setPreloadedUrls] = (0, import_react30.useState)(/* @__PURE__ */ new Set());
7249
- const entriesRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
7250
- const preloadingCountRef = (0, import_react30.useRef)(0);
7251
- const preloadQueueRef = (0, import_react30.useRef)([]);
7252
- const preloadingUrlsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Set());
7253
- const processQueue = (0, import_react30.useCallback)(() => {
7269
+ const [preloadedUrls, setPreloadedUrls] = (0, import_react31.useState)(/* @__PURE__ */ new Set());
7270
+ const entriesRef = (0, import_react31.useRef)(/* @__PURE__ */ new Map());
7271
+ const preloadingCountRef = (0, import_react31.useRef)(0);
7272
+ const preloadQueueRef = (0, import_react31.useRef)([]);
7273
+ const preloadingUrlsRef = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
7274
+ const processQueue = (0, import_react31.useCallback)(() => {
7254
7275
  while (preloadingCountRef.current < maxConcurrent && preloadQueueRef.current.length > 0) {
7255
7276
  const src = preloadQueueRef.current.shift();
7256
7277
  if (preloadingUrlsRef.current.has(src) || preloadedUrls.has(src)) {
@@ -7275,17 +7296,17 @@ function useImagePreloader(options = {}) {
7275
7296
  img.onerror = handleComplete;
7276
7297
  }
7277
7298
  }, [maxConcurrent, preloadedUrls]);
7278
- const observerOptionsRef = (0, import_react30.useRef)({
7299
+ const observerOptionsRef = (0, import_react31.useRef)({
7279
7300
  rootMargin: `${preloadMargin}px 0px`,
7280
7301
  threshold: 0
7281
7302
  });
7282
- (0, import_react30.useEffect)(() => {
7303
+ (0, import_react31.useEffect)(() => {
7283
7304
  observerOptionsRef.current = {
7284
7305
  rootMargin: `${preloadMargin}px 0px`,
7285
7306
  threshold: 0
7286
7307
  };
7287
7308
  }, [preloadMargin]);
7288
- const registerElement = (0, import_react30.useCallback)(
7309
+ const registerElement = (0, import_react31.useCallback)(
7289
7310
  (key, element, src) => {
7290
7311
  const entries = entriesRef.current;
7291
7312
  const existingEntry = entries.get(key);
@@ -7349,14 +7370,14 @@ function useImagePreloader(options = {}) {
7349
7370
  },
7350
7371
  [preloadedUrls, processQueue]
7351
7372
  );
7352
- const isPreloaded = (0, import_react30.useCallback)(
7373
+ const isPreloaded = (0, import_react31.useCallback)(
7353
7374
  (src) => {
7354
7375
  if (!src) return false;
7355
7376
  return preloadedUrls.has(src);
7356
7377
  },
7357
7378
  [preloadedUrls]
7358
7379
  );
7359
- (0, import_react30.useEffect)(() => {
7380
+ (0, import_react31.useEffect)(() => {
7360
7381
  return () => {
7361
7382
  entriesRef.current.forEach((entry) => {
7362
7383
  if (entry.unobserve) {
@@ -7374,11 +7395,11 @@ function useImagePreloader(options = {}) {
7374
7395
  }
7375
7396
 
7376
7397
  // src/hooks/useDeviceDetection.ts
7377
- var import_react31 = require("react");
7398
+ var import_react32 = require("react");
7378
7399
  function useDeviceDetection() {
7379
- const [isTouchDevice, setIsTouchDevice] = (0, import_react31.useState)(false);
7380
- const [isSafari, setIsSafari] = (0, import_react31.useState)(false);
7381
- (0, import_react31.useEffect)(() => {
7400
+ const [isTouchDevice, setIsTouchDevice] = (0, import_react32.useState)(false);
7401
+ const [isSafari, setIsSafari] = (0, import_react32.useState)(false);
7402
+ (0, import_react32.useEffect)(() => {
7382
7403
  const hasTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0;
7383
7404
  setIsTouchDevice(hasTouch);
7384
7405
  const userAgent = navigator.userAgent;
@@ -7397,51 +7418,51 @@ function useDeviceDetection() {
7397
7418
  }
7398
7419
 
7399
7420
  // src/hooks/useProductPage.ts
7400
- var import_react33 = require("react");
7421
+ var import_react34 = require("react");
7401
7422
 
7402
7423
  // src/patterns/MockupPriorityProvider.tsx
7403
- var import_react32 = require("react");
7404
- var import_jsx_runtime52 = require("react/jsx-runtime");
7424
+ var import_react33 = require("react");
7425
+ var import_jsx_runtime53 = require("react/jsx-runtime");
7405
7426
  var MAX_LEVEL3_PREFETCH = 5;
7406
7427
  var PRIORITY_RECALC_DEBOUNCE_MS = 50;
7407
7428
  var PRELOAD_MARGIN_PX = 750;
7408
- var MockupPriorityContext = (0, import_react32.createContext)(
7429
+ var MockupPriorityContext = (0, import_react33.createContext)(
7409
7430
  void 0
7410
7431
  );
7411
7432
  function MockupPriorityProvider({ children }) {
7412
- (0, import_react32.useEffect)(() => {
7433
+ (0, import_react33.useEffect)(() => {
7413
7434
  return () => {
7414
7435
  };
7415
7436
  }, []);
7416
- const visibilityMapRef = (0, import_react32.useRef)(/* @__PURE__ */ new Map());
7417
- const prioritiesRef = (0, import_react32.useRef)(/* @__PURE__ */ new Map());
7418
- const level1MockupRef = (0, import_react32.useRef)(null);
7419
- const level2MockupsRef = (0, import_react32.useRef)([]);
7420
- const level3QueueRef = (0, import_react32.useRef)([]);
7421
- const mobileCarouselRef = (0, import_react32.useRef)(null);
7422
- const registrationOrderRef = (0, import_react32.useRef)([]);
7423
- const elementRefsRef = (0, import_react32.useRef)(/* @__PURE__ */ new Map());
7424
- const prioritySubscribersRef = (0, import_react32.useRef)(
7437
+ const visibilityMapRef = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
7438
+ const prioritiesRef = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
7439
+ const level1MockupRef = (0, import_react33.useRef)(null);
7440
+ const level2MockupsRef = (0, import_react33.useRef)([]);
7441
+ const level3QueueRef = (0, import_react33.useRef)([]);
7442
+ const mobileCarouselRef = (0, import_react33.useRef)(null);
7443
+ const registrationOrderRef = (0, import_react33.useRef)([]);
7444
+ const elementRefsRef = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
7445
+ const prioritySubscribersRef = (0, import_react33.useRef)(
7425
7446
  /* @__PURE__ */ new Map()
7426
7447
  );
7427
- const level1SubscribersRef = (0, import_react32.useRef)(
7448
+ const level1SubscribersRef = (0, import_react33.useRef)(
7428
7449
  /* @__PURE__ */ new Set()
7429
7450
  );
7430
7451
  const scrollState = useScrollDirection();
7431
- const scrollDirectionRef = (0, import_react32.useRef)("idle");
7452
+ const scrollDirectionRef = (0, import_react33.useRef)("idle");
7432
7453
  scrollDirectionRef.current = scrollState.direction;
7433
- const recalcTimeoutRef = (0, import_react32.useRef)(null);
7434
- const pendingRafRef = (0, import_react32.useRef)(null);
7435
- const [level1MockupId, setLevel1MockupId] = (0, import_react32.useState)(null);
7454
+ const recalcTimeoutRef = (0, import_react33.useRef)(null);
7455
+ const pendingRafRef = (0, import_react33.useRef)(null);
7456
+ const [level1MockupId, setLevel1MockupId] = (0, import_react33.useState)(null);
7436
7457
  const realtimeContext = useRealtimeOptional();
7437
- const currentRenderingLevelRef = (0, import_react32.useRef)(null);
7438
- const pendingMockupsRef = (0, import_react32.useRef)(/* @__PURE__ */ new Set());
7439
- const renderedMockupsRef = (0, import_react32.useRef)(/* @__PURE__ */ new Set());
7440
- const lastPendingBlobTimeRef = (0, import_react32.useRef)(0);
7458
+ const currentRenderingLevelRef = (0, import_react33.useRef)(null);
7459
+ const pendingMockupsRef = (0, import_react33.useRef)(/* @__PURE__ */ new Set());
7460
+ const renderedMockupsRef = (0, import_react33.useRef)(/* @__PURE__ */ new Set());
7461
+ const lastPendingBlobTimeRef = (0, import_react33.useRef)(0);
7441
7462
  const DRAG_STOP_DEBOUNCE_MS = 250;
7442
7463
  const BLOB_SEND_DELAY_MS = 100;
7443
- const pendingBlobRequestTimeoutRef = (0, import_react32.useRef)(null);
7444
- const requestMockupsForLevel = (0, import_react32.useCallback)((level) => {
7464
+ const pendingBlobRequestTimeoutRef = (0, import_react33.useRef)(null);
7465
+ const requestMockupsForLevel = (0, import_react33.useCallback)((level) => {
7445
7466
  if (!realtimeContext?.updateMockupIds) {
7446
7467
  return;
7447
7468
  }
@@ -7469,8 +7490,8 @@ function MockupPriorityProvider({ children }) {
7469
7490
  pendingMockupsRef.current = new Set(mockupIds);
7470
7491
  realtimeContext.updateMockupIds(mockupIds);
7471
7492
  }, [realtimeContext]);
7472
- const levelAdvanceTimeoutRef = (0, import_react32.useRef)(null);
7473
- const handleMockupResult = (0, import_react32.useCallback)((mockupId) => {
7493
+ const levelAdvanceTimeoutRef = (0, import_react33.useRef)(null);
7494
+ const handleMockupResult = (0, import_react33.useCallback)((mockupId) => {
7474
7495
  renderedMockupsRef.current.add(mockupId);
7475
7496
  pendingMockupsRef.current.delete(mockupId);
7476
7497
  const currentLevel = currentRenderingLevelRef.current;
@@ -7506,7 +7527,7 @@ function MockupPriorityProvider({ children }) {
7506
7527
  }
7507
7528
  }
7508
7529
  }, [requestMockupsForLevel]);
7509
- (0, import_react32.useEffect)(() => {
7530
+ (0, import_react33.useEffect)(() => {
7510
7531
  if (!realtimeContext?.subscribeMockupResults) return;
7511
7532
  const unsubscribe = realtimeContext.subscribeMockupResults((results) => {
7512
7533
  results.forEach((result) => {
@@ -7515,13 +7536,13 @@ function MockupPriorityProvider({ children }) {
7515
7536
  });
7516
7537
  return unsubscribe;
7517
7538
  }, [realtimeContext, handleMockupResult]);
7518
- (0, import_react32.useEffect)(() => {
7539
+ (0, import_react33.useEffect)(() => {
7519
7540
  if (realtimeContext?.isConfigured && level1MockupRef.current) {
7520
7541
  renderedMockupsRef.current.clear();
7521
7542
  requestMockupsForLevel(1);
7522
7543
  }
7523
7544
  }, [realtimeContext, requestMockupsForLevel]);
7524
- (0, import_react32.useEffect)(() => {
7545
+ (0, import_react33.useEffect)(() => {
7525
7546
  if (level1MockupId === null) {
7526
7547
  return;
7527
7548
  }
@@ -7531,7 +7552,7 @@ function MockupPriorityProvider({ children }) {
7531
7552
  renderedMockupsRef.current.clear();
7532
7553
  requestMockupsForLevel(1);
7533
7554
  }, [level1MockupId, realtimeContext?.isConfigured, requestMockupsForLevel]);
7534
- (0, import_react32.useEffect)(() => {
7555
+ (0, import_react33.useEffect)(() => {
7535
7556
  if (!realtimeContext?.subscribePendingBlob) return;
7536
7557
  const handlePendingBlob = (placement) => {
7537
7558
  lastPendingBlobTimeRef.current = Date.now();
@@ -7543,7 +7564,7 @@ function MockupPriorityProvider({ children }) {
7543
7564
  const unsubscribe = realtimeContext.subscribePendingBlob(handlePendingBlob);
7544
7565
  return unsubscribe;
7545
7566
  }, [realtimeContext]);
7546
- (0, import_react32.useEffect)(() => {
7567
+ (0, import_react33.useEffect)(() => {
7547
7568
  if (!realtimeContext?.subscribeBlobSent) return;
7548
7569
  const handleBlobSent = (placement) => {
7549
7570
  if (pendingBlobRequestTimeoutRef.current) {
@@ -7560,7 +7581,7 @@ function MockupPriorityProvider({ children }) {
7560
7581
  const unsubscribe = realtimeContext.subscribeBlobSent(handleBlobSent);
7561
7582
  return unsubscribe;
7562
7583
  }, [realtimeContext, requestMockupsForLevel]);
7563
- const recalculatePriorities = (0, import_react32.useCallback)(() => {
7584
+ const recalculatePriorities = (0, import_react33.useCallback)(() => {
7564
7585
  const mobileState = mobileCarouselRef.current;
7565
7586
  if (mobileState && mobileState.mockupIds.length > 0) {
7566
7587
  const { currentIndex, mockupIds } = mobileState;
@@ -7650,7 +7671,7 @@ function MockupPriorityProvider({ children }) {
7650
7671
  subscribers?.forEach((cb) => cb(newLevel));
7651
7672
  });
7652
7673
  }, []);
7653
- const scheduleRecalculation = (0, import_react32.useCallback)(() => {
7674
+ const scheduleRecalculation = (0, import_react33.useCallback)(() => {
7654
7675
  if (recalcTimeoutRef.current) {
7655
7676
  clearTimeout(recalcTimeoutRef.current);
7656
7677
  }
@@ -7659,7 +7680,7 @@ function MockupPriorityProvider({ children }) {
7659
7680
  recalcTimeoutRef.current = null;
7660
7681
  }, PRIORITY_RECALC_DEBOUNCE_MS);
7661
7682
  }, [recalculatePriorities]);
7662
- (0, import_react32.useEffect)(() => {
7683
+ (0, import_react33.useEffect)(() => {
7663
7684
  return () => {
7664
7685
  if (recalcTimeoutRef.current) {
7665
7686
  clearTimeout(recalcTimeoutRef.current);
@@ -7675,7 +7696,7 @@ function MockupPriorityProvider({ children }) {
7675
7696
  }
7676
7697
  };
7677
7698
  }, []);
7678
- const updateVisibilityFromRefs = (0, import_react32.useCallback)(() => {
7699
+ const updateVisibilityFromRefs = (0, import_react33.useCallback)(() => {
7679
7700
  const viewportHeight = typeof window !== "undefined" ? window.innerHeight : 800;
7680
7701
  const viewportWidth = typeof window !== "undefined" ? window.innerWidth : 1200;
7681
7702
  const viewportCenterY = viewportHeight / 2;
@@ -7716,7 +7737,7 @@ function MockupPriorityProvider({ children }) {
7716
7737
  });
7717
7738
  });
7718
7739
  }, []);
7719
- (0, import_react32.useEffect)(() => {
7740
+ (0, import_react33.useEffect)(() => {
7720
7741
  const pollVisibility = () => {
7721
7742
  updateVisibilityFromRefs();
7722
7743
  recalculatePriorities();
@@ -7729,7 +7750,7 @@ function MockupPriorityProvider({ children }) {
7729
7750
  window.removeEventListener("scroll", pollVisibility);
7730
7751
  };
7731
7752
  }, [updateVisibilityFromRefs, recalculatePriorities]);
7732
- const registerMockup = (0, import_react32.useCallback)(
7753
+ const registerMockup = (0, import_react33.useCallback)(
7733
7754
  (mockupId, placement, initialPriority, elementRef) => {
7734
7755
  if (!registrationOrderRef.current.includes(mockupId)) {
7735
7756
  registrationOrderRef.current.push(mockupId);
@@ -7778,7 +7799,7 @@ function MockupPriorityProvider({ children }) {
7778
7799
  },
7779
7800
  []
7780
7801
  );
7781
- const unregisterMockup = (0, import_react32.useCallback)((mockupId) => {
7802
+ const unregisterMockup = (0, import_react33.useCallback)((mockupId) => {
7782
7803
  visibilityMapRef.current.delete(mockupId);
7783
7804
  prioritiesRef.current.delete(mockupId);
7784
7805
  prioritySubscribersRef.current.delete(mockupId);
@@ -7793,7 +7814,7 @@ function MockupPriorityProvider({ children }) {
7793
7814
  scheduleRecalculation();
7794
7815
  }
7795
7816
  }, [scheduleRecalculation]);
7796
- const updateElementRef = (0, import_react32.useCallback)((mockupId, element) => {
7817
+ const updateElementRef = (0, import_react33.useCallback)((mockupId, element) => {
7797
7818
  if (element) {
7798
7819
  const rect = element.getBoundingClientRect();
7799
7820
  if (rect.height === 0 || rect.width === 0) {
@@ -7806,7 +7827,7 @@ function MockupPriorityProvider({ children }) {
7806
7827
  elementRefsRef.current.delete(mockupId);
7807
7828
  }
7808
7829
  }, [updateVisibilityFromRefs, scheduleRecalculation]);
7809
- const reportVisibility = (0, import_react32.useCallback)(
7830
+ const reportVisibility = (0, import_react33.useCallback)(
7810
7831
  (mockupId, ratio, boundingRect) => {
7811
7832
  const existing = visibilityMapRef.current.get(mockupId);
7812
7833
  if (!existing) {
@@ -7855,21 +7876,21 @@ function MockupPriorityProvider({ children }) {
7855
7876
  },
7856
7877
  [scheduleRecalculation, recalculatePriorities]
7857
7878
  );
7858
- const reportMobileCarouselIndex = (0, import_react32.useCallback)(
7879
+ const reportMobileCarouselIndex = (0, import_react33.useCallback)(
7859
7880
  (currentIndex, mockupIds) => {
7860
7881
  mobileCarouselRef.current = { currentIndex, mockupIds };
7861
7882
  recalculatePriorities();
7862
7883
  },
7863
7884
  [recalculatePriorities]
7864
7885
  );
7865
- const clearMobileCarouselMode = (0, import_react32.useCallback)(() => {
7886
+ const clearMobileCarouselMode = (0, import_react33.useCallback)(() => {
7866
7887
  mobileCarouselRef.current = null;
7867
7888
  recalculatePriorities();
7868
7889
  }, [recalculatePriorities]);
7869
- const getPriorityLevel = (0, import_react32.useCallback)((mockupId) => {
7890
+ const getPriorityLevel = (0, import_react33.useCallback)((mockupId) => {
7870
7891
  return prioritiesRef.current.get(mockupId) || 3;
7871
7892
  }, []);
7872
- const getQueuePriority = (0, import_react32.useCallback)((mockupId) => {
7893
+ const getQueuePriority = (0, import_react33.useCallback)((mockupId) => {
7873
7894
  const level = prioritiesRef.current.get(mockupId) || 3;
7874
7895
  switch (level) {
7875
7896
  case 1:
@@ -7882,19 +7903,19 @@ function MockupPriorityProvider({ children }) {
7882
7903
  return 10;
7883
7904
  }
7884
7905
  }, []);
7885
- const getLevel1Mockup = (0, import_react32.useCallback)(() => {
7906
+ const getLevel1Mockup = (0, import_react33.useCallback)(() => {
7886
7907
  return level1MockupRef.current;
7887
7908
  }, []);
7888
- const getLevel2Mockups = (0, import_react32.useCallback)(() => {
7909
+ const getLevel2Mockups = (0, import_react33.useCallback)(() => {
7889
7910
  return [...level2MockupsRef.current];
7890
7911
  }, []);
7891
- const getLevel3Queue = (0, import_react32.useCallback)(() => {
7912
+ const getLevel3Queue = (0, import_react33.useCallback)(() => {
7892
7913
  return [...level3QueueRef.current];
7893
7914
  }, []);
7894
- const getVisibility = (0, import_react32.useCallback)((mockupId) => {
7915
+ const getVisibility = (0, import_react33.useCallback)((mockupId) => {
7895
7916
  return visibilityMapRef.current.get(mockupId) || null;
7896
7917
  }, []);
7897
- const getMockupIdsForLevel = (0, import_react32.useCallback)((level) => {
7918
+ const getMockupIdsForLevel = (0, import_react33.useCallback)((level) => {
7898
7919
  switch (level) {
7899
7920
  case 1:
7900
7921
  return level1MockupRef.current ? [level1MockupRef.current] : [];
@@ -7906,16 +7927,16 @@ function MockupPriorityProvider({ children }) {
7906
7927
  return [];
7907
7928
  }
7908
7929
  }, []);
7909
- const shouldPauseLevel = (0, import_react32.useCallback)((level) => {
7930
+ const shouldPauseLevel = (0, import_react33.useCallback)((level) => {
7910
7931
  if (level === 2) {
7911
7932
  return level1MockupRef.current !== null;
7912
7933
  }
7913
7934
  return level1MockupRef.current !== null || level2MockupsRef.current.length > 0;
7914
7935
  }, []);
7915
- const isLevel1Active = (0, import_react32.useCallback)(() => {
7936
+ const isLevel1Active = (0, import_react33.useCallback)(() => {
7916
7937
  return level1MockupRef.current !== null;
7917
7938
  }, []);
7918
- const subscribePriorityChange = (0, import_react32.useCallback)(
7939
+ const subscribePriorityChange = (0, import_react33.useCallback)(
7919
7940
  (mockupId, callback) => {
7920
7941
  if (!prioritySubscribersRef.current.has(mockupId)) {
7921
7942
  prioritySubscribersRef.current.set(mockupId, /* @__PURE__ */ new Set());
@@ -7935,7 +7956,7 @@ function MockupPriorityProvider({ children }) {
7935
7956
  },
7936
7957
  []
7937
7958
  );
7938
- const subscribeLevel1Change = (0, import_react32.useCallback)(
7959
+ const subscribeLevel1Change = (0, import_react33.useCallback)(
7939
7960
  (callback) => {
7940
7961
  level1SubscribersRef.current.add(callback);
7941
7962
  callback(level1MockupRef.current);
@@ -7945,7 +7966,7 @@ function MockupPriorityProvider({ children }) {
7945
7966
  },
7946
7967
  []
7947
7968
  );
7948
- const contextValue = (0, import_react32.useMemo)(
7969
+ const contextValue = (0, import_react33.useMemo)(
7949
7970
  () => ({
7950
7971
  registerMockup,
7951
7972
  unregisterMockup,
@@ -7985,10 +8006,10 @@ function MockupPriorityProvider({ children }) {
7985
8006
  subscribeLevel1Change
7986
8007
  ]
7987
8008
  );
7988
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MockupPriorityContext.Provider, { value: contextValue, children });
8009
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(MockupPriorityContext.Provider, { value: contextValue, children });
7989
8010
  }
7990
8011
  function useMockupPriority() {
7991
- const context = (0, import_react32.useContext)(MockupPriorityContext);
8012
+ const context = (0, import_react33.useContext)(MockupPriorityContext);
7992
8013
  if (!context) {
7993
8014
  throw new Error(
7994
8015
  "useMockupPriority must be used within a MockupPriorityProvider"
@@ -7997,7 +8018,7 @@ function useMockupPriority() {
7997
8018
  return context;
7998
8019
  }
7999
8020
  function useMockupPriorityOptional() {
8000
- return (0, import_react32.useContext)(MockupPriorityContext);
8021
+ return (0, import_react33.useContext)(MockupPriorityContext);
8001
8022
  }
8002
8023
 
8003
8024
  // src/hooks/useProductPage.ts
@@ -8028,7 +8049,7 @@ function useProductPage() {
8028
8049
  const realtime = useRealtimeOptional();
8029
8050
  const priority = useMockupPriorityOptional();
8030
8051
  const providers = useProviderStatus();
8031
- return (0, import_react33.useMemo)(
8052
+ return (0, import_react34.useMemo)(
8032
8053
  () => ({
8033
8054
  // Product Data
8034
8055
  product: productCtx.product,
@@ -8122,7 +8143,7 @@ function useArtworkAlignment(placement) {
8122
8143
  }
8123
8144
  function useSetArtworkAlignment() {
8124
8145
  const productCtx = useProductOptional();
8125
- return (0, import_react33.useCallback)(
8146
+ return (0, import_react34.useCallback)(
8126
8147
  (placement, alignment) => {
8127
8148
  if (productCtx) {
8128
8149
  const currentDesign = productCtx.placements[placement];
@@ -8139,7 +8160,7 @@ function useSelectedArtwork() {
8139
8160
  const productCtx = useProductOptional();
8140
8161
  const shopCtx = useShopOptional();
8141
8162
  const ctx = productCtx || shopCtx;
8142
- const setArtwork = (0, import_react33.useCallback)(
8163
+ const setArtwork = (0, import_react34.useCallback)(
8143
8164
  (artwork) => {
8144
8165
  ctx?.setSelectedArtwork(artwork);
8145
8166
  },
@@ -8149,7 +8170,7 @@ function useSelectedArtwork() {
8149
8170
  }
8150
8171
  function useProductSelection() {
8151
8172
  const productCtx = useProductOptional();
8152
- const update = (0, import_react33.useCallback)(
8173
+ const update = (0, import_react34.useCallback)(
8153
8174
  (selection) => {
8154
8175
  productCtx?.updateSelection?.(selection);
8155
8176
  },
@@ -8159,7 +8180,7 @@ function useProductSelection() {
8159
8180
  }
8160
8181
  function usePlacementClipShape(placement) {
8161
8182
  const productCtx = useProductOptional();
8162
- const setShape = (0, import_react33.useCallback)(
8183
+ const setShape = (0, import_react34.useCallback)(
8163
8184
  (shape) => {
8164
8185
  productCtx?.setPlacementClipShape(placement, shape);
8165
8186
  },
@@ -8172,10 +8193,10 @@ function usePlacementClipShape(placement) {
8172
8193
  }
8173
8194
 
8174
8195
  // src/hooks/viewport/useMediaQuery.ts
8175
- var import_react34 = require("react");
8196
+ var import_react35 = require("react");
8176
8197
  function useMediaQuery(query) {
8177
- const [matches, setMatches] = (0, import_react34.useState)(null);
8178
- (0, import_react34.useEffect)(() => {
8198
+ const [matches, setMatches] = (0, import_react35.useState)(null);
8199
+ (0, import_react35.useEffect)(() => {
8179
8200
  const media = window.matchMedia(query);
8180
8201
  setMatches(media.matches);
8181
8202
  const listener = () => setMatches(media.matches);
@@ -8186,15 +8207,15 @@ function useMediaQuery(query) {
8186
8207
  }
8187
8208
 
8188
8209
  // src/hooks/viewport/useViewportDimensions.ts
8189
- var import_react35 = require("react");
8210
+ var import_react36 = require("react");
8190
8211
  function useViewportDimensions(isDesktop) {
8191
- const [dimensions, setDimensions] = (0, import_react35.useState)({
8212
+ const [dimensions, setDimensions] = (0, import_react36.useState)({
8192
8213
  width: 0,
8193
8214
  height: 0,
8194
8215
  aspectRatio: 0,
8195
8216
  resizeVersion: 0
8196
8217
  });
8197
- (0, import_react35.useEffect)(() => {
8218
+ (0, import_react36.useEffect)(() => {
8198
8219
  const width = window.innerWidth;
8199
8220
  const height = window.innerHeight;
8200
8221
  setDimensions((prev) => ({
@@ -8205,7 +8226,7 @@ function useViewportDimensions(isDesktop) {
8205
8226
  // Keep at 0 for initial mount
8206
8227
  }));
8207
8228
  }, []);
8208
- (0, import_react35.useLayoutEffect)(() => {
8229
+ (0, import_react36.useLayoutEffect)(() => {
8209
8230
  if (isDesktop !== true) return;
8210
8231
  const width = window.innerWidth;
8211
8232
  const height = window.innerHeight;
@@ -8217,7 +8238,7 @@ function useViewportDimensions(isDesktop) {
8217
8238
  resizeVersion: prev.resizeVersion + 1
8218
8239
  }));
8219
8240
  }, [isDesktop]);
8220
- (0, import_react35.useEffect)(() => {
8241
+ (0, import_react36.useEffect)(() => {
8221
8242
  if (isDesktop !== true) return;
8222
8243
  let resizeTimeout = null;
8223
8244
  let lastWidth = window.innerWidth;
@@ -8258,7 +8279,7 @@ function useViewportDimensions(isDesktop) {
8258
8279
  }
8259
8280
 
8260
8281
  // src/hooks/viewport/useResponsiveImageCap.ts
8261
- var import_react36 = require("react");
8282
+ var import_react37 = require("react");
8262
8283
  var DEFAULT_IMAGE_CONFIG = {
8263
8284
  ASPECT_RATIO: 16 / 9,
8264
8285
  WIDTH_VW: 140,
@@ -8270,7 +8291,7 @@ var DEFAULT_IMAGE_CONFIG = {
8270
8291
  };
8271
8292
  function useResponsiveImageCap(dimensions, options = {}) {
8272
8293
  const { aspectRatio = DEFAULT_IMAGE_CONFIG.ASPECT_RATIO, sidebarWidthPx } = options;
8273
- return (0, import_react36.useMemo)(() => {
8294
+ return (0, import_react37.useMemo)(() => {
8274
8295
  const vw = dimensions.width;
8275
8296
  const vh = dimensions.height;
8276
8297
  const viewportAspectRatio = dimensions.aspectRatio;
@@ -8328,7 +8349,7 @@ function useResponsiveImageCap(dimensions, options = {}) {
8328
8349
  }
8329
8350
 
8330
8351
  // src/hooks/viewport/useWideMonitorMode.ts
8331
- var import_react37 = require("react");
8352
+ var import_react38 = require("react");
8332
8353
  var LAYOUT_CONFIG = {
8333
8354
  SIDEBAR_MAX_PX: 384,
8334
8355
  SIDEBAR_MARGIN_PX: 32,
@@ -8368,7 +8389,7 @@ function hasEdgeBlur(viewportWidth, maxWidthPx, sidebarPercent = 0.35, sidebarWi
8368
8389
  return gap > 10;
8369
8390
  }
8370
8391
  function useWideMonitorMode(imageCapInfo, sidebarPercent) {
8371
- return (0, import_react37.useMemo)(() => {
8392
+ return (0, import_react38.useMemo)(() => {
8372
8393
  const { viewportWidth, maxWidthPx } = imageCapInfo;
8373
8394
  if (viewportWidth < 768) return false;
8374
8395
  const effectiveSidebarPercent = sidebarPercent ?? (viewportWidth >= 1280 ? 0.35 : 0.3);
@@ -8723,8 +8744,8 @@ var CanvasExportService = class _CanvasExportService {
8723
8744
  var canvasExportService = new CanvasExportService();
8724
8745
 
8725
8746
  // src/components/CanvasIsolationBoundary.tsx
8726
- var import_react38 = __toESM(require("react"), 1);
8727
- var import_jsx_runtime53 = require("react/jsx-runtime");
8747
+ var import_react39 = __toESM(require("react"), 1);
8748
+ var import_jsx_runtime54 = require("react/jsx-runtime");
8728
8749
  function CanvasIsolationConfigurator({
8729
8750
  placementName: placementNameProp,
8730
8751
  onArtworkChange,
@@ -8733,7 +8754,7 @@ function CanvasIsolationConfigurator({
8733
8754
  }) {
8734
8755
  const productContext = useProductOptional();
8735
8756
  const realtimeContext = useRealtimeOptional();
8736
- (0, import_react38.useEffect)(() => {
8757
+ (0, import_react39.useEffect)(() => {
8737
8758
  canvasExportService.configure({
8738
8759
  sendCanvasBlob: realtimeContext?.sendCanvasBlob,
8739
8760
  sendCanvasState: realtimeContext?.sendCanvasState,
@@ -8764,16 +8785,16 @@ function CanvasIsolationConfigurator({
8764
8785
  onArtworkChange,
8765
8786
  clearImageBitmapCache
8766
8787
  ]);
8767
- (0, import_react38.useEffect)(() => {
8788
+ (0, import_react39.useEffect)(() => {
8768
8789
  return () => {
8769
8790
  canvasExportService.reset();
8770
8791
  };
8771
8792
  }, []);
8772
8793
  return null;
8773
8794
  }
8774
- var IsolatedChildren = import_react38.default.memo(
8795
+ var IsolatedChildren = import_react39.default.memo(
8775
8796
  function IsolatedChildren2({ children }) {
8776
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_jsx_runtime53.Fragment, { children });
8797
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_jsx_runtime54.Fragment, { children });
8777
8798
  },
8778
8799
  // Custom comparison: ALWAYS return true (never re-render due to parent changes)
8779
8800
  // This is intentional - children should use refs/services for updates that need to bypass this
@@ -8786,8 +8807,8 @@ function CanvasIsolationBoundary({
8786
8807
  clearImageBitmapCache,
8787
8808
  serializeStateForServer
8788
8809
  }) {
8789
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
8790
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8810
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
8811
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
8791
8812
  CanvasIsolationConfigurator,
8792
8813
  {
8793
8814
  placementName,
@@ -8796,7 +8817,7 @@ function CanvasIsolationBoundary({
8796
8817
  serializeStateForServer
8797
8818
  }
8798
8819
  ),
8799
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IsolatedChildren, { children })
8820
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(IsolatedChildren, { children })
8800
8821
  ] });
8801
8822
  }
8802
8823
  function useIsolatedCanvas() {
@@ -8819,8 +8840,8 @@ function useIsolatedCanvas() {
8819
8840
  }
8820
8841
 
8821
8842
  // src/components/LoadingOverlayPrism.tsx
8822
- var import_react39 = require("react");
8823
- var import_jsx_runtime54 = require("react/jsx-runtime");
8843
+ var import_react40 = require("react");
8844
+ var import_jsx_runtime55 = require("react/jsx-runtime");
8824
8845
  function generateParticles() {
8825
8846
  return Array.from({ length: 16 }, () => ({
8826
8847
  left: 10 + Math.random() * 80,
@@ -8924,18 +8945,18 @@ function LoadingOverlayPrism({
8924
8945
  }) {
8925
8946
  ensureStyles();
8926
8947
  console.log(`[Prism] render visible=${visible}`);
8927
- const [mounted, setMounted] = (0, import_react39.useState)(false);
8928
- (0, import_react39.useEffect)(() => {
8948
+ const [mounted, setMounted] = (0, import_react40.useState)(false);
8949
+ (0, import_react40.useEffect)(() => {
8929
8950
  console.log(`[Prism] MOUNTED \u2014 scheduling fade-in`);
8930
8951
  const raf = requestAnimationFrame(() => setMounted(true));
8931
8952
  return () => cancelAnimationFrame(raf);
8932
8953
  }, []);
8933
- const [particles, setParticles] = (0, import_react39.useState)([]);
8934
- (0, import_react39.useEffect)(() => {
8954
+ const [particles, setParticles] = (0, import_react40.useState)([]);
8955
+ (0, import_react40.useEffect)(() => {
8935
8956
  setParticles(generateParticles());
8936
8957
  }, []);
8937
- const prevVisibleRef = (0, import_react39.useRef)(visible);
8938
- (0, import_react39.useEffect)(() => {
8958
+ const prevVisibleRef = (0, import_react40.useRef)(visible);
8959
+ (0, import_react40.useEffect)(() => {
8939
8960
  if (prevVisibleRef.current && !visible) {
8940
8961
  console.log(`[Prism] visible changed true\u2192false \u2014 FADE-OUT STARTING`);
8941
8962
  } else if (!prevVisibleRef.current && visible) {
@@ -8943,7 +8964,7 @@ function LoadingOverlayPrism({
8943
8964
  }
8944
8965
  prevVisibleRef.current = visible;
8945
8966
  }, [visible]);
8946
- const handleTransitionEnd = (0, import_react39.useCallback)(() => {
8967
+ const handleTransitionEnd = (0, import_react40.useCallback)(() => {
8947
8968
  if (!visible) {
8948
8969
  console.log(`[Prism] FADE-OUT COMPLETE \u2014 calling onExited`);
8949
8970
  onExited?.();
@@ -8957,20 +8978,20 @@ function LoadingOverlayPrism({
8957
8978
  } else if (mounted) {
8958
8979
  fadeClass = " prism-fade-in";
8959
8980
  }
8960
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
8981
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
8961
8982
  "div",
8962
8983
  {
8963
8984
  className: `prism-loading-overlay absolute inset-0${fadeClass}`,
8964
8985
  onTransitionEnd: handleTransitionEnd,
8965
8986
  children: [
8966
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "prism-loading-rainbow", children: [
8967
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "prism-loading-band" }),
8968
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "prism-loading-band" }),
8969
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "prism-loading-band" }),
8970
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "prism-loading-band" }),
8971
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "prism-loading-band" })
8987
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "prism-loading-rainbow", children: [
8988
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "prism-loading-band" }),
8989
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "prism-loading-band" }),
8990
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "prism-loading-band" }),
8991
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "prism-loading-band" }),
8992
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "prism-loading-band" })
8972
8993
  ] }),
8973
- particles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
8994
+ particles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
8974
8995
  "div",
8975
8996
  {
8976
8997
  className: "prism-loading-particle",
@@ -8992,9 +9013,9 @@ function LoadingOverlayPrism({
8992
9013
  }
8993
9014
  var SHOW_DELAY_MS = 200;
8994
9015
  function useLoadingOverlay(isLoading) {
8995
- const [showOverlay, setShowOverlay] = (0, import_react39.useState)(false);
8996
- const timerRef = (0, import_react39.useRef)(null);
8997
- (0, import_react39.useEffect)(() => {
9016
+ const [showOverlay, setShowOverlay] = (0, import_react40.useState)(false);
9017
+ const timerRef = (0, import_react40.useRef)(null);
9018
+ (0, import_react40.useEffect)(() => {
8998
9019
  if (isLoading) {
8999
9020
  timerRef.current = setTimeout(() => {
9000
9021
  setShowOverlay(true);
@@ -9012,7 +9033,7 @@ function useLoadingOverlay(isLoading) {
9012
9033
  }
9013
9034
  };
9014
9035
  }, [isLoading]);
9015
- const handleExited = (0, import_react39.useCallback)(() => {
9036
+ const handleExited = (0, import_react40.useCallback)(() => {
9016
9037
  setShowOverlay(false);
9017
9038
  }, []);
9018
9039
  return {
@@ -9023,9 +9044,9 @@ function useLoadingOverlay(isLoading) {
9023
9044
  }
9024
9045
 
9025
9046
  // src/components/LoadingOverlayPrismCandy.tsx
9026
- var import_react40 = require("react");
9047
+ var import_react41 = require("react");
9027
9048
  var import_react_dom2 = require("react-dom");
9028
- var import_jsx_runtime55 = require("react/jsx-runtime");
9049
+ var import_jsx_runtime56 = require("react/jsx-runtime");
9029
9050
  var BANDS = [
9030
9051
  { rgb: "230, 45, 55", delay: "-0.0s" },
9031
9052
  // red
@@ -9195,19 +9216,19 @@ function CandyVisual({
9195
9216
  onTransitionEnd,
9196
9217
  variantClass = ""
9197
9218
  }) {
9198
- const [particles, setParticles] = (0, import_react40.useState)([]);
9199
- (0, import_react40.useEffect)(() => {
9219
+ const [particles, setParticles] = (0, import_react41.useState)([]);
9220
+ (0, import_react41.useEffect)(() => {
9200
9221
  setParticles(generateParticles2());
9201
9222
  }, []);
9202
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
9223
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
9203
9224
  "div",
9204
9225
  {
9205
9226
  className: `candy-loading-overlay ${variantClass} ${fadeClass}`.trim(),
9206
9227
  style,
9207
9228
  onTransitionEnd,
9208
9229
  children: [
9209
- BANDS.map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "candy-band" }, `b-${i}`)),
9210
- particles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9230
+ BANDS.map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "candy-band" }, `b-${i}`)),
9231
+ particles.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9211
9232
  "div",
9212
9233
  {
9213
9234
  className: "candy-particle",
@@ -9226,15 +9247,15 @@ function CandyVisual({
9226
9247
  }
9227
9248
  );
9228
9249
  }
9229
- var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayPrismCandy2({
9250
+ var LoadingOverlayPrismCandy = (0, import_react41.memo)(function LoadingOverlayPrismCandy2({
9230
9251
  visible = true,
9231
9252
  onExited
9232
9253
  }) {
9233
9254
  ensureStyles2();
9234
- const anchorRef = (0, import_react40.useRef)(null);
9235
- const [bounds, setBounds] = (0, import_react40.useState)(null);
9236
- const [mounted, setMounted] = (0, import_react40.useState)(false);
9237
- const measure = (0, import_react40.useCallback)(() => {
9255
+ const anchorRef = (0, import_react41.useRef)(null);
9256
+ const [bounds, setBounds] = (0, import_react41.useState)(null);
9257
+ const [mounted, setMounted] = (0, import_react41.useState)(false);
9258
+ const measure = (0, import_react41.useCallback)(() => {
9238
9259
  const el = anchorRef.current;
9239
9260
  if (!el) return;
9240
9261
  const r = el.getBoundingClientRect();
@@ -9245,7 +9266,7 @@ var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayP
9245
9266
  height: r.height
9246
9267
  });
9247
9268
  }, []);
9248
- (0, import_react40.useLayoutEffect)(() => {
9269
+ (0, import_react41.useLayoutEffect)(() => {
9249
9270
  measure();
9250
9271
  window.addEventListener("resize", measure);
9251
9272
  let ro = null;
@@ -9258,11 +9279,11 @@ var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayP
9258
9279
  ro?.disconnect();
9259
9280
  };
9260
9281
  }, [measure]);
9261
- (0, import_react40.useEffect)(() => {
9282
+ (0, import_react41.useEffect)(() => {
9262
9283
  const raf = requestAnimationFrame(() => setMounted(true));
9263
9284
  return () => cancelAnimationFrame(raf);
9264
9285
  }, []);
9265
- const handleTransitionEnd = (0, import_react40.useCallback)(
9286
+ const handleTransitionEnd = (0, import_react41.useCallback)(
9266
9287
  (e) => {
9267
9288
  if (e.propertyName !== "background-color") return;
9268
9289
  if (!visible) onExited?.();
@@ -9272,8 +9293,8 @@ var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayP
9272
9293
  let fadeClass = "";
9273
9294
  if (!visible) fadeClass = "candy-fade-out";
9274
9295
  else if (mounted) fadeClass = "candy-fade-in";
9275
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
9276
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9296
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
9297
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9277
9298
  "div",
9278
9299
  {
9279
9300
  ref: anchorRef,
@@ -9286,7 +9307,7 @@ var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayP
9286
9307
  }
9287
9308
  ),
9288
9309
  bounds && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
9289
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9310
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9290
9311
  CandyVisual,
9291
9312
  {
9292
9313
  fadeClass,
@@ -9305,19 +9326,19 @@ var LoadingOverlayPrismCandy = (0, import_react40.memo)(function LoadingOverlayP
9305
9326
  )
9306
9327
  ] });
9307
9328
  });
9308
- var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
9329
+ var LoadingOverlayPrismCandyInline = (0, import_react41.memo)(
9309
9330
  function LoadingOverlayPrismCandyInline2({
9310
9331
  visible = true,
9311
9332
  onExited,
9312
9333
  variant = "dark"
9313
9334
  }) {
9314
9335
  ensureStyles2();
9315
- const [mounted, setMounted] = (0, import_react40.useState)(false);
9316
- (0, import_react40.useEffect)(() => {
9336
+ const [mounted, setMounted] = (0, import_react41.useState)(false);
9337
+ (0, import_react41.useEffect)(() => {
9317
9338
  const raf = requestAnimationFrame(() => setMounted(true));
9318
9339
  return () => cancelAnimationFrame(raf);
9319
9340
  }, []);
9320
- const handleTransitionEnd = (0, import_react40.useCallback)(
9341
+ const handleTransitionEnd = (0, import_react41.useCallback)(
9321
9342
  (e) => {
9322
9343
  if (e.propertyName !== "background-color") return;
9323
9344
  if (!visible) onExited?.();
@@ -9327,7 +9348,7 @@ var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
9327
9348
  let fadeClass = "";
9328
9349
  if (!visible) fadeClass = "candy-fade-out";
9329
9350
  else if (mounted) fadeClass = "candy-fade-in";
9330
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9351
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
9331
9352
  CandyVisual,
9332
9353
  {
9333
9354
  fadeClass,
@@ -9347,17 +9368,6 @@ var LoadingOverlayPrismCandyInline = (0, import_react40.memo)(
9347
9368
  var import_react71 = require("@snowcone-app/sdk/react");
9348
9369
  var import_sdk11 = require("@snowcone-app/sdk");
9349
9370
 
9350
- // src/patterns/MockupBackground.tsx
9351
- var import_react41 = require("react");
9352
- var import_jsx_runtime56 = require("react/jsx-runtime");
9353
- var MockupBackgroundContext = (0, import_react41.createContext)(void 0);
9354
- function MockupBackground({ bg, children }) {
9355
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(MockupBackgroundContext.Provider, { value: bg, children });
9356
- }
9357
- function useMockupBackgroundOptional() {
9358
- return (0, import_react41.useContext)(MockupBackgroundContext);
9359
- }
9360
-
9361
9371
  // src/patterns/ProductPageProvider.tsx
9362
9372
  var import_jsx_runtime57 = require("react/jsx-runtime");
9363
9373
  function ProductPageProvider({