@rt-tools/utils 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1567 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, HostBinding, Directive, effect, inject, booleanAttribute, InjectionToken, Injectable, Injector, signal, computed, HostListener, DestroyRef, output, Pipe } from '@angular/core';
3
+ import { isNil, WINDOW, PlatformService } from '@rt-tools/core';
4
+ export { MessageBus, PlatformService, WINDOW, isNil } from '@rt-tools/core';
5
+ import { Validators, FormControl } from '@angular/forms';
6
+ import { MatTooltip } from '@angular/material/tooltip';
7
+ import { Router, ActivatedRoute } from '@angular/router';
8
+ import { DOCUMENT } from '@angular/common';
9
+ import { BreakpointObserver } from '@angular/cdk/layout';
10
+ import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
+ import { distinctUntilChanged, switchMap, map, filter, take } from 'rxjs/operators';
12
+ import { DomSanitizer } from '@angular/platform-browser';
13
+
14
+ const OVERLAY_POSITIONS = Object.freeze([
15
+ {
16
+ originX: 'start',
17
+ originY: 'bottom',
18
+ overlayX: 'start',
19
+ overlayY: 'top',
20
+ },
21
+ {
22
+ originX: 'end',
23
+ originY: 'bottom',
24
+ overlayX: 'end',
25
+ overlayY: 'top',
26
+ },
27
+ {
28
+ originX: 'start',
29
+ originY: 'bottom',
30
+ overlayX: 'start',
31
+ overlayY: 'top',
32
+ },
33
+ {
34
+ originX: 'start',
35
+ originY: 'top',
36
+ overlayX: 'start',
37
+ overlayY: 'bottom',
38
+ },
39
+ ]);
40
+
41
+ const DASH = '—';
42
+
43
+ class RtIconOutlinedDirective {
44
+ constructor() {
45
+ this.isOutlined = input(false, { ...(ngDevMode ? { debugName: "isOutlined" } : {}), alias: 'rtIconOutlined',
46
+ transform: (value) => {
47
+ return Boolean(value);
48
+ } });
49
+ }
50
+ get fontVariationSettings() {
51
+ // eslint-disable-next-line quotes
52
+ return this.isOutlined() ? "'FILL' 0, 'wght' 700, 'GRAD' 0, 'opsz' 48" : "'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48";
53
+ }
54
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtIconOutlinedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
55
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtIconOutlinedDirective, isStandalone: true, selector: "mat-icon[rtIconOutlined]", inputs: { isOutlined: { classPropertyName: "isOutlined", publicName: "rtIconOutlined", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.fontVariationSettings": "this.fontVariationSettings" } }, ngImport: i0 }); }
56
+ }
57
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtIconOutlinedDirective, decorators: [{
58
+ type: Directive,
59
+ args: [{
60
+ selector: 'mat-icon[rtIconOutlined]',
61
+ }]
62
+ }], propDecorators: { isOutlined: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtIconOutlined", required: false }] }], fontVariationSettings: [{
63
+ type: HostBinding,
64
+ args: ['style.fontVariationSettings']
65
+ }] } });
66
+
67
+ /**
68
+ * Date formatting and parsing utilities (replacement for date-fns)
69
+ *
70
+ * Supported format tokens:
71
+ * - yyyy: 4-digit year (2024)
72
+ * - yy: 2-digit year (24)
73
+ * - MM: 2-digit month (01-12)
74
+ * - M: month (1-12)
75
+ * - dd: 2-digit day (01-31)
76
+ * - d: day (1-31)
77
+ * - HH: 2-digit hour 24h (00-23)
78
+ * - H: hour 24h (0-23)
79
+ * - hh: 2-digit hour 12h (01-12)
80
+ * - h: hour 12h (1-12)
81
+ * - mm: 2-digit minutes (00-59)
82
+ * - m: minutes (0-59)
83
+ * - ss: 2-digit seconds (00-59)
84
+ * - s: seconds (0-59)
85
+ * - SSS: milliseconds (000-999)
86
+ * - a: AM/PM
87
+ * - EEEE: full weekday name (Monday)
88
+ * - EEE: short weekday name (Mon)
89
+ * - MMMM: full month name (January)
90
+ * - MMM: short month name (Jan)
91
+ */
92
+ const WEEKDAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
93
+ const WEEKDAYS_LONG = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
94
+ const MONTHS_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
95
+ const MONTHS_LONG = [
96
+ 'January',
97
+ 'February',
98
+ 'March',
99
+ 'April',
100
+ 'May',
101
+ 'June',
102
+ 'July',
103
+ 'August',
104
+ 'September',
105
+ 'October',
106
+ 'November',
107
+ 'December',
108
+ ];
109
+ /**
110
+ * Escapes special regex characters in a string
111
+ */
112
+ function escapeRegExp(str) {
113
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
114
+ }
115
+ /**
116
+ * Pads a number with leading zeros
117
+ */
118
+ function padStart(value, length) {
119
+ return String(value).padStart(length, '0');
120
+ }
121
+ /**
122
+ * Checks if a value is a valid Date object
123
+ */
124
+ function isDate(value) {
125
+ return value instanceof Date && !isNaN(value.getTime());
126
+ }
127
+ /**
128
+ * Formats a Date object according to the specified format string
129
+ *
130
+ * @param date - The date to format
131
+ * @param formatStr - The format string (e.g., 'dd.MM.yyyy', 'yyyy-MM-dd HH:mm:ss')
132
+ * @returns Formatted date string
133
+ *
134
+ * @example
135
+ * formatDate(new Date(2024, 0, 15), 'dd.MM.yyyy') // '15.01.2024'
136
+ * formatDate(new Date(2024, 0, 15, 14, 30), 'yyyy-MM-dd HH:mm') // '2024-01-15 14:30'
137
+ */
138
+ function formatDate(date, formatStr) {
139
+ if (!isDate(date)) {
140
+ return '';
141
+ }
142
+ const year = date.getFullYear();
143
+ const month = date.getMonth();
144
+ const day = date.getDate();
145
+ const hours = date.getHours();
146
+ const minutes = date.getMinutes();
147
+ const seconds = date.getSeconds();
148
+ const milliseconds = date.getMilliseconds();
149
+ const dayOfWeek = date.getDay();
150
+ const hours12 = hours % 12 || 12;
151
+ const ampm = hours < 12 ? 'AM' : 'PM';
152
+ // Use placeholders to avoid partial replacements
153
+ const placeholders = new Map();
154
+ let placeholderIndex = 0;
155
+ const createPlaceholder = (value) => {
156
+ const placeholder = `\x00${placeholderIndex++}\x00`;
157
+ placeholders.set(placeholder, value);
158
+ return placeholder;
159
+ };
160
+ // Order matters: longer tokens must be replaced first
161
+ // Use exact token matching to prevent partial replacements
162
+ let result = formatStr;
163
+ // Replace tokens with placeholders (longest first)
164
+ result = result.replace(/yyyy/g, createPlaceholder(String(year)));
165
+ result = result.replace(/yy/g, createPlaceholder(String(year).slice(-2)));
166
+ result = result.replace(/MMMM/g, createPlaceholder(MONTHS_LONG[month]));
167
+ result = result.replace(/MMM/g, createPlaceholder(MONTHS_SHORT[month]));
168
+ result = result.replace(/MM/g, createPlaceholder(padStart(month + 1, 2)));
169
+ result = result.replace(/M/g, createPlaceholder(String(month + 1)));
170
+ result = result.replace(/EEEE/g, createPlaceholder(WEEKDAYS_LONG[dayOfWeek]));
171
+ result = result.replace(/EEE/g, createPlaceholder(WEEKDAYS_SHORT[dayOfWeek]));
172
+ result = result.replace(/dd/g, createPlaceholder(padStart(day, 2)));
173
+ result = result.replace(/d/g, createPlaceholder(String(day)));
174
+ result = result.replace(/HH/g, createPlaceholder(padStart(hours, 2)));
175
+ result = result.replace(/H/g, createPlaceholder(String(hours)));
176
+ result = result.replace(/hh/g, createPlaceholder(padStart(hours12, 2)));
177
+ result = result.replace(/h/g, createPlaceholder(String(hours12)));
178
+ result = result.replace(/mm/g, createPlaceholder(padStart(minutes, 2)));
179
+ result = result.replace(/m/g, createPlaceholder(String(minutes)));
180
+ result = result.replace(/SSS/g, createPlaceholder(padStart(milliseconds, 3)));
181
+ result = result.replace(/ss/g, createPlaceholder(padStart(seconds, 2)));
182
+ result = result.replace(/s/g, createPlaceholder(String(seconds)));
183
+ result = result.replace(/a/g, createPlaceholder(ampm));
184
+ // Replace placeholders with actual values
185
+ for (const [placeholder, value] of placeholders) {
186
+ result = result.replace(placeholder, value);
187
+ }
188
+ return result;
189
+ }
190
+ /**
191
+ * Parses an ISO 8601 date string into a Date object
192
+ *
193
+ * @param dateString - ISO date string (e.g., '2024-01-15', '2024-01-15T14:30:00.000Z')
194
+ * @returns Date object or Invalid Date if parsing fails
195
+ *
196
+ * @example
197
+ * parseISO('2024-01-15') // Date object for Jan 15, 2024
198
+ * parseISO('2024-01-15T14:30:00.000Z') // Date object with time
199
+ */
200
+ function parseISO(dateString) {
201
+ if (!dateString || typeof dateString !== 'string') {
202
+ return new Date(NaN);
203
+ }
204
+ const date = new Date(dateString);
205
+ return date;
206
+ }
207
+ /**
208
+ * Parses a date string according to the specified format
209
+ *
210
+ * @param dateString - The date string to parse
211
+ * @param formatStr - The format string describing the input
212
+ * @param referenceDate - Reference date for missing parts (defaults to current date)
213
+ * @returns Date object or Invalid Date if parsing fails
214
+ *
215
+ * @example
216
+ * parseDate('15.01.2024', 'dd.MM.yyyy') // Date object for Jan 15, 2024
217
+ * parseDate('2024/01/15 14:30', 'yyyy/MM/dd HH:mm') // Date with time
218
+ */
219
+ function parseDate(dateString, formatStr, referenceDate = new Date()) {
220
+ if (!dateString || typeof dateString !== 'string') {
221
+ return new Date(NaN);
222
+ }
223
+ let year = referenceDate.getFullYear();
224
+ let month = referenceDate.getMonth();
225
+ let day = referenceDate.getDate();
226
+ let hours = 0;
227
+ let minutes = 0;
228
+ let seconds = 0;
229
+ let milliseconds = 0;
230
+ let isPM = false;
231
+ let hasAMPM = false;
232
+ const tokenPatterns = [
233
+ {
234
+ token: 'yyyy',
235
+ pattern: '(\\d{4})',
236
+ handler: (val) => {
237
+ year = parseInt(val, 10);
238
+ },
239
+ },
240
+ {
241
+ token: 'yy',
242
+ pattern: '(\\d{2})',
243
+ handler: (val) => {
244
+ const parsed = parseInt(val, 10);
245
+ year = parsed >= 70 ? 1900 + parsed : 2000 + parsed;
246
+ },
247
+ },
248
+ {
249
+ token: 'MMMM',
250
+ pattern: `(${MONTHS_LONG.join('|')})`,
251
+ handler: (val) => {
252
+ month = MONTHS_LONG.findIndex((m) => m.toLowerCase() === val.toLowerCase());
253
+ },
254
+ },
255
+ {
256
+ token: 'MMM',
257
+ pattern: `(${MONTHS_SHORT.join('|')})`,
258
+ handler: (val) => {
259
+ month = MONTHS_SHORT.findIndex((m) => m.toLowerCase() === val.toLowerCase());
260
+ },
261
+ },
262
+ {
263
+ token: 'MM',
264
+ pattern: '(\\d{2})',
265
+ handler: (val) => {
266
+ month = parseInt(val, 10) - 1;
267
+ },
268
+ },
269
+ {
270
+ token: 'M',
271
+ pattern: '(\\d{1,2})',
272
+ handler: (val) => {
273
+ month = parseInt(val, 10) - 1;
274
+ },
275
+ },
276
+ {
277
+ token: 'dd',
278
+ pattern: '(\\d{2})',
279
+ handler: (val) => {
280
+ day = parseInt(val, 10);
281
+ },
282
+ },
283
+ {
284
+ token: 'd',
285
+ pattern: '(\\d{1,2})',
286
+ handler: (val) => {
287
+ day = parseInt(val, 10);
288
+ },
289
+ },
290
+ {
291
+ token: 'HH',
292
+ pattern: '(\\d{2})',
293
+ handler: (val) => {
294
+ hours = parseInt(val, 10);
295
+ },
296
+ },
297
+ {
298
+ token: 'H',
299
+ pattern: '(\\d{1,2})',
300
+ handler: (val) => {
301
+ hours = parseInt(val, 10);
302
+ },
303
+ },
304
+ {
305
+ token: 'hh',
306
+ pattern: '(\\d{2})',
307
+ handler: (val) => {
308
+ hours = parseInt(val, 10);
309
+ },
310
+ },
311
+ {
312
+ token: 'h',
313
+ pattern: '(\\d{1,2})',
314
+ handler: (val) => {
315
+ hours = parseInt(val, 10);
316
+ },
317
+ },
318
+ {
319
+ token: 'mm',
320
+ pattern: '(\\d{2})',
321
+ handler: (val) => {
322
+ minutes = parseInt(val, 10);
323
+ },
324
+ },
325
+ {
326
+ token: 'm',
327
+ pattern: '(\\d{1,2})',
328
+ handler: (val) => {
329
+ minutes = parseInt(val, 10);
330
+ },
331
+ },
332
+ {
333
+ token: 'SSS',
334
+ pattern: '(\\d{3})',
335
+ handler: (val) => {
336
+ milliseconds = parseInt(val, 10);
337
+ },
338
+ },
339
+ {
340
+ token: 'ss',
341
+ pattern: '(\\d{2})',
342
+ handler: (val) => {
343
+ seconds = parseInt(val, 10);
344
+ },
345
+ },
346
+ {
347
+ token: 's',
348
+ pattern: '(\\d{1,2})',
349
+ handler: (val) => {
350
+ seconds = parseInt(val, 10);
351
+ },
352
+ },
353
+ {
354
+ token: 'a',
355
+ pattern: '(AM|PM|am|pm)',
356
+ handler: (val) => {
357
+ hasAMPM = true;
358
+ isPM = val.toUpperCase() === 'PM';
359
+ },
360
+ },
361
+ ];
362
+ // Sort by token length (longer first) to avoid partial matches
363
+ const sortedPatterns = [...tokenPatterns].sort((a, b) => b.token.length - a.token.length);
364
+ // Build regex from format string using placeholders to avoid double-replacement
365
+ // First, replace all tokens in the original format string with placeholders
366
+ let workingFormat = formatStr;
367
+ const placeholderList = [];
368
+ let placeholderIndex = 0;
369
+ for (const { token, pattern, handler } of sortedPatterns) {
370
+ if (workingFormat.includes(token)) {
371
+ const placeholder = `\x00${placeholderIndex++}\x00`;
372
+ workingFormat = workingFormat.split(token).join(placeholder);
373
+ placeholderList.push({ placeholder, pattern, handler });
374
+ }
375
+ }
376
+ // Now escape the remaining literal characters
377
+ let regexStr = escapeRegExp(workingFormat);
378
+ // Replace placeholders with actual regex patterns
379
+ for (const { placeholder, pattern } of placeholderList) {
380
+ regexStr = regexStr.replace(escapeRegExp(placeholder), pattern);
381
+ }
382
+ // Sort handlers by their placeholder position in the original working format
383
+ // to match capture group order (left-to-right in the regex)
384
+ const sortedByPosition = placeholderList
385
+ .map((item) => ({
386
+ placeholder: item.placeholder,
387
+ handler: item.handler,
388
+ position: escapeRegExp(workingFormat).indexOf(escapeRegExp(item.placeholder)),
389
+ }))
390
+ .sort((a, b) => a.position - b.position);
391
+ const handlers = sortedByPosition.map((item) => item.handler);
392
+ const regex = new RegExp(`^${regexStr}$`, 'i');
393
+ const match = dateString.match(regex);
394
+ if (!match) {
395
+ return new Date(NaN);
396
+ }
397
+ // Apply handlers in order
398
+ for (let i = 0; i < handlers.length; i++) {
399
+ if (match[i + 1]) {
400
+ handlers[i](match[i + 1]);
401
+ }
402
+ }
403
+ // Apply AM/PM adjustment after all handlers
404
+ if (hasAMPM) {
405
+ if (isPM && hours < 12) {
406
+ hours += 12;
407
+ }
408
+ else if (!isPM && hours === 12) {
409
+ hours = 0;
410
+ }
411
+ }
412
+ return new Date(year, month, day, hours, minutes, seconds, milliseconds);
413
+ }
414
+
415
+ const MAX_YEAR = 3000;
416
+ function dateStringToDate(date) {
417
+ if (date instanceof Date) {
418
+ return date;
419
+ }
420
+ const firstItem = 1;
421
+ const parsedDate = (date || '')
422
+ .replace(/^(\d)/, '0$1')
423
+ .replace(/\.(\d)\./, '.0$1.')
424
+ .replace('..', '.01.')
425
+ .replace(/^\./, '01.')
426
+ .replace(/(\d{3})\./g, (str) => str.slice(firstItem))
427
+ .replace(/(\d{2}).(\d{2}).(\d{4})/, '$2/$1/$3')
428
+ .replace(/00\//g, '01/');
429
+ const dateValue = new Date(parsedDate);
430
+ if (dateValue.getFullYear() > MAX_YEAR) {
431
+ return new Date();
432
+ }
433
+ return isNaN(dateValue.getTime()) ? new Date() : dateValue;
434
+ }
435
+
436
+ function isDateValid(date) {
437
+ return date instanceof Date && Boolean(date.getTime());
438
+ }
439
+
440
+ /**
441
+ * Indicates if the arguments are equal
442
+ *
443
+ * @param f first parameter to compare
444
+ * @param s second parameter to compare
445
+ */
446
+ function isEqual(f, s) {
447
+ const s1 = JSON.stringify(f).split('').sort().join('');
448
+ const s2 = JSON.stringify(s).split('').sort().join('');
449
+ return s1 === s2;
450
+ }
451
+ /**
452
+ * Indicates if the content of two arrays is identical
453
+ *
454
+ * @param f first array
455
+ * @param s second array
456
+ */
457
+ function areArraysEqual(f, s) {
458
+ if (!Array.isArray(f) || !Array.isArray(s)) {
459
+ return false;
460
+ }
461
+ if (f.length !== s.length) {
462
+ return false;
463
+ }
464
+ for (let i = 0; i < f.length; i++) {
465
+ const valueF = f[i];
466
+ const valueS = s[i];
467
+ if (Array.isArray(valueF) && Array.isArray(valueS)) {
468
+ if (!areArraysEqual(valueF, valueS)) {
469
+ return false;
470
+ }
471
+ }
472
+ if (typeof valueF === 'object' && valueF != null && typeof valueS === 'object' && valueS != null) {
473
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
474
+ if (!areObjectsEqual(valueF, valueS)) {
475
+ return false;
476
+ }
477
+ }
478
+ else if (valueF !== valueS) {
479
+ return false;
480
+ }
481
+ }
482
+ return true;
483
+ }
484
+ /**
485
+ * Indicates if the content of two objects is identical
486
+ *
487
+ * @param f first object
488
+ * @param s second object
489
+ */
490
+ function areObjectsEqual(f, s) {
491
+ /** If it's just the same object - no need to compare */
492
+ if (f === s) {
493
+ return true;
494
+ }
495
+ if (Array.isArray(f) && Array.isArray(s)) {
496
+ return areArraysEqual(f, s);
497
+ }
498
+ /** If one of the objects is null or undefined - no need to compare */
499
+ if (typeof f === 'object' && f != null && typeof s === 'object' && s != null) {
500
+ const keysF = Object.keys(f);
501
+ const keysS = Object.keys(s);
502
+ if (keysF.length != keysS.length) {
503
+ return false;
504
+ }
505
+ for (const key in f) {
506
+ if (!areObjectsEqual(f[key], s[key])) {
507
+ return false;
508
+ }
509
+ }
510
+ return true;
511
+ }
512
+ return false;
513
+ }
514
+ /**
515
+ * Checks whether two arrays are equal regardless of the order of their elements.
516
+ * Supports deep comparison of nested arrays and objects.
517
+ *
518
+ * @template T The type of elements in the arrays
519
+ * @param f first array
520
+ * @param s second array
521
+ * @returns True if the arrays contain the same elements in any order, false otherwise
522
+ */
523
+ function areArraysEqualUnordered(f, s) {
524
+ if (!Array.isArray(f) || !Array.isArray(s)) {
525
+ return false;
526
+ }
527
+ if (f.length !== s.length) {
528
+ return false;
529
+ }
530
+ const used = new Array(s.length).fill(false);
531
+ for (const valueF of f) {
532
+ let found = false;
533
+ for (let i = 0; i < s.length; i++) {
534
+ if (used[i]) {
535
+ continue;
536
+ }
537
+ const valueS = s[i];
538
+ if (Array.isArray(valueF) && Array.isArray(valueS)) {
539
+ if (areArraysEqualUnordered(valueF, valueS)) {
540
+ used[i] = true;
541
+ found = true;
542
+ break;
543
+ }
544
+ }
545
+ else if (typeof valueF === 'object' && valueF != null && typeof valueS === 'object' && valueS != null) {
546
+ if (areObjectsEqual(valueF, valueS)) {
547
+ used[i] = true;
548
+ found = true;
549
+ break;
550
+ }
551
+ }
552
+ else if (valueF === valueS) {
553
+ used[i] = true;
554
+ found = true;
555
+ break;
556
+ }
557
+ }
558
+ if (!found) {
559
+ return false;
560
+ }
561
+ }
562
+ return true;
563
+ }
564
+
565
+ function isNumber(value) {
566
+ return typeof value === 'number';
567
+ }
568
+
569
+ function isRecord(value) {
570
+ return value?.constructor === Object;
571
+ }
572
+
573
+ function isString(value) {
574
+ return typeof value === 'string';
575
+ }
576
+
577
+ function initToday() {
578
+ const today = new Date();
579
+ today.setHours(0, 0, 0, 0);
580
+ return today;
581
+ }
582
+ function isToday(date) {
583
+ const today = initToday();
584
+ return date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear();
585
+ }
586
+
587
+ /** Makes shallow copy of passed object */
588
+ function removeFieldFromObject(obj, key) {
589
+ const result = { ...obj };
590
+ if (key in obj) {
591
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
592
+ delete result[key];
593
+ }
594
+ return result;
595
+ }
596
+
597
+ /**
598
+ * Allow to compare two values by provided comparator
599
+ *
600
+ * @param a - T
601
+ * @param b - T
602
+ * @param comparator - ComparatorType<T>
603
+ */
604
+ function safeCompare(a, b, comparator) {
605
+ if (a == null) {
606
+ if (b == null) {
607
+ return 0;
608
+ }
609
+ else {
610
+ return 1;
611
+ }
612
+ }
613
+ else {
614
+ if (b == null) {
615
+ return -1;
616
+ }
617
+ else {
618
+ return comparator(a, b);
619
+ }
620
+ }
621
+ }
622
+ /**
623
+ * Allow to safely compare two string values
624
+ *
625
+ * @param a string
626
+ * @param b string
627
+ */
628
+ function safeStrCompare(a, b) {
629
+ return safeCompare(a, b, () => a.localeCompare(b));
630
+ }
631
+ /**
632
+ * Allow to safely compare two number values
633
+ *
634
+ * @param a number
635
+ * @param b number
636
+ */
637
+ function safeNumCompare(a, b) {
638
+ return safeCompare(a, b, () => a - b);
639
+ }
640
+ /**
641
+ * Allow composing comparison chain of several comparators
642
+ * that delegate comparison by the chain to the next comparators if current comparator returns 0
643
+ *
644
+ * @param comparators - Array<() => number>
645
+ */
646
+ function safeComparatorPipe(...comparators) {
647
+ let result = 0;
648
+ for (let i = 0, len = comparators.length; i < len; i++) {
649
+ result = comparators[i]();
650
+ if (result !== 0) {
651
+ break;
652
+ }
653
+ }
654
+ return result;
655
+ }
656
+
657
+ const sortByAlphabet = (a, b, field) => {
658
+ if (a[field] && typeof a[field] === 'string' && b[field] && typeof b[field] === 'string') {
659
+ if (a[field].toLowerCase() < b[field].toLowerCase()) {
660
+ return -1;
661
+ }
662
+ if (a[field].toLowerCase() > b[field].toLowerCase()) {
663
+ return 1;
664
+ }
665
+ }
666
+ return 0;
667
+ };
668
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
669
+ const sortByDate = (
670
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
671
+ a,
672
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
673
+ b, field) => new Date(a[field]).getTime() - new Date(b[field]).getTime();
674
+
675
+ function stringifyHttpLikeParams(params) {
676
+ return Object.keys(params).reduce((stringParams, key) => ({
677
+ ...stringParams,
678
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
679
+ [key]: encodeURI(params[key]),
680
+ }), {});
681
+ }
682
+
683
+ function transformArrayInput(array) {
684
+ if (Array.isArray(array) && array.length) {
685
+ return array;
686
+ }
687
+ else {
688
+ return [];
689
+ }
690
+ }
691
+
692
+ function transformStringInput(value) {
693
+ return isString(value) ? value : '';
694
+ }
695
+
696
+ function checkIsEntityInArrayByKey(selectedEntities, entity, keyExp) {
697
+ return !!selectedEntities.find((selectedEntity) => {
698
+ return (Object.prototype.hasOwnProperty.call(selectedEntity, keyExp) &&
699
+ Object.prototype.hasOwnProperty.call(entity, keyExp) &&
700
+ selectedEntity[keyExp] === entity[keyExp]);
701
+ });
702
+ }
703
+
704
+ function emptyToDash(value) {
705
+ return isNil(value) || value === '' ? DASH : value;
706
+ }
707
+
708
+ /**
709
+ * Check if the email is valid
710
+ * @param email
711
+ */
712
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
713
+ function isEmail(email) {
714
+ return !Boolean(Validators.email(new FormControl(email)));
715
+ }
716
+
717
+ function isEmptyArray(value) {
718
+ return value.length === 0;
719
+ }
720
+
721
+ function isEmptyObject(value) {
722
+ return isEmptyArray(Object.keys(value));
723
+ }
724
+
725
+ function isEmptyString(value) {
726
+ return value.length === 0;
727
+ }
728
+
729
+ function isObject(value) {
730
+ return typeof value === 'object';
731
+ }
732
+
733
+ function isEmpty(value) {
734
+ if (isNil(value)) {
735
+ return true;
736
+ }
737
+ if (isObject(value)) {
738
+ if (Array.isArray(value)) {
739
+ return isEmptyArray(value);
740
+ }
741
+ if (!(value instanceof Date)) {
742
+ return isEmptyObject(value);
743
+ }
744
+ }
745
+ if (isString(value)) {
746
+ return isEmptyString(value);
747
+ }
748
+ return false;
749
+ }
750
+
751
+ function debounce(timeout = 300) {
752
+ return function (_target, _key, descriptor) {
753
+ const timeoutRefs = new WeakMap();
754
+ const { value } = descriptor;
755
+ descriptor.value = function (...args) {
756
+ const timeoutRef = timeoutRefs.get(this);
757
+ if (timeoutRef !== undefined) {
758
+ clearTimeout(timeoutRef);
759
+ }
760
+ timeoutRefs.set(this, setTimeout(() => value.apply(this, args), timeout));
761
+ };
762
+ return descriptor;
763
+ };
764
+ }
765
+
766
+ var HAS_OWN_SCOPE_ENUM;
767
+ (function (HAS_OWN_SCOPE_ENUM) {
768
+ HAS_OWN_SCOPE_ENUM["ANY"] = "any";
769
+ HAS_OWN_SCOPE_ENUM["OWN"] = "own";
770
+ HAS_OWN_SCOPE_ENUM["INHERITED"] = "inherited";
771
+ })(HAS_OWN_SCOPE_ENUM || (HAS_OWN_SCOPE_ENUM = {}));
772
+ const safetyHasOwn = (o, k) => {
773
+ const native = Object.hasOwn;
774
+ return typeof native === 'function' ? native(o, k) : Object.prototype.hasOwnProperty.call(o, k);
775
+ };
776
+ /**
777
+ * Safe property existence check with configurable scope.
778
+ *
779
+ * - Returns `false` for `null`/`undefined`.
780
+ * - Boxes primitives (e.g., strings, numbers) so prototype checks work.
781
+ * - Does **not** invoke getters; relies on `in` and an own-check helper.
782
+ * - Uses `Object.hasOwn` when available; **falls back** to
783
+ * `Object.prototype.hasOwnProperty.call` on older runtimes.
784
+ *
785
+ * @param obj {unknown} - Value to check. `null`/`undefined` short-circuit to `false`.
786
+ * @param key {PropertyKey} - Property key (string | number | symbol).
787
+ * @param scope {IHasScopeType} - Check mode: `'any'` (default), `'own'`, or `'inherited'`.
788
+ *
789
+ * @returns `true` if the property exists under the selected scope.
790
+ *
791
+ * @example
792
+ * hasPropertyInChain({ a: 1 }, 'a'); // true (ANY)
793
+ * hasPropertyInChain(Object.create({ a: 1 }), 'a', HAS_OWN_SCOPE_ENUM.INHERITED); // true
794
+ * hasPropertyInChain({ a: 1 }, 'b', HAS_OWN_SCOPE_ENUM.OWN); // false
795
+ */
796
+ function hasPropertyInChain(obj, key, scope = HAS_OWN_SCOPE_ENUM.OWN) {
797
+ if (obj === undefined || obj === null) {
798
+ return false;
799
+ }
800
+ const o = Object(obj);
801
+ switch (scope) {
802
+ case HAS_OWN_SCOPE_ENUM.OWN:
803
+ return safetyHasOwn(o, key);
804
+ case HAS_OWN_SCOPE_ENUM.INHERITED:
805
+ return key in o && !safetyHasOwn(o, key);
806
+ default:
807
+ return key in o;
808
+ }
809
+ }
810
+
811
+ class RtScrollToElementDirective {
812
+ constructor() {
813
+ this.rtScrollToElement = input.required({ ...(ngDevMode ? { debugName: "rtScrollToElement" } : {}) });
814
+ this.elements = input.required({ ...(ngDevMode ? { debugName: "elements" } : {}), transform: (value) => transformArrayInput(value) });
815
+ effect(() => {
816
+ if (this.elements()?.length && this.rtScrollToElement()) {
817
+ this.#scrollToTarget();
818
+ }
819
+ });
820
+ }
821
+ #scrollToTarget() {
822
+ const targetId = this.rtScrollToElement();
823
+ const targetElement = document.getElementById(targetId.toString());
824
+ targetElement?.scrollIntoView({ behavior: 'smooth', block: 'start' });
825
+ }
826
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollToElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
827
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtScrollToElementDirective, isStandalone: true, selector: "[rtScrollToElement]", inputs: { rtScrollToElement: { classPropertyName: "rtScrollToElement", publicName: "rtScrollToElement", isSignal: true, isRequired: true, transformFunction: null }, elements: { classPropertyName: "elements", publicName: "elements", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
828
+ }
829
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollToElementDirective, decorators: [{
830
+ type: Directive,
831
+ args: [{
832
+ selector: '[rtScrollToElement]',
833
+ }]
834
+ }], ctorParameters: () => [], propDecorators: { rtScrollToElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtScrollToElement", required: true }] }], elements: [{ type: i0.Input, args: [{ isSignal: true, alias: "elements", required: true }] }] } });
835
+
836
+ class RtHideTooltipDirective {
837
+ #matTooltip;
838
+ /** Set tooltip state by 'isTooltipShown' */
839
+ constructor() {
840
+ this.#matTooltip = inject(MatTooltip);
841
+ /** Current HTMLElement */
842
+ this.element = input.required({ ...(ngDevMode ? { debugName: "element" } : {}), alias: 'rtHideTooltipDirective' });
843
+ /** Indicates is tooltip shown */
844
+ this.isTooltipShown = input.required({ ...(ngDevMode ? { debugName: "isTooltipShown" } : {}), transform: booleanAttribute });
845
+ effect(() => {
846
+ if (this.isTooltipShown()) {
847
+ this.#setTooltipState();
848
+ }
849
+ else {
850
+ this.#matTooltip.disabled = true;
851
+ }
852
+ });
853
+ }
854
+ ngAfterViewInit() {
855
+ const element = this.element();
856
+ /** Set tooltip state when HTMLElement changed */
857
+ if (element) {
858
+ const observer = new MutationObserver(() => {
859
+ if (this.isTooltipShown()) {
860
+ this.#setTooltipState();
861
+ }
862
+ });
863
+ observer.observe(element, {
864
+ childList: true,
865
+ characterData: true,
866
+ subtree: true,
867
+ });
868
+ if (this.isTooltipShown()) {
869
+ this.#setTooltipState();
870
+ }
871
+ }
872
+ }
873
+ /** Set tooltip state by container and content width */
874
+ #setTooltipState() {
875
+ this.#matTooltip.disabled = this.element()?.offsetWidth === this.element()?.scrollWidth;
876
+ }
877
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtHideTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
878
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtHideTooltipDirective, isStandalone: true, selector: "[rtHideTooltipDirective]", inputs: { element: { classPropertyName: "element", publicName: "rtHideTooltipDirective", isSignal: true, isRequired: true, transformFunction: null }, isTooltipShown: { classPropertyName: "isTooltipShown", publicName: "isTooltipShown", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
879
+ }
880
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtHideTooltipDirective, decorators: [{
881
+ type: Directive,
882
+ args: [{
883
+ selector: '[rtHideTooltipDirective]',
884
+ }]
885
+ }], ctorParameters: () => [], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtHideTooltipDirective", required: true }] }], isTooltipShown: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTooltipShown", required: true }] }] } });
886
+
887
+ class AsideRef {
888
+ constructor(answer, overlayRef, component, position, data) {
889
+ this.answer = answer;
890
+ this.overlayRef = overlayRef;
891
+ this.component = component;
892
+ this.position = position;
893
+ this.data = data;
894
+ }
895
+ close(answer) {
896
+ this.answer.next(answer ?? null);
897
+ }
898
+ }
899
+ const ASIDE_REF = new InjectionToken('ASIDE_REF');
900
+ const ddServices = [
901
+ { provide: 'ddData', useValue: undefined },
902
+ { provide: 'ddAnswer', useValue: undefined },
903
+ { provide: 'ddOverlay', useValue: undefined },
904
+ ];
905
+
906
+ const NAVIGATOR = new InjectionToken('An injection token for global navigator object', {
907
+ factory: () => {
908
+ const { defaultView } = inject(DOCUMENT);
909
+ if (!defaultView || !defaultView?.navigator) {
910
+ throw new Error('Navigator is not available');
911
+ }
912
+ return defaultView.navigator;
913
+ },
914
+ });
915
+
916
+ var OSTypes;
917
+ (function (OSTypes) {
918
+ OSTypes.WINDOWS = 'Windows';
919
+ OSTypes.MAC_OS = 'Mac OS';
920
+ OSTypes.LINUX = 'Linux';
921
+ OSTypes.ANDROID = 'Android';
922
+ OSTypes.IOS = 'iOS';
923
+ OSTypes.UNKNOWN = 'Unknown';
924
+ })(OSTypes || (OSTypes = {}));
925
+ class DeviceDetectorService {
926
+ #windowRef;
927
+ #navigatorRef;
928
+ #platformService;
929
+ constructor() {
930
+ this.#windowRef = inject(WINDOW);
931
+ this.#navigatorRef = inject(NAVIGATOR);
932
+ this.#platformService = inject(PlatformService);
933
+ this.userAgent = null;
934
+ if (this.#platformService.isPlatformBrowser &&
935
+ typeof this.#windowRef !== 'undefined' &&
936
+ typeof this.#navigatorRef !== 'undefined' &&
937
+ this.#navigatorRef?.userAgent) {
938
+ this.userAgent = this.#navigatorRef.userAgent;
939
+ }
940
+ }
941
+ isMobile() {
942
+ return this.userAgent ? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent) : false;
943
+ }
944
+ isTablet() {
945
+ return this.userAgent ? /iPad|Android|Tablet/i.test(this.userAgent) : false;
946
+ }
947
+ isDesktop() {
948
+ return !this.isMobile() && !this.isTablet();
949
+ }
950
+ getOS() {
951
+ let os;
952
+ if (this.userAgent && /Windows/i.test(this.userAgent)) {
953
+ os = OSTypes.WINDOWS;
954
+ }
955
+ else if (this.userAgent && /Macintosh|Mac OS/i.test(this.userAgent)) {
956
+ os = OSTypes.MAC_OS;
957
+ }
958
+ else if (this.userAgent && /Linux/i.test(this.userAgent)) {
959
+ os = OSTypes.LINUX;
960
+ }
961
+ else if (this.userAgent && /Android/i.test(this.userAgent)) {
962
+ os = OSTypes.ANDROID;
963
+ }
964
+ else if (this.userAgent && /iOS/i.test(this.userAgent)) {
965
+ os = OSTypes.IOS;
966
+ }
967
+ else {
968
+ os = OSTypes.UNKNOWN;
969
+ }
970
+ return os;
971
+ }
972
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
973
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService }); }
974
+ }
975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService, decorators: [{
976
+ type: Injectable
977
+ }], ctorParameters: () => [] });
978
+
979
+ class Breakpoints {
980
+ constructor() {
981
+ this.xl = '1920px';
982
+ this.lg = '1280px';
983
+ this.md = '960px';
984
+ this.sm = '720px';
985
+ this.xs = '600px';
986
+ }
987
+ }
988
+
989
+ /**
990
+ * A service that manages responsive design breakpoints using Angular's `BreakpointObserver`.
991
+ * This service provides signals for different screen sizes and allows dynamic
992
+ * breakpoint management.
993
+ *
994
+ * @Injectable
995
+ */
996
+ class BreakpointService {
997
+ constructor() {
998
+ /**
999
+ * Private instance of BreakpointObserver used to observe screen size changes.
1000
+ */
1001
+ this.#breakpointObserver = inject(BreakpointObserver);
1002
+ /**
1003
+ * Private instance of Injector.
1004
+ */
1005
+ this.#injector = inject(Injector);
1006
+ /**
1007
+ * Instance of a lass containing the breakpoint values for different screen sizes.
1008
+ */
1009
+ this.#breakpoints = signal(new Breakpoints(), { ...(ngDevMode ? { debugName: "#breakpoints" } : {}) });
1010
+ this.#desktopQuery = computed(() => `(min-width: ${this.#breakpoints().xl})`, { ...(ngDevMode ? { debugName: "#desktopQuery" } : {}) });
1011
+ this.#smallDesktopQuery = computed(() => `(min-width: ${this.#breakpoints().lg})`, { ...(ngDevMode ? { debugName: "#smallDesktopQuery" } : {}) });
1012
+ this.#tabletQuery = computed(() => `(min-width: ${this.#breakpoints().md})`, { ...(ngDevMode ? { debugName: "#tabletQuery" } : {}) });
1013
+ this.#smallTabletQuery = computed(() => `(min-width: ${this.#breakpoints().sm})`, { ...(ngDevMode ? { debugName: "#smallTabletQuery" } : {}) });
1014
+ this.#mobileQuery = computed(() => `(max-width: ${this.decrementOnePixel(this.#breakpoints().xs)})`, { ...(ngDevMode ? { debugName: "#mobileQuery" } : {}) });
1015
+ this.isDesktop = toSignal(toObservable(this.#desktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
1016
+ this.isSmallDesktop = toSignal(toObservable(this.#smallDesktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
1017
+ this.isMobile = toSignal(toObservable(this.#mobileQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
1018
+ this.isTablet = toSignal(toObservable(this.#tabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => !matches)));
1019
+ this.isSmallTablet = toSignal(toObservable(this.#smallTabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
1020
+ }
1021
+ /**
1022
+ * Private instance of BreakpointObserver used to observe screen size changes.
1023
+ */
1024
+ #breakpointObserver;
1025
+ /**
1026
+ * Private instance of Injector.
1027
+ */
1028
+ #injector;
1029
+ /**
1030
+ * Instance of a lass containing the breakpoint values for different screen sizes.
1031
+ */
1032
+ #breakpoints;
1033
+ #desktopQuery;
1034
+ #smallDesktopQuery;
1035
+ #tabletQuery;
1036
+ #smallTabletQuery;
1037
+ #mobileQuery;
1038
+ /**
1039
+ * Allows setting custom breakpoints for different screen sizes.
1040
+ *
1041
+ * @param breakpoints - The custom breakpoints to apply.
1042
+ */
1043
+ setBreakpoints(breakpoints) {
1044
+ this.#breakpoints.set(breakpoints);
1045
+ }
1046
+ /**
1047
+ * Helper function to decrement the pixel value by 1.
1048
+ * Used to exclude the exact pixel value in media queries.
1049
+ *
1050
+ * @usageNotes
1051
+ *
1052
+ * This function is useful for setting correct media queries.
1053
+ * E.g. for mobile devices: media query should be `(max-width: 599px)`,
1054
+ * and from `(min-width: 600px)` it should be considered as a tablet.
1055
+ *
1056
+ * @param value - The pixel value to decrement.
1057
+ * @returns The adjusted pixel value as a string.
1058
+ */
1059
+ decrementOnePixel(value) {
1060
+ return Number(value.split('px')[0]) - 1 + 'px';
1061
+ }
1062
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1063
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService }); }
1064
+ }
1065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService, decorators: [{
1066
+ type: Injectable
1067
+ }] });
1068
+
1069
+ class RtNavigationDirective {
1070
+ constructor() {
1071
+ this.#router = inject(Router);
1072
+ this.#windowRef = inject(WINDOW);
1073
+ this.#platformService = inject(PlatformService);
1074
+ this.link = input.required({ ...(ngDevMode ? { debugName: "link" } : {}), alias: 'rtNavigationDirective' });
1075
+ }
1076
+ #router;
1077
+ #windowRef;
1078
+ #platformService;
1079
+ onClick(event) {
1080
+ if (this.link()) {
1081
+ if (this.#platformService.isPlatformBrowser && (event.ctrlKey || event.metaKey)) {
1082
+ this.#windowRef.open(this.link());
1083
+ }
1084
+ else {
1085
+ void this.#router.navigate([this.link()]);
1086
+ }
1087
+ }
1088
+ }
1089
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1090
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtNavigationDirective, isStandalone: true, selector: "[rtNavigationDirective]", inputs: { link: { classPropertyName: "link", publicName: "rtNavigationDirective", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, providers: [PlatformService], ngImport: i0 }); }
1091
+ }
1092
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtNavigationDirective, decorators: [{
1093
+ type: Directive,
1094
+ args: [{
1095
+ selector: '[rtNavigationDirective]',
1096
+ providers: [PlatformService],
1097
+ }]
1098
+ }], propDecorators: { link: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtNavigationDirective", required: true }] }], onClick: [{
1099
+ type: HostListener,
1100
+ args: ['click', ['$event']]
1101
+ }] } });
1102
+
1103
+ class RtTabQueryParamDirective {
1104
+ constructor() {
1105
+ this.#router = inject(Router);
1106
+ this.#route = inject(ActivatedRoute);
1107
+ this.#destroyRef = inject(DestroyRef);
1108
+ this.#currentTabIndex = signal(0, { ...(ngDevMode ? { debugName: "#currentTabIndex" } : {}) });
1109
+ this.currentTabIndex = this.#currentTabIndex.asReadonly();
1110
+ }
1111
+ #router;
1112
+ #route;
1113
+ #destroyRef;
1114
+ #currentTabIndex;
1115
+ ngOnInit() {
1116
+ this.#route.queryParamMap
1117
+ .pipe(filter((params) => params.has('tab')), take(1), map((params) => Number(params.get('tab'))), takeUntilDestroyed(this.#destroyRef))
1118
+ .subscribe((tabIndex) => {
1119
+ this.#setTabIndex(tabIndex);
1120
+ });
1121
+ }
1122
+ setQueryTab(index) {
1123
+ void this.#router.navigate([], {
1124
+ relativeTo: this.#route,
1125
+ queryParams: {
1126
+ tab: index,
1127
+ },
1128
+ queryParamsHandling: 'merge',
1129
+ });
1130
+ this.#setTabIndex(index);
1131
+ }
1132
+ #setTabIndex(index) {
1133
+ this.#currentTabIndex.set(index);
1134
+ }
1135
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtTabQueryParamDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1136
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.1", type: RtTabQueryParamDirective, isStandalone: true, ngImport: i0 }); }
1137
+ }
1138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtTabQueryParamDirective, decorators: [{
1139
+ type: Directive
1140
+ }] });
1141
+
1142
+ class RtScrollDirective {
1143
+ constructor() {
1144
+ this.#windowRef = inject(WINDOW);
1145
+ this.#platformService = inject(PlatformService);
1146
+ this.active = input(true, { ...(ngDevMode ? { debugName: "active" } : {}) });
1147
+ this.multiplier = input(0.5, { ...(ngDevMode ? { debugName: "multiplier" } : {}) });
1148
+ this.scrollAction = output();
1149
+ this.scroll = (event) => {
1150
+ const target = event.target;
1151
+ if (this.active() && target.offsetHeight + target.scrollTop >= target.scrollHeight * this.multiplier()) {
1152
+ this.scrollAction.emit();
1153
+ }
1154
+ };
1155
+ }
1156
+ #windowRef;
1157
+ #platformService;
1158
+ ngOnInit() {
1159
+ if (this.#platformService.isPlatformBrowser) {
1160
+ this.#windowRef.addEventListener('scroll', this.scroll, true);
1161
+ }
1162
+ }
1163
+ ngOnDestroy() {
1164
+ this.#windowRef.removeEventListener('scroll', this.scroll, true);
1165
+ }
1166
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1167
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtScrollDirective, isStandalone: true, selector: "[rtScrollDirective]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, multiplier: { classPropertyName: "multiplier", publicName: "multiplier", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrollAction: "scrollAction" }, ngImport: i0 }); }
1168
+ }
1169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollDirective, decorators: [{
1170
+ type: Directive,
1171
+ args: [{
1172
+ selector: '[rtScrollDirective]',
1173
+ }]
1174
+ }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], multiplier: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiplier", required: false }] }], scrollAction: [{ type: i0.Output, args: ["scrollAction"] }] } });
1175
+
1176
+ class RtEscapeKeyDirective {
1177
+ constructor() {
1178
+ this.escapeKeyAction = output();
1179
+ }
1180
+ handleKeyboardEvent(event) {
1181
+ if (event.key === 'Escape') {
1182
+ this.escapeKeyAction.emit();
1183
+ }
1184
+ }
1185
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtEscapeKeyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1186
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.1", type: RtEscapeKeyDirective, isStandalone: true, selector: "[rtEscapeKey]", outputs: { escapeKeyAction: "escapeKeyAction" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0 }); }
1187
+ }
1188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtEscapeKeyDirective, decorators: [{
1189
+ type: Directive,
1190
+ args: [{
1191
+ selector: '[rtEscapeKey]',
1192
+ }]
1193
+ }], propDecorators: { escapeKeyAction: [{ type: i0.Output, args: ["escapeKeyAction"] }], handleKeyboardEvent: [{
1194
+ type: HostListener,
1195
+ args: ['document:keydown', ['$event']]
1196
+ }] } });
1197
+
1198
+ var MODAL_WINDOW_SIZE_ENUM;
1199
+ (function (MODAL_WINDOW_SIZE_ENUM) {
1200
+ MODAL_WINDOW_SIZE_ENUM["SM"] = "25rem";
1201
+ MODAL_WINDOW_SIZE_ENUM["MD"] = "45rem";
1202
+ MODAL_WINDOW_SIZE_ENUM["LG"] = "65rem";
1203
+ MODAL_WINDOW_SIZE_ENUM["FULL"] = "100%";
1204
+ })(MODAL_WINDOW_SIZE_ENUM || (MODAL_WINDOW_SIZE_ENUM = {}));
1205
+
1206
+ var ASIDE_BUTTONS_ENUM;
1207
+ (function (ASIDE_BUTTONS_ENUM) {
1208
+ ASIDE_BUTTONS_ENUM["USER_ACTIVE"] = "User active";
1209
+ ASIDE_BUTTONS_ENUM["USER_INACTIVE"] = "User inactive";
1210
+ ASIDE_BUTTONS_ENUM["DELETE"] = "Delete";
1211
+ ASIDE_BUTTONS_ENUM["RESET"] = "Reset";
1212
+ })(ASIDE_BUTTONS_ENUM || (ASIDE_BUTTONS_ENUM = {}));
1213
+
1214
+ var POSITION_ENUM;
1215
+ (function (POSITION_ENUM) {
1216
+ POSITION_ENUM["LEFT"] = "left";
1217
+ POSITION_ENUM["RIGHT"] = "right";
1218
+ POSITION_ENUM["TOP"] = "top";
1219
+ POSITION_ENUM["BOTTOM"] = "bottom";
1220
+ POSITION_ENUM["START"] = "start";
1221
+ POSITION_ENUM["END"] = "end";
1222
+ POSITION_ENUM["CENTER"] = "center";
1223
+ })(POSITION_ENUM || (POSITION_ENUM = {}));
1224
+
1225
+ class TypeCastHelper {
1226
+ getAsString(data, defaultValue = '') {
1227
+ return !isNil(data) && !Number.isNaN(data) ? String(data) : defaultValue;
1228
+ }
1229
+ getAsNumber(data, defaultValue) {
1230
+ const result = Number(data);
1231
+ return data === null || Number.isNaN(result) ? (defaultValue ?? NaN) : result;
1232
+ }
1233
+ getAsBoolean(data) {
1234
+ const stringExceptions = ['false', '0', 'null'];
1235
+ if (typeof data === 'string' && stringExceptions.includes(data)) {
1236
+ return false;
1237
+ }
1238
+ return Boolean(data);
1239
+ }
1240
+ getAsNull(data, handler) {
1241
+ if (!isNil(data) && !Number.isNaN(data)) {
1242
+ return handler ? handler(data) : data;
1243
+ }
1244
+ return null;
1245
+ }
1246
+ // eslint-disable-next-line
1247
+ getAsType(value, type) {
1248
+ if (!!value && !Object.values(type).includes(value)) {
1249
+ // eslint-disable-next-line no-console
1250
+ console.error(`getAsTyped: the value "${value}" was not found in the specified type`);
1251
+ return 'unknown';
1252
+ }
1253
+ return value;
1254
+ }
1255
+ getAsTypedArray(data, cb, showError = true) {
1256
+ if (!Array.isArray(data)) {
1257
+ if (showError) {
1258
+ // eslint-disable-next-line no-console
1259
+ console.error('getAsTypedArray: Given data must be an array (now it is ' +
1260
+ typeof data +
1261
+ '). Incorrect data will be defined as array of data (data => [data]).');
1262
+ }
1263
+ data = [data];
1264
+ }
1265
+ if (!data.length) {
1266
+ return [];
1267
+ }
1268
+ return data.map(cb);
1269
+ }
1270
+ getAsDate(date, asString, parseFormatOptions, formatOptions) {
1271
+ formatOptions = formatOptions ?? 'dd.MM.yyyy';
1272
+ asString = asString ?? true;
1273
+ const type = typeof date;
1274
+ switch (type) {
1275
+ case 'number':
1276
+ date = new Date(date);
1277
+ break;
1278
+ case 'string':
1279
+ date = !!parseFormatOptions ? parseDate(date, parseFormatOptions, new Date()) : parseISO(date);
1280
+ break;
1281
+ }
1282
+ if (!isDate(date)) {
1283
+ return '';
1284
+ }
1285
+ return asString ? formatDate(date, formatOptions) : date;
1286
+ }
1287
+ }
1288
+
1289
+ class BaseMapper {
1290
+ constructor() {
1291
+ this.typeCast = new TypeCastHelper();
1292
+ }
1293
+ // eslint-disable-next-line
1294
+ mapFrom(data, ...args) {
1295
+ return { ...data };
1296
+ }
1297
+ mapFromArray(data, ...args) {
1298
+ if (!Array.isArray(data)) {
1299
+ // eslint-disable-next-line no-console
1300
+ console.error('mapFromArray: Given data must be an array (now it is ' + typeof data + '). Incorrect data will be defined as empty array.');
1301
+ data = [];
1302
+ }
1303
+ return data.map((entry) => this.mapFrom(entry, ...args));
1304
+ }
1305
+ // eslint-disable-next-line
1306
+ mapTo(model, ...args) {
1307
+ return { ...model };
1308
+ }
1309
+ mapToArray(models, ...args) {
1310
+ if (!Array.isArray(models)) {
1311
+ // eslint-disable-next-line no-console
1312
+ console.error('mapToArray: Given data must be an array (now it is ' + typeof models + '). Incorrect data will be defined as empty array.');
1313
+ models = [];
1314
+ }
1315
+ return models.map((model) => this.mapTo(model, ...args));
1316
+ }
1317
+ }
1318
+
1319
+ class BreakStringPipe {
1320
+ transform(value) {
1321
+ if (isNil(value)) {
1322
+ return DASH;
1323
+ }
1324
+ if (value && isString(value)) {
1325
+ if (/\s/.test(value) || /^[A-Z0-9\s]+$/.test(value) || /\d/.test(value) || /[^\w\s]/.test(value)) {
1326
+ return value;
1327
+ }
1328
+ return value.split(/(?=[A-Z])/).join(' ');
1329
+ }
1330
+ return value.toString();
1331
+ }
1332
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1333
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, isStandalone: true, name: "breakString" }); }
1334
+ }
1335
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, decorators: [{
1336
+ type: Pipe,
1337
+ args: [{
1338
+ name: 'breakString',
1339
+ }]
1340
+ }] });
1341
+
1342
+ class SanitizePipe {
1343
+ #sanitizer = inject(DomSanitizer);
1344
+ transform(value) {
1345
+ return this.#sanitizer.bypassSecurityTrustHtml(value);
1346
+ }
1347
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1348
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, isStandalone: true, name: "sanitize" }); }
1349
+ }
1350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, decorators: [{
1351
+ type: Pipe,
1352
+ args: [{
1353
+ name: 'sanitize',
1354
+ pure: true,
1355
+ }]
1356
+ }] });
1357
+
1358
+ class EntityToStringPipe {
1359
+ transform(value) {
1360
+ if (isString(value)) {
1361
+ return value;
1362
+ }
1363
+ if (isNumber(value)) {
1364
+ return value.toString();
1365
+ }
1366
+ return DASH;
1367
+ }
1368
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1369
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, isStandalone: true, name: "entityToString" }); }
1370
+ }
1371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, decorators: [{
1372
+ type: Pipe,
1373
+ args: [{
1374
+ name: 'entityToString',
1375
+ pure: true,
1376
+ }]
1377
+ }] });
1378
+
1379
+ class EmptyToDashPipe {
1380
+ transform(value) {
1381
+ return emptyToDash(value);
1382
+ }
1383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1384
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, isStandalone: true, name: "emptyToDash" }); }
1385
+ }
1386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, decorators: [{
1387
+ type: Pipe,
1388
+ args: [{
1389
+ name: 'emptyToDash',
1390
+ pure: true,
1391
+ }]
1392
+ }] });
1393
+
1394
+ /**
1395
+ * @description Use to compare equality to any of items with provided value
1396
+ * @example
1397
+ *
1398
+ * Direct usage
1399
+ * ```ts
1400
+ * equalPipe.transform(100, 1, 10, 100) // => true
1401
+ * ```
1402
+ *
1403
+ * Template usage
1404
+ *
1405
+ * ```html
1406
+ * <div *ngIf="100 | equal:1:10:100">Visible</div>
1407
+ * ```
1408
+ */
1409
+ class EqualPipe {
1410
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1411
+ transform(value, ...compares) {
1412
+ return compares.reduce((equal, compare) => equal || value === compare, false);
1413
+ }
1414
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1415
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, isStandalone: true, name: "equal" }); }
1416
+ }
1417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, decorators: [{
1418
+ type: Pipe,
1419
+ args: [{
1420
+ name: 'equal',
1421
+ }]
1422
+ }] });
1423
+
1424
+ /**
1425
+ * @description Use to access to the deep object state for comparison
1426
+ * @example
1427
+ * {a: {b: true}} | equalChain:'a':'b':true => true
1428
+ */
1429
+ class EqualChainPipe {
1430
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1431
+ transform(obj, ...args) {
1432
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1433
+ const compared = args.pop();
1434
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1435
+ return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) === compared;
1436
+ }
1437
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1438
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, isStandalone: true, name: "equalChain" }); }
1439
+ }
1440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, decorators: [{
1441
+ type: Pipe,
1442
+ args: [{
1443
+ name: 'equalChain',
1444
+ }]
1445
+ }] });
1446
+
1447
+ /**
1448
+ * @description Use to compare not equality to all items with provided value
1449
+ * @example
1450
+ *
1451
+ * Direct usage
1452
+ * ```ts
1453
+ * notEqualPipe.transform(100, 1, 10, 100) // => false
1454
+ * ```
1455
+ *
1456
+ * Template usage
1457
+ *
1458
+ * ```html
1459
+ * <div *ngIf="100 | notEqual:1:10:100">Invisible</div>
1460
+ * ```
1461
+ */
1462
+ class NotEqualPipe {
1463
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1464
+ transform(value, ...compares) {
1465
+ return compares.reduce((notEqual, compare) => notEqual && value !== compare, true);
1466
+ }
1467
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1468
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, isStandalone: true, name: "notEqual" }); }
1469
+ }
1470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, decorators: [{
1471
+ type: Pipe,
1472
+ args: [{
1473
+ name: 'notEqual',
1474
+ }]
1475
+ }] });
1476
+
1477
+ /**
1478
+ * @description Use to access to the deep object state for comparison
1479
+ * @example
1480
+ * {a: {b: true}} | equalChain:'a':'b':false => true
1481
+ */
1482
+ class NotEqualChainPipe {
1483
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1484
+ transform(obj, ...args) {
1485
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1486
+ const compared = args.pop();
1487
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1488
+ return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) !== compared;
1489
+ }
1490
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1491
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, isStandalone: true, name: "notEqualChain" }); }
1492
+ }
1493
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, decorators: [{
1494
+ type: Pipe,
1495
+ args: [{
1496
+ name: 'notEqualChain',
1497
+ }]
1498
+ }] });
1499
+
1500
+ class TernaryPipe {
1501
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1502
+ transform(value, option1, option2) {
1503
+ return Boolean(value) ? option1 : option2;
1504
+ }
1505
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1506
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, isStandalone: true, name: "ternary" }); }
1507
+ }
1508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, decorators: [{
1509
+ type: Pipe,
1510
+ args: [{
1511
+ name: 'ternary',
1512
+ }]
1513
+ }] });
1514
+
1515
+ function checkIsMatchingValues(sample) {
1516
+ return (control) => {
1517
+ return sample && control.value && control.value.localeCompare(sample) === 0 ? null : { notEquivalent: true };
1518
+ };
1519
+ }
1520
+
1521
+ function arraysNotEmptyValidator(control) {
1522
+ if (control.value instanceof Object) {
1523
+ const arrays = Object.values(control.value);
1524
+ const allArraysEmpty = arrays.every((array) => !array.length);
1525
+ return allArraysEmpty ? { allArraysEmpty: true } : null;
1526
+ }
1527
+ else if (Array.isArray(control.value)) {
1528
+ const array = control.value;
1529
+ return !array.length ? { arrayEmpty: true } : null;
1530
+ }
1531
+ else {
1532
+ return { invalidType: true };
1533
+ }
1534
+ }
1535
+
1536
+ /**
1537
+ * Returns a set of dependency injection providers for utility services.
1538
+ *
1539
+ * @usageNotes
1540
+ *
1541
+ * This function provides utility services that are commonly used across
1542
+ * an Angular application. Specifically, it provides the `BreakpointService`
1543
+ * for managing responsive design breakpoints and the `PlatformService` for
1544
+ * detecting the platform on which the application is running (e.g., browser or server).
1545
+ *
1546
+ * ```typescript
1547
+ * bootstrapApplication(RootComponent, {
1548
+ * providers: [
1549
+ * provideRtUtils()
1550
+ * ]
1551
+ * });
1552
+ * ```
1553
+ *
1554
+ * @publicApi
1555
+ */
1556
+ function provideRtUtils() {
1557
+ return [BreakpointService, PlatformService];
1558
+ }
1559
+
1560
+ // constants
1561
+
1562
+ /**
1563
+ * Generated bundle index. Do not edit.
1564
+ */
1565
+
1566
+ export { ASIDE_BUTTONS_ENUM, ASIDE_REF, AsideRef, BaseMapper, BreakStringPipe, BreakpointService, Breakpoints, DASH, DeviceDetectorService, EmptyToDashPipe, EntityToStringPipe, EqualChainPipe, EqualPipe, HAS_OWN_SCOPE_ENUM, MODAL_WINDOW_SIZE_ENUM, NAVIGATOR, NotEqualChainPipe, NotEqualPipe, OSTypes, OVERLAY_POSITIONS, POSITION_ENUM, RtEscapeKeyDirective, RtHideTooltipDirective, RtIconOutlinedDirective, RtNavigationDirective, RtScrollDirective, RtScrollToElementDirective, RtTabQueryParamDirective, SanitizePipe, TernaryPipe, TypeCastHelper, areArraysEqual, areArraysEqualUnordered, areObjectsEqual, arraysNotEmptyValidator, checkIsEntityInArrayByKey, checkIsMatchingValues, dateStringToDate, ddServices, debounce, emptyToDash, formatDate, hasPropertyInChain, initToday, isDate, isDateValid, isEmail, isEmpty, isEmptyArray, isEmptyObject, isEmptyString, isEqual, isNumber, isRecord, isString, isToday, parseDate, parseISO, provideRtUtils, removeFieldFromObject, safeComparatorPipe, safeCompare, safeNumCompare, safeStrCompare, sortByAlphabet, sortByDate, stringifyHttpLikeParams, transformArrayInput, transformStringInput };
1567
+ //# sourceMappingURL=rt-tools-utils.mjs.map