sveltekit-ui 1.1.17 → 1.1.19
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/dist/Components/Alert/index.svelte +88 -0
- package/dist/Components/Alert/index.svelte.js +101 -0
- package/dist/Components/ArrowToggle/index.svelte +62 -0
- package/dist/Components/Attachment/index.svelte +77 -0
- package/dist/Components/Attachment/index.svelte.js +119 -0
- package/dist/Components/Audio/index.svelte +193 -0
- package/dist/Components/Audio/index.svelte.js +463 -0
- package/dist/Components/AudioEditor/index.svelte +252 -0
- package/dist/Components/AudioEditor/index.svelte.js +977 -0
- package/dist/Components/AudioEditor/samples/alloy-voice-sample.mp3 +0 -0
- package/dist/Components/AudioEditor/samples/echo-voice-sample.mp3 +0 -0
- package/dist/Components/AudioEditor/samples/fable-voice-sample.mp3 +0 -0
- package/dist/Components/AudioEditor/samples/nova-voice-sample.mp3 +0 -0
- package/dist/Components/AudioEditor/samples/onyx-voice-sample.mp3 +0 -0
- package/dist/Components/AudioEditor/samples/shimmer-voice-sample.mp3 +0 -0
- package/dist/Components/AuthCodeInput/index.svelte +85 -0
- package/dist/Components/AuthCodeInput/index.svelte.js +95 -0
- package/dist/Components/Breadcrumbs/index.svelte +27 -0
- package/dist/Components/Breadcrumbs/index.svelte.js +88 -0
- package/dist/Components/Button/index.svelte +721 -0
- package/dist/Components/Button/index.svelte.js +375 -0
- package/dist/Components/Chart/Klines/index.svelte +87 -0
- package/dist/Components/Chart/index.svelte +226 -0
- package/dist/Components/Chart/index.svelte.js +1099 -0
- package/dist/Components/ChartInput/DisplayNav/Klines/index.svelte +150 -0
- package/dist/Components/ChartInput/DisplayNav/Lines/index.svelte +45 -0
- package/dist/Components/ChartInput/DisplayNav/index.svelte +297 -0
- package/dist/Components/ChartInput/EditPanel/index.svelte +155 -0
- package/dist/Components/ChartInput/index.svelte +21 -0
- package/dist/Components/ChartInput/index.svelte.js +671 -0
- package/dist/Components/Checkbox/index.svelte +411 -0
- package/dist/Components/Checkbox/index.svelte.js +178 -0
- package/dist/Components/Code/index.svelte +23 -0
- package/dist/Components/Code/index.svelte.js +33 -0
- package/dist/Components/Color/index.svelte +51 -0
- package/dist/Components/Color/index.svelte.js +31 -0
- package/dist/Components/ColorInput/ChromaPicker/index.svelte +50 -0
- package/dist/Components/ColorInput/ColorPalette/index.svelte +62 -0
- package/dist/Components/ColorInput/OpacityPicker/index.svelte +68 -0
- package/dist/Components/ColorInput/ShowcasePicker/index.svelte +136 -0
- package/dist/Components/ColorInput/index.svelte +70 -0
- package/dist/Components/ColorInput/index.svelte.js +386 -0
- package/dist/Components/ConditionsInput/index.svelte +46 -0
- package/dist/Components/ConditionsInput/index.svelte.js +201 -0
- package/dist/Components/Confetti/index.svelte +98 -0
- package/dist/Components/Confetti/index.svelte.js +94 -0
- package/dist/Components/Content/index.svelte +500 -0
- package/dist/Components/Content/index.svelte.js +910 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte +31 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Audio/index.svelte.js +258 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte +31 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/AudioAdvanced/index.svelte.js +258 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte +58 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Dropdown/index.svelte.js +206 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte +28 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Image/index.svelte.js +224 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte +44 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Number/index.svelte.js +272 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte +41 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Qr/index.svelte.js +202 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte +19 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Slider/index.svelte.js +117 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte +60 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TableAdvanced/index.svelte.js +542 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte +47 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/Tag/index.svelte.js +185 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte +35 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TextInput/index.svelte.js +222 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte +20 -0
- package/dist/Components/ContentInput/AttributesInput/CustomConfig/TimeInput/index.svelte.js +84 -0
- package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte +25 -0
- package/dist/Components/ContentInput/AttributesInput/DefinedTypeInput/index.svelte.js +91 -0
- package/dist/Components/ContentInput/AttributesInput/index.svelte +352 -0
- package/dist/Components/ContentInput/AttributesInput/index.svelte.js +1436 -0
- package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte +64 -0
- package/dist/Components/ContentInput/ContentPanelBuilder/AddElement/index.svelte.js +97 -0
- package/dist/Components/ContentInput/ContentPanelBuilder/ElementList/index.svelte +184 -0
- package/dist/Components/ContentInput/ContentPanelBuilder/index.svelte +41 -0
- package/dist/Components/ContentInput/index.svelte +78 -0
- package/dist/Components/ContentInput/index.svelte.js +1197 -0
- package/dist/Components/CronInput/index.svelte +78 -0
- package/dist/Components/CronInput/index.svelte.js +198 -0
- package/dist/Components/DataTypeInput/index.svelte +174 -0
- package/dist/Components/DataTypeInput/index.svelte.js +565 -0
- package/dist/Components/Dropdown/index.svelte +116 -0
- package/dist/Components/Dropdown/index.svelte.js +403 -0
- package/dist/Components/EmailAddress/index.svelte +22 -0
- package/dist/Components/EmailAddress/index.svelte.js +45 -0
- package/dist/Components/ErrorX/index.svelte +58 -0
- package/dist/Components/Eye/index.svelte +57 -0
- package/dist/Components/FileInput/index.svelte +146 -0
- package/dist/Components/FileInput/index.svelte.js +225 -0
- package/dist/Components/Hamburger/index.svelte +99 -0
- package/dist/Components/HorizScrollBox/index.svelte +145 -0
- package/dist/Components/Icon/index.svelte +412 -0
- package/dist/Components/Icon/index.svelte.js +116 -0
- package/dist/Components/IconInput/index.svelte +77 -0
- package/dist/Components/IconInput/index.svelte.js +259 -0
- package/dist/Components/Image/index.svelte +126 -0
- package/dist/Components/Image/index.svelte.js +116 -0
- package/dist/Components/ImageEditor/Image/CropBox/index.svelte +165 -0
- package/dist/Components/ImageEditor/Image/index.svelte +104 -0
- package/dist/Components/ImageEditor/Panels/AI/index.svelte +44 -0
- package/dist/Components/ImageEditor/Panels/Crop/index.svelte +96 -0
- package/dist/Components/ImageEditor/Panels/File/QualityPicker/index.svelte +124 -0
- package/dist/Components/ImageEditor/Panels/File/index.svelte +74 -0
- package/dist/Components/ImageEditor/Panels/Filters/index.svelte +46 -0
- package/dist/Components/ImageEditor/Panels/Resize/index.svelte +58 -0
- package/dist/Components/ImageEditor/index.svelte +93 -0
- package/dist/Components/ImageEditor/index.svelte.js +1961 -0
- package/dist/Components/ImageSlider/index.svelte +124 -0
- package/dist/Components/ImageSlider/index.svelte.js +99 -0
- package/dist/Components/InfoBox/index.svelte +89 -0
- package/dist/Components/Json/Nested/index.svelte +157 -0
- package/dist/Components/Json/index.svelte +60 -0
- package/dist/Components/Json/index.svelte.js +594 -0
- package/dist/Components/LabeledItem/index.svelte +102 -0
- package/dist/Components/Layout/NavBar/FullNav/index.svelte +52 -0
- package/dist/Components/Layout/NavBar/NavGuts/index.svelte +87 -0
- package/dist/Components/Layout/NavBar/index.svelte +72 -0
- package/dist/Components/Layout/index.svelte +149 -0
- package/dist/Components/Layout/index.svelte.js +360 -0
- package/dist/Components/Link/index.svelte +47 -0
- package/dist/Components/Link/index.svelte.js +136 -0
- package/dist/Components/LoadingSuccessDiv/index.svelte +51 -0
- package/dist/Components/LoadingWheel/index.svelte +38 -0
- package/dist/Components/Location/index.svelte +79 -0
- package/dist/Components/Location/index.svelte.js +288 -0
- package/dist/Components/LocationInput/index.svelte +197 -0
- package/dist/Components/LocationInput/index.svelte.js +965 -0
- package/dist/Components/Number/index.svelte +47 -0
- package/dist/Components/Number/index.svelte.js +151 -0
- package/dist/Components/PhoneCountryCode/index.svelte +7 -0
- package/dist/Components/PhoneCountryCode/index.svelte.js +260 -0
- package/dist/Components/PhoneNumber/index.svelte +22 -0
- package/dist/Components/PhoneNumber/index.svelte.js +41 -0
- package/dist/Components/Popover/index.svelte +396 -0
- package/dist/Components/Popover/index.svelte.js +319 -0
- package/dist/Components/Qr/index.svelte +85 -0
- package/dist/Components/Qr/index.svelte.js +301 -0
- package/dist/Components/QrInput/index.svelte +47 -0
- package/dist/Components/QrInput/index.svelte.js +218 -0
- package/dist/Components/Slider/index.svelte +239 -0
- package/dist/Components/Slider/index.svelte.js +469 -0
- package/dist/Components/Spacer/index.svelte +41 -0
- package/dist/Components/StoragePicker/DisplayFile/index.svelte +15 -0
- package/dist/Components/StoragePicker/index.svelte +187 -0
- package/dist/Components/StoragePicker/index.svelte.js +592 -0
- package/dist/Components/SuccessCheck/index.svelte +56 -0
- package/dist/Components/TableAdvanced/ColumnInput/index.svelte +117 -0
- package/dist/Components/TableAdvanced/ColumnInput/index.svelte.js +456 -0
- package/dist/Components/TableAdvanced/FilterInput/index.svelte +54 -0
- package/dist/Components/TableAdvanced/FilterInput/index.svelte.js +247 -0
- package/dist/Components/TableAdvanced/Pagination/index.svelte +43 -0
- package/dist/Components/TableAdvanced/Pagination/index.svelte.js +97 -0
- package/dist/Components/TableAdvanced/SortByInput/index.svelte +72 -0
- package/dist/Components/TableAdvanced/SortByInput/index.svelte.js +176 -0
- package/dist/Components/TableAdvanced/index.svelte +275 -0
- package/dist/Components/TableAdvanced/index.svelte.js +1565 -0
- package/dist/Components/Tag/index.svelte +45 -0
- package/dist/Components/Tag/index.svelte.js +76 -0
- package/dist/Components/TextArrayInput/index.svelte +108 -0
- package/dist/Components/TextArrayInput/index.svelte.js +239 -0
- package/dist/Components/TextInput/PasswordTooltip/index.svelte +89 -0
- package/dist/Components/TextInput/index.svelte +223 -0
- package/dist/Components/TextInput/index.svelte.js +447 -0
- package/dist/Components/Time/index.svelte +7 -0
- package/dist/Components/Time/index.svelte.js +38 -0
- package/dist/Components/TimeInput/NumberToggler/index.svelte +34 -0
- package/dist/Components/TimeInput/NumberToggler/index.svelte.js +79 -0
- package/dist/Components/TimeInput/index.js +702 -0
- package/dist/Components/TimeInput/index.svelte +211 -0
- package/dist/Components/TimeInput/index.svelte.js +638 -0
- package/dist/Components/Tooltip/index.svelte +143 -0
- package/dist/Components/TransparentBackground/index.svelte +153 -0
- package/dist/Components/TypingDots/index.svelte +84 -0
- package/dist/Components/VariablePathInput/index.svelte +63 -0
- package/dist/Components/VariablePathInput/index.svelte.js +273 -0
- package/dist/Components/VideoTBD/index.svelte +100 -0
- package/dist/Components/XFollow/index.svelte +42 -0
- package/dist/Components/XPost/index.svelte +52 -0
- package/dist/Components/XPost/index.svelte.js +64 -0
- package/dist/Components/YoutubeChannelButton/index.svelte +82 -0
- package/dist/Components/YoutubeVideo/index.svelte +73 -0
- package/dist/Components/YoutubeVideo/index.svelte.js +54 -0
- package/dist/actions/draggable.js +49 -0
- package/dist/actions/index.js +24 -0
- package/dist/actions/no_spaces.js +33 -0
- package/dist/actions/numbers_only.js +26 -0
- package/dist/actions/scroll_y.js +28 -0
- package/dist/actions/stop_scroll_propagation_y.js +42 -0
- package/dist/actions/swipe_handler.js +295 -0
- package/dist/client/astc_formatting/index.js +1128 -0
- package/dist/client/docs/index.js +7622 -0
- package/dist/client/index.js +735 -0
- package/dist/client/types/index.js +2812 -0
- package/dist/index.js +180 -0
- package/dist/style.css +682 -0
- package/package.json +2 -2
- package/src/lib/Components/Chart/index.svelte.js +11 -2
|
@@ -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
|
+
}
|