@masterteam/formula-builder 0.0.6 → 0.0.8
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.
|
@@ -77,6 +77,7 @@ class FormulaValidatorService {
|
|
|
77
77
|
this.validateSubject
|
|
78
78
|
.pipe(debounceTime(this.DEBOUNCE_MS), distinctUntilChanged((a, b) => a.formula === b.formula &&
|
|
79
79
|
a.levelSchemaId === b.levelSchemaId &&
|
|
80
|
+
a.moduleId === b.moduleId &&
|
|
80
81
|
a.templateId === b.templateId &&
|
|
81
82
|
a.apiMode === b.apiMode &&
|
|
82
83
|
JSON.stringify(a.knownProperties) ===
|
|
@@ -87,7 +88,7 @@ class FormulaValidatorService {
|
|
|
87
88
|
});
|
|
88
89
|
}
|
|
89
90
|
/** Validate formula (debounced) */
|
|
90
|
-
validate(formula, knownProperties, levelSchemaId, templateId, apiMode = 'default') {
|
|
91
|
+
validate(formula, knownProperties, levelSchemaId, moduleId, templateId, apiMode = 'default') {
|
|
91
92
|
// Handle empty formula
|
|
92
93
|
if (!formula || formula.trim() === '') {
|
|
93
94
|
this._validation.set(EMPTY_VALIDATION);
|
|
@@ -98,12 +99,13 @@ class FormulaValidatorService {
|
|
|
98
99
|
formula,
|
|
99
100
|
knownProperties,
|
|
100
101
|
levelSchemaId,
|
|
102
|
+
moduleId,
|
|
101
103
|
templateId,
|
|
102
104
|
apiMode,
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
107
|
/** Validate formula immediately (no debounce) */
|
|
106
|
-
validateImmediate(formula, knownProperties, levelSchemaId, templateId, apiMode = 'default') {
|
|
108
|
+
validateImmediate(formula, knownProperties, levelSchemaId, moduleId, templateId, apiMode = 'default') {
|
|
107
109
|
if (!formula || formula.trim() === '') {
|
|
108
110
|
return of(EMPTY_VALIDATION);
|
|
109
111
|
}
|
|
@@ -112,6 +114,7 @@ class FormulaValidatorService {
|
|
|
112
114
|
formula,
|
|
113
115
|
knownProperties,
|
|
114
116
|
levelSchemaId,
|
|
117
|
+
moduleId,
|
|
115
118
|
templateId,
|
|
116
119
|
apiMode,
|
|
117
120
|
}).pipe(tap((result) => {
|
|
@@ -195,17 +198,23 @@ class FormulaContextService {
|
|
|
195
198
|
contextCache = new Map();
|
|
196
199
|
propertiesCache = new Map();
|
|
197
200
|
nextTokensCache = new Map();
|
|
198
|
-
loadContext(schemaId, contextEntityTypeKey, mode = 'default') {
|
|
201
|
+
loadContext(schemaId, moduleId, contextEntityTypeKey, mode = 'default') {
|
|
199
202
|
if (!schemaId)
|
|
200
203
|
return of(null);
|
|
201
|
-
const cacheKey = `${mode}:${schemaId}:${contextEntityTypeKey ?? ''}`;
|
|
204
|
+
const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${contextEntityTypeKey ?? ''}`;
|
|
202
205
|
const cached = this.contextCache.get(cacheKey);
|
|
203
206
|
if (cached) {
|
|
204
207
|
return of(cached);
|
|
205
208
|
}
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
const params = new URLSearchParams();
|
|
210
|
+
if (mode === 'default' && contextEntityTypeKey) {
|
|
211
|
+
params.set('contextEntityTypeKey', contextEntityTypeKey);
|
|
212
|
+
}
|
|
213
|
+
if (moduleId !== undefined) {
|
|
214
|
+
params.set('moduleId', moduleId.toString());
|
|
215
|
+
}
|
|
216
|
+
const queryString = params.toString();
|
|
217
|
+
const query = queryString ? `?${queryString}` : '';
|
|
209
218
|
return this.http
|
|
210
219
|
.get(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)
|
|
211
220
|
.pipe(map((response) => this.unwrapResponse(response)), tap((context) => {
|
|
@@ -217,12 +226,12 @@ class FormulaContextService {
|
|
|
217
226
|
return of(null);
|
|
218
227
|
}));
|
|
219
228
|
}
|
|
220
|
-
getScopeProperties(schemaId, component, tablePath, mode = 'default') {
|
|
229
|
+
getScopeProperties(schemaId, component, tablePath, moduleId, mode = 'default') {
|
|
221
230
|
if (!schemaId || !component || !tablePath)
|
|
222
231
|
return of([]);
|
|
223
232
|
if (mode === 'current-only')
|
|
224
233
|
return of([]);
|
|
225
|
-
const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;
|
|
234
|
+
const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;
|
|
226
235
|
const cached = this.propertiesCache.get(cacheKey);
|
|
227
236
|
if (cached) {
|
|
228
237
|
return of(cached);
|
|
@@ -232,6 +241,9 @@ class FormulaContextService {
|
|
|
232
241
|
component,
|
|
233
242
|
tablePath,
|
|
234
243
|
});
|
|
244
|
+
if (moduleId !== undefined) {
|
|
245
|
+
params.set('moduleId', moduleId.toString());
|
|
246
|
+
}
|
|
235
247
|
return this.http
|
|
236
248
|
.get(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)
|
|
237
249
|
.pipe(map((response) => this.unwrapResponse(response) ?? []), tap((response) => {
|
|
@@ -241,12 +253,12 @@ class FormulaContextService {
|
|
|
241
253
|
return of([]);
|
|
242
254
|
}));
|
|
243
255
|
}
|
|
244
|
-
getNextTokens(schemaId, component, tablePath, mode = 'default') {
|
|
256
|
+
getNextTokens(schemaId, component, tablePath, moduleId, mode = 'default') {
|
|
245
257
|
if (!schemaId || !component || !tablePath)
|
|
246
258
|
return of(null);
|
|
247
259
|
if (mode === 'current-only')
|
|
248
260
|
return of(null);
|
|
249
|
-
const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;
|
|
261
|
+
const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;
|
|
250
262
|
const cached = this.nextTokensCache.get(cacheKey);
|
|
251
263
|
if (cached) {
|
|
252
264
|
return of(cached);
|
|
@@ -256,6 +268,9 @@ class FormulaContextService {
|
|
|
256
268
|
component,
|
|
257
269
|
tablePath,
|
|
258
270
|
});
|
|
271
|
+
if (moduleId !== undefined) {
|
|
272
|
+
params.set('moduleId', moduleId.toString());
|
|
273
|
+
}
|
|
259
274
|
return this.http
|
|
260
275
|
.get(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)
|
|
261
276
|
.pipe(map((response) => this.unwrapResponse(response)), tap((payload) => {
|
|
@@ -410,8 +425,17 @@ const DEFAULT_TOOLBAR_TABS = [
|
|
|
410
425
|
'properties',
|
|
411
426
|
'operators',
|
|
412
427
|
];
|
|
428
|
+
const PROPERTY_SCOPE_ORDER = [
|
|
429
|
+
'Current',
|
|
430
|
+
'Host',
|
|
431
|
+
'Parent',
|
|
432
|
+
// 'Children',
|
|
433
|
+
// 'Descendants',
|
|
434
|
+
// 'Modules',
|
|
435
|
+
];
|
|
413
436
|
const SCOPE_ICON_MAP = {
|
|
414
437
|
Current: 'map.marker-pin-01',
|
|
438
|
+
Host: 'map.marker-pin-01',
|
|
415
439
|
Level: 'map.marker-pin-01',
|
|
416
440
|
Parent: 'arrow.arrow-up',
|
|
417
441
|
Children: 'user.users-01',
|
|
@@ -430,6 +454,8 @@ class FormulaBuilder {
|
|
|
430
454
|
propertiesByPath = input({}, ...(ngDevMode ? [{ debugName: "propertiesByPath" }] : []));
|
|
431
455
|
/** Level schema ID for validation context */
|
|
432
456
|
levelSchemaId = input(...(ngDevMode ? [undefined, { debugName: "levelSchemaId" }] : []));
|
|
457
|
+
/** Optional module ID when the formula is scoped inside a level-linked module */
|
|
458
|
+
moduleId = input(...(ngDevMode ? [undefined, { debugName: "moduleId" }] : []));
|
|
433
459
|
/** Optional current context entity key, e.g. LevelData or Risk */
|
|
434
460
|
contextEntityTypeKey = input(...(ngDevMode ? [undefined, { debugName: "contextEntityTypeKey" }] : []));
|
|
435
461
|
/** Template ID for validation context */
|
|
@@ -468,10 +494,20 @@ class FormulaBuilder {
|
|
|
468
494
|
const normalized = value.trim();
|
|
469
495
|
return normalized.length > 0 ? normalized : undefined;
|
|
470
496
|
}, ...(ngDevMode ? [{ debugName: "resolvedContextEntityTypeKey" }] : []));
|
|
497
|
+
isModuleContext = computed(() => {
|
|
498
|
+
const contextType = this.resolvedContextEntityTypeKey() ??
|
|
499
|
+
this.builderContext()?.contextEntityTypeKey;
|
|
500
|
+
if (typeof contextType !== 'string') {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
const normalized = contextType.trim().toLowerCase();
|
|
504
|
+
return normalized.length > 0 && normalized !== 'leveldata';
|
|
505
|
+
}, ...(ngDevMode ? [{ debugName: "isModuleContext" }] : []));
|
|
471
506
|
autocompleteProvider = (request) => {
|
|
472
507
|
return this.autocompleteService.getSuggestions({
|
|
473
508
|
...request,
|
|
474
509
|
levelSchemaId: this.levelSchemaId(),
|
|
510
|
+
moduleId: this.moduleId(),
|
|
475
511
|
contextEntityTypeKey: this.resolvedContextEntityTypeKey() ??
|
|
476
512
|
this.builderContext()?.contextEntityTypeKey,
|
|
477
513
|
}, this.isProcessBuilder() ? 'current-only' : 'default');
|
|
@@ -514,9 +550,10 @@ class FormulaBuilder {
|
|
|
514
550
|
// Validate when formula changes
|
|
515
551
|
effect(() => {
|
|
516
552
|
const formula = this.expressionValue();
|
|
553
|
+
const moduleId = this.moduleId();
|
|
517
554
|
const apiMode = this.formulaApiMode();
|
|
518
555
|
if (formula && formula.trim().length > 0) {
|
|
519
|
-
this.validatorService.validate(formula, undefined, this.levelSchemaId(), this.templateId(), apiMode);
|
|
556
|
+
this.validatorService.validate(formula, undefined, this.levelSchemaId(), moduleId, this.templateId(), apiMode);
|
|
520
557
|
}
|
|
521
558
|
});
|
|
522
559
|
// Emit validation changes
|
|
@@ -527,6 +564,7 @@ class FormulaBuilder {
|
|
|
527
564
|
// Load builder context when schema changes
|
|
528
565
|
effect(() => {
|
|
529
566
|
const schemaId = this.levelSchemaId();
|
|
567
|
+
const moduleId = this.moduleId();
|
|
530
568
|
const apiMode = this.formulaApiMode();
|
|
531
569
|
const contextEntityTypeKey = this.resolvedContextEntityTypeKey();
|
|
532
570
|
if (!schemaId) {
|
|
@@ -541,7 +579,7 @@ class FormulaBuilder {
|
|
|
541
579
|
this.propertiesByPathApi.set({});
|
|
542
580
|
this.nextTokenRulesByPath.set({});
|
|
543
581
|
this.contextService
|
|
544
|
-
.loadContext(schemaId, contextEntityTypeKey, apiMode)
|
|
582
|
+
.loadContext(schemaId, moduleId, contextEntityTypeKey, apiMode)
|
|
545
583
|
.subscribe((context) => {
|
|
546
584
|
if (requestId !== this.contextRequestId) {
|
|
547
585
|
return;
|
|
@@ -579,6 +617,7 @@ class FormulaBuilder {
|
|
|
579
617
|
// Fetch properties for the selected table path
|
|
580
618
|
effect(() => {
|
|
581
619
|
const schemaId = this.levelSchemaId();
|
|
620
|
+
const moduleId = this.moduleId();
|
|
582
621
|
const isProcessBuilder = this.isProcessBuilder();
|
|
583
622
|
const tablePath = this.resolvedTablePath();
|
|
584
623
|
const component = this.propertiesComponent();
|
|
@@ -598,7 +637,7 @@ class FormulaBuilder {
|
|
|
598
637
|
}
|
|
599
638
|
this.propertyLoadingPath.set(tablePath);
|
|
600
639
|
this.contextService
|
|
601
|
-
.getScopeProperties(schemaId, component, tablePath)
|
|
640
|
+
.getScopeProperties(schemaId, component, tablePath, moduleId)
|
|
602
641
|
.subscribe((props) => {
|
|
603
642
|
this.propertiesByPathApi.update((current) => ({
|
|
604
643
|
...current,
|
|
@@ -612,6 +651,7 @@ class FormulaBuilder {
|
|
|
612
651
|
// Fetch next-token rules for the current table path
|
|
613
652
|
effect(() => {
|
|
614
653
|
const schemaId = this.levelSchemaId();
|
|
654
|
+
const moduleId = this.moduleId();
|
|
615
655
|
const isProcessBuilder = this.isProcessBuilder();
|
|
616
656
|
const tablePath = this.resolvedTablePath();
|
|
617
657
|
const component = this.propertiesComponent();
|
|
@@ -620,7 +660,7 @@ class FormulaBuilder {
|
|
|
620
660
|
if (this.nextTokenRulesByPath()[tablePath])
|
|
621
661
|
return;
|
|
622
662
|
this.contextService
|
|
623
|
-
.getNextTokens(schemaId, component, tablePath)
|
|
663
|
+
.getNextTokens(schemaId, component, tablePath, moduleId)
|
|
624
664
|
.subscribe((response) => {
|
|
625
665
|
if (!response)
|
|
626
666
|
return;
|
|
@@ -898,7 +938,10 @@ class FormulaBuilder {
|
|
|
898
938
|
const operators = this.contextOperators();
|
|
899
939
|
if (operators.length === 0)
|
|
900
940
|
return [];
|
|
901
|
-
|
|
941
|
+
const operatorsByToken = new Map(operators.map((operator) => [operator.token, operator]));
|
|
942
|
+
return PROPERTY_SCOPE_ORDER.map((token) => operatorsByToken.get(token))
|
|
943
|
+
.filter((operator) => Boolean(operator))
|
|
944
|
+
.map((operator) => ({
|
|
902
945
|
key: operator.token,
|
|
903
946
|
label: `@${operator.token}`,
|
|
904
947
|
requiresParam: operator.requiresParameter ?? false,
|
|
@@ -908,7 +951,7 @@ class FormulaBuilder {
|
|
|
908
951
|
/** Radio card options for scope selection */
|
|
909
952
|
scopeOptions = computed(() => this.availableScopes().map((scope) => ({
|
|
910
953
|
id: scope.key,
|
|
911
|
-
name: scope.key,
|
|
954
|
+
name: this.getOperatorDisplayName(scope.key),
|
|
912
955
|
icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,
|
|
913
956
|
})), ...(ngDevMode ? [{ debugName: "scopeOptions" }] : []));
|
|
914
957
|
/** Handle scope selection from radio cards */
|
|
@@ -1062,14 +1105,20 @@ class FormulaBuilder {
|
|
|
1062
1105
|
const block = createPropertyBlock(`@${tablePath}::${prop.key}`, 'current', display);
|
|
1063
1106
|
insertBlock(block);
|
|
1064
1107
|
}
|
|
1108
|
+
getOperatorDisplayName(token) {
|
|
1109
|
+
if (token === 'Host' && this.isModuleContext()) {
|
|
1110
|
+
return 'Level';
|
|
1111
|
+
}
|
|
1112
|
+
return token;
|
|
1113
|
+
}
|
|
1065
1114
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FormulaBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1066
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FormulaBuilder, isStandalone: true, selector: "mt-formula-builder", inputs: { propertiesByPath: { classPropertyName: "propertiesByPath", publicName: "propertiesByPath", isSignal: true, isRequired: false, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null }, contextEntityTypeKey: { classPropertyName: "contextEntityTypeKey", publicName: "contextEntityTypeKey", isSignal: true, isRequired: false, transformFunction: null }, templateId: { classPropertyName: "templateId", publicName: "templateId", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hideToolbar: { classPropertyName: "hideToolbar", publicName: "hideToolbar", isSignal: true, isRequired: false, transformFunction: null }, hideStatusBar: { classPropertyName: "hideStatusBar", publicName: "hideStatusBar", isSignal: true, isRequired: false, transformFunction: null }, toolbarTabs: { classPropertyName: "toolbarTabs", publicName: "toolbarTabs", isSignal: true, isRequired: false, transformFunction: null }, codeOnly: { classPropertyName: "codeOnly", publicName: "codeOnly", isSignal: true, isRequired: false, transformFunction: null }, isProcessBuilder: { classPropertyName: "isProcessBuilder", publicName: "isProcessBuilder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validationChange: "validationChange", tokensChange: "tokensChange" }, host: { classAttribute: "block" }, providers: [
|
|
1115
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FormulaBuilder, isStandalone: true, selector: "mt-formula-builder", inputs: { propertiesByPath: { classPropertyName: "propertiesByPath", publicName: "propertiesByPath", isSignal: true, isRequired: false, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null }, moduleId: { classPropertyName: "moduleId", publicName: "moduleId", isSignal: true, isRequired: false, transformFunction: null }, contextEntityTypeKey: { classPropertyName: "contextEntityTypeKey", publicName: "contextEntityTypeKey", isSignal: true, isRequired: false, transformFunction: null }, templateId: { classPropertyName: "templateId", publicName: "templateId", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hideToolbar: { classPropertyName: "hideToolbar", publicName: "hideToolbar", isSignal: true, isRequired: false, transformFunction: null }, hideStatusBar: { classPropertyName: "hideStatusBar", publicName: "hideStatusBar", isSignal: true, isRequired: false, transformFunction: null }, toolbarTabs: { classPropertyName: "toolbarTabs", publicName: "toolbarTabs", isSignal: true, isRequired: false, transformFunction: null }, codeOnly: { classPropertyName: "codeOnly", publicName: "codeOnly", isSignal: true, isRequired: false, transformFunction: null }, isProcessBuilder: { classPropertyName: "isProcessBuilder", publicName: "isProcessBuilder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validationChange: "validationChange", tokensChange: "tokensChange" }, host: { classAttribute: "block" }, providers: [
|
|
1067
1116
|
{
|
|
1068
1117
|
provide: NG_VALUE_ACCESSOR,
|
|
1069
1118
|
useExisting: forwardRef(() => FormulaBuilder),
|
|
1070
1119
|
multi: true,
|
|
1071
1120
|
},
|
|
1072
|
-
], viewQueries: [{ propertyName: "editor", first: true, predicate: ["formulaEditor"], descendants: true, isSignal: true }, { propertyName: "codeEditor", first: true, predicate: ["formulaEditorCode"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: RadioCards, selector: "mt-radio-cards", inputs: ["circle", "color", "size", "columns", "options", "activeId", "itemTemplate"], outputs: ["optionsChange", "activeIdChange", "selectionChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: FormulaToolbar, selector: "mt-formula-toolbar", inputs: ["knownProperties", "propertiesTemplate", "functionCategories", "operators", "initialTab", "visibleTabs", "searchPlaceholder", "labels"], outputs: ["onBlockInsert", "onTabChange"] }, { kind: "component", type: FormulaStatusBar, selector: "mt-formula-status-bar", inputs: ["validation", "labels"] }, { kind: "component", type: FormulaEditor, selector: "mt-formula-editor", inputs: ["placeholder", "initialTokens", "disabled", "borderless"], outputs: ["formulaChange", "tokensChange", "onBlur", "onFocus"] }, { kind: "component", type: FormulaEditorCode, selector: "mt-formula-editor-code", inputs: ["placeholder", "initialFormula", "disabled", "language", "theme", "borderless", "autocompleteProvider", "autocompleteDebounceMs"], outputs: ["formulaChange", "onBlur", "onFocus"] }] });
|
|
1121
|
+
], viewQueries: [{ propertyName: "editor", first: true, predicate: ["formulaEditor"], descendants: true, isSignal: true }, { propertyName: "codeEditor", first: true, predicate: ["formulaEditorCode"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }, { kind: "component", type: RadioCards, selector: "mt-radio-cards", inputs: ["circle", "color", "size", "columns", "options", "activeId", "itemTemplate"], outputs: ["optionsChange", "activeIdChange", "selectionChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: FormulaToolbar, selector: "mt-formula-toolbar", inputs: ["knownProperties", "propertiesTemplate", "functionCategories", "operators", "initialTab", "visibleTabs", "searchPlaceholder", "labels"], outputs: ["onBlockInsert", "onTabChange"] }, { kind: "component", type: FormulaStatusBar, selector: "mt-formula-status-bar", inputs: ["validation", "labels"] }, { kind: "component", type: FormulaEditor, selector: "mt-formula-editor", inputs: ["placeholder", "initialTokens", "disabled", "borderless"], outputs: ["formulaChange", "tokensChange", "onBlur", "onFocus"] }, { kind: "component", type: FormulaEditorCode, selector: "mt-formula-editor-code", inputs: ["placeholder", "initialFormula", "disabled", "language", "theme", "borderless", "autocompleteProvider", "autocompleteDebounceMs"], outputs: ["formulaChange", "onBlur", "onFocus"] }] });
|
|
1073
1122
|
}
|
|
1074
1123
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FormulaBuilder, decorators: [{
|
|
1075
1124
|
type: Component,
|
|
@@ -1097,8 +1146,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1097
1146
|
useExisting: forwardRef(() => FormulaBuilder),
|
|
1098
1147
|
multi: true,
|
|
1099
1148
|
},
|
|
1100
|
-
], template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n" }]
|
|
1101
|
-
}], ctorParameters: () => [], propDecorators: { editor: [{ type: i0.ViewChild, args: ['formulaEditor', { isSignal: true }] }], codeEditor: [{ type: i0.ViewChild, args: ['formulaEditorCode', { isSignal: true }] }], propertiesByPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertiesByPath", required: false }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }], contextEntityTypeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextEntityTypeKey", required: false }] }], templateId: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateId", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hideToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideToolbar", required: false }] }], hideStatusBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideStatusBar", required: false }] }], toolbarTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarTabs", required: false }] }], codeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "codeOnly", required: false }] }], isProcessBuilder: [{ type: i0.Input, args: [{ isSignal: true, alias: "isProcessBuilder", required: false }] }], validationChange: [{ type: i0.Output, args: ["validationChange"] }], tokensChange: [{ type: i0.Output, args: ["tokensChange"] }] } });
|
|
1149
|
+
], template: "<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n \u2713 {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >\u203A</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n" }]
|
|
1150
|
+
}], ctorParameters: () => [], propDecorators: { editor: [{ type: i0.ViewChild, args: ['formulaEditor', { isSignal: true }] }], codeEditor: [{ type: i0.ViewChild, args: ['formulaEditorCode', { isSignal: true }] }], propertiesByPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertiesByPath", required: false }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }], moduleId: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleId", required: false }] }], contextEntityTypeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextEntityTypeKey", required: false }] }], templateId: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateId", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hideToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideToolbar", required: false }] }], hideStatusBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideStatusBar", required: false }] }], toolbarTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbarTabs", required: false }] }], codeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "codeOnly", required: false }] }], isProcessBuilder: [{ type: i0.Input, args: [{ isSignal: true, alias: "isProcessBuilder", required: false }] }], validationChange: [{ type: i0.Output, args: ["validationChange"] }], tokensChange: [{ type: i0.Output, args: ["tokensChange"] }] } });
|
|
1102
1151
|
|
|
1103
1152
|
/**
|
|
1104
1153
|
* Services barrel export
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masterteam-formula-builder.mjs","sources":["../../../../packages/masterteam/formula-builder/src/lib/services/formula-validator.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-context.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-autocomplete.service.ts","../../../../packages/masterteam/formula-builder/src/lib/utils/formula-path-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.html","../../../../packages/masterteam/formula-builder/src/lib/services/index.ts","../../../../packages/masterteam/formula-builder/src/public-api.ts","../../../../packages/masterteam/formula-builder/src/masterteam-formula-builder.ts"],"sourcesContent":["/**\r\n * Formula Validator Service\r\n * Handles real-time validation via API\r\n */\r\n\r\nimport { Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\r\nimport {\r\n Observable,\r\n Subject,\r\n of,\r\n catchError,\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n tap,\r\n} from 'rxjs';\r\nimport {\r\n ValidationResult,\r\n ValidationRequest,\r\n ApiErrorResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\ntype ValidationJob = ValidationRequest & { apiMode: FormulaApiMode };\r\n\r\n/** Default validation result for empty formulas */\r\nconst EMPTY_VALIDATION: ValidationResult = {\r\n isValid: true,\r\n errors: [],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n/** Error validation result */\r\nconst ERROR_VALIDATION: ValidationResult = {\r\n isValid: false,\r\n errors: [\r\n { message: 'Validation failed', line: 1, column: 1, severity: 'Error' },\r\n ],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaValidatorService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n /** Debounce time in ms */\r\n private readonly DEBOUNCE_MS = 300;\r\n\r\n /** Current validation result */\r\n private readonly _validation = signal<ValidationResult>(EMPTY_VALIDATION);\r\n\r\n /** Loading state */\r\n private readonly _isValidating = signal(false);\r\n\r\n /** Validation subject for debouncing */\r\n private readonly validateSubject = new Subject<ValidationJob>();\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n /** Public signals */\r\n readonly validation = this._validation.asReadonly();\r\n readonly isValidating = this._isValidating.asReadonly();\r\n\r\n constructor() {\r\n this.setupValidationStream();\r\n }\r\n\r\n /** Setup debounced validation stream */\r\n private setupValidationStream(): void {\r\n this.validateSubject\r\n .pipe(\r\n debounceTime(this.DEBOUNCE_MS),\r\n distinctUntilChanged(\r\n (a, b) =>\r\n a.formula === b.formula &&\r\n a.levelSchemaId === b.levelSchemaId &&\r\n a.templateId === b.templateId &&\r\n a.apiMode === b.apiMode &&\r\n JSON.stringify(a.knownProperties) ===\r\n JSON.stringify(b.knownProperties),\r\n ),\r\n tap(() => this._isValidating.set(true)),\r\n switchMap((request) => this.callValidateApi(request)),\r\n )\r\n .subscribe((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n });\r\n }\r\n\r\n /** Validate formula (debounced) */\r\n validate(\r\n formula: string,\r\n knownProperties?: string[],\r\n levelSchemaId?: number,\r\n templateId?: number,\r\n apiMode: FormulaApiMode = 'default',\r\n ): void {\r\n // Handle empty formula\r\n if (!formula || formula.trim() === '') {\r\n this._validation.set(EMPTY_VALIDATION);\r\n return;\r\n }\r\n\r\n // Push to debounced stream\r\n this.validateSubject.next({\r\n formula,\r\n knownProperties,\r\n levelSchemaId,\r\n templateId,\r\n apiMode,\r\n });\r\n }\r\n\r\n /** Validate formula immediately (no debounce) */\r\n validateImmediate(\r\n formula: string,\r\n knownProperties?: string[],\r\n levelSchemaId?: number,\r\n templateId?: number,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<ValidationResult> {\r\n if (!formula || formula.trim() === '') {\r\n return of(EMPTY_VALIDATION);\r\n }\r\n\r\n this._isValidating.set(true);\r\n\r\n return this.callValidateApi({\r\n formula,\r\n knownProperties,\r\n levelSchemaId,\r\n templateId,\r\n apiMode,\r\n }).pipe(\r\n tap((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n }),\r\n );\r\n }\r\n\r\n /** Call validation API */\r\n private callValidateApi(\r\n request: ValidationJob,\r\n ): Observable<ValidationResult> {\r\n const { apiMode, ...payload } = request;\r\n return this.http\r\n .post<\r\n ValidationResult | { data: ValidationResult }\r\n >(`${this.getBaseUrl(apiMode)}/validate`, payload)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? ERROR_VALIDATION),\r\n catchError((error: HttpErrorResponse) => {\r\n console.error('Validation API error:', error);\r\n\r\n // Try to extract error message\r\n const apiError = error.error as ApiErrorResponse;\r\n const message =\r\n apiError?.message ?? apiError?.error ?? 'Validation failed';\r\n\r\n return of({\r\n ...ERROR_VALIDATION,\r\n errors: [\r\n { message, line: 1, column: 1, severity: 'Error' as const },\r\n ],\r\n });\r\n }),\r\n );\r\n }\r\n\r\n /** Reset validation state */\r\n reset(): void {\r\n this._validation.set(EMPTY_VALIDATION);\r\n this._isValidating.set(false);\r\n }\r\n\r\n /** Get current validation result */\r\n getCurrentValidation(): ValidationResult {\r\n return this._validation();\r\n }\r\n\r\n /** Check if formula is valid */\r\n isValid(): boolean {\r\n return this._validation().isValid;\r\n }\r\n\r\n /** Get validation errors */\r\n getErrors() {\r\n return this._validation().errors;\r\n }\r\n\r\n /** Get validation warnings */\r\n getWarnings() {\r\n return this._validation().warnings;\r\n }\r\n\r\n /** Get formula dependencies */\r\n getDependencies() {\r\n return this._validation().dependencies;\r\n }\r\n\r\n /** Get formula complexity */\r\n getComplexity() {\r\n return this._validation().complexity;\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, tap, map } from 'rxjs';\r\n\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaBuilderNextTokensResponse,\r\n FormulaPropertyDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaContextService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n private readonly contextCache = new Map<\r\n string,\r\n FormulaBuilderContextResponse\r\n >();\r\n private readonly propertiesCache = new Map<\r\n string,\r\n FormulaPropertyDescriptor[]\r\n >();\r\n private readonly nextTokensCache = new Map<\r\n string,\r\n FormulaBuilderNextTokensResponse\r\n >();\r\n\r\n loadContext(\r\n schemaId: number,\r\n contextEntityTypeKey?: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaBuilderContextResponse | null> {\r\n if (!schemaId) return of(null);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${contextEntityTypeKey ?? ''}`;\r\n const cached = this.contextCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const query =\r\n mode === 'default' && contextEntityTypeKey\r\n ? `?contextEntityTypeKey=${encodeURIComponent(contextEntityTypeKey)}`\r\n : '';\r\n\r\n return this.http\r\n .get<\r\n FormulaBuilderContextResponse | { data: FormulaBuilderContextResponse }\r\n >(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((context) => {\r\n if (context) {\r\n this.contextCache.set(cacheKey, context);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula builder context:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n\r\n getScopeProperties(\r\n schemaId: number,\r\n component: string,\r\n tablePath: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaPropertyDescriptor[]> {\r\n if (!schemaId || !component || !tablePath) return of([]);\r\n if (mode === 'current-only') return of([]);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;\r\n const cached = this.propertiesCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const params = new URLSearchParams({\r\n schemaId: schemaId.toString(),\r\n component,\r\n tablePath,\r\n });\r\n\r\n return this.http\r\n .get<\r\n FormulaPropertyDescriptor[] | { data: FormulaPropertyDescriptor[] }\r\n >(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? []),\r\n tap((response) => {\r\n this.propertiesCache.set(cacheKey, response);\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula properties:', error);\r\n return of([]);\r\n }),\r\n );\r\n }\r\n\r\n getNextTokens(\r\n schemaId: number,\r\n component: string,\r\n tablePath: string,\r\n mode: FormulaApiMode = 'default',\r\n ): Observable<FormulaBuilderNextTokensResponse | null> {\r\n if (!schemaId || !component || !tablePath) return of(null);\r\n if (mode === 'current-only') return of(null);\r\n\r\n const cacheKey = `${mode}:${schemaId}:${component}:${tablePath}`;\r\n const cached = this.nextTokensCache.get(cacheKey);\r\n if (cached) {\r\n return of(cached);\r\n }\r\n\r\n const params = new URLSearchParams({\r\n schemaId: schemaId.toString(),\r\n component,\r\n tablePath,\r\n });\r\n\r\n return this.http\r\n .get<\r\n | FormulaBuilderNextTokensResponse\r\n | { data: FormulaBuilderNextTokensResponse }\r\n >(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((payload) => {\r\n if (payload) {\r\n this.nextTokensCache.set(cacheKey, payload);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula next tokens:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, map } from 'rxjs';\r\nimport type {\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaAutocompleteService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n getSuggestions(\r\n request: AutocompleteRequest,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<AutocompleteResponse | null> {\r\n if (!request) {\r\n return of(null);\r\n }\r\n\r\n const normalized: AutocompleteRequest = {\r\n ...request,\r\n formula: request.formula ?? '',\r\n };\r\n\r\n return this.http\r\n .post<\r\n AutocompleteResponse | { data: AutocompleteResponse }\r\n >(`${this.getBaseUrl(apiMode)}/autocomplete`, normalized)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n catchError((error) => {\r\n console.warn('Autocomplete API error:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import type {\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\nexport type PathSegment = {\r\n operatorToken: string;\r\n value: string;\r\n};\r\n\r\nexport type SegmentMeta = PathSegment & {\r\n parameterKind?: string | null;\r\n requiresParameter: boolean;\r\n allowedValues: string[];\r\n optional: boolean;\r\n canRemove: boolean;\r\n};\r\n\r\nexport type ResolveSegmentsParams = {\r\n scope: string;\r\n segments: PathSegment[];\r\n operators: OperatorDescriptor[];\r\n baseRule?: NextTokenRule;\r\n rulesByPath: Record<string, Record<string, NextTokenRule>>;\r\n};\r\n\r\nexport function resolveSegmentsMeta({\r\n scope,\r\n segments,\r\n operators,\r\n baseRule,\r\n rulesByPath,\r\n}: ResolveSegmentsParams): SegmentMeta[] {\r\n if (!scope || segments.length === 0) {\r\n return [];\r\n }\r\n\r\n let pathBefore = scope;\r\n let blocked = false;\r\n\r\n return segments.map((segment, index) => {\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n const operator = operators.find((op) => op.token === segment.operatorToken);\r\n const rule = blocked\r\n ? undefined\r\n : isBase\r\n ? baseRule\r\n : rulesByPath[pathBefore]?.[segment.operatorToken];\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n const normalizedValue = segment.value;\r\n const isComplete = !requiresParameter || Boolean(normalizedValue);\r\n\r\n if (!blocked && isComplete) {\r\n pathBefore = appendToPath(\r\n pathBefore,\r\n segment.operatorToken,\r\n normalizedValue,\r\n isBase,\r\n );\r\n } else {\r\n blocked = true;\r\n }\r\n\r\n return {\r\n operatorToken: segment.operatorToken,\r\n value: normalizedValue,\r\n parameterKind,\r\n requiresParameter,\r\n allowedValues,\r\n optional: !requiresParameter,\r\n canRemove: !isBase,\r\n };\r\n });\r\n}\r\n\r\nexport function buildInitialSegments(\r\n scope: string,\r\n operator: OperatorDescriptor | undefined,\r\n rule: NextTokenRule | undefined,\r\n): PathSegment[] {\r\n if (!operator || !scope) return [];\r\n const parameterKind = operator.parameterKind ?? rule?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator.requiresParameter ?? Boolean(parameterKind);\r\n const shouldHaveSegment = Boolean(parameterKind) || requiresParameter;\r\n if (!shouldHaveSegment) return [];\r\n\r\n return [{ operatorToken: scope, value: '' }];\r\n}\r\n\r\nexport function buildTablePath(\r\n scope: string,\r\n segments: SegmentMeta[],\r\n baseOperator: OperatorDescriptor | undefined,\r\n stopOnIncomplete: boolean,\r\n): string {\r\n if (!scope) return '';\r\n\r\n if (\r\n stopOnIncomplete &&\r\n segments.length === 0 &&\r\n (baseOperator?.requiresParameter || baseOperator?.parameterKind)\r\n ) {\r\n return '';\r\n }\r\n\r\n let path = scope;\r\n for (let index = 0; index < segments.length; index += 1) {\r\n const segment = segments[index];\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n if (!isBase) {\r\n path += `.${segment.operatorToken}`;\r\n }\r\n if (segment.value) {\r\n path += `.${segment.value}`;\r\n } else if (segment.requiresParameter && stopOnIncomplete) {\r\n return '';\r\n }\r\n }\r\n\r\n return path;\r\n}\r\n\r\nexport function getAllowedValues(rule: NextTokenRule | undefined): string[] {\r\n return rule?.allowedValues ?? [];\r\n}\r\n\r\nfunction appendToPath(\r\n basePath: string,\r\n operatorToken: string,\r\n value: string,\r\n isBase: boolean,\r\n): string {\r\n if (isBase) {\r\n if (!value) return basePath;\r\n if (!basePath) return value;\r\n return `${basePath}.${value}`;\r\n }\r\n if (!basePath) {\r\n return value ? `${operatorToken}.${value}` : operatorToken;\r\n }\r\n const withOperator = `${basePath}.${operatorToken}`;\r\n return value ? `${withOperator}.${value}` : withOperator;\r\n}\r\n","import {\n Component,\n forwardRef,\n input,\n output,\n signal,\n computed,\n inject,\n effect,\n OnDestroy,\n viewChild,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TranslocoDirective } from '@jsverse/transloco';\nimport {\n ControlValueAccessor,\n FormsModule,\n NG_VALUE_ACCESSOR,\n} from '@angular/forms';\nimport { Card } from '@masterteam/components/card';\nimport { Button } from '@masterteam/components/button';\nimport { SelectField } from '@masterteam/components/select-field';\nimport { Tooltip } from '@masterteam/components/tooltip';\nimport { RadioCards, type RadioItem } from '@masterteam/components/radio-cards';\nimport { ToggleField } from '@masterteam/components/toggle-field';\nimport type { MTIcon } from '@masterteam/icons';\nimport { PopoverModule } from 'primeng/popover';\nimport { Skeleton } from 'primeng/skeleton';\nimport { Observable } from 'rxjs';\n\n// Import pure UI components from @masterteam/components/formula\nimport {\n FormulaToolbar,\n FormulaEditor,\n FormulaEditorCode,\n FormulaStatusBar,\n type SmartBlock,\n type FormulaToken,\n type ToolbarTab,\n createPropertyBlock,\n serializeTokens,\n} from '@masterteam/components/formula';\n\n// Services are kept in formula-builder (backend logic)\nimport { FormulaValidatorService } from './services/formula-validator.service';\nimport { FormulaContextService } from './services/formula-context.service';\nimport { FormulaAutocompleteService } from './services/formula-autocomplete.service';\nimport type {\n ValidationResult,\n AutocompleteRequest,\n AutocompleteResponse,\n} from './models/validation-result.model';\nimport type {\n FormulaBuilderContextResponse,\n FormulaPropertyDescriptor,\n NextTokenRule,\n OperatorDescriptor,\n} from './models/formula-context.model';\nimport type { FormulaBuilderValue } from './models/formula-builder-value.model';\nimport {\n buildInitialSegments,\n buildTablePath,\n getAllowedValues,\n resolveSegmentsMeta,\n type PathSegment,\n type SegmentMeta,\n} from './utils/formula-path-builder';\n\nconst DEFAULT_SCOPE_ICON: MTIcon = 'general.placeholder';\nconst DEFAULT_TOOLBAR_TABS: readonly ToolbarTab[] = [\n 'functions',\n 'properties',\n 'operators',\n];\n\nexport interface FormulaBuilderUiConfig {\n toolbarTabs?: readonly ToolbarTab[];\n codeOnly?: boolean;\n hideToolbar?: boolean;\n hideStatusBar?: boolean;\n isProcessBuilder?: boolean;\n contextEntityTypeKey?: string;\n}\n\nconst SCOPE_ICON_MAP: Record<string, MTIcon> = {\n Current: 'map.marker-pin-01',\n Level: 'map.marker-pin-01',\n Parent: 'arrow.arrow-up',\n Children: 'user.users-01',\n Descendants: 'custom.hierarchy-structure',\n Modules: 'file.folder-closed',\n};\n\n@Component({\n selector: 'mt-formula-builder',\n standalone: true,\n imports: [\n CommonModule,\n TranslocoDirective,\n FormsModule,\n Card,\n Button,\n SelectField,\n Tooltip,\n RadioCards,\n ToggleField,\n PopoverModule,\n Skeleton,\n FormulaToolbar,\n FormulaStatusBar,\n FormulaEditor,\n FormulaEditorCode,\n ],\n templateUrl: './formula-builder.html',\n host: {\n class: 'block',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormulaBuilder),\n multi: true,\n },\n ],\n})\nexport class FormulaBuilder implements ControlValueAccessor, OnDestroy {\n private readonly validatorService = inject(FormulaValidatorService);\n private readonly contextService = inject(FormulaContextService);\n private readonly autocompleteService = inject(FormulaAutocompleteService);\n\n /** Reference to the formula editor */\n private readonly editor = viewChild<FormulaEditor>('formulaEditor');\n private readonly codeEditor =\n viewChild<FormulaEditorCode>('formulaEditorCode');\n\n // ===== INPUTS =====\n\n /** Properties per table path (e.g., \"Current\", \"Children.Project\") */\n readonly propertiesByPath = input<\n Record<string, { key: string; name?: string }[]>\n >({});\n\n /** Level schema ID for validation context */\n readonly levelSchemaId = input<number>();\n\n /** Optional current context entity key, e.g. LevelData or Risk */\n readonly contextEntityTypeKey = input<string>();\n\n /** Template ID for validation context */\n readonly templateId = input<number>();\n\n /** Placeholder text */\n readonly placeholder = input('');\n\n /** Hide the top toolbar */\n readonly hideToolbar = input(false);\n\n /** Hide the status bar */\n readonly hideStatusBar = input(false);\n\n /** Visible toolbar tabs */\n readonly toolbarTabs = input<readonly ToolbarTab[]>(DEFAULT_TOOLBAR_TABS);\n\n /** Force code editor mode and hide the mode toggle */\n readonly codeOnly = input(false);\n\n /** Use Process Builder current-only Formula Engine endpoints */\n readonly isProcessBuilder = input(false);\n\n // ===== OUTPUTS =====\n\n /** Emits validation result on change */\n readonly validationChange = output<ValidationResult>();\n\n /** Emits when tokens change */\n readonly tokensChange = output<FormulaToken[]>();\n\n // ===== STATE =====\n\n /** Editor focus state */\n readonly hasFocus = signal(false);\n\n /** Form control value */\n private readonly expressionValue = signal('');\n private readonly builderValue = signal<FormulaToken[]>([]);\n\n /** Tokens for the editor */\n readonly tokens = signal<FormulaToken[]>([]);\n readonly expression = computed(() => this.expressionValue());\n readonly resolvedContextEntityTypeKey = computed(() => {\n const value = this.contextEntityTypeKey();\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalized = value.trim();\n return normalized.length > 0 ? normalized : undefined;\n });\n\n readonly autocompleteProvider = (\n request: AutocompleteRequest,\n ): Observable<AutocompleteResponse | null> => {\n return this.autocompleteService.getSuggestions(\n {\n ...request,\n levelSchemaId: this.levelSchemaId(),\n contextEntityTypeKey:\n this.resolvedContextEntityTypeKey() ??\n this.builderContext()?.contextEntityTypeKey,\n },\n this.isProcessBuilder() ? 'current-only' : 'default',\n );\n };\n\n /** Track last synced builder JSON to avoid loops */\n private lastBuilderJson = '';\n\n /** Editor mode */\n readonly editorMode = signal<'builder' | 'code'>('builder');\n readonly isCodeMode = computed(() => this.editorMode() === 'code');\n readonly isCodeModeLocked = signal(false);\n readonly showModeToggle = computed(() => !this.codeOnly());\n readonly formulaApiMode = computed<'default' | 'current-only'>(() =>\n this.isProcessBuilder() ? 'current-only' : 'default',\n );\n readonly resolvedToolbarTabs = computed(() => {\n const tabs = this.toolbarTabs();\n return tabs.length > 0 ? tabs : DEFAULT_TOOLBAR_TABS;\n });\n private codeModeSnapshotTokens: FormulaToken[] = [];\n private codeModeSnapshotExpression = '';\n\n /** ControlValueAccessor callbacks */\n private onChange: (value: FormulaBuilderValue) => void = () => {};\n private onTouched: () => void = () => {};\n\n /** Disabled state */\n private readonly isDisabled = signal(false);\n\n /** Validation result from service */\n readonly validation = this.validatorService.validation;\n\n /** Is validation in progress */\n readonly isValidating = this.validatorService.isValidating;\n\n /** Builder context from API */\n readonly builderContext = signal<FormulaBuilderContextResponse | null>(null);\n\n /** Function categories from context */\n readonly functionCategories = computed(\n () => this.builderContext()?.functions?.categories ?? [],\n );\n\n /** Is builder context loading */\n readonly isContextLoading = signal(false);\n\n private contextRequestId = 0;\n\n /** Properties loaded from API */\n private readonly propertiesByPathApi = signal<\n Record<string, FormulaPropertyDescriptor[]>\n >({});\n\n /** Current property list loading path */\n private readonly propertyLoadingPath = signal<string | null>(null);\n\n constructor() {\n // Validate when formula changes\n effect(() => {\n const formula = this.expressionValue();\n const apiMode = this.formulaApiMode();\n if (formula && formula.trim().length > 0) {\n this.validatorService.validate(\n formula,\n undefined,\n this.levelSchemaId(),\n this.templateId(),\n apiMode,\n );\n }\n });\n\n // Emit validation changes\n effect(() => {\n const validation = this.validation();\n this.validationChange.emit(validation);\n });\n\n // Load builder context when schema changes\n effect(() => {\n const schemaId = this.levelSchemaId();\n const apiMode = this.formulaApiMode();\n const contextEntityTypeKey = this.resolvedContextEntityTypeKey();\n\n if (!schemaId) {\n this.builderContext.set(null);\n this.propertiesByPathApi.set({});\n this.nextTokenRulesByPath.set({});\n this.isContextLoading.set(false);\n return;\n }\n\n const requestId = ++this.contextRequestId;\n this.isContextLoading.set(true);\n this.propertiesByPathApi.set({});\n this.nextTokenRulesByPath.set({});\n this.contextService\n .loadContext(schemaId, contextEntityTypeKey, apiMode)\n .subscribe((context) => {\n if (requestId !== this.contextRequestId) {\n return;\n }\n\n this.builderContext.set(context);\n this.isContextLoading.set(false);\n\n if (!context) {\n return;\n }\n\n if (context.currentProperties?.length) {\n const scalarOperators =\n context.schemaDescriptor?.operators?.filter(\n (operator) =>\n operator.cardinality === 'scalar' &&\n !operator.requiresParameter &&\n !operator.parameterKind,\n ) ?? [];\n const scopedProperties = scalarOperators.reduce(\n (acc, operator) => ({\n ...acc,\n [operator.token]: context.currentProperties,\n }),\n {} as Record<string, FormulaPropertyDescriptor[]>,\n );\n this.propertiesByPathApi.update((current) => ({\n ...current,\n ...scopedProperties,\n }));\n }\n });\n });\n\n // Ensure selected scope exists in available options\n effect(() => {\n const scopes = this.availableScopes();\n if (scopes.length === 0) return;\n const current = this.propertyScope();\n if (!scopes.some((scope) => scope.key === current)) {\n this.setPropertyScope(scopes[0].key);\n }\n });\n\n // Fetch properties for the selected table path\n effect(() => {\n const schemaId = this.levelSchemaId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n const context = this.builderContext();\n\n if (\n isProcessBuilder ||\n !schemaId ||\n !tablePath ||\n !component ||\n !context\n ) {\n this.propertyLoadingPath.set(null);\n return;\n }\n\n const existing = this.propertiesByPathApi()[tablePath];\n if (existing !== undefined) {\n this.propertyLoadingPath.set(null);\n return;\n }\n\n this.propertyLoadingPath.set(tablePath);\n this.contextService\n .getScopeProperties(schemaId, component, tablePath)\n .subscribe((props) => {\n this.propertiesByPathApi.update((current) => ({\n ...current,\n [tablePath]: props ?? [],\n }));\n if (this.propertyLoadingPath() === tablePath) {\n this.propertyLoadingPath.set(null);\n }\n });\n });\n\n // Fetch next-token rules for the current table path\n effect(() => {\n const schemaId = this.levelSchemaId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n\n if (isProcessBuilder || !schemaId || !tablePath || !component) return;\n\n if (this.nextTokenRulesByPath()[tablePath]) return;\n\n this.contextService\n .getNextTokens(schemaId, component, tablePath)\n .subscribe((response) => {\n if (!response) return;\n this.nextTokenRulesByPath.update((current) => ({\n ...current,\n [tablePath]: response.nextTokenRules ?? {},\n }));\n });\n });\n\n // Keep base segment in sync with scope metadata\n effect(() => {\n const scope = this.propertyScope();\n const operator = this.baseOperator();\n const shouldHaveSegment =\n Boolean(operator?.parameterKind) ||\n Boolean(operator?.requiresParameter);\n const segments = this.propertyPathSegments();\n const hasBase = segments[0]?.operatorToken === scope;\n\n if (shouldHaveSegment && !hasBase) {\n this.propertyPathSegments.set(\n buildInitialSegments(scope, operator, this.baseRule()),\n );\n return;\n }\n\n if (!shouldHaveSegment && hasBase) {\n this.propertyPathSegments.set(segments.slice(1));\n }\n });\n\n // Normalize segment values when allowed values change\n effect(() => {\n const meta = this.pathSegments();\n const segments = this.propertyPathSegments();\n if (meta.length !== segments.length) return;\n\n let changed = false;\n const next = segments.map((segment, index) => {\n const normalized = meta[index]?.value ?? segment.value;\n if (segment.value !== normalized) {\n changed = true;\n return { ...segment, value: normalized };\n }\n return segment;\n });\n\n if (changed) {\n this.propertyPathSegments.set(next);\n }\n });\n\n // Ensure selected field exists in current options\n effect(() => {\n const options = this.propertyOptions();\n const current = this.propertyFieldKey();\n\n if (options.length === 0) {\n if (current) this.propertyFieldKey.set('');\n return;\n }\n\n if (current && !options.some((prop) => prop.key === current)) {\n this.propertyFieldKey.set('');\n }\n });\n }\n\n ngOnDestroy(): void {\n this.validatorService.reset();\n }\n\n // ===== ControlValueAccessor =====\n\n writeValue(value: FormulaBuilderValue | null): void {\n if (!value) {\n this.expressionValue.set('');\n this.applyFormulaValue([], '', this.codeOnly());\n this.validatorService.reset();\n return;\n }\n\n const builder = Array.isArray(value.builder) ? value.builder : [];\n const expression = this.codeOnly()\n ? this.resolveExpressionValue(value.expression ?? '', builder)\n : (value.expression ?? '');\n this.expressionValue.set(expression);\n\n if (this.codeOnly()) {\n this.applyFormulaValue(builder, expression, true);\n return;\n }\n\n if (builder.length === 0) {\n this.applyFormulaValue(\n [],\n expression,\n expression.trim().length > 0,\n true,\n );\n return;\n }\n\n this.applyFormulaValue(builder, expression, false);\n }\n\n registerOnChange(fn: (value: FormulaBuilderValue) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.isDisabled.set(isDisabled);\n }\n\n /** Handle formula change from editor */\n onFormulaChange(newFormula: string): void {\n this.expressionValue.set(newFormula);\n this.emitValueChange();\n }\n\n /** Handle formula change from code editor */\n onCodeFormulaChange(newFormula: string): void {\n this.expressionValue.set(newFormula);\n if (!newFormula.trim()) {\n this.clearBuilderTokens();\n this.isCodeModeLocked.set(false);\n this.codeModeSnapshotTokens = [];\n this.codeModeSnapshotExpression = '';\n this.emitValueChange();\n return;\n }\n\n if (\n !this.isCodeModeLocked() &&\n newFormula !== this.codeModeSnapshotExpression\n ) {\n this.isCodeModeLocked.set(true);\n this.clearBuilderTokens();\n }\n this.emitValueChange();\n }\n\n /** Handle block insert from toolbar */\n onBlockInsert(block: SmartBlock): void {\n if (this.isCodeMode()) {\n const editor = this.codeEditor();\n if (editor) {\n editor.addBlock(block);\n }\n return;\n }\n const editor = this.editor();\n if (editor) {\n editor.addBlock(block);\n }\n }\n\n /** Handle tokens change */\n onTokensChange(newTokens: FormulaToken[]): void {\n this.tokens.set(newTokens);\n const json = JSON.stringify(newTokens);\n this.lastBuilderJson = json;\n this.builderValue.set(newTokens);\n this.tokensChange.emit(newTokens);\n this.emitValueChange();\n }\n\n onEditorFocus(): void {\n this.hasFocus.set(true);\n }\n\n onEditorBlur(): void {\n this.hasFocus.set(false);\n this.onTouched();\n }\n\n private emitValueChange(): void {\n this.onChange({\n expression: this.expressionValue(),\n builder: this.builderValue(),\n });\n }\n\n onModeToggle(value: boolean): void {\n if (this.codeOnly()) {\n return;\n }\n const nextMode: 'builder' | 'code' = value ? 'code' : 'builder';\n this.setEditorMode(nextMode);\n }\n\n private setEditorMode(mode: 'builder' | 'code'): void {\n if (this.editorMode() === mode) return;\n\n if (mode === 'code') {\n this.enterCodeMode();\n return;\n }\n\n if (this.isCodeModeLocked()) {\n return;\n }\n\n this.exitCodeMode();\n }\n\n private enterCodeMode(): void {\n this.codeModeSnapshotTokens = this.tokens().slice();\n this.codeModeSnapshotExpression = this.expressionValue();\n const editor = this.editor();\n if (editor) {\n const formula = editor.serialize();\n this.codeModeSnapshotExpression = formula;\n this.expressionValue.set(formula);\n this.emitValueChange();\n }\n this.isCodeModeLocked.set(false);\n this.editorMode.set('code');\n }\n\n private exitCodeMode(): void {\n this.editorMode.set('builder');\n if (!this.expressionValue().trim()) {\n this.clearBuilderTokens();\n const editor = this.editor();\n if (editor) {\n editor.writeValue([]);\n }\n this.codeModeSnapshotTokens = [];\n this.codeModeSnapshotExpression = '';\n this.isCodeModeLocked.set(false);\n return;\n }\n\n if (this.codeModeSnapshotTokens.length > 0) {\n const restored = this.codeModeSnapshotTokens.slice();\n this.tokens.set(restored);\n this.builderValue.set(restored);\n this.lastBuilderJson = JSON.stringify(restored);\n const editor = this.editor();\n if (editor) {\n editor.writeValue(restored);\n }\n }\n if (this.codeModeSnapshotExpression) {\n this.expressionValue.set(this.codeModeSnapshotExpression);\n }\n this.isCodeModeLocked.set(false);\n }\n\n private clearBuilderTokens(): void {\n if (this.tokens().length === 0 && this.builderValue().length === 0) {\n return;\n }\n this.tokens.set([]);\n this.builderValue.set([]);\n this.lastBuilderJson = '';\n this.tokensChange.emit([]);\n }\n\n // ===== PUBLIC METHODS =====\n\n /** Clear the formula */\n clear(): void {\n this.expressionValue.set('');\n this.applyFormulaValue([], '', this.codeOnly());\n this.validatorService.reset();\n this.emitValueChange();\n }\n\n private resolveExpressionValue(\n expression: string,\n builder: FormulaToken[],\n ): string {\n if (expression.trim().length > 0) {\n return expression;\n }\n return builder.length > 0 ? serializeTokens(builder) : '';\n }\n\n private applyFormulaValue(\n builder: FormulaToken[],\n expression: string,\n useCodeMode: boolean,\n lockCodeMode: boolean = false,\n ): void {\n const serialized = JSON.stringify(builder);\n this.builderValue.set(builder);\n this.tokens.set(builder);\n this.lastBuilderJson = builder.length > 0 ? serialized : '';\n\n const editor = this.editor();\n if (editor) {\n editor.writeValue(builder);\n }\n\n const codeEditor = this.codeEditor();\n if (codeEditor) {\n codeEditor.writeValue(expression);\n }\n\n if (useCodeMode) {\n this.editorMode.set('code');\n this.isCodeModeLocked.set(lockCodeMode);\n this.codeModeSnapshotTokens = builder.slice();\n this.codeModeSnapshotExpression = expression;\n return;\n }\n\n this.editorMode.set('builder');\n this.isCodeModeLocked.set(false);\n this.codeModeSnapshotTokens = [];\n this.codeModeSnapshotExpression = '';\n }\n\n // ===== PROPERTY COMPOSER =====\n\n readonly propertyScope = signal<string>('');\n\n readonly propertyPathSegments = signal<PathSegment[]>([]);\n\n readonly propertyFieldKey = signal('');\n\n private readonly nextTokenRulesByPath = signal<\n Record<string, Record<string, NextTokenRule>>\n >({});\n\n readonly contextOperators = computed<OperatorDescriptor[]>(() => {\n return this.builderContext()?.schemaDescriptor?.operators ?? [];\n });\n\n readonly baseOperator = computed(() =>\n this.contextOperators().find((op) => op.token === this.propertyScope()),\n );\n\n readonly baseRule = computed(() => {\n const scope = this.propertyScope();\n return this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope];\n });\n\n readonly availableScopes = computed(() => {\n const operators = this.contextOperators();\n if (operators.length === 0) return [];\n return operators.map((operator) => ({\n key: operator.token,\n label: `@${operator.token}`,\n requiresParam: operator.requiresParameter ?? false,\n optional: !operator.requiresParameter,\n }));\n });\n\n /** Radio card options for scope selection */\n readonly scopeOptions = computed<RadioItem[]>(() =>\n this.availableScopes().map((scope) => ({\n id: scope.key,\n name: scope.key,\n icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,\n })),\n );\n\n /** Handle scope selection from radio cards */\n onScopeChange(item: RadioItem): void {\n this.setPropertyScope(String(item.id));\n }\n\n readonly pathSegments = computed<SegmentMeta[]>(() => {\n const scope = this.propertyScope();\n return resolveSegmentsMeta({\n scope,\n segments: this.propertyPathSegments(),\n operators: this.contextOperators(),\n baseRule: this.baseRule(),\n rulesByPath: this.nextTokenRulesByPath(),\n });\n });\n\n readonly isDirectAccess = computed(() => {\n const operator = this.baseOperator();\n const needsParameter =\n Boolean(operator?.parameterKind) || Boolean(operator?.requiresParameter);\n return !needsParameter && this.pathSegments().length === 0;\n });\n\n readonly propertyTablePath = computed(() =>\n buildTablePath(\n this.propertyScope(),\n this.pathSegments(),\n this.baseOperator(),\n false,\n ),\n );\n\n readonly resolvedTablePath = computed(() =>\n buildTablePath(\n this.propertyScope(),\n this.pathSegments(),\n this.baseOperator(),\n true,\n ),\n );\n\n readonly currentNextTokenRules = computed(() => {\n const path = this.resolvedTablePath();\n if (!path) return {};\n return this.nextTokenRulesByPath()[path] ?? {};\n });\n\n readonly nextOperatorOptions = computed(() => {\n const rules = this.currentNextTokenRules();\n const operators = this.contextOperators();\n return Object.keys(rules)\n .map((token) => {\n const rule = rules[token];\n const operator = operators.find((item) => item.token === token);\n const parameterKind =\n rule?.parameterKind ?? operator?.parameterKind ?? null;\n const requiresParameter =\n operator?.requiresParameter ?? Boolean(parameterKind);\n const allowedValues = getAllowedValues(rule);\n return {\n token,\n rule,\n requiresParameter,\n allowedValues,\n };\n })\n .filter(\n (option) =>\n option.allowedValues.length > 0 || !option.requiresParameter,\n );\n });\n\n readonly canAddNextSegment = computed(() => {\n if (this.nextOperatorOptions().length === 0) return false;\n const segments = this.pathSegments();\n if (segments.length === 0 || !segments[0].value) {\n return false;\n }\n return segments.every(\n (segment) => !segment.requiresParameter || Boolean(segment.value),\n );\n });\n\n readonly propertiesComponent = computed(() => {\n if (this.isProcessBuilder()) {\n return undefined;\n }\n const contextKey = this.builderContext()?.contextEntityTypeKey;\n return contextKey;\n });\n\n readonly mergedPropertiesByPath = computed<\n Record<string, FormulaPropertyDescriptor[]>\n >(() => {\n const merged: Record<string, FormulaPropertyDescriptor[]> = {\n ...this.propertiesByPath(),\n };\n const apiProps = this.propertiesByPathApi();\n Object.entries(apiProps).forEach(([path, props]) => {\n if (props && props.length > 0) {\n merged[path] = props;\n }\n });\n return merged;\n });\n\n readonly isPropertyLoading = computed(() => {\n const path = this.resolvedTablePath();\n return Boolean(path) && this.propertyLoadingPath() === path;\n });\n\n readonly propertyOptions = computed(() => {\n const path = this.resolvedTablePath();\n if (!path) return [];\n const byPath = this.mergedPropertiesByPath()[path];\n const list = byPath && byPath.length > 0 ? byPath : [];\n return list.map((prop) => ({\n key: prop.key,\n name: prop.name ?? prop.key,\n }));\n });\n\n readonly selectedProperty = computed(() => {\n const key = this.propertyFieldKey();\n return this.propertyOptions().find((prop) => prop.key === key) ?? null;\n });\n\n readonly canInsertProperty = computed(() => {\n if (!this.selectedProperty()) return false;\n return Boolean(this.resolvedTablePath());\n });\n\n setPropertyScope(scope: string): void {\n if (this.propertyScope() === scope) {\n return;\n }\n this.propertyScope.set(scope);\n this.propertyPathSegments.set(\n buildInitialSegments(\n scope,\n this.contextOperators().find((op) => op.token === scope),\n this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope],\n ),\n );\n this.propertyFieldKey.set('');\n }\n\n setPathSegmentValue(index: number, value: string | null): void {\n this.propertyPathSegments.update((segments) => {\n // Update the segment at the given index and remove all segments after it\n // because subsequent segments depend on previous values\n const updated = segments.slice(0, index + 1);\n updated[index] = { ...updated[index], value: value ?? '' };\n return updated;\n });\n }\n\n addNextSegment(operatorToken: string): void {\n const value = '';\n\n this.propertyPathSegments.update((segments) => [\n ...segments,\n { operatorToken, value },\n ]);\n }\n\n onAddSegmentSelection(\n operatorToken: string,\n popover: { hide: () => void },\n ): void {\n popover.hide();\n this.addNextSegment(operatorToken);\n }\n\n removePathSegment(index: number): void {\n this.propertyPathSegments.update((segments) =>\n segments.filter((_, i) => i !== index),\n );\n }\n\n segmentOptions(index: number): { key: string; name: string }[] {\n const segment = this.pathSegments()[index];\n if (!segment) return [];\n return segment.allowedValues.map((value) => ({\n key: value,\n name: value,\n }));\n }\n\n insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void {\n const prop = this.selectedProperty();\n if (!prop) return;\n\n if (!this.canInsertProperty()) return;\n\n const tablePath = this.resolvedTablePath();\n if (!tablePath) return;\n const display = prop.name ?? prop.key;\n const block = createPropertyBlock(\n `@${tablePath}::${prop.key}`,\n 'current',\n display,\n );\n insertBlock(block);\n }\n}\n","<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n ✓ {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >›</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\r\n segment.value ||\r\n t('properties.select') +\r\n ' ' +\r\n segment.operatorToken\r\n \"\r\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\r\n {{ segment.operatorToken }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.token\"\r\n icon=\"general.plus\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n","/**\r\n * Services barrel export\r\n */\r\n\r\nexport * from './formula-context.service';\r\nexport * from './formula-validator.service';\r\n","/**\r\n * Public API Surface of @masterteam/formula-builder\r\n *\r\n * This package provides the FormulaBuilder component which wraps\r\n * pure UI components from @masterteam/components/formula with\r\n * backend services for validation and context loading.\r\n *\r\n * Architecture:\r\n * - UI Components: imported from @masterteam/components/formula (pure, no services)\r\n * - Services: FormulaContextService, FormulaValidatorService (backend logic)\r\n * - FormulaBuilder: Main wrapper that connects UI with services\r\n */\r\n\r\n// Main component\r\nexport * from './lib/formula-builder';\r\n\r\n// Services (backend logic only)\r\nexport * from './lib/services/index';\r\n\r\n// Re-export models from base package for convenience\r\nexport {\r\n type SmartBlock,\r\n type BlockType,\r\n type ArgumentSlot,\r\n type FormulaToken,\r\n type TokenType,\r\n type DragBehavior,\r\n type ValidationResult,\r\n type ValidationError,\r\n type FunctionDefinition,\r\n type FunctionCategoryGroup,\r\n type OperatorDefinition,\r\n createFunctionBlock,\r\n createPropertyBlock,\r\n createOperatorBlock,\r\n createLiteralBlock,\r\n} from '@masterteam/components/formula';\r\n\r\n// Export validation-specific models\r\nexport type {\r\n ValidationRequest,\r\n FunctionCatalogResponse,\r\n ApiErrorResponse,\r\n} from './lib/models/validation-result.model';\r\n\r\n// Export value model for ControlValueAccessor usage\r\nexport type { FormulaBuilderValue } from './lib/models/formula-builder-value.model';\r\n\r\n// Export builder context models\r\nexport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n FormulaEngineSchemaDescriptor,\r\n OperatorDescriptor,\r\n NextTokenRule,\r\n} from './lib/models/formula-context.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;;;AAGG;AAwBH;AACA,MAAM,gBAAgB,GAAqB;AACzC,IAAA,OAAO,EAAE,IAAI;AACb,IAAA,MAAM,EAAE,EAAE;AACV,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,YAAY,EAAE,EAAE;AAChB,IAAA,UAAU,EAAE,CAAC;CACd;AAED;AACA,MAAM,gBAAgB,GAAqB;AACzC,IAAA,OAAO,EAAE,KAAK;AACd,IAAA,MAAM,EAAE;AACN,QAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE;AACxE,KAAA;AACD,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,YAAY,EAAE,EAAE;AAChB,IAAA,UAAU,EAAE,CAAC;CACd;MAGY,uBAAuB,CAAA;AACjB,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IACzB,MAAM,GAAG,WAAW;AAE7B,IAAA,UAAU,CAAC,IAAoB,EAAA;QACrC,OAAO,IAAI,KAAK;AACd,cAAE,CAAA,EAAG,IAAI,CAAC,MAAM,CAAA,aAAA;AAChB,cAAE,IAAI,CAAC,MAAM;IACjB;;IAGiB,WAAW,GAAG,GAAG;;AAGjB,IAAA,WAAW,GAAG,MAAM,CAAmB,gBAAgB,uDAAC;;AAGxD,IAAA,aAAa,GAAG,MAAM,CAAC,KAAK,yDAAC;;AAG7B,IAAA,eAAe,GAAG,IAAI,OAAO,EAAiB;AAEvD,IAAA,cAAc,CAAI,QAAgC,EAAA;AACxD,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,IAAI;QAC1B,IACE,OAAO,QAAQ,KAAK,QAAQ;AAC5B,YAAA,QAAQ,KAAK,IAAI;YACjB,MAAM,IAAI,QAAQ,EAClB;AACA,YAAA,OAAQ,QAAwB,CAAC,IAAI,IAAI,IAAI;QAC/C;AACA,QAAA,OAAO,QAAa;IACtB;;AAGS,IAAA,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;AAC1C,IAAA,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;AAEvD,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,qBAAqB,EAAE;IAC9B;;IAGQ,qBAAqB,GAAA;AAC3B,QAAA,IAAI,CAAC;aACF,IAAI,CACH,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,EAC9B,oBAAoB,CAClB,CAAC,CAAC,EAAE,CAAC,KACH,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO;AACvB,YAAA,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,aAAa;AACnC,YAAA,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU;AAC7B,YAAA,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO;AACvB,YAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC;AAC/B,gBAAA,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CACtC,EACD,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EACvC,SAAS,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAEtD,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AACpB,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;AAC5B,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,QAAA,CAAC,CAAC;IACN;;IAGA,QAAQ,CACN,OAAe,EACf,eAA0B,EAC1B,aAAsB,EACtB,UAAmB,EACnB,OAAA,GAA0B,SAAS,EAAA;;QAGnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACrC,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC;YACtC;QACF;;AAGA,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;YACxB,OAAO;YACP,eAAe;YACf,aAAa;YACb,UAAU;YACV,OAAO;AACR,SAAA,CAAC;IACJ;;IAGA,iBAAiB,CACf,OAAe,EACf,eAA0B,EAC1B,aAAsB,EACtB,UAAmB,EACnB,OAAA,GAA0B,SAAS,EAAA;QAEnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACrC,YAAA,OAAO,EAAE,CAAC,gBAAgB,CAAC;QAC7B;AAEA,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAE5B,OAAO,IAAI,CAAC,eAAe,CAAC;YAC1B,OAAO;YACP,eAAe;YACf,aAAa;YACb,UAAU;YACV,OAAO;SACR,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,CAAC,MAAM,KAAI;AACb,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;AAC5B,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,CACH;IACH;;AAGQ,IAAA,eAAe,CACrB,OAAsB,EAAA;QAEtB,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO;QACvC,OAAO,IAAI,CAAC;aACT,IAAI,CAEH,CAAA,EAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA,SAAA,CAAW,EAAE,OAAO;aAChD,IAAI,CACH,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,EACpE,UAAU,CAAC,CAAC,KAAwB,KAAI;AACtC,YAAA,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC;;AAG7C,YAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAyB;YAChD,MAAM,OAAO,GACX,QAAQ,EAAE,OAAO,IAAI,QAAQ,EAAE,KAAK,IAAI,mBAAmB;AAE7D,YAAA,OAAO,EAAE,CAAC;AACR,gBAAA,GAAG,gBAAgB;AACnB,gBAAA,MAAM,EAAE;AACN,oBAAA,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAgB,EAAE;AAC5D,iBAAA;AACF,aAAA,CAAC;QACJ,CAAC,CAAC,CACH;IACL;;IAGA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC;AACtC,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;IAC/B;;IAGA,oBAAoB,GAAA;AAClB,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE;IAC3B;;IAGA,OAAO,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO;IACnC;;IAGA,SAAS,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM;IAClC;;IAGA,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ;IACpC;;IAGA,eAAe,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,YAAY;IACxC;;IAGA,aAAa,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU;IACtC;uGApLW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cADV,MAAM,EAAA,CAAA;;2FACnB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MClCrB,qBAAqB,CAAA;AACf,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IACzB,MAAM,GAAG,WAAW;AAE7B,IAAA,UAAU,CAAC,IAAoB,EAAA;QACrC,OAAO,IAAI,KAAK;AACd,cAAE,CAAA,EAAG,IAAI,CAAC,MAAM,CAAA,aAAA;AAChB,cAAE,IAAI,CAAC,MAAM;IACjB;AAEQ,IAAA,cAAc,CAAI,QAAgC,EAAA;AACxD,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,IAAI;QAC1B,IACE,OAAO,QAAQ,KAAK,QAAQ;AAC5B,YAAA,QAAQ,KAAK,IAAI;YACjB,MAAM,IAAI,QAAQ,EAClB;AACA,YAAA,OAAQ,QAAwB,CAAC,IAAI,IAAI,IAAI;QAC/C;AACA,QAAA,OAAO,QAAa;IACtB;AAEiB,IAAA,YAAY,GAAG,IAAI,GAAG,EAGpC;AACc,IAAA,eAAe,GAAG,IAAI,GAAG,EAGvC;AACc,IAAA,eAAe,GAAG,IAAI,GAAG,EAGvC;AAEH,IAAA,WAAW,CACT,QAAgB,EAChB,oBAA6B,EAC7B,OAAuB,SAAS,EAAA;AAEhC,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QAE9B,MAAM,QAAQ,GAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,EAAI,oBAAoB,IAAI,EAAE,CAAA,CAAE;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC9C,IAAI,MAAM,EAAE;AACV,YAAA,OAAO,EAAE,CAAC,MAAM,CAAC;QACnB;AAEA,QAAA,MAAM,KAAK,GACT,IAAI,KAAK,SAAS,IAAI;AACpB,cAAE,CAAA,sBAAA,EAAyB,kBAAkB,CAAC,oBAAoB,CAAC,CAAA;cACjE,EAAE;QAER,OAAO,IAAI,CAAC;AACT,aAAA,GAAG,CAEF,CAAA,EAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA,iBAAA,EAAoB,QAAQ,CAAA,EAAG,KAAK,EAAE;aAC/D,IAAI,CACH,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAChD,GAAG,CAAC,CAAC,OAAO,KAAI;YACd,IAAI,OAAO,EAAE;gBACX,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;YAC1C;AACF,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAE,KAAK,CAAC;AAC9D,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QACjB,CAAC,CAAC,CACH;IACL;IAEA,kBAAkB,CAChB,QAAgB,EAChB,SAAiB,EACjB,SAAiB,EACjB,OAAuB,SAAS,EAAA;AAEhC,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACxD,IAAI,IAAI,KAAK,cAAc;AAAE,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QAE1C,MAAM,QAAQ,GAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QACjD,IAAI,MAAM,EAAE;AACV,YAAA,OAAO,EAAE,CAAC,MAAM,CAAC;QACnB;AAEA,QAAA,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;AACjC,YAAA,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;YAC7B,SAAS;YACT,SAAS;AACV,SAAA,CAAC;QAEF,OAAO,IAAI,CAAC;AACT,aAAA,GAAG,CAEF,CAAA,EAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE;aACnE,IAAI,CACH,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EACtD,GAAG,CAAC,CAAC,QAAQ,KAAI;YACf,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAC9C,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,KAAK,CAAC;AACzD,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACf,CAAC,CAAC,CACH;IACL;IAEA,aAAa,CACX,QAAgB,EAChB,SAAiB,EACjB,SAAiB,EACjB,OAAuB,SAAS,EAAA;AAEhC,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QAC1D,IAAI,IAAI,KAAK,cAAc;AAAE,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QAE5C,MAAM,QAAQ,GAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QACjD,IAAI,MAAM,EAAE;AACV,YAAA,OAAO,EAAE,CAAC,MAAM,CAAC;QACnB;AAEA,QAAA,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;AACjC,YAAA,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;YAC7B,SAAS;YACT,SAAS;AACV,SAAA,CAAC;QAEF,OAAO,IAAI,CAAC;AACT,aAAA,GAAG,CAGF,CAAA,EAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA,qBAAA,EAAwB,MAAM,CAAC,QAAQ,EAAE,EAAE;aACpE,IAAI,CACH,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAChD,GAAG,CAAC,CAAC,OAAO,KAAI;YACd,IAAI,OAAO,EAAE;gBACX,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;YAC7C;AACF,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC;AAC1D,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QACjB,CAAC,CAAC,CACH;IACL;uGAlJW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAArB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qBAAqB,cADR,MAAM,EAAA,CAAA;;2FACnB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBADjC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;MCDrB,0BAA0B,CAAA;AACpB,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;IACzB,MAAM,GAAG,WAAW;AAE7B,IAAA,UAAU,CAAC,IAAoB,EAAA;QACrC,OAAO,IAAI,KAAK;AACd,cAAE,CAAA,EAAG,IAAI,CAAC,MAAM,CAAA,aAAA;AAChB,cAAE,IAAI,CAAC,MAAM;IACjB;AAEQ,IAAA,cAAc,CAAI,QAAgC,EAAA;AACxD,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,IAAI;QAC1B,IACE,OAAO,QAAQ,KAAK,QAAQ;AAC5B,YAAA,QAAQ,KAAK,IAAI;YACjB,MAAM,IAAI,QAAQ,EAClB;AACA,YAAA,OAAQ,QAAwB,CAAC,IAAI,IAAI,IAAI;QAC/C;AACA,QAAA,OAAO,QAAa;IACtB;AAEA,IAAA,cAAc,CACZ,OAA4B,EAC5B,OAAA,GAA0B,SAAS,EAAA;QAEnC,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QACjB;AAEA,QAAA,MAAM,UAAU,GAAwB;AACtC,YAAA,GAAG,OAAO;AACV,YAAA,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC/B;QAED,OAAO,IAAI,CAAC;aACT,IAAI,CAEH,CAAA,EAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA,aAAA,CAAe,EAAE,UAAU;aACvD,IAAI,CACH,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAChD,UAAU,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC;AAC9C,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC;QACjB,CAAC,CAAC,CACH;IACL;uGA9CW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAA1B,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,0BAA0B,cADb,MAAM,EAAA,CAAA;;2FACnB,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBADtC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACgB5B,SAAU,mBAAmB,CAAC,EAClC,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,GACW,EAAA;IACtB,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;AACnC,QAAA,OAAO,EAAE;IACX;IAEA,IAAI,UAAU,GAAG,KAAK;IACtB,IAAI,OAAO,GAAG,KAAK;IAEnB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,KAAI;QACrC,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK;AAC7D,QAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,aAAa,CAAC;QAC3E,MAAM,IAAI,GAAG;AACX,cAAE;AACF,cAAE;AACA,kBAAE;kBACA,WAAW,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;QACtD,MAAM,aAAa,GACjB,IAAI,EAAE,aAAa,IAAI,QAAQ,EAAE,aAAa,IAAI,IAAI;QACxD,MAAM,iBAAiB,GACrB,QAAQ,EAAE,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC;AACvD,QAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC;AAC5C,QAAA,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK;QACrC,MAAM,UAAU,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,eAAe,CAAC;AAEjE,QAAA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;AAC1B,YAAA,UAAU,GAAG,YAAY,CACvB,UAAU,EACV,OAAO,CAAC,aAAa,EACrB,eAAe,EACf,MAAM,CACP;QACH;aAAO;YACL,OAAO,GAAG,IAAI;QAChB;QAEA,OAAO;YACL,aAAa,EAAE,OAAO,CAAC,aAAa;AACpC,YAAA,KAAK,EAAE,eAAe;YACtB,aAAa;YACb,iBAAiB;YACjB,aAAa;YACb,QAAQ,EAAE,CAAC,iBAAiB;YAC5B,SAAS,EAAE,CAAC,MAAM;SACnB;AACH,IAAA,CAAC,CAAC;AACJ;SAEgB,oBAAoB,CAClC,KAAa,EACb,QAAwC,EACxC,IAA+B,EAAA;AAE/B,IAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;IAClC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,IAAI,IAAI,EAAE,aAAa,IAAI,IAAI;IAC3E,MAAM,iBAAiB,GACrB,QAAQ,CAAC,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC;IACtD,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,iBAAiB;AACrE,IAAA,IAAI,CAAC,iBAAiB;AAAE,QAAA,OAAO,EAAE;IAEjC,OAAO,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC9C;AAEM,SAAU,cAAc,CAC5B,KAAa,EACb,QAAuB,EACvB,YAA4C,EAC5C,gBAAyB,EAAA;AAEzB,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;AAErB,IAAA,IACE,gBAAgB;QAChB,QAAQ,CAAC,MAAM,KAAK,CAAC;SACpB,YAAY,EAAE,iBAAiB,IAAI,YAAY,EAAE,aAAa,CAAC,EAChE;AACA,QAAA,OAAO,EAAE;IACX;IAEA,IAAI,IAAI,GAAG,KAAK;AAChB,IAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE;AACvD,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK;QAC7D,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,IAAI,IAAI,CAAA,CAAA,EAAI,OAAO,CAAC,aAAa,EAAE;QACrC;AACA,QAAA,IAAI,OAAO,CAAC,KAAK,EAAE;AACjB,YAAA,IAAI,IAAI,CAAA,CAAA,EAAI,OAAO,CAAC,KAAK,EAAE;QAC7B;AAAO,aAAA,IAAI,OAAO,CAAC,iBAAiB,IAAI,gBAAgB,EAAE;AACxD,YAAA,OAAO,EAAE;QACX;IACF;AAEA,IAAA,OAAO,IAAI;AACb;AAEM,SAAU,gBAAgB,CAAC,IAA+B,EAAA;AAC9D,IAAA,OAAO,IAAI,EAAE,aAAa,IAAI,EAAE;AAClC;AAEA,SAAS,YAAY,CACnB,QAAgB,EAChB,aAAqB,EACrB,KAAa,EACb,MAAe,EAAA;IAEf,IAAI,MAAM,EAAE;AACV,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,QAAQ;AAC3B,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,KAAK;AAC3B,QAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,KAAK,EAAE;IAC/B;IACA,IAAI,CAAC,QAAQ,EAAE;AACb,QAAA,OAAO,KAAK,GAAG,CAAA,EAAG,aAAa,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,GAAG,aAAa;IAC5D;AACA,IAAA,MAAM,YAAY,GAAG,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,aAAa,EAAE;AACnD,IAAA,OAAO,KAAK,GAAG,CAAA,EAAG,YAAY,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,GAAG,YAAY;AAC1D;;AC/EA,MAAM,kBAAkB,GAAW,qBAAqB;AACxD,MAAM,oBAAoB,GAA0B;IAClD,WAAW;IACX,YAAY;IACZ,WAAW;CACZ;AAWD,MAAM,cAAc,GAA2B;AAC7C,IAAA,OAAO,EAAE,mBAAmB;AAC5B,IAAA,KAAK,EAAE,mBAAmB;AAC1B,IAAA,MAAM,EAAE,gBAAgB;AACxB,IAAA,QAAQ,EAAE,eAAe;AACzB,IAAA,WAAW,EAAE,4BAA4B;AACzC,IAAA,OAAO,EAAE,oBAAoB;CAC9B;MAkCY,cAAc,CAAA;AACR,IAAA,gBAAgB,GAAG,MAAM,CAAC,uBAAuB,CAAC;AAClD,IAAA,cAAc,GAAG,MAAM,CAAC,qBAAqB,CAAC;AAC9C,IAAA,mBAAmB,GAAG,MAAM,CAAC,0BAA0B,CAAC;;AAGxD,IAAA,MAAM,GAAG,SAAS,CAAgB,eAAe,kDAAC;AAClD,IAAA,UAAU,GACzB,SAAS,CAAoB,mBAAmB,sDAAC;;;AAK1C,IAAA,gBAAgB,GAAG,KAAK,CAE/B,EAAE,4DAAC;;IAGI,aAAa,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,eAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;;IAG/B,oBAAoB,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,sBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;;IAGtC,UAAU,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAU;;AAG5B,IAAA,WAAW,GAAG,KAAK,CAAC,EAAE,uDAAC;;AAGvB,IAAA,WAAW,GAAG,KAAK,CAAC,KAAK,uDAAC;;AAG1B,IAAA,aAAa,GAAG,KAAK,CAAC,KAAK,yDAAC;;AAG5B,IAAA,WAAW,GAAG,KAAK,CAAwB,oBAAoB,uDAAC;;AAGhE,IAAA,QAAQ,GAAG,KAAK,CAAC,KAAK,oDAAC;;AAGvB,IAAA,gBAAgB,GAAG,KAAK,CAAC,KAAK,4DAAC;;;IAK/B,gBAAgB,GAAG,MAAM,EAAoB;;IAG7C,YAAY,GAAG,MAAM,EAAkB;;;AAKvC,IAAA,QAAQ,GAAG,MAAM,CAAC,KAAK,oDAAC;;AAGhB,IAAA,eAAe,GAAG,MAAM,CAAC,EAAE,2DAAC;AAC5B,IAAA,YAAY,GAAG,MAAM,CAAiB,EAAE,wDAAC;;AAGjD,IAAA,MAAM,GAAG,MAAM,CAAiB,EAAE,kDAAC;IACnC,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,YAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;AACnD,IAAA,4BAA4B,GAAG,QAAQ,CAAC,MAAK;AACpD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,EAAE;AACzC,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,YAAA,OAAO,SAAS;QAClB;AAEA,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE;AAC/B,QAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,GAAG,SAAS;AACvD,IAAA,CAAC,wEAAC;AAEO,IAAA,oBAAoB,GAAG,CAC9B,OAA4B,KACe;AAC3C,QAAA,OAAO,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAC5C;AACE,YAAA,GAAG,OAAO;AACV,YAAA,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;AACnC,YAAA,oBAAoB,EAClB,IAAI,CAAC,4BAA4B,EAAE;AACnC,gBAAA,IAAI,CAAC,cAAc,EAAE,EAAE,oBAAoB;AAC9C,SAAA,EACD,IAAI,CAAC,gBAAgB,EAAE,GAAG,cAAc,GAAG,SAAS,CACrD;AACH,IAAA,CAAC;;IAGO,eAAe,GAAG,EAAE;;AAGnB,IAAA,UAAU,GAAG,MAAM,CAAqB,SAAS,sDAAC;AAClD,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,KAAK,MAAM,sDAAC;AACzD,IAAA,gBAAgB,GAAG,MAAM,CAAC,KAAK,4DAAC;AAChC,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;AACjD,IAAA,cAAc,GAAG,QAAQ,CAA6B,MAC7D,IAAI,CAAC,gBAAgB,EAAE,GAAG,cAAc,GAAG,SAAS,0DACrD;AACQ,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,QAAA,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,oBAAoB;AACtD,IAAA,CAAC,+DAAC;IACM,sBAAsB,GAAmB,EAAE;IAC3C,0BAA0B,GAAG,EAAE;;AAG/B,IAAA,QAAQ,GAAyC,MAAK,EAAE,CAAC;AACzD,IAAA,SAAS,GAAe,MAAK,EAAE,CAAC;;AAGvB,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,sDAAC;;AAGlC,IAAA,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU;;AAG7C,IAAA,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY;;AAGjD,IAAA,cAAc,GAAG,MAAM,CAAuC,IAAI,0DAAC;;AAGnE,IAAA,kBAAkB,GAAG,QAAQ,CACpC,MAAM,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,8DACzD;;AAGQ,IAAA,gBAAgB,GAAG,MAAM,CAAC,KAAK,4DAAC;IAEjC,gBAAgB,GAAG,CAAC;;AAGX,IAAA,mBAAmB,GAAG,MAAM,CAE3C,EAAE,+DAAC;;AAGY,IAAA,mBAAmB,GAAG,MAAM,CAAgB,IAAI,+DAAC;AAElE,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE;AACtC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;YACrC,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;gBACxC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAC5B,OAAO,EACP,SAAS,EACT,IAAI,CAAC,aAAa,EAAE,EACpB,IAAI,CAAC,UAAU,EAAE,EACjB,OAAO,CACR;YACH;AACF,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE;AACpC,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;AACxC,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE;AACrC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;AACrC,YAAA,MAAM,oBAAoB,GAAG,IAAI,CAAC,4BAA4B,EAAE;YAEhE,IAAI,CAAC,QAAQ,EAAE;AACb,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7B,gBAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;AAChC,gBAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;AACjC,gBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;gBAChC;YACF;AAEA,YAAA,MAAM,SAAS,GAAG,EAAE,IAAI,CAAC,gBAAgB;AACzC,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;AAC/B,YAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;AAChC,YAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC;AACjC,YAAA,IAAI,CAAC;AACF,iBAAA,WAAW,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO;AACnD,iBAAA,SAAS,CAAC,CAAC,OAAO,KAAI;AACrB,gBAAA,IAAI,SAAS,KAAK,IAAI,CAAC,gBAAgB,EAAE;oBACvC;gBACF;AAEA,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC;AAChC,gBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;gBAEhC,IAAI,CAAC,OAAO,EAAE;oBACZ;gBACF;AAEA,gBAAA,IAAI,OAAO,CAAC,iBAAiB,EAAE,MAAM,EAAE;AACrC,oBAAA,MAAM,eAAe,GACnB,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,MAAM,CACzC,CAAC,QAAQ,KACP,QAAQ,CAAC,WAAW,KAAK,QAAQ;wBACjC,CAAC,QAAQ,CAAC,iBAAiB;AAC3B,wBAAA,CAAC,QAAQ,CAAC,aAAa,CAC1B,IAAI,EAAE;AACT,oBAAA,MAAM,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAC7C,CAAC,GAAG,EAAE,QAAQ,MAAM;AAClB,wBAAA,GAAG,GAAG;AACN,wBAAA,CAAC,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,iBAAiB;qBAC5C,CAAC,EACF,EAAiD,CAClD;oBACD,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,OAAO,MAAM;AAC5C,wBAAA,GAAG,OAAO;AACV,wBAAA,GAAG,gBAAgB;AACpB,qBAAA,CAAC,CAAC;gBACL;AACF,YAAA,CAAC,CAAC;AACN,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE;AACrC,YAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE;AACzB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE;AACpC,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE;gBAClD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACtC;AACF,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE;AACrC,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAChD,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC1C,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,EAAE;AAC5C,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;AAErC,YAAA,IACE,gBAAgB;AAChB,gBAAA,CAAC,QAAQ;AACT,gBAAA,CAAC,SAAS;AACV,gBAAA,CAAC,SAAS;gBACV,CAAC,OAAO,EACR;AACA,gBAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAClC;YACF;YAEA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,SAAS,CAAC;AACtD,YAAA,IAAI,QAAQ,KAAK,SAAS,EAAE;AAC1B,gBAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAClC;YACF;AAEA,YAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC;AACvC,YAAA,IAAI,CAAC;AACF,iBAAA,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS;AACjD,iBAAA,SAAS,CAAC,CAAC,KAAK,KAAI;gBACnB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,OAAO,MAAM;AAC5C,oBAAA,GAAG,OAAO;AACV,oBAAA,CAAC,SAAS,GAAG,KAAK,IAAI,EAAE;AACzB,iBAAA,CAAC,CAAC;AACH,gBAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE,KAAK,SAAS,EAAE;AAC5C,oBAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;gBACpC;AACF,YAAA,CAAC,CAAC;AACN,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE;AACrC,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAChD,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC1C,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,EAAE;YAE5C,IAAI,gBAAgB,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS;gBAAE;AAE/D,YAAA,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC,SAAS,CAAC;gBAAE;AAE5C,YAAA,IAAI,CAAC;AACF,iBAAA,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS;AAC5C,iBAAA,SAAS,CAAC,CAAC,QAAQ,KAAI;AACtB,gBAAA,IAAI,CAAC,QAAQ;oBAAE;gBACf,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,OAAO,MAAM;AAC7C,oBAAA,GAAG,OAAO;AACV,oBAAA,CAAC,SAAS,GAAG,QAAQ,CAAC,cAAc,IAAI,EAAE;AAC3C,iBAAA,CAAC,CAAC;AACL,YAAA,CAAC,CAAC;AACN,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE;AACpC,YAAA,MAAM,iBAAiB,GACrB,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC;AAChC,gBAAA,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC;AACtC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,KAAK,KAAK;AAEpD,YAAA,IAAI,iBAAiB,IAAI,CAAC,OAAO,EAAE;AACjC,gBAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAC3B,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CACvD;gBACD;YACF;AAEA,YAAA,IAAI,CAAC,iBAAiB,IAAI,OAAO,EAAE;AACjC,gBAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClD;AACF,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE;AAChC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE;AAC5C,YAAA,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;gBAAE;YAErC,IAAI,OAAO,GAAG,KAAK;YACnB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,KAAI;AAC3C,gBAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,OAAO,CAAC,KAAK;AACtD,gBAAA,IAAI,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE;oBAChC,OAAO,GAAG,IAAI;oBACd,OAAO,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE;gBAC1C;AACA,gBAAA,OAAO,OAAO;AAChB,YAAA,CAAC,CAAC;YAEF,IAAI,OAAO,EAAE;AACX,gBAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;YACrC;AACF,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE;AACtC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAEvC,YAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AACxB,gBAAA,IAAI,OAAO;AAAE,oBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1C;YACF;AAEA,YAAA,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE;AAC5D,gBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE;IAC/B;;AAIA,IAAA,UAAU,CAAC,KAAiC,EAAA;QAC1C,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;AAC5B,YAAA,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC/C,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE;YAC7B;QACF;QAEA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,GAAG,EAAE;AACjE,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ;AAC9B,cAAE,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,OAAO;eAC1D,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;AAC5B,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;AAEpC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC;YACjD;QACF;AAEA,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AACxB,YAAA,IAAI,CAAC,iBAAiB,CACpB,EAAE,EACF,UAAU,EACV,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAC5B,IAAI,CACL;YACD;QACF;QAEA,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC;IACpD;AAEA,IAAA,gBAAgB,CAAC,EAAwC,EAAA;AACvD,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;IACpB;AAEA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;IACjC;;AAGA,IAAA,eAAe,CAAC,UAAkB,EAAA;AAChC,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,eAAe,EAAE;IACxB;;AAGA,IAAA,mBAAmB,CAAC,UAAkB,EAAA;AACpC,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;AACpC,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE;YACtB,IAAI,CAAC,kBAAkB,EAAE;AACzB,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;AAChC,YAAA,IAAI,CAAC,sBAAsB,GAAG,EAAE;AAChC,YAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;YACpC,IAAI,CAAC,eAAe,EAAE;YACtB;QACF;AAEA,QAAA,IACE,CAAC,IAAI,CAAC,gBAAgB,EAAE;AACxB,YAAA,UAAU,KAAK,IAAI,CAAC,0BAA0B,EAC9C;AACA,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,kBAAkB,EAAE;QAC3B;QACA,IAAI,CAAC,eAAe,EAAE;IACxB;;AAGA,IAAA,aAAa,CAAC,KAAiB,EAAA;AAC7B,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;AACrB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE;YAChC,IAAI,MAAM,EAAE;AACV,gBAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YACxB;YACA;QACF;AACA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;QAC5B,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxB;IACF;;AAGA,IAAA,cAAc,CAAC,SAAyB,EAAA;AACtC,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;AACtC,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI;AAC3B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;AAChC,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,eAAe,EAAE;IACxB;IAEA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IACzB;IAEA,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,SAAS,EAAE;IAClB;IAEQ,eAAe,GAAA;QACrB,IAAI,CAAC,QAAQ,CAAC;AACZ,YAAA,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE;AAClC,YAAA,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE;AAC7B,SAAA,CAAC;IACJ;AAEA,IAAA,YAAY,CAAC,KAAc,EAAA;AACzB,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB;QACF;QACA,MAAM,QAAQ,GAAuB,KAAK,GAAG,MAAM,GAAG,SAAS;AAC/D,QAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;IAC9B;AAEQ,IAAA,aAAa,CAAC,IAAwB,EAAA;AAC5C,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,IAAI;YAAE;AAEhC,QAAA,IAAI,IAAI,KAAK,MAAM,EAAE;YACnB,IAAI,CAAC,aAAa,EAAE;YACpB;QACF;AAEA,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;YAC3B;QACF;QAEA,IAAI,CAAC,YAAY,EAAE;IACrB;IAEQ,aAAa,GAAA;QACnB,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;AACnD,QAAA,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,eAAe,EAAE;AACxD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;QAC5B,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE;AAClC,YAAA,IAAI,CAAC,0BAA0B,GAAG,OAAO;AACzC,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC;YACjC,IAAI,CAAC,eAAe,EAAE;QACxB;AACA,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;AAChC,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;IAC7B;IAEQ,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;YAClC,IAAI,CAAC,kBAAkB,EAAE;AACzB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YAC5B,IAAI,MAAM,EAAE;AACV,gBAAA,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACvB;AACA,YAAA,IAAI,CAAC,sBAAsB,GAAG,EAAE;AAChC,YAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;AACpC,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;YAChC;QACF;QAEA,IAAI,IAAI,CAAC,sBAAsB,CAAC,MAAM,GAAG,CAAC,EAAE;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE;AACpD,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;AACzB,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC/C,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YAC5B,IAAI,MAAM,EAAE;AACV,gBAAA,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC7B;QACF;AACA,QAAA,IAAI,IAAI,CAAC,0BAA0B,EAAE;YACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC;QAC3D;AACA,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;IAClC;IAEQ,kBAAkB,GAAA;AACxB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;YAClE;QACF;AACA,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;AACzB,QAAA,IAAI,CAAC,eAAe,GAAG,EAAE;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5B;;;IAKA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;AAC5B,QAAA,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC/C,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE;QAC7B,IAAI,CAAC,eAAe,EAAE;IACxB;IAEQ,sBAAsB,CAC5B,UAAkB,EAClB,OAAuB,EAAA;QAEvB,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;AAChC,YAAA,OAAO,UAAU;QACnB;AACA,QAAA,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE;IAC3D;IAEQ,iBAAiB,CACvB,OAAuB,EACvB,UAAkB,EAClB,WAAoB,EACpB,eAAwB,KAAK,EAAA;QAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;AAC1C,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;AACxB,QAAA,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,GAAG,EAAE;AAE3D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;QAC5B,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;QAC5B;AAEA,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE;QACpC,IAAI,UAAU,EAAE;AACd,YAAA,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;QACnC;QAEA,IAAI,WAAW,EAAE;AACf,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;AAC3B,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC;AACvC,YAAA,IAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,KAAK,EAAE;AAC7C,YAAA,IAAI,CAAC,0BAA0B,GAAG,UAAU;YAC5C;QACF;AAEA,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9B,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC;AAChC,QAAA,IAAI,CAAC,sBAAsB,GAAG,EAAE;AAChC,QAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;IACtC;;AAIS,IAAA,aAAa,GAAG,MAAM,CAAS,EAAE,yDAAC;AAElC,IAAA,oBAAoB,GAAG,MAAM,CAAgB,EAAE,gEAAC;AAEhD,IAAA,gBAAgB,GAAG,MAAM,CAAC,EAAE,4DAAC;AAErB,IAAA,oBAAoB,GAAG,MAAM,CAE5C,EAAE,gEAAC;AAEI,IAAA,gBAAgB,GAAG,QAAQ,CAAuB,MAAK;QAC9D,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,gBAAgB,EAAE,SAAS,IAAI,EAAE;AACjE,IAAA,CAAC,4DAAC;AAEO,IAAA,YAAY,GAAG,QAAQ,CAAC,MAC/B,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CACxE;AAEQ,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;AAChC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,QAAA,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,gBAAgB,EAAE,cAAc,GAAG,KAAK,CAAC;AACzE,IAAA,CAAC,oDAAC;AAEO,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;AACvC,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACzC,QAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,EAAE;QACrC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM;YAClC,GAAG,EAAE,QAAQ,CAAC,KAAK;AACnB,YAAA,KAAK,EAAE,CAAA,CAAA,EAAI,QAAQ,CAAC,KAAK,CAAA,CAAE;AAC3B,YAAA,aAAa,EAAE,QAAQ,CAAC,iBAAiB,IAAI,KAAK;AAClD,YAAA,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB;AACtC,SAAA,CAAC,CAAC;AACL,IAAA,CAAC,2DAAC;;AAGO,IAAA,YAAY,GAAG,QAAQ,CAAc,MAC5C,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;QACrC,EAAE,EAAE,KAAK,CAAC,GAAG;QACb,IAAI,EAAE,KAAK,CAAC,GAAG;QACf,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,kBAAkB;KACtD,CAAC,CAAC,wDACJ;;AAGD,IAAA,aAAa,CAAC,IAAe,EAAA;QAC3B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxC;AAES,IAAA,YAAY,GAAG,QAAQ,CAAgB,MAAK;AACnD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,QAAA,OAAO,mBAAmB,CAAC;YACzB,KAAK;AACL,YAAA,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE;AACrC,YAAA,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAClC,YAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;AACzB,YAAA,WAAW,EAAE,IAAI,CAAC,oBAAoB,EAAE;AACzC,SAAA,CAAC;AACJ,IAAA,CAAC,wDAAC;AAEO,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AACtC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE;AACpC,QAAA,MAAM,cAAc,GAClB,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC;QAC1E,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,KAAK,CAAC;AAC5D,IAAA,CAAC,0DAAC;IAEO,iBAAiB,GAAG,QAAQ,CAAC,MACpC,cAAc,CACZ,IAAI,CAAC,aAAa,EAAE,EACpB,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CAAC,YAAY,EAAE,EACnB,KAAK,CACN,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CACF;IAEQ,iBAAiB,GAAG,QAAQ,CAAC,MACpC,cAAc,CACZ,IAAI,CAAC,aAAa,EAAE,EACpB,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CACL,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CACF;AAEQ,IAAA,qBAAqB,GAAG,QAAQ,CAAC,MAAK;AAC7C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACrC,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,EAAE;QACpB,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE;AAChD,IAAA,CAAC,iEAAC;AAEO,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,EAAE;AAC1C,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACzC,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK;AACrB,aAAA,GAAG,CAAC,CAAC,KAAK,KAAI;AACb,YAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;AACzB,YAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;YAC/D,MAAM,aAAa,GACjB,IAAI,EAAE,aAAa,IAAI,QAAQ,EAAE,aAAa,IAAI,IAAI;YACxD,MAAM,iBAAiB,GACrB,QAAQ,EAAE,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC;AACvD,YAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC;YAC5C,OAAO;gBACL,KAAK;gBACL,IAAI;gBACJ,iBAAiB;gBACjB,aAAa;aACd;AACH,QAAA,CAAC;AACA,aAAA,MAAM,CACL,CAAC,MAAM,KACL,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAC/D;AACL,IAAA,CAAC,+DAAC;AAEO,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,KAAK;AACzD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE;AACpC,QAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAC/C,YAAA,OAAO,KAAK;QACd;QACA,OAAO,QAAQ,CAAC,KAAK,CACnB,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAClE;AACH,IAAA,CAAC,6DAAC;AAEO,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE;AAC3B,YAAA,OAAO,SAAS;QAClB;QACA,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,oBAAoB;AAC9D,QAAA,OAAO,UAAU;AACnB,IAAA,CAAC,+DAAC;AAEO,IAAA,sBAAsB,GAAG,QAAQ,CAExC,MAAK;AACL,QAAA,MAAM,MAAM,GAAgD;YAC1D,GAAG,IAAI,CAAC,gBAAgB,EAAE;SAC3B;AACD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE;AAC3C,QAAA,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,KAAI;YACjD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,gBAAA,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK;YACtB;AACF,QAAA,CAAC,CAAC;AACF,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,kEAAC;AAEO,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE;QACrC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI;AAC7D,IAAA,CAAC,6DAAC;AAEO,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;AACvC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACrC,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,EAAE;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,CAAC;AAClD,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,EAAE;QACtD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;YACzB,GAAG,EAAE,IAAI,CAAC,GAAG;AACb,YAAA,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG;AAC5B,SAAA,CAAC,CAAC;AACL,IAAA,CAAC,2DAAC;AAEO,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AACxC,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;QACnC,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,IAAI;AACxE,IAAA,CAAC,4DAAC;AAEO,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAAE,YAAA,OAAO,KAAK;AAC1C,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAC1C,IAAA,CAAC,6DAAC;AAEF,IAAA,gBAAgB,CAAC,KAAa,EAAA;AAC5B,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE,KAAK,KAAK,EAAE;YAClC;QACF;AACA,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,QAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAC3B,oBAAoB,CAClB,KAAK,EACL,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,EACxD,IAAI,CAAC,cAAc,EAAE,EAAE,gBAAgB,EAAE,cAAc,GAAG,KAAK,CAAC,CACjE,CACF;AACD,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/B;IAEA,mBAAmB,CAAC,KAAa,EAAE,KAAoB,EAAA;QACrD,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAI;;;AAG5C,YAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;AAC5C,YAAA,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE;AAC1D,YAAA,OAAO,OAAO;AAChB,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,cAAc,CAAC,aAAqB,EAAA;QAClC,MAAM,KAAK,GAAG,EAAE;QAEhB,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK;AAC7C,YAAA,GAAG,QAAQ;YACX,EAAE,aAAa,EAAE,KAAK,EAAE;AACzB,SAAA,CAAC;IACJ;IAEA,qBAAqB,CACnB,aAAqB,EACrB,OAA6B,EAAA;QAE7B,OAAO,CAAC,IAAI,EAAE;AACd,QAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC;IACpC;AAEA,IAAA,iBAAiB,CAAC,KAAa,EAAA;QAC7B,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,QAAQ,KACxC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CACvC;IACH;AAEA,IAAA,cAAc,CAAC,KAAa,EAAA;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC;AAC1C,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,EAAE;QACvB,OAAO,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AAC3C,YAAA,GAAG,EAAE,KAAK;AACV,YAAA,IAAI,EAAE,KAAK;AACZ,SAAA,CAAC,CAAC;IACL;AAEA,IAAA,sBAAsB,CAAC,WAAwC,EAAA;AAC7D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACpC,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAAE;AAE/B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAC1C,QAAA,IAAI,CAAC,SAAS;YAAE;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG;AACrC,QAAA,MAAM,KAAK,GAAG,mBAAmB,CAC/B,CAAA,CAAA,EAAI,SAAS,CAAA,EAAA,EAAK,IAAI,CAAC,GAAG,EAAE,EAC5B,SAAS,EACT,OAAO,CACR;QACD,WAAW,CAAC,KAAK,CAAC;IACpB;uGAh1BW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,oBAAA,EAAA,EAAA,iBAAA,EAAA,sBAAA,EAAA,UAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EARd;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,cAAc,CAAC;AAC7C,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACF,SAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,eAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3HH,qrkBAmYA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlSI,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAClB,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACJ,MAAM,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,eAAA,EAAA,MAAA,EAAA,SAAA,EAAA,WAAA,EAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,SAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACN,WAAW,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,aAAA,EAAA,sBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,SAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,OAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,qBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,sBAAA,EAAA,sBAAA,EAAA,wBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,OAAO,EAAA,QAAA,EAAA,aAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,EAAA,gBAAA,EAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,WAAW,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,eAAA,EAAA,aAAA,EAAA,UAAA,EAAA,SAAA,EAAA,UAAA,EAAA,aAAA,EAAA,MAAA,EAAA,MAAA,EAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACX,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,gBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,QAAQ,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,OAAA,EAAA,WAAA,EAAA,cAAA,EAAA,MAAA,EAAA,OAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,cAAc,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,oBAAA,EAAA,oBAAA,EAAA,WAAA,EAAA,YAAA,EAAA,aAAA,EAAA,mBAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,gBAAgB,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,aAAa,mMACb,iBAAiB,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,sBAAA,EAAA,wBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAcR,cAAc,EAAA,UAAA,EAAA,CAAA;kBAhC1B,SAAS;+BACE,oBAAoB,EAAA,UAAA,EAClB,IAAI,EAAA,OAAA,EACP;wBACP,YAAY;wBACZ,kBAAkB;wBAClB,WAAW;wBACX,IAAI;wBACJ,MAAM;wBACN,WAAW;wBACX,OAAO;wBACP,UAAU;wBACV,WAAW;wBACX,aAAa;wBACb,QAAQ;wBACR,cAAc;wBACd,gBAAgB;wBAChB,aAAa;wBACb,iBAAiB;qBAClB,EAAA,IAAA,EAEK;AACJ,wBAAA,KAAK,EAAE,OAAO;qBACf,EAAA,SAAA,EACU;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAE,UAAU,CAAC,oBAAoB,CAAC;AAC7C,4BAAA,KAAK,EAAE,IAAI;AACZ,yBAAA;AACF,qBAAA,EAAA,QAAA,EAAA,qrkBAAA,EAAA;AAQkD,SAAA,CAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,cAAA,EAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,CAAA,eAAe,oEAEnC,mBAAmB,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,eAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,oBAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,UAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,eAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AErIpD;;AAEG;;ACFH;;;;;;;;;;;AAWG;AAEH;;ACbA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"masterteam-formula-builder.mjs","sources":["../../../../packages/masterteam/formula-builder/src/lib/services/formula-validator.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-context.service.ts","../../../../packages/masterteam/formula-builder/src/lib/services/formula-autocomplete.service.ts","../../../../packages/masterteam/formula-builder/src/lib/utils/formula-path-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.ts","../../../../packages/masterteam/formula-builder/src/lib/formula-builder.html","../../../../packages/masterteam/formula-builder/src/lib/services/index.ts","../../../../packages/masterteam/formula-builder/src/public-api.ts","../../../../packages/masterteam/formula-builder/src/masterteam-formula-builder.ts"],"sourcesContent":["/**\r\n * Formula Validator Service\r\n * Handles real-time validation via API\r\n */\r\n\r\nimport { Injectable, inject, signal } from '@angular/core';\r\nimport { HttpClient, HttpErrorResponse } from '@angular/common/http';\r\nimport {\r\n Observable,\r\n Subject,\r\n of,\r\n catchError,\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n tap,\r\n} from 'rxjs';\r\nimport {\r\n ValidationResult,\r\n ValidationRequest,\r\n ApiErrorResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\ntype ValidationJob = ValidationRequest & { apiMode: FormulaApiMode };\r\n\r\n/** Default validation result for empty formulas */\r\nconst EMPTY_VALIDATION: ValidationResult = {\r\n isValid: true,\r\n errors: [],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n/** Error validation result */\r\nconst ERROR_VALIDATION: ValidationResult = {\r\n isValid: false,\r\n errors: [\r\n { message: 'Validation failed', line: 1, column: 1, severity: 'Error' },\r\n ],\r\n warnings: [],\r\n dependencies: [],\r\n complexity: 0,\r\n};\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaValidatorService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n /** Debounce time in ms */\r\n private readonly DEBOUNCE_MS = 300;\r\n\r\n /** Current validation result */\r\n private readonly _validation = signal<ValidationResult>(EMPTY_VALIDATION);\r\n\r\n /** Loading state */\r\n private readonly _isValidating = signal(false);\r\n\r\n /** Validation subject for debouncing */\r\n private readonly validateSubject = new Subject<ValidationJob>();\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n /** Public signals */\r\n readonly validation = this._validation.asReadonly();\r\n readonly isValidating = this._isValidating.asReadonly();\r\n\r\n constructor() {\r\n this.setupValidationStream();\r\n }\r\n\r\n /** Setup debounced validation stream */\r\n private setupValidationStream(): void {\r\n this.validateSubject\r\n .pipe(\r\n debounceTime(this.DEBOUNCE_MS),\r\n distinctUntilChanged(\n (a, b) =>\n a.formula === b.formula &&\n a.levelSchemaId === b.levelSchemaId &&\n a.moduleId === b.moduleId &&\n a.templateId === b.templateId &&\n a.apiMode === b.apiMode &&\n JSON.stringify(a.knownProperties) ===\n JSON.stringify(b.knownProperties),\n ),\n tap(() => this._isValidating.set(true)),\r\n switchMap((request) => this.callValidateApi(request)),\r\n )\r\n .subscribe((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n });\r\n }\r\n\r\n /** Validate formula (debounced) */\r\n validate(\n formula: string,\n knownProperties?: string[],\n levelSchemaId?: number,\n moduleId?: number,\n templateId?: number,\n apiMode: FormulaApiMode = 'default',\n ): void {\n // Handle empty formula\r\n if (!formula || formula.trim() === '') {\r\n this._validation.set(EMPTY_VALIDATION);\r\n return;\r\n }\r\n\r\n // Push to debounced stream\r\n this.validateSubject.next({\n formula,\n knownProperties,\n levelSchemaId,\n moduleId,\n templateId,\n apiMode,\n });\n }\n\r\n /** Validate formula immediately (no debounce) */\r\n validateImmediate(\n formula: string,\n knownProperties?: string[],\n levelSchemaId?: number,\n moduleId?: number,\n templateId?: number,\n apiMode: FormulaApiMode = 'default',\n ): Observable<ValidationResult> {\n if (!formula || formula.trim() === '') {\r\n return of(EMPTY_VALIDATION);\r\n }\r\n\r\n this._isValidating.set(true);\r\n\r\n return this.callValidateApi({\n formula,\n knownProperties,\n levelSchemaId,\n moduleId,\n templateId,\n apiMode,\n }).pipe(\n tap((result) => {\r\n this._validation.set(result);\r\n this._isValidating.set(false);\r\n }),\r\n );\r\n }\r\n\r\n /** Call validation API */\r\n private callValidateApi(\r\n request: ValidationJob,\r\n ): Observable<ValidationResult> {\r\n const { apiMode, ...payload } = request;\r\n return this.http\r\n .post<\r\n ValidationResult | { data: ValidationResult }\r\n >(`${this.getBaseUrl(apiMode)}/validate`, payload)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? ERROR_VALIDATION),\r\n catchError((error: HttpErrorResponse) => {\r\n console.error('Validation API error:', error);\r\n\r\n // Try to extract error message\r\n const apiError = error.error as ApiErrorResponse;\r\n const message =\r\n apiError?.message ?? apiError?.error ?? 'Validation failed';\r\n\r\n return of({\r\n ...ERROR_VALIDATION,\r\n errors: [\r\n { message, line: 1, column: 1, severity: 'Error' as const },\r\n ],\r\n });\r\n }),\r\n );\r\n }\r\n\r\n /** Reset validation state */\r\n reset(): void {\r\n this._validation.set(EMPTY_VALIDATION);\r\n this._isValidating.set(false);\r\n }\r\n\r\n /** Get current validation result */\r\n getCurrentValidation(): ValidationResult {\r\n return this._validation();\r\n }\r\n\r\n /** Check if formula is valid */\r\n isValid(): boolean {\r\n return this._validation().isValid;\r\n }\r\n\r\n /** Get validation errors */\r\n getErrors() {\r\n return this._validation().errors;\r\n }\r\n\r\n /** Get validation warnings */\r\n getWarnings() {\r\n return this._validation().warnings;\r\n }\r\n\r\n /** Get formula dependencies */\r\n getDependencies() {\r\n return this._validation().dependencies;\r\n }\r\n\r\n /** Get formula complexity */\r\n getComplexity() {\r\n return this._validation().complexity;\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, tap, map } from 'rxjs';\r\n\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaBuilderNextTokensResponse,\r\n FormulaPropertyDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaContextService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n private readonly contextCache = new Map<\r\n string,\r\n FormulaBuilderContextResponse\r\n >();\r\n private readonly propertiesCache = new Map<\r\n string,\r\n FormulaPropertyDescriptor[]\r\n >();\r\n private readonly nextTokensCache = new Map<\r\n string,\r\n FormulaBuilderNextTokensResponse\r\n >();\r\n\r\n loadContext(\n schemaId: number,\n moduleId?: number,\n contextEntityTypeKey?: string,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaBuilderContextResponse | null> {\n if (!schemaId) return of(null);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${contextEntityTypeKey ?? ''}`;\n const cached = this.contextCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\n const params = new URLSearchParams();\n if (mode === 'default' && contextEntityTypeKey) {\n params.set('contextEntityTypeKey', contextEntityTypeKey);\n }\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n const queryString = params.toString();\n const query = queryString ? `?${queryString}` : '';\n\n return this.http\n .get<\n FormulaBuilderContextResponse | { data: FormulaBuilderContextResponse }\n >(`${this.getBaseUrl(mode)}/builder/context/${schemaId}${query}`)\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((context) => {\r\n if (context) {\r\n this.contextCache.set(cacheKey, context);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula builder context:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n\r\n getScopeProperties(\n schemaId: number,\n component: string,\n tablePath: string,\n moduleId?: number,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaPropertyDescriptor[]> {\n if (!schemaId || !component || !tablePath) return of([]);\n if (mode === 'current-only') return of([]);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;\n const cached = this.propertiesCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\r\n const params = new URLSearchParams({\n schemaId: schemaId.toString(),\n component,\n tablePath,\n });\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n\n return this.http\n .get<\n FormulaPropertyDescriptor[] | { data: FormulaPropertyDescriptor[] }\n >(`${this.getBaseUrl(mode)}/builder/properties?${params.toString()}`)\n .pipe(\r\n map((response) => this.unwrapResponse(response) ?? []),\r\n tap((response) => {\r\n this.propertiesCache.set(cacheKey, response);\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula properties:', error);\r\n return of([]);\r\n }),\r\n );\r\n }\r\n\r\n getNextTokens(\n schemaId: number,\n component: string,\n tablePath: string,\n moduleId?: number,\n mode: FormulaApiMode = 'default',\n ): Observable<FormulaBuilderNextTokensResponse | null> {\n if (!schemaId || !component || !tablePath) return of(null);\n if (mode === 'current-only') return of(null);\n\n const cacheKey = `${mode}:${schemaId}:${moduleId ?? ''}:${component}:${tablePath}`;\n const cached = this.nextTokensCache.get(cacheKey);\n if (cached) {\n return of(cached);\n }\n\r\n const params = new URLSearchParams({\n schemaId: schemaId.toString(),\n component,\n tablePath,\n });\n if (moduleId !== undefined) {\n params.set('moduleId', moduleId.toString());\n }\n\n return this.http\n .get<\n | FormulaBuilderNextTokensResponse\n | { data: FormulaBuilderNextTokensResponse }\n >(`${this.getBaseUrl(mode)}/builder/next-tokens?${params.toString()}`)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n tap((payload) => {\r\n if (payload) {\r\n this.nextTokensCache.set(cacheKey, payload);\r\n }\r\n }),\r\n catchError((error) => {\r\n console.warn('Failed to load formula next tokens:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable, of, catchError, map } from 'rxjs';\r\nimport type {\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from '../models/validation-result.model';\r\n\r\ntype FormulaApiMode = 'default' | 'current-only';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class FormulaAutocompleteService {\r\n private readonly http = inject(HttpClient);\r\n private readonly apiUrl = '/formulas';\r\n\r\n private getBaseUrl(mode: FormulaApiMode): string {\r\n return mode === 'current-only'\r\n ? `${this.apiUrl}/current-only`\r\n : this.apiUrl;\r\n }\r\n\r\n private unwrapResponse<T>(response: T | { data: T } | null): T | null {\r\n if (!response) return null;\r\n if (\r\n typeof response === 'object' &&\r\n response !== null &&\r\n 'data' in response\r\n ) {\r\n return (response as { data: T }).data ?? null;\r\n }\r\n return response as T;\r\n }\r\n\r\n getSuggestions(\r\n request: AutocompleteRequest,\r\n apiMode: FormulaApiMode = 'default',\r\n ): Observable<AutocompleteResponse | null> {\r\n if (!request) {\r\n return of(null);\r\n }\r\n\r\n const normalized: AutocompleteRequest = {\r\n ...request,\r\n formula: request.formula ?? '',\r\n };\r\n\r\n return this.http\r\n .post<\r\n AutocompleteResponse | { data: AutocompleteResponse }\r\n >(`${this.getBaseUrl(apiMode)}/autocomplete`, normalized)\r\n .pipe(\r\n map((response) => this.unwrapResponse(response)),\r\n catchError((error) => {\r\n console.warn('Autocomplete API error:', error);\r\n return of(null);\r\n }),\r\n );\r\n }\r\n}\r\n","import type {\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from '../models/formula-context.model';\r\n\r\nexport type PathSegment = {\r\n operatorToken: string;\r\n value: string;\r\n};\r\n\r\nexport type SegmentMeta = PathSegment & {\r\n parameterKind?: string | null;\r\n requiresParameter: boolean;\r\n allowedValues: string[];\r\n optional: boolean;\r\n canRemove: boolean;\r\n};\r\n\r\nexport type ResolveSegmentsParams = {\r\n scope: string;\r\n segments: PathSegment[];\r\n operators: OperatorDescriptor[];\r\n baseRule?: NextTokenRule;\r\n rulesByPath: Record<string, Record<string, NextTokenRule>>;\r\n};\r\n\r\nexport function resolveSegmentsMeta({\r\n scope,\r\n segments,\r\n operators,\r\n baseRule,\r\n rulesByPath,\r\n}: ResolveSegmentsParams): SegmentMeta[] {\r\n if (!scope || segments.length === 0) {\r\n return [];\r\n }\r\n\r\n let pathBefore = scope;\r\n let blocked = false;\r\n\r\n return segments.map((segment, index) => {\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n const operator = operators.find((op) => op.token === segment.operatorToken);\r\n const rule = blocked\r\n ? undefined\r\n : isBase\r\n ? baseRule\r\n : rulesByPath[pathBefore]?.[segment.operatorToken];\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n const normalizedValue = segment.value;\r\n const isComplete = !requiresParameter || Boolean(normalizedValue);\r\n\r\n if (!blocked && isComplete) {\r\n pathBefore = appendToPath(\r\n pathBefore,\r\n segment.operatorToken,\r\n normalizedValue,\r\n isBase,\r\n );\r\n } else {\r\n blocked = true;\r\n }\r\n\r\n return {\r\n operatorToken: segment.operatorToken,\r\n value: normalizedValue,\r\n parameterKind,\r\n requiresParameter,\r\n allowedValues,\r\n optional: !requiresParameter,\r\n canRemove: !isBase,\r\n };\r\n });\r\n}\r\n\r\nexport function buildInitialSegments(\r\n scope: string,\r\n operator: OperatorDescriptor | undefined,\r\n rule: NextTokenRule | undefined,\r\n): PathSegment[] {\r\n if (!operator || !scope) return [];\r\n const parameterKind = operator.parameterKind ?? rule?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator.requiresParameter ?? Boolean(parameterKind);\r\n const shouldHaveSegment = Boolean(parameterKind) || requiresParameter;\r\n if (!shouldHaveSegment) return [];\r\n\r\n return [{ operatorToken: scope, value: '' }];\r\n}\r\n\r\nexport function buildTablePath(\r\n scope: string,\r\n segments: SegmentMeta[],\r\n baseOperator: OperatorDescriptor | undefined,\r\n stopOnIncomplete: boolean,\r\n): string {\r\n if (!scope) return '';\r\n\r\n if (\r\n stopOnIncomplete &&\r\n segments.length === 0 &&\r\n (baseOperator?.requiresParameter || baseOperator?.parameterKind)\r\n ) {\r\n return '';\r\n }\r\n\r\n let path = scope;\r\n for (let index = 0; index < segments.length; index += 1) {\r\n const segment = segments[index];\r\n const isBase = index === 0 && segment.operatorToken === scope;\r\n if (!isBase) {\r\n path += `.${segment.operatorToken}`;\r\n }\r\n if (segment.value) {\r\n path += `.${segment.value}`;\r\n } else if (segment.requiresParameter && stopOnIncomplete) {\r\n return '';\r\n }\r\n }\r\n\r\n return path;\r\n}\r\n\r\nexport function getAllowedValues(rule: NextTokenRule | undefined): string[] {\r\n return rule?.allowedValues ?? [];\r\n}\r\n\r\nfunction appendToPath(\r\n basePath: string,\r\n operatorToken: string,\r\n value: string,\r\n isBase: boolean,\r\n): string {\r\n if (isBase) {\r\n if (!value) return basePath;\r\n if (!basePath) return value;\r\n return `${basePath}.${value}`;\r\n }\r\n if (!basePath) {\r\n return value ? `${operatorToken}.${value}` : operatorToken;\r\n }\r\n const withOperator = `${basePath}.${operatorToken}`;\r\n return value ? `${withOperator}.${value}` : withOperator;\r\n}\r\n","import {\r\n Component,\r\n forwardRef,\r\n input,\r\n output,\r\n signal,\r\n computed,\r\n inject,\r\n effect,\r\n OnDestroy,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { TranslocoDirective } from '@jsverse/transloco';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NG_VALUE_ACCESSOR,\r\n} from '@angular/forms';\r\nimport { Card } from '@masterteam/components/card';\r\nimport { Button } from '@masterteam/components/button';\r\nimport { SelectField } from '@masterteam/components/select-field';\r\nimport { Tooltip } from '@masterteam/components/tooltip';\r\nimport { RadioCards, type RadioItem } from '@masterteam/components/radio-cards';\r\nimport { ToggleField } from '@masterteam/components/toggle-field';\r\nimport type { MTIcon } from '@masterteam/icons';\r\nimport { PopoverModule } from 'primeng/popover';\r\nimport { Skeleton } from 'primeng/skeleton';\r\nimport { Observable } from 'rxjs';\r\n\r\n// Import pure UI components from @masterteam/components/formula\r\nimport {\r\n FormulaToolbar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n FormulaStatusBar,\r\n type SmartBlock,\r\n type FormulaToken,\r\n type ToolbarTab,\r\n createPropertyBlock,\r\n serializeTokens,\r\n} from '@masterteam/components/formula';\r\n\r\n// Services are kept in formula-builder (backend logic)\r\nimport { FormulaValidatorService } from './services/formula-validator.service';\r\nimport { FormulaContextService } from './services/formula-context.service';\r\nimport { FormulaAutocompleteService } from './services/formula-autocomplete.service';\r\nimport type {\r\n ValidationResult,\r\n AutocompleteRequest,\r\n AutocompleteResponse,\r\n} from './models/validation-result.model';\r\nimport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n NextTokenRule,\r\n OperatorDescriptor,\r\n} from './models/formula-context.model';\r\nimport type { FormulaBuilderValue } from './models/formula-builder-value.model';\r\nimport {\r\n buildInitialSegments,\r\n buildTablePath,\r\n getAllowedValues,\r\n resolveSegmentsMeta,\r\n type PathSegment,\r\n type SegmentMeta,\r\n} from './utils/formula-path-builder';\r\n\r\nconst DEFAULT_SCOPE_ICON: MTIcon = 'general.placeholder';\nconst DEFAULT_TOOLBAR_TABS: readonly ToolbarTab[] = [\n 'functions',\n 'properties',\n 'operators',\n];\nconst PROPERTY_SCOPE_ORDER = [\n 'Current',\n 'Host',\n 'Parent',\n // 'Children',\n // 'Descendants',\n // 'Modules',\n] as const;\n\r\nexport interface FormulaBuilderUiConfig {\r\n toolbarTabs?: readonly ToolbarTab[];\r\n codeOnly?: boolean;\r\n hideToolbar?: boolean;\r\n hideStatusBar?: boolean;\r\n isProcessBuilder?: boolean;\r\n contextEntityTypeKey?: string;\r\n}\r\n\r\nconst SCOPE_ICON_MAP: Record<string, MTIcon> = {\n Current: 'map.marker-pin-01',\n Host: 'map.marker-pin-01',\n Level: 'map.marker-pin-01',\n Parent: 'arrow.arrow-up',\n Children: 'user.users-01',\n Descendants: 'custom.hierarchy-structure',\n Modules: 'file.folder-closed',\n};\r\n\r\n@Component({\r\n selector: 'mt-formula-builder',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n TranslocoDirective,\r\n FormsModule,\r\n Card,\r\n Button,\r\n SelectField,\r\n Tooltip,\r\n RadioCards,\r\n ToggleField,\r\n PopoverModule,\r\n Skeleton,\r\n FormulaToolbar,\r\n FormulaStatusBar,\r\n FormulaEditor,\r\n FormulaEditorCode,\r\n ],\r\n templateUrl: './formula-builder.html',\r\n host: {\r\n class: 'block',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => FormulaBuilder),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FormulaBuilder implements ControlValueAccessor, OnDestroy {\r\n private readonly validatorService = inject(FormulaValidatorService);\r\n private readonly contextService = inject(FormulaContextService);\r\n private readonly autocompleteService = inject(FormulaAutocompleteService);\r\n\r\n /** Reference to the formula editor */\r\n private readonly editor = viewChild<FormulaEditor>('formulaEditor');\r\n private readonly codeEditor =\r\n viewChild<FormulaEditorCode>('formulaEditorCode');\r\n\r\n // ===== INPUTS =====\r\n\r\n /** Properties per table path (e.g., \"Current\", \"Children.Project\") */\r\n readonly propertiesByPath = input<\r\n Record<string, { key: string; name?: string }[]>\r\n >({});\r\n\r\n /** Level schema ID for validation context */\n readonly levelSchemaId = input<number>();\n\n /** Optional module ID when the formula is scoped inside a level-linked module */\n readonly moduleId = input<number>();\n\n /** Optional current context entity key, e.g. LevelData or Risk */\n readonly contextEntityTypeKey = input<string>();\n\r\n /** Template ID for validation context */\r\n readonly templateId = input<number>();\r\n\r\n /** Placeholder text */\r\n readonly placeholder = input('');\r\n\r\n /** Hide the top toolbar */\r\n readonly hideToolbar = input(false);\r\n\r\n /** Hide the status bar */\r\n readonly hideStatusBar = input(false);\r\n\r\n /** Visible toolbar tabs */\r\n readonly toolbarTabs = input<readonly ToolbarTab[]>(DEFAULT_TOOLBAR_TABS);\r\n\r\n /** Force code editor mode and hide the mode toggle */\r\n readonly codeOnly = input(false);\r\n\r\n /** Use Process Builder current-only Formula Engine endpoints */\r\n readonly isProcessBuilder = input(false);\r\n\r\n // ===== OUTPUTS =====\r\n\r\n /** Emits validation result on change */\r\n readonly validationChange = output<ValidationResult>();\r\n\r\n /** Emits when tokens change */\r\n readonly tokensChange = output<FormulaToken[]>();\r\n\r\n // ===== STATE =====\r\n\r\n /** Editor focus state */\r\n readonly hasFocus = signal(false);\r\n\r\n /** Form control value */\r\n private readonly expressionValue = signal('');\r\n private readonly builderValue = signal<FormulaToken[]>([]);\r\n\r\n /** Tokens for the editor */\r\n readonly tokens = signal<FormulaToken[]>([]);\r\n readonly expression = computed(() => this.expressionValue());\r\n readonly resolvedContextEntityTypeKey = computed(() => {\n const value = this.contextEntityTypeKey();\n if (typeof value !== 'string') {\r\n return undefined;\r\n }\r\n\r\n const normalized = value.trim();\r\n return normalized.length > 0 ? normalized : undefined;\n });\n readonly isModuleContext = computed(() => {\n const contextType =\n this.resolvedContextEntityTypeKey() ??\n this.builderContext()?.contextEntityTypeKey;\n\n if (typeof contextType !== 'string') {\n return false;\n }\n\n const normalized = contextType.trim().toLowerCase();\n return normalized.length > 0 && normalized !== 'leveldata';\n });\n\r\n readonly autocompleteProvider = (\r\n request: AutocompleteRequest,\r\n ): Observable<AutocompleteResponse | null> => {\r\n return this.autocompleteService.getSuggestions(\n {\n ...request,\n levelSchemaId: this.levelSchemaId(),\n moduleId: this.moduleId(),\n contextEntityTypeKey:\n this.resolvedContextEntityTypeKey() ??\n this.builderContext()?.contextEntityTypeKey,\n },\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n };\r\n\r\n /** Track last synced builder JSON to avoid loops */\r\n private lastBuilderJson = '';\r\n\r\n /** Editor mode */\r\n readonly editorMode = signal<'builder' | 'code'>('builder');\r\n readonly isCodeMode = computed(() => this.editorMode() === 'code');\r\n readonly isCodeModeLocked = signal(false);\r\n readonly showModeToggle = computed(() => !this.codeOnly());\r\n readonly formulaApiMode = computed<'default' | 'current-only'>(() =>\r\n this.isProcessBuilder() ? 'current-only' : 'default',\r\n );\r\n readonly resolvedToolbarTabs = computed(() => {\r\n const tabs = this.toolbarTabs();\r\n return tabs.length > 0 ? tabs : DEFAULT_TOOLBAR_TABS;\r\n });\r\n private codeModeSnapshotTokens: FormulaToken[] = [];\r\n private codeModeSnapshotExpression = '';\r\n\r\n /** ControlValueAccessor callbacks */\r\n private onChange: (value: FormulaBuilderValue) => void = () => {};\r\n private onTouched: () => void = () => {};\r\n\r\n /** Disabled state */\r\n private readonly isDisabled = signal(false);\r\n\r\n /** Validation result from service */\r\n readonly validation = this.validatorService.validation;\r\n\r\n /** Is validation in progress */\r\n readonly isValidating = this.validatorService.isValidating;\r\n\r\n /** Builder context from API */\r\n readonly builderContext = signal<FormulaBuilderContextResponse | null>(null);\r\n\r\n /** Function categories from context */\r\n readonly functionCategories = computed(\r\n () => this.builderContext()?.functions?.categories ?? [],\r\n );\r\n\r\n /** Is builder context loading */\r\n readonly isContextLoading = signal(false);\r\n\r\n private contextRequestId = 0;\r\n\r\n /** Properties loaded from API */\r\n private readonly propertiesByPathApi = signal<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >({});\r\n\r\n /** Current property list loading path */\r\n private readonly propertyLoadingPath = signal<string | null>(null);\r\n\r\n constructor() {\r\n // Validate when formula changes\r\n effect(() => {\r\n const formula = this.expressionValue();\n const moduleId = this.moduleId();\n const apiMode = this.formulaApiMode();\n if (formula && formula.trim().length > 0) {\n this.validatorService.validate(\n formula,\n undefined,\n this.levelSchemaId(),\n moduleId,\n this.templateId(),\n apiMode,\n );\n }\n });\r\n\r\n // Emit validation changes\r\n effect(() => {\r\n const validation = this.validation();\r\n this.validationChange.emit(validation);\r\n });\r\n\r\n // Load builder context when schema changes\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const apiMode = this.formulaApiMode();\n const contextEntityTypeKey = this.resolvedContextEntityTypeKey();\n\r\n if (!schemaId) {\r\n this.builderContext.set(null);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.isContextLoading.set(false);\r\n return;\r\n }\r\n\r\n const requestId = ++this.contextRequestId;\r\n this.isContextLoading.set(true);\r\n this.propertiesByPathApi.set({});\r\n this.nextTokenRulesByPath.set({});\r\n this.contextService\n .loadContext(schemaId, moduleId, contextEntityTypeKey, apiMode)\n .subscribe((context) => {\n if (requestId !== this.contextRequestId) {\r\n return;\r\n }\r\n\r\n this.builderContext.set(context);\r\n this.isContextLoading.set(false);\r\n\r\n if (!context) {\r\n return;\r\n }\r\n\r\n if (context.currentProperties?.length) {\r\n const scalarOperators =\r\n context.schemaDescriptor?.operators?.filter(\r\n (operator) =>\r\n operator.cardinality === 'scalar' &&\r\n !operator.requiresParameter &&\r\n !operator.parameterKind,\r\n ) ?? [];\r\n const scopedProperties = scalarOperators.reduce(\r\n (acc, operator) => ({\r\n ...acc,\r\n [operator.token]: context.currentProperties,\r\n }),\r\n {} as Record<string, FormulaPropertyDescriptor[]>,\r\n );\r\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n ...scopedProperties,\r\n }));\r\n }\r\n });\r\n });\r\n\r\n // Ensure selected scope exists in available options\r\n effect(() => {\r\n const scopes = this.availableScopes();\r\n if (scopes.length === 0) return;\r\n const current = this.propertyScope();\r\n if (!scopes.some((scope) => scope.key === current)) {\r\n this.setPropertyScope(scopes[0].key);\r\n }\r\n });\r\n\r\n // Fetch properties for the selected table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n const context = this.builderContext();\r\n\r\n if (\r\n isProcessBuilder ||\r\n !schemaId ||\r\n !tablePath ||\r\n !component ||\r\n !context\r\n ) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n const existing = this.propertiesByPathApi()[tablePath];\r\n if (existing !== undefined) {\r\n this.propertyLoadingPath.set(null);\r\n return;\r\n }\r\n\r\n this.propertyLoadingPath.set(tablePath);\n this.contextService\n .getScopeProperties(schemaId, component, tablePath, moduleId)\n .subscribe((props) => {\n this.propertiesByPathApi.update((current) => ({\r\n ...current,\r\n [tablePath]: props ?? [],\r\n }));\r\n if (this.propertyLoadingPath() === tablePath) {\r\n this.propertyLoadingPath.set(null);\r\n }\r\n });\r\n });\r\n\r\n // Fetch next-token rules for the current table path\r\n effect(() => {\r\n const schemaId = this.levelSchemaId();\n const moduleId = this.moduleId();\n const isProcessBuilder = this.isProcessBuilder();\n const tablePath = this.resolvedTablePath();\n const component = this.propertiesComponent();\n\r\n if (isProcessBuilder || !schemaId || !tablePath || !component) return;\r\n\r\n if (this.nextTokenRulesByPath()[tablePath]) return;\r\n\r\n this.contextService\n .getNextTokens(schemaId, component, tablePath, moduleId)\n .subscribe((response) => {\n if (!response) return;\r\n this.nextTokenRulesByPath.update((current) => ({\r\n ...current,\r\n [tablePath]: response.nextTokenRules ?? {},\r\n }));\r\n });\r\n });\r\n\r\n // Keep base segment in sync with scope metadata\r\n effect(() => {\r\n const scope = this.propertyScope();\r\n const operator = this.baseOperator();\r\n const shouldHaveSegment =\r\n Boolean(operator?.parameterKind) ||\r\n Boolean(operator?.requiresParameter);\r\n const segments = this.propertyPathSegments();\r\n const hasBase = segments[0]?.operatorToken === scope;\r\n\r\n if (shouldHaveSegment && !hasBase) {\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(scope, operator, this.baseRule()),\r\n );\r\n return;\r\n }\r\n\r\n if (!shouldHaveSegment && hasBase) {\r\n this.propertyPathSegments.set(segments.slice(1));\r\n }\r\n });\r\n\r\n // Normalize segment values when allowed values change\r\n effect(() => {\r\n const meta = this.pathSegments();\r\n const segments = this.propertyPathSegments();\r\n if (meta.length !== segments.length) return;\r\n\r\n let changed = false;\r\n const next = segments.map((segment, index) => {\r\n const normalized = meta[index]?.value ?? segment.value;\r\n if (segment.value !== normalized) {\r\n changed = true;\r\n return { ...segment, value: normalized };\r\n }\r\n return segment;\r\n });\r\n\r\n if (changed) {\r\n this.propertyPathSegments.set(next);\r\n }\r\n });\r\n\r\n // Ensure selected field exists in current options\r\n effect(() => {\r\n const options = this.propertyOptions();\r\n const current = this.propertyFieldKey();\r\n\r\n if (options.length === 0) {\r\n if (current) this.propertyFieldKey.set('');\r\n return;\r\n }\r\n\r\n if (current && !options.some((prop) => prop.key === current)) {\r\n this.propertyFieldKey.set('');\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.validatorService.reset();\r\n }\r\n\r\n // ===== ControlValueAccessor =====\r\n\r\n writeValue(value: FormulaBuilderValue | null): void {\r\n if (!value) {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n return;\r\n }\r\n\r\n const builder = Array.isArray(value.builder) ? value.builder : [];\r\n const expression = this.codeOnly()\r\n ? this.resolveExpressionValue(value.expression ?? '', builder)\r\n : (value.expression ?? '');\r\n this.expressionValue.set(expression);\r\n\r\n if (this.codeOnly()) {\r\n this.applyFormulaValue(builder, expression, true);\r\n return;\r\n }\r\n\r\n if (builder.length === 0) {\r\n this.applyFormulaValue(\r\n [],\r\n expression,\r\n expression.trim().length > 0,\r\n true,\r\n );\r\n return;\r\n }\r\n\r\n this.applyFormulaValue(builder, expression, false);\r\n }\r\n\r\n registerOnChange(fn: (value: FormulaBuilderValue) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.isDisabled.set(isDisabled);\r\n }\r\n\r\n /** Handle formula change from editor */\r\n onFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle formula change from code editor */\r\n onCodeFormulaChange(newFormula: string): void {\r\n this.expressionValue.set(newFormula);\r\n if (!newFormula.trim()) {\r\n this.clearBuilderTokens();\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.emitValueChange();\r\n return;\r\n }\r\n\r\n if (\r\n !this.isCodeModeLocked() &&\r\n newFormula !== this.codeModeSnapshotExpression\r\n ) {\r\n this.isCodeModeLocked.set(true);\r\n this.clearBuilderTokens();\r\n }\r\n this.emitValueChange();\r\n }\r\n\r\n /** Handle block insert from toolbar */\r\n onBlockInsert(block: SmartBlock): void {\r\n if (this.isCodeMode()) {\r\n const editor = this.codeEditor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n return;\r\n }\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.addBlock(block);\r\n }\r\n }\r\n\r\n /** Handle tokens change */\r\n onTokensChange(newTokens: FormulaToken[]): void {\r\n this.tokens.set(newTokens);\r\n const json = JSON.stringify(newTokens);\r\n this.lastBuilderJson = json;\r\n this.builderValue.set(newTokens);\r\n this.tokensChange.emit(newTokens);\r\n this.emitValueChange();\r\n }\r\n\r\n onEditorFocus(): void {\r\n this.hasFocus.set(true);\r\n }\r\n\r\n onEditorBlur(): void {\r\n this.hasFocus.set(false);\r\n this.onTouched();\r\n }\r\n\r\n private emitValueChange(): void {\r\n this.onChange({\r\n expression: this.expressionValue(),\r\n builder: this.builderValue(),\r\n });\r\n }\r\n\r\n onModeToggle(value: boolean): void {\r\n if (this.codeOnly()) {\r\n return;\r\n }\r\n const nextMode: 'builder' | 'code' = value ? 'code' : 'builder';\r\n this.setEditorMode(nextMode);\r\n }\r\n\r\n private setEditorMode(mode: 'builder' | 'code'): void {\r\n if (this.editorMode() === mode) return;\r\n\r\n if (mode === 'code') {\r\n this.enterCodeMode();\r\n return;\r\n }\r\n\r\n if (this.isCodeModeLocked()) {\r\n return;\r\n }\r\n\r\n this.exitCodeMode();\r\n }\r\n\r\n private enterCodeMode(): void {\r\n this.codeModeSnapshotTokens = this.tokens().slice();\r\n this.codeModeSnapshotExpression = this.expressionValue();\r\n const editor = this.editor();\r\n if (editor) {\r\n const formula = editor.serialize();\r\n this.codeModeSnapshotExpression = formula;\r\n this.expressionValue.set(formula);\r\n this.emitValueChange();\r\n }\r\n this.isCodeModeLocked.set(false);\r\n this.editorMode.set('code');\r\n }\r\n\r\n private exitCodeMode(): void {\r\n this.editorMode.set('builder');\r\n if (!this.expressionValue().trim()) {\r\n this.clearBuilderTokens();\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue([]);\r\n }\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n this.isCodeModeLocked.set(false);\r\n return;\r\n }\r\n\r\n if (this.codeModeSnapshotTokens.length > 0) {\r\n const restored = this.codeModeSnapshotTokens.slice();\r\n this.tokens.set(restored);\r\n this.builderValue.set(restored);\r\n this.lastBuilderJson = JSON.stringify(restored);\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(restored);\r\n }\r\n }\r\n if (this.codeModeSnapshotExpression) {\r\n this.expressionValue.set(this.codeModeSnapshotExpression);\r\n }\r\n this.isCodeModeLocked.set(false);\r\n }\r\n\r\n private clearBuilderTokens(): void {\r\n if (this.tokens().length === 0 && this.builderValue().length === 0) {\r\n return;\r\n }\r\n this.tokens.set([]);\r\n this.builderValue.set([]);\r\n this.lastBuilderJson = '';\r\n this.tokensChange.emit([]);\r\n }\r\n\r\n // ===== PUBLIC METHODS =====\r\n\r\n /** Clear the formula */\r\n clear(): void {\r\n this.expressionValue.set('');\r\n this.applyFormulaValue([], '', this.codeOnly());\r\n this.validatorService.reset();\r\n this.emitValueChange();\r\n }\r\n\r\n private resolveExpressionValue(\r\n expression: string,\r\n builder: FormulaToken[],\r\n ): string {\r\n if (expression.trim().length > 0) {\r\n return expression;\r\n }\r\n return builder.length > 0 ? serializeTokens(builder) : '';\r\n }\r\n\r\n private applyFormulaValue(\r\n builder: FormulaToken[],\r\n expression: string,\r\n useCodeMode: boolean,\r\n lockCodeMode: boolean = false,\r\n ): void {\r\n const serialized = JSON.stringify(builder);\r\n this.builderValue.set(builder);\r\n this.tokens.set(builder);\r\n this.lastBuilderJson = builder.length > 0 ? serialized : '';\r\n\r\n const editor = this.editor();\r\n if (editor) {\r\n editor.writeValue(builder);\r\n }\r\n\r\n const codeEditor = this.codeEditor();\r\n if (codeEditor) {\r\n codeEditor.writeValue(expression);\r\n }\r\n\r\n if (useCodeMode) {\r\n this.editorMode.set('code');\r\n this.isCodeModeLocked.set(lockCodeMode);\r\n this.codeModeSnapshotTokens = builder.slice();\r\n this.codeModeSnapshotExpression = expression;\r\n return;\r\n }\r\n\r\n this.editorMode.set('builder');\r\n this.isCodeModeLocked.set(false);\r\n this.codeModeSnapshotTokens = [];\r\n this.codeModeSnapshotExpression = '';\r\n }\r\n\r\n // ===== PROPERTY COMPOSER =====\r\n\r\n readonly propertyScope = signal<string>('');\r\n\r\n readonly propertyPathSegments = signal<PathSegment[]>([]);\r\n\r\n readonly propertyFieldKey = signal('');\r\n\r\n private readonly nextTokenRulesByPath = signal<\r\n Record<string, Record<string, NextTokenRule>>\r\n >({});\r\n\r\n readonly contextOperators = computed<OperatorDescriptor[]>(() => {\r\n return this.builderContext()?.schemaDescriptor?.operators ?? [];\r\n });\r\n\r\n readonly baseOperator = computed(() =>\r\n this.contextOperators().find((op) => op.token === this.propertyScope()),\r\n );\r\n\r\n readonly baseRule = computed(() => {\r\n const scope = this.propertyScope();\r\n return this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope];\r\n });\r\n\r\n readonly availableScopes = computed(() => {\n const operators = this.contextOperators();\n if (operators.length === 0) return [];\n const operatorsByToken = new Map(\n operators.map((operator) => [operator.token, operator]),\n );\n\n return PROPERTY_SCOPE_ORDER.map((token) => operatorsByToken.get(token))\n .filter((operator): operator is OperatorDescriptor => Boolean(operator))\n .map((operator) => ({\n key: operator.token,\n label: `@${operator.token}`,\n requiresParam: operator.requiresParameter ?? false,\n optional: !operator.requiresParameter,\n }));\n });\n\r\n /** Radio card options for scope selection */\r\n readonly scopeOptions = computed<RadioItem[]>(() =>\n this.availableScopes().map((scope) => ({\n id: scope.key,\n name: this.getOperatorDisplayName(scope.key),\n icon: SCOPE_ICON_MAP[scope.key] ?? DEFAULT_SCOPE_ICON,\n })),\n );\n\r\n /** Handle scope selection from radio cards */\r\n onScopeChange(item: RadioItem): void {\r\n this.setPropertyScope(String(item.id));\r\n }\r\n\r\n readonly pathSegments = computed<SegmentMeta[]>(() => {\r\n const scope = this.propertyScope();\r\n return resolveSegmentsMeta({\r\n scope,\r\n segments: this.propertyPathSegments(),\r\n operators: this.contextOperators(),\r\n baseRule: this.baseRule(),\r\n rulesByPath: this.nextTokenRulesByPath(),\r\n });\r\n });\r\n\r\n readonly isDirectAccess = computed(() => {\r\n const operator = this.baseOperator();\r\n const needsParameter =\r\n Boolean(operator?.parameterKind) || Boolean(operator?.requiresParameter);\r\n return !needsParameter && this.pathSegments().length === 0;\r\n });\r\n\r\n readonly propertyTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n false,\r\n ),\r\n );\r\n\r\n readonly resolvedTablePath = computed(() =>\r\n buildTablePath(\r\n this.propertyScope(),\r\n this.pathSegments(),\r\n this.baseOperator(),\r\n true,\r\n ),\r\n );\r\n\r\n readonly currentNextTokenRules = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return {};\r\n return this.nextTokenRulesByPath()[path] ?? {};\r\n });\r\n\r\n readonly nextOperatorOptions = computed(() => {\r\n const rules = this.currentNextTokenRules();\r\n const operators = this.contextOperators();\r\n return Object.keys(rules)\r\n .map((token) => {\r\n const rule = rules[token];\r\n const operator = operators.find((item) => item.token === token);\r\n const parameterKind =\r\n rule?.parameterKind ?? operator?.parameterKind ?? null;\r\n const requiresParameter =\r\n operator?.requiresParameter ?? Boolean(parameterKind);\r\n const allowedValues = getAllowedValues(rule);\r\n return {\r\n token,\r\n rule,\r\n requiresParameter,\r\n allowedValues,\r\n };\r\n })\r\n .filter(\r\n (option) =>\r\n option.allowedValues.length > 0 || !option.requiresParameter,\r\n );\r\n });\r\n\r\n readonly canAddNextSegment = computed(() => {\r\n if (this.nextOperatorOptions().length === 0) return false;\r\n const segments = this.pathSegments();\r\n if (segments.length === 0 || !segments[0].value) {\r\n return false;\r\n }\r\n return segments.every(\r\n (segment) => !segment.requiresParameter || Boolean(segment.value),\r\n );\r\n });\r\n\r\n readonly propertiesComponent = computed(() => {\r\n if (this.isProcessBuilder()) {\r\n return undefined;\r\n }\r\n const contextKey = this.builderContext()?.contextEntityTypeKey;\r\n return contextKey;\r\n });\r\n\r\n readonly mergedPropertiesByPath = computed<\r\n Record<string, FormulaPropertyDescriptor[]>\r\n >(() => {\r\n const merged: Record<string, FormulaPropertyDescriptor[]> = {\r\n ...this.propertiesByPath(),\r\n };\r\n const apiProps = this.propertiesByPathApi();\r\n Object.entries(apiProps).forEach(([path, props]) => {\r\n if (props && props.length > 0) {\r\n merged[path] = props;\r\n }\r\n });\r\n return merged;\r\n });\r\n\r\n readonly isPropertyLoading = computed(() => {\r\n const path = this.resolvedTablePath();\r\n return Boolean(path) && this.propertyLoadingPath() === path;\r\n });\r\n\r\n readonly propertyOptions = computed(() => {\r\n const path = this.resolvedTablePath();\r\n if (!path) return [];\r\n const byPath = this.mergedPropertiesByPath()[path];\r\n const list = byPath && byPath.length > 0 ? byPath : [];\r\n return list.map((prop) => ({\r\n key: prop.key,\r\n name: prop.name ?? prop.key,\r\n }));\r\n });\r\n\r\n readonly selectedProperty = computed(() => {\r\n const key = this.propertyFieldKey();\r\n return this.propertyOptions().find((prop) => prop.key === key) ?? null;\r\n });\r\n\r\n readonly canInsertProperty = computed(() => {\r\n if (!this.selectedProperty()) return false;\r\n return Boolean(this.resolvedTablePath());\r\n });\r\n\r\n setPropertyScope(scope: string): void {\r\n if (this.propertyScope() === scope) {\r\n return;\r\n }\r\n this.propertyScope.set(scope);\r\n this.propertyPathSegments.set(\r\n buildInitialSegments(\r\n scope,\r\n this.contextOperators().find((op) => op.token === scope),\r\n this.builderContext()?.schemaDescriptor?.nextTokenRules?.[scope],\r\n ),\r\n );\r\n this.propertyFieldKey.set('');\r\n }\r\n\r\n setPathSegmentValue(index: number, value: string | null): void {\r\n this.propertyPathSegments.update((segments) => {\r\n // Update the segment at the given index and remove all segments after it\r\n // because subsequent segments depend on previous values\r\n const updated = segments.slice(0, index + 1);\r\n updated[index] = { ...updated[index], value: value ?? '' };\r\n return updated;\r\n });\r\n }\r\n\r\n addNextSegment(operatorToken: string): void {\r\n const value = '';\r\n\r\n this.propertyPathSegments.update((segments) => [\r\n ...segments,\r\n { operatorToken, value },\r\n ]);\r\n }\r\n\r\n onAddSegmentSelection(\r\n operatorToken: string,\r\n popover: { hide: () => void },\r\n ): void {\r\n popover.hide();\r\n this.addNextSegment(operatorToken);\r\n }\r\n\r\n removePathSegment(index: number): void {\r\n this.propertyPathSegments.update((segments) =>\r\n segments.filter((_, i) => i !== index),\r\n );\r\n }\r\n\r\n segmentOptions(index: number): { key: string; name: string }[] {\n const segment = this.pathSegments()[index];\r\n if (!segment) return [];\r\n return segment.allowedValues.map((value) => ({\r\n key: value,\r\n name: value,\r\n }));\r\n }\r\n\r\n insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void {\n const prop = this.selectedProperty();\r\n if (!prop) return;\r\n\r\n if (!this.canInsertProperty()) return;\r\n\r\n const tablePath = this.resolvedTablePath();\r\n if (!tablePath) return;\r\n const display = prop.name ?? prop.key;\r\n const block = createPropertyBlock(\n `@${tablePath}::${prop.key}`,\n 'current',\n display,\n );\n insertBlock(block);\n }\n\n getOperatorDisplayName(token: string): string {\n if (token === 'Host' && this.isModuleContext()) {\n return 'Level';\n }\n\n return token;\n }\n}\n","<mt-card\r\n headless\r\n [class.ring-2]=\"hasFocus()\"\r\n [class.ring-primary]=\"hasFocus()\"\r\n [paddingless]=\"true\"\r\n>\r\n <div\r\n *transloco=\"let t; prefix: 'formulaBuilder'\"\r\n class=\"flex flex-col overflow-hidden\"\r\n >\r\n <!-- Toolbar - Pass data via inputs (pure component) -->\r\n @if (!hideToolbar()) {\r\n <mt-formula-toolbar\r\n [functionCategories]=\"functionCategories()\"\r\n [visibleTabs]=\"resolvedToolbarTabs()\"\r\n (onBlockInsert)=\"onBlockInsert($event)\"\r\n >\r\n <ng-template #properties let-insertBlock=\"insertBlock\">\r\n @if (isContextLoading()) {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <p-skeleton\r\n width=\"18rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <p-skeleton\r\n width=\"7rem\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div class=\"flex items-center gap-4\">\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <p-skeleton\r\n width=\"3rem\"\r\n height=\"1rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n </div>\r\n <p-skeleton height=\"2rem\" styleClass=\"rounded-md\" />\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4 p-4\">\r\n <!-- Scope Selection - Full width, centered -->\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-radio-cards\r\n [options]=\"scopeOptions()\"\r\n [activeId]=\"propertyScope()\"\r\n (selectionChange)=\"onScopeChange($event)\"\r\n size=\"small\"\r\n />\r\n </div>\r\n\r\n <!-- Path + Field + Preview Row -->\r\n <div class=\"flex items-center gap-4\">\r\n <!-- Path Container - Flexible -->\r\n <div\r\n class=\"flex min-h-11 min-w-0 flex-1 flex-col gap-2 rounded-lg bg-slate-50 px-3 py-2 dark:bg-slate-800/50\"\r\n >\r\n <div class=\"flex items-center gap-2\">\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.path\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n <div class=\"flex min-w-0 flex-1 items-center gap-2\">\r\n @if (isDirectAccess()) {\r\n <span\r\n class=\"rounded-md bg-emerald-100 px-2.5 py-1 text-xs font-medium text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\r\n >\r\n ✓ {{ t(\"properties.direct-access\") }}\r\n </span>\r\n } @else if (pathSegments().length === 0) {\r\n <span class=\"text-xs italic text-slate-400\">{{\r\n t(\"properties.no-path-configured\")\r\n }}</span>\r\n } @else {\r\n <div\r\n class=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-x-auto\"\r\n >\r\n @for (\r\n segment of pathSegments();\r\n track $index;\r\n let segmentIndex = $index\r\n ) {\r\n @if (segmentIndex > 0) {\r\n <span\r\n class=\"shrink-0 text-slate-300 dark:text-slate-600\"\r\n >›</span\r\n >\r\n }\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"\n segment.value ||\n t('properties.select') +\n ' ' +\n getOperatorDisplayName(segment.operatorToken)\n \"\n icon=\"arrow.chevron-down\"\r\n [outlined]=\"true\"\r\n size=\"small\"\r\n [severity]=\"\r\n segment.value ? 'primary' : 'secondary'\r\n \"\r\n [iconPos]=\"'end'\"\r\n (onClick)=\"pathPopover.toggle($event)\"\r\n ></mt-button>\r\n\r\n <p-popover\r\n #pathPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.select\") }}\n {{ getOperatorDisplayName(segment.operatorToken) }}\n </div>\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of segmentOptions(segmentIndex);\r\n track option.key\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"option.name\"\r\n [icon]=\"\r\n segment.value === option.key\r\n ? 'general.check'\r\n : 'general.minus'\r\n \"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n [styleClass]=\"\r\n 'w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors ' +\r\n (segment.value === option.key\r\n ? 'bg-primary text-white'\r\n : 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700')\r\n \"\r\n (onClick)=\"\r\n setPathSegmentValue(\r\n segmentIndex,\r\n option.key\r\n );\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n @if (segment.optional) {\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.clear')\"\r\n [outlined]=\"true\"\r\n icon=\"general.x-close\"\r\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"mt-2 w-full rounded-md border border-slate-200 py-1 text-xs text-slate-400 hover:bg-slate-50 dark:border-slate-700\"\r\n (onClick)=\"\r\n setPathSegmentValue(segmentIndex, null);\r\n pathPopover.hide()\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </p-popover>\r\n\r\n @if (\r\n segment.canRemove &&\r\n segmentIndex === pathSegments().length - 1\r\n ) {\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.x-close\"\r\n size=\"small\"\r\n severity=\"danger\"\r\n styleClass=\"flex size-5 shrink-0 items-center justify-center rounded-full bg-red-500 text-white hover:bg-red-600\"\r\n (onClick)=\"removePathSegment(segmentIndex)\"\r\n ></mt-button>\r\n }\r\n }\r\n <mt-button\r\n type=\"button\"\r\n icon=\"general.plus\"\r\n size=\"small\"\r\n severity=\"primary\"\r\n [disabled]=\"!canAddNextSegment()\"\r\n [class.hidden]=\"!canAddNextSegment()\"\r\n styleClass=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-primary text-xs font-bold text-white hover:opacity-90 disabled:opacity-50\"\r\n (onClick)=\"nextOperatorPopover.toggle($event)\"\r\n ></mt-button>\r\n </div>\r\n }\r\n <p-popover\r\n #nextOperatorPopover\r\n [style]=\"{ width: 'max-content' }\"\r\n appendTo=\"body\"\r\n >\r\n <div class=\"p-2\">\r\n <div\r\n class=\"mb-2 text-xs font-semibold uppercase text-slate-400\"\r\n >\r\n {{ t(\"properties.add-segment\") }}\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n @for (\r\n option of nextOperatorOptions();\r\n track option.token\r\n ) {\r\n <mt-button\n type=\"button\"\n [label]=\"getOperatorDisplayName(option.token)\"\n icon=\"general.plus\"\n [iconPos]=\"'end'\"\r\n size=\"small\"\r\n severity=\"secondary\"\r\n styleClass=\"w-full justify-start rounded-md px-2.5 py-1.5 text-left text-xs font-medium transition-colors text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-700\"\r\n (onClick)=\"\r\n onAddSegmentSelection(\r\n option.token,\r\n nextOperatorPopover\r\n )\r\n \"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </p-popover>\r\n </div>\r\n </div>\r\n\r\n <!-- Field Selection - Under Path -->\r\n <div\r\n class=\"flex items-center gap-2 border-t border-slate-200 pt-2 dark:border-slate-700\"\r\n >\r\n <span\r\n class=\"shrink-0 text-xs font-semibold uppercase tracking-wider text-slate-400\"\r\n >{{ t(\"properties.field\") }}</span\r\n >\r\n <div\r\n class=\"h-4 w-px shrink-0 bg-slate-200 dark:bg-slate-700\"\r\n ></div>\r\n @if (isPropertyLoading()) {\r\n <p-skeleton\r\n class=\"flex-1\"\r\n height=\"2.5rem\"\r\n styleClass=\"rounded-md\"\r\n />\r\n } @else {\r\n <mt-select-field\r\n class=\"flex-1\"\r\n [label]=\"''\"\r\n [filter]=\"true\"\r\n [hasPlaceholderPrefix]=\"false\"\r\n [placeholder]=\"t('properties.select')\"\r\n [(ngModel)]=\"propertyFieldKey\"\r\n [options]=\"propertyOptions()\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [size]=\"'small'\"\r\n />\r\n }\r\n </div>\r\n <div\r\n class=\"w-full truncate rounded-lg bg-amber-100 px-3 py-2 text-sm font-semibold text-amber-700 shadow-sm hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:hover:bg-amber-900/50\"\r\n [mtTooltip]=\"\r\n '@' +\r\n propertyTablePath() +\r\n '::' +\r\n (selectedProperty()?.key ?? '...')\r\n \"\r\n tooltipPosition=\"top\"\r\n >\r\n @{{ propertyTablePath() }}::{{\r\n selectedProperty()?.key ?? \"...\"\r\n }}\r\n </div>\r\n <div class=\"flex justify-end\">\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"t('actions.insert')\"\r\n icon=\"general.plus\"\r\n severity=\"primary\"\r\n [disabled]=\"!canInsertProperty()\"\r\n (onClick)=\"insertSelectedProperty(insertBlock)\"\r\n ></mt-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-formula-toolbar>\r\n }\r\n\r\n <!-- Editor Area -->\r\n <div class=\"p-3\">\r\n <div\r\n class=\"overflow-hidden rounded-lg border border-surface-200 bg-white dark:border-surface-700 dark:bg-surface-800\"\r\n >\r\n @if (showModeToggle()) {\r\n <div\r\n class=\"flex items-center justify-end border-b border-surface-200 px-3 py-2 dark:border-surface-700\"\r\n >\r\n <mt-toggle-field\r\n [label]=\"t('codeMode')\"\r\n labelPosition=\"end\"\r\n size=\"small\"\r\n [ngModel]=\"isCodeMode()\"\r\n [readonly]=\"isCodeModeLocked()\"\r\n [pInputs]=\"{ disabled: isCodeModeLocked() }\"\r\n (ngModelChange)=\"onModeToggle($event)\"\r\n />\r\n </div>\r\n }\r\n <div class=\"p-0\">\r\n @if (isCodeMode()) {\r\n <mt-formula-editor-code\r\n #formulaEditorCode\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialFormula]=\"expression()\"\r\n [borderless]=\"true\"\r\n [autocompleteProvider]=\"autocompleteProvider\"\r\n (formulaChange)=\"onCodeFormulaChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n } @else {\r\n <mt-formula-editor\r\n #formulaEditor\r\n [placeholder]=\"placeholder() || t('placeholder')\"\r\n [initialTokens]=\"tokens()\"\r\n [borderless]=\"true\"\r\n (formulaChange)=\"onFormulaChange($event)\"\r\n (tokensChange)=\"onTokensChange($event)\"\r\n (onFocus)=\"onEditorFocus()\"\r\n (onBlur)=\"onEditorBlur()\"\r\n />\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Bar - Pass data via inputs (pure component) -->\r\n @if (!hideStatusBar()) {\r\n <mt-formula-status-bar [validation]=\"validation()\" />\r\n }\r\n </div>\r\n</mt-card>\r\n","/**\r\n * Services barrel export\r\n */\r\n\r\nexport * from './formula-context.service';\r\nexport * from './formula-validator.service';\r\n","/**\r\n * Public API Surface of @masterteam/formula-builder\r\n *\r\n * This package provides the FormulaBuilder component which wraps\r\n * pure UI components from @masterteam/components/formula with\r\n * backend services for validation and context loading.\r\n *\r\n * Architecture:\r\n * - UI Components: imported from @masterteam/components/formula (pure, no services)\r\n * - Services: FormulaContextService, FormulaValidatorService (backend logic)\r\n * - FormulaBuilder: Main wrapper that connects UI with services\r\n */\r\n\r\n// Main component\r\nexport * from './lib/formula-builder';\r\n\r\n// Services (backend logic only)\r\nexport * from './lib/services/index';\r\n\r\n// Re-export models from base package for convenience\r\nexport {\r\n type SmartBlock,\r\n type BlockType,\r\n type ArgumentSlot,\r\n type FormulaToken,\r\n type TokenType,\r\n type DragBehavior,\r\n type ValidationResult,\r\n type ValidationError,\r\n type FunctionDefinition,\r\n type FunctionCategoryGroup,\r\n type OperatorDefinition,\r\n createFunctionBlock,\r\n createPropertyBlock,\r\n createOperatorBlock,\r\n createLiteralBlock,\r\n} from '@masterteam/components/formula';\r\n\r\n// Export validation-specific models\r\nexport type {\r\n ValidationRequest,\r\n FunctionCatalogResponse,\r\n ApiErrorResponse,\r\n} from './lib/models/validation-result.model';\r\n\r\n// Export value model for ControlValueAccessor usage\r\nexport type { FormulaBuilderValue } from './lib/models/formula-builder-value.model';\r\n\r\n// Export builder context models\r\nexport type {\r\n FormulaBuilderContextResponse,\r\n FormulaPropertyDescriptor,\r\n FormulaEngineSchemaDescriptor,\r\n OperatorDescriptor,\r\n NextTokenRule,\r\n} from './lib/models/formula-context.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masterteam/formula-builder",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"directory": "../../../dist/masterteam/formula-builder",
|
|
6
6
|
"linkDirectory": true,
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"rxjs": "^7.8.2",
|
|
20
20
|
"tailwindcss": "^4.1.17",
|
|
21
21
|
"tailwindcss-primeui": "^0.6.1",
|
|
22
|
-
"@masterteam/
|
|
23
|
-
"@masterteam/
|
|
22
|
+
"@masterteam/components": "^0.0.131",
|
|
23
|
+
"@masterteam/icons": "^0.0.14"
|
|
24
24
|
},
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"exports": {
|
|
@@ -4,14 +4,20 @@ import { OnDestroy } from '@angular/core';
|
|
|
4
4
|
import { ControlValueAccessor } from '@angular/forms';
|
|
5
5
|
import { RadioItem } from '@masterteam/components/radio-cards';
|
|
6
6
|
import { Observable } from 'rxjs';
|
|
7
|
-
import { FunctionCategoryGroup,
|
|
7
|
+
import { FunctionCategoryGroup, AutocompleteRequest as AutocompleteRequest$1, AutocompleteResponse as AutocompleteResponse$1, ValidationResult as ValidationResult$1, FormulaToken, ToolbarTab, SmartBlock } from '@masterteam/components/formula';
|
|
8
8
|
export { ArgumentSlot, BlockType, DragBehavior, FormulaToken, FunctionCategoryGroup, FunctionDefinition, OperatorDefinition, SmartBlock, TokenType, ValidationError, ValidationResult, createFunctionBlock, createLiteralBlock, createOperatorBlock, createPropertyBlock } from '@masterteam/components/formula';
|
|
9
9
|
|
|
10
|
+
type ValidationResult = ValidationResult$1;
|
|
11
|
+
type AutocompleteResponse = AutocompleteResponse$1;
|
|
12
|
+
interface AutocompleteRequest extends AutocompleteRequest$1 {
|
|
13
|
+
moduleId?: number;
|
|
14
|
+
}
|
|
10
15
|
/** Validation request payload (for API calls) */
|
|
11
16
|
interface ValidationRequest {
|
|
12
17
|
formula: string;
|
|
13
18
|
knownProperties?: string[];
|
|
14
19
|
levelSchemaId?: number;
|
|
20
|
+
moduleId?: number;
|
|
15
21
|
templateId?: number;
|
|
16
22
|
}
|
|
17
23
|
/** Function catalog response from API */
|
|
@@ -108,6 +114,8 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
|
|
|
108
114
|
}[]>>;
|
|
109
115
|
/** Level schema ID for validation context */
|
|
110
116
|
readonly levelSchemaId: _angular_core.InputSignal<number | undefined>;
|
|
117
|
+
/** Optional module ID when the formula is scoped inside a level-linked module */
|
|
118
|
+
readonly moduleId: _angular_core.InputSignal<number | undefined>;
|
|
111
119
|
/** Optional current context entity key, e.g. LevelData or Risk */
|
|
112
120
|
readonly contextEntityTypeKey: _angular_core.InputSignal<string | undefined>;
|
|
113
121
|
/** Template ID for validation context */
|
|
@@ -125,7 +133,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
|
|
|
125
133
|
/** Use Process Builder current-only Formula Engine endpoints */
|
|
126
134
|
readonly isProcessBuilder: _angular_core.InputSignal<boolean>;
|
|
127
135
|
/** Emits validation result on change */
|
|
128
|
-
readonly validationChange: _angular_core.OutputEmitterRef<ValidationResult>;
|
|
136
|
+
readonly validationChange: _angular_core.OutputEmitterRef<_masterteam_formula_builder.ValidationResult>;
|
|
129
137
|
/** Emits when tokens change */
|
|
130
138
|
readonly tokensChange: _angular_core.OutputEmitterRef<FormulaToken[]>;
|
|
131
139
|
/** Editor focus state */
|
|
@@ -137,6 +145,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
|
|
|
137
145
|
readonly tokens: _angular_core.WritableSignal<FormulaToken[]>;
|
|
138
146
|
readonly expression: _angular_core.Signal<string>;
|
|
139
147
|
readonly resolvedContextEntityTypeKey: _angular_core.Signal<string | undefined>;
|
|
148
|
+
readonly isModuleContext: _angular_core.Signal<boolean>;
|
|
140
149
|
readonly autocompleteProvider: (request: AutocompleteRequest) => Observable<AutocompleteResponse | null>;
|
|
141
150
|
/** Track last synced builder JSON to avoid loops */
|
|
142
151
|
private lastBuilderJson;
|
|
@@ -155,7 +164,7 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
|
|
|
155
164
|
/** Disabled state */
|
|
156
165
|
private readonly isDisabled;
|
|
157
166
|
/** Validation result from service */
|
|
158
|
-
readonly validation: _angular_core.Signal<ValidationResult>;
|
|
167
|
+
readonly validation: _angular_core.Signal<_masterteam_formula_builder.ValidationResult>;
|
|
159
168
|
/** Is validation in progress */
|
|
160
169
|
readonly isValidating: _angular_core.Signal<boolean>;
|
|
161
170
|
/** Builder context from API */
|
|
@@ -248,8 +257,9 @@ declare class FormulaBuilder implements ControlValueAccessor, OnDestroy {
|
|
|
248
257
|
name: string;
|
|
249
258
|
}[];
|
|
250
259
|
insertSelectedProperty(insertBlock: (block: SmartBlock) => void): void;
|
|
260
|
+
getOperatorDisplayName(token: string): string;
|
|
251
261
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormulaBuilder, never>;
|
|
252
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormulaBuilder, "mt-formula-builder", never, { "propertiesByPath": { "alias": "propertiesByPath"; "required": false; "isSignal": true; }; "levelSchemaId": { "alias": "levelSchemaId"; "required": false; "isSignal": true; }; "contextEntityTypeKey": { "alias": "contextEntityTypeKey"; "required": false; "isSignal": true; }; "templateId": { "alias": "templateId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideToolbar": { "alias": "hideToolbar"; "required": false; "isSignal": true; }; "hideStatusBar": { "alias": "hideStatusBar"; "required": false; "isSignal": true; }; "toolbarTabs": { "alias": "toolbarTabs"; "required": false; "isSignal": true; }; "codeOnly": { "alias": "codeOnly"; "required": false; "isSignal": true; }; "isProcessBuilder": { "alias": "isProcessBuilder"; "required": false; "isSignal": true; }; }, { "validationChange": "validationChange"; "tokensChange": "tokensChange"; }, never, never, true, never>;
|
|
262
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FormulaBuilder, "mt-formula-builder", never, { "propertiesByPath": { "alias": "propertiesByPath"; "required": false; "isSignal": true; }; "levelSchemaId": { "alias": "levelSchemaId"; "required": false; "isSignal": true; }; "moduleId": { "alias": "moduleId"; "required": false; "isSignal": true; }; "contextEntityTypeKey": { "alias": "contextEntityTypeKey"; "required": false; "isSignal": true; }; "templateId": { "alias": "templateId"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hideToolbar": { "alias": "hideToolbar"; "required": false; "isSignal": true; }; "hideStatusBar": { "alias": "hideStatusBar"; "required": false; "isSignal": true; }; "toolbarTabs": { "alias": "toolbarTabs"; "required": false; "isSignal": true; }; "codeOnly": { "alias": "codeOnly"; "required": false; "isSignal": true; }; "isProcessBuilder": { "alias": "isProcessBuilder"; "required": false; "isSignal": true; }; }, { "validationChange": "validationChange"; "tokensChange": "tokensChange"; }, never, never, true, never>;
|
|
253
263
|
}
|
|
254
264
|
|
|
255
265
|
type FormulaApiMode$1 = 'default' | 'current-only';
|
|
@@ -261,9 +271,9 @@ declare class FormulaContextService {
|
|
|
261
271
|
private readonly contextCache;
|
|
262
272
|
private readonly propertiesCache;
|
|
263
273
|
private readonly nextTokensCache;
|
|
264
|
-
loadContext(schemaId: number, contextEntityTypeKey?: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderContextResponse | null>;
|
|
265
|
-
getScopeProperties(schemaId: number, component: string, tablePath: string, mode?: FormulaApiMode$1): Observable<FormulaPropertyDescriptor[]>;
|
|
266
|
-
getNextTokens(schemaId: number, component: string, tablePath: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderNextTokensResponse | null>;
|
|
274
|
+
loadContext(schemaId: number, moduleId?: number, contextEntityTypeKey?: string, mode?: FormulaApiMode$1): Observable<FormulaBuilderContextResponse | null>;
|
|
275
|
+
getScopeProperties(schemaId: number, component: string, tablePath: string, moduleId?: number, mode?: FormulaApiMode$1): Observable<FormulaPropertyDescriptor[]>;
|
|
276
|
+
getNextTokens(schemaId: number, component: string, tablePath: string, moduleId?: number, mode?: FormulaApiMode$1): Observable<FormulaBuilderNextTokensResponse | null>;
|
|
267
277
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FormulaContextService, never>;
|
|
268
278
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FormulaContextService>;
|
|
269
279
|
}
|
|
@@ -283,15 +293,15 @@ declare class FormulaValidatorService {
|
|
|
283
293
|
private readonly validateSubject;
|
|
284
294
|
private unwrapResponse;
|
|
285
295
|
/** Public signals */
|
|
286
|
-
readonly validation: _angular_core.Signal<ValidationResult>;
|
|
296
|
+
readonly validation: _angular_core.Signal<_masterteam_formula_builder.ValidationResult>;
|
|
287
297
|
readonly isValidating: _angular_core.Signal<boolean>;
|
|
288
298
|
constructor();
|
|
289
299
|
/** Setup debounced validation stream */
|
|
290
300
|
private setupValidationStream;
|
|
291
301
|
/** Validate formula (debounced) */
|
|
292
|
-
validate(formula: string, knownProperties?: string[], levelSchemaId?: number, templateId?: number, apiMode?: FormulaApiMode): void;
|
|
302
|
+
validate(formula: string, knownProperties?: string[], levelSchemaId?: number, moduleId?: number, templateId?: number, apiMode?: FormulaApiMode): void;
|
|
293
303
|
/** Validate formula immediately (no debounce) */
|
|
294
|
-
validateImmediate(formula: string, knownProperties?: string[], levelSchemaId?: number, templateId?: number, apiMode?: FormulaApiMode): Observable<ValidationResult>;
|
|
304
|
+
validateImmediate(formula: string, knownProperties?: string[], levelSchemaId?: number, moduleId?: number, templateId?: number, apiMode?: FormulaApiMode): Observable<ValidationResult>;
|
|
295
305
|
/** Call validation API */
|
|
296
306
|
private callValidateApi;
|
|
297
307
|
/** Reset validation state */
|