purity-world-ui 1.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/index.cjs +397 -0
  4. package/index.d.ts +1 -0
  5. package/index.js +1939 -0
  6. package/package.json +46 -0
  7. package/style.css +1 -0
  8. package/style.d.ts +1 -0
  9. package/styles/_base.scss +525 -0
  10. package/styles/_mixins.scss +57 -0
  11. package/styles/_theme-dark.scss +103 -0
  12. package/styles/_theme-light.scss +103 -0
  13. package/styles/_themes.scss +34 -0
  14. package/styles/_ui.scss +28 -0
  15. package/styles/_variables.scss +72 -0
  16. package/styles/index.scss +7 -0
  17. package/types/app/shared/behaviors/draggable/draggable.d.ts +14 -0
  18. package/types/app/shared/behaviors/draggable/draggable.d.ts.map +1 -0
  19. package/types/app/shared/behaviors/droppable/droppable.d.ts +23 -0
  20. package/types/app/shared/behaviors/droppable/droppable.d.ts.map +1 -0
  21. package/types/app/shared/components/date-time-picker/date-time-picker.component.d.ts +91 -0
  22. package/types/app/shared/components/date-time-picker/date-time-picker.component.d.ts.map +1 -0
  23. package/types/app/shared/components/expander/expander.component.d.ts +36 -0
  24. package/types/app/shared/components/expander/expander.component.d.ts.map +1 -0
  25. package/types/app/shared/components/loader/loader.component.d.ts +21 -0
  26. package/types/app/shared/components/loader/loader.component.d.ts.map +1 -0
  27. package/types/app/shared/components/modal/modal-view.component.d.ts +19 -0
  28. package/types/app/shared/components/modal/modal-view.component.d.ts.map +1 -0
  29. package/types/app/shared/components/navigation-menu/navigation-menu.component.d.ts +19 -0
  30. package/types/app/shared/components/navigation-menu/navigation-menu.component.d.ts.map +1 -0
  31. package/types/app/shared/components/notification/notification.component.d.ts +13 -0
  32. package/types/app/shared/components/notification/notification.component.d.ts.map +1 -0
  33. package/types/app/shared/components/popover/popover.component.d.ts +45 -0
  34. package/types/app/shared/components/popover/popover.component.d.ts.map +1 -0
  35. package/types/app/shared/components/radial-context-menu/radial-context-menu.component.d.ts +57 -0
  36. package/types/app/shared/components/radial-context-menu/radial-context-menu.component.d.ts.map +1 -0
  37. package/types/app/shared/components/switch-button/switch-button.component.d.ts +27 -0
  38. package/types/app/shared/components/switch-button/switch-button.component.d.ts.map +1 -0
  39. package/types/app/shared/directives/dropdown/dropdown.directive.d.ts +35 -0
  40. package/types/app/shared/directives/dropdown/dropdown.directive.d.ts.map +1 -0
  41. package/types/app/shared/directives/highlight/highlight.directive.d.ts +11 -0
  42. package/types/app/shared/directives/highlight/highlight.directive.d.ts.map +1 -0
  43. package/types/app/shared/interceptors/auth.interceptor.d.ts +11 -0
  44. package/types/app/shared/interceptors/auth.interceptor.d.ts.map +1 -0
  45. package/types/app/shared/interceptors/logging.interceptor.d.ts +9 -0
  46. package/types/app/shared/interceptors/logging.interceptor.d.ts.map +1 -0
  47. package/types/app/shared/pipes/date.pipe.d.ts +10 -0
  48. package/types/app/shared/pipes/date.pipe.d.ts.map +1 -0
  49. package/types/app/shared/pipes/transform-sample.pipe.d.ts +5 -0
  50. package/types/app/shared/pipes/transform-sample.pipe.d.ts.map +1 -0
  51. package/types/app/shared/pipes/uppercase.pipe.d.ts +5 -0
  52. package/types/app/shared/pipes/uppercase.pipe.d.ts.map +1 -0
  53. package/types/app/shared/validators/forms-validation.validator.d.ts +6 -0
  54. package/types/app/shared/validators/forms-validation.validator.d.ts.map +1 -0
  55. package/types/app/shared/widgets/analogue-clock/analogue-clock.component.d.ts +84 -0
  56. package/types/app/shared/widgets/analogue-clock/analogue-clock.component.d.ts.map +1 -0
  57. package/types/data/notify.service.d.ts +65 -0
  58. package/types/data/notify.service.d.ts.map +1 -0
  59. package/types/data/theme.service.d.ts +20 -0
  60. package/types/data/theme.service.d.ts.map +1 -0
  61. package/types/framework/bootstrap.d.ts +42 -0
  62. package/types/framework/bootstrap.d.ts.map +1 -0
  63. package/types/framework/component.d.ts +57 -0
  64. package/types/framework/component.d.ts.map +1 -0
  65. package/types/framework/core.d.ts +46 -0
  66. package/types/framework/core.d.ts.map +1 -0
  67. package/types/framework/di.d.ts +53 -0
  68. package/types/framework/di.d.ts.map +1 -0
  69. package/types/framework/directive.d.ts +47 -0
  70. package/types/framework/directive.d.ts.map +1 -0
  71. package/types/framework/http.d.ts +211 -0
  72. package/types/framework/http.d.ts.map +1 -0
  73. package/types/framework/pipe.d.ts +34 -0
  74. package/types/framework/pipe.d.ts.map +1 -0
  75. package/types/framework/router.d.ts +145 -0
  76. package/types/framework/router.d.ts.map +1 -0
  77. package/types/framework/seo.d.ts +134 -0
  78. package/types/framework/seo.d.ts.map +1 -0
  79. package/types/framework/validator.d.ts +73 -0
  80. package/types/framework/validator.d.ts.map +1 -0
  81. package/types/framework/virtual-for.d.ts +36 -0
  82. package/types/framework/virtual-for.d.ts.map +1 -0
  83. package/types/ui.d.ts +30 -0
  84. package/types/ui.d.ts.map +1 -0
package/index.js ADDED
@@ -0,0 +1,1939 @@
1
+ import { BaseDirective as e, BasePipe as t, BaseValidator as n, Component as r, Directive as i, Injectable as a, Pipe as o, Validator as s, ViewChild as c, effect as l, getElement as u, inject as d, signal as f, startLoadingCursor as p, stopLoadingCursor as m } from "purity-world/core";
2
+ //#region src/app/shared/directives/dropdown/dropdown.directive.ts
3
+ var h = class extends e {
4
+ isOpen = !1;
5
+ triggerEl = null;
6
+ labelEl = null;
7
+ bodyEl = null;
8
+ boundDocClick;
9
+ boundKeydown;
10
+ boundTriggerClick;
11
+ boundBodyClick;
12
+ boundResize;
13
+ boundScroll;
14
+ isCustomTrigger = !1;
15
+ openedAt = 0;
16
+ onInit() {
17
+ let e = this.element;
18
+ !e || e.hasAttribute("data-dropdown-ready") || (e.setAttribute("data-dropdown-ready", "true"), e.classList.add("p-dropdown"), this.setupDOM(), this.bindEvents());
19
+ }
20
+ onChanges(e) {
21
+ e != null && !this.isCustomTrigger && this.labelEl && (this.labelEl.textContent = String(e));
22
+ }
23
+ onDOMChange(e) {
24
+ if (this.element && e instanceof MutationRecord) {
25
+ if (e.attributeName === "label" || e.attributeName === "placeholder") {
26
+ let e = this.element.getAttribute("label") || this.element.getAttribute("placeholder");
27
+ e && this.labelEl && !this.isCustomTrigger && (this.labelEl.textContent = e);
28
+ } else if (e.attributeName === "disabled") {
29
+ let e = this.element.hasAttribute("disabled") && this.element.getAttribute("disabled") !== "false";
30
+ this.triggerEl && (e ? this.triggerEl.setAttribute("disabled", "") : this.triggerEl.removeAttribute("disabled"));
31
+ } else e.attributeName === "align" && this.isOpen && this.updatePosition();
32
+ }
33
+ }
34
+ open() {
35
+ this.isOpen || this.isDisabled() || this.bodyEl && (this.bodyEl.parentElement !== document.body && document.body.appendChild(this.bodyEl), this.openedAt = Date.now(), this.isOpen = !0, this.element.classList.add("dropdown-open", "p-dropdown--open"), this.triggerEl && this.triggerEl.setAttribute("aria-expanded", "true"), this.bodyEl.classList.add("is-open"), this.updatePosition());
36
+ }
37
+ close() {
38
+ this.isOpen && (this.isOpen = !1, this.element.classList.remove("dropdown-open", "p-dropdown--open"), this.triggerEl && this.triggerEl.setAttribute("aria-expanded", "false"), this.bodyEl && this.bodyEl.classList.remove("is-open"));
39
+ }
40
+ toggle() {
41
+ this.isOpen ? this.close() : this.open();
42
+ }
43
+ setLabel(e) {
44
+ this.labelEl && (this.labelEl.textContent = e);
45
+ }
46
+ updatePosition() {
47
+ if (!this.triggerEl || !this.bodyEl) return;
48
+ let e = this.triggerEl.getBoundingClientRect(), t = this.bodyEl.getBoundingClientRect(), n = window.innerHeight, r = window.innerWidth, i = t.height || 220, a = t.width || e.width || 180, o = n - e.bottom, s = e.top, c = this.element.getAttribute("placement"), l = !1;
49
+ c === "top" ? l = !0 : c === "bottom" ? l = !1 : o < 220 && s > o && (l = !0), this.bodyEl.classList.toggle("placement-top", l), this.bodyEl.classList.toggle("placement-bottom", !l);
50
+ let u = l ? e.top - i - 6 : e.bottom + 6, d = e.left;
51
+ (this.element.getAttribute("align") === "right" || d + a > r - 10) && (d = Math.max(10, e.right - a)), u < 10 && (u = 10), u + i > n - 10 && (u = Math.max(10, n - i - 10)), d < 10 && (d = 10);
52
+ let f = Math.max(e.width, 160);
53
+ this.bodyEl.style.minWidth = `${f}px`, this.bodyEl.style.top = `${Math.round(u)}px`, this.bodyEl.style.left = `${Math.round(d)}px`;
54
+ }
55
+ onDestroy() {
56
+ this.boundDocClick && document.removeEventListener("pointerdown", this.boundDocClick), this.boundKeydown && window.removeEventListener("keydown", this.boundKeydown), this.boundResize && window.removeEventListener("resize", this.boundResize), this.boundScroll && window.removeEventListener("scroll", this.boundScroll, !0), this.triggerEl && this.boundTriggerClick && this.triggerEl.removeEventListener("click", this.boundTriggerClick), this.bodyEl && this.boundBodyClick && this.bodyEl.removeEventListener("click", this.boundBodyClick), this.bodyEl && this.bodyEl.parentElement && (this.bodyEl.parentElement.removeChild(this.bodyEl), this.bodyEl = null);
57
+ }
58
+ setupDOM() {
59
+ let e = this.element, t = Array.from(e.childNodes), n = null;
60
+ for (let e of t) if (e instanceof HTMLElement && (e.getAttribute("slot") === "trigger" || e.classList.contains("dropdown-trigger"))) {
61
+ n = e;
62
+ break;
63
+ }
64
+ if (n) this.isCustomTrigger = !0, this.triggerEl = n;
65
+ else {
66
+ this.isCustomTrigger = !1;
67
+ let t = e.getAttribute("label") || e.getAttribute("placeholder") || "Select option", n = document.createElement("button");
68
+ n.type = "button", n.className = "dropdown-trigger", n.setAttribute("aria-haspopup", "true"), n.setAttribute("aria-expanded", "false"), this.isDisabled() && n.setAttribute("disabled", "");
69
+ let r = document.createElement("span");
70
+ r.className = "dropdown-label", r.textContent = t;
71
+ let i = document.createElement("span");
72
+ i.className = "dropdown-chevron", i.innerHTML = "<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>", n.appendChild(r), n.appendChild(i), this.triggerEl = n, this.labelEl = r;
73
+ }
74
+ let r = document.createElement("div");
75
+ r.className = "dropdown-body p-dropdown-body", r.setAttribute("role", "menu"), r.setAttribute("tabindex", "-1");
76
+ for (let e of t) e !== n && r.appendChild(e);
77
+ e.innerHTML = "", this.triggerEl && e.appendChild(this.triggerEl), document.body.appendChild(r), this.bodyEl = r;
78
+ }
79
+ bindEvents() {
80
+ let e = this.element;
81
+ this.boundTriggerClick = (e) => {
82
+ e.preventDefault(), e.stopPropagation(), this.toggle();
83
+ }, this.triggerEl?.addEventListener("click", this.boundTriggerClick), this.boundBodyClick = (t) => {
84
+ let n = t.target;
85
+ if (!n) return;
86
+ let r = n.closest("li, a, button, .dropdown-item");
87
+ if (!r || !this.bodyEl?.contains(r) || r.hasAttribute("disabled") || r.classList.contains("disabled") || r.getAttribute("aria-disabled") === "true") return;
88
+ let i = r.textContent?.trim() || "", a = r.getAttribute("data-value") ?? r.getAttribute("value") ?? i;
89
+ e.getAttribute("auto-label") !== "false" && !this.isCustomTrigger && this.labelEl && i && (this.labelEl.textContent = i), this.bodyEl.querySelectorAll("li, a, button, .dropdown-item").forEach((e) => {
90
+ e.classList.remove("is-selected", "active");
91
+ }), r.classList.add("is-selected");
92
+ let o = {
93
+ item: r,
94
+ value: a,
95
+ label: i
96
+ };
97
+ e.dispatchEvent(new CustomEvent("change", {
98
+ bubbles: !0,
99
+ composed: !0,
100
+ detail: o
101
+ })), e.dispatchEvent(new CustomEvent("select", {
102
+ bubbles: !0,
103
+ composed: !0,
104
+ detail: o
105
+ })), e.getAttribute("keep-open") === "true" || r.hasAttribute("data-keep-open") || this.close();
106
+ }, this.bodyEl?.addEventListener("click", this.boundBodyClick), this.boundDocClick = (t) => {
107
+ if (!this.isOpen || Date.now() - this.openedAt < 100) return;
108
+ let n = t.composedPath ? t.composedPath() : [], r = t.target;
109
+ e && (n.includes(e) || r && e.contains(r)) || this.bodyEl && (n.includes(this.bodyEl) || r && this.bodyEl.contains(r)) || this.close();
110
+ }, document.addEventListener("pointerdown", this.boundDocClick), this.boundResize = () => {
111
+ this.isOpen && this.updatePosition();
112
+ }, this.boundScroll = () => {
113
+ this.isOpen && this.updatePosition();
114
+ }, window.addEventListener("resize", this.boundResize), window.addEventListener("scroll", this.boundScroll, !0), this.boundKeydown = (e) => {
115
+ if (!this.isOpen) {
116
+ (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") && document.activeElement === this.triggerEl && (e.preventDefault(), this.open());
117
+ return;
118
+ }
119
+ e.key === "Escape" ? (e.preventDefault(), this.close(), this.triggerEl?.focus()) : (e.key === "ArrowDown" || e.key === "ArrowUp") && (e.preventDefault(), this.navigateItems(e.key === "ArrowDown" ? 1 : -1));
120
+ }, e.addEventListener("keydown", this.boundKeydown);
121
+ }
122
+ navigateItems(e) {
123
+ if (!this.bodyEl) return;
124
+ let t = Array.from(this.bodyEl.querySelectorAll("li, a, button, .dropdown-item:not(.disabled):not([disabled])"));
125
+ if (t.length === 0) return;
126
+ let n = t.findIndex((e) => e === document.activeElement || e.contains(document.activeElement)) + e;
127
+ n < 0 && (n = t.length - 1), n >= t.length && (n = 0), t[n]?.focus();
128
+ }
129
+ isDisabled() {
130
+ return this.element.hasAttribute("disabled") && this.element.getAttribute("disabled") !== "false";
131
+ }
132
+ };
133
+ i("dropdown")(h);
134
+ //#endregion
135
+ //#region src/app/shared/directives/highlight/highlight.directive.ts
136
+ var g = class extends e {
137
+ currentModifierClass = "";
138
+ onInit() {
139
+ this.element.classList.add("p-highlight"), this.applyHighlightClass(this.value || "blue");
140
+ }
141
+ onChanges(e) {
142
+ this.applyHighlightClass(e);
143
+ }
144
+ onDOMChange(e) {
145
+ if ("attributeName" in e || typeof MutationRecord < "u" && e instanceof MutationRecord) {
146
+ let t = e.attributeName;
147
+ if (t === "highlight" || t === "[highlight]") {
148
+ let e = this.element.getAttribute("highlight") || this.element.getAttribute("[highlight]");
149
+ e && e !== this.value && this.onChanges(e);
150
+ }
151
+ } else if (e instanceof Event && e.type === "input") {
152
+ let e = this.element;
153
+ e.value && e.value.length > 5 ? this.element.classList.add("p-highlight--valid") : this.element.classList.remove("p-highlight--valid");
154
+ }
155
+ }
156
+ onDestroy() {
157
+ this.element.classList.remove("p-highlight", "p-highlight--valid"), this.currentModifierClass && this.element.classList.remove(this.currentModifierClass);
158
+ }
159
+ applyHighlightClass(e) {
160
+ if (this.currentModifierClass &&= (this.element.classList.remove(this.currentModifierClass), ""), e) {
161
+ let t = e.replace(/^#|rgba?.*$/, "").trim().toLowerCase(), n = t.startsWith("p-highlight--") ? t : `p-highlight--${t || "blue"}`;
162
+ this.currentModifierClass = n, this.element.classList.add(n);
163
+ }
164
+ }
165
+ };
166
+ i("highlight")(g);
167
+ //#endregion
168
+ //#region src/app/shared/components/switch-button/switch-button.component.html?raw
169
+ var _ = "<div class=\"switch-container {{isOn() ? 'is-on' : 'is-off'}} {{disabled() ? 'is-disabled' : ''}}\">\n <div class=\"switch-track\" aria-hidden=\"true\">\n <div class=\"switch-thumb\"></div>\n </div>\n <span class=\"switch-label\">\n <slot></slot>\n </span>\n</div>\n", v = class {
170
+ isOn = f(!1);
171
+ checked = this.isOn;
172
+ disabled = f(!1);
173
+ handleClick = (e) => {
174
+ this.disabled() || e.target?.closest("a, button, input, textarea, select") || this.toggle();
175
+ };
176
+ handleKeydown = (e) => {
177
+ this.disabled() || (e.key === " " || e.key === "Enter") && (e.preventDefault(), this.toggle());
178
+ };
179
+ onInit() {
180
+ let e = this;
181
+ if (e && typeof e.getAttribute == "function") {
182
+ let t = e.getAttribute("checked"), n = e.getAttribute("is-on");
183
+ (t !== null && t !== "false" && t !== "null" && t !== "0" || n !== null && n !== "false" && n !== "null" && n !== "0") && this.isOn.set(!0);
184
+ let r = e.getAttribute("disabled");
185
+ r !== null && r !== "false" && r !== "null" && r !== "0" && this.disabled.set(!0), e.hasAttribute("role") || e.setAttribute("role", "switch"), e.hasAttribute("tabindex") || e.setAttribute("tabindex", this.disabled() ? "-1" : "0"), e.addEventListener("click", this.handleClick), e.addEventListener("keydown", this.handleKeydown);
186
+ }
187
+ l(() => {
188
+ let e = this.isOn(), t = this;
189
+ t && t.classList && (t.classList.toggle("is-on", e), t.classList.toggle("is-checked", e), t.setAttribute("aria-checked", String(e)));
190
+ }), l(() => {
191
+ let e = this.disabled(), t = this;
192
+ t && t.classList && (t.classList.toggle("is-disabled", e), e ? (t.setAttribute("aria-disabled", "true"), t.setAttribute("tabindex", "-1")) : (t.removeAttribute("aria-disabled"), t.setAttribute("tabindex", "0")));
193
+ });
194
+ }
195
+ onDestroy() {
196
+ let e = this;
197
+ e && typeof e.removeEventListener == "function" && (e.removeEventListener("click", this.handleClick), e.removeEventListener("keydown", this.handleKeydown));
198
+ }
199
+ switchOn() {
200
+ this.disabled() || this.isOn() || (this.isOn.set(!0), this.dispatchChangeEvent());
201
+ }
202
+ switchOff() {
203
+ this.disabled() || this.isOn() && (this.isOn.set(!1), this.dispatchChangeEvent());
204
+ }
205
+ toggle() {
206
+ if (this.disabled()) return;
207
+ let e = !this.isOn();
208
+ this.isOn.set(e), this.dispatchChangeEvent();
209
+ }
210
+ dispatchChangeEvent() {
211
+ let e = this;
212
+ e && typeof e.dispatchEvent == "function" && e.dispatchEvent(new CustomEvent("change", {
213
+ detail: {
214
+ checked: this.isOn(),
215
+ isOn: this.isOn()
216
+ },
217
+ bubbles: !0,
218
+ composed: !0
219
+ }));
220
+ }
221
+ };
222
+ r({
223
+ selector: "switch-button",
224
+ templateUrl: "./switch-button.component.html",
225
+ template: _
226
+ })(v);
227
+ //#endregion
228
+ //#region src/app/shared/components/modal/modal-view.component.html?raw
229
+ var y = "<div\n class=\"modal-backdrop {{isOpen() ? 'is-open' : 'is-closed'}} {{isMaximized() ? 'is-maximized' : ''}}\"\n onclick=\"onBackdropClick(event)\"\n>\n <div class=\"modal-dialog window\" onclick=\"event.stopPropagation()\">\n <div class=\"modal-header\">\n <div class=\"modal-title-area\">\n <span class=\"modal-icon\">🪟</span>\n <h3 class=\"modal-title\">{{title()}}</h3>\n </div>\n <div class=\"modal-controls\">\n <button\n type=\"button\"\n class=\"modal-control-btn maximize-btn\"\n title=\"{{isMaximized() ? 'Restore' : 'Maximize'}}\"\n onclick=\"maximize()\"\n >\n {{isMaximized() ? '🗗' : '🗖'}}\n </button>\n <button\n type=\"button\"\n class=\"modal-control-btn close-btn\"\n title=\"Close\"\n onclick=\"close()\"\n >\n ✕\n </button>\n </div>\n </div>\n\n <div class=\"modal-body\">\n <div class=\"modal-content-area\">\n <slot>\n <p>Welcome to the <strong>Purity Modal Dialog Component</strong>.</p>\n <p>\n This modal is managed reactively via Purity signals with fixed viewport overlay and <code>z-index: 1000</code>.\n </p>\n <div class=\"modal-info-card\">\n <div><strong>Status:</strong> <span class=\"status-pill is-active\">Active</span></div>\n <div><strong>Maximized:</strong> {{isMaximized() ? 'Yes' : 'No'}}</div>\n </div>\n </slot>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"button-cancel\" onclick=\"close()\">\n Cancel\n </button>\n <button type=\"button\" class=\"button-primary\" onclick=\"close()\">\n Done\n </button>\n </div>\n </div>\n</div>\n", b = class {
230
+ isOpen = f(!1);
231
+ isMaximized = f(!1);
232
+ title = f("Purity Modal Dialog");
233
+ _hostEl;
234
+ _backdropEl;
235
+ keydownHandler = (e) => {
236
+ e.key === "Escape" && this.isOpen() && this.close();
237
+ };
238
+ onInit() {
239
+ window.addEventListener("keydown", this.keydownHandler);
240
+ let e = this;
241
+ if (this._hostEl = e, e && typeof e.getAttribute == "function") {
242
+ let t = e.getAttribute("title");
243
+ t && this.title.set(t);
244
+ let n = e.getAttribute("is-open") || e.getAttribute("open");
245
+ n !== null && n !== "false" && n !== "null" && n !== "0" && this.isOpen.set(!0);
246
+ }
247
+ let t = e.querySelector(".modal-backdrop");
248
+ t && t.parentElement !== document.body && (this._backdropEl = t, document.body.appendChild(t));
249
+ }
250
+ onDestroy() {
251
+ window.removeEventListener("keydown", this.keydownHandler), this._backdropEl && this._backdropEl.parentElement === document.body && this._backdropEl.remove();
252
+ }
253
+ disconnectedCallback() {
254
+ this.onDestroy();
255
+ }
256
+ open(e) {
257
+ e?.title && this.title.set(e.title);
258
+ let t = this._hostEl || this, n = this._backdropEl || t?.querySelector?.(".modal-backdrop");
259
+ n && n.parentElement !== document.body && (this._backdropEl = n, document.body.appendChild(n)), this.isOpen.set(!0);
260
+ }
261
+ close() {
262
+ this.isOpen.set(!1);
263
+ }
264
+ maximize() {
265
+ this.isMaximized.update((e) => !e);
266
+ }
267
+ onBackdropClick(e) {
268
+ e.target === e.currentTarget && this.close();
269
+ }
270
+ };
271
+ r({
272
+ selector: "modal-view",
273
+ templateUrl: "./src/app/shared/components/modal/modal-view.component.html",
274
+ template: y
275
+ })(b);
276
+ //#endregion
277
+ //#region src/app/shared/components/date-time-picker/date-time-picker.component.html?raw
278
+ var x = "<div class=\"date-time-picker-container\">\n <button\n class=\"picker-toggle\"\n type=\"button\"\n aria-haspopup=\"dialog\"\n aria-expanded=\"{{isOpen() ? 'true' : 'false'}}\"\n onclick=\"togglePicker(event)\"\n >\n <span class=\"picker-toggle-icon\">📅</span>\n <span class=\"picker-toggle-text\">{{displayLabel}}</span>\n </button>\n\n <div\n class=\"picker-overlay {{isOpen() ? 'is-open' : 'is-closed'}} {{enableBlur() ? 'blur-enabled' : ''}} {{placement()}} {{alignPlacement()}}\"\n role=\"dialog\"\n aria-label=\"Date and time picker\"\n >\n <div class=\"calendar-header\">\n <div class=\"label-group\">\n <button\n class=\"year-toggle-btn\"\n type=\"button\"\n aria-label=\"Toggle year picker\"\n onclick=\"toggleYearPicker()\"\n >\n <span class=\"month-label\">{{monthYearLabel}}</span>\n <svg class=\"chevron-icon {{viewMode() === 'year' ? 'is-rotated' : ''}}\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n </button>\n </div>\n <div class=\"header-nav\">\n <button\n type=\"button\"\n class=\"nav-btn prev-btn\"\n aria-label=\"Previous month\"\n onclick=\"prevMonth()\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"nav-btn next-btn\"\n aria-label=\"Next month\"\n onclick=\"nextMonth()\"\n >\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" stroke=\"currentColor\" stroke-width=\"2.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"picker-content-wrapper\">\n <div class=\"calendar-body {{viewMode() === 'year' ? 'blurred' : ''}}\">\n <div class=\"calendar-grid\" onclick=\"onCalendarGridClick(event)\">\n <div class=\"weekday\">Sun</div>\n <div class=\"weekday\">Mon</div>\n <div class=\"weekday\">Tue</div>\n <div class=\"weekday\">Wed</div>\n <div class=\"weekday\">Thu</div>\n <div class=\"weekday\">Fri</div>\n <div class=\"weekday\">Sat</div>\n\n <button\n for=\"let day of calendarDays\"\n class=\"{{day.cellClass}}\"\n type=\"button\"\n data-time=\"{{day.time}}\"\n >\n {{day.dateNum}}\n </button>\n </div>\n </div>\n\n <div class=\"year-selector-overlay {{viewMode() === 'year' ? 'is-visible' : 'is-hidden'}}\">\n <div class=\"year-grid\" onclick=\"onYearGridClick(event)\">\n <button\n for=\"let yr of years\"\n class=\"year-cell {{yr === viewYear ? 'selected' : ''}}\"\n type=\"button\"\n data-year=\"{{yr}}\"\n >\n {{yr}}\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"time-picker\">\n <div class=\"time-label\">\n <span class=\"time-icon\">🕒</span>\n <span>Time:</span>\n </div>\n <div class=\"time-inner-container\">\n <div class=\"time-input-group\">\n <input\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"2\"\n value=\"{{workingHoursFormatted}}\"\n oninput=\"onHoursInput(this)\"\n onchange=\"onTimeChange()\"\n onkeydown=\"handleTimeKeydown(event, 'hours')\"\n onwheel=\"handleWheel(event, 'hours')\"\n aria-label=\"Hours\"\n title=\"Scroll middle mouse or use Up/Down arrows to change hours (00-23)\"\n />\n <span class=\"separator\">:</span>\n <input\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"2\"\n value=\"{{workingMinutesFormatted}}\"\n oninput=\"onMinutesInput(this)\"\n onchange=\"onTimeChange()\"\n onkeydown=\"handleTimeKeydown(event, 'minutes')\"\n onwheel=\"handleWheel(event, 'minutes')\"\n aria-label=\"Minutes\"\n title=\"Scroll middle mouse or use Up/Down arrows to change minutes (00-59)\"\n />\n </div>\n </div>\n </div>\n\n <div class=\"picker-footer\">\n <button\n class=\"confirm-button\"\n type=\"button\"\n onclick=\"confirmSelection()\"\n >\n OK\n </button>\n </div>\n </div>\n</div>\n", S = class {
279
+ isOpen = f(!1);
280
+ selectedDate = f(null);
281
+ viewDate = f(/* @__PURE__ */ new Date());
282
+ enableBlur = f(!1);
283
+ restrictions = f(null);
284
+ workingDate = f(null);
285
+ workingHours = f(12);
286
+ workingMinutes = f(0);
287
+ viewMode = f("calendar");
288
+ placement = f("placement-bottom");
289
+ alignPlacement = f("align-left");
290
+ onDateSelected;
291
+ _hostEl;
292
+ _overlayEl;
293
+ _openedAt = 0;
294
+ _boundDocClick;
295
+ _boundKeydown;
296
+ _boundResize;
297
+ _boundScroll;
298
+ getHost() {
299
+ if (this._hostEl) return this._hostEl;
300
+ let e = this;
301
+ return e && typeof e.querySelector == "function" ? e : null;
302
+ }
303
+ onInit() {
304
+ let e = this;
305
+ this._hostEl = e, this.initWorkingState();
306
+ let t = e.getAttribute?.("value") || e.getAttribute?.("selected-date");
307
+ if (t) {
308
+ let e = new Date(t);
309
+ isNaN(e.getTime()) || (this.selectedDate.set(e), this.viewDate.set(new Date(e)), this.workingDate.set(new Date(e)), this.workingHours.set(e.getHours()), this.workingMinutes.set(e.getMinutes()));
310
+ }
311
+ let n = e.querySelector(".picker-overlay");
312
+ n && (this._overlayEl = n, n.parentElement !== document.body && document.body.appendChild(n), n.classList.toggle("blur-enabled", this.enableBlur())), this._boundDocClick = (t) => {
313
+ if (!this.isOpen() || Date.now() - this._openedAt < 200) return;
314
+ let n = t.composedPath ? t.composedPath() : [], r = t.target;
315
+ e && (n.includes(e) || r && e.contains(r)) || this._overlayEl && (n.includes(this._overlayEl) || r && this._overlayEl.contains(r)) || this.close();
316
+ }, this._boundKeydown = (e) => {
317
+ this.isOpen() && e.key === "Escape" && this.close();
318
+ }, this._boundResize = () => {
319
+ this.isOpen() && this.updateOverlayPosition();
320
+ }, this._boundScroll = () => {
321
+ this.isOpen() && this.updateOverlayPosition();
322
+ }, document.addEventListener("click", this._boundDocClick), window.addEventListener("keydown", this._boundKeydown), window.addEventListener("resize", this._boundResize), window.addEventListener("scroll", this._boundScroll, !0);
323
+ }
324
+ onDestroy() {
325
+ this._boundDocClick && document.removeEventListener("click", this._boundDocClick), this._boundKeydown && window.removeEventListener("keydown", this._boundKeydown), this._boundResize && window.removeEventListener("resize", this._boundResize), this._boundScroll && window.removeEventListener("scroll", this._boundScroll, !0), this._overlayEl && this._overlayEl.parentNode && (this._overlayEl.parentNode.removeChild(this._overlayEl), this._overlayEl = void 0);
326
+ }
327
+ disconnectedCallback() {
328
+ this.onDestroy();
329
+ }
330
+ get effectiveMinDate() {
331
+ let e = this.restrictions();
332
+ if (!e) return null;
333
+ let t = /* @__PURE__ */ new Date(), n = new Date(t.getFullYear(), t.getMonth(), t.getDate()), r = [];
334
+ if (e.minDate && r.push(e.minDate.getTime()), e.daysBack !== void 0 && r.push(n.getTime() - e.daysBack * 864e5), e.weeksBack !== void 0 && r.push(n.getTime() - e.weeksBack * 7 * 864e5), e.monthsBack !== void 0) {
335
+ let t = new Date(n);
336
+ t.setMonth(t.getMonth() - e.monthsBack), r.push(t.getTime());
337
+ }
338
+ if (e.yearsBack !== void 0) {
339
+ let t = new Date(n);
340
+ t.setFullYear(t.getFullYear() - e.yearsBack), r.push(t.getTime());
341
+ }
342
+ e.futureOnly && r.push(t.getTime());
343
+ let i = r.filter((e) => e !== null);
344
+ return i.length > 0 ? new Date(Math.max(...i)) : null;
345
+ }
346
+ get effectiveMaxDate() {
347
+ let e = this.restrictions();
348
+ if (!e) return null;
349
+ let t = /* @__PURE__ */ new Date(), n = new Date(t.getFullYear(), t.getMonth(), t.getDate(), 23, 59, 59, 999), r = [];
350
+ if (e.maxDate && r.push(e.maxDate.getTime()), e.daysForward !== void 0 && r.push(n.getTime() + e.daysForward * 864e5), e.weeksForward !== void 0 && r.push(n.getTime() + e.weeksForward * 7 * 864e5), e.monthsForward !== void 0) {
351
+ let t = new Date(n);
352
+ t.setMonth(t.getMonth() + e.monthsForward), r.push(t.getTime());
353
+ }
354
+ if (e.yearsForward !== void 0) {
355
+ let t = new Date(n);
356
+ t.setFullYear(t.getFullYear() + e.yearsForward), r.push(t.getTime());
357
+ }
358
+ e.pastOnly && r.push(t.getTime());
359
+ let i = r.filter((e) => e !== null);
360
+ return i.length > 0 ? new Date(Math.min(...i)) : null;
361
+ }
362
+ get displayLabel() {
363
+ let e = this.selectedDate();
364
+ return e ? `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")} ${String(e.getHours()).padStart(2, "0")}:${String(e.getMinutes()).padStart(2, "0")}` : "Select Date & Time";
365
+ }
366
+ get monthYearLabel() {
367
+ return this.viewDate().toLocaleDateString(void 0, {
368
+ month: "long",
369
+ year: "numeric"
370
+ });
371
+ }
372
+ get viewYear() {
373
+ return this.viewDate().getFullYear();
374
+ }
375
+ get workingHoursFormatted() {
376
+ return String(this.workingHours()).padStart(2, "0");
377
+ }
378
+ get workingMinutesFormatted() {
379
+ return String(this.workingMinutes()).padStart(2, "0");
380
+ }
381
+ get calendarDays() {
382
+ let e = this.viewDate(), t = e.getFullYear(), n = e.getMonth(), r = new Date(t, n, 1), i = new Date(t, n + 1, 0), a = r.getDay(), o = i.getDate(), s = [], c = /* @__PURE__ */ new Date(), l = this.workingDate(), u = new Date(t, n, 0).getDate();
383
+ for (let e = a - 1; e >= 0; e--) {
384
+ let r = new Date(t, n - 1, u - e);
385
+ s.push(this.createCalendarDay(r, !1, c, l));
386
+ }
387
+ for (let e = 1; e <= o; e++) {
388
+ let r = new Date(t, n, e);
389
+ s.push(this.createCalendarDay(r, !0, c, l));
390
+ }
391
+ let d = 42 - s.length;
392
+ for (let e = 1; e <= d; e++) {
393
+ let r = new Date(t, n + 1, e);
394
+ s.push(this.createCalendarDay(r, !1, c, l));
395
+ }
396
+ return s;
397
+ }
398
+ get years() {
399
+ let e = this.viewYear, t = [], n = e - 12, r = e + 15;
400
+ for (let e = n; e <= r; e++) t.push(e);
401
+ return t;
402
+ }
403
+ createCalendarDay(e, t, n, r) {
404
+ let i = e.getDate() === n.getDate() && e.getMonth() === n.getMonth() && e.getFullYear() === n.getFullYear(), a = r !== null && e.getDate() === r.getDate() && e.getMonth() === r.getMonth() && e.getFullYear() === r.getFullYear(), o = this.isDateDisabled(e), s = ["day-cell"];
405
+ return t || s.push("off-month"), i && s.push("today"), a && s.push("selected"), o && s.push("disabled"), {
406
+ date: e,
407
+ time: e.getTime(),
408
+ dateNum: e.getDate(),
409
+ isCurrentMonth: t,
410
+ isToday: i,
411
+ isSelected: a,
412
+ isDisabled: o,
413
+ cellClass: s.join(" ")
414
+ };
415
+ }
416
+ isDateDisabled(e) {
417
+ let t = this.effectiveMinDate, n = this.effectiveMaxDate, r = new Date(e.getFullYear(), e.getMonth(), e.getDate()).getTime();
418
+ if (t && r < new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime() || n && r > new Date(n.getFullYear(), n.getMonth(), n.getDate()).getTime()) return !0;
419
+ let i = this.restrictions();
420
+ if (i?.disabledDates && i.disabledDates.length > 0) {
421
+ for (let t of i.disabledDates) if (e.getDate() === t.getDate() && e.getMonth() === t.getMonth() && e.getFullYear() === t.getFullYear()) return !0;
422
+ }
423
+ return !1;
424
+ }
425
+ initWorkingState() {
426
+ let e = this.selectedDate();
427
+ if (e) this.workingDate.set(new Date(e)), this.workingHours.set(e.getHours()), this.workingMinutes.set(e.getMinutes()), this.viewDate.set(new Date(e.getFullYear(), e.getMonth(), 1));
428
+ else {
429
+ let e = /* @__PURE__ */ new Date();
430
+ this.workingDate.set(null), this.workingHours.set(12), this.workingMinutes.set(0), this.viewDate.set(new Date(e.getFullYear(), e.getMonth(), 1));
431
+ }
432
+ this.enforceTimeRestrictions();
433
+ }
434
+ updateOverlayPosition() {
435
+ let e = this.getHost(), t = this._overlayEl || e?.querySelector(".picker-overlay");
436
+ if (!e || !t) return;
437
+ let n = e.querySelector(".picker-toggle");
438
+ if (!n) return;
439
+ let r = n.getBoundingClientRect(), i = window.innerHeight, a = window.innerWidth, o = i - r.bottom, s = r.top, c = !1;
440
+ o < 380 && s >= 380 && (c = !0), this.placement.set(c ? "placement-top" : "placement-bottom");
441
+ let l = c ? r.top - 380 - 6 : r.bottom + 6, u = r.left;
442
+ u + 290 > a - 10 ? (u = Math.max(10, a - 290 - 10), this.alignPlacement.set("align-right")) : this.alignPlacement.set("align-left"), l < 10 && (l = 10), l + 380 > i - 10 && (l = Math.max(10, i - 380 - 10)), t.style.top = `${l}px`, t.style.left = `${u}px`;
443
+ }
444
+ togglePicker(e) {
445
+ e?.stopPropagation(), this.isOpen() ? this.close() : this.open();
446
+ }
447
+ open() {
448
+ let e = this.getHost();
449
+ if (!this._overlayEl && e) {
450
+ let t = e.querySelector(".picker-overlay");
451
+ t && (this._overlayEl = t, t.parentElement !== document.body && document.body.appendChild(t));
452
+ }
453
+ if (!this._overlayEl) return;
454
+ this._openedAt = Date.now(), this.initWorkingState(), this.viewMode.set("calendar"), this.updateOverlayPosition(), this.isOpen.set(!0), this._overlayEl.classList.add("is-open"), this._overlayEl.classList.remove("is-closed"), this._overlayEl.classList.toggle("blur-enabled", this.enableBlur());
455
+ let t = this._overlayEl.querySelector(".calendar-body"), n = this._overlayEl.querySelector(".year-selector-overlay");
456
+ t && t.classList.remove("blurred"), n && (n.classList.remove("is-visible"), n.classList.add("is-hidden"));
457
+ }
458
+ close() {
459
+ this.isOpen.set(!1), this._overlayEl && (this._overlayEl.classList.remove("is-open"), this._overlayEl.classList.add("is-closed"));
460
+ }
461
+ onCalendarGridClick(e) {
462
+ let t = e.target?.closest(".day-cell");
463
+ if (t && t.dataset.time) {
464
+ let e = Number(t.dataset.time);
465
+ isNaN(e) || this.selectDayByTime(e);
466
+ }
467
+ }
468
+ onYearGridClick(e) {
469
+ let t = e.target?.closest(".year-cell");
470
+ if (t && t.dataset.year) {
471
+ let e = Number(t.dataset.year);
472
+ isNaN(e) || this.selectYear(e);
473
+ }
474
+ }
475
+ selectDayByTime(e) {
476
+ let t = new Date(e);
477
+ this.createCalendarDay(t, !0, /* @__PURE__ */ new Date(), null).isDisabled || (this.workingDate.set(t), (t.getMonth() !== this.viewDate().getMonth() || t.getFullYear() !== this.viewDate().getFullYear()) && this.viewDate.set(new Date(t.getFullYear(), t.getMonth(), 1)), this.enforceTimeRestrictions());
478
+ }
479
+ toggleYearPicker() {
480
+ let e = this.viewMode() === "calendar" ? "year" : "calendar";
481
+ if (this.viewMode.set(e), this._overlayEl) {
482
+ let t = this._overlayEl.querySelector(".calendar-body"), n = this._overlayEl.querySelector(".year-selector-overlay");
483
+ t && t.classList.toggle("blurred", e === "year"), n && (n.classList.toggle("is-visible", e === "year"), n.classList.toggle("is-hidden", e !== "year"));
484
+ }
485
+ }
486
+ selectYear(e) {
487
+ let t = this.viewDate();
488
+ if (this.viewDate.set(new Date(e, t.getMonth(), 1)), this.viewMode.set("calendar"), this._overlayEl) {
489
+ let e = this._overlayEl.querySelector(".calendar-body"), t = this._overlayEl.querySelector(".year-selector-overlay");
490
+ e && e.classList.remove("blurred"), t && (t.classList.remove("is-visible"), t.classList.add("is-hidden"));
491
+ }
492
+ }
493
+ prevMonth() {
494
+ let e = this.viewDate();
495
+ this.viewDate.set(new Date(e.getFullYear(), e.getMonth() - 1, 1));
496
+ }
497
+ nextMonth() {
498
+ let e = this.viewDate();
499
+ this.viewDate.set(new Date(e.getFullYear(), e.getMonth() + 1, 1));
500
+ }
501
+ onHoursInput(e) {
502
+ let t = e.value.replace(/\D/g, ""), n = parseInt(t, 10);
503
+ isNaN(n) && (n = 0), n > 23 && (n = 23), n < 0 && (n = 0), this.workingHours.set(n);
504
+ }
505
+ onMinutesInput(e) {
506
+ let t = e.value.replace(/\D/g, ""), n = parseInt(t, 10);
507
+ isNaN(n) && (n = 0), n > 59 && (n = 59), n < 0 && (n = 0), this.workingMinutes.set(n);
508
+ }
509
+ onTimeChange() {
510
+ this.enforceTimeRestrictions();
511
+ }
512
+ handleTimeKeydown(e, t) {
513
+ let n = e.target, r = e.key;
514
+ if (r === "ArrowUp" || r === "ArrowDown") {
515
+ e.preventDefault(), e.stopPropagation();
516
+ let i = r === "ArrowUp" ? 1 : -1;
517
+ if (t === "hours" || n.getAttribute("aria-label") === "Hours") {
518
+ let e = this.workingHours() + i;
519
+ e > 23 && (e = 0), e < 0 && (e = 23), this.workingHours.set(e), n.value = this.workingHoursFormatted;
520
+ } else {
521
+ let e = this.workingMinutes() + i;
522
+ e > 59 && (e = 0), e < 0 && (e = 59), this.workingMinutes.set(e), n.value = this.workingMinutesFormatted;
523
+ }
524
+ this.onTimeChange(), n.select();
525
+ return;
526
+ }
527
+ if (!([
528
+ "Backspace",
529
+ "Tab",
530
+ "Enter",
531
+ "Escape",
532
+ "Delete",
533
+ "ArrowLeft",
534
+ "ArrowRight",
535
+ "Home",
536
+ "End"
537
+ ].includes(r) || e.ctrlKey && [
538
+ "a",
539
+ "c",
540
+ "v",
541
+ "x"
542
+ ].includes(r.toLowerCase()))) {
543
+ if (!/^\d$/.test(r)) {
544
+ e.preventDefault(), e.stopPropagation();
545
+ return;
546
+ }
547
+ n.selectionStart === n.selectionEnd && n.value.length >= 2 && (e.preventDefault(), e.stopPropagation());
548
+ }
549
+ }
550
+ handleWheel(e, t) {
551
+ e.preventDefault(), e.stopPropagation();
552
+ let n = e.deltaY < 0 ? 1 : -1;
553
+ if (t === "hours") {
554
+ let e = this.workingHours() + n;
555
+ e > 23 && (e = 0), e < 0 && (e = 23), this.workingHours.set(e);
556
+ } else {
557
+ let e = this.workingMinutes() + n;
558
+ e > 59 && (e = 0), e < 0 && (e = 59), this.workingMinutes.set(e);
559
+ }
560
+ this.onTimeChange();
561
+ let r = e.target;
562
+ r && (r.value = t === "hours" ? this.workingHoursFormatted : this.workingMinutesFormatted, r.select());
563
+ }
564
+ confirmSelection() {
565
+ let e = this.workingDate();
566
+ if (!e && (e = /* @__PURE__ */ new Date(), this.isDateDisabled(e))) return;
567
+ let t = new Date(e.getFullYear(), e.getMonth(), e.getDate(), this.workingHours(), this.workingMinutes(), 0, 0);
568
+ this.selectedDate.set(t), this.emitSelection(), this.close();
569
+ }
570
+ enforceTimeRestrictions() {
571
+ let e = this.workingDate(), t = this.restrictions();
572
+ if (t && (e && t.minDate && e.getDate() === t.minDate.getDate() && e.getMonth() === t.minDate.getMonth() && e.getFullYear() === t.minDate.getFullYear() || !e)) {
573
+ let e = this.workingHours() * 60 + this.workingMinutes();
574
+ if (t.minTime) {
575
+ let [n, r] = t.minTime.split(":").map(Number);
576
+ e < n * 60 + r && this.setWorkingTime(n, r);
577
+ }
578
+ if (t.maxTime) {
579
+ let [n, r] = t.maxTime.split(":").map(Number);
580
+ e > n * 60 + r && this.setWorkingTime(n, r);
581
+ }
582
+ }
583
+ }
584
+ setWorkingTime(e, t) {
585
+ this.workingHours.set(e), this.workingMinutes.set(t);
586
+ }
587
+ setDate(e) {
588
+ this.selectedDate.set(e), this.initWorkingState();
589
+ }
590
+ setRestrictions(e) {
591
+ this.restrictions.set(e), this.enforceTimeRestrictions();
592
+ }
593
+ setBlur(e) {
594
+ this.enableBlur.set(e), this._overlayEl && this._overlayEl.classList.toggle("blur-enabled", e);
595
+ }
596
+ emitSelection() {
597
+ let e = this.selectedDate();
598
+ if (e) {
599
+ this.onDateSelected?.(e);
600
+ let t = this.getHost();
601
+ t?.dispatchEvent?.(new CustomEvent("date-selected", {
602
+ detail: { date: e },
603
+ bubbles: !0,
604
+ composed: !0
605
+ })), t?.dispatchEvent?.(new CustomEvent("change", {
606
+ detail: {
607
+ date: e,
608
+ value: e
609
+ },
610
+ bubbles: !0,
611
+ composed: !0
612
+ }));
613
+ }
614
+ }
615
+ get value() {
616
+ return this.selectedDate();
617
+ }
618
+ set value(e) {
619
+ if (!e) {
620
+ this.selectedDate.set(null);
621
+ return;
622
+ }
623
+ let t = e instanceof Date ? e : new Date(e);
624
+ isNaN(t.getTime()) || (this.selectedDate.set(t), this.viewDate.set(new Date(t)), this.workingDate.set(new Date(t)), this.workingHours.set(t.getHours()), this.workingMinutes.set(t.getMinutes()));
625
+ }
626
+ };
627
+ r({
628
+ selector: "date-time-picker",
629
+ templateUrl: "./src/app/shared/components/date-time-picker/date-time-picker.component.html",
630
+ template: x
631
+ })(S);
632
+ //#endregion
633
+ //#region src/app/shared/components/notification/notification.component.html?raw
634
+ var C = "<div class=\"notification-container\" aria-live=\"polite\">\n <div for=\"let group of positionGroups\" class=\"toast-stack pos-{{group.position}}\">\n <div\n for=\"let item of group.items\"\n class=\"toast-card toast-{{item.type}} {{item.blink ? 'toast-blink' : ''}}\"\n style=\"{{item.width ? 'width: ' + item.width + ';' : ''}} {{item.height ? 'height: ' + item.height + ';' : ''}}\"\n >\n <div class=\"toast-icon-wrapper\">\n <span class=\"toast-icon icon-{{item.type}}\"></span>\n </div>\n <div class=\"toast-body\">\n <div class=\"toast-title\">{{item.title}}</div>\n <div class=\"toast-subtitle\">{{item.subtitle}}</div>\n </div>\n <button\n type=\"button\"\n class=\"toast-close-btn\"\n title=\"Close notification\"\n onclick=\"dismiss(item.id)\"\n >\n <span class=\"toast-countdown\">{{item.remainingSeconds ? item.remainingSeconds + 's' : ''}}</span>\n <span class=\"toast-close-icon\">✕</span>\n </button>\n </div>\n </div>\n</div>\n", w = class {
635
+ notifications = f([]);
636
+ timers = /* @__PURE__ */ new Map();
637
+ tickerInterval = null;
638
+ ensureTicker() {
639
+ this.tickerInterval || typeof window > "u" || (this.tickerInterval = setInterval(() => {
640
+ let e = this.notifications();
641
+ if (e.length === 0) {
642
+ clearInterval(this.tickerInterval), this.tickerInterval = null;
643
+ return;
644
+ }
645
+ let t = !1, n = e.map((e) => e.duration > 0 && e.remainingSeconds > 0 ? (t = !0, {
646
+ ...e,
647
+ remainingSeconds: Math.max(0, e.remainingSeconds - 1)
648
+ }) : e);
649
+ t && this.notifications.set(n);
650
+ }, 1e3));
651
+ }
652
+ notify(e) {
653
+ let t = e.id || `notify_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`, n = e.duration === void 0 ? 1e4 : e.duration, r = n > 0 ? Math.ceil(n / 1e3) : 0, i = {
654
+ id: t,
655
+ type: e.type || "info",
656
+ title: e.title,
657
+ subtitle: e.subtitle || "",
658
+ position: e.position || "top-right",
659
+ duration: n,
660
+ remainingSeconds: r,
661
+ blink: e.blink === !0,
662
+ width: e.width || "",
663
+ height: e.height || "",
664
+ dismissible: e.dismissible !== !1,
665
+ createdAt: Date.now(),
666
+ onClose: e.onClose
667
+ };
668
+ if (this.notifications.update((e) => [...e, i]), n > 0 && typeof window < "u") {
669
+ let e = setTimeout(() => {
670
+ this.dismiss(t);
671
+ }, n);
672
+ this.timers.set(t, e), this.ensureTicker();
673
+ }
674
+ return t;
675
+ }
676
+ success(e, t, n) {
677
+ return this.notify({
678
+ ...n,
679
+ type: "success",
680
+ title: e,
681
+ subtitle: t
682
+ });
683
+ }
684
+ error(e, t, n) {
685
+ return this.notify({
686
+ ...n,
687
+ type: "error",
688
+ title: e,
689
+ subtitle: t
690
+ });
691
+ }
692
+ warn(e, t, n) {
693
+ return this.notify({
694
+ ...n,
695
+ type: "warn",
696
+ title: e,
697
+ subtitle: t
698
+ });
699
+ }
700
+ info(e, t, n) {
701
+ return this.notify({
702
+ ...n,
703
+ type: "info",
704
+ title: e,
705
+ subtitle: t
706
+ });
707
+ }
708
+ dismiss(e) {
709
+ let t = this.timers.get(e);
710
+ t && (clearTimeout(t), this.timers.delete(e));
711
+ let n = this.notifications(), r = n.find((t) => t.id === e);
712
+ if (r && r.onClose) try {
713
+ r.onClose();
714
+ } catch (e) {
715
+ console.error("[NotifyService] Error in onClose handler:", e);
716
+ }
717
+ let i = n.filter((t) => t.id !== e);
718
+ i.length === 0 && this.tickerInterval && (clearInterval(this.tickerInterval), this.tickerInterval = null), this.notifications.set(i);
719
+ }
720
+ clear() {
721
+ for (let e of this.timers.values()) clearTimeout(e);
722
+ this.timers.clear(), this.tickerInterval &&= (clearInterval(this.tickerInterval), null), this.notifications.set([]);
723
+ }
724
+ };
725
+ a("NotifyService")(w);
726
+ //#endregion
727
+ //#region src/app/shared/components/notification/notification.component.ts
728
+ var T = [
729
+ "top-right",
730
+ "top-left",
731
+ "top-center",
732
+ "bottom-right",
733
+ "bottom-left",
734
+ "bottom-center",
735
+ "center"
736
+ ], E = class {
737
+ notifyService = d(w);
738
+ positionGroups = f([]);
739
+ onInit() {
740
+ l(() => {
741
+ let e = this.notifyService.notifications(), t = [];
742
+ for (let n of T) {
743
+ let r = e.filter((e) => e.position === n);
744
+ r.length > 0 && t.push({
745
+ position: n,
746
+ items: r
747
+ });
748
+ }
749
+ this.positionGroups.set(t);
750
+ });
751
+ }
752
+ dismiss(e) {
753
+ this.notifyService.dismiss(e);
754
+ }
755
+ };
756
+ r({
757
+ selector: "notification-component",
758
+ templateUrl: "./src/app/shared/components/notification/notification.component.html",
759
+ template: C
760
+ })(E);
761
+ //#endregion
762
+ //#region src/app/shared/components/loader/loader.component.html?raw
763
+ var D = "<div class=\"loader-inline-root {{isLoading() ? 'visible' : ''}}\" aria-hidden=\"{{!isLoading()}}\">\n <div class=\"loader-spinner-box\">\n <svg class=\"loader-svg\" viewBox=\"0 0 50 50\" aria-label=\"Loading\">\n <circle class=\"loader-track\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"4\"></circle>\n <circle class=\"loader-head\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"4\"></circle>\n </svg>\n </div>\n <span class=\"loader-text\">{{message()}}</span>\n</div>\n", O = class {
764
+ isLoading = f(!1);
765
+ message = f("Loading...");
766
+ isHoldingCursor = !1;
767
+ onInit() {
768
+ let e = this.element || this;
769
+ if (e && typeof e.getAttribute == "function") {
770
+ let t = e.getAttribute("message");
771
+ t && this.message.set(t);
772
+ let n = e.getAttribute("is-loading");
773
+ n !== null && n !== "false" && n !== "null" && n !== "0" && this.isLoading.set(!0);
774
+ }
775
+ l(() => {
776
+ let t = this.isLoading();
777
+ e && e.classList.toggle("is-loading", t), t && !this.isHoldingCursor ? (this.isHoldingCursor = !0, p()) : !t && this.isHoldingCursor && (this.isHoldingCursor = !1, m());
778
+ });
779
+ }
780
+ onDestroy() {
781
+ this.isHoldingCursor && (this.isHoldingCursor = !1, m());
782
+ }
783
+ show(e = "Loading...") {
784
+ this.message.set(e || "Loading..."), this.isLoading.set(!0);
785
+ }
786
+ hide() {
787
+ this.isLoading.set(!1);
788
+ }
789
+ toggle(e, t = "Loading...") {
790
+ this.message.set(t || "Loading..."), e === void 0 ? this.isLoading.update((e) => !e) : this.isLoading.set(e);
791
+ }
792
+ };
793
+ r({
794
+ selector: "loader-component",
795
+ templateUrl: "./src/app/shared/components/loader/loader.component.html",
796
+ template: D
797
+ })(O);
798
+ //#endregion
799
+ //#region src/app/shared/components/popover/popover.component.html?raw
800
+ var k = "<div class=\"purity-popover-portal {{isOpen() ? 'is-open' : 'is-closed'}} pos-{{effectivePosition()}}\">\n <div class=\"popover-arrow\"></div>\n <div class=\"popover-surface\">\n <slot>Popover content</slot>\n </div>\n</div>\n", A = class {
801
+ isOpen = f(!1);
802
+ targetFor = f("");
803
+ position = f("bottom");
804
+ effectivePosition = f("bottom");
805
+ offset = 8;
806
+ closeDelay = 120;
807
+ _portalEl = null;
808
+ _targetEl = null;
809
+ _closeTimer = null;
810
+ _boundOnTargetEnter = () => this.handleTargetEnter();
811
+ _boundOnTargetLeave = () => this.handleTargetLeave();
812
+ _boundOnPopoverEnter = () => this.handlePopoverEnter();
813
+ _boundOnPopoverLeave = () => this.handlePopoverLeave();
814
+ _boundOnWindowChange = () => {
815
+ this.isOpen() && this.updatePosition();
816
+ };
817
+ onInit() {
818
+ let e = this, t = e.getAttribute?.("target-for") || e.getAttribute?.("target");
819
+ if (t) {
820
+ let e = t.replace(/^['"]|['"]$/g, "").trim();
821
+ this.targetFor.set(e);
822
+ }
823
+ let n = e.getAttribute?.("position");
824
+ if (n) {
825
+ let e = n.replace(/^['"]|['"]$/g, "").trim();
826
+ [
827
+ "top",
828
+ "bottom",
829
+ "left",
830
+ "right"
831
+ ].includes(e) && (this.position.set(e), this.effectivePosition.set(e));
832
+ }
833
+ let r = e.getAttribute?.("offset");
834
+ if (r) {
835
+ let e = parseInt(r, 10);
836
+ isNaN(e) || (this.offset = e);
837
+ }
838
+ this._portalEl = e.querySelector?.(".purity-popover-portal"), this._portalEl && this._portalEl.parentElement !== document.body && document.body.appendChild(this._portalEl), this._portalEl && (this._portalEl.addEventListener("mouseenter", this._boundOnPopoverEnter), this._portalEl.addEventListener("mouseleave", this._boundOnPopoverLeave)), this.bindTargetListeners(), l(() => {
839
+ this.targetFor() && this.bindTargetListeners();
840
+ }), l(() => {
841
+ let e = this.position();
842
+ e && (this.effectivePosition.set(e), this.isOpen() && this.updatePosition());
843
+ }), window.addEventListener("resize", this._boundOnWindowChange, { passive: !0 }), window.addEventListener("scroll", this._boundOnWindowChange, {
844
+ passive: !0,
845
+ capture: !0
846
+ });
847
+ }
848
+ onDestroy() {
849
+ this.clearCloseTimer(), this.unbindTargetListeners(), this._portalEl && (this._portalEl.removeEventListener("mouseenter", this._boundOnPopoverEnter), this._portalEl.removeEventListener("mouseleave", this._boundOnPopoverLeave), this._portalEl.parentElement === document.body && this._portalEl.remove()), this._portalEl = null, this._targetEl = null, window.removeEventListener("resize", this._boundOnWindowChange), window.removeEventListener("scroll", this._boundOnWindowChange, !0);
850
+ }
851
+ disconnectedCallback() {
852
+ this.onDestroy();
853
+ }
854
+ bindTargetListeners() {
855
+ let e = this.targetFor();
856
+ if (!e || typeof document > "u") return;
857
+ this.unbindTargetListeners();
858
+ let t = document.querySelector(e);
859
+ t && (this._targetEl = t, t.addEventListener("mouseenter", this._boundOnTargetEnter), t.addEventListener("mouseleave", this._boundOnTargetLeave));
860
+ }
861
+ unbindTargetListeners() {
862
+ this._targetEl &&= (this._targetEl.removeEventListener("mouseenter", this._boundOnTargetEnter), this._targetEl.removeEventListener("mouseleave", this._boundOnTargetLeave), null);
863
+ }
864
+ setTargetFor(e) {
865
+ this.targetFor.set(e.replace(/^['"]|['"]$/g, "").trim()), this.bindTargetListeners();
866
+ }
867
+ setPosition(e) {
868
+ [
869
+ "top",
870
+ "bottom",
871
+ "left",
872
+ "right"
873
+ ].includes(e) && (this.position.set(e), this.effectivePosition.set(e), this.isOpen() && this.updatePosition());
874
+ }
875
+ open(e) {
876
+ if (this.clearCloseTimer(), e) {
877
+ if (typeof e == "string") {
878
+ let t = document.querySelector(e);
879
+ t && (this._targetEl = t);
880
+ } else e instanceof HTMLElement && (this._targetEl = e);
881
+ }
882
+ if (!this._targetEl && this.targetFor() && (this._targetEl = document.querySelector(this.targetFor())), !this._portalEl) {
883
+ let e = this;
884
+ this._portalEl = e?.querySelector?.(".purity-popover-portal") || document.querySelector(".purity-popover-portal"), this._portalEl && this._portalEl.parentElement !== document.body && document.body.appendChild(this._portalEl);
885
+ }
886
+ this.isOpen.set(!0), this._portalEl && (this._portalEl.classList.remove("is-closed"), this._portalEl.classList.add("is-open")), requestAnimationFrame(() => {
887
+ this.updatePosition();
888
+ });
889
+ }
890
+ close() {
891
+ this.clearCloseTimer(), this.isOpen.set(!1), this._portalEl && (this._portalEl.classList.remove("is-open"), this._portalEl.classList.add("is-closed"));
892
+ }
893
+ toggle(e) {
894
+ this.isOpen() ? this.close() : this.open(e);
895
+ }
896
+ updatePosition() {
897
+ let e = this._portalEl, t = this._targetEl || (this.targetFor() ? document.querySelector(this.targetFor()) : null);
898
+ if (!e || !t || typeof window > "u") return;
899
+ let n = t.getBoundingClientRect(), r = e.getBoundingClientRect(), i = r.width || 200, a = r.height || 80, o = window.innerWidth, s = window.innerHeight, c = this.offset, l = this.position(), u = 0, d = 0;
900
+ if (l === "bottom") {
901
+ let e = n.bottom + c + a > s - 8, t = n.top - c - a >= 8;
902
+ e && t && (l = "top");
903
+ } else if (l === "top") {
904
+ let e = n.top - c - a < 8, t = n.bottom + c + a <= s - 8;
905
+ e && t && (l = "bottom");
906
+ } else if (l === "left") {
907
+ let e = n.left - c - i < 8, t = n.right + c + i <= o - 8;
908
+ e && t && (l = "right");
909
+ } else if (l === "right") {
910
+ let e = n.right + c + i > o - 8, t = n.left - c - i >= 8;
911
+ e && t && (l = "left");
912
+ }
913
+ l === "bottom" ? (u = n.bottom + c, d = n.left + (n.width - i) / 2) : l === "top" ? (u = n.top - a - c, d = n.left + (n.width - i) / 2) : l === "left" ? (u = n.top + (n.height - a) / 2, d = n.left - i - c) : l === "right" && (u = n.top + (n.height - a) / 2, d = n.right + c), d = Math.max(8, Math.min(d, o - i - 8)), u = Math.max(8, Math.min(u, s - a - 8)), e.style.top = `${Math.round(u)}px`, e.style.left = `${Math.round(d)}px`, e.classList.remove("pos-top", "pos-bottom", "pos-left", "pos-right"), e.classList.add(`pos-${l}`), this.effectivePosition.set(l);
914
+ }
915
+ handleTargetEnter() {
916
+ this.open();
917
+ }
918
+ handleTargetLeave() {
919
+ this.scheduleClose();
920
+ }
921
+ handlePopoverEnter() {
922
+ this.clearCloseTimer();
923
+ }
924
+ handlePopoverLeave() {
925
+ this.scheduleClose();
926
+ }
927
+ scheduleClose() {
928
+ this.clearCloseTimer(), this._closeTimer = setTimeout(() => {
929
+ this.close();
930
+ }, this.closeDelay);
931
+ }
932
+ clearCloseTimer() {
933
+ this._closeTimer &&= (clearTimeout(this._closeTimer), null);
934
+ }
935
+ }, j = class extends e {
936
+ instance;
937
+ onInit() {
938
+ let e = this.element;
939
+ if (!e || e.hasAttribute("data-popover-ready")) return;
940
+ e.setAttribute("data-popover-ready", "true"), e.style.display = "none";
941
+ let t = document.createElement("div");
942
+ t.className = "purity-popover-portal is-closed pos-bottom", t.innerHTML = "\n <div class=\"popover-arrow\"></div>\n <div class=\"popover-surface\"></div>\n ";
943
+ let n = t.querySelector(".popover-surface");
944
+ for (; e.firstChild;) n.appendChild(e.firstChild);
945
+ document.body.appendChild(t);
946
+ let r = new A();
947
+ r._portalEl = t;
948
+ let i = e.getAttribute("target-for") || e.getAttribute("target");
949
+ i && r.setTargetFor(i);
950
+ let a = e.getAttribute("position");
951
+ a && r.setPosition(a.replace(/^['"]|['"]$/g, "")), t.addEventListener("mouseenter", () => r.handlePopoverEnter()), t.addEventListener("mouseleave", () => r.handlePopoverLeave()), e.open = (e) => r.open(e), e.close = () => r.close(), e.toggle = (e) => r.toggle(e), e.isOpen = () => r.isOpen(), e.setPosition = (e) => r.setPosition(e), e.setTargetFor = (e) => r.setTargetFor(e), e.targetFor = r.targetFor, e.position = r.position, e.effectivePosition = r.effectivePosition, this.instance = r;
952
+ }
953
+ onDestroy() {
954
+ this.instance?.onDestroy();
955
+ }
956
+ };
957
+ r({
958
+ selector: "popover-component",
959
+ templateUrl: "./src/app/shared/components/popover/popover.component.html",
960
+ template: k
961
+ })(A), i("popover")(j);
962
+ //#endregion
963
+ //#region src/app/shared/components/radial-context-menu/radial-context-menu.component.html?raw
964
+ var M = "<div\n class=\"radial-menu-root is-closed\"\n role=\"menu\"\n aria-label=\"Radial Context Menu\"\n>\n <button\n class=\"center-button\"\n type=\"button\"\n aria-label=\"Menu Center Action\"\n >\n <span class=\"center-icon\">×</span>\n <span class=\"menu-title-pop\"></span>\n </button>\n</div>\n", N = class {
965
+ itemsSource = f([]);
966
+ navigationStack = f([]);
967
+ isOpen = f(!1);
968
+ coords = f({
969
+ x: 0,
970
+ y: 0
971
+ });
972
+ radius = f(150);
973
+ activeHoverItem = f(null);
974
+ selector = f(null);
975
+ enableBlur = f(!0);
976
+ onSelectItem;
977
+ onHover;
978
+ onOpen;
979
+ onClose;
980
+ onNavigate;
981
+ menuEl = null;
982
+ titlePopEl = null;
983
+ centerBtnEl = null;
984
+ itemsContainerEl = null;
985
+ _openedAt = 0;
986
+ _boundContextMenu;
987
+ _boundClick;
988
+ _boundKeydown;
989
+ onInit() {
990
+ this._boundContextMenu = (e) => this.onDocumentContextMenu(e), this._boundClick = (e) => this.onDocumentClick(e), this._boundKeydown = (e) => this.onDocumentKeydown(e), this.createMenuDOM(), document.addEventListener("contextmenu", this._boundContextMenu), document.addEventListener("click", this._boundClick), window.addEventListener("keydown", this._boundKeydown);
991
+ }
992
+ onDestroy() {
993
+ this._boundContextMenu && document.removeEventListener("contextmenu", this._boundContextMenu), this._boundClick && document.removeEventListener("click", this._boundClick), this._boundKeydown && window.removeEventListener("keydown", this._boundKeydown), this.menuEl && this.menuEl.parentNode && this.menuEl.parentNode.removeChild(this.menuEl), this.menuEl = null, this.titlePopEl = null, this.centerBtnEl = null, this.itemsContainerEl = null;
994
+ }
995
+ disconnectedCallback() {
996
+ this.onDestroy();
997
+ }
998
+ createMenuDOM() {
999
+ if (this.menuEl) return;
1000
+ let e = this.radius();
1001
+ this.menuEl = document.createElement("div"), this.menuEl.className = "radial-menu", this.enableBlur() && this.menuEl.classList.add("blur-enabled"), this.menuEl.style.width = `${e * 2}px`, this.menuEl.style.height = `${e * 2}px`, this.menuEl.style.display = "none", this.menuEl.setAttribute("role", "menu"), this.menuEl.setAttribute("aria-label", "Radial Context Menu"), this.titlePopEl = document.createElement("div"), this.titlePopEl.className = "menu-title-pop", this.menuEl.appendChild(this.titlePopEl), this.centerBtnEl = document.createElement("button"), this.centerBtnEl.className = "center-button", this.centerBtnEl.type = "button", this.centerBtnEl.setAttribute("aria-label", "Menu Center Action"), this.centerBtnEl.innerHTML = "<span class=\"center-icon\">×</span>", this.centerBtnEl.addEventListener("click", (e) => {
1002
+ e.stopPropagation(), this.navigationStack().length > 0 ? this.goBack() : this.close();
1003
+ }), this.menuEl.appendChild(this.centerBtnEl), document.body.appendChild(this.menuEl);
1004
+ }
1005
+ get currentItems() {
1006
+ let e = this.navigationStack();
1007
+ return e.length === 0 ? this.itemsSource() : e[e.length - 1].children || [];
1008
+ }
1009
+ get centerIcon() {
1010
+ return this.navigationStack().length > 0 ? "←" : "×";
1011
+ }
1012
+ get centerTitle() {
1013
+ let e = this.activeHoverItem();
1014
+ if (e) return e.name;
1015
+ let t = this.navigationStack();
1016
+ return t.length > 0 ? t[t.length - 1].name : "";
1017
+ }
1018
+ getPoint(e, t) {
1019
+ let n = e * Math.PI / 180;
1020
+ return {
1021
+ x: 50 + t * Math.cos(n),
1022
+ y: 50 + t * Math.sin(n)
1023
+ };
1024
+ }
1025
+ setItems(e) {
1026
+ this.itemsSource.set(e), this.navigationStack.set([]), this.activeHoverItem.set(null), this.isOpen() && (this.renderSegments("in"), this.updateCenterButton());
1027
+ }
1028
+ setSelector(e) {
1029
+ this.selector.set(e);
1030
+ }
1031
+ setBlur(e) {
1032
+ this.enableBlur.set(e), this.menuEl && (e ? this.menuEl.classList.add("blur-enabled") : this.menuEl.classList.remove("blur-enabled"));
1033
+ }
1034
+ open(e, t) {
1035
+ if (this.menuEl || this.createMenuDOM(), !this.menuEl) return;
1036
+ let n = this.radius(), r = e === void 0 ? window.innerWidth / 2 : e, i = t === void 0 ? window.innerHeight / 2 : t, a = Math.max(n + 12, Math.min(window.innerWidth - n - 12, r)), o = Math.max(n + 12, Math.min(window.innerHeight - n - 12, i));
1037
+ this.coords.set({
1038
+ x: a,
1039
+ y: o
1040
+ }), this.navigationStack.set([]), this.activeHoverItem.set(null), this.isOpen.set(!0), this._openedAt = Date.now(), this.menuEl.style.left = `${a - n}px`, this.menuEl.style.top = `${o - n}px`, this.menuEl.style.width = `${n * 2}px`, this.menuEl.style.height = `${n * 2}px`, this.menuEl.style.display = "block", this.enableBlur() ? this.menuEl.classList.add("blur-enabled") : this.menuEl.classList.remove("blur-enabled"), this.menuEl.offsetHeight, this.menuEl.classList.add("active"), this.renderSegments("in"), this.updateCenterButton(), this.onOpen?.(), this.emitEvent("menu-open", {
1041
+ x: a,
1042
+ y: o
1043
+ });
1044
+ }
1045
+ close() {
1046
+ this.menuEl && (this.isOpen.set(!1), this.activeHoverItem.set(null), this.menuEl.classList.remove("active"), this.onClose?.(), this.emitEvent("menu-close", {}), setTimeout(() => {
1047
+ !this.isOpen() && this.menuEl && !this.menuEl.classList.contains("active") && (this.menuEl.style.display = "none");
1048
+ }, 300));
1049
+ }
1050
+ navigateTo(e) {
1051
+ e.children && e.children.length > 0 && (this.navigationStack.update((t) => [...t, e]), this.activeHoverItem.set(null), this.renderSegments("in"), this.updateCenterButton(), this.onNavigate?.(e, this.navigationStack().length), this.emitEvent("menu-navigate", {
1052
+ item: e,
1053
+ depth: this.navigationStack().length
1054
+ }));
1055
+ }
1056
+ goBack() {
1057
+ if (this.navigationStack().length > 0) {
1058
+ this.navigationStack.update((e) => e.slice(0, -1)), this.activeHoverItem.set(null), this.renderSegments("out"), this.updateCenterButton();
1059
+ let e = this.navigationStack().length > 0 ? this.navigationStack()[this.navigationStack().length - 1] : null;
1060
+ this.onNavigate?.(e, this.navigationStack().length), this.emitEvent("menu-back", {
1061
+ current: e,
1062
+ depth: this.navigationStack().length
1063
+ });
1064
+ } else this.close();
1065
+ }
1066
+ updateCenterButton() {
1067
+ if (!this.centerBtnEl) return;
1068
+ let e = this.centerBtnEl.querySelector(".center-icon");
1069
+ if (e && (e.textContent = this.centerIcon, this.activeHoverItem() ? e.style.opacity = "0" : e.style.opacity = "1"), this.titlePopEl) {
1070
+ let e = this.centerTitle;
1071
+ this.titlePopEl.textContent = e, this.activeHoverItem() ? this.titlePopEl.classList.add("visible") : this.titlePopEl.classList.remove("visible");
1072
+ }
1073
+ }
1074
+ renderSegments(e = "in") {
1075
+ if (!this.menuEl) return;
1076
+ let t = this.itemsContainerEl, n = document.createElement("div");
1077
+ n.className = "items-container entering", e === "out" && (n.className = "items-container exiting");
1078
+ let r = this.currentItems, i = r.length;
1079
+ if (i > 0) {
1080
+ let e = 360 / i;
1081
+ r.forEach((t, r) => {
1082
+ let i = this.createSegmentElement(t, r, e);
1083
+ n.appendChild(i);
1084
+ });
1085
+ }
1086
+ this.centerBtnEl ? this.menuEl.insertBefore(n, this.centerBtnEl) : this.menuEl.appendChild(n), this.itemsContainerEl = n, requestAnimationFrame(() => {
1087
+ t && (t.classList.add(e === "in" ? "exiting" : "entering"), t.classList.remove("active"), setTimeout(() => {
1088
+ t.parentNode && t.parentNode.removeChild(t);
1089
+ }, 400)), n.classList.remove("entering", "exiting"), n.classList.add("active");
1090
+ });
1091
+ }
1092
+ createSegmentElement(e, t, n) {
1093
+ let r = t * n - 90, i = (t + 1) * n - 90, a = r + n / 2, o = document.createElement("div");
1094
+ o.className = "menu-segment", e.children && e.children.length > 0 && o.classList.add("has-children"), o.style.zIndex = `${t + 1}`;
1095
+ let s = 49.5, c = .5, l = [];
1096
+ for (let e = r; e <= i; e += c) l.push(this.getPoint(e, s));
1097
+ l.push(this.getPoint(i, s));
1098
+ for (let e = i; e >= r; e -= c) l.push(this.getPoint(e, 26));
1099
+ l.push(this.getPoint(r, 26));
1100
+ let u = `polygon(${l.map((e) => `${e.x.toFixed(4)}% ${e.y.toFixed(4)}%`).join(", ")})`;
1101
+ o.style.clipPath = u, o.style.webkitClipPath = u;
1102
+ let d = document.createElement("div");
1103
+ d.className = "segment-glass", o.appendChild(d);
1104
+ let f = document.createElement("div");
1105
+ f.className = "segment-shine", o.appendChild(f);
1106
+ let p = document.createElement("span");
1107
+ p.className = "segment-label";
1108
+ let m = this.getPoint(a, 38.5);
1109
+ if (p.style.left = `${m.x.toFixed(2)}%`, p.style.top = `${m.y.toFixed(2)}%`, e.image && typeof e.image == "string") {
1110
+ let t = e.image.trim();
1111
+ if (t.startsWith("<svg")) p.innerHTML = t;
1112
+ else if (t.endsWith(".svg") || t.startsWith("data:image/svg") || t.startsWith("/") || t.startsWith("./") || t.startsWith("http")) {
1113
+ let n = document.createElement("img");
1114
+ n.src = t, n.className = "segment-icon", n.alt = e.name, p.appendChild(n);
1115
+ } else p.textContent = t;
1116
+ } else p.textContent = e.name;
1117
+ if (o.appendChild(p), e.children && e.children.length > 0) {
1118
+ let e = document.createElement("div");
1119
+ e.className = "submenu-indicator";
1120
+ let t = this.getPoint(a, 47.2);
1121
+ e.style.left = `${t.x.toFixed(2)}%`, e.style.top = `${t.y.toFixed(2)}%`, o.appendChild(e);
1122
+ }
1123
+ return o.addEventListener("click", (t) => {
1124
+ t.stopPropagation(), e.children && e.children.length > 0 ? this.navigateTo(e) : (this.onSelectItem?.(e), this.emitEvent("item-selected", { item: e }), this.close());
1125
+ }), o.addEventListener("mouseenter", () => {
1126
+ this.activeHoverItem.set(e), this.onHover?.(e), this.emitEvent("menu-hover", { item: e }), this.updateCenterButton();
1127
+ }), o.addEventListener("mouseleave", () => {
1128
+ this.activeHoverItem.set(null), this.onHover?.(null), this.emitEvent("menu-hover", { item: null }), this.updateCenterButton();
1129
+ }), o;
1130
+ }
1131
+ onDocumentContextMenu(e) {
1132
+ let t = this.selector();
1133
+ t && e.target?.closest?.(t) && (e.preventDefault(), e.stopPropagation(), this.open(e.clientX, e.clientY));
1134
+ }
1135
+ onDocumentClick(e) {
1136
+ if (this.isOpen() && !(Date.now() - this._openedAt < 150)) {
1137
+ if (this.menuEl) {
1138
+ if ((e.composedPath ? e.composedPath() : []).includes(this.menuEl)) return;
1139
+ let t = e.target;
1140
+ if (t && typeof this.menuEl.contains == "function" && this.menuEl.contains(t)) return;
1141
+ }
1142
+ this.close();
1143
+ }
1144
+ }
1145
+ onDocumentKeydown(e) {
1146
+ e.key === "Escape" && this.isOpen() && (this.navigationStack().length > 0 ? this.goBack() : this.close());
1147
+ }
1148
+ emitEvent(e, t) {
1149
+ this?.dispatchEvent?.(new CustomEvent(e, {
1150
+ detail: t,
1151
+ bubbles: !0,
1152
+ composed: !0
1153
+ }));
1154
+ }
1155
+ };
1156
+ r({
1157
+ selector: "radial-context-menu",
1158
+ templateUrl: "./src/app/shared/components/radial-context-menu/radial-context-menu.component.html",
1159
+ template: M
1160
+ })(N);
1161
+ //#endregion
1162
+ //#region src/app/shared/components/expander/expander.component.html?raw
1163
+ var P = "<slot></slot>\n", F = class {
1164
+ isExpanded = f(!1);
1165
+ hostEl = null;
1166
+ titleEl = null;
1167
+ cleanupEffect;
1168
+ handleTitleClick = (e) => {
1169
+ e.target?.closest("a, button, input, textarea, select") || this.toggle();
1170
+ };
1171
+ handleTitleKeydown = (e) => {
1172
+ (e.key === " " || e.key === "Enter") && (e.preventDefault(), this.toggle());
1173
+ };
1174
+ initOnHost(e) {
1175
+ this.hostEl = e;
1176
+ let t = e.getAttribute("is-expanded"), n = e.getAttribute("expanded");
1177
+ (t !== null && t !== "false" && t !== "null" && t !== "0" || n !== null && n !== "false" && n !== "null" && n !== "0") && this.isExpanded.set(!0);
1178
+ let r = e.getAttribute("title");
1179
+ this.titleEl = e.querySelector(".title"), !this.titleEl && r && (this.titleEl = document.createElement("div"), this.titleEl.className = "title", this.titleEl.textContent = r, e.insertBefore(this.titleEl, e.firstChild)), this.titleEl && (this.titleEl.hasAttribute("role") || this.titleEl.setAttribute("role", "button"), this.titleEl.hasAttribute("tabindex") || this.titleEl.setAttribute("tabindex", "0"), this.titleEl.addEventListener("click", this.handleTitleClick), this.titleEl.addEventListener("keydown", this.handleTitleKeydown));
1180
+ let i = e.querySelector(".body");
1181
+ i && !i.hasAttribute("role") && i.setAttribute("role", "region"), this.cleanupEffect = l(() => {
1182
+ let t = this.isExpanded();
1183
+ e.classList.toggle("is-expanded", t), e.classList.toggle("is-collapsed", !t), e.setAttribute("aria-expanded", String(t));
1184
+ let n = e.querySelector(".body");
1185
+ n && (n.style.display = t ? "block" : "none", n.setAttribute("aria-hidden", String(!t)), n.classList.toggle("is-expanded", t), n.classList.toggle("is-collapsed", !t));
1186
+ let r = e.querySelector(".title");
1187
+ r && r.setAttribute("aria-expanded", String(t));
1188
+ }), e !== this && (e.toggle = () => this.toggle(), e.expand = () => this.expand(), e.collapse = () => this.collapse(), e.isExpanded = this.isExpanded, e.expandOrCollapseIcon = () => this.expandOrCollapseIcon());
1189
+ }
1190
+ onInit() {
1191
+ let e = this;
1192
+ e && typeof e.querySelector == "function" && this.initOnHost(e);
1193
+ }
1194
+ destroy() {
1195
+ this.titleEl &&= (this.titleEl.removeEventListener("click", this.handleTitleClick), this.titleEl.removeEventListener("keydown", this.handleTitleKeydown), null), this.cleanupEffect &&= (this.cleanupEffect(), void 0), this.hostEl = null;
1196
+ }
1197
+ onDestroy() {
1198
+ this.destroy();
1199
+ }
1200
+ toggle() {
1201
+ this.isExpanded.update((e) => !e), this.dispatchToggleEvent();
1202
+ }
1203
+ expand() {
1204
+ this.isExpanded() || (this.isExpanded.set(!0), this.dispatchToggleEvent());
1205
+ }
1206
+ collapse() {
1207
+ this.isExpanded() && (this.isExpanded.set(!1), this.dispatchToggleEvent());
1208
+ }
1209
+ expandOrCollapseIcon() {
1210
+ return this.isExpanded() ? "icon-collapse" : "icon-expand";
1211
+ }
1212
+ dispatchToggleEvent() {
1213
+ let e = this.hostEl || this;
1214
+ e && typeof e.dispatchEvent == "function" && e.dispatchEvent(new CustomEvent("change", {
1215
+ detail: { isExpanded: this.isExpanded() },
1216
+ bubbles: !0,
1217
+ composed: !0
1218
+ }));
1219
+ }
1220
+ };
1221
+ r({
1222
+ selector: "expander",
1223
+ templateUrl: "./expander.component.html",
1224
+ template: P
1225
+ })(F);
1226
+ //#endregion
1227
+ //#region src/app/shared/components/navigation-menu/navigation-menu.component.html?raw
1228
+ var I = "<div id=\"nav-ball\" class=\"nav-ball-container\" aria-label=\"Floating Navigation Menu\">\n <!-- Hover Drag Handle -->\n <div class=\"nav-drag-handle\" title=\"Drag to reposition navigation ball\">\n <svg class=\"drag-grip-icon\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\"></circle>\n <circle cx=\"15\" cy=\"6\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"12\" r=\"1.5\"></circle>\n <circle cx=\"15\" cy=\"12\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"18\" r=\"1.5\"></circle>\n <circle cx=\"15\" cy=\"18\" r=\"1.5\"></circle>\n </svg>\n <span class=\"handle-text\">DRAG</span>\n </div>\n\n <!-- Interactive Navigation Ball -->\n <button\n type=\"button\"\n class=\"nav-ball-orb\"\n id=\"nav-ball-trigger\"\n title=\"Open Navigation Menu\"\n onclick=\"onOrbClick(event)\"\n aria-haspopup=\"menu\"\n aria-expanded=\"{{isOpen()}}\"\n >\n <span class=\"orb-shine\"></span>\n <span class=\"orb-glow\"></span>\n <span class=\"orb-icon\">🧭</span>\n </button>\n</div>\n\n<!-- Integrated Radial Context Menu -->\n<radial-context-menu id=\"nav-radial-menu\"></radial-context-menu>\n", L = class {
1229
+ currentTheme = f("dark");
1230
+ isDark = f(!0);
1231
+ constructor() {
1232
+ this.applyInitialTheme();
1233
+ }
1234
+ applyInitialTheme() {
1235
+ if (typeof window > "u") return;
1236
+ let e = null;
1237
+ try {
1238
+ e = window.localStorage?.getItem("purity-theme");
1239
+ } catch {}
1240
+ let t = e === "light" ? "light" : "dark";
1241
+ this.applyTheme(t, !!e);
1242
+ }
1243
+ setTheme(e) {
1244
+ this.applyTheme(e, !0);
1245
+ }
1246
+ toggleTheme() {
1247
+ let e = this.currentTheme() === "dark" ? "light" : "dark";
1248
+ this.setTheme(e);
1249
+ }
1250
+ applyTheme(e, t = !0) {
1251
+ if (this.currentTheme.set(e), this.isDark.set(e === "dark"), t) try {
1252
+ window.localStorage?.setItem("purity-theme", e);
1253
+ } catch {}
1254
+ typeof document < "u" && (document.documentElement.setAttribute("data-theme", e), document.body?.setAttribute("data-theme", e));
1255
+ }
1256
+ };
1257
+ a("ThemeService")(L);
1258
+ //#endregion
1259
+ //#region src/app/shared/behaviors/droppable/droppable.ts
1260
+ var R = /* @__PURE__ */ new Set();
1261
+ function z(e) {
1262
+ let t = u(e.selector);
1263
+ if (!t) return console.warn(`Droppable behavior: Element "${e.selector}" not found.`), { destroy: () => {} };
1264
+ let n = {
1265
+ element: t,
1266
+ options: e
1267
+ };
1268
+ return R.add(n), { destroy: () => {
1269
+ R.delete(n);
1270
+ } };
1271
+ }
1272
+ function B(e, t, n) {
1273
+ for (let r of R) {
1274
+ if (!r.element || !r.element.isConnected || r.element === n) continue;
1275
+ let i = r.element.getBoundingClientRect();
1276
+ if (e >= i.left && e <= i.right && t >= i.top && t <= i.bottom && V(r.options, n)) return r;
1277
+ }
1278
+ return null;
1279
+ }
1280
+ function V(e, t) {
1281
+ return !e.accepts || t.matches(e.accepts);
1282
+ }
1283
+ //#endregion
1284
+ //#region src/app/shared/behaviors/draggable/draggable.ts
1285
+ function H(e) {
1286
+ let t = u(e.selector);
1287
+ if (!t) return console.warn(`Drag behavior: Element with selector "${e.selector}" not found.`), { destroy: () => {} };
1288
+ let n = !1, r = 0, i = 0, a = 0, o = 0, s = 0, c = 0, l = 0, d = 0, f = 0, p = 0, m = 0, h = 0, g = null, _ = null, v = null, y = () => {
1289
+ let e = window.getComputedStyle(t);
1290
+ if (!e.transform || e.transform === "none") return {
1291
+ x: 0,
1292
+ y: 0
1293
+ };
1294
+ try {
1295
+ let t = new DOMMatrix(e.transform);
1296
+ return {
1297
+ x: t.m41,
1298
+ y: t.m42
1299
+ };
1300
+ } catch {
1301
+ return {
1302
+ x: 0,
1303
+ y: 0
1304
+ };
1305
+ }
1306
+ }, b = (n) => {
1307
+ if (n.button !== 0) return;
1308
+ let r = n.target;
1309
+ if (r.closest("button, input, textarea, a, select")) return;
1310
+ if (e.handle) {
1311
+ if (_ = r.closest(e.handle), !_ || !t.contains(_) && _ !== t) {
1312
+ _ = null;
1313
+ return;
1314
+ }
1315
+ } else _ = t;
1316
+ s = n.clientX, c = n.clientY;
1317
+ let { x: i, y: l } = y();
1318
+ a = i, o = l;
1319
+ }, x = (y) => {
1320
+ if (!_ && !n) return;
1321
+ if (!n) {
1322
+ let u = Math.abs(y.clientX - s), g = Math.abs(y.clientY - c);
1323
+ if (u > 3 || g > 3) {
1324
+ n = !0, r = s, i = c;
1325
+ try {
1326
+ t.setPointerCapture(y.pointerId);
1327
+ } catch {}
1328
+ t.classList.add("is-dragging");
1329
+ let u = t.getBoundingClientRect();
1330
+ l = u.left - a, d = u.top - o, f = u.width, p = u.height, m = window.scrollX, h = window.scrollY, e.onDragStart?.(t);
1331
+ } else return;
1332
+ }
1333
+ let b = a + (y.clientX - r), x = o + (y.clientY - i), S = window.scrollX - m, C = window.scrollY - h, w = l - S, T = d - C, E = B(y.clientX, y.clientY, t);
1334
+ if (E !== g) {
1335
+ if (g) {
1336
+ let e = g.options.hoverClass || "droppable-hover";
1337
+ g.element.classList.remove(e), g.options.onLeave?.(t);
1338
+ }
1339
+ if (E) {
1340
+ let e = E.options.hoverClass || "droppable-hover";
1341
+ E.element.classList.add(e), E.options.onEnter?.(t);
1342
+ }
1343
+ g = E;
1344
+ }
1345
+ if (e.snapTo && g?.element.matches(e.snapTo)) {
1346
+ let e = g.element.getBoundingClientRect(), n = e.left + e.width / 2, r = e.top + e.height / 2, i = w + f / 2, a = T + p / 2;
1347
+ b = n - i, x = r - a, t.classList.add("snap-hit");
1348
+ } else t.classList.remove("snap-hit");
1349
+ let D = e.constrainTo ? e.constrainTo === "parent" ? t.parentElement : u(e.constrainTo) || t.closest(e.constrainTo) : null;
1350
+ if (D && D !== document.body) {
1351
+ let e = D.getBoundingClientRect(), t = e.left - w, n = e.right - (w + f), r = e.top - T, i = e.bottom - (T + p);
1352
+ t <= n && (b = Math.max(t, Math.min(n, b))), r <= i && (x = Math.max(r, Math.min(i, x)));
1353
+ }
1354
+ e.onDragMove?.(t, b, x), v && cancelAnimationFrame(v), v = requestAnimationFrame(() => {
1355
+ t.style.transform = `translate3d(${b}px, ${x}px, 0px)`, v = null;
1356
+ });
1357
+ }, S = (r) => {
1358
+ if (!n) {
1359
+ _ = null;
1360
+ return;
1361
+ }
1362
+ if (v &&= (cancelAnimationFrame(v), null), e.onDragEnd?.(t), n = !1, t.hasPointerCapture(r.pointerId)) try {
1363
+ t.releasePointerCapture(r.pointerId);
1364
+ } catch {}
1365
+ if (g) {
1366
+ let e = g.options.hoverClass || "droppable-hover";
1367
+ g.element.classList.remove(e), g.options.onDrop?.(t), g = null;
1368
+ }
1369
+ t.classList.remove("is-dragging", "snap-hit"), _ = null;
1370
+ };
1371
+ return t.addEventListener("pointerdown", b), t.addEventListener("pointermove", x), t.addEventListener("pointerup", S), t.addEventListener("pointercancel", S), t.classList.add("draggable-target"), { destroy: () => {
1372
+ n = !1, v && cancelAnimationFrame(v), t.removeEventListener("pointerdown", b), t.removeEventListener("pointermove", x), t.removeEventListener("pointerup", S), t.removeEventListener("pointercancel", S), t.classList.remove("draggable-target", "is-dragging", "snap-hit");
1373
+ } };
1374
+ }
1375
+ //#endregion
1376
+ //#region \0@oxc-project+runtime@0.146.0/helpers/esm/decorate.js
1377
+ function U(e, t, n, r) {
1378
+ var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
1379
+ if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
1380
+ else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
1381
+ return i > 3 && a && Object.defineProperty(t, n, a), a;
1382
+ }
1383
+ //#endregion
1384
+ //#region src/app/shared/components/navigation-menu/navigation-menu.component.ts
1385
+ var W = class {
1386
+ themeService = d(L);
1387
+ isOpen = f(!1);
1388
+ radialMenu;
1389
+ navBallEl;
1390
+ dragInstance;
1391
+ wasDragged = !1;
1392
+ onInit() {
1393
+ this.initMenu(), this.initDrag();
1394
+ }
1395
+ onDestroy() {
1396
+ this.dragInstance?.destroy();
1397
+ }
1398
+ disconnectedCallback() {
1399
+ this.onDestroy();
1400
+ }
1401
+ initDrag() {
1402
+ this.dragInstance = H({
1403
+ selector: "#nav-ball",
1404
+ handle: "#nav-ball",
1405
+ onDragStart: () => {
1406
+ this.wasDragged = !0, this.radialMenu?.close();
1407
+ },
1408
+ onDragEnd: () => {
1409
+ setTimeout(() => {
1410
+ this.wasDragged = !1;
1411
+ }, 100);
1412
+ }
1413
+ });
1414
+ }
1415
+ initMenu() {
1416
+ let e = [
1417
+ {
1418
+ name: "Core",
1419
+ image: "⚡",
1420
+ children: [
1421
+ {
1422
+ name: "Signal Router",
1423
+ image: "🗺️",
1424
+ data: { hash: "#router-sample" }
1425
+ },
1426
+ {
1427
+ name: "Conditionals (if)",
1428
+ image: "🔀",
1429
+ data: { hash: "#if-sample" }
1430
+ },
1431
+ {
1432
+ name: "Array Repeater",
1433
+ image: "🔁",
1434
+ data: { hash: "#for-sample" }
1435
+ },
1436
+ {
1437
+ name: "Virtual Scroll (100k)",
1438
+ image: "⚡",
1439
+ data: { hash: "#virtual-for-sample" }
1440
+ },
1441
+ {
1442
+ name: "Transform Pipes",
1443
+ image: "🏷️",
1444
+ data: { hash: "#pipe-sample" }
1445
+ },
1446
+ {
1447
+ name: "DOM Directives",
1448
+ image: "🎯",
1449
+ data: { hash: "#directive-sample" }
1450
+ },
1451
+ {
1452
+ name: "Form Validation",
1453
+ image: "📋",
1454
+ data: { hash: "#forms-validation" }
1455
+ },
1456
+ {
1457
+ name: "HTTP Client",
1458
+ image: "🌐",
1459
+ data: { hash: "#http-sample" }
1460
+ }
1461
+ ]
1462
+ },
1463
+ {
1464
+ name: "UI Components",
1465
+ image: "🧩",
1466
+ children: [
1467
+ {
1468
+ name: "Expander",
1469
+ image: "↕️",
1470
+ data: { hash: "#expander-sample" }
1471
+ },
1472
+ {
1473
+ name: "Switch Button",
1474
+ image: "🎛️",
1475
+ data: { hash: "#switch-button-sample" }
1476
+ },
1477
+ {
1478
+ name: "Date Time Picker",
1479
+ image: "📅",
1480
+ data: { hash: "#date-time-picker-sample" }
1481
+ },
1482
+ {
1483
+ name: "Modal Dialog",
1484
+ image: "🪟",
1485
+ data: { hash: "#modal-sample" }
1486
+ },
1487
+ {
1488
+ name: "Popover Anchoring",
1489
+ image: "💬",
1490
+ data: { hash: "#popover-sample" }
1491
+ },
1492
+ {
1493
+ name: "Toast Notify",
1494
+ image: "🔔",
1495
+ data: { hash: "#notification-sample" }
1496
+ },
1497
+ {
1498
+ name: "Radial Menu",
1499
+ image: "🔘",
1500
+ data: { hash: "#radial-context-menu-sample" }
1501
+ },
1502
+ {
1503
+ name: "Async Loader",
1504
+ image: "⏳",
1505
+ data: { hash: "#app-loader" }
1506
+ }
1507
+ ]
1508
+ },
1509
+ {
1510
+ name: "Widgets",
1511
+ image: "⏱️",
1512
+ children: [{
1513
+ name: "Analogue Clock",
1514
+ image: "🕒",
1515
+ data: { hash: "#analogue-clock-sample" }
1516
+ }]
1517
+ },
1518
+ {
1519
+ name: "Theme",
1520
+ image: "🎨",
1521
+ children: [
1522
+ {
1523
+ name: "Dark Theme",
1524
+ image: "🌙",
1525
+ data: { theme: "dark" }
1526
+ },
1527
+ {
1528
+ name: "Light Theme",
1529
+ image: "☀️",
1530
+ data: { theme: "light" }
1531
+ },
1532
+ {
1533
+ name: "Toggle Theme",
1534
+ image: "🌓",
1535
+ data: { theme: "toggle" }
1536
+ }
1537
+ ]
1538
+ },
1539
+ {
1540
+ name: "Playground",
1541
+ image: "🎮",
1542
+ data: { hash: "#playground-window" }
1543
+ },
1544
+ {
1545
+ name: "Overview / Intro",
1546
+ image: "🏠",
1547
+ data: { hash: ".intro-component-root" }
1548
+ }
1549
+ ];
1550
+ this.radialMenu ? (this.radialMenu.setItems(e), this.radialMenu.radius.set(155), this.radialMenu.onSelectItem = (e) => this.handleNavigate(e), this.radialMenu.onOpen = () => this.isOpen.set(!0), this.radialMenu.onClose = () => this.isOpen.set(!1)) : setTimeout(() => {
1551
+ this.radialMenu && (this.radialMenu.setItems(e), this.radialMenu.radius.set(155), this.radialMenu.onSelectItem = (e) => this.handleNavigate(e), this.radialMenu.onOpen = () => this.isOpen.set(!0), this.radialMenu.onClose = () => this.isOpen.set(!1));
1552
+ }, 50);
1553
+ }
1554
+ onOrbClick(e) {
1555
+ if (e.stopPropagation(), this.wasDragged || !this.radialMenu) return;
1556
+ if (this.radialMenu.isOpen()) {
1557
+ this.radialMenu.close();
1558
+ return;
1559
+ }
1560
+ let t = this.navBallEl || document.querySelector("#nav-ball"), n = window.innerWidth - 60, r = window.innerHeight - 60;
1561
+ if (t) {
1562
+ let e = t.getBoundingClientRect();
1563
+ n = e.left + e.width / 2, r = e.top + e.height / 2;
1564
+ }
1565
+ this.radialMenu.open(n, r);
1566
+ }
1567
+ handleNavigate(e) {
1568
+ if (e.data?.theme) {
1569
+ e.data.theme === "toggle" ? this.themeService.toggleTheme() : (e.data.theme === "dark" || e.data.theme === "light") && this.themeService.setTheme(e.data.theme);
1570
+ return;
1571
+ }
1572
+ let t = e.data?.hash;
1573
+ if (!t || typeof document > "u") return;
1574
+ let n = document.querySelector("#demo-window");
1575
+ if ((n && n.querySelector(t) || t.includes("sample") || t.includes("forms") || t.includes("app-loader") || t.includes("demo")) && n && (n.classList.remove("demo-hidden"), n.classList.add("demo-visible")), t.startsWith("#")) try {
1576
+ history.pushState(null, "", t);
1577
+ } catch {
1578
+ window.location.hash = t;
1579
+ }
1580
+ setTimeout(() => {
1581
+ let e = document.querySelector(t);
1582
+ e && (e.scrollIntoView({
1583
+ behavior: "smooth",
1584
+ block: "start"
1585
+ }), e.classList.remove("p-nav-highlight"), e.offsetHeight, e.classList.add("p-nav-highlight"), setTimeout(() => {
1586
+ e.classList.remove("p-nav-highlight");
1587
+ }, 1900));
1588
+ }, 120);
1589
+ }
1590
+ };
1591
+ U([c("#nav-radial-menu")], W.prototype, "radialMenu", void 0), U([c("#nav-ball")], W.prototype, "navBallEl", void 0), r({
1592
+ selector: "navigation-menu",
1593
+ templateUrl: "./src/app/shared/components/navigation-menu/navigation-menu.component.html",
1594
+ template: I
1595
+ })(W);
1596
+ //#endregion
1597
+ //#region src/app/shared/widgets/analogue-clock/analogue-clock.component.html?raw
1598
+ var G = "<div class=\"analogue-clock-widget\">\n <!-- Header Bar -->\n <div class=\"clock-header\">\n <div class=\"clock-title-group\">\n <span class=\"clock-icon\">⏱️</span>\n <span class=\"clock-title\">{{title()}}</span>\n <span class=\"clock-badge\">{{smoothSeconds() ? 'Smooth' : 'Quartz'}}</span>\n </div>\n <div class=\"clock-tz-badge\" title=\"Active Timezone\">\n <span class=\"tz-icon\">🌐</span>\n <span class=\"tz-text\">{{timezoneLabel()}}</span>\n </div>\n </div>\n\n <!-- Clock Canvas Stage -->\n <div class=\"clock-stage\">\n <canvas\n id=\"clock-canvas-el\"\n class=\"clock-canvas\"\n title=\"Click to toggle Smooth / Quartz ticking\"\n onclick=\"toggleSweep()\"\n ></canvas>\n </div>\n\n <!-- Digital Readout Display -->\n <div class=\"clock-digital-readout\">\n <span class=\"digital-time\">{{digitalTime()}}</span>\n <span class=\"digital-date\">{{dateString()}}</span>\n </div>\n\n <!-- Interactive Controls Bar -->\n <div class=\"clock-controls\">\n <button\n type=\"button\"\n class=\"button-secondary clock-control-btn {{smoothSeconds() ? 'is-active' : ''}}\"\n onclick=\"toggleSweep()\"\n title=\"Toggle between continuous smooth sweep and precision quartz step\"\n >\n <span>{{smoothSeconds() ? '⚡ Smooth Sweep' : '⏱ Precision Tick'}}</span>\n </button>\n\n <button\n type=\"button\"\n class=\"button-secondary clock-control-btn {{showSeconds() ? 'is-active' : ''}}\"\n onclick=\"toggleSeconds()\"\n title=\"Toggle second hand visibility\"\n >\n <span>{{showSeconds() ? '🔴 Seconds Hand' : '⚪ Hide Seconds'}}</span>\n </button>\n\n <button\n type=\"button\"\n class=\"button-secondary clock-control-btn {{showNumbers() ? 'is-active' : ''}}\"\n onclick=\"toggleNumbers()\"\n title=\"Toggle dial numerals\"\n >\n <span>{{showNumbers() ? '🔢 12/3/6/9 Numerals' : '➖ Minimal Indices'}}</span>\n </button>\n\n <button\n type=\"button\"\n class=\"button-secondary clock-control-btn {{showDateBadge() ? 'is-active' : ''}}\"\n onclick=\"toggleDateBadge()\"\n title=\"Toggle dial date aperture window\"\n >\n <span>{{showDateBadge() ? '📅 Date Aperture' : '🔲 Clean Dial'}}</span>\n </button>\n\n <dropdown label=\"{{timezoneLabel()}}\" class=\"tz-dropdown\">\n <ul>\n <li onclick=\"onTimezoneChange('local')\" class=\"{{timezone() === 'local' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">📍</span>\n <span class=\"item-text\">Local Time</span>\n </li>\n <li onclick=\"onTimezoneChange('UTC')\" class=\"{{timezone() === 'UTC' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🌐</span>\n <span class=\"item-text\">UTC / GMT</span>\n </li>\n <li onclick=\"onTimezoneChange('America/New_York')\" class=\"{{timezone() === 'America/New_York' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🗽</span>\n <span class=\"item-text\">New York (EST/EDT)</span>\n </li>\n <li onclick=\"onTimezoneChange('Europe/London')\" class=\"{{timezone() === 'Europe/London' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🇬🇧</span>\n <span class=\"item-text\">London (GMT/BST)</span>\n </li>\n <li onclick=\"onTimezoneChange('Europe/Paris')\" class=\"{{timezone() === 'Europe/Paris' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🇫🇷</span>\n <span class=\"item-text\">Paris (CET/CEST)</span>\n </li>\n <li onclick=\"onTimezoneChange('Asia/Tokyo')\" class=\"{{timezone() === 'Asia/Tokyo' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🇯🇵</span>\n <span class=\"item-text\">Tokyo (JST)</span>\n </li>\n <li onclick=\"onTimezoneChange('Australia/Sydney')\" class=\"{{timezone() === 'Australia/Sydney' ? 'is-selected' : ''}}\">\n <span class=\"item-icon\">🇦🇺</span>\n <span class=\"item-text\">Sydney (AEST/AEDT)</span>\n </li>\n </ul>\n </dropdown>\n </div>\n</div>\n", K = class {
1599
+ themeService = d(L);
1600
+ canvasEl;
1601
+ size = f(280);
1602
+ title = f("Purity Chrono");
1603
+ timezone = f("local");
1604
+ smoothSeconds = f(!0);
1605
+ showSeconds = f(!0);
1606
+ showNumbers = f(!0);
1607
+ showDateBadge = f(!0);
1608
+ digitalTime = f("00:00:00");
1609
+ dateString = f("");
1610
+ timezoneLabel = f("Local Time");
1611
+ animationFrameId = null;
1612
+ ctx = null;
1613
+ onInit() {
1614
+ let e = this;
1615
+ if (e && typeof e.getAttribute == "function") {
1616
+ let t = e.getAttribute("title");
1617
+ t && this.title.set(t);
1618
+ let n = e.getAttribute("timezone");
1619
+ n && this.timezone.set(n);
1620
+ let r = e.getAttribute("size");
1621
+ if (r) {
1622
+ let e = parseFloat(r);
1623
+ isNaN(e) || this.size.set(e);
1624
+ }
1625
+ let i = e.getAttribute("smooth-seconds");
1626
+ i !== null && this.smoothSeconds.set(i === "true" || i === "");
1627
+ let a = e.getAttribute("show-seconds");
1628
+ a !== null && this.showSeconds.set(a === "true" || a === "");
1629
+ let o = e.getAttribute("show-numbers");
1630
+ o !== null && this.showNumbers.set(o === "true" || o === "");
1631
+ let s = e.getAttribute("show-date-badge");
1632
+ s !== null && this.showDateBadge.set(s === "true" || s === "");
1633
+ }
1634
+ l(() => {
1635
+ this.themeService.isDark(), this.smoothSeconds(), this.showSeconds(), this.showNumbers(), this.showDateBadge(), this.timezone(), this.size(), this.updateLabels(), this.initCanvas();
1636
+ }), this.initCanvas(), this.startClockLoop();
1637
+ }
1638
+ onDestroy() {
1639
+ this.stopClockLoop();
1640
+ }
1641
+ disconnectedCallback() {
1642
+ this.stopClockLoop();
1643
+ }
1644
+ initCanvas() {
1645
+ let e = this?.querySelector?.("canvas") || this.canvasEl || document.querySelector("#clock-canvas-el");
1646
+ if (!e) return;
1647
+ let t = this.size(), n = typeof window < "u" && window.devicePixelRatio || 1;
1648
+ e.width = t * n, e.height = t * n, e.style.width = `${t}px`, e.style.height = `${t}px`, this.ctx = e.getContext("2d"), this.ctx && (this.ctx.setTransform(1, 0, 0, 1, 0, 0), this.ctx.scale(n, n));
1649
+ }
1650
+ startClockLoop() {
1651
+ this.stopClockLoop();
1652
+ let e = () => {
1653
+ this.renderClock(), this.animationFrameId = requestAnimationFrame(e);
1654
+ };
1655
+ this.animationFrameId = requestAnimationFrame(e);
1656
+ }
1657
+ stopClockLoop() {
1658
+ this.animationFrameId !== null && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null);
1659
+ }
1660
+ getTimeData() {
1661
+ let e = /* @__PURE__ */ new Date(), t = e, n = this.timezone();
1662
+ if (n !== "local") try {
1663
+ let r = e.toLocaleString("en-US", { timeZone: n });
1664
+ t = new Date(r);
1665
+ } catch {
1666
+ t = e;
1667
+ }
1668
+ let r = t.getHours(), i = t.getMinutes(), a = t.getSeconds(), o = t.getMilliseconds(), s = `${String(r).padStart(2, "0")}:${String(i).padStart(2, "0")}:${String(a).padStart(2, "0")}`, c = t.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase(), l = t.toLocaleDateString("en-US", { month: "short" }).toUpperCase(), u = t.getDate();
1669
+ return {
1670
+ hours: r,
1671
+ minutes: i,
1672
+ seconds: a,
1673
+ millis: o,
1674
+ digitalStr: s,
1675
+ dateStr: `${c}, ${l} ${u}`,
1676
+ dayName: c,
1677
+ dayNum: u
1678
+ };
1679
+ }
1680
+ updateLabels() {
1681
+ let e = this.timezone();
1682
+ if (e === "local") this.timezoneLabel.set("Local Time");
1683
+ else if (e === "UTC") this.timezoneLabel.set("UTC / GMT");
1684
+ else {
1685
+ let t = e.split("/").pop()?.replace(/_/g, " ") || e;
1686
+ this.timezoneLabel.set(t);
1687
+ }
1688
+ }
1689
+ renderClock() {
1690
+ if (!(this.canvasEl || document.querySelector("#clock-canvas-el")) || !this.ctx && (this.initCanvas(), !this.ctx)) return;
1691
+ let e = this.ctx, t = this.size(), n = t / 2, r = t / 2, i = t * .44, a = this.themeService.isDark(), o = this.getTimeData();
1692
+ this.digitalTime.set(o.digitalStr), this.dateString.set(o.dateStr), e.clearRect(0, 0, t, t), this.drawBezel(e, n, r, i, a), this.drawDialFace(e, n, r, i, a), this.showDateBadge() && this.drawDateAperture(e, n, r, i, o.dayName, o.dayNum, a), this.drawMarkersAndTicks(e, n, r, i, a), this.showNumbers() && this.drawNumerals(e, n, r, i, a), this.drawGlassReflection(e, n, r, i, a);
1693
+ let s = this.smoothSeconds() ? o.seconds + o.millis / 1e3 : o.seconds, c = o.minutes + s / 60, l = (o.hours % 12 + c / 60) * (Math.PI / 6) - Math.PI / 2, u = Math.PI / 30 * c - Math.PI / 2, d = Math.PI / 30 * s - Math.PI / 2;
1694
+ this.drawHourHand(e, n, r, i, l, a), this.drawMinuteHand(e, n, r, i, u, a), this.showSeconds() && this.drawSecondHand(e, n, r, i, d, a), this.drawCenterPivot(e, n, r, t, a);
1695
+ }
1696
+ drawBezel(e, t, n, r, i) {
1697
+ let a = r + r * .14;
1698
+ e.save(), e.beginPath(), e.arc(t, n, a, 0, Math.PI * 2), e.shadowColor = i ? "rgba(0, 0, 0, 0.65)" : "rgba(0, 0, 0, 0.18)", e.shadowBlur = i ? 28 : 18, e.shadowOffsetX = 0, e.shadowOffsetY = i ? 12 : 8, e.fillStyle = i ? "#1a1d26" : "#e6ebf2", e.fill(), e.shadowColor = "transparent";
1699
+ let o = e.createLinearGradient(t - a, n - a, t + a, n + a);
1700
+ i ? (o.addColorStop(0, "rgba(85, 95, 115, 0.9)"), o.addColorStop(.25, "rgba(40, 45, 58, 0.95)"), o.addColorStop(.5, "rgba(75, 85, 105, 0.85)"), o.addColorStop(.75, "rgba(30, 34, 44, 0.98)"), o.addColorStop(1, "rgba(95, 108, 130, 0.9)")) : (o.addColorStop(0, "rgba(255, 255, 255, 0.98)"), o.addColorStop(.25, "rgba(215, 222, 232, 0.95)"), o.addColorStop(.5, "rgba(245, 248, 252, 0.98)"), o.addColorStop(.75, "rgba(205, 214, 226, 0.95)"), o.addColorStop(1, "rgba(255, 255, 255, 0.98)")), e.beginPath(), e.arc(t, n, a, 0, Math.PI * 2), e.fillStyle = o, e.fill(), e.beginPath(), e.arc(t, n, a, 0, Math.PI * 2), e.strokeStyle = i ? "rgba(255, 255, 255, 0.22)" : "rgba(255, 255, 255, 0.9)", e.lineWidth = 1.5, e.stroke(), e.beginPath(), e.arc(t, n, r + 1, 0, Math.PI * 2), e.strokeStyle = i ? "rgba(0, 0, 0, 0.7)" : "rgba(0, 0, 0, 0.12)", e.lineWidth = 1.5, e.stroke(), e.restore();
1701
+ }
1702
+ drawDialFace(e, t, n, r, i) {
1703
+ e.save();
1704
+ let a = e.createRadialGradient(t, n * .9, r * .1, t, n, r);
1705
+ i ? (a.addColorStop(0, "rgba(34, 38, 52, 0.96)"), a.addColorStop(.65, "rgba(22, 25, 36, 0.98)"), a.addColorStop(1, "rgba(14, 16, 24, 1.0)")) : (a.addColorStop(0, "rgba(255, 255, 255, 0.98)"), a.addColorStop(.65, "rgba(244, 247, 252, 0.96)"), a.addColorStop(1, "rgba(230, 236, 246, 0.98)")), e.beginPath(), e.arc(t, n, r, 0, Math.PI * 2), e.fillStyle = a, e.fill(), e.beginPath(), e.arc(t, n, r - .5, 0, Math.PI * 2), e.strokeStyle = i ? "rgba(0, 0, 0, 0.45)" : "rgba(0, 0, 0, 0.08)", e.lineWidth = 2, e.stroke(), e.beginPath(), e.arc(t, n, r * .83, 0, Math.PI * 2), e.strokeStyle = i ? "rgba(255, 255, 255, 0.06)" : "rgba(0, 0, 0, 0.05)", e.lineWidth = 1, e.stroke(), e.beginPath(), e.arc(t, n, r * .54, 0, Math.PI * 2), e.strokeStyle = i ? "rgba(255, 255, 255, 0.035)" : "rgba(0, 0, 0, 0.035)", e.lineWidth = 1, e.stroke(), e.textAlign = "center", e.textBaseline = "middle", e.font = "700 9px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif", e.fillStyle = i ? "rgba(255, 255, 255, 0.35)" : "rgba(0, 0, 0, 0.38)", e.letterSpacing = "2px", e.fillText("PURITY", t, n - r * .34), e.font = "500 7px \"Adwaita Mono\", monospace", e.fillStyle = i ? "rgba(53, 132, 228, 0.75)" : "rgba(28, 113, 216, 0.85)", e.fillText("AUTOMATIC", t, n - r * .24), e.restore();
1706
+ }
1707
+ drawDateAperture(e, t, n, r, i, a, o) {
1708
+ e.save();
1709
+ let s = r * .44, c = r * .16, l = t + r * .28, u = n - c / 2;
1710
+ e.beginPath(), e.roundRect(l, u, s, c, 4), e.fillStyle = o ? "rgba(16, 18, 26, 0.95)" : "rgba(255, 255, 255, 0.98)", e.fill(), e.strokeStyle = o ? "rgba(255, 255, 255, 0.14)" : "rgba(0, 0, 0, 0.14)", e.lineWidth = 1, e.stroke();
1711
+ let d = l + s * .48;
1712
+ e.beginPath(), e.moveTo(d, u + 2), e.lineTo(d, u + c - 2), e.strokeStyle = o ? "rgba(255, 255, 255, 0.08)" : "rgba(0, 0, 0, 0.08)", e.stroke(), e.textAlign = "center", e.textBaseline = "middle", e.font = "700 8.5px \"Adwaita Mono\", monospace", e.fillStyle = o ? "#3584e4" : "#1c71d8", e.fillText(i, l + s * .24, n), e.font = "700 10px \"Adwaita Mono\", monospace", e.fillStyle = o ? "#ffffff" : "#1c1c1c", e.fillText(String(a).padStart(2, "0"), l + s * .74, n), e.restore();
1713
+ }
1714
+ drawMarkersAndTicks(e, t, n, r, i) {
1715
+ e.save();
1716
+ for (let a = 0; a < 60; a++) {
1717
+ let o = Math.PI / 30 * a - Math.PI / 2, s = Math.cos(o), c = Math.sin(o);
1718
+ if (a % 5 == 0) {
1719
+ let o = a % 15 == 0, l = o ? r * .78 : r * .81, u = r * .93, d = o ? 3.5 : 2.5, f = t + l * s, p = n + l * c, m = t + u * s, h = n + u * c;
1720
+ if (e.beginPath(), e.moveTo(f, p), e.lineTo(m, h), e.lineWidth = d, e.lineCap = "round", o ? (e.strokeStyle = i ? "#ffffff" : "#1c1c1c", e.shadowColor = i ? "rgba(53, 132, 228, 0.6)" : "rgba(28, 113, 216, 0.3)", e.shadowBlur = 4) : (e.strokeStyle = i ? "rgba(255, 255, 255, 0.85)" : "rgba(40, 45, 55, 0.85)", e.shadowBlur = 0), e.stroke(), o) {
1721
+ let a = r * .74, o = t + a * s, l = n + a * c;
1722
+ e.beginPath(), e.arc(o, l, 2, 0, Math.PI * 2), e.fillStyle = i ? "#3584e4" : "#1c71d8", e.fill();
1723
+ }
1724
+ } else {
1725
+ let a = r * .88, o = r * .93, l = t + a * s, u = n + a * c, d = t + o * s, f = n + o * c;
1726
+ e.beginPath(), e.moveTo(l, u), e.lineTo(d, f), e.lineWidth = 1, e.lineCap = "butt", e.strokeStyle = i ? "rgba(255, 255, 255, 0.28)" : "rgba(0, 0, 0, 0.24)", e.shadowBlur = 0, e.stroke();
1727
+ }
1728
+ }
1729
+ e.restore();
1730
+ }
1731
+ drawNumerals(e, t, n, r, i) {
1732
+ e.save(), e.textAlign = "center", e.textBaseline = "middle", e.font = "700 13px \"Adwaita Mono\", -apple-system, monospace", e.fillStyle = i ? "rgba(255, 255, 255, 0.9)" : "#1c1c1c";
1733
+ let a = r * .67;
1734
+ e.fillText("12", t, n - a), e.fillText("6", t, n + a), e.fillText("9", t - a, n), this.showDateBadge() || e.fillText("3", t + a, n), e.restore();
1735
+ }
1736
+ drawGlassReflection(e, t, n, r, i) {
1737
+ e.save(), e.beginPath(), e.arc(t, n, r - 1, 0, Math.PI * 2), e.clip();
1738
+ let a = e.createLinearGradient(t - r, n - r, t + r, n + r * .2);
1739
+ i ? (a.addColorStop(0, "rgba(255, 255, 255, 0.16)"), a.addColorStop(.35, "rgba(255, 255, 255, 0.05)"), a.addColorStop(.7, "rgba(255, 255, 255, 0.0)")) : (a.addColorStop(0, "rgba(255, 255, 255, 0.55)"), a.addColorStop(.35, "rgba(255, 255, 255, 0.2)"), a.addColorStop(.7, "rgba(255, 255, 255, 0.0)")), e.beginPath(), e.ellipse(t, n - r * .22, r * .92, r * .65, -.2, 0, Math.PI * 2), e.fillStyle = a, e.fill();
1740
+ let o = e.createRadialGradient(t, n + r * .9, r * .05, t, n + r * .9, r * .45);
1741
+ o.addColorStop(0, i ? "rgba(53, 132, 228, 0.12)" : "rgba(255, 255, 255, 0.4)"), o.addColorStop(1, "rgba(255, 255, 255, 0.0)"), e.beginPath(), e.arc(t, n, r, 0, Math.PI * 2), e.fillStyle = o, e.fill(), e.restore();
1742
+ }
1743
+ drawHourHand(e, t, n, r, i, a) {
1744
+ e.save(), e.translate(t, n), e.rotate(i);
1745
+ let o = r * .52, s = r * .09, c = r * .12;
1746
+ e.shadowColor = a ? "rgba(0, 0, 0, 0.65)" : "rgba(0, 0, 0, 0.25)", e.shadowBlur = 8, e.shadowOffsetX = 3, e.shadowOffsetY = 4, e.beginPath(), e.moveTo(-c, 0), e.lineTo(0, -s / 2), e.lineTo(o, 0), e.closePath(), e.fillStyle = a ? "#ffffff" : "#282e38", e.fill(), e.beginPath(), e.moveTo(-c, 0), e.lineTo(0, s / 2), e.lineTo(o, 0), e.closePath(), e.fillStyle = a ? "#98a2b5" : "#4b5563", e.fill(), e.restore();
1747
+ }
1748
+ drawMinuteHand(e, t, n, r, i, a) {
1749
+ e.save(), e.translate(t, n), e.rotate(i);
1750
+ let o = r * .76, s = r * .07, c = r * .14;
1751
+ e.shadowColor = a ? "rgba(0, 0, 0, 0.65)" : "rgba(0, 0, 0, 0.25)", e.shadowBlur = 10, e.shadowOffsetX = 3, e.shadowOffsetY = 5, e.beginPath(), e.moveTo(-c, 0), e.lineTo(0, -s / 2), e.lineTo(o, 0), e.closePath(), e.fillStyle = a ? "#ffffff" : "#282e38", e.fill(), e.beginPath(), e.moveTo(-c, 0), e.lineTo(0, s / 2), e.lineTo(o, 0), e.closePath(), e.fillStyle = a ? "#8a94a6" : "#475366", e.fill(), e.restore();
1752
+ }
1753
+ drawSecondHand(e, t, n, r, i, a) {
1754
+ e.save(), e.translate(t, n), e.rotate(i);
1755
+ let o = r * .86, s = r * .22, c = a ? "#3584e4" : "#1c71d8";
1756
+ e.shadowColor = a ? "rgba(0, 0, 0, 0.55)" : "rgba(0, 0, 0, 0.2)", e.shadowBlur = 6, e.shadowOffsetX = 2, e.shadowOffsetY = 3, e.beginPath(), e.moveTo(-s, 0), e.lineTo(o, 0), e.strokeStyle = c, e.lineWidth = 1.5, e.lineCap = "round", e.stroke(), e.beginPath(), e.arc(-s * .55, 0, 4.5, 0, Math.PI * 2), e.fillStyle = c, e.fill(), e.beginPath(), e.arc(-s * .55, 0, 2.2, 0, Math.PI * 2), e.fillStyle = a ? "#141620" : "#ffffff", e.fill(), e.beginPath(), e.arc(o - 4, 0, 2.5, 0, Math.PI * 2), e.fillStyle = a ? "#78aeed" : "#3584e4", e.shadowColor = c, e.shadowBlur = 8, e.fill(), e.restore();
1757
+ }
1758
+ drawCenterPivot(e, t, n, r, i) {
1759
+ e.save();
1760
+ let a = r * .038, o = r * .024, s = r * .012;
1761
+ e.beginPath(), e.arc(t, n, a, 0, Math.PI * 2), e.shadowColor = "rgba(0, 0, 0, 0.5)", e.shadowBlur = 6, e.fillStyle = i ? "#2e3442" : "#cbd5e1", e.fill(), e.strokeStyle = i ? "rgba(255, 255, 255, 0.4)" : "rgba(0, 0, 0, 0.15)", e.lineWidth = 1, e.stroke(), e.shadowColor = "transparent";
1762
+ let c = e.createLinearGradient(t - o, n - o, t + o, n + o);
1763
+ i ? (c.addColorStop(0, "#ffffff"), c.addColorStop(.5, "#7b879c"), c.addColorStop(1, "#2b313d")) : (c.addColorStop(0, "#ffffff"), c.addColorStop(.5, "#e2e8f0"), c.addColorStop(1, "#94a3b8")), e.beginPath(), e.arc(t, n, o, 0, Math.PI * 2), e.fillStyle = c, e.fill(), e.beginPath(), e.arc(t, n, s, 0, Math.PI * 2), e.fillStyle = i ? "#3584e4" : "#1c71d8", e.shadowColor = i ? "#3584e4" : "#1c71d8", e.shadowBlur = 4, e.fill(), e.restore();
1764
+ }
1765
+ toggleSweep() {
1766
+ this.smoothSeconds.update((e) => !e);
1767
+ }
1768
+ toggleSeconds() {
1769
+ this.showSeconds.update((e) => !e);
1770
+ }
1771
+ toggleNumbers() {
1772
+ this.showNumbers.update((e) => !e);
1773
+ }
1774
+ toggleDateBadge() {
1775
+ this.showDateBadge.update((e) => !e);
1776
+ }
1777
+ onTimezoneChange(e) {
1778
+ this.timezone.set(e || "local"), this.updateLabels();
1779
+ }
1780
+ };
1781
+ U([c("#clock-canvas-el")], K.prototype, "canvasEl", void 0), r({
1782
+ selector: "analogue-clock",
1783
+ templateUrl: "./src/app/shared/widgets/analogue-clock/analogue-clock.component.html",
1784
+ template: G
1785
+ })(K);
1786
+ //#endregion
1787
+ //#region src/app/shared/interceptors/auth.interceptor.ts
1788
+ var q = class {
1789
+ token = "purity_jwt_sample_token";
1790
+ setToken(e) {
1791
+ this.token = e;
1792
+ }
1793
+ async intercept(e, t) {
1794
+ return e.headers.has("Authorization") ? t(e) : t(e.clone({ headers: e.headers.set("Authorization", `Bearer ${this.token}`) }));
1795
+ }
1796
+ }, J = class {
1797
+ async intercept(e, t) {
1798
+ let n = performance.now(), r = (/* @__PURE__ */ new Date()).toLocaleTimeString();
1799
+ console.log(`%c[HTTP Request] ${r} %c${e.method} %c${e.url}`, "color: #9a9996;", "color: #3584e4; font-weight: bold;", "color: var(--text-main, #ffffff);");
1800
+ try {
1801
+ let i = await t(e), a = Math.round(performance.now() - n);
1802
+ return console.log(`%c[HTTP Response] ${r} %c${e.method} ${e.url} %c-> ${i.status} ${i.statusText} (${a}ms)`, "color: #9a9996;", "color: #2ec27e; font-weight: bold;", "color: #2ec27e;"), i;
1803
+ } catch (t) {
1804
+ let i = Math.round(performance.now() - n);
1805
+ throw console.error(`%c[HTTP Error] ${r} %c${e.method} ${e.url} %cfailed (${t.status || "Network"}) in ${i}ms:`, "color: #9a9996;", "color: #e01b24; font-weight: bold;", "color: #e01b24;", t), t;
1806
+ }
1807
+ }
1808
+ }, Y = [
1809
+ "Jan",
1810
+ "Feb",
1811
+ "Mar",
1812
+ "Apr",
1813
+ "May",
1814
+ "Jun",
1815
+ "Jul",
1816
+ "Aug",
1817
+ "Sep",
1818
+ "Oct",
1819
+ "Nov",
1820
+ "Dec"
1821
+ ], ee = [
1822
+ "January",
1823
+ "February",
1824
+ "March",
1825
+ "April",
1826
+ "May",
1827
+ "June",
1828
+ "July",
1829
+ "August",
1830
+ "September",
1831
+ "October",
1832
+ "November",
1833
+ "December"
1834
+ ], te = [
1835
+ "Sun",
1836
+ "Mon",
1837
+ "Tue",
1838
+ "Wed",
1839
+ "Thu",
1840
+ "Fri",
1841
+ "Sat"
1842
+ ], ne = [
1843
+ "Sunday",
1844
+ "Monday",
1845
+ "Tuesday",
1846
+ "Wednesday",
1847
+ "Thursday",
1848
+ "Friday",
1849
+ "Saturday"
1850
+ ], re = {
1851
+ short: "M/d/yy, h:mm a",
1852
+ medium: "MMM d, yyyy, h:mm:ss a",
1853
+ long: "MMMM d, yyyy, h:mm:ss a",
1854
+ full: "EEEE, MMMM d, yyyy, h:mm:ss a",
1855
+ shortDate: "M/d/yy",
1856
+ mediumDate: "MMM d, yyyy",
1857
+ longDate: "MMMM d, yyyy",
1858
+ fullDate: "EEEE, MMMM d, yyyy",
1859
+ shortTime: "h:mm a",
1860
+ mediumTime: "h:mm:ss a"
1861
+ }, X = class extends t {
1862
+ transform(e, t = "mediumDate") {
1863
+ if (e == null || e === "") return "";
1864
+ let n;
1865
+ if (e instanceof Date) n = e;
1866
+ else if (typeof e == "number" || typeof e == "string") n = new Date(e);
1867
+ else return "";
1868
+ if (isNaN(n.getTime())) return "";
1869
+ let r = re[t] || t;
1870
+ return this.formatDate(n, r);
1871
+ }
1872
+ formatDate(e, t) {
1873
+ let n = e.getFullYear(), r = e.getMonth(), i = e.getDate(), a = e.getDay(), o = e.getHours(), s = o % 12 || 12, c = e.getMinutes(), l = e.getSeconds(), u = o >= 12 ? "PM" : "AM", d = (e, t = 2) => String(e).padStart(t, "0");
1874
+ return t.replace(/(EEEE|EEE|yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|a)/g, (e) => {
1875
+ switch (e) {
1876
+ case "EEEE": return ne[a];
1877
+ case "EEE": return te[a];
1878
+ case "yyyy": return String(n);
1879
+ case "yy": return String(n).slice(-2);
1880
+ case "MMMM": return ee[r];
1881
+ case "MMM": return Y[r];
1882
+ case "MM": return d(r + 1);
1883
+ case "M": return String(r + 1);
1884
+ case "dd": return d(i);
1885
+ case "d": return String(i);
1886
+ case "HH": return d(o);
1887
+ case "H": return String(o);
1888
+ case "hh": return d(s);
1889
+ case "h": return String(s);
1890
+ case "mm": return d(c);
1891
+ case "m": return String(c);
1892
+ case "ss": return d(l);
1893
+ case "s": return String(l);
1894
+ case "a": return u;
1895
+ default: return e;
1896
+ }
1897
+ });
1898
+ }
1899
+ };
1900
+ o("date")(X);
1901
+ //#endregion
1902
+ //#region src/app/shared/pipes/transform-sample.pipe.ts
1903
+ var Z = class extends t {
1904
+ transform(e, t = !1, n) {
1905
+ if (e == null) return "";
1906
+ let r = String(e);
1907
+ return t && (r = r.toUpperCase()), n ? `${n}: ${r}` : r;
1908
+ }
1909
+ };
1910
+ o("myTransformPipe")(Z);
1911
+ //#endregion
1912
+ //#region src/app/shared/pipes/uppercase.pipe.ts
1913
+ var Q = class extends t {
1914
+ transform(e) {
1915
+ return e == null ? "" : String(e).toUpperCase();
1916
+ }
1917
+ };
1918
+ o("uppercase")(Q);
1919
+ //#endregion
1920
+ //#region src/app/shared/validators/forms-validation.validator.ts
1921
+ var $ = class extends n {
1922
+ validateInput1(e) {
1923
+ return e.trim().length >= 3;
1924
+ }
1925
+ validateInput2(e) {
1926
+ return e.trim().length >= 5;
1927
+ }
1928
+ };
1929
+ s({
1930
+ form: ".forms-validation-form",
1931
+ fields: {
1932
+ input1: "#input1",
1933
+ input2: "#input2"
1934
+ },
1935
+ validClass: "is-valid",
1936
+ invalidClass: "is-invalid"
1937
+ })($);
1938
+ //#endregion
1939
+ export { K as AnalogueClockComponent, q as AuthInterceptor, X as DatePipe, S as DateTimePickerComponent, h as DropDownDirective, h as DropdownComponent, h as DropdownDirective, F as ExpanderComponent, $ as FormsValidationValidator, g as HighlightDirective, O as LoaderComponent, J as LoggingInterceptor, b as ModalViewComponent, Z as MyTransformPipe, Z as TransformSamplePipe, W as NavigationMenuComponent, E as NotificationComponent, w as NotifyService, A as PopoverComponent, j as PopoverDirective, N as RadialContextMenuComponent, v as SwitchButtonComponent, L as ThemeService, Q as UppercasePipe, H as drag, H as draggable, z as droppable, B as findDropTarget };