@lichens-innovation/ts-common 1.17.0 → 1.20.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/dist/index.d.cts CHANGED
@@ -1,4 +1,7 @@
1
- export { D as Dimensions } from './dimensions.utils-BwIBA5op.cjs';
1
+ export { D as Dimensions, N as NormalizedRgb, R as RgbColor, a as RgbaColor, g as getColorForPercentage, b as getContrastTextColor, c as getLuminance, d as getOpacityHexValue, h as hexToNormalizedRgb, e as hexToRgb, i as isLightColor, r as rgbToHex, f as rgbToString, j as rgbaToHex, k as rgbaToHexWithAlpha, l as rgbaToString } from './dimensions.utils-C7MsHTQd.cjs';
2
+
3
+ declare const encodeBase64: (text: string) => string;
4
+ declare const decodeBase64: (base64: string) => string;
2
5
 
3
6
  interface ToleranceArea {
4
7
  flow: number;
@@ -46,47 +49,6 @@ declare const roundToNiceNumber: (rawValue: number) => number;
46
49
  */
47
50
  declare const buildTicksForChart: (max: number, targetTickCount?: number) => number[];
48
51
 
49
- interface RgbColor {
50
- r: number;
51
- g: number;
52
- b: number;
53
- }
54
- interface RgbaColor extends RgbColor {
55
- a: number;
56
- }
57
- declare const rgbToHex: (r: number, g: number, b: number) => string;
58
- declare const hexToRgb: (hex: string) => RgbColor;
59
- declare const rgbaToHex: (color: RgbaColor) => string;
60
- declare const getOpacityHexValue: (opacity: number) => string;
61
- declare const rgbaToHexWithAlpha: (color: RgbaColor) => string;
62
- declare const rgbToString: (color: RgbColor) => string;
63
- declare const rgbaToString: (color: RgbaColor) => string;
64
- declare const getLuminance: (r: number, g: number, b: number) => number;
65
- declare const getContrastTextColor: (hexColor: string) => string;
66
- /**
67
- * Normalized RGB color with values between 0 and 1.
68
- * Useful for graphics libraries like Three.js.
69
- */
70
- interface NormalizedRgb {
71
- r: number;
72
- g: number;
73
- b: number;
74
- }
75
- /**
76
- * Convert a hex color string to normalized RGB values (0-1 range).
77
- * @param hex - Hex color string (with or without # prefix)
78
- * @returns Normalized RGB object with values between 0 and 1
79
- */
80
- declare const hexToNormalizedRgb: (hex: string) => NormalizedRgb;
81
- /**
82
- * Determine if a color is light or dark based on relative luminance.
83
- * Useful for choosing contrasting text colors.
84
- * @param hex - Hex color string
85
- * @returns True if the color is considered light (luminance > 0.5)
86
- */
87
- declare const isLightColor: (hex: string) => boolean;
88
- declare const getColorForPercentage: (percent: number) => string;
89
-
90
52
  type DateInput = Date | string | number | null;
91
53
  declare const dateAs_HHMMSS: (value?: DateInput) => string;
92
54
  declare const dateAs_YYYYMMDD: (value?: DateInput) => string;
@@ -133,10 +95,27 @@ declare const toFormString: (n?: number | null) => string;
133
95
  */
134
96
  declare const toFormStringInteger: (n?: number | null) => string;
135
97
 
98
+ declare const escapeHtml: (text: string) => string;
99
+ declare const unescapeHtml: (text: string) => string;
100
+
136
101
  declare const isHttpSuccessStatus: (status?: number | null) => boolean;
137
102
  declare const isHttpClientErrorStatus: (status?: number | null) => boolean;
138
103
  declare const isHttpServerErrorStatus: (status?: number | null) => boolean;
139
104
 
105
+ declare const safeJsonParse: <T>(value: string, fallback?: T) => T | undefined;
106
+ declare const safeJsonStringify: (obj: unknown, space?: number) => string;
107
+ declare const sortObjectKeys: (_key: string, value: unknown) => unknown;
108
+ interface FormatJsonArgs {
109
+ value?: string;
110
+ space?: number;
111
+ sortKeys?: boolean;
112
+ }
113
+ declare const formatJson: ({ value, space, sortKeys }: FormatJsonArgs) => string;
114
+ declare const prettifyJson: (value?: string) => string;
115
+ declare const minifyJson: (value?: string) => string;
116
+ declare const isValidJson: (value: string) => boolean;
117
+ declare const isMinifiedJson: (value: string) => boolean;
118
+
140
119
  /**
141
120
  * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).
142
121
  */
@@ -159,6 +138,16 @@ declare const isInputValidNegativeInteger: (value: string) => boolean;
159
138
  declare const formatIntegerDisplay: (value?: number | null) => string;
160
139
  declare const toFixed: (value?: number | null, decimals?: number) => number;
161
140
  declare const roundUpToNearest10: (value?: number | null) => number;
141
+ /**
142
+ * Format a number with K (thousands) or M (millions) suffix.
143
+ */
144
+ declare const formatCount: (count: number) => string;
145
+ /**
146
+ * Format a duration in milliseconds to a human-readable string.
147
+ */
148
+ declare const formatDuration: (ms: number) => string;
149
+ declare const formatWithSpaceSeparator: (val?: number | string | null) => string;
150
+ declare const parseWithSpaceSeparator: (val?: string) => number;
162
151
  declare const getOrderOfMagnitudeExponent: (n?: number | null) => number;
163
152
 
164
153
  declare const REGEX_ALPHANUMERIC: RegExp;
@@ -207,11 +196,32 @@ declare const countWords: (text: string) => number;
207
196
  * @returns The truncated string
208
197
  */
209
198
  declare const truncate: (str: string, maxLength: number, ellipsis?: string) => string;
199
+ /**
200
+ * Converts a string to a URL-safe slug.
201
+ * Removes diacritical marks, lowercases, replaces non-alphanumeric characters with hyphens,
202
+ * and strips leading/trailing hyphens.
203
+ *
204
+ * @param value - The input string to slugify
205
+ * @returns The slugified string
206
+ *
207
+ * @example
208
+ * slugify("Héllo Wörld!") // → "hello-world"
209
+ * slugify(" My Blog Post ") // → "my-blog-post"
210
+ */
211
+ declare const slugify: (value: string) => string;
210
212
  /**
211
213
  * Parses an optional comma-separated string into a trimmed, non-blank string array.
212
214
  */
213
215
  declare const parseCommaSeparatedList: (raw?: string | null) => string[];
214
216
 
217
+ declare const firstSentence: (s: string) => string;
218
+ interface TitleFromNameArgs {
219
+ name: string;
220
+ fallback?: string;
221
+ }
222
+ declare const titleFromName: ({ name, fallback }: TitleFromNameArgs) => string;
223
+ declare const joinOxford: (items: string[]) => string;
224
+
215
225
  declare const sleep: (milliseconds: number) => Promise<void>;
216
226
  /**
217
227
  * Yields to the main thread so the UI can process events and repaint.
@@ -269,9 +279,17 @@ declare const hasScheme: (uri?: string | null) => boolean;
269
279
  * @returns The base64 data without the data URI prefix, or the original string if no comma is found
270
280
  */
271
281
  declare const extractBase64FromDataUri: (dataUri: string) => string;
282
+ declare const encodeUrl: (value?: string) => string;
283
+ declare const decodeUrl: (value?: string) => string;
284
+ interface FormatDataUriArgs {
285
+ mimeType: string;
286
+ base64: string;
287
+ }
288
+ declare const formatDataUri: ({ mimeType, base64 }: FormatDataUriArgs) => string;
289
+ declare const getBase64ApproxSize: (base64: string) => number;
272
290
 
273
291
  declare const isWsClosable: (ws?: WebSocket | null) => ws is WebSocket;
274
292
  declare const isWsOpenOrConnecting: (ws?: WebSocket | null) => ws is WebSocket;
275
293
  declare const closeWebSocket: (ws?: WebSocket | null) => void;
276
294
 
277
- export { type ChartPoint, DATA_URI_PATTERN, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
295
+ export { type ChartPoint, DATA_URI_PATTERN, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, decodeBase64, decodeUrl, encodeBase64, encodeUrl, escapeHtml, extractBase64FromDataUri, firstSentence, formatCount, formatDataUri, formatDuration, formatIntegerDisplay, formatJson, formatUnixTimestamp, formatWithSpaceSeparator, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getBase64ApproxSize, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isMinifiedJson, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isValidJson, isWsClosable, isWsOpenOrConnecting, joinOxford, minifyJson, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, parseWithSpaceSeparator, prettifyJson, removeDiacriticalMarks, roundToNiceNumber, roundUpToNearest10, safeJsonParse, safeJsonStringify, sleep, slugify, sortObjectKeys, tickFormatter, titleFromName, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, unescapeHtml, yieldToMainThread };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export { D as Dimensions } from './dimensions.utils-BwIBA5op.js';
1
+ export { D as Dimensions, N as NormalizedRgb, R as RgbColor, a as RgbaColor, g as getColorForPercentage, b as getContrastTextColor, c as getLuminance, d as getOpacityHexValue, h as hexToNormalizedRgb, e as hexToRgb, i as isLightColor, r as rgbToHex, f as rgbToString, j as rgbaToHex, k as rgbaToHexWithAlpha, l as rgbaToString } from './dimensions.utils-C7MsHTQd.js';
2
+
3
+ declare const encodeBase64: (text: string) => string;
4
+ declare const decodeBase64: (base64: string) => string;
2
5
 
3
6
  interface ToleranceArea {
4
7
  flow: number;
@@ -46,47 +49,6 @@ declare const roundToNiceNumber: (rawValue: number) => number;
46
49
  */
47
50
  declare const buildTicksForChart: (max: number, targetTickCount?: number) => number[];
48
51
 
49
- interface RgbColor {
50
- r: number;
51
- g: number;
52
- b: number;
53
- }
54
- interface RgbaColor extends RgbColor {
55
- a: number;
56
- }
57
- declare const rgbToHex: (r: number, g: number, b: number) => string;
58
- declare const hexToRgb: (hex: string) => RgbColor;
59
- declare const rgbaToHex: (color: RgbaColor) => string;
60
- declare const getOpacityHexValue: (opacity: number) => string;
61
- declare const rgbaToHexWithAlpha: (color: RgbaColor) => string;
62
- declare const rgbToString: (color: RgbColor) => string;
63
- declare const rgbaToString: (color: RgbaColor) => string;
64
- declare const getLuminance: (r: number, g: number, b: number) => number;
65
- declare const getContrastTextColor: (hexColor: string) => string;
66
- /**
67
- * Normalized RGB color with values between 0 and 1.
68
- * Useful for graphics libraries like Three.js.
69
- */
70
- interface NormalizedRgb {
71
- r: number;
72
- g: number;
73
- b: number;
74
- }
75
- /**
76
- * Convert a hex color string to normalized RGB values (0-1 range).
77
- * @param hex - Hex color string (with or without # prefix)
78
- * @returns Normalized RGB object with values between 0 and 1
79
- */
80
- declare const hexToNormalizedRgb: (hex: string) => NormalizedRgb;
81
- /**
82
- * Determine if a color is light or dark based on relative luminance.
83
- * Useful for choosing contrasting text colors.
84
- * @param hex - Hex color string
85
- * @returns True if the color is considered light (luminance > 0.5)
86
- */
87
- declare const isLightColor: (hex: string) => boolean;
88
- declare const getColorForPercentage: (percent: number) => string;
89
-
90
52
  type DateInput = Date | string | number | null;
91
53
  declare const dateAs_HHMMSS: (value?: DateInput) => string;
92
54
  declare const dateAs_YYYYMMDD: (value?: DateInput) => string;
@@ -133,10 +95,27 @@ declare const toFormString: (n?: number | null) => string;
133
95
  */
134
96
  declare const toFormStringInteger: (n?: number | null) => string;
135
97
 
98
+ declare const escapeHtml: (text: string) => string;
99
+ declare const unescapeHtml: (text: string) => string;
100
+
136
101
  declare const isHttpSuccessStatus: (status?: number | null) => boolean;
137
102
  declare const isHttpClientErrorStatus: (status?: number | null) => boolean;
138
103
  declare const isHttpServerErrorStatus: (status?: number | null) => boolean;
139
104
 
105
+ declare const safeJsonParse: <T>(value: string, fallback?: T) => T | undefined;
106
+ declare const safeJsonStringify: (obj: unknown, space?: number) => string;
107
+ declare const sortObjectKeys: (_key: string, value: unknown) => unknown;
108
+ interface FormatJsonArgs {
109
+ value?: string;
110
+ space?: number;
111
+ sortKeys?: boolean;
112
+ }
113
+ declare const formatJson: ({ value, space, sortKeys }: FormatJsonArgs) => string;
114
+ declare const prettifyJson: (value?: string) => string;
115
+ declare const minifyJson: (value?: string) => string;
116
+ declare const isValidJson: (value: string) => boolean;
117
+ declare const isMinifiedJson: (value: string) => boolean;
118
+
140
119
  /**
141
120
  * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).
142
121
  */
@@ -159,6 +138,16 @@ declare const isInputValidNegativeInteger: (value: string) => boolean;
159
138
  declare const formatIntegerDisplay: (value?: number | null) => string;
160
139
  declare const toFixed: (value?: number | null, decimals?: number) => number;
161
140
  declare const roundUpToNearest10: (value?: number | null) => number;
141
+ /**
142
+ * Format a number with K (thousands) or M (millions) suffix.
143
+ */
144
+ declare const formatCount: (count: number) => string;
145
+ /**
146
+ * Format a duration in milliseconds to a human-readable string.
147
+ */
148
+ declare const formatDuration: (ms: number) => string;
149
+ declare const formatWithSpaceSeparator: (val?: number | string | null) => string;
150
+ declare const parseWithSpaceSeparator: (val?: string) => number;
162
151
  declare const getOrderOfMagnitudeExponent: (n?: number | null) => number;
163
152
 
164
153
  declare const REGEX_ALPHANUMERIC: RegExp;
@@ -207,11 +196,32 @@ declare const countWords: (text: string) => number;
207
196
  * @returns The truncated string
208
197
  */
209
198
  declare const truncate: (str: string, maxLength: number, ellipsis?: string) => string;
199
+ /**
200
+ * Converts a string to a URL-safe slug.
201
+ * Removes diacritical marks, lowercases, replaces non-alphanumeric characters with hyphens,
202
+ * and strips leading/trailing hyphens.
203
+ *
204
+ * @param value - The input string to slugify
205
+ * @returns The slugified string
206
+ *
207
+ * @example
208
+ * slugify("Héllo Wörld!") // → "hello-world"
209
+ * slugify(" My Blog Post ") // → "my-blog-post"
210
+ */
211
+ declare const slugify: (value: string) => string;
210
212
  /**
211
213
  * Parses an optional comma-separated string into a trimmed, non-blank string array.
212
214
  */
213
215
  declare const parseCommaSeparatedList: (raw?: string | null) => string[];
214
216
 
217
+ declare const firstSentence: (s: string) => string;
218
+ interface TitleFromNameArgs {
219
+ name: string;
220
+ fallback?: string;
221
+ }
222
+ declare const titleFromName: ({ name, fallback }: TitleFromNameArgs) => string;
223
+ declare const joinOxford: (items: string[]) => string;
224
+
215
225
  declare const sleep: (milliseconds: number) => Promise<void>;
216
226
  /**
217
227
  * Yields to the main thread so the UI can process events and repaint.
@@ -269,9 +279,17 @@ declare const hasScheme: (uri?: string | null) => boolean;
269
279
  * @returns The base64 data without the data URI prefix, or the original string if no comma is found
270
280
  */
271
281
  declare const extractBase64FromDataUri: (dataUri: string) => string;
282
+ declare const encodeUrl: (value?: string) => string;
283
+ declare const decodeUrl: (value?: string) => string;
284
+ interface FormatDataUriArgs {
285
+ mimeType: string;
286
+ base64: string;
287
+ }
288
+ declare const formatDataUri: ({ mimeType, base64 }: FormatDataUriArgs) => string;
289
+ declare const getBase64ApproxSize: (base64: string) => number;
272
290
 
273
291
  declare const isWsClosable: (ws?: WebSocket | null) => ws is WebSocket;
274
292
  declare const isWsOpenOrConnecting: (ws?: WebSocket | null) => ws is WebSocket;
275
293
  declare const closeWebSocket: (ws?: WebSocket | null) => void;
276
294
 
277
- export { type ChartPoint, DATA_URI_PATTERN, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
295
+ export { type ChartPoint, DATA_URI_PATTERN, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, decodeBase64, decodeUrl, encodeBase64, encodeUrl, escapeHtml, extractBase64FromDataUri, firstSentence, formatCount, formatDataUri, formatDuration, formatIntegerDisplay, formatJson, formatUnixTimestamp, formatWithSpaceSeparator, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getBase64ApproxSize, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isMinifiedJson, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isValidJson, isWsClosable, isWsOpenOrConnecting, joinOxford, minifyJson, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, parseWithSpaceSeparator, prettifyJson, removeDiacriticalMarks, roundToNiceNumber, roundUpToNearest10, safeJsonParse, safeJsonStringify, sleep, slugify, sortObjectKeys, tickFormatter, titleFromName, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, unescapeHtml, yieldToMainThread };
package/dist/index.js CHANGED
@@ -1,5 +1,115 @@
1
1
  import { format } from 'date-fns';
2
2
 
3
+ // src/utils/base64.utils.ts
4
+ var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5
+ var encodeUtf8ToBytes = (text) => {
6
+ const codePoints = [];
7
+ for (let i = 0; i < text.length; i++) {
8
+ const codeUnit = text.charCodeAt(i);
9
+ if (codeUnit >= 55296 && codeUnit <= 56319 && i + 1 < text.length) {
10
+ const next = text.charCodeAt(i + 1);
11
+ if (next >= 56320 && next <= 57343) {
12
+ codePoints.push(65536 + (codeUnit - 55296 << 10) + (next - 56320));
13
+ i++;
14
+ continue;
15
+ }
16
+ }
17
+ codePoints.push(codeUnit);
18
+ }
19
+ const bytes = [];
20
+ for (const codePoint of codePoints) {
21
+ if (codePoint < 128) {
22
+ bytes.push(codePoint);
23
+ } else if (codePoint < 2048) {
24
+ bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
25
+ } else if (codePoint < 65536) {
26
+ bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
27
+ } else {
28
+ bytes.push(
29
+ 240 | codePoint >> 18,
30
+ 128 | codePoint >> 12 & 63,
31
+ 128 | codePoint >> 6 & 63,
32
+ 128 | codePoint & 63
33
+ );
34
+ }
35
+ }
36
+ return bytes;
37
+ };
38
+ var decodeUtf8FromBytes = (bytes) => {
39
+ let result = "";
40
+ let i = 0;
41
+ while (i < bytes.length) {
42
+ const b0 = bytes[i];
43
+ let codePoint;
44
+ if (b0 < 128) {
45
+ codePoint = b0;
46
+ i += 1;
47
+ } else if ((b0 & 224) === 192) {
48
+ codePoint = (b0 & 31) << 6 | bytes[i + 1] & 63;
49
+ i += 2;
50
+ } else if ((b0 & 240) === 224) {
51
+ codePoint = (b0 & 15) << 12 | (bytes[i + 1] & 63) << 6 | bytes[i + 2] & 63;
52
+ i += 3;
53
+ } else {
54
+ codePoint = (b0 & 7) << 18 | (bytes[i + 1] & 63) << 12 | (bytes[i + 2] & 63) << 6 | bytes[i + 3] & 63;
55
+ i += 4;
56
+ }
57
+ if (codePoint <= 65535) {
58
+ result += String.fromCharCode(codePoint);
59
+ } else {
60
+ const adjusted = codePoint - 65536;
61
+ result += String.fromCharCode(55296 + (adjusted >> 10), 56320 + (adjusted & 1023));
62
+ }
63
+ }
64
+ return result;
65
+ };
66
+ var encodeBytesToBase64 = (bytes) => {
67
+ let output = "";
68
+ for (let i = 0; i < bytes.length; i += 3) {
69
+ const b0 = bytes[i];
70
+ const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
71
+ const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
72
+ const triplet = b0 << 16 | b1 << 8 | b2;
73
+ output += BASE64_CHARS[triplet >> 18 & 63];
74
+ output += BASE64_CHARS[triplet >> 12 & 63];
75
+ output += i + 1 < bytes.length ? BASE64_CHARS[triplet >> 6 & 63] : "=";
76
+ output += i + 2 < bytes.length ? BASE64_CHARS[triplet & 63] : "=";
77
+ }
78
+ return output;
79
+ };
80
+ var decodeBase64ToBytes = (base64) => {
81
+ const sanitized = base64.replace(/[^A-Za-z0-9+/=]/g, "");
82
+ const bytes = [];
83
+ for (let i = 0; i < sanitized.length; i += 4) {
84
+ const c0 = BASE64_CHARS.indexOf(sanitized[i]);
85
+ const c1 = BASE64_CHARS.indexOf(sanitized[i + 1]);
86
+ const c2 = sanitized[i + 2] === "=" ? 0 : BASE64_CHARS.indexOf(sanitized[i + 2]);
87
+ const c3 = sanitized[i + 3] === "=" ? 0 : BASE64_CHARS.indexOf(sanitized[i + 3]);
88
+ if (c0 < 0 || c1 < 0 || sanitized[i + 2] !== "=" && c2 < 0 || sanitized[i + 3] !== "=" && c3 < 0) {
89
+ throw new Error("Invalid base64 character");
90
+ }
91
+ const triplet = c0 << 18 | c1 << 12 | c2 << 6 | c3;
92
+ bytes.push(triplet >> 16 & 255);
93
+ if (sanitized[i + 2] !== "=") bytes.push(triplet >> 8 & 255);
94
+ if (sanitized[i + 3] !== "=") bytes.push(triplet & 255);
95
+ }
96
+ return bytes;
97
+ };
98
+ var encodeBase64 = (text) => {
99
+ try {
100
+ return encodeBytesToBase64(encodeUtf8ToBytes(text));
101
+ } catch {
102
+ return "";
103
+ }
104
+ };
105
+ var decodeBase64 = (base64) => {
106
+ try {
107
+ return decodeUtf8FromBytes(decodeBase64ToBytes(base64));
108
+ } catch {
109
+ return "";
110
+ }
111
+ };
112
+
3
113
  // src/utils/types.utils.ts
4
114
  var NO_OP = () => {
5
115
  };
@@ -247,6 +357,10 @@ var truncate = (str, maxLength, ellipsis = "...") => {
247
357
  if (!str || str.length <= maxLength) return str;
248
358
  return str.slice(0, maxLength - ellipsis.length) + ellipsis;
249
359
  };
360
+ var slugify = (value) => {
361
+ if (!value) return "";
362
+ return removeDiacriticalMarks(value).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
363
+ };
250
364
  var parseCommaSeparatedList = (raw) => {
251
365
  if (isBlank(raw)) {
252
366
  return [];
@@ -282,6 +396,29 @@ var toFormStringInteger = (n) => {
282
396
  return String(Math.round(n));
283
397
  };
284
398
 
399
+ // src/utils/html.utils.ts
400
+ var HTML_ESCAPE_MAP = {
401
+ "&": "&amp;",
402
+ "<": "&lt;",
403
+ ">": "&gt;",
404
+ '"': "&quot;",
405
+ "'": "&#39;"
406
+ };
407
+ var HTML_UNESCAPE_MAP = {
408
+ "&amp;": "&",
409
+ "&lt;": "<",
410
+ "&gt;": ">",
411
+ "&quot;": '"',
412
+ "&#39;": "'",
413
+ "&#x27;": "'"
414
+ };
415
+ var escapeHtml = (text) => {
416
+ return text.replace(/[&<>"']/g, (char) => HTML_ESCAPE_MAP[char] ?? char);
417
+ };
418
+ var unescapeHtml = (text) => {
419
+ return text.replace(/&(?:amp|lt|gt|quot|#39|#x27);/g, (entity) => HTML_UNESCAPE_MAP[entity] ?? entity);
420
+ };
421
+
285
422
  // src/utils/http.utils.ts
286
423
  var isHttpSuccessStatus = (status) => {
287
424
  if (isNullish(status)) {
@@ -302,6 +439,56 @@ var isHttpServerErrorStatus = (status) => {
302
439
  return status >= 500;
303
440
  };
304
441
 
442
+ // src/utils/json.utils.ts
443
+ var safeJsonParse = (value, fallback) => {
444
+ try {
445
+ return JSON.parse(value);
446
+ } catch {
447
+ return fallback;
448
+ }
449
+ };
450
+ var safeJsonStringify = (obj, space = 2) => {
451
+ if (!obj) return "";
452
+ try {
453
+ return JSON.stringify(obj, null, space);
454
+ } catch {
455
+ return "";
456
+ }
457
+ };
458
+ var sortObjectKeys = (_key, value) => value instanceof Object && !(value instanceof Array) ? Object.keys(value).sort().reduce(
459
+ (sorted, key) => {
460
+ sorted[key] = value[key];
461
+ return sorted;
462
+ },
463
+ {}
464
+ ) : value;
465
+ var formatJson = ({ value, space = 2, sortKeys = false }) => {
466
+ if (!value) return "";
467
+ try {
468
+ const obj = JSON.parse(value);
469
+ return JSON.stringify(obj, sortKeys ? sortObjectKeys : void 0, space);
470
+ } catch {
471
+ return value;
472
+ }
473
+ };
474
+ var prettifyJson = (value) => {
475
+ return formatJson({ value, space: 4, sortKeys: true });
476
+ };
477
+ var minifyJson = (value) => {
478
+ return formatJson({ value, space: 0, sortKeys: true });
479
+ };
480
+ var isValidJson = (value) => {
481
+ try {
482
+ JSON.parse(value);
483
+ return true;
484
+ } catch {
485
+ return false;
486
+ }
487
+ };
488
+ var isMinifiedJson = (value) => {
489
+ return value === minifyJson(value);
490
+ };
491
+
305
492
  // src/utils/number.utils.ts
306
493
  var isInputValidNumber = (value) => {
307
494
  if (isBlank(value)) return false;
@@ -335,6 +522,28 @@ var roundUpToNearest10 = (value) => {
335
522
  if (isNullish(value)) return 0;
336
523
  return Math.ceil(value / 10) * 10;
337
524
  };
525
+ var formatCount = (count) => {
526
+ if (count >= 1e6) {
527
+ return `${(count / 1e6).toFixed(1)}M`;
528
+ }
529
+ if (count >= 1e3) {
530
+ return `${(count / 1e3).toFixed(1)}K`;
531
+ }
532
+ return count.toString();
533
+ };
534
+ var formatDuration = (ms) => {
535
+ if (ms < 1e3) {
536
+ return `${ms}ms`;
537
+ }
538
+ return `${(ms / 1e3).toFixed(1)}s`;
539
+ };
540
+ var formatWithSpaceSeparator = (val) => {
541
+ if (isNullish(val)) return "";
542
+ return String(val).replace(/\B(?=(\d{3})+(?!\d))/g, "\xA0");
543
+ };
544
+ var parseWithSpaceSeparator = (val) => {
545
+ return Number(val?.replace(/\u00a0/g, ""));
546
+ };
338
547
  var getOrderOfMagnitudeExponent = (n) => {
339
548
  if (isNullish(n)) return 0;
340
549
  if (!isNumber(n)) return 0;
@@ -354,6 +563,20 @@ var isRuntimeEnvNodeJs = () => {
354
563
  return true;
355
564
  };
356
565
 
566
+ // src/utils/text.utils.ts
567
+ var firstSentence = (s) => {
568
+ const m = s.match(/^[^.!?]+[.!?]/);
569
+ return m ? m[0].trim() : s.trim();
570
+ };
571
+ var titleFromName = ({ name, fallback = "" }) => {
572
+ return (name || fallback).split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
573
+ };
574
+ var joinOxford = (items) => {
575
+ if (items.length === 0) return "";
576
+ if (items.length === 1) return items[0];
577
+ return items.slice(0, -1).join(", ") + " or " + items.slice(-1)[0];
578
+ };
579
+
357
580
  // src/utils/thread.utils.ts
358
581
  var sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
359
582
  var yieldToMainThread = () => sleep(0);
@@ -426,6 +649,24 @@ var hasScheme = (uri) => {
426
649
  var extractBase64FromDataUri = (dataUri) => {
427
650
  return dataUri.split(",")[1] ?? dataUri;
428
651
  };
652
+ var encodeUrl = (value) => {
653
+ if (!value) return "";
654
+ return encodeURIComponent(value);
655
+ };
656
+ var decodeUrl = (value) => {
657
+ if (!value) return "";
658
+ try {
659
+ return decodeURIComponent(value);
660
+ } catch {
661
+ return value;
662
+ }
663
+ };
664
+ var formatDataUri = ({ mimeType, base64 }) => {
665
+ return `data:${mimeType};base64,${base64}`;
666
+ };
667
+ var getBase64ApproxSize = (base64) => {
668
+ return Math.round(base64.length * 3 / 4);
669
+ };
429
670
 
430
671
  // src/utils/websocket.utils.ts
431
672
  var WEBSOCKET_CONNECT_STATES = [WebSocket.CONNECTING, WebSocket.OPEN];
@@ -445,6 +686,6 @@ var closeWebSocket = (ws) => {
445
686
  }
446
687
  };
447
688
 
448
- export { DATA_URI_PATTERN, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
689
+ export { DATA_URI_PATTERN, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, decodeBase64, decodeUrl, encodeBase64, encodeUrl, escapeHtml, extractBase64FromDataUri, firstSentence, formatCount, formatDataUri, formatDuration, formatIntegerDisplay, formatJson, formatUnixTimestamp, formatWithSpaceSeparator, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getBase64ApproxSize, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isMinifiedJson, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isValidDataUri, isValidJson, isWsClosable, isWsOpenOrConnecting, joinOxford, minifyJson, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, parseWithSpaceSeparator, prettifyJson, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, safeJsonParse, safeJsonStringify, sleep, slugify, sortObjectKeys, tickFormatter, titleFromName, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, unescapeHtml, yieldToMainThread };
449
690
  //# sourceMappingURL=index.js.map
450
691
  //# sourceMappingURL=index.js.map