@eduboxpro/studio 0.1.34 → 0.1.36

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, untracked, output, PLATFORM_ID, ElementRef, contentChild, viewChild, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, model, afterNextRender, HostListener, Renderer2, TemplateRef, ContentChild, Input, Directive, contentChildren } from '@angular/core';
2
+ import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, untracked, output, PLATFORM_ID, ElementRef, contentChild, viewChild, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, Injector, model, afterNextRender, HostListener, Renderer2, TemplateRef, ContentChild, Input, Directive, contentChildren, ViewEncapsulation } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { DOCUMENT, CommonModule, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
5
5
  import * as LucideIcons from 'lucide-angular';
@@ -11,6 +11,7 @@ import * as i1$2 from '@angular/forms';
11
11
  import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
12
12
  import { autoUpdate, offset, flip, shift, arrow, computePosition } from '@floating-ui/dom';
13
13
  import { trigger, state, transition, style, animate } from '@angular/animations';
14
+ import { DomSanitizer } from '@angular/platform-browser';
14
15
 
15
16
  /**
16
17
  * Injection token for Studio configuration
@@ -7232,6 +7233,241 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7232
7233
  `, styles: [":host{display:inline-block}:host(.studio-button-toggle-group--disabled){opacity:.6;pointer-events:none}\n"] }]
7233
7234
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEmpty", required: false }] }], orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], attached: [{ type: i0.Input, args: [{ isSignal: true, alias: "attached", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
7234
7235
 
7236
+ /**
7237
+ * FileViewer configuration types
7238
+ */
7239
+ const defaultFileViewerLabels = {
7240
+ videoLabel: 'Video',
7241
+ audioLabel: 'Audio',
7242
+ browserNotSupported: 'Your browser does not support this media'
7243
+ };
7244
+
7245
+ class FileViewerComponent {
7246
+ sanitizer = inject(DomSanitizer);
7247
+ visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
7248
+ fileUrl = input('', ...(ngDevMode ? [{ debugName: "fileUrl" }] : []));
7249
+ fileName = input('', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
7250
+ fileType = input('', ...(ngDevMode ? [{ debugName: "fileType" }] : []));
7251
+ labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : []));
7252
+ close = output();
7253
+ resolvedLabels = computed(() => ({
7254
+ ...defaultFileViewerLabels,
7255
+ ...this.labels()
7256
+ }), ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : []));
7257
+ isPdf = computed(() => {
7258
+ const type = this.fileType();
7259
+ return type?.includes('pdf') || type === 'PDF';
7260
+ }, ...(ngDevMode ? [{ debugName: "isPdf" }] : []));
7261
+ isImage = computed(() => {
7262
+ const type = this.fileType();
7263
+ return type?.startsWith('image/') || type === 'IMAGE';
7264
+ }, ...(ngDevMode ? [{ debugName: "isImage" }] : []));
7265
+ isAudio = computed(() => {
7266
+ const type = this.fileType();
7267
+ return type?.startsWith('audio/') || type === 'AUDIO';
7268
+ }, ...(ngDevMode ? [{ debugName: "isAudio" }] : []));
7269
+ isVideo = computed(() => {
7270
+ const type = this.fileType();
7271
+ return type?.startsWith('video/') || type === 'VIDEO';
7272
+ }, ...(ngDevMode ? [{ debugName: "isVideo" }] : []));
7273
+ fileIcon = computed(() => {
7274
+ const type = this.fileType();
7275
+ if (this.isPdf())
7276
+ return 'file-text';
7277
+ if (this.isImage())
7278
+ return 'image';
7279
+ if (this.isAudio())
7280
+ return 'music';
7281
+ if (this.isVideo())
7282
+ return 'video';
7283
+ if (type?.includes('word') || type?.includes('document'))
7284
+ return 'file-text';
7285
+ if (type?.includes('excel') || type?.includes('spreadsheet'))
7286
+ return 'table';
7287
+ if (type?.includes('powerpoint') || type?.includes('presentation'))
7288
+ return 'presentation';
7289
+ return 'file';
7290
+ }, ...(ngDevMode ? [{ debugName: "fileIcon" }] : []));
7291
+ safeUrl = computed(() => {
7292
+ const url = this.fileUrl();
7293
+ if (!url || this.isPdf() || this.isVideo() || this.isImage() || this.isAudio())
7294
+ return null;
7295
+ return this.sanitizer.bypassSecurityTrustResourceUrl(url);
7296
+ }, ...(ngDevMode ? [{ debugName: "safeUrl" }] : []));
7297
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: FileViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7298
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: FileViewerComponent, isStandalone: true, selector: "studio-file-viewer", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, fileUrl: { classPropertyName: "fileUrl", publicName: "fileUrl", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, fileType: { classPropertyName: "fileType", publicName: "fileType", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, ngImport: i0, template: `
7299
+ @if (visible()) {
7300
+ @if (isVideo()) {
7301
+ <div class="studio-file-viewer studio-file-viewer--video">
7302
+ <div class="studio-file-viewer__header studio-file-viewer__header--video">
7303
+ <button
7304
+ (click)="close.emit()"
7305
+ class="studio-file-viewer__back-btn"
7306
+ type="button"
7307
+ >
7308
+ <studio-icon name="arrow-left" [size]="22" />
7309
+ </button>
7310
+ <div class="studio-file-viewer__title-wrapper">
7311
+ <h1 class="studio-file-viewer__title studio-file-viewer__title--light">{{ fileName() }}</h1>
7312
+ <p class="studio-file-viewer__subtitle">{{ resolvedLabels().videoLabel }}</p>
7313
+ </div>
7314
+ </div>
7315
+ <div class="studio-file-viewer__video-container">
7316
+ <video
7317
+ [src]="fileUrl()"
7318
+ controls
7319
+ controlslist="nodownload"
7320
+ playsinline
7321
+ autoplay
7322
+ class="studio-file-viewer__video"
7323
+ >
7324
+ {{ resolvedLabels().browserNotSupported }}
7325
+ </video>
7326
+ </div>
7327
+ </div>
7328
+ } @else {
7329
+ <div
7330
+ class="studio-file-viewer studio-file-viewer--modal"
7331
+ (click)="close.emit()"
7332
+ >
7333
+ <div
7334
+ class="studio-file-viewer__content"
7335
+ (click)="$event.stopPropagation()"
7336
+ >
7337
+ <div class="studio-file-viewer__header">
7338
+ <div class="studio-file-viewer__title-wrapper studio-file-viewer__title-wrapper--row">
7339
+ <studio-icon [name]="fileIcon()" [size]="20" class="studio-file-viewer__icon" />
7340
+ <h3 class="studio-file-viewer__title">{{ fileName() }}</h3>
7341
+ </div>
7342
+ <button
7343
+ (click)="close.emit()"
7344
+ class="studio-file-viewer__close-btn"
7345
+ type="button"
7346
+ >
7347
+ <studio-icon name="x" [size]="20" />
7348
+ </button>
7349
+ </div>
7350
+ <div class="studio-file-viewer__body">
7351
+ @if (isPdf()) {
7352
+ <ng-content select="[pdfViewer]"></ng-content>
7353
+ } @else if (isImage()) {
7354
+ <div class="studio-file-viewer__image-container">
7355
+ <img
7356
+ [src]="fileUrl()"
7357
+ [alt]="fileName()"
7358
+ class="studio-file-viewer__image"
7359
+ />
7360
+ </div>
7361
+ } @else if (isAudio()) {
7362
+ <div class="studio-file-viewer__audio-container">
7363
+ <div class="studio-file-viewer__audio-icon-wrapper">
7364
+ <studio-icon name="music" [size]="32" />
7365
+ </div>
7366
+ <p class="studio-file-viewer__audio-title">{{ fileName() }}</p>
7367
+ <audio [src]="fileUrl()" controls controlslist="nodownload" class="studio-file-viewer__audio"></audio>
7368
+ </div>
7369
+ } @else if (safeUrl()) {
7370
+ <iframe
7371
+ [src]="safeUrl()"
7372
+ class="studio-file-viewer__iframe"
7373
+ allowfullscreen
7374
+ ></iframe>
7375
+ }
7376
+ </div>
7377
+ </div>
7378
+ </div>
7379
+ }
7380
+ }
7381
+ `, isInline: true, styles: [".studio-file-viewer{position:fixed;inset:0;z-index:50;&--video{background:#000;display:flex;flex-direction:column}&--modal{display:flex;align-items:center;justify-content:center;background:#000000b3}&__header{display:flex;align-items:center;justify-content:space-between;padding:1rem;border-bottom:1px solid var(--studio-border-color, #e5e7eb);&--video{background:#000c;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);padding:.5rem .75rem;border-bottom:none;padding-top:env(safe-area-inset-top)}}&__back-btn{width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;color:#fff;background:transparent;border:none;border-radius:50%;cursor:pointer;transition:background-color .2s;&:hover{background:#ffffff1a}}&__close-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary, #6b7280);background:transparent;border:none;border-radius:.5rem;cursor:pointer;flex-shrink:0;transition:background-color .2s;&:hover{background:var(--studio-bg-secondary, #f3f4f6)}}&__title-wrapper{flex:1;min-width:0;&--row{display:flex;align-items:center;gap:.75rem}}&__title{font-weight:600;font-size:.875rem;color:var(--studio-text-primary, #111827);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0;&--light{color:#fff}}&__subtitle{font-size:.75rem;color:#9ca3af;margin:0}&__icon{color:var(--studio-text-secondary, #6b7280);flex-shrink:0}&__content{background:var(--studio-bg-primary, white);border-radius:.75rem;width:95vw;height:90vh;max-width:72rem;display:flex;flex-direction:column}&__body{flex:1;overflow:hidden}&__video-container{flex:1;display:flex;align-items:center;justify-content:center;background:#000}&__video{width:100%;height:100%;object-fit:contain}&__image-container{display:flex;align-items:center;justify-content:center;height:100%;padding:1rem;background:var(--studio-bg-secondary, #f9fafb)}&__image{max-width:100%;max-height:100%;object-fit:contain;border-radius:.5rem}&__audio-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;background:var(--studio-bg-secondary, #f9fafb);text-align:center}&__audio-icon-wrapper{width:5rem;height:5rem;border-radius:50%;background:var(--studio-primary-light, #dbeafe);display:flex;align-items:center;justify-content:center;margin-bottom:1rem;color:var(--studio-primary, #3b82f6)}&__audio-title{font-weight:500;color:var(--studio-text-primary, #111827);margin-bottom:1rem}&__audio{width:20rem}&__iframe{width:100%;height:100%;border:none}}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7382
+ }
7383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: FileViewerComponent, decorators: [{
7384
+ type: Component,
7385
+ args: [{ selector: 'studio-file-viewer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [IconComponent], template: `
7386
+ @if (visible()) {
7387
+ @if (isVideo()) {
7388
+ <div class="studio-file-viewer studio-file-viewer--video">
7389
+ <div class="studio-file-viewer__header studio-file-viewer__header--video">
7390
+ <button
7391
+ (click)="close.emit()"
7392
+ class="studio-file-viewer__back-btn"
7393
+ type="button"
7394
+ >
7395
+ <studio-icon name="arrow-left" [size]="22" />
7396
+ </button>
7397
+ <div class="studio-file-viewer__title-wrapper">
7398
+ <h1 class="studio-file-viewer__title studio-file-viewer__title--light">{{ fileName() }}</h1>
7399
+ <p class="studio-file-viewer__subtitle">{{ resolvedLabels().videoLabel }}</p>
7400
+ </div>
7401
+ </div>
7402
+ <div class="studio-file-viewer__video-container">
7403
+ <video
7404
+ [src]="fileUrl()"
7405
+ controls
7406
+ controlslist="nodownload"
7407
+ playsinline
7408
+ autoplay
7409
+ class="studio-file-viewer__video"
7410
+ >
7411
+ {{ resolvedLabels().browserNotSupported }}
7412
+ </video>
7413
+ </div>
7414
+ </div>
7415
+ } @else {
7416
+ <div
7417
+ class="studio-file-viewer studio-file-viewer--modal"
7418
+ (click)="close.emit()"
7419
+ >
7420
+ <div
7421
+ class="studio-file-viewer__content"
7422
+ (click)="$event.stopPropagation()"
7423
+ >
7424
+ <div class="studio-file-viewer__header">
7425
+ <div class="studio-file-viewer__title-wrapper studio-file-viewer__title-wrapper--row">
7426
+ <studio-icon [name]="fileIcon()" [size]="20" class="studio-file-viewer__icon" />
7427
+ <h3 class="studio-file-viewer__title">{{ fileName() }}</h3>
7428
+ </div>
7429
+ <button
7430
+ (click)="close.emit()"
7431
+ class="studio-file-viewer__close-btn"
7432
+ type="button"
7433
+ >
7434
+ <studio-icon name="x" [size]="20" />
7435
+ </button>
7436
+ </div>
7437
+ <div class="studio-file-viewer__body">
7438
+ @if (isPdf()) {
7439
+ <ng-content select="[pdfViewer]"></ng-content>
7440
+ } @else if (isImage()) {
7441
+ <div class="studio-file-viewer__image-container">
7442
+ <img
7443
+ [src]="fileUrl()"
7444
+ [alt]="fileName()"
7445
+ class="studio-file-viewer__image"
7446
+ />
7447
+ </div>
7448
+ } @else if (isAudio()) {
7449
+ <div class="studio-file-viewer__audio-container">
7450
+ <div class="studio-file-viewer__audio-icon-wrapper">
7451
+ <studio-icon name="music" [size]="32" />
7452
+ </div>
7453
+ <p class="studio-file-viewer__audio-title">{{ fileName() }}</p>
7454
+ <audio [src]="fileUrl()" controls controlslist="nodownload" class="studio-file-viewer__audio"></audio>
7455
+ </div>
7456
+ } @else if (safeUrl()) {
7457
+ <iframe
7458
+ [src]="safeUrl()"
7459
+ class="studio-file-viewer__iframe"
7460
+ allowfullscreen
7461
+ ></iframe>
7462
+ }
7463
+ </div>
7464
+ </div>
7465
+ </div>
7466
+ }
7467
+ }
7468
+ `, styles: [".studio-file-viewer{position:fixed;inset:0;z-index:50;&--video{background:#000;display:flex;flex-direction:column}&--modal{display:flex;align-items:center;justify-content:center;background:#000000b3}&__header{display:flex;align-items:center;justify-content:space-between;padding:1rem;border-bottom:1px solid var(--studio-border-color, #e5e7eb);&--video{background:#000c;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);padding:.5rem .75rem;border-bottom:none;padding-top:env(safe-area-inset-top)}}&__back-btn{width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;color:#fff;background:transparent;border:none;border-radius:50%;cursor:pointer;transition:background-color .2s;&:hover{background:#ffffff1a}}&__close-btn{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;color:var(--studio-text-secondary, #6b7280);background:transparent;border:none;border-radius:.5rem;cursor:pointer;flex-shrink:0;transition:background-color .2s;&:hover{background:var(--studio-bg-secondary, #f3f4f6)}}&__title-wrapper{flex:1;min-width:0;&--row{display:flex;align-items:center;gap:.75rem}}&__title{font-weight:600;font-size:.875rem;color:var(--studio-text-primary, #111827);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0;&--light{color:#fff}}&__subtitle{font-size:.75rem;color:#9ca3af;margin:0}&__icon{color:var(--studio-text-secondary, #6b7280);flex-shrink:0}&__content{background:var(--studio-bg-primary, white);border-radius:.75rem;width:95vw;height:90vh;max-width:72rem;display:flex;flex-direction:column}&__body{flex:1;overflow:hidden}&__video-container{flex:1;display:flex;align-items:center;justify-content:center;background:#000}&__video{width:100%;height:100%;object-fit:contain}&__image-container{display:flex;align-items:center;justify-content:center;height:100%;padding:1rem;background:var(--studio-bg-secondary, #f9fafb)}&__image{max-width:100%;max-height:100%;object-fit:contain;border-radius:.5rem}&__audio-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;background:var(--studio-bg-secondary, #f9fafb);text-align:center}&__audio-icon-wrapper{width:5rem;height:5rem;border-radius:50%;background:var(--studio-primary-light, #dbeafe);display:flex;align-items:center;justify-content:center;margin-bottom:1rem;color:var(--studio-primary, #3b82f6)}&__audio-title{font-weight:500;color:var(--studio-text-primary, #111827);margin-bottom:1rem}&__audio{width:20rem}&__iframe{width:100%;height:100%;border:none}}\n"] }]
7469
+ }], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }], fileUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileUrl", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], fileType: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileType", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], close: [{ type: i0.Output, args: ["close"] }] } });
7470
+
7235
7471
  class InspectorComponent {
7236
7472
  configService = inject(StudioConfigService);
7237
7473
  componentSize = input('sm', ...(ngDevMode ? [{ debugName: "componentSize" }] : []));
@@ -7441,6 +7677,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7441
7677
  }, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker-compact\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"] }]
7442
7678
  }], ctorParameters: () => [], propDecorators: { componentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentSize", required: false }] }], componentVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentVariant", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showDefaultIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDefaultIndicator", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], expandedByDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedByDefault", required: false }] }], expandedSectionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedSections", required: false }] }], showGroupLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGroupLabels", required: false }] }], groupDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDivider", required: false }] }], groupDividerSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDividerSpacing", required: false }] }], labelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelWidth", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], sectionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionTemplate", required: false }] }], parameterTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterTemplates", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], sectionToggled: [{ type: i0.Output, args: ["sectionToggled"] }], parameterFocused: [{ type: i0.Output, args: ["parameterFocused"] }], parameterBlurred: [{ type: i0.Output, args: ["parameterBlurred"] }] } });
7443
7679
 
7680
+ class LogoComponent {
7681
+ /** URL to navigate when logo is clicked */
7682
+ link = input('/', ...(ngDevMode ? [{ debugName: "link" }] : []));
7683
+ /** Path to logo image */
7684
+ logoSrc = input.required(...(ngDevMode ? [{ debugName: "logoSrc" }] : []));
7685
+ /** Text to display next to logo */
7686
+ logoText = input.required(...(ngDevMode ? [{ debugName: "logoText" }] : []));
7687
+ /** Size variant */
7688
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
7689
+ /** Whether to show text */
7690
+ showText = input(true, ...(ngDevMode ? [{ debugName: "showText" }] : []));
7691
+ /** Whether to show text on mobile devices */
7692
+ showTextOnMobile = input(false, ...(ngDevMode ? [{ debugName: "showTextOnMobile" }] : []));
7693
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: LogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7694
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: LogoComponent, isStandalone: true, selector: "ui-logo", inputs: { link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, logoSrc: { classPropertyName: "logoSrc", publicName: "logoSrc", isSignal: true, isRequired: true, transformFunction: null }, logoText: { classPropertyName: "logoText", publicName: "logoText", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showText: { classPropertyName: "showText", publicName: "showText", isSignal: true, isRequired: false, transformFunction: null }, showTextOnMobile: { classPropertyName: "showTextOnMobile", publicName: "showTextOnMobile", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7695
+ <a
7696
+ class="logo"
7697
+ [class.logo--sm]="size() === 'sm'"
7698
+ [class.logo--md]="size() === 'md'"
7699
+ [class.logo--lg]="size() === 'lg'"
7700
+ [routerLink]="link()"
7701
+ >
7702
+ <img [src]="logoSrc()" alt="Logo" class="logo__image" />
7703
+ @if (showText()) {
7704
+ <span
7705
+ class="logo__text"
7706
+ [class.logo__text--hide-mobile]="!showTextOnMobile()"
7707
+ >
7708
+ {{ logoText() }}
7709
+ </span>
7710
+ }
7711
+ </a>
7712
+ `, isInline: true, styles: [".logo{display:inline-flex;align-items:center;gap:.5rem;text-decoration:none;color:inherit;outline:none}.logo:focus-visible{outline:2px solid var(--ui-focus-ring, currentColor);outline-offset:2px;border-radius:4px}.logo__image{height:2rem;width:auto}.logo--sm .logo__image{height:1.5rem}.logo--lg .logo__image{height:2.5rem}.logo__text{font-weight:600;font-size:1.125rem;white-space:nowrap}.logo--sm .logo__text{font-size:1rem}.logo--lg .logo__text{font-size:1.25rem}@media (max-width: 768px){.logo__text--hide-mobile{display:none}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7713
+ }
7714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: LogoComponent, decorators: [{
7715
+ type: Component,
7716
+ args: [{ selector: 'ui-logo', standalone: true, imports: [RouterLink], template: `
7717
+ <a
7718
+ class="logo"
7719
+ [class.logo--sm]="size() === 'sm'"
7720
+ [class.logo--md]="size() === 'md'"
7721
+ [class.logo--lg]="size() === 'lg'"
7722
+ [routerLink]="link()"
7723
+ >
7724
+ <img [src]="logoSrc()" alt="Logo" class="logo__image" />
7725
+ @if (showText()) {
7726
+ <span
7727
+ class="logo__text"
7728
+ [class.logo__text--hide-mobile]="!showTextOnMobile()"
7729
+ >
7730
+ {{ logoText() }}
7731
+ </span>
7732
+ }
7733
+ </a>
7734
+ `, encapsulation: ViewEncapsulation.Emulated, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".logo{display:inline-flex;align-items:center;gap:.5rem;text-decoration:none;color:inherit;outline:none}.logo:focus-visible{outline:2px solid var(--ui-focus-ring, currentColor);outline-offset:2px;border-radius:4px}.logo__image{height:2rem;width:auto}.logo--sm .logo__image{height:1.5rem}.logo--lg .logo__image{height:2.5rem}.logo__text{font-weight:600;font-size:1.125rem;white-space:nowrap}.logo--sm .logo__text{font-size:1rem}.logo--lg .logo__text{font-size:1.25rem}@media (max-width: 768px){.logo__text--hide-mobile{display:none}}\n"] }]
7735
+ }], propDecorators: { link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], logoSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoSrc", required: true }] }], logoText: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoText", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showText: [{ type: i0.Input, args: [{ isSignal: true, alias: "showText", required: false }] }], showTextOnMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTextOnMobile", required: false }] }] } });
7736
+
7444
7737
  /**
7445
7738
  * Theme toggle switch with sun/moon icons
7446
7739
  *
@@ -8003,5 +8296,5 @@ function hasChildren(block) {
8003
8296
  * Generated bundle index. Do not edit.
8004
8297
  */
8005
8298
 
8006
- export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, COUNTRY_OPTIONS, CardComponent, ChatComponent, ChatInputComponent, ChatMessageComponent, CheckboxComponent, ColorPickerCompactComponent, ColorPickerComponent, ConfirmDialogComponent, ConfirmDialogService, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, DropdownComponent, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, ModalComponent, NavbarComponent, PaginationComponent, PhoneInputComponent, PopoverComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, SignalStore, StudioConfigService, SwitchComponent, TableColumnDirective, TableComponent, TabsComponent, TextareaComponent, ThemeSwitchComponent, ToastComponent, ToastService, TooltipComponent, classNames, hasChildren, isContentBlock, isFormBlock, isInteractiveBlock, isLayoutBlock, isSafeUrl, isStudioBlock, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
8299
+ export { BadgeComponent, BadgeWrapperComponent, BottomNavigationComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, COUNTRY_OPTIONS, CardComponent, ChatComponent, ChatInputComponent, ChatMessageComponent, CheckboxComponent, ColorPickerCompactComponent, ColorPickerComponent, ConfirmDialogComponent, ConfirmDialogService, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, DropdownComponent, FileViewerComponent, IconComponent, InputComponent, InspectorComponent, LogoComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, ModalComponent, NavbarComponent, PaginationComponent, PhoneInputComponent, PopoverComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, SignalStore, StudioConfigService, SwitchComponent, TableColumnDirective, TableComponent, TabsComponent, TextareaComponent, ThemeSwitchComponent, ToastComponent, ToastService, TooltipComponent, classNames, defaultFileViewerLabels, hasChildren, isContentBlock, isFormBlock, isInteractiveBlock, isLayoutBlock, isSafeUrl, isStudioBlock, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
8007
8300
  //# sourceMappingURL=eduboxpro-studio.mjs.map