@putkoff/abstract-utilities 1.0.131 → 1.0.134

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.
@@ -0,0 +1,1863 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var safe_storage = require('./safe_storage-BSCV5flZ.js');
5
+ var fs = require('node:fs');
6
+ var path$1 = require('node:path');
7
+ var util = require('util');
8
+
9
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
+ const PROTOCOL = 'https://';
11
+ const DOMAIN_NAME = 'abstractendeavors';
12
+ const BASE_URL = `${PROTOCOL}${DOMAIN_NAME}.com`;
13
+ const SUB_DIR = 'secure-files';
14
+ const PROD_PREFIX = `/${SUB_DIR}/`;
15
+ const API_PREFIX = `/${SUB_DIR}/api`;
16
+ const DEV_PREFIX = `/${SUB_DIR}-dev/`;
17
+
18
+ function get_window() {
19
+ try {
20
+ if (typeof window !== 'undefined') {
21
+ return window;
22
+ }
23
+ }
24
+ catch (err) {
25
+ alert(err);
26
+ }
27
+ return null;
28
+ }
29
+ function get_window_location() {
30
+ try {
31
+ const Window = get_window();
32
+ if (!Window) {
33
+ return BASE_URL;
34
+ }
35
+ return Window.location;
36
+ }
37
+ catch (err) {
38
+ alert(err);
39
+ }
40
+ return null;
41
+ }
42
+ function get_window_pathname() {
43
+ try {
44
+ const Window = get_window();
45
+ if (!Window) {
46
+ return DEV_PREFIX;
47
+ }
48
+ return Window.location.pathname;
49
+ }
50
+ catch (err) {
51
+ alert(err);
52
+ }
53
+ return null;
54
+ }
55
+ function get_window_parts() {
56
+ try {
57
+ return get_window_location();
58
+ }
59
+ catch (err) {
60
+ alert(err);
61
+ }
62
+ return null;
63
+ }
64
+
65
+ /**
66
+ * Unwraps nested { result } fields until you hit a non-object or no more "result" keys.
67
+ */
68
+ function getResult(obj) {
69
+ let current = obj;
70
+ while (current &&
71
+ typeof current === "object" &&
72
+ Object.prototype.hasOwnProperty.call(current, "result")) {
73
+ current = current.result;
74
+ }
75
+ return current;
76
+ }
77
+ // Determines HTTP method, defaults to GET or POST based on body
78
+ function getMethod(method = null, body = null) {
79
+ const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'PULL'];
80
+ method = (method || '').toUpperCase();
81
+ if (!validMethods.includes(method)) {
82
+ method = body ? 'POST' : 'GET';
83
+ }
84
+ return method;
85
+ }
86
+ // Gets headers, skips JSON headers when body is FormData
87
+ function getHeaders(headers = {}, method = null, body = null) {
88
+ const result = { ...headers };
89
+ // let browser set boundary
90
+ if (body instanceof FormData) {
91
+ return result;
92
+ }
93
+ const upper = method?.toUpperCase();
94
+ if (['POST', 'PUT', 'PATCH'].includes(upper ?? '') &&
95
+ !result['Content-Type']) {
96
+ result['Content-Type'] = 'application/json';
97
+ }
98
+ return result;
99
+ }
100
+ // Prepares request body, serializes to JSON for non-GET requests
101
+ function getBody(body = null, method = null) {
102
+ method = getMethod(method, body);
103
+ if (method === 'GET') {
104
+ return undefined;
105
+ }
106
+ if (body) {
107
+ try {
108
+ return JSON.stringify(body);
109
+ }
110
+ catch (err) {
111
+ return body;
112
+ }
113
+ }
114
+ return undefined;
115
+ }
116
+ // Prepares fetch variables, passes FormData intact
117
+ function getFetchVars(headers = null, method = null, body = null) {
118
+ method = getMethod(method, body);
119
+ headers = getHeaders(headers || {}, method, body);
120
+ // only JSON-stringify non-FormData bodies
121
+ if (!(body instanceof FormData)) {
122
+ body = getBody(body, method);
123
+ }
124
+ return { method, headers, body };
125
+ }
126
+ /*
127
+ * parseResult no longer needs to worry about JSON vs HTML redirect errors;
128
+ * all 401/403 have already been handled above.
129
+ */
130
+ async function parseResult(res) {
131
+ // runs checkResponse first, will throw if session is expired
132
+ res = checkResponse(res);
133
+ if (!res.ok) {
134
+ // for any other non-401 errors, you can still surface them
135
+ const errorText = await res.text();
136
+ throw new Error(errorText || res.statusText);
137
+ }
138
+ // now safely parse JSON
139
+ return res.json();
140
+ }
141
+ /**
142
+ * Intercept 401/403 and force a clean redirect to login
143
+ * without ever showing an alert.
144
+ */
145
+ function checkResponse(res) {
146
+ if (res.status === 401 || res.status === 403) {
147
+ // 1) clear out the stale token
148
+ localStorage.removeItem("token");
149
+ // 2) replace history so "back" doesn’t re-trigger the protected route
150
+ window.history.replaceState({}, "", "/secure-files");
151
+ // 3) short-circuit all further fetch logic
152
+ throw new Error("SessionExpired");
153
+ }
154
+ return res;
155
+ }
156
+
157
+ async function fetchIt(endpoint, body = null, method = null, headers = null, blob = false, configUrl = false, withCredentials = true, returnJson = true, returnReult = true) {
158
+ method = (method || "GET").toUpperCase();
159
+ // 2) choose the URL
160
+ const url = endpoint;
161
+ // 3) prepare headers & body
162
+ headers = {
163
+ ...(body instanceof FormData ? {} : { "Content-Type": "application/json" }),
164
+ ...headers,
165
+ };
166
+ const opts = {
167
+ method,
168
+ credentials: withCredentials ? "include" : "same-origin",
169
+ headers,
170
+ body: body instanceof FormData
171
+ ? body
172
+ : body != null && method !== "GET"
173
+ ? JSON.stringify(body)
174
+ : undefined,
175
+ };
176
+ console.debug("➡️ secureFetchIt →", url, opts);
177
+ const res = await fetch(url, opts);
178
+ if (!res.ok) {
179
+ const err = await res.text();
180
+ throw new Error(`HTTP ${res.status}: ${err}`);
181
+ }
182
+ if (blob)
183
+ return res.blob();
184
+ if (returnReult)
185
+ return getResult(res.json());
186
+ if (returnJson)
187
+ return res.json();
188
+ return res;
189
+ }
190
+ // Constructs HTML directory path
191
+ function getHtmlDirectory(directory, filename) {
192
+ return `${directory}/${filename}.html`;
193
+ }
194
+ // Fetches HTML content
195
+ async function fetchIndexHtml(filename, directory = 'sf_index', base = 'html') {
196
+ const url = `/${base}/${directory}/${filename}.html`;
197
+ const response = await fetch(url);
198
+ return await response.text();
199
+ }
200
+ // Fetches and injects HTML content into container
201
+ async function fetchIndexHtmlContainer(filename, doc = document, directory = 'html') {
202
+ const container = `${filename}-container`;
203
+ const html = await fetchIndexHtml(filename, directory);
204
+ const el = doc.getElementById(container);
205
+ if (el) {
206
+ el.innerHTML = html;
207
+ }
208
+ else {
209
+ console.warn(`⚠️ No container found for: #${container}`);
210
+ }
211
+ }
212
+
213
+ function urlJoin(...parts) {
214
+ const s = (parts.length === 1 && Array.isArray(parts[0]) ? parts[0] : parts);
215
+ let r = "";
216
+ for (let i = 0; i < s.length; i++) {
217
+ let d = (s[i] ?? "").toString();
218
+ if (!d)
219
+ continue;
220
+ if (i === 0)
221
+ r = d;
222
+ else {
223
+ d = d.replace(/^\/+/, "");
224
+ r = r.replace(/\/+$/, "");
225
+ r = `${r}/${d}`;
226
+ }
227
+ }
228
+ return r;
229
+ }
230
+ /**
231
+ * Returns a full URL.
232
+ * If partial_url is already absolute (starts with http), it is returned as is.
233
+ * Otherwise, it is combined with the base URL.
234
+ */
235
+ function get_full_url(partial_url, domain = null) {
236
+ if (typeof partial_url !== 'string') {
237
+ throw new Error('partial_url must be a string');
238
+ }
239
+ // If it already starts with http, assume it is absolute.
240
+ if (partial_url.startsWith('http')) {
241
+ return partial_url;
242
+ }
243
+ return urlJoin(domain, partial_url);
244
+ }
245
+ /**
246
+ * Returns a full file system path.
247
+ * If partial_path is already absolute, it is returned as is.
248
+ * Otherwise, it is joined with the base directory.
249
+ */
250
+ function get_full_path(partial_path, parent_dir = null) {
251
+ if (typeof partial_path !== 'string') {
252
+ throw new Error('partial_path must be a string');
253
+ }
254
+ if (path.isAbsolute(partial_path)) {
255
+ return partial_path;
256
+ }
257
+ return urlJoin(parent_dir, partial_path);
258
+ }
259
+ /**
260
+ * Converts a local file system path into its corresponding URL.
261
+ * It checks against the known directories in all_paths and replaces the matching base.
262
+ */
263
+ function path_to_url(filePath, all_paths) {
264
+ if (typeof filePath !== 'string') {
265
+ throw new Error('filePath must be a string');
266
+ }
267
+ for (const key in all_paths) {
268
+ const mapping = all_paths[key];
269
+ const normalizedBase = path.normalize(mapping.path);
270
+ if (filePath.startsWith(normalizedBase)) {
271
+ const relativePath = filePath.substring(normalizedBase.length);
272
+ return urlJoin(mapping.url, relativePath.replace(/\\/g, '/'));
273
+ }
274
+ }
275
+ return null;
276
+ }
277
+ /**
278
+ * Converts a URL into its corresponding local file system path.
279
+ * It checks against the known URL prefixes in all_paths and replaces the matching base.
280
+ */
281
+ function url_to_path(urlStr, all_paths) {
282
+ if (typeof urlStr !== 'string') {
283
+ throw new Error('urlStr must be a string');
284
+ }
285
+ for (const key in all_paths) {
286
+ const mapping = all_paths[key];
287
+ if (urlStr.startsWith(mapping.url)) {
288
+ const relativeUrl = urlStr.substring(mapping.url.length);
289
+ return urlJoin(mapping.path, relativeUrl);
290
+ }
291
+ }
292
+ return null;
293
+ }
294
+ function urljoin(...parts) {
295
+ return urlJoin(...parts);
296
+ }
297
+
298
+ function split_outside_brackets(s) {
299
+ let depth = 0;
300
+ let start = 0;
301
+ const out = [];
302
+ for (let i = 0; i < s.length; i++) {
303
+ const c = s[i];
304
+ if (c === "[")
305
+ depth++;
306
+ else if (c === "]")
307
+ depth--;
308
+ // split only when NOT inside brackets
309
+ if (c === "," && depth === 0) {
310
+ out.push(s.slice(start, i));
311
+ start = i + 1;
312
+ }
313
+ }
314
+ out.push(s.slice(start));
315
+ return out;
316
+ }
317
+ function parse_nested_list(s) {
318
+ // strip outer brackets
319
+ const inner = s.slice(1, -1).trim();
320
+ const parts = split_outside_brackets(inner);
321
+ const result = [];
322
+ for (let p of parts) {
323
+ p = p.trim();
324
+ if (p.startsWith("[") && p.endsWith("]")) {
325
+ // recursively parse nested list
326
+ result.push(parse_nested_list(p));
327
+ }
328
+ else {
329
+ result.push(p);
330
+ }
331
+ }
332
+ return result;
333
+ }
334
+
335
+ function ensure_list(obj) {
336
+ if (obj == null)
337
+ return [];
338
+ if (Array.isArray(obj)) {
339
+ return obj.flatMap(item => ensure_list(item));
340
+ }
341
+ const s = String(obj).trim();
342
+ if (s.startsWith("[") && s.endsWith("]")) {
343
+ return parse_nested_list(s);
344
+ }
345
+ return split_outside_brackets(s).map(x => x.trim());
346
+ }
347
+ // coerce any single value into a number (0 if it can't)
348
+ function ensure_number(x) {
349
+ const n = Number(x);
350
+ return isNaN(n) ? 0 : n;
351
+ }
352
+ function ensure_string(obj) {
353
+ return String(obj);
354
+ }
355
+ function ensurelist(obj) {
356
+ return ensure_list(obj);
357
+ }
358
+ function assureList(obj) {
359
+ return ensure_list(obj);
360
+ }
361
+ function assure_list(obj) {
362
+ return ensure_list(obj);
363
+ }
364
+ function ensureList(obj) {
365
+ return ensure_list(obj);
366
+ }
367
+ function assurelist(obj) {
368
+ return ensure_list(obj);
369
+ }
370
+ function ensurenumber(x) {
371
+ return ensure_number(x);
372
+ }
373
+ function assureNumber(x) {
374
+ return ensure_number(x);
375
+ }
376
+ function ensureNumber(x) {
377
+ return ensure_number(x);
378
+ }
379
+ function assurenumber(x) {
380
+ return ensure_number(x);
381
+ }
382
+ function assure_number(x) {
383
+ return ensure_number(x);
384
+ }
385
+ function ensurestring(obj) {
386
+ return ensure_string(obj);
387
+ }
388
+ function ensureString(obj) {
389
+ return ensure_string(obj);
390
+ }
391
+ function assureString(obj) {
392
+ return ensure_string(obj);
393
+ }
394
+ function assurestring(obj) {
395
+ return ensure_string(obj);
396
+ }
397
+ function assure_string(obj) {
398
+ return ensure_string(obj);
399
+ }
400
+ function assurearray(obj) {
401
+ return ensure_list(obj);
402
+ }
403
+ function ensurearray(obj) {
404
+ return ensure_list(obj);
405
+ }
406
+ function ensure_array(obj) {
407
+ return ensure_list(obj);
408
+ }
409
+ function ensureArray(obj) {
410
+ return ensure_list(obj);
411
+ }
412
+ function assure_array(obj) {
413
+ return ensure_list(obj);
414
+ }
415
+ function assureArray(obj) {
416
+ return ensure_list(obj);
417
+ }
418
+
419
+ function cleanText(input) {
420
+ // Replace delimiters with spaces and split
421
+ const str = ensure_string(input);
422
+ const words = str.replace(/[_.-]/g, ' '); // Replace _, -, . with space
423
+ return words;
424
+ }
425
+ function cleanArray(obj) {
426
+ obj = ensure_array(obj);
427
+ return Array.from(new Set(obj));
428
+ }
429
+ function getCleanArray(obj) {
430
+ obj = obj.split(/\s+/) // Split on any whitespace
431
+ .filter((item) => typeof item === 'string' && item !== '');
432
+ // Get basename
433
+ // Remove duplicates using Set
434
+ const uniqueWords = cleanArray(obj);
435
+ return uniqueWords;
436
+ }
437
+ // Cache a formatter instance for slightly better performance
438
+ const US_DECIMAL_FORMATTER = new Intl.NumberFormat('en-US', {
439
+ minimumFractionDigits: 2,
440
+ maximumFractionDigits: 2,
441
+ });
442
+ function formatNumber(value) {
443
+ try {
444
+ // coerce to number
445
+ const num = Number(value);
446
+ // if it's NaN or infinite, bail out
447
+ if (!isFinite(num))
448
+ return value;
449
+ return US_DECIMAL_FORMATTER.format(num);
450
+ }
451
+ catch {
452
+ // if anything goes wrong, return the original
453
+ return value;
454
+ }
455
+ }
456
+
457
+ // Constrain T so 'in obj' is allowed
458
+ function get_key_value(obj, key) {
459
+ // we cast to any for the indexing, since TS can’t infer arbitrary string keys
460
+ if (key in obj && obj[key] != null) {
461
+ return obj[key];
462
+ }
463
+ return null;
464
+ }
465
+ function get(obj, keys, defaultValue = null) {
466
+ const keyArray = ensure_array(keys);
467
+ if (!obj || keyArray.length === 0) {
468
+ return defaultValue;
469
+ }
470
+ for (const key of keyArray) {
471
+ const val = get_key_value(obj, key);
472
+ if (val != null) {
473
+ return val;
474
+ }
475
+ }
476
+ return defaultValue;
477
+ }
478
+ // Create the accountInfo table if it doesn't already exist
479
+ function findKeyValue(obj, keyToFind) {
480
+ if (keyToFind in obj)
481
+ return obj[keyToFind];
482
+ for (const key in obj) {
483
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
484
+ const result = findKeyValue(obj[key], keyToFind);
485
+ if (result !== undefined)
486
+ return result;
487
+ }
488
+ }
489
+ return undefined;
490
+ }
491
+ function omitKeys(obj, ...keys) {
492
+ const newObj = { ...obj };
493
+ keys.forEach(key => {
494
+ delete newObj[key];
495
+ });
496
+ return newObj;
497
+ }
498
+ /**
499
+ * Extracts necessary properties from the insertValue to prevent circular references.
500
+ *
501
+ * @param insertValue - The original RPC result.
502
+ * @returns A new object with only the required properties.
503
+ */
504
+ function extractInsertData(insertValue) {
505
+ // Example: Suppose you only need certain fields from the transaction
506
+ // Modify this function based on your actual data structure
507
+ if (insertValue && typeof insertValue === 'object') {
508
+ const { transaction, ...rest } = insertValue; // Exclude 'transaction' property
509
+ return rest;
510
+ }
511
+ return insertValue;
512
+ }
513
+ // Recursive function to load nested JSON
514
+ function loadInnerJson(data) {
515
+ if (typeof data === 'string') {
516
+ try {
517
+ const parsed = JSON.parse(data);
518
+ return loadInnerJson(parsed);
519
+ }
520
+ catch (e) {
521
+ return data;
522
+ }
523
+ }
524
+ else if (Array.isArray(data)) {
525
+ return data.map(item => loadInnerJson(item));
526
+ }
527
+ else if (typeof data === 'object' && data !== null) {
528
+ const result = {};
529
+ for (const key in data) {
530
+ if (data.hasOwnProperty(key)) {
531
+ result[key] = loadInnerJson(data[key]);
532
+ }
533
+ }
534
+ return result;
535
+ }
536
+ return data;
537
+ }
538
+
539
+ function isType(obj, type) {
540
+ if (typeof obj === type) {
541
+ return true;
542
+ }
543
+ return false;
544
+ }
545
+ function isStrInString(obj, string) {
546
+ const obj_str = ensure_string(obj).toLowerCase;
547
+ string = ensure_string(string).toLowerCase;
548
+ if (string.includes(obj_str)) {
549
+ return true;
550
+ }
551
+ return false;
552
+ }
553
+ function getChar(i, string) {
554
+ if (string.length >= i) {
555
+ return ensure_string(string)[i];
556
+ }
557
+ }
558
+ function getAlphaNum(obj) {
559
+ const is_num = isNum(obj);
560
+ const alphas = getAlphas();
561
+ if (is_num) {
562
+ return getChar(obj, alphas);
563
+ }
564
+ if (isStrInString(obj, alphas)) {
565
+ return getChar(obj, alphas);
566
+ }
567
+ }
568
+ function getNums() {
569
+ return '0123456789';
570
+ }
571
+ function isNum(obj) {
572
+ return !Number.isNaN(Number(obj));
573
+ }
574
+ function getAlphas() {
575
+ return 'abcdefghijklmnopqrstuvwxyz';
576
+ }
577
+
578
+ // Function to handle undefined or null values
579
+ function getIfNone(obj, fallback) {
580
+ return obj !== undefined && obj !== null && obj !== '' ? obj : fallback;
581
+ }
582
+ /**
583
+ * Merges non-null values from multiple dictionaries.
584
+ */
585
+ function mergeNotNullValues(dictA, dictB, dictC, dictD, dictE) {
586
+ const result = {};
587
+ for (const key of Object.keys(dictA)) {
588
+ result[key] = dictA[key] ?? dictB?.[key] ?? dictC?.[key] ?? dictD?.[key] ?? dictE?.[key];
589
+ }
590
+ return result;
591
+ }
592
+ /**
593
+ * Converts an empty object to null.
594
+ */
595
+ function emptyObjectToNull(value) {
596
+ return value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0 ? null : value;
597
+ }
598
+
599
+ function getSubstring(obj, maxLength = null, minLength = null) {
600
+ const objLength = obj.length;
601
+ const effectiveMaxLength = maxLength ?? objLength; // Use nullish coalescing for clarity
602
+ const effectiveMinLength = minLength ?? 0;
603
+ // Ensure bounds are valid
604
+ const clampedMaxLength = Math.min(Math.max(effectiveMaxLength, 0), objLength);
605
+ const clampedMinLength = Math.min(Math.max(effectiveMinLength, 0), objLength);
606
+ // If minLength exceeds maxLength, return empty string or adjust logic as needed
607
+ if (clampedMinLength >= clampedMaxLength) {
608
+ return '';
609
+ }
610
+ return obj.substring(clampedMinLength, clampedMaxLength);
611
+ }
612
+ /**
613
+ * Sanitize a string by removing null bytes and trimming whitespace.
614
+ */
615
+ function sanitizeString(input) {
616
+ if (!input)
617
+ return input;
618
+ return input.replace(/\u0000/g, "").trim(); // Remove null bytes and whitespace
619
+ }
620
+ function truncateString(obj, maxLength = 20) {
621
+ const objLength = obj.length;
622
+ if (objLength > maxLength && maxLength) {
623
+ obj = getSubstring(obj, maxLength) + '...';
624
+ }
625
+ return obj;
626
+ }
627
+ function capitalize_str(string) {
628
+ string = assureString(string);
629
+ const string_len = string.length;
630
+ let init_char = string.toUpperCase();
631
+ if (string_len > 0) {
632
+ init_char = string[0].toUpperCase();
633
+ }
634
+ let rest_chars = '';
635
+ if (string_len > 1) {
636
+ rest_chars = string.slice(1).toLowerCase();
637
+ }
638
+ const fin_chars = `${init_char}${rest_chars}`;
639
+ return fin_chars;
640
+ }
641
+ function capitalize(string) {
642
+ let nu_string = '';
643
+ string = assureString(string);
644
+ const objs = string.replace('-', '_').split('_');
645
+ for (const obj of objs) {
646
+ const str_obj = capitalize_str(obj);
647
+ nu_string = `${nu_string} ${str_obj}`;
648
+ }
649
+ return eatAll(nu_string, [' ']);
650
+ }
651
+ // string_utils/src/string_utils.ts
652
+ function stripPrefixes(str, bases = []) {
653
+ /* NEW: coerce whatever arrives into a string */
654
+ str = String(str);
655
+ const prefixes = (Array.isArray(bases) ? bases : [bases])
656
+ .filter(Boolean)
657
+ .sort((a, b) => b.length - a.length); // longest first
658
+ let changed = true;
659
+ while (changed) {
660
+ changed = false;
661
+ for (const prefix of prefixes) {
662
+ if (str.startsWith(prefix)) {
663
+ str = str.slice(prefix.length);
664
+ changed = true;
665
+ break; // restart from longest prefix
666
+ }
667
+ }
668
+ }
669
+ return str;
670
+ }
671
+ function tryEatPrefix(str, length, ...objs) {
672
+ str = String(str);
673
+ objs = ensure_list(objs);
674
+ const prefix = str.slice(0, length);
675
+ if (length < 0) {
676
+ const start = str.length + length;
677
+ const actualPrefix = str.slice(start);
678
+ return objs.includes(actualPrefix) ? [str.slice(0, start), true] : [str, false];
679
+ }
680
+ if (objs.includes(prefix)) {
681
+ return [str.slice(length), true];
682
+ }
683
+ return [str, false];
684
+ }
685
+ /** Python-equivalent eatInner */
686
+ function eatInner(str, listObjects) {
687
+ str = String(str);
688
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
689
+ // Keep removing from left while leftmost char is in the set
690
+ while (str.length > 0 && chars.includes(str[0])) {
691
+ str = str.slice(1);
692
+ }
693
+ return str;
694
+ }
695
+ /** Python-equivalent eatOuter */
696
+ function eatOuter(str, listObjects) {
697
+ str = String(str);
698
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
699
+ if (!str || chars.length === 0)
700
+ return str;
701
+ for (let i = 0; i < str.length; i++) {
702
+ if (!str)
703
+ return str;
704
+ const last = str[str.length - 1];
705
+ if (!chars.includes(last)) {
706
+ return str;
707
+ }
708
+ str = str.slice(0, -1);
709
+ }
710
+ return str;
711
+ }
712
+ /** Python-equivalent eatAll */
713
+ function eatAll(str, listObjects) {
714
+ str = String(str);
715
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
716
+ str = eatInner(str, chars);
717
+ str = eatOuter(str, chars);
718
+ return str;
719
+ }
720
+ // Plug in the actual version from your project
721
+ function get_alpha_ints(opts) {
722
+ // REPLACE WITH YOUR REAL IMPLEMENTATION
723
+ return [];
724
+ }
725
+ /** Python-equivalent eatElse */
726
+ function eatElse(stringObj, chars, ints = true, alpha = true, lower = true, capitalize = true, string = true, listObj = true) {
727
+ stringObj = String(stringObj);
728
+ const alphaInts = get_alpha_ints();
729
+ const ls = ensure_list(chars || []).concat(alphaInts);
730
+ while (true) {
731
+ if (!stringObj)
732
+ return stringObj;
733
+ const startOk = !ls.includes(stringObj[0]);
734
+ const endOk = !ls.includes(stringObj[stringObj.length - 1]);
735
+ const shouldEat = startOk || endOk;
736
+ if (!shouldEat)
737
+ return stringObj;
738
+ if (stringObj && startOk) {
739
+ stringObj = stringObj.length === 1 ? "" : stringObj.slice(1);
740
+ }
741
+ if (stringObj && endOk) {
742
+ stringObj = stringObj.length === 1 ? "" : stringObj.slice(0, -1);
743
+ }
744
+ }
745
+ }
746
+ function tryParse(obj) {
747
+ try {
748
+ obj = JSON.stringify(obj);
749
+ }
750
+ catch (err) {
751
+ try {
752
+ obj = JSON.parse(obj);
753
+ }
754
+ catch (err) {
755
+ }
756
+ }
757
+ return obj;
758
+ }
759
+ function create_list_string(array_obj) {
760
+ let string = '';
761
+ for (const obj in array_obj) {
762
+ const array_value = array_obj[obj];
763
+ const parsed_value = tryParse(array_value);
764
+ string += `${obj} == ${parsed_value}\n`;
765
+ }
766
+ return string;
767
+ }
768
+ function eatall(str, listObjects) {
769
+ return eatAll(str, listObjects);
770
+ }
771
+ function eatinner(str, listObjects) {
772
+ return eatInner(str, listObjects);
773
+ }
774
+ function eatouter(str, listObjects) {
775
+ return eatOuter(str, listObjects);
776
+ }
777
+
778
+ /**
779
+ * Checks if a value is enclosed in quotes.
780
+ */
781
+ function ends_in_quotes(value) {
782
+ if (typeof value === 'string') {
783
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
784
+ return true;
785
+ }
786
+ }
787
+ return false;
788
+ }
789
+ function stripQuotes(value) {
790
+ if (ends_in_quotes(value)) {
791
+ return value.slice(1, -1); // Remove the first and last characters
792
+ }
793
+ return value; // Return the input unchanged for all other cases
794
+ }
795
+
796
+ /**
797
+ * In the browser we already have a WHATWG URL constructor on window.
798
+ * Here we re-export it as “url” so other modules can import it.
799
+ */
800
+ /**
801
+ * Minimal fileURLToPath implementation for browser-side code.
802
+ * If you only ever need to strip off “file://” in development, this is enough.
803
+ */
804
+ function fileURLToPath(fileUrl) {
805
+ // e.g. fileUrl = "file:///Users/foo/bar.txt"
806
+ try {
807
+ const u = new URL(fileUrl);
808
+ return u.pathname;
809
+ }
810
+ catch {
811
+ // fallback: just strip file://
812
+ return fileUrl.replace(/^file:\/\//, '');
813
+ }
814
+ }
815
+ function getAbsolutePath() {
816
+ return fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('print_utils-Dsre-F_V.js', document.baseURI).href)));
817
+ }
818
+
819
+ function get_dirname(filePath) {
820
+ if (!filePath)
821
+ return '';
822
+ return safe_storage.path.dirname(filePath);
823
+ }
824
+ function get_basename(filePath) {
825
+ if (!filePath)
826
+ return '';
827
+ return safe_storage.path.basename(filePath);
828
+ }
829
+ function get_filename(filePath) {
830
+ if (!filePath)
831
+ return '';
832
+ const ext = safe_storage.path.extname(filePath);
833
+ return safe_storage.path.basename(filePath, ext);
834
+ }
835
+ function get_extname(filePath) {
836
+ if (!filePath)
837
+ return '';
838
+ return safe_storage.path.extname(filePath);
839
+ }
840
+ function get_splitext(filePath) {
841
+ if (!filePath)
842
+ return { filename: '', extname: '' };
843
+ const ext = safe_storage.path.extname(filePath);
844
+ // Get the basename without the extension
845
+ const filename = safe_storage.path.basename(filePath, ext);
846
+ return { filename, ext };
847
+ }
848
+ /**
849
+ * Returns the path of `targetPath` relative to `basePath`.
850
+ * Normalizes separators for consistent web and server environments.
851
+ *
852
+ * @param basePath - The base directory you want to compare from.
853
+ * @param targetPath - The full path of the file/directory.
854
+ * @returns A normalized relative path (e.g., "subdir/file.txt").
855
+ */
856
+ function get_relative_path(basePath, targetPath) {
857
+ try {
858
+ // Compute the relative path using Node's native path.relative
859
+ let rel = safe_storage.path.relative(basePath, targetPath);
860
+ // Normalize to POSIX-style slashes for consistency (especially on Windows)
861
+ rel = rel.split(safe_storage.path.sep).join('/');
862
+ // Avoid empty string (happens if both paths are identical)
863
+ return rel || '.';
864
+ }
865
+ catch (err) {
866
+ console.error(`[get_relative_path] Error computing relative path`, err);
867
+ return targetPath;
868
+ }
869
+ }
870
+ /**
871
+ * Join multiple path segments — clean, predictable, bulletproof.
872
+ *
873
+ * Accepts ANYTHING that ensure_list can handle:
874
+ * • 'a,b,c'
875
+ * • ['a', 'b,c']
876
+ * • 'a/b/c'
877
+ * • '/a/', 'b//c'
878
+ * • mixed arrays, comma strings, whatever
879
+ *
880
+ * Always returns a clean POSIX path string. Never a list.
881
+ */
882
+ function make_path(...parts) {
883
+ // Normalize incoming segments into a flat list
884
+ const segments = ensure_list(parts).map(x => String(x));
885
+ let out = "";
886
+ for (let i = 0; i < segments.length; i++) {
887
+ const seg = segments[i];
888
+ // Normalize a segment:
889
+ let cleaned = eatOuter(seg, "/"); // trim trailing slashes
890
+ if (!cleaned)
891
+ continue;
892
+ if (out === "") {
893
+ out = cleaned;
894
+ }
895
+ else {
896
+ cleaned = eatInner(cleaned, "/"); // trim leading slashes
897
+ out = `${out}/${cleaned}`;
898
+ }
899
+ }
900
+ return out;
901
+ }
902
+ function sanitizeFilename(filename) {
903
+ return filename
904
+ .toLowerCase()
905
+ .replace(/\s+|-/g, '-') // Replace spaces and hyphens with single hyphen
906
+ .replace(/_/g, '-') // Replace underscores with hyphens
907
+ .replace(/[^a-z0-9-.]/g, '') // Remove all non-alphanumeric chars except hyphen and dot
908
+ .replace(/-+/g, '-') // Collapse multiple hyphens into one
909
+ .replace(/^-|-$/, ''); // Remove leading/trailing hyphens
910
+ }
911
+ function make_sanitized_path(...paths) {
912
+ let real_path = '';
913
+ for (let i = 0; i < paths.length; i++) {
914
+ const sanitized = sanitizeFilename(eatOuter(paths[i], '/'));
915
+ if (i === 0) {
916
+ real_path = sanitized;
917
+ }
918
+ else if (sanitized) { // Only append if there's a non-empty segment
919
+ real_path = `${real_path}/${sanitized}`;
920
+ }
921
+ }
922
+ return real_path || '';
923
+ }
924
+ function normalizeUrl(base, p) {
925
+ if (!p)
926
+ return base;
927
+ const cleanBase = base.replace(/\/+$/, ''); // regex literal
928
+ const cleanPath = p.replace(/^\/+/, '');
929
+ // collapse multiple “//” into one, but keep the “://” after protocol
930
+ return `${cleanBase}/${cleanPath}`.replace(/([^:])\/{2,}/g, '$1/');
931
+ }
932
+ function pathjoin(...parts) {
933
+ return make_path(...parts);
934
+ }
935
+ function pathJoin(...parts) {
936
+ return make_path(...parts);
937
+ }
938
+ function makepath(...parts) {
939
+ return make_path(...parts);
940
+ }
941
+ function makePath(...parts) {
942
+ return make_path(...parts);
943
+ }
944
+ function path_join(...parts) {
945
+ return make_path(...parts);
946
+ }
947
+ function getSplitext(filePath) {
948
+ return get_splitext(filePath);
949
+ }
950
+ function getsplitext(filePath) {
951
+ return get_splitext(filePath);
952
+ }
953
+ function getextname(filePath) {
954
+ return get_extname(filePath);
955
+ }
956
+ function getExtname(filePath) {
957
+ return get_extname(filePath);
958
+ }
959
+ function getfilename(filePath) {
960
+ return get_filename(filePath);
961
+ }
962
+ function getFilename(filePath) {
963
+ return get_filename(filePath);
964
+ }
965
+ function getbasename(filePath) {
966
+ return get_basename(filePath);
967
+ }
968
+ function getBasename(filePath) {
969
+ return get_basename(filePath);
970
+ }
971
+ function getdirname(filePath) {
972
+ return get_dirname(filePath);
973
+ }
974
+ function getDirname(filePath) {
975
+ return get_dirname(filePath);
976
+ }
977
+
978
+ /**
979
+ * Returns the absolute path of the current file.
980
+ */
981
+ function getAbsDir() {
982
+ return get_dirname(getAbsolutePath());
983
+ }
984
+ function getAbsPath(subPath) {
985
+ return make_path(getAbsDir(), subPath);
986
+ }
987
+
988
+ function getFunctionsDir() {
989
+ return get_dirname(getAbsDir());
990
+ }
991
+ function geAuthsUtilsDirectory() {
992
+ return make_path(getFunctionsDir(), 'auths');
993
+ }
994
+ function geBackupsUtilsDirectory() {
995
+ return make_path(getFunctionsDir(), 'backups');
996
+ }
997
+ function geConstantsUtilsDirectory() {
998
+ return make_path(getFunctionsDir(), 'constants');
999
+ }
1000
+ function geEnvUtilsDirectory() {
1001
+ return make_path(getFunctionsDir(), 'env_utils');
1002
+ }
1003
+ function geFetchUtilsDirectory() {
1004
+ return make_path(getFunctionsDir(), 'fetch_utils');
1005
+ }
1006
+ function geFileUtilsDirectory() {
1007
+ return make_path(getFunctionsDir(), 'file_utils');
1008
+ }
1009
+ function gePathUtilsDirectory() {
1010
+ return make_path(getFunctionsDir(), 'path_utils');
1011
+ }
1012
+ function geStringUtilsDirectory() {
1013
+ return make_path(getFunctionsDir(), 'string_utils');
1014
+ }
1015
+ function geTypeUtilsDirectory() {
1016
+ return make_path(getFunctionsDir(), 'type_utils');
1017
+ }
1018
+
1019
+ function getSrcDir() {
1020
+ return get_dirname(getFunctionsDir());
1021
+ }
1022
+ function geStaticDirectory() {
1023
+ return make_path(getSrcDir(), 'static');
1024
+ }
1025
+ function getLibUtilsDirectory() {
1026
+ return make_path(getSrcDir(), 'lib');
1027
+ }
1028
+ function getHooksUtilsDirectory() {
1029
+ return make_path(getSrcDir(), 'hooks');
1030
+ }
1031
+ function getFunctionsUtilsDirectory() {
1032
+ return make_path(getSrcDir(), 'functions');
1033
+ }
1034
+ function getComponentsUtilsDirectory() {
1035
+ return make_path(getSrcDir(), 'components');
1036
+ }
1037
+
1038
+ function getBaseDir() {
1039
+ return get_dirname(getSrcDir());
1040
+ }
1041
+ function getPublicDir() {
1042
+ return make_path(getBaseDir(), 'public');
1043
+ }
1044
+ function getDistDir() {
1045
+ return make_path(getBaseDir(), 'dist');
1046
+ }
1047
+ function getEnvDir() {
1048
+ return make_path(getBaseDir(), '.env');
1049
+ }
1050
+
1051
+ function getEnvPath(string = '.env') {
1052
+ return make_path(getEnvDir(), string);
1053
+ }
1054
+ function getDbConfigsPath() {
1055
+ return make_path(getBaseDir(), 'dbConfigs');
1056
+ }
1057
+ function getSchemasPath() {
1058
+ return make_path(getDbConfigsPath(), 'schemas');
1059
+ }
1060
+ function getSchemasDirPath(subPath) {
1061
+ return make_path(getSchemasPath(), subPath);
1062
+ }
1063
+
1064
+ // src/functions/rndm_utils/utils.ts
1065
+ function alertit(obj = null) {
1066
+ let msg;
1067
+ try {
1068
+ msg = JSON.stringify(obj);
1069
+ }
1070
+ catch {
1071
+ // If JSON.stringify fails (circular refs, etc.), fall back to a simple string
1072
+ msg = String(obj);
1073
+ }
1074
+ alert(msg);
1075
+ }
1076
+
1077
+ // take N args and coerce them all to numbers
1078
+ function safeNums(...args) {
1079
+ return args.map(ensure_number);
1080
+ }
1081
+ // divide the first value by each of the following
1082
+ function safeAdd(...args) {
1083
+ const [head, ...rest] = safeNums(...args);
1084
+ // if we don’t have a head or any divisor is zero, bail
1085
+ if (head === 0 || rest.some((d) => d === 0))
1086
+ return 0;
1087
+ return rest.reduce((acc, d) => acc + d, head);
1088
+ }
1089
+ // divide the first value by each of the following
1090
+ function safeSubtract(...args) {
1091
+ const [head, ...rest] = safeNums(...args);
1092
+ // if we don’t have a head or any divisor is zero, bail
1093
+ if (head === 0 || rest.some((d) => d === 0))
1094
+ return 0;
1095
+ return rest.reduce((acc, d) => acc - d, head);
1096
+ }
1097
+ // divide the first value by each of the following
1098
+ function safeDivide(...args) {
1099
+ const [head, ...rest] = safeNums(...args);
1100
+ // if we don’t have a head or any divisor is zero, bail
1101
+ if (head === 0 || rest.some((d) => d === 0))
1102
+ return 0;
1103
+ return rest.reduce((acc, d) => acc / d, head);
1104
+ }
1105
+ // multiply all the values together
1106
+ function safeMultiply(...args) {
1107
+ const nums = safeNums(...args);
1108
+ // if any number is zero, result is zero
1109
+ if (nums.includes(0))
1110
+ return 0;
1111
+ return nums.reduce((acc, n) => acc * n, 1);
1112
+ }
1113
+ // round a value to two decimals by percent
1114
+ function roundPercentage(x) {
1115
+ const pct = safeMultiply(ensure_number(x), 100);
1116
+ return safeDivide(Math.round(pct), 100);
1117
+ }
1118
+ function exponential(i, k) {
1119
+ return i * (10 ** (k));
1120
+ }
1121
+ function isZero(obj) {
1122
+ if (obj == 0) {
1123
+ return true;
1124
+ }
1125
+ return false;
1126
+ }
1127
+
1128
+ const SECOND = 1;
1129
+ const ZEPTOSECOND = exponential(SECOND, -21);
1130
+ const ATTOSECOND = exponential(SECOND, -18);
1131
+ const FEMTOSECOND = exponential(SECOND, -15);
1132
+ const PICOSECOND = exponential(SECOND, -12);
1133
+ const NANOSECOND = exponential(SECOND, -9);
1134
+ const MICROSECOND = exponential(SECOND, -6);
1135
+ const MILISECOND = exponential(SECOND, -3);
1136
+ const CENTISECOND = exponential(SECOND, -2);
1137
+ const DECISECOND = exponential(SECOND, -1);
1138
+ const MINUTE = 60 * SECOND;
1139
+ const HOUR = 60 * MINUTE;
1140
+ const DAY = 24 * HOUR;
1141
+ const YEAR = 365 * DAY;
1142
+ const MONTH = YEAR / 12;
1143
+ // Derived: explicit names
1144
+ const SECONDS_PER_MINUTE = MINUTE;
1145
+ const SECONDS_PER_HOUR = HOUR;
1146
+ const SECONDS_PER_DAY = DAY;
1147
+ //math
1148
+ const PI = Math.PI;
1149
+ const PI2 = 2 * PI;
1150
+ // Distance
1151
+ const METERS_PER_KM = 1000;
1152
+ const METERS_PER_MILE = 1609.34;
1153
+ const METERS_PER_FOOT = 0.3048;
1154
+ const KMS_PER_METER = 1 / METERS_PER_KM;
1155
+ const MILES_PER_METER = 1 / METERS_PER_MILE;
1156
+ const FEET_PER_METER = 1 / METERS_PER_FOOT;
1157
+ const MIN_IN_S = 1 / MINUTE;
1158
+ const HOUR_IN_S = 1 / HOUR;
1159
+ const DAY_IN_S = 1 / DAY;
1160
+ const YEAR_IN_S = 1 / YEAR;
1161
+ const MONTH_IN_S = 1 / MONTH;
1162
+ const MiPerH_TO_MPerS = METERS_PER_MILE * HOUR_IN_S;
1163
+ const MPerS_TO_MiPerH = 1 / MiPerH_TO_MPerS;
1164
+
1165
+ // conversions.ts
1166
+ /*───────────────────────────────────────────────────────────────
1167
+ 🧭 CANONICAL MAPPINGS
1168
+ ───────────────────────────────────────────────────────────────*/
1169
+ const DIST_ALIASES = {
1170
+ m: "m", meter: "m", meters: "m",
1171
+ km: "km", kms: "km", kilometer: "km", kilometers: "km",
1172
+ mi: "mi", mile: "mi", miles: "mi",
1173
+ ft: "ft", f: "ft", foot: "ft", feet: "ft",
1174
+ };
1175
+ const TIME_ALIASES = {
1176
+ s: "s", sec: "s", second: "s", seconds: "s",
1177
+ min: "min", m: "min", minute: "min", minutes: "min",
1178
+ h: "h", hr: "h", hour: "h", hours: "h",
1179
+ day: "day", d: "day", days: "day",
1180
+ };
1181
+ const DIST_FACTORS = {
1182
+ m: 1,
1183
+ km: METERS_PER_KM,
1184
+ mi: METERS_PER_MILE,
1185
+ ft: METERS_PER_FOOT,
1186
+ };
1187
+ const TIME_FACTORS = {
1188
+ s: 1,
1189
+ min: MINUTE,
1190
+ h: HOUR,
1191
+ day: DAY,
1192
+ };
1193
+ /*───────────────────────────────────────────────────────────────
1194
+ 🔍 CANONICALIZATION HELPERS
1195
+ ───────────────────────────────────────────────────────────────*/
1196
+ function canonDist(u) {
1197
+ const key = (u ?? "m").toString().toLowerCase();
1198
+ const canon = DIST_ALIASES[key];
1199
+ if (!canon)
1200
+ throw new Error(`Unknown distance unit: ${u}`);
1201
+ return canon;
1202
+ }
1203
+ function canonTime(u) {
1204
+ const key = (u ?? "s").toString().toLowerCase();
1205
+ const canon = TIME_ALIASES[key];
1206
+ if (!canon)
1207
+ throw new Error(`Unknown time unit: ${u}`);
1208
+ return canon;
1209
+ }
1210
+ /*───────────────────────────────────────────────────────────────
1211
+ ⚖️ NORMALIZATION HELPERS
1212
+ ───────────────────────────────────────────────────────────────*/
1213
+ function distanceToMeters(d, unit) {
1214
+ const u = canonDist(unit);
1215
+ return safeMultiply(d, DIST_FACTORS[u]);
1216
+ }
1217
+ function metersToDistance(v, unit) {
1218
+ const u = canonDist(unit);
1219
+ return safeDivide(v, DIST_FACTORS[u]);
1220
+ }
1221
+ function timeToSeconds(t, unit) {
1222
+ const u = canonTime(unit);
1223
+ return safeMultiply(t, TIME_FACTORS[u]);
1224
+ }
1225
+ function secondsToTime(v, unit) {
1226
+ const u = canonTime(unit);
1227
+ return safeDivide(v, TIME_FACTORS[u]);
1228
+ }
1229
+ /*───────────────────────────────────────────────────────────────
1230
+ 🚀 SPEED CONVERSIONS (normalize / unnormalize)
1231
+ ───────────────────────────────────────────────────────────────*/
1232
+ function speedToMps(v, distUnit, timeUnit) {
1233
+ const du = canonDist(distUnit);
1234
+ const tu = canonTime(timeUnit);
1235
+ return v * (DIST_FACTORS[du] / TIME_FACTORS[tu]);
1236
+ }
1237
+ function mpsToSpeed(vMps, distUnit, timeUnit) {
1238
+ const du = canonDist(distUnit);
1239
+ const tu = canonTime(timeUnit);
1240
+ return vMps * (TIME_FACTORS[tu] / DIST_FACTORS[du]);
1241
+ }
1242
+ /*───────────────────────────────────────────────────────────────
1243
+ 🎯 UNIVERSAL CONVERTERS
1244
+ ───────────────────────────────────────────────────────────────*/
1245
+ function convertDistance({ d, fromDist, toDist, vOnly = true, }) {
1246
+ const m = distanceToMeters(d, fromDist);
1247
+ const D = canonDist(toDist ?? "m");
1248
+ const out = metersToDistance(m, D);
1249
+ return vOnly ? out : { d: out, D };
1250
+ }
1251
+ function convertTime({ t, fromTime, toTime, vOnly = true, }) {
1252
+ const sec = timeToSeconds(t, fromTime);
1253
+ const T = canonTime(toTime ?? "s");
1254
+ const out = secondsToTime(sec, T);
1255
+ return vOnly ? out : { t: out, T };
1256
+ }
1257
+ function convertSpeed({ v, fromDist, fromTime, toDist, toTime, vOnly = true, }) {
1258
+ const mps = speedToMps(v, fromDist, fromTime);
1259
+ const d = canonDist(toDist ?? "m");
1260
+ const t = canonTime(toTime ?? "s");
1261
+ const out = mpsToSpeed(mps, d, t);
1262
+ return vOnly ? out : { v: out, d, t };
1263
+ }
1264
+ const DistanceConverter = {
1265
+ normalize: distanceToMeters,
1266
+ unnormalize: metersToDistance,
1267
+ };
1268
+ const TimeConverter = {
1269
+ normalize: timeToSeconds,
1270
+ unnormalize: secondsToTime,
1271
+ };
1272
+ const SpeedConverter = {
1273
+ normalize: (v, [du, tu]) => speedToMps(v, du, tu),
1274
+ unnormalize: (v, [du, tu]) => mpsToSpeed(v, du, tu),
1275
+ };
1276
+ /*───────────────────────────────────────────────────────────────
1277
+ 🧩 COMPATIBILITY WRAPPERS (legacy aliases)
1278
+ ───────────────────────────────────────────────────────────────*/
1279
+ const toMeters = distanceToMeters;
1280
+ const fromMeters = metersToDistance;
1281
+ const toSeconds = timeToSeconds;
1282
+ const fromSeconds = secondsToTime;
1283
+ const velocityToMs = (value, unit) => speedToMps(value, unit, "s");
1284
+ const velocityFromMs = (value, unit) => mpsToSpeed(value, unit, "s");
1285
+ /** Non-canonical helper for arbitrary rate conversion, e.g. ft/day → m/s */
1286
+ const fromMps = (v, dist_unit, time_unit) => mpsToSpeed(v, dist_unit, time_unit);
1287
+ /*───────────────────────────────────────────────────────────────
1288
+ 📊 UTILITIES
1289
+ ───────────────────────────────────────────────────────────────*/
1290
+ const isFiniteNum = (x) => Number.isFinite(x);
1291
+ const fmt = (n, digits = 2) => isFiniteNum(n) ? n.toFixed(digits) : "N/A";
1292
+
1293
+ // Function to check time interval
1294
+ function isTimeInterval(timeObj, interval) {
1295
+ return (Date.now() / 1000 - timeObj) < (interval - 1);
1296
+ }
1297
+
1298
+ /**
1299
+ * Recursively traverse the object and convert BigInts to numbers or strings.
1300
+ *
1301
+ * @param {object|array} obj - The object to traverse
1302
+ * @param {boolean} convertToNumber - Whether to convert BigInt to Number (default is true)
1303
+ * @returns {object|array} - The transformed object
1304
+ */
1305
+ function convertBigInts(obj, convertToNumber = true) {
1306
+ if (obj === null || obj === undefined)
1307
+ return obj;
1308
+ try {
1309
+ if (typeof obj === 'bigint') {
1310
+ return convertToNumber ? Number(obj) : obj.toString();
1311
+ }
1312
+ if (typeof obj === 'object') {
1313
+ if (Array.isArray(obj)) {
1314
+ return obj.map((item) => convertBigInts(item, convertToNumber));
1315
+ }
1316
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, convertBigInts(value, convertToNumber)]));
1317
+ }
1318
+ }
1319
+ catch (error) {
1320
+ }
1321
+ return obj;
1322
+ }
1323
+
1324
+ function getSafeDocument() {
1325
+ return typeof document !== 'undefined' ? document : undefined;
1326
+ }
1327
+ function getDocumentProp(...keys) {
1328
+ let obj = getSafeDocument();
1329
+ for (const k of keys) {
1330
+ if (obj == null || typeof obj !== 'object')
1331
+ return undefined;
1332
+ obj = obj[k];
1333
+ }
1334
+ return obj;
1335
+ }
1336
+
1337
+ /**
1338
+ * Returns the global window object if it exists, otherwise undefined.
1339
+ */
1340
+ function getSafeWindow() {
1341
+ return typeof window !== 'undefined' ? window : undefined;
1342
+ }
1343
+ /**
1344
+ * Safely call a method on window by name.
1345
+ *
1346
+ * @param method The Window method to call (e.g. "alert", "open", etc.).
1347
+ * @param args Arguments to pass to that method.
1348
+ * @returns The method’s return value, or undefined if
1349
+ * window/method isn’t available or throws.
1350
+ */
1351
+ function callWindowMethod(method, ...args) {
1352
+ const w = getSafeWindow();
1353
+ if (!w)
1354
+ return undefined;
1355
+ const fn = w[method];
1356
+ if (typeof fn !== 'function')
1357
+ return undefined;
1358
+ try {
1359
+ // cast to any so TS doesn’t complain about apply/invoke
1360
+ return fn(...args);
1361
+ }
1362
+ catch {
1363
+ return undefined;
1364
+ }
1365
+ }
1366
+ /** implementation */
1367
+ function getWindowProp(...keys) {
1368
+ let obj = getSafeWindow();
1369
+ for (const k of keys) {
1370
+ if (obj == null || typeof obj !== 'object')
1371
+ return undefined;
1372
+ obj = obj[k];
1373
+ }
1374
+ return obj;
1375
+ }
1376
+ function getWindowHost() {
1377
+ return getWindowProp('location', 'host');
1378
+ }
1379
+
1380
+ async function readJsonFileBrowser(url) {
1381
+ const fetchFn = safe_storage.safeGlobalProp("fetch");
1382
+ if (typeof fetchFn !== "function")
1383
+ return null;
1384
+ try {
1385
+ const res = await fetchFn(url);
1386
+ if (!res.ok)
1387
+ return null;
1388
+ return (await res.json());
1389
+ }
1390
+ catch {
1391
+ return null;
1392
+ }
1393
+ }
1394
+
1395
+ var readJsonFile_browser = /*#__PURE__*/Object.freeze({
1396
+ __proto__: null,
1397
+ readJsonFileBrowser: readJsonFileBrowser
1398
+ });
1399
+
1400
+ function readJsonFileNode(relativeOrAbsolutePath) {
1401
+ try {
1402
+ const filePath = path$1.isAbsolute(relativeOrAbsolutePath)
1403
+ ? relativeOrAbsolutePath
1404
+ : path$1.resolve(process.cwd(), relativeOrAbsolutePath);
1405
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
1406
+ }
1407
+ catch {
1408
+ return null;
1409
+ }
1410
+ }
1411
+
1412
+ var readJsonFile_node = /*#__PURE__*/Object.freeze({
1413
+ __proto__: null,
1414
+ readJsonFileNode: readJsonFileNode
1415
+ });
1416
+
1417
+ async function readJsonFile(relativeOrAbsolutePath) {
1418
+ if (typeof process !== "undefined" && process.versions?.node) {
1419
+ const mod = await Promise.resolve().then(function () { return readJsonFile_node; });
1420
+ return mod.readJsonFileNode(relativeOrAbsolutePath);
1421
+ }
1422
+ else {
1423
+ const mod = await Promise.resolve().then(function () { return readJsonFile_browser; });
1424
+ return mod.readJsonFileBrowser(relativeOrAbsolutePath);
1425
+ }
1426
+ }
1427
+ async function getConfigContent() {
1428
+ try {
1429
+ // `readJsonFile` should throw if the file isn’t there or isn’t valid JSON
1430
+ const cfg = await readJsonFile('./config.json');
1431
+ return cfg;
1432
+ }
1433
+ catch {
1434
+ // swallow errors & return null so callers can detect “no config”
1435
+ return null;
1436
+ }
1437
+ }
1438
+
1439
+ // src/functions/config_utils/src/config_utils.ts
1440
+ let _cachedConfig = null;
1441
+ async function loadConfig(filePath = null) {
1442
+ if (_cachedConfig) {
1443
+ return _cachedConfig;
1444
+ }
1445
+ // 1) figure out where config.json lives
1446
+ let configUrl;
1447
+ if (filePath) {
1448
+ configUrl = filePath;
1449
+ }
1450
+ else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('print_utils-Dsre-F_V.js', document.baseURI).href)) }) !== 'undefined' && typeof (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('print_utils-Dsre-F_V.js', document.baseURI).href)) === 'string') {
1451
+ // ES module: resolve relative to this file
1452
+ try {
1453
+ const mod = await (new Function("return import('./config.json').catch(() => ({}))"))();
1454
+ _cachedConfig = mod.default ?? {};
1455
+ return _cachedConfig;
1456
+ }
1457
+ catch {
1458
+ configUrl = 'config.json';
1459
+ }
1460
+ }
1461
+ else {
1462
+ // browser fallback
1463
+ const baseURI = safe_storage.safeGlobalProp('document', 'baseURI');
1464
+ try {
1465
+ configUrl =
1466
+ typeof baseURI === 'string'
1467
+ ? new URL('config.json', baseURI).href
1468
+ : 'config.json';
1469
+ }
1470
+ catch {
1471
+ configUrl = 'config.json';
1472
+ }
1473
+ }
1474
+ // 2) if we have a fetch, try HTTP(S)
1475
+ const fetchFn = safe_storage.safeGlobalProp('fetch');
1476
+ if (typeof fetchFn === 'function') {
1477
+ try {
1478
+ const res = await fetchFn(configUrl);
1479
+ if (res.ok) {
1480
+ const json = await res.json();
1481
+ // cache & return
1482
+ _cachedConfig = json ?? {};
1483
+ return _cachedConfig;
1484
+ }
1485
+ }
1486
+ catch {
1487
+ /* swallow */
1488
+ }
1489
+ }
1490
+ // 3) Node fallback: try reading from disk (requires your readJsonFile util)
1491
+ try {
1492
+ const disk = await readJsonFile(configUrl);
1493
+ _cachedConfig = disk ?? {};
1494
+ return _cachedConfig;
1495
+ }
1496
+ catch {
1497
+ /* swallow */
1498
+ }
1499
+ // 4) if all else fails, return an empty config
1500
+ _cachedConfig = {};
1501
+ return _cachedConfig;
1502
+ }
1503
+ async function getConfig(key) {
1504
+ const cfg = await loadConfig();
1505
+ return key != null ? cfg[key] : cfg;
1506
+ }
1507
+
1508
+ /**
1509
+ * Processes keywords by checking if keywords is a string and splitting it.
1510
+ * Then cleans each keyword using `eatAll` with a set of characters to remove.
1511
+ *
1512
+ * @param keywords - The keywords as a comma-separated string or as an array.
1513
+ * @returns An array of cleaned keywords.
1514
+ */
1515
+ function processKeywords(keywords) {
1516
+ let keywordArray;
1517
+ // If keywords is a string, split it on commas
1518
+ if (typeof keywords === "string") {
1519
+ keywordArray = keywords.split(",");
1520
+ }
1521
+ else {
1522
+ keywordArray = keywords;
1523
+ }
1524
+ // Clean each keyword by removing unwanted characters
1525
+ return keywordArray.map(keyword => eatAll(keyword, [",", "\n", "\t", " ", "#"]));
1526
+ }
1527
+ /**
1528
+ * Constructs a keyword string where each keyword is prefixed with a hash (#).
1529
+ *
1530
+ * @param keywords - An array of keywords.
1531
+ * @returns A string with each keyword prefixed by '#'.
1532
+ */
1533
+ function get_keyword_string(keywords) {
1534
+ keywords = processKeywords(keywords);
1535
+ let allString = "";
1536
+ for (const keyword of keywords) {
1537
+ allString += ` #${keyword}`;
1538
+ }
1539
+ return allString;
1540
+ }
1541
+
1542
+ // Function to compare MB
1543
+ function exceedsMbLimit(limitMb, payloadMb) {
1544
+ return payloadMb > limitMb;
1545
+ }
1546
+ function safeJsonSizeInMb(value) {
1547
+ const seen = new WeakSet();
1548
+ const json = JSON.stringify(value, (_, v) => {
1549
+ if (typeof v === "bigint")
1550
+ return v.toString();
1551
+ if (typeof v === "object" && v !== null) {
1552
+ if (seen.has(v))
1553
+ return "[Circular]";
1554
+ seen.add(v);
1555
+ }
1556
+ return v;
1557
+ });
1558
+ return Buffer.byteLength(json, "utf8") / (1024 * 1024);
1559
+ }
1560
+ function dataSizeInMb(data) {
1561
+ const size = typeof data === "string"
1562
+ ? Buffer.byteLength(data, "utf8")
1563
+ : Buffer.byteLength(JSON.stringify(data), "utf8");
1564
+ return size / (1024 * 1024);
1565
+ }
1566
+ function getJsonSizeInMb(json) {
1567
+ return Buffer.byteLength(JSON.stringify(json), "utf8") / (1024 * 1024);
1568
+ }
1569
+ // Function to calculate data size in KB
1570
+ function dataSize(data) {
1571
+ let size = 0;
1572
+ if (typeof data === 'string') {
1573
+ size = Buffer.byteLength(data, 'utf8');
1574
+ }
1575
+ else if (Buffer.isBuffer(data)) {
1576
+ size = data.length;
1577
+ }
1578
+ else if (typeof data === 'object') {
1579
+ size = Buffer.byteLength(JSON.stringify(data), 'utf8');
1580
+ }
1581
+ else {
1582
+ size = Buffer.byteLength(String(data), 'utf8');
1583
+ }
1584
+ return size / 1000; // Convert to kilobytes
1585
+ }
1586
+
1587
+ function getLastCaller(skip = ["debugPrint"]) {
1588
+ const stack = new Error().stack;
1589
+ if (!stack)
1590
+ return null;
1591
+ const lines = stack
1592
+ .split("\n")
1593
+ .map(l => l.trim())
1594
+ .slice(1); // drop "Error"
1595
+ for (const line of lines) {
1596
+ // Example:
1597
+ // at processSingleAddress (/path/file.ts:142:7)
1598
+ const match = line.match(/at (.+?) \((.+?):(\d+):(\d+)\)/) ||
1599
+ line.match(/at (.+?):(\d+):(\d+)/);
1600
+ if (!match)
1601
+ continue;
1602
+ const functionName = match[1] ?? "anonymous";
1603
+ if (skip.includes(functionName))
1604
+ continue;
1605
+ return {
1606
+ functionName,
1607
+ file: match[2],
1608
+ line: Number(match[3]),
1609
+ column: Number(match[4]),
1610
+ };
1611
+ }
1612
+ return null;
1613
+ }
1614
+
1615
+ function debugPrint(value, label = null) {
1616
+ const caller = getLastCaller();
1617
+ const header = label ??
1618
+ (caller
1619
+ ? `${caller.functionName} @ ${caller.file}:${caller.line}`
1620
+ : "object");
1621
+ console.log(`\n🔍 ${header}`);
1622
+ console.log(util.inspect(value, {
1623
+ depth: null,
1624
+ colors: true,
1625
+ compact: false,
1626
+ maxArrayLength: null,
1627
+ }));
1628
+ }
1629
+
1630
+ exports.API_PREFIX = API_PREFIX;
1631
+ exports.ATTOSECOND = ATTOSECOND;
1632
+ exports.BASE_URL = BASE_URL;
1633
+ exports.CENTISECOND = CENTISECOND;
1634
+ exports.DAY = DAY;
1635
+ exports.DAY_IN_S = DAY_IN_S;
1636
+ exports.DECISECOND = DECISECOND;
1637
+ exports.DEV_PREFIX = DEV_PREFIX;
1638
+ exports.DIST_ALIASES = DIST_ALIASES;
1639
+ exports.DIST_FACTORS = DIST_FACTORS;
1640
+ exports.DOMAIN_NAME = DOMAIN_NAME;
1641
+ exports.DistanceConverter = DistanceConverter;
1642
+ exports.FEET_PER_METER = FEET_PER_METER;
1643
+ exports.FEMTOSECOND = FEMTOSECOND;
1644
+ exports.HOUR = HOUR;
1645
+ exports.HOUR_IN_S = HOUR_IN_S;
1646
+ exports.KMS_PER_METER = KMS_PER_METER;
1647
+ exports.METERS_PER_FOOT = METERS_PER_FOOT;
1648
+ exports.METERS_PER_KM = METERS_PER_KM;
1649
+ exports.METERS_PER_MILE = METERS_PER_MILE;
1650
+ exports.MICROSECOND = MICROSECOND;
1651
+ exports.MILES_PER_METER = MILES_PER_METER;
1652
+ exports.MILISECOND = MILISECOND;
1653
+ exports.MINUTE = MINUTE;
1654
+ exports.MIN_IN_S = MIN_IN_S;
1655
+ exports.MONTH = MONTH;
1656
+ exports.MONTH_IN_S = MONTH_IN_S;
1657
+ exports.MPerS_TO_MiPerH = MPerS_TO_MiPerH;
1658
+ exports.MiPerH_TO_MPerS = MiPerH_TO_MPerS;
1659
+ exports.NANOSECOND = NANOSECOND;
1660
+ exports.PI = PI;
1661
+ exports.PI2 = PI2;
1662
+ exports.PICOSECOND = PICOSECOND;
1663
+ exports.PROD_PREFIX = PROD_PREFIX;
1664
+ exports.PROTOCOL = PROTOCOL;
1665
+ exports.SECOND = SECOND;
1666
+ exports.SECONDS_PER_DAY = SECONDS_PER_DAY;
1667
+ exports.SECONDS_PER_HOUR = SECONDS_PER_HOUR;
1668
+ exports.SECONDS_PER_MINUTE = SECONDS_PER_MINUTE;
1669
+ exports.SUB_DIR = SUB_DIR;
1670
+ exports.SpeedConverter = SpeedConverter;
1671
+ exports.TIME_ALIASES = TIME_ALIASES;
1672
+ exports.TIME_FACTORS = TIME_FACTORS;
1673
+ exports.TimeConverter = TimeConverter;
1674
+ exports.YEAR = YEAR;
1675
+ exports.YEAR_IN_S = YEAR_IN_S;
1676
+ exports.ZEPTOSECOND = ZEPTOSECOND;
1677
+ exports.alertit = alertit;
1678
+ exports.assureArray = assureArray;
1679
+ exports.assureList = assureList;
1680
+ exports.assureNumber = assureNumber;
1681
+ exports.assureString = assureString;
1682
+ exports.assure_array = assure_array;
1683
+ exports.assure_list = assure_list;
1684
+ exports.assure_number = assure_number;
1685
+ exports.assure_string = assure_string;
1686
+ exports.assurearray = assurearray;
1687
+ exports.assurelist = assurelist;
1688
+ exports.assurenumber = assurenumber;
1689
+ exports.assurestring = assurestring;
1690
+ exports.callWindowMethod = callWindowMethod;
1691
+ exports.canonDist = canonDist;
1692
+ exports.canonTime = canonTime;
1693
+ exports.capitalize = capitalize;
1694
+ exports.capitalize_str = capitalize_str;
1695
+ exports.checkResponse = checkResponse;
1696
+ exports.cleanArray = cleanArray;
1697
+ exports.cleanText = cleanText;
1698
+ exports.convertBigInts = convertBigInts;
1699
+ exports.convertDistance = convertDistance;
1700
+ exports.convertSpeed = convertSpeed;
1701
+ exports.convertTime = convertTime;
1702
+ exports.create_list_string = create_list_string;
1703
+ exports.dataSize = dataSize;
1704
+ exports.dataSizeInMb = dataSizeInMb;
1705
+ exports.debugPrint = debugPrint;
1706
+ exports.distanceToMeters = distanceToMeters;
1707
+ exports.eatAll = eatAll;
1708
+ exports.eatElse = eatElse;
1709
+ exports.eatInner = eatInner;
1710
+ exports.eatOuter = eatOuter;
1711
+ exports.eatall = eatall;
1712
+ exports.eatinner = eatinner;
1713
+ exports.eatouter = eatouter;
1714
+ exports.emptyObjectToNull = emptyObjectToNull;
1715
+ exports.ends_in_quotes = ends_in_quotes;
1716
+ exports.ensureArray = ensureArray;
1717
+ exports.ensureList = ensureList;
1718
+ exports.ensureNumber = ensureNumber;
1719
+ exports.ensureString = ensureString;
1720
+ exports.ensure_array = ensure_array;
1721
+ exports.ensure_list = ensure_list;
1722
+ exports.ensure_number = ensure_number;
1723
+ exports.ensure_string = ensure_string;
1724
+ exports.ensurearray = ensurearray;
1725
+ exports.ensurelist = ensurelist;
1726
+ exports.ensurenumber = ensurenumber;
1727
+ exports.ensurestring = ensurestring;
1728
+ exports.exceedsMbLimit = exceedsMbLimit;
1729
+ exports.exponential = exponential;
1730
+ exports.extractInsertData = extractInsertData;
1731
+ exports.fetchIndexHtml = fetchIndexHtml;
1732
+ exports.fetchIndexHtmlContainer = fetchIndexHtmlContainer;
1733
+ exports.fetchIt = fetchIt;
1734
+ exports.findKeyValue = findKeyValue;
1735
+ exports.fmt = fmt;
1736
+ exports.formatNumber = formatNumber;
1737
+ exports.fromMeters = fromMeters;
1738
+ exports.fromMps = fromMps;
1739
+ exports.fromSeconds = fromSeconds;
1740
+ exports.geAuthsUtilsDirectory = geAuthsUtilsDirectory;
1741
+ exports.geBackupsUtilsDirectory = geBackupsUtilsDirectory;
1742
+ exports.geConstantsUtilsDirectory = geConstantsUtilsDirectory;
1743
+ exports.geEnvUtilsDirectory = geEnvUtilsDirectory;
1744
+ exports.geFetchUtilsDirectory = geFetchUtilsDirectory;
1745
+ exports.geFileUtilsDirectory = geFileUtilsDirectory;
1746
+ exports.gePathUtilsDirectory = gePathUtilsDirectory;
1747
+ exports.geStaticDirectory = geStaticDirectory;
1748
+ exports.geStringUtilsDirectory = geStringUtilsDirectory;
1749
+ exports.geTypeUtilsDirectory = geTypeUtilsDirectory;
1750
+ exports.get = get;
1751
+ exports.getAbsDir = getAbsDir;
1752
+ exports.getAbsPath = getAbsPath;
1753
+ exports.getAlphaNum = getAlphaNum;
1754
+ exports.getAlphas = getAlphas;
1755
+ exports.getBaseDir = getBaseDir;
1756
+ exports.getBasename = getBasename;
1757
+ exports.getBody = getBody;
1758
+ exports.getChar = getChar;
1759
+ exports.getCleanArray = getCleanArray;
1760
+ exports.getComponentsUtilsDirectory = getComponentsUtilsDirectory;
1761
+ exports.getConfig = getConfig;
1762
+ exports.getConfigContent = getConfigContent;
1763
+ exports.getDbConfigsPath = getDbConfigsPath;
1764
+ exports.getDirname = getDirname;
1765
+ exports.getDistDir = getDistDir;
1766
+ exports.getDocumentProp = getDocumentProp;
1767
+ exports.getEnvDir = getEnvDir;
1768
+ exports.getEnvPath = getEnvPath;
1769
+ exports.getExtname = getExtname;
1770
+ exports.getFetchVars = getFetchVars;
1771
+ exports.getFilename = getFilename;
1772
+ exports.getFunctionsDir = getFunctionsDir;
1773
+ exports.getFunctionsUtilsDirectory = getFunctionsUtilsDirectory;
1774
+ exports.getHeaders = getHeaders;
1775
+ exports.getHooksUtilsDirectory = getHooksUtilsDirectory;
1776
+ exports.getHtmlDirectory = getHtmlDirectory;
1777
+ exports.getIfNone = getIfNone;
1778
+ exports.getJsonSizeInMb = getJsonSizeInMb;
1779
+ exports.getLastCaller = getLastCaller;
1780
+ exports.getLibUtilsDirectory = getLibUtilsDirectory;
1781
+ exports.getMethod = getMethod;
1782
+ exports.getNums = getNums;
1783
+ exports.getPublicDir = getPublicDir;
1784
+ exports.getResult = getResult;
1785
+ exports.getSafeDocument = getSafeDocument;
1786
+ exports.getSafeWindow = getSafeWindow;
1787
+ exports.getSchemasDirPath = getSchemasDirPath;
1788
+ exports.getSchemasPath = getSchemasPath;
1789
+ exports.getSplitext = getSplitext;
1790
+ exports.getSrcDir = getSrcDir;
1791
+ exports.getSubstring = getSubstring;
1792
+ exports.getWindowHost = getWindowHost;
1793
+ exports.getWindowProp = getWindowProp;
1794
+ exports.get_basename = get_basename;
1795
+ exports.get_dirname = get_dirname;
1796
+ exports.get_extname = get_extname;
1797
+ exports.get_filename = get_filename;
1798
+ exports.get_full_path = get_full_path;
1799
+ exports.get_full_url = get_full_url;
1800
+ exports.get_key_value = get_key_value;
1801
+ exports.get_keyword_string = get_keyword_string;
1802
+ exports.get_relative_path = get_relative_path;
1803
+ exports.get_splitext = get_splitext;
1804
+ exports.get_window = get_window;
1805
+ exports.get_window_location = get_window_location;
1806
+ exports.get_window_parts = get_window_parts;
1807
+ exports.get_window_pathname = get_window_pathname;
1808
+ exports.getbasename = getbasename;
1809
+ exports.getdirname = getdirname;
1810
+ exports.getextname = getextname;
1811
+ exports.getfilename = getfilename;
1812
+ exports.getsplitext = getsplitext;
1813
+ exports.isFiniteNum = isFiniteNum;
1814
+ exports.isNum = isNum;
1815
+ exports.isStrInString = isStrInString;
1816
+ exports.isTimeInterval = isTimeInterval;
1817
+ exports.isType = isType;
1818
+ exports.isZero = isZero;
1819
+ exports.loadConfig = loadConfig;
1820
+ exports.loadInnerJson = loadInnerJson;
1821
+ exports.makePath = makePath;
1822
+ exports.make_path = make_path;
1823
+ exports.make_sanitized_path = make_sanitized_path;
1824
+ exports.makepath = makepath;
1825
+ exports.mergeNotNullValues = mergeNotNullValues;
1826
+ exports.metersToDistance = metersToDistance;
1827
+ exports.mpsToSpeed = mpsToSpeed;
1828
+ exports.normalizeUrl = normalizeUrl;
1829
+ exports.omitKeys = omitKeys;
1830
+ exports.parseResult = parseResult;
1831
+ exports.pathJoin = pathJoin;
1832
+ exports.path_join = path_join;
1833
+ exports.path_to_url = path_to_url;
1834
+ exports.pathjoin = pathjoin;
1835
+ exports.processKeywords = processKeywords;
1836
+ exports.readJsonFile = readJsonFile;
1837
+ exports.readJsonFileBrowser = readJsonFileBrowser;
1838
+ exports.readJsonFileNode = readJsonFileNode;
1839
+ exports.roundPercentage = roundPercentage;
1840
+ exports.safeAdd = safeAdd;
1841
+ exports.safeDivide = safeDivide;
1842
+ exports.safeJsonSizeInMb = safeJsonSizeInMb;
1843
+ exports.safeMultiply = safeMultiply;
1844
+ exports.safeNums = safeNums;
1845
+ exports.safeSubtract = safeSubtract;
1846
+ exports.sanitizeFilename = sanitizeFilename;
1847
+ exports.sanitizeString = sanitizeString;
1848
+ exports.secondsToTime = secondsToTime;
1849
+ exports.speedToMps = speedToMps;
1850
+ exports.stripPrefixes = stripPrefixes;
1851
+ exports.stripQuotes = stripQuotes;
1852
+ exports.timeToSeconds = timeToSeconds;
1853
+ exports.toMeters = toMeters;
1854
+ exports.toSeconds = toSeconds;
1855
+ exports.truncateString = truncateString;
1856
+ exports.tryEatPrefix = tryEatPrefix;
1857
+ exports.tryParse = tryParse;
1858
+ exports.urlJoin = urlJoin;
1859
+ exports.url_to_path = url_to_path;
1860
+ exports.urljoin = urljoin;
1861
+ exports.velocityFromMs = velocityFromMs;
1862
+ exports.velocityToMs = velocityToMs;
1863
+ //# sourceMappingURL=print_utils-Dsre-F_V.js.map