valtech-components 4.0.969 → 4.0.971

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 (29) hide show
  1. package/esm2022/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.component.mjs +153 -0
  2. package/esm2022/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.i18n.mjs +25 -0
  3. package/esm2022/lib/components/organisms/comms-preferences-settings/types.mjs +2 -0
  4. package/esm2022/lib/components/organisms/page-block/page-block.component.mjs +254 -0
  5. package/esm2022/lib/components/organisms/page-block/types.mjs +20 -0
  6. package/esm2022/lib/components/organisms/video-player/types.mjs +12 -0
  7. package/esm2022/lib/components/organisms/video-player/video-player.component.mjs +235 -0
  8. package/esm2022/lib/services/comms-preferences/comms-preferences.service.mjs +38 -0
  9. package/esm2022/lib/services/comms-preferences/config.mjs +18 -0
  10. package/esm2022/lib/services/comms-preferences/index.mjs +4 -0
  11. package/esm2022/lib/services/comms-preferences/types.mjs +2 -0
  12. package/esm2022/lib/version.mjs +2 -2
  13. package/esm2022/public-api.mjs +13 -1
  14. package/fesm2022/valtech-components.mjs +780 -63
  15. package/fesm2022/valtech-components.mjs.map +1 -1
  16. package/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.component.d.ts +29 -0
  17. package/lib/components/organisms/comms-preferences-settings/comms-preferences-settings.i18n.d.ts +24 -0
  18. package/lib/components/organisms/comms-preferences-settings/types.d.ts +4 -0
  19. package/lib/components/organisms/page-block/page-block.component.d.ts +65 -0
  20. package/lib/components/organisms/page-block/types.d.ts +102 -0
  21. package/lib/components/organisms/video-player/types.d.ts +45 -0
  22. package/lib/components/organisms/video-player/video-player.component.d.ts +42 -0
  23. package/lib/services/comms-preferences/comms-preferences.service.d.ts +15 -0
  24. package/lib/services/comms-preferences/config.d.ts +14 -0
  25. package/lib/services/comms-preferences/index.d.ts +3 -0
  26. package/lib/services/comms-preferences/types.d.ts +21 -0
  27. package/lib/version.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/public-api.d.ts +7 -0
@@ -67,7 +67,7 @@ import fixWebmDuration from 'fix-webm-duration';
67
67
  * Current version of valtech-components.
68
68
  * This is automatically updated during the publish process.
69
69
  */
70
- const VERSION = '4.0.969';
70
+ const VERSION = '4.0.971';
71
71
 
72
72
  function evaluateValtechAccess(rule, context, features = {}, visitedFeatures = new Set()) {
73
73
  if (rule == null)
@@ -35106,7 +35106,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
35106
35106
  type: Output
35107
35107
  }] } });
35108
35108
 
35109
- const DEFAULT_NAMESPACE$n = 'PermissionSelector';
35109
+ const DEFAULT_NAMESPACE$o = 'PermissionSelector';
35110
35110
  const PERMISSION_SELECTOR_I18N = {
35111
35111
  es: {
35112
35112
  selectAll: 'Todo',
@@ -35175,7 +35175,7 @@ class PermissionSelectorComponent {
35175
35175
  };
35176
35176
  });
35177
35177
  });
35178
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$n, PERMISSION_SELECTOR_I18N);
35178
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$o, PERMISSION_SELECTOR_I18N);
35179
35179
  }
35180
35180
  toggleAction(code) {
35181
35181
  const sel = new Set(this.selected());
@@ -35201,7 +35201,7 @@ class PermissionSelectorComponent {
35201
35201
  }
35202
35202
  tt(key) {
35203
35203
  this.i18n.lang();
35204
- return this.i18n.t(key, DEFAULT_NAMESPACE$n);
35204
+ return this.i18n.t(key, DEFAULT_NAMESPACE$o);
35205
35205
  }
35206
35206
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PermissionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
35207
35207
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PermissionSelectorComponent, isStandalone: true, selector: "val-permission-selector", inputs: { permissions: { classPropertyName: "permissions", publicName: "permissions", isSignal: true, isRequired: false, transformFunction: null }, actionLabels: { classPropertyName: "actionLabels", publicName: "actionLabels", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, ngImport: i0, template: `
@@ -38191,7 +38191,7 @@ const ACCESS_REQUEST_VIEW_I18N = {
38191
38191
  },
38192
38192
  };
38193
38193
 
38194
- const DEFAULT_NAMESPACE$m = 'AccessRequest';
38194
+ const DEFAULT_NAMESPACE$n = 'AccessRequest';
38195
38195
  /** Tipo de solicitud con que se registran estas peticiones. */
38196
38196
  const ACCESS_REQUEST_TYPE = 'access-request';
38197
38197
  /**
@@ -38215,7 +38215,7 @@ class AccessRequestViewComponent {
38215
38215
  this.requests = inject(RequestService);
38216
38216
  this.errors = inject(ValtechErrorService);
38217
38217
  /** Namespace i18n, por si una app quiere su propia redacción. */
38218
- this.i18nNamespace = DEFAULT_NAMESPACE$m;
38218
+ this.i18nNamespace = DEFAULT_NAMESPACE$n;
38219
38219
  /** Se emite cuando la solicitud quedó registrada. */
38220
38220
  this.requested = new EventEmitter();
38221
38221
  this.sending = signal(false);
@@ -38290,7 +38290,7 @@ class AccessRequestViewComponent {
38290
38290
  actions: submitButton,
38291
38291
  };
38292
38292
  });
38293
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$m, ACCESS_REQUEST_VIEW_I18N);
38293
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$n, ACCESS_REQUEST_VIEW_I18N);
38294
38294
  }
38295
38295
  ngOnInit() {
38296
38296
  this.i18n.registerDefaults(this.i18nNamespace, ACCESS_REQUEST_VIEW_I18N);
@@ -53435,7 +53435,7 @@ const PROFILE_VIEW_I18N = {
53435
53435
  const HANDLE_PATTERN = /^[a-z_][a-z0-9_]*$/;
53436
53436
  const HANDLE_MIN = 3;
53437
53437
  const HANDLE_MAX = 20;
53438
- const DEFAULT_NAMESPACE$l = 'Settings.Profile';
53438
+ const DEFAULT_NAMESPACE$m = 'Settings.Profile';
53439
53439
  /**
53440
53440
  * `val-profile-content` — CONTENIDO del perfil (avatar + handle + nombre + teléfono
53441
53441
  * en un form con un botón). Presentacional + lógica de datos, SIN cromática de
@@ -53469,7 +53469,7 @@ class ProfileContentComponent {
53469
53469
  showPhone: merged.showPhone ?? true,
53470
53470
  showShareCta: merged.showShareCta ?? true,
53471
53471
  profileBaseUrl: merged.profileBaseUrl ?? '',
53472
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$l,
53472
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$m,
53473
53473
  onSaved: merged.onSaved,
53474
53474
  onAvatarUploaded: merged.onAvatarUploaded,
53475
53475
  };
@@ -54021,7 +54021,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
54021
54021
  type: Input
54022
54022
  }] } });
54023
54023
 
54024
- const DEFAULT_NAMESPACE$k = 'Settings.Profile';
54024
+ const DEFAULT_NAMESPACE$l = 'Settings.Profile';
54025
54025
  /**
54026
54026
  * `val-profile-view` — vista Perfil ruteada (organism). Wrapper delgado:
54027
54027
  * configura el header del shell (`NavigationService.setBackHeader`) y delega TODO
@@ -54040,7 +54040,7 @@ class ProfileViewComponent {
54040
54040
  this.route = inject(ActivatedRoute, { optional: true });
54041
54041
  this.ns = computed(() => {
54042
54042
  const fromRoute = (this.route?.snapshot.data['profileConfig'] ?? {});
54043
- return this.config?.i18nNamespace ?? fromRoute.i18nNamespace ?? DEFAULT_NAMESPACE$k;
54043
+ return this.config?.i18nNamespace ?? fromRoute.i18nNamespace ?? DEFAULT_NAMESPACE$l;
54044
54044
  });
54045
54045
  const ns = this.ns();
54046
54046
  // El header usa la key 'pageTitle' del namespace; el contenido registra los
@@ -54390,7 +54390,7 @@ const PREFERENCES_VIEW_I18N = {
54390
54390
  },
54391
54391
  };
54392
54392
 
54393
- const DEFAULT_NAMESPACE$j = 'Settings.General';
54393
+ const DEFAULT_NAMESPACE$k = 'Settings.General';
54394
54394
  const DEFAULT_LANGUAGES = ['es', 'en'];
54395
54395
  /**
54396
54396
  * `val-preferences-view` — vista de preferencias de UI cross-app (tema +
@@ -54427,7 +54427,7 @@ class PreferencesViewComponent {
54427
54427
  showLanguage: merged.showLanguage ?? true,
54428
54428
  showFontSize: merged.showFontSize ?? true,
54429
54429
  supportedLanguages: merged.supportedLanguages ?? DEFAULT_LANGUAGES,
54430
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$j,
54430
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$k,
54431
54431
  onThemeChanged: merged.onThemeChanged,
54432
54432
  onLanguageChanged: merged.onLanguageChanged,
54433
54433
  onFontSizeChanged: merged.onFontSizeChanged,
@@ -55932,7 +55932,7 @@ const SECURITY_VIEW_I18N = {
55932
55932
  };
55933
55933
 
55934
55934
  addIcons({ laptopOutline, phonePortraitOutline });
55935
- const DEFAULT_NAMESPACE$i = 'Settings.Security';
55935
+ const DEFAULT_NAMESPACE$j = 'Settings.Security';
55936
55936
  /**
55937
55937
  * `val-security-view` — vista Seguridad full-feature autocontenida (organism).
55938
55938
  *
@@ -55981,7 +55981,7 @@ class SecurityViewComponent {
55981
55981
  showChangeEmail: merged.showChangeEmail ?? true,
55982
55982
  showMfa: merged.showMfa ?? true,
55983
55983
  showPolicies: merged.showPolicies ?? true,
55984
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$i,
55984
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$j,
55985
55985
  handleDeepLinks: merged.handleDeepLinks ?? true,
55986
55986
  homeRoute: merged.homeRoute ?? '/app/home',
55987
55987
  onMfaCompleted: merged.onMfaCompleted,
@@ -56913,7 +56913,7 @@ const CREATE_ORG_MODAL_I18N = {
56913
56913
  },
56914
56914
  };
56915
56915
 
56916
- const DEFAULT_NAMESPACE$h = 'CreateOrgModal';
56916
+ const DEFAULT_NAMESPACE$i = 'CreateOrgModal';
56917
56917
  /**
56918
56918
  * `val-create-org-modal` — modal de creación de organización (organism
56919
56919
  * compartido). Promovido desde `showcase` bajo el proceso de ADR-021. Reusado por
@@ -56949,12 +56949,12 @@ class CreateOrgModalComponent {
56949
56949
  this.toast = inject(ToastService);
56950
56950
  this.errors = inject(ValtechErrorService);
56951
56951
  /** Namespace i18n con que la vista resuelve sus textos. */
56952
- this.i18nNamespace = DEFAULT_NAMESPACE$h;
56952
+ this.i18nNamespace = DEFAULT_NAMESPACE$i;
56953
56953
  this._isOpen = false;
56954
56954
  this.dismissed = new EventEmitter();
56955
56955
  this.created = new EventEmitter();
56956
56956
  this._busy = signal(false);
56957
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$h, CREATE_ORG_MODAL_I18N);
56957
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$i, CREATE_ORG_MODAL_I18N);
56958
56958
  this.formMeta = signal(this.buildFormMeta());
56959
56959
  effect(() => {
56960
56960
  this.i18n.lang();
@@ -57207,7 +57207,7 @@ const DELETE_ACCOUNT_MODAL_I18N = {
57207
57207
  },
57208
57208
  };
57209
57209
 
57210
- const DEFAULT_NAMESPACE$g = 'Settings.DeleteAccount';
57210
+ const DEFAULT_NAMESPACE$h = 'Settings.DeleteAccount';
57211
57211
  /**
57212
57212
  * `val-delete-account-modal` — modal de eliminación de cuenta (organism,
57213
57213
  * cuenta-específico). Promovido desde `showcase` bajo el proceso de ADR-021.
@@ -57248,7 +57248,7 @@ class DeleteAccountModalComponent {
57248
57248
  this.i18n = inject(I18nService);
57249
57249
  this.toast = inject(ToastService);
57250
57250
  /** Namespace i18n con que la vista resuelve sus textos. */
57251
- this.i18nNamespace = DEFAULT_NAMESPACE$g;
57251
+ this.i18nNamespace = DEFAULT_NAMESPACE$h;
57252
57252
  this._isOpen = false;
57253
57253
  this.dismissed = new EventEmitter();
57254
57254
  this.hasPassword = signal(null);
@@ -57317,7 +57317,7 @@ class DeleteAccountModalComponent {
57317
57317
  ],
57318
57318
  actions: this.submitBtn('delete-code-submit', 'confirmCta'),
57319
57319
  }));
57320
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$g, DELETE_ACCOUNT_MODAL_I18N);
57320
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$h, DELETE_ACCOUNT_MODAL_I18N);
57321
57321
  }
57322
57322
  submitBtn(token, textKey) {
57323
57323
  return {
@@ -57523,7 +57523,7 @@ const ORG_INFO_SHEET_I18N = {
57523
57523
  },
57524
57524
  };
57525
57525
 
57526
- const DEFAULT_NAMESPACE$f = 'OrgInfoSheet';
57526
+ const DEFAULT_NAMESPACE$g = 'OrgInfoSheet';
57527
57527
  /**
57528
57528
  * `val-org-info-sheet` — sheet informativo "¿Qué son las organizaciones?".
57529
57529
  * Extraído del `OrgInfoSheetComponent` inline de `AccountPage` bajo el proceso de
@@ -57585,13 +57585,13 @@ class OrgInfoSheetComponent {
57585
57585
  ];
57586
57586
  });
57587
57587
  addIcons({ peopleOutline, swapHorizontalOutline, mailOutline, codeSlashOutline, shieldCheckmarkOutline, warningOutline });
57588
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$f, ORG_INFO_SHEET_I18N);
57588
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$g, ORG_INFO_SHEET_I18N);
57589
57589
  }
57590
57590
  dismiss() {
57591
57591
  this._modalRef?.dismiss(null, 'cancel');
57592
57592
  }
57593
57593
  tt(key) {
57594
- return this.i18n.t(key, DEFAULT_NAMESPACE$f);
57594
+ return this.i18n.t(key, DEFAULT_NAMESPACE$g);
57595
57595
  }
57596
57596
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OrgInfoSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
57597
57597
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: OrgInfoSheetComponent, isStandalone: true, selector: "val-org-info-sheet", inputs: { title: "title", subtitle: "subtitle", body: "body", closeLabel: "closeLabel", showFeatures: "showFeatures", features: "features", closeProps: "closeProps", _modalRef: "_modalRef" }, ngImport: i0, template: `
@@ -57817,7 +57817,7 @@ const ACCOUNT_VIEW_I18N = {
57817
57817
  };
57818
57818
 
57819
57819
  addIcons({ peopleOutline, businessOutline, chevronForwardOutline, swapHorizontalOutline, mailOutline, warningOutline });
57820
- const DEFAULT_NAMESPACE$e = 'Settings.Account';
57820
+ const DEFAULT_NAMESPACE$f = 'Settings.Account';
57821
57821
  const DEFAULT_MANAGE_ORG_ROUTE = '/app/settings/organization';
57822
57822
  /**
57823
57823
  * `val-account-view` — vista Cuenta full-feature autocontenida (organism).
@@ -57858,7 +57858,7 @@ class AccountViewComponent {
57858
57858
  showNewOrgCta: merged.showNewOrgCta ?? false,
57859
57859
  showLogout: merged.showLogout ?? true,
57860
57860
  showDeleteAccount: merged.showDeleteAccount ?? true,
57861
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$e,
57861
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$f,
57862
57862
  manageOrgRoute: merged.manageOrgRoute ?? DEFAULT_MANAGE_ORG_ROUTE,
57863
57863
  onOrgSwitched: merged.onOrgSwitched,
57864
57864
  onOrgCreated: merged.onOrgCreated,
@@ -58630,7 +58630,7 @@ const EDIT_ORG_MODAL_I18N = {
58630
58630
  },
58631
58631
  };
58632
58632
 
58633
- const DEFAULT_NAMESPACE$d = 'EditOrgModal';
58633
+ const DEFAULT_NAMESPACE$e = 'EditOrgModal';
58634
58634
  /**
58635
58635
  * `val-edit-org-modal` — modal de edición de organización (nombre + descripción).
58636
58636
  * Promovido desde `showcase` bajo el proceso de ADR-021. Reusado por la vista de
@@ -58657,7 +58657,7 @@ class EditOrgModalComponent {
58657
58657
  /** Organización a editar (pasada por `componentProps`). */
58658
58658
  this.org = null;
58659
58659
  /** Namespace i18n con que la vista resuelve sus textos. */
58660
- this.i18nNamespace = DEFAULT_NAMESPACE$d;
58660
+ this.i18nNamespace = DEFAULT_NAMESPACE$e;
58661
58661
  this.saving = signal(false);
58662
58662
  this.logoUrl = signal(null);
58663
58663
  this.removingLogo = signal(false);
@@ -58665,7 +58665,7 @@ class EditOrgModalComponent {
58665
58665
  const name = this.org?.name ?? '';
58666
58666
  return name.slice(0, 2).toUpperCase() || '?';
58667
58667
  });
58668
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$d, EDIT_ORG_MODAL_I18N);
58668
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$e, EDIT_ORG_MODAL_I18N);
58669
58669
  this.formMeta = signal(this.buildFormMeta());
58670
58670
  effect(() => {
58671
58671
  this.i18n.lang();
@@ -59035,7 +59035,7 @@ const INVITE_MEMBER_MODAL_I18N = {
59035
59035
  },
59036
59036
  };
59037
59037
 
59038
- const DEFAULT_NAMESPACE$c = 'InviteModal';
59038
+ const DEFAULT_NAMESPACE$d = 'InviteModal';
59039
59039
  addIcons({ personOutline, mailOutline, closeOutline, checkmarkCircleOutline });
59040
59040
  /**
59041
59041
  * `val-invite-member-modal` — invitación de miembros a una organización.
@@ -59066,7 +59066,7 @@ class InviteMemberModalComponent {
59066
59066
  /** Ids de miembros ya existentes (excluidos de los resultados). */
59067
59067
  this.existingMemberIds = [];
59068
59068
  /** Namespace i18n con que la vista resuelve sus textos. */
59069
- this.i18nNamespace = DEFAULT_NAMESPACE$c;
59069
+ this.i18nNamespace = DEFAULT_NAMESPACE$d;
59070
59070
  this.query = signal('');
59071
59071
  this.searching = signal(false);
59072
59072
  this.searchResults = signal([]);
@@ -59128,7 +59128,7 @@ class InviteMemberModalComponent {
59128
59128
  : ComponentStates.DISABLED,
59129
59129
  }));
59130
59130
  this.searchSubject = new Subject();
59131
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$c, INVITE_MEMBER_MODAL_I18N);
59131
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$d, INVITE_MEMBER_MODAL_I18N);
59132
59132
  this.roleSub = this.roleControl.valueChanges.subscribe(v => {
59133
59133
  this.selectedRole.set(v ?? null);
59134
59134
  });
@@ -59866,7 +59866,7 @@ const MEMBER_DETAIL_MODAL_I18N = {
59866
59866
  },
59867
59867
  };
59868
59868
 
59869
- const DEFAULT_NAMESPACE$b = 'Settings.MemberDetail';
59869
+ const DEFAULT_NAMESPACE$c = 'Settings.MemberDetail';
59870
59870
  /**
59871
59871
  * `val-member-detail-modal` — detalle de miembro de organización: perfil, rol y
59872
59872
  * permisos. Promovido desde `showcase` bajo el proceso de ADR-021.
@@ -59917,7 +59917,7 @@ class MemberDetailModalComponent {
59917
59917
  { id: 'admin', name: 'admin' },
59918
59918
  ];
59919
59919
  /** Namespace i18n con que la vista resuelve sus textos. */
59920
- this.i18nNamespace = DEFAULT_NAMESPACE$b;
59920
+ this.i18nNamespace = DEFAULT_NAMESPACE$c;
59921
59921
  this.working = signal(false);
59922
59922
  this.currentRole = signal('');
59923
59923
  this.roleControl = new FormControl('');
@@ -59996,7 +59996,7 @@ class MemberDetailModalComponent {
59996
59996
  type: 'button',
59997
59997
  state: this.working() ? ComponentStates.WORKING : ComponentStates.ENABLED,
59998
59998
  }));
59999
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$b, MEMBER_DETAIL_MODAL_I18N);
59999
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$c, MEMBER_DETAIL_MODAL_I18N);
60000
60000
  }
60001
60001
  ngOnInit() {
60002
60002
  this.i18n.registerDefaults(this.i18nNamespace, MEMBER_DETAIL_MODAL_I18N);
@@ -60454,7 +60454,7 @@ const PERMISSIONS_VIEW_I18N = {
60454
60454
  },
60455
60455
  };
60456
60456
 
60457
- const DEFAULT_NAMESPACE$a = 'Settings.Permissions';
60457
+ const DEFAULT_NAMESPACE$b = 'Settings.Permissions';
60458
60458
  /**
60459
60459
  * `val-permissions-view` — vista Permisos full-feature autocontenida (organism).
60460
60460
  * Visor RBAC de solo lectura: muestra los roles del sistema (Visor/Editor/Admin +
@@ -60500,7 +60500,7 @@ class PermissionsViewComponent {
60500
60500
  showSystemRoles: merged.showSystemRoles ?? true,
60501
60501
  showCustomRoles: merged.showCustomRoles ?? true,
60502
60502
  showOtherAppPermissions: merged.showOtherAppPermissions ?? false,
60503
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$a,
60503
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$b,
60504
60504
  };
60505
60505
  });
60506
60506
  this.loading = signal(false);
@@ -61071,7 +61071,7 @@ const TRANSFER_OWNERSHIP_MODAL_I18N = {
61071
61071
  },
61072
61072
  };
61073
61073
 
61074
- const DEFAULT_NAMESPACE$9 = 'Settings.TransferModal';
61074
+ const DEFAULT_NAMESPACE$a = 'Settings.TransferModal';
61075
61075
  /**
61076
61076
  * `val-transfer-ownership-modal` — selector de miembro para transferir la
61077
61077
  * propiedad de la organización. Promovido desde `showcase` bajo el proceso de
@@ -61095,7 +61095,7 @@ class TransferOwnershipModalComponent {
61095
61095
  /** Lista de miembros transferibles (todos excepto el owner actual). */
61096
61096
  this.members = [];
61097
61097
  /** Namespace i18n con que la vista resuelve sus textos. */
61098
- this.i18nNamespace = DEFAULT_NAMESPACE$9;
61098
+ this.i18nNamespace = DEFAULT_NAMESPACE$a;
61099
61099
  this.query = signal('');
61100
61100
  this.selectedId = signal('');
61101
61101
  this.filtered = computed(() => {
@@ -61105,7 +61105,7 @@ class TransferOwnershipModalComponent {
61105
61105
  return this.members.filter(m => m.name?.toLowerCase().includes(q) || m.email?.toLowerCase().includes(q) || m.userId.toLowerCase().includes(q));
61106
61106
  });
61107
61107
  this.noResultsLabel = computed(() => `${this.t('noResults')} "${this.query()}"`);
61108
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$9, TRANSFER_OWNERSHIP_MODAL_I18N);
61108
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$a, TRANSFER_OWNERSHIP_MODAL_I18N);
61109
61109
  }
61110
61110
  ngOnInit() {
61111
61111
  this.i18n.registerDefaults(this.i18nNamespace, TRANSFER_OWNERSHIP_MODAL_I18N);
@@ -61378,7 +61378,7 @@ const MEMBER_IMPORT_MODAL_I18N = {
61378
61378
  },
61379
61379
  };
61380
61380
 
61381
- const DEFAULT_NAMESPACE$8 = 'Settings.ImportModal';
61381
+ const DEFAULT_NAMESPACE$9 = 'Settings.ImportModal';
61382
61382
  addIcons({ cloudUploadOutline, documentTextOutline });
61383
61383
  /**
61384
61384
  * `val-member-import-modal` — panel de carga masiva de miembros (ADR-023 fase 6).
@@ -61398,7 +61398,7 @@ class MemberImportModalComponent {
61398
61398
  /** Nombres de roles disponibles (para el hint). Opcional. */
61399
61399
  this.availableRoles = [];
61400
61400
  /** Namespace i18n. */
61401
- this.i18nNamespace = DEFAULT_NAMESPACE$8;
61401
+ this.i18nNamespace = DEFAULT_NAMESPACE$9;
61402
61402
  this.csv = '';
61403
61403
  this.importMode = signal('file');
61404
61404
  this.onConflictControl = new FormControl('assignRole');
@@ -61440,7 +61440,7 @@ class MemberImportModalComponent {
61440
61440
  return this.t('summary');
61441
61441
  return `${this.t('summary')}: ${s.created} ${this.t('created')} · ${s.assigned} ${this.t('assigned')} · ${s.skipped} ${this.t('skipped')} · ${s.failed} ${this.t('failed')}`;
61442
61442
  });
61443
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$8, MEMBER_IMPORT_MODAL_I18N);
61443
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$9, MEMBER_IMPORT_MODAL_I18N);
61444
61444
  }
61445
61445
  ngOnInit() {
61446
61446
  this.i18n.registerDefaults(this.i18nNamespace, MEMBER_IMPORT_MODAL_I18N);
@@ -61875,7 +61875,7 @@ const SWITCH_ORG_MODAL_I18N = {
61875
61875
  },
61876
61876
  };
61877
61877
 
61878
- const DEFAULT_NAMESPACE$7 = 'Settings.SwitchOrg';
61878
+ const DEFAULT_NAMESPACE$8 = 'Settings.SwitchOrg';
61879
61879
  addIcons({ addOutline, businessOutline, checkmarkCircleOutline });
61880
61880
  /**
61881
61881
  * `val-switch-org-modal` — modal de cambio de organización activa (organism
@@ -61906,7 +61906,7 @@ class SwitchOrgModalComponent {
61906
61906
  this.orgSwitch = inject(OrgSwitchService);
61907
61907
  this.errors = inject(ValtechErrorService);
61908
61908
  /** Namespace i18n con que la vista resuelve sus textos. */
61909
- this.i18nNamespace = DEFAULT_NAMESPACE$7;
61909
+ this.i18nNamespace = DEFAULT_NAMESPACE$8;
61910
61910
  this.orgs = signal([]);
61911
61911
  this.loading = signal(false);
61912
61912
  this.loadingMore = signal(false);
@@ -61935,7 +61935,7 @@ class SwitchOrgModalComponent {
61935
61935
  return list;
61936
61936
  return list.filter(o => o.name.toLowerCase().includes(q));
61937
61937
  });
61938
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$7, SWITCH_ORG_MODAL_I18N);
61938
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$8, SWITCH_ORG_MODAL_I18N);
61939
61939
  this.loadOrgs();
61940
61940
  }
61941
61941
  onQueryChange(value) {
@@ -62563,7 +62563,7 @@ const ORGANIZATION_VIEW_I18N = {
62563
62563
  };
62564
62564
 
62565
62565
  addIcons({ warningOutline, swapHorizontalOutline });
62566
- const DEFAULT_NAMESPACE$6 = 'Settings.Organization';
62566
+ const DEFAULT_NAMESPACE$7 = 'Settings.Organization';
62567
62567
  const DEFAULT_VIEW_PERMISSIONS_ROUTE = '/app/settings/permissions';
62568
62568
  const DEFAULT_API_KEYS_ROUTE = '/app/settings/api-keys';
62569
62569
  const DEFAULT_LEAVE_REDIRECT_ROUTE = '/app/settings/account';
@@ -62625,7 +62625,7 @@ class OrganizationViewComponent {
62625
62625
  showLeave: merged.showLeave ?? true,
62626
62626
  showDeleteOrg: merged.showDeleteOrg ?? true,
62627
62627
  showApiKeys: merged.showApiKeys ?? true,
62628
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$6,
62628
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$7,
62629
62629
  viewPermissionsRoute: merged.viewPermissionsRoute ?? DEFAULT_VIEW_PERMISSIONS_ROUTE,
62630
62630
  apiKeysRoute: merged.apiKeysRoute ?? DEFAULT_API_KEYS_ROUTE,
62631
62631
  leaveRedirectRoute: merged.leaveRedirectRoute ?? DEFAULT_LEAVE_REDIRECT_ROUTE,
@@ -63976,7 +63976,7 @@ addIcons({
63976
63976
  notificationsOutline,
63977
63977
  refreshOutline,
63978
63978
  });
63979
- const DEFAULT_NAMESPACE$5 = 'Settings.Notifications';
63979
+ const DEFAULT_NAMESPACE$6 = 'Settings.Notifications';
63980
63980
  /**
63981
63981
  * `val-notification-preferences-view` — **preferencias de notificaciones push**
63982
63982
  * (FCM) full-feature autocontenida (organism). Promovida desde `showcase` bajo el
@@ -64019,7 +64019,7 @@ class NotificationPreferencesViewComponent {
64019
64019
  const merged = { ...fromRoute, ...(this.config ?? {}) };
64020
64020
  return {
64021
64021
  showDetails: merged.showDetails ?? true,
64022
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$5,
64022
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$6,
64023
64023
  onPushEnabled: merged.onPushEnabled,
64024
64024
  onPushDisabled: merged.onPushDisabled,
64025
64025
  };
@@ -64812,7 +64812,7 @@ const API_KEYS_MODAL_I18N = {
64812
64812
  },
64813
64813
  };
64814
64814
 
64815
- const DEFAULT_NAMESPACE$4 = 'Settings.ApiKeysModal';
64815
+ const DEFAULT_NAMESPACE$5 = 'Settings.ApiKeysModal';
64816
64816
  /**
64817
64817
  * `val-api-key-create-modal` — modal SÓLO para crear una Client API Key.
64818
64818
  *
@@ -64832,7 +64832,7 @@ class ApiKeyCreateModalComponent {
64832
64832
  this.catalog = inject(PermissionCatalogService);
64833
64833
  this.auth = inject(AuthService);
64834
64834
  /** Namespace i18n (comparte el de `val-api-keys-modal`). */
64835
- this.i18nNamespace = DEFAULT_NAMESPACE$4;
64835
+ this.i18nNamespace = DEFAULT_NAMESPACE$5;
64836
64836
  this.catalogPermissions = signal([]);
64837
64837
  this.actionLabels = signal({});
64838
64838
  this.selectedPerms = signal([]);
@@ -64889,7 +64889,7 @@ class ApiKeyCreateModalComponent {
64889
64889
  actions: submitButton,
64890
64890
  };
64891
64891
  });
64892
- this.i18n.registerDefaults(DEFAULT_NAMESPACE$4, API_KEYS_MODAL_I18N);
64892
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$5, API_KEYS_MODAL_I18N);
64893
64893
  }
64894
64894
  ngOnInit() {
64895
64895
  this.i18n.registerDefaults(this.i18nNamespace, API_KEYS_MODAL_I18N);
@@ -65143,7 +65143,7 @@ const API_KEYS_VIEW_I18N = {
65143
65143
  },
65144
65144
  };
65145
65145
 
65146
- const DEFAULT_NAMESPACE$3 = 'Settings.ApiKeys';
65146
+ const DEFAULT_NAMESPACE$4 = 'Settings.ApiKeys';
65147
65147
  /**
65148
65148
  * `val-api-keys-view` — vista full-feature de gestión de Client API Keys (ADR-021).
65149
65149
  *
@@ -65173,7 +65173,7 @@ class ApiKeysViewComponent {
65173
65173
  this.resolvedConfig = computed(() => {
65174
65174
  const fromRoute = (this.route?.snapshot.data['apiKeysConfig'] ?? {});
65175
65175
  const merged = { ...fromRoute, ...(this.config ?? {}) };
65176
- return { i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$3 };
65176
+ return { i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$4 };
65177
65177
  });
65178
65178
  this.keys = signal([]);
65179
65179
  this.loading = signal(false);
@@ -65794,7 +65794,7 @@ addIcons({
65794
65794
  chevronForwardOutline,
65795
65795
  personOutline,
65796
65796
  });
65797
- const DEFAULT_NAMESPACE$2 = 'Notifications';
65797
+ const DEFAULT_NAMESPACE$3 = 'Notifications';
65798
65798
  const DEFAULT_SETTINGS_PATH = '/app/settings/notifications';
65799
65799
  const DEFAULT_PAGE_SIZE = 10;
65800
65800
  const DEFAULT_MAX_LOAD = 50;
@@ -65854,7 +65854,7 @@ class NotificationsViewComponent {
65854
65854
  showPushOffCta: merged.showPushOffCta ?? true,
65855
65855
  enableMarkAll: merged.enableMarkAll ?? true,
65856
65856
  settingsNotificationsPath: merged.settingsNotificationsPath ?? DEFAULT_SETTINGS_PATH,
65857
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$2,
65857
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$3,
65858
65858
  pageSize: merged.pageSize ?? DEFAULT_PAGE_SIZE,
65859
65859
  maxLoad: merged.maxLoad ?? DEFAULT_MAX_LOAD,
65860
65860
  onNotificationOpen: merged.onNotificationOpen,
@@ -67005,7 +67005,7 @@ addIcons({
67005
67005
  logoYoutube,
67006
67006
  logoTiktok,
67007
67007
  });
67008
- const DEFAULT_NAMESPACE$1 = 'Settings.About';
67008
+ const DEFAULT_NAMESPACE$2 = 'Settings.About';
67009
67009
  const DEFAULT_BRAND_NAME = 'Valtech';
67010
67010
  const DEFAULT_LOGO_SRC = 'assets/images/main-icon.png';
67011
67011
  // Por default el HERO usa la CSS var de marca del factory (`--main-logo-mini`),
@@ -67085,7 +67085,7 @@ class AboutViewComponent {
67085
67085
  ratingEntityId: merged.ratingEntityId ?? DEFAULT_RATING_ENTITY_ID,
67086
67086
  actions: merged.actions ?? [],
67087
67087
  miniGamesRoute: merged.miniGamesRoute ?? '',
67088
- i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$1,
67088
+ i18nNamespace: merged.i18nNamespace ?? DEFAULT_NAMESPACE$2,
67089
67089
  onRated: merged.onRated,
67090
67090
  };
67091
67091
  });
@@ -72156,7 +72156,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
72156
72156
  * cada cambio (`itemsChange`). Patrón object-first (`@Input() props`).
72157
72157
  */
72158
72158
 
72159
- const DEFAULT_NAMESPACE = 'Settings.ApiKeysModal';
72159
+ const DEFAULT_NAMESPACE$1 = 'Settings.ApiKeysModal';
72160
72160
  /**
72161
72161
  * `val-api-keys-modal` — gestión de Client API Keys org-scopeadas (ADR-023 fase 6).
72162
72162
  *
@@ -72171,7 +72171,7 @@ class ApiKeysModalComponent {
72171
72171
  this.catalog = inject(PermissionCatalogService);
72172
72172
  this.auth = inject(AuthService);
72173
72173
  /** Namespace i18n. */
72174
- this.i18nNamespace = DEFAULT_NAMESPACE;
72174
+ this.i18nNamespace = DEFAULT_NAMESPACE$1;
72175
72175
  /** Permisos del catálogo YA filtrados (sin internal, sin otras apps). */
72176
72176
  this.catalogPermissions = signal([]);
72177
72177
  /** Labels de acción (es/en) del backend, para el selector. */
@@ -72237,7 +72237,7 @@ class ApiKeysModalComponent {
72237
72237
  actions: submitButton,
72238
72238
  };
72239
72239
  });
72240
- this.i18n.registerDefaults(DEFAULT_NAMESPACE, API_KEYS_MODAL_I18N);
72240
+ this.i18n.registerDefaults(DEFAULT_NAMESPACE$1, API_KEYS_MODAL_I18N);
72241
72241
  }
72242
72242
  ngOnInit() {
72243
72243
  this.i18n.registerDefaults(this.i18nNamespace, API_KEYS_MODAL_I18N);
@@ -81279,6 +81279,216 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
81279
81279
  args: [VALTECH_COLLECTIONS_CONFIG]
81280
81280
  }] }] });
81281
81281
 
81282
+ const VALTECH_COMMS_PREFERENCES_CONFIG = new InjectionToken('ValtechCommsPreferencesConfig');
81283
+ /**
81284
+ * Provee el servicio de comms-preferences (ADR-089) a la aplicacion Angular.
81285
+ *
81286
+ * @example
81287
+ * bootstrapApplication(AppComponent, {
81288
+ * providers: [
81289
+ * provideValtechCommsPreferences({ apiUrl: environment.apiUrl, appId: 'bingo' }),
81290
+ * ],
81291
+ * });
81292
+ */
81293
+ function provideValtechCommsPreferences(config) {
81294
+ return makeEnvironmentProviders([
81295
+ { provide: VALTECH_COMMS_PREFERENCES_CONFIG, useValue: config },
81296
+ ]);
81297
+ }
81298
+
81299
+ class CommsPreferencesService {
81300
+ constructor(http, config) {
81301
+ this.http = http;
81302
+ this.config = config;
81303
+ this.baseUrl = config ? `${config.apiUrl}/v2/comms-preferences` : null;
81304
+ this.appId = config?.appId ?? null;
81305
+ }
81306
+ list() {
81307
+ if (!this.baseUrl || !this.appId)
81308
+ return EMPTY;
81309
+ const params = new HttpParams().set('appId', this.appId);
81310
+ return this.http.get(`${this.baseUrl}/settings`, { params });
81311
+ }
81312
+ setEnabled(templateId, enabled) {
81313
+ if (!this.baseUrl || !this.appId)
81314
+ return EMPTY;
81315
+ const params = new HttpParams().set('appId', this.appId);
81316
+ return this.http.put(`${this.baseUrl}/settings/${templateId}`, { enabled }, { params });
81317
+ }
81318
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommsPreferencesService, deps: [{ token: i1$3.HttpClient }, { token: VALTECH_COMMS_PREFERENCES_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
81319
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommsPreferencesService, providedIn: 'root' }); }
81320
+ }
81321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommsPreferencesService, decorators: [{
81322
+ type: Injectable,
81323
+ args: [{ providedIn: 'root' }]
81324
+ }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: undefined, decorators: [{
81325
+ type: Optional
81326
+ }, {
81327
+ type: Inject,
81328
+ args: [VALTECH_COMMS_PREFERENCES_CONFIG]
81329
+ }] }] });
81330
+
81331
+ const COMMS_PREFERENCES_SETTINGS_I18N = {
81332
+ es: {
81333
+ pageTitle: 'Comunicaciones',
81334
+ pageDescription: 'Elige qué correos automáticos recibe tu organización.',
81335
+ empty: 'Esta app no tiene comunicaciones configurables por ahora.',
81336
+ savedOk: 'Preferencia guardada.',
81337
+ saveError: 'No se pudo guardar el cambio. Intenta de nuevo.',
81338
+ errorTitle: 'No se pudo cargar',
81339
+ offlineTitle: 'Sin conexión',
81340
+ offlineHint: 'Revisa tu conexión e intenta de nuevo.',
81341
+ retry: 'Reintentar',
81342
+ },
81343
+ en: {
81344
+ pageTitle: 'Communications',
81345
+ pageDescription: 'Choose which automatic emails your organization receives.',
81346
+ empty: 'This app has no configurable communications right now.',
81347
+ savedOk: 'Preference saved.',
81348
+ saveError: 'Could not save the change. Please try again.',
81349
+ errorTitle: 'Could not load',
81350
+ offlineTitle: 'Offline',
81351
+ offlineHint: 'Check your connection and try again.',
81352
+ retry: 'Retry',
81353
+ },
81354
+ };
81355
+
81356
+ const DEFAULT_NAMESPACE = 'Settings.Comms';
81357
+ /**
81358
+ * `val-comms-preferences-settings` (ADR-089) — la organización enciende o
81359
+ * apaga comunicaciones transaccionales configurables (hoy: bingo-transfer-
81360
+ * pending; el catálogo crece sin tocar este componente). Un toggle por
81361
+ * comunicación, guardado inmediato (sin botón "Guardar" aparte) con
81362
+ * rollback optimista si falla.
81363
+ */
81364
+ class CommsPreferencesSettingsComponent {
81365
+ get ns() {
81366
+ return this.config?.i18nNamespace ?? DEFAULT_NAMESPACE;
81367
+ }
81368
+ constructor() {
81369
+ this.i18n = inject(I18nService);
81370
+ this.nav = inject(NavigationService);
81371
+ this.toast = inject(ToastService);
81372
+ this.svc = inject(CommsPreferencesService);
81373
+ this.settings = signal([]);
81374
+ this.controls = new Map();
81375
+ this.page = createPageState(this.i18n, async () => {
81376
+ const res = await firstValueFrom(this.svc.list());
81377
+ this.settings.set(res.settings);
81378
+ });
81379
+ const ns = this.ns;
81380
+ if (!this.i18n.hasNamespace(ns)) {
81381
+ this.i18n.registerContent(ns, COMMS_PREFERENCES_SETTINGS_I18N);
81382
+ }
81383
+ this.nav.setBackHeader('pageTitle', ns, { withMenu: true });
81384
+ connectPageRefresh(() => this.page.reload());
81385
+ }
81386
+ controlFor(templateId, initial) {
81387
+ let control = this.controls.get(templateId);
81388
+ if (!control) {
81389
+ control = new FormControl(initial, { nonNullable: true });
81390
+ control.valueChanges.subscribe(v => this.onToggle(templateId, v));
81391
+ this.controls.set(templateId, control);
81392
+ }
81393
+ else if (control.value !== initial && !control.dirty) {
81394
+ control.setValue(initial, { emitEvent: false });
81395
+ }
81396
+ return control;
81397
+ }
81398
+ toggleProps(templateId) {
81399
+ const item = this.settings().find(s => s.templateId === templateId);
81400
+ return {
81401
+ control: this.controlFor(templateId, item?.enabled ?? true),
81402
+ color: 'primary',
81403
+ };
81404
+ }
81405
+ async onToggle(templateId, enabled) {
81406
+ const previous = !enabled;
81407
+ try {
81408
+ await firstValueFrom(this.svc.setEnabled(templateId, enabled));
81409
+ this.toast.show({ message: this.tt('savedOk'), duration: 1500, color: 'dark', position: 'top' });
81410
+ }
81411
+ catch {
81412
+ this.controls.get(templateId)?.setValue(previous, { emitEvent: false });
81413
+ this.toast.show({ message: this.tt('saveError'), duration: 2500, color: 'dark', position: 'top' });
81414
+ }
81415
+ }
81416
+ tt(key) {
81417
+ return this.i18n.t(key, this.ns);
81418
+ }
81419
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommsPreferencesSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
81420
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: CommsPreferencesSettingsComponent, isStandalone: true, selector: "val-comms-preferences-settings", inputs: { config: "config" }, ngImport: i0, template: `
81421
+ <val-container [props]="{ size: 'md', padding: 'none' }">
81422
+ <div class="page">
81423
+ <header class="page-header">
81424
+ <val-display [props]="{ size: 'small', color: 'dark', content: tt('pageTitle') }" />
81425
+ <val-title [props]="{ size: 'large', color: 'dark', bold: false, content: tt('pageDescription') }" />
81426
+ </header>
81427
+
81428
+ @if (page.errorState(); as e) {
81429
+ <val-empty-state [props]="e" />
81430
+ } @else if (!page.loading() && settings().length === 0) {
81431
+ <val-empty-state [props]="{ variant: 'empty', title: tt('empty') }" />
81432
+ } @else if (!page.loading()) {
81433
+ <section class="settings-section">
81434
+ @for (item of settings(); track item.templateId) {
81435
+ <div class="comm-row">
81436
+ <div class="comm-row__body">
81437
+ <val-title [props]="{ size: 'medium', color: 'dark', bold: true, content: item.label }" />
81438
+ </div>
81439
+ <div class="comm-row__control">
81440
+ <val-toggle-input [props]="toggleProps(item.templateId)" />
81441
+ </div>
81442
+ </div>
81443
+ }
81444
+ </section>
81445
+ }
81446
+ </div>
81447
+ </val-container>
81448
+ `, isInline: true, styles: [".page{padding:16px 0}.page-header{margin-bottom:8px}.settings-section{padding:8px 0}.comm-row{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:center;padding:12px 0}.comm-row+.comm-row{border-top:1px solid var(--val-border-color, rgba(0, 0, 0, .08))}\n"], dependencies: [{ kind: "component", type: ContainerComponent, selector: "val-container", inputs: ["props"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: EmptyStateComponent, selector: "val-empty-state", inputs: ["props"] }, { kind: "component", type: ToggleInputComponent, selector: "val-toggle-input", inputs: ["preset", "props"] }] }); }
81449
+ }
81450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CommsPreferencesSettingsComponent, decorators: [{
81451
+ type: Component,
81452
+ args: [{ selector: 'val-comms-preferences-settings', standalone: true, imports: [
81453
+ ContainerComponent,
81454
+ DisplayComponent,
81455
+ TitleComponent,
81456
+ TextComponent,
81457
+ EmptyStateComponent,
81458
+ ToggleInputComponent,
81459
+ ], template: `
81460
+ <val-container [props]="{ size: 'md', padding: 'none' }">
81461
+ <div class="page">
81462
+ <header class="page-header">
81463
+ <val-display [props]="{ size: 'small', color: 'dark', content: tt('pageTitle') }" />
81464
+ <val-title [props]="{ size: 'large', color: 'dark', bold: false, content: tt('pageDescription') }" />
81465
+ </header>
81466
+
81467
+ @if (page.errorState(); as e) {
81468
+ <val-empty-state [props]="e" />
81469
+ } @else if (!page.loading() && settings().length === 0) {
81470
+ <val-empty-state [props]="{ variant: 'empty', title: tt('empty') }" />
81471
+ } @else if (!page.loading()) {
81472
+ <section class="settings-section">
81473
+ @for (item of settings(); track item.templateId) {
81474
+ <div class="comm-row">
81475
+ <div class="comm-row__body">
81476
+ <val-title [props]="{ size: 'medium', color: 'dark', bold: true, content: item.label }" />
81477
+ </div>
81478
+ <div class="comm-row__control">
81479
+ <val-toggle-input [props]="toggleProps(item.templateId)" />
81480
+ </div>
81481
+ </div>
81482
+ }
81483
+ </section>
81484
+ }
81485
+ </div>
81486
+ </val-container>
81487
+ `, styles: [".page{padding:16px 0}.page-header{margin-bottom:8px}.settings-section{padding:8px 0}.comm-row{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:center;padding:12px 0}.comm-row+.comm-row{border-top:1px solid var(--val-border-color, rgba(0, 0, 0, .08))}\n"] }]
81488
+ }], ctorParameters: () => [], propDecorators: { config: [{
81489
+ type: Input
81490
+ }] } });
81491
+
81282
81492
  /**
81283
81493
  * EntityFeedService — capa de lectura Firestore para entidades proyectables.
81284
81494
  *
@@ -89651,6 +89861,513 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
89651
89861
  }]
89652
89862
  }] });
89653
89863
 
89864
+ /**
89865
+ * `val-page-block`
89866
+ *
89867
+ * Organism que renderiza UN bloque del constructor de páginas de plataforma
89868
+ * (ADR-077, `services/page` en el backend). Es el punto de la lib donde el
89869
+ * catálogo de bloques (`hero`, `text`, `gallery`, `cta`, `faq`) mapea 1:1 a
89870
+ * componentes reales — la razón de ser del ADR: "un rediseño de la lib
89871
+ * mejora todas las páginas publicadas sin tocar sus datos".
89872
+ *
89873
+ * Presentacional puro: recibe `props` ya tipados (espejo exacto del `Block`
89874
+ * del backend), sin llamadas HTTP propias ni conocimiento de a qué app
89875
+ * pertenece la página. El bloque `cta` NO navega — emite `(ctaAction)` con
89876
+ * la intención cruda (`{ action }`) para que el consumidor (la app) la
89877
+ * resuelva contra su propio routing (ADR-077: "el CTA guarda una intención,
89878
+ * nunca una URL").
89879
+ *
89880
+ * El caller típico itera `Page.Blocks` y renderiza uno de estos por bloque:
89881
+ *
89882
+ * @example
89883
+ * ```html
89884
+ * @for (block of page().blocks; track $index) {
89885
+ * <val-page-block [props]="block" (ctaAction)="onCtaAction($event)" />
89886
+ * }
89887
+ * ```
89888
+ */
89889
+ class PageBlockComponent {
89890
+ constructor() {
89891
+ /**
89892
+ * Emite la intención cruda del CTA al hacer click (`{ action }`, nunca una
89893
+ * URL — ver comentario de clase). El consumidor decide qué hacer con
89894
+ * `action`; este componente no la interpreta.
89895
+ */
89896
+ this.ctaAction = new EventEmitter();
89897
+ /** Fallback de imagen rota (convención de la lib) — un slot, una signal. */
89898
+ this.heroImageFailed = signal(false);
89899
+ /** Índices de `gallery.images` cuya carga falló (`error` del `<img>`). */
89900
+ this.failedGalleryImages = signal(new Set());
89901
+ }
89902
+ get hero() {
89903
+ return this.props.props;
89904
+ }
89905
+ get text() {
89906
+ return this.props.props;
89907
+ }
89908
+ get gallery() {
89909
+ return this.props.props;
89910
+ }
89911
+ get cta() {
89912
+ return this.props.props;
89913
+ }
89914
+ get faq() {
89915
+ return this.props.props;
89916
+ }
89917
+ /**
89918
+ * `text.body` es texto plano (no markdown — a diferencia de
89919
+ * `val-article`/`val-faq`, `blocks_validate.go` solo exige un string no
89920
+ * vacío). Partido por línea para que `val-text` (un `<p>` por línea)
89921
+ * respete los saltos que el autor escribió, sin interpretar sintaxis.
89922
+ */
89923
+ textParagraphs() {
89924
+ return this.text.body.split('\n').filter(line => line.trim().length > 0);
89925
+ }
89926
+ /**
89927
+ * `val-faq` agrupa por categoría; el bloque `faq` de `services/page` no
89928
+ * tiene categorías (solo `items` planos) — se envuelve en una única
89929
+ * categoría sin label (`hideSingleCategoryLabel` default `true` la oculta).
89930
+ */
89931
+ faqCategories() {
89932
+ return [
89933
+ {
89934
+ id: 'page-faq',
89935
+ label: '',
89936
+ items: this.faq.items.map((item, index) => ({
89937
+ id: `page-faq-${index}`,
89938
+ question: item.question,
89939
+ answer: item.answer,
89940
+ })),
89941
+ },
89942
+ ];
89943
+ }
89944
+ onCtaClick() {
89945
+ this.ctaAction.emit(this.cta.intent);
89946
+ }
89947
+ onGalleryImageError(index) {
89948
+ const next = new Set(this.failedGalleryImages());
89949
+ next.add(index);
89950
+ this.failedGalleryImages.set(next);
89951
+ }
89952
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PageBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
89953
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PageBlockComponent, isStandalone: true, selector: "val-page-block", inputs: { props: "props" }, outputs: { ctaAction: "ctaAction" }, ngImport: i0, template: `
89954
+ @switch (props.type) {
89955
+ @case ('hero') {
89956
+ <section class="page-block page-block--hero" [class]="'align-' + (hero.align || 'center')">
89957
+ @if (hero.image && !heroImageFailed()) {
89958
+ <img
89959
+ class="page-block__hero-image"
89960
+ [src]="hero.image"
89961
+ [alt]="hero.title"
89962
+ loading="lazy"
89963
+ (error)="heroImageFailed.set(true)"
89964
+ />
89965
+ }
89966
+ <div class="page-block__hero-copy">
89967
+ <val-display [props]="{ size: 'large', color: 'dark', content: hero.title }" />
89968
+ @if (hero.subtitle) {
89969
+ <val-text [props]="{ size: 'large', color: 'medium', bold: false, content: hero.subtitle }" />
89970
+ }
89971
+ </div>
89972
+ </section>
89973
+ }
89974
+ @case ('text') {
89975
+ <section class="page-block page-block--text">
89976
+ @if (text.heading) {
89977
+ <val-title [props]="{ size: 'large', color: 'dark', bold: false, content: text.heading }" />
89978
+ }
89979
+ @for (paragraph of textParagraphs(); track $index) {
89980
+ <val-text [props]="{ size: 'medium', color: 'dark', bold: false, content: paragraph }" />
89981
+ }
89982
+ </section>
89983
+ }
89984
+ @case ('gallery') {
89985
+ <section class="page-block page-block--gallery">
89986
+ <div class="page-block__gallery-grid">
89987
+ @for (image of gallery.images; track $index) {
89988
+ @if (!failedGalleryImages().has($index)) {
89989
+ <!-- Sin alt descriptivo: el backend no modela texto alternativo
89990
+ por imagen (services/page/blocks_validate.go, gallery.images
89991
+ es solo un arreglo de strings). Se marca decorativa a
89992
+ propósito, no un olvido de a11y. -->
89993
+ <img
89994
+ class="page-block__gallery-image"
89995
+ [src]="image"
89996
+ alt=""
89997
+ loading="lazy"
89998
+ (error)="onGalleryImageError($index)"
89999
+ />
90000
+ }
90001
+ }
90002
+ </div>
90003
+ </section>
90004
+ }
90005
+ @case ('cta') {
90006
+ <section class="page-block page-block--cta">
90007
+ <val-button
90008
+ [props]="{
90009
+ text: cta.label,
90010
+ color: 'primary',
90011
+ fill: 'solid',
90012
+ shape: 'round',
90013
+ type: 'button',
90014
+ state: 'ENABLED',
90015
+ }"
90016
+ (onClick)="onCtaClick()"
90017
+ />
90018
+ </section>
90019
+ }
90020
+ @case ('faq') {
90021
+ <section class="page-block page-block--faq">
90022
+ <val-faq [props]="{ categories: faqCategories(), searchable: false }" />
90023
+ </section>
90024
+ }
90025
+ }
90026
+ `, isInline: true, styles: [".page-block{display:block;width:100%}.page-block--hero{display:flex;flex-direction:column;gap:16px;text-align:center;align-items:center}.page-block--hero.align-left{text-align:left;align-items:flex-start}.page-block--hero.align-right{text-align:right;align-items:flex-end}.page-block__hero-image{width:100%;max-height:360px;object-fit:cover;border-radius:12px}.page-block__hero-copy{display:flex;flex-direction:column;gap:8px;max-width:640px}.page-block--text{display:flex;flex-direction:column;gap:8px}.page-block__gallery-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}@media (min-width: 768px){.page-block__gallery-grid{grid-template-columns:repeat(3,1fr);gap:12px}}@media (min-width: 992px){.page-block__gallery-grid{grid-template-columns:repeat(4,1fr)}}.page-block__gallery-image{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:8px}.page-block--cta{display:flex;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: FaqComponent, selector: "val-faq", inputs: ["props"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
90027
+ }
90028
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PageBlockComponent, decorators: [{
90029
+ type: Component,
90030
+ args: [{ selector: 'val-page-block', standalone: true, imports: [CommonModule, DisplayComponent, TitleComponent, TextComponent, ButtonComponent, FaqComponent], template: `
90031
+ @switch (props.type) {
90032
+ @case ('hero') {
90033
+ <section class="page-block page-block--hero" [class]="'align-' + (hero.align || 'center')">
90034
+ @if (hero.image && !heroImageFailed()) {
90035
+ <img
90036
+ class="page-block__hero-image"
90037
+ [src]="hero.image"
90038
+ [alt]="hero.title"
90039
+ loading="lazy"
90040
+ (error)="heroImageFailed.set(true)"
90041
+ />
90042
+ }
90043
+ <div class="page-block__hero-copy">
90044
+ <val-display [props]="{ size: 'large', color: 'dark', content: hero.title }" />
90045
+ @if (hero.subtitle) {
90046
+ <val-text [props]="{ size: 'large', color: 'medium', bold: false, content: hero.subtitle }" />
90047
+ }
90048
+ </div>
90049
+ </section>
90050
+ }
90051
+ @case ('text') {
90052
+ <section class="page-block page-block--text">
90053
+ @if (text.heading) {
90054
+ <val-title [props]="{ size: 'large', color: 'dark', bold: false, content: text.heading }" />
90055
+ }
90056
+ @for (paragraph of textParagraphs(); track $index) {
90057
+ <val-text [props]="{ size: 'medium', color: 'dark', bold: false, content: paragraph }" />
90058
+ }
90059
+ </section>
90060
+ }
90061
+ @case ('gallery') {
90062
+ <section class="page-block page-block--gallery">
90063
+ <div class="page-block__gallery-grid">
90064
+ @for (image of gallery.images; track $index) {
90065
+ @if (!failedGalleryImages().has($index)) {
90066
+ <!-- Sin alt descriptivo: el backend no modela texto alternativo
90067
+ por imagen (services/page/blocks_validate.go, gallery.images
90068
+ es solo un arreglo de strings). Se marca decorativa a
90069
+ propósito, no un olvido de a11y. -->
90070
+ <img
90071
+ class="page-block__gallery-image"
90072
+ [src]="image"
90073
+ alt=""
90074
+ loading="lazy"
90075
+ (error)="onGalleryImageError($index)"
90076
+ />
90077
+ }
90078
+ }
90079
+ </div>
90080
+ </section>
90081
+ }
90082
+ @case ('cta') {
90083
+ <section class="page-block page-block--cta">
90084
+ <val-button
90085
+ [props]="{
90086
+ text: cta.label,
90087
+ color: 'primary',
90088
+ fill: 'solid',
90089
+ shape: 'round',
90090
+ type: 'button',
90091
+ state: 'ENABLED',
90092
+ }"
90093
+ (onClick)="onCtaClick()"
90094
+ />
90095
+ </section>
90096
+ }
90097
+ @case ('faq') {
90098
+ <section class="page-block page-block--faq">
90099
+ <val-faq [props]="{ categories: faqCategories(), searchable: false }" />
90100
+ </section>
90101
+ }
90102
+ }
90103
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".page-block{display:block;width:100%}.page-block--hero{display:flex;flex-direction:column;gap:16px;text-align:center;align-items:center}.page-block--hero.align-left{text-align:left;align-items:flex-start}.page-block--hero.align-right{text-align:right;align-items:flex-end}.page-block__hero-image{width:100%;max-height:360px;object-fit:cover;border-radius:12px}.page-block__hero-copy{display:flex;flex-direction:column;gap:8px;max-width:640px}.page-block--text{display:flex;flex-direction:column;gap:8px}.page-block__gallery-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}@media (min-width: 768px){.page-block__gallery-grid{grid-template-columns:repeat(3,1fr);gap:12px}}@media (min-width: 992px){.page-block__gallery-grid{grid-template-columns:repeat(4,1fr)}}.page-block__gallery-image{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:8px}.page-block--cta{display:flex;justify-content:center}\n"] }]
90104
+ }], propDecorators: { props: [{
90105
+ type: Input
90106
+ }], ctaAction: [{
90107
+ type: Output
90108
+ }] } });
90109
+
90110
+ /**
90111
+ * Tipos del organism `val-page-block` — constructor de páginas de plataforma
90112
+ * (ADR-077: `docs/adr/077-constructor-de-paginas-de-plataforma.md`, primera
90113
+ * aplicación real en Eklesee, Bloque 4:
90114
+ * `docs/eklesee/03-roadmap-y-abiertos.md`).
90115
+ *
90116
+ * Espejo 1:1 de `Block`/`Props` en `backend/go/services/page/types.go` +
90117
+ * `backend/go/services/page/blocks_validate.go` — la forma de cada `props`
90118
+ * sale de ahí, no se inventa acá. El catálogo de esta primera pasada son 5
90119
+ * tipos (`hero`, `text`, `gallery`, `cta`, `faq`); `countdown`/`sponsors`/
90120
+ * `progress` (catálogo completo del ADR) quedan fuera hasta que Bingo migre.
90121
+ *
90122
+ * El componente es i18n-agnóstico y agnóstico al dominio a propósito (mismo
90123
+ * criterio que `val-faq`/`val-article`): recibe `props` ya resueltos, sin
90124
+ * llamadas HTTP propias ni conocimiento de rutas de ninguna app. La app que
90125
+ * lo consume (Eklesee) resuelve `PageCTAIntent.action` a una ruta real —
90126
+ * este organism solo la emite via `(ctaAction)`.
90127
+ */
90128
+
90129
+ const VIDEO_PLAYER_I18N = {
90130
+ es: {
90131
+ uploadingTitle: 'Subiendo video',
90132
+ uploadingBody: 'La subida está en curso. Vuelve en un momento.',
90133
+ processingTitle: 'Video en proceso',
90134
+ processingBody: 'Estamos preparando este video. Vuelve en unos minutos.',
90135
+ rejectedTitle: 'Este video no se pudo publicar',
90136
+ failedTitle: 'No pudimos procesar este video',
90137
+ unsupportedLink: 'Este enlace no se puede reproducir aquí.',
90138
+ },
90139
+ en: {
90140
+ uploadingTitle: 'Uploading video',
90141
+ uploadingBody: 'The upload is in progress. Check back in a moment.',
90142
+ processingTitle: 'Video processing',
90143
+ processingBody: "We're getting this video ready. Check back in a few minutes.",
90144
+ rejectedTitle: "This video couldn't be published",
90145
+ failedTitle: "We couldn't process this video",
90146
+ unsupportedLink: "This link can't be played here.",
90147
+ },
90148
+ };
90149
+ /**
90150
+ * `val-video-player` — reproductor de video de plataforma (ADR-087, "Fase 1 —
90151
+ * Reproducción"). Presentacional/dumb: recibe un `VideoPlayerAsset` YA
90152
+ * RESUELTO por el backend de turno y decide el render, sin fetch propio.
90153
+ *
90154
+ * - `source:'upload'` + `status:'ready'` → `<video>` nativo (`preload="none"`
90155
+ * + portada — ADR-087 §8, cero bytes de video hasta que alguien le da play).
90156
+ * - `source:'upload'` + `uploading|processing` → portada (si hay) + mensaje.
90157
+ * - `source:'upload'` + `failed|rejected` → mensaje legible con `failReason`
90158
+ * (texto ya resuelto por el backend, se muestra tal cual).
90159
+ * - `source:'link'` → iframe **siempre** contra un patrón fijo por proveedor
90160
+ * conocido (`youtube-nocookie.com/embed/{id}` · `player.vimeo.com/video/{id}`),
90161
+ * nunca un `src` armado con datos crudos del usuario. Proveedor no
90162
+ * reconocido → mensaje, nunca un iframe "por si acaso".
90163
+ *
90164
+ * @example
90165
+ * <val-video-player [video]="doc.video" />
90166
+ */
90167
+ class VideoPlayerComponent {
90168
+ constructor() {
90169
+ this.i18n = inject(I18nService);
90170
+ this.sanitizer = inject(DomSanitizer);
90171
+ /** El `VideoAsset` ya resuelto por el backend. `null`/`undefined` → no renderiza nada. */
90172
+ this.video = input(null);
90173
+ this.asset = computed(() => this.video() ?? null);
90174
+ this.thumbFailed = signal(false);
90175
+ /**
90176
+ * Arma el embed SIEMPRE contra un patrón fijo por proveedor conocido — el
90177
+ * `externalId` es el único dato del backend que entra en el `src`. Un
90178
+ * proveedor no reconocido devuelve `null` (el template cae al mensaje, no a
90179
+ * un iframe "por si acaso"). `bypassSecurityTrustResourceUrl` es seguro acá
90180
+ * porque el string completo lo arma este componente, nunca el usuario.
90181
+ */
90182
+ this.embedUrl = computed(() => {
90183
+ const v = this.asset();
90184
+ if (!v || v.source !== 'link' || !v.externalId)
90185
+ return null;
90186
+ const raw = this.buildEmbedUrl(v.provider, v.externalId);
90187
+ return raw ? this.sanitizer.bypassSecurityTrustResourceUrl(raw) : null;
90188
+ });
90189
+ if (!this.i18n.hasNamespace('VideoPlayer')) {
90190
+ this.i18n.registerContent('VideoPlayer', VIDEO_PLAYER_I18N);
90191
+ }
90192
+ }
90193
+ buildEmbedUrl(provider, externalId) {
90194
+ switch (provider) {
90195
+ case 'youtube':
90196
+ return `https://www.youtube-nocookie.com/embed/${encodeURIComponent(externalId)}`;
90197
+ case 'vimeo':
90198
+ return `https://player.vimeo.com/video/${encodeURIComponent(externalId)}`;
90199
+ default:
90200
+ return null;
90201
+ }
90202
+ }
90203
+ t(key) {
90204
+ return this.i18n.t(key, 'VideoPlayer');
90205
+ }
90206
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VideoPlayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
90207
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: VideoPlayerComponent, isStandalone: true, selector: "val-video-player", inputs: { video: { classPropertyName: "video", publicName: "video", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
90208
+ @if (asset(); as v) {
90209
+ @if (v.source === 'upload') {
90210
+ @if (v.status === 'ready' && v.url) {
90211
+ <video
90212
+ class="val-video-player__video"
90213
+ [src]="v.url"
90214
+ [poster]="v.thumbnail || undefined"
90215
+ controls
90216
+ preload="none"
90217
+ playsinline
90218
+ ></video>
90219
+ } @else if (v.status === 'rejected' || v.status === 'failed') {
90220
+ <div class="val-video-player__state val-video-player__state--error">
90221
+ @if (v.thumbnail && !thumbFailed()) {
90222
+ <img
90223
+ class="val-video-player__poster"
90224
+ [src]="v.thumbnail"
90225
+ alt=""
90226
+ loading="lazy"
90227
+ (error)="thumbFailed.set(true)"
90228
+ />
90229
+ }
90230
+ <div class="val-video-player__overlay">
90231
+ <strong>{{ v.status === 'rejected' ? t('rejectedTitle') : t('failedTitle') }}</strong>
90232
+ @if (v.failReason) {
90233
+ <span>{{ v.failReason }}</span>
90234
+ }
90235
+ </div>
90236
+ </div>
90237
+ } @else {
90238
+ <!-- uploading | processing -->
90239
+ <div class="val-video-player__state" aria-live="polite">
90240
+ @if (v.thumbnail && !thumbFailed()) {
90241
+ <img
90242
+ class="val-video-player__poster"
90243
+ [src]="v.thumbnail"
90244
+ alt=""
90245
+ loading="lazy"
90246
+ (error)="thumbFailed.set(true)"
90247
+ />
90248
+ }
90249
+ <div class="val-video-player__overlay">
90250
+ <span class="val-video-player__spinner" aria-hidden="true"></span>
90251
+ <strong>{{ v.status === 'uploading' ? t('uploadingTitle') : t('processingTitle') }}</strong>
90252
+ <span>{{ v.status === 'uploading' ? t('uploadingBody') : t('processingBody') }}</span>
90253
+ </div>
90254
+ </div>
90255
+ }
90256
+ } @else {
90257
+ <!-- source: link -->
90258
+ @if (embedUrl(); as src) {
90259
+ <div class="val-video-player__embed-wrap">
90260
+ <iframe
90261
+ class="val-video-player__embed"
90262
+ [src]="src"
90263
+ title="video"
90264
+ frameborder="0"
90265
+ referrerpolicy="strict-origin-when-cross-origin"
90266
+ allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
90267
+ allowfullscreen
90268
+ loading="lazy"
90269
+ ></iframe>
90270
+ </div>
90271
+ } @else {
90272
+ <div class="val-video-player__state">
90273
+ <div class="val-video-player__overlay">
90274
+ <span>{{ t('unsupportedLink') }}</span>
90275
+ </div>
90276
+ </div>
90277
+ }
90278
+ }
90279
+ }
90280
+ `, isInline: true, styles: [":host{display:block}.val-video-player__video{display:block;width:100%;max-height:70vh;border-radius:12px;background:#000}.val-video-player__embed-wrap{position:relative;width:100%;padding-top:56.25%;border-radius:12px;overflow:hidden;background:#000}.val-video-player__embed{position:absolute;inset:0;width:100%;height:100%;border:0}.val-video-player__state{position:relative;width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--ion-color-light, rgba(0, 0, 0, .06));display:flex;align-items:flex-end}.val-video-player__poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.55}.val-video-player__overlay{position:relative;z-index:1;display:flex;flex-direction:column;gap:4px;width:100%;padding:14px 16px;color:var(--ion-text-color, #000);background:linear-gradient(to top,rgba(0,0,0,.08),transparent)}.val-video-player__state--error .val-video-player__overlay{color:var(--ion-color-danger, #eb445a)}.val-video-player__overlay strong{font-size:.9375rem}.val-video-player__overlay span{font-size:.8125rem;opacity:.85}.val-video-player__spinner{width:18px;height:18px;border-radius:50%;border:2px solid rgba(127,127,127,.35);border-top-color:var(--ion-color-dark, #313131);animation:val-video-player-spin .8s linear infinite}@keyframes val-video-player-spin{to{transform:rotate(360deg)}}\n"] }); }
90281
+ }
90282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VideoPlayerComponent, decorators: [{
90283
+ type: Component,
90284
+ args: [{ selector: 'val-video-player', standalone: true, imports: [], template: `
90285
+ @if (asset(); as v) {
90286
+ @if (v.source === 'upload') {
90287
+ @if (v.status === 'ready' && v.url) {
90288
+ <video
90289
+ class="val-video-player__video"
90290
+ [src]="v.url"
90291
+ [poster]="v.thumbnail || undefined"
90292
+ controls
90293
+ preload="none"
90294
+ playsinline
90295
+ ></video>
90296
+ } @else if (v.status === 'rejected' || v.status === 'failed') {
90297
+ <div class="val-video-player__state val-video-player__state--error">
90298
+ @if (v.thumbnail && !thumbFailed()) {
90299
+ <img
90300
+ class="val-video-player__poster"
90301
+ [src]="v.thumbnail"
90302
+ alt=""
90303
+ loading="lazy"
90304
+ (error)="thumbFailed.set(true)"
90305
+ />
90306
+ }
90307
+ <div class="val-video-player__overlay">
90308
+ <strong>{{ v.status === 'rejected' ? t('rejectedTitle') : t('failedTitle') }}</strong>
90309
+ @if (v.failReason) {
90310
+ <span>{{ v.failReason }}</span>
90311
+ }
90312
+ </div>
90313
+ </div>
90314
+ } @else {
90315
+ <!-- uploading | processing -->
90316
+ <div class="val-video-player__state" aria-live="polite">
90317
+ @if (v.thumbnail && !thumbFailed()) {
90318
+ <img
90319
+ class="val-video-player__poster"
90320
+ [src]="v.thumbnail"
90321
+ alt=""
90322
+ loading="lazy"
90323
+ (error)="thumbFailed.set(true)"
90324
+ />
90325
+ }
90326
+ <div class="val-video-player__overlay">
90327
+ <span class="val-video-player__spinner" aria-hidden="true"></span>
90328
+ <strong>{{ v.status === 'uploading' ? t('uploadingTitle') : t('processingTitle') }}</strong>
90329
+ <span>{{ v.status === 'uploading' ? t('uploadingBody') : t('processingBody') }}</span>
90330
+ </div>
90331
+ </div>
90332
+ }
90333
+ } @else {
90334
+ <!-- source: link -->
90335
+ @if (embedUrl(); as src) {
90336
+ <div class="val-video-player__embed-wrap">
90337
+ <iframe
90338
+ class="val-video-player__embed"
90339
+ [src]="src"
90340
+ title="video"
90341
+ frameborder="0"
90342
+ referrerpolicy="strict-origin-when-cross-origin"
90343
+ allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
90344
+ allowfullscreen
90345
+ loading="lazy"
90346
+ ></iframe>
90347
+ </div>
90348
+ } @else {
90349
+ <div class="val-video-player__state">
90350
+ <div class="val-video-player__overlay">
90351
+ <span>{{ t('unsupportedLink') }}</span>
90352
+ </div>
90353
+ </div>
90354
+ }
90355
+ }
90356
+ }
90357
+ `, styles: [":host{display:block}.val-video-player__video{display:block;width:100%;max-height:70vh;border-radius:12px;background:#000}.val-video-player__embed-wrap{position:relative;width:100%;padding-top:56.25%;border-radius:12px;overflow:hidden;background:#000}.val-video-player__embed{position:absolute;inset:0;width:100%;height:100%;border:0}.val-video-player__state{position:relative;width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--ion-color-light, rgba(0, 0, 0, .06));display:flex;align-items:flex-end}.val-video-player__poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.55}.val-video-player__overlay{position:relative;z-index:1;display:flex;flex-direction:column;gap:4px;width:100%;padding:14px 16px;color:var(--ion-text-color, #000);background:linear-gradient(to top,rgba(0,0,0,.08),transparent)}.val-video-player__state--error .val-video-player__overlay{color:var(--ion-color-danger, #eb445a)}.val-video-player__overlay strong{font-size:.9375rem}.val-video-player__overlay span{font-size:.8125rem;opacity:.85}.val-video-player__spinner{width:18px;height:18px;border-radius:50%;border:2px solid rgba(127,127,127,.35);border-top-color:var(--ion-color-dark, #313131);animation:val-video-player-spin .8s linear infinite}@keyframes val-video-player-spin{to{transform:rotate(360deg)}}\n"] }]
90358
+ }], ctorParameters: () => [] });
90359
+
90360
+ /**
90361
+ * Tipos de `val-video-player` (ADR-087 — video como servicio de plataforma).
90362
+ *
90363
+ * Espejo agnóstico al dominio de `content.VideoAsset` (backend Go,
90364
+ * `backend/go/services/content/video.go`) — mismos nombres de campo en
90365
+ * camelCase. Cualquier app pasa acá el `VideoAsset` que le devuelve SU propio
90366
+ * backend (sermón en Eklesee, receta en Okhelia, animal en Chesed, artículo de
90367
+ * ayuda) con un mapeo trivial; el componente no conoce ni le importa de qué
90368
+ * dominio viene.
90369
+ */
90370
+
89654
90371
  /*
89655
90372
  * Public API Surface of valtech-components
89656
90373
  */
@@ -89660,5 +90377,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
89660
90377
  * Generated bundle index. Do not edit.
89661
90378
  */
89662
90379
 
89663
- export { ACCESS_REQUEST_TYPE, ACCESS_REQUEST_VIEW_I18N, ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccessControlService, AccessRequestViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimalCardComponent, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BackButtonComponent, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CanAccessDirective, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ChipSelectComponent, ClientTelemetryService, CodeDisplayComponent, CodeValidatorComponent, CollectionsService, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ConfirmationDialogV2Component, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CANONICAL_FIELD_ALIASES, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DangerSectionComponent, DataTableComponent, DatasetPaginationService, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EXPECTED_NOT_FOUND, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, EntradaSerializada, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeatureControlService, FeatureGuardDirective, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FieldOptionsEditorComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FolderTabsComponent, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GAME_AVATAR_CATALOG_SIZE_PER_STYLE, GameAvatarComponent, GameProfileService, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, GroupMembersComponent, GroupPickerComponent, GroupsService, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandleService, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LightRippleDirective, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METADATA_LIST_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAMES_I18N, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetadataListComponent, MeteringService, MetricCardComponent, MfaModalComponent, MiniGameCalloutComponent, MiniGamePlayerProfileService, MiniGameScorePopComponent, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NoticeComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberPickerComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OptionSheetComponent, OptionSheetService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PERSONA_CONFIG, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PersonaService, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileCardComponent, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrBrandValidationError, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RbacService, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestReviewPanelComponent, RequestService, RetroAudioService, RightsFooterComponent, RoleManagerComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SelectSearchPickerModalComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SupportTicketCtaComponent, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeSelectorComponent, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ACCESS_FEATURES, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COLLECTIONS_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_COPYRIGHT_TEMPLATE, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DIAGRAMS, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_LEGAL_ENTITY, VALTECH_MENU_I18N, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VAL_REGISTERED_ICONS, VERSION, ValCommentThreadComponent, ValQuotaWarningComponent, ValtechErrorService, VerifyViewComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, accessGuard, accessGuardFromRoute, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildPlatformMenu, buildSettingsCards, buildSideNavItemsFromBottomNav, button, canSubmitRequestType, classifyChip, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGameAvatarCatalog, createGameAvatarProps, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, defaultQrBrand, docs, errorLoggingInterceptor, evaluateValtechAccess, extractPathParams, firmaDeSesionDeCustomToken, formatClockTime, formatDateSeparator, formatRelativeTime, gameAvatarCatalogEntryToMetadata, gameAvatarDataUri, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, providePersona, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccessFeatures, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechCollections, provideValtechContent, provideValtechDebugConsole, provideValtechDiagrams, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, qrContrastRatio, qrErrorCorrectionFor, query, rbacGuard, renderGameAvatarSvg, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resolveColor, resolveCopyrightTemplate, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, roleOf, selectableRequestTypes, storagePaths, suggestEmailFix, superAdminGuard, supportedGameAvatarStyles, toArticle, validateQrBrand, validateRoutes };
90380
+ export { ACCESS_REQUEST_TYPE, ACCESS_REQUEST_VIEW_I18N, ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, APP_VERSION_PLATFORM_PLUGIN, APP_VERSION_REMOTE_PLUGIN, ARTICLE_CARD_DEFAULTS, ARTICLE_SPACING, ARTICLE_STRIP_DEFAULTS, AUTH_CTA_DEFAULTS, AVATAR_UPLOAD_DEFAULTS, AboutViewComponent, AccessControlService, AccessRequestViewComponent, AccordionComponent, AccountViewComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AnimalCardComponent, AnimatedTerminalComponent, ApiKeyCreateModalComponent, ApiKeyService, ApiKeysModalComponent, ApiKeysViewComponent, AppConfigService, AppVersionService, ArticleBuilder, ArticleCardComponent, ArticleComponent, ArticleStripComponent, AttachmentUploaderComponent, AuthBackgroundComponent, AuthCtaComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BackButtonComponent, BannerComponent, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, BubbleBlitzGameComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, CIRCLE_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CORNER_KEYS, CTA_CARD_DEFAULTS, CURRENCY_INFO, CanAccessDirective, CardComponent, CardSection, CardType, CardsCarouselComponent, ChangeEmailModalComponent, ChangePasswordModalComponent, ChatComposerComponent, ChatInputComponent, ChatWindowComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ChipSelectComponent, ClientTelemetryService, CodeDisplayComponent, CodeValidatorComponent, CollectionsService, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CommsPreferencesService, CommsPreferencesSettingsComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ConfirmationDialogV2Component, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentReactionModalComponent, ContentService, ContentTransformer, ConversationListItemComponent, ConversationService, CookieBannerComponent, CookieSettingsComponent, CountdownComponent, CreateOrgModalComponent, CtaCardComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_APP_VERSION_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_BUTTON_PRESETS, DEFAULT_CANCEL_BUTTON, DEFAULT_CANONICAL_FIELD_ALIASES, DEFAULT_CHECK_INTERVAL_MS, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DEBUG_CONSOLE_CONFIG, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_LOGIN_LOGO, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_POST_UPDATE_GRACE_MS, DEFAULT_PRESETS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DEFAULT_SPLASH_SCREEN_CONFIG, DangerSectionComponent, DataTableComponent, DatasetPaginationService, DateInputComponent, DatePickerComponent, DateRangeInputComponent, DebugConsoleComponent, DeleteAccountModalComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EXPECTED_NOT_FOUND, EditOrgModalComponent, EmptyStateComponent, EntityCardComponent, EntityFeedService, EntradaSerializada, ExpandableTextComponent, ExternalBrowserService, FEATURES_LIST_DEFAULTS, FUN_MODAL_DEFAULTS, FabComponent, FaqComponent, FeatureControlService, FeatureGuardDirective, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FieldListComponent, FieldOptionsEditorComponent, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FolderTabsComponent, FontSizeOption, FontSizeSelectorComponent, FontSizeService, FooterComponent, FooterLinksComponent, FormComponent, FormFieldComponent, FormSchemaBuilderService, FormSkeletonComponent, FunHeaderComponent, FunModalComponent, GAME_AVATAR_CATALOG_SIZE_PER_STYLE, GameAvatarComponent, GameProfileService, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, GroupMembersComponent, GroupPickerComponent, GroupsService, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandleService, HandoffService, HapticsService, HasPermissionDirective, HeaderActionsService, HeaderComponent, HintComponent, HorizontalScrollComponent, HrefComponent, HtmlViewerModalComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, INVITATION_CARD_DEFAULTS, IONIC_COLORS$5 as IONIC_COLORS, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, InvitationCardComponent, InviteMemberModalComponent, ItemListComponent, KNOWN_ROUTES, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGGED_IN_HINT_COOKIE, LOGIN_DEFAULTS, LandingSplitComponent, LandingStepsComponent, LanguageSelectorComponent, LanguageSelectorV2Component, LayeredCardComponent, LegalContentService, LegalLinkService, LightRippleDirective, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LiveReadFallbackService, LoadMoreComponent, LoadingDirective, LocalStorageService, LocaleService, LoginAttemptModalComponent, LoginComponent, MEDIA_OBJECT_DEFAULTS, MEMBER_CARD_DEFAULTS, METADATA_LIST_DEFAULTS, META_SCHEMA_VERSION, METRIC_CARD_DEFAULTS, MINI_GAMES_I18N, MINI_GAME_PLAYER_AVATARS, MINI_GAME_PLAYER_COLORS, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MediaObjectComponent, MediaViewerModalComponent, MemberCardComponent, MemberDetailModalComponent, MemberImportModalComponent, MemoryGameComponent, MenuComponent, MessageBubbleComponent, MessagingService, MetaService, MetadataListComponent, MeteringService, MetricCardComponent, MfaModalComponent, MiniGameCalloutComponent, MiniGamePlayerProfileService, MiniGameScorePopComponent, MiniGamesMenuComponent, ModalLayoutComponent, ModalService, ModalShellComponent, MultiSelectSearchComponent, NUM_KEYS, NavigationService, NetworkBannerComponent, NetworkStatusService, NewsBuilder, NoContentComponent, NotesBoxComponent, NoticeComponent, NotificationActionService, NotificationPreferencesViewComponent, NotificationsService, NotificationsViewComponent, NumberFromToComponent, NumberPickerComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OperationReferenceComponent, OptionCardsComponent, OptionSheetComponent, OptionSheetService, OrgInfoSheetComponent, OrgService, OrgSwitchService, OrganizationViewComponent, PATTERN_MOTIFS, PATTERN_PALETTES, PATTERN_STYLE_CONFIGS, PERSONA_CONFIG, PLATFORM_CONFIGS, POST_UPDATE_TS_KEY, PageBlockComponent, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWavesComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PdfService, PermissionCatalogService, PermissionSelectorComponent, PermissionsModalComponent, PermissionsViewComponent, PersonaService, PhoneDisplayComponent, PhoneFormatService, PhoneInputComponent, PickerV2Component, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PreferencesViewComponent, PresetService, PriceTagComponent, PricingTableComponent, ProcessLinksPipe, ProfileCardComponent, ProfileContentComponent, ProfileModalComponent, ProfileSkeletonComponent, ProfileViewComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrBrandValidationError, QrCodeComponent, QrGeneratorService, QrScannerComponent, QueryBuilder, QuoteBoxComponent, REQUEST_STATUSES, RadioInputComponent, RangeInputComponent, RatingComponent, RbacService, ReactionBarComponent, ReactionsService, RefresherComponent, RequestFirestoreService, RequestFormBuilderService, RequestFormComponent, RequestModalComponent, RequestReviewPanelComponent, RequestService, RetroAudioService, RightsFooterComponent, RoleManagerComponent, RotatingTextComponent, SEARCH_HEADER_DEFAULTS, SETTINGS_SECTIONS_CATALOG, SHAPE_KEYS, SHARE_PROFILE_MODAL_DEFAULTS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, STATS_BAR_DEFAULTS, STROKE_KEYS, SearchHeaderComponent, SearchSelectorComponent, SearchbarComponent, SectionHeaderComponent, SecurityViewComponent, SegmentControlComponent, SelectSearchComponent, SelectSearchPickerModalComponent, SessionListModalComponent, SessionService, SessionTransitionOverlayComponent, SettingsHubComponent, ShareButtonsComponent, ShareProfileModalComponent, SimonGameComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SplashComponent, SplashScreenService, StatsBarComponent, StatsCardComponent, StepperComponent, StorageService, SupportTicketCtaComponent, SwipeCarouselComponent, SwitchOrgModalComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeSelectorComponent, ThemeService, ThreadPanelComponent, TicketCardComponent, TicketCardImageService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TransferOwnershipModalComponent, TranslatePipe, TypedCollection, TypingIndicatorComponent, UPDATE_BANNER_DEFAULT_CONTENT, UPDATE_BANNER_I18N_NAMESPACE, UpdateBannerComponent, UsageMetersComponent, UsageService, UserAvatarComponent, UsernameInputComponent, VALTECH_ACCESS_FEATURES, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_APP_VERSION, VALTECH_AUTH_CONFIG, VALTECH_CHAT_CONFIG, VALTECH_COLLECTIONS_CONFIG, VALTECH_COMMS_PREFERENCES_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_CONTENT_CONFIG, VALTECH_COPYRIGHT_TEMPLATE, VALTECH_DEBUG_CONSOLE, VALTECH_DEFAULT_CONTENT, VALTECH_DIAGRAMS, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_LEGAL_ENTITY, VALTECH_MENU_I18N, VALTECH_NETWORK_ERROR_KEY, VALTECH_REACTIONS_CONFIG, VALTECH_SETTINGS_MENU_LINKS, VALTECH_SITE_PATHS, VALTECH_SOCIAL_LINKS, VALTECH_SPLASH_SCREEN, VALTECH_WEB_BASE_URLS, VALTECH_WHATSAPP_CONFIG, VAL_REGISTERED_ICONS, VERSION, ValCommentThreadComponent, ValQuotaWarningComponent, ValtechErrorService, VerifyViewComponent, VideoPlayerComponent, WhatsappFabComponent, WhatsappService, WizardComponent, WizardFooterComponent, WorkflowService, accessGuard, accessGuardFromRoute, applyDefaultValueToControl, authGuard, authInterceptor, authPasswordValidator, beautifyLegalArticle, blogPost, buildCompanyFooterProps, buildFooterLinks, buildLegalLinkResolver, buildPath, buildPlatformMenu, buildSettingsCards, buildSideNavItemsFromBottomNav, button, canSubmitRequestType, classifyChip, collections, connectPageRefresh, createErrorStateProps, createFirebaseConfig, createGameAvatarCatalog, createGameAvatarProps, createGlowCardProps, createInitialDatasetState, createInitialPaginationState, createNumberFromToField, createPageState, createPermissionLabeler, createRefreshableStream, createTitleProps, datasetPageFromLegacyCursor, defaultQrBrand, docs, errorLoggingInterceptor, evaluateValtechAccess, extractPathParams, firmaDeSesionDeCustomToken, formatClockTime, formatDateSeparator, formatRelativeTime, gameAvatarCatalogEntryToMetadata, gameAvatarDataUri, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, groupPermissionsByScope, guestGuard, hasEmulators, iconButton, interpretError, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isIonicColor, isKnownRoute, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, providePersona, provideSplashScreen, provideValtechAboutRoutes, provideValtechAccessFeatures, provideValtechAccountRoutes, provideValtechAds, provideValtechApiKeysRoutes, provideValtechAppConfig, provideValtechAppVersion, provideValtechAppVersionHttp, provideValtechAuth, provideValtechAuthInterceptor, provideValtechChat, provideValtechCollections, provideValtechCommsPreferences, provideValtechContent, provideValtechDebugConsole, provideValtechDiagrams, provideValtechDonations, provideValtechErrorHandling, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechNotificationClickActions, provideValtechNotificationPreferencesRoutes, provideValtechNotificationsRoutes, provideValtechOrganizationRoutes, provideValtechPermissionsRoutes, provideValtechPreferencesRoutes, provideValtechPresets, provideValtechProfileRoutes, provideValtechReactions, provideValtechSecurityRoutes, provideValtechSettingsRoutes, provideValtechSite, provideValtechSkeleton, provideValtechWhatsapp, qrContrastRatio, qrErrorCorrectionFor, query, rbacGuard, renderGameAvatarSvg, renderPatternSvgInner, replaceSpecialChars, requestSubmitMode, resolveColor, resolveCopyrightTemplate, resolveInputDefaultValue, resolveIonicColor, resolveWebBaseUrl, roleGuard, roleOf, selectableRequestTypes, storagePaths, suggestEmailFix, superAdminGuard, supportedGameAvatarStyles, toArticle, validateQrBrand, validateRoutes };
89664
90381
  //# sourceMappingURL=valtech-components.mjs.map