@myusufazmi/ultimate-tools 1.2.0 → 1.3.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.
package/README.md CHANGED
@@ -47,7 +47,61 @@ import { http } from "@myusufazmi/ultimate-tools";
47
47
 
48
48
  ---
49
49
 
50
- ### 📅 Date Utilities (NEW v1.1.0)
50
+ ### 📱 Device & Clipboard (NEW v1.3.0)
51
+
52
+ Modern device detection and clipboard interactions.
53
+
54
+ ```javascript
55
+ import { copyToClipboard, isMobile, getOS } from "@myusufazmi/ultimate-tools";
56
+
57
+ await copyToClipboard("Hello!");
58
+ if (isMobile()) console.log("User is on mobile");
59
+ console.log(getOS()); // "iOS", "Android", "Windows", etc.
60
+ ```
61
+
62
+ ---
63
+
64
+ ### 🎨 Color Manipulation (NEW v1.3.0)
65
+
66
+ Advanced color tools for theming.
67
+
68
+ ```javascript
69
+ import { hexToRgb, lighten, randomColor } from "@myusufazmi/ultimate-tools";
70
+
71
+ hexToRgb("#ffffff"); // {r: 255, g: 255, b: 255}
72
+ lighten("#000000", 20); // Lighten by 20%
73
+ randomColor(); // "#3a7f21"
74
+ ```
75
+
76
+ ---
77
+
78
+ ### 🔗 URL & Query Params (NEW v1.3.0)
79
+
80
+ Manage URL state without page rereshes.
81
+
82
+ ```javascript
83
+ import { getParam, updateParam } from "@myusufazmi/ultimate-tools";
84
+
85
+ const page = getParam("page"); // ?page=2 -> "2"
86
+ updateParam("sort", "desc"); // Updates URL automatically
87
+ ```
88
+
89
+ ---
90
+
91
+ ### 🖼️ File & Image Tools (NEW v1.3.0)
92
+
93
+ Essential file handling utilities.
94
+
95
+ ```javascript
96
+ import { toBase64, formatFileSize } from "@myusufazmi/ultimate-tools";
97
+
98
+ const base64 = await toBase64(fileInput.files[0]);
99
+ console.log(formatFileSize(1024 * 1024)); // "1 MB"
100
+ ```
101
+
102
+ ---
103
+
104
+ ### 📅 Date Utilities
51
105
 
52
106
  Simple and efficient date formatting and manipulation.
53
107
 
@@ -56,12 +110,11 @@ import { formatDate, relativeTime, addDays } from "@myusufazmi/ultimate-tools";
56
110
 
57
111
  formatDate(new Date(), "YYYY-MM-DD HH:mm:ss"); // "2026-02-09 11:58:39"
58
112
  relativeTime(new Date(Date.now() - 3600000)); // "1 hours ago"
59
- addDays(new Date(), 7); // Date object + 7 days
60
113
  ```
61
114
 
62
115
  ---
63
116
 
64
- ### 💎 Formatting Utilities (NEW v1.1.0)
117
+ ### 💎 Formatting Utilities
65
118
 
66
119
  Tools for number, currency, and string formatting.
67
120
 
@@ -72,25 +125,16 @@ import {
72
125
  slugify,
73
126
  truncate,
74
127
  } from "@myusufazmi/ultimate-tools";
75
-
76
- currency(50000); // "Rp 50.000,00" (default id-ID)
77
- number(1234.56, 1); // "1.234,6"
78
- slugify("Halo Dunia!"); // "halo-dunia"
79
- truncate("Teks yang sangat panjang sekali", 10); // "Teks yang..."
80
128
  ```
81
129
 
82
130
  ---
83
131
 
84
- ### 🛡 Validation Utilities (NEW v1.1.0)
132
+ ### 🛡 Validation Utilities
85
133
 
86
134
  Common regex-based validation helpers.
87
135
 
88
136
  ```javascript
89
137
  import { isEmail, isStrongPassword, isEmpty } from "@myusufazmi/ultimate-tools";
90
-
91
- isEmail("test@example.com"); // true
92
- isStrongPassword("Pass123"); // false (too short)
93
- isEmpty(" "); // true
94
138
  ```
95
139
 
96
140
  ---
@@ -103,9 +147,6 @@ Type-safe and auto-serialized storage for persistent data.
103
147
  import { local, session } from "@myusufazmi/ultimate-tools";
104
148
  ```
105
149
 
106
- - **`local.set(key, value)`** / **`session.set(key, value)`**
107
- - **`local.get(key, fallback)`** / **`session.get(key, fallback)`**
108
-
109
150
  ---
110
151
 
111
152
  ### 🔄 State Management
@@ -114,10 +155,6 @@ A tiny ( < 1KB) reactive state manager.
114
155
 
115
156
  ```javascript
116
157
  import { createStore } from "@myusufazmi/ultimate-tools";
117
-
118
- const count = createStore(0);
119
- count.subscribe((val) => console.log(val));
120
- count.update((n) => n + 1);
121
158
  ```
122
159
 
123
160
  ---
@@ -135,11 +172,6 @@ import {
135
172
  } from "@myusufazmi/ultimate-tools";
136
173
  ```
137
174
 
138
- - **`debounce(fn, delay)`**
139
- - **`throttle(fn, limit)`**
140
- - **`deepClone(obj)`**
141
- - **`uuid()`**
142
-
143
175
  ---
144
176
 
145
177
  ## 📜 License
package/dist/index.cjs.js CHANGED
@@ -502,30 +502,325 @@ const isEmpty = (str) => {
502
502
  return !str || str.trim().length === 0;
503
503
  };
504
504
 
505
+ /**
506
+ * Device Utilities
507
+ * Helpers for device detection and clipboard interaction.
508
+ */
509
+
510
+ /**
511
+ * Copy text to clipboard (modern & fallback)
512
+ * @param {string} text
513
+ * @returns {Promise<boolean>}
514
+ */
515
+ const copyToClipboard = async (text) => {
516
+ try {
517
+ if (navigator.clipboard) {
518
+ await navigator.clipboard.writeText(text);
519
+ return true;
520
+ } else {
521
+ // Fallback for older browsers
522
+ const textArea = document.createElement("textarea");
523
+ textArea.value = text;
524
+ textArea.style.position = "fixed";
525
+ document.body.appendChild(textArea);
526
+ textArea.focus();
527
+ textArea.select();
528
+ const success = document.execCommand("copy");
529
+ document.body.removeChild(textArea);
530
+ return success;
531
+ }
532
+ } catch (err) {
533
+ console.error("Failed to copy:", err);
534
+ return false;
535
+ }
536
+ };
537
+
538
+ /**
539
+ * Check if device is mobile (based on User Agent)
540
+ * @returns {boolean}
541
+ */
542
+ const isMobile = () => {
543
+ const ua = navigator.userAgent;
544
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
545
+ ua,
546
+ );
547
+ };
548
+
549
+ /**
550
+ * Get simple OS name
551
+ * @returns {'iOS' | 'Android' | 'Windows' | 'Mac' | 'Linux' | 'Unknown'}
552
+ */
553
+ const getOS = () => {
554
+ const ua = navigator.userAgent;
555
+ if (/iPad|iPhone|iPod/.test(ua)) return "iOS";
556
+ if (/Android/.test(ua)) return "Android";
557
+ if (/Win/.test(ua)) return "Windows";
558
+ if (/Mac/.test(ua)) return "Mac";
559
+ if (/Linux/.test(ua)) return "Linux";
560
+ return "Unknown";
561
+ };
562
+
563
+ /**
564
+ * Check if user prefers dark mode
565
+ * @returns {boolean}
566
+ */
567
+ const isDarkMode = () => {
568
+ return (
569
+ window.matchMedia &&
570
+ window.matchMedia("(prefers-color-scheme: dark)").matches
571
+ );
572
+ };
573
+
574
+ /**
575
+ * Color Utilities
576
+ * Manipulate arrays, hex, and RGB.
577
+ */
578
+
579
+ /**
580
+ * Convert Hex to RGB
581
+ * @param {string} hex
582
+ * @returns {{r: number, g: number, b: number} | null}
583
+ */
584
+ const hexToRgb = (hex) => {
585
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
586
+ return result
587
+ ? {
588
+ r: parseInt(result[1], 16),
589
+ g: parseInt(result[2], 16),
590
+ b: parseInt(result[3], 16),
591
+ }
592
+ : null;
593
+ };
594
+
595
+ /**
596
+ * Convert RGB to Hex
597
+ * @param {number} r
598
+ * @param {number} g
599
+ * @param {number} b
600
+ * @returns {string}
601
+ */
602
+ const rgbToHex = (r, g, b) => {
603
+ return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
604
+ };
605
+
606
+ /**
607
+ * Lighten a color by percentage
608
+ * @param {string} color - Hex color
609
+ * @param {number} percent - -100 to 100
610
+ * @returns {string}
611
+ */
612
+ const lighten = (color, percent) => {
613
+ let num = parseInt(color.replace("#", ""), 16),
614
+ amt = Math.round(2.55 * percent),
615
+ R = (num >> 16) + amt,
616
+ B = ((num >> 8) & 0x00ff) + amt,
617
+ G = (num & 0x0000ff) + amt;
618
+
619
+ return (
620
+ "#" +
621
+ (
622
+ 0x1000000 +
623
+ (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +
624
+ (B < 255 ? (B < 1 ? 0 : B) : 255) * 0x100 +
625
+ (G < 255 ? (G < 1 ? 0 : G) : 255)
626
+ )
627
+ .toString(16)
628
+ .slice(1)
629
+ );
630
+ };
631
+
632
+ /**
633
+ * Darken a color (alias for lighten with negative percent)
634
+ * @param {string} color
635
+ * @param {number} percent
636
+ * @returns {string}
637
+ */
638
+ const darken = (color, percent) => {
639
+ return lighten(color, -percent);
640
+ };
641
+
642
+ /**
643
+ * Generate a random hex color
644
+ * @returns {string}
645
+ */
646
+ const randomColor = () => {
647
+ return (
648
+ "#" +
649
+ Math.floor(Math.random() * 16777215)
650
+ .toString(16)
651
+ .padStart(6, "0")
652
+ );
653
+ };
654
+
655
+ /**
656
+ * URL Utilities
657
+ * Easy query parameter manipulation and URL helpers.
658
+ */
659
+
660
+ /**
661
+ * Get a query parameter value from URL
662
+ * @param {string} key
663
+ * @param {string} url - Default: window.location.href
664
+ * @returns {string|null}
665
+ */
666
+ const getParam = (key, url = window.location.href) => {
667
+ const searchParams = new URL(url).searchParams;
668
+ return searchParams.get(key);
669
+ };
670
+
671
+ /**
672
+ * Get all query parameters as an object
673
+ * @param {string} url
674
+ * @returns {Object}
675
+ */
676
+ const getQueryParams = (url = window.location.href) => {
677
+ const searchParams = new URL(url).searchParams;
678
+ const params = {};
679
+ for (const [key, value] of searchParams.entries()) {
680
+ params[key] = value;
681
+ }
682
+ return params;
683
+ };
684
+
685
+ /**
686
+ * Update a query parameter in the URL without reloading
687
+ * @param {string} key
688
+ * @param {string} value
689
+ */
690
+ const updateParam = (key, value) => {
691
+ const url = new URL(window.location.href);
692
+ if (value) {
693
+ url.searchParams.set(key, value);
694
+ } else {
695
+ url.searchParams.delete(key);
696
+ }
697
+ window.history.pushState({}, "", url);
698
+ };
699
+
700
+ /**
701
+ * Remove a query parameter
702
+ * @param {string} key
703
+ */
704
+ const removeParam = (key) => {
705
+ updateParam(key, null);
706
+ };
707
+
708
+ /**
709
+ * Determine if URL is absolute
710
+ * @param {string} url
711
+ * @returns {boolean}
712
+ */
713
+ const isAbsoluteURL = (url) => {
714
+ return /^[a-z][a-z0-9+.-]*:/.test(url);
715
+ };
716
+
717
+ /**
718
+ * File & Image Utilities
719
+ * Tools for base64 conversion, preloading, and file extension handling.
720
+ */
721
+
722
+ /**
723
+ * Convert File/Blob to Base64
724
+ * @param {File|Blob} file
725
+ * @returns {Promise<string>}
726
+ */
727
+ const toBase64 = (file) => {
728
+ return new Promise((resolve, reject) => {
729
+ const reader = new FileReader();
730
+ reader.readAsDataURL(file);
731
+ reader.onload = () => resolve(reader.result);
732
+ reader.onerror = (error) => reject(error);
733
+ });
734
+ };
735
+
736
+ /**
737
+ * Preload an image URL
738
+ * @param {string} url
739
+ * @returns {Promise<void>}
740
+ */
741
+ const preloadImage = (url) => {
742
+ return new Promise((resolve, reject) => {
743
+ const img = new Image();
744
+ img.src = url;
745
+ img.onload = () => resolve();
746
+ img.onerror = () => reject();
747
+ });
748
+ };
749
+
750
+ /**
751
+ * Get file extension from filename
752
+ * @param {string} filename
753
+ * @returns {string}
754
+ */
755
+ const getFileExtension = (filename) => {
756
+ return filename.slice(((filename.lastIndexOf(".") - 1) >>> 0) + 2);
757
+ };
758
+
759
+ /**
760
+ * Check if file is an image
761
+ * @param {File} file
762
+ * @returns {boolean}
763
+ */
764
+ const isImage = (file) => {
765
+ return file && file.type.startsWith("image/");
766
+ };
767
+
768
+ /**
769
+ * Calculate human-readable file size
770
+ * @param {number} bytes
771
+ * @returns {string}
772
+ */
773
+ const formatFileSize = (bytes) => {
774
+ if (bytes === 0) return "0 Bytes";
775
+ const k = 1024;
776
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
777
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
778
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
779
+ };
780
+
505
781
  exports.$ = $;
506
782
  exports.$$ = $$;
507
783
  exports.addDays = addDays;
508
784
  exports.capitalize = capitalize;
785
+ exports.copyToClipboard = copyToClipboard;
509
786
  exports.create = create;
510
787
  exports.createStore = createStore;
511
788
  exports.currency = currency;
789
+ exports.darken = darken;
512
790
  exports.debounce = debounce;
513
791
  exports.deepClone = deepClone;
514
792
  exports.formatDate = formatDate;
793
+ exports.formatFileSize = formatFileSize;
794
+ exports.getFileExtension = getFileExtension;
795
+ exports.getOS = getOS;
796
+ exports.getParam = getParam;
797
+ exports.getQueryParams = getQueryParams;
798
+ exports.hexToRgb = hexToRgb;
515
799
  exports.http = http;
800
+ exports.isAbsoluteURL = isAbsoluteURL;
801
+ exports.isDarkMode = isDarkMode;
516
802
  exports.isEmail = isEmail;
517
803
  exports.isEmpty = isEmpty;
804
+ exports.isImage = isImage;
805
+ exports.isMobile = isMobile;
518
806
  exports.isNumeric = isNumeric;
519
807
  exports.isSameDay = isSameDay;
520
808
  exports.isStrongPassword = isStrongPassword;
521
809
  exports.isURL = isURL;
810
+ exports.lighten = lighten;
522
811
  exports.local = local;
523
812
  exports.number = number;
524
813
  exports.on = on;
814
+ exports.preloadImage = preloadImage;
815
+ exports.randomColor = randomColor;
525
816
  exports.relativeTime = relativeTime;
817
+ exports.removeParam = removeParam;
818
+ exports.rgbToHex = rgbToHex;
526
819
  exports.session = session;
527
820
  exports.slugify = slugify;
528
821
  exports.throttle = throttle;
822
+ exports.toBase64 = toBase64;
529
823
  exports.truncate = truncate;
824
+ exports.updateParam = updateParam;
530
825
  exports.uuid = uuid;
531
826
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/dom.js","../src/http.js","../src/storage.js","../src/state.js","../src/utils.js","../src/date.js","../src/format.js","../src/validation.js"],"sourcesContent":["/**\r\n * DOM Utilities\r\n * Premium query selectors and manipulation tools.\r\n */\r\n\r\n/**\r\n * Higher performance querySelector wrapper\r\n * @param {string} selector\r\n * @param {HTMLElement|Document} context\r\n * @returns {HTMLElement|null}\r\n */\r\nexport const $ = (selector, context = document) => {\r\n return context.querySelector(selector);\r\n};\r\n\r\n/**\r\n * querySelectorAll wrapper that returns an array instead of a NodeList\r\n * @param {string} selector\r\n * @param {HTMLElement|Document} context\r\n * @returns {HTMLElement[]}\r\n */\r\nexport const $$ = (selector, context = document) => {\r\n return Array.from(context.querySelectorAll(selector));\r\n};\r\n\r\n/**\r\n * Create element with attributes and styles\r\n * @param {string} tag\r\n * @param {Object} options\r\n * @returns {HTMLElement}\r\n */\r\nexport const create = (tag, options = {}) => {\r\n const el = document.createElement(tag);\r\n const {\r\n attr = {},\r\n style = {},\r\n text = \"\",\r\n html = \"\",\r\n children = [],\r\n } = options;\r\n\r\n Object.entries(attr).forEach(([k, v]) => el.setAttribute(k, v));\r\n Object.assign(el.style, style);\r\n\r\n if (text) el.textContent = text;\r\n if (html) el.innerHTML = html;\r\n\r\n children.forEach((child) => {\r\n if (child instanceof HTMLElement) el.appendChild(child);\r\n else el.append(child);\r\n });\r\n\r\n return el;\r\n};\r\n\r\n/**\r\n * Event delegation helper\r\n * @param {HTMLElement|Document} parent\r\n * @param {string} event\r\n * @param {string} selector\r\n * @param {Function} handler\r\n */\r\nexport const on = (parent, event, selector, handler) => {\r\n parent.addEventListener(event, (e) => {\r\n const target = e.target.closest(selector);\r\n if (target && parent.contains(target)) {\r\n handler.call(target, e, target);\r\n }\r\n });\r\n};\r\n","/**\r\n * HTTP Utilities\r\n * Clean Fetch API wrapper with easy JSON handling and interceptors.\r\n */\r\n\r\nconst request = async (url, options = {}) => {\r\n const {\r\n method = \"GET\",\r\n headers = {},\r\n body = null,\r\n interceptors = { request: [], response: [] },\r\n } = options;\r\n\r\n let config = {\r\n method,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n };\r\n\r\n if (body && typeof body === \"object\") {\r\n config.body = JSON.stringify(body);\r\n } else if (body) {\r\n config.body = body;\r\n }\r\n\r\n // Request Interceptors\r\n interceptors.request.forEach((fn) => {\r\n config = fn(config) || config;\r\n });\r\n\r\n try {\r\n const response = await fetch(url, config);\r\n let data = await response.json().catch(() => null);\r\n\r\n // Response Interceptors\r\n interceptors.response.forEach((fn) => {\r\n data = fn(data, response) || data;\r\n });\r\n\r\n if (!response.ok) {\r\n throw { status: response.status, data };\r\n }\r\n\r\n return data;\r\n } catch (error) {\r\n console.error(\"Fetch Error:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\nexport const http = {\r\n get: (url, options) => request(url, { ...options, method: \"GET\" }),\r\n post: (url, body, options) =>\r\n request(url, { ...options, method: \"POST\", body }),\r\n put: (url, body, options) =>\r\n request(url, { ...options, method: \"PUT\", body }),\r\n delete: (url, options) => request(url, { ...options, method: \"DELETE\" }),\r\n};\r\n","/**\r\n * Storage Utilities\r\n * Type-safe and auto-serialized local/session storage.\r\n */\r\n\r\nconst createStorage = (type = \"localStorage\") => {\r\n const storage = window[type];\r\n\r\n return {\r\n /**\r\n * Set item with auto-serialization\r\n * @param {string} key\r\n * @param {any} value\r\n */\r\n set(key, value) {\r\n try {\r\n const serialized = JSON.stringify(value);\r\n storage.setItem(key, serialized);\r\n } catch (e) {\r\n console.error(`Storage Error (set): ${key}`, e);\r\n }\r\n },\r\n\r\n /**\r\n * Get item with auto-deserialization\r\n * @param {string} key\r\n * @param {any} fallback\r\n * @returns {any}\r\n */\r\n get(key, fallback = null) {\r\n try {\r\n const item = storage.getItem(key);\r\n return item ? JSON.parse(item) : fallback;\r\n } catch (e) {\r\n console.error(`Storage Error (get): ${key}`, e);\r\n return fallback;\r\n }\r\n },\r\n\r\n /**\r\n * Remove item\r\n * @param {string} key\r\n */\r\n remove(key) {\r\n storage.removeItem(key);\r\n },\r\n\r\n /**\r\n * Clear all items\r\n */\r\n clear() {\r\n storage.clear();\r\n },\r\n };\r\n};\r\n\r\nexport const local = createStorage(\"localStorage\");\r\nexport const session = createStorage(\"sessionStorage\");\r\n","/**\r\n * State Management\r\n * A tiny reactive store (inspired by Svelte stores).\r\n */\r\n\r\n/**\r\n * Creates a reactive store\r\n * @param {any} initialValue\r\n * @returns {Object}\r\n */\r\nexport const createStore = (initialValue) => {\r\n let value = initialValue;\r\n const subscribers = new Set();\r\n\r\n /**\r\n * Subscribe to changes\r\n * @param {Function} fn\r\n * @returns {Function} Unsubscribe function\r\n */\r\n const subscribe = (fn) => {\r\n subscribers.add(fn);\r\n fn(value);\r\n return () => subscribers.delete(fn);\r\n };\r\n\r\n /**\r\n * Update value and notify subscribers\r\n * @param {any|Function} newValue\r\n */\r\n const update = (newValue) => {\r\n if (typeof newValue === \"function\") {\r\n value = newValue(value);\r\n } else {\r\n value = newValue;\r\n }\r\n subscribers.forEach((fn) => fn(value));\r\n };\r\n\r\n /**\r\n * Get current value\r\n * @returns {any}\r\n */\r\n const get = () => value;\r\n\r\n return { subscribe, update, get };\r\n};\r\n","/**\r\n * General Utilities\r\n * Common helper functions.\r\n */\r\n\r\n/**\r\n * Debounce function\r\n * @param {Function} fn\r\n * @param {number} delay\r\n * @returns {Function}\r\n */\r\nexport const debounce = (fn, delay = 300) => {\r\n let timeout;\r\n return (...args) => {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => fn.apply(this, args), delay);\r\n };\r\n};\r\n\r\n/**\r\n * Throttle function\r\n * @param {Function} fn\r\n * @param {number} limit\r\n * @returns {Function}\r\n */\r\nexport const throttle = (fn, limit = 300) => {\r\n let lastFunc;\r\n let lastRan;\r\n return (...args) => {\r\n if (!lastRan) {\r\n fn.apply(this, args);\r\n lastRan = Date.now();\r\n } else {\r\n clearTimeout(lastFunc);\r\n lastFunc = setTimeout(\r\n () => {\r\n if (Date.now() - lastRan >= limit) {\r\n fn.apply(this, args);\r\n lastRan = Date.now();\r\n }\r\n },\r\n limit - (Date.now() - lastRan),\r\n );\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Deep clone an object\r\n * @param {any} obj\r\n * @returns {any}\r\n */\r\nexport const deepClone = (obj) => {\r\n if (obj === null || typeof obj !== \"object\") return obj;\r\n return JSON.parse(JSON.stringify(obj));\r\n};\r\n\r\n/**\r\n * Generates a simple UUID-like string\r\n * @returns {string}\r\n */\r\nexport const uuid = () => {\r\n return (\r\n Math.random().toString(36).substring(2, 10) +\r\n Date.now().toString(36).substring(2, 6)\r\n );\r\n};\r\n","/**\r\n * Date Utilities\r\n * Simple and efficient date formatting and manipulation.\r\n */\r\n\r\n/**\r\n * Basic Date Formatter\r\n * @param {Date|string|number} date\r\n * @param {string} pattern - Default: 'YYYY-MM-DD'\r\n * @returns {string}\r\n */\r\nexport const formatDate = (date, pattern = \"YYYY-MM-DD\") => {\r\n const d = new Date(date);\r\n if (isNaN(d.getTime())) return \"Invalid Date\";\r\n\r\n const map = {\r\n YYYY: d.getFullYear(),\r\n MM: String(d.getMonth() + 1).padStart(2, \"0\"),\r\n DD: String(d.getDate()).padStart(2, \"0\"),\r\n HH: String(d.getHours()).padStart(2, \"0\"),\r\n mm: String(d.getMinutes()).padStart(2, \"0\"),\r\n ss: String(d.getSeconds()).padStart(2, \"0\"),\r\n };\r\n\r\n return pattern.replace(/YYYY|MM|DD|HH|mm|ss/g, (matched) => map[matched]);\r\n};\r\n\r\n/**\r\n * Returns a human-readable relative time (e.g., \"5 minutes ago\")\r\n * @param {Date|string|number} date\r\n * @returns {string}\r\n */\r\nexport const relativeTime = (date) => {\r\n const d = new Date(date);\r\n const now = new Date();\r\n const diff = Math.floor((now - d) / 1000);\r\n\r\n if (diff < 60) return \"just now\";\r\n if (diff < 3600) return `${Math.floor(diff / 60)} minutes ago`;\r\n if (diff < 86400) return `${Math.floor(diff / 3600)} hours ago`;\r\n if (diff < 2592000) return `${Math.floor(diff / 86400)} days ago`;\r\n\r\n return formatDate(d);\r\n};\r\n\r\n/**\r\n * Add days to a date\r\n * @param {Date|string|number} date\r\n * @param {number} days\r\n * @returns {Date}\r\n */\r\nexport const addDays = (date, days) => {\r\n const d = new Date(date);\r\n d.setDate(d.getDate() + days);\r\n return d;\r\n};\r\n\r\n/**\r\n * Check if two dates are the same day\r\n * @param {Date} d1\r\n * @param {Date} d2\r\n * @returns {boolean}\r\n */\r\nexport const isSameDay = (d1, d2) => {\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n};\r\n","/**\r\n * Formatting Utilities\r\n * Tools for number, currency, and string formatting.\r\n */\r\n\r\n/**\r\n * Currency Formatter\r\n * @param {number} amount\r\n * @param {string} locale - Default: 'id-ID'\r\n * @param {string} currency - Default: 'IDR'\r\n * @returns {string}\r\n */\r\nexport const currency = (amount, locale = \"id-ID\", currency = \"IDR\") => {\r\n return new Intl.NumberFormat(locale, {\r\n style: \"currency\",\r\n currency: currency,\r\n }).format(amount);\r\n};\r\n\r\n/**\r\n * Number Formatter with decimals\r\n * @param {number} n\r\n * @param {number} decimals - Default: 0\r\n * @returns {string}\r\n */\r\nexport const number = (n, decimals = 0) => {\r\n return new Intl.NumberFormat(\"id-ID\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(n);\r\n};\r\n\r\n/**\r\n * Truncate string with ellipsis\r\n * @param {string} str\r\n * @param {number} length - Default: 30\r\n * @returns {string}\r\n */\r\nexport const truncate = (str, length = 30) => {\r\n if (!str) return \"\";\r\n return str.length > length ? str.substring(0, length) + \"...\" : str;\r\n};\r\n\r\n/**\r\n * Convert string to slug (URL friendly)\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nexport const slugify = (str) => {\r\n if (!str) return \"\";\r\n return str\r\n .toLowerCase()\r\n .trim()\r\n .replace(/[^\\w\\s-]/g, \"\")\r\n .replace(/[\\s_-]+/g, \"-\")\r\n .replace(/^-+|-+$/g, \"\");\r\n};\r\n\r\n/**\r\n * Capitalize first letter of each word\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nexport const capitalize = (str) => {\r\n if (!str) return \"\";\r\n return str.replace(/\\b\\w/g, (l) => l.toUpperCase());\r\n};\r\n","/**\r\n * Validation Utilities\r\n * Common regex-based validation helpers.\r\n */\r\n\r\n/**\r\n * Check if string is a valid email\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isEmail = (str) => {\r\n const re = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n return re.test(str);\r\n};\r\n\r\n/**\r\n * Check if string is a valid URL\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isURL = (str) => {\r\n try {\r\n new URL(str);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Check if string contains only numbers\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isNumeric = (str) => {\r\n return /^\\d+$/.test(str);\r\n};\r\n\r\n/**\r\n * Check for strong password\r\n * (Min 8 chars, 1 uppercase, 1 lowercase, 1 number)\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isStrongPassword = (str) => {\r\n return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$/.test(str);\r\n};\r\n\r\n/**\r\n * Check if string is empty or only whitespace\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isEmpty = (str) => {\r\n return !str || str.trim().length === 0;\r\n};\r\n"],"names":["this"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/dom.js","../src/http.js","../src/storage.js","../src/state.js","../src/utils.js","../src/date.js","../src/format.js","../src/validation.js","../src/device.js","../src/color.js","../src/url.js","../src/file.js"],"sourcesContent":["/**\r\n * DOM Utilities\r\n * Premium query selectors and manipulation tools.\r\n */\r\n\r\n/**\r\n * Higher performance querySelector wrapper\r\n * @param {string} selector\r\n * @param {HTMLElement|Document} context\r\n * @returns {HTMLElement|null}\r\n */\r\nexport const $ = (selector, context = document) => {\r\n return context.querySelector(selector);\r\n};\r\n\r\n/**\r\n * querySelectorAll wrapper that returns an array instead of a NodeList\r\n * @param {string} selector\r\n * @param {HTMLElement|Document} context\r\n * @returns {HTMLElement[]}\r\n */\r\nexport const $$ = (selector, context = document) => {\r\n return Array.from(context.querySelectorAll(selector));\r\n};\r\n\r\n/**\r\n * Create element with attributes and styles\r\n * @param {string} tag\r\n * @param {Object} options\r\n * @returns {HTMLElement}\r\n */\r\nexport const create = (tag, options = {}) => {\r\n const el = document.createElement(tag);\r\n const {\r\n attr = {},\r\n style = {},\r\n text = \"\",\r\n html = \"\",\r\n children = [],\r\n } = options;\r\n\r\n Object.entries(attr).forEach(([k, v]) => el.setAttribute(k, v));\r\n Object.assign(el.style, style);\r\n\r\n if (text) el.textContent = text;\r\n if (html) el.innerHTML = html;\r\n\r\n children.forEach((child) => {\r\n if (child instanceof HTMLElement) el.appendChild(child);\r\n else el.append(child);\r\n });\r\n\r\n return el;\r\n};\r\n\r\n/**\r\n * Event delegation helper\r\n * @param {HTMLElement|Document} parent\r\n * @param {string} event\r\n * @param {string} selector\r\n * @param {Function} handler\r\n */\r\nexport const on = (parent, event, selector, handler) => {\r\n parent.addEventListener(event, (e) => {\r\n const target = e.target.closest(selector);\r\n if (target && parent.contains(target)) {\r\n handler.call(target, e, target);\r\n }\r\n });\r\n};\r\n","/**\r\n * HTTP Utilities\r\n * Clean Fetch API wrapper with easy JSON handling and interceptors.\r\n */\r\n\r\nconst request = async (url, options = {}) => {\r\n const {\r\n method = \"GET\",\r\n headers = {},\r\n body = null,\r\n interceptors = { request: [], response: [] },\r\n } = options;\r\n\r\n let config = {\r\n method,\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n };\r\n\r\n if (body && typeof body === \"object\") {\r\n config.body = JSON.stringify(body);\r\n } else if (body) {\r\n config.body = body;\r\n }\r\n\r\n // Request Interceptors\r\n interceptors.request.forEach((fn) => {\r\n config = fn(config) || config;\r\n });\r\n\r\n try {\r\n const response = await fetch(url, config);\r\n let data = await response.json().catch(() => null);\r\n\r\n // Response Interceptors\r\n interceptors.response.forEach((fn) => {\r\n data = fn(data, response) || data;\r\n });\r\n\r\n if (!response.ok) {\r\n throw { status: response.status, data };\r\n }\r\n\r\n return data;\r\n } catch (error) {\r\n console.error(\"Fetch Error:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\nexport const http = {\r\n get: (url, options) => request(url, { ...options, method: \"GET\" }),\r\n post: (url, body, options) =>\r\n request(url, { ...options, method: \"POST\", body }),\r\n put: (url, body, options) =>\r\n request(url, { ...options, method: \"PUT\", body }),\r\n delete: (url, options) => request(url, { ...options, method: \"DELETE\" }),\r\n};\r\n","/**\r\n * Storage Utilities\r\n * Type-safe and auto-serialized local/session storage.\r\n */\r\n\r\nconst createStorage = (type = \"localStorage\") => {\r\n const storage = window[type];\r\n\r\n return {\r\n /**\r\n * Set item with auto-serialization\r\n * @param {string} key\r\n * @param {any} value\r\n */\r\n set(key, value) {\r\n try {\r\n const serialized = JSON.stringify(value);\r\n storage.setItem(key, serialized);\r\n } catch (e) {\r\n console.error(`Storage Error (set): ${key}`, e);\r\n }\r\n },\r\n\r\n /**\r\n * Get item with auto-deserialization\r\n * @param {string} key\r\n * @param {any} fallback\r\n * @returns {any}\r\n */\r\n get(key, fallback = null) {\r\n try {\r\n const item = storage.getItem(key);\r\n return item ? JSON.parse(item) : fallback;\r\n } catch (e) {\r\n console.error(`Storage Error (get): ${key}`, e);\r\n return fallback;\r\n }\r\n },\r\n\r\n /**\r\n * Remove item\r\n * @param {string} key\r\n */\r\n remove(key) {\r\n storage.removeItem(key);\r\n },\r\n\r\n /**\r\n * Clear all items\r\n */\r\n clear() {\r\n storage.clear();\r\n },\r\n };\r\n};\r\n\r\nexport const local = createStorage(\"localStorage\");\r\nexport const session = createStorage(\"sessionStorage\");\r\n","/**\r\n * State Management\r\n * A tiny reactive store (inspired by Svelte stores).\r\n */\r\n\r\n/**\r\n * Creates a reactive store\r\n * @param {any} initialValue\r\n * @returns {Object}\r\n */\r\nexport const createStore = (initialValue) => {\r\n let value = initialValue;\r\n const subscribers = new Set();\r\n\r\n /**\r\n * Subscribe to changes\r\n * @param {Function} fn\r\n * @returns {Function} Unsubscribe function\r\n */\r\n const subscribe = (fn) => {\r\n subscribers.add(fn);\r\n fn(value);\r\n return () => subscribers.delete(fn);\r\n };\r\n\r\n /**\r\n * Update value and notify subscribers\r\n * @param {any|Function} newValue\r\n */\r\n const update = (newValue) => {\r\n if (typeof newValue === \"function\") {\r\n value = newValue(value);\r\n } else {\r\n value = newValue;\r\n }\r\n subscribers.forEach((fn) => fn(value));\r\n };\r\n\r\n /**\r\n * Get current value\r\n * @returns {any}\r\n */\r\n const get = () => value;\r\n\r\n return { subscribe, update, get };\r\n};\r\n","/**\r\n * General Utilities\r\n * Common helper functions.\r\n */\r\n\r\n/**\r\n * Debounce function\r\n * @param {Function} fn\r\n * @param {number} delay\r\n * @returns {Function}\r\n */\r\nexport const debounce = (fn, delay = 300) => {\r\n let timeout;\r\n return (...args) => {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => fn.apply(this, args), delay);\r\n };\r\n};\r\n\r\n/**\r\n * Throttle function\r\n * @param {Function} fn\r\n * @param {number} limit\r\n * @returns {Function}\r\n */\r\nexport const throttle = (fn, limit = 300) => {\r\n let lastFunc;\r\n let lastRan;\r\n return (...args) => {\r\n if (!lastRan) {\r\n fn.apply(this, args);\r\n lastRan = Date.now();\r\n } else {\r\n clearTimeout(lastFunc);\r\n lastFunc = setTimeout(\r\n () => {\r\n if (Date.now() - lastRan >= limit) {\r\n fn.apply(this, args);\r\n lastRan = Date.now();\r\n }\r\n },\r\n limit - (Date.now() - lastRan),\r\n );\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * Deep clone an object\r\n * @param {any} obj\r\n * @returns {any}\r\n */\r\nexport const deepClone = (obj) => {\r\n if (obj === null || typeof obj !== \"object\") return obj;\r\n return JSON.parse(JSON.stringify(obj));\r\n};\r\n\r\n/**\r\n * Generates a simple UUID-like string\r\n * @returns {string}\r\n */\r\nexport const uuid = () => {\r\n return (\r\n Math.random().toString(36).substring(2, 10) +\r\n Date.now().toString(36).substring(2, 6)\r\n );\r\n};\r\n","/**\r\n * Date Utilities\r\n * Simple and efficient date formatting and manipulation.\r\n */\r\n\r\n/**\r\n * Basic Date Formatter\r\n * @param {Date|string|number} date\r\n * @param {string} pattern - Default: 'YYYY-MM-DD'\r\n * @returns {string}\r\n */\r\nexport const formatDate = (date, pattern = \"YYYY-MM-DD\") => {\r\n const d = new Date(date);\r\n if (isNaN(d.getTime())) return \"Invalid Date\";\r\n\r\n const map = {\r\n YYYY: d.getFullYear(),\r\n MM: String(d.getMonth() + 1).padStart(2, \"0\"),\r\n DD: String(d.getDate()).padStart(2, \"0\"),\r\n HH: String(d.getHours()).padStart(2, \"0\"),\r\n mm: String(d.getMinutes()).padStart(2, \"0\"),\r\n ss: String(d.getSeconds()).padStart(2, \"0\"),\r\n };\r\n\r\n return pattern.replace(/YYYY|MM|DD|HH|mm|ss/g, (matched) => map[matched]);\r\n};\r\n\r\n/**\r\n * Returns a human-readable relative time (e.g., \"5 minutes ago\")\r\n * @param {Date|string|number} date\r\n * @returns {string}\r\n */\r\nexport const relativeTime = (date) => {\r\n const d = new Date(date);\r\n const now = new Date();\r\n const diff = Math.floor((now - d) / 1000);\r\n\r\n if (diff < 60) return \"just now\";\r\n if (diff < 3600) return `${Math.floor(diff / 60)} minutes ago`;\r\n if (diff < 86400) return `${Math.floor(diff / 3600)} hours ago`;\r\n if (diff < 2592000) return `${Math.floor(diff / 86400)} days ago`;\r\n\r\n return formatDate(d);\r\n};\r\n\r\n/**\r\n * Add days to a date\r\n * @param {Date|string|number} date\r\n * @param {number} days\r\n * @returns {Date}\r\n */\r\nexport const addDays = (date, days) => {\r\n const d = new Date(date);\r\n d.setDate(d.getDate() + days);\r\n return d;\r\n};\r\n\r\n/**\r\n * Check if two dates are the same day\r\n * @param {Date} d1\r\n * @param {Date} d2\r\n * @returns {boolean}\r\n */\r\nexport const isSameDay = (d1, d2) => {\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n};\r\n","/**\r\n * Formatting Utilities\r\n * Tools for number, currency, and string formatting.\r\n */\r\n\r\n/**\r\n * Currency Formatter\r\n * @param {number} amount\r\n * @param {string} locale - Default: 'id-ID'\r\n * @param {string} currency - Default: 'IDR'\r\n * @returns {string}\r\n */\r\nexport const currency = (amount, locale = \"id-ID\", currency = \"IDR\") => {\r\n return new Intl.NumberFormat(locale, {\r\n style: \"currency\",\r\n currency: currency,\r\n }).format(amount);\r\n};\r\n\r\n/**\r\n * Number Formatter with decimals\r\n * @param {number} n\r\n * @param {number} decimals - Default: 0\r\n * @returns {string}\r\n */\r\nexport const number = (n, decimals = 0) => {\r\n return new Intl.NumberFormat(\"id-ID\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(n);\r\n};\r\n\r\n/**\r\n * Truncate string with ellipsis\r\n * @param {string} str\r\n * @param {number} length - Default: 30\r\n * @returns {string}\r\n */\r\nexport const truncate = (str, length = 30) => {\r\n if (!str) return \"\";\r\n return str.length > length ? str.substring(0, length) + \"...\" : str;\r\n};\r\n\r\n/**\r\n * Convert string to slug (URL friendly)\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nexport const slugify = (str) => {\r\n if (!str) return \"\";\r\n return str\r\n .toLowerCase()\r\n .trim()\r\n .replace(/[^\\w\\s-]/g, \"\")\r\n .replace(/[\\s_-]+/g, \"-\")\r\n .replace(/^-+|-+$/g, \"\");\r\n};\r\n\r\n/**\r\n * Capitalize first letter of each word\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nexport const capitalize = (str) => {\r\n if (!str) return \"\";\r\n return str.replace(/\\b\\w/g, (l) => l.toUpperCase());\r\n};\r\n","/**\r\n * Validation Utilities\r\n * Common regex-based validation helpers.\r\n */\r\n\r\n/**\r\n * Check if string is a valid email\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isEmail = (str) => {\r\n const re = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n return re.test(str);\r\n};\r\n\r\n/**\r\n * Check if string is a valid URL\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isURL = (str) => {\r\n try {\r\n new URL(str);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Check if string contains only numbers\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isNumeric = (str) => {\r\n return /^\\d+$/.test(str);\r\n};\r\n\r\n/**\r\n * Check for strong password\r\n * (Min 8 chars, 1 uppercase, 1 lowercase, 1 number)\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isStrongPassword = (str) => {\r\n return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$/.test(str);\r\n};\r\n\r\n/**\r\n * Check if string is empty or only whitespace\r\n * @param {string} str\r\n * @returns {boolean}\r\n */\r\nexport const isEmpty = (str) => {\r\n return !str || str.trim().length === 0;\r\n};\r\n","/**\r\n * Device Utilities\r\n * Helpers for device detection and clipboard interaction.\r\n */\r\n\r\n/**\r\n * Copy text to clipboard (modern & fallback)\r\n * @param {string} text\r\n * @returns {Promise<boolean>}\r\n */\r\nexport const copyToClipboard = async (text) => {\r\n try {\r\n if (navigator.clipboard) {\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n } else {\r\n // Fallback for older browsers\r\n const textArea = document.createElement(\"textarea\");\r\n textArea.value = text;\r\n textArea.style.position = \"fixed\";\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n const success = document.execCommand(\"copy\");\r\n document.body.removeChild(textArea);\r\n return success;\r\n }\r\n } catch (err) {\r\n console.error(\"Failed to copy:\", err);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Check if device is mobile (based on User Agent)\r\n * @returns {boolean}\r\n */\r\nexport const isMobile = () => {\r\n const ua = navigator.userAgent;\r\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\r\n ua,\r\n );\r\n};\r\n\r\n/**\r\n * Get simple OS name\r\n * @returns {'iOS' | 'Android' | 'Windows' | 'Mac' | 'Linux' | 'Unknown'}\r\n */\r\nexport const getOS = () => {\r\n const ua = navigator.userAgent;\r\n if (/iPad|iPhone|iPod/.test(ua)) return \"iOS\";\r\n if (/Android/.test(ua)) return \"Android\";\r\n if (/Win/.test(ua)) return \"Windows\";\r\n if (/Mac/.test(ua)) return \"Mac\";\r\n if (/Linux/.test(ua)) return \"Linux\";\r\n return \"Unknown\";\r\n};\r\n\r\n/**\r\n * Check if user prefers dark mode\r\n * @returns {boolean}\r\n */\r\nexport const isDarkMode = () => {\r\n return (\r\n window.matchMedia &&\r\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches\r\n );\r\n};\r\n","/**\r\n * Color Utilities\r\n * Manipulate arrays, hex, and RGB.\r\n */\r\n\r\n/**\r\n * Convert Hex to RGB\r\n * @param {string} hex\r\n * @returns {{r: number, g: number, b: number} | null}\r\n */\r\nexport const hexToRgb = (hex) => {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : null;\r\n};\r\n\r\n/**\r\n * Convert RGB to Hex\r\n * @param {number} r\r\n * @param {number} g\r\n * @param {number} b\r\n * @returns {string}\r\n */\r\nexport const rgbToHex = (r, g, b) => {\r\n return \"#\" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\r\n};\r\n\r\n/**\r\n * Lighten a color by percentage\r\n * @param {string} color - Hex color\r\n * @param {number} percent - -100 to 100\r\n * @returns {string}\r\n */\r\nexport const lighten = (color, percent) => {\r\n let num = parseInt(color.replace(\"#\", \"\"), 16),\r\n amt = Math.round(2.55 * percent),\r\n R = (num >> 16) + amt,\r\n B = ((num >> 8) & 0x00ff) + amt,\r\n G = (num & 0x0000ff) + amt;\r\n\r\n return (\r\n \"#\" +\r\n (\r\n 0x1000000 +\r\n (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +\r\n (B < 255 ? (B < 1 ? 0 : B) : 255) * 0x100 +\r\n (G < 255 ? (G < 1 ? 0 : G) : 255)\r\n )\r\n .toString(16)\r\n .slice(1)\r\n );\r\n};\r\n\r\n/**\r\n * Darken a color (alias for lighten with negative percent)\r\n * @param {string} color\r\n * @param {number} percent\r\n * @returns {string}\r\n */\r\nexport const darken = (color, percent) => {\r\n return lighten(color, -percent);\r\n};\r\n\r\n/**\r\n * Generate a random hex color\r\n * @returns {string}\r\n */\r\nexport const randomColor = () => {\r\n return (\r\n \"#\" +\r\n Math.floor(Math.random() * 16777215)\r\n .toString(16)\r\n .padStart(6, \"0\")\r\n );\r\n};\r\n","/**\r\n * URL Utilities\r\n * Easy query parameter manipulation and URL helpers.\r\n */\r\n\r\n/**\r\n * Get a query parameter value from URL\r\n * @param {string} key\r\n * @param {string} url - Default: window.location.href\r\n * @returns {string|null}\r\n */\r\nexport const getParam = (key, url = window.location.href) => {\r\n const searchParams = new URL(url).searchParams;\r\n return searchParams.get(key);\r\n};\r\n\r\n/**\r\n * Get all query parameters as an object\r\n * @param {string} url\r\n * @returns {Object}\r\n */\r\nexport const getQueryParams = (url = window.location.href) => {\r\n const searchParams = new URL(url).searchParams;\r\n const params = {};\r\n for (const [key, value] of searchParams.entries()) {\r\n params[key] = value;\r\n }\r\n return params;\r\n};\r\n\r\n/**\r\n * Update a query parameter in the URL without reloading\r\n * @param {string} key\r\n * @param {string} value\r\n */\r\nexport const updateParam = (key, value) => {\r\n const url = new URL(window.location.href);\r\n if (value) {\r\n url.searchParams.set(key, value);\r\n } else {\r\n url.searchParams.delete(key);\r\n }\r\n window.history.pushState({}, \"\", url);\r\n};\r\n\r\n/**\r\n * Remove a query parameter\r\n * @param {string} key\r\n */\r\nexport const removeParam = (key) => {\r\n updateParam(key, null);\r\n};\r\n\r\n/**\r\n * Determine if URL is absolute\r\n * @param {string} url\r\n * @returns {boolean}\r\n */\r\nexport const isAbsoluteURL = (url) => {\r\n return /^[a-z][a-z0-9+.-]*:/.test(url);\r\n};\r\n","/**\r\n * File & Image Utilities\r\n * Tools for base64 conversion, preloading, and file extension handling.\r\n */\r\n\r\n/**\r\n * Convert File/Blob to Base64\r\n * @param {File|Blob} file\r\n * @returns {Promise<string>}\r\n */\r\nexport const toBase64 = (file) => {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.readAsDataURL(file);\r\n reader.onload = () => resolve(reader.result);\r\n reader.onerror = (error) => reject(error);\r\n });\r\n};\r\n\r\n/**\r\n * Preload an image URL\r\n * @param {string} url\r\n * @returns {Promise<void>}\r\n */\r\nexport const preloadImage = (url) => {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.src = url;\r\n img.onload = () => resolve();\r\n img.onerror = () => reject();\r\n });\r\n};\r\n\r\n/**\r\n * Get file extension from filename\r\n * @param {string} filename\r\n * @returns {string}\r\n */\r\nexport const getFileExtension = (filename) => {\r\n return filename.slice(((filename.lastIndexOf(\".\") - 1) >>> 0) + 2);\r\n};\r\n\r\n/**\r\n * Check if file is an image\r\n * @param {File} file\r\n * @returns {boolean}\r\n */\r\nexport const isImage = (file) => {\r\n return file && file.type.startsWith(\"image/\");\r\n};\r\n\r\n/**\r\n * Calculate human-readable file size\r\n * @param {number} bytes\r\n * @returns {string}\r\n */\r\nexport const formatFileSize = (bytes) => {\r\n if (bytes === 0) return \"0 Bytes\";\r\n const k = 1024;\r\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\r\n};\r\n"],"names":["this"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,KAAK;AACnD,EAAE,OAAO,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AACzC,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,KAAK;AACpD,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxD,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,KAAK;AAC7C,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AACzC,EAAE,MAAM;AACR,IAAI,IAAI,GAAG,EAAE;AACb,IAAI,KAAK,GAAG,EAAE;AACd,IAAI,IAAI,GAAG,EAAE;AACb,IAAI,IAAI,GAAG,EAAE;AACb,IAAI,QAAQ,GAAG,EAAE;AACjB,GAAG,GAAG,OAAO,CAAC;AACd;AACA,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACjC;AACA,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;AAClC,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,SAAS,GAAG,IAAI,CAAC;AAChC;AACA,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK;AAC9B,IAAI,IAAI,KAAK,YAAY,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AAC5D,SAAS,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1B,EAAE,CAAC,CAAC,CAAC;AACL;AACA,EAAE,OAAO,EAAE,CAAC;AACZ,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,KAAK;AACxD,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK;AACxC,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9C,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC3C,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AACtC,IAAI,CAAC;AACL,EAAE,CAAC,CAAC,CAAC;AACL;;ACrEA;AACA;AACA;AACA;AACA;AACA,MAAM,OAAO,GAAG,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,KAAK;AAC7C,EAAE,MAAM;AACR,IAAI,MAAM,GAAG,KAAK;AAClB,IAAI,OAAO,GAAG,EAAE;AAChB,IAAI,IAAI,GAAG,IAAI;AACf,IAAI,YAAY,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;AAChD,GAAG,GAAG,OAAO,CAAC;AACd;AACA,EAAE,IAAI,MAAM,GAAG;AACf,IAAI,MAAM;AACV,IAAI,OAAO,EAAE;AACb,MAAM,cAAc,EAAE,kBAAkB;AACxC,MAAM,GAAG,OAAO;AAChB,KAAK;AACL,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AACxC,IAAI,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACvC,EAAE,CAAC,MAAM,IAAI,IAAI,EAAE;AACnB,IAAI,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;AACvB,EAAE,CAAC;AACH;AACA;AACA,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK;AACvC,IAAI,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;AAClC,EAAE,CAAC,CAAC,CAAC;AACL;AACA,EAAE,IAAI;AACN,IAAI,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC9C,IAAI,IAAI,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;AACvD;AACA;AACA,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK;AAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC;AACxC,IAAI,CAAC,CAAC,CAAC;AACP;AACA,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AACtB,MAAM,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AAC9C,IAAI,CAAC;AACL;AACA,IAAI,OAAO,IAAI,CAAC;AAChB,EAAE,CAAC,CAAC,OAAO,KAAK,EAAE;AAClB,IAAI,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AACzC,IAAI,MAAM,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACY,MAAC,IAAI,GAAG;AACpB,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACpE,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO;AAC3B,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACtD,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO;AAC1B,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACrD,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC1E;;AC3DA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAa,GAAG,CAAC,IAAI,GAAG,cAAc,KAAK;AACjD,EAAE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B;AACA,EAAE,OAAO;AACT;AACA;AACA;AACA;AACA;AACA,IAAI,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE;AACpB,MAAM,IAAI;AACV,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACjD,QAAQ,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AACzC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;AAClB,QAAQ,OAAO,CAAC,KAAK,CAAC,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,MAAM,CAAC;AACP,IAAI,CAAC;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,EAAE;AAC9B,MAAM,IAAI;AACV,QAAQ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC1C,QAAQ,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;AAClD,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;AAClB,QAAQ,OAAO,CAAC,KAAK,CAAC,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,QAAQ,OAAO,QAAQ,CAAC;AACxB,MAAM,CAAC;AACP,IAAI,CAAC;AACL;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,CAAC,GAAG,EAAE;AAChB,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC9B,IAAI,CAAC;AACL;AACA;AACA;AACA;AACA,IAAI,KAAK,GAAG;AACZ,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;AACtB,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,CAAC,CAAC;AACF;AACY,MAAC,KAAK,GAAG,aAAa,CAAC,cAAc,EAAE;AACvC,MAAC,OAAO,GAAG,aAAa,CAAC,gBAAgB;;ACzDrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,YAAY,KAAK;AAC7C,EAAE,IAAI,KAAK,GAAG,YAAY,CAAC;AAC3B,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,SAAS,GAAG,CAAC,EAAE,KAAK;AAC5B,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACxB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AACd,IAAI,OAAO,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACxC,EAAE,CAAC,CAAC;AACJ;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,MAAM,GAAG,CAAC,QAAQ,KAAK;AAC/B,IAAI,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;AACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9B,IAAI,CAAC,MAAM;AACX,MAAM,KAAK,GAAG,QAAQ,CAAC;AACvB,IAAI,CAAC;AACL,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3C,EAAE,CAAC,CAAC;AACJ;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC;AAC1B;AACA,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACpC;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,GAAG,KAAK;AAC7C,EAAE,IAAI,OAAO,CAAC;AACd,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK;AACtB,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;AAC1B,IAAI,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,CAACA,SAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5D,EAAE,CAAC,CAAC;AACJ,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,GAAG,KAAK;AAC7C,EAAE,IAAI,QAAQ,CAAC;AACf,EAAE,IAAI,OAAO,CAAC;AACd,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK;AACtB,IAAI,IAAI,CAAC,OAAO,EAAE;AAClB,MAAM,EAAE,CAAC,KAAK,CAACA,SAAI,EAAE,IAAI,CAAC,CAAC;AAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC3B,IAAI,CAAC,MAAM;AACX,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;AAC7B,MAAM,QAAQ,GAAG,UAAU;AAC3B,QAAQ,MAAM;AACd,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,KAAK,EAAE;AAC7C,YAAY,EAAE,CAAC,KAAK,CAACA,SAAI,EAAE,IAAI,CAAC,CAAC;AACjC,YAAY,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AACjC,UAAU,CAAC;AACX,QAAQ,CAAC;AACT,QAAQ,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;AACtC,OAAO,CAAC;AACR,IAAI,CAAC;AACL,EAAE,CAAC,CAAC;AACJ,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,SAAS,GAAG,CAAC,GAAG,KAAK;AAClC,EAAE,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,OAAO,GAAG,CAAC;AAC1D,EAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,IAAI,GAAG,MAAM;AAC1B,EAAE;AACF,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;AAC/C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;AAC3C,IAAI;AACJ;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,UAAU,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,KAAK;AAC5D,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,cAAc,CAAC;AAChD;AACA,EAAE,MAAM,GAAG,GAAG;AACd,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE;AACzB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACjD,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAC5C,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAC7C,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAC/C,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAC/C,GAAG,CAAC;AACJ;AACA,EAAE,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5E,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,YAAY,GAAG,CAAC,IAAI,KAAK;AACtC,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,EAAE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AACzB,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;AAC5C;AACA,EAAE,IAAI,IAAI,GAAG,EAAE,EAAE,OAAO,UAAU,CAAC;AACnC,EAAE,IAAI,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;AACjE,EAAE,IAAI,IAAI,GAAG,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;AAClE,EAAE,IAAI,IAAI,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;AACpE;AACA,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK;AACvC,EAAE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AAChC,EAAE,OAAO,CAAC,CAAC;AACX,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,SAAS,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK;AACrC,EAAE;AACF,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE;AACzC,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE;AACnC,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE;AACjC,IAAI;AACJ;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,QAAQ,GAAG,KAAK,KAAK;AACxE,EAAE,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;AACvC,IAAI,KAAK,EAAE,UAAU;AACrB,IAAI,QAAQ,EAAE,QAAQ;AACtB,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACpB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,MAAM,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,KAAK;AAC3C,EAAE,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;AACxC,IAAI,qBAAqB,EAAE,QAAQ;AACnC,IAAI,qBAAqB,EAAE,QAAQ;AACnC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACf,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK;AAC9C,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC;AACtB,EAAE,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC;AACtE,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,GAAG,KAAK;AAChC,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC;AACtB,EAAE,OAAO,GAAG;AACZ,KAAK,WAAW,EAAE;AAClB,KAAK,IAAI,EAAE;AACX,KAAK,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;AAC7B,KAAK,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;AAC7B,KAAK,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,UAAU,GAAG,CAAC,GAAG,KAAK;AACnC,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC;AACtB,EAAE,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACtD;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,GAAG,KAAK;AAChC,EAAE,MAAM,EAAE,GAAG,4BAA4B,CAAC;AAC1C,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,KAAK,GAAG,CAAC,GAAG,KAAK;AAC9B,EAAE,IAAI;AACN,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AACjB,IAAI,OAAO,IAAI,CAAC;AAChB,EAAE,CAAC,CAAC,MAAM;AACV,IAAI,OAAO,KAAK,CAAC;AACjB,EAAE,CAAC;AACH,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,SAAS,GAAG,CAAC,GAAG,KAAK;AAClC,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,gBAAgB,GAAG,CAAC,GAAG,KAAK;AACzC,EAAE,OAAO,uCAAuC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3D,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,GAAG,KAAK;AAChC,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;AACzC;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,eAAe,GAAG,OAAO,IAAI,KAAK;AAC/C,EAAE,IAAI;AACN,IAAI,IAAI,SAAS,CAAC,SAAS,EAAE;AAC7B,MAAM,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAChD,MAAM,OAAO,IAAI,CAAC;AAClB,IAAI,CAAC,MAAM;AACX;AACA,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;AAC1D,MAAM,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;AAC5B,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;AACxC,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;AACvB,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;AACxB,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACnD,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,OAAO,OAAO,CAAC;AACrB,IAAI,CAAC;AACL,EAAE,CAAC,CAAC,OAAO,GAAG,EAAE;AAChB,IAAI,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;AAC1C,IAAI,OAAO,KAAK,CAAC;AACjB,EAAE,CAAC;AACH,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,MAAM;AAC9B,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC;AACjC,EAAE,OAAO,gEAAgE,CAAC,IAAI;AAC9E,IAAI,EAAE;AACN,GAAG,CAAC;AACJ,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,KAAK,GAAG,MAAM;AAC3B,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC;AACjC,EAAE,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,KAAK,CAAC;AAChD,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,SAAS,CAAC;AAC3C,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,SAAS,CAAC;AACvC,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,KAAK,CAAC;AACnC,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,OAAO,CAAC;AACvC,EAAE,OAAO,SAAS,CAAC;AACnB,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,UAAU,GAAG,MAAM;AAChC,EAAE;AACF,IAAI,MAAM,CAAC,UAAU;AACrB,IAAI,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO;AAC7D,IAAI;AACJ;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,GAAG,KAAK;AACjC,EAAE,MAAM,MAAM,GAAG,2CAA2C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvE,EAAE,OAAO,MAAM;AACf,MAAM;AACN,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAClC,OAAO;AACP,MAAM,IAAI,CAAC;AACX,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK;AACrC,EAAE,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5E,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK;AAC3C,EAAE,IAAI,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;AAChD,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC;AACpC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,GAAG;AACzB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,MAAM,IAAI,GAAG;AACnC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,QAAQ,IAAI,GAAG,CAAC;AAC/B;AACA,EAAE;AACF,IAAI,GAAG;AACP,IAAI;AACJ,MAAM,SAAS;AACf,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,OAAO;AACjD,MAAM,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,KAAK;AAC/C,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AACvC;AACA,OAAO,QAAQ,CAAC,EAAE,CAAC;AACnB,OAAO,KAAK,CAAC,CAAC,CAAC;AACf,IAAI;AACJ,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK;AAC1C,EAAE,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC;AAClC,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,MAAM;AACjC,EAAE;AACF,IAAI,GAAG;AACP,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC;AACxC,OAAO,QAAQ,CAAC,EAAE,CAAC;AACnB,OAAO,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACvB,IAAI;AACJ;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK;AAC7D,EAAE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;AACjD,EAAE,OAAO,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC/B,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,cAAc,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK;AAC9D,EAAE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;AACjD,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;AACpB,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,EAAE;AACrD,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACxB,EAAE,CAAC;AACH,EAAE,OAAO,MAAM,CAAC;AAChB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,GAAG,EAAE,KAAK,KAAK;AAC3C,EAAE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC5C,EAAE,IAAI,KAAK,EAAE;AACb,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACrC,EAAE,CAAC,MAAM;AACT,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACjC,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AACxC,EAAE;AACF;AACA;AACA;AACA;AACA;AACY,MAAC,WAAW,GAAG,CAAC,GAAG,KAAK;AACpC,EAAE,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACzB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,aAAa,GAAG,CAAC,GAAG,KAAK;AACtC,EAAE,OAAO,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzC;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,QAAQ,GAAG,CAAC,IAAI,KAAK;AAClC,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC1C,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;AACpC,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACjD,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9C,EAAE,CAAC,CAAC,CAAC;AACL,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,YAAY,GAAG,CAAC,GAAG,KAAK;AACrC,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC1C,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;AAC5B,IAAI,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;AAClB,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;AACjC,IAAI,GAAG,CAAC,OAAO,GAAG,MAAM,MAAM,EAAE,CAAC;AACjC,EAAE,CAAC,CAAC,CAAC;AACL,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,gBAAgB,GAAG,CAAC,QAAQ,KAAK;AAC9C,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,OAAO,GAAG,CAAC,IAAI,KAAK;AACjC,EAAE,OAAO,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAChD,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,cAAc,GAAG,CAAC,KAAK,KAAK;AACzC,EAAE,IAAI,KAAK,KAAK,CAAC,EAAE,OAAO,SAAS,CAAC;AACpC,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;AACjB,EAAE,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAClD,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,EAAE,OAAO,UAAU,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}