@inweb/viewer-three 26.10.6 → 26.11.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 (143) hide show
  1. package/README.md +7 -4
  2. package/dist/{plugins → extensions}/components/AxesHelperComponent.js +23 -1
  3. package/dist/extensions/components/AxesHelperComponent.js.map +1 -0
  4. package/dist/extensions/components/AxesHelperComponent.min.js +24 -0
  5. package/dist/{plugins → extensions}/components/AxesHelperComponent.module.js +24 -2
  6. package/dist/extensions/components/AxesHelperComponent.module.js.map +1 -0
  7. package/dist/{plugins → extensions}/components/ExtentsHelperComponent.js +18 -0
  8. package/dist/extensions/components/ExtentsHelperComponent.js.map +1 -0
  9. package/dist/{plugins/components/AxesHelperComponent.min.js → extensions/components/ExtentsHelperComponent.min.js} +1 -1
  10. package/dist/{plugins → extensions}/components/ExtentsHelperComponent.module.js +19 -1
  11. package/dist/extensions/components/ExtentsHelperComponent.module.js.map +1 -0
  12. package/dist/extensions/components/GridHelperComponent.js.map +1 -0
  13. package/dist/extensions/components/GridHelperComponent.module.js.map +1 -0
  14. package/dist/extensions/components/LightHelperComponent.js.map +1 -0
  15. package/dist/extensions/components/LightHelperComponent.module.js.map +1 -0
  16. package/dist/extensions/components/RoomEnvironmentComponent.js.map +1 -0
  17. package/dist/extensions/components/RoomEnvironmentComponent.module.js.map +1 -0
  18. package/dist/extensions/components/StatsPanelComponent.js.map +1 -0
  19. package/dist/extensions/components/StatsPanelComponent.module.js.map +1 -0
  20. package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.js +2 -3
  21. package/dist/extensions/loaders/GLTFCloudLoader.js.map +1 -0
  22. package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.min.js +1 -1
  23. package/dist/{plugins → extensions}/loaders/GLTFCloudLoader.module.js +2 -3
  24. package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +1 -0
  25. package/dist/extensions/loaders/GLTFFileLoader.js +2499 -0
  26. package/dist/extensions/loaders/GLTFFileLoader.js.map +1 -0
  27. package/dist/extensions/loaders/GLTFFileLoader.min.js +24 -0
  28. package/dist/extensions/loaders/GLTFFileLoader.module.js +74 -0
  29. package/dist/extensions/loaders/GLTFFileLoader.module.js.map +1 -0
  30. package/dist/{plugins → extensions}/loaders/IFCXLoader.js +5 -7
  31. package/dist/extensions/loaders/IFCXLoader.js.map +1 -0
  32. package/dist/{plugins → extensions}/loaders/IFCXLoader.min.js +1 -1
  33. package/dist/{plugins → extensions}/loaders/IFCXLoader.module.js +5 -7
  34. package/dist/extensions/loaders/IFCXLoader.module.js.map +1 -0
  35. package/dist/{plugins → extensions}/loaders/PotreeLoader.js +1 -2
  36. package/dist/extensions/loaders/PotreeLoader.js.map +1 -0
  37. package/dist/{plugins → extensions}/loaders/PotreeLoader.min.js +1 -1
  38. package/dist/{plugins → extensions}/loaders/PotreeLoader.module.js +1 -2
  39. package/dist/extensions/loaders/PotreeLoader.module.js.map +1 -0
  40. package/dist/viewer-three.js +1015 -2926
  41. package/dist/viewer-three.js.map +1 -1
  42. package/dist/viewer-three.min.js +3 -3
  43. package/dist/viewer-three.module.js +847 -356
  44. package/dist/viewer-three.module.js.map +1 -1
  45. package/{plugins → extensions}/components/AxesHelperComponent.ts +31 -2
  46. package/{plugins → extensions}/components/ExtentsHelperComponent.ts +25 -0
  47. package/{plugins → extensions}/loaders/GLTFCloudLoader.ts +2 -3
  48. package/{src/Viewer → extensions}/loaders/GLTFFileLoader.ts +21 -12
  49. package/{plugins → extensions}/loaders/IFCX/IFCXCloudLoader.ts +5 -5
  50. package/{plugins → extensions}/loaders/IFCX/IFCXFileLoader.ts +3 -4
  51. package/{plugins → extensions}/loaders/Potree/PotreeFileLoader.ts +3 -4
  52. package/lib/Viewer/Viewer.d.ts +27 -20
  53. package/lib/Viewer/commands/GetSelected2.d.ts +2 -0
  54. package/lib/Viewer/commands/SelectModel.d.ts +1 -1
  55. package/lib/Viewer/commands/SetSelected2.d.ts +2 -0
  56. package/lib/Viewer/components/SelectionComponent.d.ts +1 -3
  57. package/lib/Viewer/components/index.d.ts +6 -6
  58. package/lib/Viewer/draggers/MeasureLineDragger.d.ts +7 -1
  59. package/lib/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.d.ts +0 -1
  60. package/lib/Viewer/loaders/GLTFBinaryExtension.d.ts +5 -0
  61. package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +2 -2
  62. package/lib/Viewer/loaders/{GLTFFileLoader.d.ts → GLTFFileDynamicLoader.d.ts} +7 -1
  63. package/lib/Viewer/loaders/GLTFLoadingManager.d.ts +4 -3
  64. package/lib/Viewer/loaders/RangesLoader.d.ts +15 -0
  65. package/lib/Viewer/loaders/index.d.ts +22 -14
  66. package/lib/Viewer/measurement/Snapper.d.ts +15 -0
  67. package/lib/Viewer/measurement/UnitConverter.d.ts +63 -0
  68. package/lib/Viewer/measurement/UnitFormatter.d.ts +4 -0
  69. package/lib/Viewer/models/IModelImpl.d.ts +10 -8
  70. package/lib/Viewer/models/ModelImpl.d.ts +7 -5
  71. package/package.json +11 -11
  72. package/src/Viewer/Viewer.ts +120 -88
  73. package/src/Viewer/commands/ClearSelected.ts +3 -1
  74. package/src/Viewer/commands/GetModels.ts +1 -1
  75. package/src/Viewer/commands/GetSelected.ts +2 -2
  76. package/src/Viewer/commands/GetSelected2.ts +34 -0
  77. package/src/Viewer/commands/HideSelected.ts +3 -1
  78. package/src/Viewer/commands/SelectModel.ts +5 -5
  79. package/src/Viewer/commands/SetSelected.ts +9 -10
  80. package/src/Viewer/commands/SetSelected2.ts +42 -0
  81. package/src/Viewer/commands/ZoomToObjects.ts +5 -6
  82. package/src/Viewer/commands/ZoomToSelected.ts +3 -1
  83. package/src/Viewer/commands/index.ts +4 -0
  84. package/src/Viewer/components/CameraComponent.ts +6 -1
  85. package/src/Viewer/components/ExtentsComponent.ts +4 -1
  86. package/src/Viewer/components/SelectionComponent.ts +7 -30
  87. package/src/Viewer/components/index.ts +6 -6
  88. package/src/Viewer/draggers/MeasureLineDragger.ts +84 -226
  89. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +263 -34
  90. package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +20 -10
  91. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +4 -1
  92. package/src/Viewer/loaders/GLTFBinaryExtension.ts +91 -0
  93. package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +13 -19
  94. package/src/Viewer/loaders/GLTFFileDynamicLoader.ts +145 -0
  95. package/src/Viewer/loaders/GLTFLoadingManager.ts +5 -4
  96. package/src/Viewer/loaders/RangesLoader.ts +95 -0
  97. package/src/Viewer/loaders/index.ts +24 -16
  98. package/src/Viewer/measurement/Snapper.ts +208 -0
  99. package/src/Viewer/measurement/UnitConverter.ts +47 -0
  100. package/src/Viewer/measurement/UnitFormatter.ts +95 -0
  101. package/src/Viewer/models/IModelImpl.ts +15 -8
  102. package/src/Viewer/models/ModelImpl.ts +48 -17
  103. package/src/index-umd.ts +1 -1
  104. package/dist/plugins/components/AxesHelperComponent.js.map +0 -1
  105. package/dist/plugins/components/AxesHelperComponent.module.js.map +0 -1
  106. package/dist/plugins/components/ExtentsHelperComponent.js.map +0 -1
  107. package/dist/plugins/components/ExtentsHelperComponent.min.js +0 -24
  108. package/dist/plugins/components/ExtentsHelperComponent.module.js.map +0 -1
  109. package/dist/plugins/components/GridHelperComponent.js.map +0 -1
  110. package/dist/plugins/components/GridHelperComponent.module.js.map +0 -1
  111. package/dist/plugins/components/LightHelperComponent.js.map +0 -1
  112. package/dist/plugins/components/LightHelperComponent.module.js.map +0 -1
  113. package/dist/plugins/components/RoomEnvironmentComponent.js.map +0 -1
  114. package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +0 -1
  115. package/dist/plugins/components/StatsPanelComponent.js.map +0 -1
  116. package/dist/plugins/components/StatsPanelComponent.module.js.map +0 -1
  117. package/dist/plugins/loaders/GLTFCloudLoader.js.map +0 -1
  118. package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +0 -1
  119. package/dist/plugins/loaders/IFCXLoader.js.map +0 -1
  120. package/dist/plugins/loaders/IFCXLoader.module.js.map +0 -1
  121. package/dist/plugins/loaders/PotreeLoader.js.map +0 -1
  122. package/dist/plugins/loaders/PotreeLoader.module.js.map +0 -1
  123. /package/dist/{plugins → extensions}/components/GridHelperComponent.js +0 -0
  124. /package/dist/{plugins → extensions}/components/GridHelperComponent.min.js +0 -0
  125. /package/dist/{plugins → extensions}/components/GridHelperComponent.module.js +0 -0
  126. /package/dist/{plugins → extensions}/components/LightHelperComponent.js +0 -0
  127. /package/dist/{plugins → extensions}/components/LightHelperComponent.min.js +0 -0
  128. /package/dist/{plugins → extensions}/components/LightHelperComponent.module.js +0 -0
  129. /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.js +0 -0
  130. /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.min.js +0 -0
  131. /package/dist/{plugins → extensions}/components/RoomEnvironmentComponent.module.js +0 -0
  132. /package/dist/{plugins → extensions}/components/StatsPanelComponent.js +0 -0
  133. /package/dist/{plugins → extensions}/components/StatsPanelComponent.min.js +0 -0
  134. /package/dist/{plugins → extensions}/components/StatsPanelComponent.module.js +0 -0
  135. /package/{plugins → extensions}/components/GridHelperComponent.ts +0 -0
  136. /package/{plugins → extensions}/components/LightHelperComponent.ts +0 -0
  137. /package/{plugins → extensions}/components/RoomEnvironmentComponent.ts +0 -0
  138. /package/{plugins → extensions}/components/StatsPanelComponent.ts +0 -0
  139. /package/{plugins → extensions}/loaders/IFCX/IFCXLoader.ts +0 -0
  140. /package/{plugins → extensions}/loaders/IFCX/index.ts +0 -0
  141. /package/{plugins → extensions}/loaders/IFCX/render.js +0 -0
  142. /package/{plugins → extensions}/loaders/Potree/PotreeModelImpl.ts +0 -0
  143. /package/{plugins → extensions}/loaders/Potree/index.ts +0 -0
@@ -0,0 +1,208 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3
+ // All rights reserved.
4
+ //
5
+ // This software and its documentation and related materials are owned by
6
+ // the Alliance. The software may only be incorporated into application
7
+ // programs owned by members of the Alliance, subject to a signed
8
+ // Membership Agreement and Supplemental Software License Agreement with the
9
+ // Alliance. The structure and organization of this software are the valuable
10
+ // trade secrets of the Alliance and its suppliers. The software is also
11
+ // protected by copyright law and international treaty provisions. Application
12
+ // programs incorporating this software must include the following statement
13
+ // with their copyright notices:
14
+ //
15
+ // This application incorporates Open Design Alliance software pursuant to a
16
+ // license agreement with Open Design Alliance.
17
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
18
+ // All rights reserved.
19
+ //
20
+ // By use of this software, its documentation or related materials, you
21
+ // acknowledge and accept the above terms.
22
+ ///////////////////////////////////////////////////////////////////////////////
23
+
24
+ import {
25
+ Camera,
26
+ EdgesGeometry,
27
+ Intersection,
28
+ Line3,
29
+ MathUtils,
30
+ Object3D,
31
+ Plane,
32
+ Raycaster,
33
+ Vector2,
34
+ Vector3,
35
+ WebGLRenderer,
36
+ } from "three";
37
+
38
+ const DESKTOP_SNAP_DISTANCE = 10;
39
+ const MOBILE_SNAP_DISTANCE = 50;
40
+
41
+ const _vertex = new Vector3();
42
+ const _start = new Vector3();
43
+ const _end = new Vector3();
44
+ const _line = new Line3();
45
+ const _center = new Vector3();
46
+ const _projection = new Vector3();
47
+
48
+ export class Snapper {
49
+ public camera: Camera;
50
+ public renderer: WebGLRenderer;
51
+ public canvas: HTMLCanvasElement;
52
+ private raycaster: Raycaster;
53
+ private detectRadiusInPixels: number;
54
+ private edgesCache: WeakMap<any, EdgesGeometry>;
55
+
56
+ constructor(camera: Camera, renderer: WebGLRenderer, canvas: HTMLCanvasElement) {
57
+ this.camera = camera;
58
+ this.renderer = renderer;
59
+ this.canvas = canvas;
60
+
61
+ this.raycaster = new Raycaster();
62
+ this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
63
+ this.edgesCache = new WeakMap();
64
+ }
65
+
66
+ isMobile(): boolean {
67
+ if (typeof navigator === "undefined") return false;
68
+
69
+ // ===================== AI-CODE-START ======================
70
+ // Source: Claude Sonnet 4
71
+ // Date: 2025-09-09
72
+ // Reviewer: roman.mochalov@opendesign.com
73
+ // Issue: CLOUD-5799
74
+
75
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
76
+
77
+ // ===================== AI-CODE-END ======================
78
+ }
79
+
80
+ getMousePosition(event: MouseEvent, target: Vector2): Vector2 {
81
+ return target.set(event.clientX, event.clientY);
82
+ }
83
+
84
+ getPointerIntersects(mouse: Vector2, objects: Object3D[]): Array<Intersection<Object3D>> {
85
+ const rect = this.canvas.getBoundingClientRect();
86
+ const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
87
+ const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
88
+
89
+ const coords = new Vector2(x, y);
90
+ this.raycaster.setFromCamera(coords, this.camera);
91
+
92
+ this.raycaster.params = {
93
+ Mesh: {},
94
+ Line: { threshold: 0.05 },
95
+ Line2: { threshold: 0.05 },
96
+ LOD: {},
97
+ Points: { threshold: 0.01 },
98
+ Sprite: {},
99
+ };
100
+
101
+ let intersects = this.raycaster.intersectObjects(objects, false);
102
+
103
+ (this.renderer.clippingPlanes || []).forEach((plane: Plane) => {
104
+ intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
105
+ });
106
+
107
+ return intersects;
108
+ }
109
+
110
+ getDetectRadius(point: Vector3): number {
111
+ const camera: any = this.camera;
112
+
113
+ // ===================== AI-CODE-START ======================
114
+ // Source: Gemini 2.5 Pro
115
+ // Date: 2025-08-27
116
+ // Reviewer: roman.mochalov@opendesign.com
117
+ // Issue: CLOUD-5799
118
+ // Notes: Originally AI-generated, modified manually
119
+
120
+ if (camera.isOrthographicCamera) {
121
+ const fieldHeight = (camera.top - camera.bottom) / camera.zoom;
122
+
123
+ const canvasHeight = this.canvas.height;
124
+ const worldUnitsPerPixel = fieldHeight / canvasHeight;
125
+
126
+ return this.detectRadiusInPixels * worldUnitsPerPixel;
127
+ }
128
+
129
+ if (camera.isPerspectiveCamera) {
130
+ const distance = camera.position.distanceTo(point);
131
+ const fieldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
132
+
133
+ const canvasHeight = this.canvas.height;
134
+ const worldUnitsPerPixel = fieldHeight / canvasHeight;
135
+
136
+ return this.detectRadiusInPixels * worldUnitsPerPixel;
137
+ }
138
+
139
+ // ===================== AI-CODE-END ======================
140
+
141
+ return 0.1;
142
+ }
143
+
144
+ getSnapPoint(mouse: Vector2, objects: Object3D[]): Vector3 {
145
+ const intersections = this.getPointerIntersects(mouse, objects);
146
+ if (intersections.length === 0) return undefined;
147
+
148
+ // ===================== AI-CODE-START ======================
149
+ // Source: Gemini 2.5 Pro
150
+ // Date: 2025-08-20
151
+ // Reviewer: roman.mochalov@opendesign.com
152
+ // Issue: CLOUD-5799
153
+ // Notes: Originally AI-generated, modified manually
154
+
155
+ const object: any = intersections[0].object;
156
+ const intersectionPoint = intersections[0].point;
157
+ const localPoint = object.worldToLocal(intersectionPoint.clone());
158
+
159
+ let snapPoint: Vector3;
160
+ let snapDistance = this.getDetectRadius(intersectionPoint);
161
+
162
+ const geometry = object.geometry;
163
+
164
+ const positions = geometry.attributes.position.array;
165
+ for (let i = 0; i < positions.length; i += 3) {
166
+ _vertex.set(positions[i], positions[i + 1], positions[i + 2]);
167
+ const distance = _vertex.distanceTo(localPoint);
168
+ if (distance < snapDistance) {
169
+ snapDistance = distance;
170
+ snapPoint = _vertex.clone();
171
+ }
172
+ }
173
+ if (snapPoint) return object.localToWorld(snapPoint);
174
+
175
+ let edges = this.edgesCache.get(geometry);
176
+ if (!edges) {
177
+ edges = new EdgesGeometry(geometry);
178
+ this.edgesCache.set(geometry, edges);
179
+ }
180
+
181
+ const edgePositions = edges.attributes.position.array;
182
+ for (let i = 0; i < edgePositions.length; i += 6) {
183
+ _start.set(edgePositions[i], edgePositions[i + 1], edgePositions[i + 2]);
184
+ _end.set(edgePositions[i + 3], edgePositions[i + 4], edgePositions[i + 5]);
185
+ _line.set(_start, _end);
186
+
187
+ _line.getCenter(_center);
188
+ const centerDistance = _center.distanceTo(localPoint);
189
+ if (centerDistance < snapDistance) {
190
+ snapDistance = centerDistance;
191
+ snapPoint = _center.clone();
192
+ continue;
193
+ }
194
+
195
+ _line.closestPointToPoint(localPoint, true, _projection);
196
+ const lineDistance = _projection.distanceTo(localPoint);
197
+ if (lineDistance < snapDistance) {
198
+ snapDistance = lineDistance;
199
+ snapPoint = _projection.clone();
200
+ }
201
+ }
202
+ if (snapPoint) return object.localToWorld(snapPoint);
203
+
204
+ // ===================== AI-CODE-END ======================
205
+
206
+ return intersectionPoint.clone();
207
+ }
208
+ }
@@ -0,0 +1,47 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3
+ // All rights reserved.
4
+ //
5
+ // This software and its documentation and related materials are owned by
6
+ // the Alliance. The software may only be incorporated into application
7
+ // programs owned by members of the Alliance, subject to a signed
8
+ // Membership Agreement and Supplemental Software License Agreement with the
9
+ // Alliance. The structure and organization of this software are the valuable
10
+ // trade secrets of the Alliance and its suppliers. The software is also
11
+ // protected by copyright law and international treaty provisions. Application
12
+ // programs incorporating this software must include the following statement
13
+ // with their copyright notices:
14
+ //
15
+ // This application incorporates Open Design Alliance software pursuant to a
16
+ // license agreement with Open Design Alliance.
17
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
18
+ // All rights reserved.
19
+ //
20
+ // By use of this software, its documentation or related materials, you
21
+ // acknowledge and accept the above terms.
22
+ ///////////////////////////////////////////////////////////////////////////////
23
+
24
+ // Model units for the user to choose from.
25
+
26
+ export const ModelUnits = {
27
+ Meters: { name: "Meters", type: "m", scale: 1.0 },
28
+ Centimeters: { name: "Centimeters", type: "cm", scale: 0.01 },
29
+ Millimeters: { name: "Millimeters", type: "mm", scale: 0.001 },
30
+ Feet: { name: "Feet", type: "ft", scale: 0.3048 },
31
+ Inches: { name: "Inches", type: "in", scale: 0.0254 },
32
+ Yards: { name: "Yards", type: "yd", scale: 0.9144 },
33
+ Kilometers: { name: "Kilometers", type: "km", scale: 1000.0 },
34
+ Miles: { name: "Miles", type: "mi", scale: 1609.344 },
35
+ Micrometers: { name: "Micrometers", type: "µm", scale: 0.000001 },
36
+ Mils: { name: "Mils", type: "mil", scale: 0.0000254 },
37
+ MicroInches: { name: "Micro-inches", type: "µin", scale: 0.0000000254 },
38
+ Default: { name: "File units", type: "unit", scale: 1.0 },
39
+ };
40
+
41
+ // Convert distance from unit to unit.
42
+
43
+ export function convertUnits(fromUnits: string, toUnits: string, distance: number) {
44
+ const fromFactor = 1 / (ModelUnits[fromUnits] || ModelUnits.Default).scale;
45
+ const toFactor = (ModelUnits[toUnits] || ModelUnits.Default).scale || 1;
46
+ return distance * fromFactor * toFactor;
47
+ }
@@ -0,0 +1,95 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3
+ // All rights reserved.
4
+ //
5
+ // This software and its documentation and related materials are owned by
6
+ // the Alliance. The software may only be incorporated into application
7
+ // programs owned by members of the Alliance, subject to a signed
8
+ // Membership Agreement and Supplemental Software License Agreement with the
9
+ // Alliance. The structure and organization of this software are the valuable
10
+ // trade secrets of the Alliance and its suppliers. The software is also
11
+ // protected by copyright law and international treaty provisions. Application
12
+ // programs incorporating this software must include the following statement
13
+ // with their copyright notices:
14
+ //
15
+ // This application incorporates Open Design Alliance software pursuant to a
16
+ // license agreement with Open Design Alliance.
17
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
18
+ // All rights reserved.
19
+ //
20
+ // By use of this software, its documentation or related materials, you
21
+ // acknowledge and accept the above terms.
22
+ ///////////////////////////////////////////////////////////////////////////////
23
+
24
+ import { ModelUnits } from "./UnitConverter";
25
+
26
+ // Returns a standard string representation of the display unit.
27
+
28
+ export function getDisplayUnit(units: string) {
29
+ return (ModelUnits[units] || ModelUnits.Default).type;
30
+ }
31
+
32
+ // ===================== AI-CODE-START ======================
33
+ // Source: Claude Sonnet 4.5
34
+ // Date: 2025-10-08
35
+ // Reviewer: roman.mochalov@opendesign.com
36
+ // Issue: CLOUD-5963
37
+
38
+ // Calculates recommended precision for small values (|value| < 1) to avoid showing "0.00".
39
+
40
+ export function calculatePrecision(value: number) {
41
+ const distance = Math.abs(value);
42
+
43
+ if (distance >= 1000) return 0;
44
+ if (distance >= 10) return 1;
45
+ if (distance >= 0.1) return 2;
46
+ if (distance >= 0.001) return 3;
47
+
48
+ return distance > 0 ? Math.floor(-Math.log10(distance)) + 1 : 2;
49
+ }
50
+
51
+ // Calculates the minimal distance for the sepecified precision.
52
+
53
+ export function calculateDistance(precision: any): number {
54
+ let digits: number;
55
+
56
+ if (precision === "Auto") digits = 2;
57
+ else if (Number.isFinite(precision)) digits = precision;
58
+ else digits = parseFloat(precision);
59
+
60
+ if (!Number.isFinite(digits) || digits < 0) digits = 2;
61
+ else if (digits > 10) digits = 10;
62
+
63
+ return Math.pow(10, -digits);
64
+ }
65
+
66
+ // ===================== AI-CODE-END ======================
67
+
68
+ // Formats a distance with units.
69
+
70
+ function formatNumber(distance: number, digits: number, precision: any) {
71
+ let result = distance.toFixed(digits);
72
+ if (precision === "Auto") result = result.replace(/\.0+$/, "").replace(/\.$/, "");
73
+ if (+result !== distance) result = "~ " + result;
74
+ return result;
75
+ }
76
+
77
+ export function formatDistance(distance: number, units: string, precision: any = 2) {
78
+ let digits: number;
79
+
80
+ if (precision === "Auto") digits = calculatePrecision(distance);
81
+ else if (Number.isFinite(precision)) digits = precision;
82
+ else digits = parseFloat(precision);
83
+
84
+ if (!Number.isFinite(digits)) digits = 2;
85
+ else if (digits < 0) digits = 0;
86
+ else if (digits > 10) digits = 10;
87
+
88
+ if (ModelUnits[units]) {
89
+ return formatNumber(distance, digits, precision) + " " + ModelUnits[units].type;
90
+ } else if (units) {
91
+ return formatNumber(distance, digits, precision) + " " + units;
92
+ } else {
93
+ return formatNumber(distance, digits, precision);
94
+ }
95
+ }
@@ -22,18 +22,21 @@
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
24
  import { Box3, Object3D } from "three";
25
- import { ILoader, IViewer } from "@inweb/viewer-core";
25
+ import { IModel } from "@inweb/viewer-core";
26
26
 
27
27
  /**
28
- * Model interface.
28
+ * Basic model implementation.
29
29
  */
30
- export interface IModelImpl {
31
- handle: string;
30
+ export interface IModelImpl extends IModel {
32
31
  scene: Object3D;
33
- loader: ILoader;
34
- viewer: IViewer;
35
32
 
36
- dispose(): void;
33
+ getUnits(): string;
34
+
35
+ getUnitScale(): number;
36
+
37
+ getUnitString(): string;
38
+
39
+ getPrecision(): number;
37
40
 
38
41
  getExtents(target: Box3): Box3;
39
42
 
@@ -41,10 +44,14 @@ export interface IModelImpl {
41
44
 
42
45
  getVisibleObjects(): Object3D[];
43
46
 
44
- hasObject(objects: Object3D): boolean;
47
+ hasObject(object: Object3D): boolean;
48
+
49
+ hasHandle(handle: string): boolean;
45
50
 
46
51
  getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
47
52
 
53
+ getOwnHandles(handles: string | string[]): string[];
54
+
48
55
  getObjectsByHandles(handles: string | string[]): Object3D[];
49
56
 
50
57
  getHandlesByObjects(objects: Object3D | Object3D[]): string[];
@@ -22,21 +22,15 @@
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
24
  import { Box3, Object3D, Vector3 } from "three";
25
- import { ILoader } from "@inweb/viewer-core";
26
-
27
25
  import { IModelImpl } from "./IModelImpl";
28
- import { Viewer } from "../Viewer";
29
-
30
- // Basic model implementation.
26
+ import { convertUnits } from "../measurement/UnitConverter";
27
+ import { getDisplayUnit } from "../measurement/UnitFormatter";
31
28
 
32
29
  export class ModelImpl implements IModelImpl {
33
- public handle: string;
30
+ public id: string;
34
31
  public scene: Object3D;
35
- public loader: ILoader;
36
- public viewer: Viewer;
37
32
 
38
33
  constructor(scene: Object3D) {
39
- this.handle = "1";
40
34
  this.scene = scene;
41
35
  }
42
36
 
@@ -81,6 +75,22 @@ export class ModelImpl implements IModelImpl {
81
75
  this.scene.clear();
82
76
  }
83
77
 
78
+ getUnits(): string {
79
+ return "Meters";
80
+ }
81
+
82
+ getUnitScale(): number {
83
+ return convertUnits(this.getUnits(), "Meters", 1);
84
+ }
85
+
86
+ getUnitString(): string {
87
+ return getDisplayUnit(this.getUnits());
88
+ }
89
+
90
+ getPrecision(): number {
91
+ return 2;
92
+ }
93
+
84
94
  getExtents(target: Box3): Box3 {
85
95
  this.scene.traverseVisible((object) => !object.children.length && target.expandByObject(object));
86
96
  return target;
@@ -106,27 +116,49 @@ export class ModelImpl implements IModelImpl {
106
116
  return false;
107
117
  }
108
118
 
119
+ hasHandle(handle: string): boolean {
120
+ return !handle.includes(":") || handle.split(":", 1)[0] === this.id + "";
121
+ }
122
+
109
123
  getOwnObjects(objects: Object3D | Object3D[]): Object3D[] {
110
124
  if (!Array.isArray(objects)) objects = [objects];
111
125
  return objects.filter((object) => this.hasObject(object));
112
126
  }
113
127
 
128
+ getOwnHandles(handles: string | string[]): string[] {
129
+ if (!Array.isArray(handles)) handles = [handles];
130
+ return handles.filter((handle) => this.hasHandle(handle));
131
+ }
132
+
114
133
  getObjectsByHandles(handles: string | string[]): Object3D[] {
115
- const handleSet = new Set(handles);
134
+ const ownHandles = this.getOwnHandles(handles);
135
+ if (ownHandles.length === 0) return [];
136
+
137
+ const handleSet = new Set(ownHandles.map((handle) => handle.slice(handle.indexOf(":") + 1)));
138
+
116
139
  const objects = [];
117
- this.scene.traverse((object) => handleSet.has(object.userData.handle) && objects.push(object));
140
+ this.scene.traverse((object) => {
141
+ const handle = object.userData.handle;
142
+ if (handle && handleSet.has(handle)) objects.push(object);
143
+ });
144
+
118
145
  return objects;
119
146
  }
120
147
 
121
148
  getHandlesByObjects(objects: Object3D | Object3D[]): string[] {
122
- if (!Array.isArray(objects)) objects = [objects];
123
- const handlesSet = new Set<string>();
124
- this.getOwnObjects(objects).forEach((object) => handlesSet.add(object.userData.handle));
125
- return Array.from(handlesSet);
149
+ const ownObjects = this.getOwnObjects(objects);
150
+ if (ownObjects.length === 0) return [];
151
+
152
+ const handleSet = new Set<string>();
153
+ ownObjects.forEach((object) => {
154
+ const handle = object.userData.handle;
155
+ if (handle) handleSet.add(`${this.id}:${handle}`);
156
+ });
157
+
158
+ return Array.from(handleSet);
126
159
  }
127
160
 
128
161
  hideObjects(objects: Object3D | Object3D[]): this {
129
- if (!Array.isArray(objects)) objects = [objects];
130
162
  this.getOwnObjects(objects).forEach((object) => (object.visible = false));
131
163
  return this;
132
164
  }
@@ -144,7 +176,6 @@ export class ModelImpl implements IModelImpl {
144
176
  }
145
177
 
146
178
  showObjects(objects: Object3D | Object3D[]): this {
147
- if (!Array.isArray(objects)) objects = [objects];
148
179
  this.getOwnObjects(objects).forEach((object) => {
149
180
  object.visible = true;
150
181
  object.traverseAncestors((parent) => (parent.visible = true));
package/src/index-umd.ts CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  export * from "./index";
25
25
 
26
- // add the global exports (was removed in 0.160.0) to expose the plugins to Three.js code
26
+ // add the global exports (was removed in 0.160.0) to expose the extensions to Three.js code
27
27
 
28
28
  import * as THREE from "three";
29
29
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"AxesHelperComponent.js","sources":["../../../plugins/components/AxesHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { AxesHelper, Vector3 } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass AxesHelperComponent implements IComponent {\n private viewer: Viewer;\n private axesHelper1: AxesHelper;\n private axesHelper2: AxesHelper;\n\n constructor(viewer: Viewer) {\n this.axesHelper1 = new AxesHelper(1);\n this.axesHelper2 = new AxesHelper(1);\n\n this.viewer = viewer;\n this.viewer.addEventListener(\"initialize\", this.syncHelper);\n this.viewer.addEventListener(\"geometryend\", this.syncHelper);\n this.viewer.addEventListener(\"clear\", this.syncHelper);\n }\n\n dispose() {\n this.axesHelper1.removeFromParent();\n this.axesHelper1.dispose();\n\n this.axesHelper2.removeFromParent();\n this.axesHelper2.dispose();\n\n this.viewer.removeEventListener(\"initialize\", this.syncHelper);\n this.viewer.removeEventListener(\"geometryend\", this.syncHelper);\n this.viewer.removeEventListener(\"clear\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.axesHelper1.removeFromParent();\n this.axesHelper2.removeFromParent();\n\n const size = this.viewer.extents.getSize(new Vector3()).length();\n const center = this.viewer.extents.getCenter(new Vector3());\n\n this.axesHelper1.position.set(0, 0, 0);\n this.axesHelper1.scale.setScalar(size);\n\n this.axesHelper2.position.copy(center);\n this.axesHelper2.scale.setScalar(size);\n\n this.viewer.helpers.add(this.axesHelper1);\n this.viewer.helpers.add(this.axesHelper2);\n };\n}\n\ncomponents.registerComponent(\"AxesHelperComponent\", (viewer) => new AxesHelperComponent(viewer));\n"],"names":["Vector3","AxesHelper","components"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0BA,MAAM,mBAAmB,CAAA;IAKvB,IAAA,WAAA,CAAY,MAAc,EAAA;YAsB1B,IAAA,CAAA,UAAU,GAAG,MAAK;IAChB,YAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;IACnC,YAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;IAEnC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAIA,aAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IAChE,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAIA,aAAO,EAAE,CAAC;IAE3D,YAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBAEtC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;gBACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBAEtC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;gBACzC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;IAC3C,QAAA,CAAC;YApCC,IAAI,CAAC,WAAW,GAAG,IAAIC,gBAAU,CAAC,CAAC,CAAC;YACpC,IAAI,CAAC,WAAW,GAAG,IAAIA,gBAAU,CAAC,CAAC,CAAC;IAEpC,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;YACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC5D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QACxD;QAEA,OAAO,GAAA;IACL,QAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;IACnC,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;IAE1B,QAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;IACnC,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;YAE1B,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QAC3D;IAkBD;AAEDC,0BAAU,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,MAAM,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AxesHelperComponent.module.js","sources":["../../../plugins/components/AxesHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { AxesHelper, Vector3 } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass AxesHelperComponent implements IComponent {\n private viewer: Viewer;\n private axesHelper1: AxesHelper;\n private axesHelper2: AxesHelper;\n\n constructor(viewer: Viewer) {\n this.axesHelper1 = new AxesHelper(1);\n this.axesHelper2 = new AxesHelper(1);\n\n this.viewer = viewer;\n this.viewer.addEventListener(\"initialize\", this.syncHelper);\n this.viewer.addEventListener(\"geometryend\", this.syncHelper);\n this.viewer.addEventListener(\"clear\", this.syncHelper);\n }\n\n dispose() {\n this.axesHelper1.removeFromParent();\n this.axesHelper1.dispose();\n\n this.axesHelper2.removeFromParent();\n this.axesHelper2.dispose();\n\n this.viewer.removeEventListener(\"initialize\", this.syncHelper);\n this.viewer.removeEventListener(\"geometryend\", this.syncHelper);\n this.viewer.removeEventListener(\"clear\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.axesHelper1.removeFromParent();\n this.axesHelper2.removeFromParent();\n\n const size = this.viewer.extents.getSize(new Vector3()).length();\n const center = this.viewer.extents.getCenter(new Vector3());\n\n this.axesHelper1.position.set(0, 0, 0);\n this.axesHelper1.scale.setScalar(size);\n\n this.axesHelper2.position.copy(center);\n this.axesHelper2.scale.setScalar(size);\n\n this.viewer.helpers.add(this.axesHelper1);\n this.viewer.helpers.add(this.axesHelper2);\n };\n}\n\ncomponents.registerComponent(\"AxesHelperComponent\", (viewer) => new AxesHelperComponent(viewer));\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAM,mBAAmB,CAAA;AAKvB,IAAA,WAAA,CAAY,MAAc,EAAA;QAsB1B,IAAA,CAAA,UAAU,GAAG,MAAK;AAChB,YAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;AACnC,YAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;AAEnC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;AAChE,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC;AAE3D,YAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;YAEtC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;YAEtC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC3C,QAAA,CAAC;QApCC,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC;AAEpC,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;QACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;IACxD;IAEA,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;AACnC,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;AAE1B,QAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;AACnC,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;QAE1B,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;IAC3D;AAkBD;AAED,UAAU,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,MAAM,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExtentsHelperComponent.js","sources":["../../../plugins/components/ExtentsHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { Box3, Box3Helper } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass ExtentsHelperComponent implements IComponent {\n private viewer: Viewer;\n private boxHelper: Box3Helper;\n\n constructor(viewer: Viewer) {\n this.boxHelper = new Box3Helper(new Box3(), \"#ff0000\");\n this.viewer = viewer;\n this.viewer.on(\"geometryend\", this.syncHelper);\n this.viewer.on(\"clear\", this.syncHelper);\n this.viewer.on(\"explode\", this.syncHelper);\n this.viewer.on(\"hide\", this.syncHelper);\n this.viewer.on(\"isolate\", this.syncHelper);\n this.viewer.on(\"show\", this.syncHelper);\n this.viewer.on(\"showall\", this.syncHelper);\n }\n\n dispose() {\n this.boxHelper.removeFromParent();\n this.boxHelper.dispose();\n\n this.viewer.off(\"geometryend\", this.syncHelper);\n this.viewer.off(\"clear\", this.syncHelper);\n this.viewer.off(\"explode\", this.syncHelper);\n this.viewer.off(\"hide\", this.syncHelper);\n this.viewer.off(\"isolate\", this.syncHelper);\n this.viewer.off(\"show\", this.syncHelper);\n this.viewer.off(\"showall\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.boxHelper.removeFromParent();\n\n if (this.viewer.extents.isEmpty()) return;\n\n this.boxHelper.box = this.viewer.extents.clone();\n this.viewer.helpers.add(this.boxHelper);\n };\n}\n\ncomponents.registerComponent(\"ExtentsHelperComponent\", (viewer) => new ExtentsHelperComponent(viewer));\n"],"names":["Box3Helper","Box3","components"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0BA,MAAM,sBAAsB,CAAA;IAI1B,IAAA,WAAA,CAAY,MAAc,EAAA;YAyB1B,IAAA,CAAA,UAAU,GAAG,MAAK;IAChB,YAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE;IAEjC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;oBAAE;IAEnC,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE;gBAChD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;IACzC,QAAA,CAAC;IA/BC,QAAA,IAAI,CAAC,SAAS,GAAG,IAAIA,gBAAU,CAAC,IAAIC,UAAI,EAAE,EAAE,SAAS,CAAC;IACtD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;YACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC5C;QAEA,OAAO,GAAA;IACL,QAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE;IACjC,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YAExB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC7C;IAUD;AAEDC,0BAAU,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,CAAC,MAAM,KAAK,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAC;;;;;;"}
@@ -1,24 +0,0 @@
1
- ///////////////////////////////////////////////////////////////////////////////
2
- // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3
- // All rights reserved.
4
- //
5
- // This software and its documentation and related materials are owned by
6
- // the Alliance. The software may only be incorporated into application
7
- // programs owned by members of the Alliance, subject to a signed
8
- // Membership Agreement and Supplemental Software License Agreement with the
9
- // Alliance. The structure and organization of this software are the valuable
10
- // trade secrets of the Alliance and its suppliers. The software is also
11
- // protected by copyright law and international treaty provisions. Application
12
- // programs incorporating this software must include the following statement
13
- // with their copyright notices:
14
- //
15
- // This application incorporates Open Design Alliance software pursuant to a
16
- // license agreement with Open Design Alliance.
17
- // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
18
- // All rights reserved.
19
- //
20
- // By use of this software, its documentation or related materials, you
21
- // acknowledge and accept the above terms.
22
- ///////////////////////////////////////////////////////////////////////////////
23
-
24
- !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("three"),require("@inweb/viewer-three")):"function"==typeof define&&define.amd?define(["three","@inweb/viewer-three"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).THREE,e.ODA.Three)}(this,function(e,i){"use strict";class s{constructor(i){this.syncHelper=()=>{this.boxHelper.removeFromParent(),this.viewer.extents.isEmpty()||(this.boxHelper.box=this.viewer.extents.clone(),this.viewer.helpers.add(this.boxHelper))},this.boxHelper=new e.Box3Helper(new e.Box3,"#ff0000"),this.viewer=i,this.viewer.on("geometryend",this.syncHelper),this.viewer.on("clear",this.syncHelper),this.viewer.on("explode",this.syncHelper),this.viewer.on("hide",this.syncHelper),this.viewer.on("isolate",this.syncHelper),this.viewer.on("show",this.syncHelper),this.viewer.on("showall",this.syncHelper)}dispose(){this.boxHelper.removeFromParent(),this.boxHelper.dispose(),this.viewer.off("geometryend",this.syncHelper),this.viewer.off("clear",this.syncHelper),this.viewer.off("explode",this.syncHelper),this.viewer.off("hide",this.syncHelper),this.viewer.off("isolate",this.syncHelper),this.viewer.off("show",this.syncHelper),this.viewer.off("showall",this.syncHelper)}}i.components.registerComponent("ExtentsHelperComponent",e=>new s(e))});
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExtentsHelperComponent.module.js","sources":["../../../plugins/components/ExtentsHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { Box3, Box3Helper } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass ExtentsHelperComponent implements IComponent {\n private viewer: Viewer;\n private boxHelper: Box3Helper;\n\n constructor(viewer: Viewer) {\n this.boxHelper = new Box3Helper(new Box3(), \"#ff0000\");\n this.viewer = viewer;\n this.viewer.on(\"geometryend\", this.syncHelper);\n this.viewer.on(\"clear\", this.syncHelper);\n this.viewer.on(\"explode\", this.syncHelper);\n this.viewer.on(\"hide\", this.syncHelper);\n this.viewer.on(\"isolate\", this.syncHelper);\n this.viewer.on(\"show\", this.syncHelper);\n this.viewer.on(\"showall\", this.syncHelper);\n }\n\n dispose() {\n this.boxHelper.removeFromParent();\n this.boxHelper.dispose();\n\n this.viewer.off(\"geometryend\", this.syncHelper);\n this.viewer.off(\"clear\", this.syncHelper);\n this.viewer.off(\"explode\", this.syncHelper);\n this.viewer.off(\"hide\", this.syncHelper);\n this.viewer.off(\"isolate\", this.syncHelper);\n this.viewer.off(\"show\", this.syncHelper);\n this.viewer.off(\"showall\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.boxHelper.removeFromParent();\n\n if (this.viewer.extents.isEmpty()) return;\n\n this.boxHelper.box = this.viewer.extents.clone();\n this.viewer.helpers.add(this.boxHelper);\n };\n}\n\ncomponents.registerComponent(\"ExtentsHelperComponent\", (viewer) => new ExtentsHelperComponent(viewer));\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAM,sBAAsB,CAAA;AAI1B,IAAA,WAAA,CAAY,MAAc,EAAA;QAyB1B,IAAA,CAAA,UAAU,GAAG,MAAK;AAChB,YAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE;AAEjC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;gBAAE;AAEnC,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE;YAChD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;AACzC,QAAA,CAAC;AA/BC,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,CAAC,IAAI,IAAI,EAAE,EAAE,SAAS,CAAC;AACtD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;QACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;IAC5C;IAEA,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE;AACjC,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;QAExB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC;IAC7C;AAUD;AAED,UAAU,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,CAAC,MAAM,KAAK,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GridHelperComponent.js","sources":["../../../plugins/components/GridHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { GridHelper, Vector3 } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass GridHelperComponent implements IComponent {\n private viewer: Viewer;\n private gridHelper: GridHelper;\n\n constructor(viewer: Viewer) {\n this.gridHelper = new GridHelper(10, 20, 0x444444, 0xaaaaaa);\n this.viewer = viewer;\n this.viewer.on(\"initialize\", this.syncHelper);\n this.viewer.on(\"geometryend\", this.syncHelper);\n this.viewer.on(\"clear\", this.syncHelper);\n }\n\n dispose() {\n this.gridHelper.removeFromParent();\n this.gridHelper.dispose();\n\n this.viewer.off(\"initialize\", this.syncHelper);\n this.viewer.off(\"geometryend\", this.syncHelper);\n this.viewer.off(\"clear\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.gridHelper.removeFromParent();\n\n if (this.viewer.extents.isEmpty()) return;\n\n const size = this.viewer.extents.getSize(new Vector3()).multiply(this.viewer.camera.up).length();\n const center = this.viewer.extents.getCenter(new Vector3());\n\n const upY = new Vector3(0, 1, 0);\n const up = new Vector3().copy(this.viewer.camera.up);\n\n this.gridHelper.scale.setScalar(size);\n this.gridHelper.position.copy(center);\n this.gridHelper.quaternion.setFromUnitVectors(upY, up);\n\n this.viewer.helpers.add(this.gridHelper);\n };\n}\n\ncomponents.registerComponent(\"GridHelperComponent\", (viewer) => new GridHelperComponent(viewer));\n"],"names":["Vector3","GridHelper","components"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0BA,MAAM,mBAAmB,CAAA;IAIvB,IAAA,WAAA,CAAY,MAAc,EAAA;YAiB1B,IAAA,CAAA,UAAU,GAAG,MAAK;IAChB,YAAA,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;IAElC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;oBAAE;IAEnC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAIA,aAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAChG,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAIA,aAAO,EAAE,CAAC;gBAE3D,MAAM,GAAG,GAAG,IAAIA,aAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAChC,YAAA,MAAM,EAAE,GAAG,IAAIA,aAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBAEpD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBACrC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;gBACrC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,EAAE,EAAE,CAAC;gBAEtD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1C,QAAA,CAAC;IAhCC,QAAA,IAAI,CAAC,UAAU,GAAG,IAAIC,gBAAU,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAC5D,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;YACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QAC1C;QAEA,OAAO,GAAA;IACL,QAAA,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;IAClC,QAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;YAEzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;QAC3C;IAmBD;AAEDC,0BAAU,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,MAAM,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GridHelperComponent.module.js","sources":["../../../plugins/components/GridHelperComponent.ts"],"sourcesContent":["///////////////////////////////////////////////////////////////////////////////\n// Copyright (C) 2002-2025, Open Design Alliance (the \"Alliance\").\n// All rights reserved.\n//\n// This software and its documentation and related materials are owned by\n// the Alliance. The software may only be incorporated into application\n// programs owned by members of the Alliance, subject to a signed\n// Membership Agreement and Supplemental Software License Agreement with the\n// Alliance. The structure and organization of this software are the valuable\n// trade secrets of the Alliance and its suppliers. The software is also\n// protected by copyright law and international treaty provisions. Application\n// programs incorporating this software must include the following statement\n// with their copyright notices:\n//\n// This application incorporates Open Design Alliance software pursuant to a\n// license agreement with Open Design Alliance.\n// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.\n// All rights reserved.\n//\n// By use of this software, its documentation or related materials, you\n// acknowledge and accept the above terms.\n///////////////////////////////////////////////////////////////////////////////\n\nimport { GridHelper, Vector3 } from \"three\";\nimport { IComponent, components, Viewer } from \"@inweb/viewer-three\";\n\nclass GridHelperComponent implements IComponent {\n private viewer: Viewer;\n private gridHelper: GridHelper;\n\n constructor(viewer: Viewer) {\n this.gridHelper = new GridHelper(10, 20, 0x444444, 0xaaaaaa);\n this.viewer = viewer;\n this.viewer.on(\"initialize\", this.syncHelper);\n this.viewer.on(\"geometryend\", this.syncHelper);\n this.viewer.on(\"clear\", this.syncHelper);\n }\n\n dispose() {\n this.gridHelper.removeFromParent();\n this.gridHelper.dispose();\n\n this.viewer.off(\"initialize\", this.syncHelper);\n this.viewer.off(\"geometryend\", this.syncHelper);\n this.viewer.off(\"clear\", this.syncHelper);\n }\n\n syncHelper = () => {\n this.gridHelper.removeFromParent();\n\n if (this.viewer.extents.isEmpty()) return;\n\n const size = this.viewer.extents.getSize(new Vector3()).multiply(this.viewer.camera.up).length();\n const center = this.viewer.extents.getCenter(new Vector3());\n\n const upY = new Vector3(0, 1, 0);\n const up = new Vector3().copy(this.viewer.camera.up);\n\n this.gridHelper.scale.setScalar(size);\n this.gridHelper.position.copy(center);\n this.gridHelper.quaternion.setFromUnitVectors(upY, up);\n\n this.viewer.helpers.add(this.gridHelper);\n };\n}\n\ncomponents.registerComponent(\"GridHelperComponent\", (viewer) => new GridHelperComponent(viewer));\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAM,mBAAmB,CAAA;AAIvB,IAAA,WAAA,CAAY,MAAc,EAAA;QAiB1B,IAAA,CAAA,UAAU,GAAG,MAAK;AAChB,YAAA,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;AAElC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;gBAAE;AAEnC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;AAChG,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC;YAE3D,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAChC,YAAA,MAAM,EAAE,GAAG,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAEpD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,EAAE,EAAE,CAAC;YAEtD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;AAC1C,QAAA,CAAC;AAhCC,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAC5D,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;QACpB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;IAC1C;IAEA,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;AAClC,QAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;QAEzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC;IAC3C;AAmBD;AAED,UAAU,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,CAAC,MAAM,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC"}