@ifc-lite/parser 4.3.0 → 4.3.2

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.
Files changed (53) hide show
  1. package/dist/columnar-parser-indexes.d.ts.map +1 -1
  2. package/dist/columnar-parser-indexes.js +3 -0
  3. package/dist/columnar-parser-indexes.js.map +1 -1
  4. package/dist/columnar-parser.d.ts.map +1 -1
  5. package/dist/columnar-parser.js +13 -53
  6. package/dist/columnar-parser.js.map +1 -1
  7. package/dist/georef-extractor.d.ts +9 -12
  8. package/dist/georef-extractor.d.ts.map +1 -1
  9. package/dist/georef-extractor.js +29 -130
  10. package/dist/georef-extractor.js.map +1 -1
  11. package/dist/georef-transform.d.ts +25 -0
  12. package/dist/georef-transform.d.ts.map +1 -0
  13. package/dist/georef-transform.js +97 -0
  14. package/dist/georef-transform.js.map +1 -0
  15. package/dist/ifc-schema.d.ts.map +1 -1
  16. package/dist/ifc-schema.js +9 -5
  17. package/dist/ifc-schema.js.map +1 -1
  18. package/dist/map-unit-label.d.ts +43 -0
  19. package/dist/map-unit-label.d.ts.map +1 -0
  20. package/dist/map-unit-label.js +140 -0
  21. package/dist/map-unit-label.js.map +1 -0
  22. package/dist/on-demand-cache.d.ts +3 -0
  23. package/dist/on-demand-cache.d.ts.map +1 -0
  24. package/dist/on-demand-cache.js +25 -0
  25. package/dist/on-demand-cache.js.map +1 -0
  26. package/dist/on-demand-extractors.d.ts +2 -2
  27. package/dist/on-demand-extractors.d.ts.map +1 -1
  28. package/dist/on-demand-extractors.js +14 -177
  29. package/dist/on-demand-extractors.js.map +1 -1
  30. package/dist/on-demand-georeferencing.d.ts +19 -0
  31. package/dist/on-demand-georeferencing.d.ts.map +1 -0
  32. package/dist/on-demand-georeferencing.js +139 -0
  33. package/dist/on-demand-georeferencing.js.map +1 -0
  34. package/dist/quantity-collect.d.ts +96 -0
  35. package/dist/quantity-collect.d.ts.map +1 -0
  36. package/dist/quantity-collect.js +146 -0
  37. package/dist/quantity-collect.js.map +1 -0
  38. package/dist/query-backend-maps.d.ts.map +1 -1
  39. package/dist/query-backend-maps.js +4 -0
  40. package/dist/query-backend-maps.js.map +1 -1
  41. package/dist/source-header.d.ts +23 -1
  42. package/dist/source-header.d.ts.map +1 -1
  43. package/dist/source-header.js +133 -43
  44. package/dist/source-header.js.map +1 -1
  45. package/dist/step-lexing.d.ts +92 -0
  46. package/dist/step-lexing.d.ts.map +1 -1
  47. package/dist/step-lexing.js +176 -7
  48. package/dist/step-lexing.js.map +1 -1
  49. package/dist/unit-extractor.d.ts +13 -0
  50. package/dist/unit-extractor.d.ts.map +1 -1
  51. package/dist/unit-extractor.js +17 -2
  52. package/dist/unit-extractor.js.map +1 -1
  53. package/package.json +4 -4
@@ -0,0 +1,146 @@
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
+ * Shared reader for an `IfcElementQuantity.Quantities` list (#3254).
6
+ *
7
+ * The instance path (`ColumnarParser.extractQuantitiesOnDemand`) and the type
8
+ * path (`extractQsetsFromIds`) both walk that list, and each used to inline its
9
+ * own copy of the walk — two copies that would disagree the moment either was
10
+ * touched. The walk lives here and both call it.
11
+ */
12
+ import { QuantityType } from '@ifc-lite/data';
13
+ import { QUANTITY_TYPE_MAP } from './columnar-parser-indexes.js';
14
+ /**
15
+ * `IfcPhysicalComplexQuantity` groups other quantities instead of carrying a
16
+ * value of its own (`packages/codegen/schemas/IFC4_ADD2_TC1.exp`, identically
17
+ * in `IFC4X3.exp`):
18
+ *
19
+ * ENTITY IfcPhysicalComplexQuantity
20
+ * SUBTYPE OF (IfcPhysicalQuantity);
21
+ * HasQuantities : SET [1:?] OF IfcPhysicalQuantity;
22
+ * Discrimination : IfcLabel;
23
+ * Quality : OPTIONAL IfcLabel;
24
+ * Usage : OPTIONAL IfcLabel;
25
+ *
26
+ * With `Name` and `Description` inherited from `IfcPhysicalQuantity`, the
27
+ * flattened slots are HasQuantities[2], Discrimination[3], Quality[4],
28
+ * Usage[5]. Slot 3 — where every `IfcPhysicalSimpleQuantity` subtype keeps its
29
+ * measure — therefore holds a label here.
30
+ */
31
+ const COMPLEX_QUANTITY_TYPE = 'IFCPHYSICALCOMPLEXQUANTITY';
32
+ /**
33
+ * Value slot on every `IfcPhysicalSimpleQuantity` subtype: Name[0],
34
+ * Description[1], Unit[2], *Value[3].
35
+ */
36
+ const SIMPLE_QUANTITY_VALUE_SLOT = 3;
37
+ /**
38
+ * Read an `IfcElementQuantity.Quantities` list into flat quantity records.
39
+ *
40
+ * An `IfcPhysicalComplexQuantity` is skipped: it has no measure to report, and
41
+ * a `{name, type, value}` triple has nowhere to put its `HasQuantities`
42
+ * children. Before #3254 it fell through the simple-quantity path and surfaced
43
+ * as a phantom `Count = 0` — a row that satisfied IDS existence requirements,
44
+ * counted as "has quantities" in `validate`, entered the compare fingerprints
45
+ * and rendered as a bogus quantity card. Skipping matches what the legacy
46
+ * `quantity-extractor.ts` already does for a type it does not recognise, so all
47
+ * three quantity readers now agree.
48
+ *
49
+ * **Its nested quantities are dropped with it, and that is a known gap with no
50
+ * tracking issue behind it.** Not "tracked separately" — an earlier version of
51
+ * this comment said so and nothing tracked it. The children are lost in every
52
+ * case — #3254's fixture nests two `IfcQuantityArea` totalling 26 m² that read
53
+ * back as nothing — and a set whose ONLY member is a complex quantity collects
54
+ * nothing, so since #3261 {@link readQuantitySet} drops the whole
55
+ * `IfcElementQuantity` rather than reporting an empty one.
56
+ *
57
+ * The gap is deliberate rather than overlooked. Flattening the children into
58
+ * this list would feed new names to a dozen name-keyed consumers, and — via the
59
+ * mutable property view that re-writes a touched `IfcElementQuantity` from these
60
+ * records, and `step-property-sets.ts` which emits them as flat siblings — would
61
+ * permanently destroy the complex structure on the next export. Surfacing them
62
+ * safely needs a representation these records do not have: one that read-side
63
+ * consumers can see and the write-back path provably skips. Until that exists,
64
+ * under-reporting is the lesser harm, and this paragraph is the whole of what
65
+ * anyone is doing about it.
66
+ *
67
+ * An entity of a type absent from {@link QUANTITY_TYPE_MAP} still reports as a
68
+ * `Count`, keeping its value under a wrong label rather than vanishing. No
69
+ * `IfcPhysicalSimpleQuantity` subtype relies on that fallback today —
70
+ * `IfcQuantityNumber` (IFC4X3) did until #3266 gave it `QuantityType.Number`,
71
+ * and `test/quantity-type-map-coverage.test.ts` now reds if a schema declares a
72
+ * subtype the map has not gained. That test guards the OTHER hand-written set
73
+ * too: `PROPERTY_ENTITY_TYPES` in `columnar-parser-indexes.ts` decides whether
74
+ * the entity is retained at all, so a subtype missing THERE never reaches this
75
+ * map and the quantity does not exist rather than being mislabelled.
76
+ */
77
+ export function collectQuantitiesFromRefs(store, extractor, refs) {
78
+ const quantities = [];
79
+ if (!Array.isArray(refs))
80
+ return quantities;
81
+ for (const qtyRef of refs) {
82
+ if (typeof qtyRef !== 'number')
83
+ continue;
84
+ const qtyEntityRef = store.entityIndex.byId.get(qtyRef) ?? store.deferredEntityIndex?.get(qtyRef);
85
+ if (!qtyEntityRef)
86
+ continue;
87
+ const qtyEntity = extractor.extractEntity(qtyEntityRef);
88
+ if (!qtyEntity)
89
+ continue;
90
+ const qtyTypeUpper = qtyEntity.type.toUpperCase();
91
+ if (qtyTypeUpper === COMPLEX_QUANTITY_TYPE)
92
+ continue;
93
+ const qtyAttrs = qtyEntity.attributes || [];
94
+ const qtyName = typeof qtyAttrs[0] === 'string' ? qtyAttrs[0] : '';
95
+ if (!qtyName)
96
+ continue;
97
+ const qtyType = QUANTITY_TYPE_MAP[qtyTypeUpper] ?? QuantityType.Count;
98
+ const rawValue = qtyAttrs[SIMPLE_QUANTITY_VALUE_SLOT];
99
+ const value = typeof rawValue === 'number' ? rawValue : 0;
100
+ quantities.push({ name: qtyName, type: qtyType, value });
101
+ }
102
+ return quantities;
103
+ }
104
+ /**
105
+ * `Quantities` slot on `IfcElementQuantity`: GlobalId[0], OwnerHistory[1],
106
+ * Name[2], Description[3] inherited from `IfcRoot`, then MethodOfMeasurement[4]
107
+ * and Quantities[5].
108
+ */
109
+ const QUANTITIES_SLOT = 5;
110
+ /**
111
+ * Read one `IfcElementQuantity` into a reportable quantity set, or `null` when
112
+ * it carries nothing worth reporting.
113
+ *
114
+ * `IFC4_ADD2_TC1.exp` (identically `IFC4X3.exp`):
115
+ *
116
+ * ENTITY IfcElementQuantity
117
+ * SUBTYPE OF (IfcQuantitySet);
118
+ * MethodOfMeasurement : OPTIONAL IfcLabel;
119
+ * Quantities : SET [1:?] OF IfcPhysicalQuantity;
120
+ *
121
+ * `SET [1:?]` admits no empty set, so a set that walks to zero quantities —
122
+ * written empty, or filled only with members this reader cannot report, such as
123
+ * an unresolvable reference or an `IfcPhysicalComplexQuantity` (#3254) — is
124
+ * non-conformant data. Reporting it anyway would assert "this element has
125
+ * quantities" on the strength of a name alone, and the consumers act on exactly
126
+ * that: `validate` counts the element as quantified in its quantity-completeness
127
+ * figure, an IDS quantity-set existence check passes, and the viewer's fallback
128
+ * to the element's TYPE quantities is suppressed by the phantom occurrence set,
129
+ * hiding the real numbers the type carries. So it is dropped (#3259).
130
+ *
131
+ * The instance path and the type path both go through here, so the drop cannot
132
+ * come apart between them again: it used to be inlined at each site, and the
133
+ * type site dropped while the instance site kept.
134
+ */
135
+ export function readQuantitySet(store, extractor, qsetRef, qsetId) {
136
+ const qsetEntity = extractor.extractEntity(qsetRef);
137
+ if (!qsetEntity)
138
+ return null;
139
+ const qsetAttrs = qsetEntity.attributes || [];
140
+ const qsetName = typeof qsetAttrs[2] === 'string' ? qsetAttrs[2] : `QuantitySet #${qsetId}`;
141
+ const quantities = collectQuantitiesFromRefs(store, extractor, qsetAttrs[QUANTITIES_SLOT]);
142
+ if (quantities.length === 0)
143
+ return null;
144
+ return { name: qsetName, quantities };
145
+ }
146
+ //# sourceMappingURL=quantity-collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantity-collect.js","sourceRoot":"","sources":["../src/quantity-collect.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAmBjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAE3D;;;GAGG;AACH,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,UAAU,yBAAyB,CACrC,KAA0B,EAC1B,SAA0B,EAC1B,IAAa;IAEb,MAAM,UAAU,GAAwB,EAAE,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC;IAE5C,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,SAAS;QAEzC,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAClG,IAAI,CAAC,YAAY;YAAE,SAAS;QAE5B,MAAM,SAAS,GAAG,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAClD,IAAI,YAAY,KAAK,qBAAqB;YAAE,SAAS;QAErD,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,MAAM,OAAO,GAAG,iBAAiB,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC;QACtE,MAAM,QAAQ,GAAG,QAAQ,CAAC,0BAA0B,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1D,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,eAAe,GAAG,CAAC,CAAC;AAQ1B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,eAAe,CAC3B,KAA0B,EAC1B,SAA0B,EAC1B,OAAkB,EAClB,MAAc;IAEd,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,MAAM,EAAE,CAAC;IAC5F,MAAM,UAAU,GAAG,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC;IAE3F,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAC1C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"query-backend-maps.d.ts","sourceRoot":"","sources":["../src/query-backend-maps.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAUjD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWrD;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAM/D,CAAC"}
1
+ {"version":3,"file":"query-backend-maps.d.ts","sourceRoot":"","sources":["../src/query-backend-maps.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAcjD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWrD;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAM/D,CAAC"}
@@ -34,6 +34,10 @@ export const IFC_SUBTYPES = {
34
34
  IFCMEMBER: ['IFCMEMBERSTANDARDCASE'],
35
35
  IFCPLATE: ['IFCPLATESTANDARDCASE'],
36
36
  IFCOPENINGELEMENT: ['IFCOPENINGSTANDARDCASE'],
37
+ // Not a `*StandardCase` family, and absent until #3229: IFC4 exporters write
38
+ // furniture as IFCFURNITURE, so `byType('IfcFurnishingElement')` answered
39
+ // with nothing on a model that plainly contained furniture.
40
+ IFCFURNISHINGELEMENT: ['IFCFURNITURE', 'IFCSYSTEMFURNITUREELEMENT'],
37
41
  };
38
42
  /**
39
43
  * Expand a caller's type list to include the known IFC subtypes, uppercasing
@@ -1 +1 @@
1
- {"version":3,"file":"query-backend-maps.js","sourceRoot":"","sources":["../src/query-backend-maps.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAA6B;IACpD,OAAO,EAAE,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;IACxD,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,OAAO,EAAE,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;IACxD,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,QAAQ,EAAE,CAAC,sBAAsB,CAAC;IAClC,iBAAiB,EAAE,CAAC,wBAAwB,CAAC;CAC9C,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,MAAM,GAAG,IAAI,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,iCAAiC,EAAE,gBAAgB,CAAC,gBAAgB;IACpE,gBAAgB,EAAE,gBAAgB,CAAC,UAAU;IAC7C,mBAAmB,EAAE,gBAAgB,CAAC,aAAa;IACnD,kBAAkB,EAAE,gBAAgB,CAAC,YAAY;IACjD,kBAAkB,EAAE,gBAAgB,CAAC,YAAY;CAClD,CAAC"}
1
+ {"version":3,"file":"query-backend-maps.js","sourceRoot":"","sources":["../src/query-backend-maps.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAA6B;IACpD,OAAO,EAAE,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;IACxD,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,OAAO,EAAE,CAAC,qBAAqB,CAAC;IAChC,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,OAAO,EAAE,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;IACxD,SAAS,EAAE,CAAC,uBAAuB,CAAC;IACpC,QAAQ,EAAE,CAAC,sBAAsB,CAAC;IAClC,iBAAiB,EAAE,CAAC,wBAAwB,CAAC;IAC7C,6EAA6E;IAC7E,0EAA0E;IAC1E,4DAA4D;IAC5D,oBAAoB,EAAE,CAAC,cAAc,EAAE,2BAA2B,CAAC;CACpE,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,MAAM,GAAG,IAAI,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,iCAAiC,EAAE,gBAAgB,CAAC,gBAAgB;IACpE,gBAAgB,EAAE,gBAAgB,CAAC,UAAU;IAC7C,mBAAmB,EAAE,gBAAgB,CAAC,aAAa;IACnD,kBAAkB,EAAE,gBAAgB,CAAC,YAAY;IACjD,kBAAkB,EAAE,gBAAgB,CAAC,YAAY;CAClD,CAAC"}
@@ -8,7 +8,7 @@
8
8
  * strings (e.g. `'CoordinateReference [..., ProjectSite: Origin]'`), which a
9
9
  * splitter that ignores quote state would mis-split.
10
10
  */
11
- import type { IfcSourceHeader } from '@ifc-lite/data';
11
+ import type { IfcSourceHeader, IfcStoreBase } from '@ifc-lite/data';
12
12
  import { type IfcSourceBytes } from './source-bytes.js';
13
13
  /**
14
14
  * Parse the HEADER section of a STEP/IFC buffer into {@link IfcSourceHeader}.
@@ -17,4 +17,26 @@ import { type IfcSourceBytes } from './source-bytes.js';
17
17
  * truncated at the first `ENDSEC` so the DATA section is never scanned.
18
18
  */
19
19
  export declare function parseSourceHeader(buffer: Uint8Array | IfcSourceBytes): IfcSourceHeader | undefined;
20
+ /**
21
+ * Determine which IFC schema a STEP buffer declares (issue #3278).
22
+ *
23
+ * The `FILE_SCHEMA` declaration is authoritative and is read from the
24
+ * already-parsed {@link IfcSourceHeader}; free text elsewhere in the header is
25
+ * not. That distinction is the whole point. `FILE_DESCRIPTION` and `FILE_NAME`
26
+ * carry author, organisation, preprocessor and originating-system strings, and
27
+ * exporters routinely stamp a schema token into their product name ("SomeApp
28
+ * IFC4 Exporter") — which a raw substring scan of the header bytes cannot tell
29
+ * apart from a declaration. Reading the record also reaches declarations that
30
+ * sit past the first 2 KB: ISO 10303-21 puts `FILE_SCHEMA` *after* `FILE_NAME`,
31
+ * and a long author or organisation list pushes it out of a small fixed window.
32
+ *
33
+ * Free on the hot path: {@link parseSourceHeader} already runs on every parse,
34
+ * so nothing extra is scanned. The raw decode below now happens only for a file
35
+ * that declares no schema at all.
36
+ *
37
+ * When no `FILE_SCHEMA` identifier resolves, fall back to the historical raw
38
+ * scan of the first 2000 bytes rather than refusing, so every file that
39
+ * resolves today keeps resolving the same way.
40
+ */
41
+ export declare function detectSchemaVersion(buffer: Uint8Array | IfcSourceBytes, header: IfcSourceHeader | undefined): IfcStoreBase['schemaVersion'];
20
42
  //# sourceMappingURL=source-header.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-header.d.ts","sourceRoot":"","sources":["../src/source-header.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA+IvE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,GAAG,cAAc,GAClC,eAAe,GAAG,SAAS,CA2D7B"}
1
+ {"version":3,"file":"source-header.d.ts","sourceRoot":"","sources":["../src/source-header.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4JvE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,GAAG,cAAc,GAClC,eAAe,GAAG,SAAS,CA2D7B;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,GAAG,cAAc,EACnC,MAAM,EAAE,eAAe,GAAG,SAAS,GAClC,YAAY,CAAC,eAAe,CAAC,CAuB/B"}
@@ -3,38 +3,33 @@
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
  import { decodeStepStringLiteral } from '@ifc-lite/encoding';
5
5
  import { asSourceBytes } from './source-bytes.js';
6
+ import { matchesKeywordAt, StepTextScan } from './step-lexing.js';
6
7
  /** Headers are tiny; cap the decode so a huge file's body is never scanned. */
7
8
  const MAX_HEADER_BYTES = 64 * 1024;
8
9
  /**
9
10
  * Split STEP record arguments at top-level commas, respecting paren/bracket
10
- * nesting and single-quoted strings (with `''` escapes). Returns the raw,
11
- * still-escaped argument substrings (trimmed).
11
+ * nesting, single-quoted strings (with `''` escapes) and comments. Returns the
12
+ * raw, still-escaped argument substrings (trimmed).
13
+ *
14
+ * A comment is dropped rather than copied through: it is not part of the
15
+ * argument's value, and its commas are not separators.
12
16
  */
13
17
  function splitTopLevel(inner) {
14
18
  const args = [];
15
19
  let depth = 0;
16
- let inString = false;
17
20
  let current = '';
21
+ const scan = new StepTextScan(inner);
18
22
  for (let i = 0; i < inner.length; i++) {
19
- const ch = inner[i];
20
- if (inString) {
21
- current += ch;
22
- if (ch === "'") {
23
- if (inner[i + 1] === "'") {
24
- current += "'";
25
- i++;
26
- }
27
- else {
28
- inString = false;
29
- }
30
- }
23
+ const skip = scan.skipLexicalAt(i);
24
+ if (skip >= 0) {
25
+ // A literal is part of the argument's text; a comment is not.
26
+ if (inner[i] === "'")
27
+ current += inner.slice(i, skip);
28
+ i = skip - 1;
31
29
  continue;
32
30
  }
33
- if (ch === "'") {
34
- inString = true;
35
- current += ch;
36
- }
37
- else if (ch === '(' || ch === '[') {
31
+ const ch = inner[i];
32
+ if (ch === '(' || ch === '[') {
38
33
  depth++;
39
34
  current += ch;
40
35
  }
@@ -111,38 +106,56 @@ function decodeStringList(arg) {
111
106
  .filter((v) => v !== undefined);
112
107
  }
113
108
  /**
114
- * Extract the argument substring inside the parentheses of `KEYWORD( ... )`,
115
- * starting the search at `fromIndex`. Quote- and nesting-aware so a quoted
116
- * `)` never closes the record early. Returns `null` if not found.
109
+ * Index of `keyword` occurring as a RECORD, outside any string or comment, or
110
+ * -1.
111
+ *
112
+ * A plain `indexOf` is not enough here and the reason is the same one #3278 is
113
+ * about, one level down: header FREE TEXT is not a declaration. STEP strings
114
+ * are single-quoted with `''` as the escape, and a `FILE_DESCRIPTION` item is
115
+ * free to contain the literal text `FILE_SCHEMA(('IFC2X3'))` -- an exporter
116
+ * stamping its own header into a description, a file round-tripped through a
117
+ * tool that quotes what it read. `indexOf` would take that quoted copy as the
118
+ * declaration and answer IFC2X3 for an IFC4X3 file. The same applies to
119
+ * `ENDSEC`: a quoted one would truncate the header before the real
120
+ * `FILE_SCHEMA` record, losing the declaration entirely.
117
121
  */
118
- function extractRecordArgs(text, keyword, fromIndex = 0) {
119
- const upper = text.toUpperCase();
120
- const at = upper.indexOf(keyword, fromIndex);
122
+ function indexOfRecord(text, keyword) {
123
+ const scan = new StepTextScan(text);
124
+ for (let i = 0; i < text.length; i++) {
125
+ const skip = scan.skipLexicalAt(i);
126
+ if (skip >= 0) {
127
+ i = skip - 1;
128
+ continue;
129
+ }
130
+ if (matchesKeywordAt(text, i, keyword))
131
+ return i;
132
+ }
133
+ return -1;
134
+ }
135
+ /**
136
+ * Extract the argument substring inside the parentheses of `KEYWORD( ... )`.
137
+ * Quote-, comment- and nesting-aware so a quoted
138
+ * `)` never closes the record early, and so a quoted KEYWORD is never mistaken
139
+ * for the record itself. Returns `null` if not found.
140
+ */
141
+ function extractRecordArgs(text, keyword) {
142
+ const at = indexOfRecord(text, keyword);
121
143
  if (at < 0)
122
144
  return null;
123
- let i = at + keyword.length;
124
- while (i < text.length && /\s/.test(text[i]))
125
- i++;
145
+ const scan = new StepTextScan(text);
146
+ let i = scan.skipTrivia(at + keyword.length);
126
147
  if (text[i] !== '(')
127
148
  return null;
128
149
  const start = i;
129
150
  let depth = 0;
130
- let inString = false;
131
151
  for (; i < text.length; i++) {
132
- const ch = text[i];
133
- if (inString) {
134
- if (ch === "'") {
135
- if (text[i + 1] === "'")
136
- i++;
137
- else
138
- inString = false;
139
- }
152
+ const skip = scan.skipLexicalAt(i);
153
+ if (skip >= 0) {
154
+ i = skip - 1;
140
155
  continue;
141
156
  }
142
- if (ch === "'") {
143
- inString = true;
144
- }
145
- else if (ch === '(') {
157
+ const ch = text[i];
158
+ if (ch === '(') {
146
159
  depth++;
147
160
  }
148
161
  else if (ch === ')') {
@@ -163,7 +176,7 @@ export function parseSourceHeader(buffer) {
163
176
  const src = asSourceBytes(buffer);
164
177
  const cap = Math.min(src.byteLength, MAX_HEADER_BYTES);
165
178
  let text = src.decodeUtf8(0, cap);
166
- const endSec = text.toUpperCase().indexOf('ENDSEC');
179
+ const endSec = indexOfRecord(text, 'ENDSEC');
167
180
  if (endSec >= 0)
168
181
  text = text.slice(0, endSec);
169
182
  const descRecord = extractRecordArgs(text, 'FILE_DESCRIPTION');
@@ -216,4 +229,81 @@ export function parseSourceHeader(buffer) {
216
229
  schemaIdentifiers,
217
230
  };
218
231
  }
232
+ /**
233
+ * Resolve one `FILE_SCHEMA` identifier to the schema version a store carries.
234
+ *
235
+ * Matched by PREFIX, longest first: the spellings that reach us in the wild
236
+ * carry addendum/corrigendum suffixes (`IFC4X3_ADD2`, `IFC4X1`, `IFC2X3_TC1`),
237
+ * and `IFC4X3` itself begins with `IFC4`, so the `IFC4X3` branch has to be
238
+ * tried before the `IFC4` one. Returns `undefined` for an identifier naming no
239
+ * schema we model, so the caller can keep looking.
240
+ */
241
+ function schemaFromIdentifier(identifier) {
242
+ const token = identifier.trim().toUpperCase();
243
+ if (token.startsWith('IFC5'))
244
+ return 'IFC5';
245
+ if (token.startsWith('IFC4X3'))
246
+ return 'IFC4X3';
247
+ if (token.startsWith('IFC4'))
248
+ return 'IFC4';
249
+ if (token.startsWith('IFC2X3'))
250
+ return 'IFC2X3';
251
+ return undefined;
252
+ }
253
+ /** Upper-case the ASCII letters and nothing else. See `detectSchemaVersion`. */
254
+ function asciiUpper(text) {
255
+ let out = '';
256
+ for (let i = 0; i < text.length; i++) {
257
+ const c = text.charCodeAt(i);
258
+ out += c >= 97 && c <= 122 ? String.fromCharCode(c - 32) : text[i];
259
+ }
260
+ return out;
261
+ }
262
+ /**
263
+ * Determine which IFC schema a STEP buffer declares (issue #3278).
264
+ *
265
+ * The `FILE_SCHEMA` declaration is authoritative and is read from the
266
+ * already-parsed {@link IfcSourceHeader}; free text elsewhere in the header is
267
+ * not. That distinction is the whole point. `FILE_DESCRIPTION` and `FILE_NAME`
268
+ * carry author, organisation, preprocessor and originating-system strings, and
269
+ * exporters routinely stamp a schema token into their product name ("SomeApp
270
+ * IFC4 Exporter") — which a raw substring scan of the header bytes cannot tell
271
+ * apart from a declaration. Reading the record also reaches declarations that
272
+ * sit past the first 2 KB: ISO 10303-21 puts `FILE_SCHEMA` *after* `FILE_NAME`,
273
+ * and a long author or organisation list pushes it out of a small fixed window.
274
+ *
275
+ * Free on the hot path: {@link parseSourceHeader} already runs on every parse,
276
+ * so nothing extra is scanned. The raw decode below now happens only for a file
277
+ * that declares no schema at all.
278
+ *
279
+ * When no `FILE_SCHEMA` identifier resolves, fall back to the historical raw
280
+ * scan of the first 2000 bytes rather than refusing, so every file that
281
+ * resolves today keeps resolving the same way.
282
+ */
283
+ export function detectSchemaVersion(buffer, header) {
284
+ for (const identifier of header?.schemaIdentifiers ?? []) {
285
+ const version = schemaFromIdentifier(identifier);
286
+ if (version !== undefined)
287
+ return version;
288
+ }
289
+ const src = asSourceBytes(buffer);
290
+ const headerEnd = Math.min(src.byteLength, 2000);
291
+ // ASCII-only, for the same reason `matchesKeywordAt` is. `toUpperCase()`
292
+ // maps `ı` (dotless i) to `I`, so a FILE_DESCRIPTION mentioning `ıFC5` chose
293
+ // IFC5 for a file that never said so. This scan is already a loose
294
+ // last-resort substring match -- it only runs when no FILE_SCHEMA identifier
295
+ // resolved at all -- but loose is not a reason to accept a fold 10303-21
296
+ // does not use. Offsets are not taken from this copy, so a copy is fine here
297
+ // where it was not in the record scan.
298
+ const headerText = asciiUpper(src.decodeUtf8(0, headerEnd));
299
+ if (headerText.includes('IFC5'))
300
+ return 'IFC5';
301
+ if (headerText.includes('IFC4X3'))
302
+ return 'IFC4X3';
303
+ if (headerText.includes('IFC4'))
304
+ return 'IFC4';
305
+ if (headerText.includes('IFC2X3'))
306
+ return 'IFC2X3';
307
+ return 'IFC4'; // Default fallback
308
+ }
219
309
  //# sourceMappingURL=source-header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-header.js","sourceRoot":"","sources":["../src/source-header.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"source-header.js","sourceRoot":"","sources":["../src/source-header.ts"],"names":[],"mappings":"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"}
@@ -9,4 +9,96 @@ export interface Skip {
9
9
  export declare function skipLexical(buf: Uint8Array, pos: number, len: number): Skip;
10
10
  export declare function opensLiteralOrComment(buf: Uint8Array, pos: number, len: number): boolean;
11
11
  export declare function countNewlines(buf: Uint8Array, from: number, to: number): number;
12
+ /**
13
+ * A scan of one decoded string.
14
+ *
15
+ * The buffer and the scan state are bound together on purpose. The state is a
16
+ * memo: once a `*\/` search from some `i` fails, no closer exists at or after
17
+ * any later position either, so no later `/*` can open a comment. Every scan
18
+ * here moves its index forward monotonically, so AT MOST ONE closer search can
19
+ * ever fail, and every other one succeeds and consumes a span disjoint from the
20
+ * rest. That is what keeps the whole thing linear.
21
+ *
22
+ * Two earlier shapes were both wrong, and the second was mine:
23
+ *
24
+ * - searching for the closer at every `/*` is QUADRATIC. A failing search
25
+ * runs to the end of the text, the caller advances one character, and the
26
+ * next `/*` repeats it. A 64 KiB header holding 21000 unterminated `/*`
27
+ * took 5.7 seconds.
28
+ * - hoisting `lastIndexOf('*\/')` to the top of each scan fixes that but
29
+ * makes every scan pay a full pass over the buffer even when the input is
30
+ * well formed and the answer is 100 bytes in. The Rust twin is handed whole
31
+ * uncapped files, where that measured 250ns -> 52ms on 200 MB.
32
+ *
33
+ * Deferring the search until a `/*` is actually seen, and remembering the one
34
+ * failure, costs nothing on well-formed input and stays linear on hostile
35
+ * input.
36
+ *
37
+ * Binding the buffer to the state also removes an invariant that was previously
38
+ * only checkable by hand: the old free functions took the closer position as an
39
+ * argument, so passing one derived from a DIFFERENT string compiled and
40
+ * silently mis-scanned.
41
+ */
42
+ export declare class StepTextScan {
43
+ private readonly text;
44
+ private searchCount;
45
+ private noCloser;
46
+ /** `*\/` searches performed. At most one of them can fail; see the class doc. */
47
+ get searches(): number;
48
+ constructor(text: string);
49
+ /**
50
+ * If a `/* ... *\/` comment starts at `text[i]`, the index just past it.
51
+ * Otherwise -1.
52
+ *
53
+ * An UNTERMINATED `/*` is not a comment. Running it to end-of-text would
54
+ * swallow every record after it and lose the whole header, which is worse
55
+ * than the malformed input deserves and worse than doing nothing. Treating it
56
+ * as ordinary text costs only that one `/`, and the scan still advances.
57
+ */
58
+ private skipCommentAt;
59
+ /**
60
+ * If a string literal or a comment starts at `text[i]`, the index just past
61
+ * it. Otherwise -1.
62
+ *
63
+ * Neither carries structure: a keyword, a comma or a bracket inside one is
64
+ * text. Every scan in `source-header.ts` has to agree on that, so it is one
65
+ * function rather than a copy per loop. #3284 was one file holding two rules
66
+ * for the same thing; three private copies of this loop is that shape again.
67
+ *
68
+ * The result always ADVANCES the caller's index. An earlier form returned the
69
+ * `*\/` offset and left -1 to mean unterminated, which a caller adding 1 to
70
+ * turns into 0: the scan restarts at the top, finds the same comment, and
71
+ * never terminates.
72
+ *
73
+ * The two unterminated cases are deliberately not symmetric. An unterminated
74
+ * literal runs to end-of-text, because a lone `'` cannot be read as ordinary
75
+ * text. An unterminated `/*` is simply not a comment, because it can. This is
76
+ * also where this half differs from `skipLexical` above; see the divider.
77
+ */
78
+ skipLexicalAt(i: number): number;
79
+ /**
80
+ * Advance past whitespace and comments. ISO 10303-21 allows a comment
81
+ * wherever whitespace is allowed, including between a record keyword and its
82
+ * `(`.
83
+ *
84
+ * ASCII whitespace only, which is what 10303-21 means. `/\s/` also matches
85
+ * U+00A0 and the other Unicode space separators, while the Rust half tests
86
+ * bytes, so the two halves disagreed on `FILE_SCHEMA (('IFC2X3'))`.
87
+ */
88
+ skipTrivia(i: number): number;
89
+ }
90
+ /**
91
+ * Case-insensitive ASCII compare of `keyword` against `text` at `i`. Callers
92
+ * pass upper-case keywords.
93
+ *
94
+ * Compares character by character instead of uppercasing a copy of `text`,
95
+ * because a copy cannot be indexed into. `'ß'.toUpperCase()` is two characters,
96
+ * so one of them shifts every later offset, and the caller then slices the
97
+ * ORIGINAL text with an offset measured in the copy.
98
+ *
99
+ * ASCII-only on purpose. That is what ISO 10303-21 case-insensitivity means,
100
+ * and it declines the matches a full Unicode fold accepts: `'ſ'` (long s)
101
+ * uppercases to `'S'`, so a full fold reads ` ENDſEC` as `ENDSEC`.
102
+ */
103
+ export declare function matchesKeywordAt(text: string, i: number, keyword: string): boolean;
12
104
  //# sourceMappingURL=step-lexing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-lexing.d.ts","sourceRoot":"","sources":["../src/step-lexing.ts"],"names":[],"mappings":"AAmBA,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/E;AAyCD,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7E;AAWD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAanF;AAED,MAAM,WAAW,IAAI;IAEnB,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAGd,IAAI,EAAE,OAAO,CAAC;CACf;AAKD,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3E;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExF;AAGD,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAM/E"}
1
+ {"version":3,"file":"step-lexing.d.ts","sourceRoot":"","sources":["../src/step-lexing.ts"],"names":[],"mappings":"AAyBA,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/E;AAyCD,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7E;AAWD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAanF;AAED,MAAM,WAAW,IAAI;IAEnB,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAGd,IAAI,EAAE,OAAO,CAAC;CACf;AAKD,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3E;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExF;AAGD,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAM/E;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,YAAY;IASX,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAS;IAEzB,iFAAiF;IACjF,IAAI,QAAQ,IAAI,MAAM,CAErB;gBAE4B,IAAI,EAAE,MAAM;IAEzC;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAarB;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAahC;;;;;;;;OAQG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAS9B;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAOlF"}