use-frontbacked 5.1.4 → 5.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 (101) hide show
  1. package/dist/cjs/index.js +396 -200
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/DownloadType/index.d.ts +12 -12
  4. package/dist/cjs/types/components/Firebase/AccessTokenDoor.d.ts +12 -12
  5. package/dist/cjs/types/components/Firebase/AuthView.d.ts +15 -15
  6. package/dist/cjs/types/components/Firebase/SignInView.d.ts +11 -11
  7. package/dist/cjs/types/components/Firebase/SignUpView.d.ts +10 -10
  8. package/dist/cjs/types/components/Firebase/data.type.d.ts +23 -23
  9. package/dist/cjs/types/components/Firebase/index.d.ts +14 -14
  10. package/dist/cjs/types/components/FrontbackedProvider/index.d.ts +55 -55
  11. package/dist/cjs/types/components/hooks/useReferralId.d.ts +5 -5
  12. package/dist/cjs/types/components/hooks/useSdkConfig.d.ts +10 -10
  13. package/dist/cjs/types/components/hooks/useTools/index.d.ts +14 -14
  14. package/dist/cjs/types/components/hooks/useTools/types.d.ts +62 -62
  15. package/dist/cjs/types/components/hooks/useTools/utils.d.ts +23 -23
  16. package/dist/cjs/types/components/index.d.ts +2 -2
  17. package/dist/cjs/types/components/types.d.ts +214 -214
  18. package/dist/cjs/types/components/widgets/AppButton.d.ts +17 -17
  19. package/dist/cjs/types/components/widgets/CopyView.d.ts +24 -24
  20. package/dist/cjs/types/components/widgets/DrawerPop/index.d.ts +25 -25
  21. package/dist/cjs/types/components/widgets/InfoLabel.d.ts +11 -11
  22. package/dist/cjs/types/components/widgets/InputBox/index.d.ts +94 -94
  23. package/dist/cjs/types/components/widgets/InputBox/utils.d.ts +1 -1
  24. package/dist/cjs/types/components/widgets/Link.d.ts +9 -9
  25. package/dist/cjs/types/components/widgets/Loading.d.ts +27 -27
  26. package/dist/cjs/types/components/widgets/ModalPop/index.d.ts +26 -26
  27. package/dist/cjs/types/components/widgets/PleaseWaitForX.d.ts +3 -3
  28. package/dist/cjs/types/index.d.ts +1 -1
  29. package/dist/cjs/types/theme.d.ts +3 -3
  30. package/dist/cjs/types/theme.type.d.ts +19 -19
  31. package/dist/cjs/types/utils/CustomError.d.ts +5 -5
  32. package/dist/cjs/types/utils/base64Images.d.ts +4 -4
  33. package/dist/cjs/types/utils/c.d.ts +33 -33
  34. package/dist/cjs/types/utils/f.d.ts +23 -23
  35. package/dist/components/DownloadType/index.d.ts +12 -12
  36. package/dist/components/Firebase/AccessTokenDoor.d.ts +12 -12
  37. package/dist/components/Firebase/AuthView.d.ts +15 -15
  38. package/dist/components/Firebase/SignInView.d.ts +11 -11
  39. package/dist/components/Firebase/SignUpView.d.ts +10 -10
  40. package/dist/components/Firebase/data.type.d.ts +23 -23
  41. package/dist/components/Firebase/index.d.ts +14 -14
  42. package/dist/components/FrontbackedProvider/index.d.ts +55 -55
  43. package/dist/components/hooks/useReferralId.d.ts +5 -5
  44. package/dist/components/hooks/useSdkConfig.d.ts +10 -10
  45. package/dist/components/hooks/useTools/index.d.ts +14 -14
  46. package/dist/components/hooks/useTools/types.d.ts +62 -62
  47. package/dist/components/hooks/useTools/utils.d.ts +23 -23
  48. package/dist/components/index.d.ts +2 -2
  49. package/dist/components/types.d.ts +214 -214
  50. package/dist/components/widgets/AppButton.d.ts +17 -17
  51. package/dist/components/widgets/CopyView.d.ts +24 -24
  52. package/dist/components/widgets/DrawerPop/index.d.ts +25 -25
  53. package/dist/components/widgets/InfoLabel.d.ts +11 -11
  54. package/dist/components/widgets/InputBox/index.d.ts +94 -94
  55. package/dist/components/widgets/InputBox/utils.d.ts +1 -1
  56. package/dist/components/widgets/Link.d.ts +9 -9
  57. package/dist/components/widgets/Loading.d.ts +27 -27
  58. package/dist/components/widgets/ModalPop/index.d.ts +26 -26
  59. package/dist/components/widgets/PleaseWaitForX.d.ts +3 -3
  60. package/dist/esm/index.es.js +396 -200
  61. package/dist/esm/index.es.js.map +1 -1
  62. package/dist/esm/types/components/DownloadType/index.d.ts +12 -12
  63. package/dist/esm/types/components/Firebase/AccessTokenDoor.d.ts +12 -12
  64. package/dist/esm/types/components/Firebase/AuthView.d.ts +15 -15
  65. package/dist/esm/types/components/Firebase/SignInView.d.ts +11 -11
  66. package/dist/esm/types/components/Firebase/SignUpView.d.ts +10 -10
  67. package/dist/esm/types/components/Firebase/data.type.d.ts +23 -23
  68. package/dist/esm/types/components/Firebase/index.d.ts +14 -14
  69. package/dist/esm/types/components/FrontbackedProvider/index.d.ts +55 -55
  70. package/dist/esm/types/components/hooks/useReferralId.d.ts +5 -5
  71. package/dist/esm/types/components/hooks/useSdkConfig.d.ts +10 -10
  72. package/dist/esm/types/components/hooks/useTools/index.d.ts +14 -14
  73. package/dist/esm/types/components/hooks/useTools/types.d.ts +62 -62
  74. package/dist/esm/types/components/hooks/useTools/utils.d.ts +23 -23
  75. package/dist/esm/types/components/index.d.ts +2 -2
  76. package/dist/esm/types/components/types.d.ts +214 -214
  77. package/dist/esm/types/components/widgets/AppButton.d.ts +17 -17
  78. package/dist/esm/types/components/widgets/CopyView.d.ts +24 -24
  79. package/dist/esm/types/components/widgets/DrawerPop/index.d.ts +25 -25
  80. package/dist/esm/types/components/widgets/InfoLabel.d.ts +11 -11
  81. package/dist/esm/types/components/widgets/InputBox/index.d.ts +94 -94
  82. package/dist/esm/types/components/widgets/InputBox/utils.d.ts +1 -1
  83. package/dist/esm/types/components/widgets/Link.d.ts +9 -9
  84. package/dist/esm/types/components/widgets/Loading.d.ts +27 -27
  85. package/dist/esm/types/components/widgets/ModalPop/index.d.ts +26 -26
  86. package/dist/esm/types/components/widgets/PleaseWaitForX.d.ts +3 -3
  87. package/dist/esm/types/index.d.ts +1 -1
  88. package/dist/esm/types/theme.d.ts +3 -3
  89. package/dist/esm/types/theme.type.d.ts +19 -19
  90. package/dist/esm/types/utils/CustomError.d.ts +5 -5
  91. package/dist/esm/types/utils/base64Images.d.ts +4 -4
  92. package/dist/esm/types/utils/c.d.ts +33 -33
  93. package/dist/esm/types/utils/f.d.ts +23 -23
  94. package/dist/index.d.ts +1 -1
  95. package/dist/theme.d.ts +3 -3
  96. package/dist/theme.type.d.ts +19 -19
  97. package/dist/utils/CustomError.d.ts +5 -5
  98. package/dist/utils/base64Images.d.ts +4 -4
  99. package/dist/utils/c.d.ts +33 -33
  100. package/dist/utils/f.d.ts +23 -23
  101. package/package.json +83 -83
@@ -254,6 +254,152 @@ var consoleLog = function consoleLog() {
254
254
  console.log.apply(console, args);
255
255
  }
256
256
  };
257
+ var isAppleMobileDevice = function isAppleMobileDevice() {
258
+ if (typeof navigator === "undefined") return false;
259
+ var userAgent = navigator.userAgent || "";
260
+ var platform = navigator.platform || "";
261
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
262
+ return /iPad|iPhone|iPod/i.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1;
263
+ };
264
+ var openBlobInBrowser = function openBlobInBrowser(blob, fileName, openInNewTab) {
265
+ if (openInNewTab === void 0) {
266
+ openInNewTab = false;
267
+ }
268
+ var objectUrl = URL.createObjectURL(blob);
269
+ var downloadLink = document.createElement("a");
270
+ downloadLink.href = objectUrl;
271
+ downloadLink.rel = "noopener";
272
+ downloadLink.style.display = "none";
273
+ if (openInNewTab) {
274
+ downloadLink.target = "_blank";
275
+ } else {
276
+ downloadLink.download = fileName;
277
+ }
278
+ document.body.appendChild(downloadLink);
279
+ downloadLink.click();
280
+ document.body.removeChild(downloadLink);
281
+ setTimeout(function () {
282
+ return URL.revokeObjectURL(objectUrl);
283
+ }, 30000);
284
+ };
285
+ var shareBlob = function shareBlob(blob, fileName) {
286
+ return __awaiter(void 0, void 0, void 0, function () {
287
+ var shareApi, canShare, file, shareData;
288
+ return __generator(this, function (_a) {
289
+ switch (_a.label) {
290
+ case 0:
291
+ shareApi = typeof navigator !== "undefined" ? navigator.share : null;
292
+ canShare = typeof navigator !== "undefined" ? navigator.canShare : null;
293
+ if (!shareApi || typeof File === "undefined") return [2 /*return*/, false];
294
+ file = new File([blob], fileName, {
295
+ type: blob.type || "application/octet-stream"
296
+ });
297
+ shareData = {
298
+ files: [file],
299
+ title: fileName
300
+ };
301
+ if (canShare && !canShare.call(navigator, shareData)) return [2 /*return*/, false];
302
+ return [4 /*yield*/, shareApi.call(navigator, shareData)];
303
+ case 1:
304
+ _a.sent();
305
+ return [2 /*return*/, true];
306
+ }
307
+ });
308
+ });
309
+ };
310
+ var promptAppleMobileSave = function promptAppleMobileSave(blob, fileName) {
311
+ return new Promise(function (resolve, reject) {
312
+ var overlay = document.createElement("div");
313
+ overlay.setAttribute("role", "dialog");
314
+ overlay.setAttribute("aria-modal", "true");
315
+ overlay.style.cssText = ["position:fixed", "inset:0", "z-index:2147483647", "display:flex", "align-items:center", "justify-content:center", "padding:24px", "background:rgba(15,23,42,0.58)", "font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif"].join(";");
316
+ var dialog = document.createElement("div");
317
+ dialog.style.cssText = ["width:min(360px,100%)", "border-radius:12px", "background:#fff", "box-shadow:0 20px 60px rgba(15,23,42,0.3)", "padding:18px", "color:#111827", "text-align:left"].join(";");
318
+ var title = document.createElement("div");
319
+ title.textContent = "File ready";
320
+ title.style.cssText = "font-size:17px;font-weight:700;margin-bottom:8px;";
321
+ var body = document.createElement("div");
322
+ body.textContent = "Choose where to save this file.";
323
+ body.style.cssText = "font-size:14px;line-height:1.45;color:#4b5563;margin-bottom:16px;";
324
+ var actions = document.createElement("div");
325
+ actions.style.cssText = "display:flex;gap:10px;justify-content:flex-end;";
326
+ var cancelButton = document.createElement("button");
327
+ cancelButton.type = "button";
328
+ cancelButton.textContent = "Cancel";
329
+ cancelButton.style.cssText = ["border:0", "border-radius:8px", "padding:10px 14px", "background:#f3f4f6", "color:#111827", "font-size:14px", "font-weight:600"].join(";");
330
+ var saveButton = document.createElement("button");
331
+ saveButton.type = "button";
332
+ saveButton.textContent = "Save File";
333
+ saveButton.style.cssText = ["border:0", "border-radius:8px", "padding:10px 14px", "background:#2563eb", "color:#fff", "font-size:14px", "font-weight:700"].join(";");
334
+ var cleanup = function cleanup() {
335
+ document.body.removeChild(overlay);
336
+ };
337
+ cancelButton.onclick = function () {
338
+ cleanup();
339
+ reject(new Error("File save was cancelled."));
340
+ };
341
+ saveButton.onclick = function () {
342
+ return __awaiter(void 0, void 0, void 0, function () {
343
+ var shared, error_1;
344
+ return __generator(this, function (_a) {
345
+ switch (_a.label) {
346
+ case 0:
347
+ saveButton.setAttribute("disabled", "true");
348
+ _a.label = 1;
349
+ case 1:
350
+ _a.trys.push([1, 3,, 4]);
351
+ return [4 /*yield*/, shareBlob(blob, fileName)];
352
+ case 2:
353
+ shared = _a.sent();
354
+ if (!shared) openBlobInBrowser(blob, fileName, true);
355
+ cleanup();
356
+ resolve();
357
+ return [3 /*break*/, 4];
358
+ case 3:
359
+ error_1 = _a.sent();
360
+ cleanup();
361
+ if ((error_1 === null || error_1 === void 0 ? void 0 : error_1.name) === "AbortError") {
362
+ reject(new Error("File save was cancelled."));
363
+ return [2 /*return*/];
364
+ }
365
+
366
+ openBlobInBrowser(blob, fileName, true);
367
+ resolve();
368
+ return [3 /*break*/, 4];
369
+ case 4:
370
+ return [2 /*return*/];
371
+ }
372
+ });
373
+ });
374
+ };
375
+
376
+ actions.appendChild(cancelButton);
377
+ actions.appendChild(saveButton);
378
+ dialog.appendChild(title);
379
+ dialog.appendChild(body);
380
+ dialog.appendChild(actions);
381
+ overlay.appendChild(dialog);
382
+ document.body.appendChild(overlay);
383
+ });
384
+ };
385
+ var downloadBlob = function downloadBlob(blob, fileName) {
386
+ return __awaiter(void 0, void 0, void 0, function () {
387
+ return __generator(this, function (_a) {
388
+ switch (_a.label) {
389
+ case 0:
390
+ if (!isAppleMobileDevice()) return [3 /*break*/, 2];
391
+ return [4 /*yield*/, promptAppleMobileSave(blob, fileName)];
392
+ case 1:
393
+ _a.sent();
394
+ return [2 /*return*/];
395
+ case 2:
396
+ openBlobInBrowser(blob, fileName);
397
+ return [2 /*return*/];
398
+ }
399
+ });
400
+ });
401
+ };
402
+
257
403
  var downloadSvgAsImage = function downloadSvgAsImage(svgString, format, fileName) {
258
404
  if (format === void 0) {
259
405
  format = 'png';
@@ -267,39 +413,48 @@ var downloadSvgAsImage = function downloadSvgAsImage(svgString, format, fileName
267
413
  });
268
414
  var svgUrl = URL.createObjectURL(svgBlob);
269
415
  var img = new Image();
416
+ img.crossOrigin = "anonymous";
270
417
  img.onload = function () {
271
- var canvas = document.createElement('canvas');
272
- canvas.width = img.width;
273
- canvas.height = img.height;
274
- var context = canvas.getContext('2d');
275
- if (context) {
276
- context.drawImage(img, 0, 0);
277
- var dataUrl = canvas.toDataURL("image/".concat(format));
278
- var imageBlob = dataURLToBlob(dataUrl);
279
- if (isiPhone()) {
280
- // Workaround for iPhone browsers
281
- var binaryData = [imageBlob];
282
- var iphoneBlob = new Blob(binaryData, {
283
- type: "image/".concat(format)
284
- });
285
- var iphoneUrl = URL.createObjectURL(iphoneBlob);
286
- var downloadLink = document.createElement('a');
287
- downloadLink.href = iphoneUrl;
288
- downloadLink.download = "".concat(fileName, ".").concat(format);
289
- downloadLink.click();
290
- URL.revokeObjectURL(iphoneUrl);
291
- resolve(iphoneUrl);
292
- } else {
293
- // For other browsers
294
- var downloadLink = document.createElement('a');
295
- downloadLink.href = dataUrl;
296
- downloadLink.download = "".concat(fileName, ".").concat(format);
297
- downloadLink.click();
298
- resolve(dataUrl);
299
- }
300
- } else {
301
- reject(new Error("Unsupported Browser. Please try to download from another browser."));
302
- }
418
+ return __awaiter(this, void 0, void 0, function () {
419
+ var canvas, context, dataUrl, imageBlob, error_2;
420
+ return __generator(this, function (_a) {
421
+ switch (_a.label) {
422
+ case 0:
423
+ _a.trys.push([0, 4,, 5]);
424
+ canvas = document.createElement('canvas');
425
+ canvas.width = img.width;
426
+ canvas.height = img.height;
427
+ context = canvas.getContext('2d');
428
+ if (!context) return [3 /*break*/, 2];
429
+ context.drawImage(img, 0, 0);
430
+ dataUrl = canvas.toDataURL("image/".concat(format));
431
+ imageBlob = dataURLToBlob(dataUrl);
432
+ URL.revokeObjectURL(svgUrl);
433
+ return [4 /*yield*/, downloadBlob(imageBlob, "".concat(fileName, ".").concat(format))];
434
+ case 1:
435
+ _a.sent();
436
+ resolve(dataUrl);
437
+ return [3 /*break*/, 3];
438
+ case 2:
439
+ reject(new Error("Unsupported Browser. Please try to download from another browser."));
440
+ _a.label = 3;
441
+ case 3:
442
+ return [3 /*break*/, 5];
443
+ case 4:
444
+ error_2 = _a.sent();
445
+ URL.revokeObjectURL(svgUrl);
446
+ reject(error_2);
447
+ return [3 /*break*/, 5];
448
+ case 5:
449
+ return [2 /*return*/];
450
+ }
451
+ });
452
+ });
453
+ };
454
+
455
+ img.onerror = function () {
456
+ URL.revokeObjectURL(svgUrl);
457
+ reject(new Error("Failed to render the SVG for download."));
303
458
  };
304
459
  img.src = svgUrl;
305
460
  });
@@ -317,9 +472,6 @@ function dataURLToBlob(dataURL) {
317
472
  type: mime
318
473
  });
319
474
  }
320
- function isiPhone() {
321
- return /iPhone/i.test(navigator.userAgent);
322
- }
323
475
  var getColor = function getColor(isDarkMode, colorName) {
324
476
  var color = theme[colorName];
325
477
  if (color) {
@@ -1344,69 +1496,69 @@ var InputBox = function InputBox(_a) {
1344
1496
  return null;
1345
1497
  }
1346
1498
  }))) :
1347
- /*
1348
- type == TYPES.location?
1349
- <LocationPicker disabled={disabled} ref={inputRef} w="100%" h="100%"
1350
- apiKey={apiKey || ""} defaultLatlng={defaultLatlng} geotype={geotype}
1351
- mapToSearchRatio={mapToSearchRatio}
1352
- twoDigitCountryCode={twoDigitCountryCode}
1353
- searchPlaceholder={placeholder as string}
1354
- value={value? {
1355
- name: value.name,
1356
- formatted_address: value.address,
1357
- geometry: {
1358
- location: {lat: () => value.position.lat, lng: () => value.position.lng},
1359
- viewport: {}
1360
- }
1361
- } : null}
1362
- onChange={(l) => {
1363
- const v = {
1364
- name: l.name,
1365
- address: l.formatted_address,
1366
- position: {
1367
- lat: l.geometry.location.lat(),
1368
- lng: l.geometry.location.lng()
1369
- }
1370
- }
1371
- if(!disabled && onChange) {
1372
- onChange(v)
1373
- }
1374
- if(!disabled && onCheckInfo) {
1375
- const { checker, waitTime } = onCheckInfo(v)
1376
- //only check input in "onChange" if waitTime is greater than zero.
1377
- // This is good in searching a text results as a user types in a search bar,
1378
- // or saving an article on a server as the user types
1379
- if(waitTime > 0) {
1380
- handleInputCheck(() => v, (checkedValue) => {
1381
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1382
- }, checker, waitTime)
1383
- }
1384
- }
1385
-
1386
- }}
1387
- onBlur={(l) => {
1388
- if(!disabled && onCheckInfo) {
1389
- const v = {
1390
- name: l.name,
1391
- address: l.formatted_address,
1392
- position: {
1393
- lat: l.geometry.location.lat(),
1394
- lng: l.geometry.location.lng()
1395
- }
1396
- }
1397
- const { checker, waitTime } = onCheckInfo(v)
1398
- //only check input in "onBlur" if waitTime is not set or equal to zero.
1399
- // This is good in validating an input as it looses focus when the user moves to another,
1400
- // input field
1401
- if(!waitTime) {
1402
- handleInputCheck(() => v, (checkedValue) => {
1403
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1404
- }, checker, waitTime)
1405
- }
1406
- }
1407
- }}
1408
- errorMessage={errorMessage}
1409
- />
1499
+ /*
1500
+ type == TYPES.location?
1501
+ <LocationPicker disabled={disabled} ref={inputRef} w="100%" h="100%"
1502
+ apiKey={apiKey || ""} defaultLatlng={defaultLatlng} geotype={geotype}
1503
+ mapToSearchRatio={mapToSearchRatio}
1504
+ twoDigitCountryCode={twoDigitCountryCode}
1505
+ searchPlaceholder={placeholder as string}
1506
+ value={value? {
1507
+ name: value.name,
1508
+ formatted_address: value.address,
1509
+ geometry: {
1510
+ location: {lat: () => value.position.lat, lng: () => value.position.lng},
1511
+ viewport: {}
1512
+ }
1513
+ } : null}
1514
+ onChange={(l) => {
1515
+ const v = {
1516
+ name: l.name,
1517
+ address: l.formatted_address,
1518
+ position: {
1519
+ lat: l.geometry.location.lat(),
1520
+ lng: l.geometry.location.lng()
1521
+ }
1522
+ }
1523
+ if(!disabled && onChange) {
1524
+ onChange(v)
1525
+ }
1526
+ if(!disabled && onCheckInfo) {
1527
+ const { checker, waitTime } = onCheckInfo(v)
1528
+ //only check input in "onChange" if waitTime is greater than zero.
1529
+ // This is good in searching a text results as a user types in a search bar,
1530
+ // or saving an article on a server as the user types
1531
+ if(waitTime > 0) {
1532
+ handleInputCheck(() => v, (checkedValue) => {
1533
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1534
+ }, checker, waitTime)
1535
+ }
1536
+ }
1537
+
1538
+ }}
1539
+ onBlur={(l) => {
1540
+ if(!disabled && onCheckInfo) {
1541
+ const v = {
1542
+ name: l.name,
1543
+ address: l.formatted_address,
1544
+ position: {
1545
+ lat: l.geometry.location.lat(),
1546
+ lng: l.geometry.location.lng()
1547
+ }
1548
+ }
1549
+ const { checker, waitTime } = onCheckInfo(v)
1550
+ //only check input in "onBlur" if waitTime is not set or equal to zero.
1551
+ // This is good in validating an input as it looses focus when the user moves to another,
1552
+ // input field
1553
+ if(!waitTime) {
1554
+ handleInputCheck(() => v, (checkedValue) => {
1555
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1556
+ }, checker, waitTime)
1557
+ }
1558
+ }
1559
+ }}
1560
+ errorMessage={errorMessage}
1561
+ />
1410
1562
  :*/
1411
1563
  type == TYPES.price ? /*#__PURE__*/React.createElement(VStack, {
1412
1564
  w: "100%",
@@ -1515,26 +1667,26 @@ var InputBox = function InputBox(_a) {
1515
1667
  }
1516
1668
  }, /*#__PURE__*/React.createElement(FaPlus, null)))
1517
1669
  }))) :
1518
- /*
1519
- type == TYPES.select_tree?
1520
- <SelectTree disabled={disabled} options={options as SelectTreeOptionWithChildren[]}
1521
- onChange={onChange}
1522
- onBlur={(e: SelectTreeEvent) => {
1523
- const { currentNode, selectedNodes } = e
1524
- if(!disabled && onCheckInfo) {
1525
- const v = "currentNode"
1526
- const { checker, waitTime } = onCheckInfo(v)
1527
- //only check input in "onBlur" if waitTime is not set or equal to zero.
1528
- // This is good in validating an input as it looses focus when the user moves to another,
1529
- // input field
1530
- if(!waitTime) {
1531
- handleInputCheck(() => v, (checkedValue) => {
1532
- return JSON.stringify(checkedValue) === JSON.stringify(v)
1533
- }, checker, waitTime)
1534
- }
1535
- }
1536
- }}
1537
- />
1670
+ /*
1671
+ type == TYPES.select_tree?
1672
+ <SelectTree disabled={disabled} options={options as SelectTreeOptionWithChildren[]}
1673
+ onChange={onChange}
1674
+ onBlur={(e: SelectTreeEvent) => {
1675
+ const { currentNode, selectedNodes } = e
1676
+ if(!disabled && onCheckInfo) {
1677
+ const v = "currentNode"
1678
+ const { checker, waitTime } = onCheckInfo(v)
1679
+ //only check input in "onBlur" if waitTime is not set or equal to zero.
1680
+ // This is good in validating an input as it looses focus when the user moves to another,
1681
+ // input field
1682
+ if(!waitTime) {
1683
+ handleInputCheck(() => v, (checkedValue) => {
1684
+ return JSON.stringify(checkedValue) === JSON.stringify(v)
1685
+ }, checker, waitTime)
1686
+ }
1687
+ }
1688
+ }}
1689
+ />
1538
1690
  :*/
1539
1691
  type == TYPES.none ? null : /*#__PURE__*/React.createElement(InputGroup, null, iconLeft ? /*#__PURE__*/React.createElement(InputLeftElement, {
1540
1692
  children: iconLeft
@@ -2155,7 +2307,7 @@ var AuthView = function AuthView(_a) {
2155
2307
  _a.isDarkMode;
2156
2308
  var setUser = _a.setUser,
2157
2309
  config = _a.config;
2158
- var _b = useState(true),
2310
+ var _b = useState(false),
2159
2311
  showSignIn = _b[0],
2160
2312
  setShowSignIn = _b[1];
2161
2313
  var handleAuthLinkClick = function handleAuthLinkClick(e) {
@@ -2192,7 +2344,7 @@ var AuthView = function AuthView(_a) {
2192
2344
  w: "auto"
2193
2345
  }), /*#__PURE__*/React.createElement(Text, {
2194
2346
  as: "div",
2195
- fontSize: "14px",
2347
+ fontSize: "1.2rem",
2196
2348
  mb: "0.1rem !important",
2197
2349
  textAlign: "center"
2198
2350
  }, signInTitle), /*#__PURE__*/React.createElement(Text, {
@@ -2200,12 +2352,12 @@ var AuthView = function AuthView(_a) {
2200
2352
  fontSize: "14px",
2201
2353
  mb: "1.5rem !important",
2202
2354
  textAlign: "center"
2203
- }, "If you don't have an account yet, ", /*#__PURE__*/React.createElement(Link, {
2355
+ }, "If you have not registered, ", /*#__PURE__*/React.createElement(Link, {
2204
2356
  color: "green.500",
2205
2357
  textDecoration: "underline",
2206
2358
  onClick: handleAuthLinkClick,
2207
2359
  fontWeight: "bold"
2208
- }, "Sign up here."))), /*#__PURE__*/React.createElement(SignInView, {
2360
+ }, "click this link to Sign Up."))), /*#__PURE__*/React.createElement(SignInView, {
2209
2361
  onAuthDone: onSuccess,
2210
2362
  setUser: setUser,
2211
2363
  config: config
@@ -2219,7 +2371,7 @@ var AuthView = function AuthView(_a) {
2219
2371
  w: "auto"
2220
2372
  }), /*#__PURE__*/React.createElement(Text, {
2221
2373
  as: "div",
2222
- fontSize: "14px",
2374
+ fontSize: "1.2rem",
2223
2375
  mb: "0.1rem !important",
2224
2376
  textAlign: "center"
2225
2377
  }, signUpTitle), /*#__PURE__*/React.createElement(Text, {
@@ -2232,7 +2384,7 @@ var AuthView = function AuthView(_a) {
2232
2384
  textDecoration: "underline",
2233
2385
  onClick: handleAuthLinkClick,
2234
2386
  fontWeight: "bold"
2235
- }, "Sign in here."))), /*#__PURE__*/React.createElement(SignUpView, {
2387
+ }, "click this link to Sign In."))), /*#__PURE__*/React.createElement(SignUpView, {
2236
2388
  onAuthDone: onSuccess,
2237
2389
  setUser: setUser,
2238
2390
  config: config
@@ -2240,15 +2392,15 @@ var AuthView = function AuthView(_a) {
2240
2392
  as: "div",
2241
2393
  textAlign: "center",
2242
2394
  fontSize: "14px"
2243
- }, showSignIn ? /*#__PURE__*/React.createElement(React.Fragment, null, "Don't have an account yet? ", /*#__PURE__*/React.createElement(Link, {
2395
+ }, showSignIn ? /*#__PURE__*/React.createElement(React.Fragment, null, "If you have not registered, ", /*#__PURE__*/React.createElement(Link, {
2244
2396
  color: "green.500",
2245
2397
  textDecoration: "underline",
2246
2398
  onClick: handleAuthLinkClick
2247
- }, "Sign up here.")) : /*#__PURE__*/React.createElement(React.Fragment, null, "Already have an account? ", /*#__PURE__*/React.createElement(Link, {
2399
+ }, "click this link to Sign Up.")) : /*#__PURE__*/React.createElement(React.Fragment, null, "If you already have an account, ", /*#__PURE__*/React.createElement(Link, {
2248
2400
  color: "green.500",
2249
2401
  textDecoration: "underline",
2250
2402
  onClick: handleAuthLinkClick
2251
- }, "Log in here.")))));
2403
+ }, "click this link to Sign In.")))));
2252
2404
  };
2253
2405
 
2254
2406
  var ModalPop = function ModalPop(_a) {
@@ -2410,17 +2562,52 @@ var AccessTokenDoor = function AccessTokenDoor(_a) {
2410
2562
  }, authenticating ? "Please wait..." : "Confirm Operation")));
2411
2563
  };
2412
2564
 
2565
+ function _typeof(o) {
2566
+ "@babel/helpers - typeof";
2567
+
2568
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
2569
+ return typeof o;
2570
+ } : function (o) {
2571
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
2572
+ }, _typeof(o);
2573
+ }
2574
+
2413
2575
  var MAX_RETRIES$1 = 5;
2414
2576
  var CACHE_KEY$1 = "sdk_config-metadata";
2577
+ var CACHE_BUST_KEY$1 = "_fb_cache_bust";
2415
2578
  // let sdkConfigCache: SdkConfig | null = null;
2416
2579
  // let fetchPromise: Promise<SdkConfig | null> | null = null;
2417
- var defaultFactoryData$1 = '{"etag":"W/\\"cfb2c25c60051f77c56bc81c008b2d80\\"","lastModified":"Thu, 15 May 2025 01:41:21 GMT","cachedData":{"aff_pct":10,"app_version_code":19,"contact_link":"https://t.me/frontbacked","group_link":"https://t.me/frontbacked","group_links":["https://t.me/frontbacked"],"min_deposit":7,"min_vendor_deposit":7,"parent_site_home":"https://hackbaker.com","ttl_days":2,"vendors":[{"name":"JinmiEx","number":"+2348130729216","freq":1}]}}';
2580
+ var addCacheBust$1 = function addCacheBust(url) {
2581
+ try {
2582
+ var parsedUrl = new URL(url);
2583
+ parsedUrl.searchParams.set(CACHE_BUST_KEY$1, Date.now().toString());
2584
+ return parsedUrl.toString();
2585
+ } catch (err) {
2586
+ return url;
2587
+ }
2588
+ };
2589
+ var readCachedMetadata$1 = function readCachedMetadata() {
2590
+ if (!isBrowser()) return null;
2591
+ try {
2592
+ var cachedMetadata = localStorage.getItem(CACHE_KEY$1);
2593
+ return cachedMetadata ? JSON.parse(cachedMetadata) : null;
2594
+ } catch (err) {
2595
+ localStorage.removeItem(CACHE_KEY$1);
2596
+ return null;
2597
+ }
2598
+ };
2418
2599
  var useSdkConfig = function useSdkConfig(appConfig) {
2419
2600
  var _a = useState(isBrowser() ? window.sdkConfigCache : null),
2420
2601
  sdkConfig = _a[0],
2421
2602
  setSdkConfig = _a[1];
2422
2603
  function parseVendors(vendorsAsTexts) {
2423
- return vendorsAsTexts.map(function (text) {
2604
+ if (vendorsAsTexts === void 0) {
2605
+ vendorsAsTexts = [];
2606
+ }
2607
+ if (!Array.isArray(vendorsAsTexts)) return [];
2608
+ return vendorsAsTexts.map(function (vendor) {
2609
+ if (typeof vendor !== "string") return vendor;
2610
+ var text = vendor;
2424
2611
  var _a = text.split(','),
2425
2612
  name = _a[0],
2426
2613
  number = _a[1],
@@ -2436,49 +2623,38 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2436
2623
  if (!(appConfig === null || appConfig === void 0 ? void 0 : appConfig.r2Domain)) return;
2437
2624
  if (window.sdkConfigCache) {
2438
2625
  setSdkConfig(window.sdkConfigCache);
2439
- return;
2440
2626
  }
2441
2627
  if (!window.fetchPromise) {
2442
2628
  window.fetchPromise = function () {
2443
2629
  return __awaiter(void 0, void 0, void 0, function () {
2444
- var attempts, headers, cachedMetadata, _a, etag, lastModified, cachedData, response, config, err_1;
2445
- var _b;
2446
- return __generator(this, function (_c) {
2447
- switch (_c.label) {
2630
+ var attempts, cachedMetadata, cachedData, response, config, err_1;
2631
+ var _a;
2632
+ return __generator(this, function (_b) {
2633
+ switch (_b.label) {
2448
2634
  case 0:
2449
2635
  attempts = 0;
2450
- headers = {};
2451
- cachedMetadata = localStorage.getItem(CACHE_KEY$1) || defaultFactoryData$1;
2636
+ cachedMetadata = readCachedMetadata$1();
2452
2637
  if (cachedMetadata) {
2453
- _a = JSON.parse(cachedMetadata), etag = _a.etag, lastModified = _a.lastModified, cachedData = _a.cachedData;
2638
+ cachedData = cachedMetadata.cachedData;
2454
2639
  if (cachedData) {
2455
2640
  window.sdkConfigCache = cachedData;
2456
2641
  setSdkConfig(cachedData);
2457
2642
  //return cachedData;
2458
2643
  }
2459
-
2460
- if (etag) headers["If-None-Match"] = etag;
2461
- if (lastModified) headers["If-Modified-Since"] = lastModified;
2462
2644
  }
2463
- consoleLog("useSdkConfig.headers: ", headers);
2464
- _c.label = 1;
2645
+
2646
+ consoleLog("useSdkConfig.refreshing");
2647
+ _b.label = 1;
2465
2648
  case 1:
2466
2649
  if (!(attempts < MAX_RETRIES$1)) return [3 /*break*/, 6];
2467
- _c.label = 2;
2650
+ _b.label = 2;
2468
2651
  case 2:
2469
- _c.trys.push([2, 4,, 5]);
2470
- return [4 /*yield*/, axios.get("https://".concat(appConfig.r2Domain, "/sdk_config.json"), {
2471
- headers: headers,
2472
- validateStatus: function validateStatus(status) {
2473
- return status < 500;
2474
- } // Accept 304 Not Modified
2475
- })];
2476
-
2652
+ _b.trys.push([2, 4,, 5]);
2653
+ return [4 /*yield*/, axios.get(addCacheBust$1("https://".concat(appConfig.r2Domain, "/sdk_config.json")))];
2477
2654
  case 3:
2478
- response = _c.sent();
2479
- if (response.status === 304) {
2480
- consoleLog("useSdkConfig.notModied: ", response.status);
2481
- return [2 /*return*/, window.sdkConfigCache];
2655
+ response = _b.sent();
2656
+ if (_typeof(response.data) !== "object") {
2657
+ throw new Error("Invalid SDK config response");
2482
2658
  }
2483
2659
  config = response.data;
2484
2660
  config.vendors = parseVendors(response.data.vendors);
@@ -2488,13 +2664,14 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2488
2664
  localStorage.setItem(CACHE_KEY$1, JSON.stringify({
2489
2665
  etag: response.headers["etag"],
2490
2666
  lastModified: response.headers["last-modified"],
2667
+ cachedAt: Date.now(),
2491
2668
  cachedData: config
2492
2669
  }));
2493
2670
  consoleLog("useSdkConfig.refreshed: ", response.data, " at ".concat(response.headers["last-modified"], ", with etag, ").concat(response.headers["etag"]));
2494
2671
  return [2 /*return*/, config];
2495
2672
  case 4:
2496
- err_1 = _c.sent();
2497
- if (((_b = err_1.response) === null || _b === void 0 ? void 0 : _b.status) === 404) {
2673
+ err_1 = _b.sent();
2674
+ if (((_a = err_1.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
2498
2675
  consoleLog("Error fetching SDK config: Resource not found (404): ", err_1);
2499
2676
  return [3 /*break*/, 6];
2500
2677
  }
@@ -2506,11 +2683,14 @@ var useSdkConfig = function useSdkConfig(appConfig) {
2506
2683
  case 5:
2507
2684
  return [3 /*break*/, 1];
2508
2685
  case 6:
2686
+ if (window.sdkConfigCache) return [2 /*return*/, window.sdkConfigCache];
2509
2687
  return [2 /*return*/, null];
2510
2688
  }
2511
2689
  });
2512
2690
  });
2513
- }();
2691
+ }()["finally"](function () {
2692
+ window.fetchPromise = null;
2693
+ });
2514
2694
  }
2515
2695
  window.fetchPromise.then(function (config) {
2516
2696
  if (config) setSdkConfig(config);
@@ -2931,12 +3111,12 @@ var DownloadType = function DownloadType(_a) {
2931
3111
  //Or it's not an update(it's a create) but create price is 0
2932
3112
  //Or it's an update but update price is 0
2933
3113
  //Or it's an update for subscription renewal
2934
- /*!docRules ||*/ /*
2935
- (updateMessage && removeFreemiumBeforeUpdate && docRules.create_price > 0) ||
2936
- (!updateMessage && !docRules.allow_freemium) ||
2937
- (!updateMessage && docRules.create_price == 0) ||
2938
- (updateMessage && docRules.update_price == 0) ||
2939
- (updateMessage && renewSubscription) ||
3114
+ /*!docRules ||*/ /*
3115
+ (updateMessage && removeFreemiumBeforeUpdate && docRules.create_price > 0) ||
3116
+ (!updateMessage && !docRules.allow_freemium) ||
3117
+ (!updateMessage && docRules.create_price == 0) ||
3118
+ (updateMessage && docRules.update_price == 0) ||
3119
+ (updateMessage && renewSubscription) ||
2940
3120
  (updateMessage && renewSubscription)*/
2941
3121
  //(!updateMessage && docRules.create_price == 0) || (updateMessage && !docRules.yearly_price && !docRules.quarterly_price)?
2942
3122
  autoProcessOn || !docRules ? /*#__PURE__*/React.createElement(PleaseWaitForX, null) : /*#__PURE__*/React.createElement(React.Fragment, null, updateMessage && !docRules.yearly_price && !docRules.quarterly_price ? /*#__PURE__*/React.createElement(Text, {
@@ -2986,11 +3166,11 @@ var DownloadType = function DownloadType(_a) {
2986
3166
  }))));
2987
3167
  };
2988
3168
 
2989
- /**
2990
- * Removes a specific query string parameter from a URL.
2991
- * @param {string} url - The original URL.
2992
- * @param {string} queryString - The query string parameter to remove.
2993
- * @returns {string} - The updated URL without the specified query string parameter.
3169
+ /**
3170
+ * Removes a specific query string parameter from a URL.
3171
+ * @param {string} url - The original URL.
3172
+ * @param {string} queryString - The query string parameter to remove.
3173
+ * @returns {string} - The updated URL without the specified query string parameter.
2994
3174
  */
2995
3175
  function removeQueryString(url, queryString) {
2996
3176
  try {
@@ -3005,12 +3185,12 @@ function removeQueryString(url, queryString) {
3005
3185
  return url; // Return the original URL if there's an error
3006
3186
  }
3007
3187
  }
3008
- /**
3009
- * Converts an array of objects to a map using a specified attribute as the key.
3010
- *
3011
- * @param {Array<Object>} arr - The array of objects to be converted.
3012
- * @param {string} attr - The attribute to use as the key for the mapping.
3013
- * @returns {Object} - An object mapping each unique attribute value to its corresponding item.
3188
+ /**
3189
+ * Converts an array of objects to a map using a specified attribute as the key.
3190
+ *
3191
+ * @param {Array<Object>} arr - The array of objects to be converted.
3192
+ * @param {string} attr - The attribute to use as the key for the mapping.
3193
+ * @returns {Object} - An object mapping each unique attribute value to its corresponding item.
3014
3194
  */
3015
3195
  function arrayToMap(attr, arr, keyParser) {
3016
3196
  return arr.reduce(function (map, item) {
@@ -3036,9 +3216,9 @@ var rmUpdates = function rmUpdates(url) {
3036
3216
 
3037
3217
  var MAX_RETRIES = 5;
3038
3218
  var CACHE_KEY = "tools-cache-metadata";
3219
+ var CACHE_BUST_KEY = "_fb_cache_bust";
3039
3220
  // let toolsCache: ToolsData | null = null;
3040
3221
  // let toolsFetchPromise: Promise<ToolsData | null> | null = null;
3041
- var defaultFactoryData = '{"etag":"W/\\"97cce03e8c6f6c8092dfac11069679e7\\"","lastModified":"Fri, 23 May 2025 17:24:27 GMT","cachedData":{"totalUpdates":1,"lastUpdatedOn":"Fri, 23 May 2025 17:24:18 GMT","tools":[{"id":"U8SL1BvlIb1nxj4JNCNX","siteUrl":"/bank","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"isActive":true,"isHidden":false,"update_price":0.1,"allow_freemium":true,"create_price_is_monthly":true,"rank":1,"icon":"Building","siteLogoUrl":"/templates/tool-U8SL1BvlIb1nxj4JNCNX.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Online Banking Website","chat_supported":true,"create_price":20000,"quarterly_price":50000,"yearly_price":150000,"create_price_discount":0,"description":"Create an online banking website for your content. No more building a custom online banking website from scratch every time you need to film a banking scene.","x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","updatedAt,current_time,0,0,true,true,true","profilePhoto,string,0,300,true,true,false","email,string,0,64,true,true,false","phone,string,0,32,true,true,false","accountType,string,0,64,true,true,false","gender,string,0,64,true,true,false","maritalStatus,string,0,64,true,true,false","dob,string,0,16,true,true,false","password,string,6,16,true,true,false","pin,number,1000,9999,true,true,false","address,string,0,128,true,true,false","occupation,string,0,64,true,true,false","accountNumber_username,number,9000000000,9999999999,false,true,false","fullname,string,0,64,true,true,false","currencySymbol,string,0,64,true,true,false","disableAccount,boolean,0,8,true,true,false","accountBalance,number,0,999999999999999,true,false,false","autoRenewSubscription,boolean,0,8,true,true,false","credits,array:string:1:200,0,10,true,false,false","debits,array:string:1:200,0,10,true,false,false","totalCredits,number,0,999999999999999,true,false,false","totalDebits,number,0,999999999999999,true,false,false","disableAccountError,string,1,500,true,false,false","noTxGeneration,boolean,0,8,false,false,false","isHidden,boolean,1,8,true,false,false","isActive,boolean,1,8,true,false,false","txProcessingDuration,string,1,64,true,true,false","isInActive,boolean,0,8,true,false,false"],"tool_version_code":7},{"id":"0QZLQQKVTRV3Q6SFAIEA","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","createdAt":{"_seconds":1733770038,"_nanoseconds":796000000},"is_static":false,"isActive":true,"is_freemium":true,"icon":"ShippingFast","isHidden":false,"editables":"Shipping_Status@small.select, error_message.textarea, expected_arrival_date.date","templates_url":"/templates/templates-awsuv5ba.json?updates=23","youtube":null,"mobileVideoUrl":null,"desktopVideoUrl":null,"allow_freemium":true,"chat_supported":true,"create_price":10000,"message":"ID_TITLE == Tracking ID\\nLINK == zendcargo.com\\nCONTENT == Track your shipment using the tracking ID above at the tracking website: {LINK}.","description":"Create a shipping invoice with a tracking website for your content. No more building a custom shipping site from scratch every time you need to film a shipping scene.","update_price":200,"updatedAt":{"_seconds":1746816982,"_nanoseconds":404000000},"rank":2,"name":"Shipping","parent":"","x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","expectedArrivalDate,time,0,0,true,true,false","invoiceNumber,string,1,16,false,true,false","packageContent,string,1,64,false,true,false","packageDestinationAddress,string,1,64,false,true,false","packageDestinationEmail,string,1,256,false,true,false","packageDestinationPhone,string,1,16,false,true,false","packageRecipientName,string,1,128,false,true,false","packageWeight,string,1,32,false,true,false","senderEmail,string,1,256,false,true,false","senderName,string,1,128,false,true,false","shipmentDate,time,0,0,false,true,false","shipmentFee,string,0,32,false,true,false","shippingStatus,string,1,32,true,true,false","updatedAt,current_time,0,0,true,true,true","costCurrency,string,0,64,false,false,false","errorMessage,string,1,500,true,false,false"],"tool_version_code":7,"freemiumDownloadMessage":"The shipping invoice will have watermark. The tracking website will also have a \\"fake tracking\\" message.","premiumDownloadMessage":"The shipping invoice will be clean with no watermark. The tracking website will also be clean with no \\"fake tracking\\" message.","templates":[{"id":"hwd7x6ou","name":"Shipping Invoice with Tracking Website","logo":"https://r2.softbaker.com/templates/templates-awsuv5ba-hwd7x6ou-logo.jpeg","data_url":"https://r2.frontbacked.com/templates/templates-awsuv5ba-hwd7x6ou-data.json?updates=1","is_default":true,"split_on_download":false,"thumbnail":"https://r2.frontbacked.com/templates/tools-awsuv5ba-hwd7x6ou-thumbnail.jpg?updates=1&tct=1748021058263"}]},{"id":"5vCsgJJVsFYhV4dZYQdI","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"name":"Invoice","isActive":true,"isHidden":false,"allow_freemium":true,"siteUrl":"/invoice","siteLogoUrl":"/templates/tool-5vCsgJJVsFYhV4dZYQdI.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"description":"Create a payment invoice easily.","rank":3,"update_price":200,"create_price":5000,"x":["authorId,uid,0,0,false,true,false","createdAt,current_time,0,0,false,true,false","updatedAt,current_time,0,0,true,true,true","companyName,string,2,64,false,true,false","companyAddress,string,2,64,false,true,false","customerName,string,2,64,false,true,false","customerAddress,string,2,64,false,true,false","invoiceNumber,string,2,64,false,true,false","date,time,0,0,false,true,false","currency,string,2,64,false,true,false","items,object_array:{description@string_1_90|quantity@number_1_1000000000000000|price@number_1_1000000000000000},1,6,false,true,false","paymentDetails,string,2,256,false,false,false","vat,number,0,99,false,true,false","logo,string,0,64,false,false,false","waterMarkWithLogo,boolean,0,64,false,true,false","grayScaleWaterMark,boolean,0,64,false,true,false"],"tool_version_code":2},{"id":"tDYsSHDnF58hFCf3nUTk","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"icon":"Coins","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Face Swap Video Call","siteUrl":"/face-swap-video-call","isActive":false,"siteLogoUrl":"/templates/tool-tDYsSHDnF58hFCf3nUTk.jpg?v=2","rank":4,"isHidden":false},{"id":"XFXW1s8LlhiJnZKPbdWX","siteUrl":"/invest","mobileVideoUrl":null,"is_static":true,"desktopVideoUrl":null,"isActive":false,"icon":"MoneyBillAlt","siteLogoUrl":"/templates/tool-XFXW1s8LlhiJnZKPbdWX.jpg","authorId":"f6dcBr3nBJQNLeRwN1ZeHYTZqGC2","youtube":null,"name":"Investment Website","rank":5,"isHidden":false}]}}';
3042
3222
  var setR2Host = function setR2Host(url, r2Domain) {
3043
3223
  if (!url) return url;
3044
3224
  if (url.startsWith('/')) {
@@ -3055,6 +3235,25 @@ var setR2Host = function setR2Host(url, r2Domain) {
3055
3235
  }
3056
3236
  };
3057
3237
 
3238
+ var addCacheBust = function addCacheBust(url) {
3239
+ try {
3240
+ var parsedUrl = new URL(url);
3241
+ parsedUrl.searchParams.set(CACHE_BUST_KEY, Date.now().toString());
3242
+ return parsedUrl.toString();
3243
+ } catch (err) {
3244
+ return url;
3245
+ }
3246
+ };
3247
+ var readCachedMetadata = function readCachedMetadata() {
3248
+ if (!isBrowser()) return null;
3249
+ try {
3250
+ var cachedMetadata = localStorage.getItem(CACHE_KEY);
3251
+ return cachedMetadata ? JSON.parse(cachedMetadata) : null;
3252
+ } catch (err) {
3253
+ localStorage.removeItem(CACHE_KEY);
3254
+ return null;
3255
+ }
3256
+ };
3058
3257
  var useTools = function useTools(config) {
3059
3258
  var _a = useState(isBrowser() ? window.toolsCache : null),
3060
3259
  data = _a[0],
@@ -3077,59 +3276,49 @@ var useTools = function useTools(config) {
3077
3276
  setData(window.toolsCache);
3078
3277
  setLoading(false);
3079
3278
  consoleLog("useTools.returns as toolsCache already exist: ", window.toolsCache);
3080
- return;
3081
3279
  }
3082
3280
  if (!window.toolsFetchPromise) {
3083
3281
  window.toolsFetchPromise = function () {
3084
3282
  return __awaiter(void 0, void 0, void 0, function () {
3085
- var attempts, headers, cachedMetadata, _a, etag, lastModified, cachedData, response, err_1;
3086
- var _b;
3283
+ var attempts, cachedMetadata, cachedData, response, err_1;
3284
+ var _a, _b;
3087
3285
  return __generator(this, function (_c) {
3088
3286
  switch (_c.label) {
3089
3287
  case 0:
3090
3288
  attempts = 0;
3091
- headers = {};
3092
- cachedMetadata = localStorage.getItem(CACHE_KEY) || defaultFactoryData;
3289
+ cachedMetadata = readCachedMetadata();
3093
3290
  if (cachedMetadata) {
3094
- _a = JSON.parse(cachedMetadata), etag = _a.etag, lastModified = _a.lastModified, cachedData = _a.cachedData;
3291
+ cachedData = cachedMetadata.cachedData;
3095
3292
  if (cachedData) {
3096
3293
  window.toolsCache = cachedData;
3097
3294
  setData(cachedData);
3098
3295
  setLoading(false);
3099
3296
  //return cachedData;
3100
3297
  }
3101
-
3102
- if (etag) headers["If-None-Match"] = etag;
3103
- if (lastModified) headers["If-Modified-Since"] = lastModified;
3104
3298
  }
3105
- consoleLog("useTools.headers: ", headers);
3299
+
3300
+ consoleLog("useTools.refreshing");
3106
3301
  _c.label = 1;
3107
3302
  case 1:
3108
3303
  if (!(attempts < MAX_RETRIES)) return [3 /*break*/, 6];
3109
3304
  _c.label = 2;
3110
3305
  case 2:
3111
3306
  _c.trys.push([2, 4,, 5]);
3112
- return [4 /*yield*/, axios.get("https://".concat(config.r2Domain, "/templates/tools.json"), {
3113
- headers: headers,
3114
- validateStatus: function validateStatus(status) {
3115
- return status < 500;
3116
- } // Accept 304 Not Modified
3117
- })];
3118
-
3307
+ return [4 /*yield*/, axios.get(addCacheBust("https://".concat(config.r2Domain, "/templates/tools.json")))];
3119
3308
  case 3:
3120
3309
  response = _c.sent();
3121
- if (response.status === 304) {
3122
- setLoading(false);
3123
- consoleLog("useTools.notModied: ", response.status);
3124
- return [2 /*return*/, window.toolsCache];
3310
+ if (_typeof(response.data) !== "object" || !Array.isArray((_a = response.data) === null || _a === void 0 ? void 0 : _a.tools)) {
3311
+ throw new Error("Invalid tools response");
3125
3312
  }
3126
3313
  window.toolsCache = response.data;
3127
3314
  setData(response.data);
3128
3315
  setError(null);
3316
+ setLoading(false);
3129
3317
  // Save cache metadata
3130
3318
  localStorage.setItem(CACHE_KEY, JSON.stringify({
3131
3319
  etag: response.headers["etag"],
3132
3320
  lastModified: response.headers["last-modified"],
3321
+ cachedAt: Date.now(),
3133
3322
  cachedData: response.data
3134
3323
  }));
3135
3324
  consoleLog("useTools.refreshed: ", response.data, " at ".concat(response.headers["last-modified"], ", with etag, ").concat(response.headers["etag"]));
@@ -3137,23 +3326,30 @@ var useTools = function useTools(config) {
3137
3326
  case 4:
3138
3327
  err_1 = _c.sent();
3139
3328
  if (((_b = err_1.response) === null || _b === void 0 ? void 0 : _b.status) === 404) {
3140
- setError("Resource not found (404)");
3329
+ if (!window.toolsCache) setError("Resource not found (404)");
3141
3330
  return [3 /*break*/, 6];
3142
3331
  }
3143
3332
  attempts++;
3144
3333
  if (attempts === MAX_RETRIES) {
3145
- setError("Failed to fetch data after multiple attempts");
3334
+ if (!window.toolsCache) setError("Failed to fetch data after multiple attempts");
3146
3335
  }
3147
3336
  return [3 /*break*/, 5];
3148
3337
  case 5:
3149
3338
  return [3 /*break*/, 1];
3150
3339
  case 6:
3340
+ if (window.toolsCache) {
3341
+ setError(null);
3342
+ setLoading(false);
3343
+ return [2 /*return*/, window.toolsCache];
3344
+ }
3151
3345
  setLoading(false);
3152
3346
  return [2 /*return*/, null];
3153
3347
  }
3154
3348
  });
3155
3349
  });
3156
- }();
3350
+ }()["finally"](function () {
3351
+ window.toolsFetchPromise = null;
3352
+ });
3157
3353
  }
3158
3354
  window.toolsFetchPromise.then(function (result) {
3159
3355
  if (result) setData(result);