@vectoriox/iox-ui 4.35.0 → 4.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -971,6 +971,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImpo
971
971
  type: Input
972
972
  }] } });
973
973
 
974
+ /**
975
+ * Phosphor's CSS needs TWO classes — a weight and a name (`.ph-thin.ph-house:before`). A class
976
+ * string carrying only the name matches nothing at all: no `font-family`, no glyph, so the element
977
+ * renders as an invisible, zero-glyph box.
978
+ *
979
+ * The icon picker used to emit exactly that (`ph-house`), so every icon chosen through it was blank
980
+ * on the canvas, in the picker grid and on the live site. Fixing the picker alone would leave every
981
+ * icon already saved broken, so the repair happens at RENDER time, here, and is shared by the
982
+ * builder's Icon component and the SSR engine's renderer.
983
+ *
984
+ * Everything that is not a weightless Phosphor class passes through untouched — Iconoir
985
+ * (`iconoir-home`), custom icon-set fonts, Font Awesome, and Phosphor strings that already carry a
986
+ * weight.
987
+ *
988
+ * See iox-ai-guidance `architecture/cms/custom-icon-fonts.md`.
989
+ */
990
+ /** The weight classes Phosphor ships. `ph` is the regular weight. */
991
+ const PHOSPHOR_WEIGHTS = new Set(['ph', 'ph-thin', 'ph-light', 'ph-regular', 'ph-bold', 'ph-fill', 'ph-duotone']);
992
+ /** The weight assumed when a Phosphor class has none — the weight this platform uses everywhere. */
993
+ const DEFAULT_PHOSPHOR_WEIGHT = 'ph-thin';
994
+ function normalizeIconClass(iconClass) {
995
+ const raw = (iconClass ?? '').trim();
996
+ if (!raw)
997
+ return '';
998
+ const tokens = raw.split(/\s+/);
999
+ const hasWeight = tokens.some(token => PHOSPHOR_WEIGHTS.has(token));
1000
+ if (hasWeight)
1001
+ return tokens.join(' ');
1002
+ // `ph-` prefixed but weightless — the broken shape. A token that is only `ph-` is not a name.
1003
+ const hasPhosphorName = tokens.some(token => token.startsWith('ph-') && token.length > 3);
1004
+ if (!hasPhosphorName)
1005
+ return tokens.join(' ');
1006
+ return [DEFAULT_PHOSPHOR_WEIGHT, ...tokens].join(' ');
1007
+ }
1008
+
974
1009
  /** Directive-host icon: the `<i>` IS the host — no wrapper. All styles on `.iox-node`. */
975
1010
  class BuilderIconComponent {
976
1011
  constructor() {
@@ -978,12 +1013,20 @@ class BuilderIconComponent {
978
1013
  this.iconClass = 'ph-thin ph-star';
979
1014
  this.nodeId = '';
980
1015
  }
1016
+ /**
1017
+ * Repaired at render time: a Phosphor class saved without its weight (`ph-house`) matches no CSS
1018
+ * rule and renders as an invisible box. The picker used to emit exactly that, so this keeps
1019
+ * every already-saved icon working. Shared with the SSR engine — see `normalizeIconClass`.
1020
+ */
1021
+ get normalizedIconClass() {
1022
+ return normalizeIconClass(this.iconClass);
1023
+ }
981
1024
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: BuilderIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
982
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.31", type: BuilderIconComponent, isStandalone: false, selector: "i[iox-icon]", inputs: { iconClass: "iconClass", nodeId: "nodeId" }, host: { properties: { "class": "iconClass + ' iox-node-' + nodeId" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}\n"] }); }
1025
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.31", type: BuilderIconComponent, isStandalone: false, selector: "i[iox-icon]", inputs: { iconClass: "iconClass", nodeId: "nodeId" }, host: { properties: { "class": "normalizedIconClass + ' iox-node-' + nodeId" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}\n"] }); }
983
1026
  }
984
1027
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.31", ngImport: i0, type: BuilderIconComponent, decorators: [{
985
1028
  type: Component,
986
- args: [{ selector: 'i[iox-icon]', template: '', host: { '[class]': "iconClass + ' iox-node-' + nodeId" }, standalone: false, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}\n"] }]
1029
+ args: [{ selector: 'i[iox-icon]', template: '', host: { '[class]': "normalizedIconClass + ' iox-node-' + nodeId" }, standalone: false, styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0}\n"] }]
987
1030
  }], propDecorators: { iconClass: [{
988
1031
  type: Input
989
1032
  }], nodeId: [{
@@ -5562,7 +5605,7 @@ const SEO_CHANGE_FREQ_OPTIONS = [
5562
5605
  * Empty branches are dropped rather than left as `{}`, so `if (seo.og)` is a meaningful test.
5563
5606
  */
5564
5607
  function normalizeSeoDoc(raw) {
5565
- const src = asRecord(raw);
5608
+ const src = asRecord$1(raw);
5566
5609
  if (!src)
5567
5610
  return {};
5568
5611
  const og = compact({
@@ -5597,7 +5640,7 @@ function normalizeSeoDoc(raw) {
5597
5640
  }
5598
5641
  /** Read `src[branch][leaf]` without assuming the branch exists or is an object. */
5599
5642
  function pick(src, branch, leaf) {
5600
- const nested = asRecord(src[branch]);
5643
+ const nested = asRecord$1(src[branch]);
5601
5644
  return nested ? nested[leaf] : undefined;
5602
5645
  }
5603
5646
  /**
@@ -5608,7 +5651,7 @@ function pick(src, branch, leaf) {
5608
5651
  * `undefined` here and `resolveSeo` fills it in from the lower rungs.
5609
5652
  */
5610
5653
  function seoString(value) {
5611
- const wrapper = asRecord(value);
5654
+ const wrapper = asRecord$1(value);
5612
5655
  const raw = wrapper ? wrapper['override'] : value;
5613
5656
  if (typeof raw === 'number')
5614
5657
  return String(raw);
@@ -5653,10 +5696,10 @@ function structured(value) {
5653
5696
  }
5654
5697
  if (Array.isArray(value))
5655
5698
  return value.length ? value : undefined;
5656
- const record = asRecord(value);
5699
+ const record = asRecord$1(value);
5657
5700
  return record && Object.keys(record).length ? record : undefined;
5658
5701
  }
5659
- function asRecord(value) {
5702
+ function asRecord$1(value) {
5660
5703
  return value !== null && typeof value === 'object' && !Array.isArray(value)
5661
5704
  ? value
5662
5705
  : undefined;
@@ -5890,14 +5933,14 @@ function resolveSeo(seo, ctx = {}) {
5890
5933
  let derived;
5891
5934
  const content = () => (derived ??= deriveSeoFromContent(ctx.tree, ctx.resolvedData));
5892
5935
  for (const field of SEO_BINDABLE_FIELDS) {
5893
- if (readField(out, field) !== undefined)
5936
+ if (readField$1(out, field) !== undefined)
5894
5937
  continue; // an override won
5895
- const stored = fieldValue(raw, field);
5938
+ const stored = fieldValue$1(raw, field);
5896
5939
  // Rung 2 — the binding.
5897
5940
  if (stored?.binding) {
5898
5941
  const value = resolveSeoBinding(stored.binding, ctx.resolvedData);
5899
5942
  if (value !== undefined) {
5900
- writeField(out, field, value);
5943
+ writeField$1(out, field, value);
5901
5944
  continue;
5902
5945
  }
5903
5946
  }
@@ -5907,7 +5950,7 @@ function resolveSeo(seo, ctx = {}) {
5907
5950
  const source = SEO_AUTO_SOURCES.find(entry => entry.field === field)?.source;
5908
5951
  const auto = source ? autoValue(source, content, ctx) : undefined;
5909
5952
  if (auto !== undefined)
5910
- writeField(out, field, auto);
5953
+ writeField$1(out, field, auto);
5911
5954
  }
5912
5955
  // One last pass so a resolved value gets the same trimming and empty-branch dropping as a stored
5913
5956
  // one — `if (seo.og)` must keep meaning something.
@@ -6024,20 +6067,20 @@ function truncate(value, max) {
6024
6067
  return (lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd() + '…';
6025
6068
  }
6026
6069
  // ── dotted-path access over the document, so the field table stays data and not a switch ───────────
6027
- function fieldValue(raw, field) {
6028
- const value = readField(raw, field);
6070
+ function fieldValue$1(raw, field) {
6071
+ const value = readField$1(raw, field);
6029
6072
  if (value === null || typeof value !== 'object' || Array.isArray(value))
6030
6073
  return undefined;
6031
6074
  return value;
6032
6075
  }
6033
- function readField(doc, field) {
6076
+ function readField$1(doc, field) {
6034
6077
  const [branch, leaf] = field.split('.');
6035
6078
  if (!leaf)
6036
6079
  return doc[branch];
6037
6080
  const nested = doc[branch];
6038
6081
  return nested && typeof nested === 'object' ? nested[leaf] : undefined;
6039
6082
  }
6040
- function writeField(doc, field, value) {
6083
+ function writeField$1(doc, field, value) {
6041
6084
  const [branch, leaf] = field.split('.');
6042
6085
  if (!leaf) {
6043
6086
  doc[branch] = value;
@@ -6048,6 +6091,137 @@ function writeField(doc, field, value) {
6048
6091
  doc[branch] = nested;
6049
6092
  }
6050
6093
 
6094
+ const MAX_LENGTHS = {
6095
+ title: SEO_TITLE_MAX,
6096
+ description: SEO_DESCRIPTION_MAX,
6097
+ 'og.description': SEO_DESCRIPTION_MAX,
6098
+ 'twitter.description': SEO_DESCRIPTION_MAX,
6099
+ };
6100
+ /**
6101
+ * Describe every bindable field for the authoring panel.
6102
+ *
6103
+ * ⚠️ `resolved` is deliberately EMPTY for a bound field on the builder side. The canvas has no
6104
+ * page-level resolved data — each component fetches its own — so a bound value genuinely is not
6105
+ * knowable here. Showing the binding expression and saying so is honest; inventing a preview from
6106
+ * design-time props is how a placeholder ends up looking like real content.
6107
+ */
6108
+ function describeSeoFields(seo, ctx = {}) {
6109
+ const raw = asRecord(seo) ?? {};
6110
+ const resolvedDoc = resolveSeo(seo, ctx);
6111
+ return SEO_BINDABLE_FIELDS.map(field => {
6112
+ const stored = fieldValue(raw, field);
6113
+ const override = seoString(readField(raw, field)) ?? '';
6114
+ const binding = stored?.binding;
6115
+ const resolved = seoString(readField(resolvedDoc, field)) ?? '';
6116
+ let source;
6117
+ if (override)
6118
+ source = 'manual';
6119
+ else if (binding)
6120
+ source = 'bound';
6121
+ else if (resolved)
6122
+ source = 'auto';
6123
+ else
6124
+ source = 'empty';
6125
+ return {
6126
+ field,
6127
+ override,
6128
+ binding,
6129
+ // A bound field's value comes from data this side cannot see.
6130
+ resolved: source === 'bound' ? '' : resolved,
6131
+ source,
6132
+ maxLength: MAX_LENGTHS[field],
6133
+ };
6134
+ });
6135
+ }
6136
+ /** Set a field's typed value. An empty string CLEARS the override so the lower rungs take over. */
6137
+ function setSeoOverride(seo, field, value) {
6138
+ const next = clone(seo);
6139
+ const text = value?.trim() ?? '';
6140
+ const existing = fieldValue(next, field);
6141
+ if (!text) {
6142
+ // Nothing else on the field → drop it entirely, so the document stays free of `{}` husks.
6143
+ if (!existing?.binding && existing?.auto !== false)
6144
+ writeField(next, field, undefined);
6145
+ else
6146
+ writeField(next, field, stripUndefined({ binding: existing?.binding, auto: existing?.auto }));
6147
+ return next;
6148
+ }
6149
+ writeField(next, field, stripUndefined({ override: text, binding: existing?.binding, auto: existing?.auto }));
6150
+ return next;
6151
+ }
6152
+ /** Attach or replace a field's binding. `undefined` removes it. */
6153
+ function setSeoBinding(seo, field, binding) {
6154
+ const next = clone(seo);
6155
+ const existing = fieldValue(next, field);
6156
+ const value = stripUndefined({ override: existing?.override, binding, auto: existing?.auto });
6157
+ writeField(next, field, Object.keys(value).length ? value : undefined);
6158
+ return next;
6159
+ }
6160
+ /** Turn the automatic rung on or off for a field. Off leaves the field genuinely empty. */
6161
+ function setSeoAuto(seo, field, enabled) {
6162
+ const next = clone(seo);
6163
+ const existing = fieldValue(next, field);
6164
+ const value = stripUndefined({
6165
+ override: existing?.override,
6166
+ binding: existing?.binding,
6167
+ auto: enabled ? undefined : false,
6168
+ });
6169
+ writeField(next, field, Object.keys(value).length ? value : undefined);
6170
+ return next;
6171
+ }
6172
+ /** Drop everything an author set on a field — back to the automatic rung. */
6173
+ function resetSeoField(seo, field) {
6174
+ const next = clone(seo);
6175
+ writeField(next, field, undefined);
6176
+ return next;
6177
+ }
6178
+ // ── shared dotted-path plumbing ───────────────────────────────────────────────────────────────
6179
+ function clone(seo) {
6180
+ return JSON.parse(JSON.stringify(asRecord(seo) ?? {}));
6181
+ }
6182
+ function asRecord(value) {
6183
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
6184
+ ? value
6185
+ : undefined;
6186
+ }
6187
+ function stripUndefined(value) {
6188
+ const out = {};
6189
+ for (const [key, entry] of Object.entries(value))
6190
+ if (entry !== undefined)
6191
+ out[key] = entry;
6192
+ return out;
6193
+ }
6194
+ function fieldValue(doc, field) {
6195
+ const value = readField(doc, field);
6196
+ return asRecord(value);
6197
+ }
6198
+ function readField(doc, field) {
6199
+ const [branch, leaf] = field.split('.');
6200
+ if (!leaf)
6201
+ return doc[branch];
6202
+ const nested = asRecord(doc[branch]);
6203
+ return nested ? nested[leaf] : undefined;
6204
+ }
6205
+ function writeField(doc, field, value) {
6206
+ const [branch, leaf] = field.split('.');
6207
+ if (!leaf) {
6208
+ if (value === undefined)
6209
+ delete doc[branch];
6210
+ else
6211
+ doc[branch] = value;
6212
+ return;
6213
+ }
6214
+ const nested = (asRecord(doc[branch]) ?? {});
6215
+ if (value === undefined)
6216
+ delete nested[leaf];
6217
+ else
6218
+ nested[leaf] = value;
6219
+ if (Object.keys(nested).length)
6220
+ doc[branch] = nested;
6221
+ else
6222
+ delete doc[branch];
6223
+ }
6224
+
6051
6225
  /**
6052
6226
  * Element context state — shared types.
6053
6227
  *
@@ -6735,5 +6909,5 @@ function effectiveTransitionId(anim) {
6735
6909
  * Generated bundle index. Do not edit.
6736
6910
  */
6737
6911
 
6738
- export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, defaultMessageResolver, deriveSeoFromContent, effectiveTransitionId, excludeSelf, feelFor, getByPath, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
6912
+ export { AOSService, AnalyticsService, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CONTEXT_ACTION_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, ContextStore, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DeclarationContext, ENVIRONMENT, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, RESERVED_ALIAS_PREFIX, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_RESPONSIVE_TRAITS, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, activeActions, applyBindingPipes, applyFeel, breakpointDef, breakpointForWidth, breakpointQueryFor, buildDataSourceFilter, buildRelatedFilter, buildSwiperBreakpoints, buildTargetedStateSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, collectContextSlotKeys, collectReferencedAliases, compileDeclarations, composeVirtualTraits, computeRelative, contextActionEffect, contextSlotKeys, countOverrides, dataSourcePlanToRequest, declaredInputNames, defaultMessageResolver, deriveSeoFromContent, describeSeoFields, effectiveTransitionId, excludeSelf, feelFor, getByPath, initialSlotValues, isActionEnabled, isContextAction, isInputOverriddenAt, isOverriddenAt, isReservedAlias, isValidSlotKey, legacyEnterToTransition, matchRouteParams, mediaQueryFor, mergeSwiperBreakpoints, nearestCommonAncestorId, nodeCssId, nodeUsesContext, normalizeCollectionResult, normalizeGalleryImage, normalizeIconClass, parentBreakpoint, parseUrlList, planDataSource, planResponsiveRules, referencedDataSources, referencedDataSourcesDeep, renderDefaultDeclarations, resetSeoField, resolveBoundValue, resolveContextValue, resolveDerivedInto, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolvePageTransition, resolvePath, resolveRelativeInto, resolveRepeaterItems, resolveSeo, resolveSiblings, resolveSingleItemId, resolveStateStyles, resolveStyleProps, resolveValueChain, rewriteViewportUnits, safeSetInput, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, stateNamesIn, stripSuppressedProps, styleKeyToKebab, variableAliases, variableItemsFrom, withContextSlots, wrapInBreakpointQuery, wrapInMediaQuery };
6739
6913
  //# sourceMappingURL=vectoriox-iox-ui.mjs.map