@ifc-lite/create 1.14.5 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/ifc-creator-math.d.ts +23 -0
  2. package/dist/ifc-creator-math.d.ts.map +1 -0
  3. package/dist/ifc-creator-math.js +50 -0
  4. package/dist/ifc-creator-math.js.map +1 -0
  5. package/dist/ifc-creator.d.ts +63 -1
  6. package/dist/ifc-creator.d.ts.map +1 -1
  7. package/dist/ifc-creator.js +222 -41
  8. package/dist/ifc-creator.js.map +1 -1
  9. package/dist/in-store/_emit-helpers.d.ts +52 -0
  10. package/dist/in-store/_emit-helpers.d.ts.map +1 -0
  11. package/dist/in-store/_emit-helpers.js +147 -0
  12. package/dist/in-store/_emit-helpers.js.map +1 -0
  13. package/dist/in-store/anchor.d.ts +29 -0
  14. package/dist/in-store/anchor.d.ts.map +1 -0
  15. package/dist/in-store/anchor.js +5 -0
  16. package/dist/in-store/anchor.js.map +1 -0
  17. package/dist/in-store/auto-space-detect.d.ts +68 -0
  18. package/dist/in-store/auto-space-detect.d.ts.map +1 -0
  19. package/dist/in-store/auto-space-detect.js +393 -0
  20. package/dist/in-store/auto-space-detect.js.map +1 -0
  21. package/dist/in-store/beam.d.ts +25 -0
  22. package/dist/in-store/beam.d.ts.map +1 -0
  23. package/dist/in-store/beam.js +119 -0
  24. package/dist/in-store/beam.js.map +1 -0
  25. package/dist/in-store/column.d.ts +42 -0
  26. package/dist/in-store/column.d.ts.map +1 -0
  27. package/dist/in-store/column.js +108 -0
  28. package/dist/in-store/column.js.map +1 -0
  29. package/dist/in-store/door.d.ts +44 -0
  30. package/dist/in-store/door.d.ts.map +1 -0
  31. package/dist/in-store/door.js +68 -0
  32. package/dist/in-store/door.js.map +1 -0
  33. package/dist/in-store/duplicate.d.ts +100 -0
  34. package/dist/in-store/duplicate.d.ts.map +1 -0
  35. package/dist/in-store/duplicate.js +122 -0
  36. package/dist/in-store/duplicate.js.map +1 -0
  37. package/dist/in-store/extract-walls.d.ts +80 -0
  38. package/dist/in-store/extract-walls.d.ts.map +1 -0
  39. package/dist/in-store/extract-walls.js +522 -0
  40. package/dist/in-store/extract-walls.js.map +1 -0
  41. package/dist/in-store/generate-spaces.d.ts +71 -0
  42. package/dist/in-store/generate-spaces.d.ts.map +1 -0
  43. package/dist/in-store/generate-spaces.js +76 -0
  44. package/dist/in-store/generate-spaces.js.map +1 -0
  45. package/dist/in-store/member.d.ts +32 -0
  46. package/dist/in-store/member.d.ts.map +1 -0
  47. package/dist/in-store/member.js +35 -0
  48. package/dist/in-store/member.js.map +1 -0
  49. package/dist/in-store/plate.d.ts +43 -0
  50. package/dist/in-store/plate.d.ts.map +1 -0
  51. package/dist/in-store/plate.js +33 -0
  52. package/dist/in-store/plate.js.map +1 -0
  53. package/dist/in-store/resolve-anchor.d.ts +12 -0
  54. package/dist/in-store/resolve-anchor.d.ts.map +1 -0
  55. package/dist/in-store/resolve-anchor.js +125 -0
  56. package/dist/in-store/resolve-anchor.js.map +1 -0
  57. package/dist/in-store/resolve-source.d.ts +19 -0
  58. package/dist/in-store/resolve-source.d.ts.map +1 -0
  59. package/dist/in-store/resolve-source.js +203 -0
  60. package/dist/in-store/resolve-source.js.map +1 -0
  61. package/dist/in-store/roof.d.ts +43 -0
  62. package/dist/in-store/roof.d.ts.map +1 -0
  63. package/dist/in-store/roof.js +33 -0
  64. package/dist/in-store/roof.js.map +1 -0
  65. package/dist/in-store/slab.d.ts +44 -0
  66. package/dist/in-store/slab.d.ts.map +1 -0
  67. package/dist/in-store/slab.js +142 -0
  68. package/dist/in-store/slab.js.map +1 -0
  69. package/dist/in-store/space.d.ts +43 -0
  70. package/dist/in-store/space.d.ts.map +1 -0
  71. package/dist/in-store/space.js +71 -0
  72. package/dist/in-store/space.js.map +1 -0
  73. package/dist/in-store/wall.d.ts +27 -0
  74. package/dist/in-store/wall.d.ts.map +1 -0
  75. package/dist/in-store/wall.js +121 -0
  76. package/dist/in-store/wall.js.map +1 -0
  77. package/dist/in-store/window.d.ts +36 -0
  78. package/dist/in-store/window.d.ts.map +1 -0
  79. package/dist/in-store/window.js +57 -0
  80. package/dist/in-store/window.js.map +1 -0
  81. package/dist/index.d.ts +18 -1
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +18 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/types.d.ts +96 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/package.json +10 -6
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Anchored builder for IfcRoof — a flat roof slab. Same geometry shape
3
+ * as IfcSlab (rectangle or polygon, extruded by Thickness) but emits
4
+ * an IfcRoof entity with `.FLAT_ROOF.` PredefinedType. Pitched roofs
5
+ * (gable / hip / mono-pitch) are out of scope for v1; users who need
6
+ * them can drop a placeholder roof here and refine via Raw STEP, or
7
+ * use `IfcCreator.addIfcGableRoof` for the from-scratch path.
8
+ */
9
+ import type { StoreEditor } from '@ifc-lite/mutations';
10
+ import type { SpatialAnchor } from './anchor.js';
11
+ export type RoofInStoreParams = RoofRectangleParams | RoofPolygonParams;
12
+ export interface RoofRectangleParams {
13
+ Position: [number, number, number];
14
+ Width: number;
15
+ Depth: number;
16
+ Thickness: number;
17
+ Profile?: 'rectangle';
18
+ Name?: string;
19
+ Description?: string;
20
+ ObjectType?: string;
21
+ Tag?: string;
22
+ }
23
+ export interface RoofPolygonParams {
24
+ Profile: 'polygon';
25
+ OuterCurve: Array<[number, number]>;
26
+ Position?: [number, number, number];
27
+ Thickness: number;
28
+ Name?: string;
29
+ Description?: string;
30
+ ObjectType?: string;
31
+ Tag?: string;
32
+ }
33
+ export interface RoofBuildResult {
34
+ roofId: number;
35
+ placementId: number;
36
+ profileId: number;
37
+ solidId: number;
38
+ shapeRepId: number;
39
+ productShapeId: number;
40
+ relContainedId: number;
41
+ }
42
+ export declare function addRoofToStore(editor: StoreEditor, anchor: SpatialAnchor, params: RoofInStoreParams): RoofBuildResult;
43
+ //# sourceMappingURL=roof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roof.d.ts","sourceRoot":"","sources":["../../src/in-store/roof.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,eAAe,CA4BjB"}
@@ -0,0 +1,33 @@
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 { emitBodyRepresentation, emitExtrudedSolid, emitLocalPlacement, emitPolygonProfile, emitRectangleProfile, emitRelContainedInSpatialStructure, ifcElementHeader, } from './_emit-helpers.js';
5
+ function isPolygonParams(p) {
6
+ return p.Profile === 'polygon';
7
+ }
8
+ export function addRoofToStore(editor, anchor, params) {
9
+ const polygon = isPolygonParams(params);
10
+ const placementOrigin = polygon
11
+ ? params.Position ?? [0, 0, 0]
12
+ : params.Position;
13
+ if (params.Thickness <= 0) {
14
+ throw new Error('addRoofToStore: Thickness must be positive');
15
+ }
16
+ if (!polygon && (params.Width <= 0 || params.Depth <= 0)) {
17
+ throw new Error('addRoofToStore: Width and Depth must be positive');
18
+ }
19
+ const placementId = emitLocalPlacement(editor, anchor.storeyPlacementId, placementOrigin);
20
+ const profileId = polygon
21
+ ? emitPolygonProfile(editor, params.OuterCurve)
22
+ : emitRectangleProfile(editor, params.Width, params.Depth, params.Width / 2, params.Depth / 2);
23
+ const solidId = emitExtrudedSolid(editor, profileId, params.Thickness);
24
+ const { shapeRepId, productShapeId } = emitBodyRepresentation(editor, anchor.bodyContextId, solidId);
25
+ const attrs = ifcElementHeader(anchor.ownerHistoryId, placementId, productShapeId, params, 'Roof');
26
+ if ((anchor.schema ?? 'IFC4') !== 'IFC2X3') {
27
+ attrs.push('.FLAT_ROOF.');
28
+ }
29
+ const roofId = editor.addEntity('IfcRoof', attrs).expressId;
30
+ const relContainedId = emitRelContainedInSpatialStructure(editor, anchor.ownerHistoryId, roofId, anchor.storeyId);
31
+ return { roofId, placementId, profileId, solidId, shapeRepId, productShapeId, relContainedId };
32
+ }
33
+ //# sourceMappingURL=roof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roof.js","sourceRoot":"","sources":["../../src/in-store/roof.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAa/D,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,kCAAkC,EAClC,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAqC5B,SAAS,eAAe,CAAC,CAAoB;IAC3C,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAmB,EACnB,MAAqB,EACrB,MAAyB;IAEzB,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,eAAe,GAA6B,OAAO;QACvD,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IAEpB,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAC1F,MAAM,SAAS,GAAG,OAAO;QACvB,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;QAC/C,CAAC,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACjG,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAErG,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,KAAgD,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,cAAc,GAAG,kCAAkC,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AACjG,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { StoreEditor } from '@ifc-lite/mutations';
2
+ import type { SpatialAnchor } from './anchor.js';
3
+ export type SlabInStoreParams = SlabRectangleParams | SlabPolygonParams;
4
+ export interface SlabRectangleParams {
5
+ Position: [number, number, number];
6
+ Width: number;
7
+ Depth: number;
8
+ Thickness: number;
9
+ /** Discriminator — omit (or `'rectangle'`) to use the rectangle path. */
10
+ Profile?: 'rectangle';
11
+ Name?: string;
12
+ Description?: string;
13
+ ObjectType?: string;
14
+ Tag?: string;
15
+ }
16
+ export interface SlabPolygonParams {
17
+ /** `'polygon'` discriminator selects the IfcArbitraryClosedProfileDef path. */
18
+ Profile: 'polygon';
19
+ /**
20
+ * Closed outline as a list of 2D storey-local points. Must contain at
21
+ * least 3 points. The polyline is auto-closed: if the last point
22
+ * doesn't equal the first, a closing edge back to the first point is
23
+ * inserted at emit time (matches the IfcPolyline convention).
24
+ */
25
+ OuterCurve: Array<[number, number]>;
26
+ /** Local placement origin (metres). Defaults to `[0, 0, 0]`. */
27
+ Position?: [number, number, number];
28
+ Thickness: number;
29
+ Name?: string;
30
+ Description?: string;
31
+ ObjectType?: string;
32
+ Tag?: string;
33
+ }
34
+ export interface SlabBuildResult {
35
+ slabId: number;
36
+ placementId: number;
37
+ profileId: number;
38
+ solidId: number;
39
+ shapeRepId: number;
40
+ productShapeId: number;
41
+ relContainedId: number;
42
+ }
43
+ export declare function addSlabToStore(editor: StoreEditor, anchor: SpatialAnchor, params: SlabInStoreParams): SlabBuildResult;
44
+ //# sourceMappingURL=slab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab.d.ts","sourceRoot":"","sources":["../../src/in-store/slab.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,OAAO,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AA8CD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,eAAe,CAuFjB"}
@@ -0,0 +1,142 @@
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
+ * Anchored builder for IfcSlab — emits a floor slab into a `StoreEditor`
6
+ * overlay. Two profile modes:
7
+ *
8
+ * - **Rectangle (default)**: placement origin at `Position` (the
9
+ * minimum corner); profile = rectangle(Width × Depth) centred at
10
+ * (Width/2, Depth/2) so the slab spans `[Position … Position+(W,D,0)]`.
11
+ *
12
+ * - **Polygon**: pass `OuterCurve` as a closed list of 2D points in
13
+ * storey-local coordinates. Emits an IfcArbitraryClosedProfileDef
14
+ * backed by an IfcPolyline. Placement origin sits at `Position`
15
+ * (defaults to `[0, 0, 0]`); the points are interpreted relative
16
+ * to that origin. The polyline is closed automatically — duplicate
17
+ * last-point-of-first-point is appended only if the input doesn't
18
+ * already end where it started.
19
+ *
20
+ * Both modes extrude upward along local +Z by `Thickness`. Pure: no
21
+ * I/O, no parser access.
22
+ */
23
+ import { generateIfcGuid } from '@ifc-lite/encoding';
24
+ const POINT_EPSILON = 1e-6;
25
+ function isPolygonParams(p) {
26
+ return p.Profile === 'polygon';
27
+ }
28
+ /** Emit the rectangle profile + return its expressId. */
29
+ function emitRectangleProfile(editor, width, depth) {
30
+ const profileOriginPt = editor.addEntity('IfcCartesianPoint', [[width / 2, depth / 2]]).expressId;
31
+ const profilePos = editor.addEntity('IfcAxis2Placement2D', [`#${profileOriginPt}`, null]).expressId;
32
+ return editor.addEntity('IfcRectangleProfileDef', [
33
+ '.AREA.',
34
+ null,
35
+ `#${profilePos}`,
36
+ width,
37
+ depth,
38
+ ]).expressId;
39
+ }
40
+ /**
41
+ * Emit an `IfcArbitraryClosedProfileDef` from a 2D outer curve. Handles
42
+ * auto-closure (appends the first point if the input doesn't already
43
+ * end where it started — IFC requires the polyline to be closed).
44
+ */
45
+ function emitPolygonProfile(editor, curve) {
46
+ if (curve.length < 3) {
47
+ throw new Error('addSlabToStore: polygon OuterCurve needs at least 3 points');
48
+ }
49
+ const first = curve[0];
50
+ const last = curve[curve.length - 1];
51
+ const closed = Math.abs(first[0] - last[0]) < POINT_EPSILON &&
52
+ Math.abs(first[1] - last[1]) < POINT_EPSILON;
53
+ const sequence = closed ? curve : [...curve, first];
54
+ const pointIds = sequence.map((pt) => editor.addEntity('IfcCartesianPoint', [pt]).expressId);
55
+ const polylineId = editor.addEntity('IfcPolyline', [pointIds.map((id) => `#${id}`)]).expressId;
56
+ return editor.addEntity('IfcArbitraryClosedProfileDef', [
57
+ '.AREA.',
58
+ null,
59
+ `#${polylineId}`,
60
+ ]).expressId;
61
+ }
62
+ export function addSlabToStore(editor, anchor, params) {
63
+ const { ownerHistoryId, bodyContextId, storeyId, storeyPlacementId } = anchor;
64
+ const polygon = isPolygonParams(params);
65
+ const placementOrigin = polygon
66
+ ? params.Position ?? [0, 0, 0]
67
+ : params.Position;
68
+ if (params.Thickness <= 0) {
69
+ throw new Error('addSlabToStore: Thickness must be positive');
70
+ }
71
+ if (!polygon && (params.Width <= 0 || params.Depth <= 0)) {
72
+ throw new Error('addSlabToStore: Width and Depth must be positive');
73
+ }
74
+ // Placement at the chosen origin (no rotation).
75
+ const slabOriginPt = editor.addEntity('IfcCartesianPoint', [placementOrigin]).expressId;
76
+ const slabAxis = editor.addEntity('IfcAxis2Placement3D', [
77
+ `#${slabOriginPt}`,
78
+ null,
79
+ null,
80
+ ]).expressId;
81
+ const placementId = editor.addEntity('IfcLocalPlacement', [
82
+ `#${storeyPlacementId}`,
83
+ `#${slabAxis}`,
84
+ ]).expressId;
85
+ const profileId = polygon
86
+ ? emitPolygonProfile(editor, params.OuterCurve)
87
+ : emitRectangleProfile(editor, params.Width, params.Depth);
88
+ // Extruded along +Z by Thickness.
89
+ const solidOriginPt = editor.addEntity('IfcCartesianPoint', [[0, 0, 0]]).expressId;
90
+ const solidAxis = editor.addEntity('IfcAxis2Placement3D', [`#${solidOriginPt}`, null, null]).expressId;
91
+ const extrudeDirection = editor.addEntity('IfcDirection', [[0, 0, 1]]).expressId;
92
+ const solidId = editor.addEntity('IfcExtrudedAreaSolid', [
93
+ `#${profileId}`,
94
+ `#${solidAxis}`,
95
+ `#${extrudeDirection}`,
96
+ params.Thickness,
97
+ ]).expressId;
98
+ const shapeRepId = editor.addEntity('IfcShapeRepresentation', [
99
+ `#${bodyContextId}`,
100
+ 'Body',
101
+ 'SweptSolid',
102
+ [`#${solidId}`],
103
+ ]).expressId;
104
+ const productShapeId = editor.addEntity('IfcProductDefinitionShape', [
105
+ null,
106
+ null,
107
+ [`#${shapeRepId}`],
108
+ ]).expressId;
109
+ // `IfcSlab.PredefinedType` only exists from IFC4 onward.
110
+ const slabAttrs = [
111
+ generateIfcGuid(),
112
+ `#${ownerHistoryId}`,
113
+ params.Name ?? 'Slab',
114
+ params.Description ?? null,
115
+ params.ObjectType ?? null,
116
+ `#${placementId}`,
117
+ `#${productShapeId}`,
118
+ params.Tag ?? null,
119
+ ];
120
+ if ((anchor.schema ?? 'IFC4') !== 'IFC2X3') {
121
+ slabAttrs.push('.FLOOR.');
122
+ }
123
+ const slabId = editor.addEntity('IfcSlab', slabAttrs).expressId;
124
+ const relContainedId = editor.addEntity('IfcRelContainedInSpatialStructure', [
125
+ generateIfcGuid(),
126
+ `#${ownerHistoryId}`,
127
+ null,
128
+ null,
129
+ [`#${slabId}`],
130
+ `#${storeyId}`,
131
+ ]).expressId;
132
+ return {
133
+ slabId,
134
+ placementId,
135
+ profileId,
136
+ solidId,
137
+ shapeRepId,
138
+ productShapeId,
139
+ relContainedId,
140
+ };
141
+ }
142
+ //# sourceMappingURL=slab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab.js","sourceRoot":"","sources":["../../src/in-store/slab.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { StoreEditor } from '@ifc-lite/mutations';
2
+ import type { SpatialAnchor } from './anchor.js';
3
+ export type SpaceInStoreParams = SpaceRectangleParams | SpacePolygonParams;
4
+ export interface SpaceRectangleParams {
5
+ Position: [number, number, number];
6
+ Width: number;
7
+ Depth: number;
8
+ Height: number;
9
+ Profile?: 'rectangle';
10
+ Name?: string;
11
+ LongName?: string;
12
+ Description?: string;
13
+ ObjectType?: string;
14
+ /**
15
+ * Slot 9 enum (without dots). IFC4 IfcSpaceTypeEnum
16
+ * (e.g. INTERNAL/EXTERNAL/USERDEFINED/NOTDEFINED), or the IFC2X3
17
+ * IfcInternalOrExternalEnum. Defaults to INTERNAL.
18
+ */
19
+ PredefinedType?: string;
20
+ }
21
+ export interface SpacePolygonParams {
22
+ Profile: 'polygon';
23
+ OuterCurve: Array<[number, number]>;
24
+ Position?: [number, number, number];
25
+ Height: number;
26
+ Name?: string;
27
+ LongName?: string;
28
+ Description?: string;
29
+ ObjectType?: string;
30
+ /** See SpaceRectangleParams.PredefinedType. */
31
+ PredefinedType?: string;
32
+ }
33
+ export interface SpaceBuildResult {
34
+ spaceId: number;
35
+ placementId: number;
36
+ profileId: number;
37
+ solidId: number;
38
+ shapeRepId: number;
39
+ productShapeId: number;
40
+ relAggregatesId: number;
41
+ }
42
+ export declare function addSpaceToStore(editor: StoreEditor, anchor: SpatialAnchor, params: SpaceInStoreParams): SpaceBuildResult;
43
+ //# sourceMappingURL=space.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"space.d.ts","sourceRoot":"","sources":["../../src/in-store/space.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,kBAAkB,GACzB,gBAAgB,CAqDlB"}
@@ -0,0 +1,71 @@
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
+ * Anchored builder for IfcSpace — a 3D room volume defined by an
6
+ * outer polyline and a height. The user-facing flow is the slab
7
+ * polygon flow plus a Height for the vertical extrusion.
8
+ *
9
+ * IfcSpace is an IfcSpatialStructureElement (not an IfcElement), so:
10
+ * - it doesn't slot into IfcRelContainedInSpatialStructure (which
11
+ * contains products); instead use IfcRelAggregates with the
12
+ * parent storey
13
+ * - the attribute tail differs: LongName at index 7, then
14
+ * CompositionType (.ELEMENT.), InteriorOrExteriorSpace
15
+ * (.INTERNAL.), ElevationWithFlooring
16
+ */
17
+ import { generateIfcGuid } from '@ifc-lite/encoding';
18
+ import { emitBodyRepresentation, emitExtrudedSolid, emitLocalPlacement, emitPolygonProfile, emitRectangleProfile, } from './_emit-helpers.js';
19
+ function isPolygonParams(p) {
20
+ return p.Profile === 'polygon';
21
+ }
22
+ export function addSpaceToStore(editor, anchor, params) {
23
+ const polygon = isPolygonParams(params);
24
+ const placementOrigin = polygon
25
+ ? params.Position ?? [0, 0, 0]
26
+ : params.Position;
27
+ if (params.Height <= 0) {
28
+ throw new Error('addSpaceToStore: Height must be positive');
29
+ }
30
+ if (!polygon && (params.Width <= 0 || params.Depth <= 0)) {
31
+ throw new Error('addSpaceToStore: Width and Depth must be positive');
32
+ }
33
+ const placementId = emitLocalPlacement(editor, anchor.storeyPlacementId, placementOrigin);
34
+ const profileId = polygon
35
+ ? emitPolygonProfile(editor, params.OuterCurve)
36
+ : emitRectangleProfile(editor, params.Width, params.Depth, params.Width / 2, params.Depth / 2);
37
+ const solidId = emitExtrudedSolid(editor, profileId, params.Height);
38
+ const { shapeRepId, productShapeId } = emitBodyRepresentation(editor, anchor.bodyContextId, solidId);
39
+ // IfcSpace attribute order:
40
+ // GlobalId, OwnerHistory, Name, Description, ObjectType,
41
+ // ObjectPlacement, Representation, LongName, CompositionType,
42
+ // PredefinedType (IFC4 IfcSpaceTypeEnum) / InteriorOrExteriorSpace
43
+ // (IFC2X3 IfcInternalOrExternalEnum), ElevationWithFlooring
44
+ // INTERNAL is a valid value in both enums, so it makes a safe default.
45
+ const attrs = [
46
+ generateIfcGuid(),
47
+ `#${anchor.ownerHistoryId}`,
48
+ params.Name ?? 'Space',
49
+ params.Description ?? null,
50
+ params.ObjectType ?? null,
51
+ `#${placementId}`,
52
+ `#${productShapeId}`,
53
+ params.LongName ?? null,
54
+ '.ELEMENT.',
55
+ `.${params.PredefinedType ?? 'INTERNAL'}.`,
56
+ null,
57
+ ];
58
+ const spaceId = editor.addEntity('IfcSpace', attrs).expressId;
59
+ // Spatial-structure parents use IfcRelAggregates, not the
60
+ // ContainedInSpatialStructure rel that IfcElement subtypes use.
61
+ const relAggregatesId = editor.addEntity('IfcRelAggregates', [
62
+ generateIfcGuid(),
63
+ `#${anchor.ownerHistoryId}`,
64
+ null,
65
+ null,
66
+ `#${anchor.storeyId}`,
67
+ [`#${spaceId}`],
68
+ ]).expressId;
69
+ return { spaceId, placementId, profileId, solidId, shapeRepId, productShapeId, relAggregatesId };
70
+ }
71
+ //# sourceMappingURL=space.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"space.js","sourceRoot":"","sources":["../../src/in-store/space.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { StoreEditor } from '@ifc-lite/mutations';
2
+ import type { SpatialAnchor } from './anchor.js';
3
+ export interface WallInStoreParams {
4
+ /** Start of the wall axis, in storey-local coordinates (metres). */
5
+ Start: [number, number, number];
6
+ /** End of the wall axis, in storey-local coordinates (metres). */
7
+ End: [number, number, number];
8
+ /** Wall thickness along the local cross-section axis (metres). */
9
+ Thickness: number;
10
+ /** Extrusion height along +Z (metres). */
11
+ Height: number;
12
+ Name?: string;
13
+ Description?: string;
14
+ ObjectType?: string;
15
+ Tag?: string;
16
+ }
17
+ export interface WallBuildResult {
18
+ wallId: number;
19
+ placementId: number;
20
+ profileId: number;
21
+ solidId: number;
22
+ shapeRepId: number;
23
+ productShapeId: number;
24
+ relContainedId: number;
25
+ }
26
+ export declare function addWallToStore(editor: StoreEditor, anchor: SpatialAnchor, params: WallInStoreParams): WallBuildResult;
27
+ //# sourceMappingURL=wall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wall.d.ts","sourceRoot":"","sources":["../../src/in-store/wall.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kEAAkE;IAClE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,eAAe,CA4GjB"}
@@ -0,0 +1,121 @@
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
+ * Anchored builder for IfcWall — emits the full sub-graph (start
6
+ * placement with direction, offset rectangle profile, extruded solid,
7
+ * representation, IfcRelContainedInSpatialStructure) into a
8
+ * `StoreEditor` overlay. Mirrors `IfcCreator.addIfcWall` semantics:
9
+ *
10
+ * - placement origin at `Start`, local X = wall direction
11
+ * - profile = rectangle(wallLen × Thickness) centred at (wallLen/2, 0)
12
+ * so the solid spans `Start → End` along local X and is centred
13
+ * on the thickness axis
14
+ * - extruded upward (local +Z) by `Height`
15
+ *
16
+ * Pure: no I/O, no parser access — operates entirely through the editor.
17
+ */
18
+ import { generateIfcGuid } from '@ifc-lite/encoding';
19
+ import { vecNorm } from '../ifc-creator-math.js';
20
+ export function addWallToStore(editor, anchor, params) {
21
+ const { ownerHistoryId, bodyContextId, storeyId, storeyPlacementId } = anchor;
22
+ if (params.Thickness <= 0 || params.Height <= 0) {
23
+ throw new Error('addWallToStore: Thickness and Height must be positive');
24
+ }
25
+ const dx = params.End[0] - params.Start[0];
26
+ const dy = params.End[1] - params.Start[1];
27
+ const dz = params.End[2] - params.Start[2];
28
+ const wallLen = Math.hypot(dx, dy);
29
+ if (wallLen <= 0) {
30
+ throw new Error('addWallToStore: Start and End must be distinct points');
31
+ }
32
+ // Walls are extruded along the placement +Z axis (storey up). Sloped
33
+ // endpoints would silently emit invalid geometry, so reject them.
34
+ // Use a length-relative epsilon so float-derived noise on nominally
35
+ // flat coordinates doesn't trip the guard for long walls.
36
+ if (Math.abs(dz) > Math.max(1e-6 * wallLen, 1e-9)) {
37
+ throw new Error('addWallToStore: Start and End must lie on the same storey plane (Z must match)');
38
+ }
39
+ const dir = vecNorm([dx, dy, 0]);
40
+ // Placement at Start with local X = wall direction. Z stays default
41
+ // (up); STEP's IfcAxis2Placement3D fills the missing axis from there.
42
+ const wallOriginPt = editor.addEntity('IfcCartesianPoint', [params.Start]).expressId;
43
+ const refDirVec = editor.addEntity('IfcDirection', [dir]).expressId;
44
+ const wallAxis = editor.addEntity('IfcAxis2Placement3D', [
45
+ `#${wallOriginPt}`,
46
+ null,
47
+ `#${refDirVec}`,
48
+ ]).expressId;
49
+ const placementId = editor.addEntity('IfcLocalPlacement', [
50
+ `#${storeyPlacementId}`,
51
+ `#${wallAxis}`,
52
+ ]).expressId;
53
+ // Rectangle profile centred at (wallLen/2, 0) so the swept solid
54
+ // spans 0..wallLen along local X and -thickness/2..+thickness/2 on Y.
55
+ const profileOriginPt = editor.addEntity('IfcCartesianPoint', [[wallLen / 2, 0]]).expressId;
56
+ const profilePos = editor.addEntity('IfcAxis2Placement2D', [`#${profileOriginPt}`, null]).expressId;
57
+ const profileId = editor.addEntity('IfcRectangleProfileDef', [
58
+ '.AREA.',
59
+ null,
60
+ `#${profilePos}`,
61
+ wallLen,
62
+ params.Thickness,
63
+ ]).expressId;
64
+ // Extruded along +Z by Height.
65
+ const solidOriginPt = editor.addEntity('IfcCartesianPoint', [[0, 0, 0]]).expressId;
66
+ const solidAxis = editor.addEntity('IfcAxis2Placement3D', [`#${solidOriginPt}`, null, null]).expressId;
67
+ const extrudeDirection = editor.addEntity('IfcDirection', [[0, 0, 1]]).expressId;
68
+ const solidId = editor.addEntity('IfcExtrudedAreaSolid', [
69
+ `#${profileId}`,
70
+ `#${solidAxis}`,
71
+ `#${extrudeDirection}`,
72
+ params.Height,
73
+ ]).expressId;
74
+ const shapeRepId = editor.addEntity('IfcShapeRepresentation', [
75
+ `#${bodyContextId}`,
76
+ 'Body',
77
+ 'SweptSolid',
78
+ [`#${solidId}`],
79
+ ]).expressId;
80
+ const productShapeId = editor.addEntity('IfcProductDefinitionShape', [
81
+ null,
82
+ null,
83
+ [`#${shapeRepId}`],
84
+ ]).expressId;
85
+ // `IfcWall.PredefinedType` only exists from IFC4 onward.
86
+ const wallAttrs = [
87
+ generateIfcGuid(),
88
+ `#${ownerHistoryId}`,
89
+ params.Name ?? 'Wall',
90
+ params.Description ?? null,
91
+ params.ObjectType ?? null,
92
+ `#${placementId}`,
93
+ `#${productShapeId}`,
94
+ params.Tag ?? null,
95
+ ];
96
+ if ((anchor.schema ?? 'IFC4') !== 'IFC2X3') {
97
+ // Default to NOTDEFINED so we don't make a semantic claim about
98
+ // the wall's classification — matches addDoorToStore /
99
+ // addWindowToStore and lets callers override via Raw STEP.
100
+ wallAttrs.push('.NOTDEFINED.');
101
+ }
102
+ const wallId = editor.addEntity('IfcWall', wallAttrs).expressId;
103
+ const relContainedId = editor.addEntity('IfcRelContainedInSpatialStructure', [
104
+ generateIfcGuid(),
105
+ `#${ownerHistoryId}`,
106
+ null,
107
+ null,
108
+ [`#${wallId}`],
109
+ `#${storeyId}`,
110
+ ]).expressId;
111
+ return {
112
+ wallId,
113
+ placementId,
114
+ profileId,
115
+ solidId,
116
+ shapeRepId,
117
+ productShapeId,
118
+ relContainedId,
119
+ };
120
+ }
121
+ //# sourceMappingURL=wall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wall.js","sourceRoot":"","sources":["../../src/in-store/wall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Anchored builder for IfcWindow — a free-standing rectangular sash.
3
+ * Same shape as IfcDoor (thin extruded box) but a different IFC type +
4
+ * a different attribute tail (`PartitioningType` / `UserDefinedPartitioningType`).
5
+ */
6
+ import type { StoreEditor } from '@ifc-lite/mutations';
7
+ import type { SpatialAnchor } from './anchor.js';
8
+ export interface WindowInStoreParams {
9
+ /** Sill-centre of the window, in storey-local coordinates. */
10
+ Position: [number, number, number];
11
+ Width: number;
12
+ Height: number;
13
+ /** Sash thickness along storey-local +Y. Defaults to 0.05 m. */
14
+ FrameThickness?: number;
15
+ /** IFC4 PredefinedType. Defaults to NOTDEFINED. */
16
+ PredefinedType?: 'WINDOW' | 'SKYLIGHT' | 'LIGHTDOME' | 'USERDEFINED' | 'NOTDEFINED';
17
+ /** IFC4 PartitioningType. Defaults to NOTDEFINED. */
18
+ PartitioningType?: string;
19
+ /** Free-text label when PartitioningType === 'USERDEFINED'. Ignored otherwise. */
20
+ UserDefinedPartitioningType?: string;
21
+ Name?: string;
22
+ Description?: string;
23
+ ObjectType?: string;
24
+ Tag?: string;
25
+ }
26
+ export interface WindowBuildResult {
27
+ windowId: number;
28
+ placementId: number;
29
+ profileId: number;
30
+ solidId: number;
31
+ shapeRepId: number;
32
+ productShapeId: number;
33
+ relContainedId: number;
34
+ }
35
+ export declare function addWindowToStore(editor: StoreEditor, anchor: SpatialAnchor, params: WindowInStoreParams): WindowBuildResult;
36
+ //# sourceMappingURL=window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/in-store/window.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA6BjD,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,cAAc,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,CAAC;IACpF,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,mBAAmB,GAC1B,iBAAiB,CAqCnB"}