web-mojo 2.1.1044 → 2.1.1087

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 (86) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.cjs.js.map +1 -1
  3. package/dist/admin.es.js +14 -14
  4. package/dist/admin.es.js.map +1 -1
  5. package/dist/auth.cjs.js +1 -1
  6. package/dist/auth.es.js +1 -1
  7. package/dist/charts.cjs.js +1 -1
  8. package/dist/charts.cjs.js.map +1 -1
  9. package/dist/charts.css +319 -0
  10. package/dist/charts.es.js +555 -3
  11. package/dist/charts.es.js.map +1 -1
  12. package/dist/chunks/{ChatView-Bvkdj-lq.js → ChatView-BnC15uoD.js} +2 -2
  13. package/dist/chunks/{ChatView-Bvkdj-lq.js.map → ChatView-BnC15uoD.js.map} +1 -1
  14. package/dist/chunks/{ChatView-DBgQzOyI.js → ChatView-D-5lHZ5H.js} +7 -7
  15. package/dist/chunks/{ChatView-DBgQzOyI.js.map → ChatView-D-5lHZ5H.js.map} +1 -1
  16. package/dist/chunks/{Collection-DD1_31eh.js → Collection-B64LJ92k.js} +2 -2
  17. package/dist/chunks/{Collection-DD1_31eh.js.map → Collection-B64LJ92k.js.map} +1 -1
  18. package/dist/chunks/{Collection-DaTm-2LH.js → Collection-CsAk0UhA.js} +2 -2
  19. package/dist/chunks/{Collection-DaTm-2LH.js.map → Collection-CsAk0UhA.js.map} +1 -1
  20. package/dist/chunks/{ContextMenu-snx9Dd1s.js → ContextMenu-CfMAB33c.js} +2 -2
  21. package/dist/chunks/{ContextMenu-snx9Dd1s.js.map → ContextMenu-CfMAB33c.js.map} +1 -1
  22. package/dist/chunks/{ContextMenu-hQH_6Pyi.js → ContextMenu-Cvls3QC_.js} +3 -3
  23. package/dist/chunks/{ContextMenu-hQH_6Pyi.js.map → ContextMenu-Cvls3QC_.js.map} +1 -1
  24. package/dist/chunks/{DataView-D7j4IWyS.js → DataView-DESqBxT-.js} +2 -2
  25. package/dist/chunks/{DataView-D7j4IWyS.js.map → DataView-DESqBxT-.js.map} +1 -1
  26. package/dist/chunks/{DataView-CWejLV3B.js → DataView-QXyfcg2M.js} +2 -2
  27. package/dist/chunks/{DataView-CWejLV3B.js.map → DataView-QXyfcg2M.js.map} +1 -1
  28. package/dist/chunks/Dialog-BfXN-fFA.js +2 -0
  29. package/dist/chunks/Dialog-BfXN-fFA.js.map +1 -0
  30. package/dist/chunks/{Dialog-BcJG5Vta.js → Dialog-DHUsZ92-.js} +20 -6
  31. package/dist/chunks/Dialog-DHUsZ92-.js.map +1 -0
  32. package/dist/chunks/{FormView-BClEkzmE.js → FormView-DGRmcKUG.js} +282 -123
  33. package/dist/chunks/FormView-DGRmcKUG.js.map +1 -0
  34. package/dist/chunks/FormView-KGvr68ju.js +3 -0
  35. package/dist/chunks/FormView-KGvr68ju.js.map +1 -0
  36. package/dist/chunks/{ListView-BrsQ26R6.js → ListView-BGJG4GYH.js} +3 -3
  37. package/dist/chunks/{ListView-BrsQ26R6.js.map → ListView-BGJG4GYH.js.map} +1 -1
  38. package/dist/chunks/{ListView-BRGiITfD.js → ListView-BpGEatee.js} +2 -2
  39. package/dist/chunks/{ListView-BRGiITfD.js.map → ListView-BpGEatee.js.map} +1 -1
  40. package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js → MetricsMiniChartWidget-BKbFGvXG.js} +4 -4
  41. package/dist/chunks/{MetricsMiniChartWidget-DALWxrzu.js.map → MetricsMiniChartWidget-BKbFGvXG.js.map} +1 -1
  42. package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js → MetricsMiniChartWidget-BNdGuSZV.js} +2 -2
  43. package/dist/chunks/{MetricsMiniChartWidget-CN1HPnWf.js.map → MetricsMiniChartWidget-BNdGuSZV.js.map} +1 -1
  44. package/dist/chunks/{PDFViewer-CgdSGU1n.js → PDFViewer-BIBNhuWY.js} +3 -3
  45. package/dist/chunks/{PDFViewer-CgdSGU1n.js.map → PDFViewer-BIBNhuWY.js.map} +1 -1
  46. package/dist/chunks/{PDFViewer-DtJIlPXi.js → PDFViewer-nZAQQScE.js} +2 -2
  47. package/dist/chunks/{PDFViewer-DtJIlPXi.js.map → PDFViewer-nZAQQScE.js.map} +1 -1
  48. package/dist/chunks/Rest-BpDyhFfG.js +2 -0
  49. package/dist/chunks/Rest-BpDyhFfG.js.map +1 -0
  50. package/dist/chunks/{Rest-CS4jRCAs.js → Rest-DpbPbmra.js} +96 -5
  51. package/dist/chunks/Rest-DpbPbmra.js.map +1 -0
  52. package/dist/chunks/{TokenManager-DIEFCQ3B.js → TokenManager-BWc_pRpg.js} +2 -2
  53. package/dist/chunks/{TokenManager-DIEFCQ3B.js.map → TokenManager-BWc_pRpg.js.map} +1 -1
  54. package/dist/chunks/{TokenManager-BanwFrq7.js → TokenManager-N3e5wDu1.js} +5 -5
  55. package/dist/chunks/{TokenManager-BanwFrq7.js.map → TokenManager-N3e5wDu1.js.map} +1 -1
  56. package/dist/chunks/{WebSocketClient-D-5DJoMX.js → WebSocketClient-DghNkEyO.js} +2 -2
  57. package/dist/chunks/{WebSocketClient-D-5DJoMX.js.map → WebSocketClient-DghNkEyO.js.map} +1 -1
  58. package/dist/chunks/{WebSocketClient-DzcqAmho.js → WebSocketClient-E08hfP5f.js} +2 -2
  59. package/dist/chunks/{WebSocketClient-DzcqAmho.js.map → WebSocketClient-E08hfP5f.js.map} +1 -1
  60. package/dist/chunks/{version-WMgX72-y.js → version-CKPqwcQJ.js} +2 -2
  61. package/dist/chunks/{version-WMgX72-y.js.map → version-CKPqwcQJ.js.map} +1 -1
  62. package/dist/chunks/{version-BaFu2yii.js → version-Dtwh-YkD.js} +4 -4
  63. package/dist/chunks/{version-BaFu2yii.js.map → version-Dtwh-YkD.js.map} +1 -1
  64. package/dist/css/web-mojo.css +1 -1
  65. package/dist/docit.cjs.js +1 -1
  66. package/dist/docit.es.js +6 -6
  67. package/dist/index.cjs.js +1 -1
  68. package/dist/index.es.js +15 -15
  69. package/dist/lightbox.cjs.js +1 -1
  70. package/dist/lightbox.es.js +5 -5
  71. package/dist/map.cjs.js +1 -1
  72. package/dist/map.cjs.js.map +1 -1
  73. package/dist/map.es.js +82 -3
  74. package/dist/map.es.js.map +1 -1
  75. package/dist/timeline.cjs.js +1 -1
  76. package/dist/timeline.es.js +4 -4
  77. package/package.json +1 -1
  78. package/dist/chunks/Dialog-7T8ENHYD.js +0 -2
  79. package/dist/chunks/Dialog-7T8ENHYD.js.map +0 -1
  80. package/dist/chunks/Dialog-BcJG5Vta.js.map +0 -1
  81. package/dist/chunks/FormView-BClEkzmE.js.map +0 -1
  82. package/dist/chunks/FormView-nulck4nL.js +0 -3
  83. package/dist/chunks/FormView-nulck4nL.js.map +0 -1
  84. package/dist/chunks/Rest-BNYqGlnP.js +0 -2
  85. package/dist/chunks/Rest-BNYqGlnP.js.map +0 -1
  86. package/dist/chunks/Rest-CS4jRCAs.js.map +0 -1
package/dist/charts.es.js CHANGED
@@ -1,9 +1,561 @@
1
- import { B, M, b, c, a, P, S } from "./chunks/MetricsMiniChartWidget-DALWxrzu.js";
2
- import { W } from "./chunks/Dialog-BcJG5Vta.js";
3
- import { B as B2, a as a2, V, b as b2, c as c2, d } from "./chunks/version-BaFu2yii.js";
1
+ import { B, M, b, c, a, P, S } from "./chunks/MetricsMiniChartWidget-BKbFGvXG.js";
2
+ import { V as View, d as dataFormatter } from "./chunks/Rest-DpbPbmra.js";
3
+ import { W } from "./chunks/Dialog-DHUsZ92-.js";
4
+ import { B as B2, a as a2, V, b as b2, c as c2, d } from "./chunks/version-Dtwh-YkD.js";
5
+ class CircularProgress extends View {
6
+ constructor(options = {}) {
7
+ super({
8
+ className: `circular-progress ${options.className || ""}`,
9
+ ...options
10
+ });
11
+ this.SIZE_PRESETS = {
12
+ "xs": 40,
13
+ "sm": 60,
14
+ "md": 80,
15
+ "lg": 120,
16
+ "xl": 180
17
+ };
18
+ this.STROKE_PRESETS = {
19
+ "xs": 4,
20
+ "sm": 6,
21
+ "md": 8,
22
+ "lg": 12,
23
+ "xl": 16
24
+ };
25
+ this.value = options.value !== void 0 ? options.value : 0;
26
+ this.min = options.min !== void 0 ? options.min : 0;
27
+ this.max = options.max !== void 0 ? options.max : 100;
28
+ this.sizePreset = typeof options.size === "string" && this.SIZE_PRESETS[options.size] ? options.size : null;
29
+ this.size = this.resolveSize(options.size !== void 0 ? options.size : "md");
30
+ this.strokeWidth = options.strokeWidth === "auto" || options.strokeWidth === void 0 ? this.getAutoStrokeWidth(options.size) : options.strokeWidth;
31
+ this.theme = options.theme || "basic";
32
+ this.variant = options.variant || "default";
33
+ this.color = options.color;
34
+ this.trackColor = options.trackColor;
35
+ this.textColor = options.textColor;
36
+ this.gradientColors = options.gradientColors || null;
37
+ this.applyTheme();
38
+ this.applyVariant();
39
+ this.rotation = options.rotation !== void 0 ? options.rotation : -90;
40
+ this.gap = options.gap || 0;
41
+ this.showValue = options.showValue !== false;
42
+ this.valueFormat = options.valueFormat || "percentage";
43
+ this.valueFormatter = options.valueFormatter || null;
44
+ this.label = options.label || null;
45
+ this.labelHtml = options.labelHtml || null;
46
+ this.icon = options.icon || null;
47
+ this.animate = options.animate !== false;
48
+ this.animationDuration = options.animationDuration || 600;
49
+ this.animationEasing = options.animationEasing || "ease-out";
50
+ this.rounded = options.rounded !== false;
51
+ this.shadow = options.shadow || false;
52
+ this.clickable = options.clickable || false;
53
+ this.tooltip = options.tooltip || null;
54
+ this.tooltipPlacement = options.tooltipPlacement || "top";
55
+ this.segments = options.segments || null;
56
+ this.segmentGap = options.segmentGap || 2;
57
+ this.dataFormatter = dataFormatter;
58
+ this.svg = null;
59
+ this.centerElement = null;
60
+ this.popover = null;
61
+ this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;
62
+ }
63
+ resolveSize(size) {
64
+ if (typeof size === "string" && this.SIZE_PRESETS[size]) {
65
+ return this.SIZE_PRESETS[size];
66
+ }
67
+ return typeof size === "number" ? size : this.SIZE_PRESETS.md;
68
+ }
69
+ getAutoStrokeWidth(size) {
70
+ if (typeof size === "string" && this.STROKE_PRESETS[size]) {
71
+ return this.STROKE_PRESETS[size];
72
+ }
73
+ const actualSize = this.resolveSize(size);
74
+ if (actualSize <= 40) return 4;
75
+ if (actualSize <= 60) return 6;
76
+ if (actualSize <= 80) return 8;
77
+ if (actualSize <= 120) return 12;
78
+ return 16;
79
+ }
80
+ applyTheme() {
81
+ const themes = {
82
+ "basic": {
83
+ trackColor: "#e9ecef",
84
+ textColor: null,
85
+ // Use default
86
+ backgroundColor: null
87
+ },
88
+ "shadowed": {
89
+ trackColor: "#d1d5db",
90
+ textColor: null,
91
+ backgroundColor: null,
92
+ shadow: true
93
+ },
94
+ "dark": {
95
+ trackColor: "#374151",
96
+ textColor: "#e5e7eb",
97
+ backgroundColor: "#1f2937"
98
+ },
99
+ "light": {
100
+ trackColor: "#f3f4f6",
101
+ textColor: "#111827",
102
+ backgroundColor: "#ffffff"
103
+ }
104
+ };
105
+ const themeConfig = themes[this.theme] || themes.basic;
106
+ if (!this.trackColor) {
107
+ this.trackColor = themeConfig.trackColor;
108
+ }
109
+ if (!this.textColor && themeConfig.textColor) {
110
+ this.textColor = themeConfig.textColor;
111
+ }
112
+ if (themeConfig.shadow && this.shadow === false) {
113
+ this.shadow = themeConfig.shadow;
114
+ }
115
+ }
116
+ applyVariant() {
117
+ const variants = {
118
+ "success": { color: "#198754", trackColor: "rgba(25, 135, 84, 0.1)" },
119
+ "danger": { color: "#dc3545", trackColor: "rgba(220, 53, 69, 0.1)" },
120
+ "warning": { color: "#ffc107", trackColor: "rgba(255, 193, 7, 0.1)" },
121
+ "info": { color: "#0dcaf0", trackColor: "rgba(13, 202, 240, 0.1)" },
122
+ "default": { color: "#0d6efd" }
123
+ // Default blue color
124
+ };
125
+ if (variants[this.variant]) {
126
+ const variantColors = variants[this.variant];
127
+ if (!this.color) {
128
+ this.color = variantColors.color;
129
+ }
130
+ if (variantColors.trackColor && this.trackColor === this.applyTheme.trackColor) {
131
+ this.trackColor = variantColors.trackColor;
132
+ }
133
+ }
134
+ if (!this.color) {
135
+ this.color = "#0d6efd";
136
+ }
137
+ }
138
+ getTemplate() {
139
+ const sizeClass = this.sizePreset ? `circular-progress-${this.sizePreset}` : "";
140
+ const variantClass = this.variant !== "default" ? `circular-progress-${this.variant}` : "";
141
+ const themeClass = this.theme !== "basic" ? `circular-progress-theme-${this.theme}` : "";
142
+ const clickableClass = this.clickable ? "circular-progress-clickable" : "";
143
+ const shadowClass = this.shadow ? "circular-progress-shadow" : "";
144
+ const textColorStyle = this.textColor ? `color: ${this.textColor};` : "";
145
+ return `
146
+ <div class="circular-progress-container ${sizeClass} ${variantClass} ${themeClass} ${clickableClass} ${shadowClass}"
147
+ style="width: ${this.size}px; height: ${this.size}px;">
148
+ <svg class="circular-progress-svg"
149
+ width="${this.size}"
150
+ height="${this.size}"
151
+ viewBox="0 0 ${this.size} ${this.size}">
152
+ </svg>
153
+ <div class="circular-progress-center" style="${textColorStyle}">
154
+ <div class="circular-progress-content"></div>
155
+ </div>
156
+ </div>
157
+ `;
158
+ }
159
+ async onAfterRender() {
160
+ this.svg = this.element.querySelector(".circular-progress-svg");
161
+ this.centerElement = this.element.querySelector(".circular-progress-content");
162
+ this.containerElement = this.element.querySelector(".circular-progress-container");
163
+ this.renderProgress();
164
+ this.renderCenterContent();
165
+ if (this.clickable) {
166
+ this.setupClickHandler();
167
+ }
168
+ if (this.tooltip && this.clickable) {
169
+ this.setupTooltip();
170
+ }
171
+ }
172
+ renderProgress() {
173
+ if (!this.svg) return;
174
+ this.svg.innerHTML = "";
175
+ const center = this.size / 2;
176
+ const radius = (this.size - this.strokeWidth) / 2;
177
+ const circumference = 2 * Math.PI * radius;
178
+ if (this.gradientColors && this.gradientColors.length > 1) {
179
+ this.createGradient();
180
+ }
181
+ if (this.segments && Array.isArray(this.segments) && this.segments.length > 0) {
182
+ this.renderSegments(center, radius, circumference);
183
+ } else {
184
+ this.renderSingleProgress(center, radius, circumference);
185
+ }
186
+ }
187
+ renderSingleProgress(center, radius, circumference) {
188
+ const arcLength = this.gap > 0 ? 360 - this.gap : 360;
189
+ const arcCircumference = arcLength / 360 * circumference;
190
+ const track = this.createCircle(center, radius, {
191
+ stroke: this.trackColor,
192
+ strokeWidth: this.strokeWidth,
193
+ fill: "none",
194
+ strokeLinecap: this.rounded ? "round" : "butt",
195
+ strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : "none",
196
+ transform: `rotate(${this.rotation} ${center} ${center})`
197
+ });
198
+ this.svg.appendChild(track);
199
+ const percentage = this.getPercentage();
200
+ const progressLength = percentage / 100 * arcCircumference;
201
+ const dashOffset = arcCircumference - progressLength;
202
+ const strokeColor = this.gradientColors ? `url(#${this.gradientId})` : this.color;
203
+ const progress = this.createCircle(center, radius, {
204
+ stroke: strokeColor,
205
+ strokeWidth: this.strokeWidth,
206
+ fill: "none",
207
+ strokeLinecap: this.rounded ? "round" : "butt",
208
+ strokeDasharray: `${arcCircumference} ${circumference}`,
209
+ strokeDashoffset: this.animate ? arcCircumference : dashOffset,
210
+ transform: `rotate(${this.rotation} ${center} ${center})`,
211
+ class: "circular-progress-bar"
212
+ });
213
+ this.svg.appendChild(progress);
214
+ if (this.animate) {
215
+ this.animateProgress(progress, dashOffset);
216
+ }
217
+ }
218
+ renderSegments(center, radius, circumference) {
219
+ const arcLength = this.gap > 0 ? 360 - this.gap : 360;
220
+ const arcCircumference = arcLength / 360 * circumference;
221
+ const track = this.createCircle(center, radius, {
222
+ stroke: this.trackColor,
223
+ strokeWidth: this.strokeWidth,
224
+ fill: "none",
225
+ strokeLinecap: this.rounded ? "round" : "butt",
226
+ strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : "none",
227
+ transform: `rotate(${this.rotation} ${center} ${center})`
228
+ });
229
+ this.svg.appendChild(track);
230
+ const total = this.segments.reduce((sum, seg) => sum + (seg.value || 0), 0);
231
+ if (total > this.max) {
232
+ console.warn("CircularProgress: Segment total exceeds max value. Clamping to max.");
233
+ }
234
+ let currentOffset = 0;
235
+ this.segments.forEach((segment, index) => {
236
+ const segmentPercentage = (segment.value || 0) / (this.max - this.min) * 100;
237
+ const segmentLength = segmentPercentage / 100 * arcCircumference;
238
+ const gapLength = this.segmentGap / 360 * circumference;
239
+ if (segmentLength > 0) {
240
+ const segmentCircle = this.createCircle(center, radius, {
241
+ stroke: segment.color || this.color,
242
+ strokeWidth: this.strokeWidth,
243
+ fill: "none",
244
+ strokeLinecap: this.rounded ? "round" : "butt",
245
+ strokeDasharray: `${segmentLength} ${circumference}`,
246
+ strokeDashoffset: this.animate ? arcCircumference : -currentOffset,
247
+ transform: `rotate(${this.rotation} ${center} ${center})`,
248
+ class: `circular-progress-segment circular-progress-segment-${index}`,
249
+ "data-segment-index": index
250
+ });
251
+ this.svg.appendChild(segmentCircle);
252
+ if (this.animate) {
253
+ this.animateProgress(segmentCircle, -currentOffset, index * 100);
254
+ }
255
+ currentOffset += segmentLength + gapLength;
256
+ }
257
+ });
258
+ }
259
+ createCircle(cx, cy, attributes = {}) {
260
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
261
+ circle.setAttribute("cx", cx);
262
+ circle.setAttribute("cy", cx);
263
+ circle.setAttribute("r", cy);
264
+ Object.entries(attributes).forEach(([key, value]) => {
265
+ if (key === "strokeWidth") {
266
+ circle.setAttribute("stroke-width", value);
267
+ } else if (key === "strokeLinecap") {
268
+ circle.setAttribute("stroke-linecap", value);
269
+ } else if (key === "strokeDasharray") {
270
+ circle.setAttribute("stroke-dasharray", value);
271
+ } else if (key === "strokeDashoffset") {
272
+ circle.setAttribute("stroke-dashoffset", value);
273
+ } else {
274
+ circle.setAttribute(key, value);
275
+ }
276
+ });
277
+ return circle;
278
+ }
279
+ createGradient() {
280
+ const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
281
+ const gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
282
+ gradient.setAttribute("id", this.gradientId);
283
+ gradient.setAttribute("x1", "0%");
284
+ gradient.setAttribute("y1", "0%");
285
+ gradient.setAttribute("x2", "100%");
286
+ gradient.setAttribute("y2", "100%");
287
+ this.gradientColors.forEach((color, index) => {
288
+ const stop = document.createElementNS("http://www.w3.org/2000/svg", "stop");
289
+ const offset = index / (this.gradientColors.length - 1) * 100;
290
+ stop.setAttribute("offset", `${offset}%`);
291
+ stop.setAttribute("stop-color", color);
292
+ gradient.appendChild(stop);
293
+ });
294
+ defs.appendChild(gradient);
295
+ this.svg.appendChild(defs);
296
+ }
297
+ animateProgress(circle, targetOffset, delay = 0) {
298
+ setTimeout(() => {
299
+ circle.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;
300
+ circle.style.strokeDashoffset = targetOffset;
301
+ }, delay);
302
+ }
303
+ renderCenterContent() {
304
+ if (!this.centerElement) return;
305
+ if (this.labelHtml) {
306
+ this.centerElement.innerHTML = this.labelHtml;
307
+ } else if (this.icon) {
308
+ this.centerElement.innerHTML = `<i class="${this.icon}"></i>`;
309
+ } else if (this.showValue) {
310
+ const formattedValue = this.getFormattedValue();
311
+ let html = `<div class="circular-progress-value">${formattedValue}</div>`;
312
+ if (this.label) {
313
+ html += `<div class="circular-progress-label">${this.label}</div>`;
314
+ }
315
+ this.centerElement.innerHTML = html;
316
+ }
317
+ }
318
+ getFormattedValue() {
319
+ const value = this.value;
320
+ const min = this.min;
321
+ const max = this.max;
322
+ if (this.valueFormatter && typeof this.valueFormatter === "function") {
323
+ return this.valueFormatter(value, min, max);
324
+ }
325
+ switch (this.valueFormat) {
326
+ case "percentage":
327
+ return `${Math.round(this.getPercentage())}%`;
328
+ case "fraction":
329
+ return `${value}/${max}`;
330
+ case "value":
331
+ return value.toString();
332
+ default:
333
+ if (this.dataFormatter) {
334
+ try {
335
+ return this.dataFormatter.pipe(value, this.valueFormat);
336
+ } catch (error) {
337
+ console.warn("CircularProgress: DataFormatter error, falling back to percentage", error);
338
+ return `${Math.round(this.getPercentage())}%`;
339
+ }
340
+ }
341
+ return `${Math.round(this.getPercentage())}%`;
342
+ }
343
+ }
344
+ getPercentage() {
345
+ const range = this.max - this.min;
346
+ if (range === 0) return 0;
347
+ return (this.value - this.min) / range * 100;
348
+ }
349
+ setupClickHandler() {
350
+ if (!this.containerElement) return;
351
+ this.containerElement.style.cursor = "pointer";
352
+ this.containerElement.addEventListener("click", (e) => {
353
+ e.preventDefault();
354
+ e.stopPropagation();
355
+ const percentage = this.getPercentage();
356
+ this.emit("progress:clicked", {
357
+ value: this.value,
358
+ percentage,
359
+ min: this.min,
360
+ max: this.max
361
+ });
362
+ if (this.tooltip) {
363
+ this.togglePopover();
364
+ }
365
+ });
366
+ }
367
+ setupTooltip() {
368
+ }
369
+ togglePopover() {
370
+ if (!this.containerElement || typeof window.bootstrap === "undefined") {
371
+ console.warn("CircularProgress: Bootstrap is required for tooltip support");
372
+ return;
373
+ }
374
+ if (!this.popover) {
375
+ const content = this.getTooltipContent();
376
+ const title = typeof this.tooltip === "object" && this.tooltip.title ? this.tooltip.title : void 0;
377
+ const popoverConfig = {
378
+ content,
379
+ html: true,
380
+ placement: this.tooltipPlacement,
381
+ trigger: "manual",
382
+ container: "body"
383
+ };
384
+ if (title) {
385
+ popoverConfig.title = title;
386
+ }
387
+ this.popover = new window.bootstrap.Popover(this.containerElement, popoverConfig);
388
+ }
389
+ const popoverElement = window.bootstrap.Popover.getInstance(this.containerElement);
390
+ if (popoverElement && this.containerElement.getAttribute("aria-describedby")) {
391
+ this.popover.hide();
392
+ } else {
393
+ this.popover.setContent({
394
+ ".popover-body": this.getTooltipContent()
395
+ });
396
+ this.popover.show();
397
+ }
398
+ }
399
+ getTooltipContent() {
400
+ if (typeof this.tooltip === "function") {
401
+ return this.tooltip(this.value, {
402
+ min: this.min,
403
+ max: this.max,
404
+ percentage: this.getPercentage()
405
+ });
406
+ }
407
+ if (typeof this.tooltip === "object") {
408
+ return this.tooltip.html || this.tooltip.content || "";
409
+ }
410
+ return this.tooltip || "";
411
+ }
412
+ // Public API
413
+ setValue(value, animate = true) {
414
+ this.value;
415
+ this.value = Math.max(this.min, Math.min(this.max, value));
416
+ this.renderCenterContent();
417
+ if (this.svg && !this.segments) {
418
+ const progressBar = this.svg.querySelector(".circular-progress-bar");
419
+ if (progressBar) {
420
+ const radius = this.size / 2 - this.strokeWidth / 2;
421
+ const circumference = 2 * Math.PI * radius;
422
+ const arcLength = this.gap > 0 ? 360 - this.gap : 360;
423
+ const arcCircumference = arcLength / 360 * circumference;
424
+ const percentage = this.getPercentage();
425
+ const progressLength = percentage / 100 * arcCircumference;
426
+ const dashOffset = arcCircumference - progressLength;
427
+ if (animate) {
428
+ progressBar.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;
429
+ progressBar.style.strokeDashoffset = dashOffset;
430
+ } else {
431
+ progressBar.style.transition = "none";
432
+ progressBar.style.strokeDashoffset = dashOffset;
433
+ }
434
+ }
435
+ } else {
436
+ const oldAnimate = this.animate;
437
+ this.animate = animate;
438
+ this.renderProgress();
439
+ this.animate = oldAnimate;
440
+ }
441
+ }
442
+ setRange(min, max) {
443
+ this.min = min;
444
+ this.max = max;
445
+ this.renderProgress();
446
+ this.renderCenterContent();
447
+ }
448
+ increment(amount = 1) {
449
+ this.setValue(this.value + amount);
450
+ }
451
+ decrement(amount = 1) {
452
+ this.setValue(this.value - amount);
453
+ }
454
+ setColor(color) {
455
+ this.color = color;
456
+ this.gradientColors = null;
457
+ if (this.svg && !this.segments) {
458
+ const progressBar = this.svg.querySelector(".circular-progress-bar");
459
+ if (progressBar) {
460
+ progressBar.setAttribute("stroke", color);
461
+ }
462
+ } else {
463
+ this.renderProgress();
464
+ }
465
+ }
466
+ setGradient(colors) {
467
+ if (Array.isArray(colors) && colors.length > 1) {
468
+ this.gradientColors = colors;
469
+ this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;
470
+ this.renderProgress();
471
+ }
472
+ }
473
+ setSize(size) {
474
+ if (this.containerElement && this.sizePreset) {
475
+ this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`);
476
+ }
477
+ this.sizePreset = typeof size === "string" && this.SIZE_PRESETS[size] ? size : null;
478
+ this.size = this.resolveSize(size);
479
+ this.strokeWidth = this.getAutoStrokeWidth(size);
480
+ if (this.containerElement) {
481
+ this.containerElement.style.width = `${this.size}px`;
482
+ this.containerElement.style.height = `${this.size}px`;
483
+ if (this.sizePreset) {
484
+ this.containerElement.classList.add(`circular-progress-${this.sizePreset}`);
485
+ }
486
+ }
487
+ if (this.svg) {
488
+ this.svg.setAttribute("width", this.size);
489
+ this.svg.setAttribute("height", this.size);
490
+ this.svg.setAttribute("viewBox", `0 0 ${this.size} ${this.size}`);
491
+ }
492
+ this.renderProgress();
493
+ }
494
+ animateTo(targetValue, duration = 1e3) {
495
+ const startValue = this.value;
496
+ const diff = targetValue - startValue;
497
+ const startTime = performance.now();
498
+ const animate = (currentTime) => {
499
+ const elapsed = currentTime - startTime;
500
+ const progress = Math.min(elapsed / duration, 1);
501
+ const easeProgress = 1 - Math.pow(1 - progress, 3);
502
+ const newValue = startValue + diff * easeProgress;
503
+ this.setValue(newValue, false);
504
+ if (progress < 1) {
505
+ requestAnimationFrame(animate);
506
+ } else {
507
+ this.setValue(targetValue, false);
508
+ }
509
+ };
510
+ requestAnimationFrame(animate);
511
+ }
512
+ pulse() {
513
+ if (!this.containerElement) return;
514
+ this.containerElement.style.animation = "none";
515
+ setTimeout(() => {
516
+ this.containerElement.style.animation = "circular-progress-pulse 0.5s ease-out";
517
+ }, 10);
518
+ setTimeout(() => {
519
+ this.containerElement.style.animation = "";
520
+ }, 500);
521
+ }
522
+ complete() {
523
+ this.variant = "success";
524
+ this.applyVariant();
525
+ this.setValue(this.max);
526
+ this.pulse();
527
+ }
528
+ reset() {
529
+ this.setValue(this.min);
530
+ }
531
+ hide() {
532
+ if (this.element) {
533
+ this.element.style.display = "none";
534
+ }
535
+ }
536
+ show() {
537
+ if (this.element) {
538
+ this.element.style.display = "";
539
+ }
540
+ }
541
+ getValue() {
542
+ return this.value;
543
+ }
544
+ getPercentageValue() {
545
+ return this.getPercentage();
546
+ }
547
+ async onBeforeDestroy() {
548
+ if (this.popover) {
549
+ this.popover.dispose();
550
+ this.popover = null;
551
+ }
552
+ await super.onBeforeDestroy();
553
+ }
554
+ }
4
555
  export {
5
556
  B2 as BUILD_TIME,
6
557
  B as BaseChart,
558
+ CircularProgress,
7
559
  M as MetricsChart,
8
560
  b as MetricsMiniChart,
9
561
  c as MetricsMiniChartWidget,
@@ -1 +1 @@
1
- {"version":3,"file":"charts.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
1
+ {"version":3,"file":"charts.es.js","sources":["../src/extensions/charts/CircularProgress.js"],"sourcesContent":["/**\n * CircularProgress - Modern circular progress indicator component\n * Supports single/multi-segment progress, animations, gradients, and tooltips\n * Uses SVG for crisp rendering at any size\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nexport default class CircularProgress extends View {\n constructor(options = {}) {\n super({\n className: `circular-progress ${options.className || ''}`,\n ...options\n });\n\n // Size presets\n this.SIZE_PRESETS = {\n 'xs': 40,\n 'sm': 60,\n 'md': 80,\n 'lg': 120,\n 'xl': 180\n };\n\n // Stroke width presets (auto-calculated based on size)\n this.STROKE_PRESETS = {\n 'xs': 4,\n 'sm': 6,\n 'md': 8,\n 'lg': 12,\n 'xl': 16\n };\n\n // Core configuration\n this.value = options.value !== undefined ? options.value : 0;\n this.min = options.min !== undefined ? options.min : 0;\n this.max = options.max !== undefined ? options.max : 100;\n\n // Dimensions\n this.sizePreset = (typeof options.size === 'string' && this.SIZE_PRESETS[options.size]) ? options.size : null;\n this.size = this.resolveSize(options.size !== undefined ? options.size : 'md');\n this.strokeWidth = options.strokeWidth === 'auto' || options.strokeWidth === undefined\n ? this.getAutoStrokeWidth(options.size)\n : options.strokeWidth;\n\n // Colors & Styling\n this.theme = options.theme || 'basic'; // 'basic', '3d', 'dark', 'light'\n this.variant = options.variant || 'default';\n this.color = options.color; // Will be set by applyVariant if not provided\n this.trackColor = options.trackColor; // Will be set by applyTheme if not provided\n this.textColor = options.textColor; // Custom text color\n this.gradientColors = options.gradientColors || null;\n\n // Apply theme (sets colors based on theme)\n this.applyTheme();\n \n // Apply variant colors (sets this.color if not provided)\n this.applyVariant();\n\n // Arc configuration\n this.rotation = options.rotation !== undefined ? options.rotation : -90; // Start at top\n this.gap = options.gap || 0; // Gap in degrees (0 = full circle)\n\n // Center content\n this.showValue = options.showValue !== false;\n this.valueFormat = options.valueFormat || 'percentage';\n this.valueFormatter = options.valueFormatter || null;\n this.label = options.label || null;\n this.labelHtml = options.labelHtml || null;\n this.icon = options.icon || null;\n\n // Animation\n this.animate = options.animate !== false;\n this.animationDuration = options.animationDuration || 600;\n this.animationEasing = options.animationEasing || 'ease-out';\n\n // Visual options\n this.rounded = options.rounded !== false;\n this.shadow = options.shadow || false;\n\n // Interaction\n this.clickable = options.clickable || false;\n this.tooltip = options.tooltip || null;\n this.tooltipPlacement = options.tooltipPlacement || 'top';\n\n // Multi-segment mode\n this.segments = options.segments || null;\n this.segmentGap = options.segmentGap || 2; // Gap between segments in degrees\n\n // DataFormatter instance\n this.dataFormatter = dataFormatter;\n\n // Internal state\n this.svg = null;\n this.centerElement = null;\n this.popover = null;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n resolveSize(size) {\n if (typeof size === 'string' && this.SIZE_PRESETS[size]) {\n return this.SIZE_PRESETS[size];\n }\n return typeof size === 'number' ? size : this.SIZE_PRESETS.md;\n }\n\n getAutoStrokeWidth(size) {\n if (typeof size === 'string' && this.STROKE_PRESETS[size]) {\n return this.STROKE_PRESETS[size];\n }\n // Auto-calculate based on size\n const actualSize = this.resolveSize(size);\n if (actualSize <= 40) return 4;\n if (actualSize <= 60) return 6;\n if (actualSize <= 80) return 8;\n if (actualSize <= 120) return 12;\n return 16;\n }\n\n applyTheme() {\n const themes = {\n 'basic': {\n trackColor: '#e9ecef',\n textColor: null, // Use default\n backgroundColor: null\n },\n 'shadowed': {\n trackColor: '#d1d5db',\n textColor: null,\n backgroundColor: null,\n shadow: true\n },\n 'dark': {\n trackColor: '#374151',\n textColor: '#e5e7eb',\n backgroundColor: '#1f2937'\n },\n 'light': {\n trackColor: '#f3f4f6',\n textColor: '#111827',\n backgroundColor: '#ffffff'\n }\n };\n\n const themeConfig = themes[this.theme] || themes.basic;\n \n // Apply theme defaults if not explicitly set\n if (!this.trackColor) {\n this.trackColor = themeConfig.trackColor;\n }\n if (!this.textColor && themeConfig.textColor) {\n this.textColor = themeConfig.textColor;\n }\n if (themeConfig.shadow && this.shadow === false) {\n this.shadow = themeConfig.shadow;\n }\n }\n\n applyVariant() {\n const variants = {\n 'success': { color: '#198754', trackColor: 'rgba(25, 135, 84, 0.1)' },\n 'danger': { color: '#dc3545', trackColor: 'rgba(220, 53, 69, 0.1)' },\n 'warning': { color: '#ffc107', trackColor: 'rgba(255, 193, 7, 0.1)' },\n 'info': { color: '#0dcaf0', trackColor: 'rgba(13, 202, 240, 0.1)' },\n 'default': { color: '#0d6efd' } // Default blue color\n };\n\n if (variants[this.variant]) {\n const variantColors = variants[this.variant];\n if (!this.color) {\n this.color = variantColors.color;\n }\n if (variantColors.trackColor && this.trackColor === this.applyTheme.trackColor) {\n this.trackColor = variantColors.trackColor;\n }\n }\n \n // Fallback if no color is set\n if (!this.color) {\n this.color = '#0d6efd';\n }\n }\n\n getTemplate() {\n const sizeClass = this.sizePreset ? `circular-progress-${this.sizePreset}` : '';\n const variantClass = this.variant !== 'default' ? `circular-progress-${this.variant}` : '';\n const themeClass = this.theme !== 'basic' ? `circular-progress-theme-${this.theme}` : '';\n const clickableClass = this.clickable ? 'circular-progress-clickable' : '';\n const shadowClass = this.shadow ? 'circular-progress-shadow' : '';\n \n const textColorStyle = this.textColor ? `color: ${this.textColor};` : '';\n\n return `\n <div class=\"circular-progress-container ${sizeClass} ${variantClass} ${themeClass} ${clickableClass} ${shadowClass}\"\n style=\"width: ${this.size}px; height: ${this.size}px;\">\n <svg class=\"circular-progress-svg\" \n width=\"${this.size}\" \n height=\"${this.size}\"\n viewBox=\"0 0 ${this.size} ${this.size}\">\n </svg>\n <div class=\"circular-progress-center\" style=\"${textColorStyle}\">\n <div class=\"circular-progress-content\"></div>\n </div>\n </div>\n `;\n }\n\n async onAfterRender() {\n this.svg = this.element.querySelector('.circular-progress-svg');\n this.centerElement = this.element.querySelector('.circular-progress-content');\n this.containerElement = this.element.querySelector('.circular-progress-container');\n\n // Render the progress circle\n this.renderProgress();\n\n // Render center content\n this.renderCenterContent();\n\n // Setup interactions\n if (this.clickable) {\n this.setupClickHandler();\n }\n\n // Setup tooltip\n if (this.tooltip && this.clickable) {\n this.setupTooltip();\n }\n }\n\n renderProgress() {\n if (!this.svg) return;\n\n // Clear previous content\n this.svg.innerHTML = '';\n\n const center = this.size / 2;\n const radius = (this.size - this.strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n\n // Create gradient definition if needed\n if (this.gradientColors && this.gradientColors.length > 1) {\n this.createGradient();\n }\n\n // Determine if we're using segments or single progress\n if (this.segments && Array.isArray(this.segments) && this.segments.length > 0) {\n this.renderSegments(center, radius, circumference);\n } else {\n this.renderSingleProgress(center, radius, circumference);\n }\n }\n\n renderSingleProgress(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track (background circle/arc)\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Create progress circle\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n\n const strokeColor = this.gradientColors ? `url(#${this.gradientId})` : this.color;\n\n const progress = this.createCircle(center, radius, {\n stroke: strokeColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${arcCircumference} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : dashOffset,\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: 'circular-progress-bar'\n });\n\n this.svg.appendChild(progress);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(progress, dashOffset);\n }\n }\n\n renderSegments(center, radius, circumference) {\n // Calculate arc length\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n\n // Create track\n const track = this.createCircle(center, radius, {\n stroke: this.trackColor,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: this.gap > 0 ? `${arcCircumference} ${circumference}` : 'none',\n transform: `rotate(${this.rotation} ${center} ${center})`\n });\n this.svg.appendChild(track);\n\n // Validate segments total\n const total = this.segments.reduce((sum, seg) => sum + (seg.value || 0), 0);\n if (total > this.max) {\n console.warn('CircularProgress: Segment total exceeds max value. Clamping to max.');\n }\n\n // Render each segment\n let currentOffset = 0;\n\n this.segments.forEach((segment, index) => {\n const segmentPercentage = ((segment.value || 0) / (this.max - this.min)) * 100;\n const segmentLength = (segmentPercentage / 100) * arcCircumference;\n\n // Gap between segments (in circumference units)\n const gapLength = (this.segmentGap / 360) * circumference;\n\n if (segmentLength > 0) {\n const segmentCircle = this.createCircle(center, radius, {\n stroke: segment.color || this.color,\n strokeWidth: this.strokeWidth,\n fill: 'none',\n strokeLinecap: this.rounded ? 'round' : 'butt',\n strokeDasharray: `${segmentLength} ${circumference}`,\n strokeDashoffset: this.animate ? arcCircumference : -(currentOffset),\n transform: `rotate(${this.rotation} ${center} ${center})`,\n class: `circular-progress-segment circular-progress-segment-${index}`,\n 'data-segment-index': index\n });\n\n this.svg.appendChild(segmentCircle);\n\n // Apply animation\n if (this.animate) {\n this.animateProgress(segmentCircle, -(currentOffset), index * 100);\n }\n\n // Update offset for next segment\n currentOffset += segmentLength + gapLength;\n }\n });\n }\n\n createCircle(cx, cy, attributes = {}) {\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', cx);\n circle.setAttribute('cy', cx); // Use cx for cy since we pass center for both\n circle.setAttribute('r', cy); // cy parameter is actually the radius\n\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'strokeWidth') {\n circle.setAttribute('stroke-width', value);\n } else if (key === 'strokeLinecap') {\n circle.setAttribute('stroke-linecap', value);\n } else if (key === 'strokeDasharray') {\n circle.setAttribute('stroke-dasharray', value);\n } else if (key === 'strokeDashoffset') {\n circle.setAttribute('stroke-dashoffset', value);\n } else {\n circle.setAttribute(key, value);\n }\n });\n\n return circle;\n }\n\n createGradient() {\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');\n gradient.setAttribute('id', this.gradientId);\n gradient.setAttribute('x1', '0%');\n gradient.setAttribute('y1', '0%');\n gradient.setAttribute('x2', '100%');\n gradient.setAttribute('y2', '100%');\n\n this.gradientColors.forEach((color, index) => {\n const stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');\n const offset = (index / (this.gradientColors.length - 1)) * 100;\n stop.setAttribute('offset', `${offset}%`);\n stop.setAttribute('stop-color', color);\n gradient.appendChild(stop);\n });\n\n defs.appendChild(gradient);\n this.svg.appendChild(defs);\n }\n\n animateProgress(circle, targetOffset, delay = 0) {\n setTimeout(() => {\n circle.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n circle.style.strokeDashoffset = targetOffset;\n }, delay);\n }\n\n renderCenterContent() {\n if (!this.centerElement) return;\n\n // Priority: labelHtml > icon > value/label\n if (this.labelHtml) {\n this.centerElement.innerHTML = this.labelHtml;\n } else if (this.icon) {\n this.centerElement.innerHTML = `<i class=\"${this.icon}\"></i>`;\n } else if (this.showValue) {\n const formattedValue = this.getFormattedValue();\n let html = `<div class=\"circular-progress-value\">${formattedValue}</div>`;\n \n if (this.label) {\n html += `<div class=\"circular-progress-label\">${this.label}</div>`;\n }\n\n this.centerElement.innerHTML = html;\n }\n }\n\n getFormattedValue() {\n const value = this.value;\n const min = this.min;\n const max = this.max;\n\n // Custom formatter function takes precedence\n if (this.valueFormatter && typeof this.valueFormatter === 'function') {\n return this.valueFormatter(value, min, max);\n }\n\n // Built-in formats\n switch (this.valueFormat) {\n case 'percentage':\n return `${Math.round(this.getPercentage())}%`;\n \n case 'fraction':\n return `${value}/${max}`;\n \n case 'value':\n return value.toString();\n \n default:\n // Try DataFormatter\n if (this.dataFormatter) {\n try {\n return this.dataFormatter.pipe(value, this.valueFormat);\n } catch (error) {\n console.warn('CircularProgress: DataFormatter error, falling back to percentage', error);\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n return `${Math.round(this.getPercentage())}%`;\n }\n }\n\n getPercentage() {\n const range = this.max - this.min;\n if (range === 0) return 0;\n return ((this.value - this.min) / range) * 100;\n }\n\n setupClickHandler() {\n if (!this.containerElement) return;\n\n this.containerElement.style.cursor = 'pointer';\n \n this.containerElement.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n const percentage = this.getPercentage();\n \n this.emit('progress:clicked', {\n value: this.value,\n percentage,\n min: this.min,\n max: this.max\n });\n\n // Toggle popover if tooltip is configured\n if (this.tooltip) {\n this.togglePopover();\n }\n });\n }\n\n setupTooltip() {\n // Bootstrap popover will be initialized on first click\n // We'll create the popover content dynamically\n }\n\n togglePopover() {\n if (!this.containerElement || typeof window.bootstrap === 'undefined') {\n console.warn('CircularProgress: Bootstrap is required for tooltip support');\n return;\n }\n\n // Get or create popover instance\n if (!this.popover) {\n const content = this.getTooltipContent();\n const title = typeof this.tooltip === 'object' && this.tooltip.title ? this.tooltip.title : undefined;\n\n // Build config object, omitting title if undefined\n const popoverConfig = {\n content: content,\n html: true,\n placement: this.tooltipPlacement,\n trigger: 'manual',\n container: 'body'\n };\n \n // Only add title if it exists\n if (title) {\n popoverConfig.title = title;\n }\n\n this.popover = new window.bootstrap.Popover(this.containerElement, popoverConfig);\n }\n\n // Toggle visibility\n const popoverElement = window.bootstrap.Popover.getInstance(this.containerElement);\n if (popoverElement && this.containerElement.getAttribute('aria-describedby')) {\n this.popover.hide();\n } else {\n // Update content before showing\n this.popover.setContent({\n '.popover-body': this.getTooltipContent()\n });\n this.popover.show();\n }\n }\n\n getTooltipContent() {\n if (typeof this.tooltip === 'function') {\n return this.tooltip(this.value, {\n min: this.min,\n max: this.max,\n percentage: this.getPercentage()\n });\n }\n\n if (typeof this.tooltip === 'object') {\n return this.tooltip.html || this.tooltip.content || '';\n }\n\n return this.tooltip || '';\n }\n\n // Public API\n\n setValue(value, animate = true) {\n const oldValue = this.value;\n this.value = Math.max(this.min, Math.min(this.max, value));\n \n // Update center content\n this.renderCenterContent();\n \n // Update progress without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n const radius = (this.size / 2) - (this.strokeWidth / 2);\n const circumference = 2 * Math.PI * radius;\n const arcLength = this.gap > 0 ? (360 - this.gap) : 360;\n const arcCircumference = (arcLength / 360) * circumference;\n const percentage = this.getPercentage();\n const progressLength = (percentage / 100) * arcCircumference;\n const dashOffset = arcCircumference - progressLength;\n \n if (animate) {\n // Animate from current offset to new offset\n progressBar.style.transition = `stroke-dashoffset ${this.animationDuration}ms ${this.animationEasing}`;\n progressBar.style.strokeDashoffset = dashOffset;\n } else {\n // Update immediately without animation\n progressBar.style.transition = 'none';\n progressBar.style.strokeDashoffset = dashOffset;\n }\n }\n } else {\n // For segments or if no existing progress bar, do full re-render\n const oldAnimate = this.animate;\n this.animate = animate;\n this.renderProgress();\n this.animate = oldAnimate;\n }\n }\n\n setRange(min, max) {\n this.min = min;\n this.max = max;\n this.renderProgress();\n this.renderCenterContent();\n }\n\n increment(amount = 1) {\n this.setValue(this.value + amount);\n }\n\n decrement(amount = 1) {\n this.setValue(this.value - amount);\n }\n\n setColor(color) {\n this.color = color;\n this.gradientColors = null; // Clear gradient\n \n // Update color without full re-render\n if (this.svg && !this.segments) {\n const progressBar = this.svg.querySelector('.circular-progress-bar');\n if (progressBar) {\n progressBar.setAttribute('stroke', color);\n }\n } else {\n // For segments, need to re-render\n this.renderProgress();\n }\n }\n\n setGradient(colors) {\n if (Array.isArray(colors) && colors.length > 1) {\n this.gradientColors = colors;\n this.gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;\n this.renderProgress();\n }\n }\n\n setSize(size) {\n // Remove old size class if it exists\n if (this.containerElement && this.sizePreset) {\n this.containerElement.classList.remove(`circular-progress-${this.sizePreset}`);\n }\n \n // Update size preset if the new size is a preset string\n this.sizePreset = (typeof size === 'string' && this.SIZE_PRESETS[size]) ? size : null;\n this.size = this.resolveSize(size);\n this.strokeWidth = this.getAutoStrokeWidth(size);\n \n // Add new size class if it's a preset\n if (this.containerElement) {\n this.containerElement.style.width = `${this.size}px`;\n this.containerElement.style.height = `${this.size}px`;\n \n if (this.sizePreset) {\n this.containerElement.classList.add(`circular-progress-${this.sizePreset}`);\n }\n }\n \n if (this.svg) {\n this.svg.setAttribute('width', this.size);\n this.svg.setAttribute('height', this.size);\n this.svg.setAttribute('viewBox', `0 0 ${this.size} ${this.size}`);\n }\n \n this.renderProgress();\n }\n\n animateTo(targetValue, duration = 1000) {\n const startValue = this.value;\n const diff = targetValue - startValue;\n const startTime = performance.now();\n\n const animate = (currentTime) => {\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Ease-out function\n const easeProgress = 1 - Math.pow(1 - progress, 3);\n \n const newValue = startValue + (diff * easeProgress);\n this.setValue(newValue, false);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n this.setValue(targetValue, false);\n }\n };\n\n requestAnimationFrame(animate);\n }\n\n pulse() {\n if (!this.containerElement) return;\n\n this.containerElement.style.animation = 'none';\n setTimeout(() => {\n this.containerElement.style.animation = 'circular-progress-pulse 0.5s ease-out';\n }, 10);\n\n setTimeout(() => {\n this.containerElement.style.animation = '';\n }, 500);\n }\n\n complete() {\n this.variant = 'success';\n this.applyVariant();\n this.setValue(this.max);\n this.pulse();\n }\n\n reset() {\n this.setValue(this.min);\n }\n\n hide() {\n if (this.element) {\n this.element.style.display = 'none';\n }\n }\n\n show() {\n if (this.element) {\n this.element.style.display = '';\n }\n }\n\n getValue() {\n return this.value;\n }\n\n getPercentageValue() {\n return this.getPercentage();\n }\n\n async onBeforeDestroy() {\n // Clean up popover\n if (this.popover) {\n this.popover.dispose();\n this.popover = null;\n }\n\n await super.onBeforeDestroy();\n }\n}\n"],"names":[],"mappings":"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"}