/**
 * Minified by jsDelivr using Terser v5.39.0.
 * Original file: /npm/online-three-viewer@0.12.7/build/engine/o3dv.module.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
import*as THREE from"three";import{TGALoader}from"three/examples/jsm/loaders/TGALoader.js";import{FBXLoader}from"three/examples/jsm/loaders/FBXLoader.js";import{ColladaLoader}from"three/examples/jsm/loaders/ColladaLoader.js";import{ThreeMFLoader}from"three/examples/jsm/loaders/3MFLoader.js";import{AMFLoader}from"three/examples/jsm/loaders/AMFLoader.js";import{BVHLoader}from"three/examples/jsm/loaders/BVHLoader.js";import"three/examples/jsm/loaders/DRACOLoader.js";import{Rhino3dmLoader}from"three/examples/jsm/loaders/3DMLoader.js";import*as fflate from"fflate";import{SVGLoader}from"three/examples/jsm/loaders/SVGLoader.js";function IsDefined(e){return null!=e}function ValueOrDefault(e,t){return null==e?t:e}function CopyObjectAttributes(e,t){if(IsDefined(e))for(let r of Object.keys(e))IsDefined(e[r])&&(t[r]=e[r])}function IsObjectEmpty(e){return 0===Object.keys(e).length}function EscapeHtmlChars(e){return e.replace(/</g,"&lt;").replace(/>/g,"&gt;")}class EventNotifier{constructor(){this.eventListeners=new Map}AddEventListener(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,[]),this.eventListeners.get(e).push(t)}HasEventListener(e){return this.eventListeners.has(e)}GetEventNotifier(e){return()=>{this.NotifyEventListeners(e)}}NotifyEventListeners(e,...t){if(!this.eventListeners.has(e))return;let r=this.eventListeners.get(e);for(let e of r)e(...t)}}class TaskRunner{constructor(){this.count=null,this.current=null,this.callbacks=null}Run(e,t){this.count=e,this.current=0,this.callbacks=t,0===e?this.TaskReady():this.RunOnce()}RunBatch(e,t,r){let n=0;e>0&&(n=parseInt((e-1)/t,10)+1),this.Run(n,{runTask:(n,i)=>{const o=n*t,s=Math.min((n+1)*t,e)-1;r.runTask(o,s,i)},onReady:r.onReady})}RunOnce(){setTimeout((()=>{this.callbacks.runTask(this.current,this.TaskReady.bind(this))}),0)}TaskReady(){this.current+=1,this.current<this.count?this.RunOnce():this.callbacks.onReady&&this.callbacks.onReady()}}function RunTaskAsync(e){setTimeout((()=>{e()}),10)}function RunTasks(e,t){(new TaskRunner).Run(e,t)}function RunTasksBatch(e,t,r){(new TaskRunner).RunBatch(e,t,r)}function WaitWhile(e){!function e(t){t()&&setTimeout((()=>{e(t)}),10)}(e)}let externalLibLocation=null,loadedExternalLibs=new Set;function SetExternalLibLocation(e){externalLibLocation=e}function GetExternalLibPath(e){return null===externalLibLocation?null:externalLibLocation+"/"+e}function LoadExternalLibrary(e){return new Promise(((t,r)=>{if(null===externalLibLocation)return void r();if(loadedExternalLibs.has(e))return void t();let n=document.createElement("script");n.type="text/javascript",n.src=GetExternalLibPath(e),n.onload=()=>{loadedExternalLibs.add(e),t()},n.onerror=()=>{r()},document.head.appendChild(n)}))}const FileSource={Url:1,File:2,Decompressed:3},FileFormat={Text:1,Binary:2};function GetFileName(e){let t=e,r=t.indexOf("?");-1!==r&&(t=t.substring(0,r));let n=t.lastIndexOf("/");return-1===n&&(n=t.lastIndexOf("\\")),-1!==n&&(t=t.substring(n+1)),decodeURI(t)}function GetFileExtension(e){let t=GetFileName(e),r=t.lastIndexOf(".");return-1===r?"":t.substring(r+1).toLowerCase()}function RequestUrl(e,t){return new Promise(((r,n)=>{let i=new XMLHttpRequest;i.open("GET",e,!0),i.onprogress=e=>{t(e.loaded,e.total)},i.onload=()=>{200===i.status?r(i.response):n()},i.onerror=()=>{n()},i.responseType="arraybuffer",i.send(null)}))}function ReadFile(e,t){return new Promise(((r,n)=>{let i=new FileReader;i.onprogress=e=>{t(e.loaded,e.total)},i.onloadend=e=>{e.target.readyState===FileReader.DONE&&r(e.target.result)},i.onerror=()=>{n()},i.readAsArrayBuffer(e)}))}function TransformFileHostUrls(e){for(let t=0;t<e.length;t++){let r=e[t];-1!==r.indexOf("www.dropbox.com")?(r=r.replace("www.dropbox.com","dl.dropbox.com"),e[t]=r):-1!==r.indexOf("github.com")&&(r=r.replace("github.com","raw.githubusercontent.com"),r=r.replace("/blob",""),e[t]=r)}}function IsUrl(e){return null!==e.match(/^https?:\/\/\S+$/g)}const Eps=1e-8,BigEps=1e-4,RadDeg=57.29577951308232,DegRad=.017453292519943;function IsZero(e){return Math.abs(e)<Eps}function IsLower(e,t){return t-e>Eps}function IsGreater(e,t){return e-t>Eps}function IsLowerOrEqual(e,t){return t-e>-Eps}function IsGreaterOrEqual(e,t){return e-t>-Eps}function IsEqual(e,t){return Math.abs(t-e)<Eps}function IsEqualEps(e,t,r){return Math.abs(t-e)<r}function IsPositive(e){return e>Eps}function IsNegative(e){return e<-Eps}const Direction={X:1,Y:2,Z:3};class Coord2D{constructor(e,t){this.x=e,this.y=t}Clone(){return new Coord2D(this.x,this.y)}}function CoordIsEqual2D(e,t){return IsEqual(e.x,t.x)&&IsEqual(e.y,t.y)}function AddCoord2D(e,t){return new Coord2D(e.x+t.x,e.y+t.y)}function SubCoord2D(e,t){return new Coord2D(e.x-t.x,e.y-t.y)}function CoordDistance2D(e,t){return Math.sqrt((e.x-t.x)*(e.x-t.x)+(e.y-t.y)*(e.y-t.y))}function DotVector2D(e,t){return e.x*t.x+e.y*t.y}class RGBColor{constructor(e,t,r){this.r=e,this.g=t,this.b=r}Set(e,t,r){this.r=e,this.g=t,this.b=r}Clone(){return new RGBColor(this.r,this.g,this.b)}}class RGBAColor{constructor(e,t,r,n){this.r=e,this.g=t,this.b=r,this.a=n}Set(e,t,r,n){this.r=e,this.g=t,this.b=r,this.a=n}Clone(){return new RGBAColor(this.r,this.g,this.b,this.a)}}function ColorComponentFromFloat(e){return parseInt(Math.round(255*e),10)}function ColorComponentToFloat(e){return e/255}function RGBColorFromFloatComponents(e,t,r){return new RGBColor(ColorComponentFromFloat(e),ColorComponentFromFloat(t),ColorComponentFromFloat(r))}function SRGBToLinear(e){return e<.04045?.0773993808*e:Math.pow(.9478672986*e+.0521327014,2.4)}function LinearToSRGB(e){return e<.0031308?12.92*e:1.055*Math.pow(e,.41666)-.055}function IntegerToHexString(e){let t=parseInt(e,10).toString(16);for(;t.length<2;)t="0"+t;return t}function RGBColorToHexString(e){return IntegerToHexString(e.r)+IntegerToHexString(e.g)+IntegerToHexString(e.b)}function RGBAColorToHexString(e){return IntegerToHexString(e.r)+IntegerToHexString(e.g)+IntegerToHexString(e.b)+IntegerToHexString(e.a)}function HexStringToRGBColor(e){if(6!==e.length)return null;let t=parseInt(e.substring(0,2),16),r=parseInt(e.substring(2,4),16),n=parseInt(e.substring(4,6),16);return new RGBColor(t,r,n)}function HexStringToRGBAColor(e){if(6!==e.length&&8!==e.length)return null;let t=parseInt(e.substring(0,2),16),r=parseInt(e.substring(2,4),16),n=parseInt(e.substring(4,6),16),i=255;return 8===e.length&&(i=parseInt(e.substring(6,8),16)),new RGBAColor(t,r,n,i)}function ArrayToRGBColor(e){return new RGBColor(e[0],e[1],e[2])}function RGBColorIsEqual(e,t){return e.r===t.r&&e.g===t.g&&e.b===t.b}class TextureMap{constructor(){this.name=null,this.mimeType=null,this.buffer=null,this.offset=new Coord2D(0,0),this.scale=new Coord2D(1,1),this.rotation=0}IsValid(){return null!==this.name&&null!==this.buffer}HasTransformation(){return!CoordIsEqual2D(this.offset,new Coord2D(0,0))||(!CoordIsEqual2D(this.scale,new Coord2D(1,1))||!IsEqual(this.rotation,0))}IsEqual(e){return this.name===e.name&&(this.mimeType===e.mimeType&&(!!CoordIsEqual2D(this.offset,e.offset)&&(!!CoordIsEqual2D(this.scale,e.scale)&&!!IsEqual(this.rotation,e.rotation))))}}function TextureMapIsEqual(e,t){return null===e&&null===t||null!==e&&null!==t&&e.IsEqual(t)}const MaterialType={Phong:1,Physical:2},MaterialSource={Model:1,DefaultFace:2,DefaultLine:3};class MaterialBase{constructor(e){this.type=e,this.source=MaterialSource.Model,this.name="",this.color=new RGBColor(0,0,0),this.vertexColors=!1}IsEqual(e){return this.type===e.type&&(this.source===e.source&&(this.name===e.name&&(!!RGBColorIsEqual(this.color,e.color)&&this.vertexColors===e.vertexColors)))}}class FaceMaterial extends MaterialBase{constructor(e){super(e),this.emissive=new RGBColor(0,0,0),this.opacity=1,this.transparent=!1,this.diffuseMap=null,this.bumpMap=null,this.normalMap=null,this.emissiveMap=null,this.alphaTest=0,this.multiplyDiffuseMap=!1}IsEqual(e){return!!super.IsEqual(e)&&(!!RGBColorIsEqual(this.emissive,e.emissive)&&(!!IsEqual(this.opacity,e.opacity)&&(this.transparent===e.transparent&&(!!TextureMapIsEqual(this.diffuseMap,e.diffuseMap)&&(!!TextureMapIsEqual(this.bumpMap,e.bumpMap)&&(!!TextureMapIsEqual(this.normalMap,e.normalMap)&&(!!TextureMapIsEqual(this.emissiveMap,e.emissiveMap)&&(!!IsEqual(this.alphaTest,e.alphaTest)&&this.multiplyDiffuseMap===e.multiplyDiffuseMap))))))))}}class PhongMaterial extends FaceMaterial{constructor(){super(MaterialType.Phong),this.ambient=new RGBColor(0,0,0),this.specular=new RGBColor(0,0,0),this.shininess=0,this.specularMap=null}IsEqual(e){return!!super.IsEqual(e)&&(!!RGBColorIsEqual(this.ambient,e.ambient)&&(!!RGBColorIsEqual(this.specular,e.specular)&&(!!IsEqual(this.shininess,e.shininess)&&!!TextureMapIsEqual(this.specularMap,e.specularMap))))}}class PhysicalMaterial extends FaceMaterial{constructor(){super(MaterialType.Physical),this.metalness=0,this.roughness=1,this.metalnessMap=null}IsEqual(e){return!!super.IsEqual(e)&&(!!IsEqual(this.metalness,e.metalness)&&(!!IsEqual(this.roughness,e.roughness)&&!!TextureMapIsEqual(this.metalnessMap,e.metalnessMap)))}}function TextureIsEqual(e,t){return e.name===t.name&&(e.mimeType===t.mimeType&&(!!CoordIsEqual2D(e.offset,t.offset)&&(!!CoordIsEqual2D(e.scale,t.scale)&&!!IsEqual(e.rotation,t.rotation))))}class Coord3D{constructor(e,t,r){this.x=e,this.y=t,this.z=r}Length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}MultiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this}Normalize(){let e=this.Length();return e>0&&this.MultiplyScalar(1/e),this}Offset(e,t){let r=e.Clone().Normalize();return this.x+=r.x*t,this.y+=r.y*t,this.z+=r.z*t,this}Rotate(e,t,r){let n=e.Clone().Normalize(),i=n.x,o=n.y,s=n.z,a=this.x-r.x,l=this.y-r.y,h=this.z-r.z,u=Math.sin(t),d=Math.cos(t);return this.x=-i*(-i*a-o*l-s*h)*(1-d)+a*d+(-s*l+o*h)*u,this.y=-o*(-i*a-o*l-s*h)*(1-d)+l*d+(s*a-i*h)*u,this.z=-s*(-i*a-o*l-s*h)*(1-d)+h*d+(-o*a+i*l)*u,this.x+=r.x,this.y+=r.y,this.z+=r.z,this}Clone(){return new Coord3D(this.x,this.y,this.z)}}function CoordIsEqual3D(e,t){return IsEqual(e.x,t.x)&&IsEqual(e.y,t.y)&&IsEqual(e.z,t.z)}function AddCoord3D(e,t){return new Coord3D(e.x+t.x,e.y+t.y,e.z+t.z)}function SubCoord3D(e,t){return new Coord3D(e.x-t.x,e.y-t.y,e.z-t.z)}function CoordDistance3D(e,t){return Math.sqrt((e.x-t.x)*(e.x-t.x)+(e.y-t.y)*(e.y-t.y)+(e.z-t.z)*(e.z-t.z))}function DotVector3D(e,t){return e.x*t.x+e.y*t.y+e.z*t.z}function VectorAngle3D(e,t){let r=e.Clone().Normalize(),n=t.Clone().Normalize();if(CoordIsEqual3D(r,n))return 0;let i=DotVector3D(r,n);return Math.acos(i)}function CrossVector3D(e,t){let r=new Coord3D(0,0,0);return r.x=e.y*t.z-e.z*t.y,r.y=e.z*t.x-e.x*t.z,r.z=e.x*t.y-e.y*t.x,r}function VectorLength3D(e,t,r){return Math.sqrt(e*e+t*t+r*r)}function ArrayToCoord3D(e){return new Coord3D(e[0],e[1],e[2])}class MeshPrimitiveBuffer{constructor(){this.indices=[],this.vertices=[],this.colors=[],this.normals=[],this.uvs=[],this.material=null}GetBounds(){let e=[1/0,1/0,1/0],t=[-1/0,-1/0,-1/0];for(let r=0;r<this.vertices.length/3;r++)for(let n=0;n<3;n++)e[n]=Math.min(e[n],this.vertices[3*r+n]),t[n]=Math.max(t[n],this.vertices[3*r+n]);return{min:e,max:t}}GetByteLength(e,t){return this.indices.length*e+(this.vertices.length+this.colors.length+this.normals.length+this.uvs.length)*t}}class MeshBuffer{constructor(){this.primitives=[]}PrimitiveCount(){return this.primitives.length}GetPrimitive(e){return this.primitives[e]}GetByteLength(e,t){let r=0;for(let n=0;n<this.primitives.length;n++){r+=this.primitives[n].GetByteLength(e,t)}return r}}function ConvertMeshToMeshBuffer(e){function t(e,t,r,n){function i(e,t,r){return null!==t?e.GetVertexColor(t):r?new RGBColor(0,0,0):null}function o(e,t,r){return null!==t?e.GetTextureUV(t):r?new Coord2D(0,0):null}function s(e,t,r){let n=e.VertexColorCount()>0,s=e.TextureUVCount()>0,a=e.GetVertex(t.vertex),l=e.GetNormal(t.normal),h=r.vertices.length/3;r.indices.push(h),r.vertices.push(a.x,a.y,a.z);let u=i(e,t.color,n);null!==u&&r.colors.push(u.r/255,u.g/255,u.b/255),r.normals.push(l.x,l.y,l.z);let d=o(e,t.uv,s);return null!==d&&r.uvs.push(d.x,d.y),{index:h,color:u,normal:l,uv:d}}if(n.has(t.vertex)){let a=n.get(t.vertex),l=function(e,t,r){function n(e,t,r){return null===r&&null===t||RGBColorIsEqual(r,i(e,t,!0))}function s(e,t,r){return CoordIsEqual3D(r,e.GetNormal(t))}function a(e,t,r){return null===r&&null===t||CoordIsEqual2D(r,o(e,t,!0))}for(let i=0;i<t.length;i++){let o=t[i],l=n(e,r.color,o.color),h=s(e,r.normal,o.normal),u=a(e,r.uv,o.uv);if(l&&h&&u)return o}return null}(e,a,t);if(null!==l)r.indices.push(l.index);else{let n=s(e,t,r);a.push(n)}}else{let i=s(e,t,r);n.set(t.vertex,[i])}}let r=new MeshBuffer,n=e.TriangleCount();if(0===n)return null;let i=[];for(let e=0;e<n;e++)i.push(e);i.sort(((t,r)=>{let n=e.GetTriangle(t),i=e.GetTriangle(r);return n.mat-i.mat}));let o=null,s=null;for(let n=0;n<i.length;n++){let a=i[n],l=e.GetTriangle(a);null!==o&&o.material===l.mat||(o=new MeshPrimitiveBuffer,o.material=l.mat,s=new Map,r.primitives.push(o));let h={vertex:l.v0,color:l.c0,normal:l.n0,uv:l.u0},u={vertex:l.v1,color:l.c1,normal:l.n1,uv:l.u1},d={vertex:l.v2,color:l.c2,normal:l.n2,uv:l.u2};t(e,h,o,s),t(e,u,o,s),t(e,d,o,s)}return r}function ArrayBufferToUtf8String(e){return new TextDecoder("utf-8").decode(e)}function ArrayBufferToAsciiString(e){let t="",r=new Uint8Array(e);for(let e=0;e<r.byteLength;e++)t+=String.fromCharCode(r[e]);return t}function AsciiStringToArrayBuffer(e){let t=new ArrayBuffer(e.length),r=new Uint8Array(t);for(let t=0;t<e.length;t++)r[t]=e.charCodeAt(t);return t}function Utf8StringToArrayBuffer(e){return(new TextEncoder).encode(e).buffer}function Base64DataURIToArrayBuffer(e){let t="data:";if(!e.startsWith(t))return null;let r=e.indexOf(";");if(-1===r)return null;let n=e.indexOf(",");if(-1===n)return null;let i=e.substring(5,5+r-5),o=atob(e.substring(n+1)),s=new ArrayBuffer(o.length),a=new Uint8Array(s);for(let e=0;e<o.length;e++)a[e]=o.charCodeAt(e);return{mimeType:i,buffer:s}}function GetFileExtensionFromMimeType(e){if(null==e)return"";let t=e.split("/");return 0===t.length?"":t[t.length-1]}function CreateObjectUrl(e){let t=new Blob([e]);return URL.createObjectURL(t)}function CreateObjectUrlWithMimeType(e,t){let r=new Blob([e],{type:t});return URL.createObjectURL(r)}function RevokeObjectUrl(e){URL.revokeObjectURL(e)}class ExportedFile{constructor(e){this.name=e,this.content=null}GetName(){return this.name}SetName(e){this.name=e}GetTextContent(){return ArrayBufferToUtf8String(this.content)}GetBufferContent(){return this.content}SetTextContent(e){let t=Utf8StringToArrayBuffer(e);this.content=t}SetBufferContent(e){this.content=e}}class ExporterBase{constructor(){}CanExport(e,t){return!1}Export(e,t,r){let n=[];this.ExportContent(e,t,n,(()=>{r(n)}))}ExportContent(e,t,r,n){}GetExportedMaterialName(e){return this.GetExportedName(e,"Material")}GetExportedMeshName(e){return this.GetExportedName(e,"Mesh")}GetExportedName(e,t){return 0===e.length?t:e}}class Exporter3dm extends ExporterBase{constructor(){super(),this.rhino=null}CanExport(e,t){return e===FileFormat.Binary&&"3dm"===t}ExportContent(e,t,r,n){null===this.rhino?LoadExternalLibrary("loaders/rhino3dm.min.js").then((()=>{rhino3dm().then((t=>{this.rhino=t,this.ExportRhinoContent(e,r,n)}))})).catch((()=>{n()})):this.ExportRhinoContent(e,r,n)}ExportRhinoContent(e,t,r){function n(e){return{r:e.r,g:e.g,b:e.b,a:255}}let i=new ExportedFile("model.3dm");t.push(i);let o=new this.rhino.File3dm;e.EnumerateTransformedMeshInstances((t=>{let r=ConvertMeshToMeshBuffer(t);for(let i=0;i<r.PrimitiveCount();i++){let s=r.GetPrimitive(i),a={data:{attributes:{position:{itemSize:3,type:"Float32Array",array:s.vertices},normal:{itemSize:3,type:"Float32Array",array:s.normals}},index:{type:"Uint16Array",array:s.indices}}},l=e.GetMaterial(s.material),h=new this.rhino.Material;h.name=this.GetExportedMaterialName(l.name),l.type===MaterialType.Phong&&(h.ambientColor=n(l.ambient),h.specularColor=n(l.specular)),h.diffuseColor=n(l.color),h.transparency=1-l.opacity;let u=o.materials().count();o.materials().add(h);let d=new this.rhino.Mesh.createFromThreejsJSON(a),c=new this.rhino.ObjectAttributes;c.name=this.GetExportedMeshName(t.GetName()),c.materialSource=this.rhino.ObjectMaterialSource.MaterialFromObject,c.materialIndex=u,o.objects().add(d,c)}}));let s=new this.rhino.File3dmWriteOptions;s.version=6;let a=o.toByteArray(s);i.SetBufferContent(a),r()}}const PropertyType={Text:1,Integer:2,Number:3,Boolean:4,Percent:5,Color:6};class Property{constructor(e,t,r){this.type=e,this.name=t,this.value=r}Clone(){const e=this.type===PropertyType.Color;return new Property(this.type,this.name,e?this.value.Clone():this.value)}}class PropertyGroup{constructor(e){this.name=e,this.properties=[]}PropertyCount(){return this.properties.length}AddProperty(e){this.properties.push(e)}GetProperty(e){return this.properties[e]}Clone(){let e=new PropertyGroup(this.name);for(let t of this.properties)e.AddProperty(t.Clone());return e}}function PropertyToString(e){return e.type===PropertyType.Text?EscapeHtmlChars(e.value):e.type===PropertyType.Integer?e.value.toLocaleString():e.type===PropertyType.Number?e.value.toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2}):e.type===PropertyType.Boolean?e.value?"True":"False":e.type===PropertyType.Percent?parseInt(100*e.value,10).toString()+"%":e.type===PropertyType.Color?"#"+RGBColorToHexString(e.value):null}function GenerateGuid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{let t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}))}class ExporterBim extends ExporterBase{constructor(){super()}CanExport(e,t){return e===FileFormat.Text&&"bim"===t}ExportContent(e,t,r,n){let i={schema_version:"1.1.0",meshes:[],elements:[],info:{}};this.ExportProperties(e.GetModel(),i.info);let o=0;e.EnumerateTransformedMeshInstances((t=>{let r={mesh_id:o,coordinates:[],indices:[]};t.EnumerateVertices((e=>{r.coordinates.push(e.x,e.y,e.z)})),t.EnumerateTriangleVertexIndices(((e,t,n)=>{r.indices.push(e,t,n)}));let n={mesh_id:o,type:"Other",color:{r:200,g:200,b:200,a:255},vector:{x:0,y:0,z:0},rotation:{qx:0,qy:0,qz:0,qw:1},guid:GenerateGuid(),info:{}},s=null,a=!0,l=[];for(let r=0;r<t.TriangleCount();r++){let n=t.GetTriangle(r),i=e.GetMaterial(n.mat),o={r:Math.round(i.color.r),g:Math.round(i.color.g),b:Math.round(i.color.b),a:ColorComponentFromFloat(i.opacity)};l.push(o.r,o.g,o.b,o.a),a&&(null===s?s=o:s.r===o.r&&s.g===o.g&&s.b===o.b&&s.a===o.a||(a=!1,s=null))}a?n.color=s:n.face_colors=l,n.info.Name=t.GetName(),this.ExportProperties(t,n.info),i.meshes.push(r),i.elements.push(n),o+=1}));let s=new ExportedFile("model.bim");s.SetTextContent(JSON.stringify(i,null,4)),r.push(s),n()}ExportProperties(e,t){for(let r=0;r<e.PropertyGroupCount();r++){let n=e.GetPropertyGroup(r);for(let e=0;e<n.PropertyCount();e++){let r=n.GetProperty(e);t[r.name]=PropertyToString(r)}}}}class BinaryWriter{constructor(e,t){this.arrayBuffer=new ArrayBuffer(e),this.dataView=new DataView(this.arrayBuffer),this.isLittleEndian=t,this.position=0}GetPosition(){return this.position}SetPosition(e){this.position=e}End(){return this.position>=this.arrayBuffer.byteLength}GetBuffer(){return this.arrayBuffer}WriteArrayBuffer(e){let t=new Uint8Array(e);new Uint8Array(this.arrayBuffer).set(t,this.position),this.position+=e.byteLength}WriteBoolean8(e){this.dataView.setInt8(this.position,e?1:0),this.position=this.position+1}WriteCharacter8(e){this.dataView.setInt8(this.position,e),this.position=this.position+1}WriteUnsignedCharacter8(e){this.dataView.setUint8(this.position,e),this.position=this.position+1}WriteInteger16(e){this.dataView.setInt16(this.position,e,this.isLittleEndian),this.position=this.position+2}WriteUnsignedInteger16(e){this.dataView.setUint16(this.position,e,this.isLittleEndian),this.position=this.position+2}WriteInteger32(e){this.dataView.setInt32(this.position,e,this.isLittleEndian),this.position=this.position+4}WriteUnsignedInteger32(e){this.dataView.setUint32(this.position,e,this.isLittleEndian),this.position=this.position+4}WriteFloat32(e){this.dataView.setFloat32(this.position,e,this.isLittleEndian),this.position=this.position+4}WriteDouble64(e){this.dataView.setFloat64(this.position,e,this.isLittleEndian),this.position=this.position+8}}class Coord4D{constructor(e,t,r,n){this.x=e,this.y=t,this.z=r,this.w=n}Clone(){return new Coord4D(this.x,this.y,this.z,this.w)}}class Quaternion{constructor(e,t,r,n){this.x=e,this.y=t,this.z=r,this.w=n}}function QuaternionIsEqual(e,t){return IsEqual(e.x,t.x)&&IsEqual(e.y,t.y)&&IsEqual(e.z,t.z)&&IsEqual(e.w,t.w)}function ArrayToQuaternion(e){return new Quaternion(e[0],e[1],e[2],e[3])}function QuaternionFromAxisAngle(e,t){const r=t/2,n=Math.sin(r);return new Quaternion(e.x*n,e.y*n,e.z*n,Math.cos(r))}function QuaternionFromXYZ(e,t,r,n){const i=Math.cos(e/2),o=Math.cos(t/2),s=Math.cos(r/2),a=Math.sin(e/2),l=Math.sin(t/2),h=Math.sin(r/2);let u=new Quaternion(0,0,0,1);if("XYZ"===n)u.x=a*o*s+i*l*h,u.y=i*l*s-a*o*h,u.z=i*o*h+a*l*s,u.w=i*o*s-a*l*h;else if("YXZ"===n)u.x=a*o*s+i*l*h,u.y=i*l*s-a*o*h,u.z=i*o*h-a*l*s,u.w=i*o*s+a*l*h;else if("ZXY"===n)u.x=a*o*s-i*l*h,u.y=i*l*s+a*o*h,u.z=i*o*h+a*l*s,u.w=i*o*s-a*l*h;else if("ZYX"===n)u.x=a*o*s-i*l*h,u.y=i*l*s+a*o*h,u.z=i*o*h-a*l*s,u.w=i*o*s+a*l*h;else if("YZX"===n)u.x=a*o*s+i*l*h,u.y=i*l*s+a*o*h,u.z=i*o*h-a*l*s,u.w=i*o*s-a*l*h;else{if("XZY"!==n)return null;u.x=a*o*s-i*l*h,u.y=i*l*s-a*o*h,u.z=i*o*h+a*l*s,u.w=i*o*s+a*l*h}return u}class Matrix{constructor(e){this.matrix=null,null!=e&&(this.matrix=e)}IsValid(){return null!==this.matrix}Set(e){return this.matrix=e,this}Get(){return this.matrix}Clone(){let e=[this.matrix[0],this.matrix[1],this.matrix[2],this.matrix[3],this.matrix[4],this.matrix[5],this.matrix[6],this.matrix[7],this.matrix[8],this.matrix[9],this.matrix[10],this.matrix[11],this.matrix[12],this.matrix[13],this.matrix[14],this.matrix[15]];return new Matrix(e)}CreateIdentity(){return this.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],this}IsIdentity(){let e=(new Matrix).CreateIdentity().Get();for(let t=0;t<16;t++)if(!IsEqual(this.matrix[t],e[t]))return!1;return!0}CreateTranslation(e,t,r){return this.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,e,t,r,1],this}CreateRotation(e,t,r,n){let i=e+e,o=t+t,s=r+r,a=e*i,l=e*o,h=e*s,u=t*o,d=t*s,c=r*s,m=n*i,p=n*o,f=n*s;return this.matrix=[1-(u+c),l+f,h-p,0,l-f,1-(a+c),d+m,0,h+p,d-m,1-(a+u),0,0,0,0,1],this}CreateRotationAxisAngle(e,t){let r=QuaternionFromAxisAngle(e,t);return this.CreateRotation(r.x,r.y,r.z,r.w)}CreateScale(e,t,r){return this.matrix=[e,0,0,0,0,t,0,0,0,0,r,0,0,0,0,1],this}ComposeTRS(e,t,r){let n=e.x,i=e.y,o=e.z,s=t.x,a=t.y,l=t.z,h=t.w,u=r.x,d=r.y,c=r.z,m=s+s,p=a+a,f=l+l,g=s*m,C=s*p,T=s*f,x=a*p,M=a*f,y=l*f,I=h*m,E=h*p,v=h*f;return this.matrix=[(1-(x+y))*u,(C+v)*u,(T-E)*u,0,(C-v)*d,(1-(g+y))*d,(M+I)*d,0,(T+E)*c,(M-I)*c,(1-(g+x))*c,0,n,i,o,1],this}DecomposeTRS(){let e=new Coord3D(this.matrix[12],this.matrix[13],this.matrix[14]),t=VectorLength3D(this.matrix[0],this.matrix[1],this.matrix[2]),r=VectorLength3D(this.matrix[4],this.matrix[5],this.matrix[6]),n=VectorLength3D(this.matrix[8],this.matrix[9],this.matrix[10]);IsNegative(this.Determinant())&&(t*=-1);let i=new Coord3D(t,r,n),o=this.matrix[0]/t,s=this.matrix[4]/r,a=this.matrix[8]/n,l=this.matrix[1]/t,h=this.matrix[5]/r,u=this.matrix[9]/n,d=this.matrix[2]/t,c=this.matrix[6]/r,m=this.matrix[10]/n,p=null,f=o+h+m;if(f>0){let e=2*Math.sqrt(f+1);p=new Quaternion((c-u)/e,(a-d)/e,(l-s)/e,.25*e)}else if(o>h&&o>m){let e=2*Math.sqrt(1+o-h-m);p=new Quaternion(.25*e,(s+l)/e,(a+d)/e,(c-u)/e)}else if(h>m){let e=2*Math.sqrt(1+h-o-m);p=new Quaternion((s+l)/e,.25*e,(u+c)/e,(a-d)/e)}else{let e=2*Math.sqrt(1+m-o-h);p=new Quaternion((a+d)/e,(u+c)/e,.25*e,(l-s)/e)}return{translation:e,rotation:p,scale:i}}Determinant(){let e=this.matrix[0],t=this.matrix[1],r=this.matrix[2],n=this.matrix[3],i=this.matrix[4],o=this.matrix[5],s=this.matrix[6],a=this.matrix[7],l=this.matrix[8],h=this.matrix[9],u=this.matrix[10],d=this.matrix[11],c=this.matrix[12],m=this.matrix[13],p=this.matrix[14],f=this.matrix[15];return(e*o-t*i)*(u*f-d*p)-(e*s-r*i)*(h*f-d*m)+(e*a-n*i)*(h*p-u*m)+(t*s-r*o)*(l*f-d*c)-(t*a-n*o)*(l*p-u*c)+(r*a-n*s)*(l*m-h*c)}Invert(){let e=this.matrix[0],t=this.matrix[1],r=this.matrix[2],n=this.matrix[3],i=this.matrix[4],o=this.matrix[5],s=this.matrix[6],a=this.matrix[7],l=this.matrix[8],h=this.matrix[9],u=this.matrix[10],d=this.matrix[11],c=this.matrix[12],m=this.matrix[13],p=this.matrix[14],f=this.matrix[15],g=e*o-t*i,C=e*s-r*i,T=e*a-n*i,x=t*s-r*o,M=t*a-n*o,y=r*a-n*s,I=l*m-h*c,E=l*p-u*c,v=l*f-d*c,G=h*p-u*m,S=h*f-d*m,b=u*f-d*p,w=g*b-C*S+T*G+x*v-M*E+y*I;return IsEqual(w,0)?null:new Matrix([(o*b-s*S+a*G)/w,(r*S-t*b-n*G)/w,(m*y-p*M+f*x)/w,(u*M-h*y-d*x)/w,(s*v-i*b-a*E)/w,(e*b-r*v+n*E)/w,(p*T-c*y-f*C)/w,(l*y-u*T+d*C)/w,(i*S-o*v+a*I)/w,(t*v-e*S-n*I)/w,(c*M-m*T+f*g)/w,(h*T-l*M-d*g)/w,(o*E-i*G-s*I)/w,(e*G-t*E+r*I)/w,(m*C-c*x-p*g)/w,(l*x-h*C+u*g)/w])}Transpose(){let e=[this.matrix[0],this.matrix[4],this.matrix[8],this.matrix[12],this.matrix[1],this.matrix[5],this.matrix[9],this.matrix[13],this.matrix[2],this.matrix[6],this.matrix[10],this.matrix[14],this.matrix[3],this.matrix[7],this.matrix[11],this.matrix[15]];return new Matrix(e)}InvertTranspose(){let e=this.Invert();return null===e?null:e.Transpose()}MultiplyVector(e){let t=e.x,r=e.y,n=e.z,i=e.w,o=this.matrix[0],s=this.matrix[1],a=this.matrix[2],l=this.matrix[3],h=this.matrix[4],u=this.matrix[5],d=this.matrix[6],c=this.matrix[7],m=this.matrix[8],p=this.matrix[9],f=this.matrix[10],g=this.matrix[11],C=this.matrix[12],T=this.matrix[13],x=this.matrix[14],M=this.matrix[15];return new Coord4D(t*o+r*h+n*m+i*C,t*s+r*u+n*p+i*T,t*a+r*d+n*f+i*x,t*l+r*c+n*g+i*M)}MultiplyMatrix(e){let t=this.matrix[0],r=this.matrix[1],n=this.matrix[2],i=this.matrix[3],o=this.matrix[4],s=this.matrix[5],a=this.matrix[6],l=this.matrix[7],h=this.matrix[8],u=this.matrix[9],d=this.matrix[10],c=this.matrix[11],m=this.matrix[12],p=this.matrix[13],f=this.matrix[14],g=this.matrix[15],C=e.matrix[0],T=e.matrix[1],x=e.matrix[2],M=e.matrix[3],y=e.matrix[4],I=e.matrix[5],E=e.matrix[6],v=e.matrix[7],G=e.matrix[8],S=e.matrix[9],b=e.matrix[10],w=e.matrix[11],R=e.matrix[12],A=e.matrix[13],D=e.matrix[14],F=e.matrix[15];return new Matrix([t*C+r*y+n*G+i*R,t*T+r*I+n*S+i*A,t*x+r*E+n*b+i*D,t*M+r*v+n*w+i*F,o*C+s*y+a*G+l*R,o*T+s*I+a*S+l*A,o*x+s*E+a*b+l*D,o*M+s*v+a*w+l*F,h*C+u*y+d*G+c*R,h*T+u*I+d*S+c*A,h*x+u*E+d*b+c*D,h*M+u*v+d*w+c*F,m*C+p*y+f*G+g*R,m*T+p*I+f*S+g*A,m*x+p*E+f*b+g*D,m*M+p*v+f*w+g*F])}}function MatrixIsEqual(e,t){const r=e.Get(),n=t.Get();for(let e=0;e<16;e++)if(!IsEqual(r[e],n[e]))return!1;return!0}class Transformation{constructor(e){null!=e?this.matrix=e:(this.matrix=new Matrix,this.matrix.CreateIdentity())}SetMatrix(e){return this.matrix=e,this}GetMatrix(){return this.matrix}IsIdentity(){return this.matrix.IsIdentity()}AppendMatrix(e){return this.matrix=this.matrix.MultiplyMatrix(e),this}Append(e){return this.AppendMatrix(e.GetMatrix()),this}TransformCoord3D(e){let t=new Coord4D(e.x,e.y,e.z,1),r=this.matrix.MultiplyVector(t);return new Coord3D(r.x,r.y,r.z)}Clone(){const e=this.matrix.Clone();return new Transformation(e)}}function TransformationIsEqual(e,t){return MatrixIsEqual(e.GetMatrix(),t.GetMatrix())}function IsEmptyMesh(e){return 0===e.LineCount()&&0===e.TriangleCount()}function CalculateTriangleNormal(e,t,r){let n=CrossVector3D(SubCoord3D(t,e),SubCoord3D(r,e));return n.Normalize(),n}function TransformMesh(e,t){if(!t.IsIdentity()){for(let r=0;r<e.VertexCount();r++){let n=e.GetVertex(r),i=t.TransformCoord3D(n);n.x=i.x,n.y=i.y,n.z=i.z}if(e.NormalCount()>0){let r=t.GetMatrix().InvertTranspose();if(null!==r){let t=new Transformation(r);for(let r=0;r<e.NormalCount();r++){let n=e.GetNormal(r),i=t.TransformCoord3D(n);n.x=i.x,n.y=i.y,n.z=i.z}}}}}function FlipMeshTrianglesOrientation(e){for(let t=0;t<e.TriangleCount();t++){let r=e.GetTriangle(t),n=r.v1;r.v1=r.v2,r.v2=n}}class Object3D{constructor(){}VertexCount(){return 0}VertexColorCount(){return 0}NormalCount(){return 0}TextureUVCount(){return 0}LineCount(){return 0}LineSegmentCount(){return 0}TriangleCount(){return 0}EnumerateVertices(e){}EnumerateTriangleVertexIndices(e){}EnumerateTriangleVertices(e){}}class ModelObject3D extends Object3D{constructor(){super(),this.name="",this.propertyGroups=[]}GetName(){return this.name}SetName(e){this.name=e}PropertyGroupCount(){return this.propertyGroups.length}AddPropertyGroup(e){return this.propertyGroups.push(e),this.propertyGroups.length-1}GetPropertyGroup(e){return this.propertyGroups[e]}CloneProperties(e){for(let t of this.propertyGroups)e.AddPropertyGroup(t.Clone())}}class MeshInstanceId{constructor(e,t){this.nodeId=e,this.meshIndex=t}IsEqual(e){return this.nodeId===e.nodeId&&this.meshIndex===e.meshIndex}GetKey(){return this.nodeId.toString()+":"+this.meshIndex.toString()}}class MeshInstance extends ModelObject3D{constructor(e,t,r){super(),this.id=e,this.node=t,this.mesh=r}GetId(){return this.id}GetTransformation(){return this.node.GetWorldTransformation()}GetMesh(){return this.mesh}VertexCount(){return this.mesh.VertexCount()}VertexColorCount(){return this.mesh.VertexColorCount()}NormalCount(){return this.mesh.NormalCount()}TextureUVCount(){return this.mesh.TextureUVCount()}LineCount(){return this.mesh.LineCount()}LineSegmentCount(){return this.mesh.LineSegmentCount()}TriangleCount(){return this.mesh.TriangleCount()}EnumerateVertices(e){let t=this.node.GetWorldTransformation();t.IsIdentity()?this.mesh.EnumerateVertices(e):this.mesh.EnumerateVertices((r=>{const n=t.TransformCoord3D(r);e(n)}))}EnumerateTriangleVertexIndices(e){this.mesh.EnumerateTriangleVertexIndices(e)}EnumerateTriangleVertices(e){let t=this.node.GetWorldTransformation();t.IsIdentity()?this.mesh.EnumerateTriangleVertices(e):this.mesh.EnumerateTriangleVertices(((r,n,i)=>{const o=t.TransformCoord3D(r),s=t.TransformCoord3D(n),a=t.TransformCoord3D(i);e(o,s,a)}))}PropertyGroupCount(){return this.mesh.PropertyGroupCount()}AddPropertyGroup(e){return this.mesh.AddPropertyGroup(e)}GetPropertyGroup(e){return this.mesh.GetPropertyGroup(e)}GetTransformedMesh(){let e=this.node.GetWorldTransformation(),t=this.mesh.Clone();return TransformMesh(t,e),t}}const GltfComponentType$1={UNSIGNED_INT:5125,FLOAT:5126},GltfBufferType={ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963};class ExporterGltf extends ExporterBase{constructor(){super(),this.components={index:{type:GltfComponentType$1.UNSIGNED_INT,size:4},number:{type:GltfComponentType$1.FLOAT,size:4}}}CanExport(e,t){return e===FileFormat.Text&&"gltf"===t||e===FileFormat.Binary&&"glb"===t}ExportContent(e,t,r,n){t===FileFormat.Text?this.ExportAsciiContent(e,r):t===FileFormat.Binary&&this.ExportBinaryContent(e,r),n()}ExportAsciiContent(e,t){let r=new ExportedFile("model.gltf"),n=new ExportedFile("model.bin");t.push(r),t.push(n);let i=this.GetMeshData(e),o=this.GetMainBuffer(i),s=this.GetMainJson(e,i);s.buffers.push({uri:n.GetName(),byteLength:o.byteLength});let a=new Map;this.ExportMaterials(e,s,(e=>{let r=GetFileName(e.name);if(a.has(r))return a.get(r);{let n=new ExportedFile(r);n.SetBufferContent(e.buffer),t.push(n);let i=s.textures.length;return a.set(r,i),s.images.push({uri:r}),s.textures.push({source:i}),i}})),r.SetTextContent(JSON.stringify(s,null,4)),n.SetBufferContent(o)}ExportBinaryContent(e,t){function r(e){let t=e%4;return 0===t?e:e+(4-t)}function n(e,t,r){for(let n=0;n<r;n++)e.WriteUnsignedCharacter8(t)}let i=new ExportedFile("model.glb");t.push(i);let o=this.GetMeshData(e),s=this.GetMainBuffer(o),a=this.GetMainJson(e,o),l=[],h=s.byteLength,u=new Map;this.ExportMaterials(e,a,(e=>{let t=GetFileName(e.name),r=GetFileExtension(e.name);if(u.has(t))return u.get(t);{let n=a.bufferViews.length,i=a.textures.length;u.set(t,i);let o=e.buffer;return l.push(o),a.bufferViews.push({buffer:0,byteOffset:h,byteLength:o.byteLength}),h+=o.byteLength,a.images.push({bufferView:n,mimeType:"image/"+r}),a.textures.push({source:i}),i}}));let d=s.byteLength;for(let e=0;e<l.length;e++){d+=l[e].byteLength}let c=r(d);a.buffers.push({byteLength:c});let m=Utf8StringToArrayBuffer(JSON.stringify(a)),p=m.byteLength,f=r(p),g=20+f+8+c,C=new BinaryWriter(g,!0);C.WriteUnsignedInteger32(1179937895),C.WriteUnsignedInteger32(2),C.WriteUnsignedInteger32(g),C.WriteUnsignedInteger32(f),C.WriteUnsignedInteger32(1313821514),C.WriteArrayBuffer(m),n(C,32,f-p),C.WriteUnsignedInteger32(c),C.WriteUnsignedInteger32(5130562),C.WriteArrayBuffer(s);for(let e=0;e<l.length;e++){let t=l[e];C.WriteArrayBuffer(t)}n(C,0,c-d),i.SetBufferContent(C.GetBuffer())}GetMeshData(e){let t=[];return e.EnumerateMeshes((e=>{let r=ConvertMeshToMeshBuffer(e);t.push({name:e.GetName(),buffer:r,offsets:[],sizes:[]})})),t}GetMainBuffer(e){let t=0;for(let r of e)t+=r.buffer.GetByteLength(this.components.index.size,this.components.number.size);let r=new BinaryWriter(t,!0);for(let t of e)for(let e=0;e<t.buffer.PrimitiveCount();e++){let n=t.buffer.GetPrimitive(e),i=r.GetPosition();for(let e=0;e<n.indices.length;e++)r.WriteUnsignedInteger32(n.indices[e]);for(let e=0;e<n.vertices.length;e++)r.WriteFloat32(n.vertices[e]);for(let e=0;e<n.colors.length;e++)r.WriteFloat32(SRGBToLinear(n.colors[e]));for(let e=0;e<n.normals.length;e++)r.WriteFloat32(n.normals[e]);for(let e=0;e<n.uvs.length;e++){let t=n.uvs[e];e%2==1&&(t*=-1),r.WriteFloat32(t)}t.offsets.push(i),t.sizes.push(r.GetPosition()-i)}return r.GetBuffer()}GetMainJson(e,t){class r{constructor(e,t){this.mainJson=e,this.byteOffset=t}AddBufferView(e,t){let r={buffer:0,byteOffset:this.byteOffset,byteLength:e,target:t};return this.mainJson.bufferViews.push(r),this.byteOffset+=e,this.mainJson.bufferViews.length-1}}function n(e,t){for(let r of t.GetMeshIndices()){let n=new MeshInstanceId(t.GetId(),r);if(e.IsMeshInstanceVisible(n))return!0}for(let r of t.GetChildNodes())if(n(e,r))return!0;return!1}function i(e,t,r,i){if(i.IsMeshNode())for(let n of i.GetMeshIndices())o(e,t,r,i,n,!0);else if(n(e,i)){let n={},o=i.GetName();o.length>0&&(n.name=o),i.GetTransformation().IsIdentity()||(n.matrix=i.GetTransformation().GetMatrix().Get()),r.push(n),t.push(r.length-1),n.children=[],s(e,n.children,r,i)}}function o(e,t,r,n,i,o){let s=new MeshInstanceId(n.GetId(),i);if(!e.IsMeshInstanceVisible(s))return;let a={mesh:e.MapMeshIndex(i)};if(o){n.GetTransformation().IsIdentity()||(a.matrix=n.GetTransformation().GetMatrix().Get())}r.push(a),t.push(r.length-1)}function s(e,t,r,n){for(let o of n.GetChildNodes())i(e,t,r,o);for(let i of n.GetMeshIndices())o(e,t,r,n,i,!1)}let a={asset:{generator:"https://3dviewer.net",version:"2.0"},scene:0,scenes:[{nodes:[]}],nodes:[],materials:[],meshes:[],buffers:[],bufferViews:[],accessors:[]},l=e.GetModel().GetRootNode();s(e,a.scenes[0].nodes,a.nodes,l);for(let e of t){let t={name:this.GetExportedMeshName(e.name),primitives:[]},n=e.buffer.primitives;for(let i=0;i<n.length;i++){let o=n[i],s=new r(a,e.offsets[i]),l=s.AddBufferView(o.indices.length*this.components.index.size,GltfBufferType.ELEMENT_ARRAY_BUFFER),h=s.AddBufferView(o.vertices.length*this.components.number.size,GltfBufferType.ARRAY_BUFFER),u=null;o.colors.length>0&&(u=s.AddBufferView(o.colors.length*this.components.number.size,GltfBufferType.ARRAY_BUFFER));let d=s.AddBufferView(o.normals.length*this.components.number.size,GltfBufferType.ARRAY_BUFFER),c=null;o.uvs.length>0&&(c=s.AddBufferView(o.uvs.length*this.components.number.size,GltfBufferType.ARRAY_BUFFER));let m={attributes:{},mode:4,material:o.material},p=o.GetBounds();a.accessors.push({bufferView:l,byteOffset:0,componentType:this.components.index.type,count:o.indices.length,type:"SCALAR"}),m.indices=a.accessors.length-1,a.accessors.push({bufferView:h,byteOffset:0,componentType:this.components.number.type,count:o.vertices.length/3,min:p.min,max:p.max,type:"VEC3"}),m.attributes.POSITION=a.accessors.length-1,null!==u&&(a.accessors.push({bufferView:u,byteOffset:0,componentType:this.components.number.type,count:o.colors.length/3,type:"VEC3"}),m.attributes.COLOR_0=a.accessors.length-1),a.accessors.push({bufferView:d,byteOffset:0,componentType:this.components.number.type,count:o.normals.length/3,type:"VEC3"}),m.attributes.NORMAL=a.accessors.length-1,null!==c&&(a.accessors.push({bufferView:c,byteOffset:0,componentType:this.components.number.type,count:o.uvs.length/2,type:"VEC2"}),m.attributes.TEXCOORD_0=a.accessors.length-1),t.primitives.push(m)}a.meshes.push(t)}return a}ExportMaterials(e,t,r){function n(e,t,r,n){function i(e,t){return[SRGBToLinear(e.r/255),SRGBToLinear(e.g/255),SRGBToLinear(e.b/255),t]}function o(e,t,r){if(null===t||!t.IsValid())return null;void 0===e.images&&(e.images=[]),void 0===e.textures&&(e.textures=[]);let n={index:r(t)};if(t.HasTransformation()){let r="KHR_texture_transform";void 0===e.extensionsUsed&&(e.extensionsUsed=[]),-1===e.extensionsUsed.indexOf(r)&&e.extensionsUsed.push(r),n.extensions={KHR_texture_transform:{offset:[t.offset.x,-t.offset.y],scale:[t.scale.x,t.scale.y],rotation:-t.rotation}}}return n}let s={name:e.GetExportedMaterialName(r.name),pbrMetallicRoughness:{baseColorFactor:i(r.color,r.opacity)},emissiveFactor:(a=r.emissive,[SRGBToLinear(a.r/255),SRGBToLinear(a.g/255),SRGBToLinear(a.b/255)]),doubleSided:!0,alphaMode:"OPAQUE"};var a;r.transparent&&(s.alphaMode="BLEND");let l=o(t,r.diffuseMap,n);if(null!==l&&(r.multiplyDiffuseMap||(s.pbrMetallicRoughness.baseColorFactor=i(new RGBColor(255,255,255),r.opacity)),s.pbrMetallicRoughness.baseColorTexture=l),r.type===MaterialType.Physical){let e=o(t,r.metalnessMap,n);null!==e?s.pbrMetallicRoughness.metallicRoughnessTexture=e:(s.pbrMetallicRoughness.metallicFactor=r.metalness,s.pbrMetallicRoughness.roughnessFactor=r.roughness)}let h=o(t,r.normalMap,n);null!==h&&(s.normalTexture=h);let u=o(t,r.emissiveMap,n);null!==u&&(s.emissiveTexture=u),t.materials.push(s)}for(let i=0;i<e.MaterialCount();i++){n(this,t,e.GetMaterial(i),r)}}}class ExporterSettings{constructor(e){this.transformation=new Transformation,this.isMeshVisible=e=>!0,CopyObjectAttributes(e,this)}}class ExporterModel{constructor(e,t){this.model=e,this.settings=t||new ExporterSettings,this.visibleMeshes=null,this.meshToVisibleMeshIndex=null}GetModel(){return this.model}MaterialCount(){return this.model.MaterialCount()}GetMaterial(e){return this.model.GetMaterial(e)}VertexCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.VertexCount()})),e}TriangleCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.TriangleCount()})),e}MeshCount(){let e=0;return this.EnumerateMeshes((t=>{e+=1})),e}EnumerateMeshes(e){this.FillVisibleMeshCache();for(let t=0;t<this.model.MeshCount();t++)if(this.visibleMeshes.has(t)){e(this.model.GetMesh(t))}}MapMeshIndex(e){return this.FillVisibleMeshCache(),this.meshToVisibleMeshIndex.get(e)}IsMeshInstanceVisible(e){return this.settings.isMeshVisible(e)}MeshInstanceCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=1})),e}EnumerateMeshInstances(e){this.model.EnumerateMeshInstances((t=>{this.settings.isMeshVisible(t.GetId())&&e(t)}))}EnumerateTransformedMeshInstances(e){this.EnumerateMeshInstances((t=>{let r=t.GetTransformation();this.settings.transformation.IsIdentity()||r.Append(this.settings.transformation);let n=t.GetMesh().Clone();r.IsIdentity()||TransformMesh(n,r),e(n)}))}EnumerateVerticesAndTriangles(e){let t=[];this.EnumerateTransformedMeshInstances((e=>{t.push(e)}));for(let r of t)r.EnumerateVertices((t=>{e.onVertex(t.x,t.y,t.z)}));let r=0;for(let n of t)n.EnumerateTriangleVertexIndices(((t,n,i)=>{e.onTriangle(t+r,n+r,i+r)})),r+=n.VertexCount()}EnumerateTrianglesWithNormals(e){this.EnumerateTransformedMeshInstances((t=>{t.EnumerateTriangleVertices(((t,r,n)=>{let i=CalculateTriangleNormal(t,r,n);e(t,r,n,i)}))}))}FillVisibleMeshCache(){if(null!==this.visibleMeshes&&null!==this.meshToVisibleMeshIndex)return;this.visibleMeshes=new Set,this.model.EnumerateMeshInstances((e=>{let t=e.GetId();this.settings.isMeshVisible(t)&&this.visibleMeshes.add(t.meshIndex)})),this.meshToVisibleMeshIndex=new Map;let e=0;for(let t=0;t<this.model.MeshCount();t++)this.visibleMeshes.has(t)&&(this.meshToVisibleMeshIndex.set(t,e),e+=1)}}class TextWriter{constructor(){this.text="",this.indentation=0}GetText(){return this.text}Indent(e){this.indentation+=e}WriteArrayLine(e){this.WriteLine(e.join(" "))}WriteLine(e){this.WriteIndentation(),this.Write(e+"\n")}WriteIndentation(){for(let e=0;e<this.indentation;e++)this.Write("  ")}Write(e){this.text+=e}}class ExporterObj extends ExporterBase{constructor(){super()}CanExport(e,t){return e===FileFormat.Text&&"obj"===t}ExportContent(e,t,r,n){function i(e,t,r,n){if(null===r||!r.IsValid())return;let i=GetFileName(r.name);if(e.WriteArrayLine([t,i]),-1===n.findIndex((e=>e.GetName()===i))){let e=new ExportedFile(i);e.SetBufferContent(r.buffer),n.push(e)}}let o=new ExportedFile("model.mtl"),s=new ExportedFile("model.obj");r.push(o),r.push(s);let a=new TextWriter;a.WriteLine(this.GetHeaderText());for(let t=0;t<e.MaterialCount();t++){let n=e.GetMaterial(t);a.WriteArrayLine(["newmtl",this.GetExportedMaterialName(n.name)]),a.WriteArrayLine(["Kd",n.color.r/255,n.color.g/255,n.color.b/255]),a.WriteArrayLine(["d",n.opacity]),n.type===MaterialType.Phong&&(a.WriteArrayLine(["Ka",n.ambient.r/255,n.ambient.g/255,n.ambient.b/255]),a.WriteArrayLine(["Ks",n.specular.r/255,n.specular.g/255,n.specular.b/255]),a.WriteArrayLine(["Ns",1e3*n.shininess])),i(a,"map_Kd",n.diffuseMap,r),n.type===MaterialType.Phong&&i(a,"map_Ks",n.specularMap,r),i(a,"bump",n.bumpMap,r)}o.SetTextContent(a.GetText());let l=new TextWriter;l.WriteLine(this.GetHeaderText()),l.WriteArrayLine(["mtllib",o.GetName()]);let h=0,u=0,d=0,c=null;e.EnumerateTransformedMeshInstances((t=>{l.WriteArrayLine(["g",this.GetExportedMeshName(t.GetName())]);for(let e=0;e<t.VertexCount();e++){let r=t.GetVertex(e);l.WriteArrayLine(["v",r.x,r.y,r.z])}for(let e=0;e<t.NormalCount();e++){let r=t.GetNormal(e);l.WriteArrayLine(["vn",r.x,r.y,r.z])}for(let e=0;e<t.TextureUVCount();e++){let r=t.GetTextureUV(e);l.WriteArrayLine(["vt",r.x,r.y])}for(let r=0;r<t.TriangleCount();r++){let n=t.GetTriangle(r),i=n.v0+h+1,o=n.v1+h+1,s=n.v2+h+1,a=n.n0+u+1,m=n.n1+u+1,p=n.n2+u+1,f="",g="",C="";if(n.HasTextureUVs()&&(f=n.u0+d+1,g=n.u1+d+1,C=n.u2+d+1),null!==n.mat){let t=e.GetMaterial(n.mat),r=this.GetExportedMaterialName(t.name);r!==c&&(l.WriteArrayLine(["usemtl",r]),c=r)}l.WriteArrayLine(["f",[i,f,a].join("/"),[o,g,m].join("/"),[s,C,p].join("/")])}for(let r=0;r<t.LineCount();r++){let n=t.GetLine(r),i=[];for(let e=0;e<n.vertices.length;e++)i.push(n.vertices[e]+h+1);if(null!==n.mat){let t=e.GetMaterial(n.mat),r=this.GetExportedMaterialName(t.name);r!==c&&(l.WriteArrayLine(["usemtl",r]),c=r)}l.WriteArrayLine(["l",i.join(" ")])}h+=t.VertexCount(),u+=t.NormalCount(),d+=t.TextureUVCount()})),s.SetTextContent(l.GetText()),n()}GetHeaderText(){return"# exported by https://3dviewer.net"}}class ExporterOff extends ExporterBase{constructor(){super()}CanExport(e,t){return e===FileFormat.Text&&"off"===t}ExportContent(e,t,r,n){let i=new ExportedFile("model.off");r.push(i);let o=new TextWriter;o.WriteLine("OFF"),o.WriteArrayLine([e.VertexCount(),e.TriangleCount(),0]),e.EnumerateVerticesAndTriangles({onVertex:function(e,t,r){o.WriteArrayLine([e,t,r])},onTriangle:function(e,t,r){o.WriteArrayLine([3,e,t,r])}}),i.SetTextContent(o.GetText()),n()}}class ExporterPly extends ExporterBase{constructor(){super()}CanExport(e,t){return(e===FileFormat.Text||e===FileFormat.Binary)&&"ply"===t}ExportContent(e,t,r,n){t===FileFormat.Text?this.ExportText(e,r):this.ExportBinary(e,r),n()}ExportText(e,t){let r=new ExportedFile("model.ply");t.push(r);let n=new TextWriter,i=e.VertexCount(),o=e.TriangleCount(),s=this.GetHeaderText("ascii",i,o);n.Write(s),e.EnumerateVerticesAndTriangles({onVertex:function(e,t,r){n.WriteArrayLine([e,t,r])},onTriangle:function(e,t,r){n.WriteArrayLine([3,e,t,r])}}),r.SetTextContent(n.GetText())}ExportBinary(e,t){let r=new ExportedFile("model.ply");t.push(r);let n=e.VertexCount(),i=e.TriangleCount(),o=this.GetHeaderText("binary_little_endian",n,i),s=o.length+3*n*4+13*i,a=new BinaryWriter(s,!0);for(let e=0;e<o.length;e++)a.WriteUnsignedCharacter8(o.charCodeAt(e));e.EnumerateVerticesAndTriangles({onVertex:function(e,t,r){a.WriteFloat32(e),a.WriteFloat32(t),a.WriteFloat32(r)},onTriangle:function(e,t,r){a.WriteUnsignedCharacter8(3),a.WriteInteger32(e),a.WriteInteger32(t),a.WriteInteger32(r)}}),r.SetBufferContent(a.GetBuffer())}GetHeaderText(e,t,r){let n=new TextWriter;return n.WriteLine("ply"),n.WriteLine("format "+e+" 1.0"),n.WriteLine("element vertex "+t),n.WriteLine("property float x"),n.WriteLine("property float y"),n.WriteLine("property float z"),n.WriteLine("element face "+r),n.WriteLine("property list uchar int vertex_index"),n.WriteLine("end_header"),n.GetText()}}class ExporterStl extends ExporterBase{constructor(){super()}CanExport(e,t){return(e===FileFormat.Text||e===FileFormat.Binary)&&"stl"===t}ExportContent(e,t,r,n){t===FileFormat.Text?this.ExportText(e,r):this.ExportBinary(e,r),n()}ExportText(e,t){let r=new ExportedFile("model.stl");t.push(r);let n=new TextWriter;n.WriteLine("solid Model"),e.EnumerateTrianglesWithNormals(((e,t,r,i)=>{n.WriteArrayLine(["facet","normal",i.x,i.y,i.z]),n.Indent(1),n.WriteLine("outer loop"),n.Indent(1),n.WriteArrayLine(["vertex",e.x,e.y,e.z]),n.WriteArrayLine(["vertex",t.x,t.y,t.z]),n.WriteArrayLine(["vertex",r.x,r.y,r.z]),n.Indent(-1),n.WriteLine("endloop"),n.Indent(-1),n.WriteLine("endfacet")})),n.WriteLine("endsolid Model"),r.SetTextContent(n.GetText())}ExportBinary(e,t){let r=new ExportedFile("model.stl");t.push(r);let n=e.TriangleCount(),i=new BinaryWriter(84+50*n,!0);for(let e=0;e<80;e++)i.WriteUnsignedCharacter8(0);i.WriteUnsignedInteger32(n),e.EnumerateTrianglesWithNormals(((e,t,r,n)=>{i.WriteFloat32(n.x),i.WriteFloat32(n.y),i.WriteFloat32(n.z),i.WriteFloat32(e.x),i.WriteFloat32(e.y),i.WriteFloat32(e.z),i.WriteFloat32(t.x),i.WriteFloat32(t.y),i.WriteFloat32(t.z),i.WriteFloat32(r.x),i.WriteFloat32(r.y),i.WriteFloat32(r.z),i.WriteUnsignedInteger16(0)})),r.SetBufferContent(i.GetBuffer())}}class Exporter{constructor(){this.exporters=[new ExporterObj,new ExporterStl,new ExporterPly,new ExporterOff,new ExporterGltf,new Exporter3dm,new ExporterBim]}AddExporter(e){this.exporters.push(e)}Export(e,t,r,n,i){let o=null;for(let e=0;e<this.exporters.length;e++){let t=this.exporters[e];if(t.CanExport(r,n)){o=t;break}}if(null===o)return void i.onError();let s=new ExporterModel(e,t);o.Export(s,r,(e=>{0===e.length?i.onError():i.onSuccess(e)}))}}class Box3D{constructor(e,t){this.min=e,this.max=t}GetMin(){return this.min}GetMax(){return this.max}GetCenter(){return new Coord3D((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,(this.min.z+this.max.z)/2)}}class BoundingBoxCalculator3D{constructor(){this.box=new Box3D(new Coord3D(1/0,1/0,1/0),new Coord3D(-1/0,-1/0,-1/0)),this.isValid=!1}GetBox(){return this.isValid?this.box:null}AddPoint(e){this.box.min.x=Math.min(this.box.min.x,e.x),this.box.min.y=Math.min(this.box.min.y,e.y),this.box.min.z=Math.min(this.box.min.z,e.z),this.box.max.x=Math.max(this.box.max.x,e.x),this.box.max.y=Math.max(this.box.max.y,e.y),this.box.max.z=Math.max(this.box.max.z,e.z),this.isValid=!0}}class Segment2D{constructor(e,t){this.beg=e,this.end=t}Clone(){return new Segment2D(this.beg,this.end)}}function ProjectPointToSegment2D(e,t){let r=SubCoord2D(e.end,e.beg),n=DotVector2D(r,SubCoord2D(t,e.beg)),i=DotVector2D(r,r);if(IsZero(i))return e.beg.Clone();let o=n/i;return o=Math.max(0,Math.min(1,o)),new Coord2D(e.beg.x+o*r.x,e.beg.y+o*r.y)}function SegmentPointDistance2D(e,t){return CoordDistance2D(ProjectPointToSegment2D(e,t),t)}class OctreeNode{constructor(e,t){this.boundingBox=e,this.level=t,this.pointItems=[],this.childNodes=[]}AddPoint(e,t,r){let n=this.FindNodeForPoint(e);if(null===n)return!1;if(null!==n.FindPointDirectly(e))return!1;if(n.pointItems.length<r.maxPointsPerNode||n.level>=r.maxTreeDepth)return n.AddPointDirectly(e,t),!0;{n.CreateChildNodes();let i=n.pointItems;n.pointItems=[];for(let e=0;e<i.length;e++){let t=i[e];if(!n.AddPoint(t.point,t.data,r))return!1}return n.AddPoint(e,t,r)}}FindPoint(e){let t=this.FindNodeForPoint(e);return null===t?null:t.FindPointDirectly(e)}AddPointDirectly(e,t){this.pointItems.push({point:e,data:t})}FindPointDirectly(e){for(let t=0;t<this.pointItems.length;t++){let r=this.pointItems[t];if(CoordIsEqual3D(e,r.point))return r.data}return null}FindNodeForPoint(e){if(!this.IsPointInBounds(e))return null;if(0===this.childNodes.length)return this;for(let t=0;t<this.childNodes.length;t++){let r=this.childNodes[t].FindNodeForPoint(e);if(null!==r)return r}return null}CreateChildNodes(){function e(e,t,r,n,i,o,s){let a=new Box3D(new Coord3D(t,r,n),new Coord3D(t+i,r+o,n+s));e.childNodes.push(new OctreeNode(a,e.level+1))}let t=this.boundingBox.min,r=this.boundingBox.GetCenter(),n=(this.boundingBox.max.x-this.boundingBox.min.x)/2,i=(this.boundingBox.max.y-this.boundingBox.min.y)/2,o=(this.boundingBox.max.z-this.boundingBox.min.z)/2;e(this,t.x,t.y,t.z,n,i,o),e(this,r.x,t.y,t.z,n,i,o),e(this,t.x,r.y,t.z,n,i,o),e(this,r.x,r.y,t.z,n,i,o),e(this,t.x,t.y,r.z,n,i,o),e(this,r.x,t.y,r.z,n,i,o),e(this,t.x,r.y,r.z,n,i,o),e(this,r.x,r.y,r.z,n,i,o)}IsPointInBounds(e){return IsGreaterOrEqual(e.x,this.boundingBox.min.x)&&IsGreaterOrEqual(e.y,this.boundingBox.min.y)&&IsGreaterOrEqual(e.z,this.boundingBox.min.z)&&IsLowerOrEqual(e.x,this.boundingBox.max.x)&&IsLowerOrEqual(e.y,this.boundingBox.max.y)&&IsLowerOrEqual(e.z,this.boundingBox.max.z)}}class Octree{constructor(e,t){this.options={maxPointsPerNode:10,maxTreeDepth:10},void 0!==t&&(void 0!==t.maxPointsPerNode&&(this.options.maxPointsPerNode=t.maxPointsPerNode),void 0!==t.maxTreeDepth&&(this.options.maxTreeDepth=t.maxTreeDepth)),this.rootNode=new OctreeNode(e,0)}AddPoint(e,t){return this.rootNode.AddPoint(e,t,this.options)}FindPoint(e){return this.rootNode.FindPoint(e)}}function BezierTweenFunction(e,t,r){let n=t/r;return e*(n*n*(3-2*n))}function LinearTweenFunction(e,t,r){return t*e/r}function ParabolicTweenFunction(e,t,r){let n=t/r,i=n*n;return e*(i/(2*(i-n)+1))}function TweenCoord3D(e,t,r,n){let i=SubCoord3D(t,e).Normalize(),o=CoordDistance3D(e,t),s=[];for(let t=0;t<r;t++){let a=n(o,t,r-1);s.push(e.Clone().Offset(i,a))}return s}class InputFile{constructor(e,t,r){this.name=e,this.source=t,this.data=r}}function InputFilesFromUrls(e){let t=[];for(let r of e){let e=GetFileName(r);t.push(new InputFile(e,FileSource.Url,r))}return t}function InputFilesFromFileObjects(e){let t=[];for(let r of e){let e=GetFileName(r.name);t.push(new InputFile(e,FileSource.File,r))}return t}class ImporterFile{constructor(e,t,r){this.name=GetFileName(e),this.extension=GetFileExtension(e),this.source=t,this.data=r,this.content=null}SetContent(e){this.content=e}}class ImporterFileList{constructor(){this.files=[]}FillFromInputFiles(e){this.files=[];for(let t of e){let e=new ImporterFile(t.name,t.source,t.data);this.files.push(e)}}ExtendFromFileList(e){let t=e.GetFiles();for(let e=0;e<t.length;e++){let r=t[e];this.ContainsFileByPath(r.name)||this.files.push(r)}}GetFiles(){return this.files}GetContent(e){RunTasks(this.files.length,{runTask:(t,r)=>{e.onFileListProgress(t,this.files.length),this.GetFileContent(this.files[t],{onReady:r,onProgress:e.onFileLoadProgress})},onReady:e.onReady})}ContainsFileByPath(e){return null!==this.FindFileByPath(e)}FindFileByPath(e){let t=GetFileName(e).toLowerCase();for(let e=0;e<this.files.length;e++){let r=this.files[e];if(r.name.toLowerCase()===t)return r}return null}IsOnlyUrlSource(){if(0===this.files.length)return!1;for(let e=0;e<this.files.length;e++){let t=this.files[e];if(t.source!==FileSource.Url&&t.source!==FileSource.Decompressed)return!1}return!0}AddFile(e){this.files.push(e)}GetFileContent(e,t){if(null!==e.content)return void t.onReady();let r=null;if(e.source===FileSource.Url)r=RequestUrl(e.data,t.onProgress);else{if(e.source!==FileSource.File)return void t.onReady();r=ReadFile(e.data,t.onProgress)}r.then((t=>{e.SetContent(t)})).catch((()=>{})).finally((()=>{t.onReady()}))}}class NodeIdGenerator{constructor(){this.nextId=0}GenerateId(){const e=this.nextId;return this.nextId+=1,e}}class Node{constructor(){this.name="",this.parent=null,this.transformation=new Transformation,this.childNodes=[],this.meshIndices=[],this.idGenerator=new NodeIdGenerator,this.id=this.idGenerator.GenerateId()}IsEmpty(){return 0===this.childNodes.length&&0===this.meshIndices.length}IsMeshNode(){return 0===this.childNodes.length&&1===this.meshIndices.length}GetId(){return this.id}GetName(){return this.name}SetName(e){this.name=e}HasParent(){return null!==this.parent}GetParent(){return this.parent}GetTransformation(){return this.transformation}GetWorldTransformation(){let e=this.transformation.Clone(),t=this.parent;for(;null!==t;)e.Append(t.transformation),t=t.parent;return e}SetTransformation(e){this.transformation=e}AddChildNode(e){return e.parent=this,e.idGenerator=this.idGenerator,e.id=e.idGenerator.GenerateId(),this.childNodes.push(e),this.childNodes.length-1}RemoveChildNode(e){e.parent=null;let t=this.childNodes.indexOf(e);this.childNodes.splice(t,1)}GetChildNodes(){return this.childNodes}ChildNodeCount(){return this.childNodes.length}GetChildNode(e){return this.childNodes[e]}AddMeshIndex(e){return this.meshIndices.push(e),this.meshIndices.length-1}MeshIndexCount(){return this.meshIndices.length}GetMeshIndex(e){return this.meshIndices[e]}GetMeshIndices(){return this.meshIndices}Enumerate(e){e(this);for(const t of this.childNodes)t.Enumerate(e)}EnumerateChildren(e){for(const t of this.childNodes)e(t),t.EnumerateChildren(e)}EnumerateMeshIndices(e){for(const t of this.meshIndices)e(t);for(const t of this.childNodes)t.EnumerateMeshIndices(e)}}const Unit={Unknown:0,Millimeter:1,Centimeter:2,Meter:3,Inch:4,Foot:5};class Model extends ModelObject3D{constructor(){super(),this.unit=Unit.Unknown,this.root=new Node,this.materials=[],this.meshes=[]}GetUnit(){return this.unit}SetUnit(e){this.unit=e}GetRootNode(){return this.root}NodeCount(){let e=0;return this.root.Enumerate((t=>{e+=1})),e-1}MaterialCount(){return this.materials.length}MeshCount(){return this.meshes.length}MeshInstanceCount(){let e=0;return this.root.Enumerate((t=>{e+=t.MeshIndexCount()})),e}VertexCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.VertexCount()})),e}VertexColorCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.VertexColorCount()})),e}NormalCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.NormalCount()})),e}TextureUVCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.TextureUVCount()})),e}LineCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.LineCount()})),e}LineSegmentCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.LineSegmentCount()})),e}TriangleCount(){let e=0;return this.EnumerateMeshInstances((t=>{e+=t.TriangleCount()})),e}AddMaterial(e){return this.materials.push(e),this.materials.length-1}GetMaterial(e){return this.materials[e]}AddMesh(e){return this.meshes.push(e),this.meshes.length-1}AddMeshToRootNode(e){const t=this.AddMesh(e);return this.root.AddMeshIndex(t),t}RemoveMesh(e){this.meshes.splice(e,1),this.root.Enumerate((t=>{for(let r=0;r<t.meshIndices.length;r++)t.meshIndices[r]===e?(t.meshIndices.splice(r,1),r-=1):t.meshIndices[r]>e&&(t.meshIndices[r]-=1)}))}GetMesh(e){return this.meshes[e]}GetMeshInstance(e){let t=null;if(this.root.Enumerate((r=>{r.GetId()===e.nodeId&&(t=r)})),null===t)return null;if(-1===t.GetMeshIndices().indexOf(e.meshIndex))return null;let r=this.GetMesh(e.meshIndex),n=new MeshInstanceId(t.GetId(),e.meshIndex);return new MeshInstance(n,t,r)}EnumerateMeshes(e){for(const t of this.meshes)e(t)}EnumerateMeshInstances(e){this.root.Enumerate((t=>{for(let r of t.GetMeshIndices()){let n=new MeshInstanceId(t.GetId(),r),i=this.GetMesh(r),o=new MeshInstance(n,t,i);e(o)}}))}EnumerateTransformedMeshInstances(e){this.EnumerateMeshInstances((t=>{const r=t.GetTransformedMesh();e(r)}))}EnumerateVertices(e){this.EnumerateMeshInstances((t=>{t.EnumerateVertices(e)}))}EnumerateTriangleVertexIndices(e){this.EnumerateMeshInstances((t=>{t.EnumerateTriangleVertexIndices(e)}))}EnumerateTriangleVertices(e){this.EnumerateMeshInstances((t=>{t.EnumerateTriangleVertices(e)}))}}class TopologyVertex{constructor(){this.edges=[],this.triangles=[]}}class TopologyEdge{constructor(e,t){this.vertex1=e,this.vertex2=t,this.triangles=[]}}class TopologyTriangleEdge{constructor(e,t){this.edge=e,this.reversed=t}}class TopologyTriangle{constructor(){this.triEdge1=null,this.triEdge2=null,this.triEdge3=null}}class Topology{constructor(){this.vertices=[],this.edges=[],this.triangleEdges=[],this.triangles=[],this.edgeStartToEndVertexMap=new Map}AddVertex(){return this.vertices.push(new TopologyVertex),this.vertices.length-1}AddTriangle(e,t,r){function n(e,t,r){e[t].triangles.push(r)}function i(e,t,r,n){let i=e[r],o=t[n];i.edges.push(o.edge)}function o(e,t,r,n){e[t[r].edge].triangles.push(n)}let s=this.triangles.length,a=new TopologyTriangle;a.triEdge1=this.AddTriangleEdge(e,t),a.triEdge2=this.AddTriangleEdge(t,r),a.triEdge3=this.AddTriangleEdge(r,e),n(this.vertices,e,s),n(this.vertices,t,s),n(this.vertices,r,s),i(this.vertices,this.triangleEdges,e,a.triEdge1),i(this.vertices,this.triangleEdges,t,a.triEdge2),i(this.vertices,this.triangleEdges,r,a.triEdge3),o(this.edges,this.triangleEdges,a.triEdge1,s),o(this.edges,this.triangleEdges,a.triEdge2,s),o(this.edges,this.triangleEdges,a.triEdge3,s),this.triangles.push(a)}AddTriangleEdge(e,t){let r=e,n=t,i=!1;t<e&&(r=t,n=e,i=!0);let o=this.AddEdge(r,n);return this.triangleEdges.push(new TopologyTriangleEdge(o,i)),this.triangleEdges.length-1}AddEdge(e,t){this.edgeStartToEndVertexMap.has(e)||this.edgeStartToEndVertexMap.set(e,[]);let r=this.edgeStartToEndVertexMap.get(e);for(let e=0;e<r.length;e++){let n=r[e];if(n.endVertex===t)return n.edgeIndex}let n=this.edges.length;return r.push({endVertex:t,edgeIndex:n}),this.edges.push(new TopologyEdge(e,t)),n}}function IsModelEmpty(e){let t=!0;return e.EnumerateMeshInstances((e=>{IsEmptyMesh(e)||(t=!1)})),t}function GetBoundingBox(e){let t=new BoundingBoxCalculator3D;return e.EnumerateVertices((e=>{t.AddPoint(e)})),t.GetBox()}function GetTopology(e){function t(e,t,r){let n=t.FindPoint(e);return null===n&&(n=r.AddVertex(),t.AddPoint(e,n)),n}let r=GetBoundingBox(e),n=new Octree(r),i=new Topology;return e.EnumerateTriangleVertices(((e,r,o)=>{let s=t(e,n,i),a=t(r,n,i),l=t(o,n,i);i.AddTriangle(s,a,l)})),i}function IsTwoManifold(e){function t(e,t,r){const n=e.triangles[t],i=e.triangleEdges[n.triEdge1],o=e.triangleEdges[n.triEdge2],s=e.triangleEdges[n.triEdge3];return i.edge===r?i.reversed:o.edge===r?o.reversed:s.edge===r?s.reversed:null}if(e instanceof Model){let t=!0;return e.EnumerateMeshInstances((e=>{t&&(t=IsTwoManifold(e))})),t}{const r=GetTopology(e);for(let e=0;e<r.edges.length;e++){const n=r.edges[e];if(2!==n.triangles.length)return!1;let i=t(r,n.triangles[0],e),o=t(r,n.triangles[1],e);if(null===i||null===o||i===o)return!1}return!0}}function GetDefaultMaterials(e){let t=[];for(let r=0;r<e.MaterialCount();r++){let n=e.GetMaterial(r);n.source===MaterialSource.Model||n.vertexColors||t.push(n)}return t}function ReplaceDefaultMaterialsColor(e,t,r){for(let n=0;n<e.MaterialCount();n++){let i=e.GetMaterial(n);i.source===MaterialSource.DefaultFace?i.color=t:i.source===MaterialSource.DefaultLine&&(i.color=r)}}class Mesh extends ModelObject3D{constructor(){super(),this.vertices=[],this.vertexColors=[],this.normals=[],this.uvs=[],this.lines=[],this.triangles=[]}VertexCount(){return this.vertices.length}VertexColorCount(){return this.vertexColors.length}NormalCount(){return this.normals.length}TextureUVCount(){return this.uvs.length}LineCount(){return this.lines.length}LineSegmentCount(){let e=0;for(let t of this.lines)e+=t.SegmentCount();return e}TriangleCount(){return this.triangles.length}AddVertex(e){return this.vertices.push(e),this.vertices.length-1}SetVertex(e,t){this.vertices[e]=t}GetVertex(e){return this.vertices[e]}AddVertexColor(e){return this.vertexColors.push(e),this.vertexColors.length-1}SetVertexColor(e,t){this.vertexColors[e]=t}GetVertexColor(e){return this.vertexColors[e]}AddNormal(e){return this.normals.push(e),this.normals.length-1}SetNormal(e,t){this.normals[e]=t}GetNormal(e){return this.normals[e]}AddTextureUV(e){return this.uvs.push(e),this.uvs.length-1}SetTextureUV(e,t){this.uvs[e]=t}GetTextureUV(e){return this.uvs[e]}AddLine(e){return this.lines.push(e),this.lines.length-1}GetLine(e){return this.lines[e]}AddTriangle(e){return this.triangles.push(e),this.triangles.length-1}GetTriangle(e){return this.triangles[e]}EnumerateVertices(e){for(const t of this.vertices)e(t)}EnumerateTriangleVertexIndices(e){for(const t of this.triangles)e(t.v0,t.v1,t.v2)}EnumerateTriangleVertices(e){for(const t of this.triangles){e(this.vertices[t.v0],this.vertices[t.v1],this.vertices[t.v2])}}Clone(){let e=new Mesh;e.SetName(this.GetName()),this.CloneProperties(e);for(let t=0;t<this.VertexCount();t++){let r=this.GetVertex(t);e.AddVertex(r.Clone())}for(let t=0;t<this.VertexColorCount();t++){let r=this.GetVertexColor(t);e.AddVertexColor(r.Clone())}for(let t=0;t<this.NormalCount();t++){let r=this.GetNormal(t);e.AddNormal(r.Clone())}for(let t=0;t<this.TextureUVCount();t++){let r=this.GetTextureUV(t);e.AddTextureUV(r.Clone())}for(let t=0;t<this.LineCount();t++){let r=this.GetLine(t);e.AddLine(r.Clone())}for(let t=0;t<this.TriangleCount();t++){let r=this.GetTriangle(t);e.AddTriangle(r.Clone())}return e}}class Triangle{constructor(e,t,r){this.v0=e,this.v1=t,this.v2=r,this.c0=null,this.c1=null,this.c2=null,this.n0=null,this.n1=null,this.n2=null,this.u0=null,this.u1=null,this.u2=null,this.mat=null,this.curve=null}HasVertices(){return null!==this.v0&&null!==this.v1&&null!==this.v2}HasVertexColors(){return null!==this.c0&&null!==this.c1&&null!==this.c2}HasNormals(){return null!==this.n0&&null!==this.n1&&null!==this.n2}HasTextureUVs(){return null!==this.u0&&null!==this.u1&&null!==this.u2}SetVertices(e,t,r){return this.v0=e,this.v1=t,this.v2=r,this}SetVertexColors(e,t,r){return this.c0=e,this.c1=t,this.c2=r,this}SetNormals(e,t,r){return this.n0=e,this.n1=t,this.n2=r,this}SetTextureUVs(e,t,r){return this.u0=e,this.u1=t,this.u2=r,this}SetMaterial(e){return this.mat=e,this}SetCurve(e){return this.curve=e,this}Clone(){let e=new Triangle(this.v0,this.v1,this.v2);return e.SetVertexColors(this.c0,this.c1,this.c2),e.SetNormals(this.n0,this.n1,this.n2),e.SetTextureUVs(this.u0,this.u1,this.u2),e.SetMaterial(this.mat),e.SetCurve(this.curve),e}}function HasHighpDriverIssue(){let e=document.createElement("canvas");document.body.appendChild(e);let t={canvas:e,antialias:!0},r=new THREE.WebGLRenderer(t);r.outputColorSpace=THREE.LinearSRGBColorSpace,r.setClearColor("#ffffff",1),r.setSize(10,10);let n=new THREE.Scene,i=new THREE.AmbientLight(8947848);n.add(i);let o=new THREE.DirectionalLight(8947848);o.position.set(0,0,1),n.add(o);let s=new THREE.PerspectiveCamera(45,1,.1,1e3);s.position.set(0,0,1),s.up.set(0,1,0),s.lookAt(new THREE.Vector3(0,0,0)),n.add(s);let a=new THREE.PlaneGeometry(1,1),l=new THREE.Mesh(a,new THREE.MeshPhongMaterial({color:13369344}));n.add(l),r.render(n,s);let h=r.getContext(),u=new Uint8Array(4);h.readPixels(5,5,1,1,h.RGBA,h.UNSIGNED_BYTE,u),document.body.removeChild(e);return u[0]<50&&u[1]<50&&u[2]<50}const ShadingType={Phong:1,Physical:2};function GetShadingType(e){let t=0,r=0;for(let n=0;n<e.MaterialCount();n++){let i=e.GetMaterial(n);i.type===MaterialType.Phong?t+=1:i.type===MaterialType.Physical&&(r+=1)}return t>=r?ShadingType.Phong:ShadingType.Physical}class ThreeColorConverter{Convert(e){return null}}class ThreeLinearToSRGBColorConverter extends ThreeColorConverter{Convert(e){return(new THREE.Color).copyLinearToSRGB(e)}}class ThreeSRGBToLinearColorConverter extends ThreeColorConverter{Convert(e){return(new THREE.Color).copySRGBToLinear(e)}}function ConvertThreeColorToColor(e){return RGBColorFromFloatComponents(e.r,e.g,e.b)}function ConvertColorToThreeColor(e){return new THREE.Color(e.r/255,e.g/255,e.b/255)}function ConvertThreeGeometryToMesh(e,t,r){let n=new Mesh,i=e.attributes.position.array,o=e.attributes.position.itemSize||3;for(let e=0;e<i.length;e+=o){let t=i[e],r=i[e+1],o=i[e+2];n.AddVertex(new Coord3D(t,r,o))}let s=void 0!==e.attributes.color;if(s){let t=e.attributes.color.array,i=e.attributes.color.itemSize||3;for(let e=0;e<t.length;e+=i){let i=new THREE.Color(t[e],t[e+1],t[e+2]);null!==r&&(i=r.Convert(i)),n.AddVertexColor(ConvertThreeColorToColor(i))}}let a=void 0!==e.attributes.normal;if(a){let t=e.attributes.normal.array,r=e.attributes.normal.itemSize||3;for(let e=0;e<t.length;e+=r){let r=t[e],i=t[e+1],o=t[e+2];n.AddNormal(new Coord3D(r,i,o))}}let l=void 0!==e.attributes.uv;if(l){let t=e.attributes.uv.array,r=e.attributes.uv.itemSize||2;for(let e=0;e<t.length;e+=r){let r=t[e],i=t[e+1];n.AddTextureUV(new Coord2D(r,i))}}let h=null;if(null!==e.index)h=e.index.array;else{h=[];for(let e=0;e<i.length/3;e++)h.push(e)}for(let e=0;e<h.length;e+=3){let r=h[e],i=h[e+1],o=h[e+2],u=new Triangle(r,i,o);s&&u.SetVertexColors(r,i,o),a&&u.SetNormals(r,i,o),l&&u.SetTextureUVs(r,i,o),null!==t&&u.SetMaterial(t),n.AddTriangle(u)}return n}function CreateHighlightMaterial(e,t,r){let n=null;return"MeshPhongMaterial"===e.type?n=new THREE.MeshPhongMaterial({color:ConvertColorToThreeColor(t),side:THREE.DoubleSide}):"MeshStandardMaterial"===e.type?n=new THREE.MeshStandardMaterial({color:ConvertColorToThreeColor(t),side:THREE.DoubleSide}):"LineBasicMaterial"===e.type&&(n=new THREE.LineBasicMaterial({color:ConvertColorToThreeColor(t)})),null!==n&&r&&(n.polygonOffset=!0,n.polygonOffsetUnit=1,n.polygonOffsetFactor=1),n}function CreateHighlightMaterials(e,t,r){let n=new Map,i=[];for(let o of e){if(n.has(o.type)){i.push(n.get(o.type));continue}let e=CreateHighlightMaterial(o,t,r);n.set(o.type,e),i.push(e)}return i}function DisposeThreeObjects(e){null!==e&&e.traverse((e=>{if(e.isMesh||e.isLineSegments){if(Array.isArray(e.material))for(let t of e.material)t.dispose();else e.material.dispose();e.userData=null,e.geometry.dispose()}}))}function GetLineSegmentsProjectedDistance(e,t,r,n,i){function o(e,t,r,n,i,o){let s=new THREE.Vector3(i[3*o],i[3*o+1],i[3*o+2]);s.applyMatrix4(n.matrixWorld);let a=s.project(e);return new Coord2D((a.x+1)*t/2,-(a.y-1)*r/2)}let s=n.geometry.attributes.position.array,a=s.length/6,l=1/0;for(let h=0;h<a;h++){let a=new Segment2D(o(e,t,r,n,s,2*h),o(e,t,r,n,s,2*h+1));l=Math.min(l,SegmentPointDistance2D(a,i))}return l}class ModelFinalizer{constructor(e){this.params={defaultLineMaterialColor:new RGBColor(0,0,0),defaultMaterialColor:new RGBColor(0,0,0)},CopyObjectAttributes(e,this.params),this.defaultLineMaterialIndex=null,this.defaultMaterialIndex=null}Finalize(e){this.Reset(),this.FinalizeMeshes(e),this.FinalizeMaterials(e),this.FinalizeNodes(e)}FinalizeMaterials(e){if(0===e.VertexColorCount())return;let t=new Map;for(let r=0;r<e.MeshCount();r++){let n=e.GetMesh(r);for(let e=0;e<n.TriangleCount();e++){let r=n.GetTriangle(e),i=r.HasVertexColors();t.has(r.mat)?i||t.set(r.mat,!1):t.set(r.mat,i)}}for(let[r,n]of t){e.GetMaterial(r).vertexColors=n}}FinalizeMeshes(e){for(let t=0;t<e.MeshCount();t++){let r=e.GetMesh(t);IsEmptyMesh(r)?(e.RemoveMesh(t),t-=1):this.FinalizeMesh(e,r)}}FinalizeMesh(e,t){let r={calculateCurveNormals:!1};for(let r=0;r<t.LineCount();r++){let n=t.GetLine(r);null===n.mat&&(n.mat=this.GetDefaultMaterialIndex(e,MaterialSource.DefaultLine))}for(let n=0;n<t.TriangleCount();n++){let i=t.GetTriangle(n);this.FinalizeTriangle(t,i,r),null===i.mat&&(i.mat=this.GetDefaultMaterialIndex(e,MaterialSource.DefaultFace))}r.calculateCurveNormals&&function(e){function t(e,t,r,n,i){function o(e,t){for(let r=0;r<e.length;r++)if(CoordIsEqual3D(e[r],t))return!0;return!1}let s=[],a=i.get(r);for(let r=0;r<a.length;r++){let i=a[r],l=e.GetTriangle(i);if(t.curve===l.curve){let e=n[i];o(s,e)||s.push(e)}}let l=new Coord3D(0,0,0);for(let e=0;e<s.length;e++)l=AddCoord3D(l,s[e]);return l.MultiplyScalar(1/s.length),l.Normalize(),e.AddNormal(l)}let r=[],n=new Map;for(let t=0;t<e.VertexCount();t++)n.set(t,[]);for(let t=0;t<e.TriangleCount();t++){let i=e.GetTriangle(t),o=CalculateTriangleNormal(e.GetVertex(i.v0),e.GetVertex(i.v1),e.GetVertex(i.v2));r.push(o),n.get(i.v0).push(t),n.get(i.v1).push(t),n.get(i.v2).push(t)}for(let i=0;i<e.TriangleCount();i++){let o=e.GetTriangle(i);if(!o.HasNormals()){let i=t(e,o,o.v0,r,n),s=t(e,o,o.v1,r,n),a=t(e,o,o.v2,r,n);o.SetNormals(i,s,a)}}}(t)}FinalizeTriangle(e,t,r){if(!t.HasNormals())if(null===t.curve||0===t.curve){let r=CalculateTriangleNormal(e.GetVertex(t.v0),e.GetVertex(t.v1),e.GetVertex(t.v2)),n=e.AddNormal(r);t.SetNormals(n,n,n)}else r.calculateCurveNormals=!0;null===t.curve&&(t.curve=0)}FinalizeNodes(e){let t=e.GetRootNode(),r=[];t.EnumerateChildren((e=>{e.IsEmpty()&&r.push(e)}));for(let e=0;e<r.length;e++){let t=r[e],n=t.GetParent();null!==n&&(n.RemoveChildNode(t),n.IsEmpty()&&r.push(n))}}GetDefaultMaterialIndex(e,t){function r(e,t,r,n){if(null!==t)return t;let i=new PhongMaterial;return i.color=n,i.source=r,e.AddMaterial(i)}return t===MaterialSource.DefaultLine?(this.defaultLineMaterialIndex=r(e,this.defaultLineMaterialIndex,MaterialSource.DefaultLine,this.params.defaultLineMaterialColor),this.defaultLineMaterialIndex):t===MaterialSource.DefaultFace?(this.defaultMaterialIndex=r(e,this.defaultMaterialIndex,MaterialSource.DefaultFace,this.params.defaultMaterialColor),this.defaultMaterialIndex):null}Reset(){this.defaultLineMaterialIndex=null,this.defaultMaterialIndex=null}}function FinalizeModel(e,t){new ModelFinalizer(t).Finalize(e)}function CheckModel(e){function t(e){return!!function(e){return null!=e}(e)&&!isNaN(e)}function r(e,r){return!!t(e)&&!(e<0||e>=r)}function n(e,n){function i(e,n,i){if(!r(i.v0,n.VertexCount()))return!1;if(!r(i.v1,n.VertexCount()))return!1;if(!r(i.v2,n.VertexCount()))return!1;if(i.HasVertexColors()){if(!r(i.c0,n.VertexColorCount()))return!1;if(!r(i.c1,n.VertexColorCount()))return!1;if(!r(i.c2,n.VertexColorCount()))return!1}if(!r(i.n0,n.NormalCount()))return!1;if(!r(i.n1,n.NormalCount()))return!1;if(!r(i.n2,n.NormalCount()))return!1;if(i.HasTextureUVs()){if(!r(i.u0,n.TextureUVCount()))return!1;if(!r(i.u1,n.TextureUVCount()))return!1;if(!r(i.u2,n.TextureUVCount()))return!1}return!!r(i.mat,e.MaterialCount())&&!!t(i.curve)}for(let e=0;e<n.VertexCount();e++){let r=n.GetVertex(e);if(!t(r.x))return!1;if(!t(r.y))return!1;if(!t(r.z))return!1}for(let e=0;e<n.VertexColorCount();e++){let r=n.GetVertexColor(e);if(!t(r.r))return!1;if(!t(r.g))return!1;if(!t(r.b))return!1}for(let e=0;e<n.NormalCount();e++){let r=n.GetNormal(e);if(!t(r.x))return!1;if(!t(r.y))return!1;if(!t(r.z))return!1}for(let e=0;e<n.TextureUVCount();e++){let r=n.GetTextureUV(e);if(!t(r.x))return!1;if(!t(r.y))return!1}for(let t=0;t<n.TriangleCount();t++){let r=n.GetTriangle(t);if(!i(e,n,r))return!1}return!0}for(let t=0;t<e.MeshCount();t++){let r=e.GetMesh(t);if(!n(e,r))return!1}return!0}class ImporterBase{constructor(){this.name=null,this.extension=null,this.callbacks=null,this.model=null,this.error=null,this.message=null}Import(e,t,r,n){this.Clear(),this.name=e,this.extension=t,this.callbacks=n,this.model=new Model,this.error=!1,this.message=null,this.ResetContent(),this.ImportContent(r,(()=>{this.CreateResult(n)}))}Clear(){this.name=null,this.extension=null,this.callbacks=null,this.model=null,this.error=null,this.message=null,this.ClearContent()}CreateResult(e){return this.error?(e.onError(),void e.onComplete()):IsModelEmpty(this.model)?(this.SetError("The model doesn't contain any meshes."),e.onError(),void e.onComplete()):(FinalizeModel(this.model,{defaultLineMaterialColor:this.callbacks.getDefaultLineMaterialColor(),defaultMaterialColor:this.callbacks.getDefaultMaterialColor()}),e.onSuccess(),void e.onComplete())}CanImportExtension(e){return!1}GetUpDirection(){return Direction.Z}ClearContent(){}ResetContent(){}ImportContent(e,t){}GetModel(){return this.model}SetError(e){this.error=!0,null!=e&&(this.message=e)}WasError(){return this.error}GetErrorMessage(){return this.message}}function NameFromLine(e,t,r){let n=e.substring(t),i=n.indexOf(r);return-1!==i&&(n=n.substring(0,i)),n.trim()}function ParametersFromLine(e,t){if(null!==t){let r=e.indexOf(t);-1!==r&&(e=e.substring(0,r).trim())}return e.split(/\s+/u)}function ReadLines(e,t){function r(e,t){let r=e.trim();r.length>0&&t(r)}let n=0,i=e.indexOf("\n",n);for(;-1!==i;)r(e.substring(n,i),t),n=i+1,i=e.indexOf("\n",n);r(e.substring(n),t)}function IsPowerOfTwo(e){return!(e&e-1)}function NextPowerOfTwo(e){if(IsPowerOfTwo(e))return e;let t=Math.pow(2,Math.ceil(Math.log(e)/Math.log(2)));return parseInt(t,10)}function UpdateMaterialTransparency(e){e.transparent=!1,IsLower(e.opacity,1)&&(e.transparent=!0)}class ColorToMaterialConverter{constructor(e){this.model=e,this.colorToMaterialIndex=new Map}GetMaterialIndex(e,t,r,n){let i=IntegerToHexString(e)+IntegerToHexString(t)+IntegerToHexString(r),o=null!=n;if(o&&(i+=IntegerToHexString(n)),this.colorToMaterialIndex.has(i))return this.colorToMaterialIndex.get(i);{let s=new PhongMaterial;s.name=i.toUpperCase(),s.color=new RGBColor(e,t,r),o&&n<255&&(s.opacity=n/255,UpdateMaterialTransparency(s));let a=this.model.AddMaterial(s);return this.colorToMaterialIndex.set(i,a),a}}}class Line{constructor(e){this.vertices=e,this.mat=null}HasVertices(){return null!==this.vertices&&this.vertices.length>=2}GetVertices(){return this.vertices}SetMaterial(e){return this.mat=e,this}SegmentCount(){return null===this.vertices?0:this.vertices.length-1}Clone(){let e=new Line([...this.vertices]);return e.SetMaterial(this.mat),e}}class Importer3dm extends ImporterBase{constructor(){super(),this.rhino=null}CanImportExtension(e){return"3dm"===e}GetUpDirection(){return Direction.Z}ClearContent(){this.instanceIdToObject=null,this.instanceIdToDefinition=null}ResetContent(){this.instanceIdToObject=new Map,this.instanceIdToDefinition=new Map}ImportContent(e,t){null===this.rhino?LoadExternalLibrary("loaders/rhino3dm.min.js").then((()=>{rhino3dm().then((r=>{this.rhino=r,this.ImportRhinoContent(e),t()}))})).catch((()=>{this.SetError("Failed to load rhino3dm."),t()})):(this.ImportRhinoContent(e),t())}ImportRhinoContent(e){let t=this.rhino.File3dm.fromByteArray(e);null!==t?(this.ImportRhinoDocument(t),IsModelEmpty(this.model)&&this.SetError("The model doesn't contain any 3D meshes. Try to save the model while you are in shaded view in Rhino.")):this.SetError("Failed to read Rhino file.")}ImportRhinoDocument(e){this.InitRhinoInstances(e),this.ImportRhinoUserStrings(e),this.ImportRhinoGeometry(e)}InitRhinoInstances(e){let t=e.objects();for(let e=0;e<t.count;e++){let r=t.get(e),n=r.attributes();n.isInstanceDefinitionObject&&this.instanceIdToObject.set(n.id,r)}let r=e.instanceDefinitions();for(let e=0;e<r.count;e++){let t=r.get(e);this.instanceIdToDefinition.set(t.id,t)}}ImportRhinoUserStrings(e){let t=e.strings();if(t.count>0){let e=new PropertyGroup("Document user texts");for(let r=0;r<t.count;r++){let n=t.get(r);e.AddProperty(new Property(PropertyType.Text,n[0],n[1]))}this.model.AddPropertyGroup(e)}}ImportRhinoGeometry(e){let t=e.objects();for(let r=0;r<t.count;r++){let n=t.get(r);this.ImportRhinoGeometryObject(e,n,[])}}ImportRhinoGeometryObject(e,t,r){let n=t.geometry(),i=t.attributes(),o=n.objectType;if(!i.isInstanceDefinitionObject||0!==r.length)if(o===this.rhino.ObjectType.Mesh)this.ImportRhinoGeometryAsMesh(e,n,t,r);else if(o===this.rhino.ObjectType.Extrusion){let i=n.getMesh(this.rhino.MeshType.Any);null!==i&&(this.ImportRhinoGeometryAsMesh(e,i,t,r),i.delete())}else if(o===this.rhino.ObjectType.Brep){let i=new this.rhino.Mesh,o=n.faces();for(let e=0;e<o.count;e++){let t=o.get(e),r=t.getMesh(this.rhino.MeshType.Any);r&&(i.append(r),r.delete()),t.delete()}o.delete(),i.compact(),this.ImportRhinoGeometryAsMesh(e,i,t,r),i.delete()}else if(o===this.rhino.ObjectType.SubD){n.subdivide(3);let i=this.rhino.Mesh.createFromSubDControlNet(n);null!==i&&(this.ImportRhinoGeometryAsMesh(e,i,t,r),i.delete())}else if(o===this.rhino.ObjectType.Curve)this.ImportRhinoGeometryAsMesh(e,n,t,r);else if(o===this.rhino.ObjectType.InstanceReference){let i=n.parentIdefId;if(this.instanceIdToDefinition.has(i)){let n=this.instanceIdToDefinition.get(i).getObjectIds();for(let i=0;i<n.length;i++){let o=n[i];if(this.instanceIdToObject.has(o)){let n=this.instanceIdToObject.get(o);r.push(t),this.ImportRhinoGeometryObject(e,n,r),r.pop()}}}}}ImportRhinoGeometryAsMesh(e,t,r,n){function i(e){let r=e.domain[1]-e.domain[0],n=Math.max(parseInt(r/.2,10),1),i=r/n,o=[];for(let r=0;r<=n;r++)if(r===n&&e.isClosed)o.push(o[0]);else{let n=t.pointAt(e.domain[0]+r*i);o.push(s.AddVertex(ArrayToCoord3D(n)))}return new Line(o)}let o=this.GetMaterialIndex(e,r,n),s=null;if(t.objectType===this.rhino.ObjectType.Mesh){let e=t.toThreejsJSON();s=ConvertThreeGeometryToMesh(e.data,o,null)}else if(t.objectType===this.rhino.ObjectType.Curve)if(s=new Mesh,t instanceof this.rhino.LineCurve){let e=s.AddVertex(ArrayToCoord3D(t.line.from)),r=s.AddVertex(ArrayToCoord3D(t.line.to)),n=new Line([e,r]);n.SetMaterial(o),s.AddLine(n)}else if(t instanceof this.rhino.NurbsCurve){let e=i(t);e.SetMaterial(o),s.AddLine(e)}else if(t instanceof this.rhino.ArcCurve){let e=i(t);e.SetMaterial(o),s.AddLine(e)}if(null===s)return null;let a=r.attributes();s.SetName(a.name);let l=a.getUserStrings();if(l.length>0){let e=new PropertyGroup("User texts");for(let t=0;t<l.length;t++){let r=l[t];e.AddProperty(new Property(PropertyType.Text,r[0],r[1]))}s.AddPropertyGroup(e)}if(0!==n.length){let e=(new Matrix).CreateIdentity();for(let t=n.length-1;t>=0;t--){let r=n[t].geometry().xform.toFloatArray(!1),i=new Matrix(r);e=e.MultiplyMatrix(i)}let t=new Transformation(e);TransformMesh(s,t)}this.model.AddMeshToRootNode(s)}GetMaterialIndex(e,t,r){let n=function t(r,n,i){let o=n.attributes();if(o.materialSource===r.ObjectMaterialSource.MaterialFromObject){let t=o.materialIndex;if(t>-1)return e.materials().get(t)}else if(o.materialSource===r.ObjectMaterialSource.MaterialFromLayer){let t=o.layerIndex;if(t>-1){let i=e.layers().get(t),o=i.renderMaterialIndex;if(o>-1)return e.materials().get(o);if(n.geometry().objectType===r.ObjectType.Curve){let e=new r.Material;return e.name=i.name,e.diffuseColor=i.color,e}}}else if(o.materialSource===r.ObjectMaterialSource.MaterialFromParent&&0!==i.length)return t(r,i[0],[]);return null}(this.rhino,t,r);return null===n?null:function(e,t,r){let n=function(e,t){function r(e,t){e.Set(t.r,t.g,t.b)}function n(e){return 0===e.r&&0===e.g&&0===e.b}function i(e){return 255===e.r&&255===e.g&&255===e.b}let o=null,s=e.physicallyBased();s.supported?(o=new PhysicalMaterial,o.metalness=s.metallic?1:0,o.roughness=s.roughness):(o=new PhongMaterial,r(o.ambient,e.ambientColor),r(o.specular,e.specularColor)),o.name=e.name,r(o.color,e.diffuseColor),o.opacity=1-e.transparency,UpdateMaterialTransparency(o),n(o.color)&&!i(e.reflectionColor)&&r(o.color,e.reflectionColor),n(o.color)&&!i(e.transparentColor)&&r(o.color,e.transparentColor);let a=e.getBitmapTexture();if(a){let e=new TextureMap,r=GetFileName(a.fileName),n=t.getFileBuffer(r);e.name=r,e.buffer=n,o.diffuseMap=e}return o}(t,r);for(let t=0;t<e.MaterialCount();t++){if(e.GetMaterial(t).IsEqual(n))return t}return e.AddMaterial(n)}(this.model,n,this.callbacks)}}class BinaryReader{constructor(e,t){this.arrayBuffer=e,this.dataView=new DataView(e),this.isLittleEndian=t,this.position=0}GetPosition(){return this.position}SetPosition(e){this.position=e}GetByteLength(){return this.arrayBuffer.byteLength}Skip(e){this.position=this.position+e}End(){return this.position>=this.arrayBuffer.byteLength}ReadArrayBuffer(e){let t=new Uint8Array(this.arrayBuffer),r=new ArrayBuffer(e),n=new Uint8Array(r),i=t.subarray(this.position,this.position+e);return n.set(i,0),this.position+=e,r}ReadBoolean8(){let e=this.dataView.getInt8(this.position);return this.position=this.position+1,!!e}ReadCharacter8(){let e=this.dataView.getInt8(this.position);return this.position=this.position+1,e}ReadUnsignedCharacter8(){let e=this.dataView.getUint8(this.position);return this.position=this.position+1,e}ReadInteger16(){let e=this.dataView.getInt16(this.position,this.isLittleEndian);return this.position=this.position+2,e}ReadUnsignedInteger16(){let e=this.dataView.getUint16(this.position,this.isLittleEndian);return this.position=this.position+2,e}ReadInteger32(){let e=this.dataView.getInt32(this.position,this.isLittleEndian);return this.position=this.position+4,e}ReadUnsignedInteger32(){let e=this.dataView.getUint32(this.position,this.isLittleEndian);return this.position=this.position+4,e}ReadFloat32(){let e=this.dataView.getFloat32(this.position,this.isLittleEndian);return this.position=this.position+4,e}ReadDouble64(){let e=this.dataView.getFloat64(this.position,this.isLittleEndian);return this.position=this.position+8,e}}const CHUNK3DS={MAIN3DS:19789,EDIT3DS:15677,EDIT_MATERIAL:45055,MAT_NAME:40960,MAT_AMBIENT:40976,MAT_DIFFUSE:40992,MAT_SPECULAR:41008,MAT_SHININESS:41024,MAT_SHININESS_STRENGTH:41025,MAT_TRANSPARENCY:41040,MAT_COLOR_F:16,MAT_COLOR:17,MAT_LIN_COLOR:18,MAT_LIN_COLOR_F:19,MAT_TEXMAP:41472,MAT_TEXMAP_NAME:41728,MAT_TEXMAP_UOFFSET:41816,MAT_TEXMAP_VOFFSET:41818,MAT_TEXMAP_USCALE:41812,MAT_TEXMAP_VSCALE:41814,MAT_TEXMAP_ROTATION:41820,PERCENTAGE:48,PERCENTAGE_F:49,EDIT_OBJECT:16384,OBJ_TRIMESH:16640,OBJ_LIGHT:17920,OBJ_CAMERA:18176,TRI_VERTEX:16656,TRI_TEXVERTEX:16704,TRI_FACE:16672,TRI_TRANSFORMATION:16736,TRI_MATERIAL:16688,TRI_SMOOTH:16720,KF3DS:45056,OBJECT_NODE:45058,OBJECT_HIERARCHY:45072,OBJECT_INSTANCE_NAME:45073,OBJECT_PIVOT:45075,OBJECT_POSITION:45088,OBJECT_ROTATION:45089,OBJECT_SCALE:45090,OBJECT_ID:45104};class Importer3dsNode{constructor(){this.id=-1,this.name="",this.flags=-1,this.parentId=-1,this.instanceName="",this.pivot=[0,0,0],this.positions=[],this.rotations=[],this.scales=[]}}class Importer3dsNodeList{constructor(){this.nodes=[],this.nodeIdToNode=new Map}IsEmpty(){return 0===this.nodes.length}AddNode(e){this.nodes.push(e),this.nodeIdToNode.set(e.nodeId,e)}GetNodes(){return this.nodes}}class Importer3ds extends ImporterBase{constructor(){super()}CanImportExtension(e){return"3ds"===e}GetUpDirection(){return Direction.Z}ClearContent(){this.materialNameToIndex=null,this.meshNameToIndex=null,this.nodeList=null}ResetContent(){this.materialNameToIndex=new Map,this.meshNameToIndex=new Map,this.nodeList=new Importer3dsNodeList}ImportContent(e,t){this.ProcessBinary(e),t()}ProcessBinary(e){let t=new BinaryReader(e,!0),r=t.GetByteLength();this.ReadChunks(t,r,((e,r)=>{e===CHUNK3DS.MAIN3DS?this.ReadMainChunk(t,r):this.SkipChunk(t,r)}))}ReadMainChunk(e,t){let r=this.GetChunkEnd(e,t);this.ReadChunks(e,r,((t,r)=>{t===CHUNK3DS.EDIT3DS?this.ReadEditorChunk(e,r):t===CHUNK3DS.KF3DS?this.ReadKeyFrameChunk(e,r):this.SkipChunk(e,r)})),this.BuildNodeHierarchy()}ReadEditorChunk(e,t){let r=this.GetChunkEnd(e,t);this.ReadChunks(e,r,((t,r)=>{t===CHUNK3DS.EDIT_MATERIAL?this.ReadMaterialChunk(e,r):t===CHUNK3DS.EDIT_OBJECT?this.ReadObjectChunk(e,r):this.SkipChunk(e,r)}))}ReadMaterialChunk(e,t){let r=new PhongMaterial,n=this.GetChunkEnd(e,t),i=null,o=null;this.ReadChunks(e,n,((t,n)=>{t===CHUNK3DS.MAT_NAME?r.name=this.ReadName(e):t===CHUNK3DS.MAT_AMBIENT?r.ambient=this.ReadColorChunk(e,n):t===CHUNK3DS.MAT_DIFFUSE?r.color=this.ReadColorChunk(e,n):t===CHUNK3DS.MAT_SPECULAR?r.specular=this.ReadColorChunk(e,n):t===CHUNK3DS.MAT_SHININESS?i=this.ReadPercentageChunk(e,n):t===CHUNK3DS.MAT_SHININESS_STRENGTH?o=this.ReadPercentageChunk(e,n):t===CHUNK3DS.MAT_TRANSPARENCY?(r.opacity=1-this.ReadPercentageChunk(e,n),UpdateMaterialTransparency(r)):t===CHUNK3DS.MAT_TEXMAP?(r.diffuseMap=this.ReadTextureMapChunk(e,n),UpdateMaterialTransparency(r)):this.SkipChunk(e,n)})),null!==i&&null!==o&&(r.shininess=i*o/10);let s=this.model.AddMaterial(r);this.materialNameToIndex.set(r.name,s)}ReadTextureMapChunk(e,t){let r=new TextureMap,n=this.GetChunkEnd(e,t);return this.ReadChunks(e,n,((t,n)=>{if(t===CHUNK3DS.MAT_TEXMAP_NAME){let t=this.ReadName(e),n=this.callbacks.getFileBuffer(t);r.name=t,r.buffer=n}else t===CHUNK3DS.MAT_TEXMAP_UOFFSET?r.offset.x=e.ReadFloat32():t===CHUNK3DS.MAT_TEXMAP_VOFFSET?r.offset.y=e.ReadFloat32():t===CHUNK3DS.MAT_TEXMAP_USCALE?r.scale.x=e.ReadFloat32():t===CHUNK3DS.MAT_TEXMAP_VSCALE?r.scale.y=e.ReadFloat32():t===CHUNK3DS.MAT_TEXMAP_ROTATION?r.rotation=e.ReadFloat32()*DegRad:this.SkipChunk(e,n)})),r}ReadColorChunk(e,t){let r=new RGBColor(0,0,0),n=this.GetChunkEnd(e,t),i=!1;return this.ReadChunks(e,n,((t,n)=>{t===CHUNK3DS.MAT_COLOR?i||(r.r=e.ReadUnsignedCharacter8(),r.g=e.ReadUnsignedCharacter8(),r.b=e.ReadUnsignedCharacter8()):t===CHUNK3DS.MAT_LIN_COLOR?(r.r=e.ReadUnsignedCharacter8(),r.g=e.ReadUnsignedCharacter8(),r.b=e.ReadUnsignedCharacter8(),i=!0):t===CHUNK3DS.MAT_COLOR_F?i||(r.r=ColorComponentFromFloat(e.ReadFloat32()),r.g=ColorComponentFromFloat(e.ReadFloat32()),r.b=ColorComponentFromFloat(e.ReadFloat32())):t===CHUNK3DS.MAT_LIN_COLOR_F?(r.r=ColorComponentFromFloat(e.ReadFloat32()),r.g=ColorComponentFromFloat(e.ReadFloat32()),r.b=ColorComponentFromFloat(e.ReadFloat32()),i=!0):this.SkipChunk(e,n)})),r}ReadPercentageChunk(e,t){let r=0,n=this.GetChunkEnd(e,t);return this.ReadChunks(e,n,((t,n)=>{t===CHUNK3DS.PERCENTAGE?r=e.ReadUnsignedInteger16()/100:t===CHUNK3DS.PERCENTAGE_F?r=e.ReadFloat32():this.SkipChunk(e,n)})),r}ReadObjectChunk(e,t){let r=this.GetChunkEnd(e,t),n=this.ReadName(e);this.ReadChunks(e,r,((t,r)=>{t===CHUNK3DS.OBJ_TRIMESH?this.ReadMeshChunk(e,r,n):this.SkipChunk(e,r)}))}ReadMeshChunk(e,t,r){let n=new Mesh;n.SetName(r);let i=this.GetChunkEnd(e,t),o=null;if(this.ReadChunks(e,i,((t,r)=>{t===CHUNK3DS.TRI_VERTEX?this.ReadVerticesChunk(n,e):t===CHUNK3DS.TRI_TEXVERTEX?this.ReadTextureVerticesChunk(n,e):t===CHUNK3DS.TRI_FACE?this.ReadFacesChunk(n,e,r):t===CHUNK3DS.TRI_TRANSFORMATION?o=this.ReadTransformationChunk(e):this.SkipChunk(e,r)})),n.VertexCount()===n.TextureUVCount())for(let e=0;e<n.TriangleCount();e++){let t=n.GetTriangle(e);t.SetTextureUVs(t.v0,t.v1,t.v2)}let s=new Matrix(o);!function(e,t){if(!t.IsValid())return;let r=IsNegative(t.Determinant());if(r){t=(new Matrix).CreateScale(-1,1,1).MultiplyMatrix(t)}let n=t.Invert();null!==n&&(TransformMesh(e,new Transformation(n)),r&&FlipMeshTrianglesOrientation(e))}(n,s);let a=this.model.AddMesh(n);this.meshNameToIndex.set(n.GetName(),a)}ReadVerticesChunk(e,t){let r=t.ReadUnsignedInteger16();for(let n=0;n<r;n++){let r=t.ReadFloat32(),n=t.ReadFloat32(),i=t.ReadFloat32();e.AddVertex(new Coord3D(r,n,i))}}ReadTextureVerticesChunk(e,t){let r=t.ReadUnsignedInteger16();for(let n=0;n<r;n++){let r=t.ReadFloat32(),n=t.ReadFloat32();e.AddTextureUV(new Coord2D(r,n))}}ReadFacesChunk(e,t,r){let n=this.GetChunkEnd(t,r),i=t.ReadUnsignedInteger16();for(let r=0;r<i;r++){let r=t.ReadUnsignedInteger16(),n=t.ReadUnsignedInteger16(),i=t.ReadUnsignedInteger16();t.ReadUnsignedInteger16(),e.AddTriangle(new Triangle(r,n,i))}this.ReadChunks(t,n,((r,n)=>{r===CHUNK3DS.TRI_MATERIAL?this.ReadFaceMaterialsChunk(e,t):r===CHUNK3DS.TRI_SMOOTH?this.ReadFaceSmoothingGroupsChunk(e,i,t):this.SkipChunk(t,n)}))}ReadFaceMaterialsChunk(e,t){let r=this.ReadName(t),n=this.materialNameToIndex.get(r),i=t.ReadUnsignedInteger16();for(let r=0;r<i;r++){let r=t.ReadUnsignedInteger16(),i=e.GetTriangle(r);void 0!==n&&(i.mat=n)}}ReadFaceSmoothingGroupsChunk(e,t,r){for(let n=0;n<t;n++){let t=r.ReadUnsignedInteger32();e.GetTriangle(n).curve=t}}ReadTransformationChunk(e){let t=[];for(let r=0;r<4;r++){for(let r=0;r<3;r++)t.push(e.ReadFloat32());r<3?t.push(0):t.push(1)}return t}ReadKeyFrameChunk(e,t){let r=this.GetChunkEnd(e,t);this.ReadChunks(e,r,((t,r)=>{t===CHUNK3DS.OBJECT_NODE?this.ReadObjectNodeChunk(e,r):this.SkipChunk(e,r)}))}BuildNodeHierarchy(){function e(e,t){let r=new Matrix;if(r.ComposeTRS(ArrayToCoord3D(function(e){return 0===e.positions.length?[0,0,0]:e.positions[0]}(e)),ArrayToQuaternion(function(e){return 0===e.rotations.length?[0,0,0,1]:function(e){let t=[0,0,0,1],r=Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);if(r>0){let n=-.5*e[3],i=Math.sin(n)/r;t=[i*e[0],i*e[1],i*e[2],Math.cos(n)]}return t}(e.rotations[0])}(e)),ArrayToCoord3D(function(e){return 0===e.scales.length?[1,1,1]:e.scales[0]}(e))),t){let t=e.pivot;r=(new Matrix).CreateTranslation(-t[0],-t[1],-t[2]).MultiplyMatrix(r)}return new Transformation(r)}let t=this.model.GetRootNode();if(this.nodeList.IsEmpty())for(let e=0;e<this.model.MeshCount();e++)t.AddMeshIndex(e);else{let r=new Map;for(let n of this.nodeList.GetNodes()){let i=new Node;if(n.name.length>0&&"$$$DUMMY"!==n.name&&(i.SetName(n.name),n.instanceName.length>0&&i.SetName(i.GetName()+" "+n.instanceName)),65535!==n.parentId&&r.has(n.parentId)){r.get(n.parentId).AddChildNode(i)}else t.AddChildNode(i);r.set(n.id,i);let o=this.meshNameToIndex.has(n.name);i.SetTransformation(e(n,o)),o&&i.AddMeshIndex(this.meshNameToIndex.get(n.name))}}}ReadObjectNodeChunk(e,t){function r(e,t,r){let n=[];t.Skip(10);let i=t.ReadInteger32();for(let o=0;o<i;o++){t.ReadInteger32(),0!==t.ReadUnsignedInteger16()&&t.ReadFloat32();let i=null;if(r===CHUNK3DS.OBJECT_ROTATION){let r=t.ReadFloat32();i=e.ReadVector(t),i[3]=r}else i=e.ReadVector(t);n.push(i)}return n}let n=new Importer3dsNode,i=this.GetChunkEnd(e,t);this.ReadChunks(e,i,((t,i)=>{t===CHUNK3DS.OBJECT_HIERARCHY?(n.name=this.ReadName(e),n.flags=e.ReadUnsignedInteger32(),n.parentId=e.ReadUnsignedInteger16()):t===CHUNK3DS.OBJECT_INSTANCE_NAME?n.instanceName=this.ReadName(e):t===CHUNK3DS.OBJECT_PIVOT?n.pivot=this.ReadVector(e):t===CHUNK3DS.OBJECT_POSITION?n.positions=r(this,e,CHUNK3DS.OBJECT_POSITION):t===CHUNK3DS.OBJECT_ROTATION?n.rotations=r(this,e,CHUNK3DS.OBJECT_ROTATION):t===CHUNK3DS.OBJECT_SCALE?n.scales=r(this,e,CHUNK3DS.OBJECT_SCALE):t===CHUNK3DS.OBJECT_ID?n.id=e.ReadUnsignedInteger16():this.SkipChunk(e,i)})),this.nodeList.AddNode(n)}ReadName(e){let t="",r=0,n=0;for(;n<64&&(r=e.ReadCharacter8(),0!==r);)t+=String.fromCharCode(r),n+=1;return t}ReadVector(e){return[e.ReadFloat32(),e.ReadFloat32(),e.ReadFloat32()]}ReadChunks(e,t,r){for(;e.GetPosition()<=t-6;){r(e.ReadUnsignedInteger16(),e.ReadUnsignedInteger32())}}GetChunkEnd(e,t){return e.GetPosition()+t-6}SkipChunk(e,t){e.Skip(t-6)}}const GltfComponentType={BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,UNSIGNED_INT:5125,FLOAT:5126},GltfDataType={SCALAR:0,VEC2:1,VEC3:2,VEC4:3,MAT2:4,MAT3:5,MAT4:6},GltfRenderMode={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},GltfConstants={GLTF_STRING:1179937895,JSON_CHUNK_TYPE:1313821514,BINARY_CHUNK_TYPE:5130562};function GetGltfColor(e){return RGBColorFromFloatComponents(LinearToSRGB(e[0]),LinearToSRGB(e[1]),LinearToSRGB(e[2]))}function GetGltfVertexColor(e,t){function r(e,t){let r=e;return t===GltfComponentType.UNSIGNED_BYTE?r/=255:t===GltfComponentType.UNSIGNED_SHORT&&(r/=65535),ColorComponentFromFloat(LinearToSRGB(r))}return new RGBColor(r(e[0],t),r(e[1],t),r(e[2],t))}class GltfBufferReader{constructor(e){this.reader=new BinaryReader(e,!0),this.componentType=null,this.dataType=null,this.byteStride=null,this.dataCount=null,this.sparseReader=null}SetComponentType(e){this.componentType=e}SetDataType(e){"SCALAR"===e?this.dataType=GltfDataType.SCALAR:"VEC2"===e?this.dataType=GltfDataType.VEC2:"VEC3"===e?this.dataType=GltfDataType.VEC3:"VEC4"===e?this.dataType=GltfDataType.VEC4:"MAT2"===e?this.dataType=GltfDataType.MAT2:"MAT3"===e?this.dataType=GltfDataType.MAT3:"MAT4"===e&&(this.dataType=GltfDataType.MAT4)}SetByteStride(e){this.byteStride=e}SetDataCount(e){this.dataCount=e}SetSparseReader(e,t){this.sparseReader={indexReader:e,valueReader:t}}ReadArrayBuffer(e){return this.reader.ReadArrayBuffer(e)}GetDataCount(){return this.dataCount}ReadData(){if(null===this.dataType)return null;if(this.dataType===GltfDataType.SCALAR){let e=this.ReadComponent();return this.SkipBytesByStride(1),e}if(this.dataType===GltfDataType.VEC2){let e=this.ReadComponent(),t=this.ReadComponent();return this.SkipBytesByStride(2),new Coord2D(e,t)}if(this.dataType===GltfDataType.VEC3){let e=this.ReadComponent(),t=this.ReadComponent(),r=this.ReadComponent();return this.SkipBytesByStride(3),new Coord3D(e,t,r)}if(this.dataType===GltfDataType.VEC4){let e=this.ReadComponent(),t=this.ReadComponent(),r=this.ReadComponent(),n=this.ReadComponent();return this.SkipBytesByStride(4),new Coord4D(e,t,r,n)}return null}EnumerateData(e){if(null===this.sparseReader)for(let t=0;t<this.dataCount;t++)e(this.ReadData());else{let t=[];for(let e=0;e<this.sparseReader.indexReader.GetDataCount();e++){let e=this.sparseReader.indexReader.ReadData(),r=this.sparseReader.valueReader.ReadData();t.push({index:e,value:r})}let r=0;for(let n=0;n<this.dataCount;n++){let i=this.ReadData();r<t.length&&t[r].index===n?(e(t[r].value),r+=1):e(i)}}}SkipBytes(e){this.reader.Skip(e)}ReadComponent(){return null===this.componentType?null:this.componentType===GltfComponentType.BYTE?this.reader.ReadCharacter8():this.componentType===GltfComponentType.UNSIGNED_BYTE?this.reader.ReadUnsignedCharacter8():this.componentType===GltfComponentType.SHORT?this.reader.ReadInteger16():this.componentType===GltfComponentType.UNSIGNED_SHORT?this.reader.ReadUnsignedInteger16():this.componentType===GltfComponentType.UNSIGNED_INT?this.reader.ReadInteger32():this.componentType===GltfComponentType.FLOAT?this.reader.ReadFloat32():null}SkipBytesByStride(e){if(null===this.byteStride)return;let t=e*this.GetComponentSize();this.reader.Skip(this.byteStride-t)}GetComponentSize(){return this.componentType===GltfComponentType.BYTE||this.componentType===GltfComponentType.UNSIGNED_BYTE?1:this.componentType===GltfComponentType.SHORT||this.componentType===GltfComponentType.UNSIGNED_SHORT?2:this.componentType===GltfComponentType.UNSIGNED_INT||this.componentType===GltfComponentType.FLOAT?4:0}}class GltfExtensions{constructor(){this.supportedExtensions=["KHR_draco_mesh_compression","KHR_materials_pbrSpecularGlossiness","KHR_texture_transform"],this.draco=null}LoadLibraries(e,t){void 0!==e&&null===this.draco&&-1!==e.indexOf("KHR_draco_mesh_compression")?LoadExternalLibrary("loaders/draco_decoder.js").then((()=>{DracoDecoderModule().then((e=>{this.draco=e,t.onSuccess()}))})).catch((()=>{t.onError("Failed to load draco decoder.")})):t.onSuccess()}GetUnsupportedExtensions(e){let t=[];if(void 0===e)return t;for(let r=0;r<e.length;r++){let n=e[r];-1===this.supportedExtensions.indexOf(n)&&t.push(n)}return t}ProcessMaterial(e,t,r){if(void 0===e.extensions)return null;let n=e.extensions.KHR_materials_pbrSpecularGlossiness;if(void 0===n)return null;let i=new PhongMaterial,o=n.diffuseFactor;void 0!==o&&(i.color=GetGltfColor(o),i.opacity=o[3]);let s=n.diffuseTexture;void 0!==s&&(i.diffuseMap=r(s));let a=n.specularFactor;void 0!==a&&(i.specular=GetGltfColor(a));let l=n.specularGlossinessTexture;void 0!==l&&(i.specularMap=r(l));let h=n.glossinessFactor;return void 0!==h&&(i.shininess=h),i}ProcessTexture(e,t){if(void 0===e.extensions)return;let r=e.extensions.KHR_texture_transform;void 0!==r&&(void 0!==r.offset&&(t.offset.x=r.offset[0],t.offset.y=-r.offset[1]),void 0!==r.scale&&(t.scale.x=r.scale[0],t.scale.y=r.scale[1]),void 0!==r.rotation&&(t.rotation=-r.rotation))}ProcessPrimitive(e,t,r,n){function i(e,t,r,n,i){let o=t.GetAttributeByUniqueId(r,n),s=o.num_components(),a=r.num_points()*s,l=4*a,h=e._malloc(l);t.GetAttributeDataArrayForAllPoints(r,o,e.DT_FLOAT32,l,h);let u=new Float32Array(e.HEAPF32.buffer,h,a).slice();if(2===s)for(let e=0;e<u.length;e+=2)i(new Coord2D(u[e+0],u[e+1]));else if(3===s)for(let e=0;e<u.length;e+=3)i(new Coord3D(u[e+0],u[e+1],u[e+2]));else if(4===s)for(let e=0;e<u.length;e+=4)i(new Coord4D(u[e+0],u[e+1],u[e+2],u[e+3]));e._free(h)}if(null===this.draco)return!1;if(void 0===r.extensions||void 0===r.extensions.KHR_draco_mesh_compression)return!1;let o=new this.draco.Decoder,s=new this.draco.DecoderBuffer,a=r.extensions.KHR_draco_mesh_compression,l=t.bufferViews[a.bufferView],h=e.GetReaderFromBufferView(l).ReadArrayBuffer(l.byteLength);if(s.Init(new Int8Array(h),h.byteLength),o.GetEncodedGeometryType(s)!==this.draco.TRIANGULAR_MESH)return!0;let u=new this.draco.Mesh;if(!o.DecodeBufferToMesh(s,u).ok())return!0;let d=void 0!==a.attributes.POSITION,c=void 0!==a.attributes.NORMAL,m=void 0!==a.attributes.TEXCOORD_0;if(!d)return!0;let p=n.VertexCount(),f=n.VertexColorCount(),g=n.NormalCount(),C=n.TextureUVCount();i(this.draco,o,u,a.attributes.POSITION,(e=>{n.AddVertex(e)})),c&&i(this.draco,o,u,a.attributes.NORMAL,(e=>{n.AddNormal(e)})),m&&i(this.draco,o,u,a.attributes.TEXCOORD_0,(e=>{e.y=-e.y,n.AddTextureUV(e)}));let T=3*u.num_faces(),x=4*T,M=this.draco._malloc(x);o.GetTrianglesUInt32Array(u,x,M);let y=new Uint32Array(this.draco.HEAPU32.buffer,M,T).slice();for(let t=0;t<y.length;t+=3){let i=y[t],o=y[t+1],s=y[t+2];e.AddTriangle(r,n,i,o,s,false,c,m,p,f,g,C)}return this.draco._free(M),!0}}class ImporterGltf extends ImporterBase{constructor(){super(),this.gltfExtensions=new GltfExtensions}CanImportExtension(e){return"gltf"===e||"glb"===e}GetUpDirection(){return Direction.Y}ClearContent(){this.bufferContents=null,this.imageIndexToTextureParams=null}ResetContent(){this.bufferContents=[],this.imageIndexToTextureParams=new Map}ImportContent(e,t){"gltf"===this.extension?this.ProcessGltf(e,t):"glb"===this.extension&&this.ProcessBinaryGltf(e,t)}ProcessGltf(e,t){let r=ArrayBufferToUtf8String(e),n=JSON.parse(r);if("2.0"!==n.asset.version)return this.SetError("Invalid glTF version."),void t();for(let e=0;e<n.buffers.length;e++){let r=null,i=n.buffers[e],o=Base64DataURIToArrayBuffer(i.uri);if(null!==o)r=o.buffer;else{let e=this.callbacks.getFileBuffer(i.uri);null!==e&&(r=e)}if(null===r)return this.SetError("One of the requested buffers is missing."),void t();this.bufferContents.push(r)}this.ProcessMainFile(n,t)}ProcessBinaryGltf(e,t){function r(e){let t=e.ReadUnsignedInteger32();return{type:e.ReadUnsignedInteger32(),buffer:e.ReadArrayBuffer(t)}}let n=new BinaryReader(e,!0);if(n.ReadUnsignedInteger32()!==GltfConstants.GLTF_STRING)return this.SetError("Invalid glTF file."),void t();if(2!==n.ReadUnsignedInteger32())return this.SetError("Invalid glTF version."),void t();if(n.ReadUnsignedInteger32()!==n.GetByteLength())return this.SetError("Invalid glTF file."),void t();let i=null;for(;!n.End();){let e=r(n);e.type===GltfConstants.JSON_CHUNK_TYPE?i=ArrayBufferToUtf8String(e.buffer):e.type===GltfConstants.BINARY_CHUNK_TYPE&&this.bufferContents.push(e.buffer)}if(null!==i){let e=JSON.parse(i);this.ProcessMainFile(e,t)}}ProcessMainFile(e,t){let r=this.gltfExtensions.GetUnsupportedExtensions(e.extensionsRequired);if(r.length>0)return this.SetError("Unsupported extension: "+r.join(", ")+"."),void t();this.gltfExtensions.LoadLibraries(e.extensionsRequired,{onSuccess:()=>{this.ImportModel(e),t()},onError:e=>{this.SetError(e),t()}})}ImportModel(e){let t=e.materials;if(void 0!==t)for(let r of t)this.ImportMaterial(e,r);let r=e.meshes;if(void 0!==r)for(let t of r)this.ImportMesh(e,t);this.ImportProperties(this.model,e.asset,"Asset properties"),this.ImportScene(e)}ImportProperties(e,t,r){if(null==t)return;let n=new PropertyGroup(r);for(let e in t)if(Object.prototype.hasOwnProperty.call(t,e)){let r=null,i=t[e];"string"==typeof i?r=new Property(PropertyType.Text,e,i):"number"==typeof i&&(r=Number.isInteger(i)?new Property(PropertyType.Integer,e,i):new Property(PropertyType.Number,e,i)),null!==r&&n.AddProperty(r)}0!==n.PropertyCount()&&e.AddPropertyGroup(n)}GetDefaultScene(e){let t=e.scene||0;return t>=e.scenes.length?null:e.scenes[t]}ImportMaterial(e,t){let r=new PhysicalMaterial;if(void 0!==t.name&&(r.name=t.name),r.color=GetGltfColor([1,1,1]),void 0!==t.pbrMetallicRoughness){let n=t.pbrMetallicRoughness.baseColorFactor;void 0!==n&&(r.color=GetGltfColor(n),r.opacity=n[3]);let i=t.pbrMetallicRoughness.metallicFactor;void 0!==i&&(r.metalness=i);let o=t.pbrMetallicRoughness.roughnessFactor;void 0!==o&&(r.roughness=o);let s=t.emissiveFactor;void 0!==s&&(r.emissive=GetGltfColor(s)),r.diffuseMap=this.ImportTexture(e,t.pbrMetallicRoughness.baseColorTexture),r.metalnessMap=this.ImportTexture(e,t.pbrMetallicRoughness.metallicRoughnessTexture),r.normalMap=this.ImportTexture(e,t.normalTexture),r.emissiveMap=this.ImportTexture(e,t.emissiveTexture),null!==r.diffuseMap&&(r.multiplyDiffuseMap=!0);let a=t.alphaMode;void 0!==a&&("BLEND"===a?r.transparent=!0:"MASK"===a&&(r.transparent=!0,r.alphaTest=t.alphaCutoff||.5))}let n=this.gltfExtensions.ProcessMaterial(t,r,(t=>this.ImportTexture(e,t)));null!==n&&(r=n),this.model.AddMaterial(r)}ImportTexture(e,t){if(null==t)return null;let r=new TextureMap,n=e.textures[t.index].source,i=e.images[n],o=null;if(this.imageIndexToTextureParams.has(n))o=this.imageIndexToTextureParams.get(n);else{o={name:null,mimeType:null,buffer:null};let t=n.toString();if(void 0!==i.uri){let e=Base64DataURIToArrayBuffer(i.uri);if(null!==e)o.name="Embedded_"+t+"."+GetFileExtensionFromMimeType(e.mimeType),o.mimeType=e.mimeType,o.buffer=e.buffer;else{let e=this.callbacks.getFileBuffer(i.uri);o.name=i.uri,o.buffer=e}}else if(void 0!==i.bufferView){let r=e.bufferViews[i.bufferView],n=this.GetReaderFromBufferView(r);if(null!==n){let e=n.ReadArrayBuffer(r.byteLength);o.name="Binary_"+t+"."+GetFileExtensionFromMimeType(i.mimeType),o.mimeType=i.mimeType,o.buffer=e}}this.imageIndexToTextureParams.set(n,o)}return r.name=o.name,r.mimeType=o.mimeType,r.buffer=o.buffer,this.gltfExtensions.ProcessTexture(t,r),r}ImportMesh(e,t){let r=new Mesh;this.model.AddMesh(r),void 0!==t.name&&r.SetName(t.name);for(let n=0;n<t.primitives.length;n++){let i=t.primitives[n];this.ImportPrimitive(e,i,r)}this.ImportProperties(r,t.extras,"Mesh properties")}ImportPrimitive(e,t,r){function n(e,t,r){let n=t.attributes[r];if(void 0===n)return!1;let i=e.accessors[n];return void 0!==i&&0!==i.count}if(this.gltfExtensions.ProcessPrimitive(this,e,t,r))return;if(void 0===t.attributes)return;let i=n(e,t,"POSITION"),o=n(e,t,"COLOR_0"),s=n(e,t,"NORMAL"),a=n(e,t,"TEXCOORD_0"),l=void 0!==t.indices,h=GltfRenderMode.TRIANGLES;if(void 0!==t.mode&&(h=t.mode),h!==GltfRenderMode.TRIANGLES&&h!==GltfRenderMode.TRIANGLE_STRIP&&h!==GltfRenderMode.TRIANGLE_FAN)return;let u=r.VertexCount(),d=r.VertexColorCount(),c=r.NormalCount(),m=r.TextureUVCount();if(!i)return;{let n=e.accessors[t.attributes.POSITION],i=this.GetReaderFromAccessor(e,n);if(null===i)return;i.EnumerateData((e=>{r.AddVertex(e)}))}let p=r.VertexCount()-u;if(o){let n=e.accessors[t.attributes.COLOR_0],i=this.GetReaderFromAccessor(e,n);if(null===i)return;i.EnumerateData((e=>{let t=GetGltfVertexColor([e.x,e.y,e.z],i.componentType);r.AddVertexColor(t)})),r.VertexColorCount()-d!==p&&(o=!1)}if(s){let n=e.accessors[t.attributes.NORMAL],i=this.GetReaderFromAccessor(e,n);if(null===i)return;i.EnumerateData((e=>{r.AddNormal(e)})),r.NormalCount()-c!==p&&(s=!1)}if(a){let n=e.accessors[t.attributes.TEXCOORD_0],i=this.GetReaderFromAccessor(e,n);if(null===i)return;i.EnumerateData((e=>{e.y=-e.y,r.AddTextureUV(e)})),r.TextureUVCount()-m!==p&&(a=!1)}let f=[];if(l){let r=e.accessors[t.indices],n=this.GetReaderFromAccessor(e,r);if(null===n)return;n.EnumerateData((e=>{f.push(e)}))}else{let e=r.VertexCount()-u;for(let t=0;t<e;t++)f.push(t)}if(h===GltfRenderMode.TRIANGLES)for(let e=0;e<f.length;e+=3){let n=f[e],i=f[e+1],l=f[e+2];this.AddTriangle(t,r,n,i,l,o,s,a,u,d,c,m)}else if(h===GltfRenderMode.TRIANGLE_STRIP)for(let e=0;e<f.length-2;e++){let n=f[e],i=f[e+1],l=f[e+2];if(e%2==1){let e=i;i=l,l=e}this.AddTriangle(t,r,n,i,l,o,s,a,u,d,c,m)}else if(h===GltfRenderMode.TRIANGLE_FAN)for(let e=1;e<f.length-1;e++){let n=f[0],i=f[e],l=f[e+1];this.AddTriangle(t,r,n,i,l,o,s,a,u,d,c,m)}}AddTriangle(e,t,r,n,i,o,s,a,l,h,u,d){let c=new Triangle(l+r,l+n,l+i);o&&c.SetVertexColors(h+r,h+n,h+i),s&&c.SetNormals(u+r,u+n,u+i),a&&c.SetTextureUVs(d+r,d+n,d+i),void 0!==e.material&&(c.mat=e.material),t.AddTriangle(c)}ImportScene(e){let t=this.GetDefaultScene(e);if(null===t)return;let r=this.model.GetRootNode();for(let n of t.nodes){let t=e.nodes[n];this.ImportNode(e,t,r)}this.ImportProperties(this.model,t.extras,"Scene properties")}ImportNode(e,t,r){if(void 0===t.children&&void 0===t.mesh)return;let n=new Node;if(void 0!==t.name&&n.SetName(t.name),n.SetTransformation(function(e){let t=(new Matrix).CreateIdentity();if(void 0!==e.matrix)t.Set(e.matrix);else{let r=[0,0,0],n=[0,0,0,1],i=[1,1,1];void 0!==e.translation&&(r=e.translation),void 0!==e.rotation&&(n=e.rotation),void 0!==e.scale&&(i=e.scale),t.ComposeTRS(ArrayToCoord3D(r),ArrayToQuaternion(n),ArrayToCoord3D(i))}return new Transformation(t)}(t)),r.AddChildNode(n),void 0!==t.children)for(let r of t.children){let t=e.nodes[r];this.ImportNode(e,t,n)}if(void 0!==t.mesh){let e=this.model.GetMesh(t.mesh);this.ImportProperties(e,t.extras,"Node properties"),n.AddMeshIndex(t.mesh)}}GetReaderFromBufferView(e){let t=e.buffer||0,r=this.bufferContents[t];if(null==r)return null;let n=new GltfBufferReader(r);n.SkipBytes(e.byteOffset||0);let i=e.byteStride;return void 0!==i&&0!==i&&n.SetByteStride(i),n}GetReaderFromAccessor(e,t){let r=t.bufferView||0,n=e.bufferViews[r],i=this.GetReaderFromBufferView(n);if(null===i)return null;if(i.SetComponentType(t.componentType),i.SetDataType(t.type),i.SetDataCount(t.count),i.SkipBytes(t.byteOffset||0),void 0!==t.sparse){let r=this.GetReaderFromSparseAccessor(e,t.sparse.indices,t.sparse.indices.componentType,"SCALAR",t.sparse.count),n=this.GetReaderFromSparseAccessor(e,t.sparse.values,t.componentType,t.type,t.sparse.count);null!==r&&null!==n&&i.SetSparseReader(r,n)}return i}GetReaderFromSparseAccessor(e,t,r,n,i){if(void 0===t.bufferView)return null;let o=e.bufferViews[t.bufferView],s=this.GetReaderFromBufferView(o);return null===s?null:(s.SetComponentType(r),s.SetDataType(n),s.SetDataCount(i),s.SkipBytes(t.byteOffset||0),s)}}class ImporterIfc extends ImporterBase{constructor(){super(),this.ifc=null}CanImportExtension(e){return"ifc"===e}GetUpDirection(){return Direction.Y}ClearContent(){this.expressIDToMesh=null,this.colorToMaterial=null}ResetContent(){this.expressIDToMesh=new Map,this.colorToMaterial=new ColorToMaterialConverter(this.model)}ImportContent(e,t){null===this.ifc?LoadExternalLibrary("loaders/web-ifc-api-browser.js").then((()=>{this.ifc=new WebIFC.IfcAPI,this.ifc.Init().then((()=>{this.ImportIfcContent(e),t()}))})).catch((()=>{this.SetError("Failed to load web-ifc."),t()})):(this.ImportIfcContent(e),t())}ImportIfcContent(e){const t=new Uint8Array(e),r=this.ifc.OpenModel(t,{COORDINATE_TO_ORIGIN:!0}),n=this.ifc.LoadAllGeometry(r);for(let e=0;e<n.size();e++){const t=n.get(e);t.geometries.size()>0&&this.ImportIfcMesh(r,t)}this.ImportProperties(r),this.ifc.CloseModel(r)}ImportIfcMesh(e,t){let r=new Mesh;r.SetName("Mesh "+t.expressID.toString());let n=0;const i=t.geometries;for(let t=0;t<i.size();t++){const o=i.get(t),s=this.ifc.GetGeometry(e,o.geometryExpressID),a=this.ifc.GetVertexArray(s.GetVertexData(),s.GetVertexDataSize()),l=this.ifc.GetIndexArray(s.GetIndexData(),s.GetIndexDataSize()),h=this.GetMaterialIndexByColor(o.color),u=new Matrix(o.flatTransformation),d=new Transformation(u);for(let e=0;e<a.length;e+=6){const t=a[e],n=a[e+1],i=a[e+2],o=new Coord3D(t,n,i),s=d.TransformCoord3D(o);r.AddVertex(s)}for(let e=0;e<l.length;e+=3){const t=l[e],i=l[e+1],o=l[e+2],s=new Triangle(n+t,n+i,n+o);s.SetMaterial(h),r.AddTriangle(s)}n+=a.length/6}this.expressIDToMesh.set(t.expressID,r),this.model.AddMeshToRootNode(r)}ImportProperties(e){const t=this.ifc.GetLineIDsWithType(e,WebIFC.IFCRELDEFINESBYPROPERTIES);for(let r=0;r<t.size();r++){const n=t.get(r),i=this.ifc.GetLine(e,n);Array.isArray(i.RelatingPropertyDefinition)||i.RelatedObjects.forEach((t=>{let r=null;if(this.expressIDToMesh.has(t.value))r=this.expressIDToMesh.get(t.value);else{this.ifc.GetLine(e,t.value,!0).type===WebIFC.IFCBUILDING&&(r=this.model)}if(null===r)return;let n=i.RelatingPropertyDefinition,o=this.ifc.GetLine(e,n.value,!0);if(!o||!o.HasProperties)return;let s=new PropertyGroup(o.Name.value);o.HasProperties.forEach((e=>{if(!e||!e.Name)return;if(!e.NominalValue||!e.NominalValue.constructor)return;if(e.type!==WebIFC.IFCPROPERTYSINGLEVALUE)return;let t=this.GetIFCString(e.Name.value),r=null,n=null;switch(e.NominalValue.constructor.name){case"IfcText":case"IfcLabel":case"IfcIdentifier":case WebIFC.IFCLABEL:r=new Property(PropertyType.Text,t,this.GetIFCString(e.NominalValue.value));break;case"IfcBoolean":case"IfcLogical":n="Unknown","T"===e.NominalValue.value?n="True":"F"===e.NominalValue.value&&(n="False"),r=new Property(PropertyType.Text,t,n);break;case"IfcInteger":case"IfcCountMeasure":r=new Property(PropertyType.Integer,t,e.NominalValue.value);break;case"IfcReal":case"IfcLengthMeasure":case"IfcPositiveLengthMeasure":case"IfcAreaMeasure":case"IfcVolumeMeasure":case"IfcRatioMeasure":case"IfcPositiveRatioMeasure":case"IfcMassMeasure":case"IfcMassPerLengthMeasure":case"IfcPlaneAngleMeasure":case"IfcThermalTransmittanceMeasure":r=new Property(PropertyType.Number,t,e.NominalValue.value);break;default:console.log(e)}null!==r&&s.AddProperty(r)})),s.PropertyCount()>0&&r.AddPropertyGroup(s)}))}}GetMaterialIndexByColor(e){const t=RGBColorFromFloatComponents(e.x,e.y,e.z),r=parseInt(255*e.w,10);return this.colorToMaterial.GetMaterialIndex(t.r,t.g,t.b,r)}GetIFCString(e){let t=this.DecodeIFCString(e);return 0===t.length&&(t="-"),t}DecodeIFCString(e){const t=/\\X2\\(.*?)\\X0\\/giu;let r=e,n=t.exec(e);for(;n;){const i=String.fromCharCode(parseInt(n[1],16));r=r.replace(n[0],i),n=t.exec(e)}return r}}class ObjMeshConverter{constructor(e){this.mesh=e,this.globalToMeshVertices=new Map,this.globalToMeshVertexColors=new Map,this.globalToMeshNormals=new Map,this.globalToMeshUvs=new Map}AddVertex(e,t){return this.GetMeshIndex(e,t,this.globalToMeshVertices,(e=>this.mesh.AddVertex(new Coord3D(e.x,e.y,e.z))))}AddVertexColor(e,t){return this.GetMeshIndex(e,t,this.globalToMeshVertexColors,(e=>this.mesh.AddVertexColor(new RGBColor(e.r,e.g,e.b))))}AddNormal(e,t){return this.GetMeshIndex(e,t,this.globalToMeshNormals,(e=>this.mesh.AddNormal(new Coord3D(e.x,e.y,e.z))))}AddUV(e,t){return this.GetMeshIndex(e,t,this.globalToMeshUvs,(e=>this.mesh.AddTextureUV(new Coord2D(e.x,e.y))))}AddLine(e){this.mesh.AddLine(e)}AddTriangle(e){this.mesh.AddTriangle(e)}GetMeshIndex(e,t,r,n){if(isNaN(e)||e<0||e>=t.length)return null;if(r.has(e))return r.get(e);{let i=n(t[e]);return r.set(e,i),i}}}function CreateColor(e,t,r){return RGBColorFromFloatComponents(parseFloat(e),parseFloat(t),parseFloat(r))}class ImporterObj extends ImporterBase{constructor(){super()}CanImportExtension(e){return"obj"===e}GetUpDirection(){return Direction.Y}ClearContent(){this.globalVertices=null,this.globalVertexColors=null,this.globalNormals=null,this.globalUvs=null,this.currentMeshConverter=null,this.currentMaterial=null,this.currentMaterialIndex=null,this.meshNameToConverter=null,this.materialNameToIndex=null}ResetContent(){this.globalVertices=[],this.globalVertexColors=[],this.globalNormals=[],this.globalUvs=[],this.currentMeshConverter=null,this.currentMaterial=null,this.currentMaterialIndex=null,this.meshNameToConverter=new Map,this.materialNameToIndex=new Map}ImportContent(e,t){ReadLines(ArrayBufferToUtf8String(e),(e=>{this.WasError()||this.ProcessLine(e)})),t()}ProcessLine(e){if("#"===e[0])return;let t=ParametersFromLine(e,"#");if(0===t.length)return;let r=t[0].toLowerCase();t.shift(),this.ProcessMeshParameter(r,t,e)||this.ProcessMaterialParameter(r,t,e)}AddNewMesh(e){if(this.meshNameToConverter.has(e))this.currentMeshConverter=this.meshNameToConverter.get(e);else{let t=new Mesh;t.SetName(e),this.model.AddMeshToRootNode(t),this.currentMeshConverter=new ObjMeshConverter(t),this.meshNameToConverter.set(e,this.currentMeshConverter)}}ProcessMeshParameter(e,t,r){if("g"===e||"o"===e){if(0===t.length)return!0;let n=NameFromLine(r,e.length,"#");return this.AddNewMesh(n),!0}if("v"===e)return t.length<3||(this.globalVertices.push(new Coord3D(parseFloat(t[0]),parseFloat(t[1]),parseFloat(t[2]))),t.length>=6&&this.globalVertexColors.push(CreateColor(t[3],t[4],t[5]))),!0;if("vn"===e)return t.length<3||this.globalNormals.push(new Coord3D(parseFloat(t[0]),parseFloat(t[1]),parseFloat(t[2]))),!0;if("vt"===e)return t.length<2||this.globalUvs.push(new Coord2D(parseFloat(t[0]),parseFloat(t[1]))),!0;if("l"===e){if(t.length<2)return!0;this.ProcessLineCommand(t)}else if("f"===e)return t.length<3||this.ProcessFaceCommand(t),!0;return!1}ProcessMaterialParameter(e,t,r){function n(e,t){let r=new TextureMap,n=e[e.length-1],i=t.getFileBuffer(n);r.name=n,r.buffer=i;let o=function(e){let t=new Map,r=null;for(let n=0;n<e.length-1;n++){let i=e[n];i.startsWith("-")?(r=i,t.set(r,[])):null!==r&&t.get(r).push(i)}return t}(e);if(o.has("-o")){let e=o.get("-o");e.length>0&&(r.offset.x=parseFloat(e[0])),e.length>1&&(r.offset.y=parseFloat(e[1]))}if(o.has("-s")){let e=o.get("-s");e.length>0&&(r.scale.x=parseFloat(e[0])),e.length>1&&(r.scale.y=parseFloat(e[1]))}return r}if("newmtl"===e){if(0===t.length)return!0;let n=new PhongMaterial,i=NameFromLine(r,e.length,"#"),o=this.model.AddMaterial(n);return n.name=i,this.currentMaterial=n,this.materialNameToIndex.set(i,o),!0}if("usemtl"===e){if(0===t.length)return!0;let n=NameFromLine(r,e.length,"#");return this.materialNameToIndex.has(n)&&(this.currentMaterialIndex=this.materialNameToIndex.get(n)),!0}if("mtllib"===e){if(0===t.length)return!0;let n=NameFromLine(r,e.length,"#"),i=this.callbacks.getFileBuffer(n);if(null!==i){ReadLines(ArrayBufferToUtf8String(i),(e=>{this.WasError()||this.ProcessLine(e)}))}return!0}return"map_kd"===e?(null===this.currentMaterial||0===t.length||(this.currentMaterial.diffuseMap=n(t,this.callbacks),UpdateMaterialTransparency(this.currentMaterial)),!0):"map_ks"===e?(null===this.currentMaterial||0===t.length||(this.currentMaterial.specularMap=n(t,this.callbacks)),!0):"map_bump"===e||"bump"===e?(null===this.currentMaterial||0===t.length||(this.currentMaterial.bumpMap=n(t,this.callbacks)),!0):"ka"===e?(null===this.currentMaterial||t.length<3||(this.currentMaterial.ambient=CreateColor(t[0],t[1],t[2])),!0):"kd"===e?(null===this.currentMaterial||t.length<3||(this.currentMaterial.color=CreateColor(t[0],t[1],t[2])),!0):"ks"===e?(null===this.currentMaterial||t.length<3||(this.currentMaterial.specular=CreateColor(t[0],t[1],t[2])),!0):"ns"===e?(null===this.currentMaterial||t.length<1||(this.currentMaterial.shininess=parseFloat(t[0])/1e3),!0):"tr"===e?(null===this.currentMaterial||t.length<1||(this.currentMaterial.opacity=1-parseFloat(t[0]),UpdateMaterialTransparency(this.currentMaterial)),!0):"d"===e&&(null===this.currentMaterial||t.length<1||(this.currentMaterial.opacity=parseFloat(t[0]),UpdateMaterialTransparency(this.currentMaterial)),!0)}ProcessLineCommand(e){null===this.currentMeshConverter&&this.AddNewMesh("");let t=[];for(let r=0;r<e.length;r++){let n=e[r].split("/"),i=this.GetRelativeIndex(parseInt(n[0],10),this.globalVertices.length),o=this.currentMeshConverter.AddVertex(i,this.globalVertices);if(null===o){this.SetError("Invalid vertex index.");break}t.push(o)}let r=new Line(t);null!==this.currentMaterialIndex&&(r.mat=this.currentMaterialIndex),this.currentMeshConverter.AddLine(r)}ProcessFaceCommand(e){let t=[],r=[],n=[],i=[];null===this.currentMeshConverter&&this.AddNewMesh("");for(let o=0;o<e.length;o++){let s=e[o].split("/");t.push(this.GetRelativeIndex(parseInt(s[0],10),this.globalVertices.length)),this.globalVertices.length===this.globalVertexColors.length&&r.push(this.GetRelativeIndex(parseInt(s[0],10),this.globalVertices.length)),s.length>1&&s[1].length>0&&i.push(this.GetRelativeIndex(parseInt(s[1],10),this.globalUvs.length)),s.length>2&&s[2].length>0&&n.push(this.GetRelativeIndex(parseInt(s[2],10),this.globalNormals.length))}for(let e=0;e<t.length-2;e++){let o=this.currentMeshConverter.AddVertex(t[0],this.globalVertices),s=this.currentMeshConverter.AddVertex(t[e+1],this.globalVertices),a=this.currentMeshConverter.AddVertex(t[e+2],this.globalVertices);if(null===o||null===s||null===a){this.SetError("Invalid vertex index.");break}let l=new Triangle(o,s,a);if(r.length===t.length){let t=this.currentMeshConverter.AddVertexColor(r[0],this.globalVertexColors),n=this.currentMeshConverter.AddVertexColor(r[e+1],this.globalVertexColors),i=this.currentMeshConverter.AddVertexColor(r[e+2],this.globalVertexColors);if(null===t||null===n||null===i){this.SetError("Invalid vertex color index.");break}l.SetVertexColors(t,n,i)}if(n.length===t.length){let t=this.currentMeshConverter.AddNormal(n[0],this.globalNormals),r=this.currentMeshConverter.AddNormal(n[e+1],this.globalNormals),i=this.currentMeshConverter.AddNormal(n[e+2],this.globalNormals);if(null===t||null===r||null===i){this.SetError("Invalid normal index.");break}l.SetNormals(t,r,i)}if(i.length===t.length){let t=this.currentMeshConverter.AddUV(i[0],this.globalUvs),r=this.currentMeshConverter.AddUV(i[e+1],this.globalUvs),n=this.currentMeshConverter.AddUV(i[e+2],this.globalUvs);if(null===t||null===r||null===n){this.SetError("Invalid uv index.");break}l.SetTextureUVs(t,r,n)}null!==this.currentMaterialIndex&&(l.mat=this.currentMaterialIndex),this.currentMeshConverter.AddTriangle(l)}}GetRelativeIndex(e,t){return e>0?e-1:t+e}}class ImporterOff extends ImporterBase{constructor(){super()}CanImportExtension(e){return"off"===e}GetUpDirection(){return Direction.Y}ClearContent(){this.mesh=null,this.status=null,this.colorToMaterial=null}ResetContent(){this.mesh=new Mesh,this.model.AddMeshToRootNode(this.mesh),this.status={vertexCount:0,faceCount:0,foundVertex:0,foundFace:0},this.colorToMaterial=new ColorToMaterialConverter(this.model)}ImportContent(e,t){ReadLines(ArrayBufferToUtf8String(e),(e=>{this.WasError()||this.ProcessLine(e)})),t()}ProcessLine(e){function t(e){return-1!==e.indexOf(".")?ColorComponentFromFloat(parseFloat(e)):parseInt(e,10)}if("#"===e[0])return;let r=ParametersFromLine(e,"#");if(0===r.length)return;if("OFF"===r[0])return;if(0===this.status.vertexCount&&0===this.status.faceCount)return void(r.length>1&&(this.status.vertexCount=parseInt(r[0],10),this.status.faceCount=parseInt(r[1],10)));if(this.status.foundVertex<this.status.vertexCount)return r.length>=3&&(this.mesh.AddVertex(new Coord3D(parseFloat(r[0]),parseFloat(r[1]),parseFloat(r[2]))),this.status.foundVertex+=1),void(r.length>=6&&this.mesh.AddVertexColor(new RGBColor(t(r[3]),t(r[4]),t(r[5]))));let n=this.mesh.VertexCount()===this.mesh.VertexColorCount();if(this.status.foundFace<this.status.faceCount){if(r.length>=4){let e=parseInt(r[0],10);if(r.length<e+1)return;let i=null;if(!n&&r.length>=e+4){let n=new RGBColor(t(r[e+1]),t(r[e+2]),t(r[e+3]));i=this.colorToMaterial.GetMaterialIndex(n.r,n.g,n.b)}for(let t=0;t<e-2;t++){let e=parseInt(r[1]),o=parseInt(r[t+2]),s=parseInt(r[t+3]),a=new Triangle(e,o,s);n?a.SetVertexColors(e,o,s):a.SetMaterial(i),this.mesh.AddTriangle(a)}this.status.foundFace+=1}}else;}}const PlyHeaderCheckResult={Ok:1,NoVertices:2,NoFaces:3,UnknownError:4};class PlyHeader{constructor(){this.format=null,this.elements=[]}SetFormat(e){this.format=e}AddElement(e,t){this.elements.push({name:e,count:t,format:[]})}GetElements(){return this.elements}AddSingleFormat(e,t){this.elements[this.elements.length-1].format.push({name:t,isSingle:!0,elemType:e})}AddListFormat(e,t,r){this.elements[this.elements.length-1].format.push({name:r,isSingle:!1,countType:e,elemType:t})}GetElement(e){for(let t=0;t<this.elements.length;t++){let r=this.elements[t];if(r.name===e)return r}return null}Check(){let e=this.GetElement("vertex");if(null===e||0===e.length||e.format.length<3)return PlyHeaderCheckResult.NoVertices;let t=this.GetElement("face");if("ascii"===this.format){if(null===t||0===t.count||t.format.length<0)return PlyHeaderCheckResult.NoFaces}else{if("binary_little_endian"!==this.format&&"binary_big_endian"!==this.format)return PlyHeaderCheckResult.UnknownError;{let e=this.GetElement("tristrips"),r=null!==t&&t.count>0&&t.format.length>0,n=null!==e&&e.count>0&&e.format.length>0;if(!r&&!n)return PlyHeaderCheckResult.NoFaces}}return PlyHeaderCheckResult.Ok}}class PlyMaterialHandler{constructor(e){this.model=e,this.colorToMaterial=new Map}GetMaterialIndexByColor(e){let t="Color "+IntegerToHexString(e[0])+IntegerToHexString(e[1])+IntegerToHexString(e[2])+IntegerToHexString(e[3]);if(this.colorToMaterial.has(t))return this.colorToMaterial.get(t);{let r=new PhongMaterial;r.name=t,r.color=new RGBColor(e[0],e[1],e[2]),r.opacity=e[3]/255,UpdateMaterialTransparency(r);let n=this.model.AddMaterial(r);return this.colorToMaterial.set(t,n),n}}}class ImporterPly extends ImporterBase{constructor(){super()}CanImportExtension(e){return"ply"===e}GetUpDirection(){return Direction.Y}ClearContent(){this.mesh=null}ResetContent(){this.mesh=new Mesh,this.model.AddMeshToRootNode(this.mesh)}ImportContent(e,t){let r=this.GetHeaderContent(e),n=this.ReadHeader(r),i=n.Check();if(i===PlyHeaderCheckResult.Ok)if("ascii"===n.format){let t=ArrayBufferToUtf8String(e);t=t.substring(r.length),this.ReadAsciiContent(n,t)}else"binary_little_endian"!==n.format&&"binary_big_endian"!==n.format||this.ReadBinaryContent(n,e,r.length);else i===PlyHeaderCheckResult.NoVertices?this.SetError("The model contains no vertices."):i===PlyHeaderCheckResult.NoFaces?this.SetError("The model contains no faces."):this.SetError("Invalid header information.");t()}GetHeaderContent(e){let t="",r=new Uint8Array(e),n=0;for(n=0;n<e.byteLength&&(t+=String.fromCharCode(r[n]),!t.endsWith("end_header"));n++);for(n+=1;n<e.byteLength;){let e=String.fromCharCode(r[n]);if(t+=e,n+=1,"\n"===e)break}return t}ReadHeader(e){let t=new PlyHeader;return ReadLines(e,(e=>{let r=ParametersFromLine(e,null);0!==r.length&&"comment"!==r[0]&&"ply"!==r[0]&&("format"===r[0]&&r.length>=2?t.SetFormat(r[1]):"element"===r[0]&&r.length>=3?t.AddElement(r[1],parseInt(r[2],10)):"property"===r[0]&&r.length>=3&&("list"===r[1]&&r.length>=5?t.AddListFormat(r[2],r[3],r[4]):t.AddSingleFormat(r[1],r[2])))})),t}ReadAsciiContent(e,t){let r=e.GetElement("vertex"),n=e.GetElement("face"),i=0,o=0;ReadLines(t,(e=>{if(this.WasError())return;let t=ParametersFromLine(e,null);if(0!==t.length&&"comment"!==t[0])if(i<r.count)t.length>=3&&(this.mesh.AddVertex(new Coord3D(parseFloat(t[0]),parseFloat(t[1]),parseFloat(t[2]))),i+=1);else if(null!==n&&o<n.count){if(t.length>=4){let e=parseInt(t[0],10);if(t.length<e+1)return;for(let r=0;r<e-2;r++){let e=parseInt(t[1]),n=parseInt(t[r+2]),i=parseInt(t[r+3]),o=new Triangle(e,n,i);this.mesh.AddTriangle(o)}o+=1}}else;}))}ReadBinaryContent(e,t,r){function n(e,t){function r(e,t){return"char"===t||"int8"===t?e.ReadCharacter8():"uchar"===t||"uint8"===t?e.ReadUnsignedCharacter8():"short"===t||"int16"===t?e.ReadInteger16():"ushort"===t||"uint16"===t?e.ReadUnsignedInteger16():"int"===t||"int32"===t?e.ReadInteger32():"uint"===t||"uint32"===t?e.ReadUnsignedInteger32():"float"===t||"float32"===t?e.ReadFloat32():"double"===t||"double64"===t?e.ReadDouble64():null}if(t.isSingle)return r(e,t.elemType);{let n=[],i=r(e,t.countType);for(let o=0;o<i;o++)n.push(r(e,t.elemType));return n}}function i(e,t,r){for(let i=r;i<t.length;i++)n(e,t[i])}function o(e,t,r){let i=null,o=null,s=null,a=255;for(let l=r;l<t.length;l++){let r=t[l],h=n(e,r);"red"===r.name?i=h:"green"===r.name?o=h:"blue"===r.name?s=h:"alpha"===r.name&&(a=h)}return null!==i&&null!==o&&null!==s?[i,o,s,a]:null}let s=null;if("binary_little_endian"===e.format)s=new BinaryReader(t,!0);else{if("binary_big_endian"!==e.format)return;s=new BinaryReader(t,!1)}s.Skip(r);let a=new PlyMaterialHandler(this.model),l=e.GetElements();for(let e=0;e<l.length;e++){let t=l[e];if("vertex"===t.name)for(let e=0;e<t.count;e++){let e=n(s,t.format[0]),r=n(s,t.format[1]),i=n(s,t.format[2]),a=o(s,t.format,3);null!==a&&this.mesh.AddVertexColor(new RGBColor(a[0],a[1],a[2])),this.mesh.AddVertex(new Coord3D(e,r,i))}else if("face"===t.name)for(let e=0;e<t.count;e++){let e=n(s,t.format[0]),r=o(s,t.format,1);for(let t=0;t<e.length-2;t++){let n=e[0],i=e[t+1],o=e[t+2],s=new Triangle(n,i,o);null!==r?s.mat=a.GetMaterialIndexByColor(r):this.mesh.VertexColorCount()>0&&s.SetVertexColors(n,i,o),this.mesh.AddTriangle(s)}}else if("tristrips"===t.name)for(let e=0;e<t.count;e++){let e=n(s,t.format[0]);i(s,t.format,1);let r=!0;for(let t=0;t<e.length-2;t++){let n=e[t],i=e[t+1],o=e[t+2];if(-1===o){t+=2,r=!0;continue}if(!r){let e=i;i=o,o=e}r=!r;let s=new Triangle(n,i,o);this.mesh.AddTriangle(s)}}else i(s,t.format,0)}}}class ImporterOcct extends ImporterBase{constructor(){super(),this.worker=null}CanImportExtension(e){return"stp"===e||"step"===e||"igs"===e||"iges"===e||"brp"===e||"brep"===e}GetUpDirection(){return Direction.Y}ClearContent(){null!==this.worker&&(this.worker.terminate(),this.worker=null)}ResetContent(){this.worker=null}ImportContent(e,t){let r=GetExternalLibPath("loaders/occt-import-js-worker.js");this.worker=new Worker(r),this.worker.addEventListener("message",(e=>{this.ImportResultJson(e.data,t)})),this.worker.addEventListener("error",(e=>{this.SetError("Failed to load occt-import-js."),t()}));let n=null;if("stp"===this.extension||"step"===this.extension)n="step";else if("igs"===this.extension||"iges"===this.extension)n="iges";else{if("brp"!==this.extension&&"brep"!==this.extension)return void t();n="brep"}"step"!==n&&"iges"!==n||this.model.SetUnit(Unit.Millimeter);let i=new Uint8Array(e);this.worker.postMessage({format:n,buffer:i,params:{linearUnit:"millimeter",linearDeflectionType:"bounding_box_ratio",linearDeflection:.001,angularDeflection:.5}})}ImportResultJson(e,t){if(!e.success)return void t();let r=new ColorToMaterialConverter(this.model),n=this.model.GetRootNode();this.ImportNode(e,e.root,n,r),t()}ImportNode(e,t,r,n){for(let i of t.meshes){let t=e.meshes[i],o=this.ImportMesh(t,n),s=this.model.AddMesh(o);r.AddMeshIndex(s)}for(let i of t.children){let t=new Node;t.SetName(i.name),r.AddChildNode(t),this.ImportNode(e,i,t,n)}}ImportMesh(e,t){let r=null;if(e.color){let n=RGBColorFromFloatComponents(e.color[0],e.color[1],e.color[2]);r=t.GetMaterialIndex(n.r,n.g,n.b,null)}let n=ConvertThreeGeometryToMesh(e,r,null);e.name&&n.SetName(e.name);for(let r of e.brep_faces){if(null===r.color)continue;let e=RGBColorFromFloatComponents(r.color[0],r.color[1],r.color[2]),i=t.GetMaterialIndex(e.r,e.g,e.b,null);for(let e=r.first;e<=r.last;e++){n.GetTriangle(e).SetMaterial(i)}}return n}}class ImporterStl extends ImporterBase{constructor(){super()}CanImportExtension(e){return"stl"===e}GetUpDirection(){return Direction.Z}ClearContent(){this.mesh=null,this.triangle=null}ResetContent(){this.mesh=new Mesh,this.model.AddMeshToRootNode(this.mesh),this.triangle=null}ImportContent(e,t){if(this.IsBinaryStlFile(e))this.ProcessBinary(e);else{ReadLines(ArrayBufferToUtf8String(e),(e=>{this.WasError()||this.ProcessLine(e)}))}t()}IsBinaryStlFile(e){let t=e.byteLength;if(t<84)return!1;let r=new BinaryReader(e,!0);return r.Skip(80),t===50*r.ReadUnsignedInteger32()+84}ProcessLine(e){if("#"===e[0])return;let t=ParametersFromLine(e,"#");if(0===t.length)return;let r=t[0];if("solid"!==r){if("facet"!==r){if("vertex"!==r||null===this.triangle)return"endfacet"===r&&null!==this.triangle?(-1!==this.triangle.v0&&-1!==this.triangle.v1&&null!==this.triangle.v2&&this.mesh.AddTriangle(this.triangle),void(this.triangle=null)):void 0;if(t.length>=4){let e=this.mesh.AddVertex(new Coord3D(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3])));-1===this.triangle.v0?this.triangle.v0=e:-1===this.triangle.v1?this.triangle.v1=e:-1===this.triangle.v2&&(this.triangle.v2=e)}}else if(this.triangle=new Triangle(-1,-1,-1),t.length>=5&&"normal"===t[1]){let e=new Coord3D(parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4]));if(IsPositive(e.Length())){let t=this.mesh.AddNormal(e);this.triangle.SetNormals(t,t,t)}}}else if(t.length>1){let t=NameFromLine(e,r.length,"#");this.mesh.SetName(t)}}ProcessBinary(e){function t(e){let t=new Coord3D;return t.x=e.ReadFloat32(),t.y=e.ReadFloat32(),t.z=e.ReadFloat32(),t}function r(e,r){let n=t(r);return e.AddVertex(n)}let n=new BinaryReader(e,!0);n.Skip(80);let i=n.ReadUnsignedInteger32();for(let e=0;e<i;e++){let e=t(n),i=r(this.mesh,n),o=r(this.mesh,n),s=r(this.mesh,n);n.Skip(2);let a=new Triangle(i,o,s);if(IsPositive(e.Length())){let t=this.mesh.AddNormal(e);a.SetNormals(t,t,t)}this.mesh.AddTriangle(a)}}}class ImporterBim extends ImporterBase{constructor(){super()}CanImportExtension(e){return"bim"===e}GetUpDirection(){return Direction.Z}ClearContent(){this.meshIdToMesh=null,this.colorToMaterial=null}ResetContent(){this.meshIdToMesh=new Map,this.colorToMaterial=new ColorToMaterialConverter(this.model)}ImportContent(e,t){this.model.SetUnit(Unit.Meter);let r=ArrayBufferToUtf8String(e),n=null;try{n=JSON.parse(r)}catch(e){return this.SetError("Failed to parse bim file."),void t()}for(let e of n.meshes)this.meshIdToMesh.set(e.mesh_id,e);this.ImportProperties(n,this.model);for(let e of n.elements){let t=this.ImportElement(e);t.SetName(e.type),this.ImportProperties(e,t)}t()}ImportElement(e){let t=null;e.color&&(t=this.colorToMaterial.GetMaterialIndex(e.color.r,e.color.g,e.color.b,e.color.a));let r=this.model.GetRootNode(),n=this.meshIdToMesh.get(e.mesh_id),i=this.ImportMesh(n,(r=>{if(e.face_colors){return this.colorToMaterial.GetMaterialIndex(e.face_colors[4*r+0],e.face_colors[4*r+1],e.face_colors[4*r+2],e.face_colors[4*r+3])}return t})),o=this.model.AddMesh(i),s=new Node;s.AddMeshIndex(o);let a=new Coord3D(0,0,0);e.vector&&(a=new Coord3D(e.vector.x,e.vector.y,e.vector.z));let l=new Quaternion(0,0,0,1);e.rotation&&(l=new Quaternion(e.rotation.qx,e.rotation.qy,e.rotation.qz,e.rotation.qw));let h=new Coord3D(1,1,1),u=(new Matrix).ComposeTRS(a,l,h);return s.SetTransformation(new Transformation(u)),r.AddChildNode(s),i}ImportMesh(e,t){let r=new Mesh;for(let t=0;t<e.coordinates.length;t+=3)r.AddVertex(new Coord3D(e.coordinates[t+0],e.coordinates[t+1],e.coordinates[t+2]));for(let n=0;n<e.indices.length;n+=3){let i=new Triangle(e.indices[n+0],e.indices[n+1],e.indices[n+2]);i.SetMaterial(t(n/3)),r.AddTriangle(i)}return r}ImportProperties(e,t){function r(e,t,r){if(null==r)return;let n=new Property(PropertyType.Text,t,r);e.AddProperty(n)}if(!e.info||IsObjectEmpty(e.info))return;let n=e.info,i=new PropertyGroup("Info");r(i,"Guid",e.guid),r(i,"Type",e.type);for(let e in n)Object.prototype.hasOwnProperty.call(n,e)&&"string"==typeof n[e]&&r(i,e,n[e]);t.AddPropertyGroup(i)}}class ImporterThreeBase extends ImporterBase{constructor(){super(),this.colorConverter=null}CreateLoader(e){return null}GetMainObject(e){return e}IsMeshVisible(e){return!0}ClearContent(){this.loader=null,this.materialIdToIndex=null,this.objectUrlToFileName=null}ResetContent(){this.loader=null,this.materialIdToIndex=new Map,this.objectUrlToFileName=new Map}ImportContent(e,t){this.LoadModel(e,t)}LoadModel(e,t){let r=!1,n=new THREE.LoadingManager((()=>{r=!0}));const i=CreateObjectUrl(e);n.setURLModifier((e=>{if(e===i)return e;const t=GetFileName(e);if(GetFileExtension(e).length>0){const r=this.callbacks.getFileBuffer(e);if(null!==r){let e=CreateObjectUrl(r);return this.objectUrlToFileName.set(e,t),e}}return e}));const o=this.CreateLoader(n);null!==o?o.load(i,(e=>{WaitWhile((()=>!r||(this.OnThreeObjectsLoaded(e,t),!1)))}),(()=>{}),(e=>{this.SetError(e),t()})):t()}OnThreeObjectsLoaded(e,t){function r(e){let t=(new Matrix).CreateIdentity();return e.updateMatrix(),void 0!==e.matrix&&null!==e.matrix&&t.Set(e.matrix.elements),new Transformation(t)}function n(e,t,i,o){let s=new Node;void 0!==i.name&&s.SetName(i.name),s.SetTransformation(r(i)),o.AddChildNode(s);for(let r of i.children)n(e,t,r,s);if(i.isMesh&&e.IsMeshVisible(i)){let r=e.ConvertThreeMesh(i),n=t.AddMesh(r);s.AddMeshIndex(n)}}let i=this.GetMainObject(e),o=this.model.GetRootNode();o.SetTransformation(r(i));for(let e of i.children)n(this,this.model,e,o);t()}ConvertThreeMesh(e){let t=null;if(Array.isArray(e.material)){if(t=ConvertThreeGeometryToMesh(e.geometry,null,this.colorConverter),void 0===e.geometry.attributes.color||null===e.geometry.attributes.color){let r=[];for(let t=0;t<e.material.length;t++){const n=e.material[t],i=this.FindOrCreateMaterial(n);r.push(i)}for(let n=0;n<e.geometry.groups.length;n++){let i=e.geometry.groups[n],o=null;o=i.count===1/0?t.TriangleCount():i.start/3+i.count/3;for(let e=i.start/3;e<o;e++){t.GetTriangle(e).SetMaterial(r[i.materialIndex])}}}}else{const r=this.FindOrCreateMaterial(e.material);t=ConvertThreeGeometryToMesh(e.geometry,r,this.colorConverter)}return void 0!==e.name&&null!==e.name&&t.SetName(e.name),t}FindOrCreateMaterial(e){if(this.materialIdToIndex.has(e.id))return this.materialIdToIndex.get(e.id);let t=this.ConvertThreeMaterial(e),r=null;return null!==t&&(r=this.model.AddMaterial(t)),this.materialIdToIndex.set(e.id,r),r}ConvertThreeMaterial(e){function t(e,t){if(null==e)return null;if(void 0===e.image||null===e.image)return null;try{const r=Base64DataURIToArrayBuffer(function(e){if(void 0!==e.data&&null!==e.data){let t=new ImageData(e.width,e.height),r=e.width*e.height*4;for(let n=0;n<r;n++)t.data[n]=e.data[n];return THREE.ImageUtils.getDataURL(t)}return THREE.ImageUtils.getDataURL(e)}(e.image));let n=new TextureMap,i=null;return i=t.has(e.image.src)?t.get(e.image.src):void 0!==e.name&&null!==e.name?e.name+"."+GetFileExtensionFromMimeType(r.mimeType):"Embedded_"+e.id.toString()+"."+GetFileExtensionFromMimeType(r.mimeType),n.name=i,n.mimeType=r.mimeType,n.buffer=r.buffer,n.rotation=e.rotation,n.offset.x=e.offset.x,n.offset.y=e.offset.y,n.scale.x=e.repeat.x,n.scale.y=e.repeat.y,n}catch(e){return null}}if(e.name===THREE.Loader.DEFAULT_MATERIAL_NAME)return null;let r=new PhongMaterial;return r.name=e.name,r.color=this.ConvertThreeColor(e.color),r.opacity=e.opacity,r.transparent=e.transparent,r.alphaTest=e.alphaTest,"MeshPhongMaterial"===e.type&&(r.specular=this.ConvertThreeColor(e.specular),r.shininess=e.shininess/100),r.diffuseMap=t(e.map,this.objectUrlToFileName),r.normalMap=t(e.normalMap,this.objectUrlToFileName),r.bumpMap=t(e.bumpMap,this.objectUrlToFileName),r}ConvertThreeColor(e){return null!==this.colorConverter&&(e=this.colorConverter.Convert(e)),ConvertThreeColorToColor(e)}}class ImporterThreeFbx extends ImporterThreeBase{constructor(){super(),this.colorConverter=new ThreeLinearToSRGBColorConverter}CanImportExtension(e){return"fbx"===e}GetUpDirection(){return Direction.Y}CreateLoader(e){return e.addHandler(/\.tga$/i,new TGALoader(e)),new FBXLoader(e)}GetMainObject(e){return e}}class ImporterThreeDae extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"dae"===e}GetUpDirection(){return Direction.Y}CreateLoader(e){return e.addHandler(/\.tga$/i,new TGALoader(e)),new ColladaLoader(e)}GetMainObject(e){return e.scene}}class ImporterThreeWrl extends ImporterThreeBase{constructor(){super(),this.colorConverter=new ThreeLinearToSRGBColorConverter}CanImportExtension(e){return"wrl"===e}GetUpDirection(){return Direction.Y}CreateLoader(e){}GetMainObject(e){return e}IsMeshVisible(e){let t=!0;if(Array.isArray(e.material)){for(let r=0;r<e.material.length;r++)if(e.material[r].side===THREE.BackSide){t=!1;break}}else t=e.material.side!==THREE.BackSide;return t}}class ImporterThree3mf extends ImporterThreeBase{constructor(){super(),this.colorConverter=new ThreeSRGBToLinearColorConverter}CanImportExtension(e){return"3mf"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){return new ThreeMFLoader(e)}GetMainObject(e){return e}}class ImporterThreeAmf extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"amf"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){return new AMFLoader(e)}GetMainObject(e){return e}}class ImporterThreeBvh extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"bvh"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){return new BVHLoader(e)}GetMainObject(e){return e}}class ImporterThreeDraco extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"bvh"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){return new BVHLoader(e)}GetMainObject(e){return e}}class ImporterThreeRhino3dm extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"3dm"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){const t=new Rhino3dmLoader(e);return t.setLibraryPath("https://cdn.jsdelivr.net/npm/rhino3dm@8.4.0/"),t}GetMainObject(e){return e}}const DocumentInitResult={Success:0,NoDocumentXml:1};class FreeCadObject{constructor(e,t){this.name=e,this.type=t,this.shapeName=null,this.isVisible=!1,this.color=null,this.fileName=null,this.fileContent=null,this.inLinkCount=0,this.properties=null}IsConvertible(){return null!==this.fileName&&null!==this.fileContent&&(!!this.isVisible&&!(this.inLinkCount>0))}}class FreeCadDocument{constructor(){this.files=null,this.properties=null,this.objectNames=[],this.objectData=new Map}Init(e){let t=new Uint8Array(e);return this.files=fflate.unzipSync(t),this.LoadDocumentXml()?(this.LoadGuiDocumentXml(),DocumentInitResult.Success):DocumentInitResult.NoDocumentXml}GetObjectListToConvert(){let e=[];for(let t of this.objectNames){let r=this.objectData.get(t);r.IsConvertible()&&e.push(r)}return e}IsSupportedType(e){return!(!e.startsWith("Part::")&&!e.startsWith("PartDesign::"))&&-1===e.indexOf("Part2D")}HasFile(e){return e in this.files}LoadDocumentXml(){let e=this.GetXMLContent("Document.xml");if(null===e)return!1;this.properties=new PropertyGroup("Properties");let t=e.getElementsByTagName("Document");for(let e of t)for(let t of e.childNodes)"Properties"===t.tagName&&this.GetPropertiesFromElement(t,this.properties);let r=e.getElementsByTagName("Objects");for(let e of r){let t=e.getElementsByTagName("Object");for(let e of t){let t=e.getAttribute("name"),r=e.getAttribute("type");if(!this.IsSupportedType(r))continue;let n=new FreeCadObject(t,r);this.objectNames.push(t),this.objectData.set(t,n)}}let n=e.getElementsByTagName("ObjectData");for(let e of n){let t=e.getElementsByTagName("Object");for(let e of t){let t=e.getAttribute("name");if(!this.objectData.has(t))continue;let r=this.objectData.get(t);r.properties=new PropertyGroup("Properties");for(let t of e.childNodes)"Properties"===t.tagName&&this.GetPropertiesFromElement(t,r.properties);let n=e.getElementsByTagName("Property");for(let e of n){let t=e.getAttribute("name");if("Label"===t)r.shapeName=this.GetFirstChildValue(e,"String","value");else if("Visibility"===t){let t=this.GetFirstChildValue(e,"Bool","value");r.isVisible="true"===t}else if("Visible"===t){let t=this.GetFirstChildValue(e,"Bool","value");r.isVisible="true"===t}else if("Shape"===t){let t=this.GetFirstChildValue(e,"Part","file");if(!this.HasFile(t))continue;let n=GetFileExtension(t);if("brp"!==n&&"brep"!==n)continue;r.fileName=t,r.fileContent=this.files[t]}}let i=e.getElementsByTagName("Link");for(let e of i){let t=e.getAttribute("value");if(this.objectData.has(t)){this.objectData.get(t).inLinkCount+=1}}}}return!0}LoadGuiDocumentXml(){let e=this.GetXMLContent("GuiDocument.xml");if(null===e)return!1;let t=e.getElementsByTagName("ViewProvider");for(let e of t){let t=e.getAttribute("name");if(!this.objectData.has(t))continue;let r=this.objectData.get(t),n=e.getElementsByTagName("Property");for(let e of n){let t=e.getAttribute("name");if("Visibility"===t){let t=this.GetFirstChildValue(e,"Bool","value");r.isVisible="true"===t}else if("ShapeColor"===t){let t=this.GetFirstChildValue(e,"PropertyColor","value"),n=parseInt(t,10);r.color=new RGBAColor(n>>24&255,n>>16&255,n>>8&255,255)}}}return!0}GetPropertiesFromElement(e,t){let r=e.getElementsByTagName("Property");for(let e of r){let r=e.getAttribute("name"),n=e.getAttribute("type"),i=null;if("App::PropertyBool"===n){let t=this.GetFirstChildValue(e,"String","bool");null!==t&&t.length>0&&(i=new Property(PropertyType.Boolean,r,"true"===t))}else if("App::PropertyInteger"===n){let t=this.GetFirstChildValue(e,"Integer","value");null!==t&&t.length>0&&(i=new Property(PropertyType.Integer,r,parseInt(t)))}else if("App::PropertyString"===n){let t=this.GetFirstChildValue(e,"String","value");null!==t&&t.length>0&&(i=new Property(PropertyType.Text,r,t))}else if("App::PropertyUUID"===n){let t=this.GetFirstChildValue(e,"Uuid","value");null!==t&&t.length>0&&(i=new Property(PropertyType.Text,r,t))}else if("App::PropertyFloat"===n||"App::PropertyLength"===n||"App::PropertyDistance"===n||"App::PropertyArea"===n||"App::PropertyVolume"===n){let t=this.GetFirstChildValue(e,"Float","value");null!==t&&t.length>0&&(i=new Property(PropertyType.Number,r,parseFloat(t)))}null!==i&&t.AddProperty(i)}}GetXMLContent(e){if(!this.HasFile(e))return null;let t=new DOMParser,r=ArrayBufferToUtf8String(this.files[e]);return t.parseFromString(r,"text/xml")}GetFirstChildValue(e,t,r){let n=e.getElementsByTagName(t);return 0===n.length?null:n[0].getAttribute(r)}}class ImporterFcstd extends ImporterBase{constructor(){super(),this.worker=null,this.document=null}CanImportExtension(e){return"fcstd"===e}GetUpDirection(){return Direction.Z}ClearContent(){null!==this.worker&&(this.worker.terminate(),this.worker=null),this.document=null}ResetContent(){this.worker=null,this.document=new FreeCadDocument}ImportContent(e,t){if(this.document.Init(e)===DocumentInitResult.NoDocumentXml)return this.SetError("No Document.xml found."),void t();null!==this.document.properties&&this.document.properties.PropertyCount()>0&&this.model.AddPropertyGroup(this.document.properties);let r=this.document.GetObjectListToConvert();if(0===r.length)return this.SetError("No importable object found."),void t();this.ConvertObjects(r,t)}ConvertObjects(e,t){let r=GetExternalLibPath("loaders/occt-import-js-worker.js");this.worker=new Worker(r);let n=0,i=new ColorToMaterialConverter(this.model),o=r=>{if(null!==r){let t=e[n];this.OnFileConverted(t,r,i)}if(n+=1,n===e.length)t();else{let t=e[n];this.worker.postMessage({format:"brep",buffer:t.fileContent})}};this.worker.addEventListener("message",(e=>{o(e.data)})),this.worker.addEventListener("error",(e=>{o(null)}));let s=e[n];this.worker.postMessage({format:"brep",buffer:s.fileContent})}OnFileConverted(e,t,r){if(!t.success||0===t.meshes.length)return;let n=new Node;null!==e.shapeName&&n.SetName(e.shapeName);let i=1;for(let o of t.meshes){let t=null;null!==e.color&&(t=r.GetMaterialIndex(e.color.r,e.color.g,e.color.b,e.color.a));let s=ConvertThreeGeometryToMesh(o,t,null);if(null!==e.shapeName){let t=i.toString().padStart(3,"0");s.SetName(e.shapeName+" "+t)}null!==e.properties&&e.properties.PropertyCount()>0&&s.AddPropertyGroup(e.properties);let a=this.model.AddMesh(s);n.AddMeshIndex(a),i+=1}this.model.GetRootNode().AddChildNode(n)}}class ImportSettings{constructor(){this.defaultLineColor=new RGBColor(100,100,100),this.defaultColor=new RGBColor(200,200,200)}}const ImportErrorCode={NoImportableFile:1,FailedToLoadFile:2,ImportFailed:3,UnknownError:4};class ImportError{constructor(e){this.code=e,this.mainFile=null,this.message=null}}class ImportResult{constructor(){this.model=null,this.mainFile=null,this.upVector=null,this.usedFiles=null,this.missingFiles=null}}class ImporterFileAccessor{constructor(e){this.getBufferCallback=e,this.fileBuffers=new Map}GetFileBuffer(e){let t=GetFileName(e);if(this.fileBuffers.has(t))return this.fileBuffers.get(t);let r=this.getBufferCallback(t);return this.fileBuffers.set(t,r),r}}class Importer{constructor(){this.importers=[new ImporterObj,new ImporterStl,new ImporterOff,new ImporterPly,new Importer3ds,new ImporterGltf,new ImporterBim,new ImporterIfc,new ImporterOcct,new ImporterFcstd,new ImporterThreeFbx,new ImporterThreeDae,new ImporterThree3mf,new ImporterThreeAmf,new ImporterThreeBvh,new ImporterThreeRhino3dm],this.fileList=new ImporterFileList,this.model=null,this.usedFiles=[],this.missingFiles=[]}AddImporter(e){this.importers.push(e)}ImportFiles(e,t,r){r.onLoadStart(),this.LoadFiles(e,{onReady:()=>{r.onImportStart(),RunTaskAsync((()=>{this.DecompressArchives(this.fileList,(()=>{this.ImportLoadedFiles(t,r)}))}))},onFileListProgress:r.onFileListProgress,onFileLoadProgress:r.onFileLoadProgress})}LoadFiles(e,t){let r=new ImporterFileList;r.FillFromInputFiles(e);let n=!1;if(this.HasImportableFile(r))n=!0;else{let e=!1;for(let t=0;t<this.missingFiles.length;t++){let n=this.missingFiles[t];r.ContainsFileByPath(n)&&(e=!0)}e?(this.fileList.ExtendFromFileList(r),n=!1):n=!0}n&&(this.fileList=r),this.fileList.GetContent({onReady:t.onReady,onFileListProgress:t.onFileListProgress,onFileLoadProgress:t.onFileLoadProgress})}ImportLoadedFiles(e,t){let r=this.GetImportableFiles(this.fileList);if(0!==r.length)if(1!==r.length&&t.onSelectMainFile){let n=r.map((e=>e.file.name));t.onSelectMainFile(n,(n=>{null!==n?RunTaskAsync((()=>{let i=r[n];this.ImportLoadedMainFile(i,e,t)})):t.onImportError(new ImportError(ImportErrorCode.NoImportableFile))}))}else{let n=r[0];this.ImportLoadedMainFile(n,e,t)}else t.onImportError(new ImportError(ImportErrorCode.NoImportableFile))}ImportLoadedMainFile(e,t,r){if(null===e||null===e.file||null===e.file.content){let t=new ImportError(ImportErrorCode.FailedToLoadFile);return null!==e&&null!==e.file&&(t.mainFile=e.file.name),void r.onImportError(t)}this.model=null,this.usedFiles=[],this.missingFiles=[],this.usedFiles.push(e.file.name);let n=e.importer,i=new ImporterFileAccessor((e=>{let t=null,r=this.fileList.FindFileByPath(e);return null===r||null===r.content?(this.missingFiles.push(e),t=null):(this.usedFiles.push(e),t=r.content),t}));n.Import(e.file.name,e.file.extension,e.file.content,{getDefaultLineMaterialColor:()=>t.defaultLineColor,getDefaultMaterialColor:()=>t.defaultColor,getFileBuffer:e=>i.GetFileBuffer(e),onSuccess:()=>{this.model=n.GetModel();let t=new ImportResult;t.mainFile=e.file.name,t.model=this.model,t.usedFiles=this.usedFiles,t.missingFiles=this.missingFiles,t.upVector=n.GetUpDirection(),r.onImportSuccess(t)},onError:()=>{let t=new ImportError(ImportErrorCode.ImportFailed);t.mainFile=e.file.name,t.message=n.GetErrorMessage(),r.onImportError(t)},onComplete:()=>{n.Clear()}})}DecompressArchives(e,t){let r=e.GetFiles(),n=[];for(let e of r)"zip"===e.extension&&n.push(e);if(0!==n.length){for(let t=0;t<n.length;t++){const r=n[t],i=new Uint8Array(r.content),o=fflate.unzipSync(i);for(const t in o)if(Object.prototype.hasOwnProperty.call(o,t)){let r=new ImporterFile(t,FileSource.Decompressed,null);r.SetContent(o[t].buffer),e.AddFile(r)}}t()}else t()}GetFileList(){return this.fileList}HasImportableFile(e){return this.GetImportableFiles(e).length>0}GetImportableFiles(e){function t(e,t){for(let r=0;r<t.length;r++){let n=t[r];if(n.CanImportExtension(e.extension))return n}return null}let r=[],n=e.GetFiles();for(let e=0;e<n.length;e++){let i=n[e],o=t(i,this.importers);null!==o&&r.push({file:i,importer:o})}return r}}class ImporterThreeSvg extends ImporterThreeBase{constructor(){super()}CanImportExtension(e){return"svg"===e}GetUpDirection(){return Direction.Z}CreateLoader(e){return new SVGLoader(e)}GetMainObject(e){function t(e){const t=e.userData.style;return void 0!==t.fill&&"none"!==t.fill}function r(e,t,r){let n=null;for(let i of e)if(i.style===t&&i.opacity===r){n=i.material;break}return null===n&&(n=new THREE.MeshPhongMaterial({color:(new THREE.Color).setStyle(t),opacity:r,transparent:r<1}),e.push({style:t,opacity:r,material:n})),n}let n=[],i=new THREE.Object3D;i.rotation.x=Math.PI;for(let o of e.paths){const e=SVGLoader.createShapes(o);if(t(o)){let t=o.userData.style,s=r(n,t.fill,t.opacity);for(const t of e){const e=new THREE.ExtrudeGeometry(t,{depth:10,bevelEnabled:!1}),r=new THREE.Mesh(e,s);r.name=o.userData.node.id,i.add(r)}}}return i}}class GeneratorParams{constructor(){this.name=null,this.material=null}SetName(e){return this.name=e,this}SetMaterial(e){return this.material=e,this}}class Generator{constructor(e){this.params=e||new GeneratorParams,this.mesh=new Mesh,null!==this.params.name&&this.mesh.SetName(this.params.name),this.curve=null}GetMesh(){return this.mesh}AddVertex(e,t,r){let n=new Coord3D(e,t,r);return this.mesh.AddVertex(n)}AddVertices(e){let t=[];for(let r=0;r<e.length;r++){let n=e[r];t.push(this.AddVertex(n.x,n.y,n.z))}return t}SetCurve(e){this.curve=e}ResetCurve(){this.curve=null}AddTriangle(e,t,r){let n=new Triangle(e,t,r);return null!==this.params.material&&(n.mat=this.params.material),null!==this.curve&&n.SetCurve(this.curve),this.mesh.AddTriangle(n)}AddTriangleInverted(e,t,r){this.AddTriangle(e,r,t)}AddConvexPolygon(e){for(let t=0;t<e.length-2;t++)this.AddTriangle(e[0],e[t+1],e[t+2])}AddConvexPolygonInverted(e){for(let t=0;t<e.length-2;t++)this.AddTriangleInverted(e[0],e[t+1],e[t+2])}}class GeneratorHelper{constructor(e){this.generator=e}GenerateSurfaceBetweenPolygons(e,t){if(e.length!==t.length)return;const r=e.length;for(let n=0;n<r;n++){const i=n,o=n<r-1?i+1:0;this.generator.AddConvexPolygon([e[i],e[o],t[o],t[i]])}}GenerateTriangleFan(e,t){const r=e.length;for(let n=0;n<r;n++){const i=n,o=n<r-1?i+1:0;this.generator.AddTriangle(t,e[i],e[o])}}}function GetCylindricalCoord(e,t){return new Coord2D(e*Math.cos(t),e*Math.sin(t))}function GenerateCuboid(e,t,r,n){if(!IsPositive(t)||!IsPositive(r)||!IsPositive(n))return null;let i=new Generator(e);return i.AddVertex(0,0,0),i.AddVertex(t,0,0),i.AddVertex(t,r,0),i.AddVertex(0,r,0),i.AddVertex(0,0,n),i.AddVertex(t,0,n),i.AddVertex(t,r,n),i.AddVertex(0,r,n),i.AddConvexPolygon([0,3,2,1]),i.AddConvexPolygon([0,1,5,4]),i.AddConvexPolygon([1,2,6,5]),i.AddConvexPolygon([2,3,7,6]),i.AddConvexPolygon([3,0,4,7]),i.AddConvexPolygon([4,5,6,7]),i.GetMesh()}function GenerateCone(e,t,r,n,i,o){if(IsNegative(t)||IsNegative(r))return null;if(!IsPositive(n)||i<3)return null;let s=IsZero(t),a=IsZero(r);if(s&&a)return null;let l=new Generator(e),h=new GeneratorHelper(l);const u=2*Math.PI/i,d=o?1:null;let c=[];if(s)c.push(l.AddVertex(0,0,n));else for(let e=0;e<i;e++){let r=GetCylindricalCoord(t,e*u);c.push(l.AddVertex(r.x,r.y,n))}let m=[];if(a)m.push(l.AddVertex(0,0,0));else for(let e=0;e<i;e++){let t=GetCylindricalCoord(r,e*u);m.push(l.AddVertex(t.x,t.y,0))}return s?(l.SetCurve(d),h.GenerateTriangleFan(m,c[0]),l.ResetCurve(),l.AddConvexPolygonInverted(m)):a?(l.SetCurve(d),h.GenerateTriangleFan(c.slice().reverse(),m[0]),l.ResetCurve(),l.AddConvexPolygon(c)):(l.SetCurve(d),h.GenerateSurfaceBetweenPolygons(m,c),l.ResetCurve(),l.AddConvexPolygonInverted(m),l.AddConvexPolygon(c)),l.GetMesh()}function GenerateCylinder(e,t,r,n,i){return GenerateCone(e,t,t,r,n,i)}function GenerateSphere(e,t,r,n){function i(e,t,r){return new Coord3D(e*Math.sin(t)*Math.cos(r),e*Math.sin(t)*Math.sin(r),e*Math.cos(t))}if(!IsPositive(t)||r<3)return null;let o=new Generator(e),s=new GeneratorHelper(o);o.SetCurve(n?1:null);let a=[],l=r+1;const h=Math.PI/r,u=2*Math.PI/r;for(let e=1;e<l-1;e++){let n=[],l=e*h;for(let e=0;e<r;e++){let r=i(t,l,-(e*u));n.push(o.AddVertex(r.x,r.y,r.z))}e>1&&s.GenerateSurfaceBetweenPolygons(a[a.length-1],n),a.push(n)}let d=o.AddVertex(0,0,t),c=o.AddVertex(0,0,-t);return s.GenerateTriangleFan(a[0].slice().reverse(),d),s.GenerateTriangleFan(a[a.length-1],c),o.ResetCurve(),o.GetMesh()}function GeneratePlatonicSolid(e,t,r){function n(e,t,r,n,i){let o=new Coord3D(r,n,i);o.MultiplyScalar(t/o.Length()),e.AddVertex(o.x,o.y,o.z)}if(!IsPositive(r))return null;let i=new Generator(e);if("tetrahedron"===t){let e=1;n(i,r,+e,+e,+e),n(i,r,-e,-e,+e),n(i,r,-e,+e,-e),n(i,r,+e,-e,-e),i.AddTriangle(0,1,3),i.AddTriangle(0,2,1),i.AddTriangle(0,3,2),i.AddTriangle(1,2,3)}else if("hexahedron"===t){let e=1;n(i,r,+e,+e,+e),n(i,r,+e,+e,-e),n(i,r,+e,-e,+e),n(i,r,+e,-e,-e),n(i,r,-e,+e,+e),n(i,r,-e,+e,-e),n(i,r,-e,-e,+e),n(i,r,-e,-e,-e),i.AddConvexPolygon([0,1,5,4]),i.AddConvexPolygon([0,2,3,1]),i.AddConvexPolygon([0,4,6,2]),i.AddConvexPolygon([1,3,7,5]),i.AddConvexPolygon([2,6,7,3]),i.AddConvexPolygon([4,5,7,6])}else if("octahedron"===t){let e=1,t=0;n(i,r,+e,+t,+t),n(i,r,-e,+t,+t),n(i,r,+t,+e,+t),n(i,r,+t,-e,+t),n(i,r,+t,+t,+e),n(i,r,+t,+t,-e),i.AddTriangle(0,2,4),i.AddTriangle(0,3,5),i.AddTriangle(0,4,3),i.AddTriangle(0,5,2),i.AddTriangle(1,2,5),i.AddTriangle(1,3,4),i.AddTriangle(1,4,2),i.AddTriangle(1,5,3)}else if("dodecahedron"===t){let e=1,t=0,o=(1+Math.sqrt(5))/2,s=1/o;n(i,r,+e,+e,+e),n(i,r,+e,+e,-e),n(i,r,+e,-e,+e),n(i,r,-e,+e,+e),n(i,r,+e,-e,-e),n(i,r,-e,+e,-e),n(i,r,-e,-e,+e),n(i,r,-e,-e,-e),n(i,r,+t,+s,+o),n(i,r,+t,+s,-o),n(i,r,+t,-s,+o),n(i,r,+t,-s,-o),n(i,r,+s,+o,+t),n(i,r,+s,-o,+t),n(i,r,-s,+o,+t),n(i,r,-s,-o,+t),n(i,r,+o,+t,+s),n(i,r,-o,+t,+s),n(i,r,+o,+t,-s),n(i,r,-o,+t,-s),i.AddConvexPolygon([0,8,10,2,16]),i.AddConvexPolygon([0,16,18,1,12]),i.AddConvexPolygon([0,12,14,3,8]),i.AddConvexPolygon([1,9,5,14,12]),i.AddConvexPolygon([1,18,4,11,9]),i.AddConvexPolygon([2,10,6,15,13]),i.AddConvexPolygon([2,13,4,18,16]),i.AddConvexPolygon([3,14,5,19,17]),i.AddConvexPolygon([3,17,6,10,8]),i.AddConvexPolygon([4,13,15,7,11]),i.AddConvexPolygon([5,9,11,7,19]),i.AddConvexPolygon([6,17,19,7,15])}else if("icosahedron"===t){let e=1,t=0,o=(1+Math.sqrt(5))/2;n(i,r,+t,+e,+o),n(i,r,+t,+e,-o),n(i,r,+t,-e,+o),n(i,r,+t,-e,-o),n(i,r,+e,+o,+t),n(i,r,+e,-o,+t),n(i,r,-e,+o,+t),n(i,r,-e,-o,+t),n(i,r,+o,+t,+e),n(i,r,+o,+t,-e),n(i,r,-o,+t,+e),n(i,r,-o,+t,-e),i.AddTriangle(0,2,8),i.AddTriangle(0,4,6),i.AddTriangle(0,6,10),i.AddTriangle(0,8,4),i.AddTriangle(0,10,2),i.AddTriangle(1,3,11),i.AddTriangle(1,4,9),i.AddTriangle(1,6,4),i.AddTriangle(1,9,3),i.AddTriangle(1,11,6),i.AddTriangle(2,5,8),i.AddTriangle(2,7,5),i.AddTriangle(2,10,7),i.AddTriangle(3,5,7),i.AddTriangle(3,7,11),i.AddTriangle(3,9,5),i.AddTriangle(4,8,9),i.AddTriangle(5,9,8),i.AddTriangle(6,11,10),i.AddTriangle(7,10,11)}return i.GetMesh()}function GetTriangleArea(e,t,r){const n=CoordDistance3D(e,t),i=CoordDistance3D(t,r),o=CoordDistance3D(e,r),s=(n+i+o)/2,a=s*(s-n)*(s-i)*(s-o);return a<0?0:Math.sqrt(a)}function GetTetrahedronSignedVolume(e,t,r){return DotVector3D(e,CrossVector3D(t,r))/6}function CalculateVolume(e){if(e instanceof Model){let t=0;return e.EnumerateMeshInstances((e=>{t+=CalculateVolume(e)})),t}{let t=0;return e.EnumerateTriangleVertices(((e,r,n)=>{t+=GetTetrahedronSignedVolume(e,r,n)})),t}}function CalculateSurfaceArea(e){let t=0;return e.EnumerateTriangleVertices(((e,r,n)=>{t+=GetTriangleArea(e,r,n)})),t}const NavigationMode={FixedUpVector:1,FreeOrbit:2},ProjectionMode={Perspective:1,Orthographic:2};class Camera{constructor(e,t,r,n){this.eye=e,this.center=t,this.up=r,this.fov=n}Clone(){return new Camera(this.eye.Clone(),this.center.Clone(),this.up.Clone(),this.fov)}}function CameraIsEqual3D(e,t){return CoordIsEqual3D(e.eye,t.eye)&&CoordIsEqual3D(e.center,t.center)&&CoordIsEqual3D(e.up,t.up)&&IsEqual(e.fov,t.fov)}const LineThresholdInPixels=10,IntersectionMode={MeshOnly:1,MeshAndLine:2};function SetThreeMeshPolygonOffset(e,t){function r(e,t){for(let r of e)r.polygonOffset=t,r.polygonOffsetUnit=1,r.polygonOffsetFactor=1}r(e.material,t),e.userData.threeMaterials&&r(e.userData.threeMaterials,t)}class ViewerModel{constructor(e){this.scene=e,this.rootObject=null}IsEmpty(){return null===this.rootObject}SetRootObject(e){null!==this.rootObject&&this.Clear(),this.rootObject=e,this.scene.add(this.rootObject)}GetRootObject(){return this.rootObject}AddObject(e){if(null===this.rootObject){let e=new THREE.Object3D;this.SetRootObject(e)}this.rootObject.add(e)}Traverse(e){null!==this.rootObject&&this.rootObject.traverse((t=>{e(t)}))}UpdateWorldMatrix(){null!==this.rootObject&&this.rootObject.updateWorldMatrix(!0,!0)}Clear(){DisposeThreeObjects(this.rootObject),this.scene.remove(this.rootObject),this.rootObject=null}}class EdgeSettings{constructor(e,t,r){this.showEdges=e,this.edgeColor=t,this.edgeThreshold=r}Clone(){return new EdgeSettings(this.showEdges,this.edgeColor.Clone(),this.edgeThreshold)}}class ViewerMainModel{constructor(e){this.scene=e,this.mainModel=new ViewerModel(this.scene),this.edgeModel=new ViewerModel(this.scene),this.edgeSettings=new EdgeSettings(!1,new RGBColor(0,0,0),1),this.hasLines=!1,this.hasPolygonOffset=!1}SetMainObject(e){this.mainModel.SetRootObject(e),this.hasLines=!1,this.hasPolygonOffset=!1,this.EnumerateLines((e=>{this.hasLines=!0})),this.edgeSettings.showEdges&&this.GenerateEdgeModel(),this.UpdatePolygonOffset()}UpdateWorldMatrix(){this.mainModel.UpdateWorldMatrix(),this.edgeModel.UpdateWorldMatrix()}SetEdgeSettings(e){let t=!1;if(!e.showEdges||this.edgeSettings.showEdges&&this.edgeSettings.edgeThreshold===e.edgeThreshold||(t=!0),this.edgeSettings=e,!this.mainModel.IsEmpty())if(this.edgeSettings.showEdges)if(t)this.ClearEdgeModel(),this.GenerateEdgeModel();else{let e=ConvertColorToThreeColor(this.edgeSettings.edgeColor);this.EnumerateEdges((t=>{t.material.color=e}))}else this.ClearEdgeModel()}GenerateEdgeModel(){let e=ConvertColorToThreeColor(this.edgeSettings.edgeColor);this.UpdateWorldMatrix(),this.EnumerateMeshes((t=>{let r=new THREE.EdgesGeometry(t.geometry,this.edgeSettings.edgeThreshold),n=new THREE.LineSegments(r,new THREE.LineBasicMaterial({color:e}));n.applyMatrix4(t.matrixWorld),n.userData=t.userData,n.visible=t.visible,this.edgeModel.AddObject(n)})),this.UpdatePolygonOffset()}GetBoundingBox(e){let t=!1,r=new THREE.Box3;return this.EnumerateMeshesAndLines((n=>{e(n.userData)&&(r.union((new THREE.Box3).setFromObject(n)),t=!0)})),t?r:null}GetBoundingSphere(e){let t=this.GetBoundingBox(e);if(null===t)return null;let r=new THREE.Sphere;return t.getBoundingSphere(r),r}Clear(){this.mainModel.Clear(),this.ClearEdgeModel()}ClearEdgeModel(){this.edgeModel.IsEmpty()||(this.UpdatePolygonOffset(),this.edgeModel.Clear())}EnumerateMeshes(e){this.mainModel.Traverse((t=>{t.isMesh&&e(t)}))}EnumerateLines(e){this.mainModel.Traverse((t=>{t.isLineSegments&&e(t)}))}EnumerateMeshesAndLines(e){this.mainModel.Traverse((t=>{(t.isMesh||t.isLineSegments)&&e(t)}))}EnumerateEdges(e){this.edgeModel.Traverse((t=>{t.isLineSegments&&e(t)}))}HasLinesOrEdges(){return this.hasLines||this.edgeSettings.showEdges}UpdatePolygonOffset(){let e=this.HasLinesOrEdges();e!==this.hasPolygonOffset&&(this.EnumerateMeshes((t=>{SetThreeMeshPolygonOffset(t,e)})),this.hasPolygonOffset=e)}GetMeshIntersectionUnderMouse(e,t,r,n,i){if(this.mainModel.IsEmpty())return null;if(t.x<0||t.x>n||t.y<0||t.y>i)return null;let o=new THREE.Vector2;o.x=t.x/n*2-1,o.y=-t.y/i*2+1;let s=new THREE.Raycaster;s.setFromCamera(o,r),s.params.Line.threshold=10;let a=s.intersectObject(this.mainModel.GetRootObject(),!0);for(let o=0;o<a.length;o++){let s=a[o];if(s.object.visible){if(s.object.isMesh)return s;if(s.object.isLineSegments){if(e===IntersectionMode.MeshOnly)continue;if(GetLineSegmentsProjectedDistance(r,n,i,s.object,t)>10)continue;return s}}}return null}}let ParameterConverter={IntegerToString:e=>e.toString(),StringToInteger:e=>parseInt(e,10),NumberToString:e=>e.toFixed(5),StringToNumber:e=>parseFloat(e),ModelUrlsToString:function(e){return null===e?null:e.join(",")},StringToModelUrls:function(e){return null===e||0===e.length?null:e.split(",")},CameraToString:function(e){if(null===e)return null;return[this.NumberToString(e.eye.x),this.NumberToString(e.eye.y),this.NumberToString(e.eye.z),this.NumberToString(e.center.x),this.NumberToString(e.center.y),this.NumberToString(e.center.z),this.NumberToString(e.up.x),this.NumberToString(e.up.y),this.NumberToString(e.up.z),this.NumberToString(e.fov)].join(",")},ProjectionModeToString:function(e){return e===ProjectionMode.Perspective?"perspective":e===ProjectionMode.Orthographic?"orthographic":null},StringToCamera:function(e){if(null===e||0===e.length)return null;let t=e.split(",");if(9!==t.length&&10!==t.length)return null;let r=45;return t.length>=10&&(r=this.StringToNumber(t[9])),new Camera(new Coord3D(this.StringToNumber(t[0]),this.StringToNumber(t[1]),this.StringToNumber(t[2])),new Coord3D(this.StringToNumber(t[3]),this.StringToNumber(t[4]),this.StringToNumber(t[5])),new Coord3D(this.StringToNumber(t[6]),this.StringToNumber(t[7]),this.StringToNumber(t[8])),r)},StringToProjectionMode:function(e){return"perspective"===e?ProjectionMode.Perspective:"orthographic"===e?ProjectionMode.Orthographic:null},RGBColorToString:function(e){return null===e?null:[this.IntegerToString(e.r),this.IntegerToString(e.g),this.IntegerToString(e.b)].join(",")},RGBAColorToString:function(e){return null===e?null:[this.IntegerToString(e.r),this.IntegerToString(e.g),this.IntegerToString(e.b),this.IntegerToString(e.a)].join(",")},StringToRGBColor:function(e){if(null===e||0===e.length)return null;let t=e.split(",");return 3!==t.length?null:new RGBColor(this.StringToInteger(t[0]),this.StringToInteger(t[1]),this.StringToInteger(t[2]))},StringToRGBAColor:function(e){if(null===e||0===e.length)return null;let t=e.split(",");if(3!==t.length&&4!==t.length)return null;let r=new RGBAColor(this.StringToInteger(t[0]),this.StringToInteger(t[1]),this.StringToInteger(t[2]),255);return 4===t.length&&(r.a=this.StringToInteger(t[3])),r},EnvironmentSettingsToString(e){if(null===e)return null;return[e.environmentMapName,e.backgroundIsEnvMap?"on":"off"].join(",")},StringToEnvironmentSettings:function(e){if(null===e||0===e.length)return null;let t=e.split(",");return 2!==t.length?null:{environmentMapName:t[0],backgroundIsEnvMap:"on"===t[1]}},EdgeSettingsToString:function(e){if(null===e)return null;return[e.showEdges?"on":"off",this.RGBColorToString(e.edgeColor),this.IntegerToString(e.edgeThreshold)].join(",")},StringToEdgeSettings:function(e){if(null===e||0===e.length)return null;let t=e.split(",");return 5!==t.length?null:new EdgeSettings("on"===t[0],new RGBColor(this.StringToInteger(t[1]),this.StringToInteger(t[2]),this.StringToInteger(t[3])),this.StringToInteger(t[4]))}};class ParameterListBuilder{constructor(e){this.separator=e,this.paramList=""}AddModelUrls(e){return this.AddUrlPart("model",ParameterConverter.ModelUrlsToString(e)),this}AddCamera(e){return this.AddUrlPart("camera",ParameterConverter.CameraToString(e)),this}AddProjectionMode(e){return this.AddUrlPart("projectionmode",ParameterConverter.ProjectionModeToString(e)),this}AddEnvironmentSettings(e){return this.AddUrlPart("envsettings",ParameterConverter.EnvironmentSettingsToString(e)),this}AddBackgroundColor(e){return this.AddUrlPart("backgroundcolor",ParameterConverter.RGBAColorToString(e)),this}AddDefaultColor(e){return this.AddUrlPart("defaultcolor",ParameterConverter.RGBColorToString(e)),this}AddDefaultLineColor(e){return this.AddUrlPart("defaultlinecolor",ParameterConverter.RGBColorToString(e)),this}AddEdgeSettings(e){return this.AddUrlPart("edgesettings",ParameterConverter.EdgeSettingsToString(e)),this}AddUrlPart(e,t){null!==e&&null!==t&&(this.paramList.length>0&&(this.paramList+=this.separator),this.paramList+=e+"="+t)}GetParameterList(){return this.paramList}}class ParameterListParser{constructor(e,t){this.separator=t,this.paramList=e}GetModelUrls(){if(-1===this.paramList.indexOf("="))return this.paramList.split(",");let e=this.GetKeywordParams("model");return ParameterConverter.StringToModelUrls(e)}GetCamera(){let e=this.GetKeywordParams("camera");return ParameterConverter.StringToCamera(e)}GetProjectionMode(){let e=this.GetKeywordParams("cameramode");return null===e&&(e=this.GetKeywordParams("projectionmode")),ParameterConverter.StringToProjectionMode(e)}GetEnvironmentSettings(){let e=this.GetKeywordParams("envsettings");return ParameterConverter.StringToEnvironmentSettings(e)}GetBackgroundColor(){let e=this.GetKeywordParams("backgroundcolor");return ParameterConverter.StringToRGBAColor(e)}GetDefaultColor(){let e=this.GetKeywordParams("defaultcolor");return ParameterConverter.StringToRGBColor(e)}GetDefaultLineColor(){let e=this.GetKeywordParams("defaultlinecolor");return ParameterConverter.StringToRGBColor(e)}GetEdgeSettings(){let e=this.GetKeywordParams("edgesettings");return ParameterConverter.StringToEdgeSettings(e)}GetKeywordParams(e){if(null===this.paramList||0===this.paramList.length)return null;let t=e+"=",r=this.paramList.split(this.separator);for(let e=0;e<r.length;e++){let n=r[e];if(n.startsWith(t))return n.substring(t.length)}return null}}function CreateUrlBuilder(){return new ParameterListBuilder("$")}function CreateUrlParser(e){return new ParameterListParser(e,"$")}function CreateModelUrlParameters(e){let t=CreateUrlBuilder();return t.AddModelUrls(e),t.GetParameterList()}const MaterialGeometryType={Line:1,Face:2};class ModelToThreeConversionParams{constructor(){this.forceMediumpForMaterials=!1}}class ModelToThreeConversionOutput{constructor(){this.defaultMaterials=[],this.objectUrls=[]}}class ThreeConversionStateHandler{constructor(e){this.callbacks=e,this.texturesNeeded=0,this.texturesLoaded=0,this.threeObject=null}OnTextureNeeded(){this.texturesNeeded+=1}OnTextureLoaded(){this.texturesLoaded+=1,this.callbacks.onTextureLoaded(),this.Finish()}OnModelLoaded(e){this.threeObject=e,this.Finish()}Finish(){null!==this.threeObject&&this.texturesNeeded===this.texturesLoaded&&this.callbacks.onModelLoaded(this.threeObject)}}class ThreeNodeTree{constructor(e,t){this.model=e,this.threeNodeItems=[],this.AddNode(e.GetRootNode(),t)}AddNode(e,t){let r=e.GetTransformation().GetMatrix(),n=(new THREE.Matrix4).fromArray(r.Get());t.applyMatrix4(n);for(let r of e.GetChildNodes()){let e=new THREE.Object3D;t.add(e),this.AddNode(r,e)}for(let r of e.GetMeshIndices()){let n=new MeshInstanceId(e.GetId(),r),i=this.model.GetMesh(r);this.threeNodeItems.push({meshInstance:new MeshInstance(n,e,i),threeNode:t})}}GetNodeItems(){return this.threeNodeItems}}class ThreeMaterialHandler{constructor(e,t,r,n){this.model=e,this.stateHandler=t,this.conversionParams=r,this.conversionOutput=n,this.shadingType=GetShadingType(e),this.modelToThreeLineMaterial=new Map,this.modelToThreeMaterial=new Map}GetThreeMaterial(e,t){if(t===MaterialGeometryType.Face){if(!this.modelToThreeMaterial.has(e)){let t=this.CreateThreeFaceMaterial(e);this.modelToThreeMaterial.set(e,t)}return this.modelToThreeMaterial.get(e)}if(t===MaterialGeometryType.Line){if(!this.modelToThreeLineMaterial.has(e)){let t=this.CreateThreeLineMaterial(e);this.modelToThreeLineMaterial.set(e,t)}return this.modelToThreeLineMaterial.get(e)}return null}CreateThreeFaceMaterial(e){let t=this.model.GetMaterial(e),r=ConvertColorToThreeColor(t.color);t.vertexColors&&r.setRGB(1,1,1);let n={color:r,vertexColors:t.vertexColors,opacity:t.opacity,transparent:t.transparent,alphaTest:t.alphaTest,side:THREE.DoubleSide};this.conversionParams.forceMediumpForMaterials&&(n.precision="mediump");let i=null;if(this.shadingType===ShadingType.Phong){if(i=new THREE.MeshPhongMaterial(n),t.type===MaterialType.Phong){let e=ConvertColorToThreeColor(t.specular);IsEqual(t.shininess,0)&&e.setRGB(0,0,0),i.specular=e,i.shininess=100*t.shininess,this.LoadFaceTexture(i,t.specularMap,(e=>{i.specularMap=e}))}}else this.shadingType===ShadingType.Physical&&(i=new THREE.MeshStandardMaterial(n),t.type===MaterialType.Physical&&(i.metalness=t.metalness,i.roughness=t.roughness,this.LoadFaceTexture(i,t.metalnessMap,(e=>{i.metalness=1,i.roughness=1,i.metalnessMap=e,i.roughnessMap=e}))));let o=ConvertColorToThreeColor(t.emissive);return i.emissive=o,this.LoadFaceTexture(i,t.diffuseMap,(e=>{t.multiplyDiffuseMap||i.color.setRGB(1,1,1),i.map=e})),this.LoadFaceTexture(i,t.bumpMap,(e=>{i.bumpMap=e})),this.LoadFaceTexture(i,t.normalMap,(e=>{i.normalMap=e})),this.LoadFaceTexture(i,t.emissiveMap,(e=>{i.emissiveMap=e})),t.source!==MaterialSource.Model&&(i.userData.source=t.source,this.conversionOutput.defaultMaterials.push(i)),i}CreateThreeLineMaterial(e){let t=this.model.GetMaterial(e),r={color:ConvertColorToThreeColor(t.color),opacity:t.opacity};this.conversionParams.forceMediumpForMaterials&&(r.precision="mediump");let n=new THREE.LineBasicMaterial(r);return t.source!==MaterialSource.Model&&(n.userData.source=t.source,this.conversionOutput.defaultMaterials.push(n)),n}LoadFaceTexture(e,t,r){if(null===t||!t.IsValid())return;let n=new THREE.TextureLoader;this.stateHandler.OnTextureNeeded();let i=null;i=null!==t.mimeType?CreateObjectUrlWithMimeType(t.buffer,t.mimeType):CreateObjectUrl(t.buffer),this.conversionOutput.objectUrls.push(i),n.load(i,(n=>{!function(e,t){t.wrapS=THREE.RepeatWrapping,t.wrapT=THREE.RepeatWrapping,t.rotation=e.rotation,t.offset.x=e.offset.x,t.offset.y=e.offset.y,t.repeat.x=e.scale.x,t.repeat.y=e.scale.y}(t,n),e.needsUpdate=!0,r(n),this.stateHandler.OnTextureLoaded()}),null,(e=>{this.stateHandler.OnTextureLoaded()}))}}class ThreeMeshMaterialHandler{constructor(e,t,r){this.threeGeometry=e,this.geometryType=t,this.materialHandler=r,this.itemVertexCount=null,t===MaterialGeometryType.Face?this.itemVertexCount=3:t===MaterialGeometryType.Line&&(this.itemVertexCount=2),this.meshThreeMaterials=[],this.meshOriginalMaterials=[],this.groupStart=null,this.previousMaterialIndex=null}ProcessItem(e,t){if(this.previousMaterialIndex!==t){null!==this.groupStart&&this.AddGroup(this.groupStart,e-1),this.groupStart=e;let r=this.materialHandler.GetThreeMaterial(t,this.geometryType);this.meshThreeMaterials.push(r),this.meshOriginalMaterials.push(t),this.previousMaterialIndex=t}}Finalize(e){this.AddGroup(this.groupStart,e-1)}AddGroup(e,t){let r=this.meshThreeMaterials.length-1;this.threeGeometry.addGroup(e*this.itemVertexCount,(t-e+1)*this.itemVertexCount,r)}}function ConvertModelToThreeObject(e,t,r,n){function i(e,t,r){if(IsEmptyMesh(t.mesh))return;let n=function(e,t){let r=e.mesh,n=r.TriangleCount();if(0===n)return null;let i=[];for(let e=0;e<n;e++)i.push(e);i.sort(((e,t)=>{let n=r.GetTriangle(e),i=r.GetTriangle(t);return n.mat-i.mat}));let o=new THREE.BufferGeometry,s=new ThreeMeshMaterialHandler(o,MaterialGeometryType.Face,t),a=[],l=[],h=[],u=[],d=r.VertexColorCount()>0,c=r.TextureUVCount()>0,m=0;for(let e of i){let t=r.GetTriangle(e),n=r.GetVertex(t.v0),i=r.GetVertex(t.v1),o=r.GetVertex(t.v2);if(a.push(n.x,n.y,n.z,i.x,i.y,i.z,o.x,o.y,o.z),t.HasVertexColors()){let e=ConvertColorToThreeColor(r.GetVertexColor(t.c0)),n=ConvertColorToThreeColor(r.GetVertexColor(t.c1)),i=ConvertColorToThreeColor(r.GetVertexColor(t.c2));l.push(e.r,e.g,e.b,n.r,n.g,n.b,i.r,i.g,i.b)}else d&&l.push(0,0,0,0,0,0,0,0,0);let p=r.GetNormal(t.n0),f=r.GetNormal(t.n1),g=r.GetNormal(t.n2);if(h.push(p.x,p.y,p.z,f.x,f.y,f.z,g.x,g.y,g.z),t.HasTextureUVs()){let e=r.GetTextureUV(t.u0),n=r.GetTextureUV(t.u1),i=r.GetTextureUV(t.u2);u.push(e.x,e.y,n.x,n.y,i.x,i.y)}else c&&u.push(0,0,0,0,0,0);s.ProcessItem(m,t.mat),m+=1}s.Finalize(m),o.setAttribute("position",new THREE.Float32BufferAttribute(a,3)),0!==l.length&&o.setAttribute("color",new THREE.Float32BufferAttribute(l,3)),o.setAttribute("normal",new THREE.Float32BufferAttribute(h,3)),0!==u.length&&o.setAttribute("uv",new THREE.Float32BufferAttribute(u,2));let p=new THREE.Mesh(o,s.meshThreeMaterials);return p.name=r.GetName(),p.userData={originalMeshInstance:e,originalMaterials:s.meshOriginalMaterials,threeMaterials:null},p}(t,r);null!==n&&e.add(n);let i=function(e,t){let r=e.mesh,n=r.LineCount();if(0===n)return null;let i=[];for(let e=0;e<n;e++)i.push(e);i.sort(((e,t)=>{let n=r.GetLine(e),i=r.GetLine(t);return n.mat-i.mat}));let o=new THREE.BufferGeometry,s=new ThreeMeshMaterialHandler(o,MaterialGeometryType.Line,t),a=[],l=0;for(let e=0;e<i.length;e++){let t=r.GetLine(i[e]),n=t.GetVertices();for(let e=0;e<n.length;e++){let t=n[e],i=r.GetVertex(t);a.push(i.x,i.y,i.z),e>0&&e<n.length-1&&a.push(i.x,i.y,i.z)}s.ProcessItem(l,t.mat),l+=t.SegmentCount()}s.Finalize(l),o.setAttribute("position",new THREE.Float32BufferAttribute(a,3));let h=new THREE.LineSegments(o,s.meshThreeMaterials);return h.userData={originalMeshInstance:e,originalMaterials:s.meshOriginalMaterials,threeMaterials:null},h}(t,r);null!==i&&e.add(i)}let o=new ThreeConversionStateHandler(n),s=new ThreeMaterialHandler(e,o,t,r);!function(e,t,r,n){let o=new ThreeNodeTree(t,e).GetNodeItems();RunTasksBatch(o.length,100,{runTask:(e,t,n)=>{for(let n=e;n<=t;n++){let e=o[n];i(e.threeNode,e.meshInstance,r)}n()},onReady:()=>{n.OnModelLoaded(e)}})}(new THREE.Object3D,e,s,o)}class ThreeModelLoader{constructor(){this.importer=new Importer,this.inProgress=!1,this.defaultMaterials=null,this.objectUrls=null,this.hasHighpDriverIssue=HasHighpDriverIssue()}InProgress(){return this.inProgress}LoadModel(e,t,r){this.inProgress||(this.inProgress=!0,this.RevokeObjectUrls(),this.importer.ImportFiles(e,t,{onLoadStart:()=>{r.onLoadStart()},onFileListProgress:(e,t)=>{r.onFileListProgress(e,t)},onFileLoadProgress:(e,t)=>{r.onFileLoadProgress(e,t)},onImportStart:()=>{r.onImportStart()},onSelectMainFile:(e,t)=>{r.onSelectMainFile?r.onSelectMainFile(e,t):t(0)},onImportSuccess:e=>{r.onVisualizationStart();let t=new ModelToThreeConversionParams;t.forceMediumpForMaterials=this.hasHighpDriverIssue;let n=new ModelToThreeConversionOutput;ConvertModelToThreeObject(e.model,t,n,{onTextureLoaded:()=>{r.onTextureLoaded()},onModelLoaded:t=>{if(this.defaultMaterials=n.defaultMaterials,this.objectUrls=n.objectUrls,e.upVector===Direction.X){let e=(new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(0,0,1),Math.PI/2);t.quaternion.multiply(e)}else if(e.upVector===Direction.Z){let e=(new THREE.Quaternion).setFromAxisAngle(new THREE.Vector3(1,0,0),-Math.PI/2);t.quaternion.multiply(e)}r.onModelFinished(e,t),this.inProgress=!1}})},onImportError:e=>{r.onLoadError(e),this.inProgress=!1}}))}GetImporter(){return this.importer}GetDefaultMaterials(){return this.defaultMaterials}ReplaceDefaultMaterialsColor(e,t){if(null!==this.defaultMaterials)for(let r of this.defaultMaterials)r.vertexColors||(r.userData.source===MaterialSource.DefaultFace?r.color=ConvertColorToThreeColor(e):r.userData.source===MaterialSource.DefaultLine&&(r.color=ConvertColorToThreeColor(t)))}RevokeObjectUrls(){if(null!==this.objectUrls){for(let e of this.objectUrls)RevokeObjectUrl(e);this.objectUrls=null}}Destroy(){this.RevokeObjectUrls(),this.importer=null}}function GetIntegerFromStyle(e){return Math.round(parseFloat(e))}function GetDomElementExternalWidth(e){return GetIntegerFromStyle(e.paddingLeft)+GetIntegerFromStyle(e.paddingRight)+(GetIntegerFromStyle(e.borderLeftWidth)+GetIntegerFromStyle(e.borderRightWidth))+(GetIntegerFromStyle(e.marginLeft)+GetIntegerFromStyle(e.marginRight))}function GetDomElementExternalHeight(e){return GetIntegerFromStyle(e.paddingTop)+GetIntegerFromStyle(e.paddingBottom)+(GetIntegerFromStyle(e.borderTopWidth)+GetIntegerFromStyle(e.borderBottomWidth))+(GetIntegerFromStyle(e.marginTop)+GetIntegerFromStyle(e.marginBottom))}function GetDomElementInnerDimensions(e,t,r){let n=getComputedStyle(e);return{width:t-GetDomElementExternalWidth(n),height:r-GetDomElementExternalHeight(n)}}function GetDomElementClientCoordinates(e,t,r){if(e.getBoundingClientRect){let n=e.getBoundingClientRect();t-=n.left,r-=n.top}return window.pageXOffset&&window.pageYOffset&&(t+=window.pageXOffset,r+=window.pageYOffset),new Coord2D(t,r)}function CreateDomElement(e,t,r){let n=document.createElement(e);return t&&(n.className=t),r&&(n.innerHTML=r),n}function AddDomElement(e,t,r,n){let i=CreateDomElement(t,r,n);return e.appendChild(i),i}function AddDiv(e,t,r){return AddDomElement(e,"div",t,r)}function ClearDomElement(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function InsertDomElementBefore(e,t){t.parentNode.insertBefore(e,t)}function InsertDomElementAfter(e,t){t.parentNode.insertBefore(e,t.nextSibling)}function ShowDomElement(e,t){e.style.display=t?"block":"none"}function IsDomElementVisible(e){return null!==e.offsetParent}function SetDomElementWidth(e,t){e.style.width=t.toString()+"px"}function SetDomElementHeight(e,t){e.style.height=t.toString()+"px"}function GetDomElementOuterWidth(e){let t=getComputedStyle(e);return e.offsetWidth+GetIntegerFromStyle(t.marginLeft)+GetIntegerFromStyle(t.marginRight)}function GetDomElementOuterHeight(e){let t=getComputedStyle(e);return e.offsetHeight+GetIntegerFromStyle(t.marginTop)+GetIntegerFromStyle(t.marginBottom)}function SetDomElementOuterWidth(e,t){SetDomElementWidth(e,t-GetDomElementExternalWidth(getComputedStyle(e)))}function SetDomElementOuterHeight(e,t){SetDomElementHeight(e,t-GetDomElementExternalHeight(getComputedStyle(e)))}function CreateDiv(e,t){return CreateDomElement("div",e,t)}class MouseInteraction{constructor(){this.prev=new Coord2D(0,0),this.curr=new Coord2D(0,0),this.diff=new Coord2D(0,0),this.buttons=[]}Down(e,t){this.buttons.push(t.which),this.curr=this.GetPositionFromEvent(e,t),this.prev=this.curr.Clone()}Move(e,t){this.curr=this.GetPositionFromEvent(e,t),this.diff=SubCoord2D(this.curr,this.prev),this.prev=this.curr.Clone()}Up(e,t){let r=this.buttons.indexOf(t.which);-1!==r&&this.buttons.splice(r,1),this.curr=this.GetPositionFromEvent(e,t)}Leave(e,t){this.buttons=[],this.curr=this.GetPositionFromEvent(e,t)}IsButtonDown(){return this.buttons.length>0}GetButton(){let e=this.buttons.length;return 0===e?0:this.buttons[e-1]}GetPosition(){return this.curr}GetMoveDiff(){return this.diff}GetPositionFromEvent(e,t){return GetDomElementClientCoordinates(e,t.clientX,t.clientY)}}class TouchInteraction{constructor(){this.prevPos=new Coord2D(0,0),this.currPos=new Coord2D(0,0),this.diffPos=new Coord2D(0,0),this.prevDist=0,this.currDist=0,this.diffDist=0,this.fingers=0}Start(e,t){0!==t.touches.length&&(this.fingers=t.touches.length,this.currPos=this.GetPositionFromEvent(e,t),this.prevPos=this.currPos.Clone(),this.currDist=this.GetTouchDistanceFromEvent(e,t),this.prevDist=this.currDist)}Move(e,t){0!==t.touches.length&&(this.currPos=this.GetPositionFromEvent(e,t),this.diffPos=SubCoord2D(this.currPos,this.prevPos),this.prevPos=this.currPos.Clone(),this.currDist=this.GetTouchDistanceFromEvent(e,t),this.diffDist=this.currDist-this.prevDist,this.prevDist=this.currDist)}End(e,t){0!==t.touches.length&&(this.fingers=0,this.currPos=this.GetPositionFromEvent(e,t),this.currDist=this.GetTouchDistanceFromEvent(e,t))}IsFingerDown(){return 0!==this.fingers}GetFingerCount(){return this.fingers}GetPosition(){return this.currPos}GetMoveDiff(){return this.diffPos}GetDistanceDiff(){return this.diffDist}GetPositionFromEvent(e,t){let r=null;if(0!==t.touches.length){let n=t.touches[0];r=GetDomElementClientCoordinates(e,n.pageX,n.pageY)}return r}GetTouchDistanceFromEvent(e,t){if(2!==t.touches.length)return 0;let r=t.touches[0],n=t.touches[1];return CoordDistance2D(GetDomElementClientCoordinates(e,r.pageX,r.pageY),GetDomElementClientCoordinates(e,n.pageX,n.pageY))}}class ClickDetector{constructor(){this.isClick=!1,this.startPosition=null}Start(e){this.isClick=!0,this.startPosition=e}Move(e){if(this.isClick)if(null!==this.startPosition){const t=3;CoordDistance2D(this.startPosition,e)>t&&this.Cancel()}else this.Cancel()}End(){this.startPosition=null}Cancel(){this.isClick=!1,this.startPosition=null}IsClick(){return this.isClick}}const NavigationType={None:0,Orbit:1,Pan:2,Zoom:3};class Navigation{constructor(e,t,r){this.canvas=e,this.camera=t,this.callbacks=r,this.navigationMode=NavigationMode.FixedUpVector,this.mouse=new MouseInteraction,this.touch=new TouchInteraction,this.clickDetector=new ClickDetector,this.onMouseClick=null,this.onMouseMove=null,this.onContext=null,this.canvas.addEventListener&&(this.canvas.addEventListener("mousedown",this.OnMouseDown.bind(this)),this.canvas.addEventListener("wheel",this.OnMouseWheel.bind(this)),this.canvas.addEventListener("touchstart",this.OnTouchStart.bind(this)),this.canvas.addEventListener("touchmove",this.OnTouchMove.bind(this)),this.canvas.addEventListener("touchcancel",this.OnTouchEnd.bind(this)),this.canvas.addEventListener("touchend",this.OnTouchEnd.bind(this)),this.canvas.addEventListener("contextmenu",this.OnContextMenu.bind(this))),document.addEventListener&&(document.addEventListener("mousemove",this.OnMouseMove.bind(this)),document.addEventListener("mouseup",this.OnMouseUp.bind(this)),document.addEventListener("mouseleave",this.OnMouseLeave.bind(this)))}SetMouseClickHandler(e){this.onMouseClick=e}SetMouseMoveHandler(e){this.onMouseMove=e}SetContextMenuHandler(e){this.onContext=e}GetNavigationMode(){return this.navigationMode}SetNavigationMode(e){this.navigationMode=e}GetCamera(){return this.camera}SetCamera(e){this.camera=e}MoveCamera(e,t){function r(e,t,n,i){e.camera.eye=t.eye[i],e.camera.center=t.center[i],e.camera.up=t.up[i],e.Update(),i<n-1&&requestAnimationFrame((()=>{r(e,t,n,i+1)}))}if(null!==e){if(0===t||CameraIsEqual3D(this.camera,e))this.camera=e;else{let n=ParabolicTweenFunction,i={eye:TweenCoord3D(this.camera.eye,e.eye,t,n),center:TweenCoord3D(this.camera.center,e.center,t,n),up:TweenCoord3D(this.camera.up,e.up,t,n)};requestAnimationFrame((()=>{r(this,i,t,0)}))}this.Update()}}GetFitToSphereCamera(e,t){if(IsZero(t))return null;let r=this.camera.Clone(),n=SubCoord3D(r.center,e);r.eye=SubCoord3D(r.eye,n),r.center=e.Clone();let i=SubCoord3D(r.eye,r.center).Normalize(),o=this.camera.fov/2;this.canvas.width<this.canvas.height&&(o=o*this.canvas.width/this.canvas.height);let s=t/Math.sin(o*DegRad);return r.eye=r.center.Clone().Offset(i,s),r}OnMouseDown(e){e.preventDefault(),this.mouse.Down(this.canvas,e),this.clickDetector.Start(this.mouse.GetPosition())}OnMouseMove(e){if(this.mouse.Move(this.canvas,e),this.clickDetector.Move(this.mouse.GetPosition()),this.onMouseMove){let t=GetDomElementClientCoordinates(this.canvas,e.clientX,e.clientY);this.onMouseMove(t)}if(!this.mouse.IsButtonDown())return;let t=this.mouse.GetMoveDiff(),r=this.mouse.GetButton(),n=NavigationType.None;if(1===r?n=e.ctrlKey?NavigationType.Zoom:e.shiftKey?NavigationType.Pan:NavigationType.Orbit:2!==r&&3!==r||(n=NavigationType.Pan),n===NavigationType.Orbit){let e=.5;this.Orbit(t.x*e,t.y*e)}else if(n===NavigationType.Pan){let e=.001*CoordDistance3D(this.camera.eye,this.camera.center);this.Pan(t.x*e,t.y*e)}else if(n===NavigationType.Zoom){let e=.005;this.Zoom(-t.y*e)}this.Update()}OnMouseUp(e){if(this.mouse.Up(this.canvas,e),this.clickDetector.End(),this.clickDetector.IsClick()){let t=this.mouse.GetPosition();this.Click(e.which,t)}}OnMouseLeave(e){this.mouse.Leave(this.canvas,e),this.clickDetector.Cancel()}OnTouchStart(e){e.preventDefault(),this.touch.Start(this.canvas,e),this.clickDetector.Start(this.touch.GetPosition())}OnTouchMove(e){if(e.preventDefault(),this.touch.Move(this.canvas,e),this.clickDetector.Move(this.touch.GetPosition()),!this.touch.IsFingerDown())return;let t=this.touch.GetMoveDiff(),r=this.touch.GetDistanceDiff(),n=this.touch.GetFingerCount(),i=NavigationType.None;if(1===n?i=NavigationType.Orbit:2===n&&(i=NavigationType.Pan),i===NavigationType.Orbit){let e=.5;this.Orbit(t.x*e,t.y*e)}else if(i===NavigationType.Pan){let e=.005;this.Zoom(r*e);let n=.001*CoordDistance3D(this.camera.eye,this.camera.center);this.Pan(t.x*n,t.y*n)}this.Update()}OnTouchEnd(e){if(e.preventDefault(),this.touch.End(this.canvas,e),this.clickDetector.End(),this.clickDetector.IsClick()){let e=this.touch.GetPosition();1===this.touch.GetFingerCount()&&this.Click(1,e)}}OnMouseWheel(e){let t=e||window.event;t.preventDefault();let r=.1;-t.deltaY/40<0&&(r*=-1),this.Zoom(r),this.Update()}OnContextMenu(e){e.preventDefault(),this.clickDetector.IsClick()&&(this.Context(e.clientX,e.clientY),this.clickDetector.Cancel())}Orbit(e,t){let r=e*DegRad,n=t*DegRad,i=SubCoord3D(this.camera.center,this.camera.eye).Normalize(),o=CrossVector3D(i,this.camera.up).Normalize();if(this.navigationMode===NavigationMode.FixedUpVector){let e=VectorAngle3D(i,this.camera.up)+n;IsGreater(e,0)&&IsLower(e,Math.PI)&&this.camera.eye.Rotate(o,-n,this.camera.center),this.camera.eye.Rotate(this.camera.up,-r,this.camera.center)}else if(this.navigationMode===NavigationMode.FreeOrbit){let e=CrossVector3D(o,i).Normalize();this.camera.eye.Rotate(o,-n,this.camera.center),this.camera.eye.Rotate(e,-r,this.camera.center),this.camera.up=e}}Pan(e,t){let r=SubCoord3D(this.camera.center,this.camera.eye).Normalize(),n=CrossVector3D(r,this.camera.up).Normalize(),i=CrossVector3D(n,r).Normalize();this.camera.eye.Offset(n,-e),this.camera.center.Offset(n,-e),this.camera.eye.Offset(i,t),this.camera.center.Offset(i,t)}Zoom(e){let t=SubCoord3D(this.camera.center,this.camera.eye),r=t.Length()*e;this.camera.eye.Offset(t,r)}Update(){this.callbacks.onUpdate()}Click(e,t){this.onMouseClick&&this.onMouseClick(e,t)}Context(e,t){if(this.onContext){let r={x:e,y:t},n=GetDomElementClientCoordinates(this.canvas,e,t);this.onContext(r,n)}}}class EnvironmentSettings{constructor(e,t){this.textureNames=e,this.backgroundIsEnvMap=t}Clone(){let e=null;if(null!==this.textureNames){e=[];for(let t of this.textureNames)e.push(t)}return new EnvironmentSettings(e,this.backgroundIsEnvMap)}}class ShadingModel{constructor(e){this.scene=e,this.type=ShadingType.Phong,this.projectionMode=ProjectionMode.Perspective,this.ambientLight=new THREE.AmbientLight(8947848,1*Math.PI),this.directionalLight=new THREE.DirectionalLight(8947848,1*Math.PI),this.environmentSettings=new EnvironmentSettings(null,!1),this.environment=null,this.scene.add(this.ambientLight),this.scene.add(this.directionalLight)}SetShadingType(e){this.type=e,this.UpdateShading()}SetProjectionMode(e){this.projectionMode=e,this.UpdateShading()}UpdateShading(){this.type===ShadingType.Phong?(this.ambientLight.color.set(8947848),this.directionalLight.color.set(8947848),this.scene.environment=null):this.type===ShadingType.Physical&&(this.ambientLight.color.set(0),this.directionalLight.color.set(5592405),this.scene.environment=this.environment),this.environmentSettings.backgroundIsEnvMap&&this.projectionMode===ProjectionMode.Perspective?this.scene.background=this.environment:this.scene.background=null}SetEnvironmentMapSettings(e,t){let r=new THREE.CubeTextureLoader;this.environment=r.load(e.textureNames,(e=>{e.colorSpace=THREE.LinearSRGBColorSpace,t()})),this.environmentSettings=e}UpdateByCamera(e){const t=SubCoord3D(e.eye,e.center);this.directionalLight.position.set(t.x,t.y,t.z)}}function GetDefaultCamera(e){return e===Direction.X?new Camera(new Coord3D(2,-3,1.5),new Coord3D(0,0,0),new Coord3D(1,0,0),45):e===Direction.Y?new Camera(new Coord3D(-1.5,2,3),new Coord3D(0,0,0),new Coord3D(0,1,0),45):e===Direction.Z?new Camera(new Coord3D(-1.5,-3,2),new Coord3D(0,0,0),new Coord3D(0,0,1),45):null}function TraverseThreeObject(e,t){if(!t(e))return!1;for(let r of e.children)if(!TraverseThreeObject(r,t))return!1;return!0}function GetShadingTypeOfObject(e){let t=null;return TraverseThreeObject(e,(e=>{if(e.isMesh)for(const r of e.material)return"MeshPhongMaterial"===r.type?t=ShadingType.Phong:"MeshStandardMaterial"===r.type&&(t=ShadingType.Physical),!1;return!0})),t}class CameraValidator{constructor(){this.eyeCenterDistance=0,this.forceUpdate=!0}ForceUpdate(){this.forceUpdate=!0}ValidatePerspective(){return!this.forceUpdate||(this.forceUpdate=!1,!1)}ValidateOrthographic(e){return!(this.forceUpdate||!IsEqual(this.eyeCenterDistance,e))||(this.eyeCenterDistance=e,this.forceUpdate=!1,!1)}}class UpVector{constructor(){this.direction=Direction.Y,this.isFixed=!0,this.isFlipped=!1}SetDirection(e,t){this.direction=e,this.isFlipped=!1;let r=GetDefaultCamera(this.direction),n=SubCoord3D(r.eye,r.center),i=CoordDistance3D(t.center,t.eye),o=t.center.Clone().Offset(n,i),s=t.Clone();return this.direction===Direction.X?(s.up=new Coord3D(1,0,0),s.eye=o):this.direction===Direction.Y?(s.up=new Coord3D(0,1,0),s.eye=o):this.direction===Direction.Z&&(s.up=new Coord3D(0,0,1),s.eye=o),s}SetFixed(e,t){return this.isFixed=e,this.isFixed?this.SetDirection(this.direction,t):null}Flip(e){this.isFlipped=!this.isFlipped;let t=e.Clone();return t.up.MultiplyScalar(-1),t}}class Viewer{constructor(){THREE.ColorManagement.enabled=!1,this.canvas=null,this.renderer=null,this.scene=null,this.mainModel=null,this.extraModel=null,this.camera=null,this.projectionMode=null,this.cameraValidator=null,this.shadingModel=null,this.navigation=null,this.upVector=null,this.settings={animationSteps:40}}Init(e){this.canvas=e,this.canvas.id="viewer";let t={canvas:this.canvas,antialias:!0};this.renderer=new THREE.WebGLRenderer(t),this.renderer.outputColorSpace=THREE.LinearSRGBColorSpace,window.devicePixelRatio&&this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setClearColor("#ffffff",1),this.renderer.setSize(this.canvas.width,this.canvas.height),this.scene=new THREE.Scene,this.mainModel=new ViewerMainModel(this.scene),this.extraModel=new ViewerModel(this.scene),this.InitNavigation(),this.InitShading(),this.Render()}SetMouseClickHandler(e){this.navigation.SetMouseClickHandler(e)}SetMouseMoveHandler(e){this.navigation.SetMouseMoveHandler(e)}SetContextMenuHandler(e){this.navigation.SetContextMenuHandler(e)}SetEdgeSettings(e){let t=e.Clone();this.mainModel.SetEdgeSettings(t),this.Render()}SetEnvironmentMapSettings(e){let t=e.Clone();this.shadingModel.SetEnvironmentMapSettings(t,(()=>{this.Render()})),this.shadingModel.UpdateShading(),this.Render()}SetBackgroundColor(e){let t=new THREE.Color(ColorComponentToFloat(e.r),ColorComponentToFloat(e.g),ColorComponentToFloat(e.b)),r=ColorComponentToFloat(e.a);this.renderer.setClearColor(t,r),this.Render()}GetCanvas(){return this.canvas}GetCamera(){return this.navigation.GetCamera()}GetProjectionMode(){return this.projectionMode}SetCamera(e){this.navigation.SetCamera(e),this.cameraValidator.ForceUpdate(),this.Render()}SetProjectionMode(e){this.projectionMode!==e&&(this.scene.remove(this.camera),e===ProjectionMode.Perspective?this.camera=new THREE.PerspectiveCamera(45,1,.1,1e3):e===ProjectionMode.Orthographic&&(this.camera=new THREE.OrthographicCamera(-1,1,1,-1,.1,1e3)),this.scene.add(this.camera),this.projectionMode=e,this.shadingModel.SetProjectionMode(e),this.cameraValidator.ForceUpdate(),this.AdjustClippingPlanes(),this.Render())}Resize(e,t){let r=GetDomElementInnerDimensions(this.canvas,e,t);this.ResizeRenderer(r.width,r.height)}ResizeRenderer(e,t){window.devicePixelRatio&&this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(e,t),this.cameraValidator.ForceUpdate(),this.Render()}FitSphereToWindow(e,t){if(null===e)return;let r=new Coord3D(e.center.x,e.center.y,e.center.z),n=e.radius,i=this.navigation.GetFitToSphereCamera(r,n);this.navigation.MoveCamera(i,t?this.settings.animationSteps:0)}AdjustClippingPlanes(){let e=this.GetBoundingSphere((e=>!0));this.AdjustClippingPlanesToSphere(e)}AdjustClippingPlanesToSphere(e){null!==e&&(e.radius<10?(this.camera.near=.01,this.camera.far=100):e.radius<100?(this.camera.near=.1,this.camera.far=1e3):e.radius<1e3?(this.camera.near=10,this.camera.far=1e4):(this.camera.near=100,this.camera.far=1e6),this.cameraValidator.ForceUpdate(),this.Render())}GetNavigationMode(){return this.navigation.GetNavigationMode()}SetNavigationMode(e){let t=this.navigation.GetCamera(),r=this.upVector.SetFixed(e===NavigationMode.FixedUpVector,t);this.navigation.SetNavigationMode(e),null!==r&&this.navigation.MoveCamera(r,this.settings.animationSteps),this.Render()}SetUpVector(e,t){let r=this.navigation.GetCamera(),n=this.upVector.SetDirection(e,r),i=t?this.settings.animationSteps:0;this.navigation.MoveCamera(n,i),this.Render()}FlipUpVector(){let e=this.navigation.GetCamera(),t=this.upVector.Flip(e);this.navigation.MoveCamera(t,0),this.Render()}Render(){let e=this.navigation.GetCamera();if(this.camera.position.set(e.eye.x,e.eye.y,e.eye.z),this.camera.up.set(e.up.x,e.up.y,e.up.z),this.camera.lookAt(new THREE.Vector3(e.center.x,e.center.y,e.center.z)),this.projectionMode===ProjectionMode.Perspective)this.cameraValidator.ValidatePerspective()||(this.camera.aspect=this.canvas.width/this.canvas.height,this.camera.fov=e.fov,this.camera.updateProjectionMatrix());else if(this.projectionMode===ProjectionMode.Orthographic){let t=CoordDistance3D(e.eye,e.center);if(!this.cameraValidator.ValidateOrthographic(t)){let t=this.canvas.width/this.canvas.height,r=CoordDistance3D(e.eye,e.center)*Math.tan(.5*e.fov*DegRad);this.camera.left=-r*t,this.camera.right=r*t,this.camera.top=r,this.camera.bottom=-r,this.camera.updateProjectionMatrix()}}this.shadingModel.UpdateByCamera(e),this.renderer.render(this.scene,this.camera)}SetMainObject(e){const t=GetShadingTypeOfObject(e);this.mainModel.SetMainObject(e),this.shadingModel.SetShadingType(t),this.Render()}AddExtraObject(e){this.extraModel.AddObject(e),this.Render()}Clear(){this.mainModel.Clear(),this.extraModel.Clear(),this.Render()}ClearExtra(){this.extraModel.Clear(),this.Render()}SetMeshesVisibility(e){this.mainModel.EnumerateMeshesAndLines((t=>{let r=e(t.userData);t.visible!==r&&(t.visible=r)})),this.mainModel.EnumerateEdges((t=>{let r=e(t.userData);t.visible!==r&&(t.visible=r)})),this.Render()}SetMeshesHighlight(e,t){let r=this.mainModel.HasLinesOrEdges();this.mainModel.EnumerateMeshesAndLines((n=>{t(n.userData)?null===n.userData.threeMaterials&&(n.userData.threeMaterials=n.material,n.material=CreateHighlightMaterials(n.userData.threeMaterials,e,r)):null!==n.userData.threeMaterials&&(n.material=n.userData.threeMaterials,n.userData.threeMaterials=null)})),this.Render()}GetMeshUserDataUnderMouse(e,t){let r=this.GetMeshIntersectionUnderMouse(e,t);return null===r?null:r.object.userData}GetMeshIntersectionUnderMouse(e,t){let r=this.GetCanvasSize(),n=this.mainModel.GetMeshIntersectionUnderMouse(e,t,this.camera,r.width,r.height);return null===n?null:n}GetBoundingBox(e){return this.mainModel.GetBoundingBox(e)}GetBoundingSphere(e){return this.mainModel.GetBoundingSphere(e)}EnumerateMeshesAndLinesUserData(e){this.mainModel.EnumerateMeshesAndLines((t=>{e(t.userData)}))}InitNavigation(){let e=GetDefaultCamera(Direction.Y);this.camera=new THREE.PerspectiveCamera(45,1,.1,1e3),this.projectionMode=ProjectionMode.Perspective,this.cameraValidator=new CameraValidator,this.scene.add(this.camera);let t=this.renderer.domElement;this.navigation=new Navigation(t,e,{onUpdate:()=>{this.Render()}}),this.upVector=new UpVector}InitShading(){this.shadingModel=new ShadingModel(this.scene)}GetShadingType(){return this.shadingModel.type}GetImageSize(){let e=new THREE.Vector2;return this.renderer.getSize(e),{width:parseInt(e.x,10),height:parseInt(e.y,10)}}GetCanvasSize(){let e=this.canvas.width,t=this.canvas.height;return window.devicePixelRatio&&(e/=window.devicePixelRatio,t/=window.devicePixelRatio),{width:e,height:t}}GetImageAsDataUrl(e,t,r){let n=this.GetImageSize(),i=e,o=t;window.devicePixelRatio&&(i/=window.devicePixelRatio,o/=window.devicePixelRatio);let s=this.renderer.getClearAlpha();r&&this.renderer.setClearAlpha(0),this.ResizeRenderer(i,o),this.Render();let a=this.renderer.domElement.toDataURL();return this.ResizeRenderer(n.width,n.height),this.renderer.setClearAlpha(s),a}Destroy(){this.Clear(),this.renderer.dispose()}}class EmbeddedViewer{constructor(e,t){this.parentElement=e,this.parameters={},IsDefined(t)&&(this.parameters=t),this.canvas=document.createElement("canvas"),this.parentElement.appendChild(this.canvas),this.viewer=new Viewer,this.viewer.Init(this.canvas);let r=this.parentElement.clientWidth,n=this.parentElement.clientHeight;this.viewer.Resize(r,n),this.parameters.projectionMode&&this.viewer.SetProjectionMode(this.parameters.projectionMode),this.parameters.backgroundColor&&this.viewer.SetBackgroundColor(this.parameters.backgroundColor),this.parameters.edgeSettings&&this.viewer.SetEdgeSettings(this.parameters.edgeSettings),this.parameters.environmentSettings&&this.viewer.SetEnvironmentMapSettings(this.parameters.environmentSettings),this.model=null,this.modelLoader=new ThreeModelLoader,window.addEventListener("resize",(()=>{this.Resize()}))}LoadModelFromUrlList(e){TransformFileHostUrls(e);let t=InputFilesFromUrls(e);this.LoadModelFromInputFiles(t)}LoadModelFromFileList(e){let t=InputFilesFromFileObjects(e);this.LoadModelFromInputFiles(t)}LoadModelFromInputFiles(e){if(null===e||0===e.length)return;this.viewer.Clear();let t=new ImportSettings;this.parameters.defaultColor&&(t.defaultColor=this.parameters.defaultColor),this.parameters.defaultLineColor&&(t.defaultLineColor=this.parameters.defaultLineColor),this.model=null;let r=null;this.modelLoader.LoadModel(e,t,{onLoadStart:()=>{this.canvas.style.display="none",r=document.createElement("div"),r.innerHTML="Loading model...",this.parentElement.appendChild(r)},onFileListProgress:(e,t)=>{},onFileLoadProgress:(e,t)=>{},onImportStart:()=>{r.innerHTML="Importing model..."},onVisualizationStart:()=>{r.innerHTML="Visualizing model..."},onModelFinished:(e,t)=>{this.parentElement.removeChild(r),this.canvas.style.display="inherit",this.viewer.SetMainObject(t);let n=this.viewer.GetBoundingSphere((e=>!0));this.viewer.AdjustClippingPlanesToSphere(n),this.parameters.camera?this.viewer.SetCamera(this.parameters.camera):(this.viewer.SetUpVector(Direction.Y,!1),this.viewer.FitSphereToWindow(n,!1)),this.model=e.model,this.parameters.onModelLoaded&&this.parameters.onModelLoaded()},onTextureLoaded:()=>{this.viewer.Render()},onLoadError:e=>{let t="Unknown error.";e.code===ImportErrorCode.NoImportableFile?t="No importable file found.":e.code===ImportErrorCode.FailedToLoadFile?t="Failed to load file for import.":e.code===ImportErrorCode.ImportFailed&&(t="Failed to import model."),null!==e.message&&(t+=" ("+e.message+")"),r.innerHTML=t}})}GetViewer(){return this.viewer}GetModel(){return this.model}Resize(){let e=this.parentElement.clientWidth,t=this.parentElement.clientHeight;this.viewer.Resize(e,t)}Destroy(){this.modelLoader.Destroy(),this.viewer.Destroy(),this.model=null}}function Init3DViewerFromUrlList(e,t,r){let n=new EmbeddedViewer(e,r);return n.LoadModelFromUrlList(t),n}function Init3DViewerFromFileList(e,t,r){let n=new EmbeddedViewer(e,r);return n.LoadModelFromFileList(t),n}function Init3DViewerElements(e){function t(e){let t=null,r=e.getAttribute("camera");r&&(t=ParameterConverter.StringToCamera(r));let n=null,i=e.getAttribute("projectionmode");i&&(n=ParameterConverter.StringToProjectionMode(i));let o=null,s=e.getAttribute("backgroundcolor");s&&(o=ParameterConverter.StringToRGBAColor(s));let a=null,l=e.getAttribute("defaultcolor");l&&(a=ParameterConverter.StringToRGBColor(l));let h=null,u=e.getAttribute("defaultlinecolor");u&&(h=ParameterConverter.StringToRGBColor(u));let d=null,c=e.getAttribute("edgesettings");c&&(d=ParameterConverter.StringToEdgeSettings(c));let m=null,p=e.getAttribute("environmentmap");if(p){let t=p.split(",");if(6===t.length){let r=!1,n=e.getAttribute("environmentmapbg");n&&"true"===n&&(r=!0),m=new EnvironmentSettings(t,r)}}let f=null,g=e.getAttribute("model");return g&&(f=ParameterConverter.StringToModelUrls(g)),Init3DViewerFromUrlList(e,f,{camera:t,projectionMode:n,backgroundColor:o,defaultLineColor:h,defaultColor:a,edgeSettings:d,environmentSettings:m})}let r=[],n=document.getElementsByClassName("online_3d_viewer");for(let e=0;e<n.length;e++){let i=t(n[e]);r.push(i)}return r}export{AddCoord2D,AddCoord3D,AddDiv,AddDomElement,ArrayBufferToAsciiString,ArrayBufferToUtf8String,ArrayToCoord3D,ArrayToQuaternion,ArrayToRGBColor,AsciiStringToArrayBuffer,Base64DataURIToArrayBuffer,BezierTweenFunction,BigEps,BinaryReader,BinaryWriter,BoundingBoxCalculator3D,Box3D,CalculateSurfaceArea,CalculateTriangleNormal,CalculateVolume,Camera,CameraIsEqual3D,CameraValidator,CheckModel,ClearDomElement,ClickDetector,ColorComponentFromFloat,ColorComponentToFloat,ColorToMaterialConverter,ConvertColorToThreeColor,ConvertMeshToMeshBuffer,ConvertModelToThreeObject,ConvertThreeColorToColor,ConvertThreeGeometryToMesh,Coord2D,Coord3D,Coord4D,CoordDistance2D,CoordDistance3D,CoordIsEqual2D,CoordIsEqual3D,CopyObjectAttributes,CreateDiv,CreateDomElement,CreateHighlightMaterial,CreateHighlightMaterials,CreateModelUrlParameters,CreateObjectUrl,CreateObjectUrlWithMimeType,CreateUrlBuilder,CreateUrlParser,CrossVector3D,DegRad,Direction,DisposeThreeObjects,DotVector2D,DotVector3D,EdgeSettings,EmbeddedViewer,EnvironmentSettings,Eps,EscapeHtmlChars,EventNotifier,ExportedFile,Exporter,Exporter3dm,ExporterBase,ExporterBim,ExporterGltf,ExporterModel,ExporterObj,ExporterOff,ExporterPly,ExporterSettings,ExporterStl,FaceMaterial,FileFormat,FileSource,FinalizeModel,FlipMeshTrianglesOrientation,GenerateCone,GenerateCuboid,GenerateCylinder,GeneratePlatonicSolid,GenerateSphere,Generator,GeneratorHelper,GeneratorParams,GetBoundingBox,GetDefaultCamera,GetDefaultMaterials,GetDomElementClientCoordinates,GetDomElementExternalHeight,GetDomElementExternalWidth,GetDomElementInnerDimensions,GetDomElementOuterHeight,GetDomElementOuterWidth,GetExternalLibPath,GetFileExtension,GetFileExtensionFromMimeType,GetFileName,GetIntegerFromStyle,GetLineSegmentsProjectedDistance,GetShadingType,GetShadingTypeOfObject,GetTetrahedronSignedVolume,GetTopology,GetTriangleArea,HasHighpDriverIssue,HexStringToRGBAColor,HexStringToRGBColor,ImportError,ImportErrorCode,ImportResult,ImportSettings,Importer,Importer3dm,Importer3ds,ImporterBase,ImporterBim,ImporterFcstd,ImporterFile,ImporterFileAccessor,ImporterFileList,ImporterGltf,ImporterIfc,ImporterObj,ImporterOcct,ImporterOff,ImporterPly,ImporterStl,ImporterThree3mf,ImporterThreeAmf,ImporterThreeBase,ImporterThreeBvh,ImporterThreeDae,ImporterThreeDraco,ImporterThreeFbx,ImporterThreeRhino3dm,ImporterThreeSvg,ImporterThreeWrl,Init3DViewerElements,Init3DViewerFromFileList,Init3DViewerFromUrlList,InputFile,InputFilesFromFileObjects,InputFilesFromUrls,InsertDomElementAfter,InsertDomElementBefore,IntegerToHexString,IntersectionMode,IsDefined,IsDomElementVisible,IsEmptyMesh,IsEqual,IsEqualEps,IsGreater,IsGreaterOrEqual,IsLower,IsLowerOrEqual,IsModelEmpty,IsNegative,IsObjectEmpty,IsPositive,IsPowerOfTwo,IsTwoManifold,IsUrl,IsZero,Line,LinearToSRGB,LinearTweenFunction,LoadExternalLibrary,MaterialBase,MaterialGeometryType,MaterialSource,MaterialType,Matrix,MatrixIsEqual,Mesh,MeshBuffer,MeshInstance,MeshInstanceId,MeshPrimitiveBuffer,Model,ModelObject3D,ModelToThreeConversionOutput,ModelToThreeConversionParams,MouseInteraction,NameFromLine,Navigation,NavigationMode,NavigationType,NextPowerOfTwo,Node,Object3D,Octree,OctreeNode,ParabolicTweenFunction,ParameterConverter,ParameterListBuilder,ParameterListParser,ParametersFromLine,PhongMaterial,PhysicalMaterial,ProjectPointToSegment2D,ProjectionMode,Property,PropertyGroup,PropertyToString,PropertyType,Quaternion,QuaternionFromAxisAngle,QuaternionFromXYZ,QuaternionIsEqual,RGBAColor,RGBAColorToHexString,RGBColor,RGBColorFromFloatComponents,RGBColorIsEqual,RGBColorToHexString,RadDeg,ReadFile,ReadLines,ReplaceDefaultMaterialsColor,RequestUrl,RevokeObjectUrl,RunTaskAsync,RunTasks,RunTasksBatch,SRGBToLinear,Segment2D,SegmentPointDistance2D,SetDomElementHeight,SetDomElementOuterHeight,SetDomElementOuterWidth,SetDomElementWidth,SetExternalLibLocation,SetThreeMeshPolygonOffset,ShadingModel,ShadingType,ShowDomElement,SubCoord2D,SubCoord3D,TaskRunner,TextWriter,TextureIsEqual,TextureMap,TextureMapIsEqual,ThreeColorConverter,ThreeConversionStateHandler,ThreeLinearToSRGBColorConverter,ThreeMaterialHandler,ThreeMeshMaterialHandler,ThreeModelLoader,ThreeNodeTree,ThreeSRGBToLinearColorConverter,Topology,TopologyEdge,TopologyTriangle,TopologyTriangleEdge,TopologyVertex,TouchInteraction,TransformFileHostUrls,TransformMesh,Transformation,TransformationIsEqual,TraverseThreeObject,Triangle,TweenCoord3D,Unit,UpVector,UpdateMaterialTransparency,Utf8StringToArrayBuffer,ValueOrDefault,VectorAngle3D,VectorLength3D,Viewer,ViewerMainModel,ViewerModel,WaitWhile};
//# sourceMappingURL=/sm/6c50290aaeab08f51926233837d7777e98282b8d88264ba099f8770e45e042fc.map