valtech-components 2.0.500 → 2.0.501

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 (30) hide show
  1. package/esm2022/lib/components/atoms/button/button.component.mjs +87 -48
  2. package/esm2022/lib/components/molecules/action-header/action-header.component.mjs +1 -1
  3. package/esm2022/lib/components/molecules/ad-slot/ad-slot.component.mjs +249 -0
  4. package/esm2022/lib/components/molecules/button-group/button-group.component.mjs +1 -1
  5. package/esm2022/lib/components/molecules/card/card.component.mjs +2 -2
  6. package/esm2022/lib/components/molecules/file-input/file-input.component.mjs +1 -1
  7. package/esm2022/lib/components/molecules/raffle-status-card/raffle-status-card.component.mjs +2 -2
  8. package/esm2022/lib/components/organisms/article/article.component.mjs +2 -2
  9. package/esm2022/lib/components/organisms/menu/menu.component.mjs +1 -1
  10. package/esm2022/lib/components/templates/page-template/page-template.component.mjs +1 -1
  11. package/esm2022/lib/services/ads/ads-consent.service.mjs +152 -0
  12. package/esm2022/lib/services/ads/ads-loader.service.mjs +160 -0
  13. package/esm2022/lib/services/ads/ads.service.mjs +449 -0
  14. package/esm2022/lib/services/ads/config.mjs +118 -0
  15. package/esm2022/lib/services/ads/index.mjs +14 -0
  16. package/esm2022/lib/services/ads/types.mjs +23 -0
  17. package/esm2022/public-api.mjs +6 -1
  18. package/fesm2022/valtech-components.mjs +1330 -154
  19. package/fesm2022/valtech-components.mjs.map +1 -1
  20. package/lib/components/atoms/button/button.component.d.ts +30 -6
  21. package/lib/components/molecules/ad-slot/ad-slot.component.d.ts +78 -0
  22. package/lib/components/organisms/article/article.component.d.ts +3 -3
  23. package/lib/services/ads/ads-consent.service.d.ts +59 -0
  24. package/lib/services/ads/ads-loader.service.d.ts +46 -0
  25. package/lib/services/ads/ads.service.d.ts +123 -0
  26. package/lib/services/ads/config.d.ts +69 -0
  27. package/lib/services/ads/index.d.ts +10 -0
  28. package/lib/services/ads/types.d.ts +163 -0
  29. package/package.json +1 -1
  30. package/public-api.d.ts +2 -0
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Ads Consent Service
3
+ *
4
+ * Integra el servicio de Ads con el Consent Mode v2 existente en AnalyticsService.
5
+ * Proporciona estado de consent especifico para ads (advertising).
6
+ */
7
+ import { Injectable, Injector, PLATFORM_ID, inject, signal, computed } from '@angular/core';
8
+ import { isPlatformBrowser } from '@angular/common';
9
+ import * as i0 from "@angular/core";
10
+ /**
11
+ * Servicio que maneja el consent para ads.
12
+ *
13
+ * Se integra con AnalyticsService para reutilizar el estado de consent GDPR.
14
+ * Si AnalyticsService no esta disponible, usa valores por defecto conservadores.
15
+ */
16
+ export class AdsConsentService {
17
+ constructor() {
18
+ this.platformId = inject(PLATFORM_ID);
19
+ this.injector = inject(Injector);
20
+ // Cache del estado de consent
21
+ this._consentState = signal({
22
+ adStorage: false,
23
+ adPersonalization: false,
24
+ adUserData: false,
25
+ });
26
+ /** Estado de consent para ads (readonly) */
27
+ this.adsConsentState = this._consentState.asReadonly();
28
+ /** Indica si se pueden mostrar ads (al menos consent basico) */
29
+ this.canShowAds = computed(() => {
30
+ // Siempre permitimos mostrar ads (pueden ser no personalizados)
31
+ // El control real esta en canPersonalize
32
+ return true;
33
+ });
34
+ /** Indica si se pueden mostrar ads personalizados */
35
+ this.canPersonalize = computed(() => {
36
+ const state = this._consentState();
37
+ return state.adStorage && state.adPersonalization && state.adUserData;
38
+ });
39
+ this.analyticsService = null;
40
+ this.consentSyncInterval = null;
41
+ if (isPlatformBrowser(this.platformId)) {
42
+ this.initializeConsentSync();
43
+ }
44
+ }
45
+ /**
46
+ * Inicializa la sincronizacion con AnalyticsService.
47
+ */
48
+ initializeConsentSync() {
49
+ // Intentar obtener AnalyticsService de forma lazy
50
+ // Usamos setTimeout para dar tiempo a que se inicialice
51
+ setTimeout(() => {
52
+ this.syncWithAnalyticsConsent();
53
+ }, 100);
54
+ // Re-sincronizar periodicamente por si el usuario cambia consent
55
+ this.consentSyncInterval = setInterval(() => {
56
+ this.syncWithAnalyticsConsent();
57
+ }, 5000);
58
+ }
59
+ /**
60
+ * Sincroniza el estado de consent desde AnalyticsService.
61
+ */
62
+ async syncWithAnalyticsConsent() {
63
+ try {
64
+ // Importar AnalyticsService dinamicamente
65
+ const { AnalyticsService } = await import('../firebase/analytics.service');
66
+ if (!this.analyticsService) {
67
+ this.analyticsService = this.injector.get(AnalyticsService, null);
68
+ }
69
+ if (this.analyticsService) {
70
+ // AnalyticsService expone consentState como signal
71
+ const consentState = this.analyticsService.consentState();
72
+ this.updateFromAnalyticsConsent(consentState.settings);
73
+ }
74
+ }
75
+ catch {
76
+ // AnalyticsService no disponible - usar defaults
77
+ this.setDefaultConsent();
78
+ }
79
+ }
80
+ /**
81
+ * Actualiza el estado de consent desde AnalyticsService.
82
+ */
83
+ updateFromAnalyticsConsent(settings) {
84
+ const hasAdvertisingConsent = settings['advertising'] === true;
85
+ this._consentState.set({
86
+ adStorage: hasAdvertisingConsent,
87
+ adPersonalization: hasAdvertisingConsent,
88
+ adUserData: hasAdvertisingConsent,
89
+ });
90
+ }
91
+ /**
92
+ * Establece consent por defecto (sin datos personales).
93
+ */
94
+ setDefaultConsent() {
95
+ this._consentState.set({
96
+ adStorage: false,
97
+ adPersonalization: false,
98
+ adUserData: false,
99
+ });
100
+ }
101
+ /**
102
+ * Actualiza manualmente el consent para ads.
103
+ * Usar cuando el usuario actualiza sus preferencias directamente.
104
+ *
105
+ * @param consent - Nuevo estado de consent parcial
106
+ */
107
+ updateConsent(consent) {
108
+ this._consentState.update((current) => ({
109
+ ...current,
110
+ ...consent,
111
+ }));
112
+ // Notificar a GPT si ya esta cargado
113
+ this.applyConsentToGPT();
114
+ }
115
+ /**
116
+ * Aplica el estado de consent actual a GPT.
117
+ */
118
+ applyConsentToGPT() {
119
+ if (!isPlatformBrowser(this.platformId))
120
+ return;
121
+ const googletag = window.googletag;
122
+ if (!googletag)
123
+ return;
124
+ googletag.cmd.push(() => {
125
+ const canPersonalize = this.canPersonalize();
126
+ // 0 = personalized, 1 = non-personalized
127
+ googletag.pubads().setRequestNonPersonalizedAds(canPersonalize ? 0 : 1);
128
+ });
129
+ }
130
+ /**
131
+ * Obtiene el estado actual de consent.
132
+ */
133
+ getConsentState() {
134
+ return this._consentState();
135
+ }
136
+ /**
137
+ * Destruye el servicio y limpia recursos.
138
+ */
139
+ destroy() {
140
+ if (this.consentSyncInterval) {
141
+ clearInterval(this.consentSyncInterval);
142
+ this.consentSyncInterval = null;
143
+ }
144
+ }
145
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsConsentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
146
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsConsentService, providedIn: 'root' }); }
147
+ }
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsConsentService, decorators: [{
149
+ type: Injectable,
150
+ args: [{ providedIn: 'root' }]
151
+ }], ctorParameters: () => [] });
152
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRzLWNvbnNlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvYWRzL2Fkcy1jb25zZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDcEcsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBR3BEOzs7OztHQUtHO0FBRUgsTUFBTSxPQUFPLGlCQUFpQjtJQThCNUI7UUE3QmlCLGVBQVUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsYUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUU3Qyw4QkFBOEI7UUFDYixrQkFBYSxHQUFHLE1BQU0sQ0FBa0I7WUFDdkQsU0FBUyxFQUFFLEtBQUs7WUFDaEIsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDLENBQUM7UUFFSCw0Q0FBNEM7UUFDbkMsb0JBQWUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRTNELGdFQUFnRTtRQUN2RCxlQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNsQyxnRUFBZ0U7WUFDaEUseUNBQXlDO1lBQ3pDLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7UUFFSCxxREFBcUQ7UUFDNUMsbUJBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ3RDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNuQyxPQUFPLEtBQUssQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDeEUsQ0FBQyxDQUFDLENBQUM7UUFFSyxxQkFBZ0IsR0FBWSxJQUFJLENBQUM7UUFDakMsd0JBQW1CLEdBQTBDLElBQUksQ0FBQztRQUd4RSxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxxQkFBcUI7UUFDM0Isa0RBQWtEO1FBQ2xELHdEQUF3RDtRQUN4RCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDbEMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRVIsaUVBQWlFO1FBQ2pFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQzFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2xDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyx3QkFBd0I7UUFDcEMsSUFBSSxDQUFDO1lBQ0gsMENBQTBDO1lBQzFDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUM7WUFFM0UsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUMzQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDcEUsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzFCLG1EQUFtRDtnQkFDbkQsTUFBTSxZQUFZLEdBQUksSUFBSSxDQUFDLGdCQUE4RixDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN6SSxJQUFJLENBQUMsMEJBQTBCLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3pELENBQUM7UUFDSCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsaURBQWlEO1lBQ2pELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSywwQkFBMEIsQ0FBQyxRQUE2QztRQUM5RSxNQUFNLHFCQUFxQixHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxJQUFJLENBQUM7UUFFL0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDckIsU0FBUyxFQUFFLHFCQUFxQjtZQUNoQyxpQkFBaUIsRUFBRSxxQkFBcUI7WUFDeEMsVUFBVSxFQUFFLHFCQUFxQjtTQUNsQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7WUFDckIsU0FBUyxFQUFFLEtBQUs7WUFDaEIsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxhQUFhLENBQUMsT0FBaUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEMsR0FBRyxPQUFPO1lBQ1YsR0FBRyxPQUFPO1NBQ1gsQ0FBQyxDQUFDLENBQUM7UUFFSixxQ0FBcUM7UUFDckMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsaUJBQWlCO1FBQ2YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7WUFBRSxPQUFPO1FBRWhELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDbkMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPO1FBRXZCLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN0QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDN0MseUNBQXlDO1lBQ3pDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsT0FBTztRQUNMLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0IsYUFBYSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7K0dBbEpVLGlCQUFpQjttSEFBakIsaUJBQWlCLGNBREosTUFBTTs7NEZBQ25CLGlCQUFpQjtrQkFEN0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFkcyBDb25zZW50IFNlcnZpY2VcbiAqXG4gKiBJbnRlZ3JhIGVsIHNlcnZpY2lvIGRlIEFkcyBjb24gZWwgQ29uc2VudCBNb2RlIHYyIGV4aXN0ZW50ZSBlbiBBbmFseXRpY3NTZXJ2aWNlLlxuICogUHJvcG9yY2lvbmEgZXN0YWRvIGRlIGNvbnNlbnQgZXNwZWNpZmljbyBwYXJhIGFkcyAoYWR2ZXJ0aXNpbmcpLlxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUsIEluamVjdG9yLCBQTEFURk9STV9JRCwgaW5qZWN0LCBzaWduYWwsIGNvbXB1dGVkLCBlZmZlY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEFkc0NvbnNlbnRTdGF0ZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIFNlcnZpY2lvIHF1ZSBtYW5lamEgZWwgY29uc2VudCBwYXJhIGFkcy5cbiAqXG4gKiBTZSBpbnRlZ3JhIGNvbiBBbmFseXRpY3NTZXJ2aWNlIHBhcmEgcmV1dGlsaXphciBlbCBlc3RhZG8gZGUgY29uc2VudCBHRFBSLlxuICogU2kgQW5hbHl0aWNzU2VydmljZSBubyBlc3RhIGRpc3BvbmlibGUsIHVzYSB2YWxvcmVzIHBvciBkZWZlY3RvIGNvbnNlcnZhZG9yZXMuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQWRzQ29uc2VudFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtSWQgPSBpbmplY3QoUExBVEZPUk1fSUQpO1xuICBwcml2YXRlIHJlYWRvbmx5IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuICAvLyBDYWNoZSBkZWwgZXN0YWRvIGRlIGNvbnNlbnRcbiAgcHJpdmF0ZSByZWFkb25seSBfY29uc2VudFN0YXRlID0gc2lnbmFsPEFkc0NvbnNlbnRTdGF0ZT4oe1xuICAgIGFkU3RvcmFnZTogZmFsc2UsXG4gICAgYWRQZXJzb25hbGl6YXRpb246IGZhbHNlLFxuICAgIGFkVXNlckRhdGE6IGZhbHNlLFxuICB9KTtcblxuICAvKiogRXN0YWRvIGRlIGNvbnNlbnQgcGFyYSBhZHMgKHJlYWRvbmx5KSAqL1xuICByZWFkb25seSBhZHNDb25zZW50U3RhdGUgPSB0aGlzLl9jb25zZW50U3RhdGUuYXNSZWFkb25seSgpO1xuXG4gIC8qKiBJbmRpY2Egc2kgc2UgcHVlZGVuIG1vc3RyYXIgYWRzIChhbCBtZW5vcyBjb25zZW50IGJhc2ljbykgKi9cbiAgcmVhZG9ubHkgY2FuU2hvd0FkcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAvLyBTaWVtcHJlIHBlcm1pdGltb3MgbW9zdHJhciBhZHMgKHB1ZWRlbiBzZXIgbm8gcGVyc29uYWxpemFkb3MpXG4gICAgLy8gRWwgY29udHJvbCByZWFsIGVzdGEgZW4gY2FuUGVyc29uYWxpemVcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG5cbiAgLyoqIEluZGljYSBzaSBzZSBwdWVkZW4gbW9zdHJhciBhZHMgcGVyc29uYWxpemFkb3MgKi9cbiAgcmVhZG9ubHkgY2FuUGVyc29uYWxpemUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb25zZW50U3RhdGUoKTtcbiAgICByZXR1cm4gc3RhdGUuYWRTdG9yYWdlICYmIHN0YXRlLmFkUGVyc29uYWxpemF0aW9uICYmIHN0YXRlLmFkVXNlckRhdGE7XG4gIH0pO1xuXG4gIHByaXZhdGUgYW5hbHl0aWNzU2VydmljZTogdW5rbm93biA9IG51bGw7XG4gIHByaXZhdGUgY29uc2VudFN5bmNJbnRlcnZhbDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUNvbnNlbnRTeW5jKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaWNpYWxpemEgbGEgc2luY3Jvbml6YWNpb24gY29uIEFuYWx5dGljc1NlcnZpY2UuXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVDb25zZW50U3luYygpOiB2b2lkIHtcbiAgICAvLyBJbnRlbnRhciBvYnRlbmVyIEFuYWx5dGljc1NlcnZpY2UgZGUgZm9ybWEgbGF6eVxuICAgIC8vIFVzYW1vcyBzZXRUaW1lb3V0IHBhcmEgZGFyIHRpZW1wbyBhIHF1ZSBzZSBpbmljaWFsaWNlXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN5bmNXaXRoQW5hbHl0aWNzQ29uc2VudCgpO1xuICAgIH0sIDEwMCk7XG5cbiAgICAvLyBSZS1zaW5jcm9uaXphciBwZXJpb2RpY2FtZW50ZSBwb3Igc2kgZWwgdXN1YXJpbyBjYW1iaWEgY29uc2VudFxuICAgIHRoaXMuY29uc2VudFN5bmNJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHRoaXMuc3luY1dpdGhBbmFseXRpY3NDb25zZW50KCk7XG4gICAgfSwgNTAwMCk7XG4gIH1cblxuICAvKipcbiAgICogU2luY3Jvbml6YSBlbCBlc3RhZG8gZGUgY29uc2VudCBkZXNkZSBBbmFseXRpY3NTZXJ2aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzeW5jV2l0aEFuYWx5dGljc0NvbnNlbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEltcG9ydGFyIEFuYWx5dGljc1NlcnZpY2UgZGluYW1pY2FtZW50ZVxuICAgICAgY29uc3QgeyBBbmFseXRpY3NTZXJ2aWNlIH0gPSBhd2FpdCBpbXBvcnQoJy4uL2ZpcmViYXNlL2FuYWx5dGljcy5zZXJ2aWNlJyk7XG5cbiAgICAgIGlmICghdGhpcy5hbmFseXRpY3NTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuYW5hbHl0aWNzU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KEFuYWx5dGljc1NlcnZpY2UsIG51bGwpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hbmFseXRpY3NTZXJ2aWNlKSB7XG4gICAgICAgIC8vIEFuYWx5dGljc1NlcnZpY2UgZXhwb25lIGNvbnNlbnRTdGF0ZSBjb21vIHNpZ25hbFxuICAgICAgICBjb25zdCBjb25zZW50U3RhdGUgPSAodGhpcy5hbmFseXRpY3NTZXJ2aWNlIGFzIHsgY29uc2VudFN0YXRlOiAoKSA9PiB7IHNldHRpbmdzOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuIHwgdW5kZWZpbmVkPiB9IH0pLmNvbnNlbnRTdGF0ZSgpO1xuICAgICAgICB0aGlzLnVwZGF0ZUZyb21BbmFseXRpY3NDb25zZW50KGNvbnNlbnRTdGF0ZS5zZXR0aW5ncyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBBbmFseXRpY3NTZXJ2aWNlIG5vIGRpc3BvbmlibGUgLSB1c2FyIGRlZmF1bHRzXG4gICAgICB0aGlzLnNldERlZmF1bHRDb25zZW50KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFjdHVhbGl6YSBlbCBlc3RhZG8gZGUgY29uc2VudCBkZXNkZSBBbmFseXRpY3NTZXJ2aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVGcm9tQW5hbHl0aWNzQ29uc2VudChzZXR0aW5nczogUmVjb3JkPHN0cmluZywgYm9vbGVhbiB8IHVuZGVmaW5lZD4pOiB2b2lkIHtcbiAgICBjb25zdCBoYXNBZHZlcnRpc2luZ0NvbnNlbnQgPSBzZXR0aW5nc1snYWR2ZXJ0aXNpbmcnXSA9PT0gdHJ1ZTtcblxuICAgIHRoaXMuX2NvbnNlbnRTdGF0ZS5zZXQoe1xuICAgICAgYWRTdG9yYWdlOiBoYXNBZHZlcnRpc2luZ0NvbnNlbnQsXG4gICAgICBhZFBlcnNvbmFsaXphdGlvbjogaGFzQWR2ZXJ0aXNpbmdDb25zZW50LFxuICAgICAgYWRVc2VyRGF0YTogaGFzQWR2ZXJ0aXNpbmdDb25zZW50LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVzdGFibGVjZSBjb25zZW50IHBvciBkZWZlY3RvIChzaW4gZGF0b3MgcGVyc29uYWxlcykuXG4gICAqL1xuICBwcml2YXRlIHNldERlZmF1bHRDb25zZW50KCk6IHZvaWQge1xuICAgIHRoaXMuX2NvbnNlbnRTdGF0ZS5zZXQoe1xuICAgICAgYWRTdG9yYWdlOiBmYWxzZSxcbiAgICAgIGFkUGVyc29uYWxpemF0aW9uOiBmYWxzZSxcbiAgICAgIGFkVXNlckRhdGE6IGZhbHNlLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdHVhbGl6YSBtYW51YWxtZW50ZSBlbCBjb25zZW50IHBhcmEgYWRzLlxuICAgKiBVc2FyIGN1YW5kbyBlbCB1c3VhcmlvIGFjdHVhbGl6YSBzdXMgcHJlZmVyZW5jaWFzIGRpcmVjdGFtZW50ZS5cbiAgICpcbiAgICogQHBhcmFtIGNvbnNlbnQgLSBOdWV2byBlc3RhZG8gZGUgY29uc2VudCBwYXJjaWFsXG4gICAqL1xuICB1cGRhdGVDb25zZW50KGNvbnNlbnQ6IFBhcnRpYWw8QWRzQ29uc2VudFN0YXRlPik6IHZvaWQge1xuICAgIHRoaXMuX2NvbnNlbnRTdGF0ZS51cGRhdGUoKGN1cnJlbnQpID0+ICh7XG4gICAgICAuLi5jdXJyZW50LFxuICAgICAgLi4uY29uc2VudCxcbiAgICB9KSk7XG5cbiAgICAvLyBOb3RpZmljYXIgYSBHUFQgc2kgeWEgZXN0YSBjYXJnYWRvXG4gICAgdGhpcy5hcHBseUNvbnNlbnRUb0dQVCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwbGljYSBlbCBlc3RhZG8gZGUgY29uc2VudCBhY3R1YWwgYSBHUFQuXG4gICAqL1xuICBhcHBseUNvbnNlbnRUb0dQVCgpOiB2b2lkIHtcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHJldHVybjtcblxuICAgIGNvbnN0IGdvb2dsZXRhZyA9IHdpbmRvdy5nb29nbGV0YWc7XG4gICAgaWYgKCFnb29nbGV0YWcpIHJldHVybjtcblxuICAgIGdvb2dsZXRhZy5jbWQucHVzaCgoKSA9PiB7XG4gICAgICBjb25zdCBjYW5QZXJzb25hbGl6ZSA9IHRoaXMuY2FuUGVyc29uYWxpemUoKTtcbiAgICAgIC8vIDAgPSBwZXJzb25hbGl6ZWQsIDEgPSBub24tcGVyc29uYWxpemVkXG4gICAgICBnb29nbGV0YWcucHViYWRzKCkuc2V0UmVxdWVzdE5vblBlcnNvbmFsaXplZEFkcyhjYW5QZXJzb25hbGl6ZSA/IDAgOiAxKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPYnRpZW5lIGVsIGVzdGFkbyBhY3R1YWwgZGUgY29uc2VudC5cbiAgICovXG4gIGdldENvbnNlbnRTdGF0ZSgpOiBBZHNDb25zZW50U3RhdGUge1xuICAgIHJldHVybiB0aGlzLl9jb25zZW50U3RhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cnV5ZSBlbCBzZXJ2aWNpbyB5IGxpbXBpYSByZWN1cnNvcy5cbiAgICovXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29uc2VudFN5bmNJbnRlcnZhbCkge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNvbnNlbnRTeW5jSW50ZXJ2YWwpO1xuICAgICAgdGhpcy5jb25zZW50U3luY0ludGVydmFsID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Ads Loader Service
3
+ *
4
+ * Maneja la carga lazy del script GPT (Google Publisher Tag).
5
+ * Solo carga el script cuando se necesita el primer ad.
6
+ */
7
+ import { Injectable, Inject, PLATFORM_ID, signal } from '@angular/core';
8
+ import { isPlatformBrowser } from '@angular/common';
9
+ import { VALTECH_ADS_CONFIG } from './config';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "./ads-consent.service";
12
+ /** URL del script GPT */
13
+ const GPT_SCRIPT_URL = 'https://securepubads.g.doubleclick.net/tag/js/gpt.js';
14
+ /**
15
+ * Servicio para cargar el script de Google Publisher Tags.
16
+ *
17
+ * Implementa lazy loading: el script solo se carga cuando
18
+ * se solicita renderizar el primer ad slot.
19
+ */
20
+ export class AdsLoaderService {
21
+ constructor(config, platformId, consentService) {
22
+ this.config = config;
23
+ this.platformId = platformId;
24
+ this.consentService = consentService;
25
+ this._isLoading = signal(false);
26
+ this._isLoaded = signal(false);
27
+ this._error = signal(null);
28
+ /** Indica si el script esta cargando */
29
+ this.isLoading = this._isLoading.asReadonly();
30
+ /** Indica si el script esta cargado */
31
+ this.isLoaded = this._isLoaded.asReadonly();
32
+ /** Error de carga (si existe) */
33
+ this.error = this._error.asReadonly();
34
+ this.loadPromise = null;
35
+ }
36
+ /**
37
+ * Carga el script GPT de forma lazy.
38
+ * Retorna la instancia de googletag o null si falla.
39
+ *
40
+ * @returns Promise con googletag o null
41
+ */
42
+ loadGPT() {
43
+ // SSR check
44
+ if (!isPlatformBrowser(this.platformId)) {
45
+ return Promise.resolve(null);
46
+ }
47
+ // Ya cargado
48
+ if (this._isLoaded() && window.googletag) {
49
+ return Promise.resolve(window.googletag);
50
+ }
51
+ // Ya hay una carga en progreso
52
+ if (this.loadPromise) {
53
+ return this.loadPromise;
54
+ }
55
+ this._isLoading.set(true);
56
+ this._error.set(null);
57
+ this.loadPromise = new Promise((resolve) => {
58
+ // Inicializar cmd queue
59
+ window.googletag = window.googletag || { cmd: [] };
60
+ const googletag = window.googletag;
61
+ // Crear script
62
+ const script = document.createElement('script');
63
+ script.async = true;
64
+ script.src = GPT_SCRIPT_URL;
65
+ script.onload = () => {
66
+ googletag.cmd.push(() => {
67
+ this.configureGPT(googletag);
68
+ this._isLoaded.set(true);
69
+ this._isLoading.set(false);
70
+ if (this.config.debugMode) {
71
+ console.log('[ValtechAds] Script GPT cargado y configurado');
72
+ }
73
+ resolve(googletag);
74
+ });
75
+ };
76
+ script.onerror = (error) => {
77
+ console.error('[ValtechAds] Error cargando GPT:', error);
78
+ this._error.set(new Error('Error cargando Google Publisher Tag'));
79
+ this._isLoading.set(false);
80
+ this.loadPromise = null;
81
+ resolve(null);
82
+ };
83
+ // Insertar script
84
+ const firstScript = document.getElementsByTagName('script')[0];
85
+ firstScript.parentNode?.insertBefore(script, firstScript);
86
+ });
87
+ return this.loadPromise;
88
+ }
89
+ /**
90
+ * Configura GPT con las opciones de la aplicacion.
91
+ */
92
+ configureGPT(googletag) {
93
+ const pubads = googletag.pubads();
94
+ // Single Request Architecture para mejor performance
95
+ pubads.enableSingleRequest();
96
+ // Colapsar divs vacios antes de fetch
97
+ pubads.collapseEmptyDivs(true);
98
+ // Lazy loading nativo de GPT
99
+ if (this.config.lazyLoad && this.config.lazyLoadConfig) {
100
+ pubads.enableLazyLoad({
101
+ fetchMarginPercent: this.config.lazyLoadConfig.fetchMarginPercent,
102
+ renderMarginPercent: this.config.lazyLoadConfig.renderMarginPercent,
103
+ mobileScaling: 2.0,
104
+ });
105
+ }
106
+ // Targeting global
107
+ if (this.config.globalTargeting) {
108
+ for (const [key, value] of Object.entries(this.config.globalTargeting)) {
109
+ pubads.setTargeting(key, value);
110
+ }
111
+ }
112
+ // Non-personalized ads segun consent
113
+ if (!this.consentService.canPersonalize()) {
114
+ pubads.setRequestNonPersonalizedAds(1);
115
+ }
116
+ // Event listeners
117
+ pubads.addEventListener('slotRenderEnded', (event) => {
118
+ const slotId = event.slot.getSlotElementId();
119
+ if (this.config.debugMode) {
120
+ console.log(`[ValtechAds] Slot ${slotId} rendered, empty: ${event.isEmpty}`);
121
+ }
122
+ });
123
+ // Debug mode
124
+ if (this.config.debugMode) {
125
+ console.log('[ValtechAds] GPT configurado:', {
126
+ lazyLoad: this.config.lazyLoad,
127
+ personalized: this.consentService.canPersonalize(),
128
+ targeting: this.config.globalTargeting,
129
+ });
130
+ }
131
+ }
132
+ /**
133
+ * Verifica si el script GPT esta disponible.
134
+ */
135
+ isGPTAvailable() {
136
+ return isPlatformBrowser(this.platformId) && !!window.googletag && this._isLoaded();
137
+ }
138
+ /**
139
+ * Obtiene la instancia de googletag si esta cargada.
140
+ */
141
+ getGPT() {
142
+ if (this.isGPTAvailable()) {
143
+ return window.googletag;
144
+ }
145
+ return null;
146
+ }
147
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsLoaderService, deps: [{ token: VALTECH_ADS_CONFIG }, { token: PLATFORM_ID }, { token: i1.AdsConsentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
148
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsLoaderService, providedIn: 'root' }); }
149
+ }
150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AdsLoaderService, decorators: [{
151
+ type: Injectable,
152
+ args: [{ providedIn: 'root' }]
153
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
154
+ type: Inject,
155
+ args: [VALTECH_ADS_CONFIG]
156
+ }] }, { type: Object, decorators: [{
157
+ type: Inject,
158
+ args: [PLATFORM_ID]
159
+ }] }, { type: i1.AdsConsentService }] });
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRzLWxvYWRlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hZHMvYWRzLWxvYWRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxVQUFVLENBQUM7OztBQUk5Qyx5QkFBeUI7QUFDekIsTUFBTSxjQUFjLEdBQUcsc0RBQXNELENBQUM7QUFFOUU7Ozs7O0dBS0c7QUFFSCxNQUFNLE9BQU8sZ0JBQWdCO0lBZ0IzQixZQUNzQyxNQUF3QixFQUMvQixVQUFrQixFQUN2QyxjQUFpQztRQUZMLFdBQU0sR0FBTixNQUFNLENBQWtCO1FBQy9CLGVBQVUsR0FBVixVQUFVLENBQVE7UUFDdkMsbUJBQWMsR0FBZCxjQUFjLENBQW1CO1FBbEIxQixlQUFVLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLGNBQVMsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDbkMsV0FBTSxHQUFHLE1BQU0sQ0FBZSxJQUFJLENBQUMsQ0FBQztRQUVyRCx3Q0FBd0M7UUFDL0IsY0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFbEQsdUNBQXVDO1FBQzlCLGFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWhELGlDQUFpQztRQUN4QixVQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVsQyxnQkFBVyxHQUF3QyxJQUFJLENBQUM7SUFNN0QsQ0FBQztJQUVKOzs7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QUUsQ0FBQztnQkFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsTUFBTSxxQkFBcUIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDL0UsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsYUFBYTtRQUNiLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixFQUFFO2dCQUMzQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO2dCQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLEVBQUU7Z0JBQ2xELFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWU7YUFDdkMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILGNBQWM7UUFDWixPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDdEYsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNKLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7WUFDMUIsT0FBTyxNQUFNLENBQUMsU0FBVSxDQUFDO1FBQzNCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7K0dBekpVLGdCQUFnQixrQkFpQmpCLGtCQUFrQixhQUNsQixXQUFXO21IQWxCVixnQkFBZ0IsY0FESCxNQUFNOzs0RkFDbkIsZ0JBQWdCO2tCQUQ1QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBa0I3QixNQUFNOzJCQUFDLGtCQUFrQjs7MEJBQ3pCLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQWRzIExvYWRlciBTZXJ2aWNlXG4gKlxuICogTWFuZWphIGxhIGNhcmdhIGxhenkgZGVsIHNjcmlwdCBHUFQgKEdvb2dsZSBQdWJsaXNoZXIgVGFnKS5cbiAqIFNvbG8gY2FyZ2EgZWwgc2NyaXB0IGN1YW5kbyBzZSBuZWNlc2l0YSBlbCBwcmltZXIgYWQuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0LCBQTEFURk9STV9JRCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmltcG9ydCB7IFZBTFRFQ0hfQURTX0NPTkZJRyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IFZhbHRlY2hBZHNDb25maWcsIEdQVE5hbWVzcGFjZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQWRzQ29uc2VudFNlcnZpY2UgfSBmcm9tICcuL2Fkcy1jb25zZW50LnNlcnZpY2UnO1xuXG4vKiogVVJMIGRlbCBzY3JpcHQgR1BUICovXG5jb25zdCBHUFRfU0NSSVBUX1VSTCA9ICdodHRwczovL3NlY3VyZXB1YmFkcy5nLmRvdWJsZWNsaWNrLm5ldC90YWcvanMvZ3B0LmpzJztcblxuLyoqXG4gKiBTZXJ2aWNpbyBwYXJhIGNhcmdhciBlbCBzY3JpcHQgZGUgR29vZ2xlIFB1Ymxpc2hlciBUYWdzLlxuICpcbiAqIEltcGxlbWVudGEgbGF6eSBsb2FkaW5nOiBlbCBzY3JpcHQgc29sbyBzZSBjYXJnYSBjdWFuZG9cbiAqIHNlIHNvbGljaXRhIHJlbmRlcml6YXIgZWwgcHJpbWVyIGFkIHNsb3QuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQWRzTG9hZGVyU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2lzTG9hZGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2lzTG9hZGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZXJyb3IgPSBzaWduYWw8RXJyb3IgfCBudWxsPihudWxsKTtcblxuICAvKiogSW5kaWNhIHNpIGVsIHNjcmlwdCBlc3RhIGNhcmdhbmRvICovXG4gIHJlYWRvbmx5IGlzTG9hZGluZyA9IHRoaXMuX2lzTG9hZGluZy5hc1JlYWRvbmx5KCk7XG5cbiAgLyoqIEluZGljYSBzaSBlbCBzY3JpcHQgZXN0YSBjYXJnYWRvICovXG4gIHJlYWRvbmx5IGlzTG9hZGVkID0gdGhpcy5faXNMb2FkZWQuYXNSZWFkb25seSgpO1xuXG4gIC8qKiBFcnJvciBkZSBjYXJnYSAoc2kgZXhpc3RlKSAqL1xuICByZWFkb25seSBlcnJvciA9IHRoaXMuX2Vycm9yLmFzUmVhZG9ubHkoKTtcblxuICBwcml2YXRlIGxvYWRQcm9taXNlOiBQcm9taXNlPEdQVE5hbWVzcGFjZSB8IG51bGw+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWQUxURUNIX0FEU19DT05GSUcpIHByaXZhdGUgY29uZmlnOiBWYWx0ZWNoQWRzQ29uZmlnLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIHByaXZhdGUgY29uc2VudFNlcnZpY2U6IEFkc0NvbnNlbnRTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogQ2FyZ2EgZWwgc2NyaXB0IEdQVCBkZSBmb3JtYSBsYXp5LlxuICAgKiBSZXRvcm5hIGxhIGluc3RhbmNpYSBkZSBnb29nbGV0YWcgbyBudWxsIHNpIGZhbGxhLlxuICAgKlxuICAgKiBAcmV0dXJucyBQcm9taXNlIGNvbiBnb29nbGV0YWcgbyBudWxsXG4gICAqL1xuICBsb2FkR1BUKCk6IFByb21pc2U8R1BUTmFtZXNwYWNlIHwgbnVsbD4ge1xuICAgIC8vIFNTUiBjaGVja1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG5cbiAgICAvLyBZYSBjYXJnYWRvXG4gICAgaWYgKHRoaXMuX2lzTG9hZGVkKCkgJiYgd2luZG93Lmdvb2dsZXRhZykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh3aW5kb3cuZ29vZ2xldGFnKTtcbiAgICB9XG5cbiAgICAvLyBZYSBoYXkgdW5hIGNhcmdhIGVuIHByb2dyZXNvXG4gICAgaWYgKHRoaXMubG9hZFByb21pc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLmxvYWRQcm9taXNlO1xuICAgIH1cblxuICAgIHRoaXMuX2lzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5fZXJyb3Iuc2V0KG51bGwpO1xuXG4gICAgdGhpcy5sb2FkUHJvbWlzZSA9IG5ldyBQcm9taXNlPEdQVE5hbWVzcGFjZSB8IG51bGw+KChyZXNvbHZlKSA9PiB7XG4gICAgICAvLyBJbmljaWFsaXphciBjbWQgcXVldWVcbiAgICAgIHdpbmRvdy5nb29nbGV0YWcgPSB3aW5kb3cuZ29vZ2xldGFnIHx8ICh7IGNtZDogW10gfSBhcyBHUFROYW1lc3BhY2UpO1xuICAgICAgY29uc3QgZ29vZ2xldGFnID0gd2luZG93Lmdvb2dsZXRhZztcblxuICAgICAgLy8gQ3JlYXIgc2NyaXB0XG4gICAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gICAgICBzY3JpcHQuc3JjID0gR1BUX1NDUklQVF9VUkw7XG5cbiAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGdvb2dsZXRhZy5jbWQucHVzaCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb25maWd1cmVHUFQoZ29vZ2xldGFnKTtcbiAgICAgICAgICB0aGlzLl9pc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5faXNMb2FkaW5nLnNldChmYWxzZSk7XG5cbiAgICAgICAgICBpZiAodGhpcy5jb25maWcuZGVidWdNb2RlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW1ZhbHRlY2hBZHNdIFNjcmlwdCBHUFQgY2FyZ2FkbyB5IGNvbmZpZ3VyYWRvJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZShnb29nbGV0YWcpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIHNjcmlwdC5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tWYWx0ZWNoQWRzXSBFcnJvciBjYXJnYW5kbyBHUFQ6JywgZXJyb3IpO1xuICAgICAgICB0aGlzLl9lcnJvci5zZXQobmV3IEVycm9yKCdFcnJvciBjYXJnYW5kbyBHb29nbGUgUHVibGlzaGVyIFRhZycpKTtcbiAgICAgICAgdGhpcy5faXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMubG9hZFByb21pc2UgPSBudWxsO1xuICAgICAgICByZXNvbHZlKG51bGwpO1xuICAgICAgfTtcblxuICAgICAgLy8gSW5zZXJ0YXIgc2NyaXB0XG4gICAgICBjb25zdCBmaXJzdFNjcmlwdCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzY3JpcHQnKVswXTtcbiAgICAgIGZpcnN0U2NyaXB0LnBhcmVudE5vZGU/Lmluc2VydEJlZm9yZShzY3JpcHQsIGZpcnN0U2NyaXB0KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmxvYWRQcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYSBHUFQgY29uIGxhcyBvcGNpb25lcyBkZSBsYSBhcGxpY2FjaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25maWd1cmVHUFQoZ29vZ2xldGFnOiBHUFROYW1lc3BhY2UpOiB2b2lkIHtcbiAgICBjb25zdCBwdWJhZHMgPSBnb29nbGV0YWcucHViYWRzKCk7XG5cbiAgICAvLyBTaW5nbGUgUmVxdWVzdCBBcmNoaXRlY3R1cmUgcGFyYSBtZWpvciBwZXJmb3JtYW5jZVxuICAgIHB1YmFkcy5lbmFibGVTaW5nbGVSZXF1ZXN0KCk7XG5cbiAgICAvLyBDb2xhcHNhciBkaXZzIHZhY2lvcyBhbnRlcyBkZSBmZXRjaFxuICAgIHB1YmFkcy5jb2xsYXBzZUVtcHR5RGl2cyh0cnVlKTtcblxuICAgIC8vIExhenkgbG9hZGluZyBuYXRpdm8gZGUgR1BUXG4gICAgaWYgKHRoaXMuY29uZmlnLmxhenlMb2FkICYmIHRoaXMuY29uZmlnLmxhenlMb2FkQ29uZmlnKSB7XG4gICAgICBwdWJhZHMuZW5hYmxlTGF6eUxvYWQoe1xuICAgICAgICBmZXRjaE1hcmdpblBlcmNlbnQ6IHRoaXMuY29uZmlnLmxhenlMb2FkQ29uZmlnLmZldGNoTWFyZ2luUGVyY2VudCxcbiAgICAgICAgcmVuZGVyTWFyZ2luUGVyY2VudDogdGhpcy5jb25maWcubGF6eUxvYWRDb25maWcucmVuZGVyTWFyZ2luUGVyY2VudCxcbiAgICAgICAgbW9iaWxlU2NhbGluZzogMi4wLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVGFyZ2V0aW5nIGdsb2JhbFxuICAgIGlmICh0aGlzLmNvbmZpZy5nbG9iYWxUYXJnZXRpbmcpIHtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY29uZmlnLmdsb2JhbFRhcmdldGluZykpIHtcbiAgICAgICAgcHViYWRzLnNldFRhcmdldGluZyhrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOb24tcGVyc29uYWxpemVkIGFkcyBzZWd1biBjb25zZW50XG4gICAgaWYgKCF0aGlzLmNvbnNlbnRTZXJ2aWNlLmNhblBlcnNvbmFsaXplKCkpIHtcbiAgICAgIHB1YmFkcy5zZXRSZXF1ZXN0Tm9uUGVyc29uYWxpemVkQWRzKDEpO1xuICAgIH1cblxuICAgIC8vIEV2ZW50IGxpc3RlbmVyc1xuICAgIHB1YmFkcy5hZGRFdmVudExpc3RlbmVyKCdzbG90UmVuZGVyRW5kZWQnLCAoZXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IHNsb3RJZCA9IGV2ZW50LnNsb3QuZ2V0U2xvdEVsZW1lbnRJZCgpO1xuICAgICAgaWYgKHRoaXMuY29uZmlnLmRlYnVnTW9kZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgW1ZhbHRlY2hBZHNdIFNsb3QgJHtzbG90SWR9IHJlbmRlcmVkLCBlbXB0eTogJHtldmVudC5pc0VtcHR5fWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gRGVidWcgbW9kZVxuICAgIGlmICh0aGlzLmNvbmZpZy5kZWJ1Z01vZGUpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdbVmFsdGVjaEFkc10gR1BUIGNvbmZpZ3VyYWRvOicsIHtcbiAgICAgICAgbGF6eUxvYWQ6IHRoaXMuY29uZmlnLmxhenlMb2FkLFxuICAgICAgICBwZXJzb25hbGl6ZWQ6IHRoaXMuY29uc2VudFNlcnZpY2UuY2FuUGVyc29uYWxpemUoKSxcbiAgICAgICAgdGFyZ2V0aW5nOiB0aGlzLmNvbmZpZy5nbG9iYWxUYXJnZXRpbmcsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpY2Egc2kgZWwgc2NyaXB0IEdQVCBlc3RhIGRpc3BvbmlibGUuXG4gICAqL1xuICBpc0dQVEF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSAmJiAhIXdpbmRvdy5nb29nbGV0YWcgJiYgdGhpcy5faXNMb2FkZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPYnRpZW5lIGxhIGluc3RhbmNpYSBkZSBnb29nbGV0YWcgc2kgZXN0YSBjYXJnYWRhLlxuICAgKi9cbiAgZ2V0R1BUKCk6IEdQVE5hbWVzcGFjZSB8IG51bGwge1xuICAgIGlmICh0aGlzLmlzR1BUQXZhaWxhYmxlKCkpIHtcbiAgICAgIHJldHVybiB3aW5kb3cuZ29vZ2xldGFnITtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiJdfQ==