@ifc-lite/create 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/cost-authoring-rules.d.ts +70 -0
- package/dist/cost-authoring-rules.d.ts.map +1 -0
- package/dist/cost-authoring-rules.js +118 -0
- package/dist/cost-authoring-rules.js.map +1 -0
- package/dist/ifc-creator-cost.d.ts +3 -14
- package/dist/ifc-creator-cost.d.ts.map +1 -1
- package/dist/ifc-creator-cost.js +4 -62
- package/dist/ifc-creator-cost.js.map +1 -1
- package/dist/in-store/cost-nesting-cycle.d.ts +8 -0
- package/dist/in-store/cost-nesting-cycle.d.ts.map +1 -0
- package/dist/in-store/cost-nesting-cycle.js +28 -0
- package/dist/in-store/cost-nesting-cycle.js.map +1 -0
- package/dist/in-store/cost-reference-validation.d.ts +13 -0
- package/dist/in-store/cost-reference-validation.d.ts.map +1 -0
- package/dist/in-store/cost-reference-validation.js +49 -0
- package/dist/in-store/cost-reference-validation.js.map +1 -0
- package/dist/in-store/cost-removal.d.ts +40 -0
- package/dist/in-store/cost-removal.d.ts.map +1 -0
- package/dist/in-store/cost-removal.js +107 -0
- package/dist/in-store/cost-removal.js.map +1 -0
- package/dist/in-store/cost.d.ts +109 -0
- package/dist/in-store/cost.d.ts.map +1 -0
- package/dist/in-store/cost.js +323 -0
- package/dist/in-store/cost.js.map +1 -0
- package/dist/in-store/resolve-source.d.ts.map +1 -1
- package/dist/in-store/resolve-source.js +11 -8
- package/dist/in-store/resolve-source.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types-cost.d.ts +2 -2
- package/dist/types-cost.d.ts.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { assertCostSchema } from '../cost-authoring-rules.js';
|
|
5
|
+
import { requireEntityTypeOneOf, requireMatchingCostSchema } from './cost-reference-validation.js';
|
|
6
|
+
const REMOVABLE_COST_ENTITY_TYPES = new Set(['IFCCOSTSCHEDULE', 'IFCCOSTITEM', 'IFCCOSTVALUE']);
|
|
7
|
+
/**
|
|
8
|
+
* Safe-delete an `IfcCostSchedule` / `IfcCostItem` / `IfcCostValue`, refusing
|
|
9
|
+
* live value references unless `detach` explicitly requests their rewrite.
|
|
10
|
+
*/
|
|
11
|
+
export function removeCostEntityInStore(editor, anchor, expressId, referrers, options = {}) {
|
|
12
|
+
assertCostSchema(requireMatchingCostSchema(editor, anchor.schema), 'removeCostEntity');
|
|
13
|
+
requireEntityTypeOneOf(editor, expressId, REMOVABLE_COST_ENTITY_TYPES, 'expressId', 'removeCostEntity');
|
|
14
|
+
const blockers = [];
|
|
15
|
+
for (const [itemId, values] of referrers.itemCostValues ?? []) {
|
|
16
|
+
if (values.includes(expressId))
|
|
17
|
+
blockers.push(`IfcCostItem #${itemId}.CostValues`);
|
|
18
|
+
}
|
|
19
|
+
for (const [valueId, components] of referrers.valueComponents ?? []) {
|
|
20
|
+
if (components.includes(expressId))
|
|
21
|
+
blockers.push(`IfcCostValue #${valueId}.Components`);
|
|
22
|
+
}
|
|
23
|
+
for (const [valueId, ref] of referrers.valueAppliedValueRef ?? []) {
|
|
24
|
+
if (ref === expressId)
|
|
25
|
+
blockers.push(`IfcCostValue #${valueId}.AppliedValue (AppliedValueRef)`);
|
|
26
|
+
}
|
|
27
|
+
for (const ref of referrers.otherRelationshipLists ?? []) {
|
|
28
|
+
if (ref.relatedIds.includes(expressId))
|
|
29
|
+
blockers.push(`relationship #${ref.relId}`);
|
|
30
|
+
}
|
|
31
|
+
for (const relId of referrers.otherRelationships ?? [])
|
|
32
|
+
blockers.push(`relationship #${relId}`);
|
|
33
|
+
for (const ref of referrers.optionalScalarReferrers ?? []) {
|
|
34
|
+
blockers.push(`entity #${ref.entityId} attribute ${ref.attributeIndex}`);
|
|
35
|
+
}
|
|
36
|
+
for (const ref of referrers.optionalListReferrers ?? []) {
|
|
37
|
+
if (ref.referencedIds.includes(expressId)) {
|
|
38
|
+
blockers.push(`entity #${ref.entityId} attribute ${ref.attributeIndex}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (blockers.length > 0 && !options.detach) {
|
|
42
|
+
throw new Error(`removeCostEntity: #${expressId} is still referenced by ${blockers.join(', ')}. `
|
|
43
|
+
+ 'Pass { detach: true } to rewrite those lists first.');
|
|
44
|
+
}
|
|
45
|
+
if (blockers.length > 0) {
|
|
46
|
+
for (const [itemId, values] of referrers.itemCostValues ?? []) {
|
|
47
|
+
if (!values.includes(expressId))
|
|
48
|
+
continue;
|
|
49
|
+
const remaining = values.filter(id => id !== expressId);
|
|
50
|
+
editor.setPositionalAttribute(itemId, 7, remaining.length === 0 ? null : remaining.map(id => `#${id}`));
|
|
51
|
+
}
|
|
52
|
+
for (const [valueId, components] of referrers.valueComponents ?? []) {
|
|
53
|
+
if (!components.includes(expressId))
|
|
54
|
+
continue;
|
|
55
|
+
const remaining = components.filter(id => id !== expressId);
|
|
56
|
+
editor.setPositionalAttribute(valueId, 9, remaining.length === 0 ? null : remaining.map(id => `#${id}`));
|
|
57
|
+
}
|
|
58
|
+
for (const [valueId, ref] of referrers.valueAppliedValueRef ?? []) {
|
|
59
|
+
if (ref === expressId)
|
|
60
|
+
editor.setPositionalAttribute(valueId, 2, null);
|
|
61
|
+
}
|
|
62
|
+
for (const ref of referrers.otherRelationshipLists ?? []) {
|
|
63
|
+
if (!ref.relatedIds.includes(expressId))
|
|
64
|
+
continue;
|
|
65
|
+
const remaining = ref.relatedIds.filter(id => id !== expressId);
|
|
66
|
+
if (remaining.length === 0)
|
|
67
|
+
editor.removeEntity(ref.relId);
|
|
68
|
+
else
|
|
69
|
+
editor.setPositionalAttribute(ref.relId, ref.attributeIndex, remaining.map(id => `#${id}`));
|
|
70
|
+
}
|
|
71
|
+
for (const relId of referrers.otherRelationships ?? [])
|
|
72
|
+
editor.removeEntity(relId);
|
|
73
|
+
for (const ref of referrers.optionalScalarReferrers ?? []) {
|
|
74
|
+
editor.setPositionalAttribute(ref.entityId, ref.attributeIndex, null);
|
|
75
|
+
}
|
|
76
|
+
for (const ref of referrers.optionalListReferrers ?? []) {
|
|
77
|
+
if (!ref.referencedIds.includes(expressId))
|
|
78
|
+
continue;
|
|
79
|
+
const remaining = ref.referencedIds.filter(id => id !== expressId);
|
|
80
|
+
editor.setPositionalAttribute(ref.entityId, ref.attributeIndex, remaining.length === 0 ? null : remaining.map(id => `#${id}`));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const [relId, related] of referrers.nestRelatedObjects ?? []) {
|
|
84
|
+
if (!related.includes(expressId))
|
|
85
|
+
continue;
|
|
86
|
+
const remaining = related.filter(id => id !== expressId);
|
|
87
|
+
if (remaining.length === 0)
|
|
88
|
+
editor.removeEntity(relId);
|
|
89
|
+
else
|
|
90
|
+
editor.setPositionalAttribute(relId, 5, remaining.map(id => `#${id}`));
|
|
91
|
+
}
|
|
92
|
+
for (const [relId, related] of referrers.assignmentRelatedObjects ?? []) {
|
|
93
|
+
if (!related.includes(expressId))
|
|
94
|
+
continue;
|
|
95
|
+
const remaining = related.filter(id => id !== expressId);
|
|
96
|
+
if (remaining.length === 0)
|
|
97
|
+
editor.removeEntity(relId);
|
|
98
|
+
else
|
|
99
|
+
editor.setPositionalAttribute(relId, 4, remaining.map(id => `#${id}`));
|
|
100
|
+
}
|
|
101
|
+
for (const relId of referrers.nestsAsParent ?? [])
|
|
102
|
+
editor.removeEntity(relId);
|
|
103
|
+
for (const relId of referrers.assignmentsAsControl ?? [])
|
|
104
|
+
editor.removeEntity(relId);
|
|
105
|
+
editor.removeEntity(expressId);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=cost-removal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-removal.js","sourceRoot":"","sources":["../../src/in-store/cost-removal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loaded-model cost authoring (#4857 PR A) — `bim.store.addCost*` / `nestCostItems`
|
|
3
|
+
* / `assignCostItemsToSchedule` / `assignToCostItem` / `setCostItemValues` /
|
|
4
|
+
* `removeCostEntity`. The counterpart of `ifc-creator-cost.ts` for a model
|
|
5
|
+
* that is already parsed and loaded rather than being built from scratch:
|
|
6
|
+
* same validation (`cost-authoring-rules.ts`, shared so a value illegal from
|
|
7
|
+
* one entry point is illegal from the other), different serialization —
|
|
8
|
+
* `StoreEditor.addEntity` takes a typed attribute array, not raw STEP text.
|
|
9
|
+
*
|
|
10
|
+
* Pure: no I/O, no parser access, no read of the store's OWN existing graph.
|
|
11
|
+
* `nestCostItemsInStore` (reparenting) and `removeCostEntityInStore`
|
|
12
|
+
* (safe-delete / cascade) both need to know what ALREADY references an
|
|
13
|
+
* entity, which only a graph READ can answer — the caller resolves referrers
|
|
14
|
+
* first and hands them in. The editor is the only mutable thing touched.
|
|
15
|
+
*/
|
|
16
|
+
import { type RandomSource } from '@ifc-lite/encoding';
|
|
17
|
+
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
18
|
+
import { type CostSchema } from '../cost-authoring-rules.js';
|
|
19
|
+
import type { CostItemParams, CostQuantityParams, CostScheduleParams, CostValueParams } from '../types-cost.js';
|
|
20
|
+
/** What `nestCostItemsInStore` / `assign*InStore` / `removeCostEntityInStore` need to
|
|
21
|
+
* reparent or detach cleanly — the model's owner history and target schema. */
|
|
22
|
+
export interface CostAnchor {
|
|
23
|
+
/** IfcOwnerHistory expressId, or null when the model has none (written as `$`). */
|
|
24
|
+
ownerHistoryId: number | null;
|
|
25
|
+
/** Target schema; IFC2X3 is refused (see `assertCostSchema`). */
|
|
26
|
+
schema: CostSchema;
|
|
27
|
+
/** Optional seeded randomness for authored GlobalIds — see `SpatialAnchor.guidRandom`. */
|
|
28
|
+
guidRandom?: RandomSource;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Emit an `IfcCostSchedule` into the loaded model's overlay.
|
|
32
|
+
*
|
|
33
|
+
* [0] GlobalId, [1] OwnerHistory, [2] Name, [3] Description, [4] ObjectType,
|
|
34
|
+
* [5] Identification, [6] PredefinedType, [7] Status, [8] SubmittedOn,
|
|
35
|
+
* [9] UpdateDate — same IFC4 layout `emitCostSchedule` writes; refused for
|
|
36
|
+
* IFC2X3 (different layout, see `assertCostSchema`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function addCostScheduleToStore(editor: StoreEditor, anchor: CostAnchor, params: CostScheduleParams): number;
|
|
39
|
+
/**
|
|
40
|
+
* Emit an `IfcCostItem`. [0] GlobalId, [1] OwnerHistory, [2] Name,
|
|
41
|
+
* [3] Description, [4] ObjectType, [5] Identification, [6] PredefinedType,
|
|
42
|
+
* [7] CostValues, [8] CostQuantities — an empty `CostValues`/`CostQuantities`
|
|
43
|
+
* array is refused (EXPRESS `[1:?]`); use `attachCostValuesToItemInStore` to
|
|
44
|
+
* attach them after the fact instead.
|
|
45
|
+
*/
|
|
46
|
+
export declare function addCostItemToStore(editor: StoreEditor, anchor: CostAnchor, params: CostItemParams): number;
|
|
47
|
+
/**
|
|
48
|
+
* Emit an `IfcCostValue`. [0] Name, [1] Description, [2] AppliedValue,
|
|
49
|
+
* [3] UnitBasis, [4] ApplicableDate, [5] FixedUntilDate, [6] Category,
|
|
50
|
+
* [7] Condition, [8] ArithmeticOperator, [9] Components.
|
|
51
|
+
*
|
|
52
|
+
* `AppliedValue` and `AppliedValueRef` are the two branches of one SELECT —
|
|
53
|
+
* at most one may be given (mirrors `emitCostValue`).
|
|
54
|
+
*/
|
|
55
|
+
export declare function addCostValueToStore(editor: StoreEditor, anchor: CostAnchor, params: CostValueParams): number;
|
|
56
|
+
/**
|
|
57
|
+
* Emit an `IfcPhysicalSimpleQuantity` (the same subtypes `emitPhysicalQuantity`
|
|
58
|
+
* writes), for `IfcCostItem.CostQuantities`. [0] Name, [1] Description,
|
|
59
|
+
* [2] Unit, [3] `<Kind>Value`, [4] Formula.
|
|
60
|
+
*/
|
|
61
|
+
export declare function addCostQuantityToStore(editor: StoreEditor, anchor: CostAnchor, params: CostQuantityParams): number;
|
|
62
|
+
/** One relationship the caller already found referencing an id, so the builders below
|
|
63
|
+
* never need to scan the store themselves — see the module header. */
|
|
64
|
+
export interface ExistingRelatedList {
|
|
65
|
+
relId: number;
|
|
66
|
+
/** The relationship's RelatingObject, when the caller is supplying a nesting graph. */
|
|
67
|
+
relatingId?: number;
|
|
68
|
+
/** The relationship's current RelatedObjects (or Components), in file order. */
|
|
69
|
+
relatedIds: readonly number[];
|
|
70
|
+
/**
|
|
71
|
+
* When a controller legally has MORE THAN ONE relationship of this kind
|
|
72
|
+
* (e.g. two separate `IfcRelAssignsToControl` records for the same
|
|
73
|
+
* schedule), every member across ALL of them — used only to decide which
|
|
74
|
+
* requested ids are genuinely new, never as the list written back. Writing
|
|
75
|
+
* this union into `relId`'s own slot would copy a secondary relationship's
|
|
76
|
+
* members into the primary one, duplicating membership while leaving the
|
|
77
|
+
* secondary relationship untouched. Defaults to `relatedIds` when absent
|
|
78
|
+
* (the single-relationship case, where the two are the same set).
|
|
79
|
+
*/
|
|
80
|
+
allMemberIds?: readonly number[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Nest `childIds` under `parentId` as `IfcRelNests.RelatedObjects` (slot 5),
|
|
84
|
+
* `RelatingObject` = parent.
|
|
85
|
+
*
|
|
86
|
+
* A child already nested under one or more DIFFERENT `IfcRelNests` is
|
|
87
|
+
* reparented: it is removed from EVERY one of those rels' `RelatedObjects`
|
|
88
|
+
* first (a file may legally list a child under more than one nest —
|
|
89
|
+
* `MULTIPLE_NESTING_PARENTS` is a diagnostic, not a refusal — so detaching
|
|
90
|
+
* from only the first one found would leave it still nested under the rest),
|
|
91
|
+
* tombstoning a rel if that empties it (`RelatedObjects` is `[1:?]`, so an
|
|
92
|
+
* emptied list cannot be left as `()`), then added to (or its own new) the
|
|
93
|
+
* target rel.
|
|
94
|
+
*/
|
|
95
|
+
export declare function nestCostItemsInStore(editor: StoreEditor, anchor: CostAnchor, parentId: number, childIds: number[], existingNestByChild: ReadonlyMap<number, readonly ExistingRelatedList[]>, existingTargetNest?: ExistingRelatedList): number;
|
|
96
|
+
/** Assign `itemIds` (IfcCostItem) to `scheduleId` (IfcCostSchedule) as its controlled objects. */
|
|
97
|
+
export declare function assignCostItemsToScheduleInStore(editor: StoreEditor, anchor: CostAnchor, scheduleId: number, itemIds: number[], existingAssignment?: ExistingRelatedList): number;
|
|
98
|
+
/**
|
|
99
|
+
* Assign IFC objects (products, tasks, resources, etc.) to a cost item.
|
|
100
|
+
* The controlling item itself is not a legal related member.
|
|
101
|
+
*/
|
|
102
|
+
export declare function assignObjectsToCostItemInStore(editor: StoreEditor, anchor: CostAnchor, costItemId: number, objectIds: number[], existingAssignment?: ExistingRelatedList): number;
|
|
103
|
+
/**
|
|
104
|
+
* Set (replace) `itemId`'s `IfcCostItem.CostValues` (slot 7). `valueIds` is
|
|
105
|
+
* REQUIRED, not optional: an empty array is how a caller CLEARS the list,
|
|
106
|
+
* written as `$` — never `()`, which `[1:?]` forbids.
|
|
107
|
+
*/
|
|
108
|
+
export declare function attachCostValuesToItemInStore(editor: StoreEditor, anchor: CostAnchor, itemId: number, valueIds: readonly number[]): void;
|
|
109
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/in-store/cost.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAM1E,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,EACxE,MAAM,kBAAkB,CAAC;AAG1B;gFACgF;AAChF,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,MAAM,EAAE,UAAU,CAAC;IACnB,0FAA0F;IAC1F,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAeD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAmBlH;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CA0B1G;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,GAAG,MAAM,CAiC5G;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA6BlH;AAED;uEACuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC,EACxE,kBAAkB,CAAC,EAAE,mBAAmB,GACvC,MAAM,CA6CR;AA4DD,kGAAkG;AAClG,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAC9E,kBAAkB,CAAC,EAAE,mBAAmB,GACvC,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAChF,kBAAkB,CAAC,EAAE,mBAAmB,GACvC,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,IAAI,CAcN"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Loaded-model cost authoring (#4857 PR A) — `bim.store.addCost*` / `nestCostItems`
|
|
6
|
+
* / `assignCostItemsToSchedule` / `assignToCostItem` / `setCostItemValues` /
|
|
7
|
+
* `removeCostEntity`. The counterpart of `ifc-creator-cost.ts` for a model
|
|
8
|
+
* that is already parsed and loaded rather than being built from scratch:
|
|
9
|
+
* same validation (`cost-authoring-rules.ts`, shared so a value illegal from
|
|
10
|
+
* one entry point is illegal from the other), different serialization —
|
|
11
|
+
* `StoreEditor.addEntity` takes a typed attribute array, not raw STEP text.
|
|
12
|
+
*
|
|
13
|
+
* Pure: no I/O, no parser access, no read of the store's OWN existing graph.
|
|
14
|
+
* `nestCostItemsInStore` (reparenting) and `removeCostEntityInStore`
|
|
15
|
+
* (safe-delete / cascade) both need to know what ALREADY references an
|
|
16
|
+
* entity, which only a graph READ can answer — the caller resolves referrers
|
|
17
|
+
* first and hands them in. The editor is the only mutable thing touched.
|
|
18
|
+
*/
|
|
19
|
+
import { generateIfcGuid } from '@ifc-lite/encoding';
|
|
20
|
+
import { ownerHistoryRef } from './_emit-helpers.js';
|
|
21
|
+
import { requireAssignableIfcObjectDefinition, requireEntitySubtype, requireEntityType, requireEntityTypeOneOf, requireMatchingCostSchema, } from './cost-reference-validation.js';
|
|
22
|
+
import { COST_ITEM_TYPES, COST_SCHEDULE_TYPES, QUANTITY_KINDS, assertCostSchema, assertOneOf, requireRef, validateArithmeticOperator, validateRefList, validateTypedValue, } from '../cost-authoring-rules.js';
|
|
23
|
+
import { assertNoNestingCycle } from './cost-nesting-cycle.js';
|
|
24
|
+
/** `IfcCostValue.Components` / `IfcAppliedValueSelect`'s entity branches: another cost/applied value. */
|
|
25
|
+
const APPLIED_VALUE_ENTITY_TYPES = new Set(['IFCCOSTVALUE', 'IFCAPPLIEDVALUE']);
|
|
26
|
+
/** The entity branches of IFC4/IFC4X3 IfcAppliedValueSelect. */
|
|
27
|
+
const APPLIED_VALUE_REF_TYPES = new Set(['IFCMEASUREWITHUNIT', 'IFCREFERENCE']);
|
|
28
|
+
function typedAttrValue(value, schema, context) {
|
|
29
|
+
validateTypedValue(value, schema, context);
|
|
30
|
+
return { typed: { type: value.Type, value: value.Value } };
|
|
31
|
+
}
|
|
32
|
+
function refListAttr(ids) {
|
|
33
|
+
return ids === undefined ? null : ids.map(id => `#${id}`);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Emit an `IfcCostSchedule` into the loaded model's overlay.
|
|
37
|
+
*
|
|
38
|
+
* [0] GlobalId, [1] OwnerHistory, [2] Name, [3] Description, [4] ObjectType,
|
|
39
|
+
* [5] Identification, [6] PredefinedType, [7] Status, [8] SubmittedOn,
|
|
40
|
+
* [9] UpdateDate — same IFC4 layout `emitCostSchedule` writes; refused for
|
|
41
|
+
* IFC2X3 (different layout, see `assertCostSchema`).
|
|
42
|
+
*/
|
|
43
|
+
export function addCostScheduleToStore(editor, anchor, params) {
|
|
44
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
45
|
+
assertCostSchema(schema, 'addCostSchedule');
|
|
46
|
+
if (typeof params.Name !== 'string' || params.Name.length === 0) {
|
|
47
|
+
throw new Error('addCostSchedule: Name is required');
|
|
48
|
+
}
|
|
49
|
+
assertOneOf(params.PredefinedType, COST_SCHEDULE_TYPES, 'PredefinedType', 'addCostSchedule');
|
|
50
|
+
return editor.addEntity('IfcCostSchedule', [
|
|
51
|
+
generateIfcGuid(anchor.guidRandom),
|
|
52
|
+
ownerHistoryRef(anchor.ownerHistoryId),
|
|
53
|
+
params.Name,
|
|
54
|
+
params.Description ?? null,
|
|
55
|
+
params.ObjectType ?? null,
|
|
56
|
+
params.Identification ?? null,
|
|
57
|
+
params.PredefinedType ? `.${params.PredefinedType}.` : null,
|
|
58
|
+
params.Status ?? null,
|
|
59
|
+
params.SubmittedOn ?? null,
|
|
60
|
+
params.UpdateDate ?? null,
|
|
61
|
+
]).expressId;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Emit an `IfcCostItem`. [0] GlobalId, [1] OwnerHistory, [2] Name,
|
|
65
|
+
* [3] Description, [4] ObjectType, [5] Identification, [6] PredefinedType,
|
|
66
|
+
* [7] CostValues, [8] CostQuantities — an empty `CostValues`/`CostQuantities`
|
|
67
|
+
* array is refused (EXPRESS `[1:?]`); use `attachCostValuesToItemInStore` to
|
|
68
|
+
* attach them after the fact instead.
|
|
69
|
+
*/
|
|
70
|
+
export function addCostItemToStore(editor, anchor, params) {
|
|
71
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
72
|
+
const costValues = params.CostValues === undefined ? undefined : [...new Set(params.CostValues)];
|
|
73
|
+
const costQuantities = params.CostQuantities === undefined ? undefined : [...new Set(params.CostQuantities)];
|
|
74
|
+
assertCostSchema(schema, 'addCostItem');
|
|
75
|
+
if (typeof params.Name !== 'string' || params.Name.length === 0) {
|
|
76
|
+
throw new Error('addCostItem: Name is required');
|
|
77
|
+
}
|
|
78
|
+
assertOneOf(params.PredefinedType, COST_ITEM_TYPES, 'PredefinedType', 'addCostItem');
|
|
79
|
+
validateRefList(costValues, 'CostValues', 'addCostItem');
|
|
80
|
+
validateRefList(costQuantities, 'CostQuantities', 'addCostItem');
|
|
81
|
+
for (const id of costValues ?? [])
|
|
82
|
+
requireEntityType(editor, id, 'IfcCostValue', 'CostValues', 'addCostItem');
|
|
83
|
+
for (const id of costQuantities ?? []) {
|
|
84
|
+
requireEntitySubtype(editor, id, 'IfcPhysicalQuantity', 'CostQuantities', 'addCostItem');
|
|
85
|
+
}
|
|
86
|
+
return editor.addEntity('IfcCostItem', [
|
|
87
|
+
generateIfcGuid(anchor.guidRandom),
|
|
88
|
+
ownerHistoryRef(anchor.ownerHistoryId),
|
|
89
|
+
params.Name,
|
|
90
|
+
params.Description ?? null,
|
|
91
|
+
params.ObjectType ?? null,
|
|
92
|
+
params.Identification ?? null,
|
|
93
|
+
params.PredefinedType ? `.${params.PredefinedType}.` : null,
|
|
94
|
+
refListAttr(costValues),
|
|
95
|
+
refListAttr(costQuantities),
|
|
96
|
+
]).expressId;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Emit an `IfcCostValue`. [0] Name, [1] Description, [2] AppliedValue,
|
|
100
|
+
* [3] UnitBasis, [4] ApplicableDate, [5] FixedUntilDate, [6] Category,
|
|
101
|
+
* [7] Condition, [8] ArithmeticOperator, [9] Components.
|
|
102
|
+
*
|
|
103
|
+
* `AppliedValue` and `AppliedValueRef` are the two branches of one SELECT —
|
|
104
|
+
* at most one may be given (mirrors `emitCostValue`).
|
|
105
|
+
*/
|
|
106
|
+
export function addCostValueToStore(editor, anchor, params) {
|
|
107
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
108
|
+
assertCostSchema(schema, 'addCostValue');
|
|
109
|
+
if (params.AppliedValue !== undefined && params.AppliedValueRef !== undefined) {
|
|
110
|
+
throw new Error('addCostValue: AppliedValue and AppliedValueRef are the two branches of one SELECT — give at most one');
|
|
111
|
+
}
|
|
112
|
+
validateArithmeticOperator(params.ArithmeticOperator, schema, 'addCostValue');
|
|
113
|
+
let applied = null;
|
|
114
|
+
if (params.AppliedValue !== undefined) {
|
|
115
|
+
applied = typedAttrValue(params.AppliedValue, schema, 'addCostValue');
|
|
116
|
+
}
|
|
117
|
+
else if (params.AppliedValueRef !== undefined) {
|
|
118
|
+
requireRef(params.AppliedValueRef, 'AppliedValueRef', 'addCostValue');
|
|
119
|
+
requireEntityTypeOneOf(editor, params.AppliedValueRef, APPLIED_VALUE_REF_TYPES, 'AppliedValueRef', 'addCostValue');
|
|
120
|
+
applied = `#${params.AppliedValueRef}`;
|
|
121
|
+
}
|
|
122
|
+
if (params.UnitBasis !== undefined) {
|
|
123
|
+
requireRef(params.UnitBasis, 'UnitBasis', 'addCostValue');
|
|
124
|
+
requireEntityType(editor, params.UnitBasis, 'IfcMeasureWithUnit', 'UnitBasis', 'addCostValue');
|
|
125
|
+
}
|
|
126
|
+
validateRefList(params.Components, 'Components', 'addCostValue');
|
|
127
|
+
for (const id of params.Components ?? [])
|
|
128
|
+
requireEntityTypeOneOf(editor, id, APPLIED_VALUE_ENTITY_TYPES, 'Components', 'addCostValue');
|
|
129
|
+
return editor.addEntity('IfcCostValue', [
|
|
130
|
+
params.Name ?? null,
|
|
131
|
+
params.Description ?? null,
|
|
132
|
+
applied,
|
|
133
|
+
params.UnitBasis === undefined ? null : `#${params.UnitBasis}`,
|
|
134
|
+
params.ApplicableDate ?? null,
|
|
135
|
+
params.FixedUntilDate ?? null,
|
|
136
|
+
params.Category ?? null,
|
|
137
|
+
params.Condition ?? null,
|
|
138
|
+
params.ArithmeticOperator ? `.${params.ArithmeticOperator}.` : null,
|
|
139
|
+
refListAttr(params.Components),
|
|
140
|
+
]).expressId;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Emit an `IfcPhysicalSimpleQuantity` (the same subtypes `emitPhysicalQuantity`
|
|
144
|
+
* writes), for `IfcCostItem.CostQuantities`. [0] Name, [1] Description,
|
|
145
|
+
* [2] Unit, [3] `<Kind>Value`, [4] Formula.
|
|
146
|
+
*/
|
|
147
|
+
export function addCostQuantityToStore(editor, anchor, params) {
|
|
148
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
149
|
+
assertCostSchema(schema, 'addCostQuantity');
|
|
150
|
+
if (typeof params.Name !== 'string' || params.Name.length === 0) {
|
|
151
|
+
throw new Error('addCostQuantity: Name is required');
|
|
152
|
+
}
|
|
153
|
+
assertOneOf(params.Kind, QUANTITY_KINDS, 'Kind', 'addCostQuantity');
|
|
154
|
+
if (!Number.isFinite(params.Value))
|
|
155
|
+
throw new Error(`addCostQuantity: ${params.Kind} value must be a finite number`);
|
|
156
|
+
if (params.Kind === 'IfcQuantityNumber' && schema !== 'IFC4X3') {
|
|
157
|
+
throw new Error(`addCostQuantity: ${params.Kind} does not exist in ${schema}; requires Schema "IFC4X3"`);
|
|
158
|
+
}
|
|
159
|
+
if (params.Kind !== 'IfcQuantityNumber' && params.Value < 0) {
|
|
160
|
+
throw new Error(`addCostQuantity: ${params.Kind} value must be non-negative, got ${params.Value}`);
|
|
161
|
+
}
|
|
162
|
+
if (params.Unit !== undefined) {
|
|
163
|
+
requireRef(params.Unit, 'Unit', 'addCostQuantity');
|
|
164
|
+
requireEntitySubtype(editor, params.Unit, 'IfcNamedUnit', 'Unit', 'addCostQuantity');
|
|
165
|
+
}
|
|
166
|
+
const isInteger = params.Kind === 'IfcQuantityCount' && schema === 'IFC4X3';
|
|
167
|
+
if (isInteger && !Number.isInteger(params.Value)) {
|
|
168
|
+
throw new Error(`addCostQuantity: ${params.Kind} value must be a finite integer in IFC4X3`);
|
|
169
|
+
}
|
|
170
|
+
return editor.addEntity(params.Kind, [
|
|
171
|
+
params.Name,
|
|
172
|
+
params.Description ?? null,
|
|
173
|
+
params.Unit === undefined ? null : `#${params.Unit}`,
|
|
174
|
+
isInteger ? params.Value : { real: params.Value },
|
|
175
|
+
params.Formula ?? null,
|
|
176
|
+
]).expressId;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Nest `childIds` under `parentId` as `IfcRelNests.RelatedObjects` (slot 5),
|
|
180
|
+
* `RelatingObject` = parent.
|
|
181
|
+
*
|
|
182
|
+
* A child already nested under one or more DIFFERENT `IfcRelNests` is
|
|
183
|
+
* reparented: it is removed from EVERY one of those rels' `RelatedObjects`
|
|
184
|
+
* first (a file may legally list a child under more than one nest —
|
|
185
|
+
* `MULTIPLE_NESTING_PARENTS` is a diagnostic, not a refusal — so detaching
|
|
186
|
+
* from only the first one found would leave it still nested under the rest),
|
|
187
|
+
* tombstoning a rel if that empties it (`RelatedObjects` is `[1:?]`, so an
|
|
188
|
+
* emptied list cannot be left as `()`), then added to (or its own new) the
|
|
189
|
+
* target rel.
|
|
190
|
+
*/
|
|
191
|
+
export function nestCostItemsInStore(editor, anchor, parentId, childIds, existingNestByChild, existingTargetNest) {
|
|
192
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
193
|
+
assertCostSchema(schema, 'nestCostItems');
|
|
194
|
+
validateRefList(childIds, 'childIds', 'nestCostItems');
|
|
195
|
+
requireRef(parentId, 'parentId', 'nestCostItems');
|
|
196
|
+
if (childIds.includes(parentId)) {
|
|
197
|
+
throw new Error(`nestCostItems: parentId #${parentId} cannot also be one of childIds (an item cannot nest itself)`);
|
|
198
|
+
}
|
|
199
|
+
requireEntityType(editor, parentId, 'IfcCostItem', 'parentId', 'nestCostItems');
|
|
200
|
+
// De-duplicated once: every use below (the reparent scan, the merge, the
|
|
201
|
+
// freshly-created rel's own RelatedObjects) reads from this, not childIds
|
|
202
|
+
// — a repeated id in the caller's list must not write a repeated #N into a
|
|
203
|
+
// list IFC readers count members of.
|
|
204
|
+
const uniqueChildIds = [...new Set(childIds)];
|
|
205
|
+
for (const childId of uniqueChildIds)
|
|
206
|
+
requireEntityType(editor, childId, 'IfcCostItem', 'childId', 'nestCostItems');
|
|
207
|
+
// The SDK supplies relatingId so the helper can reject indirect cycles.
|
|
208
|
+
assertNoNestingCycle(parentId, uniqueChildIds, existingNestByChild);
|
|
209
|
+
// Detach every child of THIS call from every old rel it is a member of, one
|
|
210
|
+
// rewrite per (rel, not per (rel, child)): two children reparented out of
|
|
211
|
+
// the same old IfcRelNests in one call must both leave it, and re-filtering
|
|
212
|
+
// the ORIGINAL (unchanged) relatedIds on each iteration would make the
|
|
213
|
+
// second child's rewrite silently undo the first child's removal.
|
|
214
|
+
const detachedRelIds = new Set();
|
|
215
|
+
for (const childId of uniqueChildIds) {
|
|
216
|
+
for (const existing of existingNestByChild.get(childId) ?? []) {
|
|
217
|
+
if (existing.relId === existingTargetNest?.relId || detachedRelIds.has(existing.relId))
|
|
218
|
+
continue;
|
|
219
|
+
detachedRelIds.add(existing.relId);
|
|
220
|
+
const remaining = existing.relatedIds.filter(id => !uniqueChildIds.includes(id));
|
|
221
|
+
if (remaining.length === 0)
|
|
222
|
+
editor.removeEntity(existing.relId);
|
|
223
|
+
else
|
|
224
|
+
editor.setPositionalAttribute(existing.relId, 5, remaining.map(id => `#${id}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (existingTargetNest) {
|
|
228
|
+
const merged = [...new Set([...existingTargetNest.relatedIds, ...uniqueChildIds])];
|
|
229
|
+
editor.setPositionalAttribute(existingTargetNest.relId, 5, merged.map(id => `#${id}`));
|
|
230
|
+
return existingTargetNest.relId;
|
|
231
|
+
}
|
|
232
|
+
return editor.addEntity('IfcRelNests', [
|
|
233
|
+
generateIfcGuid(anchor.guidRandom),
|
|
234
|
+
ownerHistoryRef(anchor.ownerHistoryId),
|
|
235
|
+
null,
|
|
236
|
+
null,
|
|
237
|
+
`#${parentId}`,
|
|
238
|
+
uniqueChildIds.map(id => `#${id}`),
|
|
239
|
+
]).expressId;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Shared `IfcRelAssignsToControl` writer behind
|
|
243
|
+
* `assignCostItemsToScheduleInStore` / `assignObjectsToCostItemInStore`:
|
|
244
|
+
* [0] GlobalId, [1] OwnerHistory, [2] Name, [3] Description,
|
|
245
|
+
* [4] RelatedObjects, [5] RelatedObjectsType, [6] RelatingControl. Appends to
|
|
246
|
+
* `existingAssignment` when the controlling entity already has one, rather
|
|
247
|
+
* than creating a second relationship for the same control.
|
|
248
|
+
*/
|
|
249
|
+
function assignToControlInStore(editor, anchor, relatingControlId, relatedObjectIds, existingAssignment, context, controlType, relatedType) {
|
|
250
|
+
const schema = requireMatchingCostSchema(editor, anchor.schema);
|
|
251
|
+
assertCostSchema(schema, context);
|
|
252
|
+
validateRefList(relatedObjectIds, 'relatedObjectIds', context);
|
|
253
|
+
requireRef(relatingControlId, 'relatingControlId', context);
|
|
254
|
+
requireEntityType(editor, relatingControlId, controlType, 'relatingControlId', context);
|
|
255
|
+
// De-duplicated once so a repeated id in the caller's list can't write a
|
|
256
|
+
// repeated #N into RelatedObjects — a caller-visible malformed member list.
|
|
257
|
+
const uniqueRelated = [...new Set(relatedObjectIds)];
|
|
258
|
+
for (const id of uniqueRelated) {
|
|
259
|
+
if (relatedType === 'IfcObjectDefinition') {
|
|
260
|
+
requireAssignableIfcObjectDefinition(editor, id, relatingControlId, context);
|
|
261
|
+
}
|
|
262
|
+
else if (relatedType) {
|
|
263
|
+
requireEntityType(editor, id, relatedType, 'relatedObjectIds', context);
|
|
264
|
+
}
|
|
265
|
+
else if (!editor.hasEntity(id)) {
|
|
266
|
+
throw new Error(`${context}: relatedObjectIds #${id} does not exist in this model`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (existingAssignment) {
|
|
270
|
+
// Filter against the union across every relationship for this control
|
|
271
|
+
// (a member of a DIFFERENT one is not re-added), but merge only into
|
|
272
|
+
// THIS rel's own list — never the union itself, which would copy a
|
|
273
|
+
// secondary relationship's members into the primary one.
|
|
274
|
+
const alreadyMember = new Set(existingAssignment.allMemberIds ?? existingAssignment.relatedIds);
|
|
275
|
+
const toAdd = uniqueRelated.filter(id => !alreadyMember.has(id));
|
|
276
|
+
if (toAdd.length === 0)
|
|
277
|
+
return existingAssignment.relId;
|
|
278
|
+
const merged = [...existingAssignment.relatedIds, ...toAdd];
|
|
279
|
+
editor.setPositionalAttribute(existingAssignment.relId, 4, merged.map(id => `#${id}`));
|
|
280
|
+
return existingAssignment.relId;
|
|
281
|
+
}
|
|
282
|
+
return editor.addEntity('IfcRelAssignsToControl', [
|
|
283
|
+
generateIfcGuid(anchor.guidRandom),
|
|
284
|
+
ownerHistoryRef(anchor.ownerHistoryId),
|
|
285
|
+
null,
|
|
286
|
+
null,
|
|
287
|
+
uniqueRelated.map(id => `#${id}`),
|
|
288
|
+
null,
|
|
289
|
+
`#${relatingControlId}`,
|
|
290
|
+
]).expressId;
|
|
291
|
+
}
|
|
292
|
+
/** Assign `itemIds` (IfcCostItem) to `scheduleId` (IfcCostSchedule) as its controlled objects. */
|
|
293
|
+
export function assignCostItemsToScheduleInStore(editor, anchor, scheduleId, itemIds, existingAssignment) {
|
|
294
|
+
return assignToControlInStore(editor, anchor, scheduleId, itemIds, existingAssignment, 'assignCostItemsToSchedule', 'IfcCostSchedule', 'IfcCostItem');
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Assign IFC objects (products, tasks, resources, etc.) to a cost item.
|
|
298
|
+
* The controlling item itself is not a legal related member.
|
|
299
|
+
*/
|
|
300
|
+
export function assignObjectsToCostItemInStore(editor, anchor, costItemId, objectIds, existingAssignment) {
|
|
301
|
+
return assignToControlInStore(editor, anchor, costItemId, objectIds, existingAssignment, 'assignToCostItem', 'IfcCostItem', 'IfcObjectDefinition');
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Set (replace) `itemId`'s `IfcCostItem.CostValues` (slot 7). `valueIds` is
|
|
305
|
+
* REQUIRED, not optional: an empty array is how a caller CLEARS the list,
|
|
306
|
+
* written as `$` — never `()`, which `[1:?]` forbids.
|
|
307
|
+
*/
|
|
308
|
+
export function attachCostValuesToItemInStore(editor, anchor, itemId, valueIds) {
|
|
309
|
+
assertCostSchema(requireMatchingCostSchema(editor, anchor.schema), 'setCostItemValues');
|
|
310
|
+
requireEntityType(editor, itemId, 'IfcCostItem', 'itemId', 'setCostItemValues');
|
|
311
|
+
for (const id of valueIds) {
|
|
312
|
+
requireRef(id, 'CostValues', 'setCostItemValues');
|
|
313
|
+
requireEntityType(editor, id, 'IfcCostValue', 'CostValues', 'setCostItemValues');
|
|
314
|
+
}
|
|
315
|
+
// De-duplicated (SET semantics, first occurrence kept), like every other
|
|
316
|
+
// list writer here (nestCostItemsInStore's childIds, assignToControlInStore's
|
|
317
|
+
// relatedObjectIds, …) — a repeated id must not write a repeated #N into a
|
|
318
|
+
// list the evaluator sums over (setCostItemValues([v, v]) would otherwise
|
|
319
|
+
// double-count that value).
|
|
320
|
+
const uniqueValueIds = [...new Set(valueIds)];
|
|
321
|
+
editor.setPositionalAttribute(itemId, 7, uniqueValueIds.length === 0 ? null : uniqueValueIds.map(id => `#${id}`));
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/in-store/cost.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,eAAe,EAAqB,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,oCAAoC,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,sBAAsB,EACrG,yBAAyB,GAC1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,eAAe,EAAE,mBAAmB,EAAE,cAAc,EACpD,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,0BAA0B,EAAE,eAAe,EAAE,kBAAkB,GAE3G,MAAM,4BAA4B,CAAC;AAIpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAa/D,yGAAyG;AACzG,MAAM,0BAA0B,GAAwB,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC;AACrG,gEAAgE;AAChE,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC,CAAC;AACrG,SAAS,cAAc,CAAC,KAA0B,EAAE,MAAkB,EAAE,OAAe;IACrF,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED,SAAS,WAAW,CAAC,GAAyB;IAC5C,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAmB,EAAE,MAAkB,EAAE,MAA0B;IACxG,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC,SAAS,CAAC,iBAAiB,EAAE;QACzC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;QACtC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,WAAW,IAAI,IAAI;QAC1B,MAAM,CAAC,UAAU,IAAI,IAAI;QACzB,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7B,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI;QAC3D,MAAM,CAAC,MAAM,IAAI,IAAI;QACrB,MAAM,CAAC,WAAW,IAAI,IAAI;QAC1B,MAAM,CAAC,UAAU,IAAI,IAAI;KAC1B,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB,EAAE,MAAkB,EAAE,MAAsB;IAChG,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACjG,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;IAC7G,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACrF,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;IACzD,eAAe,CAAC,cAAc,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACjE,KAAK,MAAM,EAAE,IAAI,UAAU,IAAI,EAAE;QAAE,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;IAC9G,KAAK,MAAM,EAAE,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC;QACtC,oBAAoB,CAAC,MAAM,EAAE,EAAE,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE;QACrC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;QACtC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,WAAW,IAAI,IAAI;QAC1B,MAAM,CAAC,UAAU,IAAI,IAAI;QACzB,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7B,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI;QAC3D,WAAW,CAAC,UAAU,CAAC;QACvB,WAAW,CAAC,cAAc,CAAC;KAC5B,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB,EAAE,MAAkB,EAAE,MAAuB;IAClG,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,sGAAsG,CAAC,CAAC;IAC1H,CAAC;IACD,0BAA0B,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9E,IAAI,OAAO,GAAsB,IAAI,CAAC;IACtC,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QAChD,UAAU,CAAC,MAAM,CAAC,eAAe,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;QACtE,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;QACnH,OAAO,GAAG,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACnC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QAC1D,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;IACjG,CAAC;IACD,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;IACjE,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,UAAU,IAAI,EAAE;QAAE,sBAAsB,CAAC,MAAM,EAAE,EAAE,EAAE,0BAA0B,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;IACvI,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE;QACtC,MAAM,CAAC,IAAI,IAAI,IAAI;QACnB,MAAM,CAAC,WAAW,IAAI,IAAI;QAC1B,OAAO;QACP,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE;QAC9D,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7B,MAAM,CAAC,cAAc,IAAI,IAAI;QAC7B,MAAM,CAAC,QAAQ,IAAI,IAAI;QACvB,MAAM,CAAC,SAAS,IAAI,IAAI;QACxB,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,IAAI;QACnE,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC;KAC/B,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAmB,EAAE,MAAkB,EAAE,MAA0B;IACxG,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,gCAAgC,CAAC,CAAC;IACrH,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,sBAAsB,MAAM,4BAA4B,CAAC,CAAC;IAC3G,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,oCAAoC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;QACnD,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,MAAM,KAAK,QAAQ,CAAC;IAC5E,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,2CAA2C,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE;QACnC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,WAAW,IAAI,IAAI;QAC1B,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;QACpD,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE;QACjD,MAAM,CAAC,OAAO,IAAI,IAAI;KACvB,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAuBD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAmB,EACnB,MAAkB,EAClB,QAAgB,EAChB,QAAkB,EAClB,mBAAwE,EACxE,kBAAwC;IAExC,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,gBAAgB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IACvD,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAClD,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,8DAA8D,CAAC,CAAC;IACtH,CAAC;IACD,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAChF,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,qCAAqC;IACrC,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9C,KAAK,MAAM,OAAO,IAAI,cAAc;QAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACpH,wEAAwE;IACxE,oBAAoB,CAAC,QAAQ,EAAE,cAAc,EAAE,mBAAmB,CAAC,CAAC;IACpE,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,uEAAuE;IACvE,kEAAkE;IAClE,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,KAAK,MAAM,QAAQ,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9D,IAAI,QAAQ,CAAC,KAAK,KAAK,kBAAkB,EAAE,KAAK,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YACjG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YACjF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;;gBAC3D,MAAM,CAAC,sBAAsB,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,kBAAkB,CAAC,UAAU,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACnF,MAAM,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACvF,OAAO,kBAAkB,CAAC,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE;QACrC,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;QACtC,IAAI;QACJ,IAAI;QACJ,IAAI,QAAQ,EAAE;QACd,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;KACnC,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,MAAmB,EACnB,MAAkB,EAClB,iBAAyB,EACzB,gBAA0B,EAC1B,kBAAmD,EACnD,OAAe,EACf,WAAmB,EACnB,WAAoB;IAEpB,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe,CAAC,gBAAgB,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC/D,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;IAC5D,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACxF,yEAAyE;IACzE,4EAA4E;IAC5E,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACrD,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;QAC/B,IAAI,WAAW,KAAK,qBAAqB,EAAE,CAAC;YAC1C,oCAAoC,CAAC,MAAM,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAC/E,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE,+BAA+B,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IACD,IAAI,kBAAkB,EAAE,CAAC;QACvB,sEAAsE;QACtE,qEAAqE;QACrE,mEAAmE;QACnE,yDAAyD;QACzD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,YAAY,IAAI,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAChG,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC;QACxD,MAAM,MAAM,GAAG,CAAC,GAAG,kBAAkB,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC;QAC5D,MAAM,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACvF,OAAO,kBAAkB,CAAC,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,wBAAwB,EAAE;QAChD,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;QACtC,IAAI;QACJ,IAAI;QACJ,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,IAAI;QACJ,IAAI,iBAAiB,EAAE;KACxB,CAAC,CAAC,SAAS,CAAC;AACf,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,gCAAgC,CAC9C,MAAmB,EAAE,MAAkB,EAAE,UAAkB,EAAE,OAAiB,EAC9E,kBAAwC;IAExC,OAAO,sBAAsB,CAC3B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,aAAa,CACvH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAmB,EAAE,MAAkB,EAAE,UAAkB,EAAE,SAAmB,EAChF,kBAAwC;IAExC,OAAO,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,EACrF,kBAAkB,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAC3C,MAAmB,EACnB,MAAkB,EAClB,MAAc,EACd,QAA2B;IAE3B,gBAAgB,CAAC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACxF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IAChF,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;QAClD,iBAAiB,CAAC,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;IACnF,CAAC;IACD,yEAAyE;IACzE,8EAA8E;IAC9E,2EAA2E;IAC3E,0EAA0E;IAC1E,4BAA4B;IAC5B,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC,EAAE,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACpH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-source.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-source.d.ts","sourceRoot":"","sources":["../../src/in-store/resolve-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,gBAAgB,CAAC;AA0ChF;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,GACtB,gBAAgB,CA+GlB"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* backend layer can call it without needing parser internals.
|
|
13
13
|
*/
|
|
14
14
|
import { EntityExtractor } from '@ifc-lite/parser';
|
|
15
|
+
import { resolvedTypeName } from '@ifc-lite/data';
|
|
15
16
|
import { safeLengthUnitScale } from './length-unit-scale.js';
|
|
16
17
|
/**
|
|
17
18
|
* Rel types whose `RelatedObjects` list is replayed against a
|
|
@@ -130,11 +131,13 @@ export function resolveDuplicateSource(store, sourceExpressId) {
|
|
|
130
131
|
// duplicate flow convert its metre offset onto the native-unit
|
|
131
132
|
// sourceLocation. Falls back to 1 (metres) on extraction failure.
|
|
132
133
|
const lengthUnitScale = safeLengthUnitScale(store.source, store.entityIndex, 'resolveDuplicateSource') ?? 1.0;
|
|
134
|
+
// Canonical PascalCase, or the raw STEP type as parsed (#4933).
|
|
135
|
+
const type = resolvedTypeName(store.entities, sourceExpressId) ?? sourceEntity.type;
|
|
136
|
+
if (!type) {
|
|
137
|
+
throw new Error(`resolveDuplicateSource: #${sourceExpressId} has no resolvable IFC type — cannot duplicate`);
|
|
138
|
+
}
|
|
133
139
|
return {
|
|
134
|
-
|
|
135
|
-
// extractor type when the entity table doesn't recognise the id
|
|
136
|
-
// (vendor extensions etc).
|
|
137
|
-
type: store.entities.getTypeName(sourceExpressId) || sourceEntity.type,
|
|
140
|
+
type,
|
|
138
141
|
attributes: attrs,
|
|
139
142
|
placementExpressId: placementId,
|
|
140
143
|
parentPlacementId,
|
|
@@ -191,10 +194,10 @@ function collectSourceAssociations(store, extractor, sourceId) {
|
|
|
191
194
|
continue;
|
|
192
195
|
const name = typeof entity.attributes[2] === 'string' ? entity.attributes[2] : null;
|
|
193
196
|
const description = typeof entity.attributes[3] === 'string' ? entity.attributes[3] : null;
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
const canonicalRelType = store.entities
|
|
197
|
+
// Canonical PascalCase when the table has it; association rels are
|
|
198
|
+
// usually categorised out of the `EntityTable` entirely, so `relType`
|
|
199
|
+
// (the constant this loop is already iterating by) is the fallback.
|
|
200
|
+
const canonicalRelType = resolvedTypeName(store.entities, relId) ?? relType;
|
|
198
201
|
out.push({
|
|
199
202
|
relType: canonicalRelType,
|
|
200
203
|
ownerHistoryId,
|