@putkoff/abstract-utilities 0.1.243 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/cjs/index.js +771 -355
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/esm/index.js +773 -341
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/index.d.ts +14 -40
  6. package/dist/types/functions/auth_utils/imports.d.ts +0 -0
  7. package/dist/types/functions/auth_utils/index.d.ts +0 -0
  8. package/dist/types/functions/auth_utils/src/index.d.ts +0 -0
  9. package/dist/types/functions/auth_utils/src/token_utils.d.ts +0 -1
  10. package/dist/types/functions/config_utils/imports.d.ts +0 -0
  11. package/dist/types/functions/config_utils/index.d.ts +0 -0
  12. package/dist/types/functions/config_utils/src/config_utils.d.ts +6 -2
  13. package/dist/types/functions/config_utils/src/index.d.ts +0 -0
  14. package/dist/types/functions/constants_utils/index.d.ts +0 -0
  15. package/dist/types/functions/constants_utils/src/constants.d.ts +0 -0
  16. package/dist/types/functions/constants_utils/src/index.d.ts +0 -0
  17. package/dist/types/functions/env_utils/imports.d.ts +0 -0
  18. package/dist/types/functions/env_utils/index.d.ts +0 -0
  19. package/dist/types/functions/env_utils/src/index.d.ts +0 -0
  20. package/dist/types/functions/env_utils/src/window_utils.d.ts +0 -0
  21. package/dist/types/functions/fetch_utils/imports.d.ts +0 -0
  22. package/dist/types/functions/fetch_utils/index.d.ts +0 -0
  23. package/dist/types/functions/fetch_utils/src/fetch_utils.d.ts +2 -2
  24. package/dist/types/functions/fetch_utils/src/index.d.ts +0 -0
  25. package/dist/types/functions/fetch_utils/src/url_utils.d.ts +0 -0
  26. package/dist/types/functions/fetch_utils/src/utils.d.ts +1 -2
  27. package/dist/types/functions/index.d.ts +1 -2
  28. package/dist/types/functions/math_utils/index.d.ts +0 -0
  29. package/dist/types/functions/math_utils/safe_math.d.ts +0 -0
  30. package/dist/types/functions/path_utils/imports.d.ts +0 -0
  31. package/dist/types/functions/path_utils/index.d.ts +0 -0
  32. package/dist/types/functions/path_utils/src/base_dirs.d.ts +0 -0
  33. package/dist/types/functions/path_utils/src/function_dirs.d.ts +0 -0
  34. package/dist/types/functions/path_utils/src/index.d.ts +0 -0
  35. package/dist/types/functions/path_utils/src/misc_dirs.d.ts +0 -0
  36. package/dist/types/functions/path_utils/src/path_utils.d.ts +0 -4
  37. package/dist/types/functions/path_utils/src/paths.d.ts +0 -0
  38. package/dist/types/functions/path_utils/src/src_dirs.d.ts +0 -0
  39. package/dist/types/functions/read_utils/imports.d.ts +0 -0
  40. package/dist/types/functions/read_utils/index.d.ts +0 -0
  41. package/dist/types/functions/read_utils/src/index.d.ts +0 -0
  42. package/dist/types/functions/read_utils/src/utils.d.ts +0 -0
  43. package/dist/types/functions/rndm_utils/imports.d.ts +0 -0
  44. package/dist/types/functions/rndm_utils/index.d.ts +0 -0
  45. package/dist/types/functions/rndm_utils/src/index.d.ts +0 -0
  46. package/dist/types/functions/rndm_utils/src/utils.d.ts +0 -1
  47. package/dist/types/functions/safe_utils/imports.d.ts +0 -0
  48. package/dist/types/functions/safe_utils/index.d.ts +0 -0
  49. package/dist/types/functions/safe_utils/src/index.d.ts +0 -0
  50. package/dist/types/functions/safe_utils/src/safe_document.d.ts +0 -0
  51. package/dist/types/functions/safe_utils/src/safe_globals.d.ts +0 -0
  52. package/dist/types/functions/safe_utils/src/safe_storage.d.ts +0 -0
  53. package/dist/types/functions/safe_utils/src/safe_window.d.ts +0 -0
  54. package/dist/types/functions/string_utils/index.d.ts +0 -0
  55. package/dist/types/functions/string_utils/src/index.d.ts +0 -0
  56. package/dist/types/functions/string_utils/src/string_utils.d.ts +0 -2
  57. package/dist/types/functions/type_utils/imports.d.ts +0 -0
  58. package/dist/types/functions/type_utils/index.d.ts +0 -0
  59. package/dist/types/functions/type_utils/src/clean_utils.d.ts +0 -0
  60. package/dist/types/functions/type_utils/src/ensure_utils.d.ts +0 -0
  61. package/dist/types/functions/type_utils/src/imports.d.ts +0 -0
  62. package/dist/types/functions/type_utils/src/index.d.ts +0 -0
  63. package/dist/types/functions/type_utils/src/json_utils.d.ts +0 -0
  64. package/dist/types/functions/type_utils/src/mime_utils.d.ts +0 -0
  65. package/dist/types/functions/type_utils/src/type_utils.d.ts +0 -0
  66. package/dist/types/functions/ui_utils/imports.d.ts +0 -0
  67. package/dist/types/functions/ui_utils/index.d.ts +0 -0
  68. package/dist/types/functions/ui_utils/src/button.d.ts +0 -0
  69. package/dist/types/functions/ui_utils/src/checkbox.d.ts +0 -0
  70. package/dist/types/functions/ui_utils/src/index.d.ts +0 -0
  71. package/dist/types/functions/ui_utils/src/input.d.ts +0 -0
  72. package/dist/types/functions/ui_utils/src/spinner.d.ts +0 -0
  73. package/dist/types/functions/variable_utils/imports.d.ts +0 -0
  74. package/dist/types/functions/variable_utils/index.d.ts +0 -0
  75. package/dist/types/functions/variable_utils/src/index.d.ts +0 -0
  76. package/dist/types/functions/variable_utils/src/variable_utils.d.ts +0 -0
  77. package/dist/types/index.d.ts +0 -0
  78. package/dist/types/types/index.d.ts +0 -0
  79. package/dist/types/types/src/ChangePassword.d.ts +0 -0
  80. package/dist/types/types/src/Files.d.ts +0 -0
  81. package/dist/types/types/src/index.d.ts +0 -0
  82. package/dist/types/types/src/login.d.ts +0 -0
  83. package/dist/types/types/src/logout.d.ts +0 -0
  84. package/dist/types/types/src/utils.d.ts +0 -0
  85. package/dist/types/utils/imports.d.ts +0 -0
  86. package/dist/types/utils/index.d.ts +0 -0
  87. package/dist/types/utils/src/Input.d.ts +0 -0
  88. package/dist/types/utils/src/config.d.ts +0 -0
  89. package/dist/types/utils/src/index.d.ts +0 -0
  90. package/package.json +89 -69
  91. package/dist/types/functions/path_utils/src/path_utils.browser.d.ts +0 -2
  92. package/dist/types/functions/path_utils/src/path_utils.node.d.ts +0 -2
  93. package/dist/types/functions/read_utils/src/read_utils.browser.d.ts +0 -1
  94. package/dist/types/functions/read_utils/src/utils.browser.d.ts +0 -3
  95. package/dist/types/functions/url_utils/index.d.ts +0 -1
  96. package/dist/types/functions/url_utils/uri_utils.d.ts +0 -19
package/dist/cjs/index.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  var react = require('react');
4
4
  var path = require('path');
5
- var path$2 = require('path-browserify');
6
5
  var fs = require('node:fs');
7
6
  var fsp = require('node:fs/promises');
8
7
  var path$1 = require('node:path');
@@ -26,7 +25,6 @@ function _interopNamespaceDefault(e) {
26
25
  return Object.freeze(n);
27
26
  }
28
27
 
29
- var path__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(path$2);
30
28
  var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
31
29
  var fsp__namespace = /*#__PURE__*/_interopNamespaceDefault(fsp);
32
30
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path$1);
@@ -170,17 +168,6 @@ function isLoggedIn() {
170
168
  const tok = getToken();
171
169
  return !!tok && !isTokenExpired(tok !== null && tok !== void 0 ? tok : "");
172
170
  }
173
- function removeToken() {
174
- let is_logged = isLoggedIn();
175
- if (is_logged) {
176
- callStorage('removeItem', "token");
177
- }
178
- is_logged = isLoggedIn();
179
- if (is_logged) {
180
- return false;
181
- }
182
- return true;
183
- }
184
171
  /**
185
172
  * Add a Bearer Authorization header.
186
173
  * A shallow copy of headers is returned so callers can keep chaining.
@@ -197,7 +184,7 @@ function requireToken() {
197
184
  const tok = getToken();
198
185
  if (!tok || isTokenExpired(tok)) {
199
186
  console.warn("→ No token or expired token, redirecting to login…");
200
- removeToken();
187
+ localStorage.removeItem("token");
201
188
  window.location.href = '/';
202
189
  throw new Error("Redirecting to login…");
203
190
  }
@@ -215,13 +202,16 @@ function isTokenExpired(token) {
215
202
  }
216
203
  /** Convenience wrapper: return username from the JWT (or null). */
217
204
  function currentUsername() {
218
- const token = getToken();
219
- let uName = null;
220
- if (token) {
221
- const decodedJwt = decodeJwt(token) || {};
222
- uName = (decodedJwt === null || decodedJwt === void 0 ? void 0 : decodedJwt.username) || null;
205
+ const tok = getToken();
206
+ if (!tok)
207
+ return null;
208
+ try {
209
+ const { username } = decodeJwt(tok);
210
+ return username !== null && username !== void 0 ? username : null;
211
+ }
212
+ catch (_a) {
213
+ return null;
223
214
  }
224
- return uName;
225
215
  }
226
216
  function currentUsernames() {
227
217
  var _a;
@@ -365,37 +355,44 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
365
355
  */
366
356
  function readJsonFile(relativeOrAbsolutePath) {
367
357
  return __awaiter(this, void 0, void 0, function* () {
368
- if (typeof window === 'undefined') {
358
+ // 1) Try Node.js fs
359
+ if (typeof process !== 'undefined' &&
360
+ process.versions != null &&
361
+ process.versions.node) {
369
362
  try {
370
- const { readFile } = yield import('fs/promises');
371
- const { isAbsolute, resolve } = yield import('path');
372
- const filePath = isAbsolute(relativeOrAbsolutePath)
363
+ const fs = yield import('fs');
364
+ const path = yield import('path');
365
+ const filePath = path.isAbsolute(relativeOrAbsolutePath)
373
366
  ? relativeOrAbsolutePath
374
- : resolve((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) ? new URL('.', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href))).pathname : '', relativeOrAbsolutePath);
375
- const text = yield readFile(filePath, 'utf8');
367
+ : path.resolve(process.cwd(), relativeOrAbsolutePath);
368
+ const text = yield fs.promises.readFile(filePath, 'utf8');
376
369
  return JSON.parse(text);
377
370
  }
378
371
  catch (_a) {
379
- return null;
372
+ // swallow and fall back to browser
380
373
  }
381
374
  }
382
- // Browser fallback
375
+ // 2) Try browser fetch
383
376
  const fetchFn = safeGlobalProp('fetch');
384
- if (typeof fetchFn !== 'function')
377
+ if (typeof fetchFn !== 'function') {
385
378
  return null;
379
+ }
380
+ // Resolve URL against document.baseURI if possible
386
381
  let url = relativeOrAbsolutePath;
387
382
  const baseURI = safeGlobalProp('document', 'baseURI');
388
383
  if (baseURI) {
389
384
  try {
390
385
  url = new URL(relativeOrAbsolutePath, baseURI).href;
391
386
  }
392
- catch (_b) { }
387
+ catch (_b) {
388
+ // keep url as-is
389
+ }
393
390
  }
394
391
  try {
395
392
  const res = yield fetchFn(url);
396
393
  if (!res.ok)
397
394
  return null;
398
- return yield res.json();
395
+ return (yield res.json());
399
396
  }
400
397
  catch (_c) {
401
398
  return null;
@@ -438,7 +435,6 @@ function getResult(obj) {
438
435
  }
439
436
  return current;
440
437
  }
441
- const get_result = getResult;
442
438
  // Determines HTTP method, defaults to GET or POST based on body
443
439
  function getMethod(method = null, body = null) {
444
440
  const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'PULL'];
@@ -527,7 +523,7 @@ function checkResponse(res) {
527
523
  }
528
524
 
529
525
  function fetchIt(endpoint_1) {
530
- return __awaiter(this, arguments, void 0, function* (endpoint, body = null, method = null, headers = null, blob = false, configUrl = false, withCredentials = true, returnJson = true, returnResult = true) {
526
+ return __awaiter(this, arguments, void 0, function* (endpoint, body = null, method = null, headers = null, blob = false, configUrl = false, withCredentials = true, returnJson = true, returnReult = true) {
531
527
  method = (method || "GET").toUpperCase();
532
528
  // 2) choose the URL
533
529
  let url = endpoint;
@@ -543,20 +539,18 @@ function fetchIt(endpoint_1) {
543
539
  ? JSON.stringify(body)
544
540
  : undefined,
545
541
  };
546
- let res = yield fetch(url, opts);
542
+ console.debug("➡️ secureFetchIt →", url, opts);
543
+ const res = yield fetch(url, opts);
547
544
  if (!res.ok) {
548
545
  const err = yield res.text();
549
546
  throw new Error(`HTTP ${res.status}: ${err}`);
550
547
  }
551
548
  if (blob)
552
549
  return res.blob();
553
- if (returnResult || returnJson) {
554
- let JsonRes = parseResult(res);
555
- if (returnResult) {
556
- JsonRes = getResult(JsonRes);
557
- }
558
- return JsonRes;
559
- }
550
+ if (returnReult)
551
+ return getResult(res.json());
552
+ if (returnJson)
553
+ return res.json();
560
554
  return res;
561
555
  });
562
556
  }
@@ -670,6 +664,637 @@ function url_to_path(urlStr, all_paths) {
670
664
  return null;
671
665
  }
672
666
 
667
+ function assertPath(path) {
668
+ if (typeof path !== 'string') {
669
+ throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
670
+ }
671
+ }
672
+
673
+ // Resolves . and .. elements in a path with directory names
674
+ function normalizeStringPosix(path, allowAboveRoot) {
675
+ var res = '';
676
+ var lastSegmentLength = 0;
677
+ var lastSlash = -1;
678
+ var dots = 0;
679
+ var code;
680
+ for (var i = 0; i <= path.length; ++i) {
681
+ if (i < path.length)
682
+ code = path.charCodeAt(i);
683
+ else if (code === 47 /*/*/)
684
+ break;
685
+ else
686
+ code = 47 /*/*/;
687
+ if (code === 47 /*/*/) {
688
+ if (lastSlash === i - 1 || dots === 1) ; else if (lastSlash !== i - 1 && dots === 2) {
689
+ if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
690
+ if (res.length > 2) {
691
+ var lastSlashIndex = res.lastIndexOf('/');
692
+ if (lastSlashIndex !== res.length - 1) {
693
+ if (lastSlashIndex === -1) {
694
+ res = '';
695
+ lastSegmentLength = 0;
696
+ } else {
697
+ res = res.slice(0, lastSlashIndex);
698
+ lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
699
+ }
700
+ lastSlash = i;
701
+ dots = 0;
702
+ continue;
703
+ }
704
+ } else if (res.length === 2 || res.length === 1) {
705
+ res = '';
706
+ lastSegmentLength = 0;
707
+ lastSlash = i;
708
+ dots = 0;
709
+ continue;
710
+ }
711
+ }
712
+ if (allowAboveRoot) {
713
+ if (res.length > 0)
714
+ res += '/..';
715
+ else
716
+ res = '..';
717
+ lastSegmentLength = 2;
718
+ }
719
+ } else {
720
+ if (res.length > 0)
721
+ res += '/' + path.slice(lastSlash + 1, i);
722
+ else
723
+ res = path.slice(lastSlash + 1, i);
724
+ lastSegmentLength = i - lastSlash - 1;
725
+ }
726
+ lastSlash = i;
727
+ dots = 0;
728
+ } else if (code === 46 /*.*/ && dots !== -1) {
729
+ ++dots;
730
+ } else {
731
+ dots = -1;
732
+ }
733
+ }
734
+ return res;
735
+ }
736
+
737
+ function _format(sep, pathObject) {
738
+ var dir = pathObject.dir || pathObject.root;
739
+ var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
740
+ if (!dir) {
741
+ return base;
742
+ }
743
+ if (dir === pathObject.root) {
744
+ return dir + base;
745
+ }
746
+ return dir + sep + base;
747
+ }
748
+
749
+ var posix = {
750
+ // path.resolve([from ...], to)
751
+ resolve: function resolve() {
752
+ var resolvedPath = '';
753
+ var resolvedAbsolute = false;
754
+ var cwd;
755
+
756
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
757
+ var path;
758
+ if (i >= 0)
759
+ path = arguments[i];
760
+ else {
761
+ if (cwd === undefined)
762
+ cwd = process.cwd();
763
+ path = cwd;
764
+ }
765
+
766
+ assertPath(path);
767
+
768
+ // Skip empty entries
769
+ if (path.length === 0) {
770
+ continue;
771
+ }
772
+
773
+ resolvedPath = path + '/' + resolvedPath;
774
+ resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;
775
+ }
776
+
777
+ // At this point the path should be resolved to a full absolute path, but
778
+ // handle relative paths to be safe (might happen when process.cwd() fails)
779
+
780
+ // Normalize the path
781
+ resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
782
+
783
+ if (resolvedAbsolute) {
784
+ if (resolvedPath.length > 0)
785
+ return '/' + resolvedPath;
786
+ else
787
+ return '/';
788
+ } else if (resolvedPath.length > 0) {
789
+ return resolvedPath;
790
+ } else {
791
+ return '.';
792
+ }
793
+ },
794
+
795
+ normalize: function normalize(path) {
796
+ assertPath(path);
797
+
798
+ if (path.length === 0) return '.';
799
+
800
+ var isAbsolute = path.charCodeAt(0) === 47 /*/*/;
801
+ var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;
802
+
803
+ // Normalize the path
804
+ path = normalizeStringPosix(path, !isAbsolute);
805
+
806
+ if (path.length === 0 && !isAbsolute) path = '.';
807
+ if (path.length > 0 && trailingSeparator) path += '/';
808
+
809
+ if (isAbsolute) return '/' + path;
810
+ return path;
811
+ },
812
+
813
+ isAbsolute: function isAbsolute(path) {
814
+ assertPath(path);
815
+ return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;
816
+ },
817
+
818
+ join: function join() {
819
+ if (arguments.length === 0)
820
+ return '.';
821
+ var joined;
822
+ for (var i = 0; i < arguments.length; ++i) {
823
+ var arg = arguments[i];
824
+ assertPath(arg);
825
+ if (arg.length > 0) {
826
+ if (joined === undefined)
827
+ joined = arg;
828
+ else
829
+ joined += '/' + arg;
830
+ }
831
+ }
832
+ if (joined === undefined)
833
+ return '.';
834
+ return posix.normalize(joined);
835
+ },
836
+
837
+ relative: function relative(from, to) {
838
+ assertPath(from);
839
+ assertPath(to);
840
+
841
+ if (from === to) return '';
842
+
843
+ from = posix.resolve(from);
844
+ to = posix.resolve(to);
845
+
846
+ if (from === to) return '';
847
+
848
+ // Trim any leading backslashes
849
+ var fromStart = 1;
850
+ for (; fromStart < from.length; ++fromStart) {
851
+ if (from.charCodeAt(fromStart) !== 47 /*/*/)
852
+ break;
853
+ }
854
+ var fromEnd = from.length;
855
+ var fromLen = fromEnd - fromStart;
856
+
857
+ // Trim any leading backslashes
858
+ var toStart = 1;
859
+ for (; toStart < to.length; ++toStart) {
860
+ if (to.charCodeAt(toStart) !== 47 /*/*/)
861
+ break;
862
+ }
863
+ var toEnd = to.length;
864
+ var toLen = toEnd - toStart;
865
+
866
+ // Compare paths to find the longest common path from root
867
+ var length = fromLen < toLen ? fromLen : toLen;
868
+ var lastCommonSep = -1;
869
+ var i = 0;
870
+ for (; i <= length; ++i) {
871
+ if (i === length) {
872
+ if (toLen > length) {
873
+ if (to.charCodeAt(toStart + i) === 47 /*/*/) {
874
+ // We get here if `from` is the exact base path for `to`.
875
+ // For example: from='/foo/bar'; to='/foo/bar/baz'
876
+ return to.slice(toStart + i + 1);
877
+ } else if (i === 0) {
878
+ // We get here if `from` is the root
879
+ // For example: from='/'; to='/foo'
880
+ return to.slice(toStart + i);
881
+ }
882
+ } else if (fromLen > length) {
883
+ if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
884
+ // We get here if `to` is the exact base path for `from`.
885
+ // For example: from='/foo/bar/baz'; to='/foo/bar'
886
+ lastCommonSep = i;
887
+ } else if (i === 0) {
888
+ // We get here if `to` is the root.
889
+ // For example: from='/foo'; to='/'
890
+ lastCommonSep = 0;
891
+ }
892
+ }
893
+ break;
894
+ }
895
+ var fromCode = from.charCodeAt(fromStart + i);
896
+ var toCode = to.charCodeAt(toStart + i);
897
+ if (fromCode !== toCode)
898
+ break;
899
+ else if (fromCode === 47 /*/*/)
900
+ lastCommonSep = i;
901
+ }
902
+
903
+ var out = '';
904
+ // Generate the relative path based on the path difference between `to`
905
+ // and `from`
906
+ for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
907
+ if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
908
+ if (out.length === 0)
909
+ out += '..';
910
+ else
911
+ out += '/..';
912
+ }
913
+ }
914
+
915
+ // Lastly, append the rest of the destination (`to`) path that comes after
916
+ // the common path parts
917
+ if (out.length > 0)
918
+ return out + to.slice(toStart + lastCommonSep);
919
+ else {
920
+ toStart += lastCommonSep;
921
+ if (to.charCodeAt(toStart) === 47 /*/*/)
922
+ ++toStart;
923
+ return to.slice(toStart);
924
+ }
925
+ },
926
+
927
+ _makeLong: function _makeLong(path) {
928
+ return path;
929
+ },
930
+
931
+ dirname: function dirname(path) {
932
+ assertPath(path);
933
+ if (path.length === 0) return '.';
934
+ var code = path.charCodeAt(0);
935
+ var hasRoot = code === 47 /*/*/;
936
+ var end = -1;
937
+ var matchedSlash = true;
938
+ for (var i = path.length - 1; i >= 1; --i) {
939
+ code = path.charCodeAt(i);
940
+ if (code === 47 /*/*/) {
941
+ if (!matchedSlash) {
942
+ end = i;
943
+ break;
944
+ }
945
+ } else {
946
+ // We saw the first non-path separator
947
+ matchedSlash = false;
948
+ }
949
+ }
950
+
951
+ if (end === -1) return hasRoot ? '/' : '.';
952
+ if (hasRoot && end === 1) return '//';
953
+ return path.slice(0, end);
954
+ },
955
+
956
+ basename: function basename(path, ext) {
957
+ if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
958
+ assertPath(path);
959
+
960
+ var start = 0;
961
+ var end = -1;
962
+ var matchedSlash = true;
963
+ var i;
964
+
965
+ if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
966
+ if (ext.length === path.length && ext === path) return '';
967
+ var extIdx = ext.length - 1;
968
+ var firstNonSlashEnd = -1;
969
+ for (i = path.length - 1; i >= 0; --i) {
970
+ var code = path.charCodeAt(i);
971
+ if (code === 47 /*/*/) {
972
+ // If we reached a path separator that was not part of a set of path
973
+ // separators at the end of the string, stop now
974
+ if (!matchedSlash) {
975
+ start = i + 1;
976
+ break;
977
+ }
978
+ } else {
979
+ if (firstNonSlashEnd === -1) {
980
+ // We saw the first non-path separator, remember this index in case
981
+ // we need it if the extension ends up not matching
982
+ matchedSlash = false;
983
+ firstNonSlashEnd = i + 1;
984
+ }
985
+ if (extIdx >= 0) {
986
+ // Try to match the explicit extension
987
+ if (code === ext.charCodeAt(extIdx)) {
988
+ if (--extIdx === -1) {
989
+ // We matched the extension, so mark this as the end of our path
990
+ // component
991
+ end = i;
992
+ }
993
+ } else {
994
+ // Extension does not match, so our result is the entire path
995
+ // component
996
+ extIdx = -1;
997
+ end = firstNonSlashEnd;
998
+ }
999
+ }
1000
+ }
1001
+ }
1002
+
1003
+ if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
1004
+ return path.slice(start, end);
1005
+ } else {
1006
+ for (i = path.length - 1; i >= 0; --i) {
1007
+ if (path.charCodeAt(i) === 47 /*/*/) {
1008
+ // If we reached a path separator that was not part of a set of path
1009
+ // separators at the end of the string, stop now
1010
+ if (!matchedSlash) {
1011
+ start = i + 1;
1012
+ break;
1013
+ }
1014
+ } else if (end === -1) {
1015
+ // We saw the first non-path separator, mark this as the end of our
1016
+ // path component
1017
+ matchedSlash = false;
1018
+ end = i + 1;
1019
+ }
1020
+ }
1021
+
1022
+ if (end === -1) return '';
1023
+ return path.slice(start, end);
1024
+ }
1025
+ },
1026
+
1027
+ extname: function extname(path) {
1028
+ assertPath(path);
1029
+ var startDot = -1;
1030
+ var startPart = 0;
1031
+ var end = -1;
1032
+ var matchedSlash = true;
1033
+ // Track the state of characters (if any) we see before our first dot and
1034
+ // after any path separator we find
1035
+ var preDotState = 0;
1036
+ for (var i = path.length - 1; i >= 0; --i) {
1037
+ var code = path.charCodeAt(i);
1038
+ if (code === 47 /*/*/) {
1039
+ // If we reached a path separator that was not part of a set of path
1040
+ // separators at the end of the string, stop now
1041
+ if (!matchedSlash) {
1042
+ startPart = i + 1;
1043
+ break;
1044
+ }
1045
+ continue;
1046
+ }
1047
+ if (end === -1) {
1048
+ // We saw the first non-path separator, mark this as the end of our
1049
+ // extension
1050
+ matchedSlash = false;
1051
+ end = i + 1;
1052
+ }
1053
+ if (code === 46 /*.*/) {
1054
+ // If this is our first dot, mark it as the start of our extension
1055
+ if (startDot === -1)
1056
+ startDot = i;
1057
+ else if (preDotState !== 1)
1058
+ preDotState = 1;
1059
+ } else if (startDot !== -1) {
1060
+ // We saw a non-dot and non-path separator before our dot, so we should
1061
+ // have a good chance at having a non-empty extension
1062
+ preDotState = -1;
1063
+ }
1064
+ }
1065
+
1066
+ if (startDot === -1 || end === -1 ||
1067
+ // We saw a non-dot character immediately before the dot
1068
+ preDotState === 0 ||
1069
+ // The (right-most) trimmed path component is exactly '..'
1070
+ preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
1071
+ return '';
1072
+ }
1073
+ return path.slice(startDot, end);
1074
+ },
1075
+
1076
+ format: function format(pathObject) {
1077
+ if (pathObject === null || typeof pathObject !== 'object') {
1078
+ throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
1079
+ }
1080
+ return _format('/', pathObject);
1081
+ },
1082
+
1083
+ parse: function parse(path) {
1084
+ assertPath(path);
1085
+
1086
+ var ret = { root: '', dir: '', base: '', ext: '', name: '' };
1087
+ if (path.length === 0) return ret;
1088
+ var code = path.charCodeAt(0);
1089
+ var isAbsolute = code === 47 /*/*/;
1090
+ var start;
1091
+ if (isAbsolute) {
1092
+ ret.root = '/';
1093
+ start = 1;
1094
+ } else {
1095
+ start = 0;
1096
+ }
1097
+ var startDot = -1;
1098
+ var startPart = 0;
1099
+ var end = -1;
1100
+ var matchedSlash = true;
1101
+ var i = path.length - 1;
1102
+
1103
+ // Track the state of characters (if any) we see before our first dot and
1104
+ // after any path separator we find
1105
+ var preDotState = 0;
1106
+
1107
+ // Get non-dir info
1108
+ for (; i >= start; --i) {
1109
+ code = path.charCodeAt(i);
1110
+ if (code === 47 /*/*/) {
1111
+ // If we reached a path separator that was not part of a set of path
1112
+ // separators at the end of the string, stop now
1113
+ if (!matchedSlash) {
1114
+ startPart = i + 1;
1115
+ break;
1116
+ }
1117
+ continue;
1118
+ }
1119
+ if (end === -1) {
1120
+ // We saw the first non-path separator, mark this as the end of our
1121
+ // extension
1122
+ matchedSlash = false;
1123
+ end = i + 1;
1124
+ }
1125
+ if (code === 46 /*.*/) {
1126
+ // If this is our first dot, mark it as the start of our extension
1127
+ if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
1128
+ } else if (startDot !== -1) {
1129
+ // We saw a non-dot and non-path separator before our dot, so we should
1130
+ // have a good chance at having a non-empty extension
1131
+ preDotState = -1;
1132
+ }
1133
+ }
1134
+
1135
+ if (startDot === -1 || end === -1 ||
1136
+ // We saw a non-dot character immediately before the dot
1137
+ preDotState === 0 ||
1138
+ // The (right-most) trimmed path component is exactly '..'
1139
+ preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
1140
+ if (end !== -1) {
1141
+ if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
1142
+ }
1143
+ } else {
1144
+ if (startPart === 0 && isAbsolute) {
1145
+ ret.name = path.slice(1, startDot);
1146
+ ret.base = path.slice(1, end);
1147
+ } else {
1148
+ ret.name = path.slice(startPart, startDot);
1149
+ ret.base = path.slice(startPart, end);
1150
+ }
1151
+ ret.ext = path.slice(startDot, end);
1152
+ }
1153
+
1154
+ if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
1155
+
1156
+ return ret;
1157
+ },
1158
+
1159
+ sep: '/',
1160
+ delimiter: ':',
1161
+ win32: null,
1162
+ posix: null
1163
+ };
1164
+
1165
+ posix.posix = posix;
1166
+
1167
+ var pathBrowserify = posix;
1168
+
1169
+ function getSubstring(obj, maxLength = null, minLength = null) {
1170
+ const objLength = obj.length;
1171
+ const effectiveMaxLength = maxLength !== null && maxLength !== void 0 ? maxLength : objLength; // Use nullish coalescing for clarity
1172
+ const effectiveMinLength = minLength !== null && minLength !== void 0 ? minLength : 0;
1173
+ // Ensure bounds are valid
1174
+ const clampedMaxLength = Math.min(Math.max(effectiveMaxLength, 0), objLength);
1175
+ const clampedMinLength = Math.min(Math.max(effectiveMinLength, 0), objLength);
1176
+ // If minLength exceeds maxLength, return empty string or adjust logic as needed
1177
+ if (clampedMinLength >= clampedMaxLength) {
1178
+ return '';
1179
+ }
1180
+ return obj.substring(clampedMinLength, clampedMaxLength);
1181
+ }
1182
+ function truncateString(obj, maxLength = 20) {
1183
+ const objLength = obj.length;
1184
+ if (objLength > maxLength && maxLength) {
1185
+ obj = getSubstring(obj, maxLength) + '...';
1186
+ }
1187
+ return obj;
1188
+ }
1189
+ // string_utils/src/string_utils.ts
1190
+ function stripPrefixes(str, bases = []) {
1191
+ /* NEW: coerce whatever arrives into a string */
1192
+ str = String(str);
1193
+ const prefixes = (Array.isArray(bases) ? bases : [bases])
1194
+ .filter(Boolean)
1195
+ .sort((a, b) => b.length - a.length); // longest first
1196
+ let changed = true;
1197
+ while (changed) {
1198
+ changed = false;
1199
+ for (const prefix of prefixes) {
1200
+ if (str.startsWith(prefix)) {
1201
+ str = str.slice(prefix.length);
1202
+ changed = true;
1203
+ break; // restart from longest prefix
1204
+ }
1205
+ }
1206
+ }
1207
+ return str;
1208
+ }
1209
+ /**
1210
+ * Removes characters from the beginning of the string
1211
+ * if they are found in the list of characters.
1212
+ *
1213
+ * @param str - The input string.
1214
+ * @param listObjects - A string or an array of characters to remove.
1215
+ * @returns The modified string.
1216
+ */
1217
+ function eatInner(str, listObjects) {
1218
+ if (!Array.isArray(listObjects)) {
1219
+ listObjects = [listObjects];
1220
+ }
1221
+ // Ensure str is a string
1222
+ str = String(str);
1223
+ // Remove characters from the beginning while they are in listObjects
1224
+ while (str.length > 0 && listObjects.includes(str[0])) {
1225
+ str = str.slice(1);
1226
+ }
1227
+ return str;
1228
+ }
1229
+ /**
1230
+ * Removes characters from the end of the string
1231
+ * if they are found in the list of characters.
1232
+ *
1233
+ * @param str - The input string.
1234
+ * @param listObjects - A string or an array of characters to remove.
1235
+ * @returns The modified string.
1236
+ */
1237
+ function eatOuter(str, listObjects) {
1238
+ if (!Array.isArray(listObjects)) {
1239
+ listObjects = [listObjects];
1240
+ }
1241
+ // Ensure str is a string
1242
+ str = String(str);
1243
+ // Remove characters from the end while they are in listObjects
1244
+ while (str.length > 0 && listObjects.includes(str[str.length - 1])) {
1245
+ str = str.slice(0, -1);
1246
+ }
1247
+ return str;
1248
+ }
1249
+ /**
1250
+ * Removes characters from both the beginning and the end of the string
1251
+ * if they are found in the list of characters.
1252
+ *
1253
+ * @param str - The input string.
1254
+ * @param listObjects - A string or an array of characters to remove.
1255
+ * @returns The modified string.
1256
+ */
1257
+ function eatAll(str, listObjects) {
1258
+ return eatOuter(eatInner(str, listObjects), listObjects);
1259
+ }
1260
+ function eatEnd(obj, endings = ['/']) {
1261
+ let result = obj;
1262
+ let modified = true;
1263
+ while (modified) {
1264
+ modified = false;
1265
+ for (const ending of endings) {
1266
+ if (result.endsWith(ending)) {
1267
+ result = result.slice(0, -ending.length);
1268
+ modified = true;
1269
+ break;
1270
+ }
1271
+ }
1272
+ }
1273
+ return result;
1274
+ }
1275
+ function tryParse(obj) {
1276
+ try {
1277
+ obj = JSON.stringify(obj);
1278
+ }
1279
+ catch (err) {
1280
+ try {
1281
+ obj = JSON.parse(obj);
1282
+ }
1283
+ catch (err) {
1284
+ }
1285
+ }
1286
+ return obj;
1287
+ }
1288
+ function create_list_string(array_obj) {
1289
+ let string = '';
1290
+ for (const obj in array_obj) {
1291
+ const array_value = array_obj[obj];
1292
+ const parsed_value = tryParse(array_value);
1293
+ string += `${obj} == ${parsed_value}\n`;
1294
+ }
1295
+ return string;
1296
+ }
1297
+
673
1298
  function ensure_list(obj) {
674
1299
  const objArray = Array.isArray(obj) ? obj : [obj];
675
1300
  return objArray;
@@ -1110,159 +1735,6 @@ const confirm_type = confirmType;
1110
1735
  const is_media_type = isMediaType;
1111
1736
  const get_mime_type = getMimeType;
1112
1737
 
1113
- function getSubstring(obj, maxLength = null, minLength = null) {
1114
- const objLength = obj.length;
1115
- const effectiveMaxLength = maxLength !== null && maxLength !== void 0 ? maxLength : objLength; // Use nullish coalescing for clarity
1116
- const effectiveMinLength = minLength !== null && minLength !== void 0 ? minLength : 0;
1117
- // Ensure bounds are valid
1118
- const clampedMaxLength = Math.min(Math.max(effectiveMaxLength, 0), objLength);
1119
- const clampedMinLength = Math.min(Math.max(effectiveMinLength, 0), objLength);
1120
- // If minLength exceeds maxLength, return empty string or adjust logic as needed
1121
- if (clampedMinLength >= clampedMaxLength) {
1122
- return '';
1123
- }
1124
- return obj.substring(clampedMinLength, clampedMaxLength);
1125
- }
1126
- function truncateString(obj, maxLength = 20) {
1127
- const objLength = obj.length;
1128
- if (objLength > maxLength && maxLength) {
1129
- obj = getSubstring(obj, maxLength) + '...';
1130
- }
1131
- return obj;
1132
- }
1133
- function capitalize_str(string) {
1134
- string = assureString(string);
1135
- const string_len = string.length;
1136
- let init_char = string.toUpperCase();
1137
- if (string_len > 0) {
1138
- init_char = string[0].toUpperCase();
1139
- }
1140
- let rest_chars = '';
1141
- if (string_len > 1) {
1142
- rest_chars = string.slice(1).toLowerCase();
1143
- }
1144
- const fin_chars = `${init_char}${rest_chars}`;
1145
- return fin_chars;
1146
- }
1147
- function capitalize(string) {
1148
- let nu_string = '';
1149
- string = assureString(string);
1150
- let objs = string.replace('-', '_').split('_');
1151
- for (const obj of objs) {
1152
- let str_obj = capitalize_str(obj);
1153
- nu_string = `${nu_string} ${str_obj}`;
1154
- }
1155
- return eatAll(nu_string, [' ']);
1156
- }
1157
- // string_utils/src/string_utils.ts
1158
- function stripPrefixes(str, bases = []) {
1159
- /* NEW: coerce whatever arrives into a string */
1160
- str = String(str);
1161
- const prefixes = (Array.isArray(bases) ? bases : [bases])
1162
- .filter(Boolean)
1163
- .sort((a, b) => b.length - a.length); // longest first
1164
- let changed = true;
1165
- while (changed) {
1166
- changed = false;
1167
- for (const prefix of prefixes) {
1168
- if (str.startsWith(prefix)) {
1169
- str = str.slice(prefix.length);
1170
- changed = true;
1171
- break; // restart from longest prefix
1172
- }
1173
- }
1174
- }
1175
- return str;
1176
- }
1177
- /**
1178
- * Removes characters from the beginning of the string
1179
- * if they are found in the list of characters.
1180
- *
1181
- * @param str - The input string.
1182
- * @param listObjects - A string or an array of characters to remove.
1183
- * @returns The modified string.
1184
- */
1185
- function eatInner(str, listObjects) {
1186
- if (!Array.isArray(listObjects)) {
1187
- listObjects = [listObjects];
1188
- }
1189
- // Ensure str is a string
1190
- str = String(str);
1191
- // Remove characters from the beginning while they are in listObjects
1192
- while (str.length > 0 && listObjects.includes(str[0])) {
1193
- str = str.slice(1);
1194
- }
1195
- return str;
1196
- }
1197
- /**
1198
- * Removes characters from the end of the string
1199
- * if they are found in the list of characters.
1200
- *
1201
- * @param str - The input string.
1202
- * @param listObjects - A string or an array of characters to remove.
1203
- * @returns The modified string.
1204
- */
1205
- function eatOuter(str, listObjects) {
1206
- if (!Array.isArray(listObjects)) {
1207
- listObjects = [listObjects];
1208
- }
1209
- // Ensure str is a string
1210
- str = String(str);
1211
- // Remove characters from the end while they are in listObjects
1212
- while (str.length > 0 && listObjects.includes(str[str.length - 1])) {
1213
- str = str.slice(0, -1);
1214
- }
1215
- return str;
1216
- }
1217
- /**
1218
- * Removes characters from both the beginning and the end of the string
1219
- * if they are found in the list of characters.
1220
- *
1221
- * @param str - The input string.
1222
- * @param listObjects - A string or an array of characters to remove.
1223
- * @returns The modified string.
1224
- */
1225
- function eatAll(str, listObjects) {
1226
- return eatOuter(eatInner(str, listObjects), listObjects);
1227
- }
1228
- function eatEnd(obj, endings = ['/']) {
1229
- let result = obj;
1230
- let modified = true;
1231
- while (modified) {
1232
- modified = false;
1233
- for (const ending of endings) {
1234
- if (result.endsWith(ending)) {
1235
- result = result.slice(0, -ending.length);
1236
- modified = true;
1237
- break;
1238
- }
1239
- }
1240
- }
1241
- return result;
1242
- }
1243
- function tryParse(obj) {
1244
- try {
1245
- obj = JSON.stringify(obj);
1246
- }
1247
- catch (err) {
1248
- try {
1249
- obj = JSON.parse(obj);
1250
- }
1251
- catch (err) {
1252
- }
1253
- }
1254
- return obj;
1255
- }
1256
- function create_list_string(array_obj) {
1257
- let string = '';
1258
- for (const obj in array_obj) {
1259
- const array_value = array_obj[obj];
1260
- const parsed_value = tryParse(array_value);
1261
- string += `${obj} == ${parsed_value}\n`;
1262
- }
1263
- return string;
1264
- }
1265
-
1266
1738
  /**
1267
1739
  * In the browser we already have a WHATWG URL constructor on window.
1268
1740
  * Here we re-export it as “url” so other modules can import it.
@@ -1283,37 +1755,34 @@ function fileURLToPath(fileUrl) {
1283
1755
  }
1284
1756
  }
1285
1757
  function getAbsolutePath() {
1286
- if (typeof window !== 'undefined')
1287
- return '';
1288
1758
  return fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
1289
1759
  }
1290
1760
 
1291
- // path_utils.browser.ts
1292
1761
  function get_dirname(filePath) {
1293
1762
  if (!filePath)
1294
1763
  return '';
1295
- return path__namespace$1.dirname(filePath);
1764
+ return pathBrowserify.dirname(filePath);
1296
1765
  }
1297
1766
  function get_basename(filePath) {
1298
1767
  if (!filePath)
1299
1768
  return '';
1300
- return path__namespace$1.basename(filePath);
1769
+ return pathBrowserify.basename(filePath);
1301
1770
  }
1302
1771
  function get_filename(file_path) {
1303
- const ext = path__namespace$1.extname(file_path);
1304
- return path__namespace$1.basename(file_path, ext);
1772
+ const ext = pathBrowserify.extname(file_path);
1773
+ return pathBrowserify.basename(file_path, ext);
1305
1774
  }
1306
1775
  function get_extname(filePath) {
1307
1776
  if (!filePath)
1308
1777
  return '';
1309
- return path__namespace$1.extname(filePath);
1778
+ return pathBrowserify.extname(filePath);
1310
1779
  }
1311
1780
  function get_splitext(filePath) {
1312
1781
  if (!filePath)
1313
1782
  return { filename: '', extname: '' };
1314
- const ext = path__namespace$1.extname(filePath);
1783
+ const ext = pathBrowserify.extname(filePath);
1315
1784
  // Get the basename without the extension
1316
- const filename = path__namespace$1.basename(filePath, ext);
1785
+ const filename = pathBrowserify.basename(filePath, ext);
1317
1786
  return { filename, ext };
1318
1787
  }
1319
1788
  /**
@@ -1344,23 +1813,6 @@ function make_path(...paths) {
1344
1813
  }
1345
1814
  return real_path;
1346
1815
  }
1347
- function makePath(...paths) {
1348
- var _a;
1349
- const pathArray = ensure_list(paths);
1350
- let real_path = '';
1351
- for (let i = 0; i < pathArray.length; i++) {
1352
- let seg = String((_a = pathArray[i]) !== null && _a !== void 0 ? _a : '');
1353
- if (i === 0) {
1354
- real_path = seg;
1355
- }
1356
- else {
1357
- seg = eatInner(seg, ['/']);
1358
- real_path = eatOuter(real_path, ['/']);
1359
- real_path = `${real_path}/${seg}`;
1360
- }
1361
- }
1362
- return real_path || '';
1363
- }
1364
1816
  function sanitizeFilename(filename) {
1365
1817
  return filename
1366
1818
  .toLowerCase()
@@ -1370,13 +1822,6 @@ function sanitizeFilename(filename) {
1370
1822
  .replace(/-+/g, '-') // Collapse multiple hyphens into one
1371
1823
  .replace(/^-|-$/, ''); // Remove leading/trailing hyphens
1372
1824
  }
1373
- function get_relative_path(directory, fullPath) {
1374
- return path__namespace$1.relative(directory, fullPath);
1375
- }
1376
- // Safer resolver that strips .. at the front only, but prefer server-side checks.
1377
- function get_safe_path(p) {
1378
- return path__namespace$1.normalize(p).replace(/^(\.\.[/\\])+/, '');
1379
- }
1380
1825
  function make_sanitized_path(...paths) {
1381
1826
  let real_path = '';
1382
1827
  for (let i = 0; i < paths.length; i++) {
@@ -1390,13 +1835,13 @@ function make_sanitized_path(...paths) {
1390
1835
  }
1391
1836
  return real_path || '';
1392
1837
  }
1393
- /** FIXED: your regexes were strings. This correctly joins without duplicate slashes. */
1394
1838
  function normalizeUrl(base, p) {
1395
1839
  if (!p)
1396
- return base.replace(/\/+$/g, '');
1397
- const cleanBase = base.replace(/\/+$/g, '');
1398
- const cleanPath = p.replace(/^\/+/g, '');
1399
- return `${cleanBase}/${cleanPath}`.replace(/([^:])\/{2,}/g, '$1/'); // keep protocol //
1840
+ return base;
1841
+ const cleanBase = base.replace(/\/+$/, ''); // regex literal
1842
+ const cleanPath = p.replace(/^\/+/, '');
1843
+ // collapse multiple “//” into one, but keep the “://” after protocol
1844
+ return `${cleanBase}/${cleanPath}`.replace(/([^:])\/{2,}/g, '$1/');
1400
1845
  }
1401
1846
 
1402
1847
  /**
@@ -1497,7 +1942,32 @@ function alertit(obj = null) {
1497
1942
  }
1498
1943
  alert(msg);
1499
1944
  }
1500
- const alertIt = alertit;
1945
+
1946
+ // take N args and coerce them all to numbers
1947
+ function safeNums(...args) {
1948
+ return args.map(ensure_number);
1949
+ }
1950
+ // divide the first value by each of the following
1951
+ function safeDivide(...args) {
1952
+ const [head, ...rest] = safeNums(...args);
1953
+ // if we don’t have a head or any divisor is zero, bail
1954
+ if (head === 0 || rest.some((d) => d === 0))
1955
+ return 0;
1956
+ return rest.reduce((acc, d) => acc / d, head);
1957
+ }
1958
+ // multiply all the values together
1959
+ function safeMultiply(...args) {
1960
+ const nums = safeNums(...args);
1961
+ // if any number is zero, result is zero
1962
+ if (nums.includes(0))
1963
+ return 0;
1964
+ return nums.reduce((acc, n) => acc * n, 1);
1965
+ }
1966
+ // round a value to two decimals by percent
1967
+ function roundPercentage(x) {
1968
+ const pct = safeMultiply(ensure_number(x), 100);
1969
+ return safeDivide(Math.round(pct), 100);
1970
+ }
1501
1971
 
1502
1972
  function Button(_a) {
1503
1973
  var { children, color = 'gray', variant = 'default', className = '' } = _a, rest = __rest(_a, ["children", "color", "variant", "className"]);
@@ -1535,17 +2005,74 @@ function Spinner() {
1535
2005
  }
1536
2006
 
1537
2007
  // src/functions/config_utils/src/config_utils.ts
1538
- /**
1539
- * Attempt to load config.json if present, otherwise return empty object.
1540
- */
1541
- function getConfigJson() {
1542
- return __awaiter(this, void 0, void 0, function* () {
2008
+ let _cachedConfig = null;
2009
+ function loadConfig() {
2010
+ return __awaiter(this, arguments, void 0, function* (filePath = null) {
2011
+ var _a;
2012
+ if (_cachedConfig) {
2013
+ return _cachedConfig;
2014
+ }
2015
+ // 1) figure out where config.json lives
2016
+ let configUrl;
2017
+ if (filePath) {
2018
+ configUrl = filePath;
2019
+ }
2020
+ else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== 'undefined' && typeof (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) === 'string') {
2021
+ // ES module: resolve relative to this file
2022
+ try {
2023
+ configUrl = new URL('./config.json', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href))).href;
2024
+ }
2025
+ catch (_b) {
2026
+ configUrl = 'config.json';
2027
+ }
2028
+ }
2029
+ else {
2030
+ // browser fallback
2031
+ const baseURI = safeGlobalProp('document', 'baseURI');
2032
+ try {
2033
+ configUrl =
2034
+ typeof baseURI === 'string'
2035
+ ? new URL('config.json', baseURI).href
2036
+ : 'config.json';
2037
+ }
2038
+ catch (_c) {
2039
+ configUrl = 'config.json';
2040
+ }
2041
+ }
2042
+ // 2) if we have a fetch, try HTTP(S)
2043
+ const fetchFn = safeGlobalProp('fetch');
2044
+ if (typeof fetchFn === 'function') {
2045
+ try {
2046
+ const res = yield fetchFn(configUrl);
2047
+ if (res.ok) {
2048
+ const json = yield res.json();
2049
+ // cache & return
2050
+ _cachedConfig = (_a = json) !== null && _a !== void 0 ? _a : {};
2051
+ return _cachedConfig;
2052
+ }
2053
+ }
2054
+ catch (_d) {
2055
+ /* swallow */
2056
+ }
2057
+ }
2058
+ // 3) Node fallback: try reading from disk (requires your readJsonFile util)
1543
2059
  try {
1544
- return (yield readJsonFile('config.json')) || {};
2060
+ const disk = yield readJsonFile(configUrl);
2061
+ _cachedConfig = disk !== null && disk !== void 0 ? disk : {};
2062
+ return _cachedConfig;
1545
2063
  }
1546
- catch (_a) {
1547
- return {};
2064
+ catch (_e) {
2065
+ /* swallow */
1548
2066
  }
2067
+ // 4) if all else fails, return an empty config
2068
+ _cachedConfig = {};
2069
+ return _cachedConfig;
2070
+ });
2071
+ }
2072
+ function getConfig(key) {
2073
+ return __awaiter(this, void 0, void 0, function* () {
2074
+ const cfg = yield loadConfig();
2075
+ return key != null ? cfg[key] : cfg;
1549
2076
  });
1550
2077
  }
1551
2078
 
@@ -1583,102 +2110,6 @@ function get_keyword_string(keywords) {
1583
2110
  return allString;
1584
2111
  }
1585
2112
 
1586
- // take N args and coerce them all to numbers
1587
- function safeNums(...args) {
1588
- return args.map(ensure_number);
1589
- }
1590
- // divide the first value by each of the following
1591
- function safeDivide(...args) {
1592
- const [head, ...rest] = safeNums(...args);
1593
- // if we don’t have a head or any divisor is zero, bail
1594
- if (head === 0 || rest.some((d) => d === 0))
1595
- return 0;
1596
- return rest.reduce((acc, d) => acc / d, head);
1597
- }
1598
- // multiply all the values together
1599
- function safeMultiply(...args) {
1600
- const nums = safeNums(...args);
1601
- // if any number is zero, result is zero
1602
- if (nums.includes(0))
1603
- return 0;
1604
- return nums.reduce((acc, n) => acc * n, 1);
1605
- }
1606
- // round a value to two decimals by percent
1607
- function roundPercentage(x) {
1608
- const pct = safeMultiply(ensure_number(x), 100);
1609
- return safeDivide(Math.round(pct), 100);
1610
- }
1611
-
1612
- // urlTools.ts
1613
- // Minimal, safe encoders/decoders + helpers to build/parse URLs
1614
- /** Encode a single query value/key safely */
1615
- const encode = (v) => encodeURIComponent(String(v !== null && v !== void 0 ? v : ""));
1616
- /** Decode a single query value/key safely (never throws) */
1617
- const decodeSafe = (v) => {
1618
- if (v == null)
1619
- return "";
1620
- try {
1621
- return decodeURIComponent(v);
1622
- }
1623
- catch (_a) {
1624
- // handles bad % sequences or already-decoded strings
1625
- return v;
1626
- }
1627
- };
1628
- /** Decode strings that might be double-encoded (up to 2 passes) */
1629
- const decodeMaybeDouble = (v) => {
1630
- const once = decodeSafe(v);
1631
- const twice = decodeSafe(once);
1632
- return twice.length < once.length ? twice : once;
1633
- };
1634
- /** Convert + to spaces (legacy www-form behavior) then decode */
1635
- const decodeFormComponent = (v) => decodeSafe(v.replace(/\+/g, " "));
1636
- /** Build a URL with query params (skips null/undefined) */
1637
- const buildUrl = (base, params) => {
1638
- const u = new URL(base, typeof window !== "undefined" ? window.location.origin : "http://localhost");
1639
- if (params) {
1640
- for (const [k, val] of Object.entries(params)) {
1641
- if (val === null || val === undefined)
1642
- continue;
1643
- // arrays -> multiple entries
1644
- if (Array.isArray(val)) {
1645
- val.forEach(v => u.searchParams.append(k, String(v)));
1646
- }
1647
- else {
1648
- u.searchParams.set(k, String(val));
1649
- }
1650
- }
1651
- }
1652
- return u.toString();
1653
- };
1654
- /** Parse a query string into an object (first value wins; arrays if repeat=true) */
1655
- const parseQuery = (qs, opts) => {
1656
- var _a;
1657
- const { repeat = false, form = false } = opts || {};
1658
- const out = {};
1659
- const s = qs.startsWith("?") ? qs.slice(1) : qs;
1660
- if (!s)
1661
- return out;
1662
- for (const part of s.split("&")) {
1663
- if (!part)
1664
- continue;
1665
- const [kRaw, vRaw = ""] = part.split("=");
1666
- const K = form ? decodeFormComponent(kRaw) : decodeSafe(kRaw);
1667
- const V = form ? decodeFormComponent(vRaw) : decodeSafe(vRaw);
1668
- if (repeat) {
1669
- ((_a = out[K]) !== null && _a !== void 0 ? _a : (out[K] = [])).push(V);
1670
- }
1671
- else {
1672
- out[K] = V;
1673
- }
1674
- }
1675
- return out;
1676
- };
1677
- /** Quick helper: percent-encode whole strings for placement in URLs */
1678
- const encodeTextForUrl = (text) => encode(text);
1679
- /** Quick helper: decode long blobs coming from share-intents/UTMs */
1680
- const decodeShareBlob = (blob) => decodeMaybeDouble(blob).replace(/\r\n/g, "\n");
1681
-
1682
2113
  Object.defineProperty(exports, "useCallback", {
1683
2114
  enumerable: true,
1684
2115
  get: function () { return react.useCallback; }
@@ -1708,7 +2139,6 @@ exports.PROD_PREFIX = PROD_PREFIX;
1708
2139
  exports.PROTOCOL = PROTOCOL;
1709
2140
  exports.SUB_DIR = SUB_DIR;
1710
2141
  exports.Spinner = Spinner;
1711
- exports.alertIt = alertIt;
1712
2142
  exports.alertit = alertit;
1713
2143
  exports.assureArray = assureArray;
1714
2144
  exports.assureList = assureList;
@@ -1718,11 +2148,8 @@ exports.assure_array = assure_array;
1718
2148
  exports.assure_list = assure_list;
1719
2149
  exports.assure_number = assure_number;
1720
2150
  exports.assure_string = assure_string;
1721
- exports.buildUrl = buildUrl;
1722
2151
  exports.callStorage = callStorage;
1723
2152
  exports.callWindowMethod = callWindowMethod;
1724
- exports.capitalize = capitalize;
1725
- exports.capitalize_str = capitalize_str;
1726
2153
  exports.checkResponse = checkResponse;
1727
2154
  exports.cleanArray = cleanArray;
1728
2155
  exports.cleanText = cleanText;
@@ -1731,17 +2158,11 @@ exports.confirm_type = confirm_type;
1731
2158
  exports.create_list_string = create_list_string;
1732
2159
  exports.currentUsername = currentUsername;
1733
2160
  exports.currentUsernames = currentUsernames;
1734
- exports.decodeFormComponent = decodeFormComponent;
1735
2161
  exports.decodeJwt = decodeJwt;
1736
- exports.decodeMaybeDouble = decodeMaybeDouble;
1737
- exports.decodeSafe = decodeSafe;
1738
- exports.decodeShareBlob = decodeShareBlob;
1739
2162
  exports.eatAll = eatAll;
1740
2163
  exports.eatEnd = eatEnd;
1741
2164
  exports.eatInner = eatInner;
1742
2165
  exports.eatOuter = eatOuter;
1743
- exports.encode = encode;
1744
- exports.encodeTextForUrl = encodeTextForUrl;
1745
2166
  exports.ensureArray = ensureArray;
1746
2167
  exports.ensureList = ensureList;
1747
2168
  exports.ensureNumber = ensureNumber;
@@ -1777,8 +2198,8 @@ exports.getBody = getBody;
1777
2198
  exports.getChar = getChar;
1778
2199
  exports.getCleanArray = getCleanArray;
1779
2200
  exports.getComponentsUtilsDirectory = getComponentsUtilsDirectory;
2201
+ exports.getConfig = getConfig;
1780
2202
  exports.getConfigContent = getConfigContent;
1781
- exports.getConfigJson = getConfigJson;
1782
2203
  exports.getConfigVar = getConfigVar;
1783
2204
  exports.getDbConfigsPath = getDbConfigsPath;
1784
2205
  exports.getDistDir = getDistDir;
@@ -1821,9 +2242,6 @@ exports.get_keyword_string = get_keyword_string;
1821
2242
  exports.get_media_exts = get_media_exts;
1822
2243
  exports.get_media_map = get_media_map;
1823
2244
  exports.get_mime_type = get_mime_type;
1824
- exports.get_relative_path = get_relative_path;
1825
- exports.get_result = get_result;
1826
- exports.get_safe_path = get_safe_path;
1827
2245
  exports.get_splitext = get_splitext;
1828
2246
  exports.get_window = get_window;
1829
2247
  exports.get_window_location = get_window_location;
@@ -1836,16 +2254,14 @@ exports.isStrInString = isStrInString;
1836
2254
  exports.isTokenExpired = isTokenExpired;
1837
2255
  exports.isType = isType;
1838
2256
  exports.is_media_type = is_media_type;
1839
- exports.makePath = makePath;
2257
+ exports.loadConfig = loadConfig;
1840
2258
  exports.make_path = make_path;
1841
2259
  exports.make_sanitized_path = make_sanitized_path;
1842
2260
  exports.normalizeUrl = normalizeUrl;
1843
- exports.parseQuery = parseQuery;
1844
2261
  exports.parseResult = parseResult;
1845
2262
  exports.path_to_url = path_to_url;
1846
2263
  exports.processKeywords = processKeywords;
1847
2264
  exports.readJsonFile = readJsonFile;
1848
- exports.removeToken = removeToken;
1849
2265
  exports.requireToken = requireToken;
1850
2266
  exports.roundPercentage = roundPercentage;
1851
2267
  exports.safeDivide = safeDivide;