@mintplayer/ng-spark 22.31.0 → 22.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +101 -1
  2. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +3 -3
  3. package/fesm2022/mintplayer-ng-spark-auth-account.mjs +18 -18
  4. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +16 -8
  5. package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs +3 -3
  7. package/fesm2022/mintplayer-ng-spark-auth-core.mjs +6 -6
  8. package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs +3 -3
  9. package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +3 -3
  10. package/fesm2022/mintplayer-ng-spark-auth-login.mjs +3 -3
  11. package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +3 -3
  12. package/fesm2022/mintplayer-ng-spark-auth-register.mjs +3 -3
  13. package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +3 -3
  14. package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs +3 -3
  15. package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +3 -3
  16. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +24 -24
  17. package/fesm2022/mintplayer-ng-spark-column-filter.mjs +3 -3
  18. package/fesm2022/mintplayer-ng-spark-contributions.mjs +9 -9
  19. package/fesm2022/mintplayer-ng-spark-grid.mjs +220 -49
  20. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  21. package/fesm2022/mintplayer-ng-spark-history.mjs +9 -9
  22. package/fesm2022/mintplayer-ng-spark-icon.mjs +3 -3
  23. package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs +3 -3
  24. package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs +9 -9
  25. package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs +6 -6
  26. package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs +3 -3
  27. package/fesm2022/mintplayer-ng-spark-models.mjs +44 -1
  28. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  29. package/fesm2022/mintplayer-ng-spark-moderation.mjs +21 -21
  30. package/fesm2022/mintplayer-ng-spark-notifications.mjs +687 -0
  31. package/fesm2022/mintplayer-ng-spark-notifications.mjs.map +1 -0
  32. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs +179 -0
  33. package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs.map +1 -0
  34. package/fesm2022/mintplayer-ng-spark-organizations.mjs +202 -0
  35. package/fesm2022/mintplayer-ng-spark-organizations.mjs.map +1 -0
  36. package/fesm2022/mintplayer-ng-spark-pipes.mjs +125 -85
  37. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-po-create.mjs +3 -3
  39. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +90 -26
  40. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  41. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +84 -12
  42. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  43. package/fesm2022/mintplayer-ng-spark-po-form.mjs +9 -9
  44. package/fesm2022/mintplayer-ng-spark-pwa.mjs +74 -6
  45. package/fesm2022/mintplayer-ng-spark-pwa.mjs.map +1 -1
  46. package/fesm2022/mintplayer-ng-spark-query-list.mjs +10 -109
  47. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  48. package/fesm2022/mintplayer-ng-spark-renderers.mjs +3 -3
  49. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +3 -3
  50. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs +801 -0
  51. package/fesm2022/mintplayer-ng-spark-score-renderers.mjs.map +1 -0
  52. package/fesm2022/mintplayer-ng-spark-services.mjs +424 -72
  53. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  54. package/fesm2022/mintplayer-ng-spark-share-page.mjs +334 -0
  55. package/fesm2022/mintplayer-ng-spark-share-page.mjs.map +1 -0
  56. package/fesm2022/mintplayer-ng-spark-share.mjs +10 -0
  57. package/fesm2022/mintplayer-ng-spark-share.mjs.map +1 -0
  58. package/fesm2022/mintplayer-ng-spark-shell.mjs +38 -36
  59. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  60. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +9 -9
  61. package/package.json +25 -1
  62. package/types/mintplayer-ng-spark-grid.d.ts +77 -26
  63. package/types/mintplayer-ng-spark-models.d.ts +150 -17
  64. package/types/mintplayer-ng-spark-notifications.d.ts +188 -0
  65. package/types/mintplayer-ng-spark-organizations-accept.d.ts +40 -0
  66. package/types/mintplayer-ng-spark-organizations.d.ts +72 -0
  67. package/types/mintplayer-ng-spark-pipes.d.ts +10 -0
  68. package/types/mintplayer-ng-spark-po-detail.d.ts +26 -0
  69. package/types/mintplayer-ng-spark-po-edit.d.ts +37 -0
  70. package/types/mintplayer-ng-spark-pwa.d.ts +48 -2
  71. package/types/mintplayer-ng-spark-query-list.d.ts +8 -23
  72. package/types/mintplayer-ng-spark-score-renderers.d.ts +340 -0
  73. package/types/mintplayer-ng-spark-services.d.ts +146 -6
  74. package/types/mintplayer-ng-spark-share-page.d.ts +67 -0
  75. package/types/mintplayer-ng-spark-share.d.ts +26 -0
package/README.md CHANGED
@@ -54,7 +54,7 @@ Import from the entry point, not from the package root; each one is a separate c
54
54
  |---|---|
55
55
  | `@mintplayer/ng-spark` | `provideSpark(config?)`, `SPARK_CONFIG` (`baseUrl`), `SPARK_AUTH_STATE` (the bridge `ng-spark/auth` fills) |
56
56
  | `/routes` | `sparkRoutes()` — the routed persistent-object and query pages |
57
- | `/services` | `SparkService`, `SparkStreamingService`, `SparkLanguageService`, `SparkQueryActionsService`, `RetryActionService`; the timezone feature `withSparkTimezone()` |
57
+ | `/services` | `SparkService`, `SparkLiveService`, `SparkLanguageService`, `SparkQueryActionsService`, `RetryActionService`; the timezone feature `withSparkTimezone()` |
58
58
  | `/models` | The wire types (persistent objects, attributes, queries, envelopes) |
59
59
  | `/shell` | `<spark-shell>` with its slot directives, `<spark-program-units>`, `<spark-language-selector>` ([guide](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-program-units.md)) |
60
60
  | `/query-list` | `<spark-query-list>` — the routed query page |
@@ -63,6 +63,7 @@ Import from the entry point, not from the package root; each one is a separate c
63
63
  | `/po-detail`, `/po-create`, `/po-edit` | The routed detail, create and edit pages |
64
64
  | `/po-form` | `<spark-po-form>`, `<spark-reference-picker>`, `<spark-lookup-picker>` |
65
65
  | `/renderers` | `provideSparkAttributeRenderers([...])`, `SPARK_ATTRIBUTE_RENDERERS` (with the core `paragraph` renderer built in), `withDeclaredInputs` ([guide](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-custom-attribute-renderers.md)) |
66
+ | `/score-renderers` | `provideSparkScoreRenderers([...])` — the `spark-gauge`, `spark-threshold-bar`, `spark-trend` and `spark-delta` renderers, their components, bands and grade presets ([guide](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-score-renderers.md)) |
66
67
  | `/panels` | `provideSparkDetailPanels(...)`, `provideSparkDetailActions(...)`, `provideSparkQueryListActions(...)` — how add-ons put components on the routed pages |
67
68
  | `/client-operations` | `provideSparkClientOperations()` — notify, navigate and refresh operations from server-side action code; the toast container |
68
69
  | `/retry-action-modal` | The modal that answers a server's retry action ([guide](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-manager-retry-actions.md)) |
@@ -72,6 +73,10 @@ Import from the entry point, not from the package root; each one is a separate c
72
73
  | `/soft-delete` | `provideSparkSoftDelete()` — the Deleted toggle on query lists, the recycle bin, Restore / Purge |
73
74
  | `/history` | `provideSparkHistory()` — `<spark-po-history>`: revision list, read-only view, diff, Revert |
74
75
  | `/moderation` | `provideSparkModeration()`, `sparkModerationRoutes()`, `sparkModerationRenderers` — vote widget, flag button, review queue, reputation badge, moderator panel |
76
+ | `/organizations` | `withOrganizationRoutes()` for `sparkAuthRoutes(...)`: the page a mailed organization invitation or join request opens (`organizations/accept/:token`), accepting on an explicit click; `<spark-organization-switcher>`: the current organization in the top bar, which lists of organization-owned rows and new rows follow ([guide](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-organizations.md)) |
77
+ | `/pwa` | `provideSparkServiceWorker()` — Angular's service worker with Spark's update policy (`SparkServiceWorkerUpdates`) and in-app navigation for a clicked push notification (`SparkNotificationClicks`) |
78
+ | `/share` | `withShareRoutes(options?)` — the anonymous page a share link opens (`shared/:type/:token?id=…`); `SparkSharedObject` (the `/spark/share/load` answer). The page itself is `SparkSharedObjectComponent` in `/share/page`, lazy-loaded |
79
+ | `/notifications` | `<spark-notification-bell>`, `<spark-push-toggle>`, `SparkNotificationsService` (live unread count, latest notifications, mark read, Web Push opt-in), `provideSparkNotifications()` — the client of MintPlayer.Spark.Notifications |
75
80
 
76
81
  ### Timezone (`withSparkTimezone`)
77
82
 
@@ -153,6 +158,27 @@ The grid also renders:
153
158
  See [guide-custom-actions.md](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-custom-actions.md)
154
159
  for the server side of this.
155
160
 
161
+ ### Live updates
162
+
163
+ A type or query marked `"live": true` in its model is followed over one WebSocket (`/spark/live`) with
164
+ nothing to write: `spark-po-detail` replaces the object when it changes and shows the unavailable state when
165
+ it is deleted; every `spark-query-grid` (the query page, sub-queries, cards) re-renders its page as rows
166
+ change, appear or leave, with server-side paging, sort, search and filters intact (`[live]` overrides the
167
+ query's flag); `spark-po-edit` adopts a newer version while the form is untouched and otherwise shows a
168
+ banner that runs the three-way merge. For a custom page:
169
+
170
+ ```ts
171
+ import { SparkLiveService } from '@mintplayer/ng-spark/services';
172
+
173
+ const live = inject(SparkLiveService);
174
+ readonly run = live.livePersistentObject(signal('AuditRun'), this.runId); // Signal<PersistentObject | null | 'gone'>
175
+ readonly running = live.liveQuery(computed(() => ({ queryId: 'runningaudits', skip: 0, take: 20 }))); // Signal<QueryResult | null>
176
+ // or the observables: live.watchPersistentObject(type, id), live.watchQuery(request | request$)
177
+ ```
178
+
179
+ This replaces streaming queries (`isStreamingQuery`, `SparkStreamingService`); there is no shim. See
180
+ [guide-live-updates.md](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-live-updates.md).
181
+
156
182
  ### Soft delete, history and moderation
157
183
 
158
184
  ```ts
@@ -191,6 +217,80 @@ No routes of its own: the History link opens `query/:queryId` with `?parentId=&p
191
217
  column filter per slot, which the query page reads for any query. Needs
192
218
  [MintPlayer.Spark.Contributions](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/libs/contributions/MintPlayer.Spark.Contributions/README.md).
193
219
 
220
+ ### Score renderers
221
+
222
+ ```ts
223
+ import { provideSparkScoreRenderers } from '@mintplayer/ng-spark/score-renderers';
224
+
225
+ providers: [
226
+ provideSparkScoreRenderers([/* the app's own renderers */]), // instead of provideSparkAttributeRenderers
227
+ ]
228
+ ```
229
+
230
+ ```json
231
+ { "name": "Score", "renderer": "spark-gauge", "rendererOptions": { "bands": "letter-grades" } }
232
+ ```
233
+
234
+ Four renderers for scores and their history, each drawing a grid cell and a detail value and configured
235
+ through `rendererOptions`:
236
+
237
+ - `spark-gauge`: a ring with the score inside and, with `"bands": "letter-grades"`, an A–F grade (A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 50).
238
+ - `spark-threshold-bar`: a compact bar coloured by band (default green ≥ 80, amber ≥ 60, red), the value beside it.
239
+ - `spark-trend`: a sparkline, or with `"display": "chart"` a trend chart with an optional goal line.
240
+ - `spark-delta`: a signed change, green up and red down, or the reverse with `"higherIsBetter": false`.
241
+
242
+ No value draws a muted dash, never a zero. The components (`<spark-threshold-bar>` and so on) can also be
243
+ used in a template with `[value]` and `[options]`; `<spark-trend-sparkline>` and `<spark-trend-chart>` are the
244
+ two halves of `spark-trend`, each loading only its own chart. CodeCoverage draws its coverage bar, sparkline, trend
245
+ chart and Δ column through them. See
246
+ [guide-score-renderers.md](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/docs/guide-score-renderers.md)
247
+ for every option.
248
+
249
+ ### Notifications
250
+
251
+ ```ts
252
+ import { SparkNotificationBellComponent, SparkPushToggleComponent } from '@mintplayer/ng-spark/notifications';
253
+ ```
254
+
255
+ ```html
256
+ <spark-notification-bell /> <!-- in the top bar -->
257
+ <spark-push-toggle /> <!-- on an account or settings page -->
258
+ ```
259
+
260
+ The client of the server package MintPlayer.Spark.Notifications (`spark.AddNotifications()`):
261
+
262
+ - The bell shows the unread count and, in its menu, the latest notifications (title, message, relative time).
263
+ Choosing one marks it read and follows its link, through the router when it is on this origin.
264
+ "Mark all as read" and a link to the full list (`/query/notifications`; `[allLink]` or
265
+ `provideSparkNotifications({ listLink, recentCount })` change it) complete the menu.
266
+ - `SparkNotificationsService` holds `unreadCount`, `recent`, `markRead(ids?)` and `open(notification)`. Both
267
+ lists are live queries on the one `/spark/live` socket: no polling. They resubscribe when the signed-in user changes.
268
+ - Web Push: `enablePush()` (call it from a click: it asks permission first), `disablePush()`, `pushState`
269
+ (`unsupported` · `denied` · `off` · `on`) and `pushConfigured` (the server has VAPID keys). Push needs
270
+ `provideSparkServiceWorker()` with the worker enabled. On iPhone and iPad the app must be on the Home Screen
271
+ first; until then the state is `unsupported` and the toggle says so.
272
+ - A push clicked while the app is open becomes an in-app navigation (`SparkNotificationClicks`, started by
273
+ `provideSparkServiceWorker()`). When the app is closed, Angular's service worker opens the page itself
274
+ from the payload's `onActionClick`.
275
+
276
+ ### Share links
277
+
278
+ ```ts
279
+ import { withShareRoutes } from '@mintplayer/ng-spark/share';
280
+
281
+ export const routes: Routes = [
282
+ ...withShareRoutes(), // shared/:type/:token, no guard
283
+ { path: '', component: ShellComponent, children: [...sparkRoutes()] },
284
+ ];
285
+ ```
286
+
287
+ A share link (`spark.AddShareLinks(...)` on the server) is `{origin}/shared/{type}/{token}?id={id}`. The page shows,
288
+ read-only and to anyone holding the link, exactly what `POST /spark/share/load` returns: the declared attributes
289
+ through the usual cells and renderers (the score renderers included) and one table per declared child query,
290
+ paged through `POST /spark/share/query`. A revoked, replaced or unknown link reads "This link does not work (any
291
+ more)" (`share.notFound`). `withShareRoutes({ path, component })` moves or replaces the page; keep
292
+ `Spark:Share:LinkPath` in step with the path.
293
+
194
294
  ## More
195
295
 
196
296
  - [Repository README](https://github.com/MintPlayer/MintPlayer.Spark/blob/master/README.md) — the developer guides
@@ -13,7 +13,7 @@ var SparkAttributeDescriptionComponent = class SparkAttributeDescriptionComponen
13
13
  }
14
14
  static ɵfac = i0.ɵɵngDeclareFactory({
15
15
  minVersion: "12.0.0",
16
- version: "22.2.0",
16
+ version: "22.2.2",
17
17
  ngImport: i0,
18
18
  type: SparkAttributeDescriptionComponent,
19
19
  deps: [],
@@ -21,7 +21,7 @@ var SparkAttributeDescriptionComponent = class SparkAttributeDescriptionComponen
21
21
  });
22
22
  static ɵcmp = i0.ɵɵngDeclareComponent({
23
23
  minVersion: "17.0.0",
24
- version: "22.2.0",
24
+ version: "22.2.2",
25
25
  type: SparkAttributeDescriptionComponent,
26
26
  isStandalone: true,
27
27
  selector: "spark-attribute-description",
@@ -72,7 +72,7 @@ var SparkAttributeDescriptionComponent = class SparkAttributeDescriptionComponen
72
72
  };
73
73
  i0.ɵɵngDeclareClassMetadata({
74
74
  minVersion: "12.0.0",
75
- version: "22.2.0",
75
+ version: "22.2.2",
76
76
  ngImport: i0,
77
77
  type: SparkAttributeDescriptionComponent,
78
78
  decorators: [{
@@ -88,7 +88,7 @@ var SparkAccountOverviewComponent = class SparkAccountOverviewComponent {
88
88
  }
89
89
  static ɵfac = i0.ɵɵngDeclareFactory({
90
90
  minVersion: "12.0.0",
91
- version: "22.2.0",
91
+ version: "22.2.2",
92
92
  ngImport: i0,
93
93
  type: SparkAccountOverviewComponent,
94
94
  deps: [],
@@ -96,7 +96,7 @@ var SparkAccountOverviewComponent = class SparkAccountOverviewComponent {
96
96
  });
97
97
  static ɵcmp = i0.ɵɵngDeclareComponent({
98
98
  minVersion: "17.0.0",
99
- version: "22.2.0",
99
+ version: "22.2.2",
100
100
  type: SparkAccountOverviewComponent,
101
101
  isStandalone: true,
102
102
  selector: "spark-account-overview",
@@ -170,7 +170,7 @@ var SparkAccountOverviewComponent = class SparkAccountOverviewComponent {
170
170
  };
171
171
  i0.ɵɵngDeclareClassMetadata({
172
172
  minVersion: "12.0.0",
173
- version: "22.2.0",
173
+ version: "22.2.2",
174
174
  ngImport: i0,
175
175
  type: SparkAccountOverviewComponent,
176
176
  decorators: [{
@@ -339,7 +339,7 @@ var SparkAccountProfileComponent = class SparkAccountProfileComponent {
339
339
  }
340
340
  static ɵfac = i0.ɵɵngDeclareFactory({
341
341
  minVersion: "12.0.0",
342
- version: "22.2.0",
342
+ version: "22.2.2",
343
343
  ngImport: i0,
344
344
  type: SparkAccountProfileComponent,
345
345
  deps: [],
@@ -347,7 +347,7 @@ var SparkAccountProfileComponent = class SparkAccountProfileComponent {
347
347
  });
348
348
  static ɵcmp = i0.ɵɵngDeclareComponent({
349
349
  minVersion: "17.0.0",
350
- version: "22.2.0",
350
+ version: "22.2.2",
351
351
  type: SparkAccountProfileComponent,
352
352
  isStandalone: true,
353
353
  selector: "spark-account-profile",
@@ -635,7 +635,7 @@ var SparkAccountProfileComponent = class SparkAccountProfileComponent {
635
635
  };
636
636
  i0.ɵɵngDeclareClassMetadata({
637
637
  minVersion: "12.0.0",
638
- version: "22.2.0",
638
+ version: "22.2.2",
639
639
  ngImport: i0,
640
640
  type: SparkAccountProfileComponent,
641
641
  decorators: [{
@@ -823,7 +823,7 @@ var SparkChangePasswordComponent = class SparkChangePasswordComponent {
823
823
  }
824
824
  static ɵfac = i0.ɵɵngDeclareFactory({
825
825
  minVersion: "12.0.0",
826
- version: "22.2.0",
826
+ version: "22.2.2",
827
827
  ngImport: i0,
828
828
  type: SparkChangePasswordComponent,
829
829
  deps: [],
@@ -831,7 +831,7 @@ var SparkChangePasswordComponent = class SparkChangePasswordComponent {
831
831
  });
832
832
  static ɵcmp = i0.ɵɵngDeclareComponent({
833
833
  minVersion: "17.0.0",
834
- version: "22.2.0",
834
+ version: "22.2.2",
835
835
  type: SparkChangePasswordComponent,
836
836
  isStandalone: true,
837
837
  selector: "spark-change-password",
@@ -969,7 +969,7 @@ var SparkChangePasswordComponent = class SparkChangePasswordComponent {
969
969
  };
970
970
  i0.ɵɵngDeclareClassMetadata({
971
971
  minVersion: "12.0.0",
972
- version: "22.2.0",
972
+ version: "22.2.2",
973
973
  ngImport: i0,
974
974
  type: SparkChangePasswordComponent,
975
975
  decorators: [{
@@ -1165,7 +1165,7 @@ var SparkTwoFactorSetupComponent = class SparkTwoFactorSetupComponent {
1165
1165
  }
1166
1166
  static ɵfac = i0.ɵɵngDeclareFactory({
1167
1167
  minVersion: "12.0.0",
1168
- version: "22.2.0",
1168
+ version: "22.2.2",
1169
1169
  ngImport: i0,
1170
1170
  type: SparkTwoFactorSetupComponent,
1171
1171
  deps: [],
@@ -1173,7 +1173,7 @@ var SparkTwoFactorSetupComponent = class SparkTwoFactorSetupComponent {
1173
1173
  });
1174
1174
  static ɵcmp = i0.ɵɵngDeclareComponent({
1175
1175
  minVersion: "17.0.0",
1176
- version: "22.2.0",
1176
+ version: "22.2.2",
1177
1177
  type: SparkTwoFactorSetupComponent,
1178
1178
  isStandalone: true,
1179
1179
  selector: "spark-two-factor-setup",
@@ -1385,7 +1385,7 @@ var SparkTwoFactorSetupComponent = class SparkTwoFactorSetupComponent {
1385
1385
  };
1386
1386
  i0.ɵɵngDeclareClassMetadata({
1387
1387
  minVersion: "12.0.0",
1388
- version: "22.2.0",
1388
+ version: "22.2.2",
1389
1389
  ngImport: i0,
1390
1390
  type: SparkTwoFactorSetupComponent,
1391
1391
  decorators: [{
@@ -1557,7 +1557,7 @@ var SparkExternalLoginsComponent = class SparkExternalLoginsComponent {
1557
1557
  }
1558
1558
  static ɵfac = i0.ɵɵngDeclareFactory({
1559
1559
  minVersion: "12.0.0",
1560
- version: "22.2.0",
1560
+ version: "22.2.2",
1561
1561
  ngImport: i0,
1562
1562
  type: SparkExternalLoginsComponent,
1563
1563
  deps: [],
@@ -1565,7 +1565,7 @@ var SparkExternalLoginsComponent = class SparkExternalLoginsComponent {
1565
1565
  });
1566
1566
  static ɵcmp = i0.ɵɵngDeclareComponent({
1567
1567
  minVersion: "17.0.0",
1568
- version: "22.2.0",
1568
+ version: "22.2.2",
1569
1569
  type: SparkExternalLoginsComponent,
1570
1570
  isStandalone: true,
1571
1571
  selector: "spark-external-logins",
@@ -1658,7 +1658,7 @@ var SparkExternalLoginsComponent = class SparkExternalLoginsComponent {
1658
1658
  };
1659
1659
  i0.ɵɵngDeclareClassMetadata({
1660
1660
  minVersion: "12.0.0",
1661
- version: "22.2.0",
1661
+ version: "22.2.2",
1662
1662
  ngImport: i0,
1663
1663
  type: SparkExternalLoginsComponent,
1664
1664
  decorators: [{
@@ -1783,7 +1783,7 @@ var SparkPersonalDataComponent = class SparkPersonalDataComponent {
1783
1783
  }
1784
1784
  static ɵfac = i0.ɵɵngDeclareFactory({
1785
1785
  minVersion: "12.0.0",
1786
- version: "22.2.0",
1786
+ version: "22.2.2",
1787
1787
  ngImport: i0,
1788
1788
  type: SparkPersonalDataComponent,
1789
1789
  deps: [],
@@ -1791,7 +1791,7 @@ var SparkPersonalDataComponent = class SparkPersonalDataComponent {
1791
1791
  });
1792
1792
  static ɵcmp = i0.ɵɵngDeclareComponent({
1793
1793
  minVersion: "17.0.0",
1794
- version: "22.2.0",
1794
+ version: "22.2.2",
1795
1795
  type: SparkPersonalDataComponent,
1796
1796
  isStandalone: true,
1797
1797
  selector: "spark-personal-data",
@@ -1951,7 +1951,7 @@ var SparkPersonalDataComponent = class SparkPersonalDataComponent {
1951
1951
  };
1952
1952
  i0.ɵɵngDeclareClassMetadata({
1953
1953
  minVersion: "12.0.0",
1954
- version: "22.2.0",
1954
+ version: "22.2.2",
1955
1955
  ngImport: i0,
1956
1956
  type: SparkPersonalDataComponent,
1957
1957
  decorators: [{
@@ -5,6 +5,7 @@ import { BsButtonGroupComponent } from "@mintplayer/ng-bootstrap/button-group";
5
5
  import { SPARK_AUTH_CONFIG, SPARK_AUTH_ROUTE_PATHS, findSparkAuthRoutePaths, resolveSignInUrl } from "@mintplayer/ng-spark/auth/models";
6
6
  import { SparkAuthService } from "@mintplayer/ng-spark/auth/core";
7
7
  import { TranslateKeyPipe } from "@mintplayer/ng-spark/auth/pipes";
8
+ import { SparkIconComponent } from "@mintplayer/ng-spark/icon";
8
9
  var SparkAuthBarComponent = class SparkAuthBarComponent {
9
10
  authService = inject(SparkAuthService);
10
11
  config = inject(SPARK_AUTH_CONFIG);
@@ -20,7 +21,7 @@ var SparkAuthBarComponent = class SparkAuthBarComponent {
20
21
  }
21
22
  static ɵfac = i0.ɵɵngDeclareFactory({
22
23
  minVersion: "12.0.0",
23
- version: "22.2.0",
24
+ version: "22.2.2",
24
25
  ngImport: i0,
25
26
  type: SparkAuthBarComponent,
26
27
  deps: [],
@@ -28,13 +29,13 @@ var SparkAuthBarComponent = class SparkAuthBarComponent {
28
29
  });
29
30
  static ɵcmp = i0.ɵɵngDeclareComponent({
30
31
  minVersion: "17.0.0",
31
- version: "22.2.0",
32
+ version: "22.2.2",
32
33
  type: SparkAuthBarComponent,
33
34
  isStandalone: true,
34
35
  selector: "spark-auth-bar",
35
36
  ngImport: i0,
36
- template: "@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\">{{ 'auth.account' | t }}</a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n",
37
- styles: [":host{display:inline-flex;align-items:center;flex-wrap:nowrap;min-width:0}.spark-auth-bar-btn{--bs-btn-color: currentColor;--bs-btn-border-color: currentColor;--bs-btn-hover-color: currentColor;--bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);--bs-btn-hover-border-color: currentColor;--bs-btn-active-color: currentColor;--bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);--bs-btn-active-border-color: currentColor}\n"],
37
+ template: "@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted.\n On a phone the two buttons are icons (their names stay as aria-label and title), so the\n topbar fits 375 px next to a language selector, an organization switcher and the bell. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-account\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\" [attr.aria-label]=\"'auth.account' | t\">\n <spark-icon name=\"person\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.account' | t }}</span>\n </a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-logout\" (click)=\"onLogout()\"\n [attr.title]=\"'auth.logout' | t\" [attr.aria-label]=\"'auth.logout' | t\">\n <spark-icon name=\"box-arrow-right\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.logout' | t }}</span>\n </button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n",
38
+ styles: [":host{display:inline-flex;align-items:center;flex-wrap:nowrap;min-width:0;flex-shrink:0}.spark-auth-bar-btn{--bs-btn-color: currentColor;--bs-btn-border-color: currentColor;--bs-btn-hover-color: currentColor;--bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);--bs-btn-hover-border-color: currentColor;--bs-btn-active-color: currentColor;--bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);--bs-btn-active-border-color: currentColor}.spark-auth-bar-icon{display:none}@media(max-width:575.98px){.spark-auth-bar-icon{display:inline-flex}.spark-auth-bar-label{display:none}}\n"],
38
39
  dependencies: [
39
40
  {
40
41
  kind: "directive",
@@ -61,6 +62,12 @@ var SparkAuthBarComponent = class SparkAuthBarComponent {
61
62
  selector: "bs-button-group",
62
63
  inputs: ["ariaLabel"]
63
64
  },
65
+ {
66
+ kind: "component",
67
+ type: SparkIconComponent,
68
+ selector: "spark-icon",
69
+ inputs: ["name"]
70
+ },
64
71
  {
65
72
  kind: "pipe",
66
73
  type: TranslateKeyPipe,
@@ -72,7 +79,7 @@ var SparkAuthBarComponent = class SparkAuthBarComponent {
72
79
  };
73
80
  i0.ɵɵngDeclareClassMetadata({
74
81
  minVersion: "12.0.0",
75
- version: "22.2.0",
82
+ version: "22.2.2",
76
83
  ngImport: i0,
77
84
  type: SparkAuthBarComponent,
78
85
  decorators: [{
@@ -84,10 +91,11 @@ i0.ɵɵngDeclareClassMetadata({
84
91
  imports: [
85
92
  RouterLink,
86
93
  BsButtonGroupComponent,
87
- TranslateKeyPipe
94
+ TranslateKeyPipe,
95
+ SparkIconComponent
88
96
  ],
89
- template: "@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\">{{ 'auth.account' | t }}</a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n",
90
- styles: [":host{display:inline-flex;align-items:center;flex-wrap:nowrap;min-width:0}.spark-auth-bar-btn{--bs-btn-color: currentColor;--bs-btn-border-color: currentColor;--bs-btn-hover-color: currentColor;--bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);--bs-btn-hover-border-color: currentColor;--bs-btn-active-color: currentColor;--bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);--bs-btn-active-border-color: currentColor}\n"]
97
+ template: "@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted.\n On a phone the two buttons are icons (their names stay as aria-label and title), so the\n topbar fits 375 px next to a language selector, an organization switcher and the bell. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-account\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\" [attr.aria-label]=\"'auth.account' | t\">\n <spark-icon name=\"person\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.account' | t }}</span>\n </a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-logout\" (click)=\"onLogout()\"\n [attr.title]=\"'auth.logout' | t\" [attr.aria-label]=\"'auth.logout' | t\">\n <spark-icon name=\"box-arrow-right\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.logout' | t }}</span>\n </button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n",
98
+ styles: [":host{display:inline-flex;align-items:center;flex-wrap:nowrap;min-width:0;flex-shrink:0}.spark-auth-bar-btn{--bs-btn-color: currentColor;--bs-btn-border-color: currentColor;--bs-btn-hover-color: currentColor;--bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);--bs-btn-hover-border-color: currentColor;--bs-btn-active-color: currentColor;--bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);--bs-btn-active-border-color: currentColor}.spark-auth-bar-icon{display:none}@media(max-width:575.98px){.spark-auth-bar-icon{display:inline-flex}.spark-auth-bar-label{display:none}}\n"]
91
99
  }]
92
100
  }]
93
101
  });
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-auth-auth-bar.mjs","names":[],"sources":["../../auth/auth-bar/src/spark-auth-bar.component.ts","../../auth/auth-bar/src/spark-auth-bar.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { RouterLink, Router } from '@angular/router';\nimport { BsButtonGroupComponent } from '@mintplayer/ng-bootstrap/button-group';\nimport {\n SPARK_AUTH_CONFIG,\n SPARK_AUTH_ROUTE_PATHS,\n findSparkAuthRoutePaths,\n resolveSignInUrl,\n} from '@mintplayer/ng-spark/auth/models';\nimport { SparkAuthService } from '@mintplayer/ng-spark/auth/core';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark/auth/pipes';\n\n@Component({\n selector: 'spark-auth-bar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterLink, BsButtonGroupComponent, TranslateKeyPipe],\n templateUrl: './spark-auth-bar.component.html',\n // Outline buttons drawn in the surrounding text colour, not `btn-outline-light`: the bar sits in\n // whatever topbar the app has, and that is no longer guaranteed to be dark (#462). currentColor\n // follows the container in either theme; the hover tint is the same colour at low alpha.\n styles: [`\n /* One line, always: the bar lives in a fixed-height topbar. */\n :host {\n display: inline-flex;\n align-items: center;\n flex-wrap: nowrap;\n min-width: 0;\n }\n\n .spark-auth-bar-btn {\n --bs-btn-color: currentColor;\n --bs-btn-border-color: currentColor;\n --bs-btn-hover-color: currentColor;\n --bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);\n --bs-btn-hover-border-color: currentColor;\n --bs-btn-active-color: currentColor;\n --bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);\n --bs-btn-active-border-color: currentColor;\n }\n `],\n})\nexport class SparkAuthBarComponent {\n readonly authService = inject(SparkAuthService);\n readonly config = inject(SPARK_AUTH_CONFIG);\n private readonly router = inject(Router);\n\n /** Same target the guard and interceptor use, so the bar cannot link somewhere they would not send you. */\n readonly signInUrl = resolveSignInUrl(this.config, this.router);\n\n /**\n * Where the account overview lives, or `undefined` when `withAccount()` did not mount it — then the\n * bar offers logout alone rather than a link that would fall through to some other route.\n *\n * `SPARK_AUTH_ROUTE_PATHS` is provided by `sparkAuthRoutes()` on its own route subtree, and this bar\n * usually lives in the application shell, outside it, so the token is injected optionally and the\n * router configuration is the fallback. Reading the configuration makes a custom `account` path\n * exact here too, instead of assuming the default.\n */\n readonly accountUrl = (inject(SPARK_AUTH_ROUTE_PATHS, { optional: true })\n ?? findSparkAuthRoutePaths(this.router.config))?.account;\n\n async onLogout(): Promise<void> {\n try {\n await this.authService.logout();\n } finally {\n // Always navigate away from the authenticated area, even if the server-side\n // logout call fails (network error, session already expired, etc.). The local\n // session state has been cleared by SparkAuthService regardless.\n this.router.navigateByUrl('/');\n }\n }\n}\n\nexport default SparkAuthBarComponent;\n","@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\">{{ 'auth.account' | t }}</a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" (click)=\"onLogout()\">{{ 'auth.logout' | t }}</button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n"],"mappings":";;;;;;;AA0CA,IAAa,wBAAb,MAAa,sBAAqB;CACvB,cAAc,OAAO,gBAAgB;CACrC,SAAS,OAAO,iBAAiB;CACzB,SAAS,OAAO,MAAM;CAG9B,YAAY,iBAAiB,KAAK,QAAQ,KAAK,MAAM;CAWrD,cAAc,OAAO,wBAAwB,EAAE,UAAU,KAAI,CAAE,KACnE,wBAAwB,KAAK,OAAO,MAAM,EAAA,EAAI;CAEnD,MAAM,WAAQ;EACZ,IAAI;GACF,MAAM,KAAK,YAAY,OAAM;EAC/B,UAAU;GAIR,KAAK,OAAO,cAAc,GAAG;EAC/B;CACF;CA7BW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAqB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAArB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAqB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UC1ClC;EAaA,QAAA,CAAA,0cAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MDGY;IAAU,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAsB,UAAA;IAAA,QAAA,CAAA,WAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,MAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AA0BnD,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAqB,YAAA,CAAA;EA9BjC,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAgB,YACd;GAAI,iBACC,wBAAwB;GAAM,SACtC;IAAC;IAAY;IAAwB;GAAgB;GAAC,UAAA;GAAA,QAAA,CAAA,0cAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"mintplayer-ng-spark-auth-auth-bar.mjs","names":[],"sources":["../../auth/auth-bar/src/spark-auth-bar.component.ts","../../auth/auth-bar/src/spark-auth-bar.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { RouterLink, Router } from '@angular/router';\nimport { BsButtonGroupComponent } from '@mintplayer/ng-bootstrap/button-group';\nimport {\n SPARK_AUTH_CONFIG,\n SPARK_AUTH_ROUTE_PATHS,\n findSparkAuthRoutePaths,\n resolveSignInUrl,\n} from '@mintplayer/ng-spark/auth/models';\nimport { SparkAuthService } from '@mintplayer/ng-spark/auth/core';\nimport { TranslateKeyPipe } from '@mintplayer/ng-spark/auth/pipes';\nimport { SparkIconComponent } from '@mintplayer/ng-spark/icon';\n\n@Component({\n selector: 'spark-auth-bar',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterLink, BsButtonGroupComponent, TranslateKeyPipe, SparkIconComponent],\n templateUrl: './spark-auth-bar.component.html',\n // Outline buttons drawn in the surrounding text colour, not `btn-outline-light`: the bar sits in\n // whatever topbar the app has, and that is no longer guaranteed to be dark (#462). currentColor\n // follows the container in either theme; the hover tint is the same colour at low alpha.\n styles: [`\n /* One line, always: the bar lives in a fixed-height topbar. */\n :host {\n display: inline-flex;\n align-items: center;\n flex-wrap: nowrap;\n min-width: 0;\n /* Never squeezed: its buttons cannot shrink, so a shrinking host only let them spill out of the topbar. */\n flex-shrink: 0;\n }\n\n .spark-auth-bar-btn {\n --bs-btn-color: currentColor;\n --bs-btn-border-color: currentColor;\n --bs-btn-hover-color: currentColor;\n --bs-btn-hover-bg: color-mix(in srgb, currentColor 15%, transparent);\n --bs-btn-hover-border-color: currentColor;\n --bs-btn-active-color: currentColor;\n --bs-btn-active-bg: color-mix(in srgb, currentColor 25%, transparent);\n --bs-btn-active-border-color: currentColor;\n }\n\n /* Labels from the small breakpoint up; on a phone (< 576 px) the icon alone. */\n .spark-auth-bar-icon { display: none; }\n @media (max-width: 575.98px) {\n .spark-auth-bar-icon { display: inline-flex; }\n .spark-auth-bar-label { display: none; }\n }\n `],\n})\nexport class SparkAuthBarComponent {\n readonly authService = inject(SparkAuthService);\n readonly config = inject(SPARK_AUTH_CONFIG);\n private readonly router = inject(Router);\n\n /** Same target the guard and interceptor use, so the bar cannot link somewhere they would not send you. */\n readonly signInUrl = resolveSignInUrl(this.config, this.router);\n\n /**\n * Where the account overview lives, or `undefined` when `withAccount()` did not mount it — then the\n * bar offers logout alone rather than a link that would fall through to some other route.\n *\n * `SPARK_AUTH_ROUTE_PATHS` is provided by `sparkAuthRoutes()` on its own route subtree, and this bar\n * usually lives in the application shell, outside it, so the token is injected optionally and the\n * router configuration is the fallback. Reading the configuration makes a custom `account` path\n * exact here too, instead of assuming the default.\n */\n readonly accountUrl = (inject(SPARK_AUTH_ROUTE_PATHS, { optional: true })\n ?? findSparkAuthRoutePaths(this.router.config))?.account;\n\n async onLogout(): Promise<void> {\n try {\n await this.authService.logout();\n } finally {\n // Always navigate away from the authenticated area, even if the server-side\n // logout call fails (network error, session already expired, etc.). The local\n // session state has been cleared by SparkAuthService regardless.\n this.router.navigateByUrl('/');\n }\n }\n}\n\nexport default SparkAuthBarComponent;\n","@if (authService.isAuthenticated()) {\n <!-- No user name here: an email address does not fit a topbar. The account page shows it, and\n the account page is also where passkeys, two-factor and the rest live when they are mounted.\n On a phone the two buttons are icons (their names stay as aria-label and title), so the\n topbar fits 375 px next to a language selector, an organization switcher and the bell. -->\n <bs-button-group>\n @if (accountUrl) {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-account\" [routerLink]=\"accountUrl\"\n [attr.title]=\"authService.user()?.userName\" [attr.aria-label]=\"'auth.account' | t\">\n <spark-icon name=\"person\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.account' | t }}</span>\n </a>\n }\n <button type=\"button\" class=\"btn btn-sm spark-auth-bar-btn text-nowrap spark-auth-bar-logout\" (click)=\"onLogout()\"\n [attr.title]=\"'auth.logout' | t\" [attr.aria-label]=\"'auth.logout' | t\">\n <spark-icon name=\"box-arrow-right\" class=\"spark-auth-bar-icon\" aria-hidden=\"true\" /><span class=\"spark-auth-bar-label\">{{ 'auth.logout' | t }}</span>\n </button>\n </bs-button-group>\n} @else {\n <a class=\"btn btn-sm spark-auth-bar-btn text-nowrap\" [routerLink]=\"signInUrl\">{{ 'auth.login' | t }}</a>\n}\n"],"mappings":";;;;;;;;AAoDA,IAAa,wBAAb,MAAa,sBAAqB;CACvB,cAAc,OAAO,gBAAgB;CACrC,SAAS,OAAO,iBAAiB;CACzB,SAAS,OAAO,MAAM;CAG9B,YAAY,iBAAiB,KAAK,QAAQ,KAAK,MAAM;CAWrD,cAAc,OAAO,wBAAwB,EAAE,UAAU,KAAI,CAAE,KACnE,wBAAwB,KAAK,OAAO,MAAM,EAAA,EAAI;CAEnD,MAAM,WAAQ;EACZ,IAAI;GACF,MAAM,KAAK,YAAY,OAAM;EAC/B,UAAU;GAIR,KAAK,OAAO,cAAc,GAAG;EAC/B;CACF;CA7BW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAqB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAArB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAqB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UCpDlC;EAoBA,QAAA,CAAA,kmBAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MDHY;IAAU,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAsB,UAAA;IAAA,QAAA,CAAA,WAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAoB;IAAkB,UAAA;IAAA,QAAA,CAAA,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAApC;IAAgB,MAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAmCnD,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAqB,YAAA,CAAA;EAvCjC,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAgB,YACd;GAAI,iBACC,wBAAwB;GAAM,SACtC;IAAC;IAAY;IAAwB;IAAkB;GAAkB;GAAC,UAAA;GAAA,QAAA,CAAA,kmBAAA;EAAA,CAAA"}
@@ -32,7 +32,7 @@ var SparkConfirmEmailComponent = class SparkConfirmEmailComponent {
32
32
  }
33
33
  static ɵfac = i0.ɵɵngDeclareFactory({
34
34
  minVersion: "12.0.0",
35
- version: "22.2.0",
35
+ version: "22.2.2",
36
36
  ngImport: i0,
37
37
  type: SparkConfirmEmailComponent,
38
38
  deps: [],
@@ -40,7 +40,7 @@ var SparkConfirmEmailComponent = class SparkConfirmEmailComponent {
40
40
  });
41
41
  static ɵcmp = i0.ɵɵngDeclareComponent({
42
42
  minVersion: "17.0.0",
43
- version: "22.2.0",
43
+ version: "22.2.2",
44
44
  type: SparkConfirmEmailComponent,
45
45
  isStandalone: true,
46
46
  selector: "spark-confirm-email",
@@ -140,7 +140,7 @@ var SparkConfirmEmailComponent = class SparkConfirmEmailComponent {
140
140
  };
141
141
  i0.ɵɵngDeclareClassMetadata({
142
142
  minVersion: "12.0.0",
143
- version: "22.2.0",
143
+ version: "22.2.2",
144
144
  ngImport: i0,
145
145
  type: SparkConfirmEmailComponent,
146
146
  decorators: [{
@@ -377,7 +377,7 @@ var SparkAuthService = class SparkAuthService {
377
377
  }
378
378
  static ɵfac = i0.ɵɵngDeclareFactory({
379
379
  minVersion: "12.0.0",
380
- version: "22.2.0",
380
+ version: "22.2.2",
381
381
  ngImport: i0,
382
382
  type: SparkAuthService,
383
383
  deps: [],
@@ -385,7 +385,7 @@ var SparkAuthService = class SparkAuthService {
385
385
  });
386
386
  static ɵprov = i0.ɵɵngDeclareInjectable({
387
387
  minVersion: "12.0.0",
388
- version: "22.2.0",
388
+ version: "22.2.2",
389
389
  ngImport: i0,
390
390
  type: SparkAuthService,
391
391
  providedIn: "root"
@@ -393,7 +393,7 @@ var SparkAuthService = class SparkAuthService {
393
393
  };
394
394
  i0.ɵɵngDeclareClassMetadata({
395
395
  minVersion: "12.0.0",
396
- version: "22.2.0",
396
+ version: "22.2.2",
397
397
  ngImport: i0,
398
398
  type: SparkAuthService,
399
399
  decorators: [{
@@ -422,7 +422,7 @@ var SparkAuthTranslationService = class SparkAuthTranslationService {
422
422
  }
423
423
  static ɵfac = i0.ɵɵngDeclareFactory({
424
424
  minVersion: "12.0.0",
425
- version: "22.2.0",
425
+ version: "22.2.2",
426
426
  ngImport: i0,
427
427
  type: SparkAuthTranslationService,
428
428
  deps: [],
@@ -430,7 +430,7 @@ var SparkAuthTranslationService = class SparkAuthTranslationService {
430
430
  });
431
431
  static ɵprov = i0.ɵɵngDeclareInjectable({
432
432
  minVersion: "12.0.0",
433
- version: "22.2.0",
433
+ version: "22.2.2",
434
434
  ngImport: i0,
435
435
  type: SparkAuthTranslationService,
436
436
  providedIn: "root"
@@ -438,7 +438,7 @@ var SparkAuthTranslationService = class SparkAuthTranslationService {
438
438
  };
439
439
  i0.ɵɵngDeclareClassMetadata({
440
440
  minVersion: "12.0.0",
441
- version: "22.2.0",
441
+ version: "22.2.2",
442
442
  ngImport: i0,
443
443
  type: SparkAuthTranslationService,
444
444
  decorators: [{
@@ -89,7 +89,7 @@ var SparkExternalLoginButtonsComponent = class SparkExternalLoginButtonsComponen
89
89
  }
90
90
  static ɵfac = i0.ɵɵngDeclareFactory({
91
91
  minVersion: "12.0.0",
92
- version: "22.2.0",
92
+ version: "22.2.2",
93
93
  ngImport: i0,
94
94
  type: SparkExternalLoginButtonsComponent,
95
95
  deps: [],
@@ -97,7 +97,7 @@ var SparkExternalLoginButtonsComponent = class SparkExternalLoginButtonsComponen
97
97
  });
98
98
  static ɵcmp = i0.ɵɵngDeclareComponent({
99
99
  minVersion: "17.0.0",
100
- version: "22.2.0",
100
+ version: "22.2.2",
101
101
  type: SparkExternalLoginButtonsComponent,
102
102
  isStandalone: true,
103
103
  selector: "spark-external-login-buttons",
@@ -158,7 +158,7 @@ var SparkExternalLoginButtonsComponent = class SparkExternalLoginButtonsComponen
158
158
  };
159
159
  i0.ɵɵngDeclareClassMetadata({
160
160
  minVersion: "12.0.0",
161
- version: "22.2.0",
161
+ version: "22.2.2",
162
162
  ngImport: i0,
163
163
  type: SparkExternalLoginButtonsComponent,
164
164
  decorators: [{
@@ -38,7 +38,7 @@ var SparkForgotPasswordComponent = class SparkForgotPasswordComponent {
38
38
  }
39
39
  static ɵfac = i0.ɵɵngDeclareFactory({
40
40
  minVersion: "12.0.0",
41
- version: "22.2.0",
41
+ version: "22.2.2",
42
42
  ngImport: i0,
43
43
  type: SparkForgotPasswordComponent,
44
44
  deps: [],
@@ -46,7 +46,7 @@ var SparkForgotPasswordComponent = class SparkForgotPasswordComponent {
46
46
  });
47
47
  static ɵcmp = i0.ɵɵngDeclareComponent({
48
48
  minVersion: "17.0.0",
49
- version: "22.2.0",
49
+ version: "22.2.2",
50
50
  type: SparkForgotPasswordComponent,
51
51
  isStandalone: true,
52
52
  selector: "spark-forgot-password",
@@ -167,7 +167,7 @@ var SparkForgotPasswordComponent = class SparkForgotPasswordComponent {
167
167
  };
168
168
  i0.ɵɵngDeclareClassMetadata({
169
169
  minVersion: "12.0.0",
170
- version: "22.2.0",
170
+ version: "22.2.2",
171
171
  ngImport: i0,
172
172
  type: SparkForgotPasswordComponent,
173
173
  decorators: [{
@@ -101,7 +101,7 @@ var SparkLoginComponent = class SparkLoginComponent {
101
101
  }
102
102
  static ɵfac = i0.ɵɵngDeclareFactory({
103
103
  minVersion: "12.0.0",
104
- version: "22.2.0",
104
+ version: "22.2.2",
105
105
  ngImport: i0,
106
106
  type: SparkLoginComponent,
107
107
  deps: [],
@@ -109,7 +109,7 @@ var SparkLoginComponent = class SparkLoginComponent {
109
109
  });
110
110
  static ɵcmp = i0.ɵɵngDeclareComponent({
111
111
  minVersion: "17.0.0",
112
- version: "22.2.0",
112
+ version: "22.2.2",
113
113
  type: SparkLoginComponent,
114
114
  isStandalone: true,
115
115
  selector: "spark-login",
@@ -250,7 +250,7 @@ var SparkLoginComponent = class SparkLoginComponent {
250
250
  };
251
251
  i0.ɵɵngDeclareClassMetadata({
252
252
  minVersion: "12.0.0",
253
- version: "22.2.0",
253
+ version: "22.2.2",
254
254
  ngImport: i0,
255
255
  type: SparkLoginComponent,
256
256
  decorators: [{
@@ -8,7 +8,7 @@ var TranslateKeyPipe = class TranslateKeyPipe {
8
8
  }
9
9
  static ɵfac = i0.ɵɵngDeclareFactory({
10
10
  minVersion: "12.0.0",
11
- version: "22.2.0",
11
+ version: "22.2.2",
12
12
  ngImport: i0,
13
13
  type: TranslateKeyPipe,
14
14
  deps: [],
@@ -16,7 +16,7 @@ var TranslateKeyPipe = class TranslateKeyPipe {
16
16
  });
17
17
  static ɵpipe = i0.ɵɵngDeclarePipe({
18
18
  minVersion: "14.0.0",
19
- version: "22.2.0",
19
+ version: "22.2.2",
20
20
  ngImport: i0,
21
21
  type: TranslateKeyPipe,
22
22
  isStandalone: true,
@@ -26,7 +26,7 @@ var TranslateKeyPipe = class TranslateKeyPipe {
26
26
  };
27
27
  i0.ɵɵngDeclareClassMetadata({
28
28
  minVersion: "12.0.0",
29
- version: "22.2.0",
29
+ version: "22.2.2",
30
30
  ngImport: i0,
31
31
  type: TranslateKeyPipe,
32
32
  decorators: [{
@@ -58,7 +58,7 @@ var SparkRegisterComponent = class SparkRegisterComponent {
58
58
  }
59
59
  static ɵfac = i0.ɵɵngDeclareFactory({
60
60
  minVersion: "12.0.0",
61
- version: "22.2.0",
61
+ version: "22.2.2",
62
62
  ngImport: i0,
63
63
  type: SparkRegisterComponent,
64
64
  deps: [],
@@ -66,7 +66,7 @@ var SparkRegisterComponent = class SparkRegisterComponent {
66
66
  });
67
67
  static ɵcmp = i0.ɵɵngDeclareComponent({
68
68
  minVersion: "17.0.0",
69
- version: "22.2.0",
69
+ version: "22.2.2",
70
70
  type: SparkRegisterComponent,
71
71
  isStandalone: true,
72
72
  selector: "spark-register",
@@ -187,7 +187,7 @@ var SparkRegisterComponent = class SparkRegisterComponent {
187
187
  };
188
188
  i0.ɵɵngDeclareClassMetadata({
189
189
  minVersion: "12.0.0",
190
- version: "22.2.0",
190
+ version: "22.2.2",
191
191
  ngImport: i0,
192
192
  type: SparkRegisterComponent,
193
193
  decorators: [{