@ifc-lite/collab 0.2.6 → 0.3.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.
Files changed (64) hide show
  1. package/dist/awareness/presence.d.ts +6 -0
  2. package/dist/awareness/presence.d.ts.map +1 -1
  3. package/dist/awareness/presence.js.map +1 -1
  4. package/dist/doc/annotation.d.ts +54 -0
  5. package/dist/doc/annotation.d.ts.map +1 -0
  6. package/dist/doc/annotation.js +84 -0
  7. package/dist/doc/annotation.js.map +1 -0
  8. package/dist/doc/entity.d.ts +18 -2
  9. package/dist/doc/entity.d.ts.map +1 -1
  10. package/dist/doc/entity.js +161 -11
  11. package/dist/doc/entity.js.map +1 -1
  12. package/dist/doc/geometry.d.ts +8 -0
  13. package/dist/doc/geometry.d.ts.map +1 -1
  14. package/dist/doc/geometry.js +12 -0
  15. package/dist/doc/geometry.js.map +1 -1
  16. package/dist/doc/placement.d.ts +102 -0
  17. package/dist/doc/placement.d.ts.map +1 -0
  18. package/dist/doc/placement.js +118 -0
  19. package/dist/doc/placement.js.map +1 -0
  20. package/dist/doc/schema.d.ts +14 -3
  21. package/dist/doc/schema.d.ts.map +1 -1
  22. package/dist/doc/schema.js +7 -0
  23. package/dist/doc/schema.js.map +1 -1
  24. package/dist/geometry/blob-store.d.ts.map +1 -1
  25. package/dist/geometry/blob-store.js +5 -1
  26. package/dist/geometry/blob-store.js.map +1 -1
  27. package/dist/geometry/gc.d.ts.map +1 -1
  28. package/dist/geometry/gc.js +12 -3
  29. package/dist/geometry/gc.js.map +1 -1
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/providers/webrtc.d.ts.map +1 -1
  35. package/dist/providers/webrtc.js +9 -1
  36. package/dist/providers/webrtc.js.map +1 -1
  37. package/dist/snapshot/from-ifcx.d.ts.map +1 -1
  38. package/dist/snapshot/from-ifcx.js +34 -2
  39. package/dist/snapshot/from-ifcx.js.map +1 -1
  40. package/dist/snapshot/from-step.d.ts +76 -0
  41. package/dist/snapshot/from-step.d.ts.map +1 -0
  42. package/dist/snapshot/from-step.js +70 -0
  43. package/dist/snapshot/from-step.js.map +1 -0
  44. package/dist/snapshot/index.d.ts +3 -0
  45. package/dist/snapshot/index.d.ts.map +1 -1
  46. package/dist/snapshot/index.js +3 -0
  47. package/dist/snapshot/index.js.map +1 -1
  48. package/dist/snapshot/minimal-layer.d.ts +20 -4
  49. package/dist/snapshot/minimal-layer.d.ts.map +1 -1
  50. package/dist/snapshot/minimal-layer.js +113 -70
  51. package/dist/snapshot/minimal-layer.js.map +1 -1
  52. package/dist/snapshot/publish-layer.d.ts +60 -0
  53. package/dist/snapshot/publish-layer.d.ts.map +1 -0
  54. package/dist/snapshot/publish-layer.js +43 -0
  55. package/dist/snapshot/publish-layer.js.map +1 -0
  56. package/dist/snapshot/structured-attrs.d.ts +107 -0
  57. package/dist/snapshot/structured-attrs.d.ts.map +1 -0
  58. package/dist/snapshot/structured-attrs.js +250 -0
  59. package/dist/snapshot/structured-attrs.js.map +1 -0
  60. package/dist/snapshot/to-ifcx.d.ts +4 -0
  61. package/dist/snapshot/to-ifcx.d.ts.map +1 -1
  62. package/dist/snapshot/to-ifcx.js +5 -2
  63. package/dist/snapshot/to-ifcx.js.map +1 -1
  64. package/package.json +4 -4
@@ -2,7 +2,9 @@
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
  import { createEntity } from '../doc/entity.js';
5
+ import { createGeometry } from '../doc/geometry.js';
5
6
  import { SEED_ORIGIN, assertSchemaInvariants, metaMap } from '../doc/schema.js';
7
+ import { inflateStructuredAttributes } from './structured-attrs.js';
6
8
  /** Decode whatever the caller hands us into a parsed IfcxFile. */
7
9
  export function parseIfcxInput(input) {
8
10
  if (typeof input === 'string') {
@@ -46,7 +48,18 @@ export function seedFromIfcx(doc, input, opts = {}) {
46
48
  const path = node.path;
47
49
  if (!path)
48
50
  continue;
49
- const attributes = node.attributes ? { ...node.attributes } : {};
51
+ // Null attribute values are removal opinions (minimal layers); with
52
+ // nothing beneath them to remove, they mean "absent" — never store
53
+ // them as values.
54
+ const rawAttributes = {};
55
+ for (const [key, value] of Object.entries(node.attributes ?? {})) {
56
+ if (value !== null)
57
+ rawAttributes[key] = value;
58
+ }
59
+ // Re-inflate structured branches the snapshot writer folded into
60
+ // namespaced attributes (#1031); the shape-gated remainder stays
61
+ // in the flat attributes branch.
62
+ const inflated = inflateStructuredAttributes(rawAttributes);
50
63
  const children = {};
51
64
  if (node.children) {
52
65
  for (const [role, target] of Object.entries(node.children)) {
@@ -62,11 +75,30 @@ export function seedFromIfcx(doc, input, opts = {}) {
62
75
  }
63
76
  }
64
77
  const ifcClass = readIfcClass(node.attributes);
78
+ // A carrier with the embedded geometry record recreates the
79
+ // geometry map entry, so the restored ref is never dangling.
80
+ // Bare-id carriers keep pointing at out-of-band hydrated geometry.
81
+ for (const carrier of inflated.geometryCarriers) {
82
+ if (typeof carrier.type !== 'string' || typeof carrier.source !== 'string')
83
+ continue;
84
+ createGeometry(doc, carrier.geomId, {
85
+ type: carrier.type,
86
+ source: carrier.source,
87
+ blobHash: carrier.blobHash,
88
+ params: carrier.params,
89
+ bbox: carrier.bbox,
90
+ });
91
+ }
65
92
  createEntity(doc, path, {
66
93
  ifcClass,
67
- attributes,
94
+ attributes: inflated.attributes,
68
95
  children,
69
96
  inherits,
97
+ psets: inflated.psets,
98
+ quantities: inflated.quantities,
99
+ classifications: inflated.classifications,
100
+ materials: inflated.materials,
101
+ geometryRef: inflated.geometryRefRecord,
70
102
  meta: {
71
103
  ifcClass,
72
104
  schemaVersion: 'ifc5',
@@ -1 +1 @@
1
- {"version":3,"file":"from-ifcx.js","sourceRoot":"","sources":["../../src/snapshot/from-ifcx.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"from-ifcx.js","sourceRoot":"","sources":["../../src/snapshot/from-ifcx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Legacy STEP IFC → Y.Doc seeding (plan §4.1, §4.2).
3
+ *
4
+ * STEP IFC (IFC2X3 / IFC4 / IFC4X3) has no IFCX paths — only file-local,
5
+ * unstable express ids (`#123`). The stable, file-independent key is the
6
+ * `IfcGloballyUniqueId` (GUID). This seeder keys CRDT entities on the GUID
7
+ * (`/<guid>`), so concurrent edits from peers converge regardless of how
8
+ * each peer's parser numbered the file.
9
+ *
10
+ * Crucially, `@ifc-lite/collab` stays parser-independent: rather than depend
11
+ * on `@ifc-lite/parser` and walk its columnar tables, this takes a minimal
12
+ * structural `StepSeedSource`. The consumer (the viewer, which already has
13
+ * the parser) adapts its `IfcDataStore` into this shape. Geometry is handled
14
+ * separately (hybrid re-tessellation / mesh blobs — plan §4.2 consequence 2),
15
+ * so this seeds entities, attributes, and property sets only.
16
+ */
17
+ import type * as Y from 'yjs';
18
+ import type { PropertyValue } from '../doc/schema.js';
19
+ /** Schema versions the CRDT entity meta accepts (see `EntityMeta`). */
20
+ export type CollabSchemaVersion = 'ifc4' | 'ifc4x3' | 'ifc5';
21
+ /** A single STEP entity reduced to what the CRDT needs. */
22
+ export interface StepSeedEntity {
23
+ /** IfcGloballyUniqueId (22-char). Entities without one are skipped. */
24
+ guid: string;
25
+ /** IFC class name, e.g. `IfcWallStandardCase`. */
26
+ ifcClass: string;
27
+ /**
28
+ * IFCX-native flat attributes (`bsi::ifc::class`, `bsi::ifc::prop::*`, …).
29
+ * Shaped this way so a recipient can reconstruct the model through the same
30
+ * IFCX path as IFC5 rooms — see the viewer's `buildStepSeedSource`.
31
+ */
32
+ attributes?: Record<string, unknown>;
33
+ /**
34
+ * Spatial containment + decomposition as IFCX children: a unique key → the
35
+ * child entity's path (`/<guid>`). Lets the recipient rebuild the spatial
36
+ * tree (Project → Site → Building → Storey → elements).
37
+ */
38
+ children?: Record<string, string>;
39
+ /** Property sets: psetName → propName → value. */
40
+ psets?: Record<string, Record<string, PropertyValue>>;
41
+ }
42
+ /** Minimal model view the seeder consumes (the viewer adapts its store to this). */
43
+ export interface StepSeedSource {
44
+ entities: Iterable<StepSeedEntity>;
45
+ /** Optional file-level metadata mirrored into the doc meta map. */
46
+ header?: {
47
+ schema?: string;
48
+ author?: string;
49
+ timestamp?: string;
50
+ fileName?: string;
51
+ };
52
+ }
53
+ export interface SeedFromStepOptions {
54
+ /** Origin tag for the seeding transaction. Defaults to `SEED_ORIGIN`. */
55
+ origin?: unknown;
56
+ /**
57
+ * Map a raw IFC schema string (`IFC4`, `IFC4X3`, …) to the value stored as
58
+ * the entity `schemaVersion`. Defaults to {@link defaultSchemaVersion}.
59
+ */
60
+ schemaVersionFor?: (schema: string | undefined) => CollabSchemaVersion;
61
+ }
62
+ export interface SeedFromStepResult {
63
+ /** Number of entities seeded (those with a GUID). */
64
+ seeded: number;
65
+ /** Number of source entities skipped (no GUID). */
66
+ skipped: number;
67
+ }
68
+ /** Path key for a STEP entity. Exported so the viewer's `resolveEntity` matches. */
69
+ export declare function guidToPath(guid: string): string;
70
+ /**
71
+ * Seed `doc` from a legacy STEP model. Idempotent: re-seeding the same source
72
+ * into a doc that already has those GUIDs is a no-op (`createEntity` returns
73
+ * the existing entity). Returns seed/skip counts.
74
+ */
75
+ export declare function seedFromStep(doc: Y.Doc, source: StepSeedSource, opts?: SeedFromStepOptions): SeedFromStepResult;
76
+ //# sourceMappingURL=from-step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-step.d.ts","sourceRoot":"","sources":["../../src/snapshot/from-step.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC;AAG9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,uEAAuE;AACvE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAkB7D,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CACvD;AAED,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnC,mEAAmE;IACnE,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,mBAAmB,CAAC;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,mBAAwB,GAC7B,kBAAkB,CA2CpB"}
@@ -0,0 +1,70 @@
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 { createEntity, setPropertyValue } from '../doc/entity.js';
5
+ import { SEED_ORIGIN, assertSchemaInvariants, metaMap } from '../doc/schema.js';
6
+ /**
7
+ * Map a raw STEP schema string to the CRDT's supported set. Legacy IFC2X3 and
8
+ * IFC4 both map to `ifc4` (the spec's editing baseline); IFC4X3 → `ifc4x3`;
9
+ * IFC5 → `ifc5`. Unknown → `ifc4`.
10
+ */
11
+ function defaultSchemaVersion(schema) {
12
+ switch ((schema ?? '').toUpperCase()) {
13
+ case 'IFC4X3':
14
+ return 'ifc4x3';
15
+ case 'IFC5':
16
+ return 'ifc5';
17
+ default:
18
+ return 'ifc4';
19
+ }
20
+ }
21
+ /** Path key for a STEP entity. Exported so the viewer's `resolveEntity` matches. */
22
+ export function guidToPath(guid) {
23
+ return `/${guid}`;
24
+ }
25
+ /**
26
+ * Seed `doc` from a legacy STEP model. Idempotent: re-seeding the same source
27
+ * into a doc that already has those GUIDs is a no-op (`createEntity` returns
28
+ * the existing entity). Returns seed/skip counts.
29
+ */
30
+ export function seedFromStep(doc, source, opts = {}) {
31
+ assertSchemaInvariants(doc);
32
+ const schemaVersionFor = opts.schemaVersionFor ?? defaultSchemaVersion;
33
+ const schemaVersion = schemaVersionFor(source.header?.schema);
34
+ let seeded = 0;
35
+ let skipped = 0;
36
+ doc.transact(() => {
37
+ const meta = metaMap(doc);
38
+ if (source.header)
39
+ meta.set('stepHeader', source.header);
40
+ for (const ent of source.entities) {
41
+ if (!ent.guid) {
42
+ skipped++;
43
+ continue;
44
+ }
45
+ const path = guidToPath(ent.guid);
46
+ createEntity(doc, path, {
47
+ ifcClass: ent.ifcClass,
48
+ attributes: ent.attributes ?? {},
49
+ children: ent.children,
50
+ schemaVersion,
51
+ meta: {
52
+ ifcClass: ent.ifcClass,
53
+ schemaVersion,
54
+ createdAt: source.header?.timestamp ?? new Date().toISOString(),
55
+ createdBy: source.header?.author,
56
+ },
57
+ });
58
+ if (ent.psets) {
59
+ for (const [psetName, props] of Object.entries(ent.psets)) {
60
+ for (const [propName, value] of Object.entries(props)) {
61
+ setPropertyValue(doc, path, psetName, propName, value);
62
+ }
63
+ }
64
+ }
65
+ seeded++;
66
+ }
67
+ }, opts.origin ?? SEED_ORIGIN);
68
+ return { seeded, skipped };
69
+ }
70
+ //# sourceMappingURL=from-step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-step.js","sourceRoot":"","sources":["../../src/snapshot/from-step.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAoB/D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAMhF;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,MAA0B;IACtD,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAqDD,oFAAoF;AACpF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAU,EACV,MAAsB,EACtB,OAA4B,EAAE;IAE9B,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,oBAAoB,CAAC;IACvE,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;QAChB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,MAAM,CAAC,MAAM;YAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAEzD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE;gBACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;gBAChC,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,aAAa;gBACb,IAAI,EAAE;oBACJ,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,aAAa;oBACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC/D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM;iBACjC;aACF,CAAC,CAAC;YAEH,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC1D,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBACtD,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;IAE/B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
@@ -1,6 +1,9 @@
1
1
  export { seedFromIfcx, parseIfcxInput, type SeedOptions, type IfcxInput, } from './from-ifcx.js';
2
+ export { seedFromStep, guidToPath, type StepSeedEntity, type StepSeedSource, type SeedFromStepOptions, type SeedFromStepResult, type CollabSchemaVersion, } from './from-step.js';
2
3
  export { snapshotToIfcx, serializeIfcx, type SnapshotOptions } from './to-ifcx.js';
3
4
  export { captureBaseline, extractUserLayer, filterUpdateByClient, } from './layers.js';
4
5
  export { extractMinimalLayer, type ExtractMinimalLayerOptions, } from './minimal-layer.js';
6
+ export { publishLayer, type PublishLayerOptions, type PublishedLayer, } from './publish-layer.js';
7
+ export { V5A_ATTR_PREFIX, structuredAttributeKey, flattenStructuredBranches, inflateStructuredAttributes, isPropertyValueShaped, geometryRecordLookup, type StructuredBranchesJSON, type InflatedAttributes, type GeometryRefCarrier, type FlattenOptions, } from './structured-attrs.js';
5
8
  export { runSnapshotWorker, type WorkerRequest, type WorkerResponse, type WorkerScopeLike, } from './worker.js';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/snapshot/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/snapshot/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC"}
@@ -2,8 +2,11 @@
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
  export { seedFromIfcx, parseIfcxInput, } from './from-ifcx.js';
5
+ export { seedFromStep, guidToPath, } from './from-step.js';
5
6
  export { snapshotToIfcx, serializeIfcx } from './to-ifcx.js';
6
7
  export { captureBaseline, extractUserLayer, filterUpdateByClient, } from './layers.js';
7
8
  export { extractMinimalLayer, } from './minimal-layer.js';
9
+ export { publishLayer, } from './publish-layer.js';
10
+ export { V5A_ATTR_PREFIX, structuredAttributeKey, flattenStructuredBranches, inflateStructuredAttributes, isPropertyValueShaped, geometryRecordLookup, } from './structured-attrs.js';
8
11
  export { runSnapshotWorker, } from './worker.js';
9
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EACL,YAAY,EACZ,cAAc,GAGf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAwB,MAAM,cAAc,CAAC;AACnF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/snapshot/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EACL,YAAY,EACZ,cAAc,GAGf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,UAAU,GAMX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAwB,MAAM,cAAc,CAAC;AACnF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,GAKrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iBAAiB,GAIlB,MAAM,aAAa,CAAC"}
@@ -5,7 +5,10 @@
5
5
  * contains *only* what changed since `baseline`:
6
6
  * - Entities created since baseline.
7
7
  * - Entities whose attributes / children / inherits changed since
8
- * baseline (only the changed fields appear).
8
+ * baseline (only the changed fields appear). Structured branches
9
+ * (psets / quantities / classifications / materials / geometryRef)
10
+ * participate via the same flattened-attribute view the full
11
+ * snapshot writer emits (`structured-attrs.ts`, #1031).
9
12
  *
10
13
  * Composed with the baseline, the layer reproduces `doc`'s current
11
14
  * state — that's the IFCX layer composition contract from §2 (each
@@ -14,9 +17,16 @@
14
17
  *
15
18
  * Strategy: reconstruct a "before" Y.Doc from the baseline state,
16
19
  * compare entity-by-entity with the live doc, and emit IFCX nodes
17
- * containing only the diff. We deliberately don't try to express
18
- * deletions in the layer — IFCX overlay semantics are additive in
19
- * v0.x, and deletion overlays are spec'd for a future version.
20
+ * containing only the diff.
21
+ *
22
+ * Deletions are expressed as overlays (layer-prs spec 02 §2.3):
23
+ * - a deleted entity emits a tombstone opinion
24
+ * `{ "ifclite::deleted": true }` which shadows weaker opinions for
25
+ * the path (and its children) during composition;
26
+ * - removed children / inherits emit `null` values (standard IFCX
27
+ * removal semantics);
28
+ * - removed attributes emit `null` values (the convention the merge
29
+ * engine and `bakeLayers` resolve).
20
30
  */
21
31
  import type { IfcxFile } from '@ifc-lite/ifcx';
22
32
  import * as Y from 'yjs';
@@ -30,6 +40,12 @@ export interface ExtractMinimalLayerOptions {
30
40
  * that didn't exist in the baseline at all.
31
41
  */
32
42
  includeUpdatedValues?: boolean;
43
+ /**
44
+ * If true (default), express deletions since the baseline as
45
+ * tombstone opinions (`ifclite::deleted`) and `null` removals. Set to
46
+ * false for the legacy additive-only layer shape.
47
+ */
48
+ includeDeletions?: boolean;
33
49
  }
34
50
  /**
35
51
  * Build a minimal IFCX layer expressing the diff between `baseline`
@@ -1 +1 @@
1
- {"version":3,"file":"minimal-layer.d.ts","sourceRoot":"","sources":["../../src/snapshot/minimal-layer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpE,MAAM,WAAW,0BAA0B;IACzC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,QAAQ,EAAE,UAAU,EACpB,OAAO,GAAE,0BAA+B,GACvC,QAAQ,CAsFV"}
1
+ {"version":3,"file":"minimal-layer.d.ts","sourceRoot":"","sources":["../../src/snapshot/minimal-layer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAEzD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpE,MAAM,WAAW,0BAA0B;IACzC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,QAAQ,EAAE,UAAU,EACpB,OAAO,GAAE,0BAA+B,GACvC,QAAQ,CA2HV"}
@@ -1,10 +1,12 @@
1
1
  /* This Source Code Form is subject to the terms of the Mozilla Public
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { IFCLITE_ATTR } from '@ifc-lite/ifcx';
4
5
  import * as Y from 'yjs';
5
6
  import { createCollabDoc, entitiesMap } from '../doc/schema.js';
6
7
  import { entityToJSON } from '../doc/entity.js';
7
8
  import { snapshotToIfcx } from './to-ifcx.js';
9
+ import { flattenStructuredBranches, geometryRecordLookup } from './structured-attrs.js';
8
10
  /**
9
11
  * Build a minimal IFCX layer expressing the diff between `baseline`
10
12
  * and `doc`. `baseline` is whatever `Y.encodeStateAsUpdate(doc)`
@@ -12,85 +14,126 @@ import { snapshotToIfcx } from './to-ifcx.js';
12
14
  */
13
15
  export function extractMinimalLayer(doc, baseline, options = {}) {
14
16
  const includeUpdatedValues = options.includeUpdatedValues ?? true;
17
+ const includeDeletions = options.includeDeletions ?? true;
15
18
  // Reconstruct the "before" state by replaying the baseline update on
16
19
  // a fresh doc.
17
20
  const before = createCollabDoc({ gc: false });
18
- if (baseline.byteLength > 0)
19
- Y.applyUpdate(before, baseline);
20
- // Snapshot the live doc through the standard writer so we get a
21
- // header + imports + schemas template, then trim the data array down
22
- // to the diff.
23
- const live = snapshotToIfcx(doc, options.snapshot);
24
- const beforeEnts = entitiesMap(before);
25
- const liveEnts = entitiesMap(doc);
26
- const diffNodes = [];
27
- liveEnts.forEach((entUntyped, path) => {
28
- const liveJson = entityToJSON(entUntyped);
29
- const beforeUntyped = beforeEnts.get(path);
30
- if (!beforeUntyped) {
31
- // Entity is new — emit it whole (sans empty branches).
21
+ try {
22
+ if (baseline.byteLength > 0)
23
+ Y.applyUpdate(before, baseline);
24
+ // Snapshot the live doc through the standard writer so we get a
25
+ // header + imports + schemas template, then trim the data array down
26
+ // to the diff.
27
+ const live = snapshotToIfcx(doc, options.snapshot);
28
+ const beforeEnts = entitiesMap(before);
29
+ const liveEnts = entitiesMap(doc);
30
+ const liveGeometryFor = geometryRecordLookup(doc);
31
+ const beforeGeometryFor = geometryRecordLookup(before);
32
+ const diffNodes = [];
33
+ liveEnts.forEach((entUntyped, path) => {
34
+ const liveJson = entityToJSON(entUntyped);
35
+ // Diff over the flattened attribute view so structured-branch
36
+ // edits (psets / quantities / classifications / materials /
37
+ // geometryRef) surface exactly like the full writer emits them —
38
+ // the two writers stay in lockstep by construction (#1031).
39
+ const liveAttrs = flattenStructuredBranches(liveJson, { geometryRecordFor: liveGeometryFor });
40
+ const beforeUntyped = beforeEnts.get(path);
41
+ if (!beforeUntyped) {
42
+ // Entity is new — emit it whole (sans empty branches).
43
+ const node = { path };
44
+ if (Object.keys(liveAttrs).length > 0)
45
+ node.attributes = liveAttrs;
46
+ if (Object.keys(liveJson.children).length > 0)
47
+ node.children = { ...liveJson.children };
48
+ if (Object.keys(liveJson.inherits).length > 0)
49
+ node.inherits = { ...liveJson.inherits };
50
+ diffNodes.push(node);
51
+ return;
52
+ }
53
+ const beforeJson = entityToJSON(beforeUntyped);
54
+ const beforeAttrs = flattenStructuredBranches(beforeJson, { geometryRecordFor: beforeGeometryFor });
32
55
  const node = { path };
33
- if (Object.keys(liveJson.attributes).length > 0)
34
- node.attributes = { ...liveJson.attributes };
35
- if (Object.keys(liveJson.children).length > 0)
36
- node.children = { ...liveJson.children };
37
- if (Object.keys(liveJson.inherits).length > 0)
38
- node.inherits = { ...liveJson.inherits };
39
- diffNodes.push(node);
40
- return;
41
- }
42
- const beforeJson = entityToJSON(beforeUntyped);
43
- const node = { path };
44
- let dirty = false;
45
- // Attributes: include keys that are new OR (when configured)
46
- // whose value changed.
47
- const addedAttrs = {};
48
- for (const [key, value] of Object.entries(liveJson.attributes)) {
49
- const wasInBaseline = key in beforeJson.attributes;
50
- if (!wasInBaseline) {
51
- addedAttrs[key] = value;
52
- continue;
56
+ let dirty = false;
57
+ // Attributes: include keys that are new OR (when configured)
58
+ // whose value changed; removed keys emit null.
59
+ const addedAttrs = {};
60
+ for (const [key, value] of Object.entries(liveAttrs)) {
61
+ const wasInBaseline = key in beforeAttrs;
62
+ if (!wasInBaseline) {
63
+ addedAttrs[key] = value;
64
+ continue;
65
+ }
66
+ if (includeUpdatedValues && !deepEqual(value, beforeAttrs[key])) {
67
+ addedAttrs[key] = value;
68
+ }
53
69
  }
54
- if (includeUpdatedValues && !deepEqual(value, beforeJson.attributes[key])) {
55
- addedAttrs[key] = value;
70
+ if (includeDeletions) {
71
+ for (const key of Object.keys(beforeAttrs)) {
72
+ if (!(key in liveAttrs))
73
+ addedAttrs[key] = null;
74
+ }
56
75
  }
57
- }
58
- if (Object.keys(addedAttrs).length > 0) {
59
- node.attributes = addedAttrs;
60
- dirty = true;
61
- }
62
- // Children: same rule.
63
- const addedChildren = {};
64
- for (const [role, child] of Object.entries(liveJson.children)) {
65
- const wasInBaseline = role in beforeJson.children;
66
- if (!wasInBaseline || (includeUpdatedValues && beforeJson.children[role] !== child)) {
67
- addedChildren[role] = child;
76
+ if (Object.keys(addedAttrs).length > 0) {
77
+ node.attributes = addedAttrs;
78
+ dirty = true;
68
79
  }
69
- }
70
- if (Object.keys(addedChildren).length > 0) {
71
- node.children = addedChildren;
72
- dirty = true;
73
- }
74
- // Inherits: same rule.
75
- const addedInherits = {};
76
- for (const [role, inh] of Object.entries(liveJson.inherits)) {
77
- const wasInBaseline = role in beforeJson.inherits;
78
- if (!wasInBaseline || (includeUpdatedValues && beforeJson.inherits[role] !== inh)) {
79
- addedInherits[role] = inh;
80
+ // Children: same rule; removed roles emit null (IFCX removal).
81
+ const addedChildren = {};
82
+ for (const [role, child] of Object.entries(liveJson.children)) {
83
+ const wasInBaseline = role in beforeJson.children;
84
+ if (!wasInBaseline || (includeUpdatedValues && beforeJson.children[role] !== child)) {
85
+ addedChildren[role] = child;
86
+ }
80
87
  }
88
+ if (includeDeletions) {
89
+ for (const role of Object.keys(beforeJson.children)) {
90
+ if (!(role in liveJson.children))
91
+ addedChildren[role] = null;
92
+ }
93
+ }
94
+ if (Object.keys(addedChildren).length > 0) {
95
+ node.children = addedChildren;
96
+ dirty = true;
97
+ }
98
+ // Inherits: same rule.
99
+ const addedInherits = {};
100
+ for (const [role, inh] of Object.entries(liveJson.inherits)) {
101
+ const wasInBaseline = role in beforeJson.inherits;
102
+ if (!wasInBaseline || (includeUpdatedValues && beforeJson.inherits[role] !== inh)) {
103
+ addedInherits[role] = inh;
104
+ }
105
+ }
106
+ if (includeDeletions) {
107
+ for (const role of Object.keys(beforeJson.inherits)) {
108
+ if (!(role in liveJson.inherits))
109
+ addedInherits[role] = null;
110
+ }
111
+ }
112
+ if (Object.keys(addedInherits).length > 0) {
113
+ node.inherits = addedInherits;
114
+ dirty = true;
115
+ }
116
+ if (dirty)
117
+ diffNodes.push(node);
118
+ });
119
+ // Entities deleted since the baseline: tombstone opinions that shadow
120
+ // the entity (and its subtree) when the stack composes.
121
+ if (includeDeletions) {
122
+ beforeEnts.forEach((_entUntyped, path) => {
123
+ if (!liveEnts.has(path)) {
124
+ diffNodes.push({ path, attributes: { [IFCLITE_ATTR.DELETED]: true } });
125
+ }
126
+ });
81
127
  }
82
- if (Object.keys(addedInherits).length > 0) {
83
- node.inherits = addedInherits;
84
- dirty = true;
85
- }
86
- if (dirty)
87
- diffNodes.push(node);
88
- });
89
- before.destroy();
90
- return {
91
- ...live,
92
- data: diffNodes,
93
- };
128
+ return {
129
+ ...live,
130
+ data: diffNodes,
131
+ };
132
+ }
133
+ finally {
134
+ // Deterministic cleanup even when extraction throws.
135
+ before.destroy();
136
+ }
94
137
  }
95
138
  /**
96
139
  * Heuristic deep-equal: handles primitives, arrays, and plain objects.
@@ -1 +1 @@
1
- {"version":3,"file":"minimal-layer.js","sourceRoot":"","sources":["../../src/snapshot/minimal-layer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"minimal-layer.js","sourceRoot":"","sources":["../../src/snapshot/minimal-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * publishLayer: freeze a draft into an immutable, content-addressed,
3
+ * provenance-stamped layer.
4
+ *
5
+ * The draft is a CRDT session (Y.Doc) bound to a base; freezing extracts
6
+ * the minimal layer (including deletion overlays), attaches the
7
+ * provenance manifest (intent, author, scope claims, base, checks), and
8
+ * content-addresses the result: `layerId = blake3(canonical_bytes)`.
9
+ *
10
+ * Check execution and scope-claim verification happen at the calling
11
+ * boundary (MCP/CLI/registry) — pass the results in; they are recorded
12
+ * in the manifest, and signatures never participate in the id.
13
+ *
14
+ * Spec: docs/architecture/layer-prs/02-layer-format.md §2.4,
15
+ * 03-provenance.md, 06-agents.md §6.2.
16
+ */
17
+ import type { IfcxFile, ProvenanceAuthor, ProvenanceBase, ProvenanceCheck, ProvenanceManifest } from '@ifc-lite/ifcx';
18
+ import type * as Y from 'yjs';
19
+ import { type ExtractMinimalLayerOptions } from './minimal-layer.js';
20
+ export interface PublishLayerOptions {
21
+ /** Human-readable why. Mandatory — the `ifc layer log` line. */
22
+ intent: string;
23
+ /** Who authored the draft (human / agent / hybrid). */
24
+ author: ProvenanceAuthor;
25
+ /**
26
+ * Baseline the draft was forked from
27
+ * (`Y.encodeStateAsUpdate` / `captureBaseline` output).
28
+ */
29
+ baseline: Uint8Array;
30
+ /** Identity of the base layer/stack the draft was authored against. */
31
+ base?: ProvenanceBase | null;
32
+ /** Capability-grammar scope claims declared for this layer. */
33
+ scope_claim?: string[];
34
+ /** Results of declared checks, run by the caller before publishing. */
35
+ checks?: ProvenanceCheck[];
36
+ /** blake3 digest of the prompt/task text that produced the layer. */
37
+ instructions_digest?: string;
38
+ /** Parent layer ids in the change DAG (defaults to the base id). */
39
+ parents?: string[];
40
+ /** Manifest timestamp override (defaults to now). */
41
+ created?: string;
42
+ /** Forwarded to the minimal-layer extractor. */
43
+ extract?: ExtractMinimalLayerOptions;
44
+ }
45
+ export interface PublishedLayer {
46
+ /** The immutable layer document, `header.id` set to the content address. */
47
+ file: IfcxFile;
48
+ /** `blake3:` content address over canonical bytes. */
49
+ layerId: string;
50
+ manifest: ProvenanceManifest;
51
+ /** Number of changed nodes the layer carries. */
52
+ opCount: number;
53
+ }
54
+ /**
55
+ * Freeze a draft doc into a published layer. Pure with respect to the
56
+ * draft: the Y.Doc is read, never mutated — publishing again after more
57
+ * edits produces a new layer with a new id.
58
+ */
59
+ export declare function publishLayer(doc: Y.Doc, options: PublishLayerOptions): PublishedLayer;
60
+ //# sourceMappingURL=publish-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-layer.d.ts","sourceRoot":"","sources":["../../src/snapshot/publish-layer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAuB,KAAK,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,QAAQ,EAAE,UAAU,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,uEAAuE;IACvE,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,IAAI,EAAE,QAAQ,CAAC;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,mBAAmB,GAAG,cAAc,CAkCrF"}