valtech-components 4.0.246 → 4.0.247

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.
@@ -0,0 +1,5 @@
1
+ // val-usage-meters — tipos. Componente presentacional del dashboard de consumo
2
+ // (ADR-046 D3). Object-first; el consumer pasa los datos ya resueltos
3
+ // (típicamente desde UsageService, que lee Firestore en vivo).
4
+ export {};
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvbW9sZWN1bGVzL3VzYWdlLW1ldGVycy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrRUFBK0U7QUFDL0Usc0VBQXNFO0FBQ3RFLCtEQUErRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIHZhbC11c2FnZS1tZXRlcnMg4oCUIHRpcG9zLiBDb21wb25lbnRlIHByZXNlbnRhY2lvbmFsIGRlbCBkYXNoYm9hcmQgZGUgY29uc3Vtb1xuLy8gKEFEUi0wNDYgRDMpLiBPYmplY3QtZmlyc3Q7IGVsIGNvbnN1bWVyIHBhc2EgbG9zIGRhdG9zIHlhIHJlc3VlbHRvc1xuLy8gKHTDrXBpY2FtZW50ZSBkZXNkZSBVc2FnZVNlcnZpY2UsIHF1ZSBsZWUgRmlyZXN0b3JlIGVuIHZpdm8pLlxuXG5leHBvcnQgaW50ZXJmYWNlIFVzYWdlTWV0cmljIHtcbiAgLyoqIENsYXZlIGRlIGxhIG3DqXRyaWNhIChlai4gXCJlbWFpbHNfbW9udGhcIikuICovXG4gIGtleTogc3RyaW5nO1xuICAvKiogRXRpcXVldGEgdmlzaWJsZSB5YSByZXN1ZWx0YSBwb3IgZWwgY29uc3VtZXIgKGVqLiBcIkVtYWlscyAvIG1lc1wiKS4gKi9cbiAgbGFiZWw6IHN0cmluZztcbiAgLyoqIENvbnN1bW8gZGVsIHBlcsOtb2RvLiAqL1xuICB1c2VkOiBudW1iZXI7XG4gIC8qKiBUb3BlOyAtMSA9IGlsaW1pdGFkby4gKi9cbiAgbGltaXQ6IG51bWJlcjtcbiAgLyoqIHRydWUgc2kgZWwgdG9wZSBlcyBpbGltaXRhZG8gKC0xKS4gKi9cbiAgdW5saW1pdGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVzYWdlTWV0ZXJzTWV0YWRhdGEge1xuICAvKiogVMOtdHVsbyBkZSBsYSBzZWNjacOzbiAob3BjaW9uYWwpLiAqL1xuICB0aXRsZT86IHN0cmluZztcbiAgLyoqIE5vbWJyZSBkZSBsYSBhcHAgYSBsYSBxdWUgcGVydGVuZWNlIGVzdGUgYmxvcXVlIChwYXJhIHZpc3RhIG11bHRpLWFwcCkuICovXG4gIGFwcE5hbWU/OiBzdHJpbmc7XG4gIC8qKiBUaWVyIGRlbCBwbGFuLCBwYXJhIG1vc3RyYXIgY29tbyBiYWRnZSAoZWouIFwiUHJvXCIpLiAqL1xuICBwbGFuPzogc3RyaW5nO1xuICAvKiogUGVyw61vZG8gKGVqLiBcIjIwMjYtMDZcIikuICovXG4gIHBlcmlvZD86IHN0cmluZztcbiAgLyoqIE3DqXRyaWNhcyBhIG1vc3RyYXIuICovXG4gIG1ldHJpY3M6IFVzYWdlTWV0cmljW107XG59XG4iXX0=
@@ -0,0 +1,124 @@
1
+ import { Component, computed, inject, input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { I18nService } from '../../../services/i18n/i18n.service';
4
+ import * as i0 from "@angular/core";
5
+ const USAGE_METERS_I18N = {
6
+ es: { unlimited: 'Ilimitado', of: 'de', empty: 'Sin datos de consumo aún.' },
7
+ en: { unlimited: 'Unlimited', of: 'of', empty: 'No usage data yet.' },
8
+ };
9
+ /**
10
+ * val-usage-meters — bloque de consumo (uso vs tope por métrica) para el
11
+ * dashboard de monetización (ADR-046 D3). Presentacional: recibe los datos ya
12
+ * resueltos (UsageService los arma desde Firestore). Reutilizable single-app o
13
+ * por sección en multi-app (myvaltech account).
14
+ */
15
+ export class UsageMetersComponent {
16
+ constructor() {
17
+ this.i18n = inject(I18nService);
18
+ this.props = input.required();
19
+ this.rows = computed(() => {
20
+ this.i18n.lang();
21
+ const unlimitedLabel = this.t('unlimited');
22
+ const ofLabel = this.t('of');
23
+ return (this.props().metrics ?? []).map((m) => {
24
+ const unlimited = m.unlimited || m.limit < 0;
25
+ const over = !unlimited && m.limit > 0 && m.used >= m.limit;
26
+ const pct = unlimited || m.limit <= 0
27
+ ? 0
28
+ : Math.min(100, Math.round((m.used / m.limit) * 100));
29
+ const usedLabel = unlimited
30
+ ? `${m.used} · ${unlimitedLabel}`
31
+ : `${m.used} ${ofLabel} ${m.limit}`;
32
+ return { key: m.key, label: m.label, usedLabel, pct, unlimited, over };
33
+ });
34
+ });
35
+ if (!this.i18n.hasNamespace('UsageMeters')) {
36
+ this.i18n.registerContent('UsageMeters', USAGE_METERS_I18N);
37
+ }
38
+ }
39
+ t(key) {
40
+ this.i18n.lang();
41
+ return this.i18n.t(key, 'UsageMeters');
42
+ }
43
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UsageMetersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
44
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UsageMetersComponent, isStandalone: true, selector: "val-usage-meters", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
45
+ <div class="usage">
46
+ @if (props().appName || props().title) {
47
+ <div class="usage__head">
48
+ <span class="usage__title">{{ props().appName || props().title }}</span>
49
+ @if (props().plan) {
50
+ <span class="usage__plan">{{ props().plan }}</span>
51
+ }
52
+ </div>
53
+ }
54
+
55
+ @if (rows().length === 0) {
56
+ <p class="usage__empty">{{ t('empty') }}</p>
57
+ } @else {
58
+ <ul class="usage__list">
59
+ @for (row of rows(); track row.key) {
60
+ <li class="meter">
61
+ <div class="meter__top">
62
+ <span class="meter__label">{{ row.label }}</span>
63
+ <span class="meter__value" [class.meter__value--over]="row.over">
64
+ {{ row.usedLabel }}
65
+ </span>
66
+ </div>
67
+ @if (!row.unlimited) {
68
+ <div class="meter__track">
69
+ <div
70
+ class="meter__fill"
71
+ [class.meter__fill--over]="row.over"
72
+ [style.width.%]="row.pct"
73
+ ></div>
74
+ </div>
75
+ }
76
+ </li>
77
+ }
78
+ </ul>
79
+ }
80
+ </div>
81
+ `, isInline: true, styles: [":host{display:block}.usage__head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.usage__title{font-size:1.125rem;font-weight:700;color:var(--ion-text-color, #000)}.usage__plan{font-size:.75rem;font-weight:600;padding:2px 10px;border-radius:999px;background:var(--ion-color-primary, #3880ff);color:var(--ion-color-primary-contrast, #fff)}.usage__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c)}.usage__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}.meter__top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}.meter__label{font-size:.875rem;color:var(--ion-text-color, #000)}.meter__value{font-size:.8125rem;font-weight:600;color:var(--ion-color-medium, #92949c)}.meter__value--over{color:var(--ion-color-danger, #eb445a)}.meter__track{height:8px;border-radius:999px;background:var(--ion-color-light, rgba(0, 0, 0, .08));overflow:hidden}.meter__fill{height:100%;border-radius:999px;background:var(--ion-color-primary, #3880ff);transition:width .3s ease}.meter__fill--over{background:var(--ion-color-danger, #eb445a)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UsageMetersComponent, decorators: [{
84
+ type: Component,
85
+ args: [{ selector: 'val-usage-meters', standalone: true, imports: [CommonModule], template: `
86
+ <div class="usage">
87
+ @if (props().appName || props().title) {
88
+ <div class="usage__head">
89
+ <span class="usage__title">{{ props().appName || props().title }}</span>
90
+ @if (props().plan) {
91
+ <span class="usage__plan">{{ props().plan }}</span>
92
+ }
93
+ </div>
94
+ }
95
+
96
+ @if (rows().length === 0) {
97
+ <p class="usage__empty">{{ t('empty') }}</p>
98
+ } @else {
99
+ <ul class="usage__list">
100
+ @for (row of rows(); track row.key) {
101
+ <li class="meter">
102
+ <div class="meter__top">
103
+ <span class="meter__label">{{ row.label }}</span>
104
+ <span class="meter__value" [class.meter__value--over]="row.over">
105
+ {{ row.usedLabel }}
106
+ </span>
107
+ </div>
108
+ @if (!row.unlimited) {
109
+ <div class="meter__track">
110
+ <div
111
+ class="meter__fill"
112
+ [class.meter__fill--over]="row.over"
113
+ [style.width.%]="row.pct"
114
+ ></div>
115
+ </div>
116
+ }
117
+ </li>
118
+ }
119
+ </ul>
120
+ }
121
+ </div>
122
+ `, styles: [":host{display:block}.usage__head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.usage__title{font-size:1.125rem;font-weight:700;color:var(--ion-text-color, #000)}.usage__plan{font-size:.75rem;font-weight:600;padding:2px 10px;border-radius:999px;background:var(--ion-color-primary, #3880ff);color:var(--ion-color-primary-contrast, #fff)}.usage__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c)}.usage__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}.meter__top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}.meter__label{font-size:.875rem;color:var(--ion-text-color, #000)}.meter__value{font-size:.8125rem;font-weight:600;color:var(--ion-color-medium, #92949c)}.meter__value--over{color:var(--ion-color-danger, #eb445a)}.meter__track{height:8px;border-radius:999px;background:var(--ion-color-light, rgba(0, 0, 0, .08));overflow:hidden}.meter__fill{height:100%;border-radius:999px;background:var(--ion-color-primary, #3880ff);transition:width .3s ease}.meter__fill--over{background:var(--ion-color-danger, #eb445a)}\n"] }]
123
+ }], ctorParameters: () => [] });
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNhZ2UtbWV0ZXJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9tb2xlY3VsZXMvdXNhZ2UtbWV0ZXJzL3VzYWdlLW1ldGVycy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFDQUFxQyxDQUFDOztBQUdsRSxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsMkJBQTJCLEVBQUU7SUFDNUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRTtDQUN0RSxDQUFDO0FBV0Y7Ozs7O0dBS0c7QUFtSEgsTUFBTSxPQUFPLG9CQUFvQjtJQUsvQjtRQUpRLFNBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFMUIsVUFBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQXVCLENBQUM7UUFROUMsU0FBSSxHQUFHLFFBQVEsQ0FBYSxHQUFHLEVBQUU7WUFDeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0IsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQzVDLE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQzdDLE1BQU0sSUFBSSxHQUFHLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFDNUQsTUFBTSxHQUFHLEdBQ1AsU0FBUyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQztvQkFDdkIsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxRCxNQUFNLFNBQVMsR0FBRyxTQUFTO29CQUN6QixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLGNBQWMsRUFBRTtvQkFDakMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksSUFBSSxPQUFPLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN0QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDekUsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQXJCRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUM5RCxDQUFDO0lBQ0gsQ0FBQztJQW9CRCxDQUFDLENBQUMsR0FBVztRQUNYLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDakIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDekMsQ0FBQzsrR0FoQ1Usb0JBQW9CO21HQUFwQixvQkFBb0IsK01BOUdyQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDVCwwckNBdENTLFlBQVk7OzRGQStHWCxvQkFBb0I7a0JBbEhoQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUMsWUFDYjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgaW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJMThuU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2kxOG4vaTE4bi5zZXJ2aWNlJztcbmltcG9ydCB7IFVzYWdlTWV0ZXJzTWV0YWRhdGEgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgVVNBR0VfTUVURVJTX0kxOE4gPSB7XG4gIGVzOiB7IHVubGltaXRlZDogJ0lsaW1pdGFkbycsIG9mOiAnZGUnLCBlbXB0eTogJ1NpbiBkYXRvcyBkZSBjb25zdW1vIGHDum4uJyB9LFxuICBlbjogeyB1bmxpbWl0ZWQ6ICdVbmxpbWl0ZWQnLCBvZjogJ29mJywgZW1wdHk6ICdObyB1c2FnZSBkYXRhIHlldC4nIH0sXG59O1xuXG5pbnRlcmZhY2UgTWV0ZXJSb3cge1xuICBrZXk6IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZztcbiAgdXNlZExhYmVsOiBzdHJpbmc7XG4gIHBjdDogbnVtYmVyOyAvLyAwLi4xMDAgKDAgc2kgaWxpbWl0YWRvKVxuICB1bmxpbWl0ZWQ6IGJvb2xlYW47XG4gIG92ZXI6IGJvb2xlYW47XG59XG5cbi8qKlxuICogdmFsLXVzYWdlLW1ldGVycyDigJQgYmxvcXVlIGRlIGNvbnN1bW8gKHVzbyB2cyB0b3BlIHBvciBtw6l0cmljYSkgcGFyYSBlbFxuICogZGFzaGJvYXJkIGRlIG1vbmV0aXphY2nDs24gKEFEUi0wNDYgRDMpLiBQcmVzZW50YWNpb25hbDogcmVjaWJlIGxvcyBkYXRvcyB5YVxuICogcmVzdWVsdG9zIChVc2FnZVNlcnZpY2UgbG9zIGFybWEgZGVzZGUgRmlyZXN0b3JlKS4gUmV1dGlsaXphYmxlIHNpbmdsZS1hcHAgb1xuICogcG9yIHNlY2Npw7NuIGVuIG11bHRpLWFwcCAobXl2YWx0ZWNoIGFjY291bnQpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtdXNhZ2UtbWV0ZXJzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cInVzYWdlXCI+XG4gICAgICBAaWYgKHByb3BzKCkuYXBwTmFtZSB8fCBwcm9wcygpLnRpdGxlKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1c2FnZV9faGVhZFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidXNhZ2VfX3RpdGxlXCI+e3sgcHJvcHMoKS5hcHBOYW1lIHx8IHByb3BzKCkudGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgQGlmIChwcm9wcygpLnBsYW4pIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidXNhZ2VfX3BsYW5cIj57eyBwcm9wcygpLnBsYW4gfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChyb3dzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIDxwIGNsYXNzPVwidXNhZ2VfX2VtcHR5XCI+e3sgdCgnZW1wdHknKSB9fTwvcD5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8dWwgY2xhc3M9XCJ1c2FnZV9fbGlzdFwiPlxuICAgICAgICAgIEBmb3IgKHJvdyBvZiByb3dzKCk7IHRyYWNrIHJvdy5rZXkpIHtcbiAgICAgICAgICAgIDxsaSBjbGFzcz1cIm1ldGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRlcl9fdG9wXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRlcl9fbGFiZWxcIj57eyByb3cubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRlcl9fdmFsdWVcIiBbY2xhc3MubWV0ZXJfX3ZhbHVlLS1vdmVyXT1cInJvdy5vdmVyXCI+XG4gICAgICAgICAgICAgICAgICB7eyByb3cudXNlZExhYmVsIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgQGlmICghcm93LnVubGltaXRlZCkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRlcl9fdHJhY2tcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtZXRlcl9fZmlsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5tZXRlcl9fZmlsbC0tb3Zlcl09XCJyb3cub3ZlclwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cInJvdy5wY3RcIlxuICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIH1cbiAgICAgICAgPC91bD5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgOmhvc3Qge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIH1cbiAgICAgIC51c2FnZV9faGVhZCB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMTJweDtcbiAgICAgIH1cbiAgICAgIC51c2FnZV9fdGl0bGUge1xuICAgICAgICBmb250LXNpemU6IDEuMTI1cmVtO1xuICAgICAgICBmb250LXdlaWdodDogNzAwO1xuICAgICAgICBjb2xvcjogdmFyKC0taW9uLXRleHQtY29sb3IsICMwMDApO1xuICAgICAgfVxuICAgICAgLnVzYWdlX19wbGFuIHtcbiAgICAgICAgZm9udC1zaXplOiAwLjc1cmVtO1xuICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICBwYWRkaW5nOiAycHggMTBweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1wcmltYXJ5LCAjMzg4MGZmKTtcbiAgICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1wcmltYXJ5LWNvbnRyYXN0LCAjZmZmKTtcbiAgICAgIH1cbiAgICAgIC51c2FnZV9fZW1wdHkge1xuICAgICAgICBmb250LXNpemU6IDAuODc1cmVtO1xuICAgICAgICBjb2xvcjogdmFyKC0taW9uLWNvbG9yLW1lZGl1bSwgIzkyOTQ5Yyk7XG4gICAgICB9XG4gICAgICAudXNhZ2VfX2xpc3Qge1xuICAgICAgICBsaXN0LXN0eWxlOiBub25lO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogMTRweDtcbiAgICAgIH1cbiAgICAgIC5tZXRlcl9fdG9wIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgICBhbGlnbi1pdGVtczogYmFzZWxpbmU7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDZweDtcbiAgICAgIH1cbiAgICAgIC5tZXRlcl9fbGFiZWwge1xuICAgICAgICBmb250LXNpemU6IDAuODc1cmVtO1xuICAgICAgICBjb2xvcjogdmFyKC0taW9uLXRleHQtY29sb3IsICMwMDApO1xuICAgICAgfVxuICAgICAgLm1ldGVyX192YWx1ZSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMC44MTI1cmVtO1xuICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICBjb2xvcjogdmFyKC0taW9uLWNvbG9yLW1lZGl1bSwgIzkyOTQ5Yyk7XG4gICAgICB9XG4gICAgICAubWV0ZXJfX3ZhbHVlLS1vdmVyIHtcbiAgICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1kYW5nZXIsICNlYjQ0NWEpO1xuICAgICAgfVxuICAgICAgLm1ldGVyX190cmFjayB7XG4gICAgICAgIGhlaWdodDogOHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgICAgICAgYmFja2dyb3VuZDogdmFyKC0taW9uLWNvbG9yLWxpZ2h0LCByZ2JhKDAsIDAsIDAsIDAuMDgpKTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIH1cbiAgICAgIC5tZXRlcl9fZmlsbCB7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1wcmltYXJ5LCAjMzg4MGZmKTtcbiAgICAgICAgdHJhbnNpdGlvbjogd2lkdGggMC4zcyBlYXNlO1xuICAgICAgfVxuICAgICAgLm1ldGVyX19maWxsLS1vdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZDogdmFyKC0taW9uLWNvbG9yLWRhbmdlciwgI2ViNDQ1YSk7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVXNhZ2VNZXRlcnNDb21wb25lbnQge1xuICBwcml2YXRlIGkxOG4gPSBpbmplY3QoSTE4blNlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IHByb3BzID0gaW5wdXQucmVxdWlyZWQ8VXNhZ2VNZXRlcnNNZXRhZGF0YT4oKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAoIXRoaXMuaTE4bi5oYXNOYW1lc3BhY2UoJ1VzYWdlTWV0ZXJzJykpIHtcbiAgICAgIHRoaXMuaTE4bi5yZWdpc3RlckNvbnRlbnQoJ1VzYWdlTWV0ZXJzJywgVVNBR0VfTUVURVJTX0kxOE4pO1xuICAgIH1cbiAgfVxuXG4gIHJlYWRvbmx5IHJvd3MgPSBjb21wdXRlZDxNZXRlclJvd1tdPigoKSA9PiB7XG4gICAgdGhpcy5pMThuLmxhbmcoKTtcbiAgICBjb25zdCB1bmxpbWl0ZWRMYWJlbCA9IHRoaXMudCgndW5saW1pdGVkJyk7XG4gICAgY29uc3Qgb2ZMYWJlbCA9IHRoaXMudCgnb2YnKTtcbiAgICByZXR1cm4gKHRoaXMucHJvcHMoKS5tZXRyaWNzID8/IFtdKS5tYXAoKG0pID0+IHtcbiAgICAgIGNvbnN0IHVubGltaXRlZCA9IG0udW5saW1pdGVkIHx8IG0ubGltaXQgPCAwO1xuICAgICAgY29uc3Qgb3ZlciA9ICF1bmxpbWl0ZWQgJiYgbS5saW1pdCA+IDAgJiYgbS51c2VkID49IG0ubGltaXQ7XG4gICAgICBjb25zdCBwY3QgPVxuICAgICAgICB1bmxpbWl0ZWQgfHwgbS5saW1pdCA8PSAwXG4gICAgICAgICAgPyAwXG4gICAgICAgICAgOiBNYXRoLm1pbigxMDAsIE1hdGgucm91bmQoKG0udXNlZCAvIG0ubGltaXQpICogMTAwKSk7XG4gICAgICBjb25zdCB1c2VkTGFiZWwgPSB1bmxpbWl0ZWRcbiAgICAgICAgPyBgJHttLnVzZWR9IMK3ICR7dW5saW1pdGVkTGFiZWx9YFxuICAgICAgICA6IGAke20udXNlZH0gJHtvZkxhYmVsfSAke20ubGltaXR9YDtcbiAgICAgIHJldHVybiB7IGtleTogbS5rZXksIGxhYmVsOiBtLmxhYmVsLCB1c2VkTGFiZWwsIHBjdCwgdW5saW1pdGVkLCBvdmVyIH07XG4gICAgfSk7XG4gIH0pO1xuXG4gIHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHRoaXMuaTE4bi5sYW5nKCk7XG4gICAgcmV0dXJuIHRoaXMuaTE4bi50KGtleSwgJ1VzYWdlTWV0ZXJzJyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,87 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { map } from 'rxjs/operators';
3
+ import { ABS_PATH_SENTINEL, FirestoreService } from '../firebase/firestore.service';
4
+ import { I18nService } from '../i18n/i18n.service';
5
+ import * as i0 from "@angular/core";
6
+ // Orden de display de las métricas conocidas.
7
+ const METRIC_ORDER = [
8
+ 'members',
9
+ 'emails_month',
10
+ 'sms_month',
11
+ 'push_month',
12
+ 'api_calls_month',
13
+ 'storage_mb',
14
+ ];
15
+ const USAGE_METRICS_I18N = {
16
+ es: {
17
+ members: 'Miembros',
18
+ emails_month: 'Emails / mes',
19
+ sms_month: 'SMS / mes',
20
+ push_month: 'Push / mes',
21
+ api_calls_month: 'Llamadas API / mes',
22
+ storage_mb: 'Almacenamiento (MB)',
23
+ },
24
+ en: {
25
+ members: 'Members',
26
+ emails_month: 'Emails / mo',
27
+ sms_month: 'SMS / mo',
28
+ push_month: 'Push / mo',
29
+ api_calls_month: 'API calls / mo',
30
+ storage_mb: 'Storage (MB)',
31
+ },
32
+ };
33
+ /**
34
+ * UsageService — lee el resumen de consumo (uso + límites + plan) en vivo desde
35
+ * Firestore y lo mapea a `UsageMetersMetadata` para `<val-usage-meters>`.
36
+ * (ADR-046 D3). Firestore es la fuente única (el backend proyecta usage+limits).
37
+ * Granular por app: `watch(appId, orgId)`. Multi-app: una suscripción por app.
38
+ */
39
+ export class UsageService {
40
+ constructor() {
41
+ this.firestore = inject(FirestoreService);
42
+ this.i18n = inject(I18nService);
43
+ if (!this.i18n.hasNamespace('UsageMetrics')) {
44
+ this.i18n.registerContent('UsageMetrics', USAGE_METRICS_I18N);
45
+ }
46
+ }
47
+ /** Período actual `YYYY-MM` (UTC), igual que el backend. */
48
+ currentPeriod() {
49
+ return new Date().toISOString().slice(0, 7);
50
+ }
51
+ /**
52
+ * Observa el consumo de (org, app) en vivo. Lee el path absoluto
53
+ * `apps/{appId}/orgs/{orgId}/usage/{period}` (sin auto-prefix de la app actual,
54
+ * para soportar la vista multi-app desde account).
55
+ */
56
+ watch(appId, orgId, appName, period) {
57
+ const p = period || this.currentPeriod();
58
+ const collectionPath = `${ABS_PATH_SENTINEL}apps/${appId}/orgs/${orgId}/usage`;
59
+ return this.firestore
60
+ .docChanges(collectionPath, p)
61
+ .pipe(map((doc) => this.toMetadata(doc, appName, p)));
62
+ }
63
+ toMetadata(doc, appName, period) {
64
+ this.i18n.lang();
65
+ const limits = doc?.limits ?? {};
66
+ const usage = doc?.usage ?? {};
67
+ const keys = METRIC_ORDER.filter((k) => k in limits || k in usage);
68
+ const metrics = keys.map((k) => {
69
+ const limit = k in limits ? Number(limits[k]) : -1;
70
+ return {
71
+ key: k,
72
+ label: this.i18n.t(k, 'UsageMetrics') || k,
73
+ used: Number(usage[k] ?? 0),
74
+ limit,
75
+ unlimited: limit < 0,
76
+ };
77
+ });
78
+ return { appName, plan: doc?.plan, period, metrics };
79
+ }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UsageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
81
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UsageService, providedIn: 'root' }); }
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UsageService, decorators: [{
84
+ type: Injectable,
85
+ args: [{ providedIn: 'root' }]
86
+ }], ctorParameters: () => [] });
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNhZ2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvdXNhZ2UvdXNhZ2Uuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFcEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDOztBQWNuRCw4Q0FBOEM7QUFDOUMsTUFBTSxZQUFZLEdBQUc7SUFDbkIsU0FBUztJQUNULGNBQWM7SUFDZCxXQUFXO0lBQ1gsWUFBWTtJQUNaLGlCQUFpQjtJQUNqQixZQUFZO0NBQ2IsQ0FBQztBQUVGLE1BQU0sa0JBQWtCLEdBQUc7SUFDekIsRUFBRSxFQUFFO1FBQ0YsT0FBTyxFQUFFLFVBQVU7UUFDbkIsWUFBWSxFQUFFLGNBQWM7UUFDNUIsU0FBUyxFQUFFLFdBQVc7UUFDdEIsVUFBVSxFQUFFLFlBQVk7UUFDeEIsZUFBZSxFQUFFLG9CQUFvQjtRQUNyQyxVQUFVLEVBQUUscUJBQXFCO0tBQ2xDO0lBQ0QsRUFBRSxFQUFFO1FBQ0YsT0FBTyxFQUFFLFNBQVM7UUFDbEIsWUFBWSxFQUFFLGFBQWE7UUFDM0IsU0FBUyxFQUFFLFVBQVU7UUFDckIsVUFBVSxFQUFFLFdBQVc7UUFDdkIsZUFBZSxFQUFFLGdCQUFnQjtRQUNqQyxVQUFVLEVBQUUsY0FBYztLQUMzQjtDQUNGLENBQUM7QUFFRjs7Ozs7R0FLRztBQUVILE1BQU0sT0FBTyxZQUFZO0lBSXZCO1FBSFEsY0FBUyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3JDLFNBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFHakMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFDaEUsQ0FBQztJQUNILENBQUM7SUFFRCw0REFBNEQ7SUFDNUQsYUFBYTtRQUNYLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUNILEtBQWEsRUFDYixLQUFhLEVBQ2IsT0FBZ0IsRUFDaEIsTUFBZTtRQUVmLE1BQU0sQ0FBQyxHQUFHLE1BQU0sSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekMsTUFBTSxjQUFjLEdBQUcsR0FBRyxpQkFBaUIsUUFBUSxLQUFLLFNBQVMsS0FBSyxRQUFRLENBQUM7UUFDL0UsT0FBTyxJQUFJLENBQUMsU0FBUzthQUNsQixVQUFVLENBQVcsY0FBYyxFQUFFLENBQUMsQ0FBQzthQUN2QyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFTyxVQUFVLENBQ2hCLEdBQW9CLEVBQ3BCLE9BQTJCLEVBQzNCLE1BQWM7UUFFZCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pCLE1BQU0sTUFBTSxHQUFHLEdBQUcsRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ2pDLE1BQU0sS0FBSyxHQUFHLEdBQUcsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQy9CLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDO1FBQ25FLE1BQU0sT0FBTyxHQUFrQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDNUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRCxPQUFPO2dCQUNMLEdBQUcsRUFBRSxDQUFDO2dCQUNOLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLElBQUksQ0FBQztnQkFDMUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzQixLQUFLO2dCQUNMLFNBQVMsRUFBRSxLQUFLLEdBQUcsQ0FBQzthQUNyQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN2RCxDQUFDOytHQXJEVSxZQUFZO21IQUFaLFlBQVksY0FEQyxNQUFNOzs0RkFDbkIsWUFBWTtrQkFEeEIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFCU19QQVRIX1NFTlRJTkVMLCBGaXJlc3RvcmVTZXJ2aWNlIH0gZnJvbSAnLi4vZmlyZWJhc2UvZmlyZXN0b3JlLnNlcnZpY2UnO1xuaW1wb3J0IHsgRmlyZXN0b3JlRG9jdW1lbnQgfSBmcm9tICcuLi9maXJlYmFzZS90eXBlcyc7XG5pbXBvcnQgeyBJMThuU2VydmljZSB9IGZyb20gJy4uL2kxOG4vaTE4bi5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIFVzYWdlTWV0ZXJzTWV0YWRhdGEsXG4gIFVzYWdlTWV0cmljLFxufSBmcm9tICcuLi8uLi9jb21wb25lbnRzL21vbGVjdWxlcy91c2FnZS1tZXRlcnMvdHlwZXMnO1xuXG4vKiogRG9jIHByb3llY3RhZG8gcG9yIGVsIGJhY2tlbmQgKEFEUi0wNDYgQzUvRDMpLiAqL1xuaW50ZXJmYWNlIFVzYWdlRG9jIGV4dGVuZHMgRmlyZXN0b3JlRG9jdW1lbnQge1xuICBwbGFuPzogc3RyaW5nO1xuICBwZXJpb2Q/OiBzdHJpbmc7XG4gIGxpbWl0cz86IFJlY29yZDxzdHJpbmcsIG51bWJlcj47XG4gIHVzYWdlPzogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbn1cblxuLy8gT3JkZW4gZGUgZGlzcGxheSBkZSBsYXMgbcOpdHJpY2FzIGNvbm9jaWRhcy5cbmNvbnN0IE1FVFJJQ19PUkRFUiA9IFtcbiAgJ21lbWJlcnMnLFxuICAnZW1haWxzX21vbnRoJyxcbiAgJ3Ntc19tb250aCcsXG4gICdwdXNoX21vbnRoJyxcbiAgJ2FwaV9jYWxsc19tb250aCcsXG4gICdzdG9yYWdlX21iJyxcbl07XG5cbmNvbnN0IFVTQUdFX01FVFJJQ1NfSTE4TiA9IHtcbiAgZXM6IHtcbiAgICBtZW1iZXJzOiAnTWllbWJyb3MnLFxuICAgIGVtYWlsc19tb250aDogJ0VtYWlscyAvIG1lcycsXG4gICAgc21zX21vbnRoOiAnU01TIC8gbWVzJyxcbiAgICBwdXNoX21vbnRoOiAnUHVzaCAvIG1lcycsXG4gICAgYXBpX2NhbGxzX21vbnRoOiAnTGxhbWFkYXMgQVBJIC8gbWVzJyxcbiAgICBzdG9yYWdlX21iOiAnQWxtYWNlbmFtaWVudG8gKE1CKScsXG4gIH0sXG4gIGVuOiB7XG4gICAgbWVtYmVyczogJ01lbWJlcnMnLFxuICAgIGVtYWlsc19tb250aDogJ0VtYWlscyAvIG1vJyxcbiAgICBzbXNfbW9udGg6ICdTTVMgLyBtbycsXG4gICAgcHVzaF9tb250aDogJ1B1c2ggLyBtbycsXG4gICAgYXBpX2NhbGxzX21vbnRoOiAnQVBJIGNhbGxzIC8gbW8nLFxuICAgIHN0b3JhZ2VfbWI6ICdTdG9yYWdlIChNQiknLFxuICB9LFxufTtcblxuLyoqXG4gKiBVc2FnZVNlcnZpY2Ug4oCUIGxlZSBlbCByZXN1bWVuIGRlIGNvbnN1bW8gKHVzbyArIGzDrW1pdGVzICsgcGxhbikgZW4gdml2byBkZXNkZVxuICogRmlyZXN0b3JlIHkgbG8gbWFwZWEgYSBgVXNhZ2VNZXRlcnNNZXRhZGF0YWAgcGFyYSBgPHZhbC11c2FnZS1tZXRlcnM+YC5cbiAqIChBRFItMDQ2IEQzKS4gRmlyZXN0b3JlIGVzIGxhIGZ1ZW50ZSDDum5pY2EgKGVsIGJhY2tlbmQgcHJveWVjdGEgdXNhZ2UrbGltaXRzKS5cbiAqIEdyYW51bGFyIHBvciBhcHA6IGB3YXRjaChhcHBJZCwgb3JnSWQpYC4gTXVsdGktYXBwOiB1bmEgc3VzY3JpcGNpw7NuIHBvciBhcHAuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVXNhZ2VTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBmaXJlc3RvcmUgPSBpbmplY3QoRmlyZXN0b3JlU2VydmljZSk7XG4gIHByaXZhdGUgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKCF0aGlzLmkxOG4uaGFzTmFtZXNwYWNlKCdVc2FnZU1ldHJpY3MnKSkge1xuICAgICAgdGhpcy5pMThuLnJlZ2lzdGVyQ29udGVudCgnVXNhZ2VNZXRyaWNzJywgVVNBR0VfTUVUUklDU19JMThOKTtcbiAgICB9XG4gIH1cblxuICAvKiogUGVyw61vZG8gYWN0dWFsIGBZWVlZLU1NYCAoVVRDKSwgaWd1YWwgcXVlIGVsIGJhY2tlbmQuICovXG4gIGN1cnJlbnRQZXJpb2QoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNsaWNlKDAsIDcpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9ic2VydmEgZWwgY29uc3VtbyBkZSAob3JnLCBhcHApIGVuIHZpdm8uIExlZSBlbCBwYXRoIGFic29sdXRvXG4gICAqIGBhcHBzL3thcHBJZH0vb3Jncy97b3JnSWR9L3VzYWdlL3twZXJpb2R9YCAoc2luIGF1dG8tcHJlZml4IGRlIGxhIGFwcCBhY3R1YWwsXG4gICAqIHBhcmEgc29wb3J0YXIgbGEgdmlzdGEgbXVsdGktYXBwIGRlc2RlIGFjY291bnQpLlxuICAgKi9cbiAgd2F0Y2goXG4gICAgYXBwSWQ6IHN0cmluZyxcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGFwcE5hbWU/OiBzdHJpbmcsXG4gICAgcGVyaW9kPzogc3RyaW5nLFxuICApOiBPYnNlcnZhYmxlPFVzYWdlTWV0ZXJzTWV0YWRhdGE+IHtcbiAgICBjb25zdCBwID0gcGVyaW9kIHx8IHRoaXMuY3VycmVudFBlcmlvZCgpO1xuICAgIGNvbnN0IGNvbGxlY3Rpb25QYXRoID0gYCR7QUJTX1BBVEhfU0VOVElORUx9YXBwcy8ke2FwcElkfS9vcmdzLyR7b3JnSWR9L3VzYWdlYDtcbiAgICByZXR1cm4gdGhpcy5maXJlc3RvcmVcbiAgICAgIC5kb2NDaGFuZ2VzPFVzYWdlRG9jPihjb2xsZWN0aW9uUGF0aCwgcClcbiAgICAgIC5waXBlKG1hcCgoZG9jKSA9PiB0aGlzLnRvTWV0YWRhdGEoZG9jLCBhcHBOYW1lLCBwKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB0b01ldGFkYXRhKFxuICAgIGRvYzogVXNhZ2VEb2MgfCBudWxsLFxuICAgIGFwcE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBwZXJpb2Q6IHN0cmluZyxcbiAgKTogVXNhZ2VNZXRlcnNNZXRhZGF0YSB7XG4gICAgdGhpcy5pMThuLmxhbmcoKTtcbiAgICBjb25zdCBsaW1pdHMgPSBkb2M/LmxpbWl0cyA/PyB7fTtcbiAgICBjb25zdCB1c2FnZSA9IGRvYz8udXNhZ2UgPz8ge307XG4gICAgY29uc3Qga2V5cyA9IE1FVFJJQ19PUkRFUi5maWx0ZXIoKGspID0+IGsgaW4gbGltaXRzIHx8IGsgaW4gdXNhZ2UpO1xuICAgIGNvbnN0IG1ldHJpY3M6IFVzYWdlTWV0cmljW10gPSBrZXlzLm1hcCgoaykgPT4ge1xuICAgICAgY29uc3QgbGltaXQgPSBrIGluIGxpbWl0cyA/IE51bWJlcihsaW1pdHNba10pIDogLTE7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBrZXk6IGssXG4gICAgICAgIGxhYmVsOiB0aGlzLmkxOG4udChrLCAnVXNhZ2VNZXRyaWNzJykgfHwgayxcbiAgICAgICAgdXNlZDogTnVtYmVyKHVzYWdlW2tdID8/IDApLFxuICAgICAgICBsaW1pdCxcbiAgICAgICAgdW5saW1pdGVkOiBsaW1pdCA8IDAsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHJldHVybiB7IGFwcE5hbWUsIHBsYW46IGRvYz8ucGxhbiwgcGVyaW9kLCBtZXRyaWNzIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,54 @@
1
+ import { inject, Injectable, Optional, Inject } from '@angular/core';
2
+ import { HttpClient } from '@angular/common/http';
3
+ import { of } from 'rxjs';
4
+ import { VALTECH_AUTH_CONFIG } from '../auth/config';
5
+ import { AuthService } from '../auth/auth.service';
6
+ import { FirestoreCollectionFactory } from '../firebase/firestore-collection';
7
+ import * as i0 from "@angular/core";
8
+ /**
9
+ * WorkflowService (ADR-045) — arranca state machines de Step Functions registradas
10
+ * y observa su ejecución en tiempo real (Firestore). Reusable por cualquier app.
11
+ *
12
+ * - start(name, input): dispara `POST /workflows/{name}/start` (el JWT lo inyecta
13
+ * el authInterceptor; orgId/appId se resuelven en el backend desde el contexto).
14
+ * - watch(executionName): onSnapshot del doc de estado, hasta SUCCEEDED/FAILED.
15
+ */
16
+ export class WorkflowService {
17
+ constructor(config) {
18
+ this.config = config;
19
+ this.http = inject(HttpClient);
20
+ this.auth = inject(AuthService);
21
+ this.collections = inject(FirestoreCollectionFactory);
22
+ }
23
+ get appIdHeader() {
24
+ const appId = this.config?.appId;
25
+ return appId ? { 'x-app-id': appId } : {};
26
+ }
27
+ start(name, input) {
28
+ const url = `${this.config?.apiUrl ?? ''}/workflows/${name}/start`;
29
+ return this.http.post(url, { input: input ?? {} }, {
30
+ headers: this.appIdHeader,
31
+ });
32
+ }
33
+ watch(executionName) {
34
+ const orgId = this.auth.user()?.activeOrg ?? '';
35
+ if (!orgId || !executionName)
36
+ return of(null);
37
+ const coll = this.collections.create(`orgs/${orgId}/workflows`, {
38
+ timestamps: false,
39
+ });
40
+ return coll.watch(executionName);
41
+ }
42
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WorkflowService, deps: [{ token: VALTECH_AUTH_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
43
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WorkflowService, providedIn: 'root' }); }
44
+ }
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: WorkflowService, decorators: [{
46
+ type: Injectable,
47
+ args: [{ providedIn: 'root' }]
48
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
49
+ type: Optional
50
+ }, {
51
+ type: Inject,
52
+ args: [VALTECH_AUTH_CONFIG]
53
+ }] }] });
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvd29ya2Zsb3dzL3dvcmtmbG93LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7O0FBNkI5RTs7Ozs7OztHQU9HO0FBRUgsTUFBTSxPQUFPLGVBQWU7SUFLMUIsWUFBNkQsTUFBZ0M7UUFBaEMsV0FBTSxHQUFOLE1BQU0sQ0FBMEI7UUFKckYsU0FBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxQixTQUFJLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNCLGdCQUFXLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFFdUMsQ0FBQztJQUVqRyxJQUFZLFdBQVc7UUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUM7UUFDakMsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFZLEVBQUUsS0FBK0I7UUFDakQsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxFQUFFLGNBQWMsSUFBSSxRQUFRLENBQUM7UUFDbkUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FDbkIsR0FBRyxFQUNILEVBQUUsS0FBSyxFQUFFLEtBQUssSUFBSSxFQUFFLEVBQUUsRUFDdEI7WUFDRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVc7U0FDMUIsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFxQjtRQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDaEQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLGFBQWE7WUFBRSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBb0IsUUFBUSxLQUFLLFlBQVksRUFBRTtZQUNqRixVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDbkMsQ0FBQzsrR0E5QlUsZUFBZSxrQkFLTSxtQkFBbUI7bUhBTHhDLGVBQWUsY0FERixNQUFNOzs0RkFDbkIsZUFBZTtrQkFEM0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQU1uQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgT3B0aW9uYWwsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBWQUxURUNIX0FVVEhfQ09ORklHIH0gZnJvbSAnLi4vYXV0aC9jb25maWcnO1xuaW1wb3J0IHsgVmFsdGVjaEF1dGhDb25maWcgfSBmcm9tICcuLi9hdXRoL3R5cGVzJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgRmlyZXN0b3JlQ29sbGVjdGlvbkZhY3RvcnkgfSBmcm9tICcuLi9maXJlYmFzZS9maXJlc3RvcmUtY29sbGVjdGlvbic7XG5pbXBvcnQgdHlwZSB7IEZpcmVzdG9yZURvY3VtZW50IH0gZnJvbSAnLi4vZmlyZWJhc2UvdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBXb3JrZmxvd1N0YXR1cyA9ICdSVU5OSU5HJyB8ICdTVUNDRUVERUQnIHwgJ0ZBSUxFRCcgfCAnVElNRURfT1VUJyB8ICdBQk9SVEVEJztcblxuLyoqIFJlc3B1ZXN0YSBhbCBhcnJhbmNhciB1biB3b3JrZmxvdyAoQURSLTA0NSkuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtmbG93U3RhcnRSZXN1bHQge1xuICBvcGVyYXRpb25JZDogc3RyaW5nO1xuICB3b3JrZmxvdzogc3RyaW5nO1xuICBleGVjdXRpb25OYW1lOiBzdHJpbmc7XG4gIGV4ZWN1dGlvbkFybjogc3RyaW5nO1xuICBzdGF0dXM6ICdSVU5OSU5HJztcbn1cblxuLyoqXG4gKiBFc3RhZG8gZGUgdW5hIGVqZWN1Y2nDs24gZGUgd29ya2Zsb3cgcHJveWVjdGFkbyBhIEZpcmVzdG9yZSBwb3IgZWwgYWRtaW4gTGFtYmRhXG4gKiAoYXBwcy97YXBwSWR9L29yZ3Mve29yZ0lkfS93b3JrZmxvd3Mve2V4ZWN1dGlvbk5hbWV9KS4gTG8gb2JzZXJ2YSB3YXRjaCgpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtmbG93RXhlY3V0aW9uIGV4dGVuZHMgRmlyZXN0b3JlRG9jdW1lbnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIHdvcmtmbG93OiBzdHJpbmc7XG4gIGV4ZWN1dGlvbkFybjogc3RyaW5nO1xuICBzdGF0dXM6IFdvcmtmbG93U3RhdHVzO1xuICBhcHBJZDogc3RyaW5nO1xuICBvcmdJZDogc3RyaW5nO1xuICBzdGFydGVkQXQ/OiBzdHJpbmc7XG4gIHN0b3BwZWRBdD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBXb3JrZmxvd1NlcnZpY2UgKEFEUi0wNDUpIOKAlCBhcnJhbmNhIHN0YXRlIG1hY2hpbmVzIGRlIFN0ZXAgRnVuY3Rpb25zIHJlZ2lzdHJhZGFzXG4gKiB5IG9ic2VydmEgc3UgZWplY3VjacOzbiBlbiB0aWVtcG8gcmVhbCAoRmlyZXN0b3JlKS4gUmV1c2FibGUgcG9yIGN1YWxxdWllciBhcHAuXG4gKlxuICogLSBzdGFydChuYW1lLCBpbnB1dCk6IGRpc3BhcmEgYFBPU1QgL3dvcmtmbG93cy97bmFtZX0vc3RhcnRgIChlbCBKV1QgbG8gaW55ZWN0YVxuICogICBlbCBhdXRoSW50ZXJjZXB0b3I7IG9yZ0lkL2FwcElkIHNlIHJlc3VlbHZlbiBlbiBlbCBiYWNrZW5kIGRlc2RlIGVsIGNvbnRleHRvKS5cbiAqIC0gd2F0Y2goZXhlY3V0aW9uTmFtZSk6IG9uU25hcHNob3QgZGVsIGRvYyBkZSBlc3RhZG8sIGhhc3RhIFNVQ0NFRURFRC9GQUlMRUQuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgV29ya2Zsb3dTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuICBwcml2YXRlIGF1dGggPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICBwcml2YXRlIGNvbGxlY3Rpb25zID0gaW5qZWN0KEZpcmVzdG9yZUNvbGxlY3Rpb25GYWN0b3J5KTtcblxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KFZBTFRFQ0hfQVVUSF9DT05GSUcpIHByaXZhdGUgY29uZmlnOiBWYWx0ZWNoQXV0aENvbmZpZyB8IG51bGwpIHt9XG5cbiAgcHJpdmF0ZSBnZXQgYXBwSWRIZWFkZXIoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgY29uc3QgYXBwSWQgPSB0aGlzLmNvbmZpZz8uYXBwSWQ7XG4gICAgcmV0dXJuIGFwcElkID8geyAneC1hcHAtaWQnOiBhcHBJZCB9IDoge307XG4gIH1cblxuICBzdGFydChuYW1lOiBzdHJpbmcsIGlucHV0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBPYnNlcnZhYmxlPFdvcmtmbG93U3RhcnRSZXN1bHQ+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZz8uYXBpVXJsID8/ICcnfS93b3JrZmxvd3MvJHtuYW1lfS9zdGFydGA7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PFdvcmtmbG93U3RhcnRSZXN1bHQ+KFxuICAgICAgdXJsLFxuICAgICAgeyBpbnB1dDogaW5wdXQgPz8ge30gfSxcbiAgICAgIHtcbiAgICAgICAgaGVhZGVyczogdGhpcy5hcHBJZEhlYWRlcixcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgd2F0Y2goZXhlY3V0aW9uTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxXb3JrZmxvd0V4ZWN1dGlvbiB8IG51bGw+IHtcbiAgICBjb25zdCBvcmdJZCA9IHRoaXMuYXV0aC51c2VyKCk/LmFjdGl2ZU9yZyA/PyAnJztcbiAgICBpZiAoIW9yZ0lkIHx8ICFleGVjdXRpb25OYW1lKSByZXR1cm4gb2YobnVsbCk7XG4gICAgY29uc3QgY29sbCA9IHRoaXMuY29sbGVjdGlvbnMuY3JlYXRlPFdvcmtmbG93RXhlY3V0aW9uPihgb3Jncy8ke29yZ0lkfS93b3JrZmxvd3NgLCB7XG4gICAgICB0aW1lc3RhbXBzOiBmYWxzZSxcbiAgICB9KTtcbiAgICByZXR1cm4gY29sbC53YXRjaChleGVjdXRpb25OYW1lKTtcbiAgfVxufVxuIl19
@@ -2,5 +2,5 @@
2
2
  * Current version of valtech-components.
3
3
  * This is automatically updated during the publish process.
4
4
  */
5
- export const VERSION = '4.0.246';
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzQuMC4yNDYnO1xuIl19
5
+ export const VERSION = '4.0.247';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXJyZW50IHZlcnNpb24gb2YgdmFsdGVjaC1jb21wb25lbnRzLlxuICogVGhpcyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQgZHVyaW5nIHRoZSBwdWJsaXNoIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gJzQuMC4yNDcnO1xuIl19