@franzzemen/brokenstock-shell 0.3.3 → 0.4.1
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.
|
@@ -68,10 +68,10 @@ class ThinkingService {
|
|
|
68
68
|
reset() {
|
|
69
69
|
this.#activeCount.set(0);
|
|
70
70
|
}
|
|
71
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
72
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
71
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThinkingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
72
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThinkingService, providedIn: 'root' }); }
|
|
73
73
|
}
|
|
74
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThinkingService, decorators: [{
|
|
75
75
|
type: Injectable,
|
|
76
76
|
args: [{ providedIn: 'root' }]
|
|
77
77
|
}] });
|
|
@@ -84,9 +84,6 @@ class AuthenticationService {
|
|
|
84
84
|
...(ngDevMode ? [{ debugName: "authenticating" }] : /* istanbul ignore next */ []));
|
|
85
85
|
this.userSession = signal(undefined, /* @ts-ignore */
|
|
86
86
|
...(ngDevMode ? [{ debugName: "userSession" }] : /* istanbul ignore next */ []));
|
|
87
|
-
/** Plan-feature grants for the current session. Absent key = not granted. */
|
|
88
|
-
this.features = signal({}, /* @ts-ignore */
|
|
89
|
-
...(ngDevMode ? [{ debugName: "features" }] : /* istanbul ignore next */ []));
|
|
90
87
|
this.conflictSessions = signal(undefined, /* @ts-ignore */
|
|
91
88
|
...(ngDevMode ? [{ debugName: "conflictSessions" }] : /* istanbul ignore next */ []));
|
|
92
89
|
this.pendingCredentials = signal(undefined, /* @ts-ignore */
|
|
@@ -108,36 +105,19 @@ class AuthenticationService {
|
|
|
108
105
|
return this.#auth;
|
|
109
106
|
}
|
|
110
107
|
// Legacy hasRole/hasAnyRole removed (legacy-authz-teardown): sessions carry no
|
|
111
|
-
// roles, and every gate
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* - `number`>0 → granted with that limit
|
|
125
|
-
*
|
|
126
|
-
* It also matters in the other direction: `!!` passed on any positive number, so a
|
|
127
|
-
* boolean slug misconfigured with a numeric value would show the affordance while
|
|
128
|
-
* the BE — which requires exactly `true` — refused every call behind it. The user
|
|
129
|
-
* sees the door and cannot open it.
|
|
130
|
-
*
|
|
131
|
-
* For QUANTITY features use {@link featureValue} and compare the limit yourself;
|
|
132
|
-
* this returns false for every numeric grant, including a valid one.
|
|
133
|
-
*/
|
|
134
|
-
hasFeature(slug) {
|
|
135
|
-
return this.authenticated() && this.features()[slug] === true;
|
|
136
|
-
}
|
|
137
|
-
/** Raw plan-feature value (`true` for boolean grants, the numeric limit for quantity features, else undefined). */
|
|
138
|
-
featureValue(slug) {
|
|
139
|
-
return this.features()[slug];
|
|
140
|
-
}
|
|
108
|
+
// roles, and every gate moved to hasFeature (commerce) with the BE enforcing the
|
|
109
|
+
// security axis.
|
|
110
|
+
//
|
|
111
|
+
// `hasFeature` and `featureValue` are now gone too, with all entitlement gating
|
|
112
|
+
// (commercial-surface-decommission.prd.md D3). BrokenStock is not a commercial
|
|
113
|
+
// product; there is nothing to be entitled to. Per P1 every capability they hid is
|
|
114
|
+
// unconditionally available, so the callers did not migrate to some other check —
|
|
115
|
+
// they simply stopped asking. The session's `features` map is no longer read here at
|
|
116
|
+
// all, which is what makes it safe for the back end to stop populating it (E9).
|
|
117
|
+
//
|
|
118
|
+
// The security axis is unaffected and still enforced server-side: this app cannot see
|
|
119
|
+
// security roles by design (`@franzzemen/endpoint-identity` is deliberately absent
|
|
120
|
+
// from its dependency graph).
|
|
141
121
|
refresh() {
|
|
142
122
|
if (this.#refreshing) {
|
|
143
123
|
return this.#refreshing;
|
|
@@ -195,7 +175,6 @@ class AuthenticationService {
|
|
|
195
175
|
// @ts-ignore
|
|
196
176
|
delete authResponse.session.token;
|
|
197
177
|
this.userSession.set(authResponse.session);
|
|
198
|
-
this.features.set(authResponse.features ?? {});
|
|
199
178
|
const auth = response.headers.get(HttpHeader.Authorization);
|
|
200
179
|
if (!auth || !BEARER_TOKEN_REGEX.test(auth)) {
|
|
201
180
|
reject('Unable to login');
|
|
@@ -253,7 +232,6 @@ class AuthenticationService {
|
|
|
253
232
|
const body = await response.json();
|
|
254
233
|
this.#auth = auth;
|
|
255
234
|
this.userSession.set(body.session);
|
|
256
|
-
this.features.set(body.features ?? {});
|
|
257
235
|
return true;
|
|
258
236
|
}
|
|
259
237
|
catch {
|
|
@@ -263,16 +241,15 @@ class AuthenticationService {
|
|
|
263
241
|
#clearSession() {
|
|
264
242
|
this.authenticated.set(false);
|
|
265
243
|
this.userSession.set(undefined);
|
|
266
|
-
this.features.set({});
|
|
267
244
|
this.conflictSessions.set(undefined);
|
|
268
245
|
this.pendingCredentials.set(undefined);
|
|
269
246
|
this.#auth = 'Bearer ..';
|
|
270
247
|
this.#router.navigate(['/login']).catch(console.error);
|
|
271
248
|
}
|
|
272
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
273
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
249
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthenticationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
250
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthenticationService, providedIn: 'root' }); }
|
|
274
251
|
}
|
|
275
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
252
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: AuthenticationService, decorators: [{
|
|
276
253
|
type: Injectable,
|
|
277
254
|
args: [{ providedIn: 'root' }]
|
|
278
255
|
}] });
|
|
@@ -341,10 +318,10 @@ class RegexValidatorDirective {
|
|
|
341
318
|
}
|
|
342
319
|
return null;
|
|
343
320
|
}
|
|
344
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
345
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
321
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RegexValidatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
322
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.2", type: RegexValidatorDirective, isStandalone: true, selector: "[regexValidator]", inputs: { regex: { classPropertyName: "regex", publicName: "regex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }], ngImport: i0 }); }
|
|
346
323
|
}
|
|
347
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
324
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RegexValidatorDirective, decorators: [{
|
|
348
325
|
type: Directive,
|
|
349
326
|
args: [{
|
|
350
327
|
selector: '[regexValidator]',
|
|
@@ -433,10 +410,10 @@ class FaqMarkdownRendererService {
|
|
|
433
410
|
},
|
|
434
411
|
};
|
|
435
412
|
}
|
|
436
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
437
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
413
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqMarkdownRendererService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
414
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqMarkdownRendererService, providedIn: 'root' }); }
|
|
438
415
|
}
|
|
439
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
416
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqMarkdownRendererService, decorators: [{
|
|
440
417
|
type: Injectable,
|
|
441
418
|
args: [{ providedIn: 'root' }]
|
|
442
419
|
}] });
|
|
@@ -486,10 +463,10 @@ class HttpFaqContentLoader {
|
|
|
486
463
|
this.contentCache.set(key, fetchPromise);
|
|
487
464
|
return fetchPromise;
|
|
488
465
|
}
|
|
489
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
490
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
466
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: HttpFaqContentLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
467
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: HttpFaqContentLoader, providedIn: 'root' }); }
|
|
491
468
|
}
|
|
492
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
469
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: HttpFaqContentLoader, decorators: [{
|
|
493
470
|
type: Injectable,
|
|
494
471
|
args: [{ providedIn: 'root' }]
|
|
495
472
|
}] });
|
|
@@ -643,10 +620,10 @@ class FaqHistoryService {
|
|
|
643
620
|
this.teardown();
|
|
644
621
|
exit?.();
|
|
645
622
|
}
|
|
646
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
647
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
623
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqHistoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
624
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqHistoryService, providedIn: 'root' }); }
|
|
648
625
|
}
|
|
649
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
626
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqHistoryService, decorators: [{
|
|
650
627
|
type: Injectable,
|
|
651
628
|
args: [{ providedIn: 'root' }]
|
|
652
629
|
}] });
|
|
@@ -859,10 +836,10 @@ class FaqService {
|
|
|
859
836
|
this._navigating.set(false);
|
|
860
837
|
}
|
|
861
838
|
}
|
|
862
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
863
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
839
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
840
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqService, providedIn: 'root' }); }
|
|
864
841
|
}
|
|
865
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
842
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqService, decorators: [{
|
|
866
843
|
type: Injectable,
|
|
867
844
|
args: [{ providedIn: 'root' }]
|
|
868
845
|
}] });
|
|
@@ -1151,12 +1128,12 @@ class FaqModal {
|
|
|
1151
1128
|
return;
|
|
1152
1129
|
}
|
|
1153
1130
|
}
|
|
1154
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1155
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FaqModal, isStandalone: true, selector: "faq-modal", host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "contentPaneRef", first: true, predicate: ["contentPane"], descendants: true }], ngImport: i0, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None, deferBlockDependencies: [() => [/* @ts-ignore */
|
|
1131
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqModal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1132
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: FaqModal, isStandalone: true, selector: "faq-modal", host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "contentPaneRef", first: true, predicate: ["contentPane"], descendants: true }], ngImport: i0, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None, deferBlockDependencies: [() => [/* @ts-ignore */
|
|
1156
1133
|
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)], () => [/* @ts-ignore */
|
|
1157
1134
|
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)]] }); }
|
|
1158
1135
|
}
|
|
1159
|
-
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.
|
|
1136
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.2", ngImport: i0, type: FaqModal, resolveDeferredDeps: () => [/* @ts-ignore */
|
|
1160
1137
|
Promise.resolve().then(function () { return faqAuthoringPanel; }).then(m => m.FaqAuthoringPanel)], resolveMetadata: FaqAuthoringPanel => ({ decorators: [{
|
|
1161
1138
|
type: Component,
|
|
1162
1139
|
args: [{ selector: 'faq-modal', standalone: true, imports: [FaqAuthoringPanel], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >\u2630</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >\u2039</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >\u203A</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >\u2302</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >\u2315</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >\u2715</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ\u2026\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index\u2026</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading\u2026</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' \u2192 ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel\u2026</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n", styles: [":host{display:contents}.faq-backdrop{position:fixed;inset:0;z-index:1100;background:#0000008c;display:flex;align-items:center;justify-content:center;padding:5vh 5vw}.faq-modal{width:80vw;height:80vh;max-width:1600px;max-height:1100px;background:var(--shell-surface, #1d1f23);color:var(--shell-fg, #e6e6e6);border-radius:8px;box-shadow:0 12px 32px #00000080;display:grid;grid-template-rows:auto 1fr;overflow:hidden;font-family:var(--shell-font, system-ui, sans-serif)}.faq-toolbar{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--shell-border, rgba(255, 255, 255, .08));background:var(--shell-surface-2, rgba(255, 255, 255, .03))}.faq-toolbar-nav,.faq-toolbar-actions{display:flex;gap:.25rem}.faq-toolbar-title{text-align:center;font-size:.95rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.faq-category{opacity:.7;margin-right:.25rem}.faq-sep{opacity:.4;margin:0 .25rem}.faq-title{font-weight:600}.faq-icon-btn{background:transparent;border:1px solid transparent;color:inherit;width:2rem;height:2rem;border-radius:4px;cursor:pointer;font-size:1rem;line-height:1;display:inline-flex;align-items:center;justify-content:center}.faq-icon-btn:hover:not(:disabled){background:#ffffff14}.faq-icon-btn:disabled{opacity:.35;cursor:not-allowed}.faq-icon-btn.active{background:#ffffff1f;border-color:#ffffff2e}.faq-body{display:grid;grid-template-columns:260px 1fr;min-height:0}.faq-body.sidebar-collapsed{grid-template-columns:0 1fr}.faq-body.sidebar-collapsed .faq-sidebar{display:none}.faq-sidebar{border-right:1px solid var(--shell-border, rgba(255, 255, 255, .08));overflow-y:auto;padding:.75rem .5rem;background:var(--shell-surface, #1d1f23)}.faq-toc-group{margin-bottom:1rem}.faq-toc-category{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.6;margin:0 0 .4rem .4rem}.faq-toc ul{list-style:none;padding:0;margin:0}.faq-toc-link{display:block;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.35rem .5rem;border-radius:4px;cursor:pointer;font-size:.88rem}.faq-toc-link:hover{background:#ffffff0f}.faq-toc-link.active{background:#ffffff1f;font-weight:600}.faq-toc-empty{padding:1rem .5rem;opacity:.7;font-size:.85rem}.faq-search{display:flex;flex-direction:column;gap:.5rem;padding:.25rem}.faq-search-input{width:100%;padding:.5rem .6rem;border-radius:4px;border:1px solid rgba(255,255,255,.18);background:#00000040;color:inherit;font-size:.9rem;box-sizing:border-box}.faq-search-input:focus{outline:none;border-color:#fff6}.faq-search-status{padding:.5rem;opacity:.65;font-size:.82rem;margin:0}.faq-search-results{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}.faq-search-result{display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;background:transparent;border:none;color:inherit;padding:.45rem .5rem;border-radius:4px;cursor:pointer}.faq-search-result:hover{background:#ffffff0f}.faq-search-result.active{background:#ffffff1f}.faq-search-result-title{font-size:.9rem;font-weight:600}.faq-search-result-category{font-size:.72rem;opacity:.6;text-transform:uppercase;letter-spacing:.04em}.faq-search-result-snippet{font-size:.78rem;opacity:.75;line-height:1.35}.faq-content{overflow-y:auto;padding:1.25rem 2rem;min-width:0}.faq-loading,.faq-empty{opacity:.75;padding:1rem 0}.faq-empty-chain code{background:#ffffff14;padding:.1rem .4rem;border-radius:3px;font-size:.85rem}.faq-empty-hint{margin-top:1rem;opacity:.55;font-size:.85rem}.faq-article{max-width:70ch;line-height:1.55;font-size:.95rem}.faq-article h1,.faq-article h2,.faq-article h3{font-weight:600;margin:1.4rem 0 .6rem}.faq-article h1{font-size:1.4rem;margin-top:0}.faq-article h2{font-size:1.15rem}.faq-article h3{font-size:1rem}.faq-article p{margin:.6rem 0}.faq-article a{color:var(--shell-link, #6ea8fe);text-decoration:none}.faq-article a:hover{text-decoration:underline}.faq-article a[data-faq-kind=external]:after{content:\" \\2197\";opacity:.65;font-size:.85em}.faq-article .faq-app-arrow{opacity:.7;font-size:.9em}.faq-article code{background:#ffffff14;padding:.1rem .35rem;border-radius:3px;font-size:.88em}.faq-article pre{background:#00000059;padding:.75rem 1rem;border-radius:4px;overflow-x:auto}.faq-article pre code{background:transparent;padding:0}.faq-article img{max-width:100%;border-radius:4px;margin:.6rem 0}.faq-article ul,.faq-article ol{padding-left:1.4rem;margin:.6rem 0}.faq-article blockquote{border-left:3px solid var(--shell-border, rgba(255, 255, 255, .15));padding-left:.9rem;margin:.8rem 0;opacity:.85}@media(max-width:900px){.faq-modal{width:100vw;height:100vh;border-radius:0;max-width:none;max-height:none}.faq-backdrop{padding:0}.faq-body{grid-template-columns:1fr}.faq-sidebar{display:none}.faq-body:not(.sidebar-collapsed) .faq-sidebar{display:block;position:absolute;inset:0;z-index:1}}\n"] }]
|
|
@@ -1297,10 +1274,10 @@ class FaqAuthoringPanel {
|
|
|
1297
1274
|
this.copyState.set(`${label}:err`);
|
|
1298
1275
|
}
|
|
1299
1276
|
}
|
|
1300
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1301
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
1277
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqAuthoringPanel, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1278
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: FaqAuthoringPanel, isStandalone: true, selector: "faq-authoring-panel", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, attempted: { classPropertyName: "attempted", publicName: "attempted", isSignal: true, isRequired: false, transformFunction: null }, entry: { classPropertyName: "entry", publicName: "entry", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} \u2197</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> \u2014 external (new tab)</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">\u2022</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} \u2197</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '\u25B2 Less' : '\u25BC More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app</li>\n <li><code>[label](https://example.com)</code> \u2014 external</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n", styles: [":host{display:block;font-family:var(--shell-font, system-ui, sans-serif);font-size:.875rem;color:var(--shell-fg, #e6e6e6)}.faq-authoring{border:1px dashed var(--shell-accent, #6aa0ff);border-radius:6px;background:#6aa0ff0a}.faq-authoring.missing{padding:1rem 1.25rem;display:grid;gap:.85rem}.faq-authoring.existing{margin-top:1.5rem;padding:.5rem .75rem;background:#6aa0ff08;border-style:dotted}.faq-authoring-header{display:flex;align-items:baseline;gap:.5rem;margin:0}.faq-authoring-header h3{margin:0;font-size:1rem}.faq-authoring-tag{display:inline-block;padding:.05rem .4rem;background:var(--shell-accent, #6aa0ff);color:#0b0d11;border-radius:3px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.faq-authoring-meta{display:grid;grid-template-columns:max-content 1fr;gap:.35rem .85rem;margin:0}.faq-authoring-meta dt{font-weight:600;opacity:.75}.faq-authoring-meta dd{margin:0}.faq-authoring code{font-family:var(--shell-mono, ui-monospace, monospace);background:#ffffff0f;padding:.05rem .3rem;border-radius:3px;font-size:.85em}.faq-authoring-chain{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:.4rem}.faq-authoring-chain.inline{display:inline-flex;margin-left:.5rem}.faq-authoring-chain li{display:inline-flex;align-items:center;gap:.25rem}.faq-authoring-chain .mark{font-weight:700}.faq-authoring-chain .missed .mark{color:#ff7676}.faq-authoring-chain .present .mark{color:#8ad27a}.faq-authoring-editor{margin-left:.75rem;color:var(--shell-accent, #6aa0ff);text-decoration:none}.faq-authoring-editor:hover{text-decoration:underline}.faq-authoring-block{border:1px solid var(--shell-border, rgba(255, 255, 255, .08));border-radius:4px;overflow:hidden}.faq-authoring-block-head{display:flex;justify-content:space-between;align-items:center;padding:.4rem .6rem;background:#ffffff0a;font-weight:600;font-size:.8rem}.faq-authoring-block-head button,.faq-authoring-more,.faq-authoring-rescaffold button{background:var(--shell-accent, #6aa0ff);color:#0b0d11;border:0;border-radius:3px;padding:.2rem .55rem;font-size:.75rem;cursor:pointer;font-family:inherit}.faq-authoring-block pre{margin:0;padding:.6rem .75rem;overflow-x:auto;background:#00000040;font-size:.8rem}.faq-authoring-cheat,.faq-authoring-all{font-size:.85rem}.faq-authoring-cheat summary,.faq-authoring-all summary{cursor:pointer;opacity:.85}.faq-authoring-cheat ul,.faq-authoring-file-list{margin:.4rem 0 0;padding-left:1.25rem}.faq-authoring-file-list{list-style:none;padding-left:0;max-height:200px;overflow-y:auto}.faq-authoring-file-list li{display:flex;justify-content:space-between;gap:.5rem;padding:.15rem 0;border-bottom:1px solid rgba(255,255,255,.04)}.faq-authoring-file-path{opacity:.6;font-family:var(--shell-mono, ui-monospace, monospace);font-size:.75rem}.faq-authoring-strip{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:.8rem}.faq-authoring-strip .sep{opacity:.4}.faq-authoring-more{margin-left:auto}.faq-authoring-expanded{margin-top:.6rem;padding-top:.5rem;border-top:1px solid rgba(255,255,255,.08);display:grid;gap:.6rem}.faq-authoring-rescaffold{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;font-size:.8rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1302
1279
|
}
|
|
1303
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1280
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqAuthoringPanel, decorators: [{
|
|
1304
1281
|
type: Component,
|
|
1305
1282
|
args: [{ selector: 'faq-authoring-panel', standalone: true, imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} \u2197</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> \u2014 external (new tab)</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">\u2022</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} \u2197</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '\u25B2 Less' : '\u25BC More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '\u2713' : '\u2717' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> \u2014 in-modal nav</li>\n <li><code>[label](app:/settings)</code> \u2014 navigates the app</li>\n <li><code>[label](https://example.com)</code> \u2014 external</li>\n <li><code>[label](#section-id)</code> \u2014 intra-page anchor</li>\n <li><code></code> \u2014 image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied \u2713' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n", styles: [":host{display:block;font-family:var(--shell-font, system-ui, sans-serif);font-size:.875rem;color:var(--shell-fg, #e6e6e6)}.faq-authoring{border:1px dashed var(--shell-accent, #6aa0ff);border-radius:6px;background:#6aa0ff0a}.faq-authoring.missing{padding:1rem 1.25rem;display:grid;gap:.85rem}.faq-authoring.existing{margin-top:1.5rem;padding:.5rem .75rem;background:#6aa0ff08;border-style:dotted}.faq-authoring-header{display:flex;align-items:baseline;gap:.5rem;margin:0}.faq-authoring-header h3{margin:0;font-size:1rem}.faq-authoring-tag{display:inline-block;padding:.05rem .4rem;background:var(--shell-accent, #6aa0ff);color:#0b0d11;border-radius:3px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.faq-authoring-meta{display:grid;grid-template-columns:max-content 1fr;gap:.35rem .85rem;margin:0}.faq-authoring-meta dt{font-weight:600;opacity:.75}.faq-authoring-meta dd{margin:0}.faq-authoring code{font-family:var(--shell-mono, ui-monospace, monospace);background:#ffffff0f;padding:.05rem .3rem;border-radius:3px;font-size:.85em}.faq-authoring-chain{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:.4rem}.faq-authoring-chain.inline{display:inline-flex;margin-left:.5rem}.faq-authoring-chain li{display:inline-flex;align-items:center;gap:.25rem}.faq-authoring-chain .mark{font-weight:700}.faq-authoring-chain .missed .mark{color:#ff7676}.faq-authoring-chain .present .mark{color:#8ad27a}.faq-authoring-editor{margin-left:.75rem;color:var(--shell-accent, #6aa0ff);text-decoration:none}.faq-authoring-editor:hover{text-decoration:underline}.faq-authoring-block{border:1px solid var(--shell-border, rgba(255, 255, 255, .08));border-radius:4px;overflow:hidden}.faq-authoring-block-head{display:flex;justify-content:space-between;align-items:center;padding:.4rem .6rem;background:#ffffff0a;font-weight:600;font-size:.8rem}.faq-authoring-block-head button,.faq-authoring-more,.faq-authoring-rescaffold button{background:var(--shell-accent, #6aa0ff);color:#0b0d11;border:0;border-radius:3px;padding:.2rem .55rem;font-size:.75rem;cursor:pointer;font-family:inherit}.faq-authoring-block pre{margin:0;padding:.6rem .75rem;overflow-x:auto;background:#00000040;font-size:.8rem}.faq-authoring-cheat,.faq-authoring-all{font-size:.85rem}.faq-authoring-cheat summary,.faq-authoring-all summary{cursor:pointer;opacity:.85}.faq-authoring-cheat ul,.faq-authoring-file-list{margin:.4rem 0 0;padding-left:1.25rem}.faq-authoring-file-list{list-style:none;padding-left:0;max-height:200px;overflow-y:auto}.faq-authoring-file-list li{display:flex;justify-content:space-between;gap:.5rem;padding:.15rem 0;border-bottom:1px solid rgba(255,255,255,.04)}.faq-authoring-file-path{opacity:.6;font-family:var(--shell-mono, ui-monospace, monospace);font-size:.75rem}.faq-authoring-strip{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;font-size:.8rem}.faq-authoring-strip .sep{opacity:.4}.faq-authoring-more{margin-left:auto}.faq-authoring-expanded{margin-top:.6rem;padding-top:.5rem;border-top:1px solid rgba(255,255,255,.08);display:grid;gap:.6rem}.faq-authoring-rescaffold{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;font-size:.8rem}\n"] }]
|
|
1306
1283
|
}], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], attempted: [{ type: i0.Input, args: [{ isSignal: true, alias: "attempted", required: false }] }], entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: false }] }] } });
|
|
@@ -1364,8 +1341,8 @@ class PublicFaqToc {
|
|
|
1364
1341
|
const manifest = await this.loader.loadManifest();
|
|
1365
1342
|
this._entries.set(manifest.entries);
|
|
1366
1343
|
}
|
|
1367
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1368
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
1344
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqToc, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1345
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: PublicFaqToc, isStandalone: true, selector: "public-faq-toc", inputs: { activeFile: { classPropertyName: "activeFile", publicName: "activeFile", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1369
1346
|
<nav class="public-faq-toc" aria-label="Help contents">
|
|
1370
1347
|
<a
|
|
1371
1348
|
class="public-faq-toc__index"
|
|
@@ -1391,7 +1368,7 @@ class PublicFaqToc {
|
|
|
1391
1368
|
</nav>
|
|
1392
1369
|
`, isInline: true, styles: [":host{display:block}.public-faq-toc{padding:1.25rem 1rem;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:.95rem;line-height:1.4}.public-faq-toc__index{display:block;font-weight:600;color:#cfd6e4;text-decoration:none;padding:.4rem .5rem;border-radius:4px;margin-bottom:.75rem}.public-faq-toc__index.active,.public-faq-toc__index:hover{background:#ffffff0f}.public-faq-toc__group{margin-bottom:1rem}.public-faq-toc__category{font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#8a93a3;margin:0 0 .35rem;padding:0 .5rem}.public-faq-toc ul{list-style:none;padding:0;margin:0}.public-faq-toc li a{display:block;padding:.35rem .5rem;border-radius:4px;color:#cfd6e4;text-decoration:none}.public-faq-toc li a:hover{background:#ffffff0d}.public-faq-toc li a.active{background:#6ea8fe2e;color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1393
1370
|
}
|
|
1394
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqToc, decorators: [{
|
|
1395
1372
|
type: Component,
|
|
1396
1373
|
args: [{ selector: 'public-faq-toc', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive], template: `
|
|
1397
1374
|
<nav class="public-faq-toc" aria-label="Help contents">
|
|
@@ -1533,8 +1510,8 @@ class PublicFaqIndex {
|
|
|
1533
1510
|
this.meta.updateTag({ name: 'twitter:title', content: 'Help — Brokenstock' });
|
|
1534
1511
|
this.meta.updateTag({ name: 'twitter:description', content: description });
|
|
1535
1512
|
}
|
|
1536
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1537
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
1513
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqIndex, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1514
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: PublicFaqIndex, isStandalone: true, selector: "public-faq-index", ngImport: i0, template: `
|
|
1538
1515
|
<div class="public-faq-layout">
|
|
1539
1516
|
<aside class="public-faq-sidebar">
|
|
1540
1517
|
<public-faq-toc />
|
|
@@ -1572,7 +1549,7 @@ class PublicFaqIndex {
|
|
|
1572
1549
|
</div>
|
|
1573
1550
|
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-index{max-width:860px;font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.55}header h1{font-size:2.25rem;margin:0 0 .5rem}.lead{color:#9aa3b3;margin:0 0 2rem;font-size:1.1rem}h2{font-size:1.35rem;margin:1.75rem 0 .5rem;border-bottom:1px solid rgba(255,255,255,.08);padding-bottom:.25rem}ul{list-style:none;padding:0;margin:0}li{padding:.4rem 0}.public-faq-index a{color:#6ea8fe;text-decoration:none;font-weight:500}.public-faq-index a:hover{text-decoration:underline}.desc{color:#8a93a3;font-weight:400}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1574
1551
|
}
|
|
1575
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1552
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqIndex, decorators: [{
|
|
1576
1553
|
type: Component,
|
|
1577
1554
|
args: [{ selector: 'public-faq-index', standalone: true, imports: [CommonModule, RouterLink, PublicFaqToc], template: `
|
|
1578
1555
|
<div class="public-faq-layout">
|
|
@@ -1743,8 +1720,8 @@ class PublicFaqPage {
|
|
|
1743
1720
|
const base = this.siteBase.replace(/\/+$/, '');
|
|
1744
1721
|
return `${base}/help/${entry.file}`;
|
|
1745
1722
|
}
|
|
1746
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1747
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
1723
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqPage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1724
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: PublicFaqPage, isStandalone: true, selector: "public-faq-page", ngImport: i0, template: `
|
|
1748
1725
|
<div class="public-faq-layout">
|
|
1749
1726
|
<aside class="public-faq-sidebar">
|
|
1750
1727
|
<public-faq-toc [activeFile]="activeFile()" />
|
|
@@ -1773,7 +1750,7 @@ class PublicFaqPage {
|
|
|
1773
1750
|
</div>
|
|
1774
1751
|
`, isInline: true, styles: [":host{display:block}.public-faq-layout{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:1.5rem;max-width:1280px;margin:0 auto;padding:1.5rem 1.25rem 4rem}.public-faq-sidebar{border-right:1px solid rgba(255,255,255,.08);align-self:start;position:sticky;top:1rem;max-height:calc(100vh - 2rem);overflow-y:auto}.public-faq-page{font-family:system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.6;max-width:860px}header h1{font-size:2.1rem;margin:0 0 .5rem}.lead{color:#9aa3b3;font-size:1.1rem;margin:0 0 1.5rem}.body :is(h1,h2,h3,h4){margin-top:2rem}.body a{color:#6ea8fe}.body img{max-width:100%;height:auto}.body pre{background:#00000059;padding:.75rem 1rem;border-radius:6px;overflow-x:auto}.body code{background:#ffffff14;padding:.1rem .3rem;border-radius:3px;font-size:.9em}.body pre code{background:transparent;padding:0}@media(max-width:900px){.public-faq-layout{grid-template-columns:1fr}.public-faq-sidebar{position:static;max-height:none;border-right:none;border-bottom:1px solid rgba(255,255,255,.08)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: PublicFaqToc, selector: "public-faq-toc", inputs: ["activeFile"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1775
1752
|
}
|
|
1776
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1753
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: PublicFaqPage, decorators: [{
|
|
1777
1754
|
type: Component,
|
|
1778
1755
|
args: [{ selector: 'public-faq-page', standalone: true, imports: [CommonModule, RouterLink, PublicFaqToc], template: `
|
|
1779
1756
|
<div class="public-faq-layout">
|
|
@@ -1822,10 +1799,10 @@ class ThemeService {
|
|
|
1822
1799
|
this.isDark = computed(() => this.mode() === 'dark', /* @ts-ignore */
|
|
1823
1800
|
...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
|
|
1824
1801
|
}
|
|
1825
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1826
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
1802
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1803
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
|
|
1827
1804
|
}
|
|
1828
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1805
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ThemeService, decorators: [{
|
|
1829
1806
|
type: Injectable,
|
|
1830
1807
|
args: [{ providedIn: 'root' }]
|
|
1831
1808
|
}] });
|
|
@@ -1838,10 +1815,10 @@ class TerminalFocusService {
|
|
|
1838
1815
|
requestFocus() {
|
|
1839
1816
|
this.focusRequested.update(v => v + 1);
|
|
1840
1817
|
}
|
|
1841
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1842
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
1818
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1819
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalFocusService, providedIn: 'root' }); }
|
|
1843
1820
|
}
|
|
1844
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1821
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalFocusService, decorators: [{
|
|
1845
1822
|
type: Injectable,
|
|
1846
1823
|
args: [{ providedIn: 'root' }]
|
|
1847
1824
|
}] });
|
|
@@ -1880,10 +1857,10 @@ class TerminalVisibilityService {
|
|
|
1880
1857
|
return true;
|
|
1881
1858
|
}
|
|
1882
1859
|
}
|
|
1883
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1884
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
1860
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalVisibilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1861
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalVisibilityService, providedIn: 'root' }); }
|
|
1885
1862
|
}
|
|
1886
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1863
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TerminalVisibilityService, decorators: [{
|
|
1887
1864
|
type: Injectable,
|
|
1888
1865
|
args: [{ providedIn: 'root' }]
|
|
1889
1866
|
}], ctorParameters: () => [] });
|
|
@@ -1967,10 +1944,10 @@ class KeyboardShortcutService {
|
|
|
1967
1944
|
}
|
|
1968
1945
|
return false;
|
|
1969
1946
|
}
|
|
1970
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
1971
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
1947
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KeyboardShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1948
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KeyboardShortcutService, providedIn: 'root' }); }
|
|
1972
1949
|
}
|
|
1973
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
1950
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: KeyboardShortcutService, decorators: [{
|
|
1974
1951
|
type: Injectable,
|
|
1975
1952
|
args: [{ providedIn: 'root' }]
|
|
1976
1953
|
}], ctorParameters: () => [] });
|
|
@@ -2022,10 +1999,10 @@ class FaqCommand {
|
|
|
2022
1999
|
void this.faqService.openModal(args[0]);
|
|
2023
2000
|
return { success: true, message: '', timestamp: ts() };
|
|
2024
2001
|
}
|
|
2025
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2026
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
2002
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2003
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqCommand, providedIn: 'root' }); }
|
|
2027
2004
|
}
|
|
2028
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2005
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: FaqCommand, decorators: [{
|
|
2029
2006
|
type: Injectable,
|
|
2030
2007
|
args: [{ providedIn: 'root' }]
|
|
2031
2008
|
}] });
|
|
@@ -2067,10 +2044,10 @@ class CommandRegistryService {
|
|
|
2067
2044
|
.filter(name => name.startsWith(prefix) && name !== prefix)
|
|
2068
2045
|
.sort();
|
|
2069
2046
|
}
|
|
2070
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2071
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
2047
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2048
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandRegistryService, providedIn: 'root' }); }
|
|
2072
2049
|
}
|
|
2073
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2050
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandRegistryService, decorators: [{
|
|
2074
2051
|
type: Injectable,
|
|
2075
2052
|
args: [{ providedIn: 'root' }]
|
|
2076
2053
|
}], ctorParameters: () => [] });
|
|
@@ -2295,10 +2272,10 @@ class CommandService {
|
|
|
2295
2272
|
const note = availability && !availability.ok ? `\n\nCurrently unavailable — ${availability.reason}` : '';
|
|
2296
2273
|
return { success: true, message: def.usage + note, timestamp: new Date(), isHelp: true };
|
|
2297
2274
|
}
|
|
2298
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2299
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
2275
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2276
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandService, providedIn: 'root' }); }
|
|
2300
2277
|
}
|
|
2301
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandService, decorators: [{
|
|
2302
2279
|
type: Injectable,
|
|
2303
2280
|
args: [{ providedIn: 'root' }]
|
|
2304
2281
|
}], ctorParameters: () => [] });
|
|
@@ -2328,10 +2305,10 @@ class StatusBar {
|
|
|
2328
2305
|
this.#commandService.execute('faq');
|
|
2329
2306
|
this.#focusService.requestFocus();
|
|
2330
2307
|
}
|
|
2331
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2332
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2308
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: StatusBar, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2309
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: StatusBar, isStandalone: true, selector: "shell-status-bar", ngImport: i0, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}.faq-button{margin-left:auto;background:none;border:1px solid var(--color-surface-border);border-radius:50%;width:22px;height:22px;font-size:.85rem;font-weight:600;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}.faq-button:hover{opacity:.8}\n"], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2333
2310
|
}
|
|
2334
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2311
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: StatusBar, decorators: [{
|
|
2335
2312
|
type: Component,
|
|
2336
2313
|
args: [{ selector: 'shell-status-bar', changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"status-bar\">\n <div class=\"status-item\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n", styles: [".status-bar{display:flex;align-items:center;gap:24px;padding:0 16px;height:100%;background-color:var(--color-surface);border-bottom:1px solid var(--color-surface-border);font-size:.8rem}.status-item{display:flex;align-items:baseline;gap:6px}.status-label{font-weight:500;text-transform:uppercase;letter-spacing:.05em;font-size:.7rem}.logout-link{cursor:pointer;text-decoration:underline}.logout-link:hover{opacity:.8}.faq-button{margin-left:auto;background:none;border:1px solid var(--color-surface-border);border-radius:50%;width:22px;height:22px;font-size:.85rem;font-weight:600;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0}.faq-button:hover{opacity:.8}\n"] }]
|
|
2337
2314
|
}] });
|
|
@@ -2377,10 +2354,10 @@ class SideMenu {
|
|
|
2377
2354
|
toggleTerminal() {
|
|
2378
2355
|
this.#terminalVisibility.toggle();
|
|
2379
2356
|
}
|
|
2380
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2381
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SideMenu, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2358
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: SideMenu, isStandalone: true, selector: "shell-side-menu", ngImport: i0, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n @if (isEnabled(item)) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n } @else {\n <!-- No routerLink: the item is inert. Pointer events stay live (see the\n .disabled rule) so the tooltip still fires \u2014 it carries the only\n explanation the user gets. -->\n <span\n class=\"menu-item disabled\"\n [matTooltip]=\"disabledReasonFor(item)\"\n matTooltipPosition=\"right\"\n aria-disabled=\"true\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </span>\n }\n }\n <div class=\"menu-spacer\"></div>\n <button\n class=\"menu-item terminal-toggle\"\n type=\"button\"\n [class.active]=\"terminalVisible()\"\n [matTooltip]=\"terminalVisible() ? 'Hide command console' : 'Show command console'\"\n matTooltipPosition=\"right\"\n [attr.aria-pressed]=\"terminalVisible()\"\n (click)=\"toggleTerminal()\"\n >\n <mat-icon>terminal</mat-icon>\n </button>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-item.active,.menu-item.active:hover{background-color:var(--color-interactive, #00e5ff);color:var(--color-surface-dark, #0d1117)}.menu-item.disabled{opacity:.25;cursor:not-allowed}.menu-item.disabled:hover{background-color:transparent;color:var(--color-secondary-info)}.menu-spacer{flex:1}.menu-item.terminal-toggle{border:none;background:none;padding:0;cursor:pointer;margin-bottom:4px}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2382
2359
|
}
|
|
2383
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2360
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: SideMenu, decorators: [{
|
|
2384
2361
|
type: Component,
|
|
2385
2362
|
args: [{ selector: 'shell-side-menu', imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<nav class=\"side-menu\">\n @for (item of menuItems(); track item.route) {\n @if (isEnabled(item)) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </a>\n } @else {\n <!-- No routerLink: the item is inert. Pointer events stay live (see the\n .disabled rule) so the tooltip still fires \u2014 it carries the only\n explanation the user gets. -->\n <span\n class=\"menu-item disabled\"\n [matTooltip]=\"disabledReasonFor(item)\"\n matTooltipPosition=\"right\"\n aria-disabled=\"true\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n </span>\n }\n }\n <div class=\"menu-spacer\"></div>\n <button\n class=\"menu-item terminal-toggle\"\n type=\"button\"\n [class.active]=\"terminalVisible()\"\n [matTooltip]=\"terminalVisible() ? 'Hide command console' : 'Show command console'\"\n matTooltipPosition=\"right\"\n [attr.aria-pressed]=\"terminalVisible()\"\n (click)=\"toggleTerminal()\"\n >\n <mat-icon>terminal</mat-icon>\n </button>\n @if (hasShortcuts()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n", styles: [".side-menu{display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px;height:100%;background-color:var(--color-surface);border-right:1px solid var(--color-surface-border)}.menu-item{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--color-secondary-info);text-decoration:none;transition:background-color .15s,color .15s}.menu-item:hover{background-color:var(--color-surface-light);color:var(--color-interactive)}.menu-item.active,.menu-item.active:hover{background-color:var(--color-interactive, #00e5ff);color:var(--color-surface-dark, #0d1117)}.menu-item.disabled{opacity:.25;cursor:not-allowed}.menu-item.disabled:hover{background-color:transparent;color:var(--color-secondary-info)}.menu-spacer{flex:1}.menu-item.terminal-toggle{border:none;background:none;padding:0;cursor:pointer;margin-bottom:4px}.help-button{margin-bottom:8px;padding:4px 6px;border:1px solid var(--color-surface-border);border-radius:6px;background:none;font-size:.7rem;font-family:Roboto Mono,monospace;cursor:pointer;color:var(--color-interactive);transition:background-color .15s}.help-button:hover{background-color:var(--color-surface-light)}.help-modifier{opacity:.6}.help-key{font-weight:700}\n"] }]
|
|
2386
2363
|
}] });
|
|
@@ -2405,10 +2382,10 @@ class MainContent {
|
|
|
2405
2382
|
closeShortcutHelp() {
|
|
2406
2383
|
this.#shortcutService.helpVisible.set(false);
|
|
2407
2384
|
}
|
|
2408
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2409
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2385
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: MainContent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2386
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: MainContent, isStandalone: true, selector: "shell-main-content", ngImport: i0, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2410
2387
|
}
|
|
2411
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2388
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: MainContent, decorators: [{
|
|
2412
2389
|
type: Component,
|
|
2413
2390
|
args: [{ selector: 'shell-main-content', imports: [RouterOutlet, MatProgressSpinnerModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n", styles: [".main-content{position:relative;height:100%;overflow:hidden}.content-area{height:100%;overflow-y:auto;padding:16px}.shortcut-overlay{position:absolute;inset:0;z-index:15;display:flex;align-items:center;justify-content:center;background-color:#0a0e1480}.shortcut-panel{background-color:var(--color-terminal-bg);border:1px solid var(--color-surface-border);border-radius:6px;padding:14px 18px;font-size:.8rem;box-shadow:0 4px 16px #00000080;min-width:220px}.shortcut-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;font-weight:500}.shortcut-row{display:flex;align-items:center;gap:10px;padding:3px 0}.shortcut-row.shortcut-dismiss{margin-top:6px;border-top:1px solid var(--color-surface-border);padding-top:8px}.shortcut-key{font-family:Roboto Mono,monospace;font-size:.75rem;background-color:#ffffff14;border:1px solid var(--color-surface-border);border-radius:3px;padding:1px 6px;min-width:70px;text-align:center}.shortcut-desc{font-size:.78rem}.thinking-overlay{position:absolute;inset:0;z-index:20;background-color:#0a0e14b3;display:flex;align-items:center;justify-content:center;pointer-events:all;cursor:wait}\n"] }]
|
|
2414
2391
|
}] });
|
|
@@ -2506,10 +2483,10 @@ class CommandTerminal {
|
|
|
2506
2483
|
focusInput() {
|
|
2507
2484
|
this.inputEl()?.nativeElement.focus();
|
|
2508
2485
|
}
|
|
2509
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2510
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2486
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandTerminal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2487
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2511
2488
|
}
|
|
2512
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandTerminal, decorators: [{
|
|
2513
2490
|
type: Component,
|
|
2514
2491
|
args: [{ selector: 'shell-command-terminal', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}\n"] }]
|
|
2515
2492
|
}], ctorParameters: () => [], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['terminalInput', { isSignal: true }] }] } });
|
|
@@ -2564,10 +2541,10 @@ class Shell {
|
|
|
2564
2541
|
document.addEventListener('mousemove', this.#onMouseMove);
|
|
2565
2542
|
document.addEventListener('mouseup', this.#onMouseUp);
|
|
2566
2543
|
}
|
|
2567
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2568
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2544
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Shell, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2545
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Shell, isStandalone: true, selector: "shell-root", ngImport: i0, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\" [class.terminal-hidden]=\"!terminalVisible()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n @if (terminalVisible()) {\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n }\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">\u2715</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words \u2014 e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".shell{position:relative;display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell.terminal-hidden{grid-template-rows:48px 1fr 0 0}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-main.full-width{grid-column:1 / -1}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}.help-backdrop{position:absolute;inset:0;z-index:100;background-color:#000000a6;display:flex;align-items:center;justify-content:center}.help-panel{background-color:var(--color-surface, #161b22);border:2px solid var(--color-interactive, #00e5ff);border-radius:4px;width:70%;max-width:820px;max-height:75vh;display:flex;flex-direction:column;font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.help-panel-header{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:var(--color-surface-light, #21262d);border-bottom:1px solid var(--color-interactive, #00e5ff);border-radius:2px 2px 0 0;flex-shrink:0}.help-panel-title{color:var(--color-interactive, #00e5ff);font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:.75rem}.help-panel-close{background:none;border:1px solid var(--color-surface-border, #30363d);color:var(--color-secondary-info, #9e9e9e);cursor:pointer;padding:2px 8px;font-size:.9rem;line-height:1.4;border-radius:3px;transition:color .15s ease,border-color .15s ease}.help-panel-close:hover{color:var(--color-text-primary, #ffffff);border-color:var(--color-interactive, #00e5ff)}.help-panel-content{flex:1;overflow-y:auto;padding:16px 20px;color:var(--color-text-primary, #ffffff);white-space:pre-wrap;line-height:1.7}.help-panel-footer{padding:6px 16px;background-color:var(--color-surface-light, #21262d);border-top:1px solid var(--color-surface-border, #30363d);border-radius:0 0 2px 2px;color:var(--color-secondary-info, #9e9e9e);font-size:.75rem;flex-shrink:0;display:flex;flex-direction:column;gap:2px}.help-panel-footer-dismiss{opacity:.6}\n"], dependencies: [{ kind: "component", type: StatusBar, selector: "shell-status-bar" }, { kind: "component", type: SideMenu, selector: "shell-side-menu" }, { kind: "component", type: MainContent, selector: "shell-main-content" }, { kind: "component", type: CommandTerminal, selector: "shell-command-terminal" }, { kind: "component", type: FaqModal, selector: "faq-modal" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2569
2546
|
}
|
|
2570
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2547
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Shell, decorators: [{
|
|
2571
2548
|
type: Component,
|
|
2572
2549
|
args: [{ selector: 'shell-root', imports: [StatusBar, SideMenu, MainContent, CommandTerminal, FaqModal], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\" [class.terminal-hidden]=\"!terminalVisible()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n @if (terminalVisible()) {\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" />\n }\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">\u2715</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words \u2014 e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".shell{position:relative;display:grid;grid-template-areas:\"status status\" \"menu main\" \"resize resize\" \"terminal terminal\";grid-template-columns:56px 1fr;grid-template-rows:48px 1fr 4px var(--terminal-height, 160px);height:100vh;width:100vw;overflow:hidden;background-color:var(--color-surface-dark)}.shell.terminal-hidden{grid-template-rows:48px 1fr 0 0}.shell-status{grid-area:status}.shell-menu{grid-area:menu}.shell-main{grid-area:main;overflow:hidden}.shell-main.full-width{grid-column:1 / -1}.shell-resize{grid-area:resize;cursor:row-resize;background-color:var(--color-surface-border);transition:background-color .15s ease}.shell-resize:hover,.shell-resize.dragging{background-color:var(--color-interactive)}.shell-terminal{grid-area:terminal}.shell.is-dragging{user-select:none;-webkit-user-select:none}.disabled-zone{pointer-events:none;opacity:.4;transition:opacity .2s ease}.help-backdrop{position:absolute;inset:0;z-index:100;background-color:#000000a6;display:flex;align-items:center;justify-content:center}.help-panel{background-color:var(--color-surface, #161b22);border:2px solid var(--color-interactive, #00e5ff);border-radius:4px;width:70%;max-width:820px;max-height:75vh;display:flex;flex-direction:column;font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.help-panel-header{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;background-color:var(--color-surface-light, #21262d);border-bottom:1px solid var(--color-interactive, #00e5ff);border-radius:2px 2px 0 0;flex-shrink:0}.help-panel-title{color:var(--color-interactive, #00e5ff);font-weight:700;letter-spacing:.05em;text-transform:uppercase;font-size:.75rem}.help-panel-close{background:none;border:1px solid var(--color-surface-border, #30363d);color:var(--color-secondary-info, #9e9e9e);cursor:pointer;padding:2px 8px;font-size:.9rem;line-height:1.4;border-radius:3px;transition:color .15s ease,border-color .15s ease}.help-panel-close:hover{color:var(--color-text-primary, #ffffff);border-color:var(--color-interactive, #00e5ff)}.help-panel-content{flex:1;overflow-y:auto;padding:16px 20px;color:var(--color-text-primary, #ffffff);white-space:pre-wrap;line-height:1.7}.help-panel-footer{padding:6px 16px;background-color:var(--color-surface-light, #21262d);border-top:1px solid var(--color-surface-border, #30363d);border-radius:0 0 2px 2px;color:var(--color-secondary-info, #9e9e9e);font-size:.75rem;flex-shrink:0;display:flex;flex-direction:column;gap:2px}.help-panel-footer-dismiss{opacity:.6}\n"] }]
|
|
2573
2550
|
}] });
|
|
@@ -2666,10 +2643,10 @@ class Login {
|
|
|
2666
2643
|
this.submitted = false;
|
|
2667
2644
|
});
|
|
2668
2645
|
}
|
|
2669
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2670
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2646
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Login, deps: [{ token: AuthenticationService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2647
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Login, isStandalone: true, selector: "shell-login", ngImport: i0, template: "@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <mat-checkbox\n class=\"login-takeover\"\n name=\"takeover\"\n [checked]=\"takeover()\"\n (change)=\"takeover.set($event.checked)\"\n [disabled]=\"submitted\"\n >\n Takeover session if logged in elsewhere\n </mat-checkbox>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n @for (session of sessions; track $index) {\n <p class=\"text-secondary-info\">\n Already logged in from <strong>{{ session.appContext }}</strong>\n since {{ session.startEpoch | date:'short' }}.\n </p>\n }\n <p class=\"text-secondary-info\">Log in here and end that session?</p>\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n <button mat-flat-button type=\"button\" (click)=\"onTakeOver()\">Take Over</button>\n </div>\n </div>\n }\n</div>\n", styles: [".login-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center}.login-header{margin-bottom:32px}.login-header h2{font-size:1.5rem;font-weight:300;margin-bottom:8px}.login-form{display:flex;flex-direction:column;align-items:center;gap:8px;width:320px}.login-field{width:100%;text-align:left}.login-takeover{align-self:flex-start;margin-top:4px}.login-button{margin-top:8px;width:100%}.login-errors{margin-top:16px;max-width:320px}.login-conflict{margin-top:16px;max-width:320px;padding:12px 16px;border-radius:4px;background-color:var(--color-surface-light);font-size:.85rem;text-align:left}.login-conflict p{margin:0 0 8px}.login-conflict-actions{display:flex;gap:8px;margin-top:12px;justify-content:flex-end}.login-error{padding:8px 12px;margin-bottom:4px;font-size:.85rem;border-radius:4px;background-color:var(--color-surface-light)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.CdkAutofill, selector: "[cdkAutofill]", outputs: ["cdkAutofill"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RegexValidatorDirective, selector: "[regexValidator]", inputs: ["regex"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2671
2648
|
}
|
|
2672
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Login, decorators: [{
|
|
2673
2650
|
type: Component,
|
|
2674
2651
|
args: [{ selector: 'shell-login', changeDetection: ChangeDetectionStrategy.Eager, imports: [
|
|
2675
2652
|
FormsModule,
|
|
@@ -2691,8 +2668,8 @@ class ConfirmDialog {
|
|
|
2691
2668
|
this.data = inject(MAT_DIALOG_DATA);
|
|
2692
2669
|
this.dialogRef = inject((MatDialogRef));
|
|
2693
2670
|
}
|
|
2694
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2695
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
2671
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2672
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: ConfirmDialog, isStandalone: true, selector: "shell-confirm-dialog", ngImport: i0, template: `
|
|
2696
2673
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
|
2697
2674
|
<mat-dialog-content>
|
|
2698
2675
|
<p>{{ data.message }}</p>
|
|
@@ -2706,7 +2683,7 @@ class ConfirmDialog {
|
|
|
2706
2683
|
</mat-dialog-actions>
|
|
2707
2684
|
`, isInline: true, styles: [":host{display:block}.warning-message{color:var(--color-warning);margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2708
2685
|
}
|
|
2709
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2686
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: ConfirmDialog, decorators: [{
|
|
2710
2687
|
type: Component,
|
|
2711
2688
|
args: [{ selector: 'shell-confirm-dialog', imports: [MatDialogModule, MatButtonModule], template: `
|
|
2712
2689
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|