sveltekit-ui 1.1.17 → 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/Components/Alert/index.svelte +88 -0
  2. package/dist/Components/Alert/index.svelte.js +101 -0
  3. package/dist/Components/ArrowToggle/index.svelte +62 -0
  4. package/dist/Components/Attachment/index.svelte +77 -0
  5. package/dist/Components/Attachment/index.svelte.js +119 -0
  6. package/dist/Components/Audio/index.svelte +193 -0
  7. package/dist/Components/Audio/index.svelte.js +463 -0
  8. package/dist/Components/AudioEditor/index.svelte +252 -0
  9. package/dist/Components/AudioEditor/index.svelte.js +977 -0
  10. package/dist/Components/AudioEditor/samples/alloy-voice-sample.mp3 +0 -0
  11. package/dist/Components/AudioEditor/samples/echo-voice-sample.mp3 +0 -0
  12. package/dist/Components/AudioEditor/samples/fable-voice-sample.mp3 +0 -0
  13. package/dist/Components/AudioEditor/samples/nova-voice-sample.mp3 +0 -0
  14. package/dist/Components/AudioEditor/samples/onyx-voice-sample.mp3 +0 -0
  15. package/dist/Components/AudioEditor/samples/shimmer-voice-sample.mp3 +0 -0
  16. package/dist/Components/AuthCodeInput/index.svelte +85 -0
  17. package/dist/Components/AuthCodeInput/index.svelte.js +95 -0
  18. package/dist/Components/Breadcrumbs/index.svelte +27 -0
  19. package/dist/Components/Breadcrumbs/index.svelte.js +88 -0
  20. package/dist/Components/Button/index.svelte +721 -0
  21. package/dist/Components/Button/index.svelte.js +375 -0
  22. package/dist/Components/Chart/Klines/index.svelte +87 -0
  23. package/dist/Components/Chart/index.svelte +226 -0
  24. package/dist/Components/Chart/index.svelte.js +1090 -0
  25. package/dist/Components/ChartInput/DisplayNav/Klines/index.svelte +150 -0
  26. package/dist/Components/ChartInput/DisplayNav/Lines/index.svelte +45 -0
  27. package/dist/Components/ChartInput/DisplayNav/index.svelte +297 -0
  28. package/dist/Components/ChartInput/EditPanel/index.svelte +155 -0
  29. package/dist/Components/ChartInput/index.svelte +21 -0
  30. package/dist/Components/ChartInput/index.svelte.js +671 -0
  31. package/dist/Components/Checkbox/index.svelte +411 -0
  32. package/dist/Components/Checkbox/index.svelte.js +178 -0
  33. package/dist/Components/Code/index.svelte +23 -0
  34. package/dist/Components/Code/index.svelte.js +33 -0
  35. package/dist/Components/Color/index.svelte +51 -0
  36. package/dist/Components/Color/index.svelte.js +31 -0
  37. package/dist/Components/ColorInput/ChromaPicker/index.svelte +50 -0
  38. package/dist/Components/ColorInput/ColorPalette/index.svelte +62 -0
  39. package/dist/Components/ColorInput/OpacityPicker/index.svelte +68 -0
  40. package/dist/Components/ColorInput/ShowcasePicker/index.svelte +136 -0
  41. package/dist/Components/ColorInput/index.svelte +70 -0
  42. package/dist/Components/ColorInput/index.svelte.js +386 -0
  43. package/dist/Components/ConditionsInput/index.svelte +46 -0
  44. package/dist/Components/ConditionsInput/index.svelte.js +201 -0
  45. package/dist/Components/Confetti/index.svelte +98 -0
  46. package/dist/Components/Confetti/index.svelte.js +94 -0
  47. package/dist/Components/Content/index.svelte +500 -0
  48. package/dist/Components/Content/index.svelte.js +910 -0
  49. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte +31 -0
  50. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte.js +258 -0
  51. package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte +31 -0
  52. package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte.js +258 -0
  53. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte +58 -0
  54. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte.js +206 -0
  55. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte +28 -0
  56. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte.js +224 -0
  57. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte +44 -0
  58. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte.js +272 -0
  59. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte +41 -0
  60. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte.js +202 -0
  61. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte +19 -0
  62. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte.js +117 -0
  63. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte +60 -0
  64. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte.js +542 -0
  65. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte +47 -0
  66. package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte.js +185 -0
  67. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte +35 -0
  68. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte.js +222 -0
  69. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte +20 -0
  70. package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte.js +84 -0
  71. package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte +25 -0
  72. package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte.js +91 -0
  73. package/dist/Components/ContentInput/AttributesInput/index.svelte +352 -0
  74. package/dist/Components/ContentInput/AttributesInput/index.svelte.js +1436 -0
  75. package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte +64 -0
  76. package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte.js +97 -0
  77. package/dist/Components/ContentInput/ContentPanelBuilder/ElementList/index.svelte +184 -0
  78. package/dist/Components/ContentInput/ContentPanelBuilder/index.svelte +41 -0
  79. package/dist/Components/ContentInput/index.svelte +78 -0
  80. package/dist/Components/ContentInput/index.svelte.js +1197 -0
  81. package/dist/Components/CronInput/index.svelte +78 -0
  82. package/dist/Components/CronInput/index.svelte.js +198 -0
  83. package/dist/Components/DataTypeInput/index.svelte +174 -0
  84. package/dist/Components/DataTypeInput/index.svelte.js +565 -0
  85. package/dist/Components/Dropdown/index.svelte +116 -0
  86. package/dist/Components/Dropdown/index.svelte.js +403 -0
  87. package/dist/Components/EmailAddress/index.svelte +22 -0
  88. package/dist/Components/EmailAddress/index.svelte.js +45 -0
  89. package/dist/Components/ErrorX/index.svelte +58 -0
  90. package/dist/Components/Eye/index.svelte +57 -0
  91. package/dist/Components/FileInput/index.svelte +146 -0
  92. package/dist/Components/FileInput/index.svelte.js +225 -0
  93. package/dist/Components/Hamburger/index.svelte +99 -0
  94. package/dist/Components/HorizScrollBox/index.svelte +145 -0
  95. package/dist/Components/Icon/index.svelte +412 -0
  96. package/dist/Components/Icon/index.svelte.js +116 -0
  97. package/dist/Components/IconInput/index.svelte +77 -0
  98. package/dist/Components/IconInput/index.svelte.js +259 -0
  99. package/dist/Components/Image/index.svelte +126 -0
  100. package/dist/Components/Image/index.svelte.js +116 -0
  101. package/dist/Components/ImageEditor/Image/CropBox/index.svelte +165 -0
  102. package/dist/Components/ImageEditor/Image/index.svelte +104 -0
  103. package/dist/Components/ImageEditor/Panels/AI/index.svelte +44 -0
  104. package/dist/Components/ImageEditor/Panels/Crop/index.svelte +96 -0
  105. package/dist/Components/ImageEditor/Panels/File/QualityPicker/index.svelte +124 -0
  106. package/dist/Components/ImageEditor/Panels/File/index.svelte +74 -0
  107. package/dist/Components/ImageEditor/Panels/Filters/index.svelte +46 -0
  108. package/dist/Components/ImageEditor/Panels/Resize/index.svelte +58 -0
  109. package/dist/Components/ImageEditor/index.svelte +93 -0
  110. package/dist/Components/ImageEditor/index.svelte.js +1961 -0
  111. package/dist/Components/ImageSlider/index.svelte +124 -0
  112. package/dist/Components/ImageSlider/index.svelte.js +99 -0
  113. package/dist/Components/InfoBox/index.svelte +89 -0
  114. package/dist/Components/Json/Nested/index.svelte +157 -0
  115. package/dist/Components/Json/index.svelte +60 -0
  116. package/dist/Components/Json/index.svelte.js +594 -0
  117. package/dist/Components/LabeledItem/index.svelte +102 -0
  118. package/dist/Components/Layout/NavBar/FullNav/index.svelte +52 -0
  119. package/dist/Components/Layout/NavBar/NavGuts/index.svelte +87 -0
  120. package/dist/Components/Layout/NavBar/index.svelte +72 -0
  121. package/dist/Components/Layout/index.svelte +149 -0
  122. package/dist/Components/Layout/index.svelte.js +360 -0
  123. package/dist/Components/Link/index.svelte +47 -0
  124. package/dist/Components/Link/index.svelte.js +136 -0
  125. package/dist/Components/LoadingSuccessDiv/index.svelte +51 -0
  126. package/dist/Components/LoadingWheel/index.svelte +38 -0
  127. package/dist/Components/Location/index.svelte +79 -0
  128. package/dist/Components/Location/index.svelte.js +288 -0
  129. package/dist/Components/LocationInput/index.svelte +197 -0
  130. package/dist/Components/LocationInput/index.svelte.js +965 -0
  131. package/dist/Components/Number/index.svelte +47 -0
  132. package/dist/Components/Number/index.svelte.js +151 -0
  133. package/dist/Components/PhoneCountryCode/index.svelte +7 -0
  134. package/dist/Components/PhoneCountryCode/index.svelte.js +260 -0
  135. package/dist/Components/PhoneNumber/index.svelte +22 -0
  136. package/dist/Components/PhoneNumber/index.svelte.js +41 -0
  137. package/dist/Components/Popover/index.svelte +396 -0
  138. package/dist/Components/Popover/index.svelte.js +319 -0
  139. package/dist/Components/Qr/index.svelte +85 -0
  140. package/dist/Components/Qr/index.svelte.js +301 -0
  141. package/dist/Components/QrInput/index.svelte +47 -0
  142. package/dist/Components/QrInput/index.svelte.js +218 -0
  143. package/dist/Components/Slider/index.svelte +239 -0
  144. package/dist/Components/Slider/index.svelte.js +469 -0
  145. package/dist/Components/Spacer/index.svelte +41 -0
  146. package/dist/Components/StoragePicker/DisplayFile/index.svelte +15 -0
  147. package/dist/Components/StoragePicker/index.svelte +187 -0
  148. package/dist/Components/StoragePicker/index.svelte.js +592 -0
  149. package/dist/Components/SuccessCheck/index.svelte +56 -0
  150. package/dist/Components/TableAdvanced/ColumnInput/index.svelte +117 -0
  151. package/dist/Components/TableAdvanced/ColumnInput/index.svelte.js +456 -0
  152. package/dist/Components/TableAdvanced/FilterInput/index.svelte +54 -0
  153. package/dist/Components/TableAdvanced/FilterInput/index.svelte.js +247 -0
  154. package/dist/Components/TableAdvanced/Pagination/index.svelte +43 -0
  155. package/dist/Components/TableAdvanced/Pagination/index.svelte.js +97 -0
  156. package/dist/Components/TableAdvanced/SortByInput/index.svelte +72 -0
  157. package/dist/Components/TableAdvanced/SortByInput/index.svelte.js +176 -0
  158. package/dist/Components/TableAdvanced/index.svelte +275 -0
  159. package/dist/Components/TableAdvanced/index.svelte.js +1565 -0
  160. package/dist/Components/Tag/index.svelte +45 -0
  161. package/dist/Components/Tag/index.svelte.js +76 -0
  162. package/dist/Components/TextArrayInput/index.svelte +108 -0
  163. package/dist/Components/TextArrayInput/index.svelte.js +239 -0
  164. package/dist/Components/TextInput/PasswordTooltip/index.svelte +89 -0
  165. package/dist/Components/TextInput/index.svelte +223 -0
  166. package/dist/Components/TextInput/index.svelte.js +447 -0
  167. package/dist/Components/Time/index.svelte +7 -0
  168. package/dist/Components/Time/index.svelte.js +38 -0
  169. package/dist/Components/TimeInput/NumberToggler/index.svelte +34 -0
  170. package/dist/Components/TimeInput/NumberToggler/index.svelte.js +79 -0
  171. package/dist/Components/TimeInput/index.js +702 -0
  172. package/dist/Components/TimeInput/index.svelte +211 -0
  173. package/dist/Components/TimeInput/index.svelte.js +638 -0
  174. package/dist/Components/Tooltip/index.svelte +143 -0
  175. package/dist/Components/TransparentBackground/index.svelte +153 -0
  176. package/dist/Components/TypingDots/index.svelte +84 -0
  177. package/dist/Components/VariablePathInput/index.svelte +63 -0
  178. package/dist/Components/VariablePathInput/index.svelte.js +273 -0
  179. package/dist/Components/VideoTBD/index.svelte +100 -0
  180. package/dist/Components/XFollow/index.svelte +42 -0
  181. package/dist/Components/XPost/index.svelte +52 -0
  182. package/dist/Components/XPost/index.svelte.js +64 -0
  183. package/dist/Components/YoutubeChannelButton/index.svelte +82 -0
  184. package/dist/Components/YoutubeVideo/index.svelte +73 -0
  185. package/dist/Components/YoutubeVideo/index.svelte.js +54 -0
  186. package/dist/actions/draggable.js +49 -0
  187. package/dist/actions/index.js +24 -0
  188. package/dist/actions/no_spaces.js +33 -0
  189. package/dist/actions/numbers_only.js +26 -0
  190. package/dist/actions/scroll_y.js +28 -0
  191. package/dist/actions/stop_scroll_propagation_y.js +42 -0
  192. package/dist/actions/swipe_handler.js +295 -0
  193. package/dist/client/astc_formatting/index.js +1128 -0
  194. package/dist/client/docs/index.js +7622 -0
  195. package/dist/client/index.js +735 -0
  196. package/dist/client/types/index.js +2812 -0
  197. package/dist/index.js +180 -0
  198. package/dist/style.css +682 -0
  199. package/package.json +1 -1
@@ -0,0 +1,735 @@
1
+ export * from "./types/index.js"
2
+ export * from "./astc_formatting/index.js"
3
+ export {
4
+ time_formats,
5
+ granularities,
6
+ month_names,
7
+ days_of_week_names,
8
+ common_timezones,
9
+ period_iso_8601_to_period_full,
10
+ total_seconds_to_period_full,
11
+ period_full_parts_to_full,
12
+ get_time_full_from_object,
13
+ get_time_object_from_val,
14
+ get_val_from_time_object,
15
+ } from "../Components/TimeInput/index.js"
16
+ export { intersection_observer } from "../actions/index.js"
17
+
18
+ export function format_date(date, is_add_zero = false) {
19
+ if (date) {
20
+ const d = new Date(date * 1000) // convert seconds to milliseconds
21
+ const year = d.getFullYear()
22
+ const month = ((is_add_zero ? "0" : "") + (d.getMonth() + 1)).slice(-2)
23
+ const day = ((is_add_zero ? "0" : "") + d.getDate()).slice(-2)
24
+ return [month, day, year].join("/")
25
+ } else {
26
+ return "mm/dd/yyyy"
27
+ }
28
+ }
29
+
30
+ export function truncate(str, n) {
31
+ return str.length > n ? str.substr(0, n - 1) + "..." : str
32
+ }
33
+
34
+ export function get_obj_from_path(obj, path) {
35
+ let current = obj
36
+ for (let i = 0; i < path.length; i++) {
37
+ if (!(path[i] in current)) return false
38
+ current = current[path[i]]
39
+ }
40
+ return current
41
+ }
42
+
43
+ export function copy_to_clipboard(text) {
44
+ if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
45
+ return navigator.clipboard.writeText(text)
46
+ }
47
+ return Promise.reject("The Clipboard API is not available.")
48
+ }
49
+
50
+ export function get_user_interface() {
51
+ const ua = navigator.userAgent
52
+ let browser_name = "unknown"
53
+ if (ua.indexOf("Firefox") > -1) {
54
+ browser_name = "Mozilla Firefox"
55
+ } else if (ua.indexOf("SamsungBrowser") > -1) {
56
+ browser_name = "Samsung Internet"
57
+ } else if (ua.indexOf("Opera") > -1 || ua.indexOf("OPR") > -1) {
58
+ browser_name = "Opera"
59
+ } else if (ua.indexOf("Trident") > -1) {
60
+ browser_name = "Microsoft Internet Explorer"
61
+ } else if (ua.indexOf("Edge") > -1) {
62
+ browser_name = "Microsoft Edge (Legacy)"
63
+ } else if (ua.indexOf("Edg") > -1) {
64
+ browser_name = "Microsoft Edge (Chromium)"
65
+ } else if (ua.indexOf("Chrome") > -1) {
66
+ browser_name = "Google Chrome or Chromium"
67
+ } else if (ua.indexOf("Safari") > -1) {
68
+ browser_name = "Apple Safari"
69
+ }
70
+ let device_type = "desktop"
71
+ if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
72
+ device_type = "tablet"
73
+ }
74
+ if (/Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {
75
+ device_type = "mobile"
76
+ }
77
+ const interface_data = {
78
+ language: navigator.language,
79
+ languages: navigator.languages,
80
+ platform: navigator.platform,
81
+ // 'platform': navigator.userAgentData.platform, navigator.platform dep but no userAgentData on safari
82
+ vendor: navigator.vendor,
83
+ device_type: device_type,
84
+ browser_name: browser_name,
85
+ used_width: innerWidth,
86
+ used_height: innerHeight,
87
+ avail_height: screen.availHeight,
88
+ avail_width: screen.availWidth,
89
+ window_left: screenLeft,
90
+ window_top: screenTop,
91
+ }
92
+ return interface_data
93
+ }
94
+
95
+ export function color_var(l, c, h, o = 16, is_dark_theme_invert = true) {
96
+ let safe_o = Math.min(Math.max(o, 0), 24)
97
+ let safe_l = Math.min(Math.max(l, 0), 24)
98
+ let safe_c = Math.min(Math.max(c, 0), 24)
99
+ let safe_h = Math.min(Math.max(h, 0), 24)
100
+ return is_dark_theme_invert
101
+ ? `oklch(var(--l${safe_l}-t) var(--c${safe_c}) var(--h${safe_h}) / var(--o${safe_o}))`
102
+ : `oklch(var(--l${safe_l}) var(--c${safe_c}) var(--h${safe_h}) / var(--o${safe_o}))`
103
+ }
104
+
105
+ export function deep_copy(val) {
106
+ return JSON.parse(JSON.stringify(set_closurable(val, null)))
107
+ // return structuredClone(val ?? null)
108
+ }
109
+
110
+ export function is_deep_equal(obj1, obj2) {
111
+ if (obj1 === obj2) return true
112
+ if (typeof obj1 === "object" && obj1 !== null && typeof obj2 === "object" && obj2 !== null) {
113
+ const keys1 = Object.keys(obj1)
114
+ const keys2 = Object.keys(obj2)
115
+ if (keys1.length !== keys2.length) return false
116
+ for (const key of keys1) {
117
+ if (!obj2.hasOwnProperty(key)) return false
118
+ if (!is_deep_equal(obj1[key], obj2[key])) return false
119
+ }
120
+ return true
121
+ } else {
122
+ return obj1 === obj2
123
+ }
124
+ }
125
+
126
+ export function create_unique_id(prefix = null, len = 5) {
127
+ const characters = "abcdefghijklmnopqrstuvwxyz"
128
+ let randstr = ""
129
+ for (let i = 0; i < len; i++) {
130
+ randstr += characters.charAt(Math.floor(Math.random() * characters.length))
131
+ }
132
+ const unique_id = prefix ? `${prefix}_${randstr}` : randstr
133
+ return unique_id
134
+ }
135
+
136
+ export function is_20_char_az_format(id_input) {
137
+ const id_regex = /^[a-z]{20}$/
138
+ return id_regex.test(id_input)
139
+ }
140
+
141
+ export function create_file_name() {
142
+ const now = new Date()
143
+ const start_of_year = new Date(now.getFullYear(), 0, 0)
144
+ const diff = now - start_of_year
145
+ const one_day = 1000 * 60 * 60 * 24
146
+ const day_of_year = Math.floor(diff / one_day)
147
+ const current_year = now.getFullYear().toString()
148
+ const hour = now.getHours().toString().padStart(2, "0")
149
+ const minute = now.getMinutes().toString().padStart(2, "0")
150
+ const seconds = now.getSeconds().toString().padStart(2, "0")
151
+ const random_val = create_unique_id(null, 6)
152
+ return `${current_year}_${day_of_year}_${hour}_${minute}_${seconds}_${random_val}`
153
+ }
154
+
155
+ export function clean_file_name(file_name) {
156
+ if (!file_name) {
157
+ return create_file_name()
158
+ } else {
159
+ const parts = file_name.split(".")
160
+ const base_name = parts.length > 1 ? parts.slice(0, -1).join(".") : file_name
161
+ let cleaned_file_name = base_name
162
+ .replace(/[^a-zA-Z0-9-_\s]/g, "")
163
+ .replace(/[ -]+/g, " ")
164
+ .replace(/(^[ -]+|[ -]+$)/g, "")
165
+ .replace(/-/g, "_")
166
+ .replace(/\s+/g, "_")
167
+ .toLowerCase()
168
+ if (cleaned_file_name.length > 200) {
169
+ cleaned_file_name = cleaned_file_name.substring(0, 200)
170
+ }
171
+ return cleaned_file_name
172
+ }
173
+ }
174
+
175
+ export function clean_custom_identifier(identifier, maximum_length = 100) {
176
+ if ([undefined, null].includes(identifier)) {
177
+ return null
178
+ }
179
+ if (typeof identifier !== "string") {
180
+ identifier = String(identifier)
181
+ }
182
+ if (identifier.length < 1) {
183
+ return null
184
+ }
185
+ let cleaned_identifier = identifier
186
+ .toLowerCase()
187
+ .replace(/[^a-z0-9]/g, "_")
188
+ .replace(/_+/g, "_")
189
+ .replace(/^_+|_+$/g, "")
190
+ if (cleaned_identifier.length > maximum_length) {
191
+ cleaned_identifier = cleaned_identifier.substring(0, maximum_length)
192
+ cleaned_identifier = cleaned_identifier.replace(/_+$/, "")
193
+ }
194
+ return cleaned_identifier
195
+ }
196
+
197
+ export async function url_to_file(src, file_name, mime_type) {
198
+ const response = await fetch(src)
199
+ const data = await response.blob()
200
+ const metadata = {
201
+ type: mime_type || data.type,
202
+ }
203
+ const file = new File([data], file_name, metadata)
204
+ return file
205
+ }
206
+
207
+ export function get_ordinal_suffix(input) {
208
+ if (input % 10 === 1 && input !== 11) {
209
+ return "st"
210
+ } else if (input % 10 === 2 && input !== 12) {
211
+ return "nd"
212
+ } else if (input % 10 === 3 && input !== 13) {
213
+ return "rd"
214
+ } else {
215
+ return "th"
216
+ }
217
+ }
218
+
219
+ export function download_json(data, file_name) {
220
+ const json_string = JSON.stringify(data)
221
+ const data_blob = new Blob([json_string], { type: "application/json" })
222
+ const url = URL.createObjectURL(data_blob)
223
+ const link = document.createElement("a")
224
+ link.href = url
225
+ link.download = file_name ?? "data.json"
226
+ link.click()
227
+ URL.revokeObjectURL(url)
228
+ }
229
+
230
+ export function download_csv(data) {
231
+ const json_string = JSON.stringify(data)
232
+ const csv = json_to_csv(json_string)
233
+ const data_blob = new Blob([csv], { type: "text/csv;charset=utf-8;" })
234
+ const url = URL.createObjectURL(data_blob)
235
+ const link = document.createElement("a")
236
+ link.href = url
237
+ const filename = "data.csv"
238
+ link.download = filename
239
+ link.click()
240
+ URL.revokeObjectURL(url)
241
+ }
242
+
243
+ export function json_to_csv(obj_array) {
244
+ let array = typeof obj_array != "object" ? JSON.parse(obj_array) : obj_array
245
+ let str = ""
246
+ let headers = get_headers(array)
247
+ str += headers.join(",") + "\r\n"
248
+ for (let i = 0; i < array.length; i++) {
249
+ let line = ""
250
+ for (let header_index in headers) {
251
+ let header = headers[header_index]
252
+ let value = get_value_by_path(array?.[i], header.split("__"))
253
+ if (line != "") line += ","
254
+ if (typeof value === "string") {
255
+ value = value.replace(/"/g, '""')
256
+ }
257
+ line += `"${value}"`
258
+ }
259
+ str += line + "\r\n"
260
+ }
261
+ return str
262
+ }
263
+
264
+ export function csv_to_json(csv_text) {
265
+ let rows = []
266
+ let current_row = []
267
+ let current_field = ""
268
+ let in_quotes = false
269
+ csv_text = csv_text.replace(/\\\""/g, "__ESCAPED_QUOTE__")
270
+ for (let i = 0; i < csv_text.length; i++) {
271
+ const char = csv_text[i]
272
+ if (char === '"') {
273
+ if (in_quotes && i + 1 < csv_text.length && csv_text[i + 1] === '"') {
274
+ current_field += '"'
275
+ i++
276
+ } else {
277
+ in_quotes = !in_quotes
278
+ }
279
+ } else if (char === "," && !in_quotes) {
280
+ current_row.push(current_field)
281
+ current_field = ""
282
+ } else if ((char === "\n" || char === "\r") && !in_quotes) {
283
+ if (char === "\r" && i + 1 < csv_text.length && csv_text[i + 1] === "\n") {
284
+ i++
285
+ }
286
+ current_row.push(current_field)
287
+ rows.push(current_row)
288
+ current_row = []
289
+ current_field = ""
290
+ } else {
291
+ current_field += char
292
+ }
293
+ }
294
+ if (current_field !== "" || current_row.length > 0) {
295
+ current_row.push(current_field)
296
+ rows.push(current_row)
297
+ }
298
+ if (rows.length < 2) {
299
+ return []
300
+ }
301
+ const headers = rows[0]
302
+ let data_rows = rows.slice(1)
303
+ const final_result = data_rows.map((row) => {
304
+ const obj = {}
305
+ headers.forEach((header, index) => {
306
+ let val = row[index] === undefined ? "" : row[index].trim()
307
+ if (val.startsWith("{") && val.endsWith("}")) {
308
+ try {
309
+ val = val.replace(/__ESCAPED_QUOTE__/g, '\\"')
310
+ val = JSON.parse(val)
311
+ } catch (e) {
312
+ console.warn("JSON parse error for field:", header, val)
313
+ }
314
+ } else if (val.startsWith("[") && val.endsWith("]")) {
315
+ try {
316
+ val = val.replace(/__ESCAPED_QUOTE__/g, '\\"')
317
+ val = JSON.parse(val)
318
+ } catch (e) {
319
+ console.warn("JSON parse error for field:", header, val)
320
+ }
321
+ } else if (!isNaN(val)) {
322
+ val = Number(val)
323
+ } else if (val.toLowerCase() === "true" || val.toLowerCase() === "false") {
324
+ val = val.toLowerCase() === "true"
325
+ }
326
+ obj[header] = val
327
+ })
328
+ return obj
329
+ })
330
+ return final_result
331
+ }
332
+
333
+ function get_headers(array) {
334
+ let header_set = new Set()
335
+ for (let i = 0; i < array.length; i++) {
336
+ add_keys_to_set(array[i], header_set, "")
337
+ }
338
+ return Array.from(header_set)
339
+ }
340
+
341
+ function add_keys_to_set(obj, set, prefix) {
342
+ for (let key in obj) {
343
+ if (typeof obj[key] === "object" && obj[key] !== null) {
344
+ add_keys_to_set(obj[key], set, prefix + key + "__")
345
+ } else {
346
+ set.add(prefix + key)
347
+ }
348
+ }
349
+ }
350
+
351
+ function get_value_by_path(obj, path) {
352
+ if (Array.isArray(path)) {
353
+ for (let i = 0; i < path.length; i++) {
354
+ if (obj && typeof obj == "object" && obj.hasOwnProperty(path?.[i])) {
355
+ obj = obj?.[path?.[i]]
356
+ if (i === path.length - 1 && typeof obj === "object" && obj !== null) {
357
+ return ""
358
+ }
359
+ } else {
360
+ return ""
361
+ }
362
+ }
363
+ }
364
+ return obj
365
+ }
366
+
367
+ export function cron_to_english(input) {
368
+ if (!input) {
369
+ return
370
+ }
371
+ const [minute = "*", hour = "*", day_of_month = "*", month = "*", day_of_week = "*"] = (input || "")
372
+ .split(" ")
373
+ .map((part) => part || "*")
374
+ function get_ordinal_suffix(num) {
375
+ const j = num % 10,
376
+ k = num % 100
377
+ if (j === 1 && k !== 11) return `${num}st`
378
+ if (j === 2 && k !== 12) return `${num}nd`
379
+ if (j === 3 && k !== 13) return `${num}rd`
380
+ return `${num}th`
381
+ }
382
+ const translate = (field, type, special_cases = {}) => {
383
+ if (field === "*" && type == "minute") return "every minute"
384
+ if (field === "*") return ""
385
+ if (field.includes(",")) {
386
+ return `on ${field
387
+ .split(",")
388
+ .map((f) => special_cases[f] || get_ordinal_suffix(f))
389
+ .join(", ")} ${type}`
390
+ }
391
+ if (field.includes("/")) {
392
+ const [start, step] = field.split("/")
393
+ return `every ${type === "day of the week" ? step : get_ordinal_suffix(step)} ${type}${
394
+ start === "*" ? "" : " starting from " + type + " " + start
395
+ }`
396
+ }
397
+ if (field.endsWith("L")) return `on the last ${type}`
398
+ if (field.includes("#")) {
399
+ const [dow, nth] = field.split("#")
400
+ return `on every ${get_ordinal_suffix(nth)} ${special_cases[dow] || dow}`
401
+ }
402
+ if (field.includes("W")) return `nearest weekday to ${field.replace("W", "")} of the month`
403
+ return `on ${
404
+ type === "day of the week" ? special_cases[field] || field : "every " + get_ordinal_suffix(field) + " " + type
405
+ }`
406
+ }
407
+ const day_names = {
408
+ 0: "Sunday",
409
+ 1: "Monday",
410
+ 2: "Tuesday",
411
+ 3: "Wednesday",
412
+ 4: "Thursday",
413
+ 5: "Friday",
414
+ 6: "Saturday",
415
+ }
416
+ const minute_text = translate(minute, "minute")
417
+ const hour_text = translate(hour, "hour")
418
+ const day_of_month_text = translate(day_of_month, "day of the month")
419
+ const month_text = translate(month, "month")
420
+ const day_of_week_text = translate(day_of_week, "day of the week", day_names)
421
+ const parts = [minute_text, hour_text, day_of_week_text, day_of_month_text, month_text].filter(Boolean)
422
+ let description = `Run ${parts.join(", ")}`
423
+ return description
424
+ }
425
+
426
+ export function set_closurable(input, default_value = null) {
427
+ return typeof input === "function" ? input() ?? default_value : input ?? default_value
428
+ }
429
+
430
+ export function set_closurable_color(input, default_value = null, is_css = false) {
431
+ let color = set_closurable(input, default_value)
432
+ if (typeof color == "object" && color != null) {
433
+ color = color
434
+ ? is_css
435
+ ? color_to_css(color)
436
+ : color_var(color?.l, color?.c, color?.h, color?.o, color?.is_dark_theme_invert)
437
+ : "transparent"
438
+ }
439
+ return color ?? default_value
440
+ }
441
+
442
+ export function color_to_css(input) {
443
+ return typeof input == "object" && !Array.isArray(input)
444
+ ? color_var(input?.l, input?.c, input?.h, input?.o, input?.is_dark_theme_invert)
445
+ : input ?? "transparent"
446
+ }
447
+
448
+ export function clean_folder_path(folder_path) {
449
+ let warnings = []
450
+ if (!Array.isArray(folder_path)) {
451
+ warnings.push("Folder path must be an array.")
452
+ return { cleaned_folder_path: [], warnings }
453
+ }
454
+ let cleaned_folder_path = folder_path.map((part) => {
455
+ let cleaned_part = clean_custom_identifier(part)
456
+ if (cleaned_part !== part) {
457
+ warnings.push(`"${part}" cleaned to "${cleaned_part}".`)
458
+ }
459
+ return cleaned_part
460
+ })
461
+ cleaned_folder_path = cleaned_folder_path.filter((part) => {
462
+ const is_valid = part.length <= 100 && !/^_|_$|__/.test(part)
463
+ if (!is_valid) {
464
+ warnings.push(`"${part}" is not a valid folder name.`)
465
+ }
466
+ return is_valid
467
+ })
468
+ return { cleaned_folder_path, warnings }
469
+ }
470
+
471
+ export async function get_image_dimensions_from_src(src) {
472
+ return new Promise((resolve, reject) => {
473
+ const img = new Image()
474
+ img.src = src
475
+ img.onload = () =>
476
+ resolve({
477
+ width: img.width,
478
+ height: img.height,
479
+ aspect_ratio: img.width && img.height ? Number((img.width / img.height).toFixed(5)) : null,
480
+ })
481
+ img.onerror = (error) => reject(error)
482
+ })
483
+ }
484
+
485
+ export function time_ago(epoch) {
486
+ const seconds = Math.floor((new Date() - new Date(epoch * 1000)) / 1000)
487
+ let interval = Math.floor(seconds / 31536000)
488
+ if (interval >= 1) {
489
+ return format_date(epoch, true)
490
+ }
491
+ interval = Math.floor(seconds / 2592000)
492
+ if (interval >= 1) {
493
+ return format_date(epoch, true)
494
+ }
495
+ interval = Math.floor(seconds / 604800)
496
+ if (interval >= 1) {
497
+ return interval + "w ago"
498
+ }
499
+ interval = Math.floor(seconds / 86400)
500
+ if (interval >= 1) {
501
+ return interval + "d ago"
502
+ }
503
+ interval = Math.floor(seconds / 3600)
504
+ if (interval >= 1) {
505
+ return interval + "h ago"
506
+ }
507
+ interval = Math.floor(seconds / 60)
508
+ if (interval >= 1) {
509
+ return interval + "m ago"
510
+ }
511
+ return "just now"
512
+ }
513
+
514
+ export function format_full_date(epoch) {
515
+ if (epoch == null) {
516
+ return null
517
+ }
518
+ const days_of_week = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]
519
+ const months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]
520
+ const current_time = new Date()
521
+ const target_time = new Date(epoch * 1000)
522
+ const day_name = days_of_week[target_time.getDay()]
523
+ const month_name = months[target_time.getMonth()]
524
+ const day = target_time.getDate()
525
+ let hour = target_time.getHours()
526
+ const minute = target_time.getMinutes()
527
+ const am_pm = hour >= 12 ? "pm" : "am"
528
+ hour = hour % 12
529
+ hour = hour ? hour : 12
530
+ const time_diff_ms = current_time - target_time
531
+ const time_diff_s = time_diff_ms / 1000
532
+ const time_diff_m = time_diff_s / 60
533
+ const time_diff_h = time_diff_m / 60
534
+ const time_diff_d = time_diff_h / 24
535
+ let time_ago = ""
536
+ if (time_diff_d >= 1) {
537
+ time_ago = `${Math.floor(time_diff_d)} day${Math.floor(time_diff_d) > 1 ? "s" : ""} ago`
538
+ } else if (time_diff_h >= 1) {
539
+ time_ago = `${Math.floor(time_diff_h)} hour${Math.floor(time_diff_h) > 1 ? "s" : ""} ago`
540
+ } else {
541
+ time_ago = `${Math.floor(time_diff_m)} minute${Math.floor(time_diff_m) > 1 ? "s" : ""} ago`
542
+ }
543
+ const human_readable = `${day_name}, ${month_name} ${day}, ${hour}:${
544
+ minute < 10 ? "0" : ""
545
+ }${minute} ${am_pm} (${time_ago})`
546
+ return human_readable
547
+ }
548
+
549
+ export function get_data_type_at_path(path, full_data_type) {
550
+ let data_type_at_path_loc = deep_copy(full_data_type)
551
+ if (Array.isArray(path)) {
552
+ for (let item of path) {
553
+ if (Array.isArray(item)) {
554
+ item = get_data_type_at_path(item)
555
+ }
556
+ if (typeof item == "number" || data_type_at_path_loc?.hasOwnProperty("items")) {
557
+ data_type_at_path_loc = data_type_at_path_loc?.items
558
+ } else if (typeof item == "string") {
559
+ data_type_at_path_loc = data_type_at_path_loc?.properties?.[item]
560
+ }
561
+ }
562
+ }
563
+ return data_type_at_path_loc
564
+ }
565
+
566
+ export function get_def(input, definition_stack) {
567
+ if (Array.isArray(definition_stack)) {
568
+ for (let item of definition_stack) {
569
+ if (item.hasOwnProperty(input)) {
570
+ return item?.[input]
571
+ }
572
+ }
573
+ }
574
+ return null
575
+ }
576
+
577
+ export function get_def_from_variable_path(input, definition_stack) {
578
+ let val = null
579
+ if (Array.isArray(input) && input.length > 0) {
580
+ val = get_def(input?.[0], definition_stack)
581
+ for (let i = 1; i < input.length; i++) {
582
+ if (Array.isArray(input?.[i])) {
583
+ const res = get_def_from_variable_path(input?.[i], definition_stack)
584
+ val = val?.[res]
585
+ } else {
586
+ val = val?.[input?.[i]]
587
+ }
588
+ }
589
+ }
590
+ return val
591
+ }
592
+
593
+ export function is_defined(input, definition_stack) {
594
+ if (Array.isArray(definition_stack)) {
595
+ for (let item of definition_stack) {
596
+ if (item && typeof item == "object" && item.hasOwnProperty(input)) {
597
+ return true
598
+ }
599
+ }
600
+ }
601
+ return false
602
+ }
603
+
604
+ export function set_def(identifier, value, definition_stack) {
605
+ if (Array.isArray(definition_stack)) {
606
+ for (let i = 0; i < definition_stack.length; i++) {
607
+ if (definition_stack[i].hasOwnProperty(identifier)) {
608
+ definition_stack[i][identifier] = value
609
+ }
610
+ }
611
+ }
612
+ return definition_stack
613
+ }
614
+
615
+ export function set_definition_stack(input, definition_stack, pass_event_down) {
616
+ if (!Array.isArray(input?.variable_path_to_target) || !Array.isArray(definition_stack)) {
617
+ throw new Error("Path must be an array")
618
+ }
619
+ let defined_i = null
620
+ const path = input.variable_path_to_target
621
+ const root_key = path[0]
622
+ for (let i = 0; i < definition_stack.length; i++) {
623
+ if (definition_stack?.[i].hasOwnProperty(root_key)) {
624
+ defined_i = i
625
+ break
626
+ }
627
+ }
628
+ if (defined_i == null) {
629
+ throw new Error("Root key not found in stack")
630
+ }
631
+ let defined_variables_loc = deep_copy(definition_stack[defined_i][root_key])
632
+ let temp = defined_variables_loc
633
+ const last_key = path[path.length - 1]
634
+ for (let i = 1; i < path.length - 1; i++) {
635
+ const key = path[i]
636
+ if (!(key in temp) || typeof temp[key] !== "object" || temp[key] === null) {
637
+ const next_key = path[i + 1]
638
+ if (Number.isInteger(next_key)) {
639
+ temp[key] = []
640
+ } else {
641
+ temp[key] = {}
642
+ }
643
+ }
644
+ temp = temp[key]
645
+ }
646
+ if (input?.type == "set_variables_insert") {
647
+ if (Array.isArray(temp[last_key])) {
648
+ if (
649
+ typeof input?.index_to_insert_at === "number" &&
650
+ input?.index_to_insert_at >= 0 &&
651
+ input?.index_to_insert_at <= temp[last_key].length
652
+ ) {
653
+ temp[last_key].splice(input.index_to_insert_at, 0, input.value)
654
+ } else {
655
+ temp[last_key].push(input.value)
656
+ }
657
+ } else if (Array.isArray(temp)) {
658
+ if (
659
+ typeof input?.index_to_insert_at === "number" &&
660
+ input?.index_to_insert_at >= 0 &&
661
+ input?.index_to_insert_at <= temp.length
662
+ ) {
663
+ temp.splice(input.index_to_insert_at, 0, input.value)
664
+ } else {
665
+ temp.push(input.value)
666
+ }
667
+ } else {
668
+ temp[last_key] = [input.value]
669
+ }
670
+ } else if (input?.type == "set_variables_delete") {
671
+ if (Array.isArray(temp)) {
672
+ if (typeof last_key === "number" && last_key > -1 && last_key < temp.length) {
673
+ temp.splice(last_key, 1)
674
+ }
675
+ } else if (typeof temp === "object" && temp?.hasOwnProperty(last_key)) {
676
+ delete temp[last_key]
677
+ }
678
+ } else if (input?.type == "set_variables_key") {
679
+ if (Array.isArray(temp)) {
680
+ throw new Error("Cannot change key in array")
681
+ } else if (typeof temp === "object" && temp?.hasOwnProperty(last_key)) {
682
+ temp[input.value] = temp[last_key]
683
+ delete temp[last_key]
684
+ } else {
685
+ throw new Error("Key not found in object")
686
+ }
687
+ } else {
688
+ temp[last_key] = input?.value
689
+ }
690
+ definition_stack[defined_i][root_key] = defined_variables_loc
691
+ if (typeof pass_event_down === "function") {
692
+ pass_event_down({
693
+ value: input.value,
694
+ definition_stack: definition_stack,
695
+ set_from_content_id: input.set_from_content_id,
696
+ variable_path_to_target: input.variable_path_to_target,
697
+ })
698
+ }
699
+ return {
700
+ is_success: true,
701
+ definition_stack: definition_stack,
702
+ }
703
+ }
704
+
705
+ // tbd could also turn into a typed thing with arrays of v or objects, color, etc
706
+ export function v(config) {
707
+ let val = $state(null)
708
+ function on_change(from_id = null) {
709
+ if (typeof config?.on_change == "function") {
710
+ config?.on_change({ val, from_id: from_id })
711
+ }
712
+ }
713
+ function init(config) {
714
+ val = config?.val
715
+ }
716
+ init(config)
717
+ return {
718
+ get val() {
719
+ return val
720
+ },
721
+ set val(input) {
722
+ val = input
723
+ on_change()
724
+ },
725
+ set_val(input) {
726
+ if (typeof input == "object" && input?.from_id) {
727
+ val = input?.val
728
+ on_change(input?.from_id)
729
+ } else {
730
+ val = input
731
+ on_change()
732
+ }
733
+ },
734
+ }
735
+ }