@s25studio/sinth 1.0.0 → 1.0.3

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @s25studio/sinth
2
2
 
3
- Sinth 1.0.0 — build snapshot `v48`.
3
+ Sinth 1.0.3 — build snapshot `v51`.
4
4
 
5
5
  Real-time 3D pattern engine for the web. Every release is published under a new
6
6
  version, so a URL you pin today serves the same bytes forever.
@@ -9,25 +9,10 @@ Three.js is never bundled in. Sinth and Three are always loaded as two files,
9
9
  so a page that already has Three does not download a second copy, and the two
10
10
  can be cached and upgraded independently.
11
11
 
12
- ## Two script tags (Webflow, WordPress, Shopify, plain HTML)
12
+ ## Modules the recommended route
13
13
 
14
- Three first `sinth.min.js` reads the global `THREE` that `three.min.js`
15
- installs, and refuses to run with a console error if it is missing.
16
-
17
- ```html
18
- <script src="https://unpkg.com/@s25studio/sinth@1.0.0/dist/three-1.0.0.min.js"></script>
19
- <script src="https://unpkg.com/@s25studio/sinth@1.0.0/dist/sinth-1.0.0.min.js"></script>
20
- ```
21
-
22
- `three.min.js` is our IIFE wrapper around three.js 0.184.0, not a file from
23
- three's own package: three ships ES modules only since r150, so there is nothing
24
- on unpkg that a plain `<script src>` can load. If your page can use modules,
25
- prefer the import map below and take three straight from its own package.
26
-
27
- ## Modules (bundlers, import maps)
28
-
29
- three.js is a **peer dependency** — this build imports it rather than bundling
30
- it, so your project's own copy is the only copy.
14
+ Three is a **peer dependency**: this build imports it, so your project's own
15
+ copy is the only copy on the page.
31
16
 
32
17
  ```bash
33
18
  npm i @s25studio/sinth three@0.184.0
@@ -37,8 +22,8 @@ npm i @s25studio/sinth three@0.184.0
37
22
  import { createSinthEmbed } from '@s25studio/sinth';
38
23
  ```
39
24
 
40
- From a CDN with no build step, name three.js in an import map — it ships ESM
41
- only, so this is the form a browser can resolve:
25
+ With no build step, name Three in an import map — **this is the route that
26
+ takes Three straight from Three's own package:**
42
27
 
43
28
  ```html
44
29
  <script type="importmap">
@@ -49,36 +34,34 @@ only, so this is the form a browser can resolve:
49
34
  }
50
35
  </script>
51
36
  <script type="module">
52
- import { createSinthEmbed } from 'https://unpkg.com/@s25studio/sinth@1.0.0/dist/esm/sinth.js';
37
+ import { createSinthEmbed } from 'https://unpkg.com/@s25studio/sinth@1.0.3/dist/esm/sinth.js';
53
38
 
54
39
  createSinthEmbed({ container: document.querySelector('#hero'), preset: 'waves' });
55
40
  </script>
56
41
  ```
57
42
 
58
- The import map must appear before the module script that uses it.
43
+ The import map must appear before any module script that uses it, and a page
44
+ can only carry one — if the site already has an import map, add the `three`
45
+ entry to it rather than adding a second.
59
46
 
60
- ## Using it
47
+ ## Plain script tags — when the page cannot use modules
61
48
 
62
- The script builds expose `window.Sinth` and auto-mount any element carrying the
63
- Sinth container class. To place one yourself:
64
-
65
- ```js
66
- const { createSinthEmbed, VERSION } = window.Sinth;
67
-
68
- console.log(VERSION); // "1.0.0"
69
-
70
- createSinthEmbed({
71
- container: document.querySelector('#hero'),
72
- preset: 'waves',
73
- });
49
+ ```html
50
+ <script src="https://unpkg.com/@s25studio/sinth@1.0.3/dist/three-0.184.0.min.js"></script>
51
+ <script src="https://unpkg.com/@s25studio/sinth@1.0.3/dist/sinth-1.0.3.min.js"></script>
74
52
  ```
75
53
 
76
- ## Filenames carry the version
54
+ Three first `sinth.min.js` reads the global `THREE` that `three.min.js`
55
+ installs, and refuses to run with a console error if it is missing.
77
56
 
78
- Each artifact ships twice: `sinth-1.0.0.min.js` names its build in the
79
- filename itself, and `sinth.min.js` keeps floating URLs
80
- (`@s25studio/sinth@^1.0/dist/sinth.min.js`)
81
- working across upgrades. Identical bytes either way.
57
+ **Why Three comes from this package here and not from `three`.** Three.js
58
+ dropped its UMD build in r150. `unpkg.com/three@0.184.0/build/` contains
59
+ `three.module.js`, `three.core.js`, `three.cjs` and the WebGPU variants —
60
+ ES modules and CommonJS, nothing a plain `<script src>` can execute. So there
61
+ is no Three URL to link to for this route. `three-0.184.0.min.js` is Three
62
+ 0.184.0 exactly, wrapped in an IIFE that assigns `window.THREE`; it is
63
+ stamped with Three's version rather than Sinth's for that reason. Use the import
64
+ map above whenever you can, and this pair only when you cannot.
82
65
 
83
66
  ## Text geometry fonts
84
67
 
package/dist/esm/sinth.js CHANGED
@@ -1,6 +1,6 @@
1
- /*! Sinth 1.0.0 (v48) · @s25studio/sinth@1.0.0 · https://unpkg.com/@s25studio/sinth@1.0.0
1
+ /*! Sinth 1.0.3 (v51) · @s25studio/sinth@1.0.3 · https://unpkg.com/@s25studio/sinth@1.0.3
2
2
  * Copyright (c) 2026 S25 Studio. Licensed, not sold — see LICENSE.md in the
3
- * package or https://unpkg.com/@s25studio/sinth@1.0.0/LICENSE.md
3
+ * package or https://unpkg.com/@s25studio/sinth@1.0.3/LICENSE.md
4
4
  *
5
5
  * Bundles three.js addons and, via TTFLoader, opentype.js — both MIT. The
6
6
  * script build three.min.js inlines three.js itself.
@@ -4064,6 +4064,6 @@ function pr() {
4064
4064
  }
4065
4065
  //#endregion
4066
4066
  //#region src/version.ts
4067
- var mr = "1.0.0", hr = "v48", gr = `${mr} · v48`;
4067
+ var mr = "1.0.3", hr = "v51", gr = `${mr} · v51`;
4068
4068
  //#endregion
4069
4069
  export { Gn as SINTH_CONTAINER_CLASS, hr as SNAPSHOT, mr as VERSION, gr as VERSION_LABEL, tr as createSinthEmbed, n as fontBaseUrl, dr as mountAll, yn as normalizeSinthConfig, Qn as resolveContainer, l as setFontBaseUrl, pr as startAutoMount };
@@ -1,6 +1,6 @@
1
- /*! Sinth 1.0.0 (v48) · @s25studio/sinth@1.0.0 · https://unpkg.com/@s25studio/sinth@1.0.0
1
+ /*! Sinth 1.0.3 (v51) · @s25studio/sinth@1.0.3 · https://unpkg.com/@s25studio/sinth@1.0.3
2
2
  * Copyright (c) 2026 S25 Studio. Licensed, not sold — see LICENSE.md in the
3
- * package or https://unpkg.com/@s25studio/sinth@1.0.0/LICENSE.md
3
+ * package or https://unpkg.com/@s25studio/sinth@1.0.3/LICENSE.md
4
4
  *
5
5
  * Bundles three.js addons and, via TTFLoader, opentype.js — both MIT. The
6
6
  * script build three.min.js inlines three.js itself.
@@ -674,4 +674,4 @@ ${n.materialTexture?`vec4 speMaterialTextureColor = getSpeMaterialTextureColor()
674
674
  diffuseColor.rgb *= speMaterialTextureColor.rgb;
675
675
  diffuseColor.a *= speMaterialTextureColor.a;`:``}`).replace(`#include <alphatest_fragment>`,`diffuseColor.a *= vInstanceOpacity;
676
676
  if (diffuseColor.a <= 0.001) discard;
677
- #include <alphatest_fragment>`)},e.customProgramCacheKey=()=>[`spe-instance-opacity`,n.alphaHash?`alpha-hash`:`transparent`,n.objectGradient?`object-gradient`:`solid`,n.materialTexture?`material-texture`:`no-material-texture`].join(`:`),e}rebuildGeometry(){let e=this.createGeometry();this.mesh.geometry.dispose(),this.outlineMesh.geometry.dispose(),this.edgeGeometry?.dispose(),this.mesh.geometry=e,this.outlineMesh.geometry=e.clone(),this.edgeGeometry=this.createEdgeGeometry(e),this.syncImageSetMeshes(),this.rebuildEdgeLines(),this.updatePattern()}setInstanceShape(e){this.settings.instanceShape=e,this.settings.colorMode===`texture`&&!this.isTextureMaterialShape()&&(this.settings.colorMode=`solid`),this.applyInstanceShapeDefaults(e),this.updateMaterial(),this.rebuildGeometry()}applyInstanceShapeDefaults(e){if(this.scaleBeforeShapeDefault&&(this.shapeAutoModified.x&&(this.settings.scaleX=this.scaleBeforeShapeDefault.x),this.shapeAutoModified.y&&(this.settings.scaleY=this.scaleBeforeShapeDefault.y),this.shapeAutoModified.z&&(this.settings.scaleZ=this.scaleBeforeShapeDefault.z)),this.scaleBeforeShapeDefault={x:this.settings.scaleX,y:this.settings.scaleY,z:this.settings.scaleZ},this.shapeAutoModified={x:!1,y:!1,z:!1},e===`pill`){let e=Math.max(this.settings.scaleX,this.settings.scaleZ),t=Math.max(this.settings.scaleY,e*2.8);t!==this.settings.scaleY&&(this.settings.scaleY=t,this.shapeAutoModified.y=!0)}}setInstanceDimension(e,t){this.shapeAutoModified[e]=!1;let n=I(t,$.scaleX,P.instance.dimension);e===`x`?(this.settings.scaleX=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleZ=I(n/this.settings.imageAspectRatio,$.scaleZ,P.instance.dimension))):e===`y`?this.settings.scaleY=n:(this.settings.scaleZ=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(n*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension))),this.syncRoundedCardRatio(),this.rebuildGeometry()}setImagePreserveAspectRatio(e){this.settings.imagePreserveAspectRatio=e,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(this.settings.scaleZ*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension)),this.rebuildGeometry()}shouldLockImageAspectRatio(){return this.settings.instanceShape===`image`&&this.settings.imagePreserveAspectRatio&&this.settings.imageAspectRatio>0}async ensureTextRuntimeLoaded(){if(!(this.textGeometryRuntime&&this.textFonts)){if(this.textRuntimeLoadPromise){await this.textRuntimeLoadPromise;return}this.textRuntimeLoadPromise=Promise.resolve().then(()=>(Au(),xu)).then(async e=>{this.textGeometryRuntime=e,this.textFonts??=new e.TextFontManager,this.settings.textFontSource.source===`url`&&await this.textFonts.loadCustomFont(this.settings.textFontSource.url)}).finally(()=>{this.textRuntimeLoadPromise=null}),await this.textRuntimeLoadPromise}}scheduleTextRuntimeLoad(){this.ensureTextRuntimeLoaded().then(()=>{this.settings.instanceShape===`text`&&this.rebuildGeometry()}).catch(e=>{console.warn(`Unable to load text runtime support.`,e)})}async loadCustomTextFont(e=this.settings.textCustomFontUrl){let t=e.trim();if(!t){this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.settings.textCustomFontUrl=``,this.rebuildGeometry();return}await this.ensureTextRuntimeLoaded(),await this.textFonts?.loadCustomFont(t),this.settings.textCustomFontUrl=t,this.settings.textFont=`custom`,this.settings.textFontSource={source:`url`,url:t},this.rebuildGeometry()}async ensureWebTextFont(e){await this.ensureTextRuntimeLoaded(),!this.textFonts?.hasFont(e)&&(await this.textFonts?.loadWebFont(e),this.settings.textFont===e&&this.settings.instanceShape===`text`&&this.rebuildGeometry())}setTextFont(e){if(this.settings.textFont=e,e===`custom`){this.settings.textCustomFontUrl.trim()?this.loadCustomTextFont().catch(e=>{console.warn(`Unable to load custom text font.`,e)}):(this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.rebuildGeometry());return}this.settings.textFontSource={source:`library`,id:e},this.settings.textCustomFontUrl=``,Dt(e)&&this.ensureWebTextFont(e).catch(e=>{console.warn(`Unable to load text font.`,e)}),this.rebuildGeometry()}syncRoundedCardRatio(){this.settings.instanceShape===`rounded-card`&&(this.settings.roundedCardRatio=this.settings.scaleX/Math.max(.01,this.settings.scaleZ))}async loadCustomObj(e=this.settings.assetUrl,t={}){await this.loadCustomAsset(e,t)}async loadCustomAsset(e=this.settings.assetUrl,{showPlaceholder:t=!1,source:n=`background`}={}){let r=e.trim();if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let i=++this.customAssetLoadId;if(n===`user`&&(this.activeUserCustomAssetLoadId=i),this.settings.assetUrl=r,!r){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry();return}t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry());try{let e=await Promise.resolve().then(()=>(cf(),qd)),t=await e.loadCustomAssetGeometry(sp(r));this.completeCustomAssetLoad(i,t,e.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadCustomFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearCustomAssetLoad(i);return}let t=await Promise.resolve().then(()=>(cf(),qd)),n=await t.loadCustomAssetGeometryFromFile(e);this.completeCustomAssetLoad(i,n,t.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearSvgAssetLoad(r);return}let e=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometry(sp(n),this.settings.svgSolidify);this.completeSvgAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearSvgAssetLoad(i);return}let t=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometryFromFile(e,this.settings.svgSolidify);this.completeSvgAssetLoad(i,t)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearImageAssetLoad(r);return}let e=await this.textureLoader.loadAsync(sp(n));this.completeImageAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageFile(e,t,n={}){await this.loadImageAsset(t,n)}async loadImageSet(e=this.settings.imageSetUrls,t={}){let n=op(e),r=this.beginCustomAssetLoad(n[0]??``,t);try{if(n.length===0){this.clearImageAssetLoad(r);return}let e=await Promise.all(n.map(e=>this.textureLoader.loadAsync(sp(e))));this.completeImageSetAssetLoad(r,n,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadBackgroundImage(e=this.settings.backgroundImageUrl){let t=e.trim();if(this.settings.backgroundImageUrl=t,!t){this.clearBackgroundImage();return}let n=await this.textureLoader.loadAsync(sp(t));this.backgroundTexture?.dispose(),this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.backgroundTexture=n,this.configureImageTexture(n),this.settings.backgroundMode=`image`,this.updateSceneBackground(),this.renderIdleFrame()}async loadBackgroundImageFile(e,t){await this.loadBackgroundImage(t)}async loadMaterialTexture(e=this.settings.materialTextureUrl){let n=e.trim();if(this.settings.materialTextureUrl=n,!n){this.clearMaterialTexture();return}let r=await this.textureLoader.loadAsync(sp(n));this.materialTexture?.dispose(),this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.materialTexture=r,this.configureImageTexture(r),r.wrapS=t.RepeatWrapping,r.wrapT=t.RepeatWrapping,this.settings.colorMode=`texture`,this.updateMaterial(),this.renderIdleFrame()}async loadMaterialTextureFile(e,t){await this.loadMaterialTexture(t)}clearMaterialTexture(){this.settings.materialTextureUrl=``,this.materialTexture?.dispose(),this.materialTexture=null,this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.updateMaterial(),this.renderIdleFrame()}clearBackgroundImage(){this.settings.backgroundImageUrl=``,this.backgroundTexture?.dispose(),this.backgroundTexture=null,this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.updateSceneBackground(),this.renderIdleFrame()}clearCustomAsset(){this.customAssetLoadId+=1,this.activeUserCustomAssetLoadId=0,this.settings.assetUrl=``,this.settings.imageSetUrls=[],this.settings.imageAspectRatio=$.imageAspectRatio,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.updateMaterial(),this.rebuildGeometry()}clearSvgAssetLoad(e){this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}beginCustomAssetLoad(e,{showPlaceholder:t=!1,source:n=`background`}){if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let r=++this.customAssetLoadId;return n===`user`&&(this.activeUserCustomAssetLoadId=r),this.settings.assetUrl=e,t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry()),r}clearCustomAssetLoad(e){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}clearImageAssetLoad(e){this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.settings.imageAspectRatio=$.imageAspectRatio,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeCustomAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw t.dispose(),new wf;this.customAssetLoadId=e,n(t,{assetScale:this.settings.assetScale,assetNormalize:this.settings.assetNormalize}),this.customObjGeometry=t,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`custom-obj`,r&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}completeSvgAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.customSvgGeometry?.dispose(),this.customSvgGeometry=t,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`svg`,n&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.configureImageTexture(t),this.imageTexture=t,this.imageSetTextures=[t],this.settings.imageSetUrls=[];let r=t.image,i=r?.width??$.imageAspectRatio,a=r?.height??1;this.settings.imageAspectRatio=a>0?Math.max(.01,i/a):$.imageAspectRatio,this.settings.instanceShape=`image`,n&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageSetAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw n.forEach(e=>e.dispose()),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,n.forEach(e=>this.configureImageTexture(e)),this.imageSetTextures=n,this.imageTexture=n[0]??null,this.settings.assetUrl=t[0]??``,this.settings.imageSetUrls=t;let i=this.imageTexture?.image,a=i?.width??$.imageAspectRatio,o=i?.height??1;this.settings.imageAspectRatio=o>0?Math.max(.01,a/o):$.imageAspectRatio,this.settings.instanceShape=`image`,r&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}configureImageTexture(e){e.colorSpace=t.SRGBColorSpace,e.needsUpdate=!0}updateSceneBackground(){if(this.settings.backgroundMode===`transparent`){this.scene.background=null;return}if(this.settings.backgroundMode===`image`){this.scene.background=this.updateBackgroundImageDisplayTexture();return}if(this.settings.backgroundMode===`gradient`){this.scene.background=this.updateBackgroundGradientTexture();return}this.scene.background=new t.Color(this.settings.backgroundColor)}invalidateBackgroundImageDisplayTexture(){this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null}invalidateTransparentBackgroundPreviewTexture(){this.transparentBackgroundPreviewTexture?.dispose(),this.transparentBackgroundPreviewTexture=null}updateTransparentBackgroundPreviewTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.max(1,Math.round(e)),i=Math.max(1,Math.round(n)),a=this.transparentBackgroundPreviewTexture,o=a?.image instanceof HTMLCanvasElement?a.image:document.createElement(`canvas`);if(a&&o.width===r&&o.height===i)return a;o.width=r,o.height=i;let s=o.getContext(`2d`);return s&&this.drawCheckerBackground(s,r,i),this.transparentBackgroundPreviewTexture||(this.transparentBackgroundPreviewTexture=new t.CanvasTexture(o),this.transparentBackgroundPreviewTexture.colorSpace=t.SRGBColorSpace,this.transparentBackgroundPreviewTexture.wrapS=t.ClampToEdgeWrapping,this.transparentBackgroundPreviewTexture.wrapT=t.ClampToEdgeWrapping),this.transparentBackgroundPreviewTexture.needsUpdate=!0,this.transparentBackgroundPreviewTexture}updateBackgroundImageDisplayTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.min(1,1600/Math.max(e,n)),i=Math.max(1,Math.round(e*r)),a=Math.max(1,Math.round(n*r)),o=i/a,s=this.backgroundImageDisplayTexture?.image instanceof HTMLCanvasElement?this.backgroundImageDisplayTexture.image:document.createElement(`canvas`);s.width=i,s.height=a;let c=s.getContext(`2d`);if(!c)return this.backgroundTexture??this.getCheckerTexture();if(!this.backgroundTexture)this.drawCheckerBackground(c,i,a);else{let e=this.backgroundTexture.image,t=this.getTextureImageAspect(this.backgroundTexture);if(!t)return this.backgroundTexture;c.fillStyle=this.settings.backgroundColor,c.fillRect(0,0,i,a);let n=this.settings.backgroundImageFit===`fit`?t>o?i/this.getTextureImageWidth(this.backgroundTexture):a/this.getTextureImageHeight(this.backgroundTexture):t>o?a/this.getTextureImageHeight(this.backgroundTexture):i/this.getTextureImageWidth(this.backgroundTexture),r=this.getTextureImageWidth(this.backgroundTexture)*n,s=this.getTextureImageHeight(this.backgroundTexture)*n;c.drawImage(e,(i-r)*.5,(a-s)*.5,r,s)}return this.backgroundImageDisplayTexture||(this.backgroundImageDisplayTexture=new t.CanvasTexture(s),this.backgroundImageDisplayTexture.colorSpace=t.SRGBColorSpace,this.backgroundImageDisplayTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundImageDisplayTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundImageDisplayTexture.needsUpdate=!0,this.backgroundImageDisplayTexture}drawCheckerBackground(e,t,n){e.fillStyle=Mf,e.fillRect(0,0,t,n),e.fillStyle=Nf;for(let r=0;r<n;r+=Af)for(let n=r/Af%2==0?Af:0;n<t;n+=Af*2)e.fillRect(n,r,Af,Af)}updateBackgroundGradientTexture(){let e=this.backgroundGradientTexture?.image instanceof HTMLCanvasElement?this.backgroundGradientTexture.image:document.createElement(`canvas`);e.width=512,e.height=512;let n=e.getContext(`2d`);if(!n)return new t.Color(this.settings.backgroundColor);let r=n.createImageData(512,512),i=new t.Color(this.settings.backgroundGradientColorA),a=new t.Color(this.settings.backgroundGradientColorB),o=new t.Color,s=Qf(this.settings.backgroundGradientMidpoint),c=511*.5,l=Math.max(1e-4,Math.hypot(c,c));for(let e=0;e<512;e+=1)for(let t=0;t<512;t+=1){let n=this.getBackgroundGradientProgress(t,e,512,c,l),u=at(this.remapGradientProgressWithMidpoint(n,s),this.settings.backgroundGradientEasing,this.settings.backgroundGradientCustomBezier);o.copy(i).lerp(a,u);let d=(e*512+t)*4;r.data[d]=Math.round(o.r*255),r.data[d+1]=Math.round(o.g*255),r.data[d+2]=Math.round(o.b*255),r.data[d+3]=255}return n.putImageData(r,0,0),this.backgroundGradientTexture||(this.backgroundGradientTexture=new t.CanvasTexture(e),this.backgroundGradientTexture.colorSpace=t.SRGBColorSpace,this.backgroundGradientTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundGradientTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundGradientTexture.needsUpdate=!0,this.backgroundGradientTexture}getBackgroundGradientProgress(e,n,r,i,a){return this.settings.backgroundGradientDirection===`x`?r<=1?.5:e/(r-1):this.settings.backgroundGradientDirection===`radial`?t.MathUtils.clamp(Math.hypot(e-i,n-i)/a,0,1):r<=1?.5:1-n/(r-1)}getTextureImageAspect(e){let t=this.getTextureImageWidth(e),n=this.getTextureImageHeight(e);return t<=0||n<=0?null:t/n}getTextureImageWidth(e){let t=e.image;return t?.naturalWidth??t?.width??0}getTextureImageHeight(e){let t=e.image;return t?.naturalHeight??t?.height??0}disposeImageSetTextures(){this.imageSetTextures.forEach(e=>{e!==this.imageTexture&&e.dispose()}),this.imageSetTextures=[]}createGeometry(){return this.settings.instanceShape===`text`&&(!this.textGeometryRuntime||!this.textFonts)&&this.scheduleTextRuntimeLoad(),this.settings.instanceShape===`image`&&this.imageTexture?this.createImageGeometryForTexture(this.imageTexture):this.settings.instanceShape===`image`&&!this.imageTexture||this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createImagePlaceholderGeometry():Bt({settings:this.settings,customObjGeometry:this.customObjGeometry,customSvgGeometry:this.customSvgGeometry,textGeometry:this.textGeometryRuntime&&this.textFonts?{createTextGeometry:this.textGeometryRuntime.createTextGeometry,textFonts:this.textFonts}:null})}getInstanceDimensions(){return Ot(this.settings)}createMaterial(){let e,n=this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`,r=this.usesMaterialTextureSurface();if(e=this.settings.instanceShape===`image`?this.imageTexture?this.createImageMaterial(this.imageTexture):this.createCheckerImageMaterial():this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createCheckerImageMaterial():this.settings.shadingMode===`flat`||this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`?new t.MeshBasicMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):this.settings.shadingMode===`toon`?new t.MeshToonMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):new t.MeshStandardMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor,roughness:this.settings.roughness,metalness:this.settings.metalness}),n)e.side=t.DoubleSide,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;else{let n=this.settings.instanceShape===`image`,r=this.settings.instanceShape===`svg`&&!this.settings.svgSolidify,i=this.settings.instanceShape===`text`&&!this.settings.textSolidify,a=this.settings.instanceShape===`custom-obj`&&this.settings.assetDoubleSided;(n||r||i||a)&&(e.side=t.DoubleSide),e.polygonOffset=!0,e.polygonOffsetFactor=1,e.polygonOffsetUnits=1}return this.enableInstanceOpacity(e,{alphaHash:!0,objectGradient:this.usesObjectGradient(),materialTexture:r})}usesGradientSurfaceColor(){return this.settings.colorMode===`gradient`&&this.settings.instanceShape!==`image`}usesMaterialTextureSurface(){return this.settings.colorMode===`texture`&&this.isTextureMaterialShape()}isTextureMaterialShape(){return this.settings.instanceShape!==`image`&&this.settings.instanceShape!==`svg`}usesInstanceColors(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`pattern`}usesObjectGradient(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`object`}getMaterialTextureModeIndex(){return this.materialTexture?this.settings.materialTextureFit===`fit`?1:this.settings.materialTextureFit===`fill`?2:this.settings.materialTextureFit===`repeat`?3:0:3}getMaterialTextureScopeIndex(){return+(this.settings.materialTextureScope===`pattern`)}getMaterialTextureProjectionIndex(){return+(this.settings.materialTextureProjection===`triplanar`)}createImageMaterial(e){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:e,transparent:!0,alphaTest:.01,depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}createCheckerImageMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:this.getCheckerTexture(),depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}getMaterialTexture(){return this.materialTexture??this.getCheckerTexture()}getMaterialTextureRepeat(e){return this.materialTexture?Math.max(.001,e):jf}getCheckerTexture(){if(this.checkerTexture)return this.checkerTexture;let e=document.createElement(`canvas`);e.width=kf*2,e.height=kf*2;let n=e.getContext(`2d`);return n&&(n.fillStyle=Mf,n.fillRect(0,0,e.width,e.height),n.fillStyle=Nf,n.fillRect(kf,0,kf,kf),n.fillRect(0,kf,kf,kf)),this.checkerTexture=new t.CanvasTexture(e),this.checkerTexture.colorSpace=t.SRGBColorSpace,this.checkerTexture.wrapS=t.RepeatWrapping,this.checkerTexture.wrapT=t.RepeatWrapping,this.checkerTexture.magFilter=t.NearestFilter,this.checkerTexture.minFilter=t.NearestFilter,this.checkerTexture.repeat.set(jf,jf),this.checkerTexture.needsUpdate=!0,this.checkerTexture}getTextureAspectRatio(e){let t=e.image,n=t?.width??$.imageAspectRatio,r=t?.height??1;return r>0?Math.max(.01,n/r):$.imageAspectRatio}createImageGeometryForTexture(e){let{scaleX:n,scaleZ:r}=this.getInstanceDimensions(),i=this.settings.imagePreserveAspectRatio?r*this.getTextureAspectRatio(e):n,a=Math.min(.5,Math.max(0,this.settings.imageCornerRadius)),o=a>0?rp(i,r,Math.min(i,r)*a):new t.PlaneGeometry(i,r);return o.rotateX(-Math.PI/2),o}createImagePlaceholderGeometry(){let{scaleX:e,scaleZ:n}=this.getInstanceDimensions(),r=new t.PlaneGeometry(e,n);return r.rotateX(-Math.PI/2),r}createOutlineMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({color:this.settings.silhouetteColor,side:t.BackSide,opacity:1,depthTest:!0,depthWrite:!0}),{alphaHash:!0})}createEdgeGeometry(e){let n=new t.EdgesGeometry(e,1),r=n.getAttribute(`position`).array,i=new p;return i.setPositions(Array.from(r)),n.dispose(),i}createEdgeMaterial(){let e=new m({color:new t.Color(this.settings.edgeColor).getHex(),linewidth:this.settings.edgeThickness*1e3,transparent:!0,opacity:this.settings.outlineOpacity,depthTest:!this.settings.outlineSeeThrough,depthWrite:!1,polygonOffset:!1,polygonOffsetFactor:0,polygonOffsetUnits:0}),{width:n,height:r}=this.getContainerSize();return e.resolution.set(n,r),e}shouldShowSilhouetteOutline(){return this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`silhouette-edge-outline`}shouldShowEdgeOutline(){return this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`}createEdgeLine(){if(!this.edgeGeometry||!this.edgeMaterial)return null;let e=this.edgeMaterial.clone(),{width:t,height:n}=this.getContainerSize();e.resolution.set(t,n),e.depthTest=!this.settings.outlineSeeThrough,e.depthWrite=!1,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;let r=new N(this.edgeGeometry,e);return r.renderOrder=this.getEdgeRenderOrder(),r.matrixAutoUpdate=!1,r.frustumCulled=!1,r}syncImageSetMeshes(){let e=this.getImageTextures(),n=Math.max(0,e.length-1),r=this.mesh.instanceMatrix.count;for(;this.imageSetMeshes.length>n;){let e=this.imageSetMeshes.pop();e&&(this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material))}for(;this.imageSetMeshes.length<n;){let n=e[this.imageSetMeshes.length+1],i=new t.InstancedMesh(this.createImageGeometryForTexture(n),this.createImageMaterial(n),r);i.renderOrder=this.mesh.renderOrder,i.frustumCulled=!1,this.imageSetMeshes.push(i),this.scene.add(i)}this.imageSetMeshes.forEach((n,i)=>{let a=e[i+1];if(n.instanceMatrix.count!==r){let e=new t.InstancedMesh(this.createImageGeometryForTexture(a),this.createImageMaterial(a),r);e.renderOrder=n.renderOrder,e.frustumCulled=!1,e.count=n.count,this.scene.remove(n),n.geometry.dispose(),this.disposeMeshMaterial(n.material),this.imageSetMeshes[i]=e,this.scene.add(e);return}n.geometry.dispose(),n.geometry=this.createImageGeometryForTexture(a),this.disposeMeshMaterial(n.material),n.material=this.createImageMaterial(a),n.renderOrder=this.mesh.renderOrder}),this.syncImageSetMeshTransforms()}disposeImageSetMeshes(){this.imageSetMeshes.forEach(e=>{this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material)}),this.imageSetMeshes=[]}disposeMeshMaterial(e){if(Array.isArray(e)){e.forEach(e=>e.dispose());return}e.dispose()}rebuildEdgeLines(){this.edgeLines.forEach(e=>{this.edgeGroup.remove(e),this.disposeMeshMaterial(e.material)}),this.edgeLines=[],this.shouldShowEdgeOutline()&&this.syncEdgeLineCount()}syncEdgeLineCount(){if(!this.shouldShowEdgeOutline()){this.edgeGroup.visible=!1;return}for(this.edgeGroup.visible=!0;this.edgeLines.length<this.layouts.length;){let e=this.createEdgeLine();if(!e)return;this.edgeLines.push(e),this.edgeGroup.add(e)}this.edgeLines.forEach((e,t)=>{e.visible=t<this.layouts.length,e.renderOrder=this.getEdgeRenderOrder()})}setEdgeLineOpacity(e,n){let r=e.material;r.opacity=this.settings.outlineOpacity*t.MathUtils.clamp(n,0,1),r.transparent=!0,r.needsUpdate=!0}getEdgeRenderOrder(){return this.settings.edgeCompositing===`surface`?2:10}getEdgeScaleLift(){return 1}ensureCameraType(){this.settings.viewMode===`perspective`!=this.camera instanceof t.PerspectiveCamera&&(this.camera=this.createCamera())}updateCamera(){this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.settings.viewMode===`orthographic`&&this.settings.orthographicView!==`custom`?this.updateOrthographicViewCamera():this.updateCameraOrbit(),this.updateCameraProjection(),this.camera.position.set(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ);let e=ve({distance:this.settings.cameraDistance,azimuth:this.settings.cameraOrbitAngle,elevation:this.settings.cameraElevation,target:{x:this.settings.cameraTargetX,y:this.settings.cameraTargetY,z:this.settings.cameraTargetZ}});this.camera.up.set(e.x,e.y,e.z),this.camera.lookAt(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),this.camera.updateProjectionMatrix()}applyCameraSettings(){this.updateCamera(),this.notifyCameraChange(),this.renderIdleFrame()}setStarfieldFlightFromCamera(e=!0){if(this.settings.distributionMode!==`starfield`)return;let t=this.alignVecScratch.set(this.settings.cameraPositionX-this.settings.cameraTargetX,this.settings.cameraPositionY-this.settings.cameraTargetY,this.settings.cameraPositionZ-this.settings.cameraTargetZ);if(t.lengthSq()<1e-8)return;t.normalize();let n=this.alignUpScratch.setFromMatrixColumn(this.camera.matrixWorld,1).normalize(),r=this.alignRightScratch.copy(n).cross(t);if(r.lengthSq()<1e-8)return;r.normalize();let i=n.copy(t).cross(r).normalize();this.alignMatrixScratch.makeBasis(r,i,t),this.orientationEulerScratch.setFromRotationMatrix(this.alignMatrixScratch),this.settings.pathOrientationX=this.orientationEulerScratch.x,this.settings.pathOrientationY=this.orientationEulerScratch.y,this.settings.pathOrientationZ=this.orientationEulerScratch.z,e&&this.updatePattern()}updateOrthographicViewCamera(){let e=Math.max(1,this.settings.cameraDistance||42),t=this.settings.cameraTargetX,n=this.settings.cameraTargetY,r=this.settings.cameraTargetZ;switch(this.settings.orthographicView){case`front`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r+e;break;case`back`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r-e;break;case`left`:this.settings.cameraPositionX=t-e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`right`:this.settings.cameraPositionX=t+e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`top`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n+e,this.settings.cameraPositionZ=r;break;default:this.updateCameraOrbit();break}}getOrthographicFrustumSize(){return Lf*(If/I(this.settings.orthoScale,$.orthoScale,P.camera.orthographicFrustumScale))}createCamera(){let{width:e,height:n}=this.getContainerSize(),r=e/n;return this.settings.viewMode===`perspective`?new t.PerspectiveCamera(this.getPerspectiveFovFromFocalLength(),r,P.camera.perspectiveClip.near,P.camera.perspectiveClip.far):new t.OrthographicCamera(this.frustumSize*r/-2,this.frustumSize*r/2,this.frustumSize/2,this.frustumSize/-2,P.camera.orthographicClip.near,P.camera.orthographicClip.far)}createViewportGrid(){let e=new t.GridHelper(80,80,`#6c6c6c`,`#6c6c6c`);return e.visible=!1,e.renderOrder=-1,(Array.isArray(e.material)?e.material:[e.material]).forEach(e=>{e.transparent=!0,e.opacity=.32,e.depthWrite=!1}),e}updateCameraProjection(){let{width:e,height:n}=this.getContainerSize(),r=e/n;if(this.camera instanceof t.PerspectiveCamera){this.camera.fov=this.getPerspectiveFovFromFocalLength(),this.camera.aspect=r,this.camera.near=P.camera.perspectiveClip.near,this.camera.far=this.getPerspectiveFarClip(),this.camera.updateProjectionMatrix();return}this.camera.left=this.frustumSize*r/-2,this.camera.right=this.frustumSize*r/2,this.camera.top=this.frustumSize/2,this.camera.bottom=this.frustumSize/-2,this.camera.updateProjectionMatrix()}getPerspectiveFarClip(){let e=P.camera.perspectiveClip.far;if(!this.mesh)return e;let n=this.getSubjectBounds(),r=new t.Sphere;n.getBoundingSphere(r);let i=new t.Vector3(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ).distanceTo(r.center)+r.radius;return Math.max(e,i*1.25)}getContainerSize(){return this.exportSizeOverride?this.exportSizeOverride:this.getLiveContainerSize()}getLiveContainerSize(){let e=this.container.getBoundingClientRect();return{width:Math.max(1,e.width||window.innerWidth),height:Math.max(1,e.height||window.innerHeight)}}getSubjectBounds(){let e=new t.Box3,n=new t.Matrix4,r=new t.Matrix4,i=new t.Box3,a=t=>{t.geometry.computeBoundingBox();let a=t.geometry.boundingBox;if(a){t.updateMatrixWorld();for(let o=0;o<t.count;o+=1)t.getMatrixAt(o,n),r.multiplyMatrices(t.matrixWorld,n),i.copy(a).applyMatrix4(r),e.union(i)}};return a(this.mesh),this.imageSetMeshes.forEach(a),e.isEmpty()&&e.setFromCenterAndSize(new t.Vector3(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),new t.Vector3(1,1,1)),e}getPerspectiveFovFromFocalLength(){return ee(this.settings.cameraFocalLength)}updateColors(){this.settings.backgroundMode===`image`&&this.invalidateBackgroundImageDisplayTexture(),this.updateSceneBackground(),this.updateMaterial(),this.renderIdleFrame()}updateMaterial(){let e=this.mesh.material;this.disposeMeshMaterial(e);let t=this.outlineMesh.material;this.disposeMeshMaterial(t),this.mesh.material=this.createMaterial(),this.syncImageSetMeshes(),this.outlineMesh.material=this.createOutlineMaterial(),this.edgeMaterial?.dispose(),this.edgeMaterial=this.createEdgeMaterial(),this.outlineMesh.visible=this.shouldShowSilhouetteOutline(),this.edgeGroup.visible=this.shouldShowEdgeOutline(),this.edgeGroup.renderOrder=this.getEdgeRenderOrder(),this.shouldShowEdgeOutline()?(this.edgeGeometry||=this.createEdgeGeometry(this.mesh.geometry),this.edgeLines.forEach(e=>{this.disposeMeshMaterial(e.material),e.material=this.edgeMaterial.clone()}),this.syncEdgeLineCount()):this.rebuildEdgeLines(),this.updateLights(),this.renderIdleFrame()}getMaxInstanceCount(){let{gridSize:e,gridLayers:t,ringCount:n,ringDensity:r,pathInstanceCount:i,pathRows:a}=Se(this.settings),o=Math.ceil(1+r*(n*(n+1))/2),s=i*Math.max(1,Math.round(a)),c=e*e*Math.max(1,Math.round(t));return Math.max(1,e*e,c,o,s)}ensureMeshCapacity(e){if(e<=this.mesh.instanceMatrix.count)return;let n=this.mesh.geometry,r=this.mesh.material,i=Math.ceil(e*1.25),a=new t.InstancedMesh(n,r,i);a.renderOrder=1,a.frustumCulled=!1;let o=new t.InstancedMesh(this.outlineMesh.geometry,this.outlineMesh.material,i);o.renderOrder=0,o.frustumCulled=!1,o.visible=this.outlineMesh.visible,this.scene.remove(this.mesh),this.scene.remove(this.outlineMesh),this.mesh=a,this.outlineMesh=o,this.scene.add(this.mesh),this.scene.add(this.outlineMesh),this.syncImageSetMeshes()}createLayouts(){return De(this.settings)}getSpinStaggerFactor(e,t){let n=this.settings.instanceSpinStagger;if(n===0)return 1;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);if(this.settings.instanceSpinStaggerMode===`alternating`){let t=e.gridX%2==0?1:-1;return Math.max(-4,1+t*n*r)}return Math.max(-4,1+n*r)}getSpinPhaseOffset(e,t){let n=this.settings.instanceSpinPhaseStagger;if(n===0)return 0;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);return this.settings.instanceSpinStaggerMode===`alternating`?(e.gridX%2==0?1:-1)*n*r:n*r}getLayoutProgress(e,t){return t===0?0:e.distance/t}renderExportFrameAt(e,t){if(!this.hasTimeVaryingMotion()){this.renderScene(t);return}this.renderAnimatedFrame(e,this.getPathTravelTime(e),this.getRingOrbitTime(e),t)}animate=()=>{let e=(performance.now()-this.startTime)/1e3;if(!this.hasTimeVaryingMotion()){this.animationFrameId=null,this.updatePattern();return}let t=Math.max(0,Math.min(.1,e-this.previousAnimationElapsed));this.previousAnimationElapsed=e,this.pathTravelProgress+=this.getPathTravelDelta(t),this.ringOrbitProgress+=this.getRingOrbitDelta(t),this.renderAnimatedFrame(e,this.pathTravelProgress,this.ringOrbitProgress),this.animationFrameId=requestAnimationFrame(this.animate)};getPathTravelTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}getPathTravelDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}renderAnimatedFrame(e,t,n,r=this.renderer){let{instanceRotationX:i,instanceRotationY:a,instanceRotationZ:o,instanceSpinX:s,instanceSpinY:c,instanceSpinZ:l,instanceSpinStagger:u,instanceSpinPhaseStagger:d,pathRotationX:f,pathRotationY:p,pathRotationZ:m,waveAmplitude:h,waveFrequency:g,waveSpeed:_,easingMode:v,easingCustomBezier:y,staggerAmount:b,scaleMode:x,scaleAmount:S,animationMode:C,scaleY:w,baseY:T,groundAlign:E}=this.settings;this.setStructureRotation(e*f,e*p,e*m);let D={...this.settings,...Se(this.settings),ringOrbitFriction:this.settings.ringOrbitFriction},O=this.getEdgeScaleLift(),k=T+(E?w/2:0),A=u===0&&d===0?0:this.layouts.reduce((e,t)=>Math.max(e,t.distance),0);this.clearInstanceColorsForImageSurfaces(),this.ensureInstanceOpacityAttribute(this.mesh),this.ensureInstanceOpacityAttribute(this.outlineMesh),this.imageSetMeshes.forEach(e=>this.ensureInstanceOpacityAttribute(e));let j=this.createSurfaceWriteState(),M=this.getLayoutBounds(this.layouts),N=this.getBuildTransform(this.getBuildProgress(e));this.layouts.forEach((r,u)=>{let d=ft({layout:r,settings:D,pathTravelProgress:t,ringOrbitProgress:n}),f=(d.gridX+d.gridZ)%2==0?1:-1,p=d.distance;C===`linear-wave`&&(p=d.x+d.z),C===`checker-wave`&&(p=d.distance*f),C===`ring-wave`&&(p=d.ringIndex);let m=(d.distance+d.ringIndex)*b,w=e*_-m,T=Math.sin(p*g-w);T=ot(T,v,y),C===`cross-field`&&(T=ot(Math.sin(d.x*g-w)*Math.sin(d.z*g+w),v,y));let E=Math.abs(_)<=Df?0:T*h;this.dummy.position.set(d.x*N.sceneScale,(k+d.y+E)*N.sceneScale+N.offsetY,d.z*N.sceneScale);let P=this.getInstanceScale(d,x,S)*N.scale*N.sceneScale;this.dummy.scale.set(P,P,P);let F=this.getSpinStaggerFactor(d,A),I=this.getSpinPhaseOffset(d,A),ee=this.alignQuaternion(d,this.alignQuatScratch);this.manualQuatScratch.setFromEuler(this.orientationEulerScratch.set(i+N.rotationX,a+N.rotationY,o+N.rotationZ)),this.spinQuatScratch.setFromEuler(this.orientationEulerScratch.set(e*s*F+(Math.abs(s)>1e-4?I:0),e*c*F+(Math.abs(c)>1e-4?I:0),e*l*F+(Math.abs(l)>1e-4?I:0))),this.dummy.quaternion.copy(ee).multiply(this.manualQuatScratch).multiply(this.spinQuatScratch),this.dummy.updateMatrix();let te=this.getInstanceOpacity(u,d)*N.opacity,ne=this.setSurfaceMatrixAt(u,this.dummy.matrix,j);this.setInstanceOpacityAt(ne.mesh,ne.index,te),this.setInstanceColorAt(ne.mesh,ne.index,this.getInstanceColor(d,M)),this.dummy.scale.setScalar(P*O),this.dummy.updateMatrix();let re=this.edgeLines[u];re&&(re.matrix.copy(this.dummy.matrix),re.matrixWorldNeedsUpdate=!0,this.setEdgeLineOpacity(re,te)),this.dummy.scale.setScalar(P*(1+this.settings.outlineThickness)),this.dummy.updateMatrix(),this.outlineMesh.setMatrixAt(u,this.dummy.matrix),this.setInstanceOpacityAt(this.outlineMesh,u,te)}),this.finishSurfaceWrites(j),this.outlineMesh.instanceMatrix.needsUpdate=!0,this.renderScene(r)}getInstanceScale(e,t,n){if(t===`constant`||n===0)return 1;let r=this.layouts.reduce((e,t)=>Math.max(e,t.distance),0),i=r===0?0:e.distance/r,a=e=>{let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)},o=(e,t=n)=>{let r=a(e);return I(t>=0?1+r*t:1/(1+r*Math.abs(t)),1,P.instance.scaleVariationMultiplier)};if(t===`center-out`)return o(i);if(t===`edge-out`)return o(1-i);if(t===`alternating`)return o(1,((e.gridX+e.gridZ)%2==0?1:-1)*n);let s=Math.max(0,Math.min(1,e.pathProgress)),c=1-Math.abs(s-.5)*2,l=Math.abs(s-.5)*2;if(t===`path-linear`)return o(s);if(t===`path-linear-reverse`)return o(1-s);if(t===`path-center`)return o(c);if(t===`path-edges`)return o(l);if(t===`path-quad`)return o(s*s);if(t===`path-quad-reverse`){let e=1-s;return o(e*e)}return 1}addLights(){this.ambientLight=new t.AmbientLight(`#ffffff`,this.settings.ambientIntensity),this.scene.add(this.ambientLight),this.directionalLight=new t.DirectionalLight(`#ffffff`,this.settings.lightIntensity),this.setDirectionalLightPosition(),this.scene.add(this.directionalLight)}updateLights(){this.ambientLight&&(this.ambientLight.intensity=this.settings.ambientIntensity),this.directionalLight&&(this.directionalLight.intensity=this.settings.lightIntensity,this.setDirectionalLightPosition()),this.renderIdleFrame()}setDirectionalLightPosition(){if(!this.directionalLight)return;let e=Math.cos(this.settings.lightElevation)*18;this.directionalLight.position.set(Math.cos(this.settings.lightAzimuth)*e,Math.sin(this.settings.lightElevation)*18,Math.sin(this.settings.lightAzimuth)*e),this.directionalLight.lookAt(0,0,0)}applyRendererPixelRatio(){this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,this.settings.renderPixelRatio))}observeContainerSize(){if(typeof ResizeObserver>`u`)return;let{width:e,height:t}=this.getLiveContainerSize();this.observedWidth=e,this.observedHeight=t,this.containerResizeObserver=new ResizeObserver(()=>{if(this.disposed)return;let e=this.getLiveContainerSize();e.width===this.observedWidth&&e.height===this.observedHeight||(this.observedWidth=e.width,this.observedHeight=e.height,this.handleResize())}),this.containerResizeObserver.observe(this.container)}handleResize=()=>{this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.updateCameraProjection();let{width:e,height:t}=this.getContainerSize();this.applyRendererPixelRatio(),this.renderer.setSize(e,t),this.invalidateBackgroundImageDisplayTexture(),this.invalidateTransparentBackgroundPreviewTexture(),this.updateSceneBackground(),this.updateEdgeResolution(e,t),this.renderIdleFrame()}},dp=8,fp=`300px`,pp=new Set,mp=new WeakMap,hp=new WeakSet,gp=new Map,_p=null,vp=dp,yp=0,bp=!1,xp=!1,Sp=()=>typeof IntersectionObserver<`u`,Cp=()=>typeof document>`u`||document.visibilityState!==`hidden`,wp=()=>{let e=0;for(let t of pp)t.isMounted()&&(e+=1);return e},Tp=e=>{let t=null;for(let n of pp)n===e||!n.isMounted()||!n.evictable||n.visible||(!t||n.lastUsed<t.lastUsed)&&(t=n);return t},Ep=()=>{bp||(bp=!0,console.warn(`Sinth: more than ${vp} embeds are on screen at once, so the WebGL context budget cannot be honoured. The browser may drop the oldest context. Show fewer patterns at a time, or raise \`maxLiveContexts\` if the page can afford it.`))},Dp=e=>{for(;wp()>=vp;){let t=Tp(e);if(!t){Ep();return}t.unmount()}},Op=e=>{yp+=1,e.lastUsed=yp,!e.isMounted()&&(Dp(e),e.mount())},kp=(e,t)=>{if(e.visible=t,!t){e.suspend();return}Op(e),Cp()&&e.resume()},Ap=()=>{let e=Cp();for(let t of pp)t.isMounted()&&(e?t.visible&&t.resume():t.suspend())},jp=()=>{xp||typeof document>`u`||(xp=!0,document.addEventListener(`visibilitychange`,Ap))},Mp=e=>{let t=gp.get(e);return t||(t=new IntersectionObserver(e=>{for(let t of e){let e=mp.get(t.target);if(e)for(let n of e)kp(n,t.isIntersecting)}},{rootMargin:e}),gp.set(e,t)),t},Np=e=>{if(hp.has(e))return;hp.add(e);let t=e.id?`id="${e.id}"`:e.className?`class="${e.className}"`:`the same element`;console.warn(`Sinth: more than one embed is pointed at ${t}, so they render on top of one another and only the topmost is visible. Each embed needs its own container. This is usually older embed code that looks the container up by name — re-copy the block from the editor (Embed → Copy embed code) and paste it again. The current code finds the container next to its own <script> tag, so it is safe to paste any number of times.`)};function Pp(e,t){if(typeof t.maxLiveContexts==`number`&&Number.isFinite(t.maxLiveContexts)){let e=Math.max(1,Math.floor(t.maxLiveContexts));_p=_p===null?e:Math.min(_p,e),vp=_p}let n=Sp(),r=t.lazy&&n,i={...e,evictable:r,visible:!r,lastUsed:0,rootMargin:t.rootMargin};if(pp.add(i),jp(),n){let t=mp.get(e.container);t?t.size>0&&Np(e.container):(t=new Set,mp.set(e.container,t)),t.add(i),Mp(i.rootMargin).observe(e.container)}return r||(Op(i),Cp()&&i.resume()),{claim:()=>{Op(i)},release:()=>{if(pp.delete(i),!n)return;let t=mp.get(e.container);t?.delete(i),(!t||t.size===0)&&(Mp(i.rootMargin).unobserve(e.container),mp.delete(e.container))}}}var Fp=`sinth`,Ip=`.${Fp}`,Lp=new WeakSet,Rp=e=>{Lp.add(e)},zp=e=>Lp.has(e),Bp=e=>e instanceof HTMLElement&&e.matches(Ip)&&!Lp.has(e),Vp=e=>{if(!e)return null;for(let t of e.querySelectorAll(Ip))if(Bp(t))return t;return null};function Hp(e){if(Bp(e??null))return e;if(e){for(let t=e.previousElementSibling;t;t=t.previousElementSibling)if(Bp(t))return t;let t=Vp(e.parentElement);if(t)return t}let t=Vp(typeof document>`u`?null:document);if(t)return t;throw Error(`Sinth: no free container found for this embed. Every block needs its own element with class "${Fp}" — the copied embed code brings one with it, so this usually means the <div> was deleted, or its class was renamed, or another embed has already taken it.`)}var Up=1e3,Wp=async e=>{e.rebuildGeometry(),e.updateMaterial(),e.updateColors(),e.updateLights(),e.updateCamera(),e.updatePattern()};function Gp({container:e,preset:t,autoStart:n=!0,lazy:r=!0,rootMargin:i=fp,maxLiveContexts:a}){let o=null,s=t,c=n,l=!1,u=!1,d=!1,f=null,p=!1,m=null,h=()=>{let t=e.getBoundingClientRect();return t.width>0&&t.height>0};Rp(e);let g=()=>{let t=new up(e,{config:s,autoStart:c&&!u});o=t,s&&Wp(t).catch(e=>{console.error(`Unable to initialise the Sinth embed.`,e)})},_=()=>{p||m!==null||typeof window>`u`||(m=window.setTimeout(()=>{if(m=null,l||p||h()||!(e.offsetParent!==null||window.getComputedStyle(e).position===`fixed`))return;p=!0;let t=e.getBoundingClientRect().height===0?`height`:`width`;console.warn(`Sinth: this container has no ${t}, so there is nothing to render into and the embed is waiting. Sinth fills the box it is given — if the container is sized \`${t}: 100%\`, give its parent a ${t} (or set a ${t} on the container itself). It will start on its own the moment the container has one.`,e)},Up))},v=()=>{if(d=!0,_(),!f){if(typeof ResizeObserver>`u`){d=!1,g();return}f=new ResizeObserver(()=>{if(!(l||!d)){if(!h()){_();return}d=!1,g()}}),f.observe(e)}},y=()=>{if(!(o||l)){if(!h()){v();return}g()}},b=()=>{d=!1,o&&=(o.dispose(),null)},x=Pp({container:e,mount:y,unmount:b,resume:()=>{u=!1,c&&o?.start()},suspend:()=>{u=!0,o?.stop()},isMounted:()=>o!==null},{lazy:r,rootMargin:i,maxLiveContexts:a});return{get engine(){return o},updatePreset:e=>{s=e,o&&(o.setConfig(e),Wp(o).catch(e=>{console.error(`Unable to update the Sinth embed preset.`,e)}))},start:()=>{c=!0,x.claim(),o?.start()},stop:()=>{c=!1,o?.stop()},destroy:()=>{l=!0,m!==null&&(clearTimeout(m),m=null),f?.disconnect(),f=null,x.release(),b()}}}var Kp=`.${Fp}, [data-sinth-preset]`,qp=`:scope > script[type="application/json"]`,Jp=new WeakSet,Yp=!1,Xp=(e,t)=>{try{return JSON.parse(e)}catch(e){return console.error(`Sinth: this embed’s preset is not valid JSON, so it was skipped.`,t,e),null}},Zp=e=>{if(e===null||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0},Qp=e=>{let t={};e.dataset.sinthLazy===`false`&&(t.lazy=!1),e.dataset.sinthAutostart===`false`&&(t.autoStart=!1),e.dataset.sinthRootMargin&&(t.rootMargin=e.dataset.sinthRootMargin);let n=Zp(e.dataset.sinthMaxContexts??null);return n!==void 0&&(t.maxLiveContexts=n),t},$p=(e,t)=>{if(zp(e))return null;try{return Gp({container:e,preset:t,...Qp(e)})}catch(t){return console.error(`Sinth: this embed could not be created.`,e,t),null}},em=e=>{if(zp(e)||Jp.has(e))return null;let t=e.querySelector(qp);if(t){let n=Xp(t.textContent??``,e);return n?$p(e,n):null}let n=e.dataset.sinthPreset?.trim();if(!n)return null;if(n.startsWith(`{`)){let t=Xp(n,e);return t?$p(e,t):null}return Jp.add(e),fetch(n,{credentials:`omit`}).then(e=>{if(!e.ok)throw Error(`${e.status} ${e.statusText}`);return e.json()}).then(t=>{Jp.delete(e),$p(e,t)}).catch(t=>{Jp.delete(e),console.error(`Sinth: could not load the preset at "${n}".`,e,t)}),null};function tm(e=document){let t=[];for(let n of e.querySelectorAll(Kp)){let e=em(n);e&&t.push(e)}return t}var nm=e=>e instanceof Element?e.matches(Kp)||e.querySelector(Kp)!==null:!1;function rm(){if(Yp||typeof document>`u`||window.SINTH_AUTO_MOUNT===!1)return;Yp=!0;let e=()=>{if(tm(document),typeof MutationObserver>`u`)return;let e=!1;new MutationObserver(t=>{if(!e){for(let n of t)for(let t of n.addedNodes)if(nm(t)){e=!0,requestAnimationFrame(()=>{e=!1,tm(document)});return}}}).observe(document.documentElement,{childList:!0,subtree:!0})};if(document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,e,{once:!0});return}e()}var im=`1.0.0`,am=`v48`,om=`${im} · v48`;return Rt(),rm(),e.SINTH_CONTAINER_CLASS=Fp,e.SNAPSHOT=am,e.VERSION=im,e.VERSION_LABEL=om,e.createSinthEmbed=Gp,e.fontBaseUrl=Tt,e.mountAll=tm,e.normalizeSinthConfig=lp,e.resolveContainer=Hp,e.setFontBaseUrl=wt,e.startAutoMount=rm,e})({},THREE);window.Sinth=e}})();
677
+ #include <alphatest_fragment>`)},e.customProgramCacheKey=()=>[`spe-instance-opacity`,n.alphaHash?`alpha-hash`:`transparent`,n.objectGradient?`object-gradient`:`solid`,n.materialTexture?`material-texture`:`no-material-texture`].join(`:`),e}rebuildGeometry(){let e=this.createGeometry();this.mesh.geometry.dispose(),this.outlineMesh.geometry.dispose(),this.edgeGeometry?.dispose(),this.mesh.geometry=e,this.outlineMesh.geometry=e.clone(),this.edgeGeometry=this.createEdgeGeometry(e),this.syncImageSetMeshes(),this.rebuildEdgeLines(),this.updatePattern()}setInstanceShape(e){this.settings.instanceShape=e,this.settings.colorMode===`texture`&&!this.isTextureMaterialShape()&&(this.settings.colorMode=`solid`),this.applyInstanceShapeDefaults(e),this.updateMaterial(),this.rebuildGeometry()}applyInstanceShapeDefaults(e){if(this.scaleBeforeShapeDefault&&(this.shapeAutoModified.x&&(this.settings.scaleX=this.scaleBeforeShapeDefault.x),this.shapeAutoModified.y&&(this.settings.scaleY=this.scaleBeforeShapeDefault.y),this.shapeAutoModified.z&&(this.settings.scaleZ=this.scaleBeforeShapeDefault.z)),this.scaleBeforeShapeDefault={x:this.settings.scaleX,y:this.settings.scaleY,z:this.settings.scaleZ},this.shapeAutoModified={x:!1,y:!1,z:!1},e===`pill`){let e=Math.max(this.settings.scaleX,this.settings.scaleZ),t=Math.max(this.settings.scaleY,e*2.8);t!==this.settings.scaleY&&(this.settings.scaleY=t,this.shapeAutoModified.y=!0)}}setInstanceDimension(e,t){this.shapeAutoModified[e]=!1;let n=I(t,$.scaleX,P.instance.dimension);e===`x`?(this.settings.scaleX=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleZ=I(n/this.settings.imageAspectRatio,$.scaleZ,P.instance.dimension))):e===`y`?this.settings.scaleY=n:(this.settings.scaleZ=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(n*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension))),this.syncRoundedCardRatio(),this.rebuildGeometry()}setImagePreserveAspectRatio(e){this.settings.imagePreserveAspectRatio=e,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(this.settings.scaleZ*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension)),this.rebuildGeometry()}shouldLockImageAspectRatio(){return this.settings.instanceShape===`image`&&this.settings.imagePreserveAspectRatio&&this.settings.imageAspectRatio>0}async ensureTextRuntimeLoaded(){if(!(this.textGeometryRuntime&&this.textFonts)){if(this.textRuntimeLoadPromise){await this.textRuntimeLoadPromise;return}this.textRuntimeLoadPromise=Promise.resolve().then(()=>(Au(),xu)).then(async e=>{this.textGeometryRuntime=e,this.textFonts??=new e.TextFontManager,this.settings.textFontSource.source===`url`&&await this.textFonts.loadCustomFont(this.settings.textFontSource.url)}).finally(()=>{this.textRuntimeLoadPromise=null}),await this.textRuntimeLoadPromise}}scheduleTextRuntimeLoad(){this.ensureTextRuntimeLoaded().then(()=>{this.settings.instanceShape===`text`&&this.rebuildGeometry()}).catch(e=>{console.warn(`Unable to load text runtime support.`,e)})}async loadCustomTextFont(e=this.settings.textCustomFontUrl){let t=e.trim();if(!t){this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.settings.textCustomFontUrl=``,this.rebuildGeometry();return}await this.ensureTextRuntimeLoaded(),await this.textFonts?.loadCustomFont(t),this.settings.textCustomFontUrl=t,this.settings.textFont=`custom`,this.settings.textFontSource={source:`url`,url:t},this.rebuildGeometry()}async ensureWebTextFont(e){await this.ensureTextRuntimeLoaded(),!this.textFonts?.hasFont(e)&&(await this.textFonts?.loadWebFont(e),this.settings.textFont===e&&this.settings.instanceShape===`text`&&this.rebuildGeometry())}setTextFont(e){if(this.settings.textFont=e,e===`custom`){this.settings.textCustomFontUrl.trim()?this.loadCustomTextFont().catch(e=>{console.warn(`Unable to load custom text font.`,e)}):(this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.rebuildGeometry());return}this.settings.textFontSource={source:`library`,id:e},this.settings.textCustomFontUrl=``,Dt(e)&&this.ensureWebTextFont(e).catch(e=>{console.warn(`Unable to load text font.`,e)}),this.rebuildGeometry()}syncRoundedCardRatio(){this.settings.instanceShape===`rounded-card`&&(this.settings.roundedCardRatio=this.settings.scaleX/Math.max(.01,this.settings.scaleZ))}async loadCustomObj(e=this.settings.assetUrl,t={}){await this.loadCustomAsset(e,t)}async loadCustomAsset(e=this.settings.assetUrl,{showPlaceholder:t=!1,source:n=`background`}={}){let r=e.trim();if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let i=++this.customAssetLoadId;if(n===`user`&&(this.activeUserCustomAssetLoadId=i),this.settings.assetUrl=r,!r){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry();return}t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry());try{let e=await Promise.resolve().then(()=>(cf(),qd)),t=await e.loadCustomAssetGeometry(sp(r));this.completeCustomAssetLoad(i,t,e.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadCustomFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearCustomAssetLoad(i);return}let t=await Promise.resolve().then(()=>(cf(),qd)),n=await t.loadCustomAssetGeometryFromFile(e);this.completeCustomAssetLoad(i,n,t.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearSvgAssetLoad(r);return}let e=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometry(sp(n),this.settings.svgSolidify);this.completeSvgAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearSvgAssetLoad(i);return}let t=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometryFromFile(e,this.settings.svgSolidify);this.completeSvgAssetLoad(i,t)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearImageAssetLoad(r);return}let e=await this.textureLoader.loadAsync(sp(n));this.completeImageAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageFile(e,t,n={}){await this.loadImageAsset(t,n)}async loadImageSet(e=this.settings.imageSetUrls,t={}){let n=op(e),r=this.beginCustomAssetLoad(n[0]??``,t);try{if(n.length===0){this.clearImageAssetLoad(r);return}let e=await Promise.all(n.map(e=>this.textureLoader.loadAsync(sp(e))));this.completeImageSetAssetLoad(r,n,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadBackgroundImage(e=this.settings.backgroundImageUrl){let t=e.trim();if(this.settings.backgroundImageUrl=t,!t){this.clearBackgroundImage();return}let n=await this.textureLoader.loadAsync(sp(t));this.backgroundTexture?.dispose(),this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.backgroundTexture=n,this.configureImageTexture(n),this.settings.backgroundMode=`image`,this.updateSceneBackground(),this.renderIdleFrame()}async loadBackgroundImageFile(e,t){await this.loadBackgroundImage(t)}async loadMaterialTexture(e=this.settings.materialTextureUrl){let n=e.trim();if(this.settings.materialTextureUrl=n,!n){this.clearMaterialTexture();return}let r=await this.textureLoader.loadAsync(sp(n));this.materialTexture?.dispose(),this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.materialTexture=r,this.configureImageTexture(r),r.wrapS=t.RepeatWrapping,r.wrapT=t.RepeatWrapping,this.settings.colorMode=`texture`,this.updateMaterial(),this.renderIdleFrame()}async loadMaterialTextureFile(e,t){await this.loadMaterialTexture(t)}clearMaterialTexture(){this.settings.materialTextureUrl=``,this.materialTexture?.dispose(),this.materialTexture=null,this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.updateMaterial(),this.renderIdleFrame()}clearBackgroundImage(){this.settings.backgroundImageUrl=``,this.backgroundTexture?.dispose(),this.backgroundTexture=null,this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.updateSceneBackground(),this.renderIdleFrame()}clearCustomAsset(){this.customAssetLoadId+=1,this.activeUserCustomAssetLoadId=0,this.settings.assetUrl=``,this.settings.imageSetUrls=[],this.settings.imageAspectRatio=$.imageAspectRatio,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.updateMaterial(),this.rebuildGeometry()}clearSvgAssetLoad(e){this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}beginCustomAssetLoad(e,{showPlaceholder:t=!1,source:n=`background`}){if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let r=++this.customAssetLoadId;return n===`user`&&(this.activeUserCustomAssetLoadId=r),this.settings.assetUrl=e,t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry()),r}clearCustomAssetLoad(e){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}clearImageAssetLoad(e){this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.settings.imageAspectRatio=$.imageAspectRatio,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeCustomAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw t.dispose(),new wf;this.customAssetLoadId=e,n(t,{assetScale:this.settings.assetScale,assetNormalize:this.settings.assetNormalize}),this.customObjGeometry=t,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`custom-obj`,r&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}completeSvgAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.customSvgGeometry?.dispose(),this.customSvgGeometry=t,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`svg`,n&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.configureImageTexture(t),this.imageTexture=t,this.imageSetTextures=[t],this.settings.imageSetUrls=[];let r=t.image,i=r?.width??$.imageAspectRatio,a=r?.height??1;this.settings.imageAspectRatio=a>0?Math.max(.01,i/a):$.imageAspectRatio,this.settings.instanceShape=`image`,n&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageSetAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw n.forEach(e=>e.dispose()),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,n.forEach(e=>this.configureImageTexture(e)),this.imageSetTextures=n,this.imageTexture=n[0]??null,this.settings.assetUrl=t[0]??``,this.settings.imageSetUrls=t;let i=this.imageTexture?.image,a=i?.width??$.imageAspectRatio,o=i?.height??1;this.settings.imageAspectRatio=o>0?Math.max(.01,a/o):$.imageAspectRatio,this.settings.instanceShape=`image`,r&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}configureImageTexture(e){e.colorSpace=t.SRGBColorSpace,e.needsUpdate=!0}updateSceneBackground(){if(this.settings.backgroundMode===`transparent`){this.scene.background=null;return}if(this.settings.backgroundMode===`image`){this.scene.background=this.updateBackgroundImageDisplayTexture();return}if(this.settings.backgroundMode===`gradient`){this.scene.background=this.updateBackgroundGradientTexture();return}this.scene.background=new t.Color(this.settings.backgroundColor)}invalidateBackgroundImageDisplayTexture(){this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null}invalidateTransparentBackgroundPreviewTexture(){this.transparentBackgroundPreviewTexture?.dispose(),this.transparentBackgroundPreviewTexture=null}updateTransparentBackgroundPreviewTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.max(1,Math.round(e)),i=Math.max(1,Math.round(n)),a=this.transparentBackgroundPreviewTexture,o=a?.image instanceof HTMLCanvasElement?a.image:document.createElement(`canvas`);if(a&&o.width===r&&o.height===i)return a;o.width=r,o.height=i;let s=o.getContext(`2d`);return s&&this.drawCheckerBackground(s,r,i),this.transparentBackgroundPreviewTexture||(this.transparentBackgroundPreviewTexture=new t.CanvasTexture(o),this.transparentBackgroundPreviewTexture.colorSpace=t.SRGBColorSpace,this.transparentBackgroundPreviewTexture.wrapS=t.ClampToEdgeWrapping,this.transparentBackgroundPreviewTexture.wrapT=t.ClampToEdgeWrapping),this.transparentBackgroundPreviewTexture.needsUpdate=!0,this.transparentBackgroundPreviewTexture}updateBackgroundImageDisplayTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.min(1,1600/Math.max(e,n)),i=Math.max(1,Math.round(e*r)),a=Math.max(1,Math.round(n*r)),o=i/a,s=this.backgroundImageDisplayTexture?.image instanceof HTMLCanvasElement?this.backgroundImageDisplayTexture.image:document.createElement(`canvas`);s.width=i,s.height=a;let c=s.getContext(`2d`);if(!c)return this.backgroundTexture??this.getCheckerTexture();if(!this.backgroundTexture)this.drawCheckerBackground(c,i,a);else{let e=this.backgroundTexture.image,t=this.getTextureImageAspect(this.backgroundTexture);if(!t)return this.backgroundTexture;c.fillStyle=this.settings.backgroundColor,c.fillRect(0,0,i,a);let n=this.settings.backgroundImageFit===`fit`?t>o?i/this.getTextureImageWidth(this.backgroundTexture):a/this.getTextureImageHeight(this.backgroundTexture):t>o?a/this.getTextureImageHeight(this.backgroundTexture):i/this.getTextureImageWidth(this.backgroundTexture),r=this.getTextureImageWidth(this.backgroundTexture)*n,s=this.getTextureImageHeight(this.backgroundTexture)*n;c.drawImage(e,(i-r)*.5,(a-s)*.5,r,s)}return this.backgroundImageDisplayTexture||(this.backgroundImageDisplayTexture=new t.CanvasTexture(s),this.backgroundImageDisplayTexture.colorSpace=t.SRGBColorSpace,this.backgroundImageDisplayTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundImageDisplayTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundImageDisplayTexture.needsUpdate=!0,this.backgroundImageDisplayTexture}drawCheckerBackground(e,t,n){e.fillStyle=Mf,e.fillRect(0,0,t,n),e.fillStyle=Nf;for(let r=0;r<n;r+=Af)for(let n=r/Af%2==0?Af:0;n<t;n+=Af*2)e.fillRect(n,r,Af,Af)}updateBackgroundGradientTexture(){let e=this.backgroundGradientTexture?.image instanceof HTMLCanvasElement?this.backgroundGradientTexture.image:document.createElement(`canvas`);e.width=512,e.height=512;let n=e.getContext(`2d`);if(!n)return new t.Color(this.settings.backgroundColor);let r=n.createImageData(512,512),i=new t.Color(this.settings.backgroundGradientColorA),a=new t.Color(this.settings.backgroundGradientColorB),o=new t.Color,s=Qf(this.settings.backgroundGradientMidpoint),c=511*.5,l=Math.max(1e-4,Math.hypot(c,c));for(let e=0;e<512;e+=1)for(let t=0;t<512;t+=1){let n=this.getBackgroundGradientProgress(t,e,512,c,l),u=at(this.remapGradientProgressWithMidpoint(n,s),this.settings.backgroundGradientEasing,this.settings.backgroundGradientCustomBezier);o.copy(i).lerp(a,u);let d=(e*512+t)*4;r.data[d]=Math.round(o.r*255),r.data[d+1]=Math.round(o.g*255),r.data[d+2]=Math.round(o.b*255),r.data[d+3]=255}return n.putImageData(r,0,0),this.backgroundGradientTexture||(this.backgroundGradientTexture=new t.CanvasTexture(e),this.backgroundGradientTexture.colorSpace=t.SRGBColorSpace,this.backgroundGradientTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundGradientTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundGradientTexture.needsUpdate=!0,this.backgroundGradientTexture}getBackgroundGradientProgress(e,n,r,i,a){return this.settings.backgroundGradientDirection===`x`?r<=1?.5:e/(r-1):this.settings.backgroundGradientDirection===`radial`?t.MathUtils.clamp(Math.hypot(e-i,n-i)/a,0,1):r<=1?.5:1-n/(r-1)}getTextureImageAspect(e){let t=this.getTextureImageWidth(e),n=this.getTextureImageHeight(e);return t<=0||n<=0?null:t/n}getTextureImageWidth(e){let t=e.image;return t?.naturalWidth??t?.width??0}getTextureImageHeight(e){let t=e.image;return t?.naturalHeight??t?.height??0}disposeImageSetTextures(){this.imageSetTextures.forEach(e=>{e!==this.imageTexture&&e.dispose()}),this.imageSetTextures=[]}createGeometry(){return this.settings.instanceShape===`text`&&(!this.textGeometryRuntime||!this.textFonts)&&this.scheduleTextRuntimeLoad(),this.settings.instanceShape===`image`&&this.imageTexture?this.createImageGeometryForTexture(this.imageTexture):this.settings.instanceShape===`image`&&!this.imageTexture||this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createImagePlaceholderGeometry():Bt({settings:this.settings,customObjGeometry:this.customObjGeometry,customSvgGeometry:this.customSvgGeometry,textGeometry:this.textGeometryRuntime&&this.textFonts?{createTextGeometry:this.textGeometryRuntime.createTextGeometry,textFonts:this.textFonts}:null})}getInstanceDimensions(){return Ot(this.settings)}createMaterial(){let e,n=this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`,r=this.usesMaterialTextureSurface();if(e=this.settings.instanceShape===`image`?this.imageTexture?this.createImageMaterial(this.imageTexture):this.createCheckerImageMaterial():this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createCheckerImageMaterial():this.settings.shadingMode===`flat`||this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`?new t.MeshBasicMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):this.settings.shadingMode===`toon`?new t.MeshToonMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):new t.MeshStandardMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor,roughness:this.settings.roughness,metalness:this.settings.metalness}),n)e.side=t.DoubleSide,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;else{let n=this.settings.instanceShape===`image`,r=this.settings.instanceShape===`svg`&&!this.settings.svgSolidify,i=this.settings.instanceShape===`text`&&!this.settings.textSolidify,a=this.settings.instanceShape===`custom-obj`&&this.settings.assetDoubleSided;(n||r||i||a)&&(e.side=t.DoubleSide),e.polygonOffset=!0,e.polygonOffsetFactor=1,e.polygonOffsetUnits=1}return this.enableInstanceOpacity(e,{alphaHash:!0,objectGradient:this.usesObjectGradient(),materialTexture:r})}usesGradientSurfaceColor(){return this.settings.colorMode===`gradient`&&this.settings.instanceShape!==`image`}usesMaterialTextureSurface(){return this.settings.colorMode===`texture`&&this.isTextureMaterialShape()}isTextureMaterialShape(){return this.settings.instanceShape!==`image`&&this.settings.instanceShape!==`svg`}usesInstanceColors(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`pattern`}usesObjectGradient(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`object`}getMaterialTextureModeIndex(){return this.materialTexture?this.settings.materialTextureFit===`fit`?1:this.settings.materialTextureFit===`fill`?2:this.settings.materialTextureFit===`repeat`?3:0:3}getMaterialTextureScopeIndex(){return+(this.settings.materialTextureScope===`pattern`)}getMaterialTextureProjectionIndex(){return+(this.settings.materialTextureProjection===`triplanar`)}createImageMaterial(e){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:e,transparent:!0,alphaTest:.01,depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}createCheckerImageMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:this.getCheckerTexture(),depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}getMaterialTexture(){return this.materialTexture??this.getCheckerTexture()}getMaterialTextureRepeat(e){return this.materialTexture?Math.max(.001,e):jf}getCheckerTexture(){if(this.checkerTexture)return this.checkerTexture;let e=document.createElement(`canvas`);e.width=kf*2,e.height=kf*2;let n=e.getContext(`2d`);return n&&(n.fillStyle=Mf,n.fillRect(0,0,e.width,e.height),n.fillStyle=Nf,n.fillRect(kf,0,kf,kf),n.fillRect(0,kf,kf,kf)),this.checkerTexture=new t.CanvasTexture(e),this.checkerTexture.colorSpace=t.SRGBColorSpace,this.checkerTexture.wrapS=t.RepeatWrapping,this.checkerTexture.wrapT=t.RepeatWrapping,this.checkerTexture.magFilter=t.NearestFilter,this.checkerTexture.minFilter=t.NearestFilter,this.checkerTexture.repeat.set(jf,jf),this.checkerTexture.needsUpdate=!0,this.checkerTexture}getTextureAspectRatio(e){let t=e.image,n=t?.width??$.imageAspectRatio,r=t?.height??1;return r>0?Math.max(.01,n/r):$.imageAspectRatio}createImageGeometryForTexture(e){let{scaleX:n,scaleZ:r}=this.getInstanceDimensions(),i=this.settings.imagePreserveAspectRatio?r*this.getTextureAspectRatio(e):n,a=Math.min(.5,Math.max(0,this.settings.imageCornerRadius)),o=a>0?rp(i,r,Math.min(i,r)*a):new t.PlaneGeometry(i,r);return o.rotateX(-Math.PI/2),o}createImagePlaceholderGeometry(){let{scaleX:e,scaleZ:n}=this.getInstanceDimensions(),r=new t.PlaneGeometry(e,n);return r.rotateX(-Math.PI/2),r}createOutlineMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({color:this.settings.silhouetteColor,side:t.BackSide,opacity:1,depthTest:!0,depthWrite:!0}),{alphaHash:!0})}createEdgeGeometry(e){let n=new t.EdgesGeometry(e,1),r=n.getAttribute(`position`).array,i=new p;return i.setPositions(Array.from(r)),n.dispose(),i}createEdgeMaterial(){let e=new m({color:new t.Color(this.settings.edgeColor).getHex(),linewidth:this.settings.edgeThickness*1e3,transparent:!0,opacity:this.settings.outlineOpacity,depthTest:!this.settings.outlineSeeThrough,depthWrite:!1,polygonOffset:!1,polygonOffsetFactor:0,polygonOffsetUnits:0}),{width:n,height:r}=this.getContainerSize();return e.resolution.set(n,r),e}shouldShowSilhouetteOutline(){return this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`silhouette-edge-outline`}shouldShowEdgeOutline(){return this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`}createEdgeLine(){if(!this.edgeGeometry||!this.edgeMaterial)return null;let e=this.edgeMaterial.clone(),{width:t,height:n}=this.getContainerSize();e.resolution.set(t,n),e.depthTest=!this.settings.outlineSeeThrough,e.depthWrite=!1,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;let r=new N(this.edgeGeometry,e);return r.renderOrder=this.getEdgeRenderOrder(),r.matrixAutoUpdate=!1,r.frustumCulled=!1,r}syncImageSetMeshes(){let e=this.getImageTextures(),n=Math.max(0,e.length-1),r=this.mesh.instanceMatrix.count;for(;this.imageSetMeshes.length>n;){let e=this.imageSetMeshes.pop();e&&(this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material))}for(;this.imageSetMeshes.length<n;){let n=e[this.imageSetMeshes.length+1],i=new t.InstancedMesh(this.createImageGeometryForTexture(n),this.createImageMaterial(n),r);i.renderOrder=this.mesh.renderOrder,i.frustumCulled=!1,this.imageSetMeshes.push(i),this.scene.add(i)}this.imageSetMeshes.forEach((n,i)=>{let a=e[i+1];if(n.instanceMatrix.count!==r){let e=new t.InstancedMesh(this.createImageGeometryForTexture(a),this.createImageMaterial(a),r);e.renderOrder=n.renderOrder,e.frustumCulled=!1,e.count=n.count,this.scene.remove(n),n.geometry.dispose(),this.disposeMeshMaterial(n.material),this.imageSetMeshes[i]=e,this.scene.add(e);return}n.geometry.dispose(),n.geometry=this.createImageGeometryForTexture(a),this.disposeMeshMaterial(n.material),n.material=this.createImageMaterial(a),n.renderOrder=this.mesh.renderOrder}),this.syncImageSetMeshTransforms()}disposeImageSetMeshes(){this.imageSetMeshes.forEach(e=>{this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material)}),this.imageSetMeshes=[]}disposeMeshMaterial(e){if(Array.isArray(e)){e.forEach(e=>e.dispose());return}e.dispose()}rebuildEdgeLines(){this.edgeLines.forEach(e=>{this.edgeGroup.remove(e),this.disposeMeshMaterial(e.material)}),this.edgeLines=[],this.shouldShowEdgeOutline()&&this.syncEdgeLineCount()}syncEdgeLineCount(){if(!this.shouldShowEdgeOutline()){this.edgeGroup.visible=!1;return}for(this.edgeGroup.visible=!0;this.edgeLines.length<this.layouts.length;){let e=this.createEdgeLine();if(!e)return;this.edgeLines.push(e),this.edgeGroup.add(e)}this.edgeLines.forEach((e,t)=>{e.visible=t<this.layouts.length,e.renderOrder=this.getEdgeRenderOrder()})}setEdgeLineOpacity(e,n){let r=e.material;r.opacity=this.settings.outlineOpacity*t.MathUtils.clamp(n,0,1),r.transparent=!0,r.needsUpdate=!0}getEdgeRenderOrder(){return this.settings.edgeCompositing===`surface`?2:10}getEdgeScaleLift(){return 1}ensureCameraType(){this.settings.viewMode===`perspective`!=this.camera instanceof t.PerspectiveCamera&&(this.camera=this.createCamera())}updateCamera(){this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.settings.viewMode===`orthographic`&&this.settings.orthographicView!==`custom`?this.updateOrthographicViewCamera():this.updateCameraOrbit(),this.updateCameraProjection(),this.camera.position.set(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ);let e=ve({distance:this.settings.cameraDistance,azimuth:this.settings.cameraOrbitAngle,elevation:this.settings.cameraElevation,target:{x:this.settings.cameraTargetX,y:this.settings.cameraTargetY,z:this.settings.cameraTargetZ}});this.camera.up.set(e.x,e.y,e.z),this.camera.lookAt(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),this.camera.updateProjectionMatrix()}applyCameraSettings(){this.updateCamera(),this.notifyCameraChange(),this.renderIdleFrame()}setStarfieldFlightFromCamera(e=!0){if(this.settings.distributionMode!==`starfield`)return;let t=this.alignVecScratch.set(this.settings.cameraPositionX-this.settings.cameraTargetX,this.settings.cameraPositionY-this.settings.cameraTargetY,this.settings.cameraPositionZ-this.settings.cameraTargetZ);if(t.lengthSq()<1e-8)return;t.normalize();let n=this.alignUpScratch.setFromMatrixColumn(this.camera.matrixWorld,1).normalize(),r=this.alignRightScratch.copy(n).cross(t);if(r.lengthSq()<1e-8)return;r.normalize();let i=n.copy(t).cross(r).normalize();this.alignMatrixScratch.makeBasis(r,i,t),this.orientationEulerScratch.setFromRotationMatrix(this.alignMatrixScratch),this.settings.pathOrientationX=this.orientationEulerScratch.x,this.settings.pathOrientationY=this.orientationEulerScratch.y,this.settings.pathOrientationZ=this.orientationEulerScratch.z,e&&this.updatePattern()}updateOrthographicViewCamera(){let e=Math.max(1,this.settings.cameraDistance||42),t=this.settings.cameraTargetX,n=this.settings.cameraTargetY,r=this.settings.cameraTargetZ;switch(this.settings.orthographicView){case`front`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r+e;break;case`back`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r-e;break;case`left`:this.settings.cameraPositionX=t-e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`right`:this.settings.cameraPositionX=t+e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`top`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n+e,this.settings.cameraPositionZ=r;break;default:this.updateCameraOrbit();break}}getOrthographicFrustumSize(){return Lf*(If/I(this.settings.orthoScale,$.orthoScale,P.camera.orthographicFrustumScale))}createCamera(){let{width:e,height:n}=this.getContainerSize(),r=e/n;return this.settings.viewMode===`perspective`?new t.PerspectiveCamera(this.getPerspectiveFovFromFocalLength(),r,P.camera.perspectiveClip.near,P.camera.perspectiveClip.far):new t.OrthographicCamera(this.frustumSize*r/-2,this.frustumSize*r/2,this.frustumSize/2,this.frustumSize/-2,P.camera.orthographicClip.near,P.camera.orthographicClip.far)}createViewportGrid(){let e=new t.GridHelper(80,80,`#6c6c6c`,`#6c6c6c`);return e.visible=!1,e.renderOrder=-1,(Array.isArray(e.material)?e.material:[e.material]).forEach(e=>{e.transparent=!0,e.opacity=.32,e.depthWrite=!1}),e}updateCameraProjection(){let{width:e,height:n}=this.getContainerSize(),r=e/n;if(this.camera instanceof t.PerspectiveCamera){this.camera.fov=this.getPerspectiveFovFromFocalLength(),this.camera.aspect=r,this.camera.near=P.camera.perspectiveClip.near,this.camera.far=this.getPerspectiveFarClip(),this.camera.updateProjectionMatrix();return}this.camera.left=this.frustumSize*r/-2,this.camera.right=this.frustumSize*r/2,this.camera.top=this.frustumSize/2,this.camera.bottom=this.frustumSize/-2,this.camera.updateProjectionMatrix()}getPerspectiveFarClip(){let e=P.camera.perspectiveClip.far;if(!this.mesh)return e;let n=this.getSubjectBounds(),r=new t.Sphere;n.getBoundingSphere(r);let i=new t.Vector3(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ).distanceTo(r.center)+r.radius;return Math.max(e,i*1.25)}getContainerSize(){return this.exportSizeOverride?this.exportSizeOverride:this.getLiveContainerSize()}getLiveContainerSize(){let e=this.container.getBoundingClientRect();return{width:Math.max(1,e.width||window.innerWidth),height:Math.max(1,e.height||window.innerHeight)}}getSubjectBounds(){let e=new t.Box3,n=new t.Matrix4,r=new t.Matrix4,i=new t.Box3,a=t=>{t.geometry.computeBoundingBox();let a=t.geometry.boundingBox;if(a){t.updateMatrixWorld();for(let o=0;o<t.count;o+=1)t.getMatrixAt(o,n),r.multiplyMatrices(t.matrixWorld,n),i.copy(a).applyMatrix4(r),e.union(i)}};return a(this.mesh),this.imageSetMeshes.forEach(a),e.isEmpty()&&e.setFromCenterAndSize(new t.Vector3(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),new t.Vector3(1,1,1)),e}getPerspectiveFovFromFocalLength(){return ee(this.settings.cameraFocalLength)}updateColors(){this.settings.backgroundMode===`image`&&this.invalidateBackgroundImageDisplayTexture(),this.updateSceneBackground(),this.updateMaterial(),this.renderIdleFrame()}updateMaterial(){let e=this.mesh.material;this.disposeMeshMaterial(e);let t=this.outlineMesh.material;this.disposeMeshMaterial(t),this.mesh.material=this.createMaterial(),this.syncImageSetMeshes(),this.outlineMesh.material=this.createOutlineMaterial(),this.edgeMaterial?.dispose(),this.edgeMaterial=this.createEdgeMaterial(),this.outlineMesh.visible=this.shouldShowSilhouetteOutline(),this.edgeGroup.visible=this.shouldShowEdgeOutline(),this.edgeGroup.renderOrder=this.getEdgeRenderOrder(),this.shouldShowEdgeOutline()?(this.edgeGeometry||=this.createEdgeGeometry(this.mesh.geometry),this.edgeLines.forEach(e=>{this.disposeMeshMaterial(e.material),e.material=this.edgeMaterial.clone()}),this.syncEdgeLineCount()):this.rebuildEdgeLines(),this.updateLights(),this.renderIdleFrame()}getMaxInstanceCount(){let{gridSize:e,gridLayers:t,ringCount:n,ringDensity:r,pathInstanceCount:i,pathRows:a}=Se(this.settings),o=Math.ceil(1+r*(n*(n+1))/2),s=i*Math.max(1,Math.round(a)),c=e*e*Math.max(1,Math.round(t));return Math.max(1,e*e,c,o,s)}ensureMeshCapacity(e){if(e<=this.mesh.instanceMatrix.count)return;let n=this.mesh.geometry,r=this.mesh.material,i=Math.ceil(e*1.25),a=new t.InstancedMesh(n,r,i);a.renderOrder=1,a.frustumCulled=!1;let o=new t.InstancedMesh(this.outlineMesh.geometry,this.outlineMesh.material,i);o.renderOrder=0,o.frustumCulled=!1,o.visible=this.outlineMesh.visible,this.scene.remove(this.mesh),this.scene.remove(this.outlineMesh),this.mesh=a,this.outlineMesh=o,this.scene.add(this.mesh),this.scene.add(this.outlineMesh),this.syncImageSetMeshes()}createLayouts(){return De(this.settings)}getSpinStaggerFactor(e,t){let n=this.settings.instanceSpinStagger;if(n===0)return 1;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);if(this.settings.instanceSpinStaggerMode===`alternating`){let t=e.gridX%2==0?1:-1;return Math.max(-4,1+t*n*r)}return Math.max(-4,1+n*r)}getSpinPhaseOffset(e,t){let n=this.settings.instanceSpinPhaseStagger;if(n===0)return 0;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);return this.settings.instanceSpinStaggerMode===`alternating`?(e.gridX%2==0?1:-1)*n*r:n*r}getLayoutProgress(e,t){return t===0?0:e.distance/t}renderExportFrameAt(e,t){if(!this.hasTimeVaryingMotion()){this.renderScene(t);return}this.renderAnimatedFrame(e,this.getPathTravelTime(e),this.getRingOrbitTime(e),t)}animate=()=>{let e=(performance.now()-this.startTime)/1e3;if(!this.hasTimeVaryingMotion()){this.animationFrameId=null,this.updatePattern();return}let t=Math.max(0,Math.min(.1,e-this.previousAnimationElapsed));this.previousAnimationElapsed=e,this.pathTravelProgress+=this.getPathTravelDelta(t),this.ringOrbitProgress+=this.getRingOrbitDelta(t),this.renderAnimatedFrame(e,this.pathTravelProgress,this.ringOrbitProgress),this.animationFrameId=requestAnimationFrame(this.animate)};getPathTravelTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}getPathTravelDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}renderAnimatedFrame(e,t,n,r=this.renderer){let{instanceRotationX:i,instanceRotationY:a,instanceRotationZ:o,instanceSpinX:s,instanceSpinY:c,instanceSpinZ:l,instanceSpinStagger:u,instanceSpinPhaseStagger:d,pathRotationX:f,pathRotationY:p,pathRotationZ:m,waveAmplitude:h,waveFrequency:g,waveSpeed:_,easingMode:v,easingCustomBezier:y,staggerAmount:b,scaleMode:x,scaleAmount:S,animationMode:C,scaleY:w,baseY:T,groundAlign:E}=this.settings;this.setStructureRotation(e*f,e*p,e*m);let D={...this.settings,...Se(this.settings),ringOrbitFriction:this.settings.ringOrbitFriction},O=this.getEdgeScaleLift(),k=T+(E?w/2:0),A=u===0&&d===0?0:this.layouts.reduce((e,t)=>Math.max(e,t.distance),0);this.clearInstanceColorsForImageSurfaces(),this.ensureInstanceOpacityAttribute(this.mesh),this.ensureInstanceOpacityAttribute(this.outlineMesh),this.imageSetMeshes.forEach(e=>this.ensureInstanceOpacityAttribute(e));let j=this.createSurfaceWriteState(),M=this.getLayoutBounds(this.layouts),N=this.getBuildTransform(this.getBuildProgress(e));this.layouts.forEach((r,u)=>{let d=ft({layout:r,settings:D,pathTravelProgress:t,ringOrbitProgress:n}),f=(d.gridX+d.gridZ)%2==0?1:-1,p=d.distance;C===`linear-wave`&&(p=d.x+d.z),C===`checker-wave`&&(p=d.distance*f),C===`ring-wave`&&(p=d.ringIndex);let m=(d.distance+d.ringIndex)*b,w=e*_-m,T=Math.sin(p*g-w);T=ot(T,v,y),C===`cross-field`&&(T=ot(Math.sin(d.x*g-w)*Math.sin(d.z*g+w),v,y));let E=Math.abs(_)<=Df?0:T*h;this.dummy.position.set(d.x*N.sceneScale,(k+d.y+E)*N.sceneScale+N.offsetY,d.z*N.sceneScale);let P=this.getInstanceScale(d,x,S)*N.scale*N.sceneScale;this.dummy.scale.set(P,P,P);let F=this.getSpinStaggerFactor(d,A),I=this.getSpinPhaseOffset(d,A),ee=this.alignQuaternion(d,this.alignQuatScratch);this.manualQuatScratch.setFromEuler(this.orientationEulerScratch.set(i+N.rotationX,a+N.rotationY,o+N.rotationZ)),this.spinQuatScratch.setFromEuler(this.orientationEulerScratch.set(e*s*F+(Math.abs(s)>1e-4?I:0),e*c*F+(Math.abs(c)>1e-4?I:0),e*l*F+(Math.abs(l)>1e-4?I:0))),this.dummy.quaternion.copy(ee).multiply(this.manualQuatScratch).multiply(this.spinQuatScratch),this.dummy.updateMatrix();let te=this.getInstanceOpacity(u,d)*N.opacity,ne=this.setSurfaceMatrixAt(u,this.dummy.matrix,j);this.setInstanceOpacityAt(ne.mesh,ne.index,te),this.setInstanceColorAt(ne.mesh,ne.index,this.getInstanceColor(d,M)),this.dummy.scale.setScalar(P*O),this.dummy.updateMatrix();let re=this.edgeLines[u];re&&(re.matrix.copy(this.dummy.matrix),re.matrixWorldNeedsUpdate=!0,this.setEdgeLineOpacity(re,te)),this.dummy.scale.setScalar(P*(1+this.settings.outlineThickness)),this.dummy.updateMatrix(),this.outlineMesh.setMatrixAt(u,this.dummy.matrix),this.setInstanceOpacityAt(this.outlineMesh,u,te)}),this.finishSurfaceWrites(j),this.outlineMesh.instanceMatrix.needsUpdate=!0,this.renderScene(r)}getInstanceScale(e,t,n){if(t===`constant`||n===0)return 1;let r=this.layouts.reduce((e,t)=>Math.max(e,t.distance),0),i=r===0?0:e.distance/r,a=e=>{let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)},o=(e,t=n)=>{let r=a(e);return I(t>=0?1+r*t:1/(1+r*Math.abs(t)),1,P.instance.scaleVariationMultiplier)};if(t===`center-out`)return o(i);if(t===`edge-out`)return o(1-i);if(t===`alternating`)return o(1,((e.gridX+e.gridZ)%2==0?1:-1)*n);let s=Math.max(0,Math.min(1,e.pathProgress)),c=1-Math.abs(s-.5)*2,l=Math.abs(s-.5)*2;if(t===`path-linear`)return o(s);if(t===`path-linear-reverse`)return o(1-s);if(t===`path-center`)return o(c);if(t===`path-edges`)return o(l);if(t===`path-quad`)return o(s*s);if(t===`path-quad-reverse`){let e=1-s;return o(e*e)}return 1}addLights(){this.ambientLight=new t.AmbientLight(`#ffffff`,this.settings.ambientIntensity),this.scene.add(this.ambientLight),this.directionalLight=new t.DirectionalLight(`#ffffff`,this.settings.lightIntensity),this.setDirectionalLightPosition(),this.scene.add(this.directionalLight)}updateLights(){this.ambientLight&&(this.ambientLight.intensity=this.settings.ambientIntensity),this.directionalLight&&(this.directionalLight.intensity=this.settings.lightIntensity,this.setDirectionalLightPosition()),this.renderIdleFrame()}setDirectionalLightPosition(){if(!this.directionalLight)return;let e=Math.cos(this.settings.lightElevation)*18;this.directionalLight.position.set(Math.cos(this.settings.lightAzimuth)*e,Math.sin(this.settings.lightElevation)*18,Math.sin(this.settings.lightAzimuth)*e),this.directionalLight.lookAt(0,0,0)}applyRendererPixelRatio(){this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,this.settings.renderPixelRatio))}observeContainerSize(){if(typeof ResizeObserver>`u`)return;let{width:e,height:t}=this.getLiveContainerSize();this.observedWidth=e,this.observedHeight=t,this.containerResizeObserver=new ResizeObserver(()=>{if(this.disposed)return;let e=this.getLiveContainerSize();e.width===this.observedWidth&&e.height===this.observedHeight||(this.observedWidth=e.width,this.observedHeight=e.height,this.handleResize())}),this.containerResizeObserver.observe(this.container)}handleResize=()=>{this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.updateCameraProjection();let{width:e,height:t}=this.getContainerSize();this.applyRendererPixelRatio(),this.renderer.setSize(e,t),this.invalidateBackgroundImageDisplayTexture(),this.invalidateTransparentBackgroundPreviewTexture(),this.updateSceneBackground(),this.updateEdgeResolution(e,t),this.renderIdleFrame()}},dp=8,fp=`300px`,pp=new Set,mp=new WeakMap,hp=new WeakSet,gp=new Map,_p=null,vp=dp,yp=0,bp=!1,xp=!1,Sp=()=>typeof IntersectionObserver<`u`,Cp=()=>typeof document>`u`||document.visibilityState!==`hidden`,wp=()=>{let e=0;for(let t of pp)t.isMounted()&&(e+=1);return e},Tp=e=>{let t=null;for(let n of pp)n===e||!n.isMounted()||!n.evictable||n.visible||(!t||n.lastUsed<t.lastUsed)&&(t=n);return t},Ep=()=>{bp||(bp=!0,console.warn(`Sinth: more than ${vp} embeds are on screen at once, so the WebGL context budget cannot be honoured. The browser may drop the oldest context. Show fewer patterns at a time, or raise \`maxLiveContexts\` if the page can afford it.`))},Dp=e=>{for(;wp()>=vp;){let t=Tp(e);if(!t){Ep();return}t.unmount()}},Op=e=>{yp+=1,e.lastUsed=yp,!e.isMounted()&&(Dp(e),e.mount())},kp=(e,t)=>{if(e.visible=t,!t){e.suspend();return}Op(e),Cp()&&e.resume()},Ap=()=>{let e=Cp();for(let t of pp)t.isMounted()&&(e?t.visible&&t.resume():t.suspend())},jp=()=>{xp||typeof document>`u`||(xp=!0,document.addEventListener(`visibilitychange`,Ap))},Mp=e=>{let t=gp.get(e);return t||(t=new IntersectionObserver(e=>{for(let t of e){let e=mp.get(t.target);if(e)for(let n of e)kp(n,t.isIntersecting)}},{rootMargin:e}),gp.set(e,t)),t},Np=e=>{if(hp.has(e))return;hp.add(e);let t=e.id?`id="${e.id}"`:e.className?`class="${e.className}"`:`the same element`;console.warn(`Sinth: more than one embed is pointed at ${t}, so they render on top of one another and only the topmost is visible. Each embed needs its own container. This is usually older embed code that looks the container up by name — re-copy the block from the editor (Embed → Copy embed code) and paste it again. The current code finds the container next to its own <script> tag, so it is safe to paste any number of times.`)};function Pp(e,t){if(typeof t.maxLiveContexts==`number`&&Number.isFinite(t.maxLiveContexts)){let e=Math.max(1,Math.floor(t.maxLiveContexts));_p=_p===null?e:Math.min(_p,e),vp=_p}let n=Sp(),r=t.lazy&&n,i={...e,evictable:r,visible:!r,lastUsed:0,rootMargin:t.rootMargin};if(pp.add(i),jp(),n){let t=mp.get(e.container);t?t.size>0&&Np(e.container):(t=new Set,mp.set(e.container,t)),t.add(i),Mp(i.rootMargin).observe(e.container)}return r||(Op(i),Cp()&&i.resume()),{claim:()=>{Op(i)},release:()=>{if(pp.delete(i),!n)return;let t=mp.get(e.container);t?.delete(i),(!t||t.size===0)&&(Mp(i.rootMargin).unobserve(e.container),mp.delete(e.container))}}}var Fp=`sinth`,Ip=`.${Fp}`,Lp=new WeakSet,Rp=e=>{Lp.add(e)},zp=e=>Lp.has(e),Bp=e=>e instanceof HTMLElement&&e.matches(Ip)&&!Lp.has(e),Vp=e=>{if(!e)return null;for(let t of e.querySelectorAll(Ip))if(Bp(t))return t;return null};function Hp(e){if(Bp(e??null))return e;if(e){for(let t=e.previousElementSibling;t;t=t.previousElementSibling)if(Bp(t))return t;let t=Vp(e.parentElement);if(t)return t}let t=Vp(typeof document>`u`?null:document);if(t)return t;throw Error(`Sinth: no free container found for this embed. Every block needs its own element with class "${Fp}" — the copied embed code brings one with it, so this usually means the <div> was deleted, or its class was renamed, or another embed has already taken it.`)}var Up=1e3,Wp=async e=>{e.rebuildGeometry(),e.updateMaterial(),e.updateColors(),e.updateLights(),e.updateCamera(),e.updatePattern()};function Gp({container:e,preset:t,autoStart:n=!0,lazy:r=!0,rootMargin:i=fp,maxLiveContexts:a}){let o=null,s=t,c=n,l=!1,u=!1,d=!1,f=null,p=!1,m=null,h=()=>{let t=e.getBoundingClientRect();return t.width>0&&t.height>0};Rp(e);let g=()=>{let t=new up(e,{config:s,autoStart:c&&!u});o=t,s&&Wp(t).catch(e=>{console.error(`Unable to initialise the Sinth embed.`,e)})},_=()=>{p||m!==null||typeof window>`u`||(m=window.setTimeout(()=>{if(m=null,l||p||h()||!(e.offsetParent!==null||window.getComputedStyle(e).position===`fixed`))return;p=!0;let t=e.getBoundingClientRect().height===0?`height`:`width`;console.warn(`Sinth: this container has no ${t}, so there is nothing to render into and the embed is waiting. Sinth fills the box it is given — if the container is sized \`${t}: 100%\`, give its parent a ${t} (or set a ${t} on the container itself). It will start on its own the moment the container has one.`,e)},Up))},v=()=>{if(d=!0,_(),!f){if(typeof ResizeObserver>`u`){d=!1,g();return}f=new ResizeObserver(()=>{if(!(l||!d)){if(!h()){_();return}d=!1,g()}}),f.observe(e)}},y=()=>{if(!(o||l)){if(!h()){v();return}g()}},b=()=>{d=!1,o&&=(o.dispose(),null)},x=Pp({container:e,mount:y,unmount:b,resume:()=>{u=!1,c&&o?.start()},suspend:()=>{u=!0,o?.stop()},isMounted:()=>o!==null},{lazy:r,rootMargin:i,maxLiveContexts:a});return{get engine(){return o},updatePreset:e=>{s=e,o&&(o.setConfig(e),Wp(o).catch(e=>{console.error(`Unable to update the Sinth embed preset.`,e)}))},start:()=>{c=!0,x.claim(),o?.start()},stop:()=>{c=!1,o?.stop()},destroy:()=>{l=!0,m!==null&&(clearTimeout(m),m=null),f?.disconnect(),f=null,x.release(),b()}}}var Kp=`.${Fp}, [data-sinth-preset]`,qp=`:scope > script[type="application/json"]`,Jp=new WeakSet,Yp=!1,Xp=(e,t)=>{try{return JSON.parse(e)}catch(e){return console.error(`Sinth: this embed’s preset is not valid JSON, so it was skipped.`,t,e),null}},Zp=e=>{if(e===null||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0},Qp=e=>{let t={};e.dataset.sinthLazy===`false`&&(t.lazy=!1),e.dataset.sinthAutostart===`false`&&(t.autoStart=!1),e.dataset.sinthRootMargin&&(t.rootMargin=e.dataset.sinthRootMargin);let n=Zp(e.dataset.sinthMaxContexts??null);return n!==void 0&&(t.maxLiveContexts=n),t},$p=(e,t)=>{if(zp(e))return null;try{return Gp({container:e,preset:t,...Qp(e)})}catch(t){return console.error(`Sinth: this embed could not be created.`,e,t),null}},em=e=>{if(zp(e)||Jp.has(e))return null;let t=e.querySelector(qp);if(t){let n=Xp(t.textContent??``,e);return n?$p(e,n):null}let n=e.dataset.sinthPreset?.trim();if(!n)return null;if(n.startsWith(`{`)){let t=Xp(n,e);return t?$p(e,t):null}return Jp.add(e),fetch(n,{credentials:`omit`}).then(e=>{if(!e.ok)throw Error(`${e.status} ${e.statusText}`);return e.json()}).then(t=>{Jp.delete(e),$p(e,t)}).catch(t=>{Jp.delete(e),console.error(`Sinth: could not load the preset at "${n}".`,e,t)}),null};function tm(e=document){let t=[];for(let n of e.querySelectorAll(Kp)){let e=em(n);e&&t.push(e)}return t}var nm=e=>e instanceof Element?e.matches(Kp)||e.querySelector(Kp)!==null:!1;function rm(){if(Yp||typeof document>`u`||window.SINTH_AUTO_MOUNT===!1)return;Yp=!0;let e=()=>{if(tm(document),typeof MutationObserver>`u`)return;let e=!1;new MutationObserver(t=>{if(!e){for(let n of t)for(let t of n.addedNodes)if(nm(t)){e=!0,requestAnimationFrame(()=>{e=!1,tm(document)});return}}}).observe(document.documentElement,{childList:!0,subtree:!0})};if(document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,e,{once:!0});return}e()}var im=`1.0.3`,am=`v51`,om=`${im} · v51`;return Rt(),rm(),e.SINTH_CONTAINER_CLASS=Fp,e.SNAPSHOT=am,e.VERSION=im,e.VERSION_LABEL=om,e.createSinthEmbed=Gp,e.fontBaseUrl=Tt,e.mountAll=tm,e.normalizeSinthConfig=lp,e.resolveContainer=Hp,e.setFontBaseUrl=wt,e.startAutoMount=rm,e})({},THREE);window.Sinth=e}})();
package/dist/sinth.min.js CHANGED
@@ -1,6 +1,6 @@
1
- /*! Sinth 1.0.0 (v48) · @s25studio/sinth@1.0.0 · https://unpkg.com/@s25studio/sinth@1.0.0
1
+ /*! Sinth 1.0.3 (v51) · @s25studio/sinth@1.0.3 · https://unpkg.com/@s25studio/sinth@1.0.3
2
2
  * Copyright (c) 2026 S25 Studio. Licensed, not sold — see LICENSE.md in the
3
- * package or https://unpkg.com/@s25studio/sinth@1.0.0/LICENSE.md
3
+ * package or https://unpkg.com/@s25studio/sinth@1.0.3/LICENSE.md
4
4
  *
5
5
  * Bundles three.js addons and, via TTFLoader, opentype.js — both MIT. The
6
6
  * script build three.min.js inlines three.js itself.
@@ -674,4 +674,4 @@ ${n.materialTexture?`vec4 speMaterialTextureColor = getSpeMaterialTextureColor()
674
674
  diffuseColor.rgb *= speMaterialTextureColor.rgb;
675
675
  diffuseColor.a *= speMaterialTextureColor.a;`:``}`).replace(`#include <alphatest_fragment>`,`diffuseColor.a *= vInstanceOpacity;
676
676
  if (diffuseColor.a <= 0.001) discard;
677
- #include <alphatest_fragment>`)},e.customProgramCacheKey=()=>[`spe-instance-opacity`,n.alphaHash?`alpha-hash`:`transparent`,n.objectGradient?`object-gradient`:`solid`,n.materialTexture?`material-texture`:`no-material-texture`].join(`:`),e}rebuildGeometry(){let e=this.createGeometry();this.mesh.geometry.dispose(),this.outlineMesh.geometry.dispose(),this.edgeGeometry?.dispose(),this.mesh.geometry=e,this.outlineMesh.geometry=e.clone(),this.edgeGeometry=this.createEdgeGeometry(e),this.syncImageSetMeshes(),this.rebuildEdgeLines(),this.updatePattern()}setInstanceShape(e){this.settings.instanceShape=e,this.settings.colorMode===`texture`&&!this.isTextureMaterialShape()&&(this.settings.colorMode=`solid`),this.applyInstanceShapeDefaults(e),this.updateMaterial(),this.rebuildGeometry()}applyInstanceShapeDefaults(e){if(this.scaleBeforeShapeDefault&&(this.shapeAutoModified.x&&(this.settings.scaleX=this.scaleBeforeShapeDefault.x),this.shapeAutoModified.y&&(this.settings.scaleY=this.scaleBeforeShapeDefault.y),this.shapeAutoModified.z&&(this.settings.scaleZ=this.scaleBeforeShapeDefault.z)),this.scaleBeforeShapeDefault={x:this.settings.scaleX,y:this.settings.scaleY,z:this.settings.scaleZ},this.shapeAutoModified={x:!1,y:!1,z:!1},e===`pill`){let e=Math.max(this.settings.scaleX,this.settings.scaleZ),t=Math.max(this.settings.scaleY,e*2.8);t!==this.settings.scaleY&&(this.settings.scaleY=t,this.shapeAutoModified.y=!0)}}setInstanceDimension(e,t){this.shapeAutoModified[e]=!1;let n=I(t,$.scaleX,P.instance.dimension);e===`x`?(this.settings.scaleX=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleZ=I(n/this.settings.imageAspectRatio,$.scaleZ,P.instance.dimension))):e===`y`?this.settings.scaleY=n:(this.settings.scaleZ=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(n*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension))),this.syncRoundedCardRatio(),this.rebuildGeometry()}setImagePreserveAspectRatio(e){this.settings.imagePreserveAspectRatio=e,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(this.settings.scaleZ*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension)),this.rebuildGeometry()}shouldLockImageAspectRatio(){return this.settings.instanceShape===`image`&&this.settings.imagePreserveAspectRatio&&this.settings.imageAspectRatio>0}async ensureTextRuntimeLoaded(){if(!(this.textGeometryRuntime&&this.textFonts)){if(this.textRuntimeLoadPromise){await this.textRuntimeLoadPromise;return}this.textRuntimeLoadPromise=Promise.resolve().then(()=>(Au(),xu)).then(async e=>{this.textGeometryRuntime=e,this.textFonts??=new e.TextFontManager,this.settings.textFontSource.source===`url`&&await this.textFonts.loadCustomFont(this.settings.textFontSource.url)}).finally(()=>{this.textRuntimeLoadPromise=null}),await this.textRuntimeLoadPromise}}scheduleTextRuntimeLoad(){this.ensureTextRuntimeLoaded().then(()=>{this.settings.instanceShape===`text`&&this.rebuildGeometry()}).catch(e=>{console.warn(`Unable to load text runtime support.`,e)})}async loadCustomTextFont(e=this.settings.textCustomFontUrl){let t=e.trim();if(!t){this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.settings.textCustomFontUrl=``,this.rebuildGeometry();return}await this.ensureTextRuntimeLoaded(),await this.textFonts?.loadCustomFont(t),this.settings.textCustomFontUrl=t,this.settings.textFont=`custom`,this.settings.textFontSource={source:`url`,url:t},this.rebuildGeometry()}async ensureWebTextFont(e){await this.ensureTextRuntimeLoaded(),!this.textFonts?.hasFont(e)&&(await this.textFonts?.loadWebFont(e),this.settings.textFont===e&&this.settings.instanceShape===`text`&&this.rebuildGeometry())}setTextFont(e){if(this.settings.textFont=e,e===`custom`){this.settings.textCustomFontUrl.trim()?this.loadCustomTextFont().catch(e=>{console.warn(`Unable to load custom text font.`,e)}):(this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.rebuildGeometry());return}this.settings.textFontSource={source:`library`,id:e},this.settings.textCustomFontUrl=``,Dt(e)&&this.ensureWebTextFont(e).catch(e=>{console.warn(`Unable to load text font.`,e)}),this.rebuildGeometry()}syncRoundedCardRatio(){this.settings.instanceShape===`rounded-card`&&(this.settings.roundedCardRatio=this.settings.scaleX/Math.max(.01,this.settings.scaleZ))}async loadCustomObj(e=this.settings.assetUrl,t={}){await this.loadCustomAsset(e,t)}async loadCustomAsset(e=this.settings.assetUrl,{showPlaceholder:t=!1,source:n=`background`}={}){let r=e.trim();if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let i=++this.customAssetLoadId;if(n===`user`&&(this.activeUserCustomAssetLoadId=i),this.settings.assetUrl=r,!r){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry();return}t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry());try{let e=await Promise.resolve().then(()=>(cf(),qd)),t=await e.loadCustomAssetGeometry(sp(r));this.completeCustomAssetLoad(i,t,e.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadCustomFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearCustomAssetLoad(i);return}let t=await Promise.resolve().then(()=>(cf(),qd)),n=await t.loadCustomAssetGeometryFromFile(e);this.completeCustomAssetLoad(i,n,t.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearSvgAssetLoad(r);return}let e=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometry(sp(n),this.settings.svgSolidify);this.completeSvgAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearSvgAssetLoad(i);return}let t=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometryFromFile(e,this.settings.svgSolidify);this.completeSvgAssetLoad(i,t)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearImageAssetLoad(r);return}let e=await this.textureLoader.loadAsync(sp(n));this.completeImageAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageFile(e,t,n={}){await this.loadImageAsset(t,n)}async loadImageSet(e=this.settings.imageSetUrls,t={}){let n=op(e),r=this.beginCustomAssetLoad(n[0]??``,t);try{if(n.length===0){this.clearImageAssetLoad(r);return}let e=await Promise.all(n.map(e=>this.textureLoader.loadAsync(sp(e))));this.completeImageSetAssetLoad(r,n,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadBackgroundImage(e=this.settings.backgroundImageUrl){let t=e.trim();if(this.settings.backgroundImageUrl=t,!t){this.clearBackgroundImage();return}let n=await this.textureLoader.loadAsync(sp(t));this.backgroundTexture?.dispose(),this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.backgroundTexture=n,this.configureImageTexture(n),this.settings.backgroundMode=`image`,this.updateSceneBackground(),this.renderIdleFrame()}async loadBackgroundImageFile(e,t){await this.loadBackgroundImage(t)}async loadMaterialTexture(e=this.settings.materialTextureUrl){let n=e.trim();if(this.settings.materialTextureUrl=n,!n){this.clearMaterialTexture();return}let r=await this.textureLoader.loadAsync(sp(n));this.materialTexture?.dispose(),this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.materialTexture=r,this.configureImageTexture(r),r.wrapS=t.RepeatWrapping,r.wrapT=t.RepeatWrapping,this.settings.colorMode=`texture`,this.updateMaterial(),this.renderIdleFrame()}async loadMaterialTextureFile(e,t){await this.loadMaterialTexture(t)}clearMaterialTexture(){this.settings.materialTextureUrl=``,this.materialTexture?.dispose(),this.materialTexture=null,this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.updateMaterial(),this.renderIdleFrame()}clearBackgroundImage(){this.settings.backgroundImageUrl=``,this.backgroundTexture?.dispose(),this.backgroundTexture=null,this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.updateSceneBackground(),this.renderIdleFrame()}clearCustomAsset(){this.customAssetLoadId+=1,this.activeUserCustomAssetLoadId=0,this.settings.assetUrl=``,this.settings.imageSetUrls=[],this.settings.imageAspectRatio=$.imageAspectRatio,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.updateMaterial(),this.rebuildGeometry()}clearSvgAssetLoad(e){this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}beginCustomAssetLoad(e,{showPlaceholder:t=!1,source:n=`background`}){if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let r=++this.customAssetLoadId;return n===`user`&&(this.activeUserCustomAssetLoadId=r),this.settings.assetUrl=e,t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry()),r}clearCustomAssetLoad(e){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}clearImageAssetLoad(e){this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.settings.imageAspectRatio=$.imageAspectRatio,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeCustomAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw t.dispose(),new wf;this.customAssetLoadId=e,n(t,{assetScale:this.settings.assetScale,assetNormalize:this.settings.assetNormalize}),this.customObjGeometry=t,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`custom-obj`,r&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}completeSvgAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.customSvgGeometry?.dispose(),this.customSvgGeometry=t,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`svg`,n&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.configureImageTexture(t),this.imageTexture=t,this.imageSetTextures=[t],this.settings.imageSetUrls=[];let r=t.image,i=r?.width??$.imageAspectRatio,a=r?.height??1;this.settings.imageAspectRatio=a>0?Math.max(.01,i/a):$.imageAspectRatio,this.settings.instanceShape=`image`,n&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageSetAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw n.forEach(e=>e.dispose()),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,n.forEach(e=>this.configureImageTexture(e)),this.imageSetTextures=n,this.imageTexture=n[0]??null,this.settings.assetUrl=t[0]??``,this.settings.imageSetUrls=t;let i=this.imageTexture?.image,a=i?.width??$.imageAspectRatio,o=i?.height??1;this.settings.imageAspectRatio=o>0?Math.max(.01,a/o):$.imageAspectRatio,this.settings.instanceShape=`image`,r&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}configureImageTexture(e){e.colorSpace=t.SRGBColorSpace,e.needsUpdate=!0}updateSceneBackground(){if(this.settings.backgroundMode===`transparent`){this.scene.background=null;return}if(this.settings.backgroundMode===`image`){this.scene.background=this.updateBackgroundImageDisplayTexture();return}if(this.settings.backgroundMode===`gradient`){this.scene.background=this.updateBackgroundGradientTexture();return}this.scene.background=new t.Color(this.settings.backgroundColor)}invalidateBackgroundImageDisplayTexture(){this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null}invalidateTransparentBackgroundPreviewTexture(){this.transparentBackgroundPreviewTexture?.dispose(),this.transparentBackgroundPreviewTexture=null}updateTransparentBackgroundPreviewTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.max(1,Math.round(e)),i=Math.max(1,Math.round(n)),a=this.transparentBackgroundPreviewTexture,o=a?.image instanceof HTMLCanvasElement?a.image:document.createElement(`canvas`);if(a&&o.width===r&&o.height===i)return a;o.width=r,o.height=i;let s=o.getContext(`2d`);return s&&this.drawCheckerBackground(s,r,i),this.transparentBackgroundPreviewTexture||(this.transparentBackgroundPreviewTexture=new t.CanvasTexture(o),this.transparentBackgroundPreviewTexture.colorSpace=t.SRGBColorSpace,this.transparentBackgroundPreviewTexture.wrapS=t.ClampToEdgeWrapping,this.transparentBackgroundPreviewTexture.wrapT=t.ClampToEdgeWrapping),this.transparentBackgroundPreviewTexture.needsUpdate=!0,this.transparentBackgroundPreviewTexture}updateBackgroundImageDisplayTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.min(1,1600/Math.max(e,n)),i=Math.max(1,Math.round(e*r)),a=Math.max(1,Math.round(n*r)),o=i/a,s=this.backgroundImageDisplayTexture?.image instanceof HTMLCanvasElement?this.backgroundImageDisplayTexture.image:document.createElement(`canvas`);s.width=i,s.height=a;let c=s.getContext(`2d`);if(!c)return this.backgroundTexture??this.getCheckerTexture();if(!this.backgroundTexture)this.drawCheckerBackground(c,i,a);else{let e=this.backgroundTexture.image,t=this.getTextureImageAspect(this.backgroundTexture);if(!t)return this.backgroundTexture;c.fillStyle=this.settings.backgroundColor,c.fillRect(0,0,i,a);let n=this.settings.backgroundImageFit===`fit`?t>o?i/this.getTextureImageWidth(this.backgroundTexture):a/this.getTextureImageHeight(this.backgroundTexture):t>o?a/this.getTextureImageHeight(this.backgroundTexture):i/this.getTextureImageWidth(this.backgroundTexture),r=this.getTextureImageWidth(this.backgroundTexture)*n,s=this.getTextureImageHeight(this.backgroundTexture)*n;c.drawImage(e,(i-r)*.5,(a-s)*.5,r,s)}return this.backgroundImageDisplayTexture||(this.backgroundImageDisplayTexture=new t.CanvasTexture(s),this.backgroundImageDisplayTexture.colorSpace=t.SRGBColorSpace,this.backgroundImageDisplayTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundImageDisplayTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundImageDisplayTexture.needsUpdate=!0,this.backgroundImageDisplayTexture}drawCheckerBackground(e,t,n){e.fillStyle=Mf,e.fillRect(0,0,t,n),e.fillStyle=Nf;for(let r=0;r<n;r+=Af)for(let n=r/Af%2==0?Af:0;n<t;n+=Af*2)e.fillRect(n,r,Af,Af)}updateBackgroundGradientTexture(){let e=this.backgroundGradientTexture?.image instanceof HTMLCanvasElement?this.backgroundGradientTexture.image:document.createElement(`canvas`);e.width=512,e.height=512;let n=e.getContext(`2d`);if(!n)return new t.Color(this.settings.backgroundColor);let r=n.createImageData(512,512),i=new t.Color(this.settings.backgroundGradientColorA),a=new t.Color(this.settings.backgroundGradientColorB),o=new t.Color,s=Qf(this.settings.backgroundGradientMidpoint),c=511*.5,l=Math.max(1e-4,Math.hypot(c,c));for(let e=0;e<512;e+=1)for(let t=0;t<512;t+=1){let n=this.getBackgroundGradientProgress(t,e,512,c,l),u=at(this.remapGradientProgressWithMidpoint(n,s),this.settings.backgroundGradientEasing,this.settings.backgroundGradientCustomBezier);o.copy(i).lerp(a,u);let d=(e*512+t)*4;r.data[d]=Math.round(o.r*255),r.data[d+1]=Math.round(o.g*255),r.data[d+2]=Math.round(o.b*255),r.data[d+3]=255}return n.putImageData(r,0,0),this.backgroundGradientTexture||(this.backgroundGradientTexture=new t.CanvasTexture(e),this.backgroundGradientTexture.colorSpace=t.SRGBColorSpace,this.backgroundGradientTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundGradientTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundGradientTexture.needsUpdate=!0,this.backgroundGradientTexture}getBackgroundGradientProgress(e,n,r,i,a){return this.settings.backgroundGradientDirection===`x`?r<=1?.5:e/(r-1):this.settings.backgroundGradientDirection===`radial`?t.MathUtils.clamp(Math.hypot(e-i,n-i)/a,0,1):r<=1?.5:1-n/(r-1)}getTextureImageAspect(e){let t=this.getTextureImageWidth(e),n=this.getTextureImageHeight(e);return t<=0||n<=0?null:t/n}getTextureImageWidth(e){let t=e.image;return t?.naturalWidth??t?.width??0}getTextureImageHeight(e){let t=e.image;return t?.naturalHeight??t?.height??0}disposeImageSetTextures(){this.imageSetTextures.forEach(e=>{e!==this.imageTexture&&e.dispose()}),this.imageSetTextures=[]}createGeometry(){return this.settings.instanceShape===`text`&&(!this.textGeometryRuntime||!this.textFonts)&&this.scheduleTextRuntimeLoad(),this.settings.instanceShape===`image`&&this.imageTexture?this.createImageGeometryForTexture(this.imageTexture):this.settings.instanceShape===`image`&&!this.imageTexture||this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createImagePlaceholderGeometry():Bt({settings:this.settings,customObjGeometry:this.customObjGeometry,customSvgGeometry:this.customSvgGeometry,textGeometry:this.textGeometryRuntime&&this.textFonts?{createTextGeometry:this.textGeometryRuntime.createTextGeometry,textFonts:this.textFonts}:null})}getInstanceDimensions(){return Ot(this.settings)}createMaterial(){let e,n=this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`,r=this.usesMaterialTextureSurface();if(e=this.settings.instanceShape===`image`?this.imageTexture?this.createImageMaterial(this.imageTexture):this.createCheckerImageMaterial():this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createCheckerImageMaterial():this.settings.shadingMode===`flat`||this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`?new t.MeshBasicMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):this.settings.shadingMode===`toon`?new t.MeshToonMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):new t.MeshStandardMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor,roughness:this.settings.roughness,metalness:this.settings.metalness}),n)e.side=t.DoubleSide,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;else{let n=this.settings.instanceShape===`image`,r=this.settings.instanceShape===`svg`&&!this.settings.svgSolidify,i=this.settings.instanceShape===`text`&&!this.settings.textSolidify,a=this.settings.instanceShape===`custom-obj`&&this.settings.assetDoubleSided;(n||r||i||a)&&(e.side=t.DoubleSide),e.polygonOffset=!0,e.polygonOffsetFactor=1,e.polygonOffsetUnits=1}return this.enableInstanceOpacity(e,{alphaHash:!0,objectGradient:this.usesObjectGradient(),materialTexture:r})}usesGradientSurfaceColor(){return this.settings.colorMode===`gradient`&&this.settings.instanceShape!==`image`}usesMaterialTextureSurface(){return this.settings.colorMode===`texture`&&this.isTextureMaterialShape()}isTextureMaterialShape(){return this.settings.instanceShape!==`image`&&this.settings.instanceShape!==`svg`}usesInstanceColors(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`pattern`}usesObjectGradient(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`object`}getMaterialTextureModeIndex(){return this.materialTexture?this.settings.materialTextureFit===`fit`?1:this.settings.materialTextureFit===`fill`?2:this.settings.materialTextureFit===`repeat`?3:0:3}getMaterialTextureScopeIndex(){return+(this.settings.materialTextureScope===`pattern`)}getMaterialTextureProjectionIndex(){return+(this.settings.materialTextureProjection===`triplanar`)}createImageMaterial(e){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:e,transparent:!0,alphaTest:.01,depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}createCheckerImageMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:this.getCheckerTexture(),depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}getMaterialTexture(){return this.materialTexture??this.getCheckerTexture()}getMaterialTextureRepeat(e){return this.materialTexture?Math.max(.001,e):jf}getCheckerTexture(){if(this.checkerTexture)return this.checkerTexture;let e=document.createElement(`canvas`);e.width=kf*2,e.height=kf*2;let n=e.getContext(`2d`);return n&&(n.fillStyle=Mf,n.fillRect(0,0,e.width,e.height),n.fillStyle=Nf,n.fillRect(kf,0,kf,kf),n.fillRect(0,kf,kf,kf)),this.checkerTexture=new t.CanvasTexture(e),this.checkerTexture.colorSpace=t.SRGBColorSpace,this.checkerTexture.wrapS=t.RepeatWrapping,this.checkerTexture.wrapT=t.RepeatWrapping,this.checkerTexture.magFilter=t.NearestFilter,this.checkerTexture.minFilter=t.NearestFilter,this.checkerTexture.repeat.set(jf,jf),this.checkerTexture.needsUpdate=!0,this.checkerTexture}getTextureAspectRatio(e){let t=e.image,n=t?.width??$.imageAspectRatio,r=t?.height??1;return r>0?Math.max(.01,n/r):$.imageAspectRatio}createImageGeometryForTexture(e){let{scaleX:n,scaleZ:r}=this.getInstanceDimensions(),i=this.settings.imagePreserveAspectRatio?r*this.getTextureAspectRatio(e):n,a=Math.min(.5,Math.max(0,this.settings.imageCornerRadius)),o=a>0?rp(i,r,Math.min(i,r)*a):new t.PlaneGeometry(i,r);return o.rotateX(-Math.PI/2),o}createImagePlaceholderGeometry(){let{scaleX:e,scaleZ:n}=this.getInstanceDimensions(),r=new t.PlaneGeometry(e,n);return r.rotateX(-Math.PI/2),r}createOutlineMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({color:this.settings.silhouetteColor,side:t.BackSide,opacity:1,depthTest:!0,depthWrite:!0}),{alphaHash:!0})}createEdgeGeometry(e){let n=new t.EdgesGeometry(e,1),r=n.getAttribute(`position`).array,i=new p;return i.setPositions(Array.from(r)),n.dispose(),i}createEdgeMaterial(){let e=new m({color:new t.Color(this.settings.edgeColor).getHex(),linewidth:this.settings.edgeThickness*1e3,transparent:!0,opacity:this.settings.outlineOpacity,depthTest:!this.settings.outlineSeeThrough,depthWrite:!1,polygonOffset:!1,polygonOffsetFactor:0,polygonOffsetUnits:0}),{width:n,height:r}=this.getContainerSize();return e.resolution.set(n,r),e}shouldShowSilhouetteOutline(){return this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`silhouette-edge-outline`}shouldShowEdgeOutline(){return this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`}createEdgeLine(){if(!this.edgeGeometry||!this.edgeMaterial)return null;let e=this.edgeMaterial.clone(),{width:t,height:n}=this.getContainerSize();e.resolution.set(t,n),e.depthTest=!this.settings.outlineSeeThrough,e.depthWrite=!1,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;let r=new N(this.edgeGeometry,e);return r.renderOrder=this.getEdgeRenderOrder(),r.matrixAutoUpdate=!1,r.frustumCulled=!1,r}syncImageSetMeshes(){let e=this.getImageTextures(),n=Math.max(0,e.length-1),r=this.mesh.instanceMatrix.count;for(;this.imageSetMeshes.length>n;){let e=this.imageSetMeshes.pop();e&&(this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material))}for(;this.imageSetMeshes.length<n;){let n=e[this.imageSetMeshes.length+1],i=new t.InstancedMesh(this.createImageGeometryForTexture(n),this.createImageMaterial(n),r);i.renderOrder=this.mesh.renderOrder,i.frustumCulled=!1,this.imageSetMeshes.push(i),this.scene.add(i)}this.imageSetMeshes.forEach((n,i)=>{let a=e[i+1];if(n.instanceMatrix.count!==r){let e=new t.InstancedMesh(this.createImageGeometryForTexture(a),this.createImageMaterial(a),r);e.renderOrder=n.renderOrder,e.frustumCulled=!1,e.count=n.count,this.scene.remove(n),n.geometry.dispose(),this.disposeMeshMaterial(n.material),this.imageSetMeshes[i]=e,this.scene.add(e);return}n.geometry.dispose(),n.geometry=this.createImageGeometryForTexture(a),this.disposeMeshMaterial(n.material),n.material=this.createImageMaterial(a),n.renderOrder=this.mesh.renderOrder}),this.syncImageSetMeshTransforms()}disposeImageSetMeshes(){this.imageSetMeshes.forEach(e=>{this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material)}),this.imageSetMeshes=[]}disposeMeshMaterial(e){if(Array.isArray(e)){e.forEach(e=>e.dispose());return}e.dispose()}rebuildEdgeLines(){this.edgeLines.forEach(e=>{this.edgeGroup.remove(e),this.disposeMeshMaterial(e.material)}),this.edgeLines=[],this.shouldShowEdgeOutline()&&this.syncEdgeLineCount()}syncEdgeLineCount(){if(!this.shouldShowEdgeOutline()){this.edgeGroup.visible=!1;return}for(this.edgeGroup.visible=!0;this.edgeLines.length<this.layouts.length;){let e=this.createEdgeLine();if(!e)return;this.edgeLines.push(e),this.edgeGroup.add(e)}this.edgeLines.forEach((e,t)=>{e.visible=t<this.layouts.length,e.renderOrder=this.getEdgeRenderOrder()})}setEdgeLineOpacity(e,n){let r=e.material;r.opacity=this.settings.outlineOpacity*t.MathUtils.clamp(n,0,1),r.transparent=!0,r.needsUpdate=!0}getEdgeRenderOrder(){return this.settings.edgeCompositing===`surface`?2:10}getEdgeScaleLift(){return 1}ensureCameraType(){this.settings.viewMode===`perspective`!=this.camera instanceof t.PerspectiveCamera&&(this.camera=this.createCamera())}updateCamera(){this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.settings.viewMode===`orthographic`&&this.settings.orthographicView!==`custom`?this.updateOrthographicViewCamera():this.updateCameraOrbit(),this.updateCameraProjection(),this.camera.position.set(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ);let e=ve({distance:this.settings.cameraDistance,azimuth:this.settings.cameraOrbitAngle,elevation:this.settings.cameraElevation,target:{x:this.settings.cameraTargetX,y:this.settings.cameraTargetY,z:this.settings.cameraTargetZ}});this.camera.up.set(e.x,e.y,e.z),this.camera.lookAt(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),this.camera.updateProjectionMatrix()}applyCameraSettings(){this.updateCamera(),this.notifyCameraChange(),this.renderIdleFrame()}setStarfieldFlightFromCamera(e=!0){if(this.settings.distributionMode!==`starfield`)return;let t=this.alignVecScratch.set(this.settings.cameraPositionX-this.settings.cameraTargetX,this.settings.cameraPositionY-this.settings.cameraTargetY,this.settings.cameraPositionZ-this.settings.cameraTargetZ);if(t.lengthSq()<1e-8)return;t.normalize();let n=this.alignUpScratch.setFromMatrixColumn(this.camera.matrixWorld,1).normalize(),r=this.alignRightScratch.copy(n).cross(t);if(r.lengthSq()<1e-8)return;r.normalize();let i=n.copy(t).cross(r).normalize();this.alignMatrixScratch.makeBasis(r,i,t),this.orientationEulerScratch.setFromRotationMatrix(this.alignMatrixScratch),this.settings.pathOrientationX=this.orientationEulerScratch.x,this.settings.pathOrientationY=this.orientationEulerScratch.y,this.settings.pathOrientationZ=this.orientationEulerScratch.z,e&&this.updatePattern()}updateOrthographicViewCamera(){let e=Math.max(1,this.settings.cameraDistance||42),t=this.settings.cameraTargetX,n=this.settings.cameraTargetY,r=this.settings.cameraTargetZ;switch(this.settings.orthographicView){case`front`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r+e;break;case`back`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r-e;break;case`left`:this.settings.cameraPositionX=t-e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`right`:this.settings.cameraPositionX=t+e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`top`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n+e,this.settings.cameraPositionZ=r;break;default:this.updateCameraOrbit();break}}getOrthographicFrustumSize(){return Lf*(If/I(this.settings.orthoScale,$.orthoScale,P.camera.orthographicFrustumScale))}createCamera(){let{width:e,height:n}=this.getContainerSize(),r=e/n;return this.settings.viewMode===`perspective`?new t.PerspectiveCamera(this.getPerspectiveFovFromFocalLength(),r,P.camera.perspectiveClip.near,P.camera.perspectiveClip.far):new t.OrthographicCamera(this.frustumSize*r/-2,this.frustumSize*r/2,this.frustumSize/2,this.frustumSize/-2,P.camera.orthographicClip.near,P.camera.orthographicClip.far)}createViewportGrid(){let e=new t.GridHelper(80,80,`#6c6c6c`,`#6c6c6c`);return e.visible=!1,e.renderOrder=-1,(Array.isArray(e.material)?e.material:[e.material]).forEach(e=>{e.transparent=!0,e.opacity=.32,e.depthWrite=!1}),e}updateCameraProjection(){let{width:e,height:n}=this.getContainerSize(),r=e/n;if(this.camera instanceof t.PerspectiveCamera){this.camera.fov=this.getPerspectiveFovFromFocalLength(),this.camera.aspect=r,this.camera.near=P.camera.perspectiveClip.near,this.camera.far=this.getPerspectiveFarClip(),this.camera.updateProjectionMatrix();return}this.camera.left=this.frustumSize*r/-2,this.camera.right=this.frustumSize*r/2,this.camera.top=this.frustumSize/2,this.camera.bottom=this.frustumSize/-2,this.camera.updateProjectionMatrix()}getPerspectiveFarClip(){let e=P.camera.perspectiveClip.far;if(!this.mesh)return e;let n=this.getSubjectBounds(),r=new t.Sphere;n.getBoundingSphere(r);let i=new t.Vector3(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ).distanceTo(r.center)+r.radius;return Math.max(e,i*1.25)}getContainerSize(){return this.exportSizeOverride?this.exportSizeOverride:this.getLiveContainerSize()}getLiveContainerSize(){let e=this.container.getBoundingClientRect();return{width:Math.max(1,e.width||window.innerWidth),height:Math.max(1,e.height||window.innerHeight)}}getSubjectBounds(){let e=new t.Box3,n=new t.Matrix4,r=new t.Matrix4,i=new t.Box3,a=t=>{t.geometry.computeBoundingBox();let a=t.geometry.boundingBox;if(a){t.updateMatrixWorld();for(let o=0;o<t.count;o+=1)t.getMatrixAt(o,n),r.multiplyMatrices(t.matrixWorld,n),i.copy(a).applyMatrix4(r),e.union(i)}};return a(this.mesh),this.imageSetMeshes.forEach(a),e.isEmpty()&&e.setFromCenterAndSize(new t.Vector3(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),new t.Vector3(1,1,1)),e}getPerspectiveFovFromFocalLength(){return ee(this.settings.cameraFocalLength)}updateColors(){this.settings.backgroundMode===`image`&&this.invalidateBackgroundImageDisplayTexture(),this.updateSceneBackground(),this.updateMaterial(),this.renderIdleFrame()}updateMaterial(){let e=this.mesh.material;this.disposeMeshMaterial(e);let t=this.outlineMesh.material;this.disposeMeshMaterial(t),this.mesh.material=this.createMaterial(),this.syncImageSetMeshes(),this.outlineMesh.material=this.createOutlineMaterial(),this.edgeMaterial?.dispose(),this.edgeMaterial=this.createEdgeMaterial(),this.outlineMesh.visible=this.shouldShowSilhouetteOutline(),this.edgeGroup.visible=this.shouldShowEdgeOutline(),this.edgeGroup.renderOrder=this.getEdgeRenderOrder(),this.shouldShowEdgeOutline()?(this.edgeGeometry||=this.createEdgeGeometry(this.mesh.geometry),this.edgeLines.forEach(e=>{this.disposeMeshMaterial(e.material),e.material=this.edgeMaterial.clone()}),this.syncEdgeLineCount()):this.rebuildEdgeLines(),this.updateLights(),this.renderIdleFrame()}getMaxInstanceCount(){let{gridSize:e,gridLayers:t,ringCount:n,ringDensity:r,pathInstanceCount:i,pathRows:a}=Se(this.settings),o=Math.ceil(1+r*(n*(n+1))/2),s=i*Math.max(1,Math.round(a)),c=e*e*Math.max(1,Math.round(t));return Math.max(1,e*e,c,o,s)}ensureMeshCapacity(e){if(e<=this.mesh.instanceMatrix.count)return;let n=this.mesh.geometry,r=this.mesh.material,i=Math.ceil(e*1.25),a=new t.InstancedMesh(n,r,i);a.renderOrder=1,a.frustumCulled=!1;let o=new t.InstancedMesh(this.outlineMesh.geometry,this.outlineMesh.material,i);o.renderOrder=0,o.frustumCulled=!1,o.visible=this.outlineMesh.visible,this.scene.remove(this.mesh),this.scene.remove(this.outlineMesh),this.mesh=a,this.outlineMesh=o,this.scene.add(this.mesh),this.scene.add(this.outlineMesh),this.syncImageSetMeshes()}createLayouts(){return De(this.settings)}getSpinStaggerFactor(e,t){let n=this.settings.instanceSpinStagger;if(n===0)return 1;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);if(this.settings.instanceSpinStaggerMode===`alternating`){let t=e.gridX%2==0?1:-1;return Math.max(-4,1+t*n*r)}return Math.max(-4,1+n*r)}getSpinPhaseOffset(e,t){let n=this.settings.instanceSpinPhaseStagger;if(n===0)return 0;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);return this.settings.instanceSpinStaggerMode===`alternating`?(e.gridX%2==0?1:-1)*n*r:n*r}getLayoutProgress(e,t){return t===0?0:e.distance/t}renderExportFrameAt(e,t){if(!this.hasTimeVaryingMotion()){this.renderScene(t);return}this.renderAnimatedFrame(e,this.getPathTravelTime(e),this.getRingOrbitTime(e),t)}animate=()=>{let e=(performance.now()-this.startTime)/1e3;if(!this.hasTimeVaryingMotion()){this.animationFrameId=null,this.updatePattern();return}let t=Math.max(0,Math.min(.1,e-this.previousAnimationElapsed));this.previousAnimationElapsed=e,this.pathTravelProgress+=this.getPathTravelDelta(t),this.ringOrbitProgress+=this.getRingOrbitDelta(t),this.renderAnimatedFrame(e,this.pathTravelProgress,this.ringOrbitProgress),this.animationFrameId=requestAnimationFrame(this.animate)};getPathTravelTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}getPathTravelDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}renderAnimatedFrame(e,t,n,r=this.renderer){let{instanceRotationX:i,instanceRotationY:a,instanceRotationZ:o,instanceSpinX:s,instanceSpinY:c,instanceSpinZ:l,instanceSpinStagger:u,instanceSpinPhaseStagger:d,pathRotationX:f,pathRotationY:p,pathRotationZ:m,waveAmplitude:h,waveFrequency:g,waveSpeed:_,easingMode:v,easingCustomBezier:y,staggerAmount:b,scaleMode:x,scaleAmount:S,animationMode:C,scaleY:w,baseY:T,groundAlign:E}=this.settings;this.setStructureRotation(e*f,e*p,e*m);let D={...this.settings,...Se(this.settings),ringOrbitFriction:this.settings.ringOrbitFriction},O=this.getEdgeScaleLift(),k=T+(E?w/2:0),A=u===0&&d===0?0:this.layouts.reduce((e,t)=>Math.max(e,t.distance),0);this.clearInstanceColorsForImageSurfaces(),this.ensureInstanceOpacityAttribute(this.mesh),this.ensureInstanceOpacityAttribute(this.outlineMesh),this.imageSetMeshes.forEach(e=>this.ensureInstanceOpacityAttribute(e));let j=this.createSurfaceWriteState(),M=this.getLayoutBounds(this.layouts),N=this.getBuildTransform(this.getBuildProgress(e));this.layouts.forEach((r,u)=>{let d=ft({layout:r,settings:D,pathTravelProgress:t,ringOrbitProgress:n}),f=(d.gridX+d.gridZ)%2==0?1:-1,p=d.distance;C===`linear-wave`&&(p=d.x+d.z),C===`checker-wave`&&(p=d.distance*f),C===`ring-wave`&&(p=d.ringIndex);let m=(d.distance+d.ringIndex)*b,w=e*_-m,T=Math.sin(p*g-w);T=ot(T,v,y),C===`cross-field`&&(T=ot(Math.sin(d.x*g-w)*Math.sin(d.z*g+w),v,y));let E=Math.abs(_)<=Df?0:T*h;this.dummy.position.set(d.x*N.sceneScale,(k+d.y+E)*N.sceneScale+N.offsetY,d.z*N.sceneScale);let P=this.getInstanceScale(d,x,S)*N.scale*N.sceneScale;this.dummy.scale.set(P,P,P);let F=this.getSpinStaggerFactor(d,A),I=this.getSpinPhaseOffset(d,A),ee=this.alignQuaternion(d,this.alignQuatScratch);this.manualQuatScratch.setFromEuler(this.orientationEulerScratch.set(i+N.rotationX,a+N.rotationY,o+N.rotationZ)),this.spinQuatScratch.setFromEuler(this.orientationEulerScratch.set(e*s*F+(Math.abs(s)>1e-4?I:0),e*c*F+(Math.abs(c)>1e-4?I:0),e*l*F+(Math.abs(l)>1e-4?I:0))),this.dummy.quaternion.copy(ee).multiply(this.manualQuatScratch).multiply(this.spinQuatScratch),this.dummy.updateMatrix();let te=this.getInstanceOpacity(u,d)*N.opacity,ne=this.setSurfaceMatrixAt(u,this.dummy.matrix,j);this.setInstanceOpacityAt(ne.mesh,ne.index,te),this.setInstanceColorAt(ne.mesh,ne.index,this.getInstanceColor(d,M)),this.dummy.scale.setScalar(P*O),this.dummy.updateMatrix();let re=this.edgeLines[u];re&&(re.matrix.copy(this.dummy.matrix),re.matrixWorldNeedsUpdate=!0,this.setEdgeLineOpacity(re,te)),this.dummy.scale.setScalar(P*(1+this.settings.outlineThickness)),this.dummy.updateMatrix(),this.outlineMesh.setMatrixAt(u,this.dummy.matrix),this.setInstanceOpacityAt(this.outlineMesh,u,te)}),this.finishSurfaceWrites(j),this.outlineMesh.instanceMatrix.needsUpdate=!0,this.renderScene(r)}getInstanceScale(e,t,n){if(t===`constant`||n===0)return 1;let r=this.layouts.reduce((e,t)=>Math.max(e,t.distance),0),i=r===0?0:e.distance/r,a=e=>{let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)},o=(e,t=n)=>{let r=a(e);return I(t>=0?1+r*t:1/(1+r*Math.abs(t)),1,P.instance.scaleVariationMultiplier)};if(t===`center-out`)return o(i);if(t===`edge-out`)return o(1-i);if(t===`alternating`)return o(1,((e.gridX+e.gridZ)%2==0?1:-1)*n);let s=Math.max(0,Math.min(1,e.pathProgress)),c=1-Math.abs(s-.5)*2,l=Math.abs(s-.5)*2;if(t===`path-linear`)return o(s);if(t===`path-linear-reverse`)return o(1-s);if(t===`path-center`)return o(c);if(t===`path-edges`)return o(l);if(t===`path-quad`)return o(s*s);if(t===`path-quad-reverse`){let e=1-s;return o(e*e)}return 1}addLights(){this.ambientLight=new t.AmbientLight(`#ffffff`,this.settings.ambientIntensity),this.scene.add(this.ambientLight),this.directionalLight=new t.DirectionalLight(`#ffffff`,this.settings.lightIntensity),this.setDirectionalLightPosition(),this.scene.add(this.directionalLight)}updateLights(){this.ambientLight&&(this.ambientLight.intensity=this.settings.ambientIntensity),this.directionalLight&&(this.directionalLight.intensity=this.settings.lightIntensity,this.setDirectionalLightPosition()),this.renderIdleFrame()}setDirectionalLightPosition(){if(!this.directionalLight)return;let e=Math.cos(this.settings.lightElevation)*18;this.directionalLight.position.set(Math.cos(this.settings.lightAzimuth)*e,Math.sin(this.settings.lightElevation)*18,Math.sin(this.settings.lightAzimuth)*e),this.directionalLight.lookAt(0,0,0)}applyRendererPixelRatio(){this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,this.settings.renderPixelRatio))}observeContainerSize(){if(typeof ResizeObserver>`u`)return;let{width:e,height:t}=this.getLiveContainerSize();this.observedWidth=e,this.observedHeight=t,this.containerResizeObserver=new ResizeObserver(()=>{if(this.disposed)return;let e=this.getLiveContainerSize();e.width===this.observedWidth&&e.height===this.observedHeight||(this.observedWidth=e.width,this.observedHeight=e.height,this.handleResize())}),this.containerResizeObserver.observe(this.container)}handleResize=()=>{this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.updateCameraProjection();let{width:e,height:t}=this.getContainerSize();this.applyRendererPixelRatio(),this.renderer.setSize(e,t),this.invalidateBackgroundImageDisplayTexture(),this.invalidateTransparentBackgroundPreviewTexture(),this.updateSceneBackground(),this.updateEdgeResolution(e,t),this.renderIdleFrame()}},dp=8,fp=`300px`,pp=new Set,mp=new WeakMap,hp=new WeakSet,gp=new Map,_p=null,vp=dp,yp=0,bp=!1,xp=!1,Sp=()=>typeof IntersectionObserver<`u`,Cp=()=>typeof document>`u`||document.visibilityState!==`hidden`,wp=()=>{let e=0;for(let t of pp)t.isMounted()&&(e+=1);return e},Tp=e=>{let t=null;for(let n of pp)n===e||!n.isMounted()||!n.evictable||n.visible||(!t||n.lastUsed<t.lastUsed)&&(t=n);return t},Ep=()=>{bp||(bp=!0,console.warn(`Sinth: more than ${vp} embeds are on screen at once, so the WebGL context budget cannot be honoured. The browser may drop the oldest context. Show fewer patterns at a time, or raise \`maxLiveContexts\` if the page can afford it.`))},Dp=e=>{for(;wp()>=vp;){let t=Tp(e);if(!t){Ep();return}t.unmount()}},Op=e=>{yp+=1,e.lastUsed=yp,!e.isMounted()&&(Dp(e),e.mount())},kp=(e,t)=>{if(e.visible=t,!t){e.suspend();return}Op(e),Cp()&&e.resume()},Ap=()=>{let e=Cp();for(let t of pp)t.isMounted()&&(e?t.visible&&t.resume():t.suspend())},jp=()=>{xp||typeof document>`u`||(xp=!0,document.addEventListener(`visibilitychange`,Ap))},Mp=e=>{let t=gp.get(e);return t||(t=new IntersectionObserver(e=>{for(let t of e){let e=mp.get(t.target);if(e)for(let n of e)kp(n,t.isIntersecting)}},{rootMargin:e}),gp.set(e,t)),t},Np=e=>{if(hp.has(e))return;hp.add(e);let t=e.id?`id="${e.id}"`:e.className?`class="${e.className}"`:`the same element`;console.warn(`Sinth: more than one embed is pointed at ${t}, so they render on top of one another and only the topmost is visible. Each embed needs its own container. This is usually older embed code that looks the container up by name — re-copy the block from the editor (Embed → Copy embed code) and paste it again. The current code finds the container next to its own <script> tag, so it is safe to paste any number of times.`)};function Pp(e,t){if(typeof t.maxLiveContexts==`number`&&Number.isFinite(t.maxLiveContexts)){let e=Math.max(1,Math.floor(t.maxLiveContexts));_p=_p===null?e:Math.min(_p,e),vp=_p}let n=Sp(),r=t.lazy&&n,i={...e,evictable:r,visible:!r,lastUsed:0,rootMargin:t.rootMargin};if(pp.add(i),jp(),n){let t=mp.get(e.container);t?t.size>0&&Np(e.container):(t=new Set,mp.set(e.container,t)),t.add(i),Mp(i.rootMargin).observe(e.container)}return r||(Op(i),Cp()&&i.resume()),{claim:()=>{Op(i)},release:()=>{if(pp.delete(i),!n)return;let t=mp.get(e.container);t?.delete(i),(!t||t.size===0)&&(Mp(i.rootMargin).unobserve(e.container),mp.delete(e.container))}}}var Fp=`sinth`,Ip=`.${Fp}`,Lp=new WeakSet,Rp=e=>{Lp.add(e)},zp=e=>Lp.has(e),Bp=e=>e instanceof HTMLElement&&e.matches(Ip)&&!Lp.has(e),Vp=e=>{if(!e)return null;for(let t of e.querySelectorAll(Ip))if(Bp(t))return t;return null};function Hp(e){if(Bp(e??null))return e;if(e){for(let t=e.previousElementSibling;t;t=t.previousElementSibling)if(Bp(t))return t;let t=Vp(e.parentElement);if(t)return t}let t=Vp(typeof document>`u`?null:document);if(t)return t;throw Error(`Sinth: no free container found for this embed. Every block needs its own element with class "${Fp}" — the copied embed code brings one with it, so this usually means the <div> was deleted, or its class was renamed, or another embed has already taken it.`)}var Up=1e3,Wp=async e=>{e.rebuildGeometry(),e.updateMaterial(),e.updateColors(),e.updateLights(),e.updateCamera(),e.updatePattern()};function Gp({container:e,preset:t,autoStart:n=!0,lazy:r=!0,rootMargin:i=fp,maxLiveContexts:a}){let o=null,s=t,c=n,l=!1,u=!1,d=!1,f=null,p=!1,m=null,h=()=>{let t=e.getBoundingClientRect();return t.width>0&&t.height>0};Rp(e);let g=()=>{let t=new up(e,{config:s,autoStart:c&&!u});o=t,s&&Wp(t).catch(e=>{console.error(`Unable to initialise the Sinth embed.`,e)})},_=()=>{p||m!==null||typeof window>`u`||(m=window.setTimeout(()=>{if(m=null,l||p||h()||!(e.offsetParent!==null||window.getComputedStyle(e).position===`fixed`))return;p=!0;let t=e.getBoundingClientRect().height===0?`height`:`width`;console.warn(`Sinth: this container has no ${t}, so there is nothing to render into and the embed is waiting. Sinth fills the box it is given — if the container is sized \`${t}: 100%\`, give its parent a ${t} (or set a ${t} on the container itself). It will start on its own the moment the container has one.`,e)},Up))},v=()=>{if(d=!0,_(),!f){if(typeof ResizeObserver>`u`){d=!1,g();return}f=new ResizeObserver(()=>{if(!(l||!d)){if(!h()){_();return}d=!1,g()}}),f.observe(e)}},y=()=>{if(!(o||l)){if(!h()){v();return}g()}},b=()=>{d=!1,o&&=(o.dispose(),null)},x=Pp({container:e,mount:y,unmount:b,resume:()=>{u=!1,c&&o?.start()},suspend:()=>{u=!0,o?.stop()},isMounted:()=>o!==null},{lazy:r,rootMargin:i,maxLiveContexts:a});return{get engine(){return o},updatePreset:e=>{s=e,o&&(o.setConfig(e),Wp(o).catch(e=>{console.error(`Unable to update the Sinth embed preset.`,e)}))},start:()=>{c=!0,x.claim(),o?.start()},stop:()=>{c=!1,o?.stop()},destroy:()=>{l=!0,m!==null&&(clearTimeout(m),m=null),f?.disconnect(),f=null,x.release(),b()}}}var Kp=`.${Fp}, [data-sinth-preset]`,qp=`:scope > script[type="application/json"]`,Jp=new WeakSet,Yp=!1,Xp=(e,t)=>{try{return JSON.parse(e)}catch(e){return console.error(`Sinth: this embed’s preset is not valid JSON, so it was skipped.`,t,e),null}},Zp=e=>{if(e===null||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0},Qp=e=>{let t={};e.dataset.sinthLazy===`false`&&(t.lazy=!1),e.dataset.sinthAutostart===`false`&&(t.autoStart=!1),e.dataset.sinthRootMargin&&(t.rootMargin=e.dataset.sinthRootMargin);let n=Zp(e.dataset.sinthMaxContexts??null);return n!==void 0&&(t.maxLiveContexts=n),t},$p=(e,t)=>{if(zp(e))return null;try{return Gp({container:e,preset:t,...Qp(e)})}catch(t){return console.error(`Sinth: this embed could not be created.`,e,t),null}},em=e=>{if(zp(e)||Jp.has(e))return null;let t=e.querySelector(qp);if(t){let n=Xp(t.textContent??``,e);return n?$p(e,n):null}let n=e.dataset.sinthPreset?.trim();if(!n)return null;if(n.startsWith(`{`)){let t=Xp(n,e);return t?$p(e,t):null}return Jp.add(e),fetch(n,{credentials:`omit`}).then(e=>{if(!e.ok)throw Error(`${e.status} ${e.statusText}`);return e.json()}).then(t=>{Jp.delete(e),$p(e,t)}).catch(t=>{Jp.delete(e),console.error(`Sinth: could not load the preset at "${n}".`,e,t)}),null};function tm(e=document){let t=[];for(let n of e.querySelectorAll(Kp)){let e=em(n);e&&t.push(e)}return t}var nm=e=>e instanceof Element?e.matches(Kp)||e.querySelector(Kp)!==null:!1;function rm(){if(Yp||typeof document>`u`||window.SINTH_AUTO_MOUNT===!1)return;Yp=!0;let e=()=>{if(tm(document),typeof MutationObserver>`u`)return;let e=!1;new MutationObserver(t=>{if(!e){for(let n of t)for(let t of n.addedNodes)if(nm(t)){e=!0,requestAnimationFrame(()=>{e=!1,tm(document)});return}}}).observe(document.documentElement,{childList:!0,subtree:!0})};if(document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,e,{once:!0});return}e()}var im=`1.0.0`,am=`v48`,om=`${im} · v48`;return Rt(),rm(),e.SINTH_CONTAINER_CLASS=Fp,e.SNAPSHOT=am,e.VERSION=im,e.VERSION_LABEL=om,e.createSinthEmbed=Gp,e.fontBaseUrl=Tt,e.mountAll=tm,e.normalizeSinthConfig=lp,e.resolveContainer=Hp,e.setFontBaseUrl=wt,e.startAutoMount=rm,e})({},THREE);window.Sinth=e}})();
677
+ #include <alphatest_fragment>`)},e.customProgramCacheKey=()=>[`spe-instance-opacity`,n.alphaHash?`alpha-hash`:`transparent`,n.objectGradient?`object-gradient`:`solid`,n.materialTexture?`material-texture`:`no-material-texture`].join(`:`),e}rebuildGeometry(){let e=this.createGeometry();this.mesh.geometry.dispose(),this.outlineMesh.geometry.dispose(),this.edgeGeometry?.dispose(),this.mesh.geometry=e,this.outlineMesh.geometry=e.clone(),this.edgeGeometry=this.createEdgeGeometry(e),this.syncImageSetMeshes(),this.rebuildEdgeLines(),this.updatePattern()}setInstanceShape(e){this.settings.instanceShape=e,this.settings.colorMode===`texture`&&!this.isTextureMaterialShape()&&(this.settings.colorMode=`solid`),this.applyInstanceShapeDefaults(e),this.updateMaterial(),this.rebuildGeometry()}applyInstanceShapeDefaults(e){if(this.scaleBeforeShapeDefault&&(this.shapeAutoModified.x&&(this.settings.scaleX=this.scaleBeforeShapeDefault.x),this.shapeAutoModified.y&&(this.settings.scaleY=this.scaleBeforeShapeDefault.y),this.shapeAutoModified.z&&(this.settings.scaleZ=this.scaleBeforeShapeDefault.z)),this.scaleBeforeShapeDefault={x:this.settings.scaleX,y:this.settings.scaleY,z:this.settings.scaleZ},this.shapeAutoModified={x:!1,y:!1,z:!1},e===`pill`){let e=Math.max(this.settings.scaleX,this.settings.scaleZ),t=Math.max(this.settings.scaleY,e*2.8);t!==this.settings.scaleY&&(this.settings.scaleY=t,this.shapeAutoModified.y=!0)}}setInstanceDimension(e,t){this.shapeAutoModified[e]=!1;let n=I(t,$.scaleX,P.instance.dimension);e===`x`?(this.settings.scaleX=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleZ=I(n/this.settings.imageAspectRatio,$.scaleZ,P.instance.dimension))):e===`y`?this.settings.scaleY=n:(this.settings.scaleZ=n,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(n*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension))),this.syncRoundedCardRatio(),this.rebuildGeometry()}setImagePreserveAspectRatio(e){this.settings.imagePreserveAspectRatio=e,this.shouldLockImageAspectRatio()&&(this.settings.scaleX=I(this.settings.scaleZ*this.settings.imageAspectRatio,$.scaleX,P.instance.dimension)),this.rebuildGeometry()}shouldLockImageAspectRatio(){return this.settings.instanceShape===`image`&&this.settings.imagePreserveAspectRatio&&this.settings.imageAspectRatio>0}async ensureTextRuntimeLoaded(){if(!(this.textGeometryRuntime&&this.textFonts)){if(this.textRuntimeLoadPromise){await this.textRuntimeLoadPromise;return}this.textRuntimeLoadPromise=Promise.resolve().then(()=>(Au(),xu)).then(async e=>{this.textGeometryRuntime=e,this.textFonts??=new e.TextFontManager,this.settings.textFontSource.source===`url`&&await this.textFonts.loadCustomFont(this.settings.textFontSource.url)}).finally(()=>{this.textRuntimeLoadPromise=null}),await this.textRuntimeLoadPromise}}scheduleTextRuntimeLoad(){this.ensureTextRuntimeLoaded().then(()=>{this.settings.instanceShape===`text`&&this.rebuildGeometry()}).catch(e=>{console.warn(`Unable to load text runtime support.`,e)})}async loadCustomTextFont(e=this.settings.textCustomFontUrl){let t=e.trim();if(!t){this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.settings.textCustomFontUrl=``,this.rebuildGeometry();return}await this.ensureTextRuntimeLoaded(),await this.textFonts?.loadCustomFont(t),this.settings.textCustomFontUrl=t,this.settings.textFont=`custom`,this.settings.textFontSource={source:`url`,url:t},this.rebuildGeometry()}async ensureWebTextFont(e){await this.ensureTextRuntimeLoaded(),!this.textFonts?.hasFont(e)&&(await this.textFonts?.loadWebFont(e),this.settings.textFont===e&&this.settings.instanceShape===`text`&&this.rebuildGeometry())}setTextFont(e){if(this.settings.textFont=e,e===`custom`){this.settings.textCustomFontUrl.trim()?this.loadCustomTextFont().catch(e=>{console.warn(`Unable to load custom text font.`,e)}):(this.textFonts?.clearCustomFont(),this.settings.textFontSource={...Lt},this.rebuildGeometry());return}this.settings.textFontSource={source:`library`,id:e},this.settings.textCustomFontUrl=``,Dt(e)&&this.ensureWebTextFont(e).catch(e=>{console.warn(`Unable to load text font.`,e)}),this.rebuildGeometry()}syncRoundedCardRatio(){this.settings.instanceShape===`rounded-card`&&(this.settings.roundedCardRatio=this.settings.scaleX/Math.max(.01,this.settings.scaleZ))}async loadCustomObj(e=this.settings.assetUrl,t={}){await this.loadCustomAsset(e,t)}async loadCustomAsset(e=this.settings.assetUrl,{showPlaceholder:t=!1,source:n=`background`}={}){let r=e.trim();if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let i=++this.customAssetLoadId;if(n===`user`&&(this.activeUserCustomAssetLoadId=i),this.settings.assetUrl=r,!r){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry();return}t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry());try{let e=await Promise.resolve().then(()=>(cf(),qd)),t=await e.loadCustomAssetGeometry(sp(r));this.completeCustomAssetLoad(i,t,e.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadCustomFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearCustomAssetLoad(i);return}let t=await Promise.resolve().then(()=>(cf(),qd)),n=await t.loadCustomAssetGeometryFromFile(e);this.completeCustomAssetLoad(i,n,t.prepareCustomAssetGeometry)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearSvgAssetLoad(r);return}let e=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometry(sp(n),this.settings.svgSolidify);this.completeSvgAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadSvgFile(e,t,n={}){let r=t.trim(),i=this.beginCustomAssetLoad(r,n);try{if(!r){this.clearSvgAssetLoad(i);return}let t=await(await Promise.resolve().then(()=>(Cf(),ff))).loadSvgAssetGeometryFromFile(e,this.settings.svgSolidify);this.completeSvgAssetLoad(i,t)}catch(e){throw this.activeUserCustomAssetLoadId===i&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageAsset(e=this.settings.assetUrl,t={}){let n=e.trim(),r=this.beginCustomAssetLoad(n,t);try{if(!n){this.clearImageAssetLoad(r);return}let e=await this.textureLoader.loadAsync(sp(n));this.completeImageAssetLoad(r,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadImageFile(e,t,n={}){await this.loadImageAsset(t,n)}async loadImageSet(e=this.settings.imageSetUrls,t={}){let n=op(e),r=this.beginCustomAssetLoad(n[0]??``,t);try{if(n.length===0){this.clearImageAssetLoad(r);return}let e=await Promise.all(n.map(e=>this.textureLoader.loadAsync(sp(e))));this.completeImageSetAssetLoad(r,n,e)}catch(e){throw this.activeUserCustomAssetLoadId===r&&(this.activeUserCustomAssetLoadId=0),e}}async loadBackgroundImage(e=this.settings.backgroundImageUrl){let t=e.trim();if(this.settings.backgroundImageUrl=t,!t){this.clearBackgroundImage();return}let n=await this.textureLoader.loadAsync(sp(t));this.backgroundTexture?.dispose(),this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.backgroundTexture=n,this.configureImageTexture(n),this.settings.backgroundMode=`image`,this.updateSceneBackground(),this.renderIdleFrame()}async loadBackgroundImageFile(e,t){await this.loadBackgroundImage(t)}async loadMaterialTexture(e=this.settings.materialTextureUrl){let n=e.trim();if(this.settings.materialTextureUrl=n,!n){this.clearMaterialTexture();return}let r=await this.textureLoader.loadAsync(sp(n));this.materialTexture?.dispose(),this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.materialTexture=r,this.configureImageTexture(r),r.wrapS=t.RepeatWrapping,r.wrapT=t.RepeatWrapping,this.settings.colorMode=`texture`,this.updateMaterial(),this.renderIdleFrame()}async loadMaterialTextureFile(e,t){await this.loadMaterialTexture(t)}clearMaterialTexture(){this.settings.materialTextureUrl=``,this.materialTexture?.dispose(),this.materialTexture=null,this.materialTextureDisplayTexture?.dispose(),this.materialTextureDisplayTexture=null,this.updateMaterial(),this.renderIdleFrame()}clearBackgroundImage(){this.settings.backgroundImageUrl=``,this.backgroundTexture?.dispose(),this.backgroundTexture=null,this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null,this.updateSceneBackground(),this.renderIdleFrame()}clearCustomAsset(){this.customAssetLoadId+=1,this.activeUserCustomAssetLoadId=0,this.settings.assetUrl=``,this.settings.imageSetUrls=[],this.settings.imageAspectRatio=$.imageAspectRatio,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.updateMaterial(),this.rebuildGeometry()}clearSvgAssetLoad(e){this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}beginCustomAssetLoad(e,{showPlaceholder:t=!1,source:n=`background`}){if(n===`background`&&this.activeUserCustomAssetLoadId>0)throw new wf;let r=++this.customAssetLoadId;return n===`user`&&(this.activeUserCustomAssetLoadId=r),this.settings.assetUrl=e,t&&(this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.settings.instanceShape=`custom-obj`,this.rebuildGeometry()),r}clearCustomAssetLoad(e){this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}clearImageAssetLoad(e){this.imageTexture?.dispose(),this.imageTexture=null,this.disposeImageSetTextures(),this.settings.imageAspectRatio=$.imageAspectRatio,this.activeUserCustomAssetLoadId===e&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeCustomAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw t.dispose(),new wf;this.customAssetLoadId=e,n(t,{assetScale:this.settings.assetScale,assetNormalize:this.settings.assetNormalize}),this.customObjGeometry=t,this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`custom-obj`,r&&(this.activeUserCustomAssetLoadId=0),this.rebuildGeometry()}completeSvgAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.customSvgGeometry?.dispose(),this.customSvgGeometry=t,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.disposeImageSetTextures(),this.imageTexture?.dispose(),this.imageTexture=null,this.settings.imageSetUrls=[],this.settings.instanceShape=`svg`,n&&(this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageAssetLoad(e,t){let n=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!n)throw t.dispose(),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,this.configureImageTexture(t),this.imageTexture=t,this.imageSetTextures=[t],this.settings.imageSetUrls=[];let r=t.image,i=r?.width??$.imageAspectRatio,a=r?.height??1;this.settings.imageAspectRatio=a>0?Math.max(.01,i/a):$.imageAspectRatio,this.settings.instanceShape=`image`,n&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}completeImageSetAssetLoad(e,t,n){let r=this.activeUserCustomAssetLoadId===e;if(e!==this.customAssetLoadId&&!r)throw n.forEach(e=>e.dispose()),new wf;this.customAssetLoadId=e,this.imageTexture?.dispose(),this.disposeImageSetTextures(),this.customSvgGeometry?.dispose(),this.customSvgGeometry=null,this.customObjGeometry?.dispose(),this.customObjGeometry=null,n.forEach(e=>this.configureImageTexture(e)),this.imageSetTextures=n,this.imageTexture=n[0]??null,this.settings.assetUrl=t[0]??``,this.settings.imageSetUrls=t;let i=this.imageTexture?.image,a=i?.width??$.imageAspectRatio,o=i?.height??1;this.settings.imageAspectRatio=o>0?Math.max(.01,a/o):$.imageAspectRatio,this.settings.instanceShape=`image`,r&&(this.settings.imagePreserveAspectRatio&&(this.settings.scaleX=this.settings.scaleZ*this.settings.imageAspectRatio),this.activeUserCustomAssetLoadId=0),this.updateMaterial(),this.rebuildGeometry()}configureImageTexture(e){e.colorSpace=t.SRGBColorSpace,e.needsUpdate=!0}updateSceneBackground(){if(this.settings.backgroundMode===`transparent`){this.scene.background=null;return}if(this.settings.backgroundMode===`image`){this.scene.background=this.updateBackgroundImageDisplayTexture();return}if(this.settings.backgroundMode===`gradient`){this.scene.background=this.updateBackgroundGradientTexture();return}this.scene.background=new t.Color(this.settings.backgroundColor)}invalidateBackgroundImageDisplayTexture(){this.backgroundImageDisplayTexture?.dispose(),this.backgroundImageDisplayTexture=null}invalidateTransparentBackgroundPreviewTexture(){this.transparentBackgroundPreviewTexture?.dispose(),this.transparentBackgroundPreviewTexture=null}updateTransparentBackgroundPreviewTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.max(1,Math.round(e)),i=Math.max(1,Math.round(n)),a=this.transparentBackgroundPreviewTexture,o=a?.image instanceof HTMLCanvasElement?a.image:document.createElement(`canvas`);if(a&&o.width===r&&o.height===i)return a;o.width=r,o.height=i;let s=o.getContext(`2d`);return s&&this.drawCheckerBackground(s,r,i),this.transparentBackgroundPreviewTexture||(this.transparentBackgroundPreviewTexture=new t.CanvasTexture(o),this.transparentBackgroundPreviewTexture.colorSpace=t.SRGBColorSpace,this.transparentBackgroundPreviewTexture.wrapS=t.ClampToEdgeWrapping,this.transparentBackgroundPreviewTexture.wrapT=t.ClampToEdgeWrapping),this.transparentBackgroundPreviewTexture.needsUpdate=!0,this.transparentBackgroundPreviewTexture}updateBackgroundImageDisplayTexture(){let{width:e,height:n}=this.getContainerSize(),r=Math.min(1,1600/Math.max(e,n)),i=Math.max(1,Math.round(e*r)),a=Math.max(1,Math.round(n*r)),o=i/a,s=this.backgroundImageDisplayTexture?.image instanceof HTMLCanvasElement?this.backgroundImageDisplayTexture.image:document.createElement(`canvas`);s.width=i,s.height=a;let c=s.getContext(`2d`);if(!c)return this.backgroundTexture??this.getCheckerTexture();if(!this.backgroundTexture)this.drawCheckerBackground(c,i,a);else{let e=this.backgroundTexture.image,t=this.getTextureImageAspect(this.backgroundTexture);if(!t)return this.backgroundTexture;c.fillStyle=this.settings.backgroundColor,c.fillRect(0,0,i,a);let n=this.settings.backgroundImageFit===`fit`?t>o?i/this.getTextureImageWidth(this.backgroundTexture):a/this.getTextureImageHeight(this.backgroundTexture):t>o?a/this.getTextureImageHeight(this.backgroundTexture):i/this.getTextureImageWidth(this.backgroundTexture),r=this.getTextureImageWidth(this.backgroundTexture)*n,s=this.getTextureImageHeight(this.backgroundTexture)*n;c.drawImage(e,(i-r)*.5,(a-s)*.5,r,s)}return this.backgroundImageDisplayTexture||(this.backgroundImageDisplayTexture=new t.CanvasTexture(s),this.backgroundImageDisplayTexture.colorSpace=t.SRGBColorSpace,this.backgroundImageDisplayTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundImageDisplayTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundImageDisplayTexture.needsUpdate=!0,this.backgroundImageDisplayTexture}drawCheckerBackground(e,t,n){e.fillStyle=Mf,e.fillRect(0,0,t,n),e.fillStyle=Nf;for(let r=0;r<n;r+=Af)for(let n=r/Af%2==0?Af:0;n<t;n+=Af*2)e.fillRect(n,r,Af,Af)}updateBackgroundGradientTexture(){let e=this.backgroundGradientTexture?.image instanceof HTMLCanvasElement?this.backgroundGradientTexture.image:document.createElement(`canvas`);e.width=512,e.height=512;let n=e.getContext(`2d`);if(!n)return new t.Color(this.settings.backgroundColor);let r=n.createImageData(512,512),i=new t.Color(this.settings.backgroundGradientColorA),a=new t.Color(this.settings.backgroundGradientColorB),o=new t.Color,s=Qf(this.settings.backgroundGradientMidpoint),c=511*.5,l=Math.max(1e-4,Math.hypot(c,c));for(let e=0;e<512;e+=1)for(let t=0;t<512;t+=1){let n=this.getBackgroundGradientProgress(t,e,512,c,l),u=at(this.remapGradientProgressWithMidpoint(n,s),this.settings.backgroundGradientEasing,this.settings.backgroundGradientCustomBezier);o.copy(i).lerp(a,u);let d=(e*512+t)*4;r.data[d]=Math.round(o.r*255),r.data[d+1]=Math.round(o.g*255),r.data[d+2]=Math.round(o.b*255),r.data[d+3]=255}return n.putImageData(r,0,0),this.backgroundGradientTexture||(this.backgroundGradientTexture=new t.CanvasTexture(e),this.backgroundGradientTexture.colorSpace=t.SRGBColorSpace,this.backgroundGradientTexture.wrapS=t.ClampToEdgeWrapping,this.backgroundGradientTexture.wrapT=t.ClampToEdgeWrapping),this.backgroundGradientTexture.needsUpdate=!0,this.backgroundGradientTexture}getBackgroundGradientProgress(e,n,r,i,a){return this.settings.backgroundGradientDirection===`x`?r<=1?.5:e/(r-1):this.settings.backgroundGradientDirection===`radial`?t.MathUtils.clamp(Math.hypot(e-i,n-i)/a,0,1):r<=1?.5:1-n/(r-1)}getTextureImageAspect(e){let t=this.getTextureImageWidth(e),n=this.getTextureImageHeight(e);return t<=0||n<=0?null:t/n}getTextureImageWidth(e){let t=e.image;return t?.naturalWidth??t?.width??0}getTextureImageHeight(e){let t=e.image;return t?.naturalHeight??t?.height??0}disposeImageSetTextures(){this.imageSetTextures.forEach(e=>{e!==this.imageTexture&&e.dispose()}),this.imageSetTextures=[]}createGeometry(){return this.settings.instanceShape===`text`&&(!this.textGeometryRuntime||!this.textFonts)&&this.scheduleTextRuntimeLoad(),this.settings.instanceShape===`image`&&this.imageTexture?this.createImageGeometryForTexture(this.imageTexture):this.settings.instanceShape===`image`&&!this.imageTexture||this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createImagePlaceholderGeometry():Bt({settings:this.settings,customObjGeometry:this.customObjGeometry,customSvgGeometry:this.customSvgGeometry,textGeometry:this.textGeometryRuntime&&this.textFonts?{createTextGeometry:this.textGeometryRuntime.createTextGeometry,textFonts:this.textFonts}:null})}getInstanceDimensions(){return Ot(this.settings)}createMaterial(){let e,n=this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`,r=this.usesMaterialTextureSurface();if(e=this.settings.instanceShape===`image`?this.imageTexture?this.createImageMaterial(this.imageTexture):this.createCheckerImageMaterial():this.settings.instanceShape===`svg`&&!this.customSvgGeometry?this.createCheckerImageMaterial():this.settings.shadingMode===`flat`||this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`?new t.MeshBasicMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):this.settings.shadingMode===`toon`?new t.MeshToonMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor}):new t.MeshStandardMaterial({color:this.usesGradientSurfaceColor()||r?`#ffffff`:this.settings.objectColor,roughness:this.settings.roughness,metalness:this.settings.metalness}),n)e.side=t.DoubleSide,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;else{let n=this.settings.instanceShape===`image`,r=this.settings.instanceShape===`svg`&&!this.settings.svgSolidify,i=this.settings.instanceShape===`text`&&!this.settings.textSolidify,a=this.settings.instanceShape===`custom-obj`&&this.settings.assetDoubleSided;(n||r||i||a)&&(e.side=t.DoubleSide),e.polygonOffset=!0,e.polygonOffsetFactor=1,e.polygonOffsetUnits=1}return this.enableInstanceOpacity(e,{alphaHash:!0,objectGradient:this.usesObjectGradient(),materialTexture:r})}usesGradientSurfaceColor(){return this.settings.colorMode===`gradient`&&this.settings.instanceShape!==`image`}usesMaterialTextureSurface(){return this.settings.colorMode===`texture`&&this.isTextureMaterialShape()}isTextureMaterialShape(){return this.settings.instanceShape!==`image`&&this.settings.instanceShape!==`svg`}usesInstanceColors(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`pattern`}usesObjectGradient(){return this.usesGradientSurfaceColor()&&this.settings.gradientScope===`object`}getMaterialTextureModeIndex(){return this.materialTexture?this.settings.materialTextureFit===`fit`?1:this.settings.materialTextureFit===`fill`?2:this.settings.materialTextureFit===`repeat`?3:0:3}getMaterialTextureScopeIndex(){return+(this.settings.materialTextureScope===`pattern`)}getMaterialTextureProjectionIndex(){return+(this.settings.materialTextureProjection===`triplanar`)}createImageMaterial(e){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:e,transparent:!0,alphaTest:.01,depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}createCheckerImageMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({map:this.getCheckerTexture(),depthTest:!0,depthWrite:!0,side:t.DoubleSide}),{alphaHash:!0})}getMaterialTexture(){return this.materialTexture??this.getCheckerTexture()}getMaterialTextureRepeat(e){return this.materialTexture?Math.max(.001,e):jf}getCheckerTexture(){if(this.checkerTexture)return this.checkerTexture;let e=document.createElement(`canvas`);e.width=kf*2,e.height=kf*2;let n=e.getContext(`2d`);return n&&(n.fillStyle=Mf,n.fillRect(0,0,e.width,e.height),n.fillStyle=Nf,n.fillRect(kf,0,kf,kf),n.fillRect(0,kf,kf,kf)),this.checkerTexture=new t.CanvasTexture(e),this.checkerTexture.colorSpace=t.SRGBColorSpace,this.checkerTexture.wrapS=t.RepeatWrapping,this.checkerTexture.wrapT=t.RepeatWrapping,this.checkerTexture.magFilter=t.NearestFilter,this.checkerTexture.minFilter=t.NearestFilter,this.checkerTexture.repeat.set(jf,jf),this.checkerTexture.needsUpdate=!0,this.checkerTexture}getTextureAspectRatio(e){let t=e.image,n=t?.width??$.imageAspectRatio,r=t?.height??1;return r>0?Math.max(.01,n/r):$.imageAspectRatio}createImageGeometryForTexture(e){let{scaleX:n,scaleZ:r}=this.getInstanceDimensions(),i=this.settings.imagePreserveAspectRatio?r*this.getTextureAspectRatio(e):n,a=Math.min(.5,Math.max(0,this.settings.imageCornerRadius)),o=a>0?rp(i,r,Math.min(i,r)*a):new t.PlaneGeometry(i,r);return o.rotateX(-Math.PI/2),o}createImagePlaceholderGeometry(){let{scaleX:e,scaleZ:n}=this.getInstanceDimensions(),r=new t.PlaneGeometry(e,n);return r.rotateX(-Math.PI/2),r}createOutlineMaterial(){return this.enableInstanceOpacity(new t.MeshBasicMaterial({color:this.settings.silhouetteColor,side:t.BackSide,opacity:1,depthTest:!0,depthWrite:!0}),{alphaHash:!0})}createEdgeGeometry(e){let n=new t.EdgesGeometry(e,1),r=n.getAttribute(`position`).array,i=new p;return i.setPositions(Array.from(r)),n.dispose(),i}createEdgeMaterial(){let e=new m({color:new t.Color(this.settings.edgeColor).getHex(),linewidth:this.settings.edgeThickness*1e3,transparent:!0,opacity:this.settings.outlineOpacity,depthTest:!this.settings.outlineSeeThrough,depthWrite:!1,polygonOffset:!1,polygonOffsetFactor:0,polygonOffsetUnits:0}),{width:n,height:r}=this.getContainerSize();return e.resolution.set(n,r),e}shouldShowSilhouetteOutline(){return this.settings.shadingMode===`silhouette-outline`||this.settings.shadingMode===`silhouette-edge-outline`}shouldShowEdgeOutline(){return this.settings.shadingMode===`edge-outline`||this.settings.shadingMode===`silhouette-edge-outline`}createEdgeLine(){if(!this.edgeGeometry||!this.edgeMaterial)return null;let e=this.edgeMaterial.clone(),{width:t,height:n}=this.getContainerSize();e.resolution.set(t,n),e.depthTest=!this.settings.outlineSeeThrough,e.depthWrite=!1,e.polygonOffset=!1,e.polygonOffsetFactor=0,e.polygonOffsetUnits=0;let r=new N(this.edgeGeometry,e);return r.renderOrder=this.getEdgeRenderOrder(),r.matrixAutoUpdate=!1,r.frustumCulled=!1,r}syncImageSetMeshes(){let e=this.getImageTextures(),n=Math.max(0,e.length-1),r=this.mesh.instanceMatrix.count;for(;this.imageSetMeshes.length>n;){let e=this.imageSetMeshes.pop();e&&(this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material))}for(;this.imageSetMeshes.length<n;){let n=e[this.imageSetMeshes.length+1],i=new t.InstancedMesh(this.createImageGeometryForTexture(n),this.createImageMaterial(n),r);i.renderOrder=this.mesh.renderOrder,i.frustumCulled=!1,this.imageSetMeshes.push(i),this.scene.add(i)}this.imageSetMeshes.forEach((n,i)=>{let a=e[i+1];if(n.instanceMatrix.count!==r){let e=new t.InstancedMesh(this.createImageGeometryForTexture(a),this.createImageMaterial(a),r);e.renderOrder=n.renderOrder,e.frustumCulled=!1,e.count=n.count,this.scene.remove(n),n.geometry.dispose(),this.disposeMeshMaterial(n.material),this.imageSetMeshes[i]=e,this.scene.add(e);return}n.geometry.dispose(),n.geometry=this.createImageGeometryForTexture(a),this.disposeMeshMaterial(n.material),n.material=this.createImageMaterial(a),n.renderOrder=this.mesh.renderOrder}),this.syncImageSetMeshTransforms()}disposeImageSetMeshes(){this.imageSetMeshes.forEach(e=>{this.scene.remove(e),e.geometry.dispose(),this.disposeMeshMaterial(e.material)}),this.imageSetMeshes=[]}disposeMeshMaterial(e){if(Array.isArray(e)){e.forEach(e=>e.dispose());return}e.dispose()}rebuildEdgeLines(){this.edgeLines.forEach(e=>{this.edgeGroup.remove(e),this.disposeMeshMaterial(e.material)}),this.edgeLines=[],this.shouldShowEdgeOutline()&&this.syncEdgeLineCount()}syncEdgeLineCount(){if(!this.shouldShowEdgeOutline()){this.edgeGroup.visible=!1;return}for(this.edgeGroup.visible=!0;this.edgeLines.length<this.layouts.length;){let e=this.createEdgeLine();if(!e)return;this.edgeLines.push(e),this.edgeGroup.add(e)}this.edgeLines.forEach((e,t)=>{e.visible=t<this.layouts.length,e.renderOrder=this.getEdgeRenderOrder()})}setEdgeLineOpacity(e,n){let r=e.material;r.opacity=this.settings.outlineOpacity*t.MathUtils.clamp(n,0,1),r.transparent=!0,r.needsUpdate=!0}getEdgeRenderOrder(){return this.settings.edgeCompositing===`surface`?2:10}getEdgeScaleLift(){return 1}ensureCameraType(){this.settings.viewMode===`perspective`!=this.camera instanceof t.PerspectiveCamera&&(this.camera=this.createCamera())}updateCamera(){this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.settings.viewMode===`orthographic`&&this.settings.orthographicView!==`custom`?this.updateOrthographicViewCamera():this.updateCameraOrbit(),this.updateCameraProjection(),this.camera.position.set(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ);let e=ve({distance:this.settings.cameraDistance,azimuth:this.settings.cameraOrbitAngle,elevation:this.settings.cameraElevation,target:{x:this.settings.cameraTargetX,y:this.settings.cameraTargetY,z:this.settings.cameraTargetZ}});this.camera.up.set(e.x,e.y,e.z),this.camera.lookAt(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),this.camera.updateProjectionMatrix()}applyCameraSettings(){this.updateCamera(),this.notifyCameraChange(),this.renderIdleFrame()}setStarfieldFlightFromCamera(e=!0){if(this.settings.distributionMode!==`starfield`)return;let t=this.alignVecScratch.set(this.settings.cameraPositionX-this.settings.cameraTargetX,this.settings.cameraPositionY-this.settings.cameraTargetY,this.settings.cameraPositionZ-this.settings.cameraTargetZ);if(t.lengthSq()<1e-8)return;t.normalize();let n=this.alignUpScratch.setFromMatrixColumn(this.camera.matrixWorld,1).normalize(),r=this.alignRightScratch.copy(n).cross(t);if(r.lengthSq()<1e-8)return;r.normalize();let i=n.copy(t).cross(r).normalize();this.alignMatrixScratch.makeBasis(r,i,t),this.orientationEulerScratch.setFromRotationMatrix(this.alignMatrixScratch),this.settings.pathOrientationX=this.orientationEulerScratch.x,this.settings.pathOrientationY=this.orientationEulerScratch.y,this.settings.pathOrientationZ=this.orientationEulerScratch.z,e&&this.updatePattern()}updateOrthographicViewCamera(){let e=Math.max(1,this.settings.cameraDistance||42),t=this.settings.cameraTargetX,n=this.settings.cameraTargetY,r=this.settings.cameraTargetZ;switch(this.settings.orthographicView){case`front`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r+e;break;case`back`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r-e;break;case`left`:this.settings.cameraPositionX=t-e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`right`:this.settings.cameraPositionX=t+e,this.settings.cameraPositionY=n,this.settings.cameraPositionZ=r;break;case`top`:this.settings.cameraPositionX=t,this.settings.cameraPositionY=n+e,this.settings.cameraPositionZ=r;break;default:this.updateCameraOrbit();break}}getOrthographicFrustumSize(){return Lf*(If/I(this.settings.orthoScale,$.orthoScale,P.camera.orthographicFrustumScale))}createCamera(){let{width:e,height:n}=this.getContainerSize(),r=e/n;return this.settings.viewMode===`perspective`?new t.PerspectiveCamera(this.getPerspectiveFovFromFocalLength(),r,P.camera.perspectiveClip.near,P.camera.perspectiveClip.far):new t.OrthographicCamera(this.frustumSize*r/-2,this.frustumSize*r/2,this.frustumSize/2,this.frustumSize/-2,P.camera.orthographicClip.near,P.camera.orthographicClip.far)}createViewportGrid(){let e=new t.GridHelper(80,80,`#6c6c6c`,`#6c6c6c`);return e.visible=!1,e.renderOrder=-1,(Array.isArray(e.material)?e.material:[e.material]).forEach(e=>{e.transparent=!0,e.opacity=.32,e.depthWrite=!1}),e}updateCameraProjection(){let{width:e,height:n}=this.getContainerSize(),r=e/n;if(this.camera instanceof t.PerspectiveCamera){this.camera.fov=this.getPerspectiveFovFromFocalLength(),this.camera.aspect=r,this.camera.near=P.camera.perspectiveClip.near,this.camera.far=this.getPerspectiveFarClip(),this.camera.updateProjectionMatrix();return}this.camera.left=this.frustumSize*r/-2,this.camera.right=this.frustumSize*r/2,this.camera.top=this.frustumSize/2,this.camera.bottom=this.frustumSize/-2,this.camera.updateProjectionMatrix()}getPerspectiveFarClip(){let e=P.camera.perspectiveClip.far;if(!this.mesh)return e;let n=this.getSubjectBounds(),r=new t.Sphere;n.getBoundingSphere(r);let i=new t.Vector3(this.settings.cameraPositionX,this.settings.cameraPositionY,this.settings.cameraPositionZ).distanceTo(r.center)+r.radius;return Math.max(e,i*1.25)}getContainerSize(){return this.exportSizeOverride?this.exportSizeOverride:this.getLiveContainerSize()}getLiveContainerSize(){let e=this.container.getBoundingClientRect();return{width:Math.max(1,e.width||window.innerWidth),height:Math.max(1,e.height||window.innerHeight)}}getSubjectBounds(){let e=new t.Box3,n=new t.Matrix4,r=new t.Matrix4,i=new t.Box3,a=t=>{t.geometry.computeBoundingBox();let a=t.geometry.boundingBox;if(a){t.updateMatrixWorld();for(let o=0;o<t.count;o+=1)t.getMatrixAt(o,n),r.multiplyMatrices(t.matrixWorld,n),i.copy(a).applyMatrix4(r),e.union(i)}};return a(this.mesh),this.imageSetMeshes.forEach(a),e.isEmpty()&&e.setFromCenterAndSize(new t.Vector3(this.settings.cameraTargetX,this.settings.cameraTargetY,this.settings.cameraTargetZ),new t.Vector3(1,1,1)),e}getPerspectiveFovFromFocalLength(){return ee(this.settings.cameraFocalLength)}updateColors(){this.settings.backgroundMode===`image`&&this.invalidateBackgroundImageDisplayTexture(),this.updateSceneBackground(),this.updateMaterial(),this.renderIdleFrame()}updateMaterial(){let e=this.mesh.material;this.disposeMeshMaterial(e);let t=this.outlineMesh.material;this.disposeMeshMaterial(t),this.mesh.material=this.createMaterial(),this.syncImageSetMeshes(),this.outlineMesh.material=this.createOutlineMaterial(),this.edgeMaterial?.dispose(),this.edgeMaterial=this.createEdgeMaterial(),this.outlineMesh.visible=this.shouldShowSilhouetteOutline(),this.edgeGroup.visible=this.shouldShowEdgeOutline(),this.edgeGroup.renderOrder=this.getEdgeRenderOrder(),this.shouldShowEdgeOutline()?(this.edgeGeometry||=this.createEdgeGeometry(this.mesh.geometry),this.edgeLines.forEach(e=>{this.disposeMeshMaterial(e.material),e.material=this.edgeMaterial.clone()}),this.syncEdgeLineCount()):this.rebuildEdgeLines(),this.updateLights(),this.renderIdleFrame()}getMaxInstanceCount(){let{gridSize:e,gridLayers:t,ringCount:n,ringDensity:r,pathInstanceCount:i,pathRows:a}=Se(this.settings),o=Math.ceil(1+r*(n*(n+1))/2),s=i*Math.max(1,Math.round(a)),c=e*e*Math.max(1,Math.round(t));return Math.max(1,e*e,c,o,s)}ensureMeshCapacity(e){if(e<=this.mesh.instanceMatrix.count)return;let n=this.mesh.geometry,r=this.mesh.material,i=Math.ceil(e*1.25),a=new t.InstancedMesh(n,r,i);a.renderOrder=1,a.frustumCulled=!1;let o=new t.InstancedMesh(this.outlineMesh.geometry,this.outlineMesh.material,i);o.renderOrder=0,o.frustumCulled=!1,o.visible=this.outlineMesh.visible,this.scene.remove(this.mesh),this.scene.remove(this.outlineMesh),this.mesh=a,this.outlineMesh=o,this.scene.add(this.mesh),this.scene.add(this.outlineMesh),this.syncImageSetMeshes()}createLayouts(){return De(this.settings)}getSpinStaggerFactor(e,t){let n=this.settings.instanceSpinStagger;if(n===0)return 1;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);if(this.settings.instanceSpinStaggerMode===`alternating`){let t=e.gridX%2==0?1:-1;return Math.max(-4,1+t*n*r)}return Math.max(-4,1+n*r)}getSpinPhaseOffset(e,t){let n=this.settings.instanceSpinPhaseStagger;if(n===0)return 0;let r=np(this.settings.distributionMode)?e.spinProgress:this.getLayoutProgress(e,t);return this.settings.instanceSpinStaggerMode===`alternating`?(e.gridX%2==0?1:-1)*n*r:n*r}getLayoutProgress(e,t){return t===0?0:e.distance/t}renderExportFrameAt(e,t){if(!this.hasTimeVaryingMotion()){this.renderScene(t);return}this.renderAnimatedFrame(e,this.getPathTravelTime(e),this.getRingOrbitTime(e),t)}animate=()=>{let e=(performance.now()-this.startTime)/1e3;if(!this.hasTimeVaryingMotion()){this.animationFrameId=null,this.updatePattern();return}let t=Math.max(0,Math.min(.1,e-this.previousAnimationElapsed));this.previousAnimationElapsed=e,this.pathTravelProgress+=this.getPathTravelDelta(t),this.ringOrbitProgress+=this.getRingOrbitDelta(t),this.renderAnimatedFrame(e,this.pathTravelProgress,this.ringOrbitProgress),this.animationFrameId=requestAnimationFrame(this.animate)};getPathTravelTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitTime(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}getPathTravelDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.pathTravelSpeed}getRingOrbitDelta(e){return this.settings.pathTravelMode===`stepped`?e:e*this.settings.ringOrbitSpeed}renderAnimatedFrame(e,t,n,r=this.renderer){let{instanceRotationX:i,instanceRotationY:a,instanceRotationZ:o,instanceSpinX:s,instanceSpinY:c,instanceSpinZ:l,instanceSpinStagger:u,instanceSpinPhaseStagger:d,pathRotationX:f,pathRotationY:p,pathRotationZ:m,waveAmplitude:h,waveFrequency:g,waveSpeed:_,easingMode:v,easingCustomBezier:y,staggerAmount:b,scaleMode:x,scaleAmount:S,animationMode:C,scaleY:w,baseY:T,groundAlign:E}=this.settings;this.setStructureRotation(e*f,e*p,e*m);let D={...this.settings,...Se(this.settings),ringOrbitFriction:this.settings.ringOrbitFriction},O=this.getEdgeScaleLift(),k=T+(E?w/2:0),A=u===0&&d===0?0:this.layouts.reduce((e,t)=>Math.max(e,t.distance),0);this.clearInstanceColorsForImageSurfaces(),this.ensureInstanceOpacityAttribute(this.mesh),this.ensureInstanceOpacityAttribute(this.outlineMesh),this.imageSetMeshes.forEach(e=>this.ensureInstanceOpacityAttribute(e));let j=this.createSurfaceWriteState(),M=this.getLayoutBounds(this.layouts),N=this.getBuildTransform(this.getBuildProgress(e));this.layouts.forEach((r,u)=>{let d=ft({layout:r,settings:D,pathTravelProgress:t,ringOrbitProgress:n}),f=(d.gridX+d.gridZ)%2==0?1:-1,p=d.distance;C===`linear-wave`&&(p=d.x+d.z),C===`checker-wave`&&(p=d.distance*f),C===`ring-wave`&&(p=d.ringIndex);let m=(d.distance+d.ringIndex)*b,w=e*_-m,T=Math.sin(p*g-w);T=ot(T,v,y),C===`cross-field`&&(T=ot(Math.sin(d.x*g-w)*Math.sin(d.z*g+w),v,y));let E=Math.abs(_)<=Df?0:T*h;this.dummy.position.set(d.x*N.sceneScale,(k+d.y+E)*N.sceneScale+N.offsetY,d.z*N.sceneScale);let P=this.getInstanceScale(d,x,S)*N.scale*N.sceneScale;this.dummy.scale.set(P,P,P);let F=this.getSpinStaggerFactor(d,A),I=this.getSpinPhaseOffset(d,A),ee=this.alignQuaternion(d,this.alignQuatScratch);this.manualQuatScratch.setFromEuler(this.orientationEulerScratch.set(i+N.rotationX,a+N.rotationY,o+N.rotationZ)),this.spinQuatScratch.setFromEuler(this.orientationEulerScratch.set(e*s*F+(Math.abs(s)>1e-4?I:0),e*c*F+(Math.abs(c)>1e-4?I:0),e*l*F+(Math.abs(l)>1e-4?I:0))),this.dummy.quaternion.copy(ee).multiply(this.manualQuatScratch).multiply(this.spinQuatScratch),this.dummy.updateMatrix();let te=this.getInstanceOpacity(u,d)*N.opacity,ne=this.setSurfaceMatrixAt(u,this.dummy.matrix,j);this.setInstanceOpacityAt(ne.mesh,ne.index,te),this.setInstanceColorAt(ne.mesh,ne.index,this.getInstanceColor(d,M)),this.dummy.scale.setScalar(P*O),this.dummy.updateMatrix();let re=this.edgeLines[u];re&&(re.matrix.copy(this.dummy.matrix),re.matrixWorldNeedsUpdate=!0,this.setEdgeLineOpacity(re,te)),this.dummy.scale.setScalar(P*(1+this.settings.outlineThickness)),this.dummy.updateMatrix(),this.outlineMesh.setMatrixAt(u,this.dummy.matrix),this.setInstanceOpacityAt(this.outlineMesh,u,te)}),this.finishSurfaceWrites(j),this.outlineMesh.instanceMatrix.needsUpdate=!0,this.renderScene(r)}getInstanceScale(e,t,n){if(t===`constant`||n===0)return 1;let r=this.layouts.reduce((e,t)=>Math.max(e,t.distance),0),i=r===0?0:e.distance/r,a=e=>{let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)},o=(e,t=n)=>{let r=a(e);return I(t>=0?1+r*t:1/(1+r*Math.abs(t)),1,P.instance.scaleVariationMultiplier)};if(t===`center-out`)return o(i);if(t===`edge-out`)return o(1-i);if(t===`alternating`)return o(1,((e.gridX+e.gridZ)%2==0?1:-1)*n);let s=Math.max(0,Math.min(1,e.pathProgress)),c=1-Math.abs(s-.5)*2,l=Math.abs(s-.5)*2;if(t===`path-linear`)return o(s);if(t===`path-linear-reverse`)return o(1-s);if(t===`path-center`)return o(c);if(t===`path-edges`)return o(l);if(t===`path-quad`)return o(s*s);if(t===`path-quad-reverse`){let e=1-s;return o(e*e)}return 1}addLights(){this.ambientLight=new t.AmbientLight(`#ffffff`,this.settings.ambientIntensity),this.scene.add(this.ambientLight),this.directionalLight=new t.DirectionalLight(`#ffffff`,this.settings.lightIntensity),this.setDirectionalLightPosition(),this.scene.add(this.directionalLight)}updateLights(){this.ambientLight&&(this.ambientLight.intensity=this.settings.ambientIntensity),this.directionalLight&&(this.directionalLight.intensity=this.settings.lightIntensity,this.setDirectionalLightPosition()),this.renderIdleFrame()}setDirectionalLightPosition(){if(!this.directionalLight)return;let e=Math.cos(this.settings.lightElevation)*18;this.directionalLight.position.set(Math.cos(this.settings.lightAzimuth)*e,Math.sin(this.settings.lightElevation)*18,Math.sin(this.settings.lightAzimuth)*e),this.directionalLight.lookAt(0,0,0)}applyRendererPixelRatio(){this.renderer.setPixelRatio(Math.min(window.devicePixelRatio,this.settings.renderPixelRatio))}observeContainerSize(){if(typeof ResizeObserver>`u`)return;let{width:e,height:t}=this.getLiveContainerSize();this.observedWidth=e,this.observedHeight=t,this.containerResizeObserver=new ResizeObserver(()=>{if(this.disposed)return;let e=this.getLiveContainerSize();e.width===this.observedWidth&&e.height===this.observedHeight||(this.observedWidth=e.width,this.observedHeight=e.height,this.handleResize())}),this.containerResizeObserver.observe(this.container)}handleResize=()=>{this.settings.viewMode===`orthographic`&&(this.frustumSize=this.getOrthographicFrustumSize()),this.updateCameraProjection();let{width:e,height:t}=this.getContainerSize();this.applyRendererPixelRatio(),this.renderer.setSize(e,t),this.invalidateBackgroundImageDisplayTexture(),this.invalidateTransparentBackgroundPreviewTexture(),this.updateSceneBackground(),this.updateEdgeResolution(e,t),this.renderIdleFrame()}},dp=8,fp=`300px`,pp=new Set,mp=new WeakMap,hp=new WeakSet,gp=new Map,_p=null,vp=dp,yp=0,bp=!1,xp=!1,Sp=()=>typeof IntersectionObserver<`u`,Cp=()=>typeof document>`u`||document.visibilityState!==`hidden`,wp=()=>{let e=0;for(let t of pp)t.isMounted()&&(e+=1);return e},Tp=e=>{let t=null;for(let n of pp)n===e||!n.isMounted()||!n.evictable||n.visible||(!t||n.lastUsed<t.lastUsed)&&(t=n);return t},Ep=()=>{bp||(bp=!0,console.warn(`Sinth: more than ${vp} embeds are on screen at once, so the WebGL context budget cannot be honoured. The browser may drop the oldest context. Show fewer patterns at a time, or raise \`maxLiveContexts\` if the page can afford it.`))},Dp=e=>{for(;wp()>=vp;){let t=Tp(e);if(!t){Ep();return}t.unmount()}},Op=e=>{yp+=1,e.lastUsed=yp,!e.isMounted()&&(Dp(e),e.mount())},kp=(e,t)=>{if(e.visible=t,!t){e.suspend();return}Op(e),Cp()&&e.resume()},Ap=()=>{let e=Cp();for(let t of pp)t.isMounted()&&(e?t.visible&&t.resume():t.suspend())},jp=()=>{xp||typeof document>`u`||(xp=!0,document.addEventListener(`visibilitychange`,Ap))},Mp=e=>{let t=gp.get(e);return t||(t=new IntersectionObserver(e=>{for(let t of e){let e=mp.get(t.target);if(e)for(let n of e)kp(n,t.isIntersecting)}},{rootMargin:e}),gp.set(e,t)),t},Np=e=>{if(hp.has(e))return;hp.add(e);let t=e.id?`id="${e.id}"`:e.className?`class="${e.className}"`:`the same element`;console.warn(`Sinth: more than one embed is pointed at ${t}, so they render on top of one another and only the topmost is visible. Each embed needs its own container. This is usually older embed code that looks the container up by name — re-copy the block from the editor (Embed → Copy embed code) and paste it again. The current code finds the container next to its own <script> tag, so it is safe to paste any number of times.`)};function Pp(e,t){if(typeof t.maxLiveContexts==`number`&&Number.isFinite(t.maxLiveContexts)){let e=Math.max(1,Math.floor(t.maxLiveContexts));_p=_p===null?e:Math.min(_p,e),vp=_p}let n=Sp(),r=t.lazy&&n,i={...e,evictable:r,visible:!r,lastUsed:0,rootMargin:t.rootMargin};if(pp.add(i),jp(),n){let t=mp.get(e.container);t?t.size>0&&Np(e.container):(t=new Set,mp.set(e.container,t)),t.add(i),Mp(i.rootMargin).observe(e.container)}return r||(Op(i),Cp()&&i.resume()),{claim:()=>{Op(i)},release:()=>{if(pp.delete(i),!n)return;let t=mp.get(e.container);t?.delete(i),(!t||t.size===0)&&(Mp(i.rootMargin).unobserve(e.container),mp.delete(e.container))}}}var Fp=`sinth`,Ip=`.${Fp}`,Lp=new WeakSet,Rp=e=>{Lp.add(e)},zp=e=>Lp.has(e),Bp=e=>e instanceof HTMLElement&&e.matches(Ip)&&!Lp.has(e),Vp=e=>{if(!e)return null;for(let t of e.querySelectorAll(Ip))if(Bp(t))return t;return null};function Hp(e){if(Bp(e??null))return e;if(e){for(let t=e.previousElementSibling;t;t=t.previousElementSibling)if(Bp(t))return t;let t=Vp(e.parentElement);if(t)return t}let t=Vp(typeof document>`u`?null:document);if(t)return t;throw Error(`Sinth: no free container found for this embed. Every block needs its own element with class "${Fp}" — the copied embed code brings one with it, so this usually means the <div> was deleted, or its class was renamed, or another embed has already taken it.`)}var Up=1e3,Wp=async e=>{e.rebuildGeometry(),e.updateMaterial(),e.updateColors(),e.updateLights(),e.updateCamera(),e.updatePattern()};function Gp({container:e,preset:t,autoStart:n=!0,lazy:r=!0,rootMargin:i=fp,maxLiveContexts:a}){let o=null,s=t,c=n,l=!1,u=!1,d=!1,f=null,p=!1,m=null,h=()=>{let t=e.getBoundingClientRect();return t.width>0&&t.height>0};Rp(e);let g=()=>{let t=new up(e,{config:s,autoStart:c&&!u});o=t,s&&Wp(t).catch(e=>{console.error(`Unable to initialise the Sinth embed.`,e)})},_=()=>{p||m!==null||typeof window>`u`||(m=window.setTimeout(()=>{if(m=null,l||p||h()||!(e.offsetParent!==null||window.getComputedStyle(e).position===`fixed`))return;p=!0;let t=e.getBoundingClientRect().height===0?`height`:`width`;console.warn(`Sinth: this container has no ${t}, so there is nothing to render into and the embed is waiting. Sinth fills the box it is given — if the container is sized \`${t}: 100%\`, give its parent a ${t} (or set a ${t} on the container itself). It will start on its own the moment the container has one.`,e)},Up))},v=()=>{if(d=!0,_(),!f){if(typeof ResizeObserver>`u`){d=!1,g();return}f=new ResizeObserver(()=>{if(!(l||!d)){if(!h()){_();return}d=!1,g()}}),f.observe(e)}},y=()=>{if(!(o||l)){if(!h()){v();return}g()}},b=()=>{d=!1,o&&=(o.dispose(),null)},x=Pp({container:e,mount:y,unmount:b,resume:()=>{u=!1,c&&o?.start()},suspend:()=>{u=!0,o?.stop()},isMounted:()=>o!==null},{lazy:r,rootMargin:i,maxLiveContexts:a});return{get engine(){return o},updatePreset:e=>{s=e,o&&(o.setConfig(e),Wp(o).catch(e=>{console.error(`Unable to update the Sinth embed preset.`,e)}))},start:()=>{c=!0,x.claim(),o?.start()},stop:()=>{c=!1,o?.stop()},destroy:()=>{l=!0,m!==null&&(clearTimeout(m),m=null),f?.disconnect(),f=null,x.release(),b()}}}var Kp=`.${Fp}, [data-sinth-preset]`,qp=`:scope > script[type="application/json"]`,Jp=new WeakSet,Yp=!1,Xp=(e,t)=>{try{return JSON.parse(e)}catch(e){return console.error(`Sinth: this embed’s preset is not valid JSON, so it was skipped.`,t,e),null}},Zp=e=>{if(e===null||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0},Qp=e=>{let t={};e.dataset.sinthLazy===`false`&&(t.lazy=!1),e.dataset.sinthAutostart===`false`&&(t.autoStart=!1),e.dataset.sinthRootMargin&&(t.rootMargin=e.dataset.sinthRootMargin);let n=Zp(e.dataset.sinthMaxContexts??null);return n!==void 0&&(t.maxLiveContexts=n),t},$p=(e,t)=>{if(zp(e))return null;try{return Gp({container:e,preset:t,...Qp(e)})}catch(t){return console.error(`Sinth: this embed could not be created.`,e,t),null}},em=e=>{if(zp(e)||Jp.has(e))return null;let t=e.querySelector(qp);if(t){let n=Xp(t.textContent??``,e);return n?$p(e,n):null}let n=e.dataset.sinthPreset?.trim();if(!n)return null;if(n.startsWith(`{`)){let t=Xp(n,e);return t?$p(e,t):null}return Jp.add(e),fetch(n,{credentials:`omit`}).then(e=>{if(!e.ok)throw Error(`${e.status} ${e.statusText}`);return e.json()}).then(t=>{Jp.delete(e),$p(e,t)}).catch(t=>{Jp.delete(e),console.error(`Sinth: could not load the preset at "${n}".`,e,t)}),null};function tm(e=document){let t=[];for(let n of e.querySelectorAll(Kp)){let e=em(n);e&&t.push(e)}return t}var nm=e=>e instanceof Element?e.matches(Kp)||e.querySelector(Kp)!==null:!1;function rm(){if(Yp||typeof document>`u`||window.SINTH_AUTO_MOUNT===!1)return;Yp=!0;let e=()=>{if(tm(document),typeof MutationObserver>`u`)return;let e=!1;new MutationObserver(t=>{if(!e){for(let n of t)for(let t of n.addedNodes)if(nm(t)){e=!0,requestAnimationFrame(()=>{e=!1,tm(document)});return}}}).observe(document.documentElement,{childList:!0,subtree:!0})};if(document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,e,{once:!0});return}e()}var im=`1.0.3`,am=`v51`,om=`${im} · v51`;return Rt(),rm(),e.SINTH_CONTAINER_CLASS=Fp,e.SNAPSHOT=am,e.VERSION=im,e.VERSION_LABEL=om,e.createSinthEmbed=Gp,e.fontBaseUrl=Tt,e.mountAll=tm,e.normalizeSinthConfig=lp,e.resolveContainer=Hp,e.setFontBaseUrl=wt,e.startAutoMount=rm,e})({},THREE);window.Sinth=e}})();
@@ -1,6 +1,6 @@
1
- /*! Sinth 1.0.0 (v48) · @s25studio/sinth@1.0.0 · https://unpkg.com/@s25studio/sinth@1.0.0
1
+ /*! Sinth 1.0.3 (v51) · @s25studio/sinth@1.0.3 · https://unpkg.com/@s25studio/sinth@1.0.3
2
2
  * Copyright (c) 2026 S25 Studio. Licensed, not sold — see LICENSE.md in the
3
- * package or https://unpkg.com/@s25studio/sinth@1.0.0/LICENSE.md
3
+ * package or https://unpkg.com/@s25studio/sinth@1.0.3/LICENSE.md
4
4
  *
5
5
  * Bundles three.js addons and, via TTFLoader, opentype.js — both MIT. The
6
6
  * script build three.min.js inlines three.js itself.
package/dist/three.min.js CHANGED
@@ -1,6 +1,6 @@
1
- /*! Sinth 1.0.0 (v48) · @s25studio/sinth@1.0.0 · https://unpkg.com/@s25studio/sinth@1.0.0
1
+ /*! Sinth 1.0.3 (v51) · @s25studio/sinth@1.0.3 · https://unpkg.com/@s25studio/sinth@1.0.3
2
2
  * Copyright (c) 2026 S25 Studio. Licensed, not sold — see LICENSE.md in the
3
- * package or https://unpkg.com/@s25studio/sinth@1.0.0/LICENSE.md
3
+ * package or https://unpkg.com/@s25studio/sinth@1.0.3/LICENSE.md
4
4
  *
5
5
  * Bundles three.js addons and, via TTFLoader, opentype.js — both MIT. The
6
6
  * script build three.min.js inlines three.js itself.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@s25studio/sinth",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "Sinth — a real-time 3D pattern engine for the web. Drop-in <script> embed, split Three.js build, and ESM library.",
5
5
  "keywords": [
6
6
  "3d",
@@ -44,6 +44,6 @@
44
44
  "./dist/three.min.js"
45
45
  ],
46
46
  "sinth": {
47
- "snapshot": "v48"
47
+ "snapshot": "v51"
48
48
  }
49
49
  }