@splinetool/loader 0.9.34 → 0.9.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../node_modules/base64-js/index.js", "../../../node_modules/svd-js/build-umd/svd-js.min.js", "../src/SplineLoader.ts", "../../common/src/collection.ts", "../../../node_modules/lodash-es/_freeGlobal.js", "../../../node_modules/lodash-es/_root.js", "../../../node_modules/lodash-es/_Symbol.js", "../../../node_modules/lodash-es/_getRawTag.js", "../../../node_modules/lodash-es/_objectToString.js", "../../../node_modules/lodash-es/_baseGetTag.js", "../../../node_modules/lodash-es/isObjectLike.js", "../../../node_modules/lodash-es/isSymbol.js", "../../../node_modules/lodash-es/_arrayMap.js", "../../../node_modules/lodash-es/isArray.js", "../../../node_modules/lodash-es/_baseToString.js", "../../../node_modules/lodash-es/isObject.js", "../../../node_modules/lodash-es/identity.js", "../../../node_modules/lodash-es/isFunction.js", "../../../node_modules/lodash-es/_coreJsData.js", "../../../node_modules/lodash-es/_isMasked.js", "../../../node_modules/lodash-es/_toSource.js", "../../../node_modules/lodash-es/_baseIsNative.js", "../../../node_modules/lodash-es/_getValue.js", "../../../node_modules/lodash-es/_getNative.js", "../../../node_modules/lodash-es/_WeakMap.js", "../../../node_modules/lodash-es/_baseCreate.js", "../../../node_modules/lodash-es/_apply.js", "../../../node_modules/lodash-es/_copyArray.js", "../../../node_modules/lodash-es/_shortOut.js", "../../../node_modules/lodash-es/constant.js", "../../../node_modules/lodash-es/_defineProperty.js", "../../../node_modules/lodash-es/_baseSetToString.js", "../../../node_modules/lodash-es/_setToString.js", "../../../node_modules/lodash-es/_arrayEach.js", "../../../node_modules/lodash-es/_isIndex.js", "../../../node_modules/lodash-es/_baseAssignValue.js", "../../../node_modules/lodash-es/eq.js", "../../../node_modules/lodash-es/_assignValue.js", "../../../node_modules/lodash-es/_copyObject.js", "../../../node_modules/lodash-es/_overRest.js", "../../../node_modules/lodash-es/_baseRest.js", "../../../node_modules/lodash-es/isLength.js", "../../../node_modules/lodash-es/isArrayLike.js", "../../../node_modules/lodash-es/_isIterateeCall.js", "../../../node_modules/lodash-es/_createAssigner.js", "../../../node_modules/lodash-es/_isPrototype.js", "../../../node_modules/lodash-es/_baseTimes.js", "../../../node_modules/lodash-es/_baseIsArguments.js", "../../../node_modules/lodash-es/isArguments.js", "../../../node_modules/lodash-es/stubFalse.js", "../../../node_modules/lodash-es/isBuffer.js", "../../../node_modules/lodash-es/_baseIsTypedArray.js", "../../../node_modules/lodash-es/_baseUnary.js", "../../../node_modules/lodash-es/_nodeUtil.js", "../../../node_modules/lodash-es/isTypedArray.js", "../../../node_modules/lodash-es/_arrayLikeKeys.js", "../../../node_modules/lodash-es/_overArg.js", "../../../node_modules/lodash-es/_nativeKeys.js", "../../../node_modules/lodash-es/_baseKeys.js", "../../../node_modules/lodash-es/keys.js", "../../../node_modules/lodash-es/_nativeKeysIn.js", "../../../node_modules/lodash-es/_baseKeysIn.js", "../../../node_modules/lodash-es/keysIn.js", "../../../node_modules/lodash-es/_isKey.js", "../../../node_modules/lodash-es/_nativeCreate.js", "../../../node_modules/lodash-es/_hashClear.js", "../../../node_modules/lodash-es/_hashDelete.js", "../../../node_modules/lodash-es/_hashGet.js", "../../../node_modules/lodash-es/_hashHas.js", "../../../node_modules/lodash-es/_hashSet.js", "../../../node_modules/lodash-es/_Hash.js", "../../../node_modules/lodash-es/_listCacheClear.js", "../../../node_modules/lodash-es/_assocIndexOf.js", "../../../node_modules/lodash-es/_listCacheDelete.js", "../../../node_modules/lodash-es/_listCacheGet.js", "../../../node_modules/lodash-es/_listCacheHas.js", "../../../node_modules/lodash-es/_listCacheSet.js", "../../../node_modules/lodash-es/_ListCache.js", "../../../node_modules/lodash-es/_Map.js", "../../../node_modules/lodash-es/_mapCacheClear.js", "../../../node_modules/lodash-es/_isKeyable.js", "../../../node_modules/lodash-es/_getMapData.js", "../../../node_modules/lodash-es/_mapCacheDelete.js", "../../../node_modules/lodash-es/_mapCacheGet.js", "../../../node_modules/lodash-es/_mapCacheHas.js", "../../../node_modules/lodash-es/_mapCacheSet.js", "../../../node_modules/lodash-es/_MapCache.js", "../../../node_modules/lodash-es/memoize.js", "../../../node_modules/lodash-es/_memoizeCapped.js", "../../../node_modules/lodash-es/_stringToPath.js", "../../../node_modules/lodash-es/toString.js", "../../../node_modules/lodash-es/_castPath.js", "../../../node_modules/lodash-es/_toKey.js", "../../../node_modules/lodash-es/_baseGet.js", "../../../node_modules/lodash-es/_arrayPush.js", "../../../node_modules/lodash-es/_isFlattenable.js", "../../../node_modules/lodash-es/_baseFlatten.js", "../../../node_modules/lodash-es/flatten.js", "../../../node_modules/lodash-es/_flatRest.js", "../../../node_modules/lodash-es/_getPrototype.js", "../../../node_modules/lodash-es/isPlainObject.js", "../../../node_modules/lodash-es/_baseSlice.js", "../../../node_modules/lodash-es/_stackClear.js", "../../../node_modules/lodash-es/_stackDelete.js", "../../../node_modules/lodash-es/_stackGet.js", "../../../node_modules/lodash-es/_stackHas.js", "../../../node_modules/lodash-es/_stackSet.js", "../../../node_modules/lodash-es/_Stack.js", "../../../node_modules/lodash-es/_baseAssign.js", "../../../node_modules/lodash-es/_baseAssignIn.js", "../../../node_modules/lodash-es/_cloneBuffer.js", "../../../node_modules/lodash-es/_arrayFilter.js", "../../../node_modules/lodash-es/stubArray.js", "../../../node_modules/lodash-es/_getSymbols.js", "../../../node_modules/lodash-es/_copySymbols.js", "../../../node_modules/lodash-es/_getSymbolsIn.js", "../../../node_modules/lodash-es/_copySymbolsIn.js", "../../../node_modules/lodash-es/_baseGetAllKeys.js", "../../../node_modules/lodash-es/_getAllKeys.js", "../../../node_modules/lodash-es/_getAllKeysIn.js", "../../../node_modules/lodash-es/_DataView.js", "../../../node_modules/lodash-es/_Promise.js", "../../../node_modules/lodash-es/_Set.js", "../../../node_modules/lodash-es/_getTag.js", "../../../node_modules/lodash-es/_initCloneArray.js", "../../../node_modules/lodash-es/_Uint8Array.js", "../../../node_modules/lodash-es/_cloneArrayBuffer.js", "../../../node_modules/lodash-es/_cloneDataView.js", "../../../node_modules/lodash-es/_cloneRegExp.js", "../../../node_modules/lodash-es/_cloneSymbol.js", "../../../node_modules/lodash-es/_cloneTypedArray.js", "../../../node_modules/lodash-es/_initCloneByTag.js", "../../../node_modules/lodash-es/_initCloneObject.js", "../../../node_modules/lodash-es/_baseIsMap.js", "../../../node_modules/lodash-es/isMap.js", "../../../node_modules/lodash-es/_baseIsSet.js", "../../../node_modules/lodash-es/isSet.js", "../../../node_modules/lodash-es/_baseClone.js", "../../../node_modules/lodash-es/cloneDeep.js", "../../../node_modules/lodash-es/_createBaseFor.js", "../../../node_modules/lodash-es/_baseFor.js", "../../../node_modules/lodash-es/_assignMergeValue.js", "../../../node_modules/lodash-es/isArrayLikeObject.js", "../../../node_modules/lodash-es/_safeGet.js", "../../../node_modules/lodash-es/toPlainObject.js", "../../../node_modules/lodash-es/_baseMergeDeep.js", "../../../node_modules/lodash-es/_baseMerge.js", "../../../node_modules/lodash-es/last.js", "../../../node_modules/lodash-es/_parent.js", "../../../node_modules/lodash-es/merge.js", "../../../node_modules/lodash-es/_baseUnset.js", "../../../node_modules/lodash-es/_customOmitClone.js", "../../../node_modules/lodash-es/omit.js", "../../../node_modules/lodash-es/lodash.js", "../../spline-data/src/camera.ts", "../../spline-data/src/primitives.ts", "../../spline-data/src/cloner.ts", "../../collab-data/src/optype.ts", "../../collab-data/src/Table.ts", "../../collab-data/src/commonUtils.ts", "../../collab-data/src/error.ts", "../../collab-data/src/util.ts", "../../collab-data/src/Tree.ts", "../../collab-data/src/Obj.ts", "../../collab-data/src/Seq.ts", "../../collab-data/src/proxy.js", "../../collab-data/src/generics.ts", "../../../node_modules/msgpackr/unpack.js", "../../../node_modules/msgpackr/pack.js", "../../collab-data/src/serialize.ts", "../../spline-data/src/light.ts", "../../spline-data/src/mesh.ts", "../../spline-data/src/text.ts", "../../spline-data/src/material.ts", "../../spline-data/src/vector.ts", "../../spline-data/src/geometry.ts", "../../spline-data/src/object.ts", "../../common/src/constants.ts", "../../spe/src/objects/entities/text/Char3D.ts", "../../spe/src/objects/entities/text/TextFrame.ts", "../../spe/src/objects/entities/AbstractMesh.ts", "../../spe/src/geometries/ConeGeometry.ts", "../../spe/src/geometries/CylinderGeometry.ts", "../../spe/src/geometries/CubeGeometry.ts", "../../spe/src/geometries/PolyhedronRoundGeometry.ts", "../../spe/src/geometries/DodecahedronGeometry.ts", "../../spe/src/objects/entities/vectors/VectorShape.ts", "../../spe/src/objects/entities/vectors/bezier.ts", "../../spe/src/geometries/vectors/ArcToCurves.ts", "../../spe/src/geometries/vectors/VectorSurfaceGeometry.ts", "../../../node_modules/tess2-ts/src/utils/constants.ts", "../../../node_modules/tess2-ts/src/utils/assert.ts", "../../../node_modules/tess2-ts/src/utils/Geom.ts", "../../../node_modules/tess2-ts/src/mesh/TESSface.ts", "../../../node_modules/tess2-ts/src/mesh/TESShalfEdge.ts", "../../../node_modules/tess2-ts/src/mesh/TESSvertex.ts", "../../../node_modules/tess2-ts/src/mesh/TESSmesh.ts", "../../../node_modules/tess2-ts/src/utils/PriorityQ.ts", "../../../node_modules/tess2-ts/src/mesh/ActiveRegion.ts", "../../../node_modules/tess2-ts/src/utils/Dict.ts", "../../../node_modules/tess2-ts/src/utils/Sweep.ts", "../../../node_modules/tess2-ts/src/Tesselator.ts", "../../../node_modules/tess2-ts/src/index.ts", "../../spe/src/geometries/vectors/VectorExtrusionGeometry.ts", "../../spe/src/geometries/vectors/DynamicBuffer.ts", "../../spe/src/geometries/vectors/VectorGeometry.ts", "../../spe/src/geometries/EllipseGeometry.ts", "../../spe/src/geometries/HelixGeometry.ts", "../../spe/src/geometries/IcosahedronGeometry.ts", "../../spe/src/geometries/LatheGeometry.ts", "../../spe/src/geometries/NonParametricGeometry.ts", "../../spe/src/SubdivisionModifier.ts", "../../spe/src/geometries/PolygonGeometry.ts", "../../spe/src/geometries/PyramidGeometry.ts", "../../spe/src/geometries/RectangleGeometry.ts", "../../spe/src/geometries/SphereGeometry.ts", "../../spe/src/geometries/PlaneGeometry.ts", "../../spe/src/geometries/StarGeometry.ts", "../../spe/src/geometries/TextFrameGeometry.ts", "../../spe/src/geometries/TorusGeometry.ts", "../../spe/src/geometries/TorusKnotGeometry.ts", "../../spe/src/geometries/TriangleGeometry.ts", "../../spe/src/geometries/GeometryUtils.ts", "../../spe/src/geometries/subdiv/SubdivGeometry.ts", "../../spe/src/geometries/subdiv/modelling-wasm.ts", "../../spe/src/geometries/index.ts", "../../spe/src/objects/entities/Entity.ts", "../../spe/src/math/Box3.ts", "../../spe/src/objects/entities/utils.ts", "../../spe/src/objects/Color.ts", "../../spe/src/shared/utils.ts", "../../spe/src/objects/Object3D.ts", "../../spe/src/fileManager/object/ObjectExporter.ts", "../../spe/src/util.ts", "../../spe/src/fileManager/object/draco-encoder.ts", "../../spe/src/objects/Cloner.ts", "../../spe/src/materials/nodes/materials/NodeMaterial.ts", "../../spe/src/materials/nodes/core/NodeBuilder.ts", "../../spe/src/materials/nodes/core/NodeUniform.ts", "../../spe/src/materials/nodes/core/Node.ts", "../../spe/src/materials/nodes/core/NodeLib.ts", "../../spe/src/materials/nodes/inputs/Vector2Node.ts", "../../spe/src/materials/nodes/core/TempNode.ts", "../../spe/src/materials/nodes/core/InputNode.ts", "../../spe/src/materials/nodes/inputs/Vector3Node.ts", "../../spe/src/materials/nodes/inputs/Vector4Node.ts", "../../spe/src/materials/nodes/core/FunctionNode.ts", "../../spe/src/materials/nodes/core/ConstNode.ts", "../../spe/src/materials/nodes/core/StructNode.ts", "../../spe/src/materials/nodes/accessors/UVNode.ts", "../../spe/src/materials/nodes/utils/ColorSpaceNode.ts", "../../spe/src/materials/nodes/core/ExpressionNode.ts", "../../spe/src/textures/Texture.ts", "../../spe/src/materials/nodes/inputs/TextureNode.ts", "../../spe/src/materials/nodes/inputs/FloatNode.ts", "../../spe/src/materials/nodes/core/FunctionCallNode.ts", "../../spe/src/materials/nodes/math/OperatorNode.ts", "../../spe/src/materials/nodes/math/MathNode.ts", "../../spe/src/materials/nodes/misc/TextureCubeUVNode.ts", "../../spe/src/materials/nodes/accessors/NormalNode.ts", "../../spe/src/materials/nodes/accessors/PositionNode.ts", "../../spe/src/materials/nodes/accessors/ReflectNode.ts", "../../spe/src/materials/nodes/misc/TextureCubeNode.ts", "../../spe/src/materials/nodes/inputs/CubeTextureNode.ts", "../../spe/src/materials/nodes/materials/nodes/RawNode.ts", "../../spe/src/materials/nodes/inputs/ColorNode.ts", "../../spe/src/materials/layers/LayerStack.ts", "../../spe/src/materials/layers/Layer.ts", "../../spe/src/materials/nodes/inputs/IntNode.ts", "../../spe/src/materials/nodes/inputs/BoolNode.ts", "../../spe/src/materials/nodes/inputs/Vector4ArrayNode.ts", "../../spe/src/materials/nodes/inputs/FloatArrayNode.ts", "../../spe/src/materials/nodes/inputs/Matrix3Node.ts", "../../spe/src/materials/nodes/custom/CustomTextureNode.ts", "../../spe/src/materials/nodes/custom/FresnelNode.ts", "../../spe/src/materials/nodes/procedural/NoiseTypes.ts", "../../spe/src/materials/nodes/custom/RainbowNode.ts", "../../spe/src/materials/nodes/custom/TransmissionNode.ts", "../../spe/src/materials/nodes/custom/CustomNormalNode.ts", "../../spe/src/materials/nodes/custom/GradientNode.ts", "../../spe/src/materials/nodes/custom/VertexDisplacementNode.ts", "../../spe/src/materials/nodes/procedural/NoiseNode.ts", "../../spe/src/materials/nodes/custom/BlendNode.ts", "../../spe/src/materials/nodes/custom/DepthNode.ts", "../../spe/src/materials/nodes/custom/MatcapNode.ts", "../../spe/src/materials/nodes/materials/nodes/BasicNode.ts", "../../spe/src/materials/nodes/materials/BasicNodeMaterial.ts", "../../spe/src/materials/BasicMaterial.ts", "../../spe/src/materials/nodes/materials/nodes/PhongNode.ts", "../../spe/src/materials/nodes/materials/PhongNodeMaterial.ts", "../../spe/src/materials/PhongMaterial.ts", "../../spe/src/materials/nodes/materials/nodes/LambertNode.ts", "../../spe/src/materials/nodes/materials/LambertNodeMaterial.ts", "../../spe/src/materials/LambertMaterial.ts", "../../spe/src/materials/nodes/materials/nodes/ToonNode.ts", "../../spe/src/materials/nodes/materials/ToonNodeMaterial.ts", "../../spe/src/materials/ToonMaterial.ts", "../../spe/src/materials/nodes/materials/nodes/StandardNode.ts", "../../spe/src/materials/nodes/materials/StandardNodeMaterial.ts", "../../spe/src/materials/PhysicalMaterial.ts", "../../spe/src/materials/create.ts", "../../spe/src/materials/layers/create.ts", "../../spe/src/updaterUtils.ts", "../../spe/src/objects/entities/text/TextLine.ts", "../../spe/src/objects/entities/vectors/VectorObject.ts", "../../spe/src/objects/entities/CombinedCamera.ts", "../../spe/src/helpers/HelperMixin.ts", "../../spe/src/helpers/CombinedCameraHelper.ts", "../../spe/src/helpers/utils.ts", "../../spe/src/helpers/DirectionalLightHelper.ts", "../../spe/src/helpers/EmptyObjectHelper.ts", "../../spe/src/helpers/PointLightHelper.ts", "../../spe/src/helpers/SpotLightHelper.ts", "../../spe/src/objects/entities/EntityHelper.ts", "../../spe/src/objects/entities/EmptyObject.ts", "../../spe/src/objects/entities/LightDirectional.ts", "../../spe/src/objects/entities/LightPoint.ts", "../../spe/src/objects/entities/LightSpot.ts", "../../spe/src/objects/entities/Mesh2D.ts", "../../spe/src/TextureUtils.ts", "../../spe/src/objects/entities/Mesh3D.ts", "../../spe/src/objects/entities/NonParametric.ts", "../../spe/src/objects/Scene.ts", "../../spe/src/geometries/create.ts", "../../spe/src/objects/entities/subdiv/SubdivObject.ts", "../../spe/src/objects/entities/create.ts", "../../spe/src/objects/create.ts", "../../spe/src/objects/sceneUtils.ts", "../../spe/src/shared/SharedAssetsManager.ts"],
4
+ "sourcesContent": ["'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n", "!function(r,f){\"object\"==typeof exports&&\"undefined\"!=typeof module?f(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],f):f((r=\"undefined\"!=typeof globalThis?globalThis:r||self).SVDJS={})}(this,function(r){\"use strict\";r.SVD=function(r,f,o,e,t){if(f=void 0===f||f,o=void 0===o||o,t=1e-64/(e=e||Math.pow(2,-52)),!r)throw new TypeError(\"Matrix a is not defined\");var i,a,n,s,h,l,M,d,p,b,u,w,y=r[0].length,q=r.length;if(q<y)throw new TypeError(\"Invalid matrix: m < n\");for(var v=[],c=[],x=[],g=\"f\"===f?q:y,m=b=M=0;m<q;m++)c[m]=new Array(g).fill(0);for(m=0;m<y;m++)x[m]=new Array(y).fill(0);var S,T=new Array(y).fill(0);for(m=0;m<q;m++)for(i=0;i<y;i++)c[m][i]=r[m][i];for(m=0;m<y;m++){for(v[m]=M,p=0,n=m+1,i=m;i<q;i++)p+=Math.pow(c[i][m],2);if(p<t)M=0;else for(d=(l=c[m][m])*(M=l<0?Math.sqrt(p):-Math.sqrt(p))-p,c[m][m]=l-M,i=n;i<y;i++){for(p=0,a=m;a<q;a++)p+=c[a][m]*c[a][i];for(l=p/d,a=m;a<q;a++)c[a][i]=c[a][i]+l*c[a][m]}for(T[m]=M,p=0,i=n;i<y;i++)p+=Math.pow(c[m][i],2);if(p<t)M=0;else{for(d=(l=c[m][m+1])*(M=l<0?Math.sqrt(p):-Math.sqrt(p))-p,c[m][m+1]=l-M,i=n;i<y;i++)v[i]=c[m][i]/d;for(i=n;i<q;i++){for(p=0,a=n;a<y;a++)p+=c[i][a]*c[m][a];for(a=n;a<y;a++)c[i][a]=c[i][a]+p*v[a]}}b<(u=Math.abs(T[m])+Math.abs(v[m]))&&(b=u)}if(o)for(m=y-1;0<=m;m--){if(0!==M){for(d=c[m][m+1]*M,i=n;i<y;i++)x[i][m]=c[m][i]/d;for(i=n;i<y;i++){for(p=0,a=n;a<y;a++)p+=c[m][a]*x[a][i];for(a=n;a<y;a++)x[a][i]=x[a][i]+p*x[a][m]}}for(i=n;i<y;i++)x[m][i]=0,x[i][m]=0;x[m][m]=1,M=v[m],n=m}if(f){if(\"f\"===f)for(m=y;m<q;m++){for(i=y;i<q;i++)c[m][i]=0;c[m][m]=1}for(m=y-1;0<=m;m--){for(n=m+1,M=T[m],i=n;i<g;i++)c[m][i]=0;if(0!==M){for(d=c[m][m]*M,i=n;i<g;i++){for(p=0,a=n;a<q;a++)p+=c[a][m]*c[a][i];for(l=p/d,a=m;a<q;a++)c[a][i]=c[a][i]+l*c[a][m]}for(i=m;i<q;i++)c[i][m]=c[i][m]/M}else for(i=m;i<q;i++)c[i][m]=0;c[m][m]=c[m][m]+1}}for(e*=b,a=y-1;0<=a;a--)for(var k=0;k<50;k++){for(S=!1,n=a;0<=n;n--){if(Math.abs(v[n])<=e){S=!0;break}if(Math.abs(T[n-1])<=e)break}if(!S)for(h=0,s=n-(p=1),m=n;m<a+1&&(l=p*v[m],v[m]=h*v[m],!(Math.abs(l)<=e));m++)if(M=T[m],T[m]=Math.sqrt(l*l+M*M),h=M/(d=T[m]),p=-l/d,f)for(i=0;i<q;i++)u=c[i][s],w=c[i][m],c[i][s]=u*h+w*p,c[i][m]=-u*p+w*h;if(w=T[a],n===a){if(w<0&&(T[a]=-w,o))for(i=0;i<y;i++)x[i][a]=-x[i][a];break}for(b=T[n],l=(((u=T[a-1])-w)*(u+w)+((M=v[a-1])-(d=v[a]))*(M+d))/(2*d*u),M=Math.sqrt(l*l+1),l=((b-w)*(b+w)+d*(u/(l<0?l-M:l+M)-d))/b,m=n+(p=h=1);m<a+1;m++){if(M=v[m],u=T[m],d=p*M,M*=h,w=Math.sqrt(l*l+d*d),l=b*(h=l/(v[m-1]=w))+M*(p=d/w),M=-b*p+M*h,d=u*p,u*=h,o)for(i=0;i<y;i++)b=x[i][m-1],w=x[i][m],x[i][m-1]=b*h+w*p,x[i][m]=-b*p+w*h;if(w=Math.sqrt(l*l+d*d),l=(h=l/(T[m-1]=w))*M+(p=d/w)*u,b=-p*M+h*u,f)for(i=0;i<q;i++)u=c[i][m-1],w=c[i][m],c[i][m-1]=u*h+w*p,c[i][m]=-u*p+w*h}v[n]=0,v[a]=l,T[a]=b}for(m=0;m<y;m++)T[m]<e&&(T[m]=0);return{u:c,q:T,v:x}},r.VERSION=\"1.1.1\",Object.defineProperty(r,\"__esModule\",{value:!0})});\n", "import { FileLoader, Loader, Scene } from 'three';\nimport { SharedAssetsManager, Scene as SplineScene } from 'spe';\nimport { DocumentData } from 'spline-data';\nimport { CollabSerialize } from 'collab-data';\n\nexport default class SplineLoader extends Loader {\n\tload(\n\t\turl: string,\n\t\tonLoad: (scene: Scene) => void,\n\t\tonProgress?: (event: ProgressEvent) => void,\n\t\tonError: (event: ErrorEvent) => void = console.error\n\t) {\n\t\tconst loader = new FileLoader(this.manager);\n\t\tloader.setPath(this.path);\n\t\tloader.setResponseType('arraybuffer');\n\t\tloader.setRequestHeader(this.requestHeader);\n\t\tloader.setWithCredentials(this.withCredentials);\n\n\t\tloader.load(\n\t\t\turl,\n\t\t\t(buffer) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof buffer == 'string') {\n\t\t\t\t\t\tthrow new Error('The .spline file is not binary!');\n\t\t\t\t\t}\n\n\t\t\t\t\tonLoad(this.parse(buffer));\n\t\t\t\t} catch (e) {\n\t\t\t\t\tonError(e);\n\t\t\t\t}\n\t\t\t},\n\t\t\tonProgress,\n\t\t\tonError\n\t\t);\n\t}\n\n\tparse(buffer: ArrayBuffer): Scene {\n\t\tconst data = CollabSerialize.deserialize(\n\t\t\tnew Uint8Array(buffer)\n\t\t) as DocumentData;\n\t\tconst sharedAssets = new SharedAssetsManager(data.shared);\n\t\tconst scene = new SplineScene(data.scene, sharedAssets);\n\t\treturn scene;\n\t}\n}\n", "// https://stackoverflow.com/questions/56248618/how-to-check-if-an-object-is-a-readonly-array-in-typescript\nexport function isReadonlyArray(arg: any): arg is ReadonlyArray<any> {\n\treturn Array.isArray(arg);\n}\n\nexport type OneOrMore<T> = T[] | T;\nexport type ReadonlyOneOrMore<T> = readonly T[] | T;\n\nexport type ObjMap<T> = { [k: string]: T };\n\nexport function wrapSingleton<T>(a: T[] | T): T[] {\n\tif (Array.isArray(a)) {\n\t\treturn a;\n\t} else {\n\t\treturn [a];\n\t}\n}\n\n/**\n * alphabetical/dictionary order, elements of `a`/`b` are compared by `<`/`>`\n */\nexport function dirSort<T>(a: T[], b: T[]): number {\n\tlet i = 0;\n\twhile (i < a.length && i < b.length) {\n\t\tif (a[i] < b[i]) {\n\t\t\treturn -1;\n\t\t} else if (a[i] > b[i]) {\n\t\t\treturn 1;\n\t\t}\n\t\ti += 1;\n\t}\n\tif (i !== b.length) {\n\t\treturn -1;\n\t} else if (i !== a.length) {\n\t\treturn 1;\n\t} else {\n\t\treturn 0;\n\t}\n}\n", "/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n", "import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n", "import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n", "import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n", "import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n", "/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n", "/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n", "/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n", "import Symbol from './_Symbol.js';\nimport arrayMap from './_arrayMap.js';\nimport isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n", "/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n", "/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nexport default identity;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObject from './isObject.js';\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nexport default isFunction;\n", "import root from './_root.js';\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nexport default coreJsData;\n", "import coreJsData from './_coreJsData.js';\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nexport default isMasked;\n", "/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nexport default toSource;\n", "import isFunction from './isFunction.js';\nimport isMasked from './_isMasked.js';\nimport isObject from './isObject.js';\nimport toSource from './_toSource.js';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nexport default baseIsNative;\n", "/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n", "import baseIsNative from './_baseIsNative.js';\nimport getValue from './_getValue.js';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nexport default getNative;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n", "import isObject from './isObject.js';\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n}());\n\nexport default baseCreate;\n", "/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nexport default apply;\n", "/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nexport default copyArray;\n", "/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nexport default shortOut;\n", "/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nexport default constant;\n", "import getNative from './_getNative.js';\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nexport default defineProperty;\n", "import constant from './constant.js';\nimport defineProperty from './_defineProperty.js';\nimport identity from './identity.js';\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nexport default baseSetToString;\n", "import baseSetToString from './_baseSetToString.js';\nimport shortOut from './_shortOut.js';\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nexport default setToString;\n", "/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n", "/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n", "import defineProperty from './_defineProperty.js';\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nexport default baseAssignValue;\n", "/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n", "import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nexport default assignValue;\n", "import assignValue from './_assignValue.js';\nimport baseAssignValue from './_baseAssignValue.js';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nexport default copyObject;\n", "import apply from './_apply.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nexport default overRest;\n", "import identity from './identity.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nexport default baseRest;\n", "/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n", "import isFunction from './isFunction.js';\nimport isLength from './isLength.js';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nexport default isArrayLike;\n", "import eq from './eq.js';\nimport isArrayLike from './isArrayLike.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\nexport default isIterateeCall;\n", "import baseRest from './_baseRest.js';\nimport isIterateeCall from './_isIterateeCall.js';\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\nexport default createAssigner;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nexport default isPrototype;\n", "/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\nexport default baseTimes;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nexport default baseIsArguments;\n", "import baseIsArguments from './_baseIsArguments.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\nexport default isArguments;\n", "/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nexport default stubFalse;\n", "import root from './_root.js';\nimport stubFalse from './stubFalse.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nexport default isBuffer;\n", "import baseGetTag from './_baseGetTag.js';\nimport isLength from './isLength.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nexport default baseIsTypedArray;\n", "/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\nexport default baseUnary;\n", "import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\nexport default nodeUtil;\n", "import baseIsTypedArray from './_baseIsTypedArray.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nexport default isTypedArray;\n", "import baseTimes from './_baseTimes.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isIndex from './_isIndex.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default arrayLikeKeys;\n", "/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n", "import overArg from './_overArg.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nexport default nativeKeys;\n", "import isPrototype from './_isPrototype.js';\nimport nativeKeys from './_nativeKeys.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeys;\n", "import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n", "/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default nativeKeysIn;\n", "import isObject from './isObject.js';\nimport isPrototype from './_isPrototype.js';\nimport nativeKeysIn from './_nativeKeysIn.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n}\n\nexport default baseKeysIn;\n", "import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeysIn from './_baseKeysIn.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nexport default keysIn;\n", "import isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nexport default isKey;\n", "import getNative from './_getNative.js';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n", "import nativeCreate from './_nativeCreate.js';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\nexport default hashClear;\n", "/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default hashDelete;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nexport default hashSet;\n", "import hashClear from './_hashClear.js';\nimport hashDelete from './_hashDelete.js';\nimport hashGet from './_hashGet.js';\nimport hashHas from './_hashHas.js';\nimport hashSet from './_hashSet.js';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n", "/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nexport default listCacheClear;\n", "import eq from './eq.js';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nexport default assocIndexOf;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nexport default listCacheDelete;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nexport default listCacheSet;\n", "import listCacheClear from './_listCacheClear.js';\nimport listCacheDelete from './_listCacheDelete.js';\nimport listCacheGet from './_listCacheGet.js';\nimport listCacheHas from './_listCacheHas.js';\nimport listCacheSet from './_listCacheSet.js';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n", "import Hash from './_Hash.js';\nimport ListCache from './_ListCache.js';\nimport Map from './_Map.js';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\nexport default mapCacheClear;\n", "/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nexport default isKeyable;\n", "import isKeyable from './_isKeyable.js';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nexport default getMapData;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nexport default mapCacheDelete;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nexport default mapCacheSet;\n", "import mapCacheClear from './_mapCacheClear.js';\nimport mapCacheDelete from './_mapCacheDelete.js';\nimport mapCacheGet from './_mapCacheGet.js';\nimport mapCacheHas from './_mapCacheHas.js';\nimport mapCacheSet from './_mapCacheSet.js';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n", "import MapCache from './_MapCache.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nexport default memoize;\n", "import memoize from './memoize.js';\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nexport default memoizeCapped;\n", "import memoizeCapped from './_memoizeCapped.js';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nexport default stringToPath;\n", "import baseToString from './_baseToString.js';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n", "import isArray from './isArray.js';\nimport isKey from './_isKey.js';\nimport stringToPath from './_stringToPath.js';\nimport toString from './toString.js';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nexport default castPath;\n", "import isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n", "import castPath from './_castPath.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n", "/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n", "import Symbol from './_Symbol.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nexport default isFlattenable;\n", "import arrayPush from './_arrayPush.js';\nimport isFlattenable from './_isFlattenable.js';\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nexport default baseFlatten;\n", "import baseFlatten from './_baseFlatten.js';\n\n/**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\nfunction flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n}\n\nexport default flatten;\n", "import flatten from './flatten.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\nfunction flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n}\n\nexport default flatRest;\n", "import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n", "import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n", "/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n}\n\nexport default baseSlice;\n", "import ListCache from './_ListCache.js';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\nexport default stackClear;\n", "/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\nexport default stackDelete;\n", "/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\nexport default stackGet;\n", "/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\nexport default stackHas;\n", "import ListCache from './_ListCache.js';\nimport Map from './_Map.js';\nimport MapCache from './_MapCache.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\nexport default stackSet;\n", "import ListCache from './_ListCache.js';\nimport stackClear from './_stackClear.js';\nimport stackDelete from './_stackDelete.js';\nimport stackGet from './_stackGet.js';\nimport stackHas from './_stackHas.js';\nimport stackSet from './_stackSet.js';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n", "import copyObject from './_copyObject.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\nexport default baseAssign;\n", "import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n}\n\nexport default baseAssignIn;\n", "import root from './_root.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n}\n\nexport default cloneBuffer;\n", "/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n", "/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n", "import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nexport default getSymbols;\n", "import copyObject from './_copyObject.js';\nimport getSymbols from './_getSymbols.js';\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\nexport default copySymbols;\n", "import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nexport default getSymbolsIn;\n", "import copyObject from './_copyObject.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n}\n\nexport default copySymbolsIn;\n", "import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n", "import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n", "import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n", "import DataView from './_DataView.js';\nimport Map from './_Map.js';\nimport Promise from './_Promise.js';\nimport Set from './_Set.js';\nimport WeakMap from './_WeakMap.js';\nimport baseGetTag from './_baseGetTag.js';\nimport toSource from './_toSource.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nexport default getTag;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n", "import root from './_root.js';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n", "import Uint8Array from './_Uint8Array.js';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\nexport default cloneArrayBuffer;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n", "/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n", "import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n", "import baseCreate from './_baseCreate.js';\nimport getPrototype from './_getPrototype.js';\nimport isPrototype from './_isPrototype.js';\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\nexport default initCloneObject;\n", "import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n", "import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n", "import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n", "import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n", "import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\nimport keysIn from './keysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n", "import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n}\n\nexport default cloneDeep;\n", "/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n}\n\nexport default createBaseFor;\n", "import createBaseFor from './_createBaseFor.js';\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nexport default baseFor;\n", "import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nexport default assignMergeValue;\n", "import isArrayLike from './isArrayLike.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\nexport default isArrayLikeObject;\n", "/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n}\n\nexport default safeGet;\n", "import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n return copyObject(value, keysIn(value));\n}\n\nexport default toPlainObject;\n", "import assignMergeValue from './_assignMergeValue.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\nimport copyArray from './_copyArray.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isArrayLikeObject from './isArrayLikeObject.js';\nimport isBuffer from './isBuffer.js';\nimport isFunction from './isFunction.js';\nimport isObject from './isObject.js';\nimport isPlainObject from './isPlainObject.js';\nimport isTypedArray from './isTypedArray.js';\nimport safeGet from './_safeGet.js';\nimport toPlainObject from './toPlainObject.js';\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n}\n\nexport default baseMergeDeep;\n", "import Stack from './_Stack.js';\nimport assignMergeValue from './_assignMergeValue.js';\nimport baseFor from './_baseFor.js';\nimport baseMergeDeep from './_baseMergeDeep.js';\nimport isObject from './isObject.js';\nimport keysIn from './keysIn.js';\nimport safeGet from './_safeGet.js';\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n stack || (stack = new Stack);\n if (isObject(srcValue)) {\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n}\n\nexport default baseMerge;\n", "/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n", "import baseGet from './_baseGet.js';\nimport baseSlice from './_baseSlice.js';\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nexport default parent;\n", "import baseMerge from './_baseMerge.js';\nimport createAssigner from './_createAssigner.js';\n\n/**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n * 'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n * 'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\nvar merge = createAssigner(function(object, source, srcIndex) {\n baseMerge(object, source, srcIndex);\n});\n\nexport default merge;\n", "import castPath from './_castPath.js';\nimport last from './last.js';\nimport parent from './_parent.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\nfunction baseUnset(object, path) {\n path = castPath(path, object);\n object = parent(object, path);\n return object == null || delete object[toKey(last(path))];\n}\n\nexport default baseUnset;\n", "import isPlainObject from './isPlainObject.js';\n\n/**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\nfunction customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n}\n\nexport default customOmitClone;\n", "import arrayMap from './_arrayMap.js';\nimport baseClone from './_baseClone.js';\nimport baseUnset from './_baseUnset.js';\nimport castPath from './_castPath.js';\nimport copyObject from './_copyObject.js';\nimport customOmitClone from './_customOmitClone.js';\nimport flatRest from './_flatRest.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\nvar omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n});\n\nexport default omit;\n", "/**\n * @license\n * Lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"es\" -o ./`\n * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nexport { default as add } from './add.js';\nexport { default as after } from './after.js';\nexport { default as ary } from './ary.js';\nexport { default as assign } from './assign.js';\nexport { default as assignIn } from './assignIn.js';\nexport { default as assignInWith } from './assignInWith.js';\nexport { default as assignWith } from './assignWith.js';\nexport { default as at } from './at.js';\nexport { default as attempt } from './attempt.js';\nexport { default as before } from './before.js';\nexport { default as bind } from './bind.js';\nexport { default as bindAll } from './bindAll.js';\nexport { default as bindKey } from './bindKey.js';\nexport { default as camelCase } from './camelCase.js';\nexport { default as capitalize } from './capitalize.js';\nexport { default as castArray } from './castArray.js';\nexport { default as ceil } from './ceil.js';\nexport { default as chain } from './chain.js';\nexport { default as chunk } from './chunk.js';\nexport { default as clamp } from './clamp.js';\nexport { default as clone } from './clone.js';\nexport { default as cloneDeep } from './cloneDeep.js';\nexport { default as cloneDeepWith } from './cloneDeepWith.js';\nexport { default as cloneWith } from './cloneWith.js';\nexport { default as commit } from './commit.js';\nexport { default as compact } from './compact.js';\nexport { default as concat } from './concat.js';\nexport { default as cond } from './cond.js';\nexport { default as conforms } from './conforms.js';\nexport { default as conformsTo } from './conformsTo.js';\nexport { default as constant } from './constant.js';\nexport { default as countBy } from './countBy.js';\nexport { default as create } from './create.js';\nexport { default as curry } from './curry.js';\nexport { default as curryRight } from './curryRight.js';\nexport { default as debounce } from './debounce.js';\nexport { default as deburr } from './deburr.js';\nexport { default as defaultTo } from './defaultTo.js';\nexport { default as defaults } from './defaults.js';\nexport { default as defaultsDeep } from './defaultsDeep.js';\nexport { default as defer } from './defer.js';\nexport { default as delay } from './delay.js';\nexport { default as difference } from './difference.js';\nexport { default as differenceBy } from './differenceBy.js';\nexport { default as differenceWith } from './differenceWith.js';\nexport { default as divide } from './divide.js';\nexport { default as drop } from './drop.js';\nexport { default as dropRight } from './dropRight.js';\nexport { default as dropRightWhile } from './dropRightWhile.js';\nexport { default as dropWhile } from './dropWhile.js';\nexport { default as each } from './each.js';\nexport { default as eachRight } from './eachRight.js';\nexport { default as endsWith } from './endsWith.js';\nexport { default as entries } from './entries.js';\nexport { default as entriesIn } from './entriesIn.js';\nexport { default as eq } from './eq.js';\nexport { default as escape } from './escape.js';\nexport { default as escapeRegExp } from './escapeRegExp.js';\nexport { default as every } from './every.js';\nexport { default as extend } from './extend.js';\nexport { default as extendWith } from './extendWith.js';\nexport { default as fill } from './fill.js';\nexport { default as filter } from './filter.js';\nexport { default as find } from './find.js';\nexport { default as findIndex } from './findIndex.js';\nexport { default as findKey } from './findKey.js';\nexport { default as findLast } from './findLast.js';\nexport { default as findLastIndex } from './findLastIndex.js';\nexport { default as findLastKey } from './findLastKey.js';\nexport { default as first } from './first.js';\nexport { default as flatMap } from './flatMap.js';\nexport { default as flatMapDeep } from './flatMapDeep.js';\nexport { default as flatMapDepth } from './flatMapDepth.js';\nexport { default as flatten } from './flatten.js';\nexport { default as flattenDeep } from './flattenDeep.js';\nexport { default as flattenDepth } from './flattenDepth.js';\nexport { default as flip } from './flip.js';\nexport { default as floor } from './floor.js';\nexport { default as flow } from './flow.js';\nexport { default as flowRight } from './flowRight.js';\nexport { default as forEach } from './forEach.js';\nexport { default as forEachRight } from './forEachRight.js';\nexport { default as forIn } from './forIn.js';\nexport { default as forInRight } from './forInRight.js';\nexport { default as forOwn } from './forOwn.js';\nexport { default as forOwnRight } from './forOwnRight.js';\nexport { default as fromPairs } from './fromPairs.js';\nexport { default as functions } from './functions.js';\nexport { default as functionsIn } from './functionsIn.js';\nexport { default as get } from './get.js';\nexport { default as groupBy } from './groupBy.js';\nexport { default as gt } from './gt.js';\nexport { default as gte } from './gte.js';\nexport { default as has } from './has.js';\nexport { default as hasIn } from './hasIn.js';\nexport { default as head } from './head.js';\nexport { default as identity } from './identity.js';\nexport { default as inRange } from './inRange.js';\nexport { default as includes } from './includes.js';\nexport { default as indexOf } from './indexOf.js';\nexport { default as initial } from './initial.js';\nexport { default as intersection } from './intersection.js';\nexport { default as intersectionBy } from './intersectionBy.js';\nexport { default as intersectionWith } from './intersectionWith.js';\nexport { default as invert } from './invert.js';\nexport { default as invertBy } from './invertBy.js';\nexport { default as invoke } from './invoke.js';\nexport { default as invokeMap } from './invokeMap.js';\nexport { default as isArguments } from './isArguments.js';\nexport { default as isArray } from './isArray.js';\nexport { default as isArrayBuffer } from './isArrayBuffer.js';\nexport { default as isArrayLike } from './isArrayLike.js';\nexport { default as isArrayLikeObject } from './isArrayLikeObject.js';\nexport { default as isBoolean } from './isBoolean.js';\nexport { default as isBuffer } from './isBuffer.js';\nexport { default as isDate } from './isDate.js';\nexport { default as isElement } from './isElement.js';\nexport { default as isEmpty } from './isEmpty.js';\nexport { default as isEqual } from './isEqual.js';\nexport { default as isEqualWith } from './isEqualWith.js';\nexport { default as isError } from './isError.js';\nexport { default as isFinite } from './isFinite.js';\nexport { default as isFunction } from './isFunction.js';\nexport { default as isInteger } from './isInteger.js';\nexport { default as isLength } from './isLength.js';\nexport { default as isMap } from './isMap.js';\nexport { default as isMatch } from './isMatch.js';\nexport { default as isMatchWith } from './isMatchWith.js';\nexport { default as isNaN } from './isNaN.js';\nexport { default as isNative } from './isNative.js';\nexport { default as isNil } from './isNil.js';\nexport { default as isNull } from './isNull.js';\nexport { default as isNumber } from './isNumber.js';\nexport { default as isObject } from './isObject.js';\nexport { default as isObjectLike } from './isObjectLike.js';\nexport { default as isPlainObject } from './isPlainObject.js';\nexport { default as isRegExp } from './isRegExp.js';\nexport { default as isSafeInteger } from './isSafeInteger.js';\nexport { default as isSet } from './isSet.js';\nexport { default as isString } from './isString.js';\nexport { default as isSymbol } from './isSymbol.js';\nexport { default as isTypedArray } from './isTypedArray.js';\nexport { default as isUndefined } from './isUndefined.js';\nexport { default as isWeakMap } from './isWeakMap.js';\nexport { default as isWeakSet } from './isWeakSet.js';\nexport { default as iteratee } from './iteratee.js';\nexport { default as join } from './join.js';\nexport { default as kebabCase } from './kebabCase.js';\nexport { default as keyBy } from './keyBy.js';\nexport { default as keys } from './keys.js';\nexport { default as keysIn } from './keysIn.js';\nexport { default as last } from './last.js';\nexport { default as lastIndexOf } from './lastIndexOf.js';\nexport { default as lodash } from './wrapperLodash.js';\nexport { default as lowerCase } from './lowerCase.js';\nexport { default as lowerFirst } from './lowerFirst.js';\nexport { default as lt } from './lt.js';\nexport { default as lte } from './lte.js';\nexport { default as map } from './map.js';\nexport { default as mapKeys } from './mapKeys.js';\nexport { default as mapValues } from './mapValues.js';\nexport { default as matches } from './matches.js';\nexport { default as matchesProperty } from './matchesProperty.js';\nexport { default as max } from './max.js';\nexport { default as maxBy } from './maxBy.js';\nexport { default as mean } from './mean.js';\nexport { default as meanBy } from './meanBy.js';\nexport { default as memoize } from './memoize.js';\nexport { default as merge } from './merge.js';\nexport { default as mergeWith } from './mergeWith.js';\nexport { default as method } from './method.js';\nexport { default as methodOf } from './methodOf.js';\nexport { default as min } from './min.js';\nexport { default as minBy } from './minBy.js';\nexport { default as mixin } from './mixin.js';\nexport { default as multiply } from './multiply.js';\nexport { default as negate } from './negate.js';\nexport { default as next } from './next.js';\nexport { default as noop } from './noop.js';\nexport { default as now } from './now.js';\nexport { default as nth } from './nth.js';\nexport { default as nthArg } from './nthArg.js';\nexport { default as omit } from './omit.js';\nexport { default as omitBy } from './omitBy.js';\nexport { default as once } from './once.js';\nexport { default as orderBy } from './orderBy.js';\nexport { default as over } from './over.js';\nexport { default as overArgs } from './overArgs.js';\nexport { default as overEvery } from './overEvery.js';\nexport { default as overSome } from './overSome.js';\nexport { default as pad } from './pad.js';\nexport { default as padEnd } from './padEnd.js';\nexport { default as padStart } from './padStart.js';\nexport { default as parseInt } from './parseInt.js';\nexport { default as partial } from './partial.js';\nexport { default as partialRight } from './partialRight.js';\nexport { default as partition } from './partition.js';\nexport { default as pick } from './pick.js';\nexport { default as pickBy } from './pickBy.js';\nexport { default as plant } from './plant.js';\nexport { default as property } from './property.js';\nexport { default as propertyOf } from './propertyOf.js';\nexport { default as pull } from './pull.js';\nexport { default as pullAll } from './pullAll.js';\nexport { default as pullAllBy } from './pullAllBy.js';\nexport { default as pullAllWith } from './pullAllWith.js';\nexport { default as pullAt } from './pullAt.js';\nexport { default as random } from './random.js';\nexport { default as range } from './range.js';\nexport { default as rangeRight } from './rangeRight.js';\nexport { default as rearg } from './rearg.js';\nexport { default as reduce } from './reduce.js';\nexport { default as reduceRight } from './reduceRight.js';\nexport { default as reject } from './reject.js';\nexport { default as remove } from './remove.js';\nexport { default as repeat } from './repeat.js';\nexport { default as replace } from './replace.js';\nexport { default as rest } from './rest.js';\nexport { default as result } from './result.js';\nexport { default as reverse } from './reverse.js';\nexport { default as round } from './round.js';\nexport { default as sample } from './sample.js';\nexport { default as sampleSize } from './sampleSize.js';\nexport { default as set } from './set.js';\nexport { default as setWith } from './setWith.js';\nexport { default as shuffle } from './shuffle.js';\nexport { default as size } from './size.js';\nexport { default as slice } from './slice.js';\nexport { default as snakeCase } from './snakeCase.js';\nexport { default as some } from './some.js';\nexport { default as sortBy } from './sortBy.js';\nexport { default as sortedIndex } from './sortedIndex.js';\nexport { default as sortedIndexBy } from './sortedIndexBy.js';\nexport { default as sortedIndexOf } from './sortedIndexOf.js';\nexport { default as sortedLastIndex } from './sortedLastIndex.js';\nexport { default as sortedLastIndexBy } from './sortedLastIndexBy.js';\nexport { default as sortedLastIndexOf } from './sortedLastIndexOf.js';\nexport { default as sortedUniq } from './sortedUniq.js';\nexport { default as sortedUniqBy } from './sortedUniqBy.js';\nexport { default as split } from './split.js';\nexport { default as spread } from './spread.js';\nexport { default as startCase } from './startCase.js';\nexport { default as startsWith } from './startsWith.js';\nexport { default as stubArray } from './stubArray.js';\nexport { default as stubFalse } from './stubFalse.js';\nexport { default as stubObject } from './stubObject.js';\nexport { default as stubString } from './stubString.js';\nexport { default as stubTrue } from './stubTrue.js';\nexport { default as subtract } from './subtract.js';\nexport { default as sum } from './sum.js';\nexport { default as sumBy } from './sumBy.js';\nexport { default as tail } from './tail.js';\nexport { default as take } from './take.js';\nexport { default as takeRight } from './takeRight.js';\nexport { default as takeRightWhile } from './takeRightWhile.js';\nexport { default as takeWhile } from './takeWhile.js';\nexport { default as tap } from './tap.js';\nexport { default as template } from './template.js';\nexport { default as templateSettings } from './templateSettings.js';\nexport { default as throttle } from './throttle.js';\nexport { default as thru } from './thru.js';\nexport { default as times } from './times.js';\nexport { default as toArray } from './toArray.js';\nexport { default as toFinite } from './toFinite.js';\nexport { default as toInteger } from './toInteger.js';\nexport { default as toIterator } from './toIterator.js';\nexport { default as toJSON } from './toJSON.js';\nexport { default as toLength } from './toLength.js';\nexport { default as toLower } from './toLower.js';\nexport { default as toNumber } from './toNumber.js';\nexport { default as toPairs } from './toPairs.js';\nexport { default as toPairsIn } from './toPairsIn.js';\nexport { default as toPath } from './toPath.js';\nexport { default as toPlainObject } from './toPlainObject.js';\nexport { default as toSafeInteger } from './toSafeInteger.js';\nexport { default as toString } from './toString.js';\nexport { default as toUpper } from './toUpper.js';\nexport { default as transform } from './transform.js';\nexport { default as trim } from './trim.js';\nexport { default as trimEnd } from './trimEnd.js';\nexport { default as trimStart } from './trimStart.js';\nexport { default as truncate } from './truncate.js';\nexport { default as unary } from './unary.js';\nexport { default as unescape } from './unescape.js';\nexport { default as union } from './union.js';\nexport { default as unionBy } from './unionBy.js';\nexport { default as unionWith } from './unionWith.js';\nexport { default as uniq } from './uniq.js';\nexport { default as uniqBy } from './uniqBy.js';\nexport { default as uniqWith } from './uniqWith.js';\nexport { default as uniqueId } from './uniqueId.js';\nexport { default as unset } from './unset.js';\nexport { default as unzip } from './unzip.js';\nexport { default as unzipWith } from './unzipWith.js';\nexport { default as update } from './update.js';\nexport { default as updateWith } from './updateWith.js';\nexport { default as upperCase } from './upperCase.js';\nexport { default as upperFirst } from './upperFirst.js';\nexport { default as value } from './value.js';\nexport { default as valueOf } from './valueOf.js';\nexport { default as values } from './values.js';\nexport { default as valuesIn } from './valuesIn.js';\nexport { default as without } from './without.js';\nexport { default as words } from './words.js';\nexport { default as wrap } from './wrap.js';\nexport { default as wrapperAt } from './wrapperAt.js';\nexport { default as wrapperChain } from './wrapperChain.js';\nexport { default as wrapperCommit } from './commit.js';\nexport { default as wrapperLodash } from './wrapperLodash.js';\nexport { default as wrapperNext } from './next.js';\nexport { default as wrapperPlant } from './plant.js';\nexport { default as wrapperReverse } from './wrapperReverse.js';\nexport { default as wrapperToIterator } from './toIterator.js';\nexport { default as wrapperValue } from './wrapperValue.js';\nexport { default as xor } from './xor.js';\nexport { default as xorBy } from './xorBy.js';\nexport { default as xorWith } from './xorWith.js';\nexport { default as zip } from './zip.js';\nexport { default as zipObject } from './zipObject.js';\nexport { default as zipObjectDeep } from './zipObjectDeep.js';\nexport { default as zipWith } from './zipWith.js';\nexport { default } from './lodash.default.js';\n", "import { Vector3 } from '.';\nimport { Nullable } from './primitives';\n\nexport type CameraType = 'PerspectiveCamera' | 'OrthographicCamera';\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace CameraType {\n\texport const all: CameraType[] = ['PerspectiveCamera', 'OrthographicCamera'];\n\texport function is(a: string | undefined): boolean {\n\t\treturn (all as any[]).includes(a);\n\t}\n}\n\nexport type NearFovZoom = {\n\treadonly near: number;\n\treadonly fov: number;\n\treadonly zoom: number;\n};\n\nexport type CameraState = {\n\treadonly type: CameraType;\n\treadonly far: number;\n\treadonly perspective: NearFovZoom;\n\treadonly orthographic: Omit<NearFovZoom, 'fov'>;\n\treadonly up: Vector3;\n\treadonly isUpVectorFlipped: boolean;\n\treadonly targetOffset: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace CameraState {\n\texport const DefaultUp: Vector3 = [0, 1, 0];\n\texport const DefaultTargetOffset = 1000;\n\texport const defaultData: CameraState = {\n\t\tfar: 500000,\n\t\ttype: 'OrthographicCamera',\n\t\tperspective: {\n\t\t\tnear: 5,\n\t\t\tfov: 45,\n\t\t\tzoom: 1,\n\t\t},\n\t\torthographic: {\n\t\t\tnear: -500000,\n\t\t\tzoom: 1,\n\t\t},\n\t\tup: CameraState.DefaultUp,\n\t\tisUpVectorFlipped: false,\n\t\ttargetOffset: CameraState.DefaultTargetOffset,\n\t};\n\texport function getZoom(camera: CameraState) {\n\t\treturn camera.type === 'PerspectiveCamera'\n\t\t\t? camera.perspective.zoom\n\t\t\t: camera.orthographic.zoom;\n\t}\n}\n\n// TODO COLLAB target offset\nexport type CameraInteractionState = {\n\treadonly perspective: Nullable<{\n\t\treadonly zoom: number;\n\t}>;\n\treadonly orthographic: Nullable<{\n\t\treadonly zoom: number;\n\t}>;\n};\n", "import { Ref } from 'collab-data';\nimport { TypedArray } from 'spe';\n\nexport type Named = {\n\treadonly name: string;\n};\n\nexport enum Axis {\n\tx = 'x',\n\ty = 'y',\n\tz = 'z',\n}\n\n/**\n *\n */\nexport enum ObjectAlignment {\n\tTop = 'top',\n\tRight = 'right',\n\tBottom = 'bottom',\n\tLeft = 'left',\n\tCenter = 'center',\n}\n\nexport type Vector2 = readonly [number, number];\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Vector2 {\n\texport function isEqual(a: Vector2, b: Vector2): boolean {\n\t\treturn a[0] === b[0] && a[1] === b[1];\n\t}\n\texport function lerp(a: Vector2, b: Vector2, t: number): Vector2 {\n\t\treturn [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];\n\t}\n}\n\nexport type Vector3 = readonly [number, number, number];\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Vector3 {\n\texport function isEqual(a: Vector3, b: Vector3): boolean {\n\t\treturn a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n\t}\n\texport function add(a: Vector3, b: Vector3): Vector3 {\n\t\treturn [a[0] + b[0], a[1] + b[1], a[2] + b[2]];\n\t}\n\texport function sub(a: Vector3, b: Vector3): Vector3 {\n\t\treturn [a[0] - b[0], a[1] - b[1], a[2] - b[2]];\n\t}\n\texport function lerp(a: Vector3, b: Vector3, t: number): Vector3 {\n\t\treturn [\n\t\t\ta[0] + (b[0] - a[0]) * t,\n\t\t\ta[1] + (b[1] - a[1]) * t,\n\t\t\ta[2] + (b[2] - a[2]) * t,\n\t\t];\n\t}\n}\n\nexport type Vector4 = readonly [number, number, number, number];\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Vector4 {\n\texport function isEqual(a: Vector4, b: Vector4): boolean {\n\t\treturn a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];\n\t}\n\texport function lerp(a: Vector4, b: Vector4, t: number): Vector4 {\n\t\treturn [\n\t\t\ta[0] + (b[0] - a[0]) * t,\n\t\t\ta[1] + (b[1] - a[1]) * t,\n\t\t\ta[2] + (b[2] - a[2]) * t,\n\t\t\ta[3] + (b[3] - a[3]) * t,\n\t\t];\n\t}\n}\n\nexport type EulerAngle = readonly [number, number, number]; // only allow xyz for now\nexport type Rotation = EulerAngle;\n\nexport type MatrixFull = readonly [\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber,\n\tnumber\n];\nexport type Matrix = MatrixFull;\n// | 0; // 0 means identity\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Matrix {\n\texport const identity: MatrixFull = [\n\t\t1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,\n\t];\n\n\texport function isEqual(m: Matrix, n: Matrix): boolean {\n\t\tfor (let i = 0; i < 16; i++) {\n\t\t\tif (m[i] !== n[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\texport function simplify(matrix: Matrix | null | undefined): Matrix {\n\t\treturn matrix ?? identity;\n\t\t// if (matrix) {\n\t\t// \tif (matrix.every((v, i) => v === identity[i])) {\n\t\t// \t\treturn 0;\n\t\t// \t} else {\n\t\t// \t\treturn matrix;\n\t\t// \t}\n\t\t// } else {\n\t\t// \treturn 0;\n\t\t// }\n\t}\n\n\texport function applyMatrix4(m: Matrix, array: TypedArray): typeof array {\n\t\tconst ret = array.slice(0);\n\t\t// prettier-ignore\n\t\tfor (var i = 0, il = array.length; i < il; i += 3) {\n\t\t\tconst w = 1 / (m[3] * array[i] + m[7] * array[i + 1] + m[11] * array[i + 2] + m[15])\n\t\t\tret[i] = (m[0] * array[i] + m[4] * array[i + 1] + m[8] * array[i + 2] + m[12]) * w\n\t\t\tret[i + 1] = (m[1] * array[i] + m[5] * array[i + 1] + m[9] * array[i + 2] + m[13]) * w\n\t\t\tret[i + 2] = (m[2] * array[i] + m[6] * array[i + 1] + m[10] * array[i + 2] + m[14]) * w\n\t\t}\n\t\treturn ret;\n\t}\n\n\t/**\n\t * @param m 4x4 matrix of which the upper 3x3 is used to transform the input array\n\t * @param array\n\t * @returns new array with the matrix tranformations applied\n\t */\n\texport function applyMatrix3Components(\n\t\tm: Matrix,\n\t\tarray: TypedArray\n\t): typeof array {\n\t\tconst ret = array.slice(0);\n\t\t// prettier-ignore\n\t\tfor (var i = 0, il = array.length; i < il; i += 3) {\n\t\t\tret[i] = m[0] * array[i] + m[4] * array[i + 1] + m[8] * array[i + 2]\n\t\t\tret[i + 1] = m[1] * array[i] + m[5] * array[i + 1] + m[9] * array[i + 2]\n\t\t\tret[i + 2] = m[2] * array[i] + m[6] * array[i + 1] + m[10] * array[i + 2]\n\t\t}\n\t\treturn ret;\n\t}\n}\n\nexport type Size2D = {\n\treadonly width: number;\n\treadonly height: number;\n};\n\nexport type Size3D = Size2D & {\n\treadonly depth: number;\n};\n\nexport type RGB = {\n\treadonly r: number;\n\treadonly g: number;\n\treadonly b: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace RGB {\n\texport const white: RGB = { r: 1, g: 1, b: 1 };\n\texport const red: RGB = { r: 1, g: 0, b: 0 };\n\texport const black: RGB = { r: 0, g: 0, b: 0 };\n\texport function toRgb255a1(rgb: RGB): RGBA {\n\t\treturn {\n\t\t\tr: Math.round(rgb.r * 255),\n\t\t\tg: Math.round(rgb.g * 255),\n\t\t\tb: Math.round(rgb.b * 255),\n\t\t\ta: 1,\n\t\t};\n\t}\n\n\texport function clone(c: RGB): RGB {\n\t\treturn { r: c.r, g: c.g, b: c.b };\n\t}\n\texport function fromHex(hex: number): RGB {\n\t\thex = Math.floor(hex);\n\t\treturn {\n\t\t\tr: ((hex >> 16) & 255) / 255,\n\t\t\tg: ((hex >> 8) & 255) / 255,\n\t\t\tb: (hex & 255) / 255,\n\t\t};\n\t}\n\texport function equals(v: RGB, w: RGB) {\n\t\treturn v.r === w.r && v.g === w.g && v.b === w.b;\n\t}\n\texport function lerp(v: RGB, w: RGB, t: number) {\n\t\treturn {\n\t\t\tr: v.r + (w.r - v.r) * t,\n\t\t\tg: v.g + (w.g - v.g) * t,\n\t\t\tb: v.b + (w.b - v.b) * t,\n\t\t};\n\t}\n}\n\nexport type RGBA = RGB & { a: number }; // 0~1\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace RGBA {\n\texport const white: RGBA = { ...RGB.white, a: 1 };\n\n\texport function from0to1(vs: Vector4): RGBA {\n\t\treturn { r: vs[0], g: vs[1], b: vs[2], a: vs[3] };\n\t}\n\texport function fromHexAndA(hex: number, a: number): RGBA {\n\t\treturn { ...RGB.fromHex(hex), a };\n\t}\n\n\texport function toRgb255a1(rgb: RGBA): RGBA {\n\t\treturn {\n\t\t\tr: Math.round(rgb.r * 255),\n\t\t\tg: Math.round(rgb.g * 255),\n\t\t\tb: Math.round(rgb.b * 255),\n\t\t\ta: rgb.a,\n\t\t};\n\t}\n\texport function equals(v: RGBA, w: RGBA) {\n\t\treturn RGB.equals(v, w) && v.a === w.a;\n\t}\n}\n\nexport type TransformState = {\n\treadonly scale: Vector3;\n\treadonly rotation: Rotation;\n\treadonly position: Vector3;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace TransformState {\n\texport const identity: TransformState = {\n\t\tposition: [0, 0, 0],\n\t\trotation: [0, 0, 0],\n\t\tscale: [1, 1, 1],\n\t};\n}\n\nexport type Nullable<T> = {\n\t[P in keyof T]?: T[P] | null;\n};\n\nexport type Sharable<T> = T | Ref<T>;\n\nexport enum BlendFunction {\n\tSKIP = 0,\n\tADD = 1,\n\tALPHA = 2,\n\tAVERAGE = 3,\n\tCOLOR_BURN = 4,\n\tCOLOR_DODGE = 5,\n\tDARKEN = 6,\n\tDIFFERENCE = 7,\n\tEXCLUSION = 8,\n\tLIGHTEN = 9,\n\tMULTIPLY = 10,\n\tDIVIDE = 11,\n\tNEGATION = 12,\n\tNORMAL = 13,\n\tOVERLAY = 14,\n\tREFLECT = 15,\n\tSCREEN = 16,\n\tSOFT_LIGHT = 17,\n\tSUBTRACT = 18,\n}\n\nexport enum EASING_TYPE {\n\tLINEAR = 0,\n\tEASE = 1,\n\tEASE_IN = 2,\n\tEASE_OUT = 3,\n\tEASE_IN_OUT = 4,\n\tCUBIC = 5,\n\tSPRING = 6,\n}\n\nexport type Spring = {\n\treadonly mass: number;\n\treadonly stiffness: number;\n\treadonly damping: number;\n\treadonly velocity: number;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Spring {\n\texport const defaultData: Spring = {\n\t\tmass: 1,\n\t\tstiffness: 80,\n\t\tdamping: 10,\n\t\tvelocity: 0,\n\t};\n}\n\nexport type CubicEasingData = {\n\treadonly control1: Vector2;\n\treadonly control2: Vector2;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace CubicEasingData {\n\texport const defaultData: CubicEasingData = {\n\t\tcontrol1: [0.5, 0.05],\n\t\tcontrol2: [0.1, 0.3],\n\t};\n}\n\nexport type Easing =\n\t| {\n\t\t\treadonly easing:\n\t\t\t\t| EASING_TYPE.LINEAR\n\t\t\t\t| EASING_TYPE.EASE\n\t\t\t\t| EASING_TYPE.EASE_IN\n\t\t\t\t| EASING_TYPE.EASE_OUT\n\t\t\t\t| EASING_TYPE.EASE_IN_OUT;\n\t }\n\t| (CubicEasingData & {\n\t\t\treadonly easing: EASING_TYPE.CUBIC;\n\t })\n\t| (Spring & {\n\t\t\treadonly easing: EASING_TYPE.SPRING;\n\t });\n", "import { TransformState } from './primitives';\nimport { Vector3, Axis } from './primitives';\n\nexport type ClonerType = 'radial' | 'linear' | 'grid';\n\nexport type ClonerState = {\n\treadonly type: ClonerType;\n\treadonly hideBase: boolean;\n\treadonly count: number; // not for grid\n\treadonly radial: TransformState & {\n\t\treadonly radius: number;\n\t\treadonly start: number;\n\t\treadonly end: number;\n\t\treadonly alignment: boolean;\n\t\treadonly axis: Axis;\n\t};\n\treadonly linear: TransformState & {};\n\treadonly grid: {\n\t\treadonly count: Vector3;\n\t\treadonly size: Vector3;\n\t\treadonly useCenter: boolean;\n\t};\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace ClonerState {\n\texport function defaultData(size: Vector3, margin = 0.1): ClonerState {\n\t\treturn {\n\t\t\ttype: 'radial',\n\t\t\thideBase: false,\n\t\t\tcount: 3,\n\t\t\tradial: {\n\t\t\t\tradius: Math.max(size[0], size[1]) * 2,\n\t\t\t\tstart: 0,\n\t\t\t\tend: 360,\n\t\t\t\talignment: false,\n\t\t\t\taxis: Axis.y,\n\t\t\t\tscale: [0, 0, 0],\n\t\t\t\trotation: [0, 0, 0],\n\t\t\t\tposition: [0, 0, 0],\n\t\t\t},\n\t\t\tlinear: {\n\t\t\t\tscale: [0, 0, 0],\n\t\t\t\trotation: [0, 0, 0],\n\t\t\t\tposition: [size[0] + size[0] * margin, 0, 0],\n\t\t\t},\n\t\t\tgrid: {\n\t\t\t\tcount: [2, 2, 2],\n\t\t\t\tsize: size.map((i) => i * (1 + margin)) as unknown as Vector3,\n\t\t\t\tuseCenter: true,\n\t\t\t},\n\t\t};\n\t}\n}\n", "export enum ObjOpType {\n\tUpdate = 0, // for plain objects\n}\n\nexport enum TableOpType {\n\tAdd = 1,\n\tDelete = 2,\n\tUnlink = 3,\n}\n\nexport enum SeqOpType {\n\tAdd = 4,\n\tDelete = 5,\n\tMove = 6,\n}\n\nexport enum TreeOpType {\n\tAdd = 7,\n\tDelete = 8,\n\tMove = 9,\n}\n", "import { CollabDataOpResult, IdMapped } from './generics';\nimport { TableOpType } from './optype';\n\nexport class Table<T> implements IdMapped<T> {\n\treadonly [key: string]: T;\n\n\t// @ts-ignore\n\tmodifyById(id: string, item: T) {\n\t\tconst t = this as any;\n\t\tconst prev = t[id];\n\t\tif (prev === undefined) {\n\t\t\tthrow new Error('not expected');\n\t\t} else {\n\t\t\tconst ret = { ...t, [id]: item };\n\t\t\tObject.setPrototypeOf(ret, Table.prototype);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t// @ts-ignore\n\tadd(id: string, data: T): Table<T> {\n\t\tlet run = this.runOp({ type: TableOpType.Add, id, data });\n\t\treturn run?.data ?? this;\n\t}\n\n\t// @ts-ignore\n\trunOp(op: TableOp<T>): TableOpResult<T> {\n\t\tconst t = this as any;\n\t\tif (op.type === TableOpType.Add) {\n\t\t\tlet prev = t[op.id];\n\t\t\tlet rev: TableOp<T>;\n\t\t\tif (prev === undefined) {\n\t\t\t\trev = { type: TableOpType.Delete, id: op.id };\n\t\t\t} else {\n\t\t\t\trev = { type: TableOpType.Add, id: op.id, data: prev };\n\t\t\t}\n\t\t\tconst { id, data } = op;\n\t\t\tlet d = { ...t, [id]: data };\n\t\t\tObject.setPrototypeOf(d, Table.prototype);\n\t\t\treturn {\n\t\t\t\tdata: d,\n\t\t\t\tactual: op,\n\t\t\t\treverse: rev,\n\t\t\t};\n\t\t} else if (op.type === TableOpType.Delete) {\n\t\t\tconst { id } = op;\n\t\t\tconst prev = t[id];\n\t\t\tif (prev === undefined) {\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tconst data = { ...t };\n\t\t\t\tObject.setPrototypeOf(data, Table.prototype);\n\t\t\t\tdelete data[id];\n\t\t\t\treturn {\n\t\t\t\t\tdata,\n\t\t\t\t\tactual: op,\n\t\t\t\t\treverse: { type: TableOpType.Add, id, data: prev },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tthrow new Error('illegal arg');\n\t}\n}\n\nexport type TableAddOp<T> = {\n\ttype: TableOpType.Add;\n\tid: string;\n\tdata: T;\n};\n\nexport type TableDeleteOp = {\n\ttype: TableOpType.Delete;\n\tid: string;\n};\n\nexport type TableUnlinkOp = {\n\ttype: TableOpType.Unlink;\n\tid: string;\n};\n\nexport type TableOp<T> = TableAddOp<T> | TableDeleteOp | TableUnlinkOp;\n\nexport type TableOpResult<T> = CollabDataOpResult<Table<T>, TableOp<T>>;\n", "/**\n * copied utility, so this package has zero dependency\n */\nexport function deepFreeze(object: any) {\n\tif (object.deepFreeze !== undefined) {\n\t\tobject.deepFreeze(object);\n\t\treturn;\n\t}\n\t// Retrieve the property names defined on object\n\tconst propNames = Object.getOwnPropertyNames(object);\n\n\t// Freeze properties before freezing self\n\n\tfor (const name of propNames) {\n\t\tconst value = object[name];\n\n\t\tif (value && typeof value === 'object') {\n\t\t\tdeepFreeze(value);\n\t\t}\n\t}\n\n\treturn Object.freeze(object);\n}\n\n/**\n * alphabetical/dictionary order, elements of `a`/`b` are compared by `<`/`>`\n */\nexport function dirSort<T>(a: T[], b: T[]): number {\n\tlet i = 0;\n\twhile (i < a.length && i < b.length) {\n\t\tif (a[i] < b[i]) {\n\t\t\treturn -1;\n\t\t} else if (a[i] > b[i]) {\n\t\t\treturn 1;\n\t\t}\n\t\ti += 1;\n\t}\n\tif (i !== b.length) {\n\t\treturn -1;\n\t} else if (i !== a.length) {\n\t\treturn 1;\n\t} else {\n\t\treturn 0;\n\t}\n}\n", "export class IllegalOpError extends Error {}\n", "export function randomFiBetween(\n\ta: number | undefined,\n\tb: number | undefined,\n\tcount: number\n): number[] {\n\tif (a === undefined) {\n\t\tif (b === undefined) {\n\t\t\ta = 0;\n\t\t\tb = 10;\n\t\t} else {\n\t\t\ta = b - 10;\n\t\t}\n\t} else if (b === undefined) {\n\t\tb = a + 10;\n\t}\n\tif (a > b) {\n\t\tlet t = a;\n\t\ta = b;\n\t\tb = t;\n\t}\n\tconst arr: number[] = [];\n\tlet fraction = 1 / (count + 1);\n\tfor (let i = 0; i < count; i++) {\n\t\tconst num = a + (b - a) * (i + 0.75 + Math.random() * 0.5) * fraction;\n\t\tarr.push(num);\n\t}\n\treturn arr;\n}\n\nexport type TypedArray =\n\t| Uint8Array\n\t| Uint16Array\n\t| Uint32Array\n\t| Int8Array\n\t| Int16Array\n\t| Int32Array\n\t| Float32Array\n\t| Float64Array;\n\nexport function isTypedArray(obj: any) {\n\treturn (\n\t\tobj instanceof Uint8Array ||\n\t\tobj instanceof Uint16Array ||\n\t\tobj instanceof Uint32Array ||\n\t\tobj instanceof Int8Array ||\n\t\tobj instanceof Int16Array ||\n\t\tobj instanceof Int32Array ||\n\t\tobj instanceof Float32Array ||\n\t\tobj instanceof Float64Array\n\t);\n}\n\nexport function isNode() {\n\treturn typeof process !== 'undefined';\n}\n", "import { deepFreeze, dirSort } from './commonUtils';\nimport { IllegalOpError } from './error';\nimport { CollabDataOpResult, FiId, LocalIndex } from './generics';\nimport { TreeOpType } from './optype';\nimport { randomFiBetween } from './util';\n\nexport type TreeData<T> = {\n\treadonly data: T;\n\treadonly children: TreeData<T>[];\n};\n\nexport type TreeItem<T> = FiId & {\n\treadonly data: T;\n\treadonly children: TreeItem<T>[];\n};\n\nexport type TreeItems<T> = TreeItem<T>[];\n\nexport type TreeMoveOp = {\n\ttype: TreeOpType.Move;\n\tparent: string | null;\n\tlocalIndex?: LocalIndex;\n} & FiId;\n\nexport type TreeDeleteOp = {\n\ttype: TreeOpType.Delete;\n\tid: string;\n\tlocalIndex?: LocalIndex;\n};\n\nexport type TreeAddOp<T> = {\n\ttype: TreeOpType.Add;\n\tparent: string | null;\n\tlocalIndex?: LocalIndex;\n} & TreeItem<T>;\n\nexport type TreeOp<T> = TreeAddOp<T> | TreeDeleteOp | TreeMoveOp;\n\nexport type TreeOpResult<T> = CollabDataOpResult<Tree<T>, TreeOp<T>>;\n\nfunction traverseHelper<T>(\n\tchildren: Array<TreeItem<T>>,\n\tmap: (id: string, _: T) => void\n): void {\n\tfor (let a of children) {\n\t\tmap(a.id, a.data);\n\t\ttraverseHelper(a.children, map);\n\t}\n}\n\nfunction traverseHelperFrom<T>(\n\titem: TreeItem<T>,\n\tmap: (id: string, _: T) => void\n): void {\n\tmap(item.id, item.data);\n\tfor (let a of item.children) {\n\t\ttraverseHelperFrom(a, map);\n\t}\n}\n\n/**\n * our Tree is \"rootless\", there is no id for the root.\n * in case when you want to reference the root node, use null instead.\n */\nexport type ItemIdOrRoot = string | null;\nexport class Tree<T> extends Array<TreeItem<T>> {\n\tconstructor(...args: TreeItem<T>[]) {\n\t\tsuper(...args);\n\t\t// we seems got this problem in Node.js???\n\t\t// https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n\t\tObject.setPrototypeOf(this, Tree.prototype);\n\t}\n\tprivate objCaches?: Map<string, TreeItem<T>>;\n\t// TODO reuse these caches\n\tprivate parentCaches?: Map<string, ItemIdOrRoot>;\n\n\tprivate deepFreeze() {\n\t\tlet i = 0;\n\t\twhile (i < this.length) {\n\t\t\tdeepFreeze(this[i]);\n\t\t\ti++;\n\t\t}\n\t}\n\n\tprivate fillCaches0(item: TreeItem<T>, parent: ItemIdOrRoot) {\n\t\tif (this.objCaches?.has(item.id)) {\n\t\t\tthrow new Error('duplicated item');\n\t\t}\n\t\tthis.objCaches!.set(item.id, item);\n\t\tthis.parentCaches!.set(item.id, parent);\n\t\tfor (const c of item.children) {\n\t\t\tthis.fillCaches0(c, item.id);\n\t\t}\n\t}\n\tprivate fillCaches() {\n\t\tif (this.objCaches === undefined) {\n\t\t\tthis.objCaches = new Map();\n\t\t\tthis.parentCaches = new Map();\n\t\t\tfor (const item of this) {\n\t\t\t\tthis.fillCaches0(item, null);\n\t\t\t}\n\t\t}\n\t}\n\n\trandomId(): string | undefined {\n\t\tthis.fillCaches();\n\t\tconst keys = Array.from(this.objCaches!.keys());\n\t\tif (keys.length === 0) return undefined;\n\t\treturn keys[Math.max(0, Math.floor(Math.random() * keys.length) - 1)];\n\t}\n\n\tisDescendantOf(id: ItemIdOrRoot, parent: ItemIdOrRoot): boolean {\n\t\twhile (id) {\n\t\t\tlet p = this.parent(id)!;\n\t\t\tif (p === parent) return true;\n\t\t\tid = p;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdata(id: string): T | undefined {\n\t\treturn this.get(id)?.data;\n\t}\n\n\thas(id: ItemIdOrRoot): boolean {\n\t\treturn this.childrenOf(id) !== undefined;\n\t}\n\n\tget(id: string): TreeItem<T> | undefined {\n\t\tthis.fillCaches();\n\t\treturn this.objCaches!.get(id);\n\t}\n\n\tchildrenOf(id: ItemIdOrRoot): TreeItem<T>[] | undefined {\n\t\tif (id === null) {\n\t\t\treturn this;\n\t\t} else {\n\t\t\treturn this.get(id)?.children;\n\t\t}\n\t}\n\n\ttraverseFrom(id: string | null, map: (id: string, _: T) => void): void {\n\t\tif (id === null) {\n\t\t\tthis.traverse(map);\n\t\t} else {\n\t\t\tconst item = this.get(id);\n\t\t\tif (item) {\n\t\t\t\ttraverseHelperFrom(item, map);\n\t\t\t}\n\t\t}\n\t}\n\n\ttraverse(map: (id: string, _: T) => void): void {\n\t\ttraverseHelper(this, map);\n\t}\n\n\ttotalSize(): number {\n\t\tthis.fillCaches();\n\t\treturn this.objCaches!.size;\n\t}\n\n\tparent(id: string): ItemIdOrRoot | undefined {\n\t\tthis.fillCaches();\n\t\treturn this.parentCaches!.get(id);\n\t}\n\n\tprivate childrenArray(parent: ItemIdOrRoot): TreeItem<T>[] {\n\t\tif (parent === null) {\n\t\t\treturn this;\n\t\t} else {\n\t\t\treturn this.get(parent)!.children;\n\t\t}\n\t}\n\n\tmodifyById(id: string, data: T): Tree<T> {\n\t\tconst prev = this.get(id);\n\t\tif (prev === undefined) {\n\t\t\tthrow new Error('not expected');\n\t\t} else {\n\t\t\tconst arrayId: ItemIdOrRoot = this.parent(id) as ItemIdOrRoot;\n\t\t\tlet childrenArray: TreeItem<T>[] = this.childrenArray(arrayId);\n\t\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\t\tif (index < 0) throw new Error('not expected');\n\t\t\tconst prev = childrenArray[index];\n\t\t\tchildrenArray = [...childrenArray];\n\t\t\tchildrenArray[index] = { ...prev, data };\n\t\t\tconst newData = this.modifyArrayBy(arrayId, childrenArray);\n\t\t\treturn newData;\n\t\t}\n\t}\n\n\tprivate modifyArrayBy(\n\t\tarrayId0: ItemIdOrRoot,\n\t\tchildrenArray0: TreeItem<T>[]\n\t): Tree<T> {\n\t\tlet arrayId: ItemIdOrRoot = arrayId0;\n\t\tlet childrenArray: TreeItems<T> = childrenArray0;\n\t\twhile (arrayId !== null) {\n\t\t\tconst prevArray = childrenArray;\n\t\t\tconst prevId = arrayId;\n\t\t\tarrayId = this.parent(arrayId) as ItemIdOrRoot;\n\t\t\tif (arrayId === undefined) throw new Error();\n\t\t\tchildrenArray = this.childrenArray(arrayId);\n\t\t\tconst index = childrenArray.findIndex((a) => a.id === prevId);\n\t\t\tif (index < 0) throw new Error();\n\t\t\tchildrenArray = [...childrenArray];\n\t\t\tchildrenArray[index] = { ...childrenArray[index], children: prevArray };\n\t\t}\n\t\tObject.setPrototypeOf(childrenArray, Tree.prototype);\n\t\tconst newData: Tree<T> = childrenArray as Tree<T>;\n\t\t// TODO this is to detect duplicated ids\n\t\tnewData.fillCaches();\n\t\treturn newData;\n\t}\n\n\trunOp(op: TreeOp<T>): TreeOpResult<T> {\n\t\tswitch (op.type) {\n\t\t\tcase TreeOpType.Add:\n\t\t\t\treturn this.addOp(op);\n\t\t\tcase TreeOpType.Delete:\n\t\t\t\treturn this.deleteOp(op);\n\t\t\tcase TreeOpType.Move:\n\t\t\t\treturn this.moveOp(op);\n\t\t}\n\t}\n\n\taddOp(op: TreeOp<T> & { type: TreeOpType.Add }): TreeOpResult<T> {\n\t\tconst { parent, fi, id, data, children } = op;\n\t\tif (parent !== null && this.get(parent) === undefined) {\n\t\t\treturn null; // adding to deleted node is a noop\n\t\t} else if (this.get(id) !== undefined) {\n\t\t\treturn null; // this mostly happens when resend on reconnect, the easy thing is just ignore the message entirely\n\t\t} else {\n\t\t\tlet arrayId: ItemIdOrRoot = parent;\n\t\t\tlet childrenArray: TreeItem<T>[] = this.childrenArray(arrayId);\n\t\t\tconst item = { fi, id, data, children };\n\t\t\tchildrenArray = [...childrenArray, item];\n\t\t\tchildrenArray.sort((a, b) => a.fi - b.fi);\n\t\t\top.localIndex = childrenArray.indexOf(item);\n\t\t\tconst newData = this.modifyArrayBy(arrayId, childrenArray);\n\t\t\treturn {\n\t\t\t\tdata: newData,\n\t\t\t\tactual: op,\n\t\t\t\treverse: { type: TreeOpType.Delete, id },\n\t\t\t};\n\t\t}\n\t}\n\n\tdeleteOp(op: TreeOp<T> & { type: TreeOpType.Delete }): TreeOpResult<T> {\n\t\tconst { id } = op;\n\t\tif (this.get(id) === null) {\n\t\t\t// delete an deleted node is a noop\n\t\t\treturn null;\n\t\t} else {\n\t\t\tlet arrayId = this.parent(id);\n\t\t\t// delete non exist item is noop\n\t\t\tif (arrayId === undefined) return null;\n\t\t\tlet childrenArray = this.childrenArray(arrayId);\n\t\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\t\top.localIndex = index;\n\t\t\tchildrenArray = [...childrenArray];\n\t\t\tconst item = childrenArray.splice(index, 1)[0];\n\t\t\tconst newData = this.modifyArrayBy(arrayId, childrenArray);\n\t\t\treturn {\n\t\t\t\tdata: newData,\n\t\t\t\tactual: op,\n\t\t\t\treverse: { type: TreeOpType.Add, ...item, parent: arrayId },\n\t\t\t};\n\t\t}\n\t}\n\n\tmoveOp(op: TreeOp<T> & { type: TreeOpType.Move }): TreeOpResult<T> {\n\t\tconst { parent, fi, id } = op;\n\t\tif (parent !== null && this.get(parent) === undefined) {\n\t\t\t// moving inside a deleted node is considered a deletion\n\t\t\treturn this.deleteOp({ type: TreeOpType.Delete, id });\n\t\t} else if (parent !== null) {\n\t\t\tlet current: ItemIdOrRoot = parent;\n\t\t\twhile (current !== null) {\n\t\t\t\tif (current === undefined) throw new Error();\n\t\t\t\tif (current === id) {\n\t\t\t\t\tthrow new IllegalOpError('cyclic tree');\n\t\t\t\t}\n\t\t\t\tcurrent = this.parent(current) as ItemIdOrRoot;\n\t\t\t}\n\t\t}\n\t\tlet arrayId = this.parent(id);\n\t\t// moving a unknown node, nothing should be done\n\t\tif (arrayId === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\tconst prevParent = arrayId;\n\t\tlet childrenArray = this.childrenArray(arrayId);\n\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\tchildrenArray = [...childrenArray];\n\t\tlet item = childrenArray.splice(index, 1)[0];\n\t\tlet newData = this.modifyArrayBy(arrayId, childrenArray);\n\t\tarrayId = parent;\n\t\tchildrenArray = newData.childrenArray(arrayId);\n\t\tconst prevFi = item.fi;\n\t\titem = { ...item, fi };\n\t\tchildrenArray = [...childrenArray, item];\n\t\tchildrenArray.sort((a, b) => a.fi - b.fi);\n\t\top.localIndex = childrenArray.indexOf(item);\n\t\tnewData = newData.modifyArrayBy(arrayId, childrenArray);\n\t\treturn {\n\t\t\tdata: newData,\n\t\t\tactual: op,\n\t\t\treverse: { type: TreeOpType.Move, parent: prevParent, fi: prevFi, id },\n\t\t};\n\t}\n\n\t/**\n\t * previous id of a given object, if null or not find, return the last object id if not empty\n\t */\n\tprevious(parent: ItemIdOrRoot, child: ItemIdOrRoot): ItemIdOrRoot {\n\t\tif (child === null) {\n\t\t\tlet arr = this.childrenArray(parent);\n\t\t\treturn arr.length === 0 ? null : arr[arr.length - 1].id;\n\t\t}\n\t\tlet previous = null;\n\t\tfor (let c of this.childrenArray(parent)) {\n\t\t\tif (c.id === child) {\n\t\t\t\treturn previous;\n\t\t\t}\n\t\t\tprevious = c.id;\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate traverseSortNext(id: string): string | undefined {\n\t\tconst p = this.parent(id);\n\t\tif (p !== undefined) {\n\t\t\tconst children = this.childrenArray(p);\n\t\t\tconst i = children.findIndex((c) => c.id === id) + 1;\n\t\t\tif (i < children.length) return children[i].id;\n\t\t\tif (p) return this.traverseSortNext(p);\n\t\t}\n\t}\n\n\t/**\n\t * return next id by preorder traversal\n\t */\n\tsortNext(id: string): string | undefined {\n\t\tconst children = this.childrenArray(id);\n\t\tif (children.length > 0) return children[0].id;\n\t\treturn this.traverseSortNext(id);\n\t}\n\n\tprivate traverseSortPrevious(id: string): string {\n\t\tconst children = this.childrenArray(id);\n\t\tif (children.length > 0)\n\t\t\treturn this.traverseSortPrevious(children[children.length - 1].id);\n\t\treturn id;\n\t}\n\n\t/**\n\t * return previous id by preorder traversal\n\t */\n\tsortPrevious(id: string): string | null | undefined {\n\t\tconst p = this.parent(id);\n\t\tif (p !== undefined) {\n\t\t\tconst children = this.childrenArray(p);\n\t\t\tconst i = children.findIndex((c) => c.id === id) - 1;\n\t\t\tif (i >= 0) return this.traverseSortPrevious(children[i].id);\n\t\t\treturn p;\n\t\t}\n\t}\n\n\t/**\n\t * get objects by the order they appear visually in object tree\n\t */\n\tgetAllSorted<E>(\n\t\tselection: ({ id: string } & E)[]\n\t): (TreeItem<T> & Omit<E, 'id'>)[] {\n\t\tlet objs: (TreeItem<T> & Omit<E, 'id'>)[] = [];\n\t\tfor (let s of selection) {\n\t\t\tlet obj = this.getWithSortKey(s.id);\n\t\t\tif (obj !== undefined) {\n\t\t\t\tobjs.push({ ...s, ...obj });\n\t\t\t}\n\t\t}\n\t\tobjs.sort((a, b) => dirSort((a as any).sortKey, (b as any).sortKey));\n\t\tfor (let s of objs) {\n\t\t\tdelete (s as any).sortKey;\n\t\t}\n\t\treturn objs;\n\t}\n\n\t/**\n\t * return the item and the indexes to get to the item from root to the item\n\t */\n\tgetWithSortKey(\n\t\tid0: string\n\t): (TreeItem<T> & { sortKey: number[] }) | undefined {\n\t\tvar id: ItemIdOrRoot = id0;\n\t\tlet ns: number[] = [];\n\t\tlet obj = this.get(id)!;\n\t\tlet obj0 = obj;\n\t\tif (obj === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\twhile (id) {\n\t\t\tns.splice(0, 0, obj.fi);\n\t\t\tid = this.parent(id)!;\n\t\t\tif (id !== null) {\n\t\t\t\tobj = this.get(id)!;\n\t\t\t}\n\t\t}\n\t\treturn { ...obj0, sortKey: ns };\n\t}\n\n\tinsertBeforeHelper(\n\t\tparent: ItemIdOrRoot,\n\t\tsibling: ItemIdOrRoot,\n\t\tcount: number\n\t): number[] {\n\t\treturn this.insertAfterHelper(\n\t\t\tparent,\n\t\t\tthis.previous(parent, sibling),\n\t\t\tcount\n\t\t);\n\t}\n\n\tinsertAfterHelper(\n\t\tparent: ItemIdOrRoot,\n\t\tprevious: ItemIdOrRoot,\n\t\tcount: number\n\t): number[] {\n\t\tconst sorted = this.childrenArray(parent);\n\t\tif (previous === null) {\n\t\t\tif (sorted.length === 0) {\n\t\t\t\treturn randomFiBetween(0, count, count);\n\t\t\t} else {\n\t\t\t\tconst base = sorted[0].fi;\n\t\t\t\treturn randomFiBetween(base - count, base, count);\n\t\t\t}\n\t\t} else {\n\t\t\tconst previousItem = this.get(previous);\n\t\t\tif (previousItem === undefined || this.parent(previous) !== parent) {\n\t\t\t\tthrow new Error('illegal args');\n\t\t\t}\n\t\t\tconst nextItem = sorted.find((a) => a.fi > previousItem.fi);\n\t\t\tif (nextItem === undefined) {\n\t\t\t\tconst base = sorted[sorted.length - 1].fi;\n\t\t\t\treturn randomFiBetween(base, base + count, count);\n\t\t\t} else {\n\t\t\t\treturn randomFiBetween(previousItem.fi, nextItem.fi, count);\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { CollabDataOpResult } from './generics';\nimport { ObjOpType } from './optype';\n\nexport type KeyValData = { [key: string]: any };\n\nexport type ObjUpdateOp<T> = {\n\treadonly type: ObjOpType.Update;\n\treadonly props: Partial<T>;\n};\n\n/**\n * An operation that updates the properties of an object.\n *\n * ```typescript\n * let someObj = { f: { a: 0, b: 0 } }\n * someObj.f.a = 1\n * someObj.f.b = 2\n * ```\n *\n * It will produce a single {@link ObjUpdateOp} with:\n * * path = [`f`]\n * * props = { a: 1, b: 2 }\n */\nexport type ObjOp<T> = ObjUpdateOp<T>;\nexport namespace ObjOp {\n\texport function runOp<T>(\n\t\tdata: T,\n\t\top: ObjOp<T>\n\t): CollabDataOpResult<T, ObjOp<T>> {\n\t\tif (Array.isArray(data)) {\n\t\t\tconst props: any = op.props;\n\t\t\tlet reverseprops: any = {};\n\t\t\tlet ret: any = [...data];\n\t\t\tlet updated = false;\n\t\t\tif (props) {\n\t\t\t\tfor (let id0 of Object.keys(props)) {\n\t\t\t\t\tlet id = parseInt(id0);\n\t\t\t\t\tif (isNaN(id)) {\n\t\t\t\t\t\tthrow new Error('wrong index');\n\t\t\t\t\t}\n\t\t\t\t\treverseprops[id0] = ret[id];\n\t\t\t\t\tret[id] = props[id0];\n\t\t\t\t\tupdated = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (updated) {\n\t\t\t\treturn {\n\t\t\t\t\tdata: ret,\n\t\t\t\t\tactual: op,\n\t\t\t\t\treverse: {\n\t\t\t\t\t\ttype: ObjOpType.Update,\n\t\t\t\t\t\tprops: reverseprops,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t} else {\n\t\t\tconst props: any = op.props;\n\t\t\tlet reverseprops: any = {};\n\t\t\tlet ret: any = { ...data };\n\t\t\tlet updated = false;\n\t\t\tif (props) {\n\t\t\t\tfor (const id of Object.keys(props)) {\n\t\t\t\t\treverseprops[id] = ret[id];\n\t\t\t\t\tret[id] = props[id];\n\t\t\t\t\tupdated = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (updated) {\n\t\t\t\treturn {\n\t\t\t\t\tdata: ret,\n\t\t\t\t\tactual: op,\n\t\t\t\t\treverse: {\n\t\t\t\t\t\ttype: ObjOpType.Update,\n\t\t\t\t\t\tprops: reverseprops,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { CollabDataOpResult, FiId } from './generics';\nimport { SeqOpType } from './optype';\nimport { isNode, randomFiBetween } from './util';\nimport { deepFreeze } from './commonUtils';\nimport { LocalIndex } from '.';\n\nexport type SeqItem<T> = FiId & { readonly data: T };\n\nexport type SeqAddOp<T> = {\n\ttype: SeqOpType.Add;\n\tlocalIndex?: LocalIndex;\n} & SeqItem<T>;\n\nexport type SeqDeleteOp = {\n\ttype: SeqOpType.Delete;\n\tid: string;\n\tlocalIndex?: LocalIndex;\n};\n\nexport type SeqMoveOp = {\n\ttype: SeqOpType.Move;\n\tlocalIndex?: LocalIndex;\n} & FiId;\n\n/**\n * For a {@link Seq} object, you can perform 3 type of operations, Add, Delete and Move.\n */\nexport type SeqOp<T> = SeqAddOp<T> | SeqDeleteOp | SeqMoveOp;\n\nexport type SeqOpResult<T> = CollabDataOpResult<Seq<T>, SeqOp<T>>;\n\nexport class Seq<T> extends Array<SeqItem<T>> {\n\tconstructor(...args: SeqItem<T>[]) {\n\t\tsuper(...args);\n\t\t// we seems got this problem in Node.js???\n\t\t// https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n\t\tObject.setPrototypeOf(this, Seq.prototype);\n\t}\n\tprivate deepFreeze() {\n\t\tlet i = 0;\n\t\twhile (i < this.length) {\n\t\t\tdeepFreeze(this[i]);\n\t\t\ti++;\n\t\t}\n\t}\n\n\tprivate objCaches?: Map<string, SeqItem<T>>;\n\n\tprivate fillCaches0(item: SeqItem<T>) {\n\t\t// TODO for some reason we are not going to check this know in server side, I think some legacy file will fails to have unique ids\n\t\t// if (!isNode()) {\n\t\t// \tif (this.objCaches?.has(item.id)) {\n\t\t// \t\tthrow new Error('duplicated item');\n\t\t// \t}\n\t\t// }\n\t\tthis.objCaches!.set(item.id, item);\n\t}\n\tprivate fillCaches() {\n\t\tif (this.objCaches === undefined) {\n\t\t\tthis.objCaches = new Map();\n\t\t\tObject.getOwnPropertyDescriptor(this, 'objCaches')!.enumerable = false;\n\t\t\tfor (const item of this) {\n\t\t\t\tthis.fillCaches0(item);\n\t\t\t}\n\t\t}\n\t}\n\n\trandomId(): string | undefined {\n\t\tthis.fillCaches();\n\t\tconst keys = Array.from(this.objCaches!.keys());\n\t\tif (keys.length === 0) return undefined;\n\t\treturn keys[Math.max(0, Math.floor(Math.random() * keys.length) - 1)];\n\t}\n\n\tdata(id: string): T | undefined {\n\t\treturn this.get(id)?.data;\n\t}\n\n\tget(id: string): SeqItem<T> | undefined {\n\t\tthis.fillCaches();\n\t\treturn this.objCaches!.get(id);\n\t}\n\n\tmodifyById(id: string, data: T): Seq<T> {\n\t\tconst prev = this.get(id);\n\t\tif (prev === undefined) {\n\t\t\tthrow new Error('not expected');\n\t\t} else {\n\t\t\tlet childrenArray: SeqItem<T>[] = this;\n\t\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\t\tif (index < 0) throw new Error('not expected');\n\t\t\tconst prev = childrenArray[index];\n\t\t\tchildrenArray = [...childrenArray];\n\t\t\tchildrenArray[index] = { ...prev, data };\n\t\t\tconst newData = this.modifyArrayBy(childrenArray);\n\t\t\treturn newData;\n\t\t}\n\t}\n\n\tprivate modifyArrayBy(childrenArray: SeqItem<T>[]): Seq<T> {\n\t\tObject.setPrototypeOf(childrenArray, Seq.prototype);\n\t\tconst newData: Seq<T> = childrenArray as Seq<T>;\n\t\tif (!isNode()) {\n\t\t\tnewData.fillCaches();\n\t\t}\n\t\treturn newData;\n\t}\n\n\trunOp(op: SeqOp<T>): SeqOpResult<T> {\n\t\tswitch (op.type) {\n\t\t\tcase SeqOpType.Add:\n\t\t\t\treturn this.addOp(op);\n\t\t\tcase SeqOpType.Delete:\n\t\t\t\treturn this.deleteOp(op);\n\t\t\tcase SeqOpType.Move:\n\t\t\t\treturn this.moveOp(op);\n\t\t}\n\t}\n\n\taddOp(op: SeqOp<T> & { type: SeqOpType.Add }): SeqOpResult<T> {\n\t\tconst { fi, id, data } = op;\n\t\tlet childrenArray: SeqItem<T>[] = this;\n\t\tconst item = { fi, id, data };\n\t\tchildrenArray = [...childrenArray, item];\n\t\tchildrenArray.sort((a, b) => a.fi - b.fi);\n\t\top.localIndex = childrenArray.indexOf(item);\n\t\tconst newData = this.modifyArrayBy(childrenArray);\n\t\treturn {\n\t\t\tdata: newData,\n\t\t\tactual: op,\n\t\t\treverse: { type: SeqOpType.Delete, id },\n\t\t};\n\t}\n\n\tdeleteOp(op: SeqOp<T> & { type: SeqOpType.Delete }): SeqOpResult<T> {\n\t\tconst { id } = op;\n\t\tlet childrenArray: SeqItem<T>[] = this;\n\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\t// delete non-exist item is noop\n\t\tif (index === -1) return null;\n\t\top.localIndex = index;\n\t\tchildrenArray = [...childrenArray];\n\t\tconst item = childrenArray.splice(index, 1)[0];\n\t\tconst newData = this.modifyArrayBy(childrenArray);\n\t\treturn {\n\t\t\tdata: newData,\n\t\t\tactual: op,\n\t\t\treverse: { type: SeqOpType.Add, ...item },\n\t\t};\n\t}\n\n\tmoveOp(op: SeqOp<T> & { type: SeqOpType.Move }): SeqOpResult<T> {\n\t\tconst { fi, id } = op;\n\t\tlet childrenArray: SeqItem<T>[] = this;\n\t\tchildrenArray = [...childrenArray];\n\t\tconst index = childrenArray.findIndex((a) => a.id === id);\n\t\tif (index === -1) {\n\t\t\treturn null;\n\t\t}\n\t\tlet prevFi = childrenArray[index].fi;\n\t\tlet item = { ...childrenArray[index], fi };\n\t\tchildrenArray[index] = item;\n\t\tchildrenArray.sort((a, b) => a.fi - b.fi);\n\t\top.localIndex = childrenArray.indexOf(item);\n\t\tlet newData = this.modifyArrayBy(childrenArray);\n\t\treturn {\n\t\t\tdata: newData,\n\t\t\tactual: op,\n\t\t\treverse: { type: SeqOpType.Move, fi: prevFi, id },\n\t\t};\n\t}\n\n\t/**\n\t * previous id of a given object, if null or not find, return the last object id if not empty\n\t */\n\tprevious(child: string | null): string | null {\n\t\tif (child === null) {\n\t\t\treturn this.length === 0 ? null : this[this.length - 1].id;\n\t\t}\n\t\tlet previous = null;\n\t\tfor (let c of this) {\n\t\t\tif (c.id === child) {\n\t\t\t\treturn previous;\n\t\t\t}\n\t\t\tprevious = c.id;\n\t\t}\n\t\treturn null;\n\t}\n\n\tinsertBeforeHelper(sibling: string | null, count: number): number[] {\n\t\treturn this.insertAfterHelper(this.previous(sibling), count);\n\t}\n\n\tinsertAfterHelper(previous: string | null, count: number): number[] {\n\t\tconst sorted = this;\n\t\tif (previous === null) {\n\t\t\tif (sorted.length === 0) {\n\t\t\t\treturn randomFiBetween(0, count, count);\n\t\t\t} else {\n\t\t\t\tconst base = sorted[0].fi;\n\t\t\t\treturn randomFiBetween(base - count, base, count);\n\t\t\t}\n\t\t} else {\n\t\t\tconst previousItem = this.get(previous);\n\t\t\tif (previousItem === undefined) {\n\t\t\t\tthrow new Error('illegal args');\n\t\t\t}\n\t\t\tconst nextItem = sorted.find((a) => a.fi > previousItem.fi);\n\t\t\tif (nextItem === undefined) {\n\t\t\t\tconst base = sorted[sorted.length - 1].fi;\n\t\t\t\treturn randomFiBetween(base, base + count, count);\n\t\t\t} else {\n\t\t\t\treturn randomFiBetween(previousItem.fi, nextItem.fi, count);\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { Table } from './Table';\nimport { Tree } from './Tree';\nimport { ObjOp } from './Obj';\nimport { TableOpType, TreeOpType, ObjOpType, SeqOpType } from './optype';\nimport { Seq } from './Seq';\nimport { Path } from '.';\nimport { isTypedArray } from './util';\n\nexport const unproxySymbol = Symbol();\nlet clearSymbol = Symbol();\n\nclass BaseState {\n\treportOp(op, res) {\n\t\tlet state = this;\n\t\tif (res === null) {\n\t\t\treturn;\n\t\t}\n\t\tstate._current = res.data;\n\t\tconst _path = [];\n\t\twhile (!(state instanceof RootState)) {\n\t\t\tconst seg = state._path;\n\t\t\tconst _current = state._current;\n\t\t\tif (seg !== '') _path.splice(0, 0, seg);\n\t\t\tstate = state._parent;\n\t\t\t// removed item\n\t\t\tif (state === null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate.update(seg, _current);\n\t\t}\n\t\tstate.push(_path, op, res.actual, res.reverse);\n\t}\n\n\tdeleteChildren(prop) {\n\t\tif (this._children) {\n\t\t\tconst prev = this._children[prop];\n\t\t\tif (prev) {\n\t\t\t\tconst clearFunction = prev[clearSymbol];\n\t\t\t\tif (clearFunction) {\n\t\t\t\t\tclearFunction();\n\t\t\t\t}\n\t\t\t\tdelete this._children[prop];\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass ObjectState extends BaseState {\n\tconstructor(_parent, _path, _current) {\n\t\tsuper();\n\t\tthis._parent = _parent;\n\t\tthis._path = _path;\n\t\tthis._current = _current;\n\t}\n\tupdate(seg, data) {\n\t\tif (Array.isArray(this._current)) {\n\t\t\tif (typeof seg === 'string') {\n\t\t\t\tseg = parseInt(seg);\n\t\t\t\tif (isNaN(seg)) {\n\t\t\t\t\tthrow new Error('Invalid path');\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._current = [...this._current];\n\t\t\tthis._current[seg] = data;\n\t\t} else {\n\t\t\tthis._current = { ...this._current, [seg]: data };\n\t\t}\n\t}\n\trunOp(op) {\n\t\tthis.reportOp(op, ObjOp.runOp(this._current, op));\n\t}\n}\n\nclass TableState extends BaseState {\n\tconstructor(_parent, _path, _current) {\n\t\tsuper();\n\t\tthis._parent = _parent;\n\t\tthis._path = _path;\n\t\tthis._current = _current;\n\t}\n\tupdate(seg, data) {\n\t\tthis._current = { ...this._current, [seg]: data };\n\t\tObject.setPrototypeOf(this._current, Table.prototype);\n\t}\n\trunOp(op) {\n\t\tthis.reportOp(op, this._current.runOp(op));\n\t}\n}\n\nconst objLikeTrap = {\n\tget(state, prop) {\n\t\tif (prop === clearSymbol) {\n\t\t\treturn () => {\n\t\t\t\tstate._parent = null;\n\t\t\t};\n\t\t} else if (prop === unproxySymbol) {\n\t\t\treturn state._current;\n\t\t}\n\t\tlet { _current, _children } = state;\n\t\tif (prop === 'push' && Array.isArray(_current)) {\n\t\t\tthrow new Error('not supported to expand array');\n\t\t}\n\t\tconst prev = _children === undefined ? undefined : _children[prop];\n\t\tif (prev !== undefined) {\n\t\t\treturn prev;\n\t\t}\n\t\tconst bs = _current[prop];\n\t\tconst prox = proxy(state, prop, bs);\n\t\tif (prox !== bs) {\n\t\t\tif (_children === undefined) {\n\t\t\t\t_children = {};\n\t\t\t\tstate._children = _children;\n\t\t\t}\n\t\t\t_children[prop] = prox;\n\t\t\treturn prox;\n\t\t} else {\n\t\t\treturn bs;\n\t\t}\n\t},\n\thas(state, prop) {\n\t\treturn prop in state._current;\n\t},\n\townKeys(state) {\n\t\treturn Reflect.ownKeys(state._current);\n\t},\n\tdefineProperty() {\n\t\tthrow Error('not supported');\n\t},\n\tgetPrototypeOf(state) {\n\t\treturn Object.getPrototypeOf(state._current);\n\t},\n\tsetPrototypeOf() {\n\t\tthrow Error('not supported');\n\t},\n\tgetOwnPropertyDescriptor(state, prop) {\n\t\tconst owner = state._current;\n\t\tconst desc = Reflect.getOwnPropertyDescriptor(owner, prop);\n\t\tif (!desc) return desc;\n\t\treturn {\n\t\t\twritable: true,\n\t\t\tconfigurable: true,\n\t\t\tenumerable: desc.enumerable,\n\t\t\tvalue: owner[prop],\n\t\t};\n\t},\n};\n\nconst objectTrap = {\n\t...objLikeTrap,\n\tset(state, prop, value) {\n\t\tlet op;\n\t\tif (value === undefined) {\n\t\t\tthrow new Error('set to undefined is not supported!');\n\t\t\t//op = { type: ObjOpType.Update, deletes: [prop] };\n\t\t} else {\n\t\t\top = {\n\t\t\t\ttype: ObjOpType.Update,\n\t\t\t\tprops: { [prop]: unproxy(value) ?? value },\n\t\t\t};\n\t\t}\n\t\tstate.deleteChildren(prop);\n\t\tstate.runOp(op);\n\t\treturn true;\n\t},\n\tdeleteProperty(state, prop) {\n\t\tthrow new Error('set to undefined is not supported!');\n\t\t// let op = { type: ObjOpType.Update, deletes: [prop] };\n\t\t// state.deleteChildren(prop);\n\t\t// state.runOp(op);\n\t\t// return true;\n\t},\n};\n\nconst tableTrap = {\n\t...objLikeTrap,\n\tset(state, prop, value) {\n\t\tif (value === undefined) {\n\t\t\tthis.deleteProperty(state, prop);\n\t\t} else {\n\t\t\tstate.deleteChildren(prop);\n\t\t\tstate.runOp({ type: TableOpType.Add, id: prop, data: value });\n\t\t}\n\t\treturn true;\n\t},\n\tdeleteProperty(state, prop) {\n\t\tstate.runOp({ type: TableOpType.Delete, id: prop });\n\t\treturn true;\n\t},\n};\n\nexport class ProxiedTreeState extends BaseState {\n\tconstructor(_parent, _path, _current) {\n\t\tsuper();\n\t\tthis._children = {};\n\t\tthis._parent = _parent;\n\t\tthis._path = _path;\n\t\tthis._current = _current;\n\t\tthis[clearSymbol] = () => {\n\t\t\tthis._parent = null;\n\t\t};\n\t}\n\n\tunproxy() {\n\t\treturn this._current;\n\t}\n\n\tupdate(seg, data) {\n\t\tthis._current = this._current.modifyById(seg, data);\n\t}\n\n\trunOp(op) {\n\t\tthis.reportOp(op, this._current.runOp(op));\n\t}\n\n\trandomId() {\n\t\treturn this._current.randomId();\n\t}\n\n\tisDescendantOf(id, parent) {\n\t\treturn this._current.isDescendantOf(id, parent);\n\t}\n\n\tchildrenOf(id) {\n\t\treturn this._current.childrenOf(id);\n\t}\n\n\ttraverse(map) {\n\t\treturn this._current.traverse(map);\n\t}\n\n\tget(id) {\n\t\treturn this._current.get(id);\n\t}\n\n\tparent(id) {\n\t\treturn this._current.parent(id);\n\t}\n\n\ttraverse(f) {\n\t\tthis._current.traverse((id, _) => {\n\t\t\tf(id, this.data(id));\n\t\t});\n\t}\n\n\tdata(id) {\n\t\tlet { _current, _children } = this;\n\t\tconst prev = _children === undefined ? undefined : _children[id];\n\t\tif (prev !== undefined) {\n\t\t\treturn prev;\n\t\t}\n\t\tconst bs = _current.get(id)?.data;\n\t\tconst prox = proxy(this, id, bs);\n\t\tif (prox !== bs) {\n\t\t\tif (_children === undefined) {\n\t\t\t\t_children = {};\n\t\t\t\tthis._children = _children;\n\t\t\t}\n\t\t\t_children[id] = prox;\n\t\t\treturn prox;\n\t\t} else {\n\t\t\treturn bs;\n\t\t}\n\t}\n\n\tadd(parent, fi, id, data, children) {\n\t\tthis.runOp({ type: TreeOpType.Add, parent, fi, id, data, children });\n\t}\n\n\tmove(parent, fi, id) {\n\t\tthis.runOp({ type: TreeOpType.Move, parent, fi, id });\n\t}\n\n\tinsertAfter(parent, sibling, children) {\n\t\tconst fis = this._current.insertAfterHelper(\n\t\t\tparent,\n\t\t\tsibling,\n\t\t\tchildren.length\n\t\t);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.add(parent, fis[i], child.id, child.data, child.children);\n\t\t}\n\t}\n\n\tinsertBefore(parent, sibling, children) {\n\t\tconst fis = this._current.insertBeforeHelper(\n\t\t\tparent,\n\t\t\tsibling,\n\t\t\tchildren.length\n\t\t);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.add(parent, fis[i], child.id, child.data, child.children);\n\t\t}\n\t}\n\n\tmoveAfter(parent, sibling, children) {\n\t\tconst fis = this._current.insertAfterHelper(\n\t\t\tparent,\n\t\t\tsibling,\n\t\t\tchildren.length\n\t\t);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.move(parent, fis[i], child);\n\t\t}\n\t}\n\n\tmoveBefore(parent, sibling, children) {\n\t\tconst fis = this._current.insertBeforeHelper(\n\t\t\tparent,\n\t\t\tsibling,\n\t\t\tchildren.length\n\t\t);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.move(parent, fis[i], child);\n\t\t}\n\t}\n\n\tdelete(id) {\n\t\tthis.deleteChildren(id);\n\t\tthis.runOp({ type: TreeOpType.Delete, id });\n\t}\n\n\tsortNext(id) {\n\t\treturn this._current.sortNext(id);\n\t}\n\n\tsortPrevious(id) {\n\t\treturn this._current.sortPrevious(id);\n\t}\n\n\tgetAllSorted(selection) {\n\t\treturn this._current.getAllSorted(selection);\n\t}\n}\n\nexport class ProxiedSeqState extends BaseState {\n\tconstructor(_parent, _path, _current) {\n\t\tsuper();\n\t\tthis._children = {};\n\t\tthis._parent = _parent;\n\t\tthis._path = _path;\n\t\tthis._current = _current;\n\t\tthis[clearSymbol] = () => {\n\t\t\tthis._parent = null;\n\t\t};\n\t}\n\n\tunproxy() {\n\t\treturn this._current;\n\t}\n\n\tget length() {\n\t\treturn this._current.length;\n\t}\n\n\tforEach(handler) {\n\t\tlet len = this.length;\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tlet id = this._current[i].id;\n\t\t\thandler(this.data(this._current[i].id), id);\n\t\t}\n\t}\n\n\tupdate(seg, data) {\n\t\tthis._current = this._current.modifyById(seg, data);\n\t}\n\trandomId() {\n\t\treturn this._current.randomId();\n\t}\n\tget(id) {\n\t\treturn { ...this._current.get(id), data: this.data(id) };\n\t}\n\tdata(id) {\n\t\tlet { _current, _children } = this;\n\t\tconst prev = _children === undefined ? undefined : _children[id];\n\t\tif (prev !== undefined) {\n\t\t\treturn prev;\n\t\t}\n\t\tconst bs = _current.get(id)?.data;\n\t\tconst prox = proxy(this, id, bs);\n\t\tif (prox !== bs) {\n\t\t\tif (_children === undefined) {\n\t\t\t\t_children = {};\n\t\t\t\tthis._children = _children;\n\t\t\t}\n\t\t\t_children[id] = prox;\n\t\t\treturn prox;\n\t\t} else {\n\t\t\treturn bs;\n\t\t}\n\t}\n\trunOp(op) {\n\t\tthis.reportOp(op, this._current.runOp(op));\n\t}\n\n\tadd(fi, id, data) {\n\t\tthis.runOp({ type: SeqOpType.Add, fi, id, data });\n\t}\n\n\tmove(fi, id) {\n\t\tthis.runOp({ type: SeqOpType.Move, fi, id });\n\t}\n\n\tinsertAfter(sibling, children) {\n\t\tconst fis = this._current.insertAfterHelper(sibling, children.length);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.add(fis[i], child.id, child.data);\n\t\t}\n\t}\n\n\tinsertBefore(sibling, children) {\n\t\tconst fis = this._current.insertBeforeHelper(sibling, children.length);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.add(fis[i], child.id, child.data);\n\t\t}\n\t}\n\n\tmoveAfter(sibling, children) {\n\t\tconst fis = this._current.insertAfterHelper(sibling, children.length);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.move(fis[i], child);\n\t\t}\n\t}\n\n\tmoveBefore(sibling, children) {\n\t\tconst fis = this._current.insertBeforeHelper(sibling, children.length);\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst child = children[i];\n\t\t\tthis.move(fis[i], child);\n\t\t}\n\t}\n\n\tdelete(id) {\n\t\tthis.deleteChildren(id);\n\t\tthis.runOp({ type: SeqOpType.Delete, id });\n\t}\n}\n\nfunction mergePushOps(ts, op, path) {\n\tif (ts.length > 0) {\n\t\tlet last = ts[ts.length - 1];\n\t\tif (last.type === ObjOpType.Update && op.type === ObjOpType.Update) {\n\t\t\tif (Path.equal(last.path, path)) {\n\t\t\t\t// the Ops are produced by the proxy system, safe to modify directly\n\t\t\t\tObject.assign(last.props, op.props);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tts.push({ ...op, path });\n}\n\nclass RootState {\n\tconstructor(_current) {\n\t\tthis.ts = [];\n\t\tthis.actual = [];\n\t\tthis.reverse = [];\n\t\tthis._current = _current;\n\t}\n\n\tupdate(seg, data) {\n\t\tif (seg !== '') {\n\t\t\tthrow new Error('');\n\t\t}\n\t\tthis._current = data;\n\t}\n\n\tpush(_path, op, actual, reverse) {\n\t\tmergePushOps(this.ts, op, _path);\n\t\tmergePushOps(this.actual, actual, _path);\n\t\tmergePushOps(this.reverse, reverse, _path);\n\t}\n\n\tresult() {\n\t\treturn {\n\t\t\tdata: this._current,\n\t\t\tts: this.ts,\n\t\t\tactual: this.actual,\n\t\t\treverse: this.reverse.reverse(),\n\t\t};\n\t}\n}\n\nfunction proxy(_parent, _path, _current) {\n\tif (_current instanceof Tree) {\n\t\treturn new ProxiedTreeState(_parent, _path, _current);\n\t} else if (_current instanceof Seq) {\n\t\treturn new ProxiedSeqState(_parent, _path, _current);\n\t} else if (_current instanceof Table) {\n\t\treturn new Proxy(new TableState(_parent, _path, _current), tableTrap);\n\t} else if (_current !== null && typeof _current === 'object') {\n\t\tif (isTypedArray(_current)) {\n\t\t\treturn _current;\n\t\t} else {\n\t\t\treturn new Proxy(new ObjectState(_parent, _path, _current), objectTrap);\n\t\t}\n\t} else {\n\t\treturn _current;\n\t}\n}\n\nexport function mutate(a) {\n\tconst state = new RootState(a);\n\treturn [proxy(state, '', a), state];\n}\n\nexport function mutateDirectly(a, f) {\n\tlet [p, s] = mutate(a);\n\tf(p);\n\treturn s.result();\n}\n\nexport function unproxy(a) {\n\tif (a instanceof ProxiedTreeState) {\n\t\treturn a._current;\n\t} else if (a instanceof ProxiedSeqState) {\n\t\treturn a._current;\n\t} else if (a !== null && typeof a === 'object') {\n\t\treturn a[unproxySymbol];\n\t} else {\n\t\treturn a;\n\t}\n}\n\nexport function debugLastOp(a) {\n\treturn a._parent.ts.last();\n}\n", "import { ProxiedTreeState, ProxiedSeqState } from './proxy';\nimport { Seq } from './Seq';\nimport { Tree } from './Tree';\n\n// a marker for id based reference, T not used, in general you should check if the thing is defined, because you cannot enforce a Ref is valid in collab\nexport type Ref<T> = string;\n\nexport type PathSeg = string | number;\nexport type Path = readonly PathSeg[];\n\nexport namespace Path {\n\texport function equal(path: Path, str: Path): boolean {\n\t\tif (str.length === path.length) {\n\t\t\tvar i = 0;\n\t\t\twhile (i < path.length) {\n\t\t\t\tif (path[i] === str[i]) {\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\ti += 1;\n\t\t\t}\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\texport function removeOverridden(\n\t\tpath: Path,\n\t\tprops: any,\n\t\toverriding: any\n\t): any {\n\t\tlet zoomed = zoom(overriding, path);\n\t\tif (zoomed !== undefined && typeof zoomed === 'object' && zoomed !== null) {\n\t\t\tlet obj = { ...props };\n\t\t\tObject.keys(zoomed).forEach((key) => {\n\t\t\t\tdelete obj[key];\n\t\t\t});\n\t\t\treturn obj;\n\t\t} else {\n\t\t\treturn props;\n\t\t}\n\t}\n\n\texport function zoom<T>(a: any, path: Path, startIndex = 0): T | undefined {\n\t\tif (path.length <= startIndex) {\n\t\t\treturn a;\n\t\t} else if (\n\t\t\t(a instanceof Tree || a instanceof ProxiedTreeState) &&\n\t\t\ttypeof path[startIndex] === 'string'\n\t\t) {\n\t\t\treturn zoom(a.data(path[startIndex] as string), path, startIndex + 1) as\n\t\t\t\t| T\n\t\t\t\t| undefined;\n\t\t} else if (\n\t\t\t(a instanceof Seq || a instanceof ProxiedSeqState) &&\n\t\t\ttypeof path[startIndex] === 'string'\n\t\t) {\n\t\t\treturn zoom(a.data(path[startIndex] as string), path, startIndex + 1) as\n\t\t\t\t| T\n\t\t\t\t| undefined;\n\t\t} else if (typeof path[startIndex] === 'number' && Array.isArray(a)) {\n\t\t\treturn zoom(a[path[startIndex] as number], path, startIndex + 1) as\n\t\t\t\t| T\n\t\t\t\t| undefined;\n\t\t} else if (typeof path[startIndex] === 'string' && typeof a === 'object') {\n\t\t\treturn zoom(a[path[startIndex] as string], path, startIndex + 1);\n\t\t}\n\t\treturn undefined;\n\t}\n}\n\nexport type CollabDataOpResult<T, OP> = {\n\tdata: T;\n\tactual: OP;\n\treverse: OP;\n} | null;\n\nexport type IdMapped<T> = {\n\treadonly [key: string]: T;\n};\n\nexport type FiId = { readonly fi: number; readonly id: string };\n\n/*\nwhen an Add/Move Op is applied locally, we will remember the index where it actually happened, this is INVALID in other\ncases, but reactions can safely use this, and it is defined for reactions\n\nbut it is kind of hacky!\n*/\nexport type LocalIndex = number;\n", "\"use strict\"\r\nvar decoder\r\ntry {\r\n\tdecoder = new TextDecoder()\r\n} catch(error) {}\r\nvar src\r\nvar srcEnd\r\nvar position = 0\r\nvar alreadySet\r\nconst EMPTY_ARRAY = []\r\nvar strings = EMPTY_ARRAY\r\nvar stringPosition = 0\r\nvar currentUnpackr = {}\r\nvar currentStructures\r\nvar srcString\r\nvar srcStringStart = 0\r\nvar srcStringEnd = 0\r\nvar bundledStrings\r\nvar referenceMap\r\nvar currentExtensions = []\r\nvar dataView\r\nvar defaultOptions = {\r\n\tuseRecords: false,\r\n\tmapsAsObjects: true\r\n}\r\nexport class C1Type {}\r\nexport const C1 = new C1Type()\r\nC1.name = 'MessagePack 0xC1'\r\nvar sequentialMode = false\r\n\r\nexport class Unpackr {\r\n\tconstructor(options) {\r\n\t\tif (options) {\r\n\t\t\tif (options.useRecords === false && options.mapsAsObjects === undefined)\r\n\t\t\t\toptions.mapsAsObjects = true\r\n\t\t\tif (options.structures)\r\n\t\t\t\toptions.structures.sharedLength = options.structures.length\r\n\t\t\telse if (options.getStructures) {\r\n\t\t\t\t(options.structures = []).uninitialized = true // this is what we use to denote an uninitialized structures\r\n\t\t\t\toptions.structures.sharedLength = 0\r\n\t\t\t}\r\n\t\t}\r\n\t\tObject.assign(this, options)\r\n\t}\r\n\tunpack(source, end) {\r\n\t\tif (src) {\r\n\t\t\t// re-entrant execution, save the state and restore it after we do this unpack\r\n\t\t\treturn saveState(() => {\r\n\t\t\t\tclearSource()\r\n\t\t\t\treturn this ? this.unpack(source, end) : Unpackr.prototype.unpack.call(defaultOptions, source, end)\r\n\t\t\t})\r\n\t\t}\r\n\t\tsrcEnd = end > -1 ? end : source.length\r\n\t\tposition = 0\r\n\t\tstringPosition = 0\r\n\t\tsrcStringEnd = 0\r\n\t\tsrcString = null\r\n\t\tstrings = EMPTY_ARRAY\r\n\t\tbundledStrings = null\r\n\t\tsrc = source\r\n\t\t// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend\r\n\t\t// technique for getting data from a database where it can be copied into an existing buffer instead of creating\r\n\t\t// new ones\r\n\t\ttry {\r\n\t\t\tdataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength))\r\n\t\t} catch(error) {\r\n\t\t\t// if it doesn't have a buffer, maybe it is the wrong type of object\r\n\t\t\tsrc = null\r\n\t\t\tif (source instanceof Uint8Array)\r\n\t\t\t\tthrow error\r\n\t\t\tthrow new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))\r\n\t\t}\r\n\t\tif (this instanceof Unpackr) {\r\n\t\t\tcurrentUnpackr = this\r\n\t\t\tif (this.structures) {\r\n\t\t\t\tcurrentStructures = this.structures\r\n\t\t\t\treturn checkedRead()\r\n\t\t\t} else if (!currentStructures || currentStructures.length > 0) {\r\n\t\t\t\tcurrentStructures = []\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tcurrentUnpackr = defaultOptions\r\n\t\t\tif (!currentStructures || currentStructures.length > 0)\r\n\t\t\t\tcurrentStructures = []\r\n\t\t}\r\n\t\treturn checkedRead()\r\n\t}\r\n\tunpackMultiple(source, forEach) {\r\n\t\tlet values, lastPosition = 0\r\n\t\ttry {\r\n\t\t\tsequentialMode = true\r\n\t\t\tlet size = source.length\r\n\t\t\tlet value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size)\r\n\t\t\tif (forEach) {\r\n\t\t\t\tforEach(value)\r\n\t\t\t\twhile(position < size) {\r\n\t\t\t\t\tlastPosition = position\r\n\t\t\t\t\tif (forEach(checkedRead()) === false) {\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tvalues = [ value ]\r\n\t\t\t\twhile(position < size) {\r\n\t\t\t\t\tlastPosition = position\r\n\t\t\t\t\tvalues.push(checkedRead())\r\n\t\t\t\t}\r\n\t\t\t\treturn values\r\n\t\t\t}\r\n\t\t} catch(error) {\r\n\t\t\terror.lastPosition = lastPosition\r\n\t\t\terror.values = values\r\n\t\t\tthrow error\r\n\t\t} finally {\r\n\t\t\tsequentialMode = false\r\n\t\t\tclearSource()\r\n\t\t}\r\n\t}\r\n\t_mergeStructures(loadedStructures, existingStructures) {\r\n\t\tloadedStructures = loadedStructures || []\r\n\t\tfor (let i = 0, l = loadedStructures.length; i < l; i++) {\r\n\t\t\tlet structure = loadedStructures[i]\r\n\t\t\tif (structure) {\r\n\t\t\t\tstructure.isShared = true\r\n\t\t\t\tif (i >= 32)\r\n\t\t\t\t\tstructure.highByte = (i - 32) >> 5\r\n\t\t\t}\r\n\t\t}\r\n\t\tloadedStructures.sharedLength = loadedStructures.length\r\n\t\tfor (let id in existingStructures || []) {\r\n\t\t\tif (id >= 0) {\r\n\t\t\t\tlet structure = loadedStructures[id]\r\n\t\t\t\tlet existing = existingStructures[id]\r\n\t\t\t\tif (existing) {\r\n\t\t\t\t\tif (structure)\r\n\t\t\t\t\t\t(loadedStructures.restoreStructures || (loadedStructures.restoreStructures = []))[id] = structure\r\n\t\t\t\t\tloadedStructures[id] = existing\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn this.structures = loadedStructures\r\n\t}\r\n\tdecode(source, end) {\r\n\t\treturn this.unpack(source, end)\r\n\t}\r\n}\r\nexport function getPosition() {\r\n\treturn position\r\n}\r\nexport function checkedRead() {\r\n\ttry {\r\n\t\tif (!currentUnpackr.trusted && !sequentialMode) {\r\n\t\t\tlet sharedLength = currentStructures.sharedLength || 0\r\n\t\t\tif (sharedLength < currentStructures.length)\r\n\t\t\t\tcurrentStructures.length = sharedLength\r\n\t\t}\r\n\t\tlet result = read()\r\n\t\tif (position == srcEnd) {\r\n\t\t\t// finished reading this source, cleanup references\r\n\t\t\tif (currentStructures.restoreStructures)\r\n\t\t\t\trestoreStructures()\r\n\t\t\tcurrentStructures = null\r\n\t\t\tsrc = null\r\n\t\t\tif (referenceMap)\r\n\t\t\t\treferenceMap = null\r\n\t\t} else if (position > srcEnd) {\r\n\t\t\t// over read\r\n\t\t\tlet error = new Error('Unexpected end of MessagePack data')\r\n\t\t\terror.incomplete = true\r\n\t\t\tthrow error\r\n\t\t} else if (!sequentialMode) {\r\n\t\t\tthrow new Error('Data read, but end of buffer not reached')\r\n\t\t}\r\n\t\t// else more to read, but we are reading sequentially, so don't clear source yet\r\n\t\treturn result\r\n\t} catch(error) {\r\n\t\tif (currentStructures.restoreStructures)\r\n\t\t\trestoreStructures()\r\n\t\tclearSource()\r\n\t\tif (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {\r\n\t\t\terror.incomplete = true\r\n\t\t}\r\n\t\tthrow error\r\n\t}\r\n}\r\n\r\nfunction restoreStructures() {\r\n\tfor (let id in currentStructures.restoreStructures) {\r\n\t\tcurrentStructures[id] = currentStructures.restoreStructures[id]\r\n\t}\r\n\tcurrentStructures.restoreStructures = null\r\n}\r\n\r\nexport function read() {\r\n\tlet token = src[position++]\r\n\tif (token < 0xa0) {\r\n\t\tif (token < 0x80) {\r\n\t\t\tif (token < 0x40)\r\n\t\t\t\treturn token\r\n\t\t\telse {\r\n\t\t\t\tlet structure = currentStructures[token & 0x3f] ||\r\n\t\t\t\t\tcurrentUnpackr.getStructures && loadStructures()[token & 0x3f]\r\n\t\t\t\tif (structure) {\r\n\t\t\t\t\tif (!structure.read) {\r\n\t\t\t\t\t\tstructure.read = createStructureReader(structure, token & 0x3f)\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn structure.read()\r\n\t\t\t\t} else\r\n\t\t\t\t\treturn token\r\n\t\t\t}\r\n\t\t} else if (token < 0x90) {\r\n\t\t\t// map\r\n\t\t\ttoken -= 0x80\r\n\t\t\tif (currentUnpackr.mapsAsObjects) {\r\n\t\t\t\tlet object = {}\r\n\t\t\t\tfor (let i = 0; i < token; i++) {\r\n\t\t\t\t\tobject[readKey()] = read()\r\n\t\t\t\t}\r\n\t\t\t\treturn object\r\n\t\t\t} else {\r\n\t\t\t\tlet map = new Map()\r\n\t\t\t\tfor (let i = 0; i < token; i++) {\r\n\t\t\t\t\tmap.set(read(), read())\r\n\t\t\t\t}\r\n\t\t\t\treturn map\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\ttoken -= 0x90\r\n\t\t\tlet array = new Array(token)\r\n\t\t\tfor (let i = 0; i < token; i++) {\r\n\t\t\t\tarray[i] = read()\r\n\t\t\t}\r\n\t\t\treturn array\r\n\t\t}\r\n\t} else if (token < 0xc0) {\r\n\t\t// fixstr\r\n\t\tlet length = token - 0xa0\r\n\t\tif (srcStringEnd >= position) {\r\n\t\t\treturn srcString.slice(position - srcStringStart, (position += length) - srcStringStart)\r\n\t\t}\r\n\t\tif (srcStringEnd == 0 && srcEnd < 140) {\r\n\t\t\t// for small blocks, avoiding the overhead of the extract call is helpful\r\n\t\t\tlet string = length < 16 ? shortStringInJS(length) : longStringInJS(length)\r\n\t\t\tif (string != null)\r\n\t\t\t\treturn string\r\n\t\t}\r\n\t\treturn readFixedString(length)\r\n\t} else {\r\n\t\tlet value\r\n\t\tswitch (token) {\r\n\t\t\tcase 0xc0: return null\r\n\t\t\tcase 0xc1:\r\n\t\t\t\tif (bundledStrings) {\r\n\t\t\t\t\tvalue = read() // followed by the length of the string in characters (not bytes!)\r\n\t\t\t\t\tif (value > 0)\r\n\t\t\t\t\t\treturn bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 -= value)\r\n\t\t\t\t}\r\n\t\t\t\treturn C1; // \"never-used\", return special object to denote that\r\n\t\t\tcase 0xc2: return false\r\n\t\t\tcase 0xc3: return true\r\n\t\t\tcase 0xc4:\r\n\t\t\t\t// bin 8\r\n\t\t\t\treturn readBin(src[position++])\r\n\t\t\tcase 0xc5:\r\n\t\t\t\t// bin 16\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn readBin(value)\r\n\t\t\tcase 0xc6:\r\n\t\t\t\t// bin 32\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn readBin(value)\r\n\t\t\tcase 0xc7:\r\n\t\t\t\t// ext 8\r\n\t\t\t\treturn readExt(src[position++])\r\n\t\t\tcase 0xc8:\r\n\t\t\t\t// ext 16\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn readExt(value)\r\n\t\t\tcase 0xc9:\r\n\t\t\t\t// ext 32\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn readExt(value)\r\n\t\t\tcase 0xca:\r\n\t\t\t\tvalue = dataView.getFloat32(position)\r\n\t\t\t\tif (currentUnpackr.useFloat32 > 2) {\r\n\t\t\t\t\t// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved\r\n\t\t\t\t\tlet multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)]\r\n\t\t\t\t\tposition += 4\r\n\t\t\t\t\treturn ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier\r\n\t\t\t\t}\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn value\r\n\t\t\tcase 0xcb:\r\n\t\t\t\tvalue = dataView.getFloat64(position)\r\n\t\t\t\tposition += 8\r\n\t\t\t\treturn value\r\n\t\t\t// uint handlers\r\n\t\t\tcase 0xcc:\r\n\t\t\t\treturn src[position++]\r\n\t\t\tcase 0xcd:\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn value\r\n\t\t\tcase 0xce:\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn value\r\n\t\t\tcase 0xcf:\r\n\t\t\t\tif (currentUnpackr.int64AsNumber) {\r\n\t\t\t\t\tvalue = dataView.getUint32(position) * 0x100000000\r\n\t\t\t\t\tvalue += dataView.getUint32(position + 4)\r\n\t\t\t\t} else\r\n\t\t\t\t\tvalue = dataView.getBigUint64(position)\r\n\t\t\t\tposition += 8\r\n\t\t\t\treturn value\r\n\r\n\t\t\t// int handlers\r\n\t\t\tcase 0xd0:\r\n\t\t\t\treturn dataView.getInt8(position++)\r\n\t\t\tcase 0xd1:\r\n\t\t\t\tvalue = dataView.getInt16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn value\r\n\t\t\tcase 0xd2:\r\n\t\t\t\tvalue = dataView.getInt32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn value\r\n\t\t\tcase 0xd3:\r\n\t\t\t\tif (currentUnpackr.int64AsNumber) {\r\n\t\t\t\t\tvalue = dataView.getInt32(position) * 0x100000000\r\n\t\t\t\t\tvalue += dataView.getUint32(position + 4)\r\n\t\t\t\t} else\r\n\t\t\t\t\tvalue = dataView.getBigInt64(position)\r\n\t\t\t\tposition += 8\r\n\t\t\t\treturn value\r\n\r\n\t\t\tcase 0xd4:\r\n\t\t\t\t// fixext 1\r\n\t\t\t\tvalue = src[position++]\r\n\t\t\t\tif (value == 0x72) {\r\n\t\t\t\t\treturn recordDefinition(src[position++] & 0x3f)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet extension = currentExtensions[value]\r\n\t\t\t\t\tif (extension) {\r\n\t\t\t\t\t\tif (extension.read) {\r\n\t\t\t\t\t\t\tposition++ // skip filler byte\r\n\t\t\t\t\t\t\treturn extension.read(read())\r\n\t\t\t\t\t\t} else if (extension.noBuffer) {\r\n\t\t\t\t\t\t\tposition++ // skip filler byte\r\n\t\t\t\t\t\t\treturn extension()\r\n\t\t\t\t\t\t} else\r\n\t\t\t\t\t\t\treturn extension(src.subarray(position, ++position))\r\n\t\t\t\t\t} else\r\n\t\t\t\t\t\tthrow new Error('Unknown extension ' + value)\r\n\t\t\t\t}\r\n\t\t\tcase 0xd5:\r\n\t\t\t\t// fixext 2\r\n\t\t\t\tvalue = src[position]\r\n\t\t\t\tif (value == 0x72) {\r\n\t\t\t\t\tposition++\r\n\t\t\t\t\treturn recordDefinition(src[position++] & 0x3f, src[position++])\r\n\t\t\t\t} else\r\n\t\t\t\t\treturn readExt(2)\r\n\t\t\tcase 0xd6:\r\n\t\t\t\t// fixext 4\r\n\t\t\t\treturn readExt(4)\r\n\t\t\tcase 0xd7:\r\n\t\t\t\t// fixext 8\r\n\t\t\t\treturn readExt(8)\r\n\t\t\tcase 0xd8:\r\n\t\t\t\t// fixext 16\r\n\t\t\t\treturn readExt(16)\r\n\t\t\tcase 0xd9:\r\n\t\t\t// str 8\r\n\t\t\t\tvalue = src[position++]\r\n\t\t\t\tif (srcStringEnd >= position) {\r\n\t\t\t\t\treturn srcString.slice(position - srcStringStart, (position += value) - srcStringStart)\r\n\t\t\t\t}\r\n\t\t\t\treturn readString8(value)\r\n\t\t\tcase 0xda:\r\n\t\t\t// str 16\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\tif (srcStringEnd >= position) {\r\n\t\t\t\t\treturn srcString.slice(position - srcStringStart, (position += value) - srcStringStart)\r\n\t\t\t\t}\r\n\t\t\t\treturn readString16(value)\r\n\t\t\tcase 0xdb:\r\n\t\t\t// str 32\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\tif (srcStringEnd >= position) {\r\n\t\t\t\t\treturn srcString.slice(position - srcStringStart, (position += value) - srcStringStart)\r\n\t\t\t\t}\r\n\t\t\t\treturn readString32(value)\r\n\t\t\tcase 0xdc:\r\n\t\t\t// array 16\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn readArray(value)\r\n\t\t\tcase 0xdd:\r\n\t\t\t// array 32\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn readArray(value)\r\n\t\t\tcase 0xde:\r\n\t\t\t// map 16\r\n\t\t\t\tvalue = dataView.getUint16(position)\r\n\t\t\t\tposition += 2\r\n\t\t\t\treturn readMap(value)\r\n\t\t\tcase 0xdf:\r\n\t\t\t// map 32\r\n\t\t\t\tvalue = dataView.getUint32(position)\r\n\t\t\t\tposition += 4\r\n\t\t\t\treturn readMap(value)\r\n\t\t\tdefault: // negative int\r\n\t\t\t\tif (token >= 0xe0)\r\n\t\t\t\t\treturn token - 0x100\r\n\t\t\t\tif (token === undefined) {\r\n\t\t\t\t\tlet error = new Error('Unexpected end of MessagePack data')\r\n\t\t\t\t\terror.incomplete = true\r\n\t\t\t\t\tthrow error\r\n\t\t\t\t}\r\n\t\t\t\tthrow new Error('Unknown MessagePack token ' + token)\r\n\r\n\t\t}\r\n\t}\r\n}\r\nconst validName = /^[a-zA-Z_$][a-zA-Z\\d_$]*$/\r\nfunction createStructureReader(structure, firstId) {\r\n\tfunction readObject() {\r\n\t\t// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function\r\n\t\tif (readObject.count++ > 2) {\r\n\t\t\tlet readObject = structure.read = (new Function('r', 'return function(){return {' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}}'))(read)\r\n\t\t\tif (structure.highByte === 0)\r\n\t\t\t\tstructure.read = createSecondByteReader(firstId, structure.read)\r\n\t\t\treturn readObject() // second byte is already read, if there is one so immediately read object\r\n\t\t}\r\n\t\tlet object = {}\r\n\t\tfor (let i = 0, l = structure.length; i < l; i++) {\r\n\t\t\tlet key = structure[i]\r\n\t\t\tobject[key] = read()\r\n\t\t}\r\n\t\treturn object\r\n\t}\r\n\treadObject.count = 0\r\n\tif (structure.highByte === 0) {\r\n\t\treturn createSecondByteReader(firstId, readObject)\r\n\t}\r\n\treturn readObject\r\n}\r\n\r\nconst createSecondByteReader = (firstId, read0) => {\r\n\treturn function() {\r\n\t\tlet highByte = src[position++]\r\n\t\tif (highByte === 0)\r\n\t\t\treturn read0()\r\n\t\tlet id = firstId < 32 ? -(firstId + (highByte << 5)) : firstId + (highByte << 5)\r\n\t\tlet structure = currentStructures[id] || loadStructures()[id]\r\n\t\tif (!structure) {\r\n\t\t\tthrow new Error('Record id is not defined for ' + id)\r\n\t\t}\r\n\t\tif (!structure.read)\r\n\t\t\tstructure.read = createStructureReader(structure, firstId)\r\n\t\treturn structure.read()\r\n\t}\r\n}\r\n\r\nfunction loadStructures() {\r\n\tlet loadedStructures = saveState(() => {\r\n\t\t// save the state in case getStructures modifies our buffer\r\n\t\tsrc = null\r\n\t\treturn currentUnpackr.getStructures()\r\n\t})\r\n\treturn currentStructures = currentUnpackr._mergeStructures(loadedStructures, currentStructures)\r\n}\r\n\r\nvar readFixedString = readStringJS\r\nvar readString8 = readStringJS\r\nvar readString16 = readStringJS\r\nvar readString32 = readStringJS\r\nexport let isNativeAccelerationEnabled = false\r\n\r\nexport function setExtractor(extractStrings) {\r\n\tisNativeAccelerationEnabled = true\r\n\treadFixedString = readString(1)\r\n\treadString8 = readString(2)\r\n\treadString16 = readString(3)\r\n\treadString32 = readString(5)\r\n\tfunction readString(headerLength) {\r\n\t\treturn function readString(length) {\r\n\t\t\tlet string = strings[stringPosition++]\r\n\t\t\tif (string == null) {\r\n\t\t\t\tlet extraction = extractStrings(position - headerLength, srcEnd, src)\r\n\t\t\t\tif (typeof extraction == 'string') {\r\n\t\t\t\t\tstring = extraction\r\n\t\t\t\t\tstrings = EMPTY_ARRAY\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstrings = extraction\r\n\t\t\t\t\tstringPosition = 1\r\n\t\t\t\t\tsrcStringEnd = 1 // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings\r\n\t\t\t\t\tstring = strings[0]\r\n\t\t\t\t\tif (string === undefined)\r\n\t\t\t\t\t\tthrow new Error('Unexpected end of buffer')\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tlet srcStringLength = string.length\r\n\t\t\tif (srcStringLength <= length) {\r\n\t\t\t\tposition += length\r\n\t\t\t\treturn string\r\n\t\t\t}\r\n\t\t\tsrcString = string\r\n\t\t\tsrcStringStart = position\r\n\t\t\tsrcStringEnd = position + srcStringLength\r\n\t\t\tposition += length\r\n\t\t\treturn string.slice(0, length) // we know we just want the beginning\r\n\t\t}\r\n\t}\r\n}\r\nfunction readStringJS(length) {\r\n\tlet result\r\n\tif (length < 16) {\r\n\t\tif (result = shortStringInJS(length))\r\n\t\t\treturn result\r\n\t}\r\n\tif (length > 64 && decoder)\r\n\t\treturn decoder.decode(src.subarray(position, position += length))\r\n\tconst end = position + length\r\n\tconst units = []\r\n\tresult = ''\r\n\twhile (position < end) {\r\n\t\tconst byte1 = src[position++]\r\n\t\tif ((byte1 & 0x80) === 0) {\r\n\t\t\t// 1 byte\r\n\t\t\tunits.push(byte1)\r\n\t\t} else if ((byte1 & 0xe0) === 0xc0) {\r\n\t\t\t// 2 bytes\r\n\t\t\tconst byte2 = src[position++] & 0x3f\r\n\t\t\tunits.push(((byte1 & 0x1f) << 6) | byte2)\r\n\t\t} else if ((byte1 & 0xf0) === 0xe0) {\r\n\t\t\t// 3 bytes\r\n\t\t\tconst byte2 = src[position++] & 0x3f\r\n\t\t\tconst byte3 = src[position++] & 0x3f\r\n\t\t\tunits.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3)\r\n\t\t} else if ((byte1 & 0xf8) === 0xf0) {\r\n\t\t\t// 4 bytes\r\n\t\t\tconst byte2 = src[position++] & 0x3f\r\n\t\t\tconst byte3 = src[position++] & 0x3f\r\n\t\t\tconst byte4 = src[position++] & 0x3f\r\n\t\t\tlet unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4\r\n\t\t\tif (unit > 0xffff) {\r\n\t\t\t\tunit -= 0x10000\r\n\t\t\t\tunits.push(((unit >>> 10) & 0x3ff) | 0xd800)\r\n\t\t\t\tunit = 0xdc00 | (unit & 0x3ff)\r\n\t\t\t}\r\n\t\t\tunits.push(unit)\r\n\t\t} else {\r\n\t\t\tunits.push(byte1)\r\n\t\t}\r\n\r\n\t\tif (units.length >= 0x1000) {\r\n\t\t\tresult += fromCharCode.apply(String, units)\r\n\t\t\tunits.length = 0\r\n\t\t}\r\n\t}\r\n\r\n\tif (units.length > 0) {\r\n\t\tresult += fromCharCode.apply(String, units)\r\n\t}\r\n\r\n\treturn result\r\n}\r\n\r\nfunction readArray(length) {\r\n\tlet array = new Array(length)\r\n\tfor (let i = 0; i < length; i++) {\r\n\t\tarray[i] = read()\r\n\t}\r\n\treturn array\r\n}\r\n\r\nfunction readMap(length) {\r\n\tif (currentUnpackr.mapsAsObjects) {\r\n\t\tlet object = {}\r\n\t\tfor (let i = 0; i < length; i++) {\r\n\t\t\tobject[readKey()] = read()\r\n\t\t}\r\n\t\treturn object\r\n\t} else {\r\n\t\tlet map = new Map()\r\n\t\tfor (let i = 0; i < length; i++) {\r\n\t\t\tmap.set(read(), read())\r\n\t\t}\r\n\t\treturn map\r\n\t}\r\n}\r\n\r\nvar fromCharCode = String.fromCharCode\r\nfunction longStringInJS(length) {\r\n\tlet start = position\r\n\tlet bytes = new Array(length)\r\n\tfor (let i = 0; i < length; i++) {\r\n\t\tconst byte = src[position++];\r\n\t\tif ((byte & 0x80) > 0) {\r\n\t\t\tposition = start\r\n \t\t\treturn\r\n \t\t}\r\n \t\tbytes[i] = byte\r\n \t}\r\n \treturn fromCharCode.apply(String, bytes)\r\n}\r\nfunction shortStringInJS(length) {\r\n\tif (length < 4) {\r\n\t\tif (length < 2) {\r\n\t\t\tif (length === 0)\r\n\t\t\t\treturn ''\r\n\t\t\telse {\r\n\t\t\t\tlet a = src[position++]\r\n\t\t\t\tif ((a & 0x80) > 1) {\r\n\t\t\t\t\tposition -= 1\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\treturn fromCharCode(a)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tlet a = src[position++]\r\n\t\t\tlet b = src[position++]\r\n\t\t\tif ((a & 0x80) > 0 || (b & 0x80) > 0) {\r\n\t\t\t\tposition -= 2\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tif (length < 3)\r\n\t\t\t\treturn fromCharCode(a, b)\r\n\t\t\tlet c = src[position++]\r\n\t\t\tif ((c & 0x80) > 0) {\r\n\t\t\t\tposition -= 3\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\treturn fromCharCode(a, b, c)\r\n\t\t}\r\n\t} else {\r\n\t\tlet a = src[position++]\r\n\t\tlet b = src[position++]\r\n\t\tlet c = src[position++]\r\n\t\tlet d = src[position++]\r\n\t\tif ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {\r\n\t\t\tposition -= 4\r\n\t\t\treturn\r\n\t\t}\r\n\t\tif (length < 6) {\r\n\t\t\tif (length === 4)\r\n\t\t\t\treturn fromCharCode(a, b, c, d)\r\n\t\t\telse {\r\n\t\t\t\tlet e = src[position++]\r\n\t\t\t\tif ((e & 0x80) > 0) {\r\n\t\t\t\t\tposition -= 5\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\treturn fromCharCode(a, b, c, d, e)\r\n\t\t\t}\r\n\t\t} else if (length < 8) {\r\n\t\t\tlet e = src[position++]\r\n\t\t\tlet f = src[position++]\r\n\t\t\tif ((e & 0x80) > 0 || (f & 0x80) > 0) {\r\n\t\t\t\tposition -= 6\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tif (length < 7)\r\n\t\t\t\treturn fromCharCode(a, b, c, d, e, f)\r\n\t\t\tlet g = src[position++]\r\n\t\t\tif ((g & 0x80) > 0) {\r\n\t\t\t\tposition -= 7\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\treturn fromCharCode(a, b, c, d, e, f, g)\r\n\t\t} else {\r\n\t\t\tlet e = src[position++]\r\n\t\t\tlet f = src[position++]\r\n\t\t\tlet g = src[position++]\r\n\t\t\tlet h = src[position++]\r\n\t\t\tif ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {\r\n\t\t\t\tposition -= 8\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tif (length < 10) {\r\n\t\t\t\tif (length === 8)\r\n\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h)\r\n\t\t\t\telse {\r\n\t\t\t\t\tlet i = src[position++]\r\n\t\t\t\t\tif ((i & 0x80) > 0) {\r\n\t\t\t\t\t\tposition -= 9\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i)\r\n\t\t\t\t}\r\n\t\t\t} else if (length < 12) {\r\n\t\t\t\tlet i = src[position++]\r\n\t\t\t\tlet j = src[position++]\r\n\t\t\t\tif ((i & 0x80) > 0 || (j & 0x80) > 0) {\r\n\t\t\t\t\tposition -= 10\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\tif (length < 11)\r\n\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j)\r\n\t\t\t\tlet k = src[position++]\r\n\t\t\t\tif ((k & 0x80) > 0) {\r\n\t\t\t\t\tposition -= 11\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j, k)\r\n\t\t\t} else {\r\n\t\t\t\tlet i = src[position++]\r\n\t\t\t\tlet j = src[position++]\r\n\t\t\t\tlet k = src[position++]\r\n\t\t\t\tlet l = src[position++]\r\n\t\t\t\tif ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {\r\n\t\t\t\t\tposition -= 12\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\tif (length < 14) {\r\n\t\t\t\t\tif (length === 12)\r\n\t\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\tlet m = src[position++]\r\n\t\t\t\t\t\tif ((m & 0x80) > 0) {\r\n\t\t\t\t\t\t\tposition -= 13\r\n\t\t\t\t\t\t\treturn\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet m = src[position++]\r\n\t\t\t\t\tlet n = src[position++]\r\n\t\t\t\t\tif ((m & 0x80) > 0 || (n & 0x80) > 0) {\r\n\t\t\t\t\t\tposition -= 14\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (length < 15)\r\n\t\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)\r\n\t\t\t\t\tlet o = src[position++]\r\n\t\t\t\t\tif ((o & 0x80) > 0) {\r\n\t\t\t\t\t\tposition -= 15\r\n\t\t\t\t\t\treturn\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction readBin(length) {\r\n\treturn currentUnpackr.copyBuffers ?\r\n\t\t// specifically use the copying slice (not the node one)\r\n\t\tUint8Array.prototype.slice.call(src, position, position += length) :\r\n\t\tsrc.subarray(position, position += length)\r\n}\r\nfunction readExt(length) {\r\n\tlet type = src[position++]\r\n\tif (currentExtensions[type]) {\r\n\t\treturn currentExtensions[type](src.subarray(position, position += length))\r\n\t}\r\n\telse\r\n\t\tthrow new Error('Unknown extension type ' + type)\r\n}\r\n\r\nvar keyCache = new Array(4096)\r\nfunction readKey() {\r\n\tlet length = src[position++]\r\n\tif (length >= 0xa0 && length < 0xc0) {\r\n\t\t// fixstr, potentially use key cache\r\n\t\tlength = length - 0xa0\r\n\t\tif (srcStringEnd >= position) // if it has been extracted, must use it (and faster anyway)\r\n\t\t\treturn srcString.slice(position - srcStringStart, (position += length) - srcStringStart)\r\n\t\telse if (!(srcStringEnd == 0 && srcEnd < 180))\r\n\t\t\treturn readFixedString(length)\r\n\t} else { // not cacheable, go back and do a standard read\r\n\t\tposition--\r\n\t\treturn read()\r\n\t}\r\n\tlet key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff\r\n\tlet entry = keyCache[key]\r\n\tlet checkPosition = position\r\n\tlet end = position + length - 3\r\n\tlet chunk\r\n\tlet i = 0\r\n\tif (entry && entry.bytes == length) {\r\n\t\twhile (checkPosition < end) {\r\n\t\t\tchunk = dataView.getUint32(checkPosition)\r\n\t\t\tif (chunk != entry[i++]) {\r\n\t\t\t\tcheckPosition = 0x70000000\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t\tcheckPosition += 4\r\n\t\t}\r\n\t\tend += 3\r\n\t\twhile (checkPosition < end) {\r\n\t\t\tchunk = src[checkPosition++]\r\n\t\t\tif (chunk != entry[i++]) {\r\n\t\t\t\tcheckPosition = 0x70000000\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (checkPosition === end) {\r\n\t\t\tposition = checkPosition\r\n\t\t\treturn entry.string\r\n\t\t}\r\n\t\tend -= 3\r\n\t\tcheckPosition = position\r\n\t}\r\n\tentry = []\r\n\tkeyCache[key] = entry\r\n\tentry.bytes = length\r\n\twhile (checkPosition < end) {\r\n\t\tchunk = dataView.getUint32(checkPosition)\r\n\t\tentry.push(chunk)\r\n\t\tcheckPosition += 4\r\n\t}\r\n\tend += 3\r\n\twhile (checkPosition < end) {\r\n\t\tchunk = src[checkPosition++]\r\n\t\tentry.push(chunk)\r\n\t}\r\n\t// for small blocks, avoiding the overhead of the extract call is helpful\r\n\tlet string = length < 16 ? shortStringInJS(length) : longStringInJS(length)\r\n\tif (string != null)\r\n\t\treturn entry.string = string\r\n\treturn entry.string = readFixedString(length)\r\n}\r\n\r\n// the registration of the record definition extension (as \"r\")\r\nconst recordDefinition = (id, highByte) => {\r\n\tvar structure = read()\r\n\tlet firstByte = id\r\n\tif (highByte !== undefined) {\r\n\t\tid = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id)\r\n\t\tstructure.highByte = highByte\r\n\t}\r\n\tlet existingStructure = currentStructures[id]\r\n\tif (existingStructure && existingStructure.isShared) {\r\n\t\t(currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure\r\n\t}\r\n\tcurrentStructures[id] = structure\r\n\tstructure.read = createStructureReader(structure, firstByte)\r\n\treturn structure.read()\r\n}\r\nvar glbl = typeof self == 'object' ? self : global\r\ncurrentExtensions[0] = () => {} // notepack defines extension 0 to mean undefined, so use that as the default here\r\ncurrentExtensions[0].noBuffer = true\r\n\r\ncurrentExtensions[0x65] = () => {\r\n\tlet data = read()\r\n\treturn (glbl[data[0]] || Error)(data[1])\r\n}\r\n\r\ncurrentExtensions[0x69] = (data) => {\r\n\t// id extension (for structured clones)\r\n\tlet id = dataView.getUint32(position - 4)\r\n\tif (!referenceMap)\r\n\t\treferenceMap = new Map()\r\n\tlet token = src[position]\r\n\tlet target\r\n\t// TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read\r\n\t// ahead past references to record structure definitions\r\n\tif (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)\r\n\t\ttarget = []\r\n\telse\r\n\t\ttarget = {}\r\n\r\n\tlet refEntry = { target } // a placeholder object\r\n\treferenceMap.set(id, refEntry)\r\n\tlet targetProperties = read() // read the next value as the target object to id\r\n\tif (refEntry.used) // there is a cycle, so we have to assign properties to original target\r\n\t\treturn Object.assign(target, targetProperties)\r\n\trefEntry.target = targetProperties // the placeholder wasn't used, replace with the deserialized one\r\n\treturn targetProperties // no cycle, can just use the returned read object\r\n}\r\n\r\ncurrentExtensions[0x70] = (data) => {\r\n\t// pointer extension (for structured clones)\r\n\tlet id = dataView.getUint32(position - 4)\r\n\tlet refEntry = referenceMap.get(id)\r\n\trefEntry.used = true\r\n\treturn refEntry.target\r\n}\r\n\r\ncurrentExtensions[0x73] = () => new Set(read())\r\n\r\nexport const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array')\r\n\r\ncurrentExtensions[0x74] = (data) => {\r\n\tlet typeCode = data[0]\r\n\tlet typedArrayName = typedArrays[typeCode]\r\n\tif (!typedArrayName)\r\n\t\tthrow new Error('Could not find typed array for code ' + typeCode)\r\n\t// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned\r\n\treturn new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)\r\n}\r\ncurrentExtensions[0x78] = () => {\r\n\tlet data = read()\r\n\treturn new RegExp(data[0], data[1])\r\n}\r\n\r\ncurrentExtensions[0x62] = (data) => {\r\n\tlet dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]\r\n\tlet dataPosition = position\r\n\tposition += dataSize - 4\r\n\tbundledStrings = [read(), read()]\r\n\tbundledStrings.position0 = 0\r\n\tbundledStrings.position1 = 0\r\n\tlet postBundlePosition = position\r\n\tposition = dataPosition\r\n\ttry {\r\n\t\treturn read()\r\n\t} finally {\r\n\t\tposition = postBundlePosition\r\n\t}\r\n}\r\n\r\ncurrentExtensions[0xff] = (data) => {\r\n\t// 32-bit date extension\r\n\tif (data.length == 4)\r\n\t\treturn new Date((data[0] * 0x1000000 + (data[1] << 16) + (data[2] << 8) + data[3]) * 1000)\r\n\telse if (data.length == 8)\r\n\t\treturn new Date(\r\n\t\t\t((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +\r\n\t\t\t((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)\r\n\telse if (data.length == 12)// TODO: Implement support for negative\r\n\t\treturn new Date(\r\n\t\t\t((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +\r\n\t\t\t(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)\r\n\telse\r\n\t\treturn new Date('invalid')\r\n} // notepack defines extension 0 to mean undefined, so use that as the default here\r\n// registration of bulk record definition?\r\n// currentExtensions[0x52] = () =>\r\n\r\nfunction saveState(callback) {\r\n\tlet savedSrcEnd = srcEnd\r\n\tlet savedPosition = position\r\n\tlet savedStringPosition = stringPosition\r\n\tlet savedSrcStringStart = srcStringStart\r\n\tlet savedSrcStringEnd = srcStringEnd\r\n\tlet savedSrcString = srcString\r\n\tlet savedStrings = strings\r\n\tlet savedReferenceMap = referenceMap\r\n\tlet savedBundledStrings = bundledStrings\r\n\r\n\t// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)\r\n\tlet savedSrc = new Uint8Array(src.slice(0, srcEnd)) // we copy the data in case it changes while external data is processed\r\n\tlet savedStructures = currentStructures\r\n\tlet savedStructuresContents = currentStructures.slice(0, currentStructures.length)\r\n\tlet savedPackr = currentUnpackr\r\n\tlet savedSequentialMode = sequentialMode\r\n\tlet value = callback()\r\n\tsrcEnd = savedSrcEnd\r\n\tposition = savedPosition\r\n\tstringPosition = savedStringPosition\r\n\tsrcStringStart = savedSrcStringStart\r\n\tsrcStringEnd = savedSrcStringEnd\r\n\tsrcString = savedSrcString\r\n\tstrings = savedStrings\r\n\treferenceMap = savedReferenceMap\r\n\tbundledStrings = savedBundledStrings\r\n\tsrc = savedSrc\r\n\tsequentialMode = savedSequentialMode\r\n\tcurrentStructures = savedStructures\r\n\tcurrentStructures.splice(0, currentStructures.length, ...savedStructuresContents)\r\n\tcurrentUnpackr = savedPackr\r\n\tdataView = new DataView(src.buffer, src.byteOffset, src.byteLength)\r\n\treturn value\r\n}\r\nexport function clearSource() {\r\n\tsrc = null\r\n\treferenceMap = null\r\n\tcurrentStructures = null\r\n}\r\n\r\nexport function addExtension(extension) {\r\n\tif (extension.unpack)\r\n\t\tcurrentExtensions[extension.type] = extension.unpack\r\n\telse\r\n\t\tcurrentExtensions[extension.type] = extension\r\n}\r\n\r\nexport const mult10 = new Array(147) // this is a table matching binary exponents to the multiplier to determine significant digit rounding\r\nfor (let i = 0; i < 256; i++) {\r\n\tmult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103))\r\n}\r\nexport const Decoder = Unpackr\r\nvar defaultUnpackr = new Unpackr({ useRecords: false })\r\nexport const unpack = defaultUnpackr.unpack\r\nexport const unpackMultiple = defaultUnpackr.unpackMultiple\r\nexport const decode = defaultUnpackr.unpack\r\nexport const FLOAT32_OPTIONS = {\r\n\tNEVER: 0,\r\n\tALWAYS: 1,\r\n\tDECIMAL_ROUND: 3,\r\n\tDECIMAL_FIT: 4\r\n}\r\nlet f32Array = new Float32Array(1)\r\nlet u8Array = new Uint8Array(f32Array.buffer, 0, 4)\r\nexport function roundFloat32(float32Number) {\r\n\tf32Array[0] = float32Number\r\n\tlet multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)]\r\n\treturn ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier\r\n}\r\n", "\"use strict\"\r\nimport { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js'\r\nlet textEncoder\r\ntry {\r\n\ttextEncoder = new TextEncoder()\r\n} catch (error) {}\r\nlet extensions, extensionClasses\r\nconst hasNodeBuffer = typeof Buffer !== 'undefined'\r\nconst ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array\r\nconst ByteArray = hasNodeBuffer ? Buffer : Uint8Array\r\nconst MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000\r\nlet target\r\nlet targetView\r\nlet position = 0\r\nlet safeEnd\r\nlet bundledStrings = null\r\nconst hasNonLatin = /[\\u0080-\\uFFFF]/\r\nconst RECORD_SYMBOL = Symbol('record-id')\r\nexport class Packr extends Unpackr {\r\n\tconstructor(options) {\r\n\t\tsuper(options)\r\n\t\tthis.offset = 0\r\n\t\tlet typeBuffer\r\n\t\tlet start\r\n\t\tlet sharedStructures\r\n\t\tlet hasSharedUpdate\r\n\t\tlet structures\r\n\t\tlet referenceMap\r\n\t\tlet lastSharedStructuresLength = 0\r\n\t\tlet encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {\r\n\t\t\treturn target.utf8Write(string, position, maxBytes)\r\n\t\t} : (textEncoder && textEncoder.encodeInto) ?\r\n\t\t\tfunction(string, position) {\r\n\t\t\t\treturn textEncoder.encodeInto(string, target.subarray(position)).written\r\n\t\t\t} : false\r\n\r\n\t\tlet packr = this\r\n\t\tif (!options)\r\n\t\t\toptions = {}\r\n\t\tlet isSequential = options && options.sequential\r\n\t\tlet hasSharedStructures = options.structures || options.saveStructures\r\n\t\tlet maxSharedStructures = options.maxSharedStructures\r\n\t\tif (maxSharedStructures == null)\r\n\t\t\tmaxSharedStructures = hasSharedStructures ? 32 : 0\r\n\t\tif (maxSharedStructures > 8160)\r\n\t\t\tthrow new Error('Maximum maxSharedStructure is 8160')\r\n\t\tlet maxOwnStructures = options.maxOwnStructures\r\n\t\tif (maxOwnStructures == null)\r\n\t\t\tmaxOwnStructures = hasSharedStructures ? 32 : 64\r\n\t\tif (isSequential && !options.saveStructures)\r\n\t\t\tthis.structures = []\r\n\t\t// two byte record ids for shared structures\r\n\t\tlet useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64)\t\t\r\n\t\tlet sharedLimitId = maxSharedStructures + 0x40\r\n\t\tlet maxStructureId = maxSharedStructures + maxOwnStructures + 0x40\r\n\t\tif (maxStructureId > 8256) {\r\n\t\t\tthrow new Error('Maximum maxSharedStructure + maxOwnStructure is 8192')\r\n\t\t}\r\n\t\tlet recordIdsToRemove = []\r\n\t\tlet transitionsCount = 0\r\n\t\tlet serializationsSinceTransitionRebuild = 0\r\n\r\n\t\tthis.pack = this.encode = function(value, encodeOptions) {\r\n\t\t\tif (!target) {\r\n\t\t\t\ttarget = new ByteArrayAllocate(8192)\r\n\t\t\t\ttargetView = new DataView(target.buffer, 0, 8192)\r\n\t\t\t\tposition = 0\r\n\t\t\t}\r\n\t\t\tsafeEnd = target.length - 10\r\n\t\t\tif (safeEnd - position < 0x800) {\r\n\t\t\t\t// don't start too close to the end, \r\n\t\t\t\ttarget = new ByteArrayAllocate(target.length)\r\n\t\t\t\ttargetView = new DataView(target.buffer, 0, target.length)\r\n\t\t\t\tsafeEnd = target.length - 10\r\n\t\t\t\tposition = 0\r\n\t\t\t} else\r\n\t\t\t\tposition = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster\r\n\t\t\tstart = position\r\n\t\t\treferenceMap = packr.structuredClone ? new Map() : null\r\n\t\t\tif (packr.bundleStrings) {\r\n\t\t\t\tbundledStrings = ['', '']\r\n\t\t\t\ttarget[position++] = 0xd6\r\n\t\t\t\ttarget[position++] = 0x62 // 'b'\r\n\t\t\t\tbundledStrings.position = position - start\r\n\t\t\t\tposition += 4\r\n\t\t\t} else\r\n\t\t\t\tbundledStrings = null\r\n\t\t\tsharedStructures = packr.structures\r\n\t\t\tif (sharedStructures) {\r\n\t\t\t\tif (sharedStructures.uninitialized)\r\n\t\t\t\t\tsharedStructures = packr._mergeStructures(packr.getStructures())\r\n\t\t\t\tlet sharedLength = sharedStructures.sharedLength || 0\r\n\t\t\t\tif (sharedLength > maxSharedStructures) {\r\n\t\t\t\t\t//if (maxSharedStructures <= 32 && sharedStructures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids\r\n\t\t\t\t\tthrow new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + sharedStructures.sharedLength)\r\n\t\t\t\t}\r\n\t\t\t\tif (!sharedStructures.transitions) {\r\n\t\t\t\t\t// rebuild our structure transitions\r\n\t\t\t\t\tsharedStructures.transitions = Object.create(null)\r\n\t\t\t\t\tfor (let i = 0; i < sharedLength; i++) {\r\n\t\t\t\t\t\tlet keys = sharedStructures[i]\r\n\t\t\t\t\t\tif (!keys)\r\n\t\t\t\t\t\t\tcontinue\r\n\t\t\t\t\t\tlet nextTransition, transition = sharedStructures.transitions\r\n\t\t\t\t\t\tfor (let j = 0, l = keys.length; j < l; j++) {\r\n\t\t\t\t\t\t\tlet key = keys[j]\r\n\t\t\t\t\t\t\tnextTransition = transition[key]\r\n\t\t\t\t\t\t\tif (!nextTransition) {\r\n\t\t\t\t\t\t\t\tnextTransition = transition[key] = Object.create(null)\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\ttransition = nextTransition\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\ttransition[RECORD_SYMBOL] = i + 0x40\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlastSharedStructuresLength = sharedLength\r\n\t\t\t\t}\r\n\t\t\t\tif (!isSequential) {\r\n\t\t\t\t\tsharedStructures.nextId = sharedLength + 0x40\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (hasSharedUpdate)\r\n\t\t\t\thasSharedUpdate = false\r\n\t\t\tstructures = sharedStructures || []\r\n\t\t\ttry {\r\n\t\t\t\tpack(value)\r\n\t\t\t\tif (bundledStrings) {\r\n\t\t\t\t\ttargetView.setUint32(bundledStrings.position + start, position - bundledStrings.position - start)\r\n\t\t\t\t\tlet writeStrings = bundledStrings\r\n\t\t\t\t\tbundledStrings = null\r\n\t\t\t\t\tpack(writeStrings[0])\r\n\t\t\t\t\tpack(writeStrings[1])\r\n\t\t\t\t}\r\n\t\t\t\tpackr.offset = position // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially\r\n\t\t\t\tif (referenceMap && referenceMap.idsToInsert) {\r\n\t\t\t\t\tposition += referenceMap.idsToInsert.length * 6\r\n\t\t\t\t\tif (position > safeEnd)\r\n\t\t\t\t\t\tmakeRoom(position)\r\n\t\t\t\t\tpackr.offset = position\r\n\t\t\t\t\tlet serialized = insertIds(target.subarray(start, position), referenceMap.idsToInsert)\r\n\t\t\t\t\treferenceMap = null\r\n\t\t\t\t\treturn serialized\r\n\t\t\t\t}\r\n\t\t\t\tif (encodeOptions & REUSE_BUFFER_MODE) {\r\n\t\t\t\t\ttarget.start = start\r\n\t\t\t\t\ttarget.end = position\r\n\t\t\t\t\treturn target\r\n\t\t\t\t}\r\n\t\t\t\treturn target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now\r\n\t\t\t} finally {\r\n\t\t\t\tif (sharedStructures) {\r\n\t\t\t\t\tif (serializationsSinceTransitionRebuild < 10)\r\n\t\t\t\t\t\tserializationsSinceTransitionRebuild++\r\n\t\t\t\t\tif (transitionsCount > 10000) {\r\n\t\t\t\t\t\t// force a rebuild occasionally after a lot of transitions so it can get cleaned up\r\n\t\t\t\t\t\tsharedStructures.transitions = null\r\n\t\t\t\t\t\tserializationsSinceTransitionRebuild = 0\r\n\t\t\t\t\t\ttransitionsCount = 0\r\n\t\t\t\t\t\tif (recordIdsToRemove.length > 0)\r\n\t\t\t\t\t\t\trecordIdsToRemove = []\r\n\t\t\t\t\t} else if (recordIdsToRemove.length > 0 && !isSequential) {\r\n\t\t\t\t\t\tfor (let i = 0, l = recordIdsToRemove.length; i < l; i++) {\r\n\t\t\t\t\t\t\trecordIdsToRemove[i][RECORD_SYMBOL] = 0\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\trecordIdsToRemove = []\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (hasSharedUpdate && packr.saveStructures) {\r\n\t\t\t\t\t\tlet sharedLength = sharedStructures.sharedLength || maxSharedStructures\r\n\t\t\t\t\t\tif (sharedStructures.length > sharedLength) {\r\n\t\t\t\t\t\t\tsharedStructures = sharedStructures.slice(0, sharedLength)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save\r\n\t\t\t\t\t\tlet returnBuffer = target.subarray(start, position)\r\n\t\t\t\t\t\tif (packr.saveStructures(sharedStructures, lastSharedStructuresLength) === false) {\r\n\t\t\t\t\t\t\t// get updated structures and try again if the update failed\r\n\t\t\t\t\t\t\tpackr._mergeStructures(packr.getStructures())\r\n\t\t\t\t\t\t\treturn packr.pack(value)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tlastSharedStructuresLength = sharedLength\r\n\t\t\t\t\t\treturn returnBuffer\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (encodeOptions & RESET_BUFFER_MODE)\r\n\t\t\t\t\tposition = start\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst pack = (value) => {\r\n\t\t\tif (position > safeEnd)\r\n\t\t\t\ttarget = makeRoom(position)\r\n\r\n\t\t\tvar type = typeof value\r\n\t\t\tvar length\r\n\t\t\tif (type === 'string') {\r\n\t\t\t\tlet strLength = value.length\r\n\t\t\t\tif (bundledStrings && strLength >= 8 && strLength < 0x1000) {\r\n\t\t\t\t\tlet twoByte = hasNonLatin.test(value)\r\n\t\t\t\t\tbundledStrings[twoByte ? 0 : 1] += value\r\n\t\t\t\t\ttarget[position++] = 0xc1\r\n\t\t\t\t\tpack(twoByte ? -strLength : strLength);\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\tlet headerSize\r\n\t\t\t\t// first we estimate the header size, so we can write to the correct location\r\n\t\t\t\tif (strLength < 0x20) {\r\n\t\t\t\t\theaderSize = 1\r\n\t\t\t\t} else if (strLength < 0x100) {\r\n\t\t\t\t\theaderSize = 2\r\n\t\t\t\t} else if (strLength < 0x10000) {\r\n\t\t\t\t\theaderSize = 3\r\n\t\t\t\t} else {\r\n\t\t\t\t\theaderSize = 5\r\n\t\t\t\t}\r\n\t\t\t\tlet maxBytes = strLength * 3\r\n\t\t\t\tif (position + maxBytes > safeEnd)\r\n\t\t\t\t\ttarget = makeRoom(position + maxBytes)\r\n\r\n\t\t\t\tif (strLength < 0x40 || !encodeUtf8) {\r\n\t\t\t\t\tlet i, c1, c2, strPosition = position + headerSize\r\n\t\t\t\t\tfor (i = 0; i < strLength; i++) {\r\n\t\t\t\t\t\tc1 = value.charCodeAt(i)\r\n\t\t\t\t\t\tif (c1 < 0x80) {\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1\r\n\t\t\t\t\t\t} else if (c1 < 0x800) {\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 6 | 0xc0\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 & 0x3f | 0x80\r\n\t\t\t\t\t\t} else if (\r\n\t\t\t\t\t\t\t(c1 & 0xfc00) === 0xd800 &&\r\n\t\t\t\t\t\t\t((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\tc1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff)\r\n\t\t\t\t\t\t\ti++\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 18 | 0xf0\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 12 & 0x3f | 0x80\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 6 & 0x3f | 0x80\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 & 0x3f | 0x80\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 12 | 0xe0\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 >> 6 & 0x3f | 0x80\r\n\t\t\t\t\t\t\ttarget[strPosition++] = c1 & 0x3f | 0x80\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlength = strPosition - position - headerSize\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlength = encodeUtf8(value, position + headerSize, maxBytes)\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (length < 0x20) {\r\n\t\t\t\t\ttarget[position++] = 0xa0 | length\r\n\t\t\t\t} else if (length < 0x100) {\r\n\t\t\t\t\tif (headerSize < 2) {\r\n\t\t\t\t\t\ttarget.copyWithin(position + 2, position + 1, position + 1 + length)\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttarget[position++] = 0xd9\r\n\t\t\t\t\ttarget[position++] = length\r\n\t\t\t\t} else if (length < 0x10000) {\r\n\t\t\t\t\tif (headerSize < 3) {\r\n\t\t\t\t\t\ttarget.copyWithin(position + 3, position + 2, position + 2 + length)\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttarget[position++] = 0xda\r\n\t\t\t\t\ttarget[position++] = length >> 8\r\n\t\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (headerSize < 5) {\r\n\t\t\t\t\t\ttarget.copyWithin(position + 5, position + 3, position + 3 + length)\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttarget[position++] = 0xdb\r\n\t\t\t\t\ttargetView.setUint32(position, length)\r\n\t\t\t\t\tposition += 4\r\n\t\t\t\t}\r\n\t\t\t\tposition += length\r\n\t\t\t} else if (type === 'number') {\r\n\t\t\t\tif (value >>> 0 === value) {// positive integer, 32-bit or less\r\n\t\t\t\t\t// positive uint\r\n\t\t\t\t\tif (value < 0x40) {\r\n\t\t\t\t\t\ttarget[position++] = value\r\n\t\t\t\t\t} else if (value < 0x100) {\r\n\t\t\t\t\t\ttarget[position++] = 0xcc\r\n\t\t\t\t\t\ttarget[position++] = value\r\n\t\t\t\t\t} else if (value < 0x10000) {\r\n\t\t\t\t\t\ttarget[position++] = 0xcd\r\n\t\t\t\t\t\ttarget[position++] = value >> 8\r\n\t\t\t\t\t\ttarget[position++] = value & 0xff\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttarget[position++] = 0xce\r\n\t\t\t\t\t\ttargetView.setUint32(position, value)\r\n\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t}\r\n\t\t\t\t} else if (value >> 0 === value) { // negative integer\r\n\t\t\t\t\tif (value >= -0x20) {\r\n\t\t\t\t\t\ttarget[position++] = 0x100 + value\r\n\t\t\t\t\t} else if (value >= -0x80) {\r\n\t\t\t\t\t\ttarget[position++] = 0xd0\r\n\t\t\t\t\t\ttarget[position++] = value + 0x100\r\n\t\t\t\t\t} else if (value >= -0x8000) {\r\n\t\t\t\t\t\ttarget[position++] = 0xd1\r\n\t\t\t\t\t\ttargetView.setInt16(position, value)\r\n\t\t\t\t\t\tposition += 2\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttarget[position++] = 0xd2\r\n\t\t\t\t\t\ttargetView.setInt32(position, value)\r\n\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet useFloat32\r\n\t\t\t\t\tif ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {\r\n\t\t\t\t\t\ttarget[position++] = 0xca\r\n\t\t\t\t\t\ttargetView.setFloat32(position, value)\r\n\t\t\t\t\t\tlet xShifted\r\n\t\t\t\t\t\tif (useFloat32 < 4 ||\r\n\t\t\t\t\t\t\t\t// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved\r\n\t\t\t\t\t\t\t\t((xShifted = value * mult10[((target[position] & 0x7f) << 1) | (target[position + 1] >> 7)]) >> 0) === xShifted) {\r\n\t\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t\t\treturn\r\n\t\t\t\t\t\t} else\r\n\t\t\t\t\t\t\tposition-- // move back into position for writing a double\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttarget[position++] = 0xcb\r\n\t\t\t\t\ttargetView.setFloat64(position, value)\r\n\t\t\t\t\tposition += 8\r\n\t\t\t\t}\r\n\t\t\t} else if (type === 'object') {\r\n\t\t\t\tif (!value)\r\n\t\t\t\t\ttarget[position++] = 0xc0\r\n\t\t\t\telse {\r\n\t\t\t\t\tif (referenceMap) {\r\n\t\t\t\t\t\tlet referee = referenceMap.get(value)\r\n\t\t\t\t\t\tif (referee) {\r\n\t\t\t\t\t\t\tif (!referee.id) {\r\n\t\t\t\t\t\t\t\tlet idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = [])\r\n\t\t\t\t\t\t\t\treferee.id = idsToInsert.push(referee)\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\ttarget[position++] = 0xd6 // fixext 4\r\n\t\t\t\t\t\t\ttarget[position++] = 0x70 // \"p\" for pointer\r\n\t\t\t\t\t\t\ttargetView.setUint32(position, referee.id)\r\n\t\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t\t\treturn\r\n\t\t\t\t\t\t} else \r\n\t\t\t\t\t\t\treferenceMap.set(value, { offset: position - start })\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlet constructor = value.constructor\r\n\t\t\t\t\tif (constructor === Object) {\r\n\t\t\t\t\t\twriteObject(value, true)\r\n\t\t\t\t\t} else if (constructor === Array) {\r\n\t\t\t\t\t\tlength = value.length\r\n\t\t\t\t\t\tif (length < 0x10) {\r\n\t\t\t\t\t\t\ttarget[position++] = 0x90 | length\r\n\t\t\t\t\t\t} else if (length < 0x10000) {\r\n\t\t\t\t\t\t\ttarget[position++] = 0xdc\r\n\t\t\t\t\t\t\ttarget[position++] = length >> 8\r\n\t\t\t\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\ttarget[position++] = 0xdd\r\n\t\t\t\t\t\t\ttargetView.setUint32(position, length)\r\n\t\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tfor (let i = 0; i < length; i++) {\r\n\t\t\t\t\t\t\tpack(value[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else if (constructor === Map) {\r\n\t\t\t\t\t\tlength = value.size\r\n\t\t\t\t\t\tif (length < 0x10) {\r\n\t\t\t\t\t\t\ttarget[position++] = 0x80 | length\r\n\t\t\t\t\t\t} else if (length < 0x10000) {\r\n\t\t\t\t\t\t\ttarget[position++] = 0xde\r\n\t\t\t\t\t\t\ttarget[position++] = length >> 8\r\n\t\t\t\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\ttarget[position++] = 0xdf\r\n\t\t\t\t\t\t\ttargetView.setUint32(position, length)\r\n\t\t\t\t\t\t\tposition += 4\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tfor (let [ key, entryValue ] of value) {\r\n\t\t\t\t\t\t\tpack(key)\r\n\t\t\t\t\t\t\tpack(entryValue)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\t\r\n\t\t\t\t\t\tfor (let i = 0, l = extensions.length; i < l; i++) {\r\n\t\t\t\t\t\t\tlet extensionClass = extensionClasses[i]\r\n\t\t\t\t\t\t\tif (value instanceof extensionClass) {\r\n\t\t\t\t\t\t\t\tlet extension = extensions[i]\r\n\t\t\t\t\t\t\t\tif (extension.write) {\r\n\t\t\t\t\t\t\t\t\tif (extension.type) {\r\n\t\t\t\t\t\t\t\t\t\ttarget[position++] = 0xd4 // one byte \"tag\" extension\r\n\t\t\t\t\t\t\t\t\t\ttarget[position++] = extension.type\r\n\t\t\t\t\t\t\t\t\t\ttarget[position++] = 0\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tpack(extension.write.call(this, value))\r\n\t\t\t\t\t\t\t\t\treturn\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tlet currentTarget = target\r\n\t\t\t\t\t\t\t\tlet currentTargetView = targetView\r\n\t\t\t\t\t\t\t\tlet currentPosition = position\r\n\t\t\t\t\t\t\t\ttarget = null\r\n\t\t\t\t\t\t\t\tlet result\r\n\t\t\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\t\tresult = extension.pack.call(this, value, (size) => {\r\n\t\t\t\t\t\t\t\t\t\t// restore target and use it\r\n\t\t\t\t\t\t\t\t\t\ttarget = currentTarget\r\n\t\t\t\t\t\t\t\t\t\tcurrentTarget = null\r\n\t\t\t\t\t\t\t\t\t\tposition += size\r\n\t\t\t\t\t\t\t\t\t\tif (position > safeEnd)\r\n\t\t\t\t\t\t\t\t\t\t\tmakeRoom(position)\r\n\t\t\t\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t\t\t\ttarget, targetView, position: position - size\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t}, pack)\r\n\t\t\t\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t\t\t\t// restore current target information (unless already restored)\r\n\t\t\t\t\t\t\t\t\tif (currentTarget) {\r\n\t\t\t\t\t\t\t\t\t\ttarget = currentTarget\r\n\t\t\t\t\t\t\t\t\t\ttargetView = currentTargetView\r\n\t\t\t\t\t\t\t\t\t\tposition = currentPosition\r\n\t\t\t\t\t\t\t\t\t\tsafeEnd = target.length - 10\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif (result) {\r\n\t\t\t\t\t\t\t\t\tif (result.length + position > safeEnd)\r\n\t\t\t\t\t\t\t\t\t\tmakeRoom(result.length + position)\r\n\t\t\t\t\t\t\t\t\tposition = writeExtensionData(result, target, position, extension.type)\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\treturn\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// no extension found, write as object\r\n\t\t\t\t\t\twriteObject(value, !value.hasOwnProperty) // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (type === 'boolean') {\r\n\t\t\t\ttarget[position++] = value ? 0xc3 : 0xc2\r\n\t\t\t} else if (type === 'bigint') {\r\n\t\t\t\tif (value < (BigInt(1)<<BigInt(63)) && value >= -(BigInt(1)<<BigInt(63))) {\r\n\t\t\t\t\t// use a signed int as long as it fits\r\n\t\t\t\t\ttarget[position++] = 0xd3\r\n\t\t\t\t\ttargetView.setBigInt64(position, value)\r\n\t\t\t\t} else if (value < (BigInt(1)<<BigInt(64)) && value > 0) {\r\n\t\t\t\t\t// if we can fit an unsigned int, use that\r\n\t\t\t\t\ttarget[position++] = 0xcf\r\n\t\t\t\t\ttargetView.setBigUint64(position, value)\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// overflow\r\n\t\t\t\t\tif (this.largeBigIntToFloat) {\r\n\t\t\t\t\t\ttarget[position++] = 0xcb\r\n\t\t\t\t\t\ttargetView.setFloat64(position, Number(value))\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthrow new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, set largeBigIntToFloat to convert to float-64')\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tposition += 8\r\n\t\t\t} else if (type === 'undefined') {\r\n\t\t\t\tif (this.encodeUndefinedAsNil)\r\n\t\t\t\t\ttarget[position++] = 0xc0\r\n\t\t\t\telse {\r\n\t\t\t\t\ttarget[position++] = 0xd4 // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite\r\n\t\t\t\t\ttarget[position++] = 0\r\n\t\t\t\t\ttarget[position++] = 0\r\n\t\t\t\t}\r\n\t\t\t} else if (type === 'function') {\r\n\t\t\t\tpack(this.writeFunction && this.writeFunction()) // if there is a writeFunction, use it, otherwise just encode as undefined\r\n\t\t\t} else {\r\n\t\t\t\tthrow new Error('Unknown type: ' + type)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {\r\n\t\t\t// this method is slightly slower, but generates \"preferred serialization\" (optimally small for smaller objects)\r\n\t\t\tlet keys = Object.keys(object)\r\n\t\t\tlet length = keys.length\r\n\t\t\tif (length < 0x10) {\r\n\t\t\t\ttarget[position++] = 0x80 | length\r\n\t\t\t} else if (length < 0x10000) {\r\n\t\t\t\ttarget[position++] = 0xde\r\n\t\t\t\ttarget[position++] = length >> 8\r\n\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t} else {\r\n\t\t\t\ttarget[position++] = 0xdf\r\n\t\t\t\ttargetView.setUint32(position, length)\r\n\t\t\t\tposition += 4\r\n\t\t\t}\r\n\t\t\tlet key\r\n\t\t\tfor (let i = 0; i < length; i++) {\r\n\t\t\t\tpack(key = keys[i])\r\n\t\t\t\tpack(object[key])\r\n\t\t\t}\r\n\t\t} :\r\n\t\t(object, safePrototype) => {\r\n\t\t\ttarget[position++] = 0xde // always using map 16, so we can preallocate and set the length afterwards\r\n\t\t\tlet objectOffset = position - start\r\n\t\t\tposition += 2\r\n\t\t\tlet size = 0\r\n\t\t\tfor (let key in object) {\r\n\t\t\t\tif (safePrototype || object.hasOwnProperty(key)) {\r\n\t\t\t\t\tpack(key)\r\n\t\t\t\t\tpack(object[key])\r\n\t\t\t\t\tsize++\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ttarget[objectOffset++ + start] = size >> 8\r\n\t\t\ttarget[objectOffset + start] = size & 0xff\r\n\t\t} :\r\n\r\n\t/*\tsharedStructures ? // For highly stable structures, using for-in can a little bit faster\r\n\t\t(object, safePrototype) => {\r\n\t\t\tlet nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))\r\n\t\t\tlet objectOffset = position++ - start\r\n\t\t\tlet wroteKeys\r\n\t\t\tfor (let key in object) {\r\n\t\t\t\tif (safePrototype || object.hasOwnProperty(key)) {\r\n\t\t\t\t\tnextTransition = transition[key]\r\n\t\t\t\t\tif (!nextTransition) {\r\n\t\t\t\t\t\tnextTransition = transition[key] = Object.create(null)\r\n\t\t\t\t\t\tnextTransition.__keys__ = (transition.__keys__ || []).concat([key])\r\n\t\t\t\t\t\t/*let keys = Object.keys(object)\r\n\t\t\t\t\t\tif \r\n\t\t\t\t\t\tlet size = 0\r\n\t\t\t\t\t\tlet startBranch = transition.__keys__ ? transition.__keys__.length : 0\r\n\t\t\t\t\t\tfor (let i = 0, l = keys.length; i++) {\r\n\t\t\t\t\t\t\tlet key = keys[i]\r\n\t\t\t\t\t\t\tsize += key.length << 2\r\n\t\t\t\t\t\t\tif (i >= startBranch) {\r\n\t\t\t\t\t\t\t\tnextTransition = nextTransition[key] = Object.create(null)\r\n\t\t\t\t\t\t\t\tnextTransition.__keys__ = keys.slice(0, i + 1)\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tmakeRoom(position + size)\r\n\t\t\t\t\t\tnextTransition = transition[key]\r\n\t\t\t\t\t\ttarget.copy(target, )\r\n\t\t\t\t\t\tobjectOffset\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttransition = nextTransition\r\n\t\t\t\t\tpack(object[key])\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tlet id = transition.id\r\n\t\t\tif (!id) {\r\n\t\t\t\tid = transition.id = structures.push(transition.__keys__) + 63\r\n\t\t\t\tif (sharedStructures.onUpdate)\r\n\t\t\t\t\tsharedStructures.onUpdate(id, transition.__keys__)\r\n\t\t\t}\r\n\t\t\ttarget[objectOffset + start] = id\r\n\t\t}*/\r\n\t\t(object) => {\r\n\t\t\tlet keys = Object.keys(object)\r\n\t\t\tlet nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))\r\n\t\t\tlet newTransitions = 0\r\n\t\t\tfor (let i = 0, l = keys.length; i < l; i++) {\r\n\t\t\t\tlet key = keys[i]\r\n\t\t\t\tnextTransition = transition[key]\r\n\t\t\t\tif (!nextTransition) {\r\n\t\t\t\t\tnextTransition = transition[key] = Object.create(null)\r\n\t\t\t\t\tnewTransitions++\r\n\t\t\t\t}\r\n\t\t\t\ttransition = nextTransition\r\n\t\t\t}\r\n\t\t\tlet recordId = transition[RECORD_SYMBOL]\r\n\t\t\tif (recordId) {\r\n\t\t\t\tif (recordId >= 0x60 && useTwoByteRecords) {\r\n\t\t\t\t\ttarget[position++] = ((recordId -= 0x60) & 0x1f) + 0x60\r\n\t\t\t\t\ttarget[position++] = recordId >> 5\r\n\t\t\t\t} else\r\n\t\t\t\t\ttarget[position++] = recordId\r\n\t\t\t} else {\r\n\t\t\t\trecordId = structures.nextId\r\n\t\t\t\tif (!recordId)\r\n\t\t\t\t\trecordId = 0x40\r\n\t\t\t\tif (recordId < sharedLimitId && this.shouldShareStructure && !this.shouldShareStructure(keys)) {\r\n\t\t\t\t\trecordId = structures.nextOwnId\r\n\t\t\t\t\tif (!(recordId < maxStructureId))\r\n\t\t\t\t\t\trecordId = sharedLimitId\r\n\t\t\t\t\tstructures.nextOwnId = recordId + 1\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (recordId >= maxStructureId)// cycle back around\r\n\t\t\t\t\t\trecordId = sharedLimitId\r\n\t\t\t\t\tstructures.nextId = recordId + 1\r\n\t\t\t\t}\r\n\t\t\t\tlet highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1\r\n\t\t\t\ttransition[RECORD_SYMBOL] = recordId\r\n\t\t\t\tstructures[recordId - 0x40] = keys\r\n\r\n\t\t\t\tif (recordId < sharedLimitId) {\r\n\t\t\t\t\tkeys.isShared = true\r\n\t\t\t\t\tstructures.sharedLength = recordId - 0x3f\r\n\t\t\t\t\thasSharedUpdate = true\r\n\t\t\t\t\tif (highByte >= 0) {\r\n\t\t\t\t\t\ttarget[position++] = (recordId & 0x1f) + 0x60\r\n\t\t\t\t\t\ttarget[position++] = highByte\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttarget[position++] = recordId\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (highByte >= 0) {\r\n\t\t\t\t\t\ttarget[position++] = 0xd5 // fixext 2\r\n\t\t\t\t\t\ttarget[position++] = 0x72 // \"r\" record defintion extension type\r\n\t\t\t\t\t\ttarget[position++] = (recordId & 0x1f) + 0x60\r\n\t\t\t\t\t\ttarget[position++] = highByte\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\ttarget[position++] = 0xd4 // fixext 1\r\n\t\t\t\t\t\ttarget[position++] = 0x72 // \"r\" record defintion extension type\r\n\t\t\t\t\t\ttarget[position++] = recordId\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (newTransitions)\r\n\t\t\t\t\t\ttransitionsCount += serializationsSinceTransitionRebuild * newTransitions\r\n\t\t\t\t\t// record the removal of the id, we can maintain our shared structure\r\n\t\t\t\t\tif (recordIdsToRemove.length >= maxOwnStructures)\r\n\t\t\t\t\t\trecordIdsToRemove.shift()[RECORD_SYMBOL] = 0 // we are cycling back through, and have to remove old ones\r\n\t\t\t\t\trecordIdsToRemove.push(transition)\r\n\t\t\t\t\tpack(keys)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// now write the values\r\n\t\t\tfor (let i = 0, l = keys.length; i < l; i++)\r\n\t\t\t\tpack(object[keys[i]])\r\n\t\t}\r\n\t\tconst makeRoom = (end) => {\r\n\t\t\tlet newSize\r\n\t\t\tif (end > 0x1000000) {\r\n\t\t\t\t// special handling for really large buffers\r\n\t\t\t\tif ((end - start) > MAX_BUFFER_SIZE)\r\n\t\t\t\t\tthrow new Error('Packed buffer would be larger than maximum buffer size')\r\n\t\t\t\tnewSize = Math.min(MAX_BUFFER_SIZE,\r\n\t\t\t\t\tMath.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)\r\n\t\t\t} else // faster handling for smaller buffers\r\n\t\t\t\tnewSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12\r\n\t\t\tlet newBuffer = new ByteArrayAllocate(newSize)\r\n\t\t\ttargetView = new DataView(newBuffer.buffer, 0, newSize)\r\n\t\t\tif (target.copy)\r\n\t\t\t\ttarget.copy(newBuffer, 0, start, end)\r\n\t\t\telse\r\n\t\t\t\tnewBuffer.set(target.slice(start, end))\r\n\t\t\tposition -= start\r\n\t\t\tstart = 0\r\n\t\t\tsafeEnd = newBuffer.length - 10\r\n\t\t\treturn target = newBuffer\r\n\t\t}\r\n\t}\r\n\tuseBuffer(buffer) {\r\n\t\t// this means we are finished using our own buffer and we can write over it safely\r\n\t\ttarget = buffer\r\n\t\ttargetView = new DataView(target.buffer, target.byteOffset, target.byteLength)\r\n\t\tposition = 0\r\n\t}\r\n}\r\n\r\nfunction copyBinary(source, target, targetOffset, offset, endOffset) {\r\n\twhile (offset < endOffset) {\r\n\t\ttarget[targetOffset++] = source[offset++]\r\n\t}\r\n}\r\n\r\nextensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ]\r\nextensions = [{\r\n\tpack(date, allocateForWrite, pack) {\r\n\t\tlet seconds = date.getTime() / 1000\r\n\t\tif ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {\r\n\t\t\t// Timestamp 32\r\n\t\t\tlet { target, targetView, position} = allocateForWrite(6)\r\n\t\t\ttarget[position++] = 0xd6\r\n\t\t\ttarget[position++] = 0xff\r\n\t\t\ttargetView.setUint32(position, seconds)\r\n\t\t} else if (seconds > 0 && seconds < 0x400000000) {\r\n\t\t\t// Timestamp 64\r\n\t\t\tlet { target, targetView, position} = allocateForWrite(10)\r\n\t\t\ttarget[position++] = 0xd7\r\n\t\t\ttarget[position++] = 0xff\r\n\t\t\ttargetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))\r\n\t\t\ttargetView.setUint32(position + 4, seconds)\r\n\t\t} else if (isNaN(seconds)) {\r\n\t\t\tif (this.onInvalidDate) {\r\n\t\t\t\tallocateForWrite(0)\r\n\t\t\t\treturn pack(this.onInvalidDate())\r\n\t\t\t}\r\n\t\t\t// Intentionally invalid timestamp\r\n\t\t\tlet { target, targetView, position} = allocateForWrite(3)\r\n\t\t\ttarget[position++] = 0xd4\r\n\t\t\ttarget[position++] = 0xff\r\n\t\t\ttarget[position++] = 0xff\r\n\t\t} else {\r\n\t\t\t// Timestamp 96\r\n\t\t\tlet { target, targetView, position} = allocateForWrite(15)\r\n\t\t\ttarget[position++] = 0xc7\r\n\t\t\ttarget[position++] = 12\r\n\t\t\ttarget[position++] = 0xff\r\n\t\t\ttargetView.setUint32(position, date.getMilliseconds() * 1000000)\r\n\t\t\ttargetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)))\r\n\t\t}\r\n\t}\r\n}, {\r\n\tpack(set, allocateForWrite, pack) {\r\n\t\tlet array = Array.from(set)\r\n\t\tlet { target, position} = allocateForWrite(this.structuredClone ? 3 : 0)\r\n\t\tif (this.structuredClone) {\r\n\t\t\ttarget[position++] = 0xd4\r\n\t\t\ttarget[position++] = 0x73 // 's' for Set\r\n\t\t\ttarget[position++] = 0\r\n\t\t}\r\n\t\tpack(array)\r\n\t}\r\n}, {\r\n\tpack(error, allocateForWrite, pack) {\r\n\t\tlet { target, position} = allocateForWrite(this.structuredClone ? 3 : 0)\r\n\t\tif (this.structuredClone) {\r\n\t\t\ttarget[position++] = 0xd4\r\n\t\t\ttarget[position++] = 0x65 // 'e' for error\r\n\t\t\ttarget[position++] = 0\r\n\t\t}\r\n\t\tpack([ error.name, error.message ])\r\n\t}\r\n}, {\r\n\tpack(regex, allocateForWrite, pack) {\r\n\t\tlet { target, position} = allocateForWrite(this.structuredClone ? 3 : 0)\r\n\t\tif (this.structuredClone) {\r\n\t\t\ttarget[position++] = 0xd4\r\n\t\t\ttarget[position++] = 0x78 // 'x' for regeXp\r\n\t\t\ttarget[position++] = 0\r\n\t\t}\r\n\t\tpack([ regex.source, regex.flags ])\r\n\t}\r\n}, {\r\n\tpack(arrayBuffer, allocateForWrite) {\r\n\t\tif (this.structuredClone)\r\n\t\t\twriteExtBuffer(arrayBuffer, 0x10, allocateForWrite)\r\n\t\telse\r\n\t\t\twriteBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)\r\n\t}\r\n}, {\r\n\tpack(typedArray, allocateForWrite) {\r\n\t\tlet constructor = typedArray.constructor\r\n\t\tif (constructor !== ByteArray && this.structuredClone)\r\n\t\t\twriteExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite)\r\n\t\telse\r\n\t\t\twriteBuffer(typedArray, allocateForWrite)\r\n\t}\r\n}, {\r\n\tpack(c1, allocateForWrite) { // specific 0xC1 object\r\n\t\tlet { target, position} = allocateForWrite(1)\r\n\t\ttarget[position] = 0xc1\r\n\t}\r\n}]\r\n\r\nfunction writeExtBuffer(typedArray, type, allocateForWrite, encode) {\r\n\tlet length = typedArray.byteLength\r\n\tif (length + 1 < 0x100) {\r\n\t\tvar { target, position } = allocateForWrite(4 + length)\r\n\t\ttarget[position++] = 0xc7\r\n\t\ttarget[position++] = length + 1\r\n\t} else if (length + 1 < 0x10000) {\r\n\t\tvar { target, position } = allocateForWrite(5 + length)\r\n\t\ttarget[position++] = 0xc8\r\n\t\ttarget[position++] = (length + 1) >> 8\r\n\t\ttarget[position++] = (length + 1) & 0xff\r\n\t} else {\r\n\t\tvar { target, position, targetView } = allocateForWrite(7 + length)\r\n\t\ttarget[position++] = 0xc9\r\n\t\ttargetView.setUint32(position, length + 1) // plus one for the type byte\r\n\t\tposition += 4\r\n\t}\r\n\ttarget[position++] = 0x74 // \"t\" for typed array\r\n\ttarget[position++] = type\r\n\ttarget.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position)\r\n}\r\nfunction writeBuffer(buffer, allocateForWrite) {\r\n\tlet length = buffer.byteLength\r\n\tvar target, position\r\n\tif (length < 0x100) {\r\n\t\tvar { target, position } = allocateForWrite(length + 2)\r\n\t\ttarget[position++] = 0xc4\r\n\t\ttarget[position++] = length\r\n\t} else if (length < 0x10000) {\r\n\t\tvar { target, position } = allocateForWrite(length + 3)\r\n\t\ttarget[position++] = 0xc5\r\n\t\ttarget[position++] = length >> 8\r\n\t\ttarget[position++] = length & 0xff\r\n\t} else {\r\n\t\tvar { target, position, targetView } = allocateForWrite(length + 5)\r\n\t\ttarget[position++] = 0xc6\r\n\t\ttargetView.setUint32(position, length)\r\n\t\tposition += 4\r\n\t}\r\n\ttarget.set(buffer, position)\r\n}\r\n\r\nfunction writeExtensionData(result, target, position, type) {\r\n\tlet length = result.length\r\n\tswitch (length) {\r\n\t\tcase 1:\r\n\t\t\ttarget[position++] = 0xd4\r\n\t\t\tbreak\r\n\t\tcase 2:\r\n\t\t\ttarget[position++] = 0xd5\r\n\t\t\tbreak\r\n\t\tcase 4:\r\n\t\t\ttarget[position++] = 0xd6\r\n\t\t\tbreak\r\n\t\tcase 8:\r\n\t\t\ttarget[position++] = 0xd7\r\n\t\t\tbreak\r\n\t\tcase 16:\r\n\t\t\ttarget[position++] = 0xd8\r\n\t\t\tbreak\r\n\t\tdefault:\r\n\t\t\tif (length < 0x100) {\r\n\t\t\t\ttarget[position++] = 0xc7\r\n\t\t\t\ttarget[position++] = length\r\n\t\t\t} else if (length < 0x10000) {\r\n\t\t\t\ttarget[position++] = 0xc8\r\n\t\t\t\ttarget[position++] = length >> 8\r\n\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t} else {\r\n\t\t\t\ttarget[position++] = 0xc9\r\n\t\t\t\ttarget[position++] = length >> 24\r\n\t\t\t\ttarget[position++] = (length >> 16) & 0xff\r\n\t\t\t\ttarget[position++] = (length >> 8) & 0xff\r\n\t\t\t\ttarget[position++] = length & 0xff\r\n\t\t\t}\r\n\t}\r\n\ttarget[position++] = type\r\n\ttarget.set(result, position)\r\n\tposition += length\r\n\treturn position\r\n}\r\n\r\nfunction insertIds(serialized, idsToInsert) {\r\n\t// insert the ids that need to be referenced for structured clones\r\n\tlet nextId\r\n\tlet distanceToMove = idsToInsert.length * 6\r\n\tlet lastEnd = serialized.length - distanceToMove\r\n\tidsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1)\r\n\twhile (nextId = idsToInsert.pop()) {\r\n\t\tlet offset = nextId.offset\r\n\t\tlet id = nextId.id\r\n\t\tserialized.copyWithin(offset + distanceToMove, offset, lastEnd)\r\n\t\tdistanceToMove -= 6\r\n\t\tlet position = offset + distanceToMove\r\n\t\tserialized[position++] = 0xd6\r\n\t\tserialized[position++] = 0x69 // 'i'\r\n\t\tserialized[position++] = id >> 24\r\n\t\tserialized[position++] = (id >> 16) & 0xff\r\n\t\tserialized[position++] = (id >> 8) & 0xff\r\n\t\tserialized[position++] = id & 0xff\r\n\t\tlastEnd = offset\r\n\t}\r\n\treturn serialized\r\n}\r\n\r\nexport function addExtension(extension) {\r\n\tif (extension.Class) {\r\n\t\tif (!extension.pack && !extension.write)\r\n\t\t\tthrow new Error('Extension has no pack or write function')\r\n\t\tif (extension.pack && !extension.type)\r\n\t\t\tthrow new Error('Extension has no type (numeric code to identify the extension)')\r\n\t\textensionClasses.unshift(extension.Class)\r\n\t\textensions.unshift(extension)\r\n\t}\r\n\tunpackAddExtension(extension)\r\n}\r\n\r\nlet defaultPackr = new Packr({ useRecords: false })\r\nexport const pack = defaultPackr.pack\r\nexport const encode = defaultPackr.pack\r\nexport const Encoder = Packr\r\nexport { FLOAT32_OPTIONS } from './unpack.js'\r\nimport { FLOAT32_OPTIONS } from './unpack.js'\r\nexport const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS\r\nexport const REUSE_BUFFER_MODE = 512\r\nexport const RESET_BUFFER_MODE = 1024\r\n", "import { Packr, addExtension } from 'msgpackr';\n// import { CompressedBin, ExternalBin } from './bigbin';\n// import { Seq } from './Seq';\n// import { Table } from './Table';\n// import { Tree } from './Tree';\n\nconst myPackr = new Packr({\n\tstructuredClone: true, // FIXME!!!!!!!!!!!!!!!!!!! temp\n});\n\n// addExtension({\n// \tClass: Table.prototype.constructor,\n// \ttype: 1,\n// \twrite(t) {\n// \t\treturn { ...t };\n// \t},\n// \tread(data) {\n// \t\tObject.setPrototypeOf(data, Table.prototype);\n// \t\treturn data;\n// \t},\n// });\n\n// addExtension({\n// \tClass: Seq.prototype.constructor,\n// \ttype: 2,\n// \twrite(t) {\n// \t\treturn [...t];\n// \t},\n// \tread(data) {\n// \t\tObject.setPrototypeOf(data, Seq.prototype);\n// \t\treturn data;\n// \t},\n// });\n\n// addExtension({\n// \tClass: Tree.prototype.constructor,\n// \ttype: 3,\n// \twrite(t) {\n// \t\treturn [...t];\n// \t},\n// \tread(data) {\n// \t\tObject.setPrototypeOf(data, Tree.prototype);\n// \t\treturn data;\n// \t},\n// });\n\n// addExtension({\n// \tClass: ExternalBin.prototype.constructor,\n// \ttype: 4,\n// \twrite(t) {\n// \t\treturn t.id;\n// \t},\n// \tread(data) {\n// \t\treturn new ExternalBin(data);\n// \t},\n// });\n\n// addExtension({\n// \tClass: CompressedBin.prototype.constructor,\n// \ttype: 5,\n// \twrite(t) {\n// \t\treturn t.data;\n// \t},\n// \tread(data) {\n// \t\treturn new CompressedBin(data);\n// \t},\n// });\n\nfunction hashCode(str: Buffer) {\n\tvar hash = 0;\n\tif (str.length === 0) return hash;\n\tfor (let i = 0; i < str.length; i++) {\n\t\tlet char = str[i];\n\t\thash = (hash << 5) - hash + char;\n\t\thash = hash & hash; // Convert to 32bit integer\n\t}\n\treturn hash;\n}\n\nexport namespace CollabSerialize {\n\texport function serialize(obj: any): Buffer {\n\t\treturn myPackr.pack(obj);\n\t}\n\texport function deserialize(buffer: Buffer | Uint8Array) {\n\t\treturn myPackr.unpack(buffer);\n\t}\n\t// TODO this should sort object by field order\n\texport function checksum(obj: any): string {\n\t\treturn hashCode(serialize(obj)).toString();\n\t}\n}\n", "import { RGB, RGBA, Sharable } from './primitives';\n\nexport type LightType =\n\t| 'PointLight'\n\t| 'SpotLight'\n\t| 'DirectionalLight'\n\t| 'HemisphereLight';\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace LightType {\n\texport const all: LightType[] = [\n\t\t'PointLight',\n\t\t'SpotLight',\n\t\t'DirectionalLight',\n\t\t'HemisphereLight',\n\t];\n\texport function is(a: string | undefined): boolean {\n\t\treturn (all as any[]).includes(a);\n\t}\n}\n\nexport type BaseLightState = {\n\treadonly type: LightType;\n\treadonly color: Sharable<RGB>;\n\treadonly intensity: number;\n\treadonly depth: number;\n\treadonly shadows: boolean; // true\n\treadonly helper: boolean;\n};\nexport type PointLightState = BaseLightState & {\n\treadonly type: 'PointLight';\n\treadonly distance: number;\n\treadonly decay: number;\n\treadonly shadowResolution: number;\n\treadonly shadowRadius: number;\n};\nexport type SpotLightState = BaseLightState & {\n\treadonly type: 'SpotLight';\n\treadonly distance: number;\n\treadonly angle: number;\n\treadonly penumbra: number;\n\treadonly decay: number;\n};\nexport type DirectionalLightState = BaseLightState & {\n\treadonly type: 'DirectionalLight';\n\treadonly size: number;\n};\n\nexport type HemisphereLightState = Omit<BaseLightState, 'shadows'> & {\n\treadonly type: 'HemisphereLight';\n\treadonly groundColor: RGB;\n};\n\nexport type LightState =\n\t| PointLightState\n\t| SpotLightState\n\t| DirectionalLightState\n\t| HemisphereLightState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace LightState {\n\texport function defaultData<T extends LightType>(\n\t\ttype: T\n\t): LightState & { type: T } {\n\t\treturn defaultDataInner(type) as any;\n\t}\n\n\tfunction defaultDataInner(type: LightType): LightState {\n\t\tif (type === 'PointLight') {\n\t\t\treturn {\n\t\t\t\ttype,\n\t\t\t\tcolor: RGBA.white,\n\t\t\t\tintensity: 1,\n\t\t\t\tdistance: 2000,\n\t\t\t\tdecay: 1,\n\t\t\t\tshadows: true,\n\t\t\t\tshadowResolution: 1024,\n\t\t\t\tshadowRadius: 1,\n\t\t\t\tdepth: 2500,\n\t\t\t\thelper: true,\n\t\t\t};\n\t\t} else if (type === 'SpotLight') {\n\t\t\treturn {\n\t\t\t\ttype,\n\t\t\t\tcolor: RGBA.white,\n\t\t\t\tintensity: 1,\n\t\t\t\tdistance: 2000,\n\t\t\t\tdecay: 1,\n\t\t\t\tshadows: true,\n\t\t\t\tpenumbra: 0,\n\t\t\t\tangle: (30 / 180) * Math.PI,\n\t\t\t\tdepth: 2500,\n\t\t\t\thelper: true,\n\t\t\t};\n\t\t} else if (type === 'DirectionalLight') {\n\t\t\treturn {\n\t\t\t\ttype,\n\t\t\t\tcolor: RGBA.white,\n\t\t\t\tintensity: 1,\n\t\t\t\tshadows: true,\n\t\t\t\tsize: 2500,\n\t\t\t\tdepth: 2500,\n\t\t\t\thelper: true,\n\t\t\t};\n\t\t} else {\n\t\t\tthrow new Error('not implemented');\n\t\t}\n\t}\n}\n\nexport type LightInteractionState = {\n\treadonly intensity: number;\n\treadonly color: RGB;\n};\n", "import {\n\tGeometryInteractionState,\n\tNonParametricGeometryParameters,\n\tSubdivGeometryParameters,\n\tParametricGeometryState,\n} from './geometry';\nimport { ClonerState } from './cloner';\nimport { MaterialState, MaterialInteractionState } from './material';\nimport { Sharable } from './primitives';\n\nexport enum Side {\n\tFront,\n\tBack,\n\tDouble,\n}\n\nexport type MeshShadowsState = {\n\treadonly castShadow: boolean;\n\treadonly receiveShadow: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace MeshShadowsState {\n\texport const defaultData: MeshShadowsState = {\n\t\tcastShadow: true,\n\t\treceiveShadow: true,\n\t};\n\texport function equals(a: MeshShadowsState, b: MeshShadowsState) {\n\t\treturn a.castShadow === b.castShadow && a.receiveShadow === b.receiveShadow;\n\t}\n}\n\nexport type MeshVisibilityState = {\n\treadonly flatShading: boolean;\n\treadonly wireframe: boolean;\n\treadonly side: Side;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace MeshVisibilityState {\n\texport const defaultData: MeshVisibilityState = {\n\t\tflatShading: false,\n\t\twireframe: false,\n\t\tside: Side.Front,\n\t};\n\texport function equals(a: MeshVisibilityState, b: MeshVisibilityState) {\n\t\treturn (\n\t\t\ta.flatShading === b.flatShading &&\n\t\t\ta.side === b.side &&\n\t\t\ta.wireframe === b.wireframe\n\t\t);\n\t}\n}\n\nexport type BaseMeshState = MeshShadowsState &\n\tMeshVisibilityState & {\n\t\treadonly cloner: ClonerState | null;\n\t};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace BaseMeshState {\n\texport const defaultData: BaseMeshState = {\n\t\t...MeshVisibilityState.defaultData,\n\t\t...MeshShadowsState.defaultData,\n\t\tcloner: null,\n\t};\n}\n\nexport type ParametricMeshMaterialGeometry = {\n\treadonly material: Sharable<MaterialState>;\n\treadonly geometry: ParametricGeometryState;\n};\n\nexport type NonParametricMaterialGeometry = {\n\treadonly materials: Sharable<MaterialState>[];\n\treadonly geometry: NonParametricGeometryParameters;\n};\n\nexport type SubdivMaterialGeometry = {\n\treadonly material: Sharable<MaterialState>;\n\treadonly geometry: SubdivGeometryParameters;\n};\n\nexport type ParametricMeshState = BaseMeshState &\n\tParametricMeshMaterialGeometry;\nexport type NonParametricMeshState = BaseMeshState &\n\tNonParametricMaterialGeometry;\nexport type SubdivMeshState = BaseMeshState & SubdivMaterialGeometry;\n\nexport type MeshState =\n\t| ParametricMeshState\n\t| NonParametricMeshState\n\t| SubdivMeshState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\n\nexport type MeshInteractionState = {\n\treadonly geometry: GeometryInteractionState;\n\t// TODO(spline-data) better typing of this\n\treadonly materials: readonly MaterialInteractionState[] | null;\n\treadonly material: MaterialInteractionState | null;\n};\n", "import { RGBA, Sharable } from './primitives';\n\nexport type Font = string;\nexport enum HorizontalAlign {\n\tLeft = 1,\n\tRight = 2,\n\tCenter = 3,\n\tJustify = 4,\n}\n\nexport enum VerticalAlign {\n\tTop = 1,\n\tCenter = 2,\n\tBottom = 3,\n}\n\nexport enum TextTransform {\n\tNone = 1,\n\tUpper = 2,\n\tLower = 3,\n}\n\nexport type SpanStyle = {\n\treadonly color: Sharable<RGBA>;\n\treadonly alpha: number;\n\treadonly font: Font;\n};\n\nexport type StyledSpan = {\n\treadonly text: string;\n} & Partial<SpanStyle>;\n\nexport type RichSpan = string | StyledSpan;\n\nexport type TextFrameData = {\n\treadonly width: number;\n\treadonly height: number;\n\treadonly horizontalAlign: HorizontalAlign;\n\treadonly verticalAlign: VerticalAlign;\n\treadonly fontSize: number;\n\treadonly lineHeight: number;\n\treadonly letterSpacing: number;\n\treadonly text: string;\n\t// TODO(spline-data) paragraphs?\n\t// TODO(spline-data) we don't support rich text yet? I guess?\n\t//readonly text: RichSpan[];\n\treadonly textTransform: TextTransform;\n} & SpanStyle;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace TextFrameData {\n\texport const defaultData: TextFrameData = {\n\t\twidth: 100,\n\t\theight: 100,\n\t\thorizontalAlign: HorizontalAlign.Left,\n\t\tverticalAlign: VerticalAlign.Top,\n\t\tfontSize: 16,\n\t\tlineHeight: 1.5,\n\t\tletterSpacing: 1,\n\t\ttext: '',\n\t\ttextTransform: TextTransform.None,\n\t\tcolor: RGBA.fromHexAndA(0x6a6a6a, 1),\n\t\talpha: 1.0,\n\t\tfont: 'roboto_regular',\n\t};\n}\n", "import { Ref, Seq, Table } from 'collab-data';\nimport { Nullable, Sharable } from './primitives';\nimport { Image } from './image';\n\nimport { RGBA, Vector2, Vector3, Axis, RGB, Vector4 } from './primitives';\n\nexport const NodeTypesExceptLight = {\n\tImage: 'texture',\n\tColor: 'color',\n\tDepth: 'depth',\n\tNormal: 'normal',\n\tGradient: 'gradient',\n\tNoise: 'noise',\n\tFresnel: 'fresnel',\n\tRainbow: 'rainbow',\n\tGlass: 'transmission',\n\tMatcap: 'matcap',\n\tDisplace: 'displace',\n};\n\nexport type NonLightNodeType =\n\t| 'texture'\n\t| 'color'\n\t| 'depth'\n\t| 'normal'\n\t| 'gradient'\n\t| 'noise'\n\t| 'fresnel'\n\t| 'rainbow'\n\t| 'transmission'\n\t| 'matcap'\n\t| 'displace';\n\nexport type NodeType = 'light' | NonLightNodeType;\n\nexport type AbstractMaterialLayer<T extends NodeType> = {\n\treadonly type: T; // lambert, gradient, etc\n\treadonly visible: boolean;\n};\n\nexport enum FragmentBlendingMode {\n\tNormal,\n\tMultiply,\n\tScreen,\n\tOverlay,\n}\n\nexport type Texture = {\n\treadonly image: Sharable<Image>; // ref to Shared data\n\treadonly wrapping: Wrapping;\n\treadonly repeat: Vector2;\n\treadonly offset: Vector2;\n};\n\n// Marking the difference between layers that affect the pixels...\nexport type AbstractFragmentLayer<T extends NodeType> =\n\tAbstractMaterialLayer<T> & {\n\t\t/**\n\t\t * Layer opacity. 0-1\n\t\t */\n\t\treadonly alpha: number;\n\t\treadonly mode: FragmentBlendingMode;\n\t};\n\n// ... and the layers that affect vertices\nexport type AbstractVertexLayer<T extends NodeType> =\n\tAbstractMaterialLayer<T> & {\n\t\treadonly intensity: number;\n\t};\n\nexport type LightCategory = 'basic' | 'phong' | 'toon' | 'lambert' | 'physical';\n\nexport type AbstractLightLayer = AbstractFragmentLayer<'light'> & {\n\treadonly category: LightCategory;\n};\n\n// Light Layer state types\nexport type BasicLightLayer = AbstractLightLayer & {\n\treadonly category: 'basic';\n};\nexport type PhongLightLayer = AbstractLightLayer & {\n\treadonly category: 'phong';\n\treadonly specular: Sharable<RGB>;\n\treadonly shininess: number;\n};\n\nexport type ToonLightLayer = AbstractLightLayer & {\n\treadonly category: 'toon';\n\treadonly specular: Sharable<RGB>;\n\treadonly shininess: number;\n};\nexport type LambertLightLayer = AbstractLightLayer & {\n\treadonly category: 'lambert';\n\treadonly emissive: Sharable<RGBA>;\n};\nexport type StandardLightLayer = AbstractLightLayer & {\n\treadonly category: 'physical';\n\treadonly roughness: number;\n\treadonly metalness: number;\n\treadonly reflectivity: number;\n};\n\nexport type LightLayer =\n\t| BasicLightLayer\n\t| LambertLightLayer\n\t| PhongLightLayer\n\t| ToonLightLayer\n\t| StandardLightLayer;\n\n// Other layer state types\nexport type ColorLayer = AbstractFragmentLayer<'color'> & {\n\treadonly color: Sharable<RGB>;\n};\n\nexport enum GradientType {\n\tLinear,\n\tRadial,\n\tPolar,\n}\n\nexport type GradientLayer = AbstractFragmentLayer<'gradient'> & {\n\treadonly gradientType: GradientType;\n\treadonly smooth: boolean;\n\treadonly colors: Vector4[];\n\treadonly steps: number[]; // array of color % in gradient\n\treadonly num: number;\n\treadonly angle: number;\n\treadonly offset: Vector2;\n\treadonly morph: Vector2;\n};\nexport type NormalLayer = AbstractFragmentLayer<'normal'> & {\n\treadonly cnormal: Vector3;\n};\nexport type DepthLayer = AbstractFragmentLayer<'depth'> & {\n\treadonly gradientType: GradientType;\n\treadonly smooth: boolean;\n\treadonly isVector: boolean; // used as a boolean\n\treadonly isWorldSpace: boolean; // used as a boolean\n\treadonly origin: Vector3;\n\treadonly direction: Vector3;\n\treadonly colors: Vector4[];\n\treadonly steps: number[]; // array of color % in gradient\n\treadonly num: number;\n\treadonly near: number;\n\treadonly far: number;\n};\n\nexport enum Wrapping {\n\tRepeatWrapping = 1000,\n\tClampToEdgeWrapping = 1001,\n\tMirroredRepeatWrapping = 1002,\n}\n\nexport enum ProjectionType {\n\tUV,\n\tPlanar,\n\tSpherical,\n\tCylindrical,\n}\n\nexport type TextureLayer = AbstractFragmentLayer<'texture'> & {\n\treadonly projection: ProjectionType;\n\treadonly size: Vector2; // Currently only used with ProjectionType.Cylindrical and ProjectionType.Planar\n\treadonly axis: Axis;\n\treadonly crop: boolean;\n\treadonly texture: Texture;\n};\n\nexport enum NoiseType {\n\tSimplex,\n\tSimplexFractal,\n\tAshima,\n\tFbm,\n\tPerlin,\n}\n\nexport type NoiseLayer = AbstractFragmentLayer<'noise'> & {\n\treadonly noiseType: NoiseType;\n\treadonly scale: number;\n\treadonly size: Vector3;\n\treadonly move: number;\n\treadonly colorA: Sharable<RGBA>;\n\treadonly colorB: Sharable<RGBA>;\n\treadonly colorC: Sharable<RGBA>;\n\treadonly colorD: Sharable<RGBA>;\n\treadonly distortion: Vector2;\n\treadonly fA: Vector2;\n\treadonly fB: Vector2;\n};\nexport type FresnelLayer = AbstractFragmentLayer<'fresnel'> & {\n\treadonly color: Sharable<RGBA>;\n\treadonly bias: number;\n\treadonly scale: number;\n\treadonly intensity: number;\n\treadonly factor: number;\n};\nexport type RainbowLayer = AbstractFragmentLayer<'rainbow'> & {\n\treadonly filmThickness: number;\n\treadonly movement: number;\n\treadonly wavelengths: Vector3;\n\treadonly noiseStrength: number;\n\treadonly noiseScale: number;\n\treadonly offset: Vector3;\n};\n\nexport type TransmissionLayer = AbstractFragmentLayer<'transmission'> & {\n\treadonly thickness: number;\n\treadonly ior: number;\n\treadonly roughness: number;\n};\n\nexport type MatcapLayer = AbstractFragmentLayer<'matcap'> & {\n\treadonly texture: Texture;\n};\n\nexport type AbstractDisplaceLayer<T extends string> =\n\tAbstractVertexLayer<'displace'> & {\n\t\treadonly displacementType: T;\n\t};\n\nexport type MapDisplaceLayer = AbstractDisplaceLayer<'map'> & {\n\treadonly crop: boolean;\n};\nexport type NoiseDisplaceLayer = AbstractDisplaceLayer<'noise'> & {\n\treadonly noiseType: NoiseType;\n\treadonly scale: number;\n\treadonly movement: number;\n\treadonly offset: Vector3;\n};\nexport type DisplaceLayer = MapDisplaceLayer | NoiseDisplaceLayer;\nexport type NonLightLayer =\n\t| DisplaceLayer\n\t| MatcapLayer\n\t| FresnelLayer\n\t| RainbowLayer\n\t| TransmissionLayer\n\t| NoiseLayer\n\t| TextureLayer\n\t| DepthLayer\n\t| NormalLayer\n\t| GradientLayer\n\t| ColorLayer;\n\nexport type Layer = LightLayer | NonLightLayer;\n\n// Numeric data type parameters that we don't want to interpolate.\n// In case we want to interpolate the blacklist and booleans: we should able to\n// change them in runtime interpolation, but some of them don't work (need more test)\nexport const MaterialNonAnimatableList = [\n\t'mode',\n\t'gradientType',\n\t'noiseType',\n\t'displacementType',\n\t// Careful in case we want to interpolate crop: the shader works\n\t// `crop` as number, but TextureLayer declare it as boolean\n\t'crop',\n];\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Layer {\n\texport function defaultData<T extends NodeType>(\n\t\ttype: T,\n\t\tcategory?: LightCategory\n\t): Layer & { type: T } {\n\t\tif (type === 'light' && category) {\n\t\t\treturn defaultDataLight(category) as Layer & { type: T };\n\t\t}\n\t\treturn defaultDataInner(type as NonLightNodeType) as Layer & { type: T };\n\t}\n\n\tfunction defaultDataLight(category: LightCategory): LightLayer {\n\t\tswitch (category) {\n\t\t\tcase 'basic': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'light',\n\t\t\t\t\tcategory: 'basic',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'phong': {\n\t\t\t\treturn {\n\t\t\t\t\tcategory: 'phong',\n\t\t\t\t\tspecular: { r: 0.2, g: 0.2, b: 0.2 },\n\t\t\t\t\tshininess: 10,\n\t\t\t\t\ttype: 'light',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'toon': {\n\t\t\t\treturn {\n\t\t\t\t\tcategory: 'toon',\n\t\t\t\t\tspecular: { r: 0.2, g: 0.2, b: 0.2 },\n\t\t\t\t\tshininess: 10,\n\t\t\t\t\ttype: 'light',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'lambert': {\n\t\t\t\treturn {\n\t\t\t\t\tcategory: 'lambert',\n\t\t\t\t\temissive: { r: 0.2, g: 0.2, b: 0.2, a: 1.0 },\n\t\t\t\t\ttype: 'light',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'physical': {\n\t\t\t\treturn {\n\t\t\t\t\tcategory: 'physical',\n\t\t\t\t\troughness: 0.2,\n\t\t\t\t\tmetalness: 0.2,\n\t\t\t\t\treflectivity: 0.2,\n\t\t\t\t\ttype: 'light',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction defaultDataInner(type: NonLightNodeType): Layer {\n\t\tswitch (type) {\n\t\t\tcase 'texture': {\n\t\t\t\treturn {\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tsize: [128, 128],\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\taxis: Axis.x,\n\t\t\t\t\ttype: 'texture',\n\t\t\t\t\tprojection: ProjectionType.UV,\n\t\t\t\t\ttexture: {\n\t\t\t\t\t\timage: 'image_0', // default texture, see SharedAssetsManager and materials/create.ts\n\t\t\t\t\t\twrapping: Wrapping.ClampToEdgeWrapping,\n\t\t\t\t\t\trepeat: [1, 1],\n\t\t\t\t\t\toffset: [0, 0],\n\t\t\t\t\t},\n\t\t\t\t\tcrop: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'color': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'color',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tcolor: RGB.fromHex(0x48484d),\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'depth': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'depth',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tgradientType: GradientType.Radial,\n\t\t\t\t\tsmooth: false,\n\t\t\t\t\tisVector: true,\n\t\t\t\t\tisWorldSpace: false,\n\t\t\t\t\torigin: [0, 0, 0],\n\t\t\t\t\tdirection: [1, 0, 0],\n\t\t\t\t\tcolors: [\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t],\n\n\t\t\t\t\tsteps: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n\t\t\t\t\tnum: 2,\n\t\t\t\t\tnear: 50,\n\t\t\t\t\tfar: 200,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'normal': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'normal',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tcnormal: [1, 1, 1],\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gradient': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'gradient',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tgradientType: GradientType.Linear,\n\t\t\t\t\tsmooth: false,\n\t\t\t\t\tcolors: [\n\t\t\t\t\t\t[0, 0, 0, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t\t[1, 1, 1, 1],\n\t\t\t\t\t],\n\t\t\t\t\tsteps: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n\t\t\t\t\tnum: 2,\n\t\t\t\t\tangle: 0,\n\t\t\t\t\toffset: [0, 0],\n\t\t\t\t\tmorph: [0, 0],\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'noise': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'noise',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tsize: [100, 100, 100],\n\t\t\t\t\tnoiseType: NoiseType.Simplex,\n\t\t\t\t\tscale: 1,\n\t\t\t\t\tmove: 1,\n\t\t\t\t\tcolorA: { ...RGB.fromHex(0x666666), a: 1 },\n\t\t\t\t\tcolorB: { ...RGB.fromHex(0x666666), a: 1 },\n\t\t\t\t\tcolorC: { ...RGB.fromHex(0xffffff), a: 1 },\n\t\t\t\t\tcolorD: { ...RGB.fromHex(0xffffff), a: 1 },\n\t\t\t\t\tdistortion: [1, 1],\n\t\t\t\t\tfA: [1.7, 9.2],\n\t\t\t\t\tfB: [8.3, 2.8],\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'fresnel': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'fresnel',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tcolor: RGBA.fromHexAndA(0xffffff, 1),\n\t\t\t\t\tbias: 0.1,\n\t\t\t\t\tscale: 1,\n\t\t\t\t\tintensity: 2,\n\t\t\t\t\tfactor: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'rainbow': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'rainbow',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tfilmThickness: 30,\n\t\t\t\t\tmovement: 0,\n\t\t\t\t\twavelengths: [0, 0, 0],\n\t\t\t\t\tnoiseStrength: 0,\n\t\t\t\t\tnoiseScale: 1,\n\t\t\t\t\toffset: [0, 0, 0],\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'matcap': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'matcap',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\ttexture: {\n\t\t\t\t\t\timage: 'matcap_0', // default texture, see SharedAssetsManager and materials/create.ts\n\t\t\t\t\t\twrapping: Wrapping.ClampToEdgeWrapping,\n\t\t\t\t\t\trepeat: [1, 1],\n\t\t\t\t\t\toffset: [0, 0],\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'transmission': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'transmission',\n\t\t\t\t\talpha: 1,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tmode: FragmentBlendingMode.Normal,\n\t\t\t\t\tthickness: 10,\n\t\t\t\t\tior: 1.5,\n\t\t\t\t\troughness: 1,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'displace': {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'displace',\n\t\t\t\t\tdisplacementType: 'noise',\n\t\t\t\t\tnoiseType: NoiseType.Simplex,\n\t\t\t\t\tscale: 10,\n\t\t\t\t\tmovement: 1,\n\t\t\t\t\toffset: [0, 0, 0],\n\t\t\t\t\tintensity: 8,\n\t\t\t\t\tvisible: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport type MaterialState = {\n\treadonly name?: string; // only used during export, not used in Editor for non-asssets\n\treadonly layers: Seq<Layer>; // the order is the same in UI\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace MaterialState {\n\t/*\n\t * Returns true if merging the geometries of objects using this material\n\t * results in a visually identical result.\n\t */\n\texport function isMergable(state: MaterialState): boolean {\n\t\tconst mergable = !state.layers.some((l) => {\n\t\t\tif (l.data.type === 'texture' && l.data.projection !== ProjectionType.UV)\n\t\t\t\treturn true;\n\t\t\tif (l.data.type === 'depth' && !l.data.isWorldSpace) return true;\n\t\t\tif (l.data.type === 'noise') return true;\n\t\t\tif (l.data.type === 'displace') return true;\n\t\t});\n\n\t\treturn mergable && !isTransparent(state);\n\t}\n\n\t/*\n\t * Returns a very unsexy hash string for a material.\n\t * Used to group similar non-asset materials when merging geometries.\n\t */\n\texport function getHash(state: MaterialState): string {\n\t\tlet hash = '';\n\t\tstate.layers.forEach((l) => {\n\t\t\tObject.entries(l.data).forEach(([k, v]) => {\n\t\t\t\thash += `${k}${v}`;\n\t\t\t\tif (Array.isArray(v)) {\n\t\t\t\t\tv.forEach((e) => (hash += `${e}`));\n\t\t\t\t} else if (typeof v === 'object') {\n\t\t\t\t\tObject.values(v).forEach((vv) => {\n\t\t\t\t\t\tif (typeof vv === 'number') {\n\t\t\t\t\t\t\thash += `${vv.toFixed(4)}`;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\thash += `${vv}`;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\thash += `${v}`;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\treturn hash;\n\t}\n\n\t/*\n\t * Returns true if this material needs transparency.\n\t * This is an estimation of the resulting shader color,\n\t * and should be tuned conservatively to not miss any cases.\n\t */\n\texport function isTransparent(state: MaterialState): boolean {\n\t\tlet accumAlpha = 0;\n\t\tfor (const l of state.layers) {\n\t\t\tif (\n\t\t\t\t'alpha' in l.data &&\n\t\t\t\tl.data.type !== 'light' &&\n\t\t\t\tl.data.type !== 'fresnel'\n\t\t\t) {\n\t\t\t\taccumAlpha += (1 - accumAlpha) * l.data.alpha;\n\t\t\t}\n\t\t}\n\t\treturn accumAlpha < 1;\n\t}\n\n\texport function defaultEmptyData(): MaterialState {\n\t\tlet layers = new Seq<Layer>();\n\t\treturn {\n\t\t\tlayers,\n\t\t};\n\t}\n\n\texport function defaultData(\n\t\tid1: string = 'layer1',\n\t\tid2: string = 'layer2'\n\t): MaterialState {\n\t\treturn defaultTwoLayerData('phong', id1, id2);\n\t}\n\t/**\n\t * a light type and a default color\n\t */\n\texport function defaultTwoLayerData(\n\t\tlight: LightCategory,\n\t\tid1: string = 'layer1',\n\t\tid2: string = 'layer2'\n\t): MaterialState {\n\t\tlet layers = new Seq<Layer>();\n\t\tlayers.push({ fi: 0, data: Layer.defaultData('light', light), id: id1 });\n\t\tlayers.push({ fi: 1, data: Layer.defaultData('color'), id: id2 });\n\t\treturn {\n\t\t\tlayers,\n\t\t};\n\t}\n\t/**\n\t * a light type and a default texture\n\t */\n\texport function defaultTwoLayerTextureData(\n\t\timage: Sharable<Image>,\n\t\tlight: LightCategory = 'basic',\n\t\tid1: string = 'layer1',\n\t\tid2: string = 'layer2'\n\t): MaterialState {\n\t\tconst textureLayerData = Layer.defaultData('texture');\n\t\tObject.assign(textureLayerData.texture, { image });\n\t\tlet layers = new Seq<Layer>();\n\t\tlayers.push({ fi: 0, data: textureLayerData, id: id1 });\n\t\tlayers.push({ fi: 1, data: Layer.defaultData('light', light), id: id2 });\n\t\treturn {\n\t\t\tlayers,\n\t\t};\n\t}\n}\n\n// see `MaterialNonAnimatableList` and logic in SPE interation layer\n// we can animate post of number/vector/color/texture/color array\n// we cannot animate any enum (`MaterialNonAnimatableList`) and boolean\nexport type MaterialInteractionState = {\n\treadonly layers: Table<Nullable<Omit<Layer, 'type' | 'visible'>>>;\n};\n", "import { Seq } from 'collab-data';\nimport { Vector2 } from './primitives';\n\nexport type ShapePoint = {\n\treadonly position: Vector2;\n};\n\nexport type BezierControl = ShapePoint;\n\nexport type BezierPoint = ShapePoint & {\n\treadonly controlPrevious: BezierControl;\n\treadonly controlNext: BezierControl;\n\treadonly areControlsDirectionsMirrored: boolean;\n\treadonly roundness: number;\n};\n\nexport type VectorShape = {\n\treadonly points: Seq<BezierPoint>;\n\treadonly roundness: number | string;\n\treadonly shapeHoles: VectorShape[];\n\treadonly isClosed: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace VectorShape {\n\texport function defaultData(): VectorShape {\n\t\treturn {\n\t\t\tpoints: new Seq<BezierPoint>(),\n\t\t\troundness: 0,\n\t\t\tshapeHoles: [],\n\t\t\tisClosed: false,\n\t\t};\n\t}\n\n\texport function isOverlappingExistingPoint(\n\t\tdest: Vector2,\n\t\tshape: VectorShape\n\t): boolean {\n\t\tconst { points } = shape;\n\t\tif (points) {\n\t\t\tfor (const point of points) {\n\t\t\t\tif (\n\t\t\t\t\tpoint.data.position[0] === dest[0] &&\n\t\t\t\t\tpoint.data.position[1] === dest[1]\n\t\t\t\t)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns true if the curve between pStart and pEnd is a straight line.\n\t * Meaning that the controls of pStart and pEnd won't influence curvature of the line\n\t * @param pStart -\n\t * @param pEnd -\n\t */\n\texport function isStraightLine(\n\t\tpStart: BezierPoint,\n\t\tpEnd: BezierPoint\n\t): boolean {\n\t\tconst c1 = pStart.controlNext;\n\t\tconst c2 = pEnd.controlPrevious;\n\t\treturn (\n\t\t\tpStart.position[0] === c1.position[0] &&\n\t\t\tpStart.position[1] === c1.position[1] &&\n\t\t\tpEnd.position[0] === c2.position[0] &&\n\t\t\tpEnd.position[1] === c2.position[1]\n\t\t);\n\t}\n}\n", "import { Nullable } from './primitives';\nimport { Size2D, Size3D, Vector2, Vector3, Vector4 } from './primitives';\nimport { VectorShape } from './vector';\n\nexport type ParametricGeometryType =\n\t| 'PolygonGeometry'\n\t| 'RectangleGeometry'\n\t| 'StarGeometry'\n\t| 'TriangleGeometry'\n\t| 'EllipseGeometry'\n\t| 'VectorGeometry'\n\t| 'ConeGeometry'\n\t| 'CubeGeometry'\n\t| 'CylinderGeometry'\n\t| 'DodecahedronGeometry'\n\t| 'HelixGeometry'\n\t| 'IcosahedronGeometry'\n\t| 'LatheGeometry'\n\t| 'PyramidGeometry'\n\t| 'SphereGeometry'\n\t| 'PlaneGeometry'\n\t| 'TorusGeometry'\n\t| 'TorusKnotGeometry';\n\nexport type GeometryType =\n\t| ParametricGeometryType\n\t| 'NonParametricGeometry'\n\t| 'SubdivGeometry';\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace GeometryType {\n\texport function is2DParametricMesh(type: GeometryType) {\n\t\treturn (\n\t\t\ttype === 'PolygonGeometry' ||\n\t\t\ttype === 'RectangleGeometry' ||\n\t\t\ttype === 'StarGeometry' ||\n\t\t\ttype === 'TriangleGeometry' ||\n\t\t\ttype === 'EllipseGeometry'\n\t\t);\n\t}\n}\n\nexport type Parametric2DParameters = Size2D & {\n\treadonly extrudeBevelSize: number;\n\treadonly extrudeBevelSegments: number;\n\treadonly surfaceMaxCount: number;\n\treadonly depth: number;\n};\n\nexport type ConeGeometryParameters = Size3D & {\n\treadonly type: 'ConeGeometry';\n\treadonly radialSegments: number;\n\treadonly heightSegments: number;\n\treadonly openEnded: boolean;\n\treadonly thetaStart: number;\n\treadonly thetaLength: number;\n\treadonly cornerRadiusTop: number;\n\treadonly cornerRadiusBottom: number;\n\treadonly cornerSegments: number;\n};\n\nexport type CubeGeometryParameters = Size3D & {\n\treadonly type: 'CubeGeometry';\n\treadonly widthSegments: number;\n\treadonly heightSegments: number;\n\treadonly depthSegments: number;\n\treadonly cornerRadius: number;\n\treadonly cornerSegments: number;\n};\nexport type CylinderGeometryParameters = Size3D & {\n\treadonly type: 'CylinderGeometry';\n\treadonly radiusTop: number;\n\treadonly radiusBottom: number;\n\treadonly radialSegments: number;\n\treadonly heightSegments: number;\n\treadonly openEnded: boolean;\n\treadonly thetaStart: number;\n\treadonly thetaLength: number;\n\treadonly cornerRadius: number;\n\treadonly cornerSegments: number;\n\treadonly hollow: number;\n};\nexport type DodecahedronGeometryParameters = Size3D & {\n\treadonly type: 'DodecahedronGeometry';\n\treadonly detail: number;\n};\nexport type EllipseGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'EllipseGeometry';\n\treadonly spikes: number;\n\treadonly angle: number;\n\treadonly innerRadius: number;\n};\nexport type HelixGeometryParameters = Size3D & {\n\treadonly type: 'HelixGeometry';\n\treadonly radius: number;\n\treadonly revolutions: number;\n\treadonly segments: number;\n\treadonly pathRadius: number;\n\treadonly pathType: number;\n\treadonly pathSegments: number;\n\treadonly cornerRadius: number;\n\treadonly cornerSegments: number;\n};\nexport type IcosahedronGeometryParameters = Size3D & {\n\treadonly type: 'IcosahedronGeometry';\n\treadonly detail: number;\n};\n\ntype CubicBezierCurve = readonly [Vector2, Vector2, Vector2, Vector2];\n\nexport type LatheGeometryParameters = Size3D & {\n\treadonly type: 'LatheGeometry';\n\treadonly segments: number;\n\treadonly verticalSegments: number;\n\treadonly points: CubicBezierCurve;\n};\n\nexport type NonParametricGeometryAttribute = {\n\treadonly array: number[];\n\treadonly itemSize: number;\n\treadonly normalized: boolean;\n\treadonly type: string;\n};\n\nexport type NonParametricGeometryParameters = Size3D & {\n\treadonly type: 'NonParametricGeometry';\n\t// before in userData moved out because.... well we don't use userData facility in Three.js anymore\n\treadonly subdivisions: number;\n\t// anything that ThreeJs handles\n\treadonly data: {\n\t\treadonly attributes: Record<string, NonParametricGeometryAttribute>;\n\t\treadonly index?: NonParametricGeometryAttribute;\n\t\treadonly groups?: { start: number; count: number; materialIndex: number }[];\n\t\treadonly interleavedBuffers?: { [key: string]: any };\n\t\treadonly arrayBuffers?: { [key: string]: any };\n\t};\n};\n\n// Subdiv specific behavior:\n// `Size3D` does not actually resize the geometry, however it is still needed\n// for the resize mouse move animation, interaction mode resize animation, and\n// for updating the shape inspector. The actual resize is controlled by the\n// `scaleBaked` property\nexport type SubdivGeometryParameters = Size3D & {\n\treadonly type: 'SubdivGeometry';\n\treadonly subdivisions: number;\n\treadonly positionWASM: Float32Array;\n\treadonly indexWASM: Uint32Array;\n\treadonly verticesPerFaceWASM: Uint8Array;\n\treadonly scaleBaked: Vector3;\n};\n\nexport type PolygonGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'PolygonGeometry';\n\treadonly spikes: number;\n\treadonly cornerRadius: number;\n};\n\nexport type PyramidGeometryParameters = Size3D & {\n\treadonly type: 'PyramidGeometry';\n\treadonly radialSegments: number;\n\treadonly heightSegments: number;\n\treadonly openEnded: boolean;\n\treadonly cornerRadius: number;\n\treadonly cornerSegments: number;\n};\n\nexport type RectangleGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'RectangleGeometry';\n\treadonly cornerRadius: Vector4;\n\treadonly cornerType: number;\n};\n\nexport type SphereGeometryParameters = Size3D & {\n\treadonly type: 'SphereGeometry';\n\treadonly widthSegments: number;\n\treadonly heightSegments: number;\n\treadonly phiStart: number;\n\treadonly phiLength: number;\n\treadonly thetaStart: number;\n\treadonly thetaLength: number;\n};\n\nexport type PlaneGeometryParameters = Size3D & {\n\treadonly type: 'PlaneGeometry';\n\treadonly widthSegments: number;\n\treadonly heightSegments: number;\n};\n\nexport type StarGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'StarGeometry';\n\treadonly innerRadiusPercent: number;\n\treadonly spikes: number;\n\treadonly cornerRadius: number;\n\treadonly angle: 360;\n};\n\nexport type TorusGeometryParameters = Size3D & {\n\treadonly type: 'TorusGeometry';\n\t// tubePercent: number;\n\treadonly radialSegments: number;\n\treadonly tubularSegments: number;\n\treadonly arc: number;\n\treadonly cornerRadius: number;\n\treadonly cornerSegments: number;\n};\n\nexport type TorusKnotGeometryParameters = Size3D & {\n\treadonly type: 'TorusKnotGeometry';\n\treadonly tube: number;\n\treadonly tubularSegments: number;\n\treadonly radialSegments: number;\n\treadonly p: number;\n\treadonly q: number;\n};\n\nexport type TriangleGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'TriangleGeometry';\n\treadonly cornerRadius: number;\n};\n\nexport type VectorGeometryParameters = Parametric2DParameters & {\n\treadonly type: 'VectorGeometry';\n\treadonly subdivisions: number;\n\treadonly shape: VectorShape;\n};\n\nexport type BaseGeometryState = {\n\treadonly type: GeometryType;\n};\nexport type GeometryState = BaseGeometryState &\n\t(\n\t\t| ConeGeometryParameters\n\t\t| CubeGeometryParameters\n\t\t| CylinderGeometryParameters\n\t\t| DodecahedronGeometryParameters\n\t\t| EllipseGeometryParameters\n\t\t| HelixGeometryParameters\n\t\t| IcosahedronGeometryParameters\n\t\t| LatheGeometryParameters\n\t\t| PolygonGeometryParameters\n\t\t| PyramidGeometryParameters\n\t\t| RectangleGeometryParameters\n\t\t| SphereGeometryParameters\n\t\t| StarGeometryParameters\n\t\t| TorusGeometryParameters\n\t\t| TorusKnotGeometryParameters\n\t\t| TriangleGeometryParameters\n\t\t| VectorGeometryParameters\n\t\t| NonParametricGeometryParameters\n\t\t| SubdivGeometryParameters\n\t);\n\nexport type ParametricGeometryState = Exclude<\n\tGeometryState,\n\tNonParametricGeometryParameters\n>;\n\nexport type ParametricGeometryState2D = Extract<\n\tGeometryState,\n\t| EllipseGeometryParameters\n\t| PolygonGeometryParameters\n\t| RectangleGeometryParameters\n\t| StarGeometryParameters\n\t| TriangleGeometryParameters\n>;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace ParametricGeometryState {\n\texport function defaultData(\n\t\ttype: ParametricGeometryType\n\t): ParametricGeometryState {\n\t\tif (type === 'RectangleGeometry') {\n\t\t\tlet ret: RectangleGeometryParameters = {\n\t\t\t\twidth: 320,\n\t\t\t\theight: 320,\n\t\t\t\ttype: type,\n\t\t\t\tcornerRadius: [0, 0, 0, 0],\n\t\t\t\tcornerType: 0,\n\t\t\t\tdepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t\tsurfaceMaxCount: 1,\n\t\t\t};\n\t\t\treturn ret;\n\t\t} else if (type === 'VectorGeometry') {\n\t\t\tlet ret: VectorGeometryParameters = {\n\t\t\t\twidth: 100,\n\t\t\t\theight: 100,\n\t\t\t\ttype: type,\n\t\t\t\tsubdivisions: 12,\n\t\t\t\tshape: VectorShape.defaultData(),\n\t\t\t\tdepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t\tsurfaceMaxCount: 1,\n\t\t\t};\n\t\t\treturn ret;\n\t\t} else {\n\t\t\tthrow new Error('not implemented');\n\t\t}\n\t}\n}\n\nexport type GeometryInteractionState = Nullable<Size3D>;\nexport type SubdivGeometryInteractionState = Nullable<\n\tSize3D & { readonly scaleBaked: Vector3 }\n>;\n", "import { mutateDirectly, Seq } from 'collab-data';\nimport { CameraInteractionState, CameraState, CameraType } from './camera';\nimport { InteractionEventState } from './interaction';\nimport { LightInteractionState, LightState, LightType } from './light';\nimport {\n\tMeshInteractionState,\n\tMeshState,\n\tBaseMeshState,\n\tSubdivMeshState,\n} from './mesh';\nimport {\n\tMatrix,\n\tNamed,\n\tNullable,\n\tRGB,\n\tTransformState,\n\tVector3,\n} from './primitives';\nimport { TextFrameData } from './text';\nimport { MaterialState } from './material';\nimport { ParametricGeometryState } from './geometry';\nimport { merge } from 'lodash-es';\n\nexport type ObjectType =\n\t| LightType\n\t| CameraType\n\t| 'Mesh'\n\t| 'TextFrame'\n\t| 'Empty';\n\n// our transformation state is SRT component + a non SRT component matrix. We should try to keep the \"matrix\" component null (assumed identity) if\n// it doesn't have shear or perspective components.\n//\n// The hidden matrix is applied before the SRT components:\n// object.worldMatrix = parentObject.worldMatrix * object.hiddenMatrix * object.SRT;\nexport type ObjectTransformState = TransformState & {\n\treadonly hiddenMatrix: Matrix; // the non SRT component matrix\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace ObjectTransformState {\n\texport const identity: ObjectTransformState = {\n\t\t...TransformState.identity,\n\t\thiddenMatrix: Matrix.identity,\n\t};\n\texport function fromObject(obj: ObjectState): ObjectTransformState {\n\t\treturn {\n\t\t\tposition: obj.position,\n\t\t\trotation: obj.rotation,\n\t\t\tscale: obj.scale,\n\t\t\thiddenMatrix: obj.hiddenMatrix,\n\t\t};\n\t}\n\n\texport function merge(\n\t\tbase: ObjectTransformState,\n\t\tpartial: Nullable<ObjectTransformState>\n\t): ObjectTransformState {\n\t\treturn {\n\t\t\tposition: partial?.position || base.position,\n\t\t\trotation: partial?.rotation || base.rotation,\n\t\t\tscale: partial?.scale || base.scale,\n\t\t\thiddenMatrix: partial?.hiddenMatrix || base.hiddenMatrix,\n\t\t};\n\t}\n\n\texport function diff(\n\t\tbefore: ObjectTransformState,\n\t\tafter: ObjectTransformState\n\t): Nullable<ObjectTransformState> {\n\t\treturn {\n\t\t\tposition: Vector3.isEqual(before.position, after.position)\n\t\t\t\t? null\n\t\t\t\t: after.position,\n\t\t\trotation: Vector3.isEqual(before.rotation, after.rotation)\n\t\t\t\t? null\n\t\t\t\t: after.rotation,\n\t\t\tscale: Vector3.isEqual(before.scale, after.scale) ? null : after.scale,\n\t\t\thiddenMatrix: Matrix.isEqual(before.hiddenMatrix, after.hiddenMatrix)\n\t\t\t\t? null\n\t\t\t\t: after.hiddenMatrix,\n\t\t};\n\t}\n}\n\nexport type BaseObjectState = ObjectTransformState & {\n\treadonly type: ObjectType;\n\treadonly name: string;\n\treadonly states: Seq<InteractionState>;\n\treadonly events: Seq<InteractionEventState>;\n\treadonly visible: boolean;\n\treadonly raycastLock: boolean;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace BaseObjectState {\n\texport const defaultData: Omit<BaseObjectState, 'name' | 'type'> = {\n\t\tstates: new Seq(),\n\t\tevents: new Seq(),\n\t\tvisible: true,\n\t\traycastLock: false,\n\t\t...ObjectTransformState.identity,\n\t};\n}\n\nexport type EmptyObjectState = BaseObjectState & {\n\treadonly type: 'Empty';\n};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace EmptyObjectState {\n\texport const defaultData: Omit<EmptyObjectState, 'name'> = {\n\t\ttype: 'Empty',\n\t\t...BaseObjectState.defaultData,\n\t};\n}\n\nexport type SubdivObjectState = BaseObjectState &\n\tSubdivMeshState & {\n\t\treadonly type: 'Mesh';\n\t};\n\nexport type MeshObjectState = BaseObjectState &\n\tMeshState & {\n\t\treadonly type: 'Mesh';\n\t};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace MeshObjectState {\n\texport const defaultData: Omit<\n\t\tMeshObjectState,\n\t\t'name' | 'geometry' | 'material' | 'materials'\n\t> = {\n\t\ttype: 'Mesh',\n\t\t...BaseObjectState.defaultData,\n\t\t...BaseMeshState.defaultData,\n\t};\n}\n\nexport type TextFrameObjectState = BaseObjectState &\n\tTextFrameData & {\n\t\treadonly type: 'TextFrame';\n\t};\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace TextFrameObjectState {\n\texport const defaultData: Omit<TextFrameObjectState, 'name'> = {\n\t\ttype: 'TextFrame',\n\t\t...BaseObjectState.defaultData,\n\t\t...TextFrameData.defaultData,\n\t};\n}\n\nexport type CameraObjectState = BaseObjectState & CameraState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace CameraObjectState {\n\texport const defaultData: Omit<CameraObjectState, 'name'> = {\n\t\t...BaseObjectState.defaultData,\n\t\t...ObjectTransformState.identity,\n\t\t...CameraState.defaultData,\n\t};\n}\n\nexport type LightObjectState = LightState & BaseObjectState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace LightObjectState {\n\texport function defaultData<T extends LightType>(type: T) {\n\t\treturn {\n\t\t\t...BaseObjectState.defaultData,\n\t\t\t...LightState.defaultData(type),\n\t\t};\n\t}\n}\n\nexport type ObjectState =\n\t| MeshObjectState\n\t| CameraObjectState\n\t| LightObjectState\n\t| TextFrameObjectState\n\t| EmptyObjectState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace ObjectState {\n\texport const defaultCamera: CameraObjectState = {\n\t\tposition: [0, 0, 1000],\n\t\tscale: [1, 1, 1],\n\t\trotation: [0, 0, 0],\n\t\thiddenMatrix: Matrix.identity,\n\t\tname: 'Play Camera',\n\t\tvisible: true,\n\t\traycastLock: false,\n\t\tstates: new Seq(),\n\t\tevents: new Seq(),\n\t\t...CameraState.defaultData,\n\t};\n\n\texport const defaultMeshObject: MeshObjectState = {\n\t\tname: 'Rectangle',\n\t\t...BaseObjectState.defaultData,\n\t\t...MeshObjectState.defaultData,\n\t\tgeometry: ParametricGeometryState.defaultData('RectangleGeometry'),\n\t\tmaterial: MaterialState.defaultTwoLayerData('basic', 'layer1', 'layer2'),\n\t};\n}\n\n/**\n * we lerp the SRT component in InteractionState, but (currently) not the hiddenMatrix component.\n */\nexport type BaseInteractionState = Named & Nullable<ObjectTransformState>;\n\nexport type CameraObjectInteractionState = BaseInteractionState &\n\tCameraInteractionState;\n\nexport type MeshObjectInteractionState = BaseInteractionState &\n\tMeshInteractionState;\n\nexport type LightObjectInteractionState = BaseInteractionState &\n\tLightInteractionState;\n\nexport type InteractionState =\n\t| CameraObjectInteractionState\n\t| MeshObjectInteractionState\n\t| LightObjectInteractionState;\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace InteractionState {\n\t// TODO this code is highly type-unsafe\n\texport function patchMaterialState(\n\t\to: MeshObjectState,\n\t\tp: InteractionState | undefined\n\t): MeshObjectState {\n\t\tif (p === undefined) return o;\n\n\t\tlet res: any = { ...o };\n\t\tif ('material' in res && 'material' in p && p.material) {\n\t\t\t// TODO don't use proxies, might be slow\n\t\t\tres.material = mutateDirectly(res.material, (ms) => {\n\t\t\t\tif (typeof ms !== 'string') {\n\t\t\t\t\tfor (let [key, v] of Object.entries((p as any).material.layers)) {\n\t\t\t\t\t\tlet ml = ms.layers.data(key);\n\t\t\t\t\t\tif (ml) {\n\t\t\t\t\t\t\t// We need to merge in case of nested objects such\n\t\t\t\t\t\t\t// as textures\n\t\t\t\t\t\t\tmerge(ml, v as any);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}).data;\n\t\t}\n\n\t\tif (res.materials && (p as any).materials) {\n\t\t\tres.materials = mutateDirectly(res.materials, (ms) => {\n\t\t\t\tfor (let i = 0; i < res.materials.length; i++) {\n\t\t\t\t\tlet pi = (p as any).materials[i];\n\t\t\t\t\tif (typeof pi !== 'string') {\n\t\t\t\t\t\tfor (let [key, v] of Object.entries(pi.layers)) {\n\t\t\t\t\t\t\tlet ml = ms[i]?.layers?.data(key);\n\t\t\t\t\t\t\tif (ml) {\n\t\t\t\t\t\t\t\tmerge(ml, v as any);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}).data;\n\t\t}\n\n\t\treturn res;\n\t}\n\n\t// TODO this code is highly type-unsafe\n\texport function patch<T extends ObjectState>(\n\t\to: T,\n\t\tp: InteractionState | undefined\n\t): T {\n\t\tif (p === undefined) return o;\n\t\tlet res: any = { ...o };\n\t\tObject.assign(res, ObjectTransformState.merge(res, p));\n\t\tif (CameraType.is(o.type)) {\n\t\t\tres.orthographic = { ...res.orthographic };\n\t\t\tres.perspective = { ...res.perspective };\n\t\t\tlet pc = p as CameraInteractionState;\n\t\t\tif (pc.orthographic?.zoom !== undefined) {\n\t\t\t\tres.orthographic.zoom = pc.orthographic.zoom;\n\t\t\t}\n\t\t\tif (pc.perspective?.zoom !== undefined) {\n\t\t\t\tres.perspective.zoom = pc.perspective.zoom;\n\t\t\t}\n\t\t} else if (o.type === 'Mesh') {\n\t\t\tres.geometry = { ...res.geometry };\n\t\t\tObject.assign(res.geometry, (p as any).geometry);\n\n\t\t\tres = patchMaterialState(res, p);\n\t\t} else if (LightType.is(o.type)) {\n\t\t\tlet state = p as LightInteractionState;\n\t\t\tif (res.intensity !== undefined) {\n\t\t\t\tres.intensity = state.intensity;\n\t\t\t}\n\t\t\tif (state.color !== undefined) {\n\t\t\t\tres.color = RGB.clone(state.color);\n\t\t\t}\n\t\t}\n\t\treturn res;\n\t}\n}\n", "/**\n * Used to make sure we don't render transmissive\n * objects into the transmissive framebuffer.\n */\nexport const TRANSMISSION_CAMERA_LAYER = 3;\n/**\n * colors\n */\nexport const colorDefault = 0x595959;\nexport const colorGreen = 0x38e2b3;\nexport const colorHandler = 0x808080;\nexport const colorHandlerDark = 0x404040;\nexport const colorHandlerLines = 0xebebeb;\nexport const colorHover = 0x349bfc;\nexport const colorMainBlue = 0x2b99ff;\nexport const colorRed = 0xfd5b5d;\nexport const colorRedLines = 0xff0000;\nexport const colorYellow = 0xefbc22;\n", "/**\n * @author Cristhian Lunardi\n * A <Char3D> is the smallest part of a <textFrame>\n * This file let instantiate an <Char3D> and gives the necessary functions\n * to update and set correctly its position, size, mesh and LOD.\n * Also after create a <Char3D> it automatically use the global array\n * Char3D.charCache to store the geometry created to re-use it later.\n */\n\nimport {\n\tDoubleSide,\n\tMaterial,\n\tMesh,\n\tMeshBasicMaterial,\n\tShape,\n\tShapeBufferGeometry,\n\tVector2,\n\tVector3,\n} from 'three';\nimport { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';\n\ntype CharCacheEntry = {\n\tgeometry: ShapeBufferGeometry;\n\tfontFamily: string;\n\tresolution: number;\n\tglyphsHa: number;\n};\n\ntype CharCacheCharacter = {\n\t[lod: number]: CharCacheEntry;\n};\ntype CharCache = {\n\t[char: string]: CharCacheCharacter;\n};\ntype FontCache = {\n\t[font: string]: JsonFont;\n};\n\nexport type Char3DParameters = {\n\tchar: string;\n\toriginalChar?: string;\n\tfontFamily: string;\n\tletterSpacing: number;\n\tfontSize: number;\n\tLOD: number;\n};\n\ntype JsonFontGlyph = {\n\tha: number;\n};\ntype JsonFontGlyphs = {\n\t[char: string]: JsonFontGlyph;\n};\n\ntype JsonFontData = {\n\tresolution: number;\n\tglyphs: JsonFontGlyphs;\n};\nexport type JsonFont = {\n\tdata: JsonFontData;\n\tgenerateShapes(text: string, size: number): Shape[];\n};\n\nexport class Char3D extends Mesh {\n\tstatic charCache: CharCache = {}; // TODO replace with Dictionnary\n\tstatic fontCache: FontCache = {}; // TODO replace with Dictionnary\n\n\tchar: string;\n\toriginalChar: string;\n\tfontFamily: string;\n\tletterSpacing: number;\n\tfontSize: number;\n\tLOD: number;\n\n\tresolution: number;\n\tglyphsHa: number;\n\tcharSize: number;\n\tlocalPosition: Vector2;\n\n\tconstructor(\n\t\t{\n\t\t\tchar,\n\t\t\toriginalChar,\n\t\t\tfontFamily,\n\t\t\tletterSpacing,\n\t\t\tfontSize,\n\t\t\tLOD = 16,\n\t\t}: Char3DParameters,\n\t\tmaterial: Material | Material[] | undefined = new MeshBasicMaterial({\n\t\t\tcolor: 0x000000,\n\t\t\topacity: 1,\n\t\t\tvisible: true,\n\t\t\ttransparent: true,\n\t\t\tside: DoubleSide,\n\t\t})\n\t) {\n\t\tconst charCache = Char3D.loadChar(char, fontFamily, LOD);\n\n\t\tsuper(charCache.geometry, material);\n\n\t\tthis.char = char;\n\t\tthis.originalChar = originalChar ?? char;\n\t\tthis.fontFamily = fontFamily;\n\t\tthis.letterSpacing = letterSpacing;\n\t\tthis.fontSize = fontSize;\n\t\tthis.LOD = LOD; // ! TESTING\n\n\t\tthis.resolution = charCache.resolution;\n\t\tthis.glyphsHa = charCache.glyphsHa;\n\t\tthis.localPosition = new Vector2();\n\t\tthis.charSize = 0;\n\n\t\t// Inject character data into geometry's user-data\n\t\tthis.geometry.userData = {\n\t\t\t// TODO Handle SPE Geometry type which includes userData\n\t\t\ttype: 'CharacterGeometry',\n\t\t\tparameters: {\n\t\t\t\tchar: this.char,\n\t\t\t\tfontFamily: this.fontFamily,\n\t\t\t\tletterSpacing: this.letterSpacing,\n\t\t\t\tfontSize: this.fontSize,\n\t\t\t\tlod: this.LOD,\n\t\t\t\tresolution: this.resolution,\n\t\t\t\tcharSize: this.charSize,\n\t\t\t\tlocalPosition: this.localPosition,\n\t\t\t},\n\t\t};\n\n\t\t// Update <Char3D> size after created, add as children to <textFrame> and add to its respective Line <Index>\n\t\tthis.updateFontSize(this.fontSize);\n\t}\n\n\tprivate static _fontPath = '/_assets/_fonts/';\n\n\tstatic get FONTS_PATH() {\n\t\treturn Char3D._fontPath;\n\t}\n\n\tstatic set FONTS_PATH(value: string) {\n\t\tChar3D._fontPath = value;\n\t}\n\n\tupdatePosition(position: Vector2, textOrigin: Vector3): void {\n\t\tthis.localPosition.copy(position);\n\n\t\tconst xAxisDirection = new Vector3(\n\t\t\tthis.localPosition.x,\n\t\t\t-this.localPosition.y,\n\t\t\t0\n\t\t);\n\t\tthis.position.copy(xAxisDirection).add(textOrigin);\n\t}\n\n\tupdateFontSize(fontSize: number): void {\n\t\tconst scale = fontSize / this.resolution;\n\n\t\tthis.fontSize = fontSize;\n\n\t\tthis.scale.set(this.fontSize, this.fontSize, 1);\n\t\tthis.charSize = this.glyphsHa * scale * this.letterSpacing;\n\t}\n\n\tupdateFontFamily(fontFamily: string): void {\n\t\tif (this.fontFamily === fontFamily) return;\n\n\t\tthis.fontFamily = fontFamily;\n\n\t\tconst charCache = Char3D.loadChar(this.char, fontFamily, this.LOD);\n\t\tthis.geometry = charCache.geometry;\n\t\tthis.resolution = charCache.resolution;\n\t\tthis.glyphsHa = charCache.glyphsHa;\n\n\t\t// Inject character data into geometry's user-data\n\t\tthis.geometry.userData = {\n\t\t\ttype: 'CharacterGeometry',\n\t\t\tparameters: {\n\t\t\t\tchar: this.char,\n\t\t\t\tfontFamily: this.fontFamily,\n\t\t\t\tletterSpacing: this.letterSpacing,\n\t\t\t\tfontSize: this.fontSize,\n\t\t\t\tlod: this.LOD,\n\t\t\t\tresolution: this.resolution,\n\t\t\t\tcharSize: this.charSize,\n\t\t\t\tlocalPosition: this.localPosition,\n\t\t\t},\n\t\t};\n\n\t\tthis.updateFontSize(this.fontSize);\n\t}\n\n\tupdateChar(char: string): void {\n\t\tif (this.char === char) return;\n\n\t\tthis.char = char;\n\n\t\tconst charCache = Char3D.loadChar(char, this.fontFamily, this.LOD);\n\t\tthis.geometry = charCache.geometry;\n\t\tthis.resolution = charCache.resolution;\n\t\tthis.glyphsHa = charCache.glyphsHa;\n\n\t\t// Inject character data into geometry's user-data\n\t\tthis.geometry.userData = {\n\t\t\ttype: 'CharacterGeometry',\n\t\t\tparameters: {\n\t\t\t\tchar: this.char,\n\t\t\t\tfontFamily: this.fontFamily,\n\t\t\t\tletterSpacing: this.letterSpacing,\n\t\t\t\tfontSize: this.fontSize,\n\t\t\t\tlod: this.LOD,\n\t\t\t\tresolution: this.resolution,\n\t\t\t\tcharSize: this.charSize,\n\t\t\t\tlocalPosition: this.localPosition,\n\t\t\t},\n\t\t};\n\n\t\tthis.updateFontSize(this.fontSize);\n\t}\n\n\tupdateLetterSpacing(letterSpacing: number): void {\n\t\tif (this.letterSpacing === letterSpacing) return;\n\n\t\tthis.letterSpacing = letterSpacing;\n\t\tthis.updateFontSize(this.fontSize);\n\t}\n\n\t// LOD is a number, which define the level of detail to assign.\n\tupdateLOD(LOD: number): void {\n\t\tif (this.LOD === LOD) return;\n\n\t\tthis.LOD = LOD;\n\n\t\tconst charCache = Char3D.loadChar(this.char, this.fontFamily, this.LOD);\n\t\tthis.geometry = charCache.geometry;\n\t\tthis.resolution = charCache.resolution;\n\t\tthis.glyphsHa = charCache.glyphsHa;\n\n\t\t// Inject character data into geometry's user-data\n\t\tthis.geometry.userData = {\n\t\t\ttype: 'CharacterGeometry',\n\t\t\tparameters: {\n\t\t\t\tchar: this.char,\n\t\t\t\tfontFamily: this.fontFamily,\n\t\t\t\tletterSpacing: this.letterSpacing,\n\t\t\t\tfontSize: this.fontSize,\n\t\t\t\tlod: this.LOD,\n\t\t\t\tresolution: this.resolution,\n\t\t\t\tcharSize: this.charSize,\n\t\t\t\tlocalPosition: this.localPosition,\n\t\t\t},\n\t\t};\n\n\t\tthis.updateFontSize(this.fontSize);\n\t}\n\n\tclone(): this {\n\t\tconst options = {\n\t\t\tchar: this.char,\n\t\t\toriginalChar: this.originalChar, // keep char after textTransformation\n\t\t\tfontFamily: this.fontFamily,\n\t\t\tletterSpacing: this.letterSpacing,\n\t\t\tfontSize: this.fontSize,\n\t\t\tLOD: this.LOD,\n\t\t};\n\n\t\treturn new Char3D(options).copy(this) as this;\n\t}\n\n\tstatic loadFont(fontFamily: string) {\n\t\treturn new Promise(function (resolve, reject) {\n\t\t\tif (!Char3D.fontCache[fontFamily]) {\n\t\t\t\tconst loader = new FontLoader();\n\t\t\t\tloader.load(\n\t\t\t\t\tChar3D.FONTS_PATH + fontFamily + '.json',\n\t\t\t\t\t(font: any) => {\n\t\t\t\t\t\tChar3D.fontCache[fontFamily] = font as JsonFont;\n\t\t\t\t\t\tresolve(font);\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\treject\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresolve(Char3D.fontCache[fontFamily]);\n\t\t\t}\n\t\t});\n\t}\n\n\t// ! required: load fontCache previously\n\tstatic loadChar(char: string, fontFamily: string, LOD: number) {\n\t\tif (Char3D.charCache[char]) {\n\t\t\tif (\n\t\t\t\tChar3D.charCache[char][LOD] &&\n\t\t\t\tChar3D.charCache[char][LOD].fontFamily === fontFamily\n\t\t\t) {\n\t\t\t\treturn Char3D.charCache[char][LOD];\n\t\t\t}\n\t\t} else {\n\t\t\tChar3D.charCache[char] = {};\n\t\t}\n\n\t\tconst font: JsonFont = Char3D.fontCache[fontFamily];\n\n\t\tconst shape = font.generateShapes(char, 1); // fontSize: 1\n\n\t\tChar3D.charCache[char][LOD] = {\n\t\t\tgeometry: new ShapeBufferGeometry(shape, LOD),\n\t\t\tfontFamily: fontFamily,\n\t\t\tresolution: font.data['resolution'],\n\t\t\tglyphsHa: font.data.glyphs[char].ha,\n\t\t};\n\n\t\treturn Char3D.charCache[char][LOD];\n\t}\n}\n", "/**\n * @author Cristhian Lunardi\n */\n\nimport {\n\tDoubleSide,\n\tIntersection,\n\tMeshBasicMaterial,\n\tRaycaster,\n\tVector3,\n\tBufferGeometry,\n\tObject3D,\n} from 'three';\nimport { AbstractMesh } from '../AbstractMesh';\nimport { Material, BasicMaterial } from '../../../materials';\nimport { Geometry, TextFrameGeometry } from '../../../geometries';\nimport { ITextLine, TextLine } from './TextLine';\nimport { Char3D } from './Char3D';\nimport { BaseInputs, NestedPartial } from '../../../geometries/Geometry';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedTextFrame,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { VectorObject, VectorShape } from '../vectors';\nimport { JsonFont } from '.';\nimport { EmptyObject } from '..';\nimport { VectorGeometry } from '../../../geometries/vectors/VectorGeometry';\nimport {\n\tHorizontalAlign,\n\tVerticalAlign,\n\tTextTransform,\n\tTextFrameObjectState,\n\tTextFrameData,\n} from 'spline-data';\nimport { getSharedColorData } from '../../../shared/utils';\nimport { SharedAssetsManager } from '../../../shared/SharedAssetsManager';\nimport { ColorA } from '../../Color';\n\nexport enum TRAVEL_DIRECTION {\n\tTO_RIGHT = 1,\n\tTO_LEFT = -1,\n}\n\ntype LegacyJSONChar = {\n\tgeometries: {\n\t\tuserData: {\n\t\t\tparameters: {\n\t\t\t\tchar: string;\n\t\t\t\tfontFamily: string;\n\t\t\t\tletterSpacing: number;\n\t\t\t\tfontSize: number;\n\t\t\t\tlod: number;\n\t\t\t\tresolution: number;\n\t\t\t\tlocalPosition: {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t}[];\n};\n\ntype TextFrameGeometryUserData = {\n\tparameters: {\n\t\twidth: number;\n\t\theight: number;\n\t\tdepth: number;\n\t};\n\ttype: string;\n};\n\nexport type TextFrameUserData = {\n\thexColor: ColorA;\n\topacity: number;\n\tvisible: boolean;\n\tfontSize: number;\n\tlineHeight: number;\n\tletterSpacing: number;\n\tfontFamily: string;\n\ttextTransform: TextTransform;\n\thorizontalAlignment: HorizontalAlign;\n\tverticalAlignment: VerticalAlign;\n\tLOD: number;\n\tmaxLineSize: number;\n\ttextOrigin: Vector3;\n\ttextLines: TextLine[];\n\ttextLinesData?: ITextLine[];\n};\n\ntype UserData = {\n\ttextFrame: TextFrameUserData;\n};\n\nexport class TextFrame extends AbstractMesh {\n\tstatic VerticalAlign = VerticalAlign;\n\tstatic HorizontalAlign = HorizontalAlign;\n\tstatic TextTransform = TextTransform;\n\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'TextFrame';\n\n\t// Contains all characters (no matter the line)\n\tcharContainer: Object3D;\n\n\tprivate _geometryUserData: TextFrameGeometryUserData;\n\n\tstatic createFromState(\n\t\tid: string,\n\t\tdata: TextFrameObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tconst geometry = TextFrameGeometry.create({\n\t\t\tparameters: {\n\t\t\t\twidth: data.width,\n\t\t\t\theight: data.height,\n\t\t\t},\n\t\t});\n\t\tconst object = new TextFrame(geometry).fromState(data, sharedAssets);\n\t\tobject.uuid = id;\n\t\treturn object;\n\t}\n\n\tconstructor(\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material | Material[] = new BasicMaterial({\n\t\t\ttransparent: true,\n\t\t\topacity: 1,\n\t\t\tvisible: false,\n\t\t\tside: DoubleSide,\n\t\t})\n\t) {\n\t\tsuper(geometry, material);\n\n\t\tthis.charContainer = new Object3D();\n\t\tthis.add(this.charContainer);\n\n\t\t(this.material as Material).visible = false;\n\n\t\tthis._geometryUserData = geometry.userData as TextFrameGeometryUserData;\n\n\t\tthis.userData.textFrame = {\n\t\t\thexColor: null,\n\t\t\topacity: 1.0,\n\t\t\tvisible: true,\n\t\t\ttext: '',\n\t\t\tfontSize: 16,\n\t\t\tlineHeight: 1.5,\n\t\t\tletterSpacing: 1,\n\t\t\tfontFamily: 'roboto_regular',\n\t\t\ttextTransform: TextTransform.None,\n\t\t\thorizontalAlignment: 1,\n\t\t\tverticalAlignment: VerticalAlign.Top,\n\t\t\tLOD: 16,\n\t\t\tmaxLineSize: this._geometryUserData.parameters.width, // total usable space to render chars\n\t\t\ttextOrigin: new Vector3(\n\t\t\t\tthis._geometryUserData.parameters.width * -0.5,\n\t\t\t\tthis._geometryUserData.parameters.height * 0.5,\n\t\t\t\t0\n\t\t\t),\n\t\t\ttextLines: [],\n\t\t};\n\n\t\t// Data is just a proxy to do the code more readable\n\t\tthis.createTextLine();\n\t}\n\n\tasync updateText(text: string) {\n\t\tthis.clearText();\n\n\t\tconst textFrameData = this.userData.textFrame;\n\t\tconst font = textFrameData.fontFamily as string;\n\n\t\tawait Char3D.loadFont(font);\n\n\t\ttextFrameData.text = text;\n\n\t\tconst textOrigin = textFrameData.textOrigin as Vector3;\n\t\tconst material = new MeshBasicMaterial({\n\t\t\tvisible: textFrameData.visible,\n\t\t\ttransparent: true,\n\t\t\tside: DoubleSide,\n\t\t});\n\n\t\tconst lines = text.split('\\n');\n\t\tlet totalLineHeight = 0;\n\t\tthis.userData.textFrame.textLines = lines.map((message, i) => {\n\t\t\tconst line = new TextLine(\n\t\t\t\ttotalLineHeight,\n\t\t\t\ttextFrameData.lineHeight,\n\t\t\t\ttextFrameData.fontSize\n\t\t\t);\n\t\t\tline.message = message.split('').map((char) => {\n\t\t\t\tconst options = {\n\t\t\t\t\tchar: char,\n\t\t\t\t\tfontFamily: font,\n\t\t\t\t\tletterSpacing: textFrameData.letterSpacing,\n\t\t\t\t\tfontSize: textFrameData.fontSize,\n\t\t\t\t\tLOD: 16,\n\t\t\t\t};\n\n\t\t\t\tconst matClone = material.clone();\n\t\t\t\t// Make sure to use the same color instance, in case\n\t\t\t\t// it is a color asset.\n\t\t\t\tmatClone.color = textFrameData.hexColor;\n\t\t\t\tmatClone.opacity = textFrameData.opacity;\n\n\t\t\t\tconst char3D = new Char3D(options, matClone);\n\t\t\t\tline.addChar3D(char3D, textOrigin);\n\t\t\t\tthis.charContainer.add(char3D);\n\t\t\t\treturn char3D;\n\t\t\t});\n\t\t\ttotalLineHeight += line.maxCharSize * line.lineHeight;\n\t\t\treturn line;\n\t\t});\n\t\tthis.textFullUpdate();\n\t\tthis.checkOverFlow();\n\t}\n\n\tclearText() {\n\t\tconst textLines = this.userData.textFrame.textLines as TextLine[];\n\t\twhile (this.charContainer.children.length) {\n\t\t\tconst char = this.charContainer.children[0] as Char3D;\n\t\t\tthis.charContainer.remove(char);\n\t\t}\n\t\twhile (textLines.length) {\n\t\t\ttextLines.pop();\n\t\t}\n\t}\n\n\t// nisa: override\n\traycast(raycaster: Raycaster, intersects: Intersection[]): void {\n\t\t// TODO - nisa: we should remove intersect with textFrame when we start to use child for special characters\n\t\tconst textFrameIntersects: Intersection[] = [];\n\n\t\tsuper.raycast(raycaster, textFrameIntersects); // TODO does nothing\n\n\t\tif (textFrameIntersects.length > 0) {\n\t\t\t// TODO Unreachable\n\t\t\tintersects.push(textFrameIntersects[0]);\n\t\t\treturn;\n\t\t}\n\n\t\tconst charIntersects: Intersection[] = [];\n\n\t\tfor (let i = 0, l = this.charContainer.children.length; i < l; ++i) {\n\t\t\tif (this.charContainer.children[i] instanceof Char3D) {\n\t\t\t\traycaster.intersectObject(\n\t\t\t\t\tthis.charContainer.children[i],\n\t\t\t\t\tfalse,\n\t\t\t\t\tcharIntersects\n\t\t\t\t);\n\n\t\t\t\tif (charIntersects.length > 0) {\n\t\t\t\t\tcharIntersects[0].object = this;\n\t\t\t\t\tintersects.push(charIntersects[0]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateGeometry<TInputs extends BaseInputs>(\n\t\tinputs: NestedPartial<TInputs>\n\t): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst lastGeometryUserData = (this.geometry as Geometry).userData;\n\t\tconst lastWidth = lastGeometryUserData.parameters.width;\n\t\tconst lastHeight = lastGeometryUserData.parameters.height;\n\t\tconst width = inputs.parameters?.width ?? lastWidth;\n\t\tconst height = inputs.parameters?.height ?? lastHeight;\n\t\tconst textFrameData = userData.textFrame;\n\n\t\tsuper.updateGeometry(inputs);\n\n\t\ttextFrameData.maxLineSize = width;\n\t\ttextFrameData.textOrigin.set(-0.5 * width, 0.5 * height, 0);\n\n\t\tif (height !== lastHeight) {\n\t\t\tthis.checkOverFlow();\n\t\t\tthis.checkCapacity();\n\t\t} else if (width !== lastWidth) {\n\t\t\tif (lastWidth < width) {\n\t\t\t\tthis.checkCapacity();\n\t\t\t} else if (lastWidth > width) {\n\t\t\t\tthis.checkOverFlow();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Using the global variable textFrameData and an <Index> from arguments\n\t * this function will process every Line from Line[Index] till the last Line.\n\t * It will check if there is an overflow and keep moving words to the next line\n\t * till there is no more overflow.\n\t * Note: this function is usually called after an <insert> method (addChar3D, for example).\n\t * @param fromLineIndex -\n\t */\n\tcheckOverFlow(fromLineIndex: number = 0): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textOrigin = userData.textFrame.textOrigin;\n\t\tconst textLines = userData.textFrame.textLines;\n\n\t\tfor (let i = fromLineIndex; i < textLines.length; i++) {\n\t\t\t/*\n\t\t\t * Relocating every char of the current Line to their correct position.\n\t\t\t * Since we constantly \"get\" and \"add\" words to current and next Lines\n\t\t\t * we need to update this line to correctly check if there's an overflow\n\t\t\t */\n\t\t\t// ! Note: since we already update the next Line at the end of this for loop, this probably is not necessary, must be checked\n\t\t\t// ! But be careful, it still will need to be updated before the loop, to be sure that we have consistency\n\n\t\t\ttextLines[i].updateYLinePos(this.getNewLinePosition(i));\n\t\t\ttextLines[i].fullUpdate(textOrigin);\n\t\t\tconst overFlow: Char3D[][] = [];\n\n\t\t\t// Now, while there's still overflow we'll put the last word to the <overFlow> array\n\t\t\twhile (textLines[i].checkOverFlow(userData.textFrame.maxLineSize)) {\n\t\t\t\t/*\n\t\t\t\t * If there's a separated (with space) <word> causing overflow, we get that <word>.\n\t\t\t\t * Otherwise, if the <word> is big enough to not have any spaces in that line,\n\t\t\t\t * we'll get just one <char>\n\t\t\t\t */\n\n\t\t\t\tif (textLines[i].containSpaceOverFlow()) {\n\t\t\t\t\toverFlow.unshift(\n\t\t\t\t\t\ttextLines[i].getWord(\n\t\t\t\t\t\t\ttextLines[i].message.length - 1,\n\t\t\t\t\t\t\tTRAVEL_DIRECTION.TO_LEFT\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\toverFlow.unshift(textLines[i].popChar());\n\t\t\t\t}\n\n\t\t\t\t// Note: pay attention the way that <char/words> are pushed. It's important for the next step.\n\t\t\t}\n\n\t\t\t// If there was an overflow\n\t\t\tif (overFlow.length > 0) {\n\t\t\t\t// If there is not next Line, we have to create one\n\t\t\t\tif (textLines[i + 1] === undefined) {\n\t\t\t\t\ttextLines[i].isEndLine(false);\n\t\t\t\t\tthis.createTextLine();\n\t\t\t\t}\n\t\t\t\t// If the line contains a line break, the content of the overflow moves to a new line,\n\t\t\t\t// not on the next.\n\t\t\t\telse if (textLines[i].endLine) {\n\t\t\t\t\tthis.createTextLine(i + 1);\n\t\t\t\t\ttextLines[i].isEndLine(false);\n\t\t\t\t\ttextLines[i + 1].isEndLine(true);\n\t\t\t\t}\n\n\t\t\t\tlet lineAddIndex = 0;\n\n\t\t\t\t// Time to add the <overFlow> to the next Line\n\t\t\t\tfor (let k = 0; k < overFlow.length; k += 1) {\n\t\t\t\t\tfor (let j = 0; j < overFlow[k].length; j += 1) {\n\t\t\t\t\t\t// TODO: This function <Line.addChar3D> could be optimized, we just want to add\n\t\t\t\t\t\t// TODO: we dont need to update the <char> position there, since we'll do it later\n\t\t\t\t\t\ttextLines[i + 1].addChar3D(\n\t\t\t\t\t\t\toverFlow[k][j],\n\t\t\t\t\t\t\ttextOrigin,\n\t\t\t\t\t\t\tlineAddIndex\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlineAddIndex += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Since the get function do not destroy the position of the <char> remaining\n\t\t\t\t// We just need to relocate (update) the next Line, where we added the overflow.\n\t\t\t\ttextLines[i + 1].fullUpdate(textOrigin);\n\t\t\t}\n\n\t\t\t// ! Note: It probably is not necessary since we already update the line before,\n\t\t\t// ! and if we didn't enter in that <if case> we do not need to update anything\n\t\t\ttextLines[i].fullUpdate(textOrigin);\n\t\t}\n\n\t\t// ! Note: This probably is not necessary neither since we already update every \"next Line\" before\n\t\tthis.textFullUpdate(fromLineIndex);\n\t}\n\n\t/**\n\t * Using the global variable textFrameData and an <Index> from arguments\n\t * this function will process every Line from Line[Index] till the last Line.\n\t * It will check if there is enough space to move a word from the current line\n\t * to the previous line.\n\t * Note: this function is usually called after an <delete> method (deleteChar3D, for example).\n\t * @param fromLineIndex -\n\t */\n\tcheckCapacity(fromLineIndex: number = 0): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textOrigin = userData.textFrame.textOrigin;\n\t\tconst maxLineSize = userData.textFrame.maxLineSize;\n\t\tconst textLines = userData.textFrame.textLines;\n\n\t\tfor (let i = fromLineIndex; i < textLines.length; i += 1) {\n\t\t\t/*\n\t\t\t * Relocating every char of the current Line to their correct position.\n\t\t\t * Since we constantly \"get\" and \"add\" words to current and previous Lines\n\t\t\t * we need to update this line to correctly check if there's space to add more words\n\t\t\t */\n\t\t\ttextLines[i].updateYLinePos(this.getNewLinePosition(i));\n\t\t\ttextLines[i].fullUpdate(textOrigin);\n\n\t\t\t// If there is not a previous Line, we havn't to check anything\n\t\t\tif (!textLines[i - 1]) continue;\n\n\t\t\t// If the previous Line have not an <endLine> (finish of a Paragraph) we can proceed\n\t\t\twhile (!textLines[i - 1].endLine) {\n\t\t\t\tlet word;\n\t\t\t\tconst spaceLeft = textLines[i - 1].spaceLeft(maxLineSize);\n\n\t\t\t\t// If the <spaceLeft> in the previous Line is enough to add the first <word> of the current Line\n\t\t\t\tif (textLines[i].wordSize(0, TRAVEL_DIRECTION.TO_RIGHT) <= spaceLeft) {\n\t\t\t\t\t// If the textLine have no spaces (the word is bigger than the Line) we just get a <char>\n\t\t\t\t\tif (textLines[i].containSpace()) {\n\t\t\t\t\t\tword = textLines[i].getWord(0, TRAVEL_DIRECTION.TO_RIGHT);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tword = textLines[i].popChar(0);\n\t\t\t\t\t}\n\n\t\t\t\t\t// The word obtained (from the current Line) is added to the previous Line\n\t\t\t\t\tfor (let k = 0; k < word.length; k += 1) {\n\t\t\t\t\t\tif (word[k]) {\n\t\t\t\t\t\t\ttextLines[i - 1].addChar3D(word[k], textOrigin);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (textLines[i].isEmpty()) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * If the current Line do not have more <words>, we must delete the Line.\n\t\t\t\t\t\t * Since we splice the Line from the textLines array the current line will be a new one\n\t\t\t\t\t\t * and in the next loop will be skipped, so we'll back one step (i - 1).\n\t\t\t\t\t\t */\n\n\t\t\t\t\t\tif (textLines[i].endLine) textLines[i - 1].isEndLine(true);\n\t\t\t\t\t\ttextLines.splice(i, 1);\n\t\t\t\t\t\ti -= 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If there are still words we'll just relocate them for the next loop\n\t\t\t\t\t\ttextLines[i].updateYLinePos(this.getNewLinePosition(i));\n\t\t\t\t\t\ttextLines[i].fullUpdate(textOrigin);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Finally, we must relocate (update) every line\n\t\t * since we didn't update after add words (we just did it after get them)\n\t\t */\n\t\tthis.textFullUpdate(fromLineIndex);\n\t}\n\n\t/**\n\t * Create a <textLine> at the very end (usually) of the textFrame\n\t * It's almost the same that <enterNewLine> method but, since it's (usually)\n\t * created at the end of the textFrame we dont need to update anything (neither text nor cursor)\n\t * @param index -\n\t */\n\tcreateTextLine(\n\t\tindex = (this.userData as UserData).textFrame.textLines.length\n\t): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textFrameData = userData.textFrame;\n\n\t\ttextFrameData.textLines.splice(\n\t\t\tindex,\n\t\t\t0,\n\t\t\tnew TextLine(\n\t\t\t\tthis.getNewLinePosition(index),\n\t\t\t\ttextFrameData.lineHeight,\n\t\t\t\ttextFrameData.fontSize\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Given the textFrameData (textFrame.userData.textFrame) and an <Index>\n\t * This function will relocate every char from Line[Index] till the last Line\n\t * @param fromLineIndex -\n\t */\n\ttextFullUpdate(fromLineIndex: number = 0): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textFrameData = userData.textFrame;\n\t\tconst textLines = textFrameData.textLines;\n\t\tconst verticalAlignmentOffSet = this.getVerticalAlignmentOffSet();\n\n\t\tfor (let i = fromLineIndex; i < textLines.length; i++) {\n\t\t\ttextLines[i].updateYLinePos(this.getNewLinePosition(i));\n\t\t\ttextLines[i].fullUpdate(textFrameData.textOrigin);\n\t\t\ttextLines[i].alignText(\n\t\t\t\ttextFrameData.textOrigin,\n\t\t\t\ttextFrameData.maxLineSize,\n\t\t\t\ttextFrameData.horizontalAlignment,\n\t\t\t\ttextFrameData.verticalAlignment,\n\t\t\t\tverticalAlignmentOffSet\n\t\t\t);\n\t\t}\n\t}\n\n\tgetVerticalAlignmentOffSet(): number {\n\t\tconst userData = this.userData as UserData;\n\t\tswitch (userData.textFrame.verticalAlignment) {\n\t\t\tcase VerticalAlign.Top:\n\t\t\t\treturn 0;\n\t\t\tcase VerticalAlign.Center:\n\t\t\t\treturn this.getRemainingVerticalSpace() / 2;\n\t\t\tcase VerticalAlign.Bottom:\n\t\t\t\treturn this.getRemainingVerticalSpace();\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t}\n\t}\n\n\tgetRemainingVerticalSpace(): number {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textLines = userData.textFrame.textLines;\n\t\t// let lastIndex = textLines.length - 1;\n\t\t// let lastLineSize = textLines[lastIndex].maxCharSize * textLines[lastIndex].lineHeight\n\n\t\t// return (this.geometry as SPEGeometry).userData.parameters.height - this.getNewLinePosition(textLines.length) - lastLineSize;\n\t\treturn (\n\t\t\t(this.geometry as Geometry).userData.parameters.height -\n\t\t\tthis.getNewLinePosition(textLines.length)\n\t\t);\n\t}\n\n\t/**\n\t * Given an <index>, the function will find the position.y for the Line[index]\n\t * @param index -\n\t */\n\tgetNewLinePosition(index: number): number {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textLines = userData.textFrame.textLines;\n\t\tlet yLinePos = 0;\n\n\t\tfor (let i = 0; i < index; i += 1) {\n\t\t\tyLinePos += textLines[i].maxCharSize * textLines[i].lineHeight;\n\t\t}\n\t\treturn yLinePos;\n\t}\n\n\t/**\n\t *\n\t * @param color - ColorA value\n\t */\n\tupdateColor(color: ColorA): void {\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.hexColor = color;\n\n\t\tconst textLines = userData.textFrame.textLines;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\tconst message: Char3D[] = textLines[i].message;\n\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\tconst material = message[j].material as MeshBasicMaterial;\n\t\t\t\tif (material.color?.isColor) {\n\t\t\t\t\tmaterial.color = color;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param opacity - opacity value\n\t */\n\tupdateOpacity(opacity: number): void {\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.opacity = opacity;\n\n\t\tconst textLines: TextLine[] = userData.textFrame.textLines;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\tconst message = textLines[i].message;\n\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\tconst material: Material = message[j].material as Material;\n\t\t\t\tmaterial.opacity = opacity;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param visible - visible value\n\t */\n\tupdateVisible(visible: boolean): void {\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.visible = visible;\n\n\t\tconst textLines: TextLine[] = userData.textFrame.textLines;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\tconst message = textLines[i].message;\n\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\tconst material: Material = message[j].material as Material;\n\t\t\t\tmaterial.visible = visible;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Load a new font and assigns it\n\t * @param fontFamily - font family value\n\t */\n\tasync updateFontFamily(fontFamily: string): Promise<void> {\n\t\tawait Char3D.loadFont(fontFamily);\n\n\t\tconst userData = this.userData as UserData;\n\t\tconst textFrameData = userData.textFrame;\n\t\tconst textLines = textFrameData.textLines;\n\n\t\ttextFrameData.fontFamily = fontFamily;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\tconst message = textLines[i].message;\n\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\tmessage[j].updateFontFamily(fontFamily);\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * We can be sure if the new <value> is bigger or smaller than the previous one.\n\t\t * So, we are running both methods <checkOverFlow> and <checkCapacity>\n\t\t */\n\t\tthis.textFullUpdate();\n\t\tthis.checkOverFlow();\n\t\tthis.checkCapacity();\n\t}\n\n\t/**\n\t * Given a new size <newFontSize> the function will update every <Char3D>'s mesh and reorganize the text\n\t * @param fontSize - font size value\n\t */\n\tupdateFontSize(fontSize: number) {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textFrameData = userData.textFrame;\n\t\tconst textLines = textFrameData.textLines;\n\t\tconst oldfontSize = textFrameData.fontSize;\n\n\t\ttextFrameData.fontSize = fontSize;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\ttextLines[i].updateFontSize(fontSize);\n\t\t}\n\n\t\tthis.textFullUpdate();\n\n\t\t/*\n\t\t * Once the text is organized, if the <fontSize> is bigger than <oldFontSize>\n\t\t * the text probably will be outside the <textFrame> area, so we must run the <checkOverFlow> method\n\t\t * otherwise run the <checkCapacity> method (small letters means more space at the end of the Line, so we'll be able to move up few words)\n\t\t */\n\t\tif (fontSize > oldfontSize) {\n\t\t\tthis.checkOverFlow();\n\t\t} else if (fontSize < oldfontSize) {\n\t\t\tthis.checkCapacity();\n\t\t}\n\t}\n\n\t/**\n\t * Updated the text transform, makes sure the font is loaded before the update.\n\t * @param textTransform - text transform value\n\t */\n\tasync updateTextTransform(value: TextTransform): Promise<void> {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textFrameData = userData.textFrame;\n\n\t\tawait Char3D.loadFont(textFrameData.fontFamily);\n\n\t\tconst textLines = textFrameData.textLines;\n\n\t\ttextFrameData.textTransform = value;\n\n\t\t// Once we are sure that the <fontFamily> is loaded, then, let's update every <Char3D> to its <upperCase> version\n\t\tswitch (value) {\n\t\t\tcase TextTransform.Upper:\n\t\t\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\t\t\tconst message = textLines[i].message;\n\t\t\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\t\t\ttextLines[i].message[j].updateChar(message[j].char.toUpperCase());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TextTransform.Lower:\n\t\t\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\t\t\tconst message = textLines[i].message;\n\t\t\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\t\t\ttextLines[i].message[j].updateChar(message[j].char.toLowerCase());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t//case TextTransform.None:\n\t\t\tdefault:\n\t\t\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\t\t\tconst message = textLines[i].message;\n\t\t\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\t\t\ttextLines[i].message[j].updateChar(message[j].originalChar);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t}\n\n\t\t// Now reorganize every <Char3D>'s position\n\t\tthis.textFullUpdate();\n\n\t\t// Since we can't be totally sure that every char will be bigger or smaller we are running both methods\n\t\t// <checkOverFlow> and <checkCapacity>\n\t\tthis.checkOverFlow();\n\t\tthis.checkCapacity();\n\t}\n\n\t/**\n\t *\n\t * @param letterSpacing - letter spacing value\n\t */\n\tupdateLetterSpacing(letterSpacing: number): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textLines = userData.textFrame.textLines;\n\n\t\tuserData.textFrame.letterSpacing = letterSpacing;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\tconst message = textLines[i].message;\n\t\t\tfor (let j = 0; j < message.length; j++) {\n\t\t\t\tmessage[j].updateLetterSpacing(letterSpacing);\n\t\t\t}\n\t\t}\n\n\t\tthis.textFullUpdate();\n\n\t\t// Since a bigger letter spacing could push the text out of the <textFrame> area we must run <checkOverFlow> method\n\t\t// Otherwise a smaller letter spacing means more free space in every Line, so we must run <checkCapacity> method\n\n\t\t// TODO: optimizations could be done by checking the old and new <letterSpacing>\n\n\t\tthis.checkOverFlow();\n\t\tthis.checkCapacity();\n\t}\n\n\t/**\n\t *\n\t * @param LOD - LOD value\n\t */\n\tupdateLOD(LOD: number): void {\n\t\t// TODO\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.LOD = LOD;\n\n\t\tconst textLines: TextLine[] = userData.textFrame.textLines;\n\n\t\tfor (let c = 0; c < textLines.length; c++) {\n\t\t\t// TODO I commented the next line since the updateLOD function does not exist on TextLine\n\t\t\t// textLines[c].updateLOD(LOD);\n\t\t}\n\n\t\t// TODO: Probably since we are just switching between LODs we do not need to check anything (neither <checkOverFlow> nor <checkCapacity>)\n\n\t\t// Now reorganize every <Char3D>'s position\n\t\tthis.textFullUpdate();\n\n\t\tthis.checkOverFlow();\n\t\tthis.checkCapacity();\n\t}\n\n\t/**\n\t *\n\t * @param lineHeight - line height value\n\t */\n\tupdateLineHeight(lineHeight: number): void {\n\t\tconst userData = this.userData as UserData;\n\t\tconst textLines = userData.textFrame.textLines;\n\n\t\tuserData.textFrame.lineHeight = lineHeight;\n\n\t\tfor (let i = 0; i < textLines.length; i++) {\n\t\t\ttextLines[i].updatelineHeight(lineHeight);\n\t\t}\n\n\t\tthis.textFullUpdate();\n\t}\n\n\t/**\n\t *\n\t * @param verticalAlign - vertical align value\n\t */\n\tupdateVerticalAlignment(verticalAlign: VerticalAlign): void {\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.verticalAlignment = verticalAlign;\n\t\tthis.textFullUpdate();\n\t}\n\n\t/**\n\t *\n\t * @param horizontalAlign - horizontal align value\n\t */\n\tupdateHorizontalAlignment(horizontalAlign: HorizontalAlign): void {\n\t\tconst userData = this.userData as UserData;\n\t\tuserData.textFrame.horizontalAlignment = horizontalAlign;\n\t\tthis.textFullUpdate();\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedTextFrame;\n\n\t\tobject.objectType = 'TextFrame';\n\n\t\tconst userData = this.userData as UserData;\n\t\tconst textLinesData: ITextLine[] = userData.textFrame.textLines.map(\n\t\t\t(textLine) => {\n\t\t\t\tconst message = textLine.message.map((char3D) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tchar: char3D.char,\n\t\t\t\t\t\toriginalChar: char3D.originalChar,\n\t\t\t\t\t\tfontFamily: char3D.fontFamily,\n\t\t\t\t\t\tletterSpacing: char3D.letterSpacing,\n\t\t\t\t\t\tfontSize: char3D.fontSize,\n\t\t\t\t\t\tLOD: char3D.LOD,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\talign: textLine.align,\n\t\t\t\t\tendLine: textLine.endLine,\n\t\t\t\t\tlineHeight: textLine.lineHeight,\n\t\t\t\t\tmaxCharSize: textLine.maxCharSize,\n\t\t\t\t\tyLinePos: textLine.yLinePos,\n\t\t\t\t\tmessage: message,\n\t\t\t\t};\n\t\t\t}\n\t\t);\n\n\t\t(object.userData as unknown as UserData).textFrame.textLinesData =\n\t\t\ttextLinesData;\n\t\treturn data;\n\t}\n\n\tasync fromJSONasync(data: SerializedTextFrame): Promise<this> {\n\t\tsuper.fromJSON(data);\n\n\t\tif (data.userData !== undefined) {\n\t\t\tconst userData = (data.userData as any as UserData).textFrame;\n\n\t\t\tawait Char3D.loadFont(userData.fontFamily);\n\n\t\t\tuserData.textOrigin = new Vector3(\n\t\t\t\tuserData.textOrigin.x,\n\t\t\t\tuserData.textOrigin.y,\n\t\t\t\tuserData.textOrigin.z\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * If using BasicMaterial we are currently unable to change the color of the text after saving closing and reopening the file.\n\t\t\t */\n\t\t\tconst material = new MeshBasicMaterial({\n\t\t\t\tcolor: userData.hexColor,\n\t\t\t\topacity: userData.opacity,\n\t\t\t\tvisible: userData.visible,\n\t\t\t\ttransparent: true,\n\t\t\t\tside: DoubleSide,\n\t\t\t});\n\n\t\t\tif (userData.textLinesData) {\n\t\t\t\tuserData.textLines = userData.textLinesData.map((textLineData, i) => {\n\t\t\t\t\tconst textLine = new TextLine(\n\t\t\t\t\t\tNumber(textLineData.yLinePos),\n\t\t\t\t\t\tNumber(textLineData.lineHeight),\n\t\t\t\t\t\tNumber(textLineData.maxCharSize)\n\t\t\t\t\t);\n\t\t\t\t\t// textLine.align = userData.horizontalAlignment;\n\n\t\t\t\t\tconst message = textLineData.message.map((char3Ddata, j) => {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Sometime I have a weird bug where all character data is undefined\n\t\t\t\t\t\t * In that case we can check if the data is not located in another place because of some\n\t\t\t\t\t\t * legacy serialization format.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (char3Ddata.char === undefined) {\n\t\t\t\t\t\t\tconst legacyData = userData.textLines[i].message[j] as\n\t\t\t\t\t\t\t\t| Char3D\n\t\t\t\t\t\t\t\t| LegacyJSONChar;\n\t\t\t\t\t\t\tif ('geometries' in legacyData) {\n\t\t\t\t\t\t\t\tconst parameters = legacyData.geometries[0].userData.parameters;\n\t\t\t\t\t\t\t\tObject.assign(char3Ddata, {\n\t\t\t\t\t\t\t\t\tLOD: parameters.lod,\n\t\t\t\t\t\t\t\t\tchar: parameters.char,\n\t\t\t\t\t\t\t\t\tfontFamily: parameters.fontFamily,\n\t\t\t\t\t\t\t\t\tfontSize: parameters.fontSize,\n\t\t\t\t\t\t\t\t\tletterSpacing: parameters.letterSpacing,\n\t\t\t\t\t\t\t\t\toriginalChar: parameters.char,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst options = {\n\t\t\t\t\t\t\tchar: char3Ddata.char,\n\t\t\t\t\t\t\tfontFamily: char3Ddata.fontFamily,\n\t\t\t\t\t\t\tletterSpacing: Number(char3Ddata.letterSpacing),\n\t\t\t\t\t\t\tfontSize: Number(char3Ddata.fontSize),\n\t\t\t\t\t\t\tLOD: char3Ddata.LOD,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst char3D = new Char3D(options, material.clone());\n\t\t\t\t\t\ttextLine.addChar3D(char3D, userData.textOrigin);\n\t\t\t\t\t\tthis.charContainer.add(char3D);\n\n\t\t\t\t\t\treturn char3D;\n\t\t\t\t\t});\n\n\t\t\t\t\ttextLine.message = message;\n\t\t\t\t\treturn textLine;\n\t\t\t\t});\n\n\t\t\t\tthis.userData.textFrame = userData;\n\t\t\t}\n\n\t\t\tthis.textFullUpdate();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tfromTextFrameData(\n\t\tdata: Partial<TextFrameData>,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tif (data.color !== undefined) {\n\t\t\tconst color = getSharedColorData(data.color, sharedAssets);\n\t\t\tthis.updateColor(color);\n\t\t\tthis.updateOpacity(color.a);\n\t\t}\n\t\tif (data.alpha !== undefined) {\n\t\t\tthis.updateOpacity(data.alpha);\n\t\t}\n\t\tif (data.font !== undefined) {\n\t\t\tthis.updateFontFamily(data.font);\n\t\t}\n\t\tif (data.horizontalAlign !== undefined) {\n\t\t\tthis.updateHorizontalAlignment(data.horizontalAlign);\n\t\t}\n\t\tif (data.verticalAlign !== undefined) {\n\t\t\tthis.updateVerticalAlignment(data.verticalAlign);\n\t\t}\n\t\tif (data.textTransform !== undefined) {\n\t\t\tthis.updateTextTransform(data.textTransform);\n\t\t}\n\t\tif (data.fontSize !== undefined) {\n\t\t\tthis.updateFontSize(data.fontSize);\n\t\t}\n\t\tif (data.lineHeight !== undefined) {\n\t\t\tthis.updateLineHeight(data.lineHeight);\n\t\t}\n\t\tif (data.letterSpacing !== undefined) {\n\t\t\tthis.updateLetterSpacing(data.letterSpacing);\n\t\t}\n\t\t// @patch not sure why we need data.text !== '', otherwise it throws an error,\n\t\t// something related with textlines === undefined, updateText is async\n\t\tif (data.text !== undefined && data.text !== '') {\n\t\t\tthis.updateText(data.text);\n\t\t}\n\t\tif (data.width !== undefined || data.height !== undefined) {\n\t\t\tthis.updateGeometry({\n\t\t\t\tparameters: { width: data.width, height: data.height },\n\t\t\t});\n\t\t}\n\t}\n\n\tfromState(\n\t\tdata: TextFrameObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t): this {\n\t\tsuper.fromState(data);\n\t\tthis.fromTextFrameData(data, sharedAssets);\n\t\treturn this;\n\t}\n\n\tconvertToVector(): EmptyObject {\n\t\tconst { fontFamily, hexColor } = this.userData.textFrame;\n\t\tconst group = new EmptyObject();\n\t\tgroup.name = 'Text Shape';\n\t\tconst font: JsonFont = Char3D.fontCache[fontFamily];\n\n\t\tfor (const char of this.charContainer.children) {\n\t\t\tif (!(char instanceof Char3D)) continue;\n\t\t\tfont.generateShapes(char.char, 1).forEach((textShape) => {\n\t\t\t\tconst shape = new VectorShape().fromShape(textShape);\n\t\t\t\tshape.applyScale(char.scale.x, char.scale.y);\n\n\t\t\t\tconst geometry = VectorGeometry.create({ shape });\n\t\t\t\tconst material = new BasicMaterial({ side: DoubleSide });\n\t\t\t\tmaterial.color = hexColor;\n\n\t\t\t\tconst obj = new VectorObject(geometry, material);\n\t\t\t\tobj.name = char.char;\n\t\t\t\tobj.position.copy(char.position);\n\t\t\t\tobj.rotation.copy(char.rotation);\n\n\t\t\t\tgroup.attach(obj);\n\t\t\t});\n\t\t}\n\n\t\treturn group;\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { Mesh, BufferGeometry, Material } from 'three';\nimport {\n\tGeometryUtils,\n\tGeometry,\n\tgeometries,\n\tcreateGeometry,\n} from '../../geometries';\nimport { EntityMixin } from './Entity';\nimport { Cloner } from '../Cloner';\nimport { Constructor } from '../Object3D';\nimport {\n\tBaseInputs,\n\tCGeometry,\n\tIGeometry,\n\tNestedPartial,\n} from '../../geometries/Geometry';\nimport {\n\tserialize,\n\tserializeGeometry,\n} from '../../fileManager/object/ObjectExporter';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedMaterial,\n\tSerializedEntity,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport {\n\tClonerState,\n\tMeshObjectState,\n\tTextFrameObjectState,\n} from 'spline-data';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\n\nexport class AbstractMesh extends EntityMixin(Mesh) {\n\treadonly isAbstractMesh: boolean = true;\n\tprivate _cloner?: Cloner;\n\tselectedMaterial?: number;\n\n\tconstructor(geometry: BufferGeometry, material: Material | Material[]) {\n\t\tsuper(geometry, material);\n\n\t\tif (Array.isArray(material)) {\n\t\t\tthis.selectedMaterial = 0;\n\t\t\tif (geometry.groups.length === 0) {\n\t\t\t\t// In some external file loads, since we force material as array, we need at least a default group if none exists\n\t\t\t\tgeometry.addGroup(0, geometry.getAttribute('position').count, 0);\n\t\t\t}\n\t\t}\n\t}\n\n\tget cloner(): Cloner | undefined {\n\t\treturn this._cloner;\n\t}\n\n\tset cloner(cloner: Cloner | undefined) {\n\t\tif (this._cloner) {\n\t\t\tthis.remove(this._cloner);\n\t\t}\n\n\t\tif (cloner) {\n\t\t\tthis.add(cloner);\n\t\t}\n\n\t\tthis._cloner = cloner;\n\t}\n\n\tgetSelectedMaterial(index?: number): Material {\n\t\tif (Array.isArray(this.material)) {\n\t\t\tif (this.selectedMaterial === undefined)\n\t\t\t\tthis.selectedMaterial = index ?? 0; // in case it was removed\n\t\t\treturn this.material[index ?? this.selectedMaterial];\n\t\t}\n\t\treturn this.material;\n\t}\n\n\tsetSelectedMaterial(material: Material, index?: number): void {\n\t\tif (Array.isArray(this.material)) {\n\t\t\tif (this.selectedMaterial === undefined)\n\t\t\t\tthis.selectedMaterial = index ?? 0; // in case it was removed\n\t\t\tindex = index ?? this.selectedMaterial;\n\t\t\tthis.material[index].dispose();\n\t\t\tthis.material[index] = material;\n\t\t} else {\n\t\t\tthis.material.dispose();\n\t\t\tthis.material = material;\n\t\t}\n\t}\n\n\tupdateGeometry<TInputs extends BaseInputs>(\n\t\tinputs: NestedPartial<TInputs>\n\t): void {\n\t\tconst oldGeometry = this.geometry as IGeometry<TInputs>;\n\t\tconst Factory = geometries[oldGeometry.userData.type] as CGeometry<TInputs>;\n\t\tconst base =\n\t\t\tthis.objectType === 'NonParametric'\n\t\t\t\t? Object.assign({}, oldGeometry.userData, { geometry: oldGeometry })\n\t\t\t\t: oldGeometry.userData;\n\t\tconst geometry = Factory.build(Factory.normalizeInputs(inputs, base));\n\n\t\tconst uuid = oldGeometry.uuid;\n\t\tthis.geometry.dispose();\n\t\tthis.geometry = geometry;\n\t\tthis.geometry.uuid = uuid;\n\t\tthis.geometry.computeBoundingSphere();\n\n\t\tif (this.cloner) {\n\t\t\tfor (const child of this.cloner.children) {\n\t\t\t\t(child as Mesh).geometry = this.geometry;\n\t\t\t}\n\t\t}\n\n\t\t// (this.geometry as BufferGeometry).copy(geometry);\n\t\t// // @ts-expect-error array is readonly\n\t\t// (this.geometry as BufferGeometry).attributes.position.array =\n\t\t// \tgeometry.attributes.position.array;\n\t}\n\n\tresizeGeometry(width: number, height: number, depth: number): void {\n\t\tGeometryUtils.resizeGeometry(this.geometry as Geometry, {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t});\n\t}\n\n\tshallowClone(recursive?: boolean): this {\n\t\treturn new (this.constructor as any as Constructor<this>)(\n\t\t\tthis.geometry,\n\t\t\tthis.material\n\t\t).shallowCopy(this, recursive);\n\t}\n\n\tclone(recursive?: boolean): this {\n\t\tconst inputs =\n\t\t\tthis.objectType === 'NonParametric'\n\t\t\t\t? Object.assign({}, this.geometry.userData, {\n\t\t\t\t\t\t// patch: the standard clone() of geometry create an instance of BufferGeometry, and the standard BufferGeometry serialization (toJson()) save information that we dont need to reproduce the (parametric) shape (attributes, index, boundingSphere);\n\t\t\t\t\t\tgeometry: this.geometry.clone(),\n\t\t\t\t })\n\t\t\t\t: this.geometry.userData;\n\n\t\tconst geometry = createGeometry(inputs as Geometry['userData']);\n\n\t\tconst material = Array.isArray(this.material)\n\t\t\t? this.material.map((item) => item.clone())\n\t\t\t: this.material.clone();\n\n\t\treturn new (this.constructor as any as Constructor<this>)(\n\t\t\tgeometry,\n\t\t\tmaterial\n\t\t).copy(this, recursive);\n\t}\n\n\tcopy(source: this, recursive: boolean = true): this {\n\t\tsuper.copy(source, recursive);\n\n\t\tif (source.cloner) {\n\t\t\tthis.cloner = new Cloner(source, source.cloner.parameters);\n\t\t\tthis.add(this.cloner);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedEntity;\n\n\t\t// if (this.cloner !== undefined) object.cloner = this.cloner.toJSON();\n\n\t\tobject.geometry = serializeGeometry(\n\t\t\tmeta!.geometries,\n\t\t\tthis.geometry,\n\t\t\tthis.material\n\t\t\t// meta\n\t\t);\n\n\t\tif (Array.isArray(this.material)) {\n\t\t\tconst uuids = [];\n\n\t\t\tfor (let i = 0, l = this.material.length; i < l; i++) {\n\t\t\t\tuuids.push(\n\t\t\t\t\tserialize<SerializedMaterial, Material>(\n\t\t\t\t\t\tmeta!.materials,\n\t\t\t\t\t\tthis.material[i],\n\t\t\t\t\t\tmeta\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tobject.material = uuids;\n\t\t} else {\n\t\t\tobject.material = serialize<SerializedMaterial, Material>(\n\t\t\t\tmeta!.materials,\n\t\t\t\tthis.material,\n\t\t\t\tmeta\n\t\t\t);\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedEntity): this {\n\t\tsuper.fromJSON(data);\n\n\t\tif (data.selectedMaterial !== undefined)\n\t\t\tthis.selectedMaterial = data.selectedMaterial;\n\n\t\treturn this;\n\t}\n\n\tsetFromClonerState(clonerState: ClonerState | null) {\n\t\tif (clonerState === null) {\n\t\t\tthis.cloner = undefined;\n\t\t} else {\n\t\t\tif (this.cloner === undefined) {\n\t\t\t\tthis.cloner = new Cloner(this);\n\t\t\t}\n\t\t\tthis.cloner.fromClonerState(clonerState);\n\t\t}\n\t}\n\n\tfromState(\n\t\tdata: MeshObjectState | TextFrameObjectState,\n\t\tsharedAssets?: SharedAssetsManager\n\t): this {\n\t\tsuper.fromState(data);\n\t\tif (data.type === 'Mesh') {\n\t\t\tthis.setFromClonerState(data.cloner);\n\t\t\tthis.castShadow = data.castShadow ?? true;\n\t\t\tthis.receiveShadow = data.receiveShadow ?? true;\n\t\t}\n\t\treturn this;\n\t}\n}\n", "/**\n * @author s-ol\n */\n\nimport {\n\tBufferGeometry,\n\tConeBufferGeometry,\n\tFloat32BufferAttribute,\n\tVector2,\n\tVector3,\n} from 'three';\nimport { RoundedCylinderBufferGeometry } from './CylinderGeometry';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type ConeGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tradialSegments: number;\n\theightSegments: number;\n\topenEnded: boolean;\n\tthetaStart: number;\n\tthetaLength: number;\n\tcornerRadiusTop: number;\n\tcornerRadiusBottom: number;\n\tcornerSegments: number;\n};\n\nexport type ConeGeometryInputs = {\n\tparameters: ConeGeometryParameters;\n};\n\nexport const ConeGeometry: CGeometry<ConeGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<ConeGeometryInputs>\n\t): IGeometry<ConeGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<ConeGeometryInputs>,\n\t\tbase?: ConeGeometryInputs\n\t): ConeGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tradialSegments: 32,\n\t\t\t\theightSegments: 8,\n\t\t\t\topenEnded: false,\n\t\t\t\tthetaStart: 0,\n\t\t\t\tthetaLength: 360,\n\t\t\t\tcornerRadiusTop: 0,\n\t\t\t\tcornerRadiusBottom: 0,\n\t\t\t\tcornerSegments: 8,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: ConeGeometryInputs): IGeometry<ConeGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\tdepth,\n\t\t\theight,\n\t\t\tradialSegments,\n\t\t\theightSegments,\n\t\t\topenEnded,\n\t\t\tthetaStart,\n\t\t\tthetaLength,\n\t\t\tcornerRadiusTop,\n\t\t\tcornerRadiusBottom,\n\t\t\tcornerSegments,\n\t\t} = inputs.parameters;\n\n\t\tlet geometry: BufferGeometry;\n\t\tif (cornerRadiusTop > 0 || cornerRadiusBottom > 0 || thetaLength < 360) {\n\t\t\tgeometry = new RoundedCylinderBufferGeometry(\n\t\t\t\t0,\n\t\t\t\twidth / 2,\n\t\t\t\theight,\n\t\t\t\tradialSegments,\n\t\t\t\theightSegments,\n\t\t\t\topenEnded,\n\t\t\t\tthetaStart,\n\t\t\t\t(thetaLength * Math.PI) / 180,\n\t\t\t\tcornerRadiusTop,\n\t\t\t\tcornerRadiusBottom,\n\t\t\t\tcornerSegments,\n\t\t\t\t0,\n\t\t\t\ttrue\n\t\t\t);\n\t\t} else {\n\t\t\tgeometry = new ConeBufferGeometry(\n\t\t\t\twidth / 2,\n\t\t\t\theight,\n\t\t\t\tradialSegments,\n\t\t\t\theightSegments,\n\t\t\t\topenEnded\n\t\t\t);\n\t\t}\n\n\t\tgeometry.scale(1, 1, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'ConeGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport class PlainConeGeometry extends BufferGeometry {\n\tparameters: {\n\t\tradialSegments: number;\n\t\theightSegments: number;\n\t};\n\n\tconstructor(\n\t\tradiusBase: number = 1,\n\t\theight: number = 1,\n\t\tradialSegments: number = 8,\n\t\theightSegments: number = 1,\n\t\tthetaStart: number = 0,\n\t\tthetaLength: number = Math.PI * 2\n\t) {\n\t\tsuper();\n\t\tconst radiusTop: number = radiusBase / heightSegments;\n\n\t\tthis.parameters = {\n\t\t\tradialSegments: radialSegments,\n\t\t\theightSegments: heightSegments,\n\t\t};\n\n\t\tconst scope = this;\n\n\t\tradialSegments = Math.floor(radialSegments);\n\t\theightSegments = Math.floor(heightSegments);\n\n\t\t// buffers\n\n\t\tconst indices: number[] = [];\n\t\tconst vertices: number[] = [];\n\t\tconst normals: number[] = [];\n\t\tconst uvs: number[] = [];\n\n\t\t// helper variables\n\n\t\tlet index = 0;\n\t\tconst indexArray: number[][] = [];\n\t\tconst halfHeight = height / 2;\n\t\tlet groupStart = 0;\n\n\t\t// generate geometry\n\n\t\tgenerateTorso();\n\t\tgenerateCap(true);\n\t\tgenerateCap(false);\n\n\t\t// build geometry\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\t// this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t\tfunction generateTorso() {\n\t\t\t// const normal = new Vector3();\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tlet groupCount = 0;\n\n\t\t\t// this will be used to calculate the normal\n\t\t\t// const slope = ( radiusBase ) / height;\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor (let y = 1; y <= heightSegments; y++) {\n\t\t\t\tconst indexRow: number[] = [];\n\n\t\t\t\tconst v = y / heightSegments;\n\n\t\t\t\t// calculate the radius of the current row\n\n\t\t\t\tconst radius = v * radiusBase;\n\n\t\t\t\tfor (let x = 0; x <= radialSegments; x++) {\n\t\t\t\t\tconst u = x / radialSegments;\n\n\t\t\t\t\tconst theta = u * thetaLength + thetaStart;\n\n\t\t\t\t\tconst sinTheta = Math.sin(theta);\n\t\t\t\t\tconst cosTheta = Math.cos(theta);\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\t\tvertex.y = -v * height + halfHeight;\n\t\t\t\t\tvertex.z = radius * cosTheta;\n\t\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\t// normal.set( sinTheta, slope, cosTheta ).normalize();\n\t\t\t\t\t// normals.push( normal.x, normal.y, normal.z );\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push(u, 1 - v);\n\n\t\t\t\t\t// save index of vertex in respective row\n\n\t\t\t\t\tindexRow.push(index++);\n\t\t\t\t}\n\n\t\t\t\t// now save vertices of the row in our index array\n\n\t\t\t\tindexArray.push(indexRow);\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor (let x = 0; x < radialSegments; x++) {\n\t\t\t\tfor (let y = 0; y < heightSegments - 1; y++) {\n\t\t\t\t\t// we use the index array to access the correct indices\n\t\t\t\t\t// console.log(x , y)\n\n\t\t\t\t\tconst a = indexArray[y][x];\n\t\t\t\t\tconst b = indexArray[y + 1][x];\n\t\t\t\t\tconst c = indexArray[y + 1][x + 1];\n\t\t\t\t\tconst d = indexArray[y][x + 1];\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push(a, b, d);\n\t\t\t\t\tindices.push(b, c, d);\n\n\t\t\t\t\t// update group counter\n\n\t\t\t\t\tgroupCount += 6;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup(groupStart, groupCount, 0);\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\t\t}\n\n\t\tfunction generateCap(top: boolean) {\n\t\t\t// save the index of the first center vertex\n\t\t\tconst centerIndexStart = index;\n\n\t\t\tconst uv = new Vector2();\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst radius = top === true ? radiusTop : radiusBase;\n\t\t\tconst sign = top === true ? 1 : -1;\n\n\t\t\t// first we generate the center vertex data of the cap.\n\t\t\t// because the geometry needs one set of uvs per face,\n\t\t\t// we must generate a center vertex per face/segment\n\n\t\t\tfor (let x = 1; x <= radialSegments; x++) {\n\t\t\t\t// vertex\n\n\t\t\t\tvertices.push(0, halfHeight * sign, 0);\n\n\t\t\t\t// normal\n\n\t\t\t\t// normals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push(0.5, 0.5);\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex++;\n\t\t\t}\n\n\t\t\t// save the index of the last center vertex\n\t\t\tconst centerIndexEnd = index;\n\n\t\t\t// now we generate the surrounding vertices, normals and uvs\n\n\t\t\tfor (let x = 0; x <= radialSegments; x++) {\n\t\t\t\tconst u = x / radialSegments;\n\t\t\t\tconst theta = u * thetaLength + thetaStart;\n\n\t\t\t\tconst cosTheta = Math.cos(theta);\n\t\t\t\tconst sinTheta = Math.sin(theta);\n\n\t\t\t\t// vertex\n\n\t\t\t\tvertex.x = radius * sinTheta;\n\t\t\t\tvertex.y = top\n\t\t\t\t\t? halfHeight *\n\t\t\t\t\t ((heightSegments - 1) / heightSegments - 1 / 2) *\n\t\t\t\t\t 2 *\n\t\t\t\t\t sign\n\t\t\t\t\t: halfHeight * sign;\n\t\t\t\tvertex.z = radius * cosTheta;\n\n\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t// normal\n\n\t\t\t\t// normals.push( 0, sign, 0 );\n\n\t\t\t\t// uv\n\n\t\t\t\tuv.x = cosTheta * 0.5 + 0.5;\n\t\t\t\tuv.y = sinTheta * 0.5 * sign + 0.5;\n\t\t\t\tuvs.push(uv.x, uv.y);\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex++;\n\t\t\t}\n\n\t\t\t// generate indices\n\n\t\t\tfor (let x = 0; x < radialSegments; x++) {\n\t\t\t\tconst c = centerIndexStart + x;\n\t\t\t\tconst i = centerIndexEnd + x;\n\n\t\t\t\tif (top === true) {\n\t\t\t\t\t// face top\n\n\t\t\t\t\tindices.push(i, i + 1, c);\n\t\t\t\t} else {\n\t\t\t\t\t// face bottom\n\n\t\t\t\t\tindices.push(i + 1, i, c);\n\t\t\t\t}\n\n\t\t\t\tgroupCount += 3;\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup(groupStart, groupCount, top === true ? 1 : 2);\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\t\t}\n\t}\n}\n", "/**\n * @author s-ol\n */\n\nimport {\n\tBufferGeometry,\n\tCylinderBufferGeometry,\n\tFloat32BufferAttribute,\n\tVector2,\n\tVector3,\n} from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type CylinderGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tradiusTop: number;\n\tradiusBottom: number;\n\tradialSegments: number;\n\theightSegments: number;\n\topenEnded: boolean;\n\tthetaStart: number;\n\tthetaLength: number;\n\tcornerRadius: number;\n\tcornerSegments: number;\n\thollow: number;\n};\n\nexport type CylinderGeometryInputs = { parameters: CylinderGeometryParameters };\n\nexport const CylinderGeometry: CGeometry<CylinderGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<CylinderGeometryInputs>\n\t): IGeometry<CylinderGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<CylinderGeometryInputs>,\n\t\tbase?: CylinderGeometryInputs\n\t): CylinderGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tradialSegments: 64,\n\t\t\t\theightSegments: 1,\n\t\t\t\topenEnded: false,\n\t\t\t\tthetaStart: 0,\n\t\t\t\tthetaLength: 360,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\tcornerSegments: 8,\n\t\t\t\thollow: 0,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\tconst radius = nParams.width / 2;\n\t\tlet radiusTop = nParams.radiusTop ?? radius;\n\t\tlet radiusBottom = nParams.radiusBottom ?? radius;\n\n\t\tif (radiusTop === radiusBottom) {\n\t\t\tradiusTop = radius;\n\t\t\tradiusBottom = radius;\n\t\t} else if (radiusTop > radiusBottom) {\n\t\t\tradiusTop = radius;\n\t\t\tradiusBottom = (radiusBottom * radius) / radiusTop;\n\t\t} else {\n\t\t\tradiusTop = (radiusTop * radius) / radiusBottom;\n\t\t\tradiusBottom = radius;\n\t\t}\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t\tradiusTop,\n\t\t\t\tradiusBottom,\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: CylinderGeometryInputs\n\t): IGeometry<CylinderGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\tdepth,\n\t\t\theight,\n\t\t\tradialSegments,\n\t\t\theightSegments,\n\t\t\topenEnded,\n\t\t\tthetaStart,\n\t\t\tthetaLength,\n\t\t\tradiusTop,\n\t\t\tradiusBottom,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments,\n\t\t\thollow,\n\t\t} = inputs.parameters;\n\n\t\tlet geometry;\n\t\tif (cornerRadius || hollow) {\n\t\t\tgeometry = new RoundedCylinderBufferGeometry(\n\t\t\t\tradiusTop,\n\t\t\t\tradiusBottom,\n\t\t\t\theight,\n\t\t\t\tradialSegments,\n\t\t\t\theightSegments,\n\t\t\t\topenEnded,\n\t\t\t\tthetaStart,\n\t\t\t\t(thetaLength * Math.PI) / 180,\n\t\t\t\tcornerRadius,\n\t\t\t\tcornerRadius,\n\t\t\t\tcornerSegments,\n\t\t\t\thollow\n\t\t\t);\n\t\t} else {\n\t\t\tgeometry = new CylinderBufferGeometry(\n\t\t\t\tradiusTop,\n\t\t\t\tradiusBottom,\n\t\t\t\theight,\n\t\t\t\tradialSegments,\n\t\t\t\theightSegments,\n\t\t\t\topenEnded,\n\t\t\t\tthetaStart,\n\t\t\t\t(thetaLength * Math.PI) / 180\n\t\t\t);\n\t\t}\n\t\tgeometry.scale(1, 1, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'CylinderGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\n/**\n * take a 2d vector in XY space and another 2d unit vector in XZ space, and\n * rotate the first into the plane of the second.\n * @param profile - 2d \"side-view\" profile position\n * @param top - unit vector describing XZ-plane rotation\n * @param out - result is stored in here\n */\nfunction two2three(profile: Vector2, top: Vector2, out: Vector3) {\n\tout.x = profile.x * top.x;\n\tout.y = profile.y;\n\tout.z = profile.x * top.y;\n}\n\n/**\n * Rotate a vector 90 degrees\n * @param vec - 2d input vector\n */\nfunction flip(vec: Vector2): Vector2 {\n\treturn new Vector2(vec.y, -vec.x);\n}\n\nexport class RoundedCylinderBufferGeometry extends BufferGeometry {\n\tconstructor(\n\t\tradiusTop: number,\n\t\tradiusBottom: number,\n\t\theight: number,\n\t\tradialSegments: number,\n\t\theightSegments: number,\n\t\topenEnded: boolean,\n\t\tthetaStart: number,\n\t\tthetaLength: number,\n\t\tcornerRadiusTop: number,\n\t\tcornerRadiusBottom: number,\n\t\tcornerSegments: number,\n\t\thollow: number,\n\t\troundAtZero = false\n\t) {\n\t\tsuper();\n\t\tthis.type = 'RoundedCylinderBufferGeometry';\n\n\t\tradiusTop = radiusTop !== undefined ? radiusTop : 1;\n\t\tradiusBottom = radiusBottom !== undefined ? radiusBottom : 1;\n\t\theight = height || 1;\n\n\t\tradialSegments = Math.floor(radialSegments) || 8;\n\t\theightSegments = Math.floor(heightSegments) || 1;\n\n\t\topenEnded = openEnded !== undefined ? openEnded : false;\n\t\tthetaStart = thetaStart !== undefined ? thetaStart : 0.0;\n\t\tthetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;\n\n\t\tif (openEnded) {\n\t\t\tcornerRadiusTop = 0;\n\t\t\tcornerRadiusBottom = 0;\n\t\t}\n\n\t\t// buffers\n\n\t\tconst indices: number[] = [];\n\t\tconst vertices: number[] = [];\n\t\tconst normals: number[] = [];\n\t\tconst uvs: number[] = [];\n\n\t\t// helper variables\n\n\t\tlet index = 0;\n\t\tconst halfHeight = height / 2;\n\n\t\t// generate geometry\n\t\tconst normal = new Vector3();\n\t\tconst vertex = new Vector3();\n\n\t\tif (roundAtZero && radiusTop == 0) {\n\t\t\tradiusTop = cornerRadiusTop;\n\t\t}\n\t\tif (roundAtZero && radiusBottom == 0) {\n\t\t\tradiusBottom = cornerRadiusBottom;\n\t\t}\n\n\t\tconst endTop = new Vector2(radiusTop, halfHeight);\n\t\tconst endBottom = new Vector2(radiusBottom, -halfHeight);\n\t\tlet cornerCenterTop = null,\n\t\t\tcornerCenterBottom = null;\n\t\tlet innerCornerCenterTop = null,\n\t\t\tinnerCornerCenterBottom = null;\n\t\tlet delta = endTop.clone().sub(endBottom);\n\n\t\tlet wallThickness = 0,\n\t\t\tradiusInnerTop = 0,\n\t\t\tradiusInnerBottom = 0;\n\t\tif (hollow > 0) {\n\t\t\twallThickness = Math.min(radiusTop, radiusBottom) * (1 - hollow);\n\t\t\tradiusInnerTop = radiusTop - wallThickness;\n\t\t\tradiusInnerBottom = radiusBottom - wallThickness;\n\t\t}\n\n\t\tconst innerEndTop = endTop.clone();\n\t\tinnerEndTop.x -= wallThickness;\n\n\t\tconst cornerAngleTop = Math.PI - delta.angle();\n\t\tconst cornerAngleBottom = delta.angle();\n\t\tconst cornerTanTop = Math.tan(cornerAngleBottom / 2);\n\t\tconst cornerTanBottom = Math.tan(cornerAngleTop / 2);\n\t\tconst cornerTanBoth = cornerTanTop + cornerTanBottom;\n\t\tconst cornerQotTop = hollow ? cornerTanBoth : cornerTanBottom;\n\t\tconst cornerQotBottom = hollow ? cornerTanBoth : cornerTanTop;\n\t\tcornerRadiusTop = Math.min(\n\t\t\tcornerRadiusTop,\n\t\t\t(radiusTop - radiusInnerTop) / cornerQotTop,\n\t\t\tdelta.length() / cornerTanBoth\n\t\t);\n\t\tcornerRadiusBottom = Math.min(\n\t\t\tcornerRadiusBottom,\n\t\t\t(radiusBottom - radiusInnerBottom) / cornerQotBottom,\n\t\t\tdelta.length() / cornerTanBoth\n\t\t);\n\n\t\tif (cornerRadiusTop > 0) {\n\t\t\tconst theThing = cornerRadiusTop / cornerTanTop;\n\t\t\tcornerCenterTop = endTop\n\t\t\t\t.clone()\n\t\t\t\t.sub(new Vector2(theThing, cornerRadiusTop));\n\n\t\t\tif (hollow) {\n\t\t\t\tinnerCornerCenterTop = cornerCenterTop.clone();\n\t\t\t\tinnerCornerCenterTop.x -=\n\t\t\t\t\twallThickness - cornerTanBoth * cornerRadiusTop;\n\t\t\t}\n\n\t\t\tendTop.sub(delta.clone().setLength(theThing));\n\t\t}\n\t\tif (cornerRadiusBottom > 0) {\n\t\t\tconst theThing = cornerRadiusBottom / cornerTanBottom;\n\t\t\tcornerCenterBottom = endBottom\n\t\t\t\t.clone()\n\t\t\t\t.sub(new Vector2(theThing, -cornerRadiusBottom));\n\t\t\tendBottom.add(delta.clone().setLength(theThing));\n\n\t\t\tif (hollow) {\n\t\t\t\tinnerCornerCenterBottom = cornerCenterBottom.clone();\n\t\t\t\tinnerCornerCenterBottom.x -=\n\t\t\t\t\twallThickness - cornerTanBoth * cornerRadiusBottom;\n\t\t\t\tinnerEndTop.sub(delta.clone().setLength(theThing));\n\t\t\t}\n\t\t}\n\t\tdelta = endTop.clone().sub(endBottom);\n\t\tconst noTorso = delta.length() < 0.5;\n\n\t\tconst profiles = [];\n\n\t\tfor (let x = 0; x <= radialSegments; x++) {\n\t\t\tconst indexProfile: number[] = [];\n\n\t\t\tconst u = x / radialSegments;\n\n\t\t\tconst theta = u * thetaLength + thetaStart;\n\t\t\tconst top = new Vector2(Math.sin(theta), Math.cos(theta));\n\n\t\t\tif (innerCornerCenterBottom && cornerCenterBottom) {\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleTop,\n\t\t\t\t\tcornerRadiusBottom,\n\t\t\t\t\tinnerCornerCenterBottom,\n\t\t\t\t\t-1,\n\t\t\t\t\ttrue\n\t\t\t\t);\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleBottom,\n\t\t\t\t\tcornerRadiusBottom,\n\t\t\t\t\tcornerCenterBottom,\n\t\t\t\t\t-1,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t} else if (cornerCenterBottom) {\n\t\t\t\tgenerateCap(indexProfile, top, cornerCenterBottom.x, 0, -1);\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleBottom,\n\t\t\t\t\tcornerRadiusBottom,\n\t\t\t\t\tcornerCenterBottom,\n\t\t\t\t\t-1,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t} else if (!openEnded) {\n\t\t\t\tgenerateCap(indexProfile, top, radiusBottom, radiusInnerBottom, -1);\n\t\t\t}\n\n\t\t\tconst norm = flip(delta).normalize();\n\t\t\ttwo2three(norm, top, normal);\n\n\t\t\t// torso segments\n\n\t\t\tif (!noTorso) {\n\t\t\t\tfor (let y = 0; y <= heightSegments; y++) {\n\t\t\t\t\tconst v = y / heightSegments;\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tconst profile = delta.clone().multiplyScalar(v).add(endBottom);\n\t\t\t\t\ttwo2three(profile, top, vertex);\n\t\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push(u, 0.5 + vertex.y / height);\n\n\t\t\t\t\tindexProfile.push(index++);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (innerCornerCenterTop && cornerCenterTop) {\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleTop,\n\t\t\t\t\tcornerRadiusTop,\n\t\t\t\t\tcornerCenterTop,\n\t\t\t\t\t1,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleBottom,\n\t\t\t\t\tcornerRadiusTop,\n\t\t\t\t\tinnerCornerCenterTop,\n\t\t\t\t\t1,\n\t\t\t\t\ttrue\n\t\t\t\t);\n\t\t\t} else if (cornerCenterTop) {\n\t\t\t\tgenerateChamfer(\n\t\t\t\t\tindexProfile,\n\t\t\t\t\tu,\n\t\t\t\t\ttop,\n\t\t\t\t\tcornerAngleTop,\n\t\t\t\t\tcornerRadiusTop,\n\t\t\t\t\tcornerCenterTop,\n\t\t\t\t\t1,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t\t\tgenerateCap(indexProfile, top, cornerCenterTop.x, 0, 1);\n\t\t\t} else if (!openEnded) {\n\t\t\t\tgenerateCap(indexProfile, top, radiusTop, radiusInnerTop, 1);\n\t\t\t}\n\n\t\t\tif (hollow && !noTorso) {\n\t\t\t\t// inner torso segments\n\n\t\t\t\t// const wallThicknessFixed = 2 * wallThickness / cornerTanBoth;\n\t\t\t\t// const innerEndTop = endTop.clone().sub(flip(delta).setLength(wallThicknessFixed));\n\t\t\t\tconst norm = flip(delta).multiplyScalar(-1).normalize();\n\t\t\t\ttwo2three(norm, top, normal);\n\n\t\t\t\tfor (let y = 0; y <= heightSegments; y++) {\n\t\t\t\t\tconst v = y / heightSegments;\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tconst profile = delta.clone().multiplyScalar(-v).add(innerEndTop);\n\t\t\t\t\ttwo2three(profile, top, vertex);\n\t\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t\t// normal\n\n\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t\t// uv\n\n\t\t\t\t\tuvs.push(u, 0.5 + vertex.y / height);\n\n\t\t\t\t\tindexProfile.push(index++);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hollow && !openEnded) indexProfile.push(indexProfile[0]);\n\n\t\t\tprofiles.push(indexProfile);\n\t\t}\n\n\t\tfor (let i = 0; i < profiles.length - 1; i++) {\n\t\t\tfor (let j = 0; j < profiles[0].length - 1; j++) {\n\t\t\t\tif (openEnded && hollow && j == heightSegments) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// we use the index array to access the correct indices\n\n\t\t\t\tconst a = profiles[i][j];\n\t\t\t\tconst b = profiles[i + 1][j];\n\t\t\t\tconst c = profiles[i + 1][j + 1];\n\t\t\t\tconst d = profiles[i][j + 1];\n\n\t\t\t\tconst cx = vertices[c * 3 + 0];\n\t\t\t\tconst cz = vertices[c * 3 + 2];\n\n\t\t\t\t// faces\n\n\t\t\t\tindices.push(a, b, d);\n\t\t\t\tif (cx != 0 || cz != 0) indices.push(b, c, d);\n\n\t\t\t\t// update group counter\n\t\t\t}\n\t\t}\n\n\t\tif (thetaLength < Math.PI * 2) {\n\t\t\t// angle caps\n\n\t\t\tgenerateAngleCap(-1, profiles[0], thetaStart);\n\n\t\t\tgenerateAngleCap(\n\t\t\t\t1,\n\t\t\t\tprofiles[profiles.length - 1],\n\t\t\t\tthetaStart + thetaLength\n\t\t\t);\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t\tfunction generateChamfer(\n\t\t\tindexProfile: number[],\n\t\t\tu: number,\n\t\t\ttop: Vector2,\n\t\t\tstartAngle: number,\n\t\t\tradius: number,\n\t\t\tcenter: Vector2,\n\t\t\tsign: number,\n\t\t\tflip: boolean\n\t\t) {\n\t\t\tfor (let y = 0; y < cornerSegments + 1; y++) {\n\t\t\t\tconst yy = y / cornerSegments;\n\t\t\t\tlet phi = sign < 0 ? yy : 1 - yy;\n\t\t\t\tif (flip) phi -= 1;\n\t\t\t\tphi *= startAngle;\n\n\t\t\t\tconst norm = new Vector2(Math.sin(phi), Math.cos(phi) * sign);\n\n\t\t\t\t// vertex\n\n\t\t\t\tconst profile = norm.clone().multiplyScalar(radius).add(center);\n\n\t\t\t\ttwo2three(profile, top, vertex);\n\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t// normal\n\n\t\t\t\ttwo2three(norm, top, normal);\n\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push(u, 0.5 + vertex.y / height);\n\n\t\t\t\t// increase index\n\n\t\t\t\tindexProfile.push(index++);\n\t\t\t}\n\t\t}\n\n\t\tfunction generateCap(\n\t\t\tindexProfile: number[],\n\t\t\ttop: Vector2,\n\t\t\tradius: number,\n\t\t\tinnerRadius: number,\n\t\t\tsign: number\n\t\t) {\n\t\t\tconst vertex = new Vector3();\n\t\t\tconst profile = new Vector2();\n\t\t\tconst radii = [radius, innerRadius];\n\n\t\t\tif (sign < 0) radii.reverse();\n\n\t\t\tfor (const x of radii) {\n\t\t\t\t// vertex\n\n\t\t\t\tprofile.set(x, halfHeight * sign);\n\t\t\t\ttwo2three(profile, top, vertex);\n\t\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push(0, sign, 0);\n\n\t\t\t\t// uv\n\n\t\t\t\tuvs.push(0.5, 0.5);\n\n\t\t\t\t// increase index\n\n\t\t\t\tindexProfile.push(index++);\n\t\t\t}\n\t\t}\n\n\t\tfunction generateAngleCap(dir: number, profile: number[], theta: number) {\n\t\t\tconst top = new Vector2(Math.sin(theta), Math.cos(theta));\n\t\t\tconst normal = new Vector2(-Math.cos(theta), Math.sin(theta));\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tconst addi =\n\t\t\t\tdir < 0\n\t\t\t\t\t? (a: number, b: number, c: number) => indices.push(a, b, c)\n\t\t\t\t\t: (a: number, b: number, c: number) => indices.push(a, c, b);\n\n\t\t\t// vertex\n\n\t\t\tconst centerProfile = new Vector2(\n\t\t\t\t(radiusTop + radiusBottom + radiusInnerTop + radiusInnerBottom) / 4,\n\t\t\t\t0\n\t\t\t);\n\t\t\ttwo2three(centerProfile, top, vertex);\n\t\t\tvertices.push(vertex.x, vertex.y, vertex.z);\n\n\t\t\t// normal\n\n\t\t\tnormals.push(normal.x, 0, normal.y);\n\n\t\t\t// uv\n\n\t\t\tuvs.push(0.5, 0.5);\n\n\t\t\tconst centerIndex = index++;\n\n\t\t\t// clone all edge points with new normals\n\n\t\t\tfor (const vi of profile) {\n\t\t\t\t// vertex\n\n\t\t\t\tconst verts = vertices.slice(vi * 3, vi * 3 + 3);\n\t\t\t\tvertices.push(...verts);\n\n\t\t\t\t// normal\n\n\t\t\t\tnormals.push(normal.x, 0, normal.y);\n\n\t\t\t\t// uv\n\n\t\t\t\tconst uv = uvs.slice(vi * 2, vi * 2 + 2);\n\t\t\t\tuvs.push(...uv);\n\n\t\t\t\t// increase index\n\n\t\t\t\tindex++;\n\t\t\t}\n\n\t\t\t// build faces\n\n\t\t\tfor (let i = centerIndex + 1; i < index - 1; i++) {\n\t\t\t\taddi(centerIndex, i, i + 1);\n\t\t\t}\n\n\t\t\taddi(centerIndex, index - 1, centerIndex + 1);\n\t\t}\n\t}\n}\n", "/**\n * @author s-ol\n */\n\nimport {\n\tBoxBufferGeometry,\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tVector3,\n} from 'three';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type CubeGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\twidthSegments: number;\n\theightSegments: number;\n\tdepthSegments: number;\n\tcornerRadius: number;\n\tcornerSegments: number;\n};\n\nexport type CubeGeometryInputs = { parameters: CubeGeometryParameters };\n\nexport const CubeGeometry: CGeometry<CubeGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<CubeGeometryInputs>\n\t): IGeometry<CubeGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<CubeGeometryInputs>,\n\t\tbase?: CubeGeometryInputs\n\t): CubeGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\twidthSegments: 1,\n\t\t\t\theightSegments: 1,\n\t\t\t\tdepthSegments: 1,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\tcornerSegments: 8,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: CubeGeometryInputs): IGeometry<CubeGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\twidthSegments,\n\t\t\theightSegments,\n\t\t\tdepthSegments,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments,\n\t\t} = inputs.parameters;\n\n\t\tlet geometry;\n\t\tif (cornerRadius == 0)\n\t\t\tgeometry = new BoxBufferGeometry(\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\theightSegments,\n\t\t\t\tdepthSegments\n\t\t\t);\n\t\telse\n\t\t\tgeometry = new RoundedBoxBufferGeometry(\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\theightSegments,\n\t\t\t\tdepthSegments,\n\t\t\t\tcornerRadius,\n\t\t\t\tcornerSegments\n\t\t\t);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'CubeGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nconst pi2 = Math.PI / 2;\n\nclass RoundedBoxBufferGeometry extends BufferGeometry {\n\tconstructor(\n\t\twidth = 1,\n\t\theight = 1,\n\t\tdepth = 1,\n\t\twidthSegments = 1,\n\t\theightSegments = 1,\n\t\tdepthSegments = 1,\n\t\tcornerRadius = 0,\n\t\tcornerSegments = 4\n\t) {\n\t\tsuper();\n\n\t\tthis.type = 'BoxBufferGeometry';\n\n\t\tconst scope = this;\n\n\t\t// segments\n\n\t\twidthSegments = Math.floor(widthSegments);\n\t\theightSegments = Math.floor(heightSegments);\n\t\tdepthSegments = Math.floor(depthSegments);\n\t\tcornerSegments = Math.floor(cornerSegments);\n\n\t\tcornerRadius = Math.min(cornerRadius, width / 2, height / 2, depth / 2);\n\n\t\t// buffers\n\n\t\tconst indices: number[] = [];\n\t\tconst vertices: number[] = [];\n\t\tconst normals: number[] = [];\n\t\tconst uvs: number[] = [];\n\n\t\t// helper variables\n\n\t\tlet index = 0;\n\t\tlet groupStart = 0;\n\n\t\t// build each side of the box geometry\n\n\t\tbuildPlane(\n\t\t\t'z',\n\t\t\t'y',\n\t\t\t'x',\n\t\t\t-1,\n\t\t\t-1,\n\t\t\tdepth,\n\t\t\theight,\n\t\t\twidth,\n\t\t\tdepthSegments,\n\t\t\theightSegments,\n\t\t\t0\n\t\t); // px\n\t\tbuildPlane(\n\t\t\t'z',\n\t\t\t'y',\n\t\t\t'x',\n\t\t\t1,\n\t\t\t-1,\n\t\t\tdepth,\n\t\t\theight,\n\t\t\t-width,\n\t\t\tdepthSegments,\n\t\t\theightSegments,\n\t\t\t1\n\t\t); // nx\n\t\tbuildPlane(\n\t\t\t'x',\n\t\t\t'z',\n\t\t\t'y',\n\t\t\t1,\n\t\t\t1,\n\t\t\twidth,\n\t\t\tdepth,\n\t\t\theight,\n\t\t\twidthSegments,\n\t\t\tdepthSegments,\n\t\t\t2\n\t\t); // py\n\t\tbuildPlane(\n\t\t\t'x',\n\t\t\t'z',\n\t\t\t'y',\n\t\t\t1,\n\t\t\t-1,\n\t\t\twidth,\n\t\t\tdepth,\n\t\t\t-height,\n\t\t\twidthSegments,\n\t\t\tdepthSegments,\n\t\t\t3\n\t\t); // ny\n\t\tbuildPlane(\n\t\t\t'x',\n\t\t\t'y',\n\t\t\t'z',\n\t\t\t1,\n\t\t\t-1,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\twidthSegments,\n\t\t\theightSegments,\n\t\t\t4\n\t\t); // pz\n\t\tbuildPlane(\n\t\t\t'x',\n\t\t\t'y',\n\t\t\t'z',\n\t\t\t-1,\n\t\t\t-1,\n\t\t\twidth,\n\t\t\theight,\n\t\t\t-depth,\n\t\t\twidthSegments,\n\t\t\theightSegments,\n\t\t\t5\n\t\t); // nz\n\n\t\tif (cornerRadius > 0) {\n\t\t\t// build two edges from each side\n\n\t\t\tbuildEdge(\n\t\t\t\t'z',\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\tdepth,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepthSegments,\n\t\t\t\t0\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'z',\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\tdepth,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepthSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'z',\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\tdepth,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepthSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge('z', 'y', 'x', 1, 1, 1, depth, height, width, depthSegments, 0);\n\t\t\tbuildEdge(\n\t\t\t\t'x',\n\t\t\t\t'y',\n\t\t\t\t'z',\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\t0\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'x',\n\t\t\t\t'y',\n\t\t\t\t'z',\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'x',\n\t\t\t\t'y',\n\t\t\t\t'z',\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\t0\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'x',\n\t\t\t\t'y',\n\t\t\t\t'z',\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\twidthSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t'z',\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepth,\n\t\t\t\theightSegments,\n\t\t\t\t0\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t'z',\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepth,\n\t\t\t\theightSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t'z',\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\t1,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepth,\n\t\t\t\theightSegments,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbuildEdge(\n\t\t\t\t'y',\n\t\t\t\t'x',\n\t\t\t\t'z',\n\t\t\t\t-1,\n\t\t\t\t1,\n\t\t\t\t-1,\n\t\t\t\theight,\n\t\t\t\twidth,\n\t\t\t\tdepth,\n\t\t\t\theightSegments,\n\t\t\t\t0\n\t\t\t);\n\n\t\t\t// build six corners\n\n\t\t\tbuildCorner(1, 1, 1);\n\t\t\tbuildCorner(-1, 1, 1);\n\t\t\tbuildCorner(1, -1, 1);\n\t\t\tbuildCorner(-1, -1, 1);\n\t\t\tbuildCorner(1, 1, -1);\n\t\t\tbuildCorner(-1, 1, -1);\n\t\t\tbuildCorner(1, -1, -1);\n\t\t\tbuildCorner(-1, -1, -1);\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t\tfunction buildPlane(\n\t\t\tu: 'x' | 'y' | 'z',\n\t\t\tv: 'x' | 'y' | 'z',\n\t\t\tw: 'x' | 'y' | 'z',\n\t\t\tudir: number,\n\t\t\tvdir: number,\n\t\t\twidth: number,\n\t\t\theight: number,\n\t\t\tdepth: number,\n\t\t\tgridX: number,\n\t\t\tgridY: number,\n\t\t\tmaterialIndex: number\n\t\t) {\n\t\t\tconst segmentWidth = (width - 2 * cornerRadius) / gridX;\n\t\t\tconst segmentHeight = (height - 2 * cornerRadius) / gridY;\n\n\t\t\tconst widthHalf = width / 2 - cornerRadius;\n\t\t\tconst heightHalf = height / 2 - cornerRadius;\n\t\t\tconst depthHalf = depth / 2;\n\n\t\t\tconst gridX1 = gridX + 1;\n\t\t\tconst gridY1 = gridY + 1;\n\n\t\t\tlet vertexCounter = 0;\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst vector = new Vector3();\n\n\t\t\t// generate vertices, normals and uvs\n\n\t\t\tfor (let iy = 0; iy < gridY1; iy++) {\n\t\t\t\tconst y = iy * segmentHeight - heightHalf;\n\n\t\t\t\tfor (let ix = 0; ix < gridX1; ix++) {\n\t\t\t\t\tconst x = ix * segmentWidth - widthHalf;\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[u] = x * udir;\n\t\t\t\t\tvector[v] = y * vdir;\n\t\t\t\t\tvector[w] = depthHalf;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t\t// set values to correct vector component\n\n\t\t\t\t\tvector[u] = 0;\n\t\t\t\t\tvector[v] = 0;\n\t\t\t\t\tvector[w] = depth > 0 ? 1 : -1;\n\n\t\t\t\t\t// now apply vector to normal buffer\n\n\t\t\t\t\tnormals.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push(ix / gridX);\n\t\t\t\t\tuvs.push(1 - iy / gridY);\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// indices\n\n\t\t\t// 1. you need three indices to draw a single face\n\t\t\t// 2. a single segment consists of two faces\n\t\t\t// 3. so we need to generate six (2*3) indices per segment\n\n\t\t\tfor (let iy = 0; iy < gridY; iy++) {\n\t\t\t\tfor (let ix = 0; ix < gridX; ix++) {\n\t\t\t\t\tconst a = index + ix + gridX1 * iy;\n\t\t\t\t\tconst b = index + ix + gridX1 * (iy + 1);\n\t\t\t\t\tconst c = index + (ix + 1) + gridX1 * (iy + 1);\n\t\t\t\t\tconst d = index + (ix + 1) + gridX1 * iy;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push(a, b, d);\n\t\t\t\t\tindices.push(b, c, d);\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup(groupStart, groupCount, materialIndex);\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tindex += vertexCounter;\n\t\t}\n\n\t\tfunction buildEdge(\n\t\t\tu: 'x' | 'y' | 'z',\n\t\t\tv: 'x' | 'y' | 'z',\n\t\t\tw: 'x' | 'y' | 'z',\n\t\t\tudir: number,\n\t\t\tvdir: number,\n\t\t\twdir: number,\n\t\t\twidth: number,\n\t\t\theight: number,\n\t\t\tdepth: number,\n\t\t\tgridX: number,\n\t\t\tmaterialIndex: number\n\t\t) {\n\t\t\tconst segmentWidth = (width - 2 * cornerRadius) / gridX;\n\n\t\t\tconst widthHalf = width / 2 - cornerRadius;\n\t\t\tconst heightHalf = height / 2 - cornerRadius;\n\t\t\tconst depthHalf = depth / 2;\n\n\t\t\tconst gridX1 = gridX + 1;\n\n\t\t\tlet vertexCounter = 0;\n\t\t\tlet groupCount = 0;\n\n\t\t\tconst vector = new Vector3();\n\t\t\tconst normal = new Vector3();\n\n\t\t\tfor (let ia = 0; ia < cornerSegments + 1; ia++) {\n\t\t\t\tconst a = (ia / cornerSegments) * pi2;\n\n\t\t\t\tconst vd = Math.sin(a) * cornerRadius;\n\t\t\t\tconst wd = (1 - Math.cos(a)) * cornerRadius;\n\n\t\t\t\tconst nv = Math.sin(a);\n\t\t\t\tconst nw = Math.cos(a);\n\n\t\t\t\tvector[v] = (heightHalf + vd) * vdir;\n\t\t\t\tvector[w] = (depthHalf - wd) * wdir;\n\n\t\t\t\tnormal[u] = 0;\n\t\t\t\tnormal[v] = nv * Math.sign(vector[v]);\n\t\t\t\tnormal[w] = nw * Math.sign(vector[w]);\n\n\t\t\t\tfor (let ix = 0; ix < gridX1; ix++) {\n\t\t\t\t\tconst x = ix * segmentWidth - widthHalf;\n\t\t\t\t\tvector[u] = x * udir;\n\n\t\t\t\t\t// now apply vector to vertex buffer\n\n\t\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t\t// now apply normal to normal buffer\n\n\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push(ix / gridX);\n\t\t\t\t\tuvs.push(0);\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tvertexCounter += 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let ia = 0; ia < cornerSegments; ia++) {\n\t\t\t\tfor (let ix = 0; ix < gridX; ix++) {\n\t\t\t\t\tconst a = index + ix + gridX1 * ia;\n\t\t\t\t\tconst b = index + ix + gridX1 * (ia + 1);\n\t\t\t\t\tconst c = index + (ix + 1) + gridX1 * (ia + 1);\n\t\t\t\t\tconst d = index + (ix + 1) + gridX1 * ia;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push(a, b, d);\n\t\t\t\t\tindices.push(b, c, d);\n\n\t\t\t\t\t// increase counter\n\n\t\t\t\t\tgroupCount += 6;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add a group to the geometry. this will ensure multi material support\n\n\t\t\tscope.addGroup(groupStart, groupCount, materialIndex);\n\n\t\t\t// calculate new start value for groups\n\n\t\t\tgroupStart += groupCount;\n\n\t\t\t// update total number of vertices\n\n\t\t\tindex += vertexCounter;\n\t\t}\n\n\t\tfunction buildCorner(udir: number, vdir: number, wdir: number) {\n\t\t\tconst delta = new Vector3();\n\t\t\tconst center = new Vector3(width / 2, height / 2, depth / 2);\n\t\t\tcenter.subScalar(cornerRadius);\n\n\t\t\tconst rows = [];\n\n\t\t\tconst addface =\n\t\t\t\tudir * vdir * wdir > 0\n\t\t\t\t\t? (a: number, b: number, c: number) => indices.push(a, b, c)\n\t\t\t\t\t: (a: number, b: number, c: number) => indices.push(a, c, b);\n\n\t\t\tfor (let segments = 0; segments <= cornerSegments; segments++) {\n\t\t\t\tconst row = [];\n\n\t\t\t\tconst anglePitch = pi2 * (1 - segments / cornerSegments);\n\t\t\t\tconst cosPitch = Math.cos(anglePitch);\n\t\t\t\tconst sinPitch = Math.sin(anglePitch);\n\n\t\t\t\tlet angleYaw = 0;\n\n\t\t\t\tfor (let j = 0; j <= segments; j++) {\n\t\t\t\t\tconst cosYaw = Math.cos(angleYaw);\n\t\t\t\t\tconst sinYaw = Math.sin(angleYaw);\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tdelta.x = cosPitch * cosYaw;\n\t\t\t\t\tdelta.y = sinPitch;\n\t\t\t\t\tdelta.z = cosPitch * sinYaw;\n\n\t\t\t\t\tconst vector = center.clone().addScaledVector(delta, cornerRadius);\n\t\t\t\t\tvertices.push(udir * vector.x, vdir * vector.y, wdir * vector.z);\n\n\t\t\t\t\t// normals\n\n\t\t\t\t\tnormals.push(udir * delta.x, vdir * delta.y, wdir * delta.z);\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t\t// index\n\n\t\t\t\t\trow.push(index++);\n\n\t\t\t\t\tangleYaw += pi2 / segments;\n\t\t\t\t}\n\n\t\t\t\trows.push(row);\n\t\t\t}\n\n\t\t\tconst R = rows.length - 1;\n\n\t\t\tfor (let r = 0; r < R; r++) {\n\t\t\t\t// rows: cur/next\n\t\t\t\tconst rC = rows[r];\n\t\t\t\tconst rN = rows[r + 1];\n\n\t\t\t\tconst I = rC.length - 1;\n\n\t\t\t\t// first tri\n\t\t\t\taddface(rC[0], rN[1], rN[0]);\n\n\t\t\t\tfor (let i = 1; i <= I; i++) {\n\t\t\t\t\t// tri to previous\n\t\t\t\t\taddface(rC[i - 1], rC[i], rN[i]);\n\n\t\t\t\t\t// tri to next\n\t\t\t\t\taddface(rC[i], rN[i + 1], rN[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "/* eslint-disable eqeqeq */\n\nimport {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tTriangle,\n\tVector3,\n\tVector2,\n} from 'three';\n\n//import { IcosahedronBufferGeometry } from 'three';\n//import { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nclass PolyhedronRoundGeometry extends BufferGeometry {\n\tconstructor(\n\t\tvertices: number[] = [],\n\t\tindices: number[] = [],\n\t\ttype: string = '',\n\t\tradius = 1,\n\t\t//detail = 1,\n\t\t//\n\t\tcorner = 0.2,\n\t\tcornerSides = 4\n\t) {\n\t\tsuper();\n\n\t\tthis.type = 'PolyhedronGeometryRound';\n\n\t\t// this.parameters = {\n\t\t// \tvertices: vertices,\n\t\t// \tindices: indices,\n\t\t// \tradius: radius,\n\t\t// \tdetail: detail,\n\t\t// \tcorner: corner,\n\t\t// \tcornerSides: cornerSides\n\t\t// };\n\n\t\t// default buffer data\n\t\tconst vertexBuffer: number[] = [];\n\t\tconst uvBuffer: number[] = [];\n\n\t\t//\n\t\tconst normalBuffer: number[] = [];\n\t\t//\n\n\t\t//----------------------------\n\t\t// original disabled function calls from PolyhedronGeometry()\n\t\t//\n\t\t// subdivide( detail );\n\t\t// applyRadius( radius );\n\t\t//----------------------------\n\t\t//\n\t\tgenRoundCorners();\n\t\t//\n\t\t//----------------------------\n\n\t\tgenerateUVs();\n\n\t\t// build non-indexed geometry\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normalBuffer, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2));\n\n\t\treturn;\n\n\t\t//======================\n\t\t// fills vertexBuffer with all icosahedron's triangles (since this geometry is Not indexed)\n\t\t//\n\t\t// obs. this code is fairly- (not super-) optimized due to being parameterized for ease of adaptation to\n\t\t// other solids (beyond the currently supported ones: platonic solids)\n\t\t//======================\n\t\t//\n\t\tfunction genRoundCorners() {\n\t\t\t//-------------------------------------------\n\t\t\t// limits for input values\n\t\t\t//-------------------------------------------\n\t\t\tcorner = Math.min(1 - 1e-5, corner);\n\n\t\t\tif (corner == 0) cornerSides = 0; // reduce triangle count\n\t\t\t//-------------------------------------------\n\n\t\t\tconst arrEdgesPerCorner: { [key: string]: number } = {\n\t\t\t\tIcosahedronGeometry: 5,\n\t\t\t\tDodecahedronGeometry: 3,\n\t\t\t\tHexahedronGeometry: 3, // BoxGeometry, BoxBufferGeometry\n\t\t\t\tOctahedronGeometry: 4,\n\t\t\t\tTetrahedronGeometry: 3,\n\t\t\t};\n\n\t\t\tconst edgesPerCorner = arrEdgesPerCorner[type];\n\n\t\t\tconst vec = new Vector3(),\n\t\t\t\tvec2 = vec.clone(); // auxiliary vectors\n\t\t\tconst tri = new Triangle();\n\t\t\tconst cornerPercentOfRadius = corner * radius;\n\t\t\tconst cornCenterLen = radius - cornerPercentOfRadius;\n\t\t\tconst cornerSidesP1 = cornerSides + 1;\n\t\t\t//\n\t\t\tconst normal = new Vector3();\n\t\t\tconst makeNormal = (surfaceVec: Vector3, centerVec: Vector3) =>\n\t\t\t\tnormal.subVectors(surfaceVec, centerVec).normalize();\n\n\t\t\t//\n\t\t\ttype typeMapFunc = (size: number, mapFunc: (...x: any) => any) => any;\n\t\t\tconst newArray: typeMapFunc = (size, mapFunc) =>\n\t\t\t\tArray(size).fill(undefined).map(mapFunc);\n\n\t\t\t// make all vertices expand to the proper radius.\n\t\t\tconst vertices2 = newArray(vertices.length / 3, (_, ind) =>\n\t\t\t\tnew Vector3().fromArray(vertices, ind * 3).setLength(radius)\n\t\t\t);\n\n\t\t\t// group triangles by normals (ie. group triangles in the same face. the search will be limited to faces around each corner)\n\t\t\t//-------------------------------------------------------------------------------------\n\t\t\t//\n\t\t\t// obs: this code is in preparation to substitute the code below (using edge length to detect connecting corners)\n\t\t\t// this will be enabled as soon as triangulation for corners is rewritten ( fixing wide triangles facing wrong directions )\n\t\t\t//{\n\t\t\t// const equalsEpsi = (v0, v1, epsilon = 1e-10) =>\n\t\t\t// \t( Math.abs( v0.x - v1.x ) < epsilon ) && ( Math.abs( v0.y - v1.y ) < epsilon ) && ( Math.abs( v0.z - v1.z ) < epsilon );\n\t\t\t// const mapNormal = [];\n\t\t\t// let pair, normal;\n\n\t\t\t// for( let indIndices = 0; indIndices < indices.length; indIndices += 3 ) // indIndice -> index of an array called \"indices\" (sorry, that's Three's naming convention for the class 'PolyhedronGeometry')\n\t\t\t// {\n\t\t\t// \tnormal = tri.setFromPointsAndIndices( vertices2, ...indices.slice( indIndices, indIndices + 3 )).getNormal();\n\t\t\t// \tpair = mapNormal.find( pair => equalsEpsi( pair[0], normal ));\n\n\t\t\t// \tif( !pair )\n\t\t\t// \t{\n\t\t\t// \t\tpair = [ normal, [] ];\n\t\t\t// \t\tmapNormal.push( pair );\n\t\t\t// \t}\n\n\t\t\t// \tpair[ 1 ].push( indIndices / 3 );\n\t\t\t// }\n\n\t\t\t// let faceGroup = mapNormal.map( x => x[1] );\n\n\t\t\t// console.log( faceGroup );\n\t\t\t//}\n\t\t\t//-------------------------------------------------------------------------------------\n\n\t\t\t// Build 'adjacentCorners'. Each sub-array is a set of all surrounding vertices.\n\t\t\t//--------------------------------------------------------------------------------\n\t\t\tconst adjacentCorners: number[][] = [];\n\t\t\tconst adjacentMask = 1e6; // this number must be greater than the biggest number inside 'indices'\n\t\t\t//\n\t\t\tfor (let cornInd = 0; cornInd < vertices2.length; cornInd++) {\n\t\t\t\t// step 1 - collect pairs - each pair is sorted in the same order as its triangle's winding direction.\n\t\t\t\t// The 'while' loop below scans all faces having the same 'cornInd' vertex (corner).\n\t\t\t\t// -if faces are single triangles, each corner will have the same number of faces\n\t\t\t\t// -if they're not triangles, each face could have one or more triangles that are directly connected to the corner.\n\t\t\t\tconst vertCorner = vertices2[cornInd];\n\t\t\t\tconst cornersAux = [];\n\t\t\t\tlet first: number, next: number, distFirst: number;\n\t\t\t\tlet minEdgeLenSq = 1e10;\n\t\t\t\tlet indSearch = -1;\n\t\t\t\twhile ((indSearch = indices.indexOf(cornInd, indSearch + 1)) != -1) {\n\t\t\t\t\t// that's really an assignment \"=\" instead of comparison \"==\".\n\t\t\t\t\tconst firstElemTriplet = indSearch - (indSearch % 3);\n\n\t\t\t\t\tfirst = indices[firstElemTriplet + ((indSearch + 1) % 3)];\n\t\t\t\t\tnext = indices[firstElemTriplet + ((indSearch + 2) % 3)];\n\t\t\t\t\tdistFirst = vertCorner.distanceToSquared(vertices2[first]);\n\n\t\t\t\t\tminEdgeLenSq = Math.min(minEdgeLenSq, distFirst);\n\n\t\t\t\t\tcornersAux.push([first, next, distFirst]);\n\t\t\t\t}\n\n\t\t\t\t// step 2 - sort by adjacent pairs. a negative number means that link already exists in some previous sub-array.\n\t\t\t\tminEdgeLenSq += 1e-6; // add a small amount to compensate for decimal imprecisions.\n\t\t\t\tconst cornersFinal: number[] = [];\n\t\t\t\tlet ind = 0;\n\t\t\t\tconst numTris = cornersAux.length;\n\t\t\t\tfor (let i = 0; i < numTris; i++) {\n\t\t\t\t\t[first, next, distFirst] = cornersAux[ind];\n\n\t\t\t\t\tconst duplicate: boolean =\n\t\t\t\t\t\tadjacentCorners[first]?.includes(cornInd) == true; // \"==true\" filters out \"undefined\"\n\n\t\t\t\t\tif (distFirst <= minEdgeLenSq)\n\t\t\t\t\t\tcornersFinal.push(first + +duplicate * adjacentMask);\n\n\t\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t\tind = cornersAux.findIndex((arr) => arr[0] == next);\n\t\t\t\t}\n\n\t\t\t\tadjacentCorners.push(cornersFinal);\n\t\t\t}\n\n\t\t\t//{\n\t\t\t// ----------- THIS ARRAY IS NO LONGER USED ---- (kept here for ref.)\n\t\t\t// // // const indicesFacesPerCorner = [\n\t\t\t// ----------- THIS ARRAY IS NO LONGER USED ---- (kept here for ref.)\n\t\t\t// // //\t0: [0, 1, 2, 3, 4] 6: [8, 18, 13, 12, 17]\n\t\t\t// // //\t1: [1, 5, 19, 9, 2] 7: [2, 9, 18, 8, 3]\n\t\t\t// // //\t2: [7, 17, 12, 11, 16] 8: [9, 19, 14, 13, 18]\n\t\t\t// // //\t3: [10, 11, 12, 13, 14] 9: [5, 15, 10, 14, 19]\n\t\t\t// // //\t4: [6, 16, 11, 10, 15] 10: [3, 8, 17, 7, 4]\n\t\t\t// // //\t5: [0, 6, 15, 5, 1] 11: [0, 4, 7, 16, 6]\n\t\t\t// // // ]\n\n\t\t\t// adjacentCorners [ // (icosa) // (dodeca)\n\t\t\t// 0: [11, 5, 1, 7, 10] 6: [10, 7, 8, -3, -2] // 0 [16, 8, 12] 6 [17, 10, 15] 13 [-3, 15, -2]\n\t\t\t// 1: [-0, 5, 9, 8, 7] 7: [-0, -1, 8, -6, 10] // 1 [12, 9, 18] 7 [11, 19, 15] 14 [-12, -4, -5]\n\t\t\t// 2: [11, 10, 6, 3, 4] 8: [-7, -1, 9, -3, -6] // 2 [16, 13, 10] 8 [-4, -0, 10] 15 [-7, -6, -13]\n\t\t\t// 3: [9, 4, -2, 6, 8] 9: [-1, -5, -4, -3, -8] // 3 [11, 13, 18] 9 [-1, -5, 11] 16 [-0, 18, -2]\n\t\t\t// 4: [5, 11, -2, -3, 9] 10: [-0, -7, -6, -2, 11] // 4 [8, 17, 14] 10 [-8, -2, -6] 17 [19, -4, -6]\n\t\t\t// 5: [-0, 11, -4, 9, -1] 11: [-5, -0, -10, -2, -4] // 5 [9, 14, 19] 11 [-7, -3, -9] 18 [-1, -3, -16]\n\t\t\t// ]; 12 [-1, -0, 14] 19 [-17, -7, -5]\n\n\t\t\t// const indices = [ // icosahedron (the 'virtual' numbers in parenthesis were just used by the deprec. array 'indicesFacesPerCorner')\n\t\t\t// \t ( 0) 0, 11, 5,\t( 1) 0, 5, 1, \t(2) 0, 1, 7, \t( 3) 0, 7, 10, \t( 4) 0, 10, 11,\n\t\t\t// \t ( 5) 1, 5, 9, \t( 6) 5, 11, 4,\t(7) 11, 10, 2,\t( 8) 10, 7, 6,\t( 9) 7, 1, 8,\n\t\t\t// \t (10) 3, 9, 4, \t(11) 3, 4, 2,\t(12) 3, 2, 6,\t(13) 3, 6, 8,\t(14) 3, 8, 9,\n\t\t\t// \t (15) 4, 9, 5, \t(16) 2, 4, 11,\t(17) 6, 2, 10,\t(18) 8, 6, 7,\t(19) 9, 8, 1\n\t\t\t// ];\n\t\t\t// const indices = [ // dodecahedron -- HUGE implications between icosa & dodeca is: 1-icosa has only One triangle per face. 2-Given a Dodeca's vertex, and all of its directly connected faces, the # of tris per face varies (from face to face) from 1 to 3.\n\t\t\t// \t3, 11, 7, \t3, 7, 15, \t3, 15, 13, // 0 1 2\n\t\t\t// \t7, 19, 17, \t7, 17, 6, \t7, 6, 15, // 3 4 5\n\t\t\t// \t17, 4, 8, \t17, 8, 10, \t17, 10, 6, // 6 7 8\n\t\t\t// \t8, 0, 16, \t8, 16, 2, \t8, 2, 10, // 9 10 11\n\t\t\t// \t0, 12, 1, \t0, 1, 18, \t0, 18, 16, // 12 13 14\n\t\t\t// \t6, 10, 2, \t6, 2, 13, \t6, 13, 15, // 15 16 17\n\t\t\t// \t2, 16, 18, \t2, 18, 3, \t2, 3, 13, // 18 19 20\n\t\t\t// \t18, 1, 9, \t18, 9, 11, \t18, 11, 3, // 21 22 23\n\t\t\t// \t4, 14, 12, \t4, 12, 0, \t4, 0, 8, // 24 25 26\n\t\t\t// \t11, 9, 5, \t11, 5, 19, \t11, 19, 7, // 27 28 29\n\t\t\t// \t19, 5, 14, \t19, 14, 4, \t19, 4, 17, // 30 31 32\n\t\t\t// \t1, 12, 14, \t1, 14, 5, \t1, 5, 9 // 33 34 35\n\t\t\t// ];\n\n\t\t\t//borderOfCorners = [\n\t\t\t// face 0 face 1 face 2 face 3 face 4\n\t\t\t//\n\t\t\t//[ [v1,2,3... cornerSides], ... [v1,2...], [v1,2...] ] // vert 0\n\t\t\t//[ [v1,2...], [v1,2...], [v1,2...], [v1,2...], [v1,2...] ] // vert 1\n\t\t\t//[ [v1,2...], [v1,2...], [v1,2...], [v1,2...], [v1,2...] ] // vert 2\n\t\t\t//..\n\t\t\t//[ [v1,2...], [v1,2...], [v1,2...], [v1,2...], [v1,2...] ] // vert 11\n\t\t\t//]\n\t\t\t//}\n\n\t\t\t// build array of pre-computed indices for 'quads' (two tris) used by 'vertsPerEdge'.\n\t\t\tconst indTris = [];\n\t\t\t{\n\t\t\t\t// each face (triangle-shaped) around the current corner 'cornInd' is made up of the vertices\n\t\t\t\t// arranged the following order inside 'vertsPerEdge':\n\t\t\t\t//\n\t\t\t\t// corner side level vertices per level (including all vertices above the corresponding level as well).\n\t\t\t\t// - 0 <- topmost vertex is the same for all faces. It's the current corner.\n\t\t\t\t// 0 1 2 numbers grow one unit to the right and one to the bottom for each\n\t\t\t\t// 1 3 4 5 corner side level.\n\t\t\t\t// 2 6 7 8 9\n\t\t\t\t// ... ...\n\t\t\t\t// the code below creates the quad above 0,1,4,2 divided into two tris: 0,1,4 & 0,4,2 (or 0,1,2 & 2,1,4 if 'invert' is true (*))\n\t\t\t\t// and then the other quads (2,4,8,5 & 1,3,7,4) and the remaining single tris (5,8,9 & 4,7,8 & 3,6,7)\n\t\t\t\t// (*) 'invert' indicates if a quad is split horizontally or vertically (to avoid concave faces).\n\n\t\t\t\tlet x = 0,\n\t\t\t\t\ty = 0,\n\t\t\t\t\tlx,\n\t\t\t\t\tly;\n\n\t\t\t\tlet invert = edgesPerCorner == 3;\n\t\t\t\tfor (let row = 0; row <= cornerSides; row++) {\n\t\t\t\t\tlx = (row * (row + 1)) / 2; // summation formula\n\t\t\t\t\tly = ((row + 1) * (row + 2)) / 2;\n\t\t\t\t\tfor (let col = 0; col < cornerSides - row; col++) {\n\t\t\t\t\t\t[x, y] = [lx + col + row + 2, ly + col + row + 3];\n\t\t\t\t\t\tindTris.push(lx, ly, ...(invert ? [y, lx] : [x, ly]), y, x);\n\t\t\t\t\t\t[lx, ly] = [x, y];\n\t\t\t\t\t}\n\t\t\t\t\tindTris.push(lx, ly, lx + cornerSides + 2);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst cornCenter = vec.clone();\n\t\t\tconst cornTop = vec.clone();\n\t\t\tconst axisRot = vec.clone();\n\t\t\t//\n\t\t\tlet vecStart = vec.clone();\n\t\t\tlet vecEnd = vec.clone();\n\t\t\t//\n\t\t\tconst borderOfCorners = [];\n\t\t\t// OBS: 'borderOfCorners' keeps 'tangPoints' values through its references 'thisTang' and 'nextTang.\n\t\t\t// References are needed instead of values for doing comparisons in the part that generates faces,\n\t\t\t// that's why we need to keep elements for all corners (not just one).\n\t\t\tconst tangPoints = newArray(vertices2.length, () =>\n\t\t\t\tnewArray(edgesPerCorner, () => vec.clone())\n\t\t\t);\n\n\t\t\t// creates vertices for each corner on the polyhedron\n\t\t\t//\n\t\t\tfor (let cornInd = 0; cornInd < vertices2.length; cornInd++) {\n\t\t\t\tvec.copy(vertices2[cornInd]).normalize();\n\t\t\t\tcornCenter.copy(vec).multiplyScalar(cornCenterLen);\n\n\t\t\t\tlet corners = adjacentCorners[cornInd];\n\n\t\t\t\t// find all points that are on the corner's sphere tangent to its adjacent faces.\n\t\t\t\tfor (\n\t\t\t\t\tlet face = 0;\n\t\t\t\t\tface < corners.length;\n\t\t\t\t\tface++ // for regular solids, corners.length == edgesPerCorner\n\t\t\t\t) {\n\t\t\t\t\tconst c1 = corners[face];\n\t\t\t\t\tconst c2 = corners[(face + 1) % edgesPerCorner];\n\n\t\t\t\t\ttri.setFromPointsAndIndices(\n\t\t\t\t\t\tvertices2,\n\t\t\t\t\t\tcornInd,\n\t\t\t\t\t\tc1 % adjacentMask,\n\t\t\t\t\t\tc2 % adjacentMask\n\t\t\t\t\t);\n\n\t\t\t\t\t//------------------------------------------------------------------\n\t\t\t\t\t// extend triangle area, so it won't be a limiting factor in case there are more than 1 triangle per face.\n\t\t\t\t\t//\n\t\t\t\t\t// **Note:** this code will be replaced once triangles are grouped by face.\n\t\t\t\t\t//\n\t\t\t\t\t//------------------------------------------------------------------\n\t\t\t\t\ttri.b.sub(tri.a).setLength(1e10).add(tri.a); // 1e10 or any big number (it's temporary)\n\t\t\t\t\ttri.c.sub(tri.a).setLength(1e10).add(tri.a);\n\t\t\t\t\t//------------------------------------------------------------------\n\n\t\t\t\t\t// TODO: substitute 'closestPointToPoint()' by another simpler calculation (this is too expensive)\n\t\t\t\t\t// (possible candidates: Vector3.projectOnPlane / .projectOnVector)\n\t\t\t\t\ttri.closestPointToPoint(cornCenter, tangPoints[cornInd][face]);\n\t\t\t\t}\n\n\t\t\t\t// calculate \"Base Vertices\"\n\t\t\t\t// ----------------------------------------\n\t\t\t\t// segment each of the vertical edges from the same top corner to the tangent of each face, and the vertical edges\n\t\t\t\t// connecting those tangent points.\n\t\t\t\t//\n\t\t\t\t// TODO: !!!! When there's just 3 edges per corner ('E'=3), then modify the code below:\n\t\t\t\t// - instead of following the rule of dividing each corner into 'E' big triangles (with the corner's center as the common\n\t\t\t\t// vertex, and segment each tri according to cornerSides) do not divide, and use one of the big triangles for the whole corner :)\n\t\t\t\t//\n\t\t\t\tconst verticesGrid = [];\n\t\t\t\tconst cornRadiusEdges = [];\n\t\t\t\tconst borderCurrentCorner = [];\n\n\t\t\t\t// find the 'flat' center of the corner (barycenter) if cornerSides == 0.\n\t\t\t\tconst flatCorner = new Vector3();\n\t\t\t\tif (cornerSides == 0)\n\t\t\t\t\t[...tangPoints[cornInd]]\n\t\t\t\t\t\t.reduce((prev, curr) => prev.add(curr), flatCorner)\n\t\t\t\t\t\t.multiplyScalar(1 / edgesPerCorner);\n\n\t\t\t\tfor (let edgeInd = 0; edgeInd < edgesPerCorner; edgeInd++) {\n\t\t\t\t\tconst borderCornerSegment = [];\n\n\t\t\t\t\tconst prevEdgeInd = (edgeInd - 1 + edgesPerCorner) % edgesPerCorner;\n\t\t\t\t\t//\n\t\t\t\t\tconst tangPrev = tangPoints[cornInd][prevEdgeInd];\n\t\t\t\t\tconst tangCurr = tangPoints[cornInd][edgeInd];\n\n\t\t\t\t\t// ---------------------------------------\n\t\t\t\t\t// if all faces form the same angle with each corner sphere's axis (ie. platonic solid), this block could be moved up out of this loop.\n\t\t\t\t\tvec.copy(tangPrev).sub(cornCenter);\n\t\t\t\t\tvec2.copy(tangCurr).sub(cornCenter);\n\t\t\t\t\tconst angTangVert = cornCenter.angleTo(vec);\n\t\t\t\t\tconst angTangHoriz = vec.angleTo(vec2);\n\t\t\t\t\t//\n\t\t\t\t\tconst cornRadius = Math.cos(angTangVert) * cornerPercentOfRadius;\n\t\t\t\t\t//\n\t\t\t\t\tif (cornerSides == 0) cornTop.copy(flatCorner);\n\t\t\t\t\telse cornTop.copy(cornCenter).setLength(cornCenterLen + cornRadius);\n\t\t\t\t\t//\n\t\t\t\t\t//\n\t\t\t\t\tcornRadiusEdges.push(cornRadius);\n\t\t\t\t\t// ---------------------------------------\n\n\t\t\t\t\tconst consecEdges = [cornTop, tangPrev, tangCurr];\n\n\t\t\t\t\tfor (\n\t\t\t\t\t\tlet edge = 0;\n\t\t\t\t\t\tedge < 2;\n\t\t\t\t\t\tedge++ // horiz or vert edge\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst thisTang = consecEdges[edge];\n\t\t\t\t\t\tconst nextTang = consecEdges[edge + 1];\n\n\t\t\t\t\t\t// Slerp using vectors (instead of quaternions)\n\t\t\t\t\t\t//--------------------------------------------------------\n\t\t\t\t\t\t// 1 - find the axis of rotation (crossVectors()), 2- apply the rotation on this axis (applyAxisAnge())\n\t\t\t\t\t\tvecStart.subVectors(thisTang, cornCenter);\n\t\t\t\t\t\tvecEnd.subVectors(nextTang, cornCenter);\n\t\t\t\t\t\taxisRot.crossVectors(vecStart, vecEnd).normalize();\n\n\t\t\t\t\t\tfor (let c = 0; c < cornerSidesP1; c++) {\n\t\t\t\t\t\t\tconst angInterp =\n\t\t\t\t\t\t\t\t([angTangVert, angTangHoriz][edge] * c) / cornerSidesP1;\n\n\t\t\t\t\t\t\tvec\n\t\t\t\t\t\t\t\t.copy(vecStart)\n\t\t\t\t\t\t\t\t.applyAxisAngle(axisRot, angInterp)\n\t\t\t\t\t\t\t\t.add(cornCenter);\n\n\t\t\t\t\t\t\tverticesGrid.push(vec.clone());\n\n\t\t\t\t\t\t\tif (edge) {\n\t\t\t\t\t\t\t\tmakeNormal(vec, cornCenter);\n\t\t\t\t\t\t\t\tborderCornerSegment.push([\n\t\t\t\t\t\t\t\t\tc == 0 ? thisTang : vec.clone(),\n\t\t\t\t\t\t\t\t\tnormal.clone(),\n\t\t\t\t\t\t\t\t]); // just consider the horizontal segments\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (edge) {\n\t\t\t\t\t\t\tmakeNormal(nextTang, cornCenter);\n\t\t\t\t\t\t\tborderCornerSegment.push([nextTang, normal.clone()]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tborderCurrentCorner.push(borderCornerSegment);\n\t\t\t\t}\n\n\t\t\t\t//--------------------------------------------\n\t\t\t\tborderOfCorners.push(borderCurrentCorner);\n\t\t\t\t//--------------------------------------------\n\n\t\t\t\t// generate a grid of vertices inside the pentagram.\n\t\t\t\t// unlike the method above, using Slerp, this one uses lerp, then projects it onto the sphere's surface (faster than Slerping)\n\t\t\t\tconst baseVerticesPerFace = 2 * cornerSidesP1; // the number of vertices generated in the loop above\n\t\t\t\tconst minDetail = 2;\n\n\t\t\t\tfor (let edgeInd = 0; edgeInd < edgesPerCorner; edgeInd++) {\n\t\t\t\t\tconst currEdgeInd = baseVerticesPerFace * edgeInd;\n\t\t\t\t\tconst nextEdgeInd =\n\t\t\t\t\t\tbaseVerticesPerFace * ((edgeInd + 1) % edgesPerCorner);\n\n\t\t\t\t\t// initialize the array with this sphere's top center index (currEdgeInd) which is the same for all edges.\n\t\t\t\t\tconst vertsPerEdge = [verticesGrid[currEdgeInd]];\n\n\t\t\t\t\tfor (\n\t\t\t\t\t\tlet c = 1;\n\t\t\t\t\t\tc < cornerSidesP1;\n\t\t\t\t\t\tc++ // iterate over theta (top to bottom)\n\t\t\t\t\t) {\n\t\t\t\t\t\tvecStart = verticesGrid[currEdgeInd + c];\n\t\t\t\t\t\tvecEnd = verticesGrid[nextEdgeInd + c];\n\n\t\t\t\t\t\tvertsPerEdge.push(vecStart);\n\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\tlet v = 1, maxv = c - minDetail + 1;\n\t\t\t\t\t\t\tv <= maxv;\n\t\t\t\t\t\t\tv++ // iterate over phi (left to right)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// -- Two \"pseudo-Slerp\" steps: (vertices not uniformly distributed: they're more concentrated the farthest from the top center)\n\t\t\t\t\t\t\tvec.lerpVectors(vecStart, vecEnd, v / (maxv + 1)); // 1: lerp\n\t\t\t\t\t\t\tvec\n\t\t\t\t\t\t\t\t.sub(cornCenter)\n\t\t\t\t\t\t\t\t.setLength(cornRadiusEdges[edgeInd])\n\t\t\t\t\t\t\t\t.add(cornCenter); // 2: project it onto sphere\n\n\t\t\t\t\t\t\tvertsPerEdge.push(vec.clone());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvertsPerEdge.push(vecEnd);\n\t\t\t\t\t}\n\n\t\t\t\t\t// add last row of indexes (already Slerp'd in the \"Base Vertices\" loop)\n\t\t\t\t\tfor (let c = 0; c < cornerSidesP1; c++) {\n\t\t\t\t\t\tvertsPerEdge.push(verticesGrid[c + cornerSidesP1 + currEdgeInd]);\n\t\t\t\t\t}\n\n\t\t\t\t\t// add the last row's last element\n\t\t\t\t\tvertsPerEdge.push(verticesGrid[nextEdgeInd + cornerSidesP1]);\n\n\t\t\t\t\t// generate triangles for each corner (based on indices in indTris).\n\t\t\t\t\tconst verts = indTris.map((ind) => vertsPerEdge[ind]);\n\t\t\t\t\t//\n\t\t\t\t\tvertexBuffer.push(...verts.map((v) => [v.x, v.y, v.z]).flat());\n\t\t\t\t\tnormalBuffer.push(\n\t\t\t\t\t\t...verts\n\t\t\t\t\t\t\t.map((v) => {\n\t\t\t\t\t\t\t\tmakeNormal(v, cornCenter);\n\t\t\t\t\t\t\t\treturn [normal.x, normal.y, normal.z];\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.flat()\n\t\t\t\t\t);\n\t\t\t\t} // end of face loop\n\t\t\t} // end of vertices2 (vertices2.length) loop\n\n\t\t\t// generate triangles for rectangles (segments) connecting corners. Also, builds a list for triangle faces.\n\t\t\tconst triFaces: Vector3[] = [];\n\t\t\tfor (let indCorn = 0; indCorn < adjacentCorners.length; indCorn++) {\n\t\t\t\tfor (let edgeInd = 0; edgeInd < edgesPerCorner; edgeInd++) {\n\t\t\t\t\tconst indCornCorresp = adjacentCorners[indCorn][edgeInd];\n\n\t\t\t\t\tif (indCornCorresp < adjacentMask) {\n\t\t\t\t\t\tconst edgeIndCorresp = adjacentCorners[indCornCorresp].findIndex(\n\t\t\t\t\t\t\t(ind) => ind % adjacentMask == indCorn\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tconst vertsCurrEdge = borderOfCorners[indCorn][edgeInd];\n\t\t\t\t\t\tconst vertsCorrespEdge =\n\t\t\t\t\t\t\tborderOfCorners[indCornCorresp][edgeIndCorresp];\n\n\t\t\t\t\t\tfor (let i = 0; i < cornerSidesP1; i++) {\n\t\t\t\t\t\t\tconst vert1 = vertsCurrEdge[i];\n\t\t\t\t\t\t\tconst vert2 = vertsCorrespEdge[cornerSidesP1 - i]; // turn CCW to CW in order to match verts.\n\t\t\t\t\t\t\tconst nextVert1 = vertsCurrEdge[i + 1];\n\t\t\t\t\t\t\tconst nextVert2 = vertsCorrespEdge[cornerSidesP1 - (i + 1)];\n\n\t\t\t\t\t\t\t[vert1, vert2, nextVert1, nextVert1, vert2, nextVert2].forEach(\n\t\t\t\t\t\t\t\t(v) => {\n\t\t\t\t\t\t\t\t\tvertexBuffer.push(v[0].x, v[0].y, v[0].z);\n\t\t\t\t\t\t\t\t\tnormalBuffer.push(v[1].x, v[1].y, v[1].z);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// add vertices from the two 'outer' edges connecting every pair of closest corners to 'triFaces'\n\t\t\t\t\t\ttriFaces.push(\n\t\t\t\t\t\t\tvertsCurrEdge[0][0],\n\t\t\t\t\t\t\tvertsCorrespEdge[cornerSidesP1][0],\n\t\t\t\t\t\t\tvertsCurrEdge[cornerSidesP1][0],\n\t\t\t\t\t\t\tvertsCorrespEdge[0][0]\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// generate triangles for each face (based on the list generated in the previous step)\n\t\t\twhile (triFaces.length) {\n\t\t\t\tlet first: Vector3, next, indNext, odd;\n\n\t\t\t\t[first, next] = triFaces.splice(0, 2);\n\n\t\t\t\tconst faceVert = [first];\n\n\t\t\t\twhile (first != next) {\n\t\t\t\t\tfaceVert.push(next);\n\n\t\t\t\t\tindNext = triFaces.indexOf(next); // IMPORTANT: 'indexOf()' is comparing *references* (not values) to vertices that are ultimately stored in 'tangPoints'.\n\t\t\t\t\todd = indNext % 2;\n\t\t\t\t\tnext = triFaces.splice(indNext - odd, 2)[1 - odd]; // this is based on pairs of vertices from adjacent corners\n\t\t\t\t}\n\n\t\t\t\tnormal\n\t\t\t\t\t.subVectors(faceVert[0], faceVert[1])\n\t\t\t\t\t.cross(vec.subVectors(faceVert[0], faceVert[2]))\n\t\t\t\t\t.normalize();\n\n\t\t\t\tconst facingInwards = normal.dot(faceVert[0]) < 0;\n\n\t\t\t\tif (facingInwards) normal.negate();\n\n\t\t\t\tfor (let i = 1; i <= faceVert.length - 2; i++) {\n\t\t\t\t\t[\n\t\t\t\t\t\tfaceVert[i + +facingInwards],\n\t\t\t\t\t\tfaceVert[i + 1 - +facingInwards],\n\t\t\t\t\t\tfaceVert[0],\n\t\t\t\t\t].forEach((v) => {\n\t\t\t\t\t\tvertexBuffer.push(v.x, v.y, v.z);\n\t\t\t\t\t\tnormalBuffer.push(normal.x, normal.y, normal.z); // same normal for all triangles in this face\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} // end of function\n\n\t\t//===========================================================================================\n\t\t// this function is the same (with minor adjustments) in PolyhedronGeometry()\n\t\t//===========================================================================================\n\t\t//\n\t\tfunction generateUVs() {\n\t\t\tconst vertex = new Vector3();\n\n\t\t\tfor (let i = 0; i < vertexBuffer.length; i += 3) {\n\t\t\t\tvertex.x = vertexBuffer[i + 0];\n\t\t\t\tvertex.y = vertexBuffer[i + 1];\n\t\t\t\tvertex.z = vertexBuffer[i + 2];\n\n\t\t\t\tconst u = azimuth(vertex) / 2 / Math.PI + 0.5;\n\t\t\t\tconst v = inclination(vertex) / Math.PI + 0.5;\n\t\t\t\tuvBuffer.push(u, 1 - v);\n\t\t\t}\n\n\t\t\t//function correctUVs()\n\t\t\t//{\n\t\t\tconst a = new Vector3();\n\t\t\tconst b = new Vector3();\n\t\t\tconst c = new Vector3();\n\n\t\t\tconst centroid = new Vector3();\n\n\t\t\tconst uvA = new Vector2();\n\t\t\tconst uvB = new Vector2();\n\t\t\tconst uvC = new Vector2();\n\n\t\t\tconst correctUV = (\n\t\t\t\tuv: Vector2,\n\t\t\t\tstride: number,\n\t\t\t\tvector: Vector3,\n\t\t\t\tazimuth: number\n\t\t\t) => {\n\t\t\t\tif (azimuth < 0 && uv.x === 1) uvBuffer[stride] = uv.x - 1;\n\t\t\t\tif (vector.x === 0 && vector.z === 0)\n\t\t\t\t\tuvBuffer[stride] = azimuth / 2 / Math.PI + 0.5;\n\t\t\t};\n\n\t\t\tfor (let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) {\n\t\t\t\ta.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]);\n\t\t\t\tb.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]);\n\t\t\t\tc.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]);\n\n\t\t\t\tuvA.set(uvBuffer[j + 0], uvBuffer[j + 1]);\n\t\t\t\tuvB.set(uvBuffer[j + 2], uvBuffer[j + 3]);\n\t\t\t\tuvC.set(uvBuffer[j + 4], uvBuffer[j + 5]);\n\n\t\t\t\tcentroid.copy(a).add(b).add(c).divideScalar(3);\n\n\t\t\t\tconst azi = azimuth(centroid);\n\n\t\t\t\tcorrectUV(uvA, j + 0, a, azi);\n\t\t\t\tcorrectUV(uvB, j + 2, b, azi);\n\t\t\t\tcorrectUV(uvC, j + 4, c, azi);\n\t\t\t}\n\t\t\t//}\n\n\t\t\t//function correctSeam()\n\t\t\t//{\n\t\t\t// handle case when face straddles the seam, see #3269\n\n\t\t\tfor (let i = 0; i < uvBuffer.length; i += 6) {\n\t\t\t\t// uv data of a single face\n\n\t\t\t\tconst x0 = uvBuffer[i + 0];\n\t\t\t\tconst x1 = uvBuffer[i + 2];\n\t\t\t\tconst x2 = uvBuffer[i + 4];\n\n\t\t\t\tconst max = Math.max(x0, x1, x2);\n\t\t\t\tconst min = Math.min(x0, x1, x2);\n\n\t\t\t\t// 0.9 is somewhat arbitrary\n\n\t\t\t\tif (max > 0.9 && min < 0.1) {\n\t\t\t\t\tif (x0 < 0.2) uvBuffer[i + 0] += 1;\n\t\t\t\t\tif (x1 < 0.2) uvBuffer[i + 2] += 1;\n\t\t\t\t\tif (x2 < 0.2) uvBuffer[i + 4] += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t//}\n\n\t\t\t// Angle around the Y axis, counter-clockwise when looking from above.\n\t\t\tfunction azimuth(vector: Vector3) {\n\t\t\t\treturn Math.atan2(vector.z, -vector.x);\n\t\t\t}\n\n\t\t\t// Angle above the XZ plane.\n\t\t\tfunction inclination(vector: Vector3) {\n\t\t\t\treturn Math.atan2(\n\t\t\t\t\t-vector.y,\n\t\t\t\t\tMath.sqrt(vector.x * vector.x + vector.z * vector.z)\n\t\t\t\t);\n\t\t\t}\n\t\t} // end of function generateUVs()\n\t}\n\n\tstatic fromJSON(data: any) {\n\t\treturn new PolyhedronRoundGeometry(\n\t\t\tdata.vertices,\n\t\t\tdata.indices,\n\t\t\tdata.radius,\n\t\t\tdata.corner,\n\t\t\tdata.cornerSides\n\t\t);\n\t}\n}\n\nexport {\n\tPolyhedronRoundGeometry,\n\tPolyhedronRoundGeometry as PolyhedronRoundBufferGeometry,\n};\n\n/*\n// --------------------------------------------------------------------------------------------------\n// data for cube, octahedron and tetrahedron\n\n// ==================================================================\n// CUBE:\n\nvertices = [\n\t1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1,\n\t1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1 \n];\nindices = [\n\t0, 1, 2, 2, 3, 0,\n\t4, 6, 5, 7, 6, 4,\n\t0, 4, 5, 5, 1, 0,\n\t1, 5, 6, 6, 2, 1,\n\t2, 6, 7, 7, 3, 2,\n\t3, 7, 4, 4, 0, 3\n];\n\n// ==================================================================\n// OCTA:\n\nvertices = [\n\t0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 0, -1, 0\n];\nindices = [\n\t0, 1, 2,\n\t0, 2, 3, \n\t0, 3, 4,\n\t0, 4, 1,\n\t5, 2, 1,\n\t5, 3, 2,\n\t5, 4, 3, \n\t5, 1, 4\n];\n\n// ==================================================================\n// TETRA:\nvertices = [\n\t1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1\n];\nindices = [\n\t0, 1, 2,\n\t0, 2, 3, \n\t0, 3, 1,\n\t3, 2, 1\n];\n\n// --------------------------------------------------------------------------------------------------\n*/\n", "/**\n * @author nisa\n */\n\nimport { PolyhedronRoundGeometry } from './PolyhedronRoundGeometry';\nimport { DodecahedronBufferGeometry } from 'three';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type DodecahedronGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tdetail: number;\n\tcorner: number;\n\tcornerSides: number;\n};\n\nexport type DodecahedronGeometryInputs = {\n\tparameters: DodecahedronGeometryParameters;\n};\n\nexport const DodecahedronGeometry: CGeometry<DodecahedronGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<DodecahedronGeometryInputs>\n\t): IGeometry<DodecahedronGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<DodecahedronGeometryInputs>,\n\t\tbase?: DodecahedronGeometryInputs\n\t): DodecahedronGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdetail: 0,\n\t\t\t\tcorner: 0,\n\t\t\t\tcornerSides: 4,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: DodecahedronGeometryInputs\n\t): IGeometry<DodecahedronGeometryInputs> {\n\t\tconst { width, height, depth, detail, corner, cornerSides } =\n\t\t\tinputs.parameters;\n\n\t\tconst geometry =\n\t\t\tdetail === 0 && corner !== 0\n\t\t\t\t? new DodecahedronRoundGeometry(width * 0.5, corner, cornerSides)\n\t\t\t\t: new DodecahedronBufferGeometry(width * 0.5, detail);\n\n\t\tgeometry.scale(1, height / width, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'DodecahedronGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nclass DodecahedronRoundGeometry extends PolyhedronRoundGeometry {\n\tconstructor(radius = 1, corner = 0.2, cornerSides = 4) {\n\t\tconst t = (1 + Math.sqrt(5)) / 2;\n\t\tconst r = 1 / t;\n\n\t\tconst vertices = [\n\t\t\t// (\u00B11, \u00B11, \u00B11)\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t-1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t-1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t1,\n\t\t\t// (0, \u00B11/\u03C6, \u00B1\u03C6)\n\t\t\t0,\n\t\t\t-r,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t-r,\n\t\t\tt,\n\t\t\t0,\n\t\t\tr,\n\t\t\t-t,\n\t\t\t0,\n\t\t\tr,\n\t\t\tt,\n\t\t\t// (\u00B11/\u03C6, \u00B1\u03C6, 0)\n\t\t\t-r,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t-r,\n\t\t\tt,\n\t\t\t0,\n\t\t\tr,\n\t\t\t-t,\n\t\t\t0,\n\t\t\tr,\n\t\t\tt,\n\t\t\t0,\n\t\t\t// (\u00B1\u03C6, 0, \u00B11/\u03C6)\n\t\t\t-t,\n\t\t\t0,\n\t\t\t-r,\n\t\t\tt,\n\t\t\t0,\n\t\t\t-r,\n\t\t\t-t,\n\t\t\t0,\n\t\t\tr,\n\t\t\tt,\n\t\t\t0,\n\t\t\tr,\n\t\t];\n\n\t\tconst indices = [\n\t\t\t3, 11, 7, 3, 7, 15, 3, 15, 13, 7, 19, 17, 7, 17, 6, 7, 6, 15, 17, 4, 8,\n\t\t\t17, 8, 10, 17, 10, 6, 8, 0, 16, 8, 16, 2, 8, 2, 10, 0, 12, 1, 0, 1, 18, 0,\n\t\t\t18, 16, 6, 10, 2, 6, 2, 13, 6, 13, 15, 2, 16, 18, 2, 18, 3, 2, 3, 13, 18,\n\t\t\t1, 9, 18, 9, 11, 18, 11, 3, 4, 14, 12, 4, 12, 0, 4, 0, 8, 11, 9, 5, 11, 5,\n\t\t\t19, 11, 19, 7, 19, 5, 14, 19, 14, 4, 19, 4, 17, 1, 12, 14, 1, 14, 5, 1, 5,\n\t\t\t9,\n\t\t];\n\n\t\tconst type = 'DodecahedronGeometry';\n\n\t\tsuper(vertices, indices, type, radius, corner, cornerSides);\n\n\t\tthis.type = type;\n\n\t\t// this.parameters = {\n\t\t// \tradius: radius,\n\t\t// \tdetail: detail\n\t\t// };\n\t}\n\n\tstatic fromJSON(data: any) {\n\t\treturn new DodecahedronRoundGeometry(\n\t\t\tdata.radius,\n\t\t\tdata.corner,\n\t\t\tdata.cornerSides\n\t\t);\n\t}\n}\n", "/**\n * @author Guillaume Gouessan\n */\n\nimport {\n\tBufferAttribute,\n\tEventDispatcher,\n\tPlane,\n\tShape,\n\tVector2,\n\tVector3,\n\tMathUtils,\n\tLineCurve,\n\tQuadraticBezierCurve,\n\tCubicBezierCurve,\n\tCurve,\n\tPath,\n} from 'three';\nimport { SerializedVectorShape } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport {\n\tBezierPoint,\n\tgetAngle,\n\tgetApproximatedCircleCubicBezierControls,\n\tgetCircleCenters,\n\tgetCurveDivision,\n\tgetCurvesDivisionsFromPoints,\n\tisStraightLine,\n\tpickFurthestFrom,\n\tpointsSegmentsToBuffer,\n\tpointsToBuffer,\n\tpointsToFlatArray,\n\tquadraticToCubic,\n\tsplitCubic,\n} from './bezier';\nimport { VectorShape as VectorShapeState } from 'spline-data';\n\nconst ts1V2 = new Vector2();\nconst ts2V2 = new Vector2();\nconst ts3V2 = new Vector2();\nconst ts4V2 = new Vector2();\nconst ts5V2 = new Vector2();\nconst ts6V2 = new Vector2();\n\n/* -----------------------------------------------------------\n\tSHAPE\n----------------------------------------------------------- */\nexport class VectorShape extends Shape {\n\tpoints: BezierPoint[] = [];\n\tshapeHoles: VectorShape[] = [];\n\teventDispatcher: EventDispatcher | null = new EventDispatcher();\n\tplane: Plane = new Plane(new Vector3(0, 0, -1)); // By default vertical plane facing the camera\n\tcurveDivisions?: number[];\n\troundedCurveDivisions?: number[];\n\tsubdivision: number = 0;\n\tcontrolSnapDistance: number = 4;\n\tpointIDs: number = 0;\n\tisMesh2D: boolean = false;\n\n\tprivate _roundness: number = 0;\n\n\tisClosed: boolean = false;\n\tuseCubicForRoundedCorners: boolean = true;\n\n\tuuid: string = MathUtils.generateUUID();\n\tneedsUpdate: boolean = false;\n\n\tprivate _width: number;\n\tprivate _height: number;\n\n\troundedCurves: Curve<Vector2>[] = [];\n\n\tstatic createFromState(\n\t\tdata: VectorShapeState,\n\t\twidth?: number,\n\t\theight?: number\n\t) {\n\t\tconst shape = new VectorShape();\n\t\tshape.isClosed = data.isClosed;\n\t\tshape.points = data.points.map((item) =>\n\t\t\tBezierPoint.create(item.id, item.data)\n\t\t);\n\t\tif (typeof data.roundness === 'number') {\n\t\t\tshape.roundness = data.roundness;\n\t\t}\n\t\tshape.shapeHoles = data.shapeHoles.map((hole) =>\n\t\t\tVectorShape.createFromState(hole)\n\t\t);\n\t\tif (width !== undefined && height !== undefined)\n\t\t\tshape.applySize(width, height);\n\t\tshape.update();\n\t\treturn shape;\n\t}\n\n\tconstructor(width: number = 100, height: number = 100) {\n\t\tsuper();\n\t\tthis._width = width;\n\t\tthis._height = height;\n\t}\n\n\tget width(): number {\n\t\treturn this._width;\n\t}\n\n\tget height(): number {\n\t\treturn this._height;\n\t}\n\n\tget roundness(): number {\n\t\treturn this._roundness;\n\t}\n\n\t/**\n\t * overrides each bezier point roundness\n\t */\n\tset roundness(value: number) {\n\t\tif (this._roundness !== value) {\n\t\t\tthis._roundness = value;\n\t\t\tfor (let i = 0, l = this.points.length; i < l; i++) {\n\t\t\t\tthis.points[i].roundness = value;\n\t\t\t}\n\t\t\tthis.needsUpdate = true;\n\t\t}\n\t}\n\n\tgetPointsIndexesByIds(pointIds: string[]) {\n\t\treturn pointIds\n\t\t\t.map((id) => this.getPointIndexById(id))\n\t\t\t.filter((o) => o >= 0);\n\t}\n\n\tgetPointIndexById(id: string) {\n\t\treturn this.points.findIndex((o) => o.uuid === id);\n\t}\n\n\tgetLineIndexById(id: string) {\n\t\treturn this.getPointIndexById(id);\n\t}\n\n\tgetBezierPoint(index: number): BezierPoint {\n\t\tif (index <= this.points.length - 1) return this.points[index];\n\n\t\tif (this.shapeHoles.length > 0) {\n\t\t\tfor (let i = 0, l = this.shapeHoles.length; i < l; i++) {\n\t\t\t\tconst hole = this.shapeHoles[i];\n\t\t\t\tconst holeIndex = index - this.points.length;\n\t\t\t\tif (holeIndex <= hole.points.length - 1) {\n\t\t\t\t\treturn hole.points[holeIndex];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t'This shape does not have a point for this index: ' + index\n\t\t);\n\t}\n\n\tgetBezierPointIndex(point: BezierPoint): number {\n\t\tlet index = this.points.indexOf(point);\n\t\tif (index >= 0) return index;\n\t\tindex = this.points.length;\n\n\t\tif (this.shapeHoles.length > 0) {\n\t\t\tfor (let i = 0, l = this.shapeHoles.length; i < l; i++) {\n\t\t\t\tconst hole = this.shapeHoles[i];\n\t\t\t\tconst holeIndex = hole.points.indexOf(point);\n\t\t\t\tif (holeIndex >= 0) return index + holeIndex;\n\t\t\t\tindex += hole.points.length;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\tgetAllPoints(): BezierPoint[] {\n\t\tconst holePoints = ([] as BezierPoint[]).concat(\n\t\t\t...this.shapeHoles.map((h) => h.points)\n\t\t);\n\t\treturn [...this.points, ...holePoints];\n\t}\n\n\tapplySize(width: number, height: number) {\n\t\tif (width === 0) width = 0.001;\n\t\tif (height === 0) height = 0.001;\n\t\tthis._width = width;\n\t\tthis._height = height;\n\t}\n\n\tapplyScale(x: number, y: number) {\n\t\tconst scale = ts1V2.set(x, y);\n\t\tfor (let i = 0, l = this.points.length; i < l; i++) {\n\t\t\tconst p = this.points[i];\n\t\t\tp.position.multiply(scale);\n\t\t\tp.controls[0].position.multiply(scale);\n\t\t\tp.controls[1].position.multiply(scale);\n\t\t}\n\t\tfor (let i = 0, l = this.shapeHoles.length; i < l; i++) {\n\t\t\tconst hole = this.shapeHoles[i];\n\t\t\thole.applyScale(x, y);\n\t\t}\n\t\tthis._update(false);\n\t}\n\n\tcreatePoint(\n\t\tx: Vector2 | number,\n\t\ty: number = 0,\n\t\tuuid: string = MathUtils.generateUUID()\n\t): BezierPoint {\n\t\tlet vec: Vector2;\n\t\tif (x instanceof Vector2) {\n\t\t\tvec = x;\n\t\t} else {\n\t\t\tvec = new Vector2(x, y);\n\t\t}\n\t\tconst p = new BezierPoint(uuid, vec);\n\t\tp.roundness = this.roundness;\n\t\treturn p;\n\t}\n\n\taddPoint(point: BezierPoint): void {\n\t\tthis.points.push(point);\n\t\tthis.needsUpdate = true;\n\t}\n\n\taddPointAt(point: BezierPoint, index: number): void {\n\t\tthis.points.splice(index, 0, point);\n\t\tthis.needsUpdate = true;\n\t}\n\n\tgetPointByUuid(uuid: string): BezierPoint | undefined {\n\t\tfor (let i = 0, l = this.points.length; i < l; i++) {\n\t\t\tconst point = this.points[i];\n\t\t\tif (point.uuid === uuid) return point;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tgetFirstPoint(): BezierPoint {\n\t\treturn this.points[0];\n\t}\n\n\tgetLastPoint(): BezierPoint {\n\t\treturn this.points[this.points.length - 1];\n\t}\n\n\tremovePoint(point: BezierPoint): void {\n\t\tconst index = this.points.indexOf(point);\n\t\tif (index >= 0) {\n\t\t\tthis.points.splice(index, 1);\n\t\t}\n\t\tthis.needsUpdate = true;\n\t}\n\n\tremovePointById(id: string): void {\n\t\tconst point = this.points.find((p) => p.uuid === id);\n\t\tif (point) {\n\t\t\tthis.removePoint(point);\n\t\t}\n\t}\n\n\tupdate(dispatch: boolean = true) {\n\t\tfor (let i = 0, l = this.shapeHoles.length; i < l; i++) {\n\t\t\tconst hole = this.shapeHoles[i];\n\t\t\thole.update(false);\n\t\t}\n\t\tthis._update(dispatch);\n\t}\n\n\t/**\n\t *\n\t * @param positions - The bufferAttribute in which we will put the shape position\n\t * @param divisions - Number of maximum subdivision by curves\n\t * @param includeRoundedCorners - boolean = false, instructs wether or not to take into account the rounded corner curves\n\t * @returns the number of vertex in the bufferattribute\n\t */\n\textractShapePointsToBuffer(\n\t\tpositions: BufferAttribute,\n\t\tdivisions: number = 12,\n\t\tincludeRoundedCorners: boolean = false\n\t): number {\n\t\tthis.subdivision = divisions;\n\n\t\tif (this.curveDivisions === undefined) {\n\t\t\tthis.computeCurveDivisions(divisions);\n\t\t}\n\n\t\tconst curveDivision = includeRoundedCorners\n\t\t\t? this.roundedCurveDivisions\n\t\t\t: this.curveDivisions;\n\n\t\tpointsToBuffer(\n\t\t\tpositions,\n\t\t\tincludeRoundedCorners ? this.roundedCurves : this.curves,\n\t\t\tdivisions,\n\t\t\tthis.autoClose\n\t\t);\n\n\t\treturn curveDivision!.reduce((a, b) => a + b, 0) + 1;\n\t}\n\n\tcomputeCurveDivisions(divisions: number = 12) {\n\t\tthis.curveDivisions = getCurvesDivisionsFromPoints(\n\t\t\tthis.points,\n\t\t\tdivisions,\n\t\t\tfalse\n\t\t);\n\t\tthis.roundedCurveDivisions = getCurvesDivisionsFromPoints(\n\t\t\tthis.points,\n\t\t\tdivisions,\n\t\t\ttrue\n\t\t);\n\t\treturn this.curveDivisions;\n\t}\n\n\t/**\n\t *\n\t * @param positions - The bufferAttribute in which we will put the shape position\n\t * @param divisions - Number of maximum subdivision by curves\n\t * @param filter - inde curve we want to exa\n\t * @returns the number of vertex in the bufferattribute\n\t */\n\textractFilteredShapePointsToBuffer(\n\t\tpositions: BufferAttribute,\n\t\tfilter: boolean[],\n\t\tdivisions: number = 12\n\t): number {\n\t\tconst segmentCurveDivisions = pointsSegmentsToBuffer(\n\t\t\tpositions,\n\t\t\tthis.curves,\n\t\t\tfilter,\n\t\t\tdivisions,\n\t\t\tthis.autoClose\n\t\t);\n\t\treturn segmentCurveDivisions.reduce((a, b) => a + b, 0) * 2;\n\t}\n\n\textractShapePointsToFlatArray(positions: number[], divisions: number = 12) {\n\t\tthis.subdivision = divisions;\n\n\t\tif (this.curveDivisions === undefined) {\n\t\t\tthis.computeCurveDivisions(divisions);\n\t\t}\n\n\t\treturn pointsToFlatArray(\n\t\t\tpositions,\n\t\t\tthis.roundedCurves,\n\t\t\tdivisions,\n\t\t\tthis.autoClose\n\t\t);\n\t}\n\n\t/**\n\t * Reverse mapping from extractShapePoints* to find the curve and T value an\n\t * output vertex corresponds to.\n\t * @param vertexId - the vertex to look up\n\t * @param includeRoundCorners - boolean = false, wether or not to take the rounded corner curves into account\n\t * @returns tuple [curveIndex, T]\n\t */\n\tgetCurveIndexFromVertexId(\n\t\tvertexId: number,\n\t\tincludeRoundCorners: boolean = false\n\t): [number, number] {\n\t\tlet sum = 0;\n\t\tif (this.curveDivisions === undefined) {\n\t\t\tthis.computeCurveDivisions(this.subdivision);\n\t\t}\n\t\tconst curveDivisions = includeRoundCorners\n\t\t\t? this.roundedCurveDivisions!\n\t\t\t: this.curveDivisions!;\n\t\tlet offset = 0;\n\t\tif (\n\t\t\tincludeRoundCorners &&\n\t\t\tthis.points[0].roundedCurveCorner !== undefined\n\t\t) {\n\t\t\toffset =\n\t\t\t\tgetCurveDivision(this.points[0].roundedCurveCorner, this.subdivision) *\n\t\t\t\t0.5;\n\t\t}\n\t\tlet id = vertexId - offset;\n\n\t\tif (id < 0) {\n\t\t\tid += curveDivisions.reduce((a, b) => a + b, 0);\n\t\t}\n\t\tfor (let i = 0, l = curveDivisions.length; i < l; i++) {\n\t\t\tconst dist = curveDivisions[i];\n\t\t\tif (id < sum + dist) return [i, (id - sum + 1) / dist];\n\t\t\tsum += dist;\n\t\t}\n\n\t\t// this is wrong, should sometimes return [0, 0], sometimes [0, 1]\n\t\treturn [0, 1];\n\t}\n\n\tgetCurveT(curveIndex: number, vertexId: number, position: Vector3): number {\n\t\tconst pStart = this.points[curveIndex];\n\t\tconst pEnd =\n\t\t\tthis.points[curveIndex >= this.points.length - 1 ? 0 : curveIndex + 1];\n\t\tconst divisions = this.curveDivisions!;\n\t\tconst division = divisions[curveIndex];\n\n\t\t// in case curve is a line we only need the ratio of position between pStart and pEnd\n\t\tif (isStraightLine(pStart, pEnd)) {\n\t\t\tconst dTot = pStart.position.distanceTo(pEnd.position);\n\t\t\tconst d = pStart.position.distanceTo(ts1V2.set(position.x, position.y));\n\t\t\treturn d / dTot;\n\t\t}\n\n\t\t// For a curve we need to know how many vertices came before vertexId\n\t\tlet prevVerticesCount = 0;\n\t\tfor (let i = 0; i < curveIndex; i++) {\n\t\t\tprevVerticesCount += divisions[i];\n\t\t}\n\n\t\t// So we can compare the vertexId to current curve division\n\t\tconst t = (vertexId - prevVerticesCount) / division;\n\n\t\t// If position doesn't exactly land on a vertex of the curve, we can consider its position in the straight line from vertexId to next vertexId\n\n\t\treturn t;\n\t}\n\n\tdispose() {\n\t\tthis.eventDispatcher = null;\n\t}\n\n\tprivate _applyCurveForPoint(current: BezierPoint, previous: BezierPoint) {\n\t\tif (isStraightLine(previous, current)) {\n\t\t\tthis.lineTo(current.position.x, current.position.y);\n\t\t} else {\n\t\t\tthis.bezierCurveTo(\n\t\t\t\tprevious.controls[1].position.x,\n\t\t\t\tprevious.controls[1].position.y,\n\t\t\t\tcurrent.controls[0].position.x,\n\t\t\t\tcurrent.controls[0].position.y,\n\t\t\t\tcurrent.position.x,\n\t\t\t\tcurrent.position.y\n\t\t\t);\n\t\t}\n\t\tconst curve = this.curves[this.curves.length - 1] as\n\t\t\t| LineCurve\n\t\t\t| CubicBezierCurve;\n\t\tcurrent.curveBefore = curve;\n\t\tprevious.curveAfter = curve;\n\n\t\tconst roundedCurve = curve.clone();\n\t\tcurrent.roundedCurveBefore = roundedCurve;\n\t\tprevious.roundedCurveAfter = roundedCurve;\n\n\t\tcurrent.roundedCurveCorner = undefined;\n\t\tthis.roundedCurves.push(roundedCurve);\n\t}\n\n\tprivate _update(dispatch: boolean = true) {\n\t\tthis.curves = [];\n\t\tthis.roundedCurves = [];\n\n\t\tif (!this.points.length) return;\n\n\t\t// Create curves\n\t\tfor (let i = 0, l = this.points.length; i < l; i++) {\n\t\t\tconst p = this.points[i];\n\t\t\tif (i === 0) {\n\t\t\t\tthis.moveTo(p.position.x, p.position.y);\n\t\t\t} else {\n\t\t\t\tconst previous = this.points[i - 1];\n\t\t\t\tthis._applyCurveForPoint(p, previous);\n\t\t\t}\n\t\t}\n\n\t\t// Need to do this in case points were removed\n\t\tconst last = this.getLastPoint();\n\t\tif (last?.curveAfter) last.curveAfter = undefined;\n\n\t\t// Close shape\n\t\tif (this.isClosed) {\n\t\t\tconst p = this.points[0];\n\t\t\tconst previous = this.points[this.points.length - 1];\n\t\t\tthis._applyCurveForPoint(p, previous);\n\t\t}\n\n\t\t// Check for round corners\n\t\tif (this.points.length > 2) {\n\t\t\tlet nbRounded = 0;\n\t\t\tfor (let i = 0, l = this.points.length; i < l; i++) {\n\t\t\t\tconst current = this.points[i];\n\t\t\t\tconst roundness = current.roundness;\n\t\t\t\tif (!current.controlsMoved() && roundness > 0) {\n\t\t\t\t\tconst curve0 = current.curveBefore;\n\t\t\t\t\tconst curve1 = current.curveAfter;\n\n\t\t\t\t\tif (curve0 === undefined || curve1 === undefined) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst roundedCurve0 = current.roundedCurveBefore!;\n\t\t\t\t\tconst roundedCurve1 = current.roundedCurveAfter!;\n\t\t\t\t\tconst d0 = curve0.getLength();\n\t\t\t\t\tconst d1 = curve1.getLength();\n\n\t\t\t\t\tconst r0 = Math.min(roundness, d0 * 0.499);\n\t\t\t\t\tconst r1 = Math.min(roundness, d1 * 0.499);\n\t\t\t\t\tconst r = Math.min(r0, r1);\n\n\t\t\t\t\tconst t0 = 1 - r / d0;\n\t\t\t\t\tconst t1 = r / d1;\n\n\t\t\t\t\tconst newP0 = curve0.getPointAt(t0, ts1V2);\n\t\t\t\t\tconst newP1 = curve1.getPointAt(t1, ts2V2);\n\n\t\t\t\t\tthis._subSplitCurve(curve0, roundedCurve0, t0, newP0, undefined);\n\t\t\t\t\tthis._subSplitCurve(curve1, roundedCurve1, t1, undefined, newP1);\n\n\t\t\t\t\tlet roundedCurveCorner;\n\n\t\t\t\t\tif (this.useCubicForRoundedCorners) {\n\t\t\t\t\t\t// angle of the corner\n\t\t\t\t\t\tconst a = getAngle(newP0, current.position, newP1) / 2;\n\t\t\t\t\t\t// radius of the circle the arc we want to draw belongs to\n\t\t\t\t\t\tconst radius = Math.tan(a) * newP0.distanceTo(current.position);\n\t\t\t\t\t\t// centers of the two possible circles the arc we want to draw belongs to\n\t\t\t\t\t\tconst [m1, m2] = getCircleCenters(\n\t\t\t\t\t\t\tnewP0,\n\t\t\t\t\t\t\tnewP1,\n\t\t\t\t\t\t\tradius,\n\t\t\t\t\t\t\tts3V2,\n\t\t\t\t\t\t\tts4V2\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// actual center of the circle the arc we want to draw belongs to\n\t\t\t\t\t\tconst m = pickFurthestFrom(m1, m2, current.position);\n\t\t\t\t\t\t// control points of the cubic bezier around this circle\n\t\t\t\t\t\tconst [c1, c2] = getApproximatedCircleCubicBezierControls(\n\t\t\t\t\t\t\tm,\n\t\t\t\t\t\t\tnewP0,\n\t\t\t\t\t\t\tnewP1,\n\t\t\t\t\t\t\tradius,\n\t\t\t\t\t\t\tts5V2,\n\t\t\t\t\t\t\tts6V2\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// final curve (approximating a perfect arc)\n\t\t\t\t\t\troundedCurveCorner = new CubicBezierCurve(\n\t\t\t\t\t\t\tnewP0.clone(),\n\t\t\t\t\t\t\tc1.clone(),\n\t\t\t\t\t\t\tc2.clone(),\n\t\t\t\t\t\t\tnewP1.clone()\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\troundedCurveCorner = new QuadraticBezierCurve(\n\t\t\t\t\t\t\tnewP0.clone(),\n\t\t\t\t\t\t\tcurrent.position.clone(),\n\t\t\t\t\t\t\tnewP1.clone()\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent.roundedCurveCorner = roundedCurveCorner;\n\n\t\t\t\t\tthis.roundedCurves.splice(i + nbRounded, 0, roundedCurveCorner);\n\t\t\t\t\tnbRounded++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (dispatch) {\n\t\t\tthis.eventDispatcher?.dispatchEvent({ type: 'update' });\n\t\t}\n\t}\n\n\t// private _getCurveLength(curve:LineCurve|CubicBezierCurve|QuadraticBezierCurve) {\n\t// \t// curve.getLength()\n\t// }\n\n\t/**\n\t * Split a curve in the backend (not reflected in the ui) to handle specific round corner cases\n\t */\n\tprivate _subSplitCurve(\n\t\tinCurve: LineCurve | CubicBezierCurve,\n\t\toutCurve: LineCurve | CubicBezierCurve,\n\t\tt: number,\n\t\tnewEnd?: Vector2,\n\t\tnewStart?: Vector2\n\t): LineCurve | CubicBezierCurve {\n\t\tif (inCurve instanceof LineCurve) {\n\t\t\tif (newEnd !== undefined) {\n\t\t\t\toutCurve.v2.copy(newEnd);\n\t\t\t}\n\t\t\tif (newStart !== undefined) {\n\t\t\t\toutCurve.v1.copy(newStart);\n\t\t\t}\n\t\t} else {\n\t\t\tconst c = inCurve;\n\t\t\tconst o = outCurve as CubicBezierCurve;\n\t\t\tconst u = c.getUtoTmapping(t, 0);\n\t\t\tconst d = splitCubic(c.v0, c.v1, c.v2, c.v3, u);\n\t\t\tif (newEnd !== undefined) {\n\t\t\t\to.v0.set(d[0], d[1]);\n\t\t\t\to.v1.set(d[2], d[3]);\n\t\t\t\to.v2.set(d[4], d[5]);\n\t\t\t\to.v3.set(d[6], d[7]);\n\t\t\t}\n\t\t\tif (newStart !== undefined) {\n\t\t\t\to.v0.set(d[6], d[7]);\n\t\t\t\to.v1.set(d[8], d[9]);\n\t\t\t\to.v2.set(d[10], d[11]);\n\t\t\t\to.v3.set(d[12], d[13]);\n\t\t\t}\n\t\t\treturn o;\n\t\t}\n\t\treturn outCurve;\n\t}\n\n\tclone(): this {\n\t\tconst shape = new VectorShape(this._width, this._height);\n\t\tshape.points = this.points.map((point) => point.clone());\n\t\tshape.isClosed = this.isClosed;\n\t\tshape.roundness = this.roundness;\n\t\tshape.isMesh2D = this.isMesh2D;\n\t\tshape.shapeHoles = this.shapeHoles.map((hole) => hole.clone());\n\t\treturn shape as this;\n\t}\n\n\t/**\n\t * The points data are mapped like an interleaved array of numbers\n\t * containing data for each points and it's two control points\n\t * [p1.x, p1.y, p1.c1.x, p1.c1.y, p1.c2.x, p1.c2.y, p1.roundness, p2.x, p2.y, p2.c1.x, ...]\n\t * @returns\n\t */\n\ttoJSON(): SerializedVectorShape {\n\t\treturn {\n\t\t\tpoints: this.points.reduce(\n\t\t\t\t(acc: number[], point: BezierPoint) => acc.concat(point.toJSON()),\n\t\t\t\t[]\n\t\t\t),\n\t\t\tshapeHoles: this.shapeHoles.map((shape) => shape.toJSON()),\n\t\t\tisClosed: this.isClosed,\n\t\t\troundness: this.roundness,\n\t\t};\n\t}\n\n\tfromJSON(data: SerializedVectorShape): this {\n\t\tthis.points = [];\n\t\tthis.pointIDs = 0;\n\t\tconst nbPoints = data.points.length / 7;\n\t\tfor (let i = 0; i < nbPoints; i++) {\n\t\t\tconst i7 = i * 7;\n\t\t\tconst x = data.points[i7 + 0];\n\t\t\tconst y = data.points[i7 + 1];\n\t\t\tconst c1x = data.points[i7 + 2];\n\t\t\tconst c1y = data.points[i7 + 3];\n\t\t\tconst c2x = data.points[i7 + 4];\n\t\t\tconst c2y = data.points[i7 + 5];\n\t\t\tconst roundness = data.points[i7 + 6];\n\t\t\tconst p = new BezierPoint(MathUtils.generateUUID(), new Vector2(x, y));\n\t\t\tp.controls[0].position.set(c1x, c1y);\n\t\t\tp.controls[1].position.set(c2x, c2y);\n\t\t\tp.roundness = roundness;\n\t\t\tthis.points.push(p);\n\t\t}\n\t\tthis.shapeHoles = data.shapeHoles?.length\n\t\t\t? data.shapeHoles.map((hole: SerializedVectorShape) => {\n\t\t\t\t\tconst shape = new VectorShape();\n\t\t\t\t\tshape.fromJSON(hole);\n\t\t\t\t\treturn shape;\n\t\t\t })\n\t\t\t: [];\n\t\tthis.isClosed = data.isClosed;\n\t\tthis._roundness = data.roundness;\n\t\tthis._update();\n\t\treturn this;\n\t}\n\n\tfromShape(shape: Shape | Path): this {\n\t\tconst applyPrevious = (p: BezierPoint, previous: Curve<Vector2>) => {\n\t\t\tif (\n\t\t\t\tprevious instanceof CubicBezierCurve &&\n\t\t\t\tprevious.v3.equals(p.position)\n\t\t\t) {\n\t\t\t\tp.controls[0].position.copy(previous.v2);\n\t\t\t}\n\t\t};\n\t\tconst convertCurves = (curves: Curve<Vector2>[]): BezierPoint[] => {\n\t\t\tconst points: BezierPoint[] = [];\n\t\t\tlet i, l;\n\n\t\t\t// Replaces Quadratic curves by their Cubic equivalent\n\t\t\tfor (i = 0, l = curves.length; i < l; i++) {\n\t\t\t\tif (curves[i] instanceof QuadraticBezierCurve) {\n\t\t\t\t\tcurves[i] = quadraticToCubic(curves[i] as QuadraticBezierCurve);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (i = 0, l = curves.length; i < l; i++) {\n\t\t\t\tconst current = curves[i];\n\t\t\t\tconst previous = i > 0 ? curves[i - 1] : null;\n\t\t\t\tlet point;\n\n\t\t\t\tif (current instanceof CubicBezierCurve) {\n\t\t\t\t\tpoint = this.createPoint(current.v0);\n\t\t\t\t\tpoint.controls[1].position.copy(current.v1);\n\t\t\t\t} else if (current instanceof LineCurve) {\n\t\t\t\t\tpoint = this.createPoint(current.v1);\n\t\t\t\t}\n\n\t\t\t\tif (point !== undefined) {\n\t\t\t\t\tif (previous !== null) {\n\t\t\t\t\t\tapplyPrevious(point, previous);\n\t\t\t\t\t}\n\t\t\t\t\tpoints.push(point);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst lastCurve = curves[curves.length - 1];\n\t\t\tlet isClosed = false;\n\t\t\tif (lastCurve instanceof CubicBezierCurve) {\n\t\t\t\tif (lastCurve.v3.equals(points[0].position)) {\n\t\t\t\t\tpoints[0].controls[0].position.copy(lastCurve.v2);\n\t\t\t\t\tisClosed = true;\n\t\t\t\t}\n\t\t\t} else if (lastCurve instanceof LineCurve) {\n\t\t\t\tif (lastCurve.v2.equals(points[0].position)) {\n\t\t\t\t\tisClosed = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.isClosed = isClosed;\n\n\t\t\treturn points;\n\t\t};\n\n\t\tthis.points = convertCurves(shape.curves);\n\n\t\tif (shape instanceof Shape) {\n\t\t\tthis.shapeHoles = shape.holes.map((shape) => {\n\t\t\t\tconst hole = new VectorShape();\n\t\t\t\thole.fromShape(shape);\n\t\t\t\treturn hole;\n\t\t\t});\n\t\t}\n\n\t\tthis.update();\n\n\t\treturn this;\n\t}\n}\n", "/* -----------------------------------------------------------\n\tBEZIER DATA\n----------------------------------------------------------- */\n\nimport {\n\tBufferAttribute,\n\tCubicBezierCurve,\n\tCurve,\n\tEllipseCurve,\n\tLineCurve,\n\tLineCurve3,\n\tMathUtils,\n\tQuadraticBezierCurve,\n\tSplineCurve,\n\tVector2,\n\tVector3,\n} from 'three';\nimport type { BezierPoint as BezierPointState } from 'spline-data';\ntype TCurves =\n\t| EllipseCurve\n\t| LineCurve\n\t| LineCurve3\n\t| SplineCurve\n\t| Curve<Vector2>;\n\nconst ROUNDED_CURVE_NORMAL_EPSILON = 1e-12;\n\n/**\n * The base point class for every kind of point on a bezier curve\n */\nclass Point {\n\tposition: Vector2 = new Vector2();\n\tstartPosition: Vector2 = new Vector2();\n\tuuid: string = MathUtils.generateUUID();\n\n\tconstructor(position: Vector2) {\n\t\tthis.position = position.clone();\n\t}\n\n\tstart() {\n\t\tthis.reset();\n\t}\n\n\treset() {\n\t\tthis.startPosition.copy(this.position);\n\t}\n\n\tapplyOffset(offset: Vector2) {\n\t\tthis.position.copy(this.startPosition).add(offset);\n\t}\n\n\tcopy(p: Point): Point {\n\t\tthis.position.copy(p.position);\n\t\tthis.startPosition.copy(p.startPosition);\n\t\treturn this;\n\t}\n\n\tclone(): Point {\n\t\treturn new Point(this.position).copy(this);\n\t}\n\n\ttoJSON(): number[] {\n\t\treturn [this.position.x, this.position.y];\n\t}\n}\n\n/**\n * The control point for a given BezierPoint (which has two control points)\n */\nexport class BezierControl extends Point {\n\tconstructor(public parent: BezierPoint) {\n\t\tsuper(parent.position);\n\t}\n\n\tcopy(p: BezierControl): BezierControl {\n\t\tsuper.copy(p);\n\t\treturn this;\n\t}\n\n\tclone(): BezierControl {\n\t\treturn new BezierControl(this.parent).copy(this);\n\t}\n}\n\n/**\n * Bezier point, either the start or the end of a bezier curve\n */\nexport class BezierPoint extends Point {\n\tcontrols: BezierControl[] = [];\n\troundness: number = 0;\n\tuuid: string;\n\n\tareControlsDirectionsMirrored: boolean = true;\n\n\tcurveBefore?: LineCurve | CubicBezierCurve;\n\tcurveAfter?: LineCurve | CubicBezierCurve;\n\n\troundedCurveBefore?: LineCurve | CubicBezierCurve;\n\troundedCurveAfter?: LineCurve | CubicBezierCurve;\n\troundedCurveCorner?: QuadraticBezierCurve | CubicBezierCurve;\n\n\tstatic create(id: string, state: BezierPointState) {\n\t\tconst point = new BezierPoint(id, new Vector2(...state.position));\n\t\tpoint.controls[0].position.set(...state.controlPrevious.position);\n\t\tpoint.controls[1].position.set(...state.controlNext.position);\n\t\tpoint.roundness = state.roundness;\n\t\tpoint.areControlsDirectionsMirrored = state.areControlsDirectionsMirrored;\n\t\treturn point;\n\t}\n\n\tconstructor(uuid: string, position: Vector2) {\n\t\tsuper(position);\n\t\tthis.uuid = uuid;\n\t\tthis.controls.push(new BezierControl(this), new BezierControl(this));\n\t}\n\n\tgetOppositeControl(control: BezierControl): BezierControl | null {\n\t\tconst index = this.controls.indexOf(control);\n\t\tif (index === 0) return this.controls[1];\n\t\telse if (index === 1) return this.controls[0];\n\t\treturn null;\n\t}\n\n\tapplyOffsetToControls(offset: Vector2, snapThreshold: number = 1) {\n\t\tfor (let i = 0, l = this.controls.length; i < l; i++) {\n\t\t\tconst c = this.controls[i];\n\t\t\tconst distance = this.position.distanceTo(c.position);\n\t\t\tif (distance <= snapThreshold) {\n\t\t\t\tc.position.copy(this.position);\n\t\t\t} else {\n\t\t\t\tc.applyOffset(offset);\n\t\t\t}\n\t\t}\n\t}\n\n\tcontrolsMoved(): boolean {\n\t\treturn !(\n\t\t\tthis.position.equals(this.controls[0].position) &&\n\t\t\tthis.position.equals(this.controls[1].position)\n\t\t);\n\t}\n\n\tcopy(p: BezierPoint): BezierPoint {\n\t\tsuper.copy(p);\n\t\tthis.controls[0].copy(p.controls[0]);\n\t\tthis.controls[1].copy(p.controls[1]);\n\t\tthis.roundness = p.roundness;\n\t\tthis.uuid = p.uuid;\n\t\treturn this;\n\t}\n\n\tclone(): BezierPoint {\n\t\treturn new BezierPoint(this.uuid, this.position).copy(this);\n\t}\n\n\ttoJSON(): number[] {\n\t\treturn super\n\t\t\t.toJSON()\n\t\t\t.concat(this.controls[0].toJSON(), this.controls[1].toJSON(), [\n\t\t\t\tthis.roundness,\n\t\t\t]);\n\t}\n}\n\n/* -----------------------------------------------------------\n\tUTILS AND FUNCTIONS\n----------------------------------------------------------- */\nconst toTCurve = (curve: TCurves): TCurves => curve;\n\nconst tempaV2 = new Vector2();\nconst tempbV2 = new Vector2();\nconst tempcV2 = new Vector2();\nconst tempdV2 = new Vector2();\nconst tempeV2 = new Vector2();\nconst tempfV2 = new Vector2();\nconst tempaV3 = new Vector3();\nconst tempbV3 = new Vector3();\n\nexport function quadraticToCubic(q: QuadraticBezierCurve): CubicBezierCurve {\n\tconst c1 = new Vector2();\n\tc1.addVectors(q.v0, tempaV2.subVectors(q.v1, q.v0).multiplyScalar(2 / 3));\n\tconst c2 = new Vector2();\n\tc2.addVectors(q.v2, tempbV2.subVectors(q.v1, q.v2).multiplyScalar(2 / 3));\n\treturn new CubicBezierCurve(q.v0, c1, c2, q.v2);\n}\n\nexport function computeOppositeControl(\n\tparent: BezierPoint,\n\tcontrol: BezierControl,\n\tout: Vector2,\n\tdistance?: number\n): Vector2 {\n\tconst oppositeControl = parent.getOppositeControl(control);\n\n\tif (oppositeControl === null) return out;\n\n\tout.copy(parent.position).sub(control.position);\n\tif (distance !== undefined) {\n\t\tout.normalize().multiplyScalar(distance);\n\t}\n\tout.add(parent.position);\n\treturn out;\n}\n\nfunction floatEqual(\n\tf1: number,\n\tf2: number,\n\te: number = Number.EPSILON\n): boolean {\n\treturn Math.abs(f1 - f2) < e;\n}\n\nfunction vector2Equal(v1: Vector2, v2: Vector2, e: number = Number.EPSILON) {\n\treturn v1.distanceTo(v2) < e;\n}\n\nfunction vector3Equal(v1: Vector3, v2: Vector3, e: number = Number.EPSILON) {\n\treturn v1.distanceTo(v2) < e;\n}\n\n/**\n * Returns in radian the angle of ABC\n * @param A - first extremity of the angle\n * @param B - center of the angle\n * @param C - second extremity of the angle\n */\nexport function getAngle(A: Vector2, B: Vector2, C: Vector2): number {\n\tconst AB = Math.sqrt(Math.pow(B.x - A.x, 2) + Math.pow(B.y - A.y, 2));\n\tconst BC = Math.sqrt(Math.pow(B.x - C.x, 2) + Math.pow(B.y - C.y, 2));\n\tconst AC = Math.sqrt(Math.pow(C.x - A.x, 2) + Math.pow(C.y - A.y, 2));\n\treturn Math.acos((BC * BC + AB * AB - AC * AC) / (2 * BC * AB));\n}\n\n/**\n * Computes the centers of the two possible circles given two points and a radius\n * @param A - a point on the circle\n * @param B - another point on the circle\n * @param radius - the radius of the circle\n * @param c1 - variable where the center of the first circle will be stored\n * @param c2 - variable where the center of the second circle will be stored\n */\nexport function getCircleCenters(\n\tA: Vector2,\n\tB: Vector2,\n\tradius: number,\n\tc1: Vector2,\n\tc2: Vector2\n): Vector2[] {\n\tconst q = Math.sqrt(Math.pow(B.x - A.x, 2) + Math.pow(B.y - A.y, 2));\n\n\tconst y3 = (A.y + B.y) / 2;\n\tconst x3 = (A.x + B.x) / 2;\n\n\tconst basex =\n\t\t(Math.sqrt(Math.pow(radius, 2) - Math.pow(q / 2, 2)) * (A.y - B.y)) / q; //calculate once\n\tconst basey =\n\t\t(Math.sqrt(Math.pow(radius, 2) - Math.pow(q / 2, 2)) * (B.x - A.x)) / q; //calculate once\n\n\tc1.set(x3 + basex, y3 + basey); //center of circle 1\n\tc2.set(x3 - basex, y3 - basey); //center of circle 2\n\n\treturn [c1, c2];\n}\n\n/**\n * returns the closest point to reference between p1 and p2\n * @param p1 - a point\n * @param p2 - another point\n * @param reference - reference to compare our points to\n */\nexport function pickFurthestFrom(p1: Vector2, p2: Vector2, reference: Vector2) {\n\tconst d1 = p1.distanceTo(reference);\n\tconst d2 = p2.distanceTo(reference);\n\tif (d1 < d2) return p2;\n\treturn p1;\n}\n\n/**\n * Computes the control points for a cubic bezier while approximating its curve around a given circle\n * @param M - center of the circle we want to make our bezier fit on\n * @param A - start of the cubic bezier, should be on the circle\n * @param B - end of the cubic bezier, should be on the circle\n * @param r - radius of the circle\n * @param c1 - variable where the first control point will be stored\n * @param c2 - variable where the second control point will be stored\n */\nexport function getApproximatedCircleCubicBezierControls(\n\tM: Vector2,\n\tA: Vector2,\n\tB: Vector2,\n\tr: number,\n\tc1: Vector2,\n\tc2: Vector2\n): Vector2[] {\n\tconst ax = A.x - M.x;\n\tconst ay = A.y - M.y;\n\tconst bx = B.x - M.x;\n\tconst by = B.y - M.y;\n\tlet d = Math.sqrt((ax + bx) * (ax + bx) + (ay + by) * (ay + by));\n\tlet k;\n\tif (getAngle(A, M, B) > Math.PI) {\n\t\td *= -1;\n\t}\n\tif (!floatEqual(by, ay)) {\n\t\tk = ((ax + bx) * (r / d - 0.5) * 8.0) / 3.0 / (by - ay);\n\t} else {\n\t\tk = ((ay + by) * (r / d - 0.5) * 8.0) / 3.0 / (ax - bx);\n\t}\n\tc1.set(A.x - k * ay, A.y + k * ax);\n\tc2.set(B.x + k * by, B.y - k * bx);\n\treturn [c1, c2];\n}\n\n/**\n * Returns true if the curve between pStart and pEnd is a straight line.\n * Meaning that the controls of pStart and pEnd won't influence curvature of the line\n * @param pStart -\n * @param pEnd -\n */\nexport function isStraightLine(\n\tpStart: BezierPoint,\n\tpEnd: BezierPoint\n): boolean {\n\treturn (\n\t\tpStart.position.equals(pStart.controls[1].position) &&\n\t\tpEnd.position.equals(pEnd.controls[0].position)\n\t);\n}\n\nexport function splitCubicFromPoints(\n\tpStart: BezierPoint,\n\tpEnd: BezierPoint,\n\tt: number = 0.5\n): number[] {\n\treturn splitCubic(\n\t\tpStart.position,\n\t\tpStart.controls[1].position,\n\t\tpEnd.controls[0].position,\n\t\tpEnd.position,\n\t\tt\n\t);\n}\n\nexport function splitCubic(\n\tstart: Vector2,\n\tc1: Vector2,\n\tc2: Vector2,\n\tend: Vector2,\n\tt: number = 0.5\n): number[] {\n\tconst midP1C1 = tempaV2.subVectors(c1, start).multiplyScalar(t).add(start);\n\tconst midC1C2 = tempbV2.subVectors(c2, c1).multiplyScalar(t).add(c1);\n\tconst midC2P2 = tempcV2.subVectors(end, c2).multiplyScalar(t).add(c2);\n\n\t// Start curve controls\n\tconst sc1 = midP1C1;\n\tconst sc2 = tempdV2\n\t\t.subVectors(midC1C2, midP1C1)\n\t\t.multiplyScalar(t)\n\t\t.add(midP1C1);\n\n\t// End curve controls\n\tconst ec1 = tempeV2\n\t\t.subVectors(midC2P2, midC1C2)\n\t\t.multiplyScalar(t)\n\t\t.add(midC1C2);\n\tconst ec2 = midC2P2;\n\n\tconst mp = tempfV2.subVectors(ec1, sc2).multiplyScalar(t).add(sc2);\n\n\treturn [\n\t\t// Start curve 1\n\t\tstart.x,\n\t\tstart.y,\n\t\t// Control a curve 1\n\t\tsc1.x,\n\t\tsc1.y,\n\t\t// Control b curve 1\n\t\tsc2.x,\n\t\tsc2.y,\n\t\t// End curve 1 and Start curve 2\n\t\tmp.x,\n\t\tmp.y,\n\t\t// Control a curve 2\n\t\tec1.x,\n\t\tec1.y,\n\t\t// Control b curve 2\n\t\tec2.x,\n\t\tec2.y,\n\t\t// End curve 2\n\t\tend.x,\n\t\tend.y,\n\t];\n}\n\n/**\n * Fill a buffer with vertex data extracted from a list of curves\n * This replaces the shape.getPoints() that is not very optimized for memory (creates a lot of object)\n * This ones put values directly in the typedArray of a bufferAttribute.\n * Beware the bufferAttribute has to be big enough to receive the data.\n * @param positions - The bufferAttribute in which we will put the shape position\n * @param curves - The curve from which we extract position data\n * @param divisions - Number of maximum subdivision by curve\n * @param autoClose - If true it will make sure that the first and last vertices are the same\n * @returns number of vertices set in the buffer\n */\nexport function pointsToBuffer(\n\tpositions: BufferAttribute,\n\tcurves: TCurves[],\n\tdivisions: number = 12,\n\tautoClose: boolean = true\n): BufferAttribute {\n\tconst current = tempbV3.set(0, 0, 0);\n\tlet last: Vector3 | undefined;\n\tlet index = 0;\n\tconst curveDivisions: number[] = [];\n\n\tfor (let i = 0; i < curves.length; i++) {\n\t\tconst curve = toTCurve(curves[i]);\n\t\tconst currentv2 = tempaV2;\n\t\tconst resolution = getCurveDivision(curve, divisions);\n\n\t\tcurveDivisions.push(resolution);\n\n\t\tfor (let d = 0; d <= resolution; d++) {\n\t\t\tif (\n\t\t\t\tcurve instanceof CubicBezierCurve ||\n\t\t\t\tcurve instanceof QuadraticBezierCurve ||\n\t\t\t\tcurve instanceof LineCurve\n\t\t\t) {\n\t\t\t\tcurve.getPoint(d / resolution, currentv2);\n\t\t\t\tcurrent.set(currentv2.x, currentv2.y, 0);\n\t\t\t\tif (last !== undefined && vector3Equal(last, current)) continue; // remove duplicates\n\t\t\t\tif (last === undefined) last = tempaV3;\n\t\t\t\tlast.copy(current);\n\t\t\t\tpositions.setXYZ(index, current.x, current.y, current.z);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (\n\t\tautoClose &&\n\t\tindex > 1 &&\n\t\t!(\n\t\t\tpositions.getX(index - 1) === positions.getX(0) &&\n\t\t\tpositions.getY(index - 1) === positions.getY(0) &&\n\t\t\tpositions.getZ(index - 1) === positions.getZ(0)\n\t\t)\n\t) {\n\t\tpositions.setXYZ(\n\t\t\tindex,\n\t\t\tpositions.getX(0),\n\t\t\tpositions.getY(0),\n\t\t\tpositions.getZ(0)\n\t\t);\n\t\tindex++;\n\t}\n\treturn positions;\n}\n\n/**\n * Fill a buffer with vertex data extracted from a list of curves\n * This replaces the shape.getPoints() that is not very optimized for memory (creates a lot of object)\n * This ones put values directly in the typedArray of a bufferAttribute.\n * Beware the bufferAttribute has to be big enough to receive the data.\n * @param positions - The bufferAttribute in which we will put the shape position\n * @param curves - The curve from which we extract position data\n * @param divisions - Number of maximum subdivision by curve\n * @param autoClose - If true it will make sure that the first and last vertices are the same\n * @param filter - which curve to extract\n * @returns number of vertices set in the buffer\n */\nexport function pointsSegmentsToBuffer(\n\tpositions: BufferAttribute,\n\tcurves: TCurves[],\n\tfilter: boolean[],\n\tdivisions: number = 12,\n\tautoClose: boolean = true\n): number[] {\n\tconst current = tempbV3.set(0, 0, 0);\n\tlet index = 0;\n\tconst curveDivisions: number[] = [];\n\n\tfor (let i = 0; i < curves.length; i++) {\n\t\tif (filter[i] === false) continue;\n\t\tlet last: Vector3 | undefined;\n\t\tconst curve = toTCurve(curves[i]);\n\t\tconst currentv2 = tempaV2;\n\t\tconst resolution = getCurveDivision(curve, divisions);\n\n\t\tcurveDivisions.push(resolution);\n\n\t\tfor (let d = 0; d <= resolution; d++) {\n\t\t\tif (\n\t\t\t\tcurve instanceof CubicBezierCurve ||\n\t\t\t\tcurve instanceof QuadraticBezierCurve ||\n\t\t\t\tcurve instanceof LineCurve\n\t\t\t) {\n\t\t\t\tcurve.getPoint(d / resolution, currentv2);\n\t\t\t\tcurrent.set(currentv2.x, currentv2.y, 0);\n\t\t\t\tif (last?.equals(current)) continue; // remove duplicates\n\t\t\t\tif (last === undefined) {\n\t\t\t\t\tlast = tempaV3;\n\t\t\t\t} else {\n\t\t\t\t\tpositions.setXYZ(index, last.x, last.y, last.z);\n\t\t\t\t\tindex++;\n\t\t\t\t\tpositions.setXYZ(index, current.x, current.y, current.z);\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\t\t\tlast.copy(current);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (\n\t\tautoClose &&\n\t\tindex > 1 &&\n\t\t!(\n\t\t\tpositions.getX(index - 1) === positions.getX(0) &&\n\t\t\tpositions.getY(index - 1) === positions.getY(0) &&\n\t\t\tpositions.getZ(index - 1) === positions.getZ(0)\n\t\t)\n\t) {\n\t\tpositions.setXYZ(\n\t\t\tindex,\n\t\t\tpositions.getX(0),\n\t\t\tpositions.getY(0),\n\t\t\tpositions.getZ(0)\n\t\t);\n\t\tindex++;\n\t}\n\treturn curveDivisions;\n}\n\nexport function getCurvesDivisionsFromPoints(\n\tpoints: BezierPoint[],\n\tdivisions: number = 12,\n\tincludeRoundedCorners: boolean = false\n) {\n\tconst curveDivisions: number[] = [];\n\tfor (let i = 0, l = points.length; i < l; i++) {\n\t\tconst p = points[i];\n\t\tlet d = 0;\n\t\tif (includeRoundedCorners && p.roundedCurveCorner !== undefined) {\n\t\t\tconst c = getCurveDivision(p.roundedCurveCorner, divisions) * 0.5;\n\t\t\tif (i > 0) {\n\t\t\t\tcurveDivisions[i - 1] += c;\n\t\t\t}\n\t\t\td += c;\n\t\t}\n\t\tif (p.curveAfter !== undefined) {\n\t\t\td += getCurveDivision(p.curveAfter, divisions);\n\t\t}\n\t\tcurveDivisions.push(d);\n\t}\n\tif (\n\t\tpoints.length > 0 &&\n\t\tincludeRoundedCorners &&\n\t\tpoints[0].roundedCurveCorner !== undefined\n\t) {\n\t\tcurveDivisions[points.length - 1] +=\n\t\t\tgetCurveDivision(points[0].roundedCurveCorner, divisions) * 0.5;\n\t}\n\treturn curveDivisions;\n}\n\nexport function getCurvesDivisions(\n\tcurves: TCurves[],\n\tdivisions: number = 12\n): number[] {\n\tconst curveDivisions: number[] = [];\n\n\tfor (let i = 0; i < curves.length; i++) {\n\t\tcurveDivisions.push(getCurveDivision(curves[i], divisions));\n\t}\n\n\treturn curveDivisions;\n}\n\nexport function getCurveDivision(\n\tcurve: TCurves,\n\tdivisions: number = 12\n): number {\n\treturn curve && curve instanceof EllipseCurve\n\t\t? divisions * 2\n\t\t: curve && (curve instanceof LineCurve || curve instanceof LineCurve3)\n\t\t? 1\n\t\t: curve && curve instanceof SplineCurve\n\t\t? divisions * curve.points.length\n\t\t: divisions;\n}\n\nexport function pointsToFlatArray(\n\tpositions: number[],\n\tcurves: TCurves[],\n\tdivisions: number = 12,\n\tautoClose: boolean = true\n): number[] {\n\tlet last: Vector2 | undefined;\n\tlet index = 0;\n\n\tfor (let i = 0; i < curves.length; i++) {\n\t\tconst curve = toTCurve(curves[i]);\n\t\tconst resolution = getCurveDivision(curve, divisions);\n\n\t\tconst current = tempaV2;\n\t\tfor (let d = 0; d <= resolution; d++) {\n\t\t\tif (\n\t\t\t\tcurve instanceof CubicBezierCurve ||\n\t\t\t\tcurve instanceof QuadraticBezierCurve ||\n\t\t\t\tcurve instanceof LineCurve\n\t\t\t) {\n\t\t\t\tcurve.getPoint(d / resolution, current);\n\n\t\t\t\t// remove duplicates, we need a custom bigger epsilon because of curve interpolation rounding errors\n\t\t\t\tif (\n\t\t\t\t\tlast !== undefined &&\n\t\t\t\t\tvector2Equal(last, current, ROUNDED_CURVE_NORMAL_EPSILON)\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (last === undefined) last = tempbV2;\n\t\t\t\tlast.copy(current);\n\t\t\t\tpositions.push(current.x, current.y);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove first/last duplicate if any\n\tif (\n\t\tfloatEqual(\n\t\t\tpositions[0],\n\t\t\tpositions[positions.length - 2],\n\t\t\tROUNDED_CURVE_NORMAL_EPSILON\n\t\t) &&\n\t\tfloatEqual(\n\t\t\tpositions[1],\n\t\t\tpositions[positions.length - 1],\n\t\t\tROUNDED_CURVE_NORMAL_EPSILON\n\t\t)\n\t) {\n\t\tpositions.pop();\n\t\tpositions.pop();\n\t}\n\n\tif (\n\t\tautoClose &&\n\t\tindex > 1 &&\n\t\t!(\n\t\t\tfloatEqual(\n\t\t\t\tpositions[index - 1],\n\t\t\t\tpositions[1],\n\t\t\t\tROUNDED_CURVE_NORMAL_EPSILON\n\t\t\t) &&\n\t\t\tfloatEqual(\n\t\t\t\tpositions[index - 2],\n\t\t\t\tpositions[0],\n\t\t\t\tROUNDED_CURVE_NORMAL_EPSILON\n\t\t\t)\n\t\t)\n\t) {\n\t\tpositions.push(positions[0], positions[1]);\n\t\tindex++;\n\t}\n\treturn positions;\n}\n", "const TAU = Math.PI * 2;\n\ntype Point = { x: number; y: number };\n\nexport type Curve = {\n\tx: number;\n\ty: number;\n\tx1: number;\n\ty1: number;\n\tx2: number;\n\ty2: number;\n};\n\nfunction mapToEllipse(\n\t{ x, y }: Point,\n\trx: number,\n\try: number,\n\tcenterx: number,\n\tcentery: number\n): Point {\n\treturn {\n\t\tx: x * rx + centerx,\n\t\ty: y * ry + centery,\n\t};\n}\n\nfunction approxUnitArc(ang1: number, ang2: number): [Point, Point, Point] {\n\t// If 90 degree circular arc, use a constant\n\t// as derived from http://spencermortensen.com/articles/bezier-circle\n\tconst a =\n\t\tang2 === 1.5707963267948966\n\t\t\t? 0.551915024494\n\t\t\t: ang2 === -1.5707963267948966\n\t\t\t? -0.551915024494\n\t\t\t: (4 / 3) * Math.tan(ang2 / 4);\n\n\tconst x1 = Math.cos(ang1);\n\tconst y1 = Math.sin(ang1);\n\tconst x2 = Math.cos(ang1 + ang2);\n\tconst y2 = Math.sin(ang1 + ang2);\n\n\treturn [\n\t\t{\n\t\t\tx: x1 - y1 * a,\n\t\t\ty: y1 + x1 * a,\n\t\t},\n\t\t{\n\t\t\tx: x2 + y2 * a,\n\t\t\ty: y2 - x2 * a,\n\t\t},\n\t\t{\n\t\t\tx: x2,\n\t\t\ty: y2,\n\t\t},\n\t];\n}\n\nfunction vectorAngle(ux: number, uy: number, vx: number, vy: number): number {\n\tconst sign = ux * vy - uy * vx < 0 ? -1 : 1;\n\tconst dot = Math.min(1, Math.max(-1, ux * vx + uy * vy));\n\treturn sign * Math.acos(dot);\n}\n\nfunction getArcCenter(\n\tpx: number,\n\tpy: number,\n\tcx: number,\n\tcy: number,\n\trx: number,\n\try: number,\n\tpxp: number,\n\tpyp: number,\n\tlargeArcFlag: boolean,\n\tsweepFlag: boolean\n): { centerx: number; centery: number; ang1: number; ang2: number } {\n\tconst rxsq = Math.pow(rx, 2);\n\tconst rysq = Math.pow(ry, 2);\n\tconst pxpsq = Math.pow(pxp, 2);\n\tconst pypsq = Math.pow(pyp, 2);\n\n\tlet radicant = rxsq * rysq - rxsq * pypsq - rysq * pxpsq;\n\n\tif (radicant < 0) {\n\t\tradicant = 0;\n\t}\n\n\tradicant /= rxsq * pypsq + rysq * pxpsq;\n\tradicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);\n\n\tconst centerxp = ((radicant * rx) / ry) * pyp;\n\tconst centeryp = ((radicant * -ry) / rx) * pxp;\n\n\tconst centerx = centerxp + (px + cx) / 2;\n\tconst centery = centeryp + (py + cy) / 2;\n\n\tconst vx1 = (pxp - centerxp) / rx;\n\tconst vy1 = (pyp - centeryp) / ry;\n\tconst vx2 = (-pxp - centerxp) / rx;\n\tconst vy2 = (-pyp - centeryp) / ry;\n\n\tconst ang1 = vectorAngle(1, 0, vx1, vy1);\n\tlet ang2 = vectorAngle(vx1, vy1, vx2, vy2);\n\n\tif (!sweepFlag && ang2 > 0) {\n\t\tang2 -= TAU;\n\t}\n\n\tif (sweepFlag && ang2 < 0) {\n\t\tang2 += TAU;\n\t}\n\n\treturn { centerx, centery, ang1, ang2 };\n}\n\nexport function arcToBezier({\n\tpx,\n\tpy,\n\tcx,\n\tcy,\n\trx,\n\try,\n\tlargeArcFlag,\n\tsweepFlag,\n}: {\n\tpx: number;\n\tpy: number;\n\tcx: number;\n\tcy: number;\n\trx: number;\n\try: number;\n\tlargeArcFlag: boolean;\n\tsweepFlag: boolean;\n}): Curve[] {\n\tconst curves = [];\n\n\tif (rx === 0 || ry === 0) {\n\t\treturn [];\n\t}\n\n\tconst pxp = (px - cx) / 2;\n\tconst pyp = (py - cy) / 2;\n\n\tif (pxp === 0 && pyp === 0) {\n\t\treturn [];\n\t}\n\n\trx = Math.abs(rx);\n\try = Math.abs(ry);\n\n\tconst lambda =\n\t\tMath.pow(pxp, 2) / Math.pow(rx, 2) + Math.pow(pyp, 2) / Math.pow(ry, 2);\n\n\tif (lambda > 1) {\n\t\trx *= Math.sqrt(lambda);\n\t\try *= Math.sqrt(lambda);\n\t}\n\n\tconst arcCenter = getArcCenter(\n\t\tpx,\n\t\tpy,\n\t\tcx,\n\t\tcy,\n\t\trx,\n\t\try,\n\t\tpxp,\n\t\tpyp,\n\t\tlargeArcFlag,\n\t\tsweepFlag\n\t);\n\tlet { ang1, ang2 } = arcCenter;\n\tconst { centerx, centery } = arcCenter;\n\n\t// If 'ang2' == 90.0000000001, then `ratio` will evaluate to\n\t// 1.0000000001. This causes `segments` to be greater than one, which is an\n\t// unecessary split, and adds extra points to the bezier curve. To alleviate\n\t// this issue, we round to 1.0 when the ratio is close to 1.0.\n\tlet ratio = Math.abs(ang2) / (TAU / 4);\n\tif (Math.abs(1.0 - ratio) < 0.0000001) {\n\t\tratio = 1.0;\n\t}\n\n\tconst segments = Math.max(Math.ceil(ratio), 1);\n\n\tang2 /= segments;\n\n\tfor (let i = 0; i < segments; i++) {\n\t\tcurves.push(approxUnitArc(ang1, ang2));\n\t\tang1 += ang2;\n\t}\n\n\treturn curves.map((curve) => {\n\t\tconst { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, centerx, centery);\n\t\tconst { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, centerx, centery);\n\t\tconst { x, y } = mapToEllipse(curve[2], rx, ry, centerx, centery);\n\n\t\treturn { x1, y1, x2, y2, x, y };\n\t});\n}\n", "import { BufferAttribute, BufferGeometry } from 'three';\nimport { tesselate, WINDING, ELEMENT } from 'tess2-ts';\nimport { VectorShape } from '../../objects/entities/vectors/VectorShape';\nimport { TypedArray } from '../../fileManager';\nimport { cloneDeep } from 'lodash-es';\n\nexport type TriangulationOptions = {\n\twindingRule: WINDING;\n\telementType: ELEMENT;\n\tpolySize: number;\n\tvertexSize: 3 | 2;\n\tstrict: boolean;\n};\nexport class VectorSurfaceGeometry extends BufferGeometry {\n\ttype: string = 'ShapeGeometry';\n\n\twindingRule: WINDING = WINDING.ODD;\n\telementType: ELEMENT = ELEMENT.POLYGONS;\n\tpolySize: number = 3;\n\tvertexSize: 3 | 2 = 2;\n\tstrict: boolean = true;\n\n\tprivate _maxCount: number;\n\tprivate _maxDrawCount: number;\n\tprivate _drawCount: number;\n\n\tprivate _triangulationOptions: TriangulationOptions;\n\tprivate _positionAttribute: BufferAttribute;\n\tprivate _normalAttribute: BufferAttribute;\n\tprivate _uvAttribute: BufferAttribute;\n\tprivate _indexAttribute: BufferAttribute;\n\tprivate _shape: VectorShape;\n\tprivate _curveSegments: number;\n\n\tconstructor(\n\t\tshape: VectorShape,\n\t\tcurveSegments: number = 12,\n\t\tmaxCount: number = 100,\n\t\ttriangulationOptions: Partial<TriangulationOptions> = {}\n\t) {\n\t\tsuper();\n\n\t\tthis._drawCount = 0;\n\t\tthis._shape = shape;\n\t\tthis._curveSegments = curveSegments;\n\t\tthis._maxCount = maxCount;\n\t\tthis._maxDrawCount = maxCount * 3;\n\n\t\tthis._triangulationOptions = Object.assign(\n\t\t\t{\n\t\t\t\twindingRule: WINDING.ODD,\n\t\t\t\telementType: ELEMENT.POLYGONS,\n\t\t\t\tpolySize: 3,\n\t\t\t\tvertexSize: 2,\n\t\t\t\tstrict: true,\n\t\t\t},\n\t\t\ttriangulationOptions\n\t\t);\n\n\t\tthis._positionAttribute = new BufferAttribute(\n\t\t\tnew Float32Array(maxCount * 3),\n\t\t\t3\n\t\t);\n\t\tthis._normalAttribute = new BufferAttribute(\n\t\t\tnew Float32Array(maxCount * 3),\n\t\t\t3\n\t\t);\n\t\tthis._uvAttribute = new BufferAttribute(new Float32Array(maxCount * 2), 2);\n\t\tthis._indexAttribute = new BufferAttribute(\n\t\t\tnew Uint32Array(maxCount * 3),\n\t\t\t1\n\t\t);\n\t\tthis.setAttribute('position', this._positionAttribute);\n\t\tthis.setAttribute('normal', this._normalAttribute);\n\t\tthis.setAttribute('uv', this._uvAttribute);\n\t\tthis.setIndex(this._indexAttribute);\n\n\t\tthis.updateFromShape();\n\t}\n\n\tcopy(source: this): this {\n\t\tthis._drawCount = source.drawCount;\n\t\tthis._maxDrawCount = source._maxDrawCount;\n\t\tthis._maxCount = source.maxCount;\n\t\treturn super.copy(source);\n\t}\n\n\tget curveSegments() {\n\t\treturn this._curveSegments;\n\t}\n\n\tset curveSegments(value: number) {\n\t\tthis._curveSegments = value;\n\t\tthis.updateFromShape();\n\t}\n\n\tget drawCount() {\n\t\treturn this._drawCount;\n\t}\n\n\tget maxDrawCount() {\n\t\treturn this._maxDrawCount;\n\t}\n\n\tget maxCount() {\n\t\treturn this._maxCount;\n\t}\n\n\t/**\n\t * Update in response to imperative changes to this._shape.\n\t * Can fail if maxDrawCount is not high enough.\n\t * @returns whether the update was successful or whether the buffer size needs to be increased.\n\t */\n\tupdateFromShape(): boolean {\n\t\tconst points = this._shape.extractShapePointsToFlatArray(\n\t\t\t[],\n\t\t\tthis._curveSegments\n\t\t);\n\t\tconst holes = this._shape.shapeHoles.map((hole) =>\n\t\t\thole.extractShapePointsToFlatArray([], this._curveSegments)\n\t\t);\n\n\t\tlet res;\n\n\t\t// Check that points are not aligned on a straight line\n\t\tlet areXAligned = true;\n\t\tlet areYAligned = true;\n\t\tlet prevX;\n\t\tlet prevY;\n\t\tfor (let i = 0, l = points.length / 2; i < l; i++) {\n\t\t\tconst i2 = i * 2;\n\t\t\tconst x = points[i2 + 0];\n\t\t\tconst y = points[i2 + 1];\n\t\t\tif (prevX !== undefined && x !== prevX) areXAligned = false;\n\t\t\tif (prevY !== undefined && y !== prevY) areYAligned = false;\n\t\t\tprevX = x;\n\t\t\tprevY = y;\n\n\t\t\tif (!areXAligned && !areYAligned) break;\n\t\t}\n\n\t\t// if points aligned on perfect horizontal or vertical line, don't triangulate them\n\t\tif (!areXAligned && !areYAligned) {\n\t\t\tres = tesselate({\n\t\t\t\tcontours: [points, ...holes],\n\t\t\t\twindingRule: this._triangulationOptions.windingRule,\n\t\t\t\telementType: this._triangulationOptions.elementType,\n\t\t\t\tpolySize: this._triangulationOptions.polySize,\n\t\t\t\tvertexSize: this._triangulationOptions.vertexSize,\n\t\t\t\tstrict: this._triangulationOptions.strict,\n\t\t\t});\n\t\t}\n\n\t\t// Prevent trailing values\n\t\t(this._positionAttribute.array as TypedArray).fill(0);\n\t\t(this._normalAttribute.array as TypedArray).fill(0);\n\t\t(this._uvAttribute.array as TypedArray).fill(0);\n\t\t(this._indexAttribute.array as TypedArray).fill(0);\n\n\t\tthis._drawCount = 0;\n\n\t\tif (res) {\n\t\t\t// Compute 2d bounding box for uvs\n\t\t\tlet minX = Infinity;\n\t\t\tlet maxX = -Infinity;\n\t\t\tlet minY = Infinity;\n\t\t\tlet maxY = -Infinity;\n\t\t\tfor (let i = 0, l = res.vertexCount; i < l; i++) {\n\t\t\t\tconst i2 = i * 2;\n\t\t\t\tconst x = res.vertices[i2 + 0];\n\t\t\t\tconst y = res.vertices[i2 + 1];\n\t\t\t\tif (x < minX) minX = x;\n\t\t\t\tif (x > maxX) maxX = x;\n\t\t\t\tif (y < minY) minY = y;\n\t\t\t\tif (y > maxY) maxY = y;\n\t\t\t}\n\t\t\tconst width = maxX - minX;\n\t\t\tconst height = maxY - minY;\n\t\t\t// set attributes\n\t\t\tfor (let i = 0, l = res.vertexCount; i < l; i++) {\n\t\t\t\tconst i2 = i * 2;\n\t\t\t\tconst x = res.vertices[i2 + 0];\n\t\t\t\tconst y = res.vertices[i2 + 1];\n\t\t\t\tconst u = (x - minX) / width;\n\t\t\t\tconst v = (y - minY) / height;\n\t\t\t\tthis._positionAttribute.setXYZ(i, x, y, 0);\n\t\t\t\tthis._normalAttribute.setXYZ(i, 0, 0, 1);\n\t\t\t\tthis._uvAttribute.setXY(i, u, v);\n\t\t\t}\n\t\t\t// set indexes\n\t\t\tfor (let i = 0, l = res.elementCount; i < l; i++) {\n\t\t\t\tconst i3 = i * 3;\n\t\t\t\tconst a = res.elements[i3 + 0];\n\t\t\t\tconst b = res.elements[i3 + 1];\n\t\t\t\tconst c = res.elements[i3 + 2];\n\t\t\t\tthis._indexAttribute.setX(i3 + 0, a);\n\t\t\t\tthis._indexAttribute.setX(i3 + 1, b);\n\t\t\t\tthis._indexAttribute.setX(i3 + 2, c);\n\t\t\t\tthis._drawCount += 3;\n\t\t\t}\n\t\t}\n\n\t\tthis._positionAttribute.needsUpdate = true;\n\t\tthis._normalAttribute.needsUpdate = true;\n\t\tthis._uvAttribute.needsUpdate = true;\n\t\tthis._indexAttribute.needsUpdate = true;\n\t\tthis.setDrawRange(0, this._drawCount);\n\n\t\treturn this._drawCount > this._maxDrawCount;\n\t}\n\n\tclone(): BufferGeometry {\n\t\tconst geom = new VectorSurfaceGeometry(\n\t\t\tthis._shape,\n\t\t\tthis._curveSegments,\n\t\t\tthis._maxCount\n\t\t);\n\t\tgeom.userData = cloneDeep(this.userData);\n\t\treturn geom as BufferGeometry;\n\t}\n}\n", "export enum WINDING{\r\n\tODD = 0,\r\n\tNONZERO = 1,\r\n\tPOSITIVE = 2,\r\n\tNEGATIVE = 3,\r\n\tABS_GEQ_TWO = 4,\r\n};\r\n\r\nexport enum ELEMENT {\r\n\tPOLYGONS = 0,\r\n\tCONNECTED_POLYGONS = 1,\r\n\tBOUNDARY_CONTOURS = 2,\r\n};\r\n", "export function assert (cond: any, message?: string) {\r\n\tif (!cond) {\r\n\t\tthrow message || \"Assertion Failed!\";\r\n\t}\r\n};", "import {assert} from \"./../utils/assert\";\r\nimport { TESSvertex, TESShalfEdge } from \"../mesh/index\";\r\n\r\nexport class Geom {\r\n\r\n\tstatic vertEq (u: TESSvertex, v: TESSvertex) {\r\n\t\treturn u.s === v.s && u.t === v.t;\r\n\t}\r\n\r\n\t/* Returns TRUE if u is lexicographically <= v. */\r\n\tstatic vertLeq(u: TESSvertex, v: TESSvertex) {\r\n\t\treturn u.s < v.s || (u.s === v.s && u.t <= v.t);\r\n\t}\r\n\r\n\t/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */\r\n\tstatic transLeq(u: TESSvertex, v: TESSvertex) {\r\n\t\treturn u.t < v.t || (u.t === v.t && u.s <= v.s);\r\n\t}\r\n\r\n\tstatic edgeGoesLeft(e: TESShalfEdge) {\r\n\t\treturn Geom.vertLeq(e.Dst, e.Org);\r\n\t}\r\n\r\n\tstatic edgeGoesRight(e: TESShalfEdge) {\r\n\t\treturn Geom.vertLeq(e.Org, e.Dst);\r\n\t}\r\n\r\n\tstatic vertL1dist(u: TESSvertex, v: TESSvertex) {\r\n\t\treturn Math.abs(u.s - v.s) + Math.abs(u.t - v.t);\r\n\t}\r\n\r\n\t//TESSreal tesedgeEval( TESSvertex *u, TESSvertex *v, TESSvertex *w )\r\n\tstatic edgeEval(u: TESSvertex, v: TESSvertex, w: TESSvertex) {\r\n\t\t/* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),\r\n\t\t * evaluates the t-coord of the edge uw at the s-coord of the vertex v.\r\n\t\t * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.\r\n\t\t * If uw is vertical (and thus passes thru v), the result is zero.\r\n\t\t *\r\n\t\t * The calculation is extremely accurate and stable, even when v\r\n\t\t * is very close to u or w. In particular if we set v->t = 0 and\r\n\t\t * let r be the negated result (this evaluates (uw)(v->s)), then\r\n\t\t * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).\r\n\t\t */\r\n\t\tassert(Geom.vertLeq(u, v) && Geom.vertLeq(v, w));\r\n\r\n\t\tvar gapL = v.s - u.s;\r\n\t\tvar gapR = w.s - v.s;\r\n\r\n\t\tif (gapL + gapR > 0.0) {\r\n\t\t\tif (gapL < gapR) {\r\n\t\t\t\treturn v.t - u.t + (u.t - w.t) * (gapL / (gapL + gapR));\r\n\t\t\t} else {\r\n\t\t\t\treturn v.t - w.t + (w.t - u.t) * (gapR / (gapL + gapR));\r\n\t\t\t}\r\n\t\t}\r\n\t\t/* vertical line */\r\n\t\treturn 0.0;\r\n\t}\r\n\r\n\t//TESSreal tesedgeSign( TESSvertex *u, TESSvertex *v, TESSvertex *w )\r\n\tstatic edgeSign(u: TESSvertex, v: TESSvertex, w: TESSvertex) {\r\n\t\t/* Returns a number whose sign matches EdgeEval(u,v,w) but which\r\n\t\t * is cheaper to evaluate. Returns > 0, == 0 , or < 0\r\n\t\t * as v is above, on, or below the edge uw.\r\n\t\t */\r\n\t\tassert(Geom.vertLeq(u, v) && Geom.vertLeq(v, w));\r\n\r\n\t\tvar gapL = v.s - u.s;\r\n\t\tvar gapR = w.s - v.s;\r\n\r\n\t\tif (gapL + gapR > 0.0) {\r\n\t\t\treturn (v.t - w.t) * gapL + (v.t - u.t) * gapR;\r\n\t\t}\r\n\t\t/* vertical line */\r\n\t\treturn 0.0;\r\n\t}\r\n\r\n\t/***********************************************************************\r\n\t * Define versions of EdgeSign, EdgeEval with s and t transposed.\r\n\t */\r\n\r\n\t//TESSreal testransEval( TESSvertex *u, TESSvertex *v, TESSvertex *w )\r\n\tstatic transEval(u: TESSvertex, v: TESSvertex, w: TESSvertex) {\r\n\t\t/* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),\r\n\t\t * evaluates the t-coord of the edge uw at the s-coord of the vertex v.\r\n\t\t * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.\r\n\t\t * If uw is vertical (and thus passes thru v), the result is zero.\r\n\t\t *\r\n\t\t * The calculation is extremely accurate and stable, even when v\r\n\t\t * is very close to u or w. In particular if we set v->s = 0 and\r\n\t\t * let r be the negated result (this evaluates (uw)(v->t)), then\r\n\t\t * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).\r\n\t\t */\r\n\t\tassert(Geom.transLeq(u, v) && Geom.transLeq(v, w));\r\n\r\n\t\tvar gapL = v.t - u.t;\r\n\t\tvar gapR = w.t - v.t;\r\n\r\n\t\tif (gapL + gapR > 0.0) {\r\n\t\t\tif (gapL < gapR) {\r\n\t\t\t\treturn v.s - u.s + (u.s - w.s) * (gapL / (gapL + gapR));\r\n\t\t\t} else {\r\n\t\t\t\treturn v.s - w.s + (w.s - u.s) * (gapR / (gapL + gapR));\r\n\t\t\t}\r\n\t\t}\r\n\t\t/* vertical line */\r\n\t\treturn 0.0;\r\n\t}\r\n\r\n\t//TESSreal testransSign( TESSvertex *u, TESSvertex *v, TESSvertex *w )\r\n\tstatic transSign(u: TESSvertex, v: TESSvertex, w: TESSvertex) {\r\n\t\t/* Returns a number whose sign matches TransEval(u,v,w) but which\r\n\t\t * is cheaper to evaluate. Returns > 0, == 0 , or < 0\r\n\t\t * as v is above, on, or below the edge uw.\r\n\t\t */\r\n\t\tassert(Geom.transLeq(u, v) && Geom.transLeq(v, w));\r\n\r\n\t\tvar gapL = v.t - u.t;\r\n\t\tvar gapR = w.t - v.t;\r\n\r\n\t\tif (gapL + gapR > 0.0) {\r\n\t\t\treturn (v.s - w.s) * gapL + (v.s - u.s) * gapR;\r\n\t\t}\r\n\t\t/* vertical line */\r\n\t\treturn 0.0;\r\n\t}\r\n\r\n\t//int tesvertCCW( TESSvertex *u, TESSvertex *v, TESSvertex *w )\r\n\tstatic vertCCW(u: TESSvertex, v: TESSvertex, w: TESSvertex) {\r\n\t\t/* For almost-degenerate situations, the results are not reliable.\r\n\t\t * Unless the floating-point arithmetic can be performed without\r\n\t\t * rounding errors, *any* implementation will give incorrect results\r\n\t\t * on some degenerate inputs, so the client must have some way to\r\n\t\t * handle this situation.\r\n\t\t */\r\n\t\treturn u.s * (v.t - w.t) + v.s * (w.t - u.t) + w.s * (u.t - v.t) >= 0.0;\r\n\t}\r\n\r\n\t/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),\r\n\t * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces\r\n\t * this in the rare case that one argument is slightly negative.\r\n\t * The implementation is extremely stable numerically.\r\n\t * In particular it guarantees that the result r satisfies\r\n\t * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate\r\n\t * even when a and b differ greatly in magnitude.\r\n\t */\r\n\tstatic interpolate(a: number, x:number, b:number, y:number) {\r\n\t\treturn (\r\n\t\t\t(a = a < 0 ? 0 : a),\r\n\t\t\t(b = b < 0 ? 0 : b),\r\n\t\t\ta <= b\r\n\t\t\t\t? b === 0\r\n\t\t\t\t\t? (x + y) / 2\r\n\t\t\t\t\t: x + (y - x) * (a / (a + b))\r\n\t\t\t\t: y + (x - y) * (b / (a + b))\r\n\t\t);\r\n\t}\r\n\r\n\t/*\r\n\t#ifndef FOR_TRITE_TEST_PROGRAM\r\n\t#define Interpolate(a,x,b,y)\tRealInterpolate(a,x,b,y)\r\n\t#else\r\n\r\n\t// Claim: the ONLY property the sweep algorithm relies on is that\r\n\t// MIN(x,y) <= r <= MAX(x,y). This is a nasty way to test that.\r\n\t#include <stdlib.h>\r\n\textern int RandomInterpolate;\r\n\r\n\tdouble Interpolate( double a, double x, double b, double y)\r\n\t{\r\n\t\tprintf(\"*********************%d\\n\",RandomInterpolate);\r\n\t\tif( RandomInterpolate ) {\r\n\t\t\ta = 1.2 * drand48() - 0.1;\r\n\t\t\ta = (a < 0) ? 0 : ((a > 1) ? 1 : a);\r\n\t\t\tb = 1.0 - a;\r\n\t\t}\r\n\t\treturn RealInterpolate(a,x,b,y);\r\n\t}\r\n\t#endif*/\r\n\r\n\tstatic intersect(o1: TESSvertex, d1: TESSvertex, o2: TESSvertex, d2:TESSvertex, v: TESSvertex) {\r\n\t\t/* Given edges (o1,d1) and (o2,d2), compute their point of intersection.\r\n\t\t * The computed point is guaranteed to lie in the intersection of the\r\n\t\t * bounding rectangles defined by each edge.\r\n\t\t */\r\n\t\tvar z1, z2;\r\n\t\tvar t;\r\n\r\n\t\t/* This is certainly not the most efficient way to find the intersection\r\n\t\t * of two line segments, but it is very numerically stable.\r\n\t\t *\r\n\t\t * Strategy: find the two middle vertices in the VertLeq ordering,\r\n\t\t * and interpolate the intersection s-value from these. Then repeat\r\n\t\t * using the TransLeq ordering to find the intersection t-value.\r\n\t\t */\r\n\r\n\t\tif (!Geom.vertLeq(o1, d1)) {\r\n\t\t\tt = o1;\r\n\t\t\to1 = d1;\r\n\t\t\td1 = t;\r\n\t\t} //swap( o1, d1 ); }\r\n\t\tif (!Geom.vertLeq(o2, d2)) {\r\n\t\t\tt = o2;\r\n\t\t\to2 = d2;\r\n\t\t\td2 = t;\r\n\t\t} //swap( o2, d2 ); }\r\n\t\tif (!Geom.vertLeq(o1, o2)) {\r\n\t\t\tt = o1;\r\n\t\t\to1 = o2;\r\n\t\t\to2 = t;\r\n\t\t\tt = d1;\r\n\t\t\td1 = d2;\r\n\t\t\td2 = t;\r\n\t\t} //swap( o1, o2 ); swap( d1, d2 ); }\r\n\r\n\t\tif (!Geom.vertLeq(o2, d1)) {\r\n\t\t\t/* Technically, no intersection -- do our best */\r\n\t\t\tv.s = (o2.s + d1.s) / 2;\r\n\t\t} else if (Geom.vertLeq(d1, d2)) {\r\n\t\t\t/* Interpolate between o2 and d1 */\r\n\t\t\tz1 = Geom.edgeEval(o1, o2, d1);\r\n\t\t\tz2 = Geom.edgeEval(o2, d1, d2);\r\n\t\t\tif (z1 + z2 < 0) {\r\n\t\t\t\tz1 = -z1;\r\n\t\t\t\tz2 = -z2;\r\n\t\t\t}\r\n\t\t\tv.s = Geom.interpolate(z1, o2.s, z2, d1.s);\r\n\t\t} else {\r\n\t\t\t/* Interpolate between o2 and d2 */\r\n\t\t\tz1 = Geom.edgeSign(o1, o2, d1);\r\n\t\t\tz2 = -Geom.edgeSign(o1, d2, d1);\r\n\t\t\tif (z1 + z2 < 0) {\r\n\t\t\t\tz1 = -z1;\r\n\t\t\t\tz2 = -z2;\r\n\t\t\t}\r\n\t\t\tv.s = Geom.interpolate(z1, o2.s, z2, d2.s);\r\n\t\t}\r\n\r\n\t\t/* Now repeat the process for t */\r\n\r\n\t\tif (!Geom.transLeq(o1, d1)) {\r\n\t\t\tt = o1;\r\n\t\t\to1 = d1;\r\n\t\t\td1 = t;\r\n\t\t} //swap( o1, d1 ); }\r\n\t\tif (!Geom.transLeq(o2, d2)) {\r\n\t\t\tt = o2;\r\n\t\t\to2 = d2;\r\n\t\t\td2 = t;\r\n\t\t} //swap( o2, d2 ); }\r\n\t\tif (!Geom.transLeq(o1, o2)) {\r\n\t\t\tt = o1;\r\n\t\t\to1 = o2;\r\n\t\t\to2 = t;\r\n\t\t\tt = d1;\r\n\t\t\td1 = d2;\r\n\t\t\td2 = t;\r\n\t\t} //swap( o1, o2 ); swap( d1, d2 ); }\r\n\r\n\t\tif (!Geom.transLeq(o2, d1)) {\r\n\t\t\t/* Technically, no intersection -- do our best */\r\n\t\t\tv.t = (o2.t + d1.t) / 2;\r\n\t\t} else if (Geom.transLeq(d1, d2)) {\r\n\t\t\t/* Interpolate between o2 and d1 */\r\n\t\t\tz1 = Geom.transEval(o1, o2, d1);\r\n\t\t\tz2 = Geom.transEval(o2, d1, d2);\r\n\t\t\tif (z1 + z2 < 0) {\r\n\t\t\t\tz1 = -z1;\r\n\t\t\t\tz2 = -z2;\r\n\t\t\t}\r\n\t\t\tv.t = Geom.interpolate(z1, o2.t, z2, d1.t);\r\n\t\t} else {\r\n\t\t\t/* Interpolate between o2 and d2 */\r\n\t\t\tz1 = Geom.transSign(o1, o2, d1);\r\n\t\t\tz2 = -Geom.transSign(o1, d2, d1);\r\n\t\t\tif (z1 + z2 < 0) {\r\n\t\t\t\tz1 = -z1;\r\n\t\t\t\tz2 = -z2;\r\n\t\t\t}\r\n\t\t\tv.t = Geom.interpolate(z1, o2.t, z2, d2.t);\r\n\t\t}\r\n\t}\r\n}\r\n", "import { TESShalfEdge } from './TESShalfEdge';\r\nexport class TESSface {\r\n\tnext: TESSface = null; /* next face (never NULL) */\r\n\tprev: TESSface = null; /* previous face (never NULL) */\r\n\tanEdge: TESShalfEdge = null; /* a half edge with this left face */\r\n\r\n\t/* Internal data (keep hidden) */\r\n\ttrail: any = null; /* \"stack\" for conversion to strips */\r\n\tn: number = 0; /* to allow identiy unique faces */\r\n\tmarked: boolean = false; /* flag for conversion to strips */\r\n\tinside: boolean = false; /* this face is in the polygon interior */\r\n}", "import { ActiveRegion } from './ActiveRegion';\r\nimport { TESSface } from './TESSface';\r\ntype TESSVertex = any;\r\n\r\nexport class TESShalfEdge {\r\n\r\n\tnext: TESShalfEdge = null; /* doubly-linked list (prev==Sym->next) */\r\n\tOrg: TESSVertex= null; /* origin vertex (Overtex too long) */\r\n\tSym: TESShalfEdge = null; /* same edge, opposite direction */\r\n\tOnext: TESShalfEdge= null; /* next edge CCW around origin */\r\n\tLnext: TESShalfEdge = null; /* next edge CCW around left face */\r\n\tLface: TESSface = null; /* left face */\r\n\r\n\t/* Internal data (keep hidden) */\r\n\tactiveRegion: ActiveRegion = null; /* a region with this upper edge (sweep.c) */\r\n\twinding: number = 0; /* change in winding number when crossing from the right face to the left face */\r\n\r\n\tconstructor(public side: number) { };\r\n\r\n\tget Rface() {\r\n\t\treturn this.Sym!.Lface;\r\n\t}\r\n\r\n\tset Rface(v: TESSface) {\r\n\t\tthis.Sym!.Lface = v;\r\n\t}\r\n\r\n\tget Dst() {\r\n\t\treturn this.Sym!.Org;\r\n\t}\r\n\r\n\tset Dst(v) {\r\n\t\tthis.Sym!.Org = v;\r\n\t}\r\n\r\n\tget Oprev() {\r\n\t\treturn this.Sym!.Lnext;\r\n\t}\r\n\r\n\tset Oprev(v: TESShalfEdge) {\r\n\t\tthis.Sym!.Lnext = v;\r\n\t}\r\n\r\n\tget Lprev() {\r\n\t\treturn this.Onext!.Sym;\r\n\t}\r\n\tset Lprev(v) {\r\n\t\tthis.Onext!.Sym = v;\r\n\t}\r\n\r\n\tget Dprev() {\r\n\t\treturn this.Lnext!.Sym;\r\n\t}\r\n\r\n\tset Dprev(v) {\r\n\t\tthis.Lnext!.Sym = v;\r\n\t}\r\n\tget Rprev() {\r\n\t\treturn this.Sym!.Onext;\r\n\t}\r\n\tset Rprev(v) {\r\n\t\tthis.Sym!.Onext = v;\r\n\t}\r\n\tget Dnext() {\r\n\t\treturn this.Sym!.Onext!.Sym;\r\n\t}\r\n\tset Dnext(v) {\r\n\t\tthis.Sym!.Onext!.Sym = v;\r\n\t}\r\n\tget Rnext() {\r\n\t\treturn this.Sym!.Lnext!.Sym;\r\n\t}\r\n\tset Rnext(v) {\r\n\t\tthis.Sym!.Lnext!.Sym = v;\r\n\t}\r\n};", "import { TESShalfEdge } from './TESShalfEdge';\r\n\r\nexport class TESSvertex {\r\n\tnext: TESSvertex = null; /* next vertex (never NULL) */\r\n\tprev: TESSvertex = null; /* previous vertex (never NULL) */\r\n\tanEdge: TESShalfEdge = null; /* a half-edge with this origin */\r\n\r\n\t/* Internal data (keep hidden) */\r\n\tcoords: [number, number, number] = [0, 0, 0]; /* vertex location in 3D */\r\n\ts: number = 0.0;\r\n\tt: number = 0.0; /* projection onto the sweep plane */\r\n\tpqHandle: number = 0; /* to allow deletion from priority queue */\r\n\tn: number = 0; /* to allow identify unique vertices */\r\n\tidx: number = 0; /* to allow map result to original verts */\r\n}", "import { Geom } from \"../utils/Geom\";\r\nimport { assert } from \"../utils/assert\";\r\nimport { TESSface } from \"./TESSface\";\r\nimport { TESShalfEdge } from \"./TESShalfEdge\";\r\nimport { TESSvertex } from \"./TESSvertex\";\r\n\r\n\r\n/* The mesh operations below have three motivations: completeness,\r\n * convenience, and efficiency. The basic mesh operations are MakeEdge,\r\n * Splice, and Delete. All the other edge operations can be implemented\r\n * in terms of these. The other operations are provided for convenience\r\n * and/or efficiency.\r\n *\r\n * When a face is split or a vertex is added, they are inserted into the\r\n * global list *before* the existing vertex or face (ie. e->Org or e->Lface).\r\n * This makes it easier to process all vertices or faces in the global lists\r\n * without worrying about processing the same data twice. As a convenience,\r\n * when a face is split, the \"inside\" flag is copied from the old face.\r\n * Other internal data (v->data, v->activeRegion, f->data, f->marked,\r\n * f->trail, e->winding) is set to zero.\r\n *\r\n * ********************** Basic Edge Operations **************************\r\n *\r\n * tessMeshMakeEdge( mesh ) creates one edge, two vertices, and a loop.\r\n * The loop (face) consists of the two new half-edges.\r\n *\r\n * tessMeshSplice( eOrg, eDst ) is the basic operation for changing the\r\n * mesh connectivity and topology. It changes the mesh so that\r\n * eOrg->Onext <- OLD( eDst->Onext )\r\n * eDst->Onext <- OLD( eOrg->Onext )\r\n * where OLD(...) means the value before the meshSplice operation.\r\n *\r\n * This can have two effects on the vertex structure:\r\n * - if eOrg->Org != eDst->Org, the two vertices are merged together\r\n * - if eOrg->Org == eDst->Org, the origin is split into two vertices\r\n * In both cases, eDst->Org is changed and eOrg->Org is untouched.\r\n *\r\n * Similarly (and independently) for the face structure,\r\n * - if eOrg->Lface == eDst->Lface, one loop is split into two\r\n * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one\r\n * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.\r\n *\r\n * tessMeshDelete( eDel ) removes the edge eDel. There are several cases:\r\n * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop\r\n * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;\r\n * the newly created loop will contain eDel->Dst. If the deletion of eDel\r\n * would create isolated vertices, those are deleted as well.\r\n *\r\n * ********************** Other Edge Operations **************************\r\n *\r\n * tessMeshAddEdgeVertex( eOrg ) creates a new edge eNew such that\r\n * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.\r\n * eOrg and eNew will have the same left face.\r\n *\r\n * tessMeshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,\r\n * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.\r\n * eOrg and eNew will have the same left face.\r\n *\r\n * tessMeshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst\r\n * to eDst->Org, and returns the corresponding half-edge eNew.\r\n * If eOrg->Lface == eDst->Lface, this splits one loop into two,\r\n * and the newly created loop is eNew->Lface. Otherwise, two disjoint\r\n * loops are merged into one, and the loop eDst->Lface is destroyed.\r\n *\r\n * ************************ Other Operations *****************************\r\n *\r\n * tessMeshNewMesh() creates a new mesh with no edges, no vertices,\r\n * and no loops (what we usually call a \"face\").\r\n *\r\n * tessMeshUnion( mesh1, mesh2 ) forms the union of all structures in\r\n * both meshes, and returns the new mesh (the old meshes are destroyed).\r\n *\r\n * tessMeshDeleteMesh( mesh ) will free all storage for any valid mesh.\r\n *\r\n * tessMeshZapFace( fZap ) destroys a face and removes it from the\r\n * global face list. All edges of fZap will have a NULL pointer as their\r\n * left face. Any edges which also have a NULL pointer as their right face\r\n * are deleted entirely (along with any isolated vertices this produces).\r\n * An entire mesh can be deleted by zapping its faces, one at a time,\r\n * in any order. Zapped faces cannot be used in further mesh operations!\r\n *\r\n * tessMeshCheckMesh( mesh ) checks a mesh for self-consistency.\r\n */\r\nexport class TESSmesh {\r\n\tvHead: TESSvertex; /* dummy header for vertex list */\r\n\tfHead: TESSface; /* dummy header for face list */\r\n\teHead: TESShalfEdge; /* dummy header for edge list */\r\n\teHeadSym: TESShalfEdge; /* and its symmetric counterpart */\r\n\r\n\tconstructor() {\r\n\t\tconst v = new TESSvertex();\r\n\t\tconst f = new TESSface();\r\n\t\tconst e = new TESShalfEdge(0);\r\n\t\tconst eSym = new TESShalfEdge(1);\r\n\r\n\t\tv.next = v.prev = v;\r\n\t\tv.anEdge = null;\r\n\r\n\t\tf.next = f.prev = f;\r\n\r\n\t\te.next = e;\r\n\t\te.Sym = eSym;\r\n\r\n\t\teSym.next = eSym;\r\n\t\teSym.Sym = e;\r\n\r\n\t\tthis.vHead = v;\r\n\t\tthis.fHead = f;\r\n\t\tthis.eHead = e;\r\n\t\tthis.eHeadSym = eSym;\r\n\t}\r\n\r\n\t/* MakeEdge creates a new pair of half-edges which form their own loop.\r\n\t * No vertex or face structures are allocated, but these must be assigned\r\n\t * before the current edge operation is completed.\r\n\t */\r\n\t//static TESShalfEdge *MakeEdge( TESSmesh* mesh, TESShalfEdge *eNext )\r\n\tmakeEdge_(eNext: TESShalfEdge) {\r\n\t\tvar e = new TESShalfEdge(0);\r\n\t\tvar eSym = new TESShalfEdge(1);\r\n\r\n\t\t/* Make sure eNext points to the first edge of the edge pair */\r\n\t\tif (eNext.Sym.side < eNext.side) {\r\n\t\t\teNext = eNext.Sym;\r\n\t\t}\r\n\r\n\t\t/* Insert in circular doubly-linked list before eNext.\r\n\t\t * Note that the prev pointer is stored in Sym->next.\r\n\t\t */\r\n\t\tvar ePrev = eNext.Sym.next;\r\n\t\teSym.next = ePrev;\r\n\t\tePrev.Sym.next = e;\r\n\t\te.next = eNext;\r\n\t\teNext.Sym.next = eSym;\r\n\r\n\t\te.Sym = eSym;\r\n\t\te.Onext = e;\r\n\t\te.Lnext = eSym;\r\n\t\te.Org = null;\r\n\t\te.Lface = null;\r\n\t\te.winding = 0;\r\n\t\te.activeRegion = null;\r\n\r\n\t\teSym.Sym = e;\r\n\t\teSym.Onext = eSym;\r\n\t\teSym.Lnext = e;\r\n\t\teSym.Org = null;\r\n\t\teSym.Lface = null;\r\n\t\teSym.winding = 0;\r\n\t\teSym.activeRegion = null;\r\n\r\n\t\treturn e;\r\n\t}\r\n\r\n\t/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the\r\n\t * CS348a notes (see mesh.h). Basically it modifies the mesh so that\r\n\t * a->Onext and b->Onext are exchanged. This can have various effects\r\n\t * depending on whether a and b belong to different face or vertex rings.\r\n\t * For more explanation see tessMeshSplice() below.\r\n\t */\r\n\t// static void Splice( TESShalfEdge *a, TESShalfEdge *b )\r\n\tsplice_(a:TESShalfEdge, b: TESShalfEdge) {\r\n\t\tvar aOnext = a.Onext;\r\n\t\tvar bOnext = b.Onext;\r\n\t\taOnext.Sym.Lnext = b;\r\n\t\tbOnext.Sym.Lnext = a;\r\n\t\ta.Onext = bOnext;\r\n\t\tb.Onext = aOnext;\r\n\t}\r\n\r\n\t/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the\r\n\t * origin of all edges in the vertex loop to which eOrig belongs. \"vNext\" gives\r\n\t * a place to insert the new vertex in the global vertex list. We insert\r\n\t * the new vertex *before* vNext so that algorithms which walk the vertex\r\n\t * list will not see the newly created vertices.\r\n\t */\r\n\t//static void MakeVertex( TESSvertex *newVertex, TESShalfEdge *eOrig, TESSvertex *vNext )\r\n\tmakeVertex_(newVertex: TESSvertex, eOrig: TESShalfEdge, vNext: TESSvertex) {\r\n\t\tvar vNew = newVertex;\r\n\r\n\t\tassert(vNew, \"Vertex can't be null!\");\r\n\r\n\t\t/* insert in circular doubly-linked list before vNext */\r\n\t\tvar vPrev = vNext.prev;\r\n\t\tvNew.prev = vPrev;\r\n\t\tvPrev.next = vNew;\r\n\t\tvNew.next = vNext;\r\n\t\tvNext.prev = vNew;\r\n\r\n\t\tvNew.anEdge = eOrig;\r\n\t\t/* leave coords, s, t undefined */\r\n\r\n\t\t/* fix other edges on this vertex loop */\r\n\t\tvar e = eOrig;\r\n\t\tdo {\r\n\t\t\te.Org = vNew;\r\n\t\t\te = e.Onext;\r\n\t\t} while (e !== eOrig);\r\n\t}\r\n\r\n\t/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left\r\n\t * face of all edges in the face loop to which eOrig belongs. \"fNext\" gives\r\n\t * a place to insert the new face in the global face list. We insert\r\n\t * the new face *before* fNext so that algorithms which walk the face\r\n\t * list will not see the newly created faces.\r\n\t */\r\n\t// static void MakeFace( TESSface *newFace, TESShalfEdge *eOrig, TESSface *fNext )\r\n\tmakeFace_(newFace: TESSface, eOrig:TESShalfEdge, fNext:TESSface) {\r\n\t\tvar fNew = newFace;\r\n\r\n\t\tassert(fNew, \"Face can't be null\");\r\n\r\n\t\t/* insert in circular doubly-linked list before fNext */\r\n\t\tvar fPrev = fNext.prev;\r\n\t\tfNew.prev = fPrev;\r\n\t\tfPrev.next = fNew;\r\n\t\tfNew.next = fNext;\r\n\t\tfNext.prev = fNew;\r\n\r\n\t\tfNew.anEdge = eOrig;\r\n\t\tfNew.trail = null;\r\n\t\tfNew.marked = false;\r\n\r\n\t\t/* The new face is marked \"inside\" if the old one was. This is a\r\n\t\t * convenience for the common case where a face has been split in two.\r\n\t\t */\r\n\t\tfNew.inside = fNext.inside;\r\n\r\n\t\t/* fix other edges on this face loop */\r\n\t\tvar e = eOrig;\r\n\t\tdo {\r\n\t\t\te.Lface = fNew;\r\n\t\t\te = e.Lnext;\r\n\t\t} while (e !== eOrig);\r\n\t}\r\n\r\n\t/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),\r\n\t * and removes from the global edge list.\r\n\t */\r\n\t//static void KillEdge( TESSmesh *mesh, TESShalfEdge *eDel )\r\n\tkillEdge_(eDel: TESShalfEdge) {\r\n\t\t/* Half-edges are allocated in pairs, see EdgePair above */\r\n\t\tif (eDel.Sym.side < eDel.side) {\r\n\t\t\teDel = eDel.Sym;\r\n\t\t}\r\n\r\n\t\t/* delete from circular doubly-linked list */\r\n\t\tvar eNext = eDel.next;\r\n\t\tvar ePrev = eDel.Sym.next;\r\n\t\teNext.Sym.next = ePrev;\r\n\t\tePrev.Sym.next = eNext;\r\n\t}\r\n\r\n\t/* KillVertex( vDel ) destroys a vertex and removes it from the global\r\n\t * vertex list. It updates the vertex loop to point to a given new vertex.\r\n\t */\r\n\t//static void KillVertex( TESSmesh *mesh, TESSvertex *vDel, TESSvertex *newOrg )\r\n\tkillVertex_(vDel: TESSvertex, newOrg: TESSvertex) {\r\n\t\tvar eStart = vDel.anEdge;\r\n\t\t/* change the origin of all affected edges */\r\n\t\tvar e = eStart;\r\n\t\tdo {\r\n\t\t\te.Org = newOrg;\r\n\t\t\te = e.Onext;\r\n\t\t} while (e !== eStart);\r\n\r\n\t\t/* delete from circular doubly-linked list */\r\n\t\tvar vPrev = vDel.prev;\r\n\t\tvar vNext = vDel.next;\r\n\t\tvNext.prev = vPrev;\r\n\t\tvPrev.next = vNext;\r\n\t}\r\n\r\n\t/* KillFace( fDel ) destroys a face and removes it from the global face\r\n\t * list. It updates the face loop to point to a given new face.\r\n\t */\r\n\t//static void KillFace( TESSmesh *mesh, TESSface *fDel, TESSface *newLface )\r\n\tkillFace_(fDel: TESSface, newLface: TESSface) {\r\n\t\tvar eStart = fDel.anEdge;\r\n\r\n\t\t/* change the left face of all affected edges */\r\n\t\tvar e = eStart;\r\n\t\tdo {\r\n\t\t\te.Lface = newLface;\r\n\t\t\te = e.Lnext;\r\n\t\t} while (e !== eStart);\r\n\r\n\t\t/* delete from circular doubly-linked list */\r\n\t\tvar fPrev = fDel.prev;\r\n\t\tvar fNext = fDel.next;\r\n\t\tfNext.prev = fPrev;\r\n\t\tfPrev.next = fNext;\r\n\t}\r\n\r\n\t/****************** Basic Edge Operations **********************/\r\n\r\n\t/* tessMeshMakeEdge creates one edge, two vertices, and a loop (face).\r\n\t * The loop consists of the two new half-edges.\r\n\t */\r\n\t//TESShalfEdge *tessMeshMakeEdge( TESSmesh *mesh )\r\n\tmakeEdge() {\r\n\t\tvar newVertex1 = new TESSvertex();\r\n\t\tvar newVertex2 = new TESSvertex();\r\n\t\tvar newFace = new TESSface();\r\n\t\tvar e = this.makeEdge_(this.eHead);\r\n\t\tthis.makeVertex_(newVertex1, e, this.vHead);\r\n\t\tthis.makeVertex_(newVertex2, e.Sym, this.vHead);\r\n\t\tthis.makeFace_(newFace, e, this.fHead);\r\n\t\treturn e;\r\n\t}\r\n\r\n\t/* tessMeshSplice( eOrg, eDst ) is the basic operation for changing the\r\n\t * mesh connectivity and topology. It changes the mesh so that\r\n\t *\teOrg->Onext <- OLD( eDst->Onext )\r\n\t *\teDst->Onext <- OLD( eOrg->Onext )\r\n\t * where OLD(...) means the value before the meshSplice operation.\r\n\t *\r\n\t * This can have two effects on the vertex structure:\r\n\t * - if eOrg->Org != eDst->Org, the two vertices are merged together\r\n\t * - if eOrg->Org == eDst->Org, the origin is split into two vertices\r\n\t * In both cases, eDst->Org is changed and eOrg->Org is untouched.\r\n\t *\r\n\t * Similarly (and independently) for the face structure,\r\n\t * - if eOrg->Lface == eDst->Lface, one loop is split into two\r\n\t * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one\r\n\t * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.\r\n\t *\r\n\t * Some special cases:\r\n\t * If eDst == eOrg, the operation has no effect.\r\n\t * If eDst == eOrg->Lnext, the new face will have a single edge.\r\n\t * If eDst == eOrg->Lprev, the old face will have a single edge.\r\n\t * If eDst == eOrg->Onext, the new vertex will have a single edge.\r\n\t * If eDst == eOrg->Oprev, the old vertex will have a single edge.\r\n\t */\r\n\t//int tessMeshSplice( TESSmesh* mesh, TESShalfEdge *eOrg, TESShalfEdge *eDst )\r\n\tsplice(eOrg: TESShalfEdge, eDst: TESShalfEdge) {\r\n\t\tvar joiningLoops = false;\r\n\t\tvar joiningVertices = false;\r\n\r\n\t\tif (eOrg === eDst) return;\r\n\r\n\t\tif (eDst.Org !== eOrg.Org) {\r\n\t\t\t/* We are merging two disjoint vertices -- destroy eDst->Org */\r\n\t\t\tjoiningVertices = true;\r\n\t\t\tthis.killVertex_(eDst.Org, eOrg.Org);\r\n\t\t}\r\n\t\tif (eDst.Lface !== eOrg.Lface) {\r\n\t\t\t/* We are connecting two disjoint loops -- destroy eDst->Lface */\r\n\t\t\tjoiningLoops = true;\r\n\t\t\tthis.killFace_(eDst.Lface, eOrg.Lface);\r\n\t\t}\r\n\r\n\t\t/* Change the edge structure */\r\n\t\tthis.splice_(eDst, eOrg);\r\n\r\n\t\tif (!joiningVertices) {\r\n\t\t\tvar newVertex = new TESSvertex();\r\n\r\n\t\t\t/* We split one vertex into two -- the new vertex is eDst->Org.\r\n\t\t\t * Make sure the old vertex points to a valid half-edge.\r\n\t\t\t */\r\n\t\t\tthis.makeVertex_(newVertex, eDst, eOrg.Org);\r\n\t\t\teOrg.Org.anEdge = eOrg;\r\n\t\t}\r\n\t\tif (!joiningLoops) {\r\n\t\t\tvar newFace = new TESSface();\r\n\r\n\t\t\t/* We split one loop into two -- the new loop is eDst->Lface.\r\n\t\t\t * Make sure the old face points to a valid half-edge.\r\n\t\t\t */\r\n\t\t\tthis.makeFace_(newFace, eDst, eOrg.Lface);\r\n\t\t\teOrg.Lface.anEdge = eOrg;\r\n\t\t}\r\n\t}\r\n\r\n\t/* tessMeshDelete( eDel ) removes the edge eDel. There are several cases:\r\n\t * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop\r\n\t * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;\r\n\t * the newly created loop will contain eDel->Dst. If the deletion of eDel\r\n\t * would create isolated vertices, those are deleted as well.\r\n\t *\r\n\t * This function could be implemented as two calls to tessMeshSplice\r\n\t * plus a few calls to memFree, but this would allocate and delete\r\n\t * unnecessary vertices and faces.\r\n\t */\r\n\t//int tessMeshDelete( TESSmesh *mesh, TESShalfEdge *eDel )\r\n\tdelete(eDel: TESShalfEdge) {\r\n\t\tvar eDelSym = eDel.Sym;\r\n\t\tvar joiningLoops = false;\r\n\r\n\t\t/* First step: disconnect the origin vertex eDel->Org. We make all\r\n\t\t * changes to get a consistent mesh in this \"intermediate\" state.\r\n\t\t */\r\n\t\tif (eDel.Lface !== eDel.Rface) {\r\n\t\t\t/* We are joining two loops into one -- remove the left face */\r\n\t\t\tjoiningLoops = true;\r\n\t\t\tthis.killFace_(eDel.Lface, eDel.Rface);\r\n\t\t}\r\n\r\n\t\tif (eDel.Onext === eDel) {\r\n\t\t\tthis.killVertex_(eDel.Org, null);\r\n\t\t} else {\r\n\t\t\t/* Make sure that eDel->Org and eDel->Rface point to valid half-edges */\r\n\t\t\teDel.Rface.anEdge = eDel.Oprev;\r\n\t\t\teDel.Org.anEdge = eDel.Onext;\r\n\r\n\t\t\tthis.splice_(eDel, eDel.Oprev);\r\n\t\t\tif (!joiningLoops) {\r\n\t\t\t\tvar newFace = new TESSface();\r\n\r\n\t\t\t\t/* We are splitting one loop into two -- create a new loop for eDel. */\r\n\t\t\t\tthis.makeFace_(newFace, eDel, eDel.Lface);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* Claim: the mesh is now in a consistent state, except that eDel->Org\r\n\t\t * may have been deleted. Now we disconnect eDel->Dst.\r\n\t\t */\r\n\t\tif (eDelSym.Onext === eDelSym) {\r\n\t\t\tthis.killVertex_(eDelSym.Org, null);\r\n\t\t\tthis.killFace_(eDelSym.Lface, null);\r\n\t\t} else {\r\n\t\t\t/* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */\r\n\t\t\teDel.Lface.anEdge = eDelSym.Oprev;\r\n\t\t\teDelSym.Org.anEdge = eDelSym.Onext;\r\n\t\t\tthis.splice_(eDelSym, eDelSym.Oprev);\r\n\t\t}\r\n\r\n\t\t/* Any isolated vertices or faces have already been freed. */\r\n\t\tthis.killEdge_(eDel);\r\n\t}\r\n\r\n\t/******************** Other Edge Operations **********************/\r\n\r\n\t/* All these routines can be implemented with the basic edge\r\n\t * operations above. They are provided for convenience and efficiency.\r\n\t */\r\n\r\n\t/* tessMeshAddEdgeVertex( eOrg ) creates a new edge eNew such that\r\n\t * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.\r\n\t * eOrg and eNew will have the same left face.\r\n\t */\r\n\t// TESShalfEdge *tessMeshAddEdgeVertex( TESSmesh *mesh, TESShalfEdge *eOrg );\r\n\taddEdgeVertex(eOrg: TESShalfEdge) {\r\n\t\tvar eNew = this.makeEdge_(eOrg);\r\n\t\tvar eNewSym = eNew.Sym;\r\n\r\n\t\t/* Connect the new edge appropriately */\r\n\t\tthis.splice_(eNew, eOrg.Lnext);\r\n\r\n\t\t/* Set the vertex and face information */\r\n\t\teNew.Org = eOrg.Dst;\r\n\r\n\t\tvar newVertex = new TESSvertex();\r\n\t\tthis.makeVertex_(newVertex, eNewSym, eNew.Org);\r\n\r\n\t\teNew.Lface = eNewSym.Lface = eOrg.Lface;\r\n\r\n\t\treturn eNew;\r\n\t}\r\n\r\n\t/* tessMeshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,\r\n\t * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.\r\n\t * eOrg and eNew will have the same left face.\r\n\t */\r\n\t// TESShalfEdge *tessMeshSplitEdge( TESSmesh *mesh, TESShalfEdge *eOrg );\r\n\tsplitEdge(eOrg: TESShalfEdge) {\r\n\t\tvar tempHalfEdge = this.addEdgeVertex(eOrg);\r\n\t\tvar eNew = tempHalfEdge.Sym;\r\n\r\n\t\t/* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */\r\n\t\tthis.splice_(eOrg.Sym, eOrg.Sym.Oprev);\r\n\t\tthis.splice_(eOrg.Sym, eNew);\r\n\r\n\t\t/* Set the vertex and face information */\r\n\t\teOrg.Dst = eNew.Org;\r\n\t\teNew.Dst.anEdge = eNew.Sym; /* may have pointed to eOrg->Sym */\r\n\t\teNew.Rface = eOrg.Rface;\r\n\t\teNew.winding = eOrg.winding; /* copy old winding information */\r\n\t\teNew.Sym.winding = eOrg.Sym.winding;\r\n\r\n\t\treturn eNew;\r\n\t}\r\n\r\n\t/* tessMeshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst\r\n\t * to eDst->Org, and returns the corresponding half-edge eNew.\r\n\t * If eOrg->Lface == eDst->Lface, this splits one loop into two,\r\n\t * and the newly created loop is eNew->Lface. Otherwise, two disjoint\r\n\t * loops are merged into one, and the loop eDst->Lface is destroyed.\r\n\t *\r\n\t * If (eOrg == eDst), the new face will have only two edges.\r\n\t * If (eOrg->Lnext == eDst), the old face is reduced to a single edge.\r\n\t * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.\r\n\t */\r\n\r\n\t// TESShalfEdge *tessMeshConnect( TESSmesh *mesh, TESShalfEdge *eOrg, TESShalfEdge *eDst );\r\n\tconnect(eOrg: TESShalfEdge, eDst: TESShalfEdge) {\r\n\t\tvar joiningLoops = false;\r\n\t\tvar eNew = this.makeEdge_(eOrg);\r\n\t\tvar eNewSym = eNew.Sym;\r\n\r\n\t\tif (eDst.Lface !== eOrg.Lface) {\r\n\t\t\t/* We are connecting two disjoint loops -- destroy eDst->Lface */\r\n\t\t\tjoiningLoops = true;\r\n\t\t\tthis.killFace_(eDst.Lface, eOrg.Lface);\r\n\t\t}\r\n\r\n\t\t/* Connect the new edge appropriately */\r\n\t\tthis.splice_(eNew, eOrg.Lnext);\r\n\t\tthis.splice_(eNewSym, eDst);\r\n\r\n\t\t/* Set the vertex and face information */\r\n\t\teNew.Org = eOrg.Dst;\r\n\t\teNewSym.Org = eDst.Org;\r\n\t\teNew.Lface = eNewSym.Lface = eOrg.Lface;\r\n\r\n\t\t/* Make sure the old face points to a valid half-edge */\r\n\t\teOrg.Lface.anEdge = eNewSym;\r\n\r\n\t\tif (!joiningLoops) {\r\n\t\t\tvar newFace = new TESSface();\r\n\t\t\t/* We split one loop into two -- the new loop is eNew->Lface */\r\n\t\t\tthis.makeFace_(newFace, eNew, eOrg.Lface);\r\n\t\t}\r\n\t\treturn eNew;\r\n\t}\r\n\r\n\t/* tessMeshZapFace( fZap ) destroys a face and removes it from the\r\n\t * global face list. All edges of fZap will have a NULL pointer as their\r\n\t * left face. Any edges which also have a NULL pointer as their right face\r\n\t * are deleted entirely (along with any isolated vertices this produces).\r\n\t * An entire mesh can be deleted by zapping its faces, one at a time,\r\n\t * in any order. Zapped faces cannot be used in further mesh operations!\r\n\t */\r\n\tzapFace(fZap: TESSface) {\r\n\t\tvar eStart = fZap.anEdge;\r\n\t\tvar e, eNext, eSym;\r\n\t\tvar fPrev, fNext;\r\n\r\n\t\t/* walk around face, deleting edges whose right face is also NULL */\r\n\t\teNext = eStart.Lnext;\r\n\t\tdo {\r\n\t\t\te = eNext;\r\n\t\t\teNext = e.Lnext;\r\n\r\n\t\t\te.Lface = null;\r\n\t\t\tif (e.Rface === null) {\r\n\t\t\t\t/* delete the edge -- see TESSmeshDelete above */\r\n\r\n\t\t\t\tif (e.Onext === e) {\r\n\t\t\t\t\tthis.killVertex_(e.Org, null);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t/* Make sure that e->Org points to a valid half-edge */\r\n\t\t\t\t\te.Org.anEdge = e.Onext;\r\n\t\t\t\t\tthis.splice_(e, e.Oprev);\r\n\t\t\t\t}\r\n\t\t\t\teSym = e.Sym;\r\n\t\t\t\tif (eSym.Onext === eSym) {\r\n\t\t\t\t\tthis.killVertex_(eSym.Org, null);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t/* Make sure that eSym->Org points to a valid half-edge */\r\n\t\t\t\t\teSym.Org.anEdge = eSym.Onext;\r\n\t\t\t\t\tthis.splice_(eSym, eSym.Oprev);\r\n\t\t\t\t}\r\n\t\t\t\tthis.killEdge_(e);\r\n\t\t\t}\r\n\t\t} while (e != eStart);\r\n\r\n\t\t/* delete from circular doubly-linked list */\r\n\t\tfPrev = fZap.prev;\r\n\t\tfNext = fZap.next;\r\n\t\tfNext.prev = fPrev;\r\n\t\tfPrev.next = fNext;\r\n\t}\r\n\r\n\tcountFaceVerts_(f: TESSface) {\r\n\t\tvar eCur = f.anEdge;\r\n\t\tvar n = 0;\r\n\t\tdo {\r\n\t\t\tn++;\r\n\t\t\teCur = eCur.Lnext;\r\n\t\t} while (eCur !== f.anEdge);\r\n\t\treturn n;\r\n\t}\r\n\r\n\t//int tessMeshMergeConvexFaces( TESSmesh *mesh, int maxVertsPerFace )\r\n\tmergeConvexFaces(maxVertsPerFace: number) {\r\n\t\tvar f;\r\n\t\tvar eCur, eNext, eSym;\r\n\t\tvar vStart;\r\n\t\tvar curNv, symNv;\r\n\r\n\t\tfor (f = this.fHead.next; f !== this.fHead; f = f.next) {\r\n\t\t\t// Skip faces which are outside the result.\r\n\t\t\tif (!f.inside) continue;\r\n\r\n\t\t\teCur = f.anEdge;\r\n\t\t\tvStart = eCur.Org;\r\n\r\n\t\t\twhile (true) {\r\n\t\t\t\teNext = eCur.Lnext;\r\n\t\t\t\teSym = eCur.Sym;\r\n\r\n\t\t\t\t// Try to merge if the neighbour face is valid.\r\n\t\t\t\tif (eSym && eSym.Lface && eSym.Lface.inside) {\r\n\t\t\t\t\t// Try to merge the neighbour faces if the resulting polygons\r\n\t\t\t\t\t// does not exceed maximum number of vertices.\r\n\t\t\t\t\tcurNv = this.countFaceVerts_(f);\r\n\t\t\t\t\tsymNv = this.countFaceVerts_(eSym.Lface);\r\n\t\t\t\t\tif (curNv + symNv - 2 <= maxVertsPerFace) {\r\n\t\t\t\t\t\t// Merge if the resulting poly is convex.\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tGeom.vertCCW(\r\n\t\t\t\t\t\t\t\teCur.Lprev.Org,\r\n\t\t\t\t\t\t\t\teCur.Org,\r\n\t\t\t\t\t\t\t\teSym.Lnext.Lnext.Org,\r\n\t\t\t\t\t\t\t) &&\r\n\t\t\t\t\t\t\tGeom.vertCCW(\r\n\t\t\t\t\t\t\t\teSym.Lprev.Org,\r\n\t\t\t\t\t\t\t\teSym.Org,\r\n\t\t\t\t\t\t\t\teCur.Lnext.Lnext.Org,\r\n\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\teNext = eSym.Lnext;\r\n\t\t\t\t\t\t\tthis.delete(eSym);\r\n\t\t\t\t\t\t\teCur = null;\r\n\t\t\t\t\t\t\teSym = null;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (eCur && eCur.Lnext.Org === vStart) break;\r\n\r\n\t\t\t\t// Continue to next edge.\r\n\t\t\t\teCur = eNext;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/* tessMeshCheckMesh( mesh ) checks a mesh for self-consistency.\r\n\t */\r\n\tcheck() {\r\n\t\tvar fHead = this.fHead;\r\n\t\tvar vHead = this.vHead;\r\n\t\tvar eHead = this.eHead;\r\n\t\tvar f, fPrev, v, vPrev, e, ePrev;\r\n\r\n\t\tfPrev = fHead;\r\n\t\tfor (fPrev = fHead; (f = fPrev.next) !== fHead; fPrev = f) {\r\n\t\t\tassert(f.prev === fPrev);\r\n\t\t\te = f.anEdge;\r\n\t\t\tdo {\r\n\t\t\t\tassert(e.Sym !== e);\r\n\t\t\t\tassert(e.Sym.Sym === e);\r\n\t\t\t\tassert(e.Lnext.Onext.Sym === e);\r\n\t\t\t\tassert(e.Onext.Sym.Lnext === e);\r\n\t\t\t\tassert(e.Lface === f);\r\n\t\t\t\te = e.Lnext;\r\n\t\t\t} while (e !== f.anEdge);\r\n\t\t}\r\n\t\tassert(f.prev === fPrev && f.anEdge === null);\r\n\r\n\t\tvPrev = vHead;\r\n\t\tfor (vPrev = vHead; (v = vPrev.next) !== vHead; vPrev = v) {\r\n\t\t\tassert(v.prev === vPrev);\r\n\t\t\te = v.anEdge;\r\n\t\t\tdo {\r\n\t\t\t\tassert(e.Sym !== e);\r\n\t\t\t\tassert(e.Sym.Sym === e);\r\n\t\t\t\tassert(e.Lnext.Onext.Sym === e);\r\n\t\t\t\tassert(e.Onext.Sym.Lnext === e);\r\n\t\t\t\tassert(e.Org === v);\r\n\t\t\t\te = e.Onext;\r\n\t\t\t} while (e !== v.anEdge);\r\n\t\t}\r\n\t\tassert(v.prev === vPrev && v.anEdge === null);\r\n\r\n\t\tePrev = eHead;\r\n\t\tfor (ePrev = eHead; (e = ePrev.next) !== eHead; ePrev = e) {\r\n\t\t\tassert(e.Sym.next === ePrev.Sym);\r\n\t\t\tassert(e.Sym !== e);\r\n\t\t\tassert(e.Sym.Sym === e);\r\n\t\t\tassert(e.Org !== null);\r\n\t\t\tassert(e.Dst !== null);\r\n\t\t\tassert(e.Lnext.Onext.Sym === e);\r\n\t\t\tassert(e.Onext.Sym.Lnext === e);\r\n\t\t}\r\n\t\tassert(\r\n\t\t\te.Sym.next === ePrev.Sym &&\r\n\t\t\t\te.Sym === this.eHeadSym &&\r\n\t\t\t\te.Sym.Sym === e &&\r\n\t\t\t\te.Org === null &&\r\n\t\t\t\te.Dst === null &&\r\n\t\t\t\te.Lface === null &&\r\n\t\t\t\te.Rface === null,\r\n\t\t);\r\n\t}\r\n};\r\n", "import { assert } from './assert';\r\n\r\nexport class PQnode {\r\n\thandle: any = null;\r\n}\r\n\r\nexport class PQhandleElem {\r\n\tkey: any = null;\r\n\tnode: number = 0;\r\n}\r\n\r\nexport class PriorityQ {\r\n\tmax: number = 0;\r\n\tnodes: Array<PQnode> = [];\r\n\thandles: Array<PQhandleElem> = [];\r\n\tinitialized: boolean = false;\r\n\tfreeList: number = 0;\r\n\tsize: number = 0;\r\n\r\n\tconstructor(size: number, public leq: (...args: any) => boolean) {\r\n\t\r\n\t\tthis.max = size;\r\n\t\tthis.nodes = [];\r\n\t\tthis.handles = [];\r\n\t\t\r\n\t\tfor(let i = 0; i < size + 1; i ++) {\r\n\t\t\tthis.nodes[i] = new PQnode();\r\n\t\t\tthis.handles[i] = new PQhandleElem();\r\n\t\t}\r\n\r\n\t\tthis.initialized = false;\r\n\t\t\r\n\t\t/* so that Minimum() returns NULL */\r\n\t\tthis.nodes[1].handle = 1; \r\n\t\tthis.handles[1].key = null;\r\n\r\n\t}\r\n\r\n\tfloatDown_(curr: number) {\r\n\t\tvar n = this.nodes;\r\n\t\tvar h = this.handles;\r\n\t\tvar hCurr, hChild;\r\n\t\tvar child;\r\n\r\n\t\thCurr = n[curr].handle;\r\n\t\tfor (; ;) {\r\n\t\t\tchild = curr << 1;\r\n\t\t\tif (\r\n\t\t\t\tchild < this.size &&\r\n\t\t\t\tthis.leq(h[n[child + 1].handle].key, h[n[child].handle].key)\r\n\t\t\t) {\r\n\t\t\t\t++child;\r\n\t\t\t}\r\n\r\n\t\t\tassert(child <= this.max);\r\n\r\n\t\t\thChild = n[child].handle;\r\n\t\t\tif (child > this.size || this.leq(h[hCurr].key, h[hChild].key)) {\r\n\t\t\t\tn[curr].handle = hCurr;\r\n\t\t\t\th[hCurr].node = curr;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tn[curr].handle = hChild;\r\n\t\t\th[hChild].node = curr;\r\n\t\t\tcurr = child;\r\n\t\t}\r\n\t}\r\n\r\n\tfloatUp_(curr: number) {\r\n\t\tvar n = this.nodes;\r\n\t\tvar h = this.handles;\r\n\t\tvar hCurr, hParent;\r\n\t\tvar parent;\r\n\r\n\t\thCurr = n[curr].handle;\r\n\t\tfor (; ;) {\r\n\t\t\tparent = curr >> 1;\r\n\t\t\thParent = n[parent].handle;\r\n\t\t\tif (parent === 0 || this.leq(h[hParent].key, h[hCurr].key)) {\r\n\t\t\t\tn[curr].handle = hCurr;\r\n\t\t\t\th[hCurr].node = curr;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tn[curr].handle = hParent;\r\n\t\t\th[hParent].node = curr;\r\n\t\t\tcurr = parent;\r\n\t\t}\r\n\t}\r\n\r\n\tinit() {\r\n\t\t/* This method of building a heap is O(n), rather than O(n lg n). */\r\n\t\tfor (let i = this.size; i >= 1; --i) {\r\n\t\t\tthis.floatDown_(i);\r\n\t\t}\r\n\t\tthis.initialized = true;\r\n\t}\r\n\r\n\tmin() {\r\n\t\treturn this.handles[this.nodes[1].handle].key;\r\n\t}\r\n\r\n\t/* really pqHeapInsert */\r\n\t/* returns INV_HANDLE iff out of memory */\r\n\t//PQhandle pqHeapInsert( TESSalloc* alloc, PriorityQHeap *pq, PQkey keyNew )\r\n\tinsert(keyNew: any) {\r\n\t\tvar curr;\r\n\t\tvar free;\r\n\r\n\t\tcurr = ++this.size;\r\n\t\tif (curr * 2 > this.max) {\r\n\t\t\tthis.max *= 2;\r\n\t\t\tvar i;\r\n\t\t\tvar s;\r\n\t\t\ts = this.nodes.length;\r\n\t\t\tthis.nodes.length = this.max + 1;\r\n\t\t\tfor (i = s; i < this.nodes.length; i++)\r\n\t\t\t\tthis.nodes[i] = new PQnode();\r\n\r\n\t\t\ts = this.handles.length;\r\n\t\t\tthis.handles.length = this.max + 1;\r\n\t\t\tfor (i = s; i < this.handles.length; i++)\r\n\t\t\t\tthis.handles[i] = new PQhandleElem();\r\n\t\t}\r\n\r\n\t\tif (this.freeList === 0) {\r\n\t\t\tfree = curr;\r\n\t\t} else {\r\n\t\t\tfree = this.freeList;\r\n\t\t\tthis.freeList = this.handles[free].node;\r\n\t\t}\r\n\r\n\t\tthis.nodes[curr].handle = free;\r\n\t\tthis.handles[free].node = curr;\r\n\t\tthis.handles[free].key = keyNew;\r\n\r\n\t\tif (this.initialized) {\r\n\t\t\tthis.floatUp_(curr);\r\n\t\t}\r\n\t\treturn free;\r\n\t}\r\n\r\n\t//PQkey pqHeapExtractMin( PriorityQHeap *pq )\r\n\textractMin() {\r\n\t\tvar n = this.nodes;\r\n\t\tvar h = this.handles;\r\n\t\tvar hMin = n[1].handle;\r\n\t\tvar min = h[hMin].key;\r\n\r\n\t\tif (this.size > 0) {\r\n\t\t\tn[1].handle = n[this.size].handle;\r\n\t\t\th[n[1].handle].node = 1;\r\n\r\n\t\t\th[hMin].key = null;\r\n\t\t\th[hMin].node = this.freeList;\r\n\t\t\tthis.freeList = hMin;\r\n\r\n\t\t\t--this.size;\r\n\t\t\tif (this.size > 0) {\r\n\t\t\t\tthis.floatDown_(1);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn min;\r\n\t}\r\n\r\n\tdelete(hCurr: number) {\r\n\t\tvar n = this.nodes;\r\n\t\tvar h = this.handles;\r\n\t\tvar curr;\r\n\r\n\t\tassert(hCurr >= 1 && hCurr <= this.max && h[hCurr].key !== null);\r\n\r\n\t\tcurr = h[hCurr].node;\r\n\t\tn[curr].handle = n[this.size].handle;\r\n\t\th[n[curr].handle].node = curr;\r\n\r\n\t\t--this.size;\r\n\t\tif (curr <= this.size) {\r\n\t\t\tif (\r\n\t\t\t\tcurr <= 1 ||\r\n\t\t\t\tthis.leq(h[n[curr >> 1].handle].key, h[n[curr].handle].key)\r\n\t\t\t) {\r\n\t\t\t\tthis.floatDown_(curr);\r\n\t\t\t} else {\r\n\t\t\t\tthis.floatUp_(curr);\r\n\t\t\t}\r\n\t\t}\r\n\t\th[hCurr].key = null;\r\n\t\th[hCurr].node = this.freeList;\r\n\t\tthis.freeList = hCurr;\r\n\t}\r\n}\r\n\r\n", "import { TESShalfEdge } from './TESShalfEdge';\r\n\r\n/* For each pair of adjacent edges crossing the sweep line, there is\r\n * an ActiveRegion to represent the region between them. The active\r\n * regions are kept in sorted order in a dynamic dictionary. As the\r\n * sweep line crosses each vertex, we update the affected regions.\r\n */\r\nexport class ActiveRegion {\r\n\teUp: TESShalfEdge = null; /* upper edge, directed right to left */\r\n\tnodeUp?: any = null; /* dictionary node corresponding to eUp */\r\n\twindingNumber: number = 0;\r\n\t/* used to determine which regions are\r\n\t * inside the polygon */\r\n\tinside: boolean = false; /* is this region inside the polygon? */\r\n\tsentinel: boolean = false; /* marks fake edges at t = +/-infinity */\r\n\tdirty: boolean = false;\r\n\t/* marks regions where the upper or lower\r\n\t * edge has changed, but we haven't checked\r\n\t * whether they intersect yet */\r\n\tfixUpperEdge: boolean = false;\r\n\t/* marks temporary edges introduced when\r\n\t * we process a \"right vertex\" (one without\r\n\t * any edges leaving to the right) */\r\n}\r\n", "\r\nexport class DictNode {\r\n\tkey: any = null;\r\n\tnext: DictNode = null;\r\n\tprev: DictNode = null;\r\n}\r\n\r\nexport class Dict {\r\n\thead: DictNode = new DictNode();\r\n\t\r\n\tconstructor(public frame: any, public leq: (...arg: any) => boolean) {\r\n\t\tthis.head.next = this.head;\r\n\t\tthis.head.prev = this.head;\r\n\t}\r\n\r\n\tmin() {\r\n\t\treturn this.head.next;\r\n\t}\r\n\r\n\tmax() {\r\n\t\treturn this.head.prev;\r\n\t}\r\n\r\n\tinsert(k: any) {\r\n\t\treturn this.insertBefore(this.head, k);\r\n\t}\r\n\r\n\tsearch(key: any) {\r\n\t\t/* Search returns the node with the smallest key greater than or equal\r\n\t\t * to the given key. If there is no such key, returns a node whose\r\n\t\t * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc.\r\n\t\t */\r\n\t\tlet node = this.head;\r\n\t\tdo {\r\n\t\t\tnode = node.next;\r\n\t\t} while (node.key !== null && !this.leq(this.frame, key, node.key));\r\n\r\n\t\treturn node;\r\n\t}\r\n\r\n\tinsertBefore(node: DictNode, key: any) {\r\n\t\tdo {\r\n\t\t\tnode = node.prev;\r\n\t\t} while (node.key !== null && !this.leq(this.frame, node.key, key));\r\n\r\n\t\tconst newNode = new DictNode();\r\n\t\tnewNode.key = key;\r\n\t\tnewNode.next = node.next;\r\n\t\tnode.next.prev = newNode;\r\n\t\tnewNode.prev = node;\r\n\t\tnode.next = newNode;\r\n\r\n\t\treturn newNode;\r\n\t}\r\n\r\n\tdelete(node:DictNode) {\r\n\t\tnode.next.prev = node.prev;\r\n\t\tnode.prev.next = node.next;\r\n\t}\r\n};", "import { Geom } from \"./Geom\";\r\nimport { assert } from \"./../utils/assert\";\r\nimport { PriorityQ } from \"./PriorityQ\";\r\nimport { WINDING } from \"./constants\";\r\nimport { ActiveRegion} from \"./../mesh/ActiveRegion\";\r\nimport { TESSvertex } from \"./../mesh/TESSvertex\";\r\n\r\nimport { Dict } from \"./Dict\";\r\nimport { TESSmesh } from \"../mesh/TESSmesh\";\r\nimport { TESShalfEdge } from \"../mesh/index\";\r\nimport { Tesselator } from \"../index\";\r\n\r\nexport class Sweep {\r\n\r\n\tstatic regionBelow(r: ActiveRegion) {\r\n\t\treturn r.nodeUp.prev.key;\r\n\t}\r\n\r\n\tstatic regionAbove(r: ActiveRegion) {\r\n\t\treturn r.nodeUp.next.key;\r\n\t}\r\n\r\n\tstatic debugEvent(tess: any) {\r\n\t\t// empty\r\n\t}\r\n\r\n\t/*\r\n\t * Invariants for the Edge Dictionary.\r\n\t * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)\r\n\t * at any valid location of the sweep event\r\n\t * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2\r\n\t * share a common endpoint\r\n\t * - for each e, e->Dst has been processed, but not e->Org\r\n\t * - each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)\r\n\t * where \"event\" is the current sweep line event.\r\n\t * - no edge e has zero length\r\n\t *\r\n\t * Invariants for the Mesh (the processed portion).\r\n\t * - the portion of the mesh left of the sweep line is a planar graph,\r\n\t * ie. there is *some* way to embed it in the plane\r\n\t * - no processed edge has zero length\r\n\t * - no two processed vertices have identical coordinates\r\n\t * - each \"inside\" region is monotone, ie. can be broken into two chains\r\n\t * of monotonically increasing vertices according to VertLeq(v1,v2)\r\n\t * - a non-invariant: these chains may intersect (very slightly)\r\n\t *\r\n\t * Invariants for the Sweep.\r\n\t * - if none of the edges incident to the event vertex have an activeRegion\r\n\t * (ie. none of these edges are in the edge dictionary), then the vertex\r\n\t * has only right-going edges.\r\n\t * - if an edge is marked \"fixUpperEdge\" (it is a temporary edge introduced\r\n\t * by ConnectRightVertex), then it is the only right-going edge from\r\n\t * its associated vertex. (This says that these edges exist only\r\n\t * when it is necessary.)\r\n\t */\r\n\r\n\t/* When we merge two edges into one, we need to compute the combined\r\n\t * winding of the new edge.\r\n\t */\r\n\tstatic addWinding(eDst: TESShalfEdge, eSrc: TESShalfEdge) {\r\n\t\teDst.winding += eSrc.winding;\r\n\t\teDst.Sym.winding += eSrc.Sym.winding;\r\n\t}\r\n\r\n\t//static int EdgeLeq( TESStesselator *tess, ActiveRegion *reg1, ActiveRegion *reg2 )\r\n\tstatic edgeLeq(tess: Tesselator, reg1: ActiveRegion, reg2: ActiveRegion) {\r\n\t\t/*\r\n\t\t * Both edges must be directed from right to left (this is the canonical\r\n\t\t * direction for the upper edge of each region).\r\n\t\t *\r\n\t\t * The strategy is to evaluate a \"t\" value for each edge at the\r\n\t\t * current sweep line position, given by tess->event. The calculations\r\n\t\t * are designed to be very stable, but of course they are not perfect.\r\n\t\t *\r\n\t\t * Special case: if both edge destinations are at the sweep event,\r\n\t\t * we sort the edges by slope (they would otherwise compare equally).\r\n\t\t */\r\n\t\tvar ev = tess.event;\r\n\t\t\r\n\t\tvar e1 = reg1.eUp;\r\n\t\tvar e2 = reg2.eUp;\r\n\r\n\t\tif (e1.Dst === ev) {\r\n\t\t\tif (e2.Dst === ev) {\r\n\t\t\t\t/* Two edges right of the sweep line which meet at the sweep event.\r\n\t\t\t\t * Sort them by slope.\r\n\t\t\t\t */\r\n\t\t\t\tif (Geom.vertLeq(e1.Org, e2.Org)) {\r\n\t\t\t\t\treturn Geom.edgeSign(e2.Dst, e1.Org, e2.Org) <= 0;\r\n\t\t\t\t}\r\n\t\t\t\treturn Geom.edgeSign(e1.Dst, e2.Org, e1.Org) >= 0;\r\n\t\t\t}\r\n\t\t\treturn Geom.edgeSign(e2.Dst, ev, e2.Org) <= 0;\r\n\t\t}\r\n\t\tif (e2.Dst === ev) {\r\n\t\t\treturn Geom.edgeSign(e1.Dst, ev, e1.Org) >= 0;\r\n\t\t}\r\n\r\n\t\t/* General case - compute signed distance *from* e1, e2 to event */\r\n\t\tconst t1 = Geom.edgeEval(e1.Dst, ev, e1.Org);\r\n\t\tconst t2 = Geom.edgeEval(e2.Dst, ev, e2.Org);\r\n\t\treturn t1 >= t2;\r\n\t}\r\n\r\n\t//static void DeleteRegion( TESStesselator *tess, ActiveRegion *reg )\r\n\tstatic deleteRegion(tess: Tesselator, reg: ActiveRegion) {\r\n\t\tif (reg.fixUpperEdge) {\r\n\t\t\t/* It was created with zero winding number, so it better be\r\n\t\t\t * deleted with zero winding number (ie. it better not get merged\r\n\t\t\t * with a real edge).\r\n\t\t\t */\r\n\t\t\tassert(reg.eUp.winding === 0);\r\n\t\t}\r\n\t\treg.eUp.activeRegion = null;\r\n\t\ttess.dict.delete(reg.nodeUp);\r\n\t}\r\n\r\n\t//static int FixUpperEdge( TESStesselator *tess, ActiveRegion *reg, TESShalfEdge *newEdge )\r\n\tstatic fixUpperEdge(tess: Tesselator, reg: ActiveRegion, newEdge: TESShalfEdge) {\r\n\t\t/*\r\n\t\t * Replace an upper edge which needs fixing (see ConnectRightVertex).\r\n\t\t */\r\n\t\tassert(reg.fixUpperEdge);\r\n\t\ttess.mesh.delete(reg.eUp);\r\n\t\treg.fixUpperEdge = false;\r\n\t\treg.eUp = newEdge;\r\n\t\tnewEdge.activeRegion = reg;\r\n\t}\r\n\r\n\t//static ActiveRegion *TopLeftRegion( TESStesselator *tess, ActiveRegion *reg )\r\n\tstatic topLeftRegion(tess: Tesselator, reg: ActiveRegion) {\r\n\t\tvar org = reg.eUp.Org;\r\n\t\tvar e;\r\n\r\n\t\t/* Find the region above the uppermost edge with the same origin */\r\n\t\tdo {\r\n\t\t\treg = Sweep.regionAbove(reg);\r\n\t\t} while (reg.eUp.Org === org);\r\n\r\n\t\t/* If the edge above was a temporary edge introduced by ConnectRightVertex,\r\n\t\t * now is the time to fix it.\r\n\t\t */\r\n\t\tif (reg.fixUpperEdge) {\r\n\t\t\te = tess.mesh.connect(\r\n\t\t\t\tSweep.regionBelow(reg).eUp.Sym,\r\n\t\t\t\treg.eUp.Lnext,\r\n\t\t\t);\r\n\t\t\tif (e === null) return null;\r\n\t\t\tSweep.fixUpperEdge(tess, reg, e);\r\n\t\t\treg = Sweep.regionAbove(reg);\r\n\t\t}\r\n\t\treturn reg;\r\n\t}\r\n\r\n\t//static ActiveRegion *TopRightRegion( ActiveRegion *reg )\r\n\tstatic topRightRegion(reg: ActiveRegion) {\r\n\t\tvar dst = reg.eUp.Dst;\r\n\t\t/* Find the region above the uppermost edge with the same destination */\r\n\t\tdo {\r\n\t\t\treg = Sweep.regionAbove(reg);\r\n\t\t} while (reg.eUp.Dst === dst);\r\n\t\treturn reg;\r\n\t}\r\n\r\n\t//static ActiveRegion *AddRegionBelow( TESStesselator *tess, ActiveRegion *regAbove, TESShalfEdge *eNewUp )\r\n\tstatic addRegionBelow(tess: Tesselator, regAbove: ActiveRegion, eNewUp: TESShalfEdge) {\r\n\t\t/*\r\n\t\t * Add a new active region to the sweep line, *somewhere* below \"regAbove\"\r\n\t\t * (according to where the new edge belongs in the sweep-line dictionary).\r\n\t\t * The upper edge of the new region will be \"eNewUp\".\r\n\t\t * Winding number and \"inside\" flag are not updated.\r\n\t\t */\r\n\t\tvar regNew = new ActiveRegion();\r\n\t\tregNew.eUp = eNewUp;\r\n\t\tregNew.nodeUp = tess.dict.insertBefore(regAbove.nodeUp, regNew);\r\n\t\t//\tif (regNew->nodeUp == NULL) longjmp(tess->env,1);\r\n\t\tregNew.fixUpperEdge = false;\r\n\t\tregNew.sentinel = false;\r\n\t\tregNew.dirty = false;\r\n\r\n\t\teNewUp.activeRegion = regNew;\r\n\t\treturn regNew;\r\n\t}\r\n\r\n\t//static int IsWindingInside( TESStesselator *tess, int n )\r\n\tstatic isWindingInside(tess:Tesselator, n: number) {\r\n\t\tswitch (tess.windingRule) {\r\n\t\t\tcase WINDING.ODD:\r\n\t\t\t\treturn (n & 1) !== 0;\r\n\t\t\tcase WINDING.NONZERO:\r\n\t\t\t\treturn n !== 0;\r\n\t\t\tcase WINDING.POSITIVE:\r\n\t\t\t\treturn n > 0;\r\n\t\t\tcase WINDING.NEGATIVE:\r\n\t\t\t\treturn n < 0;\r\n\t\t\tcase WINDING.ABS_GEQ_TWO:\r\n\t\t\t\treturn n >= 2 || n <= -2;\r\n\t\t}\r\n\r\n\t\tthrow new Error(\"Invalid winding rulle\");\r\n\t\treturn false;\r\n\t}\r\n\r\n\t//static void ComputeWinding( TESStesselator *tess, ActiveRegion *reg )\r\n\tstatic computeWinding(tess:Tesselator, reg:ActiveRegion) {\r\n\t\treg.windingNumber =\r\n\t\t\tSweep.regionAbove(reg).windingNumber + reg.eUp.winding;\r\n\t\treg.inside = Sweep.isWindingInside(tess, reg.windingNumber);\r\n\t}\r\n\r\n\t//static void FinishRegion( TESStesselator *tess, ActiveRegion *reg )\r\n\tstatic finishRegion(tess:Tesselator, reg:ActiveRegion) {\r\n\t\t/*\r\n\t\t * Delete a region from the sweep line. This happens when the upper\r\n\t\t * and lower chains of a region meet (at a vertex on the sweep line).\r\n\t\t * The \"inside\" flag is copied to the appropriate mesh face (we could\r\n\t\t * not do this before -- since the structure of the mesh is always\r\n\t\t * changing, this face may not have even existed until now).\r\n\t\t */\r\n\t\tvar e = reg.eUp;\r\n\t\tvar f = e.Lface;\r\n\r\n\t\tf.inside = reg.inside;\r\n\t\tf.anEdge = e; /* optimization for tessMeshTessellateMonoRegion() */\r\n\t\tSweep.deleteRegion(tess, reg);\r\n\t}\r\n\r\n\t//static TESShalfEdge *FinishLeftRegions( TESStesselator *tess, ActiveRegion *regFirst, ActiveRegion *regLast )\r\n\tstatic finishLeftRegions(tess:Tesselator, regFirst:ActiveRegion, regLast:ActiveRegion) {\r\n\t\t/*\r\n\t\t * We are given a vertex with one or more left-going edges. All affected\r\n\t\t * edges should be in the edge dictionary. Starting at regFirst->eUp,\r\n\t\t * we walk down deleting all regions where both edges have the same\r\n\t\t * origin vOrg. At the same time we copy the \"inside\" flag from the\r\n\t\t * active region to the face, since at this point each face will belong\r\n\t\t * to at most one region (this was not necessarily true until this point\r\n\t\t * in the sweep). The walk stops at the region above regLast; if regLast\r\n\t\t * is NULL we walk as far as possible. At the same time we relink the\r\n\t\t * mesh if necessary, so that the ordering of edges around vOrg is the\r\n\t\t * same as in the dictionary.\r\n\t\t */\r\n\t\tvar e;\r\n\t\tvar reg = null;\r\n\t\tvar regPrev = regFirst;\r\n\t\tvar ePrev = regFirst.eUp;\r\n\t\t\r\n\t\twhile (regPrev !== regLast) {\r\n\t\t\tregPrev.fixUpperEdge = false; /* placement was OK */\r\n\t\t\treg = Sweep.regionBelow(regPrev);\r\n\t\t\te = reg.eUp;\r\n\t\t\tif (e.Org != ePrev.Org) {\r\n\t\t\t\tif (!reg.fixUpperEdge) {\r\n\t\t\t\t\t/* Remove the last left-going edge. Even though there are no further\r\n\t\t\t\t\t * edges in the dictionary with this origin, there may be further\r\n\t\t\t\t\t * such edges in the mesh (if we are adding left edges to a vertex\r\n\t\t\t\t\t * that has already been processed). Thus it is important to call\r\n\t\t\t\t\t * FinishRegion rather than just DeleteRegion.\r\n\t\t\t\t\t */\r\n\t\t\t\t\tSweep.finishRegion(tess, regPrev);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\t/* If the edge below was a temporary edge introduced by\r\n\t\t\t\t * ConnectRightVertex, now is the time to fix it.\r\n\t\t\t\t */\r\n\t\t\t\te = tess.mesh.connect(ePrev.Lprev, e.Sym);\r\n\t\t\t\t//\t\t\tif (e == NULL) longjmp(tess->env,1);\r\n\t\t\t\tSweep.fixUpperEdge(tess, reg, e);\r\n\t\t\t}\r\n\r\n\t\t\t/* Relink edges so that ePrev->Onext == e */\r\n\t\t\tif (ePrev.Onext !== e) {\r\n\t\t\t\ttess.mesh.splice(e.Oprev, e);\r\n\t\t\t\ttess.mesh.splice(ePrev, e);\r\n\t\t\t}\r\n\t\t\tSweep.finishRegion(tess, regPrev); /* may change reg->eUp */\r\n\t\t\tePrev = reg.eUp;\r\n\t\t\tregPrev = reg;\r\n\t\t}\r\n\t\treturn ePrev;\r\n\t}\r\n\r\n\t//static void AddRightEdges( TESStesselator *tess, ActiveRegion *regUp, TESShalfEdge *eFirst, TESShalfEdge *eLast, TESShalfEdge *eTopLeft, int cleanUp )\r\n\tstatic addRightEdges(tess: Tesselator, regUp: ActiveRegion, eFirst: TESShalfEdge, eLast:TESShalfEdge, eTopLeft:TESShalfEdge, cleanUp: boolean) {\r\n\t\t/*\r\n\t\t * Purpose: insert right-going edges into the edge dictionary, and update\r\n\t\t * winding numbers and mesh connectivity appropriately. All right-going\r\n\t\t * edges share a common origin vOrg. Edges are inserted CCW starting at\r\n\t\t * eFirst; the last edge inserted is eLast->Oprev. If vOrg has any\r\n\t\t * left-going edges already processed, then eTopLeft must be the edge\r\n\t\t * such that an imaginary upward vertical segment from vOrg would be\r\n\t\t * contained between eTopLeft->Oprev and eTopLeft; otherwise eTopLeft\r\n\t\t * should be NULL.\r\n\t\t */\r\n\t\tvar reg, regPrev;\r\n\t\tvar e, ePrev;\r\n\t\tvar firstTime = true;\r\n\r\n\t\t/* Insert the new right-going edges in the dictionary */\r\n\t\te = eFirst;\r\n\t\tdo {\r\n\t\t\tassert(Geom.vertLeq(e.Org, e.Dst));\r\n\t\t\tSweep.addRegionBelow(tess, regUp, e.Sym);\r\n\t\t\te = e.Onext;\r\n\t\t} while (e !== eLast);\r\n\r\n\t\t/* Walk *all* right-going edges from e->Org, in the dictionary order,\r\n\t\t * updating the winding numbers of each region, and re-linking the mesh\r\n\t\t * edges to match the dictionary ordering (if necessary).\r\n\t\t */\r\n\t\tif (eTopLeft === null) {\r\n\t\t\teTopLeft = Sweep.regionBelow(regUp).eUp.Rprev;\r\n\t\t}\r\n\t\tregPrev = regUp;\r\n\t\tePrev = eTopLeft;\r\n\t\tfor (;;) {\r\n\t\t\treg = Sweep.regionBelow(regPrev);\r\n\t\t\te = reg.eUp.Sym;\r\n\t\t\tif (e.Org !== ePrev.Org) break;\r\n\r\n\t\t\tif (e.Onext !== ePrev) {\r\n\t\t\t\t/* Unlink e from its current position, and relink below ePrev */\r\n\t\t\t\ttess.mesh.splice(e.Oprev, e);\r\n\t\t\t\ttess.mesh.splice(ePrev.Oprev, e);\r\n\t\t\t}\r\n\t\t\t/* Compute the winding number and \"inside\" flag for the new regions */\r\n\t\t\treg.windingNumber = regPrev.windingNumber - e.winding;\r\n\t\t\treg.inside = Sweep.isWindingInside(tess, reg.windingNumber);\r\n\r\n\t\t\t/* Check for two outgoing edges with same slope -- process these\r\n\t\t\t * before any intersection tests (see example in tessComputeInterior).\r\n\t\t\t */\r\n\t\t\tregPrev.dirty = true;\r\n\t\t\tif (!firstTime && Sweep.checkForRightSplice(tess, regPrev)) {\r\n\t\t\t\tSweep.addWinding(e, ePrev);\r\n\t\t\t\tSweep.deleteRegion(tess, regPrev);\r\n\t\t\t\ttess.mesh.delete(ePrev);\r\n\t\t\t}\r\n\t\t\tfirstTime = false;\r\n\t\t\tregPrev = reg;\r\n\t\t\tePrev = e;\r\n\t\t}\r\n\t\tregPrev.dirty = true;\r\n\t\tassert(regPrev.windingNumber - e.winding === reg.windingNumber);\r\n\r\n\t\tif (cleanUp) {\r\n\t\t\t/* Check for intersections between newly adjacent edges. */\r\n\t\t\tSweep.walkDirtyRegions(tess, regPrev);\r\n\t\t}\r\n\t}\r\n\r\n\t//static void SpliceMergeVertices( TESStesselator *tess, TESShalfEdge *e1, TESShalfEdge *e2 )\r\n\tstatic spliceMergeVertices(tess: Tesselator, e1:TESShalfEdge, e2:TESShalfEdge) {\r\n\t\t/*\r\n\t\t * Two vertices with idential coordinates are combined into one.\r\n\t\t * e1->Org is kept, while e2->Org is discarded.\r\n\t\t */\r\n\t\ttess.mesh.splice(e1, e2);\r\n\t}\r\n\r\n\t//static void VertexWeights( TESSvertex *isect, TESSvertex *org, TESSvertex *dst, TESSreal *weights )\r\n\tstatic vertexWeights(isect:TESSvertex, org:TESSvertex, dst: any) {\r\n\t\t/*\r\n\t\t * Find some weights which describe how the intersection vertex is\r\n\t\t * a linear combination of \"org\" and \"dest\". Each of the two edges\r\n\t\t * which generated \"isect\" is allocated 50% of the weight; each edge\r\n\t\t * splits the weight between its org and dst according to the\r\n\t\t * relative distance to \"isect\".\r\n\t\t */\r\n\t\tvar t1 = Geom.vertL1dist(org, isect);\r\n\t\tvar t2 = Geom.vertL1dist(dst, isect);\r\n\t\tvar w0 = (0.5 * t2) / (t1 + t2);\r\n\t\tvar w1 = (0.5 * t1) / (t1 + t2);\r\n\t\tisect.coords[0] += w0 * org.coords[0] + w1 * dst.coords[0];\r\n\t\tisect.coords[1] += w0 * org.coords[1] + w1 * dst.coords[1];\r\n\t\tisect.coords[2] += w0 * org.coords[2] + w1 * dst.coords[2];\r\n\t}\r\n\r\n\t//static void GetIntersectData( TESStesselator *tess, TESSvertex *isect, TESSvertex *orgUp, TESSvertex *dstUp, TESSvertex *orgLo, TESSvertex *dstLo )\r\n\tstatic getIntersectData(tess: Tesselator, isect:TESSvertex, orgUp:TESSvertex, dstUp:TESSvertex, orgLo:TESSvertex, dstLo:TESSvertex) {\r\n\t\t/*\r\n\t\t * We've computed a new intersection point, now we need a \"data\" pointer\r\n\t\t * from the user so that we can refer to this new vertex in the\r\n\t\t * rendering callbacks.\r\n\t\t */\r\n\t\tisect.coords[0] = isect.coords[1] = isect.coords[2] = 0;\r\n\t\tisect.idx = -1;\r\n\t\tSweep.vertexWeights(isect, orgUp, dstUp);\r\n\t\tSweep.vertexWeights(isect, orgLo, dstLo);\r\n\t}\r\n\r\n\t//static int CheckForRightSplice( TESStesselator *tess, ActiveRegion *regUp )\r\n\tstatic checkForRightSplice(tess:Tesselator, regUp:ActiveRegion) {\r\n\t\t/*\r\n\t\t * Check the upper and lower edge of \"regUp\", to make sure that the\r\n\t\t * eUp->Org is above eLo, or eLo->Org is below eUp (depending on which\r\n\t\t * origin is leftmost).\r\n\t\t *\r\n\t\t * The main purpose is to splice right-going edges with the same\r\n\t\t * dest vertex and nearly identical slopes (ie. we can't distinguish\r\n\t\t * the slopes numerically). However the splicing can also help us\r\n\t\t * to recover from numerical errors. For example, suppose at one\r\n\t\t * point we checked eUp and eLo, and decided that eUp->Org is barely\r\n\t\t * above eLo. Then later, we split eLo into two edges (eg. from\r\n\t\t * a splice operation like this one). This can change the result of\r\n\t\t * our test so that now eUp->Org is incident to eLo, or barely below it.\r\n\t\t * We must correct this condition to maintain the dictionary invariants.\r\n\t\t *\r\n\t\t * One possibility is to check these edges for intersection again\r\n\t\t * (ie. CheckForIntersect). This is what we do if possible. However\r\n\t\t * CheckForIntersect requires that tess->event lies between eUp and eLo,\r\n\t\t * so that it has something to fall back on when the intersection\r\n\t\t * calculation gives us an unusable answer. So, for those cases where\r\n\t\t * we can't check for intersection, this routine fixes the problem\r\n\t\t * by just splicing the offending vertex into the other edge.\r\n\t\t * This is a guaranteed solution, no matter how degenerate things get.\r\n\t\t * Basically this is a combinatorial solution to a numerical problem.\r\n\t\t */\r\n\t\tvar regLo = Sweep.regionBelow(regUp);\r\n\t\tvar eUp = regUp.eUp;\r\n\t\tvar eLo = regLo.eUp;\r\n\r\n\t\tif (Geom.vertLeq(eUp.Org, eLo.Org)) {\r\n\t\t\tif (Geom.edgeSign(eLo.Dst, eUp.Org, eLo.Org) > 0) return false;\r\n\r\n\t\t\t/* eUp->Org appears to be below eLo */\r\n\t\t\tif (!Geom.vertEq(eUp.Org, eLo.Org)) {\r\n\t\t\t\t/* Splice eUp->Org into eLo */\r\n\t\t\t\ttess.mesh.splitEdge(eLo.Sym);\r\n\t\t\t\ttess.mesh.splice(eUp, eLo.Oprev);\r\n\t\t\t\tregUp.dirty = regLo.dirty = true;\r\n\t\t\t} else if (eUp.Org !== eLo.Org) {\r\n\t\t\t\t/* merge the two vertices, discarding eUp->Org */\r\n\t\t\t\ttess.pq.delete(eUp.Org.pqHandle);\r\n\t\t\t\tSweep.spliceMergeVertices(tess, eLo.Oprev, eUp);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (Geom.edgeSign(eUp.Dst, eLo.Org, eUp.Org) < 0) return false;\r\n\r\n\t\t\t/* eLo->Org appears to be above eUp, so splice eLo->Org into eUp */\r\n\t\t\tSweep.regionAbove(regUp).dirty = regUp.dirty = true;\r\n\t\t\ttess.mesh.splitEdge(eUp.Sym);\r\n\t\t\ttess.mesh.splice(eLo.Oprev, eUp);\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\t//static int CheckForLeftSplice( TESStesselator *tess, ActiveRegion *regUp )\r\n\tstatic checkForLeftSplice(tess: Tesselator, regUp: ActiveRegion) {\r\n\t\t/*\r\n\t\t * Check the upper and lower edge of \"regUp\", to make sure that the\r\n\t\t * eUp->Dst is above eLo, or eLo->Dst is below eUp (depending on which\r\n\t\t * destination is rightmost).\r\n\t\t *\r\n\t\t * Theoretically, this should always be true. However, splitting an edge\r\n\t\t * into two pieces can change the results of previous tests. For example,\r\n\t\t * suppose at one point we checked eUp and eLo, and decided that eUp->Dst\r\n\t\t * is barely above eLo. Then later, we split eLo into two edges (eg. from\r\n\t\t * a splice operation like this one). This can change the result of\r\n\t\t * the test so that now eUp->Dst is incident to eLo, or barely below it.\r\n\t\t * We must correct this condition to maintain the dictionary invariants\r\n\t\t * (otherwise new edges might get inserted in the wrong place in the\r\n\t\t * dictionary, and bad stuff will happen).\r\n\t\t *\r\n\t\t * We fix the problem by just splicing the offending vertex into the\r\n\t\t * other edge.\r\n\t\t */\r\n\t\tvar regLo = Sweep.regionBelow(regUp);\r\n\t\tvar eUp = regUp.eUp;\r\n\t\tvar eLo = regLo.eUp;\r\n\t\tvar e;\r\n\r\n\t\tassert(!Geom.vertEq(eUp.Dst, eLo.Dst));\r\n\r\n\t\tif (Geom.vertLeq(eUp.Dst, eLo.Dst)) {\r\n\t\t\tif (Geom.edgeSign(eUp.Dst, eLo.Dst, eUp.Org) < 0) return false;\r\n\r\n\t\t\t/* eLo->Dst is above eUp, so splice eLo->Dst into eUp */\r\n\t\t\tSweep.regionAbove(regUp).dirty = regUp.dirty = true;\r\n\t\t\te = tess.mesh.splitEdge(eUp);\r\n\t\t\ttess.mesh.splice(eLo.Sym, e);\r\n\t\t\te.Lface.inside = regUp.inside;\r\n\t\t} else {\r\n\t\t\tif (Geom.edgeSign(eLo.Dst, eUp.Dst, eLo.Org) > 0) return false;\r\n\r\n\t\t\t/* eUp->Dst is below eLo, so splice eUp->Dst into eLo */\r\n\t\t\tregUp.dirty = regLo.dirty = true;\r\n\t\t\te = tess.mesh.splitEdge(eLo);\r\n\t\t\ttess.mesh.splice(eUp.Lnext, eLo.Sym);\r\n\t\t\te.Rface.inside = regUp.inside;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\t//static int CheckForIntersect( TESStesselator *tess, ActiveRegion *regUp )\r\n\tstatic checkForIntersect(tess: Tesselator, regUp: ActiveRegion) {\r\n\t\t/*\r\n\t\t * Check the upper and lower edges of the given region to see if\r\n\t\t * they intersect. If so, create the intersection and add it\r\n\t\t * to the data structures.\r\n\t\t *\r\n\t\t * Returns TRUE if adding the new intersection resulted in a recursive\r\n\t\t * call to AddRightEdges(); in this case all \"dirty\" regions have been\r\n\t\t * checked for intersections, and possibly regUp has been deleted.\r\n\t\t */\r\n\t\tvar regLo = Sweep.regionBelow(regUp);\r\n\t\tvar eUp = regUp.eUp;\r\n\t\tvar eLo = regLo.eUp;\r\n\t\tvar orgUp = eUp.Org;\r\n\t\tvar orgLo = eLo.Org;\r\n\t\tvar dstUp = eUp.Dst;\r\n\t\tvar dstLo = eLo.Dst;\r\n\t\tvar tMinUp, tMaxLo;\r\n\t\tvar isect = new TESSvertex(),\r\n\t\t\torgMin;\r\n\t\tvar e;\r\n\r\n\t\tassert(!Geom.vertEq(dstLo, dstUp));\r\n\t\tassert(Geom.edgeSign(dstUp, tess.event, orgUp) <= 0);\r\n\t\tassert(Geom.edgeSign(dstLo, tess.event, orgLo) >= 0);\r\n\t\tassert(orgUp !== tess.event && orgLo !== tess.event);\r\n\t\tassert(!regUp.fixUpperEdge && !regLo.fixUpperEdge);\r\n\r\n\t\tif (orgUp === orgLo) return false; /* right endpoints are the same */\r\n\r\n\t\ttMinUp = Math.min(orgUp.t, dstUp.t);\r\n\t\ttMaxLo = Math.max(orgLo.t, dstLo.t);\r\n\t\tif (tMinUp > tMaxLo) return false; /* t ranges do not overlap */\r\n\r\n\t\tif (Geom.vertLeq(orgUp, orgLo)) {\r\n\t\t\tif (Geom.edgeSign(dstLo, orgUp, orgLo) > 0) return false;\r\n\t\t} else {\r\n\t\t\tif (Geom.edgeSign(dstUp, orgLo, orgUp) < 0) return false;\r\n\t\t}\r\n\r\n\t\t/* At this point the edges intersect, at least marginally */\r\n\t\tSweep.debugEvent(tess);\r\n\r\n\t\tGeom.intersect(dstUp, orgUp, dstLo, orgLo, isect);\r\n\t\t/* The following properties are guaranteed: */\r\n\t\tassert(Math.min(orgUp.t, dstUp.t) <= isect.t);\r\n\t\tassert(isect.t <= Math.max(orgLo.t, dstLo.t));\r\n\t\tassert(Math.min(dstLo.s, dstUp.s) <= isect.s);\r\n\t\tassert(isect.s <= Math.max(orgLo.s, orgUp.s));\r\n\r\n\t\tif (Geom.vertLeq(isect, tess.event)) {\r\n\t\t\t/* The intersection point lies slightly to the left of the sweep line,\r\n\t\t\t * so move it until it''s slightly to the right of the sweep line.\r\n\t\t\t * (If we had perfect numerical precision, this would never happen\r\n\t\t\t * in the first place). The easiest and safest thing to do is\r\n\t\t\t * replace the intersection by tess->event.\r\n\t\t\t */\r\n\t\t\tisect.s = tess.event.s;\r\n\t\t\tisect.t = tess.event.t;\r\n\t\t}\r\n\t\t/* Similarly, if the computed intersection lies to the right of the\r\n\t\t * rightmost origin (which should rarely happen), it can cause\r\n\t\t * unbelievable inefficiency on sufficiently degenerate inputs.\r\n\t\t * (If you have the test program, try running test54.d with the\r\n\t\t * \"X zoom\" option turned on).\r\n\t\t */\r\n\t\torgMin = Geom.vertLeq(orgUp, orgLo) ? orgUp : orgLo;\r\n\t\tif (Geom.vertLeq(orgMin, isect)) {\r\n\t\t\tisect.s = orgMin.s;\r\n\t\t\tisect.t = orgMin.t;\r\n\t\t}\r\n\r\n\t\tif (Geom.vertEq(isect, orgUp) || Geom.vertEq(isect, orgLo)) {\r\n\t\t\t/* Easy case -- intersection at one of the right endpoints */\r\n\t\t\tSweep.checkForRightSplice(tess, regUp);\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\t(!Geom.vertEq(dstUp, tess.event) &&\r\n\t\t\t\tGeom.edgeSign(dstUp, tess.event, isect) >= 0) ||\r\n\t\t\t(!Geom.vertEq(dstLo, tess.event) &&\r\n\t\t\t\tGeom.edgeSign(dstLo, tess.event, isect) <= 0)\r\n\t\t) {\r\n\t\t\t/* Very unusual -- the new upper or lower edge would pass on the\r\n\t\t\t * wrong side of the sweep event, or through it. This can happen\r\n\t\t\t * due to very small numerical errors in the intersection calculation.\r\n\t\t\t */\r\n\t\t\tif (dstLo === tess.event) {\r\n\t\t\t\t/* Splice dstLo into eUp, and process the new region(s) */\r\n\t\t\t\ttess.mesh.splitEdge(eUp.Sym);\r\n\t\t\t\ttess.mesh.splice(eLo.Sym, eUp);\r\n\t\t\t\tregUp = Sweep.topLeftRegion(tess, regUp);\r\n\t\t\t\t//\t\t\tif (regUp == NULL) longjmp(tess->env,1);\r\n\t\t\t\teUp = Sweep.regionBelow(regUp).eUp;\r\n\t\t\t\tSweep.finishLeftRegions(tess, Sweep.regionBelow(regUp), regLo);\r\n\t\t\t\tSweep.addRightEdges(tess, regUp, eUp.Oprev, eUp, eUp, true);\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\tif (dstUp === tess.event) {\r\n\t\t\t\t/* Splice dstUp into eLo, and process the new region(s) */\r\n\t\t\t\ttess.mesh.splitEdge(eLo.Sym);\r\n\t\t\t\ttess.mesh.splice(eUp.Lnext, eLo.Oprev);\r\n\t\t\t\tregLo = regUp;\r\n\t\t\t\tregUp = Sweep.topRightRegion(regUp);\r\n\t\t\t\te = Sweep.regionBelow(regUp).eUp.Rprev;\r\n\t\t\t\tregLo.eUp = eLo.Oprev;\r\n\t\t\t\teLo = Sweep.finishLeftRegions(tess, regLo, null);\r\n\t\t\t\tSweep.addRightEdges(tess, regUp, eLo.Onext, eUp.Rprev, e, true);\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\t/* Special case: called from ConnectRightVertex. If either\r\n\t\t\t * edge passes on the wrong side of tess->event, split it\r\n\t\t\t * (and wait for ConnectRightVertex to splice it appropriately).\r\n\t\t\t */\r\n\t\t\tif (Geom.edgeSign(dstUp, tess.event, isect) >= 0) {\r\n\t\t\t\tSweep.regionAbove(regUp).dirty = regUp.dirty = true;\r\n\t\t\t\ttess.mesh.splitEdge(eUp.Sym);\r\n\t\t\t\teUp.Org.s = tess.event.s;\r\n\t\t\t\teUp.Org.t = tess.event.t;\r\n\t\t\t}\r\n\t\t\tif (Geom.edgeSign(dstLo, tess.event, isect) <= 0) {\r\n\t\t\t\tregUp.dirty = regLo.dirty = true;\r\n\t\t\t\ttess.mesh.splitEdge(eLo.Sym);\r\n\t\t\t\teLo.Org.s = tess.event.s;\r\n\t\t\t\teLo.Org.t = tess.event.t;\r\n\t\t\t}\r\n\t\t\t/* leave the rest for ConnectRightVertex */\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t/* General case -- split both edges, splice into new vertex.\r\n\t\t * When we do the splice operation, the order of the arguments is\r\n\t\t * arbitrary as far as correctness goes. However, when the operation\r\n\t\t * creates a new face, the work done is proportional to the size of\r\n\t\t * the new face. We expect the faces in the processed part of\r\n\t\t * the mesh (ie. eUp->Lface) to be smaller than the faces in the\r\n\t\t * unprocessed original contours (which will be eLo->Oprev->Lface).\r\n\t\t */\r\n\t\ttess.mesh.splitEdge(eUp.Sym);\r\n\t\ttess.mesh.splitEdge(eLo.Sym);\r\n\t\ttess.mesh.splice(eLo.Oprev, eUp);\r\n\t\teUp.Org.s = isect.s;\r\n\t\teUp.Org.t = isect.t;\r\n\t\teUp.Org.pqHandle = tess.pq.insert(eUp.Org);\r\n\t\tSweep.getIntersectData(tess, eUp.Org, orgUp, dstUp, orgLo, dstLo);\r\n\t\tSweep.regionAbove(regUp).dirty = regUp.dirty = regLo.dirty = true;\r\n\t\treturn false;\r\n\t}\r\n\r\n\t//static void WalkDirtyRegions( TESStesselator *tess, ActiveRegion *regUp )\r\n\tstatic walkDirtyRegions(tess: Tesselator, regUp: ActiveRegion) {\r\n\t\t/*\r\n\t\t * When the upper or lower edge of any region changes, the region is\r\n\t\t * marked \"dirty\". This routine walks through all the dirty regions\r\n\t\t * and makes sure that the dictionary invariants are satisfied\r\n\t\t * (see the comments at the beginning of this file). Of course\r\n\t\t * new dirty regions can be created as we make changes to restore\r\n\t\t * the invariants.\r\n\t\t */\r\n\t\tvar regLo = Sweep.regionBelow(regUp);\r\n\t\tvar eUp, eLo;\r\n\r\n\t\tfor (;;) {\r\n\t\t\t/* Find the lowest dirty region (we walk from the bottom up). */\r\n\t\t\twhile (regLo.dirty) {\r\n\t\t\t\tregUp = regLo;\r\n\t\t\t\tregLo = Sweep.regionBelow(regLo);\r\n\t\t\t}\r\n\t\t\tif (!regUp.dirty) {\r\n\t\t\t\tregLo = regUp;\r\n\t\t\t\tregUp = Sweep.regionAbove(regUp);\r\n\t\t\t\tif (regUp === null || !regUp.dirty) {\r\n\t\t\t\t\t/* We've walked all the dirty regions */\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tregUp.dirty = false;\r\n\t\t\teUp = regUp.eUp;\r\n\t\t\teLo = regLo.eUp;\r\n\r\n\t\t\tif (eUp.Dst !== eLo.Dst) {\r\n\t\t\t\t/* Check that the edge ordering is obeyed at the Dst vertices. */\r\n\t\t\t\tif (Sweep.checkForLeftSplice(tess, regUp)) {\r\n\t\t\t\t\t/* If the upper or lower edge was marked fixUpperEdge, then\r\n\t\t\t\t\t * we no longer need it (since these edges are needed only for\r\n\t\t\t\t\t * vertices which otherwise have no right-going edges).\r\n\t\t\t\t\t */\r\n\t\t\t\t\tif (regLo.fixUpperEdge) {\r\n\t\t\t\t\t\tSweep.deleteRegion(tess, regLo);\r\n\t\t\t\t\t\ttess.mesh.delete(eLo);\r\n\t\t\t\t\t\tregLo = Sweep.regionBelow(regUp);\r\n\t\t\t\t\t\teLo = regLo.eUp;\r\n\t\t\t\t\t} else if (regUp.fixUpperEdge) {\r\n\t\t\t\t\t\tSweep.deleteRegion(tess, regUp);\r\n\t\t\t\t\t\ttess.mesh.delete(eUp);\r\n\t\t\t\t\t\tregUp = Sweep.regionAbove(regLo);\r\n\t\t\t\t\t\teUp = regUp.eUp;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (eUp.Org !== eLo.Org) {\r\n\t\t\t\tif (\r\n\t\t\t\t\teUp.Dst !== eLo.Dst &&\r\n\t\t\t\t\t!regUp.fixUpperEdge &&\r\n\t\t\t\t\t!regLo.fixUpperEdge &&\r\n\t\t\t\t\t(eUp.Dst === tess.event || eLo.Dst === tess.event)\r\n\t\t\t\t) {\r\n\t\t\t\t\t/* When all else fails in CheckForIntersect(), it uses tess->event\r\n\t\t\t\t\t * as the intersection location. To make this possible, it requires\r\n\t\t\t\t\t * that tess->event lie between the upper and lower edges, and also\r\n\t\t\t\t\t * that neither of these is marked fixUpperEdge (since in the worst\r\n\t\t\t\t\t * case it might splice one of these edges into tess->event, and\r\n\t\t\t\t\t * violate the invariant that fixable edges are the only right-going\r\n\t\t\t\t\t * edge from their associated vertex).\r\n\t\t\t\t\t */\r\n\t\t\t\t\tif (Sweep.checkForIntersect(tess, regUp)) {\r\n\t\t\t\t\t\t/* WalkDirtyRegions() was called recursively; we're done */\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t/* Even though we can't use CheckForIntersect(), the Org vertices\r\n\t\t\t\t\t * may violate the dictionary edge ordering. Check and correct this.\r\n\t\t\t\t\t */\r\n\t\t\t\t\tSweep.checkForRightSplice(tess, regUp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (eUp.Org === eLo.Org && eUp.Dst === eLo.Dst) {\r\n\t\t\t\t/* A degenerate loop consisting of only two edges -- delete it. */\r\n\t\t\t\tSweep.addWinding(eLo, eUp);\r\n\t\t\t\tSweep.deleteRegion(tess, regUp);\r\n\t\t\t\ttess.mesh.delete(eUp);\r\n\t\t\t\tregUp = Sweep.regionAbove(regLo);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t//static void ConnectRightVertex( TESStesselator *tess, ActiveRegion *regUp, TESShalfEdge *eBottomLeft )\r\n\tstatic connectRightVertex(tess: Tesselator, regUp: ActiveRegion, eBottomLeft: TESShalfEdge) {\r\n\t\t/*\r\n\t\t * Purpose: connect a \"right\" vertex vEvent (one where all edges go left)\r\n\t\t * to the unprocessed portion of the mesh. Since there are no right-going\r\n\t\t * edges, two regions (one above vEvent and one below) are being merged\r\n\t\t * into one. \"regUp\" is the upper of these two regions.\r\n\t\t *\r\n\t\t * There are two reasons for doing this (adding a right-going edge):\r\n\t\t * - if the two regions being merged are \"inside\", we must add an edge\r\n\t\t * to keep them separated (the combined region would not be monotone).\r\n\t\t * - in any case, we must leave some record of vEvent in the dictionary,\r\n\t\t * so that we can merge vEvent with features that we have not seen yet.\r\n\t\t * For example, maybe there is a vertical edge which passes just to\r\n\t\t * the right of vEvent; we would like to splice vEvent into this edge.\r\n\t\t *\r\n\t\t * However, we don't want to connect vEvent to just any vertex. We don''t\r\n\t\t * want the new edge to cross any other edges; otherwise we will create\r\n\t\t * intersection vertices even when the input data had no self-intersections.\r\n\t\t * (This is a bad thing; if the user's input data has no intersections,\r\n\t\t * we don't want to generate any false intersections ourselves.)\r\n\t\t *\r\n\t\t * Our eventual goal is to connect vEvent to the leftmost unprocessed\r\n\t\t * vertex of the combined region (the union of regUp and regLo).\r\n\t\t * But because of unseen vertices with all right-going edges, and also\r\n\t\t * new vertices which may be created by edge intersections, we don''t\r\n\t\t * know where that leftmost unprocessed vertex is. In the meantime, we\r\n\t\t * connect vEvent to the closest vertex of either chain, and mark the region\r\n\t\t * as \"fixUpperEdge\". This flag says to delete and reconnect this edge\r\n\t\t * to the next processed vertex on the boundary of the combined region.\r\n\t\t * Quite possibly the vertex we connected to will turn out to be the\r\n\t\t * closest one, in which case we won''t need to make any changes.\r\n\t\t */\r\n\t\tvar eNew;\r\n\t\tvar eTopLeft = eBottomLeft.Onext;\r\n\t\tvar regLo = Sweep.regionBelow(regUp);\r\n\t\tvar eUp = regUp.eUp;\r\n\t\tvar eLo = regLo.eUp;\r\n\t\tvar degenerate = false;\r\n\r\n\t\tif (eUp.Dst !== eLo.Dst) {\r\n\t\t\tSweep.checkForIntersect(tess, regUp);\r\n\t\t}\r\n\r\n\t\t/* Possible new degeneracies: upper or lower edge of regUp may pass\r\n\t\t * through vEvent, or may coincide with new intersection vertex\r\n\t\t */\r\n\t\tif (Geom.vertEq(eUp.Org, tess.event)) {\r\n\t\t\ttess.mesh.splice(eTopLeft.Oprev, eUp);\r\n\t\t\tregUp = Sweep.topLeftRegion(tess, regUp);\r\n\t\t\teTopLeft = Sweep.regionBelow(regUp).eUp;\r\n\t\t\tSweep.finishLeftRegions(tess, Sweep.regionBelow(regUp), regLo);\r\n\t\t\tdegenerate = true;\r\n\t\t}\r\n\t\tif (Geom.vertEq(eLo.Org, tess.event)) {\r\n\t\t\ttess.mesh.splice(eBottomLeft, eLo.Oprev);\r\n\t\t\teBottomLeft = Sweep.finishLeftRegions(tess, regLo, null);\r\n\t\t\tdegenerate = true;\r\n\t\t}\r\n\t\tif (degenerate) {\r\n\t\t\tSweep.addRightEdges(\r\n\t\t\t\ttess,\r\n\t\t\t\tregUp,\r\n\t\t\t\teBottomLeft.Onext,\r\n\t\t\t\teTopLeft,\r\n\t\t\t\teTopLeft,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t/* Non-degenerate situation -- need to add a temporary, fixable edge.\r\n\t\t * Connect to the closer of eLo->Org, eUp->Org.\r\n\t\t */\r\n\t\tif (Geom.vertLeq(eLo.Org, eUp.Org)) {\r\n\t\t\teNew = eLo.Oprev;\r\n\t\t} else {\r\n\t\t\teNew = eUp;\r\n\t\t}\r\n\t\teNew = tess.mesh.connect(eBottomLeft.Lprev, eNew);\r\n\r\n\t\t/* Prevent cleanup, otherwise eNew might disappear before we've even\r\n\t\t * had a chance to mark it as a temporary edge.\r\n\t\t */\r\n\t\tSweep.addRightEdges(tess, regUp, eNew, eNew.Onext, eNew.Onext, false);\r\n\t\teNew.Sym.activeRegion.fixUpperEdge = true;\r\n\t\tSweep.walkDirtyRegions(tess, regUp);\r\n\t}\r\n\r\n\t/* Because vertices at exactly the same location are merged together\r\n\t * before we process the sweep event, some degenerate cases can't occur.\r\n\t * However if someone eventually makes the modifications required to\r\n\t * merge features which are close together, the cases below marked\r\n\t * TOLERANCE_NONZERO will be useful. They were debugged before the\r\n\t * code to merge identical vertices in the main loop was added.\r\n\t */\r\n\t//#define TOLERANCE_NONZERO\tFALSE\r\n\r\n\t//static void ConnectLeftDegenerate( TESStesselator *tess, ActiveRegion *regUp, TESSvertex *vEvent )\r\n\tstatic connectLeftDegenerate(tess: Tesselator, regUp: ActiveRegion, vEvent: TESSvertex) {\r\n\t\t/*\r\n\t\t * The event vertex lies exacty on an already-processed edge or vertex.\r\n\t\t * Adding the new vertex involves splicing it into the already-processed\r\n\t\t * part of the mesh.\r\n\t\t */\r\n\t\tvar e, eTopLeft, eTopRight, eLast;\r\n\t\tvar reg;\r\n\r\n\t\te = regUp.eUp;\r\n\t\tif (Geom.vertEq(e.Org, vEvent)) {\r\n\t\t\t/* e->Org is an unprocessed vertex - just combine them, and wait\r\n\t\t\t * for e->Org to be pulled from the queue\r\n\t\t\t */\r\n\t\t\tassert(false /*TOLERANCE_NONZERO*/);\r\n\t\t\tSweep.spliceMergeVertices(tess, e, vEvent.anEdge);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!Geom.vertEq(e.Dst, vEvent)) {\r\n\t\t\t/* General case -- splice vEvent into edge e which passes through it */\r\n\t\t\ttess.mesh.splitEdge(e.Sym);\r\n\t\t\tif (regUp.fixUpperEdge) {\r\n\t\t\t\t/* This edge was fixable -- delete unused portion of original edge */\r\n\t\t\t\ttess.mesh.delete(e.Onext);\r\n\t\t\t\tregUp.fixUpperEdge = false;\r\n\t\t\t}\r\n\t\t\ttess.mesh.splice(vEvent.anEdge, e);\r\n\t\t\tSweep.sweepEvent(tess, vEvent); /* recurse */\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t/* vEvent coincides with e->Dst, which has already been processed.\r\n\t\t * Splice in the additional right-going edges.\r\n\t\t */\r\n\t\tassert(false /*TOLERANCE_NONZERO*/);\r\n\t\tregUp = Sweep.topRightRegion(regUp);\r\n\t\treg = Sweep.regionBelow(regUp);\r\n\t\teTopRight = reg.eUp.Sym;\r\n\t\teTopLeft = eLast = eTopRight.Onext;\r\n\t\tif (reg.fixUpperEdge) {\r\n\t\t\t/* Here e->Dst has only a single fixable edge going right.\r\n\t\t\t * We can delete it since now we have some real right-going edges.\r\n\t\t\t */\r\n\t\t\tassert(eTopLeft !== eTopRight); /* there are some left edges too */\r\n\t\t\tSweep.deleteRegion(tess, reg);\r\n\t\t\ttess.mesh.delete(eTopRight);\r\n\t\t\teTopRight = eTopLeft.Oprev;\r\n\t\t}\r\n\t\ttess.mesh.splice(vEvent.anEdge, eTopRight);\r\n\t\tif (!Geom.edgeGoesLeft(eTopLeft)) {\r\n\t\t\t/* e->Dst had no left-going edges -- indicate this to AddRightEdges() */\r\n\t\t\teTopLeft = null;\r\n\t\t}\r\n\t\tSweep.addRightEdges(\r\n\t\t\ttess,\r\n\t\t\tregUp,\r\n\t\t\teTopRight.Onext,\r\n\t\t\teLast,\r\n\t\t\teTopLeft,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t}\r\n\r\n\t//static void ConnectLeftVertex( TESStesselator *tess, TESSvertex *vEvent )\r\n\tstatic connectLeftVertex(tess: Tesselator, vEvent: TESSvertex) {\r\n\t\t/*\r\n\t\t * Purpose: connect a \"left\" vertex (one where both edges go right)\r\n\t\t * to the processed portion of the mesh. Let R be the active region\r\n\t\t * containing vEvent, and let U and L be the upper and lower edge\r\n\t\t * chains of R. There are two possibilities:\r\n\t\t *\r\n\t\t * - the normal case: split R into two regions, by connecting vEvent to\r\n\t\t * the rightmost vertex of U or L lying to the left of the sweep line\r\n\t\t *\r\n\t\t * - the degenerate case: if vEvent is close enough to U or L, we\r\n\t\t * merge vEvent into that edge chain. The subcases are:\r\n\t\t *\t- merging with the rightmost vertex of U or L\r\n\t\t *\t- merging with the active edge of U or L\r\n\t\t *\t- merging with an already-processed portion of U or L\r\n\t\t */\r\n\t\tvar regUp, regLo, reg;\r\n\t\tvar eUp, eLo, eNew;\r\n\t\tvar tmp = new ActiveRegion();\r\n\r\n\t\t/* assert( vEvent->anEdge->Onext->Onext == vEvent->anEdge ); */\r\n\r\n\t\t/* Get a pointer to the active region containing vEvent */\r\n\t\ttmp.eUp = vEvent.anEdge.Sym; /* tessDictListSearch */\r\n\t\t/* __GL_DICTLISTKEY */ regUp = tess.dict.search(tmp).key;\r\n\t\tregLo = Sweep.regionBelow(regUp);\r\n\t\tif (!regLo) {\r\n\t\t\t// This may happen if the input polygon is coplanar.\r\n\t\t\treturn;\r\n\t\t}\r\n\t\teUp = regUp.eUp;\r\n\t\teLo = regLo.eUp;\r\n\r\n\t\t/* Try merging with U or L first */\r\n\t\tif (Geom.edgeSign(eUp.Dst, vEvent, eUp.Org) === 0.0) {\r\n\t\t\tSweep.connectLeftDegenerate(tess, regUp, vEvent);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t/* Connect vEvent to rightmost processed vertex of either chain.\r\n\t\t * e->Dst is the vertex that we will connect to vEvent.\r\n\t\t */\r\n\t\treg = Geom.vertLeq(eLo.Dst, eUp.Dst) ? regUp : regLo;\r\n\r\n\t\tif (regUp.inside || reg.fixUpperEdge) {\r\n\t\t\tif (reg === regUp) {\r\n\t\t\t\teNew = tess.mesh.connect(vEvent.anEdge.Sym, eUp.Lnext);\r\n\t\t\t} else {\r\n\t\t\t\tvar tempHalfEdge = tess.mesh.connect(eLo.Dnext, vEvent.anEdge);\r\n\t\t\t\teNew = tempHalfEdge.Sym;\r\n\t\t\t}\r\n\t\t\tif (reg.fixUpperEdge) {\r\n\t\t\t\tSweep.fixUpperEdge(tess, reg, eNew);\r\n\t\t\t} else {\r\n\t\t\t\tSweep.computeWinding(\r\n\t\t\t\t\ttess,\r\n\t\t\t\t\tSweep.addRegionBelow(tess, regUp, eNew),\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tSweep.sweepEvent(tess, vEvent);\r\n\t\t} else {\r\n\t\t\t/* The new vertex is in a region which does not belong to the polygon.\r\n\t\t\t * We don''t need to connect this vertex to the rest of the mesh.\r\n\t\t\t */\r\n\t\t\tSweep.addRightEdges(\r\n\t\t\t\ttess,\r\n\t\t\t\tregUp,\r\n\t\t\t\tvEvent.anEdge,\r\n\t\t\t\tvEvent.anEdge,\r\n\t\t\t\tnull,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\t//static void SweepEvent( TESStesselator *tess, TESSvertex *vEvent )\r\n\tstatic sweepEvent(tess: Tesselator, vEvent: TESSvertex) {\r\n\t\t/*\r\n\t\t * Does everything necessary when the sweep line crosses a vertex.\r\n\t\t * Updates the mesh and the edge dictionary.\r\n\t\t */\r\n\r\n\t\ttess.event = vEvent; /* for access in EdgeLeq() */\r\n\t\tSweep.debugEvent(tess);\r\n\r\n\t\t/* Check if this vertex is the right endpoint of an edge that is\r\n\t\t * already in the dictionary. In this case we don't need to waste\r\n\t\t * time searching for the location to insert new edges.\r\n\t\t */\r\n\t\tvar e = vEvent.anEdge;\r\n\t\twhile (e.activeRegion === null) {\r\n\t\t\te = e.Onext;\r\n\t\t\tif (e === vEvent.anEdge) {\r\n\t\t\t\t/* All edges go right -- not incident to any processed edges */\r\n\t\t\t\tSweep.connectLeftVertex(tess, vEvent);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* Processing consists of two phases: first we \"finish\" all the\r\n\t\t * active regions where both the upper and lower edges terminate\r\n\t\t * at vEvent (ie. vEvent is closing off these regions).\r\n\t\t * We mark these faces \"inside\" or \"outside\" the polygon according\r\n\t\t * to their winding number, and delete the edges from the dictionary.\r\n\t\t * This takes care of all the left-going edges from vEvent.\r\n\t\t */\r\n\t\tvar regUp = Sweep.topLeftRegion(tess, e.activeRegion);\r\n\t\tassert(regUp !== null);\r\n\t\t//\tif (regUp == NULL) longjmp(tess->env,1);\r\n\t\tvar reg = Sweep.regionBelow(regUp);\r\n\t\tvar eTopLeft = reg.eUp;\r\n\t\tvar eBottomLeft = Sweep.finishLeftRegions(tess, reg, null);\r\n\r\n\t\t/* Next we process all the right-going edges from vEvent. This\r\n\t\t * involves adding the edges to the dictionary, and creating the\r\n\t\t * associated \"active regions\" which record information about the\r\n\t\t * regions between adjacent dictionary edges.\r\n\t\t */\r\n\t\tif (eBottomLeft.Onext === eTopLeft) {\r\n\t\t\t/* No right-going edges -- add a temporary \"fixable\" edge */\r\n\t\t\tSweep.connectRightVertex(tess, regUp, eBottomLeft);\r\n\t\t} else {\r\n\t\t\tSweep.addRightEdges(\r\n\t\t\t\ttess,\r\n\t\t\t\tregUp,\r\n\t\t\t\teBottomLeft.Onext,\r\n\t\t\t\teTopLeft,\r\n\t\t\t\teTopLeft,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\t/* Make the sentinel coordinates big enough that they will never be\r\n\t * merged with real input features.\r\n\t */\r\n\r\n\t//static void AddSentinel( TESStesselator *tess, TESSreal smin, TESSreal smax, TESSreal t )\r\n\tstatic addSentinel(tess: Tesselator, smin: number, smax: number, t: number) {\r\n\t\t/*\r\n\t\t * We add two sentinel edges above and below all other edges,\r\n\t\t * to avoid special cases at the top and bottom.\r\n\t\t */\r\n\t\tvar reg = new ActiveRegion();\r\n\t\tvar e = tess.mesh.makeEdge();\r\n\t\t//\tif (e == NULL) longjmp(tess->env,1);\r\n\r\n\t\te.Org.s = smax;\r\n\t\te.Org.t = t;\r\n\t\te.Dst.s = smin;\r\n\t\te.Dst.t = t;\r\n\t\ttess.event = e.Dst; /* initialize it */\r\n\r\n\t\treg.eUp = e;\r\n\t\treg.windingNumber = 0;\r\n\t\treg.inside = false;\r\n\t\treg.fixUpperEdge = false;\r\n\t\treg.sentinel = true;\r\n\t\treg.dirty = false;\r\n\t\treg.nodeUp = tess.dict.insert(reg);\r\n\t\t//\tif (reg->nodeUp == NULL) longjmp(tess->env,1);\r\n\t}\r\n\r\n\t//static void InitEdgeDict( TESStesselator *tess )\r\n\tstatic initEdgeDict(tess: Tesselator) {\r\n\t\t/*\r\n\t\t * We maintain an ordering of edge intersections with the sweep line.\r\n\t\t * This order is maintained in a dynamic dictionary.\r\n\t\t */\r\n\t\ttess.dict = new Dict(tess, Sweep.edgeLeq);\r\n\t\t//\tif (tess->dict == NULL) longjmp(tess->env,1);\r\n\r\n\t\tvar w = tess.bmax[0] - tess.bmin[0];\r\n\t\tvar h = tess.bmax[1] - tess.bmin[1];\r\n\r\n\t\tvar smin = tess.bmin[0] - w;\r\n\t\tvar smax = tess.bmax[0] + w;\r\n\t\tvar tmin = tess.bmin[1] - h;\r\n\t\tvar tmax = tess.bmax[1] + h;\r\n\r\n\t\tSweep.addSentinel(tess, smin, smax, tmin);\r\n\t\tSweep.addSentinel(tess, smin, smax, tmax);\r\n\t}\r\n\r\n\tstatic doneEdgeDict(tess: Tesselator) {\r\n\t\tvar reg;\r\n\t\tvar fixedEdges = 0;\r\n\r\n\t\twhile ((reg = tess.dict.min().key) !== null) {\r\n\t\t\t/*\r\n\t\t\t * At the end of all processing, the dictionary should contain\r\n\t\t\t * only the two sentinel edges, plus at most one \"fixable\" edge\r\n\t\t\t * created by ConnectRightVertex().\r\n\t\t\t */\r\n\t\t\tif (!reg.sentinel) {\r\n\t\t\t\tassert(reg.fixUpperEdge);\r\n\t\t\t\tassert(++fixedEdges === 1);\r\n\t\t\t}\r\n\t\t\tassert(reg.windingNumber === 0);\r\n\t\t\tSweep.deleteRegion(tess, reg);\r\n\t\t\t/* tessMeshDelete( reg->eUp );*/\r\n\t\t}\r\n\t\t//\tdictDeleteDict( &tess->alloc, tess->dict );\r\n\t}\r\n\r\n\tstatic removeDegenerateEdges(tess:Tesselator) {\r\n\t\t/*\r\n\t\t * Remove zero-length edges, and contours with fewer than 3 vertices.\r\n\t\t */\r\n\t\tvar e, eNext, eLnext;\r\n\t\tvar eHead = tess.mesh.eHead;\r\n\r\n\t\t/*LINTED*/\r\n\t\tfor (e = eHead.next; e !== eHead; e = eNext) {\r\n\t\t\teNext = e.next;\r\n\t\t\teLnext = e.Lnext;\r\n\r\n\t\t\tif (Geom.vertEq(e.Org, e.Dst) && e.Lnext.Lnext !== e) {\r\n\t\t\t\t/* Zero-length edge, contour has at least 3 edges */\r\n\t\t\t\tSweep.spliceMergeVertices(tess, eLnext, e); /* deletes e->Org */\r\n\t\t\t\ttess.mesh.delete(e); /* e is a self-loop */\r\n\t\t\t\te = eLnext;\r\n\t\t\t\teLnext = e.Lnext;\r\n\t\t\t}\r\n\t\t\tif (eLnext.Lnext === e) {\r\n\t\t\t\t/* Degenerate contour (one or two edges) */\r\n\t\t\t\tif (eLnext !== e) {\r\n\t\t\t\t\tif (eLnext === eNext || eLnext === eNext.Sym) {\r\n\t\t\t\t\t\teNext = eNext.next;\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttess.mesh.delete(eLnext);\r\n\t\t\t\t}\r\n\t\t\t\tif (e === eNext || e === eNext.Sym) {\r\n\t\t\t\t\teNext = eNext.next;\r\n\t\t\t\t}\r\n\t\t\t\ttess.mesh.delete(e);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic initPriorityQ(tess:Tesselator) {\r\n\t\t/*\r\n\t\t * Insert all vertices into the priority queue which determines the\r\n\t\t * order in which vertices cross the sweep line.\r\n\t\t */\r\n\t\tvar pq;\r\n\t\tvar v, vHead;\r\n\t\tvar vertexCount = 0;\r\n\r\n\t\tvHead = tess.mesh.vHead;\r\n\t\tfor (v = vHead.next; v !== vHead; v = v.next) {\r\n\t\t\tvertexCount++;\r\n\t\t}\r\n\t\t/* Make sure there is enough space for sentinels. */\r\n\t\tvertexCount += 8; //MAX( 8, tess->alloc.extraVertices );\r\n\r\n\t\tpq = tess.pq = new PriorityQ(vertexCount, Geom.vertLeq);\r\n\t\t//\tif (pq == NULL) return 0;\r\n\r\n\t\tvHead = tess.mesh.vHead;\r\n\t\tfor (v = vHead.next; v !== vHead; v = v.next) {\r\n\t\t\tv.pqHandle = pq.insert(v);\r\n\t\t\t//\t\tif (v.pqHandle == INV_HANDLE)\r\n\t\t\t//\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tif (v !== vHead) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tpq.init();\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\tstatic donePriorityQ(tess: Tesselator) {\r\n\t\ttess.pq = null;\r\n\t}\r\n\r\n\tstatic removeDegenerateFaces(tess: Tesselator, mesh:TESSmesh) {\r\n\t\t/*\r\n\t\t * Delete any degenerate faces with only two edges. WalkDirtyRegions()\r\n\t\t * will catch almost all of these, but it won't catch degenerate faces\r\n\t\t * produced by splice operations on already-processed edges.\r\n\t\t * The two places this can happen are in FinishLeftRegions(), when\r\n\t\t * we splice in a \"temporary\" edge produced by ConnectRightVertex(),\r\n\t\t * and in CheckForLeftSplice(), where we splice already-processed\r\n\t\t * edges to ensure that our dictionary invariants are not violated\r\n\t\t * by numerical errors.\r\n\t\t *\r\n\t\t * In both these cases it is *very* dangerous to delete the offending\r\n\t\t * edge at the time, since one of the routines further up the stack\r\n\t\t * will sometimes be keeping a pointer to that edge.\r\n\t\t */\r\n\t\tvar f, fNext;\r\n\t\tvar e;\r\n\r\n\t\t/*LINTED*/\r\n\t\tfor (f = mesh.fHead.next; f !== mesh.fHead; f = fNext) {\r\n\t\t\tfNext = f.next;\r\n\t\t\te = f.anEdge;\r\n\t\t\tassert(e.Lnext !== e);\r\n\r\n\t\t\tif (e.Lnext.Lnext === e) {\r\n\t\t\t\t/* A face with only two edges */\r\n\t\t\t\tSweep.addWinding(e.Onext, e);\r\n\t\t\t\ttess.mesh.delete(e);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\tstatic computeInterior(tess:Tesselator, validate: boolean = true) {\r\n\t\t/*\r\n\t\t * tessComputeInterior( tess ) computes the planar arrangement specified\r\n\t\t * by the given contours, and further subdivides this arrangement\r\n\t\t * into regions. Each region is marked \"inside\" if it belongs\r\n\t\t * to the polygon, according to the rule given by tess->windingRule.\r\n\t\t * Each interior region is guaranteed be monotone.\r\n\t\t */\r\n\t\tvar v, vNext;\r\n\r\n\t\t/* Each vertex defines an event for our sweep line. Start by inserting\r\n\t\t * all the vertices in a priority queue. Events are processed in\r\n\t\t * lexicographic order, ie.\r\n\t\t *\r\n\t\t *\te1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y)\r\n\t\t */\r\n\t\tSweep.removeDegenerateEdges(tess);\r\n\t\t\r\n\t\t/* if error */\r\n\t\tif (!Sweep.initPriorityQ(tess)) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tSweep.initEdgeDict(tess);\r\n\r\n\t\twhile ((v = tess.pq.extractMin()) !== null) {\r\n\t\t\tfor (;;) {\r\n\t\t\t\tvNext = tess.pq.min();\r\n\t\t\t\tif (vNext === null || !Geom.vertEq(vNext, v)) break;\r\n\r\n\t\t\t\t/* Merge together all vertices at exactly the same location.\r\n\t\t\t\t * This is more efficient than processing them one at a time,\r\n\t\t\t\t * simplifies the code (see ConnectLeftDegenerate), and is also\r\n\t\t\t\t * important for correct handling of certain degenerate cases.\r\n\t\t\t\t * For example, suppose there are two identical edges A and B\r\n\t\t\t\t * that belong to different contours (so without this code they would\r\n\t\t\t\t * be processed by separate sweep events). Suppose another edge C\r\n\t\t\t\t * crosses A and B from above. When A is processed, we split it\r\n\t\t\t\t * at its intersection point with C. However this also splits C,\r\n\t\t\t\t * so when we insert B we may compute a slightly different\r\n\t\t\t\t * intersection point. This might leave two edges with a small\r\n\t\t\t\t * gap between them. This kind of error is especially obvious\r\n\t\t\t\t * when using boundary extraction (TESS_BOUNDARY_ONLY).\r\n\t\t\t\t */\r\n\t\t\t\tvNext = tess.pq.extractMin();\r\n\t\t\t\tSweep.spliceMergeVertices(tess, v.anEdge, vNext.anEdge);\r\n\t\t\t}\r\n\t\t\tSweep.sweepEvent(tess, v);\r\n\t\t}\r\n\r\n\t\t/* Set tess->event for debugging purposes */\r\n\t\ttess.event = tess.dict.min().key.eUp.Org;\r\n\r\n\t\tSweep.debugEvent(tess);\r\n\t\tSweep.doneEdgeDict(tess);\r\n\t\tSweep.donePriorityQ(tess);\r\n\r\n\t\tif (!Sweep.removeDegenerateFaces(tess, tess.mesh)) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tif(validate) {\r\n\t\t\ttess.mesh.check();\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n}\r\n", "import { WINDING, ELEMENT } from './utils/constants';\r\nimport { TESSmesh } from './mesh/TESSmesh';\r\nimport { Geom } from \"./utils/Geom\";\r\nimport { Sweep } from \"./utils/Sweep\";\r\nimport { TESShalfEdge } from './mesh/TESShalfEdge';\r\nimport { PriorityQ } from './utils/PriorityQ';\r\nimport { Dict } from './utils/Dict';\r\n\r\nexport type V3 = [number, number, number | 0];\r\nexport type V2 = [number, number];\r\n\r\ntype TESSface = any;\r\n//type TESSmesh = any;\r\ntype TESSedge = any;\r\n\r\nexport class Tesselator {\r\n\t/*** state needed for collecting the input data ***/\r\n\t/* stores the input contours, and eventually the tessellation itself */\r\n\tmesh: TESSmesh = new TESSmesh();\r\n\r\n\t/*** state needed for projecting onto the sweep plane ***/\r\n\tnormal: V3 = [0.0, 0.0, 0.0]; /* user-specified normal (if provided) */\r\n\tsUnit: V3 = [0.0, 0.0, 0.0]; /* unit vector in s-direction (debugging) */\r\n\ttUnit: V3 = [0.0, 0.0, 0.0]; /* unit vector in t-direction (debugging) */\r\n\r\n\tbmin: V2 = [0.0, 0.0];\r\n\tbmax: V2 = [0.0, 0.0];\r\n\r\n\t/*** state needed for the line sweep ***/\r\n\t/* rule for determining polygon interior */\r\n\r\n\twindingRule = WINDING.ODD;\r\n\r\n\tdict: Dict = null; /* edge dictionary for sweep line */\r\n\tpq: PriorityQ = null; /* priority queue of vertex events */\r\n\tevent: any = null; /* current sweep event being processed */\r\n\r\n\tvertexIndexCounter: number = 0;\r\n\r\n\tvertices: Array<number> = [];\r\n\tvertexIndices: Array<number> = [];\r\n\tvertexCount: number = 0;\r\n\telements: Array<number> = [];\r\n\telementCount: number = 0;\r\n\r\n\tdot_(u: V3, v: V3) {\r\n\t\treturn u[0] * v[0] + u[1] * v[1] + u[2] * v[2];\r\n\t}\r\n\r\n\tnormalize_(v: V3) {\r\n\t\tlet len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];\r\n\r\n\t\tif (!len) {\r\n\t\t\tthrow \"Zero-size vector!\";\r\n\t\t}\r\n\r\n\t\tlen = Math.sqrt(len);\r\n\r\n\t\tv[0] /= len;\r\n\t\tv[1] /= len;\r\n\t\tv[2] /= len;\r\n\t}\r\n\r\n\tlongAxis_(v: V3) {\r\n\t\tlet i = 0;\r\n\r\n\t\tif (Math.abs(v[1]) > Math.abs(v[0])) {\r\n\t\t\ti = 1;\r\n\t\t}\r\n\r\n\t\tif (Math.abs(v[2]) > Math.abs(v[i])) {\r\n\t\t\ti = 2;\r\n\t\t}\r\n\r\n\t\treturn i;\r\n\t}\r\n\r\n\tcomputeNormal_(norm: V3) {\r\n\t\tlet v: any, v1: any, v2: any;\r\n\t\tlet c, tLen2, maxLen2;\r\n\t\tlet maxVal: V3 = [0, 0, 0],\r\n\t\t\tminVal: V3 = [0, 0, 0],\r\n\t\t\td1: V3 = [0, 0, 0],\r\n\t\t\td2: V3 = [0, 0, 0],\r\n\t\t\ttNorm: V3 = [0, 0, 0];\r\n\r\n\t\tconst maxVert:Array<any> = [null, null, null],\r\n\t\t\tminVert:Array<any> = [null, null, null];\r\n\t\tconst vHead = this.mesh.vHead;\r\n\r\n\t\tv = vHead.next;\r\n\t\tfor (let i = 0; i < 3; ++i) {\r\n\t\t\tc = v.coords[i];\r\n\t\t\tminVal[i] = c;\r\n\t\t\tminVert[i] = v;\r\n\t\t\tmaxVal[i] = c;\r\n\t\t\tmaxVert[i] = v;\r\n\t\t}\r\n\r\n\t\tfor (v = vHead.next; v !== vHead; v = v.next) {\r\n\t\t\tfor (let i = 0; i < 3; ++i) {\r\n\t\t\t\tc = v.coords[i];\r\n\r\n\t\t\t\tif (c < minVal[i]) {\r\n\t\t\t\t\tminVal[i] = c;\r\n\t\t\t\t\tminVert[i] = v;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (c > maxVal[i]) {\r\n\t\t\t\t\tmaxVal[i] = c;\r\n\t\t\t\t\tmaxVert[i] = v;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* Find two vertices separated by at least 1/sqrt(3) of the maximum\r\n\t\t * distance between any two vertices\r\n\t\t */\r\n\t\tlet i = 0;\r\n\t\tif (maxVal[1] - minVal[1] > maxVal[0] - minVal[0]) {\r\n\t\t\ti = 1;\r\n\t\t}\r\n\r\n\t\tif (maxVal[2] - minVal[2] > maxVal[i] - minVal[i]) {\r\n\t\t\ti = 2;\r\n\t\t}\r\n\r\n\t\tif (minVal[i] >= maxVal[i]) {\r\n\t\t\t/* All vertices are the same -- normal doesn't matter */\r\n\t\t\tnorm[0] = 0;\r\n\t\t\tnorm[1] = 0;\r\n\t\t\tnorm[2] = 1;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t/* Look for a third vertex which forms the triangle with maximum area\r\n\t\t * (Length of normal == twice the triangle area)\r\n\t\t */\r\n\t\tmaxLen2 = 0;\r\n\t\tv1 = minVert[i]!;\r\n\t\tv2 = maxVert[i]!;\r\n\t\td1[0] = v1.coords[0] - v2.coords[0];\r\n\t\td1[1] = v1.coords[1] - v2.coords[1];\r\n\t\td1[2] = v1.coords[2] - v2.coords[2];\r\n\r\n\t\tfor (v = vHead.next; v !== vHead; v = v.next) {\r\n\t\t\td2[0] = v.coords[0] - v2.coords[0];\r\n\t\t\td2[1] = v.coords[1] - v2.coords[1];\r\n\t\t\td2[2] = v.coords[2] - v2.coords[2];\r\n\r\n\t\t\ttNorm[0] = d1[1] * d2[2] - d1[2] * d2[1];\r\n\t\t\ttNorm[1] = d1[2] * d2[0] - d1[0] * d2[2];\r\n\t\t\ttNorm[2] = d1[0] * d2[1] - d1[1] * d2[0];\r\n\t\t\ttLen2 = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2];\r\n\r\n\t\t\tif (tLen2 > maxLen2) {\r\n\t\t\t\tmaxLen2 = tLen2;\r\n\t\t\t\tnorm[0] = tNorm[0];\r\n\t\t\t\tnorm[1] = tNorm[1];\r\n\t\t\t\tnorm[2] = tNorm[2];\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (maxLen2 <= 0) {\r\n\t\t\t/* All points lie on a single line -- any decent normal will do */\r\n\t\t\tnorm[0] = norm[1] = norm[2] = 0;\r\n\t\t\tnorm[this.longAxis_(d1)] = 1;\r\n\t\t}\r\n\t}\r\n\r\n\tcheckOrientation_() {\r\n\t\tvar f,\r\n\t\t\tfHead = this.mesh.fHead;\r\n\t\tvar v,\r\n\t\t\tvHead = this.mesh.vHead;\r\n\t\tvar e;\r\n\r\n\t\t/* When we compute the normal automatically, we choose the orientation\r\n\t\t * so that the the sum of the signed areas of all contours is non-negative.\r\n\t\t */\r\n\t\tlet area = 0;\r\n\r\n\t\tfor (let f = fHead.next!; f !== fHead; f = f.next!) {\r\n\t\t\te = f.anEdge!;\r\n\t\t\tif (e.winding <= 0) continue;\r\n\t\t\tdo {\r\n\t\t\t\tarea += (e!.Org!.s! - e!.Dst!.s!) * (e!.Org!.t + e!.Dst!.t!);\r\n\t\t\t\te = e!.Lnext!;\r\n\t\t\t} while (e !== f.anEdge);\r\n\t\t}\r\n\r\n\t\tif (area < 0) {\r\n\t\t\t/* Reverse the orientation by flipping all the t-coordinates */\r\n\t\t\tfor (v = vHead.next!; v !== vHead; v = v!.next!) {\r\n\t\t\t\tv.t = -v.t;\r\n\t\t\t}\r\n\t\t\tthis.tUnit[0] = -this.tUnit[0];\r\n\t\t\tthis.tUnit[1] = -this.tUnit[1];\r\n\t\t\tthis.tUnit[2] = -this.tUnit[2];\r\n\t\t}\r\n\t}\r\n\r\n\t/*\t#ifdef FOR_TRITE_TEST_PROGRAM\r\n\t\t#include <stdlib.h>\r\n\t\textern int RandomSweep;\r\n\t\t#define S_UNIT_X\t(RandomSweep ? (2*drand48()-1) : 1.0)\r\n\t\t#define S_UNIT_Y\t(RandomSweep ? (2*drand48()-1) : 0.0)\r\n\t\t#else\r\n\t\t#if defined(SLANTED_SWEEP) */\r\n\t/* The \"feature merging\" is not intended to be complete. There are\r\n\t * special cases where edges are nearly parallel to the sweep line\r\n\t * which are not implemented. The algorithm should still behave\r\n\t * robustly (ie. produce a reasonable tesselation) in the presence\r\n\t * of such edges, however it may miss features which could have been\r\n\t * merged. We could minimize this effect by choosing the sweep line\r\n\t * direction to be something unusual (ie. not parallel to one of the\r\n\t * coordinate axes).\r\n\t */\r\n\t/*\t#define S_UNIT_X\t(TESSreal)0.50941539564955385\t// Pre-normalized\r\n\t\t#define S_UNIT_Y\t(TESSreal)0.86052074622010633\r\n\t\t#else\r\n\t\t#define S_UNIT_X\t(TESSreal)1.0\r\n\t\t#define S_UNIT_Y\t(TESSreal)0.0\r\n\t\t#endif\r\n\t\t#endif*/\r\n\r\n\t/* Determine the polygon normal and project vertices onto the plane\r\n\t * of the polygon.\r\n\t */\r\n\tprojectPolygon_() {\r\n\t\tlet v,\r\n\t\t\tvHead = this.mesh.vHead;\r\n\t\tlet norm: V3 = [0, 0, 0];\r\n\t\tlet sUnit, tUnit;\r\n\t\tlet computedNormal = false;\r\n\r\n\t\tnorm[0] = this.normal[0];\r\n\t\tnorm[1] = this.normal[1];\r\n\t\tnorm[2] = this.normal[2];\r\n\r\n\t\tif (!norm[0] && !norm[1] && !norm[2]) {\r\n\t\t\tthis.computeNormal_(norm);\r\n\t\t\tcomputedNormal = true;\r\n\t\t}\r\n\r\n\t\tsUnit = this.sUnit;\r\n\t\ttUnit = this.tUnit;\r\n\r\n\t\tlet axis = this.longAxis_(norm);\r\n\r\n\t\t/*\t#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)\r\n\t\t\t// Choose the initial sUnit vector to be approximately perpendicular\r\n\t\t\t// to the normal.\r\n\t\t\t\r\n\t\t\tNormalize( norm );\r\n\r\n\t\t\tsUnit[i] = 0;\r\n\t\t\tsUnit[(i+1)%3] = S_UNIT_X;\r\n\t\t\tsUnit[(i+2)%3] = S_UNIT_Y;\r\n\r\n\t\t\t// Now make it exactly perpendicular \r\n\t\t\tw = Dot( sUnit, norm );\r\n\t\t\tsUnit[0] -= w * norm[0];\r\n\t\t\tsUnit[1] -= w * norm[1];\r\n\t\t\tsUnit[2] -= w * norm[2];\r\n\t\t\tNormalize( sUnit );\r\n\r\n\t\t\t// Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame \r\n\t\t\ttUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1];\r\n\t\t\ttUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2];\r\n\t\t\ttUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0];\r\n\t\t\tNormalize( tUnit );\r\n\t\t#else*/\r\n\t\t/* Project perpendicular to a coordinate axis -- better numerically */\r\n\t\tsUnit[axis] = 0;\r\n\t\tsUnit[(axis + 1) % 3] = 1.0;\r\n\t\tsUnit[(axis + 2) % 3] = 0.0;\r\n\r\n\t\ttUnit[axis] = 0;\r\n\t\ttUnit[(axis + 1) % 3] = 0.0;\r\n\t\ttUnit[(axis + 2) % 3] = norm[axis] > 0 ? 1.0 : -1.0;\r\n\t\t//\t#endif\r\n\r\n\t\t/* Project the vertices onto the sweep plane */\r\n\t\tfor (let v = vHead.next!; v !== vHead; v = v!.next!) {\r\n\t\t\tv.s = this.dot_(v.coords, sUnit);\r\n\t\t\tv.t = this.dot_(v.coords, tUnit);\r\n\t\t}\r\n\r\n\t\tif (computedNormal) {\r\n\t\t\tthis.checkOrientation_();\r\n\t\t}\r\n\r\n\t\t/* Compute ST bounds. */\r\n\t\tlet first = true;\r\n\r\n\t\tfor (let v = vHead.next; v !== vHead; v = v!.next!) {\r\n\t\t\tif (first) {\r\n\t\t\t\tthis.bmin[0] = this.bmax[0] = v!.s;\r\n\t\t\t\tthis.bmin[1] = this.bmax[1] = v!.t;\r\n\r\n\t\t\t\tfirst = false;\r\n\t\t\t} else {\r\n\t\t\t\tif (v!.s! < this.bmin[0]) this.bmin[0] = v!.s;\r\n\t\t\t\tif (v!.s! > this.bmax[0]) this.bmax[0] = v!.s;\r\n\t\t\t\tif (v!.t! < this.bmin[1]) this.bmin[1] = v!.t;\r\n\t\t\t\tif (v!.t! > this.bmax[1]) this.bmax[1] = v!.t;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\taddWinding_(eDst: any, eSrc: any) {\r\n\t\teDst.winding += eSrc.winding;\r\n\t\teDst.Sym.winding += eSrc.Sym.winding;\r\n\t}\r\n\r\n\t/* tessMeshTessellateMonoRegion( face ) tessellates a monotone region\r\n\t * (what else would it do??) The region must consist of a single\r\n\t * loop of half-edges (see mesh.h) oriented CCW. \"Monotone\" in this\r\n\t * case means that any vertical line intersects the interior of the\r\n\t * region in a single interval.\r\n\t *\r\n\t * Tessellation consists of adding interior edges (actually pairs of\r\n\t * half-edges), to split the region into non-overlapping triangles.\r\n\t *\r\n\t * The basic idea is explained in Preparata and Shamos (which I don''t\r\n\t * have handy right now), although their implementation is more\r\n\t * complicated than this one. The are two edge chains, an upper chain\r\n\t * and a lower chain. We process all vertices from both chains in order,\r\n\t * from right to left.\r\n\t *\r\n\t * The algorithm ensures that the following invariant holds after each\r\n\t * vertex is processed: the untessellated region consists of two\r\n\t * chains, where one chain (say the upper) is a single edge, and\r\n\t * the other chain is concave. The left vertex of the single edge\r\n\t * is always to the left of all vertices in the concave chain.\r\n\t *\r\n\t * Each step consists of adding the rightmost unprocessed vertex to one\r\n\t * of the two chains, and forming a fan of triangles from the rightmost\r\n\t * of two chain endpoints. Determining whether we can add each triangle\r\n\t * to the fan is a simple orientation test. By making the fan as large\r\n\t * as possible, we restore the invariant (check it yourself).\r\n\t */\r\n\t//\tint tessMeshTessellateMonoRegion( TESSmesh *mesh, TESSface *face )\r\n\ttessellateMonoRegion_(mesh: any, face: TESSface) {\r\n\t\tlet up, lo;\r\n\r\n\t\t/* All edges are oriented CCW around the boundary of the region.\r\n\t\t * First, find the half-edge whose origin vertex is rightmost.\r\n\t\t * Since the sweep goes from left to right, face->anEdge should\r\n\t\t * be close to the edge we want.\r\n\t\t */\r\n\t\tup = face.anEdge;\r\n\t\tif (!(up.Lnext !== up && up.Lnext.Lnext !== up)) {\r\n\t\t\tthrow \"Mono region invalid\";\r\n\t\t}\r\n\r\n\t\tfor (; Geom.vertLeq(up.Dst, up.Org); up = up.Lprev);\r\n\t\tfor (; Geom.vertLeq(up.Org, up.Dst); up = up.Lnext);\r\n\r\n\t\tlo = up.Lprev;\r\n\r\n\t\tlet tempHalfEdge: any = undefined;\r\n\r\n\t\twhile (up.Lnext !== lo) {\r\n\t\t\tif (Geom.vertLeq(up.Dst, lo.Org)) {\r\n\t\t\t\t/* up->Dst is on the left. It is safe to form triangles from lo->Org.\r\n\t\t\t\t * The EdgeGoesLeft test guarantees progress even when some triangles\r\n\t\t\t\t * are CW, given that the upper and lower chains are truly monotone.\r\n\t\t\t\t */\r\n\t\t\t\twhile (\r\n\t\t\t\t\tlo.Lnext !== up &&\r\n\t\t\t\t\t(Geom.edgeGoesLeft(lo.Lnext) ||\r\n\t\t\t\t\t\tGeom.edgeSign(lo.Org, lo.Dst, lo.Lnext.Dst) <= 0.0)\r\n\t\t\t\t) {\r\n\t\t\t\t\ttempHalfEdge = mesh.connect(lo.Lnext, lo);\r\n\t\t\t\t\t//if (tempHalfEdge == NULL) return 0;\r\n\t\t\t\t\tlo = tempHalfEdge.Sym;\r\n\t\t\t\t}\r\n\t\t\t\tlo = lo.Lprev;\r\n\t\t\t} else {\r\n\t\t\t\t/* lo->Org is on the left. We can make CCW triangles from up->Dst. */\r\n\t\t\t\twhile (\r\n\t\t\t\t\tlo.Lnext !== up &&\r\n\t\t\t\t\t(Geom.edgeGoesRight(up.Lprev) ||\r\n\t\t\t\t\t\tGeom.edgeSign(up.Dst, up.Org, up.Lprev.Org) >= 0.0)\r\n\t\t\t\t) {\r\n\t\t\t\t\ttempHalfEdge = mesh.connect(up, up.Lprev);\r\n\t\t\t\t\t//if (tempHalfEdge == NULL) return 0;\r\n\t\t\t\t\tup = tempHalfEdge.Sym;\r\n\t\t\t\t}\r\n\t\t\t\tup = up.Lnext;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* Now lo->Org == up->Dst == the leftmost vertex. The remaining region\r\n\t\t * can be tessellated in a fan from this leftmost vertex.\r\n\t\t */\r\n\r\n\t\tif (lo.Lnext === up) {\r\n\t\t\tthrow \"Mono region invalid\";\r\n\t\t}\r\n\r\n\t\twhile (lo.Lnext.Lnext !== up) {\r\n\t\t\ttempHalfEdge = mesh.connect(lo.Lnext, lo);\r\n\t\t\t//if (tempHalfEdge == NULL) return 0;\r\n\t\t\tlo = tempHalfEdge.Sym;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/* tessMeshTessellateInterior( mesh ) tessellates each region of\r\n\t * the mesh which is marked \"inside\" the polygon. Each such region\r\n\t * must be monotone.\r\n\t */\r\n\t//int tessMeshTessellateInterior( TESSmesh *mesh )\r\n\ttessellateInterior_(mesh: TESSmesh) {\r\n\t\tlet next;\r\n\r\n\t\t/*LINTED*/\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = next) {\r\n\t\t\t/* Make sure we don''t try to tessellate the new triangles. */\r\n\t\t\tnext = f!.next!;\r\n\t\t\tif (f!.inside) {\r\n\t\t\t\tif (!this.tessellateMonoRegion_(mesh, f)) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n\t/* tessMeshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces\r\n\t * which are not marked \"inside\" the polygon. Since further mesh operations\r\n\t * on NULL faces are not allowed, the main purpose is to clean up the\r\n\t * mesh so that exterior loops are not represented in the data structure.\r\n\t */\r\n\t//void tessMeshDiscardExterior( TESSmesh *mesh )\r\n\tdiscardExterior_(mesh: TESSmesh) {\r\n\t\tlet next;\r\n\r\n\t\t/*LINTED*/\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = next) {\r\n\t\t\t/* Since f will be destroyed, save its next pointer. */\r\n\t\t\tnext = f!.next;\r\n\r\n\t\t\tif (!f!.inside) {\r\n\t\t\t\tmesh.zapFace(f);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/* tessMeshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the\r\n\t * winding numbers on all edges so that regions marked \"inside\" the\r\n\t * polygon have a winding number of \"value\", and regions outside\r\n\t * have a winding number of 0.\r\n\t *\r\n\t * If keepOnlyBoundary is TRUE, it also deletes all edges which do not\r\n\t * separate an interior region from an exterior one.\r\n\t */\r\n\t//\tint tessMeshSetWindingNumber( TESSmesh *mesh, int value, int keepOnlyBoundary )\r\n\tsetWindingNumber_(mesh: TESSmesh, value: number, keepOnlyBoundary: boolean) {\r\n\t\tlet eNext;\r\n\r\n\t\tfor (let e = mesh.eHead.next; e !== mesh.eHead; e = eNext) {\r\n\t\t\teNext = e!.next;\r\n\t\t\tif (e.Rface.inside !== e.Lface.inside) {\r\n\t\t\t\t/* This is a boundary edge (one side is interior, one is exterior). */\r\n\t\t\t\te.winding = e.Lface.inside ? value : -value;\r\n\t\t\t} else {\r\n\t\t\t\t/* Both regions are interior, or both are exterior. */\r\n\t\t\t\tif (!keepOnlyBoundary) {\r\n\t\t\t\t\te.winding = 0;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tmesh.delete(e);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tgetNeighbourFace_(edge: TESSedge): TESSedge {\r\n\t\tif (!edge.Rface) return -1;\r\n\t\tif (!edge.Rface.inside) return -1;\r\n\t\treturn edge.Rface.n;\r\n\t}\r\n\r\n\toutputPolymesh_(mesh: TESSmesh, elementType: number, polySize: number, vertexSize: number) {\r\n\t\tlet edge;\r\n\t\tlet maxFaceCount = 0;\r\n\t\tlet maxVertexCount = 0;\r\n\t\tlet faceVerts, i;\r\n\r\n\t\t// Assume that the input data is triangles now.\r\n\t\t// Try to merge as many polygons as possible\r\n\t\tif (polySize > 3) {\r\n\t\t\tmesh.mergeConvexFaces(polySize);\r\n\t\t}\r\n\r\n\t\t// Mark unused\r\n\t\tfor (let v = mesh.vHead.next; v !== mesh.vHead; v = v.next) {\r\n\t\t\tv.n = -1;\r\n\t\t}\r\n\r\n\t\t// Create unique IDs for all vertices and faces.\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = f.next) {\r\n\t\t\tf.n = -1;\r\n\r\n\t\t\tif (!f.inside) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tedge = f.anEdge;\r\n\t\t\tfaceVerts = 0;\r\n\r\n\t\t\tdo {\r\n\t\t\t\tlet v = edge.Org;\r\n\t\t\t\tif (v.n === -1) {\r\n\t\t\t\t\tv.n = maxVertexCount;\r\n\t\t\t\t\tmaxVertexCount++;\r\n\t\t\t\t}\r\n\t\t\t\tfaceVerts++;\r\n\t\t\t\tedge = edge.Lnext;\r\n\t\t\t} while (edge !== f.anEdge);\r\n\r\n\t\t\tif ((faceVerts > polySize)) {\r\n\t\t\t\tthrow `Face vertex greater that support polygon`;\r\n\t\t\t}\r\n\r\n\t\t\tf.n = maxFaceCount;\r\n\t\t\t++maxFaceCount;\r\n\t\t}\r\n\r\n\t\tthis.elementCount = maxFaceCount;\r\n\t\tif (elementType === ELEMENT.CONNECTED_POLYGONS) {\r\n\t\t\tmaxFaceCount *= 2;\r\n\t\t}\r\n\t\t/*\t\ttess.elements = (TESSindex*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t sizeof(TESSindex) * maxFaceCount * polySize );\r\n\t\t\tif (!tess->elements)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.elements = [];\r\n\t\tthis.elements.length = maxFaceCount * polySize;\r\n\r\n\t\tthis.vertexCount = maxVertexCount;\r\n\t\t/*\t\ttess->vertices = (TESSreal*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t sizeof(TESSreal) * tess->vertexCount * vertexSize );\r\n\t\t\tif (!tess->vertices)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.vertices = [];\r\n\t\tthis.vertices.length = maxVertexCount * vertexSize;\r\n\r\n\t\t/*\t\ttess->vertexIndices = (TESSindex*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsizeof(TESSindex) * tess->vertexCount );\r\n\t\t\tif (!tess->vertexIndices)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.vertexIndices = [];\r\n\t\tthis.vertexIndices.length = maxVertexCount;\r\n\r\n\t\t// Output vertices.\r\n\t\tfor (let v = mesh.vHead.next; v !== mesh.vHead; v = v.next) {\r\n\t\t\tif (v.n !== -1) {\r\n\t\t\t\t// Store coordinate\r\n\t\t\t\tvar idx = v.n * vertexSize;\r\n\t\t\t\tthis.vertices[idx + 0] = v.coords[0];\r\n\t\t\t\tthis.vertices[idx + 1] = v.coords[1];\r\n\t\t\t\t\r\n\t\t\t\tif (vertexSize > 2) {\r\n\t\t\t\t\tthis.vertices[idx + 2] = v.coords[2];\r\n\t\t\t\t}\r\n\t\t\t\t// Store vertex index.\r\n\t\t\t\tthis.vertexIndices[v.n] = v.idx;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Output indices.\r\n\t\tlet nel = 0;\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = f.next) {\r\n\t\t\tif (!f.inside) continue;\r\n\r\n\t\t\t// Store polygon\r\n\t\t\tedge = f.anEdge;\r\n\t\t\tfaceVerts = 0;\r\n\r\n\t\t\tdo {\r\n\t\t\t\tlet v = edge.Org;\r\n\t\t\t\tthis.elements[nel++] = v.n;\r\n\t\t\t\tfaceVerts++;\r\n\t\t\t\tedge = edge.Lnext;\r\n\t\t\t} while (edge !== f.anEdge);\r\n\t\t\t// Fill unused.\r\n\r\n\t\t\tfor (let i = faceVerts; i < polySize; ++i) {\r\n\t\t\t\tthis.elements[nel++] = -1;\r\n\t\t\t}\r\n\r\n\t\t\t// Store polygon connectivity\r\n\t\t\tif (elementType === ELEMENT.CONNECTED_POLYGONS) {\r\n\t\t\t\tedge = f.anEdge;\r\n\t\t\t\tdo {\r\n\t\t\t\t\tthis.elements[nel++] = this.getNeighbourFace_(edge);\r\n\t\t\t\t\tedge = edge.Lnext;\r\n\t\t\t\t} while (edge !== f.anEdge);\r\n\t\t\t\t// Fill unused.\r\n\t\t\t\tfor (let i = faceVerts; i < polySize; ++i) {\r\n\t\t\t\t\tthis.elements[nel++] = -1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t//\tvoid OutputContours( TESStesselator *tess, TESSmesh *mesh, int vertexSize )\r\n\toutputContours_(mesh: TESSmesh, vertexSize: number) {\r\n\t\tlet edge;\r\n\t\tlet start;\r\n\t\tlet startVert = 0;\r\n\t\tlet vertCount = 0;\r\n\r\n\t\tthis.vertexCount = 0;\r\n\t\tthis.elementCount = 0;\r\n\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = f.next) {\r\n\t\t\tif (!f.inside) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tstart = edge = f.anEdge;\r\n\t\t\tdo {\r\n\t\t\t\tthis.vertexCount++;\r\n\t\t\t\tedge = edge.Lnext;\r\n\t\t\t} while (edge !== start);\r\n\r\n\t\t\tthis.elementCount++;\r\n\t\t}\r\n\r\n\t\t/*\t\ttess->elements = (TESSindex*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t sizeof(TESSindex) * tess->elementCount * 2 );\r\n\t\t\tif (!tess->elements)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.elements = [];\r\n\t\tthis.elements.length = this.elementCount * 2;\r\n\r\n\t\t/*\t\ttess->vertices = (TESSreal*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t sizeof(TESSreal) * tess->vertexCount * vertexSize );\r\n\t\t\tif (!tess->vertices)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.vertices = [];\r\n\t\tthis.vertices.length = this.vertexCount * vertexSize;\r\n\r\n\t\t/*\t\ttess->vertexIndices = (TESSindex*)tess->alloc.memalloc( tess->alloc.userData,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsizeof(TESSindex) * tess->vertexCount );\r\n\t\t\tif (!tess->vertexIndices)\r\n\t\t\t{\r\n\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\treturn;\r\n\t\t\t}*/\r\n\t\tthis.vertexIndices = [];\r\n\t\tthis.vertexIndices.length = this.vertexCount;\r\n\r\n\t\tlet nv = 0;\r\n\t\tlet nvi = 0;\r\n\t\tlet nel = 0;\r\n\r\n\t\tstartVert = 0;\r\n\r\n\t\tfor (let f = mesh.fHead.next; f !== mesh.fHead; f = f.next) {\r\n\t\t\tif (!f.inside) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tvertCount = 0;\r\n\t\t\tstart = edge = f.anEdge;\r\n\r\n\t\t\tdo {\r\n\t\t\t\tthis.vertices[nv++] = edge.Org.coords[0];\r\n\t\t\t\tthis.vertices[nv++] = edge.Org.coords[1];\r\n\t\t\t\t\r\n\t\t\t\tif (vertexSize > 2) {\r\n\t\t\t\t\tthis.vertices[nv++] = edge.Org.coords[2];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.vertexIndices[nvi++] = edge.Org.idx;\r\n\t\t\t\tvertCount++;\r\n\t\t\t\tedge = edge.Lnext;\r\n\t\t\t} while (edge !== start);\r\n\r\n\t\t\tthis.elements[nel++] = startVert;\r\n\t\t\tthis.elements[nel++] = vertCount;\r\n\r\n\t\t\tstartVert += vertCount;\r\n\t\t}\r\n\t}\r\n\r\n\taddContour(size: number, vertices: Array<number>) {\r\n\r\n\t\tif (this.mesh === null) {\r\n\t\t\tthis.mesh = new TESSmesh();\r\n\t\t}\r\n\t\t/*\t \tif ( tess->mesh == NULL ) {\r\n\t\t\ttess->outOfMemory = 1;\r\n\t\t\treturn;\r\n\t\t}*/\r\n\r\n\t\tif (size < 2) {\r\n\t\t\tsize = 2;\r\n\t\t}\r\n\r\n\t\tif (size > 3) {\r\n\t\t\tsize = 3;\r\n\t\t}\r\n\r\n\t\tlet e: TESShalfEdge = null;\r\n\r\n\t\tfor (let i = 0; i < vertices.length; i += size) {\r\n\t\t\tif (e === null) {\r\n\t\t\t\t/* Make a self-loop (one vertex, one edge). */\r\n\t\t\t\te = this.mesh.makeEdge();\r\n\t\t\t\t/*\t\t\t\tif ( e == NULL ) {\r\n\t\t\t\t\t\ttess->outOfMemory = 1;\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}*/\r\n\t\t\t\tthis.mesh.splice(e, e.Sym);\r\n\t\t\t} else {\r\n\t\t\t\t/* Create a new vertex and edge which immediately follow e\r\n\t\t\t\t * in the ordering around the left face.\r\n\t\t\t\t */\r\n\t\t\t\tthis.mesh.splitEdge(e);\r\n\t\t\t\te = e!.Lnext!;\r\n\t\t\t}\r\n\r\n\t\t\t/* The new vertex is now e->Org. */\r\n\t\t\te.Org.coords[0] = vertices[i + 0];\r\n\t\t\te.Org.coords[1] = vertices[i + 1];\r\n\r\n\t\t\tif (size > 2) {\r\n\t\t\t\te.Org.coords[2] = vertices[i + 2];\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\te.Org.coords[2] = 0.0;\r\n\t\t\t}\r\n\r\n\t\t\t/* Store the insertion number so that the vertex can be later recognized. */\r\n\t\t\te.Org.idx = this.vertexIndexCounter++;\r\n\r\n\t\t\t/* The winding of an edge says how the winding number changes as we\r\n\t\t\t * cross from the edge''s right face to its left face. We add the\r\n\t\t\t * vertices in such an order that a CCW contour will add +1 to\r\n\t\t\t * the winding number of the region inside the contour.\r\n\t\t\t */\r\n\t\t\te.winding = 1;\r\n\t\t\te.Sym.winding = -1;\r\n\t\t}\r\n\t}\r\n\r\n\t//\tint tessTesselate( TESStesselator *tess, int windingRule, int elementType, int polySize, int vertexSize, const TESSreal* normal )\r\n\t/**\r\n\t * Run tesselation\r\n\t * @param windingRule \r\n\t * @param elementType \r\n\t * @param polySize \r\n\t * @param vertexSize \r\n\t * @param normal \r\n\t * @param validate UNSAFE! Skip mesh validation pass, may throw any error.\r\n\t */\r\n\ttesselate(\r\n\t\twindingRule: WINDING = WINDING.ODD,\r\n\t\telementType: ELEMENT = ELEMENT.POLYGONS,\r\n\t\tpolySize: number,\r\n\t\tvertexSize: 2 | 3,\r\n\t\tnormal: V3,\r\n\t\tvalidate : boolean = true\r\n\t) {\r\n\t\tthis.vertices = [];\r\n\t\tthis.elements = [];\r\n\t\tthis.vertexIndices = [];\r\n\r\n\t\tthis.vertexIndexCounter = 0;\r\n\r\n\t\tif (normal) {\r\n\t\t\tthis.normal[0] = normal[0];\r\n\t\t\tthis.normal[1] = normal[1];\r\n\t\t\tthis.normal[2] = normal[2];\r\n\t\t}\r\n\r\n\t\tthis.windingRule = windingRule;\r\n\r\n\t\tif (vertexSize < 2) {\r\n\t\t\tvertexSize = 2;\r\n\t\t}\r\n\r\n\t\tif (vertexSize > 3) {\r\n\t\t\tvertexSize = 3;\r\n\t\t}\r\n\r\n\t\t/*\t\tif (setjmp(tess->env) != 0) { \r\n\t\t\t\t// come back here if out of memory\r\n\t\t\t\treturn 0;\r\n\t\t\t}*/\r\n\r\n\t\tif (!this.mesh) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\t/* Determine the polygon normal and project vertices onto the plane\r\n\t\t * of the polygon.\r\n\t\t */\r\n\t\tthis.projectPolygon_();\r\n\r\n\t\t/* tessComputeInterior( tess ) computes the planar arrangement specified\r\n\t\t * by the given contours, and further subdivides this arrangement\r\n\t\t * into regions. Each region is marked \"inside\" if it belongs\r\n\t\t * to the polygon, according to the rule given by tess->windingRule.\r\n\t\t * Each interior region is guaranteed be monotone.\r\n\t\t */\r\n\t\tSweep.computeInterior(this, validate);\r\n\r\n\t\tvar mesh = this.mesh;\r\n\r\n\t\t/* If the user wants only the boundary contours, we throw away all edges\r\n\t\t * except those which separate the interior from the exterior.\r\n\t\t * Otherwise we tessellate all the regions marked \"inside\".\r\n\t\t */\r\n\t\tif (elementType === ELEMENT.BOUNDARY_CONTOURS) {\r\n\t\t\tthis.setWindingNumber_(mesh, 1, true);\r\n\t\t} else {\r\n\t\t\tthis.tessellateInterior_(mesh);\r\n\t\t}\r\n\t\t//\t\tif (rc == 0) longjmp(tess->env,1); /* could've used a label */\r\n\r\n\t\tif(validate){\r\n\t\t\t mesh.check();\r\n\t\t}\r\n\r\n\t\tif (elementType === ELEMENT.BOUNDARY_CONTOURS) {\r\n\t\t\tthis.outputContours_(mesh, vertexSize); /* output contours */\r\n\t\t} else {\r\n\t\t\tthis.outputPolymesh_(\r\n\t\t\t\tmesh,\r\n\t\t\t\telementType,\r\n\t\t\t\tpolySize,\r\n\t\t\t\tvertexSize,\r\n\t\t\t); /* output polygons */\r\n\t\t}\r\n\r\n\t\t//\t\t\ttess.mesh = null;\r\n\r\n\t\treturn true;\r\n\t}\r\n};", "/*\r\n ** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)\r\n ** Copyright (C) [dates of first publication] Silicon Graphics, Inc.\r\n ** All Rights Reserved.\r\n **\r\n ** Permission is hereby granted, free of charge, to any person obtaining a copy\r\n ** of this software and associated documentation files (the \"Software\"), to deal\r\n ** in the Software without restriction, including without limitation the rights\r\n ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r\n ** of the Software, and to permit persons to whom the Software is furnished to do so,\r\n ** subject to the following conditions:\r\n **\r\n ** The above copyright notice including the dates of first publication and either this\r\n ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be\r\n ** included in all copies or substantial portions of the Software.\r\n **\r\n ** THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\r\n ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r\n ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.\r\n ** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r\n ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\r\n ** OR OTHER DEALINGS IN THE SOFTWARE.\r\n **\r\n ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not\r\n ** be used in advertising or otherwise to promote the sale, use or other dealings in\r\n ** this Software without prior written authorization from Silicon Graphics, Inc.\r\n */\r\n/*\r\n ** Author: Mikko Mononen, Aug 2013.\r\n ** TS-version: Timoshenko Konstantin, Mart 2020.\r\n ** The code is based on GLU libtess by Eric Veach, July 1994\r\n */\r\n\r\nimport { Tesselator } from \"./Tesselator\";\r\nimport { WINDING, ELEMENT } from \"./utils/constants\";\r\n\r\nexport type V3 = [number, number, number | 0];\r\nexport type V2 = [number, number];\r\n\r\nexport interface IOptions {\r\n\twindingRule?: number;\r\n\telementType?: number;\r\n\tpolySize?: number;\r\n\tvertexSize?: 2 | 3;\r\n\tnormal?: V3;\r\n\tcontours: Array<Array<number>>;\r\n\tstrict?: boolean;\r\n\tdebug?: boolean;\r\n}\r\n\r\nexport interface IResult {\r\n\tvertices: Array<number>;\r\n\tvertexIndices: Array<number>;\r\n\tvertexCount: number;\r\n\telements: Array<number>;\r\n\telementCount: number;\r\n\tmesh: any;\r\n}\r\n\r\nexport { Tesselator, WINDING, ELEMENT };\r\n\r\nexport function tesselate({\r\n\twindingRule = WINDING.ODD,\r\n\telementType = ELEMENT.POLYGONS,\r\n\tpolySize = 3,\r\n\tvertexSize = 2,\r\n\tnormal = [0, 0, 1],\r\n\tcontours = [],\r\n\tstrict = true,\r\n\tdebug = false,\r\n}: IOptions): IResult | undefined {\r\n\tif (!contours && strict) {\r\n\t\tthrow new Error(\"Contours can't be empty\");\r\n\t}\r\n\r\n\tif (!contours) {\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tconst tess = new Tesselator();\r\n\r\n\tfor (let i = 0; i < contours.length; i++) {\r\n\t\ttess.addContour(vertexSize || 2, contours[i]);\r\n\t}\r\n\r\n\ttess.tesselate(\r\n\t\twindingRule,\r\n\t\telementType,\r\n\t\tpolySize,\r\n\t\tvertexSize,\r\n\t\tnormal,\r\n\t\tstrict,\r\n\t);\r\n\r\n\treturn {\r\n\t\tvertices: tess.vertices,\r\n\t\tvertexIndices: tess.vertexIndices,\r\n\t\tvertexCount: tess.vertexCount,\r\n\t\telements: tess.elements,\r\n\t\telementCount: tess.elementCount,\r\n\t\tmesh: debug ? tess.mesh : undefined,\r\n\t};\r\n}\r\n\r\n// legacy, compatibility exports\r\n\r\n\r\nexport const WINDING_ODD = WINDING.ODD;\r\nexport const WINDING_NONZERO = WINDING.NONZERO;\r\nexport const WINDING_POSITIVE = WINDING.POSITIVE;\r\nexport const WINDING_NEGATIVE = WINDING.NEGATIVE;\r\nexport const WINDING_ABS_GEQ_TWO = WINDING.ABS_GEQ_TWO;\r\n\r\nexport const POLYGONS = ELEMENT.POLYGONS;\r\nexport const CONNECTED_POLYGONS = ELEMENT.CONNECTED_POLYGONS;\r\nexport const BOUNDARY_CONTOURS = ELEMENT.BOUNDARY_CONTOURS;", "import { BufferAttribute, BufferGeometry } from 'three';\nimport { tesselate, WINDING, ELEMENT, IResult } from 'tess2-ts';\nimport { TESSvertex } from 'tess2-ts/types/mesh/TESSvertex';\nimport { TESShalfEdge } from 'tess2-ts/types/mesh/TESShalfEdge';\nimport { VectorShape } from '../../objects/entities/vectors/VectorShape';\nimport { DynamicBuffer } from './DynamicBuffer';\nimport { cloneDeep } from 'lodash-es';\n\n/**\n * A [min, max] ordered, cyclical range\n */\ntype Range = [number, number];\n\n/**\n * Global information for input vertices\n */\ntype VertexInfo = {\n\t/**\n\t * (normals[i2],normals[i2+1]) is the normal of the line segment starting at (bnd.vertices[i2], bnd.vertices[i2+1])\n\t */\n\tnormals: number[];\n\tcontinuous: boolean[];\n\tconcave: boolean[];\n\n\tstart: number;\n\tcount: number;\n};\n\n/**\n * One closed loop around a region\n */\ntype BevelLoop = {\n\tbevelI: number;\n\tangle: number;\n\tsize: number;\n\tboundary: IResult<Range>;\n\tinsetPoints: number[];\n\treverseMap: number[];\n};\n\n/**\n * BevelSegment's for one region\n */\n// DEBUG:\n// type Region = { bevels: BevelLoop[] } & VertexInfo;\n\n/**\n * Indices for one logical \"vertex\" of a bevel ring.\n * May contain two different sets of normals (Previous/Next).\n * Contains vertex positions for the top/bottom of the shape.\n */\ntype BevelVertResult = {\n\t/**\n\t * Top vertex with normals following the incoming line segment at this vert.\n\t * If the vertex is continuous, this is equal to {@link topN}.\n\t */\n\ttopP: number;\n\t/**\n\t * Top vertex with normals following the outgoing line segment at this vert.\n\t * If the vertex is continuous, this is equal to {@link topP}.\n\t */\n\ttopN: number;\n\t/**\n\t * Bottom vertex with normals following the incoming line segment at this vert.\n\t * If the vertex is continuous, this is equal to {@link bottomN}.\n\t */\n\tbottomP: number;\n\t/**\n\t * Bottom vertex with normals following the outgoing line segment at this vert.\n\t * If the vertex is continuous, this is equal to {@link bottomP}.\n\t */\n\tbottomN: number;\n};\n\n/**\n * Indices for one logical \"vertex\" of a surface patch.\n * Contains vertex positions for the top/bottom of the shape.\n */\ntype SurfaceVertResult = {\n\ttop: number;\n\tbottom: number;\n};\n\n/**\n * Create a predicate function checking whether an ordered, cyclic `[min, max]`\n * range contains a number.\n *\n * @param i - the number to check for\n * @param count - size of the loop\n * @param min - start of the range (inclusive)\n * @param max - end of the range (inclusive)\n * @returns predicate function `([min, max]) => boolean`\n *\n * @example\n * ```\n * const containsVertex2 = cycContainsPredicate(2, 10); // check whether '2' is contained\n * containsVertex2([1, 3]); // => true\n * containsVertex2([2, 2]); // => true\n * containsVertex2([5, 6]); // => false\n * containsVertex2([0, 1]); // => false\n * containsVertex2([9, 4]); // => true\n * ```\n */\nconst cycContainsPredicate =\n\t(i: number, count: number) =>\n\t([min, max]: Range): boolean => {\n\t\tif (max < min) {\n\t\t\tmax += count;\n\t\t}\n\n\t\treturn (i >= min ? i : i + count) <= max;\n\t};\n\n/**\n * An extruded Vector shape as a three BufferGeometry, with optional bevelled edges\n * in the extrusion plane.\n *\n * @privateRemarks\n *\n * ## Algorithm\n *\n * Here follows a high-level overview over the algorithm.\n * The vector extrusion geometry consists of three separate sections:\n *\n * - the top and bottom surfaces (in the XY plane)\n * - the top and bottom bevel loops (if `bevel > 0`)\n * - the wall-loop (Z-parallel)\n *\n * First the vector shape is discretized using `extractPointsToFlatArray()`. The\n * result is passed through {@link tesselate} with {@link WINDING.ODD} and\n * {@link ELEMENT.BOUNDARY_CONTOURS} to obtain a set of closed, non-self-intersecting\n * boundary-loops that can be independently extruded and beveled (`originalRegions`).\n *\n * While such regions can share vertex positions, they always have different normals\n * for such vertices so there is no downside to handling the boundaries individually.\n * All further processing therefore happens on a per-region basis in a big loop.\n *\n * For each vertex/line segment in each region, three attributes are calculated and stored in `info`:\n * - `normals`: the XY-planar normals for each segment is calculated based on the vertex positions. The normals\n * always point outwards.\n * - `concave`: the angles between adjacent segments are measured to detect concave corners\n * - `continuous`: the intended normal blending is detected for each vertex based on curve data\n * where available ({@link VectorShape.getCurveIndexFromVertexId}). Vertices in the middle of a\n * curve segment are always continuous.\n *\n * Next, a series of incrementally inset {@link BevelLoop}s is generated. There are `bevelSegments + 1`\n * bevel loops. The first bevel loop is always the \"raw\" contour without any insetting applied.\n *\n * For each following bevel segment, a loop inset by an increasing amount (`1 - cos(angle)`) is generated.\n * The algorithm used is taken {@link https://mcmains.me.berkeley.edu/pubs/DAC05OffsetPolygon.pdf | from this research paper}.\n * This is done by replacing each vertex in the original loop with a set of new vertices using the following rules:\n *\n * - if the vertex represents a convex corner:\n * \t - insert a vertex inset by the inset amount along the normal of the segment arriving at the vertex\n * - insert a vertex at the original, non-inset vertex position\n * \t - insert a vertex inset by the inset amount along the normal of the segment departing from the vertex\n * - this creats a kind of \"ear\" shape for each vertex, `\u25AB \u2192 \u2318`\n * - otherwise the vertex represents a concave corner:\n * \t - insert a vertex inset by the inset amount along the normal of the segment arriving at the vertex\n * \t - insert a vertex inset by the inset amount along the normal of the segment departing from the vertex\n * - insert a number of vertices evenly-spaced along the circular arc-segment with center on the original\n * vertex and between the other vertices\n *\n * The result is a heavily self-intersecting shape, the \"most inside\" non-overlapping region of which is a clean,\n * inset loop. This loop is obtained by passing it through {@link tesselate} with {@link WINDING.POSITIVE} and\n * {@link ELEMENT.BOUNDARY_CONTOURS}. In order to generate a correct topology later, the vertices have to be\n * traced through the tesselation process. This is done by labelling all edges in the tesselator, and using\n * this information to assign labels to all newly created vertices. The result is a many-to-many mapping between\n * original vertex indices and output vertices. The mapping represented using an \"ordered cyclic range\" of\n * corresponding input vertex indices that is stored for each output vertex in `boundary.fixedIndices`.\n * The mapping is not unique in either direction, i.e. for any input vertex multiple output vertices can exist\n * (concave corner fans), and for any output vertex multiple input vertices may exist (merged vertices).\n *\n * - in the simple case, the output vertex corresponds to a single input vertex `i`. This is stored as `[i, i]`.\n * - when multiple vertices have been merged, the range includes all corresponding input vertices, e.g.\n * when the vertices 2, 3, and 4 have been merged, this is represented as `[2, 4]`. The range can wrap around\n * the boundary loop, e.g. if the vertices 4, 5, and 0 might be adjacent in a hexagon and the vertex produced\n * by merging them would be represented as `[4, 0]`.\n *\n * Once all {@link BevelLoop}s have been generated, the mesh can be assembled.\n *\n * For each successive pair of {@link BevelLoop}s, a bevel segment is created. This is the most complex\n * of the mesh generation steps. This is because in order to generate a clean topology for each bevel segment,\n * the corresponding vertices along each loop have to be matched together.\n *\n * The first {@link BevelLoop} is used to construct the outer wall. Each successive pair of vertices is mirrored\n * on the XZ plane and used to generate a simple quad.\n *\n * The last {@link BevelLoop} is used to generate the top/bottom surface. It's vertices are passed through\n * {@link tesselate} with {@link ELEMENT.POLYGONS} to obtain a triangle tesselation that is duplicated for\n * the top/bottom surfaces.\n *\n * ## Debugging\n *\n * There are a couple of comment blocks of the following form:\n *\n * // DEBUG:\n * // code;\n * // some.more(code);\n *\n * These can be uncommented to keep a reference to all the intermediate data generated throghout the algorithm\n * in the global variable `window.l`. Trigger a rebuild of the shape (e.g. change bevel size) and enter `l` in\n * the Console to print out the JSON string. The string can then be pasted in the debug viewer sandbox,\n * replacing the present data block. The sandbox can be found in the `__sandbox__` directory next to this file.\n * See the README file there for information on starting and using the debug view.\n */\nexport class VectorExtrusionGeometry extends BufferGeometry {\n\ttype: string = 'ShapeGeometry';\n\n\tprivate _shape: VectorShape;\n\tprivate _depth: number;\n\n\tprivate _buffer: DynamicBuffer;\n\tprivate _minX: number;\n\tprivate _minY: number;\n\tprivate _width: number;\n\tprivate _height: number;\n\tprivate _bevelSegments: number;\n\tprivate _bevelSize: number;\n\tprivate _bevel: number;\n\tprivate _curveSegments: number;\n\tprivate _bevelSegmentsInput: number;\n\n\tconstructor(\n\t\tshape: VectorShape,\n\t\tdepth: number,\n\t\tbevel: number = 0,\n\t\tcurveSegments: number = 12,\n\t\tbevelSegments: number = 3\n\t) {\n\t\tsuper();\n\n\t\tthis._shape = shape;\n\t\tthis._depth = depth;\n\t\tthis._bevel = bevel;\n\t\tthis._curveSegments = curveSegments;\n\t\tthis._bevelSegmentsInput = bevelSegments;\n\n\t\tif (bevel <= 0) {\n\t\t\tthis._bevelSize = 0;\n\t\t\tthis._bevelSegments = 0;\n\t\t} else {\n\t\t\tthis._bevelSize = Math.min(bevel, depth / 2 - 1e-12);\n\t\t\tthis._bevelSegments = Math.floor(bevelSegments);\n\t\t}\n\n\t\tconst points = this._shape.extractShapePointsToFlatArray([], curveSegments);\n\t\tconst holes = this._shape.shapeHoles.map((hole) => {\n\t\t\t// We can't simply reverse the list because it is an array of pair-wise (XY) points!\n\t\t\t// This code basically reverses the list of points - x0, y0, x1, y1, ..., xn, yn becomes\n\t\t\t// xn, yn, x(n-1), y(n-1), ..., x1, y1, x0, y0.\n\t\t\tlet originalOrdering = hole.extractShapePointsToFlatArray(\n\t\t\t\t[],\n\t\t\t\tcurveSegments\n\t\t\t);\n\t\t\tlet reversed = [];\n\t\t\tfor (let i = originalOrdering.length - 1; i >= 1; i -= 2) {\n\t\t\t\tconst x = originalOrdering[i - 1];\n\t\t\t\tconst y = originalOrdering[i - 0];\n\t\t\t\treversed.push(x, y);\n\t\t\t}\n\t\t\treturn reversed;\n\t\t});\n\n\t\t/**\n\t\t * calculate original boundaries\n\t\t */\n\t\tlet originalRegions = tesselate({\n\t\t\twindingRule: WINDING.ODD,\n\t\t\telementType: ELEMENT.BOUNDARY_CONTOURS,\n\t\t\tvertexSize: 2,\n\t\t\tstrict: true,\n\t\t\tcontours: [points], // Only points! Holes processed in a separate call below...\n\t\t});\n\n\t\t// Process holes separately\n\t\tconst originalRegionsHoles = tesselate({\n\t\t\twindingRule: WINDING.ODD,\n\t\t\telementType: ELEMENT.BOUNDARY_CONTOURS,\n\t\t\tvertexSize: 2,\n\t\t\tstrict: true,\n\t\t\tcontours: [...holes],\n\t\t});\n\n\t\tif (!originalRegions) throw new Error('error generating geometry');\n\n\t\tlet numNonHoles = originalRegions.elementCount;\n\n\t\t// Above, we processed \"regular\" contours and holes separately - each call to `tesselate()` returns a new set\n\t\t// of \"contour region\" geometries. Here, we combine the two results into a single object\n\t\tif (originalRegionsHoles) {\n\t\t\toriginalRegions.elementCount += originalRegionsHoles.elementCount;\n\n\t\t\t// Append elements\n\t\t\tfor (let i = 0; i < originalRegionsHoles.elements.length; i++) {\n\t\t\t\tconst original = originalRegionsHoles.elements[i];\n\t\t\t\tconst offset = i % 2 === 0 ? originalRegions.vertexCount : 0; // Only offset \"start\" not \"count\" entries (count stays the same)\n\t\t\t\toriginalRegions.elements.push(original + offset);\n\t\t\t}\n\n\t\t\t// Push back vertex indices - offset by vertex count in \"non-hole\" region\n\t\t\tfor (let i = 0; i < originalRegionsHoles.vertexIndices.length; i++) {\n\t\t\t\tconst original = originalRegionsHoles.vertexIndices[i];\n\t\t\t\tconst offset = originalRegions.vertexCount;\n\t\t\t\toriginalRegions.vertexIndices.push(original + offset);\n\t\t\t}\n\n\t\t\t// No offsets here: just push back vertex coords\n\t\t\tfor (let i = 0; i < originalRegionsHoles.vertices.length; i++) {\n\t\t\t\tconst original = originalRegionsHoles.vertices[i];\n\t\t\t\toriginalRegions.vertices.push(original);\n\t\t\t}\n\t\t}\n\n\t\t// Compute 2d bounding box for uvs\n\t\tlet minX = Infinity;\n\t\tlet maxX = -Infinity;\n\t\tlet minY = Infinity;\n\t\tlet maxY = -Infinity;\n\t\tfor (let i = 0, l = originalRegions.vertexCount; i < l; i++) {\n\t\t\tconst i2 = i * 2;\n\t\t\tconst x = originalRegions.vertices[i2 + 0];\n\t\t\tconst y = originalRegions.vertices[i2 + 1];\n\t\t\tif (x < minX) minX = x;\n\t\t\tif (x > maxX) maxX = x;\n\t\t\tif (y < minY) minY = y;\n\t\t\tif (y > maxY) maxY = y;\n\t\t}\n\t\tthis._minX = minX;\n\t\tthis._minY = minY;\n\t\tthis._width = maxX - minX;\n\t\tthis._height = maxY - minY;\n\n\t\t// DEBUG:\n\t\t// const regions: Region[] = [];\n\n\t\tconst estimatedSize =\n\t\t\toriginalRegions.vertexCount * 2 * (2 + this._bevelSegments);\n\t\tthis._buffer = new DynamicBuffer(estimatedSize);\n\t\tlet indices: number[] = [];\n\n\t\t// The modified strategy to accomodate bevels with holes is as follows:\n\t\t// 1. Process contours corresponding to holes first\n\t\t// 2. For each such contour, \"remember\" / store the \"outermost\" bevel loop (note that we use \"outer\" not \"inner\", as\n\t\t// hole contours are actually *outset* not *inset*!)\n\t\t// 3. Process contours for \"regular\" contours\n\t\t// 4. For each such contour, the surface / \"cap\" face geometry is generated by tesselating the innermost bevel loop\n\t\t// alongside all of the loops generated in step (2)\n\t\tlet holeInnermostBevels = [];\n\n\t\t// for each closed, non-self-intersecting region...(starting with holes)\n\t\tfor (\n\t\t\tlet regionI = originalRegions.elementCount - 1;\n\t\t\tregionI >= 0;\n\t\t\tregionI--\n\t\t) {\n\t\t\t// Does this region come from a hole? If so, we will *outset* the region rather than *inset*\n\t\t\tconst isFromHole = regionI >= numNonHoles;\n\n\t\t\tconst i2 = regionI * 2;\n\t\t\tconst start = originalRegions.elements[i2 + 0];\n\t\t\tconst count = originalRegions.elements[i2 + 1];\n\t\t\tconst end = start + count;\n\n\t\t\tconst info: VertexInfo = {\n\t\t\t\tstart,\n\t\t\t\tcount,\n\t\t\t\tnormals: [],\n\t\t\t\tcontinuous: [],\n\t\t\t\tconcave: [],\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * Calculate VertexInfo\n\t\t\t */\n\t\t\tlet vi = start;\n\t\t\tlet viP = end - 1;\n\t\t\tlet viN = start + 1;\n\t\t\tconst numCurves = this._shape.roundedCurves.length;\n\t\t\tdo {\n\t\t\t\tconst bi = vi - start;\n\n\t\t\t\tconst xP = originalRegions.vertices[viP * 2 + 0];\n\t\t\t\tconst yP = originalRegions.vertices[viP * 2 + 1];\n\t\t\t\tconst x = originalRegions.vertices[vi * 2 + 0];\n\t\t\t\tconst y = originalRegions.vertices[vi * 2 + 1];\n\t\t\t\tconst xN = originalRegions.vertices[viN * 2 + 0];\n\t\t\t\tconst yN = originalRegions.vertices[viN * 2 + 1];\n\n\t\t\t\t// calculate normals\n\t\t\t\tlet dxP = x - xP;\n\t\t\t\tlet dyP = y - yP;\n\t\t\t\tconst dlenP = Math.sqrt(dxP * dxP + dyP * dyP);\n\t\t\t\tdxP /= dlenP;\n\t\t\t\tdyP /= dlenP;\n\n\t\t\t\tlet dxN = x - xN;\n\t\t\t\tlet dyN = y - yN;\n\t\t\t\tconst dlenN = Math.sqrt(dxN * dxN + dyN * dyN);\n\t\t\t\tdxN /= dlenN;\n\t\t\t\tdyN /= dlenN;\n\n\t\t\t\tinfo.normals[bi * 2 + 0] = -dyN;\n\t\t\t\tinfo.normals[bi * 2 + 1] = dxN;\n\n\t\t\t\t// check if concave\n\t\t\t\tinfo.concave[bi] = dxP * dyN - dyP * dxN > 0;\n\n\t\t\t\t// check if continuous\n\t\t\t\tconst shapeIndex = originalRegions.vertexIndices[vi];\n\t\t\t\tif (Array.isArray(shapeIndex)) {\n\t\t\t\t\t// this vertex is a self-intersection corner that was inserted by\n\t\t\t\t\t// tess2.js. approximate tangent using neighbour verts.\n\t\t\t\t\tinfo.continuous[bi] = false;\n\t\t\t\t} else {\n\t\t\t\t\t// this vertex was generated by shape.extractPointsToFlatArray()\n\t\t\t\t\tconst [c, t] = this._shape.getCurveIndexFromVertexId(\n\t\t\t\t\t\tshapeIndex - 1,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t);\n\t\t\t\t\tif (t > 0 && t < 1) {\n\t\t\t\t\t\t// middle of a curve is always continuous\n\t\t\t\t\t\tinfo.continuous[bi] = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlet otherC = t === 1 ? c + 1 : c - 1;\n\t\t\t\t\t\totherC = (otherC + numCurves) % numCurves;\n\t\t\t\t\t\tconst otherT = t === 1 ? 0 : 1;\n\n\t\t\t\t\t\tconst tangent = this._shape.roundedCurves[c].getTangent(t);\n\t\t\t\t\t\tconst otherTangent =\n\t\t\t\t\t\t\tthis._shape.roundedCurves[otherC].getTangent(otherT);\n\t\t\t\t\t\t// small discontinuities can be ignored\n\t\t\t\t\t\tinfo.continuous[bi] = tangent.dot(otherTangent) > 0.95;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isFromHole) {\n\t\t\t\t\tinfo.normals[bi * 2 + 0] *= -1;\n\t\t\t\t\tinfo.normals[bi * 2 + 1] *= -1;\n\t\t\t\t}\n\n\t\t\t\t[viP, vi, viN] = [vi, viN, viN + 1];\n\t\t\t\tif (viN >= end) viN -= count;\n\t\t\t} while (viN !== start + 1);\n\n\t\t\t/**\n\t\t\t * calculate insets for each bevel segment\n\t\t\t */\n\t\t\tconst bevels: BevelLoop[] = [];\n\n\t\t\tbevels.push({\n\t\t\t\tbevelI: 0,\n\t\t\t\tangle: 0,\n\t\t\t\tsize: 0,\n\t\t\t\tboundary: {\n\t\t\t\t\tvertices: originalRegions.vertices.slice(start * 2, end * 2),\n\t\t\t\t\tvertexCount: count,\n\t\t\t\t\tvertexIndices: new Array(count).fill(true).map((_, i) => [i, i]),\n\t\t\t\t\telements: [0, count],\n\t\t\t\t\telementCount: 1,\n\t\t\t\t\tmesh: null,\n\t\t\t\t},\n\t\t\t\treverseMap: [],\n\t\t\t\tinsetPoints: originalRegions.vertices.slice(start * 2, end * 2),\n\t\t\t});\n\n\t\t\tfor (let bevelI = 1; bevelI <= this._bevelSegments; bevelI++) {\n\t\t\t\tconst angle = ((bevelI / this._bevelSegments) * Math.PI) / 2;\n\t\t\t\tconst size = (1.0 - Math.cos(angle)) * this._bevelSize;\n\n\t\t\t\tlet insetPoints: number[] = [];\n\t\t\t\tlet prePoints: number[] = [];\n\t\t\t\tlet postPoints: number[] = [];\n\t\t\t\tlet reverseMap: number[] = [];\n\t\t\t\tlet pointCount = 0;\n\n\t\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\t\tconst i2 = i * 2;\n\t\t\t\t\tconst i2P = ((i - 1 + count) % count) * 2;\n\n\t\t\t\t\tconst x = originalRegions.vertices[info.start * 2 + i2 + 0];\n\t\t\t\t\tconst y = originalRegions.vertices[info.start * 2 + i2 + 1];\n\n\t\t\t\t\tlet dxP = -info.normals[i2P + 0] * size;\n\t\t\t\t\tlet dyP = -info.normals[i2P + 1] * size;\n\t\t\t\t\tlet dxN = -info.normals[i2 + 0] * size;\n\t\t\t\t\tlet dyN = -info.normals[i2 + 1] * size;\n\n\t\t\t\t\t// For outsetting, move in opposite direction from insetting\n\t\t\t\t\t// if (isFromHole) {\n\t\t\t\t\t// \tdxN *= -1;\n\t\t\t\t\t// \tdyN *= -1;\n\t\t\t\t\t// \tdxP *= -1;\n\t\t\t\t\t// \tdyP *= -1;\n\t\t\t\t\t// }\n\n\t\t\t\t\t// Added second condition here after OR - per the paper, when outsetting,\n\t\t\t\t\t// CONVEX vertices get mapped to a fan (opposite of when insetting)\n\t\t\t\t\tif (info.concave[i] || (!info.concave[i] && isFromHole)) {\n\t\t\t\t\t\t//console.log('Concave vertex, region:', regionI);\n\t\t\t\t\t\tconst startAngle = Math.atan2(dyP, dxP);\n\t\t\t\t\t\tlet endAngle = Math.atan2(dyN, dxN);\n\t\t\t\t\t\tif (endAngle > startAngle) endAngle -= Math.PI * 2;\n\t\t\t\t\t\tconst deltaAngle = endAngle - startAngle;\n\n\t\t\t\t\t\t// Always move points from holes directly outwards\n\t\t\t\t\t\tif (info.continuous[i] || isFromHole) {\n\t\t\t\t\t\t\tconst angle = startAngle + deltaAngle / 2;\n\t\t\t\t\t\t\tconst dx = Math.cos(angle) * size;\n\t\t\t\t\t\t\tconst dy = Math.sin(angle) * size;\n\n\t\t\t\t\t\t\tinsetPoints[2 * pointCount + 0] = x + dx * (isFromHole ? -1 : 1);\n\t\t\t\t\t\t\tinsetPoints[2 * pointCount + 1] = y + dy * (isFromHole ? -1 : 1);\n\t\t\t\t\t\t\treverseMap[pointCount] = i;\n\t\t\t\t\t\t\tpointCount++;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst segments = Math.max(\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\tMath.floor(\n\t\t\t\t\t\t\t\t\t((curveSegments / 4) * Math.abs(deltaAngle)) / Math.PI\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tfor (let iA = 0; iA <= segments; iA++) {\n\t\t\t\t\t\t\t\tconst angle = startAngle + deltaAngle * (iA / segments);\n\t\t\t\t\t\t\t\tconst dx = Math.cos(angle) * size;\n\t\t\t\t\t\t\t\tconst dy = Math.sin(angle) * size;\n\n\t\t\t\t\t\t\t\tinsetPoints[2 * pointCount + 0] = x + dx;\n\t\t\t\t\t\t\t\tinsetPoints[2 * pointCount + 1] = y + dy;\n\t\t\t\t\t\t\t\treverseMap[pointCount] = i;\n\t\t\t\t\t\t\t\tpointCount++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// 1. inset by the segment ending here\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 0] = x + dxP;\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 1] = y + dyP;\n\t\t\t\t\t\treverseMap[pointCount] = i;\n\t\t\t\t\t\tprePoints[i] = pointCount;\n\t\t\t\t\t\tpointCount++;\n\n\t\t\t\t\t\t// 2. the original point\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 0] = x;\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 1] = y;\n\t\t\t\t\t\treverseMap[pointCount] = i;\n\t\t\t\t\t\tpointCount++;\n\n\t\t\t\t\t\t// 3. inset by the segment starting here\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 0] = x + dxN;\n\t\t\t\t\t\tinsetPoints[2 * pointCount + 1] = y + dyN;\n\t\t\t\t\t\treverseMap[pointCount] = i;\n\t\t\t\t\t\tpostPoints[i] = pointCount;\n\t\t\t\t\t\tpointCount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * tesselate with WINDING.NEGATIVE to get the innermost boundary cell\n\t\t\t\t * both edges and vertices are labelled in the process.\n\t\t\t\t * - edges are labelled with `[from, to]` tuples, where `from` and `to` are two vertex-indices\n\t\t\t\t * in the range `0 .. count`, denoting the start and end vertex of the edge respectively.\n\t\t\t\t * - vertices are labelled with `[min, max]` tuples, where `min` and `max` are two vertex-indices\n\t\t\t\t * in the range `0 .. count`. `min` and `max` describe an ordered range of vertices that were\n\t\t\t\t * \"consumed\" to create a specific output vertex. For input vertices, the range is `[i, i]`.\n\t\t\t\t */\n\t\t\t\tconst boundary = tesselate<Range>({\n\t\t\t\t\twindingRule: WINDING.POSITIVE,\n\t\t\t\t\telementType: ELEMENT.BOUNDARY_CONTOURS,\n\t\t\t\t\tvertexSize: 2,\n\t\t\t\t\tstrict: true,\n\t\t\t\t\tcontours: [insetPoints],\n\t\t\t\t\t/**\n\t\t\t\t\t * edges are labelled with idx [i, i+1] (from, to)\n\t\t\t\t\t */\n\t\t\t\t\tedgeCreateCallback: (edge: TESShalfEdge) => {\n\t\t\t\t\t\tconst vert = edge.Org as TESSvertex;\n\t\t\t\t\t\tconst vi = vert.idx;\n\t\t\t\t\t\tconst from = reverseMap[vi];\n\t\t\t\t\t\tconst to = reverseMap[(vi + 1) % reverseMap.length];\n\t\t\t\t\t\tedge.idx = [from, to];\n\t\t\t\t\t\tedge.Sym.idx = [to, from];\n\t\t\t\t\t},\n\t\t\t\t\t/**\n\t\t\t\t\t * mark each vertex using the two adjacent edge idx before [fromP, toP] and after [fromN, toN]\n\t\t\t\t\t * as including all verties in the range [toP, fromN].\n\t\t\t\t\t */\n\t\t\t\t\tvertexIdCallback: (edge: TESShalfEdge): Range => {\n\t\t\t\t\t\tconst prev = edge.Lprev.idx;\n\t\t\t\t\t\treturn [prev ? prev[1] : 0, edge.idx![0]];\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (!boundary) {\n\t\t\t\t\tconsole.log('Error');\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`error generating bevel geometry for ${bevelI}'th loop`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!boundary.vertexCount) break;\n\n\t\t\t\t/**\n\t\t\t\t * split non-continuous vertices\n\t\t\t\t *\n\t\t\t\t * when the algorithm merges non-continuous vertices with other vertices,\n\t\t\t\t * the correct normals are lost in the resulting shape. To prevent this,\n\t\t\t\t * whenever there is a discontinuous vertex as part of a range, split the\n\t\t\t\t * range before and after that vertex, duplicating the vertex.\n\t\t\t\t */\n\n\t\t\t\tfor (let i = 0; i < boundary.vertexIndices.length; i++) {\n\t\t\t\t\tconst [min, max] = boundary.vertexIndices[i];\n\t\t\t\t\tif (min === max) continue;\n\n\t\t\t\t\tlet _max = max;\n\t\t\t\t\tif (max < min) _max += count;\n\n\t\t\t\t\t// no <=, we never need to split after the last of a group\n\t\t\t\t\tfor (let _vi = min; _vi < _max; _vi++) {\n\t\t\t\t\t\tconst vi = _vi % count;\n\t\t\t\t\t\tconst vin = (_vi + 1) % count;\n\n\t\t\t\t\t\tif (!info.continuous[vi] || !info.continuous[vin]) {\n\t\t\t\t\t\t\tboundary.vertexIndices[i] = [min, vi];\n\t\t\t\t\t\t\tboundary.vertexIndices.splice(i + 1, 0, [vin, max]);\n\t\t\t\t\t\t\tboundary.vertices.splice(\n\t\t\t\t\t\t\t\t(i + 1) * 2,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tboundary.vertices[i * 2],\n\t\t\t\t\t\t\t\tboundary.vertices[i * 2 + 1]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbevels.push({\n\t\t\t\t\tbevelI,\n\t\t\t\t\tangle,\n\t\t\t\t\tsize,\n\t\t\t\t\tboundary,\n\t\t\t\t\treverseMap,\n\t\t\t\t\tinsetPoints,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst groupLen = (\n\t\t\t\tsegment: BevelLoop,\n\t\t\t\tj: number,\n\t\t\t\tpp: (i: Range) => boolean\n\t\t\t): number => {\n\t\t\t\tlet len = 0;\n\t\t\t\tconst max = segment.boundary.vertexIndices.length;\n\t\t\t\twhile (len < max && pp(segment.boundary.vertexIndices[j])) {\n\t\t\t\t\tj = (j + 1) % max;\n\t\t\t\t\tlen++;\n\t\t\t\t}\n\t\t\t\treturn len;\n\t\t\t};\n\n\t\t\t// Keep track of how many new indices get added below so that we can flip them below (if this is a hole)\n\t\t\tlet indicesLenBefore = indices.length;\n\n\t\t\tfor (let bevelI = 1; bevelI < bevels.length; bevelI++) {\n\t\t\t\tconst outerBevel = bevels[bevelI - 1];\n\t\t\t\tconst innerBevel = bevels[bevelI];\n\t\t\t\tconst outerMaxI = outerBevel.boundary.vertexIndices.length;\n\t\t\t\tconst innerMaxI = innerBevel.boundary.vertexIndices.length;\n\n\t\t\t\tif (!outerMaxI || !innerMaxI) break;\n\n\t\t\t\tconst maxI = info.concave.length;\n\t\t\t\tlet currentI = 0;\n\t\t\t\tlet predicate = cycContainsPredicate(currentI, count);\n\n\t\t\t\t// find first index that is present in both loops\n\t\t\t\twhile (\n\t\t\t\t\t!outerBevel.boundary.vertexIndices.filter(predicate).length ||\n\t\t\t\t\t!innerBevel.boundary.vertexIndices.filter(predicate).length\n\t\t\t\t) {\n\t\t\t\t\tcurrentI++;\n\t\t\t\t\tpredicate = cycContainsPredicate(currentI, count);\n\t\t\t\t}\n\n\t\t\t\t// find the start of the group of vertices\n\t\t\t\tlet outerI = outerBevel.boundary.vertexIndices.findIndex(predicate);\n\t\t\t\tlet innerI = innerBevel.boundary.vertexIndices.findIndex(predicate);\n\n\t\t\t\t// fast-forward until the end of the group\n\t\t\t\tdo {\n\t\t\t\t\touterI = (outerI + 1) % outerMaxI;\n\t\t\t\t} while (predicate(outerBevel.boundary.vertexIndices[outerI]));\n\t\t\t\tdo {\n\t\t\t\t\tinnerI = (innerI + 1) % innerMaxI;\n\t\t\t\t} while (predicate(innerBevel.boundary.vertexIndices[innerI]));\n\t\t\t\tcurrentI = (currentI + 1) % count;\n\t\t\t\tconst startI = currentI;\n\t\t\t\t// create buffer data for last vert of group 0\n\t\t\t\tconst outerFirst = this.buildBevelVert(\n\t\t\t\t\tinfo,\n\t\t\t\t\touterBevel,\n\t\t\t\t\t(outerI - 1 + outerMaxI) % outerMaxI\n\t\t\t\t);\n\t\t\t\tconst innerFirst = this.buildBevelVert(\n\t\t\t\t\tinfo,\n\t\t\t\t\tinnerBevel,\n\t\t\t\t\t(innerI - 1 + innerMaxI) % innerMaxI\n\t\t\t\t);\n\t\t\t\tlet outerLast = outerFirst;\n\t\t\t\tlet innerLast = innerFirst;\n\t\t\t\tlet outerV: BevelVertResult;\n\t\t\t\tlet innerV: BevelVertResult;\n\t\t\t\tlet reverseNext = false;\n\n\t\t\t\tdo {\n\t\t\t\t\tpredicate = cycContainsPredicate(currentI, count);\n\t\t\t\t\tconst outerN = groupLen(outerBevel, outerI, predicate);\n\t\t\t\t\tconst innerN = groupLen(innerBevel, innerI, predicate);\n\t\t\t\t\tconst reverseThis = reverseNext;\n\t\t\t\t\treverseNext = false;\n\t\t\t\t\tif (outerN && !innerN) {\n\t\t\t\t\t\t// special case: only outside has verts, create fan around last inner\n\t\t\t\t\t\tfor (let j = 0; j < outerN; j++) {\n\t\t\t\t\t\t\touterV = this.buildBevelVert(\n\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\touterBevel,\n\t\t\t\t\t\t\t\t(outerI + j) % outerMaxI,\n\t\t\t\t\t\t\t\tj / (outerN - 1)\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerLast.topN);\n\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\touterLast = outerV;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treverseNext = true;\n\t\t\t\t\t} else if (!outerN && innerN) {\n\t\t\t\t\t\t// special case: only inside has verts, create fan around last outer\n\t\t\t\t\t\tfor (let j = 0; j < innerN; j++) {\n\t\t\t\t\t\t\tinnerV = this.buildBevelVert(\n\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\tinnerBevel,\n\t\t\t\t\t\t\t\t(innerI + j) % innerMaxI,\n\t\t\t\t\t\t\t\tj / (innerN - 1)\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tindices.push(innerLast.topN, outerLast.topP, innerV.topP);\n\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\touterLast.bottomP,\n\t\t\t\t\t\t\t\tinnerLast.bottomN,\n\t\t\t\t\t\t\t\tinnerV.bottomP\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tinnerLast = innerV;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (outerN && innerN) {\n\t\t\t\t\t\t// general case: have verts for both bevels\n\t\t\t\t\t\touterV = this.buildBevelVert(info, outerBevel, outerI, 0);\n\t\t\t\t\t\tinnerV = this.buildBevelVert(info, innerBevel, innerI, 0);\n\n\t\t\t\t\t\t// connect to previous group\n\t\t\t\t\t\tif (reverseThis) {\n\t\t\t\t\t\t\tindices.push(outerLast.topN, innerV.topP, innerLast.topN);\n\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerV.topP);\n\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\tinnerV.bottomP,\n\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tindices.push(outerV.bottomP, outerLast.bottomN, innerV.bottomP);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerLast.topN);\n\t\t\t\t\t\t\tindices.push(innerLast.topN, outerV.topP, innerV.topP);\n\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tindices.push(outerV.bottomP, innerLast.bottomN, innerV.bottomP);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\touterLast = outerV;\n\t\t\t\t\t\tinnerLast = innerV;\n\n\t\t\t\t\t\tif (outerN === innerN) {\n\t\t\t\t\t\t\t// easy case, build quads\n\t\t\t\t\t\t\tfor (let j = 1; j < outerN; j++) {\n\t\t\t\t\t\t\t\touterV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\touterBevel,\n\t\t\t\t\t\t\t\t\t(outerI + j) % outerMaxI,\n\t\t\t\t\t\t\t\t\tj / (outerN - 1)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tinnerV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\tinnerBevel,\n\t\t\t\t\t\t\t\t\t(innerI + j) % innerMaxI,\n\t\t\t\t\t\t\t\t\tj / (innerN - 1)\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerLast.topN);\n\t\t\t\t\t\t\t\tindices.push(innerLast.topN, outerV.topP, innerV.topP);\n\t\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tindices.push(outerV.bottomP, innerLast.bottomN, innerV.bottomP);\n\n\t\t\t\t\t\t\t\touterLast = outerV;\n\t\t\t\t\t\t\t\tinnerLast = innerV;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (outerN > innerN) {\n\t\t\t\t\t\t\t// we are in a convex-corner-curve\n\t\t\t\t\t\t\t// group every N verts on the side with more verts and make\n\t\t\t\t\t\t\t// some kind of evenly-spaced fan topology\n\t\t\t\t\t\t\tconst innerStep = outerN / innerN;\n\n\t\t\t\t\t\t\tlet k = 0;\n\t\t\t\t\t\t\tfor (let j = 1; j < outerN; j++) {\n\t\t\t\t\t\t\t\touterV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\touterBevel,\n\t\t\t\t\t\t\t\t\t(outerI + j) % outerMaxI,\n\t\t\t\t\t\t\t\t\tj / (outerN - 1)\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerLast.topN);\n\t\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\touterLast = outerV;\n\n\t\t\t\t\t\t\t\tif (j > (k + 1) * innerStep) {\n\t\t\t\t\t\t\t\t\tk++;\n\n\t\t\t\t\t\t\t\t\tinnerV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\t\tinnerBevel,\n\t\t\t\t\t\t\t\t\t\t(innerI + k) % innerMaxI,\n\t\t\t\t\t\t\t\t\t\tk / (innerN - 1)\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tindices.push(innerLast.topN, outerV.topP, innerV.topP);\n\t\t\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\t\t\tinnerLast.bottomN,\n\t\t\t\t\t\t\t\t\t\tinnerV.bottomP\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tinnerLast = innerV;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// we are in a concave-corner-curve\n\t\t\t\t\t\t\t// group every N verts on the side with more verts and make\n\t\t\t\t\t\t\t// some kind of evenly-spaced fan topology\n\t\t\t\t\t\t\tconst outerStep = innerN / outerN;\n\n\t\t\t\t\t\t\tlet k = 0;\n\t\t\t\t\t\t\tfor (let j = 1; j < innerN; j++) {\n\t\t\t\t\t\t\t\tinnerV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\tinnerBevel,\n\t\t\t\t\t\t\t\t\t(innerI + j) % innerMaxI,\n\t\t\t\t\t\t\t\t\tj / (innerN - 1)\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tindices.push(innerLast.topN, outerV.topP, innerV.topP);\n\t\t\t\t\t\t\t\tindices.push(outerV.bottomP, innerLast.bottomN, innerV.bottomP);\n\n\t\t\t\t\t\t\t\tinnerLast = innerV;\n\n\t\t\t\t\t\t\t\tif (j > (k + 1) * outerStep) {\n\t\t\t\t\t\t\t\t\tk++;\n\n\t\t\t\t\t\t\t\t\touterV = this.buildBevelVert(\n\t\t\t\t\t\t\t\t\t\tinfo,\n\t\t\t\t\t\t\t\t\t\touterBevel,\n\t\t\t\t\t\t\t\t\t\t(outerI + k) % outerMaxI,\n\t\t\t\t\t\t\t\t\t\tk / (outerN - 1)\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\tindices.push(outerLast.topN, outerV.topP, innerLast.topN);\n\t\t\t\t\t\t\t\t\tindices.push(\n\t\t\t\t\t\t\t\t\t\touterV.bottomP,\n\t\t\t\t\t\t\t\t\t\touterLast.bottomN,\n\t\t\t\t\t\t\t\t\t\tinnerLast.bottomN\n\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\touterLast = outerV;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// if neither has verts, just fall through\n\n\t\t\t\t\touterI = (outerI + outerN) % outerMaxI;\n\t\t\t\t\tinnerI = (innerI + innerN) % innerMaxI;\n\t\t\t\t\tcurrentI = (currentI + 1) % maxI;\n\t\t\t\t} while (currentI !== startI);\n\t\t\t}\n\n\t\t\t{\n\t\t\t\t// create outside wall\n\t\t\t\tconst outerBevel = bevels[0];\n\t\t\t\tfor (let i = 0, maxI = outerBevel.boundary.vertexCount; i < maxI; i++) {\n\t\t\t\t\tconst last = this.buildBevelVert(info, outerBevel, i);\n\t\t\t\t\tconst next = this.buildBevelVert(info, outerBevel, (i + 1) % maxI);\n\n\t\t\t\t\tindices.push(next.topP, last.topN, last.bottomN);\n\t\t\t\t\tindices.push(next.topP, last.bottomN, next.bottomP);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isFromHole) {\n\t\t\t\t// Hole geometry (walls and bevels) are flipped for some reason if we don't do this? This basically\n\t\t\t\t// flips all of the triangles corresponding to the hole geometry\n\t\t\t\tlet reversed = [];\n\t\t\t\tfor (let i = indices.length - 1; i >= indicesLenBefore + 2; i -= 3) {\n\t\t\t\t\tconst a = indices[i - 2];\n\t\t\t\t\tconst b = indices[i - 1];\n\t\t\t\t\tconst c = indices[i - 0];\n\t\t\t\t\treversed.push(c, b, a);\n\t\t\t\t}\n\n\t\t\t\t// Replace the relevant indices with their \"reversed\" version\n\t\t\t\tindices.splice(\n\t\t\t\t\tindicesLenBefore,\n\t\t\t\t\tindices.length - indicesLenBefore,\n\t\t\t\t\t...reversed\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (isFromHole) {\n\t\t\t\t// Push back the points that form the OUTER-most ring for this region (since it is a hole, bevels are\n\t\t\t\t// actually outset, not inset) - reverse the order of the points so that they are CW again so that the\n\t\t\t\t// surface cap calculation below works? TODO this seems dumb...\n\t\t\t\tlet reversed = [];\n\t\t\t\tfor (\n\t\t\t\t\tlet i = bevels[bevels.length - 1].boundary.vertices.length - 1;\n\t\t\t\t\ti >= 1;\n\t\t\t\t\ti -= 2\n\t\t\t\t) {\n\t\t\t\t\tconst x = bevels[bevels.length - 1].boundary.vertices[i - 1];\n\t\t\t\t\tconst y = bevels[bevels.length - 1].boundary.vertices[i - 0];\n\t\t\t\t\treversed.push(x, y);\n\t\t\t\t}\n\t\t\t\tholeInnermostBevels.push(reversed);\n\t\t\t}\n\n\t\t\t// create top surface: *only* do this for non-hole regions\n\t\t\tif (!isFromHole) {\n\t\t\t\tconst innerBevel = bevels[bevels.length - 1];\n\t\t\t\tconst surface = tesselate({\n\t\t\t\t\twindingRule: bevels.length > 1 ? WINDING.POSITIVE : WINDING.ODD,\n\t\t\t\t\telementType: ELEMENT.POLYGONS,\n\t\t\t\t\tvertexSize: 2,\n\t\t\t\t\tstrict: true,\n\t\t\t\t\tcontours: [innerBevel.insetPoints, ...holeInnermostBevels],\n\t\t\t\t});\n\n\t\t\t\tif (!surface) throw new Error('Error generating geometry for surface');\n\n\t\t\t\tfor (let i3 = 0; i3 < surface.elementCount * 3; i3 += 3) {\n\t\t\t\t\tconst a = this.buildSurfaceVert(surface, surface.elements[i3 + 0]);\n\t\t\t\t\tconst b = this.buildSurfaceVert(surface, surface.elements[i3 + 1]);\n\t\t\t\t\tconst c = this.buildSurfaceVert(surface, surface.elements[i3 + 2]);\n\n\t\t\t\t\tindices.push(a.top, b.top, c.top);\n\t\t\t\t\tindices.push(c.bottom, b.bottom, a.bottom);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// DEBUG:\n\t\t\t// regions?.push(\n\t\t\t// \tObject.assign(\n\t\t\t// \t\t{\n\t\t\t// \t\t\tstart,\n\t\t\t// \t\t\tcount,\n\t\t\t// \t\t\tend,\n\t\t\t// \t\t\tbevels,\n\t\t\t// \t\t},\n\t\t\t// \t\tinfo\n\t\t\t// \t)\n\t\t\t// );\n\n\t\t\t// clear vertex cache\n\t\t\tthis.vertexCache = {};\n\t\t}\n\n\t\t// DEBUG:\n\t\t// window.l = JSON.stringify({ regions, originalRegions });\n\n\t\tthis._buffer.shrink();\n\n\t\tconst indexAttribute = new BufferAttribute(Uint32Array.from(indices), 1);\n\t\tconst positionAttribute = new BufferAttribute(this._buffer.positions, 3);\n\t\tconst normalAttribute = new BufferAttribute(this._buffer.normals, 3);\n\t\tconst uvAttribute = new BufferAttribute(this._buffer.uvs, 2);\n\n\t\tpositionAttribute.needsUpdate = true;\n\t\tnormalAttribute.needsUpdate = true;\n\t\tuvAttribute.needsUpdate = true;\n\t\tindexAttribute.needsUpdate = true;\n\n\t\tthis.setAttribute('position', positionAttribute);\n\t\tthis.setAttribute('normal', normalAttribute);\n\t\tthis.setAttribute('uv', uvAttribute);\n\t\tthis.setIndex(indexAttribute);\n\t}\n\n\t/**\n\t * per-boundary VBO cache. Needs to be cleared for each surface.\n\t * key is either:\n\t * - `i`: vertex `i` in surface\n\t * - `bevelI:i`: vertex `i` in `bevelI`th bevel\n\t */\n\tvertexCache: { [key: string]: SurfaceVertResult | BevelVertResult } = {};\n\n\tbuildSurfaceVert(surface: IResult<number>, i: number): SurfaceVertResult {\n\t\tconst key = i.toString();\n\t\tif (key in this.vertexCache) {\n\t\t\treturn this.vertexCache[key] as SurfaceVertResult;\n\t\t}\n\n\t\tconst x = surface.vertices[i * 2 + 0];\n\t\tconst y = surface.vertices[i * 2 + 1];\n\t\tconst u = (x - this._minX) / this._width;\n\t\tconst v = (y - this._minY) / this._height;\n\n\t\tconst vC = this._buffer.get(2);\n\t\tconst vC3 = vC * 3;\n\t\tconst vC2 = vC * 2;\n\n\t\tconst result = {\n\t\t\ttop: vC + 0,\n\t\t\tbottom: vC + 1,\n\t\t};\n\n\t\t// top\n\t\tthis._buffer.positions[vC3 + 0] = x;\n\t\tthis._buffer.positions[vC3 + 1] = y;\n\t\tthis._buffer.positions[vC3 + 2] = this._depth;\n\t\tthis._buffer.normals[vC3 + 0] = 0;\n\t\tthis._buffer.normals[vC3 + 1] = 0;\n\t\tthis._buffer.normals[vC3 + 2] = 1;\n\t\tthis._buffer.uvs[vC2 + 0] = u;\n\t\tthis._buffer.uvs[vC2 + 1] = v;\n\n\t\t// bottom\n\t\tthis._buffer.positions[vC3 + 3] = x;\n\t\tthis._buffer.positions[vC3 + 4] = y;\n\t\tthis._buffer.positions[vC3 + 5] = 0;\n\t\tthis._buffer.normals[vC3 + 3] = 0;\n\t\tthis._buffer.normals[vC3 + 4] = 0;\n\t\tthis._buffer.normals[vC3 + 5] = -1;\n\t\tthis._buffer.uvs[vC2 + 2] = u;\n\t\tthis._buffer.uvs[vC2 + 3] = v;\n\n\t\tthis.vertexCache[key] = result;\n\t\treturn result;\n\t}\n\n\tbuildBevelVert(\n\t\tinfo: VertexInfo,\n\t\tbevel: BevelLoop,\n\t\ti: number,\n\t\tnormalT: number = 1\n\t): BevelVertResult {\n\t\tconst key = `${bevel.bevelI}:${i}`;\n\t\tif (key in this.vertexCache) {\n\t\t\treturn this.vertexCache[key] as BevelVertResult;\n\t\t}\n\n\t\tconst [min, max] = bevel.boundary.vertexIndices[i];\n\t\tlet fi, fip;\n\t\tlet continuous;\n\t\tlet interpolate;\n\t\tif (min !== max) {\n\t\t\t// this vertex is a merge of multiple other vertices.\n\t\t\t// use the normals from the first and last contributing\n\t\t\t// vertices respectively for pre/post normals.\n\t\t\tfip = min;\n\t\t\tfi = max;\n\t\t\tinterpolate = false;\n\t\t\tcontinuous = info.continuous[fip] && info.continuous[fi];\n\t\t} else {\n\t\t\tfi = min;\n\t\t\tfip = (fi - 1 + info.count) % info.count;\n\t\t\tinterpolate = info.concave[fi] && bevel.bevelI > 0;\n\t\t\tcontinuous = info.continuous[fi] || interpolate;\n\t\t}\n\n\t\tconst cos = Math.cos(bevel.angle);\n\t\tconst sin = Math.sin(bevel.angle);\n\n\t\tconst i2 = i * 2;\n\t\tconst fi2 = fi * 2;\n\t\tconst fip2 = fip * 2;\n\n\t\tconst x = bevel.boundary.vertices[i2 + 0];\n\t\tconst y = bevel.boundary.vertices[i2 + 1];\n\t\tconst z = (1 - sin) * this._bevelSize;\n\t\tconst u = (x - this._minX) / this._width;\n\t\tconst v = (y - this._minY) / this._height;\n\t\tlet nx = info.normals[fi2 + 0];\n\t\tlet ny = info.normals[fi2 + 1];\n\t\tconst nxp = info.normals[fip2 + 0];\n\t\tconst nyp = info.normals[fip2 + 1];\n\n\t\tif (interpolate) {\n\t\t\tconst ndx = nxp - nx;\n\t\t\tconst ndy = nyp - ny;\n\t\t\tnx = nx + ndx * (1 - normalT);\n\t\t\tny = ny + ndy * (1 - normalT);\n\t\t\tconst len = Math.sqrt(nx * nx + ny * ny);\n\t\t\tnx /= len;\n\t\t\tny /= len;\n\t\t}\n\n\t\tlet vC = this._buffer.get(continuous ? 2 : 4);\n\t\tlet vC3 = vC * 3;\n\t\tlet vC2 = vC * 2;\n\n\t\tconst result = {\n\t\t\ti,\n\t\t\tfi,\n\t\t\ttopP: vC + 0,\n\t\t\ttopN: vC + 0,\n\t\t\tbottomP: vC + 1,\n\t\t\tbottomN: vC + 1,\n\t\t};\n\n\t\t// top\n\t\tthis._buffer.positions[vC3 + 0] = x;\n\t\tthis._buffer.positions[vC3 + 1] = y;\n\t\tthis._buffer.positions[vC3 + 2] = this._depth - z;\n\t\tthis._buffer.normals[vC3 + 0] = nx * cos;\n\t\tthis._buffer.normals[vC3 + 1] = ny * cos;\n\t\tthis._buffer.normals[vC3 + 2] = sin;\n\t\tthis._buffer.uvs[vC2 + 0] = u;\n\t\tthis._buffer.uvs[vC2 + 1] = v;\n\n\t\t// bottom\n\t\tthis._buffer.positions[vC3 + 3] = x;\n\t\tthis._buffer.positions[vC3 + 4] = y;\n\t\tthis._buffer.positions[vC3 + 5] = z;\n\t\tthis._buffer.normals[vC3 + 3] = nx * cos;\n\t\tthis._buffer.normals[vC3 + 4] = ny * cos;\n\t\tthis._buffer.normals[vC3 + 5] = -sin;\n\t\tthis._buffer.uvs[vC2 + 2] = v;\n\t\tthis._buffer.uvs[vC2 + 3] = u;\n\n\t\tif (!continuous) {\n\t\t\tvC += 2;\n\t\t\tvC3 += 6;\n\t\t\tvC2 += 4;\n\n\t\t\tresult.topP = vC + 0;\n\t\t\tresult.bottomP = vC + 1;\n\n\t\t\t// top\n\t\t\tthis._buffer.positions[vC3 + 0] = x;\n\t\t\tthis._buffer.positions[vC3 + 1] = y;\n\t\t\tthis._buffer.positions[vC3 + 2] = this._depth - z;\n\t\t\tthis._buffer.normals[vC3 + 0] = nxp * cos;\n\t\t\tthis._buffer.normals[vC3 + 1] = nyp * cos;\n\t\t\tthis._buffer.normals[vC3 + 2] = sin;\n\t\t\tthis._buffer.uvs[vC2 + 0] = u;\n\t\t\tthis._buffer.uvs[vC2 + 1] = v;\n\n\t\t\t// bottom\n\t\t\tthis._buffer.positions[vC3 + 3] = x;\n\t\t\tthis._buffer.positions[vC3 + 4] = y;\n\t\t\tthis._buffer.positions[vC3 + 5] = z;\n\t\t\tthis._buffer.normals[vC3 + 3] = nxp * cos;\n\t\t\tthis._buffer.normals[vC3 + 4] = nyp * cos;\n\t\t\tthis._buffer.normals[vC3 + 5] = -sin;\n\t\t\tthis._buffer.uvs[vC2 + 2] = v;\n\t\t\tthis._buffer.uvs[vC2 + 3] = u;\n\t\t}\n\n\t\tthis.vertexCache[key] = result;\n\t\treturn result;\n\t}\n\n\tclone(): BufferGeometry {\n\t\tconst geom = new VectorExtrusionGeometry(\n\t\t\tthis._shape,\n\t\t\tthis._depth,\n\t\t\tthis._bevel,\n\t\t\tthis._curveSegments,\n\t\t\tthis._bevelSegmentsInput\n\t\t);\n\t\tgeom.userData = cloneDeep(this.userData);\n\t\treturn geom as BufferGeometry;\n\t}\n}\n", "/**\n * Keep verext positions, normals and uvs in a single ArrayBuffer and dynamically\n * reallocate it as needed while inserting an unbounded number of elements.\n */\nexport class DynamicBuffer {\n\tbuffer: ArrayBuffer;\n\tpositions: Float32Array;\n\tnormals: Float32Array;\n\tuvs: Float32Array;\n\n\tsize: number;\n\tcapacity: number;\n\n\tdebug: boolean;\n\n\tstatic eSize = (3 + 3 + 2) * Float32Array.BYTES_PER_ELEMENT;\n\n\t/**\n\t * Create a new dynamic buffer with a reserved start capacity.\n\t * @param capacity - initial element capacity\n\t */\n\tconstructor(capacity: number = 256, debug: boolean = false) {\n\t\tthis.capacity = capacity;\n\t\tthis.size = 0;\n\t\tthis.debug = debug;\n\n\t\tthis.debug && console.log(`allocating with cap ${capacity}`);\n\n\t\tconst bytes = capacity * DynamicBuffer.eSize;\n\t\tthis.buffer = new ArrayBuffer(bytes);\n\n\t\tconst bpe = Float32Array.BYTES_PER_ELEMENT;\n\t\tlet i = 0;\n\t\tthis.positions = new Float32Array(this.buffer, i * bpe, 3 * capacity);\n\t\ti += 3 * capacity;\n\t\tthis.normals = new Float32Array(this.buffer, i * bpe, 3 * capacity);\n\t\ti += 3 * capacity;\n\t\tthis.uvs = new Float32Array(this.buffer, i * bpe, 2 * capacity);\n\t}\n\n\t/**\n\t * Resize the underlying buffer\n\t * @param capacity - New capacity (in number of elements). Must be at least equal to {@link size}.\n\t */\n\trealloc(capacity: number, allowShrink: boolean = false) {\n\t\tif (capacity < this.size) throw Error('cannot shrink buffer');\n\t\tif (capacity <= this.capacity && !allowShrink) return;\n\n\t\tthis.debug && console.log(`resizing from ${this.capacity} \u2192 ${capacity}`);\n\n\t\tconst bytes = capacity * DynamicBuffer.eSize;\n\t\tconst buffer = new ArrayBuffer(bytes);\n\n\t\tconst bpe = Float32Array.BYTES_PER_ELEMENT;\n\t\tlet i = 0;\n\t\tconst positions = new Float32Array(buffer, i * bpe, 3 * capacity);\n\t\ti += 3 * capacity;\n\t\tconst normals = new Float32Array(buffer, i * bpe, 3 * capacity);\n\t\ti += 3 * capacity;\n\t\tconst uvs = new Float32Array(buffer, i * bpe, 2 * capacity);\n\n\t\tpositions.set(this.positions.slice(0, this.size * 3));\n\t\tnormals.set(this.normals.slice(0, this.size * 3));\n\t\tuvs.set(this.uvs.slice(0, this.size * 2));\n\n\t\tthis.buffer = buffer;\n\t\tthis.positions = positions;\n\t\tthis.normals = normals;\n\t\tthis.uvs = uvs;\n\n\t\tthis.capacity = capacity;\n\t}\n\n\t/**\n\t * Return the index of the first free element and ensure there is enough space.\n\t * @param size - number of elements that the caller wants to write\n\t * @returns index of the first free element. The elements [i, i+size[ are\n\t * guaranteed to be writable.\n\t */\n\tget(size: number = 1): number {\n\t\tconst newSize = this.size + size;\n\t\tif (newSize > this.capacity) {\n\t\t\tlet capacity = this.capacity;\n\t\t\twhile (newSize > capacity) capacity *= 2;\n\n\t\t\tthis.realloc(capacity);\n\t\t}\n\n\t\tconst lastSize = this.size;\n\t\tthis.size = newSize;\n\t\treturn lastSize;\n\t}\n\n\t/**\n\t * Reserve a fixed amount of elements in addition to the currently used elements.\n\t * This can be used to preempt reallocations when starting with a small capacity.\n\t * @param size - number of elements to reserve\n\t */\n\treserve(size: number) {\n\t\tconst capacity = this.size + size;\n\t\tif (capacity > this.capacity) {\n\t\t\tthis.realloc(capacity);\n\t\t}\n\t}\n\n\t/**\n\t * Shrink underlying buffer to the size required to contain currently set elements\n\t * to conserve memory.\n\t */\n\tshrink() {\n\t\tthis.debug && console.log(`shrinking ${this.capacity} \u2192 ${this.size}`);\n\t\tthis.realloc(this.size, true);\n\t}\n}\n", "/**\n * @author s-ol\n */\n\nimport { CGeometry, IGeometry, NestedPartial } from '../Geometry';\nimport { VectorShape } from '../../objects/entities/vectors/VectorShape';\nimport { VectorSurfaceGeometry } from './VectorSurfaceGeometry';\nimport { VectorExtrusionGeometry } from './VectorExtrusionGeometry';\nimport { SerializedVectorShape } from 'spline-data/src/legacyFormat/ObjectSpec';\n\nexport type VectorGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tsubdivisions: number;\n\troundness: number;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tsurfaceMaxCount: number;\n};\n\nexport type VectorGeometryInputs = {\n\tparameters: VectorGeometryParameters;\n\tshape: VectorShape;\n};\n\nexport const VectorGeometry: CGeometry<VectorGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<VectorGeometryInputs>\n\t): IGeometry<VectorGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<VectorGeometryInputs>,\n\t\tbase?: VectorGeometryInputs\n\t): VectorGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tsubdivisions: 40,\n\t\t\t\troundness: 0,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\tsurfaceMaxCount: 100,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 3,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\tconst width = Math.abs(nParams.width);\n\t\tconst height = Math.abs(nParams.height ?? nParams.width);\n\t\tconst depth = Math.abs(\n\t\t\tnParams.depth !== undefined &&\n\t\t\t\tnParams.depth === 0 &&\n\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t: nParams.depth ?? 0\n\t\t);\n\n\t\tlet inputShape = inputs.shape ?? base?.shape;\n\t\tconst roundness = inputShape?.roundness ?? nParams.roundness;\n\n\t\tif (inputShape !== undefined) {\n\t\t\tif (inputShape instanceof VectorShape) {\n\t\t\t\tif (inputShape.width !== width || inputShape.height !== height) {\n\t\t\t\t\tinputShape.applySize(width, height);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tinputShape = new VectorShape(width, height).fromJSON(\n\t\t\t\t\tinputShape as SerializedVectorShape\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tinputs.parameters?.roundness !== undefined &&\n\t\t\t\tinputs.parameters?.roundness > 0\n\t\t\t) {\n\t\t\t\tinputShape.update(false);\n\t\t\t}\n\t\t}\n\n\t\tconst shape = inputShape ?? new VectorShape(width, height);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\textrudeDepth: depth,\n\t\t\t\troundness,\n\t\t\t}),\n\t\t\tshape,\n\t\t};\n\t}\n\n\tstatic build(inputs: VectorGeometryInputs): IGeometry<VectorGeometryInputs> {\n\t\tconst {\n\t\t\textrudeDepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tsubdivisions,\n\t\t\troundness,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\n\t\tinputs.shape.roundness = roundness;\n\n\t\tlet geometry;\n\t\tif (extrudeDepth <= 0) {\n\t\t\tgeometry = new VectorSurfaceGeometry(\n\t\t\t\tinputs.shape,\n\t\t\t\tsubdivisions,\n\t\t\t\tsurfaceMaxCount\n\t\t\t);\n\t\t} else {\n\t\t\tgeometry = new VectorExtrusionGeometry(\n\t\t\t\tinputs.shape,\n\t\t\t\textrudeDepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\tsubdivisions,\n\t\t\t\textrudeBevelSegments\n\t\t\t);\n\t\t}\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'VectorGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author alejandro\n * @author nisa\n * @author guillaume\n */\n\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { VectorShape } from '../objects/entities/vectors/VectorShape';\nimport { BezierPoint } from '../objects/entities/vectors/bezier';\nimport { arcToBezier, Curve } from './vectors/ArcToCurves';\nimport { VectorGeometry } from './vectors/VectorGeometry';\nimport { MathUtils, Vector2 } from 'three';\n\nconst TAU = Math.PI * 2;\n\nexport type EllipseGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tspikes: number;\n\tangle: number;\n\tinnerRadius: number;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tsurfaceMaxCount: number;\n};\n\nexport type EllipseGeometryInputs = {\n\tparameters: EllipseGeometryParameters;\n\tshape: VectorShape;\n};\n\nexport const EllipseGeometry: CGeometry<EllipseGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<EllipseGeometryInputs>\n\t): IGeometry<EllipseGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<EllipseGeometryInputs>,\n\t\tbase?: EllipseGeometryInputs\n\t): EllipseGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\tspikes: 64,\n\t\t\t\tangle: 360,\n\t\t\t\tinnerRadius: 0,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t\tsurfaceMaxCount: 1000,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\t// Can be passed from inputs when restoring from VectorObject\n\t\tconst shape =\n\t\t\tinputs.shape && inputs.shape instanceof VectorShape\n\t\t\t\t? inputs.shape\n\t\t\t\t: new VectorShape();\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(\n\t\t\t\t\tnParams.depth !== undefined &&\n\t\t\t\t\t\tnParams.depth === 0 &&\n\t\t\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t\t\t: nParams.depth ?? 0\n\t\t\t\t),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: EllipseGeometryInputs\n\t): IGeometry<EllipseGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tspikes,\n\t\t\tangle,\n\t\t\tinnerRadius,\n\t\t\tdepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\t\tconst shape = inputs.shape;\n\t\tconst outerRadiusX = width * 0.5;\n\t\tconst outerRadiusY = height * 0.5;\n\t\tconst subdivisions = createAngledEllipse(\n\t\t\tshape,\n\t\t\touterRadiusX,\n\t\t\touterRadiusY,\n\t\t\t(angle * Math.PI) / 180,\n\t\t\tspikes,\n\t\t\tinnerRadius\n\t\t);\n\t\tshape.isClosed = true;\n\t\tshape.update();\n\n\t\tconst geometry = VectorGeometry.create({\n\t\t\tshape,\n\t\t\tparameters: {\n\t\t\t\tsubdivisions,\n\t\t\t\tsurfaceMaxCount,\n\t\t\t\tdepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\textrudeBevelSegments,\n\t\t\t},\n\t\t});\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'EllipseGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport function createAngledEllipse(\n\tshape: VectorShape,\n\trx: number,\n\try: number,\n\tangle: number,\n\tsides: number,\n\tring: number\n) {\n\tif (angle >= TAU) {\n\t\tif (sides > 30 || sides % 4 === 0) {\n\t\t\tcircle(shape, rx, ry, ring);\n\t\t\treturn Math.round(sides / 4);\n\t\t} else {\n\t\t\treturn segments(shape, angle, sides, rx, ry, ring);\n\t\t}\n\t}\n\n\tconst startPoint = { x: 0, y: ry };\n\tconst offsetAngle = angle + Math.PI * 0.5;\n\tconst endPoint = {\n\t\tx: Math.cos(offsetAngle) * rx,\n\t\ty: Math.sin(offsetAngle) * ry,\n\t};\n\tconst curves = arcToBezier({\n\t\tpx: startPoint.x,\n\t\tpy: startPoint.y,\n\t\tcx: endPoint.x,\n\t\tcy: endPoint.y,\n\t\trx,\n\t\try,\n\t\tlargeArcFlag: angle > Math.PI, //false\n\t\tsweepFlag: true, // true\n\t});\n\n\t// ARC technique\n\tif (sides > 30 || sides % curves.length === 0) {\n\t\treturn arcs(shape, startPoint.x, startPoint.y, curves, sides, rx, ry, ring);\n\t}\n\t// Segments technique\n\telse {\n\t\treturn segments(shape, angle, sides, rx, ry, ring);\n\t}\n}\n\nfunction arcs(\n\tshape: VectorShape,\n\tx: number,\n\ty: number,\n\tcurves: Curve[],\n\tsides: number,\n\trx: number,\n\try: number,\n\tring: number\n) {\n\tconst subdivisions = Math.round(sides / curves.length);\n\tshape.addPoint(createPoint(x, y));\n\n\tfor (let i = 0, l = curves.length; i < l; i++) {\n\t\tconst curve = curves[i];\n\t\tconst previous = shape.points[i];\n\t\tconst current = createPoint(curve.x, curve.y);\n\t\tprevious.controls[1].position.set(curve.x1, curve.y1);\n\t\tcurrent.controls[0].position.set(curve.x2, curve.y2);\n\t\tshape.addPoint(current);\n\t}\n\n\tif (ring > 0) {\n\t\tcreateInnerPointsOnShape(shape, rx, ry, ring);\n\t} else {\n\t\tshape.addPoint(createPoint(0, 0));\n\t}\n\treturn subdivisions;\n}\nfunction segments(\n\tshape: VectorShape,\n\tangle: number,\n\tsides: number,\n\trx: number,\n\try: number,\n\tring: number\n) {\n\tconst step = -angle / sides;\n\tfor (let i = 0; i <= sides; i++) {\n\t\tconst angleCurrent = step * i;\n\t\tconst x = Math.sin(angleCurrent) * rx;\n\t\tconst y = Math.cos(angleCurrent) * ry;\n\t\tshape.addPoint(createPoint(x, y));\n\t}\n\n\tif (angle < TAU) {\n\t\tif (ring > 0) {\n\t\t\tcreateInnerPointsOnShape(shape, rx, ry, ring);\n\t\t} else {\n\t\t\tshape.addPoint(createPoint(0, 0));\n\t\t}\n\t} else {\n\t\tshape.removePoint(shape.points[shape.points.length - 1]);\n\t\tif (ring > 0) {\n\t\t\tcreateInnerPointsOnHole(shape, rx, ry, ring);\n\t\t}\n\t}\n\n\treturn 1;\n}\nfunction circle(\n\tshape: VectorShape,\n\trx: number,\n\try: number,\n\tring: number = 0,\n\tcx: number = 0,\n\tcy: number = 0\n) {\n\tconst kappa = 0.5522847498;\n\tconst ox = rx * kappa;\n\tconst oy = ry * kappa;\n\n\tshape.addPoint(\n\t\tcreatePointWithControls(cx - rx, cy, cx - rx, cy - oy, cx - rx, cy + oy)\n\t);\n\tshape.addPoint(\n\t\tcreatePointWithControls(cx, cy + ry, cx - ox, cy + ry, cx + ox, cy + ry)\n\t);\n\tshape.addPoint(\n\t\tcreatePointWithControls(cx + rx, cy, cx + rx, cy + oy, cx + rx, cy - oy)\n\t);\n\tshape.addPoint(\n\t\tcreatePointWithControls(cx, cy - ry, cx + ox, cy - ry, cx - ox, cy - ry)\n\t);\n\n\tif (ring > 0) {\n\t\tcreateInnerPointsOnHole(shape, rx, ry, ring);\n\t}\n}\n\nfunction createPoint(x: number, y: number) {\n\treturn new BezierPoint(MathUtils.generateUUID(), new Vector2(x, y));\n}\n\nfunction createPointWithControls(\n\tx: number,\n\ty: number,\n\tc1x: number,\n\tc1y: number,\n\tc2x: number,\n\tc2y: number\n) {\n\tconst point = createPoint(x, y);\n\tpoint.controls[0].position.set(c1x, c1y);\n\tpoint.controls[1].position.set(c2x, c2y);\n\treturn point;\n}\n\nfunction createInnerPointsOnShape(\n\tshape: VectorShape,\n\trx: number,\n\try: number,\n\tring: number\n) {\n\tconst innerPoints = createInnerPoints(shape, rx, ry, ring);\n\tinnerPoints.forEach((p) => shape.addPoint(p));\n}\n\nfunction createInnerPointsOnHole(\n\tshape: VectorShape,\n\trx: number,\n\try: number,\n\tring: number\n) {\n\tconst innerPoints = createInnerPoints(shape, rx, ry, ring);\n\tconst hole = new VectorShape();\n\tinnerPoints.forEach((p) => hole.addPoint(p));\n\thole.isClosed = true;\n\tshape.shapeHoles.push(hole);\n}\n\nfunction createInnerPoints(\n\tshape: VectorShape,\n\trx: number,\n\try: number,\n\tring: number\n) {\n\tconst innerRx = (ring * rx) / 100;\n\tconst innerRy = innerRx * (Math.abs(ry) / Math.abs(rx));\n\tconst scale = new Vector2(innerRx / rx, innerRy / ry);\n\tconst innerPoints = shape.points\n\t\t.map((p) => {\n\t\t\tconst c = p.clone();\n\t\t\tc.uuid = MathUtils.generateUUID();\n\t\t\treturn c;\n\t\t})\n\t\t.reverse();\n\tinnerPoints.forEach((p) => {\n\t\tp.position.multiply(scale);\n\t\tconst temp0 = p.controls[0].position.clone().multiply(scale);\n\t\tconst temp1 = p.controls[1].position.clone().multiply(scale);\n\t\tp.controls[0].position.copy(temp1);\n\t\tp.controls[1].position.copy(temp0);\n\t});\n\treturn innerPoints;\n}\n", "/**\n * @author lawrence\n */\n\nimport { BufferGeometry, Float32BufferAttribute, Vector3 } from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type HelixGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tradius: number;\n\trevolutions: number;\n\tsegments: number;\n\tpathRadius: number;\n\tpathType: number;\n\tpathSegments: number;\n\tcornerRadius: number;\n\tcornerSegments: number;\n};\n\nexport type HelixGeometryInputs = { parameters: HelixGeometryParameters };\n\nexport const HelixGeometry: CGeometry<HelixGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<HelixGeometryInputs>\n\t): IGeometry<HelixGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<HelixGeometryInputs>,\n\t\tbase?: HelixGeometryInputs\n\t): HelixGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\trevolutions: 2,\n\t\t\t\tsegments: 40,\n\t\t\t\tpathRadius: 10,\n\t\t\t\tpathType: 0,\n\t\t\t\tpathSegments: 30,\n\t\t\t\tcornerRadius: 30,\n\t\t\t\tcornerSegments: 4,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\tconst width = Math.abs(nParams.width);\n\t\tconst height = Math.abs(nParams.height ?? width);\n\t\tconst depth = Math.abs(nParams.depth ?? width);\n\t\tconst radius = Math.abs(Math.min(width, depth)) / 2;\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t\tradius,\n\t\t\t\tsegments: Math.round(nParams.segments),\n\t\t\t\tpathSegments: Math.round(nParams.pathSegments),\n\t\t\t\tcornerSegments: Math.round(nParams.cornerSegments),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: HelixGeometryInputs): IGeometry<HelixGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\tradius,\n\t\t\trevolutions,\n\t\t\tsegments,\n\t\t\tpathRadius,\n\t\t\tpathType,\n\t\t\tpathSegments,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments,\n\t\t} = inputs.parameters;\n\n\t\tconst geometry = new HelixBufferGeometry(\n\t\t\tfalse, // not a torus\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\tradius,\n\t\t\trevolutions,\n\t\t\tsegments,\n\t\t\tpathRadius,\n\t\t\tpathType,\n\t\t\tpathSegments,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments\n\t\t);\n\t\t// geometry.scale(1, 1, depth / width); // Commented to keep same behaviour as before merge\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'HelixGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\n/**\n * HelixBufferGeometry\n */\nexport class HelixBufferGeometry extends BufferGeometry {\n\tconstructor(\n\t\tisTorus: boolean = true,\n\t\tgui_width: number = 1,\n\t\tgui_height: number = 1,\n\t\tgui_depth: number = 1,\n\t\tgui_radius: number = 1,\n\t\tgui_revolutions: number = 1,\n\t\tgui_segments: number = 1,\n\t\tgui_pathRadius: number = 1,\n\t\tgui_pathType: number = 1,\n\t\tgui_pathSegments: number = 1,\n\t\tgui_cornerRadius: number = 1,\n\t\tgui_cornerSegments: number = 1\n\t) {\n\t\tsuper();\n\n\t\tconst closedTorus = isTorus && gui_revolutions === 1;\n\n\t\t//--------------------------------------------------\n\t\t// adjustments\n\t\t//--------------------------------------------------\n\t\tif (closedTorus) gui_cornerSegments = 0;\n\n\t\tif (gui_cornerRadius > 100) gui_cornerRadius = 100;\n\t\t//--------------------------------------------------\n\n\t\tconst newVec = () => new Vector3();\n\n\t\tconst v0 = new Vector3(),\n\t\t\tv1 = newVec(); // auxiliary vectors\n\t\tconst pathCenter = newVec(),\n\t\t\tcornerCenter = newVec();\n\t\tlet a, b, c, d, x, y, z, ang;\n\t\tconst lastCoord = newVec();\n\t\tconst pathRadiusLine = newVec(),\n\t\t\tpathRadiusNormal = newVec(),\n\t\t\tcornerRadiusLine = newVec(),\n\t\t\tcornerRadiusNormal = newVec();\n\t\tconst abscissa = newVec(),\n\t\t\tordinate = newVec(),\n\t\t\tpathAxis = newVec();\n\n\t\tconst heightTotal = gui_height - 2 * gui_pathRadius + 0.001; // small value added to prevent heightTotal 0 (0 means won't be drawn)\n\t\tconst revolutionHeight = heightTotal / gui_revolutions;\n\t\tconst tubeSegments = Math.ceil(gui_segments * gui_revolutions);\n\t\tconst tubeSegmentsP1 = tubeSegments + 1;\n\t\tconst heightSegment = heightTotal / tubeSegments;\n\t\tconst baseHeight = -heightTotal / 2;\n\n\t\tconst pathSegmentsP1 = gui_pathSegments + 1; // this extra segment's coord will be the same as the first (for UV wrapping purposes)\n\t\tconst pathSegmentArc = (2 * Math.PI) / gui_pathSegments;\n\t\tconst cornerSegmentArc = Math.PI / 2 / gui_cornerSegments;\n\t\tconst cornerMargin = 0.01; // small non-zero margin to subtract from pathRadius, otherwise the cap may be hidden.\n\t\tconst cornerRadiusPercent = Math.min(\n\t\t\t(1 - gui_cornerRadius / 100) * gui_pathRadius,\n\t\t\tgui_pathRadius - cornerMargin\n\t\t);\n\t\tconst arcRadius = gui_pathRadius - cornerRadiusPercent; // to use absolute cornerRadius, just replace 'cornerRadiusPercent' with 'gui_cornerRadius'\n\n\t\tlet iArr = 0;\n\t\tconst bothCapsSegments = 2; // top and bottom.\n\t\tconst totalCornerAndCapsSegments =\n\t\t\tgui_cornerSegments * bothCapsSegments + bothCapsSegments;\n\t\tconst offsetSkipTopCap =\n\t\t\t(pathSegmentsP1 * totalCornerAndCapsSegments) / bothCapsSegments;\n\t\tconst offsetSkipTopCapAndTube =\n\t\t\toffsetSkipTopCap + pathSegmentsP1 * tubeSegmentsP1;\n\t\t//\n\t\tconst dimArr =\n\t\t\tpathSegmentsP1 * (tubeSegmentsP1 + totalCornerAndCapsSegments);\n\n\t\tconst [vertices, normals, uvs] = [3, 3, 2].map((x) =>\n\t\t\tArray(dimArr * x).fill(0)\n\t\t);\n\t\tconst indices = [];\n\n\t\t// ---------------------------------------------------------------------\n\n\t\tconst difRadius = gui_radius - gui_pathRadius;\n\n\t\tfunction setPathCenter(vec: Vector3, numSeg: number) {\n\t\t\tconst startBottomAngle = Math.PI / 2;\n\n\t\t\ty = numSeg * heightSegment; // include \"+ baseHeight\" if want both sides to change simultaneously (and delete the line below, adding baseHeight)\n\t\t\tang =\n\t\t\t\t(2 * Math.PI * (y % revolutionHeight)) / revolutionHeight +\n\t\t\t\tstartBottomAngle;\n\t\t\ty += baseHeight;\n\t\t\tz = Math.sin(ang) * difRadius;\n\t\t\tx = Math.cos(ang) * difRadius;\n\n\t\t\tif (isTorus) vec.set(x, z, y);\n\t\t\telse vec.set(x, y, z);\n\t\t}\n\n\t\tsetPathCenter(v0, -1e-10); // small negative value, just to straighten the top corner's direction.\n\t\tsetPathCenter(v1, 0);\n\t\t//\n\t\tlastCoord.copy(v0);\n\n\t\t//--------------------------------------------------------\n\t\t// UVs\n\t\t//--------------------------------------------------------\n\t\tsetPathCenter(v0, 1);\n\t\tconst segmentLength = v0.distanceTo(v1);\n\t\tconst cornerAndCap = arcRadius + cornerRadiusPercent;\n\t\tconst helixLength = segmentLength * tubeSegments + 2 * cornerAndCap;\n\t\tconst startBottomCorner = cornerRadiusPercent;\n\t\tconst startTopCorner = helixLength - cornerAndCap;\n\t\t//--------------------------------------------------------\n\n\t\t// one solution to the distortion when width != depth\n\t\t// the segment circles point to the helix's center, that's why the helix tube ends up distorted in any angle that's not multiple of 90 deg.\n\t\t// - take the vector obtained by the line connecting 2 adjacent tube axis (pathCenter-lastCoord) - (next pathCenter-next lastCoord) call it 'tubeAxis'\n\t\t// then calculate the cross product between this tubeAxis and upVector ('vectorToHelixCenter' - Note: this isn't the exact helix center)\n\n\t\t//-----------------------------------------------------------------------------------\n\t\t// tube geometry with caps\n\t\t//-----------------------------------------------------------------------------------\n\t\tfor (let numSeg = 0; numSeg <= tubeSegments; numSeg++) {\n\t\t\tsetPathCenter(pathCenter, numSeg);\n\n\t\t\tpathAxis.subVectors(pathCenter, lastCoord).normalize();\n\t\t\tlastCoord.copy(pathCenter);\n\n\t\t\tabscissa\n\t\t\t\t.copy(pathCenter)\n\t\t\t\t.setComponent(+isTorus + 1, 0)\n\t\t\t\t.normalize();\n\n\t\t\tordinate.crossVectors(pathAxis, abscissa).normalize();\n\n\t\t\t//---------------------------------------------------------------------------\n\t\t\t// To Do: just execute these init calculation if (firstSeg || lastSeg)\n\t\t\t//---------------------------------------------------------------------------\n\t\t\tconst firstSeg = numSeg === 0;\n\t\t\tconst lastSeg = numSeg === tubeSegments;\n\t\t\t//\n\t\t\tconst startAngle = firstSeg ? (3 * Math.PI) / 2 : cornerSegmentArc;\n\t\t\tconst offsetUV = firstSeg ? startBottomCorner : startTopCorner;\n\t\t\t//\n\t\t\tconst iArrOffset = firstSeg ? pathSegmentsP1 : offsetSkipTopCapAndTube;\n\t\t\t//\n\t\t\tconst offsCap = firstSeg ? 0 : dimArr - pathSegmentsP1;\n\t\t\t//\n\t\t\tconst centerCap = pathAxis\n\t\t\t\t.clone()\n\t\t\t\t.multiplyScalar(firstSeg ? -arcRadius : arcRadius)\n\t\t\t\t.add(pathCenter);\n\t\t\tconst normCap = pathAxis\n\t\t\t\t.clone()\n\t\t\t\t.multiplyScalar(firstSeg ? -1 : 1)\n\t\t\t\t.normalize();\n\t\t\t//---------------------------------------------------------------------------\n\n\t\t\tfor (let i = 0; i < pathSegmentsP1; i++) {\n\t\t\t\tconst angPath = i * pathSegmentArc;\n\n\t\t\t\tpathRadiusLine.addVectors(\n\t\t\t\t\tv0.copy(abscissa).multiplyScalar(gui_pathRadius * Math.cos(angPath)),\n\t\t\t\t\tv1.copy(ordinate).multiplyScalar(gui_pathRadius * Math.sin(angPath))\n\t\t\t\t);\n\n\t\t\t\tpathRadiusNormal.copy(pathRadiusLine).normalize();\n\n\t\t\t\t// top and bottom corners\n\t\t\t\tif (firstSeg || lastSeg) {\n\t\t\t\t\t// top and bottom caps\n\t\t\t\t\tif (!closedTorus) {\n\t\t\t\t\t\tiArr = offsCap + i;\n\n\t\t\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t\t\t[0, 1, 2].forEach((ind) => {\n\t\t\t\t\t\t\tvertices[iArr * 3 + ind] = centerCap.getComponent(ind);\n\t\t\t\t\t\t\tnormals[iArr * 3 + ind] = normCap.getComponent(ind);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tuvs[iArr * 2] = +lastSeg;\n\t\t\t\t\t\tuvs[iArr * 2 + 1] = i / gui_pathSegments;\n\t\t\t\t\t}\n\n\t\t\t\t\tv1.copy(pathRadiusNormal).multiplyScalar(cornerRadiusPercent);\n\t\t\t\t\tcornerCenter.addVectors(pathCenter, v1);\n\n\t\t\t\t\tfor (let j = 0; j < gui_cornerSegments; j++) {\n\t\t\t\t\t\tconst angCorner = j * cornerSegmentArc + startAngle;\n\n\t\t\t\t\t\tcornerRadiusLine.addVectors(\n\t\t\t\t\t\t\tv0.copy(pathAxis).multiplyScalar(arcRadius * Math.sin(angCorner)),\n\t\t\t\t\t\t\tv1\n\t\t\t\t\t\t\t\t.copy(pathRadiusNormal)\n\t\t\t\t\t\t\t\t.multiplyScalar(arcRadius * Math.cos(angCorner))\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tcornerRadiusNormal.copy(cornerRadiusLine).normalize();\n\n\t\t\t\t\t\tv1.addVectors(cornerCenter, cornerRadiusLine);\n\n\t\t\t\t\t\tcornerRadiusLine.normalize();\n\n\t\t\t\t\t\tiArr = iArrOffset + j * pathSegmentsP1 + i;\n\n\t\t\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t\t\t[0, 1, 2].forEach((ind) => {\n\t\t\t\t\t\t\tvertices[iArr * 3 + ind] = v1.getComponent(ind);\n\t\t\t\t\t\t\tnormals[iArr * 3 + ind] = cornerRadiusNormal.getComponent(ind);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst sinUV = +firstSeg + Math.sin(angCorner);\n\t\t\t\t\t\tuvs[iArr * 2] = (offsetUV + arcRadius * sinUV) / helixLength;\n\t\t\t\t\t\tuvs[iArr * 2 + 1] = i / gui_pathSegments;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tv1.addVectors(pathCenter, pathRadiusLine);\n\n\t\t\t\tiArr = offsetSkipTopCap + numSeg * pathSegmentsP1 + i;\n\n\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t[0, 1, 2].forEach((ind) => {\n\t\t\t\t\tvertices[iArr * 3 + ind] = v1.getComponent(ind);\n\t\t\t\t\tnormals[iArr * 3 + ind] = pathRadiusNormal.getComponent(ind);\n\t\t\t\t});\n\t\t\t\tuvs[iArr * 2] = (cornerAndCap + numSeg * segmentLength) / helixLength;\n\t\t\t\tuvs[iArr * 2 + 1] = i / gui_pathSegments;\n\t\t\t}\n\t\t}\n\n\t\t//-----------------------------------------------------------------------------------\n\t\t// indices for the tube and corners\n\t\t//-----------------------------------------------------------------------------------\n\t\tconst totalSegs =\n\t\t\ttubeSegmentsP1 + 2 * gui_cornerSegments + bothCapsSegments;\n\t\tconst capSegment = 1;\n\n\t\tconst [startSeg, endSeg] = !closedTorus // obs: if (closedTorus) then gui_cornerSegments is 0\n\t\t\t? [0, totalSegs - 1]\n\t\t\t: [capSegment, capSegment + tubeSegmentsP1 - 1];\n\n\t\tfor (let i = startSeg; i <= endSeg - 1; i++) {\n\t\t\t// one less because the loop already connects current seg to the next (or first, if torus)\n\n\t\t\tconst lastClosedSegment = closedTorus && i === endSeg - 1;\n\n\t\t\tfor (\n\t\t\t\tlet j = 0;\n\t\t\t\tj < pathSegmentsP1 - 1;\n\t\t\t\tj++ // discard last path segment, as it's always == the first\n\t\t\t) {\n\t\t\t\ta = i * pathSegmentsP1 + j;\n\t\t\t\tb = a + 1; // a---b is each side of the circle from the current segment\n\t\t\t\tc = (lastClosedSegment ? j : a) + pathSegmentsP1;\n\t\t\t\td = (lastClosedSegment ? j + 1 : b) + pathSegmentsP1; // c---d is each corresponding side from the next segment\n\t\t\t\t//indices.push( a, b, c, b, d, c ); // two tris, CW winding.\n\t\t\t\tif (i === 0) {\n\t\t\t\t\tindices.push(b, d, c); // single triange at caps\n\t\t\t\t} else if (i === totalSegs - 2) {\n\t\t\t\t\tindices.push(a, b, c); // single triange at caps\n\t\t\t\t} else {\n\t\t\t\t\tindices.push(a, b, c, b, d, c); // two tris, CW winding.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { IcosahedronBufferGeometry } from 'three';\nimport { PolyhedronRoundGeometry } from './PolyhedronRoundGeometry';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type IcosahedronGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tdetail: number;\n\tcorner: number;\n\tcornerSides: number;\n};\n\nexport type IcosahedronGeometryInputs = {\n\tparameters: IcosahedronGeometryParameters;\n};\n\nexport const IcosahedronGeometry: CGeometry<IcosahedronGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<IcosahedronGeometryInputs>\n\t): IGeometry<IcosahedronGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<IcosahedronGeometryInputs>,\n\t\tbase?: IcosahedronGeometryInputs\n\t): IcosahedronGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdetail: 0,\n\t\t\t\tcorner: 0,\n\t\t\t\tcornerSides: 4,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: IcosahedronGeometryInputs\n\t): IGeometry<IcosahedronGeometryInputs> {\n\t\tconst { width, height, depth, detail, corner, cornerSides } =\n\t\t\tinputs.parameters;\n\n\t\tconst geometry =\n\t\t\tdetail === 0 && corner !== 0\n\t\t\t\t? new IcosahedronRoundGeometry(width * 0.5, corner, cornerSides)\n\t\t\t\t: new IcosahedronBufferGeometry(width * 0.5, detail);\n\n\t\tgeometry.scale(1, height / width, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'IcosahedronGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nclass IcosahedronRoundGeometry extends PolyhedronRoundGeometry {\n\tconstructor(radius = 1, corner = 0.2, cornerSides = 4) {\n\t\tconst t = (1 + Math.sqrt(5)) / 2;\n\n\t\tconst vertices = [\n\t\t\t-1,\n\t\t\tt,\n\t\t\t0,\n\t\t\t1,\n\t\t\tt,\n\t\t\t0,\n\t\t\t-1,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t1,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t0,\n\t\t\t-1,\n\t\t\tt,\n\t\t\t0,\n\t\t\t1,\n\t\t\tt,\n\t\t\t0,\n\t\t\t-1,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t1,\n\t\t\t-t,\n\t\t\tt,\n\t\t\t0,\n\t\t\t-1,\n\t\t\tt,\n\t\t\t0,\n\t\t\t1,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t-1,\n\t\t\t-t,\n\t\t\t0,\n\t\t\t1,\n\t\t];\n\n\t\tconst indices = [\n\t\t\t0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11,\n\t\t\t10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4,\n\t\t\t9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1,\n\t\t];\n\n\t\tconst type = 'IcosahedronGeometry';\n\n\t\tsuper(vertices, indices, type, radius, corner, cornerSides);\n\n\t\tthis.type = type;\n\n\t\t// this.parameters = {\n\t\t// \tradius: radius,\n\t\t// \tdetail: detail\n\t\t// };\n\t}\n\n\tstatic fromJSON(data: any) {\n\t\treturn new IcosahedronRoundGeometry(\n\t\t\tdata.radius,\n\t\t\tdata.corner,\n\t\t\tdata.cornerSides\n\t\t);\n\t}\n}\n", "/**\n * @author alejandro\n */\n\nimport { LatheBufferGeometry, Shape } from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\ntype Point = {\n\tx: number;\n\ty: number;\n\tid: number;\n};\n\n\nexport type LatheGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tsegments: number;\n\tverticalSegments: number;\n\tpoints: [Point, Point, Point, Point];\n};\n\nexport type LatheGeometryInputs = { parameters: LatheGeometryParameters };\n\nexport const LatheGeometry: CGeometry<LatheGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<LatheGeometryInputs>\n\t): IGeometry<LatheGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<LatheGeometryInputs>,\n\t\tbase?: LatheGeometryInputs\n\t): LatheGeometryInputs {\n\t\t// TOOD remove this conversion\n\t\t(inputs.parameters?.points ?? []).forEach((obj: any) => {\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t(obj as any).x = obj[0];\n\t\t\t\t(obj as any).y = obj[1];\n\t\t\t}\n\t\t});\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tsegments: 64,\n\t\t\t\tverticalSegments: 64,\n\t\t\t\tpoints: [\n\t\t\t\t\t{ x: 0, y: -50, id: 0 },\n\t\t\t\t\t{ x: 50, y: -50, id: 1 },\n\t\t\t\t\t{ x: 50, y: 50, id: 2 },\n\t\t\t\t\t{ x: 0, y: 50, id: 3 },\n\t\t\t\t],\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: LatheGeometryInputs): IGeometry<LatheGeometryInputs> {\n\t\tconst { points, segments, verticalSegments } = inputs.parameters;\n\n\t\tconst shape = new Shape();\n\t\tshape.moveTo(points[0].x, points[0].y);\n\t\tshape.bezierCurveTo(\n\t\t\tpoints[1].x,\n\t\t\tpoints[1].y, //CP1\n\t\t\tpoints[2].x,\n\t\t\tpoints[2].y, //CP2\n\t\t\tpoints[3].x,\n\t\t\tpoints[3].y //Final position\n\t\t);\n\n\t\tconst geometry = new LatheBufferGeometry(\n\t\t\tshape.extractPoints(verticalSegments).shape,\n\t\t\tsegments\n\t\t);\n\n\t\tgeometry.rotateZ(Math.PI);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'LatheGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n */\n\nimport {\n\tBufferGeometry,\n\tBufferGeometryLoader,\n\tVector3,\n\tLoadingManager,\n\tBoxBufferGeometry,\n} from 'three';\nimport { SubdivisionModifier } from '../SubdivisionModifier';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type NonParametricGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tsubdivisions: number;\n};\n\nexport type NonParametricGeometryInputs = {\n\tparameters: NonParametricGeometryParameters;\n\tgeometry?: BufferGeometry;\n};\n\ntype CNonParametricGeometry = CGeometry<NonParametricGeometryInputs> & {\n\tloadFromUrl(url: string, callback: (e: BufferGeometry) => void): void;\n};\n\nexport type NonParametricGeometryOutput = BufferGeometry & {\n\toriginalGeometry?: BufferGeometry;\n};\n\nconst _size = new Vector3();\n\nexport const NonParametricGeometry: CNonParametricGeometry = class {\n\tstatic create(\n\t\tinputs: NestedPartial<NonParametricGeometryInputs>\n\t): IGeometry<NonParametricGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<NonParametricGeometryInputs>,\n\t\tbase?: NonParametricGeometryInputs\n\t): NonParametricGeometryInputs {\n\t\tconst geometry =\n\t\t\tinputs.geometry ??\n\t\t\tbase?.geometry ??\n\t\t\tnew BufferGeometry().copy(new BoxBufferGeometry(100, 100, 100));\n\t\tlet parameters: NonParametricGeometryInputs['parameters'];\n\n\t\tif (base === undefined) {\n\t\t\tgeometry.computeBoundingBox();\n\t\t\tgeometry.boundingBox!.getSize(_size);\n\t\t\tparameters = {\n\t\t\t\twidth: _size.x,\n\t\t\t\theight: _size.y,\n\t\t\t\tdepth: _size.z,\n\t\t\t\tsubdivisions: 0,\n\t\t\t};\n\t\t} else {\n\t\t\tparameters = base.parameters;\n\t\t}\n\n\t\tconst nParams = {\n\t\t\t...parameters,\n\t\t\t...inputs.parameters,\n\t\t};\n\n\t\treturn {\n\t\t\tparameters: {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height),\n\t\t\t\tdepth: Math.abs(nParams.depth),\n\t\t\t\tsubdivisions: Math.abs(nParams.subdivisions),\n\t\t\t},\n\t\t\tgeometry: geometry,\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: NonParametricGeometryInputs\n\t): IGeometry<NonParametricGeometryInputs> {\n\t\tconst { width, height, depth, subdivisions } = inputs.parameters;\n\t\tlet geometry =\n\t\t\tinputs.geometry ??\n\t\t\tnew BufferGeometry().copy(new BoxBufferGeometry(100, 100, 100));\n\t\tconst parameters = geometry.userData\n\t\t\t.parameters as NonParametricGeometryInputs['parameters'];\n\n\t\tif (parameters === undefined) {\n\t\t\tgeometry.computeBoundingBox();\n\t\t\tgeometry.boundingBox!.getSize(_size);\n\t\t} else {\n\t\t\t_size.set(parameters.width, parameters.height, parameters.depth);\n\t\t}\n\n\t\tif (width !== _size.x || height !== _size.y || depth !== _size.z) {\n\t\t\tgeometry.scale(\n\t\t\t\t_size.x === 0 ? 1 : width / _size.x,\n\t\t\t\t_size.y === 0 ? 1 : height / _size.y,\n\t\t\t\t_size.z === 0 ? 1 : depth / _size.z\n\t\t\t);\n\t\t}\n\n\t\tlet originalGeometry = (geometry as NonParametricGeometryOutput)\n\t\t\t.originalGeometry;\n\n\t\tif (subdivisions > 0) {\n\t\t\tif (\n\t\t\t\toriginalGeometry === undefined ||\n\t\t\t\tparameters?.subdivisions !== subdivisions\n\t\t\t) {\n\t\t\t\t// We need to save the original geometry\n\t\t\t\tif (originalGeometry === undefined) {\n\t\t\t\t\toriginalGeometry = geometry;\n\t\t\t\t}\n\t\t\t\tconst modifier = new SubdivisionModifier(subdivisions);\n\t\t\t\tgeometry = modifier.modify(originalGeometry).toBufferGeometry();\n\t\t\t}\n\t\t} else {\n\t\t\t// if it exist revert to use originalGeometry as main geometry\n\t\t\tif (originalGeometry !== undefined) {\n\t\t\t\tgeometry = originalGeometry;\n\t\t\t}\n\t\t\t// no need for original geometry because geometry is the original geometry\n\t\t\toriginalGeometry = undefined;\n\n\t\t\tif (geometry.getAttribute('normal') === undefined) {\n\t\t\t\tgeometry.computeVertexNormals();\n\t\t\t}\n\t\t}\n\n\t\tif (originalGeometry !== undefined) {\n\t\t\tObject.assign(geometry, { originalGeometry });\n\t\t}\n\n\t\t// remove the reference of geometry inside userData to avoid circular structure (geometry.userData.geometry = geometry), this will cause error if we run JSON.stringify(geometry) (TypeError: Converting circular structure to JSON)\n\t\tdelete inputs.geometry;\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'NonParametricGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n\n\tstatic loadFromUrl(\n\t\turl: string,\n\t\tcallback: (e: BufferGeometry) => void,\n\t\tmanager?: LoadingManager\n\t): void {\n\t\tconst loader = new BufferGeometryLoader(manager);\n\t\tloader.load(url, (geometry) => {\n\t\t\tconst inputs = this.normalizeInputs({ geometry });\n\n\t\t\t// optional\n\t\t\tgeometry.boundingBox!.getSize(_size);\n\t\t\tconst aspectRatio = 100 / _size.x;\n\t\t\tObject.assign(inputs.parameters, {\n\t\t\t\twidth: 100,\n\t\t\t\theight: _size.y * aspectRatio,\n\t\t\t\tdepth: _size.z * aspectRatio,\n\t\t\t});\n\n\t\t\tcallback(this.build(inputs));\n\t\t});\n\t}\n};\n", "/**\n *\t@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog\n *\t@author centerionware / http://www.centerionware.com\n *\n *\tSubdivision Geometry Modifier\n *\t\tusing Loop Subdivision Scheme\n *\n *\tReferences:\n *\t\thttp://graphics.stanford.edu/~mdfisher/subdivision.html\n *\t\thttp://www.holmes3d.net/graphics/subdivision/\n *\t\thttp://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf\n *\n *\tKnown Issues:\n *\t\t- currently doesn't handle \"Sharp Edges\"\n */\n\nimport { BufferGeometry, Vector2, Vector3 } from 'three';\nimport { Geometry, Face3 } from 'three/examples/jsm/deprecated/Geometry.js';\n\nconst ABC = ['a', 'b', 'c'];\n\ntype IMetaVertice = {\n\tedges: IEdge[];\n};\n\ntype IEdge = {\n\ta: Vector3;\n\tb: Vector3;\n\tnewEdge: number | null;\n\tfaces: Face3[];\n};\n\n/**\n *\n * @param face -\n * @param key -\n */\nfunction getFaceIndexByString(face: Face3, key: string): number {\n\tswitch (key) {\n\t\tcase 'c':\n\t\t\treturn face.c;\n\t\tcase 'b':\n\t\t\treturn face.b;\n\t\tcase 'a':\n\t\tdefault:\n\t\t\treturn face.a;\n\t}\n}\n\n/**\n *\n * @param a -\n * @param b -\n * @param map -\n */\nfunction getEdge(a: number, b: number, map: Map<string, IEdge>): IEdge {\n\tconst vertexIndexA = Math.min(a, b);\n\tconst vertexIndexB = Math.max(a, b);\n\n\tconst key = vertexIndexA + '_' + vertexIndexB;\n\n\treturn map.get(key) as IEdge;\n}\n\n/**\n *\n * @param a -\n * @param b -\n * @param vertices -\n * @param map -\n * @param face -\n * @param metaVertices -\n */\nfunction processEdge(\n\ta: number,\n\tb: number,\n\tvertices: Vector3[],\n\tmap: Map<string, IEdge>,\n\tface: Face3,\n\tmetaVertices: IMetaVertice[]\n): void {\n\tconst vertexIndexA = Math.min(a, b);\n\tconst vertexIndexB = Math.max(a, b);\n\n\tconst key = vertexIndexA + '_' + vertexIndexB;\n\n\tlet edge: IEdge;\n\n\tif (map.has(key)) {\n\t\tedge = map.get(key) as IEdge;\n\t} else {\n\t\tconst vertexA = vertices[vertexIndexA];\n\t\tconst vertexB = vertices[vertexIndexB];\n\n\t\tedge = {\n\t\t\ta: vertexA, // pointer reference\n\t\t\tb: vertexB,\n\t\t\tnewEdge: null,\n\t\t\t// aIndex: a, // numbered reference\n\t\t\t// bIndex: b,\n\t\t\tfaces: [], // pointers to face\n\t\t};\n\n\t\tmap.set(key, edge);\n\t}\n\n\tedge.faces.push(face);\n\n\tmetaVertices[a].edges.push(edge);\n\tmetaVertices[b].edges.push(edge);\n}\n\n/**\n *\n * @param vertices -\n * @param faces -\n * @param metaVertices -\n * @param edges -\n */\nfunction generateLookups(\n\tvertices: Vector3[],\n\tfaces: Face3[],\n\tmetaVertices: IMetaVertice[],\n\tedges: Map<string, IEdge>\n): void {\n\tlet i, il, face;\n\n\tfor (i = 0, il = vertices.length; i < il; i++) {\n\t\tmetaVertices[i] = { edges: [] };\n\t}\n\n\tfor (i = 0, il = faces.length; i < il; i++) {\n\t\tface = faces[i];\n\n\t\tprocessEdge(face.a, face.b, vertices, edges, face, metaVertices);\n\t\tprocessEdge(face.b, face.c, vertices, edges, face, metaVertices);\n\t\tprocessEdge(face.c, face.a, vertices, edges, face, metaVertices);\n\t}\n}\n\n/**\n *\n * @param newFaces -\n * @param a -\n * @param b -\n * @param c -\n * @param materialIndex -\n */\nfunction newFace(\n\tnewFaces: Face3[],\n\ta: number,\n\tb: number,\n\tc: number,\n\tmaterialIndex: number\n): void {\n\tnewFaces.push(new Face3(a, b, c, undefined, undefined, materialIndex));\n}\n\n/**\n *\n * @param a -\n * @param b -\n */\nfunction midpoint(a: number, b: number) {\n\treturn Math.abs(b - a) / 2 + Math.min(a, b);\n}\n\n/**\n *\n * @param newUvs -\n * @param a -\n * @param b -\n * @param c -\n */\nfunction newUv(newUvs: Vector2[][], a: Vector2, b: Vector2, c: Vector2) {\n\tnewUvs.push([a.clone(), b.clone(), c.clone()]);\n}\n\n/**\n *\n */\nexport class SubdivisionModifier {\n\tconstructor(public subdivisions: number = 1) {}\n\n\t/**\n\t *\n\t * @param geometry -\n\t */\n\tmodify(geometry: Geometry | BufferGeometry): Geometry {\n\t\tif (geometry instanceof BufferGeometry) {\n\t\t\tgeometry = new Geometry().fromBufferGeometry(geometry);\n\t\t} else {\n\t\t\tgeometry = geometry.clone();\n\t\t}\n\n\t\tgeometry.mergeVertices();\n\n\t\tlet repeats = this.subdivisions;\n\n\t\twhile (repeats-- > 0) {\n\t\t\tthis._smooth(geometry);\n\t\t}\n\n\t\tgeometry.computeFaceNormals();\n\t\tgeometry.computeVertexNormals();\n\n\t\treturn geometry;\n\t}\n\n\t/**\n\t *\n\t * @param geometry -\n\t */\n\tprivate _smooth(geometry: Geometry) {\n\t\tconst tmp = new Vector3();\n\n\t\tlet n, i, il, j, k;\n\n\t\tconst oldVertices = geometry.vertices; // { x, y, z}\n\t\tconst oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }\n\t\tconst oldUvs = geometry.faceVertexUvs[0];\n\n\t\tconst hasUvs = oldUvs !== undefined && oldUvs.length > 0;\n\n\t\t/******************************************************\n\t\t *\n\t\t * Step 0: Preprocess Geometry to Generate edges Lookup\n\t\t *\n\t\t *******************************************************/\n\t\tconst metaVertices: IMetaVertice[] = [];\n\t\tconst sourceEdges = new Map<string, IEdge>();\n\t\t// const sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[] }\n\n\t\tgenerateLookups(oldVertices, oldFaces, metaVertices, sourceEdges);\n\n\t\t/******************************************************\n\t\t *\n\t\t *\tStep 1.\n\t\t *\tFor each edge, create a new Edge Vertex,\n\t\t *\tthen position it.\n\t\t *\n\t\t *******************************************************/\n\t\tconst newEdgeVertices = [];\n\t\tlet other, currentEdge, newEdge, face;\n\t\tlet edgeVertexWeight, adjacentVertexWeight, connectedFaces;\n\n\t\tfor (const key of Array.from(sourceEdges.keys())) {\n\t\t\tcurrentEdge = sourceEdges.get(key) as IEdge;\n\n\t\t\tnewEdge = new Vector3();\n\n\t\t\tedgeVertexWeight = 3 / 8;\n\t\t\tadjacentVertexWeight = 1 / 8;\n\n\t\t\tconnectedFaces = currentEdge.faces.length;\n\n\t\t\t// check how many linked faces. 2 should be correct.\n\t\t\tif (connectedFaces != 2) {\n\t\t\t\t// if length is not 2, handle condition\n\t\t\t\tedgeVertexWeight = 0.5;\n\t\t\t\tadjacentVertexWeight = 0;\n\n\t\t\t\tif (connectedFaces != 1) {\n\t\t\t\t\t// console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnewEdge\n\t\t\t\t.addVectors(currentEdge.a, currentEdge.b)\n\t\t\t\t.multiplyScalar(edgeVertexWeight);\n\n\t\t\ttmp.set(0, 0, 0);\n\n\t\t\tfor (j = 0; j < connectedFaces; j++) {\n\t\t\t\tface = currentEdge.faces[j];\n\n\t\t\t\tfor (k = 0; k < 3; k++) {\n\t\t\t\t\tother = oldVertices[getFaceIndexByString(face, ABC[k])];\n\t\t\t\t\tif (other !== currentEdge.a && other !== currentEdge.b) break;\n\t\t\t\t}\n\n\t\t\t\tif (other) tmp.add(other);\n\t\t\t}\n\n\t\t\ttmp.multiplyScalar(adjacentVertexWeight);\n\t\t\tnewEdge.add(tmp);\n\n\t\t\tcurrentEdge.newEdge = newEdgeVertices.length;\n\t\t\tnewEdgeVertices.push(newEdge);\n\n\t\t\t// console.log(currentEdge, newEdge);\n\t\t}\n\n\t\t/******************************************************\n\t\t *\n\t\t *\tStep 2.\n\t\t *\tReposition each source vertices.\n\t\t *\n\t\t *******************************************************/\n\t\tlet beta, sourceVertexWeight, connectingVertexWeight;\n\t\tlet connectingEdge, connectingEdges, oldVertex, newSourceVertex;\n\t\tconst newSourceVertices = [];\n\n\t\tfor (i = 0, il = oldVertices.length; i < il; i++) {\n\t\t\toldVertex = oldVertices[i];\n\n\t\t\t// find all connecting edges (using lookupTable)\n\t\t\tconnectingEdges = metaVertices[i].edges;\n\t\t\tn = connectingEdges.length;\n\n\t\t\tif (n == 3) {\n\t\t\t\tbeta = 3 / 16;\n\t\t\t} else if (n > 3) {\n\t\t\t\tbeta = 3 / (8 * n); // Warren's modified formula\n\t\t\t}\n\n\t\t\t// Loop's original beta formula\n\t\t\t// beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );\n\n\t\t\tsourceVertexWeight = 1 - n * Number(beta);\n\t\t\tconnectingVertexWeight = beta;\n\n\t\t\tif (n <= 2) {\n\t\t\t\t// crease and boundary rules\n\t\t\t\t// console.warn('crease and boundary rules');\n\n\t\t\t\tif (n == 2) {\n\t\t\t\t\t// console.warn( '2 connecting edges', connectingEdges );\n\t\t\t\t\tsourceVertexWeight = 3 / 4;\n\t\t\t\t\tconnectingVertexWeight = 1 / 8;\n\n\t\t\t\t\t// sourceVertexWeight = 1;\n\t\t\t\t\t// connectingVertexWeight = 0;\n\t\t\t\t} else if (n == 1) {\n\t\t\t\t\t// console.warn( 'only 1 connecting edge' );\n\t\t\t\t} else if (n == 0) {\n\t\t\t\t\t// console.warn( '0 connecting edges' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnewSourceVertex = oldVertex.clone().multiplyScalar(sourceVertexWeight);\n\n\t\t\ttmp.set(0, 0, 0);\n\n\t\t\tfor (j = 0; j < n; j++) {\n\t\t\t\tconnectingEdge = connectingEdges[j];\n\t\t\t\tother =\n\t\t\t\t\tconnectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b;\n\t\t\t\ttmp.add(other);\n\t\t\t}\n\n\t\t\ttmp.multiplyScalar(Number(connectingVertexWeight));\n\t\t\tnewSourceVertex.add(tmp);\n\n\t\t\tnewSourceVertices.push(newSourceVertex);\n\t\t}\n\n\t\t/******************************************************\n\t\t *\n\t\t *\tStep 3.\n\t\t *\tGenerate Faces between source vertices\n\t\t *\tand edge vertices.\n\t\t *\n\t\t *******************************************************/\n\t\tconst newVertices = newSourceVertices.concat(newEdgeVertices);\n\t\tconst sl = newSourceVertices.length;\n\t\tlet edge1, edge2, edge3;\n\t\tconst newFaces: Face3[] = [];\n\t\tconst newUVs: Vector2[][] = [];\n\n\t\tlet uv, x0, x1, x2;\n\t\tconst x3 = new Vector2();\n\t\tconst x4 = new Vector2();\n\t\tconst x5 = new Vector2();\n\n\t\tfor (i = 0, il = oldFaces.length; i < il; i++) {\n\t\t\tface = oldFaces[i];\n\n\t\t\t// find the 3 new edges vertex of each old face\n\n\t\t\tedge1 = Number(getEdge(face.a, face.b, sourceEdges).newEdge) + sl;\n\t\t\tedge2 = Number(getEdge(face.b, face.c, sourceEdges).newEdge) + sl;\n\t\t\tedge3 = Number(getEdge(face.c, face.a, sourceEdges).newEdge) + sl;\n\n\t\t\t// create 4 faces.\n\n\t\t\tnewFace(newFaces, edge1, edge2, edge3, face.materialIndex);\n\t\t\tnewFace(newFaces, face.a, edge1, edge3, face.materialIndex);\n\t\t\tnewFace(newFaces, face.b, edge2, edge1, face.materialIndex);\n\t\t\tnewFace(newFaces, face.c, edge3, edge2, face.materialIndex);\n\n\t\t\t// create 4 new uv's\n\n\t\t\tif (hasUvs) {\n\t\t\t\tuv = oldUvs[i];\n\n\t\t\t\tx0 = uv[0];\n\t\t\t\tx1 = uv[1];\n\t\t\t\tx2 = uv[2];\n\n\t\t\t\tx3.set(midpoint(x0.x, x1.x), midpoint(x0.y, x1.y));\n\t\t\t\tx4.set(midpoint(x1.x, x2.x), midpoint(x1.y, x2.y));\n\t\t\t\tx5.set(midpoint(x0.x, x2.x), midpoint(x0.y, x2.y));\n\n\t\t\t\tnewUv(newUVs, x3, x4, x5);\n\t\t\t\tnewUv(newUVs, x0, x3, x5);\n\n\t\t\t\tnewUv(newUVs, x1, x4, x3);\n\t\t\t\tnewUv(newUVs, x2, x5, x4);\n\t\t\t}\n\t\t}\n\n\t\t// Overwrite old arrays\n\t\tgeometry.vertices = newVertices;\n\t\tgeometry.faces = newFaces;\n\t\tif (hasUvs) geometry.faceVertexUvs[0] = newUVs;\n\n\t\t// console.log('done');\n\t}\n}\n", "/**\n * @author nisa\n * @author guillaume\n */\n\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { VectorShape } from '../objects/entities/vectors/VectorShape';\nimport { VectorGeometry } from './vectors/VectorGeometry';\n\nexport type PolygonGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tspikes: number;\n\tcornerRadius: number;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tsurfaceMaxCount: number;\n};\n\nexport type PolygonGeometryInputs = {\n\tparameters: PolygonGeometryParameters;\n\tshape: VectorShape;\n};\n\nexport const PolygonGeometry: CGeometry<PolygonGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<PolygonGeometryInputs>\n\t): IGeometry<PolygonGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<PolygonGeometryInputs>,\n\t\tbase?: PolygonGeometryInputs\n\t): PolygonGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\tspikes: 5,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 3,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\t// Can be passed from inputs when restoring from VectorObject\n\t\tconst shape =\n\t\t\tinputs.shape && inputs.shape instanceof VectorShape\n\t\t\t\t? inputs.shape\n\t\t\t\t: new VectorShape();\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\tsurfaceMaxCount:\n\t\t\t\t\tnParams.surfaceMaxCount ?? nParams.cornerRadius > 0 ? 1000 : 100,\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(\n\t\t\t\t\tnParams.depth !== undefined &&\n\t\t\t\t\t\tnParams.depth === 0 &&\n\t\t\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t\t\t: nParams.depth ?? 0\n\t\t\t\t),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: PolygonGeometryInputs\n\t): IGeometry<PolygonGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tspikes,\n\t\t\tcornerRadius,\n\t\t\tdepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\t\tconst shape = inputs.shape;\n\n\t\tconst outerRadiusX = width * 0.5;\n\t\tconst outerRadiusY = height * 0.5;\n\t\tconst cx = 0;\n\t\tconst cy = 0;\n\t\tconst step = (2 * Math.PI) / spikes;\n\n\t\tfor (let i = 0; i < spikes; i++) {\n\t\t\tconst angle = step * i;\n\t\t\tconst x = cx + Math.sin(angle) * outerRadiusX;\n\t\t\tconst y = cy + Math.cos(angle) * outerRadiusY;\n\t\t\tshape.addPoint(shape.createPoint(x, y));\n\t\t}\n\n\t\tshape.isClosed = true;\n\n\t\tfor (let i = 0, l = shape.points.length; i < l; i++) {\n\t\t\tshape.points[i].roundness = cornerRadius;\n\t\t}\n\n\t\tshape.roundness = cornerRadius;\n\t\tshape.update();\n\n\t\tconst geometry = VectorGeometry.create({\n\t\t\tshape,\n\t\t\tparameters: {\n\t\t\t\tsurfaceMaxCount,\n\t\t\t\troundness: cornerRadius,\n\t\t\t\tdepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\textrudeBevelSegments,\n\t\t\t},\n\t\t});\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'PolygonGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author s-ol\n */\n\nimport {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tVector2,\n\tVector3,\n} from 'three';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type PyramidGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tradialSegments: number;\n\theightSegments: number;\n\topenEnded: boolean;\n\tcornerRadius: number;\n\tcornerSegments: number;\n};\n\nexport type PyramidGeometryInputs = { parameters: PyramidGeometryParameters };\n\nexport const PyramidGeometry: CGeometry<PyramidGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<PyramidGeometryInputs>\n\t): IGeometry<PyramidGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<PyramidGeometryInputs>,\n\t\tbase?: PyramidGeometryInputs\n\t): PyramidGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tradialSegments: 4,\n\t\t\t\theightSegments: 1,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\tcornerSegments: 8,\n\t\t\t\topenEnded: false,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: PyramidGeometryInputs\n\t): IGeometry<PyramidGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\tradialSegments,\n\t\t\theightSegments,\n\t\t\topenEnded,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments,\n\t\t} = inputs.parameters;\n\n\t\tconst geometry = new RoundedPyramidBufferGeometry(\n\t\t\twidth * 0.5,\n\t\t\theight,\n\t\t\tradialSegments,\n\t\t\theightSegments,\n\t\t\topenEnded,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments\n\t\t);\n\n\t\tgeometry.scale(1, 1, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'PyramidGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\n// take a 2d vector from side view and a unit vector from the top view\n// and output the profile vector turned to the top vector into the 3d vector out\nfunction two2three(profile: Vector2, top: Vector2, out: Vector3) {\n\tout.x = profile.x * top.x;\n\tout.y = profile.y;\n\tout.z = profile.x * top.y;\n}\n\n// inset/offset point by distA from the edge to edgeEndA and distB from the edge to edgeEndB.\n// store result in out\n/**\n * inset/offset a point on a face.\n *\n * ```\n * P\n * / O \\\n * dB/ / \\ \\dA\n * / / \\ \\\n * A B\n * ```\n * @param point - the point to be offset\n * @param edgeEndA - the preceding vertex in the face\n * @param edgeEndB - the follwowing vertex in the face\n * @param distA - the amount by which the edge (PA) should be inset\n * @param distB - the amount by which the edge (PB) should be inset\n * @param out - where to store the result\n */\nfunction offset3d(\n\tpoint: Vector3,\n\tedgeEndA: Vector3,\n\tedgeEndB: Vector3,\n\tdistA: number,\n\tdistB: number,\n\tout: Vector3\n) {\n\tconst deltaA = edgeEndA.clone().sub(point);\n\tconst deltaB = edgeEndB.clone().sub(point);\n\tconst angle = deltaA.angleTo(deltaB);\n\tdeltaA.normalize();\n\tdeltaB.normalize();\n\n\tif (distA === distB) {\n\t\tconst bisector = deltaA.add(deltaB).normalize();\n\t\tout.copy(point).addScaledVector(bisector, distA / Math.sin(angle / 2));\n\t} else {\n\t\tconst angle = deltaA.angleTo(deltaB);\n\n\t\tout.copy(point);\n\t\tout.addScaledVector(deltaA, distB / Math.sin(angle));\n\t\tout.addScaledVector(deltaB, distA / Math.sin(angle));\n\t}\n}\n\n/**\n * Find closest point on (infinite) line\n * @param point - point to project\n * @param lA - point A on the infinite line\n * @param lB - point B on the infinite line\n * @returns the closest point on the line (AB)\n */\nfunction projectOntoLine(point: Vector3, lA: Vector3, lB: Vector3): Vector3 {\n\tconst deltaPoint = point.clone().sub(lA);\n\tconst deltaLine = lB.clone().sub(lA);\n\n\tdeltaPoint.projectOnVector(deltaLine);\n\treturn deltaPoint.add(lA);\n}\n\nclass RoundedPyramidBufferGeometry extends BufferGeometry {\n\tconstructor(\n\t\tradius = 0.5,\n\t\theight = 1,\n\t\tradialSegments = 4,\n\t\t_heightSegments = 1,\n\t\topenEnded = false,\n\t\tcornerRadius = 0,\n\t\tcornerSegments = 4\n\t) {\n\t\tsuper();\n\n\t\t// segments\n\n\t\tradialSegments = Math.floor(Math.max(3, radialSegments));\n\t\t// @TODO: implement height segments\n\t\t_heightSegments = Math.floor(_heightSegments);\n\t\tcornerSegments = Math.floor(cornerSegments);\n\n\t\t// buffers\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\t// helper variables\n\n\t\tlet index = 0;\n\n\t\tconst halfHeight = height / 2;\n\n\t\tconst startAngle = Math.PI / radialSegments;\n\n\t\tconst innerRadius = radius * Math.cos(Math.PI / radialSegments);\n\t\tconst centerAngle = (2 * Math.PI) / radialSegments;\n\t\tconst innerAngle = ((radialSegments - 2) * Math.PI) / radialSegments;\n\t\tconst outerAngle = Math.PI - innerAngle;\n\n\t\tconst bottomCenter = new Vector3(0, -halfHeight, 0);\n\t\tconst topCenter = new Vector3(0, halfHeight, 0);\n\t\tconst bottomOuter = new Vector2(radius, -halfHeight);\n\t\tconst bottomInner = new Vector2(innerRadius, -halfHeight);\n\n\t\tconst deltaFace = new Vector2(0, topCenter.y).sub(bottomInner);\n\t\tconst deltaEdge = new Vector2(0, topCenter.y).sub(bottomOuter);\n\t\tconst normalFace2d = new Vector2(deltaFace.y, -deltaFace.x).normalize();\n\t\tconst normalEdge2d = new Vector2(deltaEdge.y, -deltaEdge.x).normalize();\n\n\t\tconst cornerPullBottomMax = radius * Math.cos(Math.PI / radialSegments);\n\t\tconst cornerRadiusMax =\n\t\t\tcornerPullBottomMax * Math.tan((Math.PI - deltaFace.angle()) / 2) - 1e-8;\n\t\tcornerRadius = Math.min(cornerRadius, cornerRadiusMax);\n\n\t\tlet innerAngleSide;\n\t\t{\n\t\t\tconst normal = new Vector3(normalFace2d.x, normalFace2d.y, 0);\n\t\t\tconst nextNormal = new Vector3(\n\t\t\t\tMath.cos(centerAngle) * normal.x,\n\t\t\t\tnormal.y,\n\t\t\t\tMath.sin(centerAngle) * normal.x\n\t\t\t);\n\t\t\tinnerAngleSide = normal.angleTo(nextNormal);\n\t\t}\n\n\t\tconst cornerPullBottom =\n\t\t\tcornerRadius / Math.tan((Math.PI - deltaFace.angle()) / 2);\n\t\tconst cornerPullSide =\n\t\t\tcornerRadius / Math.tan((Math.PI - innerAngleSide) / 2);\n\n\t\tconst vector = new Vector3();\n\n\t\tif (!openEnded) {\n\t\t\t// bottom polygon fan\n\n\t\t\tvertices.push(bottomCenter.x, bottomCenter.y, bottomCenter.z);\n\t\t\tnormals.push(0, -1, 0);\n\t\t\tuvs.push(0, 0);\n\t\t\tconst center = index++;\n\n\t\t\tconst loop = [];\n\n\t\t\tconst bottomOutCornered = bottomOuter.clone();\n\t\t\tconst rad = cornerPullBottom / Math.cos(Math.PI / radialSegments);\n\t\t\tbottomOutCornered.x -= rad;\n\n\t\t\tfor (let i = 0; i < radialSegments; i++) {\n\t\t\t\tconst ia = (i / radialSegments) * Math.PI * 2 + startAngle;\n\t\t\t\tconst top = new Vector2(Math.sin(ia), Math.cos(ia));\n\n\t\t\t\t// vertex\n\n\t\t\t\ttwo2three(bottomOutCornered, top, vector);\n\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t// normals\n\n\t\t\t\tnormals.push(0, -1, 0);\n\n\t\t\t\t// uvs\n\n\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t// counter\n\n\t\t\t\tloop.push(index++);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < loop.length; i++) {\n\t\t\t\tindices.push(loop[i], center, loop[(i + 1) % loop.length]);\n\t\t\t}\n\t\t}\n\n\t\tconst topLoop: number[] = [];\n\n\t\t{\n\t\t\t// side faces\n\n\t\t\tconst normal = new Vector3();\n\t\t\tconst start = new Vector3();\n\t\t\tconst stop = new Vector3();\n\t\t\tconst top2 = new Vector3();\n\t\t\tconst start2 = new Vector3();\n\t\t\tconst stop2 = new Vector3();\n\n\t\t\tfor (let i = 0; i < radialSegments; i++) {\n\t\t\t\tconst iaStart = (i / radialSegments) * Math.PI * 2 + startAngle;\n\t\t\t\tconst iaMid = ((i + 0.5) / radialSegments) * Math.PI * 2 + startAngle;\n\t\t\t\tconst iaStop = ((i + 1) / radialSegments) * Math.PI * 2 + startAngle;\n\n\t\t\t\tconst turnStart = new Vector2(Math.sin(iaStart), Math.cos(iaStart));\n\t\t\t\tconst turnMid = new Vector2(Math.sin(iaMid), Math.cos(iaMid));\n\t\t\t\tconst turnStop = new Vector2(Math.sin(iaStop), Math.cos(iaStop));\n\n\t\t\t\t// find original triangle corners and normal\n\n\t\t\t\ttwo2three(bottomOuter, turnStart, start);\n\t\t\t\ttwo2three(bottomOuter, turnStop, stop);\n\t\t\t\ttwo2three(normalFace2d, turnMid, normal);\n\n\t\t\t\t// offset vertices\n\n\t\t\t\toffset3d(topCenter, start, stop, cornerPullSide, cornerPullSide, top2);\n\t\t\t\tvertices.push(top2.x, top2.y, top2.z);\n\t\t\t\toffset3d(\n\t\t\t\t\tstart,\n\t\t\t\t\ttopCenter,\n\t\t\t\t\tstop,\n\t\t\t\t\tcornerPullSide,\n\t\t\t\t\tcornerPullBottom,\n\t\t\t\t\tstart2\n\t\t\t\t);\n\t\t\t\tvertices.push(start2.x, start2.y, start2.z);\n\t\t\t\toffset3d(\n\t\t\t\t\tstop,\n\t\t\t\t\tstart,\n\t\t\t\t\ttopCenter,\n\t\t\t\t\tcornerPullBottom,\n\t\t\t\t\tcornerPullSide,\n\t\t\t\t\tstop2\n\t\t\t\t);\n\t\t\t\tvertices.push(stop2.x, stop2.y, stop2.z);\n\n\t\t\t\t// normals\n\n\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t// uvs\n\n\t\t\t\tuvs.push(0, 0);\n\t\t\t\tuvs.push(0, 0);\n\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t// counter\n\n\t\t\t\tconst iTop = index++;\n\t\t\t\tconst iStart = index++;\n\t\t\t\tconst iStop = index++;\n\t\t\t\tindices.push(iTop, iStart, iStop);\n\n\t\t\t\tif (cornerRadius > 0) {\n\t\t\t\t\t{\n\t\t\t\t\t\t// bottom bevel\n\n\t\t\t\t\t\tconst center = start.clone().add(stop).multiplyScalar(0.5);\n\t\t\t\t\t\tconst toTop = topCenter.clone().sub(center).normalize();\n\t\t\t\t\t\tconst toBottom = bottomCenter.clone().sub(center).normalize();\n\t\t\t\t\t\tconst out = toBottom.add(toTop).normalize().multiplyScalar(-1);\n\t\t\t\t\t\tconst across = stop2.clone().sub(start2);\n\n\t\t\t\t\t\tbuildBevel(center, across, out, deltaFace.angle());\n\t\t\t\t\t}\n\n\t\t\t\t\tlet bevelEnd, clampedIndices;\n\n\t\t\t\t\t{\n\t\t\t\t\t\t// side bevel\n\n\t\t\t\t\t\tconst out = new Vector3();\n\t\t\t\t\t\ttwo2three(normalEdge2d, turnStop, out);\n\n\t\t\t\t\t\tlet center = stop2.clone().add(top2).multiplyScalar(0.5);\n\t\t\t\t\t\tcenter = projectOntoLine(center, stop, topCenter);\n\t\t\t\t\t\tconst across = stop2.clone().sub(top2);\n\n\t\t\t\t\t\t[bevelEnd, clampedIndices] = buildBevel(\n\t\t\t\t\t\t\tcenter,\n\t\t\t\t\t\t\tacross,\n\t\t\t\t\t\t\tout,\n\t\t\t\t\t\t\tinnerAngleSide,\n\t\t\t\t\t\t\ttop2.y\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t{\n\t\t\t\t\t\t// side corner\n\n\t\t\t\t\t\tconst center = bevelEnd;\n\n\t\t\t\t\t\tconst u = center.clone().setY(0).normalize(); // outwards from the corner\n\t\t\t\t\t\tconst v = new Vector3(0, -1, 0); // downwards\n\t\t\t\t\t\tconst w = u.clone().cross(v); // cross the last\n\n\t\t\t\t\t\tbuildCorner3(center, u, v, w);\n\t\t\t\t\t}\n\n\t\t\t\t\ttopLoop.concat(clampedIndices);\n\n\t\t\t\t\t{\n\t\t\t\t\t\t// top half-sphere segment\n\n\t\t\t\t\t\tconst angleStart = deltaFace.angle();\n\t\t\t\t\t\tconst angleDelta = Math.PI - angleStart;\n\t\t\t\t\t\tconst center = topCenter.clone();\n\t\t\t\t\t\tcenter.y -= cornerRadius / Math.sin(angleStart - Math.PI / 2);\n\n\t\t\t\t\t\tconst vector = new Vector3();\n\t\t\t\t\t\tconst rows = [];\n\n\t\t\t\t\t\tfor (let segments = 0; segments < cornerSegments; segments++) {\n\t\t\t\t\t\t\tconst row = [];\n\n\t\t\t\t\t\t\tconst anglePitch =\n\t\t\t\t\t\t\t\tMath.PI / 2 - (angleDelta * segments) / cornerSegments;\n\t\t\t\t\t\t\tconst cosPitch = Math.cos(anglePitch);\n\t\t\t\t\t\t\tconst sinPitch = Math.sin(anglePitch);\n\n\t\t\t\t\t\t\tlet angleYaw = iaMid;\n\n\t\t\t\t\t\t\tfor (let j = 0; j <= segments; j++) {\n\t\t\t\t\t\t\t\tconst cosYaw = Math.cos(angleYaw);\n\t\t\t\t\t\t\t\tconst sinYaw = Math.sin(angleYaw);\n\n\t\t\t\t\t\t\t\tnormal.x = cosPitch * sinYaw;\n\t\t\t\t\t\t\t\tnormal.y = sinPitch;\n\t\t\t\t\t\t\t\tnormal.z = cosPitch * cosYaw;\n\t\t\t\t\t\t\t\tvector.copy(center).addScaledVector(normal, cornerRadius);\n\n\t\t\t\t\t\t\t\t// vertex\n\n\t\t\t\t\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\t\t\t\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\t\t\t\t\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t\t\t\t\t// index\n\n\t\t\t\t\t\t\t\trow.push(index++);\n\n\t\t\t\t\t\t\t\tangleYaw += (Math.PI * 2) / segments / radialSegments;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\trows.push(row);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tclampedIndices.reverse();\n\t\t\t\t\t\trows.push(clampedIndices);\n\n\t\t\t\t\t\tconst R = rows.length - 1;\n\n\t\t\t\t\t\tfor (let r = 0; r < R; r++) {\n\t\t\t\t\t\t\t// rows: cur/next\n\t\t\t\t\t\t\tconst rC = rows[r];\n\t\t\t\t\t\t\tconst rN = rows[r + 1];\n\n\t\t\t\t\t\t\tconst I = rC.length - 1;\n\n\t\t\t\t\t\t\t// first tri\n\t\t\t\t\t\t\tindices.push(rN[1], rC[0], rN[0]);\n\n\t\t\t\t\t\t\tfor (let i = 1; i <= I; i++) {\n\t\t\t\t\t\t\t\t// tri to previous\n\t\t\t\t\t\t\t\tindices.push(rC[i], rC[i - 1], rN[i]);\n\n\t\t\t\t\t\t\t\t// tri to next\n\t\t\t\t\t\t\t\tindices.push(rN[i + 1], rC[i], rN[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// build geometry\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t\t/**\n\t\t * bevel an edge between the two points at center \u00B1 across.\n\t\t *\n\t\t * the centerline of the bevel-cylinder is recessed by cornerRadius in the\n\t\t * direction of -out.\n\t\t * angleDelta is the total angle between the two faces adjacent to the edge.\n\t\t *\n\t\t * clampYMax is an optional absolute Y value defining a plane above which to\n\t\t * clamp all vertices. This is a inputscial feature only used for the top of\n\t\t * the pyramid.\n\t\t *\n\t\t * @param center - center position of the edge to be beveled\n\t\t * @param across - vector from start to end of edge to be bevelled\n\t\t * @param out - unit vector pointing \"out\" from the edge to be bevelled\n\t\t * @param angleDelta - bevel angle (between the two faces meeting at the edge)\n\t\t * @param clampYMax - optional max Y coordinate at which to clamp the edge\n\t\t */\n\t\tfunction buildBevel(\n\t\t\tcenter: Vector3,\n\t\t\tacross: Vector3,\n\t\t\tout: Vector3,\n\t\t\tangleDelta: number,\n\t\t\tclampYMax?: number\n\t\t): [Vector3, number[]] {\n\t\t\tconst angleStart = -angleDelta / 2;\n\t\t\tconst ainputsctAngle2 = (Math.PI - angleDelta) / 2;\n\n\t\t\tconst up = across.clone().normalize().cross(out);\n\t\t\tcenter.addScaledVector(out, -cornerRadius / Math.sin(ainputsctAngle2));\n\n\t\t\tconst vector = new Vector3();\n\t\t\tconst normal = new Vector3();\n\n\t\t\tconst acrossSegments = 1;\n\t\t\tconst startIndex = index;\n\t\t\tconst clampedVerts = [];\n\n\t\t\tfor (let ia = 0; ia <= cornerSegments; ia++) {\n\t\t\t\tconst a = angleStart + (ia / cornerSegments) * angleDelta;\n\n\t\t\t\tnormal.set(0, 0, 0);\n\t\t\t\tnormal.addScaledVector(up, Math.sin(a));\n\t\t\t\tnormal.addScaledVector(out, Math.cos(a));\n\n\t\t\t\tfor (let is = 0; is <= acrossSegments; is++) {\n\t\t\t\t\tconst i = is / acrossSegments - 0.5;\n\n\t\t\t\t\tvector.copy(center);\n\t\t\t\t\tvector.addScaledVector(across, i);\n\t\t\t\t\tvector.addScaledVector(normal, cornerRadius);\n\n\t\t\t\t\tif (clampYMax != null) {\n\t\t\t\t\t\tconst clampAmt = Math.max(0, vector.y - clampYMax);\n\t\t\t\t\t\tvector.addScaledVector(across, -clampAmt / across.y);\n\t\t\t\t\t}\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t\t// counters\n\n\t\t\t\t\tif (is === 0) clampedVerts.push(index);\n\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let ia = 0; ia < cornerSegments; ia++) {\n\t\t\t\tfor (let is = 0; is < acrossSegments; is++) {\n\t\t\t\t\tconst a = startIndex + is + (acrossSegments + 1) * ia;\n\t\t\t\t\tconst b = a + (acrossSegments + 1);\n\t\t\t\t\tconst c = b + 1;\n\t\t\t\t\tconst d = a + 1;\n\n\t\t\t\t\t// faces\n\n\t\t\t\t\tindices.push(a, b, d);\n\t\t\t\t\tindices.push(b, c, d);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn [center.clone().addScaledVector(across, 0.5), clampedVerts];\n\t\t}\n\n\t\tfunction buildCorner3(center: Vector3, u: Vector3, v: Vector3, w: Vector3) {\n\t\t\tconst pi2 = Math.PI / 2;\n\t\t\tconst targetPitch = deltaEdge.angle() - pi2;\n\t\t\tconst rows = [];\n\n\t\t\tconst normal = new Vector3();\n\t\t\tconst vector = new Vector3();\n\n\t\t\tfor (let segments = 0; segments <= cornerSegments; segments++) {\n\t\t\t\t// close corner up to the lower two bevels\n\n\t\t\t\tconst row = [];\n\n\t\t\t\tconst ss = segments / cornerSegments;\n\n\t\t\t\tfor (let j = 0; j <= segments; j++) {\n\t\t\t\t\tconst jj = segments ? j / segments : 0;\n\n\t\t\t\t\tconst angleYaw = (jj - 0.5) * outerAngle;\n\t\t\t\t\tconst cosYaw = Math.cos(angleYaw);\n\t\t\t\t\tconst sinYaw = Math.sin(angleYaw);\n\n\t\t\t\t\tconst maxPitch = Math.atan(Math.tan(targetPitch) * cosYaw);\n\t\t\t\t\tconst anglePitch = (pi2 + maxPitch) * ss;\n\n\t\t\t\t\tconst cosPitch = Math.cos(anglePitch);\n\t\t\t\t\tconst sinPitch = Math.sin(anglePitch);\n\n\t\t\t\t\t// vertex\n\n\t\t\t\t\tnormal.set(0, 0, 0);\n\t\t\t\t\tnormal.addScaledVector(u, sinPitch * cosYaw);\n\t\t\t\t\tnormal.addScaledVector(v, cosPitch);\n\t\t\t\t\tnormal.addScaledVector(w, sinPitch * sinYaw);\n\n\t\t\t\t\tvector.copy(center).addScaledVector(normal, cornerRadius);\n\t\t\t\t\tvertices.push(vector.x, vector.y, vector.z);\n\n\t\t\t\t\t// normals\n\n\t\t\t\t\tnormals.push(normal.x, normal.y, normal.z);\n\n\t\t\t\t\t// uvs\n\n\t\t\t\t\tuvs.push(0, 0);\n\n\t\t\t\t\t// index\n\n\t\t\t\t\trow.push(index++);\n\t\t\t\t}\n\n\t\t\t\trows.push(row);\n\t\t\t}\n\n\t\t\tconst R = rows.length - 1;\n\n\t\t\tfor (let r = 0; r < R; r++) {\n\t\t\t\t// rows: cur/next\n\t\t\t\tconst rC = rows[r];\n\t\t\t\tconst rN = rows[r + 1];\n\n\t\t\t\tconst I = rC.length - 1;\n\n\t\t\t\t// first tri\n\t\t\t\tindices.push(rC[0], rN[1], rN[0]);\n\n\t\t\t\tfor (let i = 1; i <= I; i++) {\n\t\t\t\t\t// tri to previous\n\t\t\t\t\tindices.push(rC[i - 1], rC[i], rN[i]);\n\n\t\t\t\t\t// tri to next\n\t\t\t\t\tindices.push(rC[i], rN[i + 1], rN[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @author nisa\n * @author alejandro\n * @author guillaume\n */\n\nimport { VectorShape } from '../objects/entities/vectors/VectorShape';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { VectorGeometry } from './vectors/VectorGeometry';\n\nexport type RectangleGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tcornerRadius: [number, number, number, number];\n\tcornerType: number;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tsurfaceMaxCount: number;\n};\n\ntype UI = {\n\tenabledIndieCorners: boolean;\n};\n\nexport type RectangleGeometryInputs = {\n\tparameters: RectangleGeometryParameters;\n\tui: UI;\n\tshape: VectorShape;\n};\n\nexport const RectangleGeometry: CGeometry<RectangleGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<RectangleGeometryInputs>\n\t): IGeometry<RectangleGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<RectangleGeometryInputs>,\n\t\tbase?: RectangleGeometryInputs\n\t): RectangleGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\tcornerRadius: [0, 0, 0, 0],\n\t\t\t\tcornerType: 1,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\tconst nUI: UI = Object.assign(\n\t\t\tbase?.ui ?? {\n\t\t\t\tenabledIndieCorners: false,\n\t\t\t},\n\t\t\tinputs.ui\n\t\t);\n\n\t\tconst cornerSum = nParams.cornerRadius.reduce((a, b) => a + b, 0);\n\n\t\t// Can be passed from inputs when restoring from VectorObject\n\t\tconst shape =\n\t\t\tinputs.shape && inputs.shape instanceof VectorShape\n\t\t\t\t? inputs.shape\n\t\t\t\t: new VectorShape();\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\tsurfaceMaxCount: nParams.surfaceMaxCount ?? cornerSum > 0 ? 1000 : 100,\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(\n\t\t\t\t\tnParams.depth !== undefined &&\n\t\t\t\t\t\tnParams.depth === 0 &&\n\t\t\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t\t\t: nParams.depth ?? 0\n\t\t\t\t),\n\t\t\t}),\n\t\t\tui: nUI,\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: RectangleGeometryInputs\n\t): IGeometry<RectangleGeometryInputs> {\n\t\tconst shape = inputs.shape;\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tcornerRadius,\n\t\t\tcornerType,\n\t\t\tdepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\n\t\tconst r = { x: width * 0.5, y: height * 0.5 };\n\t\tconst min = { x: -r.x, y: -r.y };\n\t\tconst max = { x: r.x, y: r.y };\n\n\t\tfunction scaleRadius(r: number, a: number, b: number): number {\n\t\t\tif (a > width && b > height) {\n\t\t\t\treturn Math.min((r * width) / a, (r * height) / b);\n\t\t\t} else if (a > width) {\n\t\t\t\treturn (r * width) / a;\n\t\t\t} else if (b > height) {\n\t\t\t\treturn (r * height) / b;\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\n\t\tconst scaledRadius = [];\n\t\tscaledRadius[0] =\n\t\t\tcornerRadius[0] === 0\n\t\t\t\t? 0\n\t\t\t\t: scaleRadius(\n\t\t\t\t\t\tcornerRadius[0],\n\t\t\t\t\t\tcornerRadius[0] + cornerRadius[3],\n\t\t\t\t\t\tcornerRadius[0] + cornerRadius[1]\n\t\t\t\t );\n\t\tscaledRadius[1] =\n\t\t\tcornerRadius[1] === 0\n\t\t\t\t? 0\n\t\t\t\t: scaleRadius(\n\t\t\t\t\t\tcornerRadius[1],\n\t\t\t\t\t\tcornerRadius[1] + cornerRadius[2],\n\t\t\t\t\t\tcornerRadius[1] + cornerRadius[0]\n\t\t\t\t );\n\t\tscaledRadius[2] =\n\t\t\tcornerRadius[2] === 0\n\t\t\t\t? 0\n\t\t\t\t: scaleRadius(\n\t\t\t\t\t\tcornerRadius[2],\n\t\t\t\t\t\tcornerRadius[2] + cornerRadius[1],\n\t\t\t\t\t\tcornerRadius[2] + cornerRadius[3]\n\t\t\t\t );\n\t\tscaledRadius[3] =\n\t\t\tcornerRadius[3] === 0\n\t\t\t\t? 0\n\t\t\t\t: scaleRadius(\n\t\t\t\t\t\tcornerRadius[3],\n\t\t\t\t\t\tcornerRadius[3] + cornerRadius[0],\n\t\t\t\t\t\tcornerRadius[3] + cornerRadius[2]\n\t\t\t\t );\n\n\t\tconst left = min.x;\n\t\tconst right = max.x;\n\t\tconst top = max.y;\n\t\tconst bottom = min.y;\n\n\t\tshape.addPoint(shape.createPoint(left, top));\n\t\tshape.addPoint(shape.createPoint(right, top));\n\t\tshape.addPoint(shape.createPoint(right, bottom));\n\t\tshape.addPoint(shape.createPoint(left, bottom));\n\n\t\tshape.isClosed = true;\n\n\t\tlet uniformCornerRadius = true;\n\t\tfor (let i = 0, l = shape.points.length; i < l; i++) {\n\t\t\tshape.points[i].roundness = scaledRadius[i];\n\t\t\tif (i > 0 && scaledRadius[i] !== scaledRadius[i - 1]) {\n\t\t\t\tuniformCornerRadius = false;\n\t\t\t}\n\t\t}\n\n\t\tif (uniformCornerRadius) {\n\t\t\tshape.roundness = scaledRadius[0];\n\t\t}\n\n\t\tshape.useCubicForRoundedCorners = cornerType !== 1;\n\n\t\tshape.update();\n\n\t\tconst geometry = VectorGeometry.create({\n\t\t\tshape,\n\t\t\tparameters: {\n\t\t\t\tsurfaceMaxCount,\n\t\t\t\tdepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\textrudeBevelSegments,\n\t\t\t},\n\t\t});\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'RectangleGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n */\n\nimport { SphereBufferGeometry } from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type SphereGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\twidthSegments: number;\n\theightSegments: number;\n\tphiStart: number;\n\tphiLength: number;\n\tthetaStart: number;\n\tthetaLength: number;\n};\n\nexport type SphereGeometryInputs = { parameters: SphereGeometryParameters };\n\nexport const SphereGeometry: CGeometry<SphereGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<SphereGeometryInputs>\n\t): IGeometry<SphereGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<SphereGeometryInputs>,\n\t\tbase?: SphereGeometryInputs\n\t): SphereGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\twidthSegments: 64,\n\t\t\t\theightSegments: 64,\n\t\t\t\tphiStart: 0,\n\t\t\t\tphiLength: 2 * Math.PI,\n\t\t\t\tthetaStart: 0,\n\t\t\t\tthetaLength: Math.PI,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: SphereGeometryInputs): IGeometry<SphereGeometryInputs> {\n\t\tconst {\n\t\t\twidth = 100,\n\t\t\theight = width,\n\t\t\tdepth = width,\n\t\t\twidthSegments = 64,\n\t\t\theightSegments = 64,\n\t\t\tphiStart,\n\t\t\tphiLength,\n\t\t\tthetaStart,\n\t\t\tthetaLength,\n\t\t} = inputs.parameters;\n\n\t\tconst geometry = new SphereBufferGeometry(\n\t\t\t0.5 * width,\n\t\t\twidthSegments,\n\t\t\theightSegments,\n\t\t\tphiStart,\n\t\t\tphiLength,\n\t\t\tthetaStart,\n\t\t\tthetaLength\n\t\t);\n\n\t\tgeometry.scale(1, height / width, depth / width);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'SphereGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author ale\n */\n\nimport { PlaneBufferGeometry } from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type PlaneGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\twidthSegments: number;\n\theightSegments: number;\n};\n\nexport type PlaneGeometryInputs = { parameters: PlaneGeometryParameters };\n\nexport const PlaneGeometry: CGeometry<PlaneGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<PlaneGeometryInputs>\n\t): IGeometry<PlaneGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<PlaneGeometryInputs>,\n\t\tbase?: PlaneGeometryInputs\n\t): PlaneGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\twidthSegments: 8,\n\t\t\t\theightSegments: 8,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: 0,\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: PlaneGeometryInputs): IGeometry<PlaneGeometryInputs> {\n\t\tconst {\n\t\t\twidth = 100,\n\t\t\theight = width,\n\t\t\twidthSegments = 8,\n\t\t\theightSegments = 8,\n\t\t} = inputs.parameters;\n\n\t\tconst geometry = new PlaneBufferGeometry(\n\t\t\twidth,\n\t\t\theight,\n\t\t\twidthSegments,\n\t\t\theightSegments\n\t\t);\n\n\t\tgeometry.scale(1, 1, 1);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'PlaneGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n * @author guillaume\n */\n\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { VectorShape } from '../objects/entities/vectors/VectorShape';\nimport { VectorGeometry } from './vectors/VectorGeometry';\n\nexport type StarGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tinnerRadiusPercent: number;\n\tspikes: number;\n\tcornerRadius: number;\n\tangle: 360;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tsurfaceMaxCount: number;\n};\n\nexport type StarGeometryInputs = {\n\tparameters: StarGeometryParameters;\n\tshape: VectorShape;\n};\n\nexport const StarGeometry: CGeometry<StarGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<StarGeometryInputs>\n\t): IGeometry<StarGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<StarGeometryInputs>,\n\t\tbase?: StarGeometryInputs\n\t): StarGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\tinnerRadiusPercent: 38.19,\n\t\t\t\tspikes: 5,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\tangle: 360,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\t// Can be passed from inputs when restoring from VectorObject\n\t\tconst shape =\n\t\t\tinputs.shape && inputs.shape instanceof VectorShape\n\t\t\t\t? inputs.shape\n\t\t\t\t: new VectorShape();\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\tsurfaceMaxCount:\n\t\t\t\t\tnParams.surfaceMaxCount ?? nParams.cornerRadius > 0 ? 1000 : 100,\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(\n\t\t\t\t\tnParams.depth !== undefined &&\n\t\t\t\t\t\tnParams.depth === 0 &&\n\t\t\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t\t\t: nParams.depth ?? 0\n\t\t\t\t),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: StarGeometryInputs): IGeometry<StarGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tinnerRadiusPercent,\n\t\t\tspikes,\n\t\t\tcornerRadius,\n\t\t\tangle,\n\t\t\tdepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\t\tconst shape = inputs.shape;\n\n\t\tconst outerRadiusX = width * 0.5;\n\t\tconst outerRadiusY = height * 0.5;\n\t\tconst cx = 0;\n\t\tconst cy = 0;\n\t\tlet step = (angle * Math.PI) / 360 / spikes;\n\t\tlet rot = (Math.PI / 2) * 3 * -1; // -1 for the fisrt spike look at up\n\t\tconst innerRadiusX = (outerRadiusX * innerRadiusPercent) / 100;\n\t\tconst innerRadiusY = (outerRadiusY * innerRadiusPercent) / 100;\n\n\t\tif (spikes == 3 && innerRadiusPercent == 50) {\n\t\t\t// Alejandro: This is to fix the issue went using 3 spikes ant 50% inner\n\t\t\t// Shape is a triangle here\n\t\t\tstep = (2 * Math.PI) / spikes; // PI = 180\u00BA\n\t\t\tfor (let i = 0; i < spikes; i++) {\n\t\t\t\tconst angle = step * i;\n\t\t\t\tconst x = cx + Math.sin(angle) * outerRadiusX;\n\t\t\t\tconst y = cy + Math.cos(angle) * outerRadiusY;\n\t\t\t\tshape.addPoint(shape.createPoint(x, y));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (let i = 0; i < spikes; i++) {\n\t\t\t\tlet x = cx + Math.cos(rot) * outerRadiusX;\n\t\t\t\tlet y = cy + Math.sin(rot) * outerRadiusY;\n\n\t\t\t\tshape.addPoint(shape.createPoint(x, y));\n\n\t\t\t\trot += step;\n\n\t\t\t\tx = cx + Math.cos(rot) * innerRadiusX;\n\t\t\t\ty = cy + Math.sin(rot) * innerRadiusY;\n\t\t\t\tif (i <= spikes) {\n\t\t\t\t}\n\t\t\t\tshape.addPoint(shape.createPoint(x, y));\n\t\t\t\trot += step;\n\t\t\t}\n\t\t}\n\n\t\tshape.isClosed = true;\n\n\t\tfor (let i = 0, l = shape.points.length; i < l; i++) {\n\t\t\tshape.points[i].roundness = cornerRadius;\n\t\t}\n\n\t\tshape.roundness = cornerRadius;\n\t\tshape.update();\n\n\t\tconst geometry = VectorGeometry.create({\n\t\t\tshape,\n\t\t\tparameters: {\n\t\t\t\tsurfaceMaxCount,\n\t\t\t\troundness: cornerRadius,\n\t\t\t\tdepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\textrudeBevelSegments,\n\t\t\t},\n\t\t});\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'StarGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n */\n\nimport { PlaneBufferGeometry } from 'three';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\n\nexport type TextFrameGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n};\n\nexport type TextFrameGeometryInputs = {\n\tparameters: TextFrameGeometryParameters;\n};\n\nexport const TextFrameGeometry: CGeometry<TextFrameGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<TextFrameGeometryInputs>\n\t): IGeometry<TextFrameGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<TextFrameGeometryInputs>,\n\t\tbase?: TextFrameGeometryInputs\n\t): TextFrameGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? 0),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: TextFrameGeometryInputs\n\t): IGeometry<TextFrameGeometryInputs> {\n\t\tconst { width, height } = inputs.parameters;\n\n\t\tconst geometry = new PlaneBufferGeometry(width, height);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'TextFrameGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author lawrence\n */\n\nimport { BufferGeometry } from 'three';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { HelixBufferGeometry } from './HelixGeometry';\n\nexport type TorusGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\t// tubePercent: number;\n\tradialSegments: number;\n\ttubularSegments: number;\n\tarc: number;\n\tcornerRadius: number;\n\tcornerSegments: number;\n};\n\nexport type TorusGeometryInputs = { parameters: TorusGeometryParameters };\n\nexport const TorusGeometry: CGeometry<TorusGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<TorusGeometryInputs>\n\t): IGeometry<TorusGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<TorusGeometryInputs>,\n\t\tbase?: TorusGeometryInputs\n\t): TorusGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\t// tubePercent: 50,\n\t\t\t\tradialSegments: 32,\n\t\t\t\ttubularSegments: 64,\n\t\t\t\tarc: Math.PI * 2,\n\t\t\t\tcornerRadius: 30,\n\t\t\t\tcornerSegments: 8,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\tconst width = Math.abs(nParams.width);\n\t\tconst height = Math.abs(nParams.height ?? nParams.width);\n\t\t// lawrence (16-december-2020) commented this part since the Depth parameter is already controlling the radius (but we could need it again, if we need a 'flat' torus, like a wedding ring)\n\t\t// const tube = width * 0.25 * Math.abs(nParams.tubePercent) * 0.01;\n\t\t// const depth = Math.abs(nParams.depth ?? tube * 2);\n\t\tconst depth = Math.abs(nParams.depth ?? nParams.width * 0.25);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tdepth,\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(inputs: TorusGeometryInputs): IGeometry<TorusGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\tradialSegments,\n\t\t\ttubularSegments,\n\t\t\tarc,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments,\n\t\t} = inputs.parameters;\n\n\t\tconst geometry = genTorus(\n\t\t\twidth,\n\t\t\theight,\n\t\t\tdepth,\n\t\t\t/*gui_radius*/ width * 0.5,\n\t\t\tarc,\n\t\t\ttubularSegments,\n\t\t\t/*gui_pathRadius*/ 0,\n\t\t\t/*gui_pathType*/ 0,\n\t\t\tradialSegments,\n\t\t\tcornerRadius,\n\t\t\tcornerSegments\n\t\t);\n\t\tgeometry.scale(1, height / width, 1);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'TorusGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n\nfunction genTorus(\n\twidth: number,\n\theight: number,\n\tdepth: number,\n\tradius: number,\n\trevolutions: number,\n\tsegments: number,\n\tpathRadius: number,\n\tpathType: number,\n\tpathSegments: number,\n\tcornerRadius: number,\n\tcornerSegments: number\n): BufferGeometry {\n\t[height, depth] = [depth, height];\n\tpathRadius = height / 2;\n\trevolutions /= 2 * Math.PI;\n\n\tif (revolutions == 1) cornerRadius = 0;\n\n\treturn new HelixBufferGeometry(\n\t\ttrue, // a torus\n\t\twidth,\n\t\theight,\n\t\tdepth,\n\t\tradius,\n\t\trevolutions,\n\t\tsegments,\n\t\tpathRadius,\n\t\tpathType,\n\t\tpathSegments,\n\t\tcornerRadius,\n\t\tcornerSegments\n\t);\n}\n", "/**\n * @author nisa\n */\n\nimport { TorusKnotBufferGeometry } from 'three';\nimport { IGeometry, CGeometry, NestedPartial } from './Geometry';\n\nexport type TorusKnotGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\ttube: number;\n\ttubularSegments: number;\n\tradialSegments: number;\n\tp: number;\n\tq: number;\n};\n\nexport type TorusKnotGeometryInputs = {\n\tparameters: TorusKnotGeometryParameters;\n};\n\nexport const TorusKnotGeometry: CGeometry<TorusKnotGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<TorusKnotGeometryInputs>\n\t): IGeometry<TorusKnotGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<TorusKnotGeometryInputs>,\n\t\tbase?: TorusKnotGeometryInputs\n\t): TorusKnotGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\ttubularSegments: 64,\n\t\t\t\tradialSegments: 32,\n\t\t\t\tp: 2,\n\t\t\t\tq: 3,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\treturn {\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\t// we should use radius instead of width, height and depth, but the editor still need them\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(nParams.height ?? nParams.width),\n\t\t\t\tdepth: Math.abs(nParams.depth ?? nParams.width),\n\t\t\t\ttube: nParams.tube ?? nParams.width * 0.125,\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: TorusKnotGeometryInputs\n\t): IGeometry<TorusKnotGeometryInputs> {\n\t\tconst {\n\t\t\twidth,\n\t\t\t// height,\n\t\t\t// depth,\n\t\t\ttube,\n\t\t\ttubularSegments,\n\t\t\tradialSegments,\n\t\t\tp,\n\t\t\tq,\n\t\t} = inputs.parameters;\n\t\t// The old files are using this formula radius = width * 0.5 - tube, there are two problems with this:\n\t\t// 1- There are no size changes when modifying height or depth (could change the position)\n\t\t// 2- When width * 0.5 === tube, the radius is 0\n\t\t// Possible solutions:\n\t\t// 1- Use `const radius = Math.max(width, height, depth) * 0.5` or `const radius = width * 0.5`, this would slightly\n\t\t// change the size of old torus knot unless we use the \"file upgrader\" to fix the old size before load them (easy option)\n\t\t// 2- Get rid of the width, height, depth (as empty objects, lights or cameras), and resize it using its radius (think about multi selection for resizing).\n\t\t// The solution need to be discussed, we may want to includ lathe and torus geometry in this solution.\n\t\t// in the meantime we use this conditiontal patch to prevent radius gets 0\n\t\tlet radius = width * 0.5;\n\t\tif (radius !== tube) {\n\t\t\tradius -= tube;\n\t\t}\n\n\t\tconst geometry = new TorusKnotBufferGeometry(\n\t\t\tradius,\n\t\t\ttube,\n\t\t\ttubularSegments,\n\t\t\tradialSegments,\n\t\t\tp,\n\t\t\tq\n\t\t);\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'TorusKnotGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n * @author guillaume\n */\n\nimport { VectorShape } from '../objects/entities/vectors/VectorShape';\nimport { CGeometry, IGeometry, NestedPartial } from './Geometry';\nimport { VectorGeometry } from './vectors/VectorGeometry';\n\nexport type TriangleGeometryParameters = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tcornerRadius: number;\n\textrudeDepth: number;\n\textrudeBevelSize: number;\n\textrudeBevelSegments: number;\n\tisRect: boolean;\n\tsurfaceMaxCount: number;\n};\n\nexport type TriangleGeometryInputs = {\n\tparameters: TriangleGeometryParameters;\n\tshape: VectorShape;\n};\n\nexport const TriangleGeometry: CGeometry<TriangleGeometryInputs> = class {\n\tstatic create(\n\t\tinputs: NestedPartial<TriangleGeometryInputs>\n\t): IGeometry<TriangleGeometryInputs> {\n\t\treturn this.build(this.normalizeInputs(inputs));\n\t}\n\n\tstatic normalizeInputs(\n\t\tinputs: NestedPartial<TriangleGeometryInputs>,\n\t\tbase?: TriangleGeometryInputs\n\t): TriangleGeometryInputs {\n\t\tconst nParams = Object.assign(\n\t\t\t{},\n\t\t\tbase?.parameters ?? {\n\t\t\t\twidth: 100,\n\t\t\t\tdepth: 0,\n\t\t\t\tspikes: 5,\n\t\t\t\tcornerRadius: 0,\n\t\t\t\textrudeDepth: 0,\n\t\t\t\textrudeBevelSize: 0,\n\t\t\t\textrudeBevelSegments: 1,\n\t\t\t\tisRect: false,\n\t\t\t},\n\t\t\tinputs.parameters\n\t\t);\n\n\t\t// Can be passed from inputs when restoring from VectorObject\n\t\tconst shape =\n\t\t\tinputs.shape && inputs.shape instanceof VectorShape\n\t\t\t\t? inputs.shape\n\t\t\t\t: new VectorShape();\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tparameters: Object.assign(nParams, {\n\t\t\t\tsurfaceMaxCount:\n\t\t\t\t\tnParams.surfaceMaxCount ?? nParams.cornerRadius > 0 ? 1000 : 100,\n\t\t\t\twidth: Math.abs(nParams.width),\n\t\t\t\theight: Math.abs(\n\t\t\t\t\tnParams.height ??\n\t\t\t\t\t\tnParams.width * (nParams.isRect ? 1 : Math.sqrt(3) / 2)\n\t\t\t\t),\n\t\t\t\tdepth: Math.abs(\n\t\t\t\t\tnParams.depth !== undefined &&\n\t\t\t\t\t\tnParams.depth === 0 &&\n\t\t\t\t\t\tnParams.extrudeDepth > 0\n\t\t\t\t\t\t? nParams.extrudeDepth\n\t\t\t\t\t\t: nParams.depth ?? 0\n\t\t\t\t),\n\t\t\t}),\n\t\t};\n\t}\n\n\tstatic build(\n\t\tinputs: TriangleGeometryInputs\n\t): IGeometry<TriangleGeometryInputs> {\n\t\tconst {\n\t\t\twidth = 100,\n\t\t\theight,\n\t\t\tcornerRadius,\n\t\t\tdepth,\n\t\t\textrudeBevelSize,\n\t\t\textrudeBevelSegments,\n\t\t\tisRect,\n\t\t\tsurfaceMaxCount,\n\t\t} = inputs.parameters;\n\t\tconst shape = inputs.shape;\n\t\tconst rx = width * 0.5;\n\t\tconst ry = height * 0.5;\n\n\t\tif (isRect) {\n\t\t\tshape.addPoint(shape.createPoint(-rx, ry));\n\t\t\tshape.addPoint(shape.createPoint(rx, -ry));\n\t\t\tshape.addPoint(shape.createPoint(-rx, -ry));\n\t\t} else {\n\t\t\tshape.addPoint(shape.createPoint(0, ry));\n\t\t\tshape.addPoint(shape.createPoint(rx, -ry));\n\t\t\tshape.addPoint(shape.createPoint(-rx, -ry));\n\t\t}\n\n\t\tshape.isClosed = true;\n\n\t\tfor (let i = 0, l = shape.points.length; i < l; i++) {\n\t\t\tshape.points[i].roundness = cornerRadius;\n\t\t}\n\n\t\tshape.roundness = cornerRadius;\n\t\tshape.update();\n\n\t\tconst geometry = VectorGeometry.create({\n\t\t\tshape,\n\t\t\tparameters: {\n\t\t\t\tsurfaceMaxCount,\n\t\t\t\troundness: cornerRadius,\n\t\t\t\tdepth,\n\t\t\t\textrudeBevelSize,\n\t\t\t\textrudeBevelSegments,\n\t\t\t},\n\t\t});\n\n\t\treturn Object.assign(geometry, {\n\t\t\tuserData: {\n\t\t\t\t...inputs,\n\t\t\t\ttype: 'TriangleGeometry' as const,\n\t\t\t},\n\t\t});\n\t}\n};\n", "/**\n * @author nisa\n */\n\nimport {\n\tBufferGeometry,\n\tBufferGeometryLoader,\n\tFloat32BufferAttribute,\n\tShape,\n\tVector2,\n\tVector3,\n} from 'three';\nimport { Geometry } from '.';\n\ntype Size = {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n};\n\ntype V = {\n\tx: number;\n\ty: number;\n\tlen: number;\n\tnx: number;\n\tny: number;\n\tang: number;\n};\n\nconst asVec = function (p: Vector2, pp: Vector2): V {\n\tconst x = pp.x - p.x;\n\tconst y = pp.y - p.y;\n\tconst len = Math.sqrt(x * x + y * y);\n\tconst nx = x / len;\n\tconst ny = y / len;\n\tconst ang = Math.atan2(ny, nx);\n\n\treturn { x, y, len, nx, ny, ang };\n};\n\nexport const roundShapePolygon = (\n\tshape: Shape,\n\tpoints: Vector2[],\n\tradius: number\n) => {\n\tlet i,\n\t\tx,\n\t\ty,\n\t\tp1,\n\t\tp2,\n\t\tp3,\n\t\tsinA,\n\t\tsinA90,\n\t\tradDirection,\n\t\tdrawDirection,\n\t\tangle,\n\t\thalfAngle,\n\t\tcRadius,\n\t\tlenOut;\n\tconst len = points.length;\n\tp1 = points[len - 2];\n\tshape.curves = [];\n\n\tfor (i = 1; i < len - 1; i++) {\n\t\tp2 = points[i % len];\n\t\tp3 = points[(i + 1) % len];\n\t\tconst v1 = asVec(p2, p1);\n\t\tconst v2 = asVec(p2, p3);\n\t\tsinA = v1.nx * v2.ny - v1.ny * v2.nx;\n\t\tsinA90 = v1.nx * v2.nx - v1.ny * -v2.ny;\n\t\tangle = Math.asin(sinA);\n\t\tradDirection = 1;\n\t\tdrawDirection = false;\n\t\tif (sinA90 < 0) {\n\t\t\tif (angle < 0) {\n\t\t\t\tangle = Math.PI + angle;\n\t\t\t} else {\n\t\t\t\tangle = Math.PI - angle;\n\t\t\t\tradDirection = -1;\n\t\t\t\tdrawDirection = true;\n\t\t\t}\n\t\t} else {\n\t\t\tif (angle > 0) {\n\t\t\t\tradDirection = -1;\n\t\t\t\tdrawDirection = true;\n\t\t\t}\n\t\t}\n\t\thalfAngle = angle / 2;\n\t\tlenOut = Math.abs((Math.cos(halfAngle) * radius) / Math.sin(halfAngle));\n\t\tif (lenOut > Math.min(v1.len / 2, v2.len / 2)) {\n\t\t\tlenOut = Math.min(v1.len / 2, v2.len / 2);\n\t\t\tcRadius = Math.abs((lenOut * Math.sin(halfAngle)) / Math.cos(halfAngle));\n\t\t} else {\n\t\t\tcRadius = radius;\n\t\t}\n\t\tx = p2.x + v2.nx * lenOut;\n\t\ty = p2.y + v2.ny * lenOut;\n\t\tx += -v2.ny * cRadius * radDirection;\n\t\ty += v2.nx * cRadius * radDirection;\n\n\t\tshape.absarc(\n\t\t\tx,\n\t\t\ty,\n\t\t\tcRadius,\n\t\t\tv1.ang + (Math.PI / 2) * radDirection,\n\t\t\tv2.ang - (Math.PI / 2) * radDirection,\n\t\t\tdrawDirection\n\t\t);\n\n\t\tp1 = p2;\n\t\tp2 = p3;\n\t}\n\tshape.closePath();\n};\n\nexport const resizeGeometry = (\n\tgeometry: Geometry,\n\t{ width, height, depth }: Size\n) => {\n\twidth = Math.abs(width);\n\theight = Math.abs(height);\n\tdepth = Math.abs(depth);\n\n\tconst parameters = geometry.userData.parameters;\n\tlet scaleX, scaleY, scaleZ;\n\n\tif (width === 0) {\n\t\twidth = parameters.width;\n\t\tscaleX = 1;\n\t} else {\n\t\tscaleX = width / parameters.width;\n\t}\n\n\tif (height === 0) {\n\t\theight = parameters.height;\n\t\tscaleY = 1;\n\t} else {\n\t\tscaleY = height / parameters.height;\n\t}\n\n\tif (depth === 0) {\n\t\tdepth = parameters.depth;\n\t\tscaleZ = 1;\n\t} else {\n\t\tscaleZ = depth / parameters.depth;\n\t}\n\n\tgeometry.scale(scaleX, scaleY, scaleZ);\n\n\tparameters.width = width;\n\tparameters.height = height;\n\tparameters.depth = depth;\n};\n\nexport const addBarycentricAttribute = (\n\tgeometry: Geometry,\n\tattribName: string\n) => {\n\tconst vectors = [\n\t\tnew Vector3(1, 0, 0),\n\t\tnew Vector3(0, 1, 0),\n\t\tnew Vector3(0, 0, 1),\n\t];\n\n\tconst position = geometry.attributes.position;\n\tconst barycentric = new Float32Array(position.count * 3);\n\n\tfor (let i = 0, l = position.count; i < l; i++)\n\t\tvectors[i % 3].toArray(barycentric, i * 3);\n\n\tgeometry.setAttribute(attribName, new Float32BufferAttribute(barycentric, 3));\n};\n\nexport const loadFromUrl = (url: string): Promise<BufferGeometry> => {\n\treturn new Promise((resolve) => {\n\t\tconst loader = new BufferGeometryLoader();\n\t\tloader.load(url, (geometry) => resolve(geometry));\n\t});\n};\n\nexport const fixUvs = (\n\tgeometry: BufferGeometry,\n\twidth: number,\n\theight: number\n) => {\n\t// NOTE: Refactored, needs testing\n\tconst uvAttribute = geometry.getAttribute('uv');\n\tif (uvAttribute) {\n\t\tfor (let i = 0; i < uvAttribute.count; i++) {\n\t\t\tconst u = uvAttribute.getX(i);\n\t\t\tconst v = uvAttribute.getY(i);\n\t\t\tuvAttribute.setXY(\n\t\t\t\ti,\n\t\t\t\t(u + width / 2) / width,\n\t\t\t\t1 - ((v - height / 2) / height) * -1\n\t\t\t);\n\t\t}\n\t}\n};\n", "/**\n * @author howard\n */\n\nimport {\n\tBufferGeometry,\n\tBufferAttribute,\n\tUint32BufferAttribute,\n\tFloat32BufferAttribute,\n\tColor,\n\tMatrix4,\n\tMatrix4Tuple,\n} from 'three';\n\nimport type { SphereGeometry, CylinderGeometry } from 'three';\nimport { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils.js';\nimport { modellingWasm } from './modelling-wasm';\nimport type { ProcessModule } from './modelling-wasm';\nimport type {\n\tSubdivGeometryParameters,\n\tTorusGeometryParameters,\n} from 'spline-data';\nimport { CollabSerialize } from 'collab-data';\n\nlet wasm: ProcessModule;\nmodellingWasm.then((inst) => {\n\twasm = inst;\n});\n\nexport type SubdivGeometryInputs = {\n\tparameters: {\n\t\twidth: number;\n\t\theight: number;\n\t\tdepth: number;\n\t\tsubdivisions: number;\n\t};\n\tgeometry?: BufferGeometry;\n\tsubdivPointer?: number;\n\tsmoothShading?: boolean;\n};\n\nexport type SubdivGeometryOutput = BufferGeometry & {\n\toriginalGeometry?: BufferGeometry;\n\tsubdivPointer: number;\n};\n\nconst positionsDefault = new Float32Array([\n\t10, 10, 0, -10, 10, 0, -10, -10, 0, 10, -10, 0,\n]);\nconst indexDefault = new Uint32Array([0, 1, 2, 3]);\nconst verticesPerFaceDefault = new Uint8Array([4]);\n\nexport const SubdivGeometry = class {\n\t/**\n\t * @param inputs object containing topological data of the geoemtry (stored in Collab)\n\t * @param oldSubdivPointer if provided, the old subdiv pointer will be freed\n\t * @param geom if provided, this (instead of `inputs`) will be used to\n\t * construct the geomtry. This is used for converting parametric primitives\n\t * such as sphere, cubes, cylinders, etc.\n\t * @param shearScale if provided, the wasm module will apply this matrix will\n\t * to the built geometry as a final step.\n\t * @returns object containing pointer to the current WASM mesh data structure,\n\t * and optionally `originalGeometry` and/or the `subdividedGeomery` only if each\n\t * of the geometries were needed to be updated.\n\t */\n\tstatic build(\n\t\tinputs?: SubdivGeometryParameters,\n\t\toldSubdivPointer?: number,\n\t\tgeom?: BufferGeometry,\n\t\tsmoothShading?: boolean,\n\t\tshearScale?: Matrix4\n\t): {\n\t\toriginalGeometry?: BufferGeometry;\n\t\tsubdividedGeometry?: BufferGeometry | null; // see note on null below\n\t\tsubdivPointer: number;\n\t} {\n\t\tlet subdivPointer, originalGeometry, subdividedGeometry;\n\n\t\tif (inputs === undefined) {\n\t\t\tsubdivPointer = SubdivGeometry.allocate(shearScale, geom!);\n\t\t\t// questionable if we need this line below\n\t\t\twasm.set_destination_refinement_level(subdivPointer, 0);\n\t\t\toriginalGeometry = SubdivGeometry.buildLevel(\n\t\t\t\tsubdivPointer,\n\t\t\t\ttrue,\n\t\t\t\tsmoothShading\n\t\t\t)!;\n\t\t} else if (inputs.positionWASM !== undefined) {\n\t\t\tif (oldSubdivPointer && oldSubdivPointer !== 0) {\n\t\t\t\t// console.log('free subdivPointer during build', oldSubdivPointer);\n\t\t\t\twasm.free_bvh(oldSubdivPointer);\n\t\t\t\twasm.free_subdivision_surface(oldSubdivPointer);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tsubdivPointer = SubdivGeometry.allocate(shearScale, undefined, inputs);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(e, inputs);\n\t\t\t\tsubdivPointer = SubdivGeometry.allocate(shearScale, undefined, {\n\t\t\t\t\tpositionWASM: positionsDefault,\n\t\t\t\t\tindexWASM: indexDefault,\n\t\t\t\t\tverticesPerFaceWASM: verticesPerFaceDefault,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// console.log('new subdivPointer', subdivPointer)\n\t\t\t// questionable if we need this line below\n\t\t\twasm.set_destination_refinement_level(subdivPointer, 0);\n\t\t\toriginalGeometry = SubdivGeometry.buildLevel(\n\t\t\t\tsubdivPointer,\n\t\t\t\ttrue,\n\t\t\t\tsmoothShading\n\t\t\t)!;\n\t\t} else {\n\t\t\tsubdivPointer = oldSubdivPointer!;\n\t\t}\n\n\t\tif (inputs !== undefined && inputs.subdivisions !== undefined) {\n\t\t\tconst actualSubdivisions = getSafeSubdivlevel(\n\t\t\t\tinputs.subdivisions,\n\t\t\t\tinputs.positionWASM.length\n\t\t\t);\n\n\t\t\t// console.log(inputs.positionWASM.length, actualSubdivisions);\n\t\t\twasm.set_destination_refinement_level(subdivPointer, actualSubdivisions);\n\n\t\t\tif (actualSubdivisions > 0) {\n\t\t\t\tsubdividedGeometry = SubdivGeometry.buildLevel(\n\t\t\t\t\tsubdivPointer,\n\t\t\t\t\tfalse,\n\t\t\t\t\tsmoothShading\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// when the user is actively setting subdivisions to 0, we need to\n\t\t\t\t// use null rather than undefined to let the calling code know that\n\t\t\t\t// we need to dispose of the existing subdivided geometry\n\t\t\t\tsubdividedGeometry = null;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tsubdivPointer,\n\t\t\toriginalGeometry,\n\t\t\tsubdividedGeometry,\n\t\t};\n\t}\n\n\tstatic allocate(\n\t\tshearScale?: Matrix4,\n\t\tgeom?: BufferGeometry,\n\t\tdata?: Partial<SubdivGeometryParameters>\n\t): number {\n\t\tlet positions: Float32Array;\n\t\tlet indices: Uint32Array;\n\t\tlet verticesPerFace: Uint8Array;\n\t\tconst normals = [] as number[];\n\t\tconst texcoords = [] as number[];\n\n\t\tif (data) {\n\t\t\tif (data.positionWASM && data.positionWASM.length > 0) {\n\t\t\t\tpositions = data.positionWASM;\n\t\t\t\tindices = data.indexWASM!;\n\t\t\t\tverticesPerFace = data.verticesPerFaceWASM!;\n\t\t\t} else {\n\t\t\t\tpositions = positionsDefault;\n\t\t\t\tindices = indexDefault;\n\t\t\t\tverticesPerFace = verticesPerFaceDefault;\n\t\t\t}\n\t\t} else {\n\t\t\tgeom!.deleteAttribute('normal');\n\t\t\tgeom!.deleteAttribute('uv');\n\t\t\tconst mergedGeom = mergeVertices(geom!);\n\t\t\tpositions = mergedGeom.attributes.position.array as Float32Array;\n\t\t\tconst triIndices = mergedGeom.getIndex()!.array;\n\t\t\tconst nTriIndicies = triIndices.length;\n\n\t\t\tif (\n\t\t\t\tgeom!.userData.type === 'TorusGeometry' &&\n\t\t\t\tgeom?.userData.parameters.arc === Math.PI * 2\n\t\t\t) {\n\t\t\t\tgeom!.userData.type = 'ClosedTorusGeometry';\n\t\t\t}\n\n\t\t\tswitch (geom!.userData.type) {\n\t\t\t\tcase 'ClosedTorusGeometry':\n\t\t\t\tcase 'PlaneGeometry':\n\t\t\t\tcase 'TorusKnotGeometry':\n\t\t\t\tcase 'CubeGeometry':\n\t\t\t\t\tindices = new Uint32Array((nTriIndicies / 3) * 2);\n\t\t\t\t\tverticesPerFace = new Uint8Array(nTriIndicies / 6).fill(4);\n\t\t\t\t\tfor (let i = 0, j = 0; i < nTriIndicies; i += 6) {\n\t\t\t\t\t\tindices[j++] = triIndices[i];\n\t\t\t\t\t\tindices[j++] = triIndices[i + 1];\n\t\t\t\t\t\tindices[j++] = triIndices[i + 4];\n\t\t\t\t\t\tindices[j++] = triIndices[i + 5];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'TorusGeometry':\n\t\t\t\tcase 'SphereGeometry':\n\t\t\t\tcase 'HelixGeometry':\n\t\t\t\tcase 'CylinderGeometry':\n\t\t\t\tcase 'ConeGeometry':\n\t\t\t\t\tlet wSeg, hSeg, isSphereSliced;\n\n\t\t\t\t\tif (geom!.userData.type === 'SphereGeometry') {\n\t\t\t\t\t\thSeg = (geom as SphereGeometry).parameters.heightSegments;\n\t\t\t\t\t\twSeg = (geom as SphereGeometry).parameters.widthSegments;\n\t\t\t\t\t\tif ((geom as SphereGeometry).parameters.thetaLength !== Math.PI) {\n\t\t\t\t\t\t\tisSphereSliced = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (geom!.userData.type === 'CylinderGeometry') {\n\t\t\t\t\t\thSeg = (geom as CylinderGeometry).parameters.heightSegments + 2;\n\t\t\t\t\t\twSeg = (geom as CylinderGeometry).parameters.radialSegments;\n\t\t\t\t\t} else if (geom!.userData.type === 'ConeGeometry') {\n\t\t\t\t\t\thSeg = (geom as CylinderGeometry).parameters.heightSegments + 1;\n\t\t\t\t\t\twSeg = (geom as CylinderGeometry).parameters.radialSegments;\n\t\t\t\t\t} else if (geom!.userData.type === 'TorusGeometry') {\n\t\t\t\t\t\tconst params = geom!.userData.parameters as TorusGeometryParameters;\n\t\t\t\t\t\thSeg =\n\t\t\t\t\t\t\tMath.ceil((params.tubularSegments * params.arc) / (2 * Math.PI)) +\n\t\t\t\t\t\t\t2;\n\t\t\t\t\t\twSeg = params.radialSegments;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// 'HelixGeometry'\n\t\t\t\t\t\tconst { pathSegments, segments, revolutions } =\n\t\t\t\t\t\t\tgeom!.userData.parameters;\n\t\t\t\t\t\thSeg = Math.ceil(segments * revolutions) + 2;\n\t\t\t\t\t\twSeg = pathSegments;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isSphereSliced) {\n\t\t\t\t\t\tindices = new Uint32Array(1 * wSeg * 3 + (hSeg - 1) * wSeg * 4);\n\t\t\t\t\t\tverticesPerFace = new Uint8Array(1 * wSeg + (hSeg - 1) * wSeg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tindices = new Uint32Array(2 * wSeg * 3 + (hSeg - 2) * wSeg * 4);\n\t\t\t\t\t\tverticesPerFace = new Uint8Array(2 * wSeg + (hSeg - 2) * wSeg);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet i = 0;\n\t\t\t\t\tlet j = 0;\n\t\t\t\t\tlet k = 0;\n\t\t\t\t\tif (\n\t\t\t\t\t\tgeom!.userData.type === 'SphereGeometry' ||\n\t\t\t\t\t\tgeom!.userData.type === 'HelixGeometry' ||\n\t\t\t\t\t\tgeom!.userData.type === 'TorusGeometry'\n\t\t\t\t\t) {\n\t\t\t\t\t\tfor (; j < 3 * wSeg; ) {\n\t\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\t\tverticesPerFace[k++] = 3;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst end = isSphereSliced\n\t\t\t\t\t\t\t? indices.length\n\t\t\t\t\t\t\t: 3 * wSeg + 4 * (hSeg - 2) * wSeg;\n\t\t\t\t\t\tfor (; j < end; i += 6) {\n\t\t\t\t\t\t\tindices[j++] = triIndices[i];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 1];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 4];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 5];\n\t\t\t\t\t\t\tverticesPerFace[k++] = 4;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (; j < 4 * (hSeg - 2) * wSeg; i += 6) {\n\t\t\t\t\t\t\tindices[j++] = triIndices[i];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 1];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 4];\n\t\t\t\t\t\t\tindices[j++] = triIndices[i + 5];\n\t\t\t\t\t\t\tverticesPerFace[k++] = 4;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (; j < indices.length; ) {\n\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\tindices[j++] = triIndices[i++];\n\t\t\t\t\t\tverticesPerFace[k++] = 3;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tindices = triIndices as Uint32Array;\n\t\t\t\t\tverticesPerFace = new Uint8Array(nTriIndicies / 3).fill(3);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// console.log('wasm allocate:', verticesPerFace.length, 'triangles');\n\n\t\tconst meshNumVertices = positions.length;\n\t\tconst meshNumIndices = indices.length;\n\t\tconst meshNumVerticesPerFace = verticesPerFace.length;\n\t\t// console.log(\n\t\t// `Input mesh has ${meshNumVertices} vertices and ${meshNumIndices} indices`\n\t\t// );\n\n\t\t// Total number of float elements and integer elements\n\t\tconst numFloats = positions.length + normals.length + texcoords.length;\n\t\tconst numInts = indices.length + verticesPerFace.length;\n\n\t\t// How big should the output buffer be?\n\t\tconst memoryRequirements =\n\t\t\tnumFloats * Float32Array.BYTES_PER_ELEMENT +\n\t\t\tnumInts * Uint32Array.BYTES_PER_ELEMENT;\n\t\t// console.log('Total WASM memory size (in bytes):', memoryRequirements);\n\t\tconst sizeF32Chunk = numFloats * Float32Array.BYTES_PER_ELEMENT;\n\t\tconst sizeI32Chunk = numInts * Uint32Array.BYTES_PER_ELEMENT;\n\n\t\t// Allocate memory for the WASM instance to use and create Javascript views into this memory\n\t\tconst pointer = wasm._malloc(memoryRequirements);\n\t\t// console.log('after malloc wasmPointer');\n\t\tconst viewF32 = new Float32Array(wasm.HEAPF32.buffer, pointer, numFloats);\n\t\tconst viewI32 = new Uint32Array(\n\t\t\twasm.HEAPU32.buffer,\n\t\t\tpointer + sizeF32Chunk,\n\t\t\tnumInts\n\t\t);\n\n\t\t// Copy data into WASM memory\n\t\tviewF32.set(positions, 0);\n\t\tviewF32.set(normals, positions.length);\n\t\tviewF32.set(texcoords, positions.length + normals.length);\n\n\t\tviewI32.set(indices, 0);\n\t\tviewI32.set(verticesPerFace, indices.length);\n\n\t\t// console.log('before wasm.alloc_subdivision_surface');\n\t\t// Process data with WASM - returns the subdivision surface's address in memory\n\t\t// const now = performance.now();\n\n\t\tlet transformMatrix: Matrix4 | undefined;\n\t\tif (data?.scaleBaked?.some((s) => s !== 1)) {\n\t\t\ttransformMatrix = new Matrix4().makeScale(...data.scaleBaked);\n\t\t}\n\t\tif (shearScale) {\n\t\t\tif (transformMatrix) {\n\t\t\t\ttransformMatrix.premultiply(shearScale);\n\t\t\t} else {\n\t\t\t\ttransformMatrix = shearScale;\n\t\t\t}\n\t\t}\n\n\t\tconst subdivPtr = transformMatrix\n\t\t\t? wasm.alloc_subdivision_surface2(\n\t\t\t\t\tpointer,\n\t\t\t\t\tmeshNumVertices,\n\t\t\t\t\tpointer + sizeF32Chunk,\n\t\t\t\t\tmeshNumIndices,\n\t\t\t\t\tpointer +\n\t\t\t\t\t\tsizeF32Chunk +\n\t\t\t\t\t\tindices.length * Uint32Array.BYTES_PER_ELEMENT,\n\t\t\t\t\tmeshNumVerticesPerFace,\n\t\t\t\t\ttransformMatrix.elements as Matrix4Tuple\n\t\t\t )\n\t\t\t: wasm.alloc_subdivision_surface(\n\t\t\t\t\tpointer,\n\t\t\t\t\tmeshNumVertices,\n\t\t\t\t\tpointer + sizeF32Chunk,\n\t\t\t\t\tmeshNumIndices,\n\t\t\t\t\tpointer +\n\t\t\t\t\t\tsizeF32Chunk +\n\t\t\t\t\t\tindices.length * Uint32Array.BYTES_PER_ELEMENT,\n\t\t\t\t\tmeshNumVerticesPerFace\n\t\t\t );\n\n\t\t// console.log('allocate subdivPointer', subdivPtr);\n\t\t// const then = performance.now();\n\t\t// console.log('Subdivision surface was constructed in:', then - now, '(ms)');\n\t\t// console.log('after wasm.alloc_subdivision_surface');\n\t\twasm._free(pointer);\n\t\treturn subdivPtr;\n\t}\n\n\t/**\n\t * @param subdivPtr the pointer to the subdivision surface\n\t * @param controlMesh returns control mesh if true, other wise returns subdivided mesh\n\t * @param smoothShading whether to use smooth shading or flat shading\n\t * @param currentGeom if provided, the ouput geometry will be copied into the `currentGeom`\n\t * @param shearScaleInv if provided, output geometry will have this matrix applied\n\t * @returns if no `currentGoem` is provided, returns a new BufferGeometry with the output geometry copied in\n\t */\n\tstatic buildLevel(\n\t\tsubdivPtr: number,\n\t\tcontrolMesh: boolean,\n\t\tsmoothShading?: boolean,\n\t\tcurrentGeom?: BufferGeometry,\n\t\tshearScaleInv?: Matrix4\n\t): BufferGeometry | undefined {\n\t\tconst vertexDataPointer = shearScaleInv\n\t\t\t? wasm.get_mesh_data2(\n\t\t\t\t\tsubdivPtr,\n\t\t\t\t\tcontrolMesh ? wasm.Level.CONTROL : wasm.Level.REFINED,\n\t\t\t\t\tsmoothShading ?? (controlMesh ? false : true),\n\t\t\t\t\tshearScaleInv.elements as Matrix4Tuple\n\t\t\t )\n\t\t\t: wasm.get_mesh_data(\n\t\t\t\t\tsubdivPtr,\n\t\t\t\t\tcontrolMesh ? wasm.Level.CONTROL : wasm.Level.REFINED,\n\t\t\t\t\tsmoothShading ?? (controlMesh ? false : true)\n\t\t\t );\n\t\tconst memoryAddrStructSize = 8;\n\t\tconst memoryAddrView = wasm.HEAPU32.subarray(\n\t\t\tvertexDataPointer >> 2,\n\t\t\t(vertexDataPointer >> 2) + memoryAddrStructSize\n\t\t);\n\t\tconst lengths = memoryAddrView.subarray(4, 4 + 4);\n\t\tlet offset = 0x0;\n\n\t\t// The code below reads 32 bits (4 bytes) as a signed integer from address ptr + offset.\n\t\t// How this works is that HEAP32 is an Int32Array, which means that each index in the array\n\t\t// has 4 bytes. So we need to divide the byte address (ptr + offset) by 4 to get the index,\n\t\t// which is what the >> 2 does.\n\t\t//\n\t\t// See: https://v8.dev/blog/4gb-wasm-memory\n\n\t\tconst positionsPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst positionsView = wasm.HEAPF32.subarray(\n\t\t\tpositionsPointer >> 2,\n\t\t\t(positionsPointer >> 2) + lengths[offset]\n\t\t);\n\t\toffset++;\n\n\t\tconst normalsPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst normalsView = wasm.HEAPF32.subarray(\n\t\t\tnormalsPointer >> 2,\n\t\t\t(normalsPointer >> 2) + lengths[offset]\n\t\t);\n\t\toffset++;\n\n\t\tconst faceMapPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst faceMapView = wasm.HEAPU32.subarray(\n\t\t\tfaceMapPointer >> 2,\n\t\t\t(faceMapPointer >> 2) + lengths[offset]\n\t\t);\n\t\toffset++;\n\n\t\tconst indicesPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst indicesView = wasm.HEAPU32.subarray(\n\t\t\tindicesPointer >> 2,\n\t\t\t(indicesPointer >> 2) + lengths[offset]\n\t\t);\n\t\toffset++;\n\n\t\tif (currentGeom === undefined) {\n\t\t\tconst geo = new BufferGeometry();\n\n\t\t\tgeo.setIndex(new Uint32BufferAttribute(indicesView, 1));\n\t\t\tgeo.setAttribute(\n\t\t\t\t'position',\n\t\t\t\tnew Float32BufferAttribute(positionsView, 3)\n\t\t\t);\n\t\t\tgeo.setAttribute('normal', new Float32BufferAttribute(normalsView, 3));\n\n\t\t\tif (controlMesh) {\n\t\t\t\tgeo.setAttribute('faceMap', new Uint32BufferAttribute(faceMapView, 1));\n\t\t\t\t// Assume that we have the same number of colors as normals (one per vertex)\n\t\t\t\tconst colors = new Float32Array((normalsView.length / 3) * 4).fill(0);\n\t\t\t\tgeo.setAttribute('color', new BufferAttribute(colors, 4));\n\t\t\t}\n\n\t\t\t// console.log('build new data')\n\t\t\twasm.free_mesh_data(vertexDataPointer);\n\t\t\tgeo.userData.type = 'SubdivGeometry'; // this is hacky stuff, took 3 hours to figure out\n\t\t\treturn geo;\n\t\t}\n\n\t\t(currentGeom.getAttribute('position') as BufferAttribute).copyArray(\n\t\t\tpositionsView\n\t\t);\n\t\t(currentGeom.getAttribute('normal') as BufferAttribute).copyArray(\n\t\t\tnormalsView\n\t\t);\n\n\t\tcurrentGeom.attributes.position.needsUpdate = true;\n\t\tcurrentGeom.attributes.normal.needsUpdate = true;\n\t\t// console.log('build copy data')\n\n\t\t// Free the struct that holds the latest vertex data in WASM memory\n\t\twasm.free_mesh_data(vertexDataPointer);\n\t}\n\n\tstatic buildControlCageWireframe(\n\t\tsubdivPtr: number,\n\t\tcurrentGeom?: BufferGeometry,\n\t\tedgeColor?: Color\n\t) {\n\t\tconst vertexDataPointer = wasm.get_wireframe_data_for_base_level(subdivPtr);\n\t\tconst memoryAddrStructSize = 4;\n\t\tconst memoryAddrView = wasm.HEAPU32.subarray(\n\t\t\tvertexDataPointer >> 2,\n\t\t\t(vertexDataPointer >> 2) + memoryAddrStructSize\n\t\t);\n\t\tconst lengths = memoryAddrView.subarray(2, 2 + 2);\n\t\tlet offset = 0x0;\n\n\t\tconst positionsPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst positionsView = wasm.HEAPF32.subarray(\n\t\t\tpositionsPointer >> 2,\n\t\t\t(positionsPointer >> 2) + lengths[offset]\n\t\t);\n\t\toffset++;\n\n\t\tconst indicesPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst indicesView = wasm.HEAPU32.subarray(\n\t\t\tindicesPointer >> 2,\n\t\t\t(indicesPointer >> 2) + lengths[offset]\n\t\t);\n\n\t\tif (currentGeom === undefined) {\n\t\t\tconst geometry = new BufferGeometry();\n\t\t\tgeometry.setAttribute(\n\t\t\t\t'position',\n\t\t\t\tnew Float32BufferAttribute(positionsView, 3)\n\t\t\t);\n\n\t\t\tconst colors = new Float32Array(positionsView.length);\n\n\t\t\tfor (let i = 0, il = positionsView.length; i < il; ) {\n\t\t\t\tcolors[i++] = edgeColor!.r;\n\t\t\t\tcolors[i++] = edgeColor!.g;\n\t\t\t\tcolors[i++] = edgeColor!.b;\n\t\t\t}\n\n\t\t\tgeometry.setAttribute('color', new BufferAttribute(colors, 3));\n\n\t\t\tgeometry.setIndex(new Uint32BufferAttribute(indicesView, 1));\n\t\t\twasm.free_wireframe_data_for_base_level(vertexDataPointer);\n\t\t\treturn geometry;\n\t\t}\n\n\t\t(currentGeom.getAttribute('position') as BufferAttribute).copyArray(\n\t\t\tpositionsView\n\t\t);\n\n\t\t// console.log('copy control cage')\n\t\tcurrentGeom.attributes.position.needsUpdate = true;\n\n\t\t// Free the struct that holds the latest vertex data in WASM memory\n\t\twasm.free_wireframe_data_for_base_level(vertexDataPointer);\n\t}\n\n\tstatic updateCollabMesh(\n\t\tsubdivPtr: number,\n\t\tisControlMesh: boolean,\n\t\ttransformMatrixInv?: Matrix4\n\t) {\n\t\tif (!isControlMesh) {\n\t\t\twasm.set_destination_refinement_level(subdivPtr, 1);\n\t\t}\n\t\tconst vertexDataPointer = transformMatrixInv\n\t\t\t? wasm.get_topological_data2(\n\t\t\t\t\tsubdivPtr,\n\t\t\t\t\tisControlMesh ? wasm.Level.CONTROL : wasm.Level.REFINED,\n\t\t\t\t\ttransformMatrixInv.elements as Matrix4Tuple\n\t\t\t )\n\t\t\t: wasm.get_topological_data(\n\t\t\t\t\tsubdivPtr,\n\t\t\t\t\tisControlMesh ? wasm.Level.CONTROL : wasm.Level.REFINED\n\t\t\t );\n\t\tconst memoryAddrStructSize = 6;\n\t\tconst memoryAddrView = wasm.HEAPU32.subarray(\n\t\t\tvertexDataPointer >> 2,\n\t\t\t(vertexDataPointer >> 2) + memoryAddrStructSize\n\t\t);\n\t\tconst lengths = memoryAddrView.subarray(3, 3 + 3);\n\t\tlet offset = 0x0;\n\n\t\tconst positionsPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst positions = new Float32Array(\n\t\t\twasm.HEAPF32.subarray(\n\t\t\t\tpositionsPointer >> 2,\n\t\t\t\t(positionsPointer >> 2) + lengths[offset]\n\t\t\t)\n\t\t);\n\t\toffset++;\n\n\t\tconst indicesPointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst indices = new Uint32Array(\n\t\t\twasm.HEAPU32.subarray(\n\t\t\t\tindicesPointer >> 2,\n\t\t\t\t(indicesPointer >> 2) + lengths[offset]\n\t\t\t)\n\t\t);\n\t\toffset++;\n\n\t\tconst verticesPerFacePointer = wasm.HEAPU32[memoryAddrView[offset] >> 2];\n\t\tconst verticesPerFace = new Uint8Array(\n\t\t\twasm.HEAPU32.subarray(\n\t\t\t\tverticesPerFacePointer >> 2,\n\t\t\t\t(verticesPerFacePointer >> 2) + lengths[offset]\n\t\t\t)\n\t\t);\n\t\twasm.free_topological_data(vertexDataPointer);\n\n\t\t// benchmarkSerialization(positions);\n\t\treturn { positions, indices, verticesPerFace };\n\t}\n};\n\nexport function getSafeSubdivlevel(\n\tsubdivisions: number,\n\tlength: number\n): number {\n\tlet actualSubdivisions = subdivisions;\n\t// hard coded override to prevent subdividing a dense mesh by too much.\n\t// 173000 is the value above which if positionWASM exceeds, subdivision > 3 will fail\n\t// since each level of subdivion quadruples the number of vertices, we derive the\n\t// formula for all other cases. we use 172000 to be safe.\n\tactualSubdivisions = Math.min(\n\t\tactualSubdivisions,\n\t\t3 - Math.ceil(Math.log(length / 172000) / Math.log(4))\n\t);\n\treturn Math.max(actualSubdivisions, 0);\n}\n\nfunction benchmarkSerialization(positions: number[]) {\n\tlet docStr = JSON.stringify(positions);\n\tlet binary = CollabSerialize.serialize(positions);\n\t{\n\t\tlet time1 = new Date().getTime();\n\t\tlet bl = 0;\n\t\tlet str: string = '';\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tstr = JSON.stringify(positions);\n\t\t\tbl = str.length;\n\t\t}\n\t\tlet time2 = new Date().getTime();\n\t\tconsole.log('JSON.stringify', time2 - time1, bl);\n\t}\n\t{\n\t\tlet time1 = new Date().getTime();\n\t\tlet bl = 0;\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tlet buffer = CollabSerialize.serialize(positions);\n\t\t\tbl = buffer.byteLength;\n\t\t}\n\t\tlet time2 = new Date().getTime();\n\t\tconsole.log('CollabSerialize', time2 - time1, bl);\n\t}\n\t{\n\t\tlet time1 = new Date().getTime();\n\t\tlet obj: any = {};\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tobj = JSON.parse(docStr);\n\t\t}\n\t\tlet time2 = new Date().getTime();\n\t\tconsole.log('JSON parse', time2 - time1, Object.keys(obj).length);\n\t}\n\t{\n\t\tlet time1 = new Date().getTime();\n\t\tlet obj: any = {};\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tobj = CollabSerialize.deserialize(binary);\n\t\t}\n\t\tlet time2 = new Date().getTime();\n\t\tconsole.log(\n\t\t\t'CollabSerialize parse',\n\t\t\ttime2 - time1,\n\t\t\tObject.keys(obj).length\n\t\t);\n\t}\n}\n", "import type { ProcessModule } from 'modelling-wasm';\n\nexport type { ProcessModule };\n\n// We need to do all this mess to avoid the module from being included in runtime\n// TODO revisit this once the toJSONs() will be deprecated\n\n// this is a promise that resolves once modelling-wasm has loaded\nlet resolver: (wasm: ProcessModule) => void;\nexport const modellingWasm: Promise<ProcessModule> = new Promise((resolve) => {\n\tresolver = resolve;\n});\n\n// this function must be run at init of editor\n// to trigger the download\nlet isLoaded = false;\nexport async function loadModellingWasm() {\n\tif (isLoaded) return;\n\n\tconst wasmModule = (\n\t\tawait import(/* webpackChunkName: \"modelling-wasm\" */ 'modelling-wasm')\n\t).default;\n\tconst wasm = await wasmModule();\n\tresolver(wasm);\n\tisLoaded = true;\n}\n", "import {\n\tConeGeometry,\n\tConeGeometryInputs,\n\tConeGeometryParameters,\n} from './ConeGeometry';\nimport {\n\tCubeGeometry,\n\tCubeGeometryInputs,\n\tCubeGeometryParameters,\n} from './CubeGeometry';\nimport {\n\tCylinderGeometry,\n\tCylinderGeometryInputs,\n\tCylinderGeometryParameters,\n} from './CylinderGeometry';\nimport {\n\tDodecahedronGeometry,\n\tDodecahedronGeometryInputs,\n\tDodecahedronGeometryParameters,\n} from './DodecahedronGeometry';\nimport { EllipseGeometry } from './EllipseGeometry';\nimport { HelixGeometry } from './HelixGeometry';\nimport { IcosahedronGeometry } from './IcosahedronGeometry';\nimport { LatheGeometry } from './LatheGeometry';\nimport {\n\tNonParametricGeometry,\n\tNonParametricGeometryInputs,\n\tNonParametricGeometryParameters,\n} from './NonParametricGeometry';\nimport { PolygonGeometry } from './PolygonGeometry';\nimport { PyramidGeometry } from './PyramidGeometry';\nimport { RectangleGeometry } from './RectangleGeometry';\nimport { SphereGeometry } from './SphereGeometry';\nimport { PlaneGeometry } from './PlaneGeometry';\nimport { StarGeometry } from './StarGeometry';\nimport { TextFrameGeometry } from './TextFrameGeometry';\nimport { TorusGeometry } from './TorusGeometry';\nimport { TorusKnotGeometry } from './TorusKnotGeometry';\nimport { TriangleGeometry } from './TriangleGeometry';\nimport {\n\tVectorGeometry,\n\tVectorGeometryInputs,\n\tVectorGeometryParameters,\n} from './vectors/VectorGeometry';\nimport { CGeometry, IGeometry, BaseInputs } from './Geometry';\nimport {\n\tEllipseGeometryInputs,\n\tEllipseGeometryParameters,\n\tHelixGeometryInputs,\n\tHelixGeometryParameters,\n\tIcosahedronGeometryInputs,\n\tIcosahedronGeometryParameters,\n\tLatheGeometryInputs,\n\tLatheGeometryParameters,\n\tPolygonGeometryInputs,\n\tPolygonGeometryParameters,\n\tPyramidGeometryInputs,\n\tPyramidGeometryParameters,\n\tRectangleGeometryInputs,\n\tRectangleGeometryParameters,\n\tSphereGeometryInputs,\n\tSphereGeometryParameters,\n\tPlaneGeometryInputs,\n\tPlaneGeometryParameters,\n\tStarGeometryInputs,\n\tStarGeometryParameters,\n\tTextFrameGeometryInputs,\n\tTextFrameGeometryParameters,\n\tTorusGeometryInputs,\n\tTorusGeometryParameters,\n\tTorusKnotGeometryInputs,\n\tTorusKnotGeometryParameters,\n\tTriangleGeometryInputs,\n\tTriangleGeometryParameters,\n} from '..';\n\n/**\n * Map of all available Geometries\n */\nexport const geometries = {\n\tConeGeometry,\n\tCubeGeometry,\n\tCylinderGeometry,\n\tDodecahedronGeometry,\n\tEllipseGeometry,\n\tHelixGeometry,\n\tIcosahedronGeometry,\n\tLatheGeometry,\n\tNonParametricGeometry,\n\tPolygonGeometry,\n\tPyramidGeometry,\n\tRectangleGeometry,\n\tSphereGeometry,\n\tPlaneGeometry,\n\tStarGeometry,\n\tTextFrameGeometry,\n\tTorusGeometry,\n\tTorusKnotGeometry,\n\tTriangleGeometry,\n\tVectorGeometry,\n};\n\n/**\n * String/enum type of \"type\" member of Geometry instances\n */\nexport type GeometryType = keyof typeof geometries;\nexport type GeometryFactory = typeof geometries[GeometryType];\n\nexport type GeometryParameters =\n\t| ConeGeometryParameters\n\t| CubeGeometryParameters\n\t| CylinderGeometryParameters\n\t| DodecahedronGeometryParameters\n\t| EllipseGeometryParameters\n\t| HelixGeometryParameters\n\t| IcosahedronGeometryParameters\n\t| LatheGeometryParameters\n\t| NonParametricGeometryParameters\n\t| PolygonGeometryParameters\n\t| PyramidGeometryParameters\n\t| RectangleGeometryParameters\n\t| SphereGeometryParameters\n\t| PlaneGeometryParameters\n\t| StarGeometryParameters\n\t| TextFrameGeometryParameters\n\t| TorusGeometryParameters\n\t| TorusKnotGeometryParameters\n\t| TriangleGeometryParameters\n\t| VectorGeometryParameters;\n\nexport type GeometryInputs =\n\t| ConeGeometryInputs\n\t| CubeGeometryInputs\n\t| CylinderGeometryInputs\n\t| DodecahedronGeometryInputs\n\t| EllipseGeometryInputs\n\t| HelixGeometryInputs\n\t| IcosahedronGeometryInputs\n\t| LatheGeometryInputs\n\t| NonParametricGeometryInputs\n\t| PolygonGeometryInputs\n\t| PyramidGeometryInputs\n\t| RectangleGeometryInputs\n\t| SphereGeometryInputs\n\t| PlaneGeometryInputs\n\t| StarGeometryInputs\n\t| TextFrameGeometryInputs\n\t| TorusGeometryInputs\n\t| TorusKnotGeometryInputs\n\t| TriangleGeometryInputs\n\t| VectorGeometryInputs;\n\n/**\n * union type of all Geometries\n */\nexport type Geometry = ReturnType<GeometryFactory['build']>;\n\nexport const createGeometry = <TInputs extends BaseInputs>(\n\tinputs: Geometry['userData']\n): IGeometry<TInputs> => {\n\tconst Factory = geometries[inputs.type] as CGeometry<TInputs>;\n\treturn Factory.create(inputs);\n};\n\nexport * from './ConeGeometry';\nexport * from './CubeGeometry';\nexport * from './CylinderGeometry';\nexport * from './DodecahedronGeometry';\nexport * from './EllipseGeometry';\nexport * as GeometryUtils from './GeometryUtils';\nexport * from './HelixGeometry';\nexport * from './IcosahedronGeometry';\nexport * from './LatheGeometry';\nexport * from './NonParametricGeometry';\nexport * from './PolygonGeometry';\nexport * from './PyramidGeometry';\nexport * from './RectangleGeometry';\nexport * from './SphereGeometry';\nexport * from './PlaneGeometry';\nexport * from './StarGeometry';\nexport * from './TextFrameGeometry';\nexport * from './TorusGeometry';\nexport * from './TorusKnotGeometry';\nexport * from './TriangleGeometry';\nexport * from './vectors/VectorGeometry';\nexport * from './vectors/VectorLineGeometry';\nexport * from './vectors/VectorSurfaceGeometry';\n\nexport * from './subdiv/SubdivGeometry';\nexport * from './subdiv/modelling-wasm';\n", "import { Object3D, Matrix4 } from 'three';\nimport { Box3 } from '../../math';\nimport { Interaction } from '../../interactions/Interaction';\nimport { CombinedCamera, ICombinedCamera } from './CombinedCamera';\nimport { EmptyObject, IEmptyObject } from './EmptyObject';\nimport { NonParametric } from './NonParametric';\nimport { ILightDirectional, LightDirectional } from './LightDirectional';\nimport { ILightPoint, LightPoint } from './LightPoint';\nimport { ILightSpot, LightSpot } from './LightSpot';\nimport { Mesh2D } from './Mesh2D';\nimport { Mesh3D } from './Mesh3D';\nimport { Object3DMixin, CObject3D, Constructor } from '../Object3D';\nimport type { VectorObject } from './vectors/VectorObject';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedEntity,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { isHelperableEntity } from './utils';\nimport { BaseObjectState, ObjectTransformState } from 'spline-data';\nimport { omit } from 'lodash-es';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\nimport { TextFrame } from './text';\nimport { SubdivObject } from './subdiv';\n\nexport type Entity =\n\t| CombinedCamera\n\t| EmptyObject\n\t| LightDirectional\n\t| LightPoint\n\t| LightSpot\n\t| Mesh2D\n\t| Mesh3D\n\t| NonParametric\n\t| VectorObject\n\t| SubdivObject\n\t| TextFrame;\n\nexport type LightEntity = LightDirectional | LightPoint | LightSpot;\n\nexport type MeshEntity =\n\t| Mesh2D\n\t| Mesh3D\n\t| NonParametric\n\t| TextFrame\n\t| VectorObject;\n\nexport type HelperableEntity =\n\t| ICombinedCamera\n\t| IEmptyObject\n\t| ILightDirectional\n\t| ILightPoint\n\t| ILightSpot;\n\nexport const isEntity = (object: Object3D): object is Entity =>\n\t'isEntity' in object;\n\nexport const isMeshEntity = (object: Object3D): object is MeshEntity =>\n\t'isAbstractMesh' in object;\n\n/**\n * @privateRemarks\n * There are a few `this as any as Entity` casts here. They are needed\n * because the {@link Entity} type is a union of all types produced using\n * {@link EntityMixin}, but the EntityMixin doesn't know that it will\n * *only be used* in that context.\n */\nexport const EntityMixin = <TBase extends CObject3D>(Base: TBase) =>\n\tclass EntityMixinShim extends Object3DMixin(Base) {\n\t\t// @deprecated avoid using isEntity\n\t\tobjectType: string = '';\n\t\t// @deprecated avoid using isEntity\n\t\tisEntity: boolean = true;\n\t\traycastLock: boolean = false;\n\t\tscaleLock: boolean = false;\n\t\thiddenMatrix: Matrix4 = new Matrix4();\n\t\tinteraction: Interaction | undefined;\n\t\t_singleBBox = new Box3();\n\t\t_recursiveBBox = new Box3();\n\t\tsingleBBoxNeedsUpdate = true;\n\t\trecursiveBBoxNeedsUpdate = true;\n\t\tforceComputeSize: boolean = false;\n\t\tenableHelper?: boolean;\n\n\t\tset visibility(value: boolean) {\n\t\t\tthis.visible = value;\n\t\t\tfor (const child of this.children) {\n\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\tchild.traverseEntity((object) => {\n\t\t\t\t\t\tif (isHelperableEntity(object) && object.visible) {\n\t\t\t\t\t\t\tobject.objectHelper.visible = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tget visibility(): boolean {\n\t\t\treturn this.visible;\n\t\t}\n\n\t\tget singleBBox(): Box3 {\n\t\t\tif (this.singleBBoxNeedsUpdate) {\n\t\t\t\tthis.singleBBoxNeedsUpdate = false;\n\t\t\t\tthis._singleBBox.setFromObjectSize(this as any as Entity, false);\n\t\t\t\tthis._singleBBox.computeVertices();\n\t\t\t\tthis._singleBBox.computeEdges();\n\t\t\t\tthis._singleBBox.computeFaces();\n\t\t\t}\n\t\t\treturn this._singleBBox!;\n\t\t}\n\n\t\tget recursiveBBox(): Box3 {\n\t\t\tif (this.recursiveBBoxNeedsUpdate) {\n\t\t\t\tthis.recursiveBBoxNeedsUpdate = false;\n\t\t\t\tthis._recursiveBBox.setFromObjectSize(this as any as Entity, true);\n\t\t\t\tthis._recursiveBBox.computeVertices();\n\t\t\t\tthis._recursiveBBox.computeEdges();\n\t\t\t\tthis._recursiveBBox.computeFaces();\n\t\t\t}\n\t\t\treturn this._recursiveBBox!;\n\t\t}\n\n\t\tresetBBoxNeedsUpdate() {\n\t\t\tthis.singleBBoxNeedsUpdate = true;\n\t\t\tthis.recursiveBBoxNeedsUpdate = true;\n\t\t\tthis.traverseAncestors((o) => {\n\t\t\t\tif (isEntity(o)) {\n\t\t\t\t\to.singleBBoxNeedsUpdate = true;\n\t\t\t\t\to.recursiveBBoxNeedsUpdate = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.traverseEntity((o) => {\n\t\t\t\to.singleBBoxNeedsUpdate = true;\n\t\t\t\to.recursiveBBoxNeedsUpdate = true;\n\t\t\t});\n\t\t}\n\n\t\ttraverseEntity(callback: (e: Entity) => void): void {\n\t\t\tcallback(this as any as Entity);\n\n\t\t\tfor (const child of this.children) {\n\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\tchild.traverseEntity(callback);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tupdateMatrixWorld(force?: boolean): void {\n\t\t\t// super.updateMatrixWorld(force);\n\t\t\tif (this.matrixAutoUpdate) this.updateMatrix();\n\n\t\t\tif (this.matrixWorldNeedsUpdate || force) {\n\t\t\t\tif (this.parent === null) {\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices(this.hiddenMatrix, this.matrix);\n\t\t\t\t} else {\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices(\n\t\t\t\t\t\tthis.parent.matrixWorld,\n\t\t\t\t\t\tthis.hiddenMatrix\n\t\t\t\t\t);\n\t\t\t\t\tthis.matrixWorld.multiplyMatrices(this.matrixWorld, this.matrix);\n\t\t\t\t}\n\n\t\t\t\tthis.matrixWorldNeedsUpdate = false;\n\t\t\t\tforce = true;\n\t\t\t}\n\n\t\t\tfor (const child of this.children) {\n\t\t\t\tchild.updateMatrixWorld(force);\n\t\t\t}\n\t\t}\n\n\t\tupdateWorldMatrix(updateParents?: boolean, updateChildren?: boolean) {\n\t\t\tconst parent = this.parent;\n\n\t\t\tif (updateParents && parent !== null) {\n\t\t\t\tparent.updateWorldMatrix(true, false);\n\t\t\t}\n\n\t\t\tif (this.matrixAutoUpdate) this.updateMatrix();\n\n\t\t\tif (this.parent === null) {\n\t\t\t\tthis.matrixWorld.multiplyMatrices(this.hiddenMatrix, this.matrix);\n\t\t\t} else {\n\t\t\t\tthis.matrixWorld.multiplyMatrices(\n\t\t\t\t\tthis.parent.matrixWorld,\n\t\t\t\t\tthis.hiddenMatrix\n\t\t\t\t);\n\t\t\t\tthis.matrixWorld.multiplyMatrices(this.matrixWorld, this.matrix);\n\t\t\t}\n\n\t\t\tif (updateChildren) {\n\t\t\t\tfor (const child of this.children) {\n\t\t\t\t\tchild.updateWorldMatrix(false, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tshallowClone(recursive?: boolean): this {\n\t\t\treturn new (this.constructor as any as Constructor<this>)().shallowCopy(\n\t\t\t\tthis,\n\t\t\t\trecursive\n\t\t\t);\n\t\t}\n\n\t\tshallowCopy(source: this, recursive: boolean = true): this {\n\t\t\tsuper.copy(source, false);\n\n\t\t\tthis.raycastLock = source.raycastLock;\n\t\t\tthis.scaleLock = source.scaleLock;\n\t\t\tthis.hiddenMatrix.copy(source.hiddenMatrix);\n\n\t\t\tif (recursive === true) {\n\t\t\t\tfor (const child of source.children) {\n\t\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\t\tthis.add(child.shallowClone());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tclone(recursive?: boolean): this {\n\t\t\treturn new (this.constructor as any as Constructor<this>)().copy(\n\t\t\t\tthis,\n\t\t\t\trecursive\n\t\t\t);\n\t\t}\n\n\t\tcopy(source: this, recursive: boolean = true): this {\n\t\t\tsuper.copy(source, false);\n\n\t\t\tthis.raycastLock = source.raycastLock;\n\t\t\tthis.scaleLock = source.scaleLock;\n\t\t\tthis.hiddenMatrix.copy(source.hiddenMatrix);\n\n\t\t\tif (recursive === true) {\n\t\t\t\tfor (const child of source.children) {\n\t\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\t\tthis.add(child.clone());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tkeepChildrenMatrixWorld() {\n\t\t\tconst m1 = new Matrix4();\n\t\t\tconst prevMatrixWorld = this.matrixWorld.clone();\n\n\t\t\tthis.updateWorldMatrix(false, false);\n\n\t\t\tm1.copy(this.matrixWorld).invert();\n\t\t\tm1.multiply(prevMatrixWorld);\n\n\t\t\tfor (const child of this.children) {\n\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\tchild.hiddenMatrix.premultiply(m1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttoJSON(meta?: Meta): SerializedBase {\n\t\t\tconst data = super.toJSON(meta);\n\t\t\tconst object = data.object as SerializedEntity;\n\n\t\t\tif (this.raycastLock === true) object.raycastLock = true;\n\t\t\tif (this.scaleLock === true) object.scaleLock = true;\n\t\t\tobject.hiddenMatrix = this.hiddenMatrix.toArray();\n\n\t\t\treturn data;\n\t\t}\n\n\t\tfromJSON(data: SerializedEntity): this {\n\t\t\tsuper.fromJSON(data);\n\n\t\t\tif (data.raycastLock !== undefined) this.raycastLock = data.raycastLock;\n\t\t\tif (data.scaleLock !== undefined) this.scaleLock = data.scaleLock;\n\t\t\tthis.hiddenMatrix.fromArray(data.hiddenMatrix);\n\n\t\t\treturn this;\n\t\t}\n\n\t\tfromObject3D(object: Object3D): this {\n\t\t\t// TODO nisa: remove this and override THREE.copy\n\t\t\tconst children = object.children;\n\t\t\tobject.children = [];\n\n\t\t\tObject.assign(object, {\n\t\t\t\traycastLock: false,\n\t\t\t\tscaleLock: false,\n\t\t\t\thiddenMatrix: new Matrix4(),\n\t\t\t});\n\t\t\tthis.copy(object as this);\n\n\t\t\tobject.children = children;\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// @todo check if it can replace getTransformStateFromSpe\n\t\ttoObjectTransformState(\n\t\t\tomited: string[] = []\n\t\t): Partial<ObjectTransformState> {\n\t\t\tthis.updateWorldMatrix(true, false);\n\t\t\tconst data: ObjectTransformState = {\n\t\t\t\tposition: this.position.toArray(),\n\t\t\t\trotation: [this.rotation.x, this.rotation.y, this.rotation.z],\n\t\t\t\tscale: this.scale.toArray(),\n\t\t\t\thiddenMatrix: this.hiddenMatrix.toArray(),\n\t\t\t};\n\t\t\treturn omit(data, omited);\n\t\t}\n\n\t\t// @todo check if it can replace updateObjectTransformState\n\t\tfromObjectTransformState(data: Partial<ObjectTransformState>): this {\n\t\t\tif (data.position) {\n\t\t\t\tthis.position.fromArray(data.position);\n\t\t\t}\n\t\t\tif (data.rotation) {\n\t\t\t\tthis.rotation.fromArray(data.rotation as any);\n\t\t\t}\n\t\t\tif (data.scale) {\n\t\t\t\tthis.scale.fromArray(data.scale);\n\t\t\t}\n\t\t\tif (data.hiddenMatrix) {\n\t\t\t\tthis.hiddenMatrix.fromArray(data.hiddenMatrix);\n\t\t\t}\n\t\t\tthis.updateMatrix();\n\t\t\treturn this;\n\t\t}\n\n\t\t// @todo missing properties\n\t\t// @todo check if it can replace extractSplineDataFromObject\n\t\ttoState(omited: string[] = []): Partial<BaseObjectState> {\n\t\t\tconst data: Partial<BaseObjectState> = {\n\t\t\t\tname: this.name,\n\t\t\t\tvisible: this.visible,\n\t\t\t\traycastLock: this.raycastLock,\n\t\t\t\t// states: new Seq(),\n\t\t\t\t// events: new Seq()\n\t\t\t\t...this.toObjectTransformState(omited),\n\t\t\t};\n\t\t\treturn omit(data, omited);\n\t\t}\n\n\t\t// @todo missing properties\n\t\tfromState(\n\t\t\tdata: Partial<BaseObjectState>,\n\t\t\tsharedAssets?: SharedAssetsManager\n\t\t): this {\n\t\t\tif (data.name) {\n\t\t\t\tthis.name = data.name;\n\t\t\t}\n\t\t\tif (data.raycastLock !== undefined) {\n\t\t\t\tthis.raycastLock = data.raycastLock;\n\t\t\t}\n\t\t\t// @patch OrbitControls updates the camera directly and we are not updating the spline data layer during the mousemove,\n\t\t\t// so the camera matrix cannot be updated\n\t\t\tif (\n\t\t\t\tdata.type !== 'OrthographicCamera' &&\n\t\t\t\tdata.type !== 'PerspectiveCamera'\n\t\t\t) {\n\t\t\t\tthis.matrixAutoUpdate = false;\n\t\t\t}\n\t\t\tif (data.visible !== undefined) {\n\t\t\t\tthis.visibility = data.visible;\n\t\t\t}\n\t\t\tthis.fromObjectTransformState(data);\n\t\t\treturn this;\n\t\t}\n\t};\n", "/**\n * @author nisa\n */\nimport {\n\tBox3 as TBox3,\n\tBufferAttribute,\n\tInterleavedBufferAttribute,\n\tLine3,\n\tMatrix4,\n\tVector3,\n} from 'three';\nimport type { Entity } from '../objects/entities/Entity';\nimport { isMeshEntity, isHelperableEntity } from '../objects/entities/utils';\nimport { Geometry } from '../geometries';\nimport type { SubdivObject } from '..';\n\nconst _box3: TBox3 = new TBox3();\nconst _center: Vector3 = new Vector3();\nconst _halfSize: Vector3 = new Vector3();\nconst _matrix: Matrix4 = new Matrix4();\n\nfunction _setFromBufferAttributeWithDrawRange(\n\tbox3: TBox3,\n\tattribute: BufferAttribute | InterleavedBufferAttribute,\n\tstart: number = 0,\n\tcount: number = attribute.count\n): TBox3 {\n\tlet minX = +Infinity;\n\tlet minY = +Infinity;\n\tlet minZ = +Infinity;\n\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\tlet maxZ = -Infinity;\n\tfor (let i = start; i < count; i++) {\n\t\tconst x = attribute.getX(i);\n\t\tconst y = attribute.getY(i);\n\t\tconst z = attribute.getZ(i);\n\n\t\tif (x < minX) minX = x;\n\t\tif (y < minY) minY = y;\n\t\tif (z < minZ) minZ = z;\n\n\t\tif (x > maxX) maxX = x;\n\t\tif (y > maxY) maxY = y;\n\t\tif (z > maxZ) maxZ = z;\n\t}\n\n\tbox3.min.set(minX, minY, minZ);\n\tbox3.max.set(maxX, maxY, maxZ);\n\n\treturn box3;\n}\n\nconst _traverseSetFromObjectSize = (\n\tnode: Entity,\n\tmatrix: Matrix4,\n\tvertices: Vector3[],\n\tenableHelper: boolean\n) => {\n\tif (isMeshEntity(node)) {\n\t\tconst parameters = (node.geometry as Geometry).userData.parameters;\n\t\tconst positionAttribute = node.geometry.getAttribute('position');\n\n\t\tif (node.geometry.userData.type === 'SubdivGeometry') {\n\t\t\t_center.copy(\n\t\t\t\t(node as SubdivObject).originalGeometry.boundingSphere!.center\n\t\t\t);\n\t\t} else {\n\t\t\t_setFromBufferAttributeWithDrawRange(\n\t\t\t\t_box3,\n\t\t\t\tpositionAttribute,\n\t\t\t\tnode.geometry.drawRange.start,\n\t\t\t\tnode.geometry.drawRange.count < Infinity\n\t\t\t\t\t? node.geometry.drawRange.count\n\t\t\t\t\t: positionAttribute.count\n\t\t\t);\n\t\t\t_box3.getCenter(_center);\n\t\t}\n\n\t\tif (node.forceComputeSize) {\n\t\t\t_box3.getSize(_halfSize).multiplyScalar(0.5);\n\t\t} else {\n\t\t\t_halfSize\n\t\t\t\t.set(parameters.width, parameters.height, parameters.depth ?? 0) // TODO reconcile with AbstractMesh and Spline Geometry\n\t\t\t\t.multiplyScalar(0.5);\n\t\t}\n\t} else if (isHelperableEntity(node) && enableHelper === true) {\n\t\tconst positionAttribute = node.geometryHelper.getAttribute('position');\n\t\t_box3.setFromArray(positionAttribute.array);\n\t\t_box3.getCenter(_center);\n\t\t_box3.getSize(_halfSize).multiplyScalar(0.5);\n\t} else {\n\t\t_center.setScalar(0);\n\t\t_halfSize.setScalar(0);\n\t}\n\n\t_matrix.copy(matrix).multiply(node.matrixWorld);\n\n\tif (_halfSize.x === 0 && _halfSize.y === 0 && _halfSize.z === 0) {\n\t\tvertices.push(\n\t\t\tnew Vector3(_center.x, _center.y, _center.z).applyMatrix4(_matrix)\n\t\t);\n\t} else {\n\t\t/* vertices\n\t\t\t 4____7\n\t\t\t0/___3/|\n\t\t\t| 5__|_6\n\t\t\t1/___2/\n\t\t*/\n\t\tvertices.push(\n\t\t\tnew Vector3(-_halfSize.x, _halfSize.y, _halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(-_halfSize.x, -_halfSize.y, _halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(_halfSize.x, -_halfSize.y, _halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(_halfSize.x, _halfSize.y, _halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(-_halfSize.x, _halfSize.y, -_halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(-_halfSize.x, -_halfSize.y, -_halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(_halfSize.x, -_halfSize.y, -_halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix),\n\t\t\tnew Vector3(_halfSize.x, _halfSize.y, -_halfSize.z)\n\t\t\t\t.add(_center)\n\t\t\t\t.applyMatrix4(_matrix)\n\t\t);\n\t}\n};\n\nexport class Box3 extends TBox3 {\n\tmatrix: Matrix4 = new Matrix4();\n\tvertices: Vector3[] = [];\n\tfaces: Vector3[] = [];\n\tedges: Line3[] = [];\n\tcenterEdges: Vector3[] = [];\n\n\tcopy(box: this): this {\n\t\tsuper.copy(box);\n\t\tthis.matrix.copy(box.matrix);\n\t\tthis.vertices = box.vertices.map((v) => v.clone());\n\t\tthis.faces = box.faces.map((f) => f.clone());\n\t\tthis.edges = box.edges.map((e) => e.clone());\n\t\tthis.centerEdges = box.centerEdges.map((c) => c.clone());\n\t\treturn this;\n\t}\n\n\tsetFromObjectSize(object: Entity, recursive: boolean = false): this {\n\t\tobject.updateWorldMatrix(false, recursive);\n\t\tthis.makeEmpty();\n\t\tthis.matrix.copy(object.matrixWorld);\n\t\tconst inverseTransform = new Matrix4().copy(object.matrixWorld).invert();\n\t\treturn this.expandByObjectSize(object, inverseTransform, recursive);\n\t}\n\n\texpandByObjectSize(\n\t\tobject: Entity,\n\t\tmatrix: Matrix4,\n\t\trecursive: boolean = false\n\t): this {\n\t\tconst vertices: Vector3[] = [];\n\n\t\tif (recursive === true) {\n\t\t\tobject.traverseEntity((node: Entity) =>\n\t\t\t\t_traverseSetFromObjectSize(\n\t\t\t\t\tnode,\n\t\t\t\t\tmatrix,\n\t\t\t\t\tvertices,\n\t\t\t\t\tobject.enableHelper === true\n\t\t\t\t)\n\t\t\t);\n\t\t} else {\n\t\t\t_traverseSetFromObjectSize(\n\t\t\t\tobject,\n\t\t\t\tmatrix,\n\t\t\t\tvertices,\n\t\t\t\tobject.enableHelper === true\n\t\t\t);\n\t\t}\n\n\t\treturn this.setFromPoints(vertices);\n\t}\n\n\tgetCenter(target: Vector3): Vector3 {\n\t\ttarget = super.getCenter(target);\n\t\ttarget.applyMatrix4(this.matrix);\n\t\treturn target;\n\t}\n\n\tgetPositionToCenter(target: Vector3): Vector3 {\n\t\ttarget = super.getCenter(target);\n\t\ttarget.applyMatrix4(_matrix.copy(this.matrix).setPosition(0, 0, 0));\n\t\treturn target;\n\t}\n\n\tcomputeVertices(): void {\n\t\tthis.getSize(_halfSize).multiplyScalar(0.5);\n\t\tthis.getCenter(_center);\n\t\t_matrix.copy(this.matrix).setPosition(_center);\n\n\t\t/* vertices\n\t\t\t 4____7\n\t\t\t0/___3/|\n\t\t\t| 5__|_6\n\t\t\t1/___2/\n\t\t*/\n\t\tthis.vertices = [\n\t\t\tnew Vector3(-_halfSize.x, _halfSize.y, _halfSize.z).applyMatrix4(_matrix),\n\t\t\tnew Vector3(-_halfSize.x, -_halfSize.y, _halfSize.z).applyMatrix4(\n\t\t\t\t_matrix\n\t\t\t),\n\t\t\tnew Vector3(_halfSize.x, -_halfSize.y, _halfSize.z).applyMatrix4(_matrix),\n\t\t\tnew Vector3(_halfSize.x, _halfSize.y, _halfSize.z).applyMatrix4(_matrix),\n\t\t\tnew Vector3(-_halfSize.x, _halfSize.y, -_halfSize.z).applyMatrix4(\n\t\t\t\t_matrix\n\t\t\t),\n\t\t\tnew Vector3(-_halfSize.x, -_halfSize.y, -_halfSize.z).applyMatrix4(\n\t\t\t\t_matrix\n\t\t\t),\n\t\t\tnew Vector3(_halfSize.x, -_halfSize.y, -_halfSize.z).applyMatrix4(\n\t\t\t\t_matrix\n\t\t\t),\n\t\t\tnew Vector3(_halfSize.x, _halfSize.y, -_halfSize.z).applyMatrix4(_matrix),\n\t\t];\n\t}\n\n\tcomputeEdges() {\n\t\tif (this.vertices.length > 0) {\n\t\t\tthis.computeVertices();\n\t\t}\n\n\t\t/* vertices and edges\n\t\t\t 4____7 __3_ ____ ____\n\t\t\t0/___3/| /__0 /| /___ /| 8/___11|\n\t\t\t| 5__|_6 | |_2|_| 4 7__5_6 | |__|_|\n\t\t\t1/___2/\t |/_1_|/ |/___|/ |9___|10\n\t\t*/\n\t\tthis.edges = [\n\t\t\tnew Line3(this.vertices[0], this.vertices[3]),\n\t\t\tnew Line3(this.vertices[1], this.vertices[2]),\n\t\t\tnew Line3(this.vertices[5], this.vertices[6]),\n\t\t\tnew Line3(this.vertices[4], this.vertices[7]),\n\t\t\tnew Line3(this.vertices[0], this.vertices[1]),\n\t\t\tnew Line3(this.vertices[3], this.vertices[2]),\n\t\t\tnew Line3(this.vertices[7], this.vertices[6]),\n\t\t\tnew Line3(this.vertices[4], this.vertices[5]),\n\t\t\tnew Line3(this.vertices[0], this.vertices[4]),\n\t\t\tnew Line3(this.vertices[1], this.vertices[5]),\n\t\t\tnew Line3(this.vertices[2], this.vertices[6]),\n\t\t\tnew Line3(this.vertices[3], this.vertices[7]),\n\t\t];\n\n\t\tthis.centerEdges = this.edges.map((edge) => edge.getCenter(new Vector3()));\n\t}\n\n\tcomputeFaces() {\n\t\tif (this.vertices.length > 0) {\n\t\t\tthis.computeVertices();\n\t\t}\n\n\t\t/* vertices and faces\n\t\t\t 4____7\t\t\t\t \t ____ __ __ ____\n\t\t\t0/___3/|\t\t/___ / /| 1 /| /|__ __ /| /|_4_/|\n\t\t\t| 5__|_6\t\t| 0 | |____| |2|__ __|3| | | |____|\n\t\t\t1/___2/\t\t |/___|/ / / |/__ __|/ |/_5_|/\n\t\t*/\n\n\t\tthis.faces = [\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[0])\n\t\t\t\t.sub(this.vertices[2])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[2]),\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[7])\n\t\t\t\t.sub(this.vertices[5])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[5]),\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[4])\n\t\t\t\t.sub(this.vertices[1])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[1]),\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[3])\n\t\t\t\t.sub(this.vertices[6])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[6]),\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[4])\n\t\t\t\t.sub(this.vertices[3])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[3]),\n\t\t\tnew Vector3()\n\t\t\t\t.copy(this.vertices[1])\n\t\t\t\t.sub(this.vertices[6])\n\t\t\t\t.multiplyScalar(0.5)\n\t\t\t\t.add(this.vertices[6]),\n\t\t];\n\t}\n}\n", "import {\n\tBaseLightState,\n\tBaseObjectState,\n\tCameraState,\n\tMatrix,\n\tObjectTransformState,\n\tTransformState,\n} from 'spline-data';\nimport {\n\tBoxBufferGeometry,\n\tDirectionalLight,\n\tHemisphereLight,\n\tObject3D,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n} from 'three';\nimport { CombinedCamera } from './';\nimport { LightDirectional, LightPoint, LightSpot } from '../entities';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\nimport { getSharedColorData } from '../../shared/utils';\nimport type {\n\tEntity,\n\tHelperableEntity,\n\tLightEntity,\n\tMeshEntity,\n} from './Entity';\nimport { NonParametric } from './NonParametric';\n\nexport const isEntity = (object: Object3D): object is Entity =>\n\t'isEntity' in object;\n\nexport const isMeshEntity = (object: Object3D): object is MeshEntity =>\n\t'isAbstractMesh' in object;\n\nexport const isCombinedCamera = (object: Object3D): object is CombinedCamera =>\n\tisEntity(object) && object.objectType === 'CombinedCamera';\n\nexport const isLight = (object: Object3D): object is LightEntity =>\n\tisEntity(object) &&\n\t(object.objectType === 'LightDirectional' ||\n\t\tobject.objectType === 'LightSpot' ||\n\t\tobject.objectType === 'LightPoint');\n\nexport const isNonParametric = (object: Entity): object is NonParametric =>\n\tobject.objectType === 'NonParametric';\n\nexport const isHelperableEntity = (\n\tobject: Object3D\n): object is HelperableEntity & {\n\tobjectHelper: Object3D;\n\tgeometryHelper: BoxBufferGeometry;\n} => 'objectHelper' in object;\n\nexport function updateObjectTransformState(\n\tobj: Object3D,\n\tdata: Partial<ObjectTransformState>\n) {\n\tlet transformUpdated = false;\n\tif (data.position) {\n\t\tobj.position.fromArray(data.position as unknown as number[]);\n\t\ttransformUpdated = true;\n\t}\n\tif (data.rotation) {\n\t\tobj.rotation.fromArray(data.rotation as unknown as number[]);\n\t\ttransformUpdated = true;\n\t}\n\tif (data.scale) {\n\t\ttransformUpdated = true;\n\t\tobj.scale.fromArray(data.scale as unknown as number[]);\n\t}\n\tif (data.hiddenMatrix !== undefined && 'hiddenMatrix' in obj) {\n\t\ttransformUpdated = true;\n\t\t(obj as Entity).hiddenMatrix.fromArray(\n\t\t\tdata.hiddenMatrix ?? Matrix.identity\n\t\t);\n\t}\n\tif (transformUpdated) {\n\t\tobj.updateMatrix();\n\t}\n\n\t/*\n\t\tWe need this after transform update from matrix decomposition such as in GroupMatrixUpdater\n\t*/\n\tif (\n\t\tdata.position &&\n\t\tdata.rotation &&\n\t\tdata.scale &&\n\t\tdata.hiddenMatrix !== undefined\n\t) {\n\t\tobj.updateWorldMatrix(false, true);\n\t}\n\n\tif ((obj as Entity).objectType === 'CombinedCamera') {\n\t\tif ((data as CameraState).isUpVectorFlipped !== undefined) {\n\t\t\t(obj as CombinedCamera).isUpVectorFlipped = (\n\t\t\t\tdata as CameraState\n\t\t\t).isUpVectorFlipped;\n\t\t}\n\t\t(obj as CombinedCamera).updateUp();\n\t}\n}\n\nexport function updateObjectBaseProps(\n\tobj: Entity,\n\tdata: Partial<BaseObjectState>\n) {\n\tupdateObjectTransformState(obj, data);\n\tif (data.name !== undefined) {\n\t\tobj.name = data.name;\n\t}\n\tif (data.visible !== undefined) {\n\t\tif (obj.isEntity) {\n\t\t\tobj.visibility = data.visible;\n\t\t} else {\n\t\t\t// TODO this is for ambient light\n\t\t\tobj.visible = data.visible;\n\t\t}\n\t}\n}\n\n// @todo mix updateLightBaseProps and fromLightState\n// should we migrate HemisphereLight and DirectionalLight to spe lights?\nexport function updateLightBaseProps(\n\tlight:\n\t\t| LightDirectional\n\t\t| LightSpot\n\t\t| HemisphereLight\n\t\t| LightPoint\n\t\t| DirectionalLight,\n\tdata: Partial<BaseLightState>,\n\tsharedAssets: SharedAssetsManager\n) {\n\tupdateObjectBaseProps(light as Entity, data);\n\tif (data.color !== undefined) {\n\t\tlight.color = getSharedColorData(data.color, sharedAssets);\n\t}\n\tif (data.intensity !== undefined) {\n\t\tlight.intensity = data.intensity;\n\t}\n\tif (data.shadows !== undefined && !(light instanceof HemisphereLight)) {\n\t\tlight.castShadow = data.shadows;\n\t}\n\tif (light.shadow && !(light instanceof HemisphereLight)) {\n\t\tif (data.depth !== undefined) {\n\t\t\t(light.shadow.camera as PerspectiveCamera | OrthographicCamera).far =\n\t\t\t\tdata.depth;\n\t\t\tlight.shadow.needsUpdate = true;\n\t\t}\n\t}\n\tif (data.helper !== undefined) {\n\t\tif (isHelperableEntity(light)) {\n\t\t\t(light as LightSpot).enableHelper = data.helper;\n\t\t\t(light as LightSpot).gizmos.shadowmap.visible = data.helper;\n\t\t}\n\t}\n}\n\nexport function setLightSize(light: DirectionalLight, value: number) {\n\tlight.shadow.camera.right = value / 2;\n\tlight.shadow.camera.left = -value / 2;\n\tlight.shadow.camera.top = value / 2;\n\tlight.shadow.camera.bottom = -value / 2;\n\tlight.shadow.needsUpdate = true;\n}\n\nexport function getTransformStateFromSpe(object: Object3D): TransformState {\n\tobject.updateWorldMatrix(true, false);\n\tlet { position, rotation, scale } = object;\n\treturn {\n\t\tposition: position.toArray() as TransformState['position'],\n\t\trotation: [rotation.x, rotation.y, rotation.z],\n\t\tscale: scale.toArray() as TransformState['scale'],\n\t};\n}\n\n/**\n * Replaced oldChild by newChild in oldChild's parent if it exists\n * @param oldChild\n * @param newChild\n */\nexport function replaceInParent(oldChild: Entity, newChild: Entity) {\n\tconst parent = oldChild.parent;\n\tconst index = parent?.children.indexOf(oldChild);\n\tparent?.remove(oldChild);\n\tparent?.add(newChild);\n\tif (index !== undefined) {\n\t\tparent?.children.splice(index, 0, parent.children.pop()!);\n\t}\n}\n", "import { Color } from 'three';\n\nexport class ColorA extends Color {\n\ta: number;\n\tconstructor(r: number, g: number, b: number, a: number) {\n\t\tsuper(r, g, b);\n\t\tthis.a = a;\n\t}\n\n\tsetRGBA(r: number, g: number, b: number, a: number) {\n\t\tsuper.setRGB(r, g, b);\n\t\tthis.a = a;\n\t}\n\n\t/*\n\t * Getters and setters needed for when this\n\t * class functions as a Vector4 stand-in\n\t */\n\tget x(): number {\n\t\treturn this.r;\n\t}\n\n\tget y(): number {\n\t\treturn this.g;\n\t}\n\n\tget z(): number {\n\t\treturn this.b;\n\t}\n\n\tget w(): number {\n\t\treturn this.a;\n\t}\n\n\tset x(x) {\n\t\tthis.r = x;\n\t}\n\tset y(y) {\n\t\tthis.g = y;\n\t}\n\tset z(z) {\n\t\tthis.b = z;\n\t}\n\tset w(w) {\n\t\tthis.a = w;\n\t}\n}\n", "import { RGB, RGBA, Sharable } from 'spline-data';\nimport { SharedAssetsManager } from './SharedAssetsManager';\nimport { ColorA } from '../objects/Color';\n\nexport function getSharedColorData(\n\tcolor: Sharable<RGB | RGBA>,\n\tsharedAssets: SharedAssetsManager\n): ColorA {\n\tlet outColor: ColorA;\n\tif (typeof color === 'string') {\n\t\tconst sharedColor = sharedAssets?.getColor(color);\n\t\tif (!sharedColor) {\n\t\t\tconsole.warn(\n\t\t\t\t'Tried to create color layer params with a color key that does not exist in the assets manager'\n\t\t\t);\n\t\t\toutColor = new ColorA(0, 0, 0, 0);\n\t\t} else {\n\t\t\toutColor = sharedColor;\n\t\t}\n\t} else {\n\t\tif ('a' in color) {\n\t\t\treturn new ColorA(color.r, color.g, color.b, color.a);\n\t\t} else {\n\t\t\treturn new ColorA(color.r, color.g, color.b, 1);\n\t\t}\n\t}\n\treturn outColor;\n}\n\nexport function getSharedColorDataAsHex(\n\tcolor: Sharable<RGB | RGBA>,\n\tsharedAssets: SharedAssetsManager\n) {\n\tlet outColor = getSharedColorData(color, sharedAssets);\n\toutColor.getHex();\n}\n", "import { Object3D, Matrix4, Light } from 'three';\nimport {\n\textractFromCache,\n\textractFromCacheNonMetadata,\n} from '../fileManager/object/ObjectExporter';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedObject,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { isEntity } from './entities/utils';\n\nexport type Constructor<T> = new (...args: any[]) => T;\nexport type CObject3D = Constructor<Object3D>;\n\nexport const Object3DMixin = <TBase extends CObject3D>(Base: TBase) =>\n\tclass SPEObjectMixinShim extends Base {\n\t\thasEntityChild(): boolean {\n\t\t\treturn this.children.some((child) => isEntity(child));\n\t\t}\n\n\t\tisDescendantOf(object: Object3D | string): boolean {\n\t\t\tif (object instanceof Object3D) {\n\t\t\t\tobject = object.uuid;\n\t\t\t}\n\t\t\tlet child: Object3D = this;\n\t\t\twhile (child.parent) {\n\t\t\t\tif (child.parent.uuid === object) return true;\n\t\t\t\tchild = child.parent;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// override\n\t\tattach(object: Object3D, index?: number): this {\n\t\t\t// adds object as a child of this, while maintaining the object's world transform\n\t\t\tthis.updateWorldMatrix(true, false);\n\t\t\tconst mat = new Matrix4().copy(this.matrixWorld).invert();\n\n\t\t\tif (object.parent !== null) {\n\t\t\t\tobject.parent.updateWorldMatrix(true, false);\n\t\t\t\tmat.multiply(object.parent.matrixWorld);\n\t\t\t}\n\n\t\t\tif (isEntity(object)) {\n\t\t\t\tobject.hiddenMatrix.premultiply(mat);\n\t\t\t} else {\n\t\t\t\tobject.applyMatrix4(mat);\n\t\t\t}\n\n\t\t\tobject.updateWorldMatrix(false, false);\n\t\t\tthis.add(object);\n\n\t\t\tif (index !== undefined) {\n\t\t\t\tthis.children.pop();\n\t\t\t\tthis.children.splice(index, 0, object);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tcopy(source: Object3D, recursive: boolean = true) {\n\t\t\tthis.name = source.name;\n\n\t\t\tthis.up.copy(source.up);\n\n\t\t\tthis.position.copy(source.position);\n\t\t\tthis.rotation.order = source.rotation.order;\n\t\t\tthis.quaternion.copy(source.quaternion);\n\t\t\tthis.scale.copy(source.scale);\n\n\t\t\tthis.matrix.copy(source.matrix);\n\t\t\tthis.matrixWorld.copy(source.matrixWorld);\n\n\t\t\tthis.matrixAutoUpdate = source.matrixAutoUpdate;\n\t\t\tthis.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;\n\n\t\t\tthis.layers.mask = source.layers.mask;\n\t\t\tthis.visible = source.visible;\n\n\t\t\tthis.castShadow = source.castShadow;\n\t\t\tthis.receiveShadow = source.receiveShadow;\n\n\t\t\tthis.frustumCulled = source.frustumCulled;\n\t\t\tthis.renderOrder = source.renderOrder;\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tthis.userData = JSON.parse(JSON.stringify(source.userData));\n\n\t\t\tif (recursive === true) {\n\t\t\t\tfor (let i = 0; i < source.children.length; i++) {\n\t\t\t\t\tconst child = source.children[i];\n\t\t\t\t\tthis.add(child.clone());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// override\n\t\t// TODO nisa\n\t\t// toJSON(): SerializedBase {\n\t\t// \tconst object: SerializedObject = {\n\t\t// \t\tuuid: this.uuid,\n\t\t// \t\tobjectType: this.type,\n\t\t// \t};\n\t\t// \tconst data: SerializedBase = { object };\n\n\t\t// \tif (this.name !== '') object.name = this.name;\n\t\t// \tobject.matrix = this.matrix.toArray();\n\t\t// \tif (this.castShadow === true) object.castShadow = true;\n\t\t// \tif (this.receiveShadow === true) object.receiveShadow = true;\n\t\t// \tif (this.visible === false) object.visible = false;\n\t\t// \tif (this.frustumCulled === false) object.frustumCulled = false;\n\t\t// \tif (this.renderOrder !== 0) object.renderOrder = this.renderOrder;\n\t\t// \tobject.layers = this.layers.mask;\n\t\t// \tif (JSON.stringify(this.userData) !== '{}')\n\t\t// \t\tobject.userData = this.userData;\n\n\t\t// \treturn data;\n\t\t// }\n\n\t\ttoJSON(meta?: Meta): SerializedBase {\n\t\t\t// meta is a string when called from JSON.stringify\n\t\t\tconst isRootObject = meta === undefined;\n\t\t\tconst data: SerializedBase = { object: { uuid: '', objectType: '' } };\n\n\t\t\t// meta is a hash used to collect geometries, materials.\n\t\t\t// not providing it implies that this is the root object\n\t\t\t// being serialized.\n\t\t\tif (meta === undefined) {\n\t\t\t\tmeta = {\n\t\t\t\t\tgeometries: {},\n\t\t\t\t\tmaterials: {},\n\t\t\t\t\ttextures: {},\n\t\t\t\t\timages: {},\n\t\t\t\t\tinteractionStates: {},\n\t\t\t\t\tnodes: {},\n\t\t\t\t};\n\t\t\t\tdata.metadata = {\n\t\t\t\t\t// TODO fix files with version 4.5 (e.g: iPhone from Spline Library)\n\t\t\t\t\t// Don't use 4.5 (the first files were using 4.5)\n\t\t\t\t\tversion: 1.5,\n\t\t\t\t\ttype: 'Object',\n\t\t\t\t\tgenerator: 'Object3D.toJSON',\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst object: SerializedObject = {\n\t\t\t\tuuid: this.uuid,\n\t\t\t\tobjectType: this.type,\n\t\t\t};\n\n\t\t\tif (this.name !== '') object.name = this.name;\n\t\t\tobject.matrix = this.matrix.toArray();\n\t\t\tif (this.castShadow === true) object.castShadow = true;\n\t\t\tif (this.receiveShadow === true) object.receiveShadow = true;\n\t\t\tif (this.visible === false) object.visible = false;\n\t\t\tif (this.frustumCulled === false) object.frustumCulled = false;\n\t\t\tif (this.renderOrder !== 0) object.renderOrder = this.renderOrder;\n\t\t\tobject.layers = this.layers.mask;\n\t\t\tif (JSON.stringify(this.userData) !== '{}')\n\t\t\t\tobject.userData = this.userData;\n\n\t\t\tif (this.children.length > 0) {\n\t\t\t\tobject.children = [];\n\n\t\t\t\tfor (const child of this.children) {\n\t\t\t\t\t// PATCH nisa: check with Light to serialize the default lights, but we need to use spline lights\n\t\t\t\t\tif (isEntity(child) || child instanceof Light) {\n\t\t\t\t\t\tobject.children.push(child.toJSON(meta).object);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isRootObject) {\n\t\t\t\tconst geometries = extractFromCache(meta.geometries);\n\t\t\t\tconst materials = extractFromCache(meta.materials);\n\t\t\t\tconst textures = extractFromCache(meta.textures);\n\t\t\t\tconst images = extractFromCache(meta.images);\n\t\t\t\tconst interactionStates = extractFromCache(meta.interactionStates);\n\t\t\t\tconst nodes = extractFromCacheNonMetadata(meta.nodes);\n\n\t\t\t\tif (geometries.length > 0) data.geometries = geometries;\n\t\t\t\tif (materials.length > 0) data.materials = materials;\n\t\t\t\tif (textures.length > 0) data.textures = textures;\n\t\t\t\tif (images.length > 0) data.images = images;\n\t\t\t\tif (interactionStates.length > 0)\n\t\t\t\t\tdata.interactionStates = interactionStates;\n\t\t\t\tif (nodes.length > 0) data.nodes = nodes;\n\t\t\t}\n\n\t\t\tdata.object = object;\n\n\t\t\treturn data;\n\t\t}\n\n\t\tfromJSON(data: SerializedObject): this {\n\t\t\tthis.uuid = data.uuid;\n\n\t\t\tif (data.name !== undefined) this.name = data.name;\n\n\t\t\tif (data.matrix !== undefined) {\n\t\t\t\tthis.matrix.fromArray(data.matrix);\n\n\t\t\t\tif (data.matrixAutoUpdate !== undefined)\n\t\t\t\t\tthis.matrixAutoUpdate = data.matrixAutoUpdate;\n\t\t\t\tif (this.matrixAutoUpdate)\n\t\t\t\t\tthis.matrix.decompose(this.position, this.quaternion, this.scale);\n\t\t\t} else {\n\t\t\t\tif (data.position !== undefined) this.position.fromArray(data.position);\n\t\t\t\tif (data.rotation !== undefined) this.rotation.fromArray(data.rotation);\n\t\t\t\tif (data.quaternion !== undefined)\n\t\t\t\t\tthis.quaternion.fromArray(data.quaternion);\n\t\t\t\tif (data.scale !== undefined) this.scale.fromArray(data.scale);\n\t\t\t}\n\n\t\t\tthis.castShadow = data.castShadow !== undefined ? true : false;\n\t\t\tthis.receiveShadow = data.receiveShadow !== undefined ? true : false;\n\t\t\tif (data.visible !== undefined) this.visible = data.visible;\n\t\t\tif (data.frustumCulled !== undefined)\n\t\t\t\tthis.frustumCulled = data.frustumCulled;\n\t\t\tif (data.renderOrder !== undefined) this.renderOrder = data.renderOrder;\n\t\t\tif (data.layers !== undefined) this.layers.mask = data.layers;\n\t\t\tif (data.userData !== undefined) this.userData = data.userData;\n\n\t\t\treturn this;\n\t\t}\n\t};\n", "/**\n * @author nisa\n */\n\nimport {\n\tBufferGeometry,\n\tGroup,\n\tMaterial,\n\tMesh,\n\tMeshStandardMaterial,\n} from 'three';\nimport { IGeometry } from '../../geometries/Geometry';\nimport {\n\tNonParametricGeometry,\n\tNonParametricGeometryOutput,\n} from '../../geometries/NonParametricGeometry';\nimport { VectorGeometryInputs } from '../../geometries/vectors/VectorGeometry';\nimport { separateGroups } from '../../util';\nimport { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';\nimport { Meta, Metadata, SerializedGeometry } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { dracoEncoder } from './draco-encoder';\nimport type { GLTF } from '@gltf-transform/core';\nimport base64js from 'base64-js';\nimport { cloneDeep } from 'lodash-es';\n\nexport const exporterConfig: {\n\tisPublish: boolean;\n\tgltfQueue: Promise<void>[];\n} = {\n\tisPublish: false,\n\tgltfQueue: [],\n};\n\nexport function serialize<\n\tS extends { uuid: string },\n\tE extends { uuid: string; toJSON: (meta?: Meta) => S }\n>(library: { [key: string]: S }, element: E, meta?: Meta): string {\n\tif (library[element.uuid] === undefined) {\n\t\tlibrary[element.uuid] = element.toJSON(meta);\n\t}\n\n\treturn element.uuid;\n}\n\nconst gltfExporter = new GLTFExporter();\n\nexport function serializeGeometry(\n\tlibrary: { [key: string]: SerializedGeometry },\n\tgeometry: BufferGeometry,\n\tmaterial: Material | Material[]\n\t// meta?: Meta\n): string {\n\tif (library[geometry.uuid] === undefined) {\n\t\tif (\n\t\t\tgeometry.userData.type === 'NonParametricGeometry' ||\n\t\t\tgeometry.userData.type === 'SubdivGeometry'\n\t\t) {\n\t\t\t// SubdivGeometry Only:\n\t\t\t// - Delete attributes that unecessary for exporting and saving\n\t\t\t// - they are different for each case\n\t\t\t// - if left undeleted, the extra attributes actually break the export\n\t\t\tif (geometry.userData.type === 'SubdivGeometry') {\n\t\t\t\tif (exporterConfig.isPublish) {\n\t\t\t\t\tgeometry = NonParametricGeometry.create({\n\t\t\t\t\t\tgeometry: geometry.clone(),\n\t\t\t\t\t});\n\n\t\t\t\t\t// Delete broken attributes that break the export\n\t\t\t\t\tif (\n\t\t\t\t\t\t(geometry.userData.parameters as { subdivisions: number })\n\t\t\t\t\t\t\t.subdivisions === 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdelete geometry.attributes.color;\n\t\t\t\t\t\tdelete geometry.attributes.faceMap;\n\t\t\t\t\t\tdelete geometry.attributes.positionWASM;\n\t\t\t\t\t\tdelete geometry.attributes.indexWASM;\n\t\t\t\t\t\tdelete geometry.attributes.verticesPerFaceWASM;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// howard: there are keys in the base mesh that are not needed for the\n\t\t\t\t\t// recreation of the object, so we can delete them to reduce filesize\n\t\t\t\t\t// because all keys are still needed for the current scene on screen\n\t\t\t\t\t// we have to clone the geometry, delete the keys, and reassign back\n\t\t\t\t\t// to variable geometry to be serialized\n\n\t\t\t\t\t// if originalGeometry exists, baseGeom === originalGeometry,\n\t\t\t\t\t// else, baseGeom === geometry\n\n\t\t\t\t\tconst originalGeom = (geometry as NonParametricGeometryOutput)\n\t\t\t\t\t\t.originalGeometry;\n\n\t\t\t\t\tif (originalGeom) {\n\t\t\t\t\t\tconst userData = geometry.userData;\n\t\t\t\t\t\tgeometry = originalGeom.clone();\n\t\t\t\t\t\tgeometry.userData = userData;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgeometry = geometry.clone();\n\t\t\t\t\t}\n\n\t\t\t\t\tdelete geometry.attributes.color;\n\t\t\t\t\tdelete geometry.attributes.faceMap;\n\t\t\t\t\tdelete geometry.attributes.position;\n\t\t\t\t\tdelete geometry.attributes.normal;\n\t\t\t\t\tgeometry.index = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// When we save a modified NonParametric we want to save the original geometry\n\t\t\t// and not the modified one + we add our modification parameters\n\t\t\tconst originalGeometry = (geometry as NonParametricGeometryOutput)\n\t\t\t\t.originalGeometry;\n\t\t\tif (originalGeometry !== undefined) {\n\t\t\t\tconst userData = geometry.userData;\n\t\t\t\tgeometry = originalGeometry;\n\t\t\t\tgeometry.userData = userData;\n\t\t\t}\n\n\t\t\t// @patch nisa: improve saving geometry in .spline and keep only one of these\n\t\t\tif (!exporterConfig.isPublish) {\n\t\t\t\tlibrary[geometry.uuid] = geometry.toJSON() as SerializedGeometry;\n\t\t\t} else {\n\t\t\t\tconst serializedGeometry: SerializedGeometry = {\n\t\t\t\t\ttype: 'NonParametricGeometry',\n\t\t\t\t\tuuid: geometry.uuid,\n\t\t\t\t\tuserData: {},\n\t\t\t\t};\n\n\t\t\t\tif (geometry.name !== '') serializedGeometry.name = geometry.name;\n\n\t\t\t\tif (Object.keys(geometry.userData).length > 0) {\n\t\t\t\t\tserializedGeometry.userData = { ...geometry.userData };\n\t\t\t\t}\n\n\t\t\t\t// save the gltf in the .gltf key\n\t\t\t\tlet isNonIndexed = geometry.index === null;\n\t\t\t\tconst tempGroup = new Group();\n\t\t\t\tif (Array.isArray(material)) {\n\t\t\t\t\tconst geometries = separateGroups(geometry);\n\t\t\t\t\tgeometries.forEach((geom, i) => {\n\t\t\t\t\t\tconst tempMesh = new Mesh(geom, new MeshStandardMaterial());\n\t\t\t\t\t\ttempGroup.add(tempMesh);\n\n\t\t\t\t\t\t// save the index to later reorder them correctly.\n\t\t\t\t\t\t// workaround for https://github.com/mrdoob/three.js/issues/15561\n\t\t\t\t\t\tgeom.userData.groupIndex = i;\n\t\t\t\t\t\tgeom.userData.materialIndex = geometry.groups[i].materialIndex;\n\n\t\t\t\t\t\tif (geom.index === null) {\n\t\t\t\t\t\t\tisNonIndexed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst tempMesh = new Mesh(geometry, new MeshStandardMaterial());\n\t\t\t\t\ttempGroup.add(tempMesh);\n\t\t\t\t}\n\n\t\t\t\texporterConfig.gltfQueue.push(\n\t\t\t\t\tnew Promise(async (resolve) => {\n\t\t\t\t\t\t// wait for the queue before this,\n\t\t\t\t\t\t// multiple compression in parallel may make\n\t\t\t\t\t\t// the browser run out of wasm memory\n\t\t\t\t\t\tawait Promise.all(exporterConfig.gltfQueue);\n\n\t\t\t\t\t\tgltfExporter.parse(\n\t\t\t\t\t\t\ttempGroup,\n\t\t\t\t\t\t\tasync (gltf) => {\n\t\t\t\t\t\t\t\t// load the draco encoder library, if it's already loaded\n\t\t\t\t\t\t\t\t// this gets called immediately\n\t\t\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\t\t\tgltfTransform,\n\t\t\t\t\t\t\t\t\tDracoMeshCompressionExtension,\n\t\t\t\t\t\t\t\t\taddIndex,\n\t\t\t\t\t\t\t\t} = await dracoEncoder;\n\n\t\t\t\t\t\t\t\tconst doc = gltfTransform.readJSON({\n\t\t\t\t\t\t\t\t\t// readJSON modifies the object, so cloneDeep is necessary\n\t\t\t\t\t\t\t\t\tjson: cloneDeep(gltf) as GLTF.IGLTF,\n\t\t\t\t\t\t\t\t\tresources: {}, // no external resources\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// enable draco compression\n\t\t\t\t\t\t\t\tdoc\n\t\t\t\t\t\t\t\t\t.createExtension(DracoMeshCompressionExtension)\n\t\t\t\t\t\t\t\t\t.setRequired(true)\n\t\t\t\t\t\t\t\t\t.setEncoderOptions({\n\t\t\t\t\t\t\t\t\t\t// https://github.com/google/draco/issues/713\n\t\t\t\t\t\t\t\t\t\tquantizationVolume: 'scene',\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t// https://github.com/donmccurdy/glTF-Transform/discussions/394\n\t\t\t\t\t\t\t\tif (isNonIndexed) {\n\t\t\t\t\t\t\t\t\tawait doc.transform(addIndex);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst { json: gltfCompressed, resources } =\n\t\t\t\t\t\t\t\t\t\tgltfTransform.writeJSON(doc);\n\n\t\t\t\t\t\t\t\t\t// embed buffer because gltf-transform doesn't do it\n\t\t\t\t\t\t\t\t\tconst encodedBuffer = base64js.fromByteArray(\n\t\t\t\t\t\t\t\t\t\tnew Uint8Array(resources['.bin'])\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tgltfCompressed.buffers![0].uri = `data:application/octet-stream;base64,${encodedBuffer}`;\n\n\t\t\t\t\t\t\t\t\t// TODO COLLAB this is commented out\n\t\t\t\t\t\t\t\t\t//serializedGeometry.gltf = gltfCompressed;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t// mesh is probably too big and we ran out of wasm memory,\n\t\t\t\t\t\t\t\t\t// continue with uncompressed mesh\n\t\t\t\t\t\t\t\t\t// TODO COLLAB this is commented out\n\t\t\t\t\t\t\t\t\t//serializedGeometry.gltf = gltf as GLTF.IGLTF;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t);\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tlibrary[geometry.uuid] = serializedGeometry;\n\t\t\t}\n\t\t} else {\n\t\t\tlet userData = geometry.userData;\n\n\t\t\tif (userData.type === 'VectorGeometry') {\n\t\t\t\tconst shape = (geometry as IGeometry<VectorGeometryInputs>).userData\n\t\t\t\t\t.shape;\n\t\t\t\tuserData = Object.assign({}, userData, {\n\t\t\t\t\tshape: shape.toJSON(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlibrary[geometry.uuid] = {\n\t\t\t\tuuid: geometry.uuid,\n\t\t\t\tuserData,\n\t\t\t} as SerializedGeometry;\n\t\t}\n\t}\n\n\treturn geometry.uuid;\n}\n\nexport function extractFromCache<T extends Metadata>(cache: {\n\t[key: string]: T;\n}): T[] {\n\tconst values: T[] = [];\n\tfor (const key in cache) {\n\t\tconst data = cache[key];\n\t\tdelete data.metadata;\n\t\tvalues.push(data);\n\t}\n\n\treturn values;\n}\n\nexport function extractFromCacheNonMetadata<T>(cache: {\n\t[key: string]: T;\n}): T[] {\n\tconst values: T[] = [];\n\tfor (const key in cache) {\n\t\tvalues.push(cache[key]);\n\t}\n\n\treturn values;\n}\n\n// TODO nisa move each toJSON to here\n// export const objectExporter = function (object: Object3D): SerializedBase {\n// \tconst meta: Meta = {\n// \t\tgeometries: {},\n// \t\tmaterials: {},\n// \t\ttextures: {},\n// \t\timages: {},\n// \t\t// shapes: {},\n// \t\tinteractionStates: {},\n// \t};\n\n// \tconst data: SerializedBase = {\n// \t\tmetadata: {\n// \t\t\t// TODO fix files with version 4.5 (e.g: iPhone from Spline Library)\n// \t\t\t// Don't use 4.5 (the first files were using 4.5)\n// \t\t\tversion: 1.4,\n// \t\t\ttype: 'Object',\n// \t\t\tgenerator: 'Object3D.toJSON',\n// \t\t},\n// \t\tobject: traverse(object, meta).object,\n// \t};\n\n// \tconst geometries = extractFromCache(meta.geometries);\n// \tconst materials = extractFromCache(meta.materials);\n// \tconst textures = extractFromCache(meta.textures);\n// \tconst images = extractFromCache(meta.images);\n// \t// const shapes = extractFromCache(meta.shapes);\n// \tconst interactionStates = extractFromCache(meta.interactionStates);\n\n// \tif (geometries.length > 0) data.geometries = geometries;\n// \tif (materials.length > 0) data.materials = materials;\n// \tif (textures.length > 0) data.textures = textures;\n// \tif (images.length > 0) data.images = images;\n// \t// if (shapes.length > 0) data.shapes = shapes;\n// \tif (interactionStates.length > 0) data.interactionStates = interactionStates;\n\n// \treturn data;\n// };\n\n// function traverse(object: Object3D, meta: Meta): SerializedBase {\n// \tlet data: SerializedBase;\n\n// \t// PATCH nisa: check with Light to serialize the default lights, but we need to use spline lights\n// \t// if (isEntity(object) || object instanceof Light || object instanceof Scene) {\n// \tif (object instanceof Light || object.isScene) {\n// \t\tdata = object.toJSON(meta);\n\n// \t\tif (object.children.length > 0) {\n// \t\t\tdata.object.children = [];\n\n// \t\t\tfor (const child of object.children) {\n// \t\t\t\tconst data2: SerializedBase = traverse(child, meta);\n// \t\t\t\tif (data2) {\n// \t\t\t\t\tdata.object.children.push(data2.object);\n// \t\t\t\t}\n// \t\t\t}\n// \t\t}\n// \t}\n\n// \treturn data;\n// }\n", "import { BufferGeometry, Float32BufferAttribute } from 'three';\n\nexport function assert<T>(val: T | null | undefined, msg?: string): T {\n\tif (!val) throw new Error(`Assertion failed: ${msg ?? '(unknown)'}`);\n\n\treturn val;\n}\n\n// Separate a grouped BufferGeometry into multiple BufferGeometries\nexport function separateGroups(geometry: BufferGeometry): BufferGeometry[] {\n\tconst outGeometries: BufferGeometry[] = [];\n\n\tconst groups = geometry.groups;\n\n\tconst origVerts = geometry.getAttribute('position').array;\n\tconst origNormals = geometry.getAttribute('normal').array;\n\tconst origUvs = geometry.getAttribute('uv')?.array;\n\t// const origNumVerts = Math.floor(origVerts.length / 3);\n\n\tgroups.forEach((group) => {\n\t\tconst numVerts = group.count;\n\n\t\tconst newBufGeom = new BufferGeometry();\n\t\tconst newPositions = new Float32Array(numVerts * 3);\n\t\tconst newNormals = new Float32Array(numVerts * 3);\n\t\tconst newUvs = new Float32Array(numVerts * 2);\n\n\t\tfor (let i = 0; i < numVerts; i++) {\n\t\t\tconst indexOrig = 3 * (group.start + i);\n\t\t\tconst indexDest = 3 * i;\n\n\t\t\t// position\n\t\t\tnewPositions[indexDest] = origVerts[indexOrig];\n\t\t\tnewPositions[indexDest + 1] = origVerts[indexOrig + 1];\n\t\t\tnewPositions[indexDest + 2] = origVerts[indexOrig + 2];\n\n\t\t\t// normal\n\t\t\tnewNormals[indexDest] = origNormals[indexOrig];\n\t\t\tnewNormals[indexDest + 1] = origNormals[indexOrig + 1];\n\t\t\tnewNormals[indexDest + 2] = origNormals[indexOrig + 2];\n\n\t\t\t// uv\n\t\t\tif (origUvs) {\n\t\t\t\tconst indexOrigUV = 2 * (group.start + i);\n\t\t\t\tconst indexDestUV = 2 * i;\n\n\t\t\t\tnewUvs[indexDestUV] = origUvs[indexOrigUV];\n\t\t\t\tnewUvs[indexDestUV + 1] = origUvs[indexOrigUV + 1];\n\t\t\t}\n\t\t}\n\n\t\tnewBufGeom.setAttribute(\n\t\t\t'position',\n\t\t\tnew Float32BufferAttribute(newPositions, 3)\n\t\t);\n\t\tnewBufGeom.setAttribute(\n\t\t\t'normal',\n\t\t\tnew Float32BufferAttribute(newNormals, 3)\n\t\t);\n\t\tif (origUvs) {\n\t\t\tnewBufGeom.setAttribute('uv', new Float32BufferAttribute(newUvs, 2));\n\t\t}\n\n\t\toutGeometries.push(newBufGeom);\n\t});\n\n\treturn outGeometries;\n}\n\n// https://stackoverflow.com/a/50652052/3741361\nexport interface CanvasElement extends HTMLCanvasElement {\n\tcaptureStream(frameRate?: number): MediaStream;\n}\n", "import type { Transform, WebIO } from '@gltf-transform/core';\nimport type { DracoMeshCompression } from '@gltf-transform/extensions';\n\n// We need to do all this mess to avoid the module from being included in runtime\n// TODO revisit this once the toJSONs() will be deprecated\n\ntype DracoEncoder = {\n\tgltfTransform: WebIO;\n\tDracoMeshCompressionExtension: typeof DracoMeshCompression;\n\taddIndex: Transform;\n};\n\n// this is a promise that resolves once the gltf libraries\n// have been loaded\nlet resolver: (dracoEncoder: DracoEncoder) => void;\nexport const dracoEncoder: Promise<DracoEncoder> = new Promise((resolve) => {\n\tresolver = resolve;\n});\n\nlet isLoaded = false;\nexport async function loadDracoEncoder() {\n\t// if it's already loaded, abort\n\tif (isLoaded) {\n\t\treturn;\n\t}\n\n\t// load necessary libraries and files\n\tconst [\n\t\t{ WebIO },\n\t\t{ KHRONOS_EXTENSIONS, DracoMeshCompression },\n\t\t{ weld },\n\t\t{ createEncoderModule },\n\t\twasmBinary,\n\t] = await Promise.all([\n\t\timport(\n\t\t\t/* webpackChunkName: \"@gltf-transform/core\" */ '@gltf-transform/core'\n\t\t),\n\t\timport(\n\t\t\t/* webpackChunkName: \"@gltf-transform/extensions\" */\n\t\t\t'@gltf-transform/extensions'\n\t\t),\n\t\timport(\n\t\t\t/* webpackChunkName: \"@gltf-transform/functions\" */\n\t\t\t'@gltf-transform/functions'\n\t\t),\n\t\timport(/* webpackChunkName: \"draco3dgltf\" */ 'draco3dgltf'),\n\t\tfetch('/_libraries/draco_encoder.wasm').then((res) => res.arrayBuffer()),\n\t]);\n\n\tconst io = new WebIO();\n\tconst DracoEncoderModule = await createEncoderModule({ wasmBinary });\n\n\tio.registerExtensions(KHRONOS_EXTENSIONS).registerDependencies({\n\t\t'draco3d.encoder': DracoEncoderModule,\n\t});\n\n\tconst gltfTransform = io;\n\tconst DracoMeshCompressionExtension = DracoMeshCompression;\n\tconst addIndex = weld({ tolerance: 0.0001 });\n\n\tresolver({ gltfTransform, DracoMeshCompressionExtension, addIndex });\n\tisLoaded = true;\n}\n", "/**\n * @author alejandro\n * @author nisa\n */\n\nimport { ClonerState } from 'spline-data';\nimport { Object3D, Vector3, Euler, MathUtils, Material } from 'three';\nimport { AbstractMesh } from './entities';\nimport { MeshEntity } from './entities/Entity';\nimport { DeepPartial, DeepWriteable } from 'common';\nimport { merge } from 'lodash-es';\n\nexport class Cloner extends Object3D {\n\t// @deprecated use instanceof instead of this\n\treadonly object: AbstractMesh;\n\tparameters: DeepWriteable<ClonerState>;\n\n\tconstructor(object: AbstractMesh, parameters: DeepPartial<ClonerState> = {}) {\n\t\tsuper();\n\n\t\tthis.object = object;\n\n\t\tconst size = object.recursiveBBox.getSize(new Vector3());\n\t\tconst margin = 0.1;\n\n\t\tthis.parameters = ClonerState.defaultData(\n\t\t\tsize.toArray(),\n\t\t\tmargin\n\t\t) as DeepWriteable<ClonerState>;\n\t\tmerge(this.parameters, parameters);\n\n\t\tthis.update();\n\t\tthis.setHideBase(this.parameters.hideBase);\n\t}\n\n\trefreshMaterial(): void {\n\t\tif (!('material' in this.object)) return;\n\n\t\tfor (const child of this.children as MeshEntity[]) {\n\t\t\tchild.material = this.object.material as Material;\n\t\t}\n\t}\n\n\tsetHideBase(hideBase: boolean): void {\n\t\tif (!('material' in this.object)) return;\n\n\t\tif (Array.isArray(this.object.material)) {\n\t\t\tif (this.children.length > 0) {\n\t\t\t\tfor (const material of this.object.material) {\n\t\t\t\t\tmaterial.visible = true;\n\t\t\t\t}\n\t\t\t\tif (hideBase) {\n\t\t\t\t\tconst materials = this.object.material.map((material) =>\n\t\t\t\t\t\tmaterial.clone()\n\t\t\t\t\t);\n\t\t\t\t\tfor (const child of this.children as MeshEntity[]) {\n\t\t\t\t\t\tchild.material = materials;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const child of this.children as MeshEntity[]) {\n\t\t\t\t\t\tchild.material = this.object.material;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const material of this.object.material) {\n\t\t\t\tmaterial.visible = !hideBase;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.children.length > 0) {\n\t\t\t\tthis.object.material.visible = true;\n\t\t\t\tif (hideBase) {\n\t\t\t\t\tconst material = this.object.material.clone();\n\t\t\t\t\tfor (const child of this.children as MeshEntity[]) {\n\t\t\t\t\t\tchild.material = material;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const child of this.children as MeshEntity[]) {\n\t\t\t\t\t\tchild.material = this.object.material;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.object.material.visible = !hideBase;\n\t\t}\n\t\tthis.parameters.hideBase = hideBase;\n\t}\n\n\tupdate(): void {\n\t\tthis._updateCount();\n\n\t\tswitch (this.parameters.type) {\n\t\t\tcase 'radial':\n\t\t\t\tthis._updateRadial(this.parameters);\n\t\t\t\tbreak;\n\t\t\tcase 'linear':\n\t\t\t\tthis._updateLinear(this.parameters);\n\t\t\t\tbreak;\n\t\t\tcase 'grid':\n\t\t\t\tthis._updateGrid(this.parameters);\n\t\t}\n\n\t\tthis.children.forEach((c) => c.updateMatrix());\n\t}\n\n\t_updateCount(): void {\n\t\tconst count =\n\t\t\tthis.parameters.type === 'grid'\n\t\t\t\t? this.parameters.grid.count[0] *\n\t\t\t\t this.parameters.grid.count[1] *\n\t\t\t\t this.parameters.grid.count[2]\n\t\t\t\t: this.parameters.count;\n\n\t\tif (this.children.length === count) return;\n\n\t\tif (this.children.length < count) {\n\t\t\tfor (let i = 0, l = count - this.children.length; i < l; ++i) {\n\t\t\t\tconst clone = this.object.shallowClone(false);\n\t\t\t\tclone.visible = true;\n\t\t\t\tthis.add(clone);\n\t\t\t\tif (this.parameters.hideBase) {\n\t\t\t\t\tthis.setHideBase(true);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (let i = 0, l = this.children.length - count; i < l; ++i) {\n\t\t\t\tthis.remove(this.children[0]);\n\t\t\t}\n\t\t}\n\t}\n\n\t_updateRadial(parameters: ClonerState): void {\n\t\tconst radial = parameters.radial;\n\t\tconst startRad = radial.start * MathUtils.DEG2RAD;\n\t\tconst endRad = radial.end * MathUtils.DEG2RAD;\n\t\tconst diffRad = startRad - endRad;\n\t\tconst rotation = new Euler(\n\t\t\tradial.rotation[0] * MathUtils.DEG2RAD,\n\t\t\tradial.rotation[1] * MathUtils.DEG2RAD,\n\t\t\tradial.rotation[2] * MathUtils.DEG2RAD\n\t\t);\n\n\t\tlet axisVector: Vector3;\n\t\tswitch (radial.axis) {\n\t\t\tcase 'z':\n\t\t\t\taxisVector = new Vector3(0, 0, 1);\n\t\t\t\tbreak;\n\t\t\tcase 'y':\n\t\t\t\taxisVector = new Vector3(0, 1, 0);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\tcase 'x':\n\t\t\t\taxisVector = new Vector3(1, 0, 0);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tfor (const [i, child] of (this.children as MeshEntity[]).entries()) {\n\t\t\tchild.hiddenMatrix.identity();\n\n\t\t\tchild.scale.x = radial.scale[0] + 1;\n\t\t\tchild.scale.y = radial.scale[1] + 1;\n\t\t\tchild.scale.z = radial.scale[2] + 1;\n\n\t\t\tchild.position.setScalar(0);\n\t\t\tconst rotationAxis = (diffRad / parameters.count) * i - startRad;\n\t\t\tswitch (radial.axis) {\n\t\t\t\tcase 'x':\n\t\t\t\t\tchild.rotation.set(0, rotationAxis, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'y':\n\t\t\t\t\tchild.rotation.set(0, 0, rotationAxis);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'z':\n\t\t\t\t\tchild.rotation.set(rotationAxis, 0, 0);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tchild.translateOnAxis(axisVector, radial.radius);\n\n\t\t\tchild.position.x += radial.position[0];\n\t\t\tchild.position.y += radial.position[1];\n\t\t\tchild.position.z += radial.position[2];\n\n\t\t\tif (radial.alignment === true) {\n\t\t\t\tchild.rotation.x += rotation.x;\n\t\t\t\tchild.rotation.y += rotation.y;\n\t\t\t\tchild.rotation.z += rotation.z;\n\t\t\t} else {\n\t\t\t\tchild.rotation.copy(rotation);\n\t\t\t}\n\t\t}\n\t}\n\n\t_updateLinear(parameters: ClonerState): void {\n\t\tif (parameters.type !== 'linear') throw new Error();\n\t\tconst linear = parameters.linear;\n\t\tconst rotation = new Euler(\n\t\t\tlinear.rotation[0] * MathUtils.DEG2RAD,\n\t\t\tlinear.rotation[1] * MathUtils.DEG2RAD,\n\t\t\tlinear.rotation[2] * MathUtils.DEG2RAD\n\t\t);\n\n\t\tfor (const [i, child] of (this.children as MeshEntity[]).entries()) {\n\t\t\tchild.hiddenMatrix.identity();\n\n\t\t\tchild.scale.x = linear.scale[0] * i + 1;\n\t\t\tchild.scale.y = linear.scale[1] * i + 1;\n\t\t\tchild.scale.z = linear.scale[2] * i + 1;\n\n\t\t\tchild.rotation.x = rotation.x * i;\n\t\t\tchild.rotation.y = rotation.y * i;\n\t\t\tchild.rotation.z = rotation.z * i;\n\n\t\t\tchild.position.x = linear.position[0] * i;\n\t\t\tchild.position.y = linear.position[1] * i;\n\t\t\tchild.position.z = linear.position[2] * i;\n\t\t}\n\t}\n\n\t_updateGrid(parameters: ClonerState): void {\n\t\tlet index = 0;\n\t\tconst grid = parameters.grid;\n\t\tif (grid.useCenter === true) {\n\t\t\tconst discount = {\n\t\t\t\tx: grid.count[0] % 2 === 0 ? 2 : 1,\n\t\t\t\ty: grid.count[1] % 2 === 0 ? 2 : 1,\n\t\t\t\tz: grid.count[2] % 2 === 0 ? 2 : 1,\n\t\t\t};\n\t\t\tconst offset = new Vector3(\n\t\t\t\tgrid.size[0] * (grid.count[0] - discount.x) * 0.5,\n\t\t\t\tgrid.size[1] * (grid.count[1] - discount.y) * 0.5,\n\t\t\t\tgrid.size[2] * (grid.count[2] - discount.z) * 0.5\n\t\t\t);\n\n\t\t\tfor (let i = 0; i < grid.count[0]; i++) {\n\t\t\t\tfor (let j = 0; j < grid.count[1]; j++) {\n\t\t\t\t\tfor (let k = 0; k < grid.count[2]; k++) {\n\t\t\t\t\t\tconst child = (this.children as MeshEntity[])[index++];\n\n\t\t\t\t\t\tchild.hiddenMatrix.identity();\n\t\t\t\t\t\tchild.scale.setScalar(1);\n\t\t\t\t\t\tchild.rotation.set(0, 0, 0);\n\n\t\t\t\t\t\tchild.position.x = grid.size[0] * i - offset.x;\n\t\t\t\t\t\tchild.position.y = grid.size[1] * j - offset.y;\n\t\t\t\t\t\tchild.position.z = grid.size[2] * k - offset.z;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor (let i = 0; i < grid.count[0]; i++) {\n\t\t\t\tfor (let j = 0; j < grid.count[1]; j++) {\n\t\t\t\t\tfor (let k = 0; k < grid.count[2]; k++) {\n\t\t\t\t\t\tconst child = (this.children as MeshEntity[])[index++];\n\n\t\t\t\t\t\tchild.hiddenMatrix.identity();\n\t\t\t\t\t\tchild.scale.setScalar(1);\n\t\t\t\t\t\tchild.rotation.set(0, 0, 0);\n\n\t\t\t\t\t\tchild.position.x = grid.size[0] * i;\n\t\t\t\t\t\tchild.position.y = -grid.size[1] * j;\n\t\t\t\t\t\tchild.position.z = -grid.size[2] * k;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @deprecated\n\t */\n\tfromJSON(_: any): Cloner {\n\t\treturn this;\n\t}\n\t/**\n\t * @deprecated\n\t */\n\ttoJSON() {\n\t\treturn {};\n\t}\n\n\tfromClonerState(parameters: DeepPartial<ClonerState>): this {\n\t\tif (parameters.hideBase !== undefined) {\n\t\t\tthis.setHideBase(parameters.hideBase);\n\t\t}\n\t\tmerge(this.parameters, parameters);\n\t\tthis.update();\n\t\treturn this;\n\t}\n}\n", "import {\n\tNormalBlending,\n\tShaderMaterial,\n\tShader,\n\tWebGLRenderer,\n\tFrontSide,\n\tShaderMaterialParameters,\n\tTexture,\n} from 'three';\n\nimport { Node } from '../core/Node';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { NodeFrame } from '../core/NodeFrame';\nimport { RawNode } from './nodes/RawNode';\nimport { ColorNode } from '../inputs/ColorNode';\nimport { PositionNode } from '../accessors/PositionNode';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { LayerStack, LAYER_TYPE } from '../../layers';\nimport type { Material } from '../../';\nimport { AssetLibrary } from '../../AssetLibrary';\nimport { colorDefault } from 'common/src/constants';\n\n// NOTE(piero): Extend three Shader with the properties we need.\ndeclare module 'three' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface Shader {\n\t\tdefines: any;\n\n\t\textensionDerivatives: boolean;\n\t\textensionFragDepth: boolean;\n\t\textensionDrawBuffers: boolean;\n\t\textensionShaderTextureLOD: boolean;\n\t}\n}\n\nexport type NodeMaterialBuildParams = {\n\tbuilder?: NodeBuilder;\n\trenderer?: WebGLRenderer;\n};\n\ntype NodeMaterialUserData = {\n\ttype: string;\n\tcategory: string;\n\tnodeType: string;\n\tlayers?: LayerStack;\n};\n\nexport type NodeMaterialParameters = ShaderMaterialParameters & {\n\tmap?: Texture;\n};\n\nexport class NodeMaterial extends ShaderMaterial {\n\tisNodeMaterial: boolean = true;\n\n\tvertex: Node | RawNode;\n\tfragment: Node | RawNode;\n\n\tsize: any;\n\tsizeAttenuation: any;\n\n\tscale: any;\n\tdashSize: any;\n\tgapSize: any;\n\n\tupdaters: Node[];\n\n\ttype: string = 'NodeMaterial';\n\n\twireframeLinecap: string = '';\n\twireframeLinejoin: string = '';\n\n\tisDetached: boolean;\n\n\tflatShading?: boolean;\n\n\t// NOTE: used to store uniform values before clamping them to avoid cloning objects for preview.\n\tuniformsBackup: Record<string, any> = {};\n\n\tuserData: NodeMaterialUserData = {\n\t\ttype: '',\n\t\tcategory: '',\n\t\tnodeType: '',\n\t};\n\n\tconstructor(\n\t\tvertex?: Node,\n\t\tfragment?: Node,\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(parameters);\n\t\tthis.fog = true;\n\t\tthis.vertex =\n\t\t\tvertex ?? new RawNode(new PositionNode(PositionNode.PROJECTION));\n\t\tthis.fragment = fragment ?? new RawNode(new ColorNode(colorDefault));\n\n\t\tthis.updaters = [];\n\t\tthis.isDetached = true;\n\t\tthis.dithering = true;\n\n\t\tthis.onBeforeCompile = this._onBeforeCompile;\n\t}\n\n\tgetDefines(): any {\n\t\treturn this.defines;\n\t}\n\n\tgetUniforms() {\n\t\treturn this.uniforms;\n\t}\n\n\tgetVertexShader() {\n\t\treturn this.vertexShader;\n\t}\n\n\tgetFragmentShader() {\n\t\treturn this.fragmentShader;\n\t}\n\n\t_onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void {\n\t\tthis.build({ renderer: renderer });\n\n\t\tshader.defines = this.defines;\n\t\tshader.uniforms = this.uniforms;\n\t\tshader.vertexShader = this.vertexShader;\n\t\tshader.fragmentShader = this.fragmentShader;\n\n\t\tshader.extensionDerivatives = this.extensions.derivatives === true;\n\t\tshader.extensionFragDepth = this.extensions.fragDepth === true;\n\t\tshader.extensionDrawBuffers = this.extensions.drawBuffers === true;\n\t\tshader.extensionShaderTextureLOD =\n\t\t\tthis.extensions.shaderTextureLOD === true;\n\t}\n\n\t_getLayerStack(texture: Texture | undefined): LayerStack {\n\t\tconst layerStack = new LayerStack(this as unknown as Material);\n\n\t\tif (texture) {\n\t\t\tvoid (async () => {\n\t\t\t\t// patch: when we load FBX, texture.image is defined instantly\n\n\t\t\t\twhile (texture.image === undefined)\n\t\t\t\t\tawait new Promise((resolve) => requestAnimationFrame(resolve));\n\n\t\t\t\tlayerStack.addLayerAt(1, {\n\t\t\t\t\ttype: LAYER_TYPE.TEXTURE,\n\t\t\t\t\ttexture,\n\t\t\t\t});\n\t\t\t\tthis.dispose();\n\t\t\t})();\n\t\t}\n\n\t\treturn layerStack;\n\t}\n\n\t// NOTE(piero): clamps some values that could make material previews go horribly wrong\n\tclampUniformsForPreview(clampMin: number, clampMax: number) {\n\t\tconst clamp = (num: number, min: number, max: number) =>\n\t\t\tMath.min(Math.max(num, min), max);\n\t\tif (this.userData.layers) {\n\t\t\tfor (const layer of this.userData.layers.getLayers()) {\n\t\t\t\tif (layer.type == LAYER_TYPE.DISPLACE) {\n\t\t\t\t\tthis.uniformsBackup[`f${layer.id}_intensity`] =\n\t\t\t\t\t\tlayer.uniforms[`f${layer.id}_intensity`].value;\n\n\t\t\t\t\tlet value = clamp(\n\t\t\t\t\t\tlayer.uniforms[`f${layer.id}_intensity`].value,\n\t\t\t\t\t\tclampMin,\n\t\t\t\t\t\tclampMax\n\t\t\t\t\t);\n\t\t\t\t\tlayer.uniforms[`f${layer.id}_intensity`].value = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\trestoreClampedUniforms() {\n\t\tif (this.userData.layers) {\n\t\t\tfor (const layer of this.userData.layers.getLayers()) {\n\t\t\t\tif (layer.type == LAYER_TYPE.DISPLACE) {\n\t\t\t\t\tlayer.uniforms[`f${layer.id}_intensity`].value =\n\t\t\t\t\t\tthis.uniformsBackup[`f${layer.id}_intensity`];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcustomProgramCacheKey(): string {\n\t\treturn this.getHash();\n\t}\n\n\tupdateFrame(frame: NodeFrame): void {\n\t\tfor (let i = 0; i < this.updaters.length; ++i) {\n\t\t\tframe.updateNode(this.updaters[i]);\n\t\t}\n\t}\n\n\tbuild(params?: NodeMaterialBuildParams): this {\n\t\tparams = params ?? {};\n\n\t\tconst builder = params.builder ?? new NodeBuilder();\n\n\t\tbuilder.setMaterial(this, params.renderer as WebGLRenderer);\n\t\tbuilder.build(this.vertex, this.fragment);\n\n\t\tthis.vertexShader = builder.getCode('vertex');\n\t\tthis.fragmentShader = builder.getCode('fragment');\n\n\t\tthis.defines = builder.defines;\n\t\tthis.uniforms = builder.uniforms;\n\t\tthis.extensions = builder.extensions;\n\t\tthis.updaters = builder.updaters;\n\n\t\tthis.fog = builder.requires.fog;\n\t\tthis.lights = builder.requires.lights;\n\n\t\tthis.transparent =\n\t\t\tbuilder.requires.transparent || this.blending > NormalBlending;\n\n\t\treturn this;\n\t}\n\n\tgetHash(): string {\n\t\tlet hash = '{';\n\n\t\thash += '\"vertex\":' + this.vertex.getHash() + ',';\n\t\thash += '\"fragment\":' + this.fragment.getHash();\n\n\t\thash += '}';\n\n\t\treturn hash;\n\t}\n\n\tcopy(source: this): this {\n\t\tconst uuid = this.uuid;\n\n\t\tfor (const name in source) {\n\t\t\tthis[name] = source[name];\n\t\t}\n\n\t\tthis.uuid = uuid;\n\n\t\tif (source.userData !== undefined) {\n\t\t\tthis.userData = JSON.parse(JSON.stringify(source.userData));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta: Meta): SerializedMaterial {\n\t\tconst layers = this.userData.layers as LayerStack;\n\t\tthis.userData.layers = undefined;\n\n\t\tconst data = super.toJSON(meta) as SerializedMaterial & {\n\t\t\tvertexShader?: unknown;\n\t\t\tfragmentShader?: unknown;\n\t\t\tcolor?: unknown;\n\t\t\tshininess?: unknown;\n\t\t\tspecular?: unknown;\n\t\t\troughness?: unknown;\n\t\t\tmetalness?: unknown;\n\t\t\tuniforms?: any;\n\t\t};\n\t\tdata.type = 'ShaderMaterial';\n\n\t\tdata.userData = {\n\t\t\ttype: this.userData.type,\n\t\t\tcategory: this.userData.category,\n\t\t\tnodeType: this.type,\n\t\t\tlayers: layers.toJSON(meta),\n\t\t};\n\n\t\tdata.vertex = this.vertex.toJSON(meta).uuid as string;\n\t\tdata.fragment = this.fragment.toJSON(meta).uuid as string;\n\n\t\tdelete data.vertexShader;\n\t\tdelete data.fragmentShader;\n\t\tdelete data.color;\n\t\tdelete data.shininess;\n\t\tdelete data.specular;\n\t\tdelete data.roughness;\n\t\tdelete data.metalness;\n\t\tdelete data.uniforms;\n\n\t\tif (meta && !meta.materials[this.uuid]) {\n\t\t\tmeta.materials[this.uuid] = data;\n\t\t}\n\n\t\tthis.userData.layers = layers;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedMaterial, assets: AssetLibrary) {\n\t\tthis.defines = data.defines ?? {};\n\t\tthis.depthFunc = data.depthFunc;\n\t\tthis.depthWrite = data.depthWrite;\n\t\tthis.side = data.side !== undefined ? data.side : FrontSide;\n\t\tthis.transparent = data.transparent;\n\t\tthis.wireframeLinecap = data.wireframeLinecap;\n\t\tthis.wireframeLinejoin = data.wireframeLinejoin;\n\t\tthis.flatShading = data.flatShading;\n\t\tthis.wireframe = data.wireframe;\n\t\t(this.userData.layers as LayerStack).fromJSON(\n\t\t\tdata.userData.layers,\n\t\t\tassets,\n\t\t\tthis as unknown as Material\n\t\t);\n\t}\n}\n\nObject.defineProperties(NodeMaterial.prototype, {\n\tproperties: {\n\t\tget: function () {\n\t\t\treturn this.fragment.properties;\n\t\t},\n\t},\n\n\tneedsUpdate: {\n\t\tset: function (value) {\n\t\t\tif (value === true) this.version++;\n\t\t\tthis.needsCompile = value;\n\t\t},\n\n\t\tget: function () {\n\t\t\treturn this.needsCompile;\n\t\t},\n\t},\n});\n", "import {\n\tCubeReflectionMapping,\n\tCubeRefractionMapping,\n\tCubeUVReflectionMapping,\n\tCubeUVRefractionMapping,\n\tLinearEncoding,\n\tMaterial,\n\tWebGLRenderer,\n\tTexture,\n\tTextureEncoding,\n\tsRGBEncoding,\n} from 'three';\n\nimport { NodeUniform } from './NodeUniform';\nimport { Node } from './Node';\nimport { nodeLib } from '../core/NodeLib';\n\nimport { Vector2Node } from '../inputs/Vector2Node';\nimport { Vector3Node } from '../inputs/Vector3Node';\nimport { Vector4Node } from '../inputs/Vector4Node';\nimport { FunctionNode } from './FunctionNode';\nimport { ConstNode } from './ConstNode';\nimport { StructNode } from './StructNode';\n\nimport { TextureCubeNode } from '../misc/TextureCubeNode';\nimport { CubeTextureNode } from '../inputs/CubeTextureNode';\nimport { TextureNode } from '../inputs/TextureNode';\n\nconst elements = ['x', 'y', 'z', 'w'];\nconst constructors = ['float', 'vec2', 'vec3', 'vec4'];\n\nconst convertFormatToType: Record<string, string> = {\n\tfloat: 'f',\n\tvec2: 'v2',\n\tvec3: 'v3',\n\tvec4: 'v4',\n\tmat4: 'v4',\n\tint: 'i',\n\tbool: 'b',\n\t'float[]': 'f[]',\n\t'vec4[]': 'v4[]',\n};\nconst convertTypeToFormat: Record<string, string> = {\n\tt: 'sampler2D',\n\ttc: 'samplerCube',\n\tb: 'bool',\n\ti: 'int',\n\tf: 'float',\n\tc: 'vec3',\n\tv2: 'vec2',\n\tv3: 'vec3',\n\tv4: 'vec4',\n\tm3: 'mat3',\n\tm4: 'mat4',\n\t'f[]': 'float[]',\n\t'v4[]': 'vec4[]',\n};\n\ninterface IShaderCode {\n\tvertex: string;\n\tfragment: string;\n}\n\nexport class NodeBuilder {\n\tslots: string[];\n\tcaches: string[];\n\tcontexts: Record<string, any>[];\n\n\tnodeData: Record<string, any>;\n\n\tincludes: { [index: string]: any } = {\n\t\tconsts: {},\n\t\tfunctions: {},\n\t\tstructs: {},\n\t};\n\n\tattributes: Record<string, any>;\n\tprefixCode: string;\n\n\tparsCode: IShaderCode;\n\n\tcode: IShaderCode;\n\n\tnodeCode: IShaderCode;\n\n\tfinalCode: IShaderCode;\n\n\tfragmentVariables: Record<string, any>;\n\n\tinputs: {\n\t\tuniforms: {\n\t\t\tlist: NodeUniform[];\n\t\t\tvertex: Record<string, any>;\n\t\t\tfragment: Record<string, any>;\n\t\t};\n\t\tarrayUniforms: {\n\t\t\tlist: NodeUniform[];\n\t\t\tvertex: Record<string, any>;\n\t\t\tfragment: Record<string, any>;\n\t\t};\n\t\tvars: {\n\t\t\tvarying: Record<string, any>;\n\t\t\tvertex: Record<string, any>;\n\t\t\tfragment: Record<string, any>;\n\t\t};\n\t};\n\n\tdefines: Record<string, any>;\n\tuniforms: Record<string, any>;\n\n\tkeywords: Record<string, any>;\n\n\textensions: {\n\t\tderivatives: boolean;\n\t\tfragDepth: boolean;\n\t\tdrawBuffers: boolean;\n\t\tshaderTextureLOD: boolean;\n\t};\n\n\tnodes: Record<string, any>[];\n\n\tmaterial: Material | undefined;\n\trenderer: WebGLRenderer | undefined;\n\n\trequires: {\n\t\t[index: string]: any;\n\t\tuv: boolean[];\n\t\tcolor: boolean[];\n\t\tlights: boolean;\n\t\tfog: boolean;\n\t\ttransparent: boolean;\n\t\tirradiance: boolean;\n\t\tposition: boolean;\n\t\tworldPosition: boolean;\n\t\tnormal: boolean;\n\t\tworldNormal: boolean;\n\t\tvWorldViewDir: boolean;\n\t\tmodelMatrix: boolean;\n\t\tviewMatrix: boolean;\n\t\tprojectionMatrix: boolean;\n\t};\n\n\tcache: string = '';\n\tslot: string = '';\n\tshader: string = '';\n\n\tupdaters: Node[];\n\n\tanalyzing: boolean;\n\n\tresultCode: {\n\t\tvertex: string;\n\t\tfragment: string;\n\t};\n\n\tcontext: Record<string, any> = {};\n\n\tconstructor() {\n\t\tthis.slots = [];\n\t\tthis.caches = [];\n\t\tthis.contexts = [];\n\n\t\tthis.keywords = {};\n\n\t\tthis.nodeData = {};\n\n\t\tthis.fragmentVariables = {};\n\n\t\tthis.requires = {\n\t\t\tuv: [],\n\t\t\tcolor: [],\n\t\t\tlights: false,\n\t\t\tfog: false,\n\t\t\ttransparent: false,\n\t\t\tirradiance: false,\n\t\t\tposition: false,\n\t\t\tworldPosition: false,\n\t\t\tnormal: false,\n\t\t\tworldNormal: false,\n\t\t\tvWorldViewDir: false,\n\t\t\tmodelMatrix: false,\n\t\t\tviewMatrix: false,\n\t\t\tprojectionMatrix: false,\n\t\t};\n\n\t\tthis.includes = {\n\t\t\tconsts: [],\n\t\t\tfunctions: [],\n\t\t\tstructs: [],\n\t\t};\n\n\t\tthis.attributes = {};\n\n\t\tthis.prefixCode = [\n\t\t\t'#ifdef TEXTURE_LOD_EXT',\n\n\t\t\t'\t#define texCube(a, b) textureCube(a, b)',\n\t\t\t'\t#define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)',\n\n\t\t\t'\t#define tex2D(a, b) texture2D(a, b)',\n\t\t\t'\t#define tex2DBias(a, b, c) texture2DLodEXT(a, b, c)',\n\n\t\t\t'#else',\n\n\t\t\t'\t#define texCube(a, b) textureCube(a, b)',\n\t\t\t'\t#define texCubeBias(a, b, c) textureCube(a, b, c)',\n\n\t\t\t'\t#define tex2D(a, b) texture2D(a, b)',\n\t\t\t'\t#define tex2DBias(a, b, c) texture2D(a, b, c)',\n\n\t\t\t'#endif',\n\n\t\t\t`\n\t\t\t// NOTE: Include Spline's blending modes. This could be part of BlendNode\n\t\t\t#define SPE_BLENDING_NORMAL 0\n\t\t\t#define SPE_BLENDING_MULTIPLY 1\n\t\t\t#define SPE_BLENDING_SCREEN 2\n\t\t\t#define SPE_BLENDING_OVERLAY 3\n\n\t\t\tvec3 spe_normalBlend( vec3 a, vec3 b, float alpha ) {\n\t\t\t\treturn mix( a, b, alpha );\n\t\t\t}\n\n\t\t\tvec3 spe_multiplyBlend( vec3 a, vec3 b, float alpha ) {\n\t\t\t\treturn mix( a, a * b, alpha );\n\t\t\t}\n\n\t\t\tvec3 spe_screenBlend( vec3 a, vec3 b, float alpha ) {\n\t\t\t\tvec3 tmp = 1.0 - ( 1.0 - a ) * ( 1.0 - b );\n\t\t\t\treturn mix( a, tmp, alpha );\n\t\t\t}\n\n\t\t\tvec3 spe_overlayBlend( vec3 a, vec3 b, float alpha ) {\n\t\t\t\tvec3 tmp = mix( 1. - 2. * (1. - a) * (1. - b), 2. * a * b, step( a, vec3(.5) ) );\n\t\t\t\treturn clamp( mix( a, tmp, alpha ), 0.0, 1.0 );\n\t\t\t}\n\n\t\t\tvec3 spe_blend( vec3 a, vec3 b, float alpha, int mode ) {\n\t\t\t\tif ( mode == SPE_BLENDING_NORMAL ) return spe_normalBlend( a, b, alpha );\n\t\t\t\telse if ( mode == SPE_BLENDING_MULTIPLY ) return spe_multiplyBlend( a, b, alpha );\n\t\t\t\telse if ( mode == SPE_BLENDING_SCREEN ) return spe_screenBlend( a, b, alpha );\n\t\t\t\telse if ( mode == SPE_BLENDING_OVERLAY ) return spe_overlayBlend( a, b, alpha );\n\t\t\t\treturn vec3( 1.0 );\n\t\t\t}\n\t\t\t`,\n\n\t\t\t'#include <packing>',\n\t\t\t'#include <common>',\n\t\t].join('\\n');\n\n\t\tthis.parsCode = {\n\t\t\tvertex: ['float neighbor_offset = 0.0001;', ''].join('\\n'),\n\t\t\tfragment: [\n\t\t\t\t'float accumAlpha = 0.0;',\n\t\t\t\t`void accumulateAlpha(float alpha) {\n\t\t\t\t\taccumAlpha += (1.0 - accumAlpha) * alpha;\n\t\t\t\t}`,\n\t\t\t\t'',\n\t\t\t].join('\\n'),\n\t\t};\n\n\t\tthis.code = {\n\t\t\tvertex: '',\n\t\t\tfragment: '',\n\t\t};\n\n\t\tthis.nodeCode = {\n\t\t\tvertex: '',\n\t\t\tfragment: '',\n\t\t};\n\n\t\tthis.resultCode = {\n\t\t\tvertex: '',\n\t\t\tfragment: '',\n\t\t};\n\n\t\tthis.finalCode = {\n\t\t\tvertex: '',\n\t\t\tfragment: '',\n\t\t};\n\n\t\tthis.inputs = {\n\t\t\tuniforms: {\n\t\t\t\tlist: [],\n\t\t\t\tvertex: [],\n\t\t\t\tfragment: [],\n\t\t\t},\n\t\t\tarrayUniforms: {\n\t\t\t\tlist: [],\n\t\t\t\tvertex: [],\n\t\t\t\tfragment: [],\n\t\t\t},\n\t\t\tvars: {\n\t\t\t\tvarying: [],\n\t\t\t\tvertex: [],\n\t\t\t\tfragment: [],\n\t\t\t},\n\t\t};\n\n\t\t// send to material\n\n\t\tthis.defines = {};\n\n\t\tthis.uniforms = {};\n\n\t\tthis.extensions = {\n\t\t\tderivatives: false,\n\t\t\tfragDepth: false,\n\t\t\tdrawBuffers: false,\n\t\t\tshaderTextureLOD: false,\n\t\t};\n\n\t\tthis.updaters = [];\n\n\t\tthis.nodes = [];\n\n\t\t// --\n\n\t\tthis.analyzing = false;\n\t}\n\n\tbuild(vertex: Node, fragment: Node): this {\n\t\tthis.buildShader('vertex', vertex);\n\t\tthis.buildShader('fragment', fragment);\n\n\t\tfor (let i = 0; i < this.requires.uv.length; i++) {\n\t\t\tif (this.requires.uv[i]) {\n\t\t\t\tconst uvIndex = i > 0 ? i + 1 : '';\n\n\t\t\t\tthis.addVaryCode('varying vec2 vUv' + uvIndex + ';');\n\n\t\t\t\tif (i > 0) {\n\t\t\t\t\tthis.addVertexParsCode('attribute vec2 uv' + uvIndex + ';');\n\t\t\t\t}\n\n\t\t\t\tthis.addVertexFinalCode('vUv' + uvIndex + ' = uv' + uvIndex + ';');\n\t\t\t}\n\t\t}\n\n\t\tif (this.requires.color[0]) {\n\t\t\tthis.addVaryCode('varying vec4 vColor;');\n\t\t\tthis.addVertexParsCode('attribute vec4 color;');\n\n\t\t\tthis.addVertexFinalCode('vColor = color;');\n\t\t}\n\n\t\tif (this.requires.color[1]) {\n\t\t\tthis.addVaryCode('varying vec4 vColor2;');\n\t\t\tthis.addVertexParsCode('attribute vec4 color2;');\n\n\t\t\tthis.addVertexFinalCode('vColor2 = color2;');\n\t\t}\n\n\t\tif (this.requires.position) {\n\t\t\tthis.addVaryCode('varying vec3 vPosition;');\n\n\t\t\tthis.addVertexFinalCode('vPosition = transformed;');\n\t\t}\n\n\t\tif (this.requires.worldPosition) {\n\t\t\tthis.addVaryCode('varying vec3 vWPosition;');\n\n\t\t\tthis.addVertexFinalCode(\n\t\t\t\t'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;'\n\t\t\t);\n\t\t}\n\n\t\tif (this.requires.normal) {\n\t\t\tthis.addVaryCode('varying vec3 vObjectNormal;');\n\n\t\t\tthis.addVertexFinalCode('vObjectNormal = normal;');\n\t\t}\n\n\t\tif (this.requires.modelMatrix) {\n\t\t\tthis.addFragmentParsCode('uniform mat4 modelMatrix;');\n\t\t}\n\n\t\tif (this.requires.viewMatrix) {\n\t\t\tthis.addFragmentParsCode('uniform mat4 viewMatrix;');\n\t\t}\n\n\t\tif (this.requires.projectionMatrix) {\n\t\t\tthis.addFragmentParsCode('uniform mat4 projectionMatrix;');\n\t\t}\n\n\t\tif (this.requires.worldNormal) {\n\t\t\tthis.addVaryCode('varying vec3 vWNormal;');\n\n\t\t\tthis.addVertexFinalCode(\n\t\t\t\t'vWNormal = inverseTransformDirection( transformedNormal, viewMatrix ).xyz;'\n\t\t\t);\n\t\t}\n\n\t\tif (this.requires.vWorldViewDir) {\n\t\t\tthis.addVaryCode('varying vec3 vWorldViewDir;');\n\t\t\tthis.addVertexFinalCode(\n\t\t\t\t'vWorldViewDir = isPerspectiveMatrix( projectionMatrix ) ? ( (modelMatrix * vec4(position, 1.0)).xyz - cameraPosition ) : vec3( -viewMatrix[0][2], -viewMatrix[1][2], -viewMatrix[2][2] );'\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tbuildShader(shader: string, node: Node): void {\n\t\tthis.resultCode[shader as keyof IShaderCode] = node.build(\n\t\t\tthis.setShader(shader),\n\t\t\t'v4'\n\t\t);\n\t}\n\n\tsetMaterial(material: Material, renderer: WebGLRenderer): this {\n\t\tthis.material = material;\n\t\tthis.renderer = renderer;\n\n\t\tthis.requires.lights = (material as any).lights;\n\t\tthis.requires.fog = material.fog;\n\n\t\tthis.mergeDefines(material.defines as Record<string, any>);\n\n\t\treturn this;\n\t}\n\n\taddFlow(\n\t\tslot: string,\n\t\tcache?: string,\n\t\tcontext?: Record<string, unknown>\n\t): this {\n\t\treturn this.addSlot(slot).addCache(cache).addContext(context);\n\t}\n\n\tremoveFlow(): this {\n\t\treturn this.removeSlot().removeCache().removeContext();\n\t}\n\n\taddCache(name?: string): this {\n\t\tthis.cache = name ?? '';\n\t\tthis.caches.push(this.cache);\n\n\t\treturn this;\n\t}\n\n\tremoveCache(): this {\n\t\tthis.caches.pop();\n\t\tthis.cache = this.caches[this.caches.length - 1] || '';\n\n\t\treturn this;\n\t}\n\n\taddContext(context?: Record<string, unknown>): this {\n\t\tthis.context = Object.assign({}, this.context, context);\n\t\tthis.context.extra = this.context.extra || {};\n\n\t\tthis.contexts.push(this.context);\n\n\t\treturn this;\n\t}\n\n\tremoveContext(): this {\n\t\tthis.contexts.pop();\n\t\tthis.context = this.contexts[this.contexts.length - 1] || {};\n\n\t\treturn this;\n\t}\n\n\taddSlot(name: string): this {\n\t\tthis.slot = name || '';\n\t\tthis.slots.push(this.slot);\n\n\t\treturn this;\n\t}\n\n\tremoveSlot(): this {\n\t\tthis.slots.pop();\n\t\tthis.slot = this.slots[this.slots.length - 1] || '';\n\n\t\treturn this;\n\t}\n\n\taddFragmentVariable(name: string, type: string): void {\n\t\tif (this.fragmentVariables[name] === undefined) {\n\t\t\tthis.addFragmentCode(`${type} ${name};`);\n\t\t\tthis.fragmentVariables[name] = '';\n\t\t}\n\t}\n\n\taddVertexCode(code: string): void {\n\t\tthis.addCode(code, 'vertex');\n\t}\n\n\taddFragmentCode(code: string): void {\n\t\tthis.addCode(code, 'fragment');\n\t}\n\n\taddCode(code: string, shader?: string): void {\n\t\tthis.code[(shader ?? this.shader) as keyof IShaderCode] += code + '\\n';\n\t}\n\n\taddVertexNodeCode(code: string): void {\n\t\tthis.addNodeCode(code, 'vertex');\n\t}\n\n\taddFragmentNodeCode(code: string): void {\n\t\tthis.addNodeCode(code, 'fragment');\n\t}\n\n\taddNodeCode(code: string, shader?: string): void {\n\t\tthis.nodeCode[(shader ?? this.shader) as keyof IShaderCode] += code + '\\n';\n\t}\n\n\tclearNodeCode(shader?: string): string {\n\t\tshader = shader ?? this.shader;\n\n\t\tconst code = this.nodeCode[shader as keyof IShaderCode];\n\n\t\tthis.nodeCode[shader as keyof IShaderCode] = '';\n\n\t\treturn code;\n\t}\n\n\tclearVertexNodeCode(): string {\n\t\treturn this.clearNodeCode('vertex');\n\t}\n\n\tclearFragmentNodeCode(): string {\n\t\treturn this.clearNodeCode('fragment');\n\t}\n\n\taddVertexFinalCode(code: string): void {\n\t\tthis.addFinalCode(code, 'vertex');\n\t}\n\n\taddFragmentFinalCode(code: string): void {\n\t\tthis.addFinalCode(code, 'fragment');\n\t}\n\n\taddFinalCode(code: string, shader?: string): void {\n\t\tthis.finalCode[(shader ?? this.shader) as keyof IShaderCode] += code + '\\n';\n\t}\n\n\taddVertexParsCode(code: string): void {\n\t\tthis.addParsCode(code, 'vertex');\n\t}\n\n\taddFragmentParsCode(code: string): void {\n\t\tthis.addParsCode(code, 'fragment');\n\t}\n\n\taddParsCode(code: string, shader?: string): void {\n\t\tthis.parsCode[(shader ?? this.shader) as keyof IShaderCode] += code + '\\n';\n\t}\n\n\taddVaryCode(code: string): void {\n\t\tthis.addVertexParsCode(code);\n\t\tthis.addFragmentParsCode(code);\n\t}\n\n\tisCache(name: string): boolean {\n\t\treturn this.caches.indexOf(name) !== -1;\n\t}\n\n\tisSlot(name: string): boolean {\n\t\treturn this.slots.indexOf(name) !== -1;\n\t}\n\n\tdefine(name: string, value?: any): void {\n\t\tthis.defines[name] = value === undefined ? 1 : value;\n\t}\n\n\trequire(name: string) {\n\t\tthis.requires[name] = true;\n\t}\n\n\tisDefined(name: string): boolean {\n\t\treturn this.defines[name] !== undefined;\n\t}\n\n\tgetVar(\n\t\tuuid: string,\n\t\ttype: string,\n\t\tns?: string,\n\t\tshader: string = 'varying',\n\t\tprefix: string = 'V',\n\t\tlabel: string = ''\n\t): Record<string, string> {\n\t\tconst vars = this.getVars(shader);\n\t\tlet data = vars[uuid];\n\n\t\tif (!data) {\n\t\t\tconst index = vars.length,\n\t\t\t\tname = ns ? ns : 'node' + prefix + index + (label ? '_' + label : '');\n\n\t\t\tdata = { name: name, type: type };\n\n\t\t\tvars.push(data);\n\t\t\tvars[uuid] = data;\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tgetTempVar(\n\t\tuuid: string,\n\t\ttype: string,\n\t\tns: string,\n\t\tlabel: string\n\t): Record<string, string> {\n\t\treturn this.getVar(uuid, type, ns, this.shader, 'T', label);\n\t}\n\n\tgetAttribute(name: string, type: string): any {\n\t\tif (!this.attributes[name]) {\n\t\t\tconst varying = this.getVar(name, type);\n\n\t\t\tthis.addVertexParsCode('attribute ' + type + ' ' + name + ';');\n\t\t\tthis.addVertexFinalCode(varying.name + ' = ' + name + ';');\n\n\t\t\tthis.attributes[name] = { varying: varying, name: name, type: type };\n\t\t}\n\n\t\treturn this.attributes[name];\n\t}\n\n\tgetCode(shader: string): string {\n\t\treturn [\n\t\t\tthis.prefixCode,\n\t\t\tthis.parsCode[shader as keyof IShaderCode],\n\t\t\tthis.getVarListCode(this.getVars('varying'), 'varying'),\n\t\t\tthis.getVarListCode(\n\t\t\t\tthis.inputs.uniforms[shader as keyof IShaderCode],\n\t\t\t\t'uniform'\n\t\t\t),\n\t\t\tthis.getVarListCode(\n\t\t\t\tthis.inputs.arrayUniforms[shader as keyof IShaderCode],\n\t\t\t\t'uniform'\n\t\t\t),\n\t\t\tthis.getIncludesCode('consts', shader),\n\t\t\tthis.getIncludesCode('structs', shader),\n\t\t\tthis.getIncludesCode('functions', shader),\n\t\t\t'void main() {',\n\t\t\tthis.getVarListCode(this.getVars(shader)),\n\t\t\tthis.code[shader as keyof IShaderCode],\n\t\t\tthis.resultCode[shader as keyof IShaderCode],\n\t\t\tthis.finalCode[shader as keyof IShaderCode],\n\t\t\t'}',\n\t\t].join('\\n');\n\t}\n\n\tgetVarListCode(vars: Record<string, any>, prefix?: string): string {\n\t\tprefix = prefix ?? '';\n\n\t\tlet code = '';\n\n\t\tfor (let i = 0, l = vars.length; i < l; ++i) {\n\t\t\tconst nVar = vars[i];\n\t\t\tconst type = nVar.type;\n\t\t\tconst name = nVar.name;\n\t\t\tconst size = nVar.size;\n\n\t\t\tconst formatType = this.getFormatByType(type);\n\n\t\t\tif (formatType === undefined) {\n\t\t\t\tthrow new Error('Node pars ' + formatType + ' not found.');\n\t\t\t}\n\n\t\t\t// array types\n\t\t\tif (formatType.includes('[]')) {\n\t\t\t\tcode +=\n\t\t\t\t\tprefix +\n\t\t\t\t\t' ' +\n\t\t\t\t\tformatType.substring(0, formatType.length - 2) +\n\t\t\t\t\t' ' +\n\t\t\t\t\tname +\n\t\t\t\t\t`[${size}]` +\n\t\t\t\t\t';\\n';\n\t\t\t} else {\n\t\t\t\tcode += prefix + ' ' + formatType + ' ' + name + ';\\n';\n\t\t\t}\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tgetVars(shader?: string): Record<string, any> {\n\t\treturn this.inputs.vars[(shader ?? this.shader) as keyof IShaderCode];\n\t}\n\n\tgetNodeData(node: Node | string): Record<string, any> {\n\t\tconst uuid = node instanceof Node ? node.uuid : node;\n\t\treturn (this.nodeData[uuid] = this.nodeData[uuid] || {});\n\t}\n\n\tcreateUniform(\n\t\tshader: string,\n\t\ttype: string,\n\t\tnode: Node,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean,\n\t\tlabel?: string\n\t): NodeUniform {\n\t\tif (type.includes('[]')) {\n\t\t\tconst uniforms = this.inputs.arrayUniforms;\n\t\t\tconst index = uniforms.list.length;\n\n\t\t\tconst uniform = new NodeUniform({\n\t\t\t\ttype: type,\n\t\t\t\tsize: (node as any).size,\n\t\t\t\tname: ns ? ns : 'nodeUA' + index + (label ? '_' + label : ''),\n\t\t\t\tnode: node,\n\t\t\t\tneedsUpdate: needsUpdate as boolean,\n\t\t\t});\n\n\t\t\tuniforms.list.push(uniform);\n\n\t\t\tuniforms[shader as keyof IShaderCode].push(uniform);\n\t\t\tuniforms[shader as keyof IShaderCode][uniform.name as string] = uniform;\n\n\t\t\tthis.uniforms[uniform.name as string] = uniform;\n\n\t\t\treturn uniform;\n\t\t} else {\n\t\t\tconst uniforms = this.inputs.uniforms;\n\t\t\tconst index = uniforms.list.length;\n\n\t\t\tconst uniform = new NodeUniform({\n\t\t\t\ttype: type,\n\t\t\t\tname: ns ? ns : 'nodeU' + index + (label ? '_' + label : ''),\n\t\t\t\tnode: node,\n\t\t\t\tneedsUpdate: needsUpdate as boolean,\n\t\t\t});\n\n\t\t\tuniforms.list.push(uniform);\n\n\t\t\tuniforms[shader as keyof IShaderCode].push(uniform);\n\t\t\tuniforms[shader as keyof IShaderCode][uniform.name as string] = uniform;\n\n\t\t\tthis.uniforms[uniform.name as string] = uniform;\n\n\t\t\treturn uniform;\n\t\t}\n\t}\n\n\tcreateVertexUniform(\n\t\ttype: string,\n\t\tnode: Node,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean,\n\t\tlabel?: string\n\t): NodeUniform {\n\t\treturn this.createUniform('vertex', type, node, ns, needsUpdate, label);\n\t}\n\n\tcreateFragmentUniform(\n\t\ttype: string,\n\t\tnode: Node,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean,\n\t\tlabel?: string\n\t): NodeUniform {\n\t\treturn this.createUniform('fragment', type, node, ns, needsUpdate, label);\n\t}\n\n\tinclude(node: Node, parent?: Node, source?: string): string {\n\t\tlet includesStruct;\n\n\t\tnode = typeof node === 'string' ? nodeLib.get(node) : node;\n\n\t\tif (this.context.include === false) {\n\t\t\treturn node.name;\n\t\t}\n\n\t\tif (node instanceof FunctionNode) {\n\t\t\tincludesStruct = this.includes.functions;\n\t\t} else if (node instanceof ConstNode) {\n\t\t\tincludesStruct = this.includes.consts;\n\t\t} else if (node instanceof StructNode) {\n\t\t\tincludesStruct = this.includes.structs;\n\t\t}\n\n\t\tconst includes = (includesStruct[this.shader] =\n\t\t\tincludesStruct[this.shader] || []);\n\n\t\tif (node) {\n\t\t\tlet included = includes[node.name];\n\n\t\t\tif (!included) {\n\t\t\t\tincluded = includes[node.name] = {\n\t\t\t\t\tnode: node,\n\t\t\t\t\tdeps: [],\n\t\t\t\t};\n\n\t\t\t\tincludes.push(included);\n\n\t\t\t\tincluded.src = node.build(this, 'source');\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tnode instanceof FunctionNode &&\n\t\t\t\tparent &&\n\t\t\t\tincludes[parent.name] &&\n\t\t\t\tincludes[parent.name].deps.indexOf(node) === -1\n\t\t\t) {\n\t\t\t\tincludes[parent.name].deps.push(node);\n\n\t\t\t\tif (node.includes?.length) {\n\t\t\t\t\tlet i = 0;\n\n\t\t\t\t\tdo {\n\t\t\t\t\t\tthis.include(node.includes[i++], parent);\n\t\t\t\t\t} while (i < node.includes.length);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (source) {\n\t\t\t\tincluded.src = source;\n\t\t\t}\n\n\t\t\treturn node.name;\n\t\t} else {\n\t\t\tthrow new Error('Include not found.');\n\t\t}\n\t}\n\n\tcolorToVectorProperties(color: string): string {\n\t\treturn color\n\t\t\t.replace('r', 'x')\n\t\t\t.replace('g', 'y')\n\t\t\t.replace('b', 'z')\n\t\t\t.replace('a', 'w');\n\t}\n\n\tcolorToVector(color: string): string {\n\t\treturn color.replace(/c/g, 'v3');\n\t}\n\n\tgetIncludes(type: string, shader: string): Record<string, unknown>[] {\n\t\treturn this.includes[type][shader || this.shader];\n\t}\n\n\tgetIncludesCode: (type: string, shader: string) => string = (function () {\n\t\tfunction sortByPosition(a: any, b: any) {\n\t\t\treturn a.deps.length - b.deps.length;\n\t\t}\n\n\t\treturn function getIncludesCode(\n\t\t\tthis: NodeBuilder,\n\t\t\ttype: string,\n\t\t\tshader: string\n\t\t) {\n\t\t\tlet includes = this.getIncludes(type, shader);\n\n\t\t\tif (!includes) return '';\n\n\t\t\tlet code = '';\n\t\t\tincludes = includes.sort(sortByPosition);\n\n\t\t\tfor (let i = 0; i < includes.length; i++) {\n\t\t\t\tif (includes[i].src) code += includes[i].src + '\\n';\n\t\t\t}\n\n\t\t\treturn code;\n\t\t};\n\t})();\n\n\tgetConstructorFromLength(len: number): string {\n\t\treturn constructors[len - 1];\n\t}\n\n\tisTypeMatrix(format: string): boolean {\n\t\treturn /^m/.test(format);\n\t}\n\n\tgetTypeLength(type: string): number {\n\t\tif (type === 'f') return 1;\n\t\treturn parseInt(this.colorToVector(type).substr(1));\n\t}\n\n\tgetTypeFromLength(len: number): string {\n\t\tif (len === 1) return 'f';\n\t\treturn 'v' + len;\n\t}\n\n\tfindNode(...args: any[]): Node | undefined {\n\t\tfor (let i = 0; i < arguments.length; i++) {\n\t\t\tconst nodeCandidate = args[i];\n\n\t\t\tif (nodeCandidate?.isNode) {\n\t\t\t\treturn nodeCandidate;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tresolve(...args: any[]): Node | undefined {\n\t\tfor (let i = 0; i < arguments.length; i++) {\n\t\t\tconst nodeCandidate = args[i];\n\n\t\t\tif (nodeCandidate !== undefined) {\n\t\t\t\tif (nodeCandidate.isNode) {\n\t\t\t\t\treturn nodeCandidate;\n\t\t\t\t} else if (nodeCandidate.isTexture) {\n\t\t\t\t\tswitch (nodeCandidate.mapping) {\n\t\t\t\t\t\tcase CubeReflectionMapping:\n\t\t\t\t\t\tcase CubeRefractionMapping:\n\t\t\t\t\t\t\treturn new CubeTextureNode(nodeCandidate);\n\n\t\t\t\t\t\tcase CubeUVReflectionMapping:\n\t\t\t\t\t\tcase CubeUVRefractionMapping:\n\t\t\t\t\t\t\treturn new TextureCubeNode(new TextureNode(nodeCandidate));\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn new TextureNode(nodeCandidate);\n\t\t\t\t\t}\n\t\t\t\t} else if (nodeCandidate.isVector2) {\n\t\t\t\t\treturn new Vector2Node(nodeCandidate);\n\t\t\t\t} else if (nodeCandidate.isVector3) {\n\t\t\t\t\treturn new Vector3Node(nodeCandidate);\n\t\t\t\t} else if (nodeCandidate.isVector4) {\n\t\t\t\t\treturn new Vector4Node(nodeCandidate);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tformat(code: string, from: string, to: string): string {\n\t\tconst typeToType = this.colorToVector(to + ' <- ' + from);\n\n\t\tswitch (typeToType) {\n\t\t\tcase 'f <- v2':\n\t\t\t\treturn code + '.x';\n\t\t\tcase 'f <- v3':\n\t\t\t\treturn code + '.x';\n\t\t\tcase 'f <- v4':\n\t\t\t\treturn code + '.x';\n\t\t\tcase 'f <- i':\n\t\t\tcase 'f <- b':\n\t\t\t\treturn 'float( ' + code + ' )';\n\n\t\t\tcase 'v2 <- f':\n\t\t\t\treturn 'vec2( ' + code + ' )';\n\t\t\tcase 'v2 <- v3':\n\t\t\t\treturn code + '.xy';\n\t\t\tcase 'v2 <- v4':\n\t\t\t\treturn code + '.xy';\n\t\t\tcase 'v2 <- i':\n\t\t\tcase 'v2 <- b':\n\t\t\t\treturn 'vec2( float( ' + code + ' ) )';\n\n\t\t\tcase 'v3 <- f':\n\t\t\t\treturn 'vec3( ' + code + ' )';\n\t\t\tcase 'v3 <- v2':\n\t\t\t\treturn 'vec3( ' + code + ', 0.0 )';\n\t\t\tcase 'v3 <- v4':\n\t\t\t\treturn code + '.xyz';\n\t\t\tcase 'v3 <- i':\n\t\t\tcase 'v3 <- b':\n\t\t\t\treturn 'vec2( float( ' + code + ' ) )';\n\n\t\t\tcase 'v4 <- f':\n\t\t\t\treturn 'vec4( ' + code + ' )';\n\t\t\tcase 'v4 <- v2':\n\t\t\t\treturn 'vec4( ' + code + ', 0.0, 1.0 )';\n\t\t\tcase 'v4 <- v3':\n\t\t\t\treturn 'vec4( ' + code + ', 1.0 )';\n\t\t\tcase 'v4 <- i':\n\t\t\tcase 'v4 <- b':\n\t\t\t\treturn 'vec4( float( ' + code + ' ) )';\n\n\t\t\tcase 'i <- f':\n\t\t\tcase 'i <- b':\n\t\t\t\treturn 'int( ' + code + ' )';\n\t\t\tcase 'i <- v2':\n\t\t\t\treturn 'int( ' + code + '.x )';\n\t\t\tcase 'i <- v3':\n\t\t\t\treturn 'int( ' + code + '.x )';\n\t\t\tcase 'i <- v4':\n\t\t\t\treturn 'int( ' + code + '.x )';\n\n\t\t\tcase 'b <- f':\n\t\t\t\treturn '( ' + code + ' != 0.0 )';\n\t\t\tcase 'b <- v2':\n\t\t\t\treturn '( ' + code + ' != vec2( 0.0 ) )';\n\t\t\tcase 'b <- v3':\n\t\t\t\treturn '( ' + code + ' != vec3( 0.0 ) )';\n\t\t\tcase 'b <- v4':\n\t\t\t\treturn '( ' + code + ' != vec4( 0.0 ) )';\n\t\t\tcase 'b <- i':\n\t\t\t\treturn '( ' + code + ' != 0 )';\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tgetTypeByFormat(format: string): string {\n\t\treturn convertFormatToType[format] || format;\n\t}\n\n\tgetFormatByType(type: string): string {\n\t\treturn convertTypeToFormat[type] || type;\n\t}\n\n\tgetUUID(uuid: string, useCache?: boolean): string {\n\t\tuseCache = useCache !== undefined ? useCache : true;\n\n\t\tif (useCache && this.cache) uuid = this.cache + '-' + uuid;\n\n\t\treturn uuid;\n\t}\n\n\tgetElementByIndex(index: number): string {\n\t\treturn elements[index];\n\t}\n\n\tgetIndexByElement(elm: string): number {\n\t\treturn elements.indexOf(elm);\n\t}\n\n\tisShader(shader: string): boolean {\n\t\treturn this.shader === shader;\n\t}\n\n\tsetShader(shader: string): this {\n\t\tthis.shader = shader;\n\t\treturn this;\n\t}\n\n\tmergeDefines(defines: Record<string, any>): Record<string, any> {\n\t\tfor (const name in defines) {\n\t\t\tthis.defines[name] = defines[name];\n\t\t}\n\n\t\treturn this.defines;\n\t}\n\n\tmergeUniform(uniforms: Record<string, unknown>): Record<string, unknown> {\n\t\tfor (const name in uniforms) {\n\t\t\tthis.uniforms[name] = uniforms[name];\n\t\t}\n\t\treturn this.uniforms;\n\t}\n\n\tgetTextureEncodingFromMap(map: Texture): TextureEncoding {\n\t\tlet encoding;\n\n\t\tif (!map) {\n\t\t\tencoding = LinearEncoding;\n\t\t} else if (map.isTexture) {\n\t\t\tencoding = map.encoding;\n\t\t\t/*\n\t\t\t } else if (map.isWebGLRenderTarget) {\n\t\t\t encoding = map.texture.encoding;\n\t\t\t */\n\t\t}\n\n\t\tif (encoding === LinearEncoding && this.context.gamma) {\n\t\t\tencoding = sRGBEncoding;\n\t\t}\n\n\t\treturn encoding as TextureEncoding;\n\t}\n}\n", "import type { Node } from './Node';\n\nexport interface INodeUniformParams {\n\tname: string;\n\ttype: string;\n\tsize?: number;\n\tnode: Node;\n\tneedsUpdate: boolean;\n}\n\nexport class NodeUniform {\n\tname: string | undefined;\n\ttype: string | undefined;\n\tsize: number | undefined;\n\tnode: Node;\n\tneedsUpdate: boolean | undefined;\n\n\tconstructor(params: INodeUniformParams) {\n\t\tparams = params ?? {};\n\t\tthis.name = params.name;\n\t\tthis.type = params.type;\n\t\tthis.node = params.node;\n\t\tthis.size = params.size;\n\t\tthis.needsUpdate = params.needsUpdate;\n\t}\n\n\tget value(): any {\n\t\treturn this.node.value;\n\t}\n\n\tset value(val: any) {\n\t\tthis.node.value = val;\n\t}\n}\n", "import { MathUtils } from 'three';\nimport { Meta, SerializedNode } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\nimport { NodeBuilder } from './NodeBuilder';\nimport { NodeFrame } from './NodeFrame';\n\nexport type Flow = {\n\tresult: string;\n\tcode: string;\n\textra: Record<string, unknown>;\n};\n\nexport class Node {\n\tuserData: Record<string, unknown>;\n\n\thashProperties: string[] | undefined = undefined;\n\n\tname: string;\n\tuuid: string;\n\ttype: string | undefined;\n\tvalue: any;\n\tisNode: boolean = true;\n\tframeId: number | undefined;\n\tshortcuts: Record<string, unknown> = {};\n\n\tconstructor(type?: string) {\n\t\tthis.uuid = MathUtils.generateUUID();\n\t\tthis.type = type;\n\t\tthis.name = '';\n\t\tthis.userData = {};\n\t}\n\n\tanalyze(builder: NodeBuilder, settings?: Record<string, any>): void {\n\t\tsettings = settings ?? {};\n\n\t\tbuilder.analyzing = true;\n\t\tthis.build(\n\t\t\tbuilder.addFlow(settings.slot, settings.cache, settings.context),\n\t\t\t'v4'\n\t\t);\n\n\t\tbuilder.clearVertexNodeCode();\n\t\tbuilder.clearFragmentNodeCode();\n\n\t\tbuilder.removeFlow();\n\n\t\tbuilder.analyzing = false;\n\t}\n\n\tanalyzeAndFlow(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tsettings?: Record<string, unknown>\n\t): Flow {\n\t\tsettings = settings ?? {};\n\n\t\tthis.analyze(builder, settings);\n\t\treturn this.flow(builder, output, settings);\n\t}\n\n\tflow(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tsettings?: Record<string, any>\n\t): Flow {\n\t\tsettings = settings ?? {};\n\n\t\tbuilder.addFlow(settings.slot, settings.cache, settings.context);\n\n\t\tconst flow: Flow = {\n\t\t\tresult: this.build(builder, output),\n\t\t\tcode: builder.clearNodeCode(),\n\t\t\textra: builder.context.extra,\n\t\t};\n\n\t\tbuilder.removeFlow();\n\n\t\treturn flow;\n\t}\n\n\tbuild(builder: NodeBuilder, output?: string, uuid?: string): string {\n\t\toutput = output ?? this.getType(builder, output);\n\n\t\tconst data = builder.getNodeData(uuid ?? this);\n\n\t\tif (builder.analyzing) {\n\t\t\tthis.appendDepsNode(builder, data, output as string);\n\t\t}\n\n\t\tif (builder.nodes.indexOf(this as Record<string, unknown>) === -1) {\n\t\t\tbuilder.nodes.push(this as Record<string, unknown>);\n\t\t}\n\n\t\tif (\n\t\t\tthis.updateFrame !== undefined &&\n\t\t\tbuilder.updaters.indexOf(this) === -1\n\t\t) {\n\t\t\tbuilder.updaters.push(this);\n\t\t}\n\n\t\treturn this.generate(builder, output as string, uuid);\n\t}\n\n\tupdateFrame(frame: NodeFrame): void {}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean\n\t): string {\n\t\treturn '';\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string\n\t): string {\n\t\treturn '';\n\t}\n\n\tparse(\n\t\tsrc: string,\n\t\tincludes?: Record<string, any>,\n\t\textensions?: Record<string, any>,\n\t\tkeywords?: Record<string, any>\n\t): void {}\n\n\tappendDepsNode(\n\t\tbuilder: NodeBuilder,\n\t\tdata: Record<string, any>,\n\t\toutput: string\n\t): void {\n\t\tdata.deps = (data.deps || 0) + 1;\n\n\t\tconst outputLen = builder.getTypeLength(output);\n\n\t\tif (outputLen > (data.outputMax || 0) || this.getType(builder, output)) {\n\t\t\tdata.outputMax = outputLen;\n\t\t\tdata.output = output;\n\t\t}\n\t}\n\n\tsetName(name: string): void {\n\t\tthis.name = name;\n\t}\n\n\tgetName(): string {\n\t\treturn this.name;\n\t}\n\n\tgetType(builder: NodeBuilder, output?: string): string | undefined {\n\t\treturn output === 'sampler2D' || output === 'samplerCube'\n\t\t\t? output\n\t\t\t: this.type;\n\t}\n\n\tgetJSONNode(meta?: Meta): Record<string, any> | undefined {\n\t\tif (meta?.materials && meta?.materials[this.uuid] !== undefined) {\n\t\t\treturn meta.materials[this.uuid];\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tgetHash(): string {\n\t\tlet hash = '{';\n\t\tlet prop, obj;\n\n\t\tfor (prop in this) {\n\t\t\tobj = this[prop as keyof Node];\n\n\t\t\tif (obj instanceof Node) {\n\t\t\t\thash += '\"' + prop + '\":' + obj.getHash() + ',';\n\t\t\t}\n\t\t}\n\n\t\tif (this.hashProperties) {\n\t\t\tfor (let i = 0; i < this.hashProperties.length; i++) {\n\t\t\t\tprop = this.hashProperties[i];\n\t\t\t\tobj = this[prop as keyof Node];\n\n\t\t\t\thash += '\"' + prop + '\":\"' + String(obj) + '\",';\n\t\t\t}\n\t\t}\n\n\t\thash += '\"id\":\"' + this.uuid + '\"}';\n\n\t\treturn hash;\n\t}\n\n\tcopy(source: Node): this {\n\t\tthis.name = source.name;\n\t\tif (source.type) this.type = source.type;\n\t\tif (source.frameId) this.frameId = source.frameId;\n\t\tif (source.hashProperties)\n\t\t\tthis.hashProperties = source.hashProperties.map((prop) => prop);\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\tthis.userData = JSON.parse(JSON.stringify(source.userData));\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\tthis.shortcuts = JSON.parse(JSON.stringify(source.shortcuts));\n\n\t\treturn this;\n\t}\n\n\tclone(): this {\n\t\treturn new (this.constructor as any)().copy(this);\n\t}\n\n\tcreateJSONNode(meta?: Meta): Record<string, unknown> {\n\t\tconst isRootObject = meta === undefined || typeof meta === 'string';\n\n\t\tif (typeof this.type !== 'string')\n\t\t\tthrow new Error('Node does not allow serialization.');\n\n\t\tconst data: Record<string, unknown> = {};\n\n\t\tdata.uuid = this.uuid;\n\t\tdata.type = this.type;\n\n\t\tif (this.name !== '') data.name = this.name;\n\n\t\tif (JSON.stringify(this.userData) !== '{}') data.userData = this.userData;\n\n\t\tif (!isRootObject && meta) {\n\t\t\t// (meta as Record<string, any>).materials[this.uuid] = data;\n\t\t\tmeta.nodes[this.uuid] = data as SerializedNode;\n\t\t}\n\n\t\treturn data;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, any> {\n\t\treturn this.getJSONNode(meta) ?? this.createJSONNode(meta);\n\t}\n\n\tfromJSON(source: Record<string, any>, _assetLibrary: AssetLibrary): this {\n\t\tthis.uuid = source.uuid as string;\n\t\tthis.type = source.type as string;\n\t\tif (source.name) this.name = source.name as string;\n\t\tif (source.userData)\n\t\t\tthis.userData = source.userData as Record<string, unknown>;\n\t\treturn this;\n\t}\n}\n", "import { Node } from './Node';\nimport { NodeBuilder } from './NodeBuilder';\n\nexport interface INodeLibKeyword {\n\tcallback: (builder: NodeBuilder) => void;\n\tcache?: Record<string, unknown> | boolean;\n}\n\nclass NodeLib {\n\tnodes: Record<string, Node> = {};\n\tkeywords: Record<string, INodeLibKeyword> = {};\n\n\tadd(node: Node): void {\n\t\tthis.nodes[node.name] = node;\n\t}\n\n\taddKeyword(\n\t\tname: string,\n\t\tcallback: (builder: NodeBuilder) => void,\n\t\tcache?: Record<string, unknown> | boolean\n\t): void {\n\t\tcache = cache !== undefined ? cache : true;\n\n\t\tthis.keywords[name] = { callback: callback, cache: cache };\n\t}\n\n\tremove(node: Node): void {\n\t\tdelete this.nodes[node.name];\n\t}\n\n\tremoveKeyword(name: string): void {\n\t\tdelete this.keywords[name];\n\t}\n\n\tget(name: string): Node {\n\t\treturn this.nodes[name];\n\t}\n\n\tgetKeyword(name: string, builder: NodeBuilder): void {\n\t\treturn this.keywords[name].callback(builder);\n\t}\n\n\tgetKeywordData(name: string): INodeLibKeyword {\n\t\treturn this.keywords[name];\n\t}\n\n\tcontains(name: string): boolean {\n\t\treturn this.nodes[name] !== undefined;\n\t}\n\n\tcontainsKeyword(name: string): boolean {\n\t\treturn this.keywords[name] !== undefined;\n\t}\n}\n\nexport const nodeLib = new NodeLib();\n", "import { Vector2 } from 'three';\nimport { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class Vector2Node extends InputNode {\n\tnodeType: string = 'Vector2';\n\n\tvalue: Vector2;\n\n\tget x() {\n\t\treturn this.value.x;\n\t}\n\tset x(val) {\n\t\tthis.value.x = val;\n\t}\n\n\tget y() {\n\t\treturn this.value.y;\n\t}\n\tset y(val) {\n\t\tthis.value.y = val;\n\t}\n\n\tconstructor(x: Vector2 | number = 0, y?: number) {\n\t\tsuper('v2');\n\t\tthis.value = x instanceof Vector2 ? x : new Vector2(x, y);\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\t'vec2(' + this.value.x + ', ' + this.value.y + ')',\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\n\t\treturn this;\n\t}\n}\n", "import { Node } from './Node';\nimport { MathUtils } from 'three';\nimport type { NodeBuilder } from './NodeBuilder';\n\nexport interface ITempNodeParams {\n\tshared?: boolean;\n\tunique?: boolean;\n}\n\nexport class TempNode extends Node {\n\tshared: boolean;\n\tunique: boolean;\n\tlabel: string | undefined;\n\tscope: string = '';\n\n\tconstructor(type?: string, params?: ITempNodeParams) {\n\t\tsuper(type);\n\n\t\tparams = params ?? {};\n\n\t\tthis.shared = params.shared !== undefined ? params.shared : true;\n\t\tthis.unique = params.unique !== undefined ? params.unique : false;\n\t}\n\n\tbuild(\n\t\tbuilder: NodeBuilder,\n\t\toutput?: string,\n\t\tuuid?: string,\n\t\tns?: string\n\t): string {\n\t\toutput = (output ?? this.getType(builder)) as string;\n\n\t\tif (this.getShared(builder, output)) {\n\t\t\tconst isUnique = this.getUnique(builder, output);\n\n\t\t\tif (isUnique && this.uuid === undefined) {\n\t\t\t\tthis.uuid = MathUtils.generateUUID();\n\t\t\t}\n\n\t\t\tuuid = builder.getUUID(uuid ?? this.getUUID(), !isUnique);\n\n\t\t\tconst data = builder.getNodeData(uuid);\n\t\t\tconst type = data.output || this.getType(builder);\n\n\t\t\tif (builder.analyzing) {\n\t\t\t\tif ((data.deps || 0) > 0 || this.getLabel()) {\n\t\t\t\t\tthis.appendDepsNode(builder, data, output);\n\t\t\t\t\treturn this.generate(builder, output, uuid);\n\t\t\t\t}\n\n\t\t\t\treturn super.build(builder, output, uuid);\n\t\t\t} else if (isUnique) {\n\t\t\t\tdata.name = data.name || super.build(builder, output, uuid);\n\n\t\t\t\treturn data.name;\n\t\t\t} else if (\n\t\t\t\t!this.getLabel() &&\n\t\t\t\t(!this.getShared(builder, type) ||\n\t\t\t\t\tbuilder.context.ignoreCache ||\n\t\t\t\t\tdata.deps === 1)\n\t\t\t) {\n\t\t\t\treturn super.build(builder, output, uuid);\n\t\t\t}\n\n\t\t\tuuid = this.getUUID(false);\n\n\t\t\tlet name = this.getTemp(builder, uuid);\n\n\t\t\tif (name) {\n\t\t\t\treturn builder.format(name, type, output);\n\t\t\t} else {\n\t\t\t\tname = super.generate(builder, output, uuid, data.output, ns);\n\n\t\t\t\tconst code = this.generate(builder, type, uuid);\n\n\t\t\t\tbuilder.addNodeCode(name + ' = ' + code + ';');\n\n\t\t\t\treturn builder.format(name, type, output);\n\t\t\t}\n\t\t}\n\n\t\treturn super.build(builder, output, uuid);\n\t}\n\n\tgetShared(_builder: NodeBuilder, output: string): boolean {\n\t\treturn output !== 'sampler2D' && output !== 'samplerCube' && this.shared;\n\t}\n\n\tgetUnique(_builder: NodeBuilder, _output: string): boolean {\n\t\treturn this.unique;\n\t}\n\n\tsetLabel(name: string): this {\n\t\tthis.label = name;\n\t\treturn this;\n\t}\n\n\tgetLabel(/*builder: NodeBuilder*/): string {\n\t\treturn this.label as string;\n\t}\n\n\tgetUUID(_unique?: boolean): string {\n\t\tlet uuid = this.uuid;\n\n\t\tif (typeof this.scope === 'string') uuid = this.scope + '-' + uuid;\n\n\t\treturn uuid;\n\t}\n\n\tgetTemp(builder: NodeBuilder, uuid: string): string | undefined {\n\t\tuuid = uuid || this.uuid;\n\t\tconst tempVar = builder.getVars()[uuid];\n\t\treturn tempVar ? tempVar.name : undefined;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string\n\t): string {\n\t\tif (!this.getShared(builder, output))\n\t\t\tconsole.error('TempNode is not shared');\n\n\t\tuuid = uuid ?? this.uuid;\n\n\t\treturn builder.getTempVar(\n\t\t\tuuid,\n\t\t\t(type ?? this.getType(builder)) as string,\n\t\t\tns as string,\n\t\t\tthis.getLabel()\n\t\t).name;\n\t}\n}\n", "import { TempNode, ITempNodeParams } from './TempNode';\nimport { NodeBuilder } from './NodeBuilder';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class InputNode extends TempNode {\n\treadonly: boolean;\n\n\tconstructor(type: string, params?: ITempNodeParams) {\n\t\tparams = params ?? {};\n\t\tparams.shared = params.shared !== undefined ? params.shared : false;\n\n\t\tsuper(type, params);\n\n\t\tthis.readonly = false;\n\t}\n\n\tsetReadonly(value: boolean): this {\n\t\tthis.readonly = value;\n\n\t\tthis.hashProperties = this.readonly ? ['value'] : undefined;\n\n\t\treturn this;\n\t}\n\n\tgetReadonly(): boolean {\n\t\treturn this.readonly;\n\t}\n\n\tcreateJSONNode(meta?: Meta): Record<string, any> {\n\t\tconst data = super.createJSONNode(meta);\n\t\tif (this.readonly === true) data.readonly = this.readonly;\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, any>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.readonly !== undefined) {\n\t\t\tthis.setReadonly(source.readonly as boolean);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean\n\t): string {\n\t\tuuid = builder.getUUID(uuid ?? this.getUUID());\n\t\ttype = type ?? this.getType(builder);\n\n\t\tconst data = builder.getNodeData(uuid);\n\t\tconst readonly = this.getReadonly() && this.generateReadonly !== undefined;\n\n\t\tif (readonly) {\n\t\t\treturn this.generateReadonly(\n\t\t\t\tbuilder,\n\t\t\t\toutput,\n\t\t\t\tuuid,\n\t\t\t\ttype,\n\t\t\t\tns,\n\t\t\t\tneedsUpdate\n\t\t\t);\n\t\t} else {\n\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\tif (!data.vertex) {\n\t\t\t\t\tdata.vertex = builder.createVertexUniform(\n\t\t\t\t\t\ttype as string,\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tns,\n\t\t\t\t\t\tneedsUpdate,\n\t\t\t\t\t\tthis.getLabel()\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn builder.format(data.vertex.name, type as string, output);\n\t\t\t} else {\n\t\t\t\tif (!data.fragment) {\n\t\t\t\t\tdata.fragment = builder.createFragmentUniform(\n\t\t\t\t\t\ttype as string,\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tns,\n\t\t\t\t\t\tneedsUpdate,\n\t\t\t\t\t\tthis.getLabel()\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn builder.format(data.fragment.name, type as string, output);\n\t\t\t}\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.readonly = source.readonly;\n\n\t\treturn this;\n\t}\n}\n", "import { Vector3 } from 'three';\n\nimport { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class Vector3Node extends InputNode {\n\tnodeType: string = 'Vector3';\n\n\tvalue: Vector3;\n\n\tget x() {\n\t\treturn this.value.x;\n\t}\n\tset x(val) {\n\t\tthis.value.x = val;\n\t}\n\n\tget y() {\n\t\treturn this.value.y;\n\t}\n\tset y(val) {\n\t\tthis.value.y = val;\n\t}\n\n\tget z() {\n\t\treturn this.value.z;\n\t}\n\tset z(val) {\n\t\tthis.value.z = val;\n\t}\n\n\tconstructor(x: Vector3 | number = 0, y?: number, z?: number) {\n\t\tsuper('v3');\n\t\tthis.value = x instanceof Vector3 ? x : new Vector3(x, y, z);\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\t'vec3(' + this.value.x + ', ' + this.value.y + ', ' + this.value.z + ')',\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\n\t\treturn this;\n\t}\n}\n", "import { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nimport { RGBA } from 'spline-data';\nimport { ColorA } from '../../../objects/Color';\n\nexport class Vector4Node extends InputNode {\n\tnodeType: string = 'Vector4';\n\tvalue: ColorA;\n\n\tconstructor(value: RGBA | ColorA) {\n\t\tsuper('v4');\n\t\tthis.value =\n\t\t\tvalue instanceof ColorA\n\t\t\t\t? value\n\t\t\t\t: new ColorA(value.r, value.g, value.b, value.a);\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\t'vec4(' +\n\t\t\t\tthis.value.r +\n\t\t\t\t', ' +\n\t\t\t\tthis.value.g +\n\t\t\t\t', ' +\n\t\t\t\tthis.value.b +\n\t\t\t\t', ' +\n\t\t\t\tthis.value.a +\n\t\t\t\t')',\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: Vector4Node): this {\n\t\tsuper.copy(source as this);\n\n\t\tthis.value.copy(source.value);\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from './TempNode';\nimport { NodeBuilder } from './NodeBuilder';\nimport { nodeLib } from '../core/NodeLib';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Node } from './Node';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport interface IFunctionNodeInput {\n\tname: string;\n\ttype: string;\n\tqualifier: string;\n}\n\nconst declarationRegexp = /^\\s*([a-z_0-9]+)\\s([a-z_0-9]+)\\s*\\((.*?)\\)/i;\nconst propertiesRegexp = /[a-z_0-9]+/gi;\n\nexport class FunctionNode extends TempNode {\n\tisMethod: boolean;\n\tisInterface: boolean;\n\tsrc: string = '';\n\tnodeType: string = 'Function';\n\tuseKeywords: boolean = true;\n\n\tinputs: IFunctionNodeInput[] | undefined;\n\tincludes: Node[] = [];\n\textensions: Record<string, boolean> = {};\n\tkeywords: Record<string, Node> = {};\n\n\tconstructor(\n\t\tsrc: string,\n\t\tincludes?: Node[],\n\t\textensions?: Record<string, boolean>,\n\t\tkeywords?: Record<string, Node>,\n\t\ttype?: string\n\t) {\n\t\tsuper(type);\n\t\tthis.isMethod = type === undefined;\n\t\tthis.isInterface = false;\n\n\t\tthis.parse(src, includes, extensions, keywords);\n\t}\n\n\tgetShared(_builder: NodeBuilder, _output: string): boolean {\n\t\treturn !this.isMethod;\n\t}\n\n\tgetType(builder: NodeBuilder): string {\n\t\treturn builder.getTypeByFormat(this.type as string);\n\t}\n\n\tgetInputByName(name: string): IFunctionNodeInput | undefined {\n\t\tif (this.inputs) {\n\t\t\tlet i = this.inputs.length;\n\n\t\t\twhile (i--) {\n\t\t\t\tif (this.inputs[i].name === name) {\n\t\t\t\t\treturn this.inputs[i];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgetIncludeByName(name: string): Node | undefined {\n\t\tif (this.includes) {\n\t\t\tlet i = this.includes.length;\n\n\t\t\twhile (i--) {\n\t\t\t\tif (this.includes[i].name === name) {\n\t\t\t\t\treturn this.includes[i];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\tlet match,\n\t\t\toffset = 0,\n\t\t\tsrc = this.src;\n\n\t\tif (this.includes) {\n\t\t\tfor (let i = 0; i < this.includes.length; i++) {\n\t\t\t\tbuilder.include(this.includes[i], this);\n\t\t\t}\n\t\t}\n\n\t\tfor (const ext in this.extensions) {\n\t\t\tbuilder.extensions[ext as keyof typeof builder.extensions] = true;\n\t\t}\n\n\t\tconst matches = [];\n\n\t\twhile ((match = propertiesRegexp.exec(this.src))) matches.push(match);\n\n\t\tfor (let i = 0; i < matches.length; i++) {\n\t\t\tconst match = matches[i];\n\n\t\t\tconst prop = match[0];\n\t\t\tconst isGlobal = this.isMethod ? !this.getInputByName(prop) : true;\n\t\t\tlet reference = prop;\n\n\t\t\tif (\n\t\t\t\tthis.keywords[prop] ||\n\t\t\t\t(this.useKeywords && isGlobal && nodeLib.containsKeyword(prop))\n\t\t\t) {\n\t\t\t\tlet node = this.keywords[prop];\n\n\t\t\t\tif (!node) {\n\t\t\t\t\tconst keyword = nodeLib.getKeywordData(prop);\n\n\t\t\t\t\tif (keyword.cache) node = builder.keywords[prop] as Node;\n\n\t\t\t\t\tnode = node || nodeLib.getKeyword(prop, builder);\n\n\t\t\t\t\tif (keyword.cache) builder.keywords[prop] = node;\n\t\t\t\t}\n\n\t\t\t\treference = node.build(builder);\n\t\t\t}\n\n\t\t\tif (prop !== reference) {\n\t\t\t\tsrc =\n\t\t\t\t\tsrc.substring(0, match.index + offset) +\n\t\t\t\t\treference +\n\t\t\t\t\tsrc.substring(match.index + prop.length + offset);\n\n\t\t\t\toffset += reference.length - prop.length;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tthis.getIncludeByName(reference) === undefined &&\n\t\t\t\tnodeLib.contains(reference)\n\t\t\t) {\n\t\t\t\tbuilder.include(nodeLib.get(reference));\n\t\t\t}\n\t\t}\n\n\t\tif (output === 'source') {\n\t\t\treturn src;\n\t\t} else if (this.isMethod) {\n\t\t\tif (!this.isInterface) {\n\t\t\t\tbuilder.include(this, undefined, src);\n\t\t\t}\n\n\t\t\treturn this.name;\n\t\t} else {\n\t\t\treturn builder.format('( ' + src + ' )', this.getType(builder), output);\n\t\t}\n\t}\n\n\tparse(\n\t\tsrc: string,\n\t\tincludes?: Node[],\n\t\textensions?: Record<string, boolean>,\n\t\tkeywords?: Record<string, Node>\n\t): void {\n\t\tthis.src = src || '';\n\n\t\tthis.includes = includes ?? [];\n\t\tthis.extensions = extensions ?? {};\n\t\tthis.keywords = keywords ?? {};\n\n\t\tif (this.isMethod) {\n\t\t\tconst match = declarationRegexp.exec(this.src);\n\n\t\t\tthis.inputs = [];\n\n\t\t\tif (match && match.length == 4) {\n\t\t\t\tthis.type = match[1];\n\t\t\t\tthis.name = match[2];\n\n\t\t\t\tconst inputs = match[3].match(propertiesRegexp);\n\n\t\t\t\tif (inputs) {\n\t\t\t\t\tlet i = 0;\n\n\t\t\t\t\twhile (i < inputs.length) {\n\t\t\t\t\t\tlet qualifier = inputs[i++];\n\t\t\t\t\t\tlet type;\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tqualifier === 'in' ||\n\t\t\t\t\t\t\tqualifier === 'out' ||\n\t\t\t\t\t\t\tqualifier === 'inout'\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = inputs[i++];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttype = qualifier;\n\t\t\t\t\t\t\tqualifier = '';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst name = inputs[i++];\n\n\t\t\t\t\t\tthis.inputs.push({\n\t\t\t\t\t\t\tname: name,\n\t\t\t\t\t\t\ttype: type,\n\t\t\t\t\t\t\tqualifier: qualifier,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.isInterface = this.src.indexOf('{') === -1;\n\t\t\t} else {\n\t\t\t\tthis.type = '';\n\t\t\t\tthis.name = '';\n\t\t\t}\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.isMethod = source.isMethod;\n\t\tthis.useKeywords = source.useKeywords;\n\t\tif (source.type !== undefined) this.type = source.type;\n\t\tthis.parse(source.src, source.includes, source.extensions, source.keywords);\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, unknown> {\n\t\tlet data = this.getJSONNode(meta) as Record<string, any>;\n\n\t\tif (!data) {\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.src = this.src;\n\t\t\tdata.isMethod = this.isMethod;\n\t\t\tdata.useKeywords = this.useKeywords;\n\n\t\t\tif (!this.isMethod) data.type = this.type;\n\n\t\t\tdata.extensions = JSON.parse(JSON.stringify(this.extensions)) as Record<\n\t\t\t\tstring,\n\t\t\t\tany\n\t\t\t>;\n\n\t\t\tconst keywords: Record<string, string> = {};\n\t\t\tfor (const keyword in this.keywords) {\n\t\t\t\tkeywords[keyword] = this.keywords[keyword].toJSON(meta).uuid as string;\n\t\t\t}\n\t\t\tdata.keywords = keywords;\n\n\t\t\tif (this.includes?.length) {\n\t\t\t\tconst includes: string[] = [];\n\t\t\t\tfor (let i = 0; i < this.includes.length; i++) {\n\t\t\t\t\tincludes.push(this.includes[i].toJSON(meta).uuid);\n\t\t\t\t}\n\t\t\t\tdata.includes = includes;\n\t\t\t}\n\n\t\t\tdata.isMethod = this.isMethod;\n\t\t\tdata.inputs = this.inputs;\n\t\t}\n\n\t\tdata.nodeType = this.nodeType;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, any>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.inputs !== undefined)\n\t\t\tthis.inputs = source.inputs as IFunctionNodeInput[];\n\t\tif (source.isMethod !== undefined)\n\t\t\tthis.isMethod = source.isMethod as boolean;\n\t\tif (source.src) this.src = source.src as string;\n\t\tif (source.isMethod) this.isMethod = source.isMethod as boolean;\n\t\tif (source.useKeywords) this.useKeywords = source.useKeywords as boolean;\n\t\tif (source.type) this.type = source.type as string;\n\t\tif (source.extensions)\n\t\t\tthis.extensions = source.extensions as Record<string, any>;\n\t\tif (source.keywords && assetLibrary) {\n\t\t\tthis.keywords = {};\n\t\t\tfor (const keyword in source.keywords) {\n\t\t\t\tthis.keywords[keyword] = assetLibrary.getNode(\n\t\t\t\t\t(source.keywords as Record<string, string>)[keyword]\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (source.includes && assetLibrary) {\n\t\t\tthis.includes = (source.includes as string[]).map((uuid: string) =>\n\t\t\t\tassetLibrary.getNode(uuid)\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from './TempNode';\nimport { NodeBuilder } from './NodeBuilder';\n\nconst declarationRegexp = /^([a-z_0-9]+)\\s([a-z_0-9]+)\\s?\\=?\\s?(.*?)(\\;|$)/i;\n\nexport class ConstNode extends TempNode {\n\tsrc: string = '';\n\tuseDefine: boolean = false;\n\tnodeType: string = 'Const';\n\tinputs: any;\n\n\tconstructor(src: string = '', useDefine?: boolean) {\n\t\tsuper();\n\t\tthis.parse(src || ConstNode.PI, undefined, undefined, undefined, useDefine);\n\t}\n\n\tgetType(builder: NodeBuilder): string {\n\t\treturn builder.getTypeByFormat(this.type as string);\n\t}\n\n\tparse(\n\t\tsrc: string,\n\t\t_includes?: Record<string, any>,\n\t\t_extensions?: Record<string, any>,\n\t\t_keywords?: Record<string, any>,\n\t\t_useDefine?: boolean\n\t): void {\n\t\tthis.src = src || '';\n\n\t\tlet name,\n\t\t\ttype,\n\t\t\tvalue = '';\n\n\t\tconst match = declarationRegexp.exec(src);\n\n\t\tthis.useDefine = _useDefine ?? this.src.charAt(0) === '#';\n\n\t\tif (match && match.length > 1) {\n\t\t\ttype = match[1];\n\t\t\tname = match[2];\n\t\t\tvalue = match[3];\n\t\t} else {\n\t\t\tname = this.src;\n\t\t\ttype = 'f';\n\t\t}\n\n\t\tthis.name = name;\n\t\tthis.type = type;\n\t\tthis.value = value;\n\t}\n\n\tbuild(builder: NodeBuilder, output: string): string {\n\t\tif (output === 'source') {\n\t\t\tif (this.value) {\n\t\t\t\tif (this.useDefine) {\n\t\t\t\t\treturn '#define ' + this.name + ' ' + this.value;\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t'const ' + this.type + ' ' + this.name + ' = ' + this.value + ';'\n\t\t\t\t);\n\t\t\t} else if (this.useDefine) {\n\t\t\t\treturn this.src;\n\t\t\t}\n\t\t}\n\t\tbuilder.include(this);\n\n\t\treturn builder.format(this.name, this.getType(builder), output);\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\treturn builder.format(this.name, this.getType(builder), output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.parse(source.src, undefined, undefined, undefined, source.useDefine);\n\n\t\treturn this;\n\t}\n\n\tstatic PI: string = 'PI';\n\tstatic PI2: string = 'PI2';\n\tstatic RECIPROCAL_PI: string = 'RECIPROCAL_PI';\n\tstatic RECIPROCAL_PI2: string = 'RECIPROCAL_PI2';\n\tstatic LOG2: string = 'LOG2';\n\tstatic EPSILON: string = 'EPSILON';\n}\n", "import { TempNode } from './TempNode';\nimport { NodeBuilder } from './NodeBuilder';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport interface IStructNodeInput {\n\ttype: string;\n\tname: string;\n}\n\nconst declarationRegexp = new RegExp(\n\t'^structs*([a-z_0-9]+)s*{s*((.|\\n)*?)}',\n\t'gim'\n);\nconst propertiesRegexp = new RegExp('s*(w*?)s*(w*?)(=|;)', 'gim');\n\nexport class StructNode extends TempNode {\n\tinputs: IStructNodeInput[] = [];\n\tsrc: string = '';\n\tnodeType: string = 'Struct';\n\n\tconstructor(src: string = '') {\n\t\tsuper();\n\t\tthis.parse(src);\n\t}\n\n\tgetType(builder: NodeBuilder): string {\n\t\treturn builder.getTypeByFormat(this.name);\n\t}\n\n\tgetInputByName(name: string): IStructNodeInput | undefined {\n\t\tlet i = this.inputs.length;\n\n\t\twhile (i--) {\n\t\t\tif (this.inputs[i].name === name) {\n\t\t\t\treturn this.inputs[i];\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\tif (output === 'source') {\n\t\t\treturn this.src + ';';\n\t\t} else {\n\t\t\treturn builder.format(\n\t\t\t\t'( ' + this.src + ' )',\n\t\t\t\tthis.getType(builder),\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tparse(src: string = ''): void {\n\t\tthis.src = src;\n\n\t\tthis.inputs = [];\n\n\t\tconst declaration = declarationRegexp.exec(src);\n\n\t\tif (declaration) {\n\t\t\tconst properties = declaration[2];\n\t\t\tlet match;\n\n\t\t\twhile ((match = propertiesRegexp.exec(properties))) {\n\t\t\t\tthis.inputs.push({\n\t\t\t\t\ttype: match[1],\n\t\t\t\t\tname: match[2],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.name = declaration[1];\n\t\t} else {\n\t\t\tthis.name = '';\n\t\t}\n\n\t\tthis.type = this.name;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { nodeLib } from '../core/NodeLib';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { AssetLibrary } from '../../AssetLibrary';\n\nexport class UVNode extends TempNode {\n\tindex: number;\n\tnodeType: string = 'UV';\n\n\tconstructor(index?: number) {\n\t\tsuper('v2', { shared: false });\n\t\tthis.index = index ?? 0;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tbuilder.requires.uv[this.index] = true;\n\n\t\tconst uvIndex = this.index > 0 ? this.index + 1 : '';\n\t\tconst result = builder.isShader('vertex')\n\t\t\t? 'uv' + uvIndex\n\t\t\t: 'vUv' + uvIndex;\n\n\t\treturn builder.format(result, this.getType(builder) as string, output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.index = source.index;\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, any> {\n\t\tlet data = this.getJSONNode(meta);\n\n\t\tif (!data) {\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.index = this.index;\n\t\t}\n\n\t\tdata.nodeType = this.nodeType;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, unknown>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.index) this.index = source.index as number;\n\n\t\treturn this;\n\t}\n}\n\nnodeLib.addKeyword('uv', function () {\n\treturn new UVNode();\n});\n\nnodeLib.addKeyword('uv2', function () {\n\treturn new UVNode(1);\n});\n", "import { LinearEncoding, sRGBEncoding } from 'three';\n\nimport { Node } from '../core/Node';\nimport { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FunctionNode } from '../core/FunctionNode';\n\ntype Methods = {\n\tLinearToLinear: FunctionNode;\n\tsRGBToLinear: FunctionNode;\n\tLinearTosRGB: FunctionNode;\n};\n\nexport class ColorSpaceNode extends TempNode {\n\tinput: Node;\n\tmethod: string;\n\tnodeType: string = 'ColorSpace';\n\tfactor: Node = new Node();\n\n\t// NOTE(piero): Probably move this to its own file. Lots of clutter for this file.\n\tstatic Nodes: Methods = {\n\t\tLinearToLinear: new FunctionNode(\n\t\t\t['vec4 LinearToLinear( in vec4 value ) {', '\treturn value;', '}'].join(\n\t\t\t\t'\\n'\n\t\t\t)\n\t\t),\n\t\tsRGBToLinear: new FunctionNode(\n\t\t\t[\n\t\t\t\t'vec4 sRGBToLinear( in vec4 value ) {',\n\n\t\t\t\t'\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );',\n\n\t\t\t\t'}',\n\t\t\t].join('\\n')\n\t\t),\n\t\tLinearTosRGB: new FunctionNode(\n\t\t\t[\n\t\t\t\t'vec4 LinearTosRGB( in vec4 value ) {',\n\n\t\t\t\t'\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );',\n\n\t\t\t\t'}',\n\t\t\t].join('\\n')\n\t\t),\n\t};\n\n\tstatic LINEAR_TO_LINEAR = 'LinearToLinear';\n\tstatic SRGB_TO_LINEAR = 'sRGBToLinear';\n\tstatic LINEAR_TO_SRGB = 'LinearTosRGB';\n\n\tconstructor(input: Node = new Node(), method?: string) {\n\t\tsuper('v4');\n\n\t\tthis.input = input;\n\t\tthis.method = method ?? ColorSpaceNode.LINEAR_TO_LINEAR;\n\t\tthis.hashProperties = ['method'];\n\t}\n\n\tstatic getEncodingComponents(encoding: number): any[] {\n\t\tswitch (encoding) {\n\t\t\tcase LinearEncoding:\n\t\t\t\treturn ['Linear'];\n\t\t\tcase sRGBEncoding:\n\t\t\t\treturn ['sRGB'];\n\t\t\tdefault:\n\t\t\t\treturn [];\n\t\t}\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tconst input = this.input.build(builder, 'v4');\n\t\tconst outputType = this.getType(builder);\n\n\t\tconst methodNode = ColorSpaceNode.Nodes[this.method as keyof Methods];\n\t\tconst method = builder.include(methodNode);\n\n\t\tif (method === ColorSpaceNode.LINEAR_TO_LINEAR) {\n\t\t\treturn builder.format(input, outputType as string, output);\n\t\t} else {\n\t\t\tif (methodNode.inputs?.length === 2) {\n\t\t\t\tconst factor = this.factor.build(builder, 'f');\n\n\t\t\t\treturn builder.format(\n\t\t\t\t\tmethod + '( ' + input + ', ' + factor + ' )',\n\t\t\t\t\toutputType as string,\n\t\t\t\t\toutput\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn builder.format(\n\t\t\t\t\tmethod + '( ' + input + ' )',\n\t\t\t\t\toutputType as string,\n\t\t\t\t\toutput\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfromEncoding(encoding: number): void {\n\t\tconst components = ColorSpaceNode.getEncodingComponents(encoding);\n\n\t\tthis.method = 'LinearTo' + components[0];\n\t\tthis.factor = components[1];\n\t}\n\n\tfromDecoding(encoding: number): void {\n\t\tconst components = ColorSpaceNode.getEncodingComponents(encoding);\n\n\t\tthis.method = components[0] + 'ToLinear';\n\t\tthis.factor = components[1];\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.input.copy(source.input);\n\t\tthis.method = source.method;\n\t\tthis.factor.copy(source.factor);\n\n\t\treturn this;\n\t}\n}\n", "import { FunctionNode } from './FunctionNode';\nimport { Node } from './Node';\n\nexport class ExpressionNode extends FunctionNode {\n\tnodeType: string = 'Expression';\n\n\tconstructor(\n\t\tsrc: string = '',\n\t\ttype?: string,\n\t\tkeywords?: Record<string, Node>,\n\t\textensions?: Record<string, boolean>,\n\t\tincludes?: Node[]\n\t) {\n\t\tsuper(src, includes, extensions, keywords, type);\n\t}\n}\n", "import { Texture as TTexture } from 'three';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\n\ntype ThreeImage = HTMLImageElement & {\n\tuuid: string;\n\tisDataTexture?: boolean;\n\timage?: HTMLImageElement;\n};\n\n// marcofugaro - override the three.js Texture to customize its toJSON property.\n// Changes:\n// - removed the .jpg conversion for large .png textures\n// - save .jpg textures as .jpg instead of .pngs\n// - \u26A0\uFE0F drop support for DataTextures for ease of typings\nexport class Texture extends TTexture {\n\ttoJSON(meta?: Meta) {\n\t\tconst json = super.toJSON(meta) as Record<string, any>;\n\n\t\tconst isRootObject = meta === undefined || typeof meta === 'string';\n\n\t\tif (this.image !== undefined && !isRootObject) {\n\t\t\tconst image = this.image as\n\t\t\t\t| ThreeImage\n\t\t\t\t| (ThreeImage[] & { uuid: string });\n\n\t\t\tif (Array.isArray(image)) {\n\t\t\t\t// process array of images e.g. CubeTexture\n\t\t\t\tmeta!.images[image.uuid].url = [];\n\t\t\t\tfor (let i = 0; i < image.length; i++) {\n\t\t\t\t\t// @ts-expect-error I don't know wtf is going on\n\t\t\t\t\tmeta!.images[image.uuid].url[i] = serializeImage(image[i]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// process single image\n\t\t\t\tmeta!.images[image.uuid].url = serializeImage(image);\n\t\t\t}\n\t\t}\n\n\t\treturn json;\n\t}\n}\n\nfunction serializeImage(\n\timage: HTMLImageElement | HTMLCanvasElement | ImageBitmap\n): string {\n\tif (\n\t\t(typeof HTMLImageElement !== 'undefined' &&\n\t\t\timage instanceof HTMLImageElement) ||\n\t\t(typeof HTMLCanvasElement !== 'undefined' &&\n\t\t\timage instanceof HTMLCanvasElement) ||\n\t\t(typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap)\n\t) {\n\t\t// default images\n\t\treturn getDataURL(image as HTMLImageElement);\n\t} else {\n\t\tconsole.warn('THREE.Texture: Unable to serialize Texture.');\n\t\treturn '';\n\t}\n}\n\nlet _canvas: HTMLCanvasElement;\nfunction getDataURL(image: HTMLImageElement) {\n\tif (/^data:/i.test(image.src)) {\n\t\treturn image.src;\n\t}\n\n\tlet canvas;\n\n\tif (image instanceof HTMLCanvasElement) {\n\t\tcanvas = image;\n\t} else {\n\t\tif (_canvas === undefined) {\n\t\t\t_canvas = document.createElement('canvas');\n\t\t}\n\n\t\t_canvas.width = image.width;\n\t\t_canvas.height = image.height;\n\n\t\tconst context = _canvas.getContext('2d') as CanvasRenderingContext2D;\n\n\t\tif (image instanceof ImageData) {\n\t\t\tcontext.putImageData(image, 0, 0);\n\t\t} else {\n\t\t\tcontext.drawImage(image, 0, 0, image.width, image.height);\n\t\t}\n\n\t\tcanvas = _canvas;\n\t}\n\n\t// @ts-expect-error we added fileName when uploading an image\n\tconst fileName = image.src.startsWith('blob:') ? image.fileName : image.src;\n\n\t// if it's a jpg\n\tif (/\\.jpe?g$/i.test(fileName)) {\n\t\treturn canvas.toDataURL('image/jpeg', 0.6);\n\t} else {\n\t\treturn canvas.toDataURL('image/png');\n\t}\n}\n", "import { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Node } from '../core/Node';\nimport { UVNode } from '../accessors/UVNode';\nimport { ColorSpaceNode } from '../utils/ColorSpaceNode';\nimport { ExpressionNode } from '../core/ExpressionNode';\nimport { Texture } from '../../../textures/Texture';\n\nexport class TextureNode extends InputNode {\n\tvalue: Texture;\n\tuv: UVNode;\n\tbias: Node | undefined;\n\tcolorSpace: ColorSpaceNode | undefined;\n\tproject: boolean;\n\tnodeType: string = 'Texture';\n\n\tconstructor(\n\t\tvalue: Texture = new Texture(),\n\t\tuv?: UVNode,\n\t\tbias?: Node,\n\t\tproject?: boolean\n\t) {\n\t\tsuper('v4', { shared: true });\n\n\t\tthis.value = value;\n\t\tthis.uv = uv ?? new UVNode();\n\t\tthis.bias = bias;\n\t\tthis.project = project !== undefined ? project : false;\n\t}\n\n\tgetTexture(builder: NodeBuilder, output: string): string {\n\t\treturn super.generate(builder, output, this.value.uuid, 't');\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tif (output === 'sampler2D') {\n\t\t\treturn this.getTexture(builder, output);\n\t\t}\n\n\t\tconst tex = this.getTexture(builder, output);\n\t\tconst uv = this.uv.build(builder, this.project ? 'v4' : 'v2');\n\t\tlet bias = this.bias ? this.bias.build(builder, 'f') : undefined;\n\n\t\tif (bias === undefined && builder.context.bias) {\n\t\t\tbias = builder.context.bias.setTexture(this).build(builder, 'f');\n\t\t}\n\n\t\tlet method, code;\n\n\t\tif (this.project) method = 'texture2DProj';\n\t\telse method = bias ? 'tex2DBias' : 'tex2D';\n\n\t\tif (bias) code = method + '( ' + tex + ', ' + uv + ', ' + bias + ' )';\n\t\telse code = method + '( ' + tex + ', ' + uv + ' )';\n\n\t\t// add a custom context for fix incompatibility with the core\n\t\t// include ColorSpace function only for vertex shader (in fragment shader color space functions is added automatically by core)\n\t\t// this should be removed in the future\n\t\t// context.include is used to include or not functions if used FunctionNode\n\t\t// context.ignoreCache =: not create temp variables nodeT0..9 to optimize the code\n\t\tconst context = { include: builder.isShader('vertex'), ignoreCache: true };\n\t\tconst outputType = this.getType(builder);\n\n\t\tbuilder.addContext(context);\n\n\t\tthis.colorSpace =\n\t\t\tthis.colorSpace ?? new ColorSpaceNode(new ExpressionNode('', outputType));\n\t\tthis.colorSpace.fromDecoding(builder.getTextureEncodingFromMap(this.value));\n\t\tthis.colorSpace.input.parse(code);\n\n\t\tcode = this.colorSpace.build(builder, outputType as string);\n\n\t\t// end custom context\n\n\t\tbuilder.removeContext();\n\n\t\treturn builder.format(code, outputType as string, output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\t// We don't want to actually copy\n\t\t// render target textures.\n\t\tif (source.value.isRenderTargetTexture) {\n\t\t\tthis.value = source.value;\n\t\t} else {\n\t\t\tthis.value.copy(source.value);\n\t\t}\n\t\tthis.uv.copy(source.uv);\n\t\tif (source.bias) {\n\t\t\tif (this.bias) this.bias.copy(source.bias);\n\t\t\telse this.bias = source.bias.clone();\n\t\t} else {\n\t\t\tthis.bias = undefined;\n\t\t}\n\t\tif (source.colorSpace) {\n\t\t\tif (this.colorSpace) this.colorSpace.copy(source.colorSpace);\n\t\t\telse this.colorSpace = source.colorSpace.clone();\n\t\t} else {\n\t\t\tthis.colorSpace = undefined;\n\t\t}\n\t\tthis.project = source.project;\n\n\t\tif (!source.value.isRenderTargetTexture) {\n\t\t\tthis.value.updateMatrix();\n\t\t\tthis.value.needsUpdate = true;\n\t\t}\n\t\treturn this;\n\t}\n}\n", "import { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class FloatNode extends InputNode {\n\tvalue: number;\n\tnodeType: string = 'Float';\n\n\tconstructor(value?: number) {\n\t\tsuper('f');\n\t\tthis.value = value ?? 0;\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\tthis.value + (this.value % 1 ? '' : '.0'),\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value = source.value;\n\n\t\treturn this;\n\t}\n}\n", "import { Node } from './Node';\nimport { NodeBuilder } from './NodeBuilder';\nimport { FunctionNode } from './FunctionNode';\nimport { TempNode } from './TempNode';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\n\nexport class FunctionCallNode extends TempNode {\n\tvalue: FunctionNode;\n\tinputs: Node[] = [];\n\n\tnodeType: string = 'FunctionCall';\n\n\tconstructor(func: FunctionNode, inputs?: Node[]) {\n\t\tsuper();\n\t\tthis.value = func;\n\t\tthis.inputs = inputs ?? [];\n\t}\n\n\tgetFunction(): FunctionNode {\n\t\treturn this.value;\n\t}\n\n\tgetType(builder: NodeBuilder): string {\n\t\treturn this.value.getType(builder);\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string\n\t): string {\n\t\ttype = this.getType(builder);\n\t\tconst func = this.value;\n\n\t\tlet code = func.build(builder, output) + '( ';\n\t\tconst params = [];\n\n\t\tif (func.inputs) {\n\t\t\tfor (let i = 0; i < func.inputs.length; i++) {\n\t\t\t\tconst inpt = func.inputs[i];\n\t\t\t\tconst param =\n\t\t\t\t\tthis.inputs[i] || this.inputs[(inpt.name as unknown) as number];\n\n\t\t\t\tparams.push(param.build(builder, builder.getTypeByFormat(inpt.type)));\n\t\t\t}\n\t\t\tcode += params.join(', ') + ' )';\n\t\t}\n\n\t\treturn builder.format(code, type, output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\t\tthis.inputs = source.inputs.map((input) => input.clone());\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, any> {\n\t\tlet data = this.getJSONNode(meta) as Record<string, any>;\n\n\t\tif (!data) {\n\t\t\tconst func = this.value;\n\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.value = this.value.toJSON(meta).uuid as string;\n\n\t\t\tif (func.inputs?.length) {\n\t\t\t\tdata.inputs = {};\n\n\t\t\t\tfor (let i = 0; i < func.inputs.length; i++) {\n\t\t\t\t\tconst inpt = func.inputs[i],\n\t\t\t\t\t\tnode = this.inputs[i]; /* || this.inputs[inpt.name] */\n\n\t\t\t\t\tdata.inputs[inpt.name] = node.toJSON(meta).uuid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Node } from '../core/Node';\n\nenum OPERATOR {\n\tADD = '+',\n\tSUB = '-',\n\tMUL = '*',\n\tDIV = '/',\n}\nexport class OperatorNode extends TempNode {\n\ta: Node;\n\tb: Node;\n\top: OPERATOR;\n\tnodeType: string = 'Operator';\n\n\tstatic ADD = OPERATOR.ADD;\n\tstatic SUB = OPERATOR.SUB;\n\tstatic MUL = OPERATOR.MUL;\n\tstatic DIV = OPERATOR.DIV;\n\n\tconstructor(\n\t\ta: Node = new Node(),\n\t\tb: Node = new Node(),\n\t\top: OPERATOR = OperatorNode.ADD\n\t) {\n\t\tsuper();\n\n\t\t/*\n\t\t\ttype will be overidden but it's temporarily needed for when \n\t\t\tdragging spline files on the app (will call toJSON before generate) \n\t\t*/\n\t\tthis.type = a.type;\n\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.op = op;\n\t}\n\n\tgetType(builder: NodeBuilder) {\n\t\tconst a = this.a.getType(builder);\n\t\tconst b = this.b.getType(builder);\n\n\t\tif (builder.isTypeMatrix(a as string)) {\n\t\t\treturn 'v4';\n\t\t} else if (\n\t\t\tbuilder.getTypeLength(b as string) > builder.getTypeLength(a as string)\n\t\t) {\n\t\t\treturn b;\n\t\t}\n\n\t\treturn a;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tconst type = this.getType(builder);\n\t\tthis.type = type;\n\n\t\tconst a = this.a.build(builder, type),\n\t\t\tb = this.b.build(builder, type);\n\n\t\treturn builder.format(\n\t\t\t'( ' + a + ' ' + this.op + ' ' + b + ' )',\n\t\t\ttype as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.a.copy(source.a);\n\t\tthis.b.copy(source.b);\n\t\tthis.op = source.op;\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Node } from '../core/Node';\n\nenum METHOD {\n\tRAD = 'radians',\n\tDEG = 'degrees',\n\tEXP = 'exp',\n\tEXP2 = 'exp2',\n\tLOG = 'log',\n\tLOG2 = 'log2',\n\tSQRT = 'sqrt',\n\tINV_SQRT = 'inversesqrt',\n\tFLOOR = 'floor',\n\tCEIL = 'ceil',\n\tNORMALIZE = 'normalize',\n\tFRACT = 'fract',\n\tSATURATE = 'saturate',\n\tSIN = 'sin',\n\tCOS = 'cos',\n\tTAN = 'tan',\n\tASIN = 'asin',\n\tACOS = 'acos',\n\tARCTAN = 'atan',\n\tABS = 'abs',\n\tSIGN = 'sign',\n\tLENGTH = 'length',\n\tNEGATE = 'negate',\n\tINVERT = 'invert',\n\n\t// 2 inputs\n\n\tMIN = 'min',\n\tMAX = 'max',\n\tMOD = 'mod',\n\tSTEP = 'step',\n\tREFLECT = 'reflect',\n\tDISTANCE = 'distance',\n\tDOT = 'dot',\n\tCROSS = 'cross',\n\tPOW = 'pow',\n\n\t// 3 inputs\n\n\tMIX = 'mix',\n\tCLAMP = 'clamp',\n\tREFRACT = 'refract',\n\tSMOOTHSTEP = 'smoothstep',\n\tFACEFORWARD = 'faceforward',\n}\nexport class MathNode extends TempNode {\n\ta: Node;\n\tb: Node | string | undefined;\n\tc: Node | string | undefined;\n\tmethod: METHOD | undefined;\n\tnodeType: string = 'Math';\n\n\tstatic RAD = METHOD.RAD;\n\tstatic DEG = METHOD.DEG;\n\tstatic EXP = METHOD.EXP;\n\tstatic EXP2 = METHOD.EXP2;\n\tstatic LOG = METHOD.LOG;\n\tstatic LOG2 = METHOD.LOG2;\n\tstatic SQRT = METHOD.SQRT;\n\tstatic INV_SQRT = METHOD.INV_SQRT;\n\tstatic FLOOR = METHOD.FLOOR;\n\tstatic CEIL = METHOD.CEIL;\n\tstatic NORMALIZE = METHOD.NORMALIZE;\n\tstatic FRACT = METHOD.FRACT;\n\tstatic SATURATE = METHOD.SATURATE;\n\tstatic SIN = METHOD.SIN;\n\tstatic COS = METHOD.COS;\n\tstatic TAN = METHOD.TAN;\n\tstatic ASIN = METHOD.ASIN;\n\tstatic ACOS = METHOD.ACOS;\n\tstatic ARCTAN = METHOD.ARCTAN;\n\tstatic ABS = METHOD.ABS;\n\tstatic SIGN = METHOD.SIGN;\n\tstatic LENGTH = METHOD.LENGTH;\n\tstatic NEGATE = METHOD.NEGATE;\n\tstatic INVERT = METHOD.INVERT;\n\n\t// 2 inputs\n\n\tstatic MIN = METHOD.MIN;\n\tstatic MAX = METHOD.MAX;\n\tstatic MOD = METHOD.MOD;\n\tstatic STEP = METHOD.STEP;\n\tstatic REFLECT = METHOD.REFLECT;\n\tstatic DISTANCE = METHOD.DISTANCE;\n\tstatic DOT = METHOD.DOT;\n\tstatic CROSS = METHOD.CROSS;\n\tstatic POW = METHOD.POW;\n\n\t// 3 inputs\n\n\tstatic MIX = METHOD.MIX;\n\tstatic CLAMP = METHOD.CLAMP;\n\tstatic REFRACT = METHOD.REFRACT;\n\tstatic SMOOTHSTEP = METHOD.SMOOTHSTEP;\n\tstatic FACEFORWARD = METHOD.FACEFORWARD;\n\n\tconstructor(\n\t\ta: Node = new Node(),\n\t\tbOrMethod: Node | METHOD = MathNode.ABS,\n\t\tcOrMethod?: Node | METHOD,\n\t\tmethod?: METHOD\n\t) {\n\t\tsuper();\n\n\t\tthis.a = a;\n\t\ttypeof bOrMethod !== 'string' ? (this.b = bOrMethod) : (method = bOrMethod);\n\t\ttypeof cOrMethod !== 'string' ? (this.c = cOrMethod) : (method = cOrMethod);\n\n\t\tthis.method = method;\n\n\t\tthis.hashProperties = ['method'];\n\t}\n\n\tgetNumInputs(_builder?: NodeBuilder): number {\n\t\tswitch (this.method) {\n\t\t\tcase MathNode.MIX:\n\t\t\tcase MathNode.CLAMP:\n\t\t\tcase MathNode.REFRACT:\n\t\t\tcase MathNode.SMOOTHSTEP:\n\t\t\tcase MathNode.FACEFORWARD:\n\t\t\t\treturn 3;\n\n\t\t\tcase MathNode.MIN:\n\t\t\tcase MathNode.MAX:\n\t\t\tcase MathNode.MOD:\n\t\t\tcase MathNode.STEP:\n\t\t\tcase MathNode.REFLECT:\n\t\t\tcase MathNode.DISTANCE:\n\t\t\tcase MathNode.DOT:\n\t\t\tcase MathNode.CROSS:\n\t\t\tcase MathNode.POW:\n\t\t\t\treturn 2;\n\n\t\t\tdefault:\n\t\t\t\treturn 1;\n\t\t}\n\t}\n\n\tgetInputType(builder: NodeBuilder): string {\n\t\tconst a = builder.getTypeLength(this.a.getType(builder) as string);\n\t\tconst b = this.b\n\t\t\t? builder.getTypeLength((this.b as Node).getType(builder) as string)\n\t\t\t: 0;\n\t\tconst c = this.c\n\t\t\t? builder.getTypeLength((this.c as Node).getType(builder) as string)\n\t\t\t: 0;\n\n\t\tif (a > b && a > c) {\n\t\t\treturn this.a.getType(builder) as string;\n\t\t} else if (b > c) {\n\t\t\treturn (this.b as Node).getType(builder) as string;\n\t\t}\n\n\t\treturn (this.c as Node).getType(builder) as string;\n\t}\n\n\tgetType(builder: NodeBuilder) {\n\t\tswitch (this.method) {\n\t\t\tcase MathNode.LENGTH:\n\t\t\tcase MathNode.DISTANCE:\n\t\t\tcase MathNode.DOT:\n\t\t\t\treturn 'f';\n\n\t\t\tcase MathNode.CROSS:\n\t\t\t\treturn 'v3';\n\t\t}\n\n\t\treturn this.getInputType(builder);\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tlet a, b, c;\n\n\t\tconst al = this.a\n\t\t\t? builder.getTypeLength(this.a.getType(builder) as string)\n\t\t\t: 0;\n\t\tconst bl = this.b\n\t\t\t? builder.getTypeLength((this.b as Node).getType(builder) as string)\n\t\t\t: 0;\n\t\tconst cl = this.c\n\t\t\t? builder.getTypeLength((this.c as Node).getType(builder) as string)\n\t\t\t: 0;\n\n\t\tconst inputType = this.getInputType(builder);\n\t\tconst nodeType = this.getType(builder);\n\n\t\tthis.type = nodeType;\n\n\t\tswitch (this.method) {\n\t\t\t// 1 input\n\n\t\t\tcase MathNode.NEGATE:\n\t\t\t\treturn builder.format(\n\t\t\t\t\t'( -' + this.a.build(builder, inputType) + ' )',\n\t\t\t\t\tinputType,\n\t\t\t\t\toutput\n\t\t\t\t);\n\n\t\t\tcase MathNode.INVERT:\n\t\t\t\treturn builder.format(\n\t\t\t\t\t'( 1.0 - ' + this.a.build(builder, inputType) + ' )',\n\t\t\t\t\tinputType,\n\t\t\t\t\toutput\n\t\t\t\t);\n\n\t\t\t// 2 inputs\n\n\t\t\tcase MathNode.CROSS:\n\t\t\t\ta = this.a.build(builder, 'v3');\n\t\t\t\tb = (this.b as Node).build(builder, 'v3');\n\n\t\t\t\tbreak;\n\n\t\t\tcase MathNode.STEP:\n\t\t\t\ta = this.a.build(builder, al === 1 ? 'f' : inputType);\n\t\t\t\tb = (this.b as Node).build(builder, inputType);\n\n\t\t\t\tbreak;\n\n\t\t\tcase MathNode.MIN:\n\t\t\tcase MathNode.MAX:\n\t\t\tcase MathNode.MOD:\n\t\t\t\ta = this.a.build(builder, inputType);\n\t\t\t\tb = (this.b as Node).build(builder, bl === 1 ? 'f' : inputType);\n\n\t\t\t\tbreak;\n\n\t\t\t// 3 inputs\n\n\t\t\tcase MathNode.REFRACT:\n\t\t\t\ta = this.a.build(builder, inputType);\n\t\t\t\tb = (this.b as Node).build(builder, inputType);\n\t\t\t\tc = (this.c as Node).build(builder, 'f');\n\n\t\t\t\tbreak;\n\n\t\t\tcase MathNode.MIX:\n\t\t\t\ta = this.a.build(builder, inputType);\n\t\t\t\tb = (this.b as Node).build(builder, inputType);\n\t\t\t\tc = (this.c as Node).build(builder, cl === 1 ? 'f' : inputType);\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\ta = this.a.build(builder, inputType);\n\t\t\t\tif (this.b) b = (this.b as Node).build(builder, inputType);\n\t\t\t\tif (this.c) c = (this.c as Node).build(builder, inputType);\n\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// build function call\n\n\t\tconst params = [];\n\t\tparams.push(a);\n\t\tif (b) params.push(b);\n\t\tif (c) params.push(c);\n\n\t\tconst numInputs = this.getNumInputs(builder);\n\n\t\tif (params.length !== numInputs) {\n\t\t\tthrow Error(\n\t\t\t\t`Arguments not match used in \"${this.method}\". Require ${numInputs}, currently ${params.length}.`\n\t\t\t);\n\t\t}\n\n\t\treturn builder.format(\n\t\t\tthis.method + '( ' + params.join(', ') + ' )',\n\t\t\tnodeType,\n\t\t\toutput\n\t\t);\n\t}\n\n\t// @todo copy: it is hard copy if the variables can be Node | string, maybe we could have node for string\n\t// StringNode???\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.a.copy(source.a);\n\t\tthis.b = source.b instanceof Node ? source.b.clone() : source.b;\n\t\tthis.c = source.c instanceof Node ? source.c.clone() : source.c;\n\t\tthis.method = source.method;\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { ConstNode } from '../core/ConstNode';\nimport { ExpressionNode } from '../core/ExpressionNode';\nimport { FunctionCallNode } from '../core/FunctionCallNode';\nimport { ColorSpaceNode } from '../utils/ColorSpaceNode';\nimport { StructNode } from '../core/StructNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { OperatorNode } from '../math/OperatorNode';\nimport { MathNode } from '../math/MathNode';\nimport { Node } from '../core/Node';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class TextureCubeUVNode extends TempNode {\n\tuv: Node;\n\tbias: Node;\n\tvalue: Node;\n\tcolorSpaceTL: ColorSpaceNode | undefined;\n\tcolorSpaceTR: ColorSpaceNode | undefined;\n\tcolorSpaceBL: ColorSpaceNode | undefined;\n\tcolorSpaceBR: ColorSpaceNode | undefined;\n\tcolorSpaceTLExp: ExpressionNode | undefined;\n\tcolorSpaceTRExp: ExpressionNode | undefined;\n\tcolorSpaceBLExp: ExpressionNode | undefined;\n\tcolorSpaceBRExp: ExpressionNode | undefined;\n\n\tnodeType: string = 'TextureCubeUV';\n\n\tstatic Nodes: {\n\t\tbilinearCubeUV: FunctionNode;\n\t\troughnessToMip: FunctionNode;\n\t\tm0: ConstNode;\n\t\tcubeUV_maxMipLevel: ConstNode;\n\t} = (function () {\n\t\tconst TextureCubeUVData = new StructNode(\n\t\t\t`struct TextureCubeUVData {\n\t\t\tvec4 tl;\n\t\t\tvec4 tr;\n\t\t\tvec4 br;\n\t\t\tvec4 bl;\n\t\t\tvec2 f;\n\t\t}`\n\t\t);\n\n\t\tconst cubeUVMaxMipLevel = new ConstNode(\n\t\t\t'float cubeUV_maxMipLevel 8.0',\n\t\t\ttrue\n\t\t);\n\t\tconst cubeUVMinMipLevel = new ConstNode(\n\t\t\t'float cubeUV_minMipLevel 4.0',\n\t\t\ttrue\n\t\t);\n\t\tconst cubeUVMaxTileSize = new ConstNode(\n\t\t\t'float cubeUV_maxTileSize 256.0',\n\t\t\ttrue\n\t\t);\n\t\tconst cubeUVMinTileSize = new ConstNode(\n\t\t\t'float cubeUV_minTileSize 16.0',\n\t\t\ttrue\n\t\t);\n\n\t\t// These shader functions convert between the UV coordinates of a single face of\n\t\t// a cubemap, the 0-5 integer index of a cube face, and the direction vector for\n\t\t// sampling a textureCube (not generally normalized).\n\n\t\tconst getFace = new FunctionNode(\n\t\t\t`float getFace(vec3 direction) {\n\t\t\t\tvec3 absDirection = abs(direction);\n\t\t\t\tfloat face = -1.0;\n\t\t\t\tif (absDirection.x > absDirection.z) {\n\t\t\t\t\tif (absDirection.x > absDirection.y)\n\t\t\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\t\t\telse\n\t\t\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t\t\t} else {\n\t\t\t\t\tif (absDirection.z > absDirection.y)\n\t\t\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\t\t\telse\n\t\t\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t\t\t}\n\t\t\t\treturn face;\n\t\t}`\n\t\t);\n\t\tgetFace.useKeywords = false;\n\n\t\tconst getUV = new FunctionNode(\n\t\t\t`vec2 getUV(vec3 direction, float face) {\n\t\t\t\tvec2 uv;\n\t\t\t\tif (face == 0.0) {\n\t\t\t\t\tuv = vec2(direction.z, direction.y) / abs(direction.x); // pos x\n\t\t\t\t} else if (face == 1.0) {\n\t\t\t\t\tuv = vec2(-direction.x, -direction.z) / abs(direction.y); // pos y\n\t\t\t\t} else if (face == 2.0) {\n\t\t\t\t\tuv = vec2(-direction.x, direction.y) / abs(direction.z); // pos z\n\t\t\t\t} else if (face == 3.0) {\n\t\t\t\t\tuv = vec2(-direction.z, direction.y) / abs(direction.x); // neg x\n\t\t\t\t} else if (face == 4.0) {\n\t\t\t\t\tuv = vec2(-direction.x, direction.z) / abs(direction.y); // neg y\n\t\t\t\t} else {\n\t\t\t\t\tuv = vec2(direction.x, direction.y) / abs(direction.z); // neg z\n\t\t\t\t}\n\t\t\t\treturn 0.5 * (uv + 1.0);\n\t\t}`\n\t\t);\n\t\tgetUV.useKeywords = false;\n\n\t\tconst bilinearCubeUV = new FunctionNode(\n\t\t\t`TextureCubeUVData bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n\t\t\tfloat face = getFace(direction);\n\t\t\tfloat filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n\t\t\tmipInt = max(mipInt, cubeUV_minMipLevel);\n\t\t\tfloat faceSize = exp2(mipInt);\n\t\t\tfloat texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n\t\t\tvec2 uv = getUV(direction, face) * (faceSize - 1.0);\n\t\t\tvec2 f = fract(uv);\n\t\t\tuv += 0.5 - f;\n\t\t\tif (face > 2.0) {\n\t\t\t\tuv.y += faceSize;\n\t\t\t\tface -= 3.0;\n\t\t\t}\n\t\t\tuv.x += face * faceSize;\n\t\t\tif(mipInt < cubeUV_maxMipLevel){\n\t\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t\t}\n\t\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\t\tuv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n\t\t\tuv *= texelSize;\n\t\t\tvec4 tl = texture2D(envMap, uv);\n\t\t\tuv.x += texelSize;\n\t\t\tvec4 tr = texture2D(envMap, uv);\n\t\t\tuv.y += texelSize;\n\t\t\tvec4 br = texture2D(envMap, uv);\n\t\t\tuv.x -= texelSize;\n\t\t\tvec4 bl = texture2D(envMap, uv);\n\t\t\treturn TextureCubeUVData( tl, tr, br, bl, f );\n\t\t}`,\n\t\t\t[\n\t\t\t\tTextureCubeUVData,\n\t\t\t\tgetFace,\n\t\t\t\tgetUV,\n\t\t\t\tcubeUVMaxMipLevel,\n\t\t\t\tcubeUVMinMipLevel,\n\t\t\t\tcubeUVMaxTileSize,\n\t\t\t\tcubeUVMinTileSize,\n\t\t\t]\n\t\t);\n\t\tbilinearCubeUV.useKeywords = false;\n\n\t\t// These defines must match with PMREMGenerator\n\n\t\tconst r0 = new ConstNode('float r0 1.0', true);\n\t\tconst v0 = new ConstNode('float v0 0.339', true);\n\t\tconst m0 = new ConstNode('float m0 -2.0', true);\n\t\tconst r1 = new ConstNode('float r1 0.8', true);\n\t\tconst v1 = new ConstNode('float v1 0.276', true);\n\t\tconst m1 = new ConstNode('float m1 -1.0', true);\n\t\tconst r4 = new ConstNode('float r4 0.4', true);\n\t\tconst v4 = new ConstNode('float v4 0.046', true);\n\t\tconst m4 = new ConstNode('float m4 2.0', true);\n\t\tconst r5 = new ConstNode('float r5 0.305', true);\n\t\tconst v5 = new ConstNode('float v5 0.016', true);\n\t\tconst m5 = new ConstNode('float m5 3.0', true);\n\t\tconst r6 = new ConstNode('float r6 0.21', true);\n\t\tconst v6 = new ConstNode('float v6 0.0038', true);\n\t\tconst m6 = new ConstNode('float m6 4.0', true);\n\n\t\tconst defines = [\n\t\t\tr0,\n\t\t\tv0,\n\t\t\tm0,\n\t\t\tr1,\n\t\t\tv1,\n\t\t\tm1,\n\t\t\tr4,\n\t\t\tv4,\n\t\t\tm4,\n\t\t\tr5,\n\t\t\tv5,\n\t\t\tm5,\n\t\t\tr6,\n\t\t\tv6,\n\t\t\tm6,\n\t\t];\n\n\t\tconst roughnessToMip = new FunctionNode(\n\t\t\t`float roughnessToMip(float roughness) {\n\t\t\tfloat mip = 0.0;\n\t\t\tif (roughness >= r1) {\n\t\t\t\tmip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n\t\t\t} else if (roughness >= r4) {\n\t\t\t\tmip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n\t\t\t} else if (roughness >= r5) {\n\t\t\t\tmip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n\t\t\t} else if (roughness >= r6) {\n\t\t\t\tmip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n\t\t\t} else {\n\t\t\t\tmip = -2.0 * log2(1.16 * roughness);// 1.16 = 1.79^0.25\n\t\t\t}\n\t\t\treturn mip;\n\t\t}`,\n\t\t\tdefines\n\t\t);\n\n\t\treturn {\n\t\t\tbilinearCubeUV: bilinearCubeUV,\n\t\t\troughnessToMip: roughnessToMip,\n\t\t\tm0: m0,\n\t\t\tcubeUV_maxMipLevel: cubeUVMaxMipLevel,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tvalue: Node = new Node(),\n\t\tuv: Node = new Node(),\n\t\tbias: Node = new Node()\n\t) {\n\t\tsuper('v4');\n\n\t\tthis.value = value;\n\t\tthis.uv = uv;\n\t\tthis.bias = bias;\n\t}\n\n\tbilinearCubeUV(builder: NodeBuilder, texture: Node, uv: Node, mipInt: any) {\n\t\tconst bilinearCubeUV = new FunctionCallNode(\n\t\t\tTextureCubeUVNode.Nodes.bilinearCubeUV,\n\t\t\t[texture, uv, mipInt]\n\t\t);\n\n\t\tthis.colorSpaceTL =\n\t\t\tthis.colorSpaceTL ?? new ColorSpaceNode(new ExpressionNode('', 'v4'));\n\t\tthis.colorSpaceTL.fromDecoding(\n\t\t\tbuilder.getTextureEncodingFromMap(this.value.value)\n\t\t);\n\t\tthis.colorSpaceTL.input.parse(bilinearCubeUV.build(builder) + '.tl');\n\n\t\tthis.colorSpaceTR =\n\t\t\tthis.colorSpaceTR ?? new ColorSpaceNode(new ExpressionNode('', 'v4'));\n\t\tthis.colorSpaceTR.fromDecoding(\n\t\t\tbuilder.getTextureEncodingFromMap(this.value.value)\n\t\t);\n\t\tthis.colorSpaceTR.input.parse(bilinearCubeUV.build(builder) + '.tr');\n\n\t\tthis.colorSpaceBL =\n\t\t\tthis.colorSpaceBL ?? new ColorSpaceNode(new ExpressionNode('', 'v4'));\n\t\tthis.colorSpaceBL.fromDecoding(\n\t\t\tbuilder.getTextureEncodingFromMap(this.value.value)\n\t\t);\n\t\tthis.colorSpaceBL.input.parse(bilinearCubeUV.build(builder) + '.bl');\n\n\t\tthis.colorSpaceBR =\n\t\t\tthis.colorSpaceBR ?? new ColorSpaceNode(new ExpressionNode('', 'v4'));\n\t\tthis.colorSpaceBR.fromDecoding(\n\t\t\tbuilder.getTextureEncodingFromMap(this.value.value)\n\t\t);\n\t\tthis.colorSpaceBR.input.parse(bilinearCubeUV.build(builder) + '.br');\n\n\t\t// add a custom context for fix incompatibility with the core\n\t\t// include ColorSpace function only for vertex shader (in fragment shader color space functions is added automatically by core)\n\t\t// this should be removed in the future\n\t\t// context.include =: is used to include or not functions if used FunctionNode\n\t\t// context.ignoreCache =: not create temp variables nodeT0..9 to optimize the code\n\t\tconst context = { include: builder.isShader('vertex'), ignoreCache: true };\n\n\t\tbuilder.addContext(context);\n\n\t\tthis.colorSpaceTLExp = new ExpressionNode(\n\t\t\tthis.colorSpaceTL.build(builder, 'v4'),\n\t\t\t'v4'\n\t\t);\n\t\tthis.colorSpaceTRExp = new ExpressionNode(\n\t\t\tthis.colorSpaceTR.build(builder, 'v4'),\n\t\t\t'v4'\n\t\t);\n\t\tthis.colorSpaceBLExp = new ExpressionNode(\n\t\t\tthis.colorSpaceBL.build(builder, 'v4'),\n\t\t\t'v4'\n\t\t);\n\t\tthis.colorSpaceBRExp = new ExpressionNode(\n\t\t\tthis.colorSpaceBR.build(builder, 'v4'),\n\t\t\t'v4'\n\t\t);\n\n\t\t// end custom context\n\n\t\tbuilder.removeContext();\n\n\t\t// --\n\n\t\tconst output = new ExpressionNode(\n\t\t\t'mix( mix( cubeUV_TL, cubeUV_TR, cubeUV.f.x ), mix( cubeUV_BL, cubeUV_BR, cubeUV.f.x ), cubeUV.f.y )',\n\t\t\t'v4'\n\t\t);\n\t\toutput.keywords['cubeUV_TL'] = this.colorSpaceTLExp;\n\t\toutput.keywords['cubeUV_TR'] = this.colorSpaceTRExp;\n\t\toutput.keywords['cubeUV_BL'] = this.colorSpaceBLExp;\n\t\toutput.keywords['cubeUV_BR'] = this.colorSpaceBRExp;\n\t\toutput.keywords['cubeUV'] = bilinearCubeUV;\n\n\t\treturn output;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tconst uv = this.uv;\n\t\t\tconst bias = this.bias || builder.context.roughness;\n\n\t\t\tconst mipV = new FunctionCallNode(\n\t\t\t\tTextureCubeUVNode.Nodes.roughnessToMip,\n\t\t\t\t[bias]\n\t\t\t);\n\t\t\tconst mip = new MathNode(\n\t\t\t\tmipV,\n\t\t\t\tTextureCubeUVNode.Nodes.m0,\n\t\t\t\tTextureCubeUVNode.Nodes.cubeUV_maxMipLevel,\n\t\t\t\tMathNode.CLAMP\n\t\t\t);\n\t\t\tconst mipInt = new MathNode(mip, MathNode.FLOOR);\n\t\t\tconst mipF = new MathNode(mip, MathNode.FRACT);\n\n\t\t\tconst color0 = this.bilinearCubeUV(builder, this.value, uv, mipInt);\n\t\t\tconst color1 = this.bilinearCubeUV(\n\t\t\t\tbuilder,\n\t\t\t\tthis.value,\n\t\t\t\tuv,\n\t\t\t\tnew OperatorNode(\n\t\t\t\t\tmipInt,\n\t\t\t\t\tnew FloatNode(1).setReadonly(true),\n\t\t\t\t\tOperatorNode.ADD\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tconst color1Mix = new MathNode(color0, color1, mipF, MathNode.MIX);\n\n\t\t\t/*\n\t\t// TODO: Optimize this in the future\n\t\tlet cond = new CondNode(\n\t\t\tmipF,\n\t\t\tnew FloatNode( 0 ).setReadonly( true ),\n\t\t\tCondNode.EQUAL,\n\t\t\tcolor0, // if\n\t\t\tcolor1Mix\t// else\n\t\t);\n\t\t*/\n\n\t\t\treturn builder.format(color1Mix.build(builder), 'v4', output);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'TextureCubeUVNode is not compatible with ' +\n\t\t\t\t\tbuilder.shader +\n\t\t\t\t\t' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec4( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.uv.copy(source.uv);\n\t\tthis.bias.copy(source.bias);\n\t\tthis.value.copy(source.value);\n\t\tif (source.colorSpaceTL) {\n\t\t\tif (this.colorSpaceTL) this.colorSpaceTL.copy(source.colorSpaceTL);\n\t\t\telse this.colorSpaceTL = source.colorSpaceTL.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceTL = undefined;\n\t\t}\n\t\tif (source.colorSpaceTR) {\n\t\t\tif (this.colorSpaceTR) this.colorSpaceTR.copy(source.colorSpaceTR);\n\t\t\telse this.colorSpaceTR = source.colorSpaceTR.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceTR = undefined;\n\t\t}\n\t\tif (source.colorSpaceBL) {\n\t\t\tif (this.colorSpaceBL) this.colorSpaceBL.copy(source.colorSpaceBL);\n\t\t\telse this.colorSpaceBL = source.colorSpaceBL.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceBL = undefined;\n\t\t}\n\t\tif (source.colorSpaceBR) {\n\t\t\tif (this.colorSpaceBR) this.colorSpaceBR.copy(source.colorSpaceBR);\n\t\t\telse this.colorSpaceBR = source.colorSpaceBR.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceBR = undefined;\n\t\t}\n\t\tif (source.colorSpaceTLExp) {\n\t\t\tif (this.colorSpaceTLExp)\n\t\t\t\tthis.colorSpaceTLExp.copy(source.colorSpaceTLExp);\n\t\t\telse this.colorSpaceTLExp = source.colorSpaceTLExp.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceTLExp = undefined;\n\t\t}\n\t\tif (source.colorSpaceTRExp) {\n\t\t\tif (this.colorSpaceTRExp)\n\t\t\t\tthis.colorSpaceTRExp.copy(source.colorSpaceTRExp);\n\t\t\telse this.colorSpaceTRExp = source.colorSpaceTRExp.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceTRExp = undefined;\n\t\t}\n\t\tif (source.colorSpaceBLExp) {\n\t\t\tif (this.colorSpaceBLExp)\n\t\t\t\tthis.colorSpaceBLExp.copy(source.colorSpaceBLExp);\n\t\t\telse this.colorSpaceBLExp = source.colorSpaceBLExp.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceBLExp = undefined;\n\t\t}\n\t\tif (source.colorSpaceBRExp) {\n\t\t\tif (this.colorSpaceBRExp)\n\t\t\t\tthis.colorSpaceBRExp.copy(source.colorSpaceBRExp);\n\t\t\telse this.colorSpaceBRExp = source.colorSpaceBRExp.clone();\n\t\t} else {\n\t\t\tthis.colorSpaceBRExp = undefined;\n\t\t}\n\n\t\treturn this;\n\t}\n}\n", "import { NodeBuilder } from '../core/NodeBuilder';\nimport { TempNode } from '../core/TempNode';\nimport { nodeLib } from '../core/NodeLib';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { AssetLibrary } from '../../AssetLibrary';\n\nexport class NormalNode extends TempNode {\n\tscope: string;\n\tnodeType: string = 'Normal';\n\n\tstatic LOCAL: string = 'local';\n\tstatic WORLD: string = 'world';\n\tstatic VIEW: string = 'view';\n\tstatic NORMAL: string = 'normal';\n\n\tconstructor(scope?: string) {\n\t\tsuper('v3');\n\t\tthis.scope = scope ?? NormalNode.VIEW;\n\t}\n\n\tgetShared(): boolean {\n\t\treturn this.scope === NormalNode.WORLD;\n\t}\n\n\tbuild(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\tns?: string\n\t): string {\n\t\tconst contextNormal = builder.context[this.scope + 'Normal'];\n\n\t\tif (contextNormal) {\n\t\t\treturn contextNormal.build(builder, output, uuid, ns);\n\t\t}\n\n\t\treturn super.build(builder, output, uuid);\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\tlet result;\n\n\t\tswitch (this.scope) {\n\t\t\tcase NormalNode.VIEW:\n\t\t\t\tif (builder.isShader('vertex')) result = 'transformedNormal';\n\t\t\t\telse result = 'geometryNormal';\n\n\t\t\t\tbreak;\n\n\t\t\tcase NormalNode.LOCAL:\n\t\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\t\tresult = 'objectNormal';\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.requires.normal = true;\n\n\t\t\t\t\tresult = 'vObjectNormal';\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase NormalNode.WORLD:\n\t\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\t\tresult =\n\t\t\t\t\t\t'inverseTransformDirection( transformedNormal, viewMatrix ).xyz';\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.requires.worldNormal = true;\n\n\t\t\t\t\tresult = 'vWNormal';\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn builder.format(\n\t\t\tresult as string,\n\t\t\tthis.getType(builder) as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.scope = source.scope;\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, unknown> {\n\t\tlet data = this.getJSONNode(meta);\n\n\t\tif (!data) {\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.scope = this.scope;\n\t\t}\n\n\t\tdata.nodeType = this.nodeType;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, unknown>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.scope) this.scope = source.scope as string;\n\n\t\treturn this;\n\t}\n}\n\nnodeLib.addKeyword('viewNormal', function () {\n\treturn new NormalNode(NormalNode.VIEW);\n});\n\nnodeLib.addKeyword('localNormal', function () {\n\treturn new NormalNode(NormalNode.NORMAL);\n});\n\nnodeLib.addKeyword('worldNormal', function () {\n\treturn new NormalNode(NormalNode.WORLD);\n});\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { nodeLib } from '../core/NodeLib';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class PositionNode extends TempNode {\n\tstatic LOCAL: string = 'local';\n\tstatic WORLD: string = 'world';\n\tstatic VIEW: string = 'view';\n\tstatic PROJECTION: string = 'projection';\n\n\tscope: string;\n\tnodeType: string = 'Position';\n\n\tconstructor(scope?: string) {\n\t\tsuper('v3');\n\n\t\tthis.scope = scope ?? PositionNode.LOCAL;\n\t}\n\n\tgetType(): string {\n\t\tswitch (this.scope) {\n\t\t\tcase PositionNode.PROJECTION:\n\t\t\t\treturn 'v4';\n\t\t}\n\n\t\treturn this.type as string;\n\t}\n\n\tgetShader(): boolean {\n\t\tswitch (this.scope) {\n\t\t\tcase PositionNode.LOCAL:\n\t\t\tcase PositionNode.WORLD:\n\t\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\tlet result;\n\n\t\tswitch (this.scope) {\n\t\t\tcase PositionNode.LOCAL:\n\t\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\t\tresult = 'transformed';\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.requires.position = true;\n\n\t\t\t\t\tresult = 'vPosition';\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase PositionNode.WORLD:\n\t\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\t\treturn '( modelMatrix * vec4( transformed, 1.0 ) ).xyz';\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.requires.worldPosition = true;\n\n\t\t\t\t\tresult = 'vWPosition';\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase PositionNode.VIEW:\n\t\t\t\tresult = builder.isShader('vertex')\n\t\t\t\t\t? '-mvPosition.xyz'\n\t\t\t\t\t: 'vViewPosition';\n\n\t\t\t\tbreak;\n\n\t\t\tcase PositionNode.PROJECTION:\n\t\t\t\tresult = builder.isShader('vertex')\n\t\t\t\t\t? '( projectionMatrix * modelViewMatrix * vec4( position, 1.0 ) )'\n\t\t\t\t\t: 'vec4( 0.0 )';\n\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn builder.format(result as string, this.getType(), output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.scope = source.scope;\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, unknown> {\n\t\tlet data = this.getJSONNode(meta);\n\n\t\tif (!data) {\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.scope = this.scope;\n\t\t}\n\n\t\tdata.nodeType = this.nodeType;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, unknown>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.scope) this.scope = source.scope as string;\n\n\t\treturn this;\n\t}\n}\n\nnodeLib.addKeyword('position', function () {\n\treturn new PositionNode();\n});\n\nnodeLib.addKeyword('worldPosition', function () {\n\treturn new PositionNode(PositionNode.WORLD);\n});\n\nnodeLib.addKeyword('viewPosition', function () {\n\treturn new PositionNode(PositionNode.VIEW);\n});\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { NormalNode } from '../accessors/NormalNode';\nimport { PositionNode } from '../accessors/PositionNode';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class ReflectNode extends TempNode {\n\tscope: string;\n\tnodeType: string = 'Reflect';\n\n\tstatic CUBE: string = 'cube';\n\tstatic SPHERE: string = 'sphere';\n\tstatic VECTOR: string = 'vector';\n\n\tconstructor(scope?: string) {\n\t\tsuper('v3');\n\n\t\tthis.scope = scope ?? ReflectNode.CUBE;\n\t}\n\n\tgetUnique(builder: NodeBuilder) {\n\t\treturn !builder.context.viewNormal;\n\t}\n\n\tgetType() {\n\t\tswitch (this.scope) {\n\t\t\tcase ReflectNode.SPHERE:\n\t\t\t\treturn 'v2';\n\t\t}\n\n\t\treturn this.type;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tconst isUnique = this.getUnique(builder);\n\n\t\tif (builder.isShader('fragment')) {\n\t\t\tlet result;\n\n\t\t\tswitch (this.scope) {\n\t\t\t\tcase ReflectNode.VECTOR: {\n\t\t\t\t\tconst viewNormalNode = new NormalNode(NormalNode.VIEW);\n\t\t\t\t\tconst roughnessNode = builder.context.roughness;\n\n\t\t\t\t\tconst viewNormal = viewNormalNode.build(builder, 'v3');\n\t\t\t\t\tconst viewPosition = new PositionNode(PositionNode.VIEW).build(\n\t\t\t\t\t\tbuilder,\n\t\t\t\t\t\t'v3'\n\t\t\t\t\t);\n\t\t\t\t\tconst roughness = roughnessNode\n\t\t\t\t\t\t? roughnessNode.build(builder, 'f')\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\tlet method = `reflect( -normalize( ${viewPosition} ), ${viewNormal} )`;\n\n\t\t\t\t\tif (roughness) {\n\t\t\t\t\t\t// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.\n\t\t\t\t\t\tmethod = `normalize( mix( ${method}, ${viewNormal}, ${roughness} * ${roughness} ) )`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst code = `inverseTransformDirection( ${method}, viewMatrix )`;\n\n\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\tbuilder.addNodeCode(`vec3 reflectVec = ${code};`);\n\n\t\t\t\t\t\tresult = 'reflectVec';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = code;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase ReflectNode.CUBE: {\n\t\t\t\t\tconst reflectVec = new ReflectNode(ReflectNode.VECTOR).build(\n\t\t\t\t\t\tbuilder,\n\t\t\t\t\t\t'v3'\n\t\t\t\t\t);\n\n\t\t\t\t\tconst code = 'vec3( -' + reflectVec + '.x, ' + reflectVec + '.yz )';\n\n\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\tbuilder.addNodeCode(`vec3 reflectCubeVec = ${code};`);\n\n\t\t\t\t\t\tresult = 'reflectCubeVec';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = code;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase ReflectNode.SPHERE: {\n\t\t\t\t\tconst reflectVec = new ReflectNode(ReflectNode.VECTOR).build(\n\t\t\t\t\t\tbuilder,\n\t\t\t\t\t\t'v3'\n\t\t\t\t\t);\n\n\t\t\t\t\tconst code =\n\t\t\t\t\t\t'normalize( ( viewMatrix * vec4( ' +\n\t\t\t\t\t\treflectVec +\n\t\t\t\t\t\t', 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) ).xy * 0.5 + 0.5';\n\n\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\tbuilder.addNodeCode(`vec2 reflectSphereVec = ${code};`);\n\n\t\t\t\t\t\tresult = 'reflectSphereVec';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = code;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn builder.format(result as string, this.getType() as string, output);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'ReflectNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format('vec3( 0.0 )', this.type as string, output);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.scope = source.scope;\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): Record<string, any> {\n\t\tlet data = this.getJSONNode(meta);\n\n\t\tif (!data) {\n\t\t\tdata = this.createJSONNode(meta);\n\n\t\t\tdata.scope = this.scope;\n\t\t}\n\n\t\tdata.nodeType = this.nodeType;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(source: Record<string, unknown>, assetLibrary: AssetLibrary): this {\n\t\tsuper.fromJSON(source, assetLibrary);\n\n\t\tif (source.scope) this.scope = source.scope as string;\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { TextureNode } from '../inputs/TextureNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { TextureCubeUVNode } from './TextureCubeUVNode';\nimport { ReflectNode } from '../accessors/ReflectNode';\nimport { NormalNode } from '../accessors/NormalNode';\nimport { Node } from '../core/Node';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class TextureCubeNode extends TempNode {\n\tvalue: TextureNode;\n\t// textureSize: FloatNode;\n\tradianceNode: TextureCubeUVNode;\n\tirradianceNode: TextureCubeUVNode;\n\t/*\n\tradianceCache: {\n\t\tuv: TextureCubeUVNode;\n\t};\n\tirradianceCache: {\n\t\tuv: TextureCubeUVNode;\n\t};\n\t*/\n\tnodeType: string = 'TextureCube';\n\n\tconstructor(value: TextureNode = new TextureNode(), uv?: Node, bias?: Node) {\n\t\tsuper('v4');\n\n\t\tthis.value = value;\n\t\tthis.radianceNode = new TextureCubeUVNode(\n\t\t\tthis.value,\n\t\t\tuv ?? new ReflectNode(ReflectNode.VECTOR),\n\t\t\t// bias should be replaced in builder.context in build process\n\t\t\tbias as Node\n\t\t);\n\t\tthis.irradianceNode = new TextureCubeUVNode(\n\t\t\tthis.value,\n\t\t\tnew NormalNode(NormalNode.WORLD),\n\t\t\tnew FloatNode(1).setReadonly(true)\n\t\t);\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.require('irradiance');\n\n\t\t\tif (builder.context.bias) {\n\t\t\t\tbuilder.context.bias.setTexture(this.value);\n\t\t\t}\n\n\t\t\tconst scopeNode =\n\t\t\t\tbuilder.slot === 'irradiance' ? this.irradianceNode : this.radianceNode;\n\n\t\t\treturn scopeNode.build(builder, output);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'TextureCubeNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec4( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\t\tthis.radianceNode.copy(source.radianceNode);\n\t\tthis.irradianceNode.copy(source.irradianceNode);\n\n\t\treturn this;\n\t}\n}\n", "import { CubeTexture } from 'three';\n\nimport { InputNode } from '../core/InputNode';\nimport { Node } from '../core/Node';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { ExpressionNode } from '../core/ExpressionNode';\nimport { ColorSpaceNode } from '../utils/ColorSpaceNode';\nimport { ReflectNode } from '../accessors/ReflectNode';\n\nexport class CubeTextureNode extends InputNode {\n\tvalue: CubeTexture;\n\tuv: Node | undefined;\n\tbias: Node | undefined;\n\tnodeType: string = 'CubeTexture';\n\tcolorSpace: ColorSpaceNode | undefined;\n\n\tconstructor(value: CubeTexture = new CubeTexture(), uv?: Node, bias?: Node) {\n\t\tsuper('v4', { shared: true });\n\n\t\tthis.value = value;\n\t\tthis.uv = uv ?? new ReflectNode();\n\t\tthis.bias = bias;\n\t}\n\n\tgetTexture(builder: NodeBuilder, output: string): string {\n\t\treturn super.generate(builder, output, this.value.uuid, 'tc');\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string) {\n\t\tif (output === 'samplerCube') {\n\t\t\treturn this.getTexture(builder, output);\n\t\t}\n\n\t\tconst cubetex = this.getTexture(builder, output);\n\t\tconst uv = this.uv?.build(builder, 'v3');\n\t\tlet bias = this.bias ? this.bias.build(builder, 'f') : undefined;\n\n\t\tif (bias === undefined && builder.context.bias) {\n\t\t\tbias = builder.context.bias.setTexture(this).build(builder, 'f');\n\t\t}\n\n\t\tlet code;\n\n\t\tif (bias) code = 'texCubeBias( ' + cubetex + ', ' + uv + ', ' + bias + ' )';\n\t\telse code = 'texCube( ' + cubetex + ', ' + uv + ' )';\n\n\t\t// add a custom context for fix incompatibility with the core\n\t\t// include ColorSpace function only for vertex shader (in fragment shader color space functions is added automatically by core)\n\t\t// this should be removed in the future\n\t\t// context.include =: is used to include or not functions if used FunctionNode\n\t\t// context.ignoreCache =: not create variables temp nodeT0..9 to optimize the code\n\t\tconst context = { include: builder.isShader('vertex'), ignoreCache: true };\n\t\tconst outputType = this.getType(builder);\n\n\t\tbuilder.addContext(context);\n\n\t\tthis.colorSpace =\n\t\t\tthis.colorSpace ?? new ColorSpaceNode(new ExpressionNode('', outputType));\n\t\tthis.colorSpace.fromDecoding(builder.getTextureEncodingFromMap(this.value));\n\t\tthis.colorSpace.input.parse(code);\n\n\t\tcode = this.colorSpace.build(builder, outputType as string);\n\n\t\t// end custom context\n\n\t\tbuilder.removeContext();\n\n\t\treturn builder.format(code, outputType as string, output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\t\tif (source.uv) {\n\t\t\tif (this.uv) this.uv.copy(source.uv);\n\t\t\telse this.uv = source.uv.clone();\n\t\t} else {\n\t\t\tthis.uv = undefined;\n\t\t}\n\t\tif (source.bias) {\n\t\t\tif (this.bias) this.bias.copy(source.bias);\n\t\t\telse this.bias = source.bias.clone();\n\t\t} else {\n\t\t\tthis.bias = undefined;\n\t\t}\n\n\t\treturn this;\n\t}\n}\n", "import { Node } from '../../core/Node';\nimport { NodeBuilder } from '../../core/NodeBuilder';\n\nexport class RawNode extends Node {\n\tvalue: Node;\n\tnodeType: string = 'Raw';\n\n\tconstructor(value: Node = new Node()) {\n\t\tsuper('v4');\n\t\tthis.value = value;\n\t}\n\n\tgenerate(builder: NodeBuilder): string {\n\t\tconst data = this.value.analyzeAndFlow(builder, this.type as string);\n\t\tlet code = data.code + '\\n';\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tcode += 'gl_Position = ' + data.result + ';';\n\t\t} else {\n\t\t\tcode += 'gl_FragColor = ' + data.result + ';';\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value.copy(source.value);\n\n\t\treturn this;\n\t}\n}\n", "import { RGBA } from 'spline-data';\nimport { Node } from '../core/Node';\nimport { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { ColorA } from '../../../objects/Color';\n\nexport class ColorNode extends InputNode {\n\tvalue: ColorA;\n\tnodeType: string = 'Color';\n\talpha?: Node;\n\n\tconstructor(\n\t\tcolor: ColorA | number | string = 0,\n\t\tg?: number,\n\t\tb?: number,\n\t\ta?: number\n\t) {\n\t\tsuper('c');\n\t\tthis.value =\n\t\t\tcolor instanceof ColorA\n\t\t\t\t? (color as ColorA)\n\t\t\t\t: new ColorA(\n\t\t\t\t\t\t(color as number) || 0,\n\t\t\t\t\t\tg as number,\n\t\t\t\t\t\tb as number,\n\t\t\t\t\t\ta as number\n\t\t\t\t );\n\t}\n\n\tsetRGBA(color: RGBA): void {\n\t\tthis.value.setRGBA(color.r, color.g, color.b, color.a);\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\tuuid?: string,\n\t\ttype?: string,\n\t\tns?: string,\n\t\tneedsUpdate?: boolean\n\t): string {\n\t\tuuid = builder.getUUID(uuid ?? this.getUUID());\n\t\ttype = type ?? this.getType(builder);\n\n\t\tconst data = builder.getNodeData(uuid);\n\t\tconst readonly = this.getReadonly() && this.generateReadonly !== undefined;\n\n\t\tif (this.alpha) {\n\t\t\tconst alphaName = this.alpha.build(builder, 'f');\n\t\t\tbuilder.addFragmentNodeCode(\n\t\t\t\t`accumAlpha += ( 1.0 - accumAlpha ) * ${alphaName};`\n\t\t\t);\n\t\t}\n\n\t\tif (readonly) {\n\t\t\treturn this.generateReadonly(\n\t\t\t\tbuilder,\n\t\t\t\toutput,\n\t\t\t\tuuid,\n\t\t\t\ttype,\n\t\t\t\tns,\n\t\t\t\tneedsUpdate\n\t\t\t);\n\t\t} else {\n\t\t\tif (builder.isShader('vertex')) {\n\t\t\t\tif (!data.vertex) {\n\t\t\t\t\tdata.vertex = builder.createVertexUniform(\n\t\t\t\t\t\ttype as string,\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tns,\n\t\t\t\t\t\tneedsUpdate,\n\t\t\t\t\t\tthis.getLabel()\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn builder.format(\n\t\t\t\t\t(data.vertex as Record<string, any>).name,\n\t\t\t\t\ttype as string,\n\t\t\t\t\toutput\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (!data.fragment) {\n\t\t\t\t\tdata.fragment = builder.createFragmentUniform(\n\t\t\t\t\t\ttype as string,\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tns,\n\t\t\t\t\t\tneedsUpdate,\n\t\t\t\t\t\tthis.getLabel()\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn builder.format(\n\t\t\t\t\t(data.fragment as Record<string, any>).name,\n\t\t\t\t\ttype as string,\n\t\t\t\t\toutput\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\t'vec3(' + this.value.r + ', ' + this.value.g + ', ' + this.value.b + ')',\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n}\n", "import { Color, MathUtils, Vector2, Vector3, Vector4, Matrix3 } from 'three';\n\nimport {\n\tLayer,\n\tLayerParameters,\n\tClonableValue,\n\tLAYER_TYPE,\n\tLAYER_NODE_TYPE,\n} from './Layer';\nimport { Node } from '../nodes/core/Node';\nimport { ColorNode } from '../nodes/inputs/ColorNode';\nimport { FloatNode } from '../nodes/inputs/FloatNode';\nimport { IntNode } from '../nodes/inputs/IntNode';\nimport { BoolNode } from '../nodes/inputs/BoolNode';\nimport { Vector2Node } from '../nodes/inputs/Vector2Node';\nimport { Vector3Node } from '../nodes/inputs/Vector3Node';\nimport { Vector4Node } from '../nodes/inputs/Vector4Node';\nimport { Vector4ArrayNode } from '../nodes/inputs/Vector4ArrayNode';\nimport { FloatArrayNode } from '../nodes/inputs/FloatArrayNode';\nimport { TextureNode } from '../nodes/inputs/TextureNode';\nimport { CustomTextureNode } from '../nodes/custom/CustomTextureNode';\nimport { FresnelNode } from '../nodes/custom/FresnelNode';\nimport { RainbowNode } from '../nodes/custom/RainbowNode';\nimport { TransmissionNode } from '../nodes/custom/TransmissionNode';\nimport { CustomNormalNode } from '../nodes/custom/CustomNormalNode';\nimport { GradientNode } from '../nodes/custom/GradientNode';\nimport { VertexDisplacementNode } from '../nodes/custom/VertexDisplacementNode';\nimport { NoiseNode } from '../nodes/procedural/NoiseNode';\nimport { ExpressionNode } from '../nodes/core/ExpressionNode';\nimport { OperatorNode } from '../nodes/math/OperatorNode';\nimport { BlendNode } from '../nodes/custom/BlendNode';\nimport { DepthNode } from '../nodes/custom/DepthNode';\nimport { Material } from '../';\nimport {\n\tMeta,\n\tSerializedLayerStack,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../AssetLibrary';\nimport { MatcapNode } from '../nodes/custom/MatcapNode';\nimport { Texture } from '../../textures/Texture';\nimport { ColorA } from '../../objects';\nimport { colorDefault } from 'common/src/constants';\n\ntype LightNodes = {\n\temissive?: ColorNode;\n\tshininess?: FloatNode;\n\tspecular?: ColorNode;\n\troughness?: FloatNode;\n\tmetalness: FloatNode;\n\treflectivity: FloatNode;\n};\n\nexport type LayerNode = {\n\tid: number;\n\ttype:\n\t\t| LAYER_NODE_TYPE.COLOR\n\t\t| LAYER_NODE_TYPE.POSITION\n\t\t| LAYER_NODE_TYPE.LIGHTING;\n\tcolor?: Node;\n\talpha?: Node;\n\tmode?: Node;\n\tposition?: Node;\n};\n\nexport class LayerStack {\n\tid: number;\n\tuuid: string;\n\tlayerCount: number;\n\tneedsUpdate: boolean;\n\thead?: Layer;\n\n\tprivate _material: Material;\n\tprivate _layerNodes: Array<LayerNode>;\n\n\tconstructor(material: Material) {\n\t\tthis.id = 2;\n\t\tthis.layerCount = 2;\n\t\tthis.uuid = MathUtils.generateUUID();\n\t\tthis.needsUpdate = false;\n\t\tthis._material = material;\n\t\tthis._layerNodes = [];\n\n\t\tconst data = this._createLayer({ id: 0, type: LAYER_TYPE.COLOR });\n\n\t\tthis._material.color = data.color as ColorNode;\n\n\t\tif (this._material.alpha === undefined) {\n\t\t\tthis._material.alpha = new FloatNode(1.0);\n\t\t}\n\n\t\tconst shadingAlpha = new FloatNode(1);\n\t\tconst shadingBlend = new IntNode(0);\n\n\t\tif ('shadingAlpha' in this._material && 'shadingBlend' in this._material) {\n\t\t\tthis._material.shadingAlpha = shadingAlpha;\n\t\t\tthis._material.shadingBlend = shadingBlend;\n\t\t}\n\n\t\tthis._layerNodes.push({\n\t\t\tid: 0,\n\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\tcolor: data.color as ColorNode,\n\t\t\talpha: data.alpha as FloatNode,\n\t\t\tmode: data.mode as IntNode,\n\t\t});\n\t\tthis._layerNodes.push({\n\t\t\tid: 1,\n\t\t\ttype: LAYER_NODE_TYPE.LIGHTING,\n\t\t\talpha: shadingAlpha,\n\t\t\tmode: shadingBlend,\n\t\t});\n\n\t\tthis.head = data.layer as Layer;\n\n\t\tthis.head.next = new Layer(1, undefined, {\n\t\t\ttype: LAYER_TYPE.LIGHTING,\n\t\t\talpha: shadingAlpha,\n\t\t\tmode: shadingBlend,\n\t\t});\n\n\t\tthis.attachLightNodes(this.getLightLayer());\n\t}\n\n\tget material() {\n\t\treturn this._material;\n\t}\n\n\tset material(value: Material) {\n\t\tthis._material = value;\n\n\t\tlet shadingAlpha;\n\t\tlet shadingBlend;\n\n\t\t// NOTE: replace alpha and blend nodes on the light 'layer'\n\t\tlet curr: Layer | undefined = this.head;\n\t\twhile (curr !== undefined) {\n\t\t\tif (curr.type === LAYER_TYPE.LIGHTING) {\n\t\t\t\tshadingAlpha = curr.uniforms[`f${curr.id}_alpha`] as FloatNode;\n\t\t\t\tshadingBlend = curr.uniforms[`f${curr.id}_mode`] as IntNode;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurr = curr.next;\n\t\t}\n\n\t\tif ('shadingAlpha' in this._material && 'shadingBlend' in this._material) {\n\t\t\tthis._material.shadingAlpha = shadingAlpha;\n\t\t\tthis._material.shadingBlend = shadingBlend;\n\t\t}\n\n\t\tthis.attachLightNodes(value.userData.layers?.getLightLayer());\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\t}\n\n\tgetLayersOfType(layerType: LAYER_TYPE): Layer[] {\n\t\tlet layers = [];\n\t\tlet layer = this.head;\n\t\twhile (layer) {\n\t\t\tif (layer.type === layerType) layers.push(layer);\n\t\t\tlayer = layer.next;\n\t\t}\n\n\t\treturn layers;\n\t}\n\n\taddLayer(params: LayerParameters) {\n\t\tparams.id = params.id ?? ++this.id;\n\t\tthis.layerCount++;\n\n\t\tif (params.type === LAYER_TYPE.LIGHTING) {\n\t\t\tconst newLayer = this.createLightLayer(params);\n\n\t\t\tthis.uuid = MathUtils.generateUUID();\n\t\t\tthis.blendColors();\n\t\t\tthis.blendAfterColors();\n\t\t\tthis.blendPositions();\n\n\t\t\treturn newLayer;\n\t\t}\n\n\t\tconst data = this._createLayer(params);\n\t\tconst newLayer = data.layer as Layer;\n\n\t\tif (this.head === undefined) {\n\t\t\tthis.head = newLayer;\n\t\t} else {\n\t\t\tlet layer = this.head;\n\t\t\twhile (layer.next != undefined) {\n\t\t\t\tlayer = layer.next;\n\t\t\t}\n\t\t\tlayer.next = newLayer;\n\t\t}\n\n\t\tif (data.color) {\n\t\t\tthis._layerNodes.push({\n\t\t\t\tid: newLayer.id,\n\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\tmode: data.mode as IntNode,\n\t\t\t});\n\t\t}\n\t\tif (data.position) {\n\t\t\tthis._layerNodes.push({\n\t\t\t\tid: newLayer.id,\n\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\tposition: data.position as Node,\n\t\t\t});\n\t\t}\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn newLayer;\n\t}\n\n\taddLayerBeforeAt(params: LayerParameters, before: Layer): Layer {\n\t\tlet layer: Layer | undefined = this.head;\n\n\t\tparams.id = params.id ?? ++this.id;\n\t\tthis.layerCount++;\n\n\t\tconst data = this._createLayer(params);\n\t\tconst newLayer = data.layer as Layer;\n\n\t\tnewLayer.next = before;\n\n\t\tlet index = 0;\n\t\tif (layer === before) {\n\t\t\tthis.head = newLayer;\n\t\t\tif (data.color) {\n\t\t\t\tthis._layerNodes.splice(0, 0, {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\t\tmode: data.mode as IntNode,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (data.position) {\n\t\t\t\tthis._layerNodes.splice(0, 0, {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\t\tposition: data.position as Node,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tindex = 1;\n\t\t\twhile (layer?.next !== before) {\n\t\t\t\tlayer = layer?.next as Layer;\n\t\t\t\tindex++;\n\t\t\t}\n\n\t\t\tlayer.next = newLayer;\n\t\t\tif (data.color) {\n\t\t\t\tthis._layerNodes.splice(index, 0, {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\t\tmode: data.mode as IntNode,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (data.position) {\n\t\t\t\tthis._layerNodes.splice(index, 0, {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\t\tposition: data.position as Node,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn newLayer;\n\t}\n\n\taddLayerAt(pos: number, params: LayerParameters) {\n\t\tparams.id = params.id ?? ++this.id;\n\t\tthis.layerCount++;\n\n\t\tconst data = this._createLayer(params);\n\t\tconst newLayer = data.layer as Layer;\n\n\t\tif (data.color) {\n\t\t\tthis._layerNodes.splice(pos, 0, {\n\t\t\t\tid: newLayer.id,\n\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\tmode: data.mode as IntNode,\n\t\t\t});\n\t\t}\n\t\tif (data.position) {\n\t\t\tthis._layerNodes.splice(pos, 0, {\n\t\t\t\tid: newLayer.id,\n\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\tposition: data.position as Node,\n\t\t\t});\n\t\t}\n\n\t\tif (pos == 0) {\n\t\t\tnewLayer.next = this.head;\n\t\t\tthis.head = newLayer;\n\t\t} else {\n\t\t\tlet prev = this.head!;\n\t\t\tlet layer = this.head!.next as Layer;\n\n\t\t\tfor (let i = 0; i < pos - 1; i++) {\n\t\t\t\tprev = layer;\n\t\t\t\tlayer = layer.next as Layer;\n\t\t\t}\n\n\t\t\tnewLayer.next = layer;\n\t\t\tprev.next = newLayer;\n\t\t}\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn newLayer;\n\t}\n\n\tremoveLayer(id: number) {\n\t\tlet layer: Layer | undefined = this.head;\n\t\tlet prev = undefined;\n\t\tlet pos = 0;\n\n\t\tif (layer?.id == id) {\n\t\t\tthis.head = layer.next as Layer;\n\t\t} else {\n\t\t\tpos = 1;\n\t\t\tprev = layer!;\n\t\t\tlayer = layer?.next;\n\n\t\t\twhile (layer != undefined) {\n\t\t\t\tif (layer.id == id) {\n\t\t\t\t\tprev.next = layer.next;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tpos++;\n\t\t\t\tprev = layer;\n\t\t\t\tlayer = layer.next;\n\t\t\t}\n\t\t}\n\n\t\tthis.cleanupChangedLayer(layer as Layer);\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\t\tthis.layerCount--;\n\n\t\treturn pos;\n\t}\n\n\tchangeLayer(id: number, params: LayerParameters): Layer {\n\t\tlet prev = undefined;\n\t\tlet layer = this.head!;\n\t\tlet newLayer: Layer;\n\n\t\tif (layer?.id == id) {\n\t\t\tconst data = this._createLayer({ id, uuid: layer.uuid, ...params });\n\t\t\tnewLayer = data.layer as Layer;\n\n\t\t\tnewLayer.next = layer.next;\n\t\t\tthis.head = newLayer;\n\n\t\t\tif (data.color) {\n\t\t\t\tthis._layerNodes[0] = {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\t\tmode: data.mode as IntNode,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (data.position) {\n\t\t\t\tthis._layerNodes[0] = {\n\t\t\t\t\tid: newLayer.id,\n\t\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\t\tposition: data.position as Node,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tnewLayer.uniforms[`f${id}_mode`].value = layer.uniforms[`f${id}_mode`]\n\t\t\t\t.value as number;\n\t\t\tnewLayer.uniforms[`f${id}_alpha`].value = layer.uniforms[`f${id}_alpha`]\n\t\t\t\t.value as number;\n\t\t} else {\n\t\t\tprev = layer;\n\t\t\tlayer = layer.next as Layer;\n\n\t\t\tlet index = 1;\n\t\t\twhile (layer != undefined) {\n\t\t\t\tif (layer.id == id) {\n\t\t\t\t\tconst data = this._createLayer({ id, uuid: layer.uuid, ...params });\n\t\t\t\t\tnewLayer = data.layer as Layer;\n\n\t\t\t\t\tprev.next = newLayer;\n\t\t\t\t\tnewLayer.next = layer.next;\n\n\t\t\t\t\tif (data.color) {\n\t\t\t\t\t\tthis._layerNodes[index] = {\n\t\t\t\t\t\t\tid: id,\n\t\t\t\t\t\t\ttype: LAYER_NODE_TYPE.COLOR,\n\t\t\t\t\t\t\tcolor: data.color as ColorNode,\n\t\t\t\t\t\t\talpha: data.alpha as FloatNode,\n\t\t\t\t\t\t\tmode: data.mode as IntNode,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (data.position) {\n\t\t\t\t\t\tthis._layerNodes[index] = {\n\t\t\t\t\t\t\tid: id,\n\t\t\t\t\t\t\ttype: LAYER_NODE_TYPE.POSITION,\n\t\t\t\t\t\t\tposition: data.position as Node,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tnewLayer.uniforms[`f${id}_mode`].value = layer.uniforms[`f${id}_mode`]\n\t\t\t\t\t\t.value as number;\n\t\t\t\t\tnewLayer.uniforms[`f${id}_alpha`].value = layer.uniforms[\n\t\t\t\t\t\t`f${id}_alpha`\n\t\t\t\t\t].value as number;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tprev = layer;\n\t\t\t\tlayer = layer.next as Layer;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn newLayer!;\n\t}\n\n\tgetLayer(id: number): Layer {\n\t\tlet layer = this.head!;\n\n\t\twhile (layer != undefined) {\n\t\t\tif (layer.id == id) break;\n\t\t\tlayer = layer.next as Layer;\n\t\t}\n\t\treturn layer;\n\t}\n\n\tgetLayerByUuid(uuid: string): Layer | undefined {\n\t\tlet layer: Layer | undefined = this.head!;\n\n\t\twhile (layer !== undefined) {\n\t\t\tif (layer.uuid === uuid) return layer;\n\t\t\tlayer = layer.next;\n\t\t}\n\t}\n\n\tgetLayers(): Layer[] {\n\t\tconst arr = [];\n\t\tlet layer = this.head;\n\n\t\twhile (layer != undefined) {\n\t\t\tarr.push(layer);\n\t\t\tlayer = layer.next as Layer;\n\t\t}\n\n\t\treturn arr;\n\t}\n\n\t// NOTE(piero): imitating behavior from original.\n\t// This should give an error, not just return 0.\n\tgetLayerPosition(id: number): number {\n\t\tlet layer = this.head;\n\t\tlet pos = 0;\n\n\t\twhile (layer !== undefined) {\n\t\t\tif (layer.id == id) break;\n\t\t\tpos++;\n\t\t\tlayer = layer.next as Layer;\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\tgetDefines() {}\n\n\tgetBeforeProgram() {}\n\n\tgetLightingProgram() {}\n\n\tgetAfterProgram() {}\n\n\tgetVarPrograms() {}\n\n\tgetUniforms() {}\n\n\tmoveLayer(oldIndex: number, newIndex: number) {\n\t\tlet moved = undefined;\n\t\tlet layer = this.head!;\n\t\tlet prev: Layer | undefined;\n\n\t\tif (oldIndex == 0) {\n\t\t\tmoved = this.head!;\n\t\t\tthis.head = moved.next as Layer;\n\t\t} else {\n\t\t\tfor (let i = 0; i < oldIndex; i++) {\n\t\t\t\tprev = layer;\n\t\t\t\tlayer = layer.next as Layer;\n\t\t\t}\n\n\t\t\tprev!.next = layer.next as Layer;\n\t\t\tmoved = layer;\n\t\t}\n\n\t\t// detached oldIndex layer\n\n\t\tlayer = this.head!;\n\t\tprev = undefined;\n\n\t\tif (newIndex == 0) {\n\t\t\tmoved.next = this.head;\n\t\t\tthis.head = moved;\n\t\t} else {\n\t\t\tfor (let i = 0; i < newIndex - 1; i++) {\n\t\t\t\tlayer = layer.next as Layer;\n\t\t\t}\n\n\t\t\tmoved.next = layer?.next;\n\t\t\tlayer.next = moved;\n\t\t}\n\n\t\t// NOTE: move layerNodes accordingly.\n\t\tconst toMove = this._layerNodes.splice(oldIndex, 1)[0];\n\t\tthis._layerNodes.splice(newIndex, 0, toMove);\n\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t}\n\n\t// NOTE(piero): These functions are no longer needed apparently\n\tupdateLayerUniform() {\n\t\tthis.uuid = MathUtils.generateUUID();\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t}\n\n\tcopy(source: this): this {\n\t\tthis.needsUpdate = false;\n\t\tthis.layerCount = source.layerCount;\n\n\t\tthis._layerNodes = [];\n\t\tthis.layerCount = 0;\n\n\t\t// this.head = source.head.clone();\n\t\tthis.head = undefined;\n\n\t\tthis.rebuildLayerNodes(this.head, source.head!);\n\n\t\tlet sourceLayer: Layer = source.head!;\n\t\tlet layer: Layer = this.head!;\n\n\t\twhile (sourceLayer.next != undefined) {\n\t\t\tthis.rebuildLayerNodes(layer, sourceLayer.next);\n\n\t\t\tlayer = layer.next as Layer;\n\t\t\tsourceLayer = sourceLayer.next;\n\t\t}\n\n\t\tthis.id = source.id;\n\t\t// @tpatch nisa: rebuildLayerNodes using addLayer is changing this.uuid. We need to keep the same uuid in order to identify the same material. We need improve this\n\t\tthis.uuid = source.uuid;\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn this;\n\t}\n\n\tcreateLightLayer(params: LayerParameters): Layer {\n\t\tconst shadingAlpha = new FloatNode(params.alpha);\n\t\tconst shadingBlend = new IntNode(params.mode);\n\n\t\tthis._material.shadingAlpha = shadingAlpha;\n\t\tthis._material.shadingBlend = shadingBlend;\n\n\t\tthis._layerNodes.push({\n\t\t\tid: params.id as number,\n\t\t\ttype: LAYER_NODE_TYPE.LIGHTING,\n\t\t\talpha: shadingAlpha,\n\t\t\tmode: shadingBlend,\n\t\t});\n\n\t\tconst newLayer = new Layer(params.id as number, undefined, {\n\t\t\ttype: LAYER_TYPE.LIGHTING,\n\t\t\talpha: shadingAlpha,\n\t\t\tmode: shadingBlend,\n\t\t});\n\n\t\tif (this.head === undefined) {\n\t\t\tthis.head = newLayer;\n\t\t} else {\n\t\t\tlet layer = this.head;\n\t\t\twhile (layer.next != undefined) {\n\t\t\t\tlayer = layer.next;\n\t\t\t}\n\t\t\tlayer.next = newLayer;\n\t\t}\n\n\t\tthis.attachLightNodes(this.getLightLayer());\n\n\t\treturn newLayer;\n\t}\n\n\trebuildLayerNodes(\n\t\tlayer: Layer | undefined,\n\t\tsource: Layer,\n\t\tpreserveNodes: boolean = false\n\t) {\n\t\tif (source.type === LAYER_TYPE.LIGHTING) {\n\t\t\tconst shadingAlpha = preserveNodes\n\t\t\t\t? (source.uniforms[`f${source.id}_alpha`] as FloatNode)\n\t\t\t\t: new FloatNode(source.uniforms[`f${source.id}_alpha`].value);\n\t\t\tconst shadingBlend = preserveNodes\n\t\t\t\t? (source.uniforms[`f${source.id}_mode`] as IntNode)\n\t\t\t\t: new IntNode(source.uniforms[`f${source.id}_mode`].value);\n\n\t\t\tthis._material.shadingAlpha = shadingAlpha;\n\t\t\tthis._material.shadingBlend = shadingBlend;\n\n\t\t\tthis._layerNodes.push({\n\t\t\t\tid: source.id,\n\t\t\t\ttype: LAYER_NODE_TYPE.LIGHTING,\n\t\t\t\talpha: shadingAlpha,\n\t\t\t\tmode: shadingBlend,\n\t\t\t});\n\t\t\tif (this.head === undefined) {\n\t\t\t\tthis.head = new Layer(source.id, source.uuid, {\n\t\t\t\t\ttype: LAYER_TYPE.LIGHTING,\n\t\t\t\t\talpha: shadingAlpha,\n\t\t\t\t\tmode: shadingBlend,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (layer)\n\t\t\t\t\tlayer.next = new Layer(source.id, source.uuid, {\n\t\t\t\t\t\ttype: LAYER_TYPE.LIGHTING,\n\t\t\t\t\t\talpha: shadingAlpha,\n\t\t\t\t\t\tmode: shadingBlend,\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.attachLightNodes(source);\n\t\t} else {\n\t\t\tconst params: Record<string, any> = {\n\t\t\t\ttype: source.type,\n\t\t\t\tid: source.id,\n\t\t\t};\n\n\t\t\tfor (const fullkey in source.uniforms) {\n\t\t\t\tconst key = source.getName(fullkey);\n\t\t\t\tif (!key) continue;\n\t\t\t\tconst sourceKey = `f${source.id}_${key}`;\n\n\t\t\t\tif (Array.isArray(source.uniforms[sourceKey].value)) {\n\t\t\t\t\tparams[key] = (\n\t\t\t\t\t\tsource.uniforms[sourceKey].value as ClonableValue[]\n\t\t\t\t\t).map((ele) => {\n\t\t\t\t\t\treturn (ele.clone && !preserveNodes ? ele.clone() : ele) as unknown;\n\t\t\t\t\t}) as unknown;\n\t\t\t\t} else {\n\t\t\t\t\tconst value = source.uniforms[sourceKey].value as ClonableValue;\n\n\t\t\t\t\t// NOTE: The transmission node uses a depth texture created from\n\t\t\t\t\t// a render target. Idk if there's any better way of not cloning that texture\n\t\t\t\t\t// than this. We should have some way of flagging textures that should\n\t\t\t\t\t// never be cloned.\n\t\t\t\t\tif (key === 'transmissionDepthMap') {\n\t\t\t\t\t\tparams[key] = value;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\t\t\tparams[key] = (\n\t\t\t\t\t\t\tvalue.clone && !preserveNodes && !value.isRenderTargetTexture\n\t\t\t\t\t\t\t\t? value.clone()\n\t\t\t\t\t\t\t\t: value\n\t\t\t\t\t\t) as unknown;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.addLayer(params);\n\t\t}\n\t}\n\n\t// Creates material specific nodes and makes sure that\n\t// both the material and the Layer refers to the same node.\n\t// This is necessary for interaction state to function properly with\n\t// light layer values.\n\tprivate attachLightNodes(source?: Layer) {\n\t\tlet nodes: any = {};\n\n\t\tconst layer = this.getLightLayer();\n\n\t\tswitch (this._material.userData.category) {\n\t\t\tcase 'Lambert':\n\t\t\t\tnodes.emissive = new ColorNode(\n\t\t\t\t\tsource?.getValue<ColorA>('emissive')?.clone() ?? 0x000000\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'Phong':\n\t\t\t\tnodes.shininess = new FloatNode(source?.getValue('shininess') ?? 30.0);\n\t\t\t\tnodes.specular = new ColorNode(\n\t\t\t\t\tsource?.getValue<ColorA>('specular')?.clone() ?? 0x111111\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'Toon':\n\t\t\t\tnodes.shininess = new FloatNode(source?.getValue('shininess') ?? 30.0);\n\t\t\t\tnodes.specular = new ColorNode(\n\t\t\t\t\tsource?.getValue<ColorA>('specular')?.clone() ?? 0x111111\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'Physical':\n\t\t\t\tnodes.roughness = new FloatNode(source?.getValue('roughness') ?? 0.3);\n\t\t\t\tnodes.metalness = new FloatNode(source?.getValue('metalness') ?? 0.0);\n\t\t\t\tnodes.reflectivity = new FloatNode(\n\t\t\t\t\tsource?.getValue('reflectivity') ?? 0.5\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tObject.keys(nodes).forEach((key) => {\n\t\t\t// @ts-expect-error\n\t\t\tthis._material[key] = nodes[key];\n\t\t\tlayer!.uniforms[`f${layer!.id}_${key}`] = nodes[key];\n\t\t});\n\t}\n\n\tclone(material: Material): LayerStack {\n\t\treturn new LayerStack(material).copy(this);\n\t}\n\n\ttoJSON(meta: Meta): SerializedLayerStack {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\tuuid: this.uuid,\n\t\t\thead: this.head!.toJSON(meta),\n\t\t};\n\t}\n\n\tfromJSON(\n\t\tlayers: SerializedLayerStack,\n\t\tassets: AssetLibrary,\n\t\tmaterial: Material\n\t) {\n\t\tconst sourceHead = new Layer(layers.head.id, undefined, {\n\t\t\ttype: layers.head.type,\n\t\t}).fromJSON(layers.head, assets);\n\n\t\tlet layerJson = layers.head.next;\n\t\tlet layer = sourceHead;\n\n\t\twhile (layerJson != undefined) {\n\t\t\tlayer.next = new Layer(layerJson.id, undefined, {\n\t\t\t\ttype: layerJson.type,\n\t\t\t}).fromJSON(layerJson, assets);\n\n\t\t\tlayerJson = layerJson.next;\n\t\t\tlayer = layer.next;\n\t\t}\n\n\t\tthis._layerNodes = [];\n\n\t\tthis.head = undefined;\n\n\t\tthis.rebuildLayerNodes(this.head, sourceHead, true);\n\n\t\tlet sourceLayer: Layer = sourceHead;\n\t\tlayer = this.head!;\n\n\t\twhile (sourceLayer.next != undefined) {\n\t\t\t// layer.next = sourceLayer.next.clone();\n\t\t\tthis.rebuildLayerNodes(layer, sourceLayer.next, true);\n\n\t\t\tlayer = layer.next as Layer;\n\t\t\tsourceLayer = sourceLayer.next;\n\t\t}\n\n\t\tthis._material = material;\n\n\t\tthis.id = layers.id;\n\t\t// @tpatch nisa: rebuildLayerNodes using addLayer is changing this.uuid. We need to keep the same uuid in order to identify the same material. We need improve this\n\t\tthis.uuid = layers.uuid;\n\n\t\tthis.blendColors();\n\t\tthis.blendAfterColors();\n\t\tthis.blendPositions();\n\n\t\treturn this;\n\t}\n\n\tgetLightLayer() {\n\t\tlet layer: Layer | undefined = this.head;\n\t\twhile (layer !== undefined) {\n\t\t\tif (layer.type === 'light') break;\n\t\t\tlayer = layer.next ?? layer;\n\t\t}\n\t\treturn layer;\n\t}\n\n\tdispose() {\n\t\tlet layer = this.head;\n\t\tthis._layerNodes = [];\n\t\tthis.layerCount = 0;\n\n\t\twhile (layer !== undefined) {\n\t\t\tif (layer.hasOwnProperty('dispose') === true) {\n\t\t\t\tlayer.dispose();\n\t\t\t}\n\n\t\t\tlayer = layer.next as Layer;\n\t\t}\n\n\t\tthis.head = undefined;\n\t}\n\n\tprivate _createLayer(params: Record<string, any>): Record<string, any> {\n\t\tconst type = params.type as string;\n\t\tswitch (type) {\n\t\t\tcase LAYER_TYPE.COLOR: {\n\t\t\t\tconst color = new ColorNode(params.color ?? colorDefault);\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1);\n\t\t\t\tconst calpha = new ExpressionNode(\n\t\t\t\t\t'alpha / clamp(alpha + accumAlpha, 0.00001, 1.0 )',\n\t\t\t\t\t'f'\n\t\t\t\t);\n\t\t\t\tcalpha.keywords['alpha'] = alpha;\n\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tcolor.alpha = alpha;\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tcolor,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.TEXTURE: {\n\t\t\t\tconst tex = (params.texture as Texture) ?? new Texture();\n\t\t\t\tconst textureMatrix = tex.matrix;\n\t\t\t\tif (params.mat) {\n\t\t\t\t\ttextureMatrix.copy(params.mat as Matrix3);\n\t\t\t\t}\n\t\t\t\ttex.needsUpdate = true;\n\t\t\t\tconst crop = new FloatNode(params.crop ?? 0.0);\n\t\t\t\tconst projection = new IntNode(params.projection ?? 0);\n\t\t\t\tconst axis = new IntNode(params.axis ?? 0);\n\t\t\t\tconst size = new Vector2Node(\n\t\t\t\t\tparams.size\n\t\t\t\t\t\t? new Vector2(params.size[0], params.size[1])\n\t\t\t\t\t\t: new Vector2(100, 100)\n\t\t\t\t);\n\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\t\t\t\tconst texture = new TextureNode(tex);\n\n\t\t\t\tconst textureSize = new Vector3Node(\n\t\t\t\t\tparams.textureSize ??\n\t\t\t\t\t\tnew Vector3(\n\t\t\t\t\t\t\ttex.image ? tex.image.width : 0,\n\t\t\t\t\t\t\ttex.image ? tex.image.height : 0\n\t\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t\tconst customTexture = new CustomTextureNode(\n\t\t\t\t\ttexture,\n\t\t\t\t\ttextureSize,\n\t\t\t\t\tcrop,\n\t\t\t\t\tprojection,\n\t\t\t\t\taxis,\n\t\t\t\t\tsize,\n\t\t\t\t\talpha,\n\t\t\t\t\tmode\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(customTexture.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\ttexture: texture,\n\t\t\t\t\ttextureSize,\n\t\t\t\t\tcrop,\n\t\t\t\t\tprojection,\n\t\t\t\t\taxis,\n\t\t\t\t\tsize,\n\t\t\t\t\tmat: customTexture.mat,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: customTexture, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.MATCAP: {\n\t\t\t\tconst tex = (params.texture as Texture) ?? new Texture();\n\t\t\t\ttex.needsUpdate = true;\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1);\n\t\t\t\tconst texture = new TextureNode(tex);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst matcap = new MatcapNode(texture, alpha, mode);\n\n\t\t\t\tconst calpha = new ExpressionNode(matcap.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\ttexture,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: matcap, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.FRESNEL: {\n\t\t\t\tconst color = new ColorNode(params.color ?? 0xffffff);\n\t\t\t\tconst bias = new FloatNode(params.bias ?? 0.1);\n\t\t\t\tconst scale = new FloatNode(params.scale ?? 1.0);\n\t\t\t\tconst intensity = new FloatNode(params.intensity ?? 2);\n\t\t\t\tconst factor = new FloatNode(params.factor ?? 1);\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst fresnel = new FresnelNode(\n\t\t\t\t\tcolor,\n\t\t\t\t\tbias,\n\t\t\t\t\tscale,\n\t\t\t\t\tintensity,\n\t\t\t\t\tfactor,\n\t\t\t\t\talpha,\n\t\t\t\t\tmode\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(fresnel.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tcolor,\n\t\t\t\t\tbias,\n\t\t\t\t\tscale,\n\t\t\t\t\tintensity,\n\t\t\t\t\tfactor,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: fresnel, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.RAINBOW: {\n\t\t\t\tconst filmThickness = new FloatNode(params.filmThickness ?? 30.0);\n\t\t\t\tconst movement = new FloatNode(params.movement ?? 0.0);\n\t\t\t\tconst wavelengths = new Vector3Node(\n\t\t\t\t\tparams.wavelengths ?? new Vector3(0.0, 0.0, 0.0)\n\t\t\t\t);\n\t\t\t\tconst noiseStrength = new FloatNode(params.noiseStrength ?? 0.0);\n\t\t\t\tconst noiseScale = new FloatNode(params.noiseScale ?? 1.0);\n\t\t\t\tconst offset = new Vector3Node(\n\t\t\t\t\tparams.offset ?? new Vector3(0.0, 0.0, 0.0)\n\t\t\t\t);\n\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\n\t\t\t\tconst rainbow = new RainbowNode(\n\t\t\t\t\tfilmThickness,\n\t\t\t\t\tmovement,\n\t\t\t\t\twavelengths,\n\t\t\t\t\tnoiseStrength,\n\t\t\t\t\tnoiseScale,\n\t\t\t\t\toffset,\n\t\t\t\t\talpha\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(rainbow.calpha, 'f');\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tfilmThickness,\n\t\t\t\t\tmovement,\n\t\t\t\t\twavelengths,\n\t\t\t\t\tnoiseStrength,\n\t\t\t\t\tnoiseScale,\n\t\t\t\t\toffset,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: rainbow, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.TRANSMISSION: {\n\t\t\t\tconst thickness = new FloatNode(params.thickness ?? 10.0);\n\t\t\t\tconst ior = new FloatNode(params.ior ?? 1.5);\n\t\t\t\tconst roughness = new FloatNode(params.roughness ?? 0.5);\n\t\t\t\tconst transmissionSamplerSize = new Vector2Node(\n\t\t\t\t\tparams.transmissionSamplerSize ?? new Vector2(2048, 2048)\n\t\t\t\t);\n\n\t\t\t\tconst tex = (params.transmissionSamplerMap as Texture) ?? new Texture();\n\t\t\t\tconst depthTex =\n\t\t\t\t\t(params.transmissionDepthMap as Texture) ?? new Texture();\n\t\t\t\tconst transmissionSamplerMap = new TextureNode(tex);\n\t\t\t\tconst transmissionDepthMap = new TextureNode(depthTex);\n\n\t\t\t\tconst width = window.innerWidth;\n\t\t\t\tconst height = window.innerHeight;\n\t\t\t\tconst aspectRatio =\n\t\t\t\t\twidth >= height\n\t\t\t\t\t\t? new Vector2Node(height / width, 1)\n\t\t\t\t\t\t: new Vector2Node(1, width / height);\n\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\n\t\t\t\tconst transmission = new TransmissionNode(\n\t\t\t\t\tthickness,\n\t\t\t\t\tior,\n\t\t\t\t\troughness,\n\t\t\t\t\ttransmissionSamplerSize,\n\t\t\t\t\ttransmissionSamplerMap,\n\t\t\t\t\ttransmissionDepthMap,\n\t\t\t\t\taspectRatio,\n\t\t\t\t\talpha\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(transmission.calpha, 'f');\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tthickness,\n\t\t\t\t\tior,\n\t\t\t\t\troughness,\n\t\t\t\t\ttransmissionSamplerSize,\n\t\t\t\t\ttransmissionSamplerMap,\n\t\t\t\t\ttransmissionDepthMap,\n\t\t\t\t\taspectRatio,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: transmission, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.DEPTH: {\n\t\t\t\tconst gradientType = new IntNode(params.gradientType ?? 0);\n\t\t\t\tconst smooth = new BoolNode(params.smooth ?? false);\n\t\t\t\tconst near = new FloatNode(params.near ?? 50);\n\t\t\t\tconst far = new FloatNode(params.far ?? 200);\n\t\t\t\tconst isVector = new FloatNode(params.isVector ?? 1);\n\t\t\t\tconst isWorldSpace = new FloatNode(params.isWorldSpace ?? 0);\n\t\t\t\tconst origin = new Vector3Node(params.origin ?? new Vector3());\n\t\t\t\tconst direction = new Vector3Node(params.direction ?? new Vector3());\n\t\t\t\tconst num = new IntNode(params.num ?? 0);\n\t\t\t\tlet colors: Vector4ArrayNode;\n\t\t\t\tif (params.colors) {\n\t\t\t\t\tcolors = new Vector4ArrayNode(num.value + 1, params.colors);\n\t\t\t\t} else {\n\t\t\t\t\tcolors = new Vector4ArrayNode(num.value + 1, new Vector4(0, 0, 0, 1));\n\t\t\t\t\tcolors.value[1] = new Vector4(1, 1, 1, 1);\n\t\t\t\t}\n\n\t\t\t\tlet steps: FloatArrayNode;\n\t\t\t\tif (params.steps) {\n\t\t\t\t\tsteps = new FloatArrayNode(\n\t\t\t\t\t\t(params.steps as number[]).length,\n\t\t\t\t\t\tparams.steps\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tsteps = new FloatArrayNode(10, 1);\n\t\t\t\t\tsteps.value[0] = 0;\n\t\t\t\t}\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst depth = new DepthNode(\n\t\t\t\t\tgradientType,\n\t\t\t\t\tsmooth,\n\t\t\t\t\tnear,\n\t\t\t\t\tfar,\n\t\t\t\t\tisVector,\n\t\t\t\t\tisWorldSpace,\n\t\t\t\t\torigin,\n\t\t\t\t\tdirection,\n\t\t\t\t\tcolors,\n\t\t\t\t\tsteps,\n\t\t\t\t\tnum,\n\t\t\t\t\talpha\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(depth.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tgradientType,\n\t\t\t\t\tsmooth,\n\t\t\t\t\tnear,\n\t\t\t\t\tfar,\n\t\t\t\t\tisVector,\n\t\t\t\t\tisWorldSpace,\n\t\t\t\t\torigin,\n\t\t\t\t\tdirection,\n\t\t\t\t\tcolors,\n\t\t\t\t\tsteps,\n\t\t\t\t\tnum,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: depth, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.NOISE: {\n\t\t\t\tconst scale = new FloatNode(params.scale ?? 1.0);\n\t\t\t\tconst size = new Vector3Node(params.size ?? new Vector3(100, 100, 100));\n\t\t\t\tconst move = new FloatNode(params.move ?? 1.0);\n\t\t\t\tconst fA = new Vector2Node(params.fA ?? new Vector2(1.7, 9.2));\n\t\t\t\tconst fB = new Vector2Node(params.fB ?? new Vector2(8.3, 2.8));\n\t\t\t\tconst distortion = new Vector2Node(\n\t\t\t\t\tparams.distortion ?? new Vector2(1, 1)\n\t\t\t\t);\n\t\t\t\tconst colorA = new Vector4Node(params.colorA);\n\t\t\t\tconst colorB = new Vector4Node(params.colorB);\n\t\t\t\tconst colorC = new Vector4Node(params.colorC);\n\t\t\t\tconst colorD = new Vector4Node(params.colorD);\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\t\t\t\tconst noiseType = new IntNode(params.noiseType ?? 0);\n\n\t\t\t\tconst noise = new NoiseNode(\n\t\t\t\t\tscale,\n\t\t\t\t\tsize,\n\t\t\t\t\tmove,\n\t\t\t\t\tfA,\n\t\t\t\t\tfB,\n\t\t\t\t\tdistortion,\n\t\t\t\t\tcolorA,\n\t\t\t\t\tcolorB,\n\t\t\t\t\tcolorC,\n\t\t\t\t\tcolorD,\n\t\t\t\t\talpha,\n\t\t\t\t\tnoiseType\n\t\t\t\t);\n\n\t\t\t\tconst calpha = new ExpressionNode(noise.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tscale,\n\t\t\t\t\tsize,\n\t\t\t\t\tmove,\n\t\t\t\t\tfA,\n\t\t\t\t\tfB,\n\t\t\t\t\tdistortion,\n\t\t\t\t\tcolorA,\n\t\t\t\t\tcolorB,\n\t\t\t\t\tcolorC,\n\t\t\t\t\tcolorD,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t\tnoiseType,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: noise, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.NORMAL: {\n\t\t\t\tconst cnormal = new Vector3Node(params.cnormal ?? new Vector3(1, 1, 1));\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst normal = new CustomNormalNode(cnormal, alpha);\n\n\t\t\t\tconst calpha = new ExpressionNode(\n\t\t\t\t\t'alpha / clamp(alpha + accumAlpha, 0.00001, 1.0 )',\n\t\t\t\t\t'f'\n\t\t\t\t);\n\t\t\t\tcalpha.keywords['alpha'] = alpha;\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tcnormal,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: normal, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.GRADIENT: {\n\t\t\t\tconst gradientType = new IntNode(params.gradientType ?? 0);\n\t\t\t\tconst smooth = new BoolNode(params.smooth ?? false);\n\n\t\t\t\tlet colors: Vector4ArrayNode;\n\t\t\t\tif (params.colors) {\n\t\t\t\t\tcolors = new Vector4ArrayNode(\n\t\t\t\t\t\t(params.colors as Vector4[]).length,\n\t\t\t\t\t\tparams.colors\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tcolors = new Vector4ArrayNode(10, new Vector4(0, 0, 0, 1));\n\t\t\t\t\tcolors.value[1] = new Vector4(1, 1, 1, 1);\n\t\t\t\t}\n\n\t\t\t\tlet steps: FloatArrayNode;\n\t\t\t\tif (params.steps) {\n\t\t\t\t\tsteps = new FloatArrayNode(\n\t\t\t\t\t\t(params.steps as number[]).length,\n\t\t\t\t\t\tparams.steps\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tsteps = new FloatArrayNode(10, 1);\n\t\t\t\t\tsteps.value[0] = 0;\n\t\t\t\t}\n\n\t\t\t\tconst offset = new Vector2Node(params.offset ?? new Vector2(0, 0));\n\t\t\t\tconst morph = new Vector2Node(params.morph ?? new Vector2(0, 0));\n\t\t\t\tconst angle = new FloatNode(params.angle ?? 0);\n\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\tconst gradient = new GradientNode(\n\t\t\t\t\tgradientType,\n\t\t\t\t\tsmooth,\n\t\t\t\t\tcolors,\n\t\t\t\t\tsteps,\n\t\t\t\t\toffset,\n\t\t\t\t\tmorph,\n\t\t\t\t\tangle,\n\t\t\t\t\talpha\n\t\t\t\t);\n\t\t\t\tconst calpha = new ExpressionNode(gradient.calpha, 'f');\n\n\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\ttype,\n\t\t\t\t\tgradientType,\n\t\t\t\t\tsmooth,\n\t\t\t\t\tcolors,\n\t\t\t\t\tsteps,\n\t\t\t\t\toffset,\n\t\t\t\t\tmorph,\n\t\t\t\t\tangle,\n\t\t\t\t\talpha,\n\t\t\t\t\tcalpha,\n\t\t\t\t\tmode,\n\t\t\t\t});\n\n\t\t\t\treturn { layer, color: gradient, alpha: calpha, mode };\n\t\t\t}\n\t\t\tcase LAYER_TYPE.DISPLACE: {\n\t\t\t\t// NOTE(piero): Assumes that the layer will be 'changed' (aka call changeLayer) with different parameters.\n\t\t\t\t//\t\t\t\tAnother option that doesn't require to do this is binding all the variables needed for both\n\t\t\t\t//\t\t\t\tdisplacement types and just setting material.needsUpdate\n\t\t\t\tconst displacementType = new IntNode(params.displacementType ?? 0);\n\n\t\t\t\tif (displacementType.value === 0) {\n\t\t\t\t\t// NOISE\n\t\t\t\t\tconst offset = new Vector3Node(params.offset ?? new Vector3(0, 0, 0));\n\t\t\t\t\tconst scale = new FloatNode(params.scale ?? 10);\n\t\t\t\t\tconst intensity = new FloatNode(params.intensity ?? 8);\n\t\t\t\t\tconst movement = new FloatNode(params.movement ?? 1);\n\t\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\n\t\t\t\t\tconst noiseType = new IntNode(params.noiseType ?? 0);\n\n\t\t\t\t\tconst displacement = new VertexDisplacementNode(\n\t\t\t\t\t\tdisplacementType,\n\t\t\t\t\t\tintensity,\n\t\t\t\t\t\tmovement,\n\t\t\t\t\t\toffset,\n\t\t\t\t\t\tscale,\n\t\t\t\t\t\tnoiseType\n\t\t\t\t\t);\n\n\t\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\t\tdisplacementType,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\toffset,\n\t\t\t\t\t\tscale,\n\t\t\t\t\t\tintensity,\n\t\t\t\t\t\tmovement,\n\t\t\t\t\t\talpha,\n\t\t\t\t\t\tmode,\n\t\t\t\t\t\tnoiseType,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn { layer, position: displacement };\n\t\t\t\t} else if (displacementType.value === 1) {\n\t\t\t\t\t// MAP\n\t\t\t\t\tconst tex = (params.texture as Texture) ?? new Texture();\n\t\t\t\t\tconst textureMatrix = tex.matrix;\n\t\t\t\t\tif (params.mat) {\n\t\t\t\t\t\ttextureMatrix.copy(params.mat as Matrix3);\n\t\t\t\t\t}\n\t\t\t\t\ttex.needsUpdate = true;\n\t\t\t\t\tconst intensity = new FloatNode(params.intensity ?? 8);\n\t\t\t\t\tconst texture = new TextureNode(tex);\n\t\t\t\t\tconst crop = new FloatNode(params.crop ?? 0.0);\n\t\t\t\t\tconst alpha = new FloatNode(params.alpha ?? 1.0);\n\t\t\t\t\tconst mode = new IntNode(params.mode ?? 0);\n\t\t\t\t\tconst displacement = new VertexDisplacementNode(\n\t\t\t\t\t\tdisplacementType,\n\t\t\t\t\t\tintensity,\n\t\t\t\t\t\ttexture,\n\t\t\t\t\t\tcrop\n\t\t\t\t\t);\n\n\t\t\t\t\tconst layer = new Layer(params.id, params.uuid, {\n\t\t\t\t\t\tdisplacementType,\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tintensity,\n\t\t\t\t\t\ttexture,\n\t\t\t\t\t\tcrop,\n\t\t\t\t\t\tmat: displacement.mat,\n\t\t\t\t\t\talpha,\n\t\t\t\t\t\tmode,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn { layer, position: displacement };\n\t\t\t\t}\n\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\t\treturn {};\n\t}\n\n\tblendColors() {\n\t\tconst startIndex = this._layerNodes.findIndex(\n\t\t\t(ele) => ele.type === LAYER_NODE_TYPE.COLOR\n\t\t);\n\t\tconst endIndex = this._layerNodes.findIndex(\n\t\t\t(ele) => ele.type === LAYER_NODE_TYPE.LIGHTING\n\t\t);\n\n\t\tif (startIndex !== -1 && startIndex < endIndex) {\n\t\t\tlet blended = this._layerNodes[startIndex].color as BlendNode;\n\n\t\t\tfor (let i = startIndex + 1; i < endIndex; ++i) {\n\t\t\t\tconst current = this._layerNodes[i];\n\t\t\t\tif (current.type === LAYER_NODE_TYPE.COLOR) {\n\t\t\t\t\tblended = new BlendNode(\n\t\t\t\t\t\tblended,\n\t\t\t\t\t\tcurrent.color as Node,\n\t\t\t\t\t\tcurrent.alpha as Node,\n\t\t\t\t\t\tcurrent.mode as Node\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._material.color = blended;\n\t\t} else {\n\t\t\tthis._material.color = undefined;\n\t\t}\n\t}\n\n\tblendAfterColors() {\n\t\tlet blended: ExpressionNode | BlendNode = new ExpressionNode(\n\t\t\t'outgoingLight',\n\t\t\t'f'\n\t\t);\n\t\tconst startIndex = this._layerNodes.findIndex(\n\t\t\t(ele) => ele.type === LAYER_NODE_TYPE.LIGHTING\n\t\t);\n\n\t\tif (this._layerNodes.length > startIndex + 1) {\n\t\t\tfor (let i = startIndex + 1; i < this._layerNodes.length; ++i) {\n\t\t\t\tconst current = this._layerNodes[i];\n\t\t\t\tif (current.type === LAYER_NODE_TYPE.COLOR) {\n\t\t\t\t\tblended = new BlendNode(\n\t\t\t\t\t\tblended,\n\t\t\t\t\t\tcurrent.color as Node,\n\t\t\t\t\t\tcurrent.alpha as Node,\n\t\t\t\t\t\tcurrent.mode as Node\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ('afterColor' in this._material) {\n\t\t\t\tthis._material.afterColor = blended;\n\t\t\t}\n\t\t} else {\n\t\t\tif ('afterColor' in this._material) {\n\t\t\t\tthis._material.afterColor = undefined;\n\t\t\t}\n\t\t}\n\t}\n\n\tblendPositions() {\n\t\tconst posNodes = this._layerNodes.filter(\n\t\t\t(ele) => ele.type === LAYER_NODE_TYPE.POSITION\n\t\t);\n\n\t\tif (posNodes.length > 0) {\n\t\t\tlet pos: Vector3Node | OperatorNode = posNodes[0].position as Vector3Node;\n\t\t\tfor (let i = 1; i < posNodes.length; ++i) {\n\t\t\t\tif (posNodes[i]) {\n\t\t\t\t\tpos = new OperatorNode(\n\t\t\t\t\t\tpos,\n\t\t\t\t\t\tposNodes[i].position as Node,\n\t\t\t\t\t\tOperatorNode.ADD\n\t\t\t\t\t);\n\n\t\t\t\t\tpos = new OperatorNode(\n\t\t\t\t\t\tpos,\n\t\t\t\t\t\tnew FloatNode(0.5).setReadonly(true),\n\t\t\t\t\t\tOperatorNode.MUL\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._material.position = pos;\n\t\t} else {\n\t\t\tthis._material.position = undefined;\n\t\t}\n\t}\n\n\tcleanupChangedLayer(layer: Layer) {\n\t\tthis._layerNodes = this._layerNodes.filter((ele) => ele.id !== layer.id);\n\t\tswitch (layer.type) {\n\t\t\tcase LAYER_TYPE.DISPLACE: {\n\t\t\t\tthis.blendPositions();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthis.blendColors();\n\t\t\t\tthis.blendAfterColors();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { Texture } from 'three';\nimport { Node } from '../nodes/core/Node';\nimport { Meta, SerializedLayer } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../AssetLibrary';\nimport { Vector3Node } from '../nodes/inputs/Vector3Node';\nimport { Vector2Node } from '../nodes/inputs/Vector2Node';\nimport { IntNode } from '../nodes/inputs/IntNode';\nimport { FloatNode } from '../nodes/inputs/FloatNode';\n\nexport type LayerParameters = Record<string, any> & {\n\tid?: number;\n};\n\nexport type ClonableValue = {\n\tclone?: () => void;\n\tequals?: (a: any) => boolean;\n\tisRenderTargetTexture?: boolean;\n};\n\nexport enum LAYER_TYPE {\n\tPOSITION = 'position',\n\tLIGHTING = 'light',\n\tCOLOR = 'color',\n\tGRADIENT = 'gradient',\n\tNORMAL = 'normal',\n\tDEPTH = 'depth',\n\tTEXTURE = 'texture',\n\tNOISE = 'noise',\n\tFRESNEL = 'fresnel',\n\tRAINBOW = 'rainbow',\n\tTRANSMISSION = 'transmission',\n\tPOINTS = 'points',\n\tMATCAP = 'matcap',\n\tLINES = 'lines',\n\tDISPLACE = 'displace',\n}\n\nexport enum LAYER_NODE_TYPE {\n\tPOSITION = 'position',\n\tLIGHTING = 'light',\n\tCOLOR = 'color',\n}\n\nexport class Layer {\n\tuuid?: string;\n\tid: number;\n\tnext?: Layer = undefined;\n\ttype?: string;\n\tuniforms: Record<string, Node> = {};\n\ttextures: Record<string, Texture> = {};\n\tdefines: Record<string, any> = {};\n\n\tconstructor(\n\t\tid: number,\n\t\tuuid?: string,\n\t\tparams?: LayerParameters,\n\t\tdefines?: LayerParameters\n\t) {\n\t\tthis.id = id;\n\t\tthis.uuid = uuid;\n\n\t\tif (params) {\n\t\t\tthis.type = params.type as string;\n\n\t\t\tfor (const key in params) {\n\t\t\t\tif (key !== 'type' && key !== 'calpha') {\n\t\t\t\t\tthis.uniforms[`f${this.id}_${key}`] = params[key] as Node;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const key in defines) {\n\t\t\t\tthis.defines[key] = defines[key] as unknown;\n\t\t\t}\n\t\t}\n\t}\n\n\tcopy(source: this): Layer {\n\t\tthis.id = source.id;\n\t\tthis.type = source.type;\n\n\t\tthis.defines = { ...source.defines };\n\n\t\tfor (const key in source.uniforms) {\n\t\t\t// @PATCH: We do not want to copy the transmission textures.\n\t\t\t// When the interaction state copied these textures and later got serialized,\n\t\t\t// this would cause an error when loading the file again.\n\t\t\t//\n\t\t\t// This line makes sure that these textures are never included in the\n\t\t\t// interaction states.\n\t\t\tif (\n\t\t\t\tthis.getName(key) === 'transmissionSamplerMap' ||\n\t\t\t\tthis.getName(key) === 'transmissionDepthMap'\n\t\t\t)\n\t\t\t\tcontinue;\n\n\t\t\tif (this.uniforms[key]) {\n\t\t\t\tthis.uniforms[key].copy(source.uniforms[key]);\n\t\t\t} else {\n\t\t\t\tthis.uniforms[key] = source.uniforms[key].clone();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tclone(): Layer {\n\t\treturn new Layer(this.id).copy(this);\n\t}\n\n\tfromJSON(source: SerializedLayer, assets: AssetLibrary): Layer {\n\t\tthis.id = source.id;\n\t\tthis.defines = { ...source.defines };\n\n\t\tfor (const key in source.uniforms) {\n\t\t\tthis.uniforms[key] = assets.getNode(source.uniforms[key]);\n\t\t}\n\n\t\t// @PATCH new uniforms were added but old files don't have them\n\t\t// we should use UpraderObject to separated constructors for each type of Layer\n\t\t// See FRO-1739\n\t\tif (source.type === LAYER_TYPE.TEXTURE) {\n\t\t\tif (!(`f${this.id}_textureSize` in this.uniforms)) {\n\t\t\t\tconst image = (this.uniforms[`f${this.id}_texture`].value as Texture)\n\t\t\t\t\t.image as HTMLImageElement | HTMLCanvasElement | HTMLVideoElement;\n\t\t\t\tthis.uniforms[`f${source.id}_textureSize`] = new Vector3Node(\n\t\t\t\t\timage.width,\n\t\t\t\t\timage.height\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!(`f${this.id}_size` in this.uniforms)) {\n\t\t\t\tthis.uniforms[`f${source.id}_size`] = new Vector2Node(200, 200);\n\t\t\t}\n\t\t\tif (!(`f${source.id}_axis` in this.uniforms))\n\t\t\t\tthis.uniforms[`f${source.id}_axis`] = new IntNode(0);\n\t\t\tif (!(`f${source.id}_projection` in this.uniforms))\n\t\t\t\tthis.uniforms[`f${source.id}_projection`] = new IntNode(0);\n\t\t} else if (source.type === LAYER_TYPE.NOISE) {\n\t\t\tif (!(`f${source.id}_noiseType` in this.uniforms))\n\t\t\t\tthis.uniforms[`f${source.id}_noiseType`] = new IntNode(0);\n\t\t\t// TODO COLLAB we don't have ObjectLoader anymore what about this?\n\t\t\t// HACK: ObjectLoader checks these values and sets them correctly based\n\t\t\t// on the object's bounding box. This should be removed and replaced with\n\t\t\t// a proper ObjectUpgrader\n\t\t\tif (!(`f${source.id}_size` in this.uniforms))\n\t\t\t\tthis.uniforms[`f${source.id}_size`] = new Vector3Node(-1, -1, -1);\n\t\t} else if (source.type === LAYER_TYPE.DEPTH) {\n\t\t\tif (!(`f${source.id}_isWorldSpace` in this.uniforms))\n\t\t\t\tthis.uniforms[`f${source.id}_isWorldSpace`] = new FloatNode(1);\n\t\t}\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedLayer {\n\t\tconst uniforms: Record<string, string> = {};\n\t\tfor (const key in this.uniforms) {\n\t\t\tuniforms[key] = this.uniforms[key].toJSON(meta).uuid as string;\n\t\t}\n\n\t\tconst serialized: SerializedLayer = {\n\t\t\tid: this.id,\n\t\t\ttype: this.type,\n\t\t\tdefines: JSON.parse(JSON.stringify(this.defines)) as Record<string, any>,\n\t\t\tuniforms,\n\t\t\tnext: this.next == undefined ? undefined : this.next.toJSON(meta),\n\t\t};\n\n\t\treturn serialized;\n\t}\n\n\tcopyUniforms(source: Layer): Layer {\n\t\tfor (const fullkey in this.uniforms) {\n\t\t\tconst key = this.getName(fullkey);\n\t\t\tif (key === undefined) continue;\n\t\t\t// PATCH(Max): In cases where this function is called from InteractionState\n\t\t\t// and the file was created before light layer values were added to\n\t\t\t// interactions the source might not have the same uniforms as the target.\n\t\t\t// We should rethink how interactions and materials and layers interact when refactoring.\n\t\t\tif (\n\t\t\t\tsource.uniforms[`f${source.id}_${key}`] &&\n\t\t\t\tkey !== 'transmissionDepthMap' && // these two conditions are added to deal with some files\n\t\t\t\tkey !== 'transmissionSamplerMap' // that still have these two keys serialized. We can maybe remove later\n\t\t\t) {\n\t\t\t\tthis.uniforms[fullkey].copy(source.uniforms[`f${source.id}_${key}`]);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\thasValueByKey(key: string): boolean {\n\t\treturn this.uniforms[key] !== undefined;\n\t}\n\n\thasValue(name: string): boolean {\n\t\treturn this.hasValueByKey(`f${this.id}_${name}`);\n\t}\n\n\tsetValue<T>(name: string, value: T) {\n\t\tconst key = `f${this.id}_${name}`;\n\t\tif (this.hasValueByKey(key) && value !== undefined) {\n\t\t\tthis.uniforms[key].value = value;\n\t\t}\n\t}\n\n\tgetValue<T>(name: string): T | undefined {\n\t\tconst key = `f${this.id}_${name}`;\n\t\tif (this.hasValueByKey(key)) {\n\t\t\treturn this.uniforms[key].value as T;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// @nisa: we should not have this\n\tgetValues(): Record<string, any> {\n\t\tconst params: Record<string, any> = { type: this.type };\n\n\t\tfor (const fullname in this.uniforms) {\n\t\t\tconst name = this.getName(fullname);\n\t\t\tif (name === undefined) continue;\n\t\t\tconst uniform = this.uniforms[`f${this.id}_${name}`];\n\t\t\tconst value = uniform.value as ClonableValue;\n\t\t\tif (value !== undefined) {\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tparams[name] = value.map((ele) => (ele.clone ? ele.clone() : ele));\n\t\t\t\t} else {\n\t\t\t\t\tparams[name] = (value.clone ? value.clone() : value) as unknown;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn params;\n\t}\n\n\tgetName(key: string): string | undefined {\n\t\tconst rx = /f\\d+_(.*)/;\n\t\tconst arr = rx.exec(key);\n\n\t\tif (arr && arr.length > 1) {\n\t\t\treturn arr[1];\n\t\t} else {\n\t\t\tconsole.log(`Layer.getName: error ${key}`);\n\t\t}\n\t}\n\n\t// @nisa: we should not have this\n\tgetNames(): string[] {\n\t\tconst names = [];\n\n\t\tfor (const key in this.uniforms) {\n\t\t\tconst name = this.getName(key);\n\t\t\tif (name) names.push(name);\n\t\t}\n\n\t\treturn names;\n\t}\n\n\t// @todo nisa: this was not tested enough. We should have diferent instnaces of layers and isEqual for each one\n\tisEqual(source: Layer): boolean {\n\t\tfor (const fullkey in source.uniforms) {\n\t\t\tconst key = source.getName(fullkey);\n\n\t\t\tif (!key) return false;\n\n\t\t\tconst value = this.getValue(key);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst sourceValue = source.uniforms[fullkey].value;\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\tif (sourceValue.value instanceof Texture) {\n\t\t\t\tif ((value as Texture).image !== (sourceValue as Texture).image)\n\t\t\t\t\treturn false;\n\t\t\t} else if (Array.isArray(sourceValue)) {\n\t\t\t\tconst tempValue = value as Array<number | string | boolean>;\n\n\t\t\t\tfor (let i = 0, l = tempValue.length; i < l; ++i) {\n\t\t\t\t\tif (tempValue[i] !== sourceValue[i]) return false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst tempValue = value as ClonableValue;\n\n\t\t\t\tif (tempValue.equals) {\n\t\t\t\t\tif (!tempValue.equals(sourceValue)) return false;\n\t\t\t\t} else {\n\t\t\t\t\tif (value !== sourceValue) return false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tdispose() {}\n}\n\nexport const CreateLayerFromJSON = function (\n\tjson: SerializedLayer,\n\tassets: AssetLibrary\n) {\n\tconst layerID = json.id;\n\tconst layerType = json.type;\n\tconst layer = new Layer(layerID, undefined, { type: layerType }).fromJSON(\n\t\tjson,\n\t\tassets\n\t);\n\treturn layer;\n};\n\nexport function isTextureLayer(layer: Layer | string): boolean {\n\tconst type = layer instanceof Layer ? layer.type : layer;\n\treturn type === 'texture' || type === 'displace_map' || type === 'matcap';\n}\n", "import { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class IntNode extends InputNode {\n\tvalue: number;\n\tnodeType: string = 'Int';\n\n\tconstructor(value?: number) {\n\t\tsuper('i');\n\t\tthis.value = Math.floor(value ?? 0);\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(this.value.toString(), _type as string, output);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value = source.value;\n\n\t\treturn this;\n\t}\n}\n", "import { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class BoolNode extends InputNode {\n\tvalue: boolean;\n\tnodeType: string = 'Bool';\n\n\tconstructor(value?: boolean) {\n\t\tsuper('b');\n\t\tthis.value = value ?? false;\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\ttype?: string\n\t): string {\n\t\treturn builder.format(\n\t\t\tthis.value ? 'true' : 'false',\n\t\t\ttype as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value = source.value;\n\n\t\treturn this;\n\t}\n}\n", "import { Vector4 } from 'three';\nimport { InputNode } from '../core/InputNode';\n\nexport class Vector4ArrayNode extends InputNode {\n\tvalue: Vector4[];\n\tsize: number;\n\tnodeType: string = 'Vector4Array';\n\n\tconstructor(size: number = 1, value?: Vector4 | Vector4[]) {\n\t\tsuper('v4[]');\n\t\tthis.size = size;\n\t\tthis.value = Array.isArray(value)\n\t\t\t? value\n\t\t\t: value instanceof Vector4\n\t\t\t? new Array<Vector4>(size).fill(value)\n\t\t\t: new Array<Vector4>(size).fill(new Vector4(0));\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.value = source.value.map((ele: Vector4) => ele.clone());\n\n\t\treturn this;\n\t}\n}\n", "import { InputNode } from '../core/InputNode';\n\nexport class FloatArrayNode extends InputNode {\n\tvalue: number[];\n\tsize: number;\n\tnodeType: string = 'FloatArray';\n\n\tconstructor(size: number = 1, value?: number | number[]) {\n\t\tsuper('f[]');\n\t\tthis.size = size;\n\t\tthis.value = Array.isArray(value)\n\t\t\t? value\n\t\t\t: typeof value == 'number'\n\t\t\t? new Array<number>(size).fill(value)\n\t\t\t: new Array<number>(size).fill(0);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.size = source.size;\n\t\tthis.value = [...source.value];\n\n\t\treturn this;\n\t}\n}\n", "import { Matrix3 } from 'three';\nimport { InputNode } from '../core/InputNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class Matrix3Node extends InputNode {\n\tvalue: Matrix3;\n\tnodeType: string = 'Matrix3';\n\n\tconstructor(matrix?: Matrix3) {\n\t\tsuper('m3');\n\t\tthis.value = matrix ?? new Matrix3();\n\t}\n\n\tgenerateReadonly(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string,\n\t\t_needsUpdate?: boolean\n\t): string {\n\t\treturn builder.format(\n\t\t\t'mat3(' + this.value.elements.join(', ') + ')',\n\t\t\t_type as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.elements = source.elements;\n\n\t\treturn this;\n\t}\n\n\tget elements(): number[] {\n\t\treturn this.value.elements;\n\t}\n\n\tset elements(value: number[]) {\n\t\tthis.value.fromArray(value);\n\t}\n}\n", "import { Vector3Node } from '../inputs/Vector3Node';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { IntNode } from '../inputs/IntNode';\nimport { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { TextureNode } from '../inputs/TextureNode';\nimport { Matrix3Node } from '../inputs/Matrix3Node';\nimport { Vector2Node } from '../inputs/Vector2Node';\n\nexport enum PROJECTION_TYPE {\n\tUV,\n\tPLANAR,\n\tSPHERICAL,\n\tCYLINDRICAL,\n}\n\n// TODO: rename\nexport class CustomTextureNode extends TempNode {\n\tfirstTime: boolean;\n\ttexture: TextureNode;\n\ttextureSize: Vector3Node;\n\tcrop: FloatNode;\n\tprojection: IntNode;\n\taxis: IntNode;\n\tsize: Vector2Node;\n\n\tmat: Matrix3Node;\n\talpha: FloatNode;\n\tmode: IntNode;\n\n\t// out params\n\tcalpha: string;\n\n\tnodeType: string = 'CustomTexture';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst cylindrical = new FunctionNode(`\nvec3 cylindricalTexture(sampler2D tex, vec2 textureSize, float crop, mat3 mat, vec2 size, float alpha, int mode, out float calpha) {\n vec3 posN = normalize(position);\n float u = 0.5 + atan(posN.z, posN.x) / (2.*3.1415);\n float scaledHeight = position.y / (size.y * 0.5);\n float v = (scaledHeight / 2.) + .5;\n\n vec2 calculatedUv = vec2(u,v);\n\t\t\t\tvec2 uvs = ( mat * vec3( calculatedUv * 2. - 1., 1. ) / 2. + 0.5 ).xy;\n\n vec2 df = fwidth(uvs);\n \tif(df.x > 0.5) df.x = 0.;\n\n\t\t\t\t#ifdef GL_EXT_shader_texture_lod\n vec4 tmp = texture2DLodEXT(tex, uvs, log2(max(df.x, df.y)*min(textureSize.x, textureSize.y)));\n\t\t\t\t#else\n vec4 tmp = textureLod(tex, uvs, log2(max(df.x, df.y)*min(textureSize.x, textureSize.y)));\n\t\t\t\t#endif\n\n\t\t\t\tvec3 col = tmp.rgb;\n\t\t\t\tfloat lalpha = alpha * tmp.a;\n\t\t\t\tif ( crop > 0.5 ) {\n\t\t\t\t\tif ( uvs.x < 0.0 || uvs.x > 1.0 || uvs.y < 0.0 || uvs.y > 1.0 ) {\n\t\t\t\t\t\tlalpha = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcalpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\t\t\t\treturn col;\n\t\t\t}\n`);\n\n\t\tconst spherical = new FunctionNode(`\nvec3 sphericalTexture(sampler2D tex, vec2 textureSize, float crop, mat3 mat, vec2 size, float alpha, int mode, out float calpha) {\n vec3 posN = normalize(vPosition);\n float u = 0.5 + atan(posN.z, posN.x) / (2.*3.1415);\n float v = 0.5 + asin(posN.y) / 3.1415;\n\n vec2 calculatedUv = vec2(u,v);\n\t\t\t\tvec2 uvs = ( mat * vec3( calculatedUv * 2. - 1., 1. ) / 2. + 0.5 ).xy;\n\n vec2 df = fwidth(uvs);\n \tif(df.x > 0.5) df.x = 0.;\n\t\t\t\t#ifdef GL_EXT_shader_texture_lod\n vec4 tmp = texture2DLodEXT(tex, uvs, log2(max(df.x, df.y)*min(textureSize.x, textureSize.y)));\n\t\t\t\t#else\n vec4 tmp = textureLod(tex, uvs, log2(max(df.x, df.y)*min(textureSize.x, textureSize.y)));\n\t\t\t\t#endif\n\n\t\t\t\tvec3 col = tmp.rgb;\n\t\t\t\tfloat lalpha = alpha * tmp.a;\n\t\t\t\tif ( crop > 0.5 ) {\n\t\t\t\t\tif ( uvs.x < 0.0 || uvs.x > 1.0 || uvs.y < 0.0 || uvs.y > 1.0 ) {\n\t\t\t\t\t\tlalpha = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcalpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\t\t\t\treturn col;\n\t\t\t}\n`);\n\n\t\tconst uv = new FunctionNode(\n\t\t\t`vec3 uvTexture(sampler2D tex, vec2 textureSize, float crop, mat3 mat, vec2 size, float alpha, int mode, out float calpha) {\n\n\t\t\t\tvec2 uvs = ( mat * vec3( vUv * 2. - 1., 1. ) / 2. + 0.5 ).xy;\n\t\t\t\tvec4 tmp = texture2D( tex, uvs );\n\n\t\t\t\tvec3 col = tmp.rgb;\n\n\t\t\t\tfloat lalpha = alpha * tmp.a;\n\t\t\t\tif ( crop > 0.5 ) {\n\t\t\t\t\tif ( uvs.x < 0.0 || uvs.x > 1.0 || uvs.y < 0.0 || uvs.y > 1.0 ) {\n\t\t\t\t\t\tlalpha = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcalpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\t\t\t\treturn col;\n\t\t\t}`\n\t\t);\n\n\t\treturn {\n\t\t\tcylindrical,\n\t\t\tspherical,\n\t\t\tuv,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\ttexture: TextureNode = new TextureNode(),\n\t\ttextureSize: Vector3Node,\n\t\tcrop: FloatNode,\n\t\tprojection: IntNode,\n\t\taxis: IntNode,\n\t\tsize: Vector2Node,\n\t\talpha: FloatNode,\n\t\tmode: IntNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.firstTime = true; //TODO (Max)\n\t\tthis.texture = texture;\n\t\tthis.textureSize = textureSize;\n\t\tthis.crop = crop;\n\t\tthis.projection = projection;\n\t\tthis.axis = axis;\n\t\tthis.size = size;\n\t\tthis.mat = new Matrix3Node(this.texture.value.matrix);\n\t\tthis.alpha = alpha;\n\t\tthis.mode = mode;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tbuilder.require('position');\n\t\tbuilder.require('uv');\n\t\tbuilder.requires.uv = [true];\n\t\tbuilder.extensions.shaderTextureLOD = true;\n\t\tbuilder.extensions.derivatives = true;\n\n\t\tlet textureFunction;\n\t\tswitch (this.projection.value) {\n\t\t\tcase PROJECTION_TYPE.CYLINDRICAL:\n\t\t\t\ttextureFunction = builder.include(CustomTextureNode.Nodes.cylindrical);\n\t\t\t\tbreak;\n\t\t\tcase PROJECTION_TYPE.SPHERICAL:\n\t\t\t\ttextureFunction = builder.include(CustomTextureNode.Nodes.spherical);\n\t\t\t\tbreak;\n\t\t\tcase PROJECTION_TYPE.PLANAR:\n\t\t\t\tconst planar = new FunctionNode(`\n\t\tvec3 g${this.uuid\n\t\t\t.toString()\n\t\t\t.replace(\n\t\t\t\t/-/g,\n\t\t\t\t''\n\t\t\t)}_planarTexture(sampler2D tex, vec2 textureSize, float crop, mat3 mat, vec2 size, float alpha, int mode, out float calpha) {\n\n\t\t\t\tvec2 uvs = ( mat * vec3( (g${this.uuid\n\t\t\t\t\t.toString()\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t/-/g,\n\t\t\t\t\t\t''\n\t\t\t\t\t)}_vCustomUv * 2. - 1.) / (size * .5), 1. ) / 2. + 0.5 ).xy;\n\n\t\t\t\tvec4 tmp = texture2D( tex, uvs );\n\n\t\t\t\tvec3 col = tmp.rgb;\n\t\t\t\tfloat lalpha = alpha * tmp.a;\n\t\t\t\tif ( crop > 0.5 ) {\n\t\t\t\t\tif ( uvs.x < 0.0 || uvs.x > 1.0 || uvs.y < 0.0 || uvs.y > 1.0 ) {\n\t\t\t\t\t\tlalpha = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcalpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\t\t\t\treturn col;\n\t\t\t}`);\n\n\t\t\t\ttextureFunction = builder.include(planar);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\ttextureFunction = builder.include(CustomTextureNode.Nodes.uv);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// We can do planar projection in the vertex shader\n\t\tif (this.projection.value === PROJECTION_TYPE.PLANAR && this.firstTime) {\n\t\t\tconst uuid = `g${this.uuid.toString().replace(/-/g, '')}`;\n\t\t\tbuilder.addVertexParsCode(`varying vec2 ${uuid}_vCustomUv;`);\n\t\t\tbuilder.addFragmentParsCode(`varying vec2 ${uuid}_vCustomUv;`);\n\n\t\t\tbuilder.addVertexFinalCode(`\n vec3 ${uuid}_posN = transformed;\n${\n\tthis.axis.value === 0\n\t\t? `\n\t\t\t\t\t\t\t\t\t float ${uuid}_u = (1. + (${uuid}_posN.z)) / 2.;\n\t\t\t\t\t\t\t\t\t float ${uuid}_v = (1. + (${uuid}_posN.y)) / 2.;\n\t\t\t\t\t\t\t\t\t `\n\t\t: ''\n}\n\n${\n\tthis.axis.value === 1\n\t\t? `\n\t\t\t\t\t\t\t\t\t float ${uuid}_u = (1. + (${uuid}_posN.x)) / 2.;\n\t\t\t\t\t\t\t\t\t float ${uuid}_v = (1. - (${uuid}_posN.z)) / 2.;\n\t\t\t\t\t\t\t\t\t `\n\t\t: ''\n}\n\n${\n\tthis.axis.value === 2\n\t\t? `\n\t\t\t\t\t\t\t\t\t float ${uuid}_u = (1. + (${uuid}_posN.x)) / 2.;\n\t\t\t\t\t\t\t\t\t float ${uuid}_v = (1. + (${uuid}_posN.y)) / 2.;\n\t\t\t\t\t\t\t\t\t `\n\t\t: ''\n}\n\n ${uuid}_vCustomUv = vec2(${uuid}_u, ${uuid}_v);\n `);\n\t\t}\n\n\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\tconst params: Array<string> = [];\n\n\t\tparams.push(this.texture.getTexture(builder, 't'));\n\t\tparams.push(this.textureSize.build(builder, 'v2'));\n\t\tparams.push(this.crop.build(builder, 'f'));\n\t\tparams.push(this.mat.build(builder, 'mat3'));\n\t\tparams.push(this.size.build(builder, 'v2'));\n\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\tparams.push(this.mode.build(builder, 'i'));\n\t\tparams.push(this.calpha);\n\n\t\tthis.firstTime = !this.firstTime;\n\n\t\treturn builder.format(\n\t\t\ttextureFunction + '(' + params.join(',') + ')',\n\t\t\tthis.getType(builder) as string,\n\t\t\toutput\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.texture.copy(source.texture);\n\t\tthis.textureSize = source.textureSize.clone();\n\t\tthis.crop = source.crop.clone();\n\t\tthis.projection = source.projection.clone();\n\t\tthis.axis = source.axis.clone();\n\t\tthis.size = source.size.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.mode = source.mode.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { ColorNode } from '../inputs/ColorNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { IntNode } from '../inputs/IntNode';\nimport { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FunctionNode } from '../core/FunctionNode';\n\nexport class FresnelNode extends TempNode {\n\tcolor: ColorNode;\n\tbias: FloatNode;\n\tscale: FloatNode;\n\tintensity: FloatNode;\n\tfactor: FloatNode;\n\talpha: FloatNode;\n\tmode: IntNode;\n\n\t// out params\n\tcalpha: string;\n\n\tnodeType: string = 'Fresnel';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst fresnel = new FunctionNode(\n\t\t\t`vec3 fresnel(vec3 color, float bias, float scale, float intensity, float factor, float alpha, int mode, out float calpha) {\n\t\t\t\tfloat fresnel = bias + scale * pow( abs( factor + dot( normalize( vWorldViewDir ), normalize( vWNormal ) ) ), intensity );\n\n\t\t\t\tfloat lalpha = clamp( fresnel, 0.0, 1.0 ) * alpha;\n\t\t\t\tcalpha = lalpha / clamp(lalpha + accumAlpha, 0.001, 1.0);\n\t\t\t\taccumAlpha += (1.0 - accumAlpha) * lalpha;\n\t\t\t\treturn color;\n\t\t\t}`\n\t\t);\n\n\t\treturn {\n\t\t\tfresnel,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tcolor: ColorNode,\n\t\tbias: FloatNode,\n\t\tscale: FloatNode,\n\t\tintensity: FloatNode,\n\t\tfactor: FloatNode,\n\t\talpha: FloatNode,\n\t\tmode: IntNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.color = color;\n\t\tthis.bias = bias;\n\t\tthis.scale = scale;\n\t\tthis.intensity = intensity;\n\t\tthis.factor = factor;\n\t\tthis.alpha = alpha;\n\t\tthis.mode = mode;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tbuilder.require('vWorldViewDir');\n\t\tbuilder.require('worldNormal');\n\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\t\tconst fresnel = builder.include(FresnelNode.Nodes.fresnel);\n\n\t\t\tconst params: Array<string> = [];\n\n\t\t\tparams.push(this.color.build(builder, 'c'));\n\t\t\tparams.push(this.bias.build(builder, 'f'));\n\t\t\tparams.push(this.scale.build(builder, 'f'));\n\t\t\tparams.push(this.intensity.build(builder, 'f'));\n\t\t\tparams.push(this.factor.build(builder, 'f'));\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.mode.build(builder, 'i'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\tfresnel + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'FresnelNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.color = source.color.clone();\n\t\tthis.bias = source.bias.clone();\n\t\tthis.scale = source.scale.clone();\n\t\tthis.intensity = source.intensity.clone();\n\t\tthis.factor = source.factor.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.mode = source.mode.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { ConstNode } from '../core/ConstNode';\nimport { FunctionNode } from '../core/FunctionNode';\n\nexport enum NOISE_TYPE {\n\tSIMPLEX = 'simplex3d',\n\tSIMPLEX_FRACTAL = 'simplex3dFractal',\n\tASHIMA = 'simplexAshima',\n\tFBM = 'fbm',\n\tPERLIN = 'perlin',\n}\n\nexport const NoiseFunctions: Record<string, FunctionNode> = (function () {\n\tconst NUM_OCTAVES = 5;\n\n\tconst random3 = new FunctionNode(\n\t\t`vec3 random3(vec3 c) {\n\t\t\tfloat j = 4096.0*sin(dot(c,vec3(17.0, 59.4, 15.0)));\n\t\t\tvec3 r;\n\t\t\tr.z = fract(512.0*j);\n\t\t\tj *= .125;\n\t\t\tr.x = fract(512.0*j);\n\t\t\tj *= .125;\n\t\t\tr.y = fract(512.0*j);\n\t\t\treturn r-0.5;\n\t\t}`\n\t);\n\n\tconst simplex = new FunctionNode(\n\t\t`float simplex3d(vec3 p) {\n\t\t\t vec3 s = floor(p + dot(p, vec3(F3)));\n\t\t\t vec3 x = p - s + dot(s, vec3(G3));\n\t\t\t \n\t\t\t vec3 e = step(vec3(0.0), x - x.yzx);\n\t\t\t vec3 i1 = e*(1.0 - e.zxy);\n\t\t\t vec3 i2 = 1.0 - e.zxy*(1.0 - e);\n\t\t\t\t\n\t\t\t vec3 x1 = x - i1 + G3;\n\t\t\t vec3 x2 = x - i2 + 2.0*G3;\n\t\t\t vec3 x3 = x - 1.0 + 3.0*G3;\n\t\t\t \n\t\t\t vec4 w, d;\n\t\t\t \n\t\t\t w.x = dot(x, x);\n\t\t\t w.y = dot(x1, x1);\n\t\t\t w.z = dot(x2, x2);\n\t\t\t w.w = dot(x3, x3);\n\t\t\t \n\t\t\t w = max(0.6 - w, 0.0);\n\t\t\t \n\t\t\t d.x = dot(random3(s), x);\n\t\t\t d.y = dot(random3(s + i1), x1);\n\t\t\t d.z = dot(random3(s + i2), x2);\n\t\t\t d.w = dot(random3(s + 1.0), x3);\n\t\t\t \n\t\t\t w *= w;\n\t\t\t w *= w;\n\t\t\t d *= w;\n\t\t\t \n\t\t\t return dot(d, vec4(52.0));\n\t\t}`,\n\t\t[random3]\n\t);\n\n\tsimplex.keywords['F3'] = new ConstNode('float F3 0.3333333');\n\tsimplex.keywords['G3'] = new ConstNode('float G3 0.1666667');\n\n\tconst simplexFractal = new FunctionNode(\n\t\t`float simplex3dFractal(vec3 m) {\n\t\t\tmat3 rot1 = mat3(-0.37, 0.36, 0.85,-0.14,-0.93, 0.34,0.92, 0.01,0.4);\n\t\t\tmat3 rot2 = mat3(-0.55,-0.39, 0.74, 0.33,-0.91,-0.24,0.77, 0.12,0.63);\n\t\t\tmat3 rot3 = mat3(-0.71, 0.52,-0.47,-0.08,-0.72,-0.68,-0.7,-0.45,0.56);\n\t\t\treturn 0.5333333 * simplex3d(m * rot1)\n\t\t\t\t + 0.2666667 * simplex3d(2.0 * m * rot2)\n\t\t\t\t + 0.1333333 * simplex3d(4.0 * m * rot3)\n\t\t\t\t + 0.0666667 * simplex3d(8.0 * m);\n\t\t}`,\n\t\t[simplex]\n\t);\n\n\tconst permute = new FunctionNode(\n\t\t`vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}`\n\t);\n\tconst taylorInvSqrt = new FunctionNode(\n\t\t`vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}`\n\t);\n\n\tconst simplexAshima = new FunctionNode(\n\t\t`float simplexAshima(vec3 v) {\n\t\t const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n\t\t const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\t\t vec3 i = floor(v + dot(v, C.yyy) );\n\t\t vec3 x0 = v - i + dot(i, C.xxx) ;\n\t\t vec3 g = step(x0.yzx, x0.xyz);\n\t\t vec3 l = 1.0 - g;\n\t\t vec3 i1 = min( g.xyz, l.zxy );\n\t\t vec3 i2 = max( g.xyz, l.zxy );\n\t\t vec3 x1 = x0 - i1 + 1.0 * C.xxx;\n\t\t vec3 x2 = x0 - i2 + 2.0 * C.xxx;\n\t\t vec3 x3 = x0 - 1. + 3.0 * C.xxx;\n\t\t i = mod(i, 289.0 ); \n\t\t vec4 p = permute( permute( permute( \n\t\t\t\t\t i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n\t\t\t\t + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n\t\t\t\t + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\t\t float n_ = 1.0/7.0; // N=7\n\t\t vec3 ns = n_ * D.wyz - D.xzx;\n\t\t vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)\n\t\t vec4 x_ = floor(j * ns.z);\n\t\t vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\t\t vec4 x = x_ *ns.x + ns.yyyy;\n\t\t vec4 y = y_ *ns.x + ns.yyyy;\n\t\t vec4 h = 1.0 - abs(x) - abs(y);\n\t\t vec4 b0 = vec4( x.xy, y.xy );\n\t\t vec4 b1 = vec4( x.zw, y.zw );\n\t\t vec4 s0 = floor(b0)*2.0 + 1.0;\n\t\t vec4 s1 = floor(b1)*2.0 + 1.0;\n\t\t vec4 sh = -step(h, vec4(0.0));\n\t\t vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n\t\t vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\t\t vec3 p0 = vec3(a0.xy,h.x);\n\t\t vec3 p1 = vec3(a0.zw,h.y);\n\t\t vec3 p2 = vec3(a1.xy,h.z);\n\t\t vec3 p3 = vec3(a1.zw,h.w);\n\t\t vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n\t\t p0 *= norm.x;\n\t\t p1 *= norm.y;\n\t\t p2 *= norm.z;\n\t\t p3 *= norm.w;\n\t\t vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n\t\t m = m * m;\n\t\t return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n\t\t\t\t\t\t\t\t\t\tdot(p2,x2), dot(p3,x3) ) );\n\t\t}`,\n\t\t[permute, taylorInvSqrt]\n\t);\n\n\tconst mod289 = new FunctionNode(\n\t\t`vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}`\n\t);\n\tconst perm = new FunctionNode(\n\t\t`vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);}`,\n\t\t[mod289]\n\t);\n\n\tconst noise = new FunctionNode(\n\t\t`float noise(vec3 p){\n\t\t\tvec3 a = floor(p);\n\t\t\tvec3 d = p - a;\n\t\t\td = d * d * (3.0 - 2.0 * d);\n\t\t\tvec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);\n\t\t\tvec4 k1 = perm(b.xyxy);\n\t\t\tvec4 k2 = perm(k1.xyxy + b.zzww);\n\t\t\tvec4 c = k2 + a.zzzz;\n\t\t\tvec4 k3 = perm(c);\n\t\t\tvec4 k4 = perm(c + 1.0);\n\t\t\tvec4 o1 = fract(k3 * (1.0 / 41.0));\n\t\t\tvec4 o2 = fract(k4 * (1.0 / 41.0));\n\t\t\tvec4 o3 = o2 * d.z + o1 * (1.0 - d.z);\n\t\t\tvec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);\n\t\t\treturn o4.y * d.y + o4.x * (1.0 - d.y);\n\t\t}`,\n\t\t[perm]\n\t);\n\n\tconst fbm = new FunctionNode(\n\t\t`float fbm(vec3 x) {\n\t\t\tfloat v = 0.0;\n\t\t\tfloat a = 0.5;\n\t\t\tvec3 shift = vec3(100);\n\t\t\tfor (int i = 0; i < NUM_OCTAVES; ++i) {\n\t\t\t\tv += a * noise(x);\n\t\t\t\tx = x * 2.0 + shift;\n\t\t\t\ta *= 0.5;\n\t\t\t}\n\t\t\treturn v;\n\t\t}`,\n\t\t[noise]\n\t);\n\tfbm.keywords['NUM_OCTAVES'] = new ConstNode(`int NUM_OCTAVES ${NUM_OCTAVES}`);\n\n\tconst fade = new FunctionNode(\n\t\t`vec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}`\n\t);\n\n\tconst perlin = new FunctionNode(\n\t\t`float perlin(vec3 P){\n\t\t vec3 Pi0 = floor(P);\n\t\t vec3 Pi1 = Pi0 + vec3(1.0);\n\t\t Pi0 = mod(Pi0, 289.0);\n\t\t Pi1 = mod(Pi1, 289.0);\n\t\t vec3 Pf0 = fract(P);\n\t\t vec3 Pf1 = Pf0 - vec3(1.0);\n\t\t vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n\t\t vec4 iy = vec4(Pi0.yy, Pi1.yy);\n\t\t vec4 iz0 = Pi0.zzzz;\n\t\t vec4 iz1 = Pi1.zzzz;\n\t\t vec4 ixy = permute(permute(ix) + iy);\n\t\t vec4 ixy0 = permute(ixy + iz0);\n\t\t vec4 ixy1 = permute(ixy + iz1);\n\t\t vec4 gx0 = ixy0 / 7.0;\n\t\t vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;\n\t\t gx0 = fract(gx0);\n\t\t vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);\n\t\t vec4 sz0 = step(gz0, vec4(0.0));\n\t\t gx0 -= sz0 * (step(0.0, gx0) - 0.5);\n\t\t gy0 -= sz0 * (step(0.0, gy0) - 0.5);\n\t\t vec4 gx1 = ixy1 / 7.0;\n\t\t vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;\n\t\t gx1 = fract(gx1);\n\t\t vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);\n\t\t vec4 sz1 = step(gz1, vec4(0.0));\n\t\t gx1 -= sz1 * (step(0.0, gx1) - 0.5);\n\t\t gy1 -= sz1 * (step(0.0, gy1) - 0.5);\n\t\t vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);\n\t\t vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);\n\t\t vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);\n\t\t vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);\n\t\t vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);\n\t\t vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);\n\t\t vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);\n\t\t vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);\n\t\t vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));\n\t\t g000 *= norm0.x;\n\t\t g010 *= norm0.y;\n\t\t g100 *= norm0.z;\n\t\t g110 *= norm0.w;\n\t\t vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));\n\t\t g001 *= norm1.x;\n\t\t g011 *= norm1.y;\n\t\t g101 *= norm1.z;\n\t\t g111 *= norm1.w;\n\t\t float n000 = dot(g000, Pf0);\n\t\t float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));\n\t\t float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));\n\t\t float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));\n\t\t float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));\n\t\t float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));\n\t\t float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));\n\t\t float n111 = dot(g111, Pf1);\n\t\t vec3 fade_xyz = fade(Pf0);\n\t\t vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);\n\t\t vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);\n\t\t float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); \n\t\t return 2.2 * n_xyz;\n\t\t}`,\n\t\t[permute, taylorInvSqrt, fade]\n\t);\n\n\treturn {\n\t\tsimplex,\n\t\tsimplexFractal,\n\t\tsimplexAshima,\n\t\tfbm,\n\t\tperlin,\n\t};\n})();\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { Vector3Node } from '../inputs/Vector3Node';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nimport { NoiseFunctions } from '../procedural/NoiseTypes';\n\nexport class RainbowNode extends TempNode {\n\tfilmThickness: FloatNode;\n\tmovement: FloatNode;\n\twavelengths: Vector3Node;\n\tnoiseStrength: FloatNode;\n\tnoiseScale: FloatNode;\n\toffset: Vector3Node;\n\talpha: FloatNode;\n\n\tcalpha: string;\n\tnodeType: string = 'Rainbow';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst attenuation = new FunctionNode(\n\t\t\t`vec3 attenuation(vec3 wavelengths, float filmThickness, float movement, float noiseStrength, float noiseScale, vec3 offset) {\n vec3 st = position / noiseScale;\n\t\t\t\t vec3 q = vec3(simplex3d(st),\n\t\t\t\t\t\t\t simplex3d(st + vec3(1.0)),\n\t\t\t\t\t\t\t simplex3d(st + vec3(1.0)));\n\n\t\t\t\t vec3 r = vec3(simplex3d(st + vec3(1.4, 1.3, 1.0) * q + vec3(1.7, 9.2, 1.0)),\n\t\t\t\t\t\t\t simplex3d(st + vec3(2.0, 1.2, 1.0) * q + vec3(8.3, 2.8, 1.0)),\n\t\t\t\t\t\t\t simplex3d(st * q));\n\n float noise = simplex3d(st + r);\n\n return .5 + .5 * cos((((filmThickness + (noise * noiseStrength)) / (vec3(wavelengths.r * 1.0, wavelengths.g * 0.8, wavelengths.b * 0.6) + 1.0)) * dot(normalize(vWorldViewDir + (offset * -0.001)), normalize(vWNormal))) + movement);\n }`,\n\t\t\t[NoiseFunctions.simplex]\n\t\t);\n\n\t\tconst rainbow = new FunctionNode(\n\t\t\t`vec3 rainbow(float filmThickness, float movement, vec3 wavelengths, float noiseStrength, float noiseScale, vec3 offset, float alpha, out float calpha) {\n vec3 res = clamp(attenuation(wavelengths, filmThickness, movement, noiseStrength, noiseScale, offset), 0.0, 2.0);\n\n float rainbowContribution = clamp(res.r + res.g + res.b, 0.0, 1.0);\n float lalpha = alpha * rainbowContribution;\n calpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n accumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\n return res;\n }`,\n\t\t\t[attenuation]\n\t\t);\n\n\t\treturn {\n\t\t\trainbow,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tfilmThickness: FloatNode,\n\t\tmovement: FloatNode,\n\t\twavelengths: Vector3Node,\n\t\tnoiseStrength: FloatNode,\n\t\tnoiseScale: FloatNode,\n\t\toffset: Vector3Node,\n\t\talpha: FloatNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.filmThickness = filmThickness;\n\t\tthis.movement = movement;\n\t\tthis.wavelengths = wavelengths;\n\t\tthis.noiseStrength = noiseStrength;\n\t\tthis.noiseScale = noiseScale;\n\t\tthis.offset = offset;\n\t\tthis.alpha = alpha;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tbuilder.require('vWorldViewDir');\n\t\tbuilder.require('worldNormal');\n\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.require('uv');\n\t\t\tbuilder.requires.uv = [true];\n\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\t\tconst rainbow = builder.include(RainbowNode.Nodes.rainbow);\n\n\t\t\tconst params: Array<string> = [];\n\t\t\tparams.push(this.filmThickness.build(builder, 'f'));\n\t\t\tparams.push(this.movement.build(builder, 'f'));\n\t\t\tparams.push(this.wavelengths.build(builder, 'v3'));\n\t\t\tparams.push(this.noiseStrength.build(builder, 'f'));\n\t\t\tparams.push(this.noiseScale.build(builder, 'f'));\n\t\t\tparams.push(this.offset.build(builder, 'v3'));\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\trainbow + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'RainbowNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.filmThickness = source.filmThickness.clone();\n\t\tthis.movement = source.movement.clone();\n\t\tthis.wavelengths = source.wavelengths.clone();\n\t\tthis.noiseStrength = source.noiseStrength.clone();\n\t\tthis.noiseScale = source.noiseScale.clone();\n\t\tthis.offset = source.offset.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { TextureNode } from '../inputs/TextureNode';\nimport { Vector2Node } from '../inputs/Vector2Node';\n\nexport class TransmissionNode extends TempNode {\n\tthickness: FloatNode;\n\tior: FloatNode;\n\troughness: FloatNode;\n\ttransmissionSamplerSize: Vector2Node;\n\ttransmissionSamplerMap: TextureNode;\n\ttransmissionDepthMap: TextureNode;\n\taspectRatio: Vector2Node;\n\n\talpha: FloatNode;\n\tcalpha: string;\n\tnodeType: string = 'Transmission';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst gaussian = new FunctionNode(\n\t\t\t`\n float gaussian(vec2 i) {\n const float sigma = float(NUM_SAMPLES) * .25;\n return exp( -.5* dot(i/=sigma,i) ) / ( 6.28 * sigma*sigma );\n }`\n\t\t);\n\t\tconst blur = new FunctionNode(\n\t\t\t`\n vec4 blur(sampler2D sp, vec2 U, vec2 scale, float lod, sampler2D dm, vec2 unrefractedU, vec2 aspectRatio) {\n // Slightly modified version of this:\n // https://www.shadertoy.com/view/ltScRG\n\n const int LOD = 2;\n const int sLOD = 4; // tile size = 2^LOD\n\n vec4 O = vec4(0);\n const int s = NUM_SAMPLES/sLOD;\n for ( int i = 0; i < s*s; i++ ) {\n int modulo = (i)-((i)/(s))*(s);\n vec2 d = vec2(float(modulo), float(i/s))*float(sLOD) - float(NUM_SAMPLES)/2.;\n vec2 uv = U + (scale * aspectRatio) * d;\n // What is the depth of the opaque object we're trying to sample\n float opaqueDepth = texture2D(dm, uv).r;\n if (opaqueDepth < gl_FragCoord.z) {\n uv = unrefractedU + ((scale * min(lod / 2., 1.)) * aspectRatio) * d;\n lod = lod > 4.0 ? lod : lod / 2.0;\n }\n\t\t #ifdef TEXTURE_LOD_EXT\n O += gaussian(d) * texture2DLodEXT( sp, uv, lod);\n #else\n O += gaussian(d) * textureLod( sp, uv, lod);\n #endif\n }\n return O / O.a;\n }`,\n\t\t\t[gaussian]\n\t\t);\n\t\tconst getVolumeTransmissionRay = new FunctionNode(\n\t\t\t`\n vec3 getVolumeTransmissionRay( vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix ) {\n\t\t // Direction of refracted light.\n\t\t vec3 refractionVector = refract( -v, n, 1.0 / ior );\n\t\t // Compute rotation-independant scaling of the model matrix.\n\t\t vec3 modelScale;\n\t\t modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\t modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\t modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\t // The thickness is specified in local space.\n\t\t return normalize( refractionVector ) * thickness * modelScale;\n\t }`\n\t\t);\n\n\t\tconst applyIorToRoughness = new FunctionNode(\n\t\t\t`\nfloat applyIorToRoughness( float roughness, float ior ) {\n\t\t// Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and\n\t\t// an IOR of 1.5 results in the default amount of microfacet refraction.\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t} `\n\t\t);\n\t\tconst getTransmissionSample = new FunctionNode(\n\t\t\t`\nvec4 getTransmissionSample( vec2 fragCoord, float roughness, float ior, vec2 transmissionSamplerSize, sampler2D transmissionSamplerMap, sampler2D transmissionDepthMap, vec2 unrefractedCoords, vec2 aspectRatio) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n float lod = applyIorToRoughness(roughness, ior);\n\n return blur(transmissionSamplerMap, fragCoord, vec2(lod / (transmissionSamplerSize.x / 2.)), min(framebufferLod / 5.5, 8.5), transmissionDepthMap, unrefractedCoords, aspectRatio);\n\t}`,\n\t\t\t[applyIorToRoughness, blur]\n\t\t);\n\n\t\tconst getIBLVolumeRefraction = new FunctionNode(\n\t\t\t`\nvec4 getIBLVolumeRefraction( vec3 n, vec3 v, float roughness, vec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness, vec2 transmissionSamplerSize, sampler2D transmissionSamplerMap, sampler2D transmissionDepthMap, vec2 aspectRatio ) {\n vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n vec3 refractedRayExit = position + transmissionRay;\n\n // Project refracted vector on the framebuffer, while mapping to normalized device coordinates.\n vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = ndcPos.xy / ndcPos.w;\n refractionCoords += 1.0;\n refractionCoords /= 2.0;\n\n vec4 ndcPosUnrefracted = projMatrix * viewMatrix * vec4(position, 1.0 );\n vec2 unrefractedCoords = ndcPosUnrefracted.xy / ndcPosUnrefracted.w;\n unrefractedCoords += 1.0;\n unrefractedCoords /= 2.0;\n\n // Sample framebuffer to get pixel the refracted ray hits.\n vec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior, transmissionSamplerSize, transmissionSamplerMap, transmissionDepthMap, unrefractedCoords, aspectRatio );\n // Get the specular component.\n return vec4( ( 1.0 ) * transmittedLight.rgb, transmittedLight.a );\n }`,\n\t\t\t[getTransmissionSample, getVolumeTransmissionRay]\n\t\t);\n\t\tconst transmission = new FunctionNode(\n\t\t\t`\n vec3 transmission(float thickness, float ior, float roughness, vec2 transmissionSamplerSize, sampler2D transmissionSamplerMap, sampler2D transmissionDepthMap, vec2 aspectRatio, vec3 normal, float alpha, out float calpha) {\n vec3 v = vec3(0.);\n if (isOrthographic) {\n v = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n } else {\n v = normalize(vWPosition - cameraPosition);\n }\n vec4 transmission = getIBLVolumeRefraction(vWNormal, -v, roughness, vWPosition, modelMatrix, viewMatrix, projectionMatrix, ior, thickness, transmissionSamplerSize, transmissionSamplerMap, transmissionDepthMap, aspectRatio );\n float lalpha = alpha;\n\n calpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n accumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n return transmission.rgb;\n }`,\n\t\t\t[getIBLVolumeRefraction]\n\t\t);\n\n\t\treturn {\n\t\t\ttransmission,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tthickness: FloatNode,\n\t\tior: FloatNode,\n\t\troughness: FloatNode,\n\t\ttransmissionSamplerSize: Vector2Node,\n\t\ttransmissionSamplerMap: TextureNode,\n\t\ttransmissionDepthMap: TextureNode,\n\t\taspectRatio: Vector2Node,\n\t\talpha: FloatNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.thickness = thickness;\n\t\tthis.ior = ior;\n\t\tthis.roughness = roughness;\n\t\tthis.transmissionSamplerSize = transmissionSamplerSize;\n\t\tthis.transmissionSamplerMap = transmissionSamplerMap;\n\t\tthis.transmissionDepthMap = transmissionDepthMap;\n\t\tthis.aspectRatio = aspectRatio;\n\n\t\tthis.alpha = alpha;\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tbuilder.extensions.shaderTextureLOD = true;\n\t\tbuilder.extensions.derivatives = true;\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.define('NUM_SAMPLES', 30);\n\n\t\t\tbuilder.require('worldPosition');\n\t\t\tbuilder.requires.worldNormal = true;\n\t\t\tbuilder.requires.modelMatrix = true;\n\t\t\tbuilder.requires.projectionMatrix = true;\n\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\t\tconst transmission = builder.include(TransmissionNode.Nodes.transmission);\n\n\t\t\tconst params: Array<string> = [];\n\t\t\tparams.push(this.thickness.build(builder, 'f'));\n\t\t\tparams.push(this.ior.build(builder, 'f'));\n\t\t\tparams.push(this.roughness.build(builder, 'f'));\n\t\t\tparams.push(this.transmissionSamplerSize.build(builder, 'v2'));\n\t\t\tparams.push(this.transmissionSamplerMap.getTexture(builder, 't'));\n\t\t\tparams.push(this.transmissionDepthMap.getTexture(builder, 't'));\n\t\t\tparams.push(this.aspectRatio.build(builder, 'v2'));\n\t\t\tparams.push('normal');\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\ttransmission + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'TransmissionNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(this);\n\n\t\tthis.thickness = source.thickness.clone();\n\t\tthis.ior = source.ior.clone();\n\t\tthis.roughness = source.roughness.clone();\n\t\tthis.transmissionSamplerSize = source.transmissionSamplerSize.clone();\n\t\tthis.transmissionSamplerMap = source.transmissionSamplerMap;\n\t\tthis.transmissionDepthMap = source.transmissionDepthMap;\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { Vector3Node } from '../inputs/Vector3Node';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { TempNode } from '../core/TempNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class CustomNormalNode extends TempNode {\n\tcnormal: Vector3Node;\n\talpha: FloatNode;\n\tnodeType: string = 'CustomNormal';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst customNormal = new FunctionNode(\n\t\t\t`vec3 customNormal(vec3 cnormal, vec3 norm, float alpha) {\n\t\t\t\tvec3 normal = packNormalToRGB( norm ).rgb;\n\t\t\t\tnormal *= step( vec3(0.5), cnormal );\n\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * alpha;\n\n\t\t\t\treturn normal;\n\t\t\t}`\n\t\t);\n\t\treturn {\n\t\t\tcustomNormal,\n\t\t};\n\t})();\n\n\tconstructor(cnormal: Vector3Node, alpha: FloatNode) {\n\t\tsuper('v3');\n\n\t\tthis.cnormal = cnormal;\n\t\tthis.alpha = alpha;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tconst customNormal = builder.include(CustomNormalNode.Nodes.customNormal);\n\n\t\t\tconst params: Array<any> = [];\n\t\t\tparams.push(this.cnormal.build(builder, 'v3'));\n\t\t\tparams.push('normal');\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\n\t\t\treturn builder.format(\n\t\t\t\tcustomNormal + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'CustomNormalNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.cnormal.copy(source.cnormal);\n\t\tthis.alpha.copy(source.alpha);\n\n\t\treturn this;\n\t}\n}\n", "import { IntNode } from '../inputs/IntNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { BoolNode } from '../inputs/BoolNode';\nimport { Vector4ArrayNode } from '../inputs/Vector4ArrayNode';\nimport { FloatArrayNode } from '../inputs/FloatArrayNode';\nimport { Vector2Node } from '../inputs/Vector2Node';\nimport { TempNode } from '../core/TempNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nexport class GradientNode extends TempNode {\n\tgradientType: IntNode;\n\tsmooth: BoolNode;\n\tcolors: Vector4ArrayNode;\n\tsteps: FloatArrayNode;\n\toffset: Vector2Node;\n\tmorph: Vector2Node;\n\tangle: FloatNode;\n\talpha: FloatNode;\n\n\t// out params\n\tcalpha: string;\n\n\tnodeType: string = 'Gradient';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst gradient = new FunctionNode(\n\t\t\t`vec3 gradient(int gradientType, bool smoothed, vec4 colors[GRAD_MAX], float steps[GRAD_MAX], vec2 offset, vec2 morph, float angle, float alpha, out float calpha) {\n\t\t\t\tvec4 color = colors[0];\n\t\t\t\tvec2 m = morph / vUv.xy;\n\t\t\t\tvec2 rot = vec2( 0.5 + m.x, m.y );\n\t\t\t\tvec2 dt = vec2(\n\t\t\t\t\tcos( angle ) * rot.x - sin( angle ) * rot.y,\n\t\t\t\t\tsin( angle ) * rot.x + cos( angle ) * rot.y\n\t\t\t\t);\n\t\t\t\tvec2 pt = ( vUv - 0.5 + offset ) / 2.0 + dt / 2.0;\n\t\t\t\tfloat t = dot( pt, dt ) / dot( dt, dt );\n\t\t\t\tif ( gradientType == 1 ) {\n\t\t\t\t\tt = distance (\n\t\t\t\t\t\t( vUv + morph ) * 3.0,\n\t\t\t\t\t\t( vUv + offset ) + 1.0\n\t\t\t\t\t) + angle;\n\t\t\t\t} else if ( gradientType == 2 ) {\n\t\t\t\t\tfloat polar = atan(\n\t\t\t\t\t\tvUv.x + morph.x - 0.5 + offset.x,\n\t\t\t\t\t\tvUv.y + morph.y - 0.5 + offset.y\n\t\t\t\t\t) * -1.0;\n\t\t\t\t\tt = fract( ( angle / PI / -2.0 ) + 0.5 * ( polar / PI ) );\n\t\t\t\t}\n\n\t\t\t\tfloat p;\n\t\t\t\tif (smoothed) {\n\t\t\t\t\tfor ( int i = 1; i < GRAD_MAX; i++ ) {\n\t\t\t\t\t\tp = clamp( ( t - steps[i-1] ) / ( steps[i] - steps[i-1] ), 0.0, 1.0 );\n\t\t\t\t\t\tcolor = mix(color, colors[i], smoothstep(0.0, 1.0, p));\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tfor ( int i = 1; i < GRAD_MAX; i++ ) {\n\t\t\t\t\t\tp = clamp( ( t - steps[i-1] ) / ( steps[i] - steps[i-1] ), 0.0, 1.0 );\n\t\t\t\t\t\tcolor = mix(color, colors[i], p);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfloat lalpha = alpha * color.a;\n\t\t\t\tcalpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\n\t\t\t\treturn color.xyz;\n\t\t\t}`\n\t\t);\n\n\t\treturn {\n\t\t\tgradient,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tgradientType: IntNode,\n\t\tsmooth: BoolNode,\n\t\tcolors: Vector4ArrayNode,\n\t\tsteps: FloatArrayNode,\n\t\toffset: Vector2Node,\n\t\tmorph: Vector2Node,\n\t\tangle: FloatNode,\n\t\talpha: FloatNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.gradientType = gradientType;\n\t\tthis.smooth = smooth;\n\t\tthis.colors = colors;\n\t\tthis.steps = steps;\n\t\tthis.offset = offset;\n\t\tthis.morph = morph;\n\t\tthis.angle = angle;\n\t\tthis.alpha = alpha;\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.define('GRAD_MAX', 10);\n\t\t\tbuilder.require('uv');\n\t\t\tbuilder.requires.uv = [true];\n\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\t\tconst gradient = builder.include(GradientNode.Nodes.gradient);\n\n\t\t\tconst params: Array<string> = [];\n\t\t\tparams.push(this.gradientType.build(builder, 'i'));\n\t\t\tparams.push(this.smooth.build(builder, 'b'));\n\n\t\t\tparams.push(this.colors.build(builder, 'v4[]'));\n\t\t\tparams.push(this.steps.build(builder, 'f[]'));\n\n\t\t\tparams.push(this.offset.build(builder, 'v2'));\n\t\t\tparams.push(this.morph.build(builder, 'v2'));\n\t\t\tparams.push(this.angle.build(builder, 'f'));\n\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\tgradient + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'GradientNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.gradientType = source.gradientType.clone();\n\t\tthis.smooth = source.smooth.clone();\n\n\t\tthis.colors = source.colors.clone();\n\t\tthis.steps = source.steps.clone();\n\n\t\tthis.offset = source.offset.clone();\n\t\tthis.morph = source.morph.clone();\n\t\tthis.angle = source.angle.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { IntNode } from '../inputs/IntNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { Vector3Node } from '../inputs/Vector3Node';\nimport { TempNode } from '../core/TempNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { TextureNode } from '../inputs/TextureNode';\nimport { Matrix3Node } from '../inputs/Matrix3Node';\n\nimport { NOISE_TYPE, NoiseFunctions } from '../procedural/NoiseTypes';\n\nexport enum DISPLACEMENT_TYPE {\n\tNOISE = 'noise',\n\tMAP = 'map',\n}\n\nexport class VertexDisplacementNode extends TempNode {\n\tcropOrOffset: Vector3Node | FloatNode;\n\tscale?: FloatNode;\n\n\tintensity: FloatNode;\n\tmovementOrTexture: FloatNode | TextureNode;\n\n\tmat?: Matrix3Node;\n\n\tdisplacementTypeIndex: IntNode;\n\tnoiseFunctionIndex?: IntNode;\n\n\tnodeType: string = 'VertexDisplacement';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst orthogonal = new FunctionNode(\n\t\t\t`vec3 orthogonal(vec3 v) {\n\t\t\t\treturn normalize(abs(v.x) > abs(v.z) ? vec3(-v.y, v.x, 0.0) : vec3(0.0, -v.z, v.y));\n\t\t\t}`\n\t\t);\n\n\t\tconst texture = new FunctionNode(\n\t\t\t`float displacementMapTexture(sampler2D tex, float crop, vec2 uv, mat3 mat, vec2 offset) {\n\t\t\t\tvec2 uvs = (mat * vec3(uv * 2.0 - 1.0, 1.0) / 2.0 + 0.5).xy + offset;\n\t\t\t\tvec4 tmp = texture2D(tex, uvs);\n\t\t\t\tvec3 col = tmp.rgb;\n\t\t\t\tif (crop > 0.5) {\n\t\t\t\t\tif ( uvs.x < 0.0 || uvs.x > 1.0 || uvs.y < 0.0 || uvs.y > 1.0 ) {\n\t\t\t\t\t\treturn 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn col.r;\n\t\t\t}`\n\t\t);\n\n\t\tconst map = new FunctionNode(\n\t\t\t`vec3 vertexDisplacementMap(vec3 position, vec3 normal, sampler2D tex, vec2 uv, float crop, mat3 mat, float intensity, out vec3 displaced_normal) {\n\t\t\t\tvec3 displaced_position = position + normal * displacementMapTexture(tex, crop, uv, mat, vec2(0.0)) * intensity;\n\t\t\t\tvec3 tangent1 = normalize(orthogonal(normal));\n\t\t\t\tvec3 tangent2 = normalize(cross(normal, tangent1));\n\t\t\t\tvec3 nearby1 = position + tangent1 * 0.1;\n\t\t\t\tvec3 nearby2 = position + tangent2 * 0.1;\n\t\t\t\tvec3 distorted1 = nearby1 + normal * displacementMapTexture(tex, crop, uv, mat, vec2(neighbor_offset)) * intensity;\n\t\t\t\tvec3 distorted2 = nearby2 + normal * displacementMapTexture(tex, crop, uv, mat, vec2(neighbor_offset)) * intensity;\n\t\t\t\tdisplaced_normal = normalize(cross(distorted1 - displaced_position, distorted2 - displaced_position));\n\t\t\t\treturn displaced_position;\n\t\t\t}`,\n\t\t\t[orthogonal, texture]\n\t\t);\n\n\t\treturn {\n\t\t\tmap,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tdisplacementTypeIndex: IntNode = new IntNode(0),\n\t\tintensity: FloatNode,\n\t\tmovementOrTexture: FloatNode | TextureNode,\n\t\tcropOrOffset: Vector3Node | FloatNode,\n\t\tscale?: FloatNode,\n\t\tnoiseFunctionIndex?: IntNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.displacementTypeIndex = displacementTypeIndex;\n\n\t\tthis.intensity = intensity;\n\t\tthis.movementOrTexture = movementOrTexture;\n\n\t\tif (\n\t\t\tObject.values(DISPLACEMENT_TYPE)[\n\t\t\t\tthis.displacementTypeIndex.value as number\n\t\t\t] === DISPLACEMENT_TYPE.MAP\n\t\t) {\n\t\t\tthis.mat = new Matrix3Node(\n\t\t\t\t(this.movementOrTexture as TextureNode).value.matrix\n\t\t\t);\n\t\t}\n\n\t\tthis.cropOrOffset = cropOrOffset;\n\t\tthis.scale = scale;\n\t\tthis.noiseFunctionIndex = noiseFunctionIndex;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tif (builder.isShader('vertex')) {\n\t\t\tbuilder.define('USE_LAYER_DISPLACE');\n\n\t\t\tlet displacement: string;\n\n\t\t\tconst params: Array<string> = [];\n\n\t\t\tparams.push('displaced_position');\n\t\t\tparams.push('displaced_normal');\n\n\t\t\tconst selectedDisplacement =\n\t\t\t\tObject.values(DISPLACEMENT_TYPE)[\n\t\t\t\t\tthis.displacementTypeIndex.value as number\n\t\t\t\t];\n\n\t\t\tswitch (selectedDisplacement) {\n\t\t\t\tcase DISPLACEMENT_TYPE.MAP: {\n\t\t\t\t\tdisplacement = builder.include(VertexDisplacementNode.Nodes.map);\n\t\t\t\t\tparams.push(\n\t\t\t\t\t\t(this.movementOrTexture as TextureNode).getTexture(builder, 't')\n\t\t\t\t\t);\n\t\t\t\t\tparams.push('uv');\n\t\t\t\t\tparams.push(this.cropOrOffset.build(builder, 'f'));\n\t\t\t\t\tif (this.mat) params.push(this.mat.build(builder, 'mat3'));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase DISPLACEMENT_TYPE.NOISE: {\n\t\t\t\t\tconst noiseFunction = Object.values(NOISE_TYPE)[\n\t\t\t\t\t\tthis.noiseFunctionIndex!.value as number\n\t\t\t\t\t] as string;\n\n\t\t\t\t\tconst orthogonal = new FunctionNode(\n\t\t\t\t\t\t`vec3 orthogonal(vec3 v) {\n\t\t\t\t\t\t\treturn normalize(abs(v.x) > abs(v.z) ? vec3(-v.y, v.x, 0.0) : vec3(0.0, -v.z, v.y));\n\t\t\t\t\t\t}`\n\t\t\t\t\t);\n\n\t\t\t\t\tconst distorted = new FunctionNode(\n\t\t\t\t\t\t`vec3 distorted(vec3 p, vec3 n, float scale, float intensity, vec3 offset, float neighbour_offset, float movement) {\n\t\t\t\t\t\t\treturn p + n * ${noiseFunction}((p + offset) * scale * 0.001 + neighbour_offset + (movement * 0.1)) * intensity;\n\t\t\t\t\t\t}`,\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tNoiseFunctions.simplex,\n\t\t\t\t\t\t\tNoiseFunctions.simplexFractal,\n\t\t\t\t\t\t\tNoiseFunctions.simplexAshima,\n\t\t\t\t\t\t\tNoiseFunctions.fbm,\n\t\t\t\t\t\t\tNoiseFunctions.perlin,\n\t\t\t\t\t\t]\n\t\t\t\t\t);\n\n\t\t\t\t\tconst displaceFunc = new FunctionNode(\n\t\t\t\t\t\t`vec3 vertexDisplacementNoise(vec3 position, vec3 normal, float scale, vec3 offset, float movement, float intensity, out vec3 displaced_normal) {\n\t\t\t\t\t\t\tvec3 displaced_position = distorted(position, normal, scale, intensity, offset, neighbor_offset, movement);\n\t\t\t\t\t\t\tvec3 tangent1 = orthogonal(normal);\n\t\t\t\t\t\t\tvec3 tangent2 = normalize(cross(normal, tangent1));\n\n // TODO(Max): The distance to the neighbors was originally scaled by 0.1.\n // This caused some small oval/circular visual artifacts in the lighting.\n // For now, simply using neighbors further away betters the problem,\n // but we should figure out the underlying cause when we have some time.\n // Maybe its related to how we calculate the tangent and bitangent?\n\t\t\t\t\t\t\tvec3 nearby1 = position + tangent1;\n\t\t\t\t\t\t\tvec3 nearby2 = position + tangent2;\n\t\t\t\t\t\t\tvec3 distorted1 = distorted(nearby1, normal, scale, intensity, offset, neighbor_offset, movement);\n\t\t\t\t\t\t\tvec3 distorted2 = distorted(nearby2, normal, scale, intensity, offset, neighbor_offset, movement);\n\t\t\t\t\t\t\tdisplaced_normal = normalize(cross(distorted1 - displaced_position, distorted2 - displaced_position));\n\t\t\t\t\t\t\treturn displaced_position;\n\t\t\t\t\t\t}`,\n\t\t\t\t\t\t[distorted, orthogonal]\n\t\t\t\t\t);\n\t\t\t\t\tdisplacement = builder.include(displaceFunc);\n\n\t\t\t\t\tparams.push(this.scale!.build(builder, 'f'));\n\t\t\t\t\tparams.push(this.cropOrOffset.build(builder, 'v3'));\n\t\t\t\t\tparams.push(this.movementOrTexture.build(builder, 'f'));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparams.push(this.intensity.build(builder, 'f'));\n\t\t\tparams.push('displaced_normal');\n\n\t\t\treturn builder.format(\n\t\t\t\tdisplacement + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'VertexDisplacementNode is not compatible with ' +\n\t\t\t\t\tbuilder.shader +\n\t\t\t\t\t' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: VertexDisplacementNode) {\n\t\tsuper.copy(source);\n\n\t\tthis.noiseFunctionIndex = source.noiseFunctionIndex?.clone();\n\t\tthis.scale = source.scale?.clone();\n\t\tthis.cropOrOffset = source.cropOrOffset.clone();\n\t\tthis.intensity = source.intensity.clone();\n\t\tthis.movementOrTexture = source.movementOrTexture.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { TempNode } from '../core/TempNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { Node } from '../core/Node';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Meta } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../AssetLibrary';\n\nimport { NOISE_TYPE, NoiseFunctions } from './NoiseTypes';\n\nexport class NoiseNode extends TempNode {\n\tscale: Node;\n\tsize: Node;\n\tmove: Node;\n\tfA: Node;\n\tfB: Node;\n\tdistortion: Node;\n\tcolorA: Node;\n\tcolorB: Node;\n\tcolorC: Node;\n\tcolorD: Node;\n\talpha: Node;\n\tnoiseType: Node;\n\n\tcalpha: string;\n\tnodeType: string = 'Noise';\n\n\tstatic numOctaves: number = 5;\n\n\tconstructor(\n\t\tscale: Node = new Node(),\n\t\tsize: Node = new Node(),\n\t\tmove: Node = new Node(),\n\t\tfA: Node = new Node(),\n\t\tfB: Node = new Node(),\n\t\tdistortion: Node = new Node(),\n\t\tcolorA: Node = new Node(),\n\t\tcolorB: Node = new Node(),\n\t\tcolorC: Node = new Node(),\n\t\tcolorD: Node = new Node(),\n\t\talpha: Node = new Node(),\n\t\tnoiseType: Node = new Node()\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.scale = scale;\n\t\tthis.size = size;\n\t\tthis.move = move;\n\t\tthis.fA = fA;\n\t\tthis.fB = fB;\n\t\tthis.distortion = distortion;\n\t\tthis.colorA = colorA;\n\t\tthis.colorB = colorB;\n\t\tthis.colorC = colorC;\n\t\tthis.colorD = colorD;\n\n\t\tthis.alpha = alpha;\n\t\tthis.noiseType = noiseType;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(\n\t\tbuilder: NodeBuilder,\n\t\toutput: string,\n\t\t_uuid?: string,\n\t\t_type?: string,\n\t\t_ns?: string\n\t): string {\n\t\tbuilder.require('uv');\n\t\tbuilder.requires.uv = [true];\n\n\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\tconst noiseFunction = Object.values(NOISE_TYPE)[\n\t\t\tthis.noiseType.value as number\n\t\t] as string;\n\t\tconst customNoise = new FunctionNode(\n\t\t\t// TODO(piero): colors should have alpha channel.\n\t\t\t`vec3 ${noiseFunction}customNoise(float scale, vec3 size, float move, vec2 fA, vec2 fB, vec2 distortion, vec4 colorA, vec4 colorB, vec4 colorC, vec4 colorD, float alpha, out float calpha) {\n vec3 st = position / size;\n\t\t\t\tst /= scale;\n\t\t\t\tvec3 q = vec3(${noiseFunction}(st),\n\t\t\t\t\t\t\t ${noiseFunction}(st + vec3(1.0)),\n\t\t\t\t\t\t\t ${noiseFunction}(st + vec3(1.0)));\n\t\t\t\tvec3 r = vec3(${noiseFunction}(st + vec3(distortion, 1.0) * q + vec3(fA, 1.0) + move),\n\t\t\t\t\t\t\t ${noiseFunction}(st + vec3(distortion, 1.0) * q + vec3(fB, 1.0) + move), \n\t\t\t\t\t\t\t ${noiseFunction}(st * q));\n\t\t\t\tfloat f = ${noiseFunction}(st + r);\n\t\t\t\tvec4 color;\n\t\t\t\tcolor = mix(colorA, colorB, clamp((f * f) * 4.0, 0.0, 1.0));\n\t\t\t\tcolor = mix(color, colorC, clamp(length(q), 0.0, 1.0));\n\t\t\t\tcolor = mix(color, colorD, clamp(length(r.x), 0.0, 1.0));\n\n float lalpha = alpha * color.a;\n calpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\n\t\t\t accumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n\t\t\t\treturn clamp(color, 0.0, 1.0).rgb;\n\t\t\t}`,\n\t\t\t[\n\t\t\t\tNoiseFunctions.simplex,\n\t\t\t\tNoiseFunctions.simplexFractal,\n\t\t\t\tNoiseFunctions.simplexAshima,\n\t\t\t\tNoiseFunctions.fbm,\n\t\t\t\tNoiseFunctions.perlin,\n\t\t\t]\n\t\t);\n\t\tconst customNoiseInclude = builder.include(customNoise);\n\n\t\tconst params: Array<any> = [];\n\n\t\tparams.push(this.scale.build(builder, 'f'));\n\t\tparams.push(this.size.build(builder, 'v3'));\n\t\tparams.push(this.move.build(builder, 'f'));\n\t\tparams.push(this.fA.build(builder, 'v2'));\n\t\tparams.push(this.fB.build(builder, 'v2'));\n\t\tparams.push(this.distortion.build(builder, 'v2'));\n\t\tparams.push(this.colorA.build(builder, 'v4'));\n\t\tparams.push(this.colorB.build(builder, 'v4'));\n\t\tparams.push(this.colorC.build(builder, 'v4'));\n\t\tparams.push(this.colorD.build(builder, 'v4'));\n\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\tparams.push(this.calpha);\n\n\t\tconst x = builder.format(\n\t\t\tcustomNoiseInclude + '(' + params.join(',') + ')',\n\t\t\tthis.getType(builder) as string,\n\t\t\toutput\n\t\t);\n\t\treturn x;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.scale.copy(source.scale);\n\t\tthis.size.copy(source.size);\n\t\tthis.move.copy(source.move);\n\t\tthis.fA.copy(source.fA);\n\t\tthis.fB.copy(source.fB);\n\t\tthis.distortion.copy(source.distortion);\n\t\tthis.colorA.copy(source.colorA);\n\t\tthis.colorB.copy(source.colorB);\n\t\tthis.colorC.copy(source.colorC);\n\t\tthis.colorD.copy(source.colorD);\n\t\tthis.alpha.copy(source.alpha);\n\t\tthis.calpha = source.calpha;\n\t\tthis.noiseType.copy(source.noiseType);\n\n\t\treturn this;\n\t}\n}\n", "import { Node } from '../core/Node';\nimport { TempNode } from '../core/TempNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\n\nexport class BlendNode extends TempNode {\n\ta: Node;\n\tb: Node;\n\talpha: Node;\n\tmode: Node;\n\tnodeType: string = 'Blend';\n\n\tconstructor(\n\t\ta: Node = new Node(),\n\t\tb: Node = new Node(),\n\t\talpha: Node = new Node(),\n\t\tmode: Node = new Node()\n\t) {\n\t\tsuper('v3');\n\t\tthis.a = a;\n\t\tthis.b = b;\n\t\tthis.alpha = alpha;\n\t\tthis.mode = mode;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tconst params: Array<any> = [];\n\n\t\t\tparams.push(this.a.build(builder, 'c'));\n\t\t\tparams.push(this.b.build(builder, 'c'));\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.mode.build(builder, 'i'));\n\n\t\t\treturn builder.format(\n\t\t\t\t'spe_blend(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'BlendNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.a.copy(source.a);\n\t\tthis.b.copy(source.b);\n\t\tthis.alpha.copy(source.alpha);\n\t\tthis.mode.copy(source.mode);\n\n\t\treturn this;\n\t}\n}\n", "import { FloatNode } from '../inputs/FloatNode';\nimport { Vector3Node } from '../inputs/Vector3Node';\nimport { TempNode } from '../core/TempNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { Vector4ArrayNode } from '../inputs/Vector4ArrayNode';\nimport { FloatArrayNode } from '../inputs/FloatArrayNode';\nimport { IntNode } from '../inputs/IntNode';\nimport { BoolNode } from '../inputs/BoolNode';\nimport { GradientType } from 'spline-data';\n\nexport class DepthNode extends TempNode {\n\tgradientType: IntNode;\n\tsmooth: BoolNode;\n\tnear: FloatNode;\n\tfar: FloatNode;\n\tisVector: FloatNode;\n\tisWorldSpace: FloatNode;\n\torigin: Vector3Node;\n\tdirection: Vector3Node;\n\tcolors: Vector4ArrayNode;\n\tsteps: FloatArrayNode;\n\tnum: IntNode;\n\talpha: FloatNode;\n\n\tcalpha: string;\n\tnodeType: string = 'Depth';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst vectorLinearWorldSpaceDepth = new FunctionNode(\n\t\t\t`float vectorLinearWorldSpaceDepth(vec3 direction, vec3 origin, float near, float far) {\n vec3 n = normalize(direction);\n float dist = (n.x*(vWPosition.x - origin.x) + n.y*(vWPosition.y - origin.y) + n.z*(vWPosition.z - origin.z));\n return ( dist - near ) / ( far - near );\n }`\n\t\t);\n\n\t\tconst vectorLinearObjectSpaceDepth = new FunctionNode(\n\t\t\t`float vectorLinearObjectSpaceDepth(vec3 direction, vec3 origin, float near, float far) {\n vec3 n = normalize(direction);\n float dist = (n.x*(position.x - origin.x) + n.y*(position.y - origin.y) + n.z*(position.z - origin.z));\n return ( dist - near ) / ( far - near );\n }`\n\t\t);\n\n\t\tconst vectorSphericalWorldSpaceDepth = new FunctionNode(\n\t\t\t`float vectorSphericalWorldSpaceDepth(vec3 origin, float near, float far) {\n float dist = length(vWPosition - origin);\n return ( dist - near ) / ( far - near );\n }`\n\t\t);\n\n\t\tconst vectorSphericalObjectSpaceDepth = new FunctionNode(\n\t\t\t`float vectorSphericalObjectSpaceDepth(vec3 origin, float near, float far) {\n float dist = length(position - origin);\n return ( dist - near ) / ( far - near );\n }`\n\t\t);\n\n\t\treturn {\n\t\t\tvectorLinearWorldSpaceDepth,\n\t\t\tvectorLinearObjectSpaceDepth,\n\t\t\tvectorSphericalWorldSpaceDepth,\n\t\t\tvectorSphericalObjectSpaceDepth,\n\t\t};\n\t})();\n\n\tconstructor(\n\t\tgradientType: IntNode,\n\t\tsmooth: BoolNode,\n\t\tnear: FloatNode,\n\t\tfar: FloatNode,\n\t\tisVector: FloatNode,\n\t\tisWorldSpace: FloatNode,\n\t\torigin: Vector3Node,\n\t\tdirection: Vector3Node,\n\t\tcolors: Vector4ArrayNode,\n\t\tsteps: FloatArrayNode,\n\t\tnum: IntNode,\n\t\talpha: FloatNode\n\t) {\n\t\tsuper('v3');\n\n\t\tthis.gradientType = gradientType;\n\t\tthis.smooth = smooth;\n\t\tthis.near = near;\n\t\tthis.far = far;\n\t\tthis.isVector = isVector;\n\t\tthis.isWorldSpace = isWorldSpace;\n\t\tthis.origin = origin;\n\t\tthis.direction = direction;\n\t\tthis.colors = colors;\n\t\tthis.steps = steps;\n\t\tthis.num = num;\n\t\tthis.alpha = alpha;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tconst idString = `g${this.uuid.toString().replace(/-/g, '')}`;\n\t\tconst depthFunction = new FunctionNode(\n\t\t\t`vec3 ${idString}_sdepth(float near, float far, vec3 origin, vec3 direction, vec4 colors[${idString}_MAX_COLORS], float steps[10], float alpha, out float calpha) {\n vec4 color = colors[0];\n #ifdef ${idString}_IS_VECTOR\n #ifdef ${idString}_LINEAR\n #ifdef ${idString}_WORLDSPACE\n float depth = vectorLinearWorldSpaceDepth(direction, origin, near, far);\n #else\n float depth = vectorLinearObjectSpaceDepth(direction, origin, near, far);\n #endif\n #else\n #ifdef ${idString}_WORLDSPACE\n float depth = vectorSphericalWorldSpaceDepth(origin, near, far);\n #else\n float depth = vectorSphericalObjectSpaceDepth(origin, near, far);\n #endif\n #endif\n #else\n float dist = length(vWPosition - cameraPosition);\n\t\t\t float depth = ( dist - near ) / ( far - near );\n #endif\n\n\n float p;\n #ifdef ${idString}_SMOOTH\n\t\t\t\tfor ( int i = 1; i < ${idString}_MAX_COLORS; i++ ) {\n\t\t\t\t\t\tp = clamp( ( depth - steps[i-1] ) / ( steps[i] - steps[i-1] ), 0.0, 1.0 );\n\t\t\t\t\t\tcolor = mix(color, colors[i], smoothstep(0.0, 1.0, p));\n\t\t\t\t\t}\n #else\n for ( int i = 1; i < ${idString}_MAX_COLORS; i++ ) {\n p = clamp(( depth - steps[i - 1] ) / ( steps[i] - steps[i - 1] ), 0.0, 1.0);\n color = mix(color, colors[i], p);\n }\n #endif\n\n float lalpha = alpha * color.a;\n calpha = lalpha / clamp( lalpha + accumAlpha, 0.00001, 1.0 );\n\n\t\t\t accumAlpha += ( 1.0 - accumAlpha ) * lalpha;\n return color.rgb;\n\t\t\t}`,\n\t\t\t[\n\t\t\t\tDepthNode.Nodes.vectorLinearWorldSpaceDepth,\n\t\t\t\tDepthNode.Nodes.vectorLinearObjectSpaceDepth,\n\t\t\t\tDepthNode.Nodes.vectorSphericalObjectSpaceDepth,\n\t\t\t\tDepthNode.Nodes.vectorSphericalWorldSpaceDepth,\n\t\t\t]\n\t\t);\n\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.define(`${idString}_MAX_COLORS`, this.num.value + 1);\n\t\t\tif (this.smooth.value) builder.define(`${idString}_SMOOTH`);\n\n\t\t\tif (this.isVector.value > 0.5) {\n\t\t\t\tbuilder.define(`${idString}_IS_VECTOR`);\n\t\t\t}\n\n\t\t\tif (this.gradientType.value === GradientType.Linear) {\n\t\t\t\tbuilder.define(`${idString}_LINEAR`);\n\t\t\t}\n\n\t\t\tif (this.isWorldSpace.value > 0.5) {\n\t\t\t\tbuilder.define(`${idString}_WORLDSPACE`);\n\t\t\t}\n\n\t\t\tbuilder.require('worldPosition');\n\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\n\t\t\tconst sdepth = builder.include(depthFunction);\n\n\t\t\tconst params: Array<any> = [];\n\t\t\tparams.push(this.near.build(builder, 'f'));\n\t\t\tparams.push(this.far.build(builder, 'f'));\n\t\t\tparams.push(this.origin.build(builder, 'v3'));\n\t\t\tparams.push(this.direction.build(builder, 'v3'));\n\t\t\tparams.push(this.colors.build(builder, 'v4[]'));\n\t\t\tparams.push(this.steps.build(builder, 'f[]'));\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\tsdepth + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'DepthNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.gradientType = source.gradientType.clone();\n\t\tthis.smooth = source.smooth.clone();\n\t\tthis.near = source.near.clone();\n\t\tthis.far = source.far.clone();\n\t\tthis.isVector = source.isVector.clone();\n\t\tthis.isWorldSpace = source.isWorldSpace.clone();\n\t\tthis.origin = source.origin.clone();\n\t\tthis.direction = source.direction.clone();\n\t\tthis.colors = source.colors.clone();\n\t\tthis.steps = source.steps.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { IntNode } from '../inputs/IntNode';\nimport { FloatNode } from '../inputs/FloatNode';\nimport { FunctionNode } from '../core/FunctionNode';\nimport { NodeBuilder } from '../core/NodeBuilder';\nimport { TempNode } from '../core/TempNode';\nimport { TextureNode } from '../inputs/TextureNode';\n\nexport class MatcapNode extends TempNode {\n\ttexture: TextureNode;\n\talpha: FloatNode;\n\tmode: IntNode;\n\n\t// out params\n\tcalpha: string;\n\n\tnodeType: string = 'Matcap';\n\n\tstatic Nodes: Record<string, FunctionNode> = (function () {\n\t\tconst matcap =\n\t\t\tnew FunctionNode(/* glsl */ `vec3 matcap(sampler2D matcapTex, vec3 normal, float alpha, int mode, out float calpha) {\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n vec4 matcapColor = texture2D( matcapTex, uv );\n\n calpha = alpha / clamp( alpha + accumAlpha, 0.00001, 1.0 );\n\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * alpha;\n \n return matcapColor.rgb;\n }\n `);\n\n\t\treturn {\n\t\t\tmatcap,\n\t\t};\n\t})();\n\n\tconstructor(texture: TextureNode, alpha: FloatNode, mode: IntNode) {\n\t\tsuper('v3');\n\n\t\tthis.texture = texture;\n\t\tthis.alpha = alpha;\n\t\tthis.mode = mode;\n\n\t\tthis.calpha = `g${this.uuid.toString().replace(/-/g, '')}_calpha`;\n\t}\n\n\tgenerate(builder: NodeBuilder, output: string): string {\n\t\tif (builder.isShader('fragment')) {\n\t\t\tbuilder.addFragmentVariable(this.calpha, 'float');\n\t\t\tconst matcap = builder.include(MatcapNode.Nodes.matcap);\n\n\t\t\tbuilder.require('normal');\n\t\t\tbuilder.requires.normal = true;\n\n\t\t\tconst params: Array<string> = [];\n\t\t\tparams.push(this.texture.getTexture(builder, 't'));\n\t\t\tparams.push('normal');\n\t\t\tparams.push(this.alpha.build(builder, 'f'));\n\t\t\tparams.push(this.mode.build(builder, 'i'));\n\t\t\tparams.push(this.calpha);\n\n\t\t\treturn builder.format(\n\t\t\t\tmatcap + '(' + params.join(',') + ')',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'MatcapNode is not compatible with ' + builder.shader + ' shader.'\n\t\t\t);\n\n\t\t\treturn builder.format(\n\t\t\t\t'vec3( 0.0 )',\n\t\t\t\tthis.getType(builder) as string,\n\t\t\t\toutput\n\t\t\t);\n\t\t}\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.texture = source.texture.clone();\n\t\tthis.alpha = source.alpha.clone();\n\t\tthis.mode = source.mode.clone();\n\t\tthis.calpha = source.calpha;\n\n\t\treturn this;\n\t}\n}\n", "import { NodeBuilder } from '../../core/NodeBuilder';\nimport { Node } from '../../core/Node';\nimport { ColorNode } from '../../inputs/ColorNode';\nimport { FloatNode } from '../../inputs/FloatNode';\nimport { Vector3Node } from '../../inputs/Vector3Node';\nimport { IntNode } from '../../inputs/IntNode';\nimport { ExpressionNode } from '../../core/ExpressionNode';\nimport { BlendNode } from '../../custom/BlendNode';\nimport { OperatorNode } from '../../math/OperatorNode';\nimport { UniformsLib, UniformsUtils } from 'three';\nimport { colorDefault } from 'common/src/constants';\n\nexport class BasicNode extends Node {\n\tcolor?: ColorNode | BlendNode;\n\tposition?: Vector3Node | OperatorNode;\n\talpha?: FloatNode;\n\tafterColor?: ExpressionNode | BlendNode;\n\tshadingAlpha?: FloatNode;\n\tshadingBlend?: IntNode;\n\tnodeType: string = 'Basic';\n\n\tconstructor() {\n\t\tsuper('basic');\n\t\tthis.color = new ColorNode(colorDefault);\n\t}\n\n\tgenerate(builder: NodeBuilder) {\n\t\tlet code;\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tconst position = this.position\n\t\t\t\t? this.position.analyzeAndFlow(builder, 'v3', { cache: 'position' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.mergeUniform(UniformsUtils.merge([UniformsLib.fog]));\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\t\t\t\t\t'#include <fog_pars_vertex>',\n\t\t\t\t\t'#include <normal_pars_vertex>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <beginnormal_vertex>',\n\t\t\t\t`\n\t\t\t\t#if !defined( USE_LAYER_DISPLACE )\n\t\t\t\t\t#include <defaultnormal_vertex>\n\t\t\t\t#endif\n\n\t\t\t\tvec3 displaced_position = position;\n\t\t\t\tvec3 displaced_normal = normal;\n\n\t\t\t\t#if defined( USE_LAYER_DISPLACE )\n\t\t\t\t\tvec3 transformed;\n\t\t\t\t\tvec3 transformedNormal;\n\t\t\t\t#endif\n\t\t\t\t`,\n\n\t\t\t\t'#include <normal_vertex>',\n\n\t\t\t\t`\n\t\t\t\t#if !defined( USE_LAYER_DISPLACE )\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t#endif /* !USE_LAYER_DISPLACE */\n\t\t\t\t`,\n\t\t\t];\n\n\t\t\tif (position) {\n\t\t\t\toutput.push(\n\t\t\t\t\tposition.code,\n\t\t\t\t\tposition.result ? 'displaced_position = ' + position.result + ';' : ''\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'transformed = displaced_position;',\n\t\t\t\t'transformedNormal = normalMatrix * displaced_normal;',\n\n\t\t\t\t'#ifndef FLAT_SHADED',\n\t\t\t\t'\tvNormal = transformedNormal;',\n\t\t\t\t'#endif'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'#include <project_vertex>',\n\t\t\t\t'#include <fog_vertex>',\n\t\t\t\t'#include <clipping_planes_vertex>',\n\n\t\t\t\t'\tvViewPosition = - mvPosition.xyz;',\n\n\t\t\t\t'#include <worldpos_vertex>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t} else {\n\t\t\t// Analyze all nodes to reuse generate codes\n\t\t\tif (this.color === undefined) this.color = new ColorNode(colorDefault);\n\t\t\tthis.color.analyze(builder, { slot: 'color' });\n\n\t\t\tif (this.alpha) this.alpha.analyze(builder);\n\n\t\t\tif (this.afterColor)\n\t\t\t\tthis.afterColor.analyze(builder, { slot: 'afterColor' });\n\n\t\t\t// Build code\n\t\t\tconst color = this.color.flow(builder, 'c', { slot: 'color' });\n\t\t\tconst alpha = this.alpha ? this.alpha.flow(builder, 'f') : undefined;\n\n\t\t\tconst afterColor = this.afterColor\n\t\t\t\t? this.afterColor.flow(builder, 'c', { slot: 'afterColor' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.requires.transparent = alpha !== undefined;\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'#include <fog_pars_fragment>',\n\t\t\t\t\t'#include <dithering_pars_fragment>',\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\n\t\t\t\t\t'#include <normal_pars_fragment>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t// add before: prevent undeclared normal\n\t\t\t\t'#include <normal_fragment_begin>',\n\n\t\t\t\tcolor.code,\n\t\t\t];\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\talpha.code,\n\t\t\t\t\t'#ifdef ALPHATEST',\n\n\t\t\t\t\t' if ( ' + alpha.result + ' <= ALPHATEST ) discard;',\n\n\t\t\t\t\t'#endif'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (afterColor) {\n\t\t\t\toutput.push(\n\t\t\t\t\tafterColor.code,\n\t\t\t\t\t`vec3 outgoingLight = ${color.result};`,\n\t\t\t\t\t`vec3 finalColor = spe_blend(outgoingLight, ${afterColor.result}, 1.0, SPE_BLENDING_NORMAL);`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push(`vec3 finalColor = ${color.result};`);\n\t\t\t}\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\t`gl_FragColor = vec4( finalColor, accumAlpha * ${alpha.result} );`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push('gl_FragColor = vec4(' + color.result + ', 1.0 );');\n\t\t\t}\n\n\t\t\toutput.push('#include <fog_fragment>', '#include <dithering_fragment>');\n\n\t\t\tcode = output.join('\\n');\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tif (source.color) this.color = source.color.clone();\n\t\tif (source.position) this.position = source.position.clone();\n\t\tif (source.alpha) this.alpha = source.alpha.clone();\n\t\tif (source.afterColor) this.afterColor = source.afterColor.clone();\n\t\tif (source.shadingAlpha) this.shadingAlpha = source.shadingAlpha.clone();\n\t\tif (source.shadingBlend) this.shadingBlend = source.shadingBlend.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { NodeMaterial, NodeMaterialParameters } from './NodeMaterial';\nimport { BasicNode } from './nodes/BasicNode';\n\nexport class BasicNodeMaterial extends NodeMaterial {\n\tfragment: BasicNode;\n\n\tget color() {\n\t\treturn this.fragment.color;\n\t}\n\tset color(val) {\n\t\tthis.fragment.color = val;\n\t}\n\n\tget afterColor() {\n\t\treturn this.fragment.afterColor;\n\t}\n\tset afterColor(val) {\n\t\tthis.fragment.afterColor = val;\n\t}\n\n\tget alpha() {\n\t\treturn this.fragment.alpha;\n\t}\n\tset alpha(val) {\n\t\tthis.fragment.alpha = val;\n\t}\n\n\tget shadingAlpha() {\n\t\treturn this.fragment.shadingAlpha;\n\t}\n\tset shadingAlpha(val) {\n\t\tthis.fragment.shadingAlpha = val;\n\t}\n\n\tget shadingBlend() {\n\t\treturn this.fragment.shadingBlend;\n\t}\n\tset shadingBlend(val) {\n\t\tthis.fragment.shadingBlend = val;\n\t}\n\n\tget position() {\n\t\treturn this.fragment.position;\n\t}\n\tset position(val) {\n\t\tthis.fragment.position = val;\n\t}\n\n\tconstructor(\n\t\tnode: BasicNode = new BasicNode(),\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(node, node, parameters);\n\t\tthis.type = 'BasicNodeMaterial';\n\n\t\t// It's set in the super() constructor,\n\t\t// we explicitly set it here since the type is not inferred\n\t\tthis.fragment = node;\n\t}\n}\n", "import { BasicNode } from './nodes/materials/nodes/BasicNode';\nimport { BasicNodeMaterial } from './nodes/materials/BasicNodeMaterial';\nimport type { Material } from '.';\nimport { LayerStack } from './layers';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Material as TMaterial } from 'three';\nimport type { MeshBasicMaterial } from 'three';\nimport type { AssetLibrary } from './AssetLibrary';\nimport { ColorNode, FloatNode, NodeMaterialParameters } from './nodes/Nodes';\n\nexport class BasicMaterial extends BasicNodeMaterial {\n\tconstructor(\n\t\tparameters?: NodeMaterialParameters,\n\t\tnode?: BasicNode,\n\t\tlayerStack?: LayerStack\n\t) {\n\t\tsuper(node, parameters);\n\n\t\tthis.userData.type = 'BasicMaterial';\n\t\tthis.userData.category = 'Basic';\n\t\tthis.userData.layers = layerStack ?? this._getLayerStack(parameters?.map);\n\t}\n\n\tget layersList(): LayerStack {\n\t\treturn this.userData.layers as LayerStack;\n\t}\n\n\tset layersList(list: LayerStack) {\n\t\tthis.userData.layers = list;\n\t}\n\n\tequals(material: Material) {\n\t\treturn (\n\t\t\tthis.userData.type === material.userData.type &&\n\t\t\t(this.userData.layers as LayerStack).uuid ==\n\t\t\t\t(material.userData.layers as LayerStack).uuid\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tif (\n\t\t\tsource.userData.layers !== undefined &&\n\t\t\tsource.userData.layers instanceof LayerStack\n\t\t) {\n\t\t\t// Save original layerstack and core ode\n\t\t\tconst sourceLayers = source.userData.layers;\n\t\t\tconst sourceFragment = source.fragment;\n\n\t\t\t// Copy all things\n\t\t\tsuper.copy(source);\n\n\t\t\t// Clone the core node\n\t\t\tconst node = sourceFragment.clone();\n\t\t\tthis.fragment = node;\n\t\t\tthis.vertex = node;\n\n\t\t\t// Clone the layerstack\n\t\t\tconst layers = sourceLayers.clone(this);\n\t\t\tthis.userData.layers = layers;\n\t\t} else {\n\t\t\tsuper.copy(source);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// TODO it is not actually from JSON\n\tstatic fromJSON(\n\t\tsource: TMaterial,\n\t\tdata: SerializedMaterial,\n\t\tassets: AssetLibrary\n\t): BasicMaterial {\n\t\tconst node = assets.getNode(data.vertex) as BasicNode;\n\t\tconst material = new BasicMaterial(undefined, node);\n\t\tmaterial.fromJSON(data, assets);\n\n\t\treturn material;\n\t}\n\n\tstatic fromMaterial(material: MeshBasicMaterial) {\n\t\tconst phong = new BasicMaterial(material.map ? { map: material.map } : {});\n\t\tconst node = phong.fragment;\n\n\t\t(node.color as ColorNode).value.copy(material.color);\n\t\t(node.alpha as FloatNode).value = material.opacity;\n\n\t\treturn phong;\n\t}\n\n\tdispose() {\n\t\tsuper.dispose();\n\t}\n}\n", "import { UniformsLib, UniformsUtils } from 'three';\n\nimport { NodeBuilder } from '../../core/NodeBuilder';\nimport { Node } from '../../core/Node';\nimport { ColorNode } from '../../inputs/ColorNode';\nimport { FloatNode } from '../../inputs/FloatNode';\nimport { Vector3Node } from '../../inputs/Vector3Node';\nimport { ExpressionNode } from '../../core/ExpressionNode';\nimport { IntNode } from '../../inputs/IntNode';\nimport { BlendNode } from '../../custom/BlendNode';\nimport { OperatorNode } from '../../math/OperatorNode';\nimport { colorDefault } from 'common/src/constants';\n\nexport class PhongNode extends Node {\n\tcolor: ColorNode | BlendNode;\n\tspecular: ColorNode;\n\tshininess: FloatNode;\n\tshadingAlpha: FloatNode;\n\tshadingBlend: IntNode;\n\tafterColor?: ExpressionNode | BlendNode;\n\talpha?: FloatNode;\n\tposition?: Vector3Node | OperatorNode;\n\tnodeType: string = 'Phong';\n\n\tconstructor() {\n\t\tsuper('phong');\n\n\t\tthis.color = new ColorNode(colorDefault);\n\t\tthis.specular = new ColorNode(0x111111);\n\t\tthis.shininess = new FloatNode(30);\n\n\t\tthis.shadingAlpha = new FloatNode(1);\n\t\tthis.shadingBlend = new IntNode(0);\n\t}\n\n\tbuild(builder: NodeBuilder): string {\n\t\tlet code;\n\n\t\tbuilder.define('PHONG');\n\n\t\tbuilder.requires.lights = true;\n\t\tbuilder.extensions.derivatives = true;\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tconst position = this.position\n\t\t\t\t? this.position.analyzeAndFlow(builder, 'v3', { cache: 'position' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.mergeUniform(\n\t\t\t\tUniformsUtils.merge([UniformsLib.fog, UniformsLib.lights])\n\t\t\t);\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\n\t\t\t\t\t'#include <fog_pars_vertex>',\n\t\t\t\t\t'#include <normal_pars_vertex>',\n\t\t\t\t\t'#include <shadowmap_pars_vertex>',\n\t\t\t\t\t'#include <clipping_planes_pars_vertex>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <beginnormal_vertex>',\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <defaultnormal_vertex>\n\t\t\t\t#endif\n\n\t\t\t\tvec3 displaced_position = position;\n\t\t\t\tvec3 displaced_normal = normal;\n\n\t\t\t\t#ifdef USE_LAYER_DISPLACE\n\t\t\t\t\tvec3 transformed;\n\t\t\t\t\tvec3 transformedNormal;\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t\t'#include <normal_vertex>',\n\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t];\n\n\t\t\tif (position) {\n\t\t\t\toutput.push(\n\t\t\t\t\tposition.code,\n\t\t\t\t\tposition.result ? 'displaced_position = ' + position.result + ';' : ''\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'transformed = displaced_position;',\n\t\t\t\t'transformedNormal = normalMatrix * displaced_normal;',\n\n\t\t\t\t'#ifndef FLAT_SHADED',\n\t\t\t\t' vNormal = transformedNormal;',\n\t\t\t\t'#endif'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'\t#include <project_vertex>',\n\t\t\t\t'\t#include <clipping_planes_vertex>',\n\n\t\t\t\t'\tvViewPosition = - mvPosition.xyz;',\n\n\t\t\t\t'\t#include <worldpos_vertex>',\n\t\t\t\t'\t#include <shadowmap_vertex>',\n\t\t\t\t'\t#include <fog_vertex>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t} else {\n\t\t\tif (this.color === undefined) this.color = new ColorNode(colorDefault);\n\t\t\tthis.color.analyze(builder, { slot: 'color' });\n\n\t\t\tthis.specular.analyze(builder);\n\t\t\tthis.shininess.analyze(builder);\n\n\t\t\tthis.shadingAlpha.analyze(builder);\n\t\t\tthis.shadingBlend.analyze(builder);\n\n\t\t\tif (this.afterColor)\n\t\t\t\tthis.afterColor.analyze(builder, { slot: 'afterColor' });\n\n\t\t\tif (this.alpha) this.alpha.analyze(builder);\n\n\t\t\t// build code\n\n\t\t\tconst color = this.color.flow(builder, 'c', { slot: 'color' });\n\t\t\tconst specular = this.specular.flow(builder, 'c');\n\t\t\tconst shininess = this.shininess.flow(builder, 'f');\n\n\t\t\tconst shadingAlpha = this.shadingAlpha.flow(builder, 'f');\n\t\t\tconst shadingBlend = this.shadingBlend.flow(builder, 'i');\n\n\t\t\tconst afterColor = this.afterColor\n\t\t\t\t? this.afterColor.flow(builder, 'c', { slot: 'afterColor' })\n\t\t\t\t: undefined;\n\n\t\t\tconst alpha = this.alpha ? this.alpha.flow(builder, 'f') : undefined;\n\n\t\t\tbuilder.requires.transparent = alpha !== undefined;\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'uniform vec3 emissive;', // TODO add as node uniform\n\t\t\t\t\t'#include <normal_pars_fragment>',\n\t\t\t\t\t'#include <fog_pars_fragment>',\n\t\t\t\t\t'#include <bsdfs>',\n\t\t\t\t\t'#include <lights_pars_begin>',\n\t\t\t\t\t'#include <lights_phong_pars_fragment>',\n\t\t\t\t\t'#include <shadowmap_pars_fragment>',\n\t\t\t\t\t'#include <dithering_pars_fragment>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t// prevent undeclared normal\n\t\t\t\t'#include <normal_fragment_begin>',\n\n\t\t\t\t`\n\t\t\t\t// NOTE: gl_FrontFacing alternative using face normal estimation.\n\t\t\t\tvec3 viewdx = dFdx(vViewPosition);\n\t\t\t\tvec3 viewdy = dFdy(vViewPosition);\n\t\t\t\tvec3 faceNormal = normalize(cross(viewdx,viewdy));\n\t\t\t\tif (dot(normal, faceNormal) < 0.0) {\n\t\t\t\t\tnormal *= -1.0;\n\t\t\t\t}\n\t\t\t\t`,\n\n\t\t\t\t// prevent undeclared material\n\t\t\t\t'\tBlinnPhongMaterial material;',\n\t\t\t];\n\n\t\t\toutput.push(\n\t\t\t\tcolor.code,\n\t\t\t\t'\tvec3 diffuseColor = ' + color.result + ';',\n\t\t\t\t'\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );',\n\t\t\t\t'\tvec3 totalEmissiveRadiance = emissive;',\n\n\t\t\t\tspecular.code,\n\t\t\t\t'\tvec3 specular = ' + specular.result + ';',\n\n\t\t\t\tshininess.code,\n\t\t\t\t'\tfloat shininess = max( 0.0001, ' + shininess.result + ' );',\n\n\t\t\t\t'\tfloat specularStrength = 1.0;'\n\t\t\t);\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\talpha.code,\n\t\t\t\t\t'#ifdef ALPHATEST',\n\n\t\t\t\t\t'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',\n\n\t\t\t\t\t'#endif'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// optimization for now\n\n\t\t\toutput.push('material.diffuseColor = diffuseColor;');\n\n\t\t\toutput.push(\n\t\t\t\t// accumulation\n\t\t\t\t'material.specularColor = specular;',\n\t\t\t\t'material.specularShininess = shininess;',\n\t\t\t\t'material.specularStrength = specularStrength;',\n\n\t\t\t\t'#include <lights_fragment_begin>',\n\t\t\t\t'#include <lights_fragment_end>'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t`\n\t\t\t\tif (outgoingLight != diffuseColor) {\n\t\t\t\t\tfloat lightAccu = clamp( length( reflectedLight.directSpecular + reflectedLight.indirectSpecular ), 0.0, 1.0 );\n\t\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * ${shadingAlpha.result} * lightAccu;\n\t\t\t\t\toutgoingLight = spe_blend( diffuseColor, outgoingLight, ${shadingAlpha.result}, ${shadingBlend.result} );\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\n\t\t\tif (afterColor) {\n\t\t\t\toutput.push(\n\t\t\t\t\tafterColor.code,\n\t\t\t\t\t`outgoingLight = spe_blend(outgoingLight, ${afterColor.result}, 1.0, SPE_BLENDING_NORMAL);`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\t`gl_FragColor = vec4( outgoingLight, accumAlpha * ${alpha.result} );`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push('gl_FragColor = vec4( outgoingLight, 1.0 );');\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'#include <encodings_fragment>',\n\t\t\t\t'#include <fog_fragment>',\n\t\t\t\t'#include <dithering_fragment>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tif (source.color) this.color = source.color.clone();\n\t\tthis.specular = source.specular.clone();\n\t\tthis.shininess = source.shininess.clone();\n\t\tif (source.position) this.position = source.position.clone();\n\t\tif (source.afterColor) this.afterColor = source.afterColor.clone();\n\t\tif (source.alpha) this.alpha = source.alpha.clone();\n\t\tif (source.shadingAlpha) this.shadingAlpha = source.shadingAlpha.clone();\n\t\tif (source.shadingBlend) this.shadingBlend = source.shadingBlend.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { NodeMaterial, NodeMaterialParameters } from './NodeMaterial';\nimport { PhongNode } from './nodes/PhongNode';\n\nexport class PhongNodeMaterial extends NodeMaterial {\n\tfragment: PhongNode;\n\n\tget color() {\n\t\treturn this.fragment.color;\n\t}\n\tset color(val) {\n\t\tthis.fragment.color = val;\n\t}\n\n\tget afterColor() {\n\t\treturn this.fragment.afterColor;\n\t}\n\tset afterColor(val) {\n\t\tthis.fragment.afterColor = val;\n\t}\n\n\tget alpha() {\n\t\treturn this.fragment.alpha;\n\t}\n\tset alpha(val) {\n\t\tthis.fragment.alpha = val;\n\t}\n\n\tget shadingAlpha() {\n\t\treturn this.fragment.shadingAlpha;\n\t}\n\tset shadingAlpha(val) {\n\t\tthis.fragment.shadingAlpha = val;\n\t}\n\n\tget shadingBlend() {\n\t\treturn this.fragment.shadingBlend;\n\t}\n\tset shadingBlend(val) {\n\t\tthis.fragment.shadingBlend = val;\n\t}\n\n\tget position() {\n\t\treturn this.fragment.position;\n\t}\n\tset position(val) {\n\t\tthis.fragment.position = val;\n\t}\n\n\tget specular() {\n\t\treturn this.fragment.specular;\n\t}\n\tset specular(val) {\n\t\tthis.fragment.specular = val;\n\t}\n\n\tget shininess() {\n\t\treturn this.fragment.shininess;\n\t}\n\tset shininess(val) {\n\t\tthis.fragment.shininess = val;\n\t}\n\n\tconstructor(\n\t\tnode: PhongNode = new PhongNode(),\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(node, node, parameters);\n\t\tthis.type = 'PhongNodeMaterial';\n\n\t\t// It's set in the super() constructor,\n\t\t// we explicitly set it here since the type is not inferred\n\t\tthis.fragment = node;\n\t}\n}\n", "import { PhongNode } from './nodes/materials/nodes/PhongNode';\nimport { PhongNodeMaterial } from './nodes/materials/PhongNodeMaterial';\nimport type { Material } from './';\nimport { LayerStack } from './layers';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Material as TMaterial } from 'three';\nimport type { MeshPhongMaterial } from 'three';\nimport type { AssetLibrary } from './AssetLibrary';\nimport { ColorNode, FloatNode, NodeMaterialParameters } from './nodes/Nodes';\n\nexport class PhongMaterial extends PhongNodeMaterial {\n\tconstructor(\n\t\tparameters?: NodeMaterialParameters,\n\t\tnode?: PhongNode,\n\t\tlayerStack?: LayerStack\n\t) {\n\t\tsuper(node, parameters);\n\n\t\tthis.userData.type = 'PhongMaterial';\n\t\tthis.userData.category = 'Phong';\n\t\tthis.userData.layers = layerStack ?? this._getLayerStack(parameters?.map);\n\t}\n\n\tget layersList(): LayerStack {\n\t\treturn this.userData.layers as LayerStack;\n\t}\n\n\tset layersList(list: LayerStack) {\n\t\tthis.userData.layers = list;\n\t}\n\n\tequals(material: Material) {\n\t\treturn (\n\t\t\tthis.userData.type === material.userData.type &&\n\t\t\t(this.userData.layers as LayerStack).uuid ==\n\t\t\t\t(material.userData.layers as LayerStack).uuid\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tif (\n\t\t\tsource.userData.layers !== undefined &&\n\t\t\tsource.userData.layers instanceof LayerStack\n\t\t) {\n\t\t\t// Save original layerstack and core ode\n\t\t\tconst sourceLayers = source.userData.layers;\n\t\t\tconst sourceFragment = source.fragment;\n\n\t\t\t// Copy all things\n\t\t\tsuper.copy(source);\n\n\t\t\t// Clone the core node\n\t\t\tconst node = sourceFragment.clone();\n\t\t\tthis.fragment = node;\n\t\t\tthis.vertex = node;\n\n\t\t\t// Clone the layerstack\n\t\t\tconst layers = sourceLayers.clone(this);\n\t\t\tthis.userData.layers = layers;\n\n\t\t\t// Restore from source the values that were overriden by cloning process\n\t\t\tnode.shadingAlpha.value = sourceFragment.shadingAlpha.value as number;\n\t\t\tnode.shadingBlend.value = sourceFragment.shadingBlend.value as number;\n\t\t} else {\n\t\t\tsuper.copy(source);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// TODO it is not actually from JSON\n\tstatic fromJSON(\n\t\tsource: TMaterial,\n\t\tdata: SerializedMaterial,\n\t\tassets: AssetLibrary\n\t): PhongMaterial {\n\t\tconst node = assets.getNode(data.vertex) as PhongNode;\n\t\tconst material = new PhongMaterial(undefined, node);\n\t\tmaterial.fromJSON(data, assets);\n\n\t\treturn material;\n\t}\n\n\tstatic fromMaterial(material: MeshPhongMaterial) {\n\t\tconst phong = new PhongMaterial(material.map ? { map: material.map } : {});\n\t\tconst node = phong.fragment;\n\n\t\t(node.color as ColorNode).value.copy(material.color);\n\t\t(node.alpha as FloatNode).value = material.opacity;\n\n\t\treturn phong;\n\t}\n\n\tdispose() {\n\t\tsuper.dispose();\n\t}\n}\n", "import { UniformsLib, UniformsUtils } from 'three';\n\nimport { NodeBuilder } from '../../core/NodeBuilder';\nimport { Node } from '../../core/Node';\nimport { ColorNode } from '../../inputs/ColorNode';\nimport { FloatNode } from '../../inputs/FloatNode';\nimport { IntNode } from '../../inputs/IntNode';\nimport { BlendNode } from '../../custom/BlendNode';\nimport { OperatorNode } from '../../math/OperatorNode';\nimport { ExpressionNode } from '../../core/ExpressionNode';\nimport { Vector3Node } from '../../inputs/Vector3Node';\nimport { colorDefault } from 'common/src/constants';\n\nexport class LambertNode extends Node {\n\tcolor?: ColorNode | BlendNode;\n\tshadingAlpha: FloatNode;\n\tshadingBlend: IntNode;\n\tafterColor?: ExpressionNode | BlendNode;\n\temissive: ColorNode;\n\temissiveIntensity: FloatNode;\n\talpha?: FloatNode;\n\tposition?: Vector3Node | OperatorNode;\n\tnodeType: string = 'Lambert';\n\n\tconstructor() {\n\t\tsuper('lambert');\n\n\t\tthis.color = new ColorNode(colorDefault);\n\t\tthis.emissive = new ColorNode(0x000000);\n\t\tthis.emissiveIntensity = new FloatNode(1);\n\n\t\tthis.shadingAlpha = new FloatNode(1);\n\t\tthis.shadingBlend = new IntNode(0);\n\t}\n\n\tbuild(builder: NodeBuilder): string {\n\t\tlet code;\n\n\t\tbuilder.define('LAMBERT');\n\n\t\tbuilder.requires.lights = true;\n\t\tbuilder.extensions.derivatives = true;\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tconst position = this.position\n\t\t\t\t? this.position.analyzeAndFlow(builder, 'v3', { cache: 'position' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.mergeUniform(\n\t\t\t\tUniformsUtils.merge([UniformsLib.fog, UniformsLib.lights])\n\t\t\t);\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\t\t\t\t\t'varying vec3 vLightFront;',\n\t\t\t\t\t'varying vec3 vIndirectFront;',\n\t\t\t\t\t'#ifndef DOUBLE_SIDED',\n\t\t\t\t\t' #define DOUBLE_SIDED',\n\t\t\t\t\t'#endif',\n\n\t\t\t\t\t'#ifdef DOUBLE_SIDED',\n\t\t\t\t\t'\tvarying vec3 vLightBack;',\n\t\t\t\t\t'\tvarying vec3 vIndirectBack;',\n\t\t\t\t\t'#endif',\n\n\t\t\t\t\t'#include <bsdfs>',\n\t\t\t\t\t'#include <lights_pars_begin>',\n\t\t\t\t\t'#include <color_pars_vertex>',\n\t\t\t\t\t'#include <fog_pars_vertex>',\n\t\t\t\t\t'#include <normal_pars_vertex>',\n\t\t\t\t\t'#include <shadowmap_pars_vertex>',\n\t\t\t\t\t'#include <clipping_planes_pars_vertex>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <beginnormal_vertex>',\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <defaultnormal_vertex>\n\t\t\t\t#endif\n\n\t\t\t\tvec3 displaced_position = position;\n\t\t\t\tvec3 displaced_normal = normal;\n\n\t\t\t\t#ifdef USE_LAYER_DISPLACE\n\t\t\t\t\tvec3 transformed;\n\t\t\t\t\tvec3 transformedNormal;\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t\t'#include <normal_vertex>',\n\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t];\n\n\t\t\tif (position) {\n\t\t\t\toutput.push(\n\t\t\t\t\tposition.code,\n\t\t\t\t\tposition.result ? 'displaced_position = ' + position.result + ';' : ''\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'transformed = displaced_position;',\n\t\t\t\t'transformedNormal = normalMatrix * displaced_normal;',\n\n\t\t\t\t'#ifndef FLAT_SHADED',\n\t\t\t\t' vNormal = transformedNormal;',\n\t\t\t\t'#endif'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'\t#include <project_vertex>',\n\t\t\t\t'\t#include <clipping_planes_vertex>',\n\n\t\t\t\t'\tvViewPosition = - mvPosition.xyz;',\n\n\t\t\t\t'\t#include <worldpos_vertex>',\n\n\t\t\t\t`\n\t\t\t\t\tvec3 diffuse = vec3( 1.0 );\n\t\t\t\t\tGeometricContext geometry;\n\t\t\t\t\tgeometry.position = mvPosition.xyz;\n\t\t\t\t\tgeometry.normal = normalize( transformedNormal );\n\t\t\t\t\tgeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\n\t\t\t\t\tGeometricContext backGeometry;\n\t\t\t\t\tbackGeometry.position = geometry.position;\n\t\t\t\t\tbackGeometry.normal = -geometry.normal;\n\t\t\t\t\tbackGeometry.viewDir = geometry.viewDir;\n\t\t\t\t\tvLightFront = vec3( 0.0 );\n\t\t\t\t\tvIndirectFront = vec3( 0.0 );\n\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\tvLightBack = vec3( 0.0 );\n\t\t\t\t\t\tvIndirectBack = vec3( 0.0 );\n\t\t\t\t\t#endif\n\t\t\t\t\tIncidentLight directLight;\n\t\t\t\t\tfloat dotNL;\n\t\t\t\t\tvec3 directLightColor_Diffuse;\n\t\t\t\t\tvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\n\t\t\t\t\tvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\n\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\t\t\t\t\t\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\n\t\t\t\t\t#endif\n\t\t\t\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\t\t\t\t#pragma unroll_loop_start\n\t\t\t\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\t\t\t\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\t\t\t\t\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\t\t\t\t\t\tdirectLightColor_Diffuse = directLight.color;\n\t\t\t\t\t\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t\t#pragma unroll_loop_end\n\t\t\t\t\t#endif\n\t\t\t\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\t\t\t\t#pragma unroll_loop_start\n\t\t\t\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\t\t\t\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\t\t\t\t\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\t\t\t\t\t\tdirectLightColor_Diffuse = directLight.color;\n\t\t\t\t\t\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t\t#pragma unroll_loop_end\n\t\t\t\t\t#endif\n\t\t\t\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\t\t\t\t#pragma unroll_loop_start\n\t\t\t\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\t\t\t\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\t\t\t\t\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\t\t\t\t\t\tdirectLightColor_Diffuse = directLight.color;\n\t\t\t\t\t\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t\t\t\t\t\t#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t\t#pragma unroll_loop_end\n\t\t\t\t\t#endif\n\t\t\t\t\t#if NUM_HEMI_LIGHTS > 0\n\t\t\t\t\t\t#pragma unroll_loop_start\n\t\t\t\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\t\t\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t\t\t\t\t\t#ifdef DOUBLE_SIDED\n\t\t\t\t\t\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t\t\t\t\t\t#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t\t#pragma unroll_loop_end\n\t\t\t\t\t#endif\n\t\t\t\t`,\n\n\t\t\t\t'\t#include <shadowmap_vertex>',\n\t\t\t\t'\t#include <fog_vertex>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t} else {\n\t\t\tif (this.color === undefined) this.color = new ColorNode(colorDefault);\n\t\t\tthis.color.analyze(builder, { slot: 'color' });\n\n\t\t\tthis.shadingAlpha.analyze(builder);\n\t\t\tthis.shadingBlend.analyze(builder);\n\n\t\t\tif (this.afterColor)\n\t\t\t\tthis.afterColor.analyze(builder, { slot: 'afterColor' });\n\n\t\t\tif (this.alpha) this.alpha.analyze(builder);\n\n\t\t\t// build code\n\n\t\t\tconst color = this.color.flow(builder, 'c', { slot: 'color' });\n\n\t\t\tconst emissive = this.emissive.flow(builder, 'c', { slot: 'emissive' });\n\t\t\tconst emissiveIntensity = this.emissiveIntensity.flow(builder, 'f', {\n\t\t\t\tslot: 'emissive',\n\t\t\t});\n\n\t\t\tconst shadingAlpha = this.shadingAlpha.flow(builder, 'f');\n\t\t\tconst shadingBlend = this.shadingBlend.flow(builder, 'i');\n\n\t\t\tconst afterColor = this.afterColor\n\t\t\t\t? this.afterColor.flow(builder, 'c', { slot: 'afterColor' })\n\t\t\t\t: undefined;\n\n\t\t\tconst alpha = this.alpha ? this.alpha.flow(builder, 'f') : undefined;\n\n\t\t\tbuilder.requires.transparent = alpha !== undefined;\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\t\t\t\t\t'varying vec3 vLightFront;',\n\t\t\t\t\t'varying vec3 vIndirectFront;',\n\n\t\t\t\t\t'#ifndef DOUBLE_SIDED',\n\t\t\t\t\t' #define DOUBLE_SIDED',\n\t\t\t\t\t'#endif',\n\n\t\t\t\t\t'#include <normal_pars_fragment>',\n\n\t\t\t\t\t'#ifdef DOUBLE_SIDED',\n\t\t\t\t\t'\tvarying vec3 vLightBack;',\n\t\t\t\t\t'\tvarying vec3 vIndirectBack;',\n\t\t\t\t\t'#endif',\n\n\t\t\t\t\t'#include <bsdfs>',\n\t\t\t\t\t'#include <lights_pars_begin>',\n\t\t\t\t\t'#include <fog_pars_fragment>',\n\t\t\t\t\t'#include <shadowmap_pars_fragment>',\n\t\t\t\t\t'#include <shadowmask_pars_fragment>',\n\t\t\t\t\t'#include <clipping_planes_pars_fragment>',\n\t\t\t\t\t'#include <dithering_pars_fragment>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t// Necessary to handle Normal layer\n\t\t\t\t'#include <normal_fragment_begin>',\n\n\t\t\t\t`\n\t\t\t\t// NOTE: gl_FrontFacing alternative using face normal estimation.\n\t\t\t\tvec3 viewdx = dFdx(vViewPosition);\n\t\t\t\tvec3 viewdy = dFdy(vViewPosition);\n\t\t\t\tvec3 faceNormal = normalize(cross(viewdx, viewdy));\n\t\t\t\tbool isFrontFacing = (dot(normal, faceNormal) >= 0.0);\n\t\t\t\t`,\n\n\t\t\t\t'#include <clipping_planes_fragment>',\n\t\t\t];\n\n\t\t\toutput.push(\n\t\t\t\tcolor.code,\n\t\t\t\t'vec3 diffuseColor = ' + color.result + ';',\n\t\t\t\t'ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );'\n\t\t\t);\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\talpha.code,\n\t\t\t\t\t'#ifdef ALPHATEST',\n\n\t\t\t\t\t'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',\n\n\t\t\t\t\t'#endif'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'#ifdef DOUBLE_SIDED',\n\t\t\t\t'\treflectedLight.indirectDiffuse += ( isFrontFacing ) ? vIndirectFront : vIndirectBack;',\n\t\t\t\t'#else',\n\t\t\t\t'\treflectedLight.indirectDiffuse += vIndirectFront;',\n\t\t\t\t'#endif',\n\t\t\t\t'#include <lightmap_fragment>',\n\t\t\t\t'reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );',\n\t\t\t\t'#ifdef DOUBLE_SIDED',\n\t\t\t\t'\treflectedLight.directDiffuse = ( isFrontFacing ) ? vLightFront : vLightBack;',\n\t\t\t\t'#else',\n\t\t\t\t'\treflectedLight.directDiffuse = vLightFront;',\n\t\t\t\t'#endif',\n\t\t\t\t'reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();'\n\t\t\t);\n\n\t\t\tif (emissive) {\n\t\t\t\toutput.push(\n\t\t\t\t\temissive.code,\n\t\t\t\t\t'reflectedLight.directDiffuse += ' +\n\t\t\t\t\t\temissive.result +\n\t\t\t\t\t\t' * ' +\n\t\t\t\t\t\temissiveIntensity.result +\n\t\t\t\t\t\t';'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t`\n\t\t\t\tif (outgoingLight != diffuseColor) {\n\t\t\t\t\tfloat lightAccu = clamp( length( reflectedLight.directSpecular + reflectedLight.indirectSpecular ), 0.0, 1.0 );\n\t\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * ${shadingAlpha.result} * lightAccu;\n\t\t\t\t\toutgoingLight = spe_blend( diffuseColor, outgoingLight, ${shadingAlpha.result}, ${shadingBlend.result} );\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\n\t\t\tif (afterColor) {\n\t\t\t\toutput.push(\n\t\t\t\t\tafterColor.code,\n\t\t\t\t\t`outgoingLight = spe_blend(outgoingLight, ${afterColor.result}, 1.0, SPE_BLENDING_NORMAL);`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\t`gl_FragColor = vec4( outgoingLight, accumAlpha * ${alpha.result} );`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push('gl_FragColor = vec4( outgoingLight, 1.0 );');\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'#include <encodings_fragment>',\n\t\t\t\t'#include <fog_fragment>',\n\t\t\t\t'#include <dithering_fragment>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tthis.emissiveIntensity = source.emissiveIntensity.clone();\n\t\tif (source.color) this.color = source.color.clone();\n\t\tif (source.position) this.position = source.position.clone();\n\t\tif (source.afterColor) this.afterColor = source.afterColor.clone();\n\t\tif (source.alpha) this.alpha = source.alpha.clone();\n\t\tif (source.shadingAlpha) this.shadingAlpha = source.shadingAlpha.clone();\n\t\tif (source.shadingBlend) this.shadingBlend = source.shadingBlend.clone();\n\t\tif (source.emissive) this.emissive = source.emissive.clone();\n\t\treturn this;\n\t}\n}\n", "import { NodeMaterial, NodeMaterialParameters } from './NodeMaterial';\nimport { LambertNode } from './nodes/LambertNode';\n\nexport class LambertNodeMaterial extends NodeMaterial {\n\tfragment: LambertNode;\n\n\tget color() {\n\t\treturn this.fragment.color;\n\t}\n\tset color(val) {\n\t\tthis.fragment.color = val;\n\t}\n\n\tget afterColor() {\n\t\treturn this.fragment.afterColor;\n\t}\n\tset afterColor(val) {\n\t\tthis.fragment.afterColor = val;\n\t}\n\n\tget alpha() {\n\t\treturn this.fragment.alpha;\n\t}\n\tset alpha(val) {\n\t\tthis.fragment.alpha = val;\n\t}\n\n\tget shadingAlpha() {\n\t\treturn this.fragment.shadingAlpha;\n\t}\n\tset shadingAlpha(val) {\n\t\tthis.fragment.shadingAlpha = val;\n\t}\n\n\tget shadingBlend() {\n\t\treturn this.fragment.shadingBlend;\n\t}\n\tset shadingBlend(val) {\n\t\tthis.fragment.shadingBlend = val;\n\t}\n\n\tget position() {\n\t\treturn this.fragment.position;\n\t}\n\tset position(val) {\n\t\tthis.fragment.position = val;\n\t}\n\n\tget emissive() {\n\t\treturn this.fragment.emissive;\n\t}\n\tset emissive(val) {\n\t\tthis.fragment.emissive = val;\n\t}\n\n\tget emissiveIntensity() {\n\t\treturn this.fragment.emissiveIntensity;\n\t}\n\tset emissiveIntensity(val) {\n\t\tthis.fragment.emissiveIntensity = val;\n\t}\n\n\tconstructor(\n\t\tnode: LambertNode = new LambertNode(),\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(node, node, parameters);\n\t\tthis.type = 'LambertNodeMaterial';\n\n\t\t// It's set in the super() constructor,\n\t\t// we explicitly set it here since the type is not inferred\n\t\tthis.fragment = node;\n\t}\n}\n", "import { LambertNode } from './nodes/materials/nodes/LambertNode';\nimport { LambertNodeMaterial } from './nodes/materials/LambertNodeMaterial';\nimport type { Material } from './';\nimport { LayerStack } from './layers';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Material as TMaterial } from 'three';\nimport type { AssetLibrary } from './AssetLibrary';\nimport { NodeMaterialParameters } from './nodes/Nodes';\n\nexport class LambertMaterial extends LambertNodeMaterial {\n\tconstructor(\n\t\tparameters?: NodeMaterialParameters,\n\t\tnode?: LambertNode,\n\t\tlayerStack?: LayerStack\n\t) {\n\t\tsuper(node, parameters);\n\n\t\tthis.userData.type = 'LambertMaterial';\n\t\tthis.userData.category = 'Lambert';\n\t\tthis.userData.layers = layerStack ?? this._getLayerStack(parameters?.map);\n\t}\n\n\tget layersList(): LayerStack {\n\t\treturn this.userData.layers as LayerStack;\n\t}\n\n\tset layersList(list: LayerStack) {\n\t\tthis.userData.layers = list;\n\t}\n\n\tequals(material: Material) {\n\t\treturn (\n\t\t\tthis.userData.type === material.userData.type &&\n\t\t\t(this.userData.layers as LayerStack).uuid ==\n\t\t\t\t(material.userData.layers as LayerStack).uuid\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tif (\n\t\t\tsource.userData.layers !== undefined &&\n\t\t\tsource.userData.layers instanceof LayerStack\n\t\t) {\n\t\t\t// Save original layerstack and core ode\n\t\t\tconst sourceLayers = source.userData.layers;\n\t\t\tconst sourceFragment = source.fragment;\n\n\t\t\t// Copy all things\n\t\t\tsuper.copy(source);\n\n\t\t\t// Clone the core node\n\t\t\tconst node = sourceFragment.clone();\n\t\t\tthis.fragment = node;\n\t\t\tthis.vertex = node;\n\n\t\t\t// Clone the layerstack\n\t\t\tconst layers = sourceLayers.clone(this);\n\t\t\tthis.userData.layers = layers;\n\n\t\t\t// Restore from source the values that were overriden by cloning process\n\t\t\tnode.shadingAlpha.value = sourceFragment.shadingAlpha.value as number;\n\t\t\tnode.shadingBlend.value = sourceFragment.shadingBlend.value as number;\n\t\t} else {\n\t\t\tsuper.copy(source);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// TODO it is not actually from JSON\n\tstatic fromJSON(\n\t\tsource: TMaterial,\n\t\tdata: SerializedMaterial,\n\t\tassets: AssetLibrary\n\t): LambertMaterial {\n\t\tconst node = assets.getNode(data.vertex) as LambertNode;\n\t\tconst material = new LambertMaterial(undefined, node);\n\t\tmaterial.fromJSON(data, assets);\n\n\t\treturn material;\n\t}\n\n\tdispose() {\n\t\tsuper.dispose();\n\t}\n}\n", "import { UniformsLib, UniformsUtils } from 'three';\n\nimport { NodeBuilder } from '../../core/NodeBuilder';\nimport { Node } from '../../core/Node';\nimport { ColorNode } from '../../inputs/ColorNode';\nimport { FloatNode } from '../../inputs/FloatNode';\nimport { Vector3Node } from '../../inputs/Vector3Node';\nimport { IntNode } from '../../inputs/IntNode';\nimport { ExpressionNode } from '../../core/ExpressionNode';\nimport { BlendNode } from '../../custom/BlendNode';\nimport { OperatorNode } from '../../math/OperatorNode';\nimport { colorDefault } from 'common/src/constants';\n\nexport class ToonNode extends Node {\n\tcolor?: ColorNode | BlendNode;\n\tspecular: ColorNode;\n\tshininess: FloatNode;\n\tshadingAlpha: FloatNode;\n\tshadingBlend: IntNode;\n\tafterColor?: ExpressionNode | BlendNode;\n\talpha?: FloatNode;\n\tposition?: Vector3Node | OperatorNode;\n\tnodeType: string = 'Toon';\n\n\tconstructor() {\n\t\tsuper('toon');\n\n\t\tthis.color = new ColorNode(colorDefault);\n\t\tthis.specular = new ColorNode(0x111111);\n\t\tthis.shininess = new FloatNode(30);\n\n\t\tthis.shadingAlpha = new FloatNode(1);\n\t\tthis.shadingBlend = new IntNode(0);\n\t}\n\n\tbuild(builder: NodeBuilder): string {\n\t\tlet code;\n\n\t\tbuilder.define('TOON');\n\n\t\tbuilder.requires.lights = true;\n\t\tbuilder.extensions.derivatives = true;\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tconst position = this.position\n\t\t\t\t? this.position.analyzeAndFlow(builder, 'v3', { cache: 'position' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.mergeUniform(\n\t\t\t\tUniformsUtils.merge([UniformsLib.fog, UniformsLib.lights])\n\t\t\t);\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\n\t\t\t\t\t'#include <fog_pars_vertex>',\n\t\t\t\t\t'#include <normal_pars_vertex>',\n\t\t\t\t\t'#include <shadowmap_pars_vertex>',\n\t\t\t\t\t'#include <clipping_planes_pars_vertex>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <beginnormal_vertex>',\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <defaultnormal_vertex>\n\t\t\t\t#endif\n\n\t\t\t\tvec3 displaced_position = position;\n\t\t\t\tvec3 displaced_normal = normal;\n\n\t\t\t\t#ifdef USE_LAYER_DISPLACE\n\t\t\t\t\tvec3 transformed;\n\t\t\t\t\tvec3 transformedNormal;\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t\t'#include <normal_vertex>',\n\n\t\t\t\t`\n\t\t\t\t#ifndef USE_LAYER_DISPLACE\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t];\n\n\t\t\tif (position) {\n\t\t\t\toutput.push(\n\t\t\t\t\tposition.code,\n\t\t\t\t\tposition.result ? 'displaced_position = ' + position.result + ';' : ''\n\t\t\t\t);\n\t\t\t}\n\t\t\toutput.push(\n\t\t\t\t'transformed = displaced_position;',\n\t\t\t\t'transformedNormal = normalMatrix * displaced_normal;',\n\n\t\t\t\t'#ifndef FLAT_SHADED',\n\t\t\t\t' vNormal = transformedNormal;',\n\t\t\t\t'#endif'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'\t#include <project_vertex>',\n\t\t\t\t'\t#include <fog_vertex>',\n\t\t\t\t'\t#include <clipping_planes_vertex>',\n\n\t\t\t\t'\tvViewPosition = - mvPosition.xyz;',\n\n\t\t\t\t'\t#include <worldpos_vertex>',\n\t\t\t\t'\t#include <shadowmap_vertex>',\n\t\t\t\t'\t#include <fog_vertex>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t} else {\n\t\t\tif (this.color === undefined) this.color = new ColorNode(colorDefault);\n\t\t\tthis.color.analyze(builder, { slot: 'color' });\n\n\t\t\tthis.specular.analyze(builder);\n\t\t\tthis.shininess.analyze(builder);\n\n\t\t\tthis.shadingAlpha.analyze(builder);\n\t\t\tthis.shadingBlend.analyze(builder);\n\n\t\t\tif (this.afterColor)\n\t\t\t\tthis.afterColor.analyze(builder, { slot: 'afterColor' });\n\n\t\t\tif (this.alpha) this.alpha.analyze(builder);\n\n\t\t\t// build code\n\n\t\t\tconst color = this.color.flow(builder, 'c', { slot: 'color' });\n\t\t\tconst specular = this.specular.flow(builder, 'c');\n\t\t\tconst shininess = this.shininess.flow(builder, 'f');\n\n\t\t\tconst shadingAlpha = this.shadingAlpha.flow(builder, 'f');\n\t\t\tconst shadingBlend = this.shadingBlend.flow(builder, 'i');\n\n\t\t\tconst afterColor = this.afterColor\n\t\t\t\t? this.afterColor.flow(builder, 'c', { slot: 'afterColor' })\n\t\t\t\t: undefined;\n\t\t\tconst alpha = this.alpha ? this.alpha.flow(builder, 'f') : undefined;\n\n\t\t\tbuilder.requires.transparent = alpha !== undefined;\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'#include <normal_pars_fragment>',\n\t\t\t\t\t'#include <gradientmap_pars_fragment>',\n\t\t\t\t\t'#include <fog_pars_fragment>',\n\t\t\t\t\t'#include <bsdfs>',\n\t\t\t\t\t'#include <lights_pars_begin>',\n\t\t\t\t\t'#include <dithering_pars_fragment>',\n\t\t\t\t\t// '#include <lights_toon_pars_fragment>',\n\n\t\t\t\t\t// NOTE(piero): we are not using Three's toon shader since they removed the parameters we need\n\t\t\t\t\t// https://github.com/mrdoob/three.js/commit/5ee79ac7f1a6980e0721791ac4fae642fff5ee43#diff-a97f2462391cfe58191d8ad3d05f29abe1dc2a3a38a3cbbe6c4b87186577d67a\n\t\t\t\t\t`\n\t\t\t\t\tvarying vec3 vViewPosition;\n\t\t\t\t\tstruct ToonMaterial {\n\t\t\t\t\t\tvec3\tdiffuseColor;\n\t\t\t\t\t\tvec3\tspecularColor;\n\t\t\t\t\t\tfloat\tspecularShininess;\n\t\t\t\t\t\tfloat\tspecularStrength;\n\t\t\t\t\t};\n\t\t\t\t\tvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\t\t\t\t\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t\t\t\n\t\t\t\t\t\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\t\t\t\t\t\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\n\t\t\t\t\t}\n\t\t\t\t\tvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\t\t\t\t\t\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\t\t\t\t\t}\n\t\t\t\t\t#define RE_Direct\t\t\t\tRE_Direct_Toon\n\t\t\t\t\t#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n\t\t\t\t\t#define Material_LightProbeLOD( material )\t(0)\n\t\t\t\t\t`,\n\n\t\t\t\t\t'#include <shadowmap_pars_fragment>',\n\t\t\t\t\t'#include <bumpmap_pars_fragment>',\n\t\t\t\t\t'#include <normalmap_pars_fragment>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t// prevent undeclared normal\n\t\t\t\t'#include <normal_fragment_begin>',\n\n\t\t\t\t`\n\t\t\t\t// NOTE: gl_FrontFacing alternative using face normal estimation.\n\t\t\t\tvec3 viewdx = dFdx(vViewPosition);\n\t\t\t\tvec3 viewdy = dFdy(vViewPosition);\n\t\t\t\tvec3 faceNormal = normalize(cross(viewdx,viewdy));\n\t\t\t\tif (dot(normal, faceNormal) < 0.0) {\n\t\t\t\t\tnormal *= -1.0;\n\t\t\t\t}\n\t\t\t\t`,\n\n\t\t\t\t// prevent undeclared material\n\t\t\t\t'\tToonMaterial material;',\n\t\t\t];\n\n\t\t\toutput.push(\n\t\t\t\tcolor.code,\n\t\t\t\t'\tvec3 diffuseColor = ' + color.result + ';',\n\t\t\t\t'\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );',\n\n\t\t\t\tspecular.code,\n\t\t\t\t'\tvec3 specular = ' + specular.result + ';',\n\n\t\t\t\tshininess.code,\n\t\t\t\t'\tfloat shininess = max( 0.0001, ' + shininess.result + ' );',\n\n\t\t\t\t'\tfloat specularStrength = 1.0;'\n\t\t\t);\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\talpha.code,\n\t\t\t\t\t'#ifdef ALPHATEST',\n\n\t\t\t\t\t'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',\n\n\t\t\t\t\t'#endif'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// optimization for now\n\n\t\t\toutput.push('material.diffuseColor = diffuseColor;');\n\n\t\t\toutput.push(\n\t\t\t\t'material.specularColor = specular;',\n\t\t\t\t'material.specularShininess = shininess;',\n\t\t\t\t'material.specularStrength = specularStrength;',\n\n\t\t\t\t'#include <lights_fragment_begin>',\n\t\t\t\t'#include <lights_fragment_end>'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular;'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t`\n\t\t\t\tif (outgoingLight != diffuseColor) {\n\t\t\t\t\tfloat lightAccu = clamp( length( reflectedLight.directSpecular + reflectedLight.indirectSpecular ), 0.0, 1.0 );\n\t\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * ${shadingAlpha.result} * lightAccu;\n\t\t\t\t\toutgoingLight = spe_blend( diffuseColor, outgoingLight, ${shadingAlpha.result}, ${shadingBlend.result} );\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\n\t\t\tif (afterColor) {\n\t\t\t\toutput.push(\n\t\t\t\t\tafterColor.code,\n\t\t\t\t\t`outgoingLight = spe_blend(outgoingLight, ${afterColor.result}, 1.0, SPE_BLENDING_NORMAL);`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\t`gl_FragColor = vec4( outgoingLight, accumAlpha * ${alpha.result} );`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push('gl_FragColor = vec4( outgoingLight, 1.0 );');\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'#include <encodings_fragment>',\n\t\t\t\t'#include <fog_fragment>',\n\t\t\t\t'#include <dithering_fragment>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tif (source.color) this.color = source.color.clone();\n\t\tthis.specular = source.specular.clone();\n\t\tthis.shininess = source.shininess.clone();\n\t\tif (source.position) this.position = source.position.clone();\n\t\tif (source.afterColor) this.afterColor = source.afterColor.clone();\n\t\tif (source.alpha) this.alpha = source.alpha.clone();\n\t\tif (source.shadingAlpha) this.shadingAlpha = source.shadingAlpha.clone();\n\t\tif (source.shadingBlend) this.shadingBlend = source.shadingBlend.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { NodeMaterial, NodeMaterialParameters } from './NodeMaterial';\nimport { ToonNode } from './nodes/ToonNode';\n\nexport class ToonNodeMaterial extends NodeMaterial {\n\tfragment: ToonNode;\n\n\tget color() {\n\t\treturn this.fragment.color;\n\t}\n\tset color(val) {\n\t\tthis.fragment.color = val;\n\t}\n\n\tget afterColor() {\n\t\treturn this.fragment.afterColor;\n\t}\n\tset afterColor(val) {\n\t\tthis.fragment.afterColor = val;\n\t}\n\n\tget alpha() {\n\t\treturn this.fragment.alpha;\n\t}\n\tset alpha(val) {\n\t\tthis.fragment.alpha = val;\n\t}\n\n\tget shadingAlpha() {\n\t\treturn this.fragment.shadingAlpha;\n\t}\n\tset shadingAlpha(val) {\n\t\tthis.fragment.shadingAlpha = val;\n\t}\n\n\tget shadingBlend() {\n\t\treturn this.fragment.shadingBlend;\n\t}\n\tset shadingBlend(val) {\n\t\tthis.fragment.shadingBlend = val;\n\t}\n\n\tget position() {\n\t\treturn this.fragment.position;\n\t}\n\tset position(val) {\n\t\tthis.fragment.position = val;\n\t}\n\n\tget specular() {\n\t\treturn this.fragment.specular;\n\t}\n\tset specular(val) {\n\t\tthis.fragment.specular = val;\n\t}\n\n\tget shininess() {\n\t\treturn this.fragment.shininess;\n\t}\n\tset shininess(val) {\n\t\tthis.fragment.shininess = val;\n\t}\n\n\tconstructor(\n\t\tnode: ToonNode = new ToonNode(),\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(node, node, parameters);\n\t\tthis.type = 'ToonNodeMaterial';\n\n\t\t// It's set in the super() constructor,\n\t\t// we explicitly set it here since the type is not inferred\n\t\tthis.fragment = node;\n\t}\n}\n", "import { ToonNode } from './nodes/materials/nodes/ToonNode';\nimport { ToonNodeMaterial } from './nodes/materials/ToonNodeMaterial';\nimport type { Material } from '.';\nimport { LayerStack } from './layers';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Material as TMaterial } from 'three';\nimport type { AssetLibrary } from './AssetLibrary';\nimport { NodeMaterialParameters } from './nodes/Nodes';\n\n// TODO(piero): implement ToonNodeMaterial\nexport class ToonMaterial extends ToonNodeMaterial {\n\tconstructor(\n\t\tparameters?: NodeMaterialParameters,\n\t\tnode?: ToonNode,\n\t\tlayerStack?: LayerStack\n\t) {\n\t\tsuper(node, parameters);\n\n\t\tthis.userData.type = 'ToonMaterial';\n\t\tthis.userData.category = 'Toon';\n\t\tthis.userData.layers = layerStack ?? this._getLayerStack(parameters?.map);\n\t}\n\n\tget layersList(): LayerStack {\n\t\treturn this.userData.layers as LayerStack;\n\t}\n\n\tset layersList(list: LayerStack) {\n\t\tthis.userData.layers = list;\n\t}\n\n\tequals(material: Material) {\n\t\treturn (\n\t\t\tthis.userData.type === material.userData.type &&\n\t\t\t(this.userData.layers as LayerStack).uuid ==\n\t\t\t\t(material.userData.layers as LayerStack).uuid\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tif (\n\t\t\tsource.userData.layers !== undefined &&\n\t\t\tsource.userData.layers instanceof LayerStack\n\t\t) {\n\t\t\t// Save original layerstack and core ode\n\t\t\tconst sourceLayers = source.userData.layers;\n\t\t\tconst sourceFragment = source.fragment;\n\n\t\t\t// Copy all things\n\t\t\tsuper.copy(source);\n\n\t\t\t// Clone the core node\n\t\t\tconst node = sourceFragment.clone();\n\t\t\tthis.fragment = node;\n\t\t\tthis.vertex = node;\n\n\t\t\t// Clone the layerstack\n\t\t\tconst layers = sourceLayers.clone(this);\n\t\t\tthis.userData.layers = layers;\n\n\t\t\t// Restore from source the values that were overriden by cloning process\n\t\t\tnode.shadingAlpha.value = sourceFragment.shadingAlpha.value as number;\n\t\t\tnode.shadingBlend.value = sourceFragment.shadingBlend.value as number;\n\t\t} else {\n\t\t\tsuper.copy(source);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// TODO it is not actually from JSON\n\tstatic fromJSON(\n\t\tsource: TMaterial,\n\t\tdata: SerializedMaterial,\n\t\tassets: AssetLibrary\n\t): ToonMaterial {\n\t\tconst node = assets.getNode(data.vertex) as ToonNode;\n\t\tconst material = new ToonMaterial(undefined, node);\n\t\tmaterial.fromJSON(data, assets);\n\n\t\treturn material;\n\t}\n\n\tdispose() {\n\t\tsuper.dispose();\n\t}\n}\n", "import { UniformsLib, UniformsUtils } from 'three';\n\nimport { NodeBuilder } from '../../core/NodeBuilder';\nimport { Node } from '../../core/Node';\n\nimport { ExpressionNode } from '../../core/ExpressionNode';\nimport { ColorNode } from '../../inputs/ColorNode';\nimport { FloatNode } from '../../inputs/FloatNode';\nimport { IntNode } from '../../inputs/IntNode';\nimport { Vector3Node } from '../../inputs/Vector3Node';\nimport { BlendNode } from '../../custom/BlendNode';\nimport { OperatorNode } from '../../math/OperatorNode';\n\nimport {\n\tMeta,\n\tSerializedStandardNode,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport type { AssetLibrary } from '../../../AssetLibrary';\nimport { colorDefault } from 'common/src/constants';\n\nexport class StandardNode extends Node {\n\tcolor?: ColorNode | BlendNode;\n\troughness: FloatNode;\n\tmetalness: FloatNode;\n\treflectivity: FloatNode;\n\tshadingAlpha: FloatNode;\n\tshadingBlend: IntNode;\n\tafterColor?: ExpressionNode | BlendNode;\n\talpha?: FloatNode;\n\tposition?: Vector3Node | OperatorNode;\n\tnodeType: string = 'Standard';\n\n\tconstructor() {\n\t\tsuper('standard');\n\t\tthis.color = new ColorNode(colorDefault);\n\t\tthis.roughness = new FloatNode(0.3);\n\t\tthis.metalness = new FloatNode(0);\n\t\tthis.reflectivity = new FloatNode(0.5);\n\n\t\tthis.shadingAlpha = new FloatNode(1);\n\t\tthis.shadingBlend = new IntNode(0);\n\t}\n\n\tbuild(builder: NodeBuilder): string {\n\t\tlet code;\n\n\t\tbuilder.define('STANDARD');\n\n\t\tbuilder.requires.lights = true;\n\n\t\tbuilder.extensions.derivatives = true;\n\t\tbuilder.extensions.shaderTextureLOD = true;\n\n\t\tif (builder.isShader('vertex')) {\n\t\t\tconst position = this.position\n\t\t\t\t? this.position.analyzeAndFlow(builder, 'v3', { cache: 'position' })\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.mergeUniform(\n\t\t\t\tUniformsUtils.merge([UniformsLib.fog, UniformsLib.lights])\n\t\t\t);\n\n\t\t\tif ((UniformsLib as { LTC_1?: any }).LTC_1) {\n\t\t\t\t// add ltc data textures to material uniforms\n\n\t\t\t\tbuilder.uniforms.ltc_1 = { value: undefined };\n\t\t\t\tbuilder.uniforms.ltc_2 = { value: undefined };\n\t\t\t}\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\n\t\t\t\t\t//\"#include <encodings_pars_fragment>\", // encoding functions\n\t\t\t\t\t'#include <fog_pars_vertex>',\n\t\t\t\t\t'#include <normal_pars_vertex>',\n\t\t\t\t\t'#include <shadowmap_pars_vertex>',\n\t\t\t\t\t'#include <clipping_planes_pars_vertex>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <beginnormal_vertex>',\n\t\t\t\t`\n\t\t\t\t#if !defined( USE_LAYER_DISPLACE )\n\t\t\t\t\t#include <defaultnormal_vertex>\n\t\t\t\t#endif\n\n\t\t\t\tvec3 displaced_position = position;\n\t\t\t\tvec3 displaced_normal = normal;\n\n\t\t\t\t#if defined( USE_LAYER_DISPLACE )\n\t\t\t\t\tvec3 transformed;\n\t\t\t\t\tvec3 transformedNormal;\n\t\t\t\t#endif\n\t\t\t\t`,\n\t\t\t\t'#include <normal_vertex>',\n\n\t\t\t\t`\n\t\t\t\t#if !defined( USE_LAYER_DISPLACE )\n\t\t\t\t\t#include <begin_vertex>\n\t\t\t\t#endif /* !USE_LAYER_DISPLACE */\n\t\t\t\t`,\n\t\t\t];\n\n\t\t\tif (position) {\n\t\t\t\toutput.push(\n\t\t\t\t\tposition.code,\n\t\t\t\t\tposition.result ? 'displaced_position = ' + position.result + ';' : ''\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'transformed = displaced_position;',\n\t\t\t\t'transformedNormal = normalMatrix * displaced_normal;',\n\n\t\t\t\t'#ifndef FLAT_SHADED',\n\t\t\t\t' vNormal = transformedNormal;',\n\t\t\t\t'#endif'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t'#include <project_vertex>',\n\t\t\t\t'#include <fog_vertex>',\n\t\t\t\t'#include <clipping_planes_vertex>',\n\n\t\t\t\t'\tvViewPosition = - mvPosition.xyz;',\n\n\t\t\t\t'#include <worldpos_vertex>',\n\t\t\t\t'#include <shadowmap_vertex>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t} else {\n\t\t\tconst contextGammaOnly = {\n\t\t\t\tgamma: true,\n\t\t\t};\n\n\t\t\t// analyze all nodes to reuse generate codes\n\n\t\t\tif (this.color === undefined) this.color = new ColorNode(colorDefault);\n\t\t\tthis.color.analyze(builder, {\n\t\t\t\tslot: 'color',\n\t\t\t\tcontext: contextGammaOnly,\n\t\t\t});\n\n\t\t\tthis.roughness.analyze(builder);\n\t\t\tthis.metalness.analyze(builder);\n\n\t\t\tthis.shadingAlpha.analyze(builder);\n\t\t\tthis.shadingBlend.analyze(builder);\n\n\t\t\tif (this.afterColor)\n\t\t\t\tthis.afterColor.analyze(builder, { slot: 'afterColor' });\n\n\t\t\tif (this.alpha) this.alpha.analyze(builder);\n\n\t\t\tif (this.reflectivity) this.reflectivity.analyze(builder);\n\n\t\t\t// build code\n\n\t\t\tconst color = this.color.flow(builder, 'c', {\n\t\t\t\tslot: 'color',\n\t\t\t\tcontext: contextGammaOnly,\n\t\t\t});\n\t\t\tconst roughness = this.roughness.flow(builder, 'f');\n\t\t\tconst metalness = this.metalness.flow(builder, 'f');\n\n\t\t\tconst shadingAlpha = this.shadingAlpha.flow(builder, 'f');\n\t\t\tconst shadingBlend = this.shadingBlend.flow(builder, 'i');\n\n\t\t\tconst afterColor = this.afterColor\n\t\t\t\t? this.afterColor.flow(builder, 'c', { slot: 'afterColor' })\n\t\t\t\t: undefined;\n\n\t\t\tconst alpha = this.alpha ? this.alpha.flow(builder, 'f') : undefined;\n\n\t\t\tconst reflectivity = this.reflectivity\n\t\t\t\t? this.reflectivity.flow(builder, 'f')\n\t\t\t\t: undefined;\n\n\t\t\tbuilder.requires.transparent = alpha !== undefined;\n\n\t\t\tbuilder.addParsCode(\n\t\t\t\t[\n\t\t\t\t\t'varying vec3 vViewPosition;',\n\n\t\t\t\t\t'#include <normal_pars_fragment>',\n\t\t\t\t\t'#include <dithering_pars_fragment>',\n\t\t\t\t\t'#include <fog_pars_fragment>',\n\t\t\t\t\t'#include <bsdfs>',\n\t\t\t\t\t'#include <lights_pars_begin>',\n\t\t\t\t\t'#include <lights_physical_pars_fragment>',\n\t\t\t\t\t'#include <shadowmap_pars_fragment>',\n\t\t\t\t].join('\\n')\n\t\t\t);\n\n\t\t\tconst output = [\n\t\t\t\t'#include <clipping_planes_fragment>',\n\n\t\t\t\t// add before: prevent undeclared normal\n\t\t\t\t'\t#include <normal_fragment_begin>',\n\n\t\t\t\t`\n\t\t\t\t// NOTE: gl_FrontFacing alternative using face normal estimation.\n\t\t\t\tvec3 viewdx = dFdx(vViewPosition);\n\t\t\t\tvec3 viewdy = dFdy(vViewPosition);\n\t\t\t\tvec3 faceNormal = normalize(cross(viewdx,viewdy));\n\t\t\t\tif (dot(normal, faceNormal) < 0.0) {\n\t\t\t\t\tnormal *= -1.0;\n\t\t\t\t}\n\t\t\t\t`,\n\n\t\t\t\t// add before: prevent undeclared material\n\t\t\t\t'\tPhysicalMaterial material;',\n\t\t\t\t'\tmaterial.diffuseColor = vec3( 1.0 );',\n\t\t\t];\n\n\t\t\toutput.push(\n\t\t\t\tcolor.code,\n\t\t\t\t'\tvec3 diffuseColor = ' + color.result + ';',\n\t\t\t\t'\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );',\n\n\t\t\t\troughness.code,\n\t\t\t\t'\tfloat roughnessFactor = ' + roughness.result + ';',\n\n\t\t\t\tmetalness.code,\n\t\t\t\t'\tfloat metalnessFactor = ' + metalness.result + ';'\n\t\t\t);\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\talpha.code,\n\t\t\t\t\t'#ifdef ALPHATEST',\n\n\t\t\t\t\t'\tif ( ' + alpha.result + ' <= ALPHATEST ) discard;',\n\n\t\t\t\t\t'#endif'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// anti-aliasing code by @elalish\n\n\t\t\toutput.push(\n\t\t\t\t'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',\n\t\t\t\t'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );'\n\t\t\t);\n\n\t\t\t// optimization for now\n\n\t\t\toutput.push(\n\t\t\t\t'material.diffuseColor = diffuseColor * ( 1.0 - metalnessFactor );',\n\t\t\t\t'material.roughness = max( roughnessFactor, 0.0525 );',\n\t\t\t\t'material.roughness += geometryRoughness;',\n\t\t\t\t'material.roughness = min( material.roughness, 1.0 );',\n\n\t\t\t\t'material.roughness = clamp( roughnessFactor, 0.04, 1.0 );'\n\t\t\t);\n\n\t\t\tif (reflectivity) {\n\t\t\t\toutput.push(\n\t\t\t\t\treflectivity.code,\n\t\t\t\t\t'material.specularColor = mix( vec3( 0.16 * pow2( ' +\n\t\t\t\t\t\treflectivity.result +\n\t\t\t\t\t\t' ) ), diffuseColor, metalnessFactor );'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push(\n\t\t\t\t\t'material.specularColor = mix( vec3( 0.04 ), diffuseColor, metalnessFactor );'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toutput.push('#include <lights_fragment_begin>');\n\n\t\t\toutput.push('#include <lights_fragment_end>');\n\n\t\t\toutput.push(\n\t\t\t\t'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;'\n\t\t\t);\n\n\t\t\toutput.push(\n\t\t\t\t`\n\t\t\t\tif (outgoingLight != diffuseColor) {\n\t\t\t\t\tfloat lightAccu = clamp( length( reflectedLight.directSpecular + reflectedLight.indirectSpecular ), 0.0, 1.0 );\n\t\t\t\t\taccumAlpha += ( 1.0 - accumAlpha ) * ${shadingAlpha.result} * lightAccu;\n\t\t\t\t\toutgoingLight = spe_blend( diffuseColor, outgoingLight, ${shadingAlpha.result}, ${shadingBlend.result} );\n\t\t\t\t}\n\t\t\t\t`\n\t\t\t);\n\n\t\t\tif (afterColor) {\n\t\t\t\toutput.push(\n\t\t\t\t\tafterColor.code,\n\t\t\t\t\t`outgoingLight = spe_blend(outgoingLight, ${afterColor.result}, 1.0, SPE_BLENDING_NORMAL);`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (alpha) {\n\t\t\t\toutput.push(\n\t\t\t\t\t`gl_FragColor = vec4( outgoingLight, accumAlpha * ${alpha.result} );`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toutput.push('gl_FragColor = vec4( outgoingLight, 1.0 );');\n\t\t\t}\n\n\t\t\toutput.push(\n\t\t\t\t'#include <encodings_fragment>',\n\t\t\t\t'#include <fog_fragment>',\n\t\t\t\t'#include <dithering_fragment>'\n\t\t\t);\n\n\t\t\tcode = output.join('\\n');\n\t\t}\n\n\t\treturn code;\n\t}\n\n\tcopy(source: this): this {\n\t\tsuper.copy(source);\n\n\t\tif (source.color) this.color = source.color.clone();\n\t\tthis.roughness = source.roughness.clone();\n\t\tthis.metalness = source.metalness.clone();\n\t\tif (source.position) this.position = source.position.clone();\n\t\tif (source.afterColor) this.afterColor = source.afterColor.clone();\n\t\tif (source.alpha) this.alpha = source.alpha.clone();\n\t\tif (source.reflectivity) this.reflectivity = source.reflectivity.clone();\n\t\tif (source.shadingAlpha) this.shadingAlpha = source.shadingAlpha.clone();\n\t\tif (source.shadingBlend) this.shadingBlend = source.shadingBlend.clone();\n\n\t\treturn this;\n\t}\n}\n", "import { NodeMaterial, NodeMaterialParameters } from './NodeMaterial';\nimport { StandardNode } from './nodes/StandardNode';\n\nexport class StandardNodeMaterial extends NodeMaterial {\n\tfragment: StandardNode;\n\n\tget color() {\n\t\treturn this.fragment.color;\n\t}\n\tset color(val) {\n\t\tthis.fragment.color = val;\n\t}\n\n\tget afterColor() {\n\t\treturn this.fragment.afterColor;\n\t}\n\tset afterColor(val) {\n\t\tthis.fragment.afterColor = val;\n\t}\n\n\tget alpha() {\n\t\treturn this.fragment.alpha;\n\t}\n\tset alpha(val) {\n\t\tthis.fragment.alpha = val;\n\t}\n\n\tget shadingAlpha() {\n\t\treturn this.fragment.shadingAlpha;\n\t}\n\tset shadingAlpha(val) {\n\t\tthis.fragment.shadingAlpha = val;\n\t}\n\n\tget shadingBlend() {\n\t\treturn this.fragment.shadingBlend;\n\t}\n\tset shadingBlend(val) {\n\t\tthis.fragment.shadingBlend = val;\n\t}\n\n\tget position() {\n\t\treturn this.fragment.position;\n\t}\n\tset position(val) {\n\t\tthis.fragment.position = val;\n\t}\n\n\tget roughness() {\n\t\treturn this.fragment.roughness;\n\t}\n\tset roughness(val) {\n\t\tthis.fragment.roughness = val;\n\t}\n\n\tget metalness() {\n\t\treturn this.fragment.metalness;\n\t}\n\tset metalness(val) {\n\t\tthis.fragment.metalness = val;\n\t}\n\n\tget reflectivity() {\n\t\treturn this.fragment.reflectivity;\n\t}\n\tset reflectivity(val) {\n\t\tthis.fragment.reflectivity = val;\n\t}\n\n\tconstructor(\n\t\tnode: StandardNode = new StandardNode(),\n\t\tparameters?: NodeMaterialParameters\n\t) {\n\t\tsuper(node, node, parameters);\n\t\tthis.type = 'StandardNodeMaterial';\n\n\t\t// It's set in the super() constructor,\n\t\t// we explicitly set it here since the type is not inferred\n\t\tthis.fragment = node;\n\t}\n}\n", "import { StandardNode } from './nodes/materials/nodes/StandardNode';\nimport { StandardNodeMaterial } from './nodes/materials/StandardNodeMaterial';\nimport type { Material } from '.';\nimport { LayerStack } from './layers';\nimport { SerializedMaterial } from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { Material as TMaterial } from 'three';\nimport type { AssetLibrary } from './AssetLibrary';\nimport { NodeMaterialParameters } from './nodes/Nodes';\n\nexport class PhysicalMaterial extends StandardNodeMaterial {\n\tconstructor(\n\t\tparameters?: NodeMaterialParameters,\n\t\tnode?: StandardNode,\n\t\tlayerStack?: LayerStack\n\t) {\n\t\tsuper(node, parameters);\n\n\t\tthis.userData.type = 'PhysicalMaterial';\n\t\tthis.userData.category = 'Physical';\n\t\tthis.userData.layers = layerStack ?? this._getLayerStack(parameters?.map);\n\t}\n\n\tget layersList(): LayerStack {\n\t\treturn this.userData.layers as LayerStack;\n\t}\n\n\tset layersList(list: LayerStack) {\n\t\tthis.userData.layers = list;\n\t}\n\n\tequals(material: Material) {\n\t\treturn (\n\t\t\tthis.userData.type === material.userData.type &&\n\t\t\t(this.userData.layers as LayerStack).uuid ==\n\t\t\t\t(material.userData.layers as LayerStack).uuid\n\t\t);\n\t}\n\n\tcopy(source: this): this {\n\t\tif (\n\t\t\tsource.userData.layers !== undefined &&\n\t\t\tsource.userData.layers instanceof LayerStack\n\t\t) {\n\t\t\t// Save original layerstack and core ode\n\t\t\tconst sourceLayers = source.userData.layers;\n\t\t\tconst sourceFragment = source.fragment;\n\n\t\t\t// Copy all things\n\t\t\tsuper.copy(source);\n\n\t\t\t// Clone the core node\n\t\t\tconst node = sourceFragment.clone();\n\t\t\tthis.fragment = node;\n\t\t\tthis.vertex = node;\n\n\t\t\t// Clone the layerstack\n\t\t\tconst layers = sourceLayers.clone(this);\n\t\t\tthis.userData.layers = layers;\n\n\t\t\t// Restore from source the values that were overriden by cloning process\n\t\t\tnode.shadingAlpha.value = sourceFragment.shadingAlpha.value as number;\n\t\t\tnode.shadingBlend.value = sourceFragment.shadingBlend.value as number;\n\t\t} else {\n\t\t\tsuper.copy(source);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t// TODO it is not actually from JSON\n\tstatic fromJSON(\n\t\tsource: TMaterial,\n\t\tdata: SerializedMaterial,\n\t\tassets: AssetLibrary\n\t): PhysicalMaterial {\n\t\tconst node = assets.getNode(data.vertex) as StandardNode;\n\t\tconst material = new PhysicalMaterial(undefined, node);\n\t\tmaterial.fromJSON(data, assets);\n\n\t\treturn material;\n\t}\n\n\tdispose() {\n\t\tsuper.dispose();\n\t}\n}\n", "import { Seq, SeqItem } from 'collab-data';\nimport {\n\tFragmentBlendingMode,\n\tLambertLightLayer,\n\tLayer,\n\tLightLayer,\n\tMaterialState,\n\tNamed,\n\tPhongLightLayer,\n\tSharable,\n\tStandardLightLayer,\n\tToonLightLayer,\n} from 'spline-data';\nimport { Color } from 'three';\nimport { Material } from '.';\nimport { SharedAssetsManager } from '../shared/SharedAssetsManager';\nimport { getSharedColorData } from '../shared/utils';\nimport { BasicMaterial } from './BasicMaterial';\nimport { LambertMaterial } from './LambertMaterial';\nimport { LayerStack } from './layers';\nimport { createLayer, applyDerivedLayerValue } from './layers/create';\nimport { PhongMaterial } from './PhongMaterial';\nimport { PhysicalMaterial } from './PhysicalMaterial';\nimport { ToonMaterial } from './ToonMaterial';\nimport { FromThreeVector4 } from '../updaterUtils';\n\nexport function getMaterial(\n\tdata: Sharable<MaterialState>,\n\tsharedAssets: SharedAssetsManager\n) {\n\tif (typeof data === 'string') {\n\t\treturn sharedAssets.getMaterialOrDeletedPlaceholder(data);\n\t} else {\n\t\treturn createMaterial(data as MaterialState, sharedAssets);\n\t}\n}\n\nexport function getMaterials(\n\tmaterial: Sharable<MaterialState>[],\n\tsharedAssets: SharedAssetsManager\n) {\n\treturn material.map((a) => getMaterial(a, sharedAssets));\n}\n\nexport function createMaterial(\n\tdata: MaterialState,\n\tsharedAssets: SharedAssetsManager\n): Material {\n\t// hack: some old files were migrated without being able to assign the data layers, so we use default layers instead\n\tconst layers =\n\t\tdata.layers ?? MaterialState.defaultTwoLayerData('phong').layers;\n\tconst lightLayer = getLightLayer(layers);\n\tlet material: Material;\n\tswitch (lightLayer.category) {\n\t\tcase 'basic':\n\t\t\tmaterial = new BasicMaterial();\n\t\t\tbreak;\n\t\tcase 'lambert': {\n\t\t\tmaterial = new LambertMaterial();\n\t\t\tbreak;\n\t\t}\n\t\tcase 'toon': {\n\t\t\tmaterial = new ToonMaterial();\n\t\t\tbreak;\n\t\t}\n\t\tcase 'physical':\n\t\t\tmaterial = new PhysicalMaterial();\n\t\t\tbreak;\n\t\tcase 'phong':\n\t\tdefault: {\n\t\t\tmaterial = new PhongMaterial();\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tmaterial.name = data.name ?? 'Untitled Material';\n\n\t// TODO this is a hack, layerStack should not create layers when created a new\n\tconst layerStack = material.userData.layers!;\n\tremoveAllMaterialLayer(layerStack);\n\n\tfor (let i = layers.length - 1; i >= 0; i--) {\n\t\taddMaterialLayer(layerStack, layers[i], sharedAssets);\n\t}\n\n\tswitch (lightLayer.category) {\n\t\tcase 'basic':\n\t\t\tbreak;\n\t\tcase 'lambert': {\n\t\t\tconst lambertMaterial = material as LambertMaterial;\n\t\t\tconst lambertData = lightLayer as LambertLightLayer;\n\t\t\tconst color = getSharedColorData(lambertData.emissive, sharedAssets);\n\t\t\tif (color instanceof Color) {\n\t\t\t\tlambertMaterial.emissive.value = color;\n\t\t\t} else {\n\t\t\t\tlambertMaterial.emissive.value.setHex(FromThreeVector4.getHex(color));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'toon': {\n\t\t\tconst toonMaterial = material as ToonMaterial;\n\t\t\tconst toonData = lightLayer as ToonLightLayer;\n\t\t\ttoonMaterial.shininess.value = toonData.shininess;\n\t\t\tconst color = getSharedColorData(toonData.specular, sharedAssets);\n\t\t\tif (color instanceof Color) {\n\t\t\t\ttoonMaterial.specular.value = color;\n\t\t\t} else {\n\t\t\t\ttoonMaterial.specular.value.setHex(FromThreeVector4.getHex(color));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'physical':\n\t\t\tconst physicalMaterial = material as PhysicalMaterial;\n\t\t\tconst standardData = lightLayer as StandardLightLayer;\n\t\t\tphysicalMaterial.metalness.value = standardData.metalness;\n\t\t\tphysicalMaterial.roughness.value = standardData.roughness;\n\t\t\tphysicalMaterial.reflectivity.value = standardData.reflectivity;\n\t\t\tbreak;\n\t\tcase 'phong':\n\t\tdefault: {\n\t\t\tconst phongMaterial = material as PhongMaterial;\n\t\t\tconst phongData = lightLayer as PhongLightLayer;\n\t\t\tphongMaterial.shininess.value = phongData.shininess;\n\t\t\tconst color = getSharedColorData(phongData.specular, sharedAssets);\n\t\t\tif (color instanceof Color) {\n\t\t\t\tphongMaterial.specular.value = color;\n\t\t\t} else {\n\t\t\t\tphongMaterial.specular.value.setHex(FromThreeVector4.getHex(color));\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlayerStack.blendColors();\n\tlayerStack.blendAfterColors();\n\tlayerStack.blendPositions();\n\treturn material as unknown as Material;\n}\n\nfunction getLightLayer(layers: Seq<Layer>): LightLayer {\n\tfor (const layer of layers) {\n\t\tif (layer.data.type === 'light') return layer.data;\n\t}\n\n\treturn {\n\t\ttype: 'light',\n\t\tcategory: 'basic',\n\t\tvisible: true,\n\t\talpha: 1,\n\t\tmode: FragmentBlendingMode.Normal,\n\t};\n}\n// TODO COLLAB this should be done by layer stack itself, also about the uuid hack\nexport function removeMaterialLayer(layerStack: LayerStack, id: string) {\n\tfor (let layer of layerStack.getLayers()) {\n\t\tif (layer.uuid === id) {\n\t\t\tlayerStack.removeLayer(layer.id);\n\t\t}\n\t}\n}\n\nexport function removeAllMaterialLayer(layerStack: LayerStack) {\n\tfor (let layer of layerStack.getLayers()) {\n\t\tlayerStack.removeLayer(layer.id);\n\t}\n}\n\nexport function addMaterialLayer(\n\tlayerStack: LayerStack,\n\targ1: SeqItem<Layer>,\n\tsharedAssets: SharedAssetsManager\n) {\n\tconst layerParams = createLayer(arg1, sharedAssets);\n\tif (layerParams.type === 'transmission') {\n\t\tlayerParams.transmissionSamplerMap = sharedAssets?.transmissionSamplerMap;\n\t\tlayerParams.transmissionDepthMap = sharedAssets?.transmissionDepthMap;\n\t}\n\n\tlet runtimeLayer = layerStack.addLayer(layerParams);\n\truntimeLayer.uuid = arg1.id;\n\n\tfor (const k in arg1.data) {\n\t\tapplyDerivedLayerValue(k, runtimeLayer, arg1.data);\n\t}\n}\n", "import { SeqItem } from 'collab-data';\nimport {\n\tAbstractFragmentLayer,\n\tAbstractMaterialLayer,\n\tColorLayer,\n\tDepthLayer,\n\tDisplaceLayer,\n\tFresnelLayer,\n\tGradientLayer,\n\tLayer,\n\tLightLayer,\n\tMatcapLayer,\n\tNoiseLayer,\n\tNormalLayer,\n\tRainbowLayer,\n\tRGBA,\n\tTextureLayer,\n\tTransmissionLayer,\n} from 'spline-data';\nimport { Matrix3, Texture, Vector2, Vector3, Vector4, Wrapping } from 'three';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\nimport { getSharedColorData } from '../../shared/utils';\nimport { Node } from '../nodes/Nodes';\nimport { LayerParameters, Layer as SpeLayer } from './Layer';\n\nexport function createLayer(\n\tlayer: SeqItem<Layer>,\n\tsharedAssets: SharedAssetsManager\n): LayerParameters {\n\tswitch (layer.data.type) {\n\t\tcase 'light':\n\t\t\treturn createFragmentLayerParams(layer as SeqItem<LightLayer>);\n\t\tcase 'fresnel':\n\t\t\treturn createFresnelLayerParams(\n\t\t\t\tlayer as SeqItem<FresnelLayer>,\n\t\t\t\tsharedAssets\n\t\t\t);\n\t\tcase 'gradient':\n\t\t\treturn createGradientLayerParams(layer as SeqItem<GradientLayer>);\n\t\tcase 'depth':\n\t\t\treturn createDepthLayerParams(layer as SeqItem<DepthLayer>);\n\t\tcase 'normal':\n\t\t\treturn createNormalLayerParams(layer as SeqItem<NormalLayer>);\n\t\tcase 'noise':\n\t\t\treturn createNoiseLayerParams(layer as SeqItem<NoiseLayer>, sharedAssets);\n\t\tcase 'texture':\n\t\t\treturn createTextureLayerParams(\n\t\t\t\tlayer as SeqItem<TextureLayer>,\n\t\t\t\tsharedAssets\n\t\t\t);\n\t\tcase 'rainbow':\n\t\t\treturn createRainbowLayerParams(layer as SeqItem<RainbowLayer>);\n\t\tcase 'transmission':\n\t\t\treturn createTransmissionLayerParams(\n\t\t\t\tlayer as SeqItem<TransmissionLayer>,\n\t\t\t\tsharedAssets\n\t\t\t);\n\t\tcase 'matcap':\n\t\t\treturn createMatcapLayer(layer as SeqItem<MatcapLayer>, sharedAssets);\n\t\tcase 'displace':\n\t\t\treturn createDisplaceLayer(layer as SeqItem<DisplaceLayer>);\n\t\tcase 'color':\n\t\tdefault:\n\t\t\treturn createColorLayerParams(layer as SeqItem<ColorLayer>, sharedAssets);\n\t}\n}\n\nfunction createLayerParams(\n\tlayer: SeqItem<AbstractMaterialLayer<any>>\n): LayerParameters {\n\treturn {\n\t\ttype: layer.data.type,\n\t};\n}\n\nfunction createFragmentLayerParams(\n\tlayer: SeqItem<AbstractFragmentLayer<any>>\n): LayerParameters {\n\tconst { alpha, mode } = layer.data;\n\treturn {\n\t\t...createLayerParams(layer),\n\t\talpha,\n\t\tmode,\n\t};\n}\n\nfunction createColorLayerParams(\n\tlayer: SeqItem<ColorLayer>,\n\tsharedAssets: SharedAssetsManager\n): LayerParameters {\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tcolor: getSharedColorData(layer.data.color, sharedAssets),\n\t};\n}\n\nfunction createFresnelLayerParams(\n\tlayer: SeqItem<FresnelLayer>,\n\tsharedAssets: SharedAssetsManager\n): LayerParameters {\n\tconst { bias, scale, intensity, factor, color } = layer.data;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tcolor: getSharedColorData(color, sharedAssets),\n\t\tbias,\n\t\tscale,\n\t\tintensity,\n\t\tfactor,\n\t};\n}\n\nfunction createGradientLayerParams(\n\tlayer: SeqItem<GradientLayer>\n): LayerParameters {\n\tconst { gradientType, smooth, colors, steps, angle, offset, morph } =\n\t\tlayer.data;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tgradientType: gradientType,\n\t\tsmooth,\n\t\tcolors: colors.map((c) => new Vector4(c[0], c[1], c[2], c[3])),\n\t\tnum: colors.length,\n\t\tsteps,\n\t\toffset: new Vector2(...offset),\n\t\tmorph: new Vector2(...morph),\n\t\tangle,\n\t};\n}\n\nexport function createDepthLayerParams(\n\tlayer: SeqItem<DepthLayer>\n): LayerParameters {\n\tconst {\n\t\tgradientType,\n\t\tnear,\n\t\tfar,\n\t\tisVector,\n\t\tisWorldSpace,\n\t\torigin,\n\t\tdirection,\n\t\tcolors,\n\t\tsteps,\n\t\tsmooth,\n\t\tnum,\n\t} = layer.data;\n\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tgradientType: gradientType,\n\t\tnear,\n\t\tfar,\n\t\tisVector,\n\t\tisWorldSpace,\n\t\torigin: new Vector3(...origin),\n\t\tdirection: direction ? new Vector3(...direction) : new Vector3(1, 0, 0),\n\t\tnum,\n\t\tcolors: colors.map((c) => new Vector4(c[0], c[1], c[2], c[3])),\n\t\tsteps,\n\t\tsmooth,\n\t};\n}\n\nfunction createNormalLayerParams(layer: SeqItem<NormalLayer>): LayerParameters {\n\tconst { cnormal } = layer.data;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tcnormal: new Vector3(cnormal[0], cnormal[1], cnormal[2]),\n\t};\n}\n\nfunction createNoiseLayerParams(\n\tlayer: SeqItem<NoiseLayer>,\n\tsharedAssetsData: SharedAssetsManager\n): LayerParameters {\n\tconst { data } = layer;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tscale: data.scale,\n\t\tmove: data.move,\n\t\tfA: new Vector2(...data.fA),\n\t\tfB: new Vector2(...data.fB),\n\t\tdistortion: new Vector2(...data.distortion),\n\t\tcolorA: getSharedColorData(data.colorA, sharedAssetsData),\n\t\tcolorB: getSharedColorData(data.colorB, sharedAssetsData),\n\t\tcolorC: getSharedColorData(data.colorC, sharedAssetsData),\n\t\tcolorD: getSharedColorData(data.colorD, sharedAssetsData),\n\t\tnoiseType: data.noiseType,\n\t};\n}\n\nfunction createTextureLayerParams(\n\tlayer: SeqItem<TextureLayer>,\n\tsharedAssets?: SharedAssetsManager\n): LayerParameters {\n\tconst { projection, axis, crop, size } = layer.data;\n\tconst { image, wrapping, repeat, offset } = layer.data.texture;\n\tconst texture = new Texture();\n\n\tlet sharedImage;\n\tif (typeof image === 'string') {\n\t\tsharedImage = sharedAssets?.getImage(image);\n\t} else {\n\t\tconst img = new Image();\n\t\timg.src = image.data;\n\t\timg.onload = () => {\n\t\t\tsharedAssets?.onImageLoad && sharedAssets?.onImageLoad(image.data);\n\t\t};\n\t\tsharedImage = img;\n\t}\n\n\ttexture.image = sharedImage;\n\n\ttexture.wrapS = texture.wrapT = wrapping as unknown as Wrapping;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\ttexture,\n\t\tmat: new Matrix3().setUvTransform(\n\t\t\toffset[0],\n\t\t\toffset[1],\n\t\t\trepeat[0],\n\t\t\trepeat[1],\n\t\t\t0,\n\t\t\t0,\n\t\t\t0\n\t\t),\n\t\tcrop,\n\t\tprojection,\n\t\taxis: ['x', 'y', 'z'].indexOf(axis),\n\t\tsize,\n\t};\n}\n\nfunction createRainbowLayerParams(\n\tlayer: SeqItem<RainbowLayer>\n): LayerParameters {\n\tconst { data } = layer;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tfilmThickness: data.filmThickness,\n\t\tmovement: data.movement,\n\t\twavelengths: new Vector3(...data.wavelengths),\n\t\tnoiseStrength: data.noiseStrength,\n\t\tnoiseScale: data.noiseScale,\n\t\toffset: new Vector3(...data.offset),\n\t};\n}\n\nfunction createTransmissionLayerParams(\n\tlayer: SeqItem<TransmissionLayer>,\n\tsharedAssets: SharedAssetsManager\n): LayerParameters {\n\tconst { data } = layer;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tthickness: data.thickness,\n\t\tior: data.ior,\n\t\troughness: data.roughness,\n\t\ttransmissionSamplerMap: sharedAssets.transmissionSamplerMap,\n\t\ttransmissionDepthMap: sharedAssets.transmissionDepthMap,\n\t};\n}\n\nfunction createMatcapLayer(\n\tlayer: SeqItem<MatcapLayer>,\n\tsharedAssets?: SharedAssetsManager\n): LayerParameters {\n\tconst texture = new Texture();\n\n\tconst { image } = layer.data.texture;\n\tlet sharedImage;\n\tif (typeof image === 'string') {\n\t\tsharedImage = sharedAssets?.getImage(image);\n\t} else {\n\t\tconst img = new Image();\n\t\timg.src = image.data;\n\t\timg.onload = () => {\n\t\t\tsharedAssets?.onImageLoad && sharedAssets?.onImageLoad(image.data);\n\t\t};\n\t\tsharedImage = img;\n\t}\n\ttexture.image = sharedImage;\n\n\t// TODO handle color for real\n\tconst color = 0xffffff;\n\treturn {\n\t\t...createFragmentLayerParams(layer),\n\t\tcolor,\n\t\ttexture,\n\t};\n}\n\nfunction createDisplaceLayer(layer: SeqItem<DisplaceLayer>): LayerParameters {\n\tconst { data } = layer;\n\tconst common = {\n\t\t...createLayerParams(layer),\n\t\tintensity: data.intensity,\n\t};\n\tif (data.displacementType === 'noise') {\n\t\treturn {\n\t\t\t...common,\n\t\t\toffset: new Vector3(...data.offset),\n\t\t\tscale: data.scale,\n\t\t\tmovement: data.movement,\n\t\t\tnoiseType: data.noiseType,\n\t\t};\n\t} else {\n\t\t// TODO handle textures for real\n\t\tconst texture = new Texture();\n\t\t// TODO handle transform matrix for real\n\t\tconst mat = new Matrix3().setUvTransform(0, 0, 1, 1, 0, 0, 0);\n\t\treturn {\n\t\t\t...common,\n\t\t\ttexture,\n\t\t\tmat,\n\t\t\tcrop: data.crop,\n\t\t};\n\t}\n}\n\nexport function applyDerivedLayerValue(\n\tkey: string,\n\tlayer: SpeLayer,\n\tlayerState: Layer\n): Node | undefined {\n\tif (\n\t\tlayerState.type === 'displace' &&\n\t\t(key === 'intensity' || key === 'visible')\n\t) {\n\t\tconst uniform = layer.uniforms[`f${layer.id}_intensity`];\n\t\tif (!uniform) return undefined;\n\t\tuniform.value = layerState.intensity * (layerState.visible ? 1 : 0);\n\t\treturn uniform;\n\t}\n\n\tif (\n\t\tlayerState.type !== 'displace' &&\n\t\t(key === 'alpha' || key === 'visible')\n\t) {\n\t\tconst uniform = layer.uniforms[`f${layer.id}_alpha`];\n\t\tif (!uniform) return undefined;\n\t\tuniform.value = layerState.alpha * (layerState.visible ? 1 : 0);\n\t\treturn uniform;\n\t}\n\n\treturn undefined;\n}\n", "import { RGB, RGBA } from 'spline-data';\nimport { Color, Vector4 } from 'three';\nexport namespace FromThreeVector4 {\n\texport function getHex(c: Vector4) {\n\t\treturn new Color(c.x, c.y, c.z).getHex();\n\t}\n}\n\nexport namespace FromDataRGBA {\n\texport function getThreeVector4(c: RGBA) {\n\t\treturn new Vector4(c.r, c.g, c.b, c.a);\n\t}\n\n}\n\nexport namespace FromDataRGB {\n\texport function setThreeColor(color: Color, c: RGB) {\n\t\tcolor.setRGB(c.r, c.g, c.b);\n\t}\n\n\texport function getHex(c: RGB | RGBA): number {\n\t\treturn new Color(c.r, c.g, c.b).getHex();\n\t}\n}\n", "/**\n * @author Cristhian Lunardi\n * textUtils.js\n * A TextLine is a structure which will have its childrens (<Char3D>)\n * inside the <message> array.\n * This file contains the necessary functions to handle and update\n * the <TextLine>'s properties and consequently its childrens\n */\n\nimport { HorizontalAlign } from 'spline-data';\nimport { Vector2, Vector3 } from 'three';\nimport { Char3D, Char3DParameters } from './Char3D';\n\nconst TEMPV2: Vector2 = new Vector2();\n\nexport type ITextLine = {\n\talign: HorizontalAlign;\n\tendLine: boolean;\n\tlineHeight: number;\n\tmaxCharSize: number;\n\tyLinePos: number;\n\tmessage: Char3DParameters[];\n};\n\nexport class TextLine implements ITextLine {\n\tyLinePos: number;\n\tlineHeight: number;\n\tmaxCharSize: number;\n\tmessage: Char3D[] = [];\n\tnextChar3DPos: Vector2;\n\talign: HorizontalAlign;\n\tendLine: boolean = true;\n\n\t/**\n\t *\n\t * @param yLinePos -\n\t * @param lineHeight -\n\t * @param maxCharSize - it's the fontSize\n\t */\n\tconstructor(yLinePos: number, lineHeight: number, maxCharSize: number) {\n\t\tthis.yLinePos = yLinePos;\n\t\tthis.lineHeight = lineHeight;\n\t\tthis.maxCharSize = maxCharSize;\n\n\t\tthis.nextChar3DPos = new Vector2(\n\t\t\t0,\n\t\t\tthis.yLinePos + this.maxCharSize * this.lineHeight\n\t\t);\n\t\tthis.align = HorizontalAlign.Left;\n\t}\n\n\taddChar3D(\n\t\tchar3D: Char3D,\n\t\ttextOrigin: Vector3,\n\t\tindex: number = this.message.length\n\t): void {\n\t\tthis.message.splice(index, 0, char3D);\n\n\t\tif (char3D.fontSize > this.maxCharSize) {\n\t\t\tthis.maxCharSize = char3D.fontSize;\n\t\t\tthis.nextChar3DPos.y = this.yLinePos + this.maxCharSize * this.lineHeight;\n\t\t\tthis.fullUpdate(textOrigin);\n\t\t} else {\n\t\t\tchar3D.updatePosition(this.nextChar3DPos, textOrigin);\n\t\t\tthis.nextChar3DPos.x += char3D.charSize;\n\t\t}\n\t}\n\n\tdeleteChar3D(index: number = this.message.length - 1): Char3D | undefined {\n\t\tconst deletedChar: Char3D = this.message[index];\n\n\t\tif (deletedChar) {\n\t\t\tthis.message.splice(index, 1);\n\t\t\tthis.nextChar3DPos.x -= deletedChar.charSize;\n\t\t\treturn deletedChar;\n\t\t} else {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tisEndLine(isEndLine: boolean): void {\n\t\tthis.endLine = isEndLine;\n\t}\n\n\tfullUpdate(textOrigin: Vector3, fromIndex: number = 0): void {\n\t\tthis.nextChar3DPos.x = 0;\n\n\t\tfor (let i = fromIndex, l = this.message.length; i < l; i += 1) {\n\t\t\tthis.message[i].updatePosition(this.nextChar3DPos, textOrigin);\n\t\t\tthis.nextChar3DPos.x += this.message[i].charSize;\n\t\t}\n\t}\n\n\t/**\n\t * Return <true> if there is at least one character\n\t * out of the Frame, using maxLineSize as reference.\n\t * @param maxLineSize - maximum line size\n\t */\n\tcheckOverFlow(maxLineSize: number): boolean {\n\t\tlet char3D;\n\t\tlet i = this.message.length - 1;\n\n\t\t// If there's just one (or zero) character => return;\n\t\tif (i <= 0) return false;\n\n\t\t// Let's find the last character (not space) in this Line\n\t\twhile (i >= 0) {\n\t\t\tif (this.message[i].char !== ' ') {\n\t\t\t\tchar3D = this.message[i];\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\ti -= 1;\n\t\t}\n\n\t\tif (\n\t\t\ti >= 0 &&\n\t\t\tchar3D &&\n\t\t\tchar3D.localPosition.x + char3D.charSize > maxLineSize\n\t\t) {\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Checks if there's at least one space (\" \") in this Line.\n\t * @param index - starting character index\n\t */\n\tcontainSpaceOverFlow(index = this.message.length - 1): boolean {\n\t\tfor (let i = index; i >= 0; i -= 1) {\n\t\t\tif (this.message[i].char === ' ') return true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks if there's at least one space (\" \") in this Line.\n\t * @param index - starting character index\n\t */\n\tcontainSpace(index = this.message.length - 1): boolean {\n\t\tif (this.endLine) return true;\n\n\t\tfor (let i = index; i >= 0; i -= 1) {\n\t\t\tif (this.message[i].char === ' ') return true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tpopWord(index = this.message.length - 1): Char3D[] {\n\t\tlet word: Char3D[] = [];\n\t\tlet isWordFlowing: boolean = true;\n\t\tlet i;\n\n\t\tfor (i = index; i >= 0; i -= 1) {\n\t\t\tif (this.message[i].char === ' ') {\n\t\t\t\tisWordFlowing = false;\n\t\t\t\tif (word.length === 0) {\n\t\t\t\t\ti -= 1;\n\t\t\t\t\tword.splice(0, 0, this.message[i]);\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tword.splice(0, 0, this.message[i]);\n\t\t\t}\n\t\t}\n\n\t\tif (!isWordFlowing) {\n\t\t\tthis.message.splice(i + 1, word.length);\n\t\t} else {\n\t\t\tword = [];\n\t\t}\n\n\t\treturn word;\n\t}\n\n\t/**\n\t * Returns a word array of <Char3D>).\n\t * @param index - starting index in line\n\t * @param travel - when travel is 1, Match to right side, when travel is -1, March to left side.\n\t * @returns a word\n\t */\n\tgetWord(index: number = 0, travel = 1): Char3D[] {\n\t\tconst word: Char3D[] = [];\n\t\tlet i = index;\n\n\t\tfor (i = index; ; i += travel) {\n\t\t\tif (!this.message[i] || this.message[i].char === ' ') {\n\t\t\t\tif (word.length === 0) {\n\t\t\t\t\t// If the first <Char3D> which we verify is a space (\" \")\n\t\t\t\t\t// then it's the 'word' which we'll return\n\t\t\t\t\tif (this.message[i]) {\n\t\t\t\t\t\tword.push(this.message[i]);\n\t\t\t\t\t\tthis.message.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Otherwise, if there's at least one <Char3D> in word array\n\t\t\t\t// we found the complete word to be returned\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (travel > 0) {\n\t\t\t\t// Since we are going through the main word from left to right, every\n\t\t\t\t// <Char3D> must be 'pushed' on last position of the new word array\n\t\t\t\tword.push(this.message[i]);\n\t\t\t\tthis.message.splice(i, 1);\n\n\t\t\t\t// Also, due to we are using 'splice' on main <Char3D> array\n\t\t\t\t// we must verify the position that we just deleted (so, we return one)\n\t\t\t\ti -= travel;\n\t\t\t} else {\n\t\t\t\t// Since we are going through the main word from right to left, every\n\t\t\t\t// <Char3D> must be 'pushed' on first position of the new word array\n\t\t\t\tword.splice(0, 0, this.message[i]);\n\t\t\t\tthis.message.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\treturn word;\n\t}\n\n\tgetWordAtIndex(index: number): Char3D[] {\n\t\tconst word: Char3D[] = [];\n\t\tfor (let i = index; i < this.message.length; i++) {\n\t\t\tif (this.message[i].char === ' ') break;\n\n\t\t\tword.push(this.message[i]);\n\t\t}\n\n\t\tfor (let i = index - 1; i >= 0; i--) {\n\t\t\tif (this.message[i].char === ' ') break;\n\n\t\t\tword.splice(0, 0, this.message[i]);\n\t\t}\n\n\t\treturn word;\n\t}\n\n\twordSize(index = 0, travel = -1): number {\n\t\tlet wordSize = 0;\n\t\tlet i = index;\n\n\t\twhile (i >= 0 && i < this.message.length) {\n\t\t\tif (this.message[i].char === ' ') {\n\t\t\t\tif (wordSize === 0) wordSize = this.message[i].charSize;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\twordSize += this.message[i].charSize;\n\t\t\ti += travel;\n\t\t}\n\n\t\tif ((i < 0 || i >= this.message.length) && !this.endLine) {\n\t\t\tif (this.message[index]) {\n\t\t\t\treturn this.message[index].charSize;\n\t\t\t}\n\n\t\t\treturn 999999999;\n\t\t}\n\n\t\tif (wordSize === 0) return 999999999;\n\n\t\treturn wordSize;\n\t}\n\n\tspaceLeft(maxLineSize: number): number {\n\t\treturn maxLineSize - this.nextChar3DPos.x;\n\t}\n\n\tpopChar(index: number = this.message.length - 1): Char3D[] {\n\t\tthis.nextChar3DPos.x -= this.message[index].charSize;\n\t\treturn this.message.splice(index, 1);\n\t}\n\n\tisEmpty(): boolean {\n\t\treturn this.message.length ? false : true;\n\t}\n\n\tupdateNextCharPosY(): void {\n\t\tthis.nextChar3DPos.y = this.yLinePos + this.maxCharSize * this.lineHeight;\n\t}\n\n\tupdateYLinePos(yLinePos: number): void {\n\t\tthis.yLinePos = yLinePos;\n\t\tthis.updateNextCharPosY();\n\t}\n\n\tupdatelineHeight(newlineHeight: number): void {\n\t\tthis.lineHeight = newlineHeight;\n\t\tthis.updateNextCharPosY();\n\t}\n\n\tupdateFontSize(\n\t\tnewfontSize: number,\n\t\tstartIndex: number = 0,\n\t\tendIndex: number = this.message.length - 1\n\t): void {\n\t\tfor (let i = startIndex; i <= endIndex; i += 1) {\n\t\t\tthis.message[i].updateFontSize(newfontSize);\n\t\t}\n\n\t\tthis.maxCharSize = newfontSize;\n\t\tthis.nextChar3DPos.y = this.yLinePos + this.maxCharSize * this.lineHeight;\n\t}\n\n\tcountSpaces(): number {\n\t\tlet count = 0;\n\n\t\tfor (let i = 0; i < this.message.length; i++) {\n\t\t\tif (this.message[i].char === ' ') count += 1;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\talignText(\n\t\ttextOrigin: Vector3,\n\t\tmaxLineSize: number,\n\t\thorizontalAlignment: number,\n\t\tverticalAlignment: number, // TODO this param is not used, maybe delete it and update all API calls of this method\n\t\toffSetY: number\n\t): void {\n\t\tswitch (horizontalAlignment) {\n\t\t\tcase HorizontalAlign.Left:\n\t\t\t\tthis.leftAlign(textOrigin, offSetY);\n\t\t\t\tbreak;\n\n\t\t\tcase HorizontalAlign.Center:\n\t\t\t\tthis.centerAlign(this.spaceLeft(maxLineSize), textOrigin, offSetY);\n\t\t\t\tbreak;\n\n\t\t\tcase HorizontalAlign.Right:\n\t\t\t\tthis.rightAlign(this.spaceLeft(maxLineSize), textOrigin, offSetY);\n\t\t\t\tbreak;\n\n\t\t\tcase HorizontalAlign.Justify:\n\t\t\t\tthis.justifyAlign(this.spaceLeft(maxLineSize), textOrigin, offSetY);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\toffsetCharacters(textOrigin: Vector3, offsetX: number, offsetY: number) {\n\t\tTEMPV2.set(offsetX, offsetY);\n\t\tconst l = this.message.length;\n\t\tfor (let i = 0; i < l; i++) {\n\t\t\tthis.message[i].updatePosition(\n\t\t\t\tthis.message[i].localPosition.add(TEMPV2),\n\t\t\t\ttextOrigin\n\t\t\t);\n\t\t}\n\t}\n\n\tleftAlign(textOrigin: Vector3, offSetY: number): void {\n\t\tthis.align = HorizontalAlign.Left;\n\t\tthis.offsetCharacters(textOrigin, 0, offSetY);\n\t}\n\n\tcenterAlign(spaceLeft: number, textOrigin: Vector3, offSetY: number): void {\n\t\tthis.align = HorizontalAlign.Center;\n\t\tthis.offsetCharacters(textOrigin, spaceLeft / 2, offSetY);\n\t}\n\n\trightAlign(spaceLeft: number, textOrigin: Vector3, offSetY: number): void {\n\t\tthis.align = HorizontalAlign.Right;\n\t\tthis.offsetCharacters(textOrigin, spaceLeft, offSetY);\n\t}\n\n\tjustifyAlign(spaceLeft: number, textOrigin: Vector3, offSetY: number): void {\n\t\tthis.align = HorizontalAlign.Justify;\n\n\t\tif (this.endLine) {\n\t\t\t// If the line is a <endLine> we haven't to handle horizontal alignment.\n\t\t\t// However, we still have to handle vertical alignment.\n\t\t\tthis.offsetCharacters(textOrigin, 0, offSetY);\n\t\t\treturn;\n\t\t}\n\n\t\tconst blankSpaces = this.countSpaces();\n\t\tif (blankSpaces === 0) {\n\t\t\t// If the line have not any spaces (to distribute and justify the remaining space)\n\t\t\t// we haven't to handle horizontal alignment.\n\t\t\t// However, we still have to handle vertical alignment.\n\t\t\tthis.offsetCharacters(textOrigin, 0, offSetY);\n\t\t\treturn;\n\t\t}\n\n\t\tconst baseOffSet = spaceLeft / blankSpaces;\n\t\tlet myOffSet = 0;\n\n\t\tfor (let i = 0; i < this.message.length; i++) {\n\t\t\tif (this.message[i].char === ' ') {\n\t\t\t\tmyOffSet += baseOffSet;\n\t\t\t}\n\n\t\t\tTEMPV2.set(myOffSet, offSetY);\n\t\t\tthis.message[i].updatePosition(\n\t\t\t\tthis.message[i].localPosition.add(TEMPV2),\n\t\t\t\ttextOrigin\n\t\t\t);\n\t\t}\n\t}\n\n\tclone(): this {\n\t\tconst model = new TextLine(\n\t\t\tthis.yLinePos,\n\t\t\tthis.lineHeight,\n\t\t\tthis.maxCharSize\n\t\t);\n\t\tmodel.nextChar3DPos = this.nextChar3DPos.clone();\n\t\tmodel.align = this.align;\n\t\tmodel.endLine = this.endLine;\n\n\t\tfor (let i = 0; i < this.message.length; i++) {\n\t\t\tmodel.message.push(this.message[i].clone());\n\t\t}\n\n\t\treturn model as this;\n\t}\n}\n", "/**\n * @author Guillaume Gouessan\n */\nimport {\n\tBufferGeometry,\n\tDoubleSide,\n\tEventDispatcher,\n\tIntersection,\n\tMatrix3,\n\tRaycaster,\n\tVector3,\n} from 'three';\nimport { VectorShape } from './VectorShape';\nimport {\n\tVectorGeometry,\n\tVectorGeometryInputs,\n} from '../../../geometries/vectors/VectorGeometry';\nimport { VectorSurfaceGeometry } from '../../../geometries/vectors/VectorSurfaceGeometry';\nimport { BasicMaterial, Material } from '../../../materials';\nimport { AbstractMesh } from '../AbstractMesh';\nimport {\n\tBaseInputs,\n\tIGeometry,\n\tNestedPartial,\n} from '../../../geometries/Geometry';\nimport { Geometry } from '../../../geometries';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedVectorObject,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { MeshObjectState } from 'spline-data';\n\nconst normal = new Vector3(0, 0, 1);\nconst worldNormal = new Vector3();\nconst coplanarPoint = new Vector3();\nconst normalMatrix = new Matrix3();\n\nexport class VectorObject extends AbstractMesh {\n\trecursiveSelection: boolean = false;\n\tobjectType: string = 'VectorObject';\n\tshape: VectorShape;\n\teventDispatcher: EventDispatcher = new EventDispatcher();\n\n\tconstructor(\n\t\tgeometry: BufferGeometry = VectorGeometry.create({}),\n\t\tmaterial: Material | Material[] = new BasicMaterial({\n\t\t\tside: DoubleSide,\n\t\t})\n\t) {\n\t\tsuper(geometry, material);\n\n\t\t// Default configuration for shadows\n\t\tthis.castShadow = true;\n\t\tthis.receiveShadow = true;\n\t\tthis.forceComputeSize = true;\n\n\t\tthis.shape = (geometry as IGeometry<VectorGeometryInputs>).userData.shape;\n\n\t\t// SHAPE HOLE TEST\n\t\t// const hole = new VectorShape();\n\t\t// hole.addPoint(hole.createPoint(-10, -10));\n\t\t// hole.addPoint(hole.createPoint(10, -10));\n\t\t// hole.addPoint(hole.createPoint(10, 10));\n\t\t// hole.addPoint(hole.createPoint(-10, 10));\n\t\t// hole.update();\n\t\t// this.shape.shapeHoles.push(hole);\n\n\t\tthis.shape.eventDispatcher?.addEventListener('update', this._onShapeUpdate);\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedVectorObject).objectType = 'VectorObject';\n\t\treturn data;\n\t}\n\n\tfromState(data: MeshObjectState): this {\n\t\tsuper.fromState(data);\n\t\tthis.shape.update();\n\t\treturn this;\n\t}\n\n\t// Need to override default behavior\n\tsetHelperVisibility() {}\n\n\tupdateGeometry<TInputs extends BaseInputs>(\n\t\tinputs: NestedPartial<TInputs>\n\t): void {\n\t\tsuper.updateGeometry(inputs);\n\t\tif ('userData' in this.geometry) {\n\t\t\tconst parameters = (this.geometry.userData as VectorGeometryInputs)\n\t\t\t\t.parameters;\n\t\t\tthis.eventDispatcher.dispatchEvent({\n\t\t\t\ttype: 'geometryUpdate',\n\t\t\t\tparameters,\n\t\t\t});\n\t\t\t// this.objectHelper.subdivisions = parameters.subdivisions;\n\t\t}\n\t}\n\n\tsetShape(shape: VectorShape) {\n\t\tif (this.shape) {\n\t\t\tthis.shape.eventDispatcher?.removeEventListener(\n\t\t\t\t'update',\n\t\t\t\tthis._onShapeUpdate\n\t\t\t);\n\t\t}\n\t\tthis.shape = shape;\n\t\tthis.shape.eventDispatcher?.addEventListener('update', this._onShapeUpdate);\n\t}\n\n\tupdateWorldMatrix(updateParents?: boolean, updateChildren?: boolean) {\n\t\tsuper.updateWorldMatrix(updateParents, updateChildren);\n\n\t\tnormalMatrix.getNormalMatrix(this.matrixWorld);\n\t\tworldNormal.copy(normal).applyMatrix3(normalMatrix).normalize();\n\t\tcoplanarPoint.setFromMatrixPosition(this.matrixWorld);\n\t\t// this.getWorldPosition(coplanarPoint);\n\n\t\tthis.shape.plane.setFromNormalAndCoplanarPoint(worldNormal, coplanarPoint);\n\t}\n\n\t_onShapeUpdate = () => {\n\t\tif (this.geometry instanceof VectorSurfaceGeometry) {\n\t\t\t/*\n\t\t\t\tIf the shape interpolation has more vertices than current geometry can handle, \n\t\t\t\twe need to recreate a geometry with a new maximum (+ new mesh)\n\t\t\t\tThis is more performant than to create a new geometry everytime,\n\t\t\t\talthough it uses slightly more memory than what's needed\n\t\t\t*/\n\t\t\tif (this.geometry.updateFromShape()) {\n\t\t\t\tconst count = this.geometry.drawCount;\n\t\t\t\tconst inputs = this.geometry.userData as VectorGeometryInputs;\n\n\t\t\t\tthis.updateGeometry(\n\t\t\t\t\tObject.assign(this.geometry.userData, {\n\t\t\t\t\t\tparameters: Object.assign(inputs.parameters, {\n\t\t\t\t\t\t\tsurfaceMaxCount: count + 1000,\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.updateGeometry({});\n\t\t}\n\t\t// this.computeSingleBoundingBox();\n\t\tthis.geometry.computeBoundingSphere();\n\t\tthis.geometry.computeBoundingBox();\n\t};\n\n\tclone(recursive?: boolean): this {\n\t\tconst shape = this.shape.clone();\n\t\tconst material = (this.material as Material).clone();\n\t\tconst geometryUserData = (this.geometry as Geometry)\n\t\t\t.userData as NestedPartial<VectorGeometryInputs>;\n\t\tconst geometry = VectorGeometry.create(\n\t\t\tObject.assign({}, geometryUserData, { shape })\n\t\t);\n\n\t\tconst object = new VectorObject(geometry, material).copy(\n\t\t\tthis,\n\t\t\trecursive\n\t\t) as this;\n\n\t\tobject.shape = shape;\n\n\t\tshape.update();\n\n\t\t// object.updateHelperMatrix();\n\n\t\treturn object;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\t// We need to do this to override EntityHelper.raycast and use the actual mesh of this object\n\t\tAbstractMesh.prototype.raycast.call(this, raycaster, intersects);\n\t}\n}\n", "/**\n * @author nisa\n *\n * @remarks\n *\n * references:\n * - {@link https://github.com/mrdoob/three.js/blob/7f43f4e6ef087cec168fea25bb53591052d5ff12/examples/js/cameras/CombinedCamera.js}\n * - {@link https://observablehq.com/@grantcuster/understanding-scale-and-the-three-js-perspective-camera}\n * - {@link https://stackoverflow.com/questions/48758959/what-is-required-to-convert-threejs-perspective-camera-to-orthographic}\n * - {@link https://discourse.threejs.org/t/how-to-switch-camera-between-perspective-and-orthographic-with-similar-zoom/10444}\n * - {@link https://discourse.threejs.org/t/camera-zoom-to-fit-object/936/8}\n */\n\nimport {\n\tCamera,\n\tOrthographicCamera,\n\tPerspectiveCamera,\n\tVector3,\n\tObject3D,\n\tQuaternion,\n} from 'three';\nimport { CombinedCameraHelper } from '../../helpers';\nimport { EntityHelperMixin } from './EntityHelper';\nimport { EntityMixin } from './Entity';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedCombineCamera,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { CameraObjectState, CameraState, CameraType } from 'spline-data';\nimport { omit } from 'lodash-es';\n\nexport type ICombinedCamera = Camera; // guigui: for now it's only an alias but we may have to extend it using &\n\nconst _worldPosition = new Vector3();\nconst _worldDirection = new Vector3();\n\nexport class CombinedCamera\n\textends EntityHelperMixin(EntityMixin(Camera), CombinedCameraHelper)\n\timplements ICombinedCamera\n{\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'CombinedCamera';\n\t_cameraType: 'OrthographicCamera' | 'PerspectiveCamera' =\n\t\t'OrthographicCamera';\n\n\torthoCamera: OrthographicCamera;\n\tperspCamera: PerspectiveCamera;\n\n\twidth: number;\n\theight: number;\n\ttargetOffset = CameraState.DefaultTargetOffset;\n\n\t// orthographic parameters\n\tleft: number;\n\tright: number;\n\ttop: number;\n\tbottom: number;\n\tfar: number;\n\tview: OrthographicCamera['view'];\n\n\t// perspective parameters\n\taspect: number;\n\tfov: number;\n\tfocus: number;\n\tfilmGauge: number;\n\tfilmOffset: number;\n\n\tisUpVectorFlipped: boolean = false;\n\tangleOffsetFromUp: number = 0;\n\n\t// @todo should we use the canvas size instead of the default window size?\n\tstatic createFromState(id: string, data: CameraObjectState): CombinedCamera {\n\t\tconst object = new CombinedCamera().fromState(data);\n\t\tobject.enableHelper = true;\n\t\tobject.objectHelper.update();\n\t\tobject.uuid = id;\n\t\treturn object;\n\t}\n\n\tconstructor(\n\t\twidth = window.innerWidth,\n\t\theight = window.innerHeight,\n\t\tfov = 45,\n\t\tnear?: number,\n\t\tfar = 100000\n\t) {\n\t\tsuper();\n\n\t\tthis.width = width;\n\t\tthis.height = height;\n\n\t\tthis.orthoCamera = new OrthographicCamera(\n\t\t\twidth * -0.5,\n\t\t\twidth * 0.5,\n\t\t\theight * 0.5,\n\t\t\theight * -0.5,\n\t\t\tnear ?? -50000,\n\t\t\tfar\n\t\t);\n\t\tthis.perspCamera = new PerspectiveCamera(\n\t\t\tfov,\n\t\t\twidth / height,\n\t\t\tnear ?? 50,\n\t\t\tfar\n\t\t);\n\n\t\t// orthographic parameters\n\t\tthis.left = this.orthoCamera.left;\n\t\tthis.right = this.orthoCamera.right;\n\t\tthis.top = this.orthoCamera.top;\n\t\tthis.bottom = this.orthoCamera.bottom;\n\t\tthis.far = this.orthoCamera.far;\n\t\tthis.view = this.orthoCamera.view;\n\n\t\t// perspective parameters\n\t\tthis.aspect = this.perspCamera.aspect;\n\t\tthis.fov = this.perspCamera.fov;\n\t\tthis.focus = this.perspCamera.focus;\n\t\tthis.filmGauge = this.perspCamera.filmGauge;\n\t\tthis.filmOffset = this.perspCamera.filmOffset;\n\n\t\tthis.toOrthographic(true);\n\t}\n\n\tget isPerspectiveCamera(): boolean {\n\t\treturn this.cameraType === 'PerspectiveCamera';\n\t}\n\n\tget isOrthographicCamera(): boolean {\n\t\treturn !this.isPerspectiveCamera;\n\t}\n\n\tget cameraType() {\n\t\treturn this._cameraType;\n\t}\n\n\tsetNear(type: CameraType, near: number) {\n\t\tif (type === 'PerspectiveCamera') {\n\t\t\tthis.perspCamera.near = near;\n\t\t} else {\n\t\t\tthis.orthoCamera.near = near;\n\t\t}\n\t}\n\n\tsetZoom(type: CameraType, zoom: number) {\n\t\tif (zoom >= 0) {\n\t\t\tif (type === 'PerspectiveCamera') {\n\t\t\t\tthis.perspCamera.zoom = zoom;\n\t\t\t} else {\n\t\t\t\tthis.orthoCamera.zoom = zoom;\n\t\t\t}\n\t\t}\n\t}\n\n\tset cameraType(cameraType: 'PerspectiveCamera' | 'OrthographicCamera') {\n\t\tif (cameraType === 'PerspectiveCamera') {\n\t\t\tthis.toPerspective();\n\t\t}\n\t\t// We need this condition in order to avoir three.js type setter call in three Camera constructor\n\t\telse if (cameraType === 'OrthographicCamera') {\n\t\t\tthis.toOrthographic();\n\t\t}\n\t}\n\n\tget near(): number {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\treturn this.perspCamera.near;\n\t\t} else {\n\t\t\treturn this.orthoCamera.near;\n\t\t}\n\t}\n\n\tset near(near: number) {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\tthis.perspCamera.near = near;\n\t\t} else {\n\t\t\tthis.orthoCamera.near = near;\n\t\t}\n\t}\n\n\tget zoom() {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\treturn this.perspCamera.zoom;\n\t\t} else {\n\t\t\treturn this.orthoCamera.zoom;\n\t\t}\n\t}\n\n\tset zoom(zoom) {\n\t\tif (zoom >= 0) {\n\t\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\t\tthis.perspCamera.zoom = zoom;\n\t\t\t} else {\n\t\t\t\tthis.orthoCamera.zoom = zoom;\n\t\t\t}\n\t\t}\n\t}\n\n\tlookAt(target: Vector3) {\n\t\tsuper.lookAt(target);\n\n\t\tthis.getWorldPosition(_worldPosition);\n\t\tthis.targetOffset = _worldPosition.distanceTo(target);\n\t}\n\n\tgetTarget(target = new Vector3()): Vector3 {\n\t\tthis.getWorldDirection(_worldDirection);\n\t\tthis.getWorldPosition(_worldPosition);\n\t\t_worldDirection.multiplyScalar(this.targetOffset);\n\t\ttarget.copy(_worldPosition).add(_worldDirection);\n\t\treturn target;\n\t}\n\n\tgetDistanceToTarget() {\n\t\tconst target = this.getTarget();\n\t\tthis.getWorldPosition(_worldPosition);\n\t\treturn _worldPosition.distanceTo(target);\n\t}\n\n\tupdateUp() {\n\t\tconst quaternion = this.getWorldQuaternion(new Quaternion());\n\t\tconst planeNormal = new Vector3(0, 0, 1).applyQuaternion(quaternion);\n\t\tconst upProjectedRot = new Vector3().copy(Object3D.DefaultUp);\n\t\tif (this.isUpVectorFlipped) {\n\t\t\tupProjectedRot.negate();\n\t\t}\n\t\tupProjectedRot.applyQuaternion(quaternion);\n\t\tconst upProjected = new Vector3()\n\t\t\t.copy(Object3D.DefaultUp)\n\t\t\t.projectOnPlane(planeNormal);\n\t\tconst sign =\n\t\t\tnew Vector3()\n\t\t\t\t.crossVectors(upProjected, upProjectedRot)\n\t\t\t\t.dot(planeNormal) >= 0\n\t\t\t\t? 1\n\t\t\t\t: -1;\n\t\tthis.angleOffsetFromUp = upProjected.angleTo(upProjectedRot) * sign;\n\t}\n\n\tgetViewFrontToObject(object: Object3D) {\n\t\tconst target = object.getWorldPosition(new Vector3());\n\t\tconst direction = object.getWorldDirection(new Vector3());\n\t\tconst offset = direction.multiplyScalar(this.targetOffset);\n\t\treturn { position: target.clone().add(offset), target: target };\n\t}\n\n\tgetViewToObject(object: Object3D) {\n\t\tconst target = object.getWorldPosition(new Vector3());\n\t\tconst direction = this.getWorldDirection(new Vector3());\n\t\tconst offset = direction.multiplyScalar(this.targetOffset);\n\t\treturn { position: target.clone().sub(offset), target: target };\n\t}\n\n\tsetViewplaneSize(width: number, height: number) {\n\t\tthis.left = -width * 0.5;\n\t\tthis.right = width * 0.5;\n\t\tthis.top = height * 0.5;\n\t\tthis.bottom = -height * 0.5;\n\t\tthis.aspect = width / height;\n\t\tthis.updateProjectionMatrix();\n\t}\n\n\ttoOrthographic(forceUpdateHelper?: boolean) {\n\t\tthis.orthoCamera.left = this.left;\n\t\tthis.orthoCamera.right = this.right;\n\t\tthis.orthoCamera.top = this.top;\n\t\tthis.orthoCamera.bottom = this.bottom;\n\t\tthis.orthoCamera.view = this.view;\n\t\tthis.orthoCamera.far = this.far;\n\n\t\tthis.orthoCamera.updateProjectionMatrix();\n\t\tthis.projectionMatrix = this.orthoCamera.projectionMatrix;\n\t\tthis.projectionMatrixInverse = this.orthoCamera.projectionMatrixInverse;\n\n\t\tthis._cameraType = 'OrthographicCamera';\n\n\t\tif (this.enableHelper === true || forceUpdateHelper === true) {\n\t\t\tthis.objectHelper.update();\n\t\t}\n\t}\n\n\ttoPerspective(forceUpdateHelper?: boolean) {\n\t\tthis.perspCamera.aspect = this.aspect;\n\t\tthis.perspCamera.fov = this.fov;\n\t\tthis.perspCamera.view = this.view;\n\t\tthis.perspCamera.far = this.far;\n\n\t\tthis.perspCamera.updateProjectionMatrix();\n\t\tthis.projectionMatrix = this.perspCamera.projectionMatrix;\n\t\tthis.projectionMatrixInverse = this.perspCamera.projectionMatrixInverse;\n\n\t\tthis._cameraType = 'PerspectiveCamera';\n\n\t\tif (this.enableHelper === true || forceUpdateHelper === true) {\n\t\t\tthis.objectHelper.update();\n\t\t}\n\t}\n\n\tsetFocalLength(focalLength: number): void {\n\t\tthis.perspCamera.setFocalLength(focalLength);\n\t\tthis.toPerspective();\n\t}\n\n\tgetFocalLength() {\n\t\treturn this.perspCamera.getFocalLength();\n\t}\n\n\tgetEffectiveFOV() {\n\t\treturn this.perspCamera.getEffectiveFOV();\n\t}\n\n\tgetFilmWidth() {\n\t\treturn this.perspCamera.getFilmWidth();\n\t}\n\n\tgetFilmHeight() {\n\t\treturn this.perspCamera.getFilmHeight();\n\t}\n\n\tsetViewOffset(\n\t\tfullWidth: number,\n\t\tfullHeight: number,\n\t\tx: number,\n\t\ty: number,\n\t\twidth: number,\n\t\theight: number\n\t) {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\tthis.perspCamera.setViewOffset(\n\t\t\t\tfullWidth,\n\t\t\t\tfullHeight,\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\twidth,\n\t\t\t\theight\n\t\t\t);\n\t\t} else {\n\t\t\tthis.orthoCamera.setViewOffset(\n\t\t\t\tfullWidth,\n\t\t\t\tfullHeight,\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\twidth,\n\t\t\t\theight\n\t\t\t);\n\t\t}\n\t}\n\n\t// override\n\tclearViewOffset() {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\tthis.perspCamera.clearViewOffset();\n\t\t\tthis.toPerspective();\n\t\t} else {\n\t\t\tthis.orthoCamera.clearViewOffset();\n\t\t\tthis.toOrthographic();\n\t\t}\n\t}\n\n\t// override\n\tupdateProjectionMatrix(forceUpdateHelper?: boolean) {\n\t\tif (this._cameraType === 'PerspectiveCamera') {\n\t\t\tthis.toPerspective(forceUpdateHelper);\n\t\t\t// } else {\n\t\t} else if (this._cameraType === 'OrthographicCamera') {\n\t\t\t// ts: TODO we still need this\n\t\t\tthis.toOrthographic(forceUpdateHelper);\n\t\t}\n\t}\n\n\tupdateMatrixWorld(force?: boolean): void {\n\t\tsuper.updateMatrixWorld(force);\n\t\tthis.matrixWorldInverse.copy(this.matrixWorld).invert();\n\t}\n\n\tupdateWorldMatrix(updateParents: boolean, updateChildren: boolean): void {\n\t\tsuper.updateWorldMatrix(updateParents, updateChildren);\n\t\tthis.matrixWorldInverse.copy(this.matrixWorld).invert();\n\t}\n\n\t// override\n\tcopy(source: this, recursive?: boolean) {\n\t\tsuper.copy(source, recursive);\n\n\t\tthis.orthoCamera.copy(source.orthoCamera);\n\t\tthis.perspCamera.copy(source.perspCamera);\n\n\t\t// orthographic parameters\n\t\tthis.left = source.left;\n\t\tthis.right = source.right;\n\t\tthis.top = source.top;\n\t\tthis.bottom = source.bottom;\n\t\tthis.far = source.far;\n\t\tthis.view = source.view === null ? null : Object.assign({}, source.view);\n\t\tthis._cameraType = source._cameraType;\n\n\t\t// perspective parameters\n\t\tthis.aspect = source.aspect;\n\t\tthis.fov = source.fov;\n\t\tthis.focus = source.focus;\n\t\tthis.filmGauge = source.filmGauge;\n\t\tthis.filmOffset = source.filmOffset;\n\n\t\t// custom parameters\n\t\tthis.targetOffset = source.targetOffset;\n\n\t\tthis.updateProjectionMatrix();\n\n\t\treturn this;\n\t}\n\n\tfromCameraRender(source: this): this {\n\t\tconst orthoCamera = {\n\t\t\tnear: this.orthoCamera.near,\n\t\t\tfar: this.orthoCamera.far,\n\t\t};\n\t\tconst perspCamera = {\n\t\t\tnear: this.perspCamera.near,\n\t\t\tfar: this.perspCamera.far,\n\t\t};\n\n\t\tthis.copy(source);\n\t\tthis.name = '';\n\t\tthis.enableHelper = true;\n\t\tthis.objectHelper.visible = true;\n\t\tthis.orthoCamera.near = orthoCamera.near;\n\t\tthis.orthoCamera.far = orthoCamera.far;\n\t\tthis.perspCamera.near = perspCamera.near;\n\t\tthis.perspCamera.far = perspCamera.far;\n\t\tthis.updateProjectionMatrix();\n\n\t\treturn this;\n\t}\n\n\t// override\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedCombineCamera;\n\n\t\tobject.objectType = 'CombinedCamera';\n\t\tobject.cameraType = this.cameraType;\n\n\t\tobject.targetOffset = this.targetOffset;\n\t\tobject.isUpVectorFlipped = this.isUpVectorFlipped;\n\t\tobject.angleOffsetFromUp = this.angleOffsetFromUp;\n\n\t\t// orthographic parameters\n\t\tobject.left = this.left;\n\t\tobject.right = this.right;\n\t\tobject.top = this.top;\n\t\tobject.bottom = this.bottom;\n\t\tif (this.view !== null) object.view = Object.assign({}, this.view);\n\t\tobject.zoomOrtho = this.orthoCamera.zoom;\n\t\tobject.nearOrtho = this.orthoCamera.near;\n\t\tobject.far = this.far;\n\n\t\t// perspective parameters\n\t\tobject.aspect = this.aspect;\n\t\tobject.fov = this.fov;\n\t\tobject.focus = this.focus;\n\t\tobject.filmGauge = this.filmGauge;\n\t\tobject.filmOffset = this.filmOffset;\n\t\tobject.zoomPersp = this.perspCamera.zoom;\n\t\tobject.nearPersp = this.perspCamera.near;\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedCombineCamera): this {\n\t\tsuper.fromJSON(data);\n\n\t\tthis.cameraType = data.cameraType;\n\n\t\tif (data.targetOffset !== undefined) this.targetOffset = data.targetOffset;\n\t\tif (data.orbitControlsTarget !== undefined) {\n\t\t\tconst worldPosition = this.getWorldPosition(new Vector3());\n\t\t\tconst orbitControlsTarget = new Vector3().fromArray(\n\t\t\t\tdata.orbitControlsTarget\n\t\t\t);\n\t\t\tthis.targetOffset = orbitControlsTarget.distanceTo(worldPosition);\n\t\t} else {\n\t\t\tif (data.targetOffset !== undefined)\n\t\t\t\tthis.targetOffset = data.targetOffset;\n\t\t}\n\n\t\tthis.isUpVectorFlipped = false;\n\t\tthis.angleOffsetFromUp = data.angleOffsetFromUp ?? 0;\n\n\t\t// orthographic parameters\n\t\tif (data.left !== undefined) this.left = data.left;\n\t\tif (data.right !== undefined) this.right = data.right;\n\t\tif (data.top !== undefined) this.top = data.top;\n\t\tif (data.bottom !== undefined) this.bottom = data.bottom;\n\t\tif (data.view !== undefined) this.view = Object.assign({}, data.view);\n\t\tif (data.zoomOrtho !== undefined) this.orthoCamera.zoom = data.zoomOrtho;\n\t\tif (data.nearOrtho !== undefined) this.orthoCamera.near = data.nearOrtho;\n\t\tif (data.far !== undefined) this.far = data.far;\n\n\t\t// perspective parameters\n\t\tif (data.aspect !== undefined) this.aspect = data.aspect;\n\t\tif (data.fov !== undefined) this.fov = data.fov;\n\t\tif (data.focus !== undefined) this.focus = data.focus;\n\t\tif (data.filmGauge !== undefined) this.filmGauge = data.filmGauge;\n\t\tif (data.filmOffset !== undefined) this.filmOffset = data.filmOffset;\n\t\tif (data.zoomPersp !== undefined) this.perspCamera.zoom = data.zoomPersp;\n\t\tif (data.nearPersp !== undefined) this.perspCamera.near = data.nearPersp;\n\n\t\tthis.updateProjectionMatrix();\n\n\t\treturn this;\n\t}\n\n\t// @todo replace fromCameraRender\n\ttoCameraState(omited: string[] = []): Partial<CameraState> {\n\t\tconst data: CameraState = {\n\t\t\ttype: this.cameraType,\n\t\t\tfar: this.far,\n\t\t\torthographic: {\n\t\t\t\tnear: this.orthoCamera.near,\n\t\t\t\tzoom: this.orthoCamera.zoom,\n\t\t\t},\n\t\t\tperspective: {\n\t\t\t\tnear: this.perspCamera.near,\n\t\t\t\tfov: this.perspCamera.fov,\n\t\t\t\tzoom: this.perspCamera.zoom,\n\t\t\t},\n\t\t\tup: this.up.toArray(),\n\t\t\ttargetOffset: this.targetOffset,\n\t\t\tisUpVectorFlipped: this.isUpVectorFlipped,\n\t\t};\n\t\treturn omit(data, omited);\n\t}\n\n\t// @todo merge with lodash\n\tfromCameraState(data: Partial<CameraState>) {\n\t\tconst { orthographic, perspective } = data;\n\n\t\tif (data.type !== undefined) {\n\t\t\tthis.cameraType = data.type;\n\t\t}\n\t\tif (data.far !== undefined) {\n\t\t\tthis.far = data.far;\n\t\t}\n\t\tif (orthographic !== undefined) {\n\t\t\tif (orthographic.near !== undefined) {\n\t\t\t\tthis.orthoCamera.near = orthographic.near;\n\t\t\t}\n\t\t\tif (orthographic.zoom !== undefined) {\n\t\t\t\tthis.orthoCamera.zoom = orthographic.zoom;\n\t\t\t}\n\t\t}\n\t\tif (perspective !== undefined) {\n\t\t\tif (perspective.near !== undefined) {\n\t\t\t\tthis.perspCamera.near = perspective.near;\n\t\t\t}\n\t\t\tif (perspective.fov !== undefined) {\n\t\t\t\tthis.perspCamera.fov = perspective.fov;\n\t\t\t}\n\t\t\tif (perspective.zoom !== undefined) {\n\t\t\t\tthis.perspCamera.zoom = perspective.zoom;\n\t\t\t}\n\t\t}\n\t\tif (data.up !== undefined) {\n\t\t\tthis.up.fromArray(data.up);\n\t\t}\n\t\tif (data.targetOffset !== undefined) {\n\t\t\tthis.targetOffset = data.targetOffset;\n\t\t}\n\t\tif (data.isUpVectorFlipped !== undefined) {\n\t\t\tthis.isUpVectorFlipped = data.isUpVectorFlipped;\n\t\t}\n\t\tthis.updateProjectionMatrix();\n\t\treturn this;\n\t}\n\n\ttoState(omited?: string[]): Partial<CameraObjectState> {\n\t\treturn {\n\t\t\t...super.toState(omited),\n\t\t\t...this.toCameraState(omited),\n\t\t\ttype: this.cameraType,\n\t\t};\n\t}\n\n\tfromState(data: CameraObjectState): this {\n\t\tsuper.fromState(data);\n\t\tthis.fromCameraState(data);\n\t\treturn this;\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { BoxBufferGeometry, Intersection, Object3D, Raycaster } from 'three';\n\nexport type IHelper<T> = Object3D & {\n\tobject: T;\n\traycast(raycaster: Raycaster, intersects: Intersection[]): void;\n\tupdate(): void;\n};\n\ntype Constructor<T> = new (...args: any[]) => T;\ntype CObject3D = Constructor<Object3D>;\n\nexport const HelperMixin = <TBase extends CObject3D>(Base: TBase) =>\n\tclass HelperMixShim extends Base {\n\t\t/**\n\t\t * @deprecated avoid isObjectHelper, use instanceof instead\n\t\t */\n\t\tisObjectHelper: boolean = true;\n\n\t\tstatic geometryHelper: BoxBufferGeometry = new BoxBufferGeometry(\n\t\t\t30,\n\t\t\t30,\n\t\t\t30\n\t\t);\n\t};\n", "/**\n * @author nisa\n */\n\nimport { colorMainBlue, colorYellow } from 'common/src/constants';\nimport {\n\tIntersection,\n\tRaycaster,\n\tCamera,\n\tLineSegments,\n\tBufferGeometry,\n\tLineBasicMaterial,\n\tColor,\n\tVector3,\n\tFloat32BufferAttribute,\n} from 'three';\nimport { ICombinedCamera } from '../objects/entities';\nimport { HelperMixin, IHelper } from './HelperMixin';\nimport { helperRaycast } from './utils';\n\nconst _vector = new Vector3();\nconst _camera = new Camera();\n\ntype pointMap = { [key: string]: number[] };\nclass CameraHelper extends LineSegments {\n\tpointMap;\n\tcamera;\n\n\tconstructor(camera: Camera) {\n\t\tconst geometry = new BufferGeometry();\n\t\tconst material = new LineBasicMaterial({\n\t\t\tcolor: 0xffffff,\n\t\t\tvertexColors: true,\n\t\t\ttoneMapped: false,\n\t\t});\n\n\t\tconst vertices = [] as number[];\n\t\tconst colors = [] as number[];\n\n\t\tconst pointMap = {} as pointMap;\n\n\t\t// colors\n\n\t\tconst colorFrustum = new Color(colorYellow);\n\t\tconst colorCone = new Color(colorYellow);\n\t\tconst colorUp = new Color(colorMainBlue);\n\n\t\t// near\n\n\t\taddLine('n1', 'n2', colorFrustum);\n\t\taddLine('n2', 'n4', colorFrustum);\n\t\taddLine('n4', 'n3', colorFrustum);\n\t\taddLine('n3', 'n1', colorFrustum);\n\n\t\t// far\n\n\t\taddLine('f1', 'f2', colorFrustum);\n\t\taddLine('f2', 'f4', colorFrustum);\n\t\taddLine('f4', 'f3', colorFrustum);\n\t\taddLine('f3', 'f1', colorFrustum);\n\n\t\t// sides\n\n\t\taddLine('n1', 'f1', colorFrustum);\n\t\taddLine('n2', 'f2', colorFrustum);\n\t\taddLine('n3', 'f3', colorFrustum);\n\t\taddLine('n4', 'f4', colorFrustum);\n\n\t\t// cone\n\n\t\taddLine('p', 'n1', colorCone);\n\t\taddLine('p', 'n2', colorCone);\n\t\taddLine('p', 'n3', colorCone);\n\t\taddLine('p', 'n4', colorCone);\n\n\t\t// up\n\n\t\taddLine('u1', 'u2', colorUp);\n\t\taddLine('u2', 'u3', colorUp);\n\t\taddLine('u3', 'u1', colorUp);\n\n\t\t// target\n\n\t\t// addLine( 'c', 't', colorTarget );\n\t\t// addLine( 'p', 'c', colorCross );\n\n\t\t// cross\n\n\t\t// addLine( 'cn1', 'cn2', colorCross );\n\t\t// addLine( 'cn3', 'cn4', colorCross );\n\n\t\t// addLine( 'cf1', 'cf2', colorCross );\n\t\t// addLine( 'cf3', 'cf4', colorCross );\n\n\t\tfunction addLine(a: string, b: string, color: Color) {\n\t\t\taddPoint(a, color);\n\t\t\taddPoint(b, color);\n\t\t}\n\n\t\tfunction addPoint(id: string, color: Color) {\n\t\t\tvertices.push(0, 0, 0);\n\t\t\tcolors.push(color.r, color.g, color.b);\n\n\t\t\tif (pointMap[id] === undefined) {\n\t\t\t\tpointMap[id] = [];\n\t\t\t}\n\n\t\t\tpointMap[id].push(vertices.length / 3 - 1);\n\t\t}\n\n\t\tgeometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tgeometry.setAttribute('color', new Float32BufferAttribute(colors, 3));\n\n\t\tsuper(geometry, material);\n\n\t\tthis.type = 'CameraHelper';\n\n\t\tthis.camera = camera;\n\t\tif ((this.camera as any).updateProjectionMatrix)\n\t\t\t(this.camera as any).updateProjectionMatrix();\n\n\t\tthis.matrix = camera.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\n\t\tthis.pointMap = pointMap;\n\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\tconst geometry = this.geometry;\n\t\tconst pointMap = this.pointMap;\n\n\t\t// the original helper update based on camera's projection matrix, per Alejandro's\n\t\t// request, we are overriding this with a static helper that looks the same for\n\t\t// all cameras. To revert to the original behavior uncomment the original and\n\t\t// delete the override\n\n\t\t// original\n\t\t// const isPerspective = (this.camera as CombinedCamera).isPerspectiveCamera;\n\t\t// _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse);\n\n\t\t// override\n\t\tconst isPerspective = true;\n\t\t_camera.projectionMatrixInverse.elements = [\n\t\t\t0.5112609807824982, -0, -0, -0, -0, 0.41421356237309503, -0, -0, -0, -0,\n\t\t\t-0, -0.099999, -0, -0, -1.0000000000000002, 0.100001,\n\t\t];\n\n\t\tconst w = 1,\n\t\t\th = 1;\n\n\t\t// center / target\n\n\t\t// setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );\n\t\t// setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );\n\n\t\t// near\n\t\t// const nearZ = -1;\n\t\tconst nearZ = isPerspective ? 0.8 : 0.0001;\n\n\t\tsetPoint('n1', pointMap, geometry, _camera, -w, -h, nearZ);\n\t\tsetPoint('n2', pointMap, geometry, _camera, w, -h, nearZ);\n\t\tsetPoint('n3', pointMap, geometry, _camera, -w, h, nearZ);\n\t\tsetPoint('n4', pointMap, geometry, _camera, w, h, nearZ);\n\n\t\t// far\n\n\t\t// const farZ = 1;\n\t\tconst farZ = nearZ;\n\t\tsetPoint('f1', pointMap, geometry, _camera, -w, -h, farZ);\n\t\tsetPoint('f2', pointMap, geometry, _camera, w, -h, farZ);\n\t\tsetPoint('f3', pointMap, geometry, _camera, -w, h, farZ);\n\t\tsetPoint('f4', pointMap, geometry, _camera, w, h, farZ);\n\n\t\t// up\n\n\t\t// const upZ = -1;\n\t\tconst upZ = farZ;\n\t\tconst sc = 0.5;\n\n\t\tsetPoint('u1', pointMap, geometry, _camera, w * 0.7 * sc, h * 1.1, upZ);\n\t\tsetPoint('u2', pointMap, geometry, _camera, -w * 0.7 * sc, h * 1.1, upZ);\n\t\tsetPoint('u3', pointMap, geometry, _camera, 0, h * (1.1 + 0.9 * sc), upZ);\n\n\t\t// cross\n\n\t\t// setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );\n\t\t// setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );\n\t\t// setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );\n\t\t// setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );\n\n\t\t// setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );\n\t\t// setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );\n\t\t// setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );\n\t\t// setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );\n\n\t\tgeometry.getAttribute('position').needsUpdate = true;\n\t}\n\n\tdispose() {\n\t\tthis.geometry.dispose();\n\t\t(this.material as any).dispose();\n\t}\n}\n\nfunction setPoint(\n\tpoint: any,\n\tpointMap: any,\n\tgeometry: BufferGeometry,\n\tcamera: Camera,\n\tx: number,\n\ty: number,\n\tz: number\n) {\n\t_vector.set(x, y, z).unproject(camera);\n\n\tconst points = pointMap[point];\n\n\tif (points !== undefined) {\n\t\tconst position = geometry.getAttribute('position');\n\n\t\tfor (let i = 0, l = points.length; i < l; i++) {\n\t\t\tposition.setXYZ(points[i], _vector.x, _vector.y, _vector.z);\n\t\t}\n\t}\n}\n\nexport class CombinedCameraHelper\n\textends HelperMixin(CameraHelper)\n\timplements IHelper<ICombinedCamera>\n{\n\tconstructor(public object: ICombinedCamera) {\n\t\tsuper(object);\n\n\t\tthis.object = object;\n\t\tthis.name = `CombinedCameraHelper: ${object.uuid}`;\n\t}\n\n\tupdateMatrixWorld(force: boolean) {\n\t\tsuper.updateMatrixWorld(force);\n\t\tthis.updateTarget();\n\t}\n\n\tupdateTarget(): void {\n\t\t// @ts-expect-error\n\t\tconst target = this.object.getTarget();\n\t\tthis.updateWorldMatrix(true, false);\n\t\tthis.worldToLocal(target);\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\thelperRaycast(this.object, this.geometry, raycaster, intersects, true);\n\t}\n}\n", "import {\n\tRay,\n\tSphere,\n\tMatrix4,\n\tObject3D,\n\tRaycaster,\n\tIntersection,\n\tBufferAttribute,\n\tInterleavedBufferAttribute,\n\tVector3,\n\tBufferGeometry,\n} from 'three';\n\nconst _ray: Ray = new Ray();\nconst _sphere: Sphere = new Sphere();\nconst _inverseMatrix: Matrix4 = new Matrix4();\n\n// type IhelperRaycast = <T extends Object3D>(a: T, b: BoxBufferGeometry, c:Raycaster, d: Intersection[]) => void; // nisa: ask\n\nexport const helperRaycast = <T extends Object3D>(\n\tobject: T,\n\tgeometryHelper: BufferGeometry,\n\traycaster: Raycaster,\n\tintersects: Intersection[],\n\tuseLineRaycast: boolean = false\n) => {\n\t// TODO simplify\n\n\tconst geometry = geometryHelper;\n\tconst matrixWorld: Matrix4 = object.matrixWorld;\n\n\t// Checking boundingSphere distance to ray\n\n\tif (geometry.boundingSphere === null) geometry.computeBoundingSphere();\n\n\t_sphere.copy(geometry.boundingSphere!);\n\t_sphere.applyMatrix4(matrixWorld);\n\n\tif (raycaster.ray.intersectsSphere(_sphere) === false) return;\n\n\t//\n\n\t_inverseMatrix.copy(matrixWorld).invert();\n\t// _inverseMatrix.copy(matrixWorld).invert();\n\t_ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix);\n\n\t// Check boundingBox before continuing\n\n\tif (geometry.boundingBox !== null) {\n\t\tif (_ray.intersectsBox(geometry.boundingBox) === false) return;\n\t}\n\n\tlet intersection;\n\n\tlet a, b, c;\n\tconst index = geometry.index!;\n\tconst position = geometry.attributes.position;\n\tconst drawRange = geometry.drawRange;\n\tlet i, il;\n\n\tif (useLineRaycast === false) {\n\t\t// indexed buffer geometry\n\t\tconst start = Math.max(0, drawRange.start);\n\t\tconst end = Math.min(index.count, drawRange.start + drawRange.count);\n\n\t\tfor (i = start, il = end; i < il; i += 3) {\n\t\t\ta = index.getX(i);\n\t\t\tb = index.getX(i + 1);\n\t\t\tc = index.getX(i + 2);\n\n\t\t\tintersection = checkBufferGeometryIntersection(\n\t\t\t\tobject,\n\t\t\t\traycaster,\n\t\t\t\t_ray,\n\t\t\t\tposition,\n\t\t\t\ta,\n\t\t\t\tb,\n\t\t\t\tc\n\t\t\t);\n\n\t\t\tif (intersection) {\n\t\t\t\tintersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics\n\t\t\t\tintersects.push(intersection);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst attributes = geometry.attributes;\n\t\tconst positionAttribute = attributes.position;\n\n\t\tconst vStart = new Vector3();\n\t\tconst vEnd = new Vector3();\n\t\tconst interSegment = new Vector3();\n\t\tconst interRay = new Vector3();\n\t\t// const step = this.isLineSegments ? 2 : 1;\n\t\tconst step = 2;\n\n\t\tconst threshold = 1;\n\t\tconst localThreshold =\n\t\t\tthreshold / ((object.scale.x + object.scale.y + object.scale.z) / 3);\n\t\tconst localThresholdSq = localThreshold * localThreshold;\n\n\t\tconst start = Math.max(0, drawRange.start);\n\t\tconst end = Math.min(\n\t\t\tpositionAttribute.count,\n\t\t\tdrawRange.start + drawRange.count\n\t\t);\n\n\t\tfor (let i = start, l = end - 1; i < l; i += step) {\n\t\t\tvStart.fromBufferAttribute(positionAttribute, i);\n\t\t\tvEnd.fromBufferAttribute(positionAttribute, i + 1);\n\n\t\t\tconst distSq = _ray.distanceSqToSegment(\n\t\t\t\tvStart,\n\t\t\t\tvEnd,\n\t\t\t\tinterRay,\n\t\t\t\tinterSegment\n\t\t\t);\n\n\t\t\tif (distSq > localThresholdSq) continue;\n\n\t\t\tinterRay.applyMatrix4(object.matrixWorld); //Move back to world space for distance calculation\n\n\t\t\tconst distance = raycaster.ray.origin.distanceTo(interRay);\n\n\t\t\tif (distance < raycaster.near || distance > raycaster.far) continue;\n\n\t\t\tintersects.push({\n\t\t\t\tdistance: distance,\n\t\t\t\t// What do we want? intersection point on the ray or on the segment??\n\t\t\t\t// point: raycaster.ray.at( distance ),\n\t\t\t\tpoint: interSegment.clone().applyMatrix4(object.matrixWorld),\n\t\t\t\t// index: i,\n\t\t\t\t// face: null,\n\t\t\t\tobject,\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction checkBufferGeometryIntersection(\n\t\tobject: Object3D,\n\t\traycaster: Raycaster,\n\t\tray: Ray,\n\t\tposition: BufferAttribute | InterleavedBufferAttribute,\n\t\ta: number,\n\t\tb: number,\n\t\tc: number\n\t) {\n\t\tconst _vA = new Vector3();\n\t\tconst _vB = new Vector3();\n\t\tconst _vC = new Vector3();\n\n\t\tconst point = new Vector3();\n\t\tconst _intersectionPointWorld = new Vector3();\n\n\t\t_vA.fromBufferAttribute(position as BufferAttribute, a);\n\t\t_vB.fromBufferAttribute(position as BufferAttribute, b);\n\t\t_vC.fromBufferAttribute(position as BufferAttribute, c);\n\n\t\tconst intersect = ray.intersectTriangle(_vA, _vB, _vC, false, point);\n\n\t\tif (intersect === null) return null;\n\n\t\t_intersectionPointWorld.copy(point);\n\t\t_intersectionPointWorld.applyMatrix4(object.matrixWorld);\n\n\t\tconst distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld);\n\n\t\tif (distance < raycaster.near || distance > raycaster.far) return null;\n\n\t\treturn {\n\t\t\tfaceIndex: 1,\n\t\t\tdistance: distance,\n\t\t\tpoint: _intersectionPointWorld.clone(),\n\t\t\tobject: object,\n\t\t};\n\t}\n};\n", "/**\n * @author nisa\n */\n\nimport {\n\tDirectionalLightHelper as TDirectionalLightHelper,\n\tIntersection,\n\tRaycaster,\n} from 'three';\nimport { ILightDirectional } from '../objects/entities';\nimport { HelperMixin, IHelper } from './HelperMixin';\nimport { helperRaycast } from './utils';\n\nexport class DirectionalLightHelper\n\textends HelperMixin(TDirectionalLightHelper)\n\timplements IHelper<ILightDirectional> {\n\tconstructor(\n\t\tpublic object: ILightDirectional,\n\t\tsize: number = 15,\n\t\tcolor: number = 0x999999\n\t) {\n\t\tsuper(object, size, color);\n\n\t\tthis.name = `DirectionalLightHelper: ${object.uuid}`;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\thelperRaycast(\n\t\t\tthis.object,\n\t\t\tDirectionalLightHelper.geometryHelper,\n\t\t\traycaster,\n\t\t\tintersects\n\t\t);\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { AxesHelper, Intersection, Raycaster } from 'three';\nimport { IEmptyObject } from '../objects/entities';\nimport { HelperMixin, IHelper } from './HelperMixin';\nimport { helperRaycast } from './utils';\n\nexport class EmptyObjectHelper\n\textends HelperMixin(AxesHelper)\n\timplements IHelper<IEmptyObject> {\n\tconstructor(public object: IEmptyObject, size: number = 15) {\n\t\tsuper(size);\n\n\t\tthis.object.updateMatrixWorld();\n\t\tthis.name = `EmptyObjectHelper: ${object.uuid}`;\n\n\t\tthis.matrix = object.matrixWorld;\n\t\tthis.matrixAutoUpdate = false;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\thelperRaycast(\n\t\t\tthis.object,\n\t\t\tEmptyObjectHelper.geometryHelper,\n\t\t\traycaster,\n\t\t\tintersects\n\t\t);\n\t}\n\n\t// Does not exist on AxesHelper but needed to be considered a Helper\n\tupdate() {}\n}\n", "/**\n * @author nisa\n */\n\nimport {\n\tIntersection,\n\tPointLightHelper as TPointLightHelper,\n\tRaycaster,\n} from 'three';\nimport { ILightPoint } from '../objects/entities';\nimport { HelperMixin, IHelper } from './HelperMixin';\nimport { helperRaycast } from './utils';\n\nexport class PointLightHelper\n\textends HelperMixin(TPointLightHelper)\n\timplements IHelper<ILightPoint> {\n\tconstructor(\n\t\tpublic object: ILightPoint,\n\t\tsphereSize: number = 15,\n\t\tcolor: number = 0x666666\n\t) {\n\t\tsuper(object, sphereSize, color);\n\n\t\tthis.name = `PointLightHelper: ${object.uuid}`;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\thelperRaycast(\n\t\t\tthis.object,\n\t\t\tPointLightHelper.geometryHelper,\n\t\t\traycaster,\n\t\t\tintersects\n\t\t);\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport {\n\tIntersection,\n\tLineBasicMaterial,\n\tRaycaster,\n\tSpotLightHelper as TSpotLightHelper,\n\tVector3,\n} from 'three';\nimport { ILightSpot } from '../objects/entities';\nimport { HelperMixin, IHelper } from './HelperMixin';\nimport { helperRaycast } from './utils';\n\nexport class SpotLightHelper\n\textends HelperMixin(TSpotLightHelper)\n\timplements IHelper<ILightSpot> {\n\tprivate static _vector: Vector3 = new Vector3();\n\n\tconstructor(public object: ILightSpot, color: number = 0x666666) {\n\t\tsuper(object, color);\n\n\t\tthis.name = `SpotLightHelper: ${object.uuid}`;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\thelperRaycast(\n\t\t\tthis.object,\n\t\t\tSpotLightHelper.geometryHelper,\n\t\t\traycaster,\n\t\t\tintersects\n\t\t);\n\t}\n\n\tupdate() {\n\t\tif (this.object !== undefined) {\n\t\t\t// patch:\n\t\t\t// this.object.updateMatrixWorld(); // remove to prevent loop, light.updateMatrixWorld is calling this method\n\n\t\t\tconst _vector = SpotLightHelper._vector; // nisa: we can avoid this using a fork\n\n\t\t\tconst coneLength = this.object.distance ? this.object.distance : 1000;\n\t\t\tconst coneWidth = coneLength * Math.tan(this.object.angle);\n\n\t\t\tthis.cone.scale.set(coneWidth, coneWidth, coneLength);\n\n\t\t\t_vector.setFromMatrixPosition(this.object.target.matrixWorld);\n\n\t\t\tthis.cone.lookAt(_vector);\n\n\t\t\tconst color = this.color !== undefined ? this.color : this.light.color;\n\t\t\tif (this.cone.material instanceof Array) {\n\t\t\t\tfor (let i = 0, l = this.cone.material.length; i < l; i++) {\n\t\t\t\t\t(<LineBasicMaterial>this.cone.material[i]).color.set(color);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t(<LineBasicMaterial>this.cone.material).color.set(color);\n\t\t\t}\n\t\t}\n\t}\n}\n", "import {\n\tBufferGeometry,\n\tRaycaster,\n\tIntersection,\n\tPerspectiveCamera,\n\tOrthographicCamera,\n} from 'three';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedEntity,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { IHelper } from '../../helpers';\nimport { EntityMixin, HelperableEntity, isEntity } from './Entity';\nimport { isHelperableEntity } from './utils';\nimport { BaseLightState } from 'spline-data';\nimport { LightDirectional, LightPoint, LightSpot } from '.';\nimport { getSharedColorData } from '../../shared/utils';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\n\nexport type CHelper<T> = {\n\tnew (...args: any[]): T;\n\n\tgeometryHelper: BufferGeometry;\n};\n\ntype EntityMixinType = typeof EntityMixin;\n\nexport const EntityHelperMixin = <\n\tTBase extends ReturnType<EntityMixinType>,\n\tTHelp extends IHelper<HelperableEntity>\n>(\n\tBase: TBase,\n\tHelp: CHelper<THelp>\n) =>\n\tclass EntityHelperMixinShim extends Base {\n\t\tobjectHelper: THelp = new Help(this);\n\t\tenableHelper: boolean = false;\n\n\t\tset visibility(value: boolean) {\n\t\t\tthis.visible = value;\n\t\t\tthis.setHelperVisibility(value);\n\t\t\tthis.setHelperChildrenVisibility(value);\n\t\t}\n\n\t\tget visibility(): boolean {\n\t\t\treturn this.visible;\n\t\t}\n\n\t\tget geometryHelper(): BufferGeometry {\n\t\t\treturn Help.geometryHelper;\n\t\t}\n\n\t\tsetHelperVisibility(value: boolean) {\n\t\t\tthis.objectHelper.visible = value;\n\t\t}\n\n\t\tsetHelperChildrenVisibility(value: boolean) {\n\t\t\tfor (const child of this.children) {\n\t\t\t\tif (isEntity(child)) {\n\t\t\t\t\tchild.traverseEntity((object) => {\n\t\t\t\t\t\tif (isHelperableEntity(object) && object.visible) {\n\t\t\t\t\t\t\tobject.objectHelper.visible = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\traycast(raycaster: Raycaster, intersects: Intersection[]): void {\n\t\t\tthis.objectHelper.raycast(raycaster, intersects);\n\t\t}\n\n\t\tcopy(source: this, recursive: boolean = true): this {\n\t\t\tsuper.copy(source, recursive);\n\n\t\t\t// check if exist because there is no helper in the source from customParseObject\n\t\t\tif (source.enableHelper !== undefined)\n\t\t\t\tthis.enableHelper = source.enableHelper;\n\t\t\tif (source.objectHelper !== undefined)\n\t\t\t\tthis.objectHelper.visible = source.objectHelper.visible;\n\n\t\t\treturn this;\n\t\t}\n\n\t\ttoJSON(meta?: Meta): SerializedBase {\n\t\t\tconst data = super.toJSON(meta);\n\t\t\tconst object = data.object as SerializedEntity;\n\t\t\tobject.enableHelper = this.enableHelper;\n\n\t\t\treturn data;\n\t\t}\n\n\t\tfromJSON(data: SerializedEntity): this {\n\t\t\tsuper.fromJSON(data);\n\n\t\t\tif (data.enableHelper !== undefined) this.enableHelper = true;\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// @todo create a AbstractLight\n\t\tfromLightState(\n\t\t\tdata: Partial<BaseLightState>,\n\t\t\tsharedAssets: SharedAssetsManager\n\t\t): this {\n\t\t\tif (\n\t\t\t\tthis.objectType === 'LightDirectional' ||\n\t\t\t\tthis.objectType === 'LightPoint' ||\n\t\t\t\tthis.objectType === 'LightSpot'\n\t\t\t) {\n\t\t\t\tconst object = this as unknown as\n\t\t\t\t\t| LightDirectional\n\t\t\t\t\t| LightPoint\n\t\t\t\t\t| LightSpot;\n\t\t\t\tif (data.color !== undefined) {\n\t\t\t\t\tobject.color = getSharedColorData(data.color, sharedAssets);\n\t\t\t\t}\n\t\t\t\tif (data.intensity !== undefined) {\n\t\t\t\t\tobject.intensity = data.intensity;\n\t\t\t\t}\n\t\t\t\tif (data.depth !== undefined) {\n\t\t\t\t\t(object.shadow.camera as PerspectiveCamera | OrthographicCamera).far =\n\t\t\t\t\t\tdata.depth;\n\t\t\t\t\tobject.shadow.needsUpdate = true;\n\t\t\t\t}\n\t\t\t\tif (data.shadows !== undefined) {\n\t\t\t\t\tthis.castShadow = data.shadows;\n\t\t\t\t}\n\t\t\t\tif (data.helper !== undefined) {\n\t\t\t\t\tthis.enableHelper = data.helper;\n\t\t\t\t\tobject.gizmos.shadowmap.visible = data.helper;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t};\n", "/**\n * @author nisa\n */\n\nimport { EmptyObjectState } from 'spline-data';\nimport { Group } from 'three';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedEmptyObject,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { EmptyObjectHelper } from '../../helpers';\nimport { EntityMixin } from './Entity';\nimport { EntityHelperMixin } from './EntityHelper';\n\nexport type IEmptyObject = Group; // guigui: for now it's only an alias but we may have to extend it using &\n\nexport class EmptyObject\n\textends EntityHelperMixin(EntityMixin(Group), EmptyObjectHelper)\n\timplements IEmptyObject\n{\n\t// @deprecated use instanceof instead of this\n\treadonly objectType = 'EmptyObject';\n\n\tstatic createFromState(id: string, data: EmptyObjectState): EmptyObject {\n\t\tconst object = new EmptyObject().fromState(data);\n\t\tobject.uuid = id;\n\t\tobject.enableHelper = true;\n\t\tobject.objectHelper.update();\n\t\treturn object;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedEmptyObject).objectType = 'EmptyObject';\n\n\t\treturn data;\n\t}\n}\n", "/**\n * @author sciecode\n * @author nisa\n */\n\nimport { DirectionalLightState, LightObjectState } from 'spline-data';\nimport { DirectionalLight, CameraHelper, OrthographicCamera } from 'three';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedLightDirectional,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { DirectionalLightHelper } from '../../helpers';\nimport { EntityMixin } from './Entity';\nimport { EntityHelperMixin } from './EntityHelper';\nimport { setLightSize } from './utils';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\n\nexport type ILightDirectional = DirectionalLight; // guigui: for now it's only an alias but we may have to extend it using &\n\nexport class LightDirectional\n\textends EntityHelperMixin(\n\t\tEntityMixin(DirectionalLight),\n\t\tDirectionalLightHelper\n\t)\n\timplements ILightDirectional\n{\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'LightDirectional';\n\t// Storage for all gizmos handled by this object\n\t_gizmos: { [type: string]: CameraHelper } = {};\n\n\tview?: {\n\t\tenabled: boolean;\n\t\tfullWidth: number;\n\t\tfullHeight: number;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\twidth: number;\n\t\theight: number;\n\t};\n\n\tstatic createFromState(\n\t\tid: string,\n\t\tdata: LightObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t): LightDirectional {\n\t\tconst object = new LightDirectional().fromState(data, sharedAssets);\n\t\tobject.uuid = id;\n\t\treturn object;\n\t}\n\n\tconstructor(...args: any[]) {\n\t\tsuper(...args);\n\n\t\tthis.castShadow = true;\n\n\t\tthis.shadow.mapSize.width = 1024;\n\t\tthis.shadow.mapSize.height = 1024;\n\n\t\t// Configure the shadow-map to some default acceptable parameters\n\t\tconst shadowmapConfig = this.shadow;\n\t\tconst viewFrustum = shadowmapConfig.camera;\n\t\tviewFrustum.top = 1250.0;\n\t\tviewFrustum.bottom = -1250.0;\n\t\tviewFrustum.right = 1250.0;\n\t\tviewFrustum.left = -1250.0;\n\t\tviewFrustum.near = 1.0;\n\t\tviewFrustum.far = 2500.0;\n\n\t\t// Add a gizmo to visualize the view-frustum handled by the shadow-map\n\t\tconst shadowmapViewGizmo = new CameraHelper(this.shadow.camera);\n\t\tshadowmapViewGizmo.visible = false;\n\t\tthis._gizmos['shadowmap'] = shadowmapViewGizmo;\n\n\t\tthis.update();\n\t}\n\n\tget gizmos() {\n\t\treturn this._gizmos;\n\t}\n\n\tshowGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.visible = true;\n\t\t\t}\n\t\t}\n\t}\n\n\thideGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate() {\n\t\t// Update the current frustum of the shadow volume\n\t\tthis.shadow.camera.updateProjectionMatrix();\n\t\t// Update gizmos, as they depend on this object as its parent\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.update();\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateMatrixWorld(force?: boolean): void {\n\t\tsuper.updateMatrixWorld(force);\n\t\tif (this.enableHelper === true && this.objectHelper.visible === true)\n\t\t\tthis.objectHelper.update();\n\t}\n\n\tcopy(source: this, recursive: boolean = true): this {\n\t\tsuper.copy(source, recursive);\n\n\t\t// use AbstractLight?\n\t\tthis.color.copy(source.color);\n\t\tthis.intensity = source.intensity;\n\n\t\tthis.target = source.target.clone();\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedLightDirectional;\n\n\t\tobject.objectType = 'LightDirectional';\n\n\t\t// use AbstractLight?\n\t\tobject.color = this.color.getHex();\n\t\tobject.intensity = this.intensity;\n\n\t\tobject.shadow =\n\t\t\tthis.shadow.toJSON() as SerializedLightDirectional['shadow'];\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedLightDirectional): this {\n\t\tsuper.fromJSON(data);\n\n\t\t// use AbstractLight?\n\t\tthis.color.set(data.color);\n\t\tthis.intensity = data.intensity;\n\n\t\tthis.shadow.normalBias = data.shadow.normalBias ?? 0;\n\t\tthis.shadow.radius = data.shadow.radius;\n\t\tthis.shadow.mapSize.fromArray(data.shadow.mapSize);\n\n\t\tconst camera: OrthographicCamera = this.shadow.camera;\n\t\tconst cameraData = data.shadow.camera;\n\t\tcamera.near = cameraData.near;\n\t\tcamera.far = cameraData.far;\n\t\tcamera.zoom = cameraData.zoom;\n\t\tcamera.left = cameraData.left;\n\t\tcamera.right = cameraData.right;\n\t\tcamera.top = cameraData.top;\n\t\tcamera.bottom = cameraData.bottom;\n\t\tif (cameraData.view !== undefined)\n\t\t\tcamera.view = Object.assign({}, cameraData.view);\n\n\t\treturn this;\n\t}\n\n\tfromDirectionalLightState(\n\t\tdata: Partial<DirectionalLightState>,\n\t\tsharedAssets: SharedAssetsManager\n\t): this {\n\t\tconst shadowDirty =\n\t\t\t(data.depth !== undefined && data.depth !== this.shadow.camera.far) ||\n\t\t\t(data.size !== undefined && data.size / 2 !== this.shadow.camera.right);\n\n\t\tsuper.fromLightState(data, sharedAssets);\n\t\tif (data.size !== undefined) {\n\t\t\tsetLightSize(this, data.size);\n\t\t}\n\n\t\tif (shadowDirty) this.update();\n\n\t\treturn this;\n\t}\n\n\tfromState(data: LightObjectState, sharedAssets: SharedAssetsManager): this {\n\t\tsuper.fromState(data);\n\t\tthis.fromDirectionalLightState(data as DirectionalLightState, sharedAssets);\n\t\treturn this;\n\t}\n}\n", "/**\n * @author sciecode\n * @author nisa\n */\n\nimport { LightObjectState, PointLightState } from 'spline-data';\nimport {\n\tPointLight,\n\tVector3,\n\tBox3,\n\tBox3Helper,\n\tColor,\n\tPerspectiveCamera,\n} from 'three';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedLightPoint,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { PointLightHelper } from '../../helpers';\nimport { EntityMixin } from './Entity';\nimport { EntityHelperMixin } from './EntityHelper';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\n\nexport type ILightPoint = PointLight; // guigui: for now it's only an alias but we may have to extend it using &\n\nexport class LightPoint\n\textends EntityHelperMixin(EntityMixin(PointLight), PointLightHelper)\n\timplements ILightPoint\n{\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'LightPoint';\n\t// Storage for all gizmos handled by this object\n\t_gizmos: { [type: string]: Box3Helper } = {};\n\n\tview?: {\n\t\tenabled: boolean;\n\t\tfullWidth: number;\n\t\tfullHeight: number;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\twidth: number;\n\t\theight: number;\n\t};\n\n\t// @todo replace create\n\tstatic createFromState(\n\t\tid: string,\n\t\tdata: LightObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t): LightPoint {\n\t\tconst object = new LightPoint().fromState(data, sharedAssets);\n\t\tobject.uuid = id;\n\t\treturn object;\n\t}\n\n\tconstructor(...args: any[]) {\n\t\tsuper(...args);\n\n\t\tthis.castShadow = true;\n\n\t\tthis.shadow.mapSize.width = 1024;\n\t\tthis.shadow.mapSize.height = 1024;\n\n\t\t// Configure the shadow-map to some default acceptable parameters\n\t\tconst shadowmapConfig = this.shadow;\n\t\tconst viewFrustum = shadowmapConfig.camera;\n\t\t// Keep 90\u00B0 and aspect-1 for the frustums to generate a cubemap\n\t\tviewFrustum.fov = 90;\n\t\tviewFrustum.aspect = 1;\n\t\tviewFrustum.near = 100.0;\n\t\tviewFrustum.far = 2500.0;\n\n\t\t// Add a gizmo to visualize the view-frustum handled by the shadow-map\n\t\tconst vMin = new Vector3(\n\t\t\t-viewFrustum.far + this.position.x,\n\t\t\t-viewFrustum.far + this.position.y,\n\t\t\t-viewFrustum.far + this.position.z\n\t\t);\n\t\tconst vMax = new Vector3(\n\t\t\tviewFrustum.far + this.position.x,\n\t\t\tviewFrustum.far + this.position.y,\n\t\t\tviewFrustum.far + this.position.z\n\t\t);\n\t\tconst shadpwmapViewBox = new Box3(vMin, vMax);\n\t\tconst shadowmapViewGizmo = new Box3Helper(\n\t\t\tshadpwmapViewBox,\n\t\t\tnew Color(0xffaa00)\n\t\t);\n\t\tshadowmapViewGizmo.visible = false;\n\t\tthis._gizmos['shadowmap'] = shadowmapViewGizmo;\n\n\t\tthis.update();\n\t}\n\n\tget gizmos() {\n\t\treturn this._gizmos;\n\t}\n\n\tshowGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof Box3Helper) {\n\t\t\t\tgizmo.visible = true;\n\t\t\t}\n\t\t}\n\t}\n\n\thideGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof Box3Helper) {\n\t\t\t\tgizmo.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate() {\n\t\tif (this.shadow) {\n\t\t\t// Update the current frustum of the shadow volume\n\t\t\tthis.shadow.camera.updateProjectionMatrix();\n\t\t\tif (this._gizmos) {\n\t\t\t\t// Update gizmos, as they depend on this object as its parent\n\t\t\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\t\t\tfor (const key in this._gizmos) {\n\t\t\t\t\tconst gizmo = this._gizmos[key];\n\t\t\t\t\tif (gizmo instanceof Box3Helper) {\n\t\t\t\t\t\tconst viewFrustum = this.shadow.camera;\n\t\t\t\t\t\tconst vMin = new Vector3(\n\t\t\t\t\t\t\t-viewFrustum.far + this.position.x,\n\t\t\t\t\t\t\t-viewFrustum.far + this.position.y,\n\t\t\t\t\t\t\t-viewFrustum.far + this.position.z\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst vMax = new Vector3(\n\t\t\t\t\t\t\tviewFrustum.far + this.position.x,\n\t\t\t\t\t\t\tviewFrustum.far + this.position.y,\n\t\t\t\t\t\t\tviewFrustum.far + this.position.z\n\t\t\t\t\t\t);\n\t\t\t\t\t\tgizmo.box.set(vMin, vMax);\n\t\t\t\t\t\tgizmo.updateMatrixWorld(true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateMatrixWorld(force?: boolean): void {\n\t\tsuper.updateMatrixWorld(force);\n\t\tif (this.enableHelper === true && this.objectHelper.visible === true)\n\t\t\tthis.objectHelper.update();\n\t}\n\n\tcopy(source: this, recursive: boolean = true): this {\n\t\tsuper.copy(source, recursive);\n\n\t\t// use AbstractLight?\n\t\tthis.color.copy(source.color);\n\t\tthis.intensity = source.intensity;\n\n\t\tthis.distance = source.distance;\n\t\tthis.decay = source.decay;\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedLightPoint;\n\n\t\tobject.objectType = 'LightPoint';\n\n\t\t// use AbstractLight?\n\t\tobject.color = this.color.getHex();\n\t\tobject.intensity = this.intensity;\n\n\t\tobject.distance = this.distance;\n\t\tobject.decay = this.decay;\n\t\tobject.shadow = this.shadow.toJSON() as SerializedLightPoint['shadow'];\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedLightPoint): this {\n\t\tsuper.fromJSON(data);\n\n\t\t// use AbstractLight?\n\t\tthis.color.set(data.color);\n\t\tthis.intensity = data.intensity;\n\n\t\tthis.distance = data.distance;\n\t\tthis.decay = data.decay;\n\n\t\tthis.shadow.normalBias = data.shadow.normalBias ?? 0;\n\t\tthis.shadow.radius = data.shadow.radius;\n\t\tthis.shadow.mapSize.fromArray(data.shadow.mapSize ?? [512, 512]); // we need to have defaults because three.js does not save the value when it's 512\n\t\tif (this.shadow.map) {\n\t\t\t// To be able to dynamically change the resolution of the shadow, we have to dispose\n\t\t\t// @ts-ignore\n\t\t\tthis.shadow.map.dispose();\n\t\t\t// @ts-ignore\n\t\t\tthis.shadow.map = null;\n\t\t}\n\n\t\tconst camera: PerspectiveCamera = this.shadow.camera;\n\t\tconst cameraData = data.shadow.camera;\n\t\tcamera.near = cameraData.near;\n\t\tcamera.far = cameraData.far;\n\t\tcamera.zoom = cameraData.zoom;\n\t\tcamera.fov = cameraData.fov;\n\t\tcamera.focus = cameraData.focus;\n\t\tcamera.aspect = cameraData.aspect;\n\t\tcamera.filmGauge = cameraData.filmGauge;\n\t\tcamera.filmOffset = cameraData.filmOffset;\n\t\tif (cameraData.view !== undefined)\n\t\t\tcamera.view = Object.assign({}, cameraData.view);\n\n\t\treturn this;\n\t}\n\n\tfromPointLightState(\n\t\tdata: Partial<PointLightState>,\n\t\tsharedAssets: SharedAssetsManager\n\t): this {\n\t\tsuper.fromLightState(data, sharedAssets);\n\t\tif (data.distance !== undefined) {\n\t\t\tthis.distance = data.distance;\n\t\t}\n\t\tif (data.decay !== undefined) {\n\t\t\tthis.decay = data.decay;\n\t\t}\n\t\tif (data.shadowRadius !== undefined) {\n\t\t\tthis.shadow.radius = data.shadowRadius;\n\t\t}\n\t\tif (data.shadowResolution !== undefined) {\n\t\t\tthis.shadow.mapSize.set(data.shadowResolution, data.shadowResolution);\n\t\t\tif (this.shadow.map) {\n\t\t\t\t// To be able to dynamically change the resolution of the shadow, we have to dispose\n\t\t\t\t// @ts-ignore\n\t\t\t\tthis.shadow.map.dispose();\n\t\t\t\t// @ts-ignore\n\t\t\t\tthis.shadow.map = null;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tfromState(data: LightObjectState, sharedAssets: SharedAssetsManager): this {\n\t\tsuper.fromState(data);\n\t\tthis.fromPointLightState(data as PointLightState, sharedAssets);\n\t\treturn this;\n\t}\n}\n", "/**\n * @author sciecode\n * @author nisa\n */\n\nimport { LightObjectState, SpotLightState } from 'spline-data';\nimport {\n\tSpotLight,\n\tCameraHelper,\n\tMathUtils as TMath,\n\tPerspectiveCamera,\n\tVector3,\n\tQuaternion,\n} from 'three';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedLightSpot,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport { SpotLightHelper } from '../../helpers';\nimport { EntityMixin } from './Entity';\nimport { EntityHelperMixin } from './EntityHelper';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\n\nconst _v1 = new Vector3();\nconst _position = new Vector3();\nconst _quaternion = new Quaternion();\n\nexport type ILightSpot = SpotLight; // guigui: for now it's only an alias but we may have to extend it using &\n\nexport class LightSpot\n\textends EntityHelperMixin(EntityMixin(SpotLight), SpotLightHelper)\n\timplements ILightSpot\n{\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'LightSpot';\n\t// Storage for all gizmos handled by this object\n\t_gizmos: { [type: string]: CameraHelper } = {};\n\n\tview?: {\n\t\tenabled: boolean;\n\t\tfullWidth: number;\n\t\tfullHeight: number;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\twidth: number;\n\t\theight: number;\n\t};\n\n\tstatic createFromState(\n\t\tid: string,\n\t\tdata: LightObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t): LightSpot {\n\t\tconst object = new LightSpot().fromState(data, sharedAssets);\n\t\tobject.uuid = id;\n\t\treturn object;\n\t}\n\n\tconstructor(...args: any[]) {\n\t\tsuper(...args);\n\n\t\tthis.castShadow = true;\n\n\t\tthis.shadow.mapSize.width = 1024;\n\t\tthis.shadow.mapSize.height = 1024;\n\n\t\t// Configure the shadow-map to some default acceptable parameters\n\t\tconst shadowmapConfig = this.shadow;\n\t\tconst viewFrustum = shadowmapConfig.camera;\n\t\t// Keep the frustum to the same size as the spotlight-angle\n\t\tviewFrustum.fov = TMath.RAD2DEG * 2 * this.angle;\n\t\tviewFrustum.aspect = 1;\n\t\tviewFrustum.near = 100.0;\n\t\tviewFrustum.far = 2500.0;\n\n\t\t// Add a gizmo to visualize the view-frustum handled by the shadow-map\n\t\tconst shadowmapViewGizmo = new CameraHelper(this.shadow.camera);\n\t\tshadowmapViewGizmo.visible = false;\n\t\tthis._gizmos['shadowmap'] = shadowmapViewGizmo;\n\n\t\tthis.update();\n\t}\n\n\tget gizmos() {\n\t\treturn this._gizmos;\n\t}\n\n\tshowGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.visible = true;\n\t\t\t}\n\t\t}\n\t}\n\n\thideGizmos() {\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdate() {\n\t\t// Update the current frustum of the shadow volume\n\t\tthis.shadow.camera.updateProjectionMatrix();\n\t\t// Update gizmos, as they depend on this object as its parent\n\t\t// for (const [_, gizmo] of Object.entries(this._gizmos)) {\n\t\tfor (const key in this._gizmos) {\n\t\t\tconst gizmo = this._gizmos[key];\n\t\t\tif (gizmo instanceof CameraHelper) {\n\t\t\t\tgizmo.update();\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateMatrixWorld(force?: boolean): void {\n\t\tsuper.updateMatrixWorld(force);\n\n\t\t// update target\n\t\t_position.setFromMatrixPosition(this.matrixWorld);\n\t\t_quaternion.setFromRotationMatrix(this.matrixWorld);\n\t\t_v1\n\t\t\t.copy(this.up)\n\t\t\t.applyQuaternion(_quaternion)\n\t\t\t.negate()\n\t\t\t.multiplyScalar(this.distance);\n\t\tthis.target.position.copy(_position).add(_v1);\n\t\tthis.target.updateMatrixWorld();\n\t\t//\n\n\t\tif (this.enableHelper === true && this.objectHelper.visible === true)\n\t\t\tthis.objectHelper.update();\n\t}\n\n\tcopy(source: this, recursive: boolean = true): this {\n\t\tsuper.copy(source, recursive);\n\n\t\t// use AbstractLight?\n\t\tthis.color.copy(source.color);\n\t\tthis.intensity = source.intensity;\n\n\t\tthis.distance = source.distance;\n\t\tthis.angle = source.angle;\n\t\tthis.penumbra = source.penumbra;\n\t\tthis.decay = source.decay;\n\t\tthis.target = source.target.clone();\n\t\tthis.shadow = source.shadow.clone();\n\n\t\treturn this;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\tconst object = data.object as SerializedLightSpot;\n\n\t\tobject.objectType = 'LightSpot';\n\n\t\t// use AbstractLight?\n\t\tobject.color = this.color.getHex();\n\t\tobject.intensity = this.intensity;\n\n\t\tobject.distance = this.distance;\n\t\tobject.angle = this.angle;\n\t\tobject.decay = this.decay;\n\t\tobject.penumbra = this.penumbra;\n\t\tobject.shadow = this.shadow.toJSON() as SerializedLightSpot['shadow'];\n\n\t\treturn data;\n\t}\n\n\tfromJSON(data: SerializedLightSpot): this {\n\t\tsuper.fromJSON(data);\n\n\t\t// use AbstractLight?\n\t\tthis.color.set(data.color);\n\t\tthis.intensity = data.intensity;\n\n\t\tthis.distance = data.distance;\n\t\tthis.angle = data.angle;\n\t\tthis.decay = data.decay;\n\t\tthis.penumbra = data.penumbra;\n\n\t\tthis.shadow.normalBias = data.shadow.normalBias ?? 0;\n\t\tthis.shadow.radius = data.shadow.radius;\n\t\tthis.shadow.mapSize.fromArray(data.shadow.mapSize);\n\n\t\tconst camera: PerspectiveCamera = this.shadow.camera;\n\t\tconst cameraData = data.shadow.camera;\n\t\tcamera.near = cameraData.near;\n\t\tcamera.far = cameraData.far;\n\t\tcamera.zoom = cameraData.zoom;\n\t\tcamera.fov = cameraData.fov;\n\t\tcamera.focus = cameraData.focus;\n\t\tcamera.aspect = cameraData.aspect;\n\t\tcamera.filmGauge = cameraData.filmGauge;\n\t\tcamera.filmOffset = cameraData.filmOffset;\n\t\tif (cameraData.view !== undefined)\n\t\t\tcamera.view = Object.assign({}, cameraData.view);\n\n\t\treturn this;\n\t}\n\n\tfromSpotLightState(\n\t\tdata: Partial<SpotLightState>,\n\t\tsharedAssets: SharedAssetsManager\n\t): this {\n\t\tsuper.fromLightState(data, sharedAssets);\n\t\tif (data.distance !== undefined) {\n\t\t\tthis.distance = data.distance;\n\t\t}\n\t\tif (data.decay !== undefined) {\n\t\t\tthis.decay = data.decay;\n\t\t}\n\t\tif (data.angle !== undefined) {\n\t\t\tthis.angle = data.angle;\n\t\t}\n\t\tif (data.penumbra !== undefined) {\n\t\t\tthis.penumbra = data.penumbra;\n\t\t}\n\t\treturn this;\n\t}\n\n\tfromState(data: LightObjectState, sharedAssets: SharedAssetsManager): this {\n\t\tsuper.fromState(data);\n\t\tthis.fromSpotLightState(data as SpotLightState, sharedAssets);\n\t\treturn this;\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { BufferGeometry, Texture, VideoTexture } from 'three';\nimport { AbstractMesh } from './AbstractMesh';\nimport { Material, BasicMaterial, LAYER_TYPE } from '../../materials';\nimport { Geometry, RectangleGeometry } from '../../geometries';\nimport { BaseInputs, NestedPartial } from '../../geometries/Geometry';\nimport { TextureUtils } from '../../TextureUtils';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedMesh2D,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\n\ntype TextureImage =\n\t| HTMLImageElement\n\t| ImageData\n\t| { width: number; height: number };\n\nexport class Mesh2D extends AbstractMesh {\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'Mesh2D';\n\n\tconstructor(\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material | Material[] = new BasicMaterial()\n\t) {\n\t\tsuper(geometry, material);\n\n\t\t// Default configuration for shadows\n\t\tthis.castShadow = true;\n\t\tthis.receiveShadow = true;\n\t}\n\n\tupdateGeometry<TInputs extends BaseInputs>(\n\t\tinputs: NestedPartial<TInputs>\n\t): void {\n\t\tsuper.updateGeometry(inputs);\n\n\t\tif ((this.material as Material).userData.layers) {\n\t\t\tTextureUtils.resizeTextureLayers(\n\t\t\t\t(this.geometry as Geometry).userData.parameters.width,\n\t\t\t\t(this.geometry as Geometry).userData.parameters.height,\n\t\t\t\tthis.material as Material\n\t\t\t);\n\t\t}\n\t}\n\n\tresizeGeometry(width: number, height: number): void {\n\t\tsuper.resizeGeometry(width, height, 0);\n\n\t\tif ((this.material as Material).userData.layers) {\n\t\t\tTextureUtils.resizeTextureLayers(\n\t\t\t\t(this.geometry as Geometry).userData.parameters.width,\n\t\t\t\t(this.geometry as Geometry).userData.parameters.height,\n\t\t\t\tthis.material as Material\n\t\t\t);\n\t\t}\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedMesh2D).objectType = 'Mesh2D';\n\n\t\treturn data;\n\t}\n\n\tclone() {\n\t\tconst clone = super.clone();\n\t\tclone.updateGeometry({});\n\t\treturn clone;\n\t}\n\n\tstatic fromTexture(texture: VideoTexture | Texture): Mesh2D {\n\t\tlet width, height;\n\n\t\tif (texture instanceof VideoTexture) {\n\t\t\tconst video = texture.image as HTMLVideoElement;\n\t\t\twidth = video.videoWidth * 0.5;\n\t\t\theight = video.videoHeight * 0.5;\n\t\t} else {\n\t\t\tconst image = texture.image as TextureImage;\n\t\t\twidth = image.width * 0.5;\n\t\t\theight = image.height * 0.5;\n\t\t}\n\n\t\tconst geometry = RectangleGeometry.create({\n\t\t\tparameters: {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t},\n\t\t});\n\n\t\tconst material = new BasicMaterial();\n\t\tmaterial.layersList.changeLayer(0, {\n\t\t\ttype: LAYER_TYPE.TEXTURE,\n\t\t\ttexture: texture,\n\t\t});\n\t\tmaterial.layersList.moveLayer(0, 1);\n\t\tmaterial.dispose();\n\n\t\treturn new Mesh2D(geometry, material);\n\t}\n}\n", "/**\n * @author alejandro\n * Handles texture resizing\n */\n\nimport type { Mesh, Texture as TTexture } from 'three';\nimport { Material } from './materials';\nimport { isTextureLayer } from './materials/layers/Layer';\n\ntype Texture = TTexture & {\n\timageType: 'WEBCAM' | unknown;\n\timage: HTMLImageElement | HTMLVideoElement;\n\tupdateMatrix: () => void;\n};\n\nconst isVideoElement = (element: HTMLElement): element is HTMLVideoElement =>\n\telement.tagName === 'VIDEO';\n\nexport class TextureUtils {\n\tstatic resize(sizeX: number, sizeY: number, texture: Texture) {\n\t\tconst aspectRatioMesh: number = sizeX / sizeY;\n\t\tlet aspectRatioTexture: number;\n\t\tif (!texture.image) return;\n\t\tconst image = texture.image as HTMLImageElement | HTMLVideoElement;\n\n\t\tif (isVideoElement(image)) {\n\t\t\taspectRatioTexture = image.videoWidth / image.videoHeight;\n\t\t} else {\n\t\t\taspectRatioTexture = image.width / image.height;\n\t\t}\n\t\tif (aspectRatioMesh > aspectRatioTexture) {\n\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\ttexture.repeat.set(-1, (1 * aspectRatioTexture) / aspectRatioMesh);\n\t\t\t} else {\n\t\t\t\ttexture.repeat.set(1, (1 * aspectRatioTexture) / aspectRatioMesh);\n\t\t\t}\n\t\t}\n\n\t\tif (aspectRatioMesh < aspectRatioTexture) {\n\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t((1 * aspectRatioMesh) / aspectRatioTexture) * -1,\n\t\t\t\t\t1\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\ttexture.repeat.set((1 * aspectRatioMesh) / aspectRatioTexture, 1);\n\t\t\t}\n\t\t}\n\n\t\tif (aspectRatioMesh == aspectRatioTexture) {\n\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\ttexture.repeat.set(-1, 1);\n\t\t\t} else {\n\t\t\t\ttexture.repeat.set(1, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic resizeTextureLayer(sizeX: number, sizeY: number, texture: Texture) {\n\t\tconst aspectRatioMesh = sizeX / sizeY;\n\t\tconst aspectRatioTexture =\n\t\t\ttexture.image !== undefined\n\t\t\t\t? (texture.image as HTMLVideoElement).width /\n\t\t\t\t (texture.image as HTMLVideoElement).height\n\t\t\t\t: 1;\n\n\t\tlet repeat: { x: number; y: number };\n\t\tif (aspectRatioMesh > aspectRatioTexture) {\n\t\t\trepeat = {\n\t\t\t\tx: 1,\n\t\t\t\ty: aspectRatioTexture / aspectRatioMesh,\n\t\t\t};\n\t\t} else if (aspectRatioMesh < aspectRatioTexture) {\n\t\t\trepeat = {\n\t\t\t\tx: aspectRatioMesh / aspectRatioTexture,\n\t\t\t\ty: 1,\n\t\t\t};\n\t\t} else {\n\t\t\trepeat = {\n\t\t\t\tx: 1,\n\t\t\t\ty: 1,\n\t\t\t};\n\t\t}\n\n\t\ttexture.repeat.set(repeat.x, repeat.y);\n\t\ttexture.updateMatrix();\n\t}\n\n\tstatic resizeTextureLayers(sizeX: number, sizeY: number, material: Material) {\n\t\tconst layerStack = material.userData.layers!;\n\t\tconst layers = layerStack.getLayers();\n\n\t\tfor (let i = 0; i < layers.length; i++) {\n\t\t\tconst layer = layers[i];\n\n\t\t\tif (isTextureLayer(layer)) {\n\t\t\t\tTextureUtils.resizeTextureLayer(\n\t\t\t\t\tsizeX,\n\t\t\t\t\tsizeY,\n\t\t\t\t\tlayer.uniforms[`f${layer.id}_texture`].value\n\t\t\t\t);\n\t\t\t\tlayerStack.updateLayerUniform();\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic resizeComplex(\n\t\tsizeX: number,\n\t\tsizeY: number,\n\t\ttexture: Texture,\n\t\tmesh: Mesh\n\t) {\n\t\tconst aspectRatioMesh = sizeX / sizeY;\n\t\tlet aspectRatioTexture;\n\t\tconst image = texture.image as HTMLImageElement | HTMLVideoElement;\n\n\t\tif (isVideoElement(image)) {\n\t\t\taspectRatioTexture = image.videoWidth / image.videoHeight;\n\t\t} else {\n\t\t\taspectRatioTexture = image.width / image.height;\n\t\t}\n\n\t\tif (mesh.geometry.type.includes('Shape')) {\n\t\t\t//\"Shape geometry\"\n\t\t\tif (aspectRatioMesh > aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t\t(1 / sizeX) * -1,\n\t\t\t\t\t\t((1 / sizeY) * aspectRatioTexture) / aspectRatioMesh\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t\t1 / sizeX,\n\t\t\t\t\t\t((1 / sizeY) * aspectRatioTexture) / aspectRatioMesh\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (aspectRatioMesh < aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t\t(((1 / sizeX) * aspectRatioMesh) / aspectRatioTexture) * -1,\n\t\t\t\t\t\t1 / sizeY\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t\t((1 / sizeX) * aspectRatioMesh) / aspectRatioTexture,\n\t\t\t\t\t\t1 / sizeY\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (aspectRatioMesh == aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set((1 / sizeX) * -1, 1 / sizeY);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set(1 / sizeX, 1 / sizeY);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//\"Normal geometry\"\n\n\t\t\tif (aspectRatioMesh > aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set(-1, (1 * aspectRatioTexture) / aspectRatioMesh);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set(1, (1 * aspectRatioTexture) / aspectRatioMesh);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (aspectRatioMesh < aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set(\n\t\t\t\t\t\t((1 * aspectRatioMesh) / aspectRatioTexture) * -1,\n\t\t\t\t\t\t1\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set((1 * aspectRatioMesh) / aspectRatioTexture, 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (aspectRatioMesh == aspectRatioTexture) {\n\t\t\t\tif (texture.imageType == 'WEBCAM') {\n\t\t\t\t\ttexture.repeat.set(-1, 1);\n\t\t\t\t} else {\n\t\t\t\t\ttexture.repeat.set(1, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { AbstractMesh } from './AbstractMesh';\nimport { BufferGeometry, Material } from 'three';\nimport { PhongMaterial } from '../../materials';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedMesh3D,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\n\nexport class Mesh3D extends AbstractMesh {\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'Mesh3D';\n\n\tconstructor(\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material | Material[] = new PhongMaterial()\n\t) {\n\t\tsuper(geometry, material);\n\n\t\t// Default configuration for shadows\n\t\tthis.castShadow = true;\n\t\tthis.receiveShadow = true;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedMesh3D).objectType = 'Mesh3D';\n\n\t\treturn data;\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport { BufferGeometry, Material } from 'three';\nimport { Mesh3D } from './Mesh3D';\nimport { PhongMaterial } from '../../materials';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedNonParametric,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\n\nexport class NonParametric extends Mesh3D {\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'NonParametric';\n\n\tconstructor(\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material | Material[] = new PhongMaterial()\n\t) {\n\t\tsuper(geometry, material);\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedNonParametric).objectType = 'NonParametric';\n\n\t\treturn data;\n\t}\n}\n", "/**\n * @author nisa\n */\n\nimport {\n\tHemisphereLight,\n\tIntersection,\n\tRaycaster,\n\tScene as TScene,\n\tVector3,\n\tColor,\n\tFog,\n\tObject3D,\n\tMatrix4,\n\tBox3,\n\tWebGLRenderTarget,\n} from 'three';\nimport { CombinedCamera } from './entities/CombinedCamera';\nimport { isEntity, Entity } from './entities/Entity';\nimport { Object3DMixin } from './Object3D';\nimport {\n\tisHelperableEntity,\n\tisMeshEntity,\n\tupdateLightBaseProps,\n} from './entities/utils';\nimport {\n\tMeta,\n\tSerializedBase,\n\tSerializedScene,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\nimport {\n\tCameraObjectState,\n\tEnvironmentLightData,\n\tFogState,\n\tObjectState,\n\tSceneData,\n} from 'spline-data';\nimport { SharedAssetsManager } from '../shared/SharedAssetsManager';\nimport { createObject } from './create';\nimport { TreeItem, TreeItems } from 'collab-data';\nimport { objectDispose, updateTransmission } from './sceneUtils';\nimport { LAYER_TYPE, Material } from '../materials';\nimport { AbstractMesh } from './entities';\nimport { getSharedColorData } from '../shared/utils';\nimport { ColorA } from './Color';\n\nconst tempVector = new Vector3();\n\nexport class Scene extends Object3DMixin(TScene) {\n\tstatic PERSONAL_CAMERA_ID =\n\t\t'f23858d0-4a3b-4bd8-8173-66ed0af7f6fb-personalCamera';\n\t// @deprecated use instanceof instead of this\n\tobjectType = 'Scene';\n\tactiveCamera: CombinedCamera;\n\t// local default camera\n\tpersonalCamera: CombinedCamera;\n\n\t// default ambient light\n\tambientLight: HemisphereLight;\n\n\tsharedAssetManager: SharedAssetsManager;\n\n\talpha: number = 1;\n\t// used for disable this.fog\n\tbackupFog: Fog = new Fog(0xffffff, 0.1, 2000);\n\tfogUseBGColor: boolean = false;\n\n\twireframeState: boolean = false;\n\n\tneedsTransmissionDirty = true;\n\tprivate _needsTransmission: boolean = false;\n\n\tneedsTransmission(target: WebGLRenderTarget | undefined): boolean {\n\t\tif (this.needsTransmissionDirty) {\n\t\t\tthis._needsTransmission = updateTransmission(target, this);\n\t\t\tif (target !== undefined) {\n\t\t\t\tthis.needsTransmissionDirty = false;\n\t\t\t}\n\t\t}\n\t\treturn this._needsTransmission;\n\t}\n\n\t_color: Color = new Color(1, 0, 0);\n\tbgColor: Color = new Color(1, 1, 1);\n\n\tentityByUuid: Record<string, Entity> = {};\n\n\tfind(id: string): Entity | undefined {\n\t\tif (id === '' || id === undefined) return undefined;\n\t\tlet obj = this.entityByUuid[id];\n\t\tif (obj === undefined) {\n\t\t\tlet objFallback = this.getObjectByProperty('uuid', id as string) as\n\t\t\t\t| Entity\n\t\t\t\t| undefined;\n\t\t\treturn objFallback;\n\t\t} else {\n\t\t\treturn obj;\n\t\t}\n\t}\n\n\tget color(): Color {\n\t\treturn this._color;\n\t}\n\n\tset color(color: Color) {\n\t\tif (this.fogUseBGColor === true) {\n\t\t\tthis.backupFog.color.copy(color);\n\t\t}\n\t\tthis._color.copy(color);\n\t}\n\n\tget enableFog(): boolean {\n\t\treturn this.fog !== null ? true : false;\n\t}\n\n\tset enableFog(enableFog: boolean) {\n\t\tthis.fog = enableFog === true ? this.backupFog : null;\n\t}\n\n\tconstructor(data: SceneData, sharedAssets: SharedAssetsManager) {\n\t\tsuper();\n\t\tthis.ambientLight = new HemisphereLight(0xd3d3d3, 0x828282, 0.75);\n\t\tthis.ambientLight.name = 'Default Ambient Light';\n\t\tthis.personalCamera = this.createPersonalCamera();\n\t\tthis.activeCamera = this.personalCamera;\n\t\tthis.sharedAssetManager = sharedAssets;\n\t\tthis.init(data, sharedAssets);\n\t}\n\n\tprivate init(data: SceneData, sharedAssets: SharedAssetsManager) {\n\t\tthis.createChildrenObjects(data.objects, this, sharedAssets);\n\t\t// put them in the end\n\t\tthis.personalCamera.removeFromParent();\n\t\tthis.add(this.personalCamera);\n\t\tthis.ambientLight.removeFromParent();\n\t\tthis.add(this.ambientLight);\n\n\t\tthis.setBackgroundColor(\n\t\t\tgetSharedColorData(data.backgroundColor, sharedAssets)\n\t\t);\n\n\t\tthis.updateFog(data.fog, sharedAssets);\n\t\tthis.updateAmbientLight(data.environment.ambientLight, sharedAssets);\n\t\tthis.activeCamera = this.personalCamera;\n\t\tif (data.publish.playCamera !== null) {\n\t\t\tlet playCamera = this.find(data.publish.playCamera);\n\t\t\tif (playCamera instanceof CombinedCamera) {\n\t\t\t\tthis.switchActiveCamera(playCamera);\n\t\t\t}\n\t\t}\n\t}\n\tclearScene(sharedAssets: SharedAssetsManager) {\n\t\tthis.traverseEntity((e) => {\n\t\t\tobjectDispose(e, sharedAssets);\n\t\t});\n\t\tfor (let c of this.children) {\n\t\t\tif (isEntity(c)) {\n\t\t\t\tc.removeFromParent();\n\t\t\t}\n\t\t}\n\t}\n\n\tresetAfterClear(data: SceneData, sharedAssets: SharedAssetsManager) {\n\t\tthis.init(data, sharedAssets);\n\t}\n\n\tcreatePersonalCamera() {\n\t\tconst camera = CombinedCamera.createFromState(Scene.PERSONAL_CAMERA_ID, {\n\t\t\t...CameraObjectState.defaultData,\n\t\t\tname: 'Personal Camera',\n\t\t});\n\t\tcamera.enableHelper = false;\n\t\tcamera.objectHelper.visible = false;\n\t\t// TODO for legacy code\n\t\t// @ts-ignore\n\t\tdelete camera['isEntity'];\n\t\tthis.registerObjectCreatedInLegacy(camera);\n\t\treturn camera;\n\t}\n\n\t// override\n\traycast(raycaster: Raycaster): Intersection[] {\n\t\tconst intersects: Intersection[] = [];\n\t\tconst traverse = (object: Entity): void => {\n\t\t\tfor (const child of object.children) {\n\t\t\t\tif (isEntity(child) && !child.raycastLock && child.visible) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tisMeshEntity(child) ||\n\t\t\t\t\t\t(isHelperableEntity(child) &&\n\t\t\t\t\t\t\tchild.enableHelper &&\n\t\t\t\t\t\t\t// the helper is not a child of the object, it is added separetly, so we need to check if it exist of the scenegraph\n\t\t\t\t\t\t\tchild.objectHelper.parent)\n\t\t\t\t\t) {\n\t\t\t\t\t\traycaster.intersectObject(child, false, intersects);\n\t\t\t\t\t}\n\t\t\t\t\ttraverse(child);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\ttraverse(this as unknown as Entity);\n\n\t\treturn intersects;\n\t}\n\n\ttraverseEntity(callback: (e: Entity) => void): void {\n\t\tfor (const child of this.children) {\n\t\t\tif (isEntity(child)) {\n\t\t\t\t// without default camera\n\t\t\t\tchild.traverseEntity(callback);\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateFog(fog: FogState, sharedAssets: SharedAssetsManager): void {\n\t\t// it seems updating all of these is ok because they are only simple assignments\n\t\tthis.enableFog = fog.enabled;\n\t\tthis.fogUseBGColor = fog.useBackgroundColor;\n\t\tif (!fog.useBackgroundColor) {\n\t\t\tthis.backupFog.color = getSharedColorData(fog.color, sharedAssets);\n\t\t} else {\n\t\t\tthis.backupFog.color.set(this.bgColor);\n\t\t}\n\t\tthis.backupFog.near = fog.near;\n\t\tthis.backupFog.far = fog.far;\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\treturn {} as any;\n\t}\n\n\tfromJSON(data: SerializedScene): this {\n\t\treturn this;\n\t}\n\n\tdispose() {\n\t\tthis.clearScene(this.sharedAssetManager);\n\t\tthis.sharedAssetManager.dispose();\n\t}\n\n\tupdateAmbientLight(\n\t\tprops: Partial<EnvironmentLightData['ambientLight']>,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tupdateLightBaseProps(this.ambientLight!, props, sharedAssets);\n\t\tif (props.groundColor !== undefined) {\n\t\t\tthis.ambientLight!.groundColor = getSharedColorData(\n\t\t\t\tprops.groundColor,\n\t\t\t\tsharedAssets\n\t\t\t);\n\t\t}\n\t\tif (props.enabled !== undefined) {\n\t\t\tthis.ambientLight!.visible = props.enabled;\n\t\t}\n\t}\n\n\tswitchActiveCamera(newCamera: CombinedCamera) {\n\t\tif (this.activeCamera !== this.personalCamera) {\n\t\t\tthis.activeCamera.enableHelper = true;\n\t\t}\n\t\tthis.activeCamera = newCamera;\n\t\tnewCamera.enableHelper = false;\n\t}\n\n\tsetBackgroundColor(color: ColorA) {\n\t\tthis.bgColor = color;\n\t\tthis.alpha = color.a;\n\t}\n\n\tprivate createChildrenObjects(\n\t\tarr: TreeItem<ObjectState>[],\n\t\tparent: Object3D,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tfor (const item of arr) {\n\t\t\tthis.createChildObject(\n\t\t\t\titem.id,\n\t\t\t\titem.data,\n\t\t\t\titem.children,\n\t\t\t\tparent,\n\t\t\t\tsharedAssets\n\t\t\t);\n\t\t}\n\t}\n\n\tregisterObjectCreatedInLegacy(obj: Entity) {\n\t\tthis.entityByUuid[obj.uuid] = obj as Entity;\n\t}\n\n\tunregisterObject(obj: Entity) {\n\t\tdelete this.entityByUuid[obj.uuid];\n\t\tfor (let c of obj.children) {\n\t\t\tthis.unregisterObject(c as Entity);\n\t\t}\n\t}\n\n\tcreateChildObject(\n\t\tid: string,\n\t\tobjectData: ObjectState,\n\t\tchildren: TreeItems<ObjectState>,\n\t\tparent: Object3D,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tconst obj = createObject(id, objectData, sharedAssets);\n\t\tif (obj) {\n\t\t\tthis.entityByUuid[id] = obj as Entity;\n\t\t\tparent.add(obj);\n\t\t\tthis.createChildrenObjects(children, obj, sharedAssets);\n\t\t}\n\t\treturn obj;\n\t}\n\n\tgetCenter(selection: { id: string; recursive: boolean }[]): Vector3 {\n\t\tlet vertices = [];\n\n\t\tfor (let i = 0, l = selection.length; i < l; ++i) {\n\t\t\tconst { id, recursive } = selection[i];\n\t\t\tconst object = this.find(id)!;\n\n\t\t\tconst box3 = recursive ? object.recursiveBBox : object.singleBBox;\n\t\t\tvertices.push(...box3.vertices);\n\t\t}\n\n\t\tconst box3 = new Box3();\n\t\tbox3.setFromPoints(vertices);\n\n\t\tbox3.getCenter(tempVector);\n\t\treturn tempVector;\n\t}\n\n\tcopyMatrixWorld(id: string | null, matrix: Matrix4) {\n\t\tif (id === null) {\n\t\t\tmatrix.identity();\n\t\t\treturn;\n\t\t}\n\t\tlet obj = this.find(id);\n\t\tif (obj) {\n\t\t\tmatrix.copy(obj.matrixWorld);\n\t\t} else {\n\t\t\tmatrix.identity();\n\t\t}\n\t}\n\n\tcopyParentMatrixWorld(id: string | null, matrix: Matrix4) {\n\t\tif (id === null) {\n\t\t\tmatrix.identity();\n\t\t\treturn;\n\t\t}\n\t\tlet parent = this.find(id)?.parent;\n\t\tif (parent) {\n\t\t\tmatrix.copy(parent.matrixWorld);\n\t\t} else {\n\t\t\tmatrix.identity();\n\t\t}\n\t}\n\n\ttraverseMaterial(callback: (m: Material) => void) {\n\t\tthis.traverseEntity((e) => {\n\t\t\tif (e instanceof AbstractMesh) {\n\t\t\t\tif (Array.isArray(e.material)) {\n\t\t\t\t\tfor (let i = 0; i < e.material.length; i++) {\n\t\t\t\t\t\tcallback(e.material[i] as Material);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcallback(e.material as Material);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tupdateCanvasSize(width: number, height: number) {\n\t\tthis.activeCamera.setViewplaneSize(width, height);\n\t\tlet x: number, y: number;\n\t\tif (width >= height) {\n\t\t\tx = height / width;\n\t\t\ty = 1;\n\t\t} else {\n\t\t\tx = 1;\n\t\t\ty = width / height;\n\t\t}\n\t\tthis.traverseMaterial((m) => {\n\t\t\tconst transmissionLayers = m.layersList.getLayersOfType(\n\t\t\t\tLAYER_TYPE.TRANSMISSION\n\t\t\t);\n\t\t\ttransmissionLayers.forEach((l) => {\n\t\t\t\tl.uniforms[`f${l.id}_aspectRatio`].value.x = x;\n\t\t\t\tl.uniforms[`f${l.id}_aspectRatio`].value.y = y;\n\t\t\t});\n\t\t});\n\t}\n}\n", "import { GeometryState, VectorShape as VectorShapeData } from 'spline-data';\nimport { BufferGeometry, BufferGeometryLoader } from 'three';\nimport { createGeometry } from '.';\nimport { VectorShape } from '../objects/entities/vectors';\nimport { SharedAssetsManager } from '../shared/SharedAssetsManager';\n\nexport function getGeometry(\n\tdata: GeometryState,\n\tsharedAssets?: SharedAssetsManager\n) {\n\t// TODO: Maybe add shared geometry?\n\t// const sharedGeometry =\n\t// \tsharedAssets && typeof data === 'string'\n\t// \t\t? sharedAssets.getGeometry(data)\n\t// \t\t: null;\n\treturn createGeometryFromData(data);\n}\n\nexport function createGeometryFromData(data: GeometryState): BufferGeometry {\n\tconst inputs = {\n\t\tparameters: data as any,\n\t\ttype: data.type,\n\t} as any;\n\tif (data.type === 'VectorGeometry') {\n\t\tconst shape = VectorShape.createFromState(\n\t\t\tdata.shape,\n\t\t\tdata.width,\n\t\t\tdata.height\n\t\t);\n\t\tinputs.shape = shape;\n\t} else if (data.type === 'NonParametricGeometry') {\n\t\tif (data.data.groups) {\n\t\t\tdata.data.groups.forEach(\n\t\t\t\t(g) => (g.materialIndex = Math.max(g.materialIndex ?? 0, 0))\n\t\t\t);\n\t\t}\n\t\tinputs.geometry = new BufferGeometryLoader().parse(data);\n\t}\n\tlet geometry;\n\ttry {\n\t\tgeometry = createGeometry(inputs);\n\t} catch (e) {\n\t\tconsole.error(e);\n\t}\n\tif (!geometry) {\n\t\t// In case geometry creation failed with data, let's use default ones so we can still open the file\n\t\tconst shape = VectorShape.createFromState(\n\t\t\tVectorShapeData.defaultData(),\n\t\t\t100,\n\t\t\t100\n\t\t);\n\t\tinputs.shape = shape;\n\t\tgeometry = createGeometry(inputs);\n\t}\n\treturn geometry;\n}\n", "/**\n * @author howard\n */\n\nimport { AbstractMesh } from '../AbstractMesh';\nimport {\n\tBox3,\n\tBufferAttribute,\n\tBufferGeometry,\n\tIntersection,\n\tMaterial,\n\tMatrix4,\n\tMesh,\n\tRaycaster,\n\tSphere,\n\tVector3,\n\tVector3Tuple,\n} from 'three';\nimport { getMaterial, PhongMaterial } from '../../../materials';\nimport type {\n\tMeta,\n\tSerializedBase,\n\tSerializedSubdivObject,\n} from 'spline-data/src/legacyFormat/ObjectSpec';\n\nimport { SubdivGeometry } from '../../../geometries/subdiv/SubdivGeometry';\nimport { SubdivGeometryParameters, SubdivObjectState } from 'spline-data';\n\nimport { SVD } from 'svd-js';\nimport type { ProxiedObject } from 'collab-data';\nimport { ProcessModule } from 'modelling-wasm';\nimport { modellingWasm } from '../../../geometries';\nimport { BaseInputs, NestedPartial } from '../../..';\nimport { SharedAssetsManager } from '../../../shared/SharedAssetsManager';\nimport { NonParametric } from '..';\n\nlet wasm: ProcessModule;\nmodellingWasm.then((inst) => {\n\twasm = inst;\n});\n\nconst _m1 = new Matrix4();\nconst _m2 = new Matrix4();\nconst _m3 = new Matrix4();\nconst _box = new Box3();\nconst _x = new Vector3();\nconst _shearScale = new Matrix4();\nconst _shearScaleInv = new Matrix4();\n\nexport class SubdivObject extends AbstractMesh {\n\tobjectType = 'SubdivObject';\n\thiddenMatrixOld: Matrix4 = new Matrix4();\n\tsmoothShading = true;\n\tmatrixWorldRigid = new Matrix4();\n\tshearScale?: Matrix4;\n\tshearScaleInv?: Matrix4;\n\n\tstatic createFromState(\n\t\tid: string,\n\t\tdata: SubdivObjectState,\n\t\tsharedAssets: SharedAssetsManager\n\t) {\n\t\tconst { subdivPointer, originalGeometry, subdividedGeometry } =\n\t\t\tSubdivGeometry.build(\n\t\t\t\tdata.geometry,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t!data.flatShading\n\t\t\t);\n\t\tconst material = getMaterial(data.material, sharedAssets);\n\t\tconst object = new SubdivObject(\n\t\t\tsubdivPointer,\n\t\t\toriginalGeometry!,\n\t\t\tsubdividedGeometry ? subdividedGeometry : undefined,\n\t\t\tmaterial\n\t\t);\n\t\tobject.calcBoundingBox();\n\t\tobject.freeSubdivPointer();\n\t\tobject.uuid = id;\n\t\tobject.fromState(data);\n\t\treturn object;\n\t}\n\n\tconstructor(\n\t\tpublic subdivPointer: number,\n\t\tpublic originalGeometry: BufferGeometry,\n\t\tpublic subdividedGeometry?: BufferGeometry,\n\t\tmaterial: Material | Material[] = new PhongMaterial()\n\t) {\n\t\tsuper(subdividedGeometry ?? originalGeometry, material);\n\n\t\t// Default configuration for shadows\n\t\tthis.castShadow = true;\n\t\tthis.receiveShadow = true;\n\t\tthis.forceComputeSize = false;\n\t}\n\n\tshallowClone(recursive?: boolean): this {\n\t\treturn new (NonParametric as any)(this.geometry, this.material).shallowCopy(\n\t\t\tthis,\n\t\t\trecursive\n\t\t);\n\t}\n\n\ttoJSON(meta?: Meta): SerializedBase {\n\t\tconst data = super.toJSON(meta);\n\t\t(data.object as SerializedSubdivObject).objectType = 'SubdivObject';\n\t\treturn data;\n\t}\n\n\tbuildFromStore(inputs: SubdivGeometryParameters) {\n\t\tconst { originalGeometry, subdividedGeometry, subdivPointer } =\n\t\t\tSubdivGeometry.build(\n\t\t\t\tinputs,\n\t\t\t\tthis.subdivPointer,\n\t\t\t\tundefined,\n\t\t\t\tthis.smoothShading,\n\t\t\t\tthis.shearScale\n\t\t\t);\n\n\t\tthis.subdivPointer = subdivPointer;\n\n\t\tif (originalGeometry !== undefined) {\n\t\t\tthis.originalGeometry?.dispose();\n\t\t\tthis.originalGeometry = originalGeometry;\n\t\t}\n\t\tif (subdividedGeometry !== undefined) {\n\t\t\tthis.subdividedGeometry?.dispose();\n\t\t\tthis.subdividedGeometry = subdividedGeometry ?? undefined; // null becomes undefined\n\t\t}\n\n\t\tthis.geometry = this.subdividedGeometry ?? this.originalGeometry;\n\n\t\tif (this.cloner) {\n\t\t\tfor (const child of this.cloner.children) {\n\t\t\t\t(child as Mesh).geometry = this.geometry;\n\t\t\t}\n\t\t}\n\n\t\tif (inputs.width) {\n\t\t\tthis.geometry.userData.parameters = {\n\t\t\t\twidth: inputs.width,\n\t\t\t\theight: inputs.height,\n\t\t\t\tdepth: inputs.depth,\n\t\t\t};\n\t\t}\n\t}\n\n\tupdateMesh(isApplyShearScaleInv = false) {\n\t\tSubdivGeometry.buildLevel(\n\t\t\tthis.subdivPointer,\n\t\t\ttrue,\n\t\t\tthis.smoothShading,\n\t\t\tthis.originalGeometry,\n\t\t\tisApplyShearScaleInv ? this.shearScaleInv : undefined\n\t\t);\n\t\tif (this.subdividedGeometry) {\n\t\t\tSubdivGeometry.buildLevel(\n\t\t\t\tthis.subdivPointer,\n\t\t\t\tfalse,\n\t\t\t\tthis.smoothShading,\n\t\t\t\tthis.subdividedGeometry,\n\t\t\t\tisApplyShearScaleInv ? this.shearScaleInv : undefined\n\t\t\t);\n\t\t}\n\t}\n\n\tupdateTopology() {\n\t\tthis.originalGeometry.dispose();\n\t\tthis.originalGeometry = SubdivGeometry.buildLevel(\n\t\t\tthis.subdivPointer,\n\t\t\ttrue,\n\t\t\tthis.smoothShading\n\t\t)!;\n\n\t\tif (this.subdividedGeometry) {\n\t\t\tthis.subdividedGeometry.dispose();\n\t\t\tthis.subdividedGeometry = SubdivGeometry.buildLevel(\n\t\t\t\tthis.subdivPointer,\n\t\t\t\tfalse,\n\t\t\t\tthis.smoothShading\n\t\t\t);\n\t\t}\n\n\t\tthis.geometry = this.subdividedGeometry ?? this.originalGeometry;\n\t}\n\n\traycast(raycaster: Raycaster, intersects: Intersection[]) {\n\t\tthis.geometry = this.originalGeometry;\n\t\tAbstractMesh.prototype.raycast.call(this, raycaster, intersects);\n\t\tthis.geometry = this.subdividedGeometry ?? this.originalGeometry;\n\t}\n\n\t/**\n\t * Decomposes the 3x3 affine tranformation matrix [a] from matrixWorld\n\t * using SVD (https://en.wikipedia.org/wiki/Singular_value_decomposition).\n\t * SVD decomposes the matrix into the form: [a] = [u][q][v^T]. We can think of\n\t * [a] as being comprised of [v^t] an initial pure rotation step, followed\n\t * by [q] a pure scaling step (can be non-uniform), and finally [u] another pure\n\t * rotation that rotates our geometry to its final orientation.\n\t *\n\t * Finally, we further decompose [u][q][v^T] into ([u][v^T])([v][q][v^T]) where\n\t * the first part is a pure rotation rigid transformation, which we store in\n\t * object.matrixWorldRigid, and the second part a pure scaling transformation with\n\t * shear components which we store in object.shearScale.\n\t */\n\tupdateMatrixWorldSVD() {\n\t\tconst e = this.matrixWorld.elements;\n\t\tconst a = [\n\t\t\t[e[0], e[4], e[8]],\n\t\t\t[e[1], e[5], e[9]],\n\t\t\t[e[2], e[6], e[10]],\n\t\t];\n\t\t// const f = e.map(f => f.toFixed(5))\n\t\t// console.log(\n\t\t// `{{${f[0]},${f[4]},${f[8]}},{${f[1]},${f[5]},${f[9]}},{${f[2]},${f[6]},${f[10]}}}`\n\t\t// );\n\n\t\tconst { u, v, q } = SVD(a);\n\n\t\t// prettier-ignore\n\t\tconst uMat = _m1.set(\n\t\t\tu[0][0], u[0][1], u[0][2], 0,\n\t\t\tu[1][0], u[1][1], u[1][2], 0,\n\t\t\tu[2][0], u[2][1], u[2][2], 0,\n\t\t\t0, 0, 0, 1\n\t\t);\n\t\t// prettier-ignore\n\t\tconst vMat = _m2.set(\n\t\t\tv[0][0], v[0][1], v[0][2], 0,\n\t\t\tv[1][0], v[1][1], v[1][2], 0,\n\t\t\tv[2][0], v[2][1], v[2][2], 0,\n\t\t\t0, 0, 0, 1\n\t\t);\n\n\t\tconst vMatTranspose = _m3.copy(vMat).transpose();\n\n\t\t// shearScale = [v][q][v^T]\n\t\tthis.shearScale = _shearScale\n\t\t\t.makeScale(q[0], q[1], q[2])\n\t\t\t.multiply(vMatTranspose)\n\t\t\t.premultiply(vMat);\n\n\t\tthis.shearScaleInv = _shearScaleInv.copy(this.shearScale).invert();\n\n\t\t// matrixWorldRigid = [u][v^T]\n\t\tthis.matrixWorldRigid.multiplyMatrices(uMat, vMatTranspose);\n\n\t\tif (q.every((e) => Math.abs(q[0] - e) < 0.01)) {\n\t\t\tthis.shearScale = undefined;\n\t\t\tthis.shearScaleInv = undefined;\n\t\t}\n\t}\n\n\tactivateSVDCompensation() {\n\t\tif (this.shearScale === undefined) return;\n\t\tthis.matrixAutoUpdate = false;\n\t\tthis.matrix.copy(this.matrixWorldRigid).copyPosition(this.matrixWorld);\n\t\tthis.hiddenMatrixOld.copy(this.hiddenMatrix);\n\t\tthis.hiddenMatrix.copy(this.parent!.matrixWorld).invert();\n\t}\n\n\tdeactivateSVDCompensation() {\n\t\tif (this.shearScale === undefined) return;\n\t\tthis.shearScale = undefined;\n\t\tthis.shearScaleInv = undefined;\n\t\tthis.matrixAutoUpdate = true;\n\t\tthis.hiddenMatrix.copy(this.hiddenMatrixOld);\n\t}\n\n\tcalcBoundingBox() {\n\t\tconst geom = this.originalGeometry;\n\n\t\tif (geom.boundingSphere === null) {\n\t\t\tgeom.boundingSphere = new Sphere();\n\t\t}\n\n\t\tconst position = geom.attributes.position;\n\n\t\t// first, find the center of the bounding sphere\n\n\t\tconst center = geom.boundingSphere.center;\n\n\t\t_box.setFromBufferAttribute(position as BufferAttribute);\n\n\t\t_box.getCenter(center);\n\n\t\t// Bounding sphere calculation\n\t\t// we disable this more precise (but costlier?) calc for now, can switch back if needed\n\n\t\t// // second, try to find a boundingSphere with a radius smaller than the\n\t\t// // boundingSphere of the boundingBox: sqrt(3) smaller in the best case\n\n\t\t// let maxRadiusSq = 0;\n\n\t\t// for (let i = 0, il = position.count; i < il; i++) {\n\t\t// \t_x.fromBufferAttribute(position, i);\n\n\t\t// \tmaxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_x));\n\t\t// }\n\n\t\t// geom.boundingSphere.radius = Math.sqrt(maxRadiusSq);\n\n\t\tgeom.boundingSphere.radius = center.distanceTo(_box.max);\n\n\t\tif (isNaN(geom.boundingSphere.radius)) {\n\t\t\tconsole.error(\n\t\t\t\t'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\t_box.getSize(_x);\n\n\t\tconst size = {\n\t\t\twidth: _x.x,\n\t\t\theight: _x.y,\n\t\t\tdepth: _x.z,\n\t\t};\n\n\t\t// when Box3 gets refactored we need to rethink where we store the cached\n\t\t// bounding box size\n\t\tthis.geometry.userData.parameters = size;\n\n\t\treturn size;\n\t}\n\n\tupdateBoundingBox(bounds: number[]) {\n\t\tconst geom = this.originalGeometry;\n\n\t\t_box.min.set(bounds[0], bounds[2], bounds[4]);\n\t\t_box.max.set(bounds[1], bounds[3], bounds[5]);\n\n\t\tif (this.shearScaleInv) {\n\t\t\t_box.min.applyMatrix4(this.shearScaleInv);\n\t\t\t_box.max.applyMatrix4(this.shearScaleInv);\n\t\t}\n\n\t\tif (geom.boundingSphere === null) {\n\t\t\tgeom.boundingSphere = new Sphere();\n\t\t}\n\n\t\tconst center = geom.boundingSphere.center;\n\n\t\t_box.getCenter(center);\n\n\t\tgeom.boundingSphere.radius = center.distanceTo(_box.max);\n\n\t\tif (isNaN(geom.boundingSphere.radius)) {\n\t\t\tconsole.error(\n\t\t\t\t'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The \"position\" attribute is likely to have NaN values.',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\t_box.getSize(_x);\n\n\t\tconst size = {\n\t\t\twidth: _x.x,\n\t\t\theight: _x.y,\n\t\t\tdepth: _x.z,\n\t\t};\n\n\t\t// when Box3 gets refactored we need to rethink where we store the cached\n\t\t// bounding box size\n\t\tthis.geometry.userData.parameters = size;\n\n\t\treturn size;\n\t}\n\n\tfreeSubdivPointer() {\n\t\tif (this.subdivPointer) {\n\t\t\t// console.log('freeing subdiv pointer', this.subdivPointer);\n\t\t\twasm.free_bvh(this.subdivPointer);\n\t\t\twasm.free_subdivision_surface(this.subdivPointer);\n\t\t\tthis.subdivPointer = 0;\n\t\t}\n\t}\n\n\t/**\n\t * only called during resize mouse move\n\t */\n\tupdateGeometry<TInputs extends BaseInputs>(\n\t\tinputs: NestedPartial<TInputs>\n\t): void {\n\t\tif (!this.geometry.userData.scale) {\n\t\t\tthis.geometry.userData.scale = Array(3);\n\t\t}\n\t\tthis.geometry.userData.scale[0] =\n\t\t\tthis.geometry.userData.parameters.width === 0\n\t\t\t\t? 1\n\t\t\t\t: inputs.parameters!.width! / this.geometry.userData.parameters.width!;\n\t\tthis.geometry.userData.scale[1] =\n\t\t\tthis.geometry.userData.parameters.height === 0\n\t\t\t\t? 1\n\t\t\t\t: inputs.parameters!.height! /\n\t\t\t\t this.geometry.userData.parameters.height!;\n\t\tthis.geometry.userData.scale[2] =\n\t\t\tthis.geometry.userData.parameters.depth === 0\n\t\t\t\t? 1\n\t\t\t\t: inputs.parameters!.depth! / this.geometry.userData.parameters.depth!;\n\n\t\tapplyScale(\n\t\t\tthis.originalGeometry.attributes,\n\t\t\t...(this.geometry.userData.scale as Vector3Tuple)\n\t\t);\n\t\tthis.originalGeometry.attributes.position.needsUpdate = true;\n\t\tthis.originalGeometry.attributes.normal.needsUpdate = true;\n\t\tif (this.subdividedGeometry) {\n\t\t\tapplyScale(\n\t\t\t\tthis.subdividedGeometry.attributes,\n\t\t\t\t...(this.subdividedGeometry.userData.scale as Vector3Tuple)\n\t\t\t);\n\t\t\tthis.subdividedGeometry.attributes.position.needsUpdate = true;\n\t\t\tthis.subdividedGeometry.attributes.normal.needsUpdate = true;\n\t\t}\n\n\t\tthis.geometry.userData.parameters = { ...inputs.parameters };\n\t}\n}\n\nfunction applyScale(attributes: any, sx: number, sy: number, sz: number): void {\n\tconst position = attributes.position.array;\n\tconst normal = attributes.normal.array;\n\tconst m = _m1.makeScale(sx, sy, sz).invert().elements;\n\tlet x, y, z;\n\t// prettier-ignore\n\tfor (var i = 0, il = position.length; i < il; i += 3) {\n\t\tposition[i] *= sx; \n\t\tposition[i+1] *= sy;\n\t\tposition[i+2] *= sz;\n\t\tx = normal[i]; y = normal[i + 1]; z = normal[i + 2];\n\t\tnormal[i] = m[0] * x + m[4] * y + m[8] * z; \n\t\tnormal[i + 1] = m[1] * x + m[5] * y + m[9] * z;\n\t\tnormal[i + 2] = m[2] * x + m[6] * y + m[10] * z; \n\t}\n}\n", "import {\n\tGeometryType,\n\tMeshObjectState,\n\tMeshVisibilityState,\n\tSide,\n\tSubdivObjectState,\n} from 'spline-data';\nimport { getGeometry } from '../../geometries/create';\nimport { Mesh2D } from './Mesh2D';\nimport { Mesh3D } from './Mesh3D';\nimport { NonParametric } from './NonParametric';\nimport { SubdivObject } from './subdiv';\nimport { VectorObject } from './vectors/VectorObject';\nimport { SharedAssetsManager } from '../../shared/SharedAssetsManager';\nimport { AbstractMesh } from './AbstractMesh';\nimport { BackSide, DoubleSide, FrontSide } from 'three';\nimport { NodeMaterial } from '../../materials/nodes/Nodes';\nimport { getMaterial, getMaterials } from '../../materials';\n\nexport function updateMaterialVisibilityProps(\n\tmaterial: NodeMaterial,\n\tdata: Partial<MeshVisibilityState>\n) {\n\tif (data.flatShading !== undefined) {\n\t\tmaterial.flatShading = data.flatShading;\n\t\tmaterial.needsUpdate = true;\n\t}\n\tif (data.wireframe !== undefined) {\n\t\tmaterial.wireframe = data.wireframe;\n\t}\n\tif (data.side !== undefined) {\n\t\tif (data.side === Side.Front) {\n\t\t\tmaterial.side = FrontSide;\n\t\t} else if (data.side === Side.Back) {\n\t\t\tmaterial.side = BackSide;\n\t\t} else {\n\t\t\tmaterial.side = DoubleSide;\n\t\t}\n\t}\n}\n\n// TODO bug: this causes shared material to update together\nexport function updateMeshVisibilityProps(\n\tobject: AbstractMesh,\n\tdata: Partial<MeshVisibilityState>\n) {\n\tif (Array.isArray(object.material)) {\n\t\tfor (let material of object.material) {\n\t\t\tupdateMaterialVisibilityProps(material as NodeMaterial, data);\n\t\t}\n\t} else {\n\t\tlet material = object.material;\n\t\tupdateMaterialVisibilityProps(material as NodeMaterial, data);\n\t}\n\tif (object.objectType === 'SubdivObject' && data.flatShading !== undefined) {\n\t\t// because we need quads to appear flat rather than as 2 triangles\n\t\t// we set flat shading to always be false, and delegate the calculating\n\t\t// the flat/smooth normals to WASM(to which we pass the object.smoothShading prop)\n\t\t(object.material as NodeMaterial).flatShading = false;\n\t\t(object as SubdivObject).smoothShading = !data.flatShading;\n\t\t(object as SubdivObject).updateMesh();\n\t}\n}\n\nexport function createMesh(\n\tid: string,\n\tdata: MeshObjectState,\n\tsharedAssets: SharedAssetsManager\n) {\n\tlet mesh;\n\tif (data.geometry.type === 'SubdivGeometry') {\n\t\tmesh = SubdivObject.createFromState(\n\t\t\tid,\n\t\t\tdata as SubdivObjectState,\n\t\t\tsharedAssets\n\t\t);\n\t} else {\n\t\tconst geometry = getGeometry(data.geometry, sharedAssets);\n\t\tconst material =\n\t\t\t'materials' in data\n\t\t\t\t? getMaterials(data.materials, sharedAssets)\n\t\t\t\t: getMaterial(data.material, sharedAssets);\n\n\t\tif (GeometryType.is2DParametricMesh(geometry.userData.type)) {\n\t\t\tmesh = new Mesh2D(geometry, material);\n\t\t} else if (geometry?.userData.type === 'VectorGeometry') {\n\t\t\tmesh = new VectorObject(geometry, material);\n\t\t} else if (data.geometry.type === 'NonParametricGeometry') {\n\t\t\tmesh = new NonParametric(geometry, material);\n\t\t} else {\n\t\t\tmesh = new Mesh3D(geometry, material);\n\t\t}\n\t\tmesh.uuid = id;\n\t\tmesh.fromState(data);\n\t}\n\tupdateMeshVisibilityProps(mesh, data);\n\treturn mesh;\n}\n", "import { CameraObjectState, CameraType, ObjectState } from 'spline-data';\nimport { Object3D } from 'three';\nimport {\n\tCombinedCamera,\n\tEmptyObject,\n\tLightDirectional,\n\tLightPoint,\n\tLightSpot,\n} from './entities';\nimport { createMesh } from './entities/create';\nimport { SharedAssetsManager } from '../shared/SharedAssetsManager';\nimport { Entity } from './entities/Entity';\nimport { TextFrame } from './entities/text';\n\nexport function createObject(\n\tid: string,\n\tdata: ObjectState,\n\tsharedAssets: SharedAssetsManager\n): Object3D & Entity {\n\tif (data.type === 'Mesh') {\n\t\treturn createMesh(id, data, sharedAssets);\n\t} else if (data.type === 'TextFrame') {\n\t\treturn TextFrame.createFromState(id, data, sharedAssets);\n\t} else if (data.type === 'Empty') {\n\t\treturn EmptyObject.createFromState(id, data);\n\t} else if (data.type === 'PointLight') {\n\t\treturn LightPoint.createFromState(id, data, sharedAssets);\n\t} else if (data.type === 'SpotLight') {\n\t\treturn LightSpot.createFromState(id, data, sharedAssets);\n\t} else if (data.type === 'DirectionalLight') {\n\t\treturn LightDirectional.createFromState(id, data, sharedAssets);\n\t} else if (CameraType.is(data.type)) {\n\t\treturn CombinedCamera.createFromState(id, data as CameraObjectState);\n\t}\n\n\tconsole.error(data);\n\treturn new EmptyObject();\n}\n", "import { wrapSingleton } from 'common';\nimport { WebGLRenderTarget } from 'three';\nimport { Layer, LAYER_TYPE, Material } from '../materials';\nimport { SharedAssetsManager } from '../shared/SharedAssetsManager';\nimport { AbstractMesh } from './entities';\nimport { Entity } from './entities/Entity';\nimport { Scene } from './Scene';\n\nfunction setTransmissionUniforms(\n\ttransmissionRenderTarget: WebGLRenderTarget,\n\tlayer: Layer\n): void {\n\tlayer.uniforms[`f${layer.id}_transmissionSamplerMap`].value =\n\t\ttransmissionRenderTarget.texture;\n\tlayer.uniforms[`f${layer.id}_transmissionDepthMap`].value =\n\t\ttransmissionRenderTarget.depthTexture;\n}\n\n// Return true if this mesh needed transmission\nfunction updateMeshAndMaterial(\n\ttransmissionRenderTarget: WebGLRenderTarget | undefined,\n\tmesh: AbstractMesh,\n\tmaterial: Material\n): boolean {\n\tif (!material.userData.layers) return false;\n\n\tlet needsTransmission = false;\n\n\tconst transmissionLayers = material.userData.layers.getLayersOfType(\n\t\tLAYER_TYPE.TRANSMISSION\n\t);\n\tif (transmissionLayers.length > 0) {\n\t\tmesh.layers.set(3);\n\t\tneedsTransmission = true;\n\n\t\tif (transmissionRenderTarget !== undefined) {\n\t\t\ttransmissionLayers.forEach((l: Layer) =>\n\t\t\t\tsetTransmissionUniforms(transmissionRenderTarget, l)\n\t\t\t);\n\t\t}\n\t} else {\n\t\tmesh.layers.set(0);\n\t}\n\treturn needsTransmission;\n}\n\nexport function updateTransmission(\n\ttransmissionRenderTarget: WebGLRenderTarget | undefined,\n\tscene: Scene\n): boolean {\n\tlet needsTransmission = false;\n\tscene.traverseEntity((e) => {\n\t\tif (e instanceof AbstractMesh) {\n\t\t\tif (Array.isArray(e.material)) {\n\t\t\t\tfor (let i = 0; i < e.material.length; i++) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tupdateMeshAndMaterial(\n\t\t\t\t\t\t\ttransmissionRenderTarget,\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\te.material[i] as Material\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tneedsTransmission = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tupdateMeshAndMaterial(\n\t\t\t\t\t\ttransmissionRenderTarget,\n\t\t\t\t\t\te,\n\t\t\t\t\t\te.material as Material\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tneedsTransmission = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn needsTransmission;\n}\n\nexport function objectDispose(\n\tobject: Entity,\n\tsharedAssets: SharedAssetsManager\n) {\n\tif ('material' in object) {\n\t\tmaterialDispose(object.material as Material | Material[], sharedAssets);\n\t}\n\n\tif ('geometry' in object) {\n\t\tobject.geometry.dispose();\n\t}\n}\n\nexport function materialDispose(\n\tmaterial: Material | Material[],\n\tsharedAssets: SharedAssetsManager\n) {\n\twrapSingleton(material).forEach((material) => {\n\t\tif (!sharedAssets.isSharedMaterial(material)) {\n\t\t\tmaterial.dispose();\n\t\t}\n\t});\n}\n", "import { RGB, RGBA, SharedAssetsData } from 'spline-data';\nimport {\n\tTexture,\n\tWebGLRenderTarget,\n\tLinearMipmapLinearFilter,\n\tLinearFilter,\n\tClampToEdgeWrapping,\n\tDepthTexture,\n} from 'three';\nimport { BasicMaterial, Material } from '../materials';\nimport { createMaterial } from '../materials/create';\nimport { ColorA } from '../objects/Color';\n\n/*\n\nHow should reference to assets to be handled:\n\nWhy it can happen that we reference to a deleted asset?\n\n - If two user concurrently perform these operations:\n - User A: delete the asset\n - User B: change a mesh to reference that material asset\n and the user B's action arrives after user A's action to the server\n\nWhat should we do? Ideally we should enable the user to recover the deleted asset, but it's kind of hard to change now.\n\nThe easiest thing to do for us now is:\n\n- In runtime layer, we know that a material reference can be set to a deleted asset,\n so each time we get an asset by id, we should failback to a default asset, so no crash happens because of undefined\n- In UI layer, we should check if the material exists in data layer. We should display that the asset is deleted, and the user can unlink as usual\n*/\nconst deletedMaterial = new BasicMaterial();\n\nexport class SharedColor extends ColorA {}\n\nexport class SharedAssetsManager {\n\ttransmissionRenderTarget: WebGLRenderTarget;\n\tprivate materials: Record<string, Material> = {};\n\tprivate images: Record<string, HTMLImageElement> = {};\n\tprivate colors: Record<string, SharedColor> = {};\n\n\tonImageLoad?: (id: string) => void;\n\n\tconstructor(data: SharedAssetsData) {\n\t\tthis.transmissionRenderTarget = new WebGLRenderTarget(2048, 2048, {\n\t\t\tgenerateMipmaps: true,\n\t\t\tminFilter: LinearMipmapLinearFilter,\n\t\t\tmagFilter: LinearFilter,\n\t\t\twrapS: ClampToEdgeWrapping,\n\t\t\twrapT: ClampToEdgeWrapping,\n\t\t});\n\t\tthis.transmissionRenderTarget.depthTexture = new DepthTexture(2048, 2048);\n\n\t\tthis.reset(data);\n\t}\n\n\treset(data: SharedAssetsData) {\n\t\t// Load all images and store them\n\t\tfor (let [id, imageData] of Object.entries(data.images)) {\n\t\t\tthis.addImage(id, imageData.data);\n\t\t}\n\n\t\t// Load all colors and store them\n\t\tfor (let [id, colorData] of Object.entries(data.colors)) {\n\t\t\tthis.addColor(id, colorData);\n\t\t}\n\n\t\t// Creating materials needs to happen after storing the images and textures\n\t\tfor (let [id, materialData] of Object.entries(data.materials)) {\n\t\t\tthis.addMaterial(id, createMaterial(materialData, this));\n\t\t}\n\t}\n\n\tget transmissionSamplerMap(): Texture {\n\t\treturn this.transmissionRenderTarget.texture;\n\t}\n\n\tget transmissionDepthMap(): Texture {\n\t\treturn this.transmissionRenderTarget.depthTexture;\n\t}\n\n\taddMaterial(id: string, material: Material) {\n\t\tmaterial.uuid = id;\n\t\tthis.materials[id] = material;\n\t}\n\n\tdeleteMaterial(id: string) {\n\t\tif (this.materials[id]) {\n\t\t\tthis.materials[id].dispose();\n\t\t\tdelete this.materials[id];\n\t\t}\n\t}\n\n\t// TODO better with a marker class like SharedColor, but currently Material is not a class but a type\n\tisSharedMaterial(material: Material): boolean {\n\t\treturn material.uuid in this.materials || material === deletedMaterial;\n\t}\n\n\tgetMaterial(id: string): Material {\n\t\tlet material = this.materials[id];\n\t\tif (material === undefined) {\n\t\t\t// throw new Error('illegal state ' + id);\n\t\t}\n\t\treturn material;\n\t}\n\n\tgetMaterialOrDeletedPlaceholder(id: string): Material {\n\t\treturn this.materials[id] ?? deletedMaterial;\n\t}\n\n\tgetMaterials() {\n\t\treturn this.materials;\n\t}\n\n\t// Returns true if a key was overwritten, false otherwise\n\taddImage(id: string, imgSrc: string): boolean {\n\t\tif (this.images[id]) {\n\t\t\tthis.images[id].onload = () => {\n\t\t\t\tthis.onImageLoad && this.onImageLoad(id);\n\t\t\t};\n\t\t\tthis.images[id].src = imgSrc;\n\t\t\treturn true;\n\t\t} else {\n\t\t\tconst img = new Image();\n\t\t\timg.src = imgSrc;\n\t\t\timg.onload = () => {\n\t\t\t\tthis.onImageLoad && this.onImageLoad(id);\n\t\t\t};\n\t\t\tthis.images[id] = img;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tdeleteImage(id: string): void {\n\t\tif (this.images[id]) {\n\t\t\tdelete this.images[id];\n\t\t}\n\t}\n\n\tgetDefaultImage() {\n\t\treturn this.images['image_0'];\n\t}\n\n\tgetImage(id: string) {\n\t\treturn this.images[id];\n\t}\n\n\tgetImages() {\n\t\treturn this.images;\n\t}\n\n\t// Return true if the color was overwritten, false otherwise\n\taddColor(id: string, colorData: RGB | RGBA) {\n\t\tif (this.colors[id]) {\n\t\t\tif ('a' in colorData) {\n\t\t\t\tthis.colors[id].setRGBA(\n\t\t\t\t\tcolorData.r,\n\t\t\t\t\tcolorData.g,\n\t\t\t\t\tcolorData.b,\n\t\t\t\t\tcolorData.a\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.colors[id].setRGBA(colorData.r, colorData.g, colorData.b, 1);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tif ('a' in colorData) {\n\t\t\tthis.colors[id] = new SharedColor(\n\t\t\t\tcolorData.r,\n\t\t\t\tcolorData.g,\n\t\t\t\tcolorData.b,\n\t\t\t\tcolorData.a\n\t\t\t);\n\t\t} else {\n\t\t\tthis.colors[id] = new SharedColor(\n\t\t\t\tcolorData.r,\n\t\t\t\tcolorData.g,\n\t\t\t\tcolorData.b,\n\t\t\t\t1.0\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\tupdateColor(id: string, colorData: Partial<RGBA>) {\n\t\tif (this.colors[id]) {\n\t\t\tconst oldColor = this.colors[id];\n\t\t\tthis.colors[id].r = colorData.r ?? oldColor.r;\n\t\t\tthis.colors[id].g = colorData.g ?? oldColor.g;\n\t\t\tthis.colors[id].b = colorData.b ?? oldColor.b;\n\t\t\tthis.colors[id].a = colorData.a ?? oldColor.a;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdeleteColor(id: string) {\n\t\tif (this.colors[id]) {\n\t\t\tdelete this.colors[id];\n\t\t}\n\t}\n\n\tgetColor(id: string) {\n\t\treturn this.colors[id];\n\t}\n\n\tdispose() {\n\t\tconst ids = Object.keys(this.materials);\n\t\tids.forEach((id) => this.deleteMaterial(id));\n\t\tthis.transmissionRenderTarget.depthTexture.dispose();\n\t\tthis.transmissionRenderTarget.dispose();\n\t\tthis.onImageLoad = undefined;\n\t}\n}\n"],
5
+ "mappings": "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GACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,EACA,EACA,CAAC,EACD,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,EACA,EACA,CAAC,EACD,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,GACA,GACA,EACA,EACA,CAAC,EACD,EACA,EACA,GAGG,EAAe,GAGlB,GACC,IACA,IACA,IACA,GACA,GACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,GACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,GACA,EACA,GACA,EACA,EACA,EACA,EACA,GAED,EAAU,IAAK,IAAK,IAAK,EAAG,EAAG,EAAG,EAAO,EAAQ,EAAO,EAAe,GACvE,EACC,IACA,IACA,IACA,GACA,GACA,GACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,GACA,GACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,GACA,GACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GAED,EACC,IACA,IACA,IACA,GACA,EACA,GACA,EACA,EACA,EACA,EACA,GAKD,EAAY,EAAG,EAAG,GAClB,EAAY,GAAI,EAAG,GACnB,EAAY,EAAG,GAAI,GACnB,EAAY,GAAI,GAAI,GACpB,EAAY,EAAG,EAAG,IAClB,EAAY,GAAI,EAA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",
6
+ "names": []
7
+ }