@newheap/platform-common 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -253,10 +253,10 @@ class NhTwoFactorTranslationMerger {
253
253
  const merged = mergeTrees(bundleRoot, isTree(existing) ? existing : {});
254
254
  this.translate?.setTranslation(language, { [rootKey]: merged }, true);
255
255
  }
256
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorTranslationMerger, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
257
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorTranslationMerger, providedIn: 'root' }); }
256
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorTranslationMerger, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
257
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorTranslationMerger, providedIn: 'root' }); }
258
258
  }
259
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorTranslationMerger, decorators: [{
259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorTranslationMerger, decorators: [{
260
260
  type: Injectable,
261
261
  args: [{ providedIn: 'root' }]
262
262
  }] });
@@ -393,10 +393,10 @@ class NhTwoFactorChallengeComponent {
393
393
  ?? methods[0]
394
394
  ?? NhTwoFactorMethods.authenticator;
395
395
  }
396
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorChallengeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
397
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: NhTwoFactorChallengeComponent, isStandalone: true, selector: "nh-two-factor-challenge", inputs: { challenge: { classPropertyName: "challenge", publicName: "challenge", isSignal: true, isRequired: true, transformFunction: null }, allowRememberDevice: { classPropertyName: "allowRememberDevice", publicName: "allowRememberDevice", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { authenticated: "authenticated", expired: "expired", cancelled: "cancelled" }, viewQueries: [{ propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); verify()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.challenge-title' | translate }}</h2>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @if (method() === 'email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n @if (usesCode()) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [attr.inputmode]=\"numericCode() ? 'numeric' : 'text'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-verify-instructions' | translate }}</p>\n }\n\n @if (offerRememberDevice()) {\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"rememberDevice()\" [disabled]=\"busy()\" (change)=\"rememberDevice.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.remember-device' | translate }}</span>\n </label>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n @if (busy()) {\n {{ 'nh-two-factor.ui.verifying' | translate }}\n } @else {\n {{ (usesCode() ? 'nh-two-factor.ui.verify' : 'nh-two-factor.ui.use-passkey') | translate }}\n }\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n</form>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
396
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorChallengeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
397
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: NhTwoFactorChallengeComponent, isStandalone: true, selector: "nh-two-factor-challenge", inputs: { challenge: { classPropertyName: "challenge", publicName: "challenge", isSignal: true, isRequired: true, transformFunction: null }, allowRememberDevice: { classPropertyName: "allowRememberDevice", publicName: "allowRememberDevice", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { authenticated: "authenticated", expired: "expired", cancelled: "cancelled" }, viewQueries: [{ propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); verify()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.challenge-title' | translate }}</h2>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @if (method() === 'email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n @if (usesCode()) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [attr.inputmode]=\"numericCode() ? 'numeric' : 'text'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-verify-instructions' | translate }}</p>\n }\n\n @if (offerRememberDevice()) {\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"rememberDevice()\" [disabled]=\"busy()\" (change)=\"rememberDevice.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.remember-device' | translate }}</span>\n </label>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n @if (busy()) {\n {{ 'nh-two-factor.ui.verifying' | translate }}\n } @else {\n {{ (usesCode() ? 'nh-two-factor.ui.verify' : 'nh-two-factor.ui.use-passkey') | translate }}\n }\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n</form>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
398
398
  }
399
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorChallengeComponent, decorators: [{
399
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorChallengeComponent, decorators: [{
400
400
  type: Component,
401
401
  args: [{ selector: 'nh-two-factor-challenge', standalone: true, imports: [TranslatePipe, DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); verify()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.challenge-title' | translate }}</h2>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @if (method() === 'email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n @if (usesCode()) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [attr.inputmode]=\"numericCode() ? 'numeric' : 'text'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-verify-instructions' | translate }}</p>\n }\n\n @if (offerRememberDevice()) {\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"rememberDevice()\" [disabled]=\"busy()\" (change)=\"rememberDevice.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.remember-device' | translate }}</span>\n </label>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n @if (busy()) {\n {{ 'nh-two-factor.ui.verifying' | translate }}\n } @else {\n {{ (usesCode() ? 'nh-two-factor.ui.verify' : 'nh-two-factor.ui.use-passkey') | translate }}\n }\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n</form>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
402
402
  }], ctorParameters: () => [], propDecorators: { codeInput: [{ type: i0.ViewChild, args: ['codeInput', { isSignal: true }] }], challenge: [{ type: i0.Input, args: [{ isSignal: true, alias: "challenge", required: true }] }], allowRememberDevice: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowRememberDevice", required: false }] }], authenticated: [{ type: i0.Output, args: ["authenticated"] }], expired: [{ type: i0.Output, args: ["expired"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
@@ -436,10 +436,10 @@ class NhTwoFactorRecoveryCodesComponent {
436
436
  link.click();
437
437
  URL.revokeObjectURL(url);
438
438
  }
439
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorRecoveryCodesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
440
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: NhTwoFactorRecoveryCodesComponent, isStandalone: true, selector: "nh-two-factor-recovery-codes", inputs: { codes: { classPropertyName: "codes", publicName: "codes", isSignal: true, isRequired: true, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { acknowledged: "acknowledged" }, ngImport: i0, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.recovery-codes-title' | translate }}</h3>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.recovery-codes-instructions' | translate }}</p>\n\n <ul class=\"nh-two-factor__codes\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (code of codes(); track code) {\n <li>{{ code }}</li>\n }\n </ul>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"copy()\">\n {{ (copied() ? 'nh-two-factor.ui.copied' : 'nh-two-factor.ui.copy') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"download()\">\n {{ 'nh-two-factor.ui.download' | translate }}\n </button>\n </div>\n\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"saved()\" (change)=\"saved.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.recovery-codes-saved' | translate }}</span>\n </label>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"!saved()\" (click)=\"acknowledged.emit()\">\n {{ 'nh-two-factor.ui.continue' | translate }}\n </button>\n </div>\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
439
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorRecoveryCodesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
440
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: NhTwoFactorRecoveryCodesComponent, isStandalone: true, selector: "nh-two-factor-recovery-codes", inputs: { codes: { classPropertyName: "codes", publicName: "codes", isSignal: true, isRequired: true, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { acknowledged: "acknowledged" }, ngImport: i0, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.recovery-codes-title' | translate }}</h3>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.recovery-codes-instructions' | translate }}</p>\n\n <ul class=\"nh-two-factor__codes\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (code of codes(); track code) {\n <li>{{ code }}</li>\n }\n </ul>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"copy()\">\n {{ (copied() ? 'nh-two-factor.ui.copied' : 'nh-two-factor.ui.copy') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"download()\">\n {{ 'nh-two-factor.ui.download' | translate }}\n </button>\n </div>\n\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"saved()\" (change)=\"saved.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.recovery-codes-saved' | translate }}</span>\n </label>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"!saved()\" (click)=\"acknowledged.emit()\">\n {{ 'nh-two-factor.ui.continue' | translate }}\n </button>\n </div>\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
441
441
  }
442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorRecoveryCodesComponent, decorators: [{
442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorRecoveryCodesComponent, decorators: [{
443
443
  type: Component,
444
444
  args: [{ selector: 'nh-two-factor-recovery-codes', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.recovery-codes-title' | translate }}</h3>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.recovery-codes-instructions' | translate }}</p>\n\n <ul class=\"nh-two-factor__codes\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (code of codes(); track code) {\n <li>{{ code }}</li>\n }\n </ul>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"copy()\">\n {{ (copied() ? 'nh-two-factor.ui.copied' : 'nh-two-factor.ui.copy') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"download()\">\n {{ 'nh-two-factor.ui.download' | translate }}\n </button>\n </div>\n\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"saved()\" (change)=\"saved.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.recovery-codes-saved' | translate }}</span>\n </label>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"!saved()\" (click)=\"acknowledged.emit()\">\n {{ 'nh-two-factor.ui.continue' | translate }}\n </button>\n </div>\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
445
445
  }], ctorParameters: () => [], propDecorators: { codes: [{ type: i0.Input, args: [{ isSignal: true, alias: "codes", required: true }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], acknowledged: [{ type: i0.Output, args: ["acknowledged"] }] } });
@@ -561,10 +561,10 @@ class NhTwoFactorEnrollmentComponent {
561
561
  focusCode() {
562
562
  afterNextRender(() => this.codeInput()?.nativeElement.focus(), { injector: this.injector });
563
563
  }
564
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorEnrollmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
565
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: NhTwoFactorEnrollmentComponent, isStandalone: true, selector: "nh-two-factor-enrollment", inputs: { enrollment: { classPropertyName: "enrollment", publicName: "enrollment", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completed: "completed", expired: "expired", cancelled: "cancelled" }, viewQueries: [{ propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (result(); as completedResult) {\n <nh-two-factor-recovery-codes [codes]=\"completedResult.recoveryCodes ?? []\" (acknowledged)=\"finish()\" />\n} @else {\n <form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); confirm()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.enrollment-title' | translate }}</h2>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.enrollment-instructions' | translate }}</p>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @switch (method()) {\n @case ('authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n } @else if (busy()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n }\n @case ('email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n @case ('passkey') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-instructions' | translate }}</p>\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-passkey-name'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-passkey-name'\"\n [value]=\"passkeyName()\"\n [disabled]=\"busy()\"\n (input)=\"passkeyName.set(value($event))\" />\n </div>\n }\n }\n\n @if (method() !== 'passkey' && (method() !== 'authenticator' || setup())) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ (method() === 'passkey' ? 'nh-two-factor.ui.create-passkey' : 'nh-two-factor.ui.confirm') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: NhTwoFactorRecoveryCodesComponent, selector: "nh-two-factor-recovery-codes", inputs: ["codes", "fileName"], outputs: ["acknowledged"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
564
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorEnrollmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
565
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: NhTwoFactorEnrollmentComponent, isStandalone: true, selector: "nh-two-factor-enrollment", inputs: { enrollment: { classPropertyName: "enrollment", publicName: "enrollment", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completed: "completed", expired: "expired", cancelled: "cancelled" }, viewQueries: [{ propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (result(); as completedResult) {\n <nh-two-factor-recovery-codes [codes]=\"completedResult.recoveryCodes ?? []\" (acknowledged)=\"finish()\" />\n} @else {\n <form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); confirm()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.enrollment-title' | translate }}</h2>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.enrollment-instructions' | translate }}</p>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @switch (method()) {\n @case ('authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n } @else if (busy()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n }\n @case ('email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n @case ('passkey') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-instructions' | translate }}</p>\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-passkey-name'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-passkey-name'\"\n [value]=\"passkeyName()\"\n [disabled]=\"busy()\"\n (input)=\"passkeyName.set(value($event))\" />\n </div>\n }\n }\n\n @if (method() !== 'passkey' && (method() !== 'authenticator' || setup())) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ (method() === 'passkey' ? 'nh-two-factor.ui.create-passkey' : 'nh-two-factor.ui.confirm') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: NhTwoFactorRecoveryCodesComponent, selector: "nh-two-factor-recovery-codes", inputs: ["codes", "fileName"], outputs: ["acknowledged"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
566
566
  }
567
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorEnrollmentComponent, decorators: [{
567
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorEnrollmentComponent, decorators: [{
568
568
  type: Component,
569
569
  args: [{ selector: 'nh-two-factor-enrollment', standalone: true, imports: [TranslatePipe, DatePipe, NhTwoFactorRecoveryCodesComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (result(); as completedResult) {\n <nh-two-factor-recovery-codes [codes]=\"completedResult.recoveryCodes ?? []\" (acknowledged)=\"finish()\" />\n} @else {\n <form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); confirm()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.enrollment-title' | translate }}</h2>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.enrollment-instructions' | translate }}</p>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @switch (method()) {\n @case ('authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n } @else if (busy()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n }\n @case ('email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n @case ('passkey') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-instructions' | translate }}</p>\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-passkey-name'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-passkey-name'\"\n [value]=\"passkeyName()\"\n [disabled]=\"busy()\"\n (input)=\"passkeyName.set(value($event))\" />\n </div>\n }\n }\n\n @if (method() !== 'passkey' && (method() !== 'authenticator' || setup())) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ (method() === 'passkey' ? 'nh-two-factor.ui.create-passkey' : 'nh-two-factor.ui.confirm') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
570
570
  }], ctorParameters: () => [], propDecorators: { codeInput: [{ type: i0.ViewChild, args: ['codeInput', { isSignal: true }] }], enrollment: [{ type: i0.Input, args: [{ isSignal: true, alias: "enrollment", required: true }] }], completed: [{ type: i0.Output, args: ["completed"] }], expired: [{ type: i0.Output, args: ["expired"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
@@ -813,10 +813,10 @@ class NhTwoFactorSettingsComponent {
813
813
  isAvailable(method) {
814
814
  return this.status()?.availableMethods.includes(method) === true;
815
815
  }
816
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
817
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: NhTwoFactorSettingsComponent, isStandalone: true, selector: "nh-two-factor-settings", inputs: { showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, viewQueries: [{ propertyName: "reauthenticationInput", first: true, predicate: ["reauthenticationInput"], descendants: true, isSignal: true }, { propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <div class=\"nh-two-factor__status\">\n <h2 class=\"nh-two-factor__title\" [class.visually-hidden]=\"!showTitle()\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.settings-title' | translate }}</h2>\n @if (status(); as current) {\n <span class=\"nh-two-factor__badge\" [class.nh-two-factor__badge--on]=\"current.enabled\">\n {{ (current.enabled ? 'nh-two-factor.ui.status-enabled' : 'nh-two-factor.ui.status-disabled') | translate }}\n </span>\n @if (current.required) {\n <span class=\"nh-two-factor__badge\">{{ 'nh-two-factor.ui.status-required' | translate }}</span>\n }\n }\n </div>\n\n @if (loading() && !status()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n\n <div role=\"status\">\n @if (noticeKey(); as notice) {\n <p class=\"nh-two-factor__notice\">{{ notice | translate }}</p>\n }\n </div>\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n @if (pendingAction()) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-reauthentication-title'\" (submit)=\"$event.preventDefault(); confirmReauthentication()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-reauthentication-title'\">{{ 'nh-two-factor.ui.reauthentication-title' | translate }}</h3>\n\n @if (reauthenticationMethods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.reauthentication-method' | translate }}</legend>\n @for (option of reauthenticationMethods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-reauthentication-method'\"\n [value]=\"option\"\n [checked]=\"reauthenticationMethod() === option\"\n (change)=\"reauthenticationMethod.set(option); reauthenticationSecret.set('')\" />\n <span>{{ (option === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.method.' + option) | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-reauthentication'\">\n {{ (reauthenticationMethod() === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.code-label.' + reauthenticationMethod()) | translate }}\n </label>\n <input\n #reauthenticationInput\n class=\"nh-two-factor__input\"\n [id]=\"id + '-reauthentication'\"\n [type]=\"reauthenticationMethod() === 'password' ? 'password' : 'text'\"\n [attr.autocomplete]=\"reauthenticationMethod() === 'password' ? 'current-password' : 'one-time-code'\"\n [value]=\"reauthenticationSecret()\"\n [disabled]=\"busy()\"\n (input)=\"reauthenticationSecret.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelReauthentication()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (recoveryCodes(); as codes) {\n <div class=\"nh-two-factor__section\">\n <nh-two-factor-recovery-codes [codes]=\"codes\" (acknowledged)=\"recoveryCodes.set(null)\" />\n </div>\n }\n\n @if (setupPanel(); as panel) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-setup-title'\" (submit)=\"$event.preventDefault(); confirmSetup()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-setup-title'\">{{ 'nh-two-factor.ui.method.' + panel | translate }}</h3>\n\n @if (panel === 'authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n }\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + panel | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n (input)=\"code.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n @if (panel === 'email') {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"resendEmailCode()\">\n {{ 'nh-two-factor.ui.resend-email-code' | translate }}\n </button>\n }\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"closeSetup()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (status(); as current) {\n @if (!setupPanel() && !pendingAction()) {\n <div class=\"nh-two-factor__actions\">\n @if (authenticatorAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'authenticator' })\">\n {{ (hasAuthenticator() ? 'nh-two-factor.ui.change-authenticator' : 'nh-two-factor.ui.set-up-authenticator') | translate }}\n </button>\n }\n @if (emailAvailable() && !hasEmail()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'email' })\">\n {{ 'nh-two-factor.ui.set-up-email' | translate }}\n </button>\n }\n </div>\n }\n\n @if (passkeysAvailable()) {\n <div class=\"nh-two-factor__section\">\n <h3 class=\"nh-two-factor__subtitle\">{{ 'nh-two-factor.ui.passkeys-title' | translate }}</h3>\n\n @if (passkeys().length === 0) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.no-passkeys' | translate }}</p>\n } @else {\n <ul class=\"nh-two-factor__list\">\n @for (passkey of passkeys(); track passkey.id) {\n <li class=\"nh-two-factor__item\">\n @if (renamingId() === passkey.id) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); saveRename(passkey)\">\n <label class=\"visually-hidden\" [for]=\"id + '-rename-' + $index\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n [id]=\"id + '-rename-' + $index\"\n [value]=\"renameValue()\"\n [disabled]=\"busy()\"\n (input)=\"renameValue.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.save' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelRename()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </form>\n } @else {\n <div>\n <p class=\"nh-two-factor__text\"><strong>{{ passkey.name }}</strong></p>\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.passkey-created' | translate: { date: (passkey.createdAt | date: 'mediumDate') } }}\n @if (passkey.isBackedUp) {\n \u00B7 {{ 'nh-two-factor.ui.passkey-synced' | translate }}\n }\n </p>\n </div>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"startRename(passkey)\">\n {{ 'nh-two-factor.ui.rename' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'remove-passkey', passkeyId: passkey.id })\">\n {{ 'nh-two-factor.ui.remove' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n\n @if (passkeySupported && !pendingAction()) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); request({ kind: 'add-passkey' })\">\n <label class=\"visually-hidden\" [for]=\"id + '-new-passkey'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-new-passkey'\"\n [attr.placeholder]=\"'nh-two-factor.ui.passkey-name' | translate\"\n [value]=\"newPasskeyName()\"\n [disabled]=\"busy()\"\n (input)=\"newPasskeyName.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.add-passkey' | translate }}\n </button>\n </form>\n }\n </div>\n }\n\n @if (current.enabled && !pendingAction()) {\n <div class=\"nh-two-factor__section\">\n @if (recoveryCodesAvailable()) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.recovery-codes-left' | translate: { count: current.recoveryCodesLeft } }}</p>\n }\n <div class=\"nh-two-factor__actions\">\n @if (recoveryCodesAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'recovery-codes' })\">\n {{ 'nh-two-factor.ui.regenerate-recovery-codes' | translate }}\n </button>\n }\n @if (current.rememberDeviceAvailable) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'forget-devices' })\">\n {{ 'nh-two-factor.ui.forget-devices' | translate }}\n </button>\n }\n @if (!required()) {\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'disable' })\">\n {{ 'nh-two-factor.ui.disable' | translate }}\n </button>\n }\n </div>\n </div>\n }\n }\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: NhTwoFactorRecoveryCodesComponent, selector: "nh-two-factor-recovery-codes", inputs: ["codes", "fileName"], outputs: ["acknowledged"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
816
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
817
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: NhTwoFactorSettingsComponent, isStandalone: true, selector: "nh-two-factor-settings", inputs: { showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, viewQueries: [{ propertyName: "reauthenticationInput", first: true, predicate: ["reauthenticationInput"], descendants: true, isSignal: true }, { propertyName: "codeInput", first: true, predicate: ["codeInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <div class=\"nh-two-factor__status\">\n <h2 class=\"nh-two-factor__title\" [class.visually-hidden]=\"!showTitle()\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.settings-title' | translate }}</h2>\n @if (status(); as current) {\n <span class=\"nh-two-factor__badge\" [class.nh-two-factor__badge--on]=\"current.enabled\">\n {{ (current.enabled ? 'nh-two-factor.ui.status-enabled' : 'nh-two-factor.ui.status-disabled') | translate }}\n </span>\n @if (current.required) {\n <span class=\"nh-two-factor__badge\">{{ 'nh-two-factor.ui.status-required' | translate }}</span>\n }\n }\n </div>\n\n @if (loading() && !status()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n\n <div role=\"status\">\n @if (noticeKey(); as notice) {\n <p class=\"nh-two-factor__notice\">{{ notice | translate }}</p>\n }\n </div>\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n @if (pendingAction()) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-reauthentication-title'\" (submit)=\"$event.preventDefault(); confirmReauthentication()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-reauthentication-title'\">{{ 'nh-two-factor.ui.reauthentication-title' | translate }}</h3>\n\n @if (reauthenticationMethods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.reauthentication-method' | translate }}</legend>\n @for (option of reauthenticationMethods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-reauthentication-method'\"\n [value]=\"option\"\n [checked]=\"reauthenticationMethod() === option\"\n (change)=\"reauthenticationMethod.set(option); reauthenticationSecret.set('')\" />\n <span>{{ (option === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.method.' + option) | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-reauthentication'\">\n {{ (reauthenticationMethod() === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.code-label.' + reauthenticationMethod()) | translate }}\n </label>\n <input\n #reauthenticationInput\n class=\"nh-two-factor__input\"\n [id]=\"id + '-reauthentication'\"\n [type]=\"reauthenticationMethod() === 'password' ? 'password' : 'text'\"\n [attr.autocomplete]=\"reauthenticationMethod() === 'password' ? 'current-password' : 'one-time-code'\"\n [value]=\"reauthenticationSecret()\"\n [disabled]=\"busy()\"\n (input)=\"reauthenticationSecret.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelReauthentication()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (recoveryCodes(); as codes) {\n <div class=\"nh-two-factor__section\">\n <nh-two-factor-recovery-codes [codes]=\"codes\" (acknowledged)=\"recoveryCodes.set(null)\" />\n </div>\n }\n\n @if (setupPanel(); as panel) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-setup-title'\" (submit)=\"$event.preventDefault(); confirmSetup()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-setup-title'\">{{ 'nh-two-factor.ui.method.' + panel | translate }}</h3>\n\n @if (panel === 'authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n }\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + panel | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n (input)=\"code.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n @if (panel === 'email') {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"resendEmailCode()\">\n {{ 'nh-two-factor.ui.resend-email-code' | translate }}\n </button>\n }\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"closeSetup()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (status(); as current) {\n @if (!setupPanel() && !pendingAction()) {\n <div class=\"nh-two-factor__actions\">\n @if (authenticatorAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'authenticator' })\">\n {{ (hasAuthenticator() ? 'nh-two-factor.ui.change-authenticator' : 'nh-two-factor.ui.set-up-authenticator') | translate }}\n </button>\n }\n @if (emailAvailable() && !hasEmail()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'email' })\">\n {{ 'nh-two-factor.ui.set-up-email' | translate }}\n </button>\n }\n </div>\n }\n\n @if (passkeysAvailable()) {\n <div class=\"nh-two-factor__section\">\n <h3 class=\"nh-two-factor__subtitle\">{{ 'nh-two-factor.ui.passkeys-title' | translate }}</h3>\n\n @if (passkeys().length === 0) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.no-passkeys' | translate }}</p>\n } @else {\n <ul class=\"nh-two-factor__list\">\n @for (passkey of passkeys(); track passkey.id) {\n <li class=\"nh-two-factor__item\">\n @if (renamingId() === passkey.id) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); saveRename(passkey)\">\n <label class=\"visually-hidden\" [for]=\"id + '-rename-' + $index\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n [id]=\"id + '-rename-' + $index\"\n [value]=\"renameValue()\"\n [disabled]=\"busy()\"\n (input)=\"renameValue.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.save' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelRename()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </form>\n } @else {\n <div>\n <p class=\"nh-two-factor__text\"><strong>{{ passkey.name }}</strong></p>\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.passkey-created' | translate: { date: (passkey.createdAt | date: 'mediumDate') } }}\n @if (passkey.isBackedUp) {\n \u00B7 {{ 'nh-two-factor.ui.passkey-synced' | translate }}\n }\n </p>\n </div>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"startRename(passkey)\">\n {{ 'nh-two-factor.ui.rename' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'remove-passkey', passkeyId: passkey.id })\">\n {{ 'nh-two-factor.ui.remove' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n\n @if (passkeySupported && !pendingAction()) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); request({ kind: 'add-passkey' })\">\n <label class=\"visually-hidden\" [for]=\"id + '-new-passkey'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-new-passkey'\"\n [attr.placeholder]=\"'nh-two-factor.ui.passkey-name' | translate\"\n [value]=\"newPasskeyName()\"\n [disabled]=\"busy()\"\n (input)=\"newPasskeyName.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.add-passkey' | translate }}\n </button>\n </form>\n }\n </div>\n }\n\n @if (current.enabled && !pendingAction()) {\n <div class=\"nh-two-factor__section\">\n @if (recoveryCodesAvailable()) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.recovery-codes-left' | translate: { count: current.recoveryCodesLeft } }}</p>\n }\n <div class=\"nh-two-factor__actions\">\n @if (recoveryCodesAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'recovery-codes' })\">\n {{ 'nh-two-factor.ui.regenerate-recovery-codes' | translate }}\n </button>\n }\n @if (current.rememberDeviceAvailable) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'forget-devices' })\">\n {{ 'nh-two-factor.ui.forget-devices' | translate }}\n </button>\n }\n @if (!required()) {\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'disable' })\">\n {{ 'nh-two-factor.ui.disable' | translate }}\n </button>\n }\n </div>\n </div>\n }\n }\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: NhTwoFactorRecoveryCodesComponent, selector: "nh-two-factor-recovery-codes", inputs: ["codes", "fileName"], outputs: ["acknowledged"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
818
818
  }
819
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhTwoFactorSettingsComponent, decorators: [{
819
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhTwoFactorSettingsComponent, decorators: [{
820
820
  type: Component,
821
821
  args: [{ selector: 'nh-two-factor-settings', standalone: true, imports: [TranslatePipe, DatePipe, NhTwoFactorRecoveryCodesComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <div class=\"nh-two-factor__status\">\n <h2 class=\"nh-two-factor__title\" [class.visually-hidden]=\"!showTitle()\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.settings-title' | translate }}</h2>\n @if (status(); as current) {\n <span class=\"nh-two-factor__badge\" [class.nh-two-factor__badge--on]=\"current.enabled\">\n {{ (current.enabled ? 'nh-two-factor.ui.status-enabled' : 'nh-two-factor.ui.status-disabled') | translate }}\n </span>\n @if (current.required) {\n <span class=\"nh-two-factor__badge\">{{ 'nh-two-factor.ui.status-required' | translate }}</span>\n }\n }\n </div>\n\n @if (loading() && !status()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n\n <div role=\"status\">\n @if (noticeKey(); as notice) {\n <p class=\"nh-two-factor__notice\">{{ notice | translate }}</p>\n }\n </div>\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n @if (pendingAction()) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-reauthentication-title'\" (submit)=\"$event.preventDefault(); confirmReauthentication()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-reauthentication-title'\">{{ 'nh-two-factor.ui.reauthentication-title' | translate }}</h3>\n\n @if (reauthenticationMethods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.reauthentication-method' | translate }}</legend>\n @for (option of reauthenticationMethods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-reauthentication-method'\"\n [value]=\"option\"\n [checked]=\"reauthenticationMethod() === option\"\n (change)=\"reauthenticationMethod.set(option); reauthenticationSecret.set('')\" />\n <span>{{ (option === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.method.' + option) | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-reauthentication'\">\n {{ (reauthenticationMethod() === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.code-label.' + reauthenticationMethod()) | translate }}\n </label>\n <input\n #reauthenticationInput\n class=\"nh-two-factor__input\"\n [id]=\"id + '-reauthentication'\"\n [type]=\"reauthenticationMethod() === 'password' ? 'password' : 'text'\"\n [attr.autocomplete]=\"reauthenticationMethod() === 'password' ? 'current-password' : 'one-time-code'\"\n [value]=\"reauthenticationSecret()\"\n [disabled]=\"busy()\"\n (input)=\"reauthenticationSecret.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelReauthentication()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (recoveryCodes(); as codes) {\n <div class=\"nh-two-factor__section\">\n <nh-two-factor-recovery-codes [codes]=\"codes\" (acknowledged)=\"recoveryCodes.set(null)\" />\n </div>\n }\n\n @if (setupPanel(); as panel) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-setup-title'\" (submit)=\"$event.preventDefault(); confirmSetup()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-setup-title'\">{{ 'nh-two-factor.ui.method.' + panel | translate }}</h3>\n\n @if (panel === 'authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n }\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + panel | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n (input)=\"code.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n @if (panel === 'email') {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"resendEmailCode()\">\n {{ 'nh-two-factor.ui.resend-email-code' | translate }}\n </button>\n }\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"closeSetup()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (status(); as current) {\n @if (!setupPanel() && !pendingAction()) {\n <div class=\"nh-two-factor__actions\">\n @if (authenticatorAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'authenticator' })\">\n {{ (hasAuthenticator() ? 'nh-two-factor.ui.change-authenticator' : 'nh-two-factor.ui.set-up-authenticator') | translate }}\n </button>\n }\n @if (emailAvailable() && !hasEmail()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'email' })\">\n {{ 'nh-two-factor.ui.set-up-email' | translate }}\n </button>\n }\n </div>\n }\n\n @if (passkeysAvailable()) {\n <div class=\"nh-two-factor__section\">\n <h3 class=\"nh-two-factor__subtitle\">{{ 'nh-two-factor.ui.passkeys-title' | translate }}</h3>\n\n @if (passkeys().length === 0) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.no-passkeys' | translate }}</p>\n } @else {\n <ul class=\"nh-two-factor__list\">\n @for (passkey of passkeys(); track passkey.id) {\n <li class=\"nh-two-factor__item\">\n @if (renamingId() === passkey.id) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); saveRename(passkey)\">\n <label class=\"visually-hidden\" [for]=\"id + '-rename-' + $index\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n [id]=\"id + '-rename-' + $index\"\n [value]=\"renameValue()\"\n [disabled]=\"busy()\"\n (input)=\"renameValue.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.save' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelRename()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </form>\n } @else {\n <div>\n <p class=\"nh-two-factor__text\"><strong>{{ passkey.name }}</strong></p>\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.passkey-created' | translate: { date: (passkey.createdAt | date: 'mediumDate') } }}\n @if (passkey.isBackedUp) {\n \u00B7 {{ 'nh-two-factor.ui.passkey-synced' | translate }}\n }\n </p>\n </div>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"startRename(passkey)\">\n {{ 'nh-two-factor.ui.rename' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'remove-passkey', passkeyId: passkey.id })\">\n {{ 'nh-two-factor.ui.remove' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n\n @if (passkeySupported && !pendingAction()) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); request({ kind: 'add-passkey' })\">\n <label class=\"visually-hidden\" [for]=\"id + '-new-passkey'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-new-passkey'\"\n [attr.placeholder]=\"'nh-two-factor.ui.passkey-name' | translate\"\n [value]=\"newPasskeyName()\"\n [disabled]=\"busy()\"\n (input)=\"newPasskeyName.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.add-passkey' | translate }}\n </button>\n </form>\n }\n </div>\n }\n\n @if (current.enabled && !pendingAction()) {\n <div class=\"nh-two-factor__section\">\n @if (recoveryCodesAvailable()) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.recovery-codes-left' | translate: { count: current.recoveryCodesLeft } }}</p>\n }\n <div class=\"nh-two-factor__actions\">\n @if (recoveryCodesAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'recovery-codes' })\">\n {{ 'nh-two-factor.ui.regenerate-recovery-codes' | translate }}\n </button>\n }\n @if (current.rememberDeviceAvailable) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'forget-devices' })\">\n {{ 'nh-two-factor.ui.forget-devices' | translate }}\n </button>\n }\n @if (!required()) {\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'disable' })\">\n {{ 'nh-two-factor.ui.disable' | translate }}\n </button>\n }\n </div>\n </div>\n }\n }\n</section>\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
822
822
  }], ctorParameters: () => [], propDecorators: { reauthenticationInput: [{ type: i0.ViewChild, args: ['reauthenticationInput', { isSignal: true }] }], codeInput: [{ type: i0.ViewChild, args: ['codeInput', { isSignal: true }] }], showTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTitle", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
@@ -862,10 +862,10 @@ class NhPasskeyLoginButtonComponent {
862
862
  }
863
863
  this.pending.emit(result.data);
864
864
  }
865
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhPasskeyLoginButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
866
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.28", type: NhPasskeyLoginButtonComponent, isStandalone: true, selector: "nh-passkey-login-button", inputs: { showErrors: { classPropertyName: "showErrors", publicName: "showErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { authenticated: "authenticated", pending: "pending", failed: "failed" }, ngImport: i0, template: "@if (supported) {\n <div class=\"nh-two-factor\">\n <div class=\"nh-two-factor__actions\">\n <button\n type=\"button\"\n class=\"nh-two-factor__button\"\n [disabled]=\"busy()\"\n [attr.aria-busy]=\"busy()\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (click)=\"signIn()\">\n {{ 'nh-two-factor.ui.sign-in-with-passkey' | translate }}\n </button>\n </div>\n\n @if (showErrors()) {\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
865
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhPasskeyLoginButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
866
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.33", type: NhPasskeyLoginButtonComponent, isStandalone: true, selector: "nh-passkey-login-button", inputs: { showErrors: { classPropertyName: "showErrors", publicName: "showErrors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { authenticated: "authenticated", pending: "pending", failed: "failed" }, ngImport: i0, template: "@if (supported) {\n <div class=\"nh-two-factor\">\n <div class=\"nh-two-factor__actions\">\n <button\n type=\"button\"\n class=\"nh-two-factor__button\"\n [disabled]=\"busy()\"\n [attr.aria-busy]=\"busy()\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (click)=\"signIn()\">\n {{ 'nh-two-factor.ui.sign-in-with-passkey' | translate }}\n </button>\n </div>\n\n @if (showErrors()) {\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
867
867
  }
868
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: NhPasskeyLoginButtonComponent, decorators: [{
868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.33", ngImport: i0, type: NhPasskeyLoginButtonComponent, decorators: [{
869
869
  type: Component,
870
870
  args: [{ selector: 'nh-passkey-login-button', standalone: true, imports: [TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (supported) {\n <div class=\"nh-two-factor\">\n <div class=\"nh-two-factor__actions\">\n <button\n type=\"button\"\n class=\"nh-two-factor__button\"\n [disabled]=\"busy()\"\n [attr.aria-busy]=\"busy()\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (click)=\"signIn()\">\n {{ 'nh-two-factor.ui.sign-in-with-passkey' | translate }}\n </button>\n </div>\n\n @if (showErrors()) {\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;min-width:0;color:var(--nh-color-text, #1f2933)}.nh-two-factor{display:flex;flex-direction:column;gap:1rem;min-width:0}.nh-two-factor__title{margin:0;font-size:1.125rem;font-weight:650}.nh-two-factor__subtitle{margin:0;font-size:1rem;font-weight:650}.nh-two-factor__text,.nh-two-factor__hint{margin:0;overflow-wrap:anywhere}.nh-two-factor__hint{color:var(--nh-color-muted, #52606d);font-size:.875rem}.nh-two-factor__notice{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__methods{display:flex;flex-wrap:wrap;gap:.5rem;min-width:0;margin:0;padding:0;border:0}.nh-two-factor__legend{width:100%;margin-bottom:.25rem;padding:0;font-weight:600}.nh-two-factor__method{position:relative}.nh-two-factor__method input{position:absolute;inset:0;opacity:0;cursor:pointer}.nh-two-factor__method span{display:inline-flex;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff)}.nh-two-factor__method input:checked+span{border-color:var(--nh-color-primary, #2563eb);box-shadow:inset 0 0 0 1px var(--nh-color-primary, #2563eb);font-weight:600}.nh-two-factor__method input:focus-visible+span{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__method input:disabled+span{opacity:.6}.nh-two-factor__field{display:flex;flex-direction:column;gap:.375rem;min-width:0}.nh-two-factor__field label{font-weight:600}.nh-two-factor__input{width:100%;max-width:20rem;padding:.5rem .75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-input-background, #fff);color:inherit;font:inherit}.nh-two-factor__input:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:1px}.nh-two-factor__input[aria-invalid=true]{border-color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__input--code{font-variant-numeric:tabular-nums;letter-spacing:.15em}.nh-two-factor__check{display:flex;align-items:center;gap:.5rem}.nh-two-factor__actions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__button{padding:.5rem 1rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem;background:var(--nh-color-surface, #fff);color:inherit;font:inherit;cursor:pointer}.nh-two-factor__button:focus-visible{outline:2px solid var(--nh-color-focus, #2563eb);outline-offset:2px}.nh-two-factor__button:disabled{opacity:.6;cursor:not-allowed}.nh-two-factor__button--primary{border-color:var(--nh-color-primary, #2563eb);background:var(--nh-color-primary, #2563eb);color:var(--nh-color-on-primary, #fff)}.nh-two-factor__button--danger{border-color:var(--nh-color-danger, #b91c1c);color:var(--nh-color-danger, #b91c1c)}.nh-two-factor__errors{margin:0;padding:.5rem .75rem;border-radius:.5rem;background:var(--nh-color-danger-background, #fdecec);color:var(--nh-color-danger, #b91c1c);list-style:none}.nh-two-factor__setup{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem}.nh-two-factor__qr{width:11rem;height:11rem;padding:.5rem;border-radius:.5rem;background:#fff;image-rendering:pixelated}.nh-two-factor__key{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.nh-two-factor__codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr));gap:.5rem;margin:0;padding:0;list-style:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.nh-two-factor__codes li{padding:.375rem .5rem;border:1px dashed var(--nh-color-border, #cbd2d9);border-radius:.375rem;text-align:center}.nh-two-factor__section{display:flex;flex-direction:column;gap:.75rem;padding-top:1rem;border-top:1px solid var(--nh-color-border, #cbd2d9)}.nh-two-factor__status{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}.nh-two-factor__badge{padding:.125rem .5rem;border-radius:999px;background:var(--nh-color-status-background, #eef2f7);font-size:.8125rem;font-weight:600}.nh-two-factor__badge--on{background:var(--nh-color-success-background, #e7f6ec);color:var(--nh-color-success, #1e6b3a)}.nh-two-factor__list{display:flex;flex-direction:column;gap:.5rem;margin:0;padding:0;list-style:none}.nh-two-factor__item{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.5rem;min-width:0;padding:.75rem;border:1px solid var(--nh-color-border, #cbd2d9);border-radius:.5rem}.nh-two-factor__item>div{min-width:0}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
871
871
  }], ctorParameters: () => [], propDecorators: { showErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showErrors", required: false }] }], authenticated: [{ type: i0.Output, args: ["authenticated"] }], pending: [{ type: i0.Output, args: ["pending"] }], failed: [{ type: i0.Output, args: ["failed"] }] } });