mypgs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +33 -0
  2. package/assets/javascript/_pgs.js +214 -0
  3. package/assets/javascript/base/_darkmode.js +121 -0
  4. package/assets/javascript/base/_object.js +42 -0
  5. package/assets/javascript/components/_accordion.js +77 -0
  6. package/assets/javascript/components/_dropdown.js +107 -0
  7. package/assets/javascript/components/_exeNotifications.js +85 -0
  8. package/assets/javascript/components/_menu.js +92 -0
  9. package/assets/javascript/components/_modals.js +123 -0
  10. package/assets/javascript/components/_slides.js +183 -0
  11. package/assets/javascript/components/_steps.js +27 -0
  12. package/assets/javascript/components/_tabs.js +134 -0
  13. package/assets/javascript/functions/_formValidate.js +217 -0
  14. package/assets/javascript/functions/_notifications.js +74 -0
  15. package/assets/javascript/functions/_scrollY.js +77 -0
  16. package/assets/javascript/functions/_sendForm.js +100 -0
  17. package/assets/javascript/index.js +20 -0
  18. package/assets/javascript/patterns/_cookieConsent.js +209 -0
  19. package/assets/javascript/patterns/_header.js +134 -0
  20. package/assets/javascript/pgs.d.ts +23 -0
  21. package/assets/scss/base/_body.scss +151 -0
  22. package/assets/scss/base/_color.scss +56 -0
  23. package/assets/scss/base/_general.scss +58 -0
  24. package/assets/scss/base/_heading.scss +20 -0
  25. package/assets/scss/base/_html.scss +4 -0
  26. package/assets/scss/base/_reset.scss +15 -0
  27. package/assets/scss/base/_variables.scss +39 -0
  28. package/assets/scss/components/_accordion.scss +91 -0
  29. package/assets/scss/components/_breadcumbs.scss +40 -0
  30. package/assets/scss/components/_button.scss +28 -0
  31. package/assets/scss/components/_dropdown.scss +106 -0
  32. package/assets/scss/components/_form.scss +53 -0
  33. package/assets/scss/components/_logo.scss +51 -0
  34. package/assets/scss/components/_menu.scss +23 -0
  35. package/assets/scss/components/_modals.scss +120 -0
  36. package/assets/scss/components/_notification.scss +193 -0
  37. package/assets/scss/components/_searchbar.scss +68 -0
  38. package/assets/scss/components/_slides.scss +198 -0
  39. package/assets/scss/components/_steps.scss +111 -0
  40. package/assets/scss/components/_table.scss +59 -0
  41. package/assets/scss/components/_tabs.scss +69 -0
  42. package/assets/scss/components/_tooltip.scss +16 -0
  43. package/assets/scss/index.scss +64 -0
  44. package/assets/scss/layout/_flex.scss +47 -0
  45. package/assets/scss/layout/_gap.scss +12 -0
  46. package/assets/scss/layout/_grid.scss +11 -0
  47. package/assets/scss/layout/_layout.scss +41 -0
  48. package/assets/scss/layout/_pageShell.scss +171 -0
  49. package/assets/scss/mixin/_mx-base.scss +126 -0
  50. package/assets/scss/mixin/_mx-button.scss +186 -0
  51. package/assets/scss/mixin/_mx-card.scss +77 -0
  52. package/assets/scss/mixin/_mx-color.scss +34 -0
  53. package/assets/scss/mixin/_mx-form-addon.scss +180 -0
  54. package/assets/scss/mixin/_mx-form.scss +512 -0
  55. package/assets/scss/mixin/_mx-menu.scss +154 -0
  56. package/assets/scss/mixin/_mx-responsive.scss +353 -0
  57. package/assets/scss/mixin/_mx-semantic.scss +147 -0
  58. package/assets/scss/mixin/mixin.scss +36 -0
  59. package/assets/scss/patterns/_cookieConsent.scss +101 -0
  60. package/assets/scss/patterns/_footer.scss +180 -0
  61. package/assets/scss/patterns/_header.scss +143 -0
  62. package/dist/css/index.css +7026 -0
  63. package/dist/css/index.css.map +1 -0
  64. package/dist/css/index.min.css +1 -0
  65. package/dist/index.d.ts +24 -0
  66. package/dist/javascript/index.js +2034 -0
  67. package/dist/javascript/index.js.map +1 -0
  68. package/dist/javascript/index.min.js +1 -0
  69. package/package.json +40 -0
  70. package/templates/components/md-breadcumbs.html +23 -0
  71. package/templates/components/md-menu.html +6 -0
  72. package/templates/components/md-notification.html +10 -0
  73. package/templates/components/md-searchbar.html +24 -0
  74. package/templates/components/md-tooltip.html +5 -0
  75. package/templates/layout/md-body.html +20 -0
  76. package/templates/layout/md-cookieConsent.html +51 -0
  77. package/templates/layout/md-footer.html +16 -0
  78. package/templates/layout/md-header.html +43 -0
  79. package/webpack.config.js +131 -0
@@ -0,0 +1,2034 @@
1
+ /******/ (() => { // webpackBootstrap
2
+ /******/ var __webpack_modules__ = ({
3
+
4
+ /***/ "./assets/javascript/_pgs.js"
5
+ /*!***********************************!*\
6
+ !*** ./assets/javascript/_pgs.js ***!
7
+ \***********************************/
8
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
+
10
+ "use strict";
11
+ __webpack_require__.r(__webpack_exports__);
12
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13
+ /* harmony export */ pgs: () => (/* binding */ pgs)
14
+ /* harmony export */ });
15
+ /**
16
+ * @param {Element | Document} root
17
+ */
18
+ function pgs(root) {
19
+ const ATTR = "pgs";
20
+ if (!root) throw new TypeError("pgs(root): root richiesto");
21
+
22
+ const canAttr = typeof root.getAttribute === "function" && typeof root.setAttribute === "function";
23
+ const canQuery = typeof root.querySelector === "function" && typeof root.querySelectorAll === "function";
24
+
25
+ if (!canQuery) {
26
+ throw new TypeError("pgs(root): root deve supportare querySelector/querySelectorAll");
27
+ }
28
+
29
+ //+
30
+ function attrOnlyForElements(methodName) {
31
+ throw new TypeError(`pgs(${root.nodeName || "root"}).${methodName}(): disponibile solo su Element (non su Document)`);
32
+ };
33
+
34
+ //+
35
+ function concactSelector(value) {
36
+ if (Array.isArray(value)) value = value.join(",");
37
+ return String(value)
38
+ .split(",")
39
+ .map(v => v.trim())
40
+ .filter(Boolean)
41
+ .map(v => `[${ATTR}~="${v}"]`)
42
+ .join(",");
43
+ }
44
+
45
+ //+
46
+ function getValues(el, separator = " ") {
47
+ return (el.getAttribute(ATTR) || "")
48
+ .split(separator)
49
+ .filter(Boolean);
50
+ }
51
+
52
+ //+
53
+ function setValues(el, values, separator = " ") {
54
+ el.setAttribute(ATTR, values.join(separator));
55
+ }
56
+
57
+ //= BASE PGS
58
+ function createBasePgs() {
59
+ function api() {
60
+ return api;
61
+ }
62
+
63
+ api.querySelector = function (value) {
64
+ return root.querySelector(concactSelector(value));
65
+ };
66
+
67
+ api.querySelectorAll = function (value) {
68
+ return root.querySelectorAll(concactSelector(value));
69
+ };
70
+
71
+ api.add = function (...values) {
72
+ if (!canAttr) return attrOnlyForElements("add");
73
+ const current = getValues(root);
74
+ for (const v of values) if (!current.includes(v)) current.push(v);
75
+ setValues(root, current);
76
+ return api;
77
+ };
78
+
79
+ api.remove = function (...values) {
80
+ if (!canAttr) return attrOnlyForElements("remove");
81
+ setValues(root, getValues(root).filter(v => !values.includes(v)));
82
+ return api;
83
+ };
84
+
85
+ api.toggle = function (value, force) {
86
+ if (!canAttr) return attrOnlyForElements("toggle");
87
+
88
+ const exists = getValues(root).includes(value);
89
+
90
+ if (force !== undefined) {
91
+ if (force && !exists) api.add(value);
92
+ if (!force && exists) api.remove(value);
93
+ return !!force;
94
+ }
95
+
96
+ if (exists) {
97
+ api.remove(value);
98
+ return false;
99
+ }
100
+
101
+ api.add(value);
102
+ return true;
103
+ };
104
+
105
+ api.contains = function (value) {
106
+ if (!canAttr) return attrOnlyForElements("contains");
107
+ return getValues(root).includes(value);
108
+ };
109
+
110
+ Object.defineProperty(api, "value", {
111
+ get() {
112
+ if (!canAttr) return undefined;
113
+ return root.getAttribute(ATTR);
114
+ },
115
+ set(v) {
116
+ if (!canAttr) return attrOnlyForElements("value");
117
+ root.setAttribute(ATTR, v);
118
+ }
119
+ });
120
+
121
+ return api;
122
+ }
123
+
124
+ //= STATE
125
+ function createState(attribute) {
126
+ if (!canAttr) return undefined;
127
+
128
+ const read = (sep = " ") =>
129
+ (root.getAttribute(attribute) || "").split(sep).filter(Boolean);
130
+
131
+ const write = (vals, sep = " ") =>
132
+ root.setAttribute(attribute, vals.join(sep));
133
+
134
+ // funzione chiamabile: state("active") == add("active")
135
+ function api(...values) {
136
+ api.add(...values);
137
+ return api;
138
+ }
139
+
140
+ api.add = function (...values) {
141
+ const toAdd = values.flat().map(v => String(v).trim()).filter(Boolean);
142
+ const current = read();
143
+ for (const v of toAdd) if (!current.includes(v)) current.push(v);
144
+ write(current);
145
+ return api;
146
+ };
147
+
148
+ api.remove = function (...values) {
149
+ const toRemove = values.flat().map(v => String(v).trim()).filter(Boolean);
150
+ const current = read().filter(v => !toRemove.includes(v));
151
+ write(current);
152
+ return api;
153
+ };
154
+
155
+ api.toggle = function (value) {
156
+ const v = String(value).trim();
157
+ if (!v) return false;
158
+
159
+ const current = read();
160
+ if (current.includes(v)) {
161
+ write(current.filter(x => x !== v));
162
+ return false;
163
+ }
164
+ current.push(v);
165
+ write(current);
166
+ return true;
167
+ };
168
+
169
+ api.contains = function (value) {
170
+ const v = String(value).trim();
171
+ if (!v) return false;
172
+ return read().includes(v);
173
+ };
174
+
175
+ Object.defineProperty(api, "value", {
176
+ get() { return root.getAttribute(attribute); },
177
+ set(v) { root.setAttribute(attribute, v); }
178
+ });
179
+
180
+ return api;
181
+ }
182
+
183
+ //= OPTION
184
+ function createOption(attribute) {
185
+ if (!canAttr) return undefined;
186
+
187
+ function api() {
188
+ return api;
189
+ }
190
+
191
+ api.contains = function (key) {
192
+ const source = root.getAttribute(attribute) || "";
193
+ const safeKey = String(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
194
+
195
+ return new RegExp(`(?:^|\\s)${safeKey}(?:\\[[^\\]]*\\])?(?=\\s|$)`)
196
+ .test(source);
197
+ };
198
+
199
+ api.getValueBrackets = function (key) {
200
+ const source = root.getAttribute(attribute) || "";
201
+ const safeKey = String(key).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
202
+
203
+ const match = source.match(
204
+ new RegExp(`(?:^|\\s)${safeKey}\\[([^\\]]*)\\]`)
205
+ );
206
+
207
+ return match ? match[1] : undefined;
208
+ };
209
+
210
+ Object.defineProperty(api, "value", {
211
+ get() { return root.getAttribute(attribute); },
212
+ set(v) { root.setAttribute(attribute, v); }
213
+ });
214
+
215
+ return api;
216
+ }
217
+
218
+ //# RETURN
219
+ const api = createBasePgs();
220
+ api.state = createState("pgs-state");
221
+ api.option = createOption("pgs-option");
222
+ api.modules = createOption("pgs-modules");
223
+ return api;
224
+ }
225
+
226
+ globalThis.pgs ??= pgs;
227
+
228
+
229
+
230
+
231
+ /***/ },
232
+
233
+ /***/ "./assets/javascript/base/_darkmode.js"
234
+ /*!*********************************************!*\
235
+ !*** ./assets/javascript/base/_darkmode.js ***!
236
+ \*********************************************/
237
+ () {
238
+
239
+ //# DARKMODE
240
+
241
+
242
+ //= CHANGE COLOR SVG & LOTTIE
243
+ //+ SEARCH COLOR
244
+ function searchColor(type = "svg") {
245
+ const ROOT = getComputedStyle(document.documentElement);
246
+ const colors = []
247
+ for (let I = 0; I < 20; I++) {
248
+ const color = ROOT.getPropertyValue('--' + type + '-color-' + I).toLocaleLowerCase().split("&");
249
+ if (!color[0] == "" && !color[1] == "") {
250
+ let lightDark = [color[0], color[1]]
251
+ colors.push(lightDark)
252
+ }
253
+ }
254
+ return colors;
255
+ }
256
+ const colors_svg_lottie = [searchColor("svg"), searchColor("lottie")];
257
+
258
+
259
+ //+ change COLORS
260
+ function darkmodeColorSVG() {
261
+ function changecolor(svgDoc, type = "svg") {
262
+ let isDarkMode = (document.documentElement.getAttribute("data-darkmode") === "true") ? false : true;
263
+
264
+ svgDoc.querySelectorAll('[fill], [stroke]').forEach(fillStroke => {
265
+
266
+ for (const colors of colors_svg_lottie) {
267
+ for (const color of colors) {
268
+ let OLD = (color[0] || '').replace(/\s/g, '');
269
+ let NEW = (color[1] || '').replace(/\s/g, '');
270
+
271
+ ["fill", "stroke"].forEach(attr => {
272
+ const current = fillStroke.getAttribute(attr);
273
+
274
+ fillStroke.style.transition = "fill 0.5s ease, stroke 0.5s ease";
275
+
276
+ if (!isDarkMode) {
277
+ if (current == OLD) fillStroke.setAttribute(attr, NEW)
278
+ } else {
279
+ if (current == NEW) fillStroke.setAttribute(attr, OLD)
280
+ }
281
+ });
282
+ }
283
+ }
284
+ });
285
+ }
286
+
287
+ //== OBJECTS
288
+ const objects = document.querySelectorAll('object[type="image/svg+xml"]');
289
+ objects.forEach(obj => {
290
+
291
+ //=== ALL FILL / STROKE
292
+ obj.addEventListener("load", () => {
293
+ const svgDoc = obj.contentDocument;
294
+ if (svgDoc) changecolor(svgDoc, "svg")
295
+ });
296
+
297
+ //=== In caso l'object sia già caricato
298
+ if (obj.contentDocument) {
299
+ const event = new Event("load");
300
+ obj.dispatchEvent(event);
301
+ }
302
+ });
303
+
304
+ //== LOTTIE
305
+ const lottiePlayers = document.querySelectorAll('lottie-player');
306
+ lottiePlayers.forEach(lottiePlayer => {
307
+
308
+ //=== ALL FILL / STROKE
309
+ lottiePlayer.addEventListener("load", () => {
310
+ const svg = lottiePlayer.shadowRoot.querySelector('svg');
311
+ if (svg) changecolor(svg, "lottie")
312
+ });
313
+
314
+ //=== In caso lottie sia già caricato
315
+ if (lottiePlayer.shadowRoot) {
316
+ const event = new Event("load");
317
+ lottiePlayer.dispatchEvent(event);
318
+ }
319
+ });
320
+ }
321
+
322
+
323
+
324
+ //= BUTTON DARKMODE
325
+ //+ CHANGE ICON AND SVG
326
+ let toggleDarkmode = pgs(document).querySelectorAll("toggleDarkmode");
327
+ if (localStorage.getItem("screenIsDarkMode") === "true") {
328
+ document.body.classList.add("darkmode");
329
+ document.querySelector(":root").setAttribute("data-darkmode", "true");
330
+ document.body.setAttribute("data-darkmode", "true");
331
+ }
332
+
333
+ function change(selector, isDarkMode) {
334
+ selector.forEach(button => {
335
+ const ICON = button.querySelector("i");
336
+ if (!ICON) return;
337
+ ICON.classList.toggle("fa-moon", !isDarkMode);
338
+ ICON.classList.toggle("fa-sun", isDarkMode);
339
+ });
340
+ darkmodeColorSVG();
341
+ }
342
+
343
+ toggleDarkmode.forEach(button => {
344
+
345
+ //== EXECUTE IMMEDIATELY
346
+ let isDarkMode = document.documentElement.getAttribute("data-darkmode") === "true";
347
+ change(toggleDarkmode, isDarkMode);
348
+
349
+ //== CLICK BUTTON
350
+ button.addEventListener("click", () => {
351
+ let isDarkMode = (document.documentElement.getAttribute("data-darkmode") === "true") ? false : true;
352
+ localStorage.setItem("screenIsDarkMode", isDarkMode);
353
+
354
+ document.body.classList.toggle("darkmode", isDarkMode);
355
+ document.body.setAttribute("data-darkmode", isDarkMode);
356
+ document.querySelector(":root").setAttribute("data-darkmode", isDarkMode);
357
+ change(toggleDarkmode, isDarkMode);
358
+ });
359
+ });
360
+
361
+
362
+ /***/ },
363
+
364
+ /***/ "./assets/javascript/base/_object.js"
365
+ /*!*******************************************!*\
366
+ !*** ./assets/javascript/base/_object.js ***!
367
+ \*******************************************/
368
+ () {
369
+
370
+ document.addEventListener('DOMContentLoaded', () => {
371
+ const objects = document.querySelectorAll('object[type="image/svg+xml"]');
372
+
373
+ objects.forEach(obj => {
374
+ function applyAspectRatio(svgDoc) {
375
+ if (!svgDoc) return;
376
+ const svg = svgDoc.querySelector("svg");
377
+ if (!svg) return;
378
+
379
+ const computedStyle = window.getComputedStyle(obj);
380
+ svg.setAttribute("preserveAspectRatio", computedStyle.objectFit === 'cover' ? "xMidYMid slice" : "xMidYMid meet");
381
+ }
382
+
383
+ function init() {
384
+ const svgDoc = obj.contentDocument;
385
+ if (!svgDoc) return;
386
+
387
+ const svg = svgDoc.querySelector('svg');
388
+ if (!svg) return;
389
+
390
+ applyAspectRatio(svgDoc);
391
+ if (obj.__objectResizeObserver) return;
392
+
393
+ let rafId = 0;
394
+ const resizeObserver = new ResizeObserver(() => {
395
+ if (rafId) return;
396
+ rafId = requestAnimationFrame(() => {
397
+ rafId = 0;
398
+ applyAspectRatio(svgDoc);
399
+ });
400
+ });
401
+
402
+ resizeObserver.observe(obj);
403
+ obj.__objectResizeObserver = resizeObserver;
404
+ }
405
+
406
+ if (obj.contentDocument && obj.contentDocument.querySelector('svg')) init();
407
+ else obj.addEventListener('load', init, { once: true });
408
+ });
409
+
410
+ document.body.classList.add("object-loaded");
411
+ });
412
+
413
+
414
+ /***/ },
415
+
416
+ /***/ "./assets/javascript/components/_accordion.js"
417
+ /*!****************************************************!*\
418
+ !*** ./assets/javascript/components/_accordion.js ***!
419
+ \****************************************************/
420
+ () {
421
+
422
+ //= ACCORDION
423
+ const allAccordion = pgs(document).querySelectorAll("accordion")
424
+
425
+ allAccordion.forEach((accordion, index) => {
426
+
427
+ const BUTTON = pgs(accordion).querySelector("accordion-button");
428
+ const CONTENT = pgs(accordion).querySelector("accordion-content");
429
+
430
+ //== ID univoci per aria-controls / aria-labelledby
431
+ const ID = index + 1;
432
+ const btnId = `acc-btn-${ID}`;
433
+ const panelId = `acc-panel-${ID}`;
434
+
435
+ //== Stato iniziale
436
+ const isOpenInit = pgs(accordion).state.contains("open");
437
+
438
+ //== Accessibilità (setup una volta)
439
+ BUTTON.setAttribute("role", "button");
440
+ BUTTON.setAttribute("tabindex", "0");
441
+ BUTTON.setAttribute("id", btnId);
442
+ BUTTON.setAttribute("aria-controls", panelId);
443
+
444
+ CONTENT.setAttribute("id", panelId);
445
+ CONTENT.setAttribute("role", "region");
446
+ CONTENT.setAttribute("aria-labelledby", btnId);
447
+
448
+ //+ Accessibility (applica stato aperto/chiuso)
449
+ function accordionAccessibility(isOpen, button, content) {
450
+ const text = (button?.textContent || "").trim().replace(/\s+/g, " ");
451
+ button.setAttribute("aria-label", `${isOpen ? "Chiudi" : "Apri"} ${text || "sezione"}`);
452
+ button.setAttribute("aria-expanded", String(isOpen));
453
+ content.hidden = !isOpen;
454
+ }
455
+
456
+ //+ Chiudi tutti gli altri
457
+ function closeOltherAccordion() {
458
+ for (const otherLi of allAccordion) {
459
+ if (otherLi === accordion) continue;
460
+
461
+ const otherBtn = pgs(otherLi).querySelector("accordion-button");
462
+ const otherContent = pgs(otherLi).querySelector("accordion-content");
463
+ if (!otherBtn || !otherContent) continue;
464
+
465
+ pgs(otherLi).state().remove("open");
466
+ accordionAccessibility(false, otherBtn, otherContent);
467
+ }
468
+ }
469
+
470
+ //+ FN ACCORDION
471
+ function accordionFunction() {
472
+ const isOpen = pgs(accordion).state.contains("open");
473
+ const nowOpen = !isOpen;
474
+
475
+ pgs(accordion).state.toggle("open", nowOpen);
476
+ accordionAccessibility(nowOpen, BUTTON, CONTENT);
477
+
478
+ closeOltherAccordion();
479
+
480
+ //== scroll to view
481
+ if (nowOpen) setTimeout(() => accordion.scrollIntoView({ block: "nearest", inline: "nearest" }), 100);
482
+ }
483
+
484
+ // applica stato iniziale
485
+ accordionAccessibility(isOpenInit, BUTTON, CONTENT);
486
+
487
+ //- Eventi
488
+ BUTTON.addEventListener("click", accordionFunction);
489
+
490
+ //- Tastiera: Enter / Space
491
+ BUTTON.addEventListener("keydown", (e) => {
492
+ if (e.key === "Enter" || e.key === " ") {
493
+ e.preventDefault();
494
+ accordionFunction();
495
+ }
496
+ });
497
+
498
+ });
499
+
500
+
501
+ /***/ },
502
+
503
+ /***/ "./assets/javascript/components/_dropdown.js"
504
+ /*!***************************************************!*\
505
+ !*** ./assets/javascript/components/_dropdown.js ***!
506
+ \***************************************************/
507
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
508
+
509
+ "use strict";
510
+ __webpack_require__.r(__webpack_exports__);
511
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
512
+ /* harmony export */ pgs_dropdown: () => (/* binding */ pgs_dropdown)
513
+ /* harmony export */ });
514
+ // + dropdown (Popover API)
515
+ function pgs_dropdown() {
516
+ pgs(document).querySelectorAll("dropdown").forEach((DROPDOWN, index) => {
517
+ const BUTTON = pgs(DROPDOWN).querySelector("dropdown-button");
518
+ const CONTENT = pgs(DROPDOWN).querySelector("dropdown-content");
519
+
520
+ if (!BUTTON || !CONTENT) return;
521
+
522
+ // = INIT
523
+ if (DROPDOWN.getAttribute("data-initialize") === "true") return;
524
+ DROPDOWN.setAttribute("data-initialize", "true");
525
+
526
+ // == CSS dropdown-anchor
527
+ const ANCHOR_NAME = `--dropdown-anchor-${index}`;
528
+ DROPDOWN.style.setProperty("--dropdown-anchor", ANCHOR_NAME);
529
+
530
+ // == IDs + ACCESSIBILITY
531
+ if (!BUTTON.id) BUTTON.id = `dropdown-btn-${index}`;
532
+ if (!CONTENT.id) CONTENT.id = `dropdown-panel-${index}`;
533
+ BUTTON.setAttribute("type", "button");
534
+ BUTTON.setAttribute("aria-haspopup", "true");
535
+ BUTTON.setAttribute("aria-controls", CONTENT.id);
536
+ BUTTON.setAttribute("aria-expanded", "false");
537
+ CONTENT.setAttribute("aria-labelledby", BUTTON.id);
538
+
539
+ // == POPVER SETUP
540
+ if (!CONTENT.hasAttribute("popover")) CONTENT.setAttribute("popover", "auto");
541
+ BUTTON.setAttribute("popovertarget", CONTENT.id);
542
+ BUTTON.setAttribute("popovertargetaction", "toggle");
543
+
544
+ //-( Safari / legacy fallback: popover is in the top layer, so fixed coords are viewport-based.
545
+ const HAS_ANCHOR_POSITIONING =
546
+ CSS.supports("anchor-name: --dropdown-anchor") &&
547
+ CSS.supports("position-anchor: --dropdown-anchor") &&
548
+ CSS.supports("position-area: bottom") &&
549
+ CSS.supports("top: anchor(bottom)");
550
+
551
+ const updatePopoverPosition = () => {
552
+ if (HAS_ANCHOR_POSITIONING) return;
553
+
554
+ const buttonRect = BUTTON.getBoundingClientRect();
555
+ const style = getComputedStyle(DROPDOWN);
556
+ const offset = parseFloat(style.getPropertyValue("--dropdown-offset")) || 10;
557
+ const padding = parseFloat(style.getPropertyValue("--dropdown-padding")) || 0;
558
+ const arrowSize = parseFloat(style.getPropertyValue("--dropdown-arrow-size")) || 12;
559
+ const viewportGap = 8;
560
+ const viewportWidth = window.innerWidth;
561
+ const maxWidth = viewportWidth - viewportGap * 2;
562
+ const contentStyle = getComputedStyle(CONTENT);
563
+ const cssMaxWidth = parseFloat(contentStyle.maxWidth);
564
+ const dropdownMaxWidth = Number.isFinite(cssMaxWidth) ? Math.min(cssMaxWidth, maxWidth) : maxWidth;
565
+ const contentWidth = Math.min(
566
+ Math.max(CONTENT.scrollWidth + padding * 2, buttonRect.width),
567
+ dropdownMaxWidth
568
+ );
569
+ const top = buttonRect.bottom + offset;
570
+ const centeredLeft = buttonRect.left + buttonRect.width / 2 - contentWidth / 2;
571
+ const left = Math.min(
572
+ Math.max(centeredLeft, viewportGap),
573
+ viewportWidth - contentWidth - viewportGap
574
+ );
575
+ const buttonCenter = buttonRect.left + buttonRect.width / 2;
576
+ const arrowLeft = Math.min(
577
+ Math.max(buttonCenter - left, padding + arrowSize),
578
+ contentWidth - padding - arrowSize
579
+ );
580
+
581
+ DROPDOWN.style.setProperty("--dropdown-fallback-top", `${top}px`);
582
+ DROPDOWN.style.setProperty("--dropdown-fallback-left", `${left}px`);
583
+ DROPDOWN.style.setProperty("--dropdown-arrow-left", `${arrowLeft}px`);
584
+ };
585
+
586
+ BUTTON.addEventListener("click", e => {
587
+ if (HAS_ANCHOR_POSITIONING) return;
588
+
589
+ e.preventDefault();
590
+ if (CONTENT.matches(":popover-open")) {
591
+ CONTENT.hidePopover();
592
+ return;
593
+ }
594
+
595
+ updatePopoverPosition();
596
+ CONTENT.showPopover();
597
+ });
598
+
599
+ // == sync ARIA + data-open quando apre/chiude
600
+ CONTENT.addEventListener("toggle", e => {
601
+ const open = CONTENT.matches(":popover-open");
602
+ BUTTON.setAttribute("aria-expanded", open ? "true" : "false");
603
+ pgs(DROPDOWN).state.toggle("open", open);
604
+ if (open) {
605
+ updatePopoverPosition();
606
+ CONTENT.querySelector('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])')?.focus();
607
+ }
608
+ });
609
+
610
+ window.addEventListener("resize", () => {
611
+ if (CONTENT.matches(":popover-open")) updatePopoverPosition();
612
+ });
613
+ window.addEventListener("scroll", () => {
614
+ if (CONTENT.matches(":popover-open")) updatePopoverPosition();
615
+ }, true);
616
+ });
617
+ }
618
+
619
+ // # INIT
620
+ pgs_dropdown();
621
+
622
+
623
+ /***/ },
624
+
625
+ /***/ "./assets/javascript/components/_exeNotifications.js"
626
+ /*!***********************************************************!*\
627
+ !*** ./assets/javascript/components/_exeNotifications.js ***!
628
+ \***********************************************************/
629
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
630
+
631
+ "use strict";
632
+ __webpack_require__.r(__webpack_exports__);
633
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
634
+ /* harmony export */ PGS_md_notification: () => (/* binding */ PGS_md_notification)
635
+ /* harmony export */ });
636
+ /* harmony import */ var _functions_notifications_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../functions/_notifications.js */ "./assets/javascript/functions/_notifications.js");
637
+
638
+
639
+ function escapeHtml(value) {
640
+ return String(value ?? "");
641
+ }
642
+
643
+ function getDuration(notification) {
644
+ const rawDuration = notification.duration;
645
+ const duration = Number.parseInt(rawDuration, 10);
646
+
647
+ return Number.isNaN(duration) ? 5000 : duration;
648
+ }
649
+
650
+ function getNotificationApi(notification) {
651
+ const element = String(notification.element || "notification").trim();
652
+
653
+ return element === "toast" ? _functions_notifications_js__WEBPACK_IMPORTED_MODULE_0__.PGS_toast : _functions_notifications_js__WEBPACK_IMPORTED_MODULE_0__.PGS_notification;
654
+ }
655
+
656
+ function getNotificationType(notification, api) {
657
+ const type = String(notification.type || "info").trim();
658
+
659
+ return typeof api[type] === "function" ? type : "info";
660
+ }
661
+
662
+ function getNotificationData(root) {
663
+ try {
664
+ return JSON.parse(root.dataset.notification || "{}");
665
+ } catch (error) {
666
+ console.warn("PGS notification: dati non validi", error);
667
+ return {};
668
+ }
669
+ }
670
+
671
+ function getNotificationContent(title, content) {
672
+ const safeContent = escapeHtml(content);
673
+ const safeTitle = escapeHtml(title);
674
+
675
+ if (!safeTitle) return safeContent;
676
+ if (!safeContent) return `<span pgs="notification-element-title">${safeTitle}</span>`;
677
+
678
+ return `
679
+ <span pgs="notification-element-title">${safeTitle}</span>
680
+ <br>
681
+ <span pgs="notification-element-content">${safeContent}</span>
682
+ `;
683
+ }
684
+
685
+ function PGS_md_notification(root) {
686
+ if (!root || root.dataset.initialize === "true") return;
687
+ root.dataset.initialize = "true";
688
+
689
+ const notification = getNotificationData(root);
690
+ const title = String(notification.title || "").trim();
691
+ const content = String(notification.message || "").trim();
692
+ if (!title && !content) {
693
+ root.remove();
694
+ return;
695
+ }
696
+
697
+ const link = notification.link || null;
698
+ const icon = notification.icon || undefined;
699
+ const duration = getDuration(notification);
700
+ const api = getNotificationApi(notification);
701
+ const type = getNotificationType(notification, api);
702
+ const formattedContent = getNotificationContent(title, content);
703
+
704
+ if (api === _functions_notifications_js__WEBPACK_IMPORTED_MODULE_0__.PGS_toast) {
705
+ api[type](formattedContent, duration, icon);
706
+ } else {
707
+ api[type](formattedContent, link, duration, icon);
708
+ }
709
+
710
+ root.remove();
711
+ }
712
+
713
+ function initMdNotifications() {
714
+ pgs(document).querySelectorAll("notificationTrigger").forEach(PGS_md_notification);
715
+ }
716
+
717
+ if (document.readyState === "loading") {
718
+ document.addEventListener("DOMContentLoaded", initMdNotifications);
719
+ } else {
720
+ initMdNotifications();
721
+ }
722
+
723
+
724
+ /***/ },
725
+
726
+ /***/ "./assets/javascript/components/_menu.js"
727
+ /*!***********************************************!*\
728
+ !*** ./assets/javascript/components/_menu.js ***!
729
+ \***********************************************/
730
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
731
+
732
+ "use strict";
733
+ __webpack_require__.r(__webpack_exports__);
734
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
735
+ /* harmony export */ PGS_menu: () => (/* binding */ PGS_menu)
736
+ /* harmony export */ });
737
+ /* harmony import */ var _dropdown__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_dropdown */ "./assets/javascript/components/_dropdown.js");
738
+
739
+
740
+ //= DROP DOWN MENU
741
+ function PGS_menu() {
742
+
743
+ pgs(document).querySelectorAll('menu-horizontal').forEach(MENU => {
744
+
745
+ MENU.querySelectorAll('nav > ul > li.menu-item-has-children').forEach(li => {
746
+ if (li.querySelector("ul")) {
747
+ const ul = li.querySelector("ul");
748
+
749
+ const button = document.createElement("button");
750
+ button.className = "icon-down";
751
+ button.type = "button";
752
+ button.innerHTML = "<span>&#9207;</span>";
753
+ li.querySelector("a").insertAdjacentElement("afterend", button);
754
+
755
+ pgs(li).add("dropdown")
756
+ pgs(button).add("dropdown-button")
757
+ pgs(button).add("buttonNohover")
758
+ pgs(ul).add("dropdown-content")
759
+ pgs(ul).add("menu-vertical")
760
+ }
761
+ });
762
+ });
763
+
764
+ pgs(document).querySelectorAll('menu-vertical').forEach(MENU => {
765
+
766
+ MENU.querySelectorAll('.menu-item-has-children').forEach((li, index) => {
767
+ const ul = li.querySelector("ul");
768
+
769
+ if (!ul) return
770
+
771
+ const button = document.createElement("button");
772
+ button.className = "icon-down buttonIcon";
773
+ button.type = "button";
774
+
775
+ // ID unico per aria-controls
776
+ const submenuId = `vertical-submenu-${index}`;
777
+ ul.id = submenuId;
778
+
779
+ // Stato iniziale
780
+ pgs(button).add("buttonIcon")
781
+ button.setAttribute("aria-expanded", "false");
782
+ button.setAttribute("aria-controls", submenuId);
783
+ button.setAttribute("aria-label", "Apri sottomenu");
784
+ button.innerHTML = "<span aria-hidden='true'>&#9207;</span>";
785
+ li.querySelector("a").insertAdjacentElement("afterend", button);
786
+
787
+ function toggleMenu() {
788
+ // const isOpena = ul.classList.toggle("open");
789
+ const isOpen = pgs(ul).state.toggle("open");
790
+ button.setAttribute("aria-expanded", isOpen);
791
+ button.setAttribute("aria-label", isOpen ? "Chiudi sottomenu" : "Apri sottomenu");
792
+ };
793
+
794
+ // Click
795
+ button.addEventListener("click", toggleMenu);
796
+ button.addEventListener("keydown", (e) => {
797
+ if (e.key === "Enter" || e.key === " ") {
798
+ e.preventDefault();
799
+ toggleMenu();
800
+ }
801
+ });
802
+ });
803
+
804
+ // pgs(document).querySelectorAll('menu-vertical').forEach(MENU => {
805
+
806
+ // MENU.querySelectorAll('.menu-item-has-children').forEach(li => {
807
+ // if (li.querySelector("ul")) {
808
+ // const ul = li.querySelector("ul");
809
+
810
+ // const button = document.createElement("button");
811
+ // button.className = "icon-down";
812
+ // button.type = "button";
813
+ // button.innerHTML = "<span>&#9207;</span>";
814
+ // li.querySelector("a").insertAdjacentElement("afterend", button);
815
+
816
+
817
+ // pgs(button).add("buttonIcon")
818
+ // button.addEventListener("click", () => {
819
+ // ul.classList.toggle("open")
820
+ // })
821
+ // }
822
+ // });
823
+ // });
824
+ });
825
+ (0,_dropdown__WEBPACK_IMPORTED_MODULE_0__.pgs_dropdown)()
826
+ }
827
+
828
+ //# INIT PGS_menu
829
+ PGS_menu()
830
+
831
+ /***/ },
832
+
833
+ /***/ "./assets/javascript/components/_modals.js"
834
+ /*!*************************************************!*\
835
+ !*** ./assets/javascript/components/_modals.js ***!
836
+ \*************************************************/
837
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
838
+
839
+ "use strict";
840
+ __webpack_require__.r(__webpack_exports__);
841
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
842
+ /* harmony export */ PGS_modal: () => (/* binding */ PGS_modal)
843
+ /* harmony export */ });
844
+ //# MODAL
845
+ PGS_modal()
846
+ function PGS_modal(selector = "modal") {
847
+ pgs(document).querySelectorAll(selector).forEach(MODAL => {
848
+
849
+ const BUTTON_OPEN = pgs(MODAL).querySelector("modal-button");
850
+ const DIALOG = MODAL.querySelector("dialog");
851
+ if (!BUTTON_OPEN || !DIALOG) return;
852
+
853
+ //== SELECTOR
854
+ const DOMButtonClose = '<button pgs="buttonClose modal-close" type="button" tabindex="0" aria-label="Chiudi"><i class="fa-solid fa-close"></i></button>';
855
+ const modalContentHeader = pgs(MODAL)?.querySelector("modal-dialog-content-header")
856
+
857
+
858
+ //== OPTION ATTRIBUTES MODAL
859
+ const disableBackdropClose = pgs(MODAL).option.contains("disableBackdropClose")
860
+ const data_history = pgs(MODAL).option.contains("history");
861
+ const data_container = pgs(MODAL).option.getValueBrackets("containerID");
862
+ const data_containerPGS = pgs(MODAL).option.getValueBrackets("containerPGS");
863
+
864
+ //== OPTION ATTRIBUTES DIALOG
865
+ const topLevel = pgs(DIALOG).option.contains("topLevel")
866
+
867
+
868
+ //== BUTTON CLOSE
869
+ if (pgs(MODAL).querySelector("modal-close")) null
870
+ else if (modalContentHeader) modalContentHeader.insertAdjacentHTML("beforeend", DOMButtonClose)
871
+ else DIALOG.insertAdjacentHTML("beforeend", DOMButtonClose)
872
+ const BUTTON_CLOSE = pgs(MODAL).querySelector("modal-close")
873
+
874
+
875
+ //== SET
876
+ pgs(DIALOG).add("dialog modal-dialog");
877
+
878
+ //== BUTTON OPEN
879
+ BUTTON_OPEN.setAttribute("role", "button");
880
+ BUTTON_OPEN.setAttribute("aria-label", "apri modale");
881
+
882
+
883
+ //== POSITION
884
+ if(!topLevel){
885
+ if (data_container) document.querySelector("#" + data_container)?.append(DIALOG);
886
+ else if (data_containerPGS) pgs(document).querySelector(data_containerPGS)?.append(DIALOG);
887
+ else document.body.append(DIALOG);
888
+ }
889
+
890
+
891
+ //+ FN STATUS
892
+ function statusModal(status = true) {
893
+ BUTTON_OPEN?.setAttribute("aria-expanded", status);
894
+ DIALOG?.setAttribute("aria-expanded", status);
895
+ }
896
+
897
+ //+ FN OPEN
898
+ function openModal(e) {
899
+ e?.stopImmediatePropagation();
900
+ if (!DIALOG.open) document.querySelectorAll("dialog[open]").forEach((dlg) => dlg.close());
901
+ statusModal(true);
902
+ DIALOG.open ? closeModal(e) : topLevel ? DIALOG.showModal() : DIALOG.show();
903
+ // modalCustomEvents('modal:open', { event: e });
904
+ MODAL.dispatchEvent(new CustomEvent('modal:open'));
905
+ DIALOG.dispatchEvent(new CustomEvent('modal:open'));
906
+ }
907
+
908
+ //+ FN CLOSE
909
+ function closeModal(e) {
910
+ e?.stopImmediatePropagation()
911
+ statusModal(false);
912
+ DIALOG.close();
913
+ // modalCustomEvents('modal:close', { event: e });
914
+ MODAL.dispatchEvent(new CustomEvent('modal:close'));
915
+ DIALOG.dispatchEvent(new CustomEvent('modal:close'));
916
+ }
917
+
918
+ //+ fn OPEN ON HISTORY
919
+ function openModalOnHistory() {
920
+ const params = new URLSearchParams(window.location.search);
921
+ if (params.get('modal') !== BUTTON_OPEN.id) return;
922
+ document.getElementById(BUTTON_OPEN.id)?.scrollIntoView({ behavior: 'smooth' });
923
+ openModal();
924
+ }
925
+
926
+
927
+ //= OPEN
928
+ BUTTON_OPEN.addEventListener("click", (e) => openModal(e));
929
+ BUTTON_OPEN.addEventListener("keypress", (e) => !DIALOG.open && (e.key === "Enter" || e.key === " ") && openModal(e));
930
+
931
+ //= CLOSE
932
+ DIALOG.addEventListener("close", () => statusModal(false));
933
+ DIALOG.addEventListener("click", e => { if (e.target == DIALOG && !disableBackdropClose) closeModal(e) });
934
+ BUTTON_CLOSE?.addEventListener("click", e => closeModal(e));
935
+
936
+ //= UPDATE HISTORY
937
+ if (data_history && BUTTON_OPEN.id) {
938
+ setTimeout(openModalOnHistory, 1);
939
+
940
+ //== Aggiorna URL quando cambia l'attributo "open" del dialog
941
+ const obs = new MutationObserver(() => {
942
+ let isOpen = DIALOG.hasAttribute("open");
943
+ try {
944
+ const url = new URL(window.location.href);
945
+ const params = new URLSearchParams(url.search);
946
+ isOpen ? params.set('modal', BUTTON_OPEN.id) : params.delete('modal');
947
+ url.search = params.toString() ? `?${params.toString()}` : "";
948
+ window.history.pushState({ modal: BUTTON_OPEN.id, open: isOpen }, "", url);
949
+ } catch (_) { }
950
+ });
951
+ obs.observe(DIALOG, { attributes: true, attributeFilter: ["open"] });
952
+
953
+ //== Gestisce back/forward del browser per aprire/chiudere il dialog coerentemente
954
+ window.addEventListener("popstate", () => {
955
+ try {
956
+ const params = new URLSearchParams(window.location.search);
957
+ const shouldOpen = params.get('modal') === BUTTON_OPEN.id;
958
+ if (shouldOpen && !DIALOG.open) DIALOG.showModal();
959
+ if (!shouldOpen && DIALOG.open) closeModal()
960
+ } catch (_) { }
961
+ });
962
+ }
963
+ });
964
+ }
965
+
966
+ //# INIT PGS_modal
967
+
968
+
969
+ /***/ },
970
+
971
+ /***/ "./assets/javascript/components/_slides.js"
972
+ /*!*************************************************!*\
973
+ !*** ./assets/javascript/components/_slides.js ***!
974
+ \*************************************************/
975
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
976
+
977
+ "use strict";
978
+ __webpack_require__.r(__webpack_exports__);
979
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
980
+ /* harmony export */ PGS_slides_api: () => (/* binding */ PGS_slides_api),
981
+ /* harmony export */ PGS_slides_init: () => (/* binding */ PGS_slides_init)
982
+ /* harmony export */ });
983
+ /* harmony import */ var _functions_scrollY__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../functions/_scrollY */ "./assets/javascript/functions/_scrollY.js");
984
+
985
+ const API = new WeakMap();
986
+
987
+ class PGS_Slides {
988
+ //- CONSTRUCTOR
989
+ constructor({ selector, viewRatio = 0.97, optionIntersectionObserver = {}, scrollOptions = {} } = {}) {
990
+ this.selector = selector;
991
+ this.viewRatio = viewRatio;
992
+
993
+ this.optionIntersectionObserver = {
994
+ threshold: Array.from({ length: 101 }, (_, i) => i / 100), // 0%,1%,2%...100%
995
+ rootMargin: "0px",
996
+ ...optionIntersectionObserver,
997
+ };
998
+
999
+ this.scrollOptions = {
1000
+ behavior: "smooth",
1001
+ inline: "center",
1002
+ block: "nearest",
1003
+ container: "nearest",
1004
+ ...scrollOptions,
1005
+ };
1006
+
1007
+ this.container = this.selector ? pgs(this.selector).querySelector("slides-container") : null;
1008
+ }
1009
+
1010
+ //+ CREATE BUTTON
1011
+ #createButtonsAndDots() {
1012
+ const EL = this.selector
1013
+
1014
+ //== PULSANTI
1015
+ if (!pgs(EL).querySelector('slides-prec') && !pgs(EL).querySelector('slides-next')) {
1016
+ EL.insertAdjacentHTML("afterbegin", `<button pgs="slides-prec button" type="button" class="precButton" aria-label="slide precedente"> <span> <i class="fa-solid fa-arrow-left"></i></span></button>`);
1017
+ EL.insertAdjacentHTML("beforeend", `<button pgs="slides-next button" type="button" class="nextButton" aria-label="prossima slide"> <span> <i class="fa-solid fa-arrow-right"></i></span></button>`);
1018
+ }
1019
+
1020
+ //== DOTS
1021
+ if (!pgs(EL).querySelector('slides-dots')) {
1022
+ EL.insertAdjacentHTML("beforeend", `<div pgs="slides-dots" class="slides-dots"></div>`);
1023
+
1024
+ Array.from(this.container.children).forEach(() => {
1025
+ pgs(EL).querySelector('slides-dots')
1026
+ .insertAdjacentHTML("beforeend", `<button type="button" class="slide-dot" aria-label="vai alla prossima slide"></button>`);
1027
+ });
1028
+ }
1029
+ }
1030
+
1031
+ //+ PREV
1032
+ #previousSlide() {
1033
+ const currents = this.container.querySelectorAll('.view');
1034
+ let current;
1035
+
1036
+
1037
+ if (pgs(this.selector).option.contains('singleScroll')) current = currents[currents.length - 1];
1038
+ else current = currents[0];
1039
+
1040
+ const prev = current?.previousElementSibling;
1041
+
1042
+ prev?.scrollIntoView(this.scrollOptions);
1043
+ prev?.focus({ preventScroll: true });
1044
+ }
1045
+
1046
+ //+ NEXT
1047
+ #nextSlide() {
1048
+ const currents = this.container.querySelectorAll('.view');
1049
+ let current;
1050
+
1051
+
1052
+
1053
+ if (pgs(this.selector).option.contains('singleScroll')) current = currents[0];
1054
+ else current = currents[currents.length - 1];
1055
+
1056
+ const next = current?.nextElementSibling;
1057
+ console.log(current, next);
1058
+
1059
+ next?.scrollIntoView(this.scrollOptions);
1060
+ next?.focus({ preventScroll: true });
1061
+ }
1062
+
1063
+ //+ GO TO NUMBER SLIDE
1064
+ #goToNumberSlide(index) {
1065
+ this.container.children[index].scrollIntoView(this.scrollOptions)
1066
+ }
1067
+
1068
+ //+ CALLBACK
1069
+ #callback(allLi, container, precButton, nextButton, dots) {
1070
+ allLi.forEach(LI => {
1071
+ const visiblePercent = 0.9 + LI.intersectionRatio * 0.1;
1072
+ const isView = visiblePercent >= 0.98;
1073
+
1074
+ //== SCROLL ANIMATION
1075
+ if (!pgs(LI.target).option.contains('notScrollAnimation')) {
1076
+ LI.target.firstElementChild.style.setProperty('--visible-percent', `${visiblePercent}`);
1077
+ };
1078
+
1079
+ //== VIEW & NOT-VIEW
1080
+ LI.target.classList.toggle("view", isView);
1081
+ LI.target.classList.toggle("notView", !isView);
1082
+
1083
+ //== VIEW PREC e NEXT
1084
+ const all = LI.target.parentNode.children;
1085
+ const atStart = all[0].classList.contains("view");
1086
+ const atEnd = all[all.length - 1].classList.contains("view");
1087
+ nextButton.disabled = atEnd;
1088
+ precButton.disabled = atStart;
1089
+ nextButton.setAttribute('aria-disabled', String(atEnd));
1090
+ precButton.setAttribute('aria-disabled', String(atStart));
1091
+
1092
+ //== ACTIVE DOT
1093
+ const viewElements = Array.from(container.children).filter(el => el.classList.contains('view'));
1094
+ dots.forEach((btn, i) => {
1095
+ const isActive = viewElements.some(el => Array.from(container.children).indexOf(el) === i);
1096
+ btn.classList.toggle('active', isActive);
1097
+ btn.setAttribute('aria-current', isActive ? 'true' : 'false');
1098
+ });
1099
+ })
1100
+ }
1101
+
1102
+ //= EXECUTE
1103
+ execute() {
1104
+ const slides = this.selector;
1105
+ if (!this.container) return
1106
+
1107
+ //== elements
1108
+ this.#createButtonsAndDots();
1109
+ const precButton = pgs(slides).querySelector('slides-prec');
1110
+ const nextButton = pgs(slides).querySelector('slides-next');
1111
+ const dots = Array.from(pgs(slides).querySelector('slides-dots').children);
1112
+
1113
+ //== option
1114
+ const notScrollWithMouse = pgs(slides).option.contains('notScrollWithMouse');
1115
+
1116
+ //== scroll
1117
+ if (!notScrollWithMouse) (0,_functions_scrollY__WEBPACK_IMPORTED_MODULE_0__.PGS_scrollHorizontal)(this.container, 5);
1118
+
1119
+ //==Listener: DOT, PREC, NEXT
1120
+ dots.forEach((dot, index) => dot.addEventListener("click", e => this.#goToNumberSlide(index)));
1121
+ precButton.addEventListener("click", e => this.#previousSlide(), { passive: true });
1122
+ nextButton.addEventListener("click", e => this.#nextSlide(), { passive: true });
1123
+
1124
+ //== observer
1125
+ const observer = new IntersectionObserver(
1126
+ (allLi) => this.#callback(allLi, this.container, precButton, nextButton, dots),
1127
+ { root: this.container, ...this.optionIntersectionObserver }
1128
+ );
1129
+ Array.from(this.container.children).forEach(allLi => observer.observe(allLi));
1130
+
1131
+
1132
+ //- API
1133
+ API.set(this.selector, {
1134
+ element: this.selector,
1135
+ container: this.container,
1136
+ previous: () => this.#previousSlide(),
1137
+ next: () => this.#nextSlide(),
1138
+ goTo: (index) => this.#goToNumberSlide(index),
1139
+ getCurrentIndexes: () => Array.from(this.container.children).map((el, i) => el.classList.contains("view") ? i : -1).filter(i => i !== -1),
1140
+ getCurrentElements: () => Array.from(this.container.children).filter(el => el.classList.contains("view")),
1141
+ getTotal: () => this.container.children.length,
1142
+ isAtStart: () => this.container.children[0]?.classList.contains("view") || false,
1143
+ isAtEnd: () => {
1144
+ const children = this.container.children;
1145
+ const last = children[children.length - 1];
1146
+ return last?.classList.contains("view") || false;
1147
+ },
1148
+ });
1149
+ }
1150
+ }
1151
+ PGS_slides_init();
1152
+
1153
+ //# INIT
1154
+ function PGS_slides_init(root = document) {
1155
+ pgs(root).querySelectorAll("slides").forEach(el => {
1156
+ if (API.has(el)) return;
1157
+
1158
+ const instance = new PGS_Slides({ selector: el });
1159
+ instance.execute();
1160
+ });
1161
+ }
1162
+
1163
+ //# API
1164
+ function PGS_slides_api(selector) {
1165
+ return API.get(selector);
1166
+ }
1167
+
1168
+
1169
+ /***/ },
1170
+
1171
+ /***/ "./assets/javascript/components/_steps.js"
1172
+ /*!************************************************!*\
1173
+ !*** ./assets/javascript/components/_steps.js ***!
1174
+ \************************************************/
1175
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1176
+
1177
+ "use strict";
1178
+ __webpack_require__.r(__webpack_exports__);
1179
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1180
+ /* harmony export */ PGS_ol: () => (/* binding */ PGS_ol)
1181
+ /* harmony export */ });
1182
+
1183
+ function PGS_ol() {
1184
+ pgs(document).querySelectorAll("steps").forEach(steps => {
1185
+
1186
+ pgs(steps).querySelectorAll("steps-step").forEach((li, index) => {
1187
+
1188
+ //= CIRCLE
1189
+ let circleLi;
1190
+ if (!pgs(li).querySelector("steps-step-circle")) {
1191
+ circleLi = document.createElement("span");
1192
+ pgs(circleLi).add("steps-step-circle")
1193
+ circleLi.textContent = index + 1;
1194
+ li.insertAdjacentElement("afterbegin", circleLi);
1195
+ } else{
1196
+ circleLi = pgs(li).querySelector("steps-step-circle");
1197
+ }
1198
+
1199
+ //= line
1200
+ const line = document.createElement("span");
1201
+ pgs(line).add("steps-step-line")
1202
+ li.insertAdjacentElement("afterbegin", line);
1203
+ });
1204
+ });
1205
+ }
1206
+
1207
+ //# INIT PGS_ol
1208
+ PGS_ol()
1209
+
1210
+ /***/ },
1211
+
1212
+ /***/ "./assets/javascript/components/_tabs.js"
1213
+ /*!***********************************************!*\
1214
+ !*** ./assets/javascript/components/_tabs.js ***!
1215
+ \***********************************************/
1216
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1217
+
1218
+ "use strict";
1219
+ __webpack_require__.r(__webpack_exports__);
1220
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1221
+ /* harmony export */ PGS_tabs: () => (/* binding */ PGS_tabs),
1222
+ /* harmony export */ PGS_tabs_api: () => (/* binding */ PGS_tabs_api)
1223
+ /* harmony export */ });
1224
+ const API = new WeakMap();
1225
+ PGS_tabs()
1226
+
1227
+ function PGS_tabs() {
1228
+ pgs(document).querySelectorAll("tabs").forEach(tabsWizard => {
1229
+
1230
+ //= INIT
1231
+ // if (tabsWizard.getAttribute("data-initialize") == "true") return;
1232
+ // tabsWizard.setAttribute("data-initialize", "true");
1233
+
1234
+ //= SELECTOR
1235
+ const prev = pgs(tabsWizard).querySelector("tabs-prev")
1236
+ const next = pgs(tabsWizard).querySelector("tabs-next")
1237
+ const restart = pgs(tabsWizard).querySelector("tabs-restart")
1238
+ const dots = pgs(tabsWizard).querySelector("tabs-dots")
1239
+ const tabsContainer = pgs(tabsWizard).querySelector("tabs-container");
1240
+ const allTab = pgs(tabsContainer).querySelectorAll("tab");
1241
+
1242
+ //= SETTING
1243
+ const total = allTab.length;
1244
+ const defaultTabLocked = Array.from(allTab).filter(tab => tab.getAttribute("data-tab-locked") === "true")
1245
+ let current = 0;
1246
+ prev.disabled = true;
1247
+
1248
+ //- CREAZIONE DOTS
1249
+ const tabDots = [];
1250
+ if (dots) {
1251
+ dots.innerHTML = "";
1252
+
1253
+ allTab.forEach((tab, index) => {
1254
+
1255
+ const iconClass = tab.getAttribute("data-tab-icon") || "fa-circle";
1256
+
1257
+ const dot = document.createElement("button");
1258
+ dot.type = "button";
1259
+ dot.className = "tab-dot";
1260
+ dot.setAttribute("data-step", index);
1261
+ dot.innerHTML = `<i class="fa-solid ${iconClass}"></i>`;
1262
+
1263
+ dot.addEventListener("click", () => {
1264
+ if (dot.classList.contains("is-completed")) {
1265
+ goTo(index, true);
1266
+ }
1267
+ });
1268
+
1269
+ dots.appendChild(dot);
1270
+ tabDots.push(dot);
1271
+ });
1272
+ }
1273
+
1274
+ //+ DOTS
1275
+ function updateDots() {
1276
+ tabDots.forEach((dot, i) => {
1277
+ dot.classList.toggle("is-active", i === current);
1278
+ dot.classList.toggle("is-completed", i < current);
1279
+ });
1280
+ }
1281
+
1282
+ //+ Step
1283
+ function goTo(index) {
1284
+ current = Math.min(Math.max(index, 0), total - 1);
1285
+ const tab = allTab[current]
1286
+
1287
+ prev.disabled = (current === 0);
1288
+ next.disabled = (current === total - 1 || tab.getAttribute("data-tab-locked") === "true");
1289
+
1290
+ allTab.forEach((tab, i) => tab.classList.toggle("is-active", i === current));
1291
+ tab?.focus();
1292
+ tabsWizard?.scrollIntoView({ behavior: "smooth", block: "start" });
1293
+ updateDots();
1294
+ tabsWizard.dispatchEvent(new CustomEvent('tabs:change', { detail: { current, total } }));
1295
+ }
1296
+
1297
+ //+ restart
1298
+ function restartTab() {
1299
+ goTo(0);
1300
+ defaultTabLocked.forEach(tab => tab.setAttribute("data-tab-locked", "true"));
1301
+ }
1302
+
1303
+ //= INIT
1304
+ goTo(0);
1305
+
1306
+ //= data-tab-locked
1307
+ const observer = new MutationObserver(() => goTo(current));
1308
+ allTab?.forEach(tabEl => observer.observe(tabEl, { attributes: true, attributeFilter: ["data-tab-locked"], }));
1309
+
1310
+
1311
+ //= Click su Avanti/Indietro
1312
+ prev?.addEventListener("click", e => goTo(current - 1));
1313
+ next?.addEventListener("click", e => goTo(current + 1));
1314
+ restart?.addEventListener("click", e => restartTab(), { capture: true });
1315
+
1316
+ //-(API)
1317
+ // tabsWizard.addEventListener("tabs:reset", () => restartTab());
1318
+ API.set(tabsWizard, {
1319
+ restart: restartTab,
1320
+ goTo,
1321
+ next: () => goTo(current + 1),
1322
+ prev: () => goTo(current - 1),
1323
+ toggleLock: (step, lock = true) => typeof step === "number" && allTab[step] && (allTab[step].setAttribute("data-tab-locked", lock.toString()), goTo(current)),
1324
+ getCurrent: () => current,
1325
+ getState: () => ({ current, total }),
1326
+ });
1327
+ });
1328
+ }
1329
+
1330
+ function PGS_tabs_api(selector) {
1331
+ return API.get(selector);
1332
+ }
1333
+
1334
+
1335
+ /*
1336
+ / EXAMPLE
1337
+ // vai allo step 2
1338
+ w.dispatchEvent(new CustomEvent("tabs:go", { detail: { step: 2 } }));
1339
+
1340
+ // next
1341
+ w.dispatchEvent(new CustomEvent("tabs:next"));
1342
+
1343
+ // prev
1344
+ w.dispatchEvent(new CustomEvent("tabs:prev"));
1345
+
1346
+ // reset a 0 senza relock
1347
+ w.dispatchEvent(new CustomEvent("tabs:reset"));
1348
+
1349
+ // lock step 3
1350
+ w.dispatchEvent(new CustomEvent("tabs:toggle-lock", { detail: { step: 3, lock: true } }));
1351
+
1352
+ // unlock step 3
1353
+ w.dispatchEvent(new CustomEvent("tabs:toggle-lock", { detail: { step: 3, lock: false } }));
1354
+
1355
+ // leggi stato
1356
+ w.dispatchEvent(new CustomEvent("tabs:get", { detail: { reply: (state) => console.log(state) } }));
1357
+ */
1358
+
1359
+
1360
+ /***/ },
1361
+
1362
+ /***/ "./assets/javascript/functions/_notifications.js"
1363
+ /*!*******************************************************!*\
1364
+ !*** ./assets/javascript/functions/_notifications.js ***!
1365
+ \*******************************************************/
1366
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1367
+
1368
+ "use strict";
1369
+ __webpack_require__.r(__webpack_exports__);
1370
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1371
+ /* harmony export */ PGS_notification: () => (/* binding */ PGS_notification),
1372
+ /* harmony export */ PGS_toast: () => (/* binding */ PGS_toast)
1373
+ /* harmony export */ });
1374
+ //# PGS_notification
1375
+ function initNotification(type, containerToken, icon, text, timeout, methodDelete = "replace", link = null) {
1376
+ let containerNotification = pgs(document).querySelector(containerToken);
1377
+
1378
+ //== Create Container
1379
+ if (!containerNotification) {
1380
+ const newContainer = document.createElement("div");
1381
+ pgs(newContainer).add(containerToken);
1382
+ newContainer.setAttribute("aria-live", "polite");
1383
+ newContainer.setAttribute("aria-relevant", "additions");
1384
+ document.body.appendChild(newContainer);
1385
+ containerNotification = newContainer;
1386
+ }
1387
+
1388
+ //== Create Notification
1389
+ const notification = document.createElement(link ? "a" : "div");
1390
+ if (methodDelete == "replace") containerNotification.innerHTML = "";
1391
+ if (link) notification.href = link;
1392
+ if (timeout > 0) notification.style.setProperty("--notification-timeout", timeout + "ms");
1393
+ pgs(notification).state.add(type);
1394
+ pgs(notification).add("notification-element");
1395
+ notification.setAttribute("role", type == "error" ? "alert" : "status")
1396
+ notification.innerHTML = `${icon} <p>${text}</p>`;
1397
+ containerNotification.appendChild(notification);
1398
+
1399
+
1400
+ //+ Animation delete
1401
+ function deleteNotification() {
1402
+ methodDelete == "stack" ? notification.style.translate = "120%" : notification.style.opacity = "0";
1403
+ setTimeout(() => notification.remove(), 300);
1404
+ }
1405
+
1406
+ //== Timeout delete
1407
+ if (timeout > 0) setTimeout(() => { deleteNotification() }, timeout);
1408
+
1409
+ //== button delete
1410
+ const btnDelete = document.createElement("button");
1411
+ btnDelete.type = "button";
1412
+ btnDelete.ariaLabel = "Rimuovi notifica";
1413
+ btnDelete.innerHTML = '<i class="fa-solid fa-xmark"></i>';
1414
+ btnDelete.setAttribute("pgs", "buttonClose");
1415
+ notification.insertAdjacentElement("afterbegin", btnDelete);
1416
+
1417
+ //== event
1418
+ btnDelete.addEventListener("click", function (e) {
1419
+ e.preventDefault();
1420
+ e.stopPropagation();
1421
+ e.stopImmediatePropagation()
1422
+ deleteNotification(e); // Esegue la tua funzione
1423
+ });
1424
+ }
1425
+
1426
+ function deleteALl(containerToken) {
1427
+ let containerNotification = pgs(document).querySelector(containerToken);
1428
+ if (containerNotification) containerNotification.innerHTML = "";
1429
+ }
1430
+
1431
+
1432
+
1433
+ let PGS_notification = {
1434
+ error: (text = "Errore", link = null, timeout = 0, icon = '<i class="fa-solid fa-octagon-xmark"></i>') => initNotification("error", "notification", icon, text, timeout, "stack", link),
1435
+ success: (text = "Aggiornato", link = null, timeout = 0, icon = '<i class="fa-solid fa-check"></i>') => initNotification("success", "notification", icon, text, timeout, "stack", link),
1436
+ info: (text = "Aggiornamento", link = null, timeout = 0, icon = '<i class="fa-solid fa-circle-info"></i>',) => initNotification("info", "notification", icon, text, timeout, "stack", link),
1437
+ warning: (text = "Attenzione", link = null, timeout = 0, icon = '<i class="fa-solid fa-triangle-exclamation"></i>') => initNotification("warning", "notification", icon, text, timeout, "stack", link),
1438
+ deleteAllNotification: () => deleteALl("notification")
1439
+ }
1440
+
1441
+ let PGS_toast = {
1442
+ error: (text = "Errore", timeout = 4000, icon = '<i class="fa-solid fa-octagon-xmark"></i>',) => initNotification("error", "toast", icon, text, timeout),
1443
+ success: (text = "Aggiornato", timeout = 4000, icon = '<i class="fa-solid fa-check"></i>',) => initNotification("success", "toast", icon, text, timeout),
1444
+ info: (text = "Aggiornamento", timeout = 0, icon = '<i class="fa-solid fa-circle-info"></i>',) => initNotification("info", "toast", icon, text, timeout),
1445
+ warning: (text = "Attenzione", timeout = 4000, icon = '<i class="fa-solid fa-triangle-exclamation"></i>',) => initNotification("warning", "toast", icon, text, timeout),
1446
+ deleteTost: () => deleteALl("toast")
1447
+ }
1448
+
1449
+ /***/ },
1450
+
1451
+ /***/ "./assets/javascript/functions/_scrollY.js"
1452
+ /*!*************************************************!*\
1453
+ !*** ./assets/javascript/functions/_scrollY.js ***!
1454
+ \*************************************************/
1455
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1456
+
1457
+ "use strict";
1458
+ __webpack_require__.r(__webpack_exports__);
1459
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1460
+ /* harmony export */ PGS_scrollHorizontal: () => (/* binding */ PGS_scrollHorizontal)
1461
+ /* harmony export */ });
1462
+ function PGS_scrollHorizontal(querySelector, dataSpeed) {
1463
+ // Se hai più contenitori, selezionali tutti:
1464
+ // Semplice "singleton" per stimare se la sorgente è trackpad
1465
+ const TrackpadDetector = (() => {
1466
+ let lastTs = 0;
1467
+ let smallAndFast = 0;
1468
+ let samples = 0;
1469
+ let isTrackpad = false;
1470
+
1471
+ function update(e) {
1472
+ const now = performance.now();
1473
+ const dt = now - lastTs;
1474
+
1475
+ // Porta delta in px (0: px, 1: linee, 2: pagine)
1476
+ let dy = Math.abs(e.deltaY);
1477
+ if (e.deltaMode === 1) dy *= 16;
1478
+ else if (e.deltaMode === 2) dy *= e.currentTarget?.clientHeight || 800;
1479
+
1480
+ // Heuristica: eventi piccoli e ravvicinati → prob. trackpad
1481
+ const small = dy < 30; // soglia prudente
1482
+ const fast = dt < 35; // alta frequenza
1483
+ if (small && fast) smallAndFast++;
1484
+
1485
+ samples++;
1486
+ if (samples >= 6) { // aggiorna il giudizio ogni N eventi
1487
+ isTrackpad = smallAndFast >= 3;
1488
+ smallAndFast = 0;
1489
+ samples = 0;
1490
+ }
1491
+
1492
+ lastTs = now;
1493
+ return isTrackpad;
1494
+ }
1495
+
1496
+ return {
1497
+ update,
1498
+ get value() { return isTrackpad; }
1499
+ };
1500
+ })();
1501
+
1502
+ //= Scorrimento orizzontale con rotella (evita il trackpad)
1503
+
1504
+ let el = querySelector
1505
+ el.addEventListener('wheel', (e) => {
1506
+ const speed = dataSpeed;
1507
+
1508
+ //== lascia lo scroll naturale del trackpad
1509
+ if (TrackpadDetector.update(e)) return;
1510
+
1511
+ //== Evita interferenze con zoom o scroll orizzontale nativo
1512
+ if (e.ctrlKey) return;
1513
+ if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return;
1514
+
1515
+ //== Converti delta in px per lo shift orizzontale
1516
+ let delta = e.deltaY;
1517
+ if (e.deltaMode === 1) delta *= 16;
1518
+ else if (e.deltaMode === 2) delta *= el.clientHeight;
1519
+
1520
+ //== Verifica se il contenitore può ancora scrollare orizzontalmente
1521
+ const atStart = el.scrollLeft <= 0;
1522
+ const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;
1523
+ const scrollingRight = delta > 0;
1524
+ const scrollingLeft = delta < 0;
1525
+ const canScrollHoriz =
1526
+ (scrollingRight && !atEnd) ||
1527
+ (scrollingLeft && !atStart);
1528
+
1529
+ // Se non può più scrollare in quella direzione, lascia che la pagina gestisca lo scroll verticale
1530
+ if (!canScrollHoriz) return;
1531
+
1532
+ //== Previeni il default solo quando facciamo noi lo scroll orizzontale
1533
+ e.preventDefault();
1534
+
1535
+ //== rotella giù => destra
1536
+ el.scrollLeft += delta * speed;
1537
+ }, { passive: false });
1538
+ }
1539
+
1540
+
1541
+ /***/ },
1542
+
1543
+ /***/ "./assets/javascript/patterns/_cookieConsent.js"
1544
+ /*!******************************************************!*\
1545
+ !*** ./assets/javascript/patterns/_cookieConsent.js ***!
1546
+ \******************************************************/
1547
+ () {
1548
+
1549
+ const STORAGE_KEY = 'pgs_cookie_preferences_v1';
1550
+ const focusableSelectors = 'a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])';
1551
+
1552
+ //+
1553
+ function safeJsonParse(value) {
1554
+ try {
1555
+ return value ? JSON.parse(value) : null;
1556
+ } catch (error) {
1557
+ console.warn('PGS cookie consent: impossibile leggere le preferenze', error);
1558
+ return null;
1559
+ }
1560
+ }
1561
+
1562
+ //+
1563
+ function readPreferences() {
1564
+ try {
1565
+ return safeJsonParse(localStorage.getItem(STORAGE_KEY));
1566
+ } catch (error) {
1567
+ return null;
1568
+ }
1569
+ }
1570
+
1571
+ //+
1572
+ function savePreferences(prefs) {
1573
+ try {
1574
+ localStorage.setItem(
1575
+ STORAGE_KEY,
1576
+ JSON.stringify({ ...prefs, updatedAt: new Date().toISOString() })
1577
+ );
1578
+ } catch (error) {
1579
+ console.warn('PGS cookie consent: impossibile salvare le preferenze', error);
1580
+ }
1581
+ }
1582
+
1583
+ //+
1584
+ function bootstrapGtag() {
1585
+ window.dataLayer = window.dataLayer || [];
1586
+ window.gtag = window.gtag || function gtag() {
1587
+ window.dataLayer.push(arguments);
1588
+ };
1589
+ }
1590
+
1591
+ //+
1592
+ function loadGoogleAnalytics(measurementId) {
1593
+ if (!measurementId || window.__PGS_gaLoaded) return;
1594
+ window.__PGS_gaLoaded = true;
1595
+
1596
+ const script = document.createElement('script');
1597
+ script.async = true;
1598
+ script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
1599
+ document.head.appendChild(script);
1600
+
1601
+ window.gtag('js', new Date());
1602
+ window.gtag('config', measurementId, {
1603
+ anonymize_ip: true,
1604
+ allow_google_signals: false,
1605
+ });
1606
+ }
1607
+
1608
+ //+
1609
+ function applyAnalyticsConsent({ allowAnalytics, measurementId }) {
1610
+ bootstrapGtag();
1611
+ if (allowAnalytics) {
1612
+ window.gtag('consent', 'update', { analytics_storage: 'granted' });
1613
+ loadGoogleAnalytics(measurementId);
1614
+ } else {
1615
+ window.gtag('consent', 'update', { analytics_storage: 'denied' });
1616
+ }
1617
+ }
1618
+
1619
+ //+
1620
+ function setPgsFlag(element, token, enabled) {
1621
+ if (!(element instanceof HTMLElement) || !token) return;
1622
+ const current = (element.getAttribute('pgs') || '').split(/\s+/).filter(Boolean);
1623
+ const next = enabled ? [...new Set([...current, token])] : current.filter((item) => item !== token);
1624
+ if (next.length > 0) {
1625
+ element.setAttribute('pgs', next.join(' '));
1626
+ } else {
1627
+ element.removeAttribute('pgs');
1628
+ }
1629
+ }
1630
+
1631
+ //+
1632
+ function assignCookieRuntimeAttributes({ root, analyticsToggle, acceptAllButton, rejectButton, openButtons }) {
1633
+ root.dataset.cookieComponent = 'consent';
1634
+ analyticsToggle?.setAttribute('data-cookie-toggle', 'analytics');
1635
+ acceptAllButton?.setAttribute('data-cookie-action', 'accept');
1636
+ rejectButton?.setAttribute('data-cookie-action', 'reject');
1637
+
1638
+ root.querySelector('[pgs~="cookieConsent-featureEssential"]')?.setAttribute('data-cookie-feature', 'essential');
1639
+ root.querySelector('[pgs~="cookieConsent-featureAnalytics"]')?.setAttribute('data-cookie-feature', 'analytics');
1640
+
1641
+ openButtons.forEach((button) => {
1642
+ button.setAttribute('data-cookie-action', 'open');
1643
+ });
1644
+ }
1645
+
1646
+ //= CookieConsent
1647
+ document.addEventListener('DOMContentLoaded', function () {
1648
+ const root = pgs(document).querySelector('cookieConsent');
1649
+ if (!root) return;
1650
+
1651
+ const analyticsToggle = root.querySelector('[pgs~="cookieConsent-toggleAnalytics"]');
1652
+ const acceptAllButton = root.querySelector('[pgs~="cookieConsent-actionAccept"]');
1653
+ const rejectButton = root.querySelector('[pgs~="cookieConsent-actionReject"]');
1654
+ const openButtons = document.querySelectorAll('[pgs~="cookieConsent-actionOpen"]');
1655
+ const measurementId = (root.dataset.gaId || '').trim();
1656
+ const prefersGa = measurementId.length > 0;
1657
+ let lastFocusedElement = null;
1658
+
1659
+ assignCookieRuntimeAttributes({ root, analyticsToggle, acceptAllButton, rejectButton, openButtons });
1660
+
1661
+ if (analyticsToggle) {
1662
+ analyticsToggle.disabled = !prefersGa;
1663
+ if (!prefersGa) {
1664
+ analyticsToggle.checked = false;
1665
+ setPgsFlag(root, 'cookieConsent-gaUnavailable', true);
1666
+ } else {
1667
+ setPgsFlag(root, 'cookieConsent-gaUnavailable', false);
1668
+ }
1669
+ }
1670
+
1671
+ bootstrapGtag();
1672
+ window.gtag('consent', 'default', { analytics_storage: 'denied' });
1673
+
1674
+ function setBannerVisibility(show) {
1675
+ root.hidden = !show;
1676
+ root.setAttribute('aria-hidden', String(!show));
1677
+ document.body.classList.toggle('cookieConsent-open', show);
1678
+ if (show) {
1679
+ lastFocusedElement = document.activeElement;
1680
+ setTimeout(() => {
1681
+ root.focus();
1682
+ }, 0);
1683
+ } else if (lastFocusedElement instanceof HTMLElement) {
1684
+ lastFocusedElement.focus({ preventScroll: true });
1685
+ }
1686
+ }
1687
+
1688
+ function closeBanner() {
1689
+ setBannerVisibility(false);
1690
+ }
1691
+
1692
+ function openBanner() {
1693
+ setBannerVisibility(true);
1694
+ }
1695
+
1696
+ function persistAndApply(allowAnalytics) {
1697
+ savePreferences({ analytics: allowAnalytics });
1698
+ setPgsFlag(root, 'cookieConsent-accepted', !!allowAnalytics);
1699
+ setPgsFlag(root, 'cookieConsent-declined', !allowAnalytics);
1700
+ applyAnalyticsConsent({ allowAnalytics: !!allowAnalytics, measurementId });
1701
+ }
1702
+
1703
+ acceptAllButton?.addEventListener('click', () => {
1704
+ if (analyticsToggle && prefersGa) analyticsToggle.checked = true;
1705
+ persistAndApply(!!prefersGa);
1706
+ closeBanner();
1707
+ });
1708
+
1709
+ rejectButton?.addEventListener('click', () => {
1710
+ const allowAnalytics = analyticsToggle ? analyticsToggle.checked && prefersGa : false;
1711
+ if (!allowAnalytics && analyticsToggle) analyticsToggle.checked = false;
1712
+ persistAndApply(allowAnalytics);
1713
+ closeBanner();
1714
+ });
1715
+
1716
+ analyticsToggle?.addEventListener('change', (event) => {
1717
+ if (!prefersGa && event.target instanceof HTMLInputElement) {
1718
+ event.target.checked = false;
1719
+ }
1720
+ });
1721
+
1722
+ root.addEventListener('keydown', (event) => {
1723
+ if (event.key === 'Escape') {
1724
+ event.preventDefault();
1725
+ closeBanner();
1726
+ } else if (event.key === 'Tab') {
1727
+ const focusables = root.querySelectorAll(focusableSelectors);
1728
+ if (focusables.length === 0) return;
1729
+ const first = focusables[0];
1730
+ const last = focusables[focusables.length - 1];
1731
+ if (!event.shiftKey && document.activeElement === last) {
1732
+ event.preventDefault();
1733
+ first.focus();
1734
+ }
1735
+ if (event.shiftKey && document.activeElement === first) {
1736
+ event.preventDefault();
1737
+ last.focus();
1738
+ }
1739
+ }
1740
+ });
1741
+
1742
+ openButtons.forEach((button) => {
1743
+ button.addEventListener('click', (event) => {
1744
+ event.preventDefault();
1745
+ openBanner();
1746
+ });
1747
+ });
1748
+
1749
+ const savedPrefs = readPreferences();
1750
+ if (savedPrefs && typeof savedPrefs.analytics === 'boolean') {
1751
+ if (analyticsToggle) analyticsToggle.checked = !!savedPrefs.analytics && prefersGa;
1752
+ persistAndApply(savedPrefs.analytics && prefersGa);
1753
+ closeBanner();
1754
+ } else {
1755
+ setBannerVisibility(true);
1756
+ }
1757
+ });
1758
+
1759
+
1760
+ /***/ },
1761
+
1762
+ /***/ "./assets/javascript/patterns/_header.js"
1763
+ /*!***********************************************!*\
1764
+ !*** ./assets/javascript/patterns/_header.js ***!
1765
+ \***********************************************/
1766
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1767
+
1768
+ "use strict";
1769
+ __webpack_require__.r(__webpack_exports__);
1770
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1771
+ /* harmony export */ PGS_header: () => (/* binding */ PGS_header)
1772
+ /* harmony export */ });
1773
+ //# HEADER
1774
+ const header = pgs(document).querySelector("header");
1775
+ const headerElements = pgs(header).querySelectorAll("header-element");
1776
+ headerElements.forEach(element => PGS_header(element));
1777
+
1778
+ //= HEADER
1779
+ function PGS_header(selectHeader) {
1780
+
1781
+ //= INIT
1782
+ if (selectHeader.getAttribute("data-initialize") == "true") return;
1783
+ selectHeader.setAttribute("data-initialize", "true");
1784
+
1785
+ //= ACTIVE MOBILE
1786
+ let menuAttivate = false;
1787
+ let childsWidthSAVE;
1788
+
1789
+ function mobileActive(headerElement) {
1790
+
1791
+ //=== header
1792
+ let style = window.getComputedStyle(headerElement);
1793
+ let padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
1794
+ let gap = parseFloat(style.gap);
1795
+ let headerElementWidth = parseInt(headerElement.offsetWidth - padding);
1796
+ let childsWidth;
1797
+
1798
+ if (menuAttivate) {
1799
+ childsWidth = childsWidthSAVE;
1800
+ } else {
1801
+ let childs = [];
1802
+
1803
+ // Esclude l'area mobile dedicata e l'hamburger, poi misura i figli sempre visibili su desktop.
1804
+ Array.from(headerElement.children)
1805
+ .filter(el => !pgs(el).contains("header-element-onlyMobile"))
1806
+ .forEach(child => {
1807
+ if (pgs(child).contains("header-element-hamburger")) return;
1808
+ childs.push(...child.children);
1809
+ });
1810
+
1811
+ gap = Math.round(gap * (childs.length - 1));
1812
+ let childsReduce = childs.reduce((totalWidth, child) => totalWidth + child.offsetWidth, 0) - 2;
1813
+
1814
+ childsWidth = childsReduce + gap;
1815
+ }
1816
+
1817
+ //===set data
1818
+ if (window.innerWidth < 600) {
1819
+ header.setAttribute("data-header-mobileActive", "true");
1820
+ selectHeader.setAttribute("data-header-mobileActive", "true");
1821
+ } else if (headerElementWidth < childsWidth) {
1822
+ header.setAttribute("data-header-mobileActive", "true");
1823
+ headerElement.setAttribute("data-header-mobileActive", "true");
1824
+ menuAttivate = true;
1825
+ childsWidthSAVE = childsWidth;
1826
+ } else {
1827
+ header.setAttribute("data-header-mobileActive", "false");
1828
+ headerElement.setAttribute("data-header-mobileActive", "false");
1829
+ }
1830
+ }
1831
+
1832
+ //== observer (throttled to avoid ResizeObserver loop warnings)
1833
+ let resizeRafId = 0;
1834
+ const scheduleMobileActive = () => {
1835
+ if (resizeRafId) return;
1836
+ resizeRafId = requestAnimationFrame(() => {
1837
+ resizeRafId = 0;
1838
+ mobileActive(selectHeader);
1839
+ });
1840
+ };
1841
+
1842
+ let observer = new ResizeObserver(scheduleMobileActive);
1843
+ observer.observe(selectHeader);
1844
+ scheduleMobileActive();
1845
+
1846
+ }
1847
+
1848
+
1849
+
1850
+
1851
+ //= HEADER HEIGHT
1852
+ const body = document.querySelector("body");
1853
+ function headerHeight() {
1854
+ const headerElements = document.querySelectorAll("header > [data-initialize=true]");
1855
+ const wordPressBar = window.getComputedStyle(document.documentElement).marginTop ?? 0;
1856
+
1857
+ const totalHeight = Array.from(headerElements)
1858
+ .map(el => el.offsetHeight)
1859
+ .reduce((sum, h) => sum + h);
1860
+
1861
+ const height = totalHeight + parseInt(wordPressBar);
1862
+
1863
+ body.style.setProperty('--heightOfHeader', `${height}px`);
1864
+ const scrollHeight = document.querySelector("header").getAttribute("data-header-scroll") === "true" ? 0 : height;
1865
+ body.style.setProperty('--heightOfHeaderScroll', `${scrollHeight}px`);
1866
+
1867
+ }
1868
+ headerHeight()
1869
+ window.addEventListener("resize", headerHeight);
1870
+ window.addEventListener("scroll", headerHeight);
1871
+
1872
+
1873
+ //= SCROLL
1874
+ // Nasconde l'header quando si scorre verso il basso e lo mostra quando si scorre verso l'alto su dispositivi con larghezza fino a 900px.
1875
+ let lastScrollY = window.scrollY;
1876
+ window.addEventListener("scroll", () => {
1877
+ let currentScrollY = window.scrollY;
1878
+
1879
+ if (window.innerHeight <= 900) {
1880
+ if (currentScrollY >= 80) {
1881
+ if (currentScrollY > lastScrollY) {
1882
+ header.style.transform = "translateY(-100%)";
1883
+ header.setAttribute("data-header-scroll", true)
1884
+ } else {
1885
+ header.style.transform = "translateY(0px)";
1886
+ header.setAttribute("data-header-scroll", false)
1887
+ }
1888
+ } else {
1889
+ header.style.transform = "translateY(0)"; // Mostra sempre l'header se il scroll è inferiore a 80px
1890
+ header.setAttribute("data-header-scroll", false)
1891
+ }
1892
+ }
1893
+ lastScrollY = currentScrollY;
1894
+
1895
+ });
1896
+
1897
+ // Ripristina la posizione dell'header quando si esce dalla modalità mobile
1898
+ window.addEventListener("resize", () => {
1899
+ if (window.innerWidth > 768) header.style.transform = "translateY(0)";
1900
+ });
1901
+
1902
+ // MOBILE ACTIVE
1903
+ if (window.innerWidth < 600) {
1904
+ document.querySelector("header").setAttribute("data-header-mobileActive", "true");
1905
+ document.querySelector("[pgs~=header-element]").setAttribute("data-header-mobileActive", "true");
1906
+ }
1907
+
1908
+ /***/ }
1909
+
1910
+ /******/ });
1911
+ /************************************************************************/
1912
+ /******/ // The module cache
1913
+ /******/ var __webpack_module_cache__ = {};
1914
+ /******/
1915
+ /******/ // The require function
1916
+ /******/ function __webpack_require__(moduleId) {
1917
+ /******/ // Check if module is in cache
1918
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
1919
+ /******/ if (cachedModule !== undefined) {
1920
+ /******/ return cachedModule.exports;
1921
+ /******/ }
1922
+ /******/ // Create a new module (and put it into the cache)
1923
+ /******/ var module = __webpack_module_cache__[moduleId] = {
1924
+ /******/ // no module.id needed
1925
+ /******/ // no module.loaded needed
1926
+ /******/ exports: {}
1927
+ /******/ };
1928
+ /******/
1929
+ /******/ // Execute the module function
1930
+ /******/ if (!(moduleId in __webpack_modules__)) {
1931
+ /******/ delete __webpack_module_cache__[moduleId];
1932
+ /******/ var e = new Error("Cannot find module '" + moduleId + "'");
1933
+ /******/ e.code = 'MODULE_NOT_FOUND';
1934
+ /******/ throw e;
1935
+ /******/ }
1936
+ /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
1937
+ /******/
1938
+ /******/ // Return the exports of the module
1939
+ /******/ return module.exports;
1940
+ /******/ }
1941
+ /******/
1942
+ /************************************************************************/
1943
+ /******/ /* webpack/runtime/compat get default export */
1944
+ /******/ (() => {
1945
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
1946
+ /******/ __webpack_require__.n = (module) => {
1947
+ /******/ var getter = module && module.__esModule ?
1948
+ /******/ () => (module['default']) :
1949
+ /******/ () => (module);
1950
+ /******/ __webpack_require__.d(getter, { a: getter });
1951
+ /******/ return getter;
1952
+ /******/ };
1953
+ /******/ })();
1954
+ /******/
1955
+ /******/ /* webpack/runtime/define property getters */
1956
+ /******/ (() => {
1957
+ /******/ // define getter functions for harmony exports
1958
+ /******/ __webpack_require__.d = (exports, definition) => {
1959
+ /******/ for(var key in definition) {
1960
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
1961
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
1962
+ /******/ }
1963
+ /******/ }
1964
+ /******/ };
1965
+ /******/ })();
1966
+ /******/
1967
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
1968
+ /******/ (() => {
1969
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
1970
+ /******/ })();
1971
+ /******/
1972
+ /******/ /* webpack/runtime/make namespace object */
1973
+ /******/ (() => {
1974
+ /******/ // define __esModule on exports
1975
+ /******/ __webpack_require__.r = (exports) => {
1976
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
1977
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1978
+ /******/ }
1979
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
1980
+ /******/ };
1981
+ /******/ })();
1982
+ /******/
1983
+ /************************************************************************/
1984
+ var __webpack_exports__ = {};
1985
+ // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
1986
+ (() => {
1987
+ "use strict";
1988
+ /*!************************************!*\
1989
+ !*** ./assets/javascript/index.js ***!
1990
+ \************************************/
1991
+ __webpack_require__.r(__webpack_exports__);
1992
+ /* harmony import */ var _pgs_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_pgs.js */ "./assets/javascript/_pgs.js");
1993
+ /* harmony import */ var _base_darkmode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base/_darkmode.js */ "./assets/javascript/base/_darkmode.js");
1994
+ /* harmony import */ var _base_darkmode_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_base_darkmode_js__WEBPACK_IMPORTED_MODULE_1__);
1995
+ /* harmony import */ var _base_object_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base/_object.js */ "./assets/javascript/base/_object.js");
1996
+ /* harmony import */ var _base_object_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_base_object_js__WEBPACK_IMPORTED_MODULE_2__);
1997
+ /* harmony import */ var _components_accordion_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/_accordion.js */ "./assets/javascript/components/_accordion.js");
1998
+ /* harmony import */ var _components_accordion_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_components_accordion_js__WEBPACK_IMPORTED_MODULE_3__);
1999
+ /* harmony import */ var _components_dropdown_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/_dropdown.js */ "./assets/javascript/components/_dropdown.js");
2000
+ /* harmony import */ var _components_exeNotifications_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/_exeNotifications.js */ "./assets/javascript/components/_exeNotifications.js");
2001
+ /* harmony import */ var _components_menu_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/_menu.js */ "./assets/javascript/components/_menu.js");
2002
+ /* harmony import */ var _components_modals_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/_modals.js */ "./assets/javascript/components/_modals.js");
2003
+ /* harmony import */ var _components_slides_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/_slides.js */ "./assets/javascript/components/_slides.js");
2004
+ /* harmony import */ var _components_steps_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/_steps.js */ "./assets/javascript/components/_steps.js");
2005
+ /* harmony import */ var _components_tabs_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/_tabs.js */ "./assets/javascript/components/_tabs.js");
2006
+ /* harmony import */ var _patterns_header_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./patterns/_header.js */ "./assets/javascript/patterns/_header.js");
2007
+ /* harmony import */ var _patterns_cookieConsent_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./patterns/_cookieConsent.js */ "./assets/javascript/patterns/_cookieConsent.js");
2008
+ /* harmony import */ var _patterns_cookieConsent_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_patterns_cookieConsent_js__WEBPACK_IMPORTED_MODULE_12__);
2009
+ //= PGS
2010
+
2011
+
2012
+ //= BASE
2013
+
2014
+
2015
+
2016
+ //= CN
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+ //= patterns
2027
+
2028
+
2029
+
2030
+ })();
2031
+
2032
+ /******/ })()
2033
+ ;
2034
+ //# sourceMappingURL=index.js.map