taon-ui 21.0.35 → 21.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/browser/fesm2022/taon-ui-browser.mjs +131 -25
  2. package/browser/fesm2022/taon-ui-browser.mjs.map +1 -1
  3. package/browser/package.json +1 -1
  4. package/browser/types/taon-ui-browser.d.ts +23 -10
  5. package/browser-prod/fesm2022/taon-ui-browser-prod.mjs +131 -27
  6. package/browser-prod/fesm2022/taon-ui-browser-prod.mjs.map +1 -1
  7. package/browser-prod/package.json +1 -1
  8. package/browser-prod/types/taon-ui-browser-prod.d.ts +23 -8
  9. package/lib/build-info._auto-generated_.d.ts +1 -3
  10. package/lib/build-info._auto-generated_.js +1 -1
  11. package/lib/index._auto-generated_.d.ts +1 -0
  12. package/lib/index._auto-generated_.js +1 -0
  13. package/lib/index._auto-generated_.js.map +1 -1
  14. package/lib/layouts/taon-bootstrap-navbar/index.js +2 -2
  15. package/lib/package.json +1 -1
  16. package/lib/ui/directives/index.js +2 -2
  17. package/lib/ui/index.js +2 -2
  18. package/lib/ui/taon-auth/auth-button.component.d.ts +2 -1
  19. package/lib/ui/taon-auth/auth-dialog.component.d.ts +6 -3
  20. package/lib/ui/taon-auth/microsoft-auth.service.d.ts +5 -0
  21. package/lib/ui/taon-auth/session.service.d.ts +2 -0
  22. package/lib/ui/taon-github-fork-me-corner/index.js +2 -2
  23. package/lib/ui/taon-github-fork-me-ribbon/index.js +2 -2
  24. package/lib/ui/taon-iframe-sync/index.js +2 -2
  25. package/lib/ui/taon-kv-authorization/taon-kv-authorization.component.d.ts +5 -2
  26. package/lib/ui/taon-progress-bar/index.js +2 -2
  27. package/lib/ui/taon-session-passcode/index.js +2 -2
  28. package/lib/ui/taon-table/index.js +2 -2
  29. package/lib-prod/build-info._auto-generated_.d.ts +1 -1
  30. package/lib-prod/build-info._auto-generated_.js +1 -3
  31. package/lib-prod/build-info._auto-generated_.js.map +1 -1
  32. package/lib-prod/index._auto-generated_.js +1 -0
  33. package/lib-prod/index._auto-generated_.js.map +1 -1
  34. package/lib-prod/layouts/taon-bootstrap-navbar/index.d.ts +1 -1
  35. package/lib-prod/layouts/taon-bootstrap-navbar/index.js +1 -1
  36. package/lib-prod/package.json +1 -1
  37. package/lib-prod/ui/directives/index.d.ts +1 -1
  38. package/lib-prod/ui/directives/index.js +1 -1
  39. package/lib-prod/ui/index.d.ts +1 -1
  40. package/lib-prod/ui/index.js +1 -1
  41. package/lib-prod/ui/taon-github-fork-me-corner/index.d.ts +1 -1
  42. package/lib-prod/ui/taon-github-fork-me-corner/index.js +1 -1
  43. package/lib-prod/ui/taon-github-fork-me-ribbon/index.d.ts +1 -1
  44. package/lib-prod/ui/taon-github-fork-me-ribbon/index.js +1 -1
  45. package/lib-prod/ui/taon-iframe-sync/index.d.ts +1 -1
  46. package/lib-prod/ui/taon-iframe-sync/index.js +1 -1
  47. package/lib-prod/ui/taon-progress-bar/index.d.ts +1 -1
  48. package/lib-prod/ui/taon-progress-bar/index.js +1 -1
  49. package/lib-prod/ui/taon-session-passcode/index.d.ts +1 -1
  50. package/lib-prod/ui/taon-session-passcode/index.js +1 -1
  51. package/lib-prod/ui/taon-table/index.d.ts +1 -1
  52. package/lib-prod/ui/taon-table/index.js +1 -1
  53. package/package.json +1 -1
  54. package/scss/lib/ui/taon-auth/auth-dialog.component.scss +11 -0
  55. package/websql/fesm2022/taon-ui-websql.mjs +131 -25
  56. package/websql/fesm2022/taon-ui-websql.mjs.map +1 -1
  57. package/websql/package.json +1 -1
  58. package/websql/types/taon-ui-websql.d.ts +23 -10
  59. package/websql-prod/fesm2022/taon-ui-websql-prod.mjs +131 -27
  60. package/websql-prod/fesm2022/taon-ui-websql-prod.mjs.map +1 -1
  61. package/websql-prod/package.json +1 -1
  62. package/websql-prod/types/taon-ui-websql-prod.d.ts +23 -8
@@ -109,7 +109,7 @@ const CURRENT_PACKAGE_TAON_VERSION = 'v21';
109
109
  /**
110
110
  * Autogenerated by current cli tool. Use *tnp release* to bump version.
111
111
  */
112
- const CURRENT_PACKAGE_VERSION = '21.0.35';
112
+ const CURRENT_PACKAGE_VERSION = '21.0.37';
113
113
  // THIS FILE IS GENERATED - DO NOT MODIFY
114
114
 
115
115
  function myOrgProj() { }
@@ -1036,9 +1036,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
1036
1036
  args: [{ providedIn: 'root' }]
1037
1037
  }], ctorParameters: () => [{ type: i0.NgZone }] });
1038
1038
 
1039
+ class MicrosoftAuthService {
1040
+ login(clientId) {
1041
+ return new Observable(subscriber => {
1042
+ const redirectUri = window.location.origin;
1043
+ const nonce = crypto.randomUUID();
1044
+ const url = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize' +
1045
+ `?client_id=${clientId}` +
1046
+ `&response_type=id_token` +
1047
+ `&redirect_uri=${encodeURIComponent(redirectUri)}` +
1048
+ `&scope=openid profile email` +
1049
+ `&response_mode=fragment` +
1050
+ `&prompt=login` +
1051
+ `&nonce=${nonce}`;
1052
+ const popup = window.open(url, 'microsoft-login', 'width=500,height=600');
1053
+ if (!popup) {
1054
+ subscriber.error('Popup blocked');
1055
+ return;
1056
+ }
1057
+ const timer = setInterval(() => {
1058
+ try {
1059
+ if (popup.closed) {
1060
+ clearInterval(timer);
1061
+ subscriber.complete();
1062
+ return;
1063
+ }
1064
+ const popupUrl = popup.location.href;
1065
+ // Wait until redirect happens back to our domain
1066
+ if (!popupUrl.startsWith(redirectUri))
1067
+ return;
1068
+ const hash = popup.location.hash;
1069
+ if (!hash)
1070
+ return;
1071
+ const params = new URLSearchParams(hash.substring(1));
1072
+ const idToken = params.get('id_token');
1073
+ if (idToken) {
1074
+ clearInterval(timer);
1075
+ popup.close();
1076
+ const payload = this.decodeJwt(idToken);
1077
+ subscriber.next({
1078
+ email: payload.email || payload.preferred_username,
1079
+ name: payload.name,
1080
+ picture: undefined,
1081
+ });
1082
+ subscriber.complete();
1083
+ }
1084
+ }
1085
+ catch {
1086
+ // Cross-origin access throws until redirect returns to our domain
1087
+ }
1088
+ }, 300);
1089
+ });
1090
+ }
1091
+ decodeJwt(token) {
1092
+ const base64Url = token.split('.')[1];
1093
+ const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
1094
+ const jsonPayload = decodeURIComponent(atob(base64)
1095
+ .split('')
1096
+ .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
1097
+ .join(''));
1098
+ return JSON.parse(jsonPayload);
1099
+ }
1100
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: MicrosoftAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1101
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: MicrosoftAuthService, providedIn: 'root' }); }
1102
+ }
1103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: MicrosoftAuthService, decorators: [{
1104
+ type: Injectable,
1105
+ args: [{ providedIn: 'root' }]
1106
+ }] });
1107
+
1039
1108
  const STORAGE_KEY = 'auth_session_v1';
1040
1109
  class SessionService {
1041
1110
  constructor() {
1111
+ this.microsoftLogin = inject(MicrosoftAuthService);
1042
1112
  this.state$ = new BehaviorSubject(this.load());
1043
1113
  this.data$ = this.state$.asObservable();
1044
1114
  this.isLoggedIn$ = this.state$.pipe(map(s => !!s.isLoggedIn), distinctUntilChanged(), shareReplay({ bufferSize: 1, refCount: true }));
@@ -1090,15 +1160,33 @@ class AuthDialogComponent {
1090
1160
  this.form = new FormGroup({
1091
1161
  email: new FormControl('', [
1092
1162
  Validators.required,
1093
- Validators.pattern(this.emailRegex), // Use pattern instead of .email
1163
+ Validators.pattern(this.emailRegex),
1094
1164
  ]),
1095
1165
  });
1096
1166
  this.diableLoginByEmail = !(window.location.hostname === 'localhost');
1097
1167
  this.dialogRef = inject((MatDialogRef));
1098
1168
  this.googleAuth = inject(GoogleAuthService);
1169
+ this.microsoftAuth = inject(MicrosoftAuthService);
1099
1170
  this.session = inject(SessionService);
1100
1171
  this.googleButtonLoaded = false;
1101
1172
  }
1173
+ loginWithMicrosoft() {
1174
+ if (!this.microsoftClientId) {
1175
+ console.warn('Microsoft client id missing [microsoftClientId]');
1176
+ return;
1177
+ }
1178
+ this.microsoftAuth.login(this.microsoftClientId).subscribe(profile => {
1179
+ if (!profile?.email)
1180
+ return;
1181
+ this.session.loginWithGoogle({
1182
+ email: profile.email,
1183
+ emailVerified: true,
1184
+ displayName: profile.name,
1185
+ pictureUrl: profile.picture,
1186
+ });
1187
+ this.dialogRef.close();
1188
+ });
1189
+ }
1102
1190
  loginByEmail() {
1103
1191
  this.form.markAllAsTouched();
1104
1192
  this.form.updateValueAndValidity();
@@ -1110,28 +1198,23 @@ class AuthDialogComponent {
1110
1198
  email: this.form.value.email,
1111
1199
  emailVerified: true,
1112
1200
  displayName,
1113
- // pictureUrl: payload.picture,
1114
1201
  });
1115
1202
  this.dialogRef.close();
1116
1203
  }
1117
1204
  ngOnInit() {
1118
- //Called after the constructor, initializing input properties, and the first call to ngOnChanges.
1119
- //Add 'implements OnInit' to the class.
1120
1205
  if (this.diableLoginByEmail) {
1121
1206
  this.form.controls.email.disable();
1122
1207
  }
1123
1208
  }
1124
1209
  ngAfterViewInit() {
1125
1210
  if (!this.googleClientId) {
1126
- console.warn('Google client id missing');
1211
+ console.warn('Google client id missing [googleClientId]');
1127
1212
  return;
1128
1213
  }
1129
1214
  this.dialogRef.afterOpened().subscribe(() => {
1130
1215
  setTimeout(() => {
1131
1216
  const el = this.emailLoginBtn.nativeElement;
1132
1217
  const width = Math.floor(el.getBoundingClientRect().width);
1133
- // el.style.width = `${width}px`;
1134
- // console.log({ width });
1135
1218
  this.googleAuth
1136
1219
  .renderButton(this.googleBtn.nativeElement, this.googleClientId, width)
1137
1220
  .subscribe(payload => {
@@ -1153,7 +1236,7 @@ class AuthDialogComponent {
1153
1236
  });
1154
1237
  }
1155
1238
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: AuthDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1156
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: AuthDialogComponent, isStandalone: true, selector: "app-auth-dialog", inputs: { googleClientId: "googleClientId" }, viewQueries: [{ propertyName: "emailLoginBtn", first: true, predicate: ["emailLoginBtn"], descendants: true, static: true }, { propertyName: "googleBtn", first: true, predicate: ["googleBtn"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"auth-dialog p-4\">\n <h4 class=\"mb-3\">Login or register</h4>\n\n <div\n class=\"w-full\"\n #emailLoginBtn>\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"loginByEmail()\"\n class=\"w-full\">\n <mat-form-field\n appearance=\"outline\"\n class=\"w-full email-field\">\n <mat-label *ngIf=\"!diableLoginByEmail\">Email</mat-label>\n\n <input\n matInput\n formControlName=\"email\"\n class=\"pl-1\"\n type=\"email\"\n [placeholder]=\"\n diableLoginByEmail ? 'Login by email (disabled)' : ''\n \" />\n\n <button\n mat-icon-button\n [disabled]=\"diableLoginByEmail\"\n matSuffix\n color=\"primary\">\n <mat-icon>mail</mat-icon>\n </button>\n <mat-error *ngIf=\"form.get('email')?.hasError('email')\">\n Please enter a valid email address\n </mat-error>\n </mat-form-field>\n </form>\n <div class=\"divider\">\n <span>or</span>\n </div>\n <!-- Placeholder for goole button -->\n <div\n #googleBtn\n class=\"google-container\">\n <span\n *ngIf=\"!googleButtonLoaded\"\n class=\"text-300 p-2\"\n >loading google button..</span\n >\n <mat-progress-bar\n *ngIf=\"!googleButtonLoaded\"\n mode=\"indeterminate\"\n class=\"auth-progress\" />\n </div>\n </div>\n <br />\n <!-- <mat-divider class=\"my-3\"></mat-divider> -->\n\n <div class=\"flex justify-content-end\">\n <button\n mat-button\n mat-dialog-close>\n Cancel\n </button>\n </div>\n</div>", styles: [".auth-dialog{width:100%}.google-container{width:100%;height:50px;border-color:#9ca3af!important}:host::ng-deep .email-field .mdc-notched-outline__trailing,:host::ng-deep .email-field .mdc-notched-outline__leading,:host::ng-deep .email-field .mdc-notched-outline__notch{border-color:#9ca3af!important}:host ::ng-deep .auth-progress .mdc-linear-progress__bar-inner{border-color:#9ca3af!important}.divider{display:flex;align-items:center;text-align:center;width:100%;margin:1rem 0}.divider:before,.divider:after{content:\"\";flex:1;border-bottom:1px solid #ccc}.divider span{padding:0 10px;color:#666;font-size:14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i6.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MtxLoaderModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1239
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: AuthDialogComponent, isStandalone: true, selector: "app-auth-dialog", inputs: { googleClientId: "googleClientId", microsoftClientId: "microsoftClientId" }, viewQueries: [{ propertyName: "emailLoginBtn", first: true, predicate: ["emailLoginBtn"], descendants: true, static: true }, { propertyName: "googleBtn", first: true, predicate: ["googleBtn"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"auth-dialog p-4\">\n <h4 class=\"mb-3\">Login or register</h4>\n\n <div\n class=\"w-full\"\n #emailLoginBtn>\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"loginByEmail()\"\n class=\"w-full\">\n <mat-form-field\n appearance=\"outline\"\n class=\"w-full email-field\">\n <mat-label *ngIf=\"!diableLoginByEmail\">Email</mat-label>\n\n <input\n matInput\n formControlName=\"email\"\n class=\"pl-1\"\n type=\"email\"\n [placeholder]=\"\n diableLoginByEmail ? 'Login by email (disabled)' : ''\n \" />\n\n <button\n mat-icon-button\n [disabled]=\"diableLoginByEmail\"\n matSuffix\n color=\"primary\">\n <mat-icon>mail</mat-icon>\n </button>\n <mat-error *ngIf=\"form.get('email')?.hasError('email')\">\n Please enter a valid email address\n </mat-error>\n </mat-form-field>\n </form>\n\n <div class=\"divider\">\n <span>or</span>\n </div>\n\n <!-- GOOGLE BUTTON -->\n <div\n #googleBtn\n class=\"google-container\">\n <span\n *ngIf=\"!googleButtonLoaded\"\n class=\"text-300 p-2\"\n >loading google button..</span\n >\n <mat-progress-bar\n *ngIf=\"!googleButtonLoaded\"\n mode=\"indeterminate\"\n class=\"auth-progress\" />\n </div>\n\n <!-- MICROSOFT BUTTON -->\n <div\n *ngIf=\"microsoftClientId\"\n #microsoftBtn\n class=\"microsoft-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n class=\"w-full microsoft-btn\"\n (click)=\"loginWithMicrosoft()\">\n <mat-icon class=\"mr-2\">login</mat-icon>\n Continue with Microsoft\n </button>\n </div>\n </div>\n\n <br />\n\n <div class=\"flex justify-content-end\">\n <button\n mat-button\n mat-dialog-close>\n Cancel\n </button>\n </div>\n</div>", styles: [".auth-dialog{width:100%}.google-container{width:100%;height:50px;border-color:#9ca3af!important}.microsoft-container{width:100%}.microsoft-btn{height:40px;border-radius:4px!important;border-color:#9ca3af!important;background-color:#fff}:host::ng-deep .email-field .mdc-notched-outline__trailing,:host::ng-deep .email-field .mdc-notched-outline__leading,:host::ng-deep .email-field .mdc-notched-outline__notch{border-color:#9ca3af!important}:host ::ng-deep .auth-progress .mdc-linear-progress__bar-inner{border-color:#9ca3af!important}.divider{display:flex;align-items:center;text-align:center;width:100%;margin:1rem 0}.divider:before,.divider:after{content:\"\";flex:1;border-bottom:1px solid #ccc}.divider span{padding:0 10px;color:#666;font-size:14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i5$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i6.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MtxLoaderModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1157
1240
  }
1158
1241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: AuthDialogComponent, decorators: [{
1159
1242
  type: Component,
@@ -1171,10 +1254,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
1171
1254
  InputTextModule,
1172
1255
  ReactiveFormsModule,
1173
1256
  FormsModule,
1174
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"auth-dialog p-4\">\n <h4 class=\"mb-3\">Login or register</h4>\n\n <div\n class=\"w-full\"\n #emailLoginBtn>\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"loginByEmail()\"\n class=\"w-full\">\n <mat-form-field\n appearance=\"outline\"\n class=\"w-full email-field\">\n <mat-label *ngIf=\"!diableLoginByEmail\">Email</mat-label>\n\n <input\n matInput\n formControlName=\"email\"\n class=\"pl-1\"\n type=\"email\"\n [placeholder]=\"\n diableLoginByEmail ? 'Login by email (disabled)' : ''\n \" />\n\n <button\n mat-icon-button\n [disabled]=\"diableLoginByEmail\"\n matSuffix\n color=\"primary\">\n <mat-icon>mail</mat-icon>\n </button>\n <mat-error *ngIf=\"form.get('email')?.hasError('email')\">\n Please enter a valid email address\n </mat-error>\n </mat-form-field>\n </form>\n <div class=\"divider\">\n <span>or</span>\n </div>\n <!-- Placeholder for goole button -->\n <div\n #googleBtn\n class=\"google-container\">\n <span\n *ngIf=\"!googleButtonLoaded\"\n class=\"text-300 p-2\"\n >loading google button..</span\n >\n <mat-progress-bar\n *ngIf=\"!googleButtonLoaded\"\n mode=\"indeterminate\"\n class=\"auth-progress\" />\n </div>\n </div>\n <br />\n <!-- <mat-divider class=\"my-3\"></mat-divider> -->\n\n <div class=\"flex justify-content-end\">\n <button\n mat-button\n mat-dialog-close>\n Cancel\n </button>\n </div>\n</div>", styles: [".auth-dialog{width:100%}.google-container{width:100%;height:50px;border-color:#9ca3af!important}:host::ng-deep .email-field .mdc-notched-outline__trailing,:host::ng-deep .email-field .mdc-notched-outline__leading,:host::ng-deep .email-field .mdc-notched-outline__notch{border-color:#9ca3af!important}:host ::ng-deep .auth-progress .mdc-linear-progress__bar-inner{border-color:#9ca3af!important}.divider{display:flex;align-items:center;text-align:center;width:100%;margin:1rem 0}.divider:before,.divider:after{content:\"\";flex:1;border-bottom:1px solid #ccc}.divider span{padding:0 10px;color:#666;font-size:14px}\n"] }]
1257
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"auth-dialog p-4\">\n <h4 class=\"mb-3\">Login or register</h4>\n\n <div\n class=\"w-full\"\n #emailLoginBtn>\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"loginByEmail()\"\n class=\"w-full\">\n <mat-form-field\n appearance=\"outline\"\n class=\"w-full email-field\">\n <mat-label *ngIf=\"!diableLoginByEmail\">Email</mat-label>\n\n <input\n matInput\n formControlName=\"email\"\n class=\"pl-1\"\n type=\"email\"\n [placeholder]=\"\n diableLoginByEmail ? 'Login by email (disabled)' : ''\n \" />\n\n <button\n mat-icon-button\n [disabled]=\"diableLoginByEmail\"\n matSuffix\n color=\"primary\">\n <mat-icon>mail</mat-icon>\n </button>\n <mat-error *ngIf=\"form.get('email')?.hasError('email')\">\n Please enter a valid email address\n </mat-error>\n </mat-form-field>\n </form>\n\n <div class=\"divider\">\n <span>or</span>\n </div>\n\n <!-- GOOGLE BUTTON -->\n <div\n #googleBtn\n class=\"google-container\">\n <span\n *ngIf=\"!googleButtonLoaded\"\n class=\"text-300 p-2\"\n >loading google button..</span\n >\n <mat-progress-bar\n *ngIf=\"!googleButtonLoaded\"\n mode=\"indeterminate\"\n class=\"auth-progress\" />\n </div>\n\n <!-- MICROSOFT BUTTON -->\n <div\n *ngIf=\"microsoftClientId\"\n #microsoftBtn\n class=\"microsoft-container\">\n <button\n mat-stroked-button\n color=\"primary\"\n class=\"w-full microsoft-btn\"\n (click)=\"loginWithMicrosoft()\">\n <mat-icon class=\"mr-2\">login</mat-icon>\n Continue with Microsoft\n </button>\n </div>\n </div>\n\n <br />\n\n <div class=\"flex justify-content-end\">\n <button\n mat-button\n mat-dialog-close>\n Cancel\n </button>\n </div>\n</div>", styles: [".auth-dialog{width:100%}.google-container{width:100%;height:50px;border-color:#9ca3af!important}.microsoft-container{width:100%}.microsoft-btn{height:40px;border-radius:4px!important;border-color:#9ca3af!important;background-color:#fff}:host::ng-deep .email-field .mdc-notched-outline__trailing,:host::ng-deep .email-field .mdc-notched-outline__leading,:host::ng-deep .email-field .mdc-notched-outline__notch{border-color:#9ca3af!important}:host ::ng-deep .auth-progress .mdc-linear-progress__bar-inner{border-color:#9ca3af!important}.divider{display:flex;align-items:center;text-align:center;width:100%;margin:1rem 0}.divider:before,.divider:after{content:\"\";flex:1;border-bottom:1px solid #ccc}.divider span{padding:0 10px;color:#666;font-size:14px}\n"] }]
1175
1258
  }], propDecorators: { googleClientId: [{
1176
- type: Input,
1177
- args: [{ required: true }]
1259
+ type: Input
1260
+ }], microsoftClientId: [{
1261
+ type: Input
1178
1262
  }], emailLoginBtn: [{
1179
1263
  type: ViewChild,
1180
1264
  args: ['emailLoginBtn', { static: true }]
@@ -1190,10 +1274,12 @@ class AuthButtonComponent {
1190
1274
  this.router = inject(Router);
1191
1275
  }
1192
1276
  openLogin() {
1193
- this.dialog.open(AuthDialogComponent, {
1277
+ const instance = this.dialog.open(AuthDialogComponent, {
1194
1278
  width: '410px',
1195
1279
  data: null,
1196
- }).componentInstance.googleClientId = this.googleClientId;
1280
+ }).componentInstance;
1281
+ instance.googleClientId = this.googleClientId;
1282
+ instance.microsoftClientId = this.microsoftClientId;
1197
1283
  }
1198
1284
  goDashboard() {
1199
1285
  if (this.linkToDashboard) {
@@ -1204,6 +1290,12 @@ class AuthButtonComponent {
1204
1290
  this.session.logout();
1205
1291
  }
1206
1292
  ngOnInit() {
1293
+ if (!this.microsoftClientId) {
1294
+ console.warn('[taon-auth-button] Microsoft client id missing [microsoftClientId]');
1295
+ }
1296
+ if (!this.googleClientId) {
1297
+ console.warn('[taon-auth-button] Google client id missing [googleClientId]');
1298
+ }
1207
1299
  //Called after the constructor, initializing input properties, and the first call to ngOnChanges.
1208
1300
  //Add 'implements OnInit' to the class.
1209
1301
  // console.log('this.displayDashboardButton', this.displayDashboardButton);
@@ -1212,7 +1304,7 @@ class AuthButtonComponent {
1212
1304
  : true;
1213
1305
  }
1214
1306
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: AuthButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1215
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: AuthButtonComponent, isStandalone: true, selector: "taon-auth-button", inputs: { linkToDashboard: "linkToDashboard", googleClientId: "googleClientId", displayDashboardButton: "displayDashboardButton" }, ngImport: i0, template: "<div class=\"flex align-items-center gap-2\">\n <ng-container *ngIf=\"(session.isLoggedIn$ | async) === false; else loggedIn\">\n <button\n mat-button\n (click)=\"openLogin()\">\n Login\n </button>\n </ng-container>\n\n <ng-template #loggedIn>\n <button\n *ngIf=\"displayDashboardButton\"\n mat-button\n color=\"primary\"\n class=\"auth-btn\"\n (click)=\"goDashboard()\">\n <mat-icon>dashboard</mat-icon>\n Dashboard\n </button>\n\n <button\n mat-button\n class=\"ml-2\"\n (click)=\"logout()\">\n Logout ({{ (session.data$ | async)?.displayName }})\n </button>\n </ng-template>\n</div>", styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
1307
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: AuthButtonComponent, isStandalone: true, selector: "taon-auth-button", inputs: { linkToDashboard: "linkToDashboard", googleClientId: "googleClientId", microsoftClientId: "microsoftClientId", displayDashboardButton: "displayDashboardButton" }, ngImport: i0, template: "<div class=\"flex align-items-center gap-2\">\n <ng-container *ngIf=\"(session.isLoggedIn$ | async) === false; else loggedIn\">\n <button\n mat-button\n (click)=\"openLogin()\">\n Login\n </button>\n </ng-container>\n\n <ng-template #loggedIn>\n <button\n *ngIf=\"displayDashboardButton\"\n mat-button\n color=\"primary\"\n class=\"auth-btn\"\n (click)=\"goDashboard()\">\n <mat-icon>dashboard</mat-icon>\n Dashboard\n </button>\n\n <button\n mat-button\n class=\"ml-2\"\n (click)=\"logout()\">\n Logout ({{ (session.data$ | async)?.displayName }})\n </button>\n </ng-template>\n</div>", styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] }); }
1216
1308
  }
1217
1309
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: AuthButtonComponent, decorators: [{
1218
1310
  type: Component,
@@ -1221,8 +1313,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
1221
1313
  type: Input,
1222
1314
  args: [{ required: true }]
1223
1315
  }], googleClientId: [{
1224
- type: Input,
1225
- args: [{ required: true }]
1316
+ type: Input
1317
+ }], microsoftClientId: [{
1318
+ type: Input
1226
1319
  }], displayDashboardButton: [{
1227
1320
  type: Input
1228
1321
  }] } });
@@ -1498,12 +1591,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
1498
1591
 
1499
1592
  class TaonKvAuthorizationComponent {
1500
1593
  constructor() {
1594
+ this.cdr = inject(ChangeDetectorRef);
1501
1595
  this.products = [];
1502
1596
  this.authorizedProducts = new EventEmitter();
1503
1597
  this.loading = signal(true, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1504
1598
  this.authorizedProductsData = signal([], ...(ngDevMode ? [{ debugName: "authorizedProductsData" }] : []));
1599
+ this.authorizationCheckingInProgress = false;
1505
1600
  }
1506
- async ngOnInit() {
1601
+ ngOnInit() {
1602
+ this.checkIfProducstsAuthorized();
1603
+ }
1604
+ async checkIfProducstsAuthorized() {
1605
+ if (this.authorizationCheckingInProgress) {
1606
+ return;
1607
+ }
1608
+ this.authorizationCheckingInProgress = true;
1507
1609
  const worker = new TaonStripeCloudflareWorker(this.url);
1508
1610
  const results = [];
1509
1611
  for (const product of this.products) {
@@ -1516,27 +1618,31 @@ class TaonKvAuthorizationComponent {
1516
1618
  ...product,
1517
1619
  authorized,
1518
1620
  });
1621
+ this.cdr.markForCheck();
1519
1622
  }
1520
1623
  catch {
1521
1624
  results.push({
1522
1625
  ...product,
1523
1626
  authorized: false,
1524
1627
  });
1628
+ this.cdr.markForCheck();
1525
1629
  }
1526
1630
  }
1527
1631
  this.authorizedProductsData.set(results);
1528
1632
  this.loading.set(false);
1529
1633
  this.authorizedProducts.emit(results);
1634
+ this.authorizationCheckingInProgress = false;
1635
+ this.cdr.markForCheck();
1530
1636
  }
1531
1637
  authorizedCount() {
1532
1638
  return this.authorizedProductsData().filter(p => p.authorized).length;
1533
1639
  }
1534
1640
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonKvAuthorizationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1535
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonKvAuthorizationComponent, isStandalone: true, selector: "taon-kv-authorization", inputs: { email: "email", url: "url", products: "products" }, outputs: { authorizedProducts: "authorizedProducts" }, ngImport: i0, template: "<div class=\"taon-kv-authorization\">\n <div *ngIf=\"loading()\">Loading authorization info...</div>\n\n <div *ngIf=\"!loading()\">\n <div *ngIf=\"authorizedCount() === 0\">You did not purchase any products</div>\n\n <div *ngIf=\"authorizedCount() > 0\">\n You purchased {{ authorizedCount() }} products\n </div>\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1641
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonKvAuthorizationComponent, isStandalone: true, selector: "taon-kv-authorization", inputs: { email: "email", url: "url", products: "products" }, outputs: { authorizedProducts: "authorizedProducts" }, ngImport: i0, template: "<div class=\"taon-kv-authorization\">\n <div *ngIf=\"loading()\">Loading authorization info...</div>\n\n <div *ngIf=\"!loading()\">\n <div *ngIf=\"authorizedCount() === 0\">You did not purchase any products</div>\n\n <div *ngIf=\"authorizedCount() > 0\">\n You purchased {{ authorizedCount() }} products\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1536
1642
  }
1537
1643
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonKvAuthorizationComponent, decorators: [{
1538
1644
  type: Component,
1539
- args: [{ selector: 'taon-kv-authorization', standalone: true, imports: [CommonModule], template: "<div class=\"taon-kv-authorization\">\n <div *ngIf=\"loading()\">Loading authorization info...</div>\n\n <div *ngIf=\"!loading()\">\n <div *ngIf=\"authorizedCount() === 0\">You did not purchase any products</div>\n\n <div *ngIf=\"authorizedCount() > 0\">\n You purchased {{ authorizedCount() }} products\n </div>\n </div>\n</div>" }]
1645
+ args: [{ selector: 'taon-kv-authorization', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule], template: "<div class=\"taon-kv-authorization\">\n <div *ngIf=\"loading()\">Loading authorization info...</div>\n\n <div *ngIf=\"!loading()\">\n <div *ngIf=\"authorizedCount() === 0\">You did not purchase any products</div>\n\n <div *ngIf=\"authorizedCount() > 0\">\n You purchased {{ authorizedCount() }} products\n </div>\n </div>\n</div>\n" }]
1540
1646
  }], propDecorators: { email: [{
1541
1647
  type: Input,
1542
1648
  args: [{ required: true }]
@@ -1582,11 +1688,11 @@ class TaonRumbleComponent {
1582
1688
  return this.state === 'video-preview-private';
1583
1689
  }
1584
1690
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonRumbleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1585
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonRumbleComponent, isStandalone: true, selector: "taon-rumble", inputs: { title: "title", clipId: "clipId", picturePreviewUrl: "picturePreviewUrl", state: "state" }, outputs: { paddlockClicked: "paddlockClicked", previewClicked: "previewClicked" }, ngImport: i0, template: "<div class=\"taon-rumble\">\n <!-- PREVIEW MODE -->\n <div\n *ngIf=\"isPreview()\"\n class=\"preview\"\n (click)=\"onPreviewClick()\">\n <img\n class=\"preview-img\"\n [src]=\"picturePreviewUrl\"\n [alt]=\"title\" />\n\n <div class=\"title\">\n {{ title }}\n </div>\n\n <!-- PLAY BUTTON -->\n <div class=\"play-button\">\u25B6</div>\n\n <!-- LOCK -->\n <div\n *ngIf=\"isLocked()\"\n class=\"lock\"\n (click)=\"onPadlockClick($event)\">\n \uD83D\uDD12\n </div>\n </div>\n\n <!-- VIDEO OPEN -->\n <div\n *ngIf=\"isVideoOpen()\"\n class=\"video\">\n <iframe\n class=\"rumble-frame\"\n [src]=\"embedUrl()\"\n frameborder=\"0\"\n allowfullscreen>\n </iframe>\n </div>\n\n <!-- PRIVATE VIDEO -->\n <div\n *ngIf=\"isPrivate()\"\n class=\"private\">\n <div class=\"private-box\">\uD83D\uDD12 Private video</div>\n </div>\n</div>", styles: [".taon-rumble{width:100%;max-width:640px;margin:auto;position:relative;font-family:inherit}.preview{position:relative;cursor:pointer;overflow:hidden;border-radius:10px}.preview-img{width:100%;display:block}.title{position:absolute;left:0;bottom:0;right:0;padding:10px 14px;background:linear-gradient(transparent,#000c);color:#fff;font-size:14px}.play-button{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:40px;color:#fff;background:#00000080;width:70px;height:70px;display:flex;align-items:center;justify-content:center;border-radius:50%}.lock{position:absolute;top:10px;right:10px;font-size:20px;background:#0009;color:#fff;padding:6px 8px;border-radius:6px}.video{position:relative;padding-top:56.25%}.rumble-frame{position:absolute;top:0;left:0;width:100%;height:100%}.private{display:flex;align-items:center;justify-content:center;height:200px;background:#111;color:#fff}.private-box{opacity:.7}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1691
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonRumbleComponent, isStandalone: true, selector: "taon-rumble", inputs: { title: "title", clipId: "clipId", picturePreviewUrl: "picturePreviewUrl", state: "state" }, outputs: { paddlockClicked: "paddlockClicked", previewClicked: "previewClicked" }, ngImport: i0, template: "<div class=\"taon-rumble\">\n <!-- PREVIEW MODE -->\n <div\n *ngIf=\"isPreview()\"\n class=\"preview\"\n (click)=\"onPreviewClick()\">\n <img\n class=\"preview-img\"\n [src]=\"picturePreviewUrl\"\n [alt]=\"title\" />\n\n <div class=\"title\">\n {{ title }}\n </div>\n\n <!-- PLAY BUTTON -->\n <div class=\"play-button\">\u25B6</div>\n\n <!-- LOCK -->\n <div\n *ngIf=\"isLocked()\"\n class=\"lock\"\n (click)=\"onPadlockClick($event)\">\n \uD83D\uDD12\n </div>\n </div>\n\n <!-- VIDEO OPEN -->\n <div\n *ngIf=\"isVideoOpen()\"\n class=\"video\">\n <iframe\n class=\"rumble-frame\"\n [src]=\"embedUrl()\"\n frameborder=\"0\"\n allowfullscreen>\n </iframe>\n </div>\n\n <!-- PRIVATE VIDEO -->\n <div\n *ngIf=\"isPrivate()\"\n class=\"private\">\n <div class=\"private-box\">\uD83D\uDD12 Private video</div>\n </div>\n</div>\n", styles: [".taon-rumble{width:100%;max-width:640px;margin:auto;position:relative;font-family:inherit}.preview{position:relative;cursor:pointer;overflow:hidden;border-radius:10px}.preview-img{width:100%;display:block}.title{position:absolute;left:0;bottom:0;right:0;padding:10px 14px;background:linear-gradient(transparent,#000c);color:#fff;font-size:14px}.play-button{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:40px;color:#fff;background:#00000080;width:70px;height:70px;display:flex;align-items:center;justify-content:center;border-radius:50%}.lock{position:absolute;top:10px;right:10px;font-size:20px;background:#0009;color:#fff;padding:6px 8px;border-radius:6px}.video{position:relative;padding-top:56.25%}.rumble-frame{position:absolute;top:0;left:0;width:100%;height:100%}.private{display:flex;align-items:center;justify-content:center;height:200px;background:#111;color:#fff}.private-box{opacity:.7}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1586
1692
  }
1587
1693
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonRumbleComponent, decorators: [{
1588
1694
  type: Component,
1589
- args: [{ selector: 'taon-rumble', standalone: true, imports: [NgIf], template: "<div class=\"taon-rumble\">\n <!-- PREVIEW MODE -->\n <div\n *ngIf=\"isPreview()\"\n class=\"preview\"\n (click)=\"onPreviewClick()\">\n <img\n class=\"preview-img\"\n [src]=\"picturePreviewUrl\"\n [alt]=\"title\" />\n\n <div class=\"title\">\n {{ title }}\n </div>\n\n <!-- PLAY BUTTON -->\n <div class=\"play-button\">\u25B6</div>\n\n <!-- LOCK -->\n <div\n *ngIf=\"isLocked()\"\n class=\"lock\"\n (click)=\"onPadlockClick($event)\">\n \uD83D\uDD12\n </div>\n </div>\n\n <!-- VIDEO OPEN -->\n <div\n *ngIf=\"isVideoOpen()\"\n class=\"video\">\n <iframe\n class=\"rumble-frame\"\n [src]=\"embedUrl()\"\n frameborder=\"0\"\n allowfullscreen>\n </iframe>\n </div>\n\n <!-- PRIVATE VIDEO -->\n <div\n *ngIf=\"isPrivate()\"\n class=\"private\">\n <div class=\"private-box\">\uD83D\uDD12 Private video</div>\n </div>\n</div>", styles: [".taon-rumble{width:100%;max-width:640px;margin:auto;position:relative;font-family:inherit}.preview{position:relative;cursor:pointer;overflow:hidden;border-radius:10px}.preview-img{width:100%;display:block}.title{position:absolute;left:0;bottom:0;right:0;padding:10px 14px;background:linear-gradient(transparent,#000c);color:#fff;font-size:14px}.play-button{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:40px;color:#fff;background:#00000080;width:70px;height:70px;display:flex;align-items:center;justify-content:center;border-radius:50%}.lock{position:absolute;top:10px;right:10px;font-size:20px;background:#0009;color:#fff;padding:6px 8px;border-radius:6px}.video{position:relative;padding-top:56.25%}.rumble-frame{position:absolute;top:0;left:0;width:100%;height:100%}.private{display:flex;align-items:center;justify-content:center;height:200px;background:#111;color:#fff}.private-box{opacity:.7}\n"] }]
1695
+ args: [{ selector: 'taon-rumble', standalone: true, imports: [NgIf], template: "<div class=\"taon-rumble\">\n <!-- PREVIEW MODE -->\n <div\n *ngIf=\"isPreview()\"\n class=\"preview\"\n (click)=\"onPreviewClick()\">\n <img\n class=\"preview-img\"\n [src]=\"picturePreviewUrl\"\n [alt]=\"title\" />\n\n <div class=\"title\">\n {{ title }}\n </div>\n\n <!-- PLAY BUTTON -->\n <div class=\"play-button\">\u25B6</div>\n\n <!-- LOCK -->\n <div\n *ngIf=\"isLocked()\"\n class=\"lock\"\n (click)=\"onPadlockClick($event)\">\n \uD83D\uDD12\n </div>\n </div>\n\n <!-- VIDEO OPEN -->\n <div\n *ngIf=\"isVideoOpen()\"\n class=\"video\">\n <iframe\n class=\"rumble-frame\"\n [src]=\"embedUrl()\"\n frameborder=\"0\"\n allowfullscreen>\n </iframe>\n </div>\n\n <!-- PRIVATE VIDEO -->\n <div\n *ngIf=\"isPrivate()\"\n class=\"private\">\n <div class=\"private-box\">\uD83D\uDD12 Private video</div>\n </div>\n</div>\n", styles: [".taon-rumble{width:100%;max-width:640px;margin:auto;position:relative;font-family:inherit}.preview{position:relative;cursor:pointer;overflow:hidden;border-radius:10px}.preview-img{width:100%;display:block}.title{position:absolute;left:0;bottom:0;right:0;padding:10px 14px;background:linear-gradient(transparent,#000c);color:#fff;font-size:14px}.play-button{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:40px;color:#fff;background:#00000080;width:70px;height:70px;display:flex;align-items:center;justify-content:center;border-radius:50%}.lock{position:absolute;top:10px;right:10px;font-size:20px;background:#0009;color:#fff;padding:6px 8px;border-radius:6px}.video{position:relative;padding-top:56.25%}.rumble-frame{position:absolute;top:0;left:0;width:100%;height:100%}.private{display:flex;align-items:center;justify-content:center;height:200px;background:#111;color:#fff}.private-box{opacity:.7}\n"] }]
1590
1696
  }], propDecorators: { title: [{
1591
1697
  type: Input,
1592
1698
  args: [{
@@ -1808,11 +1914,11 @@ class TaonStripeBuyButtonComponent {
1808
1914
  }
1809
1915
  }
1810
1916
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonStripeBuyButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1811
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonStripeBuyButtonComponent, isStandalone: true, selector: "taon-stripe-buy-button", inputs: { priceId: "priceId", productId: "productId", workerUrl: "workerUrl", email: "email", successUrl: "successUrl", cancelUrl: "cancelUrl", label: "label" }, ngImport: i0, template: "<button\n type=\"button\"\n matButton=\"filled\"\n (click)=\"buy()\"\n [disabled]=\"loading\">\n <span *ngIf=\"!loading\">\n {{ label }}\n </span>\n\n <span *ngIf=\"loading\"> Redirecting to Stripe... </span>\n</button>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
1917
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.9", type: TaonStripeBuyButtonComponent, isStandalone: true, selector: "taon-stripe-buy-button", inputs: { priceId: "priceId", productId: "productId", workerUrl: "workerUrl", email: "email", successUrl: "successUrl", cancelUrl: "cancelUrl", label: "label" }, ngImport: i0, template: "<button\n type=\"button\"\n matButton=\"filled\"\n (click)=\"buy()\"\n [disabled]=\"loading\">\n <span *ngIf=\"!loading\">\n {{ label }}\n </span>\n\n <span *ngIf=\"loading\"> Redirecting to Stripe... </span>\n</button>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] }); }
1812
1918
  }
1813
1919
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: TaonStripeBuyButtonComponent, decorators: [{
1814
1920
  type: Component,
1815
- args: [{ selector: 'taon-stripe-buy-button', imports: [CommonModule, MatButtonModule], template: "<button\n type=\"button\"\n matButton=\"filled\"\n (click)=\"buy()\"\n [disabled]=\"loading\">\n <span *ngIf=\"!loading\">\n {{ label }}\n </span>\n\n <span *ngIf=\"loading\"> Redirecting to Stripe... </span>\n</button>" }]
1921
+ args: [{ selector: 'taon-stripe-buy-button', imports: [CommonModule, MatButtonModule], template: "<button\n type=\"button\"\n matButton=\"filled\"\n (click)=\"buy()\"\n [disabled]=\"loading\">\n <span *ngIf=\"!loading\">\n {{ label }}\n </span>\n\n <span *ngIf=\"loading\"> Redirecting to Stripe... </span>\n</button>\n" }]
1816
1922
  }], propDecorators: { priceId: [{
1817
1923
  type: Input,
1818
1924
  args: [{ required: true }]
@@ -2270,5 +2376,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
2270
2376
  * Generated bundle index. Do not edit.
2271
2377
  */
2272
2378
 
2273
- export { APP_ID, AuthButtonComponent, AuthDialogComponent, AuthGuard, BUILD_BASE_HREF, BUILD_FRAMEWORK_CLI_NAME, CURRENT_PACKAGE_TAON_VERSION, CURRENT_PACKAGE_VERSION, GoogleAuthService, PROJECT_NPM_NAME, SafePipe, SessionService, TaonAdminModeConfigurationComponent, TaonBootstrapNavbarComponent, TaonFullMaterialModule, TaonGithubForkMeCornerComponent, TaonGithubForkMeCornerModule, TaonGithubForkMeRibbonComponent, TaonGithubForkMeRibbonModule, TaonIframeSyncComponent, TaonInjectHTMLDirective, TaonKvAuthorizationComponent, TaonLongPress, TaonNotificationOptions, TaonNotificationsComponent, TaonNotificationsModule, TaonNotificationsService, TaonProgressBarComponent, TaonProgressBarModule, TaonRumbleComponent, TaonSessionPasscodeComponent, TaonSimpleLayoutComponent, TaonSimpleLayoutRoutes, TaonStripeBuyButtonComponent, TaonTableComponent, TaonTableModule, TaonThemeComponent, TaonThemeMode, TaonThemeService, TaonYoutubeVideoComponent, ViewMode, myOrgProj };
2379
+ export { APP_ID, AuthButtonComponent, AuthDialogComponent, AuthGuard, BUILD_BASE_HREF, BUILD_FRAMEWORK_CLI_NAME, CURRENT_PACKAGE_TAON_VERSION, CURRENT_PACKAGE_VERSION, GoogleAuthService, MicrosoftAuthService, PROJECT_NPM_NAME, SafePipe, SessionService, TaonAdminModeConfigurationComponent, TaonBootstrapNavbarComponent, TaonFullMaterialModule, TaonGithubForkMeCornerComponent, TaonGithubForkMeCornerModule, TaonGithubForkMeRibbonComponent, TaonGithubForkMeRibbonModule, TaonIframeSyncComponent, TaonInjectHTMLDirective, TaonKvAuthorizationComponent, TaonLongPress, TaonNotificationOptions, TaonNotificationsComponent, TaonNotificationsModule, TaonNotificationsService, TaonProgressBarComponent, TaonProgressBarModule, TaonRumbleComponent, TaonSessionPasscodeComponent, TaonSimpleLayoutComponent, TaonSimpleLayoutRoutes, TaonStripeBuyButtonComponent, TaonTableComponent, TaonTableModule, TaonThemeComponent, TaonThemeMode, TaonThemeService, TaonYoutubeVideoComponent, ViewMode, myOrgProj };
2274
2380
  //# sourceMappingURL=taon-ui-browser.mjs.map