UNPKG

coersystem

Version:

Library for Angular projects

1 lines 195 kB
{"version":3,"file":"coersystem-tools.mjs","sources":["../../../projects/mycore/tools/lib/numbers.tools.ts","../../../projects/mycore/tools/lib/tools.ts","../../../projects/mycore/tools/lib/colors.tools.ts","../../../projects/mycore/tools/lib/coer-alert/coer-alert.component.ts","../../../projects/mycore/tools/lib/coer-alert/coer-alert.component.html","../../../projects/mycore/tools/lib/breadcrumbs.tools.ts","../../../projects/mycore/tools/lib/coer-grid.templates.ts","../../../projects/mycore/tools/lib/collections.tools.ts","../../../projects/mycore/tools/lib/control-value.tools.ts","../../../projects/mycore/tools/lib/strings.tools.ts","../../../projects/mycore/tools/lib/dates.ts","../../../projects/mycore/tools/lib/html-elements.tools.ts","../../../projects/mycore/tools/lib/files.tools.ts","../../../projects/mycore/tools/lib/user.class.ts","../../../projects/mycore/tools/lib/filters.tools.ts","../../../projects/mycore/tools/lib/menu.tools.ts","../../../projects/mycore/tools/lib/source.tools.ts","../../../projects/mycore/tools/lib/page.tools.ts","../../../projects/mycore/tools/lib/screen.tools.ts","../../../projects/mycore/tools/lib/section.tools.ts","../../../projects/mycore/tools/lib/service.tools.ts","../../../projects/mycore/tools/coersystem-tools.ts"],"sourcesContent":["import { Strings } from \"./strings.tools\";\r\n\r\n/** Provides several methods for string manipulation */\r\nexport class Numbers { \r\n\r\n\r\n /** Validates if the value is a numeric type */\r\n public static IsNumber(value: any): boolean {\r\n return typeof value === 'number' && !Number.isNaN(Number(value));\r\n }\r\n\r\n\r\n /** Validates if the value isn't a numeric type */\r\n public static IsNotNumber(value: any): boolean {\r\n return !this.IsNumber(value);\r\n }\r\n\r\n\r\n /** */\r\n public static SetDecimals(value: string | number | null | undefined, decimals: number = 2): string {\r\n if(typeof value === 'string') value = Number(value);\r\n if (this.IsNotNumber(value)) return '0';\r\n\r\n let valueInteger = '';\r\n let valueDecimal = '';\r\n value = String(value); \r\n\r\n if (value.includes('.') || (decimals > 0)) {\r\n valueInteger = value.includes('.') ? value.split('.')[0] : value;\r\n\r\n if (decimals > 0) { \r\n valueDecimal = value.includes('.') ? value.split('.')[1] : '';\r\n for(let i = 0; i < decimals; i++) valueDecimal += '0';\r\n valueDecimal = valueDecimal.substring(0, decimals);\r\n valueDecimal = `.${valueDecimal}`;\r\n }\r\n }\r\n\r\n else {\r\n valueInteger = value;\r\n }\r\n \r\n return `${valueInteger}${valueDecimal}`;\r\n }\r\n\r\n\r\n /** Return a string with numeric format */\r\n public static GetNumericFormat(value: string | number | null | undefined, decimals: number = 0): string {\r\n const [INTEGER, DECIMAL = ''] = this.SetDecimals(value).split('.');\r\n\r\n return decimals > 0\r\n ? `${INTEGER.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')}.${DECIMAL}`\r\n : INTEGER.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\r\n }\r\n \r\n \r\n /** Return a string with currency format */\r\n public static GetCurrencyFormat(value: string | number | null | undefined, symbol: string = '$', currency: string = ''): string { \r\n return `${symbol}${this.GetNumericFormat(value, 2)}${currency.length > 0 ? ` ${currency}` : ''}`;\r\n }\r\n}","import { signal } from \"@angular/core\"; \r\nimport { CoerAlert } from \"./coer-alert/coer-alert.component\";\r\nimport { Numbers } from \"./numbers.tools\";\r\nconst reference_signal = signal<any>({});\r\n\r\n/** Generic Methods */\r\nexport const Tools = {\r\n\r\n\r\n /** Generates a guid */\r\n GetGuid: (seed: string = 'coer-system'): string => {\r\n let time = new Date().getTime();\r\n seed = seed.toString().trim()\r\n return seed + `-xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, (c) => {\r\n const random = (time + Math.random() * 16) % 16 | 0\r\n time = Math.floor(time / 16)\r\n return (c == 'x' ? random : (random & 0x3 | 0x8)).toString(16)\r\n })\r\n },\r\n\r\n\r\n /** Returns true if the value is null or undefined, false otherwise */\r\n IsNull: (value: any): boolean => {\r\n return (value === undefined || value === null);\r\n },\r\n\r\n\r\n /** Returns true if the value is not null or undefined, false otherwise */\r\n IsNotNull: (value: any): boolean => {\r\n return !Tools.IsNull(value); \r\n },\r\n\r\n\r\n /** Returns true if the value is null or undefined or is an empty string or contains only whitespace, false otherwise */\r\n IsOnlyWhiteSpace: (value: any): boolean => {\r\n return Tools.IsNull(value) || (typeof value === 'string' && value.trim() === '');\r\n },\r\n\r\n\r\n /** Returns true if it has a string value and is not all whitespace, false otherwise */\r\n IsNotOnlyWhiteSpace: (value: any): boolean => {\r\n return Tools.IsNotNull(value) && !Tools.IsOnlyWhiteSpace(value); \r\n },\r\n \r\n \r\n /** Avoids null value and responds with the specified type */\r\n AvoidNull: <T>(value: T | null | undefined, type: 'string' | 'number' | 'boolean' = 'string'): T => {\r\n\r\n if (Tools.IsNull(value)) {\r\n return (type === 'string' ? '' : type === 'number' ? 0 : false) as T;\r\n }\r\n\r\n else if (typeof value === 'string') {\r\n if (type === 'string' ) return value as T;\r\n if (type === 'number' ) return (Numbers.IsNumber(Number(value)) ? Number(value) : 0) as T;\r\n if (type === 'boolean') return (\r\n Numbers.IsNumber(Number(value)) \r\n ? Number(value) > 0 \r\n : (value.toLowerCase().trim() === 'true')\r\n ) as T;\r\n } \r\n \r\n else if (typeof value === 'number') {\r\n if (type === 'string' ) return String(value) as T;\r\n if (type === 'number' ) return value as T; \r\n if (type === 'boolean') return (value > 0) as T;\r\n }\r\n\r\n else if (typeof value === \"boolean\") { \r\n if (type === 'string' ) return (value ? 'true' : 'false') as T;\r\n if (type === 'number' ) return (value ? 1 : 0) as T; \r\n if (type === 'boolean') return value as T;\r\n }\r\n\r\n return (type === 'string' ? '' : type === 'number' ? 0 : false) as T;\r\n }, \r\n\r\n\r\n /** Break reference of a object or array */\r\n BreakReference: <T>(object: T): T => { \r\n if (Tools.IsNull(object) || ['string', 'number', 'boolean'].includes(typeof object)) return object; \r\n return JSON.parse(JSON.stringify(object)) as T;\r\n }, \r\n \r\n\r\n /** Get properties of an object */\r\n GetPropertyList: <T>(object: T | object | null | undefined): string[] => {\r\n return Tools.IsNotNull(object) && typeof object === 'object' \r\n ? Object.keys(object!) \r\n : [];\r\n }, \r\n\r\n\r\n /** */\r\n HasProperty: (object: any, property: string): boolean => {\r\n return typeof object === 'object' && object.hasOwnProperty(property)\r\n }, \r\n\r\n\r\n /** */\r\n IsBoolean: (object: any, property: string = ''): boolean => {\r\n return Tools.IsOnlyWhiteSpace(property)\r\n ? typeof object === 'boolean'\r\n : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean'); \r\n }, \r\n\r\n\r\n /** */\r\n IsBooleanTrue: (object: any, property: string = ''): boolean => {\r\n return Tools.IsOnlyWhiteSpace(property)\r\n ? typeof object === 'boolean' && object === true\r\n : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean') && object[property] === true; \r\n },\r\n\r\n\r\n /** */\r\n IsBooleanFalse: (object: any, property: string = ''): boolean => {\r\n return Tools.IsOnlyWhiteSpace(property)\r\n ? typeof object === 'boolean' && object === false\r\n : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean') && object[property] === false; \r\n },\r\n\r\n\r\n /** */\r\n IsString: (object: any, property: string = ''): boolean => {\r\n return Tools.IsOnlyWhiteSpace(property)\r\n ? typeof object === 'string'\r\n : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'string'); \r\n },\r\n\r\n\r\n /** */\r\n IsFunction: (object: any, property: string = ''): boolean => {\r\n return Tools.IsOnlyWhiteSpace(property)\r\n ? typeof object === 'function'\r\n : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'function'); \r\n },\r\n \r\n \r\n /** Wait the time indicated */\r\n Sleep: (milliseconds: number = 0, reference: string | null = null): Promise<void> => {\r\n if (Tools.IsNull(reference)) {\r\n return new Promise(Resolve => setTimeout(Resolve, milliseconds));\r\n }\r\n\r\n else return new Promise<void>(Resolve => {\r\n reference = reference!.replaceAll(' ', '_').toLowerCase();\r\n\r\n if (reference_signal().hasOwnProperty(reference)) {\r\n clearInterval(reference_signal()[reference!]);\r\n }\r\n\r\n reference_signal.set(Object.assign(reference_signal(), {\r\n [reference!]: setTimeout(() => {\r\n Resolve();\r\n clearInterval(reference_signal()[reference!]);\r\n const _reference = { ...reference_signal() };\r\n delete _reference[reference!];\r\n reference_signal.set({ ..._reference });\r\n }, milliseconds)\r\n }));\r\n });\r\n },\r\n\r\n\r\n /** Send text to the computer's clipboard */\r\n Clipboard: (text: string, message: string = '', title: string = 'Copied'): void => {\r\n try {\r\n navigator.clipboard.writeText(text.trim()).then(() => {\r\n new CoerAlert().Info(message, title, 'bi bi-clipboard-fill');\r\n }); \r\n } \r\n \r\n catch { \r\n new CoerAlert().Warning('Unable to copy to clipboard', 'Quick Implement', 'bi bi-clipboard-fill');\r\n } \r\n }\r\n}; ","import { colorsSIGNAL } from \"coersystem/signals\";\r\nimport { IActionColors, IAppColors, IFixedColors } from \"coersystem/interfaces\";\r\nimport { Tools } from \"./tools\";\r\n\r\n/** class to work with colors */\r\nexport class Colors {\r\n\r\n /** Provides the fixed colors set by the coersystem library */\r\n public static get fixedColors(): IFixedColors {\r\n return {\r\n blue : colorsSIGNAL().fixedColors.blue,\r\n gray : colorsSIGNAL().fixedColors.gray,\r\n green : colorsSIGNAL().fixedColors.green,\r\n yellow : colorsSIGNAL().fixedColors.yellow,\r\n red : colorsSIGNAL().fixedColors.red,\r\n smoke : colorsSIGNAL().fixedColors.smoke,\r\n black : colorsSIGNAL().fixedColors.black,\r\n orange : colorsSIGNAL().fixedColors.orange,\r\n white : colorsSIGNAL().fixedColors.white,\r\n purple : colorsSIGNAL().fixedColors.purple\r\n }\r\n }\r\n\r\n\r\n /** Provides the action colors set in the application */\r\n public static get actionColors(): IActionColors {\r\n return {\r\n primary : colorsSIGNAL().actionColors.primary, \r\n secondary : colorsSIGNAL().actionColors.secondary, \r\n success : colorsSIGNAL().actionColors.success,\r\n warning : colorsSIGNAL().actionColors.warning, \r\n danger : colorsSIGNAL().actionColors.danger, \r\n navigation : colorsSIGNAL().actionColors.navigation, \r\n information : colorsSIGNAL().actionColors.information\r\n }\r\n }\r\n \r\n \r\n /** Provides the colors of the application */\r\n public static get appColors(): IAppColors {\r\n return {\r\n breadcrumbs : colorsSIGNAL().appColors.breadcrumbs,\r\n background : colorsSIGNAL().appColors.background, \r\n containers : colorsSIGNAL().appColors.containers,\r\n sidenav : colorsSIGNAL().appColors.sidenav, \r\n sidenavText : colorsSIGNAL().appColors.sidenavText, \r\n sidenavActive: colorsSIGNAL().appColors.sidenavActive,\r\n toolbar : colorsSIGNAL().appColors.toolbar, \r\n toolbarText : colorsSIGNAL().appColors.toolbarText\r\n } \r\n }\r\n \r\n \r\n /** Get Hexadecimal color */\r\n public static ToHexadecimal(red: number, green: number, blue: number, alpha?: number): string {\r\n const _red = `${Number(red).toString(16).padStart(2, '0')}`;\r\n const _green = `${Number(green).toString(16).padStart(2, '0')}`;\r\n const _blue = `${Number(blue).toString(16).padStart(2, '0')}`;\r\n const _alpha = (Tools.IsNotNull(alpha)) ? Math.round(Number(alpha) * 255).toString(16).padStart(2, '0') : '';\r\n return `#${_red}${_green}${_blue}${_alpha}`.toLowerCase();\r\n }\r\n\r\n\r\n /** Returns a random color in hexadecimal \r\n public static GetRandomColorHex = (): string => \"#xxxxxx\".replace(/x/g, () => (Math.random() * 16 | 0).toString(16)); */\r\n\r\n\r\n /** Returns the number of colors requested */\r\n public static GetColorList(quantity: number): string[] {\r\n const colors: string[] = [];\r\n let counter: number = 0;\r\n\r\n while (counter < quantity) {\r\n for (const color in this.fixedColors) {\r\n colors.push(color);\r\n if (++counter === quantity) break;\r\n }\r\n }\r\n\r\n return colors;\r\n }\r\n\r\n\r\n /** Returns the number of colors requested with opacity \r\n public static GetColorRGBList(quantity: number): string[] {\r\n const colors: string[] = [];\r\n\r\n let alpha: number = 1.0;\r\n let counter: number = 0;\r\n let lastColor = [...Array.from(this.ColorsRGB.keys())].pop();\r\n\r\n while (counter < quantity) {\r\n for (const [color, value] of this.ColorsRGB.entries()) {\r\n colors.push(`rgba(${value[0]}, ${value[1]}, ${value[2]}, ${alpha})`);\r\n\r\n if (color === lastColor) alpha -= 0.2;\r\n if (++counter === quantity) break;\r\n }\r\n }\r\n\r\n return colors;\r\n } */\r\n}","import { Component } from '@angular/core';\r\nimport { Tools } from '../tools';\r\nimport { Colors } from '../colors.tools';\r\nimport * as bootstrap from 'bootstrap';\r\nimport Swal from 'sweetalert2';\r\n\r\n@Component({\r\n selector: 'coer-alert',\r\n templateUrl: './coer-alert.component.html',\r\n styleUrls: ['./coer-alert.component.scss'],\r\n standalone: true\r\n})\r\nexport class CoerAlert {\r\n\r\n /** Use this alert to issue a success message */\r\n public Success(message: string | null = null, title: string | null = null, icon: string | null = null, autohide: number | null = 3000): void {\r\n //Title\r\n if (Tools.IsOnlyWhiteSpace(title)) title = 'Success';\r\n const alertSuccessTitle = document.getElementById('alert-success-title')!;\r\n alertSuccessTitle.textContent = title;\r\n\r\n //Icon\r\n icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-check-circle fa-beat' : icon;\r\n const alertSuccessIcon = document.getElementById('alert-success-icon')!;\r\n this._SetIcon(alertSuccessIcon, icon!);\r\n\r\n //Message\r\n if (Tools.IsNull(message)) message = '';\r\n const alertSuccessMessage = document.getElementById('alert-success-message')!;\r\n alertSuccessMessage.innerHTML = message!;\r\n\r\n //Toast\r\n const alertSuccess = document.getElementById('alert-success')!;\r\n this._SetAutoHide(alertSuccess, autohide);\r\n\r\n const toast = bootstrap.Toast.getOrCreateInstance(alertSuccess);\r\n toast.show();\r\n }\r\n\r\n\r\n /** Use this alert to issue a error or danger */\r\n public Error(message: string | null = null, title: string | null = null, icon: string | null = null, autohide: number | null = 3000): void {\r\n //Title\r\n if (Tools.IsOnlyWhiteSpace(title)) title = 'Error';\r\n const alertErrorTitle = document.getElementById('alert-error-title')!;\r\n alertErrorTitle.textContent = title;\r\n\r\n //Icon \r\n icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-octagon fa-beat' : icon;\r\n const alertErrorIcon = document.getElementById('alert-error-icon')!;\r\n this._SetIcon(alertErrorIcon, icon!);\r\n\r\n //Message\r\n if (Tools.IsNull(message)) message = '';\r\n const alertErrorBody = document.getElementById('alert-error-message')!;\r\n alertErrorBody.innerHTML = message!;\r\n\r\n //Toast\r\n const alertError = document.getElementById('alert-error')!;\r\n this._SetAutoHide(alertError, autohide);\r\n\r\n const toast = bootstrap.Toast.getOrCreateInstance(alertError);\r\n toast.show();\r\n }\r\n\r\n\r\n /** Use this alert to broadcast an informational message */\r\n public Info(message: string | null = null, title: string | null = null, icon: string | null = null, autohide: number | null = 3000): void {\r\n //Title\r\n if (Tools.IsOnlyWhiteSpace(title)) title = 'Info';\r\n const alertInfoTitle = document.getElementById('alert-info-title')!;\r\n alertInfoTitle.textContent = title;\r\n\r\n //Icon \r\n icon = Tools.IsOnlyWhiteSpace(icon) ? 'circle-info fa-beat' : icon;\r\n const alertInfoIcon = document.getElementById('alert-info-icon')!;\r\n this._SetIcon(alertInfoIcon, icon!);\r\n\r\n //Message\r\n if (Tools.IsNull(message)) message = '';\r\n const alertInfoBody = document.getElementById('alert-info-message')!;\r\n alertInfoBody.innerHTML = message!;\r\n\r\n //Toast\r\n const alertInfo = document.getElementById('alert-info')!;\r\n this._SetAutoHide(alertInfo, autohide);\r\n\r\n const toast = bootstrap.Toast.getOrCreateInstance(alertInfo);\r\n toast.show();\r\n }\r\n\r\n\r\n /** Use this alert to issue a warning message */\r\n public Warning(message: string | null = null, title: string | null = null, icon: string | null = null, autohide: number | null = 3000): void {\r\n //Title\r\n if (Tools.IsOnlyWhiteSpace(title)) title = 'Warning';\r\n const alertWarningTitle = document.getElementById('alert-warning-title')!;\r\n alertWarningTitle.textContent = title;\r\n\r\n //Icon \r\n icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-triangle-fill fa-beat' : icon;\r\n const alertWarningIcon = document.getElementById('alert-warning-icon')!;\r\n this._SetIcon(alertWarningIcon, icon!);\r\n\r\n //Message\r\n if (Tools.IsNull(message)) message = '';\r\n const alertWarningBody = document.getElementById('alert-warning-message')!;\r\n alertWarningBody.innerHTML = message!;\r\n\r\n //Toast\r\n const alertWarning = document.getElementById('alert-warning')!;\r\n this._SetAutoHide(alertWarning, autohide);\r\n\r\n const toast = bootstrap.Toast.getOrCreateInstance(alertWarning);\r\n toast.show();\r\n } \r\n\r\n\r\n /** Use this alert to confirm a user action */\r\n public Confirm(\r\n message: string = 'Proceed?',\r\n alertType: 'warning' | 'danger' | 'success' | 'info' = 'warning',\r\n icon: string | null = null) {\r\n return new Promise<boolean>(Resolve => {\r\n let color: string;\r\n let iconType: 'warning' | 'error' | 'success' | 'info';\r\n switch(alertType) {\r\n case 'danger': { \r\n if (Tools.IsNull(icon)) icon = 'bi-exclamation-octagon';\r\n iconType = 'error';\r\n color = Colors.actionColors.danger;\r\n break;\r\n };\r\n\r\n case 'success': {\r\n if (Tools.IsNull(icon)) icon = 'bi-check-circle';\r\n iconType = 'info';\r\n color = Colors.actionColors.success;\r\n break;\r\n };\r\n\r\n case 'info': {\r\n if (Tools.IsNull(icon)) icon = 'icon-circle-info';\r\n iconType = 'error';\r\n color = Colors.actionColors.information;\r\n break\r\n };\r\n\r\n default: {\r\n if (Tools.IsNull(icon)) icon = 'bi-exclamation-triangle-fill';\r\n iconType = 'warning';\r\n color = Colors.actionColors.warning; \r\n break;\r\n }\r\n }\r\n\r\n switch(icon) {\r\n case 'delete': icon = 'fa-regular fa-trash-can'; break;\r\n }\r\n\r\n Swal.fire({\r\n icon: iconType,\r\n iconColor: 'transparent',\r\n iconHtml: `<i class=\"${icon}\" style=\"color: ${color};\"></i>`,\r\n html: message,\r\n showConfirmButton: true,\r\n confirmButtonText: 'Yes',\r\n confirmButtonColor: color,\r\n focusConfirm: true,\r\n showDenyButton: true,\r\n denyButtonColor: color,\r\n focusDeny: false,\r\n reverseButtons: true,\r\n allowOutsideClick: false,\r\n allowEscapeKey: false,\r\n allowEnterKey: true,\r\n customClass: {\r\n denyButton: 'sweet-alert-button',\r\n confirmButton: 'sweet-alert-button'\r\n }\r\n }).then(({ value }) => setTimeout(() => Resolve(value)));\r\n });\r\n }\r\n\r\n\r\n /** */\r\n protected _Close(alert: 'alert-success' | 'alert-error' | 'alert-info' | 'alert-warning') {\r\n return new Promise<void>(Resolve => {\r\n const element = document.getElementById(alert)!;\r\n const toast = bootstrap.Toast.getOrCreateInstance(element);\r\n toast.hide();\r\n\r\n setTimeout(() => { Resolve() }, 200);\r\n })\r\n }\r\n\r\n\r\n /** */\r\n private _SetIcon(element: HTMLElement, icon: string): void {\r\n if (icon.toUpperCase() != 'NONE') {\r\n for (const item of [...element.classList.value.split(' ')]) {\r\n if (item.length > 0) {\r\n element.classList.remove(item);\r\n element.classList.remove('q');\r\n }\r\n }\r\n \r\n icon = icon.trim();\r\n const hasWhiteSpaces: RegExp = / /;\r\n if (hasWhiteSpaces.test(icon)) {\r\n const classes = icon.split(' ');\r\n for (const icon of classes) element.classList.add(icon);\r\n }\r\n \r\n else element.classList.add(icon); \r\n }\r\n }\r\n\r\n\r\n /** */\r\n private _SetAutoHide(element: HTMLElement, autohide: number | null): void {\r\n element.removeAttribute('data-bs-autohide');\r\n element.removeAttribute('data-bs-delay');\r\n\r\n if (autohide && autohide > 0) {\r\n if (autohide < 1000) autohide = 1000;\r\n element.setAttribute('data-bs-autohide', 'true');\r\n element.setAttribute('data-bs-delay', String(autohide));\r\n }\r\n\r\n else element.setAttribute('data-bs-autohide', 'false');\r\n } \r\n}","<aside class=\"toast-container coer-alert\">\r\n <!-- Success -->\r\n <div id=\"alert-success\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-success-icon\"></i>\r\n <strong id=\"alert-success-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-success')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-success-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Error -->\r\n <div id=\"alert-error\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-error-icon\"></i>\r\n <strong id=\"alert-error-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-error')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-error-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Info -->\r\n <div id=\"alert-info\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-info-icon\"></i>\r\n <strong id=\"alert-info-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-info')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-info-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Warning -->\r\n <div id=\"alert-warning\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-warning-icon\"></i>\r\n <strong id=\"alert-warning-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-warning')\" class=\"btn-close\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-warning-message\"></pre>\r\n </div>\r\n </div>\r\n</aside>","import { IAppSource } from \"coersystem/interfaces\";\r\nimport { Tools } from './tools';\r\n\r\n/** Controls the breadcrumbs in sessionStorage */\r\nexport class Breadcrumbs {\r\n\r\n private static readonly storage = 'COER-System';\r\n\r\n /** Add a breadcrumb */\r\n public static Add(page: string, path: string): void {\r\n const breadcrumbs = this.Get();\r\n const paths = breadcrumbs.map(item => item.path);\r\n\r\n if (!paths.includes(path)) {\r\n breadcrumbs.push({ page, path });\r\n this.Save(breadcrumbs);\r\n }\r\n }\r\n\r\n\r\n /** Get the breadcrumbs */\r\n public static Get(): IAppSource[] {\r\n let storage = sessionStorage.getItem(this.storage) as any;\r\n\r\n if (storage) {\r\n storage = JSON.parse(storage);\r\n\r\n if (storage.hasOwnProperty('breadcrumbs')) {\r\n return Tools.BreakReference(storage.breadcrumbs);\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n\r\n /** Get the first breadcrumb */\r\n public static GetFirst(): IAppSource | null {\r\n const breadcrumbs = this.Get();\r\n return (breadcrumbs.length > 0) ? breadcrumbs.shift()! : null;\r\n }\r\n\r\n\r\n /** Get the last breadcrumb */\r\n public static GetLast(): IAppSource | null {\r\n const breadcrumbs = this.Get();\r\n return (breadcrumbs.length > 0) ? breadcrumbs.pop()! : null;\r\n }\r\n\r\n\r\n /** */\r\n private static Save(breadcrumbs: IAppSource[]): void {\r\n let storage = sessionStorage.getItem(this.storage) as any;\r\n if (storage) storage = JSON.parse(storage);\r\n storage = Object.assign({}, storage, { breadcrumbs });\r\n sessionStorage.setItem(this.storage, JSON.stringify(storage));\r\n }\r\n\r\n\r\n /** Removes one breadcrumb by route */\r\n public static RemoveByPath(path: string): void { \r\n let breadcrumbs = this.Get();\r\n const index = breadcrumbs.findIndex(x => x.path.toLowerCase().trim() === path.toLowerCase().trim());\r\n\r\n if (index >= 0) {\r\n breadcrumbs = Tools.BreakReference(breadcrumbs).splice(0, index + 1);\r\n this.Save(breadcrumbs);\r\n }\r\n }\r\n\r\n\r\n /** Update the last breadcrumb */\r\n public static UpdateLast(page: string, path: string): void {\r\n const breadcrumbs = this.Get();\r\n\r\n if (breadcrumbs.length > 0) {\r\n breadcrumbs[breadcrumbs.length - 1] = { page, path };\r\n this.Save(breadcrumbs);\r\n }\r\n }\r\n\r\n\r\n /** Remove the last breadcrumb */\r\n public static RemoveLast(): void {\r\n const breadcrumbs = this.Get();\r\n\r\n if (breadcrumbs.length > 0) {\r\n breadcrumbs.pop();\r\n this.Save(breadcrumbs);\r\n }\r\n }\r\n}","import { IGridCoerSwitch, IGridCoerTextBox, IGridItem } from \"coersystem/interfaces\";\r\n\r\nexport const GridTemplates = {\r\n\r\n /** Set Active/Disabled values, template for boolean property */\r\n isActiveTemplate: (item: IGridItem<any>): string => {\r\n if (item.value) {\r\n return `\r\n <span class='text-green font-weight-bold'>\r\n <i class=\"icon-circle-check icon-fill\"></i> Active\r\n </span>\r\n `;\r\n }\r\n\r\n else {\r\n return `\r\n <span class='text-gray font-weight-bold'>\r\n <i class=\"fa-solid fa-circle-minus\"></i> Disabled\r\n </span>\r\n `;\r\n }\r\n },\r\n\r\n\r\n /** Enable switch by row, template for boolean property */\r\n coerSwitchTemplate: (item: IGridItem<any>): IGridCoerSwitch => ({\r\n showInput: true,\r\n tooltip: `${item.value ? 'Active' : 'Disabled' }`\r\n }),\r\n\r\n\r\n /** Enable textbox by row, template for text property */\r\n coerTextboxTemplate: (item: IGridItem<any>): IGridCoerTextBox => ({\r\n showInput: true,\r\n isInvalid: item.value.length <= 0\r\n }),\r\n\r\n\r\n /** Template for icons */\r\n coerIconTemplate: (icon: string, color: string = 'black'): string => {\r\n return `<i class='${icon} display-block width-100 text-center' style='color: ${color};'></i>`;\r\n }\r\n}","import { Tools } from \"./tools\";\r\n\r\n/** Provides several methods for collection manipulation */\r\nexport class Collections {\r\n \r\n /** Set an index and concat more arrays of the same type */\r\n public static SetIndex<T>(array: T[], ...args: T[][]): T[] { \r\n for (const arg of args) {\r\n array = [...array].concat([...arg]);\r\n }\r\n\r\n return [...array].map((item, index) => Object.assign({}, item, { index }));\r\n } \r\n\r\n\r\n /** Sort an array in ascending order by property */\r\n public static SortBy<T>(array: T[], property: string, propertyType: 'string' | 'number' = 'string'): T[] {\r\n switch (propertyType) {\r\n case 'string': {\r\n return array.sort((x: any, y: any) => {\r\n if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim()) return -1;\r\n else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim()) return 1;\r\n else return 0;\r\n });\r\n }\r\n\r\n case 'number': {\r\n return array.sort((x: any, y: any) => Number(x[property] - Number(y[property])));\r\n }\r\n }\r\n }\r\n\r\n\r\n /** Sort an array in descending order by property */\r\n public static SortByDesc<T>(array: T[], property: string, propertyType: 'string' | 'number' = 'string'): T[] {\r\n switch (propertyType) {\r\n case 'string': {\r\n return array.sort((x: any, y: any) => {\r\n if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim()) return 1;\r\n else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim()) return -1;\r\n else return 0;\r\n });\r\n }\r\n\r\n case 'number': {\r\n return array.sort((x: any, y: any) => Number(Number(y[property])) - x[property]);\r\n }\r\n }\r\n }\r\n\r\n\r\n /** */\r\n public static Distinct<T>(array: T[]): T[] { \r\n return Tools.IsNotNull(array) \r\n ? Array.from(new Set(array))\r\n : []; \r\n } \r\n\r\n\r\n /** */\r\n public static Except<T>(array: T[], exceptions: T[]): T[] {\r\n if(Tools.IsNull(array)) return []; \r\n if(Tools.IsNull(exceptions) || exceptions.length <= 0) return [...array];\r\n exceptions = Collections.Distinct(exceptions);\r\n return [...array].filter(item => !exceptions.includes(item)); \r\n }\r\n}","import { ControlValueAccessor, NG_VALUE_ACCESSOR } from \"@angular/forms\";\r\nimport { forwardRef } from \"@angular/core\";\r\n\r\nexport const CONTROL_VALUE = <T>(component: T) => {\r\n return {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => component),\r\n multi: true\r\n }\r\n}\r\n\r\n/** Implements the ControlValueAccessor interface to build a components */\r\nexport abstract class ControlValue implements ControlValueAccessor {\r\n\r\n //Variables\r\n private _isTouched: boolean = false;\r\n private _IsTouched!: Function;\r\n protected _UpdateValue!: Function;\r\n\r\n /** Current value of the component */\r\n protected _value: any; \r\n\r\n\r\n /** Property to validate if the component has been touched */\r\n public get isTouched(): boolean {\r\n return this._isTouched;\r\n } \r\n\r\n\r\n /** Sets the value of the component when it is created */\r\n public writeValue(value: any): void { \r\n this.SetValue(value);\r\n }\r\n\r\n\r\n /** Sets the value of the component when it is updated */\r\n public registerOnChange(callback: Function): void { \r\n if(typeof callback === 'function') {\r\n this._UpdateValue = callback; \r\n } \r\n }\r\n\r\n\r\n /** Sets the component's touched status when it is updated */\r\n public registerOnTouched(callback: Function): void {\r\n this._IsTouched = callback;\r\n }\r\n\r\n\r\n /** Sets the value of the component */\r\n protected SetValue(value: any): void {\r\n if(typeof this._UpdateValue === 'function') {\r\n this._UpdateValue(value); \r\n }\r\n \r\n this._value = value;\r\n }\r\n\r\n\r\n /** Sets whether the component has been touched */\r\n public SetTouched(isTouched: boolean): void {\r\n if(typeof this._IsTouched === 'function') {\r\n this._IsTouched(isTouched);\r\n }\r\n\r\n this._isTouched = isTouched;\r\n } \r\n}","import { Tools } from \"./tools\";\r\n\r\n/** Provides several methods for string manipulation */\r\nexport class Strings { \r\n\r\n\r\n /** Sets the first character to lowercase */\r\n public static FirstCharToLower(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).charAt(0).toLowerCase() + String(value).slice(1)\r\n : ''; \r\n }\r\n\r\n\r\n /** Sets the first character to uppercase */\r\n public static FirstCharToUpper(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).charAt(0).toUpperCase() + String(value).slice(1)\r\n : '';\r\n }\r\n\r\n\r\n /** Clean extra whitespaces */\r\n public static CleanUpBlanks(value: string | number | null | undefined): string {\r\n return value && Tools.IsNotOnlyWhiteSpace(value) \r\n ? String(value).replace(/\\s+/g, ' ').trim()\r\n : ''; \r\n }\r\n\r\n\r\n /** Apply title formatting */\r\n public static ToTitle(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).split(' ').filter(x => x.length > 0).map(x => Strings.FirstCharToUpper(x.toLowerCase())).join(' ')\r\n : ''; \r\n }\r\n\r\n\r\n /** Remove whitespaces */\r\n public static RemoveWhiteSpaces(value: string | number | null | undefined): string {\r\n return Tools.IsNotOnlyWhiteSpace(value) \r\n ? String(value).replaceAll(' ', '')\r\n : ''; \r\n }\r\n\r\n\r\n /** Removes the last character */\r\n public static RemoveLastChar(value: string | number | null | undefined): string {\r\n return Tools.IsNotOnlyWhiteSpace(value)\r\n ? String(value).trimEnd().slice(0, -1)\r\n : '';\r\n } \r\n\r\n\r\n /** Removes accents */\r\n public static RemoveAccents(value: string | number | null | undefined, except: string[] = []): string { \r\n if(Tools.IsOnlyWhiteSpace(value)) return ''; \r\n\r\n if (except.length > 0) {\r\n let index = 0;\r\n const mapValue = new Map<number, string>();\r\n for(const char of String(value)) { \r\n mapValue.set(index++, char);\r\n }\r\n \r\n index = 0;\r\n const mapNormalize = new Map<number, string>();\r\n for(const char of String(value).normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')) {\r\n mapNormalize.set(index++, char);\r\n } \r\n \r\n for (const char of except) {\r\n for (const [index, value] of mapValue.entries()) {\r\n if (value === char) {\r\n mapNormalize.set(index, char);\r\n }\r\n }\r\n } \r\n\r\n return Array.from(mapNormalize.values()).join('');\r\n }\r\n\r\n else {\r\n return String(value).normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\r\n } \r\n }\r\n\r\n\r\n /** Removes special characters */\r\n public static RemoveSpecialCharacters(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).replace(/[^a-zA-Z0-9áéíóúÁÉÍÓÚüÜñÑ\\s]/g , '') : ''; \r\n }\r\n\r\n\r\n /** Only Alphanumeric */\r\n public static OnlyAlphanumeric(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).replace(/[^a-zA-Z0-9\\s]/g , '') : ''; \r\n }\r\n\r\n\r\n /** Only Alphanumeric */\r\n public static OnlyNumbers(value: string | number | null | undefined): string {\r\n return (Tools.IsNotOnlyWhiteSpace(value)) \r\n ? String(value).replace(/[^0-9\\s]/g , '') : ''; \r\n }\r\n\r\n\r\n /** Validates if both strings are equal */\r\n public static Equals(value: string | number | null | undefined, value2: string | number | null | undefined, sensitive: boolean = false): boolean {\r\n if(typeof value === null && typeof value2 === null) return true;\r\n if(typeof value === 'undefined' && typeof value2 === 'undefined') return true;\r\n\r\n if(typeof value === 'string' && typeof value2 === 'string') {\r\n if (!sensitive) {\r\n value = value.toUpperCase();\r\n value2 = value2.toUpperCase(); \r\n }\r\n\r\n return value.length === value2.length\r\n && value === value2;\r\n } \r\n \r\n return false;\r\n }\r\n}","import { Numbers } from \"./numbers.tools\";\r\nimport { Strings } from \"./strings.tools\";\r\nimport { Tools } from \"./tools\";\r\ndeclare const appSettings: any;\r\n\r\n/** Provides several methods for dates manipulation */\r\nexport class Dates {\r\n \r\n private static readonly MONTHS = new Map<number, string>([\r\n [1, 'Jan'], [2, 'Feb'], [3, 'Mar'], [4, 'Apr' ], [5, 'May' ], [6, 'Jun' ],\r\n [7, 'Jul'], [8, 'Aug'], [9, 'Sep'], [10, 'Oct'], [11, 'Nov'], [12, 'Dec'],\r\n ]);\r\n\r\n \r\n /** */\r\n public static GetOffset(): number {\r\n return -(new Date().getTimezoneOffset());\r\n }\r\n\r\n\r\n /** */\r\n public static GetLastDay(date: string | Date): number {\r\n const DATE = this._CleanDate(date); \r\n return new Date(DATE.getFullYear(), DATE.getMonth() + 1, 0).getDate();\r\n }\r\n\r\n\r\n /** */\r\n public static IsValidDate(date: string | Date): boolean { \r\n return !isNaN(new Date(date).getTime());\r\n }\r\n\r\n\r\n /** */\r\n public static GetCurrentDate(): Date { \r\n return new Date();\r\n }\r\n\r\n\r\n /** */\r\n private static _CleanDate(date: string | Date): Date { \r\n if(typeof date === 'string') { \r\n date = Strings.CleanUpBlanks(date.replace(/(?:at|AT|t|T)/g, ' '));\r\n return /\\b([01]?\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?\\b/.test(date) \r\n ? new Date(date) : new Date(`${date} 00:00:00`)\r\n }\r\n\r\n else return date; \r\n } \r\n\r\n\r\n /** */\r\n public static ToLocalZone(utcDate: string | Date): Date { \r\n return new Date(new Date(utcDate).getTime() + this.GetOffset() * 60000);\r\n }\r\n\r\n\r\n /** */\r\n public static ToUTC(date: string | Date): Date { \r\n return new Date(new Date(date).getTime() - this.GetOffset() * 60000); \r\n }\r\n\r\n\r\n /** YYYY-MM-DD HH:mm:ss */\r\n public static ToFormatDB(date: string | Date): string { \r\n const DATE = this._CleanDate(date);\r\n return `${DATE.getFullYear()}` + '-' \r\n + `${DATE.getMonth() + 1}`.padStart(2, '0') + '-' \r\n + `${DATE.getDate()}`.padStart(2, '0') + ' ' \r\n + `${DATE.getHours()}`.padStart(2, '0') + ':'\r\n + `${DATE.getMinutes()}`.padStart(2, '0') + ':'\r\n + `${DATE.getSeconds()}`.padStart(2, '0')\r\n } \r\n\r\n\r\n /** */\r\n public static ToFormatDate(date: string | Date, format?: 'MDY' | 'DMY' | 'YMD'): string { \r\n const DATE = this._CleanDate(date);\r\n\r\n switch(format || Tools.AvoidNull<string>(appSettings?.dateTime?.format, 'string')) {\r\n case 'DMY': { /** DD MMM YYYY - MX ES */\r\n return `${DATE.getDate()}`.padStart(2, '0') + ' ' \r\n + `${this.MONTHS.get(DATE.getMonth() + 1)}` + ' ' \r\n + `${DATE.getFullYear()}`;\r\n }\r\n \r\n case 'YMD': { /** YYYY MMM DD - International */\r\n return `${DATE.getFullYear()}` + ' ' \r\n + `${this.MONTHS.get(DATE.getMonth() + 1)}` + ' ' \r\n + `${DATE.getDate()}`.padStart(2, '0') + ' ' ;\r\n }\r\n \r\n default : { /** MMM DD, YYYY - US */\r\n return `${this.MONTHS.get(DATE.getMonth() + 1)}` + ' ' \r\n + `${DATE.getDate()}`.padStart(2, '0') + ', ' \r\n + `${DATE.getFullYear()}`;\r\n }\r\n }\r\n }\r\n\r\n\r\n /** */\r\n public static ToFormatTime(date: string | Date, ampm: boolean = false): string { \r\n const DATE = this._CleanDate(date);\r\n\r\n if(ampm) {\r\n let hours = DATE.getHours();\r\n const AM_PM = hours >= 12 ? 'pm' : 'am';\r\n hours = hours % 12;\r\n hours = hours === 0 ? 12 : hours; \r\n\r\n return `${hours}`.padStart(2, '0') + ':'\r\n + `${DATE.getMinutes()}`.padStart(2, '0') + ' '\r\n + `${AM_PM}`;\r\n } \r\n\r\n else {\r\n return `${DATE.getHours()}`.padStart(2, '0') + ':'\r\n + `${DATE.getMinutes()}`.padStart(2, '0');\r\n }\r\n }\r\n\r\n\r\n /** */\r\n public static ToFormatDateTime(date: string | Date, ampm: boolean = false, format?: 'MDY' | 'DMY' | 'YMD'): string { \r\n return this.ToFormatDate(date, format) + ' at ' + this.ToFormatTime(date, ampm);\r\n } \r\n \r\n\r\n /** */\r\n public static AddMilliseconds(date: string | Date, milliseconds: number): Date {\r\n return new Date(this._CleanDate(date).getTime() + milliseconds);\r\n }\r\n\r\n\r\n /** */\r\n public static AddSeconds(date: string | Date, seconds: number = 1): Date {\r\n return this.AddMilliseconds(date, seconds * 1000);\r\n }\r\n\r\n\r\n /** */\r\n public static AddMinutes(date: string | Date, minutes: number = 1): Date {\r\n return this.AddMilliseconds(date, minutes * 60 * 1000);\r\n }\r\n\r\n\r\n /** */\r\n public static AddHours(date: string | Date, hours: number = 1): Date {\r\n return this.AddMilliseconds(date, hours * 60 * 60 * 1000);\r\n }\r\n\r\n\r\n /** Add days */\r\n public static AddDays(date: string | Date, days: number = 1): Date {\r\n return this.AddMilliseconds(date, days * 24 * 60 * 60 * 1000);\r\n }\r\n\r\n\r\n /** Add weeks */\r\n public static AddWeeks(date: string | Date, weeks: number = 1): Date {\r\n return this.AddMilliseconds(date, weeks * 7 * 24 * 60 * 60 * 1000);\r\n }\r\n\r\n\r\n /** Add months */\r\n public static AddMonths(date: string | Date, months: number = 1): Date {\r\n const DATE = this._CleanDate(date); \r\n const DATE_UPDATED = new Date(DATE.getFullYear(), (DATE.getMonth() + months), 1); \r\n DATE_UPDATED.setDate(Math.min(DATE.getDate(), new Date(DATE_UPDATED.getFullYear(), (DATE_UPDATED.getMonth() + 1), 0).getDate())); \r\n DATE_UPDATED.setHours(DATE.getHours(), DATE.getMinutes(), DATE.getSeconds(), DATE.getMilliseconds());\r\n return DATE_UPDATED;\r\n }\r\n\r\n\r\n /** Add years */\r\n public static AddYears(date: string | Date, years: number = 1): Date {\r\n const DATE = this._CleanDate(date); \r\n const DATE_UPDATED = new Date((DATE.getFullYear() + years), DATE.getMonth(), 1); \r\n DATE_UPDATED.setDate(Math.min(DATE.getDate(), new Date(DATE_UPDATED.getFullYear(), DATE_UPDATED.getMonth() + 1, 0).getDate())); \r\n DATE_UPDATED.setHours(DATE.getHours(), DATE.getMinutes(), DATE.getSeconds(), DATE.getMilliseconds());\r\n return DATE_UPDATED;\r\n }\r\n\r\n\r\n /** */\r\n public static SetMillisecond(date: string | Date, millisecond: number = 0): Date {\r\n const DATE = this._CleanDate(date);\r\n\r\n if (millisecond < 0 || millisecond >= 1000) {\r\n millisecond = DATE.getMilliseconds();\r\n }\r\n\r\n DATE.setMilliseconds(millisecond);\r\n return DATE;\r\n }\r\n\r\n\r\n /** */\r\n public static SetSecond(date: string | Date, second: number = 0): Date {\r\n const DATE = this._CleanDate(date);\r\n\r\n if (second < 0 || second >= 60) {\r\n second = DATE.getSeconds(); \r\n }\r\n\r\n DATE.setSeconds(second);\r\n return DATE;\r\n }\r\n\r\n\r\n /** */\r\n public static SetMinute(date: string | Date, minute: number = 0): Date {\r\n const DATE = this._CleanDate(date);\r\n \r\n if (minute < 0 || minute >= 60) {\r\n minute = DATE.getMinutes(); \r\n } \r\n\r\n DATE.setMinutes(minute, DATE.getSeconds()); \r\n return DATE;\r\n } \r\n\r\n\r\n /** */\r\n public static SetHour(date: string | Date, hour: number = 0): Date { \r\n const DATE = this._CleanDate(date); \r\n\r\n if (hour < 0 || hour >= 24) {\r\n hour = DATE.getHours(); \r\n } \r\n\r\n DATE.setHours(hour, DATE.getMinutes(), DATE.getSeconds()); \r\n return DATE;\r\n } \r\n\r\n\r\n /** Set 00:00:00 */\r\n public static SetFirstHour(date: string | Date): Date { \r\n const DATE = this._CleanDate(date);\r\n DATE.setHours(0, 0, 0);\r\n return DATE;\r\n }\r\n\r\n\r\n /** Set 23:59:59 */\r\n public static SetLastHour(date: string | Date): Date { \r\n const DATE = this._CleanDate(date);\r\n DATE.setHours(23, 59, 59);\r\n return DATE;\r\n } \r\n\r\n\r\n /** */\r\n public static SetDay(date: string | Date, day: number = 1): Date {\r\n const DATE = this._CleanDate(date); \r\n\r\n if (day < 1 || day > this.GetLastDay(DATE)) {\r\n day = DATE.getDate();\r\n }\r\n\r\n DATE.setDate(day);\r\n return DATE;\r\n } \r\n\r\n\r\n /** */\r\n public static SetFirstDay(date: string | Date): Date { \r\n return this.SetDay(date, 1);\r\n }\r\n\r\n\r\n /** */\r\n public static SetLastDay(date: string | Date): Date { \r\n return this.SetDay(date, this.GetLastDay(date));\r\n }\r\n\r\n\r\n /** */\r\n public static GetDiffNow( \r\n date: string | Date, \r\n unit: 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' = 'minutes'\r\n ): number { \r\n return this.GetDiff(this.GetCurrentDate(), date, unit);\r\n