valtech-components 2.0.628 → 2.0.629

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,298 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, computed, EventEmitter, inject, input, Output, } from '@angular/core';
3
+ import { RouterLink } from '@angular/router';
4
+ import { IonIcon, IonRippleEffect } from '@ionic/angular/standalone';
5
+ import { addIcons } from 'ionicons';
6
+ import { chevronForwardOutline } from 'ionicons/icons';
7
+ import { I18nService } from '../../../services/i18n';
8
+ import { NavigationService } from '../../../services/navigation.service';
9
+ import { ACTION_CARD_DEFAULTS, } from './types';
10
+ import * as i0 from "@angular/core";
11
+ addIcons({ chevronForwardOutline });
12
+ const IONIC_COLORS = [
13
+ 'primary', 'secondary', 'tertiary', 'success',
14
+ 'warning', 'danger', 'light', 'medium', 'dark'
15
+ ];
16
+ /**
17
+ * val-action-card
18
+ *
19
+ * A clickable card component with icon, title, description, and optional badge.
20
+ * Supports multiple icon formats: Ionicons, SVG paths, and image URLs.
21
+ *
22
+ * @example Basic usage with Ionicon
23
+ * ```html
24
+ * <val-action-card
25
+ * [props]="{
26
+ * icon: { ionicon: 'settings-outline' },
27
+ * title: 'Settings',
28
+ * description: 'Manage your preferences'
29
+ * }"
30
+ * (cardClick)="onCardClick($event)"
31
+ * />
32
+ * ```
33
+ *
34
+ * @example With routerLink navigation
35
+ * ```html
36
+ * <val-action-card
37
+ * [props]="{
38
+ * icon: { ionicon: 'person-outline', color: 'primary' },
39
+ * title: 'Profile',
40
+ * description: 'View and edit your profile',
41
+ * routerLink: '/settings/profile',
42
+ * showChevron: true
43
+ * }"
44
+ * />
45
+ * ```
46
+ *
47
+ * @example With custom SVG icon
48
+ * ```html
49
+ * <val-action-card
50
+ * [props]="{
51
+ * icon: { svgPath: 'M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5' },
52
+ * title: 'Custom Feature',
53
+ * description: 'A feature with custom SVG icon',
54
+ * badge: { text: 'NEW', color: 'light', backgroundColor: 'primary' }
55
+ * }"
56
+ * />
57
+ * ```
58
+ */
59
+ export class ActionCardComponent {
60
+ constructor() {
61
+ this.i18n = inject(I18nService);
62
+ this.navigation = inject(NavigationService);
63
+ /** Component configuration */
64
+ this.props = input({});
65
+ /** Event emitted when card is clicked */
66
+ this.cardClick = new EventEmitter();
67
+ /** Merged configuration with defaults */
68
+ this.config = computed(() => ({
69
+ ...ACTION_CARD_DEFAULTS,
70
+ ...this.props(),
71
+ }));
72
+ }
73
+ /** Get title with i18n support */
74
+ getTitle() {
75
+ const cfg = this.config();
76
+ if (cfg.i18nNamespace && cfg.titleKey) {
77
+ this.i18n.lang(); // Track language changes for reactivity
78
+ return this.i18n.t(cfg.titleKey, cfg.i18nNamespace);
79
+ }
80
+ return cfg.title || '';
81
+ }
82
+ /** Get description with i18n support */
83
+ getDescription() {
84
+ const cfg = this.config();
85
+ if (cfg.i18nNamespace && cfg.descriptionKey) {
86
+ this.i18n.lang(); // Track language changes for reactivity
87
+ return this.i18n.t(cfg.descriptionKey, cfg.i18nNamespace);
88
+ }
89
+ return cfg.description || '';
90
+ }
91
+ /** Resolve color to CSS value */
92
+ resolveColor(color) {
93
+ if (!color)
94
+ return null;
95
+ if (IONIC_COLORS.includes(color)) {
96
+ return `var(--ion-color-${color})`;
97
+ }
98
+ return color;
99
+ }
100
+ getBackgroundColor() {
101
+ return this.resolveColor(this.config().backgroundColor);
102
+ }
103
+ getBorderColor() {
104
+ return this.resolveColor(this.config().borderColor) || 'var(--ion-color-light-shade)';
105
+ }
106
+ getIconColor() {
107
+ return this.resolveColor(this.config().icon?.color) || 'var(--ion-color-primary)';
108
+ }
109
+ getIconBackgroundColor() {
110
+ const bg = this.config().icon?.backgroundColor;
111
+ if (!bg)
112
+ return 'rgba(var(--ion-color-primary-rgb), 0.1)';
113
+ return this.resolveColor(bg);
114
+ }
115
+ getBadgeColor() {
116
+ return this.resolveColor(this.config().badge?.color) || 'white';
117
+ }
118
+ getBadgeBackgroundColor() {
119
+ return this.resolveColor(this.config().badge?.backgroundColor) || 'var(--ion-color-primary)';
120
+ }
121
+ /** Handle card click */
122
+ handleClick(event) {
123
+ const cfg = this.config();
124
+ if (cfg.disabled) {
125
+ event.preventDefault();
126
+ event.stopPropagation();
127
+ return;
128
+ }
129
+ // Emit click event
130
+ this.cardClick.emit({
131
+ token: cfg.token,
132
+ navigated: !!cfg.routerLink || !!cfg.href,
133
+ });
134
+ // Handle external URL
135
+ if (cfg.href) {
136
+ this.navigation.openInNewTab(cfg.href);
137
+ }
138
+ }
139
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ActionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
140
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ActionCardComponent, isStandalone: true, selector: "val-action-card", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, ngImport: i0, template: `
141
+ <article
142
+ class="action-card"
143
+ [class.action-card--small]="config().size === 'small'"
144
+ [class.action-card--medium]="config().size === 'medium'"
145
+ [class.action-card--large]="config().size === 'large'"
146
+ [class.action-card--bordered]="config().bordered"
147
+ [class.action-card--shadowed]="config().shadowed"
148
+ [class.action-card--disabled]="config().disabled"
149
+ [class.action-card--clickable]="!config().disabled"
150
+ [style.--card-bg]="getBackgroundColor()"
151
+ [style.--card-border-color]="getBorderColor()"
152
+ [routerLink]="config().disabled ? null : config().routerLink"
153
+ (click)="handleClick($event)"
154
+ [attr.tabindex]="config().disabled ? -1 : 0"
155
+ [attr.role]="'button'"
156
+ [attr.aria-disabled]="config().disabled"
157
+ >
158
+ <ion-ripple-effect></ion-ripple-effect>
159
+
160
+ <!-- Badge (top-right corner) -->
161
+ @if (config().badge) {
162
+ <span
163
+ class="action-card__badge"
164
+ [style.color]="getBadgeColor()"
165
+ [style.background-color]="getBadgeBackgroundColor()"
166
+ >
167
+ {{ config().badge!.text }}
168
+ </span>
169
+ }
170
+
171
+ <!-- Icon Container -->
172
+ <div
173
+ class="action-card__icon"
174
+ [style.color]="getIconColor()"
175
+ [style.background-color]="getIconBackgroundColor()"
176
+ >
177
+ @if (config().icon?.ionicon) {
178
+ <ion-icon [name]="config().icon!.ionicon!"></ion-icon>
179
+ } @else if (config().icon?.svgPath) {
180
+ <svg
181
+ viewBox="0 0 24 24"
182
+ fill="none"
183
+ stroke="currentColor"
184
+ stroke-width="1.5"
185
+ stroke-linecap="round"
186
+ stroke-linejoin="round"
187
+ >
188
+ <path [attr.d]="config().icon!.svgPath" />
189
+ </svg>
190
+ } @else if (config().icon?.imageUrl) {
191
+ <img
192
+ [src]="config().icon!.imageUrl"
193
+ [alt]="getTitle()"
194
+ class="action-card__icon-image"
195
+ />
196
+ }
197
+ </div>
198
+
199
+ <!-- Content -->
200
+ <div class="action-card__content">
201
+ <h3 class="action-card__title">{{ getTitle() }}</h3>
202
+ @if (getDescription()) {
203
+ <p class="action-card__description">{{ getDescription() }}</p>
204
+ }
205
+ </div>
206
+
207
+ <!-- Chevron (optional) -->
208
+ @if (config().showChevron && !config().disabled) {
209
+ <ion-icon
210
+ name="chevron-forward-outline"
211
+ class="action-card__chevron"
212
+ ></ion-icon>
213
+ }
214
+ </article>
215
+ `, isInline: true, styles: [":host{display:block}.action-card{position:relative;display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--card-bg, var(--ion-card-background, var(--ion-background-color)));border-radius:12px;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,background-color .2s ease;text-decoration:none;overflow:hidden;--ripple-color: var(--ion-color-primary)}.action-card--small{padding:.75rem;gap:.75rem}.action-card--small .action-card__icon{width:36px;height:36px;font-size:18px;border-radius:8px}.action-card--small .action-card__icon svg{width:18px;height:18px}.action-card--small .action-card__title{font-size:.9rem}.action-card--small .action-card__description{font-size:.8rem}.action-card--medium{padding:1rem;gap:1rem}.action-card--medium .action-card__icon{width:48px;height:48px;font-size:24px;border-radius:10px}.action-card--medium .action-card__icon svg{width:24px;height:24px}.action-card--medium .action-card__title{font-size:1rem}.action-card--medium .action-card__description{font-size:.875rem}.action-card--large{padding:1.25rem;gap:1.25rem}.action-card--large .action-card__icon{width:56px;height:56px;font-size:28px;border-radius:12px}.action-card--large .action-card__icon svg{width:28px;height:28px}.action-card--large .action-card__title{font-size:1.1rem}.action-card--large .action-card__description{font-size:.9rem}.action-card--bordered{border:1px solid var(--card-border-color, var(--ion-color-light-shade))}.action-card--shadowed{box-shadow:0 2px 8px #00000014}.action-card--clickable:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.action-card--clickable:focus-visible{outline:2px solid var(--ion-color-primary);outline-offset:2px}.action-card--clickable:active{transform:translateY(0)}.action-card--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.action-card__badge{position:absolute;top:8px;right:8px;padding:2px 8px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;border-radius:10px;z-index:1}.action-card__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center}.action-card__icon ion-icon{font-size:inherit}.action-card__icon svg{display:block}.action-card__icon-image{width:100%;height:100%;object-fit:cover;border-radius:8px}.action-card__content{flex:1;min-width:0}.action-card__title{margin:0 0 .25rem;font-weight:600;color:var(--ion-text-color);line-height:1.3}.action-card__description{margin:0;color:var(--ion-color-medium);line-height:1.4}.action-card__chevron{flex-shrink:0;font-size:1.25rem;color:var(--ion-color-medium);transition:transform .2s ease}.action-card--clickable:hover .action-card__chevron{transform:translate(4px)}@media (prefers-color-scheme: dark){.action-card--shadowed{box-shadow:0 2px 8px #0000004d}.action-card--clickable:hover{box-shadow:0 4px 16px #0006}}:host-context(.dark) .action-card--shadowed,:host-context(body.dark) .action-card--shadowed,:host-context([data-theme=dark]) .action-card--shadowed{box-shadow:0 2px 8px #0000004d}:host-context(.dark) .action-card--clickable:hover,:host-context(body.dark) .action-card--clickable:hover,:host-context([data-theme=dark]) .action-card--clickable:hover{box-shadow:0 4px 16px #0006}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonRippleEffect, selector: "ion-ripple-effect", inputs: ["type"] }] }); }
216
+ }
217
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ActionCardComponent, decorators: [{
218
+ type: Component,
219
+ args: [{ selector: 'val-action-card', standalone: true, imports: [CommonModule, RouterLink, IonIcon, IonRippleEffect], template: `
220
+ <article
221
+ class="action-card"
222
+ [class.action-card--small]="config().size === 'small'"
223
+ [class.action-card--medium]="config().size === 'medium'"
224
+ [class.action-card--large]="config().size === 'large'"
225
+ [class.action-card--bordered]="config().bordered"
226
+ [class.action-card--shadowed]="config().shadowed"
227
+ [class.action-card--disabled]="config().disabled"
228
+ [class.action-card--clickable]="!config().disabled"
229
+ [style.--card-bg]="getBackgroundColor()"
230
+ [style.--card-border-color]="getBorderColor()"
231
+ [routerLink]="config().disabled ? null : config().routerLink"
232
+ (click)="handleClick($event)"
233
+ [attr.tabindex]="config().disabled ? -1 : 0"
234
+ [attr.role]="'button'"
235
+ [attr.aria-disabled]="config().disabled"
236
+ >
237
+ <ion-ripple-effect></ion-ripple-effect>
238
+
239
+ <!-- Badge (top-right corner) -->
240
+ @if (config().badge) {
241
+ <span
242
+ class="action-card__badge"
243
+ [style.color]="getBadgeColor()"
244
+ [style.background-color]="getBadgeBackgroundColor()"
245
+ >
246
+ {{ config().badge!.text }}
247
+ </span>
248
+ }
249
+
250
+ <!-- Icon Container -->
251
+ <div
252
+ class="action-card__icon"
253
+ [style.color]="getIconColor()"
254
+ [style.background-color]="getIconBackgroundColor()"
255
+ >
256
+ @if (config().icon?.ionicon) {
257
+ <ion-icon [name]="config().icon!.ionicon!"></ion-icon>
258
+ } @else if (config().icon?.svgPath) {
259
+ <svg
260
+ viewBox="0 0 24 24"
261
+ fill="none"
262
+ stroke="currentColor"
263
+ stroke-width="1.5"
264
+ stroke-linecap="round"
265
+ stroke-linejoin="round"
266
+ >
267
+ <path [attr.d]="config().icon!.svgPath" />
268
+ </svg>
269
+ } @else if (config().icon?.imageUrl) {
270
+ <img
271
+ [src]="config().icon!.imageUrl"
272
+ [alt]="getTitle()"
273
+ class="action-card__icon-image"
274
+ />
275
+ }
276
+ </div>
277
+
278
+ <!-- Content -->
279
+ <div class="action-card__content">
280
+ <h3 class="action-card__title">{{ getTitle() }}</h3>
281
+ @if (getDescription()) {
282
+ <p class="action-card__description">{{ getDescription() }}</p>
283
+ }
284
+ </div>
285
+
286
+ <!-- Chevron (optional) -->
287
+ @if (config().showChevron && !config().disabled) {
288
+ <ion-icon
289
+ name="chevron-forward-outline"
290
+ class="action-card__chevron"
291
+ ></ion-icon>
292
+ }
293
+ </article>
294
+ `, styles: [":host{display:block}.action-card{position:relative;display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--card-bg, var(--ion-card-background, var(--ion-background-color)));border-radius:12px;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,background-color .2s ease;text-decoration:none;overflow:hidden;--ripple-color: var(--ion-color-primary)}.action-card--small{padding:.75rem;gap:.75rem}.action-card--small .action-card__icon{width:36px;height:36px;font-size:18px;border-radius:8px}.action-card--small .action-card__icon svg{width:18px;height:18px}.action-card--small .action-card__title{font-size:.9rem}.action-card--small .action-card__description{font-size:.8rem}.action-card--medium{padding:1rem;gap:1rem}.action-card--medium .action-card__icon{width:48px;height:48px;font-size:24px;border-radius:10px}.action-card--medium .action-card__icon svg{width:24px;height:24px}.action-card--medium .action-card__title{font-size:1rem}.action-card--medium .action-card__description{font-size:.875rem}.action-card--large{padding:1.25rem;gap:1.25rem}.action-card--large .action-card__icon{width:56px;height:56px;font-size:28px;border-radius:12px}.action-card--large .action-card__icon svg{width:28px;height:28px}.action-card--large .action-card__title{font-size:1.1rem}.action-card--large .action-card__description{font-size:.9rem}.action-card--bordered{border:1px solid var(--card-border-color, var(--ion-color-light-shade))}.action-card--shadowed{box-shadow:0 2px 8px #00000014}.action-card--clickable:hover{transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.action-card--clickable:focus-visible{outline:2px solid var(--ion-color-primary);outline-offset:2px}.action-card--clickable:active{transform:translateY(0)}.action-card--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.action-card__badge{position:absolute;top:8px;right:8px;padding:2px 8px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;border-radius:10px;z-index:1}.action-card__icon{flex-shrink:0;display:flex;align-items:center;justify-content:center}.action-card__icon ion-icon{font-size:inherit}.action-card__icon svg{display:block}.action-card__icon-image{width:100%;height:100%;object-fit:cover;border-radius:8px}.action-card__content{flex:1;min-width:0}.action-card__title{margin:0 0 .25rem;font-weight:600;color:var(--ion-text-color);line-height:1.3}.action-card__description{margin:0;color:var(--ion-color-medium);line-height:1.4}.action-card__chevron{flex-shrink:0;font-size:1.25rem;color:var(--ion-color-medium);transition:transform .2s ease}.action-card--clickable:hover .action-card__chevron{transform:translate(4px)}@media (prefers-color-scheme: dark){.action-card--shadowed{box-shadow:0 2px 8px #0000004d}.action-card--clickable:hover{box-shadow:0 4px 16px #0006}}:host-context(.dark) .action-card--shadowed,:host-context(body.dark) .action-card--shadowed,:host-context([data-theme=dark]) .action-card--shadowed{box-shadow:0 2px 8px #0000004d}:host-context(.dark) .action-card--clickable:hover,:host-context(body.dark) .action-card--clickable:hover,:host-context([data-theme=dark]) .action-card--clickable:hover{box-shadow:0 4px 16px #0006}\n"] }]
295
+ }], propDecorators: { cardClick: [{
296
+ type: Output
297
+ }] } });
298
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWNhcmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL21vbGVjdWxlcy9hY3Rpb24tY2FyZC9hY3Rpb24tY2FyZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCxTQUFTLEVBQ1QsUUFBUSxFQUNSLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN6RSxPQUFPLEVBR0wsb0JBQW9CLEdBQ3JCLE1BQU0sU0FBUyxDQUFDOztBQUVqQixRQUFRLENBQUMsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7QUFFcEMsTUFBTSxZQUFZLEdBQUc7SUFDbkIsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsU0FBUztJQUM3QyxTQUFTLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTTtDQUMvQyxDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDRztBQW1GSCxNQUFNLE9BQU8sbUJBQW1CO0lBbEZoQztRQW1GVSxTQUFJLEdBQUcs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Ozs7Ozs7Ozs7Ozs7OztHQTJFVDs4QkFXUyxTQUFTO3NCQUFsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIEV2ZW50RW1pdHRlcixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgT3V0cHV0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlckxpbmsgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgSW9uSWNvbiwgSW9uUmlwcGxlRWZmZWN0IH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBhZGRJY29ucyB9IGZyb20gJ2lvbmljb25zJztcbmltcG9ydCB7IGNoZXZyb25Gb3J3YXJkT3V0bGluZSB9IGZyb20gJ2lvbmljb25zL2ljb25zJztcbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaTE4bic7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL25hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQge1xuICBBY3Rpb25DYXJkTWV0YWRhdGEsXG4gIEFjdGlvbkNhcmRDbGlja0V2ZW50LFxuICBBQ1RJT05fQ0FSRF9ERUZBVUxUUyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmFkZEljb25zKHsgY2hldnJvbkZvcndhcmRPdXRsaW5lIH0pO1xuXG5jb25zdCBJT05JQ19DT0xPUlMgPSBbXG4gICdwcmltYXJ5JywgJ3NlY29uZGFyeScsICd0ZXJ0aWFyeScsICdzdWNjZXNzJyxcbiAgJ3dhcm5pbmcnLCAnZGFuZ2VyJywgJ2xpZ2h0JywgJ21lZGl1bScsICdkYXJrJ1xuXTtcblxuLyoqXG4gKiB2YWwtYWN0aW9uLWNhcmRcbiAqXG4gKiBBIGNsaWNrYWJsZSBjYXJkIGNvbXBvbmVudCB3aXRoIGljb24sIHRpdGxlLCBkZXNjcmlwdGlvbiwgYW5kIG9wdGlvbmFsIGJhZGdlLlxuICogU3VwcG9ydHMgbXVsdGlwbGUgaWNvbiBmb3JtYXRzOiBJb25pY29ucywgU1ZHIHBhdGhzLCBhbmQgaW1hZ2UgVVJMcy5cbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyB1c2FnZSB3aXRoIElvbmljb25cbiAqIGBgYGh0bWxcbiAqIDx2YWwtYWN0aW9uLWNhcmRcbiAqICAgW3Byb3BzXT1cIntcbiAqICAgICBpY29uOiB7IGlvbmljb246ICdzZXR0aW5ncy1vdXRsaW5lJyB9LFxuICogICAgIHRpdGxlOiAnU2V0dGluZ3MnLFxuICogICAgIGRlc2NyaXB0aW9uOiAnTWFuYWdlIHlvdXIgcHJlZmVyZW5jZXMnXG4gKiAgIH1cIlxuICogICAoY2FyZENsaWNrKT1cIm9uQ2FyZENsaWNrKCRldmVudClcIlxuICogLz5cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFdpdGggcm91dGVyTGluayBuYXZpZ2F0aW9uXG4gKiBgYGBodG1sXG4gKiA8dmFsLWFjdGlvbi1jYXJkXG4gKiAgIFtwcm9wc109XCJ7XG4gKiAgICAgaWNvbjogeyBpb25pY29uOiAncGVyc29uLW91dGxpbmUnLCBjb2xvcjogJ3ByaW1hcnknIH0sXG4gKiAgICAgdGl0bGU6ICdQcm9maWxlJyxcbiAqICAgICBkZXNjcmlwdGlvbjogJ1ZpZXcgYW5kIGVkaXQgeW91ciBwcm9maWxlJyxcbiAqICAgICByb3V0ZXJMaW5rOiAnL3NldHRpbmdzL3Byb2ZpbGUnLFxuICogICAgIHNob3dDaGV2cm9uOiB0cnVlXG4gKiAgIH1cIlxuICogLz5cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFdpdGggY3VzdG9tIFNWRyBpY29uXG4gKiBgYGBodG1sXG4gKiA8dmFsLWFjdGlvbi1jYXJkXG4gKiAgIFtwcm9wc109XCJ7XG4gKiAgICAgaWNvbjogeyBzdmdQYXRoOiAnTTEyIDJMMiA3bDEwIDUgMTAtNS0xMC01ek0yIDE3bDEwIDUgMTAtNU0yIDEybDEwIDUgMTAtNScgfSxcbiAqICAgICB0aXRsZTogJ0N1c3RvbSBGZWF0dXJlJyxcbiAqICAgICBkZXNjcmlwdGlvbjogJ0EgZmVhdHVyZSB3aXRoIGN1c3RvbSBTVkcgaWNvbicsXG4gKiAgICAgYmFkZ2U6IHsgdGV4dDogJ05FVycsIGNvbG9yOiAnbGlnaHQnLCBiYWNrZ3JvdW5kQ29sb3I6ICdwcmltYXJ5JyB9XG4gKiAgIH1cIlxuICogLz5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtYWN0aW9uLWNhcmQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBSb3V0ZXJMaW5rLCBJb25JY29uLCBJb25SaXBwbGVFZmZlY3RdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxhcnRpY2xlXG4gICAgICBjbGFzcz1cImFjdGlvbi1jYXJkXCJcbiAgICAgIFtjbGFzcy5hY3Rpb24tY2FyZC0tc21hbGxdPVwiY29uZmlnKCkuc2l6ZSA9PT0gJ3NtYWxsJ1wiXG4gICAgICBbY2xhc3MuYWN0aW9uLWNhcmQtLW1lZGl1bV09XCJjb25maWcoKS5zaXplID09PSAnbWVkaXVtJ1wiXG4gICAgICBbY2xhc3MuYWN0aW9uLWNhcmQtLWxhcmdlXT1cImNvbmZpZygpLnNpemUgPT09ICdsYXJnZSdcIlxuICAgICAgW2NsYXNzLmFjdGlvbi1jYXJkLS1ib3JkZXJlZF09XCJjb25maWcoKS5ib3JkZXJlZFwiXG4gICAgICBbY2xhc3MuYWN0aW9uLWNhcmQtLXNoYWRvd2VkXT1cImNvbmZpZygpLnNoYWRvd2VkXCJcbiAgICAgIFtjbGFzcy5hY3Rpb24tY2FyZC0tZGlzYWJsZWRdPVwiY29uZmlnKCkuZGlzYWJsZWRcIlxuICAgICAgW2NsYXNzLmFjdGlvbi1jYXJkLS1jbGlja2FibGVdPVwiIWNvbmZpZygpLmRpc2FibGVkXCJcbiAgICAgIFtzdHlsZS4tLWNhcmQtYmddPVwiZ2V0QmFja2dyb3VuZENvbG9yKClcIlxuICAgICAgW3N0eWxlLi0tY2FyZC1ib3JkZXItY29sb3JdPVwiZ2V0Qm9yZGVyQ29sb3IoKVwiXG4gICAgICBbcm91dGVyTGlua109XCJjb25maWcoKS5kaXNhYmxlZCA/IG51bGwgOiBjb25maWcoKS5yb3V0ZXJMaW5rXCJcbiAgICAgIChjbGljayk9XCJoYW5kbGVDbGljaygkZXZlbnQpXCJcbiAgICAgIFthdHRyLnRhYmluZGV4XT1cImNvbmZpZygpLmRpc2FibGVkID8gLTEgOiAwXCJcbiAgICAgIFthdHRyLnJvbGVdPVwiJ2J1dHRvbidcIlxuICAgICAgW2F0dHIuYXJpYS1kaXNhYmxlZF09XCJjb25maWcoKS5kaXNhYmxlZFwiXG4gICAgPlxuICAgICAgPGlvbi1yaXBwbGUtZWZmZWN0PjwvaW9uLXJpcHBsZS1lZmZlY3Q+XG5cbiAgICAgIDwhLS0gQmFkZ2UgKHRvcC1yaWdodCBjb3JuZXIpIC0tPlxuICAgICAgQGlmIChjb25maWcoKS5iYWRnZSkge1xuICAgICAgICA8c3BhblxuICAgICAgICAgIGNsYXNzPVwiYWN0aW9uLWNhcmRfX2JhZGdlXCJcbiAgICAgICAgICBbc3R5bGUuY29sb3JdPVwiZ2V0QmFkZ2VDb2xvcigpXCJcbiAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJnZXRCYWRnZUJhY2tncm91bmRDb2xvcigpXCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IGNvbmZpZygpLmJhZGdlIS50ZXh0IH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIH1cblxuICAgICAgPCEtLSBJY29uIENvbnRhaW5lciAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJhY3Rpb24tY2FyZF9faWNvblwiXG4gICAgICAgIFtzdHlsZS5jb2xvcl09XCJnZXRJY29uQ29sb3IoKVwiXG4gICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cImdldEljb25CYWNrZ3JvdW5kQ29sb3IoKVwiXG4gICAgICA+XG4gICAgICAgIEBpZiAoY29uZmlnKCkuaWNvbj8uaW9uaWNvbikge1xuICAgICAgICAgIDxpb24taWNvbiBbbmFtZV09XCJjb25maWcoKS5pY29uIS5pb25pY29uIVwiPjwvaW9uLWljb24+XG4gICAgICAgIH0gQGVsc2UgaWYgKGNvbmZpZygpLmljb24/LnN2Z1BhdGgpIHtcbiAgICAgICAgICA8c3ZnXG4gICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgIGZpbGw9XCJub25lXCJcbiAgICAgICAgICAgIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjVcIlxuICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBhdGggW2F0dHIuZF09XCJjb25maWcoKS5pY29uIS5zdmdQYXRoXCIgLz5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgfSBAZWxzZSBpZiAoY29uZmlnKCkuaWNvbj8uaW1hZ2VVcmwpIHtcbiAgICAgICAgICA8aW1nXG4gICAgICAgICAgICBbc3JjXT1cImNvbmZpZygpLmljb24hLmltYWdlVXJsXCJcbiAgICAgICAgICAgIFthbHRdPVwiZ2V0VGl0bGUoKVwiXG4gICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1jYXJkX19pY29uLWltYWdlXCJcbiAgICAgICAgICAvPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDb250ZW50IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1jYXJkX19jb250ZW50XCI+XG4gICAgICAgIDxoMyBjbGFzcz1cImFjdGlvbi1jYXJkX190aXRsZVwiPnt7IGdldFRpdGxlKCkgfX08L2gzPlxuICAgICAgICBAaWYgKGdldERlc2NyaXB0aW9uKCkpIHtcbiAgICAgICAgICA8cCBjbGFzcz1cImFjdGlvbi1jYXJkX19kZXNjcmlwdGlvblwiPnt7IGdldERlc2NyaXB0aW9uKCkgfX08L3A+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIENoZXZyb24gKG9wdGlvbmFsKSAtLT5cbiAgICAgIEBpZiAoY29uZmlnKCkuc2hvd0NoZXZyb24gJiYgIWNvbmZpZygpLmRpc2FibGVkKSB7XG4gICAgICAgIDxpb24taWNvblxuICAgICAgICAgIG5hbWU9XCJjaGV2cm9uLWZvcndhcmQtb3V0bGluZVwiXG4gICAgICAgICAgY2xhc3M9XCJhY3Rpb24tY2FyZF9fY2hldnJvblwiXG4gICAgICAgID48L2lvbi1pY29uPlxuICAgICAgfVxuICAgIDwvYXJ0aWNsZT5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vYWN0aW9uLWNhcmQuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgQWN0aW9uQ2FyZENvbXBvbmVudCB7XG4gIHByaXZhdGUgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG4gIHByaXZhdGUgbmF2aWdhdGlvbiA9IGluamVjdChOYXZpZ2F0aW9uU2VydmljZSk7XG5cbiAgLyoqIENvbXBvbmVudCBjb25maWd1cmF0aW9uICovXG4gIHJlYWRvbmx5IHByb3BzID0gaW5wdXQ8UGFydGlhbDxBY3Rpb25DYXJkTWV0YWRhdGE+Pih7fSk7XG5cbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiBjYXJkIGlzIGNsaWNrZWQgKi9cbiAgQE91dHB1dCgpIGNhcmRDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8QWN0aW9uQ2FyZENsaWNrRXZlbnQ+KCk7XG5cbiAgLyoqIE1lcmdlZCBjb25maWd1cmF0aW9uIHdpdGggZGVmYXVsdHMgKi9cbiAgY29uZmlnID0gY29tcHV0ZWQoKCkgPT4gKHtcbiAgICAuLi5BQ1RJT05fQ0FSRF9ERUZBVUxUUyxcbiAgICAuLi50aGlzLnByb3BzKCksXG4gIH0pKTtcblxuICAvKiogR2V0IHRpdGxlIHdpdGggaTE4biBzdXBwb3J0ICovXG4gIGdldFRpdGxlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcoKTtcbiAgICBpZiAoY2ZnLmkxOG5OYW1lc3BhY2UgJiYgY2ZnLnRpdGxlS2V5KSB7XG4gICAgICB0aGlzLmkxOG4ubGFuZygpOyAvLyBUcmFjayBsYW5ndWFnZSBjaGFuZ2VzIGZvciByZWFjdGl2aXR5XG4gICAgICByZXR1cm4gdGhpcy5pMThuLnQoY2ZnLnRpdGxlS2V5LCBjZmcuaTE4bk5hbWVzcGFjZSk7XG4gICAgfVxuICAgIHJldHVybiBjZmcudGl0bGUgfHwgJyc7XG4gIH1cblxuICAvKiogR2V0IGRlc2NyaXB0aW9uIHdpdGggaTE4biBzdXBwb3J0ICovXG4gIGdldERlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5jb25maWcoKTtcbiAgICBpZiAoY2ZnLmkxOG5OYW1lc3BhY2UgJiYgY2ZnLmRlc2NyaXB0aW9uS2V5KSB7XG4gICAgICB0aGlzLmkxOG4ubGFuZygpOyAvLyBUcmFjayBsYW5ndWFnZSBjaGFuZ2VzIGZvciByZWFjdGl2aXR5XG4gICAgICByZXR1cm4gdGhpcy5pMThuLnQoY2ZnLmRlc2NyaXB0aW9uS2V5LCBjZmcuaTE4bk5hbWVzcGFjZSk7XG4gICAgfVxuICAgIHJldHVybiBjZmcuZGVzY3JpcHRpb24gfHwgJyc7XG4gIH1cblxuICAvKiogUmVzb2x2ZSBjb2xvciB0byBDU1MgdmFsdWUgKi9cbiAgcHJpdmF0ZSByZXNvbHZlQ29sb3IoY29sb3I/OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIWNvbG9yKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoSU9OSUNfQ09MT1JTLmluY2x1ZGVzKGNvbG9yKSkge1xuICAgICAgcmV0dXJuIGB2YXIoLS1pb24tY29sb3ItJHtjb2xvcn0pYDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9XG5cbiAgZ2V0QmFja2dyb3VuZENvbG9yKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVDb2xvcih0aGlzLmNvbmZpZygpLmJhY2tncm91bmRDb2xvciBhcyBzdHJpbmcpO1xuICB9XG5cbiAgZ2V0Qm9yZGVyQ29sb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZUNvbG9yKHRoaXMuY29uZmlnKCkuYm9yZGVyQ29sb3IgYXMgc3RyaW5nKSB8fCAndmFyKC0taW9uLWNvbG9yLWxpZ2h0LXNoYWRlKSc7XG4gIH1cblxuICBnZXRJY29uQ29sb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZUNvbG9yKHRoaXMuY29uZmlnKCkuaWNvbj8uY29sb3IgYXMgc3RyaW5nKSB8fCAndmFyKC0taW9uLWNvbG9yLXByaW1hcnkpJztcbiAgfVxuXG4gIGdldEljb25CYWNrZ3JvdW5kQ29sb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgYmcgPSB0aGlzLmNvbmZpZygpLmljb24/LmJhY2tncm91bmRDb2xvcjtcbiAgICBpZiAoIWJnKSByZXR1cm4gJ3JnYmEodmFyKC0taW9uLWNvbG9yLXByaW1hcnktcmdiKSwgMC4xKSc7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZUNvbG9yKGJnIGFzIHN0cmluZyk7XG4gIH1cblxuICBnZXRCYWRnZUNvbG9yKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVDb2xvcih0aGlzLmNvbmZpZygpLmJhZGdlPy5jb2xvciBhcyBzdHJpbmcpIHx8ICd3aGl0ZSc7XG4gIH1cblxuICBnZXRCYWRnZUJhY2tncm91bmRDb2xvcigpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlQ29sb3IodGhpcy5jb25maWcoKS5iYWRnZT8uYmFja2dyb3VuZENvbG9yIGFzIHN0cmluZykgfHwgJ3ZhcigtLWlvbi1jb2xvci1wcmltYXJ5KSc7XG4gIH1cblxuICAvKiogSGFuZGxlIGNhcmQgY2xpY2sgKi9cbiAgaGFuZGxlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBjZmcgPSB0aGlzLmNvbmZpZygpO1xuXG4gICAgaWYgKGNmZy5kaXNhYmxlZCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEVtaXQgY2xpY2sgZXZlbnRcbiAgICB0aGlzLmNhcmRDbGljay5lbWl0KHtcbiAgICAgIHRva2VuOiBjZmcudG9rZW4sXG4gICAgICBuYXZpZ2F0ZWQ6ICEhY2ZnLnJvdXRlckxpbmsgfHwgISFjZmcuaHJlZixcbiAgICB9KTtcblxuICAgIC8vIEhhbmRsZSBleHRlcm5hbCBVUkxcbiAgICBpZiAoY2ZnLmhyZWYpIHtcbiAgICAgIHRoaXMubmF2aWdhdGlvbi5vcGVuSW5OZXdUYWIoY2ZnLmhyZWYpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Default values for ActionCardMetadata
3
+ */
4
+ export const ACTION_CARD_DEFAULTS = {
5
+ size: 'medium',
6
+ bordered: false,
7
+ shadowed: true,
8
+ disabled: false,
9
+ showChevron: false,
10
+ };
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvbW9sZWN1bGVzL2FjdGlvbi1jYXJkL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTBGQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUU3QjtJQUNGLElBQUksRUFBRSxRQUFRO0lBQ2QsUUFBUSxFQUFFLEtBQUs7SUFDZixRQUFRLEVBQUUsSUFBSTtJQUNkLFFBQVEsRUFBRSxLQUFLO0lBQ2YsV0FBVyxFQUFFLEtBQUs7Q0FDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbG9yIH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuXG4vKipcbiAqIFNpemUgb3B0aW9ucyBmb3IgYWN0aW9uLWNhcmRcbiAqL1xuZXhwb3J0IHR5cGUgQWN0aW9uQ2FyZFNpemUgPSAnc21hbGwnIHwgJ21lZGl1bScgfCAnbGFyZ2UnO1xuXG4vKipcbiAqIEJhZGdlIGNvbmZpZ3VyYXRpb24gZm9yIGFjdGlvbi1jYXJkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uQ2FyZEJhZGdlIHtcbiAgLyoqIEJhZGdlIHRleHQgKi9cbiAgdGV4dDogc3RyaW5nO1xuICAvKiogQmFkZ2UgY29sb3IgKElvbmljIGNvbG9yIG5hbWUgb3IgQ1NTIGNvbG9yKSAqL1xuICBjb2xvcj86IENvbG9yIHwgc3RyaW5nO1xuICAvKiogQmFkZ2UgYmFja2dyb3VuZCBjb2xvciAqL1xuICBiYWNrZ3JvdW5kQ29sb3I/OiBDb2xvciB8IHN0cmluZztcbn1cblxuLyoqXG4gKiBJY29uIGNvbmZpZ3VyYXRpb24gLSBzdXBwb3J0cyBtdWx0aXBsZSBpY29uIHNvdXJjZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY3Rpb25DYXJkSWNvbiB7XG4gIC8qKiBJb25pY29uIG5hbWUgKGUuZy4sICdzZXR0aW5ncy1vdXRsaW5lJywgJ2hvbWUnKSAqL1xuICBpb25pY29uPzogc3RyaW5nO1xuICAvKiogU1ZHIHBhdGggZGF0YSBmb3IgY3VzdG9tIGljb25zICovXG4gIHN2Z1BhdGg/OiBzdHJpbmc7XG4gIC8qKiBJbWFnZSBVUkwgZm9yIGN1c3RvbSBpbWFnZXMgKi9cbiAgaW1hZ2VVcmw/OiBzdHJpbmc7XG4gIC8qKiBJY29uIGNvbG9yIChJb25pYyBjb2xvciBuYW1lIG9yIENTUyBjb2xvcikgKi9cbiAgY29sb3I/OiBDb2xvciB8IHN0cmluZztcbiAgLyoqIEljb24gYmFja2dyb3VuZCBjb2xvciAqL1xuICBiYWNrZ3JvdW5kQ29sb3I/OiBDb2xvciB8IHN0cmluZztcbn1cblxuLyoqXG4gKiBDbGljayBldmVudCBlbWl0dGVkIGJ5IGFjdGlvbi1jYXJkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uQ2FyZENsaWNrRXZlbnQge1xuICAvKiogVG9rZW4gaWRlbnRpZmllciBmb3IgdGhlIGNhcmQgKi9cbiAgdG9rZW4/OiBzdHJpbmc7XG4gIC8qKiBXaGV0aGVyIG5hdmlnYXRpb24gd2FzIHRyaWdnZXJlZCAoaWYgcm91dGVyTGluayB3YXMgc2V0KSAqL1xuICBuYXZpZ2F0ZWQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIGZvciB2YWwtYWN0aW9uLWNhcmQgY29tcG9uZW50XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uQ2FyZE1ldGFkYXRhIHtcbiAgLyoqIFVuaXF1ZSB0b2tlbiBmb3IgaWRlbnRpZmljYXRpb24gKi9cbiAgdG9rZW4/OiBzdHJpbmc7XG5cbiAgLyoqIEljb24gY29uZmlndXJhdGlvbiBvYmplY3QgKi9cbiAgaWNvbj86IEFjdGlvbkNhcmRJY29uO1xuXG4gIC8qKiBDYXJkIHRpdGxlIChzdGF0aWMgdGV4dCkgKi9cbiAgdGl0bGU6IHN0cmluZztcbiAgLyoqIGkxOG4ga2V5IGZvciB0aXRsZSAqL1xuICB0aXRsZUtleT86IHN0cmluZztcbiAgLyoqIENhcmQgZGVzY3JpcHRpb24gKHN0YXRpYyB0ZXh0KSAqL1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqIGkxOG4ga2V5IGZvciBkZXNjcmlwdGlvbiAqL1xuICBkZXNjcmlwdGlvbktleT86IHN0cmluZztcbiAgLyoqIGkxOG4gbmFtZXNwYWNlIGZvciB0cmFuc2xhdGlvbnMgKi9cbiAgaTE4bk5hbWVzcGFjZT86IHN0cmluZztcblxuICAvKiogQ2FyZCBzaXplIHZhcmlhbnQgKi9cbiAgc2l6ZT86IEFjdGlvbkNhcmRTaXplO1xuICAvKiogU2hvdyBib3JkZXIgKi9cbiAgYm9yZGVyZWQ/OiBib29sZWFuO1xuICAvKiogQm9yZGVyIGNvbG9yICovXG4gIGJvcmRlckNvbG9yPzogQ29sb3IgfCBzdHJpbmc7XG4gIC8qKiBDYXJkIGJhY2tncm91bmQgY29sb3IgKi9cbiAgYmFja2dyb3VuZENvbG9yPzogQ29sb3IgfCBzdHJpbmc7XG4gIC8qKiBTaG93IHNoYWRvdyAqL1xuICBzaGFkb3dlZD86IGJvb2xlYW47XG5cbiAgLyoqIERpc2FibGVkIHN0YXRlICovXG4gIGRpc2FibGVkPzogYm9vbGVhbjtcbiAgLyoqIFJvdXRlciBsaW5rIGZvciBuYXZpZ2F0aW9uICovXG4gIHJvdXRlckxpbms/OiBzdHJpbmcgfCBhbnlbXTtcbiAgLyoqIEV4dGVybmFsIFVSTCAob3BlbnMgaW4gbmV3IHRhYi9icm93c2VyKSAqL1xuICBocmVmPzogc3RyaW5nO1xuXG4gIC8qKiBCYWRnZSBjb25maWd1cmF0aW9uICovXG4gIGJhZGdlPzogQWN0aW9uQ2FyZEJhZGdlO1xuICAvKiogU2hvdyBjaGV2cm9uIGljb24gb24gdGhlIHJpZ2h0ICovXG4gIHNob3dDaGV2cm9uPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IHZhbHVlcyBmb3IgQWN0aW9uQ2FyZE1ldGFkYXRhXG4gKi9cbmV4cG9ydCBjb25zdCBBQ1RJT05fQ0FSRF9ERUZBVUxUUzogUmVxdWlyZWQ8XG4gIFBpY2s8QWN0aW9uQ2FyZE1ldGFkYXRhLCAnc2l6ZScgfCAnYm9yZGVyZWQnIHwgJ3NoYWRvd2VkJyB8ICdkaXNhYmxlZCcgfCAnc2hvd0NoZXZyb24nPlxuPiA9IHtcbiAgc2l6ZTogJ21lZGl1bScsXG4gIGJvcmRlcmVkOiBmYWxzZSxcbiAgc2hhZG93ZWQ6IHRydWUsXG4gIGRpc2FibGVkOiBmYWxzZSxcbiAgc2hvd0NoZXZyb246IGZhbHNlLFxufTtcbiJdfQ==
@@ -0,0 +1,236 @@
1
+ import { Component, Input, computed } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonList, IonItem, IonLabel, IonIcon, IonButton, IonText, IonChip, AlertController, } from '@ionic/angular/standalone';
4
+ import { addIcons } from 'ionicons';
5
+ import { logoGoogle, logoApple, logoMicrosoft, linkOutline, unlinkOutline, checkmarkCircle, } from 'ionicons/icons';
6
+ import { OAUTH_PROVIDERS_INFO } from './types';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ addIcons({
10
+ logoGoogle,
11
+ logoApple,
12
+ logoMicrosoft,
13
+ linkOutline,
14
+ unlinkOutline,
15
+ checkmarkCircle,
16
+ });
17
+ /**
18
+ * Linked Providers Component
19
+ *
20
+ * Muestra los proveedores OAuth vinculados al usuario y permite
21
+ * vincular nuevos o desvincular existentes.
22
+ *
23
+ * @example
24
+ * <val-linked-providers
25
+ * [props]="{
26
+ * providers: linkedProviders(),
27
+ * onLink: linkProvider,
28
+ * onUnlink: unlinkProvider
29
+ * }"
30
+ * />
31
+ */
32
+ export class LinkedProvidersComponent {
33
+ constructor() {
34
+ this.alertCtrl = new AlertController();
35
+ // Computed signals
36
+ this.linkedProviders = computed(() => this.props?.providers || []);
37
+ this.unlinkedProviders = computed(() => {
38
+ const linked = new Set(this.linkedProviders().map(p => p.provider));
39
+ const available = this.props?.availableProviders || ['google'];
40
+ return available
41
+ .filter(p => !linked.has(p))
42
+ .map(p => OAUTH_PROVIDERS_INFO[p]);
43
+ });
44
+ this.canUnlink = computed(() => {
45
+ // Can unlink if there's more than one provider or user has password
46
+ return this.linkedProviders().length > 1;
47
+ });
48
+ }
49
+ getProviderInfo(provider) {
50
+ return OAUTH_PROVIDERS_INFO[provider] || OAUTH_PROVIDERS_INFO.google;
51
+ }
52
+ onLinkProvider(provider) {
53
+ this.props.onLink?.(provider);
54
+ }
55
+ async confirmUnlink(provider) {
56
+ const info = this.getProviderInfo(provider);
57
+ const alert = await this.alertCtrl.create({
58
+ header: 'Desvincular cuenta',
59
+ message: `¿Estás seguro de que quieres desvincular tu cuenta de ${info.name}?`,
60
+ buttons: [
61
+ {
62
+ text: 'Cancelar',
63
+ role: 'cancel',
64
+ },
65
+ {
66
+ text: 'Desvincular',
67
+ role: 'destructive',
68
+ handler: () => {
69
+ this.props.onUnlink?.(provider);
70
+ },
71
+ },
72
+ ],
73
+ });
74
+ await alert.present();
75
+ }
76
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LinkedProvidersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
77
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LinkedProvidersComponent, isStandalone: true, selector: "val-linked-providers", inputs: { props: "props" }, ngImport: i0, template: `
78
+ @if (props.compact) {
79
+ <ng-container *ngTemplateOutlet="providersList" />
80
+ } @else {
81
+ <ion-card>
82
+ <ion-card-header>
83
+ <ion-card-title>{{ props.title || 'Cuentas vinculadas' }}</ion-card-title>
84
+ </ion-card-header>
85
+ <ion-card-content>
86
+ @if (props.description) {
87
+ <p class="section-description">{{ props.description }}</p>
88
+ }
89
+ <ng-container *ngTemplateOutlet="providersList" />
90
+ </ion-card-content>
91
+ </ion-card>
92
+ }
93
+
94
+ <ng-template #providersList>
95
+ <ion-list lines="none" class="providers-list">
96
+ <!-- Linked providers -->
97
+ @for (provider of linkedProviders(); track provider.provider) {
98
+ <ion-item class="provider-item linked">
99
+ <div class="provider-icon" [style.background-color]="getProviderInfo(provider.provider).bgColor" slot="start">
100
+ <ion-icon [name]="getProviderInfo(provider.provider).icon" [style.color]="getProviderInfo(provider.provider).color" />
101
+ </div>
102
+ <ion-label>
103
+ <h3>{{ getProviderInfo(provider.provider).name }}</h3>
104
+ <p>{{ provider.email }}</p>
105
+ </ion-label>
106
+ <ion-icon name="checkmark-circle" color="success" slot="end" class="linked-icon" />
107
+ @if (props.allowUnlink !== false && canUnlink()) {
108
+ <ion-button
109
+ fill="clear"
110
+ color="medium"
111
+ slot="end"
112
+ (click)="confirmUnlink(provider.provider)"
113
+ class="unlink-btn"
114
+ >
115
+ <ion-icon name="unlink-outline" slot="icon-only" />
116
+ </ion-button>
117
+ }
118
+ </ion-item>
119
+ }
120
+
121
+ <!-- Available providers to link -->
122
+ @if (props.showLinkButton !== false) {
123
+ @for (provider of unlinkedProviders(); track provider.id) {
124
+ <ion-item class="provider-item available" button (click)="onLinkProvider(provider.id)">
125
+ <div class="provider-icon muted" slot="start">
126
+ <ion-icon [name]="provider.icon" />
127
+ </div>
128
+ <ion-label>
129
+ <h3>{{ provider.name }}</h3>
130
+ <p>Vincular cuenta</p>
131
+ </ion-label>
132
+ <ion-icon name="link-outline" color="primary" slot="end" />
133
+ </ion-item>
134
+ }
135
+ }
136
+
137
+ @if (linkedProviders().length === 0 && unlinkedProviders().length === 0) {
138
+ <ion-item>
139
+ <ion-label class="ion-text-center">
140
+ <p>No hay proveedores disponibles</p>
141
+ </ion-label>
142
+ </ion-item>
143
+ }
144
+ </ion-list>
145
+ </ng-template>
146
+ `, isInline: true, styles: ["ion-card{margin:0;border-radius:12px;box-shadow:0 1px 3px #00000014}ion-card-title{font-size:1.125rem;font-weight:600}.section-description{margin:0 0 1rem;color:var(--ion-color-medium);font-size:.875rem}.providers-list{padding:0}.provider-item{--padding-start: 0;--padding-end: 0;--inner-padding-end: 0;margin-bottom:.5rem;border-radius:8px;border:1px solid var(--ion-border-color, #e0e0e0)}.provider-item:last-child{margin-bottom:0}.provider-icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;margin-right:.75rem}.provider-icon ion-icon{font-size:1.25rem}.provider-icon.muted{background:var(--ion-color-light)}.provider-icon.muted ion-icon{color:var(--ion-color-medium)}.provider-item ion-label h3{font-weight:600;font-size:.9375rem;margin-bottom:.125rem}.provider-item ion-label p{font-size:.8125rem;color:var(--ion-color-medium)}.linked-icon{font-size:1.25rem}.unlink-btn{--padding-start: .5rem;--padding-end: .5rem}.provider-item.available{cursor:pointer}.provider-item.available:hover{background:var(--ion-color-light-tint)}:host-context(body.dark){.provider-item{border-color:var(--ion-color-step-150)}.provider-icon.muted{background:var(--ion-color-step-100)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }] }); }
147
+ }
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LinkedProvidersComponent, decorators: [{
149
+ type: Component,
150
+ args: [{ selector: 'val-linked-providers', standalone: true, imports: [
151
+ CommonModule,
152
+ IonCard,
153
+ IonCardHeader,
154
+ IonCardTitle,
155
+ IonCardContent,
156
+ IonList,
157
+ IonItem,
158
+ IonLabel,
159
+ IonIcon,
160
+ IonButton,
161
+ IonText,
162
+ IonChip,
163
+ ], template: `
164
+ @if (props.compact) {
165
+ <ng-container *ngTemplateOutlet="providersList" />
166
+ } @else {
167
+ <ion-card>
168
+ <ion-card-header>
169
+ <ion-card-title>{{ props.title || 'Cuentas vinculadas' }}</ion-card-title>
170
+ </ion-card-header>
171
+ <ion-card-content>
172
+ @if (props.description) {
173
+ <p class="section-description">{{ props.description }}</p>
174
+ }
175
+ <ng-container *ngTemplateOutlet="providersList" />
176
+ </ion-card-content>
177
+ </ion-card>
178
+ }
179
+
180
+ <ng-template #providersList>
181
+ <ion-list lines="none" class="providers-list">
182
+ <!-- Linked providers -->
183
+ @for (provider of linkedProviders(); track provider.provider) {
184
+ <ion-item class="provider-item linked">
185
+ <div class="provider-icon" [style.background-color]="getProviderInfo(provider.provider).bgColor" slot="start">
186
+ <ion-icon [name]="getProviderInfo(provider.provider).icon" [style.color]="getProviderInfo(provider.provider).color" />
187
+ </div>
188
+ <ion-label>
189
+ <h3>{{ getProviderInfo(provider.provider).name }}</h3>
190
+ <p>{{ provider.email }}</p>
191
+ </ion-label>
192
+ <ion-icon name="checkmark-circle" color="success" slot="end" class="linked-icon" />
193
+ @if (props.allowUnlink !== false && canUnlink()) {
194
+ <ion-button
195
+ fill="clear"
196
+ color="medium"
197
+ slot="end"
198
+ (click)="confirmUnlink(provider.provider)"
199
+ class="unlink-btn"
200
+ >
201
+ <ion-icon name="unlink-outline" slot="icon-only" />
202
+ </ion-button>
203
+ }
204
+ </ion-item>
205
+ }
206
+
207
+ <!-- Available providers to link -->
208
+ @if (props.showLinkButton !== false) {
209
+ @for (provider of unlinkedProviders(); track provider.id) {
210
+ <ion-item class="provider-item available" button (click)="onLinkProvider(provider.id)">
211
+ <div class="provider-icon muted" slot="start">
212
+ <ion-icon [name]="provider.icon" />
213
+ </div>
214
+ <ion-label>
215
+ <h3>{{ provider.name }}</h3>
216
+ <p>Vincular cuenta</p>
217
+ </ion-label>
218
+ <ion-icon name="link-outline" color="primary" slot="end" />
219
+ </ion-item>
220
+ }
221
+ }
222
+
223
+ @if (linkedProviders().length === 0 && unlinkedProviders().length === 0) {
224
+ <ion-item>
225
+ <ion-label class="ion-text-center">
226
+ <p>No hay proveedores disponibles</p>
227
+ </ion-label>
228
+ </ion-item>
229
+ }
230
+ </ion-list>
231
+ </ng-template>
232
+ `, styles: ["ion-card{margin:0;border-radius:12px;box-shadow:0 1px 3px #00000014}ion-card-title{font-size:1.125rem;font-weight:600}.section-description{margin:0 0 1rem;color:var(--ion-color-medium);font-size:.875rem}.providers-list{padding:0}.provider-item{--padding-start: 0;--padding-end: 0;--inner-padding-end: 0;margin-bottom:.5rem;border-radius:8px;border:1px solid var(--ion-border-color, #e0e0e0)}.provider-item:last-child{margin-bottom:0}.provider-icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;margin-right:.75rem}.provider-icon ion-icon{font-size:1.25rem}.provider-icon.muted{background:var(--ion-color-light)}.provider-icon.muted ion-icon{color:var(--ion-color-medium)}.provider-item ion-label h3{font-weight:600;font-size:.9375rem;margin-bottom:.125rem}.provider-item ion-label p{font-size:.8125rem;color:var(--ion-color-medium)}.linked-icon{font-size:1.25rem}.unlink-btn{--padding-start: .5rem;--padding-end: .5rem}.provider-item.available{cursor:pointer}.provider-item.available:hover{background:var(--ion-color-light-tint)}:host-context(body.dark){.provider-item{border-color:var(--ion-color-step-150)}.provider-icon.muted{background:var(--ion-color-step-100)}}\n"] }]
233
+ }], propDecorators: { props: [{
234
+ type: Input
235
+ }] } });
236
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlua2VkLXByb3ZpZGVycy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvbW9sZWN1bGVzL2xpbmtlZC1wcm92aWRlcnMvbGlua2VkLXByb3ZpZGVycy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsT0FBTyxFQUNQLGFBQWEsRUFDYixZQUFZLEVBQ1osY0FBYyxFQUNkLE9BQU8sRUFDUCxPQUFPLEVBQ1AsUUFBUSxFQUNSLE9BQU8sRUFDUCxTQUFTLEVBQ1QsT0FBTyxFQUNQLE9BQU8sRUFDUCxlQUFlLEdBQ2hCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEVBQ0wsVUFBVSxFQUNWLFNBQVMsRUFDVCxhQUFhLEVBQ2IsV0FBVyxFQUNYLGFBQWEsRUFDYixlQUFlLEdBQ2hCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUEyQixvQkFBb0IsRUFBdUIsTUFBTSxTQUFTLENBQUM7OztBQUc3RixRQUFRLENBQUM7SUFDUCxVQUFVO0lBQ1YsU0FBUztJQUNULGFBQWE7SUFDYixXQUFXO0lBQ1gsYUFBYTtJQUNiLGVBQWU7Q0FDaEIsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUF5TEgsTUFBTSxPQUFPLHdCQUF3QjtJQXhMckM7UUEyTFUsY0FBUyxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFFMUMsbUJBQW1CO1FBQ25CLG9CQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FB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dCwgSW5wdXQsIGNvbXB1dGVkLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBJb25DYXJkLFxuICBJb25DYXJkSGVhZGVyLFxuICBJb25DYXJkVGl0bGUsXG4gIElvbkNhcmRDb250ZW50LFxuICBJb25MaXN0LFxuICBJb25JdGVtLFxuICBJb25MYWJlbCxcbiAgSW9uSWNvbixcbiAgSW9uQnV0dG9uLFxuICBJb25UZXh0LFxuICBJb25DaGlwLFxuICBBbGVydENvbnRyb2xsZXIsXG59IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuaW1wb3J0IHsgYWRkSWNvbnMgfSBmcm9tICdpb25pY29ucyc7XG5pbXBvcnQge1xuICBsb2dvR29vZ2xlLFxuICBsb2dvQXBwbGUsXG4gIGxvZ29NaWNyb3NvZnQsXG4gIGxpbmtPdXRsaW5lLFxuICB1bmxpbmtPdXRsaW5lLFxuICBjaGVja21hcmtDaXJjbGUsXG59IGZyb20gJ2lvbmljb25zL2ljb25zJztcbmltcG9ydCB7IExpbmtlZFByb3ZpZGVyc01ldGFkYXRhLCBPQVVUSF9QUk9WSURFUlNfSU5GTywgUHJvdmlkZXJEaXNwbGF5SW5mbyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgTGlua2VkUHJvdmlkZXIsIE9BdXRoUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hdXRoL3R5cGVzJztcblxuYWRkSWNvbnMoe1xuICBsb2dvR29vZ2xlLFxuICBsb2dvQXBwbGUsXG4gIGxvZ29NaWNyb3NvZnQsXG4gIGxpbmtPdXRsaW5lLFxuICB1bmxpbmtPdXRsaW5lLFxuICBjaGVja21hcmtDaXJjbGUsXG59KTtcblxuLyoqXG4gKiBMaW5rZWQgUHJvdmlkZXJzIENvbXBvbmVudFxuICpcbiAqIE11ZXN0cmEgbG9zIHByb3ZlZWRvcmVzIE9BdXRoIHZpbmN1bGFkb3MgYWwgdXN1YXJpbyB5IHBlcm1pdGVcbiAqIHZpbmN1bGFyIG51ZXZvcyBvIGRlc3ZpbmN1bGFyIGV4aXN0ZW50ZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIDx2YWwtbGlua2VkLXByb3ZpZGVyc1xuICogICBbcHJvcHNdPVwie1xuICogICAgIHByb3ZpZGVyczogbGlua2VkUHJvdmlkZXJzKCksXG4gKiAgICAgb25MaW5rOiBsaW5rUHJvdmlkZXIsXG4gKiAgICAgb25Vbmxpbms6IHVubGlua1Byb3ZpZGVyXG4gKiAgIH1cIlxuICogLz5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndmFsLWxpbmtlZC1wcm92aWRlcnMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIElvbkNhcmQsXG4gICAgSW9uQ2FyZEhlYWRlcixcbiAgICBJb25DYXJkVGl0bGUsXG4gICAgSW9uQ2FyZENvbnRlbnQsXG4gICAgSW9uTGlzdCxcbiAgICBJb25JdGVtLFxuICAgIElvbkxhYmVsLFxuICAgIElvbkljb24sXG4gICAgSW9uQnV0dG9uLFxuICAgIElvblRleHQsXG4gICAgSW9uQ2hpcCxcbiAgXSxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKHByb3BzLmNvbXBhY3QpIHtcbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwcm92aWRlcnNMaXN0XCIgLz5cbiAgICB9IEBlbHNlIHtcbiAgICAgIDxpb24tY2FyZD5cbiAgICAgICAgPGlvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWNhcmQtdGl0bGU+e3sgcHJvcHMudGl0bGUgfHwgJ0N1ZW50YXMgdmluY3VsYWRhcycgfX08L2lvbi1jYXJkLXRpdGxlPlxuICAgICAgICA8L2lvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgPGlvbi1jYXJkLWNvbnRlbnQ+XG4gICAgICAgICAgQGlmIChwcm9wcy5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgPHAgY2xhc3M9XCJzZWN0aW9uLWRlc2NyaXB0aW9uXCI+e3sgcHJvcHMuZGVzY3JpcHRpb24gfX08L3A+XG4gICAgICAgICAgfVxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwcm92aWRlcnNMaXN0XCIgLz5cbiAgICAgICAgPC9pb24tY2FyZC1jb250ZW50PlxuICAgICAgPC9pb24tY2FyZD5cbiAgICB9XG5cbiAgICA8bmctdGVtcGxhdGUgI3Byb3ZpZGVyc0xpc3Q+XG4gICAgICA8aW9uLWxpc3QgbGluZXM9XCJub25lXCIgY2xhc3M9XCJwcm92aWRlcnMtbGlzdFwiPlxuICAgICAgICA8IS0tIExpbmtlZCBwcm92aWRlcnMgLS0+XG4gICAgICAgIEBmb3IgKHByb3ZpZGVyIG9mIGxpbmtlZFByb3ZpZGVycygpOyB0cmFjayBwcm92aWRlci5wcm92aWRlcikge1xuICAgICAgICAgIDxpb24taXRlbSBjbGFzcz1cInByb3ZpZGVyLWl0ZW0gbGlua2VkXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvdmlkZXItaWNvblwiIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cImdldFByb3ZpZGVySW5mbyhwcm92aWRlci5wcm92aWRlcikuYmdDb2xvclwiIHNsb3Q9XCJzdGFydFwiPlxuICAgICAgICAgICAgICA8aW9uLWljb24gW25hbWVdPVwiZ2V0UHJvdmlkZXJJbmZvKHByb3ZpZGVyLnByb3ZpZGVyKS5pY29uXCIgW3N0eWxlLmNvbG9yXT1cImdldFByb3ZpZGVySW5mbyhwcm92aWRlci5wcm92aWRlcikuY29sb3JcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8aW9uLWxhYmVsPlxuICAgICAgICAgICAgICA8aDM+e3sgZ2V0UHJvdmlkZXJJbmZvKHByb3ZpZGVyLnByb3ZpZGVyKS5uYW1lIH19PC9oMz5cbiAgICAgICAgICAgICAgPHA+e3sgcHJvdmlkZXIuZW1haWwgfX08L3A+XG4gICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2hlY2ttYXJrLWNpcmNsZVwiIGNvbG9yPVwic3VjY2Vzc1wiIHNsb3Q9XCJlbmRcIiBjbGFzcz1cImxpbmtlZC1pY29uXCIgLz5cbiAgICAgICAgICAgIEBpZiAocHJvcHMuYWxsb3dVbmxpbmsgIT09IGZhbHNlICYmIGNhblVubGluaygpKSB7XG4gICAgICAgICAgICAgIDxpb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgZmlsbD1cImNsZWFyXCJcbiAgICAgICAgICAgICAgICBjb2xvcj1cIm1lZGl1bVwiXG4gICAgICAgICAgICAgICAgc2xvdD1cImVuZFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbmZpcm1VbmxpbmsocHJvdmlkZXIucHJvdmlkZXIpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInVubGluay1idG5cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJ1bmxpbmstb3V0bGluZVwiIHNsb3Q9XCJpY29uLW9ubHlcIiAvPlxuICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgfVxuXG4gICAgICAgIDwhLS0gQXZhaWxhYmxlIHByb3ZpZGVycyB0byBsaW5rIC0tPlxuICAgICAgICBAaWYgKHByb3BzLnNob3dMaW5rQnV0dG9uICE9PSBmYWxzZSkge1xuICAgICAgICAgIEBmb3IgKHByb3ZpZGVyIG9mIHVubGlua2VkUHJvdmlkZXJzKCk7IHRyYWNrIHByb3ZpZGVyLmlkKSB7XG4gICAgICAgICAgICA8aW9uLWl0ZW0gY2xhc3M9XCJwcm92aWRlci1pdGVtIGF2YWlsYWJsZVwiIGJ1dHRvbiAoY2xpY2spPVwib25MaW5rUHJvdmlkZXIocHJvdmlkZXIuaWQpXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm92aWRlci1pY29uIG11dGVkXCIgc2xvdD1cInN0YXJ0XCI+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uIFtuYW1lXT1cInByb3ZpZGVyLmljb25cIiAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGlvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aDM+e3sgcHJvdmlkZXIubmFtZSB9fTwvaDM+XG4gICAgICAgICAgICAgICAgPHA+VmluY3VsYXIgY3VlbnRhPC9wPlxuICAgICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJsaW5rLW91dGxpbmVcIiBjb2xvcj1cInByaW1hcnlcIiBzbG90PVwiZW5kXCIgLz5cbiAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChsaW5rZWRQcm92aWRlcnMoKS5sZW5ndGggPT09IDAgJiYgdW5saW5rZWRQcm92aWRlcnMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICA8aW9uLWl0ZW0+XG4gICAgICAgICAgICA8aW9uLWxhYmVsIGNsYXNzPVwiaW9uLXRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxwPk5vIGhheSBwcm92ZWVkb3JlcyBkaXNwb25pYmxlczwvcD5cbiAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgIH1cbiAgICAgIDwvaW9uLWxpc3Q+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIGlvbi1jYXJkIHtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgICBib3gtc2hhZG93OiAwIDFweCAzcHggcmdiYSgwLCAwLCAwLCAwLjA4KTtcbiAgICB9XG5cbiAgICBpb24tY2FyZC10aXRsZSB7XG4gICAgICBmb250LXNpemU6IDEuMTI1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICB9XG5cbiAgICAuc2VjdGlvbi1kZXNjcmlwdGlvbiB7XG4gICAgICBtYXJnaW46IDAgMCAxcmVtO1xuICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1tZWRpdW0pO1xuICAgICAgZm9udC1zaXplOiAwLjg3NXJlbTtcbiAgICB9XG5cbiAgICAucHJvdmlkZXJzLWxpc3Qge1xuICAgICAgcGFkZGluZzogMDtcbiAgICB9XG5cbiAgICAucHJvdmlkZXItaXRlbSB7XG4gICAgICAtLXBhZGRpbmctc3RhcnQ6IDA7XG4gICAgICAtLXBhZGRpbmctZW5kOiAwO1xuICAgICAgLS1pbm5lci1wYWRkaW5nLWVuZDogMDtcbiAgICAgIG1hcmdpbi1ib3R0b206IDAuNXJlbTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWlvbi1ib3JkZXItY29sb3IsICNlMGUwZTApO1xuICAgIH1cblxuICAgIC5wcm92aWRlci1pdGVtOmxhc3QtY2hpbGQge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMDtcbiAgICB9XG5cbiAgICAucHJvdmlkZXItaWNvbiB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgd2lkdGg6IDQwcHg7XG4gICAgICBoZWlnaHQ6IDQwcHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDAuNzVyZW07XG4gICAgfVxuXG4gICAgLnByb3ZpZGVyLWljb24gaW9uLWljb24ge1xuICAgICAgZm9udC1zaXplOiAxLjI1cmVtO1xuICAgIH1cblxuICAgIC5wcm92aWRlci1pY29uLm11dGVkIHtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1saWdodCk7XG4gICAgfVxuXG4gICAgLnByb3ZpZGVyLWljb24ubXV0ZWQgaW9uLWljb24ge1xuICAgICAgY29sb3I6IHZhcigtLWlvbi1jb2xvci1tZWRpdW0pO1xuICAgIH1cblxuICAgIC5wcm92aWRlci1pdGVtIGlvbi1sYWJlbCBoMyB7XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgZm9udC1zaXplOiAwLjkzNzVyZW07XG4gICAgICBtYXJnaW4tYm90dG9tOiAwLjEyNXJlbTtcbiAgICB9XG5cbiAgICAucHJvdmlkZXItaXRlbSBpb24tbGFiZWwgcCB7XG4gICAgICBmb250LXNpemU6IDAuODEyNXJlbTtcbiAgICAgIGNvbG9yOiB2YXIoLS1pb24tY29sb3ItbWVkaXVtKTtcbiAgICB9XG5cbiAgICAubGlua2VkLWljb24ge1xuICAgICAgZm9udC1zaXplOiAxLjI1cmVtO1xuICAgIH1cblxuICAgIC51bmxpbmstYnRuIHtcbiAgICAgIC0tcGFkZGluZy1zdGFydDogMC41cmVtO1xuICAgICAgLS1wYWRkaW5nLWVuZDogMC41cmVtO1xuICAgIH1cblxuICAgIC5wcm92aWRlci1pdGVtLmF2YWlsYWJsZSB7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuXG4gICAgLnByb3ZpZGVyLWl0ZW0uYXZhaWxhYmxlOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWlvbi1jb2xvci1saWdodC10aW50KTtcbiAgICB9XG5cbiAgICAvKiBEYXJrIG1vZGUgKi9cbiAgICA6aG9zdC1jb250ZXh0KGJvZHkuZGFyaykge1xuICAgICAgLnByb3ZpZGVyLWl0ZW0ge1xuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLWlvbi1jb2xvci1zdGVwLTE1MCk7XG4gICAgICB9XG5cbiAgICAgIC5wcm92aWRlci1pY29uLm11dGVkIHtcbiAgICAgICAgYmFja2dyb3VuZDogdmFyKC0taW9uLWNvbG9yLXN0ZXAtMTAwKTtcbiAgICAgIH1cbiAgICB9XG4gIGBdLFxufSlcbmV4cG9ydCBjbGFzcyBMaW5rZWRQcm92aWRlcnNDb21wb25lbnQge1xuICBASW5wdXQoKSBwcm9wcyE6IExpbmtlZFByb3ZpZGVyc01ldGFkYXRhO1xuXG4gIHByaXZhdGUgYWxlcnRDdHJsID0gbmV3IEFsZXJ0Q29udHJvbGxlcigpO1xuXG4gIC8vIENvbXB1dGVkIHNpZ25hbHNcbiAgbGlua2VkUHJvdmlkZXJzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5wcm9wcz8ucHJvdmlkZXJzIHx8IFtdKTtcblxuICB1bmxpbmtlZFByb3ZpZGVycyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBsaW5rZWQgPSBuZXcgU2V0KHRoaXMubGlua2VkUHJvdmlkZXJzKCkubWFwKHAgPT4gcC5wcm92aWRlcikpO1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IHRoaXMucHJvcHM/LmF2YWlsYWJsZVByb3ZpZGVycyB8fCBbJ2dvb2dsZSddO1xuICAgIHJldHVybiBhdmFpbGFibGVcbiAgICAgIC5maWx0ZXIocCA9PiAhbGlua2VkLmhhcyhwKSlcbiAgICAgIC5tYXAocCA9PiBPQVVUSF9QUk9WSURFUlNfSU5GT1twXSk7XG4gIH0pO1xuXG4gIGNhblVubGluayA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAvLyBDYW4gdW5saW5rIGlmIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZSBwcm92aWRlciBvciB1c2VyIGhhcyBwYXNzd29yZFxuICAgIHJldHVybiB0aGlzLmxpbmtlZFByb3ZpZGVycygpLmxlbmd0aCA+IDE7XG4gIH0pO1xuXG4gIGdldFByb3ZpZGVySW5mbyhwcm92aWRlcjogT0F1dGhQcm92aWRlcik6IFByb3ZpZGVyRGlzcGxheUluZm8ge1xuICAgIHJldHVybiBPQVVUSF9QUk9WSURFUlNfSU5GT1twcm92aWRlcl0gfHwgT0FVVEhfUFJPVklERVJTX0lORk8uZ29vZ2xlO1xuICB9XG5cbiAgb25MaW5rUHJvdmlkZXIocHJvdmlkZXI6IE9BdXRoUHJvdmlkZXIpOiB2b2lkIHtcbiAgICB0aGlzLnByb3BzLm9uTGluaz8uKHByb3ZpZGVyKTtcbiAgfVxuXG4gIGFzeW5jIGNvbmZpcm1VbmxpbmsocHJvdmlkZXI6IE9BdXRoUHJvdmlkZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpbmZvID0gdGhpcy5nZXRQcm92aWRlckluZm8ocHJvdmlkZXIpO1xuXG4gICAgY29uc3QgYWxlcnQgPSBhd2FpdCB0aGlzLmFsZXJ0Q3RybC5jcmVhdGUoe1xuICAgICAgaGVhZGVyOiAnRGVzdmluY3VsYXIgY3VlbnRhJyxcbiAgICAgIG1lc3NhZ2U6IGDCv0VzdMOhcyBzZWd1cm8gZGUgcXVlIHF1aWVyZXMgZGVzdmluY3VsYXIgdHUgY3VlbnRhIGRlICR7aW5mby5uYW1lfT9gLFxuICAgICAgYnV0dG9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ0NhbmNlbGFyJyxcbiAgICAgICAgICByb2xlOiAnY2FuY2VsJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdEZXN2aW5jdWxhcicsXG4gICAgICAgICAgcm9sZTogJ2Rlc3RydWN0aXZlJyxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uVW5saW5rPy4ocHJvdmlkZXIpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgYWxlcnQucHJlc2VudCgpO1xuICB9XG59XG4iXX0=