@memberjunction/core-entities 5.39.0 → 5.40.1
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.
- package/dist/custom/MJQueryEntityExtended.d.ts +18 -4
- package/dist/custom/MJQueryEntityExtended.d.ts.map +1 -1
- package/dist/custom/MJQueryEntityExtended.js +62 -5
- package/dist/custom/MJQueryEntityExtended.js.map +1 -1
- package/dist/engines/ApplicationSettingEngine.d.ts +195 -0
- package/dist/engines/ApplicationSettingEngine.d.ts.map +1 -0
- package/dist/engines/ApplicationSettingEngine.js +407 -0
- package/dist/engines/ApplicationSettingEngine.js.map +1 -0
- package/dist/generated/entity_subclasses.d.ts +2608 -153
- package/dist/generated/entity_subclasses.d.ts.map +1 -1
- package/dist/generated/entity_subclasses.js +10736 -7204
- package/dist/generated/entity_subclasses.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -42,11 +42,25 @@ export declare class MJQueryEntityExtended extends MJQueryEntity {
|
|
|
42
42
|
*/
|
|
43
43
|
UserHasRunPermissions(user: UserInfo): boolean;
|
|
44
44
|
/**
|
|
45
|
-
* Checks
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* Checks whether a user can run this query, considering query-level permissions,
|
|
46
|
+
* entity-level read permissions, and composition dependencies (recursive).
|
|
47
|
+
*
|
|
48
|
+
* Permission logic:
|
|
49
|
+
* 1. Check query-level run permissions (role-based)
|
|
50
|
+
* 2. If the query has explicit Query Permissions, those take precedence for this
|
|
51
|
+
* query AND its composition dependencies (stored-procedure semantics)
|
|
52
|
+
* 3. If no explicit Query Permissions, check entity read permissions for all
|
|
53
|
+
* referenced entities via the Query Entities bridge
|
|
54
|
+
* 4. Recursively check all composition dependencies ({{query:"..."}})
|
|
55
|
+
*
|
|
56
|
+
* @param user The user to check permissions for
|
|
57
|
+
* @param _visited Internal — tracks visited query IDs to prevent infinite loops in cyclic dependencies
|
|
58
|
+
* @returns Object with canRun boolean and list of denied entity names
|
|
48
59
|
*/
|
|
49
|
-
UserCanRun(user: UserInfo):
|
|
60
|
+
UserCanRun(user: UserInfo, _visited?: Set<string>): {
|
|
61
|
+
canRun: boolean;
|
|
62
|
+
deniedEntities: string[];
|
|
63
|
+
};
|
|
50
64
|
/** Whether this query has been formally approved for production use */
|
|
51
65
|
get IsApproved(): boolean;
|
|
52
66
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJQueryEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"MJQueryEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAEjG,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACxB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;;;;;GAOG;AACH,qBACa,qBAAsB,SAAQ,aAAa;IAIpD,2CAA2C;IAC3C,IAAW,WAAW,IAAI,kBAAkB,EAAE,CAE7C;IAED,+CAA+C;IAC/C,IAAW,eAAe,IAAI,sBAAsB,EAAE,CAErD;IAED,6CAA6C;IAC7C,IAAW,aAAa,IAAI,mBAAmB,EAAE,CAEhD;IAED,4CAA4C;IAC5C,IAAW,gBAAgB,IAAI,uBAAuB,EAAE,CAEvD;IAED,oGAAoG;IACpG,IAAW,iBAAiB,IAAI,uBAAuB,EAAE,CAExD;IAED,+EAA+E;IAC/E,IAAW,eAAe,IAAI,uBAAuB,EAAE,CAEtD;IAID,6EAA6E;IAC7E,IAAW,cAAc,IAAI,qBAAqB,GAAG,SAAS,CAG7D;IAED,OAAO,CAAC,aAAa,CAAuB;IAE5C;;;OAGG;IACH,IAAW,YAAY,IAAI,MAAM,CAKhC;IAED;;OAEG;IACI,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAmBpD;;;;;OAKG;IACI,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO;IAkBrD;;;;;;;;;;;;;;;OAeG;IACI,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE;IAyDxG,uEAAuE;IACvE,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED;;;OAGG;IACH,IAAW,YAAY,IAAI,OAAO,CAEjC;IAID;;;;;OAKG;IACI,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM;IAgBzD,OAAO,CAAC,YAAY,CAAiC;IAErD;;;;OAIG;IACH,IAAW,WAAW,IAAI,gBAAgB,CAuBzC;IAED,OAAO,CAAC,uBAAuB;CAqBlC"}
|
|
@@ -105,12 +105,69 @@ let MJQueryEntityExtended = class MJQueryEntityExtended extends MJQueryEntity {
|
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
|
-
* Checks
|
|
109
|
-
*
|
|
110
|
-
*
|
|
108
|
+
* Checks whether a user can run this query, considering query-level permissions,
|
|
109
|
+
* entity-level read permissions, and composition dependencies (recursive).
|
|
110
|
+
*
|
|
111
|
+
* Permission logic:
|
|
112
|
+
* 1. Check query-level run permissions (role-based)
|
|
113
|
+
* 2. If the query has explicit Query Permissions, those take precedence for this
|
|
114
|
+
* query AND its composition dependencies (stored-procedure semantics)
|
|
115
|
+
* 3. If no explicit Query Permissions, check entity read permissions for all
|
|
116
|
+
* referenced entities via the Query Entities bridge
|
|
117
|
+
* 4. Recursively check all composition dependencies ({{query:"..."}})
|
|
118
|
+
*
|
|
119
|
+
* @param user The user to check permissions for
|
|
120
|
+
* @param _visited Internal — tracks visited query IDs to prevent infinite loops in cyclic dependencies
|
|
121
|
+
* @returns Object with canRun boolean and list of denied entity names
|
|
111
122
|
*/
|
|
112
|
-
UserCanRun(user) {
|
|
113
|
-
|
|
123
|
+
UserCanRun(user, _visited) {
|
|
124
|
+
// Cycle guard
|
|
125
|
+
const visited = _visited ?? new Set();
|
|
126
|
+
if (visited.has(this.ID)) {
|
|
127
|
+
return { canRun: true, deniedEntities: [] };
|
|
128
|
+
}
|
|
129
|
+
visited.add(this.ID);
|
|
130
|
+
// Step 1: Check query-level run permissions
|
|
131
|
+
if (!this.UserHasRunPermissions(user)) {
|
|
132
|
+
return { canRun: false, deniedEntities: [] };
|
|
133
|
+
}
|
|
134
|
+
// Step 2: Explicit Query Permissions override entity checks for this query
|
|
135
|
+
// and all its dependencies (stored-procedure semantics)
|
|
136
|
+
const permissions = this.QueryPermissions;
|
|
137
|
+
if (permissions && permissions.length > 0) {
|
|
138
|
+
return { canRun: true, deniedEntities: [] };
|
|
139
|
+
}
|
|
140
|
+
// Step 3: No explicit permissions — check entity read access
|
|
141
|
+
const deniedEntities = [];
|
|
142
|
+
const queryEntities = this.QueryEntities;
|
|
143
|
+
if (queryEntities && queryEntities.length > 0) {
|
|
144
|
+
const md = this.ProviderToUse;
|
|
145
|
+
for (const qe of queryEntities) {
|
|
146
|
+
const entityInfo = md.EntityByID(qe.EntityID);
|
|
147
|
+
if (!entityInfo)
|
|
148
|
+
continue; // Stale reference — skip
|
|
149
|
+
const perms = entityInfo.GetUserPermisions(user);
|
|
150
|
+
if (!perms || !perms.CanRead) {
|
|
151
|
+
deniedEntities.push(entityInfo.Name);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Step 4: Recursively check composition dependencies
|
|
156
|
+
const dependencies = this.QueryDependencies;
|
|
157
|
+
if (dependencies && dependencies.length > 0) {
|
|
158
|
+
const allQueries = QueryEngine.Instance.Queries;
|
|
159
|
+
for (const dep of dependencies) {
|
|
160
|
+
const depQuery = allQueries.find(q => UUIDsEqual(q.ID, dep.DependsOnQueryID));
|
|
161
|
+
if (!depQuery)
|
|
162
|
+
continue; // Dependency not found — skip
|
|
163
|
+
const depResult = depQuery.UserCanRun(user, visited);
|
|
164
|
+
if (!depResult.canRun) {
|
|
165
|
+
return { canRun: false, deniedEntities: [...deniedEntities, ...depResult.deniedEntities] };
|
|
166
|
+
}
|
|
167
|
+
deniedEntities.push(...depResult.deniedEntities);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { canRun: deniedEntities.length === 0, deniedEntities };
|
|
114
171
|
}
|
|
115
172
|
// ─── Status Checks ──────────────────────────────────────────────────────────
|
|
116
173
|
/** Whether this query has been formally approved for production use */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJQueryEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJQueryEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"MJQueryEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJQueryEntityExtended.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { BaseEngine, IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { MJApplicationSettingEntity } from '../generated/entity_subclasses.js';
|
|
4
|
+
/**
|
|
5
|
+
* ApplicationSettingEngine is a singleton engine that provides centralized, cached access to
|
|
6
|
+
* application configuration settings stored in the `MJ: Application Settings` entity
|
|
7
|
+
* (table `ApplicationSetting`).
|
|
8
|
+
*
|
|
9
|
+
* Each setting row has an optional `ApplicationID`:
|
|
10
|
+
* - **NULL** → a GLOBAL setting that applies across all applications.
|
|
11
|
+
* - **non-NULL** → a setting scoped to that single application.
|
|
12
|
+
*
|
|
13
|
+
* **Resolution semantics**: when reading a setting for a given application, an app-scoped row
|
|
14
|
+
* (matching applicationId + name) takes precedence over the GLOBAL row (ApplicationID NULL) of
|
|
15
|
+
* the same name. If neither exists, the read returns `undefined`.
|
|
16
|
+
*
|
|
17
|
+
* This engine mirrors {@link UserInfoEngine}: it loads all setting rows into an in-memory cache
|
|
18
|
+
* via a BaseEnginePropertyConfig (which auto-subscribes to BaseEntity events for reactivity),
|
|
19
|
+
* exposes a reactive observable, and supports debounced writes with read-after-write semantics.
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const engine = ApplicationSettingEngine.Instance;
|
|
24
|
+
* await engine.Config(false, contextUser);
|
|
25
|
+
*
|
|
26
|
+
* // Read a setting (app-scoped first, then GLOBAL fallback)
|
|
27
|
+
* const raw = engine.GetSetting('feature.flag', applicationId);
|
|
28
|
+
*
|
|
29
|
+
* // Write a GLOBAL setting
|
|
30
|
+
* await engine.SetSetting('feature.flag', 'true');
|
|
31
|
+
*
|
|
32
|
+
* // Write an app-scoped setting
|
|
33
|
+
* await engine.SetSetting('feature.flag', 'false', applicationId);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class ApplicationSettingEngine extends BaseEngine<ApplicationSettingEngine> {
|
|
37
|
+
/**
|
|
38
|
+
* Returns the global instance of the class. This is a singleton class, so there is only one
|
|
39
|
+
* instance of it in the application. Do not directly create new instances of it, always use
|
|
40
|
+
* this method to get the instance.
|
|
41
|
+
*/
|
|
42
|
+
static get Instance(): ApplicationSettingEngine;
|
|
43
|
+
private _ApplicationSettings;
|
|
44
|
+
/**
|
|
45
|
+
* Debounce time in milliseconds for SetSettingDebounced calls.
|
|
46
|
+
* Default is 500ms. Change via the SettingsDebounceMs setter.
|
|
47
|
+
*/
|
|
48
|
+
private _settingsDebounceMs;
|
|
49
|
+
/**
|
|
50
|
+
* Map of pending setting updates keyed by `${applicationId}::${name}`.
|
|
51
|
+
* These are queued and flushed after the debounce period of inactivity.
|
|
52
|
+
*/
|
|
53
|
+
private _pendingSettings;
|
|
54
|
+
/**
|
|
55
|
+
* Timer handle for the debounce flush.
|
|
56
|
+
*/
|
|
57
|
+
private _settingsDebounceTimer;
|
|
58
|
+
/**
|
|
59
|
+
* Promise that resolves when the current flush operation completes.
|
|
60
|
+
* Used to prevent concurrent flush operations.
|
|
61
|
+
*/
|
|
62
|
+
private _flushPromise;
|
|
63
|
+
/**
|
|
64
|
+
* Configures the engine by loading all application settings from the database into the
|
|
65
|
+
* in-memory cache. Application settings are global reference data (not per-user), so all rows
|
|
66
|
+
* are loaded regardless of provider type.
|
|
67
|
+
*
|
|
68
|
+
* @param forceRefresh - If true, forces a refresh from the server even if data is cached
|
|
69
|
+
* @param contextUser - The user context (required for server-side)
|
|
70
|
+
* @param provider - Optional custom metadata provider
|
|
71
|
+
*/
|
|
72
|
+
Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Observable stream of the application settings cache array. Emits the current array on
|
|
75
|
+
* subscribe and re-emits whenever the cache is mutated (save, delete, remote-invalidate,
|
|
76
|
+
* refresh).
|
|
77
|
+
*/
|
|
78
|
+
get ApplicationSettings$(): Observable<MJApplicationSettingEntity[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Get all application settings in the cache (global + app-scoped, unfiltered).
|
|
81
|
+
*/
|
|
82
|
+
get ApplicationSettings(): MJApplicationSettingEntity[];
|
|
83
|
+
/**
|
|
84
|
+
* Get all settings for a specific application, OR all GLOBAL settings when no applicationId
|
|
85
|
+
* is supplied.
|
|
86
|
+
*
|
|
87
|
+
* @param applicationId - The application ID to filter by; omit/undefined for GLOBAL settings
|
|
88
|
+
* @returns The matching settings (does NOT merge global fallbacks into the app-scoped list)
|
|
89
|
+
*/
|
|
90
|
+
GetAllForApplication(applicationId?: string): MJApplicationSettingEntity[];
|
|
91
|
+
/**
|
|
92
|
+
* Get an application setting value by name with scope resolution.
|
|
93
|
+
*
|
|
94
|
+
* **Resolution**: if `applicationId` is given and an app-scoped row exists for
|
|
95
|
+
* (applicationId, name), its value is returned. Otherwise the GLOBAL row (ApplicationID NULL)
|
|
96
|
+
* for that name is used as a fallback. Returns `undefined` if neither exists.
|
|
97
|
+
*
|
|
98
|
+
* **Read-after-write semantics**: this consults the in-memory pending-debounced-writes map
|
|
99
|
+
* FIRST (app-scoped pending takes precedence over global pending, mirroring the persisted
|
|
100
|
+
* resolution order). Without that, a `SetSettingDebounced` followed immediately by
|
|
101
|
+
* `GetSetting` would return the old DB-cached value because the debounce timer hasn't fired
|
|
102
|
+
* yet and the entity hasn't been saved.
|
|
103
|
+
*
|
|
104
|
+
* @param name - The setting name to find
|
|
105
|
+
* @param applicationId - Optional application scope; when given, app-scoped overrides global
|
|
106
|
+
* @returns The setting value string, or undefined if not found
|
|
107
|
+
*/
|
|
108
|
+
GetSetting(name: string, applicationId?: string): string | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* Get an application setting entity by name with the same scope resolution as
|
|
111
|
+
* {@link GetSetting} (app-scoped first, then GLOBAL fallback). Does NOT consult pending
|
|
112
|
+
* debounced writes — returns the persisted entity instance.
|
|
113
|
+
*
|
|
114
|
+
* @param name - The setting name to find
|
|
115
|
+
* @param applicationId - Optional application scope
|
|
116
|
+
* @returns The MJApplicationSettingEntity, or undefined if not found
|
|
117
|
+
*/
|
|
118
|
+
GetSettingEntity(name: string, applicationId?: string): MJApplicationSettingEntity | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Internal: find the cache row that exactly matches (name, scope) WITHOUT fallback.
|
|
121
|
+
* A null/undefined applicationId matches only GLOBAL rows; a non-null applicationId matches
|
|
122
|
+
* only the app-scoped row for that application.
|
|
123
|
+
*/
|
|
124
|
+
private findEntity;
|
|
125
|
+
/**
|
|
126
|
+
* Set an application setting by name. Creates a new setting if one doesn't exist for the
|
|
127
|
+
* exact (name, scope) pair; updates it otherwise. When `applicationId` is omitted the setting
|
|
128
|
+
* is written as a GLOBAL setting (ApplicationID NULL).
|
|
129
|
+
*
|
|
130
|
+
* @param name - The setting name
|
|
131
|
+
* @param value - The setting value (string, typically JSON for complex data)
|
|
132
|
+
* @param applicationId - Optional application scope; omit for a GLOBAL setting
|
|
133
|
+
* @param contextUser - Optional user context for server-side use
|
|
134
|
+
* @returns true if successful, false otherwise
|
|
135
|
+
*/
|
|
136
|
+
SetSetting(name: string, value: string, applicationId?: string, contextUser?: UserInfo): Promise<boolean>;
|
|
137
|
+
/**
|
|
138
|
+
* Delete an application setting by name and scope.
|
|
139
|
+
*
|
|
140
|
+
* @param name - The setting name to delete
|
|
141
|
+
* @param applicationId - Optional application scope; omit to delete the GLOBAL setting
|
|
142
|
+
* @returns true if successful (or setting didn't exist), false on error
|
|
143
|
+
*/
|
|
144
|
+
DeleteSetting(name: string, applicationId?: string): Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* Get the current debounce time in milliseconds for SetSettingDebounced calls.
|
|
147
|
+
*/
|
|
148
|
+
get SettingsDebounceMs(): number;
|
|
149
|
+
/**
|
|
150
|
+
* Set the debounce time in milliseconds for SetSettingDebounced calls.
|
|
151
|
+
* When changed, any pending settings are flushed first before the new debounce time takes effect.
|
|
152
|
+
* @param value - The debounce time in milliseconds (minimum 100ms, maximum 10000ms)
|
|
153
|
+
*/
|
|
154
|
+
set SettingsDebounceMs(value: number);
|
|
155
|
+
/**
|
|
156
|
+
* Queue a setting update with debouncing. Multiple calls within the debounce period for the
|
|
157
|
+
* same (name, scope) pair are batched together, with only the last value being saved. The
|
|
158
|
+
* actual database save occurs after the debounce period of inactivity.
|
|
159
|
+
*
|
|
160
|
+
* This is the preferred method for UI components that may update settings frequently.
|
|
161
|
+
*
|
|
162
|
+
* @param name - The setting name
|
|
163
|
+
* @param value - The setting value (string, typically JSON for complex data)
|
|
164
|
+
* @param applicationId - Optional application scope; omit for a GLOBAL setting
|
|
165
|
+
* @param contextUser - Optional user context for server-side use
|
|
166
|
+
*/
|
|
167
|
+
SetSettingDebounced(name: string, value: string, applicationId?: string, contextUser?: UserInfo): void;
|
|
168
|
+
/**
|
|
169
|
+
* Immediately flush all pending debounced settings to the database.
|
|
170
|
+
* Call this when you need to ensure settings are saved (e.g., before navigation).
|
|
171
|
+
* Safe to call multiple times - concurrent calls will wait for the current flush to complete.
|
|
172
|
+
*
|
|
173
|
+
* @returns Promise that resolves when all pending settings have been saved
|
|
174
|
+
*/
|
|
175
|
+
FlushPendingSettings(): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Internal method to perform the actual flush of settings.
|
|
178
|
+
* @param settingsToSave - Map of settings to save
|
|
179
|
+
*/
|
|
180
|
+
private doFlushSettings;
|
|
181
|
+
/**
|
|
182
|
+
* Check if there are any pending debounced settings waiting to be saved.
|
|
183
|
+
*/
|
|
184
|
+
get HasPendingSettings(): boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Get the number of pending debounced settings.
|
|
187
|
+
*/
|
|
188
|
+
get PendingSettingsCount(): number;
|
|
189
|
+
/**
|
|
190
|
+
* Force refresh all application setting data.
|
|
191
|
+
* @param contextUser - Optional user context for server-side use
|
|
192
|
+
*/
|
|
193
|
+
Refresh(contextUser?: UserInfo): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=ApplicationSettingEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApplicationSettingEngine.d.ts","sourceRoot":"","sources":["../../src/engines/ApplicationSettingEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,iBAAiB,EAEjB,QAAQ,EACT,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAW5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBACa,wBAAyB,SAAQ,UAAU,CAAC,wBAAwB,CAAC;IAChF;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,wBAAwB,CAErD;IAGD,OAAO,CAAC,oBAAoB,CAAoC;IAMhE;;;OAGG;IACH,OAAO,CAAC,mBAAmB,CAAe;IAE1C;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAGV;IAEd;;OAEG;IACH,OAAO,CAAC,sBAAsB,CAA8C;IAE5E;;;OAGG;IACH,OAAO,CAAC,aAAa,CAA8B;IAEnD;;;;;;;;OAQG;IACU,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhH;;;;OAIG;IACH,IAAW,oBAAoB,IAAI,UAAU,CAAC,0BAA0B,EAAE,CAAC,CAE1E;IAMD;;OAEG;IACH,IAAW,mBAAmB,IAAI,0BAA0B,EAAE,CAE7D;IAED;;;;;;OAMG;IACI,oBAAoB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAOjF;;;;;;;;;;;;;;;;OAgBG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAsB3E;;;;;;;;OAQG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAQrG;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAUlB;;;;;;;;;;OAUG;IACU,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAkCtH;;;;;;OAMG;IACU,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BlF;;OAEG;IACH,IAAW,kBAAkB,IAAI,MAAM,CAEtC;IAED;;;;OAIG;IACH,IAAW,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAM1C;IAED;;;;;;;;;;;OAWG;IACI,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI;IAkB7G;;;;;;OAMG;IACU,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BlD;;;OAGG;YACW,eAAe;IAiB7B;;OAEG;IACH,IAAW,kBAAkB,IAAI,OAAO,CAEvC;IAED;;OAEG;IACH,IAAW,oBAAoB,IAAI,MAAM,CAExC;IAMD;;;OAGG;IACU,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAG5D"}
|