@pascal-app/core 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/events/bus.d.ts +38 -2
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/hooks/scene-registry/scene-registry.d.ts +2 -0
  4. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  5. package/dist/hooks/scene-registry/scene-registry.js +2 -0
  6. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  7. package/dist/hooks/spatial-grid/spatial-grid-manager.js +164 -6
  8. package/dist/index.d.ts +8 -15
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +7 -14
  11. package/dist/lib/door-operation.d.ts +7 -0
  12. package/dist/lib/door-operation.d.ts.map +1 -0
  13. package/dist/lib/door-operation.js +25 -0
  14. package/dist/lib/slab-polygon.d.ts +3 -0
  15. package/dist/lib/slab-polygon.d.ts.map +1 -0
  16. package/dist/lib/slab-polygon.js +58 -0
  17. package/dist/material-library.d.ts +5 -3
  18. package/dist/material-library.d.ts.map +1 -1
  19. package/dist/material-library.js +26 -49
  20. package/dist/schema/asset-url.d.ts +34 -0
  21. package/dist/schema/asset-url.d.ts.map +1 -0
  22. package/dist/schema/asset-url.js +79 -0
  23. package/dist/schema/asset-url.test.d.ts +2 -0
  24. package/dist/schema/asset-url.test.d.ts.map +1 -0
  25. package/dist/schema/asset-url.test.js +138 -0
  26. package/dist/schema/index.d.ts +7 -5
  27. package/dist/schema/index.d.ts.map +1 -1
  28. package/dist/schema/index.js +5 -3
  29. package/dist/schema/material.d.ts +3 -2
  30. package/dist/schema/material.d.ts.map +1 -1
  31. package/dist/schema/material.js +13 -11
  32. package/dist/schema/nodes/ceiling.d.ts +1 -1
  33. package/dist/schema/nodes/column.d.ts +520 -0
  34. package/dist/schema/nodes/column.d.ts.map +1 -0
  35. package/dist/schema/nodes/column.js +385 -0
  36. package/dist/schema/nodes/door.d.ts +73 -1
  37. package/dist/schema/nodes/door.d.ts.map +1 -1
  38. package/dist/schema/nodes/door.js +39 -2
  39. package/dist/schema/nodes/fence.d.ts +1 -1
  40. package/dist/schema/nodes/guide.d.ts +17 -0
  41. package/dist/schema/nodes/guide.d.ts.map +1 -1
  42. package/dist/schema/nodes/guide.js +11 -1
  43. package/dist/schema/nodes/item.d.ts +8 -0
  44. package/dist/schema/nodes/item.d.ts.map +1 -1
  45. package/dist/schema/nodes/item.js +18 -1
  46. package/dist/schema/nodes/level.d.ts +1 -1
  47. package/dist/schema/nodes/level.d.ts.map +1 -1
  48. package/dist/schema/nodes/level.js +6 -0
  49. package/dist/schema/nodes/roof-segment.d.ts +1 -1
  50. package/dist/schema/nodes/roof.d.ts +4 -4
  51. package/dist/schema/nodes/scan.d.ts.map +1 -1
  52. package/dist/schema/nodes/scan.js +2 -1
  53. package/dist/schema/nodes/site.d.ts +1 -0
  54. package/dist/schema/nodes/site.d.ts.map +1 -1
  55. package/dist/schema/nodes/slab.d.ts +1 -1
  56. package/dist/schema/nodes/spawn.d.ts +24 -0
  57. package/dist/schema/nodes/spawn.d.ts.map +1 -0
  58. package/dist/schema/nodes/spawn.js +8 -0
  59. package/dist/schema/nodes/stair-segment.d.ts +1 -1
  60. package/dist/schema/nodes/stair.d.ts +8 -8
  61. package/dist/schema/nodes/wall.d.ts +3 -3
  62. package/dist/schema/nodes/window.d.ts +56 -1
  63. package/dist/schema/nodes/window.d.ts.map +1 -1
  64. package/dist/schema/nodes/window.js +29 -0
  65. package/dist/schema/types.d.ts +324 -21
  66. package/dist/schema/types.d.ts.map +1 -1
  67. package/dist/schema/types.js +4 -0
  68. package/dist/store/actions/node-actions.d.ts.map +1 -1
  69. package/dist/store/actions/node-actions.js +6 -5
  70. package/dist/store/use-interactive.d.ts +43 -0
  71. package/dist/store/use-interactive.d.ts.map +1 -1
  72. package/dist/store/use-interactive.js +66 -0
  73. package/dist/store/use-scene.d.ts.map +1 -1
  74. package/dist/store/use-scene.js +60 -2
  75. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  76. package/dist/systems/stair/stair-opening-sync.js +81 -20
  77. package/dist/systems/stair/stair-opening-sync.test.d.ts +2 -0
  78. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +1 -0
  79. package/dist/systems/stair/stair-opening-sync.test.js +65 -0
  80. package/dist/systems/stair/stair-system.js +1 -1
  81. package/package.json +31 -3
@@ -1,6 +1,6 @@
1
1
  import type { ThreeEvent } from '@react-three/fiber';
2
2
  import type { Object3D } from 'three';
3
- import type { BuildingNode, CeilingNode, DoorNode, FenceNode, ItemNode, LevelNode, RoofNode, RoofSegmentNode, SiteNode, SlabNode, StairNode, StairSegmentNode, WallNode, WindowNode, ZoneNode } from '../schema';
3
+ import type { BuildingNode, CeilingNode, ColumnNode, DoorNode, FenceNode, GuideNode, ItemNode, LevelNode, RoofNode, RoofSegmentNode, SiteNode, SlabNode, SpawnNode, StairNode, StairSegmentNode, WallNode, WindowNode, ZoneNode } from '../schema';
4
4
  import type { AnyNode } from '../schema/types';
5
5
  export interface GridEvent {
6
6
  /** World-space intersection point on the grid plane. */
@@ -32,7 +32,9 @@ export type BuildingEvent = NodeEvent<BuildingNode>;
32
32
  export type LevelEvent = NodeEvent<LevelNode>;
33
33
  export type ZoneEvent = NodeEvent<ZoneNode>;
34
34
  export type SlabEvent = NodeEvent<SlabNode>;
35
+ export type SpawnEvent = NodeEvent<SpawnNode>;
35
36
  export type CeilingEvent = NodeEvent<CeilingNode>;
37
+ export type ColumnEvent = NodeEvent<ColumnNode>;
36
38
  export type RoofEvent = NodeEvent<RoofNode>;
37
39
  export type RoofSegmentEvent = NodeEvent<RoofSegmentNode>;
38
40
  export type StairEvent = NodeEvent<StairNode>;
@@ -67,6 +69,18 @@ export interface ThumbnailGenerateEvent {
67
69
  */
68
70
  snapLevels?: boolean;
69
71
  }
72
+ export interface CameraControlFitSceneEvent {
73
+ /**
74
+ * XZ-plane axis-aligned bounds for camera framing. Omitted values let the
75
+ * listener choose its default framing pose.
76
+ */
77
+ bounds?: {
78
+ min: [number, number];
79
+ max: [number, number];
80
+ center: [number, number];
81
+ size: [number, number];
82
+ };
83
+ }
70
84
  type CameraControlEvents = {
71
85
  'camera-controls:view': CameraControlEvent;
72
86
  'camera-controls:focus': CameraControlEvent;
@@ -74,11 +88,33 @@ type CameraControlEvents = {
74
88
  'camera-controls:top-view': undefined;
75
89
  'camera-controls:orbit-cw': undefined;
76
90
  'camera-controls:orbit-ccw': undefined;
91
+ 'camera-controls:fit-scene': CameraControlFitSceneEvent;
77
92
  'camera-controls:generate-thumbnail': ThumbnailGenerateEvent;
78
93
  };
79
94
  type ToolEvents = {
80
95
  'tool:cancel': undefined;
81
96
  };
97
+ type GuideEvents = {
98
+ 'guide:set-reference-scale': {
99
+ guideId: GuideNode['id'];
100
+ };
101
+ 'guide:cancel-reference-scale': undefined;
102
+ 'guide:deleted': {
103
+ guideId: GuideNode['id'];
104
+ };
105
+ };
106
+ type DoorAnimationEvents = {
107
+ 'door:animation-completed': {
108
+ doorId: DoorNode['id'];
109
+ field: 'operationState' | 'swingAngle';
110
+ };
111
+ };
112
+ type WindowAnimationEvents = {
113
+ 'window:animation-completed': {
114
+ windowId: WindowNode['id'];
115
+ field: 'operationState';
116
+ };
117
+ };
82
118
  type PresetEvents = {
83
119
  'preset:generate-thumbnail': {
84
120
  presetId: string;
@@ -109,7 +145,7 @@ type AIChatEvents = {
109
145
  }[];
110
146
  };
111
147
  };
112
- type EditorEvents = GridEvents & NodeEvents<'wall', WallEvent> & NodeEvents<'fence', FenceEvent> & NodeEvents<'item', ItemEvent> & NodeEvents<'site', SiteEvent> & NodeEvents<'building', BuildingEvent> & NodeEvents<'level', LevelEvent> & NodeEvents<'zone', ZoneEvent> & NodeEvents<'slab', SlabEvent> & NodeEvents<'ceiling', CeilingEvent> & NodeEvents<'roof', RoofEvent> & NodeEvents<'roof-segment', RoofSegmentEvent> & NodeEvents<'stair', StairEvent> & NodeEvents<'stair-segment', StairSegmentEvent> & NodeEvents<'window', WindowEvent> & NodeEvents<'door', DoorEvent> & CameraControlEvents & ToolEvents & PresetEvents & ThumbnailEvents & SnapshotEvents & AIChatEvents;
148
+ type EditorEvents = GridEvents & NodeEvents<'wall', WallEvent> & NodeEvents<'fence', FenceEvent> & NodeEvents<'item', ItemEvent> & NodeEvents<'site', SiteEvent> & NodeEvents<'building', BuildingEvent> & NodeEvents<'level', LevelEvent> & NodeEvents<'zone', ZoneEvent> & NodeEvents<'slab', SlabEvent> & NodeEvents<'spawn', SpawnEvent> & NodeEvents<'ceiling', CeilingEvent> & NodeEvents<'column', ColumnEvent> & NodeEvents<'roof', RoofEvent> & NodeEvents<'roof-segment', RoofSegmentEvent> & NodeEvents<'stair', StairEvent> & NodeEvents<'stair-segment', StairSegmentEvent> & NodeEvents<'window', WindowEvent> & NodeEvents<'door', DoorEvent> & CameraControlEvents & ToolEvents & GuideEvents & DoorAnimationEvents & WindowAnimationEvents & PresetEvents & ThumbnailEvents & SnapshotEvents & AIChatEvents;
113
149
  export declare const emitter: import("mitt").Emitter<EditorEvents>;
114
150
  export {};
115
151
  //# sourceMappingURL=bus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/events/bus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/events/bus.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,13 @@ export declare const sceneRegistry: {
5
5
  site: Set<string>;
6
6
  building: Set<string>;
7
7
  ceiling: Set<string>;
8
+ column: Set<string>;
8
9
  level: Set<string>;
9
10
  wall: Set<string>;
10
11
  fence: Set<string>;
11
12
  item: Set<string>;
12
13
  slab: Set<string>;
14
+ spawn: Set<string>;
13
15
  zone: Set<string>;
14
16
  roof: Set<string>;
15
17
  'roof-segment': Set<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"scene-registry.d.ts","sourceRoot":"","sources":["../../../src/hooks/scene-registry/scene-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;IA0BxB,gFAAgF;;CAOjF,CAAA;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,OAAO,aAAa,CAAC,MAAM,EACvC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,QAkBrC"}
1
+ {"version":3,"file":"scene-registry.d.ts","sourceRoot":"","sources":["../../../src/hooks/scene-registry/scene-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;IA4BxB,gFAAgF;;CAOjF,CAAA;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,OAAO,aAAa,CAAC,MAAM,EACvC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,QAkBrC"}
@@ -9,11 +9,13 @@ export const sceneRegistry = {
9
9
  site: new Set(),
10
10
  building: new Set(),
11
11
  ceiling: new Set(),
12
+ column: new Set(),
12
13
  level: new Set(),
13
14
  wall: new Set(),
14
15
  fence: new Set(),
15
16
  item: new Set(),
16
17
  slab: new Set(),
18
+ spawn: new Set(),
17
19
  zone: new Set(),
18
20
  roof: new Set(),
19
21
  'roof-segment': new Set(),
@@ -1 +1 @@
1
- {"version":3,"file":"spatial-grid-manager.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spatial-grid-manager.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid-manager.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { getScaledDimensions } from '../../schema';
1
+ import { getScaledDimensions, isLowProfileItemSurface } from '../../schema';
2
+ import useScene from '../../store/use-scene';
2
3
  import { SpatialGrid } from './spatial-grid';
3
4
  import { WallSpatialGrid } from './wall-spatial-grid';
4
5
  // ============================================================================
@@ -37,6 +38,65 @@ function getItemFootprint(position, dimensions, rotation, inset = 0) {
37
38
  [x + (-halfW * cos - halfD * sin), z + (-halfW * sin + halfD * cos)],
38
39
  ];
39
40
  }
41
+ function getItemLocalBounds(item) {
42
+ const [width, height, depth] = getScaledDimensions(item);
43
+ const minZ = item.asset.attachTo === 'wall-side' ? -depth : -depth / 2;
44
+ const maxZ = item.asset.attachTo === 'wall-side' ? 0 : depth / 2;
45
+ return {
46
+ min: [-width / 2, 0, minZ],
47
+ max: [width / 2, height, maxZ],
48
+ };
49
+ }
50
+ function getItemParentAabb(item) {
51
+ const bounds = getItemLocalBounds(item);
52
+ const corners = [
53
+ [bounds.min[0], bounds.min[1], bounds.min[2]],
54
+ [bounds.min[0], bounds.min[1], bounds.max[2]],
55
+ [bounds.min[0], bounds.max[1], bounds.min[2]],
56
+ [bounds.min[0], bounds.max[1], bounds.max[2]],
57
+ [bounds.max[0], bounds.min[1], bounds.min[2]],
58
+ [bounds.max[0], bounds.min[1], bounds.max[2]],
59
+ [bounds.max[0], bounds.max[1], bounds.min[2]],
60
+ [bounds.max[0], bounds.max[1], bounds.max[2]],
61
+ ];
62
+ const yRot = item.rotation[1] ?? 0;
63
+ const cos = Math.cos(yRot);
64
+ const sin = Math.sin(yRot);
65
+ let minX = Number.POSITIVE_INFINITY;
66
+ let minY = Number.POSITIVE_INFINITY;
67
+ let minZ = Number.POSITIVE_INFINITY;
68
+ let maxX = Number.NEGATIVE_INFINITY;
69
+ let maxY = Number.NEGATIVE_INFINITY;
70
+ let maxZ = Number.NEGATIVE_INFINITY;
71
+ for (const [cx, cy, cz] of corners) {
72
+ const rotatedX = cx * cos + cz * sin;
73
+ const rotatedZ = -cx * sin + cz * cos;
74
+ const worldX = rotatedX + item.position[0];
75
+ const worldY = cy + item.position[1];
76
+ const worldZ = rotatedZ + item.position[2];
77
+ minX = Math.min(minX, worldX);
78
+ minY = Math.min(minY, worldY);
79
+ minZ = Math.min(minZ, worldZ);
80
+ maxX = Math.max(maxX, worldX);
81
+ maxY = Math.max(maxY, worldY);
82
+ maxZ = Math.max(maxZ, worldZ);
83
+ }
84
+ return { minX, maxX, minY, maxY, minZ, maxZ };
85
+ }
86
+ function intervalsOverlap(minA, maxA, minB, maxB, epsilon = 1e-4) {
87
+ return minA < maxB - epsilon && maxA > minB + epsilon;
88
+ }
89
+ function resolveNodeLevelId(node, nodes) {
90
+ if (node.type === 'level')
91
+ return node.id;
92
+ let current = node;
93
+ while (current) {
94
+ if (current.type === 'level')
95
+ return current.id;
96
+ current = current.parentId ? nodes[current.parentId] : undefined;
97
+ }
98
+ return 'default';
99
+ }
40
100
  /**
41
101
  * Test if two line segments (a1->a2) and (b1->b2) intersect.
42
102
  */
@@ -373,8 +433,40 @@ export class SpatialGridManager {
373
433
  }
374
434
  // Query methods
375
435
  canPlaceOnFloor(levelId, position, dimensions, rotation, ignoreIds) {
376
- const grid = this.getFloorGrid(levelId);
377
- return grid.canPlace(position, dimensions, rotation, ignoreIds);
436
+ const nodes = useScene.getState().nodes;
437
+ const ignoreSet = new Set(ignoreIds ?? []);
438
+ const [width, , depth] = dimensions;
439
+ const yRot = rotation[1];
440
+ const cos = Math.abs(Math.cos(yRot));
441
+ const sin = Math.abs(Math.sin(yRot));
442
+ const rotatedW = width * cos + depth * sin;
443
+ const rotatedD = width * sin + depth * cos;
444
+ const draftBounds = {
445
+ minX: position[0] - rotatedW / 2,
446
+ maxX: position[0] + rotatedW / 2,
447
+ minZ: position[2] - rotatedD / 2,
448
+ maxZ: position[2] + rotatedD / 2,
449
+ };
450
+ const conflicts = [];
451
+ for (const node of Object.values(nodes)) {
452
+ if (node.type !== 'item')
453
+ continue;
454
+ const item = node;
455
+ if (item.asset.attachTo)
456
+ continue;
457
+ if (isLowProfileItemSurface(item))
458
+ continue;
459
+ if (ignoreSet.has(item.id))
460
+ continue;
461
+ if (resolveNodeLevelId(item, nodes) !== levelId)
462
+ continue;
463
+ const bounds = getItemParentAabb(item);
464
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
465
+ intervalsOverlap(draftBounds.minZ, draftBounds.maxZ, bounds.minZ, bounds.maxZ)) {
466
+ conflicts.push(item.id);
467
+ }
468
+ }
469
+ return { valid: conflicts.length === 0, conflictIds: conflicts };
378
470
  }
379
471
  /**
380
472
  * Check if an item can be placed on a wall
@@ -396,7 +488,43 @@ export class SpatialGridManager {
396
488
  // Convert local X position to parametric t (0-1)
397
489
  const tCenter = localX / wallLength;
398
490
  const [itemWidth, itemHeight] = dimensions;
399
- return this.getWallGrid(levelId).canPlaceOnWall(wallId, wallLength, wallHeight, tCenter, itemWidth, localY, itemHeight, attachType, side, ignoreIds);
491
+ const baseResult = this.getWallGrid(levelId).canPlaceOnWall(wallId, wallLength, wallHeight, tCenter, itemWidth, localY, itemHeight, attachType, side, ignoreIds);
492
+ if (!baseResult.valid)
493
+ return baseResult;
494
+ const nodes = useScene.getState().nodes;
495
+ const ignoreSet = new Set(ignoreIds ?? []);
496
+ const draftBounds = {
497
+ minX: localX - itemWidth / 2,
498
+ maxX: localX + itemWidth / 2,
499
+ minY: baseResult.adjustedY,
500
+ maxY: baseResult.adjustedY + itemHeight,
501
+ };
502
+ const conflicts = [];
503
+ for (const node of Object.values(nodes)) {
504
+ if (node.type !== 'item')
505
+ continue;
506
+ const item = node;
507
+ if (!(item.asset.attachTo === 'wall' || item.asset.attachTo === 'wall-side'))
508
+ continue;
509
+ if (ignoreSet.has(item.id))
510
+ continue;
511
+ if (item.parentId !== wallId)
512
+ continue;
513
+ if (attachType === 'wall-side' && item.asset.attachTo === 'wall-side' && side && item.side) {
514
+ if (side !== item.side)
515
+ continue;
516
+ }
517
+ const bounds = getItemParentAabb(item);
518
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
519
+ intervalsOverlap(draftBounds.minY, draftBounds.maxY, bounds.minY, bounds.maxY)) {
520
+ conflicts.push(item.id);
521
+ }
522
+ }
523
+ return {
524
+ ...baseResult,
525
+ valid: conflicts.length === 0,
526
+ conflictIds: conflicts,
527
+ };
400
528
  }
401
529
  getWallForItem(levelId, itemId) {
402
530
  return this.getWallGrid(levelId).getWallForItem(itemId);
@@ -541,8 +669,38 @@ export class SpatialGridManager {
541
669
  return { valid: false, conflictIds: [] };
542
670
  }
543
671
  }
544
- // Check for overlaps with other ceiling items
545
- return this.getCeilingGrid(ceilingId).canPlace(position, dimensions, rotation, ignoreIds);
672
+ const nodes = useScene.getState().nodes;
673
+ const ignoreSet = new Set(ignoreIds ?? []);
674
+ const [width, , depth] = dimensions;
675
+ const yRot = rotation[1];
676
+ const cos = Math.abs(Math.cos(yRot));
677
+ const sin = Math.abs(Math.sin(yRot));
678
+ const rotatedW = width * cos + depth * sin;
679
+ const rotatedD = width * sin + depth * cos;
680
+ const draftBounds = {
681
+ minX: position[0] - rotatedW / 2,
682
+ maxX: position[0] + rotatedW / 2,
683
+ minZ: position[2] - rotatedD / 2,
684
+ maxZ: position[2] + rotatedD / 2,
685
+ };
686
+ const conflicts = [];
687
+ for (const node of Object.values(nodes)) {
688
+ if (node.type !== 'item')
689
+ continue;
690
+ const item = node;
691
+ if (item.asset.attachTo !== 'ceiling')
692
+ continue;
693
+ if (ignoreSet.has(item.id))
694
+ continue;
695
+ if (item.parentId !== ceilingId)
696
+ continue;
697
+ const bounds = getItemParentAabb(item);
698
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
699
+ intervalsOverlap(draftBounds.minZ, draftBounds.maxZ, bounds.minZ, bounds.maxZ)) {
700
+ conflicts.push(item.id);
701
+ }
702
+ }
703
+ return { valid: conflicts.length === 0, conflictIds: conflicts };
546
704
  }
547
705
  clearLevel(levelId) {
548
706
  this.floorGrids.delete(levelId);
package/dist/index.d.ts CHANGED
@@ -1,30 +1,23 @@
1
- export type { BuildingEvent, CameraControlEvent, CeilingEvent, DoorEvent, EventSuffix, FenceEvent, GridEvent, ItemEvent, LevelEvent, NodeEvent, RoofEvent, RoofSegmentEvent, SiteEvent, SlabEvent, StairEvent, StairSegmentEvent, WallEvent, WindowEvent, ZoneEvent, } from './events/bus';
1
+ export type { BuildingEvent, CameraControlEvent, CameraControlFitSceneEvent, CeilingEvent, ColumnEvent, DoorEvent, EventSuffix, FenceEvent, GridEvent, ItemEvent, LevelEvent, NodeEvent, RoofEvent, RoofSegmentEvent, SiteEvent, SlabEvent, SpawnEvent, StairEvent, StairSegmentEvent, WallEvent, WindowEvent, ZoneEvent, } from './events/bus';
2
2
  export { emitter, eventSuffixes } from './events/bus';
3
3
  export { sceneRegistry, useRegistry, } from './hooks/scene-registry/scene-registry';
4
4
  export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial-grid-manager';
5
5
  export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
6
6
  export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
7
7
  export { loadAssetUrl, saveAsset } from './lib/asset-storage';
8
+ export { clampDoorOperationState, getDoorRenderOpenAmount, getGarageVisibleOpeningRatio, isOperationDoorType, SECTIONAL_GARAGE_RENDER_OPEN_SCALE, } from './lib/door-operation';
9
+ export { getRenderableSlabPolygon } from './lib/slab-polygon';
8
10
  export { detectSpacesForLevel, initSpaceDetectionSync, type Space, wallTouchesOthers, } from './lib/space-detection';
9
- export { baseMaterial, glassMaterial } from './materials';
10
- export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForTarget, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, type MaterialCatalogItem, toLibraryMaterialRef, } from './material-library';
11
+ export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForCategory, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, MATERIAL_CATEGORIES, type MaterialCatalogItem, type MaterialCategory, toLibraryMaterialRef, } from './material-library';
11
12
  export * from './schema';
12
- export { type ControlValue, type ItemInteractiveState, useInteractive, } from './store/use-interactive';
13
13
  export { getSceneHistoryPauseDepth, pauseSceneHistory, resetSceneHistoryPauseDepth, resumeSceneHistory, } from './store/history-control';
14
+ export { type ControlValue, type DoorAnimationState, type DoorInteractiveState, type ItemInteractiveState, useInteractive, type WindowAnimationState, type WindowInteractiveState, } from './store/use-interactive';
14
15
  export { default as useLiveTransforms, type LiveTransform } from './store/use-live-transforms';
15
- export { FenceSystem } from './systems/fence/fence-system';
16
16
  export { clearSceneHistory, default as useScene } from './store/use-scene';
17
- export { CeilingSystem } from './systems/ceiling/ceiling-system';
18
- export { DoorSystem } from './systems/door/door-system';
19
- export { ItemSystem } from './systems/item/item-system';
20
- export { RoofSystem } from './systems/roof/roof-system';
21
- export { SlabSystem } from './systems/slab/slab-system';
22
- export { StairSystem } from './systems/stair/stair-system';
23
- export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
17
+ export { syncAutoStairOpenings } from './systems/stair/stair-opening-sync';
24
18
  export { getClampedWallCurveOffset, getMaxWallCurveOffset, getWallChordFrame, getWallCurveFrameAt, getWallCurveLength, getWallMidpointHandlePoint, getWallStraightSnapOffset, getWallSurfacePolygon, isCurvedWall, normalizeWallCurveOffset, sampleWallCenterline, } from './systems/wall/wall-curve';
25
- export { calculateLevelMiters, getWallMiterBoundaryPoints, type Point2D, type WallMiterBoundaryPoints, pointToKey, type WallMiterData, } from './systems/wall/wall-mitering';
26
- export { WallSystem } from './systems/wall/wall-system';
27
- export { WindowSystem } from './systems/window/window-system';
19
+ export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
20
+ export { calculateLevelMiters, getAdjacentWallIds, getWallMiterBoundaryPoints, type Point2D, pointToKey, type WallMiterBoundaryPoints, type WallMiterData, } from './systems/wall/wall-mitering';
28
21
  export type { SceneGraph } from './utils/clone-scene-graph';
29
22
  export { cloneLevelSubtree, cloneSceneGraph, forkSceneGraph } from './utils/clone-scene-graph';
30
23
  export { isObject } from './utils/types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EACL,aAAa,EACb,WAAW,GACZ,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9F,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACnB,kCAAkC,GACnC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC9F,OAAO,EAAE,iBAAiB,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAC1E,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,KAAK,OAAO,EACZ,UAAU,EACV,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -4,25 +4,18 @@ export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial
4
4
  export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
5
5
  export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
6
6
  export { loadAssetUrl, saveAsset } from './lib/asset-storage';
7
+ export { clampDoorOperationState, getDoorRenderOpenAmount, getGarageVisibleOpeningRatio, isOperationDoorType, SECTIONAL_GARAGE_RENDER_OPEN_SCALE, } from './lib/door-operation';
8
+ export { getRenderableSlabPolygon } from './lib/slab-polygon';
7
9
  export { detectSpacesForLevel, initSpaceDetectionSync, wallTouchesOthers, } from './lib/space-detection';
8
- export { baseMaterial, glassMaterial } from './materials';
9
- export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForTarget, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, toLibraryMaterialRef, } from './material-library';
10
+ export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForCategory, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, MATERIAL_CATEGORIES, toLibraryMaterialRef, } from './material-library';
10
11
  export * from './schema';
11
- export { useInteractive, } from './store/use-interactive';
12
12
  export { getSceneHistoryPauseDepth, pauseSceneHistory, resetSceneHistoryPauseDepth, resumeSceneHistory, } from './store/history-control';
13
+ export { useInteractive, } from './store/use-interactive';
13
14
  export { default as useLiveTransforms } from './store/use-live-transforms';
14
- export { FenceSystem } from './systems/fence/fence-system';
15
15
  export { clearSceneHistory, default as useScene } from './store/use-scene';
16
- export { CeilingSystem } from './systems/ceiling/ceiling-system';
17
- export { DoorSystem } from './systems/door/door-system';
18
- export { ItemSystem } from './systems/item/item-system';
19
- export { RoofSystem } from './systems/roof/roof-system';
20
- export { SlabSystem } from './systems/slab/slab-system';
21
- export { StairSystem } from './systems/stair/stair-system';
22
- export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
16
+ export { syncAutoStairOpenings } from './systems/stair/stair-opening-sync';
23
17
  export { getClampedWallCurveOffset, getMaxWallCurveOffset, getWallChordFrame, getWallCurveFrameAt, getWallCurveLength, getWallMidpointHandlePoint, getWallStraightSnapOffset, getWallSurfacePolygon, isCurvedWall, normalizeWallCurveOffset, sampleWallCenterline, } from './systems/wall/wall-curve';
24
- export { calculateLevelMiters, getWallMiterBoundaryPoints, pointToKey, } from './systems/wall/wall-mitering';
25
- export { WallSystem } from './systems/wall/wall-system';
26
- export { WindowSystem } from './systems/window/window-system';
18
+ export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
19
+ export { calculateLevelMiters, getAdjacentWallIds, getWallMiterBoundaryPoints, pointToKey, } from './systems/wall/wall-mitering';
27
20
  export { cloneLevelSubtree, cloneSceneGraph, forkSceneGraph } from './utils/clone-scene-graph';
28
21
  export { isObject } from './utils/types';
@@ -0,0 +1,7 @@
1
+ import type { DoorNode, DoorType } from '../schema/nodes/door';
2
+ export declare const SECTIONAL_GARAGE_RENDER_OPEN_SCALE = 0.88;
3
+ export declare function clampDoorOperationState(value: number | undefined): number;
4
+ export declare function isOperationDoorType(doorType: DoorType | DoorNode['doorType'] | string | undefined): doorType is "folding" | "pocket" | "barn" | "sliding" | "garage-sectional" | "garage-rollup" | "garage-tiltup";
5
+ export declare function getDoorRenderOpenAmount(doorType: DoorType | DoorNode['doorType'], operationState: number | undefined): number;
6
+ export declare function getGarageVisibleOpeningRatio(doorType: DoorType | DoorNode['doorType'], operationState: number | undefined): number;
7
+ //# sourceMappingURL=door-operation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"door-operation.d.ts","sourceRoot":"","sources":["../../src/lib/door-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE9D,eAAO,MAAM,kCAAkC,OAAO,CAAA;AAEtD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,UAEhE;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,SAAS,kHAW/D;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,EACzC,cAAc,EAAE,MAAM,GAAG,SAAS,UAMnC;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,EACzC,cAAc,EAAE,MAAM,GAAG,SAAS,UAOnC"}
@@ -0,0 +1,25 @@
1
+ export const SECTIONAL_GARAGE_RENDER_OPEN_SCALE = 0.88;
2
+ export function clampDoorOperationState(value) {
3
+ return Math.max(0, Math.min(1, value ?? 0));
4
+ }
5
+ export function isOperationDoorType(doorType) {
6
+ return (doorType === 'folding' ||
7
+ doorType === 'pocket' ||
8
+ doorType === 'barn' ||
9
+ doorType === 'sliding' ||
10
+ doorType === 'garage-sectional' ||
11
+ doorType === 'garage-rollup' ||
12
+ doorType === 'garage-tiltup');
13
+ }
14
+ export function getDoorRenderOpenAmount(doorType, operationState) {
15
+ const openAmount = clampDoorOperationState(operationState);
16
+ return doorType === 'garage-sectional'
17
+ ? openAmount * SECTIONAL_GARAGE_RENDER_OPEN_SCALE
18
+ : openAmount;
19
+ }
20
+ export function getGarageVisibleOpeningRatio(doorType, operationState) {
21
+ if (doorType === 'garage-sectional') {
22
+ return Math.min(1, clampDoorOperationState(operationState) / SECTIONAL_GARAGE_RENDER_OPEN_SCALE);
23
+ }
24
+ return clampDoorOperationState(operationState);
25
+ }
@@ -0,0 +1,3 @@
1
+ import type { SlabNode } from '../schema';
2
+ export declare function getRenderableSlabPolygon(slabNode: SlabNode): Array<[number, number]>;
3
+ //# sourceMappingURL=slab-polygon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slab-polygon.d.ts","sourceRoot":"","sources":["../../src/lib/slab-polygon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQzC,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAOpF"}
@@ -0,0 +1,58 @@
1
+ import { insetPolygonFromCentroid, simplifyClosedPolygon } from './polygon-geometry';
2
+ /** Half of default wall thickness — used to extend slab geometry under walls */
3
+ const SLAB_OUTSET = 0.05;
4
+ const AUTO_SLAB_INSET = 0.02;
5
+ const AUTO_SLAB_SIMPLIFY_TOLERANCE = 0.08;
6
+ export function getRenderableSlabPolygon(slabNode) {
7
+ return slabNode.autoFromWalls
8
+ ? simplifyClosedPolygon(insetPolygonFromCentroid(slabNode.polygon, AUTO_SLAB_INSET), AUTO_SLAB_SIMPLIFY_TOLERANCE)
9
+ : outsetPolygon(slabNode.polygon, SLAB_OUTSET);
10
+ }
11
+ /**
12
+ * Expand a polygon outward by a uniform distance.
13
+ * Offsets each edge outward then intersects consecutive offset edges.
14
+ */
15
+ function outsetPolygon(polygon, amount) {
16
+ const n = polygon.length;
17
+ if (n < 3)
18
+ return polygon;
19
+ // Determine winding via signed area
20
+ let area2 = 0;
21
+ for (let i = 0; i < n; i++) {
22
+ const j = (i + 1) % n;
23
+ area2 += polygon[i][0] * polygon[j][1] - polygon[j][0] * polygon[i][1];
24
+ }
25
+ const s = area2 >= 0 ? 1 : -1;
26
+ // Offset each edge outward by amount
27
+ const offEdges = [];
28
+ for (let i = 0; i < n; i++) {
29
+ const j = (i + 1) % n;
30
+ const dx = polygon[j][0] - polygon[i][0];
31
+ const dz = polygon[j][1] - polygon[i][1];
32
+ const len = Math.sqrt(dx * dx + dz * dz);
33
+ if (len < 1e-9) {
34
+ offEdges.push([polygon[i][0], polygon[i][1], dx, dz]);
35
+ continue;
36
+ }
37
+ const nx = ((s * dz) / len) * amount;
38
+ const nz = ((s * -dx) / len) * amount;
39
+ offEdges.push([polygon[i][0] + nx, polygon[i][1] + nz, dx, dz]);
40
+ }
41
+ // Intersect consecutive offset edges to get new vertices
42
+ const result = [];
43
+ for (let i = 0; i < n; i++) {
44
+ const j = (i + 1) % n;
45
+ const [ax, az, adx, adz] = offEdges[i];
46
+ const [bx, bz, bdx, bdz] = offEdges[j];
47
+ const denom = adx * bdz - adz * bdx;
48
+ if (Math.abs(denom) < 1e-9) {
49
+ // Parallel edges — use offset endpoint
50
+ result.push([ax + adx, az + adz]);
51
+ }
52
+ else {
53
+ const t = ((bx - ax) * bdz - (bz - az) * bdx) / denom;
54
+ result.push([ax + t * adx, az + t * adz]);
55
+ }
56
+ }
57
+ return result;
58
+ }
@@ -1,15 +1,17 @@
1
- import { type MaterialPresetPayload, type MaterialTarget } from './schema/material';
1
+ import { type MaterialPresetPayload } from './schema/material';
2
2
  export type MaterialCatalogItem = {
3
3
  id: string;
4
4
  label: string;
5
+ category: MaterialCategory;
5
6
  description?: string;
6
- targets: MaterialTarget[];
7
7
  previewThumbnailUrl?: string;
8
8
  previewColor?: string;
9
9
  preset: MaterialPresetPayload;
10
10
  };
11
+ export declare const MATERIAL_CATEGORIES: readonly ["wood", "wallpaper", "parquet", "granite", "marble", "other"];
12
+ export type MaterialCategory = (typeof MATERIAL_CATEGORIES)[number];
11
13
  export declare const MATERIAL_CATALOG: MaterialCatalogItem[];
12
- export declare function getMaterialsForTarget(target: MaterialTarget): MaterialCatalogItem[];
14
+ export declare function getMaterialsForCategory(category: MaterialCategory): MaterialCatalogItem[];
13
15
  export declare function getCatalogMaterialById(id?: string): MaterialCatalogItem | undefined;
14
16
  export declare const LIBRARY_MATERIAL_REF_PREFIX = "library:";
15
17
  export declare function toLibraryMaterialRef(id: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"material-library.d.ts","sourceRoot":"","sources":["../src/material-library.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EAEpB,MAAM,mBAAmB,CAAA;AAE1B,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,qBAAqB,CAAA;CAC9B,CAAA;AAkCD,eAAO,MAAM,gBAAgB,EAAE,mBAAmB,EAuiBjD,CAAA;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,mBAAmB,EAAE,CAEnF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAGnF;AAED,eAAO,MAAM,2BAA2B,aAAa,CAAA;AAErD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,UAE9C;AAED,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,iBAItE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,qBAAqB,GAAG,IAAI,CAIhG"}
1
+ {"version":3,"file":"material-library.d.ts","sourceRoot":"","sources":["../src/material-library.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAA;AAE1B,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,qBAAqB,CAAA;CAC9B,CAAA;AAED,eAAO,MAAM,mBAAmB,yEAOtB,CAAA;AACV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,eAAO,MAAM,gBAAgB,EAAE,mBAAmB,EAiiBjD,CAAA;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAEzF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAGnF;AAED,eAAO,MAAM,2BAA2B,aAAa,CAAA;AAErD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,UAE9C;AAED,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,iBAItE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,qBAAqB,GAAG,IAAI,CAIhG"}