@praxisui/core 8.0.0-beta.20 → 8.0.0-beta.21

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.
@@ -10,7 +10,7 @@ import { Router, ActivatedRoute } from '@angular/router';
10
10
  import * as i1$1 from '@angular/forms';
11
11
  import { Validators, FormGroup, FormControl, FormArray, FormsModule } from '@angular/forms';
12
12
  import { MatSnackBar } from '@angular/material/snack-bar';
13
- import * as i3$1 from '@angular/material/icon';
13
+ import * as i2$1 from '@angular/material/icon';
14
14
  import { MatIconRegistry, MatIconModule } from '@angular/material/icon';
15
15
  import * as i2 from '@angular/material/button';
16
16
  import { MatButtonModule } from '@angular/material/button';
@@ -22,18 +22,18 @@ import * as i6 from '@angular/material/select';
22
22
  import { MatSelectModule } from '@angular/material/select';
23
23
  import * as i7 from '@angular/material/slide-toggle';
24
24
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
25
- import * as i8 from '@angular/material/tooltip';
25
+ import * as i4 from '@angular/material/tooltip';
26
26
  import { MatTooltipModule } from '@angular/material/tooltip';
27
27
  import { DomSanitizer } from '@angular/platform-browser';
28
- import * as i4 from '@angular/material/menu';
28
+ import * as i4$1 from '@angular/material/menu';
29
29
  import { MatMenuModule } from '@angular/material/menu';
30
- import * as i3$2 from '@angular/material/card';
30
+ import * as i3$1 from '@angular/material/card';
31
31
  import { MatCardModule } from '@angular/material/card';
32
- import * as i8$1 from '@angular/material/chips';
32
+ import * as i8 from '@angular/material/chips';
33
33
  import { MatChipsModule } from '@angular/material/chips';
34
34
  import * as i1$3 from '@angular/material/dialog';
35
35
  import { MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
36
- import * as i2$1 from '@angular/material/tabs';
36
+ import * as i2$2 from '@angular/material/tabs';
37
37
  import { MatTabsModule } from '@angular/material/tabs';
38
38
 
39
39
  class PraxisCore {
@@ -829,6 +829,7 @@ const LOOKUP_OPEN_DETAIL_MODES = new Set([
829
829
  'newTab',
830
830
  'drawer',
831
831
  'modal',
832
+ 'route',
832
833
  ]);
833
834
  const LOOKUP_FILTER_FIELD_TYPES = new Set([
834
835
  'text',
@@ -6357,7 +6358,7 @@ function getGlobalActionUiSchema(id) {
6357
6358
  return GLOBAL_ACTION_UI_SCHEMAS.find((schema) => schema.id === id);
6358
6359
  }
6359
6360
 
6360
- function normalizeGlobalActionRef(ref) {
6361
+ function normalizeGlobalActionRef$1(ref) {
6361
6362
  const actionId = String(ref?.actionId || '').trim();
6362
6363
  if (!actionId)
6363
6364
  return null;
@@ -6445,7 +6446,7 @@ function getGlobalActionPayloadTypeIssue(ref, catalogEntry) {
6445
6446
  function validateGlobalActionRef(ref, catalogEntry, path) {
6446
6447
  if (!ref)
6447
6448
  return [];
6448
- const normalized = normalizeGlobalActionRef(ref);
6449
+ const normalized = normalizeGlobalActionRef$1(ref);
6449
6450
  if (!normalized) {
6450
6451
  return [{ code: 'globalAction.actionId.required', path }];
6451
6452
  }
@@ -6536,7 +6537,7 @@ class GlobalActionService {
6536
6537
  }
6537
6538
  }
6538
6539
  async executeRef(ref, context) {
6539
- const normalized = normalizeGlobalActionRef(ref);
6540
+ const normalized = normalizeGlobalActionRef$1(ref);
6540
6541
  if (!normalized) {
6541
6542
  return { success: false, error: 'Global action ref requires actionId' };
6542
6543
  }
@@ -14610,6 +14611,69 @@ function clampPrecision(value) {
14610
14611
  return Math.floor(value);
14611
14612
  }
14612
14613
 
14614
+ function isPraxisRuntimeGlobalActionEffect(value) {
14615
+ const candidate = value;
14616
+ return (!!candidate &&
14617
+ candidate.kind === 'global-action' &&
14618
+ !!candidate.globalAction &&
14619
+ typeof candidate.globalAction.actionId === 'string' &&
14620
+ candidate.globalAction.actionId.trim().length > 0);
14621
+ }
14622
+ function normalizePraxisEffectPolicy(policy) {
14623
+ return {
14624
+ trigger: policy?.trigger || 'on-condition-enter',
14625
+ ...(policy?.distinct !== undefined ? { distinct: policy.distinct } : {}),
14626
+ ...(policy?.distinctBy ? { distinctBy: policy.distinctBy } : {}),
14627
+ ...(typeof policy?.debounceMs === 'number' ? { debounceMs: policy.debounceMs } : {}),
14628
+ ...(policy?.missingValuePolicy ? { missingValuePolicy: policy.missingValuePolicy } : {}),
14629
+ ...(policy?.errorPolicy ? { errorPolicy: policy.errorPolicy } : {}),
14630
+ ...(policy?.runOnInitialEvaluation !== undefined
14631
+ ? { runOnInitialEvaluation: policy.runOnInitialEvaluation }
14632
+ : {}),
14633
+ };
14634
+ }
14635
+ function buildPraxisEffectDistinctKey(input) {
14636
+ return [
14637
+ input.componentId || 'component',
14638
+ input.ruleId || 'rule',
14639
+ input.effectId || 'effect',
14640
+ input.actionId || 'action',
14641
+ input.contextKey || 'context',
14642
+ input.distinctBy || 'condition',
14643
+ stableSerializePraxisEffectValue(input.value),
14644
+ ].join('|');
14645
+ }
14646
+ function stableSerializePraxisEffectValue(value) {
14647
+ if (value === undefined)
14648
+ return 'undefined';
14649
+ if (value === null)
14650
+ return 'null';
14651
+ if (typeof value !== 'object') {
14652
+ const serialized = JSON.stringify(value);
14653
+ return serialized === undefined ? String(value) : serialized;
14654
+ }
14655
+ try {
14656
+ return JSON.stringify(sortPraxisEffectObject(value));
14657
+ }
14658
+ catch {
14659
+ return String(value);
14660
+ }
14661
+ }
14662
+ function sortPraxisEffectObject(value) {
14663
+ if (Array.isArray(value)) {
14664
+ return value.map((item) => sortPraxisEffectObject(item));
14665
+ }
14666
+ if (!value || typeof value !== 'object') {
14667
+ return value;
14668
+ }
14669
+ return Object.keys(value)
14670
+ .sort()
14671
+ .reduce((acc, key) => {
14672
+ acc[key] = sortPraxisEffectObject(value[key]);
14673
+ return acc;
14674
+ }, {});
14675
+ }
14676
+
14613
14677
  /**
14614
14678
  * Enum que define os tipos de dados (`TYPE`) disponíveis para configuração dos campos de formulário.
14615
14679
  */
@@ -16199,6 +16263,7 @@ const RULE_PROPERTY_SCHEMA = {
16199
16263
  { value: 'end', label: 'Fim' },
16200
16264
  ],
16201
16265
  },
16266
+ { name: 'value', type: 'object', label: 'Valor calculado' },
16202
16267
  { name: 'validators', type: 'object', label: 'Validadores' },
16203
16268
  ],
16204
16269
  section: [
@@ -17388,6 +17453,12 @@ function normalizeEndpoint(endpoint) {
17388
17453
  },
17389
17454
  };
17390
17455
  }
17456
+ if (endpoint.kind === 'global-action') {
17457
+ return {
17458
+ kind: 'global-action',
17459
+ ref: normalizeGlobalActionRef(endpoint.ref),
17460
+ };
17461
+ }
17391
17462
  return {
17392
17463
  kind: 'state',
17393
17464
  ref: {
@@ -17396,6 +17467,14 @@ function normalizeEndpoint(endpoint) {
17396
17467
  },
17397
17468
  };
17398
17469
  }
17470
+ function normalizeGlobalActionRef(ref) {
17471
+ return {
17472
+ actionId: String(ref.actionId || '').trim(),
17473
+ ...(ref.payload !== undefined ? { payload: clone$1(ref.payload) } : {}),
17474
+ ...(ref.payloadExpr ? { payloadExpr: String(ref.payloadExpr).trim() } : {}),
17475
+ ...(ref.meta && typeof ref.meta === 'object' ? { meta: { ...ref.meta } } : {}),
17476
+ };
17477
+ }
17399
17478
  function normalizeNestedPath(nestedPath) {
17400
17479
  if (!nestedPath?.length) {
17401
17480
  return [];
@@ -17496,6 +17575,14 @@ function endpointSortKey(endpoint) {
17496
17575
  JSON.stringify(normalizeNestedPath(endpoint.ref.nestedPath)),
17497
17576
  ].join('|');
17498
17577
  }
17578
+ if (endpoint.kind === 'global-action') {
17579
+ return [
17580
+ endpoint.kind,
17581
+ endpoint.ref.actionId,
17582
+ endpoint.ref.payloadExpr || '',
17583
+ JSON.stringify(endpoint.ref.payload ?? null),
17584
+ ].join('|');
17585
+ }
17499
17586
  return [
17500
17587
  endpoint.kind,
17501
17588
  endpoint.ref.path,
@@ -19134,7 +19221,7 @@ class SurfaceOpenActionEditorComponent {
19134
19221
  </mat-form-field>
19135
19222
  </div>
19136
19223
  </div>
19137
- `, isInline: true, styles: [".surface-editor{display:grid;gap:16px}.surface-section{padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .18));border-radius:10px;background:var(--md-sys-color-surface-container-lowest, #fff)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.surface-section-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #5f6368);margin-bottom:10px}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%}.surface-component-meta{display:grid;gap:4px}.surface-component-title{font-weight:600}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant, #5f6368);font-size:12px}.surface-bindings{display:grid;gap:12px}.surface-binding-row{display:grid;grid-template-columns:minmax(200px,1.2fr) minmax(220px,1.4fr) minmax(140px,.8fr) minmax(180px,1fr) auto;gap:12px;align-items:start}mat-form-field{width:100%}@media(max-width:960px){.surface-binding-row{grid-template-columns:minmax(0,1fr)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
19224
+ `, isInline: true, styles: [".surface-editor{display:grid;gap:16px}.surface-section{padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .18));border-radius:10px;background:var(--md-sys-color-surface-container-lowest, #fff)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.surface-section-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #5f6368);margin-bottom:10px}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%}.surface-component-meta{display:grid;gap:4px}.surface-component-title{font-weight:600}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant, #5f6368);font-size:12px}.surface-bindings{display:grid;gap:12px}.surface-binding-row{display:grid;grid-template-columns:minmax(200px,1.2fr) minmax(220px,1.4fr) minmax(140px,.8fr) minmax(180px,1fr) auto;gap:12px;align-items:start}mat-form-field{width:100%}@media(max-width:960px){.surface-binding-row{grid-template-columns:minmax(0,1fr)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
19138
19225
  }
19139
19226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceOpenActionEditorComponent, decorators: [{
19140
19227
  type: Component,
@@ -20529,7 +20616,7 @@ const CAPS = [
20529
20616
  { path: 'page.state.derived.<token>.cache', category: 'state', valueKind: 'boolean', description: 'Permite cache futuro do valor derivado.' },
20530
20617
  { path: 'page.composition', category: 'connections', valueKind: 'object', description: 'Envelope canonico da composicao persistida.' },
20531
20618
  { path: 'page.composition.version', category: 'connections', valueKind: 'string', description: 'Versao do envelope de composicao.' },
20532
- { path: 'page.composition.links', category: 'connections', valueKind: 'array', description: 'Links canonicos entre widgets e estado.' },
20619
+ { path: 'page.composition.links', category: 'connections', valueKind: 'array', description: 'Links canonicos entre widgets, estado e actions globais.' },
20533
20620
  { path: 'page.composition.links[].id', category: 'connections', valueKind: 'string', description: 'Identificador estavel do link.' },
20534
20621
  { path: 'page.composition.links[].from', category: 'connections', valueKind: 'object', description: 'Endpoint de origem do link.' },
20535
20622
  { path: 'page.composition.links[].from.kind', category: 'connections', valueKind: 'string', description: 'Tipo do endpoint de origem, como component-port ou state.' },
@@ -20544,8 +20631,11 @@ const CAPS = [
20544
20631
  { path: 'page.composition.links[].from.ref.nestedPath[].index', category: 'connections', valueKind: 'number', description: 'Indice auxiliar para diagnostico visual; nao use como identidade primaria.' },
20545
20632
  { path: 'page.composition.links[].from.ref.nestedPath[].componentType', category: 'connections', valueKind: 'string', description: 'Tipo do componente real do widget filho de origem.' },
20546
20633
  { path: 'page.composition.links[].to', category: 'connections', valueKind: 'object', description: 'Endpoint de destino do link.' },
20547
- { path: 'page.composition.links[].to.kind', category: 'connections', valueKind: 'string', description: 'Tipo do endpoint de destino, como component-port ou state.' },
20634
+ { path: 'page.composition.links[].to.kind', category: 'connections', valueKind: 'string', description: 'Tipo do endpoint de destino, como component-port, state ou global-action.' },
20548
20635
  { path: 'page.composition.links[].to.ref', category: 'connections', valueKind: 'object', description: 'Referencia estruturada do endpoint de destino.' },
20636
+ { path: 'page.composition.links[].to.ref.[actionId]', category: 'connections', valueKind: 'string', description: 'ID da action global quando to.kind = global-action.' },
20637
+ { path: 'page.composition.links[].to.ref.payload', category: 'connections', valueKind: 'object', description: 'Payload fixo opcional da action global; quando omitido, o runtime entrega o valor transformado do link.' },
20638
+ { path: 'page.composition.links[].to.ref.payloadExpr', category: 'connections', valueKind: 'expression', description: 'Expressao opcional de payload da action global suportada pelo GlobalActionService.' },
20549
20639
  { path: 'page.composition.links[].to.ref.widget', category: 'connections', valueKind: 'string', description: 'Widget top-level dono do endpoint de destino.' },
20550
20640
  { path: 'page.composition.links[].to.ref.port', category: 'connections', valueKind: 'string', description: 'Porta de destino do componente.' },
20551
20641
  { path: 'page.composition.links[].to.ref.direction', category: 'connections', valueKind: 'string', description: 'Direcao da porta de destino.' },
@@ -20772,7 +20862,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
20772
20862
  requiresExistingTarget: true,
20773
20863
  scope: 'ROW',
20774
20864
  params: [
20775
- { name: 'linkId', type: 'STRING' },
20865
+ { name: 'id', type: 'STRING' },
20776
20866
  ],
20777
20867
  patchTemplate: {
20778
20868
  page: {
@@ -20781,7 +20871,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
20781
20871
  links: [
20782
20872
  {
20783
20873
  _beforeKey: '{{target}}',
20784
- id: '{{params.linkId}}',
20874
+ id: '{{params.id}}',
20785
20875
  _remove: true,
20786
20876
  },
20787
20877
  ],
@@ -22329,7 +22419,7 @@ class PraxisRichTextBlockComponent {
22329
22419
 
22330
22420
  <div class="prt-content" [innerHTML]="renderedContent"></div>
22331
22421
  </section>
22332
- `, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22422
+ `, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
22333
22423
  }
22334
22424
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisRichTextBlockComponent, decorators: [{
22335
22425
  type: Component,
@@ -23620,7 +23710,7 @@ class WidgetShellComponent {
23620
23710
  @if (expanded || fullscreen) {
23621
23711
  <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
23622
23712
  }
23623
- `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;top:50%;left:50%;width:95vw;height:95vh;transform:translate(-50%,-50%);z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
23713
+ `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;top:50%;left:50%;width:95vw;height:95vh;transform:translate(-50%,-50%);z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
23624
23714
  }
23625
23715
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellComponent, decorators: [{
23626
23716
  type: Component,
@@ -24673,187 +24763,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
24673
24763
  args: [{ providedIn: 'root' }]
24674
24764
  }], ctorParameters: () => [{ type: PraxisJsonLogicService }] });
24675
24765
 
24676
- class CompositionRuntimeStore {
24677
- snapshot;
24678
- listeners = new Set();
24679
- constructor(init) {
24680
- this.snapshot = freezeSnapshot(createSnapshot(init));
24681
- }
24682
- getSnapshot() {
24683
- return this.snapshot;
24684
- }
24685
- subscribe(listener) {
24686
- this.listeners.add(listener);
24687
- listener(this.snapshot);
24688
- return () => {
24689
- this.listeners.delete(listener);
24690
- };
24691
- }
24692
- reset(init) {
24693
- this.snapshot = freezeSnapshot(createSnapshot(init));
24694
- this.emit();
24695
- return this.snapshot;
24696
- }
24697
- applyCycle(update) {
24698
- const nextState = update.stateSnapshot
24699
- ? cloneStateSnapshot$1(update.stateSnapshot)
24700
- : applyStatePatch(this.snapshot.state, update);
24701
- const nextLinks = applyLinkPatches(this.snapshot.links, update.linkPatches);
24702
- this.snapshot = freezeSnapshot({
24703
- pageId: this.snapshot.pageId,
24704
- status: update.status ?? this.snapshot.status,
24705
- generatedAt: update.generatedAt ?? this.snapshot.generatedAt,
24706
- links: nextLinks,
24707
- state: nextState,
24708
- diagnostics: cloneDiagnostics$1(update.diagnostics ?? this.snapshot.diagnostics),
24709
- traceTail: cloneTraceTail(update.traceTail ?? this.snapshot.traceTail),
24710
- });
24711
- this.emit();
24712
- return this.snapshot;
24713
- }
24714
- emit() {
24715
- for (const listener of this.listeners) {
24716
- listener(this.snapshot);
24717
- }
24718
- }
24719
- }
24720
- function createSnapshot(init) {
24721
- return {
24722
- pageId: init?.pageId,
24723
- status: init?.status ?? 'booting',
24724
- generatedAt: init?.generatedAt ?? new Date(0).toISOString(),
24725
- links: cloneLinks(init?.links ?? []),
24726
- state: {
24727
- primaryValues: cloneRecord$1(init?.state?.primaryValues),
24728
- derivedValues: cloneRecord$1(init?.state?.derivedValues),
24729
- transientValues: init?.state?.transientValues
24730
- ? cloneRecord$1(init.state.transientValues)
24731
- : undefined,
24732
- changedPaths: init?.state?.changedPaths ? [...init.state.changedPaths] : [],
24733
- diagnostics: cloneDiagnostics$1(init?.state?.diagnostics ?? []),
24734
- },
24735
- diagnostics: cloneDiagnostics$1(init?.diagnostics ?? []),
24736
- traceTail: cloneTraceTail(init?.traceTail ?? []),
24737
- };
24738
- }
24739
- function applyStatePatch(current, update) {
24740
- return {
24741
- primaryValues: {
24742
- ...current.primaryValues,
24743
- ...cloneRecord$1(update.primaryValuesPatch),
24744
- },
24745
- derivedValues: {
24746
- ...current.derivedValues,
24747
- ...cloneRecord$1(update.derivedValuesPatch),
24748
- },
24749
- transientValues: mergeTransientValues(current.transientValues, update.transientValuesPatch),
24750
- changedPaths: update.changedPaths ? [...update.changedPaths] : [...(current.changedPaths ?? [])],
24751
- diagnostics: cloneDiagnostics$1(current.diagnostics),
24752
- };
24753
- }
24754
- function cloneStateSnapshot$1(state) {
24755
- return {
24756
- primaryValues: cloneRecord$1(state.primaryValues),
24757
- derivedValues: cloneRecord$1(state.derivedValues),
24758
- transientValues: state.transientValues ? cloneRecord$1(state.transientValues) : undefined,
24759
- changedPaths: state.changedPaths ? [...state.changedPaths] : [],
24760
- diagnostics: cloneDiagnostics$1(state.diagnostics),
24761
- };
24762
- }
24763
- function mergeTransientValues(current, patch) {
24764
- if (!current && !patch) {
24765
- return undefined;
24766
- }
24767
- return {
24768
- ...cloneRecord$1(current),
24769
- ...cloneRecord$1(patch),
24770
- };
24771
- }
24772
- function applyLinkPatches(current, patches) {
24773
- const patchMap = new Map((patches ?? []).map((patch) => [patch.linkId, patch]));
24774
- return current.map((link) => {
24775
- const patch = patchMap.get(link.linkId);
24776
- if (!patch) {
24777
- return cloneLink(link);
24778
- }
24779
- const next = cloneLink(link);
24780
- next.status = patch.status ?? link.status;
24781
- setOptionalLinkValue(next, 'lastEventAt', pickPatchedValue(patch, 'lastEventAt', link.lastEventAt));
24782
- setOptionalLinkValue(next, 'lastDispatchTraceId', pickPatchedValue(patch, 'lastDispatchTraceId', link.lastDispatchTraceId));
24783
- setOptionalLinkValue(next, 'lastDeliveredValuePreview', pickPatchedValue(patch, 'lastDeliveredValuePreview', link.lastDeliveredValuePreview));
24784
- next.diagnostics = cloneDiagnostics$1(patch.diagnostics ?? link.diagnostics);
24785
- return next;
24786
- });
24787
- }
24788
- function pickPatchedValue(patch, key, fallback) {
24789
- return Object.prototype.hasOwnProperty.call(patch, key)
24790
- ? patch[key]
24791
- : fallback;
24792
- }
24793
- function cloneLinks(links) {
24794
- return links.map((link) => cloneLink(link));
24795
- }
24796
- function cloneLink(link) {
24797
- const next = {
24798
- linkId: link.linkId,
24799
- status: link.status,
24800
- source: { ...link.source },
24801
- target: { ...link.target },
24802
- diagnostics: cloneDiagnostics$1(link.diagnostics),
24803
- };
24804
- setOptionalLinkValue(next, 'lastEventAt', link.lastEventAt);
24805
- setOptionalLinkValue(next, 'lastDispatchTraceId', link.lastDispatchTraceId);
24806
- setOptionalLinkValue(next, 'lastDeliveredValuePreview', link.lastDeliveredValuePreview);
24807
- return next;
24808
- }
24809
- function setOptionalLinkValue(link, key, value) {
24810
- if (value === undefined) {
24811
- delete link[key];
24812
- return;
24813
- }
24814
- link[key] = value;
24815
- }
24816
- function cloneDiagnostics$1(diagnostics) {
24817
- return diagnostics.map((diagnostic) => ({
24818
- ...diagnostic,
24819
- subject: { ...diagnostic.subject },
24820
- related: diagnostic.related?.map((item) => ({ ...item })),
24821
- details: diagnostic.details ? { ...diagnostic.details } : undefined,
24822
- }));
24823
- }
24824
- function cloneTraceTail(traceTail) {
24825
- return traceTail.map((entry) => ({
24826
- ...entry,
24827
- subject: { ...entry.subject },
24828
- payloadSummary: entry.payloadSummary
24829
- ? {
24830
- ...entry.payloadSummary,
24831
- keys: entry.payloadSummary.keys ? [...entry.payloadSummary.keys] : undefined,
24832
- }
24833
- : undefined,
24834
- details: entry.details ? { ...entry.details } : undefined,
24835
- diagnostics: entry.diagnostics ? [...entry.diagnostics] : undefined,
24836
- }));
24837
- }
24838
- function cloneRecord$1(value) {
24839
- return value ? { ...value } : {};
24840
- }
24841
- function freezeSnapshot(snapshot) {
24842
- return deepFreeze(snapshot);
24843
- }
24844
- function deepFreeze(value) {
24845
- if (!value || typeof value !== 'object' || Object.isFrozen(value)) {
24846
- return value;
24847
- }
24848
- Object.freeze(value);
24849
- for (const nested of Object.values(value)) {
24850
- if (nested && typeof nested === 'object') {
24851
- deepFreeze(nested);
24852
- }
24853
- }
24854
- return value;
24855
- }
24856
-
24857
24766
  const TRANSFORM_CATALOG = [
24858
24767
  {
24859
24768
  kind: 'identity',
@@ -24954,39 +24863,638 @@ function isSupportedTransformKind(kind) {
24954
24863
  return TRANSFORM_CATALOG_MAP.has(kind);
24955
24864
  }
24956
24865
 
24957
- const DEFAULT_PATH_ACCESSOR$1 = new ConnectionManagerService();
24958
- const DEFAULT_TEMPLATE_RESOLVER = new SurfaceBindingRuntimeService();
24959
- const DEFAULT_JSON_LOGIC$1 = new PraxisJsonLogicService(null);
24960
- const TRANSFORM_RULE_OPTIONS = {
24961
- availableRoots: ['event', 'payload', 'state', 'context', 'source'],
24962
- defaultRoot: 'source',
24963
- allowImplicitRoot: true,
24964
- };
24965
- class TransformRuntimeService {
24966
- pathAccessor;
24967
- templateResolver;
24968
- jsonLogic;
24969
- constructor(pathAccessor = DEFAULT_PATH_ACCESSOR$1, templateResolver = DEFAULT_TEMPLATE_RESOLVER, jsonLogic = DEFAULT_JSON_LOGIC$1) {
24970
- this.pathAccessor = pathAccessor;
24971
- this.templateResolver = templateResolver;
24972
- this.jsonLogic = jsonLogic;
24866
+ class NestedPortCatalogService {
24867
+ accessor;
24868
+ constructor(accessor = new NestedWidgetConfigAccessor()) {
24869
+ this.accessor = accessor;
24973
24870
  }
24974
- executePipeline(pipeline, runtime) {
24871
+ resolve(page, registry) {
24872
+ const ports = [];
24975
24873
  const diagnostics = [];
24976
- const env = this.buildEnvironment(runtime);
24977
- let current = this.resolvePipelineSeed(pipeline, env);
24978
- for (const [index, step] of pipeline.steps.entries()) {
24979
- try {
24980
- if (!this.matchesStepCondition(step.when, env)) {
24981
- continue;
24982
- }
24983
- if (!isSupportedTransformKind(step.kind)) {
24984
- diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_UNSUPPORTED', `O transform ${step.kind} ainda nao e suportado pelo runtime da Wave 1.`, {
24985
- kind: 'transform-step',
24986
- transformIndex: index,
24987
- label: step.id,
24988
- }, { transformKind: step.kind, pipelineId: pipeline.id, stepId: step.id }, undefined, 'unsupported-kind'));
24989
- continue;
24874
+ for (const owner of page.widgets || []) {
24875
+ const nestedWidgets = this.accessor.listNestedWidgets(owner);
24876
+ for (const nested of nestedWidgets) {
24877
+ if (!this.hasStableTerminalKey(nested.nestedPath)) {
24878
+ diagnostics.push({
24879
+ code: 'NESTED_WIDGET_KEY_MISSING',
24880
+ severity: 'error',
24881
+ ownerWidgetKey: owner.key,
24882
+ nestedPath: this.clone(nested.nestedPath),
24883
+ componentId: nested.componentId,
24884
+ message: `Nested widget inside '${owner.key}' must declare a stable childWidgetKey.`,
24885
+ });
24886
+ continue;
24887
+ }
24888
+ const meta = registry.get(nested.componentId);
24889
+ if (!meta?.ports?.length) {
24890
+ diagnostics.push({
24891
+ code: 'NESTED_WIDGET_METADATA_MISSING',
24892
+ severity: 'warning',
24893
+ ownerWidgetKey: owner.key,
24894
+ nestedPath: this.clone(nested.nestedPath),
24895
+ componentId: nested.componentId,
24896
+ message: `No component metadata ports found for nested widget '${nested.componentId}'.`,
24897
+ });
24898
+ continue;
24899
+ }
24900
+ for (const port of meta.ports) {
24901
+ ports.push({
24902
+ ownerWidgetKey: owner.key,
24903
+ ownerComponentId: owner.definition.id,
24904
+ nestedPath: this.clone(nested.nestedPath),
24905
+ containerPath: this.containerPath(nested.nestedPath),
24906
+ port: this.clone(port),
24907
+ componentId: nested.componentId,
24908
+ childWidgetKey: nested.childWidgetKey,
24909
+ });
24910
+ }
24911
+ }
24912
+ }
24913
+ return { ports, diagnostics };
24914
+ }
24915
+ resolveEndpoint(page, registry, options) {
24916
+ return this.resolve(page, registry).ports.find((port) => port.ownerWidgetKey === options.ownerWidgetKey
24917
+ && port.port.id === options.portId
24918
+ && port.port.direction === options.direction
24919
+ && this.isSamePath(port.nestedPath, options.nestedPath));
24920
+ }
24921
+ hasStableTerminalKey(nestedPath) {
24922
+ const terminal = nestedPath[nestedPath.length - 1];
24923
+ return terminal?.kind === 'widget'
24924
+ && typeof terminal.key === 'string'
24925
+ && terminal.key.trim().length > 0;
24926
+ }
24927
+ containerPath(nestedPath) {
24928
+ return nestedPath.slice(0, -1).map((segment) => this.clone(segment));
24929
+ }
24930
+ isSamePath(left, right) {
24931
+ return JSON.stringify(left) === JSON.stringify(right);
24932
+ }
24933
+ clone(value) {
24934
+ if (value == null || typeof value !== 'object') {
24935
+ return value;
24936
+ }
24937
+ return JSON.parse(JSON.stringify(value));
24938
+ }
24939
+ }
24940
+
24941
+ const COMPOSITION_RULE_ROOTS$1 = ['source', 'event', 'payload', 'state', 'context', 'meta'];
24942
+ const COMPATIBLE_TARGET_KINDS = {
24943
+ event: ['event'],
24944
+ value: ['value', 'selection', 'query-context', 'view-context', 'config-fragment'],
24945
+ selection: ['selection', 'value'],
24946
+ collection: ['collection'],
24947
+ 'query-context': ['query-context', 'value'],
24948
+ 'view-context': ['view-context', 'value'],
24949
+ 'config-fragment': ['config-fragment', 'value'],
24950
+ status: ['status', 'value'],
24951
+ diagnostic: ['diagnostic'],
24952
+ };
24953
+ class CompositionValidatorService {
24954
+ nestedPortCatalog;
24955
+ jsonLogic;
24956
+ constructor(nestedPortCatalog = new NestedPortCatalogService(), jsonLogic = new PraxisJsonLogicService(null)) {
24957
+ this.nestedPortCatalog = nestedPortCatalog;
24958
+ this.jsonLogic = jsonLogic;
24959
+ }
24960
+ validateLink(link, context = {}) {
24961
+ const diagnostics = [];
24962
+ this.validateEndpointDirections(link, diagnostics);
24963
+ this.validateNestedComponentEndpoints(link, diagnostics);
24964
+ this.validateNestedPortCatalog(link, diagnostics, context);
24965
+ this.validateNestedWidgetEventCoexistence(link, diagnostics, context);
24966
+ this.validateBindingPathBridge(link, diagnostics);
24967
+ this.validateStateWrites(link, diagnostics);
24968
+ this.validateGlobalActionTarget(link, diagnostics);
24969
+ this.validateCondition(link, diagnostics);
24970
+ this.validateTransformCatalog(link, diagnostics);
24971
+ this.validateSemanticCompatibility(link, diagnostics);
24972
+ return diagnostics;
24973
+ }
24974
+ validateEndpointDirections(link, diagnostics) {
24975
+ if (link.from.kind === 'component-port' && link.from.ref.direction !== 'output') {
24976
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_PORT_DIRECTION_INVALID_SOURCE', 'error', `A origem do link ${link.id} precisa apontar para uma porta de saida.`, {
24977
+ kind: 'port',
24978
+ widgetKey: link.from.ref.widget,
24979
+ widgetType: link.from.ref.componentType,
24980
+ portId: link.from.ref.port,
24981
+ linkId: link.id,
24982
+ }, { expectedDirection: 'output', actualDirection: link.from.ref.direction }));
24983
+ }
24984
+ if (link.to.kind === 'component-port' && link.to.ref.direction !== 'input') {
24985
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_PORT_DIRECTION_INVALID_TARGET', 'error', `O destino do link ${link.id} precisa apontar para uma porta de entrada.`, {
24986
+ kind: 'port',
24987
+ widgetKey: link.to.ref.widget,
24988
+ widgetType: link.to.ref.componentType,
24989
+ portId: link.to.ref.port,
24990
+ linkId: link.id,
24991
+ }, { expectedDirection: 'input', actualDirection: link.to.ref.direction }));
24992
+ }
24993
+ }
24994
+ validateBindingPathBridge(link, diagnostics) {
24995
+ const componentEndpoints = [link.from, link.to].filter((endpoint) => endpoint.kind === 'component-port');
24996
+ for (const endpoint of componentEndpoints) {
24997
+ if (!endpoint.ref.bindingPath || endpoint.ref.nestedPath?.length) {
24998
+ continue;
24999
+ }
25000
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_BINDING_PATH_BRIDGE', 'warning', `O link ${link.id} ainda depende de bindingPath como bridge temporaria.`, {
25001
+ kind: 'port',
25002
+ widgetKey: endpoint.ref.widget,
25003
+ widgetType: endpoint.ref.componentType,
25004
+ portId: endpoint.ref.port,
25005
+ linkId: link.id,
25006
+ path: endpoint.ref.bindingPath,
25007
+ }, { bindingPath: endpoint.ref.bindingPath }, false));
25008
+ }
25009
+ }
25010
+ validateNestedComponentEndpoints(link, diagnostics) {
25011
+ const componentEndpoints = [link.from, link.to].filter((endpoint) => endpoint.kind === 'component-port');
25012
+ for (const endpoint of componentEndpoints) {
25013
+ const nestedPath = endpoint.ref.nestedPath || [];
25014
+ if (!nestedPath.length) {
25015
+ continue;
25016
+ }
25017
+ const terminal = nestedPath[nestedPath.length - 1];
25018
+ if (terminal?.kind !== 'widget'
25019
+ || typeof terminal.key !== 'string'
25020
+ || terminal.key.trim().length === 0) {
25021
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_PORT_TERMINAL_WIDGET_KEY_REQUIRED', 'error', `O endpoint nested do link ${link.id} precisa terminar em widget.key estavel.`, {
25022
+ kind: 'port',
25023
+ widgetKey: endpoint.ref.widget,
25024
+ widgetType: endpoint.ref.componentType,
25025
+ portId: endpoint.ref.port,
25026
+ linkId: link.id,
25027
+ path: this.formatNestedPath(nestedPath),
25028
+ }, { nestedPath }));
25029
+ }
25030
+ if (!endpoint.ref.bindingPath) {
25031
+ continue;
25032
+ }
25033
+ const isLegacyLink = link.metadata?.source === 'legacy-widget-connection';
25034
+ diagnostics.push(this.createDiagnostic(link, isLegacyLink
25035
+ ? 'SEMANTIC_NESTED_BINDING_PATH_LEGACY_BRIDGE'
25036
+ : 'SEMANTIC_NESTED_BINDING_PATH_CONFLICT', isLegacyLink ? 'warning' : 'error', isLegacyLink
25037
+ ? `O link legado ${link.id} mantem bindingPath junto de nestedPath durante migracao.`
25038
+ : `O link ${link.id} nao pode combinar bindingPath com nestedPath.`, {
25039
+ kind: 'port',
25040
+ widgetKey: endpoint.ref.widget,
25041
+ widgetType: endpoint.ref.componentType,
25042
+ portId: endpoint.ref.port,
25043
+ linkId: link.id,
25044
+ path: this.formatNestedPath(nestedPath),
25045
+ }, {
25046
+ bindingPath: endpoint.ref.bindingPath,
25047
+ nestedPath,
25048
+ }, !isLegacyLink));
25049
+ }
25050
+ }
25051
+ validateNestedPortCatalog(link, diagnostics, context) {
25052
+ if (!context.page || !context.registry) {
25053
+ return;
25054
+ }
25055
+ const catalog = this.nestedPortCatalog.resolve(context.page, context.registry);
25056
+ const componentEndpoints = [link.from, link.to].filter((endpoint) => endpoint.kind === 'component-port' && !!endpoint.ref.nestedPath?.length);
25057
+ for (const endpoint of componentEndpoints) {
25058
+ const nestedPath = endpoint.ref.nestedPath || [];
25059
+ const terminal = nestedPath[nestedPath.length - 1];
25060
+ if (terminal?.kind !== 'widget' || !terminal.key?.trim()) {
25061
+ continue;
25062
+ }
25063
+ const ownerExists = (context.page.widgets || []).some((widget) => widget.key === endpoint.ref.widget);
25064
+ if (!ownerExists) {
25065
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_OWNER_WIDGET_MISSING', 'error', `O owner top-level ${endpoint.ref.widget} do endpoint nested do link ${link.id} nao existe.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25066
+ ownerWidgetKey: endpoint.ref.widget,
25067
+ nestedPath,
25068
+ }));
25069
+ continue;
25070
+ }
25071
+ this.projectCatalogDiagnostics(link, endpoint, nestedPath, catalog, diagnostics);
25072
+ const matchingPathPorts = catalog.ports.filter((port) => port.ownerWidgetKey === endpoint.ref.widget
25073
+ && this.isSameNestedPath(port.nestedPath, nestedPath));
25074
+ if (!matchingPathPorts.length) {
25075
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_WIDGET_MISSING', 'error', `O nestedPath do link ${link.id} nao resolve um widget interno conectavel.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25076
+ ownerWidgetKey: endpoint.ref.widget,
25077
+ nestedPath,
25078
+ }));
25079
+ continue;
25080
+ }
25081
+ const samePort = matchingPathPorts.filter((port) => port.port.id === endpoint.ref.port);
25082
+ if (!samePort.length) {
25083
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_PORT_MISSING', 'error', `A porta nested ${endpoint.ref.port} do link ${link.id} nao existe no componente filho.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25084
+ ownerWidgetKey: endpoint.ref.widget,
25085
+ nestedPath,
25086
+ portId: endpoint.ref.port,
25087
+ availablePorts: matchingPathPorts.map((port) => port.port.id),
25088
+ }));
25089
+ continue;
25090
+ }
25091
+ const resolved = samePort.find((port) => port.port.direction === endpoint.ref.direction);
25092
+ if (!resolved) {
25093
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_PORT_DIRECTION_MISMATCH', 'error', `A porta nested ${endpoint.ref.port} do link ${link.id} existe, mas com direcao diferente.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25094
+ ownerWidgetKey: endpoint.ref.widget,
25095
+ nestedPath,
25096
+ portId: endpoint.ref.port,
25097
+ expectedDirection: endpoint.ref.direction,
25098
+ availableDirections: samePort.map((port) => port.port.direction),
25099
+ }));
25100
+ continue;
25101
+ }
25102
+ if (endpoint.ref.componentType && endpoint.ref.componentType !== resolved.componentId) {
25103
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_COMPONENT_TYPE_MISMATCH', 'error', `O componentType do endpoint nested do link ${link.id} nao corresponde ao componente filho resolvido.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25104
+ ownerWidgetKey: endpoint.ref.widget,
25105
+ nestedPath,
25106
+ expectedComponentType: endpoint.ref.componentType,
25107
+ actualComponentType: resolved.componentId,
25108
+ }));
25109
+ }
25110
+ }
25111
+ }
25112
+ projectCatalogDiagnostics(link, endpoint, nestedPath, catalog, diagnostics) {
25113
+ for (const diagnostic of catalog.diagnostics) {
25114
+ if (diagnostic.ownerWidgetKey !== endpoint.ref.widget
25115
+ || !this.isSameNestedPath(diagnostic.nestedPath, nestedPath)) {
25116
+ continue;
25117
+ }
25118
+ diagnostics.push(this.createDiagnostic(link, diagnostic.code === 'NESTED_WIDGET_KEY_MISSING'
25119
+ ? 'SEMANTIC_NESTED_WIDGET_KEY_MISSING'
25120
+ : 'SEMANTIC_NESTED_WIDGET_METADATA_MISSING', diagnostic.severity, diagnostic.message, this.nestedEndpointSubject(link, endpoint, nestedPath), {
25121
+ ownerWidgetKey: endpoint.ref.widget,
25122
+ nestedPath,
25123
+ componentId: diagnostic.componentId,
25124
+ }, diagnostic.severity === 'error'));
25125
+ }
25126
+ }
25127
+ validateNestedWidgetEventCoexistence(link, diagnostics, context) {
25128
+ if (link.from.kind !== 'component-port'
25129
+ || link.from.ref.direction !== 'output'
25130
+ || !link.from.ref.nestedPath?.length
25131
+ || link.from.ref.port === 'widgetEvent'
25132
+ || !context.links?.length) {
25133
+ return;
25134
+ }
25135
+ const sourceRef = link.from.ref;
25136
+ const legacyLinks = context.links.filter((candidate) => candidate.id !== link.id
25137
+ && candidate.from.kind === 'component-port'
25138
+ && candidate.from.ref.widget === sourceRef.widget
25139
+ && candidate.from.ref.port === 'widgetEvent'
25140
+ && candidate.from.ref.direction === 'output'
25141
+ && !candidate.from.ref.nestedPath?.length);
25142
+ if (!legacyLinks.length) {
25143
+ return;
25144
+ }
25145
+ const nestedPath = sourceRef.nestedPath || [];
25146
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_WIDGET_EVENT_BRIDGE_COEXISTS', 'warning', `O link nested ${link.id} coexiste com link legado owner.widgetEvent no mesmo owner; o runtime deduplica, mas a composicao deve migrar para nestedPath canonico.`, this.nestedEndpointSubject(link, link.from, nestedPath), {
25147
+ ownerWidgetKey: sourceRef.widget,
25148
+ portId: sourceRef.port,
25149
+ nestedPath,
25150
+ legacyLinkIds: legacyLinks.map((candidate) => candidate.id),
25151
+ }, false));
25152
+ }
25153
+ validateStateWrites(link, diagnostics) {
25154
+ if (link.to.kind !== 'state') {
25155
+ return;
25156
+ }
25157
+ const layer = link.to.ref.layer || 'values';
25158
+ const writable = link.to.ref.writable ?? layer !== 'derived';
25159
+ if (layer === 'derived' || !writable) {
25160
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_STATE_WRITE_INVALID', 'error', `O link ${link.id} nao pode escrever no state ${link.to.ref.path}.`, {
25161
+ kind: layer === 'derived' ? 'derived-state' : 'state',
25162
+ statePath: link.to.ref.path,
25163
+ linkId: link.id,
25164
+ }, { layer, writable }));
25165
+ }
25166
+ }
25167
+ validateGlobalActionTarget(link, diagnostics) {
25168
+ if (link.to.kind !== 'global-action') {
25169
+ return;
25170
+ }
25171
+ const issues = validateGlobalActionRef(link.to.ref, null, 'to.ref');
25172
+ for (const issue of issues) {
25173
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_GLOBAL_ACTION_TARGET_INVALID', 'error', `O destino global-action do link ${link.id} esta invalido.`, {
25174
+ kind: 'global-action',
25175
+ actionId: issue.actionId || link.to.ref.actionId,
25176
+ linkId: link.id,
25177
+ path: issue.path,
25178
+ }, { issue }));
25179
+ }
25180
+ }
25181
+ validateCondition(link, diagnostics) {
25182
+ if (!link.condition) {
25183
+ return;
25184
+ }
25185
+ const result = this.jsonLogic.validateResult(link.condition, {
25186
+ availableRoots: [...COMPOSITION_RULE_ROOTS$1],
25187
+ defaultRoot: null,
25188
+ allowImplicitRoot: false,
25189
+ requireExpressionObject: true,
25190
+ });
25191
+ for (const issue of result.issues) {
25192
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_LINK_CONDITION_INVALID', 'error', `A condicao Json Logic do link ${link.id} esta invalida.`, {
25193
+ kind: 'link',
25194
+ linkId: link.id,
25195
+ path: `condition${issue.path === '$' ? '' : issue.path.slice(1)}`,
25196
+ }, { issue }));
25197
+ }
25198
+ }
25199
+ validateTransformCatalog(link, diagnostics) {
25200
+ for (const [index, step] of (link.transform?.steps || []).entries()) {
25201
+ if (getTransformCatalogEntry(step.kind)) {
25202
+ continue;
25203
+ }
25204
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_TRANSFORM_UNSUPPORTED', 'error', `O transform ${step.kind} nao pertence ao catalogo inicial suportado da Fase 2A.`, {
25205
+ kind: 'transform-step',
25206
+ linkId: link.id,
25207
+ transformIndex: index,
25208
+ label: step.id,
25209
+ }, { transformKind: step.kind }));
25210
+ }
25211
+ }
25212
+ validateSemanticCompatibility(link, diagnostics) {
25213
+ const sourceKind = this.endpointSemanticKind(link.from);
25214
+ const targetKind = this.endpointSemanticKind(link.to);
25215
+ if (!sourceKind || !targetKind) {
25216
+ return;
25217
+ }
25218
+ if (this.areSemanticKindsCompatible(sourceKind, targetKind, link.transform)) {
25219
+ return;
25220
+ }
25221
+ if (!link.transform?.steps?.length) {
25222
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_TRANSFORM_REQUIRED', 'error', `O link ${link.id} exige transform explicita para converter ${sourceKind} em ${targetKind}.`, {
25223
+ kind: 'link',
25224
+ linkId: link.id,
25225
+ }, { sourceKind, targetKind }));
25226
+ return;
25227
+ }
25228
+ diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_KIND_INCOMPATIBLE', 'error', `O link ${link.id} continua semanticamente incompativel mesmo com transform declarada.`, {
25229
+ kind: 'link',
25230
+ linkId: link.id,
25231
+ }, {
25232
+ sourceKind,
25233
+ targetKind,
25234
+ transformOutputKind: link.transform.output?.semanticKind,
25235
+ transformKinds: link.transform.steps.map((step) => step.kind),
25236
+ }));
25237
+ }
25238
+ endpointSemanticKind(endpoint) {
25239
+ return endpoint.ref.semanticKind;
25240
+ }
25241
+ areSemanticKindsCompatible(sourceKind, targetKind, transform) {
25242
+ const transformOutputKind = transform?.output?.semanticKind;
25243
+ if (transformOutputKind) {
25244
+ return this.areKindsDirectlyCompatible(transformOutputKind, targetKind);
25245
+ }
25246
+ return this.areKindsDirectlyCompatible(sourceKind, targetKind);
25247
+ }
25248
+ areKindsDirectlyCompatible(sourceKind, targetKind) {
25249
+ return (COMPATIBLE_TARGET_KINDS[sourceKind] || []).includes(targetKind);
25250
+ }
25251
+ createDiagnostic(link, code, severity, message, subject, details, blocking = true) {
25252
+ return {
25253
+ id: `${link.id}:${code}`,
25254
+ code,
25255
+ severity,
25256
+ phase: 'semantic-validation',
25257
+ message,
25258
+ summary: message,
25259
+ subject,
25260
+ details,
25261
+ source: 'semantic-validator',
25262
+ blocking,
25263
+ createdAt: new Date().toISOString(),
25264
+ };
25265
+ }
25266
+ formatNestedPath(nestedPath) {
25267
+ return JSON.stringify(nestedPath);
25268
+ }
25269
+ nestedEndpointSubject(link, endpoint, nestedPath) {
25270
+ return {
25271
+ kind: 'port',
25272
+ widgetKey: endpoint.ref.widget,
25273
+ widgetType: endpoint.ref.componentType,
25274
+ portId: endpoint.ref.port,
25275
+ linkId: link.id,
25276
+ path: this.formatNestedPath(nestedPath),
25277
+ };
25278
+ }
25279
+ isSameNestedPath(left, right) {
25280
+ return JSON.stringify(left) === JSON.stringify(right);
25281
+ }
25282
+ }
25283
+
25284
+ class CompositionRuntimeStore {
25285
+ snapshot;
25286
+ listeners = new Set();
25287
+ constructor(init) {
25288
+ this.snapshot = freezeSnapshot(createSnapshot(init));
25289
+ }
25290
+ getSnapshot() {
25291
+ return this.snapshot;
25292
+ }
25293
+ subscribe(listener) {
25294
+ this.listeners.add(listener);
25295
+ listener(this.snapshot);
25296
+ return () => {
25297
+ this.listeners.delete(listener);
25298
+ };
25299
+ }
25300
+ reset(init) {
25301
+ this.snapshot = freezeSnapshot(createSnapshot(init));
25302
+ this.emit();
25303
+ return this.snapshot;
25304
+ }
25305
+ applyCycle(update) {
25306
+ const nextState = update.stateSnapshot
25307
+ ? cloneStateSnapshot$1(update.stateSnapshot)
25308
+ : applyStatePatch(this.snapshot.state, update);
25309
+ const nextLinks = applyLinkPatches(this.snapshot.links, update.linkPatches);
25310
+ this.snapshot = freezeSnapshot({
25311
+ pageId: this.snapshot.pageId,
25312
+ status: update.status ?? this.snapshot.status,
25313
+ generatedAt: update.generatedAt ?? this.snapshot.generatedAt,
25314
+ links: nextLinks,
25315
+ state: nextState,
25316
+ diagnostics: cloneDiagnostics$1(update.diagnostics ?? this.snapshot.diagnostics),
25317
+ traceTail: cloneTraceTail(update.traceTail ?? this.snapshot.traceTail),
25318
+ });
25319
+ this.emit();
25320
+ return this.snapshot;
25321
+ }
25322
+ emit() {
25323
+ for (const listener of this.listeners) {
25324
+ listener(this.snapshot);
25325
+ }
25326
+ }
25327
+ }
25328
+ function createSnapshot(init) {
25329
+ return {
25330
+ pageId: init?.pageId,
25331
+ status: init?.status ?? 'booting',
25332
+ generatedAt: init?.generatedAt ?? new Date(0).toISOString(),
25333
+ links: cloneLinks(init?.links ?? []),
25334
+ state: {
25335
+ primaryValues: cloneRecord$1(init?.state?.primaryValues),
25336
+ derivedValues: cloneRecord$1(init?.state?.derivedValues),
25337
+ transientValues: init?.state?.transientValues
25338
+ ? cloneRecord$1(init.state.transientValues)
25339
+ : undefined,
25340
+ changedPaths: init?.state?.changedPaths ? [...init.state.changedPaths] : [],
25341
+ diagnostics: cloneDiagnostics$1(init?.state?.diagnostics ?? []),
25342
+ },
25343
+ diagnostics: cloneDiagnostics$1(init?.diagnostics ?? []),
25344
+ traceTail: cloneTraceTail(init?.traceTail ?? []),
25345
+ };
25346
+ }
25347
+ function applyStatePatch(current, update) {
25348
+ return {
25349
+ primaryValues: {
25350
+ ...current.primaryValues,
25351
+ ...cloneRecord$1(update.primaryValuesPatch),
25352
+ },
25353
+ derivedValues: {
25354
+ ...current.derivedValues,
25355
+ ...cloneRecord$1(update.derivedValuesPatch),
25356
+ },
25357
+ transientValues: mergeTransientValues(current.transientValues, update.transientValuesPatch),
25358
+ changedPaths: update.changedPaths ? [...update.changedPaths] : [...(current.changedPaths ?? [])],
25359
+ diagnostics: cloneDiagnostics$1(current.diagnostics),
25360
+ };
25361
+ }
25362
+ function cloneStateSnapshot$1(state) {
25363
+ return {
25364
+ primaryValues: cloneRecord$1(state.primaryValues),
25365
+ derivedValues: cloneRecord$1(state.derivedValues),
25366
+ transientValues: state.transientValues ? cloneRecord$1(state.transientValues) : undefined,
25367
+ changedPaths: state.changedPaths ? [...state.changedPaths] : [],
25368
+ diagnostics: cloneDiagnostics$1(state.diagnostics),
25369
+ };
25370
+ }
25371
+ function mergeTransientValues(current, patch) {
25372
+ if (!current && !patch) {
25373
+ return undefined;
25374
+ }
25375
+ return {
25376
+ ...cloneRecord$1(current),
25377
+ ...cloneRecord$1(patch),
25378
+ };
25379
+ }
25380
+ function applyLinkPatches(current, patches) {
25381
+ const patchMap = new Map((patches ?? []).map((patch) => [patch.linkId, patch]));
25382
+ return current.map((link) => {
25383
+ const patch = patchMap.get(link.linkId);
25384
+ if (!patch) {
25385
+ return cloneLink(link);
25386
+ }
25387
+ const next = cloneLink(link);
25388
+ next.status = patch.status ?? link.status;
25389
+ setOptionalLinkValue(next, 'lastEventAt', pickPatchedValue(patch, 'lastEventAt', link.lastEventAt));
25390
+ setOptionalLinkValue(next, 'lastDispatchTraceId', pickPatchedValue(patch, 'lastDispatchTraceId', link.lastDispatchTraceId));
25391
+ setOptionalLinkValue(next, 'lastDeliveredValuePreview', pickPatchedValue(patch, 'lastDeliveredValuePreview', link.lastDeliveredValuePreview));
25392
+ next.diagnostics = cloneDiagnostics$1(patch.diagnostics ?? link.diagnostics);
25393
+ return next;
25394
+ });
25395
+ }
25396
+ function pickPatchedValue(patch, key, fallback) {
25397
+ return Object.prototype.hasOwnProperty.call(patch, key)
25398
+ ? patch[key]
25399
+ : fallback;
25400
+ }
25401
+ function cloneLinks(links) {
25402
+ return links.map((link) => cloneLink(link));
25403
+ }
25404
+ function cloneLink(link) {
25405
+ const next = {
25406
+ linkId: link.linkId,
25407
+ status: link.status,
25408
+ source: { ...link.source },
25409
+ target: { ...link.target },
25410
+ diagnostics: cloneDiagnostics$1(link.diagnostics),
25411
+ };
25412
+ setOptionalLinkValue(next, 'lastEventAt', link.lastEventAt);
25413
+ setOptionalLinkValue(next, 'lastDispatchTraceId', link.lastDispatchTraceId);
25414
+ setOptionalLinkValue(next, 'lastDeliveredValuePreview', link.lastDeliveredValuePreview);
25415
+ return next;
25416
+ }
25417
+ function setOptionalLinkValue(link, key, value) {
25418
+ if (value === undefined) {
25419
+ delete link[key];
25420
+ return;
25421
+ }
25422
+ link[key] = value;
25423
+ }
25424
+ function cloneDiagnostics$1(diagnostics) {
25425
+ return diagnostics.map((diagnostic) => ({
25426
+ ...diagnostic,
25427
+ subject: { ...diagnostic.subject },
25428
+ related: diagnostic.related?.map((item) => ({ ...item })),
25429
+ details: diagnostic.details ? { ...diagnostic.details } : undefined,
25430
+ }));
25431
+ }
25432
+ function cloneTraceTail(traceTail) {
25433
+ return traceTail.map((entry) => ({
25434
+ ...entry,
25435
+ subject: { ...entry.subject },
25436
+ payloadSummary: entry.payloadSummary
25437
+ ? {
25438
+ ...entry.payloadSummary,
25439
+ keys: entry.payloadSummary.keys ? [...entry.payloadSummary.keys] : undefined,
25440
+ }
25441
+ : undefined,
25442
+ details: entry.details ? { ...entry.details } : undefined,
25443
+ diagnostics: entry.diagnostics ? [...entry.diagnostics] : undefined,
25444
+ }));
25445
+ }
25446
+ function cloneRecord$1(value) {
25447
+ return value ? { ...value } : {};
25448
+ }
25449
+ function freezeSnapshot(snapshot) {
25450
+ return deepFreeze(snapshot);
25451
+ }
25452
+ function deepFreeze(value) {
25453
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) {
25454
+ return value;
25455
+ }
25456
+ Object.freeze(value);
25457
+ for (const nested of Object.values(value)) {
25458
+ if (nested && typeof nested === 'object') {
25459
+ deepFreeze(nested);
25460
+ }
25461
+ }
25462
+ return value;
25463
+ }
25464
+
25465
+ const DEFAULT_PATH_ACCESSOR$1 = new ConnectionManagerService();
25466
+ const DEFAULT_TEMPLATE_RESOLVER = new SurfaceBindingRuntimeService();
25467
+ const DEFAULT_JSON_LOGIC$1 = new PraxisJsonLogicService(null);
25468
+ const TRANSFORM_RULE_OPTIONS = {
25469
+ availableRoots: ['event', 'payload', 'state', 'context', 'source'],
25470
+ defaultRoot: 'source',
25471
+ allowImplicitRoot: true,
25472
+ };
25473
+ class TransformRuntimeService {
25474
+ pathAccessor;
25475
+ templateResolver;
25476
+ jsonLogic;
25477
+ constructor(pathAccessor = DEFAULT_PATH_ACCESSOR$1, templateResolver = DEFAULT_TEMPLATE_RESOLVER, jsonLogic = DEFAULT_JSON_LOGIC$1) {
25478
+ this.pathAccessor = pathAccessor;
25479
+ this.templateResolver = templateResolver;
25480
+ this.jsonLogic = jsonLogic;
25481
+ }
25482
+ executePipeline(pipeline, runtime) {
25483
+ const diagnostics = [];
25484
+ const env = this.buildEnvironment(runtime);
25485
+ let current = this.resolvePipelineSeed(pipeline, env);
25486
+ for (const [index, step] of pipeline.steps.entries()) {
25487
+ try {
25488
+ if (!this.matchesStepCondition(step.when, env)) {
25489
+ continue;
25490
+ }
25491
+ if (!isSupportedTransformKind(step.kind)) {
25492
+ diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_UNSUPPORTED', `O transform ${step.kind} ainda nao e suportado pelo runtime da Wave 1.`, {
25493
+ kind: 'transform-step',
25494
+ transformIndex: index,
25495
+ label: step.id,
25496
+ }, { transformKind: step.kind, pipelineId: pipeline.id, stepId: step.id }, undefined, 'unsupported-kind'));
25497
+ continue;
24990
25498
  }
24991
25499
  current = this.executeStep(step, current, env, diagnostics, index);
24992
25500
  env.current = this.clone(current);
@@ -25519,6 +26027,9 @@ class LinkExecutorService {
25519
26027
  if (endpoint.kind === 'state') {
25520
26028
  return this.readStatePath(snapshot, endpoint.ref.path, endpoint.ref.layer);
25521
26029
  }
26030
+ if (endpoint.kind === 'global-action') {
26031
+ return this.clone(context.payload ?? context.event);
26032
+ }
25522
26033
  const payload = context.payload !== undefined
25523
26034
  ? context.payload
25524
26035
  : (context.event && typeof context.event === 'object' && 'payload' in context.event)
@@ -25680,6 +26191,14 @@ class LinkExecutorService {
25680
26191
  stateLayer: layer,
25681
26192
  };
25682
26193
  }
26194
+ if (link.to.kind === 'global-action') {
26195
+ return {
26196
+ kind: 'global-action',
26197
+ value,
26198
+ actionId: link.to.ref.actionId,
26199
+ actionRef: this.clone(link.to.ref),
26200
+ };
26201
+ }
25683
26202
  return {
25684
26203
  kind: 'component-port',
25685
26204
  value,
@@ -25883,6 +26402,7 @@ class CompositionRuntimeEngine {
25883
26402
  linkExecutor;
25884
26403
  stateRuntime;
25885
26404
  traceService;
26405
+ compositionValidator;
25886
26406
  pathAccessor = new ConnectionManagerService();
25887
26407
  nestedWidgetAccessor = new NestedWidgetConfigAccessor();
25888
26408
  definition = null;
@@ -25893,12 +26413,17 @@ class CompositionRuntimeEngine {
25893
26413
  this.linkExecutor = options.linkExecutor ?? createDefaultLinkExecutor();
25894
26414
  this.stateRuntime = options.stateRuntime ?? createDefaultStateRuntime();
25895
26415
  this.traceService = options.traceService ?? new RuntimeTraceService();
26416
+ this.compositionValidator = options.compositionValidator ?? new CompositionValidatorService();
25896
26417
  }
25897
26418
  bootstrap(definition) {
25898
26419
  this.definition = definition;
25899
26420
  const generatedAt = this.now();
25900
26421
  const stateSnapshot = this.materializeDerivedState(definition.state.primaryValues, definition);
25901
- const bootstrapDiagnostics = uniqueDiagnosticsById(stateSnapshot.diagnostics);
26422
+ const semanticDiagnostics = this.validateComposition(definition);
26423
+ const bootstrapDiagnostics = uniqueDiagnosticsById([
26424
+ ...semanticDiagnostics,
26425
+ ...stateSnapshot.diagnostics,
26426
+ ]);
25902
26427
  const init = {
25903
26428
  status: bootstrapDiagnostics.some(isBlockingDiagnostic) ? 'degraded' : 'ready',
25904
26429
  generatedAt,
@@ -26294,6 +26819,18 @@ class CompositionRuntimeEngine {
26294
26819
  diagnostics: derivedSnapshot.diagnostics.map((message, index) => this.createDerivedDiagnostic(definition, message, index)),
26295
26820
  };
26296
26821
  }
26822
+ validateComposition(definition) {
26823
+ const page = {
26824
+ widgets: definition.widgetOrder
26825
+ .map((widgetKey) => definition.widgetsByKey[widgetKey])
26826
+ .filter((widget) => !!widget),
26827
+ };
26828
+ const links = definition.links;
26829
+ return links.flatMap((link) => this.compositionValidator.validateLink(link, {
26830
+ page,
26831
+ links,
26832
+ }));
26833
+ }
26297
26834
  createDerivedDiagnostic(definition, message, index) {
26298
26835
  const nodeKey = this.extractDerivedNodeKey(message);
26299
26836
  const classification = classifyDerivedDiagnosticMessage(message);
@@ -26410,6 +26947,9 @@ class CompositionRuntimeEngine {
26410
26947
  function isComponentPortEndpoint(endpoint) {
26411
26948
  return endpoint.kind === 'component-port';
26412
26949
  }
26950
+ function isGlobalActionEndpoint(endpoint) {
26951
+ return endpoint.kind === 'global-action';
26952
+ }
26413
26953
  function createDefaultLinkExecutor() {
26414
26954
  const connections = new ConnectionManagerService();
26415
26955
  const transforms = new TransformRuntimeService(connections, new SurfaceBindingRuntimeService());
@@ -26538,6 +27078,9 @@ function matchesEndpoint(expected, actual) {
26538
27078
  return expected.ref.path === actual.ref.path
26539
27079
  && (expected.ref.layer ?? 'values') === (actual.ref.layer ?? 'values');
26540
27080
  }
27081
+ if (isGlobalActionEndpoint(expected) && isGlobalActionEndpoint(actual)) {
27082
+ return expected.ref.actionId === actual.ref.actionId;
27083
+ }
26541
27084
  return false;
26542
27085
  }
26543
27086
  function areNestedPathsEqual(expected, actual) {
@@ -26567,6 +27110,14 @@ function toSubjectRef(endpoint) {
26567
27110
  : endpoint.ref.bindingPath,
26568
27111
  };
26569
27112
  }
27113
+ if (endpoint.kind === 'global-action') {
27114
+ return {
27115
+ kind: 'global-action',
27116
+ actionId: endpoint.ref.actionId,
27117
+ path: endpoint.ref.actionId,
27118
+ label: endpoint.ref.actionId,
27119
+ };
27120
+ }
26570
27121
  return {
26571
27122
  kind: endpoint.ref.layer === 'derived' ? 'derived-state' : 'state',
26572
27123
  statePath: endpoint.ref.path,
@@ -26580,6 +27131,11 @@ function endpointTraceDetails(prefix, endpoint) {
26580
27131
  [`${prefix}StateLayer`]: endpoint.ref.layer ?? 'values',
26581
27132
  };
26582
27133
  }
27134
+ if (endpoint.kind === 'global-action') {
27135
+ return {
27136
+ [`${prefix}ActionId`]: endpoint.ref.actionId,
27137
+ };
27138
+ }
26583
27139
  const details = {
26584
27140
  [`${prefix}WidgetKey`]: endpoint.ref.widget,
26585
27141
  [`${prefix}PortId`]: endpoint.ref.port,
@@ -26600,6 +27156,11 @@ function deliveryTraceDetails(delivery) {
26600
27156
  targetStateLayer: delivery.stateLayer ?? 'values',
26601
27157
  };
26602
27158
  }
27159
+ if (delivery.kind === 'global-action') {
27160
+ return {
27161
+ targetActionId: delivery.actionId,
27162
+ };
27163
+ }
26603
27164
  const details = {
26604
27165
  targetWidgetKey: delivery.widgetKey,
26605
27166
  targetPortId: delivery.portId,
@@ -26847,105 +27408,244 @@ function looksLikePath(value) {
26847
27408
  return /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\[\d+\])*$/.test(value);
26848
27409
  }
26849
27410
  function toJsonLogicValue(value) {
26850
- switch (typeof value) {
26851
- case 'string':
26852
- case 'number':
26853
- case 'boolean':
26854
- return value;
26855
- case 'undefined':
26856
- return null;
26857
- default:
26858
- break;
26859
- }
26860
- if (value === null) {
26861
- return null;
26862
- }
26863
- if (Array.isArray(value) || (value && typeof value === 'object')) {
26864
- return clone(value);
26865
- }
26866
- return String(value);
26867
- }
26868
- function clone(value) {
26869
- if (value == null || typeof value !== 'object') {
26870
- return value;
26871
- }
26872
- return JSON.parse(JSON.stringify(value));
26873
- }
26874
-
26875
- class NestedPortCatalogService {
26876
- accessor;
26877
- constructor(accessor = new NestedWidgetConfigAccessor()) {
26878
- this.accessor = accessor;
26879
- }
26880
- resolve(page, registry) {
26881
- const ports = [];
26882
- const diagnostics = [];
26883
- for (const owner of page.widgets || []) {
26884
- const nestedWidgets = this.accessor.listNestedWidgets(owner);
26885
- for (const nested of nestedWidgets) {
26886
- if (!this.hasStableTerminalKey(nested.nestedPath)) {
26887
- diagnostics.push({
26888
- code: 'NESTED_WIDGET_KEY_MISSING',
26889
- severity: 'error',
26890
- ownerWidgetKey: owner.key,
26891
- nestedPath: this.clone(nested.nestedPath),
26892
- componentId: nested.componentId,
26893
- message: `Nested widget inside '${owner.key}' must declare a stable childWidgetKey.`,
26894
- });
26895
- continue;
26896
- }
26897
- const meta = registry.get(nested.componentId);
26898
- if (!meta?.ports?.length) {
26899
- diagnostics.push({
26900
- code: 'NESTED_WIDGET_METADATA_MISSING',
26901
- severity: 'warning',
26902
- ownerWidgetKey: owner.key,
26903
- nestedPath: this.clone(nested.nestedPath),
26904
- componentId: nested.componentId,
26905
- message: `No component metadata ports found for nested widget '${nested.componentId}'.`,
26906
- });
26907
- continue;
26908
- }
26909
- for (const port of meta.ports) {
26910
- ports.push({
26911
- ownerWidgetKey: owner.key,
26912
- ownerComponentId: owner.definition.id,
26913
- nestedPath: this.clone(nested.nestedPath),
26914
- containerPath: this.containerPath(nested.nestedPath),
26915
- port: this.clone(port),
26916
- componentId: nested.componentId,
26917
- childWidgetKey: nested.childWidgetKey,
26918
- });
26919
- }
26920
- }
26921
- }
26922
- return { ports, diagnostics };
26923
- }
26924
- resolveEndpoint(page, registry, options) {
26925
- return this.resolve(page, registry).ports.find((port) => port.ownerWidgetKey === options.ownerWidgetKey
26926
- && port.port.id === options.portId
26927
- && port.port.direction === options.direction
26928
- && this.isSamePath(port.nestedPath, options.nestedPath));
26929
- }
26930
- hasStableTerminalKey(nestedPath) {
26931
- const terminal = nestedPath[nestedPath.length - 1];
26932
- return terminal?.kind === 'widget'
26933
- && typeof terminal.key === 'string'
26934
- && terminal.key.trim().length > 0;
27411
+ switch (typeof value) {
27412
+ case 'string':
27413
+ case 'number':
27414
+ case 'boolean':
27415
+ return value;
27416
+ case 'undefined':
27417
+ return null;
27418
+ default:
27419
+ break;
26935
27420
  }
26936
- containerPath(nestedPath) {
26937
- return nestedPath.slice(0, -1).map((segment) => this.clone(segment));
27421
+ if (value === null) {
27422
+ return null;
26938
27423
  }
26939
- isSamePath(left, right) {
26940
- return JSON.stringify(left) === JSON.stringify(right);
27424
+ if (Array.isArray(value) || (value && typeof value === 'object')) {
27425
+ return clone(value);
26941
27426
  }
26942
- clone(value) {
26943
- if (value == null || typeof value !== 'object') {
26944
- return value;
26945
- }
26946
- return JSON.parse(JSON.stringify(value));
27427
+ return String(value);
27428
+ }
27429
+ function clone(value) {
27430
+ if (value == null || typeof value !== 'object') {
27431
+ return value;
26947
27432
  }
27433
+ return JSON.parse(JSON.stringify(value));
27434
+ }
27435
+
27436
+ class DynamicWidgetContextToolbarComponent {
27437
+ toolbarLabel = '';
27438
+ contextLabel = '';
27439
+ contextTooltip = '';
27440
+ showAssistant = false;
27441
+ assistantLabel = '';
27442
+ assistantTooltip = '';
27443
+ showComponentSettings = false;
27444
+ componentSettingsLabel = '';
27445
+ componentSettingsTooltip = '';
27446
+ showShellSettings = false;
27447
+ shellSettingsLabel = '';
27448
+ shellSettingsTooltip = '';
27449
+ moreActionsLabel = '';
27450
+ removeLabel = '';
27451
+ assistant = new EventEmitter();
27452
+ componentSettings = new EventEmitter();
27453
+ shellSettings = new EventEmitter();
27454
+ remove = new EventEmitter();
27455
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetContextToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
27456
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: DynamicWidgetContextToolbarComponent, isStandalone: true, selector: "praxis-dynamic-widget-context-toolbar", inputs: { toolbarLabel: "toolbarLabel", contextLabel: "contextLabel", contextTooltip: "contextTooltip", showAssistant: "showAssistant", assistantLabel: "assistantLabel", assistantTooltip: "assistantTooltip", showComponentSettings: "showComponentSettings", componentSettingsLabel: "componentSettingsLabel", componentSettingsTooltip: "componentSettingsTooltip", showShellSettings: "showShellSettings", shellSettingsLabel: "shellSettingsLabel", shellSettingsTooltip: "shellSettingsTooltip", moreActionsLabel: "moreActionsLabel", removeLabel: "removeLabel" }, outputs: { assistant: "assistant", componentSettings: "componentSettings", shellSettings: "shellSettings", remove: "remove" }, ngImport: i0, template: `
27457
+ <div
27458
+ class="pdx-widget-context-toolbar"
27459
+ [class.pdx-widget-context-toolbar--with-context]="!!contextLabel"
27460
+ data-testid="dynamic-widget-context-toolbar"
27461
+ role="toolbar"
27462
+ [attr.aria-label]="toolbarLabel"
27463
+ (click)="$event.stopPropagation()"
27464
+ (pointerdown)="$event.stopPropagation()"
27465
+ >
27466
+ @if (contextLabel) {
27467
+ <span
27468
+ class="pdx-widget-context-toolbar__context"
27469
+ data-testid="dynamic-widget-context-label"
27470
+ [matTooltip]="contextTooltip || contextLabel"
27471
+ >
27472
+ {{ contextLabel }}
27473
+ </span>
27474
+ }
27475
+ @if (showAssistant) {
27476
+ <button
27477
+ mat-icon-button
27478
+ type="button"
27479
+ data-testid="dynamic-widget-assistant"
27480
+ [matTooltip]="assistantTooltip"
27481
+ [attr.aria-label]="assistantLabel"
27482
+ (click)="assistant.emit()"
27483
+ >
27484
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
27485
+ </button>
27486
+ }
27487
+ @if (showComponentSettings) {
27488
+ <button
27489
+ mat-icon-button
27490
+ type="button"
27491
+ data-testid="dynamic-widget-component-settings"
27492
+ [matTooltip]="componentSettingsTooltip"
27493
+ [attr.aria-label]="componentSettingsLabel"
27494
+ (click)="componentSettings.emit()"
27495
+ >
27496
+ <mat-icon [praxisIcon]="'tune'"></mat-icon>
27497
+ </button>
27498
+ }
27499
+ @if (showShellSettings) {
27500
+ <button
27501
+ mat-icon-button
27502
+ type="button"
27503
+ data-testid="dynamic-widget-shell-settings"
27504
+ [matTooltip]="shellSettingsTooltip"
27505
+ [attr.aria-label]="shellSettingsLabel"
27506
+ (click)="shellSettings.emit()"
27507
+ >
27508
+ <mat-icon [praxisIcon]="'settings'"></mat-icon>
27509
+ </button>
27510
+ }
27511
+ <button
27512
+ mat-icon-button
27513
+ type="button"
27514
+ data-testid="dynamic-widget-more-actions"
27515
+ [matTooltip]="moreActionsLabel"
27516
+ [attr.aria-label]="moreActionsLabel"
27517
+ [matMenuTriggerFor]="widgetContextMenu"
27518
+ >
27519
+ <mat-icon praxisIcon="ms:more_horiz"></mat-icon>
27520
+ </button>
27521
+ <mat-menu #widgetContextMenu="matMenu">
27522
+ <button mat-menu-item type="button" data-testid="dynamic-widget-remove" (click)="remove.emit()">
27523
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
27524
+ <span>{{ removeLabel }}</span>
27525
+ </button>
27526
+ </mat-menu>
27527
+ </div>
27528
+ `, isInline: true, styles: [".pdx-widget-context-toolbar{position:absolute;top:-19px;right:12px;z-index:4;display:inline-flex;align-items:center;gap:4px;min-height:34px;padding:2px 4px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 88%,transparent);box-shadow:0 10px 28px #0f172a38,0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.pdx-widget-context-toolbar--with-context{border-radius:18px}.pdx-widget-context-toolbar__context{display:inline-flex;align-items:center;align-self:stretch;max-width:180px;padding:0 8px 0 10px;border-right:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 64%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:700;letter-spacing:.01em;line-height:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-widget-context-toolbar button{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;flex:0 0 auto;width:30px;height:30px;padding:0;line-height:1;vertical-align:middle}.pdx-widget-context-toolbar mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
26948
27529
  }
27530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetContextToolbarComponent, decorators: [{
27531
+ type: Component,
27532
+ args: [{ selector: 'praxis-dynamic-widget-context-toolbar', standalone: true, imports: [
27533
+ CommonModule,
27534
+ MatButtonModule,
27535
+ MatIconModule,
27536
+ MatMenuModule,
27537
+ MatTooltipModule,
27538
+ PraxisIconDirective,
27539
+ ], template: `
27540
+ <div
27541
+ class="pdx-widget-context-toolbar"
27542
+ [class.pdx-widget-context-toolbar--with-context]="!!contextLabel"
27543
+ data-testid="dynamic-widget-context-toolbar"
27544
+ role="toolbar"
27545
+ [attr.aria-label]="toolbarLabel"
27546
+ (click)="$event.stopPropagation()"
27547
+ (pointerdown)="$event.stopPropagation()"
27548
+ >
27549
+ @if (contextLabel) {
27550
+ <span
27551
+ class="pdx-widget-context-toolbar__context"
27552
+ data-testid="dynamic-widget-context-label"
27553
+ [matTooltip]="contextTooltip || contextLabel"
27554
+ >
27555
+ {{ contextLabel }}
27556
+ </span>
27557
+ }
27558
+ @if (showAssistant) {
27559
+ <button
27560
+ mat-icon-button
27561
+ type="button"
27562
+ data-testid="dynamic-widget-assistant"
27563
+ [matTooltip]="assistantTooltip"
27564
+ [attr.aria-label]="assistantLabel"
27565
+ (click)="assistant.emit()"
27566
+ >
27567
+ <mat-icon [praxisIcon]="'auto_awesome'"></mat-icon>
27568
+ </button>
27569
+ }
27570
+ @if (showComponentSettings) {
27571
+ <button
27572
+ mat-icon-button
27573
+ type="button"
27574
+ data-testid="dynamic-widget-component-settings"
27575
+ [matTooltip]="componentSettingsTooltip"
27576
+ [attr.aria-label]="componentSettingsLabel"
27577
+ (click)="componentSettings.emit()"
27578
+ >
27579
+ <mat-icon [praxisIcon]="'tune'"></mat-icon>
27580
+ </button>
27581
+ }
27582
+ @if (showShellSettings) {
27583
+ <button
27584
+ mat-icon-button
27585
+ type="button"
27586
+ data-testid="dynamic-widget-shell-settings"
27587
+ [matTooltip]="shellSettingsTooltip"
27588
+ [attr.aria-label]="shellSettingsLabel"
27589
+ (click)="shellSettings.emit()"
27590
+ >
27591
+ <mat-icon [praxisIcon]="'settings'"></mat-icon>
27592
+ </button>
27593
+ }
27594
+ <button
27595
+ mat-icon-button
27596
+ type="button"
27597
+ data-testid="dynamic-widget-more-actions"
27598
+ [matTooltip]="moreActionsLabel"
27599
+ [attr.aria-label]="moreActionsLabel"
27600
+ [matMenuTriggerFor]="widgetContextMenu"
27601
+ >
27602
+ <mat-icon praxisIcon="ms:more_horiz"></mat-icon>
27603
+ </button>
27604
+ <mat-menu #widgetContextMenu="matMenu">
27605
+ <button mat-menu-item type="button" data-testid="dynamic-widget-remove" (click)="remove.emit()">
27606
+ <mat-icon [praxisIcon]="'delete'"></mat-icon>
27607
+ <span>{{ removeLabel }}</span>
27608
+ </button>
27609
+ </mat-menu>
27610
+ </div>
27611
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".pdx-widget-context-toolbar{position:absolute;top:-19px;right:12px;z-index:4;display:inline-flex;align-items:center;gap:4px;min-height:34px;padding:2px 4px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 28%,var(--md-sys-color-outline-variant));border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 88%,transparent);box-shadow:0 10px 28px #0f172a38,0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.pdx-widget-context-toolbar--with-context{border-radius:18px}.pdx-widget-context-toolbar__context{display:inline-flex;align-items:center;align-self:stretch;max-width:180px;padding:0 8px 0 10px;border-right:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 64%,transparent);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:700;letter-spacing:.01em;line-height:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-widget-context-toolbar button{--mdc-icon-button-state-layer-size: 30px;--mat-icon-button-state-layer-size: 30px;display:inline-grid;place-items:center;flex:0 0 auto;width:30px;height:30px;padding:0;line-height:1;vertical-align:middle}.pdx-widget-context-toolbar mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}\n"] }]
27612
+ }], propDecorators: { toolbarLabel: [{
27613
+ type: Input
27614
+ }], contextLabel: [{
27615
+ type: Input
27616
+ }], contextTooltip: [{
27617
+ type: Input
27618
+ }], showAssistant: [{
27619
+ type: Input
27620
+ }], assistantLabel: [{
27621
+ type: Input
27622
+ }], assistantTooltip: [{
27623
+ type: Input
27624
+ }], showComponentSettings: [{
27625
+ type: Input
27626
+ }], componentSettingsLabel: [{
27627
+ type: Input
27628
+ }], componentSettingsTooltip: [{
27629
+ type: Input
27630
+ }], showShellSettings: [{
27631
+ type: Input
27632
+ }], shellSettingsLabel: [{
27633
+ type: Input
27634
+ }], shellSettingsTooltip: [{
27635
+ type: Input
27636
+ }], moreActionsLabel: [{
27637
+ type: Input
27638
+ }], removeLabel: [{
27639
+ type: Input
27640
+ }], assistant: [{
27641
+ type: Output
27642
+ }], componentSettings: [{
27643
+ type: Output
27644
+ }], shellSettings: [{
27645
+ type: Output
27646
+ }], remove: [{
27647
+ type: Output
27648
+ }] } });
26949
27649
 
26950
27650
  const DYNAMIC_WIDGET_PAGE_I18N_NAMESPACE = 'dynamicWidgetPage';
26951
27651
  const DYNAMIC_WIDGET_PAGE_I18N_CONFIG = {
@@ -26953,9 +27653,22 @@ const DYNAMIC_WIDGET_PAGE_I18N_CONFIG = {
26953
27653
  [DYNAMIC_WIDGET_PAGE_I18N_NAMESPACE]: {
26954
27654
  'pt-BR': {
26955
27655
  'controls.pageSettings': 'Configurar página',
27656
+ 'controls.componentSettings': 'Configurar conteúdo',
27657
+ 'controls.componentSettingsTooltip': 'Abrir configurações do componente',
26956
27658
  'controls.widgetSettings': 'Configurar widget',
26957
27659
  'controls.widgetSettingsTooltip': 'Abrir configurações do widget',
27660
+ 'controls.widgetAssistant': 'Abrir assistente do widget',
27661
+ 'controls.widgetAssistantTooltip': 'Abrir o assistente Praxis com contexto deste widget',
27662
+ 'controls.widgetRemove': 'Excluir widget',
27663
+ 'controls.widgetRemoveTooltip': 'Excluir este widget e limpar conexões vinculadas',
27664
+ 'controls.widgetRemoveConfirmTitle': 'Excluir widget?',
27665
+ 'controls.widgetRemoveConfirmMessage': 'O widget "{{widget}}" será removido da página. Conexões e posições vinculadas também serão limpas.',
27666
+ 'controls.widgetRemoveConfirm': 'Excluir widget',
27667
+ 'controls.cancel': 'Cancelar',
26958
27668
  'controls.cardSettings': 'Configurar card',
27669
+ 'controls.moreWidgetActions': 'Mais ações do widget',
27670
+ 'controls.widgetContextToolbar': 'Ações do widget {{widget}}',
27671
+ 'controls.widgetContextTooltip': 'Editando {{widget}}',
26959
27672
  'controls.widgetLayoutToolbar': 'Ações de layout do widget',
26960
27673
  'controls.dragWidget': 'Arrastar widget',
26961
27674
  'controls.resizeWidget': 'Redimensionar widget',
@@ -26976,9 +27689,22 @@ const DYNAMIC_WIDGET_PAGE_I18N_CONFIG = {
26976
27689
  },
26977
27690
  'en-US': {
26978
27691
  'controls.pageSettings': 'Configure page',
27692
+ 'controls.componentSettings': 'Configure content',
27693
+ 'controls.componentSettingsTooltip': 'Open component settings',
26979
27694
  'controls.widgetSettings': 'Configure widget',
26980
27695
  'controls.widgetSettingsTooltip': 'Open widget settings',
27696
+ 'controls.widgetAssistant': 'Open widget assistant',
27697
+ 'controls.widgetAssistantTooltip': 'Open the Praxis assistant with this widget context',
27698
+ 'controls.widgetRemove': 'Delete widget',
27699
+ 'controls.widgetRemoveTooltip': 'Delete this widget and clean linked connections',
27700
+ 'controls.widgetRemoveConfirmTitle': 'Delete widget?',
27701
+ 'controls.widgetRemoveConfirmMessage': 'The widget "{{widget}}" will be removed from the page. Linked connections and positions will also be cleaned.',
27702
+ 'controls.widgetRemoveConfirm': 'Delete widget',
27703
+ 'controls.cancel': 'Cancel',
26981
27704
  'controls.cardSettings': 'Configure card',
27705
+ 'controls.moreWidgetActions': 'More widget actions',
27706
+ 'controls.widgetContextToolbar': 'Widget {{widget}} actions',
27707
+ 'controls.widgetContextTooltip': 'Editing {{widget}}',
26982
27708
  'controls.widgetLayoutToolbar': 'Widget layout actions',
26983
27709
  'controls.dragWidget': 'Drag widget',
26984
27710
  'controls.resizeWidget': 'Resize widget',
@@ -27158,8 +27884,12 @@ class DynamicWidgetPageComponent {
27158
27884
  pageIdentity;
27159
27885
  /** Optional instance key for pages rendered multiple times. */
27160
27886
  componentInstanceId;
27887
+ /** Enables a contextual authoring assistant entrypoint for the selected widget. */
27888
+ showWidgetAssistantButton = false;
27161
27889
  pageChange = new EventEmitter();
27162
27890
  widgetEvent = new EventEmitter();
27891
+ widgetSelectionChange = new EventEmitter();
27892
+ widgetAssistantRequested = new EventEmitter();
27163
27893
  widgetDiagnosticsChange = new EventEmitter();
27164
27894
  widgets = signal([], ...(ngDevMode ? [{ debugName: "widgets" }] : []));
27165
27895
  renderedGroups = signal([], ...(ngDevMode ? [{ debugName: "renderedGroups" }] : []));
@@ -27184,7 +27914,7 @@ class DynamicWidgetPageComponent {
27184
27914
  pageColumnCount = 1;
27185
27915
  activeTabs = {};
27186
27916
  widgetDiagnostics = {};
27187
- selectedCanvasWidgetKey = null;
27917
+ selectedWidgetKey = null;
27188
27918
  blockedCanvasWidgetKey = null;
27189
27919
  canvasPreviewState = signal(null, ...(ngDevMode ? [{ debugName: "canvasPreviewState" }] : []));
27190
27920
  canvasPreviewInvalidState = signal(false, ...(ngDevMode ? [{ debugName: "canvasPreviewInvalidState" }] : []));
@@ -27195,6 +27925,7 @@ class DynamicWidgetPageComponent {
27195
27925
  persistenceReady = false;
27196
27926
  warnedMissingKey = false;
27197
27927
  runtimeEventSequence = 0;
27928
+ widgetShellRenderCache = new Map();
27198
27929
  compositionFactory = new WidgetPageCompositionFactory();
27199
27930
  compositionRuntime = new CompositionRuntimeFacade();
27200
27931
  compositionDefinition;
@@ -27233,6 +27964,7 @@ class DynamicWidgetPageComponent {
27233
27964
  if (changes['page'] ||
27234
27965
  changes['context'] ||
27235
27966
  changes['enableCustomization']) {
27967
+ this.widgetShellRenderCache.clear();
27236
27968
  const parsed = this.parsePage(this.page);
27237
27969
  const resolvedPage = parsed ? this.resolvePagePresets(parsed) : parsed;
27238
27970
  this.assertNoLegacyConnections(resolvedPage);
@@ -27298,6 +28030,11 @@ class DynamicWidgetPageComponent {
27298
28030
  }
27299
28031
  return;
27300
28032
  }
28033
+ this.executeCompositionGlobalActionDeliveries(cycle, {
28034
+ fromKey,
28035
+ event: evt,
28036
+ page: pageWithPatchedInputs,
28037
+ });
27301
28038
  const state = this.stateFromCompositionSnapshot(pageWithPatchedInputs.state, cycle.snapshot.state.primaryValues);
27302
28039
  const runtimeStatePaths = Array.from(new Set((cycle.snapshot.state.changedPaths || []).filter((path) => typeof path === 'string')));
27303
28040
  const updatedPrimaryStatePaths = runtimeStatePaths.filter((path) => !this.areStateValuesEqual(this.conn.extractByPath(this.stateRuntime.normalizeState(page.state).values || {}, path), this.conn.extractByPath(state.values || {}, path)));
@@ -27386,52 +28123,7 @@ class DynamicWidgetPageComponent {
27386
28123
  return this.compositionRuntime.bootstrap(this.compositionDefinition);
27387
28124
  }
27388
28125
  applyEditShellActions(widgets) {
27389
- return this.cloneWidgets(widgets).map((widget) => {
27390
- if (!this.shouldInjectEditShellActions(widget)) {
27391
- return widget;
27392
- }
27393
- const existingActions = widget.shell?.actions || [];
27394
- const metadata = this.componentMetadata?.get(widget.definition?.id || '');
27395
- const nextActions = [...existingActions];
27396
- if (metadata?.configEditor &&
27397
- !nextActions.some((action) => action.id === 'component-settings')) {
27398
- nextActions.push({
27399
- id: 'component-settings',
27400
- icon: 'tune',
27401
- variant: 'icon',
27402
- placement: 'header',
27403
- label: this.t('controls.componentSettings', 'Configurar conteudo'),
27404
- tooltip: this.t('controls.componentSettingsTooltip', 'Abrir configuracoes do componente'),
27405
- });
27406
- }
27407
- if (nextActions.some((action) => action.id === 'widget-settings') ||
27408
- !this.canOpenWidgetShellSettings()) {
27409
- return this.withShellActions(widget, nextActions);
27410
- }
27411
- const widgetSettingsAction = {
27412
- id: 'widget-settings',
27413
- icon: 'settings',
27414
- variant: 'icon',
27415
- placement: 'header',
27416
- label: this.t('controls.widgetSettings', 'Configurar widget'),
27417
- tooltip: this.t('controls.widgetSettingsTooltip', 'Abrir configurações do widget'),
27418
- };
27419
- return this.withShellActions(widget, [...nextActions, widgetSettingsAction]);
27420
- });
27421
- }
27422
- withShellActions(widget, actions) {
27423
- const existingActions = widget.shell?.actions || [];
27424
- if (existingActions.length === actions.length &&
27425
- existingActions.every((action, index) => action === actions[index])) {
27426
- return widget;
27427
- }
27428
- return {
27429
- ...widget,
27430
- shell: {
27431
- ...(widget.shell || {}),
27432
- actions,
27433
- },
27434
- };
28126
+ return this.cloneWidgets(widgets);
27435
28127
  }
27436
28128
  applyBootstrapCompositionHydration(widgets, bootstrapSnapshot) {
27437
28129
  if (!this.compositionDefinition || !bootstrapSnapshot) {
@@ -27579,6 +28271,50 @@ class DynamicWidgetPageComponent {
27579
28271
  }
27580
28272
  return { widgets: nextWidgets, changed };
27581
28273
  }
28274
+ executeCompositionGlobalActionDeliveries(cycle, options) {
28275
+ if (!this.compositionDefinition) {
28276
+ return;
28277
+ }
28278
+ const linksById = new Map(this.compositionDefinition.links.map((link) => [link.id, link]));
28279
+ const runtimeLinks = cycle.snapshot.links.filter((link) => link.lastDispatchTraceId === cycle.cycleId &&
28280
+ link.status === 'delivered');
28281
+ for (const runtimeLink of runtimeLinks) {
28282
+ const link = linksById.get(runtimeLink.linkId);
28283
+ if (!link || link.to.kind !== 'global-action') {
28284
+ continue;
28285
+ }
28286
+ const deliveredValue = this.cloneStateValues(runtimeLink.lastDeliveredValuePreview);
28287
+ const actionRef = this.resolveCompositionGlobalActionRef(link.to.ref, deliveredValue);
28288
+ void this.globalActions.executeRef(actionRef, {
28289
+ sourceId: options.fromKey,
28290
+ widgetKey: options.event.ownerWidgetKey || options.fromKey,
28291
+ output: options.event.output,
28292
+ payload: deliveredValue,
28293
+ pageContext: options.page.context || null,
28294
+ runtime: {
28295
+ value: deliveredValue,
28296
+ state: this.cloneStateValues(cycle.snapshot.state.primaryValues),
28297
+ },
28298
+ meta: {
28299
+ origin: 'dynamic-page.composition-link',
28300
+ componentId: 'praxis-dynamic-page',
28301
+ linkId: link.id,
28302
+ intent: link.intent,
28303
+ },
28304
+ });
28305
+ }
28306
+ }
28307
+ resolveCompositionGlobalActionRef(ref, deliveredValue) {
28308
+ const hasConfiguredPayload = Object.prototype.hasOwnProperty.call(ref, 'payload') ||
28309
+ String(ref.payloadExpr || '').trim().length > 0;
28310
+ if (hasConfiguredPayload) {
28311
+ return this.cloneStateValues(ref);
28312
+ }
28313
+ return {
28314
+ ...this.cloneStateValues(ref),
28315
+ payload: deliveredValue,
28316
+ };
28317
+ }
27582
28318
  buildStateContext(pageContext) {
27583
28319
  return {
27584
28320
  ...(this.cloneStateValues(pageContext) || {}),
@@ -27705,7 +28441,7 @@ class DynamicWidgetPageComponent {
27705
28441
  case 'page.autoPersist.disabled':
27706
28442
  return !this.autoPersist;
27707
28443
  case 'page.widget.selected':
27708
- return this.selectedCanvasWidgetKey === widgetKey;
28444
+ return this.selectedWidgetKey === widgetKey;
27709
28445
  case 'page.widget.configurable': {
27710
28446
  const widget = this.widgets().find((candidate) => candidate.key === widgetKey);
27711
28447
  const widgetType = widget?.definition?.id || '';
@@ -27746,14 +28482,185 @@ class DynamicWidgetPageComponent {
27746
28482
  }
27747
28483
  return `widget:${fromKey}:${output}:${timestamp}:${sequence}`;
27748
28484
  }
27749
- shouldInjectEditShellActions(widget) {
27750
- if (!this.enableCustomization || !this.settingsPanel) {
28485
+ canOpenWidgetShellSettings() {
28486
+ return !!(this.shellEditorComponent || this.defaultShellEditor);
28487
+ }
28488
+ canOpenWidgetComponentSettings(key) {
28489
+ const page = this.pageDefinition || this.parsePage(this.page);
28490
+ const widget = page?.widgets?.find((candidate) => candidate.key === key);
28491
+ if (!widget)
28492
+ return false;
28493
+ const metadata = this.componentMetadata?.get(widget.definition?.id || '');
28494
+ return !!metadata?.configEditor?.component;
28495
+ }
28496
+ componentSettingsLabel() {
28497
+ return this.t('controls.componentSettings', 'Configurar conteúdo');
28498
+ }
28499
+ componentSettingsTooltip() {
28500
+ return this.t('controls.componentSettingsTooltip', 'Abrir configurações do componente');
28501
+ }
28502
+ widgetSettingsLabel() {
28503
+ return this.t('controls.widgetSettings', 'Configurar widget');
28504
+ }
28505
+ widgetSettingsTooltip() {
28506
+ return this.t('controls.widgetSettingsTooltip', 'Abrir configurações do widget');
28507
+ }
28508
+ widgetAssistantLabel() {
28509
+ return this.t('controls.widgetAssistant', 'Abrir assistente do widget');
28510
+ }
28511
+ widgetAssistantTooltip() {
28512
+ return this.t('controls.widgetAssistantTooltip', 'Abrir o assistente Praxis com contexto deste widget');
28513
+ }
28514
+ requestWidgetAssistant(widgetKey) {
28515
+ this.selectWidget(widgetKey);
28516
+ this.widgetAssistantRequested.emit(widgetKey);
28517
+ }
28518
+ widgetRemoveLabel() {
28519
+ return this.t('controls.widgetRemove', 'Excluir widget');
28520
+ }
28521
+ moreWidgetActionsLabel() {
28522
+ return this.t('controls.moreWidgetActions', 'Mais ações do widget');
28523
+ }
28524
+ widgetContextToolbarLabel(widgetKey) {
28525
+ return this.t('controls.widgetContextToolbar', 'Ações do widget {{widget}}', {
28526
+ widget: widgetKey,
28527
+ });
28528
+ }
28529
+ widgetContextLabel(widget) {
28530
+ return this.resolveWidgetDisplayName(widget);
28531
+ }
28532
+ widgetContextTooltip(widget) {
28533
+ const label = this.resolveWidgetDisplayName(widget);
28534
+ return this.t('controls.widgetContextTooltip', 'Editando {{widget}}', {
28535
+ widget: label,
28536
+ });
28537
+ }
28538
+ shouldRenderWidgetContextOverlay(widget) {
28539
+ return (this.enableCustomization &&
28540
+ this.isWidgetSelected(widget.key) &&
28541
+ !this.hasVisibleWidgetShellHeader(widget));
28542
+ }
28543
+ widgetShellForRender(widget) {
28544
+ if (!this.shouldProjectWidgetHeaderActions(widget)) {
28545
+ return widget.shell;
28546
+ }
28547
+ const projectedActions = this.buildProjectedWidgetShellActions(widget);
28548
+ if (!projectedActions.length) {
28549
+ return widget.shell;
28550
+ }
28551
+ const signature = this.widgetShellActionSignature(projectedActions);
28552
+ const cached = this.widgetShellRenderCache.get(widget.key);
28553
+ if (cached &&
28554
+ cached.source === widget.shell &&
28555
+ cached.signature === signature) {
28556
+ return cached.shell;
28557
+ }
28558
+ const existingActions = widget.shell?.actions || [];
28559
+ const existingIds = new Set(existingActions.map((action) => action.id));
28560
+ const shell = {
28561
+ ...widget.shell,
28562
+ actions: [
28563
+ ...existingActions,
28564
+ ...projectedActions.filter((action) => !existingIds.has(action.id)),
28565
+ ],
28566
+ };
28567
+ this.widgetShellRenderCache.set(widget.key, {
28568
+ source: widget.shell,
28569
+ signature,
28570
+ shell,
28571
+ });
28572
+ return shell;
28573
+ }
28574
+ resolveWidgetDisplayName(widget) {
28575
+ const shellTitle = String(widget.shell?.title || '').trim();
28576
+ if (shellTitle)
28577
+ return shellTitle;
28578
+ const componentId = widget.definition?.id || '';
28579
+ const metadata = componentId ? this.componentMetadata?.get(componentId) : undefined;
28580
+ return metadata?.friendlyName || componentId || widget.key;
28581
+ }
28582
+ shouldProjectWidgetHeaderActions(widget) {
28583
+ return (this.enableCustomization &&
28584
+ this.isWidgetSelected(widget.key) &&
28585
+ this.hasVisibleWidgetShellHeader(widget));
28586
+ }
28587
+ hasVisibleWidgetShellHeader(widget) {
28588
+ const shell = widget.shell;
28589
+ if (!shell || shell.kind === 'none')
27751
28590
  return false;
28591
+ if (shell.showHeader != null)
28592
+ return !!shell.showHeader;
28593
+ return !!(shell.title ||
28594
+ shell.subtitle ||
28595
+ shell.icon ||
28596
+ this.hasVisibleShellActions(shell) ||
28597
+ this.hasVisibleWindowActions(shell));
28598
+ }
28599
+ hasVisibleShellActions(shell) {
28600
+ return (shell.actions || []).some((action) => this.isVisibleShellAction(action));
28601
+ }
28602
+ hasVisibleWindowActions(shell) {
28603
+ return ((shell.windowActions?.collapsible !== false ||
28604
+ shell.windowActions?.fullscreen !== false) ||
28605
+ (shell.actions || []).some((action) => this.isVisibleShellAction(action) &&
28606
+ (action.placement || 'header') === 'window'));
28607
+ }
28608
+ buildProjectedWidgetShellActions(widget) {
28609
+ const actions = [];
28610
+ if (this.showWidgetAssistantButton) {
28611
+ actions.push({
28612
+ id: 'widget-assistant',
28613
+ label: this.widgetAssistantLabel(),
28614
+ tooltip: this.widgetAssistantTooltip(),
28615
+ icon: 'auto_awesome',
28616
+ variant: 'icon',
28617
+ placement: 'header',
28618
+ });
28619
+ }
28620
+ if (this.canOpenWidgetComponentSettings(widget.key)) {
28621
+ actions.push({
28622
+ id: 'component-settings',
28623
+ label: this.componentSettingsLabel(),
28624
+ tooltip: this.componentSettingsTooltip(),
28625
+ icon: 'tune',
28626
+ variant: 'icon',
28627
+ placement: 'header',
28628
+ });
28629
+ }
28630
+ if (this.canOpenWidgetShellSettings()) {
28631
+ actions.push({
28632
+ id: 'widget-settings',
28633
+ label: this.widgetSettingsLabel(),
28634
+ tooltip: this.widgetSettingsTooltip(),
28635
+ icon: 'settings',
28636
+ variant: 'icon',
28637
+ placement: 'header',
28638
+ });
27752
28639
  }
27753
- return !!widget.shell && widget.shell.kind !== 'none';
28640
+ actions.push({
28641
+ id: 'widget-remove',
28642
+ label: this.widgetRemoveLabel(),
28643
+ tooltip: this.widgetRemoveLabel(),
28644
+ icon: 'delete',
28645
+ variant: 'icon',
28646
+ placement: 'header',
28647
+ });
28648
+ return actions;
27754
28649
  }
27755
- canOpenWidgetShellSettings() {
27756
- return !!(this.shellEditorComponent || this.defaultShellEditor);
28650
+ widgetShellActionSignature(actions) {
28651
+ return actions
28652
+ .map((action) => [
28653
+ action.id,
28654
+ action.label || '',
28655
+ action.tooltip || '',
28656
+ action.icon || '',
28657
+ action.variant || '',
28658
+ action.placement || '',
28659
+ ].join(':'))
28660
+ .join('|');
28661
+ }
28662
+ isVisibleShellAction(action) {
28663
+ return action.visible == null || !!action.visible;
27757
28664
  }
27758
28665
  areStateValuesEqual(left, right) {
27759
28666
  if (left === right)
@@ -27791,6 +28698,10 @@ class DynamicWidgetPageComponent {
27791
28698
  this.widgetDiagnosticsChange.emit({ ...this.widgetDiagnostics });
27792
28699
  }
27793
28700
  onShellAction(fromKey, evt) {
28701
+ if (evt.id === 'widget-assistant') {
28702
+ this.requestWidgetAssistant(fromKey);
28703
+ return;
28704
+ }
27794
28705
  if (evt.id === 'component-settings') {
27795
28706
  this.openWidgetComponentSettings(fromKey);
27796
28707
  return;
@@ -27799,6 +28710,10 @@ class DynamicWidgetPageComponent {
27799
28710
  this.openWidgetShellSettings(fromKey);
27800
28711
  return;
27801
28712
  }
28713
+ if (evt.id === 'widget-remove') {
28714
+ void this.confirmAndRemoveWidget(fromKey);
28715
+ return;
28716
+ }
27802
28717
  if (this.handleSetInputCommand(fromKey, evt))
27803
28718
  return;
27804
28719
  const output = evt?.emit || (evt?.id ? `shell:${evt.id}` : undefined);
@@ -27968,6 +28883,124 @@ class DynamicWidgetPageComponent {
27968
28883
  : w);
27969
28884
  this.applyPageUpdate({ ...page, widgets }, persist);
27970
28885
  }
28886
+ async confirmAndRemoveWidget(widgetKey) {
28887
+ const page = this.ensurePageDefinition();
28888
+ const widget = page.widgets.find((item) => item.key === widgetKey);
28889
+ if (!widget) {
28890
+ return;
28891
+ }
28892
+ const title = widget.shell?.title || widget.definition?.id || widgetKey;
28893
+ const confirmation = await this.globalActions.execute('dialog.confirm', {
28894
+ title: this.t('controls.widgetRemoveConfirmTitle', 'Excluir widget?'),
28895
+ message: this.t('controls.widgetRemoveConfirmMessage', 'O widget "{{widget}}" será removido da página. Conexões e posições vinculadas também serão limpas.', { widget: title }),
28896
+ confirmLabel: this.t('controls.widgetRemoveConfirm', 'Excluir widget'),
28897
+ cancelLabel: this.t('controls.cancel', 'Cancelar'),
28898
+ type: 'danger',
28899
+ });
28900
+ if (!confirmation.success || confirmation.data !== true) {
28901
+ return;
28902
+ }
28903
+ this.applyPageUpdate(this.removeWidgetReferences(page, widgetKey), true);
28904
+ if (this.selectedWidgetKey === widgetKey) {
28905
+ this.selectedWidgetKey = null;
28906
+ this.widgetSelectionChange.emit(null);
28907
+ }
28908
+ }
28909
+ removeSelectedWidget() {
28910
+ if (!this.selectedWidgetKey) {
28911
+ return;
28912
+ }
28913
+ void this.confirmAndRemoveWidget(this.selectedWidgetKey);
28914
+ }
28915
+ removeSelectedCanvasWidget() {
28916
+ this.removeSelectedWidget();
28917
+ }
28918
+ removeWidgetReferences(page, widgetKey) {
28919
+ const source = this.cloneStateValues(page);
28920
+ const next = {
28921
+ ...source,
28922
+ widgets: (source.widgets || []).filter((widget) => widget.key !== widgetKey),
28923
+ };
28924
+ if (next.canvas?.items) {
28925
+ const items = { ...next.canvas.items };
28926
+ delete items[widgetKey];
28927
+ next.canvas = { ...next.canvas, items };
28928
+ }
28929
+ if (next.composition?.links) {
28930
+ next.composition = {
28931
+ ...next.composition,
28932
+ links: next.composition.links.filter((link) => !this.linkReferencesWidget(link, widgetKey)),
28933
+ };
28934
+ }
28935
+ if (next.grouping) {
28936
+ next.grouping = next.grouping.map((group) => {
28937
+ if (group.kind === 'tabs') {
28938
+ return {
28939
+ ...group,
28940
+ tabs: group.tabs.map((tab) => ({
28941
+ ...tab,
28942
+ widgetKeys: tab.widgetKeys.filter((key) => key !== widgetKey),
28943
+ })),
28944
+ };
28945
+ }
28946
+ return {
28947
+ ...group,
28948
+ widgetKeys: group.widgetKeys.filter((key) => key !== widgetKey),
28949
+ };
28950
+ });
28951
+ }
28952
+ if (next.slotAssignments?.[widgetKey] !== undefined) {
28953
+ const slotAssignments = { ...next.slotAssignments };
28954
+ delete slotAssignments[widgetKey];
28955
+ next.slotAssignments = slotAssignments;
28956
+ }
28957
+ if (next.deviceLayouts) {
28958
+ const deviceLayouts = {};
28959
+ for (const [device, variant] of Object.entries(next.deviceLayouts)) {
28960
+ const canvasItems = variant.canvas?.items
28961
+ ? { ...variant.canvas.items }
28962
+ : undefined;
28963
+ if (canvasItems) {
28964
+ delete canvasItems[widgetKey];
28965
+ }
28966
+ const widgetOverrides = variant.widgetOverrides
28967
+ ? { ...variant.widgetOverrides }
28968
+ : undefined;
28969
+ if (widgetOverrides) {
28970
+ delete widgetOverrides[widgetKey];
28971
+ }
28972
+ const groupingOverrides = variant.groupingOverrides?.map((override) => ({
28973
+ ...override,
28974
+ ...(override.widgetKeys
28975
+ ? { widgetKeys: override.widgetKeys.filter((key) => key !== widgetKey) }
28976
+ : {}),
28977
+ ...(override.tabs
28978
+ ? {
28979
+ tabs: override.tabs.map((tab) => ({
28980
+ ...tab,
28981
+ widgetKeys: tab.widgetKeys.filter((key) => key !== widgetKey),
28982
+ })),
28983
+ }
28984
+ : {}),
28985
+ }));
28986
+ deviceLayouts[device] = {
28987
+ ...variant,
28988
+ ...(variant.canvas ? { canvas: { ...variant.canvas, ...(canvasItems ? { items: canvasItems } : {}) } } : {}),
28989
+ ...(widgetOverrides ? { widgetOverrides } : {}),
28990
+ ...(groupingOverrides ? { groupingOverrides } : {}),
28991
+ };
28992
+ }
28993
+ next.deviceLayouts = deviceLayouts;
28994
+ }
28995
+ return next;
28996
+ }
28997
+ linkReferencesWidget(link, widgetKey) {
28998
+ return this.endpointReferencesWidget(link.from, widgetKey)
28999
+ || this.endpointReferencesWidget(link.to, widgetKey);
29000
+ }
29001
+ endpointReferencesWidget(endpoint, widgetKey) {
29002
+ return endpoint.kind === 'component-port' && endpoint.ref.widget === widgetKey;
29003
+ }
27971
29004
  openPageSettings() {
27972
29005
  if (!this.settingsPanel)
27973
29006
  return;
@@ -28372,11 +29405,12 @@ class DynamicWidgetPageComponent {
28372
29405
  }
28373
29406
  return widget?.definition?.inputs?.['enableCustomization'] === true;
28374
29407
  }
28375
- selectCanvasWidget(widgetKey) {
29408
+ selectWidget(widgetKey) {
28376
29409
  if (!this.enableCustomization)
28377
29410
  return;
28378
- if (this.selectedCanvasWidgetKey !== widgetKey) {
28379
- this.selectedCanvasWidgetKey = widgetKey;
29411
+ if (this.selectedWidgetKey !== widgetKey) {
29412
+ this.selectedWidgetKey = widgetKey;
29413
+ this.widgetSelectionChange.emit(widgetKey);
28380
29414
  }
28381
29415
  if (this.blockedCanvasWidgetKey &&
28382
29416
  this.blockedCanvasWidgetKey !== widgetKey) {
@@ -28384,7 +29418,13 @@ class DynamicWidgetPageComponent {
28384
29418
  }
28385
29419
  }
28386
29420
  isCanvasWidgetSelected(widgetKey) {
28387
- return this.selectedCanvasWidgetKey === widgetKey;
29421
+ return this.isWidgetSelected(widgetKey);
29422
+ }
29423
+ isWidgetSelected(widgetKey) {
29424
+ return this.selectedWidgetKey === widgetKey;
29425
+ }
29426
+ selectCanvasWidget(widgetKey) {
29427
+ this.selectWidget(widgetKey);
28388
29428
  }
28389
29429
  isCanvasWidgetBlocked(widgetKey) {
28390
29430
  return this.blockedCanvasWidgetKey === widgetKey;
@@ -29232,7 +30272,7 @@ class DynamicWidgetPageComponent {
29232
30272
  throw new Error('DynamicWidgetPageComponent no longer accepts `page.connections`. Use `composition.links` only.');
29233
30273
  }
29234
30274
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
29235
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: DynamicWidgetPageComponent, isStandalone: true, selector: "praxis-dynamic-page", inputs: { page: "page", context: "context", strictValidation: "strictValidation", enableCustomization: "enableCustomization", showPageSettingsButton: "showPageSettingsButton", shellEditorComponent: "shellEditorComponent", pageEditorComponent: "pageEditorComponent", autoPersist: "autoPersist", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId" }, outputs: { pageChange: "pageChange", widgetEvent: "widgetEvent", widgetDiagnosticsChange: "widgetDiagnosticsChange" }, host: { listeners: { "window:resize": "onWindowResize()", "window:pointermove": "onCanvasPointerMove($event)", "window:pointerup": "onCanvasPointerUp($event)", "window:pointercancel": "onCanvasPointerCancel($event)" } }, providers: [providePraxisI18nConfig(DYNAMIC_WIDGET_PAGE_I18N_CONFIG)], viewQueries: [{ propertyName: "pageCanvasHost", first: true, predicate: ["pageCanvasHost"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
30275
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: DynamicWidgetPageComponent, isStandalone: true, selector: "praxis-dynamic-page", inputs: { page: "page", context: "context", strictValidation: "strictValidation", enableCustomization: "enableCustomization", showPageSettingsButton: "showPageSettingsButton", shellEditorComponent: "shellEditorComponent", pageEditorComponent: "pageEditorComponent", autoPersist: "autoPersist", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", showWidgetAssistantButton: "showWidgetAssistantButton" }, outputs: { pageChange: "pageChange", widgetEvent: "widgetEvent", widgetSelectionChange: "widgetSelectionChange", widgetAssistantRequested: "widgetAssistantRequested", widgetDiagnosticsChange: "widgetDiagnosticsChange" }, host: { listeners: { "window:resize": "onWindowResize()", "window:pointermove": "onCanvasPointerMove($event)", "window:pointerup": "onCanvasPointerUp($event)", "window:pointercancel": "onCanvasPointerCancel($event)" } }, providers: [providePraxisI18nConfig(DYNAMIC_WIDGET_PAGE_I18N_CONFIG)], viewQueries: [{ propertyName: "pageCanvasHost", first: true, predicate: ["pageCanvasHost"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
29236
30276
  <div class="pdx-page-wrapper" [class.editing]="enableCustomization">
29237
30277
  @if (enableCustomization && showPageSettingsButton) {
29238
30278
  <button
@@ -29260,8 +30300,11 @@ class DynamicWidgetPageComponent {
29260
30300
  <div
29261
30301
  class="pdx-widget pdx-widget--canvas"
29262
30302
  [class.pdx-widget--interactive]="enableCustomization"
30303
+ [class.pdx-widget--selected]="
30304
+ enableCustomization && isWidgetSelected(w.key)
30305
+ "
29263
30306
  [class.pdx-widget--canvas-selected]="
29264
- enableCustomization && isCanvasWidgetSelected(w.key)
30307
+ enableCustomization && isWidgetSelected(w.key)
29265
30308
  "
29266
30309
  [class.pdx-widget--canvas-blocked]="
29267
30310
  enableCustomization && isCanvasWidgetBlocked(w.key)
@@ -29270,8 +30313,8 @@ class DynamicWidgetPageComponent {
29270
30313
  [style.gridColumn]="widgetGridColumn(w)"
29271
30314
  [style.gridRow]="widgetGridRow(w)"
29272
30315
  [style.zIndex]="widgetZIndex(w)"
29273
- (click)="selectCanvasWidget(w.key)"
29274
- (focusin)="selectCanvasWidget(w.key)"
30316
+ (click)="selectWidget(w.key)"
30317
+ (focusin)="selectWidget(w.key)"
29275
30318
  >
29276
30319
  @if (enableCustomization) {
29277
30320
  @for (handle of canvasResizeHandles; track handle.id) {
@@ -29292,7 +30335,7 @@ class DynamicWidgetPageComponent {
29292
30335
  }
29293
30336
  }
29294
30337
  <praxis-widget-shell
29295
- [shell]="w.shell"
30338
+ [shell]="widgetShellForRender(w)"
29296
30339
  [context]="mergedContext"
29297
30340
  [dragSurfaceEnabled]="enableCustomization && isCanvasMode()"
29298
30341
  [dragSurfaceLabel]="dragWidgetLabel()"
@@ -29312,6 +30355,28 @@ class DynamicWidgetPageComponent {
29312
30355
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29313
30356
  ></ng-container>
29314
30357
  </praxis-widget-shell>
30358
+ @if (shouldRenderWidgetContextOverlay(w)) {
30359
+ <praxis-dynamic-widget-context-toolbar
30360
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30361
+ [contextLabel]="widgetContextLabel(w)"
30362
+ [contextTooltip]="widgetContextTooltip(w)"
30363
+ [showAssistant]="showWidgetAssistantButton"
30364
+ [assistantLabel]="widgetAssistantLabel()"
30365
+ [assistantTooltip]="widgetAssistantTooltip()"
30366
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30367
+ [componentSettingsLabel]="componentSettingsLabel()"
30368
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30369
+ [showShellSettings]="canOpenWidgetShellSettings()"
30370
+ [shellSettingsLabel]="widgetSettingsLabel()"
30371
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30372
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30373
+ [removeLabel]="widgetRemoveLabel()"
30374
+ (assistant)="requestWidgetAssistant(w.key)"
30375
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30376
+ (shellSettings)="openWidgetShellSettings(w.key)"
30377
+ (remove)="confirmAndRemoveWidget(w.key)"
30378
+ />
30379
+ }
29315
30380
  </div>
29316
30381
  }
29317
30382
  @if (canvasPreviewItem()) {
@@ -29370,11 +30435,17 @@ class DynamicWidgetPageComponent {
29370
30435
  @for (w of tab.widgets; track w.key) {
29371
30436
  <div
29372
30437
  class="pdx-widget"
30438
+ [class.pdx-widget--interactive]="enableCustomization"
30439
+ [class.pdx-widget--selected]="
30440
+ enableCustomization && isWidgetSelected(w.key)
30441
+ "
29373
30442
  [class]="w.renderClassName || w.className || ''"
29374
30443
  [style.gridColumn]="widgetGridColumn(w)"
30444
+ (click)="selectWidget(w.key)"
30445
+ (focusin)="selectWidget(w.key)"
29375
30446
  >
29376
30447
  <praxis-widget-shell
29377
- [shell]="w.shell"
30448
+ [shell]="widgetShellForRender(w)"
29378
30449
  [context]="mergedContext"
29379
30450
  (action)="onShellAction(w.key, $event)"
29380
30451
  >
@@ -29390,6 +30461,28 @@ class DynamicWidgetPageComponent {
29390
30461
  "
29391
30462
  ></ng-container>
29392
30463
  </praxis-widget-shell>
30464
+ @if (shouldRenderWidgetContextOverlay(w)) {
30465
+ <praxis-dynamic-widget-context-toolbar
30466
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30467
+ [contextLabel]="widgetContextLabel(w)"
30468
+ [contextTooltip]="widgetContextTooltip(w)"
30469
+ [showAssistant]="showWidgetAssistantButton"
30470
+ [assistantLabel]="widgetAssistantLabel()"
30471
+ [assistantTooltip]="widgetAssistantTooltip()"
30472
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30473
+ [componentSettingsLabel]="componentSettingsLabel()"
30474
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30475
+ [showShellSettings]="canOpenWidgetShellSettings()"
30476
+ [shellSettingsLabel]="widgetSettingsLabel()"
30477
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30478
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30479
+ [removeLabel]="widgetRemoveLabel()"
30480
+ (assistant)="requestWidgetAssistant(w.key)"
30481
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30482
+ (shellSettings)="openWidgetShellSettings(w.key)"
30483
+ (remove)="confirmAndRemoveWidget(w.key)"
30484
+ />
30485
+ }
29393
30486
  </div>
29394
30487
  }
29395
30488
  </div>
@@ -29406,11 +30499,17 @@ class DynamicWidgetPageComponent {
29406
30499
  @for (w of group.widgets; track w.key) {
29407
30500
  <div
29408
30501
  class="pdx-widget"
30502
+ [class.pdx-widget--interactive]="enableCustomization"
30503
+ [class.pdx-widget--selected]="
30504
+ enableCustomization && isWidgetSelected(w.key)
30505
+ "
29409
30506
  [class]="widgetClassName(w)"
29410
30507
  [style.gridColumn]="widgetGridColumn(w)"
30508
+ (click)="selectWidget(w.key)"
30509
+ (focusin)="selectWidget(w.key)"
29411
30510
  >
29412
30511
  <praxis-widget-shell
29413
- [shell]="w.shell"
30512
+ [shell]="widgetShellForRender(w)"
29414
30513
  [context]="mergedContext"
29415
30514
  (action)="onShellAction(w.key, $event)"
29416
30515
  >
@@ -29424,6 +30523,28 @@ class DynamicWidgetPageComponent {
29424
30523
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29425
30524
  ></ng-container>
29426
30525
  </praxis-widget-shell>
30526
+ @if (shouldRenderWidgetContextOverlay(w)) {
30527
+ <praxis-dynamic-widget-context-toolbar
30528
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30529
+ [contextLabel]="widgetContextLabel(w)"
30530
+ [contextTooltip]="widgetContextTooltip(w)"
30531
+ [showAssistant]="showWidgetAssistantButton"
30532
+ [assistantLabel]="widgetAssistantLabel()"
30533
+ [assistantTooltip]="widgetAssistantTooltip()"
30534
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30535
+ [componentSettingsLabel]="componentSettingsLabel()"
30536
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30537
+ [showShellSettings]="canOpenWidgetShellSettings()"
30538
+ [shellSettingsLabel]="widgetSettingsLabel()"
30539
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30540
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30541
+ [removeLabel]="widgetRemoveLabel()"
30542
+ (assistant)="requestWidgetAssistant(w.key)"
30543
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30544
+ (shellSettings)="openWidgetShellSettings(w.key)"
30545
+ (remove)="confirmAndRemoveWidget(w.key)"
30546
+ />
30547
+ }
29427
30548
  </div>
29428
30549
  }
29429
30550
  </div>
@@ -29434,11 +30555,17 @@ class DynamicWidgetPageComponent {
29434
30555
  @for (w of widgets(); track w.key) {
29435
30556
  <div
29436
30557
  class="pdx-widget"
30558
+ [class.pdx-widget--interactive]="enableCustomization"
30559
+ [class.pdx-widget--selected]="
30560
+ enableCustomization && isWidgetSelected(w.key)
30561
+ "
29437
30562
  [class]="widgetClassName(w)"
29438
30563
  [style.gridColumn]="widgetGridColumn(w)"
30564
+ (click)="selectWidget(w.key)"
30565
+ (focusin)="selectWidget(w.key)"
29439
30566
  >
29440
30567
  <praxis-widget-shell
29441
- [shell]="w.shell"
30568
+ [shell]="widgetShellForRender(w)"
29442
30569
  [context]="mergedContext"
29443
30570
  (action)="onShellAction(w.key, $event)"
29444
30571
  >
@@ -29452,6 +30579,28 @@ class DynamicWidgetPageComponent {
29452
30579
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29453
30580
  ></ng-container>
29454
30581
  </praxis-widget-shell>
30582
+ @if (shouldRenderWidgetContextOverlay(w)) {
30583
+ <praxis-dynamic-widget-context-toolbar
30584
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30585
+ [contextLabel]="widgetContextLabel(w)"
30586
+ [contextTooltip]="widgetContextTooltip(w)"
30587
+ [showAssistant]="showWidgetAssistantButton"
30588
+ [assistantLabel]="widgetAssistantLabel()"
30589
+ [assistantTooltip]="widgetAssistantTooltip()"
30590
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30591
+ [componentSettingsLabel]="componentSettingsLabel()"
30592
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30593
+ [showShellSettings]="canOpenWidgetShellSettings()"
30594
+ [shellSettingsLabel]="widgetSettingsLabel()"
30595
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30596
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30597
+ [removeLabel]="widgetRemoveLabel()"
30598
+ (assistant)="requestWidgetAssistant(w.key)"
30599
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30600
+ (shellSettings)="openWidgetShellSettings(w.key)"
30601
+ (remove)="confirmAndRemoveWidget(w.key)"
30602
+ />
30603
+ }
29455
30604
  </div>
29456
30605
  }
29457
30606
  }
@@ -29462,7 +30611,7 @@ class DynamicWidgetPageComponent {
29462
30611
  </div>
29463
30612
  }
29464
30613
  </div>
29465
- `, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:12px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:12px;width:36px;height:36px;margin-bottom:6px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:6px;min-width:0;min-height:0}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-selected:before{border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context", "dragSurfaceEnabled", "dragSurfaceLabel"], outputs: ["action", "dragSurfacePointerDown", "dragSurfaceKeydown"] }] });
30614
+ `, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:12px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:12px;width:36px;height:36px;margin-bottom:6px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:6px;min-width:0;min-height:0}.pdx-widget--interactive{cursor:pointer}.pdx-widget--selected:before{content:\"\";position:absolute;inset:0;border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);border-radius:14px;pointer-events:none;z-index:1;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: DynamicWidgetContextToolbarComponent, selector: "praxis-dynamic-widget-context-toolbar", inputs: ["toolbarLabel", "contextLabel", "contextTooltip", "showAssistant", "assistantLabel", "assistantTooltip", "showComponentSettings", "componentSettingsLabel", "componentSettingsTooltip", "showShellSettings", "shellSettingsLabel", "shellSettingsTooltip", "moreActionsLabel", "removeLabel"], outputs: ["assistant", "componentSettings", "shellSettings", "remove"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context", "dragSurfaceEnabled", "dragSurfaceLabel"], outputs: ["action", "dragSurfacePointerDown", "dragSurfaceKeydown"] }] });
29466
30615
  }
29467
30616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, decorators: [{
29468
30617
  type: Component,
@@ -29471,6 +30620,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29471
30620
  MatButtonModule,
29472
30621
  MatIconModule,
29473
30622
  MatTooltipModule,
30623
+ DynamicWidgetContextToolbarComponent,
29474
30624
  DynamicWidgetLoaderDirective,
29475
30625
  WidgetShellComponent,
29476
30626
  ], providers: [providePraxisI18nConfig(DYNAMIC_WIDGET_PAGE_I18N_CONFIG)], template: `
@@ -29501,8 +30651,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29501
30651
  <div
29502
30652
  class="pdx-widget pdx-widget--canvas"
29503
30653
  [class.pdx-widget--interactive]="enableCustomization"
30654
+ [class.pdx-widget--selected]="
30655
+ enableCustomization && isWidgetSelected(w.key)
30656
+ "
29504
30657
  [class.pdx-widget--canvas-selected]="
29505
- enableCustomization && isCanvasWidgetSelected(w.key)
30658
+ enableCustomization && isWidgetSelected(w.key)
29506
30659
  "
29507
30660
  [class.pdx-widget--canvas-blocked]="
29508
30661
  enableCustomization && isCanvasWidgetBlocked(w.key)
@@ -29511,8 +30664,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29511
30664
  [style.gridColumn]="widgetGridColumn(w)"
29512
30665
  [style.gridRow]="widgetGridRow(w)"
29513
30666
  [style.zIndex]="widgetZIndex(w)"
29514
- (click)="selectCanvasWidget(w.key)"
29515
- (focusin)="selectCanvasWidget(w.key)"
30667
+ (click)="selectWidget(w.key)"
30668
+ (focusin)="selectWidget(w.key)"
29516
30669
  >
29517
30670
  @if (enableCustomization) {
29518
30671
  @for (handle of canvasResizeHandles; track handle.id) {
@@ -29533,7 +30686,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29533
30686
  }
29534
30687
  }
29535
30688
  <praxis-widget-shell
29536
- [shell]="w.shell"
30689
+ [shell]="widgetShellForRender(w)"
29537
30690
  [context]="mergedContext"
29538
30691
  [dragSurfaceEnabled]="enableCustomization && isCanvasMode()"
29539
30692
  [dragSurfaceLabel]="dragWidgetLabel()"
@@ -29553,6 +30706,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29553
30706
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29554
30707
  ></ng-container>
29555
30708
  </praxis-widget-shell>
30709
+ @if (shouldRenderWidgetContextOverlay(w)) {
30710
+ <praxis-dynamic-widget-context-toolbar
30711
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30712
+ [contextLabel]="widgetContextLabel(w)"
30713
+ [contextTooltip]="widgetContextTooltip(w)"
30714
+ [showAssistant]="showWidgetAssistantButton"
30715
+ [assistantLabel]="widgetAssistantLabel()"
30716
+ [assistantTooltip]="widgetAssistantTooltip()"
30717
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30718
+ [componentSettingsLabel]="componentSettingsLabel()"
30719
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30720
+ [showShellSettings]="canOpenWidgetShellSettings()"
30721
+ [shellSettingsLabel]="widgetSettingsLabel()"
30722
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30723
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30724
+ [removeLabel]="widgetRemoveLabel()"
30725
+ (assistant)="requestWidgetAssistant(w.key)"
30726
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30727
+ (shellSettings)="openWidgetShellSettings(w.key)"
30728
+ (remove)="confirmAndRemoveWidget(w.key)"
30729
+ />
30730
+ }
29556
30731
  </div>
29557
30732
  }
29558
30733
  @if (canvasPreviewItem()) {
@@ -29611,11 +30786,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29611
30786
  @for (w of tab.widgets; track w.key) {
29612
30787
  <div
29613
30788
  class="pdx-widget"
30789
+ [class.pdx-widget--interactive]="enableCustomization"
30790
+ [class.pdx-widget--selected]="
30791
+ enableCustomization && isWidgetSelected(w.key)
30792
+ "
29614
30793
  [class]="w.renderClassName || w.className || ''"
29615
30794
  [style.gridColumn]="widgetGridColumn(w)"
30795
+ (click)="selectWidget(w.key)"
30796
+ (focusin)="selectWidget(w.key)"
29616
30797
  >
29617
30798
  <praxis-widget-shell
29618
- [shell]="w.shell"
30799
+ [shell]="widgetShellForRender(w)"
29619
30800
  [context]="mergedContext"
29620
30801
  (action)="onShellAction(w.key, $event)"
29621
30802
  >
@@ -29631,6 +30812,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29631
30812
  "
29632
30813
  ></ng-container>
29633
30814
  </praxis-widget-shell>
30815
+ @if (shouldRenderWidgetContextOverlay(w)) {
30816
+ <praxis-dynamic-widget-context-toolbar
30817
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30818
+ [contextLabel]="widgetContextLabel(w)"
30819
+ [contextTooltip]="widgetContextTooltip(w)"
30820
+ [showAssistant]="showWidgetAssistantButton"
30821
+ [assistantLabel]="widgetAssistantLabel()"
30822
+ [assistantTooltip]="widgetAssistantTooltip()"
30823
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30824
+ [componentSettingsLabel]="componentSettingsLabel()"
30825
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30826
+ [showShellSettings]="canOpenWidgetShellSettings()"
30827
+ [shellSettingsLabel]="widgetSettingsLabel()"
30828
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30829
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30830
+ [removeLabel]="widgetRemoveLabel()"
30831
+ (assistant)="requestWidgetAssistant(w.key)"
30832
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30833
+ (shellSettings)="openWidgetShellSettings(w.key)"
30834
+ (remove)="confirmAndRemoveWidget(w.key)"
30835
+ />
30836
+ }
29634
30837
  </div>
29635
30838
  }
29636
30839
  </div>
@@ -29647,11 +30850,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29647
30850
  @for (w of group.widgets; track w.key) {
29648
30851
  <div
29649
30852
  class="pdx-widget"
30853
+ [class.pdx-widget--interactive]="enableCustomization"
30854
+ [class.pdx-widget--selected]="
30855
+ enableCustomization && isWidgetSelected(w.key)
30856
+ "
29650
30857
  [class]="widgetClassName(w)"
29651
30858
  [style.gridColumn]="widgetGridColumn(w)"
30859
+ (click)="selectWidget(w.key)"
30860
+ (focusin)="selectWidget(w.key)"
29652
30861
  >
29653
30862
  <praxis-widget-shell
29654
- [shell]="w.shell"
30863
+ [shell]="widgetShellForRender(w)"
29655
30864
  [context]="mergedContext"
29656
30865
  (action)="onShellAction(w.key, $event)"
29657
30866
  >
@@ -29665,6 +30874,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29665
30874
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29666
30875
  ></ng-container>
29667
30876
  </praxis-widget-shell>
30877
+ @if (shouldRenderWidgetContextOverlay(w)) {
30878
+ <praxis-dynamic-widget-context-toolbar
30879
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30880
+ [contextLabel]="widgetContextLabel(w)"
30881
+ [contextTooltip]="widgetContextTooltip(w)"
30882
+ [showAssistant]="showWidgetAssistantButton"
30883
+ [assistantLabel]="widgetAssistantLabel()"
30884
+ [assistantTooltip]="widgetAssistantTooltip()"
30885
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30886
+ [componentSettingsLabel]="componentSettingsLabel()"
30887
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30888
+ [showShellSettings]="canOpenWidgetShellSettings()"
30889
+ [shellSettingsLabel]="widgetSettingsLabel()"
30890
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30891
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30892
+ [removeLabel]="widgetRemoveLabel()"
30893
+ (assistant)="requestWidgetAssistant(w.key)"
30894
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30895
+ (shellSettings)="openWidgetShellSettings(w.key)"
30896
+ (remove)="confirmAndRemoveWidget(w.key)"
30897
+ />
30898
+ }
29668
30899
  </div>
29669
30900
  }
29670
30901
  </div>
@@ -29675,11 +30906,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29675
30906
  @for (w of widgets(); track w.key) {
29676
30907
  <div
29677
30908
  class="pdx-widget"
30909
+ [class.pdx-widget--interactive]="enableCustomization"
30910
+ [class.pdx-widget--selected]="
30911
+ enableCustomization && isWidgetSelected(w.key)
30912
+ "
29678
30913
  [class]="widgetClassName(w)"
29679
30914
  [style.gridColumn]="widgetGridColumn(w)"
30915
+ (click)="selectWidget(w.key)"
30916
+ (focusin)="selectWidget(w.key)"
29680
30917
  >
29681
30918
  <praxis-widget-shell
29682
- [shell]="w.shell"
30919
+ [shell]="widgetShellForRender(w)"
29683
30920
  [context]="mergedContext"
29684
30921
  (action)="onShellAction(w.key, $event)"
29685
30922
  >
@@ -29693,6 +30930,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29693
30930
  (widgetDiagnostic)="onWidgetDiagnostic(w.key, $event)"
29694
30931
  ></ng-container>
29695
30932
  </praxis-widget-shell>
30933
+ @if (shouldRenderWidgetContextOverlay(w)) {
30934
+ <praxis-dynamic-widget-context-toolbar
30935
+ [toolbarLabel]="widgetContextToolbarLabel(w.key)"
30936
+ [contextLabel]="widgetContextLabel(w)"
30937
+ [contextTooltip]="widgetContextTooltip(w)"
30938
+ [showAssistant]="showWidgetAssistantButton"
30939
+ [assistantLabel]="widgetAssistantLabel()"
30940
+ [assistantTooltip]="widgetAssistantTooltip()"
30941
+ [showComponentSettings]="canOpenWidgetComponentSettings(w.key)"
30942
+ [componentSettingsLabel]="componentSettingsLabel()"
30943
+ [componentSettingsTooltip]="componentSettingsTooltip()"
30944
+ [showShellSettings]="canOpenWidgetShellSettings()"
30945
+ [shellSettingsLabel]="widgetSettingsLabel()"
30946
+ [shellSettingsTooltip]="widgetSettingsTooltip()"
30947
+ [moreActionsLabel]="moreWidgetActionsLabel()"
30948
+ [removeLabel]="widgetRemoveLabel()"
30949
+ (assistant)="requestWidgetAssistant(w.key)"
30950
+ (componentSettings)="openWidgetComponentSettings(w.key)"
30951
+ (shellSettings)="openWidgetShellSettings(w.key)"
30952
+ (remove)="confirmAndRemoveWidget(w.key)"
30953
+ />
30954
+ }
29696
30955
  </div>
29697
30956
  }
29698
30957
  }
@@ -29703,7 +30962,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29703
30962
  </div>
29704
30963
  }
29705
30964
  </div>
29706
- `, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:12px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:12px;width:36px;height:36px;margin-bottom:6px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:6px;min-width:0;min-height:0}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-selected:before{border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"] }]
30965
+ `, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:12px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:12px;width:36px;height:36px;margin-bottom:6px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:6px;min-width:0;min-height:0}.pdx-widget--interactive{cursor:pointer}.pdx-widget--selected:before{content:\"\";position:absolute;inset:0;border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);border-radius:14px;pointer-events:none;z-index:1;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"] }]
29707
30966
  }], ctorParameters: () => [], propDecorators: { pageCanvasHost: [{
29708
30967
  type: ViewChild,
29709
30968
  args: ['pageCanvasHost']
@@ -29727,10 +30986,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
29727
30986
  type: Input
29728
30987
  }], componentInstanceId: [{
29729
30988
  type: Input
30989
+ }], showWidgetAssistantButton: [{
30990
+ type: Input
29730
30991
  }], pageChange: [{
29731
30992
  type: Output
29732
30993
  }], widgetEvent: [{
29733
30994
  type: Output
30995
+ }], widgetSelectionChange: [{
30996
+ type: Output
30997
+ }], widgetAssistantRequested: [{
30998
+ type: Output
29734
30999
  }], widgetDiagnosticsChange: [{
29735
31000
  type: Output
29736
31001
  }], onWindowResize: [{
@@ -29912,7 +31177,7 @@ class EmptyStateCardComponent {
29912
31177
  </div>
29913
31178
  </mat-card-content>
29914
31179
  </mat-card>
29915
- `, isInline: true, styles: [".empty-card{display:block;margin:12px;border-color:var(--md-sys-color-outline-variant);--empty-icon-color: var(--md-sys-color-on-surface-variant)}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;color:var(--empty-icon-color)}.texts{display:grid;gap:4px}.title{margin:0;font-size:16px;font-weight:600;color:var(--md-sys-color-on-surface)}.desc{margin:0;color:var(--md-sys-color-on-surface-variant)}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}.empty-card.tone-primary{--empty-icon-color: var(--md-sys-color-primary)}.empty-card.tone-secondary{--empty-icon-color: var(--md-sys-color-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
31180
+ `, isInline: true, styles: [".empty-card{display:block;margin:12px;border-color:var(--md-sys-color-outline-variant);--empty-icon-color: var(--md-sys-color-on-surface-variant)}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;color:var(--empty-icon-color)}.texts{display:grid;gap:4px}.title{margin:0;font-size:16px;font-weight:600;color:var(--md-sys-color-on-surface)}.desc{margin:0;color:var(--md-sys-color-on-surface-variant)}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}.empty-card.tone-primary{--empty-icon-color: var(--md-sys-color-primary)}.empty-card.tone-secondary{--empty-icon-color: var(--md-sys-color-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
29916
31181
  }
29917
31182
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: EmptyStateCardComponent, decorators: [{
29918
31183
  type: Component,
@@ -30017,7 +31282,7 @@ class ResourceQuickConnectComponent {
30017
31282
  Rota normalizada: {{ normalizedPath() }}
30018
31283
  </small>
30019
31284
  </div>
30020
- `, isInline: true, styles: [".pdx-quick-connect{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.pdx-quick-connect__hint{color:var(--md-sys-color-on-surface-variant);font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
31285
+ `, isInline: true, styles: [".pdx-quick-connect{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.pdx-quick-connect__hint{color:var(--md-sys-color-on-surface-variant);font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
30021
31286
  }
30022
31287
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceQuickConnectComponent, decorators: [{
30023
31288
  type: Component,
@@ -30245,7 +31510,7 @@ class PraxisIconPickerComponent {
30245
31510
  <span class="pip-typed" *ngIf="query.trim()">{{ previewValue() }}</span>
30246
31511
  </div>
30247
31512
  </div>
30248
- `, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px;color:var(--md-sys-color-on-surface)}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap}.pip-search{flex:1;min-width:180px}.pip-spacer{flex:1}.pip-body{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;padding:4px}.pip-item{display:flex;gap:10px;align-items:center;justify-content:flex-start;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface);color:inherit;cursor:pointer;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pip-item:hover{background:var(--md-sys-color-surface-container)}.pip-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pip-item.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:-6px 0 8px}.pip-stats{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:8px}.pip-shortcut{opacity:.9}.pip-empty{padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:10px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);margin-top:8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;color:var(--md-sys-color-on-surface)}.pip-family{display:flex;align-items:center}.pip-family .mat-mdc-chip-listbox{min-width:260px}.pip-root .mat-icon{font-family:Material Icons,Material Symbols Outlined,Material Symbols Rounded,Material Symbols Sharp!important;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24;color:currentColor}.material-symbols-outlined{font-family:Material Symbols Outlined;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-rounded{font-family:Material Symbols Rounded;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-sharp{font-family:Material Symbols Sharp;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatChipsModule }, { kind: "component", type: i8$1.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i8$1.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
31513
+ `, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px;color:var(--md-sys-color-on-surface)}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap}.pip-search{flex:1;min-width:180px}.pip-spacer{flex:1}.pip-body{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;padding:4px}.pip-item{display:flex;gap:10px;align-items:center;justify-content:flex-start;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface);color:inherit;cursor:pointer;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pip-item:hover{background:var(--md-sys-color-surface-container)}.pip-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pip-item.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:-6px 0 8px}.pip-stats{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:8px}.pip-shortcut{opacity:.9}.pip-empty{padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:10px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);margin-top:8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;color:var(--md-sys-color-on-surface)}.pip-family{display:flex;align-items:center}.pip-family .mat-mdc-chip-listbox{min-width:260px}.pip-root .mat-icon{font-family:Material Icons,Material Symbols Outlined,Material Symbols Rounded,Material Symbols Sharp!important;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24;color:currentColor}.material-symbols-outlined{font-family:Material Symbols Outlined;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-rounded{font-family:Material Symbols Rounded;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-sharp{font-family:Material Symbols Sharp;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatChipsModule }, { kind: "component", type: i8.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i8.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
30249
31514
  }
30250
31515
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisIconPickerComponent, decorators: [{
30251
31516
  type: Component,
@@ -30589,7 +31854,7 @@ class SchemaViewerComponent {
30589
31854
  </mat-tab-group>
30590
31855
  </mat-card-content>
30591
31856
  </mat-card>
30592
- `, isInline: true, styles: [".schema-viewer{display:block;border-color:var(--md-sys-color-outline-variant)}.header{display:flex;align-items:center;justify-content:space-between;gap:8px}.title{display:flex;align-items:center;gap:8px}.title h3{margin:0;font-weight:600;color:var(--md-sys-color-on-surface)}.notes{margin-top:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.copy-status{margin-top:6px;font-size:12px;color:var(--md-sys-color-primary)}.section{padding:12px}.section-actions{display:flex;justify-content:flex-end;margin-bottom:8px}.sub{font-weight:600;margin:12px 0 4px;color:var(--md-sys-color-on-surface)}.pretty{background:var(--md-sys-color-surface-container);padding:10px;border-radius:8px;overflow:auto;border:1px solid var(--md-sys-color-outline-variant)}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{color:var(--md-sys-color-on-surface-variant)}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$2.MatCardHeader, selector: "mat-card-header" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31857
+ `, isInline: true, styles: [".schema-viewer{display:block;border-color:var(--md-sys-color-outline-variant)}.header{display:flex;align-items:center;justify-content:space-between;gap:8px}.title{display:flex;align-items:center;gap:8px}.title h3{margin:0;font-weight:600;color:var(--md-sys-color-on-surface)}.notes{margin-top:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.copy-status{margin-top:6px;font-size:12px;color:var(--md-sys-color-primary)}.section{padding:12px}.section-actions{display:flex;justify-content:flex-end;margin-bottom:8px}.sub{font-weight:600;margin:12px 0 4px;color:var(--md-sys-color-on-surface)}.pretty{background:var(--md-sys-color-surface-container);padding:10px;border-radius:8px;overflow:auto;border:1px solid var(--md-sys-color-outline-variant)}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{color:var(--md-sys-color-on-surface-variant)}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: MatIconModule }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
30593
31858
  }
30594
31859
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SchemaViewerComponent, decorators: [{
30595
31860
  type: Component,
@@ -31212,4 +32477,4 @@ function provideHookWhitelist(allowed) {
31212
32477
  * Generated bundle index. Do not edit.
31213
32478
  */
31214
32479
 
31215
- export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, CompositionRuntimeFacade, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceOpenActionEditorComponent, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisLayerScaleCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldConstraints, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizeResourceAvailabilityReasonCode, normalizeStart, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveBuiltinPresets, resolveControlTypeAlias, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolveResourceAvailabilityReasonKey, resolveSpan, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToJson, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withMessage, withPraxisHttpLoading };
32480
+ export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, CompositionRuntimeFacade, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceOpenActionEditorComponent, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisEffectDistinctKey, buildPraxisLayerScaleCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isPraxisRuntimeGlobalActionEffect, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldConstraints, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef$1 as normalizeGlobalActionRef, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizePraxisEffectPolicy, normalizeResourceAvailabilityReasonCode, normalizeStart, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveBuiltinPresets, resolveControlTypeAlias, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolveResourceAvailabilityReasonKey, resolveSpan, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToJson, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withMessage, withPraxisHttpLoading };